Aleris Design Tokens — Reference

The canonical reference for Aleris design tokens. Read this document to understand the token system, then use aleris-tokens.css as your implementation source.

This document has two reading paths. Beginner sections give you the answer — use them when building. Expert sections explain the reasoning — read them when you're making decisions the tokens don't cover, or when you need to argue for or against a change.


Architecture

Aleris tokens use a three-layer model. This is the industry standard architecture (IBM Carbon, Google Material, Salesforce Lightning, Atlassian all converge on it).

Layer 1 — Primitives. Raw values. Hex codes, pixel values, font names. These are the complete Aleris visual palette. You almost never reference these directly in product code.

Layer 2 — Semantic tokens. Primitives mapped to usage context. --text-primary rather than --color-petrol-500. These carry meaning: where a value should be used and why. This is the layer product teams reference in code.

Layer 3 — Component tokens. Specific to individual UI components. --button-primary-bg rather than --brand-accent. These matter when multiple teams build against the same codebase or when theming.

Beginner: Reference semantic tokens (Layer 2) in your code. Use component tokens (Layer 3) when they exist for your component. Never reference primitives directly — if you find yourself typing a hex code, something is wrong.

Expert: The three-layer architecture is an expression of Aleris's foundational design principle: progressive enhancement. Primitives are the base layer — always present, always functional. A product that only implements primitives still gets a coherent Aleris palette. Semantic tokens add meaning and context. Surface mode tokens add situational adaptation. Each layer references the one below it; no layer requires the one above it to function.

This structure also means a single decision change propagates correctly. If Aleris changes its primary brand color, you update one primitive, and every semantic and component token that references it updates automatically. If you reference a primitive directly, you've created a manual update point that will drift. The semantic layer is also what makes surface temperature modes possible — communicative and instrumental surfaces can remap semantic tokens to different primitives without touching component code.


Color

Primitives

Token Value Visual
--color-petrol-500 #004851 Primary brand. Deep teal.
--color-petrol-300 #7fa9ae Mid teal.
--color-petrol-100 #d9e1e2 Light teal tint.
--color-orange-500 #f58c61 Accent. Warm coral-orange.
--color-orange-300 #ffbe9f Mid orange.
--color-orange-100 #fde8df Light orange tint.
--color-sand-500 #d9b48f Warm amber.
--color-sand-300 #e7ceb5 Mid sand.
--color-sand-100 #f2ece4 Light sand. Default page background.
--color-gray-500 #585044 Dark warm gray.
--color-gray-300 #9e9281 Mid warm gray.
--color-gray-100 #d7d2cb Light warm gray. Borders, disabled.
--color-white #ffffff Card surfaces.
--color-error-500 #c14444 Error states only.
--color-warning-500 #d9b48f Warning states only. Same as sand-500.

Design Decision Record: Why these colors

