Mirror av ms-ai-architect playground-arkitektur, tilpasset llm-security:
- 4 overflater (onboarding/home/catalog/project) med surface-router
- IndexedDB persistens (llm-security-playground-v1) + localStorage fallback
- Theme-bootstrap med FOUC-prevention og localStorage-persist
- 20 kommandoer i CATALOG (5 kategorier: discover/posture/findings-ops/
hardening/adversarial/mcp-ops) med full input_fields + report_archetype
- 5-gruppers onboarding (organisasjon/scope/profil/plattform/compliance)
med form-progress sidebar
- Home: 3 tracks + fleet-grid prosjektliste + tom-state med demo-data
- Katalog: ekspanderbare grupper med live-søk og forhåndsvisning
- Prosjekt-stub: 4 screen-tabs + 6 kategori-tabs + per-kommando
skjema/paste-import/rapport-soner
- Demo-state: Direktoratet for digital tjenesteutvikling med 2 prosjekter
- Eksport/import (JSON envelope), action-handlers (35), modal-portal
PARSERS + RENDERERS er tomme routing-objekter — fylles i Fase 2 (10 høy-prio
kommandoer) og Fase 3 (resterende 10). Paste-import viser «parser ikke
implementert»-guide-panel for kommandoer uten parser, og lagrer rå markdown
i state for fremtidig parsing.
Vendor: 27 filer synket fra shared/playground-design-system/
(MANIFEST.json sjekksum-låst, source_commit 487f7ae).
Verifisert: node --check OK (2737 linjer, 113733 char inline JS),
HTML-tag-balanse OK. Manuell smoke-test gjenstår.
Docs (plugin README, CLAUDE.md, rot-README) bumpes ved Fase 3-fullføring
sammen med plugin.json v7.5.0. Derfor [skip-docs] her.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
176 lines
7 KiB
CSS
176 lines
7 KiB
CSS
/* Code generated by sync-design-system.mjs; DO NOT EDIT. */
|
|
/* =============================================================================
|
|
print.css — A4 print stylesheet for offentlige dokumenter
|
|
- Severity-mønstre (skravur) som fungerer i B/W
|
|
- Header/footer med kommune-logo-slot, signaturfelt, paginering
|
|
- 12pt minimum kropp, 11pt for metadata
|
|
- Skjuler interaktiv chrome (header, knapper, toggles)
|
|
============================================================================= */
|
|
|
|
@page {
|
|
size: A4 portrait;
|
|
margin: 22mm 18mm 24mm 18mm;
|
|
@bottom-right { content: counter(page) " / " counter(pages); font-family: "Inter", sans-serif; font-size: 9pt; color: #555; }
|
|
}
|
|
@page :first { @top-left { content: none; } }
|
|
@page landscape { size: A4 landscape; }
|
|
|
|
/* SVG severity-mønstre (skravur) — definert i print-only inline-svg.
|
|
For å bruke: legg til class .pattern-low/.pattern-medium/etc. på elementet
|
|
som ellers fyller med severity-fargen. */
|
|
@media print {
|
|
|
|
:root {
|
|
--color-bg: #FFFFFF;
|
|
--color-surface: #FFFFFF;
|
|
--color-surface-sunken: #F5F5F5;
|
|
--color-bg-soft: #F7F7F7;
|
|
--color-border-subtle: #C7C7C7;
|
|
--color-border-moderate: #888888;
|
|
--color-text-primary: #000000;
|
|
--color-text-secondary: #2A2A2A;
|
|
--color-text-tertiary: #555555;
|
|
}
|
|
|
|
html, body { background: #FFFFFF !important; color: #000 !important; font-size: 11pt !important; }
|
|
body { -webkit-print-color-adjust: exact; print-color-adjust: exact; }
|
|
|
|
/* Hide interactive chrome */
|
|
.app-header, header.app-header,
|
|
.theme-toggle, #theme-toggle, #themeToggle,
|
|
.filter-bar, .view-toggle, .screen-tabs,
|
|
.btn--primary, .btn--secondary, .btn--ghost,
|
|
.live-dot, .pane__head .badge,
|
|
.accept-banner button,
|
|
.scenario-card .btn,
|
|
.footer { display: none !important; }
|
|
|
|
/* Container = full width on print */
|
|
.container, .container--wide { max-width: none !important; padding: 0 !important; }
|
|
|
|
/* Body type */
|
|
body, p, li, dd, dt, td, th, .field__value {
|
|
font-family: "Inter", sans-serif;
|
|
font-size: 11pt; line-height: 1.45; color: #000;
|
|
}
|
|
h1 { font-size: 22pt; line-height: 1.2; margin: 0 0 6pt; }
|
|
h2 { font-size: 16pt; line-height: 1.25; margin: 18pt 0 6pt; page-break-after: avoid; }
|
|
h3 { font-size: 13pt; margin: 12pt 0 4pt; page-break-after: avoid; }
|
|
h4 { font-size: 11pt; margin: 10pt 0 3pt; }
|
|
|
|
/* Page breaks */
|
|
.page-break { page-break-before: always; }
|
|
.avoid-break, .finding, .critique, .scenario-card, table, figure {
|
|
page-break-inside: avoid;
|
|
}
|
|
|
|
/* Severity patterns (B/W-safe). Stack pattern-bg + dotted/diag border indicators. */
|
|
.matrix__cell[data-score],
|
|
.badge--severity-low, .badge--severity-medium, .badge--severity-high,
|
|
.badge--severity-critical, .badge--severity-extreme {
|
|
background-color: #FFF !important;
|
|
color: #000 !important;
|
|
border: 1px solid #000 !important;
|
|
}
|
|
.badge--severity-low::before, .badge--severity-medium::before,
|
|
.badge--severity-high::before, .badge--severity-critical::before,
|
|
.badge--severity-extreme::before {
|
|
content: ""; display: inline-block;
|
|
width: 7pt; height: 7pt; margin-right: 4pt;
|
|
border: 1px solid #000;
|
|
vertical-align: middle;
|
|
}
|
|
.badge--severity-low::before { background: #FFF; }
|
|
.badge--severity-medium::before { background: repeating-linear-gradient(45deg, #000 0 0.6pt, transparent 0.6pt 3pt); }
|
|
.badge--severity-high::before { background: repeating-linear-gradient(45deg, #000 0 1pt, transparent 1pt 2.5pt); }
|
|
.badge--severity-critical::before { background: repeating-linear-gradient(0deg, #000 0 0.5pt, transparent 0.5pt 2pt),
|
|
repeating-linear-gradient(90deg, #000 0 0.5pt, transparent 0.5pt 2pt); }
|
|
.badge--severity-extreme::before { background: #000; }
|
|
|
|
/* Matrix cells in print: skravur i stedet for farge */
|
|
.matrix__cell { color: #000 !important; border: 0.5pt solid #888 !important; }
|
|
.matrix__cell[data-score]:not([data-score="0"]) { background: #FFF !important; }
|
|
.matrix__cell[data-score="1"], .matrix__cell[data-score="2"],
|
|
.matrix__cell[data-score="3"], .matrix__cell[data-score="4"] {
|
|
background: #FFF !important;
|
|
}
|
|
.matrix__cell[data-score="5"], .matrix__cell[data-score="6"], .matrix__cell[data-score="8"] {
|
|
background: repeating-linear-gradient(45deg, rgba(0,0,0,0.18) 0 0.5pt, transparent 0.5pt 4pt) !important;
|
|
}
|
|
.matrix__cell[data-score="9"], .matrix__cell[data-score="10"], .matrix__cell[data-score="12"] {
|
|
background: repeating-linear-gradient(45deg, rgba(0,0,0,0.32) 0 0.7pt, transparent 0.7pt 3pt) !important;
|
|
}
|
|
.matrix__cell[data-score="15"], .matrix__cell[data-score="16"], .matrix__cell[data-score="20"] {
|
|
background: repeating-linear-gradient(45deg, rgba(0,0,0,0.48) 0 1pt, transparent 1pt 2pt) !important;
|
|
}
|
|
.matrix__cell[data-score="25"] { background: #000 !important; color: #FFF !important; }
|
|
.matrix__cell[data-score="25"] .matrix__cell-score { color: #FFF !important; }
|
|
|
|
/* Surfaces flat */
|
|
.card, .pane, .finding, .critique, .scenario-card, .posture-summary, .verdict-block {
|
|
background: #FFF !important;
|
|
border: 0.5pt solid #888 !important;
|
|
box-shadow: none !important;
|
|
border-radius: 0 !important;
|
|
}
|
|
|
|
/* Links visible but not underlined-everything */
|
|
a { color: #000; text-decoration: none; }
|
|
a[href^="http"]::after { content: " (" attr(href) ")"; font-size: 9pt; color: #555; }
|
|
a[href^="#"]::after, a[href^="/"]::after, a:not([href*="://"])::after { content: ""; }
|
|
|
|
/* Standard footer block: signaturfelt for offentlige dokumenter */
|
|
.print-footer {
|
|
margin-top: 24pt;
|
|
padding-top: 10pt;
|
|
border-top: 0.5pt solid #888;
|
|
display: grid;
|
|
grid-template-columns: 1fr 1fr;
|
|
gap: 18pt;
|
|
font-size: 10pt;
|
|
}
|
|
.print-signature { display: flex; flex-direction: column; gap: 28pt; }
|
|
.print-signature__line {
|
|
border-bottom: 0.5pt solid #000;
|
|
height: 28pt;
|
|
}
|
|
.print-signature__caption {
|
|
font-size: 9pt;
|
|
color: #555;
|
|
}
|
|
|
|
/* Header for offisielle rapporter — kommune-logo-slot */
|
|
.print-header {
|
|
display: grid;
|
|
grid-template-columns: auto 1fr;
|
|
gap: 14pt;
|
|
align-items: center;
|
|
padding-bottom: 10pt;
|
|
margin-bottom: 16pt;
|
|
border-bottom: 0.5pt solid #888;
|
|
}
|
|
.print-header__logo {
|
|
width: 40pt; height: 40pt;
|
|
border: 0.5pt solid #888;
|
|
display: flex; align-items: center; justify-content: center;
|
|
font-family: "Inter", sans-serif; font-size: 9pt; color: #888;
|
|
}
|
|
.print-header__meta { font-size: 9pt; color: #555; }
|
|
.print-header__meta strong { color: #000; }
|
|
|
|
/* Avoid orphan headings */
|
|
h2, h3, h4 { orphans: 3; widows: 3; }
|
|
p, li { orphans: 2; widows: 2; }
|
|
}
|
|
|
|
/* Screen-mode preview class — see print preview without actually printing */
|
|
.preview-print { background: #ddd; padding: var(--space-8); }
|
|
.preview-print .a4 {
|
|
width: 210mm; min-height: 297mm;
|
|
margin: 0 auto;
|
|
background: #fff;
|
|
padding: 22mm 18mm;
|
|
box-shadow: 0 6px 24px rgba(0,0,0,0.18);
|
|
font-size: 11pt; line-height: 1.45; color: #000;
|
|
}
|
|
.preview-print .a4 + .a4 { margin-top: 12mm; }
|