Two changes in one commit because they were prepared together and the component demos depend on the new self-hosted fonts.css. Tier 3 wave 2 — 12 new components --------------------------------- Adds components-tier3-supplement.css (886 lines) and 12 isolated demo HTML pages under shared/playground-examples/components/: toxic-flow chain, fleet-overview, kanban Keep/Review/Remove, maturity-ladder, classify-and-transform, cycle-ribbon, persistent-antipattern, suppressed-signals, ExpansionCard, ReadMore, FormProgress, Aspirational-vs-Committed. Reuses existing tokens — no new CSS custom properties. Honors the Phase 1 feedback rules: no large pink areas for body text, severity-red distinct from failure-red, dark mode via existing [data-theme="dark"]. Provenance: components-tier3-supplement.css and the 12 demo bodies were authored by claude.ai/design (separate Anthropic instance) on 2026-05-03. This commit only integrates them — path rewrites, font swap, generic name substitution in fleet-overview demo data, README updates. base.css from the export was deliberately NOT taken in because it reverted the inline-message contrast fix from v0.1. Self-hosted fonts (Inter, JetBrains Mono, Source Serif 4) --------------------------------------------------------- Replaces all fonts.googleapis.com / fonts.gstatic.com requests with .woff2 files bundled at shared/playground-design-system/fonts/. Why: - No data leaked to Google about end-user IPs and User-Agents. - GDPR-safe for Norwegian public-sector deployments. - Works offline / behind air-gapped firewalls. - Forkers downloading the marketplace get a complete bundle. All three families are SIL Open Font License 1.1 — license texts included alongside the woff2 files. Source Serif 4 woff2 generated locally from the upstream OTF release using fonttools ttLib.woff2 compress; Inter and JetBrains Mono are unmodified upstream webfont releases. Total bundle: 9 woff2 files, ~940 KB. New fonts.css declares all @font-face rules with font-display: swap. All 6 example HTMLs and 12 new component demos load it via a single relative path. Verified -------- - Privacy grep returns empty across plugins/ and shared/ - Google Fonts grep returns empty across shared/*.html - Smoke test via python -m http.server: HTML + 7 stylesheets + Inter-Regular.woff2 all return 200 Doc updates ----------- - shared/playground-design-system/README.md: file tree updated, Quick start snippet shows fonts.css link, "Self-hosted fonts" section added - shared/playground-design-system/fonts/LICENSES.md: combined attribution - README.md (root): Tier 3 wave 1+2 component list, Privacy-first bullet - CLAUDE.md (root): tree entry expanded for new components + fonts Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
16 KiB
Playground Design System
A shared design system for plugin Playgrounds — visual self-service UIs that complement terminal slash-commands. Built for Norwegian public sector with WCAG 2.1 AA compliance, Aksel/Digdir-aligned aesthetics, and self-contained HTML deployment.
Version: 0.1 (Phase 1 — 2026-05-02)
Provenance
This design system was generated by claude.ai/design (Anthropic) in a dialog-based design session driven by a comprehensive brief covering five plugins (ms-ai-architect, okr, llm-security, ultraplan-local, config-audit), Norwegian public-sector design conventions (Aksel/Digdir), and domain-specific visual standards (NS 5814 risk matrices, EU AI Act 4-tier pyramide, Doerr OKR scoring, NIST CSF, OWASP threat modeling).
Integration into the marketplace (file organization, path normalization, README authoring, root-doc cross-references) was performed in a separate Claude Code session. Per Anthropic Consumer Terms §4, ownership of outputs is assigned to the user; this design system is licensed MIT alongside the rest of the marketplace.
Directory layout
shared/
├── playground-design-system/ # The design system (this directory)
│ ├── README.md # This file
│ ├── tokens.css # CSS custom properties (Aksel/Digdir-aligned)
│ ├── base.css # Reset, typography, primitives, focus, print
│ ├── components.css # Tier 1: radar, matrix, findings-browser, critique-card, wizard, live-meter
│ ├── components-tier2.css # Tier 2: decision-tree, traffic-lights, diff-review, treemap, distribution, command-pipeline, pyramide, pipeline-cockpit, verdict-pill+risk-meter, codepoint-reveal, small-multiples, OWASP badges
│ ├── components-tier3.css # Tier 3 wave 1: pair-before-after, AI Act timeline, 3-track entry, FRIA rights-matrix, capability-matrix, parallel-agent-status, ErrorSummary, GuidePanel
│ ├── components-tier3-supplement.css # Tier 3 wave 2 (12): toxic-flow, fleet-overview, kanban Keep/Review/Remove, maturity-ladder, classify-and-transform, cycle-ribbon, persistent-antipattern, suppressed-signals, ExpansionCard, ReadMore, FormProgress, Aspirational-vs-Committed
│ ├── fonts.css # @font-face declarations for self-hosted fonts
│ ├── fonts/ # Self-hosted woff2 + license attribution
│ │ ├── Inter-{Regular,Medium,SemiBold,Bold}.woff2
│ │ ├── JetBrainsMono-{Regular,Medium,SemiBold}.woff2
│ │ ├── SourceSerif4-{Regular,Semibold}.woff2
│ │ └── LICENSES.md # All three are SIL OFL 1.1
│ ├── print.css # A4 print stylesheet with B/W severity patterns
│ └── schemas/ # Cross-plugin JSON schemas
│ ├── finding.schema.json # Used by llm-security, config-audit, ultraplan-review, ms-ai-review
│ ├── okr-set.schema.json # Used by OKR plugin
│ └── ros-threat.schema.json # Used by ms-ai-architect ROS workflow
│
└── playground-examples/ # Showcase + reference scenarios
├── index.html # System showcase (browse all components)
├── ros-lier-kommune.html # Scenario A — ms-ai-architect ROS report
├── okr-baerum.html # Scenario B — OKR live writer
├── security-direktorat.html # Scenario C — llm-security findings review
├── templates.html # Skeleton + print-template demos
├── tier3-preview.html # Tier 3 wave 1 visual preview
├── components/ # Tier 3 wave 2 — 12 isolated demo pages
│ ├── sankey-toxic-flow.html
│ ├── fleet-overview.html
│ ├── kanban.html
│ ├── maturity-ladder.html
│ ├── classify-transform.html
│ ├── cycle-ribbon.html
│ ├── persistent-antipattern.html
│ ├── suppressed-signals.html
│ ├── expansion-card.html
│ ├── read-more.html
│ ├── form-progress.html
│ └── aspirational-committed.html
├── ros-app.js # Scenario A interactivity
└── ros-data.js # Scenario A mock data
Quick start
To use the design system from a plugin's Playground:
<!doctype html>
<html lang="nb" data-theme="light">
<head>
<meta charset="utf-8">
<link rel="stylesheet" href="../../shared/playground-design-system/tokens.css">
<link rel="stylesheet" href="../../shared/playground-design-system/base.css">
<link rel="stylesheet" href="../../shared/playground-design-system/components.css">
<link rel="stylesheet" href="../../shared/playground-design-system/components-tier2.css">
<!-- Optional: include components-tier3.css for Tier 3 wave 1 components -->
<!-- Optional: include components-tier3-supplement.css for Tier 3 wave 2 (12 additional components) -->
<!-- Optional: only include print.css if scenario produces a printable A4 report -->
<link rel="stylesheet" href="../../shared/playground-design-system/print.css">
<!-- Self-hosted fonts (no external requests) -->
<link rel="stylesheet" href="../../shared/playground-design-system/fonts.css">
</head>
<body>
<header class="app-header">
<a class="app-header__brand" href="...">
<span class="app-header__brand-mark">MS</span>
ms-ai-architect
</a>
<span class="app-header__breadcrumb">/ Playground</span>
<div class="app-header__spacer"></div>
<button class="theme-toggle" data-theme-toggle>Mørk modus</button>
</header>
<!-- Your Playground content using design-system classes -->
</body>
</html>
The relative path ../../shared/playground-design-system/ assumes the plugin's Playground lives at plugins/{plugin-name}/playground/index.html. Adjust the prefix to match your plugin's structure.
Design principles
- Aksel/Digdir-aligned. Inter font, body 17px, Digdir blue
#0062BA, semantic CSS tokens. Norwegian public sector users recognize this DNA. - WCAG 2.1 AA non-negotiable. Required by
Forskrift om universell utforming av IKTfor Norwegian public sector. Every component ships with proper focus rings, ARIA attributes, keyboard navigation, and contrast that passes deuteranopia simulators. - Vanilla HTML/CSS/JS. No React, no Tailwind, no build step. A plugin can copy a Playground HTML file to disk and it will render correctly.
- Self-contained per Playground. Each plugin's
playground/*.htmlshould be openable offline with only the design-system CSS files alongside. - Print-aware. The
print.cssstylesheet ensures matrix cells use B/W-safe hatching patterns when printed, severity badges become outlined boxes with patterns, and interactive chrome disappears. Designed for A4 reports going to Datatilsynet, kommunestyre, statsråd. - Severity is universal. All severity-coded UI uses the same five-level ramp (low/medium/high/critical/extreme) with deuteranopia-safe hex values defined in
tokens.css. Distinct from "state" tokens (failed/blocked/queued/running) used in pipeline contexts — never mix severity-red with failure-red. - Two-spor strategy. The system supports both non-technical decision makers (Spor 1: ms-ai-architect, OKR, llm-security) and developer power-users (Spor 2: ultraplan-local, config-audit) — same component library, different information densities.
Token system
See tokens.css for full reference. Highlights:
- Typography:
--font-family-sans(Inter),--font-size-md(17px body),--measure(65ch line length) - Primary:
--color-primary-500=#0062BA(Digdir blue), with 50/100/300/500/700/900 ramp - Severity:
--color-severity-{low,medium,high,critical,extreme}+-soft(background) +-on(foreground) variants. Deuteranopia-safe. - State:
--color-state-{success,warning,failed,blocked,info,running,queued,pending,done}— distinct from severity - Surface: Warm off-white
#FBFAF7(light), graphite#0F1419(dark). Theme via[data-theme="dark"]on<html>or<body> - Plugin scope:
--color-scope-{architect,okr,security,ultraplan,config}for visual differentiation between plugins - Spacing: 4px grid, scale 1-20 (4px to 80px)
- Radius:
--radius-sm(3px) /-md(5px) /-lg(8px) /-pill(999px) — max 8px (no consumer-app rounded corners) - Motion: Respects
prefers-reduced-motion
Component reference
Tier 1 (components.css)
| Component | Class prefix | Used by |
|---|---|---|
| Radar / Spider chart | .radar |
OKR maturity (7-axis), ms-ai security (6), ms-ai ROS dimensions (7), ultraplan plan-critic (7) |
| Matrix / 5×5 heatmap | .matrix |
ms-ai ROS, DPIA, OKR coverage, security scanner, license map |
| Findings-browser | .findings |
llm-security, ultraplan-review, config-audit, ms-ai-review |
| Critique-card | .critique-card |
llm-security findings, ultraplan, config-audit feature-gap, OKR antipatterns |
| Wizard / Stepper | .stepper, .wizard__panel |
ms-ai 5-step intake, security clean, config-audit audit, ultraplan, OKR onboarding |
| Live-meter | .live-meter, .lint-annotation |
OKR writer, ultraplan brief-reviewer, cost, config-audit |
Plus app-shell primitives: .app-header, .sidepanel, .scrim, .theme-toggle.
Tier 3 (components-tier3.css)
Critical components for ms-ai-architect Playground v3 plus universal Aksel patterns. Authored 2026-05-02 in Claude Code (not via claude.ai/design — visual coherence verified against Tier 1+2 in playground-examples/tier3-preview.html).
| Component | Class prefix | Used by |
|---|---|---|
| Inherent + residual pair | .pair-before-after |
ms-ai ROS before/after, DPIA, AI Act mitigations, OKR check-ins |
| AI Act compliance-tidslinje | .aiact-timeline, .aiact-countdown |
ms-ai-architect classify flow + dashboard |
| 3-track entry | .tracks |
All plugins — entry-level UX choice (Guide/Explore/Expert) |
| FRIA rights-matrix | .rights-matrix |
ms-ai-architect FRIA (Art. 27, 12 EU Charter rights × impact) |
| Capability-matrix | .capability-matrix |
ms-ai-architect license × kapabilitet mapping |
| Parallel-agent-status | .agent-grid, .agent-card |
ms-ai utredning multi-worker, ultraplan multi-wave execute |
| ErrorSummary | .error-summary |
All plugins — Aksel/GOV.UK form-validation pattern |
| GuidePanel | .guide-panel |
All plugins — Aksel friendly inline guidance with optional CTA |
Tier 2 (components-tier2.css)
| Component | Class prefix | Used by |
|---|---|---|
| Decision-tree | .decision-tree, .dt-node, .dt-edge |
ms-ai AI Act 4-step classifier, security MAESTRO drill |
| Traffic-lights | .traffic-light |
ms-ai compliance, OKR KR-status, security pre-deploy, config-audit risk |
| Diff-review | .diff |
security diff, config-audit drift, ultraplan triage |
| Treemap | .treemap |
config-audit token-hotspots |
| Distribution / range-viz | .distribution |
ms-ai cost P10/P50/P90, security risk-score, OKR progress |
| Command-pipeline | .cmd-pipeline, .cmd-step |
All plugins — final export of slash-command sequence |
| Pyramide (4-tier) | .pyramide |
ms-ai AI Act risk classification |
| Pipeline-cockpit | .pipeline-cockpit, .pc-stage |
ultraplan 6-stage flow, ms-ai utredning, config-audit audit |
| Verdict-pill + risk-meter | .verdict-pill-lg, .risk-meter |
llm-security BLOCK/WARNING/ALLOW + 0-100 risk-score |
| Codepoint-reveal | .codepoint-reveal |
llm-security Unicode steganography demo |
| Small-multiples grid | .small-multiples, .sm-card |
llm-security 16-category posture (alternative to overcrowded radar) |
| OWASP badges | .badge--owasp-{llm,asi,ast,mcp} |
llm-security finding cross-mapping (4 frameworks) |
Schemas
schemas/ contains JSON schemas for cross-plugin data interchange:
finding.schema.json— universal "finding" shape (id, title, severity, source, evidence, rationale, recommendation, status). Consumed by llm-security, config-audit, ultraplan-review, ms-ai-review. Maps directly to the.critique-cardcomponent.okr-set.schema.json— OKR shape (objectives + key results, scoring, antipattern annotations). Consumed by OKR plugin.ros-threat.schema.json— ROS threat shape (likelihood × consequence, mitigation references, residual risk). Consumed by ms-ai-architect.
A plugin command can output JSON conforming to these schemas, and a Playground can render the result without further translation.
Theming
Default is light. Toggle dark via data-theme="dark" attribute on <html> or <body>. The system also respects prefers-color-scheme: dark when no explicit theme is set:
// Toggle dark/light
document.documentElement.dataset.theme =
document.documentElement.dataset.theme === 'dark' ? 'light' : 'dark';
localStorage.setItem('theme', document.documentElement.dataset.theme);
Print mode
Include print.css if your scenario produces an A4 report. Then add class="no-print" to interactive chrome (header, buttons, theme toggle), and use class="page-break" to force page breaks. Severity-coded matrix cells will automatically render as B/W-safe hatching patterns when printed. The .print-header and .print-footer blocks support kommune-logo slots and signature lines for offentlige dokumenter.
Known limitations
- No JavaScript framework. Components are CSS-first. Interactivity (e.g.
aria-selectedtoggling, sidepanel open/close, live-meter updates) must be wired by each Playground using vanilla JS. Seeplayground-examples/ros-app.jsfor a reference implementation pattern. - No icon set bundled. The system assumes Lucide or Phosphor SVG sprites are inlined per Playground. Iconography is intentionally out-of-system to keep the shared system small.
- Mobile responsiveness is partial. The 5×5 matrix, findings-browser, codepoint-reveal split-pane, and small-multiples grid have explicit
@media (max-width: ...)rules. Other components may need polish for narrow viewports.
Self-hosted fonts
All three font families (Inter, JetBrains Mono, Source Serif 4) are bundled as woff2 in fonts/ and loaded via fonts.css. No external requests to Google Fonts or any CDN. All three are SIL OFL 1.1 — see fonts/LICENSES.md for full attribution.
Versioning
This system follows semver:
- Major: Breaking token rename, component class rename, schema field removal/rename
- Minor: New tokens, new components, new schema fields, new variants
- Patch: Bugfixes, accessibility improvements, visual polish without contract changes
Every plugin Playground that consumes the design system should declare the version in a comment at the top of its HTML:
<!-- playground-design-system v0.1 -->
License
MIT, same as the parent ktg-plugin-marketplace. Reuse freely; attribution appreciated.
Contributing
This is a solo project. PRs are not accepted, but issues and suggestions are welcome at the marketplace repo (Forgejo: git.fromaitochitta.com/open/ktg-plugin-marketplace).
When adding a new component:
- Add CSS to
components.css(Tier 1) orcomponents-tier2.css(Tier 2) - Use BEM naming convention:
.component-name__element--modifier - Reference only
tokens.csscustom properties — never hard-code colors, spacing, or fonts - Test in light + dark themes, with deuteranopia simulator (Stark, Sim Daltonism)
- Test keyboard navigation and screen reader (NVDA on Windows, VoiceOver on Mac)
- Add a print rule if the component appears in printable reports
- Document in this README under the appropriate Tier table