From 2e8cb9ed93f84a9aa1f09206d423f9e0f40a1927 Mon Sep 17 00:00:00 2001 From: Kjell Tore Guttormsen Date: Mon, 4 May 2026 06:03:35 +0200 Subject: [PATCH] feat(ms-ai-architect): renderer A.1 classify adopt page-header + tier-desc - renderAiActPyramid wrapped med renderPageShell (eyebrow KLASSIFISERING, verdict via aiact-archetype, keyStats via inferKeyStats) - 4 details/summary-blokker under pyramide for klikk-pa-tier kort beskrivelse (active tier open by default) - Inline CSS for pyramide-desc + scenario-card-grid + residual-pair + read-more-block (klargjor renderers A.2-A.6) --- .../ms-ai-architect-playground.html | 58 +++++++++++++++++-- 1 file changed, 53 insertions(+), 5 deletions(-) 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 7312635..cc49acd 100644 --- a/plugins/ms-ai-architect/playground/ms-ai-architect-playground.html +++ b/plugins/ms-ai-architect/playground/ms-ai-architect-playground.html @@ -177,6 +177,39 @@ .key-stat[data-modifier="medium"] .key-stat__value { color: var(--color-severity-medium); } .key-stat[data-modifier="low"] .key-stat__value { color: var(--color-severity-low); } + /* Renderer-batch A inlines (v1.10.0 Sesjon 3). Klasser ikke i vendor — + inline her per scope-regel (plugin standalone). Kandidat for hoisting + til shared/playground-design-system/ i Sesjon 6 visual QA. */ + .pyramide-desc { margin: var(--space-4) 0 0 0; display: flex; flex-direction: column; gap: var(--space-2); } + .pyramide-desc__item { background: var(--color-bg-soft); border: 1px solid var(--color-border-subtle); border-radius: var(--radius-sm); padding: var(--space-2) var(--space-3); } + .pyramide-desc__item summary { cursor: pointer; font-weight: var(--font-weight-semibold); color: var(--color-text-primary); } + .pyramide-desc__item[open] summary { margin-bottom: var(--space-2); } + .pyramide-desc__item p { margin: 0; font-size: var(--font-size-sm); color: var(--color-text-secondary); } + + .scenario-card-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); gap: var(--space-3); margin: 0 0 var(--space-4) 0; } + .scenario-card { 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: var(--space-2); } + .scenario-card[data-status="met"] { border-left: 4px solid var(--color-state-success); } + .scenario-card[data-status="partial"] { border-left: 4px solid var(--color-severity-medium); } + .scenario-card[data-status="missing"] { border-left: 4px solid var(--color-severity-critical); } + .scenario-card__head { display: flex; justify-content: space-between; align-items: baseline; gap: var(--space-2); } + .scenario-card__source { font-family: var(--font-family-mono); font-size: var(--font-size-xs); color: var(--color-text-tertiary); } + .scenario-card__count { font-family: var(--font-family-mono); font-size: 11px; padding: 2px 8px; background: var(--color-bg-soft); border-radius: var(--radius-pill); color: var(--color-text-secondary); border: 1px solid var(--color-border-subtle); } + .scenario-card__title { font-size: var(--font-size-md); font-weight: var(--font-weight-semibold); color: var(--color-text-primary); margin: 0; } + + .residual-pair { display: grid; grid-template-columns: 1fr auto 1fr; gap: var(--space-4); align-items: center; margin: var(--space-4) 0; padding: var(--space-3); background: var(--color-bg-soft); border: 1px solid var(--color-border-subtle); border-radius: var(--radius-md); } + .residual-pair__cell { background: var(--color-surface); border: 1px solid var(--color-border-subtle); border-radius: var(--radius-sm); padding: var(--space-3); display: flex; flex-direction: column; gap: 4px; } + .residual-pair__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); } + .residual-pair__cell-value { font-size: var(--font-size-2xl); font-weight: var(--font-weight-bold); font-variant-numeric: tabular-nums; line-height: 1; color: var(--color-text-primary); } + .residual-pair__cell-meta { font-size: var(--font-size-xs); color: var(--color-text-secondary); } + .residual-pair__arrow { font-size: var(--font-size-xl); color: var(--color-text-tertiary); justify-self: center; } + .residual-pair__cell[data-severity="low"] { border-left: 4px solid var(--color-severity-low); } + .residual-pair__cell[data-severity="medium"] { border-left: 4px solid var(--color-severity-medium); } + .residual-pair__cell[data-severity="high"] { border-left: 4px solid var(--color-severity-high); } + .residual-pair__cell[data-severity="critical"] { border-left: 4px solid var(--color-severity-critical); } + + .read-more-block { margin: var(--space-2) 0; } + .read-more-block summary { cursor: pointer; color: var(--color-text-link); font-weight: var(--font-weight-medium); } + /* Tier 3 A4 — Screen-tabs (segmented). Inline her per scope-regel (plugin standalone). Kandidat for hoisting til shared/ i Sesjon 6. */ .screen-tabs { display: flex; gap: var(--space-1); padding: 4px; background: var(--color-bg-soft); border-radius: var(--radius-md); width: fit-content; margin: 0 0 var(--space-4) 0; } @@ -2964,10 +2997,10 @@ else if (/minimal|low/.test(norm)) activeTier = 'minimal'; const tiers = [ - { id: 'forbidden', label: 'Uakseptabel risiko (Art. 5)' }, - { id: 'high', label: 'Høyrisiko (Art. 6 + Annex III)' }, - { id: 'limited', label: 'Begrenset risiko (Art. 50)' }, - { id: 'minimal', label: 'Minimal risiko' } + { id: 'forbidden', label: 'Uakseptabel risiko (Art. 5)', desc: 'Forbudte AI-praksiser: subliminal manipulasjon, sosial scoring, manipulering av sårbare grupper, biometrisk fjernidentifisering i sanntid (med unntak).' }, + { id: 'high', label: 'Høyrisiko (Art. 6 + Annex III)', desc: 'Krever full compliance: risikostyringssystem, datakvalitet, teknisk dokumentasjon, transparens, menneskelig oversikt, robusthet og — for offentlig sektor — FRIA før idriftsettelse.' }, + { id: 'limited', label: 'Begrenset risiko (Art. 50)', desc: 'Transparenskrav: brukere skal informeres om at de samhandler med AI. Gjelder bl.a. chatboter, deepfakes og emosjonell gjenkjenning.' }, + { id: 'minimal', label: 'Minimal risiko', desc: 'Ingen særskilte krav under AI Act. Frivillige Codes of Conduct anbefales og dokumenteres som god praksis.' } ]; const tiersHtml = tiers.map(function (t) { const active = (t.id === activeTier); @@ -2979,6 +3012,14 @@ ''; }).join(''); + const tierDescsHtml = '
' + tiers.map(function (t) { + const open = (t.id === activeTier) ? ' open' : ''; + return '
' + + '' + escapeHtml(t.label) + '' + + '

' + escapeHtml(t.desc) + '

' + + '
'; + }).join('') + '
'; + const obligationsHtml = (data.obligations || []).length ? '

Forpliktelser

'; - slot.innerHTML = '
' + tiersHtml + '
' + meta + obligationsHtml; + const body = '
' + tiersHtml + '
' + tierDescsHtml + meta + obligationsHtml; + slot.innerHTML = renderPageShell({ + eyebrow: 'KLASSIFISERING', + title: data.title || 'EU AI Act-klassifisering', + lede: data.lede || 'Risikonivå, rolle og forpliktelser etter AI Act.', + verdict: data.verdict || inferVerdict(data, 'aiact'), + keyStats: data.keyStats || inferKeyStats(data, 'aiact') + }, body); } function renderRequirements(data, slot) {