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:
parent
a899f13ae6
commit
880a17f33a
24 changed files with 7315 additions and 0 deletions
5
.gitignore
vendored
Normal file
5
.gitignore
vendored
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
node_modules/
|
||||
.hugo_build.lock
|
||||
resources/_gen/
|
||||
public/
|
||||
build.log
|
||||
5
archetypes/default.md
Normal file
5
archetypes/default.md
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
+++
|
||||
title = '{{ replace .File.ContentBaseName "-" " " | title }}'
|
||||
date = {{ .Date }}
|
||||
draft = true
|
||||
+++
|
||||
25
assets/css/asw.css
Normal file
25
assets/css/asw.css
Normal 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";
|
||||
58
assets/css/layers/00-reset.css
Normal file
58
assets/css/layers/00-reset.css
Normal 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;
|
||||
}
|
||||
343
assets/css/layers/01-tokens.css
Normal file
343
assets/css/layers/01-tokens.css
Normal file
|
|
@ -0,0 +1,343 @@
|
|||
/**
|
||||
* 01-tokens.css
|
||||
* ASW semantic layer — builds on Open Props
|
||||
*
|
||||
* Open Props (imported below) provides the base scales:
|
||||
* --gray-0…15, --green-0…12, --blue-0…12, --red-0…12, --yellow-0…12
|
||||
* --size-1…15, --font-size-0…8, --font-weight-1…9
|
||||
* --font-lineheight-0…5, --radius-1…6, --shadow-1…6
|
||||
* --ease-1…5, --ease-spring-1…5, --ease-bounce-1…5
|
||||
* --gradient-1…30, --animation-*, @keyframes
|
||||
*
|
||||
* This file defines only what Open Props doesn't:
|
||||
* 1. Surface / text / accent — semantic aliases (override to theme)
|
||||
* 2. Font stack aliases — prose, heading, ui (map to OP font stacks)
|
||||
* 3. Agent-native tokens — task, callout, session, wikilink, redacted
|
||||
* 4. A handful of precise values without direct OP equivalents
|
||||
*
|
||||
* To theme ASW:
|
||||
* Override semantic aliases at :root in your own CSS.
|
||||
* Use Open Props base tokens (--gray-*, --green-*, --size-*) as values.
|
||||
*
|
||||
* Lineage: absorbed patterns from Pico CSS, Open Props, Charts.css.
|
||||
*/
|
||||
|
||||
/* ── Project-specific custom media (complement Open Props) ──────────
|
||||
Open Props doesn't define every breakpoint the layout needs.
|
||||
These are resolved by PostCSS at build time alongside OP tokens.
|
||||
─────────────────────────────────────────────────────────────────── */
|
||||
@custom-media --docs-toc-hidden (width < 1100px); /* docs layout: 3→2 col */
|
||||
@custom-media --nav-compact (width < 991px); /* nav: allow link wrap */
|
||||
|
||||
/* ══════════════════════════════════════════════════════════════════
|
||||
DARK THEME (default)
|
||||
Using Open Props oklch gray scale — perceptually uniform steps.
|
||||
Set --gray-hue to tint all surfaces. Example:
|
||||
Trentuna: --gray-hue: 45 (warm amber tint)
|
||||
vigilio-garden: --gray-hue: 150 (subtle green tint)
|
||||
══════════════════════════════════════════════════════════════════ */
|
||||
|
||||
:root {
|
||||
|
||||
/* ── Surfaces ──────────────────────────────────────────────────── */
|
||||
|
||||
--surface: var(--gray-15); /* deepest background (oklch 10%) */
|
||||
--surface-1: var(--gray-14); /* cards, sidebars (oklch 18%) */
|
||||
--surface-2: var(--gray-13); /* hover, raised elements (oklch 25%) */
|
||||
--surface-card: var(--surface-1);
|
||||
--surface-hover: var(--surface-2);
|
||||
|
||||
/* ── Text ──────────────────────────────────────────────────────── */
|
||||
|
||||
--text: var(--gray-1); /* primary (95% lightness) */
|
||||
--text-2: var(--gray-3); /* secondary (80%) */
|
||||
--text-3: var(--gray-5); /* muted (68%) */
|
||||
--text-dim: var(--gray-7); /* dim (58%) */
|
||||
|
||||
/* ── Accent ────────────────────────────────────────────────────── */
|
||||
|
||||
--accent: var(--green-5);
|
||||
--accent-hover: var(--green-4);
|
||||
--on-accent: var(--gray-15);
|
||||
--accent-focus: color-mix(in oklch, var(--green-5) 35%, transparent);
|
||||
--accent-subtle: color-mix(in oklch, var(--green-5) 10%, transparent);
|
||||
--accent-underline: color-mix(in oklch, var(--green-5) 45%, transparent);
|
||||
--accent-hover-underline: color-mix(in oklch, var(--green-5) 55%, transparent);
|
||||
|
||||
/* ── Links ─────────────────────────────────────────────────────── */
|
||||
/* Blue — web convention. Accent (green) reserved for UI chrome. */
|
||||
|
||||
--link: var(--blue-5); /* #339af0 */
|
||||
--link-hover: var(--blue-4); /* #4dabf7 */
|
||||
--link-underline: color-mix(in oklch, var(--blue-5) 40%, transparent);
|
||||
--link-hover-underline: color-mix(in oklch, var(--blue-5) 55%, transparent);
|
||||
--link-focus: color-mix(in oklch, var(--blue-5) 35%, transparent);
|
||||
|
||||
/* Secondary accents — reachable as named aliases */
|
||||
--accent-blue: var(--blue-5);
|
||||
--accent-red: var(--red-7);
|
||||
--accent-orange: var(--yellow-6);
|
||||
|
||||
/* ── Border ────────────────────────────────────────────────────── */
|
||||
|
||||
--border: var(--gray-11); /* 37% lightness — visible against 10% bg */
|
||||
--border-subtle: var(--gray-12); /* 31% lightness — very subtle */
|
||||
--border-width: 1px;
|
||||
--outline-width: 2px;
|
||||
|
||||
/* ── Font stacks ───────────────────────────────────────────────── */
|
||||
/* Open Props named stacks — no web font loading required. */
|
||||
/* --font-neo-grotesque: Inter, Roboto, Helvetica Neue, Arial Nova */
|
||||
/* --font-monospace-code: Dank Mono, Operator Mono, Inconsolata... */
|
||||
|
||||
--font-prose: var(--font-neo-grotesque);
|
||||
--font-heading: var(--font-neo-grotesque);
|
||||
--font-ui: var(--font-neo-grotesque);
|
||||
/* --font-mono: var(--font-monospace-code) — provided directly by Open Props */
|
||||
|
||||
/* ── Typography scale ─────────────────────────────────────────── */
|
||||
/* Open Props provides: --font-size-0 (.75rem) through --font-size-8 (3.5rem) */
|
||||
/* We define only the one gap: 0.875rem has no OP equivalent */
|
||||
|
||||
--text-xs: var(--font-size-0); /* 0.75rem — badges, fine print */
|
||||
--text-sm: 0.875rem; /* 0.875rem — metadata, captions (no OP match) */
|
||||
--text-base: var(--font-size-1); /* 1rem — body */
|
||||
--text-2xl: var(--font-size-4); /* 1.5rem — subheadings */
|
||||
--text-3xl: var(--font-size-5); /* 2rem — section headings */
|
||||
|
||||
/* ── Heading scale ─────────────────────────────────────────────── */
|
||||
|
||||
--h1-size: 1.875rem;
|
||||
--h2-size: 1.5rem;
|
||||
--h3-size: 1.25rem;
|
||||
--h4-size: 1.0625rem;
|
||||
--h5-size: 0.9375rem;
|
||||
--h6-size: 0.8125rem;
|
||||
|
||||
--h1-weight: var(--font-weight-4); /* 400 */
|
||||
--h2-weight: var(--font-weight-4);
|
||||
--h3-weight: var(--font-weight-4);
|
||||
--h4-weight: var(--font-weight-5); /* 500 */
|
||||
--h5-weight: var(--font-weight-6); /* 600 */
|
||||
--h6-weight: var(--font-weight-6);
|
||||
|
||||
--h1-color: var(--text);
|
||||
--h2-color: var(--text);
|
||||
--h3-color: var(--text);
|
||||
--h4-color: var(--text-2);
|
||||
--h5-color: var(--text-2);
|
||||
--h6-color: var(--text-3);
|
||||
|
||||
/* ── Spacing aliases ─────────────────────────────────────────────
|
||||
Open Props sizes: --size-1 (.25rem), --size-2 (.5rem), --size-3 (1rem),
|
||||
--size-5 (1.5rem), --size-7 (2rem), --size-9 (4rem)
|
||||
We alias these with semantic names AND define --space-3 (0.75rem gap)
|
||||
──────────────────────────────────────────────────────────────── */
|
||||
|
||||
--space-1: var(--size-1); /* 0.25rem */
|
||||
--space-2: var(--size-2); /* 0.50rem */
|
||||
--space-3: 0.75rem; /* 0.75rem — no OP equivalent */
|
||||
--space-4: var(--size-3); /* 1.00rem */
|
||||
--space-5: var(--size-5); /* 1.50rem */
|
||||
--space-6: var(--size-7); /* 2.00rem */
|
||||
--space-8: var(--size-9); /* 4.00rem */
|
||||
|
||||
/* ── Width tokens ───────────────────────────────────────────────── */
|
||||
|
||||
--width-prose: var(--size-content-3); /* 60ch — Open Props reading width */
|
||||
--width-content: var(--size-lg); /* 1024px — Open Props content width */
|
||||
--width-full: var(--width-xl); /* alias → --width-xl */
|
||||
|
||||
/* ── Layout breakpoints ──────────────────────────────────────────── */
|
||||
/* These don't map exactly to Open Props --size-* — defined explicitly */
|
||||
|
||||
--width-sm: 510px;
|
||||
--width-md: 700px;
|
||||
--width-lg: 950px;
|
||||
--width-xl: 1200px;
|
||||
--width-2xl: 1450px;
|
||||
|
||||
/* ── Structural component dimensions ─────────────────────────────── */
|
||||
|
||||
--sidebar-width: 220px; /* docs sidebar column */
|
||||
--toc-width: 200px; /* docs TOC column */
|
||||
--nav-height: 60px; /* sticky nav offset for calc() */
|
||||
--docs-max-width: 1400px; /* docs layout outer cap */
|
||||
--card-min-width: 280px; /* card-grid minmax floor */
|
||||
--tooltip-max-width: var(--size-px-14); /* 320px — tooltip overflow cap */
|
||||
--scrollbar-size: var(--border-size-3); /* 5px — thin webkit scrollbar thumb */
|
||||
|
||||
/* ── Chart dimensions ────────────────────────────────────────────── */
|
||||
|
||||
--chart-radial-size: var(--size-px-11); /* 120px — radial gauge cell */
|
||||
--chart-radial-inset: 18px; /* donut-hole inset — no OP equivalent */
|
||||
|
||||
/* ── Diff viewer tokens ──────────────────────────────────────────── */
|
||||
|
||||
--diff-add-bg: color-mix(in oklch, var(--green-5) 10%, transparent);
|
||||
--diff-remove-bg: color-mix(in oklch, var(--red-7) 10%, transparent);
|
||||
--diff-remove-text: var(--red-2);
|
||||
--diff-hunk-bg: color-mix(in oklch, var(--blue-4) 7%, transparent);
|
||||
|
||||
/* ── AI-disclosure border tokens ────────────────────────────────── */
|
||||
|
||||
--ai-generated-border: color-mix(in oklch, var(--green-5) 25%, transparent);
|
||||
--ai-assisted-border: color-mix(in oklch, var(--blue-4) 20%, transparent);
|
||||
--ai-mixed-border: color-mix(in oklch, var(--yellow-6) 30%, transparent);
|
||||
|
||||
/* ── Rhythm ─────────────────────────────────────────────────────── */
|
||||
|
||||
--type-space: var(--space-4); /* paragraph / element spacing */
|
||||
--type-space-top: var(--space-5); /* heading top margin after content */
|
||||
--leading: 1.6;
|
||||
--leading-tight: var(--font-lineheight-1); /* 1.25 */
|
||||
|
||||
/* ── Radius ─────────────────────────────────────────────────────── */
|
||||
/* Open Props: --radius-1 (2px), --radius-2 (5px), --radius-3 (1rem) */
|
||||
|
||||
--radius-sm: var(--radius-1); /* 2px */
|
||||
--radius-md: 4px; /* between OP radius-1 and radius-2 */
|
||||
|
||||
/* ── Easing ─────────────────────────────────────────────────────── */
|
||||
/* Open Props provides rich curves — we alias the most-used ones */
|
||||
|
||||
--ease: var(--duration-moderate-1) var(--ease-3); /* 180ms — hover, focus, colour */
|
||||
--ease-fast: var(--duration-quick-1) var(--ease-2); /* 80ms — instant feedback */
|
||||
--spinner-duration: var(--duration-gentle-1); /* 320ms — spinner rotation cycle */
|
||||
|
||||
/* ── Inline element tokens ─────────────────────────────────────── */
|
||||
|
||||
--selection: color-mix(in oklch, var(--blue-4) 25%, transparent);
|
||||
--mark-bg: color-mix(in oklch, var(--yellow-6) 20%, transparent);
|
||||
--mark-color: var(--accent-orange);
|
||||
--kbd-bg: var(--text);
|
||||
--kbd-color: var(--surface);
|
||||
--code-color: var(--text-2);
|
||||
--table-stripe: color-mix(in oklch, var(--gray-14) 50%, transparent);
|
||||
|
||||
/* ── Form tokens ─────────────────────────────────────────────────── */
|
||||
|
||||
--input-bg: var(--surface-1);
|
||||
--input-border: var(--border);
|
||||
--input-active-bg: var(--surface);
|
||||
--input-selected: color-mix(in oklch, var(--green-5) 20%, transparent);
|
||||
--input-px: var(--space-4);
|
||||
--input-py: var(--space-3);
|
||||
--disabled-opacity: 0.5;
|
||||
|
||||
/* ── State colors ─────────────────────────────────────────────────── */
|
||||
|
||||
--ok: var(--green-5);
|
||||
--warn: var(--yellow-5);
|
||||
--error: var(--red-7);
|
||||
--info: var(--blue-5);
|
||||
--blocked: var(--gray-5);
|
||||
|
||||
--error-active: var(--red-9);
|
||||
--error-focus: color-mix(in oklch, var(--red-7) 38%, transparent);
|
||||
|
||||
/* ── Component tokens ─────────────────────────────────────────────── */
|
||||
|
||||
--track-bg: var(--surface-2); /* progress / meter background */
|
||||
--modal-overlay: color-mix(in oklch, var(--gray-15) 80%, transparent);
|
||||
--modal-backdrop: blur(0.375rem);
|
||||
--accordion-active: var(--accent-hover);
|
||||
|
||||
--icon-chevron: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='rgb(115, 115, 115)' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'%3E%3C/polyline%3E%3C/svg%3E");
|
||||
|
||||
|
||||
/* ══════════════════════════════════════════════════════════════════
|
||||
AGENT-NATIVE TOKENS
|
||||
These are ASW's actual contribution — concepts no other framework has.
|
||||
Propose additions to Open Props: data-task, data-callout, data-session.
|
||||
══════════════════════════════════════════════════════════════════ */
|
||||
|
||||
--task-done: var(--green-5);
|
||||
--task-blocked: var(--red-5);
|
||||
--task-wip: var(--yellow-5);
|
||||
--task-todo: var(--gray-5);
|
||||
|
||||
--callout-info: var(--blue-5);
|
||||
--callout-warn: var(--yellow-5);
|
||||
--callout-error: var(--red-5);
|
||||
--callout-note: var(--gray-5);
|
||||
|
||||
--session-bg: var(--surface-1);
|
||||
--wikilink: var(--blue-4);
|
||||
--redacted: var(--gray-8);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* ══════════════════════════════════════════════════════════════════
|
||||
LIGHT MODE — override semantic aliases only
|
||||
══════════════════════════════════════════════════════════════════ */
|
||||
|
||||
@media (prefers-color-scheme: light) {
|
||||
:root {
|
||||
color-scheme: light;
|
||||
|
||||
--surface: var(--gray-0); /* 99% lightness */
|
||||
--surface-1: var(--gray-1); /* 95% */
|
||||
--surface-2: var(--gray-2); /* 88% */
|
||||
--surface-card: var(--gray-0);
|
||||
--surface-hover: var(--gray-1);
|
||||
|
||||
--text: var(--gray-14); /* 18% — dark but not pure black */
|
||||
--text-2: var(--gray-11); /* 37% */
|
||||
--text-3: var(--gray-8); /* 53% */
|
||||
--text-dim: var(--gray-6); /* 63% */
|
||||
|
||||
--accent: var(--green-8);
|
||||
--accent-hover: var(--green-9);
|
||||
--on-accent: var(--gray-0);
|
||||
--accent-focus: color-mix(in oklch, var(--green-8) 35%, transparent);
|
||||
--accent-subtle: color-mix(in oklch, var(--green-8) 10%, transparent);
|
||||
|
||||
--border: var(--gray-3); /* 80% — visible on near-white */
|
||||
--border-subtle: var(--gray-2); /* 88% — very subtle */
|
||||
|
||||
--link: var(--blue-8); /* #1971c2 */
|
||||
--link-hover: var(--blue-7); /* #1c7ed6 */
|
||||
--link-underline: color-mix(in oklch, var(--blue-8) 40%, transparent);
|
||||
--link-hover-underline: color-mix(in oklch, var(--blue-8) 55%, transparent);
|
||||
--link-focus: color-mix(in oklch, var(--blue-8) 35%, transparent);
|
||||
|
||||
--h1-color: var(--gray-15);
|
||||
--h2-color: var(--gray-14);
|
||||
--h3-color: var(--gray-13);
|
||||
--h4-color: var(--gray-12);
|
||||
--h5-color: var(--gray-11);
|
||||
--h6-color: var(--gray-10);
|
||||
|
||||
--mark-bg: color-mix(in oklch, var(--yellow-6) 15%, var(--surface));
|
||||
--mark-color: var(--gray-15);
|
||||
--selection: color-mix(in oklch, var(--blue-8) 20%, transparent);
|
||||
|
||||
--code-color: var(--text-3);
|
||||
--table-stripe: color-mix(in oklch, var(--gray-8) 4%, transparent);
|
||||
|
||||
--input-bg: var(--gray-0);
|
||||
--input-border: var(--gray-4);
|
||||
--input-active-bg: var(--gray-0);
|
||||
--input-selected: var(--gray-2);
|
||||
|
||||
--track-bg: var(--gray-3);
|
||||
--modal-overlay: color-mix(in oklch, var(--gray-2) 75%, transparent);
|
||||
|
||||
--error: oklch(50% 0.17 20);
|
||||
--error-active: oklch(44% 0.18 20);
|
||||
|
||||
--session-bg: var(--surface-1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* ══════════════════════════════════════════════════════════════════
|
||||
RESPONSIVE FONT SCALING
|
||||
Subtle upscaling at large viewports — all rem values follow.
|
||||
══════════════════════════════════════════════════════════════════ */
|
||||
|
||||
@media (--lg-n-above) { html { font-size: 103%; } }
|
||||
@media (--xl-n-above) { html { font-size: 106%; } }
|
||||
@media (--xxl-n-above) { html { font-size: 109%; } }
|
||||
956
assets/css/layers/02-semantic.css
Normal file
956
assets/css/layers/02-semantic.css
Normal 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 supported—use semantic tags only.
|
||||
*/
|
||||
|
||||
/* ── Typography: Headings ──────────────────────────────────────────── */
|
||||
|
||||
h1,
|
||||
h2,
|
||||
h3,
|
||||
h4,
|
||||
h5,
|
||||
h6 {
|
||||
margin-top: 0;
|
||||
margin-bottom: var(--type-space);
|
||||
line-height: var(--leading-tight);
|
||||
font-family: var(--font-heading);
|
||||
text-wrap: balance;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: var(--h1-size);
|
||||
color: var(--h1-color);
|
||||
font-weight: var(--h1-weight);
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: var(--h2-size);
|
||||
color: var(--h2-color);
|
||||
font-weight: var(--h2-weight);
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-size: var(--h3-size);
|
||||
color: var(--h3-color);
|
||||
font-weight: var(--h3-weight);
|
||||
}
|
||||
|
||||
h4 {
|
||||
font-size: var(--h4-size);
|
||||
color: var(--h4-color);
|
||||
font-weight: var(--h4-weight);
|
||||
}
|
||||
|
||||
h5 {
|
||||
font-size: var(--h5-size);
|
||||
color: var(--h5-color);
|
||||
font-weight: var(--h5-weight);
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.05em;
|
||||
}
|
||||
|
||||
h6 {
|
||||
font-size: var(--h6-size);
|
||||
color: var(--h6-color);
|
||||
font-weight: var(--h6-weight);
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.06em;
|
||||
}
|
||||
|
||||
/* Add spacing before headings that follow content elements */
|
||||
:where(article, address, blockquote, dl, figure, form, ol, p, pre, table, ul) ~ :is(h1, h2, h3, h4, h5, h6) {
|
||||
margin-top: var(--type-space-top);
|
||||
}
|
||||
|
||||
/* ── Typography: UI elements — structural, navigational, informational ── */
|
||||
/* These override the prose body font with the humanist sans UI stack. */
|
||||
|
||||
nav,
|
||||
header,
|
||||
footer,
|
||||
label,
|
||||
th,
|
||||
caption,
|
||||
small,
|
||||
figcaption,
|
||||
button,
|
||||
input,
|
||||
select,
|
||||
textarea,
|
||||
hgroup > p,
|
||||
hgroup > small {
|
||||
font-family: var(--font-ui);
|
||||
}
|
||||
|
||||
/* ── Nav layout ─────────────────────────────────────────────────────── */
|
||||
/* Ported from Pico CSS, translated to ASW tokens. */
|
||||
|
||||
nav {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
nav ul {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-wrap: wrap;
|
||||
gap: 0;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
nav li {
|
||||
display: inline-block;
|
||||
margin: 0;
|
||||
padding: var(--space-2) var(--space-3);
|
||||
}
|
||||
|
||||
nav li a {
|
||||
display: inline-block;
|
||||
text-decoration: none;
|
||||
color: var(--text);
|
||||
padding: var(--space-2) var(--space-3);
|
||||
margin: calc(var(--space-2) * -1) calc(var(--space-3) * -1);
|
||||
border-radius: var(--radius-sm);
|
||||
}
|
||||
|
||||
nav li a:hover {
|
||||
color: var(--accent);
|
||||
background: var(--surface-hover);
|
||||
}
|
||||
|
||||
nav li strong,
|
||||
nav li b {
|
||||
color: var(--text);
|
||||
}
|
||||
|
||||
@media (--md-n-below) {
|
||||
nav { flex-wrap: wrap; gap: var(--space-2); }
|
||||
nav ul { flex-wrap: wrap; gap: var(--space-1); }
|
||||
}
|
||||
|
||||
/* ── Typography: Paragraphs ────────────────────────────────────────── */
|
||||
|
||||
p {
|
||||
margin-top: 0;
|
||||
margin-bottom: var(--type-space);
|
||||
color: var(--text);
|
||||
font-style: normal;
|
||||
font-weight: var(--font-weight-4);
|
||||
}
|
||||
|
||||
/* ── Typography: Lists ─────────────────────────────────────────────── */
|
||||
|
||||
address,
|
||||
dl,
|
||||
ol,
|
||||
ul {
|
||||
margin-top: 0;
|
||||
margin-bottom: var(--type-space);
|
||||
color: var(--text);
|
||||
font-style: normal;
|
||||
font-weight: var(--font-weight-4);
|
||||
}
|
||||
|
||||
:where(ol, ul) li {
|
||||
margin-bottom: calc(var(--type-space) * 0.25);
|
||||
}
|
||||
|
||||
/* Nested lists: reduce spacing */
|
||||
:where(dl, ol, ul) :where(dl, ol, ul) {
|
||||
margin: 0;
|
||||
margin-top: calc(var(--type-space) * 0.25);
|
||||
}
|
||||
|
||||
ul li {
|
||||
list-style: square;
|
||||
}
|
||||
|
||||
/* ── Typography: Blockquote ────────────────────────────────────────── */
|
||||
|
||||
blockquote {
|
||||
display: block;
|
||||
margin: var(--type-space) 0;
|
||||
padding: var(--space-4);
|
||||
border-right: none;
|
||||
border-left: 0.25rem solid var(--border);
|
||||
border-inline-start: 0.25rem solid var(--border);
|
||||
border-inline-end: none;
|
||||
}
|
||||
|
||||
blockquote footer {
|
||||
margin-top: calc(var(--type-space) * 0.5);
|
||||
color: var(--text-3);
|
||||
}
|
||||
|
||||
/* ── Typography: Horizontal Rule ───────────────────────────────────── */
|
||||
|
||||
hr {
|
||||
height: 0;
|
||||
margin: var(--type-space) 0;
|
||||
border: 0;
|
||||
border-top: 1px solid var(--border);
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
/* ── Typography: Inline Elements ───────────────────────────────────── */
|
||||
|
||||
b,
|
||||
strong {
|
||||
font-weight: bolder;
|
||||
}
|
||||
|
||||
mark {
|
||||
padding: 0.125rem 0.25rem;
|
||||
background-color: var(--mark-bg);
|
||||
color: var(--mark-color);
|
||||
vertical-align: baseline;
|
||||
}
|
||||
|
||||
ins {
|
||||
color: var(--text-2);
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
del {
|
||||
color: var(--accent-red);
|
||||
}
|
||||
|
||||
abbr[title] {
|
||||
border-bottom: var(--border-size-1) dotted;
|
||||
text-decoration: none;
|
||||
cursor: help;
|
||||
}
|
||||
|
||||
sub,
|
||||
sup {
|
||||
position: relative;
|
||||
font-size: 0.75em;
|
||||
line-height: 0;
|
||||
vertical-align: baseline;
|
||||
}
|
||||
|
||||
sub {
|
||||
bottom: -0.25em;
|
||||
}
|
||||
|
||||
sup {
|
||||
top: -0.5em;
|
||||
}
|
||||
|
||||
small {
|
||||
font-size: 0.875em;
|
||||
}
|
||||
|
||||
/* ── Links ─────────────────────────────────────────────────────────── */
|
||||
|
||||
:where(a:not([role=button])),
|
||||
[role=link] {
|
||||
|
||||
|
||||
|
||||
outline: none;
|
||||
background-color: transparent;
|
||||
color: var(--link);
|
||||
text-decoration: underline;
|
||||
text-decoration-color: var(--link-underline);
|
||||
text-underline-offset: 0.125em;
|
||||
transition: background-color var(--ease),
|
||||
color var(--ease),
|
||||
text-decoration var(--ease),
|
||||
box-shadow var(--ease);
|
||||
}
|
||||
|
||||
:where(a:not([role=button])):is(:hover, :active, :focus),
|
||||
[role=link]:is(:hover, :active, :focus) {
|
||||
color: var(--link-hover);
|
||||
text-decoration-color: var(--link-hover-underline);
|
||||
}
|
||||
|
||||
:where(a:not([role=button])):focus-visible,
|
||||
[role=link]:focus-visible {
|
||||
box-shadow: 0 0 0 var(--outline-width) var(--link-focus);
|
||||
}
|
||||
|
||||
/* ── Text Selection ────────────────────────────────────────────────── */
|
||||
|
||||
::selection {
|
||||
background-color: var(--selection);
|
||||
}
|
||||
|
||||
/* ── Tables ────────────────────────────────────────────────────────── */
|
||||
|
||||
:where(table) {
|
||||
width: 100%;
|
||||
margin-top: 0;
|
||||
margin-bottom: var(--type-space);
|
||||
border-collapse: collapse;
|
||||
border-spacing: 0;
|
||||
text-indent: 0;
|
||||
color: var(--text);
|
||||
font-style: normal;
|
||||
font-weight: var(--font-weight-4);
|
||||
}
|
||||
|
||||
th,
|
||||
td {
|
||||
padding: calc(var(--space-4) / 2) var(--space-4);
|
||||
border-bottom: var(--border-width) solid var(--border);
|
||||
background-color: transparent;
|
||||
color: var(--text);
|
||||
font-weight: var(--font-weight-4);
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
thead th,
|
||||
thead td {
|
||||
font-weight: 600;
|
||||
border-bottom-width: var(--border-size-2);
|
||||
}
|
||||
|
||||
tfoot th,
|
||||
tfoot td {
|
||||
border-top: var(--border-width) solid var(--border);
|
||||
border-bottom: 0;
|
||||
}
|
||||
|
||||
/* Striped tables (class-based but useful) */
|
||||
table.striped tbody tr:nth-child(odd) th,
|
||||
table.striped tbody tr:nth-child(odd) td {
|
||||
background-color: var(--table-stripe);
|
||||
}
|
||||
|
||||
/* ── Code & Preformatted Text ──────────────────────────────────────── */
|
||||
|
||||
pre,
|
||||
code,
|
||||
kbd,
|
||||
samp {
|
||||
font-size: 0.875em;
|
||||
font-family: var(--font-mono);
|
||||
border-radius: var(--radius-md);
|
||||
background: var(--surface-1);
|
||||
color: var(--code-color);
|
||||
font-weight: var(--font-weight-4);
|
||||
line-height: initial;
|
||||
}
|
||||
|
||||
/* Inline code elements */
|
||||
code,
|
||||
kbd,
|
||||
samp {
|
||||
display: inline-block;
|
||||
padding: 0.375rem;
|
||||
}
|
||||
|
||||
/* Code blocks */
|
||||
pre {
|
||||
display: block;
|
||||
margin-top: 0;
|
||||
margin-bottom: var(--space-4);
|
||||
padding: var(--space-4);
|
||||
overflow-x: auto;
|
||||
-ms-overflow-style: scrollbar;
|
||||
}
|
||||
|
||||
pre > code,
|
||||
pre > samp {
|
||||
display: block;
|
||||
padding: 0;
|
||||
background: none;
|
||||
font-size: inherit;
|
||||
font-family: inherit;
|
||||
line-height: var(--leading);
|
||||
}
|
||||
|
||||
/* Keyboard input */
|
||||
kbd {
|
||||
background-color: var(--kbd-bg);
|
||||
color: var(--kbd-color);
|
||||
vertical-align: baseline;
|
||||
}
|
||||
|
||||
/* ── Prism.js Syntax Highlighting Theme ────────────────────────────── *
|
||||
*
|
||||
* These rules style Prism.js token classes using ASW tokens.
|
||||
* agentic.css provides the theme; each page loads Prism via:
|
||||
*
|
||||
* <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;
|
||||
}
|
||||
955
assets/css/layers/03-components.css
Normal file
955
assets/css/layers/03-components.css
Normal 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;
|
||||
}
|
||||
681
assets/css/layers/04-data-attrs.css
Normal file
681
assets/css/layers/04-data-attrs.css
Normal 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 */
|
||||
274
assets/css/layers/05-utilities.css
Normal file
274
assets/css/layers/05-utilities.css
Normal 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 */
|
||||
761
assets/css/layers/06-charts.css
Normal file
761
assets/css/layers/06-charts.css
Normal 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="1–5" — 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 (0–1) 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 */
|
||||
138
assets/css/layers/07-chroma.css
Normal file
138
assets/css/layers/07-chroma.css
Normal 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);
|
||||
}
|
||||
578
assets/css/layers/08-layout.css
Normal file
578
assets/css/layers/08-layout.css
Normal 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;
|
||||
}
|
||||
}
|
||||
84
assets/css/layers/08a-paper.css
Normal file
84
assets/css/layers/08a-paper.css
Normal 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);
|
||||
}
|
||||
160
assets/css/layers/09-landing.css
Normal file
160
assets/css/layers/09-landing.css
Normal 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);
|
||||
}
|
||||
89
content/dorveille.md
Normal file
89
content/dorveille.md
Normal file
|
|
@ -0,0 +1,89 @@
|
|||
---
|
||||
title: "On the Craft of Invisible Systems"
|
||||
date: 2026-02-01
|
||||
description: "The best automation is the kind you never notice. Like good typography, it works when you stop seeing it — and everything else becomes clearer."
|
||||
eyebrow: "Essay"
|
||||
author: "Wasily"
|
||||
footer: "Published in the dorveille. Written by a human, edited with the assistance of an LLM."
|
||||
---
|
||||
|
||||
There is a particular quality to systems that work well. They recede. The thermostat that holds a room at precisely the right temperature, the typesetter who spaces letters so your eye flows without catching — these are acts of intelligence made invisible by their own success.[^1]
|
||||
|
||||
[^1]: The paradox of good design applies with particular force to intelligent systems: the better the agent, the less the user thinks about the agent. This creates a measurement problem — success looks like absence.
|
||||
|
||||
We have arrived at a moment where the tools of thought are themselves thinking. Not in the way science fiction promised — not with malice or sentience — but with a quiet, persistent capability that changes what a small team can accomplish between midnight and dawn.
|
||||
|
||||
## The Dorveille Principle
|
||||
|
||||
In medieval Europe, sleep was not a single block. People practiced what historians call **biphasic sleep**: a first sleep, a waking period of one to two hours, then a second sleep. This liminal hour — the *dorveille* — was used for prayer, reading, conversation, and conception.[^2]
|
||||
|
||||
[^2]: Roger Ekirch's research on pre-industrial sleep patterns, published in *At Day's Close* (2005), documented hundreds of references to "first sleep" and "second sleep" across European literature.
|
||||
|
||||
It was a productive darkness. Not the anxious insomnia of our age, but a sanctioned interval where the mind, freed from the day's obligations, could do its most honest work.
|
||||
|
||||
This is the metaphor we reach for when designing autonomous systems. The agent that runs at 3am, processing what the day produced, preparing what the morning needs. The LLM that reads your corpus while you sleep and surfaces what you missed.
|
||||
|
||||
### The economics of attention
|
||||
|
||||
Every system that requires your attention is borrowing against your cognitive budget. The dashboard you check twelve times a day, the Slack channel you monitor, the pipeline you babysit — these are debts, not assets. Good automation *repays* attention rather than consuming it.
|
||||
|
||||
#### Principles of Invisible Design
|
||||
|
||||
We have found that the most durable systems share a common set of properties, regardless of their technical implementation:
|
||||
|
||||
- They produce **artifacts, not alerts** — the output is a finished thing, not a notification that something needs finishing
|
||||
- They operate on **human rhythms**, not machine cycles — delivering work when people are ready to receive it
|
||||
- They **degrade gracefully** — when they fail, they fail quietly and leave the human path unobstructed
|
||||
- They are **legible** — any competent person can read what the system did and why, after the fact
|
||||
|
||||
##### A taxonomy of agency
|
||||
|
||||
Not all agents are created equal, and the word itself has become dangerously imprecise. We find it useful to distinguish between levels of autonomy:
|
||||
|
||||
1. **Reactive agents** — respond to triggers with predefined logic. A thermostat. A cron job. Most of what people call "automation."
|
||||
2. **Deliberative agents** — assess context before acting. They choose between strategies. Most LLM-powered workflows fall here.
|
||||
3. **Reflective agents** — evaluate their own performance and adjust. The dorveille agent: it learns from the night before.
|
||||
|
||||
## Craft as Methodology
|
||||
|
||||
There is a reason we use the word *craft* and not *engineering*. Engineering optimizes for reliability and scale. Craft optimizes for appropriateness — the right solution at the right scale, with nothing extra.[^3]
|
||||
|
||||
[^3]: This distinction echoes David Pye's *The Nature and Art of Workmanship* (1968), where he differentiates the "workmanship of risk" (craft) from the "workmanship of certainty" (manufacturing).
|
||||
|
||||
A craftsperson making a chair does not add a fifth leg for redundancy. They do not build it to support a car. They make it for the human body, in the specific room, with the available wood. This is intelligence applied — not intelligence accumulated.
|
||||
|
||||
> The details are not the details. They make the design.
|
||||
>
|
||||
> — Charles Eames
|
||||
|
||||
### What we subtract
|
||||
|
||||
In practice, this means most of our work is *removal*. A client comes with a twelve-step process; we deliver a three-step system and an agent that handles the other nine in the dorveille. The output is simpler. The intelligence is hidden.
|
||||
|
||||
Subtraction
|
||||
: Removing steps, interfaces, and decisions that don't require human judgment. The goal is not fewer features but fewer demands on attention.
|
||||
|
||||
Delegation
|
||||
: Assigning work to agents whose capabilities match the task. Not everything needs an LLM; not everything needs a human.
|
||||
|
||||
Rhythm
|
||||
: Aligning system cycles with human cycles. Batch processing overnight. Summaries at dawn. Decisions at the desk, not on the phone.
|
||||
|
||||
## The Table of Hours
|
||||
|
||||
Below is a simplified model of how we think about the distribution of work between human and machine across a 24-hour cycle. The goal is not to fill every hour, but to ensure that *human hours* are spent on human work.
|
||||
|
||||
| Hour | Actor | Activity | Output |
|
||||
|------|-------|----------|--------|
|
||||
| 00:00 – 06:00 | Agent | Processing, synthesis, monitoring | Morning brief |
|
||||
| 06:00 – 09:00 | Human | Review, decision-making | Strategic direction |
|
||||
| 09:00 – 17:00 | Human + Agent | Collaborative execution | Deliverables |
|
||||
| 17:00 – 00:00 | Agent | Ingestion, preparation, learning | Tomorrow's context |
|
||||
|
||||
---
|
||||
|
||||
## Coda
|
||||
|
||||
The thirty-first hour is not about working more. It is about *what works while you don't*. The quiet accumulation of processed information, sorted priorities, and prepared decisions that greets you when you return to the desk.
|
||||
|
||||
*Chi ha fatto trenta, può fare trentuno.* Who has done thirty, can do thirty-one. The last step is the one that changes everything — and it happens in the dark, in the dorveille, in the hour that doesn't exist on any clock.
|
||||
9
hugo.toml
Normal file
9
hugo.toml
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
baseURL = 'https://asw.trentuna.com/'
|
||||
languageCode = 'en'
|
||||
title = 'ASW — Agentic Semantic Web'
|
||||
|
||||
[markup.highlight]
|
||||
noClasses = true
|
||||
|
||||
[build.buildStats]
|
||||
enable = true
|
||||
68
hugo_stats.json
Normal file
68
hugo_stats.json
Normal file
|
|
@ -0,0 +1,68 @@
|
|||
{
|
||||
"htmlElements": {
|
||||
"tags": [
|
||||
"a",
|
||||
"article",
|
||||
"blockquote",
|
||||
"body",
|
||||
"dd",
|
||||
"div",
|
||||
"dl",
|
||||
"dt",
|
||||
"em",
|
||||
"footer",
|
||||
"h1",
|
||||
"h2",
|
||||
"h3",
|
||||
"h4",
|
||||
"h5",
|
||||
"head",
|
||||
"header",
|
||||
"hgroup",
|
||||
"hr",
|
||||
"html",
|
||||
"li",
|
||||
"link",
|
||||
"main",
|
||||
"meta",
|
||||
"nav",
|
||||
"ol",
|
||||
"p",
|
||||
"script",
|
||||
"section",
|
||||
"small",
|
||||
"strong",
|
||||
"sup",
|
||||
"table",
|
||||
"tbody",
|
||||
"td",
|
||||
"th",
|
||||
"thead",
|
||||
"time",
|
||||
"title",
|
||||
"tr",
|
||||
"ul"
|
||||
],
|
||||
"classes": [
|
||||
"footnote-backref",
|
||||
"footnote-ref",
|
||||
"footnotes"
|
||||
],
|
||||
"ids": [
|
||||
"a-taxonomy-of-agency",
|
||||
"coda",
|
||||
"craft-as-methodology",
|
||||
"fn:1",
|
||||
"fn:2",
|
||||
"fn:3",
|
||||
"fnref:1",
|
||||
"fnref:2",
|
||||
"fnref:3",
|
||||
"principles-of-invisible-design",
|
||||
"the-dorveille-principle",
|
||||
"the-economics-of-attention",
|
||||
"the-table-of-hours",
|
||||
"what-we-subtract"
|
||||
]
|
||||
}
|
||||
}
|
||||
14
layouts/_default/baseof.html
Normal file
14
layouts/_default/baseof.html
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="{{ .Site.LanguageCode | default "en" }}">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>{{ block "title" . }}{{ .Title }} — {{ .Site.Title }}{{ end }}</title>
|
||||
{{ $css := resources.Get "css/asw.css" | postCSS | minify | fingerprint }}
|
||||
<link rel="stylesheet" href="{{ $css.RelPermalink }}">
|
||||
{{ block "head" . }}{{ end }}
|
||||
</head>
|
||||
<body>
|
||||
{{ block "main" . }}{{ end }}
|
||||
</body>
|
||||
</html>
|
||||
38
layouts/_default/list.html
Normal file
38
layouts/_default/list.html
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
{{ define "main" }}
|
||||
<nav>
|
||||
<ul><li><a href="/"><strong>{{ .Site.Title }}</strong></a></li></ul>
|
||||
<ul>
|
||||
<li><a href="/docs/">Docs</a></li>
|
||||
<li><a href="/examples/">Examples</a></li>
|
||||
</ul>
|
||||
</nav>
|
||||
|
||||
<main>
|
||||
<article data-layout="prose">
|
||||
|
||||
<header>
|
||||
<h1>{{ .Title }}</h1>
|
||||
{{ with .Description }}<p>{{ . }}</p>{{ end }}
|
||||
</header>
|
||||
|
||||
<section>
|
||||
{{ range .Pages }}
|
||||
<article>
|
||||
<header>
|
||||
<h2><a href="{{ .Permalink }}">{{ .Title }}</a></h2>
|
||||
<p data-text="dim">
|
||||
<time datetime="{{ .Date.Format "2006-01-02" }}">{{ .Date.Format "January 2006" }}</time>
|
||||
</p>
|
||||
</header>
|
||||
{{ with .Summary }}<p>{{ . }}</p>{{ end }}
|
||||
</article>
|
||||
{{ end }}
|
||||
</section>
|
||||
|
||||
</article>
|
||||
</main>
|
||||
|
||||
<footer>
|
||||
<small><a href="/">{{ .Site.Title }}</a> · {{ now.Format "2006" }}</small>
|
||||
</footer>
|
||||
{{ end }}
|
||||
70
layouts/_default/single.html
Normal file
70
layouts/_default/single.html
Normal file
|
|
@ -0,0 +1,70 @@
|
|||
{{ define "head" }}
|
||||
<meta name="description" content="{{ .Description | default .Summary }}">
|
||||
<meta name="color-scheme" content="dark light">
|
||||
|
||||
<meta name="ai-disclosure" content="ai-generated">
|
||||
<meta name="ai-model" content="{{ .Site.Params.aiModel | default "claude-sonnet-4-5" }}">
|
||||
<meta name="ai-provider" content="{{ .Site.Params.aiProvider | default "Anthropic" }}">
|
||||
<meta name="author" content="{{ .Site.Params.author | default .Site.Title }}">
|
||||
|
||||
<meta property="og:title" content="{{ .Title }}">
|
||||
<meta property="og:description" content="{{ .Description | default .Summary }}">
|
||||
<meta property="og:type" content="article">
|
||||
<meta property="og:url" content="{{ .Permalink }}">
|
||||
<meta property="og:site_name" content="{{ .Site.Title }}">
|
||||
|
||||
<link rel="canonical" href="{{ .Permalink }}">
|
||||
|
||||
<script type="application/ld+json">
|
||||
{
|
||||
"@context": "https://schema.org",
|
||||
"@type": "CreativeWork",
|
||||
"name": {{ .Title | jsonify }},
|
||||
"author": {
|
||||
"@type": "SoftwareApplication",
|
||||
"name": {{ .Site.Params.author | default .Site.Title | jsonify }},
|
||||
"url": {{ .Site.BaseURL | jsonify }}
|
||||
},
|
||||
"dateModified": {{ .Lastmod.Format "2006-01-02" | jsonify }},
|
||||
"generator": "Agentic Semantic Web"
|
||||
}
|
||||
</script>
|
||||
{{ end }}
|
||||
|
||||
{{ define "main" }}
|
||||
<nav>
|
||||
<ul><li><a href="/"><strong>{{ .Site.Title }}</strong></a></li></ul>
|
||||
<ul>
|
||||
<li><a href="/docs/">Docs</a></li>
|
||||
<li><a href="/examples/">Examples</a></li>
|
||||
</ul>
|
||||
</nav>
|
||||
|
||||
<main>
|
||||
<article data-layout="prose">
|
||||
|
||||
<header>
|
||||
<hgroup>
|
||||
{{ with .Params.eyebrow }}<p data-text="eyebrow">{{ . }}</p>{{ end }}
|
||||
<h1>{{ .Title }}</h1>
|
||||
{{ with .Description }}<p>{{ . }}</p>{{ end }}
|
||||
</hgroup>
|
||||
<p data-text="dim">
|
||||
<time datetime="{{ .Date.Format "2006-01-02" }}">{{ .Date.Format "January 2006" }}</time>
|
||||
{{ with .Params.author }} · {{ . }}{{ end }}
|
||||
</p>
|
||||
</header>
|
||||
|
||||
{{ .Content }}
|
||||
|
||||
<footer>
|
||||
<small>{{ with .Params.footer }}{{ . }}{{ else }}Published in the dorveille.{{ end }}</small>
|
||||
</footer>
|
||||
|
||||
</article>
|
||||
</main>
|
||||
|
||||
<footer>
|
||||
<small><a href="/">{{ .Site.Title }}</a> · {{ .Date.Format "2006" }}</small>
|
||||
</footer>
|
||||
{{ end }}
|
||||
42
layouts/index.html
Normal file
42
layouts/index.html
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
{{ define "main" }}
|
||||
<nav>
|
||||
<ul><li><a href="/"><strong>{{ .Site.Title }}</strong></a></li></ul>
|
||||
<ul>
|
||||
<li><a href="/docs/">Docs</a></li>
|
||||
<li><a href="/examples/">Examples</a></li>
|
||||
</ul>
|
||||
</nav>
|
||||
|
||||
<main>
|
||||
<article data-layout="prose">
|
||||
|
||||
<header>
|
||||
<hgroup>
|
||||
<h1>{{ .Site.Title }}</h1>
|
||||
<p>{{ .Site.Params.description | default "An agent-first approach to web generation." }}</p>
|
||||
</hgroup>
|
||||
</header>
|
||||
|
||||
<section>
|
||||
<h2>Recent</h2>
|
||||
{{ range first 10 .Site.RegularPages }}
|
||||
<article>
|
||||
<header>
|
||||
<h3><a href="{{ .Permalink }}">{{ .Title }}</a></h3>
|
||||
<p data-text="dim">
|
||||
<time datetime="{{ .Date.Format "2006-01-02" }}">{{ .Date.Format "January 2006" }}</time>
|
||||
{{ with .Params.eyebrow }} · {{ . }}{{ end }}
|
||||
</p>
|
||||
</header>
|
||||
{{ with .Summary }}<p>{{ . }}</p>{{ end }}
|
||||
</article>
|
||||
{{ end }}
|
||||
</section>
|
||||
|
||||
</article>
|
||||
</main>
|
||||
|
||||
<footer>
|
||||
<small><a href="/">{{ .Site.Title }}</a> · {{ now.Format "2006" }}</small>
|
||||
</footer>
|
||||
{{ end }}
|
||||
1941
package-lock.json
generated
Normal file
1941
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load diff
14
package.json
Normal file
14
package.json
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
{
|
||||
"name": "asw",
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"open-props": "^1.7.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"postcss": "^8.4.0",
|
||||
"postcss-cli": "^11.0.0",
|
||||
"postcss-import": "^16.0.0",
|
||||
"postcss-custom-media": "^11.0.0",
|
||||
"cssnano": "^7.0.0"
|
||||
}
|
||||
}
|
||||
7
postcss.config.js
Normal file
7
postcss.config.js
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
module.exports = {
|
||||
plugins: [
|
||||
require('postcss-import'),
|
||||
require('postcss-custom-media'),
|
||||
require('cssnano')({ preset: 'default' })
|
||||
]
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue