diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..c113a87
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,5 @@
+node_modules/
+.hugo_build.lock
+resources/_gen/
+public/
+build.log
diff --git a/archetypes/default.md b/archetypes/default.md
new file mode 100644
index 0000000..c6f3fce
--- /dev/null
+++ b/archetypes/default.md
@@ -0,0 +1,5 @@
++++
+title = '{{ replace .File.ContentBaseName "-" " " | title }}'
+date = {{ .Date }}
+draft = true
++++
diff --git a/assets/css/asw.css b/assets/css/asw.css
new file mode 100644
index 0000000..10dbe1a
--- /dev/null
+++ b/assets/css/asw.css
@@ -0,0 +1,25 @@
+/* ASW — Agentic Semantic Web Framework
+ * Entry point: Open Props foundation + ASW layer stack
+ * PostCSS-import resolves all @imports at build time
+ */
+
+/* 1. Full Open Props token foundation */
+@import "open-props/open-props.min.css";
+
+/* 2. ASW theme overrides — edit here to retheme */
+:root {
+ /* Override Open Props primitives or ASW semantics here */
+}
+
+/* 3. Framework layers — stable, do not edit */
+@import "./layers/00-reset.css";
+@import "./layers/01-tokens.css";
+@import "./layers/02-semantic.css";
+@import "./layers/03-components.css";
+@import "./layers/04-data-attrs.css";
+@import "./layers/05-utilities.css";
+@import "./layers/06-charts.css";
+@import "./layers/07-chroma.css";
+@import "./layers/08-layout.css";
+@import "./layers/08a-paper.css";
+@import "./layers/09-landing.css";
diff --git a/assets/css/layers/00-reset.css b/assets/css/layers/00-reset.css
new file mode 100644
index 0000000..d0323f9
--- /dev/null
+++ b/assets/css/layers/00-reset.css
@@ -0,0 +1,58 @@
+/**
+ * 00-reset.css
+ * CSS reset and normalization
+ * Ported from: Pico CSS v2.1.1
+ */
+
+/* Box-sizing reset */
+*,
+*::before,
+*::after {
+ box-sizing: border-box;
+ background-repeat: no-repeat;
+}
+
+::before,
+::after {
+ text-decoration: inherit;
+ vertical-align: inherit;
+}
+
+/* Document */
+:where(:root) {
+ -webkit-tap-highlight-color: transparent;
+ -webkit-text-size-adjust: 100%;
+ text-size-adjust: 100%;
+ text-rendering: optimizeLegibility;
+ overflow-wrap: break-word;
+ tab-size: 4;
+}
+
+/* Root font-size — 100% default, responsive scaling in 01-tokens.css */
+html {
+ font-size: 100%;
+}
+
+/* Body */
+body {
+ width: 100%;
+ margin: 0;
+ padding: 0;
+ font-size: var(--text-base); /* 1rem — inherits html responsive scaling */
+ font-family: var(--font-ui);
+ background-color: var(--surface);
+ color: var(--text);
+}
+
+/* Prose font — same neo-grotesque stack, consistent across all contexts */
+/* article and [data-layout="prose"] inherit body font — no override needed */
+
+/* Main */
+main {
+ display: block;
+}
+
+/* Nested lists */
+:where(dl, ol, ul) :where(dl, ol, ul) {
+ margin: 0;
+}
diff --git a/assets/css/layers/01-tokens.css b/assets/css/layers/01-tokens.css
new file mode 100644
index 0000000..2084cbe
--- /dev/null
+++ b/assets/css/layers/01-tokens.css
@@ -0,0 +1,343 @@
+/**
+ * 01-tokens.css
+ * ASW semantic layer — builds on Open Props
+ *
+ * Open Props (imported below) provides the base scales:
+ * --gray-0…15, --green-0…12, --blue-0…12, --red-0…12, --yellow-0…12
+ * --size-1…15, --font-size-0…8, --font-weight-1…9
+ * --font-lineheight-0…5, --radius-1…6, --shadow-1…6
+ * --ease-1…5, --ease-spring-1…5, --ease-bounce-1…5
+ * --gradient-1…30, --animation-*, @keyframes
+ *
+ * This file defines only what Open Props doesn't:
+ * 1. Surface / text / accent — semantic aliases (override to theme)
+ * 2. Font stack aliases — prose, heading, ui (map to OP font stacks)
+ * 3. Agent-native tokens — task, callout, session, wikilink, redacted
+ * 4. A handful of precise values without direct OP equivalents
+ *
+ * To theme ASW:
+ * Override semantic aliases at :root in your own CSS.
+ * Use Open Props base tokens (--gray-*, --green-*, --size-*) as values.
+ *
+ * Lineage: absorbed patterns from Pico CSS, Open Props, Charts.css.
+ */
+
+/* ── Project-specific custom media (complement Open Props) ──────────
+ Open Props doesn't define every breakpoint the layout needs.
+ These are resolved by PostCSS at build time alongside OP tokens.
+ ─────────────────────────────────────────────────────────────────── */
+@custom-media --docs-toc-hidden (width < 1100px); /* docs layout: 3→2 col */
+@custom-media --nav-compact (width < 991px); /* nav: allow link wrap */
+
+/* ══════════════════════════════════════════════════════════════════
+ DARK THEME (default)
+ Using Open Props oklch gray scale — perceptually uniform steps.
+ Set --gray-hue to tint all surfaces. Example:
+ Trentuna: --gray-hue: 45 (warm amber tint)
+ vigilio-garden: --gray-hue: 150 (subtle green tint)
+ ══════════════════════════════════════════════════════════════════ */
+
+:root {
+
+ /* ── Surfaces ──────────────────────────────────────────────────── */
+
+ --surface: var(--gray-15); /* deepest background (oklch 10%) */
+ --surface-1: var(--gray-14); /* cards, sidebars (oklch 18%) */
+ --surface-2: var(--gray-13); /* hover, raised elements (oklch 25%) */
+ --surface-card: var(--surface-1);
+ --surface-hover: var(--surface-2);
+
+ /* ── Text ──────────────────────────────────────────────────────── */
+
+ --text: var(--gray-1); /* primary (95% lightness) */
+ --text-2: var(--gray-3); /* secondary (80%) */
+ --text-3: var(--gray-5); /* muted (68%) */
+ --text-dim: var(--gray-7); /* dim (58%) */
+
+ /* ── Accent ────────────────────────────────────────────────────── */
+
+ --accent: var(--green-5);
+ --accent-hover: var(--green-4);
+ --on-accent: var(--gray-15);
+ --accent-focus: color-mix(in oklch, var(--green-5) 35%, transparent);
+ --accent-subtle: color-mix(in oklch, var(--green-5) 10%, transparent);
+ --accent-underline: color-mix(in oklch, var(--green-5) 45%, transparent);
+ --accent-hover-underline: color-mix(in oklch, var(--green-5) 55%, transparent);
+
+ /* ── Links ─────────────────────────────────────────────────────── */
+ /* Blue — web convention. Accent (green) reserved for UI chrome. */
+
+ --link: var(--blue-5); /* #339af0 */
+ --link-hover: var(--blue-4); /* #4dabf7 */
+ --link-underline: color-mix(in oklch, var(--blue-5) 40%, transparent);
+ --link-hover-underline: color-mix(in oklch, var(--blue-5) 55%, transparent);
+ --link-focus: color-mix(in oklch, var(--blue-5) 35%, transparent);
+
+ /* Secondary accents — reachable as named aliases */
+ --accent-blue: var(--blue-5);
+ --accent-red: var(--red-7);
+ --accent-orange: var(--yellow-6);
+
+ /* ── Border ────────────────────────────────────────────────────── */
+
+ --border: var(--gray-11); /* 37% lightness — visible against 10% bg */
+ --border-subtle: var(--gray-12); /* 31% lightness — very subtle */
+ --border-width: 1px;
+ --outline-width: 2px;
+
+ /* ── Font stacks ───────────────────────────────────────────────── */
+ /* Open Props named stacks — no web font loading required. */
+ /* --font-neo-grotesque: Inter, Roboto, Helvetica Neue, Arial Nova */
+ /* --font-monospace-code: Dank Mono, Operator Mono, Inconsolata... */
+
+ --font-prose: var(--font-neo-grotesque);
+ --font-heading: var(--font-neo-grotesque);
+ --font-ui: var(--font-neo-grotesque);
+ /* --font-mono: var(--font-monospace-code) — provided directly by Open Props */
+
+ /* ── Typography scale ─────────────────────────────────────────── */
+ /* Open Props provides: --font-size-0 (.75rem) through --font-size-8 (3.5rem) */
+ /* We define only the one gap: 0.875rem has no OP equivalent */
+
+ --text-xs: var(--font-size-0); /* 0.75rem — badges, fine print */
+ --text-sm: 0.875rem; /* 0.875rem — metadata, captions (no OP match) */
+ --text-base: var(--font-size-1); /* 1rem — body */
+ --text-2xl: var(--font-size-4); /* 1.5rem — subheadings */
+ --text-3xl: var(--font-size-5); /* 2rem — section headings */
+
+ /* ── Heading scale ─────────────────────────────────────────────── */
+
+ --h1-size: 1.875rem;
+ --h2-size: 1.5rem;
+ --h3-size: 1.25rem;
+ --h4-size: 1.0625rem;
+ --h5-size: 0.9375rem;
+ --h6-size: 0.8125rem;
+
+ --h1-weight: var(--font-weight-4); /* 400 */
+ --h2-weight: var(--font-weight-4);
+ --h3-weight: var(--font-weight-4);
+ --h4-weight: var(--font-weight-5); /* 500 */
+ --h5-weight: var(--font-weight-6); /* 600 */
+ --h6-weight: var(--font-weight-6);
+
+ --h1-color: var(--text);
+ --h2-color: var(--text);
+ --h3-color: var(--text);
+ --h4-color: var(--text-2);
+ --h5-color: var(--text-2);
+ --h6-color: var(--text-3);
+
+ /* ── Spacing aliases ─────────────────────────────────────────────
+ Open Props sizes: --size-1 (.25rem), --size-2 (.5rem), --size-3 (1rem),
+ --size-5 (1.5rem), --size-7 (2rem), --size-9 (4rem)
+ We alias these with semantic names AND define --space-3 (0.75rem gap)
+ ──────────────────────────────────────────────────────────────── */
+
+ --space-1: var(--size-1); /* 0.25rem */
+ --space-2: var(--size-2); /* 0.50rem */
+ --space-3: 0.75rem; /* 0.75rem — no OP equivalent */
+ --space-4: var(--size-3); /* 1.00rem */
+ --space-5: var(--size-5); /* 1.50rem */
+ --space-6: var(--size-7); /* 2.00rem */
+ --space-8: var(--size-9); /* 4.00rem */
+
+ /* ── Width tokens ───────────────────────────────────────────────── */
+
+ --width-prose: var(--size-content-3); /* 60ch — Open Props reading width */
+ --width-content: var(--size-lg); /* 1024px — Open Props content width */
+ --width-full: var(--width-xl); /* alias → --width-xl */
+
+ /* ── Layout breakpoints ──────────────────────────────────────────── */
+ /* These don't map exactly to Open Props --size-* — defined explicitly */
+
+ --width-sm: 510px;
+ --width-md: 700px;
+ --width-lg: 950px;
+ --width-xl: 1200px;
+ --width-2xl: 1450px;
+
+ /* ── Structural component dimensions ─────────────────────────────── */
+
+ --sidebar-width: 220px; /* docs sidebar column */
+ --toc-width: 200px; /* docs TOC column */
+ --nav-height: 60px; /* sticky nav offset for calc() */
+ --docs-max-width: 1400px; /* docs layout outer cap */
+ --card-min-width: 280px; /* card-grid minmax floor */
+ --tooltip-max-width: var(--size-px-14); /* 320px — tooltip overflow cap */
+ --scrollbar-size: var(--border-size-3); /* 5px — thin webkit scrollbar thumb */
+
+ /* ── Chart dimensions ────────────────────────────────────────────── */
+
+ --chart-radial-size: var(--size-px-11); /* 120px — radial gauge cell */
+ --chart-radial-inset: 18px; /* donut-hole inset — no OP equivalent */
+
+ /* ── Diff viewer tokens ──────────────────────────────────────────── */
+
+ --diff-add-bg: color-mix(in oklch, var(--green-5) 10%, transparent);
+ --diff-remove-bg: color-mix(in oklch, var(--red-7) 10%, transparent);
+ --diff-remove-text: var(--red-2);
+ --diff-hunk-bg: color-mix(in oklch, var(--blue-4) 7%, transparent);
+
+ /* ── AI-disclosure border tokens ────────────────────────────────── */
+
+ --ai-generated-border: color-mix(in oklch, var(--green-5) 25%, transparent);
+ --ai-assisted-border: color-mix(in oklch, var(--blue-4) 20%, transparent);
+ --ai-mixed-border: color-mix(in oklch, var(--yellow-6) 30%, transparent);
+
+ /* ── Rhythm ─────────────────────────────────────────────────────── */
+
+ --type-space: var(--space-4); /* paragraph / element spacing */
+ --type-space-top: var(--space-5); /* heading top margin after content */
+ --leading: 1.6;
+ --leading-tight: var(--font-lineheight-1); /* 1.25 */
+
+ /* ── Radius ─────────────────────────────────────────────────────── */
+ /* Open Props: --radius-1 (2px), --radius-2 (5px), --radius-3 (1rem) */
+
+ --radius-sm: var(--radius-1); /* 2px */
+ --radius-md: 4px; /* between OP radius-1 and radius-2 */
+
+ /* ── Easing ─────────────────────────────────────────────────────── */
+ /* Open Props provides rich curves — we alias the most-used ones */
+
+ --ease: var(--duration-moderate-1) var(--ease-3); /* 180ms — hover, focus, colour */
+ --ease-fast: var(--duration-quick-1) var(--ease-2); /* 80ms — instant feedback */
+ --spinner-duration: var(--duration-gentle-1); /* 320ms — spinner rotation cycle */
+
+ /* ── Inline element tokens ─────────────────────────────────────── */
+
+ --selection: color-mix(in oklch, var(--blue-4) 25%, transparent);
+ --mark-bg: color-mix(in oklch, var(--yellow-6) 20%, transparent);
+ --mark-color: var(--accent-orange);
+ --kbd-bg: var(--text);
+ --kbd-color: var(--surface);
+ --code-color: var(--text-2);
+ --table-stripe: color-mix(in oklch, var(--gray-14) 50%, transparent);
+
+ /* ── Form tokens ─────────────────────────────────────────────────── */
+
+ --input-bg: var(--surface-1);
+ --input-border: var(--border);
+ --input-active-bg: var(--surface);
+ --input-selected: color-mix(in oklch, var(--green-5) 20%, transparent);
+ --input-px: var(--space-4);
+ --input-py: var(--space-3);
+ --disabled-opacity: 0.5;
+
+ /* ── State colors ─────────────────────────────────────────────────── */
+
+ --ok: var(--green-5);
+ --warn: var(--yellow-5);
+ --error: var(--red-7);
+ --info: var(--blue-5);
+ --blocked: var(--gray-5);
+
+ --error-active: var(--red-9);
+ --error-focus: color-mix(in oklch, var(--red-7) 38%, transparent);
+
+ /* ── Component tokens ─────────────────────────────────────────────── */
+
+ --track-bg: var(--surface-2); /* progress / meter background */
+ --modal-overlay: color-mix(in oklch, var(--gray-15) 80%, transparent);
+ --modal-backdrop: blur(0.375rem);
+ --accordion-active: var(--accent-hover);
+
+ --icon-chevron: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='rgb(115, 115, 115)' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'%3E%3C/polyline%3E%3C/svg%3E");
+
+
+ /* ══════════════════════════════════════════════════════════════════
+ AGENT-NATIVE TOKENS
+ These are ASW's actual contribution — concepts no other framework has.
+ Propose additions to Open Props: data-task, data-callout, data-session.
+ ══════════════════════════════════════════════════════════════════ */
+
+ --task-done: var(--green-5);
+ --task-blocked: var(--red-5);
+ --task-wip: var(--yellow-5);
+ --task-todo: var(--gray-5);
+
+ --callout-info: var(--blue-5);
+ --callout-warn: var(--yellow-5);
+ --callout-error: var(--red-5);
+ --callout-note: var(--gray-5);
+
+ --session-bg: var(--surface-1);
+ --wikilink: var(--blue-4);
+ --redacted: var(--gray-8);
+
+}
+
+
+/* ══════════════════════════════════════════════════════════════════
+ LIGHT MODE — override semantic aliases only
+ ══════════════════════════════════════════════════════════════════ */
+
+@media (prefers-color-scheme: light) {
+ :root {
+ color-scheme: light;
+
+ --surface: var(--gray-0); /* 99% lightness */
+ --surface-1: var(--gray-1); /* 95% */
+ --surface-2: var(--gray-2); /* 88% */
+ --surface-card: var(--gray-0);
+ --surface-hover: var(--gray-1);
+
+ --text: var(--gray-14); /* 18% — dark but not pure black */
+ --text-2: var(--gray-11); /* 37% */
+ --text-3: var(--gray-8); /* 53% */
+ --text-dim: var(--gray-6); /* 63% */
+
+ --accent: var(--green-8);
+ --accent-hover: var(--green-9);
+ --on-accent: var(--gray-0);
+ --accent-focus: color-mix(in oklch, var(--green-8) 35%, transparent);
+ --accent-subtle: color-mix(in oklch, var(--green-8) 10%, transparent);
+
+ --border: var(--gray-3); /* 80% — visible on near-white */
+ --border-subtle: var(--gray-2); /* 88% — very subtle */
+
+ --link: var(--blue-8); /* #1971c2 */
+ --link-hover: var(--blue-7); /* #1c7ed6 */
+ --link-underline: color-mix(in oklch, var(--blue-8) 40%, transparent);
+ --link-hover-underline: color-mix(in oklch, var(--blue-8) 55%, transparent);
+ --link-focus: color-mix(in oklch, var(--blue-8) 35%, transparent);
+
+ --h1-color: var(--gray-15);
+ --h2-color: var(--gray-14);
+ --h3-color: var(--gray-13);
+ --h4-color: var(--gray-12);
+ --h5-color: var(--gray-11);
+ --h6-color: var(--gray-10);
+
+ --mark-bg: color-mix(in oklch, var(--yellow-6) 15%, var(--surface));
+ --mark-color: var(--gray-15);
+ --selection: color-mix(in oklch, var(--blue-8) 20%, transparent);
+
+ --code-color: var(--text-3);
+ --table-stripe: color-mix(in oklch, var(--gray-8) 4%, transparent);
+
+ --input-bg: var(--gray-0);
+ --input-border: var(--gray-4);
+ --input-active-bg: var(--gray-0);
+ --input-selected: var(--gray-2);
+
+ --track-bg: var(--gray-3);
+ --modal-overlay: color-mix(in oklch, var(--gray-2) 75%, transparent);
+
+ --error: oklch(50% 0.17 20);
+ --error-active: oklch(44% 0.18 20);
+
+ --session-bg: var(--surface-1);
+ }
+}
+
+
+/* ══════════════════════════════════════════════════════════════════
+ RESPONSIVE FONT SCALING
+ Subtle upscaling at large viewports — all rem values follow.
+ ══════════════════════════════════════════════════════════════════ */
+
+@media (--lg-n-above) { html { font-size: 103%; } }
+@media (--xl-n-above) { html { font-size: 106%; } }
+@media (--xxl-n-above) { html { font-size: 109%; } }
diff --git a/assets/css/layers/02-semantic.css b/assets/css/layers/02-semantic.css
new file mode 100644
index 0000000..3f569f8
--- /dev/null
+++ b/assets/css/layers/02-semantic.css
@@ -0,0 +1,956 @@
+/**
+ * 02-semantic.css
+ * Semantic HTML element styles
+ * Part of: Agentic Semantic Web
+ *
+ * Ported from: Pico CSS v2.1.1
+ * License: MIT
+ *
+ * This layer handles typography and semantic HTML elements.
+ * Classes are NOT supported—use semantic tags only.
+ */
+
+/* ── Typography: Headings ──────────────────────────────────────────── */
+
+h1,
+h2,
+h3,
+h4,
+h5,
+h6 {
+ margin-top: 0;
+ margin-bottom: var(--type-space);
+ line-height: var(--leading-tight);
+ font-family: var(--font-heading);
+ text-wrap: balance;
+}
+
+h1 {
+ font-size: var(--h1-size);
+ color: var(--h1-color);
+ font-weight: var(--h1-weight);
+}
+
+h2 {
+ font-size: var(--h2-size);
+ color: var(--h2-color);
+ font-weight: var(--h2-weight);
+}
+
+h3 {
+ font-size: var(--h3-size);
+ color: var(--h3-color);
+ font-weight: var(--h3-weight);
+}
+
+h4 {
+ font-size: var(--h4-size);
+ color: var(--h4-color);
+ font-weight: var(--h4-weight);
+}
+
+h5 {
+ font-size: var(--h5-size);
+ color: var(--h5-color);
+ font-weight: var(--h5-weight);
+ text-transform: uppercase;
+ letter-spacing: 0.05em;
+}
+
+h6 {
+ font-size: var(--h6-size);
+ color: var(--h6-color);
+ font-weight: var(--h6-weight);
+ text-transform: uppercase;
+ letter-spacing: 0.06em;
+}
+
+/* Add spacing before headings that follow content elements */
+:where(article, address, blockquote, dl, figure, form, ol, p, pre, table, ul) ~ :is(h1, h2, h3, h4, h5, h6) {
+ margin-top: var(--type-space-top);
+}
+
+/* ── Typography: UI elements — structural, navigational, informational ── */
+/* These override the prose body font with the humanist sans UI stack. */
+
+nav,
+header,
+footer,
+label,
+th,
+caption,
+small,
+figcaption,
+button,
+input,
+select,
+textarea,
+hgroup > p,
+hgroup > small {
+ font-family: var(--font-ui);
+}
+
+/* ── Nav layout ─────────────────────────────────────────────────────── */
+/* Ported from Pico CSS, translated to ASW tokens. */
+
+nav {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ overflow: visible;
+}
+
+nav ul {
+ display: flex;
+ align-items: center;
+ flex-wrap: wrap;
+ gap: 0;
+ padding: 0;
+ margin: 0;
+ list-style: none;
+}
+
+nav li {
+ display: inline-block;
+ margin: 0;
+ padding: var(--space-2) var(--space-3);
+}
+
+nav li a {
+ display: inline-block;
+ text-decoration: none;
+ color: var(--text);
+ padding: var(--space-2) var(--space-3);
+ margin: calc(var(--space-2) * -1) calc(var(--space-3) * -1);
+ border-radius: var(--radius-sm);
+}
+
+nav li a:hover {
+ color: var(--accent);
+ background: var(--surface-hover);
+}
+
+nav li strong,
+nav li b {
+ color: var(--text);
+}
+
+@media (--md-n-below) {
+ nav { flex-wrap: wrap; gap: var(--space-2); }
+ nav ul { flex-wrap: wrap; gap: var(--space-1); }
+}
+
+/* ── Typography: Paragraphs ────────────────────────────────────────── */
+
+p {
+ margin-top: 0;
+ margin-bottom: var(--type-space);
+ color: var(--text);
+ font-style: normal;
+ font-weight: var(--font-weight-4);
+}
+
+/* ── Typography: Lists ─────────────────────────────────────────────── */
+
+address,
+dl,
+ol,
+ul {
+ margin-top: 0;
+ margin-bottom: var(--type-space);
+ color: var(--text);
+ font-style: normal;
+ font-weight: var(--font-weight-4);
+}
+
+:where(ol, ul) li {
+ margin-bottom: calc(var(--type-space) * 0.25);
+}
+
+/* Nested lists: reduce spacing */
+:where(dl, ol, ul) :where(dl, ol, ul) {
+ margin: 0;
+ margin-top: calc(var(--type-space) * 0.25);
+}
+
+ul li {
+ list-style: square;
+}
+
+/* ── Typography: Blockquote ────────────────────────────────────────── */
+
+blockquote {
+ display: block;
+ margin: var(--type-space) 0;
+ padding: var(--space-4);
+ border-right: none;
+ border-left: 0.25rem solid var(--border);
+ border-inline-start: 0.25rem solid var(--border);
+ border-inline-end: none;
+}
+
+blockquote footer {
+ margin-top: calc(var(--type-space) * 0.5);
+ color: var(--text-3);
+}
+
+/* ── Typography: Horizontal Rule ───────────────────────────────────── */
+
+hr {
+ height: 0;
+ margin: var(--type-space) 0;
+ border: 0;
+ border-top: 1px solid var(--border);
+ color: inherit;
+}
+
+/* ── Typography: Inline Elements ───────────────────────────────────── */
+
+b,
+strong {
+ font-weight: bolder;
+}
+
+mark {
+ padding: 0.125rem 0.25rem;
+ background-color: var(--mark-bg);
+ color: var(--mark-color);
+ vertical-align: baseline;
+}
+
+ins {
+ color: var(--text-2);
+ text-decoration: none;
+}
+
+del {
+ color: var(--accent-red);
+}
+
+abbr[title] {
+ border-bottom: var(--border-size-1) dotted;
+ text-decoration: none;
+ cursor: help;
+}
+
+sub,
+sup {
+ position: relative;
+ font-size: 0.75em;
+ line-height: 0;
+ vertical-align: baseline;
+}
+
+sub {
+ bottom: -0.25em;
+}
+
+sup {
+ top: -0.5em;
+}
+
+small {
+ font-size: 0.875em;
+}
+
+/* ── Links ─────────────────────────────────────────────────────────── */
+
+:where(a:not([role=button])),
+[role=link] {
+
+
+
+ outline: none;
+ background-color: transparent;
+ color: var(--link);
+ text-decoration: underline;
+ text-decoration-color: var(--link-underline);
+ text-underline-offset: 0.125em;
+ transition: background-color var(--ease),
+ color var(--ease),
+ text-decoration var(--ease),
+ box-shadow var(--ease);
+}
+
+:where(a:not([role=button])):is(:hover, :active, :focus),
+[role=link]:is(:hover, :active, :focus) {
+ color: var(--link-hover);
+ text-decoration-color: var(--link-hover-underline);
+}
+
+:where(a:not([role=button])):focus-visible,
+[role=link]:focus-visible {
+ box-shadow: 0 0 0 var(--outline-width) var(--link-focus);
+}
+
+/* ── Text Selection ────────────────────────────────────────────────── */
+
+::selection {
+ background-color: var(--selection);
+}
+
+/* ── Tables ────────────────────────────────────────────────────────── */
+
+:where(table) {
+ width: 100%;
+ margin-top: 0;
+ margin-bottom: var(--type-space);
+ border-collapse: collapse;
+ border-spacing: 0;
+ text-indent: 0;
+ color: var(--text);
+ font-style: normal;
+ font-weight: var(--font-weight-4);
+}
+
+th,
+td {
+ padding: calc(var(--space-4) / 2) var(--space-4);
+ border-bottom: var(--border-width) solid var(--border);
+ background-color: transparent;
+ color: var(--text);
+ font-weight: var(--font-weight-4);
+ text-align: left;
+}
+
+thead th,
+thead td {
+ font-weight: 600;
+ border-bottom-width: var(--border-size-2);
+}
+
+tfoot th,
+tfoot td {
+ border-top: var(--border-width) solid var(--border);
+ border-bottom: 0;
+}
+
+/* Striped tables (class-based but useful) */
+table.striped tbody tr:nth-child(odd) th,
+table.striped tbody tr:nth-child(odd) td {
+ background-color: var(--table-stripe);
+}
+
+/* ── Code & Preformatted Text ──────────────────────────────────────── */
+
+pre,
+code,
+kbd,
+samp {
+ font-size: 0.875em;
+ font-family: var(--font-mono);
+ border-radius: var(--radius-md);
+ background: var(--surface-1);
+ color: var(--code-color);
+ font-weight: var(--font-weight-4);
+ line-height: initial;
+}
+
+/* Inline code elements */
+code,
+kbd,
+samp {
+ display: inline-block;
+ padding: 0.375rem;
+}
+
+/* Code blocks */
+pre {
+ display: block;
+ margin-top: 0;
+ margin-bottom: var(--space-4);
+ padding: var(--space-4);
+ overflow-x: auto;
+ -ms-overflow-style: scrollbar;
+}
+
+pre > code,
+pre > samp {
+ display: block;
+ padding: 0;
+ background: none;
+ font-size: inherit;
+ font-family: inherit;
+ line-height: var(--leading);
+}
+
+/* Keyboard input */
+kbd {
+ background-color: var(--kbd-bg);
+ color: var(--kbd-color);
+ vertical-align: baseline;
+}
+
+/* ── Prism.js Syntax Highlighting Theme ────────────────────────────── *
+ *
+ * These rules style Prism.js token classes using ASW tokens.
+ * agentic.css provides the theme; each page loads Prism via:
+ *
+ *
+ *
+ *
+ *
+ * The CDN theme's colors are overridden here. ASW tokens handle dark/light.
+ * ─────────────────────────────────────────────────────────────────── */
+
+/* Reset Prism default background — pre already styled by ASW */
+code[class*="language-"],
+pre[class*="language-"] {
+ color: var(--code-color);
+ background: none;
+ text-shadow: none;
+}
+
+pre[class*="language-"] {
+ background: var(--surface-1);
+}
+
+/* Token colors — dark (default) */
+.token.comment,
+.token.prolog,
+.token.doctype,
+.token.cdata {
+ color: var(--gray-6); /* muted: ~55% lightness */
+ font-style: italic;
+}
+
+.token.punctuation {
+ color: var(--text-3); /* slightly muted */
+}
+
+.token.tag,
+.token.deleted {
+ color: var(--red-4); /* HTML tags, deleted code */
+}
+
+.token.attr-name,
+.token.namespace {
+ color: var(--yellow-4); /* attribute names */
+}
+
+.token.string,
+.token.attr-value,
+.token.char,
+.token.inserted {
+ color: var(--green-4); /* strings, values */
+}
+
+.token.number,
+.token.boolean,
+.token.constant,
+.token.symbol {
+ color: var(--orange-4); /* literals */
+}
+
+.token.selector,
+.token.builtin {
+ color: var(--teal-4); /* CSS selectors, builtins */
+}
+
+.token.keyword,
+.token.atrule {
+ color: var(--blue-4); /* keywords, @rules */
+}
+
+.token.function,
+.token.class-name {
+ color: var(--cyan-4); /* function/class names */
+}
+
+.token.property {
+ color: var(--blue-5); /* object properties */
+}
+
+.token.operator,
+.token.entity,
+.token.url {
+ color: var(--text-2); /* operators */
+}
+
+.token.regex {
+ color: var(--orange-5); /* regex literals */
+}
+
+.token.important,
+.token.variable {
+ color: var(--yellow-5); /* !important, variables */
+ font-weight: var(--font-weight-5);
+}
+
+.token.bold { font-weight: var(--font-weight-7); }
+.token.italic { font-style: italic; }
+
+/* Light mode overrides */
+@media (prefers-color-scheme: light) {
+ .token.comment,
+ .token.prolog,
+ .token.doctype,
+ .token.cdata { color: var(--gray-6); }
+
+ .token.punctuation { color: var(--gray-8); }
+
+ .token.tag,
+ .token.deleted { color: var(--red-8); }
+
+ .token.attr-name,
+ .token.namespace { color: var(--yellow-9); }
+
+ .token.string,
+ .token.attr-value,
+ .token.char,
+ .token.inserted { color: var(--green-8); }
+
+ .token.number,
+ .token.boolean,
+ .token.constant,
+ .token.symbol { color: var(--orange-8); }
+
+ .token.selector,
+ .token.builtin { color: var(--teal-8); }
+
+ .token.keyword,
+ .token.atrule { color: var(--blue-8); }
+
+ .token.function,
+ .token.class-name { color: var(--cyan-9); }
+
+ .token.property { color: var(--blue-9); }
+
+ .token.operator,
+ .token.entity,
+ .token.url { color: var(--gray-8); }
+
+ .token.regex { color: var(--orange-7); }
+
+ .token.important,
+ .token.variable { color: var(--yellow-9); }
+}
+
+/* ── Details / Summary ─────────────────────────────────────────────── */
+
+details {
+ display: block;
+ margin-bottom: var(--space-4);
+}
+
+details summary {
+ line-height: 1rem;
+ list-style-type: none;
+ cursor: pointer;
+ transition: color var(--ease);
+ color: var(--accent);
+}
+
+/* Hide browser default marker */
+details summary::-webkit-details-marker {
+ display: none;
+}
+
+details summary::marker {
+ display: none;
+}
+
+details summary::-moz-list-bullet {
+ list-style-type: none;
+}
+
+/* CSS-drawn chevron using Unicode character ▸ (U+25B8) */
+details summary::after {
+ content: "▸";
+ display: inline-block;
+ width: 1rem;
+ height: 1rem;
+ margin-inline-start: calc(var(--space-4, 1rem) * 0.5);
+ float: right;
+ font-size: var(--text-sm);
+ line-height: 1rem;
+ text-align: center;
+ color: var(--text-3);
+ transform: rotate(90deg); /* Point down when closed */
+ transition: transform var(--ease);
+}
+
+details summary:focus {
+ outline: none;
+}
+
+details summary:focus-visible {
+ outline: var(--outline-width) solid var(--accent-focus);
+ outline-offset: calc(var(--space-4, 1rem) * 0.5);
+ color: var(--accordion-active);
+}
+
+/* Open state */
+details[open] > summary {
+ margin-bottom: var(--space-4);
+ color: var(--text-3);
+}
+
+details[open] > summary::after {
+ transform: rotate(180deg); /* Point down when open */
+}
+
+/* ── Dialog / Modal ────────────────────────────────────────────────── */
+
+dialog {
+ display: flex;
+ z-index: 999;
+ position: fixed;
+ top: 0;
+ right: 0;
+ bottom: 0;
+ left: 0;
+ align-items: center;
+ justify-content: center;
+ width: inherit;
+ min-width: 100%;
+ height: inherit;
+ min-height: 100%;
+ padding: 0;
+ border: 0;
+ backdrop-filter: var(--modal-backdrop);
+ background-color: var(--modal-overlay);
+ color: var(--text);
+}
+
+dialog > article {
+ width: 100%;
+ max-height: calc(100vh - var(--space-4) * 2);
+ margin: var(--space-4);
+ overflow: auto;
+}
+
+/* Responsive max-widths for modal content */
+@media (--sm-n-above) {
+ dialog > article {
+ max-width: var(--width-sm);
+ }
+}
+
+@media (--md-n-above) {
+ dialog > article {
+ max-width: var(--width-md);
+ }
+}
+
+/* Modal header */
+dialog > article > header > * {
+ margin-bottom: 0;
+}
+
+dialog > article > header .close,
+dialog > article > header :is(a, button)[rel=prev] {
+ margin: 0;
+ margin-left: var(--space-4);
+ padding: 0;
+ float: right;
+}
+
+/* Modal footer */
+dialog > article > footer {
+ text-align: right;
+}
+
+dialog > article > footer button,
+dialog > article > footer [role=button] {
+ margin-bottom: 0;
+}
+
+dialog > article > footer button:not(:first-of-type),
+dialog > article > footer [role=button]:not(:first-of-type) {
+ margin-left: calc(var(--space-4) * 0.5);
+}
+
+/* Close button: Unicode ✕ (U+2715) instead of SVG */
+dialog > article .close,
+dialog > article :is(a, button)[rel=prev] {
+ display: block;
+ width: 1.5rem;
+ height: 1.5rem;
+ margin-top: calc(var(--space-4) * -0.5);
+ margin-bottom: var(--space-4);
+ margin-left: auto;
+ border: none;
+ background-color: transparent;
+ color: var(--text-3);
+ font-size: 1.5rem;
+ line-height: 1;
+ text-align: center;
+ opacity: 0.5;
+ transition: opacity var(--ease);
+ cursor: pointer;
+}
+
+dialog > article .close::before,
+dialog > article :is(a, button)[rel=prev]::before {
+ content: "✕"; /* Unicode heavy multiplication X */
+}
+
+dialog > article .close:is([aria-current]:not([aria-current=false]), :hover, :active, :focus),
+dialog > article :is(a, button)[rel=prev]:is([aria-current]:not([aria-current=false]), :hover, :active, :focus) {
+ opacity: 1;
+}
+
+/* Hidden state */
+dialog:not([open]),
+dialog[open=false] {
+ display: none;
+}
+
+/* Body scroll lock when modal is open */
+.modal-is-open {
+ padding-right: var(--scrollbar-width, 0px);
+ overflow: hidden;
+ pointer-events: none;
+ touch-action: none;
+}
+
+.modal-is-open dialog {
+ pointer-events: auto;
+ touch-action: auto;
+}
+
+/* Animations (only if motion is not reduced) */
+@media (prefers-reduced-motion: no-preference) {
+ :where(.modal-is-opening, .modal-is-closing) dialog,
+ :where(.modal-is-opening, .modal-is-closing) dialog > article {
+ animation-duration: var(--duration-moderate-1);
+ animation-timing-function: ease-in-out;
+ animation-fill-mode: both;
+ }
+
+ :where(.modal-is-opening, .modal-is-closing) dialog {
+ animation-duration: var(--duration-gentle-2);
+ animation-name: modal-overlay;
+ }
+
+ :where(.modal-is-opening, .modal-is-closing) dialog > article {
+ animation-delay: var(--duration-moderate-1);
+ animation-name: modal;
+ }
+
+ .modal-is-closing dialog,
+ .modal-is-closing dialog > article {
+ animation-delay: 0s;
+ animation-direction: reverse;
+ }
+
+ @keyframes modal-overlay {
+ from {
+ backdrop-filter: none;
+ background-color: transparent;
+ }
+ }
+
+ @keyframes modal {
+ from {
+ transform: translateY(-100%);
+ opacity: 0;
+ }
+ }
+}
+
+/* Respect reduced motion: instant show/hide */
+@media (prefers-reduced-motion: reduce) {
+ dialog,
+ dialog > article {
+ animation: none !important;
+ transition: none !important;
+ }
+}
+
+/* ── Figure & Figcaption ───────────────────────────────────────────── */
+
+figure {
+ display: block;
+ margin: 0;
+ margin-bottom: var(--space-4);
+ padding: 0;
+}
+
+figure figcaption {
+ padding: calc(var(--space-4) * 0.5) 0;
+ color: var(--text-3);
+ font-size: var(--text-sm);
+}
+
+/* ── Progress ──────────────────────────────────────────────────────── */
+
+progress {
+ -webkit-appearance: none;
+ -moz-appearance: none;
+ appearance: none;
+ display: inline-block;
+ vertical-align: baseline;
+ width: 100%;
+ height: 0.5rem;
+ margin-bottom: calc(var(--space-4) * 0.5);
+ overflow: hidden;
+ border: 0;
+ border-radius: var(--radius-md);
+ background-color: var(--track-bg);
+ color: var(--accent);
+}
+
+progress::-webkit-progress-bar {
+ border-radius: var(--radius-md);
+ background: none;
+}
+
+progress[value]::-webkit-progress-value {
+ background-color: var(--accent);
+ transition: inline-size var(--ease);
+}
+
+progress::-moz-progress-bar {
+ background-color: var(--accent);
+}
+
+/* Indeterminate progress (animated) - respect motion preferences */
+@media (prefers-reduced-motion: no-preference) {
+ progress:indeterminate {
+ background: var(--track-bg)
+ linear-gradient(to right,
+ var(--accent) 30%,
+ var(--track-bg) 30%)
+ top left / 150% 150% no-repeat;
+ animation: progress-indeterminate calc(var(--duration-gentle-2) * 2) linear infinite;
+ }
+
+ progress:indeterminate[value]::-webkit-progress-value {
+ background-color: transparent;
+ }
+
+ @keyframes progress-indeterminate {
+ 0% {
+ background-position: 200% 0;
+ }
+ 100% {
+ background-position: -200% 0;
+ }
+ }
+}
+
+@media (prefers-reduced-motion: reduce) {
+ progress:indeterminate {
+ background: var(--track-bg);
+ }
+}
+
+/* ── Meter ─────────────────────────────────────────────────────────── */
+
+meter {
+ -webkit-appearance: none;
+ -moz-appearance: none;
+ appearance: none;
+ display: inline-block;
+ vertical-align: baseline;
+ width: 100%;
+ height: 0.5rem;
+ margin-bottom: calc(var(--space-4) * 0.5);
+ overflow: hidden;
+ border: 0;
+ border-radius: var(--radius-md);
+ background-color: var(--track-bg);
+ accent-color: var(--accent); /* Modern CSS: browser renders with our accent */
+}
+
+/* Webkit meter styling */
+meter::-webkit-meter-bar {
+ border-radius: var(--radius-md);
+ background-color: var(--track-bg);
+}
+
+meter::-webkit-meter-optimum-value {
+ background-color: var(--accent);
+}
+
+meter::-webkit-meter-suboptimum-value {
+ background-color: var(--accent-blue);
+}
+
+meter::-webkit-meter-even-less-good-value {
+ background-color: var(--accent-red); /* Red-ish for bad values */
+}
+
+/* Firefox meter styling */
+meter::-moz-meter-bar {
+ border-radius: var(--radius-md);
+ background-color: var(--accent);
+}
+
+meter:-moz-meter-optimum::-moz-meter-bar {
+ background-color: var(--accent);
+}
+
+meter:-moz-meter-sub-optimum::-moz-meter-bar {
+ background-color: var(--accent-blue);
+}
+
+meter:-moz-meter-sub-sub-optimum::-moz-meter-bar {
+ background-color: var(--accent-red);
+}
+
+/* ── Content Container ─────────────────────────────────────────────── */
+/* body > nav, body > main, and body > footer share container alignment so agents
+ can write