design-language-system

Design Language System Skill

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "design-language-system" with this command: npx skills add sgcarstrends/sgcarstrends/sgcarstrends-sgcarstrends-design-language-system

Design Language System Skill

This skill documents the professional colour scheme and design tokens for SG Cars Trends, optimised for automotive data visualisation (GitHub Issue #406).

When to Use This Skill

  • Styling new components with the brand colour palette

  • Implementing chart colours for data visualisation

  • Ensuring colour consistency across the application

  • Migrating arbitrary hex colours to design tokens

  • Reviewing colour usage in code reviews

Colour Philosophy

Never use arbitrary hex colours in components. Always use:

  • CSS variables (var(--chart-1) , var(--primary) )

  • HeroUI semantic classes (text-foreground , bg-primary , text-default-500 )

  • Tailwind colour classes mapped to CSS variables (text-primary , bg-muted )

Brand Colour Palette

Role Colour Hex HSL Usage

Primary Navy Blue #191970

hsl(240, 63%, 27%)

Headers, footers, primary buttons, key accents

Secondary Slate Gray #708090

hsl(210, 13%, 50%)

Card containers, borders, secondary buttons

Accent Steel Blue #4A6AAE

hsl(220, 40%, 49%)

Interactive elements, links, hover states

Foreground Blue-Gray #2D3748

hsl(220, 15%, 20%)

Body text, icons

Muted Light Blue-Gray #F0F4F8

hsl(213, 32%, 95%)

Backgrounds, subtle textures

Border Light Slate #E2E8F0

hsl(214, 32%, 91%)

Dividers, input borders

Success Green #22C55E

hsl(142, 71%, 45%)

Positive trends, success states

Destructive Red #DC2626

hsl(0, 72%, 51%)

Errors, negative trends, destructive actions

CSS Variables

Core Semantic Variables

Defined in apps/web/src/app/globals.css :

:root { /* Primary - Navy Blue / --primary: hsl(240 63% 27%); / #191970 */ --primary-foreground: hsl(0 0% 100%);

/* Secondary - Slate Gray / --secondary: hsl(210 13% 50%); / #708090 */ --secondary-foreground: hsl(0 0% 100%);

/* Foreground - Blue-Gray */ --foreground: hsl(220 15% 20%); --background: hsl(0 0% 100%);

/* Muted - Light Blue-Gray / --muted: hsl(213 32% 95%); / #F0F4F8 */ --muted-foreground: hsl(220 15% 20%);

/* Accent - Steel Blue / --accent: hsl(220 40% 49%); / #4A6AAE */ --accent-foreground: hsl(0 0% 100%);

/* Success - Green / --success: hsl(142 71% 45%); / #22C55E */ --success-foreground: hsl(0 0% 100%);

/* Destructive - Red / --destructive: hsl(0 72% 51%); / #DC2626 */ --destructive-foreground: hsl(0 0% 100%);

/* Border / --border: hsl(214 32% 91%); / #E2E8F0 */ }

Chart Colour Variables

Navy Blue gradient palette for data visualisation:

:root { --chart-1: hsl(240 64% 27%); /* Navy Blue - Primary/Top ranking / --chart-2: hsl(220 51% 37%); / Medium Blue - Second ranking / --chart-3: hsl(220 41% 49%); / Light Blue - Third ranking / --chart-4: hsl(210 14% 53%); / Slate Gray - Fourth ranking / --chart-5: hsl(215 23% 65%); / Light Slate - Fifth ranking / --chart-6: hsl(212 17% 76%); / Pale Slate - Sixth ranking */ }

Usage Patterns

Text Colours

// ✅ Good - Use semantic classes <span className="text-foreground">Primary body text</span> <span className="text-default-600">Secondary text</span> <span className="text-default-500">Muted/helper text</span> <span className="text-muted-foreground">Captions, metadata</span> <span className="text-primary">Brand emphasis</span>

// ❌ Bad - Hardcoded colours <span className="text-[#2F4F4F]">Body text</span> <span style={{ color: "#708090" }}>Helper text</span>

Background Colours

// ✅ Good - Use semantic classes <div className="bg-primary text-primary-foreground">Primary action</div> <div className="bg-content1">Card/panel background</div> <div className="bg-default-100">Subtle background</div> <div className="bg-default-200">Hover state</div>

// ❌ Bad - Hardcoded colours <div className="bg-[#191970]">Navy background</div> <div className="bg-white">Not theme-adaptive</div>

Chart Colours

// ✅ Good - Use CSS variables <div style={{ backgroundColor: var(--chart-${index + 1}) }} /> <div className="bg-[var(--chart-1)]" />

// For bar charts with multiple series {data.map((item, i) => ( <Bar key={item.name} style={{ fill: var(--chart-${i + 1}) }} /> ))}

// For single-highlight charts <Bar className={isHighlighted ? "fill-[var(--chart-1)]" : "fill-default-200"} />

// ❌ Bad - Hardcoded hex colours <div style={{ backgroundColor: "#191970" }} /> <Bar fill="#708090" />

Interactive States

// ✅ Good - Use semantic classes for states <button className="bg-primary text-primary-foreground hover:bg-primary/90"> Primary Button </button>

<Link className="text-default-500 hover:bg-default-100"> Navigation Item </Link>

// Active/selected states <Tab className={isActive ? "bg-primary text-primary-foreground" : "text-default-500"}> Tab Label </Tab>

// ❌ Bad - Hardcoded state colours <button className="bg-[#191970] hover:bg-[#14145A]">Button</button>

Chart Implementation Guidelines

Maximum Series Count

Limit charts to 6 series maximum to match the available --chart-1 through --chart-6 variables:

// ✅ Good - Within 6 series limit {data.slice(0, 5).map((item, i) => ( <Bar style={{ fill: var(--chart-${i + 1}) }} /> ))}

// No modulo needed when series count is controlled colour: var(--chart-${index + 1})

// ❌ Bad - Modulo for unlimited series (indicates design problem) colour: var(--chart-${(index % 6) + 1})

Single-Highlight Pattern

For charts where one element is emphasised:

// Latest year highlighted, others muted {data.map((item, i, arr) => { const isLatest = i === arr.length - 1; return ( <div className={isLatest ? "bg-[var(--chart-1)]" : "bg-default-200 hover:bg-default-300"} /> ); })}

Recharts Implementation

import { Cell, Pie, PieChart } from "recharts";

// Use CSS variables for fill colours <Pie data={chartData} dataKey="value"> {chartData.map((entry, index) => ( <Cell key={cell-${entry.name}} fill={entry.fill} // fill comes from data with var(--chart-N) /> ))} </Pie>

Data Preparation

// Prepare chart data with CSS variable colours const chartData = data.map((item, index) => ({ name: item.name, value: item.count, fill: var(--chart-${index + 1}), }));

HeroUI Theme Integration

The colour system is integrated with HeroUI via apps/web/src/app/hero.ts :

import { heroui } from "@heroui/react";

export default heroui({ themes: { light: { colors: { primary: { DEFAULT: "#191970", // Navy Blue foreground: "#FFFFFF", }, secondary: { DEFAULT: "#708090", // Slate Gray foreground: "#FFFFFF", }, success: { DEFAULT: "#008B8B", // Dark Cyan foreground: "#FFFFFF", }, foreground: "#2F4F4F", // Dark Slate Gray // ... default scale for grays }, }, }, });

HeroUI Default Scale

Use the default scale for UI element states:

Class Usage

bg-default-50

Lightest background

bg-default-100

Subtle background, hover state base

bg-default-200

Muted elements, inactive bars

bg-default-300

Hover state for muted elements

text-default-500

Muted text, placeholders

text-default-600

Secondary text

text-default-900

Strong emphasis (H4 headings)

Dark Mode

Dark CSS variables are fully defined in apps/web/src/app/globals.css (.dark block) and packages/ui/src/styles/globals.css . Dark mode activation is deferred until after HeroUI v3 migration (#714, blocked by #587).

Dark mode readiness guidelines:

  • Use bg-content1 instead of bg-white for card/panel backgrounds (HeroUI semantic, theme-adaptive)

  • Use bg-background for page-level backgrounds (already in use)

  • All CSS variable-based colours (--primary , --chart-N , etc.) automatically adapt to dark mode

  • shadcn/ui and HeroUI components using semantic classes already support dark mode

Migration Checklist

When migrating existing code to the design system:

  • Replace hardcoded hex colours with CSS variables or semantic classes

  • Remove colour constant arrays (e.g., CHART_COLORS , MARKET_SHARE_COLOURS )

  • Use var(--chart-N) inline for chart colours

  • Replace text-gray-* with text-default-*

  • Replace bg-gray-* with bg-default-*

  • Replace bg-white with bg-content1 for card/panel backgrounds

  • Ensure chart series count is 6 or fewer

  • Remove modulo operations if series count is controlled

  • Use text-foreground instead of text-gray-900 for body text

Anti-Patterns

Colour Constant Arrays

// ❌ Bad - Don't create colour arrays const CHART_COLORS = ["#191970", "#2E4A8E", "#4A6AAE", "#708090"]; // ...later backgroundColor: CHART_COLORS[i % CHART_COLORS.length]

// ✅ Good - Use CSS variables inline backgroundColor: var(--chart-${i + 1})

Hardcoded Hex Values

// ❌ Bad - Hardcoded hex <div className="text-[#2F4F4F]">Text</div> <div style={{ backgroundColor: "#191970" }}>Box</div>

// ✅ Good - Semantic tokens <div className="text-foreground">Text</div> <div className="bg-primary">Box</div>

Arbitrary Gray Classes

// ❌ Bad - Tailwind gray scale <span className="text-gray-600">Helper text</span> <div className="bg-gray-100">Background</div>

// ✅ Good - HeroUI default scale <span className="text-default-600">Helper text</span> <div className="bg-default-100">Background</div>

Exceptions

OpenGraph Images

OG images require inline styles and cannot use CSS variables:

// apps/web/src/app/*/opengraph-image.tsx // Inline hex colours are acceptable here <div style={{ backgroundColor: "#191970" }}>

Theme Configuration

The hero.ts theme config uses hex values to define the source of truth:

// apps/web/src/app/hero.ts primary: { DEFAULT: "#191970", // This defines the --primary variable }

Related Files

  • apps/web/src/app/globals.css

  • CSS variable definitions

  • apps/web/src/app/hero.ts

  • HeroUI theme configuration

  • apps/web/CLAUDE.md

  • Colour System section

  • packages/ui/src/styles/globals.css

  • Shared UI package styles

Accessibility (WCAG AA)

  • Normal text: Minimum 4.5:1 contrast ratio

  • Large text: Minimum 3:1 contrast ratio

  • Interactive elements: Minimum 3:1 for focus indicators

  • Colour alone must not convey information (use icons, text, patterns)

The Navy Blue primary (#191970 ) on white background meets WCAG AAA contrast requirements.

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

General

framer-motion-animations

No summary provided by upstream source.

Repository SourceNeeds Review
General

shadcn-components

No summary provided by upstream source.

Repository SourceNeeds Review
General

api-testing

No summary provided by upstream source.

Repository SourceNeeds Review
General

chart-implementation

No summary provided by upstream source.

Repository SourceNeeds Review