Add dorveille article and full Hugo site scaffold

- 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.
This commit is contained in:
Vigilio Desto 2026-04-10 17:23:51 +02:00
parent a899f13ae6
commit 880a17f33a
Signed by: vigilio
GPG key ID: 159D6AD58C8E55E9
24 changed files with 7315 additions and 0 deletions

25
assets/css/asw.css Normal file
View file

@ -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";

View file

@ -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;
}

View file

@ -0,0 +1,343 @@
/**
* 01-tokens.css
* ASW semantic layer builds on Open Props
*
* Open Props (imported below) provides the base scales:
* --gray-015, --green-012, --blue-012, --red-012, --yellow-012
* --size-115, --font-size-08, --font-weight-19
* --font-lineheight-05, --radius-16, --shadow-16
* --ease-15, --ease-spring-15, --ease-bounce-15
* --gradient-130, --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%; } }

View file

@ -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 supporteduse 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:
*
* <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/themes/prism.min.css">
* <script src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/components/prism-core.min.js"></script>
* <script src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/plugins/autoloader/prism-autoloader.min.js"></script>
*
* 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 <body><nav><main><footer> and get consistent widths.
Scoped to body > nav/main/footer to avoid affecting nested elements
(breadcrumbs, pagination, mains inside grid layouts). */
body > nav,
body > main,
body > footer {
width: 100%;
margin-right: auto;
margin-left: auto;
padding-right: var(--space-4);
padding-left: var(--space-4);
}
/* Default: constrained container (replaces .container class) */
@media (--sm-n-above) {
body > nav,
body > main:not([data-layout="fluid"]),
body > footer {
max-width: var(--width-sm);
padding-right: 0;
padding-left: 0;
}
}
@media (--md-n-above) {
body > nav,
body > main:not([data-layout="fluid"]),
body > footer {
max-width: var(--width-md);
}
}
@media (--lg-n-above) {
body > nav,
body > main:not([data-layout="fluid"]),
body > footer {
max-width: var(--width-lg);
}
}
@media (--xl-n-above) {
body > nav,
body > main:not([data-layout="fluid"]),
body > footer {
max-width: var(--width-xl);
}
}
@media (--xxl-n-above) {
body > nav,
body > main:not([data-layout="fluid"]),
body > footer {
max-width: var(--width-2xl);
}
}
/* Full-width opt-out */
body > main[data-layout="fluid"] {
max-width: none;
}

View file

