diff --git a/plugins/ms-ai-architect/playground/ms-ai-architect-playground.html b/plugins/ms-ai-architect/playground/ms-ai-architect-playground.html index aaab9d1..02d5387 100644 --- a/plugins/ms-ai-architect/playground/ms-ai-architect-playground.html +++ b/plugins/ms-ai-architect/playground/ms-ai-architect-playground.html @@ -49,8 +49,8 @@ setter eksplisitt display, som overstyrer HTMLs default [hidden] {display:none}. Globalt override slik at hidden-attributt faktisk skjuler elementet. */ [hidden] { display: none !important; } - .app-shell { max-width: 1200px; margin: 0 auto; padding: var(--space-6) var(--space-5); } - .app-shell--wide { max-width: 1400px; } + + /* .app-shell + .app-shell--wide hentet fra vendored DS v0.3 (tier3-supplement section 25) */ /* Topbar — vises på alle surfaces unntatt onboarding (uten projekt-kontekst) */ .topbar { display: flex; align-items: center; justify-content: space-between; padding: var(--space-3) var(--space-5); border-bottom: 1px solid var(--color-border-subtle); background: var(--color-surface); position: sticky; top: 0; z-index: 10; } @@ -68,13 +68,10 @@ .onboarding-header p { color: var(--color-text-secondary); margin: 0; max-width: 60ch; } .onboarding-groups { display: flex; flex-direction: column; gap: var(--space-3); margin-bottom: var(--space-6); } .onboarding-fields { display: flex; flex-direction: column; gap: var(--space-4); padding: var(--space-2) 0; } - .field-row { display: flex; flex-direction: column; gap: 6px; } - .field-label { font-size: var(--font-size-sm); font-weight: var(--font-weight-medium); color: var(--color-text-primary); } - .field-help { font-size: var(--font-size-xs); color: var(--color-text-tertiary); } - .multi-select { display: flex; flex-direction: column; gap: 4px; border: 0; padding: 0; margin: 0; } - .checkbox-row { display: inline-flex; align-items: center; gap: 8px; cursor: pointer; font-size: var(--font-size-sm); padding: 4px 0; } - .checkbox-row input { margin: 0; } - .required-mark { color: var(--color-severity-critical); margin-left: 2px; } + + /* Form-patterns (.field-row, .field-label, .field-help, .multi-select, + .checkbox-row, .required-mark) hentet fra vendored DS v0.3 (tier3-supplement section 21) */ + .onboarding-actions { display: flex; align-items: center; gap: var(--space-3); padding: var(--space-3) 0; flex-wrap: wrap; } .onboarding-help { font-size: var(--font-size-sm); color: var(--color-text-tertiary); } diff --git a/plugins/ms-ai-architect/playground/screenshots/v1.10.0/01-onboarding-empty-dark.png b/plugins/ms-ai-architect/playground/screenshots/v1.10.0/01-onboarding-empty-dark.png index 5da0b08..794227e 100644 Binary files a/plugins/ms-ai-architect/playground/screenshots/v1.10.0/01-onboarding-empty-dark.png and b/plugins/ms-ai-architect/playground/screenshots/v1.10.0/01-onboarding-empty-dark.png differ diff --git a/plugins/ms-ai-architect/playground/screenshots/v1.10.0/01-onboarding-empty-light.png b/plugins/ms-ai-architect/playground/screenshots/v1.10.0/01-onboarding-empty-light.png index e8ec2a4..f7852f9 100644 Binary files a/plugins/ms-ai-architect/playground/screenshots/v1.10.0/01-onboarding-empty-light.png and b/plugins/ms-ai-architect/playground/screenshots/v1.10.0/01-onboarding-empty-light.png differ diff --git a/plugins/ms-ai-architect/playground/screenshots/v1.10.0/02-project-rapporter-regulatory-dark.png b/plugins/ms-ai-architect/playground/screenshots/v1.10.0/02-project-rapporter-regulatory-dark.png index 5310613..12bd2e6 100644 Binary files a/plugins/ms-ai-architect/playground/screenshots/v1.10.0/02-project-rapporter-regulatory-dark.png and b/plugins/ms-ai-architect/playground/screenshots/v1.10.0/02-project-rapporter-regulatory-dark.png differ diff --git a/plugins/ms-ai-architect/playground/screenshots/v1.10.0/02-project-rapporter-regulatory-light.png b/plugins/ms-ai-architect/playground/screenshots/v1.10.0/02-project-rapporter-regulatory-light.png index 62edf71..9b96cd7 100644 Binary files a/plugins/ms-ai-architect/playground/screenshots/v1.10.0/02-project-rapporter-regulatory-light.png and b/plugins/ms-ai-architect/playground/screenshots/v1.10.0/02-project-rapporter-regulatory-light.png differ diff --git a/plugins/ms-ai-architect/playground/screenshots/v1.10.0/03-project-rapporter-documentation-dark.png b/plugins/ms-ai-architect/playground/screenshots/v1.10.0/03-project-rapporter-documentation-dark.png index b4b5dd7..a6af613 100644 Binary files a/plugins/ms-ai-architect/playground/screenshots/v1.10.0/03-project-rapporter-documentation-dark.png and b/plugins/ms-ai-architect/playground/screenshots/v1.10.0/03-project-rapporter-documentation-dark.png differ diff --git a/plugins/ms-ai-architect/playground/screenshots/v1.10.0/03-project-rapporter-documentation-light.png b/plugins/ms-ai-architect/playground/screenshots/v1.10.0/03-project-rapporter-documentation-light.png index db3c5da..f17360d 100644 Binary files a/plugins/ms-ai-architect/playground/screenshots/v1.10.0/03-project-rapporter-documentation-light.png and b/plugins/ms-ai-architect/playground/screenshots/v1.10.0/03-project-rapporter-documentation-light.png differ diff --git a/plugins/ms-ai-architect/playground/screenshots/v1.10.0/03-project-rapporter-economy-dark.png b/plugins/ms-ai-architect/playground/screenshots/v1.10.0/03-project-rapporter-economy-dark.png index 9b95a58..d5b8835 100644 Binary files a/plugins/ms-ai-architect/playground/screenshots/v1.10.0/03-project-rapporter-economy-dark.png and b/plugins/ms-ai-architect/playground/screenshots/v1.10.0/03-project-rapporter-economy-dark.png differ diff --git a/plugins/ms-ai-architect/playground/screenshots/v1.10.0/03-project-rapporter-economy-light.png b/plugins/ms-ai-architect/playground/screenshots/v1.10.0/03-project-rapporter-economy-light.png index 8c6ab5e..929cfb3 100644 Binary files a/plugins/ms-ai-architect/playground/screenshots/v1.10.0/03-project-rapporter-economy-light.png and b/plugins/ms-ai-architect/playground/screenshots/v1.10.0/03-project-rapporter-economy-light.png differ diff --git a/plugins/ms-ai-architect/playground/screenshots/v1.10.0/03-project-rapporter-security-dark.png b/plugins/ms-ai-architect/playground/screenshots/v1.10.0/03-project-rapporter-security-dark.png index 40a3192..14cb3ae 100644 Binary files a/plugins/ms-ai-architect/playground/screenshots/v1.10.0/03-project-rapporter-security-dark.png and b/plugins/ms-ai-architect/playground/screenshots/v1.10.0/03-project-rapporter-security-dark.png differ diff --git a/plugins/ms-ai-architect/playground/screenshots/v1.10.0/03-project-rapporter-security-light.png b/plugins/ms-ai-architect/playground/screenshots/v1.10.0/03-project-rapporter-security-light.png index 0c180d0..41acacd 100644 Binary files a/plugins/ms-ai-architect/playground/screenshots/v1.10.0/03-project-rapporter-security-light.png and b/plugins/ms-ai-architect/playground/screenshots/v1.10.0/03-project-rapporter-security-light.png differ diff --git a/plugins/ms-ai-architect/playground/screenshots/v1.10.0/03-project-rapporter-tool-dark.png b/plugins/ms-ai-architect/playground/screenshots/v1.10.0/03-project-rapporter-tool-dark.png index 9b3a462..1cd7175 100644 Binary files a/plugins/ms-ai-architect/playground/screenshots/v1.10.0/03-project-rapporter-tool-dark.png and b/plugins/ms-ai-architect/playground/screenshots/v1.10.0/03-project-rapporter-tool-dark.png differ diff --git a/plugins/ms-ai-architect/playground/screenshots/v1.10.0/03-project-rapporter-tool-light.png b/plugins/ms-ai-architect/playground/screenshots/v1.10.0/03-project-rapporter-tool-light.png index e439667..2f17fb4 100644 Binary files a/plugins/ms-ai-architect/playground/screenshots/v1.10.0/03-project-rapporter-tool-light.png and b/plugins/ms-ai-architect/playground/screenshots/v1.10.0/03-project-rapporter-tool-light.png differ diff --git a/plugins/ms-ai-architect/playground/screenshots/v1.10.0/04-project-oversikt-dark.png b/plugins/ms-ai-architect/playground/screenshots/v1.10.0/04-project-oversikt-dark.png index dd7ff54..c02322d 100644 Binary files a/plugins/ms-ai-architect/playground/screenshots/v1.10.0/04-project-oversikt-dark.png and b/plugins/ms-ai-architect/playground/screenshots/v1.10.0/04-project-oversikt-dark.png differ diff --git a/plugins/ms-ai-architect/playground/screenshots/v1.10.0/04-project-oversikt-light.png b/plugins/ms-ai-architect/playground/screenshots/v1.10.0/04-project-oversikt-light.png index dbb22a3..3b4064a 100644 Binary files a/plugins/ms-ai-architect/playground/screenshots/v1.10.0/04-project-oversikt-light.png and b/plugins/ms-ai-architect/playground/screenshots/v1.10.0/04-project-oversikt-light.png differ diff --git a/plugins/ms-ai-architect/playground/screenshots/v1.10.0/05-project-kontekst-dark.png b/plugins/ms-ai-architect/playground/screenshots/v1.10.0/05-project-kontekst-dark.png index c41607e..c652c80 100644 Binary files a/plugins/ms-ai-architect/playground/screenshots/v1.10.0/05-project-kontekst-dark.png and b/plugins/ms-ai-architect/playground/screenshots/v1.10.0/05-project-kontekst-dark.png differ diff --git a/plugins/ms-ai-architect/playground/screenshots/v1.10.0/05-project-kontekst-light.png b/plugins/ms-ai-architect/playground/screenshots/v1.10.0/05-project-kontekst-light.png index 293fa17..c48854e 100644 Binary files a/plugins/ms-ai-architect/playground/screenshots/v1.10.0/05-project-kontekst-light.png and b/plugins/ms-ai-architect/playground/screenshots/v1.10.0/05-project-kontekst-light.png differ diff --git a/plugins/ms-ai-architect/playground/screenshots/v1.10.0/06-project-eksport-dark.png b/plugins/ms-ai-architect/playground/screenshots/v1.10.0/06-project-eksport-dark.png index 96034c4..f57d145 100644 Binary files a/plugins/ms-ai-architect/playground/screenshots/v1.10.0/06-project-eksport-dark.png and b/plugins/ms-ai-architect/playground/screenshots/v1.10.0/06-project-eksport-dark.png differ diff --git a/plugins/ms-ai-architect/playground/screenshots/v1.10.0/06-project-eksport-light.png b/plugins/ms-ai-architect/playground/screenshots/v1.10.0/06-project-eksport-light.png index 2d8d92c..07c827f 100644 Binary files a/plugins/ms-ai-architect/playground/screenshots/v1.10.0/06-project-eksport-light.png and b/plugins/ms-ai-architect/playground/screenshots/v1.10.0/06-project-eksport-light.png differ diff --git a/plugins/ms-ai-architect/playground/screenshots/v1.10.0/07-home-dark.png b/plugins/ms-ai-architect/playground/screenshots/v1.10.0/07-home-dark.png index 064912e..67eb6a4 100644 Binary files a/plugins/ms-ai-architect/playground/screenshots/v1.10.0/07-home-dark.png and b/plugins/ms-ai-architect/playground/screenshots/v1.10.0/07-home-dark.png differ diff --git a/plugins/ms-ai-architect/playground/screenshots/v1.10.0/07-home-light.png b/plugins/ms-ai-architect/playground/screenshots/v1.10.0/07-home-light.png index 2d49660..fa3cb21 100644 Binary files a/plugins/ms-ai-architect/playground/screenshots/v1.10.0/07-home-light.png and b/plugins/ms-ai-architect/playground/screenshots/v1.10.0/07-home-light.png differ diff --git a/plugins/ms-ai-architect/playground/screenshots/v1.10.0/08-catalog-dark.png b/plugins/ms-ai-architect/playground/screenshots/v1.10.0/08-catalog-dark.png index 5847718..f8906cb 100644 Binary files a/plugins/ms-ai-architect/playground/screenshots/v1.10.0/08-catalog-dark.png and b/plugins/ms-ai-architect/playground/screenshots/v1.10.0/08-catalog-dark.png differ diff --git a/plugins/ms-ai-architect/playground/screenshots/v1.10.0/08-catalog-light.png b/plugins/ms-ai-architect/playground/screenshots/v1.10.0/08-catalog-light.png index a17c0b9..912cc08 100644 Binary files a/plugins/ms-ai-architect/playground/screenshots/v1.10.0/08-catalog-light.png and b/plugins/ms-ai-architect/playground/screenshots/v1.10.0/08-catalog-light.png differ diff --git a/plugins/ms-ai-architect/playground/screenshots/v1.10.0/09-onboarding-prefilled-dark.png b/plugins/ms-ai-architect/playground/screenshots/v1.10.0/09-onboarding-prefilled-dark.png index 814ad11..f123348 100644 Binary files a/plugins/ms-ai-architect/playground/screenshots/v1.10.0/09-onboarding-prefilled-dark.png and b/plugins/ms-ai-architect/playground/screenshots/v1.10.0/09-onboarding-prefilled-dark.png differ diff --git a/plugins/ms-ai-architect/playground/screenshots/v1.10.0/09-onboarding-prefilled-light.png b/plugins/ms-ai-architect/playground/screenshots/v1.10.0/09-onboarding-prefilled-light.png index e8ec2a4..f7852f9 100644 Binary files a/plugins/ms-ai-architect/playground/screenshots/v1.10.0/09-onboarding-prefilled-light.png and b/plugins/ms-ai-architect/playground/screenshots/v1.10.0/09-onboarding-prefilled-light.png differ diff --git a/plugins/ms-ai-architect/playground/vendor/playground-design-system/CHANGELOG.md b/plugins/ms-ai-architect/playground/vendor/playground-design-system/CHANGELOG.md index 4b0c89f..8ae80b3 100644 --- a/plugins/ms-ai-architect/playground/vendor/playground-design-system/CHANGELOG.md +++ b/plugins/ms-ai-architect/playground/vendor/playground-design-system/CHANGELOG.md @@ -1,5 +1,36 @@ # playground-design-system — CHANGELOG +## 0.3.0 — 2026-05-04 + +### Added — Playground/report-page foundation primitives (sections 13-25 in tier3-supplement) + +Generiske mønstre som tidligere ble definert inline i plugin-playgrounds (først i ms-ai-architect v1.10) er hoisted hit slik at alle 5 plugin-konsumenter (`ms-ai-architect`, `okr`, `llm-security`, `ultraplan-local`, `config-audit`) kan dele samme vokabular og visuelle profil. + +- **`.eyebrow` utility** — uppercase 11px monospace label med 0.08em letter-spacing. Bruk over seksjons-titler. +- **`.page__*` page-shell** (`.page__header`, `.page__header-main`, `.page__header-aside`, `.page__eyebrow`, `.page__title`, `.page__lede`, `.page__meta`) — standard rapport-side-header med eyebrow → h1 → lede → meta + verdict-slot side-by-side. Responsiv: kollapser til én kolonne under 720px. +- **`.key-stats` / `.key-stat`** — 2-5-kolonne responsivt grid av store tall-metrikker. `font-variant-numeric: tabular-nums`, `font-size-2xl` bold. Severity-modifiers (`.key-stat--critical/high/medium/low/positive/info`) tinter value-fargen. +- **`.verdict-pill-lg` 5-band utvidelse** — eksisterende `.verdict-pill-lg` aksepterer nå alle 5 severity-bånd: `critical/extreme/high/medium/low/positive` + neutral `n-a/info/neutral`. Bakoverkompatibel med eksisterende `block/warning/allow`. +- **`.tab-list` / `.tab` / `.tab-panel`** — generisk faneflate-komponent. ARIA-paritet: `role="tablist"`, `role="tab"`, `aria-current="true"`. `.tab__count` for badge-tall, `.tab-panel[hidden]` for skjuling. +- **`.top-risks` / `.top-risk[data-severity]`** — severity-ordnet liste over topp-risikoer med rank/desc/score-kolonner. Severity-attribut driver venstre-border + score-pill-bakgrunn. +- **`.recommendation-card[data-severity]`** — emphasized advisory-callout med label + body. 6 severity-modifiers. +- **`.card__*` subkomponenter** — komponerbare tillegg til eksisterende `.card` (base.css): `.card__head`, `.card__title`, `.card__desc`, `.card__id`, `.card__meta`, `.card__hint`, `.card__actions`, `.card__pill`. Pluss `.card--severity-{level}` for 4px venstre-border-modifier. +- **Form patterns** — `.field-row` (vertikal flex), `.field-label` (medium weight), `.field-help` (xs tertiary), `.required-mark` (severity-critical asterisk), `.multi-select` (fieldset reset), `.checkbox-row` (inline-flex med hover). Mirrors Aksel/Digdir form-konvensjoner. +- **Section-spacing utilities** — `.stack-lg` (margin-block: var(--space-8)), `.stack-md` (var(--space-5)), `.stack-sm` (var(--space-3)). Anvendes på parent for å gi konsistent vertikal rytme mellom barn-elementer. +- **`.pyramide-tier-detail`** — utvidbar `
`-blokk under `.pyramide`-visualisering. Custom chevron, ingen native marker. Brukes av AI Act-klassifiserings-renderer. +- **`.scenario-card-grid` / `.scenario-card[data-status="winner"]`** — auto-fit grid (minmax 240px) av scenario/alternativ-cards. Vinnerstatus får success-tinted bakgrunn + grønn count-pill. +- **`.app-shell` / `.app-shell--wide` / `.app-shell--narrow`** — sentralisert max-width page-wrapper. 1200/1400/880px varianter. + +### Notes for vendor consumers + +Versjon 0.3.0 er **rent additiv** — ingen eksisterende selector er endret eller fjernet. Alle eksisterende klasser (`.btn`, `.card`, `.expansion`, `.kanban-*`, `.mat-ladder`, `.read-more`, `.suppressed`, `.pair-before-after`, `.verdict-pill-lg` osv.) fungerer uendret. + +For å adoptere v0.3: +1. Re-sync via `node scripts/sync-design-system.mjs ` (kreves `--force` hvis eksisterende drift) +2. Oppdater plugin HTML til å bruke nye klasser i stedet for inline CSS +3. Andre plugins kan vente med adopsjon — eksisterende DS-bruk fortsetter å fungere + +Førsteadopter: `ms-ai-architect` v1.11.0 (planlagt 2026-05-04). + ## 0.2.0 — 2026-05-04 ### Added diff --git a/plugins/ms-ai-architect/playground/vendor/playground-design-system/MANIFEST.json b/plugins/ms-ai-architect/playground/vendor/playground-design-system/MANIFEST.json index 140fdd1..c27c8e1 100644 --- a/plugins/ms-ai-architect/playground/vendor/playground-design-system/MANIFEST.json +++ b/plugins/ms-ai-architect/playground/vendor/playground-design-system/MANIFEST.json @@ -2,15 +2,15 @@ "generated_by": "scripts/sync-design-system.mjs", "do_not_edit": true, "source": "shared/playground-design-system/", - "source_commit": "a5c12b68d9f1eba093c876f5bd33394f99d422ef", - "sync_date": "2026-05-04T01:03:31.587Z", + "source_commit": "e3378e9b9c8df259ba12f8146c44e5c18b40ff31", + "sync_date": "2026-05-04T07:56:18.490Z", "file_count": 26, "files": { - "CHANGELOG.md": "7e559e64a5e854c250b697696ca8d50bc81c7a683d1e5d77ce722d0f47329a32", + "CHANGELOG.md": "e293a911701e0ae8e95f8d30e2b583d1c578d0c2af4fd2abfbee3a7d65d5f7ba", "README.md": "83de0e29b207c979b7b2a3327b7a4ec0c2e1b4d3705ee2677f26c28c3a3ee643", "base.css": "604fe6839e2ed304bc0ba112a4e045f208b4b3f084f449a1abdb94ce0a1e5263", "components-tier2.css": "c2cb7e9d76d6af28d50db654030413777feb2f2f2b93213e598de8b686b14523", - "components-tier3-supplement.css": "5b70503ce81a4aefc269e894ab0ae0921ab48370a00de19c737354274f520387", + "components-tier3-supplement.css": "b78664275948f05b9cb4e577921695bd39d15b34c671809d8c8465cac4e1739b", "components-tier3.css": "c391ea387298ce864bc35078e7e044b2cdd4187e3130456347d91876599ff4b1", "components.css": "f76b22ba9fd64c2e806b4467536174347105f3e5ccca8a6349a919287d864b86", "fonts.css": "e3c3df581c6e4d66e25c555f125c745f6512a33038401089d2519a94ea63ee3d", diff --git a/plugins/ms-ai-architect/playground/vendor/playground-design-system/components-tier3-supplement.css b/plugins/ms-ai-architect/playground/vendor/playground-design-system/components-tier3-supplement.css index 00bbbb4..2ee9560 100644 --- a/plugins/ms-ai-architect/playground/vendor/playground-design-system/components-tier3-supplement.css +++ b/plugins/ms-ai-architect/playground/vendor/playground-design-system/components-tier3-supplement.css @@ -885,3 +885,571 @@ .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; } + +/* ============================================================================= + v0.3 ADDITIONS — playground/report-page foundation primitives. + Originally defined inline in plugin playgrounds (ms-ai-architect v1.10). + Hoisted here so all 5 plugin consumers share the same vocabulary. + ============================================================================= */ + +/* ========================================================================= + 13. Eyebrow utility (.eyebrow) + Uppercase mini-label above section titles. Mono, generous tracking. + ========================================================================= */ +.eyebrow { + display: inline-block; + font-family: var(--font-family-mono); + font-size: 11px; + font-weight: var(--font-weight-semibold); + letter-spacing: 0.08em; + text-transform: uppercase; + color: var(--color-scope-architect, var(--color-text-link)); + margin: 0 0 var(--space-2); +} + +/* ========================================================================= + 14. Page-shell (.page__*) + Standard report-page header used by renderPageShell() in playgrounds. + eyebrow → h1 → optional lede → optional meta + verdict slot side-by-side. + ========================================================================= */ +.page__header { + display: grid; + grid-template-columns: 1fr auto; + gap: var(--space-5); + align-items: start; + padding-block: var(--space-3) var(--space-4); + margin-bottom: var(--space-5); + border-bottom: 1px solid var(--color-border-subtle); +} +.page__header-main { min-width: 0; } +.page__header-aside { + display: flex; + flex-direction: column; + align-items: flex-end; + gap: var(--space-2); +} +.page__eyebrow { + display: inline-block; + font-family: var(--font-family-mono); + font-size: 11px; + font-weight: var(--font-weight-semibold); + letter-spacing: 0.08em; + text-transform: uppercase; + color: var(--color-scope-architect, var(--color-text-link)); + margin: 0 0 var(--space-2); +} +.page__title { + font-family: var(--font-family-sans); + font-size: var(--font-size-3xl); + font-weight: var(--font-weight-bold); + letter-spacing: -0.02em; + line-height: 1.15; + color: var(--color-text-primary); + margin: 0 0 var(--space-2); +} +.page__lede { + font-size: var(--font-size-md); + line-height: 1.55; + color: var(--color-text-secondary); + max-width: 70ch; + margin: 0 0 var(--space-2); +} +.page__meta { + font-family: var(--font-family-mono); + font-size: 12px; + color: var(--color-text-tertiary); + display: flex; + gap: var(--space-3); + flex-wrap: wrap; +} +@media (max-width: 720px) { + .page__header { grid-template-columns: 1fr; } + .page__header-aside { align-items: flex-start; } +} + +/* ========================================================================= + 15. Key-stats grid (.key-stats / .key-stat) + 2-5 column responsive grid of large-number metrics. Uses tabular-nums for + visual alignment. Severity modifiers tint the value color. + ========================================================================= */ +.key-stats { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); + gap: var(--space-4); + padding: var(--space-4) var(--space-5); + background: var(--color-bg-soft); + border: 1px solid var(--color-border-subtle); + border-radius: var(--radius-lg); + margin-block: var(--space-4); +} +.key-stat { + display: flex; + flex-direction: column; + gap: 4px; + min-width: 0; +} +.key-stat__label { + font-family: var(--font-family-mono); + font-size: 11px; + font-weight: var(--font-weight-semibold); + letter-spacing: 0.08em; + text-transform: uppercase; + color: var(--color-text-tertiary); +} +.key-stat__value { + font-family: var(--font-family-sans); + font-size: var(--font-size-2xl); + font-weight: var(--font-weight-bold); + letter-spacing: -0.02em; + font-variant-numeric: tabular-nums; + color: var(--color-text-primary); + line-height: 1.1; + word-break: break-word; +} +.key-stat__hint { + font-size: 12px; + color: var(--color-text-tertiary); + margin-top: 2px; +} +.key-stat--critical .key-stat__value { color: var(--color-severity-critical); } +.key-stat--high .key-stat__value { color: var(--color-severity-high); } +.key-stat--medium .key-stat__value { color: var(--color-severity-medium); } +.key-stat--low .key-stat__value { color: var(--color-severity-low); } +.key-stat--positive .key-stat__value { color: var(--color-state-success); } +.key-stat--info .key-stat__value { color: var(--color-state-info); } + +/* ========================================================================= + 16. Verdict-pill 5-band extension + Extends existing .verdict-pill-lg (Tier 2) to all 5 severity bands + + neutral n-a. Backward compatible — existing block/warning/allow keys + remain unchanged. + ========================================================================= */ +.verdict-pill-lg[data-verdict="critical"], +.verdict-pill-lg[data-verdict="extreme"] { background: var(--color-severity-critical); color: #fff; } +.verdict-pill-lg[data-verdict="high"] { background: var(--color-severity-high); color: #fff; } +.verdict-pill-lg[data-verdict="medium"] { background: var(--color-severity-medium); color: var(--color-severity-medium-on); } +.verdict-pill-lg[data-verdict="low"] { background: var(--color-severity-low); color: #fff; } +.verdict-pill-lg[data-verdict="positive"] { background: var(--color-state-success); color: #fff; } +.verdict-pill-lg[data-verdict="n-a"], +.verdict-pill-lg[data-verdict="info"], +.verdict-pill-lg[data-verdict="neutral"] { + background: var(--color-surface-sunken); + color: var(--color-text-secondary); + border: 1px solid var(--color-border-moderate); +} + +/* ========================================================================= + 17. Tab-component (.tab-list / .tab / .tab-panel) + Generic tabbed interface. ARIA-paritet: role="tablist", role="tab", + aria-current="true" for active. tab-panel is hidden via [hidden] attr. + ========================================================================= */ +.tab-list { + display: flex; + gap: var(--space-1); + flex-wrap: wrap; + padding: 4px; + background: var(--color-bg-soft); + border: 1px solid var(--color-border-subtle); + border-radius: var(--radius-md); + margin-bottom: var(--space-4); +} +.tab { + appearance: none; + border: 1px solid transparent; + background: transparent; + color: var(--color-text-secondary); + font-family: var(--font-family-sans); + font-size: var(--font-size-sm); + font-weight: var(--font-weight-medium); + padding: 6px var(--space-3); + border-radius: var(--radius-sm); + cursor: pointer; + display: inline-flex; + align-items: center; + gap: 6px; + transition: background var(--duration-fast), color var(--duration-fast); +} +.tab:hover { background: var(--color-surface-sunken); color: var(--color-text-primary); } +.tab[aria-current="true"] { + background: var(--color-surface); + color: var(--color-text-primary); + border-color: var(--color-border-subtle); + box-shadow: var(--shadow-sm); +} +.tab:focus-visible { outline: none; box-shadow: var(--shadow-focus); } +.tab__count { + display: inline-flex; + align-items: center; + justify-content: center; + min-width: 22px; + padding: 0 6px; + font-family: var(--font-family-mono); + font-size: 11px; + background: var(--color-surface-sunken); + color: var(--color-text-tertiary); + border-radius: 999px; +} +.tab[aria-current="true"] .tab__count { + background: var(--color-bg-soft); + color: var(--color-text-primary); +} +.tab-panel { padding-block: var(--space-3); } +.tab-panel[hidden] { display: none; } + +/* ========================================================================= + 18. Top-risks (.top-risks / .top-risk) + Severity-ordered list of top risk items used by ROS/security renderers. + Each row: rank dot - description - score column. Severity drives left-border. + ========================================================================= */ +.top-risks { + display: flex; + flex-direction: column; + gap: var(--space-2); + margin-block: var(--space-4); +} +.top-risks__heading { + font-family: var(--font-family-mono); + font-size: 11px; + font-weight: var(--font-weight-semibold); + letter-spacing: 0.08em; + text-transform: uppercase; + color: var(--color-text-tertiary); + margin: 0 0 var(--space-1); +} +.top-risk { + display: grid; + grid-template-columns: 32px 1fr auto; + gap: var(--space-3); + align-items: center; + padding: var(--space-3) var(--space-4); + background: var(--color-surface); + border: 1px solid var(--color-border-subtle); + border-left: 4px solid var(--color-border-moderate); + border-radius: var(--radius-md); +} +.top-risk[data-severity="critical"] { border-left-color: var(--color-severity-critical); } +.top-risk[data-severity="high"] { border-left-color: var(--color-severity-high); } +.top-risk[data-severity="medium"] { border-left-color: var(--color-severity-medium); } +.top-risk[data-severity="low"] { border-left-color: var(--color-severity-low); } +.top-risk__rank { + font-family: var(--font-family-mono); + font-size: var(--font-size-md); + font-weight: var(--font-weight-bold); + color: var(--color-text-tertiary); + text-align: center; +} +.top-risk__desc { + font-size: var(--font-size-md); + line-height: 1.4; + color: var(--color-text-primary); + min-width: 0; +} +.top-risk__score { + font-family: var(--font-family-mono); + font-size: var(--font-size-sm); + font-weight: var(--font-weight-bold); + font-variant-numeric: tabular-nums; + padding: 4px 10px; + border-radius: var(--radius-sm); + background: var(--color-bg-soft); + color: var(--color-text-primary); + white-space: nowrap; +} +.top-risk[data-severity="critical"] .top-risk__score { background: var(--color-severity-critical-soft); color: var(--color-severity-critical-on); } +.top-risk[data-severity="high"] .top-risk__score { background: var(--color-severity-high-soft); color: var(--color-severity-high-on); } +.top-risk[data-severity="medium"] .top-risk__score { background: var(--color-severity-medium-soft); color: var(--color-severity-medium-on); } +.top-risk[data-severity="low"] .top-risk__score { background: var(--color-severity-low-soft); color: var(--color-severity-low-on); } + +/* ========================================================================= + 19. Recommendation-card (.recommendation-card) + Emphasized advisory callout. Severity-tinted background + bold label. + Used by security/ROS recommendations and architecture-review next-actions. + ========================================================================= */ +.recommendation-card { + display: grid; + grid-template-columns: auto 1fr; + gap: var(--space-3); + align-items: start; + padding: var(--space-4) var(--space-5); + background: var(--color-bg-soft); + border: 1px solid var(--color-border-subtle); + border-left: 4px solid var(--color-state-info); + border-radius: var(--radius-md); + margin-block: var(--space-3); +} +.recommendation-card__label { + font-family: var(--font-family-mono); + font-size: 11px; + font-weight: var(--font-weight-bold); + letter-spacing: 0.08em; + text-transform: uppercase; + padding: 4px 10px; + border-radius: var(--radius-sm); + background: var(--color-state-info); + color: #fff; + white-space: nowrap; +} +.recommendation-card__body { + font-size: var(--font-size-md); + line-height: 1.55; + color: var(--color-text-primary); +} +.recommendation-card[data-severity="critical"] { border-left-color: var(--color-severity-critical); } +.recommendation-card[data-severity="critical"] .recommendation-card__label { background: var(--color-severity-critical); } +.recommendation-card[data-severity="high"] { border-left-color: var(--color-severity-high); } +.recommendation-card[data-severity="high"] .recommendation-card__label { background: var(--color-severity-high); } +.recommendation-card[data-severity="medium"] { border-left-color: var(--color-severity-medium); } +.recommendation-card[data-severity="medium"] .recommendation-card__label { background: var(--color-severity-medium); color: var(--color-severity-medium-on); } +.recommendation-card[data-severity="low"] { border-left-color: var(--color-severity-low); } +.recommendation-card[data-severity="low"] .recommendation-card__label { background: var(--color-severity-low); } +.recommendation-card[data-severity="positive"] { border-left-color: var(--color-state-success); } +.recommendation-card[data-severity="positive"] .recommendation-card__label { background: var(--color-state-success); } + +/* ========================================================================= + 20. Card subcomponents (.card__*) + Composable subcomponents extending the existing .card primitive (base.css). + Use as:
...
...
+ ========================================================================= */ +.card__head { + display: flex; + align-items: flex-start; + justify-content: space-between; + gap: var(--space-3); + margin-bottom: var(--space-2); +} +.card__title { + font-family: var(--font-family-sans); + font-size: var(--font-size-lg); + font-weight: var(--font-weight-semibold); + letter-spacing: -0.01em; + color: var(--color-text-primary); + margin: 0; + line-height: 1.3; +} +.card__desc { + font-size: var(--font-size-sm); + line-height: 1.5; + color: var(--color-text-secondary); + margin: 0 0 var(--space-2); +} +.card__id { + font-family: var(--font-family-mono); + font-size: 12px; + color: var(--color-text-tertiary); + background: var(--color-surface-sunken); + padding: 2px 8px; + border-radius: var(--radius-sm); + display: inline-block; +} +.card__meta { + display: flex; + gap: var(--space-2); + align-items: center; + flex-wrap: wrap; + font-size: 12px; + color: var(--color-text-tertiary); + margin-top: var(--space-2); +} +.card__hint { + font-family: var(--font-family-mono); + font-size: 12px; + color: var(--color-text-tertiary); + margin-top: var(--space-1); +} +.card__actions { + display: flex; + gap: var(--space-2); + align-items: center; + flex-wrap: wrap; + margin-top: var(--space-3); +} +.card__pill { + display: inline-flex; + align-items: center; + padding: 2px 8px; + font-family: var(--font-family-mono); + font-size: 11px; + font-weight: var(--font-weight-semibold); + letter-spacing: 0.04em; + text-transform: uppercase; + background: var(--color-surface-sunken); + color: var(--color-text-secondary); + border-radius: 999px; + white-space: nowrap; +} + +/* Severity left-border modifier on cards */ +.card--severity-critical { border-left: 4px solid var(--color-severity-critical); } +.card--severity-high { border-left: 4px solid var(--color-severity-high); } +.card--severity-medium { border-left: 4px solid var(--color-severity-medium); } +.card--severity-low { border-left: 4px solid var(--color-severity-low); } +.card--severity-positive { border-left: 4px solid var(--color-state-success); } +.card--severity-info { border-left: 4px solid var(--color-state-info); } + +/* ========================================================================= + 21. Form patterns (.field-row / .field-label / .field-help / etc) + Standard form-field building blocks. Mirrors Aksel/Digdir conventions. + ========================================================================= */ +.field-row { + display: flex; + flex-direction: column; + gap: 6px; +} +.field-row + .field-row { margin-top: var(--space-3); } +.field-label { + font-size: var(--font-size-sm); + font-weight: var(--font-weight-medium); + color: var(--color-text-primary); +} +.field-help { + font-size: var(--font-size-xs); + color: var(--color-text-tertiary); +} +.required-mark { + color: var(--color-severity-critical); + margin-left: 2px; + font-weight: var(--font-weight-bold); +} +.multi-select { + display: flex; + flex-direction: column; + gap: 4px; + border: 0; + padding: 0; + margin: 0; +} +.checkbox-row { + display: inline-flex; + align-items: center; + gap: 8px; + cursor: pointer; + font-size: var(--font-size-sm); + padding: 4px 0; + color: var(--color-text-primary); +} +.checkbox-row input { margin: 0; } +.checkbox-row:hover { color: var(--color-text-link); } + +/* ========================================================================= + 22. Section-spacing utility (.stack-lg / .stack-md / .stack-sm) + Consistent vertical rhythm between major sections. + ========================================================================= */ +.stack-lg > * + * { margin-top: var(--space-8); } +.stack-md > * + * { margin-top: var(--space-5); } +.stack-sm > * + * { margin-top: var(--space-3); } + +/* ========================================================================= + 23. Pyramide-tier-detail (.pyramide-tier-detail) + Expandable details below a .pyramide visualization. Used by AI Act + classification renderer to describe each tier's obligations. + ========================================================================= */ +.pyramide-tier-detail { + background: var(--color-surface); + border: 1px solid var(--color-border-subtle); + border-radius: var(--radius-md); + padding: var(--space-3) var(--space-4); + margin-top: var(--space-2); +} +.pyramide-tier-detail summary { + cursor: pointer; + font-family: var(--font-family-sans); + font-size: var(--font-size-md); + font-weight: var(--font-weight-semibold); + color: var(--color-text-primary); + list-style: none; + display: flex; + align-items: center; + gap: var(--space-2); +} +.pyramide-tier-detail summary::-webkit-details-marker { display: none; } +.pyramide-tier-detail summary::before { + content: "\25B8"; + font-size: 11px; + color: var(--color-text-tertiary); + transition: transform var(--duration-fast); + display: inline-block; +} +.pyramide-tier-detail[open] summary::before { transform: rotate(90deg); } +.pyramide-tier-detail__body { + font-size: var(--font-size-sm); + line-height: 1.55; + color: var(--color-text-secondary); + margin-top: var(--space-2); + padding-left: var(--space-3); +} + +/* ========================================================================= + 24. Scenario-card-grid (.scenario-card-grid / .scenario-card) + Grid of scenario/option cards used by license, compare renderers. + Each card: header (title + count) -> optional source line -> optional body. + ========================================================================= */ +.scenario-card-grid { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); + gap: var(--space-3); + margin-block: var(--space-3); +} +.scenario-card { + display: flex; + flex-direction: column; + gap: var(--space-2); + padding: var(--space-4); + background: var(--color-surface); + border: 1px solid var(--color-border-subtle); + border-radius: var(--radius-md); + transition: border-color var(--duration-fast), box-shadow var(--duration-fast); +} +.scenario-card:hover { border-color: var(--color-border-moderate); box-shadow: var(--shadow-sm); } +.scenario-card__head { + display: flex; + align-items: flex-start; + justify-content: space-between; + gap: var(--space-2); +} +.scenario-card__title { + font-family: var(--font-family-sans); + font-size: var(--font-size-md); + font-weight: var(--font-weight-semibold); + color: var(--color-text-primary); + margin: 0; + line-height: 1.3; +} +.scenario-card__count { + display: inline-flex; + align-items: center; + justify-content: center; + min-width: 24px; + padding: 2px 8px; + font-family: var(--font-family-mono); + font-size: 11px; + font-weight: var(--font-weight-bold); + background: var(--color-bg-soft); + color: var(--color-text-secondary); + border-radius: 999px; +} +.scenario-card__source { + font-family: var(--font-family-mono); + font-size: 12px; + color: var(--color-text-tertiary); +} +.scenario-card[data-status="winner"] { + border-color: var(--color-state-success); + background: var(--color-severity-low-soft); +} +.scenario-card[data-status="winner"] .scenario-card__count { + background: var(--color-state-success); + color: #fff; +} + +/* ========================================================================= + 25. App-shell utility (.app-shell) + Centered max-width page wrapper. Hoisted from playgrounds - every plugin + playground uses the same shell pattern. + ========================================================================= */ +.app-shell { + max-width: 1200px; + margin: 0 auto; + padding: var(--space-6) var(--space-5); +} +.app-shell--wide { max-width: 1400px; } +.app-shell--narrow { max-width: 880px; } diff --git a/shared/playground-design-system/CHANGELOG.md b/shared/playground-design-system/CHANGELOG.md index 4b0c89f..8ae80b3 100644 --- a/shared/playground-design-system/CHANGELOG.md +++ b/shared/playground-design-system/CHANGELOG.md @@ -1,5 +1,36 @@ # playground-design-system — CHANGELOG +## 0.3.0 — 2026-05-04 + +### Added — Playground/report-page foundation primitives (sections 13-25 in tier3-supplement) + +Generiske mønstre som tidligere ble definert inline i plugin-playgrounds (først i ms-ai-architect v1.10) er hoisted hit slik at alle 5 plugin-konsumenter (`ms-ai-architect`, `okr`, `llm-security`, `ultraplan-local`, `config-audit`) kan dele samme vokabular og visuelle profil. + +- **`.eyebrow` utility** — uppercase 11px monospace label med 0.08em letter-spacing. Bruk over seksjons-titler. +- **`.page__*` page-shell** (`.page__header`, `.page__header-main`, `.page__header-aside`, `.page__eyebrow`, `.page__title`, `.page__lede`, `.page__meta`) — standard rapport-side-header med eyebrow → h1 → lede → meta + verdict-slot side-by-side. Responsiv: kollapser til én kolonne under 720px. +- **`.key-stats` / `.key-stat`** — 2-5-kolonne responsivt grid av store tall-metrikker. `font-variant-numeric: tabular-nums`, `font-size-2xl` bold. Severity-modifiers (`.key-stat--critical/high/medium/low/positive/info`) tinter value-fargen. +- **`.verdict-pill-lg` 5-band utvidelse** — eksisterende `.verdict-pill-lg` aksepterer nå alle 5 severity-bånd: `critical/extreme/high/medium/low/positive` + neutral `n-a/info/neutral`. Bakoverkompatibel med eksisterende `block/warning/allow`. +- **`.tab-list` / `.tab` / `.tab-panel`** — generisk faneflate-komponent. ARIA-paritet: `role="tablist"`, `role="tab"`, `aria-current="true"`. `.tab__count` for badge-tall, `.tab-panel[hidden]` for skjuling. +- **`.top-risks` / `.top-risk[data-severity]`** — severity-ordnet liste over topp-risikoer med rank/desc/score-kolonner. Severity-attribut driver venstre-border + score-pill-bakgrunn. +- **`.recommendation-card[data-severity]`** — emphasized advisory-callout med label + body. 6 severity-modifiers. +- **`.card__*` subkomponenter** — komponerbare tillegg til eksisterende `.card` (base.css): `.card__head`, `.card__title`, `.card__desc`, `.card__id`, `.card__meta`, `.card__hint`, `.card__actions`, `.card__pill`. Pluss `.card--severity-{level}` for 4px venstre-border-modifier. +- **Form patterns** — `.field-row` (vertikal flex), `.field-label` (medium weight), `.field-help` (xs tertiary), `.required-mark` (severity-critical asterisk), `.multi-select` (fieldset reset), `.checkbox-row` (inline-flex med hover). Mirrors Aksel/Digdir form-konvensjoner. +- **Section-spacing utilities** — `.stack-lg` (margin-block: var(--space-8)), `.stack-md` (var(--space-5)), `.stack-sm` (var(--space-3)). Anvendes på parent for å gi konsistent vertikal rytme mellom barn-elementer. +- **`.pyramide-tier-detail`** — utvidbar `
`-blokk under `.pyramide`-visualisering. Custom chevron, ingen native marker. Brukes av AI Act-klassifiserings-renderer. +- **`.scenario-card-grid` / `.scenario-card[data-status="winner"]`** — auto-fit grid (minmax 240px) av scenario/alternativ-cards. Vinnerstatus får success-tinted bakgrunn + grønn count-pill. +- **`.app-shell` / `.app-shell--wide` / `.app-shell--narrow`** — sentralisert max-width page-wrapper. 1200/1400/880px varianter. + +### Notes for vendor consumers + +Versjon 0.3.0 er **rent additiv** — ingen eksisterende selector er endret eller fjernet. Alle eksisterende klasser (`.btn`, `.card`, `.expansion`, `.kanban-*`, `.mat-ladder`, `.read-more`, `.suppressed`, `.pair-before-after`, `.verdict-pill-lg` osv.) fungerer uendret. + +For å adoptere v0.3: +1. Re-sync via `node scripts/sync-design-system.mjs ` (kreves `--force` hvis eksisterende drift) +2. Oppdater plugin HTML til å bruke nye klasser i stedet for inline CSS +3. Andre plugins kan vente med adopsjon — eksisterende DS-bruk fortsetter å fungere + +Førsteadopter: `ms-ai-architect` v1.11.0 (planlagt 2026-05-04). + ## 0.2.0 — 2026-05-04 ### Added diff --git a/shared/playground-design-system/components-tier3-supplement.css b/shared/playground-design-system/components-tier3-supplement.css index cfdf9fc..2e3be2b 100644 --- a/shared/playground-design-system/components-tier3-supplement.css +++ b/shared/playground-design-system/components-tier3-supplement.css @@ -884,3 +884,571 @@ .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; } + +/* ============================================================================= + v0.3 ADDITIONS — playground/report-page foundation primitives. + Originally defined inline in plugin playgrounds (ms-ai-architect v1.10). + Hoisted here so all 5 plugin consumers share the same vocabulary. + ============================================================================= */ + +/* ========================================================================= + 13. Eyebrow utility (.eyebrow) + Uppercase mini-label above section titles. Mono, generous tracking. + ========================================================================= */ +.eyebrow { + display: inline-block; + font-family: var(--font-family-mono); + font-size: 11px; + font-weight: var(--font-weight-semibold); + letter-spacing: 0.08em; + text-transform: uppercase; + color: var(--color-scope-architect, var(--color-text-link)); + margin: 0 0 var(--space-2); +} + +/* ========================================================================= + 14. Page-shell (.page__*) + Standard report-page header used by renderPageShell() in playgrounds. + eyebrow → h1 → optional lede → optional meta + verdict slot side-by-side. + ========================================================================= */ +.page__header { + display: grid; + grid-template-columns: 1fr auto; + gap: var(--space-5); + align-items: start; + padding-block: var(--space-3) var(--space-4); + margin-bottom: var(--space-5); + border-bottom: 1px solid var(--color-border-subtle); +} +.page__header-main { min-width: 0; } +.page__header-aside { + display: flex; + flex-direction: column; + align-items: flex-end; + gap: var(--space-2); +} +.page__eyebrow { + display: inline-block; + font-family: var(--font-family-mono); + font-size: 11px; + font-weight: var(--font-weight-semibold); + letter-spacing: 0.08em; + text-transform: uppercase; + color: var(--color-scope-architect, var(--color-text-link)); + margin: 0 0 var(--space-2); +} +.page__title { + font-family: var(--font-family-sans); + font-size: var(--font-size-3xl); + font-weight: var(--font-weight-bold); + letter-spacing: -0.02em; + line-height: 1.15; + color: var(--color-text-primary); + margin: 0 0 var(--space-2); +} +.page__lede { + font-size: var(--font-size-md); + line-height: 1.55; + color: var(--color-text-secondary); + max-width: 70ch; + margin: 0 0 var(--space-2); +} +.page__meta { + font-family: var(--font-family-mono); + font-size: 12px; + color: var(--color-text-tertiary); + display: flex; + gap: var(--space-3); + flex-wrap: wrap; +} +@media (max-width: 720px) { + .page__header { grid-template-columns: 1fr; } + .page__header-aside { align-items: flex-start; } +} + +/* ========================================================================= + 15. Key-stats grid (.key-stats / .key-stat) + 2-5 column responsive grid of large-number metrics. Uses tabular-nums for + visual alignment. Severity modifiers tint the value color. + ========================================================================= */ +.key-stats { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); + gap: var(--space-4); + padding: var(--space-4) var(--space-5); + background: var(--color-bg-soft); + border: 1px solid var(--color-border-subtle); + border-radius: var(--radius-lg); + margin-block: var(--space-4); +} +.key-stat { + display: flex; + flex-direction: column; + gap: 4px; + min-width: 0; +} +.key-stat__label { + font-family: var(--font-family-mono); + font-size: 11px; + font-weight: var(--font-weight-semibold); + letter-spacing: 0.08em; + text-transform: uppercase; + color: var(--color-text-tertiary); +} +.key-stat__value { + font-family: var(--font-family-sans); + font-size: var(--font-size-2xl); + font-weight: var(--font-weight-bold); + letter-spacing: -0.02em; + font-variant-numeric: tabular-nums; + color: var(--color-text-primary); + line-height: 1.1; + word-break: break-word; +} +.key-stat__hint { + font-size: 12px; + color: var(--color-text-tertiary); + margin-top: 2px; +} +.key-stat--critical .key-stat__value { color: var(--color-severity-critical); } +.key-stat--high .key-stat__value { color: var(--color-severity-high); } +.key-stat--medium .key-stat__value { color: var(--color-severity-medium); } +.key-stat--low .key-stat__value { color: var(--color-severity-low); } +.key-stat--positive .key-stat__value { color: var(--color-state-success); } +.key-stat--info .key-stat__value { color: var(--color-state-info); } + +/* ========================================================================= + 16. Verdict-pill 5-band extension + Extends existing .verdict-pill-lg (Tier 2) to all 5 severity bands + + neutral n-a. Backward compatible — existing block/warning/allow keys + remain unchanged. + ========================================================================= */ +.verdict-pill-lg[data-verdict="critical"], +.verdict-pill-lg[data-verdict="extreme"] { background: var(--color-severity-critical); color: #fff; } +.verdict-pill-lg[data-verdict="high"] { background: var(--color-severity-high); color: #fff; } +.verdict-pill-lg[data-verdict="medium"] { background: var(--color-severity-medium); color: var(--color-severity-medium-on); } +.verdict-pill-lg[data-verdict="low"] { background: var(--color-severity-low); color: #fff; } +.verdict-pill-lg[data-verdict="positive"] { background: var(--color-state-success); color: #fff; } +.verdict-pill-lg[data-verdict="n-a"], +.verdict-pill-lg[data-verdict="info"], +.verdict-pill-lg[data-verdict="neutral"] { + background: var(--color-surface-sunken); + color: var(--color-text-secondary); + border: 1px solid var(--color-border-moderate); +} + +/* ========================================================================= + 17. Tab-component (.tab-list / .tab / .tab-panel) + Generic tabbed interface. ARIA-paritet: role="tablist", role="tab", + aria-current="true" for active. tab-panel is hidden via [hidden] attr. + ========================================================================= */ +.tab-list { + display: flex; + gap: var(--space-1); + flex-wrap: wrap; + padding: 4px; + background: var(--color-bg-soft); + border: 1px solid var(--color-border-subtle); + border-radius: var(--radius-md); + margin-bottom: var(--space-4); +} +.tab { + appearance: none; + border: 1px solid transparent; + background: transparent; + color: var(--color-text-secondary); + font-family: var(--font-family-sans); + font-size: var(--font-size-sm); + font-weight: var(--font-weight-medium); + padding: 6px var(--space-3); + border-radius: var(--radius-sm); + cursor: pointer; + display: inline-flex; + align-items: center; + gap: 6px; + transition: background var(--duration-fast), color var(--duration-fast); +} +.tab:hover { background: var(--color-surface-sunken); color: var(--color-text-primary); } +.tab[aria-current="true"] { + background: var(--color-surface); + color: var(--color-text-primary); + border-color: var(--color-border-subtle); + box-shadow: var(--shadow-sm); +} +.tab:focus-visible { outline: none; box-shadow: var(--shadow-focus); } +.tab__count { + display: inline-flex; + align-items: center; + justify-content: center; + min-width: 22px; + padding: 0 6px; + font-family: var(--font-family-mono); + font-size: 11px; + background: var(--color-surface-sunken); + color: var(--color-text-tertiary); + border-radius: 999px; +} +.tab[aria-current="true"] .tab__count { + background: var(--color-bg-soft); + color: var(--color-text-primary); +} +.tab-panel { padding-block: var(--space-3); } +.tab-panel[hidden] { display: none; } + +/* ========================================================================= + 18. Top-risks (.top-risks / .top-risk) + Severity-ordered list of top risk items used by ROS/security renderers. + Each row: rank dot - description - score column. Severity drives left-border. + ========================================================================= */ +.top-risks { + display: flex; + flex-direction: column; + gap: var(--space-2); + margin-block: var(--space-4); +} +.top-risks__heading { + font-family: var(--font-family-mono); + font-size: 11px; + font-weight: var(--font-weight-semibold); + letter-spacing: 0.08em; + text-transform: uppercase; + color: var(--color-text-tertiary); + margin: 0 0 var(--space-1); +} +.top-risk { + display: grid; + grid-template-columns: 32px 1fr auto; + gap: var(--space-3); + align-items: center; + padding: var(--space-3) var(--space-4); + background: var(--color-surface); + border: 1px solid var(--color-border-subtle); + border-left: 4px solid var(--color-border-moderate); + border-radius: var(--radius-md); +} +.top-risk[data-severity="critical"] { border-left-color: var(--color-severity-critical); } +.top-risk[data-severity="high"] { border-left-color: var(--color-severity-high); } +.top-risk[data-severity="medium"] { border-left-color: var(--color-severity-medium); } +.top-risk[data-severity="low"] { border-left-color: var(--color-severity-low); } +.top-risk__rank { + font-family: var(--font-family-mono); + font-size: var(--font-size-md); + font-weight: var(--font-weight-bold); + color: var(--color-text-tertiary); + text-align: center; +} +.top-risk__desc { + font-size: var(--font-size-md); + line-height: 1.4; + color: var(--color-text-primary); + min-width: 0; +} +.top-risk__score { + font-family: var(--font-family-mono); + font-size: var(--font-size-sm); + font-weight: var(--font-weight-bold); + font-variant-numeric: tabular-nums; + padding: 4px 10px; + border-radius: var(--radius-sm); + background: var(--color-bg-soft); + color: var(--color-text-primary); + white-space: nowrap; +} +.top-risk[data-severity="critical"] .top-risk__score { background: var(--color-severity-critical-soft); color: var(--color-severity-critical-on); } +.top-risk[data-severity="high"] .top-risk__score { background: var(--color-severity-high-soft); color: var(--color-severity-high-on); } +.top-risk[data-severity="medium"] .top-risk__score { background: var(--color-severity-medium-soft); color: var(--color-severity-medium-on); } +.top-risk[data-severity="low"] .top-risk__score { background: var(--color-severity-low-soft); color: var(--color-severity-low-on); } + +/* ========================================================================= + 19. Recommendation-card (.recommendation-card) + Emphasized advisory callout. Severity-tinted background + bold label. + Used by security/ROS recommendations and architecture-review next-actions. + ========================================================================= */ +.recommendation-card { + display: grid; + grid-template-columns: auto 1fr; + gap: var(--space-3); + align-items: start; + padding: var(--space-4) var(--space-5); + background: var(--color-bg-soft); + border: 1px solid var(--color-border-subtle); + border-left: 4px solid var(--color-state-info); + border-radius: var(--radius-md); + margin-block: var(--space-3); +} +.recommendation-card__label { + font-family: var(--font-family-mono); + font-size: 11px; + font-weight: var(--font-weight-bold); + letter-spacing: 0.08em; + text-transform: uppercase; + padding: 4px 10px; + border-radius: var(--radius-sm); + background: var(--color-state-info); + color: #fff; + white-space: nowrap; +} +.recommendation-card__body { + font-size: var(--font-size-md); + line-height: 1.55; + color: var(--color-text-primary); +} +.recommendation-card[data-severity="critical"] { border-left-color: var(--color-severity-critical); } +.recommendation-card[data-severity="critical"] .recommendation-card__label { background: var(--color-severity-critical); } +.recommendation-card[data-severity="high"] { border-left-color: var(--color-severity-high); } +.recommendation-card[data-severity="high"] .recommendation-card__label { background: var(--color-severity-high); } +.recommendation-card[data-severity="medium"] { border-left-color: var(--color-severity-medium); } +.recommendation-card[data-severity="medium"] .recommendation-card__label { background: var(--color-severity-medium); color: var(--color-severity-medium-on); } +.recommendation-card[data-severity="low"] { border-left-color: var(--color-severity-low); } +.recommendation-card[data-severity="low"] .recommendation-card__label { background: var(--color-severity-low); } +.recommendation-card[data-severity="positive"] { border-left-color: var(--color-state-success); } +.recommendation-card[data-severity="positive"] .recommendation-card__label { background: var(--color-state-success); } + +/* ========================================================================= + 20. Card subcomponents (.card__*) + Composable subcomponents extending the existing .card primitive (base.css). + Use as:
...
...
+ ========================================================================= */ +.card__head { + display: flex; + align-items: flex-start; + justify-content: space-between; + gap: var(--space-3); + margin-bottom: var(--space-2); +} +.card__title { + font-family: var(--font-family-sans); + font-size: var(--font-size-lg); + font-weight: var(--font-weight-semibold); + letter-spacing: -0.01em; + color: var(--color-text-primary); + margin: 0; + line-height: 1.3; +} +.card__desc { + font-size: var(--font-size-sm); + line-height: 1.5; + color: var(--color-text-secondary); + margin: 0 0 var(--space-2); +} +.card__id { + font-family: var(--font-family-mono); + font-size: 12px; + color: var(--color-text-tertiary); + background: var(--color-surface-sunken); + padding: 2px 8px; + border-radius: var(--radius-sm); + display: inline-block; +} +.card__meta { + display: flex; + gap: var(--space-2); + align-items: center; + flex-wrap: wrap; + font-size: 12px; + color: var(--color-text-tertiary); + margin-top: var(--space-2); +} +.card__hint { + font-family: var(--font-family-mono); + font-size: 12px; + color: var(--color-text-tertiary); + margin-top: var(--space-1); +} +.card__actions { + display: flex; + gap: var(--space-2); + align-items: center; + flex-wrap: wrap; + margin-top: var(--space-3); +} +.card__pill { + display: inline-flex; + align-items: center; + padding: 2px 8px; + font-family: var(--font-family-mono); + font-size: 11px; + font-weight: var(--font-weight-semibold); + letter-spacing: 0.04em; + text-transform: uppercase; + background: var(--color-surface-sunken); + color: var(--color-text-secondary); + border-radius: 999px; + white-space: nowrap; +} + +/* Severity left-border modifier on cards */ +.card--severity-critical { border-left: 4px solid var(--color-severity-critical); } +.card--severity-high { border-left: 4px solid var(--color-severity-high); } +.card--severity-medium { border-left: 4px solid var(--color-severity-medium); } +.card--severity-low { border-left: 4px solid var(--color-severity-low); } +.card--severity-positive { border-left: 4px solid var(--color-state-success); } +.card--severity-info { border-left: 4px solid var(--color-state-info); } + +/* ========================================================================= + 21. Form patterns (.field-row / .field-label / .field-help / etc) + Standard form-field building blocks. Mirrors Aksel/Digdir conventions. + ========================================================================= */ +.field-row { + display: flex; + flex-direction: column; + gap: 6px; +} +.field-row + .field-row { margin-top: var(--space-3); } +.field-label { + font-size: var(--font-size-sm); + font-weight: var(--font-weight-medium); + color: var(--color-text-primary); +} +.field-help { + font-size: var(--font-size-xs); + color: var(--color-text-tertiary); +} +.required-mark { + color: var(--color-severity-critical); + margin-left: 2px; + font-weight: var(--font-weight-bold); +} +.multi-select { + display: flex; + flex-direction: column; + gap: 4px; + border: 0; + padding: 0; + margin: 0; +} +.checkbox-row { + display: inline-flex; + align-items: center; + gap: 8px; + cursor: pointer; + font-size: var(--font-size-sm); + padding: 4px 0; + color: var(--color-text-primary); +} +.checkbox-row input { margin: 0; } +.checkbox-row:hover { color: var(--color-text-link); } + +/* ========================================================================= + 22. Section-spacing utility (.stack-lg / .stack-md / .stack-sm) + Consistent vertical rhythm between major sections. + ========================================================================= */ +.stack-lg > * + * { margin-top: var(--space-8); } +.stack-md > * + * { margin-top: var(--space-5); } +.stack-sm > * + * { margin-top: var(--space-3); } + +/* ========================================================================= + 23. Pyramide-tier-detail (.pyramide-tier-detail) + Expandable details below a .pyramide visualization. Used by AI Act + classification renderer to describe each tier's obligations. + ========================================================================= */ +.pyramide-tier-detail { + background: var(--color-surface); + border: 1px solid var(--color-border-subtle); + border-radius: var(--radius-md); + padding: var(--space-3) var(--space-4); + margin-top: var(--space-2); +} +.pyramide-tier-detail summary { + cursor: pointer; + font-family: var(--font-family-sans); + font-size: var(--font-size-md); + font-weight: var(--font-weight-semibold); + color: var(--color-text-primary); + list-style: none; + display: flex; + align-items: center; + gap: var(--space-2); +} +.pyramide-tier-detail summary::-webkit-details-marker { display: none; } +.pyramide-tier-detail summary::before { + content: "\25B8"; + font-size: 11px; + color: var(--color-text-tertiary); + transition: transform var(--duration-fast); + display: inline-block; +} +.pyramide-tier-detail[open] summary::before { transform: rotate(90deg); } +.pyramide-tier-detail__body { + font-size: var(--font-size-sm); + line-height: 1.55; + color: var(--color-text-secondary); + margin-top: var(--space-2); + padding-left: var(--space-3); +} + +/* ========================================================================= + 24. Scenario-card-grid (.scenario-card-grid / .scenario-card) + Grid of scenario/option cards used by license, compare renderers. + Each card: header (title + count) -> optional source line -> optional body. + ========================================================================= */ +.scenario-card-grid { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); + gap: var(--space-3); + margin-block: var(--space-3); +} +.scenario-card { + display: flex; + flex-direction: column; + gap: var(--space-2); + padding: var(--space-4); + background: var(--color-surface); + border: 1px solid var(--color-border-subtle); + border-radius: var(--radius-md); + transition: border-color var(--duration-fast), box-shadow var(--duration-fast); +} +.scenario-card:hover { border-color: var(--color-border-moderate); box-shadow: var(--shadow-sm); } +.scenario-card__head { + display: flex; + align-items: flex-start; + justify-content: space-between; + gap: var(--space-2); +} +.scenario-card__title { + font-family: var(--font-family-sans); + font-size: var(--font-size-md); + font-weight: var(--font-weight-semibold); + color: var(--color-text-primary); + margin: 0; + line-height: 1.3; +} +.scenario-card__count { + display: inline-flex; + align-items: center; + justify-content: center; + min-width: 24px; + padding: 2px 8px; + font-family: var(--font-family-mono); + font-size: 11px; + font-weight: var(--font-weight-bold); + background: var(--color-bg-soft); + color: var(--color-text-secondary); + border-radius: 999px; +} +.scenario-card__source { + font-family: var(--font-family-mono); + font-size: 12px; + color: var(--color-text-tertiary); +} +.scenario-card[data-status="winner"] { + border-color: var(--color-state-success); + background: var(--color-severity-low-soft); +} +.scenario-card[data-status="winner"] .scenario-card__count { + background: var(--color-state-success); + color: #fff; +} + +/* ========================================================================= + 25. App-shell utility (.app-shell) + Centered max-width page wrapper. Hoisted from playgrounds - every plugin + playground uses the same shell pattern. + ========================================================================= */ +.app-shell { + max-width: 1200px; + margin: 0 auto; + padding: var(--space-6) var(--space-5); +} +.app-shell--wide { max-width: 1400px; } +.app-shell--narrow { max-width: 880px; }