design-language-system

安装量: 64
排名: #21083

安装

npx skills add https://github.com/sgcarstrends/sgcarstrends --skill 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 Primary body text Secondary text Muted/helper text Captions, metadata Brand emphasis

// ❌ Bad - Hardcoded colours Body text Helper text

Background Colours // ✅ Good - Use semantic classes

Primary action
Subtle background
Hover state
Card background

// ❌ Bad - Hardcoded colours

Navy background

Chart Colours // ✅ Good - Use CSS variables

var(--chart-${index + 1}) }} />

// For bar charts with multiple series {data.map((item, i) => ( var(--chart-${i + 1}) }} /> ))}

// For single-highlight charts

// ❌ Bad - Hardcoded hex colours

Interactive States // ✅ Good - Use semantic classes for states

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

// Active/selected states Tab Label

// ❌ Bad - Hardcoded state colours

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) => ( 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 (

); })}

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

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

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) 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- 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

Text
Box

// ✅ Good - Semantic tokens

Text
Box

Arbitrary Gray Classes // ❌ Bad - Tailwind gray scale Helper text

Background

// ✅ Good - HeroUI default scale Helper text

Background

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

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.
← 返回排行榜