Skip to content

Last updated:

Theming

CPR has a consistent visual identity built around a teal/cyan brand color and a clean, neutral UI palette. This page documents the color conventions, typography patterns, and icon usage so that new features maintain visual consistency.

Brand Colors

Primary -- #117ea7

The primary brand color is a teal/cyan used for:

  • Header background
  • Primary action buttons
  • Active navigation indicators
  • Modal headers
  • Focus rings on form inputs
  • Links and interactive accents
StateColorUsage
Default#117ea7bg-[#117ea7], text-[#117ea7]
Hover#0e6b8fhover:bg-[#0e6b8f]
Focus ring#117ea7 at 50% opacityfocus:ring-[#117ea7]/50

Applying the brand color

html
<!-- Solid background -->
<div class="bg-[#117ea7] text-white">

<!-- Text accent -->
<span class="text-[#117ea7] font-medium">Active</span>

<!-- Button -->
<button class="bg-[#117ea7] hover:bg-[#0e6b8f] text-white rounded-lg px-4 py-2 transition-colors">

<!-- Focus ring -->
<input class="focus:ring-2 focus:ring-[#117ea7]/50 focus:border-transparent">

Some components also use Tailwind's primary-* color classes (e.g., bg-primary-600, hover:bg-primary-700, focus:ring-primary-500). These map to a configured primary palette. When adding new brand-colored elements, prefer the arbitrary value bg-[#117ea7] for consistency with existing components, unless you are working within a component that already uses primary-* classes.

Neutral palette

CPR uses Tailwind's default gray scale for all neutral surfaces:

ElementColorClass
Page backgroundgray-50bg-gray-50
Card / panel backgroundwhitebg-white
Card bordergray-100border-gray-100
Table row hovergray-50hover:bg-gray-50
Dividersgray-100 / gray-200border-gray-100
Body textgray-900text-gray-900
Secondary textgray-500 / gray-600text-gray-500
Placeholder textgray-400text-gray-400 / placeholder-gray-400
Disabled elements50% opacitydisabled:opacity-50

Status colors

Use Tailwind's semantic color scales for status indicators:

html
<!-- Success -->
<span class="text-green-600 bg-green-50 px-2 py-0.5 rounded-full text-xs font-medium">Active</span>

<!-- Warning -->
<span class="text-yellow-700 bg-yellow-50 px-2 py-0.5 rounded-full text-xs font-medium">Pending</span>

<!-- Error / danger -->
<span class="text-red-600 bg-red-50 px-2 py-0.5 rounded-full text-xs font-medium">Failed</span>

<!-- Info / neutral -->
<span class="text-blue-600 bg-blue-50 px-2 py-0.5 rounded-full text-xs font-medium">Draft</span>

Typography Conventions

CPR uses Tailwind's default font stack (system fonts). Text sizing and weight follow these conventions:

Headings

html
<!-- Page title -->
<h1 class="text-xl font-bold text-gray-900">Page Title</h1>

<!-- Section heading -->
<h2 class="text-lg font-semibold text-gray-900">Section</h2>

<!-- Card heading -->
<h3 class="text-base font-semibold text-gray-900">Card Title</h3>

<!-- Modal heading (inside branded header) -->
<h2 class="text-lg font-semibold text-white">Modal Title</h2>

Body text

html
<!-- Standard body text -->
<p class="text-sm text-gray-700">Description goes here.</p>

<!-- Secondary / muted text -->
<p class="text-sm text-gray-500">Last updated 2 hours ago</p>

<!-- Small detail text -->
<span class="text-xs text-gray-400">Optional note</span>

Labels and metadata

Table headers, form labels, and metadata use a distinctive uppercase style:

html
<!-- Table column header -->
<th class="text-xs font-semibold text-gray-500 uppercase tracking-wide">
  Column Name
</th>

<!-- Form label -->
<label class="block text-xs font-semibold text-gray-600 uppercase tracking-wide mb-1">
  Field Label
</label>

<!-- Metadata tag -->
<span class="text-xs uppercase tracking-wide text-gray-400 font-medium">
  Category
</span>

The combination of text-xs uppercase tracking-wide is the standard label pattern in CPR. Use font-semibold for labels that are associated with input fields.

Input text

html
<!-- Inputs use text-sm and font-semibold for entered values -->
<input class="text-sm font-semibold" />

<!-- Placeholder text is normal weight -->
<input class="text-sm font-semibold placeholder:font-normal" placeholder="Enter value" />

Icon Usage

CPR uses @heroicons/vue for all icons. Import icons from the appropriate style:

vue
<script setup lang="ts">
import { MagnifyingGlassIcon, PlusIcon } from '@heroicons/vue/24/outline'
import { CheckCircleIcon } from '@heroicons/vue/24/solid'
</script>

Sizing conventions

ContextSize classExample
Inside buttonsw-5 h-5Action buttons
Table row actionsw-4 h-4 or w-5 h-5Edit, delete icons
Navigationw-5 h-5Nav item icons
Empty state illustrationw-12 h-12Large centered icon
Inline with textw-4 h-4Status indicators

Pattern

html
<!-- Icon button -->
<button class="p-1.5 rounded-lg hover:bg-gray-100 transition-colors text-gray-500 hover:text-gray-700">
  <PencilSquareIcon class="w-5 h-5" />
</button>

<!-- Icon + text button -->
<button class="flex items-center gap-2 bg-[#117ea7] text-white px-4 py-2 rounded-lg">
  <PlusIcon class="w-5 h-5" />
  Add Item
</button>

<!-- Inline status icon -->
<div class="flex items-center gap-1.5 text-green-600">
  <CheckCircleIcon class="w-4 h-4" />
  <span class="text-sm">Verified</span>
</div>

Maintaining Visual Consistency

Follow these rules when building new features:

  1. Use the brand color only for primary actions and navigation. Do not use #117ea7 for decorative purposes or secondary elements.
  2. Stick to the gray scale for neutral UI. Use gray-50 through gray-900 -- do not introduce slate, zinc, or other neutral palettes.
  3. Keep border radius consistent. Cards and containers use rounded-xl. Buttons and inputs use rounded-lg. Modals use rounded-3xl. Status badges use rounded-full.
  4. Use consistent shadows. Cards use shadow-sm. Modals use shadow-xl. Avoid shadow-lg on cards.
  5. Apply transitions to all interactive elements. Use transition-colors for buttons and links, transition-all for inputs, transition-shadow for hoverable cards.
  6. Follow the label typography pattern. All labels, table headers, and metadata use text-xs uppercase tracking-wide.
  7. Size icons according to context. Refer to the icon sizing table above.

Border radius reference

ElementRadius
Cards, table containersrounded-xl
Buttons, inputs, selectsrounded-lg
Modalsrounded-3xl
Status badges, pillsrounded-full
Avatarsrounded-full

CPR - Clinical Patient Records