Calm screens for
serious work.
How Novis looks, reads, moves and keeps patients safe. The visual language takes the warm paper surfaces and single-accent restraint of the Paper Widgets study. The workflow patterns come from a review of the Transom clinic app: patient context always in view, checks before anything is sent, and AI that shows its sources.
Seven rules every screen follows
When two options both look fine, pick the one that keeps more of these true.
The patient is always in view
Every clinical screen carries the patient banner: name, age, MRN, allergies and where they are in the visit. Allergies and critical flags are never behind a click.
Check before it leaves
Orders, prescriptions and bookings show their safety checks next to the form, with the fix one click away. The send button stays disabled until every blocking check passes or a clinician overrides it with a reason.
AI drafts, clinicians decide
AI text is always marked, cites its sources line by line and never enters the chart until a person accepts it. Every draft is logged.
One next step
Each screen has a single primary action, top right and bottom right. Secondary actions are quiet. Show the next thing to do, not every option.
Colour means something
Paper and ink carry the interface. Sea blue means "act", iris means "AI", and green, amber and red mean clinical status. Nothing else gets colour.
Plain language
Short sentences, real names, real times. Write "Results by about 4 PM", not "TAT: 240 min". Anything a patient will read gets a patient-language preview.
Never lose work
Autosave everything and say when ("Saved as draft at 11:26 AM"). Undo beats confirm dialogs, except for actions that leave the clinic: sending, signing, billing.
Colour, type, space and shape
All values live in novis-ui.css as --n-* tokens. Screens never use raw hex values or pixel sizes outside the scale.
Colour roles
| Role | Token | Use for | Never for |
|---|---|---|---|
| Canvas | --n-canvas | App background behind panels | Inputs or cards |
| Paper | --n-paper | Panels, tiles, cards | Full-bleed backgrounds |
| Ink / Nav | --n-ink --n-nav | Headings, names, key values; the left navigation | Buttons (navy buttons read as disabled next to sea) |
| Action | --n-action | Primary buttons, links, focus rings, the current step, selected rows | Status, decoration |
| AI (iris) | --n-ai | AI buttons, AI drafts, citations, AI activity | Anything a person wrote |
| Brand gold | --n-gold | The logo, the active nav marker, marketing | Status or warnings (it would read as "abnormal") |
| Normal | --n-ok | In range, passed, done, signed | "Go" buttons |
| Abnormal | --n-warn | Out of range, missing, waiting too long, needs action | Brand accents |
| Critical | --n-crit | Allergies, critical values, conflicts, errors, destructive actions | Anything that isn't urgent |
The Paper Widgets rule, adapted: one accent per job. On any screen, colour has to be the action, AI or a status. If it's none of those, it's ink on paper.
Type
2xl 36/40 · 30048 arrivals
xl 24/32 · 600James Holloway
lg 20/28 · 600Front desk
md 16/24 · 600History of present illness
base 14/20 · 400Take one tablet by mouth every night at bedtime.
sm 13/18 · 400Saved as draft at 11:26 AM
eyebrow 11 · JostBefore you sign
Inter for the whole product, with tabular figures so vitals, doses and times line up. Jost appears only in the small capitals of section labels. Fraunces is for marketing and the guide, never for the app. Dashboard numbers are light (300) and calm. Patient values are semibold (600) because they have to be read correctly the first time.
Space, shape and depth
4 px grid
4 · 8 · 12 · 16 · 20 · 24 · 32 · 40 · 48. Panels pad 20, tiles 20–24, rows 12. Gaps between panels are 16.
Radius by size
8 for controls and chips, 12 for inner cards and rows, 18 for panels, 24 for dashboard tiles, pills fully round. A child's radius is always smaller than its parent's.
Paper depth
Panels use a 1 px hairline ring, a white top edge and a long soft shadow (--n-shadow-panel). Only popovers and modals float higher (--n-shadow-pop). No borders and shadows on the same thing.
The shell, the banner and the three columns
Clinical work happens in one repeatable frame: navigation on the left, the patient banner and visit stepper on top, then the work in three columns. Steps on the left, the task in the middle, context on the right.
Under 1280 px the context rail folds into a drawer. Under 960 px the steps column becomes a dropdown. The patient banner never collapses below name + allergies + MRN.
Patient banner and visit stepper
Each step shows who or when, not just a check mark. The current step uses the action colour, done steps use green. The stepper is also navigation: clicking a step returns to it.
The parts list
Everything below is rendered from novis-ui.css. Copy the class names, not the pixels.
Buttons
One primary per view. Labels are verbs plus objects ("Add to orders", not "OK"). Disabled buttons always say why nearby, e.g. "Resolve 1 flag to insert".
Fields and controls
R07.89Other chest painI10Essential hypertensionStatus pills are always a dot plus a word, so they still work without colour. Chips hold values the user can add or remove, such as diagnoses and symptoms. Codes go in the chip, the plain name next to them.
Numbers: dashboard tiles and vitals
Dashboard tiles use a quiet light numeral, a delta and a dot-matrix trend, one colour per metric. Vitals use a firm numeral and a range bar where the green band is the normal range. Out-of-range vitals tint the whole card amber and add "above range" to the panel header. Colour is never the only signal.
Lists and loading
| Time | Patient | Clinician | Status |
|---|---|---|---|
| 10:30 AM | James Holloway | Dr. Olivia Bennett | Arrived 10:41 |
| 11:00 AM | Layla Haddad | Dr. Sophia Carter | Double booked |
| 11:30 AM | Carlos Mendoza | Dr. Daniel Park | Intake missing |
Skeletons match the shape of what's coming. Show them after 300 ms, never for clinical values that are being re-checked. Those keep the last value with an "Updating…" label.
Make the safe path the easy path
An EMR's interface is part of patient safety. These patterns are required wherever they apply.
Rules
- Checks sit beside the form, not after it. Show each check as passed, needs action or blocked, with its reason and the fix as a button.
- Conflicts offer the way out. A clash, double booking or interaction always comes with alternatives (open times, a substitute drug) and who can override.
- Overrides need a reason and are logged with the clinician's name and time.
- Allergies follow the patient into every order, banner and printout. Severity is a word ("High"), not just red.
- Say what happens next. Before signing, list where everything goes: "Pike Street Pharmacy, sent at once · Clinic lab, 2nd floor · James's portal, plain language".
- Show cost before commit when the patient pays: tier, estimate, cheaper options.
- Confirm only what leaves the building. Sending, signing, billing and cancelling confirm. Everything else autosaves and can be undone.
AI that shows its work
AI can draft notes, summaries and replies, always as a suggestion with sources. The clinician stays the author.
James is a 58-year-old man referred by Dr. Karen Liu for chest tightness on exertion for 3 weeks [1]. It starts after climbing stairs and eases within about 5 minutes of rest [2]. No radiation to the arm or jaw. He takes Cardivex 10 mg each morning [3].
…three weeks of chest tightness with exertion, please evaluate…
Tight chest going up stairs, better after resting about 5 minutes.
Cardivex 10 mg, once daily, started 09/14/2026
Rules
- Iris marks AI, everywhere. AI buttons, drafts, pills and citations use
--n-ai. Nothing a person wrote uses it. - Nothing enters the chart until a person accepts it. Drafts sit in a dashed (running) or solid (ready) iris frame outside the note until accepted.
- Every line cites a source from this chart. Lines without a source are underlined and block "Insert" until confirmed or removed.
- Show what was read and what was left out, and say the draft uses only this chart, not outside data.
- Show progress honestly: the steps being run, an estimated time, and a "Stop drafting" button.
- Keep the history. Accepted text keeps tracked changes (AI text vs. clinician edits) and is logged in AI activity: who reviewed it, how long it took, how much was changed.
- Never auto-send. AI may draft a patient message. Only a person sends it.
The core flows
The first screens to build, in visit order. Each one uses the shell above, so a clinician who has learned one already knows the rest.
| Flow | Main view | Primary action | Must show |
|---|---|---|---|
| Front desk | Today's KPI tiles, arrivals list (Upcoming / In clinic / Completed / All), arrivals by hour, open slots | Check in | Search by name, DOB, phone or MRN; double booked and intake missing flags |
| Check-in | Side sheet: identity, insurance, intake, consent; copay; where to send the patient | Check in and send to waiting area | Each item with status and time; payment method; who rooms the patient next |
| Waiting room | Board with columns: Waiting · Rooming · With clinician · Checkout | Room patient | Minutes waiting, turning amber past the clinic's threshold |
| Scheduling | Week strip, day column with booked, held, blocked and open time; booking form on the right | Book appointment | Conflicts inline with open times that fit; coverage, referral and intake checks; waitlist |
| Rooming | Vitals grid with range bars, chief complaint and intake, med reconciliation, allergies, room checklist | Ready for the clinician | Out-of-range count; repeat-reading reminders; "notify when ready" toggle |
| Chart overview | Tabs: Overview · Timeline · Encounters · Medications · Labs · Documents · Billing | Start encounter | Vitals trends, reason for referral with files, clinical summary, problems, care gaps |
| Visit note | Sections with progress (left), editor with Write / Structured (middle), pinned patient context (right) | Continue to orders | Before-you-sign checklist, shortcuts, autosave, AI draft per section |
| Orders | Orders for this visit (left), the order form (middle), checks before sending + cost (right) | Add to orders → Review and sign | Allergy and interaction checks, linked diagnoses, patient instructions in plain language, where each order goes |
| Sign and close | Summary of note, orders, follow-up and billing codes | Sign and close visit | Anything unsigned or unresolved, with links back to fix it |
| Dashboards | KPI tiles, tables, outcome breakdowns (including AI activity) | Export | Date range, filters, the time the data was last updated |
Write like a good charge nurse
Clear, calm, specific. Use the patient's first name in staff-facing tips ("Ask James to tap his card"). Use full names in lists and records.
| Instead of | Write | Why |
|---|---|---|
| Error 409: slot conflict | Overlaps Samuel Adeyemi, 11:30 AM | Say what clashed and with whom |
| Submit | Add to orders | Verb plus object |
| TAT 240 min | Results today by about 4 PM | Real times, plain words |
| Are you sure? | Send to Pike Street Pharmacy now? | Name the consequence |
| Invalid input | Enter a dose, for example "1 tablet" | Say how to fix it |
| No data | No lipid panel in the last 12 months | Empty states say what's missing and why it matters |
| AI-generated content may be inaccurate | 1 line has no source. Confirm it with James or remove it. | A specific flag beats a generic disclaimer |
Numbers
Units always ("148/92 mmHg"). 12-hour times with AM/PM. Dates as "Tue, Oct 27". Durations as "45 min" and "3 h". Money as "$40.00", or "about $10" for estimates.
Case
Sentence case for everything, including buttons and titles. Small capitals only for section eyebrows.
Patient-facing text
Grade 6 reading level, second person, no abbreviations. Always preview it as the patient will see it.
Motion explains, then gets out of the way
Borrowed from Paper Widgets: every motion is an eased slice of time with exact numbers, tiles rise in one after another, and reduced-motion users get the finished state. In a clinical tool, motion stays short and never plays on patient values.
Timing
| Moment | Duration | Easing | Movement |
|---|---|---|---|
| Press (buttons, switches) | 120 ms | cubic out | scale 0.97 |
| Hover, state change, colour | 200 ms | cubic out | colour only |
| Enter (popover, toast, row) | 320 ms | cubic out | opacity 0 → 1, rise 8 px |
| Panel, drawer, side sheet | 480 ms | cubic in-out | slide from the edge it lives on |
| Dashboard tiles on first load | 650 ms, +80 ms per tile | cubic out | opacity, rise 22 px, scale 0.955 → 1 (the Paper Widgets entry) |
| Dashboard numbers | 1.2 s | cubic out | count up once on load. Never on refresh. |
| Charts and bars | 600 ms, +80 ms per bar | back out (1.5) | grow from the baseline |
| List roll / reorder | 600 ms | cubic in-out | slide one row; fade the row leaving and the row arriving |
- Never animate patient values. Vitals, doses, results and allergies appear instantly and stay still. Count-ups are for dashboards only.
- Motion follows cause. A drawer slides from the side it lives on. A new row appears where it lands. Nothing moves without a cause.
- Reduced motion: with
prefers-reduced-motion: reduce, show the end state immediately, with no transitions and no shimmer. - Write motion as numbers. Durations and easings come from
--n-dur-*and--n-ease-*, so a whole screen can be retimed from one file.
Done when
Borrowed from Paper Widgets' "Done when" list: a screen ships only when every box below can be ticked.
- The patient banner shows name, age, MRN and allergies at every width
- There is exactly one primary button, and its label is a verb plus an object
- Body text meets WCAG AA (4.5:1); icons and borders meet 3:1
- Status is a word or icon as well as a colour
- Every action works from the keyboard, with a visible focus ring
- Common actions have a shortcut, listed in the left column
- Targets are 36 px on desktop and 44 px on touch and kiosk screens
- Blocking checks disable send, and the reason is shown next to the button
- Autosave state is visible, and nothing is lost on refresh
- AI text is iris-framed, sourced line by line and not in the chart until accepted
- Empty, loading and error states are designed and written
- Live changes (waiting room, AI progress) are announced with
aria-live="polite" - Patient values never animate; reduced motion shows final states
- Light mode is the default; dark mode only through the user's toggle
- It works at 1440, 1280, 1024 and 768 px wide with no horizontal scroll
- Times, units and names follow the voice rules
Files
guidelines/novis-ui.cssTokens (--n-*) and the base components shown on this pageguidelines/NOVIS-UI-SPEC.mdThe same rules as a build prompt for coding agents: stack, tokens, layout, components, motion and "Done when"brand/Logo, colours and type: the brand kit