From 880a17f33a0d2ca32cecc67b8cb22b30c54dbaff Mon Sep 17 00:00:00 2001 From: Vigilio Desto Date: Fri, 10 Apr 2026 17:23:51 +0200 Subject: [PATCH] Add dorveille article and full Hugo site scaffold MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - content/dorveille.md: 'On the Craft of Invisible Systems' - assets/css/: ASW layer system (00-reset through 09-landing + Open Props) - layouts/: baseof, single, list, index — semantic HTML, no classes - hugo.toml: baseURL asw.trentuna.com, PostCSS + minify pipeline - package.json: postcss-import, postcss-custom-media, cssnano - .gitignore: excludes public/, node_modules, build artifacts Site builds to public/ via hugo --minify. nginx serves public/ statically. --- .gitignore | 5 + archetypes/default.md | 5 + assets/css/asw.css | 25 + assets/css/layers/00-reset.css | 58 + assets/css/layers/01-tokens.css | 343 +++++ assets/css/layers/02-semantic.css | 956 +++++++++++++ assets/css/layers/03-components.css | 955 +++++++++++++ assets/css/layers/04-data-attrs.css | 681 ++++++++++ assets/css/layers/05-utilities.css | 274 ++++ assets/css/layers/06-charts.css | 761 +++++++++++ assets/css/layers/07-chroma.css | 138 ++ assets/css/layers/08-layout.css | 578 ++++++++ assets/css/layers/08a-paper.css | 84 ++ assets/css/layers/09-landing.css | 160 +++ content/dorveille.md | 89 ++ hugo.toml | 9 + hugo_stats.json | 68 + layouts/_default/baseof.html | 14 + layouts/_default/list.html | 38 + layouts/_default/single.html | 70 + layouts/index.html | 42 + package-lock.json | 1941 +++++++++++++++++++++++++++ package.json | 14 + postcss.config.js | 7 + 24 files changed, 7315 insertions(+) create mode 100644 .gitignore create mode 100644 archetypes/default.md create mode 100644 assets/css/asw.css create mode 100644 assets/css/layers/00-reset.css create mode 100644 assets/css/layers/01-tokens.css create mode 100644 assets/css/layers/02-semantic.css create mode 100644 assets/css/layers/03-components.css create mode 100644 assets/css/layers/04-data-attrs.css create mode 100644 assets/css/layers/05-utilities.css create mode 100644 assets/css/layers/06-charts.css create mode 100644 assets/css/layers/07-chroma.css create mode 100644 assets/css/layers/08-layout.css create mode 100644 assets/css/layers/08a-paper.css create mode 100644 assets/css/layers/09-landing.css create mode 100644 content/dorveille.md create mode 100644 hugo.toml create mode 100644 hugo_stats.json create mode 100644 layouts/_default/baseof.html create mode 100644 layouts/_default/list.html create mode 100644 layouts/_default/single.html create mode 100644 layouts/index.html create mode 100644 package-lock.json create mode 100644 package.json create mode 100644 postcss.config.js 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