feat(ms-ai-architect): vendor playground-design-system v0.1 [skip-docs]
Initial sync of shared/playground-design-system/ into
plugins/ms-ai-architect/playground/vendor/playground-design-system/
via scripts/sync-design-system.mjs.
Source commit: f1fecf39b8
Files: 25 (7 CSS + 11 fonts/licenses + 3 schemas + README + MANIFEST)
Vendored copy keeps the plugin standalone — playground will load CSS
from ./vendor/ regardless of where the plugin is installed.
Also adds .gitleaks.toml at repo root with a path allowlist for
vendored MANIFEST.json files (SHA-256 file hashes are not secrets).
Docs updated together with the playground HTML refactor that actually
consumes the vendored CSS (next commit). This commit is internal-only.
This commit is contained in:
parent
f4aa1ed58f
commit
660bd106ce
26 changed files with 4130 additions and 0 deletions
35
plugins/ms-ai-architect/playground/vendor/playground-design-system/MANIFEST.json
vendored
Normal file
35
plugins/ms-ai-architect/playground/vendor/playground-design-system/MANIFEST.json
vendored
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
{
|
||||
"generated_by": "scripts/sync-design-system.mjs",
|
||||
"do_not_edit": true,
|
||||
"source": "shared/playground-design-system/",
|
||||
"source_commit": "f1fecf39b8fc20e86f6ec3c737f0dfda8403712e",
|
||||
"sync_date": "2026-05-03T10:24:01.408Z",
|
||||
"file_count": 25,
|
||||
"files": {
|
||||
"README.md": "83de0e29b207c979b7b2a3327b7a4ec0c2e1b4d3705ee2677f26c28c3a3ee643",
|
||||
"base.css": "604fe6839e2ed304bc0ba112a4e045f208b4b3f084f449a1abdb94ce0a1e5263",
|
||||
"components-tier2.css": "c2cb7e9d76d6af28d50db654030413777feb2f2f2b93213e598de8b686b14523",
|
||||
"components-tier3-supplement.css": "5b70503ce81a4aefc269e894ab0ae0921ab48370a00de19c737354274f520387",
|
||||
"components-tier3.css": "c391ea387298ce864bc35078e7e044b2cdd4187e3130456347d91876599ff4b1",
|
||||
"components.css": "f76b22ba9fd64c2e806b4467536174347105f3e5ccca8a6349a919287d864b86",
|
||||
"fonts.css": "e3c3df581c6e4d66e25c555f125c745f6512a33038401089d2519a94ea63ee3d",
|
||||
"fonts/Inter-Bold.woff2": "220976705fbec109f43c5cfdceca639e99ace7e51f3eb67292b105d3575eb39b",
|
||||
"fonts/Inter-Medium.woff2": "8458f8afa67b5691c1fcbe51607a2dafb53a9839e48131c608a186b65415d96d",
|
||||
"fonts/Inter-Regular.woff2": "b6f9db9e45be20f3c1312c97fbee7ec36b7d8280f8caa4d53c9ba0408cc9997a",
|
||||
"fonts/Inter-SemiBold.woff2": "8e52a861dc26ff4608c50bd7ff89b65d0d6216a2afe7b47ce5d84544811ca400",
|
||||
"fonts/JetBrainsMono-Medium.woff2": "086c48dfbea9ddaff1320f7e09399b8e2924e88ce67453721255db3bdbb5a353",
|
||||
"fonts/JetBrainsMono-Regular.woff2": "a9cb1cd82332b23a47e3a1239d25d13c86d16c4220695e34b243effa999f45f2",
|
||||
"fonts/JetBrainsMono-SemiBold.woff2": "918edad542a1da608fd2ba8daebaff9ac802309103fe760eed465b8b4e47faf1",
|
||||
"fonts/LICENSE-Inter.txt": "262481e844521b326f5ecd053e59b98c8b2da78c8ee1bdbb6e8174305e54935a",
|
||||
"fonts/LICENSE-JetBrainsMono.txt": "30f0c136e3c88e422d0791acd97238870f9054a9729bc34cf2ff0d4ed8cac4ad",
|
||||
"fonts/LICENSE-SourceSerif4.md": "75784a295293a8992f5a8d99210566e0064a012e6dab6731305e3787f15896c7",
|
||||
"fonts/LICENSES.md": "16ef4cb2f4d85233c27be390c3f52ee60d24f1a2a5f72886a0c5dbc8cfcf2c28",
|
||||
"fonts/SourceSerif4-Regular.woff2": "d5f6830fbdb42425cb60b5cd61d91afa9a2f59b8e99057b1a1d4c2e43b1b06dc",
|
||||
"fonts/SourceSerif4-Semibold.woff2": "dd00d4b1fea42ca7bd806175662ec51ec09494de986d85087861216cbcf17add",
|
||||
"print.css": "cd62f08d1b13e0308b5083b6cb5135739eb834e85e88468bd349a642d92b7a6f",
|
||||
"schemas/finding.schema.json": "0b24797373650582bac232d31a4dd9260593375a0d17259e18f1141a20de8d0c",
|
||||
"schemas/okr-set.schema.json": "aa27347fb232a956ec9dcee1775115710e2715a665c8d729ac50b90c6884de26",
|
||||
"schemas/ros-threat.schema.json": "e16497c1a6b79d6e78149d6cf1c28ac9df1e93234627a0c546814fb24d6c96d9",
|
||||
"tokens.css": "7598d5eda83e189418125cd73b8646e1b0d15a1c195b6f180fafa7944b5ba328"
|
||||
}
|
||||
}
|
||||
234
plugins/ms-ai-architect/playground/vendor/playground-design-system/README.md
vendored
Normal file
234
plugins/ms-ai-architect/playground/vendor/playground-design-system/README.md
vendored
Normal file
|
|
@ -0,0 +1,234 @@
|
|||
# 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](https://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:
|
||||
|
||||
```html
|
||||
<!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
|
||||
|
||||
1. **Aksel/Digdir-aligned.** Inter font, body 17px, Digdir blue `#0062BA`, semantic CSS tokens. Norwegian public sector users recognize this DNA.
|
||||
2. **WCAG 2.1 AA non-negotiable.** Required by `Forskrift om universell utforming av IKT` for Norwegian public sector. Every component ships with proper focus rings, ARIA attributes, keyboard navigation, and contrast that passes deuteranopia simulators.
|
||||
3. **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.
|
||||
4. **Self-contained per Playground.** Each plugin's `playground/*.html` should be openable offline with only the design-system CSS files alongside.
|
||||
5. **Print-aware.** The `print.css` stylesheet 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.
|
||||
6. **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.
|
||||
7. **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-card` component.
|
||||
- **`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:
|
||||
|
||||
```js
|
||||
// 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
|
||||
|
||||
1. **No JavaScript framework.** Components are CSS-first. Interactivity (e.g. `aria-selected` toggling, sidepanel open/close, live-meter updates) must be wired by each Playground using vanilla JS. See `playground-examples/ros-app.js` for a reference implementation pattern.
|
||||
2. **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.
|
||||
3. **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:
|
||||
|
||||
```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:
|
||||
|
||||
1. Add CSS to `components.css` (Tier 1) or `components-tier2.css` (Tier 2)
|
||||
2. Use BEM naming convention: `.component-name__element--modifier`
|
||||
3. Reference only `tokens.css` custom properties — never hard-code colors, spacing, or fonts
|
||||
4. Test in light + dark themes, with deuteranopia simulator (Stark, Sim Daltonism)
|
||||
5. Test keyboard navigation and screen reader (NVDA on Windows, VoiceOver on Mac)
|
||||
6. Add a print rule if the component appears in printable reports
|
||||
7. Document in this README under the appropriate Tier table
|
||||
264
plugins/ms-ai-architect/playground/vendor/playground-design-system/base.css
vendored
Normal file
264
plugins/ms-ai-architect/playground/vendor/playground-design-system/base.css
vendored
Normal file
|
|
@ -0,0 +1,264 @@
|
|||
/* Code generated by sync-design-system.mjs; DO NOT EDIT. */
|
||||
/* =============================================================================
|
||||
base.css — reset, typography, layout primitives, focus, print
|
||||
============================================================================= */
|
||||
|
||||
*, *::before, *::after { box-sizing: border-box; }
|
||||
|
||||
html {
|
||||
-webkit-text-size-adjust: 100%;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
text-rendering: optimizeLegibility;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
font-family: var(--font-family-sans);
|
||||
font-size: var(--font-size-md);
|
||||
line-height: var(--line-height-normal);
|
||||
color: var(--color-text-primary);
|
||||
background: var(--color-bg);
|
||||
font-feature-settings: "ss01", "cv11";
|
||||
}
|
||||
|
||||
h1, h2, h3, h4, h5, h6 {
|
||||
margin: 0;
|
||||
font-weight: var(--font-weight-semibold);
|
||||
line-height: var(--line-height-tight);
|
||||
letter-spacing: -0.01em;
|
||||
color: var(--color-text-primary);
|
||||
text-wrap: balance;
|
||||
}
|
||||
|
||||
h1 { font-size: var(--font-size-3xl); letter-spacing: -0.02em; }
|
||||
h2 { font-size: var(--font-size-2xl); letter-spacing: -0.015em; }
|
||||
h3 { font-size: var(--font-size-xl); }
|
||||
h4 { font-size: var(--font-size-lg); }
|
||||
h5 { font-size: var(--font-size-md); }
|
||||
|
||||
p {
|
||||
margin: 0;
|
||||
text-wrap: pretty;
|
||||
max-width: var(--measure);
|
||||
}
|
||||
|
||||
small { font-size: var(--font-size-sm); color: var(--color-text-secondary); }
|
||||
code, kbd, samp { font-family: var(--font-family-mono); font-size: 0.92em; }
|
||||
kbd {
|
||||
display: inline-block;
|
||||
padding: 1px 6px;
|
||||
font-size: 0.85em;
|
||||
border: 1px solid var(--color-border-moderate);
|
||||
border-bottom-width: 2px;
|
||||
border-radius: var(--radius-sm);
|
||||
background: var(--color-surface);
|
||||
color: var(--color-text-secondary);
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
a {
|
||||
color: var(--color-text-link);
|
||||
text-decoration: underline;
|
||||
text-underline-offset: 2px;
|
||||
text-decoration-thickness: 1px;
|
||||
}
|
||||
a:hover { color: var(--color-text-link-hover); text-decoration-thickness: 2px; }
|
||||
|
||||
button { font-family: inherit; }
|
||||
|
||||
/* Focus rings — WCAG */
|
||||
:focus-visible {
|
||||
outline: 2px solid var(--color-border-focus);
|
||||
outline-offset: 2px;
|
||||
border-radius: var(--radius-sm);
|
||||
}
|
||||
:focus:not(:focus-visible) { outline: none; }
|
||||
|
||||
/* ---------- Buttons ---------- */
|
||||
.btn {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: var(--space-2);
|
||||
padding: 9px 16px;
|
||||
font-size: var(--font-size-sm);
|
||||
font-weight: var(--font-weight-medium);
|
||||
line-height: 1.3;
|
||||
border-radius: var(--radius-md);
|
||||
border: 1px solid transparent;
|
||||
cursor: pointer;
|
||||
transition: background var(--duration-fast) var(--ease-default),
|
||||
border-color var(--duration-fast) var(--ease-default),
|
||||
color var(--duration-fast) var(--ease-default);
|
||||
white-space: nowrap;
|
||||
text-decoration: none;
|
||||
}
|
||||
.btn:disabled, .btn[aria-disabled="true"] { opacity: 0.5; cursor: not-allowed; }
|
||||
|
||||
.btn--primary { background: var(--color-primary-500); color: var(--color-text-on-primary); }
|
||||
.btn--primary:hover { background: var(--color-primary-700); }
|
||||
|
||||
.btn--secondary {
|
||||
background: var(--color-surface);
|
||||
color: var(--color-text-primary);
|
||||
border-color: var(--color-border-moderate);
|
||||
}
|
||||
.btn--secondary:hover { background: var(--color-bg-soft); border-color: var(--color-border-strong); }
|
||||
|
||||
.btn--ghost {
|
||||
background: transparent;
|
||||
color: var(--color-text-primary);
|
||||
border-color: transparent;
|
||||
}
|
||||
.btn--ghost:hover { background: var(--color-bg-soft); }
|
||||
|
||||
.btn--destructive { background: var(--color-severity-critical); color: #fff; }
|
||||
.btn--destructive:hover { background: var(--color-severity-extreme); }
|
||||
|
||||
.btn--sm { padding: 5px 10px; font-size: var(--font-size-xs); }
|
||||
.btn--lg { padding: 12px 20px; font-size: var(--font-size-md); }
|
||||
|
||||
/* ---------- Badges / pills ---------- */
|
||||
.badge {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
padding: 2px 8px;
|
||||
font-size: var(--font-size-xs);
|
||||
font-weight: var(--font-weight-medium);
|
||||
line-height: 1.4;
|
||||
border-radius: var(--radius-pill);
|
||||
border: 1px solid var(--color-border-subtle);
|
||||
background: var(--color-bg-soft);
|
||||
color: var(--color-text-secondary);
|
||||
white-space: nowrap;
|
||||
}
|
||||
.badge--severity-low { background: var(--color-severity-low-soft); color: var(--color-severity-low-on); border-color: transparent; }
|
||||
.badge--severity-medium { background: var(--color-severity-medium-soft); color: var(--color-severity-medium-on); border-color: transparent; }
|
||||
.badge--severity-high { background: var(--color-severity-high-soft); color: var(--color-severity-high-on); border-color: transparent; }
|
||||
.badge--severity-critical { background: var(--color-severity-critical); color: var(--color-severity-critical-on); border-color: transparent; }
|
||||
.badge--severity-extreme { background: var(--color-severity-extreme); color: var(--color-severity-extreme-on); border-color: transparent; }
|
||||
|
||||
.badge--owasp { font-family: var(--font-family-mono); font-size: 11px; padding: 1px 6px; }
|
||||
|
||||
.badge--scope-architect { background: var(--color-scope-architect); color: #fff; border-color: transparent; }
|
||||
.badge--scope-okr { background: var(--color-scope-okr); color: #fff; border-color: transparent; }
|
||||
.badge--scope-security { background: var(--color-scope-security); color: #fff; border-color: transparent; }
|
||||
.badge--scope-ultraplan { background: var(--color-scope-ultraplan); color: #fff; border-color: transparent; }
|
||||
.badge--scope-config { background: var(--color-scope-config); color: #fff; border-color: transparent; }
|
||||
|
||||
/* ---------- Cards / surfaces ---------- */
|
||||
.card {
|
||||
background: var(--color-surface);
|
||||
border: 1px solid var(--color-border-subtle);
|
||||
border-radius: var(--radius-lg);
|
||||
padding: var(--space-6);
|
||||
}
|
||||
.card--sunken { background: var(--color-surface-sunken); }
|
||||
.card--raised { box-shadow: var(--shadow-sm); }
|
||||
|
||||
/* ---------- Inline messages (Aksel 3-tier) ---------- */
|
||||
.inline-message {
|
||||
display: flex;
|
||||
gap: var(--space-3);
|
||||
padding: var(--space-3) var(--space-4);
|
||||
border-radius: var(--radius-md);
|
||||
border-left: 4px solid;
|
||||
background: var(--color-bg-soft);
|
||||
font-size: var(--font-size-sm);
|
||||
line-height: var(--line-height-snug);
|
||||
}
|
||||
.inline-message--info { border-color: var(--color-state-info); background: #EAF3FB; color: #08416B; }
|
||||
.inline-message--success { border-color: var(--color-state-success); background: var(--color-severity-low-soft); color: var(--color-severity-low-on); }
|
||||
.inline-message--warning { border-color: var(--color-state-warning); background: var(--color-severity-medium-soft); color: var(--color-severity-medium-on); }
|
||||
.inline-message--error { border-color: var(--color-severity-critical); background: var(--color-surface); color: var(--color-text-primary); }
|
||||
.inline-message--error strong, .inline-message--error b { color: var(--color-severity-critical); }
|
||||
|
||||
[data-theme="dark"] .inline-message--info { background: #0E2A3F; color: #9CC0EA; }
|
||||
[data-theme="dark"] .inline-message--error { background: var(--color-surface); color: var(--color-text-primary); }
|
||||
[data-theme="dark"] .inline-message--error strong, [data-theme="dark"] .inline-message--error b { color: #F09095; }
|
||||
|
||||
/* ---------- Form controls ---------- */
|
||||
.input, .select, .textarea {
|
||||
width: 100%;
|
||||
padding: 9px 12px;
|
||||
font-family: inherit;
|
||||
font-size: var(--font-size-sm);
|
||||
line-height: 1.4;
|
||||
color: var(--color-text-primary);
|
||||
background: var(--color-surface);
|
||||
border: 1px solid var(--color-border-moderate);
|
||||
border-radius: var(--radius-md);
|
||||
transition: border-color var(--duration-fast) var(--ease-default),
|
||||
box-shadow var(--duration-fast) var(--ease-default);
|
||||
}
|
||||
.input:hover, .select:hover, .textarea:hover { border-color: var(--color-border-strong); }
|
||||
.input:focus, .select:focus, .textarea:focus {
|
||||
outline: none;
|
||||
border-color: var(--color-primary-500);
|
||||
box-shadow: var(--shadow-focus);
|
||||
}
|
||||
.textarea { min-height: 96px; resize: vertical; line-height: var(--line-height-normal); }
|
||||
|
||||
.label {
|
||||
display: block;
|
||||
font-size: var(--font-size-sm);
|
||||
font-weight: var(--font-weight-medium);
|
||||
color: var(--color-text-primary);
|
||||
margin-bottom: 6px;
|
||||
}
|
||||
.label__hint { display: block; font-size: var(--font-size-xs); color: var(--color-text-tertiary); font-weight: 400; margin-top: 2px; }
|
||||
|
||||
/* ---------- Layout primitives ---------- */
|
||||
.stack { display: flex; flex-direction: column; gap: var(--space-4); }
|
||||
.stack--lg { gap: var(--space-8); }
|
||||
.stack--sm { gap: var(--space-2); }
|
||||
.row { display: flex; gap: var(--space-4); align-items: center; }
|
||||
.row--wrap { flex-wrap: wrap; }
|
||||
.row--between { justify-content: space-between; }
|
||||
|
||||
.container { max-width: var(--container-default); margin: 0 auto; padding: 0 var(--space-6); }
|
||||
.container--wide { max-width: var(--container-wide); }
|
||||
.container--narrow { max-width: var(--container-narrow); }
|
||||
|
||||
.divider {
|
||||
height: 1px;
|
||||
background: var(--color-border-subtle);
|
||||
border: none;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
/* ---------- Utilities ---------- */
|
||||
.text-secondary { color: var(--color-text-secondary); }
|
||||
.text-tertiary { color: var(--color-text-tertiary); }
|
||||
.text-mono { font-family: var(--font-family-mono); }
|
||||
.text-sm { font-size: var(--font-size-sm); }
|
||||
.text-xs { font-size: var(--font-size-xs); }
|
||||
.text-lg { font-size: var(--font-size-lg); }
|
||||
.font-medium { font-weight: var(--font-weight-medium); }
|
||||
.font-semibold { font-weight: var(--font-weight-semibold); }
|
||||
.tabular { font-variant-numeric: tabular-nums; }
|
||||
|
||||
.sr-only {
|
||||
position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
|
||||
overflow: hidden; clip: rect(0,0,0,0); white-space: nowrap; border: 0;
|
||||
}
|
||||
|
||||
/* ---------- Reduced motion ---------- */
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
*, *::before, *::after {
|
||||
animation-duration: 0.01ms !important;
|
||||
transition-duration: 0.01ms !important;
|
||||
}
|
||||
}
|
||||
|
||||
/* ---------- Print ---------- */
|
||||
@media print {
|
||||
body { background: #fff; color: #000; font-size: 11pt; }
|
||||
.no-print, button.btn, nav, .nav, .toolbar, .tweaks-panel { display: none !important; }
|
||||
.card { border: 1px solid #000; box-shadow: none; break-inside: avoid; }
|
||||
a { color: #000; text-decoration: underline; }
|
||||
h1, h2, h3 { break-after: avoid; }
|
||||
.matrix-cell { print-color-adjust: exact; -webkit-print-color-adjust: exact; }
|
||||
@page { margin: 18mm; }
|
||||
}
|
||||
352
plugins/ms-ai-architect/playground/vendor/playground-design-system/components-tier2.css
vendored
Normal file
352
plugins/ms-ai-architect/playground/vendor/playground-design-system/components-tier2.css
vendored
Normal file
|
|
@ -0,0 +1,352 @@
|
|||
/* Code generated by sync-design-system.mjs; DO NOT EDIT. */
|
||||
/* =============================================================================
|
||||
components-tier2.css — Tier 2 components (Phase 2)
|
||||
7. Decision-tree (AI Act 4-step)
|
||||
8. Traffic-lights
|
||||
9. Diff-review
|
||||
10. Treemap (config-audit token hotspots)
|
||||
11. Distribution / range-viz (P10/P50/P90)
|
||||
12. Command-pipeline output
|
||||
13. Pyramide (AI Act 4-tier)
|
||||
14. Pipeline-cockpit
|
||||
15. Verdict-pill with risk-meter
|
||||
16. Codepoint-reveal (security Unicode steg)
|
||||
17. Inherent + residual pair (already partially in Tier 1, formalize)
|
||||
18. Small-multiples grid
|
||||
============================================================================= */
|
||||
|
||||
/* DECISION-TREE — vertical flowchart with 4 colored terminals */
|
||||
.decision-tree { display: flex; flex-direction: column; align-items: center; gap: 0; }
|
||||
.dt-node {
|
||||
padding: 12px 18px;
|
||||
background: var(--color-surface);
|
||||
border: 1px solid var(--color-border-moderate);
|
||||
border-radius: var(--radius-md);
|
||||
font-size: var(--font-size-sm);
|
||||
font-weight: var(--font-weight-medium);
|
||||
text-align: center;
|
||||
min-width: 240px;
|
||||
max-width: 340px;
|
||||
}
|
||||
.dt-edge {
|
||||
width: 1px; height: 28px; background: var(--color-border-moderate);
|
||||
position: relative;
|
||||
}
|
||||
.dt-edge__label {
|
||||
position: absolute;
|
||||
left: 8px; top: 50%; transform: translateY(-50%);
|
||||
font-size: 11px; color: var(--color-text-tertiary);
|
||||
white-space: nowrap;
|
||||
font-family: var(--font-family-mono);
|
||||
}
|
||||
.dt-node--terminal { color: #fff; border: none; padding: 14px 20px; font-weight: var(--font-weight-semibold); }
|
||||
.dt-node--forbidden { background: var(--color-severity-extreme); }
|
||||
.dt-node--high { background: var(--color-severity-critical); }
|
||||
.dt-node--limited { background: var(--color-severity-medium); color: var(--color-severity-medium-on); }
|
||||
.dt-node--minimal { background: var(--color-severity-low); }
|
||||
.dt-row { display: flex; gap: var(--space-3); }
|
||||
|
||||
/* TRAFFIC-LIGHTS */
|
||||
.traffic-light {
|
||||
display: inline-flex; align-items: center; gap: 8px;
|
||||
padding: 6px 12px;
|
||||
border-radius: var(--radius-md);
|
||||
background: var(--color-bg-soft);
|
||||
border: 1px solid var(--color-border-subtle);
|
||||
font-size: var(--font-size-sm);
|
||||
}
|
||||
.traffic-light__dot {
|
||||
width: 10px; height: 10px; border-radius: 50%;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.traffic-light[data-status="green"] .traffic-light__dot { background: var(--color-state-success); }
|
||||
.traffic-light[data-status="yellow"] .traffic-light__dot { background: var(--color-severity-medium); }
|
||||
.traffic-light[data-status="red"] .traffic-light__dot { background: var(--color-severity-critical); }
|
||||
.traffic-light[data-status="gray"] .traffic-light__dot { background: var(--color-text-tertiary); }
|
||||
.traffic-light__label { font-weight: var(--font-weight-medium); }
|
||||
.traffic-light__why { color: var(--color-text-tertiary); font-size: var(--font-size-xs); }
|
||||
|
||||
/* DIFF-REVIEW */
|
||||
.diff { border: 1px solid var(--color-border-subtle); border-radius: var(--radius-md); overflow: hidden; }
|
||||
.diff__row { display: grid; grid-template-columns: 1fr 1fr; border-top: 1px solid var(--color-border-subtle); }
|
||||
.diff__row:first-child { border-top: none; }
|
||||
.diff__cell { padding: 10px 14px; font-size: var(--font-size-sm); font-family: var(--font-family-mono); }
|
||||
.diff__cell--removed { background: var(--color-severity-critical-soft); color: var(--color-severity-critical-on); border-right: 1px solid var(--color-border-subtle); }
|
||||
.diff__cell--added { background: var(--color-severity-low-soft); color: var(--color-severity-low-on); }
|
||||
.diff__cell--unchanged { color: var(--color-text-secondary); border-right: 1px solid var(--color-border-subtle); }
|
||||
.diff__summary { display: flex; gap: var(--space-4); padding: 12px 16px; background: var(--color-bg-soft); border-bottom: 1px solid var(--color-border-subtle); font-size: var(--font-size-sm); }
|
||||
.diff__summary-item { display: flex; gap: 6px; align-items: baseline; }
|
||||
.diff__summary-count { font-weight: var(--font-weight-semibold); font-variant-numeric: tabular-nums; }
|
||||
|
||||
/* TREEMAP — pure CSS treemap with grid */
|
||||
.treemap {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(12, 1fr);
|
||||
grid-auto-rows: 36px;
|
||||
gap: 2px;
|
||||
background: var(--color-border-subtle);
|
||||
border-radius: var(--radius-md);
|
||||
overflow: hidden;
|
||||
padding: 2px;
|
||||
}
|
||||
.treemap__tile {
|
||||
padding: 8px 10px;
|
||||
font-size: var(--font-size-xs);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
color: #fff;
|
||||
overflow: hidden;
|
||||
cursor: pointer;
|
||||
position: relative;
|
||||
}
|
||||
.treemap__tile-label { font-weight: var(--font-weight-semibold); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
|
||||
.treemap__tile-tokens { font-family: var(--font-family-mono); font-size: 11px; opacity: 0.85; }
|
||||
.treemap__tile[data-kind="claudemd"] { background: #4338CA; }
|
||||
.treemap__tile[data-kind="plugin"] { background: #0F6E76; }
|
||||
.treemap__tile[data-kind="skill"] { background: #9A6700; }
|
||||
.treemap__tile[data-kind="mcp"] { background: #3F5963; }
|
||||
.treemap__tile[data-kind="hook"] { background: #A40E26; }
|
||||
|
||||
/* DISTRIBUTION / range-viz */
|
||||
.distribution { display: flex; flex-direction: column; gap: var(--space-3); }
|
||||
.distribution__row { display: grid; grid-template-columns: 140px 1fr; gap: var(--space-3); align-items: center; font-size: var(--font-size-sm); }
|
||||
.distribution__label { color: var(--color-text-secondary); }
|
||||
.distribution__track {
|
||||
position: relative; height: 28px;
|
||||
background: var(--color-surface-sunken);
|
||||
border-radius: var(--radius-sm);
|
||||
overflow: visible;
|
||||
}
|
||||
.distribution__band {
|
||||
position: absolute; top: 6px; bottom: 6px;
|
||||
background: var(--color-primary-300);
|
||||
border-radius: var(--radius-pill);
|
||||
opacity: 0.4;
|
||||
}
|
||||
.distribution__median {
|
||||
position: absolute; top: 0; bottom: 0; width: 2px;
|
||||
background: var(--color-primary-700);
|
||||
}
|
||||
.distribution__median-label {
|
||||
position: absolute; top: -18px; left: 50%; transform: translateX(-50%);
|
||||
font-size: 11px; font-family: var(--font-family-mono); white-space: nowrap;
|
||||
color: var(--color-text-primary); font-weight: var(--font-weight-semibold);
|
||||
}
|
||||
.distribution__axis {
|
||||
display: grid; grid-template-columns: 140px 1fr; gap: var(--space-3);
|
||||
font-size: 11px; color: var(--color-text-tertiary); font-family: var(--font-family-mono);
|
||||
margin-top: 4px;
|
||||
}
|
||||
.distribution__axis-ticks { display: flex; justify-content: space-between; }
|
||||
|
||||
/* COMMAND-PIPELINE OUTPUT */
|
||||
.cmd-pipeline { display: flex; flex-direction: column; gap: var(--space-2); }
|
||||
.cmd-step {
|
||||
display: grid;
|
||||
grid-template-columns: 32px 1fr auto;
|
||||
gap: var(--space-3);
|
||||
padding: 12px 14px;
|
||||
background: var(--color-surface-sunken);
|
||||
border: 1px solid var(--color-border-subtle);
|
||||
border-radius: var(--radius-md);
|
||||
align-items: center;
|
||||
}
|
||||
.cmd-step__num {
|
||||
width: 24px; height: 24px;
|
||||
border-radius: 50%;
|
||||
background: var(--color-text-primary);
|
||||
color: var(--color-bg);
|
||||
display: flex; align-items: center; justify-content: center;
|
||||
font-family: var(--font-family-mono);
|
||||
font-size: 11px; font-weight: var(--font-weight-bold);
|
||||
}
|
||||
.cmd-step__cmd {
|
||||
font-family: var(--font-family-mono);
|
||||
font-size: var(--font-size-sm);
|
||||
color: var(--color-text-primary);
|
||||
word-break: break-all;
|
||||
}
|
||||
.cmd-step__cmd .cmd-flag { color: var(--color-state-info); }
|
||||
.cmd-step__cmd .cmd-arg { color: var(--color-severity-medium-on); }
|
||||
|
||||
/* PYRAMIDE — AI Act 4-tier */
|
||||
.pyramide { display: flex; flex-direction: column; align-items: center; gap: 4px; }
|
||||
.pyramide__tier {
|
||||
display: flex; align-items: center; justify-content: space-between;
|
||||
padding: 10px 18px;
|
||||
color: #fff;
|
||||
font-weight: var(--font-weight-semibold);
|
||||
font-size: var(--font-size-sm);
|
||||
border-radius: var(--radius-sm);
|
||||
width: 100%;
|
||||
}
|
||||
.pyramide__tier--forbidden { background: var(--color-severity-extreme); max-width: 30%; }
|
||||
.pyramide__tier--high { background: var(--color-severity-critical); max-width: 50%; }
|
||||
.pyramide__tier--limited { background: var(--color-severity-medium); color: var(--color-severity-medium-on); max-width: 75%; }
|
||||
.pyramide__tier--minimal { background: var(--color-severity-low); max-width: 100%; }
|
||||
.pyramide__tier-label { display: flex; gap: var(--space-2); align-items: center; }
|
||||
.pyramide__tier-share { font-family: var(--font-family-mono); font-size: 11px; opacity: 0.85; }
|
||||
|
||||
/* PIPELINE-COCKPIT */
|
||||
.pipeline-cockpit {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
|
||||
gap: 0;
|
||||
align-items: stretch;
|
||||
border: 1px solid var(--color-border-subtle);
|
||||
border-radius: var(--radius-md);
|
||||
overflow: hidden;
|
||||
background: var(--color-surface);
|
||||
}
|
||||
.pc-stage {
|
||||
padding: var(--space-3) var(--space-4);
|
||||
border-right: 1px solid var(--color-border-subtle);
|
||||
display: flex; flex-direction: column; gap: 4px;
|
||||
position: relative;
|
||||
}
|
||||
.pc-stage:last-child { border-right: none; }
|
||||
.pc-stage__num { font-family: var(--font-family-mono); font-size: 11px; color: var(--color-text-tertiary); }
|
||||
.pc-stage__name { font-weight: var(--font-weight-semibold); font-size: var(--font-size-sm); }
|
||||
.pc-stage__state {
|
||||
font-size: 11px; padding: 2px 8px; border-radius: var(--radius-pill);
|
||||
align-self: flex-start; margin-top: 4px;
|
||||
font-weight: var(--font-weight-medium);
|
||||
}
|
||||
.pc-stage__state[data-state="done"] { background: var(--color-severity-low-soft); color: var(--color-severity-low-on); }
|
||||
.pc-stage__state[data-state="running"] { background: var(--color-severity-medium-soft); color: var(--color-severity-medium-on); }
|
||||
.pc-stage__state[data-state="empty"] { background: var(--color-bg-soft); color: var(--color-text-tertiary); }
|
||||
.pc-stage__state[data-state="failed"] { background: var(--color-severity-critical); color: #fff; }
|
||||
.pc-stage[data-current="true"] { background: var(--color-primary-50); }
|
||||
[data-theme="dark"] .pc-stage[data-current="true"] { background: var(--color-primary-900); }
|
||||
|
||||
/* VERDICT-PILL with risk-meter */
|
||||
.verdict-block {
|
||||
display: grid;
|
||||
grid-template-columns: auto 1fr;
|
||||
gap: var(--space-6);
|
||||
align-items: center;
|
||||
padding: var(--space-5) var(--space-6);
|
||||
background: var(--color-surface);
|
||||
border: 1px solid var(--color-border-subtle);
|
||||
border-radius: var(--radius-lg);
|
||||
}
|
||||
.verdict-pill-lg {
|
||||
display: flex; flex-direction: column; align-items: center; gap: 2px;
|
||||
padding: var(--space-4) var(--space-5);
|
||||
border-radius: var(--radius-md);
|
||||
font-weight: var(--font-weight-bold);
|
||||
letter-spacing: 0.04em;
|
||||
}
|
||||
.verdict-pill-lg__verdict { font-size: var(--font-size-xl); }
|
||||
.verdict-pill-lg__sub { font-size: 11px; font-weight: var(--font-weight-medium); opacity: 0.8; text-transform: uppercase; letter-spacing: 0.1em; }
|
||||
.verdict-pill-lg[data-verdict="block"] { background: var(--color-severity-critical); color: #fff; }
|
||||
.verdict-pill-lg[data-verdict="warning"] { background: var(--color-severity-medium); color: var(--color-severity-medium-on); }
|
||||
.verdict-pill-lg[data-verdict="allow"] { background: var(--color-severity-low); color: #fff; }
|
||||
|
||||
.risk-meter { display: flex; flex-direction: column; gap: 6px; }
|
||||
.risk-meter__track {
|
||||
position: relative;
|
||||
height: 12px;
|
||||
background: linear-gradient(to right,
|
||||
var(--color-severity-low) 0%, var(--color-severity-low) 14%,
|
||||
var(--color-severity-medium) 14%, var(--color-severity-medium) 39%,
|
||||
var(--color-severity-high) 39%, var(--color-severity-high) 64%,
|
||||
var(--color-severity-critical) 64%, var(--color-severity-critical) 84%,
|
||||
var(--color-severity-extreme) 84%, var(--color-severity-extreme) 100%);
|
||||
border-radius: var(--radius-pill);
|
||||
}
|
||||
.risk-meter__pointer {
|
||||
position: absolute; top: -4px; bottom: -4px;
|
||||
width: 4px;
|
||||
background: var(--color-text-primary);
|
||||
border-radius: 2px;
|
||||
box-shadow: 0 0 0 2px var(--color-bg);
|
||||
}
|
||||
.risk-meter__scale {
|
||||
display: flex; justify-content: space-between;
|
||||
font-size: 11px; color: var(--color-text-tertiary);
|
||||
font-family: var(--font-family-mono);
|
||||
}
|
||||
.risk-meter__bands {
|
||||
display: flex; justify-content: space-between;
|
||||
font-size: 11px; color: var(--color-text-secondary);
|
||||
}
|
||||
.risk-meter__readout {
|
||||
display: flex; align-items: baseline; gap: 8px;
|
||||
}
|
||||
.risk-meter__score {
|
||||
font-size: var(--font-size-3xl); font-weight: var(--font-weight-bold);
|
||||
font-variant-numeric: tabular-nums;
|
||||
letter-spacing: -0.02em;
|
||||
}
|
||||
.risk-meter__band-label { font-size: var(--font-size-sm); color: var(--color-text-secondary); }
|
||||
|
||||
/* CODEPOINT-REVEAL */
|
||||
.codepoint-reveal { background: var(--color-surface-sunken); border: 1px solid var(--color-border-subtle); border-radius: var(--radius-md); overflow: hidden; }
|
||||
.codepoint-reveal__head { padding: 10px 14px; background: var(--color-bg-soft); border-bottom: 1px solid var(--color-border-subtle); display: flex; justify-content: space-between; align-items: center; }
|
||||
.codepoint-reveal__body { padding: var(--space-4); display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-4); }
|
||||
.codepoint-reveal__col { display: flex; flex-direction: column; gap: 8px; }
|
||||
.codepoint-reveal__col-label { font-size: 11px; text-transform: uppercase; letter-spacing: 0.06em; color: var(--color-text-tertiary); font-weight: var(--font-weight-semibold); }
|
||||
.codepoint-reveal__source {
|
||||
font-family: var(--font-family-mono);
|
||||
font-size: var(--font-size-sm);
|
||||
padding: 12px;
|
||||
background: var(--color-surface);
|
||||
border: 1px solid var(--color-border-subtle);
|
||||
border-radius: var(--radius-sm);
|
||||
min-height: 64px;
|
||||
word-break: break-all;
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
.cp-tag { background: var(--color-severity-critical); color: #fff; padding: 1px 4px; border-radius: 2px; font-size: 11px; }
|
||||
.cp-zw { background: var(--color-severity-medium); color: var(--color-severity-medium-on); padding: 1px 4px; border-radius: 2px; font-size: 11px; }
|
||||
.cp-bidi { background: var(--color-severity-high); color: #fff; padding: 1px 4px; border-radius: 2px; font-size: 11px; }
|
||||
.codepoint-reveal__decoded {
|
||||
font-family: var(--font-family-mono);
|
||||
font-size: var(--font-size-sm);
|
||||
padding: 12px;
|
||||
background: var(--color-text-primary);
|
||||
color: var(--color-bg);
|
||||
border-radius: var(--radius-sm);
|
||||
word-break: break-all;
|
||||
}
|
||||
|
||||
/* SMALL-MULTIPLES GRID (16-category posture) */
|
||||
.small-multiples {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(4, 1fr);
|
||||
gap: var(--space-3);
|
||||
}
|
||||
.sm-card {
|
||||
padding: var(--space-3);
|
||||
background: var(--color-surface);
|
||||
border: 1px solid var(--color-border-subtle);
|
||||
border-radius: var(--radius-md);
|
||||
display: flex; flex-direction: column; gap: 6px;
|
||||
}
|
||||
.sm-card__header { display: flex; justify-content: space-between; align-items: baseline; }
|
||||
.sm-card__name { font-size: var(--font-size-xs); font-weight: var(--font-weight-semibold); color: var(--color-text-secondary); text-transform: uppercase; letter-spacing: 0.04em; }
|
||||
.sm-card__grade {
|
||||
font-family: var(--font-family-mono);
|
||||
font-size: var(--font-size-lg);
|
||||
font-weight: var(--font-weight-bold);
|
||||
width: 28px; height: 28px;
|
||||
display: flex; align-items: center; justify-content: center;
|
||||
border-radius: var(--radius-sm);
|
||||
}
|
||||
.sm-card__grade[data-grade="A"] { background: var(--color-severity-low); color: #fff; }
|
||||
.sm-card__grade[data-grade="B"] { background: var(--color-severity-low-soft); color: var(--color-severity-low-on); }
|
||||
.sm-card__grade[data-grade="C"] { background: var(--color-severity-medium-soft); color: var(--color-severity-medium-on); }
|
||||
.sm-card__grade[data-grade="D"] { background: var(--color-severity-high-soft); color: var(--color-severity-high-on); }
|
||||
.sm-card__grade[data-grade="F"] { background: var(--color-severity-critical); color: #fff; }
|
||||
.sm-card__bar { height: 4px; background: var(--color-surface-sunken); border-radius: var(--radius-pill); overflow: hidden; }
|
||||
.sm-card__bar-fill { height: 100%; background: var(--color-primary-500); }
|
||||
.sm-card__status { font-size: 11px; color: var(--color-text-tertiary); }
|
||||
@media (max-width: 880px) { .small-multiples { grid-template-columns: repeat(2, 1fr); } }
|
||||
|
||||
/* OWASP badges (specific colors) */
|
||||
.badge--owasp-llm { background: #1F2328; color: #fff; }
|
||||
.badge--owasp-asi { background: #4338CA; color: #fff; }
|
||||
.badge--owasp-ast { background: #9A6700; color: #fff; }
|
||||
.badge--owasp-mcp { background: #0F6E76; color: #fff; }
|
||||
887
plugins/ms-ai-architect/playground/vendor/playground-design-system/components-tier3-supplement.css
vendored
Normal file
887
plugins/ms-ai-architect/playground/vendor/playground-design-system/components-tier3-supplement.css
vendored
Normal file
|
|
@ -0,0 +1,887 @@
|
|||
/* Code generated by sync-design-system.mjs; DO NOT EDIT. */
|
||||
/* =============================================================================
|
||||
components-tier3-supplement.css
|
||||
Tier 3 supplement — 12 components added after Tier 3 main set.
|
||||
Pinned rules:
|
||||
- No big pink fills for text. Use surface bg + colored border + dark body text.
|
||||
- severity-critical (#A40E26) ≠ state-failed (#7D1A1A). Don't conflate.
|
||||
- Light + dark theme via existing tokens only.
|
||||
============================================================================= */
|
||||
|
||||
/* =========================================================================
|
||||
1. Sankey / Toxic-Flow Chain (.tfa-flow)
|
||||
3-step: Input → Access → Exfil with mitigation shields breaking the chain.
|
||||
========================================================================= */
|
||||
.tfa-flow {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr auto 1fr auto 1fr;
|
||||
gap: 0;
|
||||
align-items: stretch;
|
||||
background: var(--color-surface);
|
||||
border: 1px solid var(--color-border-subtle);
|
||||
border-radius: var(--radius-lg);
|
||||
padding: var(--space-5);
|
||||
position: relative;
|
||||
}
|
||||
.tfa-flow__verdict {
|
||||
position: absolute;
|
||||
top: -12px; right: var(--space-5);
|
||||
padding: 4px 10px;
|
||||
font-size: 11px;
|
||||
font-weight: var(--font-weight-bold);
|
||||
letter-spacing: 0.06em;
|
||||
border-radius: var(--radius-pill);
|
||||
background: var(--color-severity-critical);
|
||||
color: #fff;
|
||||
}
|
||||
.tfa-flow__verdict[data-verdict="ALLOW"] { background: var(--color-state-success); }
|
||||
.tfa-flow__verdict[data-verdict="WARN"] { background: var(--color-severity-medium); color: #fff; }
|
||||
.tfa-flow__verdict[data-verdict="BLOCK"] { background: var(--color-severity-critical); }
|
||||
|
||||
.tfa-leg {
|
||||
display: flex; flex-direction: column; gap: 6px;
|
||||
padding: var(--space-3);
|
||||
background: var(--color-surface);
|
||||
border: 1px solid var(--color-border-subtle);
|
||||
border-left-width: 4px;
|
||||
border-radius: var(--radius-md);
|
||||
cursor: pointer;
|
||||
transition: background var(--duration-fast) var(--ease-default);
|
||||
text-align: left;
|
||||
}
|
||||
.tfa-leg:hover { background: var(--color-bg-soft); }
|
||||
.tfa-leg:focus-visible { outline: none; box-shadow: var(--shadow-focus); }
|
||||
.tfa-leg[data-severity="medium"] { border-left-color: var(--color-severity-medium); }
|
||||
.tfa-leg[data-severity="high"] { border-left-color: var(--color-severity-high); }
|
||||
.tfa-leg[data-severity="critical"] { border-left-color: var(--color-severity-critical); }
|
||||
|
||||
.tfa-leg__label {
|
||||
font-size: 11px; text-transform: uppercase; letter-spacing: 0.08em;
|
||||
color: var(--color-text-tertiary); font-weight: var(--font-weight-semibold);
|
||||
}
|
||||
.tfa-leg__name { font-size: var(--font-size-md); font-weight: var(--font-weight-semibold); color: var(--color-text-primary); }
|
||||
.tfa-leg__source { font-family: var(--font-family-mono); font-size: 12px; color: var(--color-text-secondary); }
|
||||
.tfa-leg__status {
|
||||
margin-top: auto;
|
||||
font-size: 11px;
|
||||
font-weight: var(--font-weight-medium);
|
||||
display: inline-flex; align-items: center; gap: 4px;
|
||||
}
|
||||
.tfa-leg__status[data-mit="unmitigated"] { color: var(--color-severity-critical); }
|
||||
.tfa-leg__status[data-mit="partially_mitigated"] { color: var(--color-severity-medium); }
|
||||
.tfa-leg__status[data-mit="mitigated"] { color: var(--color-state-success); }
|
||||
|
||||
/* Arrow connectors. Width grows with severity */
|
||||
.tfa-arrow {
|
||||
display: flex; align-items: center; justify-content: center;
|
||||
position: relative;
|
||||
min-width: 56px;
|
||||
padding: 0 4px;
|
||||
}
|
||||
.tfa-arrow__line {
|
||||
height: 4px;
|
||||
width: 100%;
|
||||
background: var(--color-border-moderate);
|
||||
position: relative;
|
||||
}
|
||||
.tfa-arrow[data-severity="medium"] .tfa-arrow__line { background: var(--color-severity-medium); height: 6px; }
|
||||
.tfa-arrow[data-severity="high"] .tfa-arrow__line { background: var(--color-severity-high); height: 8px; }
|
||||
.tfa-arrow[data-severity="critical"] .tfa-arrow__line { background: var(--color-severity-critical); height: 10px; }
|
||||
.tfa-arrow__line::after {
|
||||
content: ""; position: absolute; right: -1px; top: 50%;
|
||||
width: 0; height: 0;
|
||||
border-left: 10px solid currentColor;
|
||||
border-top: 8px solid transparent;
|
||||
border-bottom: 8px solid transparent;
|
||||
transform: translateY(-50%);
|
||||
color: inherit;
|
||||
}
|
||||
.tfa-arrow[data-severity="medium"] .tfa-arrow__line { color: var(--color-severity-medium); }
|
||||
.tfa-arrow[data-severity="high"] .tfa-arrow__line { color: var(--color-severity-high); }
|
||||
.tfa-arrow[data-severity="critical"] .tfa-arrow__line { color: var(--color-severity-critical); }
|
||||
|
||||
.tfa-arrow__shield {
|
||||
position: absolute;
|
||||
top: 50%; left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
width: 32px; height: 32px;
|
||||
background: var(--color-state-success);
|
||||
color: #fff;
|
||||
border-radius: 50%;
|
||||
display: flex; align-items: center; justify-content: center;
|
||||
border: 3px solid var(--color-surface);
|
||||
font-size: 16px;
|
||||
}
|
||||
.tfa-arrow--mitigated .tfa-arrow__line {
|
||||
background: repeating-linear-gradient(90deg, var(--color-state-success) 0 4px, transparent 4px 8px);
|
||||
}
|
||||
|
||||
@media (max-width: 720px) {
|
||||
.tfa-flow {
|
||||
grid-template-columns: 1fr;
|
||||
grid-template-rows: auto auto auto auto auto;
|
||||
}
|
||||
.tfa-arrow { min-height: 48px; min-width: auto; }
|
||||
.tfa-arrow__line { width: 4px; height: 100%; }
|
||||
.tfa-arrow[data-severity="medium"] .tfa-arrow__line { width: 6px; height: 100%; }
|
||||
.tfa-arrow[data-severity="high"] .tfa-arrow__line { width: 8px; height: 100%; }
|
||||
.tfa-arrow[data-severity="critical"] .tfa-arrow__line { width: 10px; height: 100%; }
|
||||
.tfa-arrow__line::after {
|
||||
right: 50%; top: auto; bottom: -1px; transform: translateX(50%);
|
||||
border-left: 8px solid transparent;
|
||||
border-right: 8px solid transparent;
|
||||
border-top: 10px solid currentColor;
|
||||
border-bottom: none;
|
||||
}
|
||||
}
|
||||
|
||||
/* =========================================================================
|
||||
2. Fleet-Overview (.fleet-grid, .fleet-tile)
|
||||
========================================================================= */
|
||||
.fleet-toolbar {
|
||||
display: flex; gap: var(--space-3); flex-wrap: wrap;
|
||||
align-items: center;
|
||||
padding: var(--space-3) var(--space-4);
|
||||
background: var(--color-bg-soft);
|
||||
border: 1px solid var(--color-border-subtle);
|
||||
border-radius: var(--radius-md);
|
||||
margin-bottom: var(--space-3);
|
||||
}
|
||||
.fleet-toolbar__label { font-size: 11px; text-transform: uppercase; letter-spacing: 0.06em; color: var(--color-text-tertiary); font-weight: var(--font-weight-semibold); }
|
||||
.fleet-toolbar__spacer { flex: 1; }
|
||||
.fleet-toolbar__count { font-size: var(--font-size-sm); color: var(--color-text-secondary); }
|
||||
|
||||
.fleet-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(4, 1fr);
|
||||
gap: var(--space-3);
|
||||
}
|
||||
@media (max-width: 980px) { .fleet-grid { grid-template-columns: repeat(2, 1fr); } }
|
||||
@media (max-width: 540px) { .fleet-grid { grid-template-columns: 1fr; } }
|
||||
|
||||
.fleet-tile {
|
||||
background: var(--color-surface);
|
||||
border: 1px solid var(--color-border-subtle);
|
||||
border-radius: var(--radius-md);
|
||||
padding: var(--space-3);
|
||||
display: grid;
|
||||
grid-template-rows: auto auto auto auto;
|
||||
gap: 6px;
|
||||
cursor: pointer;
|
||||
transition: border-color var(--duration-fast), transform var(--duration-fast);
|
||||
}
|
||||
.fleet-tile:hover { border-color: var(--color-primary-300); transform: translateY(-1px); }
|
||||
.fleet-tile:focus-visible { outline: none; box-shadow: var(--shadow-focus); }
|
||||
|
||||
.fleet-tile__row { display: flex; justify-content: space-between; align-items: center; gap: 8px; }
|
||||
.fleet-tile__name {
|
||||
font-family: var(--font-family-mono);
|
||||
font-size: 12px;
|
||||
color: var(--color-text-primary);
|
||||
white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
|
||||
flex: 1;
|
||||
}
|
||||
.fleet-tile__grade {
|
||||
width: 28px; height: 28px;
|
||||
display: flex; align-items: center; justify-content: center;
|
||||
font-weight: var(--font-weight-bold);
|
||||
font-size: 13px;
|
||||
border-radius: var(--radius-sm);
|
||||
color: #fff;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.fleet-tile__grade[data-grade="A"] { background: var(--color-state-success); }
|
||||
.fleet-tile__grade[data-grade="B"] { background: #4D8E2F; }
|
||||
.fleet-tile__grade[data-grade="C"] { background: var(--color-severity-medium); }
|
||||
.fleet-tile__grade[data-grade="D"] { background: var(--color-severity-high); }
|
||||
.fleet-tile__grade[data-grade="E"] { background: var(--color-severity-critical); }
|
||||
.fleet-tile__grade[data-grade="F"] { background: var(--color-severity-extreme); }
|
||||
|
||||
.fleet-tile__meter {
|
||||
height: 6px; border-radius: 3px;
|
||||
background: var(--color-bg-soft);
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
}
|
||||
.fleet-tile__meter-fill { height: 100%; border-radius: 3px; }
|
||||
.fleet-tile__meter-fill[data-band="1"] { background: var(--color-state-success); }
|
||||
.fleet-tile__meter-fill[data-band="2"] { background: var(--color-severity-medium); }
|
||||
.fleet-tile__meter-fill[data-band="3"] { background: var(--color-severity-high); }
|
||||
.fleet-tile__meter-fill[data-band="4"] { background: var(--color-severity-critical); }
|
||||
|
||||
.fleet-tile__chip {
|
||||
display: inline-flex; align-items: center;
|
||||
font-size: 11px;
|
||||
padding: 2px 8px;
|
||||
border-radius: var(--radius-pill);
|
||||
background: var(--color-bg-soft);
|
||||
color: var(--color-text-secondary);
|
||||
border: 1px solid var(--color-border-subtle);
|
||||
width: fit-content;
|
||||
}
|
||||
.fleet-tile__meta {
|
||||
display: flex; justify-content: space-between;
|
||||
font-size: 11px; color: var(--color-text-tertiary);
|
||||
font-family: var(--font-family-mono);
|
||||
}
|
||||
.fleet-tile__trend--better { color: var(--color-state-success); }
|
||||
.fleet-tile__trend--worse { color: var(--color-severity-critical); }
|
||||
.fleet-tile__trend--stable { color: var(--color-text-tertiary); }
|
||||
|
||||
/* =========================================================================
|
||||
3. Kanban Keep / Review / Remove (.kanban-board)
|
||||
========================================================================= */
|
||||
.kanban-board {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
gap: var(--space-4);
|
||||
}
|
||||
@media (max-width: 820px) { .kanban-board { grid-template-columns: 1fr; } }
|
||||
|
||||
.kanban-col {
|
||||
background: var(--color-bg-soft);
|
||||
border: 1px solid var(--color-border-subtle);
|
||||
border-radius: var(--radius-md);
|
||||
padding: var(--space-3);
|
||||
display: flex; flex-direction: column; gap: var(--space-3);
|
||||
min-height: 320px;
|
||||
}
|
||||
.kanban-col__head {
|
||||
display: flex; align-items: center; justify-content: space-between;
|
||||
padding-bottom: var(--space-2);
|
||||
border-bottom: 2px solid var(--color-border-subtle);
|
||||
}
|
||||
.kanban-col[data-bucket="keep"] .kanban-col__head { border-bottom-color: var(--color-state-success); }
|
||||
.kanban-col[data-bucket="review"] .kanban-col__head { border-bottom-color: var(--color-state-warning); }
|
||||
.kanban-col[data-bucket="remove"] .kanban-col__head { border-bottom-color: var(--color-severity-critical); }
|
||||
|
||||
.kanban-col__title { font-size: var(--font-size-md); font-weight: var(--font-weight-semibold); color: var(--color-text-primary); }
|
||||
.kanban-col__count {
|
||||
font-family: var(--font-family-mono);
|
||||
font-size: 12px;
|
||||
background: var(--color-surface);
|
||||
padding: 2px 8px;
|
||||
border-radius: var(--radius-pill);
|
||||
color: var(--color-text-secondary);
|
||||
border: 1px solid var(--color-border-subtle);
|
||||
}
|
||||
|
||||
.kanban-card {
|
||||
background: var(--color-surface);
|
||||
border: 1px solid var(--color-border-subtle);
|
||||
border-radius: var(--radius-md);
|
||||
padding: var(--space-3);
|
||||
cursor: grab;
|
||||
display: flex; flex-direction: column; gap: 6px;
|
||||
transition: box-shadow var(--duration-fast);
|
||||
}
|
||||
.kanban-card:hover { box-shadow: var(--shadow-md); }
|
||||
.kanban-card[data-verdict="BLOCK"] { border-color: var(--color-severity-critical); border-left-width: 4px; }
|
||||
.kanban-card[data-verdict="trusted"] { border-left: 4px solid var(--color-state-success); }
|
||||
.kanban-card[data-verdict="unknown"] { border-left: 4px solid var(--color-state-warning); }
|
||||
|
||||
.kanban-card__name { font-family: var(--font-family-mono); font-size: 13px; color: var(--color-text-primary); word-break: break-all; }
|
||||
.kanban-card__meta { font-size: 11px; color: var(--color-text-tertiary); }
|
||||
.kanban-card__reason { font-size: 12px; color: var(--color-text-secondary); }
|
||||
|
||||
.kanban-col__empty {
|
||||
margin: auto;
|
||||
text-align: center;
|
||||
color: var(--color-text-tertiary);
|
||||
font-size: var(--font-size-sm);
|
||||
padding: var(--space-4);
|
||||
}
|
||||
.kanban-col__empty button { margin-top: var(--space-2); }
|
||||
|
||||
.kanban-actions { display: flex; gap: 4px; margin-top: 4px; }
|
||||
.kanban-actions button {
|
||||
flex: 1; font-size: 11px; padding: 4px 6px;
|
||||
background: var(--color-bg-soft); border: 1px solid var(--color-border-subtle);
|
||||
border-radius: var(--radius-sm); color: var(--color-text-secondary);
|
||||
cursor: pointer; font-family: inherit;
|
||||
}
|
||||
.kanban-actions button:hover { background: var(--color-surface-sunken); color: var(--color-text-primary); }
|
||||
|
||||
/* =========================================================================
|
||||
4. Maturity-Ladder (.mat-ladder)
|
||||
========================================================================= */
|
||||
.mat-ladder {
|
||||
display: flex; flex-direction: column;
|
||||
background: var(--color-surface);
|
||||
border: 1px solid var(--color-border-subtle);
|
||||
border-radius: var(--radius-md);
|
||||
padding: var(--space-4);
|
||||
gap: 0;
|
||||
}
|
||||
.mat-step {
|
||||
display: grid;
|
||||
grid-template-columns: 56px 1fr;
|
||||
gap: var(--space-4);
|
||||
padding: var(--space-3) 0;
|
||||
position: relative;
|
||||
}
|
||||
.mat-step + .mat-step { border-top: 1px dashed var(--color-border-subtle); }
|
||||
|
||||
.mat-step__icon {
|
||||
width: 44px; height: 44px;
|
||||
border-radius: 50%;
|
||||
display: flex; align-items: center; justify-content: center;
|
||||
background: var(--color-surface);
|
||||
border: 2px solid var(--color-border-moderate);
|
||||
color: var(--color-text-tertiary);
|
||||
font-weight: var(--font-weight-semibold);
|
||||
font-size: 15px;
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
}
|
||||
.mat-step[data-state="completed"] .mat-step__icon {
|
||||
background: var(--color-state-success);
|
||||
border-color: var(--color-state-success);
|
||||
color: #fff;
|
||||
}
|
||||
.mat-step[data-state="current"] .mat-step__icon {
|
||||
border-color: var(--color-primary-500);
|
||||
color: var(--color-primary-700);
|
||||
background: var(--color-surface);
|
||||
}
|
||||
|
||||
/* progress ring around current step */
|
||||
.mat-step__ring {
|
||||
position: absolute;
|
||||
inset: -4px;
|
||||
border-radius: 50%;
|
||||
pointer-events: none;
|
||||
}
|
||||
.mat-step__ring svg { width: 100%; height: 100%; transform: rotate(-90deg); }
|
||||
.mat-step__ring circle { fill: none; stroke-width: 3; }
|
||||
.mat-step__ring .ring-bg { stroke: var(--color-border-subtle); }
|
||||
.mat-step__ring .ring-fill { stroke: var(--color-primary-500); }
|
||||
|
||||
.mat-step__name {
|
||||
font-size: var(--font-size-md);
|
||||
font-weight: var(--font-weight-semibold);
|
||||
color: var(--color-text-primary);
|
||||
display: flex; align-items: center; gap: 8px;
|
||||
}
|
||||
.mat-step[data-state="completed"] .mat-step__name { color: var(--color-text-secondary); }
|
||||
.mat-step[data-state="future"] .mat-step__name { color: var(--color-text-tertiary); }
|
||||
|
||||
.mat-step__pill {
|
||||
font-size: 11px; padding: 2px 8px; border-radius: var(--radius-pill);
|
||||
text-transform: uppercase; letter-spacing: 0.06em; font-weight: var(--font-weight-semibold);
|
||||
}
|
||||
.mat-step__pill--current { background: var(--color-primary-100); color: var(--color-primary-700); }
|
||||
.mat-step__pill--complete { background: transparent; color: var(--color-state-success); border: 1px solid currentColor; }
|
||||
|
||||
.mat-step__desc {
|
||||
font-size: var(--font-size-sm);
|
||||
color: var(--color-text-secondary);
|
||||
margin-top: 2px;
|
||||
max-width: 60ch;
|
||||
}
|
||||
|
||||
.mat-step__progress {
|
||||
margin-top: 6px;
|
||||
display: flex; align-items: center; gap: 8px;
|
||||
font-size: 12px; color: var(--color-text-tertiary);
|
||||
}
|
||||
.mat-step__progress-bar {
|
||||
flex: 1; height: 4px;
|
||||
background: var(--color-bg-soft);
|
||||
border-radius: 2px;
|
||||
overflow: hidden;
|
||||
max-width: 200px;
|
||||
}
|
||||
.mat-step__progress-fill { height: 100%; background: var(--color-primary-500); border-radius: 2px; }
|
||||
|
||||
/* =========================================================================
|
||||
5. Classify-and-Transform / 5-Bucket-Sorter (.cls-sorter)
|
||||
========================================================================= */
|
||||
.cls-sorter { display: flex; flex-direction: column; gap: var(--space-4); }
|
||||
|
||||
.cls-input {
|
||||
background: var(--color-surface);
|
||||
border: 1px solid var(--color-border-subtle);
|
||||
border-radius: var(--radius-md);
|
||||
padding: var(--space-3);
|
||||
}
|
||||
.cls-input textarea {
|
||||
width: 100%; min-height: 100px;
|
||||
font-family: var(--font-family-sans);
|
||||
font-size: var(--font-size-sm);
|
||||
border: 1px solid var(--color-border-subtle);
|
||||
border-radius: var(--radius-sm);
|
||||
padding: var(--space-2) var(--space-3);
|
||||
background: var(--color-bg);
|
||||
color: var(--color-text-primary);
|
||||
resize: vertical;
|
||||
}
|
||||
.cls-input textarea:focus { outline: none; box-shadow: var(--shadow-focus); border-color: var(--color-border-focus); }
|
||||
|
||||
.cls-buckets {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(5, 1fr);
|
||||
gap: var(--space-3);
|
||||
}
|
||||
@media (max-width: 1100px) { .cls-buckets { grid-template-columns: repeat(3, 1fr); } }
|
||||
@media (max-width: 720px) { .cls-buckets { grid-template-columns: repeat(2, 1fr); } }
|
||||
@media (max-width: 460px) { .cls-buckets { grid-template-columns: 1fr; } }
|
||||
|
||||
.cls-bucket {
|
||||
background: var(--color-surface);
|
||||
border: 1px solid var(--color-border-subtle);
|
||||
border-top-width: 4px;
|
||||
border-radius: var(--radius-md);
|
||||
padding: var(--space-3);
|
||||
display: flex; flex-direction: column; gap: var(--space-2);
|
||||
min-height: 200px;
|
||||
}
|
||||
.cls-bucket[data-egnethet="lav"] { border-top-color: var(--color-text-tertiary); }
|
||||
.cls-bucket[data-egnethet="medium"] { border-top-color: var(--color-state-info); }
|
||||
.cls-bucket[data-egnethet="hoy"] { border-top-color: var(--color-state-success); }
|
||||
|
||||
.cls-bucket__head {
|
||||
display: flex; flex-direction: column; gap: 2px;
|
||||
padding-bottom: var(--space-2);
|
||||
border-bottom: 1px solid var(--color-border-subtle);
|
||||
}
|
||||
.cls-bucket__title { font-size: var(--font-size-sm); font-weight: var(--font-weight-semibold); color: var(--color-text-primary); }
|
||||
.cls-bucket__egnethet {
|
||||
font-size: 10px; text-transform: uppercase; letter-spacing: 0.08em;
|
||||
color: var(--color-text-tertiary); font-weight: var(--font-weight-semibold);
|
||||
}
|
||||
.cls-bucket[data-egnethet="lav"] .cls-bucket__egnethet { color: var(--color-text-tertiary); }
|
||||
.cls-bucket[data-egnethet="medium"] .cls-bucket__egnethet { color: var(--color-state-info); }
|
||||
.cls-bucket[data-egnethet="hoy"] .cls-bucket__egnethet { color: var(--color-state-success); }
|
||||
|
||||
.cls-item {
|
||||
background: var(--color-bg-soft);
|
||||
border: 1px solid var(--color-border-subtle);
|
||||
border-radius: var(--radius-sm);
|
||||
padding: 6px 8px;
|
||||
font-size: 12px;
|
||||
color: var(--color-text-primary);
|
||||
cursor: grab;
|
||||
display: flex; flex-direction: column; gap: 2px;
|
||||
}
|
||||
.cls-item__action {
|
||||
font-size: 10px; text-transform: uppercase; letter-spacing: 0.06em;
|
||||
color: var(--color-text-tertiary); font-weight: var(--font-weight-medium);
|
||||
}
|
||||
.cls-bucket__action {
|
||||
margin-top: auto;
|
||||
padding-top: var(--space-2);
|
||||
border-top: 1px dashed var(--color-border-subtle);
|
||||
}
|
||||
.cls-bucket__empty {
|
||||
font-size: 12px; color: var(--color-text-tertiary);
|
||||
font-style: italic;
|
||||
text-align: center;
|
||||
padding: var(--space-3);
|
||||
}
|
||||
|
||||
/* =========================================================================
|
||||
6. Cycle Position Ribbon (.cycle-ribbon)
|
||||
========================================================================= */
|
||||
.cycle-ribbon {
|
||||
position: relative;
|
||||
background: var(--color-surface);
|
||||
border-bottom: 1px solid var(--color-border-subtle);
|
||||
padding: 8px var(--space-5);
|
||||
display: flex; align-items: center; gap: var(--space-4);
|
||||
font-size: 13px;
|
||||
cursor: pointer;
|
||||
overflow: hidden;
|
||||
}
|
||||
.cycle-ribbon::before {
|
||||
content: ""; position: absolute; inset: 0;
|
||||
background: var(--color-state-info);
|
||||
opacity: 0.06;
|
||||
width: var(--cycle-progress, 0%);
|
||||
transition: width var(--duration-normal);
|
||||
}
|
||||
.cycle-ribbon[data-phase="planning"] { border-bottom-color: var(--color-state-info); }
|
||||
.cycle-ribbon[data-phase="planning"]::before { background: var(--color-state-info); }
|
||||
.cycle-ribbon[data-phase="execution"] { border-bottom-color: var(--color-state-success); }
|
||||
.cycle-ribbon[data-phase="execution"]::before { background: var(--color-state-success); }
|
||||
.cycle-ribbon[data-phase="retrospective_prep"] { border-bottom-color: var(--color-severity-medium); }
|
||||
.cycle-ribbon[data-phase="retrospective_prep"]::before { background: var(--color-severity-medium); }
|
||||
|
||||
.cycle-ribbon > * { position: relative; z-index: 1; }
|
||||
.cycle-ribbon__id { font-family: var(--font-family-mono); font-weight: var(--font-weight-semibold); color: var(--color-text-primary); white-space: nowrap; flex-shrink: 0; }
|
||||
.cycle-ribbon__week { color: var(--color-text-secondary); font-family: var(--font-family-mono); white-space: nowrap; flex-shrink: 0; }
|
||||
.cycle-ribbon__phase {
|
||||
font-size: 11px; padding: 2px 8px;
|
||||
border-radius: var(--radius-pill);
|
||||
text-transform: uppercase; letter-spacing: 0.06em;
|
||||
font-weight: var(--font-weight-semibold);
|
||||
white-space: nowrap; flex-shrink: 0;
|
||||
}
|
||||
.cycle-ribbon[data-phase="planning"] .cycle-ribbon__phase { background: var(--color-primary-100); color: var(--color-primary-700); }
|
||||
.cycle-ribbon[data-phase="execution"] .cycle-ribbon__phase { background: var(--color-severity-low-soft); color: var(--color-severity-low-on); }
|
||||
.cycle-ribbon[data-phase="retrospective_prep"] .cycle-ribbon__phase { background: var(--color-severity-medium-soft); color: var(--color-severity-medium-on); }
|
||||
.cycle-ribbon__msg { color: var(--color-text-secondary); flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
||||
.cycle-ribbon__chev { color: var(--color-text-tertiary); transition: transform var(--duration-fast); }
|
||||
.cycle-ribbon[aria-expanded="true"] .cycle-ribbon__chev { transform: rotate(180deg); }
|
||||
|
||||
.cycle-ribbon__panel {
|
||||
background: var(--color-bg-soft);
|
||||
border-bottom: 1px solid var(--color-border-subtle);
|
||||
padding: var(--space-4) var(--space-5);
|
||||
display: none;
|
||||
font-size: var(--font-size-sm);
|
||||
}
|
||||
.cycle-ribbon__panel[data-open="true"] { display: block; }
|
||||
|
||||
@media (max-width: 720px) {
|
||||
.cycle-ribbon__msg { display: none; }
|
||||
}
|
||||
|
||||
/* =========================================================================
|
||||
7. Persistent-Antipattern Badge (.pap-badge)
|
||||
========================================================================= */
|
||||
.pap-badge {
|
||||
display: inline-flex; align-items: center; gap: 6px;
|
||||
padding: 4px 10px;
|
||||
background: var(--color-surface);
|
||||
border: 1px solid var(--color-severity-critical);
|
||||
border-radius: var(--radius-pill);
|
||||
font-size: 12px;
|
||||
font-weight: var(--font-weight-medium);
|
||||
color: var(--color-severity-critical);
|
||||
cursor: pointer;
|
||||
position: relative;
|
||||
}
|
||||
.pap-badge::before {
|
||||
content: "";
|
||||
width: 8px; height: 8px;
|
||||
border-radius: 50%;
|
||||
background: var(--color-severity-critical);
|
||||
animation: pap-pulse 2.4s var(--ease-default) infinite;
|
||||
}
|
||||
@keyframes pap-pulse {
|
||||
0%, 100% { opacity: 1; transform: scale(1); }
|
||||
50% { opacity: 0.45; transform: scale(0.7); }
|
||||
}
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
.pap-badge::before { animation: none; opacity: 1; }
|
||||
}
|
||||
.pap-badge__count { font-family: var(--font-family-mono); font-weight: var(--font-weight-semibold); }
|
||||
|
||||
.pap-detail {
|
||||
margin-top: var(--space-3);
|
||||
background: var(--color-surface);
|
||||
border: 1px solid var(--color-severity-critical);
|
||||
border-left-width: 4px;
|
||||
border-radius: var(--radius-md);
|
||||
padding: var(--space-4);
|
||||
display: none;
|
||||
}
|
||||
.pap-detail[data-open="true"] { display: block; }
|
||||
.pap-detail h4 { margin: 0 0 4px; color: var(--color-severity-critical); font-size: var(--font-size-md); }
|
||||
.pap-detail__cycles { display: flex; gap: 4px; flex-wrap: wrap; margin: var(--space-2) 0; }
|
||||
.pap-detail__cycle {
|
||||
font-family: var(--font-family-mono);
|
||||
font-size: 11px;
|
||||
padding: 2px 6px;
|
||||
background: var(--color-bg-soft);
|
||||
border-radius: var(--radius-sm);
|
||||
color: var(--color-text-secondary);
|
||||
}
|
||||
.pap-detail__rec {
|
||||
background: var(--color-bg-soft);
|
||||
border-radius: var(--radius-sm);
|
||||
padding: var(--space-2) var(--space-3);
|
||||
margin-top: var(--space-2);
|
||||
font-size: var(--font-size-sm);
|
||||
color: var(--color-text-primary);
|
||||
}
|
||||
|
||||
/* one-shot variant */
|
||||
.pap-badge--oneshot {
|
||||
border-style: dashed;
|
||||
border-color: var(--color-severity-medium);
|
||||
color: var(--color-severity-medium);
|
||||
}
|
||||
.pap-badge--oneshot::before { display: none; }
|
||||
|
||||
/* =========================================================================
|
||||
8. Suppressed-Signals Panel (.suppressed)
|
||||
========================================================================= */
|
||||
.suppressed {
|
||||
background: var(--color-bg-soft);
|
||||
border: 1px solid var(--color-border-subtle);
|
||||
border-radius: var(--radius-md);
|
||||
overflow: hidden;
|
||||
}
|
||||
.suppressed__head {
|
||||
width: 100%;
|
||||
display: flex; align-items: center; gap: var(--space-3);
|
||||
padding: var(--space-3) var(--space-4);
|
||||
background: transparent;
|
||||
border: 0;
|
||||
cursor: pointer;
|
||||
font-family: inherit;
|
||||
text-align: left;
|
||||
color: var(--color-text-secondary);
|
||||
}
|
||||
.suppressed__head:hover { background: var(--color-surface-sunken); color: var(--color-text-primary); }
|
||||
.suppressed__head:focus-visible { outline: none; box-shadow: var(--shadow-focus); }
|
||||
.suppressed__chev { color: var(--color-text-tertiary); transition: transform var(--duration-fast); }
|
||||
.suppressed[aria-expanded="true"] .suppressed__chev { transform: rotate(90deg); }
|
||||
.suppressed__label { font-size: var(--font-size-sm); }
|
||||
.suppressed__count {
|
||||
font-family: var(--font-family-mono);
|
||||
font-size: 12px;
|
||||
background: var(--color-surface);
|
||||
padding: 2px 8px;
|
||||
border-radius: var(--radius-pill);
|
||||
color: var(--color-text-secondary);
|
||||
border: 1px solid var(--color-border-subtle);
|
||||
margin-left: auto;
|
||||
}
|
||||
|
||||
.suppressed__body {
|
||||
display: none;
|
||||
padding: 0 var(--space-4) var(--space-4);
|
||||
}
|
||||
.suppressed[aria-expanded="true"] .suppressed__body { display: block; }
|
||||
|
||||
.suppressed-group {
|
||||
background: var(--color-surface);
|
||||
border: 1px solid var(--color-border-subtle);
|
||||
border-radius: var(--radius-sm);
|
||||
padding: var(--space-3);
|
||||
}
|
||||
.suppressed-group + .suppressed-group { margin-top: var(--space-2); }
|
||||
.suppressed-group__head {
|
||||
display: flex; justify-content: space-between; align-items: center; gap: 8px;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
.suppressed-group__reason { font-family: var(--font-family-mono); font-size: 12px; color: var(--color-text-tertiary); }
|
||||
.suppressed-group__count { font-size: 11px; color: var(--color-text-tertiary); }
|
||||
.suppressed-group__desc { font-size: var(--font-size-sm); color: var(--color-text-secondary); margin: 0 0 6px; }
|
||||
.suppressed-group__examples {
|
||||
display: flex; gap: 4px; flex-wrap: wrap;
|
||||
}
|
||||
.suppressed-group__example {
|
||||
font-family: var(--font-family-mono);
|
||||
font-size: 11px;
|
||||
background: var(--color-bg-soft);
|
||||
padding: 2px 6px;
|
||||
border-radius: var(--radius-sm);
|
||||
color: var(--color-text-secondary);
|
||||
}
|
||||
|
||||
/* =========================================================================
|
||||
9. ExpansionCard (Aksel) (.expansion)
|
||||
========================================================================= */
|
||||
.expansion {
|
||||
background: var(--color-surface);
|
||||
border: 1px solid var(--color-border-subtle);
|
||||
border-radius: var(--radius-md);
|
||||
overflow: hidden;
|
||||
}
|
||||
.expansion + .expansion { margin-top: var(--space-2); }
|
||||
.expansion__head {
|
||||
width: 100%;
|
||||
display: flex; align-items: flex-start; gap: var(--space-3);
|
||||
padding: var(--space-3) var(--space-4);
|
||||
background: transparent;
|
||||
border: 0;
|
||||
cursor: pointer;
|
||||
font-family: inherit;
|
||||
text-align: left;
|
||||
}
|
||||
.expansion__head:hover { background: var(--color-bg-soft); }
|
||||
.expansion__head:focus-visible { outline: none; box-shadow: var(--shadow-focus); }
|
||||
.expansion__title { flex: 1; }
|
||||
.expansion__title-main { font-size: var(--font-size-md); color: var(--color-text-primary); font-weight: var(--font-weight-medium); }
|
||||
.expansion__title-sub { font-size: var(--font-size-sm); color: var(--color-text-secondary); margin-top: 2px; }
|
||||
.expansion__chev {
|
||||
color: var(--color-text-tertiary);
|
||||
transition: transform var(--duration-normal) var(--ease-default);
|
||||
flex-shrink: 0;
|
||||
margin-top: 2px;
|
||||
}
|
||||
.expansion[aria-expanded="true"] .expansion__chev { transform: rotate(180deg); }
|
||||
|
||||
.expansion__body {
|
||||
display: grid;
|
||||
grid-template-rows: 0fr;
|
||||
transition: grid-template-rows var(--duration-normal) var(--ease-default);
|
||||
}
|
||||
.expansion[aria-expanded="true"] .expansion__body { grid-template-rows: 1fr; }
|
||||
.expansion__body-inner { overflow: hidden; }
|
||||
.expansion__body-inner > div {
|
||||
padding: 0 var(--space-4) var(--space-4);
|
||||
border-top: 1px solid var(--color-border-subtle);
|
||||
padding-top: var(--space-3);
|
||||
margin-top: -1px;
|
||||
}
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
.expansion__body { transition: none; }
|
||||
}
|
||||
|
||||
/* =========================================================================
|
||||
10. ReadMore (Aksel) (.read-more)
|
||||
========================================================================= */
|
||||
.read-more {
|
||||
display: inline;
|
||||
}
|
||||
.read-more__trigger {
|
||||
display: inline-flex; align-items: center; gap: 4px;
|
||||
background: transparent;
|
||||
border: 0;
|
||||
color: var(--color-text-link);
|
||||
font-family: inherit;
|
||||
font-size: inherit;
|
||||
font-weight: var(--font-weight-medium);
|
||||
cursor: pointer;
|
||||
padding: 0;
|
||||
text-decoration: underline;
|
||||
text-decoration-thickness: 1px;
|
||||
text-underline-offset: 3px;
|
||||
}
|
||||
.read-more__trigger:hover { color: var(--color-text-link-hover); }
|
||||
.read-more__trigger:focus-visible { outline: none; box-shadow: var(--shadow-focus); border-radius: 2px; }
|
||||
.read-more__chev { transition: transform var(--duration-fast); }
|
||||
.read-more[aria-expanded="true"] .read-more__chev { transform: rotate(180deg); }
|
||||
.read-more__body { display: none; margin-top: var(--space-2); }
|
||||
.read-more[aria-expanded="true"] .read-more__body { display: block; }
|
||||
|
||||
/* =========================================================================
|
||||
11. FormProgress (Aksel multi-step skjema) (.form-progress)
|
||||
========================================================================= */
|
||||
.form-progress {
|
||||
background: var(--color-surface);
|
||||
border: 1px solid var(--color-border-subtle);
|
||||
border-radius: var(--radius-md);
|
||||
padding: var(--space-4);
|
||||
display: flex; flex-direction: column; gap: var(--space-3);
|
||||
width: 280px;
|
||||
position: sticky;
|
||||
top: var(--space-4);
|
||||
}
|
||||
.form-progress__autosave {
|
||||
display: flex; align-items: center; gap: 6px;
|
||||
font-size: 12px;
|
||||
color: var(--color-text-tertiary);
|
||||
padding-bottom: var(--space-2);
|
||||
border-bottom: 1px solid var(--color-border-subtle);
|
||||
}
|
||||
.form-progress__autosave-dot {
|
||||
width: 6px; height: 6px;
|
||||
border-radius: 50%;
|
||||
background: var(--color-state-success);
|
||||
}
|
||||
.form-progress__steps { display: flex; flex-direction: column; gap: 2px; }
|
||||
.fp-step {
|
||||
display: grid;
|
||||
grid-template-columns: 28px 1fr;
|
||||
gap: var(--space-2);
|
||||
align-items: start;
|
||||
padding: 8px;
|
||||
border-radius: var(--radius-sm);
|
||||
text-align: left;
|
||||
background: transparent;
|
||||
border: 0;
|
||||
cursor: pointer;
|
||||
font-family: inherit;
|
||||
position: relative;
|
||||
}
|
||||
.fp-step:hover { background: var(--color-bg-soft); }
|
||||
.fp-step:focus-visible { outline: none; box-shadow: var(--shadow-focus); }
|
||||
.fp-step[disabled] { cursor: not-allowed; opacity: 0.5; }
|
||||
|
||||
.fp-step__num {
|
||||
width: 22px; height: 22px;
|
||||
border-radius: 50%;
|
||||
display: flex; align-items: center; justify-content: center;
|
||||
background: var(--color-surface);
|
||||
border: 1.5px solid var(--color-border-moderate);
|
||||
color: var(--color-text-tertiary);
|
||||
font-size: 11px;
|
||||
font-weight: var(--font-weight-semibold);
|
||||
}
|
||||
.fp-step[data-state="done"] .fp-step__num {
|
||||
background: var(--color-state-success);
|
||||
border-color: var(--color-state-success);
|
||||
color: #fff;
|
||||
}
|
||||
.fp-step[data-state="in-progress"] .fp-step__num {
|
||||
border-color: var(--color-primary-500);
|
||||
color: var(--color-primary-700);
|
||||
font-weight: var(--font-weight-bold);
|
||||
}
|
||||
.fp-step__name { font-size: var(--font-size-sm); color: var(--color-text-primary); font-weight: var(--font-weight-medium); }
|
||||
.fp-step[data-state="done"] .fp-step__name { color: var(--color-text-secondary); font-weight: var(--font-weight-regular); }
|
||||
.fp-step[data-state="in-progress"] .fp-step__name { color: var(--color-primary-700); font-weight: var(--font-weight-semibold); }
|
||||
|
||||
.fp-step__progress {
|
||||
margin-top: 4px;
|
||||
font-size: 11px;
|
||||
color: var(--color-text-tertiary);
|
||||
display: flex; align-items: center; gap: 6px;
|
||||
}
|
||||
.fp-step__bar {
|
||||
flex: 1; height: 3px;
|
||||
background: var(--color-bg-soft);
|
||||
border-radius: 2px; overflow: hidden;
|
||||
max-width: 80px;
|
||||
}
|
||||
.fp-step__bar-fill { height: 100%; background: var(--color-primary-500); }
|
||||
|
||||
.form-progress__remaining {
|
||||
padding-top: var(--space-2);
|
||||
border-top: 1px solid var(--color-border-subtle);
|
||||
font-size: 12px; color: var(--color-text-tertiary);
|
||||
display: flex; justify-content: space-between;
|
||||
}
|
||||
|
||||
/* =========================================================================
|
||||
12. Aspirational vs Committed Visual (.okr-mode)
|
||||
Modifier added to OKR Objective cards
|
||||
========================================================================= */
|
||||
.okr-mode {
|
||||
position: relative;
|
||||
background: var(--color-surface);
|
||||
border: 1px solid var(--color-border-subtle);
|
||||
border-radius: var(--radius-md);
|
||||
padding: var(--space-4);
|
||||
}
|
||||
.okr-mode__gauge {
|
||||
position: relative;
|
||||
width: 88px; height: 88px;
|
||||
display: flex; align-items: center; justify-content: center;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.okr-mode__gauge svg { position: absolute; inset: 0; transform: rotate(-90deg); width: 100%; height: 100%; }
|
||||
.okr-mode__gauge circle.gauge-bg { fill: none; stroke: var(--color-border-subtle); stroke-width: 6; }
|
||||
.okr-mode__gauge circle.gauge-fill { fill: none; stroke: var(--color-state-success); stroke-width: 6; stroke-linecap: round; }
|
||||
.okr-mode__gauge .gauge-value { font-family: var(--font-family-mono); font-size: 22px; font-weight: var(--font-weight-bold); color: var(--color-text-primary); position: relative; z-index: 1; }
|
||||
|
||||
/* aspirational variant — dashed stroke */
|
||||
.okr-mode[data-mode="aspirational"] .okr-mode__gauge circle.gauge-fill {
|
||||
stroke: var(--color-scope-okr);
|
||||
stroke-dasharray: 6 4;
|
||||
}
|
||||
.okr-mode__badge {
|
||||
position: absolute;
|
||||
top: var(--space-2); right: var(--space-2);
|
||||
font-size: 10px; font-weight: var(--font-weight-bold); letter-spacing: 0.08em;
|
||||
padding: 2px 8px;
|
||||
border-radius: var(--radius-sm);
|
||||
}
|
||||
.okr-mode[data-mode="aspirational"] .okr-mode__badge {
|
||||
background: transparent;
|
||||
color: var(--color-scope-okr);
|
||||
border: 1px dashed var(--color-scope-okr);
|
||||
}
|
||||
.okr-mode[data-mode="committed"] .okr-mode__badge {
|
||||
background: var(--color-primary-700);
|
||||
color: #fff;
|
||||
}
|
||||
.okr-mode__row { display: flex; gap: var(--space-4); align-items: center; }
|
||||
.okr-mode__objective { font-size: var(--font-size-md); color: var(--color-text-primary); flex: 1; }
|
||||
.okr-mode__hint { font-size: 12px; color: var(--color-text-tertiary); margin-top: 4px; }
|
||||
717
plugins/ms-ai-architect/playground/vendor/playground-design-system/components-tier3.css
vendored
Normal file
717
plugins/ms-ai-architect/playground/vendor/playground-design-system/components-tier3.css
vendored
Normal file
|
|
@ -0,0 +1,717 @@
|
|||
/* Code generated by sync-design-system.mjs; DO NOT EDIT. */
|
||||
/* =============================================================================
|
||||
components-tier3.css — Tier 3 components (Phase 2)
|
||||
Critical components for ms-ai-architect Playground v3 + universal Aksel patterns.
|
||||
19. Inherent + residual pair (before/after matrix transition)
|
||||
20. AI Act compliance-tidslinje (4-milepel timeline + countdown)
|
||||
21. 3-track entry (Guide/Explore/Expert — carried from Playground v2)
|
||||
22. FRIA rights-matrix (12 EU Charter rights × impact level)
|
||||
23. Capability-matrix (license × kapabilitet — available/cost/missing/conditional)
|
||||
24. Parallel-agent-status panel (multi-worker status grid)
|
||||
25. ErrorSummary (Aksel/GOV.UK form error pattern)
|
||||
26. GuidePanel (Aksel friendly inline guidance)
|
||||
============================================================================= */
|
||||
|
||||
/* =============================================================================
|
||||
19. INHERENT + RESIDUAL PAIR
|
||||
Used by: ROS (before/after mitigation), DPIA, AI Act mitigations, OKR check-ins
|
||||
Pattern: two cells/scores side-by-side with arrow showing transition.
|
||||
============================================================================= */
|
||||
.pair-before-after {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr auto 1fr;
|
||||
gap: var(--space-4);
|
||||
align-items: center;
|
||||
}
|
||||
.pair-before-after__cell {
|
||||
background: var(--color-surface);
|
||||
border: 1px solid var(--color-border-subtle);
|
||||
border-radius: var(--radius-md);
|
||||
padding: var(--space-3) var(--space-4);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 4px;
|
||||
}
|
||||
.pair-before-after__cell-label {
|
||||
font-size: var(--font-size-xs);
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.06em;
|
||||
color: var(--color-text-tertiary);
|
||||
font-weight: var(--font-weight-semibold);
|
||||
}
|
||||
.pair-before-after__cell-value {
|
||||
font-size: var(--font-size-2xl);
|
||||
font-weight: var(--font-weight-bold);
|
||||
font-variant-numeric: tabular-nums;
|
||||
letter-spacing: -0.02em;
|
||||
line-height: 1;
|
||||
}
|
||||
.pair-before-after__cell-meta {
|
||||
font-size: var(--font-size-xs);
|
||||
color: var(--color-text-secondary);
|
||||
}
|
||||
.pair-before-after__cell--severity-low { border-left: 4px solid var(--color-severity-low); }
|
||||
.pair-before-after__cell--severity-medium { border-left: 4px solid var(--color-severity-medium); }
|
||||
.pair-before-after__cell--severity-high { border-left: 4px solid var(--color-severity-high); }
|
||||
.pair-before-after__cell--severity-critical { border-left: 4px solid var(--color-severity-critical); }
|
||||
.pair-before-after__cell--severity-extreme { border-left: 4px solid var(--color-severity-extreme); }
|
||||
|
||||
.pair-before-after__arrow {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: var(--font-size-2xl);
|
||||
color: var(--color-text-tertiary);
|
||||
line-height: 1;
|
||||
user-select: none;
|
||||
}
|
||||
.pair-before-after__arrow::before { content: "→"; font-family: var(--font-family-sans); }
|
||||
.pair-before-after__arrow--down::before { content: "↓"; }
|
||||
|
||||
.pair-before-after__delta {
|
||||
display: inline-flex;
|
||||
align-items: baseline;
|
||||
gap: 4px;
|
||||
font-family: var(--font-family-mono);
|
||||
font-size: var(--font-size-xs);
|
||||
padding: 2px 8px;
|
||||
border-radius: var(--radius-pill);
|
||||
margin-top: 2px;
|
||||
}
|
||||
.pair-before-after__delta--improved {
|
||||
background: var(--color-severity-low-soft);
|
||||
color: var(--color-severity-low-on);
|
||||
}
|
||||
.pair-before-after__delta--worsened {
|
||||
background: var(--color-severity-critical-soft);
|
||||
color: var(--color-severity-critical-on);
|
||||
}
|
||||
|
||||
@media (max-width: 640px) {
|
||||
.pair-before-after { grid-template-columns: 1fr; }
|
||||
.pair-before-after__arrow { transform: rotate(90deg); }
|
||||
}
|
||||
|
||||
/* =============================================================================
|
||||
20. AI ACT COMPLIANCE-TIDSLINJE
|
||||
Horizontal timeline with 4 fixed EU AI Act milestones (2025-02-02, 2025-08-02,
|
||||
2026-08-02, 2027-08-02) plus a "today" marker and per-system countdown chips.
|
||||
============================================================================= */
|
||||
.aiact-timeline {
|
||||
position: relative;
|
||||
padding: var(--space-8) 0 var(--space-4);
|
||||
margin: var(--space-4) 0;
|
||||
}
|
||||
.aiact-timeline__track {
|
||||
position: relative;
|
||||
height: 4px;
|
||||
background: var(--color-border-subtle);
|
||||
border-radius: var(--radius-pill);
|
||||
margin: 0 12px;
|
||||
}
|
||||
.aiact-timeline__progress {
|
||||
position: absolute;
|
||||
top: 0; bottom: 0; left: 0;
|
||||
background: var(--color-primary-500);
|
||||
border-radius: var(--radius-pill);
|
||||
/* width set inline based on today vs milestone span */
|
||||
}
|
||||
.aiact-timeline__milestone {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
/* left set inline as percentage based on date span */
|
||||
}
|
||||
.aiact-timeline__dot {
|
||||
width: 16px; height: 16px;
|
||||
border-radius: 50%;
|
||||
background: var(--color-surface);
|
||||
border: 3px solid var(--color-border-moderate);
|
||||
cursor: pointer;
|
||||
transition: transform var(--duration-fast) var(--ease-default),
|
||||
border-color var(--duration-fast) var(--ease-default);
|
||||
}
|
||||
.aiact-timeline__dot:hover { transform: scale(1.15); }
|
||||
.aiact-timeline__milestone[data-state="passed"] .aiact-timeline__dot {
|
||||
background: var(--color-primary-500);
|
||||
border-color: var(--color-primary-500);
|
||||
}
|
||||
.aiact-timeline__milestone[data-state="active"] .aiact-timeline__dot {
|
||||
background: var(--color-severity-critical);
|
||||
border-color: var(--color-severity-critical);
|
||||
box-shadow: 0 0 0 4px var(--color-severity-critical-soft);
|
||||
}
|
||||
.aiact-timeline__milestone[data-state="upcoming"] .aiact-timeline__dot {
|
||||
background: var(--color-surface);
|
||||
border-color: var(--color-border-strong);
|
||||
}
|
||||
|
||||
.aiact-timeline__today {
|
||||
position: absolute;
|
||||
top: -6px; bottom: -6px;
|
||||
width: 2px;
|
||||
background: var(--color-text-primary);
|
||||
/* left set inline based on current date */
|
||||
}
|
||||
.aiact-timeline__today::after {
|
||||
content: "I dag";
|
||||
position: absolute;
|
||||
top: -22px;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
font-size: 10px;
|
||||
font-family: var(--font-family-mono);
|
||||
font-weight: var(--font-weight-semibold);
|
||||
color: var(--color-text-primary);
|
||||
background: var(--color-bg);
|
||||
padding: 2px 6px;
|
||||
border-radius: var(--radius-sm);
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.aiact-timeline__label {
|
||||
position: absolute;
|
||||
top: 22px; left: 50%;
|
||||
transform: translateX(-50%);
|
||||
text-align: center;
|
||||
white-space: nowrap;
|
||||
font-size: 11px;
|
||||
font-family: var(--font-family-mono);
|
||||
color: var(--color-text-secondary);
|
||||
}
|
||||
.aiact-timeline__label-date { font-weight: var(--font-weight-semibold); display: block; }
|
||||
.aiact-timeline__label-name { color: var(--color-text-tertiary); display: block; margin-top: 1px; max-width: 140px; white-space: normal; line-height: 1.2; }
|
||||
|
||||
.aiact-countdown {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
padding: 4px 10px;
|
||||
font-size: var(--font-size-xs);
|
||||
font-family: var(--font-family-mono);
|
||||
border-radius: var(--radius-pill);
|
||||
background: var(--color-bg-soft);
|
||||
border: 1px solid var(--color-border-subtle);
|
||||
}
|
||||
.aiact-countdown__days {
|
||||
font-weight: var(--font-weight-bold);
|
||||
font-variant-numeric: tabular-nums;
|
||||
}
|
||||
.aiact-countdown[data-urgency="urgent"] { background: var(--color-severity-critical-soft); color: var(--color-severity-critical-on); border-color: transparent; }
|
||||
.aiact-countdown[data-urgency="soon"] { background: var(--color-severity-medium-soft); color: var(--color-severity-medium-on); border-color: transparent; }
|
||||
.aiact-countdown[data-urgency="distant"] { background: var(--color-severity-low-soft); color: var(--color-severity-low-on); border-color: transparent; }
|
||||
|
||||
/* =============================================================================
|
||||
21. 3-TRACK ENTRY (Guide / Explore / Expert)
|
||||
Carried forward from Playground v2 — the most-validated UX pattern in our
|
||||
fleet. Three large cards as the very first decision the user makes.
|
||||
============================================================================= */
|
||||
.tracks {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
gap: var(--space-5);
|
||||
margin: var(--space-8) 0;
|
||||
}
|
||||
.tracks__card {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: var(--space-3);
|
||||
padding: var(--space-6);
|
||||
background: var(--color-surface);
|
||||
border: 1px solid var(--color-border-subtle);
|
||||
border-radius: var(--radius-lg);
|
||||
cursor: pointer;
|
||||
transition: border-color var(--duration-fast) var(--ease-default),
|
||||
transform var(--duration-fast) var(--ease-default),
|
||||
box-shadow var(--duration-fast) var(--ease-default);
|
||||
text-decoration: none;
|
||||
color: inherit;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
.tracks__card::before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
top: 0; left: 0; right: 0;
|
||||
height: 4px;
|
||||
background: var(--color-border-moderate);
|
||||
transition: background var(--duration-fast) var(--ease-default);
|
||||
}
|
||||
.tracks__card:hover {
|
||||
border-color: var(--color-border-strong);
|
||||
transform: translateY(-2px);
|
||||
box-shadow: var(--shadow-md);
|
||||
}
|
||||
.tracks__card--guided::before { background: var(--color-state-success); }
|
||||
.tracks__card--explore::before { background: var(--color-primary-500); }
|
||||
.tracks__card--expert::before { background: var(--color-text-primary); }
|
||||
|
||||
.tracks__card-icon {
|
||||
width: 40px; height: 40px;
|
||||
border-radius: var(--radius-md);
|
||||
background: var(--color-bg-soft);
|
||||
display: flex; align-items: center; justify-content: center;
|
||||
color: var(--color-text-secondary);
|
||||
}
|
||||
.tracks__card-title {
|
||||
font-size: var(--font-size-lg);
|
||||
font-weight: var(--font-weight-semibold);
|
||||
margin: 0;
|
||||
}
|
||||
.tracks__card-desc {
|
||||
font-size: var(--font-size-sm);
|
||||
color: var(--color-text-secondary);
|
||||
line-height: var(--line-height-snug);
|
||||
margin: 0;
|
||||
}
|
||||
.tracks__card-meta {
|
||||
margin-top: auto;
|
||||
padding-top: var(--space-3);
|
||||
display: flex; justify-content: space-between; align-items: baseline;
|
||||
font-size: var(--font-size-xs);
|
||||
color: var(--color-text-tertiary);
|
||||
font-family: var(--font-family-mono);
|
||||
}
|
||||
.tracks__card-cta {
|
||||
font-family: var(--font-family-sans);
|
||||
font-weight: var(--font-weight-medium);
|
||||
color: var(--color-text-primary);
|
||||
}
|
||||
|
||||
@media (max-width: 880px) {
|
||||
.tracks { grid-template-columns: 1fr; }
|
||||
}
|
||||
|
||||
/* =============================================================================
|
||||
22. FRIA RIGHTS-MATRIX
|
||||
12 EU Charter rights × impact level. Long left labels, compact right cells.
|
||||
Each cell shows checkmark + severity color when right is impacted.
|
||||
============================================================================= */
|
||||
.rights-matrix {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr;
|
||||
gap: 1px;
|
||||
background: var(--color-border-subtle);
|
||||
border: 1px solid var(--color-border-subtle);
|
||||
border-radius: var(--radius-md);
|
||||
overflow: hidden;
|
||||
}
|
||||
.rights-matrix__head,
|
||||
.rights-matrix__row {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr repeat(5, 64px);
|
||||
background: var(--color-surface);
|
||||
}
|
||||
.rights-matrix__head {
|
||||
background: var(--color-bg-soft);
|
||||
}
|
||||
.rights-matrix__head-cell,
|
||||
.rights-matrix__name,
|
||||
.rights-matrix__cell {
|
||||
padding: 10px 12px;
|
||||
font-size: var(--font-size-sm);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
.rights-matrix__head-cell {
|
||||
font-size: var(--font-size-xs);
|
||||
font-weight: var(--font-weight-semibold);
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.04em;
|
||||
color: var(--color-text-secondary);
|
||||
justify-content: center;
|
||||
}
|
||||
.rights-matrix__head-cell--name { justify-content: flex-start; }
|
||||
.rights-matrix__name {
|
||||
font-weight: var(--font-weight-medium);
|
||||
color: var(--color-text-primary);
|
||||
}
|
||||
.rights-matrix__name-meta {
|
||||
display: block;
|
||||
font-size: var(--font-size-xs);
|
||||
color: var(--color-text-tertiary);
|
||||
font-weight: var(--font-weight-regular);
|
||||
margin-top: 2px;
|
||||
}
|
||||
.rights-matrix__cell {
|
||||
justify-content: center;
|
||||
font-family: var(--font-family-mono);
|
||||
font-size: var(--font-size-sm);
|
||||
font-weight: var(--font-weight-semibold);
|
||||
font-variant-numeric: tabular-nums;
|
||||
color: var(--color-text-tertiary);
|
||||
border-left: 1px solid var(--color-border-subtle);
|
||||
}
|
||||
.rights-matrix__cell[data-impact="0"]::before { content: "—"; color: var(--color-text-tertiary); }
|
||||
.rights-matrix__cell[data-impact="1"] { background: var(--color-severity-low-soft); color: var(--color-severity-low-on); }
|
||||
.rights-matrix__cell[data-impact="2"] { background: var(--color-severity-medium-soft); color: var(--color-severity-medium-on); }
|
||||
.rights-matrix__cell[data-impact="3"] { background: var(--color-severity-high-soft); color: var(--color-severity-high-on); }
|
||||
.rights-matrix__cell[data-impact="4"] { background: var(--color-severity-critical-soft); color: var(--color-severity-critical-on); }
|
||||
.rights-matrix__cell[data-impact="5"] { background: var(--color-severity-critical); color: var(--color-severity-critical-on); }
|
||||
|
||||
@media (max-width: 720px) {
|
||||
.rights-matrix__head,
|
||||
.rights-matrix__row { grid-template-columns: 1fr repeat(5, 44px); }
|
||||
.rights-matrix__head-cell,
|
||||
.rights-matrix__cell { padding: 8px 6px; font-size: var(--font-size-xs); }
|
||||
}
|
||||
|
||||
/* =============================================================================
|
||||
23. CAPABILITY-MATRIX
|
||||
Rows = capabilities (e.g. "Generate text via M365 Chat"), columns = licenses
|
||||
(E3, E5, Copilot, etc.). Cells use one of four states with explicit icon +
|
||||
color so meaning never depends solely on color.
|
||||
============================================================================= */
|
||||
.capability-matrix {
|
||||
display: grid;
|
||||
gap: 1px;
|
||||
background: var(--color-border-subtle);
|
||||
border: 1px solid var(--color-border-subtle);
|
||||
border-radius: var(--radius-md);
|
||||
overflow: hidden;
|
||||
font-size: var(--font-size-sm);
|
||||
}
|
||||
.capability-matrix__head,
|
||||
.capability-matrix__row {
|
||||
display: grid;
|
||||
background: var(--color-surface);
|
||||
/* grid-template-columns set inline based on license count */
|
||||
}
|
||||
.capability-matrix__head { background: var(--color-bg-soft); }
|
||||
.capability-matrix__head-cell,
|
||||
.capability-matrix__name,
|
||||
.capability-matrix__cell {
|
||||
padding: 10px 12px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
}
|
||||
.capability-matrix__head-cell {
|
||||
font-size: var(--font-size-xs);
|
||||
font-weight: var(--font-weight-semibold);
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.04em;
|
||||
color: var(--color-text-secondary);
|
||||
justify-content: center;
|
||||
}
|
||||
.capability-matrix__head-cell--name { justify-content: flex-start; }
|
||||
.capability-matrix__name {
|
||||
font-weight: var(--font-weight-medium);
|
||||
border-right: 1px solid var(--color-border-subtle);
|
||||
}
|
||||
.capability-matrix__cell {
|
||||
justify-content: center;
|
||||
font-family: var(--font-family-mono);
|
||||
font-size: var(--font-size-md);
|
||||
border-left: 1px solid var(--color-border-subtle);
|
||||
}
|
||||
.capability-matrix__cell-icon {
|
||||
font-style: normal;
|
||||
width: 22px; height: 22px;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border-radius: 50%;
|
||||
font-size: 13px;
|
||||
font-weight: var(--font-weight-bold);
|
||||
}
|
||||
.capability-matrix__cell[data-status="available"] { background: var(--color-severity-low-soft); }
|
||||
.capability-matrix__cell[data-status="available"] .capability-matrix__cell-icon { background: var(--color-severity-low); color: #fff; }
|
||||
.capability-matrix__cell[data-status="available"] .capability-matrix__cell-icon::before { content: "✓"; }
|
||||
.capability-matrix__cell[data-status="cost"] { background: var(--color-severity-medium-soft); }
|
||||
.capability-matrix__cell[data-status="cost"] .capability-matrix__cell-icon { background: var(--color-severity-medium); color: #fff; }
|
||||
.capability-matrix__cell[data-status="cost"] .capability-matrix__cell-icon::before { content: "kr"; font-size: 10px; }
|
||||
.capability-matrix__cell[data-status="conditional"] { background: var(--color-severity-high-soft); }
|
||||
.capability-matrix__cell[data-status="conditional"] .capability-matrix__cell-icon { background: var(--color-severity-high); color: #fff; }
|
||||
.capability-matrix__cell[data-status="conditional"] .capability-matrix__cell-icon::before { content: "!"; }
|
||||
.capability-matrix__cell[data-status="missing"] { background: var(--color-bg-soft); }
|
||||
.capability-matrix__cell[data-status="missing"] .capability-matrix__cell-icon { background: var(--color-text-tertiary); color: #fff; }
|
||||
.capability-matrix__cell[data-status="missing"] .capability-matrix__cell-icon::before { content: "×"; }
|
||||
|
||||
.capability-matrix__legend {
|
||||
display: flex;
|
||||
gap: var(--space-4);
|
||||
flex-wrap: wrap;
|
||||
font-size: var(--font-size-xs);
|
||||
margin-top: var(--space-3);
|
||||
color: var(--color-text-secondary);
|
||||
}
|
||||
.capability-matrix__legend-item {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
}
|
||||
|
||||
/* =============================================================================
|
||||
24. PARALLEL-AGENT-STATUS PANEL
|
||||
Used by ms-ai-architect utredning (4 parallel workers — security-worker,
|
||||
cost-worker, dpia-worker, diagram-worker writing to .work/-files) and
|
||||
ultraplan-local multi-wave execute. Grid of agent cards with state pills,
|
||||
progress bars, and per-agent metrics.
|
||||
============================================================================= */
|
||||
.agent-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
|
||||
gap: var(--space-3);
|
||||
}
|
||||
.agent-card {
|
||||
background: var(--color-surface);
|
||||
border: 1px solid var(--color-border-subtle);
|
||||
border-radius: var(--radius-md);
|
||||
padding: var(--space-4);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: var(--space-2);
|
||||
position: relative;
|
||||
}
|
||||
.agent-card__head {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: flex-start;
|
||||
gap: var(--space-2);
|
||||
}
|
||||
.agent-card__name {
|
||||
font-weight: var(--font-weight-semibold);
|
||||
font-size: var(--font-size-sm);
|
||||
margin: 0;
|
||||
}
|
||||
.agent-card__role {
|
||||
font-family: var(--font-family-mono);
|
||||
font-size: 11px;
|
||||
color: var(--color-text-tertiary);
|
||||
}
|
||||
.agent-card__state {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
padding: 2px 8px;
|
||||
font-size: 11px;
|
||||
font-weight: var(--font-weight-medium);
|
||||
border-radius: var(--radius-pill);
|
||||
white-space: nowrap;
|
||||
}
|
||||
.agent-card__state[data-state="queued"] { background: var(--color-bg-soft); color: var(--color-text-tertiary); }
|
||||
.agent-card__state[data-state="running"] { background: var(--color-severity-medium-soft); color: var(--color-severity-medium-on); }
|
||||
.agent-card__state[data-state="done"] { background: var(--color-severity-low-soft); color: var(--color-severity-low-on); }
|
||||
.agent-card__state[data-state="failed"] { background: var(--color-state-failed); color: #fff; }
|
||||
.agent-card__state[data-state="blocked"] { background: var(--color-state-blocked); color: #fff; }
|
||||
.agent-card__state-dot {
|
||||
width: 6px; height: 6px;
|
||||
border-radius: 50%;
|
||||
background: currentColor;
|
||||
}
|
||||
.agent-card__state[data-state="running"] .agent-card__state-dot {
|
||||
animation: agent-pulse 1.4s var(--ease-default) infinite;
|
||||
}
|
||||
@keyframes agent-pulse {
|
||||
0%, 100% { opacity: 1; }
|
||||
50% { opacity: 0.35; }
|
||||
}
|
||||
|
||||
.agent-card__progress {
|
||||
height: 4px;
|
||||
background: var(--color-surface-sunken);
|
||||
border-radius: var(--radius-pill);
|
||||
overflow: hidden;
|
||||
}
|
||||
.agent-card__progress-fill {
|
||||
height: 100%;
|
||||
background: var(--color-primary-500);
|
||||
transition: width var(--duration-normal) var(--ease-default);
|
||||
}
|
||||
.agent-card__metrics {
|
||||
display: flex;
|
||||
gap: var(--space-3);
|
||||
font-size: var(--font-size-xs);
|
||||
color: var(--color-text-secondary);
|
||||
}
|
||||
.agent-card__metric { display: flex; gap: 4px; align-items: baseline; }
|
||||
.agent-card__metric-value {
|
||||
font-variant-numeric: tabular-nums;
|
||||
font-weight: var(--font-weight-semibold);
|
||||
color: var(--color-text-primary);
|
||||
}
|
||||
.agent-card__output {
|
||||
font-family: var(--font-family-mono);
|
||||
font-size: 11px;
|
||||
background: var(--color-surface-sunken);
|
||||
padding: 6px 8px;
|
||||
border-radius: var(--radius-sm);
|
||||
max-height: 56px;
|
||||
overflow: hidden;
|
||||
color: var(--color-text-secondary);
|
||||
white-space: pre-wrap;
|
||||
word-break: break-word;
|
||||
}
|
||||
.agent-card__output::after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
bottom: var(--space-4);
|
||||
left: var(--space-4);
|
||||
right: var(--space-4);
|
||||
height: 18px;
|
||||
background: linear-gradient(to bottom, transparent, var(--color-surface));
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
/* =============================================================================
|
||||
25. ERROR-SUMMARY (Aksel/GOV.UK pattern)
|
||||
Concentrated list of validation errors at top of a form. Each error
|
||||
anchor-links to the offending field. Required for accessible long forms.
|
||||
============================================================================= */
|
||||
.error-summary {
|
||||
background: var(--color-surface);
|
||||
border: 1px solid var(--color-severity-critical);
|
||||
border-left-width: 4px;
|
||||
border-radius: var(--radius-md);
|
||||
padding: var(--space-4) var(--space-5);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: var(--space-2);
|
||||
}
|
||||
.error-summary__heading {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
font-size: var(--font-size-md);
|
||||
font-weight: var(--font-weight-semibold);
|
||||
color: var(--color-severity-critical);
|
||||
margin: 0;
|
||||
}
|
||||
[data-theme="dark"] .error-summary__heading { color: #F09095; }
|
||||
.error-summary__heading::before {
|
||||
content: "!";
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 20px; height: 20px;
|
||||
border-radius: 50%;
|
||||
background: var(--color-severity-critical);
|
||||
color: #fff;
|
||||
font-size: 14px;
|
||||
font-weight: var(--font-weight-bold);
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.error-summary__body {
|
||||
font-size: var(--font-size-sm);
|
||||
color: var(--color-text-primary);
|
||||
line-height: var(--line-height-snug);
|
||||
}
|
||||
.error-summary__list {
|
||||
margin: var(--space-2) 0 0;
|
||||
padding: 0 0 0 var(--space-5);
|
||||
list-style: disc;
|
||||
color: var(--color-text-primary);
|
||||
}
|
||||
.error-summary__item { margin-bottom: 4px; }
|
||||
.error-summary__link {
|
||||
color: var(--color-severity-critical);
|
||||
text-decoration: underline;
|
||||
text-underline-offset: 2px;
|
||||
text-decoration-thickness: 1px;
|
||||
font-weight: var(--font-weight-medium);
|
||||
}
|
||||
.error-summary__link:hover { text-decoration-thickness: 2px; color: var(--color-severity-extreme); }
|
||||
[data-theme="dark"] .error-summary__link { color: #F09095; }
|
||||
[data-theme="dark"] .error-summary__link:hover { color: #FFB7BA; }
|
||||
|
||||
/* =============================================================================
|
||||
26. GUIDE-PANEL (Aksel pattern)
|
||||
Friendly inline guidance with optional illustration and CTA. Used to scaffold
|
||||
first-time users through unfamiliar territory without scolding tone.
|
||||
============================================================================= */
|
||||
.guide-panel {
|
||||
display: grid;
|
||||
grid-template-columns: 56px 1fr auto;
|
||||
gap: var(--space-4);
|
||||
align-items: start;
|
||||
background: var(--color-bg-soft);
|
||||
border: 1px solid var(--color-border-subtle);
|
||||
border-radius: var(--radius-lg);
|
||||
padding: var(--space-4) var(--space-5);
|
||||
}
|
||||
.guide-panel--info { background: #EAF3FB; border-color: rgba(9, 105, 218, 0.25); }
|
||||
.guide-panel--success { background: var(--color-severity-low-soft); border-color: rgba(26, 127, 55, 0.3); }
|
||||
.guide-panel--warn { background: var(--color-severity-medium-soft); border-color: rgba(191, 135, 0, 0.3); }
|
||||
[data-theme="dark"] .guide-panel--info { background: #0E2A3F; border-color: rgba(111, 165, 221, 0.3); }
|
||||
|
||||
.guide-panel__icon {
|
||||
width: 56px; height: 56px;
|
||||
border-radius: var(--radius-md);
|
||||
background: var(--color-surface);
|
||||
border: 1px solid var(--color-border-subtle);
|
||||
display: flex; align-items: center; justify-content: center;
|
||||
color: var(--color-primary-500);
|
||||
}
|
||||
.guide-panel--info .guide-panel__icon { color: var(--color-state-info); }
|
||||
.guide-panel--success .guide-panel__icon { color: var(--color-state-success); }
|
||||
.guide-panel--warn .guide-panel__icon { color: var(--color-severity-medium); }
|
||||
|
||||
.guide-panel__body {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 4px;
|
||||
min-width: 0;
|
||||
}
|
||||
.guide-panel__title {
|
||||
font-size: var(--font-size-md);
|
||||
font-weight: var(--font-weight-semibold);
|
||||
margin: 0;
|
||||
color: var(--color-text-primary);
|
||||
}
|
||||
.guide-panel__text {
|
||||
font-size: var(--font-size-sm);
|
||||
color: var(--color-text-secondary);
|
||||
line-height: var(--line-height-snug);
|
||||
margin: 0;
|
||||
max-width: var(--measure);
|
||||
}
|
||||
.guide-panel__action {
|
||||
align-self: center;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.guide-panel__dismiss {
|
||||
position: absolute;
|
||||
top: var(--space-2);
|
||||
right: var(--space-2);
|
||||
background: none;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
width: 28px; height: 28px;
|
||||
border-radius: var(--radius-sm);
|
||||
display: flex; align-items: center; justify-content: center;
|
||||
color: var(--color-text-tertiary);
|
||||
font-family: inherit;
|
||||
}
|
||||
.guide-panel__dismiss:hover { background: rgba(0,0,0,0.06); color: var(--color-text-primary); }
|
||||
|
||||
@media (max-width: 640px) {
|
||||
.guide-panel {
|
||||
grid-template-columns: 40px 1fr;
|
||||
gap: var(--space-3);
|
||||
}
|
||||
.guide-panel__icon { width: 40px; height: 40px; }
|
||||
.guide-panel__action {
|
||||
grid-column: 1 / -1;
|
||||
align-self: stretch;
|
||||
}
|
||||
}
|
||||
|
||||
/* =============================================================================
|
||||
Print rules for Tier 3
|
||||
============================================================================= */
|
||||
@media print {
|
||||
.pair-before-after { page-break-inside: avoid; }
|
||||
.aiact-timeline { page-break-inside: avoid; }
|
||||
.agent-grid { page-break-inside: avoid; }
|
||||
.tracks { display: none; } /* entry choice = screen-only */
|
||||
.guide-panel__dismiss { display: none; } /* dismiss only meaningful on screen */
|
||||
.error-summary {
|
||||
background: #FFF !important;
|
||||
border: 1pt solid #000 !important;
|
||||
color: #000 !important;
|
||||
}
|
||||
.error-summary__heading,
|
||||
.error-summary__body,
|
||||
.error-summary__link { color: #000 !important; }
|
||||
}
|
||||
650
plugins/ms-ai-architect/playground/vendor/playground-design-system/components.css
vendored
Normal file
650
plugins/ms-ai-architect/playground/vendor/playground-design-system/components.css
vendored
Normal file
|
|
@ -0,0 +1,650 @@
|
|||
/* Code generated by sync-design-system.mjs; DO NOT EDIT. */
|
||||
/* =============================================================================
|
||||
components.css — Tier 1 components (Phase 1)
|
||||
1. Radar / Spider
|
||||
2. Matrix / Heatmap (5x5 ROS)
|
||||
3. Findings-browser
|
||||
4. Critique-card
|
||||
5. Wizard / Stepper
|
||||
6. Live-meter / Quality-validator
|
||||
============================================================================= */
|
||||
|
||||
/* =============================================================================
|
||||
1. RADAR
|
||||
============================================================================= */
|
||||
.radar {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 240px;
|
||||
gap: var(--space-6);
|
||||
align-items: start;
|
||||
}
|
||||
.radar__chart {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
aspect-ratio: 1 / 1;
|
||||
max-width: 460px;
|
||||
}
|
||||
.radar__svg { width: 100%; height: 100%; display: block; overflow: visible; }
|
||||
.radar__grid-line { fill: none; stroke: var(--color-border-subtle); stroke-width: 1; }
|
||||
.radar__axis { stroke: var(--color-border-moderate); stroke-width: 1; }
|
||||
.radar__label {
|
||||
font-family: var(--font-family-sans);
|
||||
font-size: 12px;
|
||||
font-weight: var(--font-weight-medium);
|
||||
fill: var(--color-text-secondary);
|
||||
text-anchor: middle;
|
||||
}
|
||||
.radar__tick { font-size: 10px; fill: var(--color-text-tertiary); }
|
||||
.radar__series {
|
||||
fill: var(--color-primary-500);
|
||||
fill-opacity: 0.18;
|
||||
stroke: var(--color-primary-500);
|
||||
stroke-width: 2;
|
||||
stroke-linejoin: round;
|
||||
}
|
||||
.radar__series--target {
|
||||
fill: none;
|
||||
stroke: var(--color-text-tertiary);
|
||||
stroke-width: 1.5;
|
||||
stroke-dasharray: 4 4;
|
||||
}
|
||||
.radar__point { fill: var(--color-primary-500); r: 4; }
|
||||
.radar__point--target { fill: var(--color-bg); stroke: var(--color-text-tertiary); stroke-width: 1.5; r: 3; }
|
||||
|
||||
.radar__legend { display: flex; flex-direction: column; gap: var(--space-3); font-size: var(--font-size-sm); }
|
||||
.radar__legend-item { display: flex; align-items: baseline; gap: var(--space-2); }
|
||||
.radar__legend-swatch { width: 12px; height: 12px; border-radius: 2px; flex-shrink: 0; transform: translateY(1px); }
|
||||
.radar__legend-swatch--current { background: var(--color-primary-500); }
|
||||
.radar__legend-swatch--target {
|
||||
background: transparent;
|
||||
border: 1.5px dashed var(--color-text-tertiary);
|
||||
}
|
||||
.radar__scores {
|
||||
margin-top: var(--space-4);
|
||||
border-top: 1px solid var(--color-border-subtle);
|
||||
padding-top: var(--space-3);
|
||||
display: grid;
|
||||
gap: 4px;
|
||||
}
|
||||
.radar__score-row { display: flex; justify-content: space-between; font-size: var(--font-size-xs); }
|
||||
.radar__score-row dt { color: var(--color-text-secondary); }
|
||||
.radar__score-row dd { margin: 0; font-variant-numeric: tabular-nums; font-weight: var(--font-weight-medium); }
|
||||
|
||||
@media (max-width: 720px) {
|
||||
.radar { grid-template-columns: 1fr; }
|
||||
}
|
||||
|
||||
/* =============================================================================
|
||||
2. MATRIX / HEATMAP (5x5 ROS)
|
||||
============================================================================= */
|
||||
.matrix {
|
||||
display: grid;
|
||||
grid-template-columns: auto 1fr;
|
||||
gap: var(--space-3);
|
||||
}
|
||||
.matrix__y-label {
|
||||
writing-mode: vertical-rl;
|
||||
transform: rotate(180deg);
|
||||
text-align: center;
|
||||
font-size: var(--font-size-sm);
|
||||
font-weight: var(--font-weight-semibold);
|
||||
color: var(--color-text-secondary);
|
||||
letter-spacing: 0.06em;
|
||||
text-transform: uppercase;
|
||||
align-self: stretch;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
.matrix__main { display: flex; flex-direction: column; gap: var(--space-2); }
|
||||
.matrix__grid {
|
||||
display: grid;
|
||||
grid-template-columns: 32px repeat(5, 1fr);
|
||||
grid-template-rows: repeat(5, 1fr) 32px;
|
||||
gap: 4px;
|
||||
aspect-ratio: 5 / 5;
|
||||
width: 100%;
|
||||
}
|
||||
.matrix__y-tick {
|
||||
display: flex; align-items: center; justify-content: center;
|
||||
font-size: var(--font-size-sm); font-weight: var(--font-weight-semibold);
|
||||
color: var(--color-text-secondary);
|
||||
font-variant-numeric: tabular-nums;
|
||||
}
|
||||
.matrix__x-tick {
|
||||
display: flex; align-items: center; justify-content: center;
|
||||
font-size: var(--font-size-sm); font-weight: var(--font-weight-semibold);
|
||||
color: var(--color-text-secondary);
|
||||
font-variant-numeric: tabular-nums;
|
||||
}
|
||||
.matrix__corner { /* empty bottom-left */ }
|
||||
.matrix__cell {
|
||||
position: relative;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border-radius: var(--radius-sm);
|
||||
cursor: pointer;
|
||||
border: 1px solid transparent;
|
||||
transition: transform var(--duration-fast) var(--ease-default),
|
||||
box-shadow var(--duration-fast) var(--ease-default);
|
||||
min-height: 64px;
|
||||
background: var(--color-severity-low-soft);
|
||||
}
|
||||
.matrix__cell:hover { transform: scale(1.02); box-shadow: var(--shadow-md); z-index: 2; }
|
||||
.matrix__cell[aria-selected="true"] {
|
||||
outline: 3px solid var(--color-primary-500);
|
||||
outline-offset: 2px;
|
||||
z-index: 3;
|
||||
}
|
||||
|
||||
/* Severity zones based on score (sannsynlighet × konsekvens, 1-25) */
|
||||
.matrix__cell[data-score="1"],
|
||||
.matrix__cell[data-score="2"],
|
||||
.matrix__cell[data-score="3"],
|
||||
.matrix__cell[data-score="4"] { background: var(--color-severity-low-soft); }
|
||||
.matrix__cell[data-score="5"],
|
||||
.matrix__cell[data-score="6"],
|
||||
.matrix__cell[data-score="8"] { background: var(--color-severity-low-soft); }
|
||||
.matrix__cell[data-score="9"],
|
||||
.matrix__cell[data-score="10"],
|
||||
.matrix__cell[data-score="12"] { background: var(--color-severity-medium-soft); }
|
||||
.matrix__cell[data-score="15"],
|
||||
.matrix__cell[data-score="16"] { background: var(--color-severity-high-soft); }
|
||||
.matrix__cell[data-score="20"],
|
||||
.matrix__cell[data-score="25"] { background: var(--color-severity-critical-soft); }
|
||||
|
||||
.matrix__cell-score {
|
||||
position: absolute;
|
||||
top: 4px;
|
||||
left: 6px;
|
||||
font-size: 11px;
|
||||
font-weight: var(--font-weight-semibold);
|
||||
color: var(--color-text-tertiary);
|
||||
font-variant-numeric: tabular-nums;
|
||||
}
|
||||
.matrix__cell-bubbles {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 3px;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 12px 6px 6px;
|
||||
}
|
||||
.matrix__bubble {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
min-width: 22px;
|
||||
height: 22px;
|
||||
padding: 0 6px;
|
||||
font-size: 10px;
|
||||
font-weight: var(--font-weight-semibold);
|
||||
font-family: var(--font-family-mono);
|
||||
color: var(--color-text-primary);
|
||||
background: rgba(255, 255, 255, 0.85);
|
||||
border: 1px solid rgba(15, 18, 22, 0.18);
|
||||
border-radius: var(--radius-pill);
|
||||
}
|
||||
.matrix__bubble--count {
|
||||
background: var(--color-text-primary);
|
||||
color: var(--color-bg);
|
||||
border: none;
|
||||
}
|
||||
[data-theme="dark"] .matrix__bubble { background: rgba(0,0,0,0.45); color: var(--color-text-primary); border-color: rgba(255,255,255,0.15); }
|
||||
|
||||
.matrix__x-label {
|
||||
text-align: center;
|
||||
font-size: var(--font-size-sm);
|
||||
font-weight: var(--font-weight-semibold);
|
||||
color: var(--color-text-secondary);
|
||||
letter-spacing: 0.06em;
|
||||
text-transform: uppercase;
|
||||
margin-top: var(--space-1);
|
||||
}
|
||||
.matrix__legend {
|
||||
display: flex; gap: var(--space-4); flex-wrap: wrap;
|
||||
font-size: var(--font-size-xs);
|
||||
margin-top: var(--space-3);
|
||||
color: var(--color-text-secondary);
|
||||
}
|
||||
.matrix__legend-swatch {
|
||||
display: inline-block; width: 14px; height: 14px;
|
||||
border-radius: 3px; margin-right: 6px; vertical-align: -3px;
|
||||
}
|
||||
|
||||
/* =============================================================================
|
||||
3. FINDINGS-BROWSER
|
||||
============================================================================= */
|
||||
.findings {
|
||||
display: grid;
|
||||
grid-template-columns: 360px 1fr;
|
||||
gap: var(--space-6);
|
||||
align-items: start;
|
||||
}
|
||||
.findings__list {
|
||||
background: var(--color-surface);
|
||||
border: 1px solid var(--color-border-subtle);
|
||||
border-radius: var(--radius-lg);
|
||||
overflow: hidden;
|
||||
max-height: 640px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
.findings__toolbar {
|
||||
display: flex;
|
||||
gap: var(--space-2);
|
||||
padding: var(--space-3);
|
||||
border-bottom: 1px solid var(--color-border-subtle);
|
||||
background: var(--color-bg-soft);
|
||||
align-items: center;
|
||||
}
|
||||
.findings__search {
|
||||
flex: 1;
|
||||
padding: 6px 10px;
|
||||
font-size: var(--font-size-xs);
|
||||
border: 1px solid var(--color-border-moderate);
|
||||
border-radius: var(--radius-md);
|
||||
background: var(--color-surface);
|
||||
color: inherit;
|
||||
font-family: inherit;
|
||||
}
|
||||
.findings__group {
|
||||
border-bottom: 1px solid var(--color-border-subtle);
|
||||
}
|
||||
.findings__group-header {
|
||||
padding: 8px 12px;
|
||||
font-size: var(--font-size-xs);
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.08em;
|
||||
font-weight: var(--font-weight-semibold);
|
||||
color: var(--color-text-secondary);
|
||||
background: var(--color-bg-soft);
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
.findings__items {
|
||||
list-style: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
overflow-y: auto;
|
||||
}
|
||||
.findings__item {
|
||||
padding: 10px 12px;
|
||||
border-top: 1px solid var(--color-border-subtle);
|
||||
cursor: pointer;
|
||||
display: grid;
|
||||
grid-template-columns: auto 1fr;
|
||||
gap: 8px 10px;
|
||||
align-items: start;
|
||||
transition: background var(--duration-fast) var(--ease-default);
|
||||
}
|
||||
.findings__item:first-child { border-top: none; }
|
||||
.findings__item:hover { background: var(--color-bg-soft); }
|
||||
.findings__item[aria-selected="true"] {
|
||||
background: var(--color-primary-50);
|
||||
box-shadow: inset 3px 0 0 var(--color-primary-500);
|
||||
}
|
||||
[data-theme="dark"] .findings__item[aria-selected="true"] { background: var(--color-primary-900); }
|
||||
.findings__item-id {
|
||||
font-family: var(--font-family-mono);
|
||||
font-size: 11px;
|
||||
color: var(--color-text-tertiary);
|
||||
grid-column: 2;
|
||||
}
|
||||
.findings__item-title {
|
||||
font-size: var(--font-size-sm);
|
||||
font-weight: var(--font-weight-medium);
|
||||
line-height: 1.4;
|
||||
color: var(--color-text-primary);
|
||||
grid-column: 2;
|
||||
}
|
||||
.findings__item-meta {
|
||||
display: flex;
|
||||
gap: 6px;
|
||||
flex-wrap: wrap;
|
||||
grid-column: 2;
|
||||
}
|
||||
.findings__item-severity-dot {
|
||||
width: 8px; height: 8px; border-radius: 50%;
|
||||
margin-top: 7px;
|
||||
grid-row: 1 / span 3;
|
||||
}
|
||||
.findings__item-severity-dot[data-severity="critical"] { background: var(--color-severity-critical); }
|
||||
.findings__item-severity-dot[data-severity="high"] { background: var(--color-severity-high); }
|
||||
.findings__item-severity-dot[data-severity="medium"] { background: var(--color-severity-medium); }
|
||||
.findings__item-severity-dot[data-severity="low"] { background: var(--color-severity-low); }
|
||||
.findings__item-severity-dot[data-severity="info"] { background: var(--color-text-tertiary); }
|
||||
|
||||
.findings__detail {
|
||||
background: var(--color-surface);
|
||||
border: 1px solid var(--color-border-subtle);
|
||||
border-radius: var(--radius-lg);
|
||||
padding: var(--space-6);
|
||||
}
|
||||
|
||||
@media (max-width: 880px) { .findings { grid-template-columns: 1fr; } }
|
||||
|
||||
/* =============================================================================
|
||||
4. CRITIQUE-CARD
|
||||
============================================================================= */
|
||||
.critique-card {
|
||||
background: var(--color-surface);
|
||||
border: 1px solid var(--color-border-subtle);
|
||||
border-left: 4px solid var(--color-border-moderate);
|
||||
border-radius: var(--radius-md);
|
||||
padding: var(--space-4) var(--space-5);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: var(--space-3);
|
||||
}
|
||||
.critique-card[data-severity="critical"] { border-left-color: var(--color-severity-critical); }
|
||||
.critique-card[data-severity="high"] { border-left-color: var(--color-severity-high); }
|
||||
.critique-card[data-severity="medium"] { border-left-color: var(--color-severity-medium); }
|
||||
.critique-card[data-severity="low"] { border-left-color: var(--color-severity-low); }
|
||||
.critique-card[data-severity="info"] { border-left-color: var(--color-state-info); }
|
||||
|
||||
.critique-card__header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: flex-start;
|
||||
gap: var(--space-3);
|
||||
}
|
||||
.critique-card__title {
|
||||
font-size: var(--font-size-md);
|
||||
font-weight: var(--font-weight-semibold);
|
||||
margin: 0;
|
||||
}
|
||||
.critique-card__meta { display: flex; gap: 6px; flex-wrap: wrap; align-items: center; }
|
||||
.critique-card__id {
|
||||
font-family: var(--font-family-mono);
|
||||
font-size: var(--font-size-xs);
|
||||
color: var(--color-text-tertiary);
|
||||
}
|
||||
.critique-card__evidence {
|
||||
font-family: var(--font-family-mono);
|
||||
font-size: var(--font-size-xs);
|
||||
background: var(--color-surface-sunken);
|
||||
border: 1px solid var(--color-border-subtle);
|
||||
border-radius: var(--radius-sm);
|
||||
padding: 8px 10px;
|
||||
white-space: pre-wrap;
|
||||
word-break: break-word;
|
||||
color: var(--color-text-secondary);
|
||||
}
|
||||
.critique-card__recommendation {
|
||||
font-size: var(--font-size-sm);
|
||||
color: var(--color-text-primary);
|
||||
line-height: var(--line-height-snug);
|
||||
}
|
||||
.critique-card__actions {
|
||||
display: flex;
|
||||
gap: var(--space-2);
|
||||
margin-top: 4px;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
.critique-card[data-status="approved"] { opacity: 0.65; background: var(--color-bg-soft); }
|
||||
.critique-card[data-status="rejected"] { opacity: 0.5; }
|
||||
|
||||
/* =============================================================================
|
||||
5. WIZARD / STEPPER
|
||||
============================================================================= */
|
||||
.stepper {
|
||||
display: flex;
|
||||
gap: 0;
|
||||
margin-bottom: var(--space-8);
|
||||
border-bottom: 1px solid var(--color-border-subtle);
|
||||
padding-bottom: var(--space-4);
|
||||
overflow-x: auto;
|
||||
}
|
||||
.stepper__step {
|
||||
flex: 1;
|
||||
min-width: 140px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: var(--space-3);
|
||||
padding: 0 var(--space-4) 0 0;
|
||||
text-align: left;
|
||||
background: none;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
position: relative;
|
||||
font-family: inherit;
|
||||
color: var(--color-text-tertiary);
|
||||
}
|
||||
.stepper__step:not(:last-child)::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
width: 16px;
|
||||
height: 1px;
|
||||
background: var(--color-border-moderate);
|
||||
}
|
||||
.stepper__step-number {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 28px; height: 28px;
|
||||
border-radius: 50%;
|
||||
border: 1.5px solid var(--color-border-moderate);
|
||||
font-size: var(--font-size-sm);
|
||||
font-weight: var(--font-weight-semibold);
|
||||
color: var(--color-text-tertiary);
|
||||
background: var(--color-surface);
|
||||
flex-shrink: 0;
|
||||
font-variant-numeric: tabular-nums;
|
||||
}
|
||||
.stepper__step-text {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 1px;
|
||||
min-width: 0;
|
||||
}
|
||||
.stepper__step-label {
|
||||
font-size: var(--font-size-sm);
|
||||
font-weight: var(--font-weight-medium);
|
||||
color: inherit;
|
||||
line-height: 1.3;
|
||||
}
|
||||
.stepper__step-hint {
|
||||
font-size: var(--font-size-xs);
|
||||
color: var(--color-text-tertiary);
|
||||
line-height: 1.3;
|
||||
}
|
||||
.stepper__step[data-state="active"] { color: var(--color-text-primary); }
|
||||
.stepper__step[data-state="active"] .stepper__step-number { border-color: var(--color-primary-500); background: var(--color-primary-500); color: #fff; }
|
||||
.stepper__step[data-state="complete"] { color: var(--color-text-secondary); }
|
||||
.stepper__step[data-state="complete"] .stepper__step-number { border-color: var(--color-state-success); background: var(--color-state-success); color: #fff; }
|
||||
.stepper__step[data-state="complete"] .stepper__step-number::before { content: '✓'; font-size: 14px; }
|
||||
.stepper__step[data-state="complete"] .stepper__step-number-text { display: none; }
|
||||
|
||||
.wizard__panel { display: none; }
|
||||
.wizard__panel[data-active="true"] { display: block; }
|
||||
.wizard__nav {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
margin-top: var(--space-8);
|
||||
padding-top: var(--space-6);
|
||||
border-top: 1px solid var(--color-border-subtle);
|
||||
}
|
||||
|
||||
/* =============================================================================
|
||||
6. LIVE-METER
|
||||
============================================================================= */
|
||||
.live-meter {
|
||||
display: grid;
|
||||
gap: var(--space-3);
|
||||
}
|
||||
.live-meter__row {
|
||||
display: grid;
|
||||
grid-template-columns: 180px 1fr 56px;
|
||||
gap: var(--space-3);
|
||||
align-items: center;
|
||||
font-size: var(--font-size-sm);
|
||||
}
|
||||
.live-meter__label { color: var(--color-text-secondary); }
|
||||
.live-meter__bar {
|
||||
height: 8px;
|
||||
background: var(--color-surface-sunken);
|
||||
border-radius: var(--radius-pill);
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
}
|
||||
.live-meter__bar-fill {
|
||||
height: 100%;
|
||||
background: var(--color-primary-500);
|
||||
border-radius: var(--radius-pill);
|
||||
transition: width var(--duration-normal) var(--ease-default);
|
||||
}
|
||||
.live-meter__bar-fill[data-state="pass"] { background: var(--color-state-success); }
|
||||
.live-meter__bar-fill[data-state="weak"] { background: var(--color-severity-medium); }
|
||||
.live-meter__bar-fill[data-state="fail"] { background: var(--color-severity-critical); }
|
||||
.live-meter__value {
|
||||
text-align: right;
|
||||
font-variant-numeric: tabular-nums;
|
||||
font-weight: var(--font-weight-semibold);
|
||||
font-size: var(--font-size-sm);
|
||||
}
|
||||
.live-meter__overall {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: baseline;
|
||||
padding: var(--space-3) var(--space-4);
|
||||
background: var(--color-bg-soft);
|
||||
border-radius: var(--radius-md);
|
||||
margin-top: var(--space-2);
|
||||
}
|
||||
.live-meter__overall-value {
|
||||
font-size: var(--font-size-2xl);
|
||||
font-weight: var(--font-weight-bold);
|
||||
font-variant-numeric: tabular-nums;
|
||||
letter-spacing: -0.02em;
|
||||
}
|
||||
|
||||
/* Antipattern annotations (inline, subtle) */
|
||||
.lint-annotation {
|
||||
display: inline-flex;
|
||||
gap: 6px;
|
||||
padding: 6px 10px;
|
||||
margin-top: 6px;
|
||||
background: var(--color-severity-medium-soft);
|
||||
border-left: 3px solid var(--color-severity-medium);
|
||||
border-radius: 0 var(--radius-sm) var(--radius-sm) 0;
|
||||
font-size: var(--font-size-xs);
|
||||
color: var(--color-severity-medium-on);
|
||||
line-height: var(--line-height-snug);
|
||||
}
|
||||
.lint-annotation--error {
|
||||
background: var(--color-severity-critical-soft);
|
||||
color: var(--color-severity-critical);
|
||||
border-left-color: var(--color-severity-critical);
|
||||
}
|
||||
.lint-annotation__code {
|
||||
font-family: var(--font-family-mono);
|
||||
font-weight: var(--font-weight-semibold);
|
||||
}
|
||||
|
||||
/* =============================================================================
|
||||
App shell — header / nav (used by Scenario A and showcase)
|
||||
============================================================================= */
|
||||
.app-header {
|
||||
position: sticky;
|
||||
top: 0;
|
||||
z-index: 50;
|
||||
background: var(--color-surface);
|
||||
border-bottom: 1px solid var(--color-border-subtle);
|
||||
padding: var(--space-3) var(--space-6);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: var(--space-4);
|
||||
}
|
||||
.app-header__brand {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: var(--space-3);
|
||||
font-weight: var(--font-weight-semibold);
|
||||
font-size: var(--font-size-md);
|
||||
text-decoration: none;
|
||||
color: var(--color-text-primary);
|
||||
}
|
||||
.app-header__brand-mark {
|
||||
width: 28px; height: 28px;
|
||||
background: var(--color-primary-500);
|
||||
border-radius: var(--radius-sm);
|
||||
display: flex; align-items: center; justify-content: center;
|
||||
color: #fff;
|
||||
font-family: var(--font-family-mono);
|
||||
font-size: 13px;
|
||||
font-weight: 700;
|
||||
}
|
||||
.app-header__breadcrumb {
|
||||
color: var(--color-text-tertiary);
|
||||
font-size: var(--font-size-sm);
|
||||
display: flex; gap: var(--space-2); align-items: center;
|
||||
}
|
||||
.app-header__spacer { flex: 1; }
|
||||
.app-header__actions { display: flex; gap: var(--space-2); align-items: center; }
|
||||
|
||||
.theme-toggle {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
padding: 6px 10px;
|
||||
border: 1px solid var(--color-border-moderate);
|
||||
border-radius: var(--radius-md);
|
||||
background: var(--color-surface);
|
||||
color: var(--color-text-secondary);
|
||||
font-size: var(--font-size-xs);
|
||||
font-family: inherit;
|
||||
cursor: pointer;
|
||||
}
|
||||
.theme-toggle:hover { border-color: var(--color-border-strong); color: var(--color-text-primary); }
|
||||
|
||||
/* Detail sidepanel (slides from right) */
|
||||
.sidepanel {
|
||||
position: fixed;
|
||||
inset: 0 0 0 auto;
|
||||
width: min(560px, 92vw);
|
||||
background: var(--color-surface);
|
||||
border-left: 1px solid var(--color-border-subtle);
|
||||
box-shadow: var(--shadow-lg);
|
||||
transform: translateX(100%);
|
||||
transition: transform var(--duration-normal) var(--ease-default);
|
||||
z-index: 100;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow: hidden;
|
||||
}
|
||||
.sidepanel[data-open="true"] { transform: translateX(0); }
|
||||
.sidepanel__header {
|
||||
padding: var(--space-4) var(--space-6);
|
||||
border-bottom: 1px solid var(--color-border-subtle);
|
||||
display: flex; justify-content: space-between; align-items: flex-start;
|
||||
gap: var(--space-3);
|
||||
}
|
||||
.sidepanel__body {
|
||||
flex: 1;
|
||||
overflow-y: auto;
|
||||
padding: var(--space-6);
|
||||
}
|
||||
.sidepanel__close {
|
||||
background: none; border: none; cursor: pointer;
|
||||
width: 32px; height: 32px;
|
||||
border-radius: var(--radius-sm);
|
||||
display: flex; align-items: center; justify-content: center;
|
||||
color: var(--color-text-secondary);
|
||||
}
|
||||
.sidepanel__close:hover { background: var(--color-bg-soft); color: var(--color-text-primary); }
|
||||
|
||||
.scrim {
|
||||
position: fixed; inset: 0;
|
||||
background: var(--color-overlay);
|
||||
opacity: 0;
|
||||
pointer-events: none;
|
||||
transition: opacity var(--duration-normal) var(--ease-default);
|
||||
z-index: 99;
|
||||
}
|
||||
.scrim[data-open="true"] { opacity: 1; pointer-events: auto; }
|
||||
84
plugins/ms-ai-architect/playground/vendor/playground-design-system/fonts.css
vendored
Normal file
84
plugins/ms-ai-architect/playground/vendor/playground-design-system/fonts.css
vendored
Normal file
|
|
@ -0,0 +1,84 @@
|
|||
/* Code generated by sync-design-system.mjs; DO NOT EDIT. */
|
||||
/*
|
||||
* Self-hosted web fonts for Playground Design System.
|
||||
*
|
||||
* All three families are licensed under SIL Open Font License 1.1.
|
||||
* Full license text and provenance: ./fonts/LICENSES.md
|
||||
*
|
||||
* Why self-hosted:
|
||||
* - No external requests (no fonts.googleapis.com, no IP/UA leakage).
|
||||
* - Works offline / behind air-gapped firewalls.
|
||||
* - GDPR-compliant for Norwegian public-sector deployments.
|
||||
*
|
||||
* Bundle size: ~940 KB total across 9 woff2 files.
|
||||
* Loaded via font-display: swap to avoid FOIT.
|
||||
*/
|
||||
|
||||
/* ========== Inter (UI / body) ========== */
|
||||
@font-face {
|
||||
font-family: "Inter";
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
font-display: swap;
|
||||
src: url("./fonts/Inter-Regular.woff2") format("woff2");
|
||||
}
|
||||
@font-face {
|
||||
font-family: "Inter";
|
||||
font-style: normal;
|
||||
font-weight: 500;
|
||||
font-display: swap;
|
||||
src: url("./fonts/Inter-Medium.woff2") format("woff2");
|
||||
}
|
||||
@font-face {
|
||||
font-family: "Inter";
|
||||
font-style: normal;
|
||||
font-weight: 600;
|
||||
font-display: swap;
|
||||
src: url("./fonts/Inter-SemiBold.woff2") format("woff2");
|
||||
}
|
||||
@font-face {
|
||||
font-family: "Inter";
|
||||
font-style: normal;
|
||||
font-weight: 700;
|
||||
font-display: swap;
|
||||
src: url("./fonts/Inter-Bold.woff2") format("woff2");
|
||||
}
|
||||
|
||||
/* ========== JetBrains Mono (code) ========== */
|
||||
@font-face {
|
||||
font-family: "JetBrains Mono";
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
font-display: swap;
|
||||
src: url("./fonts/JetBrainsMono-Regular.woff2") format("woff2");
|
||||
}
|
||||
@font-face {
|
||||
font-family: "JetBrains Mono";
|
||||
font-style: normal;
|
||||
font-weight: 500;
|
||||
font-display: swap;
|
||||
src: url("./fonts/JetBrainsMono-Medium.woff2") format("woff2");
|
||||
}
|
||||
@font-face {
|
||||
font-family: "JetBrains Mono";
|
||||
font-style: normal;
|
||||
font-weight: 600;
|
||||
font-display: swap;
|
||||
src: url("./fonts/JetBrainsMono-SemiBold.woff2") format("woff2");
|
||||
}
|
||||
|
||||
/* ========== Source Serif 4 (occasional editorial accents) ========== */
|
||||
@font-face {
|
||||
font-family: "Source Serif 4";
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
font-display: swap;
|
||||
src: url("./fonts/SourceSerif4-Regular.woff2") format("woff2");
|
||||
}
|
||||
@font-face {
|
||||
font-family: "Source Serif 4";
|
||||
font-style: normal;
|
||||
font-weight: 600;
|
||||
font-display: swap;
|
||||
src: url("./fonts/SourceSerif4-Semibold.woff2") format("woff2");
|
||||
}
|
||||
BIN
plugins/ms-ai-architect/playground/vendor/playground-design-system/fonts/Inter-Bold.woff2
vendored
Normal file
BIN
plugins/ms-ai-architect/playground/vendor/playground-design-system/fonts/Inter-Bold.woff2
vendored
Normal file
Binary file not shown.
BIN
plugins/ms-ai-architect/playground/vendor/playground-design-system/fonts/Inter-Medium.woff2
vendored
Normal file
BIN
plugins/ms-ai-architect/playground/vendor/playground-design-system/fonts/Inter-Medium.woff2
vendored
Normal file
Binary file not shown.
BIN
plugins/ms-ai-architect/playground/vendor/playground-design-system/fonts/Inter-Regular.woff2
vendored
Normal file
BIN
plugins/ms-ai-architect/playground/vendor/playground-design-system/fonts/Inter-Regular.woff2
vendored
Normal file
Binary file not shown.
BIN
plugins/ms-ai-architect/playground/vendor/playground-design-system/fonts/Inter-SemiBold.woff2
vendored
Normal file
BIN
plugins/ms-ai-architect/playground/vendor/playground-design-system/fonts/Inter-SemiBold.woff2
vendored
Normal file
Binary file not shown.
BIN
plugins/ms-ai-architect/playground/vendor/playground-design-system/fonts/JetBrainsMono-Medium.woff2
vendored
Normal file
BIN
plugins/ms-ai-architect/playground/vendor/playground-design-system/fonts/JetBrainsMono-Medium.woff2
vendored
Normal file
Binary file not shown.
BIN
plugins/ms-ai-architect/playground/vendor/playground-design-system/fonts/JetBrainsMono-Regular.woff2
vendored
Normal file
BIN
plugins/ms-ai-architect/playground/vendor/playground-design-system/fonts/JetBrainsMono-Regular.woff2
vendored
Normal file
Binary file not shown.
Binary file not shown.
92
plugins/ms-ai-architect/playground/vendor/playground-design-system/fonts/LICENSE-Inter.txt
vendored
Normal file
92
plugins/ms-ai-architect/playground/vendor/playground-design-system/fonts/LICENSE-Inter.txt
vendored
Normal file
|
|
@ -0,0 +1,92 @@
|
|||
Copyright (c) 2016 The Inter Project Authors (https://github.com/rsms/inter)
|
||||
|
||||
This Font Software is licensed under the SIL Open Font License, Version 1.1.
|
||||
This license is copied below, and is also available with a FAQ at:
|
||||
http://scripts.sil.org/OFL
|
||||
|
||||
-----------------------------------------------------------
|
||||
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
|
||||
-----------------------------------------------------------
|
||||
|
||||
PREAMBLE
|
||||
The goals of the Open Font License (OFL) are to stimulate worldwide
|
||||
development of collaborative font projects, to support the font creation
|
||||
efforts of academic and linguistic communities, and to provide a free and
|
||||
open framework in which fonts may be shared and improved in partnership
|
||||
with others.
|
||||
|
||||
The OFL allows the licensed fonts to be used, studied, modified and
|
||||
redistributed freely as long as they are not sold by themselves. The
|
||||
fonts, including any derivative works, can be bundled, embedded,
|
||||
redistributed and/or sold with any software provided that any reserved
|
||||
names are not used by derivative works. The fonts and derivatives,
|
||||
however, cannot be released under any other type of license. The
|
||||
requirement for fonts to remain under this license does not apply
|
||||
to any document created using the fonts or their derivatives.
|
||||
|
||||
DEFINITIONS
|
||||
"Font Software" refers to the set of files released by the Copyright
|
||||
Holder(s) under this license and clearly marked as such. This may
|
||||
include source files, build scripts and documentation.
|
||||
|
||||
"Reserved Font Name" refers to any names specified as such after the
|
||||
copyright statement(s).
|
||||
|
||||
"Original Version" refers to the collection of Font Software components as
|
||||
distributed by the Copyright Holder(s).
|
||||
|
||||
"Modified Version" refers to any derivative made by adding to, deleting,
|
||||
or substituting -- in part or in whole -- any of the components of the
|
||||
Original Version, by changing formats or by porting the Font Software to a
|
||||
new environment.
|
||||
|
||||
"Author" refers to any designer, engineer, programmer, technical
|
||||
writer or other person who contributed to the Font Software.
|
||||
|
||||
PERMISSION AND CONDITIONS
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of the Font Software, to use, study, copy, merge, embed, modify,
|
||||
redistribute, and sell modified and unmodified copies of the Font
|
||||
Software, subject to the following conditions:
|
||||
|
||||
1) Neither the Font Software nor any of its individual components,
|
||||
in Original or Modified Versions, may be sold by itself.
|
||||
|
||||
2) Original or Modified Versions of the Font Software may be bundled,
|
||||
redistributed and/or sold with any software, provided that each copy
|
||||
contains the above copyright notice and this license. These can be
|
||||
included either as stand-alone text files, human-readable headers or
|
||||
in the appropriate machine-readable metadata fields within text or
|
||||
binary files as long as those fields can be easily viewed by the user.
|
||||
|
||||
3) No Modified Version of the Font Software may use the Reserved Font
|
||||
Name(s) unless explicit written permission is granted by the corresponding
|
||||
Copyright Holder. This restriction only applies to the primary font name as
|
||||
presented to the users.
|
||||
|
||||
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
|
||||
Software shall not be used to promote, endorse or advertise any
|
||||
Modified Version, except to acknowledge the contribution(s) of the
|
||||
Copyright Holder(s) and the Author(s) or with their explicit written
|
||||
permission.
|
||||
|
||||
5) The Font Software, modified or unmodified, in part or in whole,
|
||||
must be distributed entirely under this license, and must not be
|
||||
distributed under any other license. The requirement for fonts to
|
||||
remain under this license does not apply to any document created
|
||||
using the Font Software.
|
||||
|
||||
TERMINATION
|
||||
This license becomes null and void if any of the above conditions are
|
||||
not met.
|
||||
|
||||
DISCLAIMER
|
||||
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
|
||||
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
|
||||
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
|
||||
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
|
||||
OTHER DEALINGS IN THE FONT SOFTWARE.
|
||||
|
|
@ -0,0 +1,93 @@
|
|||
Copyright 2020 The JetBrains Mono Project Authors (https://github.com/JetBrains/JetBrainsMono)
|
||||
|
||||
This Font Software is licensed under the SIL Open Font License, Version 1.1.
|
||||
This license is copied below, and is also available with a FAQ at:
|
||||
https://scripts.sil.org/OFL
|
||||
|
||||
|
||||
-----------------------------------------------------------
|
||||
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
|
||||
-----------------------------------------------------------
|
||||
|
||||
PREAMBLE
|
||||
The goals of the Open Font License (OFL) are to stimulate worldwide
|
||||
development of collaborative font projects, to support the font creation
|
||||
efforts of academic and linguistic communities, and to provide a free and
|
||||
open framework in which fonts may be shared and improved in partnership
|
||||
with others.
|
||||
|
||||
The OFL allows the licensed fonts to be used, studied, modified and
|
||||
redistributed freely as long as they are not sold by themselves. The
|
||||
fonts, including any derivative works, can be bundled, embedded,
|
||||
redistributed and/or sold with any software provided that any reserved
|
||||
names are not used by derivative works. The fonts and derivatives,
|
||||
however, cannot be released under any other type of license. The
|
||||
requirement for fonts to remain under this license does not apply
|
||||
to any document created using the fonts or their derivatives.
|
||||
|
||||
DEFINITIONS
|
||||
"Font Software" refers to the set of files released by the Copyright
|
||||
Holder(s) under this license and clearly marked as such. This may
|
||||
include source files, build scripts and documentation.
|
||||
|
||||
"Reserved Font Name" refers to any names specified as such after the
|
||||
copyright statement(s).
|
||||
|
||||
"Original Version" refers to the collection of Font Software components as
|
||||
distributed by the Copyright Holder(s).
|
||||
|
||||
"Modified Version" refers to any derivative made by adding to, deleting,
|
||||
or substituting -- in part or in whole -- any of the components of the
|
||||
Original Version, by changing formats or by porting the Font Software to a
|
||||
new environment.
|
||||
|
||||
"Author" refers to any designer, engineer, programmer, technical
|
||||
writer or other person who contributed to the Font Software.
|
||||
|
||||
PERMISSION & CONDITIONS
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of the Font Software, to use, study, copy, merge, embed, modify,
|
||||
redistribute, and sell modified and unmodified copies of the Font
|
||||
Software, subject to the following conditions:
|
||||
|
||||
1) Neither the Font Software nor any of its individual components,
|
||||
in Original or Modified Versions, may be sold by itself.
|
||||
|
||||
2) Original or Modified Versions of the Font Software may be bundled,
|
||||
redistributed and/or sold with any software, provided that each copy
|
||||
contains the above copyright notice and this license. These can be
|
||||
included either as stand-alone text files, human-readable headers or
|
||||
in the appropriate machine-readable metadata fields within text or
|
||||
binary files as long as those fields can be easily viewed by the user.
|
||||
|
||||
3) No Modified Version of the Font Software may use the Reserved Font
|
||||
Name(s) unless explicit written permission is granted by the corresponding
|
||||
Copyright Holder. This restriction only applies to the primary font name as
|
||||
presented to the users.
|
||||
|
||||
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
|
||||
Software shall not be used to promote, endorse or advertise any
|
||||
Modified Version, except to acknowledge the contribution(s) of the
|
||||
Copyright Holder(s) and the Author(s) or with their explicit written
|
||||
permission.
|
||||
|
||||
5) The Font Software, modified or unmodified, in part or in whole,
|
||||
must be distributed entirely under this license, and must not be
|
||||
distributed under any other license. The requirement for fonts to
|
||||
remain under this license does not apply to any document created
|
||||
using the Font Software.
|
||||
|
||||
TERMINATION
|
||||
This license becomes null and void if any of the above conditions are
|
||||
not met.
|
||||
|
||||
DISCLAIMER
|
||||
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
|
||||
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
|
||||
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
|
||||
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
|
||||
OTHER DEALINGS IN THE FONT SOFTWARE.
|
||||
93
plugins/ms-ai-architect/playground/vendor/playground-design-system/fonts/LICENSE-SourceSerif4.md
vendored
Normal file
93
plugins/ms-ai-architect/playground/vendor/playground-design-system/fonts/LICENSE-SourceSerif4.md
vendored
Normal file
|
|
@ -0,0 +1,93 @@
|
|||
Copyright 2014 - 2023 Adobe (http://www.adobe.com/), with Reserved Font Name ‘Source’. All Rights Reserved. Source is a trademark of Adobe in the United States and/or other countries.
|
||||
|
||||
This Font Software is licensed under the SIL Open Font License, Version 1.1.
|
||||
|
||||
This license is copied below, and is also available with a FAQ at: http://scripts.sil.org/OFL
|
||||
|
||||
|
||||
-----------------------------------------------------------
|
||||
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
|
||||
-----------------------------------------------------------
|
||||
|
||||
PREAMBLE
|
||||
The goals of the Open Font License (OFL) are to stimulate worldwide
|
||||
development of collaborative font projects, to support the font creation
|
||||
efforts of academic and linguistic communities, and to provide a free and
|
||||
open framework in which fonts may be shared and improved in partnership
|
||||
with others.
|
||||
|
||||
The OFL allows the licensed fonts to be used, studied, modified and
|
||||
redistributed freely as long as they are not sold by themselves. The
|
||||
fonts, including any derivative works, can be bundled, embedded,
|
||||
redistributed and/or sold with any software provided that any reserved
|
||||
names are not used by derivative works. The fonts and derivatives,
|
||||
however, cannot be released under any other type of license. The
|
||||
requirement for fonts to remain under this license does not apply
|
||||
to any document created using the fonts or their derivatives.
|
||||
|
||||
DEFINITIONS
|
||||
"Font Software" refers to the set of files released by the Copyright
|
||||
Holder(s) under this license and clearly marked as such. This may
|
||||
include source files, build scripts and documentation.
|
||||
|
||||
"Reserved Font Name" refers to any names specified as such after the
|
||||
copyright statement(s).
|
||||
|
||||
"Original Version" refers to the collection of Font Software components as
|
||||
distributed by the Copyright Holder(s).
|
||||
|
||||
"Modified Version" refers to any derivative made by adding to, deleting,
|
||||
or substituting -- in part or in whole -- any of the components of the
|
||||
Original Version, by changing formats or by porting the Font Software to a
|
||||
new environment.
|
||||
|
||||
"Author" refers to any designer, engineer, programmer, technical
|
||||
writer or other person who contributed to the Font Software.
|
||||
|
||||
PERMISSION & CONDITIONS
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of the Font Software, to use, study, copy, merge, embed, modify,
|
||||
redistribute, and sell modified and unmodified copies of the Font
|
||||
Software, subject to the following conditions:
|
||||
|
||||
1) Neither the Font Software nor any of its individual components,
|
||||
in Original or Modified Versions, may be sold by itself.
|
||||
|
||||
2) Original or Modified Versions of the Font Software may be bundled,
|
||||
redistributed and/or sold with any software, provided that each copy
|
||||
contains the above copyright notice and this license. These can be
|
||||
included either as stand-alone text files, human-readable headers or
|
||||
in the appropriate machine-readable metadata fields within text or
|
||||
binary files as long as those fields can be easily viewed by the user.
|
||||
|
||||
3) No Modified Version of the Font Software may use the Reserved Font
|
||||
Name(s) unless explicit written permission is granted by the corresponding
|
||||
Copyright Holder. This restriction only applies to the primary font name as
|
||||
presented to the users.
|
||||
|
||||
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
|
||||
Software shall not be used to promote, endorse or advertise any
|
||||
Modified Version, except to acknowledge the contribution(s) of the
|
||||
Copyright Holder(s) and the Author(s) or with their explicit written
|
||||
permission.
|
||||
|
||||
5) The Font Software, modified or unmodified, in part or in whole,
|
||||
must be distributed entirely under this license, and must not be
|
||||
distributed under any other license. The requirement for fonts to
|
||||
remain under this license does not apply to any document created
|
||||
using the Font Software.
|
||||
|
||||
TERMINATION
|
||||
This license becomes null and void if any of the above conditions are
|
||||
not met.
|
||||
|
||||
DISCLAIMER
|
||||
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
|
||||
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
|
||||
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
|
||||
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
|
||||
OTHER DEALINGS IN THE FONT SOFTWARE.
|
||||
42
plugins/ms-ai-architect/playground/vendor/playground-design-system/fonts/LICENSES.md
vendored
Normal file
42
plugins/ms-ai-architect/playground/vendor/playground-design-system/fonts/LICENSES.md
vendored
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
# Font Licenses
|
||||
|
||||
All three font families bundled with Playground Design System are licensed
|
||||
under the SIL Open Font License, Version 1.1 (OFL-1.1). They are free to
|
||||
use, modify, embed, and redistribute under the terms of OFL-1.1.
|
||||
|
||||
Full license text per family:
|
||||
|
||||
- **Inter** (Regular, Medium, SemiBold, Bold) — `LICENSE-Inter.txt`
|
||||
Copyright (c) 2016 The Inter Project Authors
|
||||
Source: https://github.com/rsms/inter
|
||||
Version bundled: 4.0
|
||||
|
||||
- **JetBrains Mono** (Regular, Medium, SemiBold) — `LICENSE-JetBrainsMono.txt`
|
||||
Copyright 2020 The JetBrains Mono Project Authors
|
||||
Source: https://github.com/JetBrains/JetBrainsMono
|
||||
Version bundled: 2.304
|
||||
|
||||
- **Source Serif 4** (Regular, Semibold) — `LICENSE-SourceSerif4.md`
|
||||
Copyright 2014–2023 Adobe (Reserved Font Name "Source")
|
||||
Source: https://github.com/adobe-fonts/source-serif
|
||||
Version bundled: 4.005
|
||||
|
||||
## Provenance
|
||||
|
||||
Files in this directory were obtained from the upstream release artifacts
|
||||
linked above on 2026-05-03. Source Serif 4 woff2 files were generated locally
|
||||
from the desktop OTF release using `fonttools ttLib.woff2 compress`; all
|
||||
others are unmodified from upstream webfont releases.
|
||||
|
||||
## Why bundled
|
||||
|
||||
These fonts ship with the design system to eliminate runtime requests to
|
||||
external CDNs (e.g., fonts.googleapis.com). This guarantees:
|
||||
|
||||
- No data leakage about end-user IPs / User-Agents to third parties.
|
||||
- GDPR compliance for Norwegian public-sector deployments.
|
||||
- Functioning Playgrounds in offline / air-gapped environments.
|
||||
|
||||
Each Playground HTML loads `../shared/playground-design-system/fonts.css`,
|
||||
which declares all `@font-face` rules pointing at the .woff2 files in this
|
||||
directory.
|
||||
BIN
plugins/ms-ai-architect/playground/vendor/playground-design-system/fonts/SourceSerif4-Regular.woff2
vendored
Normal file
BIN
plugins/ms-ai-architect/playground/vendor/playground-design-system/fonts/SourceSerif4-Regular.woff2
vendored
Normal file
Binary file not shown.
BIN
plugins/ms-ai-architect/playground/vendor/playground-design-system/fonts/SourceSerif4-Semibold.woff2
vendored
Normal file
BIN
plugins/ms-ai-architect/playground/vendor/playground-design-system/fonts/SourceSerif4-Semibold.woff2
vendored
Normal file
Binary file not shown.
176
plugins/ms-ai-architect/playground/vendor/playground-design-system/print.css
vendored
Normal file
176
plugins/ms-ai-architect/playground/vendor/playground-design-system/print.css
vendored
Normal file
|
|
@ -0,0 +1,176 @@
|
|||
/* Code generated by sync-design-system.mjs; DO NOT EDIT. */
|
||||
/* =============================================================================
|
||||
print.css — A4 print stylesheet for offentlige dokumenter
|
||||
- Severity-mønstre (skravur) som fungerer i B/W
|
||||
- Header/footer med kommune-logo-slot, signaturfelt, paginering
|
||||
- 12pt minimum kropp, 11pt for metadata
|
||||
- Skjuler interaktiv chrome (header, knapper, toggles)
|
||||
============================================================================= */
|
||||
|
||||
@page {
|
||||
size: A4 portrait;
|
||||
margin: 22mm 18mm 24mm 18mm;
|
||||
@bottom-right { content: counter(page) " / " counter(pages); font-family: "Inter", sans-serif; font-size: 9pt; color: #555; }
|
||||
}
|
||||
@page :first { @top-left { content: none; } }
|
||||
@page landscape { size: A4 landscape; }
|
||||
|
||||
/* SVG severity-mønstre (skravur) — definert i print-only inline-svg.
|
||||
For å bruke: legg til class .pattern-low/.pattern-medium/etc. på elementet
|
||||
som ellers fyller med severity-fargen. */
|
||||
@media print {
|
||||
|
||||
:root {
|
||||
--color-bg: #FFFFFF;
|
||||
--color-surface: #FFFFFF;
|
||||
--color-surface-sunken: #F5F5F5;
|
||||
--color-bg-soft: #F7F7F7;
|
||||
--color-border-subtle: #C7C7C7;
|
||||
--color-border-moderate: #888888;
|
||||
--color-text-primary: #000000;
|
||||
--color-text-secondary: #2A2A2A;
|
||||
--color-text-tertiary: #555555;
|
||||
}
|
||||
|
||||
html, body { background: #FFFFFF !important; color: #000 !important; font-size: 11pt !important; }
|
||||
body { -webkit-print-color-adjust: exact; print-color-adjust: exact; }
|
||||
|
||||
/* Hide interactive chrome */
|
||||
.app-header, header.app-header,
|
||||
.theme-toggle, #theme-toggle, #themeToggle,
|
||||
.filter-bar, .view-toggle, .screen-tabs,
|
||||
.btn--primary, .btn--secondary, .btn--ghost,
|
||||
.live-dot, .pane__head .badge,
|
||||
.accept-banner button,
|
||||
.scenario-card .btn,
|
||||
.footer { display: none !important; }
|
||||
|
||||
/* Container = full width on print */
|
||||
.container, .container--wide { max-width: none !important; padding: 0 !important; }
|
||||
|
||||
/* Body type */
|
||||
body, p, li, dd, dt, td, th, .field__value {
|
||||
font-family: "Inter", sans-serif;
|
||||
font-size: 11pt; line-height: 1.45; color: #000;
|
||||
}
|
||||
h1 { font-size: 22pt; line-height: 1.2; margin: 0 0 6pt; }
|
||||
h2 { font-size: 16pt; line-height: 1.25; margin: 18pt 0 6pt; page-break-after: avoid; }
|
||||
h3 { font-size: 13pt; margin: 12pt 0 4pt; page-break-after: avoid; }
|
||||
h4 { font-size: 11pt; margin: 10pt 0 3pt; }
|
||||
|
||||
/* Page breaks */
|
||||
.page-break { page-break-before: always; }
|
||||
.avoid-break, .finding, .critique, .scenario-card, table, figure {
|
||||
page-break-inside: avoid;
|
||||
}
|
||||
|
||||
/* Severity patterns (B/W-safe). Stack pattern-bg + dotted/diag border indicators. */
|
||||
.matrix__cell[data-score],
|
||||
.badge--severity-low, .badge--severity-medium, .badge--severity-high,
|
||||
.badge--severity-critical, .badge--severity-extreme {
|
||||
background-color: #FFF !important;
|
||||
color: #000 !important;
|
||||
border: 1px solid #000 !important;
|
||||
}
|
||||
.badge--severity-low::before, .badge--severity-medium::before,
|
||||
.badge--severity-high::before, .badge--severity-critical::before,
|
||||
.badge--severity-extreme::before {
|
||||
content: ""; display: inline-block;
|
||||
width: 7pt; height: 7pt; margin-right: 4pt;
|
||||
border: 1px solid #000;
|
||||
vertical-align: middle;
|
||||
}
|
||||
.badge--severity-low::before { background: #FFF; }
|
||||
.badge--severity-medium::before { background: repeating-linear-gradient(45deg, #000 0 0.6pt, transparent 0.6pt 3pt); }
|
||||
.badge--severity-high::before { background: repeating-linear-gradient(45deg, #000 0 1pt, transparent 1pt 2.5pt); }
|
||||
.badge--severity-critical::before { background: repeating-linear-gradient(0deg, #000 0 0.5pt, transparent 0.5pt 2pt),
|
||||
repeating-linear-gradient(90deg, #000 0 0.5pt, transparent 0.5pt 2pt); }
|
||||
.badge--severity-extreme::before { background: #000; }
|
||||
|
||||
/* Matrix cells in print: skravur i stedet for farge */
|
||||
.matrix__cell { color: #000 !important; border: 0.5pt solid #888 !important; }
|
||||
.matrix__cell[data-score]:not([data-score="0"]) { background: #FFF !important; }
|
||||
.matrix__cell[data-score="1"], .matrix__cell[data-score="2"],
|
||||
.matrix__cell[data-score="3"], .matrix__cell[data-score="4"] {
|
||||
background: #FFF !important;
|
||||
}
|
||||
.matrix__cell[data-score="5"], .matrix__cell[data-score="6"], .matrix__cell[data-score="8"] {
|
||||
background: repeating-linear-gradient(45deg, rgba(0,0,0,0.18) 0 0.5pt, transparent 0.5pt 4pt) !important;
|
||||
}
|
||||
.matrix__cell[data-score="9"], .matrix__cell[data-score="10"], .matrix__cell[data-score="12"] {
|
||||
background: repeating-linear-gradient(45deg, rgba(0,0,0,0.32) 0 0.7pt, transparent 0.7pt 3pt) !important;
|
||||
}
|
||||
.matrix__cell[data-score="15"], .matrix__cell[data-score="16"], .matrix__cell[data-score="20"] {
|
||||
background: repeating-linear-gradient(45deg, rgba(0,0,0,0.48) 0 1pt, transparent 1pt 2pt) !important;
|
||||
}
|
||||
.matrix__cell[data-score="25"] { background: #000 !important; color: #FFF !important; }
|
||||
.matrix__cell[data-score="25"] .matrix__cell-score { color: #FFF !important; }
|
||||
|
||||
/* Surfaces flat */
|
||||
.card, .pane, .finding, .critique, .scenario-card, .posture-summary, .verdict-block {
|
||||
background: #FFF !important;
|
||||
border: 0.5pt solid #888 !important;
|
||||
box-shadow: none !important;
|
||||
border-radius: 0 !important;
|
||||
}
|
||||
|
||||
/* Links visible but not underlined-everything */
|
||||
a { color: #000; text-decoration: none; }
|
||||
a[href^="http"]::after { content: " (" attr(href) ")"; font-size: 9pt; color: #555; }
|
||||
a[href^="#"]::after, a[href^="/"]::after, a:not([href*="://"])::after { content: ""; }
|
||||
|
||||
/* Standard footer block: signaturfelt for offentlige dokumenter */
|
||||
.print-footer {
|
||||
margin-top: 24pt;
|
||||
padding-top: 10pt;
|
||||
border-top: 0.5pt solid #888;
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
gap: 18pt;
|
||||
font-size: 10pt;
|
||||
}
|
||||
.print-signature { display: flex; flex-direction: column; gap: 28pt; }
|
||||
.print-signature__line {
|
||||
border-bottom: 0.5pt solid #000;
|
||||
height: 28pt;
|
||||
}
|
||||
.print-signature__caption {
|
||||
font-size: 9pt;
|
||||
color: #555;
|
||||
}
|
||||
|
||||
/* Header for offisielle rapporter — kommune-logo-slot */
|
||||
.print-header {
|
||||
display: grid;
|
||||
grid-template-columns: auto 1fr;
|
||||
gap: 14pt;
|
||||
align-items: center;
|
||||
padding-bottom: 10pt;
|
||||
margin-bottom: 16pt;
|
||||
border-bottom: 0.5pt solid #888;
|
||||
}
|
||||
.print-header__logo {
|
||||
width: 40pt; height: 40pt;
|
||||
border: 0.5pt solid #888;
|
||||
display: flex; align-items: center; justify-content: center;
|
||||
font-family: "Inter", sans-serif; font-size: 9pt; color: #888;
|
||||
}
|
||||
.print-header__meta { font-size: 9pt; color: #555; }
|
||||
.print-header__meta strong { color: #000; }
|
||||
|
||||
/* Avoid orphan headings */
|
||||
h2, h3, h4 { orphans: 3; widows: 3; }
|
||||
p, li { orphans: 2; widows: 2; }
|
||||
}
|
||||
|
||||
/* Screen-mode preview class — see print preview without actually printing */
|
||||
.preview-print { background: #ddd; padding: var(--space-8); }
|
||||
.preview-print .a4 {
|
||||
width: 210mm; min-height: 297mm;
|
||||
margin: 0 auto;
|
||||
background: #fff;
|
||||
padding: 22mm 18mm;
|
||||
box-shadow: 0 6px 24px rgba(0,0,0,0.18);
|
||||
font-size: 11pt; line-height: 1.45; color: #000;
|
||||
}
|
||||
.preview-print .a4 + .a4 { margin-top: 12mm; }
|
||||
88
plugins/ms-ai-architect/playground/vendor/playground-design-system/schemas/finding.schema.json
vendored
Normal file
88
plugins/ms-ai-architect/playground/vendor/playground-design-system/schemas/finding.schema.json
vendored
Normal file
|
|
@ -0,0 +1,88 @@
|
|||
{
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$id": "https://playground-ds.no/schemas/finding.json",
|
||||
"title": "Finding",
|
||||
"description": "Et enkelt funn fra en plugin-skanning. Brukes av llm-security, config-audit, ultraplan-review og ms-ai-review.",
|
||||
"type": "object",
|
||||
"required": ["id", "title", "severity", "source"],
|
||||
"properties": {
|
||||
"id": {
|
||||
"type": "string",
|
||||
"description": "Stabil ID, f.eks. DDT-2026-118-F-001",
|
||||
"pattern": "^[A-Z0-9-]{4,}$"
|
||||
},
|
||||
"title": { "type": "string", "minLength": 4, "maxLength": 140 },
|
||||
"severity": {
|
||||
"enum": ["info", "low", "medium", "high", "critical"],
|
||||
"description": "Standard 5-trinns skala. Maps til CSS-tokens --color-severity-*."
|
||||
},
|
||||
"score": {
|
||||
"type": "number", "minimum": 0, "maximum": 10,
|
||||
"description": "CVSS-lignende numerisk score. Valgfri — severity er primær."
|
||||
},
|
||||
"rules": {
|
||||
"type": "array",
|
||||
"items": { "type": "string", "pattern": "^[A-Z]{2,4}[0-9]{2}(\\.[0-9]+)?$" },
|
||||
"description": "Regler/categories truffet, f.eks. LLM01, ASI02, DDT01"
|
||||
},
|
||||
"source": {
|
||||
"type": "object",
|
||||
"required": ["kind", "ref"],
|
||||
"properties": {
|
||||
"kind": { "enum": ["document", "prompt-response", "code-file", "config-file", "okr-set"] },
|
||||
"ref": { "type": "string", "description": "Filnavn / URL / sak-ID" },
|
||||
"line": { "type": "integer", "minimum": 1 },
|
||||
"col": { "type": "integer", "minimum": 0 },
|
||||
"snippet": { "type": "string", "maxLength": 800 }
|
||||
}
|
||||
},
|
||||
"evidence": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"required": ["kind", "value"],
|
||||
"properties": {
|
||||
"kind": { "enum": ["text", "codepoint", "metric", "url", "image"] },
|
||||
"value": { "type": "string" },
|
||||
"label": { "type": "string" }
|
||||
}
|
||||
}
|
||||
},
|
||||
"rationale": { "type": "string", "description": "Norsk forklaring av hvorfor dette er et problem i denne konteksten" },
|
||||
"recommendation": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"summary": { "type": "string" },
|
||||
"steps": { "type": "array", "items": { "type": "string" } },
|
||||
"ttf": { "type": "string", "description": "Tid til løsning, f.eks. '2 t', '1 d', '5 d'" },
|
||||
"owner": { "type": "string", "description": "Foreslått eier (rolle eller person)" }
|
||||
}
|
||||
},
|
||||
"references": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"label": { "type": "string" },
|
||||
"url": { "type": "string", "format": "uri" }
|
||||
}
|
||||
}
|
||||
},
|
||||
"status": {
|
||||
"enum": ["new", "acknowledged", "in-progress", "fixed", "accepted-risk", "false-positive"],
|
||||
"default": "new"
|
||||
},
|
||||
"acceptance": {
|
||||
"type": "object",
|
||||
"description": "Påkrevd hvis status = accepted-risk og severity ≥ high",
|
||||
"properties": {
|
||||
"approver": { "type": "string" },
|
||||
"date": { "type": "string", "format": "date" },
|
||||
"rationale": { "type": "string" },
|
||||
"review_by": { "type": "string", "format": "date" }
|
||||
}
|
||||
},
|
||||
"created": { "type": "string", "format": "date-time" },
|
||||
"updated": { "type": "string", "format": "date-time" }
|
||||
}
|
||||
}
|
||||
78
plugins/ms-ai-architect/playground/vendor/playground-design-system/schemas/okr-set.schema.json
vendored
Normal file
78
plugins/ms-ai-architect/playground/vendor/playground-design-system/schemas/okr-set.schema.json
vendored
Normal file
|
|
@ -0,0 +1,78 @@
|
|||
{
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$id": "https://playground-ds.no/schemas/okr-set.json",
|
||||
"title": "OKR-sett",
|
||||
"description": "Et OKR-sett: ett mål (Objective) med 1–6 nøkkelresultater (KR). Brukes av OKR live-writer.",
|
||||
"type": "object",
|
||||
"required": ["id", "objective", "key_results", "owner", "period"],
|
||||
"properties": {
|
||||
"id": { "type": "string" },
|
||||
"owner": {
|
||||
"type": "object",
|
||||
"required": ["name", "unit"],
|
||||
"properties": {
|
||||
"name": { "type": "string" },
|
||||
"unit": { "type": "string", "description": "Avdeling/seksjon" },
|
||||
"org": { "type": "string", "description": "Kommune/etat" }
|
||||
}
|
||||
},
|
||||
"period": {
|
||||
"type": "object",
|
||||
"required": ["kind", "label", "start", "end"],
|
||||
"properties": {
|
||||
"kind": { "enum": ["tertial", "kvartal", "halvår", "år"] },
|
||||
"label": { "type": "string", "description": "f.eks. 'T2 2026'" },
|
||||
"start": { "type": "string", "format": "date" },
|
||||
"end": { "type": "string", "format": "date" }
|
||||
}
|
||||
},
|
||||
"objective": {
|
||||
"type": "object",
|
||||
"required": ["text"],
|
||||
"properties": {
|
||||
"text": { "type": "string", "minLength": 10, "maxLength": 240 },
|
||||
"rationale": { "type": "string" }
|
||||
}
|
||||
},
|
||||
"key_results": {
|
||||
"type": "array", "minItems": 1, "maxItems": 6,
|
||||
"items": {
|
||||
"type": "object",
|
||||
"required": ["id", "text"],
|
||||
"properties": {
|
||||
"id": { "type": "string", "pattern": "^KR[0-9]+$" },
|
||||
"text": { "type": "string" },
|
||||
"metric": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"name": { "type": "string" },
|
||||
"unit": { "type": "string", "description": "%, dager, kr, antall, …" },
|
||||
"baseline": { "type": "number" },
|
||||
"target": { "type": "number" },
|
||||
"stretch": { "type": "number" },
|
||||
"source": { "type": "string", "description": "KPI-katalog ref / Tableau-sett / etc." }
|
||||
}
|
||||
},
|
||||
"deadline": { "type": "string", "format": "date" }
|
||||
}
|
||||
}
|
||||
},
|
||||
"score": {
|
||||
"type": "object",
|
||||
"description": "Generert av OKR-writer ved kvalitetsanalyse",
|
||||
"properties": {
|
||||
"overall": { "type": "number", "minimum": 0, "maximum": 100 },
|
||||
"measurability": { "type": "number" },
|
||||
"specificity": { "type": "number" },
|
||||
"ambition": { "type": "number" },
|
||||
"actionability": { "type": "number" }
|
||||
}
|
||||
},
|
||||
"critiques": {
|
||||
"type": "array",
|
||||
"items": { "$ref": "https://playground-ds.no/schemas/finding.json" }
|
||||
},
|
||||
"version": { "type": "string", "description": "Semver eller utkast 0.4-stil" },
|
||||
"status": { "enum": ["draft", "in-review", "approved", "active", "closed"], "default": "draft" }
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,59 @@
|
|||
{
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$id": "https://playground-ds.no/schemas/ros-threat.json",
|
||||
"title": "ROS-trussel",
|
||||
"description": "Én identifisert trussel i en risiko- og sårbarhetsanalyse. NS 5814-justert.",
|
||||
"type": "object",
|
||||
"required": ["id", "title", "category", "inherent"],
|
||||
"properties": {
|
||||
"id": { "type": "string", "pattern": "^T-[0-9]{3,}$" },
|
||||
"title": { "type": "string" },
|
||||
"description": { "type": "string" },
|
||||
"category": {
|
||||
"enum": ["personvern", "informasjonssikkerhet", "datakvalitet",
|
||||
"compliance", "dataintegritet", "leverandørrisiko",
|
||||
"tilgjengelighet", "omdømme", "økonomi", "andre"]
|
||||
},
|
||||
"actors": {
|
||||
"type": "array",
|
||||
"items": { "enum": ["intern-bruker", "saksbehandler", "innbygger", "ekstern-aktør", "leverandør", "system", "ai-modell"] }
|
||||
},
|
||||
"inherent": {
|
||||
"type": "object",
|
||||
"required": ["likelihood", "consequence"],
|
||||
"properties": {
|
||||
"likelihood": { "type": "integer", "minimum": 1, "maximum": 5 },
|
||||
"consequence": { "type": "integer", "minimum": 1, "maximum": 5 },
|
||||
"rationale": { "type": "string" }
|
||||
}
|
||||
},
|
||||
"controls": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"required": ["id", "title"],
|
||||
"properties": {
|
||||
"id": { "type": "string", "pattern": "^M-[0-9]{3,}$" },
|
||||
"title": { "type": "string" },
|
||||
"kind": { "enum": ["preventiv", "deteksjon", "korreksjon", "policy", "opplæring", "teknisk"] },
|
||||
"status": { "enum": ["planlagt", "implementert", "validert", "ute-av-drift"] },
|
||||
"owner": { "type": "string" },
|
||||
"due": { "type": "string", "format": "date" }
|
||||
}
|
||||
}
|
||||
},
|
||||
"residual": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"likelihood": { "type": "integer", "minimum": 1, "maximum": 5 },
|
||||
"consequence": { "type": "integer", "minimum": 1, "maximum": 5 },
|
||||
"rationale": { "type": "string" }
|
||||
}
|
||||
},
|
||||
"regulatory_refs": {
|
||||
"type": "array",
|
||||
"items": { "type": "string", "description": "GDPR Art. 35, AI Act Art. 6, NS 5814, …" }
|
||||
},
|
||||
"status": { "enum": ["open", "mitigating", "monitored", "closed", "transferred"], "default": "open" }
|
||||
}
|
||||
}
|
||||
186
plugins/ms-ai-architect/playground/vendor/playground-design-system/tokens.css
vendored
Normal file
186
plugins/ms-ai-architect/playground/vendor/playground-design-system/tokens.css
vendored
Normal file
|
|
@ -0,0 +1,186 @@
|
|||
/* Code generated by sync-design-system.mjs; DO NOT EDIT. */
|
||||
/* =============================================================================
|
||||
Playground Design System — tokens.css
|
||||
v0.1 — Phase 1
|
||||
Aksel/Digdir-aligned. Norwegian public sector. WCAG 2.1 AA.
|
||||
============================================================================= */
|
||||
|
||||
:root {
|
||||
/* ---------- Typography -------------------------------------------------- */
|
||||
--font-family-sans: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", system-ui, sans-serif;
|
||||
--font-family-mono: "JetBrains Mono", "SF Mono", "Fira Code", ui-monospace, monospace;
|
||||
--font-family-serif: "Source Serif 4", Georgia, serif;
|
||||
|
||||
--font-size-xs: 13px;
|
||||
--font-size-sm: 15px;
|
||||
--font-size-md: 17px; /* body default */
|
||||
--font-size-lg: 19px;
|
||||
--font-size-xl: 23px;
|
||||
--font-size-2xl: 28px;
|
||||
--font-size-3xl: 34px;
|
||||
--font-size-4xl: 44px;
|
||||
|
||||
--line-height-tight: 1.2;
|
||||
--line-height-snug: 1.4;
|
||||
--line-height-normal: 1.55;
|
||||
--measure: 65ch;
|
||||
|
||||
--font-weight-regular: 400;
|
||||
--font-weight-medium: 500;
|
||||
--font-weight-semibold: 600;
|
||||
--font-weight-bold: 700;
|
||||
|
||||
/* ---------- Primary (Digdir) ------------------------------------------- */
|
||||
--color-primary-50: #E8F1FB;
|
||||
--color-primary-100: #C6DCF4;
|
||||
--color-primary-200: #9CC0EA;
|
||||
--color-primary-300: #6FA5DD;
|
||||
--color-primary-400: #3B83CB;
|
||||
--color-primary-500: #0062BA; /* Digdir blue */
|
||||
--color-primary-600: #00569F;
|
||||
--color-primary-700: #004A8F;
|
||||
--color-primary-800: #003A70;
|
||||
--color-primary-900: #002F5C;
|
||||
|
||||
/* ---------- Severity ramp (deuteranopia-safe) ------------------------- */
|
||||
--color-severity-low: #1A7F37;
|
||||
--color-severity-medium: #BF8700;
|
||||
--color-severity-high: #CC5A00;
|
||||
--color-severity-critical: #A40E26;
|
||||
--color-severity-extreme: #66050F;
|
||||
|
||||
/* Soft fills (matrix cells, badges) */
|
||||
--color-severity-low-soft: #DDF4E4;
|
||||
--color-severity-medium-soft: #FBF0CC;
|
||||
--color-severity-high-soft: #FCE0CC;
|
||||
--color-severity-critical-soft: #F8D7DC;
|
||||
--color-severity-extreme-soft: #E8C7CC;
|
||||
|
||||
/* Foreground on severity bg */
|
||||
--color-severity-low-on: #0E4A20;
|
||||
--color-severity-medium-on: #5C3F00;
|
||||
--color-severity-high-on: #5C2900;
|
||||
--color-severity-critical-on: #FFFFFF;
|
||||
--color-severity-extreme-on: #FFFFFF;
|
||||
|
||||
/* ---------- State (distinct from severity) --------------------------- */
|
||||
--color-state-success: #1A7F37;
|
||||
--color-state-warning: #BF8700;
|
||||
--color-state-failed: #7D1A1A; /* dark desaturated red — "broke" */
|
||||
--color-state-blocked: #5C2D91; /* purple — distinct */
|
||||
--color-state-info: #0969DA;
|
||||
--color-state-running: #BF8700;
|
||||
--color-state-queued: #6E7781;
|
||||
--color-state-pending: #4D7DAD;
|
||||
--color-state-done: #1A7F37;
|
||||
|
||||
/* ---------- Surface / background ------------------------------------- */
|
||||
--color-bg: #FBFAF7; /* warm off-white page */
|
||||
--color-bg-soft: #F4F2EC; /* subtle section */
|
||||
--color-surface: #FFFFFF;
|
||||
--color-surface-raised: #FFFFFF;
|
||||
--color-surface-sunken: #F1EEE7;
|
||||
--color-overlay: rgba(15, 18, 22, 0.45);
|
||||
|
||||
/* ---------- Border --------------------------------------------------- */
|
||||
--color-border-subtle: #E4E0D6;
|
||||
--color-border-moderate: #C8C2B3;
|
||||
--color-border-strong: #6E7781;
|
||||
--color-border-focus: #0062BA;
|
||||
|
||||
/* ---------- Text ----------------------------------------------------- */
|
||||
--color-text-primary: #1F2328;
|
||||
--color-text-secondary: #4D5663;
|
||||
--color-text-tertiary: #6E7781;
|
||||
--color-text-on-primary: #FFFFFF;
|
||||
--color-text-link: #00569F;
|
||||
--color-text-link-hover: #002F5C;
|
||||
|
||||
/* ---------- Plugin scope colors -------------------------------------- */
|
||||
--color-scope-architect: #0F6E76; /* ms-ai-architect — petrol */
|
||||
--color-scope-okr: #9A6700; /* OKR — amber */
|
||||
--color-scope-security: #A40E26; /* llm-security — crimson */
|
||||
--color-scope-ultraplan: #4338CA; /* ultraplan-local — indigo */
|
||||
--color-scope-config: #3F5963; /* config-audit — slate */
|
||||
|
||||
/* ---------- Spacing -------------------------------------------------- */
|
||||
--space-1: 4px;
|
||||
--space-2: 8px;
|
||||
--space-3: 12px;
|
||||
--space-4: 16px;
|
||||
--space-5: 20px;
|
||||
--space-6: 24px;
|
||||
--space-8: 32px;
|
||||
--space-10: 40px;
|
||||
--space-12: 48px;
|
||||
--space-16: 64px;
|
||||
--space-20: 80px;
|
||||
|
||||
/* ---------- Radius --------------------------------------------------- */
|
||||
--radius-sm: 3px;
|
||||
--radius-md: 5px;
|
||||
--radius-lg: 8px;
|
||||
--radius-pill: 999px;
|
||||
|
||||
/* ---------- Shadow --------------------------------------------------- */
|
||||
--shadow-sm: 0 1px 2px rgba(15, 18, 22, 0.04), 0 0 0 1px rgba(15, 18, 22, 0.04);
|
||||
--shadow-md: 0 2px 4px rgba(15, 18, 22, 0.06), 0 4px 12px rgba(15, 18, 22, 0.04);
|
||||
--shadow-lg: 0 4px 8px rgba(15, 18, 22, 0.06), 0 12px 32px rgba(15, 18, 22, 0.06);
|
||||
--shadow-focus: 0 0 0 3px rgba(0, 98, 186, 0.35);
|
||||
|
||||
/* ---------- Motion --------------------------------------------------- */
|
||||
--duration-instant: 100ms;
|
||||
--duration-fast: 150ms;
|
||||
--duration-normal: 250ms;
|
||||
--duration-slow: 400ms;
|
||||
--ease-default: cubic-bezier(0.2, 0, 0, 1);
|
||||
|
||||
/* ---------- Layout --------------------------------------------------- */
|
||||
--container-narrow: 720px;
|
||||
--container-default: 1080px;
|
||||
--container-wide: 1280px;
|
||||
--sidebar-width: 280px;
|
||||
}
|
||||
|
||||
[data-theme="dark"] {
|
||||
--color-bg: #0F1419;
|
||||
--color-bg-soft: #161B22;
|
||||
--color-surface: #1A2027;
|
||||
--color-surface-raised: #232A33;
|
||||
--color-surface-sunken: #0B1015;
|
||||
|
||||
--color-border-subtle: #2A323C;
|
||||
--color-border-moderate: #3B4452;
|
||||
--color-border-strong: #6E7781;
|
||||
|
||||
--color-text-primary: #E6EDF3;
|
||||
--color-text-secondary: #B0BAC4;
|
||||
--color-text-tertiary: #8B96A2;
|
||||
--color-text-link: #6FA5DD;
|
||||
--color-text-link-hover: #9CC0EA;
|
||||
|
||||
/* Severity soft fills tuned for dark surfaces */
|
||||
--color-severity-low-soft: #163322;
|
||||
--color-severity-medium-soft: #3A2C0A;
|
||||
--color-severity-high-soft: #3D260F;
|
||||
--color-severity-critical-soft: #3B0F18;
|
||||
--color-severity-extreme-soft: #2A0408;
|
||||
|
||||
--color-severity-low-on: #7FE0A0;
|
||||
--color-severity-medium-on: #F2C66B;
|
||||
--color-severity-high-on: #F09060;
|
||||
--color-severity-critical-on: #FFFFFF;
|
||||
--color-severity-extreme-on: #FFFFFF;
|
||||
|
||||
--shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.4), 0 0 0 1px rgba(255, 255, 255, 0.04);
|
||||
--shadow-md: 0 2px 4px rgba(0, 0, 0, 0.4), 0 4px 12px rgba(0, 0, 0, 0.3);
|
||||
--shadow-lg: 0 4px 8px rgba(0, 0, 0, 0.5), 0 12px 32px rgba(0, 0, 0, 0.4);
|
||||
--shadow-focus: 0 0 0 3px rgba(111, 165, 221, 0.45);
|
||||
}
|
||||
|
||||
/* Auto dark when no override */
|
||||
@media (prefers-color-scheme: dark) {
|
||||
:root:not([data-theme]) {
|
||||
color-scheme: dark;
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue