ktg-plugin-marketplace/shared/playground-examples/templates.html
Kjell Tore Guttormsen f95cc4b13d chore(privacy): scrub real-org references from shared/ + root
Replace named real-world entity with fictional generic Norwegian
public-sector entity ("Direktoratet for digital tjenesteutvikling",
DDT) across the design system reference scenarios and root docs.
Repository is a private personal project; references to a real
organization were unintended and unrelated to the project.

- Rename: security-vegvesen.html -> security-direktorat.html
- Persona: replaced with fictional Kari Nordmann
- Domain refs / acronym / rule-IDs: SVV* -> DDT*
- Internal system names (Autosys etc.): replaced with fictional names

Phase 2 (plugin-internal references) follows in next commit.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-03 04:22:29 +02:00

465 lines
28 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!doctype html>
<html lang="nb">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Templates · 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/print.css" />
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<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>
.page { padding: var(--space-8) 0 var(--space-16); }
.tpl-grid { display: grid; grid-template-columns: 240px 1fr; gap: var(--space-8); align-items: start; }
.tpl-nav { position: sticky; top: var(--space-4); display: flex; flex-direction: column; gap: 2px; }
.tpl-nav a {
padding: 8px 12px; font-size: var(--font-size-sm);
color: var(--color-text-secondary); text-decoration: none;
border-radius: var(--radius-sm); border-left: 2px solid transparent;
}
.tpl-nav a:hover { background: var(--color-bg-soft); color: var(--color-text-primary); }
.tpl-nav a[aria-current="true"] { background: var(--color-primary-50); color: var(--color-primary-700); border-left-color: var(--color-primary-500); font-weight: var(--font-weight-medium); }
.tpl-nav__heading { font-size: 11px; text-transform: uppercase; letter-spacing: 0.06em; color: var(--color-text-tertiary); padding: 6px 12px; margin-top: var(--space-3); }
.tpl-nav__heading:first-child { margin-top: 0; }
.tpl { margin-bottom: var(--space-12); padding-bottom: var(--space-8); border-bottom: 1px solid var(--color-border-subtle); }
.tpl__head { display: flex; justify-content: space-between; align-items: flex-end; margin-bottom: var(--space-4); }
.tpl__title { display: flex; flex-direction: column; gap: 4px; }
.tpl__title h2 { font-size: var(--font-size-2xl); margin: 0; }
.tpl__eyebrow { font-size: 11px; text-transform: uppercase; letter-spacing: 0.08em; color: var(--color-text-tertiary); font-weight: var(--font-weight-semibold); }
.tpl__lede { color: var(--color-text-secondary); font-size: var(--font-size-sm); margin-top: 4px; max-width: var(--measure); }
.tpl__demo {
background: var(--color-bg-soft);
border: 1px solid var(--color-border-subtle);
border-radius: var(--radius-md);
padding: var(--space-6);
margin-bottom: var(--space-3);
}
.tpl__code {
background: #1F2328; color: #E6E6E6;
border-radius: var(--radius-md);
padding: var(--space-4);
font-family: var(--font-family-mono);
font-size: 12px;
line-height: 1.55;
overflow-x: auto;
white-space: pre;
max-height: 320px;
overflow-y: auto;
}
.tpl__copy {
display: flex; justify-content: space-between; align-items: center;
padding: 6px 10px;
background: #2A2F36; color: #C2C8D0;
font-size: 11px; font-family: var(--font-family-mono);
border-radius: var(--radius-md) var(--radius-md) 0 0;
margin-bottom: 0;
}
.tpl__copy + .tpl__code { border-radius: 0 0 var(--radius-md) var(--radius-md); }
.tpl__copy button {
background: transparent; border: 1px solid #3A3F47; color: #C2C8D0;
padding: 3px 8px; border-radius: 3px; font-size: 11px; cursor: pointer; font-family: inherit;
}
.tpl__copy button:hover { background: #3A3F47; }
.pg-print-preview-banner {
background: var(--color-bg-soft); border: 1px solid var(--color-border-subtle); padding: var(--space-3) var(--space-4);
border-radius: var(--radius-md); display: flex; gap: var(--space-3); align-items: center;
margin-bottom: var(--space-4); font-size: var(--font-size-sm);
}
/* A4-preview emulator (skjerm) */
.a4-preview {
background: #ddd;
padding: var(--space-6);
border-radius: var(--radius-md);
overflow: auto;
}
.a4-page {
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-family: "Inter", sans-serif;
font-size: 11pt;
line-height: 1.45;
color: #000;
transform: scale(0.72); transform-origin: top center;
}
@media (max-width: 980px) {
.tpl-grid { grid-template-columns: 1fr; }
.tpl-nav { position: static; }
}
</style>
</head>
<body>
<header class="app-header">
<a href="index.html" class="app-header__brand">
<span class="app-header__brand-mark">P</span>
<span>Playground Design System</span>
</a>
<span class="app-header__breadcrumb"><span aria-hidden="true">/</span> Templates</span>
<span class="app-header__spacer"></span>
<a href="index.html" class="btn btn--ghost btn--sm">← Til oversikt</a>
</header>
<main class="container container--wide page">
<div class="tpl-grid">
<!-- NAV -->
<nav class="tpl-nav" aria-label="Templates">
<span class="tpl-nav__heading">HTML-startere</span>
<a href="#skeleton" aria-current="true">Skeleton</a>
<a href="#intake-wizard">Intake-wizard</a>
<a href="#single-report">Single-report</a>
<a href="#findings-review">Findings-review</a>
<a href="#live-writer">Live-writer</a>
<span class="tpl-nav__heading">Print &amp; data</span>
<a href="#a4-print">A4-rapport (print)</a>
<a href="#schemas">JSON-skjemaer</a>
</nav>
<!-- CONTENT -->
<div>
<div style="margin-bottom: var(--space-8);">
<span style="font-size: 11px; text-transform: uppercase; letter-spacing: 0.1em; color: var(--color-text-tertiary); font-weight: var(--font-weight-semibold);">Fase 3 · Templates</span>
<h1 style="margin: 4px 0 8px; font-size: var(--font-size-3xl);">Copy-paste startere for nye plugins</h1>
<p style="color: var(--color-text-secondary); max-width: 65ch; font-size: var(--font-size-md);">
Hver template er minst mulig HTML som korrekt importerer designsystemet og bruker etablerte mønstre.
Forke en plugin? Start fra én av disse, ikke fra blank fil.
</p>
</div>
<!-- ============================================== -->
<!-- SKELETON -->
<!-- ============================================== -->
<section class="tpl" id="skeleton">
<div class="tpl__head">
<div class="tpl__title">
<span class="tpl__eyebrow">Template 01</span>
<h2>Skeleton — minimal HTML-side</h2>
<p class="tpl__lede">Bare designsystemet importert. Container, header, og en tom <code>main</code>. Bruk når du vil bygge noe helt eget med tokens og base-styling.</p>
</div>
<span class="badge badge--soft">~ 30 linjer</span>
</div>
<div class="tpl__copy"><span>scenarios/&lt;ditt-scenario&gt;.html</span><button onclick="copyCode(this)">Kopier</button></div>
<pre class="tpl__code">&lt;!doctype html&gt;
&lt;html lang="nb"&gt;
&lt;head&gt;
&lt;meta charset="utf-8" /&gt;
&lt;meta name="viewport" content="width=device-width, initial-scale=1" /&gt;
&lt;title&gt;Min plugin — &lt;org&gt;&lt;/title&gt;
&lt;link rel="stylesheet" href="../playground-design-system/tokens.css" /&gt;
&lt;link rel="stylesheet" href="../playground-design-system/base.css" /&gt;
&lt;link rel="stylesheet" href="../playground-design-system/components.css" /&gt;
&lt;link rel="stylesheet" href="../playground-design-system/components-tier2.css" /&gt;
&lt;link rel="stylesheet" href="../playground-design-system/print.css" /&gt;
&lt;link rel="preconnect" href="https://fonts.googleapis.com"&gt;
&lt;link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&amp;family=JetBrains+Mono:wght@400;500;600&amp;display=swap" rel="stylesheet"&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;header class="app-header"&gt;
&lt;a href="index.html" class="app-header__brand"&gt;
&lt;span class="app-header__brand-mark"&gt;P&lt;/span&gt;
&lt;span&gt;Min plugin&lt;/span&gt;
&lt;/a&gt;
&lt;span class="app-header__breadcrumb"&gt;/ &lt;org&gt;&lt;/span&gt;
&lt;/header&gt;
&lt;main class="container container--wide" style="padding: var(--space-8) 0;"&gt;
&lt;h1&gt;Tittel&lt;/h1&gt;
&lt;p class="text-secondary"&gt;Innhold her.&lt;/p&gt;
&lt;/main&gt;
&lt;/body&gt;
&lt;/html&gt;</pre>
</section>
<!-- ============================================== -->
<!-- INTAKE WIZARD -->
<!-- ============================================== -->
<section class="tpl" id="intake-wizard">
<div class="tpl__head">
<div class="tpl__title">
<span class="tpl__eyebrow">Template 02</span>
<h2>Intake-wizard</h2>
<p class="tpl__lede">Fire-stegs onboarding. Sticky stepper, valideringsgate framover, localStorage-persistens. Brukes for ROS-intake, OKR-onboarding, security-clean.</p>
</div>
<span class="badge badge--soft">scenarios/ros-lier-kommune.html (skjerm 1)</span>
</div>
<div class="tpl__demo">
<nav class="stepper" style="margin-bottom: 0; border-bottom: none; padding-bottom: 0;">
<button type="button" class="stepper__step" data-state="complete">
<span class="stepper__step-number"><span class="stepper__step-number-text">1</span></span>
<span class="stepper__step-text"><span class="stepper__step-label">Org-profil</span><span class="stepper__step-hint">Ferdig</span></span>
</button>
<button type="button" class="stepper__step" data-state="active">
<span class="stepper__step-number"><span class="stepper__step-number-text">2</span></span>
<span class="stepper__step-text"><span class="stepper__step-label">System</span><span class="stepper__step-hint">Pågår</span></span>
</button>
<button type="button" class="stepper__step" data-state="pending">
<span class="stepper__step-number"><span class="stepper__step-number-text">3</span></span>
<span class="stepper__step-text"><span class="stepper__step-label">Compliance</span><span class="stepper__step-hint">Venter</span></span>
</button>
<button type="button" class="stepper__step" data-state="pending">
<span class="stepper__step-number"><span class="stepper__step-number-text">4</span></span>
<span class="stepper__step-text"><span class="stepper__step-label">Bekreft</span><span class="stepper__step-hint">Venter</span></span>
</button>
</nav>
</div>
<p style="font-size: 12px; color: var(--color-text-tertiary); font-family: var(--font-family-mono);">→ Se <a href="../scenarios/ros-lier-kommune.html#intake">ros-lier-kommune.html#intake</a> for full implementasjon med skjema-felt og validering.</p>
</section>
<!-- ============================================== -->
<!-- SINGLE REPORT -->
<!-- ============================================== -->
<section class="tpl" id="single-report">
<div class="tpl__head">
<div class="tpl__title">
<span class="tpl__eyebrow">Template 03</span>
<h2>Single-report</h2>
<p class="tpl__lede">Én rapport, fire seksjoner: header med metadata + verdict-pill, hovedinnhold, sidefelt, signatur. Bygd for projector-bruk og PDF-eksport.</p>
</div>
<span class="badge badge--soft">scenarios/security-direktorat.html</span>
</div>
<div class="tpl__demo" style="background: #fff; padding: var(--space-5);">
<div style="display: grid; grid-template-columns: 1fr auto; gap: var(--space-5); align-items: start; padding-bottom: var(--space-4); border-bottom: 1px solid var(--color-border-subtle);">
<div>
<span style="font-size: 11px; text-transform: uppercase; letter-spacing: 0.08em; color: var(--color-scope-architect); font-weight: var(--font-weight-semibold);">Eyebrow · scope</span>
<h3 style="margin: 4px 0 6px; font-size: var(--font-size-xl);">Rapporttittel</h3>
<div style="display: flex; gap: var(--space-3); font-size: var(--font-size-sm); color: var(--color-text-secondary);">
<span><span style="font-size: 11px; color: var(--color-text-tertiary); text-transform: uppercase; letter-spacing: 0.06em;">Eier</span> Person</span>
<span><span style="font-size: 11px; color: var(--color-text-tertiary); text-transform: uppercase; letter-spacing: 0.06em;">Dato</span> 02. mai</span>
</div>
</div>
<span class="verdict-pill-lg" data-verdict="warning" style="padding: 8px 14px;">
<span class="verdict-pill-lg__verdict" style="font-size: var(--font-size-md);">WARN</span>
<span class="verdict-pill-lg__sub">Manuell gjennomgang</span>
</span>
</div>
<div style="display: grid; grid-template-columns: 1fr 220px; gap: var(--space-5); margin-top: var(--space-4);">
<div>
<h4 style="font-size: 11px; text-transform: uppercase; letter-spacing: 0.06em; color: var(--color-text-tertiary); margin: 0 0 8px;">Sammendrag</h4>
<p style="font-size: var(--font-size-sm); color: var(--color-text-secondary); margin: 0;">Hovedinnhold går her — typisk 2-4 avsnitt med mellomtitler.</p>
</div>
<aside style="padding-left: var(--space-4); border-left: 1px solid var(--color-border-subtle); font-size: 12px; color: var(--color-text-secondary);">
<strong>Kort fakta</strong><br>
Sidekontekst, henvisninger, neste-steg.
</aside>
</div>
</div>
</section>
<!-- ============================================== -->
<!-- FINDINGS REVIEW -->
<!-- ============================================== -->
<section class="tpl" id="findings-review">
<div class="tpl__head">
<div class="tpl__title">
<span class="tpl__eyebrow">Template 04</span>
<h2>Findings-review</h2>
<p class="tpl__lede">Posture-grid + filter-bar + finding-kort + tiltaksplan. Strukturen i Scenario C i konsentrert form.</p>
</div>
<span class="badge badge--soft">scenarios/security-direktorat.html</span>
</div>
<div class="tpl__demo" style="background: var(--color-surface);">
<div class="filter-bar" style="margin-bottom: var(--space-4);">
<div class="filter-bar__group">
<span class="filter-bar__label">Alvorlighet</span>
<button class="chip" aria-pressed="true">Alle <span class="chip__count">12</span></button>
<button class="chip" aria-pressed="false">Kritisk <span class="chip__count">2</span></button>
<button class="chip" aria-pressed="false">Høy <span class="chip__count">3</span></button>
</div>
</div>
<article class="finding" data-sev="high" style="margin-bottom: 0;">
<header class="finding__head">
<div>
<div class="finding__id">PROJEKT-123 · F-001</div>
<h3 class="finding__title" style="font-size: var(--font-size-md);">Funn-tittel</h3>
</div>
<div></div>
<div class="finding__badges">
<span class="rule-badge badge--owasp-llm">RULE01</span>
<span class="badge" style="background: var(--color-severity-high); color: #fff;">Høy</span>
</div>
</header>
<div class="finding__body" style="padding: var(--space-3) var(--space-4);">
<p style="margin: 0; font-size: var(--font-size-sm); color: var(--color-text-secondary);">Kort beskrivelse av funnet. Full struktur med kildekontekst, anbefaling og side-felt finnes i Scenario C.</p>
</div>
</article>
</div>
</section>
<!-- ============================================== -->
<!-- LIVE WRITER -->
<!-- ============================================== -->
<section class="tpl" id="live-writer">
<div class="tpl__head">
<div class="tpl__title">
<span class="tpl__eyebrow">Template 05</span>
<h2>Live-writer</h2>
<p class="tpl__lede">To-pane: editor med inline highlights til venstre, kritikk-stack til høyre. Score-strip øverst. Fire view-modi: skriv / sammenlign / kohort / endelig.</p>
</div>
<span class="badge badge--soft">scenarios/okr-baerum.html</span>
</div>
<div class="tpl__demo" style="padding: var(--space-4);">
<div style="display: grid; grid-template-columns: 1.4fr 1fr; gap: var(--space-4);">
<div style="background: #fff; border: 1px solid var(--color-border-subtle); border-radius: var(--radius-md); padding: var(--space-3);">
<div style="font-size: 11px; color: var(--color-text-tertiary); text-transform: uppercase; letter-spacing: 0.06em; margin-bottom: 6px;">Editor</div>
<p style="margin: 0; font-family: var(--font-family-serif); font-size: 16px; line-height: 1.55;">
Innhold med <span style="background-image: linear-gradient(transparent 60%, rgba(204,90,0,0.22) 60%); border-bottom: 2px solid var(--color-severity-high); padding-bottom: 1px;">inline highlight</span> som lenker til kritikk-kortet til høyre.
</p>
</div>
<div style="background: #fff; border: 1px solid var(--color-primary-500); border-radius: var(--radius-md); padding: var(--space-3); box-shadow: 0 0 0 2px var(--color-primary-100);">
<div style="display: flex; gap: 8px; align-items: center; margin-bottom: 4px;">
<span style="width: 8px; height: 8px; border-radius: 50%; background: var(--color-severity-high);"></span>
<strong style="font-size: var(--font-size-sm);">Kritikk-tittel</strong>
</div>
<p style="margin: 0 0 8px; font-size: 12px; color: var(--color-text-secondary); line-height: 1.5;">Kort forklaring og forslag til omskriving.</p>
<button class="btn btn--primary btn--sm">Bruk forslag</button>
</div>
</div>
</div>
</section>
<!-- ============================================== -->
<!-- A4 PRINT -->
<!-- ============================================== -->
<section class="tpl" id="a4-print">
<div class="tpl__head">
<div class="tpl__title">
<span class="tpl__eyebrow">Template 06 · Print</span>
<h2>A4-rapport · offentlig dokument</h2>
<p class="tpl__lede">Skraverings-mønstre i stedet for farge for B/W-utskrift. Header med kommune-logo-slot og signaturfelt. Importer <code>print.css</code> og legg innhold i en <code>.a4</code>-wrapper for skjerm-preview.</p>
</div>
<button class="btn btn--secondary btn--sm" onclick="window.print()">Skriv ut nå</button>
</div>
<div class="pg-print-preview-banner">
<span style="font-size: 18px;">📄</span>
<span>Slik ser dokumentet ut på A4. <kbd style="background: var(--color-bg-soft); border: 1px solid var(--color-border-moderate); border-radius: 3px; padding: 1px 5px; font-family: var(--font-family-mono); font-size: 11px;">Cmd/Ctrl + P</kbd> for ekte print-preview.</span>
</div>
<div class="a4-preview">
<div class="a4-page" id="a4-demo">
<div class="print-header" style="display: grid; grid-template-columns: auto 1fr; gap: 14pt; align-items: center; padding-bottom: 10pt; margin-bottom: 16pt; border-bottom: 0.5pt solid #888;">
<div class="print-header__logo" style="width: 40pt; height: 40pt; border: 0.5pt solid #888; display: flex; align-items: center; justify-content: center; font-size: 9pt; color: #888;">[logo]</div>
<div>
<div style="font-size: 9pt; color: #555; text-transform: uppercase; letter-spacing: 0.06em;">Lier kommune · IT-styring</div>
<div style="font-size: 14pt; font-weight: 600; margin: 2pt 0;">Risiko- og sårbarhetsanalyse · M365 Copilot</div>
<div style="font-size: 9pt; color: #555;"><strong>ROS-2026-LIER-COPILOT-01</strong> · 02. mai 2026 · Eier: Eli Bjerke</div>
</div>
</div>
<h2 style="font-size: 12pt; margin: 12pt 0 4pt;">Sammendrag</h2>
<p style="font-size: 10pt; line-height: 1.45; margin: 0 0 8pt;">M365 Copilot foreslås innført for 1 850 ansatte. Analysen identifiserte 49 trusler, hvorav 4 ligger i kritisk sone og 12 i høy sone før mitigerende tiltak. Anbefalingen er <strong>GO med fire betingelser</strong> beskrevet i kap. 6.</p>
<h2 style="font-size: 12pt; margin: 12pt 0 4pt;">Risiko-matrise (5×5)</h2>
<table style="border-collapse: collapse; width: 100%; font-size: 9pt; margin-bottom: 8pt;">
<thead>
<tr><th style="padding: 4pt; border-bottom: 0.5pt solid #000; text-align: left;">Sone</th><th style="padding: 4pt; border-bottom: 0.5pt solid #000;">Mønster</th><th style="padding: 4pt; border-bottom: 0.5pt solid #000;">Antall trusler</th></tr>
</thead>
<tbody>
<tr><td style="padding: 4pt;">Lav (14)</td><td style="padding: 4pt;"><span style="display: inline-block; width: 18pt; height: 10pt; background: #fff; border: 0.5pt solid #000; vertical-align: middle;"></span></td><td style="padding: 4pt;">21</td></tr>
<tr><td style="padding: 4pt;">Moderat (58)</td><td style="padding: 4pt;"><span style="display: inline-block; width: 18pt; height: 10pt; background: repeating-linear-gradient(45deg, #000 0 0.5pt, transparent 0.5pt 4pt); border: 0.5pt solid #000; vertical-align: middle;"></span></td><td style="padding: 4pt;">12</td></tr>
<tr><td style="padding: 4pt;">Høy (912)</td><td style="padding: 4pt;"><span style="display: inline-block; width: 18pt; height: 10pt; background: repeating-linear-gradient(45deg, #000 0 0.7pt, transparent 0.7pt 3pt); border: 0.5pt solid #000; vertical-align: middle;"></span></td><td style="padding: 4pt;">12</td></tr>
<tr><td style="padding: 4pt;">Kritisk (1520)</td><td style="padding: 4pt;"><span style="display: inline-block; width: 18pt; height: 10pt; background: repeating-linear-gradient(45deg, #000 0 1pt, transparent 1pt 2pt); border: 0.5pt solid #000; vertical-align: middle;"></span></td><td style="padding: 4pt;">3</td></tr>
<tr><td style="padding: 4pt;">Ekstrem (25)</td><td style="padding: 4pt;"><span style="display: inline-block; width: 18pt; height: 10pt; background: #000; border: 0.5pt solid #000; vertical-align: middle;"></span></td><td style="padding: 4pt;">1</td></tr>
</tbody>
</table>
<h2 style="font-size: 12pt; margin: 12pt 0 4pt;">Anbefaling</h2>
<p style="font-size: 10pt; line-height: 1.45; margin: 0 0 8pt;">GO med fire betingelser: (1) DLP-policy aktivert i tenant før utrulling. (2) Sensitivity Labels innført i alle arkivsystem. (3) Schrems II-vurdering ferdigstilt for cross-tenant. (4) Innbygger-tilfredshetsmåling baseline T1.</p>
<div class="print-footer" style="margin-top: 24pt; padding-top: 10pt; border-top: 0.5pt solid #888; display: grid; grid-template-columns: 1fr 1fr; gap: 18pt; font-size: 9pt;">
<div class="print-signature">
<div class="print-signature__line" style="border-bottom: 0.5pt solid #000; height: 28pt;"></div>
<div class="print-signature__caption" style="font-size: 9pt; color: #555;">Eli Bjerke · IT-sikkerhetsleder · dato</div>
</div>
<div class="print-signature">
<div class="print-signature__line" style="border-bottom: 0.5pt solid #000; height: 28pt;"></div>
<div class="print-signature__caption" style="font-size: 9pt; color: #555;">Kommunaldirektør · dato</div>
</div>
</div>
</div>
</div>
</section>
<!-- ============================================== -->
<!-- SCHEMAS -->
<!-- ============================================== -->
<section class="tpl" id="schemas">
<div class="tpl__head">
<div class="tpl__title">
<span class="tpl__eyebrow">Datakontrakter</span>
<h2>JSON-skjemaer</h2>
<p class="tpl__lede">Tre skjemaer som lar plugins utveksle data uten gjetting. Validér med vanilig <code>ajv</code> eller VS Codes innebygde schema-validator.</p>
</div>
</div>
<div style="display: grid; grid-template-columns: 1fr 1fr 1fr; gap: var(--space-3);">
<a class="card" style="text-decoration: none; color: inherit; display: flex; flex-direction: column; gap: 6px;" href="../playground-design-system/schemas/finding.schema.json">
<span style="font-size: 11px; color: var(--color-text-tertiary); text-transform: uppercase; letter-spacing: 0.06em;">Schema</span>
<strong>finding.schema.json</strong>
<span style="font-size: 12px; color: var(--color-text-secondary);">Ett funn fra en skanning. severity, source, evidence, recommendation, status.</span>
<span style="font-family: var(--font-family-mono); font-size: 11px; color: var(--color-text-tertiary); margin-top: auto;">llm-security · config-audit · ms-ai-review · ultraplan-review</span>
</a>
<a class="card" style="text-decoration: none; color: inherit; display: flex; flex-direction: column; gap: 6px;" href="../playground-design-system/schemas/okr-set.schema.json">
<span style="font-size: 11px; color: var(--color-text-tertiary); text-transform: uppercase; letter-spacing: 0.06em;">Schema</span>
<strong>okr-set.schema.json</strong>
<span style="font-size: 12px; color: var(--color-text-secondary);">Objective + 16 nøkkelresultater. baseline/target/stretch, period, score, critiques.</span>
<span style="font-family: var(--font-family-mono); font-size: 11px; color: var(--color-text-tertiary); margin-top: auto;">OKR live-writer</span>
</a>
<a class="card" style="text-decoration: none; color: inherit; display: flex; flex-direction: column; gap: 6px;" href="../playground-design-system/schemas/ros-threat.schema.json">
<span style="font-size: 11px; color: var(--color-text-tertiary); text-transform: uppercase; letter-spacing: 0.06em;">Schema</span>
<strong>ros-threat.schema.json</strong>
<span style="font-size: 12px; color: var(--color-text-secondary);">NS 5814-justert trussel. inherent + residual, controls (M-001…), regulatory_refs.</span>
<span style="font-family: var(--font-family-mono); font-size: 11px; color: var(--color-text-tertiary); margin-top: auto;">ms-ai-architect</span>
</a>
</div>
<p style="font-size: 12px; color: var(--color-text-tertiary); margin-top: var(--space-4);">Bruk i HTML/JS: <code>fetch('/shared/playground-design-system/schemas/finding.schema.json').then(r =&gt; r.json())</code></p>
</section>
</div>
</div>
</main>
<script>
// smooth nav
document.querySelectorAll('.tpl-nav a').forEach(a => {
a.addEventListener('click', () => {
document.querySelectorAll('.tpl-nav a').forEach(x => x.removeAttribute('aria-current'));
a.setAttribute('aria-current', 'true');
});
});
function copyCode(btn) {
const code = btn.closest('.tpl').querySelector('.tpl__code').textContent;
navigator.clipboard?.writeText(code).then(() => {
const orig = btn.textContent;
btn.textContent = 'Kopiert!';
setTimeout(() => { btn.textContent = orig; }, 1400);
});
}
</script>
</body>
</html>