Compare commits
4 commits
b2cca6d6c3
...
08856c8343
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
08856c8343 | ||
|
|
ab923def34 | ||
|
|
cfbc110be6 | ||
|
|
a25ad2e0b4 |
30 changed files with 1641 additions and 662 deletions
|
|
@ -155,10 +155,10 @@ export const TrackAnalyticsView: React.FC<TrackAnalyticsViewProps> = ({
|
|||
width: `${val}%`,
|
||||
backgroundColor:
|
||||
range === '18-24'
|
||||
? '#7c9dd6'
|
||||
? 'var(--sumi-viz-indigo)'
|
||||
: range === '25-34'
|
||||
? '#7a9e6c'
|
||||
: '#2a2a31',
|
||||
? 'var(--sumi-viz-sage)'
|
||||
: 'var(--sumi-bg-hover)',
|
||||
}}
|
||||
>
|
||||
<div className="absolute inset-0 flex items-center justify-center text-xs font-bold text-foreground opacity-0 group-hover:opacity-100 transition-opacity">
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ export function BarChart({
|
|||
data,
|
||||
xAxisLabel,
|
||||
yAxisLabel,
|
||||
color = '#7c9dd6',
|
||||
color = 'var(--sumi-viz-indigo)',
|
||||
showGrid = true,
|
||||
showValues = false,
|
||||
height = 300,
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ export function LineChart({
|
|||
data,
|
||||
xAxisLabel,
|
||||
yAxisLabel,
|
||||
color = '#7c9dd6',
|
||||
color = 'var(--sumi-viz-indigo)',
|
||||
showGrid = true,
|
||||
showDots = true,
|
||||
height = 300,
|
||||
|
|
|
|||
|
|
@ -15,15 +15,18 @@ export interface PieChartProps extends Omit<ChartProps, 'children'> {
|
|||
colors?: string[];
|
||||
}
|
||||
|
||||
// Data viz pigments — see CHARTE_GRAPHIQUE_TALAS §4.5 (data viz only).
|
||||
// First 5 are canonical; sakura/terminal/magenta are app-specific extras pending
|
||||
// canonical definition in tokens (follow-up Sprint 2).
|
||||
const DEFAULT_COLORS = [
|
||||
'#7c9dd6', // indigo
|
||||
'#d4634a', // vermillion
|
||||
'#7a9e6c', // sage
|
||||
'#c9a84c', // gold
|
||||
'#a8a4a0', // text-secondary
|
||||
'#e0a0b8', // sakura
|
||||
'#3eaa5e', // terminal-green
|
||||
'#c840a0', // graffiti-magenta
|
||||
'var(--sumi-viz-indigo)',
|
||||
'var(--sumi-viz-vermillion)',
|
||||
'var(--sumi-viz-sage)',
|
||||
'var(--sumi-viz-gold)',
|
||||
'var(--sumi-viz-neutral)',
|
||||
'#e0a0b8', // sakura — TODO: canonize in tokens/primitive/color.json viz palette
|
||||
'#3eaa5e', // terminal-green — TODO: canonize
|
||||
'#c840a0', // graffiti-magenta — TODO: canonize
|
||||
];
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -240,7 +240,7 @@ export function SwaggerUIDoc({ specUrl, spec, useIframe = false }: SwaggerUIProp
|
|||
color: rgba(255, 255, 255, 0.8);
|
||||
}
|
||||
.swagger-ui-container .swagger-ui .parameter__name {
|
||||
color: #7c9dd6;
|
||||
color: var(--sumi-viz-indigo);
|
||||
}
|
||||
.swagger-ui-container .swagger-ui .response-col_status {
|
||||
color: #fff;
|
||||
|
|
@ -256,7 +256,7 @@ export function SwaggerUIDoc({ specUrl, spec, useIframe = false }: SwaggerUIProp
|
|||
color: #fff;
|
||||
}
|
||||
.swagger-ui-container .swagger-ui .btn {
|
||||
background: #7c9dd6;
|
||||
background: var(--sumi-viz-indigo);
|
||||
color: #000;
|
||||
border: none;
|
||||
}
|
||||
|
|
@ -264,7 +264,7 @@ export function SwaggerUIDoc({ specUrl, spec, useIframe = false }: SwaggerUIProp
|
|||
background: #93afe0;
|
||||
}
|
||||
.swagger-ui-container .swagger-ui .btn.execute {
|
||||
background: #7c9dd6;
|
||||
background: var(--sumi-viz-indigo);
|
||||
color: #000;
|
||||
}
|
||||
.swagger-ui-container .swagger-ui .btn.cancel {
|
||||
|
|
|
|||
|
|
@ -91,8 +91,8 @@ export const WaveformVisualizer: React.FC<WaveformVisualizerProps> = ({
|
|||
progress,
|
||||
onSeek,
|
||||
height = 64,
|
||||
color = '#2a2a31', // sumi-bg-hover
|
||||
playedColor = '#7c9dd6', // sumi-accent
|
||||
color = 'var(--sumi-bg-hover)',
|
||||
playedColor = 'var(--sumi-viz-indigo)',
|
||||
}) => {
|
||||
const canvasRef = useRef<HTMLCanvasElement>(null);
|
||||
const [data, setData] = useState<number[]>([]);
|
||||
|
|
@ -133,6 +133,15 @@ export const WaveformVisualizer: React.FC<WaveformVisualizerProps> = ({
|
|||
const gap = 1;
|
||||
const effectiveBarWidth = Math.max(1, barWidth - gap);
|
||||
|
||||
// Resolve CSS vars to hex values (canvas can't resolve var() directly)
|
||||
const styles = getComputedStyle(canvas);
|
||||
const resolve = (c: string) =>
|
||||
c.startsWith('var(')
|
||||
? styles.getPropertyValue(c.slice(4, -1).trim()).trim() || c
|
||||
: c;
|
||||
const resolvedColor = resolve(color);
|
||||
const resolvedPlayed = resolve(playedColor);
|
||||
|
||||
data.forEach((val, i) => {
|
||||
const x = i * barWidth;
|
||||
const barHeight = val * drawHeight;
|
||||
|
|
@ -140,7 +149,7 @@ export const WaveformVisualizer: React.FC<WaveformVisualizerProps> = ({
|
|||
|
||||
// Determine color based on progress
|
||||
const isPlayed = (i / data.length) * 100 <= progress;
|
||||
ctx.fillStyle = isPlayed ? playedColor : color;
|
||||
ctx.fillStyle = isPlayed ? resolvedPlayed : resolvedColor;
|
||||
|
||||
// Draw rounded rect equivalent
|
||||
ctx.fillRect(x, y, effectiveBarWidth, barHeight);
|
||||
|
|
|
|||
|
|
@ -175,8 +175,8 @@ export const MetadataEditor: React.FC<MetadataEditorProps> = ({
|
|||
progress={progress}
|
||||
onSeek={setProgress}
|
||||
height={48}
|
||||
color="#2a2a31"
|
||||
playedColor="#7c9dd6"
|
||||
color="var(--sumi-bg-hover)"
|
||||
playedColor="var(--sumi-viz-indigo)"
|
||||
/>
|
||||
</div>
|
||||
</Card>
|
||||
|
|
|
|||
|
|
@ -13,6 +13,13 @@ import { cn } from '@/lib/utils';
|
|||
import { Button } from '@/components/ui/button';
|
||||
import { BarChart3, Activity, Radio } from 'lucide-react';
|
||||
import type { VisualizerMode } from '../hooks/useSpectrumAnalyser';
|
||||
import {
|
||||
ColorVizIndigo,
|
||||
ColorVizVermillion,
|
||||
ColorVizSage,
|
||||
ColorVizGold,
|
||||
ColorVoidBase,
|
||||
} from '@veza/design-system/tokens-generated';
|
||||
|
||||
interface AudioVisualizerProps {
|
||||
/** Normalized frequency bands [0-1] */
|
||||
|
|
@ -31,11 +38,24 @@ const MODES: { mode: VisualizerMode; icon: typeof BarChart3; label: string }[] =
|
|||
{ mode: 'spectrogram', icon: Radio, label: 'Spectrogram' },
|
||||
];
|
||||
|
||||
// SUMI colors
|
||||
const ACCENT_COLOR = '#7c9dd6'; // --sumi-accent
|
||||
const SAGE = '#7a9e6c'; // --sumi-sage
|
||||
const GOLD = '#c9a84c'; // --sumi-gold
|
||||
const BG_VOID = '#0c0c0f'; // --sumi-bg-void
|
||||
// SUMI colors — resolved hex values from generated tokens (source of truth: packages/design-system/tokens/).
|
||||
// Canvas can't resolve var(--sumi-*) directly, so we use the imported hex strings to enable
|
||||
// gradient interpolation and string concatenation (alpha suffix) below.
|
||||
const ACCENT_COLOR = ColorVizIndigo;
|
||||
const VERMILLION = ColorVizVermillion;
|
||||
const SAGE = ColorVizSage;
|
||||
const GOLD = ColorVizGold;
|
||||
const BG_VOID = ColorVoidBase;
|
||||
|
||||
// Decompose hex colors to RGB byte tuples for spectrogram interpolation.
|
||||
const hexToRgb = (hex: string): [number, number, number] => {
|
||||
const m = hex.match(/^#?([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})$/i);
|
||||
if (!m || !m[1] || !m[2] || !m[3]) return [0, 0, 0];
|
||||
return [parseInt(m[1], 16), parseInt(m[2], 16), parseInt(m[3], 16)];
|
||||
};
|
||||
const [I_R, I_G, I_B] = hexToRgb(ACCENT_COLOR);
|
||||
const [V_R, V_G, V_B] = hexToRgb(VERMILLION);
|
||||
const [GOLD_R, GOLD_G, GOLD_B] = hexToRgb(GOLD);
|
||||
|
||||
export function AudioVisualizer({
|
||||
bands,
|
||||
|
|
@ -75,11 +95,11 @@ export function AudioVisualizer({
|
|||
const x = i * (barWidth + gap);
|
||||
const y = H - barH;
|
||||
|
||||
// Gradient from accent to vermillion based on frequency
|
||||
// Gradient from accent (indigo) to vermillion based on frequency
|
||||
const t = i / barCount;
|
||||
const r = lerp(0x7c, 0xd4, t);
|
||||
const g = lerp(0x9d, 0x63, t);
|
||||
const b = lerp(0xd6, 0x4a, t);
|
||||
const r = lerp(I_R, V_R, t);
|
||||
const g = lerp(I_G, V_G, t);
|
||||
const b = lerp(I_B, V_B, t);
|
||||
ctx.fillStyle = `rgb(${r}, ${g}, ${b})`;
|
||||
|
||||
// Rounded top rect
|
||||
|
|
@ -276,21 +296,19 @@ function lerp(a: number, b: number, t: number): number {
|
|||
}
|
||||
|
||||
function spectrogramColor(intensity: number): [number, number, number] {
|
||||
// 0..0.25: black → deep blue
|
||||
// 0.25..0.5: deep blue → accent
|
||||
// 0.5..0.75: accent → vermillion
|
||||
// 0.75..1: vermillion → gold
|
||||
// Heat map: black → deep blue → indigo → vermillion → gold
|
||||
// Bytes derived from token-imported hex via hexToRgb (above).
|
||||
if (intensity < 0.25) {
|
||||
const t = intensity / 0.25;
|
||||
return [lerp(12, 40, t), lerp(12, 50, t), lerp(15, 100, t)];
|
||||
} else if (intensity < 0.5) {
|
||||
const t = (intensity - 0.25) / 0.25;
|
||||
return [lerp(40, 0x7c, t), lerp(50, 0x9d, t), lerp(100, 0xd6, t)];
|
||||
return [lerp(40, I_R, t), lerp(50, I_G, t), lerp(100, I_B, t)];
|
||||
} else if (intensity < 0.75) {
|
||||
const t = (intensity - 0.5) / 0.25;
|
||||
return [lerp(0x7c, 0xd4, t), lerp(0x9d, 0x63, t), lerp(0xd6, 0x4a, t)];
|
||||
return [lerp(I_R, V_R, t), lerp(I_G, V_G, t), lerp(I_B, V_B, t)];
|
||||
} else {
|
||||
const t = (intensity - 0.75) / 0.25;
|
||||
return [lerp(0xd4, 0xc9, t), lerp(0x63, 0xa8, t), lerp(0x4a, 0x4c, t)];
|
||||
return [lerp(V_R, GOLD_R, t), lerp(V_G, GOLD_G, t), lerp(V_B, GOLD_B, t)];
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ export function PlaybackDashboardCharts({
|
|||
data={sessionsChartData}
|
||||
xAxisLabel="Date"
|
||||
yAxisLabel="Nombre de sessions"
|
||||
color="#7c9dd6"
|
||||
color="var(--sumi-viz-indigo)"
|
||||
height={300}
|
||||
showGrid
|
||||
showDots
|
||||
|
|
@ -56,7 +56,7 @@ export function PlaybackDashboardCharts({
|
|||
data={playTimeChartData}
|
||||
xAxisLabel="Date"
|
||||
yAxisLabel="Temps moyen (secondes)"
|
||||
color="#7a9e6c"
|
||||
color="var(--sumi-viz-sage)"
|
||||
height={300}
|
||||
showGrid
|
||||
showDots
|
||||
|
|
@ -78,7 +78,7 @@ export function PlaybackDashboardCharts({
|
|||
data={completionChartData}
|
||||
xAxisLabel="Date"
|
||||
yAxisLabel="Taux de complétion (%)"
|
||||
color="#c9a84c"
|
||||
color="var(--sumi-viz-gold)"
|
||||
height={300}
|
||||
showGrid
|
||||
showDots
|
||||
|
|
|
|||
|
|
@ -1,6 +1,12 @@
|
|||
@import 'tailwindcss';
|
||||
@import 'tw-animate-css';
|
||||
|
||||
/* SUMI generated tokens — Single source of truth. See packages/design-system/tokens/.
|
||||
This adds --color-* primitives and --sumi-* semantics (bg/text/accent/viz/feedback).
|
||||
The legacy :root block below still defines additional --sumi-* vars (typography, motion,
|
||||
z-index, glass…) pending migration to tokens.json (Sprint 2 follow-up). */
|
||||
@import '@veza/design-system/tokens.css';
|
||||
|
||||
@custom-variant dark (&:is([data-theme="dark"] *));
|
||||
|
||||
/* ╔══════════════════════════════════════════════════════════════════════════╗
|
||||
|
|
|
|||
1009
package-lock.json
generated
1009
package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
|
@ -1,87 +1,106 @@
|
|||
# @veza/design-system
|
||||
|
||||
**SUMI Design System v2.0** — "L'encre et la lumière" (Ink and Light)
|
||||
**SUMI Design System v3.0** — "Lavis d'encre" (Ink wash)
|
||||
|
||||
The centralized design system for the Veza platform. Provides design tokens, component type registry, and utilities.
|
||||
Token-only package for the Veza platform. Single source of truth for all design tokens (colors, typography, spacing, motion, elevation), authored as W3C-spec JSON tokens and compiled via Style Dictionary to CSS variables and TypeScript exports.
|
||||
|
||||
## Structure
|
||||
|
||||
```
|
||||
packages/design-system/
|
||||
├── src/
|
||||
│ ├── index.ts # Barrel exports
|
||||
│ ├── utils.ts # cn() utility
|
||||
│ ├── tokens/
|
||||
│ │ ├── index.ts # All token exports
|
||||
│ │ ├── colors.ts # Background, surface, text, pigment, semantic colors
|
||||
│ │ ├── typography.ts # Font families, sizes, weights, line heights
|
||||
│ │ ├── spacing.ts # Spacing scale, border radius, z-index, layout
|
||||
│ │ └── motion.ts # Duration and easing tokens
|
||||
│ └── components/
|
||||
│ └── index.ts # Component type registry
|
||||
├── tokens/ # SOURCE OF TRUTH (edit these)
|
||||
│ ├── primitive/
|
||||
│ │ ├── color.json # ink, washi, void, mizu, kin, viz, functional, alpha
|
||||
│ │ ├── typography.json # Space Grotesk + Inter + JetBrains Mono scales
|
||||
│ │ ├── spacing.json # 4px scale + radius + z-index
|
||||
│ │ ├── motion.json # goutte/trait/lavis/vague/maree + easings
|
||||
│ │ └── elevation.json # shadows + blur + opacity
|
||||
│ └── semantic/
|
||||
│ ├── dark.json # default :root, [data-theme="dark"]
|
||||
│ └── light.json # [data-theme="light"] (washi paper)
|
||||
├── dist/ # GENERATED (do NOT edit, gitignored)
|
||||
│ ├── tokens.css # Unified primitive + dark + light
|
||||
│ ├── tokens-{primitive,dark,light}.css
|
||||
│ └── tokens.{ts,d.ts} # TS exports of resolved hex values
|
||||
├── style-dictionary.config.mjs # Build config
|
||||
└── package.json
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
### Design Tokens (TypeScript)
|
||||
### CSS variables (recommended for UI)
|
||||
|
||||
```typescript
|
||||
import { pigments, fontFamilies, spacing } from '@veza/design-system/tokens';
|
||||
|
||||
// Colors
|
||||
pigments.accent.base // '#7c9dd6'
|
||||
pigments.vermillion.base // '#d4634a'
|
||||
|
||||
// Typography
|
||||
fontFamilies.heading // "'Space Grotesk', 'Inter', sans-serif"
|
||||
|
||||
// Spacing
|
||||
spacing['4'] // '16px'
|
||||
```
|
||||
|
||||
### Design Tokens (CSS)
|
||||
|
||||
The CSS custom properties are the primary token interface, defined in `apps/web/src/index.css`:
|
||||
`apps/web/src/index.css` imports the unified file:
|
||||
|
||||
```css
|
||||
color: var(--sumi-accent);
|
||||
padding: var(--sumi-space-4);
|
||||
font-family: var(--sumi-font-heading);
|
||||
border-radius: var(--sumi-radius-md);
|
||||
@import '@veza/design-system/tokens.css';
|
||||
```
|
||||
|
||||
### Components
|
||||
Then components reference vars via Tailwind arbitrary values or inline styles:
|
||||
|
||||
Components are implemented in `apps/web/src/components/ui/` and imported via path alias:
|
||||
|
||||
```typescript
|
||||
import { Button } from '@/components/ui/button';
|
||||
import { Card } from '@/components/ui/card';
|
||||
import { Dialog } from '@/components/ui/dialog';
|
||||
```tsx
|
||||
<div style={{ color: 'var(--sumi-accent-default)' }}>...</div>
|
||||
<div className="bg-[var(--sumi-bg-card)] text-[var(--sumi-text-primary)]">...</div>
|
||||
```
|
||||
|
||||
See `apps/web/.storybook/` for Storybook documentation of all components.
|
||||
### TypeScript imports (for canvas / runtime needs)
|
||||
|
||||
For contexts that can't resolve CSS vars (canvas drawing, programmatic gradients, byte interpolation):
|
||||
|
||||
```ts
|
||||
import { ColorVizIndigo, SumiAccentDefault } from '@veza/design-system/tokens-generated';
|
||||
|
||||
ctx.fillStyle = ColorVizIndigo; // resolved hex string '#7c9dd6'
|
||||
const accent = SumiAccentDefault; // '#0098b5'
|
||||
```
|
||||
|
||||
## Build
|
||||
|
||||
```bash
|
||||
npm run build:tokens --workspace=@veza/design-system
|
||||
```
|
||||
|
||||
Triggered automatically via `turbo run build` (the apps/web build depends on this package).
|
||||
|
||||
## Color system — Option B palette
|
||||
|
||||
Per `CHARTE_GRAPHIQUE_TALAS.md` §4 (canonical brand source) + §4.5 (data viz):
|
||||
|
||||
### UI palette (everywhere except data viz)
|
||||
|
||||
The cyan **Mizu** (`#0098B5`) is the **sole** accent color. Functional colors (success/error/warning) are always diluted (max 60% opacity), never solid fills.
|
||||
|
||||
| Token | Role | Value |
|
||||
|-------|------|-------|
|
||||
| `--sumi-accent-default` | Primary actions, links, focus | Mizu cyan `#0098B5` |
|
||||
| `--sumi-feedback-success` | Success states (subtle) | Diluted sage |
|
||||
| `--sumi-feedback-error` | Error states (subtle) | Diluted brick |
|
||||
| `--sumi-feedback-warning` | Warning states (subtle) | Diluted amber |
|
||||
|
||||
### Data viz palette (charts, waveforms, analytics ONLY)
|
||||
|
||||
For graphs and visualizations needing distinguishable colors, the 4 viz pigments + neutral are authorized:
|
||||
|
||||
| Pigment | Hex | Token |
|
||||
|---------|-----|-------|
|
||||
| Indigo | `#7c9dd6` | `--sumi-viz-indigo` |
|
||||
| Vermillion | `#d4634a` | `--sumi-viz-vermillion` |
|
||||
| Sage | `#7a9e6c` | `--sumi-viz-sage` |
|
||||
| Gold | `#c9a84c` | `--sumi-viz-gold` |
|
||||
| Neutral grey | `#a8a4a0` | `--sumi-viz-neutral` |
|
||||
|
||||
**These are NEVER allowed in standard UI** (buttons, links, accents). The cyan rule above stays absolute.
|
||||
|
||||
## Themes
|
||||
|
||||
- **Dark** (default) — Ink on void
|
||||
- **Light** — Washi paper aesthetic (`[data-theme="light"]`)
|
||||
- **High Contrast** — WCAG AA 4.5:1+ (`[data-contrast="high"]`)
|
||||
- **Compact Density** — Reduced spacing (`[data-density="compact"]`)
|
||||
- **Circadian + patina + density + contrast** — Runtime modifiers handled by `apps/web/src/components/theme/ThemeProvider.tsx`
|
||||
|
||||
## Color System — The 4 Pigments
|
||||
## See also
|
||||
|
||||
| Pigment | Hex | Usage |
|
||||
|---------|-----|-------|
|
||||
| **Accent** (Indigo) | `#7c9dd6` | Primary actions, links, focus |
|
||||
| **Vermillion** | `#d4634a` | Errors, destructive, live |
|
||||
| **Sage** | `#7a9e6c` | Success, online |
|
||||
| **Gold** | `#c9a84c` | Warnings, achievements |
|
||||
|
||||
## References
|
||||
|
||||
- Design tokens source: `apps/web/src/index.css`
|
||||
- Token documentation: `apps/web/docs/DESIGN_TOKENS.md`
|
||||
- Brand source of truth: `~/Documents/TG__Talas_Group/05_EXPERIENCE_UTILISATEUR/CHARTE_GRAPHIQUE_TALAS.md`
|
||||
- Brand decisions: `~/Documents/TG__Talas_Group/05_EXPERIENCE_UTILISATEUR/DECISIONS_IDENTITE.md`
|
||||
- Veza UI/UX contract: `veza-docs/ORIGIN/ORIGIN_UI_UX_SYSTEM.md`
|
||||
- Storybook: `apps/web/.storybook/`
|
||||
- Component source: `apps/web/src/components/ui/`
|
||||
|
|
|
|||
|
|
@ -1,34 +1,26 @@
|
|||
{
|
||||
"name": "@veza/design-system",
|
||||
"version": "2.0.0",
|
||||
"description": "SUMI Design System — Design tokens, utilities, and component re-exports for the Veza platform",
|
||||
"version": "3.0.0",
|
||||
"description": "SUMI Design System — Design tokens (single source of truth) for the Veza platform. Authored as W3C JSON tokens, compiled via Style Dictionary to CSS vars + TS exports.",
|
||||
"type": "module",
|
||||
"main": "./src/index.ts",
|
||||
"types": "./src/index.ts",
|
||||
"exports": {
|
||||
".": "./src/index.ts",
|
||||
"./tokens": "./src/tokens/index.ts",
|
||||
"./tokens/colors": "./src/tokens/colors.ts",
|
||||
"./tokens/typography": "./src/tokens/typography.ts",
|
||||
"./tokens/spacing": "./src/tokens/spacing.ts",
|
||||
"./tokens/motion": "./src/tokens/motion.ts"
|
||||
"./tokens.css": "./dist/tokens.css",
|
||||
"./tokens-generated": {
|
||||
"types": "./dist/tokens.d.ts",
|
||||
"default": "./dist/tokens.ts"
|
||||
}
|
||||
},
|
||||
"files": [
|
||||
"src/"
|
||||
"tokens/",
|
||||
"dist/",
|
||||
"style-dictionary.config.mjs"
|
||||
],
|
||||
"scripts": {
|
||||
"typecheck": "tsc --noEmit"
|
||||
},
|
||||
"dependencies": {
|
||||
"clsx": "^2.0.0",
|
||||
"tailwind-merge": "^3.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": ">=18",
|
||||
"react-dom": ">=18"
|
||||
"build": "node style-dictionary.config.mjs",
|
||||
"build:tokens": "node style-dictionary.config.mjs"
|
||||
},
|
||||
"devDependencies": {
|
||||
"typescript": "^5.9.0"
|
||||
"style-dictionary": "^4.4.0"
|
||||
},
|
||||
"license": "UNLICENSED"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,116 +0,0 @@
|
|||
/**
|
||||
* SUMI Design System v2.0 — Component Registry
|
||||
*
|
||||
* This file documents the canonical component set of the SUMI design system.
|
||||
* Components are implemented in apps/web/src/components/ui/ and imported
|
||||
* from there using the @/components/ui/ path alias.
|
||||
*
|
||||
* To use in the web app:
|
||||
* import { Button } from '@/components/ui/button';
|
||||
* import { Card } from '@/components/ui/card';
|
||||
*
|
||||
* This registry exists for documentation and type-checking purposes.
|
||||
*/
|
||||
|
||||
/**
|
||||
* SUMI Component Categories:
|
||||
*
|
||||
* ═══ PRIMITIVES ═══
|
||||
* Button — Primary action element (variants: default, destructive, outline, secondary, ghost, link)
|
||||
* Input — Text input field
|
||||
* Textarea — Multi-line text input
|
||||
* Label — Form field label
|
||||
* Checkbox — Binary selection
|
||||
* RadioGroup — Single selection from options
|
||||
* Switch — Toggle control
|
||||
* Slider — Range input
|
||||
* Select — Dropdown selection
|
||||
*
|
||||
* ═══ LAYOUT ═══
|
||||
* Card — Content container with border
|
||||
* Accordion — Collapsible content sections
|
||||
* Tabs — Tabbed content panels
|
||||
* Sidebar — Navigation sidebar
|
||||
* ScrollArea — Custom scrollable container
|
||||
* Table — Data table
|
||||
*
|
||||
* ═══ FEEDBACK ═══
|
||||
* Alert — Informational message
|
||||
* Badge — Status indicator
|
||||
* Dialog — Modal dialog
|
||||
* Toast — Temporary notification
|
||||
* Tooltip — Hover information
|
||||
* HoverCard — Rich hover popup
|
||||
* Skeleton — Loading placeholder
|
||||
* Progress — Progress indicator
|
||||
* LoadingSpinner — Animated spinner
|
||||
*
|
||||
* ═══ NAVIGATION ═══
|
||||
* DropdownMenu — Contextual menu
|
||||
* ContextMenu — Right-click menu
|
||||
* NavigationProgress — Page transition indicator
|
||||
*
|
||||
* ═══ SPECIALIZED ═══
|
||||
* FileUpload — File upload with drag & drop
|
||||
* AvatarUpload — Avatar image upload with cropper
|
||||
* DatePicker — Date selection
|
||||
* VirtualizedList — Virtualized scrolling for large lists
|
||||
* OptimizedImage — Responsive image with blur placeholder
|
||||
* AnimatedNumber — Animated numeric display
|
||||
*/
|
||||
|
||||
// Component type exports for type-safety when referencing SUMI components
|
||||
export type SumiComponentName =
|
||||
// Primitives
|
||||
| 'Button'
|
||||
| 'Input'
|
||||
| 'Textarea'
|
||||
| 'Label'
|
||||
| 'Checkbox'
|
||||
| 'RadioGroup'
|
||||
| 'Switch'
|
||||
| 'Slider'
|
||||
| 'Select'
|
||||
| 'FloatingInput'
|
||||
// Layout
|
||||
| 'Card'
|
||||
| 'Accordion'
|
||||
| 'Tabs'
|
||||
| 'Sidebar'
|
||||
| 'ScrollArea'
|
||||
| 'Table'
|
||||
| 'Collapsible'
|
||||
// Feedback
|
||||
| 'Alert'
|
||||
| 'Badge'
|
||||
| 'Dialog'
|
||||
| 'ConfirmationDialog'
|
||||
| 'Toast'
|
||||
| 'Tooltip'
|
||||
| 'HoverCard'
|
||||
| 'Skeleton'
|
||||
| 'Progress'
|
||||
| 'LoadingSpinner'
|
||||
| 'LoadingState'
|
||||
| 'ErrorBoundary'
|
||||
| 'ErrorDisplay'
|
||||
// Navigation
|
||||
| 'DropdownMenu'
|
||||
| 'ContextMenu'
|
||||
| 'NavigationProgress'
|
||||
| 'ScrollToTop'
|
||||
// Specialized
|
||||
| 'Avatar'
|
||||
| 'AvatarUpload'
|
||||
| 'FileUpload'
|
||||
| 'DatePicker'
|
||||
| 'ImageCropper'
|
||||
| 'VirtualizedList'
|
||||
| 'OptimizedImage'
|
||||
| 'AnimatedNumber'
|
||||
| 'DataList'
|
||||
| 'FormField'
|
||||
| 'FAB'
|
||||
| 'FocusTrap'
|
||||
| 'KeyboardShortcutsPanel'
|
||||
| 'WaveformVisualizer';
|
||||
|
|
@ -1,52 +0,0 @@
|
|||
/**
|
||||
* @veza/design-system — SUMI Design System v2.0
|
||||
* "L'encre et la lumière" — Ink and Light
|
||||
*
|
||||
* This package provides:
|
||||
* - Design tokens (colors, typography, spacing, motion) as TypeScript objects
|
||||
* - Component type registry for the SUMI component set
|
||||
* - Utility functions (cn)
|
||||
*
|
||||
* Components are implemented in apps/web/src/components/ui/ and should be
|
||||
* imported from there using the @/components/ui/ path alias.
|
||||
*
|
||||
* Usage:
|
||||
* import { colors, typography } from '@veza/design-system/tokens';
|
||||
* import { pigments } from '@veza/design-system/tokens/colors';
|
||||
*/
|
||||
|
||||
// ═══ Design Tokens ═══
|
||||
export {
|
||||
colors,
|
||||
backgrounds,
|
||||
surfaces,
|
||||
borders,
|
||||
text,
|
||||
pigments,
|
||||
semantic,
|
||||
glass,
|
||||
shadows,
|
||||
lightTheme,
|
||||
typography,
|
||||
fontFamilies,
|
||||
fontSizes,
|
||||
lineHeights,
|
||||
letterSpacings,
|
||||
fontWeights,
|
||||
spacingTokens,
|
||||
spacing,
|
||||
radius,
|
||||
zIndex,
|
||||
layout,
|
||||
motion,
|
||||
durations,
|
||||
easings,
|
||||
} from './tokens';
|
||||
|
||||
export type { SumiColor } from './tokens';
|
||||
|
||||
// ═══ Component Registry ═══
|
||||
export type { SumiComponentName } from './components';
|
||||
|
||||
// ═══ Utilities ═══
|
||||
export { cn } from './utils';
|
||||
|
|
@ -1,191 +0,0 @@
|
|||
/**
|
||||
* SUMI Design System v4.0 — Color Tokens
|
||||
* "Lavis d'encre" — Ink Wash (墨の濃淡)
|
||||
*
|
||||
* Named after traditional Japanese ink tones:
|
||||
* Kuro (黒), Sumi (墨), Usuzumi (薄墨), Hai (灰), Gin (銀), Kasumi (霞)
|
||||
* Shiro (白), Kinari (生成), Kinu (絹), Torinoko (鳥の子), Cha (茶)
|
||||
*
|
||||
* Source of truth: apps/web/src/index.css
|
||||
*/
|
||||
|
||||
// ═══ DARK THEME (default) — Ink on void (墨の闇) ═══
|
||||
|
||||
export const backgrounds = {
|
||||
void: '#0d0d0b',
|
||||
base: '#13110f',
|
||||
raised: '#1a1714',
|
||||
overlay: '#242018',
|
||||
hover: '#2e2a22',
|
||||
active: '#383228',
|
||||
wash: '#17140f',
|
||||
} as const;
|
||||
|
||||
export const surfaces = {
|
||||
inset: '#0f0d0b',
|
||||
subtle: '#1e1a15',
|
||||
card: '#1a1714',
|
||||
elevated: '#242018',
|
||||
} as const;
|
||||
|
||||
export const borders = {
|
||||
faint: 'rgba(232,224,208, 0.03)',
|
||||
default: 'rgba(232,224,208, 0.06)',
|
||||
strong: 'rgba(232,224,208, 0.10)',
|
||||
focus: 'rgba(184,58,30, 0.50)',
|
||||
accent: 'rgba(184,58,30, 0.25)',
|
||||
} as const;
|
||||
|
||||
export const text = {
|
||||
primary: '#e8e0d0',
|
||||
secondary: '#9e9688',
|
||||
tertiary: '#6b6560',
|
||||
disabled: '#3d3930',
|
||||
inverse: '#13110f',
|
||||
link: '#b83a1e',
|
||||
} as const;
|
||||
|
||||
// ═══ PIGMENTS — Shu vermillion primary (朱) + Kin gold (金) ═══
|
||||
|
||||
export const pigments = {
|
||||
accent: {
|
||||
base: '#b83a1e',
|
||||
hover: '#c84a2e',
|
||||
active: '#8b2500',
|
||||
muted: 'rgba(184,58,30, 0.18)',
|
||||
subtle: 'rgba(184,58,30, 0.06)',
|
||||
emphasis: '#8b2500',
|
||||
},
|
||||
vermillion: {
|
||||
base: '#a04050',
|
||||
hover: '#b05060',
|
||||
subtle: 'rgba(160,64,80, 0.10)',
|
||||
},
|
||||
sage: {
|
||||
base: '#4f6840',
|
||||
hover: '#5f7850',
|
||||
subtle: 'rgba(79,104,64, 0.10)',
|
||||
},
|
||||
gold: {
|
||||
base: '#b8860b',
|
||||
hover: '#c8960b',
|
||||
subtle: 'rgba(184,134,11, 0.10)',
|
||||
},
|
||||
kin: {
|
||||
base: '#b8860b',
|
||||
glow: '0 0 8px rgba(184,134,11, 0.2)',
|
||||
},
|
||||
patinaGreen: {
|
||||
base: '#5A8A72',
|
||||
},
|
||||
} as const;
|
||||
|
||||
// ═══ SEMANTIC ═══
|
||||
|
||||
export const semantic = {
|
||||
success: pigments.sage.base,
|
||||
successSubtle: pigments.sage.subtle,
|
||||
warning: pigments.gold.base,
|
||||
warningSubtle: pigments.gold.subtle,
|
||||
error: pigments.vermillion.base,
|
||||
errorSubtle: pigments.vermillion.subtle,
|
||||
info: pigments.accent.base,
|
||||
live: '#a04050',
|
||||
online: pigments.sage.base,
|
||||
} as const;
|
||||
|
||||
// ═══ GLASS — Shoji screen (障子) ═══
|
||||
|
||||
export const glass = {
|
||||
bg: 'rgba(19,17,15, 0.80)',
|
||||
border: 'rgba(232,224,208, 0.04)',
|
||||
blur: '12px',
|
||||
} as const;
|
||||
|
||||
// ═══ SHADOWS — Ink diffusion (滲み) ═══
|
||||
|
||||
export const shadows = {
|
||||
xs: '0 1px 3px rgba(13,13,11,0.20)',
|
||||
sm: '0 2px 8px rgba(13,13,11,0.15), 0 1px 3px rgba(13,13,11,0.12)',
|
||||
md: '0 4px 20px rgba(13,13,11,0.15), 0 2px 6px rgba(13,13,11,0.10)',
|
||||
lg: '0 8px 35px rgba(13,13,11,0.18), 0 4px 12px rgba(13,13,11,0.10)',
|
||||
xl: '0 16px 55px rgba(13,13,11,0.22), 0 8px 20px rgba(13,13,11,0.12)',
|
||||
'2xl': '0 24px 75px rgba(13,13,11,0.30)',
|
||||
glow: '0 0 0 3px rgba(184,58,30, 0.20)',
|
||||
glowLg: '0 0 20px rgba(184,58,30, 0.10)',
|
||||
kin: '0 0 16px rgba(184,134,11, 0.15)',
|
||||
} as const;
|
||||
|
||||
// ═══ LIGHT THEME — Washi paper (和紙) ═══
|
||||
|
||||
export const lightTheme = {
|
||||
backgrounds: {
|
||||
void: '#e8e0cf',
|
||||
base: '#f0ebe0',
|
||||
raised: '#f0ebe0',
|
||||
overlay: '#f0ebe0',
|
||||
hover: '#e4dccb',
|
||||
active: '#ddd4c0',
|
||||
wash: '#ece5d6',
|
||||
},
|
||||
surfaces: {
|
||||
inset: '#e0d8c8',
|
||||
subtle: '#e8e0cf',
|
||||
card: '#f0ebe0',
|
||||
elevated: '#f5f0e5',
|
||||
},
|
||||
borders: {
|
||||
faint: 'rgba(26,23,20, 0.04)',
|
||||
default: 'rgba(26,23,20, 0.06)',
|
||||
strong: 'rgba(26,23,20, 0.12)',
|
||||
focus: 'rgba(139,37,0, 0.45)',
|
||||
accent: 'rgba(139,37,0, 0.20)',
|
||||
},
|
||||
text: {
|
||||
primary: '#1a1714',
|
||||
secondary: '#3d3930',
|
||||
tertiary: '#6b6560',
|
||||
disabled: '#c4bba8',
|
||||
inverse: '#e8e0d0',
|
||||
link: '#8b2500',
|
||||
},
|
||||
} as const;
|
||||
|
||||
// ═══ INK TONES — 墨の六色 ═══
|
||||
|
||||
export const inkTones = {
|
||||
kuro: '#0d0d0b',
|
||||
sumi: '#1a1714',
|
||||
usuzumi: '#3d3930',
|
||||
hai: '#6b6560',
|
||||
gin: '#9e9688',
|
||||
kasumi: '#c4bba8',
|
||||
} as const;
|
||||
|
||||
// ═══ WASHI TONES — 和紙の色 ═══
|
||||
|
||||
export const washiTones = {
|
||||
shiro: '#f0ebe0',
|
||||
kinari: '#e8e0cf',
|
||||
kinu: '#ddd4c0',
|
||||
torinoko: '#d0c5ad',
|
||||
cha: '#c4b698',
|
||||
} as const;
|
||||
|
||||
// ═══ ALL COLORS ═══
|
||||
|
||||
export const colors = {
|
||||
backgrounds,
|
||||
surfaces,
|
||||
borders,
|
||||
text,
|
||||
pigments,
|
||||
semantic,
|
||||
glass,
|
||||
shadows,
|
||||
lightTheme,
|
||||
inkTones,
|
||||
washiTones,
|
||||
} as const;
|
||||
|
||||
export type SumiColor = typeof colors;
|
||||
|
|
@ -1,21 +0,0 @@
|
|||
/**
|
||||
* SUMI Design System v2.0 — Design Tokens
|
||||
*
|
||||
* Centralized design tokens extracted from CSS custom properties.
|
||||
* Use these for TypeScript-level access to the design system values.
|
||||
*
|
||||
* For CSS usage, prefer the CSS custom properties directly:
|
||||
* var(--sumi-accent), var(--sumi-space-4), etc.
|
||||
*
|
||||
* For JS/TS usage (e.g., inline styles, canvas, SVG):
|
||||
* import { colors, typography, spacing, motion } from '@veza/design-system/tokens';
|
||||
*/
|
||||
|
||||
export { colors, backgrounds, surfaces, borders, text, pigments, semantic, glass, shadows, lightTheme } from './colors';
|
||||
export type { SumiColor } from './colors';
|
||||
|
||||
export { typography, fontFamilies, fontSizes, lineHeights, letterSpacings, fontWeights } from './typography';
|
||||
|
||||
export { spacingTokens, spacing, radius, zIndex, layout } from './spacing';
|
||||
|
||||
export { motion, durations, easings } from './motion';
|
||||
|
|
@ -1,27 +0,0 @@
|
|||
/**
|
||||
* SUMI Design System v4.0 — Motion & Animation Tokens
|
||||
*
|
||||
* Source of truth: apps/web/src/index.css
|
||||
*/
|
||||
|
||||
export const durations = {
|
||||
instant: '75ms',
|
||||
fast: '150ms',
|
||||
normal: '200ms',
|
||||
slow: '300ms',
|
||||
slower: '500ms',
|
||||
} as const;
|
||||
|
||||
export const easings = {
|
||||
default: 'cubic-bezier(0.25, 0.1, 0.25, 1)',
|
||||
out: 'cubic-bezier(0.33, 1, 0.68, 1)',
|
||||
in: 'cubic-bezier(0.32, 0, 0.67, 0)',
|
||||
inOut: 'cubic-bezier(0.65, 0, 0.35, 1)',
|
||||
bounce: 'cubic-bezier(0.34, 1.56, 0.64, 1)',
|
||||
spring: 'cubic-bezier(0.175, 0.885, 0.32, 1.1)',
|
||||
} as const;
|
||||
|
||||
export const motion = {
|
||||
durations,
|
||||
easings,
|
||||
} as const;
|
||||
|
|
@ -1,57 +0,0 @@
|
|||
/**
|
||||
* SUMI Design System v4.0 — Spacing & Layout Tokens
|
||||
*
|
||||
* Source of truth: apps/web/src/index.css
|
||||
*/
|
||||
|
||||
export const spacing = {
|
||||
'0.5': '2px',
|
||||
'1': '4px',
|
||||
'1.5': '6px',
|
||||
'2': '8px',
|
||||
'2.5': '10px',
|
||||
'3': '12px',
|
||||
'4': '16px',
|
||||
'5': '20px',
|
||||
'6': '24px',
|
||||
'8': '32px',
|
||||
'10': '40px',
|
||||
'12': '48px',
|
||||
'16': '64px',
|
||||
'20': '80px',
|
||||
} as const;
|
||||
|
||||
export const radius = {
|
||||
xs: '2px',
|
||||
sm: '4px',
|
||||
md: '6px',
|
||||
lg: '12px',
|
||||
xl: '16px',
|
||||
'2xl': '20px',
|
||||
full: '9999px',
|
||||
} as const;
|
||||
|
||||
export const zIndex = {
|
||||
base: 0,
|
||||
raised: 10,
|
||||
dropdown: 100,
|
||||
sticky: 200,
|
||||
overlay: 300,
|
||||
modal: 400,
|
||||
popover: 500,
|
||||
toast: 600,
|
||||
tooltip: 700,
|
||||
max: 999,
|
||||
} as const;
|
||||
|
||||
export const layout = {
|
||||
maxWidth: '1400px',
|
||||
maxWidthContent: '1200px',
|
||||
} as const;
|
||||
|
||||
export const spacingTokens = {
|
||||
spacing,
|
||||
radius,
|
||||
zIndex,
|
||||
layout,
|
||||
} as const;
|
||||
|
|
@ -1,59 +0,0 @@
|
|||
/**
|
||||
* SUMI Design System v4.0 — Typography Tokens
|
||||
* "Lavis d'encre" — Brush calligraphy meets clean sans
|
||||
*
|
||||
* Source of truth: apps/web/src/index.css
|
||||
*/
|
||||
|
||||
export const fontFamilies = {
|
||||
body: "'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif",
|
||||
heading: "'Noto Serif JP', Georgia, serif",
|
||||
mono: "'JetBrains Mono', 'SF Mono', 'Consolas', monospace",
|
||||
serif: "'Noto Serif JP', Georgia, serif",
|
||||
} as const;
|
||||
|
||||
export const fontSizes = {
|
||||
'4xl': '2.25rem', // 36px
|
||||
'3xl': '1.875rem', // 30px
|
||||
'2xl': '1.5rem', // 24px
|
||||
xl: '1.25rem', // 20px
|
||||
lg: '1.125rem', // 18px
|
||||
md: '1rem', // 16px
|
||||
base: '0.875rem', // 14px
|
||||
sm: '0.8125rem', // 13px
|
||||
xs: '0.75rem', // 12px
|
||||
} as const;
|
||||
|
||||
export const lineHeights = {
|
||||
none: '1',
|
||||
tight: '1.25',
|
||||
snug: '1.375',
|
||||
normal: '1.5',
|
||||
relaxed: '1.625',
|
||||
loose: '1.75',
|
||||
} as const;
|
||||
|
||||
export const letterSpacings = {
|
||||
tighter: '-0.03em',
|
||||
tight: '-0.015em',
|
||||
normal: '0',
|
||||
wide: '0.025em',
|
||||
wider: '0.05em',
|
||||
widest: '0.1em',
|
||||
} as const;
|
||||
|
||||
export const fontWeights = {
|
||||
light: 300,
|
||||
regular: 400,
|
||||
medium: 500,
|
||||
semibold: 600,
|
||||
bold: 700,
|
||||
} as const;
|
||||
|
||||
export const typography = {
|
||||
fontFamilies,
|
||||
fontSizes,
|
||||
lineHeights,
|
||||
letterSpacings,
|
||||
fontWeights,
|
||||
} as const;
|
||||
|
|
@ -1,20 +0,0 @@
|
|||
/**
|
||||
* SUMI Design System — Utility Functions
|
||||
*
|
||||
* Canonical implementation of cn() for merging Tailwind classes.
|
||||
* Also available at apps/web/src/lib/utils.ts.
|
||||
*/
|
||||
|
||||
import { type ClassValue, clsx } from 'clsx';
|
||||
import { twMerge } from 'tailwind-merge';
|
||||
|
||||
/**
|
||||
* Merge Tailwind CSS classes with deduplication.
|
||||
* Combines clsx (conditional classes) + tailwind-merge (conflict resolution).
|
||||
*
|
||||
* @example
|
||||
* cn('px-4 py-2', isActive && 'bg-primary', className)
|
||||
*/
|
||||
export function cn(...inputs: ClassValue[]): string {
|
||||
return twMerge(clsx(inputs));
|
||||
}
|
||||
121
packages/design-system/style-dictionary.config.mjs
Normal file
121
packages/design-system/style-dictionary.config.mjs
Normal file
|
|
@ -0,0 +1,121 @@
|
|||
/**
|
||||
* SUMI Design System — Style Dictionary configuration
|
||||
*
|
||||
* Source : tokens/primitive/*.json + tokens/semantic/*.json (W3C tokens spec)
|
||||
* Outputs :
|
||||
* - dist/tokens.css (concat of primitive + dark + light themes)
|
||||
* - dist/tokens-primitive.css
|
||||
* - dist/tokens-dark.css (selector :root, [data-theme="dark"])
|
||||
* - dist/tokens-light.css (selector [data-theme="light"])
|
||||
* - dist/tokens.ts (TS exports — values resolved against dark theme)
|
||||
*
|
||||
* SOURCE OF TRUTH = tokens/*.json
|
||||
* Do NOT edit dist/* manually — they are generated. Edit tokens/* and run `npm run build:tokens`.
|
||||
*
|
||||
* Charte : ../../../Documents/TG__Talas_Group/05_EXPERIENCE_UTILISATEUR/CHARTE_GRAPHIQUE_TALAS.md
|
||||
*/
|
||||
|
||||
import StyleDictionary from 'style-dictionary';
|
||||
import { readFileSync, writeFileSync } from 'node:fs';
|
||||
|
||||
const PRIMITIVE_GLOB = 'tokens/primitive/**/*.json';
|
||||
const SEMANTIC_DARK = 'tokens/semantic/dark.json';
|
||||
const SEMANTIC_LIGHT = 'tokens/semantic/light.json';
|
||||
|
||||
/** Filter that keeps only tokens whose path starts with one of `prefixes`. */
|
||||
const filterByPathPrefix = (prefixes) => (token) => prefixes.includes(token.path[0]);
|
||||
|
||||
/** Build primitive tokens — :root only (raw values shared by all themes). */
|
||||
const buildPrimitive = async () => {
|
||||
const sd = new StyleDictionary({
|
||||
source: [PRIMITIVE_GLOB],
|
||||
platforms: {
|
||||
css: {
|
||||
transformGroup: 'css',
|
||||
buildPath: 'dist/',
|
||||
files: [
|
||||
{
|
||||
destination: 'tokens-primitive.css',
|
||||
format: 'css/variables',
|
||||
options: { selector: ':root', outputReferences: false },
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
});
|
||||
await sd.buildAllPlatforms();
|
||||
};
|
||||
|
||||
/** Build a theme — semantic tokens with theme selector. */
|
||||
const buildTheme = async (themeName, semanticFile, selector) => {
|
||||
const sd = new StyleDictionary({
|
||||
source: [PRIMITIVE_GLOB, semanticFile],
|
||||
platforms: {
|
||||
css: {
|
||||
transformGroup: 'css',
|
||||
buildPath: 'dist/',
|
||||
files: [
|
||||
{
|
||||
destination: `tokens-${themeName}.css`,
|
||||
format: 'css/variables',
|
||||
filter: filterByPathPrefix(['sumi']),
|
||||
options: { selector, outputReferences: true },
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
});
|
||||
await sd.buildAllPlatforms();
|
||||
};
|
||||
|
||||
/** Build TS exports — values resolved against dark theme (default). */
|
||||
const buildTypeScript = async () => {
|
||||
const sd = new StyleDictionary({
|
||||
source: [PRIMITIVE_GLOB, SEMANTIC_DARK],
|
||||
platforms: {
|
||||
ts: {
|
||||
transformGroup: 'js',
|
||||
buildPath: 'dist/',
|
||||
files: [
|
||||
{
|
||||
destination: 'tokens.ts',
|
||||
format: 'javascript/es6',
|
||||
},
|
||||
{
|
||||
destination: 'tokens.d.ts',
|
||||
format: 'typescript/es6-declarations',
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
});
|
||||
await sd.buildAllPlatforms();
|
||||
};
|
||||
|
||||
await buildPrimitive();
|
||||
await buildTheme('dark', SEMANTIC_DARK, ':root, [data-theme="dark"]');
|
||||
await buildTheme('light', SEMANTIC_LIGHT, '[data-theme="light"]');
|
||||
await buildTypeScript();
|
||||
|
||||
// Concatenate the three CSS files into a single tokens.css
|
||||
const header = `/**
|
||||
* SUMI tokens — generated by style-dictionary.config.mjs
|
||||
* Source: packages/design-system/tokens/
|
||||
* Do NOT edit this file. Edit tokens/*.json and run \`npm run build:tokens\`.
|
||||
*/
|
||||
|
||||
`;
|
||||
const primitive = readFileSync('dist/tokens-primitive.css', 'utf8');
|
||||
const dark = readFileSync('dist/tokens-dark.css', 'utf8');
|
||||
const light = readFileSync('dist/tokens-light.css', 'utf8');
|
||||
const stripGenerated = (s) => s.replace(/^\/\*\*\n \* Do not edit directly[\s\S]*?\*\/\n\n?/m, '');
|
||||
writeFileSync(
|
||||
'dist/tokens.css',
|
||||
header + stripGenerated(primitive) + '\n' + stripGenerated(dark) + '\n' + stripGenerated(light),
|
||||
);
|
||||
|
||||
console.log('\n✓ Style Dictionary build complete.');
|
||||
console.log(' Output: packages/design-system/dist/');
|
||||
console.log(' - tokens.css (unified)');
|
||||
console.log(' - tokens-primitive.css, tokens-dark.css, tokens-light.css');
|
||||
console.log(' - tokens.ts, tokens.d.ts');
|
||||
74
packages/design-system/tokens/primitive/color.json
Normal file
74
packages/design-system/tokens/primitive/color.json
Normal file
|
|
@ -0,0 +1,74 @@
|
|||
{
|
||||
"color": {
|
||||
"ink": {
|
||||
"kuro": { "$value": "#0A0A0C", "$type": "color", "$description": "黒 — pure black, deepest void" },
|
||||
"sumi": { "$value": "#1A1A1E", "$type": "color", "$description": "墨 — ink, dense black" },
|
||||
"usuzumi": { "$value": "#3D3A35", "$type": "color", "$description": "薄墨 — light ink" },
|
||||
"hai": { "$value": "#6B6660", "$type": "color", "$description": "灰 — ash" },
|
||||
"gin": { "$value": "#9A958D", "$type": "color", "$description": "銀 — silver" },
|
||||
"kasumi": { "$value": "#B5B0A8", "$type": "color", "$description": "霞 — mist" }
|
||||
},
|
||||
"washi": {
|
||||
"shiro": { "$value": "#F2EDE6", "$type": "color", "$description": "白 — washi paper, warm white (charte canonique)" },
|
||||
"kinari": { "$value": "#E8E3DB", "$type": "color", "$description": "生成 — undyed cream" },
|
||||
"kinu": { "$value": "#DDD4C0", "$type": "color", "$description": "絹 — silk" },
|
||||
"torinoko": { "$value": "#D0C5AD", "$type": "color", "$description": "鳥の子 — torinoko paper" },
|
||||
"cha": { "$value": "#C4B698", "$type": "color", "$description": "茶 — tea" }
|
||||
},
|
||||
"void": {
|
||||
"base": { "$value": "#0D0D0F", "$type": "color", "$description": "Dark theme paper — deep ink" },
|
||||
"raised": { "$value": "#141416", "$type": "color" },
|
||||
"overlay":{ "$value": "#1A1A1E", "$type": "color" },
|
||||
"hover": { "$value": "#222226", "$type": "color" },
|
||||
"active": { "$value": "#2A2A2F", "$type": "color" },
|
||||
"wash": { "$value": "#111113", "$type": "color" },
|
||||
"inset": { "$value": "#0B0B0D", "$type": "color" },
|
||||
"subtle": { "$value": "#161618", "$type": "color" }
|
||||
},
|
||||
"mizu": {
|
||||
"base": { "$value": "#0098B5", "$type": "color", "$description": "水 — mizu cyan, the SOLE accent (charte §4.1)" },
|
||||
"hover": { "$value": "#00B4D8", "$type": "color" },
|
||||
"active": { "$value": "#007A94", "$type": "color" },
|
||||
"deep": { "$value": "#006B7F", "$type": "color", "$description": "Cyan profond — for normal text WCAG AA" },
|
||||
"muted": { "$value": "rgba(0,152,181, 0.18)", "$type": "color" },
|
||||
"subtle": { "$value": "rgba(0,152,181, 0.06)", "$type": "color" },
|
||||
"focus": { "$value": "rgba(0,152,181, 0.50)", "$type": "color" },
|
||||
"border": { "$value": "rgba(0,152,181, 0.25)", "$type": "color" }
|
||||
},
|
||||
"kin": {
|
||||
"base": { "$value": "#b8860b", "$type": "color", "$description": "金 — gold leaf, decorative only" },
|
||||
"hover": { "$value": "#c8960b", "$type": "color" },
|
||||
"subtle": { "$value": "rgba(184,134,11, 0.08)", "$type": "color" }
|
||||
},
|
||||
"viz": {
|
||||
"_comment": "Data viz palette ONLY (charts, waveforms, analytics). Forbidden in standard UI per CHARTE_GRAPHIQUE_TALAS §4.5",
|
||||
"indigo": { "$value": "#7c9dd6", "$type": "color", "$description": "Data viz pigment — indigo" },
|
||||
"vermillion": { "$value": "#d4634a", "$type": "color", "$description": "Data viz pigment — vermillion" },
|
||||
"sage": { "$value": "#7a9e6c", "$type": "color", "$description": "Data viz pigment — sage" },
|
||||
"gold": { "$value": "#c9a84c", "$type": "color", "$description": "Data viz pigment — gold" },
|
||||
"neutral": { "$value": "#a8a4a0", "$type": "color", "$description": "Data viz pigment — neutral grey" }
|
||||
},
|
||||
"functional": {
|
||||
"_comment": "Functional colors are ALWAYS diluted (max 60% opacity). Never as solid fill (charte §4.2)",
|
||||
"sage-diluted": { "$value": "rgba(90,140,100, 0.60)", "$type": "color", "$description": "Success — vert sauge dilué" },
|
||||
"sage-hover": { "$value": "rgba(90,140,100, 0.70)", "$type": "color" },
|
||||
"sage-subtle": { "$value": "rgba(90,140,100, 0.10)", "$type": "color" },
|
||||
"brick-diluted": { "$value": "rgba(180,80,70, 0.55)", "$type": "color", "$description": "Error — rouge brique dilué" },
|
||||
"brick-hover": { "$value": "rgba(180,80,70, 0.65)", "$type": "color" },
|
||||
"brick-subtle": { "$value": "rgba(180,80,70, 0.10)", "$type": "color" },
|
||||
"amber-diluted": { "$value": "rgba(190,150,60, 0.55)", "$type": "color", "$description": "Warning — ambre dilué" },
|
||||
"amber-hover": { "$value": "rgba(190,150,60, 0.65)", "$type": "color" },
|
||||
"amber-subtle": { "$value": "rgba(190,150,60, 0.10)", "$type": "color" }
|
||||
},
|
||||
"alpha": {
|
||||
"ink-04": { "$value": "rgba(26,26,30, 0.04)", "$type": "color", "$description": "Ink wash — surface card" },
|
||||
"ink-06": { "$value": "rgba(26,26,30, 0.06)", "$type": "color" },
|
||||
"ink-08": { "$value": "rgba(26,26,30, 0.08)", "$type": "color" },
|
||||
"ink-12": { "$value": "rgba(26,26,30, 0.12)", "$type": "color" },
|
||||
"ink-20": { "$value": "rgba(26,26,30, 0.20)", "$type": "color" },
|
||||
"ivory-03":{ "$value": "rgba(232,227,219, 0.03)", "$type": "color", "$description": "Ivory border — faint" },
|
||||
"ivory-06":{ "$value": "rgba(232,227,219, 0.06)", "$type": "color" },
|
||||
"ivory-10":{ "$value": "rgba(232,227,219, 0.10)", "$type": "color" }
|
||||
}
|
||||
}
|
||||
}
|
||||
29
packages/design-system/tokens/primitive/elevation.json
Normal file
29
packages/design-system/tokens/primitive/elevation.json
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
{
|
||||
"shadow": {
|
||||
"_comment": "Diffusions d'encre (滲み) — JAMAIS de border 1px solid (charte §7.3)",
|
||||
"xs": { "$value": "0 1px 3px rgba(13,13,11,0.20)", "$type": "shadow" },
|
||||
"sm": { "$value": "0 2px 8px rgba(13,13,11,0.15), 0 1px 3px rgba(13,13,11,0.12)", "$type": "shadow" },
|
||||
"md": { "$value": "0 4px 20px rgba(13,13,11,0.15), 0 2px 6px rgba(13,13,11,0.10)", "$type": "shadow" },
|
||||
"lg": { "$value": "0 8px 35px rgba(13,13,11,0.18), 0 4px 12px rgba(13,13,11,0.10)", "$type": "shadow" },
|
||||
"xl": { "$value": "0 16px 55px rgba(13,13,11,0.22), 0 8px 20px rgba(13,13,11,0.12)", "$type": "shadow" },
|
||||
"2xl": { "$value": "0 24px 75px rgba(13,13,11,0.30)", "$type": "shadow" },
|
||||
"ink": { "$value": "0 0 6px rgba(26,26,30, 0.06)", "$type": "shadow", "$description": "Diffusion d'encre — remplace border" },
|
||||
"glow": { "$value": "0 0 0 3px rgba(0,152,181, 0.20)", "$type": "shadow", "$description": "Focus ring cyan" },
|
||||
"kin": { "$value": "0 0 16px rgba(184,134,11, 0.15)", "$type": "shadow" }
|
||||
},
|
||||
"blur": {
|
||||
"_comment": "Couches d'encre (charte §7.2) — backdrop-filter croissant par élévation",
|
||||
"surface": { "$value": "8px", "$type": "dimension", "$description": "Surface cards" },
|
||||
"overlay": { "$value": "16px", "$type": "dimension", "$description": "Dropdowns, menus" },
|
||||
"modal": { "$value": "24px", "$type": "dimension", "$description": "Modales" },
|
||||
"suzuri": { "$value": "32px", "$type": "dimension", "$description": "Player audio (硯 — pierre à encre)" }
|
||||
},
|
||||
"opacity": {
|
||||
"_comment": "Opacités d'encre par élévation",
|
||||
"surface": { "$value": "0.06", "$type": "number" },
|
||||
"overlay": { "$value": "0.10", "$type": "number" },
|
||||
"modal": { "$value": "0.16", "$type": "number" },
|
||||
"suzuri": { "$value": "0.25", "$type": "number" },
|
||||
"grain": { "$value": "0.04", "$type": "number", "$description": "Grain washi standard" }
|
||||
}
|
||||
}
|
||||
20
packages/design-system/tokens/primitive/motion.json
Normal file
20
packages/design-system/tokens/primitive/motion.json
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
{
|
||||
"motion": {
|
||||
"_comment": "Le poids de l'eau (charte §3) — 5 niveaux de masse, max 2 animations simultanées",
|
||||
"duration": {
|
||||
"goutte": { "$value": "100ms", "$type": "duration", "$description": "滴 — drop : tooltips, badges" },
|
||||
"trait": { "$value": "150ms", "$type": "duration", "$description": "筆 — stroke : boutons, icônes" },
|
||||
"lavis": { "$value": "250ms", "$type": "duration", "$description": "墨 — wash : cards, dropdowns" },
|
||||
"vague": { "$value": "350ms", "$type": "duration", "$description": "波 — wave : modales, sidebars" },
|
||||
"maree": { "$value": "450ms", "$type": "duration", "$description": "潮 — tide : navigation, player" }
|
||||
},
|
||||
"ease": {
|
||||
"goutte": { "$value": "cubic-bezier(0.25, 0.1, 0.25, 1)", "$type": "cubicBezier" },
|
||||
"trait": { "$value": "cubic-bezier(0.33, 1, 0.68, 1)", "$type": "cubicBezier", "$description": "Rebond léger" },
|
||||
"lavis": { "$value": "cubic-bezier(0.25, 0.8, 0.25, 1)", "$type": "cubicBezier" },
|
||||
"vague": { "$value": "cubic-bezier(0.16, 1, 0.3, 1)", "$type": "cubicBezier" },
|
||||
"maree": { "$value": "cubic-bezier(0.33, 1, 0.68, 1)", "$type": "cubicBezier" },
|
||||
"rebond": { "$value": "cubic-bezier(0.34, 1.56, 0.64, 1)", "$type": "cubicBezier", "$description": "Rebond marqué — accents" }
|
||||
}
|
||||
}
|
||||
}
|
||||
37
packages/design-system/tokens/primitive/spacing.json
Normal file
37
packages/design-system/tokens/primitive/spacing.json
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
{
|
||||
"space": {
|
||||
"_comment": "Échelle 4px stricte (charte §6 + ORIGIN règle 5). Aucune valeur arbitraire.",
|
||||
"0": { "$value": "0", "$type": "dimension" },
|
||||
"1": { "$value": "0.25rem", "$type": "dimension", "$description": "4px" },
|
||||
"2": { "$value": "0.5rem", "$type": "dimension", "$description": "8px" },
|
||||
"3": { "$value": "0.75rem", "$type": "dimension", "$description": "12px" },
|
||||
"4": { "$value": "1rem", "$type": "dimension", "$description": "16px" },
|
||||
"5": { "$value": "1.25rem", "$type": "dimension", "$description": "20px" },
|
||||
"6": { "$value": "1.5rem", "$type": "dimension", "$description": "24px" },
|
||||
"8": { "$value": "2rem", "$type": "dimension", "$description": "32px" },
|
||||
"10": { "$value": "2.5rem", "$type": "dimension", "$description": "40px" },
|
||||
"12": { "$value": "3rem", "$type": "dimension", "$description": "48px" },
|
||||
"16": { "$value": "4rem", "$type": "dimension", "$description": "64px" },
|
||||
"20": { "$value": "5rem", "$type": "dimension", "$description": "80px" },
|
||||
"24": { "$value": "6rem", "$type": "dimension", "$description": "96px" }
|
||||
},
|
||||
"radius": {
|
||||
"none": { "$value": "0", "$type": "dimension" },
|
||||
"sm": { "$value": "0.25rem", "$type": "dimension" },
|
||||
"md": { "$value": "0.5rem", "$type": "dimension" },
|
||||
"lg": { "$value": "0.75rem", "$type": "dimension" },
|
||||
"xl": { "$value": "1rem", "$type": "dimension" },
|
||||
"full": { "$value": "9999px", "$type": "dimension" }
|
||||
},
|
||||
"z": {
|
||||
"base": { "$value": "0", "$type": "number" },
|
||||
"raised": { "$value": "10", "$type": "number" },
|
||||
"sticky": { "$value": "100", "$type": "number" },
|
||||
"header": { "$value": "200", "$type": "number" },
|
||||
"drawer": { "$value": "300", "$type": "number" },
|
||||
"modal": { "$value": "400", "$type": "number" },
|
||||
"popover": { "$value": "500", "$type": "number" },
|
||||
"toast": { "$value": "600", "$type": "number" },
|
||||
"tooltip": { "$value": "700", "$type": "number" }
|
||||
}
|
||||
}
|
||||
42
packages/design-system/tokens/primitive/typography.json
Normal file
42
packages/design-system/tokens/primitive/typography.json
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
{
|
||||
"font": {
|
||||
"family": {
|
||||
"heading": { "$value": "'Space Grotesk', system-ui, sans-serif", "$type": "fontFamily", "$description": "Titres — MAJUSCULES, letter-spacing 0.10-0.15em" },
|
||||
"body": { "$value": "'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif", "$type": "fontFamily" },
|
||||
"mono": { "$value": "'JetBrains Mono', 'SF Mono', 'Consolas', monospace", "$type": "fontFamily", "$description": "Code et specs techniques uniquement" }
|
||||
},
|
||||
"weight": {
|
||||
"regular": { "$value": 400, "$type": "fontWeight" },
|
||||
"medium": { "$value": 500, "$type": "fontWeight" },
|
||||
"semibold": { "$value": 600, "$type": "fontWeight" },
|
||||
"bold": { "$value": 700, "$type": "fontWeight" }
|
||||
},
|
||||
"size": {
|
||||
"xs": { "$value": "0.75rem", "$type": "dimension" },
|
||||
"sm": { "$value": "0.8125rem", "$type": "dimension" },
|
||||
"base": { "$value": "0.875rem", "$type": "dimension" },
|
||||
"md": { "$value": "1rem", "$type": "dimension" },
|
||||
"lg": { "$value": "1.125rem", "$type": "dimension" },
|
||||
"xl": { "$value": "1.25rem", "$type": "dimension" },
|
||||
"2xl": { "$value": "1.5rem", "$type": "dimension" },
|
||||
"3xl": { "$value": "1.875rem", "$type": "dimension" },
|
||||
"4xl": { "$value": "2.25rem", "$type": "dimension" }
|
||||
},
|
||||
"leading": {
|
||||
"none": { "$value": "1", "$type": "number" },
|
||||
"tight": { "$value": "1.25", "$type": "number" },
|
||||
"snug": { "$value": "1.375", "$type": "number" },
|
||||
"normal": { "$value": "1.5", "$type": "number" },
|
||||
"relaxed": { "$value": "1.625", "$type": "number" },
|
||||
"loose": { "$value": "1.7", "$type": "number", "$description": "Corps de texte — interligne charte" }
|
||||
},
|
||||
"tracking": {
|
||||
"tight": { "$value": "-0.02em", "$type": "dimension" },
|
||||
"normal": { "$value": "0", "$type": "dimension" },
|
||||
"wide": { "$value": "0.08em", "$type": "dimension" },
|
||||
"wider": { "$value": "0.10em", "$type": "dimension", "$description": "H3 charte" },
|
||||
"widest": { "$value": "0.12em", "$type": "dimension", "$description": "H2 charte" },
|
||||
"huge": { "$value": "0.15em", "$type": "dimension", "$description": "H1 charte" }
|
||||
}
|
||||
}
|
||||
}
|
||||
69
packages/design-system/tokens/semantic/dark.json
Normal file
69
packages/design-system/tokens/semantic/dark.json
Normal file
|
|
@ -0,0 +1,69 @@
|
|||
{
|
||||
"sumi": {
|
||||
"_comment": "Semantic tokens — dark theme (default :root). Tous les refs pointent vers tokens/primitive/.",
|
||||
"bg": {
|
||||
"void": { "$value": "{color.void.base}", "$type": "color" },
|
||||
"base": { "$value": "{color.void.base}", "$type": "color" },
|
||||
"raised": { "$value": "{color.void.raised}", "$type": "color" },
|
||||
"overlay": { "$value": "{color.void.overlay}", "$type": "color" },
|
||||
"hover": { "$value": "{color.void.hover}", "$type": "color" },
|
||||
"active": { "$value": "{color.void.active}", "$type": "color" },
|
||||
"wash": { "$value": "{color.void.wash}", "$type": "color" }
|
||||
},
|
||||
"surface": {
|
||||
"inset": { "$value": "{color.void.inset}", "$type": "color" },
|
||||
"subtle": { "$value": "{color.void.subtle}", "$type": "color" },
|
||||
"card": { "$value": "{color.void.raised}", "$type": "color" },
|
||||
"elevated": { "$value": "{color.void.overlay}", "$type": "color" }
|
||||
},
|
||||
"border": {
|
||||
"faint": { "$value": "{color.alpha.ivory-03}", "$type": "color" },
|
||||
"default": { "$value": "{color.alpha.ivory-06}", "$type": "color" },
|
||||
"strong": { "$value": "{color.alpha.ivory-10}", "$type": "color" },
|
||||
"focus": { "$value": "{color.mizu.focus}", "$type": "color" },
|
||||
"accent": { "$value": "{color.mizu.border}", "$type": "color" }
|
||||
},
|
||||
"text": {
|
||||
"primary": { "$value": "{color.washi.kinari}", "$type": "color" },
|
||||
"secondary": { "$value": "{color.ink.gin}", "$type": "color" },
|
||||
"tertiary": { "$value": "{color.ink.hai}", "$type": "color" },
|
||||
"disabled": { "$value": "{color.ink.usuzumi}", "$type": "color" },
|
||||
"inverse": { "$value": "{color.washi.shiro}", "$type": "color" },
|
||||
"link": { "$value": "{color.mizu.base}", "$type": "color" }
|
||||
},
|
||||
"accent": {
|
||||
"default": { "$value": "{color.mizu.base}", "$type": "color" },
|
||||
"hover": { "$value": "{color.mizu.hover}", "$type": "color" },
|
||||
"active": { "$value": "{color.mizu.active}", "$type": "color" },
|
||||
"muted": { "$value": "{color.mizu.muted}", "$type": "color" },
|
||||
"subtle": { "$value": "{color.mizu.subtle}", "$type": "color" },
|
||||
"emphasis": { "$value": "{color.mizu.deep}", "$type": "color", "$description": "Pour texte normal AA" }
|
||||
},
|
||||
"viz": {
|
||||
"_comment": "Data viz uniquement (charts, waveforms, analytics)",
|
||||
"indigo": { "$value": "{color.viz.indigo}", "$type": "color" },
|
||||
"vermillion": { "$value": "{color.viz.vermillion}", "$type": "color" },
|
||||
"sage": { "$value": "{color.viz.sage}", "$type": "color" },
|
||||
"gold": { "$value": "{color.viz.gold}", "$type": "color" },
|
||||
"neutral": { "$value": "{color.viz.neutral}", "$type": "color" }
|
||||
},
|
||||
"feedback": {
|
||||
"success": { "$value": "{color.functional.sage-diluted}", "$type": "color" },
|
||||
"success-hover": { "$value": "{color.functional.sage-hover}", "$type": "color" },
|
||||
"success-subtle": { "$value": "{color.functional.sage-subtle}", "$type": "color" },
|
||||
"error": { "$value": "{color.functional.brick-diluted}", "$type": "color" },
|
||||
"error-hover": { "$value": "{color.functional.brick-hover}", "$type": "color" },
|
||||
"error-subtle": { "$value": "{color.functional.brick-subtle}", "$type": "color" },
|
||||
"warning": { "$value": "{color.functional.amber-diluted}", "$type": "color" },
|
||||
"warning-hover": { "$value": "{color.functional.amber-hover}", "$type": "color" },
|
||||
"warning-subtle": { "$value": "{color.functional.amber-subtle}", "$type": "color" },
|
||||
"info": { "$value": "{color.mizu.base}", "$type": "color" }
|
||||
},
|
||||
"kin": {
|
||||
"base": { "$value": "{color.kin.base}", "$type": "color" },
|
||||
"hover": { "$value": "{color.kin.hover}", "$type": "color" },
|
||||
"subtle": { "$value": "{color.kin.subtle}", "$type": "color" },
|
||||
"glow": { "$value": "{shadow.kin}", "$type": "shadow" }
|
||||
}
|
||||
}
|
||||
}
|
||||
68
packages/design-system/tokens/semantic/light.json
Normal file
68
packages/design-system/tokens/semantic/light.json
Normal file
|
|
@ -0,0 +1,68 @@
|
|||
{
|
||||
"sumi": {
|
||||
"_comment": "Semantic tokens — light theme ([data-theme=\"light\"]). Washi paper aesthetic.",
|
||||
"bg": {
|
||||
"void": { "$value": "{color.washi.shiro}", "$type": "color" },
|
||||
"base": { "$value": "{color.washi.shiro}", "$type": "color" },
|
||||
"raised": { "$value": "{color.washi.shiro}", "$type": "color" },
|
||||
"overlay": { "$value": "{color.washi.kinari}", "$type": "color" },
|
||||
"hover": { "$value": "{color.washi.kinari}", "$type": "color" },
|
||||
"active": { "$value": "{color.washi.kinu}", "$type": "color" },
|
||||
"wash": { "$value": "{color.washi.kinari}", "$type": "color" }
|
||||
},
|
||||
"surface": {
|
||||
"inset": { "$value": "{color.washi.kinari}", "$type": "color" },
|
||||
"subtle": { "$value": "{color.washi.shiro}", "$type": "color" },
|
||||
"card": { "$value": "{color.washi.shiro}", "$type": "color" },
|
||||
"elevated": { "$value": "{color.washi.shiro}", "$type": "color" }
|
||||
},
|
||||
"border": {
|
||||
"faint": { "$value": "{color.alpha.ink-04}", "$type": "color" },
|
||||
"default": { "$value": "{color.alpha.ink-06}", "$type": "color" },
|
||||
"strong": { "$value": "{color.alpha.ink-12}", "$type": "color" },
|
||||
"focus": { "$value": "{color.mizu.focus}", "$type": "color" },
|
||||
"accent": { "$value": "{color.mizu.border}", "$type": "color" }
|
||||
},
|
||||
"text": {
|
||||
"primary": { "$value": "{color.ink.sumi}", "$type": "color" },
|
||||
"secondary": { "$value": "{color.ink.gin}", "$type": "color" },
|
||||
"tertiary": { "$value": "{color.ink.hai}", "$type": "color" },
|
||||
"disabled": { "$value": "{color.ink.kasumi}", "$type": "color" },
|
||||
"inverse": { "$value": "{color.washi.kinari}", "$type": "color" },
|
||||
"link": { "$value": "{color.mizu.deep}", "$type": "color", "$description": "Cyan profond pour AA en mode jour" }
|
||||
},
|
||||
"accent": {
|
||||
"default": { "$value": "{color.mizu.base}", "$type": "color" },
|
||||
"hover": { "$value": "{color.mizu.active}", "$type": "color" },
|
||||
"active": { "$value": "{color.mizu.deep}", "$type": "color" },
|
||||
"muted": { "$value": "{color.mizu.muted}", "$type": "color" },
|
||||
"subtle": { "$value": "{color.mizu.subtle}", "$type": "color" },
|
||||
"emphasis": { "$value": "{color.mizu.deep}", "$type": "color" }
|
||||
},
|
||||
"viz": {
|
||||
"indigo": { "$value": "{color.viz.indigo}", "$type": "color" },
|
||||
"vermillion": { "$value": "{color.viz.vermillion}", "$type": "color" },
|
||||
"sage": { "$value": "{color.viz.sage}", "$type": "color" },
|
||||
"gold": { "$value": "{color.viz.gold}", "$type": "color" },
|
||||
"neutral": { "$value": "{color.viz.neutral}", "$type": "color" }
|
||||
},
|
||||
"feedback": {
|
||||
"success": { "$value": "{color.functional.sage-diluted}", "$type": "color" },
|
||||
"success-hover": { "$value": "{color.functional.sage-hover}", "$type": "color" },
|
||||
"success-subtle": { "$value": "{color.functional.sage-subtle}", "$type": "color" },
|
||||
"error": { "$value": "{color.functional.brick-diluted}", "$type": "color" },
|
||||
"error-hover": { "$value": "{color.functional.brick-hover}", "$type": "color" },
|
||||
"error-subtle": { "$value": "{color.functional.brick-subtle}", "$type": "color" },
|
||||
"warning": { "$value": "{color.functional.amber-diluted}", "$type": "color" },
|
||||
"warning-hover": { "$value": "{color.functional.amber-hover}", "$type": "color" },
|
||||
"warning-subtle": { "$value": "{color.functional.amber-subtle}", "$type": "color" },
|
||||
"info": { "$value": "{color.mizu.base}", "$type": "color" }
|
||||
},
|
||||
"kin": {
|
||||
"base": { "$value": "{color.kin.base}", "$type": "color" },
|
||||
"hover": { "$value": "{color.kin.hover}", "$type": "color" },
|
||||
"subtle": { "$value": "{color.kin.subtle}", "$type": "color" },
|
||||
"glow": { "$value": "{shadow.kin}", "$type": "shadow" }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -3,7 +3,13 @@
|
|||
"tasks": {
|
||||
"build": {
|
||||
"dependsOn": ["^build"],
|
||||
"outputs": ["dist/**", ".next/**", "!.next/cache/**"]
|
||||
"outputs": ["dist/**", ".next/**", "!.next/cache/**"],
|
||||
"inputs": [
|
||||
"src/**",
|
||||
"tokens/**",
|
||||
"*.config.*",
|
||||
"package.json"
|
||||
]
|
||||
},
|
||||
"test": {
|
||||
"dependsOn": [],
|
||||
|
|
|
|||
Loading…
Reference in a new issue