Petrol reads as trustworthy and medical without being cold corporate blue. Orange is warm and approachable without being alarming red. Sand feels calm and natural — not clinical white. The entire palette is warm-shifted: even the grays have warmth (#585044 rather than #555555). This is deliberate. Aleris's brand essence ("den nära experten") requires interfaces that feel human and present, not institutional.

Turquoise was in the palette historically and was removed. It competed with petrol and created visual noise.

Semantic: Text

Token References Use
--text-primary petrol-500 Default text color. All body text, headings.
--text-secondary gray-500 Supporting text that isn't the main content.
--text-tertiary gray-300 Placeholder text, low-emphasis metadata.
--text-inverse white Text on dark backgrounds (petrol, orange).
--text-accent orange-500 Text that needs accent emphasis. Use sparingly.
--text-link petrol-500 Links. Same as primary text — underline differentiates.
--text-disabled gray-300 Disabled interactive elements.
--text-error error-500 Error messages. Always paired with an icon or border.

Beginner: Use --text-primary for nearly everything. Reach for --text-secondary only when you have a clear visual hierarchy reason. If you're using more than two text colors on a screen, reconsider your information hierarchy.

Semantic: Surfaces and Backgrounds

Token References Use
--surface-page sand-100 Page background. Never white.
--surface-card white Cards, panels, content containers.
--surface-elevated white Dropdowns, popovers, tooltips.
--surface-overlay white Modals (use sparingly — prefer inline).

Surface temperature variants:

Token References Mode
--surface-subtle-neutral sand-100 Default. Communicative surfaces.
--surface-subtle-warm orange-100 Warm emphasis. Onboarding, welcome states.
--surface-subtle-cold petrol-100 Cool emphasis. Instrumental surfaces, dashboards.
--surface-strong-neutral sand-500 Strong neutral. Active states, pressed.
--surface-strong-warm orange-500 Strong warm. Primary actions, highlights.
--surface-strong-cold petrol-500 Strong cold. Navigation, structural elements.

Design Decision Record: Surface temperature

Surface temperature describes the type of situation an interface supports, not the type of user. A patient managing their treatment plan is in instrumental mode. A staff member reading a newsletter is in communicative mode.

Communicative surfaces (guides, marketing, onboarding) use sand tones, generous spacing, and softer hierarchy. Instrumental surfaces (dashboards, scheduling, admin) use lighter/neutral tones, tighter spacing, and higher contrast.

Temperature is a property of an entire flow, never individual steps within a flow. A booking flow is instrumental throughout, even if it contains informational content. Mixing modes within a flow creates incoherent experience.

See aleris-surface-temperature-tokens.md for the full framework including escalation levels.

Semantic: Borders

Token References Use
--border-default gray-100 Default borders. Subtle.
--border-strong gray-300 Borders that need more presence. Tables, dividers.
--border-focus petrol-500 Focus rings on interactive elements.
--border-error error-500 Error state borders on inputs.

Semantic: Interactive States

Token References Use
--state-hover orange-500 Hover state for interactive elements.
--state-active sand-500 Active/pressed state.
--state-focus-ring petrol-500 Focus ring color (keyboard navigation).
--state-disabled-bg gray-100 Disabled element background.
--state-disabled-text gray-300 Disabled element text.

Semantic: Status / Feedback

Token References Use
--status-error error-500 Errors, destructive actions.
--status-warning warning-500 Caution states.
--status-background white Background for status messages.

Beginner: Status colors are for state communication only — never decoration. If you're using error red for anything other than an actual error, stop.

Design Decision Record: No success or info status colors

The current Figma token set does not define dedicated success or info colors. If these are needed, they should be added to Figma first and flow into this file. Do not invent hex values in code.

If you need a success indicator now, use petrol-500 (the brand primary) with a checkmark icon. Petrol already carries "trustworthy and confirmed" semantics in the Aleris context.

Goal Status Colors

For KPI dashboards and goal-tracking views only. These are traffic light indicators for instrumental surfaces — never use them in patient-facing interfaces.

Token Hex Meaning
--goal-achieved #2e8540 Target met.
--goal-borderline #ffb81c Near the limit. Attention needed.
--goal-missed #d4351c Target not met.
--goal-no-data #007bc7 No valid data available.

Beginner: Always pair these with an icon or shape — a checkmark for achieved, a warning triangle for borderline, an X for missed, a dash or question mark for no data. Never rely on color alone.

Design Decision Record: Goal colors are not brand colors

These are deliberately standard traffic light conventions (green/yellow/red) rather than brand-derived colors. In a goal-tracking context, users expect these exact associations — remapping them to petrol/orange/sand would create cognitive friction for no benefit.

The "no data" blue (#007bc7) is a distinct hue from both petrol and the chart blues. It signals "neutral information" rather than "disabled" (which gray would imply) or "error" (which red would imply). It reads as "we're aware, there's nothing to show yet."

Accessibility concern: ~8% of men have red-green color deficiency. The icon/shape requirement is not optional — it's a Fixed accessibility rule, same as "never convey information by color alone" elsewhere in the system.

Data Visualization Colors

A dedicated 12-color palette for charts, graphs, figures, pills, and chips in tool contexts. These colors are deliberately distinct from the brand palette — chart teal is not petrol, chart terracotta is not orange. This prevents users from reading data points as interactive UI elements.

The palette is organized in two series of six: a cool series and a warm series. Colors at the same position in each series pair well for comparison charts (before/after, two-category, etc.).

# Token Hex Name Pair
01 --chart-1 #0f9081 Teal ↔ 07
02 --chart-2 #94cbc4 Mint ↔ 08
03 --chart-3 #577ba3 Blue ↔ 09
04 --chart-4 #98c9ef Light Blue ↔ 10
05 --chart-5 #a078c2 Purple ↔ 11
06 --chart-6 #d8b8ef Light Purple ↔ 12
07 --chart-7 #d77a61 Terracotta ↔ 01
08 --chart-8 #f0c3b2 Light Terracotta ↔ 02
09 --chart-9 #6b9495 Marine ↔ 03
10 --chart-10 #bed0c0 Olive ↔ 04
11 --chart-11 #e4ded5 Warm Grey ↔ 05
12 --chart-12 #d9b48f Dark Sand ↔ 06

Beginner: Use --chart-1 through --chart-N in sequence. Start with teal, add colors as you need more categories. For a two-series comparison chart (e.g., this year vs. last year), use the paired tokens: --chart-pair-1-a (teal) and --chart-pair-1-b (terracotta).

If you need more than 6-8 colors in a single chart, the problem is the visualization, not the palette. Simplify the data grouping.

Expert: The cool/warm pairing is intentional. Cool colors (teal → purple) and warm colors (terracotta → sand) each form a distinguishable sequence, and cross-series pairs (teal/terracotta, blue/terracotta-light, purple/olive) have enough hue contrast to work for color-deficient users. Light variants (mint, light blue, light purple, light terracotta, olive, warm grey) are useful for area fills, background shading, and secondary data series.

Note that chart-12 (dark sand, #d9b48f) shares its hex value with --color-sand-500 and --color-warning-500. This is safe when these tokens appear in different contexts (brand surface vs. warning state vs. chart category). If a dashboard displays both a warning state AND chart-12 data in the same view, choose a different chart color to avoid ambiguity.

Design Decision Record: Separate chart palette from brand palette

The data visualization palette was designed to be perceptually distinct from the brand palette. Chart teal (#0f9081) is greener and brighter than petrol (#004851). Chart terracotta (#d77a61) is warmer and more muted than orange (#f58c61). This separation is functional: in an instrumental surface with both interactive UI elements and data charts, users need to instantly distinguish "I can click this" (brand orange button) from "this represents a data category" (chart terracotta bar).

The palette provides 6 light/dark pairs which is sufficient for most healthcare data visualization needs. The numbered ordering (01-12) establishes a canonical sequence so that "category 1" always maps to teal across different dashboards and reports — consistency that builds pattern recognition over time.


Typography

Font Family

Token Value Use
--font-family-primary 'Museo Sans', Arial, sans-serif All text. Museo Sans where licensed, Arial as fallback.
--font-family-fallback Arial, sans-serif Explicit fallback for contexts where Museo Sans is unavailable.
--font-family-icons 'Font Awesome 6 Pro' Icon font. Licensed. Available styles: solid, regular, light.

Design Decision Record: Arial as default for new products

The switch from Museo Sans to Arial as the practical default was made to eliminate licensing complexity across three countries. The visual difference is acceptable. The operational cost of managing font licenses for every digital product across Sweden, Norway, and Denmark is not. New products should use Arial unless Museo Sans is already licensed for the context.

Font Weights — Mapped to Museo Sans Files

Museo Sans is available as woff2 web fonts in weights 100, 300, 500, 700, 900 (plus italics for each). There is no 400 weight. This is critical: if you set font-weight: 400 the browser will synthesize it from adjacent weights, which looks bad.

Token Value Museo Sans file Use
--font-weight-light 300 museosans_300 Large display text, decorative. Use sparingly.
--font-weight-regular 500 museosans_500 (Medium) Default body weight. This IS the "normal" weight.
--font-weight-bold 700 museosans_700 Headings.
--font-weight-black 900 museosans_900 Extra emphasis. Use very sparingly.

Beginner: Use --font-weight-regular (500) for body text and --font-weight-bold (700) for headings. That covers almost everything. Never type font-weight: 400 — it doesn't exist in Museo Sans.

Expert: When falling back to Arial, weight 500 renders slightly heavier than Arial's natural 400. This is acceptable — the difference is subtle and Museo Sans 500 is designed as a regular reading weight despite the higher numeric value. If you notice weight discrepancy between Museo Sans and Arial at a specific size, test both fonts at that size before adjusting.

Type Scale — Perfect Fifth

The type scale uses a perfect fifth ratio (1.5) from an 18px base. The same ratio drives the spacing scale, creating cross-dimensional harmony: proportional relationships between text sizes echo in the spacing between elements.

                          ×1.5
  14  16  18  ···  22  ···  27  ···  40  ···  60
  xs  sm  base     h4       h3       h2       h1
Token Rem Px Derivation Role
--font-size-2xl 3.33rem 60px base × 1.5³ Heading 1. Communicative hero, landing pages.
--font-size-xl 2.22rem 40px base × 1.5² Heading 2. Page title, major section.
--font-size-lg 1.5rem 27px base × 1.5 Heading 3. Section heading.
--font-size-md 1.22rem 22px √(18×27) Heading 4. Card header, sub-subsection. Half-step.
--font-size-base 1rem 18px Body text. Scale anchor.
--font-size-sm 0.89rem 16px √(14×18) Label. Form labels, UI chrome. Half-step.
--font-size-xs 0.78rem 14px Accessibility floor Small. Captions, metadata, timestamps.

Half-steps (sm at 16px, md at 22px) are geometric means of their adjacent scale values. They sit outside the strict 1.5 ratio but are mathematically grounded and serve real needs: labels need a size between body and captions, card headers need a size between body and section headings.

Design Decision Record: Perfect fifth over golden ratio

The golden ratio (1.618) and its square root (1.272) were both evaluated. Golden ratio is too aggressive — it produces dramatic jumps unsuitable for healthcare UI where hierarchy should be clear but calm. √φ gives more steps but the intervals (27.2%) produce sizes like 23px, 29px, 37px, 47px that don't resonate with spacing or line-height values.

Perfect fifth (1.5) produces visible hierarchy without drama. The intervals feel deliberate, not theatrical. This matches Aleris's brand character: precision, professionalism, warmth — not impact or spectacle.

Crucially, using the same ratio for typography AND spacing means line-heights at each type level map to values in the spacing scale: body line-height (27px) = h3 size. h3 line-height (36px) = spacing-lg. h2 line-height (48px) = spacing-xl. This internal resonance is the practical payoff of a modular scale.

Design Decision Record: 18px body text and 14px minimum

Body text at 18px reads calm, not rushed. It's larger than the web default (16px) because healthcare interfaces serve anxious users who may be reading on unfamiliar devices under stress. Larger body text is a structural empathy decision, not an aesthetic one.

14px is the absolute floor. Nothing in any Aleris interface should render below 14px. This is a Fixed accessibility requirement. The Figma export contained tokens at 12px and 13px — these have been removed from the canonical scale entirely.

Type Compositions

Role Token prefix Size Weight Line-height Letter-spacing Color
Heading 1 --type-h1-* 2xl (60px) Bold (700) 1.1 -0.02em text-primary
Heading 2 --type-h2-* xl (40px) Bold (700) 1.2 -0.015em text-primary
Heading 3 --type-h3-* lg (27px) Bold (700) 1.33 -0.01em text-primary
Heading 4 --type-h4-* md (22px) Bold (700) 1.33 Normal text-primary
Body --type-body-* base (18px) Regular (500) 1.5 Normal text-primary
Body bold base (18px) Bold (700) 1.5 Normal text-primary
Label --type-label-* sm (16px) Regular (500) 1.5 Normal text-primary
Small --type-small-* xs (14px) Regular (500) 1.5 Normal text-secondary

Line-height resonance with the scale:

body  18px × 1.5  = 27px  ← h3 font size
h3    27px × 1.33 = 36px  ← spacing-lg
h2    40px × 1.2  = 48px  ← spacing-xl

These aren't coincidences. They're the modular scale producing harmonic relationships across dimensions. The eye perceives this as "everything belongs together" even without conscious awareness of the underlying mathematics.

Beginner: Most pages use h2 for the page title, h3 for sections, h4 for card headers, and body for everything else. h1 at 60px is for communicative surfaces only (landing pages, hero areas) — most instrumental interfaces won't use it. Never skip heading levels.

Expert: Communicative surfaces (patient guides, marketing, onboarding) use the full scale including h1 at 60px, with generous spacing from the upper range of the spacing scale. Instrumental surfaces (dashboards, admin tools) typically cap at h2 (40px) as the largest heading, using the tighter end of the spacing scale. Both modes use the same tokens — the difference is which slice of the scale is active, not a separate set of values.

Icons — Font Awesome 6 Pro

Font Awesome Pro is the standard icon system. Available styles: solid, regular, light.

Token Value Use
--icon-xs 12px Inline indicators, badge icons
--icon-sm 16px Button icons, form field icons
--icon-md 18px Default inline icon (matches body text)
--icon-lg 24px Navigation, card header icons
--icon-xl 48px Feature icons, empty states

Beginner: Match icon size to the text it accompanies. Body text gets --icon-md (18px). Labels get --icon-sm (16px). Use solid style as default, regular for secondary/outline contexts, light only on communicative surfaces at large sizes.

Typography rules

  • Never use all-caps (text-transform: uppercase). Sentence case for everything. All-caps reads as shouting in Scandinavian communication contexts.
  • Never use title case for headings. Sentence case only.
  • Font sizes in rem, not px. This respects browser text size settings for users who need larger text.
  • All headings are petrol (text-primary). Don't color headings differently.
  • Never set font-weight: 400. Museo Sans doesn't have this weight. Use the token --font-weight-regular (500).

Spacing

Typography and spacing share the same perfect fifth (1.5) ratio, aligned to a 4px grid. This creates proportional harmony: the size jump from body to h3 (×1.5) has the same feel as the spacing jump from sm to md (16→24, also ×1.5).

Scale

Token Value Notes
--spacing-0 0px
--spacing-3xs 4px Minimum gap. Icon padding, label-to-input.
--spacing-2xs 8px Tight element spacing, inline gaps.
--spacing-xs 12px Related element spacing.
--spacing-sm 16px Default component padding. Page edge padding.
--spacing-md 24px Section spacing within components. Card padding.
--spacing-lg 36px Between components. = h3 line-height (27×1.33).
--spacing-xl 48px Between sections. = h2 line-height (40×1.2).
--spacing-2xl 72px Major section breaks.
--spacing-3xl 96px Page-level spacing. Communicative surfaces.

Heading spacing rule

Spacing above a heading should be proportional to the heading's visual weight:

Heading Size Space above
h2 40px spacing-lg (36px)
h3 27px spacing-md (24px)
h4 22px spacing-sm (16px)

Semantic

Token References Use
--spacing-page-padding spacing-sm (16px) Horizontal padding at page edges.
--spacing-card-padding spacing-md (24px) Internal padding of cards and panels.
--spacing-section-gap spacing-md (24px) Vertical space between sections/cards.
--spacing-element-gap spacing-xs (12px) Space between elements within a section.
--spacing-label-gap spacing-3xs (4px) Space between a label and its input/content.

Design Decision Record: Unified ratio across type and spacing

Using the same 1.5 ratio for both typography and spacing creates a system where measurements resonate across dimensions. This isn't aesthetic purity — it's practical. When a developer needs to decide how much space goes above a section heading, the answer is built into the system: spacing proportional to the heading's visual weight, derived from the same ratio. The system teaches correct usage through its own internal logic rather than through memorised rules.

Communicative surfaces use the full spacing range (sm through 3xl). Instrumental surfaces use the tighter range (3xs through lg). Same tokens, different slice — exactly like the type scale.

Design Decision Record: 4px grid alignment

The spacing scale is aligned to a 4px grid rather than pure 1.5× progression. Sub-pixel rounding creates visual inconsistency across devices. 4px grid ensures crisp rendering and aligns with industry standard (8px grid with 4px half-step). The proportional relationships are preserved even when individual values are rounded.


Border Radius

Token Value Use
--radius-0 0px No rounding. Tables, specific layout edges.
--radius-s 4px Subtle rounding. Rarely used alone.
--radius-m 8px Inputs, smaller interactive elements.
--radius-l 12px Cards, panels, containers.
--radius-full 100px Pill shape. Buttons, badges.

Design Decision Record: Pill buttons as visual signature

The contrast between rounded cards (radius-l, 12px) and pill-shaped buttons (radius-full, 100px) is a deliberate Aleris visual signature. Pill buttons read as friendlier and more tappable than rectangular or subtly-rounded alternatives — appropriate for healthcare contexts where users may be hesitant to take action.

This is one of the strongest "not-a-framework-default" signals. Most component libraries default to 4-8px button radii. Aleris buttons are pills.

Beginner: Cards get --radius-l. Buttons get --radius-full. Inputs get --radius-m. That covers 90% of cases.


Shadows / Elevation

Token Alias Value Use
--shadow-e0 --elevation-flat none No elevation. Default for most elements.
--shadow-e1 --elevation-card 0px 2px 8px rgba(0,72,81,0.08) Cards, default elevated surfaces.
--shadow-e2 --elevation-dropdown 0px 4px 16px rgba(0,72,81,0.12) Dropdowns, popovers.
--shadow-e3 --elevation-modal 0px 6px 24px rgba(0,72,81,0.16) Modals, the highest elevation.

Design Decision Record: Petrol-tinted shadows

Shadows use rgba(0, 72, 81, ...) (petrol) rather than rgba(0, 0, 0, ...) (black). Black shadows on a warm palette create visual discord — they read as "off" without most people being able to articulate why. Petrol-tinted shadows integrate with the warm sand/cream backgrounds and maintain the overall warm-shifted aesthetic. This is a subtle detail that has disproportionate impact on whether an interface "feels like Aleris."

The Figma export uses black-based shadows. This needs to be updated in Figma to match the petrol-tinted canonical values.


Stroke / Border Width

Token Value Use
--stroke-0 0px No border.
--stroke-xs 1px Default borders. Input fields, dividers.
--stroke-m 2px Focus rings, emphasis borders.
--stroke-xl 4px Strong emphasis. Active indicators, selected states.

Component Tokens

Component tokens are stubs — starting points for the most common components. Extend these as the system matures and more teams build against the same codebase.

Button

Token Value Notes
--button-primary-bg orange-500 One primary button per screen.
--button-primary-text white
--button-primary-hover-bg orange-300
--button-primary-radius radius-full (pill)
--button-primary-shadow shadow-e1 Subtle lift.
--button-secondary-bg petrol-500 Supporting actions.
--button-secondary-text white
--button-outline-bg transparent Tertiary actions.
--button-outline-text petrol-500
--button-outline-border petrol-500
--button-ghost-bg transparent Inline actions, "View details."
--button-ghost-text petrol-500

Beginner: One orange (primary) button per screen. If you need two actions, make the second one outline or ghost. If you've got two orange buttons visible at the same time, one of them is wrong.

Card

Token Value
--card-bg white
--card-radius radius-l (12px)
--card-padding spacing-l (24px)
--card-shadow shadow-e1

Input

Token Value
--input-bg white
--input-border gray-100
--input-border-focus petrol-500
--input-border-error error-500
--input-radius radius-m (8px)
--input-font-size base (18px)
--input-text petrol-500
--input-placeholder gray-300

Figma Sync Notes

The following changes were made to the Figma export values. These need to be synced back to Figma to maintain single-source-of-truth integrity.

Change Figma value Canonical value Reason
Full type scale replacement title 40px, h1 32px, h2 22px, h3 18px h1 60px, h2 40px, h3 27px, h4 22px Rebuilt on perfect fifth (1.5) modular scale. Eliminates h3/body collision. Unified ratio with spacing.
Spacing scale replacement 4,8,12,16,24,32,40,48,64,240 4,8,12,16,24,36,48,72,96 Rebuilt on 1.5 ratio aligned to 4px grid. Shared ratio with type scale.
Sizes below 14px label-small 12px, card-comment 13px, button-label-s 13px Removed entirely Below 14px accessibility floor.
Duplicate token sets global--tokens---museo--sans---* Removed Identical values with auto-generated Figma naming.
Icon size tokens Mixed into text-size styles Separated to --icon-s/m/l/xl Icons are not typography.
Font Awesome tokens global--tokens---font--awesome-6--pro---* Removed Implementation detail, not design token.
Shadow values (e1-e3) black-based rgba petrol-based rgba Brand coherence with warm palette.
radius-m Not in Figma 8px Needed for input components.
radius-l Not in Figma 12px Needed for card components.
warning-100 naming warning-100 error-500 The value (#c14444) is an error red, not a warning amber.
warning amber Not in Figma warning-500 (#d9b48f) Distinct warning color in sand family.

Framework Mapping Examples

These show how Aleris tokens translate to common frameworks. The tokens are the source of truth — these are convenience references, not specifications.

Tailwind CSS v4 (recommended)

Tailwind v4 consumes CSS custom properties natively via @theme. Import the token file and map tokens to Tailwind's namespace — no JavaScript config needed:

@import "tailwindcss";
@import "./aleris-tokens.css";

@theme {
  --color-surface-warm: var(--surface-subtle-warm);
  --color-surface-cold: var(--surface-subtle-cold);
  --color-text-primary: var(--text-primary);
  --color-brand-accent: var(--brand-accent);
  --spacing-sm: var(--spacing-sm);
  --spacing-md: var(--spacing-md);
  --spacing-lg: var(--spacing-lg);
  --spacing-xl: var(--spacing-xl);
}

Developers write bg-surface-warm p-md text-primary. The values resolve from the token file. See aleris-token-governance-frameworks.md for the full architectural rationale.

Tailwind CSS v3 (legacy)

// Extend, don't replace. Never use default Tailwind colors.
module.exports = {
  theme: {
    extend: {
      colors: {
        petrol: { 100: '#d9e1e2', 300: '#7fa9ae', 500: '#004851' },
        sand: { 100: '#f2ece4', 300: '#e7ceb5', 500: '#d9b48f' },
        orange: { 100: '#fde8df', 300: '#ffbe9f', 500: '#f58c61' },
        gray: { 100: '#d7d2cb', 300: '#9e9281', 500: '#585044' },
        error: '#c14444',
        warning: '#d9b48f',
        goal: {
          achieved: '#2e8540',
          borderline: '#ffb81c',
          missed: '#d4351c',
          'no-data': '#007bc7',
        },
        chart: {
          1: '#0f9081', 2: '#94cbc4', 3: '#577ba3', 4: '#98c9ef',
          5: '#a078c2', 6: '#d8b8ef', 7: '#d77a61', 8: '#f0c3b2',
          9: '#6b9495', 10: '#bed0c0', 11: '#e4ded5', 12: '#d9b48f',
        },
      },
      fontFamily: {
        sans: ['Museo Sans', 'Arial', 'sans-serif'],
      },
      fontSize: {
        // Perfect fifth scale (1.5) from 18px base
        xs: '0.78rem',    // 14px — accessibility floor
        sm: '0.89rem',    // 16px — labels, UI chrome
        base: '1rem',     // 18px — body text (scale anchor)
        md: '1.22rem',    // 22px — h4, card headers (half-step)
        lg: '1.5rem',     // 27px — h3 (×1.5)
        xl: '2.22rem',    // 40px — h2 (×1.5²)
        '2xl': '3.33rem', // 60px — h1 (×1.5³)
      },
      spacing: {
        // Perfect fifth scale (1.5) aligned to 4px grid
        '3xs': '4px', '2xs': '8px', xs: '12px', sm: '16px',
        md: '24px', lg: '36px', xl: '48px', '2xl': '72px', '3xl': '96px',
      },
      borderRadius: {
        DEFAULT: '8px',
        lg: '12px',
        full: '100px',
      },
      boxShadow: {
        soft: '0px 2px 8px rgba(0, 72, 81, 0.08)',
        medium: '0px 4px 16px rgba(0, 72, 81, 0.12)',
        strong: '0px 6px 24px rgba(0, 72, 81, 0.16)',
      },
    },
  },
}

Vanilla CSS

Reference aleris-tokens.css directly via import or link. All tokens are CSS custom properties on :root and work in any CSS environment.

@import url('aleris-tokens.css');

body {
  background-color: var(--surface-page);
  color: var(--text-primary);
  font-family: var(--font-family-primary);
  font-size: var(--type-body-size);
  line-height: var(--type-body-line-height);
}

Canonical token reference — March 2026. Source: Figma variable exports + documented design decisions. Maintainer: Torfinn Almers, Head of Design, Aleris Group.