From b602a8d54e36501db7f08cea1ce3640277c79066 Mon Sep 17 00:00:00 2001 From: Ludo Date: Sat, 11 Apr 2026 15:26:02 +0200 Subject: [PATCH] =?UTF-8?q?refactor:=20CSS=20tasks=201-6=20=E2=80=94=20add?= =?UTF-8?q?=20token=20aliases,=20fix=20all=20primitive=20leaks?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Rename 01-asw.css → 01-tokens.css (pure :root, no rules) - Add semantic aliases: --weight-*, --shadow-*, --focus-ring-width, --dropdown-min-width, --space-5a, --weight-light, --border-width-thick - Extract editorial rules from token file to components/layout - Replace all Open Props primitives in layers 02-09 with semantic aliases - Zero primitive leaks remain outside 01-tokens.css Co-Authored-By: Claude Opus 4.6 (1M context) --- src/layers/{01-asw.css => 01-tokens.css} | 37 +++++++++++++---------- src/layers/02-semantic.css | 18 +++++------ src/layers/03-components.css | 38 ++++++++++++++---------- src/layers/04-data-attrs.css | 14 ++++----- src/layers/05-utilities.css | 10 +++---- src/layers/06-charts.css | 34 ++++++++++----------- src/layers/07-chroma.css | 4 +-- src/layers/08-layout.css | 11 +++---- src/layers/08a-essay.css | 2 +- src/layers/09-landing.css | 2 +- src/main.css | 2 +- 11 files changed, 92 insertions(+), 80 deletions(-) rename src/layers/{01-asw.css => 01-tokens.css} (96%) diff --git a/src/layers/01-asw.css b/src/layers/01-tokens.css similarity index 96% rename from src/layers/01-asw.css rename to src/layers/01-tokens.css index b73ed12..035004d 100644 --- a/src/layers/01-asw.css +++ b/src/layers/01-tokens.css @@ -266,6 +266,27 @@ --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"); + /* Font weights */ + --weight-light: var(--font-weight-2); + --weight-normal: var(--font-weight-4); + --weight-medium: var(--font-weight-5); + --weight-semibold: var(--font-weight-6); + --weight-bold: var(--font-weight-7); + + /* Shadows */ + --shadow-dropdown: var(--shadow-2); + --shadow-modal: var(--shadow-4); + + /* Focus ring */ + --focus-ring-width: var(--border-size-2); + --border-width-thick: var(--border-size-3); + + /* Dropdown */ + --dropdown-min-width: var(--size-px-12); + + /* Gap in spacing scale */ + --space-5a: 1.25rem; /* between --space-4 (1rem) and --space-5 (1.5rem) */ + /* ══════════════════════════════════════════════════════════════════ AGENT-NATIVE TOKENS @@ -395,19 +416,3 @@ @media (--lg-n-above) { html { font-size: 103%; } } @media (--xl-n-above) { html { font-size: 106%; } } @media (--xxl-n-above) { html { font-size: 109%; } } - - -/* ══════════════════════════════════════════════════════════════════ - EDITORIAL DEFAULTS - Opinionated ASW decisions that go beyond tokens — centering, - spacing rhythms, and layout choices that define the ASW look. - ══════════════════════════════════════════════════════════════════ */ - -/* Nav content centered at --width-xl without a wrapper element. - max() falls back to --container-padding on narrow viewports. */ -body > nav { - padding-inline: max(var(--container-padding), calc((100% - var(--width-xl)) / 2)); -} -[data-layout="docs"] > article { - max-width: var(--width-prose); -} diff --git a/src/layers/02-semantic.css b/src/layers/02-semantic.css index 3c93523..f3391e2 100644 --- a/src/layers/02-semantic.css +++ b/src/layers/02-semantic.css @@ -145,7 +145,7 @@ p { margin-bottom: var(--type-space); color: var(--text); font-style: normal; - font-weight: var(--font-weight-4); + font-weight: var(--weight-normal); } /* ── Typography: Lists ─────────────────────────────────────────────── */ @@ -158,7 +158,7 @@ ul { margin-bottom: var(--type-space); color: var(--text); font-style: normal; - font-weight: var(--font-weight-4); + font-weight: var(--weight-normal); } :where(ol, ul) li { @@ -225,7 +225,7 @@ del { } abbr[title] { - border-bottom: var(--border-size-1) dotted; + border-bottom: var(--border-width) dotted; text-decoration: none; cursor: help; } @@ -297,7 +297,7 @@ small { text-indent: 0; color: var(--text); font-style: normal; - font-weight: var(--font-weight-4); + font-weight: var(--weight-normal); } th, @@ -306,14 +306,14 @@ td { border-bottom: var(--border-width) solid var(--border); background-color: transparent; color: var(--text); - font-weight: var(--font-weight-4); + font-weight: var(--weight-normal); text-align: left; } thead th, thead td { font-weight: 600; - border-bottom-width: var(--border-size-2); + border-bottom-width: var(--focus-ring-width); } tfoot th, @@ -339,7 +339,7 @@ samp { border-radius: var(--radius-md); background: var(--surface-1); color: var(--code-color); - font-weight: var(--font-weight-4); + font-weight: var(--weight-normal); line-height: initial; } @@ -471,10 +471,10 @@ pre[class*="language-"] { .token.important, .token.variable { color: var(--syntax-variable); - font-weight: var(--font-weight-5); + font-weight: var(--weight-medium); } -.token.bold { font-weight: var(--font-weight-7); } +.token.bold { font-weight: var(--weight-bold); } .token.italic { font-style: italic; } /* Light mode overrides */ diff --git a/src/layers/03-components.css b/src/layers/03-components.css index f27fa01..f89a6b4 100644 --- a/src/layers/03-components.css +++ b/src/layers/03-components.css @@ -35,7 +35,7 @@ button, outline: none; background-color: var(--surface); color: var(--text); - font-weight: var(--font-weight-4); + font-weight: var(--weight-normal); font-size: var(--text-base); line-height: var(--leading); text-align: center; @@ -100,7 +100,7 @@ label { display: block; margin-bottom: calc(var(--space-4) * 0.375); color: var(--text); - font-weight: var(--font-weight-4); + font-weight: var(--weight-normal); } input:not([type=checkbox], [type=radio], [type=range], [type=file]), @@ -113,7 +113,7 @@ textarea { outline: none; background-color: var(--input-bg); color: var(--text); - font-weight: var(--font-weight-4); + font-weight: var(--weight-normal); transition: background-color var(--ease), border-color var(--ease), color var(--ease); @@ -259,6 +259,12 @@ label > :where(input, select, textarea) { /* ── Navigation ────────────────────────────────────────────────────────*/ /* Semantic nav: */ +/* Nav content centered at --width-xl without a wrapper element. + max() falls back to --container-padding on narrow viewports. */ +body > nav { + padding-inline: max(var(--container-padding), calc((100% - var(--width-xl)) / 2)); +} + body > nav { display: flex; justify-content: space-between; @@ -382,13 +388,13 @@ body > nav details > div { position: absolute; top: calc(100% + 0.5rem); left: 0; - min-width: var(--size-px-12); + min-width: var(--dropdown-min-width); 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); + box-shadow: var(--shadow-dropdown); z-index: 20; list-style: none; display: flex; @@ -452,7 +458,7 @@ article { background: transparent; border: 1px solid var(--border); border-radius: var(--radius-md); - padding: var(--size-3) var(--size-4); + padding: var(--space-4) var(--space-5a); margin: var(--space-3) 0; } @@ -601,7 +607,7 @@ details:not(nav details) > summary { padding: var(--space-3) var(--space-4); font-family: var(--font-ui); font-size: var(--text-base); - font-weight: var(--font-weight-5, 500); + font-weight: var(--weight-medium); color: var(--text); cursor: pointer; list-style: none; @@ -687,7 +693,7 @@ dialog { border-radius: var(--radius-md); background: var(--surface-1); color: var(--text); - box-shadow: var(--shadow-4); + box-shadow: var(--shadow-modal); z-index: var(--layer-4); max-width: min(90vw, 42rem); max-height: min(90vh, 40rem); @@ -779,7 +785,7 @@ dialog > footer { color: var(--text-3); padding-inline: var(--space-2); user-select: none; - font-weight: var(--font-weight-4); + font-weight: var(--weight-normal); } [data-role="breadcrumb"] a { @@ -795,7 +801,7 @@ dialog > footer { /* Current page: plain text, full colour, no link underline */ [data-role="breadcrumb"] [aria-current="page"] { color: var(--text); - font-weight: var(--font-weight-5); + font-weight: var(--weight-medium); } @@ -861,7 +867,7 @@ dialog > footer { justify-content: center; font-family: var(--font-mono); font-size: var(--text-xs); - font-weight: var(--font-weight-6); + font-weight: var(--weight-semibold); z-index: 1; /* default (pending) colours — overridden below */ background: var(--surface-card); @@ -902,12 +908,12 @@ dialog > footer { background: var(--accent); border-color: var(--accent); color: var(--on-accent); - box-shadow: 0 0 0 var(--border-size-2) var(--accent-focus); + box-shadow: 0 0 0 var(--focus-ring-width) var(--accent-focus); } [data-role="steps"] > [data-status="active"] > span { color: var(--text); - font-weight: var(--font-weight-5); + font-weight: var(--weight-medium); } /* pending is the default — no additional rules needed */ @@ -961,7 +967,7 @@ nav[data-nav="sidebar"] h3 { color: var(--text-3); font-size: var(--text-xs); font-family: var(--font-mono); - font-weight: var(--font-weight-5); + font-weight: var(--weight-medium); text-transform: uppercase; letter-spacing: 0.08em; margin-top: var(--space-4); @@ -1008,7 +1014,7 @@ aside[data-toc] h3 { color: var(--text-3); font-size: var(--text-xs); font-family: var(--font-mono); - font-weight: var(--font-weight-5); + font-weight: var(--weight-medium); text-transform: uppercase; letter-spacing: 0.08em; margin-bottom: var(--space-2); @@ -1030,7 +1036,7 @@ aside[data-toc] nav a { padding: var(--space-1) var(--space-2); color: var(--text-3); text-decoration: none; - border-left: var(--border-size-2) solid transparent; + border-left: var(--focus-ring-width) solid transparent; transition: color var(--ease), border-color var(--ease); } diff --git a/src/layers/04-data-attrs.css b/src/layers/04-data-attrs.css index 9170033..8b5897c 100644 --- a/src/layers/04-data-attrs.css +++ b/src/layers/04-data-attrs.css @@ -522,7 +522,7 @@ position: fixed; top: 0; left: 0; - height: var(--border-size-2); + height: var(--focus-ring-width); background: var(--accent); z-index: 9999; /* Subtle shadow so bar is visible on light pages too */ @@ -546,7 +546,7 @@ /* Subtle accent on AI-generated sections — light left border indicator */ [data-ai-disclosure] { - border-left: var(--border-size-2) solid transparent; + border-left: var(--focus-ring-width) solid transparent; padding-left: var(--space-3); } @@ -561,7 +561,7 @@ /* Autonomous — more distinct: full accent treatment */ [data-ai-disclosure="autonomous"] { border-left-color: var(--accent); - border-left-width: var(--border-size-2); + border-left-width: var(--focus-ring-width); } /* Mixed — yellow/amber to signal blended provenance */ @@ -649,14 +649,14 @@ a[data-role="secondary"]:hover { [data-size="xs"] { font-size: var(--font-size-00, 0.6rem); - padding: var(--size-1) var(--size-2); - gap: var(--size-1); + padding: var(--space-1) var(--space-2); + gap: var(--space-1); } [data-size="sm"] { font-size: var(--text-xs); - padding: var(--size-1) var(--size-3); - gap: var(--size-2); + padding: var(--space-1) var(--space-4); + gap: var(--space-2); } /* md is the default — explicit reset for override contexts */ diff --git a/src/layers/05-utilities.css b/src/layers/05-utilities.css index 53c3030..b410b0a 100644 --- a/src/layers/05-utilities.css +++ b/src/layers/05-utilities.css @@ -111,7 +111,7 @@ dl[data-layout="inline"] dd { height: 1em; margin-right: 0.5em; vertical-align: -0.125em; - border: var(--border-size-2) solid currentColor; + border: var(--focus-ring-width) solid currentColor; border-top-color: transparent; border-radius: 50%; } @@ -175,7 +175,7 @@ dl[data-layout="inline"] dd { --border-color-subtle: var(--border-subtle); --text-primary: var(--hc-text); --text-secondary: var(--text-2); - --border-width: var(--border-size-2); + --border-width: var(--focus-ring-width); } /* Thicker borders on interactive elements */ @@ -185,13 +185,13 @@ dl[data-layout="inline"] dd { select, textarea, [data-wikilink] { - border-width: var(--border-size-2); + border-width: var(--focus-ring-width); } /* Stronger focus indicators */ :focus-visible { - outline-width: var(--border-size-3); - outline-offset: var(--border-size-3); + outline-width: var(--border-width-thick); + outline-offset: var(--border-width-thick); } } diff --git a/src/layers/06-charts.css b/src/layers/06-charts.css index 9af3fb6..3cdda19 100644 --- a/src/layers/06-charts.css +++ b/src/layers/06-charts.css @@ -69,7 +69,7 @@ font-size: var(--text-sm); color: var(--text-3); text-align: start; - padding-block-end: var(--size-3); + padding-block-end: var(--space-4); caption-side: top; } @@ -118,7 +118,7 @@ [data-chart="bar"] tr { display: flex; align-items: center; - gap: var(--size-3); + gap: var(--space-4); } /* Row label (th) */ @@ -130,7 +130,7 @@ max-inline-size: 8rem; text-align: end; padding-block: 0; - padding-inline: var(--size-2) 0; + padding-inline: var(--space-2) 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; @@ -227,7 +227,7 @@ justify-content: flex-end; flex: 1; block-size: 100%; - gap: var(--size-1); + gap: var(--space-1); } /* Column label (th) at the bottom */ @@ -241,10 +241,10 @@ text-overflow: ellipsis; max-inline-size: 100%; padding: 0; - padding-block-start: var(--size-1); + padding-block-start: var(--space-1); /* Move below axis */ order: 2; - margin-block-start: var(--size-2); + margin-block-start: var(--space-2); } /* Data cell — the column bar */ @@ -285,7 +285,7 @@ [data-chart="column"][data-chart-labels] thead { display: flex; justify-content: space-around; - margin-block-end: var(--size-2); + margin-block-end: var(--space-2); } [data-chart="column"][data-chart-labels] thead th { @@ -332,7 +332,7 @@ color: var(--chart-label); text-align: center; order: 2; - padding-block-start: var(--size-1); + padding-block-start: var(--space-1); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; @@ -390,7 +390,7 @@ color: var(--chart-label); text-align: center; order: 2; - padding-block-start: var(--size-1); + padding-block-start: var(--space-1); white-space: nowrap; } @@ -456,9 +456,9 @@ [data-chart="pie"] thead { display: flex; flex-wrap: wrap; - gap: var(--size-2); + gap: var(--space-2); justify-content: center; - margin-block-end: var(--size-3); + margin-block-end: var(--space-4); } [data-chart="pie"] thead th { @@ -549,7 +549,7 @@ display: inline-flex; flex-direction: column; align-items: center; - gap: var(--size-2); + gap: var(--space-2); } [data-chart="radial"] caption { @@ -557,7 +557,7 @@ color: var(--chart-label); text-align: center; caption-side: bottom; - padding-block-start: var(--size-2); + padding-block-start: var(--space-2); } [data-chart="radial"] tbody { display: flex; } @@ -666,7 +666,7 @@ justify-content: flex-end; flex: 1; block-size: 100%; - gap: var(--size-1); + gap: var(--space-1); } /* Remaining-work bar — red, with ideal line overlay above it */ @@ -693,10 +693,10 @@ color: var(--chart-label); text-align: center; order: 2; - padding-block-start: var(--size-1); + padding-block-start: var(--space-1); white-space: nowrap; padding: 0; - margin-block-start: var(--size-2); + margin-block-start: var(--space-2); } /* ── Spacing modifiers for area and line (port from bar/column) ──── */ @@ -749,7 +749,7 @@ [data-chart="bar"][data-chart-labels] thead { display: block; - margin-block-end: var(--size-2); + margin-block-end: var(--space-2); } [data-chart="bar"][data-chart-labels] thead th { diff --git a/src/layers/07-chroma.css b/src/layers/07-chroma.css index e3e6628..8acad83 100644 --- a/src/layers/07-chroma.css +++ b/src/layers/07-chroma.css @@ -18,7 +18,7 @@ .chroma pre { background: var(--surface-2); - padding: var(--size-3); + padding: var(--space-4); border-radius: var(--radius-2); overflow-x: auto; margin: 0; @@ -134,5 +134,5 @@ .chroma .lnt { color: var(--text-3); user-select: none; - padding-inline-end: var(--size-3); + padding-inline-end: var(--space-4); } diff --git a/src/layers/08-layout.css b/src/layers/08-layout.css index b298466..17e362d 100644 --- a/src/layers/08-layout.css +++ b/src/layers/08-layout.css @@ -40,7 +40,7 @@ body > section { body { background-color: var(--surface); color: var(--text); - font-weight: var(--font-weight-4); + font-weight: var(--weight-normal); line-height: var(--leading); font-variant-emoji: text; /* render emoji as monochrome glyphs, not OS pictographs */ min-height: 100vh; @@ -202,9 +202,10 @@ nav[data-layout="actions"] a:hover { } } -/* Allow article as content column in docs layout — override body > article container sizing */ +/* Article content column: reading-optimised prose width. + Overrides body > article container sizing from 08-layout.css. */ [data-layout="docs"] > article { - max-width: none; + max-width: var(--width-prose); min-width: 0; } @@ -299,7 +300,7 @@ nav[data-layout="actions"] a:hover { [data-layout="stats"] .value { font-family: var(--font-mono); font-size: var(--text-3xl); - font-weight: var(--font-weight-7); + font-weight: var(--weight-bold); color: var(--accent); display: block; } @@ -349,7 +350,7 @@ article[data-layout="prose"], left: 0.6rem; top: 0.5rem; bottom: 0.5rem; - width: var(--border-size-1); + width: var(--border-width); background: var(--border); } diff --git a/src/layers/08a-essay.css b/src/layers/08a-essay.css index 2e1e612..d2e884e 100644 --- a/src/layers/08a-essay.css +++ b/src/layers/08a-essay.css @@ -23,7 +23,7 @@ article[data-paper] > header { article[data-paper] > header h1 { font-size: clamp(1.6rem, 4vw, 2.4rem); - font-weight: var(--font-weight-3); + font-weight: var(--weight-light); letter-spacing: -0.02em; line-height: 1.15; margin-bottom: var(--space-4); diff --git a/src/layers/09-landing.css b/src/layers/09-landing.css index a2a2b9c..6f49e9f 100644 --- a/src/layers/09-landing.css +++ b/src/layers/09-landing.css @@ -44,7 +44,7 @@ [data-layout="hero"] h1 { font-size: clamp(2.6rem, 6vw, 4.5rem); - font-weight: var(--font-weight-2); + font-weight: var(--weight-light); letter-spacing: -0.025em; line-height: 1.05; margin-bottom: var(--space-4); diff --git a/src/main.css b/src/main.css index 2303e92..6fef13b 100644 --- a/src/main.css +++ b/src/main.css @@ -12,7 +12,7 @@ /* 2. Framework layers */ @import "./layers/00-reset.css"; -@import "./layers/01-asw.css"; +@import "./layers/01-tokens.css"; @import "./layers/02-semantic.css"; @import "./layers/03-components.css"; @import "./layers/04-data-attrs.css";