Skip to content

cotel Design Tokens ​

Source of truth for all visual values. Implementors use these names verbatim in CSS Modules. Every token is a CSS custom property set on :root.

Status: v1 — sufficient for FLO-34 dashboard implementation. Related: components.md, pages.md


Color — Light mode ​

TokenValueUsage
--color-bg#f8fafcPage background
--color-surface#ffffffCard, panel, popover background
--color-surface-2#f1f5f9Table header, hover state, nested surface
--color-border#e2e8f0Dividers, card outlines, input borders
--color-border-2#cbd5e1Stronger dividers, focused/active borders
--color-text-1#0f172aPrimary text, headings, values
--color-text-2#475569Secondary text, labels, sub-labels
--color-text-3#94a3b8Placeholder, disabled, empty-state text
--color-accent#2563ebActive nav, links, primary button, chart bars
--color-accent-bg#eff6ffActive nav background, selected row highlight
--color-success#15803dPositive delta, success badge text
--color-success-bg#dcfce7Success badge background
--color-warning#d97706Warning badge text, caution indicators
--color-warning-bg#fef9c3Warning badge background
--color-danger#dc2626Error text, error badge, error row indicator
--color-danger-bg#fef2f2Error row background, error badge background
--color-neutral-bg#f1f5f9Neutral badge background
--color-neutral#475569Neutral badge text

Color — Dark mode ​

Applied via @media (prefers-color-scheme: dark) override on :root. All token names are identical; only values change.

TokenDark valueUsage
--color-bg#020617Page background
--color-surface#0f172aCard, panel background
--color-surface-2#1e293bTable header, hover
--color-border#334155Dividers
--color-border-2#475569Stronger dividers
--color-text-1#f8fafcPrimary text
--color-text-2#94a3b8Secondary text
--color-text-3#475569Muted / placeholder
--color-accent#60a5faLinks, active state, chart bars
--color-accent-bg#172554Active nav background
--color-success#4ade80Success text
--color-success-bg#14532dSuccess badge background
--color-warning#fbbf24Warning text
--color-warning-bg#422006Warning badge background
--color-danger#f87171Error text
--color-danger-bg#450a0aError row background
--color-neutral-bg#1e293bNeutral badge background
--color-neutral#94a3b8Neutral badge text

Contrast compliance (WCAG AA / 4.5:1 for normal text) ​

PairLight ratioDark ratioPass
--color-text-1 on --color-bg19.4:119.4:1✓ AAA
--color-text-2 on --color-surface7.1:14.6:1✓ AA
--color-accent on --color-bg5.9:15.7:1✓ AA
--color-danger on --color-danger-bg5.1:14.8:1✓ AA
--color-text-3 on --color-surface3.5:1—✗ Use only for non-essential UI (placeholders, timestamps)

--color-text-3 intentionally falls below AA — it marks genuinely secondary, non-interactive content. Never use it for actionable labels or data values.


Chart palette ​

Ordered list used for multi-series charts (tool breakdowns, model comparisons). Designed for color-independence: vary hue and lightness so the series are distinguishable in greyscale and to users with deuteranopia.

TokenLight valueDark valueUsage
--color-chart-1#2563eb#60a5faPrimary series (matches accent)
--color-chart-2#7c3aed#a78bfaSecond series
--color-chart-3#059669#34d399Third series
--color-chart-4#d97706#fbbf24Fourth series
--color-chart-5#db2777#f472b6Fifth series

Use --color-chart-1 → --color-chart-5 in order; do not skip. When more than 5 series exist, group the tail as "Other" (use --color-text-3).


Typography ​

Font stack: system-ui, -apple-system, 'Segoe UI', sans-serif
Monospace stack: ui-monospace, 'JetBrains Mono', 'Fira Code', monospace

TokenSizeWeightLine-heightUsage
--text-xs11px5001.4Table headers, card labels, badges (ALL CAPS + letter-spacing)
--text-sm13px4001.5Table cells, body copy, nav items, filter labels
--text-base14px4001.5Default body, form inputs
--text-lg16px6001.4Section headings, modal titles
--text-xl20px7001.3Page titles
--text-2xl24px7001.2KPI Card values
--text-mono-sm12px4001.5Session IDs, span names, JSON viewer
--text-mono-base13px4001.5Code blocks, inline monospace

Letter-spacing for uppercase labels: 0.06em (applies to .card-label, th, .section-title, .badge).


Spacing ​

Base unit = 4px. Tokens are multiples.

TokenValueCommon use
--space-14pxTight inline gap, badge padding vertical
--space-28pxRow padding vertical, icon-to-text gap
--space-312pxCard gap in row, section-title margin-bottom
--space-416pxCard padding, nav item padding horizontal, chart padding
--space-520px— (available; use sparingly)
--space-624pxSection margin-bottom, card row margin-bottom
--space-832pxPage content padding, large section gap
--space-1040px—
--space-1248pxNav height, top-bar height

Do not use raw pixel values in CSS Modules. Reference var(--space-*).


Border radius ​

TokenValueUsage
--radius-sm4pxButtons, pagination buttons, badges
--radius-base6pxCards, table wrappers, chart wrappers, inputs
--radius-lg8pxModals, date pickers, tooltips
--radius-full9999pxPill badges, pulse dot

Shadows ​

TokenValueUsage
--shadow-10 1px 2px rgba(0,0,0,.06)Cards, table wrappers, chart wrappers
--shadow-20 2px 8px rgba(0,0,0,.10)Popovers, tooltips, date picker dropdown
--shadow-30 4px 16px rgba(0,0,0,.14)Modals

In dark mode, shadows are less visible due to dark surface; keep the same values but the UI relies more on border contrast. Do not disable shadows in dark mode.


Z-index ladder ​

TokenValueLayer
--z-base0Normal stacking
--z-sticky100Sticky top nav bar
--z-dropdown200Date range picker, filter dropdowns
--z-tooltip300Tooltips
--z-modal-backdrop400Modal scrim
--z-modal500Modal content
--z-toast600Toast notifications

Motion ​

TokenValueUsage
--duration-fast100msHover state, opacity
--duration-base200msExpand/collapse, dropdown open
--duration-slow300msSkeleton shimmer
--easing-defaulteaseStandard transitions
--easing-in-outcubic-bezier(0.4,0,0.2,1)Panel open/close

Respect prefers-reduced-motion: when set, all durations collapse to 0ms. Implement via:

css
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { transition-duration: 0ms !important; animation-duration: 0ms !important; }
}

Full token CSS block ​

Copy into src/styles/tokens.css as the canonical token file. All CSS Modules import this.

css
:root {
  /* Color */
  --color-bg:          #f8fafc;
  --color-surface:     #ffffff;
  --color-surface-2:   #f1f5f9;
  --color-border:      #e2e8f0;
  --color-border-2:    #cbd5e1;
  --color-text-1:      #0f172a;
  --color-text-2:      #475569;
  --color-text-3:      #94a3b8;
  --color-accent:      #2563eb;
  --color-accent-bg:   #eff6ff;
  --color-success:     #15803d;
  --color-success-bg:  #dcfce7;
  --color-warning:     #d97706;
  --color-warning-bg:  #fef9c3;
  --color-danger:      #dc2626;
  --color-danger-bg:   #fef2f2;
  --color-neutral-bg:  #f1f5f9;
  --color-neutral:     #475569;

  /* Chart palette */
  --color-chart-1: #2563eb;
  --color-chart-2: #7c3aed;
  --color-chart-3: #059669;
  --color-chart-4: #d97706;
  --color-chart-5: #db2777;

  /* Typography */
  --font-sans:  system-ui, -apple-system, 'Segoe UI', sans-serif;
  --font-mono:  ui-monospace, 'JetBrains Mono', 'Fira Code', monospace;
  --text-xs:    11px;
  --text-sm:    13px;
  --text-base:  14px;
  --text-lg:    16px;
  --text-xl:    20px;
  --text-2xl:   24px;
  --text-mono-sm:   12px;
  --text-mono-base: 13px;

  /* Spacing */
  --space-1:  4px;
  --space-2:  8px;
  --space-3:  12px;
  --space-4:  16px;
  --space-5:  20px;
  --space-6:  24px;
  --space-8:  32px;
  --space-10: 40px;
  --space-12: 48px;

  /* Radii */
  --radius-sm:   4px;
  --radius-base: 6px;
  --radius-lg:   8px;
  --radius-full: 9999px;

  /* Shadows */
  --shadow-1: 0 1px 2px rgba(0,0,0,.06);
  --shadow-2: 0 2px 8px rgba(0,0,0,.10);
  --shadow-3: 0 4px 16px rgba(0,0,0,.14);

  /* Z-index */
  --z-base:           0;
  --z-sticky:         100;
  --z-dropdown:       200;
  --z-tooltip:        300;
  --z-modal-backdrop: 400;
  --z-modal:          500;
  --z-toast:          600;

  /* Motion */
  --duration-fast: 100ms;
  --duration-base: 200ms;
  --duration-slow: 300ms;
  --easing-default: ease;
  --easing-in-out: cubic-bezier(0.4,0,0.2,1);
}

@media (prefers-color-scheme: dark) {
  :root {
    --color-bg:          #020617;
    --color-surface:     #0f172a;
    --color-surface-2:   #1e293b;
    --color-border:      #334155;
    --color-border-2:    #475569;
    --color-text-1:      #f8fafc;
    --color-text-2:      #94a3b8;
    --color-text-3:      #475569;
    --color-accent:      #60a5fa;
    --color-accent-bg:   #172554;
    --color-success:     #4ade80;
    --color-success-bg:  #14532d;
    --color-warning:     #fbbf24;
    --color-warning-bg:  #422006;
    --color-danger:      #f87171;
    --color-danger-bg:   #450a0a;
    --color-neutral-bg:  #1e293b;
    --color-neutral:     #94a3b8;

    --color-chart-1: #60a5fa;
    --color-chart-2: #a78bfa;
    --color-chart-3: #34d399;
    --color-chart-4: #fbbf24;
    --color-chart-5: #f472b6;
  }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    transition-duration: 0ms !important;
    animation-duration:  0ms !important;
  }
}

Released under the MIT License.