feat: design system v1.0.0 — reconcile tokens from cross-repo audit
Extracted real production usage from 8 KDC repos and consolidated the consensus (kdcsurveyadd / kdcvault / kdc_void_planner) into the canonical design.md + tokens. Highlights: - brand.ink #000000 -> #1A1530 (purple-tinted, matches real usage) - brand.canvas #F5F4F0 -> #F7F4ED (warm) - neutral ramp rebuilt around ink (purple-tinted, not cold slate) - semantic palette retuned for warm canvas + soft tints - elevation shadows retinted with brand-ink rgb - new accent.gold (product) and accent.mint (marketing) tokens - real themes/light, themes/dark, themes/high-contrast - fleshed out every component + foundation README - docs/consolidation-2026-05.md captures the full audit + drift inventory Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,34 +1,60 @@
|
||||
---
|
||||
version: beta
|
||||
version: 1.0.0
|
||||
name: Kode Design Consultants Ltd Design System
|
||||
description: The official design system for Kode Design Consultants — tokens, components, and guidelines for building consistent KDC product and brand experiences.
|
||||
description: The official design system for Kode Design Consultants — tokens, components, and guidelines for building consistent KDC product and brand experiences. Reconciled 2026-05-17 from production usage across kdcsurveyadd, kdcvault, kdc_void_planner and k-d-c-workspace.
|
||||
colors:
|
||||
brand.primary: "#6B35A7"
|
||||
brand.primaryHover: "#582A8D"
|
||||
brand.primary: "#6B35A7"
|
||||
brand.primaryHover: "#5C2D90"
|
||||
brand.primaryPressed: "#45216E"
|
||||
brand.ink: "#000000"
|
||||
brand.canvas: "#F5F4F0"
|
||||
neutral.0: "#FFFFFF"
|
||||
neutral.50: "#F5F4F0"
|
||||
neutral.100: "#EDEFF3"
|
||||
neutral.200: "#D9DCE3"
|
||||
neutral.300: "#B8BDC9"
|
||||
neutral.500: "#6B7280"
|
||||
neutral.700: "#374151"
|
||||
neutral.900: "#111827"
|
||||
brand.primaryLight: "#8456C2"
|
||||
brand.primarySoft: "#F1E9F8"
|
||||
brand.ink: "#1A1530"
|
||||
brand.canvas: "#F7F4ED"
|
||||
brand.canvasCool: "#F7F6FB"
|
||||
accent.gold: "#C9892B"
|
||||
accent.goldStrong: "#A86F1F"
|
||||
accent.goldSoft: "#F5E9D2"
|
||||
accent.mint: "#46C194"
|
||||
neutral.0: "#FFFFFF"
|
||||
neutral.50: "#FBF8F1"
|
||||
neutral.100: "#F7F4ED"
|
||||
neutral.150: "#ECE9F3"
|
||||
neutral.200: "#E6E0D2"
|
||||
neutral.300: "#D4CCB8"
|
||||
neutral.400: "#A39DB0"
|
||||
neutral.500: "#8C869C"
|
||||
neutral.600: "#6B647A"
|
||||
neutral.700: "#4A4360"
|
||||
neutral.800: "#3A2D5A"
|
||||
neutral.900: "#1A1530"
|
||||
neutral.1000: "#000000"
|
||||
semantic.success: "#16A34A"
|
||||
semantic.warning: "#F59E0B"
|
||||
semantic.danger: "#DC2626"
|
||||
semantic.info: "#0EA5E9"
|
||||
semantic.success: "#2F7A5A"
|
||||
semantic.successSoft: "#E2F0E8"
|
||||
semantic.warning: "#C9892B"
|
||||
semantic.warningSoft: "#F5E9D2"
|
||||
semantic.danger: "#B0382F"
|
||||
semantic.dangerSoft: "#F7E4E1"
|
||||
semantic.info: "#5C2D90"
|
||||
surface.background: "{colors.neutral.0}"
|
||||
surface.subtle: "{colors.neutral.50}"
|
||||
surface.muted: "{colors.neutral.100}"
|
||||
text.default: "{colors.neutral.900}"
|
||||
text.muted: "{colors.neutral.500}"
|
||||
text.inverse: "{colors.neutral.0}"
|
||||
border.default: "{colors.neutral.200}"
|
||||
border.strong: "{colors.neutral.300}"
|
||||
surface.canvas: "{colors.brand.canvas}"
|
||||
surface.subtle: "{colors.neutral.50}"
|
||||
surface.muted: "{colors.brand.primarySoft}"
|
||||
text.default: "{colors.brand.ink}"
|
||||
text.soft: "{colors.neutral.700}"
|
||||
text.muted: "{colors.neutral.600}"
|
||||
text.disabled: "{colors.neutral.400}"
|
||||
text.inverse: "{colors.neutral.0}"
|
||||
text.brand: "{colors.brand.primary}"
|
||||
border.default: "{colors.neutral.200}"
|
||||
border.strong: "{colors.neutral.300}"
|
||||
border.subtle: "{colors.neutral.150}"
|
||||
elevation:
|
||||
"0": "none"
|
||||
"1": "0 1px 2px rgba(26,21,48,0.04)"
|
||||
"2": "0 4px 12px -4px rgba(26,21,48,0.08)"
|
||||
"3": "0 16px 40px -16px rgba(26,21,48,0.18)"
|
||||
"4": "0 24px 80px -24px rgba(26,21,48,0.22)"
|
||||
focusRing: "0 0 0 3px rgba(107,53,167,0.18)"
|
||||
typography:
|
||||
display:
|
||||
fontFamily: "Opificio"
|
||||
@@ -117,53 +143,90 @@ components:
|
||||
textColor: "{colors.text.inverse}"
|
||||
typography: "{typography.bodyM}"
|
||||
rounded: "{rounded.md}"
|
||||
padding: "12px 20px"
|
||||
padding: "10px 16px"
|
||||
height: "40px"
|
||||
shadow: "{elevation.1}"
|
||||
button.primaryHover:
|
||||
backgroundColor: "{colors.brand.primaryHover}"
|
||||
textColor: "{colors.text.inverse}"
|
||||
button.primaryPressed:
|
||||
backgroundColor: "{colors.brand.primaryPressed}"
|
||||
textColor: "{colors.text.inverse}"
|
||||
button.accent:
|
||||
backgroundColor: "{colors.accent.gold}"
|
||||
textColor: "{colors.text.inverse}"
|
||||
typography: "{typography.bodyM}"
|
||||
rounded: "{rounded.md}"
|
||||
padding: "10px 16px"
|
||||
height: "40px"
|
||||
description: "Submit / emphasis button. Used sparingly — one per surface."
|
||||
button.secondary:
|
||||
backgroundColor: "{colors.surface.subtle}"
|
||||
textColor: "{colors.text.default}"
|
||||
borderColor: "{colors.border.default}"
|
||||
typography: "{typography.bodyM}"
|
||||
rounded: "{rounded.md}"
|
||||
padding: "12px 20px"
|
||||
padding: "10px 16px"
|
||||
height: "40px"
|
||||
button.ghost:
|
||||
backgroundColor: "transparent"
|
||||
textColor: "{colors.brand.primary}"
|
||||
typography: "{typography.bodyM}"
|
||||
rounded: "{rounded.md}"
|
||||
padding: "12px 20px"
|
||||
padding: "10px 16px"
|
||||
height: "40px"
|
||||
button.outline:
|
||||
backgroundColor: "transparent"
|
||||
textColor: "{colors.text.default}"
|
||||
borderColor: "{colors.border.strong}"
|
||||
typography: "{typography.bodyM}"
|
||||
rounded: "{rounded.md}"
|
||||
padding: "10px 16px"
|
||||
height: "40px"
|
||||
input.default:
|
||||
backgroundColor: "{colors.surface.background}"
|
||||
textColor: "{colors.text.default}"
|
||||
borderColor: "{colors.border.default}"
|
||||
typography: "{typography.bodyM}"
|
||||
rounded: "{rounded.md}"
|
||||
padding: "10px 12px"
|
||||
padding: "8px 12px"
|
||||
height: "40px"
|
||||
focusRing: "{elevation.focusRing}"
|
||||
card.default:
|
||||
backgroundColor: "{colors.surface.background}"
|
||||
textColor: "{colors.text.default}"
|
||||
borderColor: "{colors.border.default}"
|
||||
rounded: "{rounded.lg}"
|
||||
padding: "24px"
|
||||
shadow: "{elevation.1}"
|
||||
card.elevated:
|
||||
backgroundColor: "{colors.surface.background}"
|
||||
rounded: "{rounded.xl}"
|
||||
padding: "28px"
|
||||
shadow: "{elevation.3}"
|
||||
badge.default:
|
||||
backgroundColor: "{colors.surface.muted}"
|
||||
textColor: "{colors.text.default}"
|
||||
backgroundColor: "{colors.brand.primarySoft}"
|
||||
textColor: "{colors.brand.primaryHover}"
|
||||
typography: "{typography.caption}"
|
||||
rounded: "{rounded.full}"
|
||||
padding: "2px 8px"
|
||||
height: "20px"
|
||||
padding: "2px 10px"
|
||||
height: "22px"
|
||||
badge.success:
|
||||
backgroundColor: "{colors.semantic.successSoft}"
|
||||
textColor: "{colors.semantic.success}"
|
||||
badge.warning:
|
||||
backgroundColor: "{colors.semantic.warningSoft}"
|
||||
textColor: "{colors.semantic.warning}"
|
||||
badge.danger:
|
||||
backgroundColor: "{colors.semantic.dangerSoft}"
|
||||
textColor: "{colors.semantic.danger}"
|
||||
modal.default:
|
||||
backgroundColor: "{colors.surface.background}"
|
||||
textColor: "{colors.text.default}"
|
||||
rounded: "{rounded.xl}"
|
||||
padding: "24px"
|
||||
width: "480px"
|
||||
shadow: "{elevation.4}"
|
||||
---
|
||||
|
||||
## Overview
|
||||
@@ -180,13 +243,14 @@ KDS targets WCAG 2.2 AA at minimum across all components and themes.
|
||||
|
||||
## Colors
|
||||
|
||||
Color is organized in three layers:
|
||||
Color is organized in four layers:
|
||||
|
||||
1. **Brand** — the four-color brand palette: `brand.primary` (`#6B35A7` purple), `brand.ink` (`#000000`), `neutral.0` (`#FFFFFF`), and `brand.canvas` (`#F5F4F0` off-white).
|
||||
2. **Neutral** — a 12-step gray ramp powering surfaces, text, and borders. `neutral.50` is set to `brand.canvas` so the off-white reads as the natural page surface.
|
||||
3. **Semantic** — meaning-bearing colors for status: success, warning, danger, info. These sit alongside the brand palette but are not part of brand identity.
|
||||
1. **Brand** — Kode purple (`brand.primary` `#6B35A7`) plus its hover / pressed / light / soft variants, anchored by a purple-tinted ink (`brand.ink` `#1A1530` — never pure black) and the warm off-white canvas (`brand.canvas` `#F7F4ED`).
|
||||
2. **Accent** — `accent.gold` (`#C9892B`) is the product emphasis colour for submit / commit actions; `accent.mint` (`#46C194`) is reserved for marketing surfaces (workspace dashboard, decks). Use one accent per surface — never both.
|
||||
3. **Neutral** — a purple-tinted 13-step ramp (`neutral.0` → `neutral.1000`). The ramp deliberately walks toward the brand ink rather than a cold grey, so muted text and borders stay on-brand. `neutral.50` is a warm inset surface, `neutral.100` aliases `brand.canvas`, `neutral.900` aliases `brand.ink`.
|
||||
4. **Semantic** — `success` / `warning` / `danger` / `info` plus matching `*Soft` background tints, tuned to sit calmly on the warm canvas (e.g. `success` is `#2F7A5A`, not the louder `#16A34A`).
|
||||
|
||||
Always reference *role* tokens (`text.default`, `surface.subtle`, `border.default`) in product code rather than raw palette values, so themes can swap without churn.
|
||||
Always reference *role* tokens (`text.default`, `surface.canvas`, `border.default`) in product code — never raw palette values — so themes can swap without churn.
|
||||
|
||||
Contrast minimums:
|
||||
|
||||
@@ -238,12 +302,13 @@ Elevation is conveyed through a small set of layered shadows plus subtle backgro
|
||||
| Level | Use | Shadow |
|
||||
|-------|-----|--------|
|
||||
| 0 | flush surfaces, page background | none |
|
||||
| 1 | cards, list rows | `0 1px 2px rgba(17,24,39,0.06)` |
|
||||
| 2 | dropdowns, popovers | `0 4px 12px rgba(17,24,39,0.10)` |
|
||||
| 3 | modals, dialogs | `0 16px 32px rgba(17,24,39,0.16)` |
|
||||
| 4 | toasts, command bars | `0 24px 48px rgba(17,24,39,0.20)` |
|
||||
| 1 | cards, list rows, buttons | `0 1px 2px rgba(26,21,48,0.04)` |
|
||||
| 2 | dropdowns, popovers | `0 4px 12px -4px rgba(26,21,48,0.08)` |
|
||||
| 3 | modals, dialogs | `0 16px 40px -16px rgba(26,21,48,0.18)` |
|
||||
| 4 | toasts, command bars | `0 24px 80px -24px rgba(26,21,48,0.22)` |
|
||||
| focusRing | any focusable element | `0 0 0 3px rgba(107,53,167,0.18)` |
|
||||
|
||||
In dark theme, shadows are de-emphasized and elevation is communicated primarily through lighter surface tints.
|
||||
Shadows are tinted with the brand ink (`rgb(26 21 48)`) — not cold slate — so they read warm against the canvas. In dark theme, shadows are de-emphasized and elevation is communicated primarily through lighter surface tints.
|
||||
|
||||
## Shapes
|
||||
|
||||
|
||||
Reference in New Issue
Block a user