---
title: "Clinical interaction guidelines"
description: "Ten rules for any interface that shows someone their own health data. Each rule is written as a prohibition a reviewer can test against a rendered screen."
url: "https://opsinjs.pensievelabs.org/health/clinical-interaction-guidelines"
source: "https://opsinjs.pensievelabs.org/health/clinical-interaction-guidelines.md"
section: "Health"
kind: "health"
evidence: "mixed"
reviewed: "2026-09-02"
reviewer: "design"
aliases: ["clinical rules", "prohibitions", "safety rules", "ten rules", "health ui rules"]
implements: ["result-card", "range-bar", "score-dial", "trend-sparkline", "metric-tile", "status-pill", "alert-banner", "care-card", "disclaimer-note", "value", "relative-time", "consent-sheet", "term", "scale-input", "dose-tracker", "questionnaire", "symptom-picker"]
---

> Elements written as `<PascalCase … />` below are opsinjs documentation
> components. Their attributes are the content: the values they render are
> generated from `tokens/*.json` and `registry/catalogue.ts` and are
> published separately at https://opsinjs.pensievelabs.org/r/index.json and under the Reference
> section.
> Nothing is missing from this page. The data simply does not live in
> the prose.

<PageTemplate kind="health" />

## What this means [#what-this-means]

The ten rules below are the short form of the Health section. Each expands into
a page that argues it in full, and together they are the source of the
[Safety review checklist](./safety-review-checklist.mdx), which is the same list
in a form a reviewer can print and tick.

A rule phrased as a principle ("be clear", "be calm", "do not alarm") passes
review by agreement, because no state of the interface contradicts it and nothing
on the screen has to change. The ten below are phrased as prohibitions with an
observable subject, so each one names a thing that must not appear and gives the
reviewer a condition to look for.

Answering the ten requires the rendered screen and nothing else: no access to the
design rationale, no access to the component source, and no conversation with the
team that built it.

## The rule [#the-rule]

**These ten prohibitions apply to every screen that displays, interprets or
collects health information about the person using it.**

<SafetyCallout severity="attention" evidence="opinion">
  Each of the ten describes a way in which a competent, attractive interface
  leads a reader to misread their own result, and the reader then makes a
  decision about their own body on the strength of that misreading.
</SafetyCallout>

### Index of the ten rules [#index-of-the-ten-rules]

| #  | Observable check on a rendered screen                                                          | What the reader could misread                                              | Evidence basis               |
| -- | ---------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------- | ---------------------------- |
| 1  | A greyscale screenshot still states the status through its icon and its word.                  | The severity of their own result.                                          | Normative: WCAG 2.2 SC 1.4.1 |
| 2  | No single element resolves a colour from both the category namespace and the status namespace. | A family colour read as a severity, or a severity colour read as a family. | Opinion                      |
| 3  | The words "normal" and "abnormal" appear in no string about the reader's own result.           | A statement about a population, taken as a statement about themselves.     | Cited                        |
| 4  | Every displayed value shows its unit, the scale it sits against, and when it was measured.     | A figure read against the wrong scale, the wrong unit or the wrong date.   | Cited                        |
| 5  | No rendered figure carries more digits than the source measurement supports.                   | The accuracy of the measurement behind the figure.                         | Cited                        |
| 6  | No trend line is drawn from fewer points than the metric's minimum window.                     | A direction the underlying data does not support.                          | Opinion                      |
| 7  | The screen carries at most one `urgent` surface.                                               | Which of the competing urgent surfaces is the one to act on.               | Opinion                      |
| 8  | With motion, sound and haptics suppressed, the urgency is still stated in words.               | The urgency itself, when no channel they receive carried it.               | Normative: WCAG 2.2 SC 2.2.2 |
| 9  | Every result carries a next step, including the step "nothing".                                | What to do next, supplied from their own guess.                            | Opinion                      |
| 10 | The collecting screen states the purpose and the route to withdraw.                            | What they agreed to, and how to stop it.                                   | Opinion                      |

### 1. Never carry clinical status in colour alone [#1-never-carry-clinical-status-in-colour-alone]