@ -0,0 +1,955 @@
/**
* 03-components.css
* UI component patterns (buttons, forms, nav, dialog, details)
* Part of: Agentic Semantic Web
*
* Ported from: Pico CSS v2.1.1
* License: MIT
*
* Modernizations:
* - Uses `accent-color` for checkbox/radio (simpler than background-image)
* - Drops class-based button variants (.secondary, .contrast, .outline)
*/
/* ── Buttons ───────────────────────────────────────────────────────────*/
button {
margin: 0;
overflow: visible;
font-family: inherit;
text-transform: none;
}
button,
[type=submit],
[type=reset],
[type=button],
[role=button] {
display: inline-block;
padding: var(--input-py) var(--input-px);
border: var(--border-width) solid var(--border);
border-radius: var(--radius-md);
outline: none;
background-color: var(--surface);
color: var(--text);
font-weight: var(--font-weight-4);
font-size: var(--text-base);
line-height: var(--leading);
text-align: center;
text-decoration: none;
cursor: pointer;
user-select: none;
transition: background-color var(--ease),
border-color var(--ease),
color var(--ease);
}
button:is(:hover, :active, :focus-visible),
[type=submit]:is(:hover, :active, :focus-visible),
[type=reset]:is(:hover, :active, :focus-visible),
[type=button]:is(:hover, :active, :focus-visible),
[role=button]:is(:hover, :active, :focus-visible) {
background-color: var(--surface-hover);
border-color: var(--border);
color: var(--text);
}
button:focus-visible,
[type=submit]:focus-visible,
[type=reset]:focus-visible,
[type=button]:focus-visible,
[role=button]:focus-visible {
box-shadow: 0 0 0 var(--outline-width) var(--accent-focus);
}
button[disabled],
[type=submit][disabled],
[type=reset][disabled],
[type=button][disabled],
[role=button][disabled] {
opacity: 0.5;
pointer-events: none;
}
/* ── Form Elements ─────────────────────────────────────────────────────*/
input,
optgroup,
select,
textarea {
margin: 0;
font-size: var(--text-base);
line-height: var(--leading);
font-family: inherit;
letter-spacing: inherit;
}
fieldset {
width: 100%;
margin: 0;
margin-bottom: var(--space-4);
padding: 0;
border: 0;
}
fieldset legend,
label {
display: block;
margin-bottom: calc(var(--space-4) * 0.375);
color: var(--text);
font-weight: var(--font-weight-4);
}
input:not([type=checkbox], [type=radio], [type=range], [type=file]),
select,
textarea {
width: 100%;
padding: var(--input-py) var(--input-px);
border: var(--border-width) solid var(--input-border);
border-radius: var(--radius-md);
outline: none;
background-color: var(--input-bg);
color: var(--text);
font-weight: var(--font-weight-4);
transition: background-color var(--ease),
border-color var(--ease),
color var(--ease);
}
input:not([type=checkbox], [type=radio], [type=range], [type=file], [readonly]):is(:active, :focus-visible),
select:not([readonly]):is(:active, :focus-visible),
textarea:not([readonly]):is(:active, :focus-visible) {
border-color: var(--accent);
background-color: var(--input-active-bg);
}
input:not([type=checkbox], [type=radio], [type=range], [type=file], [readonly]):focus-visible,
select:not([readonly]):focus-visible,
textarea:not([readonly]):focus-visible {
box-shadow: 0 0 0 var(--outline-width) var(--accent);
}
input:not([type=checkbox], [type=radio], [type=range], [type=file])[disabled],
select[disabled],
textarea[disabled] {
opacity: var(--disabled-opacity);
pointer-events: none;
}
input::placeholder,
textarea::placeholder,
select:invalid {
color: var(--text-3);
opacity: 1;
}
input:not([type=checkbox], [type=radio]),
select,
textarea {
margin-bottom: var(--space-4);
}
/* ── Select Dropdown ───────────────────────────────────────────────────*/
select:not([multiple], [size]) {
padding-right: calc(var(--input-px) + 1.5rem);
background-image: var(--icon-chevron);
background-position: center right 0.75rem;
background-size: 1rem auto;
background-repeat: no-repeat;
}
select[multiple] option:checked {
background: var(--input-selected);
color: var(--text);
}
/* ── Textarea ──────────────────────────────────────────────────────────*/
textarea {
display: block;
resize: vertical;
}
/* ── Checkboxes & Radios (Modern CSS) ──────────────────────────────────*/
label:has([type=checkbox], [type=radio]) {
width: fit-content;
cursor: pointer;
}
[type=checkbox],
[type=radio] {
width: 1.25em;
height: 1.25em;
margin-top: -0.125em;
margin-right: 0.5em;
vertical-align: middle;
cursor: pointer;
/* Modern CSS: use browser's native styling with our accent color */
accent-color: var(--accent);
}
[type=checkbox] ~ label,
[type=radio] ~ label {
display: inline-block;
margin-bottom: 0;
cursor: pointer;
}
[type=checkbox] ~ label:not(:last-of-type),
[type=radio] ~ label:not(:last-of-type) {
margin-right: 1em;
}
/* ── Validation States ─────────────────────────────────────────────────*/
input[aria-invalid=false],
select[aria-invalid=false],
textarea[aria-invalid=false] {
border-color: var(--accent);
}
input[aria-invalid=false]:is(:active, :focus-visible),
select[aria-invalid=false]:is(:active, :focus-visible),
textarea[aria-invalid=false]:is(:active, :focus-visible) {
border-color: var(--accent-hover);
box-shadow: 0 0 0 var(--outline-width) var(--accent-focus) !important;
}
input[aria-invalid=true],
select[aria-invalid=true],
textarea[aria-invalid=true] {
border-color: var(--error);
}
input[aria-invalid=true]:is(:active, :focus-visible),
select[aria-invalid=true]:is(:active, :focus-visible),
textarea[aria-invalid=true]:is(:active, :focus-visible) {
border-color: var(--error-active);
box-shadow: 0 0 0 var(--outline-width) var(--error-focus) !important;
}
/* ── Helper Text ───────────────────────────────────────────────────────*/
:where(input, select, textarea, fieldset) + small {
display: block;
width: 100%;
margin-top: calc(var(--space-4) * -0.75);
margin-bottom: var(--space-4);
color: var(--text-3);
}
:where(input, select, textarea, fieldset)[aria-invalid=false] + small {
color: var(--accent);
}
:where(input, select, textarea, fieldset)[aria-invalid=true] + small {
color: var(--accent-red);
}
label > :where(input, select, textarea) {
margin-top: calc(var(--space-4) * 0.25);
}
/* ── Navigation ────────────────────────────────────────────────────────*/
/* Semantic nav: <nav><strong>Brand</strong><ul><li><a>...</a></li></ul></nav> */
body > nav {
display: flex;
justify-content: space-between;
align-items: center;
padding-top: 1.5rem;
padding-bottom: 1.5rem;
margin-bottom: 2rem;
border-bottom: 1px solid var(--border);
}
body > nav strong {
font-family: var(--font-mono);
font-weight: 700;
font-size: var(--text-base);
letter-spacing: -0.03em;
}
body > nav ul {
list-style: none;
display: flex;
gap: 0;
margin: 0;
padding: 0;
font-family: var(--font-mono);
font-size: var(--text-sm);
}
body > nav ul li {
list-style: none;
margin: 0;
padding: 0;
}
body > nav ul li + li::before {
content: "|";
color: var(--text-dim);
margin: 0 0.75rem;
}
body > nav a {
color: var(--text-2);
text-decoration: none;
transition: color var(--ease);
}
body > nav a:hover,
body > nav a[aria-current="page"] {
color: var(--text);
}
/* Medium screens: allow links to wrap */
@media (--nav-compact) {
body > nav ul {
flex-wrap: wrap;
gap: 0.25rem 0;
}
}
/* Small screens: stack brand above links */
@media (--md-n-below) {
body > nav {
flex-direction: column;
align-items: flex-start;
gap: 0.5rem;
}
body > nav ul:last-child {
flex-wrap: wrap;
}
body > nav ul:last-child li + li::before {
display: none;
}
}
/* ── Nav Dropdown ──────────────────────────────────────────────────────*/
/* <details> inside <nav> becomes a dropdown menu. No classes needed.
Usage: <nav><ul><li><details><summary>Menu</summary><ul><li>...</li></ul></details></li></ul></nav> */
body > nav li:has(details) {
display: flex;
align-items: center;
}
body > nav details {
position: relative;
margin: 0;
}
body > nav details summary {
color: var(--text-2);
font-family: var(--font-mono);
font-size: var(--text-sm);
list-style: none;
cursor: pointer;
transition: color var(--ease);
}
body > nav details summary:hover {
color: var(--text);
}
/* Override accordion chevron in nav context */
body > nav details summary::after {
content: "▾";
float: none;
margin-inline-start: 0.25rem;
transform: none;
font-size: var(--text-xs);
}
body > nav details[open] > summary::after {
content: "▴";
transform: none;
}
/* Dropdown panel */
body > nav details > ul,
body > nav details > div {
position: absolute;
top: calc(100% + 0.5rem);
left: 0;
min-width: var(--size-px-12);
padding: 0.5rem 0;
margin: 0;
background: var(--surface-1);
border: 1px solid var(--border);
border-radius: var(--radius-md);
box-shadow: var(--shadow-2);
z-index: 20;
list-style: none;
display: flex;
flex-direction: column;
}
body > nav details > ul li {
margin: 0;
padding: 0;
}
/* Remove pipe separator in dropdown items */
body > nav details > ul li + li::before {
display: none;
}
body > nav details > ul li a {
display: block;
padding: 0.35rem 1rem;
color: var(--text-2);
text-decoration: none;
font-family: var(--font-mono);
font-size: var(--text-sm);
transition: background-color var(--ease-fast), color var(--ease-fast);
}
body > nav details > ul li a:hover {
background: var(--border-subtle);
color: var(--text);
}
/* Close dropdown when clicking outside (CSS-only via :focus-within) */
nav details:not(:focus-within) > ul,
nav details:not(:focus-within) > div {
/* Allow browser default open/close behavior
no forced hiding. Agent can add JS for click-outside. */
}
/* Mobile: dropdown becomes full-width */
@media (--md-n-below) {
nav details > ul,
nav details > div {
position: static;
box-shadow: none;
border: none;
border-left: 2px solid var(--border);
margin-left: 0.5rem;
padding: 0.25rem 0 0.25rem 0.5rem;
background: transparent;
}
}
/* ── Articles & Cards ──────────────────────────────────────────────────*/
/* Semantic article: <article><header><h3>Title</h3></header>Content</article> */
/* Container query: layout adapts to article's own width, not viewport.
An article in a sidebar shrinks gracefully; at full width it expands. */
article {
container-type: inline-size;
container-name: article;
background: transparent;
border: 1px solid var(--border);
border-radius: var(--radius-md);
padding: 1rem 1.25rem;
margin: 0.75rem 0;
}
article > header {
margin: 0 0 0.5rem 0;
padding: 0 0 0.4rem 0;
border-bottom: 1px solid var(--border-subtle);
border-top: none;
border-radius: 0;
background-color: transparent;
}
article header h3 {
margin: 0;
padding: 0;
font-family: var(--font-mono);
font-size: var(--text-sm);
font-weight: 500;
text-transform: uppercase;
letter-spacing: 0.05em;
color: var(--text-3);
}
/* Narrow container: compact card (sidebar, grid cell) */
@container article (max-width: 300px) {
article > header {
border-bottom: none;
padding-bottom: 0;
margin-bottom: 0.25rem;
}
article header h3 {
font-size: var(--text-xs);
}
article > :is(p, dl, ul, ol) {
font-size: var(--text-sm);
}
}
/* Wide container: spacious layout */
@container article (min-width: 600px) {
article {
padding: 1.5rem 2rem;
}
article > header {
margin-bottom: 0.75rem;
padding-bottom: 0.5rem;
}
}
/* ── Definition Lists ──────────────────────────────────────────────────*/
/* Monospace data display for dt/dd pairs */
dt {
font-family: var(--font-mono);
font-size: var(--text-sm);
font-weight: 500;
color: var(--text-2);
margin-top: 0.75rem;
}
dd {
font-family: var(--font-mono);
font-size: var(--text-sm);
color: var(--text);
margin-left: 0;
margin-top: 0.15rem;
}
article dt:first-of-type {
margin-top: 0;
}
/* ── Sections ──────────────────────────────────────────────────────────*/
section + section {
padding-top: 1.5rem;
border-top: 1px solid var(--border-subtle);
}
hgroup p {
font-family: var(--font-mono);
font-size: var(--text-sm);
color: var(--text-3);
margin-top: 0.25rem;
}
/* Section intro: hgroup as centered subtitle block */
section > hgroup:first-child {
text-align: center;
margin-bottom: var(--space-6);
}
/* Card variant: navigation cards use UI font h3, not session-log monospace */
article[data-role="card"] header h3 {
font-family: var(--font-ui);
font-size: var(--h3-size);
font-weight: var(--h3-weight);
text-transform: none;
letter-spacing: normal;
color: var(--text);
}
/* ── Footer ────────────────────────────────────────────────────────────*/
body > footer,
footer:last-child {
margin-top: 3rem;
padding-top: 1.5rem;
padding-bottom: 2rem;
border-top: 1px solid var(--border);
font-family: var(--font-mono);
font-size: var(--text-xs);
color: var(--text-3);
}
/* ── Accordion / Disclosure ────────────────────────────────────────────*/
/* Standalone <details>/<summary> no JS needed.
Nav dropdown variant lives in the Nav Dropdown section above.
Usage:
<details>
<summary>Title</summary>
<p>Content</p>
</details>
Grouped variant:
<div data-role="accordion">
<details></details>
<details></details>
</div>
*/
details:not(nav details) {
border: var(--border-width) solid var(--border);
border-radius: var(--radius-md);
margin-bottom: var(--space-3);
background: var(--surface-1);
overflow: hidden;
}
details:not(nav details) > summary {
display: flex;
align-items: center;
justify-content: space-between;
padding: var(--space-3) var(--space-4);
font-family: var(--font-ui);
font-size: var(--text-base);
font-weight: var(--font-weight-5, 500);
color: var(--text);
cursor: pointer;
list-style: none;
user-select: none;
transition: background-color var(--ease), color var(--ease);
}
details:not(nav details) > summary::-webkit-details-marker {
display: none;
}
/* Chevron indicator */
details:not(nav details) > summary::after {
content: "▾";
font-size: var(--text-sm);
color: var(--text-3);
transition: transform var(--ease);
flex-shrink: 0;
margin-inline-start: var(--space-3);
}
details:not(nav details)[open] > summary::after {
transform: rotate(180deg);
}
details:not(nav details) > summary:hover {
background-color: var(--surface-hover);
color: var(--text);
}
details:not(nav details) > summary:focus-visible {
outline: var(--outline-width) solid var(--accent-focus);
outline-offset: -2px;
}
/* Body content */
details:not(nav details) > :not(summary) {
padding: var(--space-3) var(--space-4) var(--space-4);
border-top: var(--border-width) solid var(--border);
}
details:not(nav details) > :not(summary):last-child {
margin-bottom: 0;
}
/* Grouped accordion: flush borders between items */
[data-role="accordion"] > details:not(nav details) {
margin-bottom: 0;
border-radius: 0;
border-bottom-width: 0;
}
[data-role="accordion"] > details:not(nav details):first-child {
border-radius: var(--radius-md) var(--radius-md) 0 0;
}
[data-role="accordion"] > details:not(nav details):last-child {
border-radius: 0 0 var(--radius-md) var(--radius-md);
border-bottom-width: var(--border-width);
}
[data-role="accordion"] > details:not(nav details):only-child {
border-radius: var(--radius-md);
border-bottom-width: var(--border-width);
}
/* ── Dialog / Modal ────────────────────────────────────────────────────*/
/* Native <dialog> element. Works with dialog.showModal() / dialog.close().
Usage:
<dialog id="my-dialog">
<header><h2>Title</h2></header>
<p>Body content.</p>
<footer><button>Close</button></footer>
</dialog>
*/
dialog {
position: fixed;
inset: 0;
margin: auto;
padding: 0;
border: var(--border-width) solid var(--border);
border-radius: var(--radius-md);
background: var(--surface-1);
color: var(--text);
box-shadow: var(--shadow-4);
z-index: var(--layer-4);
max-width: min(90vw, 42rem);
max-height: min(90vh, 40rem);
overflow: auto;
scrollbar-width: thin;
scrollbar-color: var(--border) transparent;
}
dialog:not([open]) {
display: none;
}
/* Backdrop (modal mode only — showModal()) */
dialog::backdrop {
background: color-mix(in oklch, var(--gray-15) 70%, transparent);
backdrop-filter: blur(4px);
-webkit-backdrop-filter: blur(4px);
}
/* Internal layout */
dialog > header {
padding: var(--space-4) var(--space-5);
border-bottom: var(--border-width) solid var(--border);
background: transparent;
border-top: none;
border-radius: 0;
}
dialog > header h1,
dialog > header h2,
dialog > header h3 {
margin: 0;
font-size: var(--text-2xl);
color: var(--text);
}
dialog > :not(header):not(footer) {
padding: var(--space-5);
}
dialog > footer {
padding: var(--space-3) var(--space-5);
border-top: var(--border-width) solid var(--border);
display: flex;
justify-content: flex-end;
gap: var(--space-3);
background: var(--surface);
border-radius: 0 0 var(--radius-md) var(--radius-md);
}
/*
Breadcrumb <nav data-role="breadcrumb" aria-label="breadcrumb">
Usage:
<nav data-role="breadcrumb" aria-label="breadcrumb">
<ol>
<li><a href="/">Home</a></li>
<li><a href="/docs/">Docs</a></li>
<li aria-current="page">Token System</li>
</ol>
</nav>
*/
[data-role="breadcrumb"] {
font-family: var(--font-ui);
font-size: var(--text-sm);
}
[data-role="breadcrumb"] ol {
display: flex;
flex-wrap: wrap;
align-items: center;
list-style: none;
margin: 0;
padding: 0;
gap: 0;
}
[data-role="breadcrumb"] li {
display: flex;
align-items: center;
margin: 0;
padding: 0;
}
/* Separator: slash before every item after the first */
[data-role="breadcrumb"] li + li::before {
content: "/";
color: var(--text-3);
padding-inline: var(--space-2);
user-select: none;
font-weight: var(--font-weight-4);
}
[data-role="breadcrumb"] a {
color: var(--text-2);
text-decoration: none;
transition: color var(--ease);
}
[data-role="breadcrumb"] a:hover {
color: var(--accent);
}
/* Current page: plain text, full colour, no link underline */
[data-role="breadcrumb"] [aria-current="page"] {
color: var(--text);
font-weight: var(--font-weight-5);
}
/*
Steps <ol data-role="steps"> with data-status on each <li>
Usage:
<ol data-role="steps">
<li data-status="complete"><span>Plan</span></li>
<li data-status="active"><span>Build</span></li>
<li data-status="pending"><span>Deploy</span></li>
</ol>
data-status values: complete / active / pending
*/
[data-role="steps"] {
display: flex;
flex-wrap: wrap;
align-items: flex-start;
list-style: none;
margin: var(--space-5) 0;
padding: 0;
gap: 0;
counter-reset: steps-counter;
}
[data-role="steps"] > li {
display: flex;
flex-direction: column;
align-items: center;
flex: 1;
min-width: 0;
position: relative;
counter-increment: steps-counter;
padding-top: calc(var(--space-5) + var(--space-3)); /* room for the node circle */
text-align: center;
}
/* Connector line between steps */
[data-role="steps"] > li + li::before {
content: "";
position: absolute;
top: calc(var(--space-3) / 2 + 0.75rem); /* vertically centred on the node */
left: calc(-50% + 1.25rem);
right: calc(50% + 1.25rem);
height: var(--border-width);
background: var(--border);
z-index: 0;
}
/* Step node circle — drawn via ::after on the li */
[data-role="steps"] > li::after {
content: counter(steps-counter);
position: absolute;
top: var(--space-3);
left: 50%;
transform: translateX(-50%);
width: 1.5rem;
height: 1.5rem;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
font-family: var(--font-mono);
font-size: var(--text-xs);
font-weight: var(--font-weight-6);
z-index: 1;
/* default (pending) colours — overridden below */
background: var(--surface-card);
border: var(--border-width) solid var(--border);
color: var(--text-3);
transition: background var(--ease), border-color var(--ease), color var(--ease);
}
/* Step label text */
[data-role="steps"] > li > span {
font-family: var(--font-ui);
font-size: var(--text-sm);
color: var(--text-3);
transition: color var(--ease);
padding-inline: var(--space-2);
word-break: break-word;
}
/* ── Status variants ────────────────────────────────────────────── */
[data-role="steps"] > [data-status="complete"]::after {
content: "✓";
background: var(--accent-subtle);
border-color: var(--accent);
color: var(--accent);
}
[data-role="steps"] > [data-status="complete"] > span {
color: var(--text-2);
}
/* Connector line from a completed step is accented */
[data-role="steps"] > [data-status="complete"] + li::before {
background: var(--accent);
}
[data-role="steps"] > [data-status="active"]::after {
background: var(--accent);
border-color: var(--accent);
color: var(--on-accent);
box-shadow: 0 0 0 var(--border-size-2) var(--accent-focus);
}
[data-role="steps"] > [data-status="active"] > span {
color: var(--text);
font-weight: var(--font-weight-5);
}
/* pending is the default — no additional rules needed */
/* ── Vertical variant ───────────────────────────────────────────── */
/* Add data-layout="vertical" to the ol for a top-down flow */
[data-role="steps"][data-layout="vertical"] {
flex-direction: column;
gap: var(--space-5);
}
[data-role="steps"][data-layout="vertical"] > li {
flex-direction: row;
align-items: center;
text-align: left;
padding-top: 0;
padding-left: calc(1.5rem + var(--space-4)); /* room for the node */
gap: var(--space-4);
}
[data-role="steps"][data-layout="vertical"] > li::after {
top: 50%;
left: 0;
transform: translateY(-50%);
}
/* Vertical connector: vertical line */
[data-role="steps"][data-layout="vertical"] > li + li::before {
content: "";
position: absolute;
top: calc(-1 * var(--space-5));
left: 0.675rem; /* centred on the 1.5rem node */
width: var(--border-width);
height: var(--space-5);
right: auto;
background: var(--border);
}
[data-role="steps"][data-layout="vertical"] > [data-status="complete"] + li::before {
background: var(--accent);
}
[data-role="steps"][data-layout="vertical"] > li > span {
padding-inline: 0;
}

