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
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);
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue