Same screens, new foundation: turning Clinside's EHR into a design system
Project Overview
Clinside is a web-based electronic health record for clinics in underserved Brazilian regions. It replaces paper appointment books and disconnected tools with one synchronized agenda, patient records and consultation history, so professionals can spend less time on admin and more on patients.
The MVP shipped fast, and every screen was drawn by hand. As new modules arrived (Atendimento, Atestados, Academy, FAQ), the same button, row or field started to look different on each page. This case study is about the second chapter: turning the product's screens into a system that stays consistent, accessible and cheap to extend.
Our main goals were...
Give every role the same, predictable interface so receptionists, doctors and nurses learn it once
Make the interface readable in busy, bright clinics: accessible contrast and status that never relies on colour alone
Let designers and developers build new screens from components, not from scratch
Outcomes
Measured in the Figma files, comparing the 32 original screens with the 31 equivalent v2 screens.
text layers failing WCAG AA contrast (down from 138)
distinct button styles across the product
of fills now use semantic tokens (from 0%)
The Challenge
How might we keep a fast-growing clinical product consistent, accessible and easy to extend for people with little time and mixed technical comfort?
Drift: 17 visual button styles across the product, and 11 different corner radii
Accessibility debt: 138 text layers failed WCAG AA contrast, from about 1,000 checked
No shared language: colours pointed at a raw palette, so a brand change or dark mode meant redrawing every screen
Missing states: focus, error and disabled were designed screen by screen, or not at all
Defining my design question
Framing a system around the people who use it every day.
How might we build a component language that clinic staff can read at a glance, and that designers and engineers can ship without redrawing?
Research that shaped the system
We interviewed doctors, nurses, nutritionists, pharmacists and receptionists across 12 clinics, and turned what we heard into system requirements.
Users moved from paper appointment books, often on slow connections and shared computers. We analysed each role's tasks and workflow inefficiencies, then wrote two personas to keep decisions grounded.
Status must be scannable: receptionists need to see who arrived without reading rows, so status carries a colour, a dot and a label.
Plain language and one familiar home screen: the agenda replaces the paper book.
Professionals work across several clinics, so switching clinic must be one control, always in the same place.
The two personas that guided the product and the system
The design system
The product's interface is in Brazilian Portuguese, so the screens and the names inside the system (tokens, states, sections) stay in Portuguese. Titles and explanations are in English.
Step 1 – 32 screens, 17 button styles, 11 corner radii
The Problem This Solved
Before drawing anything, I inventoried every colour, radius, text style and button across the 32 original screens, to see what the system had to replace.
Same content and flow; only the foundation changed (original left, v2 right)
Step 2 – Tokens that carry meaning, not values
My Design Rationale
Colour, spacing and radius are variables, not values. Raw primitives feed semantic tokens (bg/brand, text/secondary, border/input), and components may only use the semantic layer. Typography is 13 Inter styles on a 4px rhythm.
Foundations: colour tokens, type scale, spacing and radii
Why I Made This Decision
Status colours also had to work for people who can't rely on colour. Each status (Confirmado, Chegou, Aguardando, Cancelado) pairs a dot, a label and a tested contrast ratio of at least 4.9:1.
Contrast tested against WCAG AA for status and text tokens
Step 3 – 25 components, every state designed
My Design Rationale
The library has 25 components and 134 variants, in three layers: basics (Icon, Avatar, Status Badge, Alert, Empty State), actions and forms (Button, Input, Checkbox, Radio, Textarea, Toggle, Segment), and Clinside product components (Nav Item, Stat Card, Appointment Row, Chat Bubble, Sidebar, Clinical Field, Course Card, and more). Every interactive component has default, hover, focus and disabled states, and form fields add an error state.
The component library, grouped from basics to product components
Anatomy of Button: every property maps to a token
Anatomy of Input: label, help text and four states
Step 4 – Change a Button once, update every screen
The Problem This Solved
Product components are assembled from basics, so a change to Button or Status Badge flows into every Appointment Row. A single dashboard screen is just eight components, with their counts documented.
Anatomy of Appointment Row: Status Badge, Button and text styles composed
One screen, broken into the components that build it
Dark mode came from switching one variable mode, with no screen redrawn
The system in the product
The same components power very different screens, which is what keeps the product learnable.
Agenda and patients
The agenda is the home of the product and replaces the paper book. Weekly view, Mês/Semana/Dia segments and patient lists reuse Segment, Table Cell and Table Action, with consistent focus states.
From the agenda to a patient's history and into a consultation, with the same sidebar and components on every page
Clinical notes
Atendimento's long forms are built from Clinical Field, which pairs a label, a "Não possui" checkbox and a single or multi-line field. Doctors can skip empty sections in one tap, and validation looks the same on every step.
Atendimento step by step: every tab, field and button comes from the same components
Learning and help
New modules were assembled from existing parts: Clinside Academy uses Course Card and Nav Item, and the FAQ uses Accordion Item and Button, inside the same sidebar and top bar.
Academy and FAQ, built from existing components without new patterns
Results
Measured layer by layer in Figma, comparing the original screens with the v2 screens (new screens excluded).
What hasn't improved yet: typographic combinations rose from 15 to 18, because the new styles fix line height and some older screens still mix off-scale sizes. The next step is migrating those texts to the 13 shared styles.
My Takeaways
Measure the starting point
The audit turned "the UI feels inconsistent" into numbers (17 button styles, 138 failing texts), which made priorities, and later results, easy to agree on.
Semantic tokens pay off twice
Using meaning-based tokens gave us dark mode almost for free and made accessibility fixes a one-place change instead of a hunt through every screen.
Systems need partners
Close communication with developers and clinical stakeholders kept components feasible and relevant. User testing still drove the product itself, such as simplifying how patient data is shown.