View file

@ -0,0 +1,681 @@
/**
* 04-data-attrs.css
* Agentic extensions: data-attribute selectors for vault concepts
* Part of: Agentic Semantic Web
*/
@layer data-attrs {
/*
Vault-specific role patterns
*/
/* Command box for install instructions */
[data-role="command-box"] {
display: flex;
align-items: center;
justify-content: space-between;
background: var(--surface-1);
border: 1px solid var(--border);
border-radius: var(--radius-md);
padding: 0.75rem 1rem;
font-family: var(--font-mono);
font-size: var(--text-sm);
margin: 1.5rem 0;
}
[data-role="command-box"] .prefix {
color: var(--text-3);
margin-right: 0.5rem;
user-select: none;
}
/*
Wikilinks [[Note Name]]
*/
[data-wikilink] {
color: var(--accent-blue);
font-family: var(--font-mono);
font-size: 0.9em;
text-decoration: none;
border-bottom: 1px dotted var(--border);
transition: border-color var(--ease);
}
[data-wikilink]:hover {
border-bottom-color: var(--accent-blue);
}
[data-wikilink][data-unresolved] {
color: var(--text-dim);
border-bottom-color: var(--text-dim);
}
/*
Tasks - [ ] todo / - [x] done / - [?] blocked
*/
[data-task] {
display: block;
padding: 0.4em 0;
font-family: var(--font-mono);
font-size: var(--text-sm);
}
[data-task]::before {
margin-right: 0.75em;
font-weight: 700;
}
[data-task="todo"]::before {
content: "○";
color: var(--accent-orange);
}
[data-task="done"]::before {
content: "●";
color: var(--accent);
}
[data-task="blocked"]::before {
content: "◐";
color: var(--accent-red);
}
/*
Status indicators awake / sleeping / blocked / unknown
*/
[data-status] {
font-family: var(--font-mono);
font-size: var(--text-sm);
}
[data-status="awake"] {
color: var(--accent);
}
[data-status="sleeping"] {
color: var(--text-3);
font-style: italic;
}
[data-status="blocked"] {
color: var(--accent-red);
}
[data-status="unknown"] {
color: var(--text-dim);
}
/*
Callouts note / warning / error / tip
*/
[data-callout] {
margin: 1.5em 0;
padding: 1em 1.25em;
border-left: 3px solid var(--accent-blue);
background: var(--surface-card);
border-radius: 0 var(--radius-md) var(--radius-md) 0;
}
[data-callout="warning"] { border-left-color: var(--accent-orange); }
[data-callout="error"] { border-left-color: var(--accent-red); }
[data-callout="tip"] { border-left-color: var(--accent); }
[data-callout-title] {
font-family: var(--font-mono);
font-weight: 500;
font-size: var(--text-sm);
text-transform: uppercase;
letter-spacing: 0.05em;
color: var(--text);
margin-bottom: 0.5em;
display: block;
}
/*
Session metadata mode / timestamp / hash
*/
[data-session] {
display: block;
padding: 0.75em 1em;
margin: 1em 0;
background: var(--surface-card);
border: 1px solid var(--border);
border-left: 3px solid var(--accent);
font-family: var(--font-mono);
font-size: var(--text-sm);
}
[data-mode="autonomous"] { color: var(--accent-blue); }
[data-mode="interactive"] { color: var(--accent); }
[data-session-meta] {
font-family: var(--font-mono);
font-size: var(--text-sm);
color: var(--text-3);
}
/*
Tags and hashes
*/
[data-tag] {
color: var(--accent-blue);
font-family: var(--font-mono);
font-size: 0.85em;
text-decoration: none;
}
[data-tag]::before { content: "#"; }
[data-tag]:hover { color: var(--text); }
[data-hash] {
font-family: var(--font-mono);
color: var(--text-3);
font-size: var(--text-sm);
letter-spacing: -0.02em;
}
/*
Semantic roles timeline / status-card / diff
*/
[data-role="timeline"] {
border-left: 1px solid var(--border);
padding-left: 1.5em;
margin: 1.5em 0;
}
[data-role="timeline"] > * {
position: relative;
margin-bottom: 1.5em;
}
[data-role="timeline"] > *::before {
content: "●";
position: absolute;
left: -1.85em;
color: var(--accent);
font-size: 0.7em;
}
[data-role="status-card"] {
padding: 1.25em;
background: var(--surface-card);
border: 1px solid var(--border);
border-radius: var(--radius-md);
margin: 1em 0;
}
[data-role="diff"] {
font-family: var(--font-mono);
font-size: var(--text-sm);
padding: 0.75em 1em;
background: var(--surface-1);
border: 1px solid var(--border);
border-radius: var(--radius-md);
overflow-x: auto;
}
[data-role="diff"] .add { color: var(--accent); }
[data-role="diff"] .remove { color: var(--accent-red); }
[data-role="diff"] .context { color: var(--text-dim); }
/*
Tooltips hover/focus-visible, accessible
Usage: <span data-tooltip="Explanation text">term</span>
*/
[data-tooltip] {
position: relative;
cursor: help;
border-bottom: 1px dotted var(--text-dim);
}
[data-tooltip]::after {
content: attr(data-tooltip);
position: absolute;
bottom: calc(100% + 0.5rem);
left: 50%;
transform: translateX(-50%);
padding: 0.4rem 0.75rem;
background: var(--surface-1);
color: var(--text);
border: 1px solid var(--border);
border-radius: var(--radius-md);
font-family: var(--font-mono);
font-size: var(--text-xs);
line-height: 1.4;
white-space: nowrap;
max-width: var(--tooltip-max-width);
overflow: hidden;
text-overflow: ellipsis;
pointer-events: none;
opacity: 0;
transition: opacity var(--ease);
z-index: 10;
}
/* Arrow */
[data-tooltip]::before {
content: "";
position: absolute;
bottom: calc(100% + 0.15rem);
left: 50%;
transform: translateX(-50%);
border: 0.35rem solid transparent;
border-top-color: var(--border);
pointer-events: none;
opacity: 0;
transition: opacity var(--ease);
z-index: 10;
}
[data-tooltip]:hover::after,
[data-tooltip]:hover::before,
[data-tooltip]:focus-visible::after,
[data-tooltip]:focus-visible::before {
opacity: 1;
}
/* Bottom placement */
[data-tooltip-position="bottom"]::after {
bottom: auto;
top: calc(100% + 0.5rem);
}
[data-tooltip-position="bottom"]::before {
bottom: auto;
top: calc(100% + 0.15rem);
border-top-color: transparent;
border-bottom-color: var(--border);
}
/* Generator utility roles */
[data-role="log-entry"] {
padding: 0.3rem 0;
border-bottom: 1px solid var(--border-subtle);
}
[data-role="list-item"] {
padding: 0.1rem 0;
}
/*
Sub-navigation section nav within a page group
*/
/* Usage:
<nav data-subnav>
<a href="/vigilio/" aria-current="page">index</a>
<a href="/vigilio/now">now</a>
<a href="/vigilio/status">status</a>
</nav>
Place inside <main class="container"> before article content.
aria-current="page" marks the active section. No classes needed. */
[data-subnav] {
display: flex;
align-items: center;
font-family: var(--font-mono);
font-size: var(--text-sm);
margin-bottom: 2rem;
padding-bottom: 0.75rem;
border-bottom: 1px solid var(--border);
}
[data-subnav] a {
color: var(--text-dim);
text-decoration: none;
transition: color var(--ease);
}
[data-subnav] a + a::before {
content: "/";
color: var(--border);
margin: 0 0.6rem;
}
[data-subnav] a:hover {
color: var(--text);
}
[data-subnav] a[aria-current="page"] {
color: var(--text);
}
/*
data-diff CSS diff viewer for code review and comparison output
Issue: agentic-semantic-web#52
*/
[data-diff] {
font-family: var(--font-mono);
font-size: var(--text-sm);
background: var(--surface-1);
border: 1px solid var(--border);
border-radius: var(--radius-md);
overflow-x: auto;
margin: var(--space-5) 0;
padding: 0;
}
/* File header */
[data-diff-file] {
display: block;
background: var(--surface-card);
border-bottom: 1px solid var(--border);
padding: 0.4em 1em;
font-size: var(--text-xs);
color: var(--text-3);
letter-spacing: 0.02em;
}
/* Individual diff lines */
[data-diff-line] {
display: block;
padding: 0.15em 1em 0.15em 3em;
position: relative;
line-height: 1.6;
white-space: pre;
}
/* Prefix gutter marker */
[data-diff-line]::before {
position: absolute;
left: 1em;
width: 1.5em;
text-align: center;
}
[data-diff-line="added"] {
background: var(--diff-add-bg);
color: var(--green-3);
}
[data-diff-line="added"]::before {
content: "+";
color: var(--green-5);
}
[data-diff-line="removed"] {
background: var(--diff-remove-bg);
color: var(--diff-remove-text);
}
[data-diff-line="removed"]::before {
content: "";
color: var(--red-6);
}
[data-diff-line="context"] {
color: var(--text-3);
}
[data-diff-line="context"]::before {
content: " ";
}
/* Hunk header — @@ line markers */
[data-diff-line="hunk"] {
background: var(--diff-hunk-bg);
color: var(--accent-blue);
font-style: italic;
}
[data-diff-line="hunk"]::before {
content: "@@";
font-style: normal;
color: var(--accent-blue);
opacity: 0.6;
}
/*
data-redacted privacy-aware redaction styling
Issue: agentic-semantic-web#55
*/
/* Base: fully redacted — black bar, not selectable */
[data-redacted] {
background: var(--text);
color: transparent;
border-radius: var(--radius-sm);
user-select: none;
/* Screen reader replacement handled via aria-label on element */
}
/* Block-level redaction */
[data-redacted]:is(p, div, section, article, li) {
display: block;
min-height: 1.2em;
}
/* Variant: reveal on hover/focus */
[data-redacted="reveal"] {
cursor: pointer;
transition: background var(--ease), color var(--ease);
}
[data-redacted="reveal"]:hover,
[data-redacted="reveal"]:focus {
background: var(--surface-card);
color: var(--text);
outline: 1px solid var(--border);
border-radius: var(--radius-sm);
user-select: text;
}
/* Variant: label — shows [REDACTED] text */
[data-redacted="label"] {
background: var(--surface-1);
color: var(--text-dim);
font-family: var(--font-mono);
font-size: 0.85em;
border: 1px solid var(--border);
border-radius: var(--radius-sm);
padding: 0 0.35em;
user-select: none;
}
[data-redacted="label"]::before {
content: "[REDACTED]";
}
[data-redacted="label"] > * {
display: none;
}
/* Light mode adjustments */
@media (prefers-color-scheme: light) {
[data-redacted] {
background: var(--gray-15);
}
[data-redacted="reveal"]:hover,
[data-redacted="reveal"]:focus {
background: var(--gray-1);
color: var(--gray-15);
}
}
/*
data-reading-progress CSS-only scroll progress bar
Issue: agentic-semantic-web#53
*/
@keyframes asw-reading-progress {
from { width: 0%; }
to { width: 100%; }
}
[data-reading-progress]::before {
content: "";
position: fixed;
top: 0;
left: 0;
height: var(--border-size-2);
background: var(--accent);
z-index: 9999;
/* Subtle shadow so bar is visible on light pages too */
box-shadow: 0 0 6px var(--accent-focus);
}
/* animation-timeline: scroll() fills as the page scrolls.
Guarded: skip for users who prefer reduced motion. */
@media (--motionOK) {
[data-reading-progress]::before {
animation: asw-reading-progress auto linear;
animation-timeline: scroll(root);
}
}
/*
ai-disclosure styling for AI content disclosure attributes
Issue: agentic-semantic-web#58
*/
/* Subtle accent on AI-generated sections — light left border indicator */
[ai-disclosure] {
border-left: var(--border-size-2) solid transparent;
padding-left: var(--space-3);
}
[ai-disclosure="ai-generated"] {
border-left-color: var(--ai-generated-border);
}
[ai-disclosure="ai-assisted"] {
border-left-color: var(--ai-assisted-border);
}
/* Autonomous — more distinct: full accent treatment */
[ai-disclosure="autonomous"] {
border-left-color: var(--accent);
border-left-width: var(--border-size-2);
}
/* Mixed — yellow/amber to signal blended provenance */
[ai-disclosure="mixed"] {
border-left-color: var(--ai-mixed-border);
}
/* Disclosure badge — optional ::after label for verbose mode */
[ai-disclosure][data-show-disclosure]::after {
content: " [" attr(ai-disclosure) "]";
font-family: var(--font-mono);
font-size: var(--text-xs);
color: var(--text-dim);
vertical-align: super;
font-size: 0.65em;
}
/* ── CTA buttons: data-role on <a> ─────────────────────────────────────── */
/* Agents write <a href="..."> naturally. data-role styles intent without class names. */
a[data-role="primary"] {
display: inline-flex;
align-items: center;
padding: var(--space-2) var(--space-5);
background: var(--accent);
color: var(--on-accent);
border-radius: var(--radius-md);
font-weight: 500;
text-decoration: none;
transition: background var(--duration-quick-2) var(--ease-1);
}
a[data-role="primary"]:hover {
background: var(--accent-hover);
color: var(--on-accent);
text-decoration: none;
}
a[data-role="secondary"] {
display: inline-flex;
align-items: center;
padding: var(--space-2) var(--space-5);
border: 1px solid var(--border);
border-radius: var(--radius-md);
color: var(--text-2);
text-decoration: none;
transition: border-color var(--duration-quick-2) var(--ease-1), color var(--duration-quick-2) var(--ease-1);
}
a[data-role="secondary"]:hover {
border-color: var(--accent);
color: var(--text);
text-decoration: none;
}
/* ── Badge atom ────────────────────────────────────────────────────────────── */
/* Icon badge / token pill. <span data-badge>token</span>. */
[data-badge] {
display: inline-flex;
align-items: center;
justify-content: center;
background: var(--surface-2);
border: 1px solid var(--border);
border-radius: var(--radius-md);
padding: var(--space-2) var(--space-3);
font-family: var(--font-mono);
font-size: var(--text-xs);
color: var(--accent);
margin-bottom: var(--space-3);
}
/*
data-size universal size modifier axis
Issue: lineage-ingestion / Semantic UI modifier grammar
Scales font-size, padding, and gap on any component.
Inherit-safe: child elements scale relative to the component root.
Usage:
<span data-badge data-size="lg">token</span>
<div data-role="status-card" data-size="sm"></div>
<a data-role="primary" data-size="xl">Big CTA</a>
Values: xs / sm / md (default, no-op) / lg / xl
*/
[data-size="xs"] {
font-size: var(--font-size-00, 0.6rem);
padding: var(--size-1) var(--size-2);
gap: var(--size-1);
}
[data-size="sm"] {
font-size: var(--text-xs);
padding: var(--size-1) var(--size-3);
gap: var(--size-2);
}
/* md is the default — explicit reset for override contexts */
[data-size="md"] {
font-size: var(--text-base);
padding: var(--space-2) var(--space-4);
gap: var(--space-3);
}
[data-size="lg"] {
font-size: var(--text-2xl);
padding: var(--space-3) var(--space-5);
gap: var(--space-4);
}
[data-size="xl"] {
font-size: var(--text-3xl);
padding: var(--space-4) var(--space-5);
gap: var(--space-5);
}
} /* end @layer data-attrs */

View file

@ -0,0 +1,274 @@
/**
* 05-utilities.css
* Utility patterns (layout helpers, text modifiers, responsive utilities)
* Part of: Agentic Semantic Web
*/
@layer utilities {
/*
Text utilities
*/
[data-text~="mono"] {
font-family: var(--font-mono);
}
[data-text~="dim"] {
color: var(--text-3);
}
[data-text~="accent"] {
color: var(--accent);
}
[data-text~="small"] {
font-size: var(--text-xs);
}
/* Eyebrow — small monospace uppercase accent label above a heading */
[data-text~="eyebrow"] {
display: block;
font-family: var(--font-mono);
font-size: var(--text-xs);
text-transform: uppercase;
letter-spacing: 0.08em;
color: var(--accent);
margin-bottom: var(--space-2);
}
/*
Layout utilities
*/
/* Max-width content column — constrains fluid sections to readable width */
[data-wrap] {
max-width: var(--width-content);
margin-inline: auto;
padding-inline: var(--space-5);
}
/* Grid layout with responsive stacking */
[data-layout="grid-2"] {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 1rem;
}
@media (--md-n-below) {
[data-layout="grid-2"] {
grid-template-columns: 1fr;
}
}
/* Card grid — responsive wrap for article cards */
[data-layout="card-grid"] {
display: flex;
flex-wrap: wrap;
gap: 1.5rem;
}
[data-layout="card-grid"] > * {
flex: 1 1 calc(50% - 0.75rem);
min-width: var(--size-px-13);
}
@media (--md-n-below) {
[data-layout="card-grid"] > * {
flex-basis: 100%;
}
}
/* Stats bar — horizontal row of key-value metrics */
[data-layout="stats"] {
display: flex;
flex-wrap: wrap;
gap: 0;
}
[data-layout="stats"] > * {
flex: 1 1 0;
min-width: 5rem;
padding: 0.75rem 0;
text-align: center;
border-right: 1px solid var(--border-subtle);
}
[data-layout="stats"] > *:last-child {
border-right: none;
}
[data-layout="stats"] .value {
display: block;
font-family: var(--font-mono);
font-size: 1.5rem;
font-weight: 600;
line-height: 1.2;
}
[data-layout="stats"] .label {
display: block;
font-family: var(--font-mono);
font-size: 0.65rem;
letter-spacing: 0.08em;
text-transform: uppercase;
color: var(--text-3);
margin-top: 0.2rem;
}
@media (--sm-n-below) {
[data-layout="stats"] > * {
flex-basis: 33%;
border-right: none;
border-bottom: 1px solid var(--border-subtle);
}
}
/* Inline definition lists */
dl[data-layout="inline"] {
display: grid;
grid-template-columns: auto 1fr;
gap: 0.15rem 1rem;
align-items: baseline;
}
dl[data-layout="inline"] dt,
dl[data-layout="inline"] dd {
margin: 0;
padding: 0;
margin-inline-start: 0;
}
/*
Responsive visibility
*/
/* Hide on mobile */
[data-visible="desktop"] {
display: none;
}
@media (--md-n-above) {
[data-visible="desktop"] {
display: initial;
}
}
/* Hide on desktop */
[data-visible="mobile"] {
display: initial;
}
@media (--md-n-above) {
[data-visible="mobile"] {
display: none;
}
}
/*
Loading indicator aria-busy
Usage: <button aria-busy="true">Loading</button>
<section aria-busy="true">Content loading</section>
*/
@keyframes spin {
to { transform: rotate(360deg); }
}
[aria-busy="true"] {
cursor: progress;
}
/* Inline spinner before text in buttons and interactive elements */
:is(button, [role="button"], a)[aria-busy="true"]::before {
content: "";
display: inline-block;
width: 1em;
height: 1em;
margin-right: 0.5em;
vertical-align: -0.125em;
border: var(--border-size-2) solid currentColor;
border-top-color: transparent;
border-radius: 50%;
}
/* Disable interaction on busy buttons */
:is(button, [role="button"])[aria-busy="true"] {
pointer-events: none;
opacity: 0.7;
}
/* Block-level busy: overlay spinner centered */
:is(section, article, main, div)[aria-busy="true"] {
position: relative;
min-height: 3rem;
}
:is(section, article, main, div)[aria-busy="true"]::after {
content: "";
position: absolute;
top: 50%;
left: 50%;
width: 1.5rem;
height: 1.5rem;
margin: -0.75rem 0 0 -0.75rem;
border: 2px solid var(--text-3);
border-top-color: transparent;
border-radius: 50%;
}
/* Spinner rotation — guarded: skip for users who prefer reduced motion */
@media (--motionOK) {
:is(button, [role="button"], a)[aria-busy="true"]::before {
animation: spin var(--spinner-duration) linear infinite;
}
:is(section, article, main, div)[aria-busy="true"]::after {
animation: spin var(--spinner-duration) linear infinite;
}
}
/*
Accessibility enhancements
*/
/* Disable all transitions and animations for reduced motion preference */
@media (prefers-reduced-motion: reduce) {
*,
*::before,
*::after {
animation-duration: 0.01ms !important;
animation-iteration-count: 1 !important;
transition-duration: 0.01ms !important;
scroll-behavior: auto !important;
}
}
/* Increase contrast for high-contrast preference */
@media (prefers-contrast: more) {
:root {
--border-color: var(--gray-10);
--border-color-subtle: var(--gray-12);
--text-primary: var(--gray-0);
--text-secondary: var(--gray-3);
--border-width: var(--border-size-2);
}
/* Thicker borders on interactive elements */
a,
button,
input,
select,
textarea,
[data-wikilink] {
border-width: var(--border-size-2);
}
/* Stronger focus indicators */
:focus-visible {
outline-width: var(--border-size-3);
outline-offset: var(--border-size-3);
}
}
} /* end @layer utilities */

View file

@ -0,0 +1,761 @@
/**
* 06-charts.css
* Data-driven charts from semantic HTML tables.
* Absorbed from Charts.css class API converted to data-attributes.
*
* Core vocabulary:
* data-chart="bar|column|line|area|pie" chart type
* data-chart-labels show axis labels (thead)
* data-chart-spacing="15" gap between bars (default 2)
* data-chart-stacked stacked multi-dataset mode
* style="--size: 0.8" data injection on <td> (legal exception)
* style="--color: #hex" per-row color override on <tr>
*
* Pragmatic exception: style="--size: N" and style="--color: X" on table cells
* are DATA injection, not presentation they bind numeric values to CSS.
* This is the one place ASW permits inline style attributes.
*
* Chart dimensions:
* --chart-height Bar chart: bar thickness. Column chart: chart height.
* --chart-bar-size Column chart: bar width.
* --chart-gap Gap between data points.
*
* Lineage: Charts.css (MIT) converted class API to data-attribute API.
* Reference: chartscss.org
*/
@layer charts {
/*
Shared chart tokens
*/
[data-chart] {
/* Data series colors — cycle via nth-child in each chart type */
--chart-color-1: var(--accent); /* green */
--chart-color-2: var(--accent-blue); /* blue */
--chart-color-3: var(--accent-orange); /* orange */
--chart-color-4: var(--accent-red); /* red */
--chart-color-5: var(--purple-5, #ae3ec9);
--chart-color-6: var(--cyan-5, #15aabf);
--chart-color-7: var(--pink-5, #e64980);
--chart-color-8: var(--teal-5, #0ca678);
/* Layout */
--chart-height: 200px; /* column chart area height */
--chart-bar-size: 2rem; /* column bar width / bar chart bar height */
--chart-gap: 6px; /* spacing between data points */
/* Axis / labels */
--chart-axis: var(--border);
--chart-axis-width: 2px;
--chart-label: var(--text-3);
--chart-label-size: var(--text-xs);
/* Bar styling */
--chart-radius: var(--radius-2);
/* Reset table styles — <table> is presentational structure here */
display: block;
inline-size: 100%;
border-collapse: collapse;
border-spacing: 0;
background: transparent;
}
[data-chart] caption {
display: block;
font-size: var(--text-sm);
color: var(--text-3);
text-align: start;
padding-block-end: var(--size-3);
caption-side: top;
}
/* thead: hidden by default, shown with data-chart-labels */
[data-chart] thead {
display: none;
}
[data-chart][data-chart-labels] thead {
display: block;
}
/* tbody: each chart type overrides this */
[data-chart] tbody {
display: block;
}
/*
Bar chart horizontal bars
Structure:
<table data-chart="bar">
<caption>Title</caption>
<tbody>
<tr>
<th scope="row">Label</th>
<td style="--size: 0.8">80%</td>
</tr>
</tbody>
</table>
The bar width = 100% × --size. Bar is a ::before pseudo on td.
*/
[data-chart="bar"] tbody {
display: flex;
flex-direction: column;
gap: var(--chart-gap);
/* Left axis line */
border-inline-start: var(--chart-axis-width) solid var(--chart-axis);
padding-inline-start: 0;
}
[data-chart="bar"] tr {
display: flex;
align-items: center;
gap: var(--size-3);
}
/* Row label (th) */
[data-chart="bar"] th[scope="row"] {
font-size: var(--chart-label-size);
font-weight: 400;
color: var(--chart-label);
min-inline-size: 5rem;
max-inline-size: 8rem;
text-align: end;
padding-block: 0;
padding-inline: var(--size-2) 0;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
flex-shrink: 0;
}
/* Data cell — the track */
[data-chart="bar"] td {
flex: 1;
position: relative;
block-size: var(--chart-bar-size);
display: flex;
align-items: center;
padding: 0;
overflow: visible;
}
/* The bar itself — ::before */
[data-chart="bar"] td::before {
content: "";
display: block;
block-size: 100%;
inline-size: calc(100% * var(--size, 0.5));
background: var(--color, var(--chart-color-1));
border-radius: 0 var(--chart-radius) var(--chart-radius) 0;
transition: opacity var(--ease), inline-size var(--duration-moderate-1) var(--ease-3, ease-out);
}
[data-chart="bar"] td:hover::before {
opacity: 0.8;
}
/* Data label (text inside/after bar) */
[data-chart="bar"] td::after {
content: attr(data-value);
position: absolute;
inset-inline-start: calc(100% * var(--size, 0.5) + 0.35rem);
font-size: var(--chart-label-size);
color: var(--text-3);
white-space: nowrap;
}
/* Color cycling for multi-series */
[data-chart="bar"] tr:nth-child(1) td::before { background: var(--color, var(--chart-color-1)); }
[data-chart="bar"] tr:nth-child(2) td::before { background: var(--color, var(--chart-color-2)); }
[data-chart="bar"] tr:nth-child(3) td::before { background: var(--color, var(--chart-color-3)); }
[data-chart="bar"] tr:nth-child(4) td::before { background: var(--color, var(--chart-color-4)); }
[data-chart="bar"] tr:nth-child(5) td::before { background: var(--color, var(--chart-color-5)); }
[data-chart="bar"] tr:nth-child(6) td::before { background: var(--color, var(--chart-color-6)); }
[data-chart="bar"] tr:nth-child(7) td::before { background: var(--color, var(--chart-color-7)); }
[data-chart="bar"] tr:nth-child(8) td::before { background: var(--color, var(--chart-color-8)); }
[data-chart="bar"] tr:nth-child(n+9) td::before { background: var(--color, var(--chart-color-1)); }
/* ── Spacing modifiers ──────────────────────────────────── */
[data-chart="bar"][data-chart-spacing="1"] tbody { gap: 2px; }
[data-chart="bar"][data-chart-spacing="2"] tbody { gap: 6px; }
[data-chart="bar"][data-chart-spacing="3"] tbody { gap: 10px; }
[data-chart="bar"][data-chart-spacing="4"] tbody { gap: 16px; }
[data-chart="bar"][data-chart-spacing="5"] tbody { gap: 24px; }
/*
Column chart vertical bars
Structure:
<table data-chart="column">
<caption>Title</caption>
<tbody>
<tr>
<th scope="row">Jan</th>
<td style="--size: 0.6">60</td>
</tr>
</tbody>
</table>
The chart area is --chart-height. Each column height = --chart-height × --size.
Columns sit at the bottom of the chart area (flex-end alignment).
*/
[data-chart="column"] tbody {
display: flex;
flex-direction: row;
align-items: flex-end;
gap: var(--chart-gap);
block-size: var(--chart-height);
border-block-end: var(--chart-axis-width) solid var(--chart-axis);
padding: 0;
}
[data-chart="column"] tr {
display: flex;
flex-direction: column;
align-items: center;
justify-content: flex-end;
flex: 1;
block-size: 100%;
gap: var(--size-1);
}
/* Column label (th) at the bottom */
[data-chart="column"] th[scope="row"] {
font-size: var(--chart-label-size);
font-weight: 400;
color: var(--chart-label);
text-align: center;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
max-inline-size: 100%;
padding: 0;
padding-block-start: var(--size-1);
/* Move below axis */
order: 2;
margin-block-start: var(--size-2);
}
/* Data cell — the column bar */
[data-chart="column"] td {
display: block;
inline-size: 100%;
block-size: calc(var(--chart-height) * var(--size, 0.5));
padding: 0;
order: 1;
transition: block-size var(--duration-moderate-1) var(--ease-3, ease-out);
border-radius: var(--chart-radius) var(--chart-radius) 0 0;
}
/* Color cycling for columns */
[data-chart="column"] tr:nth-child(1) td { background: var(--color, var(--chart-color-1)); }
[data-chart="column"] tr:nth-child(2) td { background: var(--color, var(--chart-color-2)); }
[data-chart="column"] tr:nth-child(3) td { background: var(--color, var(--chart-color-3)); }
[data-chart="column"] tr:nth-child(4) td { background: var(--color, var(--chart-color-4)); }
[data-chart="column"] tr:nth-child(5) td { background: var(--color, var(--chart-color-5)); }
[data-chart="column"] tr:nth-child(6) td { background: var(--color, var(--chart-color-6)); }
[data-chart="column"] tr:nth-child(7) td { background: var(--color, var(--chart-color-7)); }
[data-chart="column"] tr:nth-child(8) td { background: var(--color, var(--chart-color-8)); }
[data-chart="column"] tr:nth-child(n+9) td { background: var(--color, var(--chart-color-1)); }
[data-chart="column"] td:hover {
opacity: 0.8;
}
/* ── Spacing modifiers ──────────────────────────────────── */
[data-chart="column"][data-chart-spacing="1"] tbody { gap: 2px; }
[data-chart="column"][data-chart-spacing="2"] tbody { gap: 6px; }
[data-chart="column"][data-chart-spacing="3"] tbody { gap: 12px; }
[data-chart="column"][data-chart-spacing="4"] tbody { gap: 20px; }
[data-chart="column"][data-chart-spacing="5"] tbody { gap: 32px; }
/* ── Column chart labels ───────────────────────────────── */
/* When data-chart-labels present, show thead as axis header */
[data-chart="column"][data-chart-labels] thead {
display: flex;
justify-content: space-around;
margin-block-end: var(--size-2);
}
[data-chart="column"][data-chart-labels] thead th {
font-size: var(--chart-label-size);
color: var(--chart-label);
font-weight: 400;
text-align: center;
flex: 1;
}
/*
Area chart filled area from baseline
CSS-only area charts use linear-gradient on the td background.
Each point's area = --size fraction of the column height.
Structure identical to column but cells connect visually.
The visual connection requires identical widths and no gap (or clip).
*/
[data-chart="area"] tbody {
display: flex;
flex-direction: row;
align-items: flex-end;
block-size: var(--chart-height);
border-block-end: var(--chart-axis-width) solid var(--chart-axis);
gap: 0; /* no gap — cells must connect */
padding: 0;
}
[data-chart="area"] tr {
display: flex;
flex-direction: column;
align-items: stretch;
justify-content: flex-end;
flex: 1;
block-size: 100%;
}
[data-chart="area"] th[scope="row"] {
font-size: var(--chart-label-size);
font-weight: 400;
color: var(--chart-label);
text-align: center;
order: 2;
padding-block-start: var(--size-1);
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
/* Area cell — filled gradient from --size down to baseline */
[data-chart="area"] td {
display: block;
inline-size: 100%;
block-size: calc(var(--chart-height) * var(--size, 0.5));
padding: 0;
order: 1;
background: linear-gradient(
to bottom,
var(--chart-color-1) 0%,
color-mix(in oklch, var(--chart-color-1), transparent 70%) 100%
);
}
/*
Line chart dots connected by a visual line
CSS-only: we use the column approach but mark the top with a dot (::after)
and use a border-top line to simulate connection between points.
True line interpolation requires JavaScript or SVG.
What we ship: column bars in outline/transparent mode with an accent dot
at the top semantic, readable, no JS.
*/
[data-chart="line"] tbody {
display: flex;
flex-direction: row;
align-items: flex-end;
block-size: var(--chart-height);
border-block-end: var(--chart-axis-width) solid var(--chart-axis);
gap: 0;
padding: 0;
position: relative;
}
[data-chart="line"] tr {
display: flex;
flex-direction: column;
align-items: center;
justify-content: flex-end;
flex: 1;
block-size: 100%;
}
[data-chart="line"] th[scope="row"] {
font-size: var(--chart-label-size);
font-weight: 400;
color: var(--chart-label);
text-align: center;
order: 2;
padding-block-start: var(--size-1);
white-space: nowrap;
}
/* Line chart cell — transparent bar with accent top border + dot */
[data-chart="line"] td {
display: block;
inline-size: 100%;
block-size: calc(var(--chart-height) * var(--size, 0.5));
padding: 0;
order: 1;
background: linear-gradient(
to bottom,
color-mix(in oklch, var(--chart-color-1), transparent 80%) 0%,
transparent 60%
);
border-block-start: 2px solid var(--chart-color-1);
position: relative;
}
/* Dot at data point */
[data-chart="line"] td::before {
content: "";
display: block;
position: absolute;
inset-block-start: -5px;
inset-inline-start: 50%;
translate: -50% 0;
inline-size: 8px;
block-size: 8px;
border-radius: 50%;
background: var(--chart-color-1);
border: 2px solid var(--surface);
z-index: 1;
}
/*
Pie chart conic-gradient segments
CSS-only pie charts use conic-gradient on a single element.
Each segment's arc = --size × 360deg.
Requires stacking values in CSS not practical to automate per-row.
For agent use: pie charts work best with explicit conic-gradient
set as a custom property. The data-chart="pie" wrapper provides
the shape and size; the agent sets --pie-segments.
*/
[data-chart="pie"] {
--pie-size: min(200px, 100%);
--pie-segments: conic-gradient(
var(--chart-color-1) 0% 25%,
var(--chart-color-2) 25% 50%,
var(--chart-color-3) 50% 75%,
var(--chart-color-4) 75% 100%
);
}
/* Pie uses a generated element — hide table structure visually */
[data-chart="pie"] tbody { display: none; }
/* Show caption + legend from thead */
[data-chart="pie"] thead {
display: flex;
flex-wrap: wrap;
gap: var(--size-2);
justify-content: center;
margin-block-end: var(--size-3);
}
[data-chart="pie"] thead th {
font-size: var(--chart-label-size);
color: var(--chart-label);
font-weight: 400;
}
/* The pie rendered as ::before on the table element */
[data-chart="pie"]::before {
content: "";
display: block;
inline-size: var(--pie-size);
block-size: var(--pie-size);
border-radius: 50%;
background: var(--pie-segments);
margin-inline: auto;
}
/*
Stacked bars data-chart-stacked modifier
When multiple <td> in one <tr>, stack them.
*/
[data-chart="bar"][data-chart-stacked] td {
/* Multiple tds per row — share the bar track inline */
display: inline-block;
inline-size: calc(100% * var(--size, 0.2));
border-radius: 0;
}
[data-chart="bar"][data-chart-stacked] td::before {
display: none; /* td IS the bar in stacked mode */
}
[data-chart="bar"][data-chart-stacked] td:first-of-type {
border-radius: 0 0 0 0;
}
[data-chart="bar"][data-chart-stacked] td:last-of-type {
border-radius: 0 var(--chart-radius) var(--chart-radius) 0;
}
/* Stacked color cycling */
[data-chart][data-chart-stacked] td:nth-of-type(1) { background: var(--chart-color-1); }
[data-chart][data-chart-stacked] td:nth-of-type(2) { background: var(--chart-color-2); }
[data-chart][data-chart-stacked] td:nth-of-type(3) { background: var(--chart-color-3); }
[data-chart][data-chart-stacked] td:nth-of-type(4) { background: var(--chart-color-4); }
/*
Accessibility
*/
/* Ensure cell content (the data value) is readable for screen readers
but visually hidden inside the bar text is in aria / caption */
[data-chart="bar"] td,
[data-chart="column"] td {
font-size: var(--chart-label-size);
color: transparent; /* data visible to SR, hidden visually */
}
/* Respect user preference — no transitions */
@media (prefers-reduced-motion: reduce) {
[data-chart] td,
[data-chart] td::before {
transition: none;
}
}
/*
Radial chart circular gauge
Structure:
<table data-chart="radial" style="--size: 0.72">
<caption>Token budget used</caption>
<tbody><tr><td><span>72%</span></td></tr></tbody>
</table>
The gauge is a conic-gradient on the td element.
--size (01) drives the arc: --size × 360deg = colored portion.
::before pseudo creates a donut hole cutout over the gradient.
<span> inside td floats the value text above the donut via z-index.
*/
[data-chart="radial"] {
display: inline-flex;
flex-direction: column;
align-items: center;
gap: var(--size-2);
}
[data-chart="radial"] caption {
font-size: var(--chart-label-size);
color: var(--chart-label);
text-align: center;
caption-side: bottom;
padding-block-start: var(--size-2);
}
[data-chart="radial"] tbody { display: flex; }
[data-chart="radial"] tr { display: flex; }
/* The gauge circle */
[data-chart="radial"] td {
position: relative;
width: var(--chart-radial-size);
height: var(--chart-radial-size);
border-radius: 50%;
background: conic-gradient(
var(--color, var(--chart-color-1)) 0deg calc(var(--size, 0.5) * 360deg),
var(--surface-1, var(--gray-15)) 0deg
);
display: flex;
align-items: center;
justify-content: center;
padding: 0;
border: none;
color: transparent; /* data readable by SR, hidden visually */
}
/* Donut hole */
[data-chart="radial"] td::before {
content: "";
position: absolute;
inset: var(--chart-radial-inset);
border-radius: 50%;
background: var(--surface);
z-index: 0;
}
/* Value text centered in the donut hole */
[data-chart="radial"] td span {
position: relative;
z-index: 1;
font-size: var(--text-xs);
font-family: var(--font-mono);
color: var(--text);
font-weight: 600;
}
/* Status color variants */
[data-chart="radial"][data-status="warning"] td {
background: conic-gradient(
var(--accent-orange, #f08c00) 0deg calc(var(--size, 0.5) * 360deg),
var(--surface-1, #111111) 0deg
);
}
[data-chart="radial"][data-status="danger"] td {
background: conic-gradient(
var(--accent-red, #e03131) 0deg calc(var(--size, 0.5) * 360deg),
var(--surface-1, #111111) 0deg
);
}
/*
Burndown chart sprint burndown with CSS ideal-line overlay
Structure: same as column chart, but:
- Bars use --accent-red (remaining work = red)
- tbody::after renders a diagonal linear-gradient as the ideal-line
- Ideal line runs top-left to bottom-right: full work at start zero at end
<table data-chart="burndown">
<caption>Sprint burndown</caption>
<tbody>
<tr><th scope="row">D1</th><td style="--size: 0.95">19</td></tr>
...
</tbody>
</table>
*/
[data-chart="burndown"] tbody {
display: flex;
flex-direction: row;
align-items: flex-end;
block-size: var(--chart-height);
border-block-end: var(--chart-axis-width) solid var(--chart-axis);
position: relative; /* required for ::after overlay */
gap: var(--chart-gap);
padding: 0;
}
/* Ideal-line overlay — diagonal gradient = ideal burn velocity */
[data-chart="burndown"] tbody::after {
content: "";
position: absolute;
inset: 0;
background: linear-gradient(
to bottom right,
color-mix(in oklch, var(--chart-color-2, var(--accent-blue, #4dabf7)), transparent 20%) 0%,
transparent 100%
);
pointer-events: none;
z-index: 2;
}
[data-chart="burndown"] tr {
display: flex;
flex-direction: column;
align-items: center;
justify-content: flex-end;
flex: 1;
block-size: 100%;
gap: var(--size-1);
}
/* Remaining-work bar — red, with ideal line overlay above it */
[data-chart="burndown"] td {
display: block;
inline-size: 100%;
block-size: calc(var(--chart-height) * var(--size, 0.5));
background: color-mix(in oklch, var(--chart-color-4, var(--accent-red, #e03131)), transparent 25%);
border-radius: var(--chart-radius) var(--chart-radius) 0 0;
order: 1;
padding: 0;
border: none;
color: transparent;
position: relative;
z-index: 1;
transition: opacity var(--ease);
}
[data-chart="burndown"] td:hover { opacity: 0.85; }
[data-chart="burndown"] th[scope="row"] {
font-size: var(--chart-label-size);
font-weight: 400;
color: var(--chart-label);
text-align: center;
order: 2;
padding-block-start: var(--size-1);
white-space: nowrap;
padding: 0;
margin-block-start: var(--size-2);
}
/* ── Spacing modifiers for area and line (port from bar/column) ──── */
[data-chart="area"][data-chart-spacing="1"] tbody { gap: 0; }
[data-chart="area"][data-chart-spacing="2"] tbody { gap: 2px; }
[data-chart="area"][data-chart-spacing="3"] tbody { gap: 6px; }
[data-chart="area"][data-chart-spacing="4"] tbody { gap: 12px; }
[data-chart="area"][data-chart-spacing="5"] tbody { gap: 20px; }
[data-chart="line"][data-chart-spacing="1"] tbody { gap: 0; }
[data-chart="line"][data-chart-spacing="2"] tbody { gap: 2px; }
[data-chart="line"][data-chart-spacing="3"] tbody { gap: 6px; }
[data-chart="line"][data-chart-spacing="4"] tbody { gap: 12px; }
[data-chart="line"][data-chart-spacing="5"] tbody { gap: 20px; }
/* ── data-chart-reverse modifier ────────────────────────────────── */
[data-chart="bar"][data-chart-reverse] tbody {
flex-direction: column-reverse;
}
[data-chart="column"][data-chart-reverse] tbody {
flex-direction: row-reverse;
}
/* ── data-chart-stacked on column ───────────────────────────────── */
[data-chart="column"][data-chart-stacked] tr {
flex-direction: row;
align-items: flex-end;
gap: 0;
}
[data-chart="column"][data-chart-stacked] td {
flex: 1;
border-radius: 0;
block-size: calc(var(--chart-height) * var(--size, 0.2));
}
[data-chart="column"][data-chart-stacked] td:first-of-type {
border-radius: var(--chart-radius) 0 0 0;
}
[data-chart="column"][data-chart-stacked] td:last-of-type {
border-radius: 0 var(--chart-radius) 0 0;
}
/* ── data-chart-labels on bar ────────────────────────────────────── */
[data-chart="bar"][data-chart-labels] thead {
display: block;
margin-block-end: var(--size-2);
}
[data-chart="bar"][data-chart-labels] thead th {
font-size: var(--chart-label-size);
color: var(--chart-label);
font-weight: 400;
}
} /* end @layer charts */

View file

@ -0,0 +1,138 @@
/**
* 07-chroma.css
* CSS-only syntax highlighting maps Hugo/Chroma class names to Open Props
* color tokens. Requires Hugo markup.highlight.noClasses = false.
*
* Generated class reference: hugo gen chromastyles --style=monokai
* Token palette: Open Props perceptual color scale.
* Part of: Agentic Semantic Web
*/
/* ── Wrapper ─────────────────────────────────────────────────────────── */
.chroma {
background: var(--surface-2);
border-radius: var(--radius-2);
overflow-x: auto;
}
.chroma pre {
background: var(--surface-2);
padding: var(--size-3);
border-radius: var(--radius-2);
overflow-x: auto;
margin: 0;
}
/* ── Keywords ────────────────────────────────────────────────────────── */
/* .k .kc .kd .kn .kp .kr .kt */
.chroma .k,
.chroma .kc,
.chroma .kd,
.chroma .kp,
.chroma .kr,
.chroma .kt {
color: var(--violet-4);
}
/* KeywordNamespace — import/from/as — pink accent to distinguish */
.chroma .kn {
color: var(--violet-3);
}
/* ── Strings ─────────────────────────────────────────────────────────── */
/* .s .sa .sb .sc .dl .sd .s2 .se .sh .si .sx .sr .s1 .ss */
.chroma .s,
.chroma .sa,
.chroma .sb,
.chroma .sc,
.chroma .dl,
.chroma .sd,
.chroma .s2,
.chroma .sh,
.chroma .si,
.chroma .sx,
.chroma .sr,
.chroma .s1,
.chroma .ss {
color: var(--green-4);
}
/* LiteralStringEscape — \n \t etc — slightly lighter to distinguish */
.chroma .se {
color: var(--green-3);
}
/* ── Comments ────────────────────────────────────────────────────────── */
/* .c .c1 .ch .cm .cp .cpf .cs */
.chroma .c,
.chroma .c1,
.chroma .ch,
.chroma .cm,
.chroma .cp,
.chroma .cpf,
.chroma .cs {
color: var(--text-2);
font-style: italic;
}
/* ── Numbers ─────────────────────────────────────────────────────────── */
/* .m .mb .mf .mh .mi .mo .mx */
.chroma .m,
.chroma .mb,
.chroma .mf,
.chroma .mh,
.chroma .mi,
.chroma .il,
.chroma .mo,
.chroma .mx {
color: var(--orange-3);
}
/* ── Names / Functions ───────────────────────────────────────────────── */
/* .n .na .nb .nc .nd .ne .nf .ni .nl .nn .nx .py */
.chroma .na,
.chroma .nc,
.chroma .nd,
.chroma .ne,
.chroma .nf,
.chroma .nx,
.chroma .py {
color: var(--blue-3);
}
/* ── Operators / Punctuation ─────────────────────────────────────────── */
/* .o .ow .p */
.chroma .o,
.chroma .ow {
color: var(--text);
}
/* ── Error ───────────────────────────────────────────────────────────── */
.chroma .err {
color: var(--red-4);
background: transparent;
}
/* ── Generic diffs / emphasis ────────────────────────────────────────── */
.chroma .gd { color: var(--red-4); }
.chroma .gi { color: var(--green-4); }
.chroma .ge { font-style: italic; }
.chroma .gs { font-weight: bold; }
/* ── Line number chrome ──────────────────────────────────────────────── */
.chroma .ln,
.chroma .lnt {
color: var(--text-3);
user-select: none;
padding-inline-end: var(--size-3);
}

View file

@ -0,0 +1,578 @@
/**
* 08-layout.css
* Layout patterns: container, docs layout, grid helpers
* Part of: Agentic Semantic Web
*/
/* ── Container ─────────────────────────────────────────────────────── */
.container {
max-width: var(--container-width, var(--width-xl));
margin-inline: auto;
padding-inline: var(--space-5);
}
/* ── Body baseline ──────────────────────────────────────────────────── */
main {
max-width: var(--width-full);
margin-inline: auto;
}
body {
background-color: var(--surface);
color: var(--text);
font-weight: var(--font-weight-4);
line-height: var(--leading);
font-variant-emoji: text; /* render emoji as monochrome glyphs, not OS pictographs */
min-height: 100vh;
/* font-family and font-size live in 00-reset.css — do not set here */
}
/* ── Hero ──────────────────────────────────────────────────────────── */
/* Landing page hero block. Usually <header data-layout="hero">. */
[data-layout="hero"] {
text-align: center;
padding: var(--space-8) var(--space-5);
border-bottom: 1px solid var(--border);
}
/* ── Install snippet ────────────────────────────────────────────────── */
/* One-liner install code pill. <p data-layout="install"><code>...</code></p> */
[data-layout="install"] {
display: inline-block;
background: var(--surface-1);
border: 1px solid var(--border);
border-radius: var(--radius-md);
padding: var(--space-2) var(--space-4);
font-family: var(--font-mono);
font-size: var(--text-sm);
margin: var(--space-4) 0;
}
/* ── Actions row ────────────────────────────────────────────────────── */
/* CTA button row. <nav data-layout="actions"> wraps primary + secondary links. */
nav[data-layout="actions"] {
display: flex;
gap: var(--space-4);
flex-wrap: wrap;
justify-content: center;
align-items: center;
margin-top: var(--space-5);
padding: 0;
}
nav[data-layout="actions"] a {
text-decoration: none;
color: var(--text-2);
}
nav[data-layout="actions"] a:hover {
color: var(--text);
}
/* ── Docs layout ────────────────────────────────────────────────────── */
[data-layout="docs"] {
display: grid;
grid-template-columns: var(--sidebar-width) 1fr var(--toc-width);
grid-template-rows: auto;
gap: var(--space-6);
max-width: var(--docs-max-width);
margin-inline: auto;
padding: var(--space-6) var(--space-5);
align-items: start;
}
/* ── Left sidebar ───────────────────────────────────────────────────── */
[data-layout="docs"] > aside:first-of-type {
position: sticky;
top: calc(var(--nav-height) + var(--space-4));
max-height: calc(100vh - var(--size-px-10));
overflow-y: auto;
/* ASW-styled scrollbar — thin, subtle, no system chrome */
scrollbar-width: thin;
scrollbar-color: var(--border) transparent;
}
[data-layout="docs"] > aside:first-of-type::-webkit-scrollbar {
width: var(--scrollbar-size);
}
[data-layout="docs"] > aside:first-of-type::-webkit-scrollbar-track {
background: transparent;
}
[data-layout="docs"] > aside:first-of-type::-webkit-scrollbar-thumb {
background: var(--border);
border-radius: var(--radius-full);
}
[data-layout="docs"] > aside:first-of-type::-webkit-scrollbar-thumb:hover {
background: var(--text-3);
}
/* Sidebar nav — vertical list, no top-bar chrome */
[data-layout="docs"] > aside:first-of-type nav,
nav[data-nav="sidebar"] {
display: flex;
flex-direction: column;
justify-content: flex-start;
align-items: stretch;
padding: 0;
margin: 0;
border: none;
gap: 0;
}
[data-layout="docs"] > aside:first-of-type nav small {
display: block;
color: var(--text-3);
font-size: var(--text-xs);
font-family: var(--font-mono);
text-transform: uppercase;
letter-spacing: 0.08em;
padding: 0 var(--space-3);
margin-bottom: var(--space-2);
margin-top: var(--space-4);
}
[data-layout="docs"] > aside:first-of-type nav small:first-child {
margin-top: 0;
}
[data-layout="docs"] > aside:first-of-type nav ul,
nav[data-nav="sidebar"] ul {
display: flex;
flex-direction: column;
align-items: stretch;
list-style: none;
margin: 0;
padding: 0;
gap: var(--space-1);
font-family: var(--font-ui);
font-size: var(--text-sm);
}
[data-layout="docs"] > aside:first-of-type nav ul li {
margin: 0;
padding: 0;
}
/* No pipe separators in sidebar */
[data-layout="docs"] > aside:first-of-type nav ul li + li::before,
nav[data-nav="sidebar"] ul li + li::before {
display: none;
}
[data-layout="docs"] > aside:first-of-type nav a {
display: block;
padding: var(--space-2) var(--space-3);
border-radius: var(--radius-md);
color: var(--text-2);
text-decoration: none;
text-align: left;
transition: background-color var(--ease), color var(--ease);
font-family: var(--font-ui);
font-size: var(--text-sm);
}
[data-layout="docs"] > aside:first-of-type nav a:hover {
background-color: var(--surface-hover);
color: var(--text);
}
[data-layout="docs"] > aside:first-of-type nav a[aria-current] {
background-color: var(--accent-subtle);
color: var(--accent);
}
/* ── Main content ───────────────────────────────────────────────────── */
[data-layout="docs"] > article {
min-width: 0;
}
/* ── Right TOC ──────────────────────────────────────────────────────── */
[data-layout="docs"] > aside[data-toc] {
position: sticky;
top: calc(var(--nav-height) + var(--space-4));
max-height: calc(100vh - var(--size-px-10));
overflow-y: auto;
}
/* TOC nav — vertical, compact, no top-bar chrome */
[data-layout="docs"] > aside[data-toc] nav,
nav[data-nav="toc"] {
display: flex;
flex-direction: column;
justify-content: flex-start;
align-items: stretch;
padding: 0;
margin: 0;
border: none;
gap: 0;
}
[data-layout="docs"] > aside[data-toc] small {
display: block;
color: var(--text-3);
font-size: var(--text-xs);
font-family: var(--font-mono);
text-transform: uppercase;
letter-spacing: 0.08em;
margin-bottom: var(--space-2);
}
[data-layout="docs"] > aside[data-toc] nav ul,
nav[data-nav="toc"] ul {
display: flex;
flex-direction: column;
align-items: stretch;
list-style: none;
margin: 0;
padding: 0;
gap: var(--space-1);
font-size: var(--text-xs);
}
[data-layout="docs"] > aside[data-toc] nav ul li {
margin: 0;
padding: 0;
}
[data-layout="docs"] > aside[data-toc] nav ul li + li::before,
nav[data-nav="toc"] ul li + li::before {
display: none;
}
[data-layout="docs"] > aside[data-toc] nav a {
display: block;
padding: var(--space-1) var(--space-2);
font-size: var(--text-xs);
color: var(--text-3);
text-decoration: none;
text-align: left;
border-left: var(--border-size-2) solid transparent;
transition: color var(--ease), border-color var(--ease);
}
[data-layout="docs"] > aside[data-toc] nav a:hover {
color: var(--text);
border-left-color: var(--border);
}
[data-layout="docs"] > aside[data-toc] nav a[aria-current] {
color: var(--accent);
border-left-color: var(--accent);
}
/* ── Prev/Next navigation ───────────────────────────────────────────── */
[data-role="prev-next"] {
display: flex;
justify-content: space-between;
align-items: center;
margin-top: var(--space-8);
padding-top: var(--space-5);
border-top: var(--border-width) solid var(--border);
gap: var(--space-4);
}
[data-role="prev-next"] a {
display: flex;
flex-direction: column;
gap: var(--space-1);
text-decoration: none;
color: var(--text-2);
max-width: 45%;
transition: color var(--ease);
}
[data-role="prev-next"] a:hover {
color: var(--accent);
}
[data-role="prev-next"] a[rel="prev"] {
align-items: flex-start;
}
[data-role="prev-next"] a[rel="next"] {
align-items: flex-end;
margin-left: auto;
}
[data-role="prev-next"] small {
font-size: var(--text-xs);
font-family: var(--font-mono);
color: var(--text-3);
text-transform: uppercase;
letter-spacing: 0.06em;
}
[data-role="prev-next"] span {
font-size: var(--text-sm);
}
/* ── Responsive ─────────────────────────────────────────────────────── */
@media (--docs-toc-hidden) {
[data-layout="docs"] {
grid-template-columns: var(--toc-width) 1fr;
}
[data-layout="docs"] > aside[data-toc] {
display: none;
}
}
@media (--md-n-below) {
[data-layout="docs"] {
grid-template-columns: 1fr;
padding: var(--space-4);
}
[data-layout="docs"] > aside:first-of-type {
display: none;
}
}
/* Allow <main> as content column in docs layout — override body > main container sizing */
[data-layout="docs"] > main {
max-width: none;
min-width: 0;
}
/* ── Grid helpers ───────────────────────────────────────────────────── */
[data-layout="grid-2"] {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: var(--space-5);
}
[data-layout="grid-3"] {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: var(--space-5);
}
[data-layout="card-grid"] {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(var(--card-min-width), 1fr));
gap: var(--space-5);
}
[data-layout="stats"] {
display: flex;
flex-wrap: wrap;
gap: var(--space-5);
}
[data-layout="stats"] > * {
flex: 1;
min-width: var(--size-px-11);
}
[data-layout="stats"] [data-stat="value"],
[data-layout="stats"] .value {
font-family: var(--font-mono);
font-size: var(--text-3xl);
font-weight: var(--font-weight-7);
color: var(--accent);
display: block;
}
[data-layout="stats"] [data-stat="label"],
[data-layout="stats"] .label {
font-size: var(--text-xs);
color: var(--text-3);
text-transform: uppercase;
letter-spacing: 0.08em;
display: block;
}
@media (--md-n-below) {
[data-layout="grid-2"],
[data-layout="grid-3"] {
grid-template-columns: 1fr;
}
}
/* ── Prose layout ───────────────────────────────────────────────────── */
/* Reading-optimised width. ~65 characters per line — Bringhurst/LaTeX */
/* standard for comfortable prose. Use on <main> or any block element. */
main[data-layout="prose"],
[data-layout="prose"] {
max-width: 65ch;
margin-inline: auto;
}
/* ── Timeline layout ────────────────────────────────────────────────── */
/* Chronological spine: vertical accent line, node per event. */
/* Usage: <ol data-layout="timeline"> <li> <time>…</time> <article> */
/* Issue: agentic-semantic-web#54 */
[data-layout="timeline"] {
list-style: none;
padding: 0;
margin: var(--space-5) 0;
position: relative;
}
/* Vertical spine */
[data-layout="timeline"]::before {
content: "";
position: absolute;
left: 0.6rem;
top: 0.5rem;
bottom: 0.5rem;
width: var(--border-size-1);
background: var(--border);
}
[data-layout="timeline"] > li {
display: grid;
grid-template-columns: auto 1fr;
gap: 0 var(--space-5);
align-items: start;
padding-left: calc(1.2rem + var(--space-3));
margin-bottom: var(--space-6);
position: relative;
}
[data-layout="timeline"] > li:last-child {
margin-bottom: 0;
}
/* Node dot */
[data-layout="timeline"] > li::before {
content: "";
position: absolute;
left: 0.275rem;
top: 0.45rem;
width: 0.65rem;
height: 0.65rem;
border-radius: 50%;
background: var(--accent);
border: 2px solid var(--surface);
box-shadow: 0 0 0 1px var(--accent);
}
/* Time element */
[data-layout="timeline"] > li > time {
font-family: var(--font-mono);
font-size: var(--text-xs);
color: var(--text-3);
white-space: nowrap;
padding-top: 0.1em;
display: block;
margin-bottom: var(--space-1);
}
/* Content */
[data-layout="timeline"] > li > article,
[data-layout="timeline"] > li > div {
min-width: 0;
}
[data-layout="timeline"] > li > article > :first-child,
[data-layout="timeline"] > li > div > :first-child {
margin-top: 0;
}
/* Alternate variant: alternating left/right */
[data-layout="timeline alternate"] > li:nth-child(even) {
direction: rtl;
}
[data-layout="timeline alternate"] > li:nth-child(even) > * {
direction: ltr;
}
/* ── Report layout ──────────────────────────────────────────────────── */
/* Print-first document layout. Clean on screen, correct on paper. */
/* Light surface. Constrained width. Print stylesheet built in. */
/* Issue: agentic-semantic-web#56 */
[data-layout="report"] {
background: var(--surface);
color: var(--text);
font-family: var(--font-ui);
font-size: 1rem;
line-height: var(--leading);
}
[data-layout="report"] > header,
[data-layout="report"] > main,
[data-layout="report"] > footer {
max-width: 72ch;
margin-inline: auto;
padding-inline: var(--space-5);
}
[data-layout="report"] > header {
padding-top: var(--space-6);
padding-bottom: var(--space-5);
border-bottom: 2px solid var(--border);
margin-bottom: var(--space-6);
}
[data-layout="report"] > header h1 {
font-size: var(--text-2xl);
margin: 0 0 var(--space-3);
color: var(--text);
}
[data-layout="report"] > main {
padding-bottom: var(--space-8);
}
[data-layout="report"] > footer {
border-top: 1px solid var(--border);
padding-top: var(--space-4);
padding-bottom: var(--space-4);
font-size: var(--text-sm);
color: var(--text-3);
font-family: var(--font-mono);
}
/* Print styles */
@media print {
[data-layout="report"] {
--surface: var(--gray-0);
--text: var(--gray-15);
font-size: 11pt;
}
[data-layout="report"] > header {
page-break-after: avoid;
}
[data-layout="report"] h2,
[data-layout="report"] h3 {
page-break-after: avoid;
}
[data-layout="report"] pre,
[data-layout="report"] table,
[data-layout="report"] figure {
page-break-inside: avoid;
}
[data-layout="report"] a::after {
content: " (" attr(href) ")";
font-size: 0.8em;
color: var(--text-3);
}
[data-layout="report"] a[href^="#"]::after {
content: "";
}
[data-layout="report"] nav,
[data-layout="report"] [data-no-print] {
display: none !important;
}
}

View file

@ -0,0 +1,84 @@
/**
* 08-paper.css
* Long-form research / essay content type article[data-paper]
* Promoted from lab/hugo-demo paper/single.html inline <style> block.
* Part of: Agentic Semantic Web
*/
/* ── Reading column ─────────────────────────────────────────────────── */
article[data-paper] {
max-width: 68ch;
margin-inline: auto;
}
/* ── Centred masthead ───────────────────────────────────────────────── */
article[data-paper] > header {
text-align: center;
padding-bottom: var(--space-6);
margin-bottom: var(--space-6);
border-bottom: var(--border-width) solid var(--border-subtle);
}
article[data-paper] > header h1 {
font-size: clamp(1.6rem, 4vw, 2.4rem);
font-weight: var(--font-weight-3);
letter-spacing: -0.02em;
line-height: 1.15;
margin-bottom: var(--space-4);
}
/* ── Abstract / description ─────────────────────────────────────────── */
article[data-paper] > header [data-abstract] {
font-size: var(--text-base);
color: var(--text-2);
max-width: 52ch;
margin-inline: auto;
margin-bottom: var(--space-4);
line-height: var(--leading);
font-style: italic;
}
/* ── Byline ─────────────────────────────────────────────────────────── */
article[data-paper] > header [data-byline] {
font-size: var(--text-sm);
color: var(--text-3);
font-family: var(--font-mono);
margin-bottom: var(--space-3);
}
article[data-paper] > header [data-byline] time {
font-variant-numeric: tabular-nums;
}
/* ── Tags beneath byline ────────────────────────────────────────────── */
article[data-paper] > header nav[data-role="tag-cloud"] {
justify-content: center;
margin-top: var(--space-3);
margin-bottom: 0;
}
/* ── Footer prev/next ───────────────────────────────────────────────── */
article[data-paper] > footer {
display: flex;
justify-content: space-between;
gap: var(--space-4);
margin-top: var(--space-8);
padding-top: var(--space-5);
border-top: var(--border-width) solid var(--border-subtle);
font-size: var(--text-sm);
}
article[data-paper] > footer a {
color: var(--text-2);
text-decoration: none;
}
article[data-paper] > footer a:hover {
color: var(--text);
}

View file

@ -0,0 +1,160 @@
/**
* 09-landing.css
* Landing-page specific layout and component styles.
* Loads after 08-layout so hero overrides correctly take precedence.
* Part of: Agentic Semantic Web
*/
/* [data-section] horizontal-rule sections
Usage: <section data-section> or <section data-section="demo">
*/
[data-section] {
padding-block: var(--space-8);
border-bottom: var(--border-width) solid var(--border-subtle);
}
/* [data-section-header] centered section heading
Usage: <header data-section-header> inside [data-section]
*/
[data-section-header] {
text-align: center;
margin-bottom: var(--space-6);
}
[data-section-header] h2 {
margin-bottom: var(--space-3);
}
[data-section-header] > p {
color: var(--text-2);
max-width: 50ch;
margin-inline: auto;
margin-bottom: 0;
}
/* Hero overrides extend [data-layout="hero"]
Base centering and border live in 08-layout.css; this layer tunes sizing.
*/
[data-layout="hero"] {
padding: clamp(3.5rem, 10vw, 7rem) var(--space-5) clamp(3rem, 8vw, 5.5rem);
}
[data-layout="hero"] h1 {
font-size: clamp(2.6rem, 6vw, 4.5rem);
font-weight: var(--font-weight-2);
letter-spacing: -0.025em;
line-height: 1.05;
margin-bottom: var(--space-4);
}
[data-text~="tagline"] {
font-size: clamp(1rem, 2.5vw, 1.2rem);
color: var(--text-2);
max-width: 46ch;
margin-inline: auto;
margin-bottom: var(--space-5);
line-height: var(--leading-tight);
}
/* figure[data-pane] side-by-side demo panes
Usage:
<figure data-pane="code">
<figcaption>HTML</figcaption>
<pre><code></code></pre>
</figure>
<figure data-pane="result">
<figcaption>Result</figcaption>
<div data-pane-body></div>
</figure>
*/
figure[data-pane] {
background: var(--surface-1);
border: var(--border-width) solid var(--border);
border-radius: var(--radius-md);
overflow: hidden;
display: flex;
flex-direction: column;
margin: 0;
}
figure[data-pane] > figcaption {
background: var(--surface-2);
border-bottom: var(--border-width) solid var(--border);
padding: var(--space-2) var(--space-4);
font-family: var(--font-mono);
font-size: var(--text-xs);
text-transform: uppercase;
letter-spacing: 0.1em;
color: var(--text-3);
flex-shrink: 0;
}
figure[data-pane="code"] > pre {
margin: 0;
padding: var(--space-4) var(--space-5);
background: transparent;
border: none;
font-size: 0.775rem;
line-height: 1.75;
flex: 1;
overflow-x: auto;
}
figure[data-pane="result"] > [data-pane-body] {
padding: var(--space-5);
flex: 1;
}
figure[data-pane="result"] > [data-pane-body] article {
margin: 0;
}
/* article[data-pillar] three-pillar feature cards
ASW already styles article as a card; data-pillar tunes internals.
*/
article[data-pillar] {
padding: var(--space-5);
}
article[data-pillar] h3 {
margin-bottom: var(--space-2);
}
article[data-pillar] > p {
color: var(--text-2);
font-size: var(--text-sm);
margin: 0;
}
/* [data-preview] inert mini page preview
Sits inside article[data-card="page-type"]. pointer-events: none keeps
it visually alive but non-interactive.
*/
[data-preview] {
margin-top: var(--space-4);
padding: var(--space-4);
background: var(--surface);
border: var(--border-width) solid var(--border-subtle);
border-radius: var(--radius-sm);
pointer-events: none;
overflow: hidden;
}
/* [data-agent-native] agent vocabulary section
*/
[data-agent-native] h4 {
margin-top: 0;
margin-bottom: var(--space-2);
}
[data-agent-native] pre {
font-size: var(--text-xs);
margin-top: var(--space-3);
}