feat(shared): add Tier 3 components (8 critical for ms-ai-architect Playground v3)

Authored in Claude Code following the design-DNA established by claude.ai/design
in v0.1 (tokens + Tier 1 + Tier 2). Visual coherence verified against existing
components via tier3-preview.html showcase.

shared/playground-design-system/components-tier3.css (~480 lines):
- pair-before-after: ROS/DPIA/AI Act inherent->residual primitive with delta
  pill (improved/worsened); responsive collapse to vertical on narrow viewports
- aiact-timeline: 4 EU AI Act milestones (2025-02-02 .. 2027-08-02) with
  per-system countdown chips (urgent/soon/distant), today-marker, and per-
  milestone passed/active/upcoming states
- tracks: Guide/Explore/Expert 3-track entry pattern carried from Playground v2,
  top-bar color coding per track
- rights-matrix: FRIA 12 EU Charter rights x 5 impact levels (Art. 27 EU AI Act)
- capability-matrix: license x kapabilitet with explicit icons per status
  (available/cost/conditional/missing) - never color-only
- agent-grid + agent-card: parallel-worker status with state pills, progress
  bars, metric chips, pulsing dot for running, distinct failure-red token
- error-summary: Aksel/GOV.UK pattern, white bg + red border + dark body text
  + red heading (NOT large pink fill — fixes contrast bug)
- guide-panel: Aksel friendly inline guidance, info/success/warn variants

Also fixes shared/playground-design-system/base.css inline-message--error which
had the same contrast bug as ErrorSummary v1: white text on light-pink soft-fill
was unreadable. Now uses surface bg + critical border + primary text + critical
strong/heading color. Same dark-mode treatment.

shared/playground-examples/tier3-preview.html (~470 lines): live demo for all
8 components with realistic Norwegian mock-data (Lier kommune ROS T-001
threat, AI Act timeline 2026-05-02 today-marker, FRIA EU Charter rights, M365
capability-matrix, 4-worker utredning grid). Used to validate visual coherence
before committing.

Updates shared/playground-design-system/README.md with Tier 3 component table
and provenance note distinguishing v0.1 (claude.ai/design) from this addition
(Claude Code).

Remaining for v0.2: 12 plugin-specific Tier 3 components (sankey/toxic-flow,
fleet-overview, kanban Keep/Review/Remove, maturity-ladder, classify-and-
transform, cycle-ribbon, persistent-antipattern badge, suppressed-signals,
ExpansionCard, ReadMore, FormProgress, Aspirational vs Committed visual). To
be generated by claude.ai/design in a supplement session before plugin
Playground work begins.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
Kjell Tore Guttormsen 2026-05-02 07:22:44 +02:00
commit 992d6b3f76
4 changed files with 1237 additions and 2 deletions

View file