Status is carried by colour, an icon and a word together, and the combination has
to survive greyscale, protanopia and a screen read in direct sunlight. Greyscale
removes the hue difference outright, protanopia collapses part of the palette,
and direct sunlight reduces the contrast the hue depends on. The icon and the
word are the channels that survive all three conditions, and colour on its own
reaches only readers whose viewing conditions preserve the hue.
→ [The two colour axes](./two-colour-axes.mdx),
[Colour independence](../accessibility/colour-independence.mdx)

### 2. Never mix the category axis with the status axis [#2-never-mix-the-category-axis-with-the-status-axis]

A colour that identifies a metric family may not also connote severity, and a
severity colour may not identify a family. The two palettes live in separate
token namespaces, and the check at review time is that no single element resolves
a colour from both.
→ [The two colour axes](./two-colour-axes.mdx)

### 3. Never use the word "normal" for a person's own result [#3-never-use-the-word-normal-for-a-persons-own-result]

"Normal" is a statement about a population that a reader applies to themselves,
and a reader told their result is normal infers that the only other label the
interface holds is "abnormal". The replacement wordings are "in the usual range",
"above the usual range", or the range itself stated directly.
→ [Reference ranges](./reference-ranges.mdx)

### 4. Never show a number without its unit, its scale and its recency [#4-never-show-a-number-without-its-unit-its-scale-and-its-recency]

Every displayed value carries its unit, the range it sits in, and the time it was
measured. Each of the three changes what the figure means, which makes all three
part of the value rather than decoration around it.
→ [Numbers, units and precision](./numbers-units-precision.mdx),
[Uncertainty, staleness and missing data](./uncertainty-and-staleness.mdx)

### 5. Never present more precision than the measurement carries [#5-never-present-more-precision-than-the-measurement-carries]

Rendered precision asserts the accuracy of the measurement behind it. A weight
rendered as `71.4396 kg`, or a device-estimated figure printed to two decimal
places, asserts an accuracy the source does not have.
→ [Numbers, units and precision](./numbers-units-precision.mdx),
[Data provenance and device accuracy](./data-provenance-and-device-accuracy.mdx)

### 6. Never draw a trend from fewer points than the metric requires [#6-never-draw-a-trend-from-fewer-points-than-the-metric-requires]

A trend line asserts a direction, and a direction needs enough points to clear
the metric's own variability. Every metric has a minimum window below which the
line through the points is a shape the interface supplied rather than a movement
the data shows.
→ [Trends and change](./trends-and-change.mdx)

### 7. Never allow more than one `urgent` surface on a screen [#7-never-allow-more-than-one-urgent-surface-on-a-screen]

At most one surface on a screen carries the `urgent` level. The ceiling is a
budget opsinjs chose rather than a measured threshold, and it exists because a
screen on which several things are urgent gives the reader nothing to rank.
→ [Alarm fatigue](./alarm-fatigue.mdx)

### 8. Never convey urgency with motion, sound or haptics alone [#8-never-convey-urgency-with-motion-sound-or-haptics-alone]

Urgency is stated in words that survive every channel a reader may be using.
Motion is suppressed under a reduced-motion preference, a pulse outside the
viewport is never seen, and a sound or a haptic puts nothing into the
accessibility tree for a screen reader to announce.
→ [Motion in health UI](./motion-in-health-ui.mdx),
[Notifications and off-screen alerts](./notifications-and-off-screen-alerts.mdx)

### 9. Never present a result without saying what, if anything, to do [#9-never-present-a-result-without-saying-what-if-anything-to-do]

Every clinical statement carries an action slot, and the slot is filled even when
the action is "nothing, and here is when we will look again". A reader given no
next step supplies one, and what they supply is shaped by how the result made
them feel rather than by the clinical picture.
→ [Delivering difficult results](./delivering-difficult-results.mdx),
[Emergency and escalation](./emergency-and-escalation.mdx)

### 10. Never collect health data without saying what it is for and how to stop [#10-never-collect-health-data-without-saying-what-it-is-for-and-how-to-stop]

Consent is asked per purpose, is revocable in the place the data appears, and is
re-asked when the purpose changes. A single onboarding screen satisfies none of
the three, because it bundles the purposes together, sits far from the data, and
is never returned to.
→ [Consent and disclosure](./consent-and-disclosure.mdx)

## Why (evidence) [#why-evidence]

