Design Tokens & Typography
Flo uses a design token system based on CSS custom properties. Tokens are defined in JSON theme files and injected into :root at runtime, enabling multi-brand theming.
How It Works
- Theme JSON files live in
public/configs/(e.g.,flo.theme.json,respirastudio.theme.json) - On app startup, the appropriate theme is loaded based on hostname detection
- CSS variables are injected into
:rootviaapplyCssVariables() - Tailwind CSS and component styles reference these variables
All CSS variables use the --r- prefix.
Color Tokens
Flo Brand Colors
| Token | CSS Variable | Value | Usage |
|---|---|---|---|
| Primary | --r-primary-color | #9EE771 | Main brand color, buttons, links |
| Accent | --r-accent-color | #80e142 | Hover states, active elements |
| Alt Primary | --r-alt-primary-color | #80e142 | Alternative primary interactions |
| Secondary | --r-secondary-color | #76DD36 | Secondary actions, badges |
| Text | --r-text-color | #263717 | Body text, headings |
| Background | --r-background-color | #FFFFFF | Page background |
| Black | --r-black | #2B2A29 | High-contrast text |
Primary Color Scale
| Token | Tailwind Class | Flo Value | Usage |
|---|---|---|---|
--r-primary-100 | bg-primary-100 | #F2F9E6 | Lightest background tint |
--r-primary-150 | bg-primary-150 | #E6F5D1 | Very light background |
--r-primary-200 | bg-primary-200 | #DAF1BB | Light background, focus rings |
--r-primary-300 | bg-primary-300 | #CEF0A6 | Light accent |
--r-primary-400 | bg-primary-400 | #C2EE91 | Medium accent |
--r-primary-500 | bg-primary-500 | #9EE771 | Primary brand color |
--r-primary-600 | bg-primary-600 | #8CD66B | Darker primary |
--r-primary-700 | bg-primary-700 | #7AC065 | Darkest primary |
Secondary Color Scale
| Token | Tailwind Class | Flo Value |
|---|---|---|
--r-secondary-100 | bg-secondary-100 | #F0F9E3 |
--r-secondary-200 | bg-secondary-200 | #E1F3C7 |
--r-secondary-300 | bg-secondary-300 | #D2EDAB |
--r-secondary-400 | bg-secondary-400 | #C3E98F |
--r-secondary-500 | bg-secondary-500 | #76DD36 |
--r-secondary-600 | bg-secondary-600 | #68C630 |
--r-secondary-700 | bg-secondary-700 | #5AB22A |
Tertiary Color Scale
| Token | Tailwind Class | Flo Value |
|---|---|---|
--r-tertiary-100 | bg-tertiary-100 | #F3F0FD |
--r-tertiary-200 | bg-tertiary-200 | #E0D7FA |
--r-tertiary-300 | bg-tertiary-300 | #CCBEF7 |
--r-tertiary-400 | bg-tertiary-400 | #B9A5F4 |
--r-tertiary-500 | bg-tertiary-500 | #A280E6 |
--r-tertiary-600 | bg-tertiary-600 | #8C74CC |
--r-tertiary-700 | bg-tertiary-700 | #7569B3 |
Gray Scale
| Token | Tailwind Class | Flo Value | Usage |
|---|---|---|---|
--r-gray-000 | bg-gray-000 | #FFFFFF | White |
--r-gray-100 | bg-gray-100 | #faf9f6 | Surface background |
--r-gray-200 | bg-gray-200 | #EDEFEC | Borders, dividers |
--r-gray-300 | bg-gray-300 | #dedcd8 | Disabled elements |
--r-gray-400 | bg-gray-400 | #c6c2bd | Placeholder text |
--r-gray-500 | bg-gray-500 | #aea9a4 | Muted text |
--r-gray-600 | bg-gray-600 | #96928d | Secondary text |
--r-gray-700 | bg-gray-700 | #7e7a75 | Strong muted text |
Typography
Font Families
| Token | CSS Variable | Flo | Respirastudio |
|---|---|---|---|
| Primary | --r-primary-font-family | Bricolage Grotesque | Playfair Display |
| Secondary | --r-secondary-font-family | Inter | Lato |
Tailwind usage:
<h1 class="font-primary">Heading</h1>
<p class="font-secondary">Body text</p>
Fonts are loaded from Google Fonts with a 3-second fallback timeout. The .fonts-loaded class is applied to <html> once fonts are available.
Font Weights
| Token | Flo Value |
|---|---|
--r-primary-desktop-font-weigth | semi-bold |
--r-secondary-desktop-font-weigth | regular |
--r-primary-mobile-font-weigth | regular |
Desktop Type Scale
| Token | Tailwind Class | Size | Usage |
|---|---|---|---|
--r-desktop-font-size-header-1 | text-desktop-header-1 | 3rem (48px) | Page titles |
--r-desktop-font-size-header-2 | text-desktop-header-2 | 2.5rem (40px) | Section headers |
--r-desktop-font-size-header-3 | text-desktop-header-3 | 2.062rem (33px) | Subsection headers |
--r-desktop-font-size-header-4 | text-desktop-header-4 | 1.75rem (28px) | Card titles |
--r-desktop-font-size-header-5 | text-desktop-header-5 | 1.238rem (20px) | Small headers |
--r-desktop-font-size-body-text | text-desktop-body | 1rem (16px) | Body text |
--r-desktop-font-size-body-caption-text-1 | text-desktop-caption-1 | 1rem (16px) | Captions |
--r-desktop-font-size-body-caption-text-2 | text-desktop-caption-2 | 0.812rem (13px) | Small captions |
--r-desktop-font-size-body-tiny-text | — | 0.688rem (11px) | Labels, badges |
Mobile Type Scale
| Token | Tailwind Class | Size |
|---|---|---|
--r-primary-mobile-font-size-header-1 | text-mobile-header-1 | 2.625rem (42px) |
--r-primary-mobile-font-size-header-2 | text-mobile-header-2 | 2.1875rem (35px) |
--r-primary-mobile-font-size-header-3 | text-mobile-header-3 | 1.8125rem (29px) |
--r-primary-mobile-font-size-header-4 | text-mobile-header-4 | 1.5rem (24px) |
--r-primary-mobile-font-size-header-5 | text-mobile-header-5 | 1.25rem (20px) |
--r-primary-mobile-font-size-body-text | text-mobile-body | 1.0625rem (17px) |
--r-primary-mobile-font-size-body-caption-text-1 | text-mobile-caption-1 | 0.875rem (14px) |
--r-primary-mobile-font-size-body-caption-text-2 | text-mobile-caption-2 | 0.75rem (12px) |
--r-primary-mobile-font-size-body-tiny-text | — | 0.625rem (10px) |
Using Tokens in Code
Tailwind Classes
<!-- Colors -->
<div class="bg-primary-100 text-text-color">
<button class="bg-primary text-white hover:bg-alt-primary">
<!-- Typography -->
<h1 class="font-primary text-desktop-header-1">Title</h1>
<p class="font-secondary text-desktop-body">Body text</p>
<!-- Responsive typography -->
<h2 class="text-mobile-header-2 md:text-desktop-header-2">Heading</h2>
<!-- Gray scale -->
<div class="bg-gray-100 border border-gray-300">
<p class="text-gray-600">Muted text</p>
Raw CSS Variables
.custom-element {
background-color: var(--r-primary-200);
color: var(--r-text-color);
font-family: var(--r-primary-font-family);
font-size: var(--r-desktop-font-size-header-4);
}
Important: Tailwind Classes with /
When using Tailwind classes with / (opacity modifiers), use [ngClass] instead of class:
<!-- Correct -->
<div [ngClass]="'bg-primary-200/20'">
<!-- Will break -->
<div class="bg-primary-200/20">
PrimeNG Theme
PrimeNG uses the Lara preset with custom CSS layer ordering:
tailwind-base → primeng → tailwind-utilities → overrides
This ensures Tailwind utilities can override PrimeNG styles, and custom overrides take highest priority.
Theme Files
| File | Purpose |
|---|---|
public/configs/flo.theme.json | Flo color and typography tokens |
public/configs/respirastudio.theme.json | Respirastudio tokens |
public/configs/flo.configs.json | Flo app config (title, fonts, PWA) |
public/configs/respirastudio.configs.json | Respirastudio app config |
tailwind.config.js | Maps CSS variables to Tailwind classes |
src/styles.scss | Global styles and layer config |
src/assets/styles/overrides/ | PrimeNG component style overrides |