Aksel/Digdir-aligned design system for plugin Playgrounds — visual self-service UIs that complement terminal slash-commands. Targets ms-ai-architect, okr, llm-security, ultraplan-local, config-audit. Built for Norwegian public sector decision-makers plus developer power-users — one visual family, two info densities. Generated by claude.ai/design (Anthropic) in a dialog-based design session driven by a comprehensive brief covering all five target plugins, Aksel/Digdir conventions, and domain-specific visual standards (NS 5814 ROS matrices, EU AI Act 4-tier pyramide, Doerr OKR scoring, NIST CSF, OWASP threat modeling). Per Anthropic Consumer Terms §4, ownership of outputs is assigned to the user; licensed MIT. shared/playground-design-system/ (5874 lines CSS + JSON): - tokens.css: Inter font, Digdir blue #0062BA, deuteranopia-safe severity ramp, distinct severity-red (#A40E26) vs failure-red (#7D1A1A), plugin scope colors, light + dark themes - base.css: reset, typography (17px body, 65ch measure), focus rings, buttons, badges, forms, Aksel 3-tier inline messages, prefers-reduced-motion support - components.css: Tier 1 — radar/spider, 5x5 matrix-heatmap (bottom-left origin, ROS/DPIA), findings-browser, critique-card, wizard/stepper, live-meter with antipattern lints - components-tier2.css: Tier 2 — decision-tree, traffic-lights with rationale, diff-review, treemap, distribution P10/P50/P90, command-pipeline output, AI Act 4-color pyramide, pipeline-cockpit, verdict-pill + 5-band risk-meter, codepoint-reveal (Unicode steg), small-multiples grid (16-cat posture), OWASP badges (LLM/ASI/AST/MCP) - print.css: A4 stylesheet with BW severity hatching, kommune-logo slot, signature lines for offentlige dokumenter - schemas/: finding.schema.json, okr-set.schema.json, ros-threat.schema.json - README.md: usage guide, design principles, component reference, provenance shared/playground-examples/: - index.html: system showcase with all components live - ros-lier-kommune.html: Lier kommune Copilot ROS-rapport (Scenario A) - okr-baerum.html: Baerum kommune T2-2026 OKR live writer (Scenario B) - security-vegvesen.html: SVV ToxicSkills findings review, 85 funn BLOCK (Scenario C) - templates.html: A4 print template demos - ros-app.js + ros-data.js: Scenario A interactivity WCAG 2.1 AA throughout (UU-loven krav for offentlig sektor): focus rings, ARIA attributes, keyboard navigation, severity numerical redundancy for deuteranopia and BW print, semantic HTML. Known limitation: Inter loaded via Google Fonts CDN violates self-contained no-CDN constraint. System-stack fallback works offline. Self-host woff2 files in Phase 2.
175 lines
6.9 KiB
CSS
175 lines
6.9 KiB
CSS
/* =============================================================================
|
|
print.css — A4 print stylesheet for offentlige dokumenter
|
|
- Severity-mønstre (skravur) som fungerer i B/W
|
|
- Header/footer med kommune-logo-slot, signaturfelt, paginering
|
|
- 12pt minimum kropp, 11pt for metadata
|
|
- Skjuler interaktiv chrome (header, knapper, toggles)
|
|
============================================================================= */
|
|
|
|
@page {
|
|
size: A4 portrait;
|
|
margin: 22mm 18mm 24mm 18mm;
|
|
@bottom-right { content: counter(page) " / " counter(pages); font-family: "Inter", sans-serif; font-size: 9pt; color: #555; }
|
|
}
|
|
@page :first { @top-left { content: none; } }
|
|
@page landscape { size: A4 landscape; }
|
|
|
|
/* SVG severity-mønstre (skravur) — definert i print-only inline-svg.
|
|
For å bruke: legg til class .pattern-low/.pattern-medium/etc. på elementet
|
|
som ellers fyller med severity-fargen. */
|
|
@media print {
|
|
|
|
:root {
|
|
--color-bg: #FFFFFF;
|
|
--color-surface: #FFFFFF;
|
|
--color-surface-sunken: #F5F5F5;
|
|
--color-bg-soft: #F7F7F7;
|
|
--color-border-subtle: #C7C7C7;
|
|
--color-border-moderate: #888888;
|
|
--color-text-primary: #000000;
|
|
--color-text-secondary: #2A2A2A;
|
|
--color-text-tertiary: #555555;
|
|
}
|
|
|
|
html, body { background: #FFFFFF !important; color: #000 !important; font-size: 11pt !important; }
|
|
body { -webkit-print-color-adjust: exact; print-color-adjust: exact; }
|
|
|
|
/* Hide interactive chrome */
|
|
.app-header, header.app-header,
|
|
.theme-toggle, #theme-toggle, #themeToggle,
|
|
.filter-bar, .view-toggle, .screen-tabs,
|
|
.btn--primary, .btn--secondary, .btn--ghost,
|
|
.live-dot, .pane__head .badge,
|
|
.accept-banner button,
|
|
.scenario-card .btn,
|
|
.footer { display: none !important; }
|
|
|
|
/* Container = full width on print */
|
|
.container, .container--wide { max-width: none !important; padding: 0 !important; }
|
|
|
|
/* Body type */
|
|
body, p, li, dd, dt, td, th, .field__value {
|
|
font-family: "Inter", sans-serif;
|
|
font-size: 11pt; line-height: 1.45; color: #000;
|
|
}
|
|
h1 { font-size: 22pt; line-height: 1.2; margin: 0 0 6pt; }
|
|
h2 { font-size: 16pt; line-height: 1.25; margin: 18pt 0 6pt; page-break-after: avoid; }
|
|
h3 { font-size: 13pt; margin: 12pt 0 4pt; page-break-after: avoid; }
|
|
h4 { font-size: 11pt; margin: 10pt 0 3pt; }
|
|
|
|
/* Page breaks */
|
|
.page-break { page-break-before: always; }
|
|
.avoid-break, .finding, .critique, .scenario-card, table, figure {
|
|
page-break-inside: avoid;
|
|
}
|
|
|
|
/* Severity patterns (B/W-safe). Stack pattern-bg + dotted/diag border indicators. */
|
|
.matrix__cell[data-score],
|
|
.badge--severity-low, .badge--severity-medium, .badge--severity-high,
|
|
.badge--severity-critical, .badge--severity-extreme {
|
|
background-color: #FFF !important;
|
|
color: #000 !important;
|
|
border: 1px solid #000 !important;
|
|
}
|
|
.badge--severity-low::before, .badge--severity-medium::before,
|
|
.badge--severity-high::before, .badge--severity-critical::before,
|
|
.badge--severity-extreme::before {
|
|
content: ""; display: inline-block;
|
|
width: 7pt; height: 7pt; margin-right: 4pt;
|
|
border: 1px solid #000;
|
|
vertical-align: middle;
|
|
}
|
|
.badge--severity-low::before { background: #FFF; }
|
|
.badge--severity-medium::before { background: repeating-linear-gradient(45deg, #000 0 0.6pt, transparent 0.6pt 3pt); }
|
|
.badge--severity-high::before { background: repeating-linear-gradient(45deg, #000 0 1pt, transparent 1pt 2.5pt); }
|
|
.badge--severity-critical::before { background: repeating-linear-gradient(0deg, #000 0 0.5pt, transparent 0.5pt 2pt),
|
|
repeating-linear-gradient(90deg, #000 0 0.5pt, transparent 0.5pt 2pt); }
|
|
.badge--severity-extreme::before { background: #000; }
|
|
|
|
/* Matrix cells in print: skravur i stedet for farge */
|
|
.matrix__cell { color: #000 !important; border: 0.5pt solid #888 !important; }
|
|
.matrix__cell[data-score]:not([data-score="0"]) { background: #FFF !important; }
|
|
.matrix__cell[data-score="1"], .matrix__cell[data-score="2"],
|
|
.matrix__cell[data-score="3"], .matrix__cell[data-score="4"] {
|
|
background: #FFF !important;
|
|
}
|
|
.matrix__cell[data-score="5"], .matrix__cell[data-score="6"], .matrix__cell[data-score="8"] {
|
|
background: repeating-linear-gradient(45deg, rgba(0,0,0,0.18) 0 0.5pt, transparent 0.5pt 4pt) !important;
|
|
}
|
|
.matrix__cell[data-score="9"], .matrix__cell[data-score="10"], .matrix__cell[data-score="12"] {
|
|
background: repeating-linear-gradient(45deg, rgba(0,0,0,0.32) 0 0.7pt, transparent 0.7pt 3pt) !important;
|
|
}
|
|
.matrix__cell[data-score="15"], .matrix__cell[data-score="16"], .matrix__cell[data-score="20"] {
|
|
background: repeating-linear-gradient(45deg, rgba(0,0,0,0.48) 0 1pt, transparent 1pt 2pt) !important;
|
|
}
|
|
.matrix__cell[data-score="25"] { background: #000 !important; color: #FFF !important; }
|
|
.matrix__cell[data-score="25"] .matrix__cell-score { color: #FFF !important; }
|
|
|
|
/* Surfaces flat */
|
|
.card, .pane, .finding, .critique, .scenario-card, .posture-summary, .verdict-block {
|
|
background: #FFF !important;
|
|
border: 0.5pt solid #888 !important;
|
|
box-shadow: none !important;
|
|
border-radius: 0 !important;
|
|
}
|
|
|
|
/* Links visible but not underlined-everything */
|
|
a { color: #000; text-decoration: none; }
|
|
a[href^="http"]::after { content: " (" attr(href) ")"; font-size: 9pt; color: #555; }
|
|
a[href^="#"]::after, a[href^="/"]::after, a:not([href*="://"])::after { content: ""; }
|
|
|
|
/* Standard footer block: signaturfelt for offentlige dokumenter */
|
|
.print-footer {
|
|
margin-top: 24pt;
|
|
padding-top: 10pt;
|
|
border-top: 0.5pt solid #888;
|
|
display: grid;
|
|
grid-template-columns: 1fr 1fr;
|
|
gap: 18pt;
|
|
font-size: 10pt;
|
|
}
|
|
.print-signature { display: flex; flex-direction: column; gap: 28pt; }
|
|
.print-signature__line {
|
|
border-bottom: 0.5pt solid #000;
|
|
height: 28pt;
|
|
}
|
|
.print-signature__caption {
|
|
font-size: 9pt;
|
|
color: #555;
|
|
}
|
|
|
|
/* Header for offisielle rapporter — kommune-logo-slot */
|
|
.print-header {
|
|
display: grid;
|
|
grid-template-columns: auto 1fr;
|
|
gap: 14pt;
|
|
align-items: center;
|
|
padding-bottom: 10pt;
|
|
margin-bottom: 16pt;
|
|
border-bottom: 0.5pt solid #888;
|
|
}
|
|
.print-header__logo {
|
|
width: 40pt; height: 40pt;
|
|
border: 0.5pt solid #888;
|
|
display: flex; align-items: center; justify-content: center;
|
|
font-family: "Inter", sans-serif; font-size: 9pt; color: #888;
|
|
}
|
|
.print-header__meta { font-size: 9pt; color: #555; }
|
|
.print-header__meta strong { color: #000; }
|
|
|
|
/* Avoid orphan headings */
|
|
h2, h3, h4 { orphans: 3; widows: 3; }
|
|
p, li { orphans: 2; widows: 2; }
|
|
}
|
|
|
|
/* Screen-mode preview class — see print preview without actually printing */
|
|
.preview-print { background: #ddd; padding: var(--space-8); }
|
|
.preview-print .a4 {
|
|
width: 210mm; min-height: 297mm;
|
|
margin: 0 auto;
|
|
background: #fff;
|
|
padding: 22mm 18mm;
|
|
box-shadow: 0 6px 24px rgba(0,0,0,0.18);
|
|
font-size: 11pt; line-height: 1.45; color: #000;
|
|
}
|
|
.preview-print .a4 + .a4 { margin-top: 12mm; }
|