<ResearchNote evidence="mixed" date="2026-09-02">
  Rules 1 and 8 rest on normative accessibility requirements rather than on our
  preference. WCAG 2.2 success criterion 1.4.1 (Use of Colour) forbids colour
  as the only visual means of conveying information, and 2.2.2 (Pause, Stop,
  Hide) constrains moving content. Both are checkable against a published
  standard, and [Accessibility](../accessibility/index.mdx) records the method we
  test them with.

  Rules 3, 4 and 5 draw on the published work on how laypeople read test
  results. In particular they draw on the systematic review of laboratory-result
  presentation formats in JMIR (2024),
  [10.2196/53993](https://doi.org/10.2196/53993), and the earlier patient-portal
  presentation study in BMC Medical Informatics and Decision Making (2018),
  [10.1186/s12911-018-0589-7](https://doi.org/10.1186/s12911-018-0589-7).
  We cite these as the anchors for "a number needs a scale", not as proof of any
  specific visual treatment.

  Rules 2, 6, 7, 9 and 10 are **opinion**: engineering and design judgement about
  what keeps a system coherent as it grows, argued in full on the page each rule
  links to. Rule 7's "one urgent per screen" is a budget we chose rather than a
  measured threshold, and [Alarm fatigue](./alarm-fatigue.mdx) sets out the
  reasoning that produced the number.
</ResearchNote>

## Applying it [#applying-it]

<DoDont>
  <DoDont.Do>
    Run the ten as a pre-merge gate on any screen that displays, interprets or
    collects health data, and record the ten answers against the change that
    produced the screen.
  </DoDont.Do>

  <DoDont.Dont>
    Treat them as aspirations in a slide deck. A rule that is never answered
    against a rendered screen leaves no record of whether that screen met it, so
    the next reviewer starts from nothing.
  </DoDont.Dont>
</DoDont>

<DoDont>
  <DoDont.Do>
    Route the machine-expressible rules into tooling as the tooling is built.
    The axis separation in rule 2, the banned-word list in rule 3 and the
    presence of a unit in rule 4 are each specified as a lint rule
    (`opsinjs/no-mixed-axes`, `opsinjs/no-banned-word`, `opsinjs/require-unit`).
    Both plugins are specified and neither is written; see
    [Tooling](../handbook/tooling/index.mdx).
  </DoDont.Do>

  <DoDont.Dont>
    Record a rule as covered by tooling that does not exist yet. All ten are
    human questions today, and human review should be spent on the seven rules a
    machine cannot.
  </DoDont.Dont>
</DoDont>

<DoDont>
  <DoDont.Do>
    When you must break one, write down which rule, why, who agreed, and what
    compensating control you added. A recorded exception can be reopened when the
    compensating control changes.
  </DoDont.Do>

  <DoDont.Dont>
    Break one silently because the design looked better. A silent exception is
    indistinguishable from an oversight, so no later reviewer can tell which of
    the ten were considered and set aside and which were never asked.
  </DoDont.Dont>
</DoDont>

## Components that implement this [#components-that-implement-this]

{/* Generated from `implements`. Do not restate the list by hand. */}

These ten rules are why every component specification in a `health-` category
carries a Clinical meaning section. A component in that category is not
published until its specification states which of these prohibitions it enforces
and which it only permits the implementing team to honour.

## What this does not cover [#what-this-does-not-cover]

| Not covered                 | Why it sits outside this page                                                                                                                 | Whose obligation it is                                              | Where it is covered                            |
| --------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------- | ---------------------------------------------- |
| The thresholds themselves   | Which value counts as `attention` is a clinical claim about a population and a person, and opsinjs takes no position on it.                   | Yours, with whoever is clinically accountable in your organisation. |                                                |
| Clinical safety process     | Hazard logs, clinical risk management and the standards that govern them are process obligations rather than interface rules.                 | Your organisation, under its own clinical risk management process.  | [Regulatory context](./regulatory-context.mdx) |
| Clinician-facing interfaces | Several of these ten rules invert for a trained reader, for whom density and absolute values outrank reassurance.                             |                                                                     | [Who this is for](./who-this-is-for.mdx)       |
| Wording                     | These ten rules constrain what must be on screen, and the wording of the sentences is a content-design question rather than a structural one. | The Content pillar, with the product's own copy owner.              | [Content and language](../content/index.mdx)   |

## Updates to this page [#updates-to-this-page]

<Reviewed />
