Skip to content

Design System

Decided 2026-10-12. This page is the source of truth for how every screen looks and reads: the home page, the therapist and patient web portals, and both sides of the phone app. The values live in code (OktaPT-FE/tailwind.config.js, Okta-Mobile/lib/theme.ts); this page says what they mean and how to use them. Change the code and this page together.

How to use this page

Every screen is judged against three priorities in this order: simple, then warm, then professional. When two pull apart, the earlier one wins.

Priority What it means on a screen What it rules out
1. Simple One job per screen, one primary action, the fewest words that still say it. Good defaults instead of settings. Dense toolbars, nested menus, decorative chrome, two accent colors on one screen
2. Warm Soft off-white surfaces, warm neutrals, rounded shapes, plain friendly language, real people in photos. Cold grays, pure black text, sharp corners, clinical jargon
3. Professional Precise numbers, consistent alignment, legible at a glance, calm motion. Nothing that reads as a toy. Gradients for their own sake, bouncy motion, emoji in the interface, playful illustration

A screen that needs something this page does not cover gets a line added here before it ships, not a one-off style.

Foundations

Warm paper, white cards with hairlines, one accent, green only for done.

Color

Token Value Where it goes Web class App key
paper #FAFAF9 Screen background (a stronger cream, #F7F4F2, was tried on 2026-10-12 and read as too tinted) bg-paper colors.paper
paper-muted #F5F5F4 Segmented tracks, icon tiles, skeletons, neutral chips bg-paper-muted colors.paperMuted
card #FFFFFF Cards, rows, sheets, inputs bg-card colors.card
line #E7E5E4 Hairline borders and dividers border-line, divide-line colors.line
ink #1C1917 Titles and body text-ink colors.ink
ink-2 #57534E Secondary text, meta lines text-ink-2 colors.ink2
ink-3 #A8A29E Placeholders, disabled text, chevrons text-ink-3 colors.ink3
accent #2563EB (the logo blue; a clinic deployment may override it on the web) Primary buttons, links, selection, the active tab, focus rings bg-accent, text-accent, ring-accent colors.accent
accent-strong #1D4ED8 Hover and pressed hover:bg-accent-strong colors.accentStrong
accent-soft #EFF6FF Selected rows, icon tiles, the "seeing today" pill bg-accent-soft colors.accentSoft
good fill #10B981, text #047857, tint #ECFDF5 Done, on track, success bg-good, text-good-strong, bg-good-soft colors.good, goodStrong, goodSoft
attention fill #F59E0B, text #B45309, tint #FFFBEB Overdue, needs review, a warning bg-attention, text-attention-strong, bg-attention-soft colors.attention, attentionStrong, attentionSoft
problem fill #DC2626, text #B91C1C, tint #FEF2F2 Errors, destructive actions, a flag bg-problem, text-problem-strong, bg-problem-soft colors.problem, problemStrong, problemSoft
scrim ink at 60 % (rgba(28, 25, 23, 0.6)) A small badge on a picture, such as the play button on an exercise's photo (app only so far) colors.scrim

On the web, gray-* classes map to Tailwind's warm stone scale, so existing code is already on the warm neutrals; new code uses the named tokens above. The brand-* classes remain the per-deployment accent scale (--brand-500 is the tenant's primary colour from GET /v2/branding/theme, default #2563EB); accent is an alias of it. In the app the accent is static for now; per-clinic accents in the app are a later step.

Status mapping: compliance grades A+, A and B are good, C and D attention, F problem, no grade neutral (paper-muted on ink-2). Streak days: done is good, a rest day neutral, a missed day attention, never problem. Pain and exertion ratings use the same three steps. Never more than one status color in a row.

Leaderboard tiers (Starter to Platinum) are neutral chips in Label text, never a status color; four Gold weeks in a row add a small outline trophy to the chip. A board's podium is three cards with the place as the one big number, the first a little taller, names on up to two lines and one short fact under the points ("3 of 3", "14 patients") rather than a cut-off sentence; the viewer's own row is accent-soft and its sentence is read whole, and nothing on a board uses green, since nothing on it is "done".

No dark mode for now; the names allow it later without renaming anything.

Type

Nunito everywhere, the face the web already had: self-hosted through next/font on the web (pages/_app.tsx, Latin and Cyrillic subsets), assets/fonts/nunito in the app, registered in app/_layout.tsx and picked per weight through fonts.* in lib/theme.ts. Six roles; no pixel size outside this table.

