{"id":49826716,"url":"https://github.com/gregnblack/kanso-protocol","last_synced_at":"2026-05-18T07:13:55.872Z","repository":{"id":349886784,"uuid":"1204354943","full_name":"GregNBlack/kanso-protocol","owner":"GregNBlack","description":"Kanso Protocol — an open source design system for Angular, built on architectural consistency. Design tokens in W3C DTCG format serve as a single source of truth for both Figma and code. 簡素 — simplicity through elimination of excess.","archived":false,"fork":false,"pushed_at":"2026-05-12T14:15:32.000Z","size":7495,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-05-12T14:32:22.819Z","etag":null,"topics":["accessibility","angular","component-library","dark-mode","design-system","design-tokens","figma","figma-community","mit-license","open-source","storybook","tabler-icons","typescript","w3c-dtcg"],"latest_commit_sha":null,"homepage":"https://www.figma.com/community/file/1633266134559104948","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/GregNBlack.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":"docs/roadmap.md","authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-04-07T23:52:54.000Z","updated_at":"2026-05-12T13:54:13.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/GregNBlack/kanso-protocol","commit_stats":null,"previous_names":["gregnblack/kanso-protocol"],"tags_count":27,"template":false,"template_full_name":null,"purl":"pkg:github/GregNBlack/kanso-protocol","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/GregNBlack%2Fkanso-protocol","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/GregNBlack%2Fkanso-protocol/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/GregNBlack%2Fkanso-protocol/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/GregNBlack%2Fkanso-protocol/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/GregNBlack","download_url":"https://codeload.github.com/GregNBlack/kanso-protocol/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/GregNBlack%2Fkanso-protocol/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32991982,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-13T13:14:54.681Z","status":"ssl_error","status_checked_at":"2026-05-13T13:14:51.610Z","response_time":115,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["accessibility","angular","component-library","dark-mode","design-system","design-tokens","figma","figma-community","mit-license","open-source","storybook","tabler-icons","typescript","w3c-dtcg"],"created_at":"2026-05-13T17:03:40.016Z","updated_at":"2026-05-18T07:13:55.852Z","avatar_url":"https://github.com/GregNBlack.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# 簡素 Kanso Protocol\n\n[![CI](https://github.com/GregNBlack/kanso-protocol/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/GregNBlack/kanso-protocol/actions/workflows/ci.yml)\n[![Storybook](https://img.shields.io/badge/Storybook-live-FF4785?logo=storybook\u0026logoColor=white)](https://gregnblack.github.io/kanso-protocol)\n[![Figma Community](https://img.shields.io/badge/Figma-Community-F24E1E?logo=figma\u0026logoColor=white)](https://www.figma.com/community/file/1633266134559104948)\n[![Tests](https://img.shields.io/endpoint?url=https%3A%2F%2Fraw.githubusercontent.com%2FGregNBlack%2Fkanso-protocol%2Fmain%2F.github%2Fbadges%2Ftests.json)](https://gregnblack.github.io/kanso-protocol/?path=/docs/foundations-test-coverage--docs)\n[![MCP](https://img.shields.io/badge/MCP-ready-7c3aed)](https://www.npmjs.com/package/@kanso-protocol/mcp)\n[![License](https://img.shields.io/badge/license-MIT-blue)](LICENSE)\n\n**Open source design system for Angular, built on architectural consistency.**\n\nDesign tokens in W3C DTCG format serve as a single source of truth for both Figma and code. Rules are embedded in architecture, not in agreements.\n\n\u003e **Status: `2.x` stable.** Components are `stable` or `beta` per [`docs/1.0-readiness.md`](docs/1.0-readiness.md); a handful remain `experimental` and may break in minor releases. Pin exact versions in production. The `2.0` line shipped native HTML form controls everywhere; `2.0.3` finished the a11y phase-2 cleanup (AA contrast + ARIA, CI gate hard-blocks on critical impacts). See [`docs/roadmap.md`](docs/roadmap.md) for what's next and the [changelog](CHANGELOG.md) for what landed.\n\n---\n\n## Why Kanso Protocol?\n\n簡素 (*kanso*) — one of the seven principles of Japanese aesthetics — is the practice of restraint and the removal of the unnecessary. The library follows the same idea: a small, opinionated, internally consistent surface where the rules live in the code, not in conventions.\n\n- **Every value is a token.** Components never carry magic numbers or inline hex. CSS custom properties — generated from W3C DTCG tokens — are the single source of truth shared between Figma and code.\n- **Every component follows the same anatomy.** Container → Content → Element. New components don't introduce a new mental model.\n- **Every state is explicit.** Six named states (rest / hover / active / focus / disabled / loading), each with its own color and motion tokens.\n- **No exception without a record.** When a component departs from the contract, the deviation lives as an ADR with a reason — not as an undocumented one-off.\n- **Designed to stay small.** Components are added intentionally, when there's a clear need — not because something might be useful.\n- **One npm package per component.** Install only what you use; nothing transitive comes along.\n- **AI-native.** Ships with `@kanso-protocol/mcp` — a Model Context Protocol server that exposes the live, typed catalog to Claude Code, Cursor, and VS Code, so the assistant authors Kanso UI from the actual API instead of from training-data guesses.\n\n## Live Preview\n\n- **Storybook:** [gregnblack.github.io/kanso-protocol](https://gregnblack.github.io/kanso-protocol) — every component, pattern and example page with autodocs, live controls, and a light/dark theme toggle.\n- **Figma Community:** [figma.com/community/file/1633266134559104948](https://www.figma.com/community/file/1633266134559104948) — the full design library; duplicate it into your team to use the components, variables, and example pages directly.\n\n## AI-native: ship with an MCP server\n\nKanso Protocol is one of the first design systems to ship a [**Model Context Protocol**](https://modelcontextprotocol.io) server out of the box — [`@kanso-protocol/mcp`](https://www.npmjs.com/package/@kanso-protocol/mcp). Your AI assistant (Claude Code, Cursor, VS Code, any MCP-aware client) can introspect the entire catalog over stdio: every component's inputs / outputs / ARIA role / keyboard pattern, every pattern, every design token. No copy-pasting docs, no guessing prop names, no out-of-date snippets.\n\n### Install\n\nThe server runs via `npx`, so there's nothing to install globally — pick the snippet for your editor below.\n\n\u003cdetails open\u003e\n\u003csummary\u003e\u003cb\u003eClaude Code\u003c/b\u003e\u003c/summary\u003e\n\nOne command from the project root:\n\n```bash\nclaude mcp add kanso -- npx @kanso-protocol/mcp\n```\n\n…or, equivalently, drop this into your project's `.mcp.json` (create the file if missing):\n\n```jsonc\n{\n  \"mcpServers\": {\n    \"kanso\": { \"command\": \"npx\", \"args\": [\"@kanso-protocol/mcp\"] }\n  }\n}\n```\n\nRestart Claude Code, then run `/mcp` to confirm `kanso` appears as ✔ connected with 7 tools.\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cb\u003eCursor\u003c/b\u003e\u003c/summary\u003e\n\nOpen *Settings → Features → MCP* → **Add new MCP server**, then fill:\n\n- Name: `kanso`\n- Type: `command`\n- Command: `npx @kanso-protocol/mcp`\n\n…or edit `~/.cursor/mcp.json` directly (project-scoped: `.cursor/mcp.json` in repo root):\n\n```jsonc\n{\n  \"mcpServers\": {\n    \"kanso\": { \"command\": \"npx\", \"args\": [\"@kanso-protocol/mcp\"] }\n  }\n}\n```\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cb\u003eVS Code (Continue, Cline, GitHub Copilot agent mode)\u003c/b\u003e\u003c/summary\u003e\n\nAdd to the extension's MCP config — for Continue this is `~/.continue/config.json`, for Cline it's the *Cline MCP Servers* settings panel. Same shape:\n\n```jsonc\n{\n  \"mcpServers\": {\n    \"kanso\": { \"command\": \"npx\", \"args\": [\"@kanso-protocol/mcp\"] }\n  }\n}\n```\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cb\u003eOther MCP-aware clients (Zed, Windsurf, Goose, custom)\u003c/b\u003e\u003c/summary\u003e\n\nAny client that speaks the [MCP stdio transport](https://modelcontextprotocol.io/docs/concepts/transports) works. Point it at:\n\n```\ncommand: npx\nargs:    [\"@kanso-protocol/mcp\"]\n```\n\nThe server registers seven tools at startup (`catalog_overview`, `list_components`, `get_component`, `list_patterns`, `get_pattern`, `list_tokens`, `get_token`).\n\n\u003c/details\u003e\n\n### Try it\n\nOnce connected, ask your assistant things like:\n\n- *\"Which size ramp does `kp-input` support, and which validators does `form-field` translate by default?\"*\n- *\"List every `--kp-color-*` token tied to the danger role.\"*\n- *\"I need a settings page with a sidebar of collapsible sections — which Kanso pieces compose that?\"*\n\nThe assistant calls `list_components` / `get_component` / `list_tokens` under the hood and answers from the live catalog. Full tool reference and the roadmap (Figma bridge in `0.2.x`) live in the [package README](packages/mcp/README.md).\n\n## Install \u0026 Use\n\nInstall the pieces you need — each component is its own package. Zero transitive dependencies between components, so you only ship what you import.\n\n```bash\nnpm install @kanso-protocol/core @kanso-protocol/button\n```\n\nLoad the tokens once in your app bootstrap. The primary distribution is **CSS custom properties** — all components consume them at runtime:\n\n```ts\nimport '@kanso-protocol/core/styles/tokens.css';\nimport '@kanso-protocol/core/styles/dark.css';   // optional — enables [data-theme=\"dark\"]\n```\n\n**Sass / SCSS consumers** can also import the equivalent compile-time `$kp-*` variables (handy for projects that haven't migrated to CSS custom properties yet):\n\n```scss\n@use '@kanso-protocol/core/styles/tokens' as *;   // exposes $kp-color-blue-600 etc.\n```\n\nBoth files are generated from the same DTCG source; pick whichever fits your stylesheet pipeline. Components themselves only depend on the CSS variables — they work identically regardless of which import you choose.\n\nUse the component as a standalone Angular import:\n\n```ts\nimport { Component } from '@angular/core';\nimport { KpButtonComponent } from '@kanso-protocol/button';\n\n@Component({\n  standalone: true,\n  imports: [KpButtonComponent],\n  template: `\u003ckp-button color=\"primary\" (click)=\"save()\"\u003eSave\u003c/kp-button\u003e`,\n})\nexport class MyFeatureComponent { save() { /* ... */ } }\n```\n\nSwitch themes by toggling `data-theme` on `\u003chtml\u003e` or `\u003cbody\u003e`:\n\n```html\n\u003chtml data-theme=\"dark\"\u003e   \u003c!-- or \"light\" / omit for light --\u003e\n```\n\nSee the [Storybook](https://gregnblack.github.io/kanso-protocol) for the full API of every component — props, slots, variants, states, a11y notes.\n\n## Visual regression\n\nA small Playwright suite (`e2e/visual.spec.ts`) takes pixel-level screenshots of a curated set of representative stories — one per component family — in both light and dark themes. Baselines live in `e2e/visual.spec.ts-snapshots/` and are committed alongside source changes.\n\n```bash\n# Run against a locally-served Storybook\nnpm run build-storybook\nnpx http-server storybook-static --port 6006 --silent \u0026\nnpm run test:visual\n\n# Update baselines after an intentional visual change\nnpm run test:visual:update\n```\n\nCI runs the same suite under the `visual-regression` job. On a clean PR diffs above `maxDiffPixelRatio` (1%) fail the build; on the very first run (no committed baselines) CI generates them and uploads as a `visual-snapshots` artifact for review.\n\n## Contributing\n\nSee [CONTRIBUTING.md](CONTRIBUTING.md) for dev-environment setup, coding conventions, how to add a component, and the token workflow.\n\n## Development\n\n```bash\ngit clone https://github.com/GregNBlack/kanso-protocol.git\ncd kanso-protocol\nnpm install\nnpm run build:tokens    # DTCG JSON → CSS / SCSS / TS\nnpm run storybook       # localhost:6006\n```\n\n## Architecture\n\n```\nkanso-protocol/\n├── tokens/\n│   ├── primitive/        ← Raw values (colors, spacing, sizing)\n│   └── semantic/         ← Roles \u0026 states (color.primary.default.bg.rest)\n├── packages/\n│   ├── core/             ← Compiled tokens, types, mixins\n│   └── components/\n│       └── button/       ← Reference implementation\n├── .storybook/           ← Component showcase\n└── .github/workflows/    ← CI/CD\n```\n\n## Design Tokens\n\nTokens follow the [W3C DTCG](https://design-tokens.github.io/community-group/format/) specification.\n\n**Naming convention:**\n```\n{category}.{role}.{variant}.{property}.{state}\n```\n\nExample: `color.primary.default.bg.hover`\n\n**Two-level architecture:**\n\n| Level     | Purpose              | Example                              |\n|-----------|----------------------|--------------------------------------|\n| Primitive | Raw palette values   | `color.blue.600` → `#2563EB`        |\n| Semantic  | Interface roles      | `color.primary.default.bg.rest` → `{color.blue.600}` |\n\n## Component Anatomy\n\nEvery component follows a unified three-layer model:\n\n```\n┌─ Container ──────────────────────────┐\n│  padding · border · radius · bg      │\n│  ┌─ Content ──────────────────────┐  │\n│  │  gap                           │  │\n│  │  [Element] [Element] [Element] │  │\n│  │   icon      label     badge    │  │\n│  └────────────────────────────────┘  │\n└──────────────────────────────────────┘\n```\n\n\u003e Full vocabulary, naming rules, and the variant-vs-state model live in [`docs/component-anatomy.md`](docs/component-anatomy.md).\n\n## Component Sizes\n\n| Size | Height | Radius | Use case                  |\n|------|--------|--------|---------------------------|\n| XS   | 24px   | 8px    | Dense UI, tables, tags    |\n| SM   | 28px   | 10px   | Secondary actions         |\n| MD   | 36px   | 12px   | **Default** — buttons, inputs |\n| LG   | 44px   | 14px   | Touch-friendly, primary CTA |\n| XL   | 52px   | 16px   | Hero actions              |\n\n## States\n\nSix explicit states for every interactive component:\n\n| State    | Behavior                                        |\n|----------|-------------------------------------------------|\n| Rest     | Default appearance                              |\n| Hover    | Pointer over element                            |\n| Active   | Pointer pressed                                 |\n| Focus    | Keyboard focus — 2px outline ring               |\n| Disabled | Action unavailable — removed from tab order     |\n| Loading  | Action in progress — keeps focus, `aria-busy`   |\n\n**Loading ≠ Disabled.** Loading preserves focus and announces state to screen readers.\n\n## Usage\n\n```typescript\nimport { KpButtonComponent } from '@kanso-protocol/button';\n\n@Component({\n  imports: [KpButtonComponent],\n  template: `\n    \u003ckp-button size=\"md\" variant=\"default\" color=\"primary\"\u003e\n      Save\n    \u003c/kp-button\u003e\n\n    \u003ckp-button variant=\"outline\" color=\"danger\" [loading]=\"isSaving\"\u003e\n      Delete\n    \u003c/kp-button\u003e\n  `,\n})\nexport class MyComponent {\n  isSaving = false;\n}\n```\n\n## Components\n\n41 components, each its own npm package — install only what you import. Tokens live in `@kanso-protocol/core` and need to be loaded once for any of them to render correctly.\n\nInstall all components in one shot (zsh / bash brace expansion):\n\n```bash\nnpm i @kanso-protocol/core @kanso-protocol/{accordion,alert,avatar,avatar-group,badge,breadcrumbs,button,card,checkbox,combobox,command-palette,datepicker,dialog,divider,drawer,empty-state,file-upload,form-field,icon,input,markdown-viewer,menu,number-stepper,pagination,popover,progress,radio,rich-text-editor,segmented-control,select,skeleton,slider,table,tabs,textarea,timepicker,toast,toggle,tooltip,tree,virtual-list}\n```\n\nOr pick what you need from the catalog. Every component has a formal API contract (props, variants, states, a11y rules) and a live Storybook page with controls.\n\n| Component | Contract | Storybook | Install |\n|---|---|---|---|\n| Accordion | [accordion.md](docs/components/accordion.md) | [live ↗](https://gregnblack.github.io/kanso-protocol/?path=/docs/components-accordion--docs) | `npm i @kanso-protocol/accordion` |\n| Alert | [alert.md](docs/components/alert.md) | [live ↗](https://gregnblack.github.io/kanso-protocol/?path=/docs/components-alert--docs) | `npm i @kanso-protocol/alert` |\n| Avatar | [avatar.md](docs/components/avatar.md) | [live ↗](https://gregnblack.github.io/kanso-protocol/?path=/docs/components-avatar--docs) | `npm i @kanso-protocol/avatar` |\n| AvatarGroup | [avatar-group.md](docs/components/avatar-group.md) | [live ↗](https://gregnblack.github.io/kanso-protocol/?path=/docs/components-avatargroup--docs) | `npm i @kanso-protocol/avatar-group` |\n| Badge | [badge.md](docs/components/badge.md) | [live ↗](https://gregnblack.github.io/kanso-protocol/?path=/docs/components-badge--docs) | `npm i @kanso-protocol/badge` |\n| Breadcrumbs | [breadcrumbs.md](docs/components/breadcrumbs.md) | [live ↗](https://gregnblack.github.io/kanso-protocol/?path=/docs/components-breadcrumbs--docs) | `npm i @kanso-protocol/breadcrumbs` |\n| Button | [button.md](docs/components/button.md) | [live ↗](https://gregnblack.github.io/kanso-protocol/?path=/docs/components-button--docs) | `npm i @kanso-protocol/button` |\n| Card | [card.md](docs/components/card.md) | [live ↗](https://gregnblack.github.io/kanso-protocol/?path=/docs/components-card--docs) | `npm i @kanso-protocol/card` |\n| Checkbox | [checkbox.md](docs/components/checkbox.md) | [live ↗](https://gregnblack.github.io/kanso-protocol/?path=/docs/components-checkbox--docs) | `npm i @kanso-protocol/checkbox` |\n| Combobox | [combobox.md](docs/components/combobox.md) | [live ↗](https://gregnblack.github.io/kanso-protocol/?path=/docs/components-combobox--docs) | `npm i @kanso-protocol/combobox` |\n| CommandPalette | [command-palette.md](docs/components/command-palette.md) | [live ↗](https://gregnblack.github.io/kanso-protocol/?path=/docs/components-commandpalette--docs) | `npm i @kanso-protocol/command-palette` |\n| DatePicker | [datepicker.md](docs/components/datepicker.md) | [live ↗](https://gregnblack.github.io/kanso-protocol/?path=/docs/components-datepicker--docs) | `npm i @kanso-protocol/datepicker` |\n| Dialog | [dialog.md](docs/components/dialog.md) | [live ↗](https://gregnblack.github.io/kanso-protocol/?path=/docs/components-dialog--docs) | `npm i @kanso-protocol/dialog` |\n| Divider | [divider.md](docs/components/divider.md) | [live ↗](https://gregnblack.github.io/kanso-protocol/?path=/docs/components-divider--docs) | `npm i @kanso-protocol/divider` |\n| Drawer | [drawer.md](docs/components/drawer.md) | [live ↗](https://gregnblack.github.io/kanso-protocol/?path=/docs/components-drawer--docs) | `npm i @kanso-protocol/drawer` |\n| DropdownMenu | [dropdown-menu.md](docs/components/dropdown-menu.md) | [live ↗](https://gregnblack.github.io/kanso-protocol/?path=/docs/components-dropdownmenu--docs) | `npm i @kanso-protocol/menu` |\n| EmptyState | [empty-state.md](docs/components/empty-state.md) | [live ↗](https://gregnblack.github.io/kanso-protocol/?path=/docs/components-emptystate--docs) | `npm i @kanso-protocol/empty-state` |\n| FileUpload | [file-upload.md](docs/components/file-upload.md) | [live ↗](https://gregnblack.github.io/kanso-protocol/?path=/docs/components-fileupload--docs) | `npm i @kanso-protocol/file-upload` |\n| FormField | [form-field.md](docs/components/form-field.md) | [live ↗](https://gregnblack.github.io/kanso-protocol/?path=/docs/components-formfield--docs) | `npm i @kanso-protocol/form-field` |\n| Icon | [icon.md](docs/components/icon.md) | [live ↗](https://gregnblack.github.io/kanso-protocol/?path=/docs/components-icon--docs) | `npm i @kanso-protocol/icon` |\n| Input | [input.md](docs/components/input.md) | [live ↗](https://gregnblack.github.io/kanso-protocol/?path=/docs/components-input--docs) | `npm i @kanso-protocol/input` |\n| MarkdownViewer | [markdown-viewer.md](docs/components/markdown-viewer.md) | [live ↗](https://gregnblack.github.io/kanso-protocol/?path=/docs/components-markdownviewer--docs) | `npm i @kanso-protocol/markdown-viewer` |\n| NumberStepper | [number-stepper.md](docs/components/number-stepper.md) | [live ↗](https://gregnblack.github.io/kanso-protocol/?path=/docs/components-numberstepper--docs) | `npm i @kanso-protocol/number-stepper` |\n| Pagination | [pagination.md](docs/components/pagination.md) | [live ↗](https://gregnblack.github.io/kanso-protocol/?path=/docs/components-pagination--docs) | `npm i @kanso-protocol/pagination` |\n| Popover | [popover.md](docs/components/popover.md) | [live ↗](https://gregnblack.github.io/kanso-protocol/?path=/docs/components-popover--docs) | `npm i @kanso-protocol/popover` |\n| Progress | [progress.md](docs/components/progress.md) | [linear ↗](https://gregnblack.github.io/kanso-protocol/?path=/docs/components-progress-linear--docs) · [circular ↗](https://gregnblack.github.io/kanso-protocol/?path=/docs/components-progress-circular--docs) · [segmented ↗](https://gregnblack.github.io/kanso-protocol/?path=/docs/components-progress-segmented--docs) | `npm i @kanso-protocol/progress` |\n| Radio | [radio.md](docs/components/radio.md) | [live ↗](https://gregnblack.github.io/kanso-protocol/?path=/docs/components-radio--docs) | `npm i @kanso-protocol/radio` |\n| RichTextEditor | [rich-text-editor.md](docs/components/rich-text-editor.md) | [live ↗](https://gregnblack.github.io/kanso-protocol/?path=/docs/components-richtexteditor--docs) | `npm i @kanso-protocol/rich-text-editor` |\n| SegmentedControl | [segmented-control.md](docs/components/segmented-control.md) | [live ↗](https://gregnblack.github.io/kanso-protocol/?path=/docs/components-segmentedcontrol--docs) | `npm i @kanso-protocol/segmented-control` |\n| Select | [select.md](docs/components/select.md) | [live ↗](https://gregnblack.github.io/kanso-protocol/?path=/docs/components-select--docs) | `npm i @kanso-protocol/select` |\n| Skeleton | [skeleton.md](docs/components/skeleton.md) | [live ↗](https://gregnblack.github.io/kanso-protocol/?path=/docs/components-skeleton--docs) | `npm i @kanso-protocol/skeleton` |\n| Slider | [slider.md](docs/components/slider.md) | [live ↗](https://gregnblack.github.io/kanso-protocol/?path=/docs/components-slider--docs) | `npm i @kanso-protocol/slider` |\n| Table | [table.md](docs/components/table.md) | [live ↗](https://gregnblack.github.io/kanso-protocol/?path=/docs/components-table--docs) | `npm i @kanso-protocol/table` |\n| Tabs | [tabs.md](docs/components/tabs.md) | [live ↗](https://gregnblack.github.io/kanso-protocol/?path=/docs/components-tabs--docs) | `npm i @kanso-protocol/tabs` |\n| Textarea | [textarea.md](docs/components/textarea.md) | [live ↗](https://gregnblack.github.io/kanso-protocol/?path=/docs/components-textarea--docs) | `npm i @kanso-protocol/textarea` |\n| TimePicker | [timepicker.md](docs/components/timepicker.md) | [live ↗](https://gregnblack.github.io/kanso-protocol/?path=/docs/components-timepicker--docs) | `npm i @kanso-protocol/timepicker` |\n| Toast | [toast.md](docs/components/toast.md) | [live ↗](https://gregnblack.github.io/kanso-protocol/?path=/docs/components-toast--docs) | `npm i @kanso-protocol/toast` |\n| Toggle | [toggle.md](docs/components/toggle.md) | [live ↗](https://gregnblack.github.io/kanso-protocol/?path=/docs/components-toggle--docs) | `npm i @kanso-protocol/toggle` |\n| Tooltip | [tooltip.md](docs/components/tooltip.md) | [live ↗](https://gregnblack.github.io/kanso-protocol/?path=/docs/components-tooltip--docs) | `npm i @kanso-protocol/tooltip` |\n| Tree | [tree.md](docs/components/tree.md) | [live ↗](https://gregnblack.github.io/kanso-protocol/?path=/docs/components-tree--docs) | `npm i @kanso-protocol/tree` |\n| VirtualList | [virtual-list.md](docs/components/virtual-list.md) | [live ↗](https://gregnblack.github.io/kanso-protocol/?path=/docs/components-virtuallist--docs) | `npm i @kanso-protocol/virtual-list` |\n\nAdding a new component? Start from [`docs/components/_template.md`](docs/components/_template.md).\n\n## Patterns\n\nPatterns are opinionated compositions of components for specific UI use cases.\nThey live in `packages/patterns/` and are imported the same way as components.\n\n| Pattern | What it is | Docs |\n|---|---|---|\n| AppShell | Page chrome — Header + Sidebar + main slot | [docs/patterns/app-shell.md](docs/patterns/app-shell.md) |\n| Banner | Full-width announcement strip | [docs/patterns/banner.md](docs/patterns/banner.md) |\n| Container | Page max-width + padding | [docs/patterns/container.md](docs/patterns/container.md) |\n| FilterBar | Active filter chips + add/save/clear | [docs/patterns/filter-bar.md](docs/patterns/filter-bar.md) |\n| FormSection | Titled block of form fields (inline / stacked) | [docs/patterns/form-section.md](docs/patterns/form-section.md) |\n| Grid | Equal-column responsive grid | [docs/patterns/grid.md](docs/patterns/grid.md) |\n| Header | Top app bar with logo, nav, search, user | [docs/patterns/header.md](docs/patterns/header.md) |\n| NavItem | Single sidebar / nav link with icon and badge | [docs/patterns/nav-item.md](docs/patterns/nav-item.md) |\n| NotificationCenter | Bell-anchored notification panel | [docs/patterns/notification-center.md](docs/patterns/notification-center.md) |\n| PageError | 404 / 500 / generic error page layout | [docs/patterns/page-error.md](docs/patterns/page-error.md) |\n| PageHeader | Title + breadcrumbs + actions + tabs | [docs/patterns/page-header.md](docs/patterns/page-header.md) |\n| Row | Horizontal flex row primitive | [docs/patterns/row.md](docs/patterns/row.md) |\n| SearchBar | Inline + command-palette search | [docs/patterns/search-bar.md](docs/patterns/search-bar.md) |\n| SettingsPanel | Card of settings rows with controls | [docs/patterns/settings-panel.md](docs/patterns/settings-panel.md) |\n| Sidebar | Expanded / collapsed app sidebar | [docs/patterns/sidebar.md](docs/patterns/sidebar.md) |\n| Stack | Vertical flex stack primitive | [docs/patterns/stack.md](docs/patterns/stack.md) |\n| StatCard | Single-metric tile for dashboards | [docs/patterns/stat-card.md](docs/patterns/stat-card.md) |\n| TableToolbar | Search / filter / actions bar above a table | [docs/patterns/table-toolbar.md](docs/patterns/table-toolbar.md) |\n| ThemeToggle | Light / dark / system switcher | [docs/patterns/theme-toggle.md](docs/patterns/theme-toggle.md) |\n| UserMenu | Avatar + popover with profile + logout | [docs/patterns/user-menu.md](docs/patterns/user-menu.md) |\n\n## Example Pages\n\nReference page compositions, built only from Kanso components and patterns —\nno forks, no hand-drawn parts. They live in `packages/examples/` (Storybook\nonly, not published to npm) and serve as the integration test for the system.\n\n| Page | What it shows | Docs |\n|---|---|---|\n| Login | Centered auth card with form, divider, social buttons | [docs/examples/login.md](docs/examples/login.md) |\n| Dashboard | Full app shell: KPIs, charts, recent activity | [docs/examples/dashboard.md](docs/examples/dashboard.md) |\n| Settings | Tabs + stack of SettingsPanels (Profile / Preferences / Danger zone) | [docs/examples/settings.md](docs/examples/settings.md) |\n| List View | Team members table — toolbar, filters, paginated table | [docs/examples/list-view.md](docs/examples/list-view.md) |\n| Detail View | Project record — rich PageHeader + 2/1 grid of cards | [docs/examples/detail-view.md](docs/examples/detail-view.md) |\n\n## Templates\n\nReusable application scaffolds — composed entirely from `@kanso-protocol/*`\ncomponents and patterns, but **distributed as code, not as npm packages.**\nDrop the file into your project, install peer packages, own the copy.\nSame convention as Material UI templates, Vercel templates, shadcn-ui.\n\n\u003e **Why not npm-publish them?** Templates are compositions, and every\n\u003e consumer ends up tweaking the layout. Stable layout APIs are hard\n\u003e (one project wants 3 panes, another wants RTL drawer, a third wants\n\u003e a mobile-first stack). Code-as-template lets you take it as a\n\u003e starting point without inheriting our opinions.\n\n| Template | What it is | Docs |\n|---|---|---|\n| Workspace | Productivity / admin scaffold — transparent header (logo + flexible header-nav + theme toggle + notifications + user menu), collapsible sidebar with smooth animation, 1-or-2-pane content area with drag-to-resize, light / dark / system theme handling, `prefers-color-scheme` live-tracking. Slot-first API: header-nav / notifications / user-menu items are content-projection slots, so each projected element keeps its own `routerLink` / `(click)` / `*ngIf`. | [docs/templates/workspace.md](docs/templates/workspace.md) |\n\n### Quick start (Workspace)\n\n```bash\n# 1. Install peer packages once (skip the ones you already have):\nnpm i @kanso-protocol/{core,app-shell,sidebar,nav-item,avatar,user-menu,\\\nmenu,theme-toggle,popover,notification-center,icon,button,badge,breadcrumbs}\n\n# 2. Copy the template file into your project:\nmkdir -p src/templates\ncurl -o src/templates/template-workspace.component.ts \\\n  https://raw.githubusercontent.com/GregNBlack/kanso-protocol/main/packages/examples/template-modern/template-workspace.component.ts\n```\n\nThen drop it into a route or page component:\n\n```ts\nimport { KpTemplateWorkspaceComponent } from './templates/template-workspace.component';\nimport {\n  KpBreadcrumbsComponent,\n  KpBreadcrumbItemComponent,\n  KpBreadcrumbSeparatorComponent,\n} from '@kanso-protocol/breadcrumbs';\nimport { KpMenuItemComponent } from '@kanso-protocol/menu';\nimport { KpIconComponent } from '@kanso-protocol/icon';\n\n@Component({\n  standalone: true,\n  imports: [\n    KpTemplateWorkspaceComponent,\n    KpBreadcrumbsComponent,\n    KpBreadcrumbItemComponent,\n    KpBreadcrumbSeparatorComponent,\n    KpMenuItemComponent,\n    KpIconComponent,\n  ],\n  template: `\n    \u003ckp-template-workspace\n      [navSections]=\"sections\"\n      [user]=\"user\"\n      [(theme)]=\"theme\"\n      (signOut)=\"logout()\"\u003e\n\n      \u003c!-- Header-nav slot — breadcrumbs (or a tenant select / tabs / search). --\u003e\n      \u003ckp-breadcrumbs kpWsHeaderNav size=\"md\"\u003e\n        \u003ckp-breadcrumb-item type=\"link\" href=\"/\"\u003eWorkspace\u003c/kp-breadcrumb-item\u003e\n        \u003ckp-breadcrumb-separator/\u003e\n        \u003ckp-breadcrumb-item type=\"current\"\u003eDashboard\u003c/kp-breadcrumb-item\u003e\n      \u003c/kp-breadcrumbs\u003e\n\n      \u003c!-- User-menu items — each is a real Angular element with own routerLink / click. --\u003e\n      \u003ckp-menu-item kpWsUserMenuItems label=\"Profile\"  routerLink=\"/profile\"\u003e\n        \u003ckp-icon kpMenuItemIcon name=\"user\" size=\"md\"/\u003e\n      \u003c/kp-menu-item\u003e\n      \u003ckp-menu-item kpWsUserMenuItems label=\"Settings\" routerLink=\"/settings\"\u003e\n        \u003ckp-icon kpMenuItemIcon name=\"settings\" size=\"md\"/\u003e\n      \u003c/kp-menu-item\u003e\n\n      \u003cdiv kpWsMain\u003e\u003c!-- your main content --\u003e\u003c/div\u003e\n      \u003cdiv kpWsSide\u003e\u003c!-- optional side pane --\u003e\u003c/div\u003e\n    \u003c/kp-template-workspace\u003e\n  `,\n})\n```\n\nLive demo: [Storybook → Templates / Workspace](https://gregnblack.github.io/kanso-protocol/?path=/story/templates-workspace--default).\nPublic API contract: [docs/templates/workspace.md](docs/templates/workspace.md).\n\n## Figma Integration\n\nThe full design library is published on Figma Community — duplicate it into your team to use the components, variables, and example pages directly:\n\n**[→ Kanso Protocol on Figma Community](https://www.figma.com/community/file/1633266134559104948)**\n\nInside: 41 components × variants, 20 patterns, 900+ W3C DTCG variables (light + dark modes), Iconography, and 5 example pages (Login, Dashboard, Settings, List View, Detail View).\n\n### Token sync\n\nTokens stay in lockstep with code via [Tokens Studio](https://tokens.studio):\n\n1. Tokens Studio reads DTCG JSON from this repository\n2. Changes to tokens create a Pull Request\n3. After merge, tokens update in both code and Figma Variables\n4. Components in Figma use Variables — theme switching works automatically\n\n## Built with Kanso\n\nShipping something built on Kanso Protocol? We'd love to feature it here.\n\nOpen a PR adding your project to this list, or [open an issue](https://github.com/GregNBlack/kanso-protocol/issues/new) with `[showcase]` in the title and we'll add it for you.\n\n| Project | What it is | Link |\n|---|---|---|\n| _Be the first._ | Open-source app, internal tool, side project — anything counts. | [Add yours →](https://github.com/GregNBlack/kanso-protocol/issues/new?title=%5Bshowcase%5D+) |\n\nWhat we ask for: a one-line description, a public link (live URL or GitHub repo), and a single screenshot or short clip.\n\n## Guiding Principles\n\n1. **Explicit over implicit.** No magic values — everything through tokens.\n2. **Architecture over agreements.** Rules are structural, not written.\n3. **Predictability over flexibility.** A small, opinionated API beats a configurable one — every consumer gets the same behavior instead of each team building their own dialect.\n4. **Single source of truth.** One change, one place.\n5. **Every component is equal.** Same anatomy, same contract, no exceptions without ADR.\n\n## Tech Stack\n\n- **Framework:** Angular 21+\n- **Monorepo:** Nx\n- **Tokens:** W3C DTCG + Style Dictionary 4 (emits CSS custom properties as the primary runtime, plus equivalent SCSS variables and TS constants for compile-time consumers)\n- **Docs:** Storybook 8\n- **Font:** [Onest](https://fonts.google.com/specimen/Onest) (Google Fonts, Cyrillic)\n- **Icons:** [Tabler Icons](https://tabler.io/icons)\n- **CI/CD:** GitHub Actions\n- **Figma sync:** Tokens Studio\n- **AI tooling:** [Model Context Protocol](https://modelcontextprotocol.io) — `@kanso-protocol/mcp`\n\n## License\n\n[MIT](LICENSE) © GregNBlack\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgregnblack%2Fkanso-protocol","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgregnblack%2Fkanso-protocol","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgregnblack%2Fkanso-protocol/lists"}