@ -0,0 +1,500 @@
<!doctype html>
<html lang="nb" data-theme="light">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Tier 3 preview — Playground Design System</title>
<link rel="stylesheet" href="../playground-design-system/tokens.css">
<link rel="stylesheet" href="../playground-design-system/base.css">
<link rel="stylesheet" href="../playground-design-system/components.css">
<link rel="stylesheet" href="../playground-design-system/components-tier2.css">
<link rel="stylesheet" href="../playground-design-system/components-tier3.css">
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500;600&display=swap" rel="stylesheet">
<style>
.preview-section {
padding: var(--space-10) 0;
border-bottom: 1px solid var(--color-border-subtle);
}
.preview-section:last-child { border-bottom: none; }
.preview-section__heading {
display: flex;
align-items: baseline;
gap: var(--space-3);
margin-bottom: var(--space-2);
}
.preview-section__num {
font-family: var(--font-family-mono);
font-size: var(--font-size-sm);
color: var(--color-text-tertiary);
font-weight: var(--font-weight-semibold);
min-width: 32px;
}
.preview-section__intro {
max-width: 60ch;
color: var(--color-text-secondary);
margin-bottom: var(--space-6);
}
.preview-section__demo {
padding: var(--space-6);
background: var(--color-surface);
border: 1px solid var(--color-border-subtle);
border-radius: var(--radius-lg);
}
</style>
</head>
<body>
<header class="app-header">
<a class="app-header__brand" href="index.html">
<span class="app-header__brand-mark">PG</span>
Playground Design System
</a>
<span class="app-header__breadcrumb">/ Tier 3 preview</span>
<div class="app-header__spacer"></div>
<button class="theme-toggle" id="themeToggle" type="button">Mørk modus</button>
<a href="index.html" class="btn btn--ghost btn--sm">← Til oversikt</a>
</header>
<main class="container container--wide">
<div style="padding: var(--space-8) 0 var(--space-4);">
<h1>Tier 3 — Critical components</h1>
<p class="text-secondary" style="max-width: 65ch; margin-top: var(--space-3);">
8 komponenter bygd direkte for ms-ai-architect Playground v3. Hvis disse ser ut som de hører hjemme i samme familie som Tier 1 + 2, beholder vi dem og lar claude.ai/design lage de resterende 12 (sankey/toxic-flow, fleet-overview, kanban Keep/Review/Remove, maturity-ladder, classify-and-transform, cycle-ribbon, persistent-antipattern badge, suppressed-signals panel, ExpansionCard, ReadMore, FormProgress, Aspirational vs Committed visual).
</p>
</div>
<!-- 19. Pair before/after -->
<section class="preview-section">
<div class="preview-section__heading">
<span class="preview-section__num">19</span>
<h2>Inherent + residual pair</h2>
</div>
<p class="preview-section__intro">Brukes i ROS før/etter mitigering, DPIA inherent → residual, OKR check-in score over tid.</p>
<div class="preview-section__demo">
<h4 style="margin-bottom: var(--space-2);">T-001: Eksponering av personopplysninger via Copilot Chat</h4>
<div class="pair-before-after">
<div class="pair-before-after__cell pair-before-after__cell--severity-critical">
<span class="pair-before-after__cell-label">Inherent risiko</span>
<span class="pair-before-after__cell-value">20</span>
<span class="pair-before-after__cell-meta">S4 × K5 — Kritisk sone</span>
</div>
<div class="pair-before-after__arrow" aria-label="reduseres til"></div>
<div class="pair-before-after__cell pair-before-after__cell--severity-medium">
<span class="pair-before-after__cell-label">Etter M-001 + M-002</span>
<span class="pair-before-after__cell-value">8</span>
<span class="pair-before-after__cell-meta">S2 × K4 — Gul sone</span>
<span class="pair-before-after__delta pair-before-after__delta--improved">12 (60 % reduksjon)</span>
</div>
</div>
</div>
</section>
<!-- 20. AI Act timeline -->
<section class="preview-section">
<div class="preview-section__heading">
<span class="preview-section__num">20</span>
<h2>AI Act compliance-tidslinje</h2>
</div>
<p class="preview-section__intro">4 milepeler i EU AI Act med per-system countdown. Brukes i ms-ai-architect classify-flow og dashboard.</p>
<div class="preview-section__demo">
<div class="aiact-timeline">
<div class="aiact-timeline__track">
<div class="aiact-timeline__progress" style="width: 41%;"></div>
<div class="aiact-timeline__milestone" style="left: 0%;" data-state="passed">
<div class="aiact-timeline__dot"></div>
<div class="aiact-timeline__label">
<span class="aiact-timeline__label-date">2025-02-02</span>
<span class="aiact-timeline__label-name">Forbudte praksiser (Art. 5)</span>
</div>
</div>
<div class="aiact-timeline__milestone" style="left: 22%;" data-state="passed">
<div class="aiact-timeline__dot"></div>
<div class="aiact-timeline__label">
<span class="aiact-timeline__label-date">2025-08-02</span>
<span class="aiact-timeline__label-name">Governance og sanksjoner (Art. 99)</span>
</div>
</div>
<div class="aiact-timeline__today" style="left: 41%;"></div>
<div class="aiact-timeline__milestone" style="left: 60%;" data-state="active">
<div class="aiact-timeline__dot"></div>
<div class="aiact-timeline__label">
<span class="aiact-timeline__label-date">2026-08-02</span>
<span class="aiact-timeline__label-name">GPAI + Annex III høyrisiko</span>
</div>
</div>
<div class="aiact-timeline__milestone" style="left: 100%;" data-state="upcoming">
<div class="aiact-timeline__dot"></div>
<div class="aiact-timeline__label">
<span class="aiact-timeline__label-date">2027-08-02</span>
<span class="aiact-timeline__label-name">Full compliance for all høyrisiko</span>
</div>
</div>
</div>
</div>
<div style="display: flex; gap: var(--space-3); flex-wrap: wrap; margin-top: var(--space-12);">
<span class="aiact-countdown" data-urgency="urgent">
<span>Kommunal Copilot-utrulling:</span>
<span class="aiact-countdown__days">92 dager</span>
<span>til Annex III-frist</span>
</span>
<span class="aiact-countdown" data-urgency="soon">
<span>Saksbehandling AI:</span>
<span class="aiact-countdown__days">457 dager</span>
<span>til full compliance</span>
</span>
<span class="aiact-countdown" data-urgency="distant">
<span>Intern HR-bot:</span>
<span class="aiact-countdown__days">457 dager</span>
<span>(begrenset risiko)</span>
</span>
</div>
</div>
</section>
<!-- 21. 3-track entry -->
<section class="preview-section">
<div class="preview-section__heading">
<span class="preview-section__num">21</span>
<h2>3-track entry</h2>
</div>
<p class="preview-section__intro">Carry-forward fra Playground v2. Den første beslutningen — bruker velger sin ferdighetsnivå-vei inn i Playground.</p>
<div class="preview-section__demo">
<div class="tracks">
<a class="tracks__card tracks__card--guided" href="#">
<div class="tracks__card-icon">
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 2v8M12 22v-2M4.93 4.93l5.66 5.66M19.07 19.07l-1.41-1.41M2 12h8M22 12h-2M4.93 19.07l5.66-5.66M19.07 4.93l-1.41 1.41"/></svg>
</div>
<h3 class="tracks__card-title">Guide meg</h3>
<p class="tracks__card-desc">Strukturert wizard som leder deg gjennom intake, kapabilitetsvalg og eksport. Anbefalt for første gangs bruk eller når du er usikker.</p>
<div class="tracks__card-meta">
<span>56 klikk</span>
<span class="tracks__card-cta">Start →</span>
</div>
</a>
<a class="tracks__card tracks__card--explore" href="#">
<div class="tracks__card-icon">
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="11" cy="11" r="8"/><path d="m21 21-4.3-4.3"/></svg>
</div>
<h3 class="tracks__card-title">La meg utforske</h3>
<p class="tracks__card-desc">Bla i kapabilitetskatalogen, filtrér på lisens og dataresidens, og bygg arkitekturen din ad-hoc.</p>
<div class="tracks__card-meta">
<span>810 klikk</span>
<span class="tracks__card-cta">Bla →</span>
</div>
</a>
<a class="tracks__card tracks__card--expert" href="#">
<div class="tracks__card-icon">
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="16 18 22 12 16 6"/><polyline points="8 6 2 12 8 18"/></svg>
</div>
<h3 class="tracks__card-title">Jeg vet hva jeg vil</h3>
<p class="tracks__card-desc">Hopp direkte til konfigurasjon, hent fra forrige beslutningsrekord, eller skriv inn JSON og la oss generere kommando-pipelinen.</p>
<div class="tracks__card-meta">
<span>34 klikk</span>
<span class="tracks__card-cta">Hopp inn →</span>
</div>
</a>
</div>
</div>
</section>
<!-- 22. FRIA rights-matrix -->
<section class="preview-section">
<div class="preview-section__heading">
<span class="preview-section__num">22</span>
<h2>FRIA rights-matrix</h2>
</div>
<p class="preview-section__intro">12 EU Charter-rettigheter × konsekvensnivå (05). Brukes i FRIA-vurdering (Art. 27 EU AI Act) for offentlig sektor høyrisiko-systemer.</p>
<div class="preview-section__demo">
<div class="rights-matrix">
<div class="rights-matrix__head">
<div class="rights-matrix__head-cell rights-matrix__head-cell--name">Grunnleggende rettighet (EU Charter)</div>
<div class="rights-matrix__head-cell">N/A</div>
<div class="rights-matrix__head-cell">Lav</div>
<div class="rights-matrix__head-cell">Med</div>
<div class="rights-matrix__head-cell">Høy</div>
<div class="rights-matrix__head-cell">Kritisk</div>
</div>
<div class="rights-matrix__row">
<div class="rights-matrix__name">Art. 7 — Rett til privatliv<span class="rights-matrix__name-meta">Korrespondanse, hjem, familieliv</span></div>
<div class="rights-matrix__cell" data-impact="0"></div>
<div class="rights-matrix__cell" data-impact="0"></div>
<div class="rights-matrix__cell" data-impact="0"></div>
<div class="rights-matrix__cell" data-impact="4"></div>
<div class="rights-matrix__cell" data-impact="0"></div>
</div>
<div class="rights-matrix__row">
<div class="rights-matrix__name">Art. 8 — Personopplysninger<span class="rights-matrix__name-meta">GDPR-forankret</span></div>
<div class="rights-matrix__cell" data-impact="0"></div>
<div class="rights-matrix__cell" data-impact="0"></div>
<div class="rights-matrix__cell" data-impact="0"></div>
<div class="rights-matrix__cell" data-impact="0"></div>
<div class="rights-matrix__cell" data-impact="5"></div>
</div>
<div class="rights-matrix__row">
<div class="rights-matrix__name">Art. 11 — Ytringsfrihet<span class="rights-matrix__name-meta">Innhentings- og spredningsfrihet</span></div>
<div class="rights-matrix__cell" data-impact="0"></div>
<div class="rights-matrix__cell" data-impact="1"></div>
<div class="rights-matrix__cell" data-impact="0"></div>
<div class="rights-matrix__cell" data-impact="0"></div>
<div class="rights-matrix__cell" data-impact="0"></div>
</div>
<div class="rights-matrix__row">
<div class="rights-matrix__name">Art. 21 — Diskrimineringsforbud<span class="rights-matrix__name-meta">Kjønn, etnisitet, religion, alder</span></div>
<div class="rights-matrix__cell" data-impact="0"></div>
<div class="rights-matrix__cell" data-impact="0"></div>
<div class="rights-matrix__cell" data-impact="0"></div>
<div class="rights-matrix__cell" data-impact="0"></div>
<div class="rights-matrix__cell" data-impact="5"></div>
</div>
<div class="rights-matrix__row">
<div class="rights-matrix__name">Art. 41 — God forvaltning<span class="rights-matrix__name-meta">Habilitet, begrunnelse, klagerett</span></div>
<div class="rights-matrix__cell" data-impact="0"></div>
<div class="rights-matrix__cell" data-impact="0"></div>
<div class="rights-matrix__cell" data-impact="0"></div>
<div class="rights-matrix__cell" data-impact="3"></div>
<div class="rights-matrix__cell" data-impact="0"></div>
</div>
<div class="rights-matrix__row">
<div class="rights-matrix__name">Art. 47 — Effektivt rettsmiddel<span class="rights-matrix__name-meta">Rett til rettferdig rettergang</span></div>
<div class="rights-matrix__cell" data-impact="0"></div>
<div class="rights-matrix__cell" data-impact="0"></div>
<div class="rights-matrix__cell" data-impact="2"></div>
<div class="rights-matrix__cell" data-impact="0"></div>
<div class="rights-matrix__cell" data-impact="0"></div>
</div>
</div>
<p class="text-xs text-tertiary" style="margin-top: var(--space-3);">Demo viser 6 av 12 rettigheter. Full FRIA dekker alle relevante artikler i EU-pakten.</p>
</div>
</section>
<!-- 23. Capability-matrix -->
<section class="preview-section">
<div class="preview-section__heading">
<span class="preview-section__num">23</span>
<h2>Capability-matrix</h2>
</div>
<p class="preview-section__intro">Brukes i ms-ai-architect for å mappe kapabilitet × lisens. Statuser: tilgjengelig, koster ekstra, betinget, mangler. Aldri kun farge — ikon + farge sammen.</p>
<div class="preview-section__demo">
<div class="capability-matrix" style="grid-template-columns: 1fr;">
<div class="capability-matrix__head" style="grid-template-columns: 2fr 1fr 1fr 1fr 1fr;">
<div class="capability-matrix__head-cell capability-matrix__head-cell--name">Kapabilitet</div>
<div class="capability-matrix__head-cell">M365 E3</div>
<div class="capability-matrix__head-cell">M365 E5</div>
<div class="capability-matrix__head-cell">Copilot</div>
<div class="capability-matrix__head-cell">Power Premium</div>
</div>
<div class="capability-matrix__row" style="grid-template-columns: 2fr 1fr 1fr 1fr 1fr;">
<div class="capability-matrix__name">Generer tekst i M365 Chat</div>
<div class="capability-matrix__cell" data-status="missing"><i class="capability-matrix__cell-icon"></i></div>
<div class="capability-matrix__cell" data-status="missing"><i class="capability-matrix__cell-icon"></i></div>
<div class="capability-matrix__cell" data-status="available"><i class="capability-matrix__cell-icon"></i></div>
<div class="capability-matrix__cell" data-status="missing"><i class="capability-matrix__cell-icon"></i></div>
</div>
<div class="capability-matrix__row" style="grid-template-columns: 2fr 1fr 1fr 1fr 1fr;">
<div class="capability-matrix__name">Sensitivity Labels på dokumenter</div>
<div class="capability-matrix__cell" data-status="cost"><i class="capability-matrix__cell-icon"></i></div>
<div class="capability-matrix__cell" data-status="available"><i class="capability-matrix__cell-icon"></i></div>
<div class="capability-matrix__cell" data-status="available"><i class="capability-matrix__cell-icon"></i></div>
<div class="capability-matrix__cell" data-status="missing"><i class="capability-matrix__cell-icon"></i></div>
</div>
<div class="capability-matrix__row" style="grid-template-columns: 2fr 1fr 1fr 1fr 1fr;">
<div class="capability-matrix__name">DLP for endpoints</div>
<div class="capability-matrix__cell" data-status="missing"><i class="capability-matrix__cell-icon"></i></div>
<div class="capability-matrix__cell" data-status="available"><i class="capability-matrix__cell-icon"></i></div>
<div class="capability-matrix__cell" data-status="conditional"><i class="capability-matrix__cell-icon"></i></div>
<div class="capability-matrix__cell" data-status="missing"><i class="capability-matrix__cell-icon"></i></div>
</div>
<div class="capability-matrix__row" style="grid-template-columns: 2fr 1fr 1fr 1fr 1fr;">
<div class="capability-matrix__name">Power Automate AI Builder-flows</div>
<div class="capability-matrix__cell" data-status="cost"><i class="capability-matrix__cell-icon"></i></div>
<div class="capability-matrix__cell" data-status="cost"><i class="capability-matrix__cell-icon"></i></div>
<div class="capability-matrix__cell" data-status="conditional"><i class="capability-matrix__cell-icon"></i></div>
<div class="capability-matrix__cell" data-status="available"><i class="capability-matrix__cell-icon"></i></div>
</div>
<div class="capability-matrix__row" style="grid-template-columns: 2fr 1fr 1fr 1fr 1fr;">
<div class="capability-matrix__name">Copilot Studio agent (custom)</div>
<div class="capability-matrix__cell" data-status="missing"><i class="capability-matrix__cell-icon"></i></div>
<div class="capability-matrix__cell" data-status="missing"><i class="capability-matrix__cell-icon"></i></div>
<div class="capability-matrix__cell" data-status="cost"><i class="capability-matrix__cell-icon"></i></div>
<div class="capability-matrix__cell" data-status="conditional"><i class="capability-matrix__cell-icon"></i></div>
</div>
</div>
<div class="capability-matrix__legend">
<span class="capability-matrix__legend-item"><i class="capability-matrix__cell-icon" style="background: var(--color-severity-low); color: #fff;"></i> Tilgjengelig</span>
<span class="capability-matrix__legend-item"><i class="capability-matrix__cell-icon" style="background: var(--color-severity-medium); color: #fff; font-size: 10px;">kr</i> Krever tilleggslisens</span>
<span class="capability-matrix__legend-item"><i class="capability-matrix__cell-icon" style="background: var(--color-severity-high); color: #fff;">!</i> Betinget (krever konfigurasjon)</span>
<span class="capability-matrix__legend-item"><i class="capability-matrix__cell-icon" style="background: var(--color-text-tertiary); color: #fff;">×</i> Ikke tilgjengelig</span>
</div>
</div>
</section>
<!-- 24. Parallel-agent-status -->
<section class="preview-section">
<div class="preview-section__heading">
<span class="preview-section__num">24</span>
<h2>Parallel-agent-status panel</h2>
</div>
<p class="preview-section__intro">Brukes i ms-ai-architect utredning (4 parallelle workers skriver til <code>.work/</code>) og ultraplan-local multi-wave execute. Per worker: tilstand, fremdrift og siste output-utdrag.</p>
<div class="preview-section__demo">
<div class="agent-grid">
<div class="agent-card">
<div class="agent-card__head">
<div>
<h4 class="agent-card__name">security-worker</h4>
<span class="agent-card__role">6×5 sikkerhetsmatrise</span>
</div>
<span class="agent-card__state" data-state="done"><span class="agent-card__state-dot"></span>Ferdig</span>
</div>
<div class="agent-card__progress"><div class="agent-card__progress-fill" style="width: 100%;"></div></div>
<div class="agent-card__metrics">
<span class="agent-card__metric"><span>Tid:</span><span class="agent-card__metric-value">2m 14s</span></span>
<span class="agent-card__metric"><span>Funn:</span><span class="agent-card__metric-value">12</span></span>
</div>
</div>
<div class="agent-card">
<div class="agent-card__head">
<div>
<h4 class="agent-card__name">cost-worker</h4>
<span class="agent-card__role">P10/P50/P90 NOK-estimat</span>
</div>
<span class="agent-card__state" data-state="running"><span class="agent-card__state-dot"></span>Kjører</span>
</div>
<div class="agent-card__progress"><div class="agent-card__progress-fill" style="width: 67%;"></div></div>
<div class="agent-card__metrics">
<span class="agent-card__metric"><span>Tid:</span><span class="agent-card__metric-value">1m 32s</span></span>
<span class="agent-card__metric"><span>SKU-er:</span><span class="agent-card__metric-value">8 / 12</span></span>
</div>
</div>
<div class="agent-card">
<div class="agent-card__head">
<div>
<h4 class="agent-card__name">dpia-worker</h4>
<span class="agent-card__role">GDPR Art. 35-vurdering</span>
</div>
<span class="agent-card__state" data-state="running"><span class="agent-card__state-dot"></span>Kjører</span>
</div>
<div class="agent-card__progress"><div class="agent-card__progress-fill" style="width: 23%;"></div></div>
<div class="agent-card__metrics">
<span class="agent-card__metric"><span>Tid:</span><span class="agent-card__metric-value">42s</span></span>
<span class="agent-card__metric"><span>Risiko:</span><span class="agent-card__metric-value">2 / 10</span></span>
</div>
</div>
<div class="agent-card">
<div class="agent-card__head">
<div>
<h4 class="agent-card__name">diagram-worker</h4>
<span class="agent-card__role">Imagen 3 / Mermaid fallback</span>
</div>
<span class="agent-card__state" data-state="failed"><span class="agent-card__state-dot"></span>Feilet</span>
</div>
<div class="agent-card__progress"><div class="agent-card__progress-fill" style="width: 100%; background: var(--color-state-failed);"></div></div>
<div class="agent-card__metrics">
<span class="agent-card__metric"><span>Feil:</span><span class="agent-card__metric-value" style="color: var(--color-state-failed);">MCP timeout</span></span>
</div>
</div>
</div>
</div>
</section>
<!-- 25. ErrorSummary -->
<section class="preview-section">
<div class="preview-section__heading">
<span class="preview-section__num">25</span>
<h2>ErrorSummary (Aksel/GOV.UK)</h2>
</div>
<p class="preview-section__intro">Konsentrert valideringsfeil-liste øverst i lange skjemaer. Hver feil har anker-link til feltet. Skjermlesere leser hele listen først — kritisk for tilgjengelig skjema-UX.</p>
<div class="preview-section__demo">
<div class="error-summary" role="alert" aria-labelledby="es-heading">
<h3 class="error-summary__heading" id="es-heading">Det er 4 feil i ROS-skjemaet</h3>
<p class="error-summary__body">Rett opp feilene før du fortsetter. Hver feil lenker til feltet.</p>
<ul class="error-summary__list">
<li class="error-summary__item"><a class="error-summary__link" href="#field-system">System-navn må fylles ut</a></li>
<li class="error-summary__item"><a class="error-summary__link" href="#field-residency">Dataresidens er påkrevd for offentlig sektor (velg EU eller Norway East)</a></li>
<li class="error-summary__item"><a class="error-summary__link" href="#field-threats">Minst 5 trusler må plasseres i matrisen før du kan generere rapport</a></li>
<li class="error-summary__item"><a class="error-summary__link" href="#field-owner">Behandlingsansvarlig må navngis (rolle eller person)</a></li>
</ul>
</div>
</div>
</section>
<!-- 26. GuidePanel -->
<section class="preview-section">
<div class="preview-section__heading">
<span class="preview-section__num">26</span>
<h2>GuidePanel (Aksel)</h2>
</div>
<p class="preview-section__intro">Vennlig inline-veiledning for første-gangs-brukere. Skala av hjelp uten å være skoleflink.</p>
<div class="preview-section__demo stack">
<div class="guide-panel guide-panel--info">
<div class="guide-panel__icon" aria-hidden="true">
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><path d="M12 16v-4M12 8h.01"/></svg>
</div>
<div class="guide-panel__body">
<h4 class="guide-panel__title">Første gang du gjør en ROS for AI?</h4>
<p class="guide-panel__text">Vi følger NS 5814:2021 og bruker "evalueringskriterier" (ikke "akseptkriterier"). De 49 forhåndsdefinerte truslene er hentet fra EU AI Act Annex III og NSM grunnprinsipper for IKT-sikkerhet.</p>
</div>
<a href="#" class="btn btn--secondary btn--sm guide-panel__action">Les metodikk</a>
</div>
<div class="guide-panel guide-panel--success">
<div class="guide-panel__icon" aria-hidden="true">
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M22 11.08V12a10 10 0 1 1-5.93-9.14"/><polyline points="22 4 12 14.01 9 11.01"/></svg>
</div>
<div class="guide-panel__body">
<h4 class="guide-panel__title">Onboarding fullført</h4>
<p class="guide-panel__text">Profilen din er lagret i <code>org/profile.md</code>. Alle agenter (security, cost, dpia, diagram) leser denne automatisk — du slipper å skrive om virksomheten på nytt.</p>
</div>
</div>
<div class="guide-panel guide-panel--warn">
<div class="guide-panel__icon" aria-hidden="true">
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M10.29 3.86 1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z"/><line x1="12" y1="9" x2="12" y2="13"/><line x1="12" y1="17" x2="12.01" y2="17"/></svg>
</div>
<div class="guide-panel__body">
<h4 class="guide-panel__title">Schrems II-flagging</h4>
<p class="guide-panel__text">Du har valgt en region som ikke er EU/EØS. For offentlig sektor i Norge krever dette rettslig vurdering av overføringsmekanismen (SCCs + supplementary measures eller Microsoft EU Data Boundary).</p>
</div>
<a href="#" class="btn btn--secondary btn--sm guide-panel__action">Vis vurderingsmal</a>
</div>
</div>
</section>
<div style="padding: var(--space-12) 0; text-align: center; color: var(--color-text-tertiary); font-size: var(--font-size-sm);">
<p>Hvis disse 8 ser ut som de hører til familien: behold dem. Hvis ikke: scrap og kjør alle 20 i claude.ai/design.</p>
<p style="margin-top: var(--space-2);"><a href="index.html">← Til hovedoversikt</a></p>
</div>
</main>
<script>
const themeToggle = document.getElementById('themeToggle');
const root = document.documentElement;
const saved = localStorage.getItem('pgds-theme') || 'light';
root.dataset.theme = saved;
themeToggle.textContent = saved === 'dark' ? 'Lys modus' : 'Mørk modus';
themeToggle.addEventListener('click', () => {
const next = root.dataset.theme === 'dark' ? 'light' : 'dark';
root.dataset.theme = next;
localStorage.setItem('pgds-theme', next);
themeToggle.textContent = next === 'dark' ? 'Lys modus' : 'Mørk modus';
});
</script>
</body>
</html>