Foundations

Colour

Brand colours, semantic roles in light and dark, status tones and live contrast ratios.

Brand colours

Five named colours. Everything else is derived from them in OKLCH.

  • Signal Amber

    #e69431 · oklch(0.734 0.146 66.1)

    The live dot: the app icon’s dot, “you are here”, things that need the patient

  • Harbour Blue

    #0c6091 · oklch(0.469 0.107 242.3)

    Primary actions, links, focus — the calm, trustworthy working colour

  • Ink

    #191713 · oklch(0.205 0.008 84.6)

    Primary text on light surfaces

  • Deep Navy

    #003554 · oklch(0.315 0.075 242.1)

    Logo square and “flow” on light, app icon field, deep brand surfaces

  • Paper

    #fbfaf8 · oklch(0.985 0.003 84.6)

    Light backgrounds — warm, never clinical white

Semantic roles

Every role in light and dark, with its CSS variable. Components use roles, never raw values.

Colour roles in light and dark
RoleVariableLightDark
accent--accent#f0f8ff#272e37
accentForeground--accent-foreground#003554#fbfaf8
background--background#fbfaf8#0f141b
border--border#e9e6e1#272e37
borderStrong--border-strong#d7d4ce#414853
brand--brand#003554#fbfaf8
brandForeground--brand-foreground#ffffff#070b11
card--card#ffffff#181f27
cardForeground--card-foreground#191713#fbfaf8
chart1--chart-1#0061a2#4391d7
chart2--chart-2#e48e00#cf8100
chart3--chart-3#d85891#db6397
chart4--chart-4#c0b529#a09600
chart5--chart-5#49b3d8#32a0c5
chart6--chart-6#c53829#d64938
chart7--chart-7#5d3fa8#846cd1
chart8--chart-8#00896d#00896d
destructive--destructive#c72e2b#ff7c70
destructiveForeground--destructive-foreground#ffffff#070b11
foreground--foreground#191713#fbfaf8
glass--glass#fbfaf8b8#181f27b8
glassBorder--glass-border#ffffff99#ffffff1f
glow--glow#e69431#e69431
glowForeground--glow-foreground#191713#191713
glowSoft--glow-soft#ffe8d3#3d3429
input--input#8a867f#848d98
link--link#0c6091#99cdf4
muted--muted#f5f3f0#272e37
mutedForeground--muted-foreground#69655f#a7afb9
overlay--overlay#19171373#070b1199
popover--popover#ffffff#272e37
popoverForeground--popover-foreground#191713#fbfaf8
primary--primary#0c6091#99cdf4
primaryForeground--primary-foreground#ffffff#070b11
ring--ring#4895cc#6eb1e2
secondary--secondary#f5f3f0#272e37
secondaryForeground--secondary-foreground#292622#f5f3f0
sidebar--sidebar#f5f3f0#070b11
sidebarAccent--sidebar-accent#e9e6e1#181f27
sidebarAccentForeground--sidebar-accent-foreground#191713#fbfaf8
sidebarBorder--sidebar-border#e9e6e1#181f27
sidebarForeground--sidebar-foreground#3c3933#c8ced7
sidebarPrimary--sidebar-primary#0c6091#99cdf4
sidebarPrimaryForeground--sidebar-primary-foreground#ffffff#070b11
sidebarRing--sidebar-ring#4895cc#6eb1e2
surfaceInverse--surface-inverse#181f27#f5f3f0
surfaceInverseForeground--surface-inverse-foreground#fbfaf8#0f141b
surfaceSunken--surface-sunken#f5f3f0#070b11
statusNeutralFg--status-neutral-fg#524e48#c8ced7
statusNeutralBg--status-neutral-bg#f5f3f0#283038
statusNeutralBorder--status-neutral-border#e9e6e1#434b54
statusNeutralSolid--status-neutral-solid#69655f#a7afb9
statusNeutralSolidForeground--status-neutral-solid-foreground#ffffff#070b11
statusInfoFg--status-info-fg#0c6091#99cdf4
statusInfoBg--status-info-bg#ddf0ff#223748
statusInfoBorder--status-info-border#bde2fe#3a5972
statusInfoSolid--status-info-solid#2177ad#6eb1e2
statusInfoSolidForeground--status-info-solid-foreground#ffffff#070b11
statusProgressFg--status-progress-fg#5e499d#c6bbff
statusProgressBg--status-progress-bg#edeaff#30324b
statusProgressBorder--status-progress-border#dcd6ff#535177
statusProgressSolid--status-progress-solid#735dba#ab9bee
statusProgressSolidForeground--status-progress-solid-foreground#ffffff#070b11
statusHighlightFg--status-highlight-fg#653b00#f9b671
statusHighlightBg--status-highlight-bg#ffd3a9#503c1b
statusHighlightBorder--status-highlight-border#f9b671#6a4e2b
statusHighlightSolid--status-highlight-solid#c77900#e69431
statusHighlightSolidForeground--status-highlight-solid-foreground#191713#070b11
statusSuccessFg--status-success-fg#006c45#94d7b3
statusSuccessBg--status-success-bg#d9f5e4#1f3a36
statusSuccessBorder--status-success-border#bbe9cf#385f52
statusSuccessSolid--status-success-solid#008556#67be92
statusSuccessSolidForeground--status-success-solid-foreground#ffffff#070b11
statusWarningFg--status-warning-fg#715700#e0c279
statusWarningBg--status-warning-bg#f9eccd#36341f
statusWarningBorder--status-warning-border#f0daa8#5f5431
statusWarningSolid--status-warning-solid#af8800#caa43f
statusWarningSolidForeground--status-warning-solid-foreground#191713#070b11
statusDangerFg--status-danger-fg#a8181a#ffada3
statusDangerBg--status-danger-bg#ffe6e3#422a2e
statusDangerBorder--status-danger-border#ffcfc9#744444
statusDangerSolid--status-danger-solid#c72e2b#ff7c70
statusDangerSolidForeground--status-danger-solid-foreground#ffffff#070b11