Role Web size / line App size / line Weight Use Web class App key
Display 36 / 40 34 / 40 800 The one big number on a screen: minutes, sessions, days text-display type.display
Title 24 / 32 28 / 34 700 Screen title text-title type.title
Heading 18 / 26 18 / 24 700 Card title, section heading text-heading type.heading
Body 15 / 22 16 / 22 500 Rows, paragraphs, buttons (600 for a row's name and button labels) text-body type.body, type.bodyStrong
Meta 13 / 18 13 / 18 500 Second line of a row, dates text-meta type.meta
Label 12 / 16 12 / 16 600 Chips, captions, table headers, in sentence case text-label type.label

Spacing

Steps of 4: 4, 8, 12, 16, 24, 32, 48 (space.xs to space.xxxl in the app; Tailwind's own scale on the web). Gutter 16 on phones, 24 on desktop. Rows 8 apart, blocks 24 apart. Card padding 16, or 12 on rows with a 44 px avatar. Every tap target is at least 44 px (hit.min); primary buttons are 52 on touch screens (hit.primary) and 44 on desktop.

Shape

Radius Where Web class App key
8 Thumbnails inside rows, small controls rounded-lg radius.sm
12 Inputs, buttons, menus rounded-control radius.control
16 Cards, rows, icon tiles rounded-card radius.card
24 Sheets and hero cards rounded-sheet radius.sheet
Pill Chips, segmented controls, the tab bar, avatars rounded-full radius.pill

Elevation

Cards and rows are flat: card white on paper with a 1 px line. One shadow exists, for things that float (menus, the tab bar, toasts): offset 0 4, blur 12, #1C1917 at 8 percent (shadow-float, shadow.float). Dialog backdrops are #1C1917 at 40 percent (colors.backdrop).

Motion

150 ms in, 200 ms out, ease-out, no bounce. Pressing scales to 0.98 with a light haptic in the app. Sheets slide up in 240 ms. Reduced motion turns all of it off except opacity. (motion.* in the app.)

The one exception is finishing a session (decision 12). The app celebrates it once, the same way however the session was finished: a thin ring in the done colour pulses out of the point of completion and a burst of confetti in accent, good and attention rises and falls for 1.2 s (motion.celebrate), the check on a done view pops in with a small overshoot, and the phone plays the celebration rhythm: a firm tap, the success chime, then two soft taps as the pieces land. It lies over the screen without catching touches and says nothing to screen readers. Reduced motion keeps the haptics and skips the burst. Nothing else gets confetti, and new motion stays calm. (SessionCelebration, CelebrationCheck and hapticCelebrate() in the app.)

Icons and imagery

Outline sets only: Heroicons 24 outline on the web, Ionicons outline in the app. 20 px inline, 24 px in bars, filled only for the active tab. No emoji as icons: the streak uses a flame icon, warnings a warning icon. Photos of real people belong on the home page; product screens use the patient's own exercise thumbnails and icons, not illustrations. AI-written content is never marked with a sparkle or star icon; say it in words.

Components

These parts cover every screen. Each exists once per platform; a screen that needs a variant adds a prop, not a copy.

Component Looks like Rules
Button, primary Accent fill, white Body text, radius 12, 44 tall on desktop and 52 on touch screens One per screen. Loading swaps the label for a spinner and keeps the width
Button, secondary Card fill, 1 px line, ink text, same size Pairs with a primary; never two secondaries alone
Button, text Accent text, no box Cancel, See all, Skip
Button, destructive Problem text, outlined; filled only inside a confirm dialog Always behind a confirm step
Card Card fill, radius 16, 1 px line, padding 16, no shadow Heading at the top, one action at most, never a card inside a card
Row 44 avatar or 48 thumbnail (radius 8), name Body 600, Meta line, right slot for a chip or chevron; at least 64 tall 8 px between rows, one fact per line
Suggested request A full-width button for a request the person is likely to make next: card fill, 1 px line, a name and a reason line. Web: radius 12, at least 44 tall, Meta 600 label over a Meta ink-2 reason, both wrapping. App: a Row (Body 600 name, Meta line, chevron), two lines each Before the person types, in an assistant's empty state; a tap sends the request as if typed. Up to five on the web, three in the app sheet; skeleton rows while the first list loads, the previous list dimmed and disabled while a fresh one comes. Never pills, never marked as AI
Media row A row whose picture fills its left edge, 96 by 72 (the card's radius clips it; a paper-muted tile with an icon when there is none), then name Body 600, the dose in Meta, at most two neutral chips, a one-line note; a 44 px trash (ink-2) or chevron column at the right For lists a therapist edits exercise by exercise (the HEP editor in the app). The picture is read first, so nothing covers it: a 24 px scrim badge (play, expand; problem red for a failed video) sits 8 px into its corner
Chip Pill, Label text, tint fill and text from one status family; neutral is paper-muted on ink-2 At most one status color per row
Input and search Card fill, 1 px line, radius 12, 44 tall (48 in the app), placeholder ink-3, 2 px accent ring on focus Search gets a leading icon and a clear button. A value filled in by AI stays marked, accent line on accent-soft, until the person edits it or saves
File drop (web) Dashed 1 px line on paper, outline icon in ink-3, a "choose files" link in accent; accent line on accent-soft while a file is over it Says which files it takes and that pasting works too
Segmented control Paper-muted track, radius 12, padding 3; active segment card white, radius 9, soft shadow; Label 600 Two or three views, never a navigation; four only for parallel rankings of the same thing (the therapist leaderboard), where labels stay whole and the track scrolls sideways when they do not fit (scrollable in the app)
Choice tiles (app) Two tiles side by side under a Body 600 question: card fill, 1 px line, radius 12, at least 52 tall, outline icon and Body 600 label; the chosen one accent line on accent-soft with accent text; a Meta hint underneath that turns problem-strong when the answer is missing A required either-or question inside a form (who a new video is for), answered in one tap; no default, so the hint says what to choose
Question card (app) A card in a sheet's footer, in place of its primary button: Heading question, one Meta line, then a primary and a secondary button A one-time question before an action goes through (the HEP picker's "Is this video for {Name} only?"); the action runs once it is answered
Tabs (web) Underline tabs, accent for the active one Sections within a page; never on the same screen as a segmented control
Toolbar tabs (web) The segmented track at toolbar height: paper-muted, radius 12, padding 3, 44 tall; active tab card white, radius 9, soft shadow, accent text; Body 600 A page's tabs at the head of a toolbar of 44 px controls (the exercise library: All, My private, Favorites). A view toggle in that toolbar takes the same track, icon only, each button named by a tooltip and an accessibility label
Sheet App: from the bottom, top radius 24, 36 by 4 handle in line color, 40 percent backdrop. Web: bottom sheet on phones, centered radius 16 on desktop. A work surface where a plan or a template is put together (the plan builder, the template editor) fills the screen on desktop too: a compact header over a hairline (the title level with the close button) and a compact footer One sheet component per platform; no hand-made overlays
Empty state Icon 48 in ink-3, Heading, one Meta line, one primary button Says what will appear here
Loading Skeleton rows in paper-muted with a shimmer; spinner only inside a button Never a full-screen spinner over existing content
Toast Card fill, radius 12, floating shadow, status icon, gone after 3 s One at a time, bottom on phones
Notice Next to a form, radius 12, padding 12, a 20 status icon then the text. Error: problem-soft fill, problem-strong text. Info: accent-soft fill (an accent text button on it keeps 4.5:1), accent icon Says what happened and what to do next. May carry one text button as that next step and never two: after a refused email sign-in the "Forgot password?" link gives way to the notice "Did you forget your password?" with Reset password, and the reset sheet opens on the email already typed (FormNotice with action in the app, ForgotPasswordPrompt on the web)
Stat tile Label in ink-2 over a Display or Heading value with a small unit Three per row at most
Progress Ring, 6 px stroke, accent on paper-muted, for one completion; bar 8 px pill for a timeline; done turns good green One progress element per card
Table (web desktop) Header Label in ink-2 on paper-muted, sentence case; rows 56 tall with hairlines; hover paper Switches to Rows under 768 px
Set log One header row of Labels in ink-2 (Set, Reps or Seconds, the weight unit) over one line per set with hairlines: the set number, number boxes (Input, 44 tall on the web and 48 in the app, up to 96 wide) and a 44 round tick, card with an ink-3 ring, good-strong when done; a done set's boxes tint good-soft Labels once, never repeated on each line. The plan shows in ink-3 inside the boxes of sets not done yet, what was entered in ink; an empty box on a done set reads "—". The grey weight in an empty box is the therapist's weight for that set, else a weight present in a set above, else the same set's weight last time. Under the dose, a Meta line in ink-2 with an outline clock (ink-3) says the last logged result, "Last: 4 × 5 · 35 lbs", with the day after 30 days and always for the therapist ("Last, Oct 24: …")
Avatar Pill; initials Body 600 on accent-soft for patients and paper-muted for staff; photo when there is one 44 in rows, 36 in lists of staff
Tab bar (app) Floating pill, 64 tall, one accent for every tab, Label text under each icon Accessibility label on every tab
Top bar (app) 44 px back target, Title left or Body 600 centered One right-side action at most
Provider sign-in (app) Above a sign-in or sign-up form: Apple's own button on iOS (the system draws it; white outline, radius 12, 52 tall), then Google as a secondary button with the Google mark, then an "or" hairline Only where an account is signed in or created; a provider's brand color never becomes the screen's; a build without a provider draws nothing
Provider sign-in (web) Above a sign-in or sign-up form: Sign in with Apple as a secondary button (white, hairline, radius 12, 44 tall) with the Apple mark, then Google's own button (Google draws it: outline, large, 40 tall with its own corners), then an "or" hairline Only where the site offers them; never the primary button; Google's button cannot be restyled, so nothing else is matched to it; a site without a provider, or with Google's script blocked and no Apple, draws nothing (no lone "or" line)

Patterns by surface

The same tokens everywhere; what changes per surface is density and the one job each screen has.

  • Home page. The marketing pages have their own palette and display face, below. Cards with a 1 px ring, buttons with the 12 px radius, one primary call to action per section; accent only on links and that button.
  • Therapist web. Dense but calm. The dashboard is a Table on desktop and Rows on phones, with one primary action at the top right (Add patient). Status lives in Chips; sub-tabs are plain tabs with counts, not colors. The patient popup stays a Sheet with tabs.
  • Patient web. The patient app, larger: today's plan as a Card with one Start button and a progress ring, history as Rows. The player stays full screen.
  • Doctor app. The reference the system grew from. Keep its structure (hairline rows, 8 px gaps, 44 px targets, one fact per line) and use the tokens: paper, line, accent. No hand-rolled buttons. The HEP editor's week is slim day headings on the paper (Heading date, Meta session and count, the focus on its own Meta line, a text Add and a quiet more button) over Media rows, 24 px between days. A Program row is a card whose top section has the picture at the left (120 wide, 104 under 390 px) beside the name, a strip of day dots and a dose chip (paper-muted, Meta in ink; accent-soft with accent text while open). The strip keeps every session on one row: dots are 20 px for a normal week and shrink for more sessions, a day's sessions sit 1 px apart and the days 4 px; below 16 px the letters drop and empty dots take the line colour. Under the top section, one at a time, the strip unfolds a sideways-scrolling row of 36 px preset chips (paper-muted, the current one accent-filled), with 44 px tall day chips for Custom, and the dose chip unfolds the full-size steppers; the note runs across the card below, behind a hairline. The presets and the dose are choice chips, not pill buttons (decision 4), and each is a 44 px target.
  • Patient app. The doctor app's Card and Row for the workout, visit and screening cards. One accent across messages, history and profile. The streak uses an icon. The tab bar has one accent and labels.
  • Admin. Internal; swaps blue-600 for the accent and keeps its kit.
  • Email. One layout for every email (OktaPT-API/src/services/notifications/templates/layout.ts, decided 2026-10-17): the brand name in ink above a white card with a 1 px line and radius 16 on paper, 560 px wide, no logo image, gradient or shadow. Nunito where the reader has it, the system font otherwise; no web font is fetched. Inside: one Title, the greeting, body text, at most one accent button (the second action a secondary button), a paper-muted panel for the thing to notice, hairline rows for exercises, Meta lines for what a link does and how long it works; under the card, a Meta line on why the person got it. Wording, brand and language rules and the list of emails: Transactional emails.

Marketing pages

The home page, Pricing, Team, Careers and Contact (both brands) and the footer, approved on 2026-10-13. They stay simple and professional but carry more warmth than the product: a photo of real-looking people (AI-generated, no real person), a serif display face and a little colour. None of this is used inside the product.

Token Value Where it goes Web class
marketing-paper #F4F7FC Every other section's background: paper with a hint of the logo blue bg-marketing-paper
marketing-tint #E9EEF8 Icon tiles, chips and tracks inside the product mocks bg-marketing-tint
marketing-wash #F7F9FD The lightest fill inside cards and mocks bg-marketing-wash
marketing-stage #EEF2FA The flat stage behind a section's product visual bg-marketing-stage
marketing-line #DDE5F4 Hairlines on the tinted paper bg-marketing-line
marketing-navy #0B1739 Dark panels: the AI band, the closing call to action, the highlighted plan, the footer bg-marketing-navy
marketing-sunrise #FFF6EC The top of the warm wash over every hero, fading to white from-marketing-sunrise to-white/0
marketing-ember #9A5A2A The warm shadow under the hero photo, at 20 percent shadow-marketing-ember/20
  • Type. Headlines (the hero, section titles and big figures) use Lora 400 through next/font (components/landing/shared/displayFont.ts), sized from Tailwind's scale (4xl to 7xl), with balanced wrapping (text-balance) so no line is left holding one word; subtitles use text-pretty. Body text stays Nunito.
  • Imagery. One family of soft clay-style illustrations (AI-generated, on a plain colour, no text) on the platform cards, the loop, the onboarding steps, the AI band and the compliance strip. Product visuals are text-built mocks with fictional people, so they translate and show no patient.
  • No pastel glows on light surfaces. Warmth comes from the sunrise wash, the photos and the clay art; radial glows live only on navy. Solid warm blocks behind images read as orange and were dropped.
  • Eyebrows only where a title alone would not say who a section is for (the owner and therapist sections).

Narrow screens

Every screen is checked at 360 and 390 px, at 768, and at 1024 to 1920 on desktop, in English and Russian (Russian labels run about a fifth longer).

  • Text keeps the width. When a card or bar has text and a button, the button goes under the text on phones, full width, instead of squeezing the text into a narrow column beside it. Side by side is for sm and up.
  • Labels never wrap. Buttons, tabs, nav links and segmented controls keep their label on one line. Two buttons in a row share it evenly and drop their icons on phones; a row of tabs scrolls sideways rather than pushing the page wider than the screen.
  • The desktop header gives way in steps. When the nav doesn't fit, its links drop their icons first, then the menu button stands in for the whole nav, as on a tablet.
  • Tabs and their toolbar share a line only when both fit. Otherwise the toolbar drops under the tabs as one row; a tab is never cut off and a control never wraps onto a second line.
  • Tables lose a column, not their actions. Between 768 and 1024 px a table hides its least needed column so the actions stay on screen.
  • Short windows keep the list. Under 900 px of height (short: in Tailwind, stacked as short:md:; a 13–14" laptop with the browser's bars and a taskbar) a sheet that holds a list takes almost the whole window (the plan builder and the template editor fill it at any height). In an exercise picker only the search box stays pinned; the scope buttons, the tag filter, the chosen tags and the AI results line scroll away with the cards, so two rows of cards stay in view. The AI results line is one line: "AI: “knee” · 10" with a small ×, the query cut short when long.

Voice and writing

Write the way a good therapist talks in the room: short, concrete, kind. Patients get everyday words; therapists get clinical terms where they are faster (ROM, RTM, HEP), never where a plain word does the same job.

Rule Say Not
Buttons are verbs, one or two words Start, Mark done, Send, Add patient Submit, OK, Click here to continue
Titles say what the screen is for the person reading it Your plan for today, Patients to review Assigned HEP, Dashboard
One warm line at a milestone, none in between Nice work. That is five days in a row. Awesome!!! You crushed it!
Errors say what happened and what to do next The video did not upload. Check your connection and try again. Error 500, Something went wrong
Empty states name what will appear and offer the one action No patients yet. Add your first patient. Nothing to show
Numbers carry a unit, in words a person uses 12 min, 3 of 5 done, 110 degrees 00:12:00, 60%, 110° ROM
Weights use the clinic's unit: kg on OKTA, lbs on OTERA, kept with the number on one line 16 kg, 35 lbs, 2,5 кг 16, 35 lb on an OKTA screen
Exclamation marks: at most one per screen, only for a result the person earned Workout complete! Hello Patient!

AI-written content is labelled in words next to it ("Written by AI from the visit captions") and reviewed by the therapist before a patient sees it. Every string ships in English and Russian together; Russian uses the formal "вы" everywhere.

Decisions

The first eleven were made on 2026-10-12, the twelfth on 2026-10-16. Reopen one by changing the code and this page together, with the reason in the changelog.

# Decision Outcome
1 The accent The logo blue #2563EB on web and app; the app's emerald is the "done" color only
2 Neutrals Near-white paper #FAFAF9, line #E7E5E4, stone inks; web gray-* aliased to stone. The cream #F7F4F2 was tried and rejected the same day as too tinted
3 Typeface Nunito on both platforms, one six-step scale. Manrope was tried the same day and the web's Nunito was preferred
4 Shape and elevation Cards 16, buttons and inputs 12, sheets 24, chips pill; flat cards with hairlines, shadow only on floating things; no pill buttons
5 Buttons One primary per screen; 44 on desktop, 52 on touch; secondary white with a line; destructive as red text
6 Status colors Three families (good, attention, problem) plus neutral; grades and streak days map onto them
7 App tab bar One accent, labels under the icons, accessibility labels; the floating pill stays
8 Home page hero Lora headline on white under a warm wash, two calls to action and a clinic photo with product cards; the marketing pages keep their own palette (see Marketing pages). Settled 2026-10-13
9 Icons and emoji Outline icons only; no emoji as icons
10 Dark mode Parked; token names allow it later
11 Where the system lives Tokens in code, this page, lint against raw hex in the app
12 Finishing a session The one playful moment: a 1.2 s confetti burst with a haptic rhythm when a patient finishes a session, whichever way they finish it; calm motion everywhere else stands

Rollout

  1. Tokens (landed in the design-tokens branches): tailwind.config.js and styles/global.css on the web (palette, type roles, radii, the float shadow, Nunito through next/font, gray aliased to stone, paper as the page background); lib/theme.ts, the Nunito files and the app/_layout.tsx font gate in the app; a lint warning on raw hex values outside the theme file.
  2. Primitives (landed in the design-tokens branches). Web, in components/ui/: Button (themes primary, secondary/default, text/alternative, danger; sizes xs 32, sm 36, md 44; loading keeps the width), Card (DashboardCard now renders it, framed on phones too), Chip, Input and SearchInput (components/Input.tsx wraps them), Sheet (Modal is a wrapper over it), EmptyState and Table (the admin copies re-export). App, in components/ui/: Card, Row, Chip, Input and SearchInput, EmptyState, Avatar, Sheet; PrimaryButton (52 tall, accent; brand and primary both mean the accent, record is problem red), SecondaryButton and Segmented restyled; the tab bar has one accent, labels under the icons and accessibility labels.
  3. Screens, in this order: doctor app patient management (landed: dashboard, rows, grades and flags, search, today picker, patient detail, quick analysis, visits, the two onboarding modals' buttons), therapist web dashboard and patient popup (landed: dashboard tabs and sub-tabs, patient table and phone cards, archived / assign / resend modals, popup header, Profile, Cases, Workouts and Videos tabs), patient app (landed: home and streak header, workout cards and the whole workout flow, history, messaging, profile, the sign-in theme, loading / error / toast states), patient web (landed: dashboard, plan management, the player and its sheets, completion, feedback and setup modals, shared ConfirmDiscardDialog / DOBFieldInput / TherapistBubbles / PDF button), then admin. The classic plan editors, Edit session, Create session and the exercise picker landed on 2026-10-21, sharing the HEP builder's dose controls (components/plan-creation/hep-builder/controls/), whose labels moved to the Label role; the feedback card in Messages the same day. The home page v2 was rebased onto the tokens on 2026-10-14; its colours are the marketing.* tokens.
  4. Guardrails. The app's hex lint goes from warning to error when the count reaches zero; the mobile design doc is cut down to what the code does.

References

The six reference shots agree on one recipe: a light off-white screen, white cards with large radius, one accent, pill chips and buttons, rows of thumbnail + name + one fact, real photos, almost no shadows. We took the recipe and left the gradients.

  • Pilates Workout App and Pilates Fitness App by Imran Jakir: exercise rows, pill filters, one big Start, player controls as three pills.
  • AthletiQ training and AthletiQ programs by Panze: one big number as the hero, three-up stats with small units. Gradients and the dark tab bar were left out.
  • Training, analytics and progress by Helal Hossain: calendar with completed days, two-tile stat row, one-tint bar chart.
  • FitFlow by Sienna Rose: cream background with a single accent, hairline card borders, a human line on the summary ring. The warmest of the six.
  • In-house: the doctor app's patient management screens (components/doctor/PatientRow.tsx, DoctorDashboard.tsx): hairline rows, 8 px gaps, 44 px targets, one fact per line.