6593bdf689
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>
366 lines
13 KiB
Markdown
366 lines
13 KiB
Markdown
---
|
||
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. Reconciled 2026-05-17 from production usage across kdcsurveyadd, kdcvault, kdc_void_planner and k-d-c-workspace.
|
||
colors:
|
||
brand.primary: "#6B35A7"
|
||
brand.primaryHover: "#5C2D90"
|
||
brand.primaryPressed: "#45216E"
|
||
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: "#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.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"
|
||
fontSize: "72px"
|
||
fontWeight: 700
|
||
lineHeight: "80px"
|
||
letterSpacing: "-0.01em"
|
||
wordmarkSecondary:
|
||
fontFamily: "Manrope"
|
||
fontSize: "20px"
|
||
fontWeight: 200
|
||
lineHeight: "28px"
|
||
letterSpacing: "0.04em"
|
||
headingXL:
|
||
fontFamily: "Manrope"
|
||
fontSize: "32px"
|
||
fontWeight: 700
|
||
lineHeight: "40px"
|
||
headingL:
|
||
fontFamily: "Manrope"
|
||
fontSize: "24px"
|
||
fontWeight: 600
|
||
lineHeight: "32px"
|
||
headingM:
|
||
fontFamily: "Manrope"
|
||
fontSize: "20px"
|
||
fontWeight: 600
|
||
lineHeight: "28px"
|
||
headingS:
|
||
fontFamily: "Manrope"
|
||
fontSize: "16px"
|
||
fontWeight: 600
|
||
lineHeight: "24px"
|
||
bodyL:
|
||
fontFamily: "Manrope"
|
||
fontSize: "18px"
|
||
fontWeight: 400
|
||
lineHeight: "28px"
|
||
bodyM:
|
||
fontFamily: "Manrope"
|
||
fontSize: "16px"
|
||
fontWeight: 400
|
||
lineHeight: "24px"
|
||
bodyS:
|
||
fontFamily: "Manrope"
|
||
fontSize: "14px"
|
||
fontWeight: 400
|
||
lineHeight: "20px"
|
||
caption:
|
||
fontFamily: "Manrope"
|
||
fontSize: "12px"
|
||
fontWeight: 500
|
||
lineHeight: "16px"
|
||
letterSpacing: "0.02em"
|
||
mono:
|
||
fontFamily: "Roboto Mono"
|
||
fontSize: "14px"
|
||
fontWeight: 400
|
||
lineHeight: "20px"
|
||
rounded:
|
||
none: "0px"
|
||
xs: "2px"
|
||
sm: "4px"
|
||
md: "8px"
|
||
lg: "12px"
|
||
xl: "16px"
|
||
"2xl": "24px"
|
||
full: "9999px"
|
||
spacing:
|
||
"0": "0px"
|
||
"1": "4px"
|
||
"2": "8px"
|
||
"3": "12px"
|
||
"4": "16px"
|
||
"5": "20px"
|
||
"6": "24px"
|
||
"8": "32px"
|
||
"10": "40px"
|
||
"12": "48px"
|
||
"16": "64px"
|
||
"20": "80px"
|
||
"24": "96px"
|
||
components:
|
||
button.primary:
|
||
backgroundColor: "{colors.brand.primary}"
|
||
textColor: "{colors.text.inverse}"
|
||
typography: "{typography.bodyM}"
|
||
rounded: "{rounded.md}"
|
||
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: "10px 16px"
|
||
height: "40px"
|
||
button.ghost:
|
||
backgroundColor: "transparent"
|
||
textColor: "{colors.brand.primary}"
|
||
typography: "{typography.bodyM}"
|
||
rounded: "{rounded.md}"
|
||
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: "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.brand.primarySoft}"
|
||
textColor: "{colors.brand.primaryHover}"
|
||
typography: "{typography.caption}"
|
||
rounded: "{rounded.full}"
|
||
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
|
||
|
||
The KDC Design System (KDS) is the source of truth for the visual and interaction language across all KDC products, marketing, and brand surfaces. It exists to make consistency cheap, accessibility default, and good design fast.
|
||
|
||
**Brand pillars**
|
||
|
||
- **Clear** — communication is direct and free of jargon.
|
||
- **Confident** — strong typography, decisive color, generous whitespace.
|
||
- **Human** — warm accents and approachable voice balance the precision.
|
||
|
||
KDS targets WCAG 2.2 AA at minimum across all components and themes.
|
||
|
||
## Colors
|
||
|
||
Color is organized in four layers:
|
||
|
||
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.canvas`, `border.default`) in product code — never raw palette values — so themes can swap without churn.
|
||
|
||
Contrast minimums:
|
||
|
||
- Body text on background: ≥ 4.5:1
|
||
- Large text and UI icons: ≥ 3:1
|
||
- Disabled/decorative content is exempt but should still be perceivable.
|
||
|
||
## Typography
|
||
|
||
KDS uses two brand typefaces:
|
||
|
||
- **Opificio Bold** — reserved for the **kode** wordmark and headline display moments. Available in Bold, Rounded, and Regular cuts; Bold is the canonical brand weight.
|
||
- **Manrope** — the working typeface for all UI: headings, body, captions, and the secondary wordmark line ("design consultants"). Use the full weight ramp: ExtraLight (200), Light (300), Regular (400), Medium (500), SemiBold (600), Bold (700), ExtraBold (800).
|
||
|
||
The wordmark lockup pairs them: primary line in Opificio Bold (72pt, 52pt spacing), secondary line in Manrope ExtraLight (20pt, 76pt spacing).
|
||
|
||
The UI scale is a modular 8-step ramp (`caption` → `display`). Use semantic tokens (`headingL`, `bodyM`) — never hardcode `font-size`. Body copy defaults to `bodyM`/16px with a 1.5 line-height for readability.
|
||
|
||
A monospace stack (Roboto Mono fallback to system mono) is available for code and tabular figures only — it is **not** part of the brand identity.
|
||
|
||
Web fonts are self-hosted from `assets/fonts/` and preloaded for Manrope Regular (400) and SemiBold (600), plus Opificio Bold for the wordmark.
|
||
|
||
## Layout
|
||
|
||
KDS is built on a **4px base unit**. All spacing, sizing, and layout dimensions are multiples of 4. The `spacing` scale exposes the curated set most commonly needed (`1`–`24`).
|
||
|
||
**Grid**
|
||
|
||
- 12-column responsive grid.
|
||
- Gutters: 16px (mobile) / 24px (tablet) / 32px (desktop).
|
||
- Max content width: 1200px, centered.
|
||
|
||
**Breakpoints**
|
||
|
||
| Token | Min width |
|
||
|-------|-----------|
|
||
| sm | 640px |
|
||
| md | 768px |
|
||
| lg | 1024px |
|
||
| xl | 1280px |
|
||
| 2xl | 1536px |
|
||
|
||
Layouts should be mobile-first and use logical properties (`inline-start`, `block-end`) for RTL readiness.
|
||
|
||
## Elevation & Depth
|
||
|
||
Elevation is conveyed through a small set of layered shadows plus subtle background shifts. Avoid using elevation for decoration — reserve it for affordance and hierarchy.
|
||
|
||
| Level | Use | Shadow |
|
||
|-------|-----|--------|
|
||
| 0 | flush surfaces, page background | none |
|
||
| 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)` |
|
||
|
||
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
|
||
|
||
Corner radius is calibrated to component density:
|
||
|
||
- `xs` (2px) — chips, inline tags
|
||
- `sm` (4px) — inputs, small controls
|
||
- `md` (8px) — buttons, default surfaces
|
||
- `lg` (12px) — cards, sections
|
||
- `xl` (16px) — modals, sheets
|
||
- `2xl` (24px) — marketing surfaces, feature panels
|
||
- `full` — pills, avatars, circular buttons
|
||
|
||
Avoid mixing more than two radii in a single composition.
|
||
|
||
## Components
|
||
|
||
The component library lives under `components/` with one folder per primitive. Each folder ships:
|
||
|
||
- A spec (`README.md`) documenting variants, states, props, and a11y notes.
|
||
- Anatomy SVG/PNG.
|
||
- Implementation references (web/mobile, where applicable).
|
||
|
||
Core primitives shipped today:
|
||
|
||
- **Buttons** — primary, secondary, ghost, destructive; sizes sm/md/lg; loading & disabled states.
|
||
- **Inputs** — text, textarea, select, checkbox, radio, switch.
|
||
- **Cards** — default, elevated, outlined.
|
||
- **Modals** — dialog, sheet, drawer.
|
||
- **Navigation** — top bar, side nav, tabs, breadcrumbs, pagination.
|
||
- **Forms** — field, label, helper text, error message, fieldset.
|
||
- **Tables** — sortable, selectable, paginated.
|
||
- **Badges** — neutral, success, warning, danger, info.
|
||
- **Tooltips, Alerts, Tabs, Dropdowns**.
|
||
|
||
Every interactive component must define: default, hover, focus-visible, active/pressed, disabled, and (where relevant) loading.
|
||
|
||
## Do's and Don'ts
|
||
|
||
**Do**
|
||
|
||
- Use role tokens (`text.default`) over palette tokens (`neutral.900`).
|
||
- Pair every color with a contrast check before shipping.
|
||
- Lean on whitespace before adding rules, borders, or shadows.
|
||
- Keep motion under 250ms for UI feedback; ease-out for entrances, ease-in for exits.
|
||
- Provide focus-visible styles on every interactive element.
|
||
|
||
**Don't**
|
||
|
||
- Don't introduce off-system colors, fonts, or radii in product UI.
|
||
- Don't use color alone to convey meaning — always pair with icon or text.
|
||
- Don't stack more than two elevation levels in a single composition.
|
||
- Don't override component internals; extend via documented props/slots.
|
||
- Don't ship animations longer than 400ms on transactional UI.
|