Status tones

Seven tones shared by every status map. Subtle for most states; solid for one high-emphasis mark per row.

Status tone matrix
ToneBackgroundTextBorderSolidExample
neutralneutral
infoinfo
progressprogress
highlighthighlight
successsuccess
warningwarning
dangerdanger

Data visualisation

Eight categorical slots in a fixed order; the dark palette is chosen, not inverted.

light

12345678

dark

12345678

Contrast

Every pair the tokens test, computed live. Text needs 4.5:1, interface marks 3:1 (WCAG 2.2 AA).

Contrast of every tested pair
ForegroundBackgroundUseLightLight AADarkDark AA
foregroundbackgroundnormal17.15:1Pass17.71:1Pass
foregroundcardnormal17.89:1Pass15.92:1Pass
foregroundpopovernormal17.89:1Pass13.13:1Pass
foregroundmutednormal16.16:1Pass13.13:1Pass
foregroundsecondarynormal16.16:1Pass13.13:1Pass
foregroundaccentnormal16.68:1Pass13.13:1Pass
foregroundsidebarnormal16.16:1Pass18.90:1Pass
foregroundsidebarAccentnormal14.37:1Pass15.92:1Pass
foregroundsurfaceSunkennormal16.16:1Pass18.90:1Pass
foregroundglowSoftnormal15.11:1Pass11.69:1Pass
mutedForegroundbackgroundnormal5.54:1Pass8.33:1Pass
mutedForegroundcardnormal5.78:1Pass7.49:1Pass
mutedForegroundpopovernormal5.78:1Pass6.18:1Pass
mutedForegroundmutednormal5.22:1Pass6.18:1Pass
mutedForegroundsecondarynormal5.22:1Pass6.18:1Pass
mutedForegroundaccentnormal5.39:1Pass6.18:1Pass
mutedForegroundsidebarnormal5.22:1Pass8.89:1Pass
mutedForegroundsidebarAccentnormal4.65:1Pass7.49:1Pass
mutedForegroundsurfaceSunkennormal5.22:1Pass8.89:1Pass
mutedForegroundglowSoftnormal4.88:1Pass5.50:1Pass
cardForegroundcardnormal17.89:1Pass15.92:1Pass
popoverForegroundpopovernormal17.89:1Pass13.13:1Pass
primaryForegroundprimarynormal6.77:1Pass11.63:1Pass
secondaryForegroundsecondarynormal13.59:1Pass12.37:1Pass
accentForegroundaccentnormal11.95:1Pass13.13:1Pass
destructiveForegrounddestructivenormal5.44:1Pass7.85:1Pass
sidebarForegroundsidebarnormal10.38:1Pass12.45:1Pass
sidebarForegroundsidebarAccentnormal9.24:1Pass10.49:1Pass
sidebarPrimaryForegroundsidebarPrimarynormal6.77:1Pass11.63:1Pass
sidebarAccentForegroundsidebarAccentnormal14.37:1Pass15.92:1Pass
surfaceInverseForegroundsurfaceInversenormal15.92:1Pass16.68:1Pass
brandForegroundbrandnormal12.82:1Pass18.90:1Pass
glowForegroundglownormal7.36:1Pass7.36:1Pass
linkbackgroundnormal6.49:1Pass10.90:1Pass
linkcardnormal6.77:1Pass9.80:1Pass
linkpopovernormal6.77:1Pass8.08:1Pass
primarybackgroundnormal6.49:1Pass10.90:1Pass
primarycardnormal6.77:1Pass9.80:1Pass
primarypopovernormal6.77:1Pass8.08:1Pass
destructivebackgroundnormal5.22:1Pass7.36:1Pass
destructivecardnormal5.44:1Pass6.62:1Pass
destructivepopovernormal5.44:1Pass5.46:1Pass
statusNeutralFgstatusNeutralBgnormal7.45:1Pass8.44:1Pass
statusNeutralFgbackgroundnormal7.91:1Pass11.67:1Pass
statusNeutralFgcardnormal8.26:1Pass10.49:1Pass
statusNeutralFgpopovernormal8.26:1Pass8.65:1Pass
statusNeutralSolidForegroundstatusNeutralSolidnormal5.78:1Pass8.89:1Pass
statusInfoFgstatusInfoBgnormal5.80:1Pass7.25:1Pass
statusInfoFgbackgroundnormal6.49:1Pass10.90:1Pass
statusInfoFgcardnormal6.77:1Pass9.80:1Pass
statusInfoFgpopovernormal6.77:1Pass8.08:1Pass
statusInfoSolidForegroundstatusInfoSolidnormal4.87:1Pass8.49:1Pass
statusProgressFgstatusProgressBgnormal6.10:1Pass7.10:1Pass
statusProgressFgbackgroundnormal6.90:1Pass10.52:1Pass
statusProgressFgcardnormal7.20:1Pass9.45:1Pass
statusProgressFgpopovernormal7.20:1Pass7.80:1Pass
statusProgressSolidForegroundstatusProgressSolidnormal5.24:1Pass8.12:1Pass
statusHighlightFgstatusHighlightBgnormal6.94:1Pass5.96:1Pass
statusHighlightFgbackgroundnormal9.23:1Pass10.52:1Pass
statusHighlightFgcardnormal9.63:1Pass9.45:1Pass
statusHighlightFgpopovernormal9.63:1Pass7.80:1Pass
statusHighlightSolidForegroundstatusHighlightSolidnormal5.25:1Pass8.11:1Pass
statusSuccessFgstatusSuccessBgnormal5.61:1Pass7.35:1Pass
statusSuccessFgbackgroundnormal6.23:1Pass11.11:1Pass
statusSuccessFgcardnormal6.49:1Pass9.99:1Pass
statusSuccessFgpopovernormal6.49:1Pass8.24:1Pass
statusSuccessSolidForegroundstatusSuccessSolidnormal4.67:1Pass8.78:1Pass
statusWarningFgstatusWarningBgnormal5.84:1Pass7.29:1Pass
statusWarningFgbackgroundnormal6.56:1Pass10.70:1Pass
statusWarningFgcardnormal6.85:1Pass9.62:1Pass
statusWarningFgpopovernormal6.85:1Pass7.93:1Pass
statusWarningSolidForegroundstatusWarningSolidnormal5.40:1Pass8.35:1Pass
statusDangerFgstatusDangerBgnormal6.29:1Pass7.33:1Pass
statusDangerFgbackgroundnormal7.16:1Pass10.34:1Pass
statusDangerFgcardnormal7.47:1Pass9.30:1Pass
statusDangerFgpopovernormal7.47:1Pass7.67:1Pass
statusDangerSolidForegroundstatusDangerSolidnormal5.44:1Pass7.85:1Pass
inputbackgroundui3.47:1Pass5.49:1Pass
inputcardui3.62:1Pass4.93:1Pass
inputpopoverui3.62:1Pass4.07:1Pass
ringbackgroundui3.12:1Pass7.96:1Pass
ringcardui3.25:1Pass7.15:1Pass
ringpopoverui3.25:1Pass5.90:1Pass
statusNeutralSolidcardui5.78:1Pass7.49:1Pass
statusInfoSolidcardui4.87:1Pass7.15:1Pass
statusProgressSolidcardui5.24:1Pass6.84:1Pass
statusHighlightSolidcardui3.40:1Pass6.83:1Pass
statusSuccessSolidcardui4.67:1Pass7.40:1Pass
statusWarningSolidcardui3.30:1Pass7.03:1Pass
statusDangerSolidcardui5.44:1Pass6.62:1Pass