Compare commits
3 commits
376bfb2364
...
d9641b0485
| Author | SHA1 | Date | |
|---|---|---|---|
| d9641b0485 | |||
| ea51dbd7cf | |||
| 9b1dcdab6e |
10 changed files with 398 additions and 248 deletions
File diff suppressed because one or more lines are too long
|
|
@ -3,6 +3,7 @@
|
|||
* ASW semantic layer — builds on Open Props
|
||||
*
|
||||
* Open Props (imported in main.css) provides the base scales:
|
||||
* --color-1…16 (oklch, palette-hue-tinted — the primary color scale)
|
||||
* --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
|
||||
|
|
@ -16,8 +17,8 @@
|
|||
* 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.
|
||||
* Set --palette-hue in your own CSS to shift all color-N surfaces/text.
|
||||
* Override semantic aliases at :root for finer control.
|
||||
*
|
||||
* Lineage: absorbed patterns from Pico CSS, Open Props, Charts.css.
|
||||
*/
|
||||
|
|
@ -31,57 +32,64 @@
|
|||
|
||||
/* ══════════════════════════════════════════════════════════════════
|
||||
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)
|
||||
Using Open Props oklch --color-N 16-step palette.
|
||||
Set --palette-hue to tint all surfaces and text. Example:
|
||||
Trentuna: --palette-hue: 45 (warm amber tint)
|
||||
vigilio-garden: --palette-hue: 150 (subtle green tint)
|
||||
══════════════════════════════════════════════════════════════════ */
|
||||
|
||||
:root {
|
||||
|
||||
/* ── Surfaces ──────────────────────────────────────────────────── */
|
||||
/* ── Palette controls ───────────────────────────────────────────────
|
||||
--color-1 (lightest) through --color-16 (darkest) follow this hue.
|
||||
Change --palette-hue to retheme all surfaces and text in one place.
|
||||
─────────────────────────────────────────────────────────────────── */
|
||||
--palette-hue: 250; /* blue-violet default */
|
||||
--palette-chroma: 0.15;
|
||||
|
||||
--surface: var(--gray-12); /* deepest background (oklch 10%) */
|
||||
--surface-1: var(--gray-11); /* cards, sidebars (oklch 18%) */
|
||||
--surface-2: var(--gray-10); /* hover, raised elements (oklch 25%) */
|
||||
/* ── Surfaces — dark end of the 16-step scale ─────────────────── */
|
||||
|
||||
--surface: var(--color-16); /* ~10% lightness */
|
||||
--surface-1: var(--color-15); /* ~16% */
|
||||
--surface-2: var(--color-14); /* ~20% */
|
||||
--surface-card: var(--surface-1);
|
||||
--surface-hover: var(--surface-2);
|
||||
|
||||
/* ── Text ──────────────────────────────────────────────────────── */
|
||||
/* ── Text — light end of the scale ────────────────────────────── */
|
||||
|
||||
--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%) */
|
||||
--text: var(--color-3); /* 93% lightness */
|
||||
--text-2: var(--color-5); /* 80% */
|
||||
--text-3: var(--color-7); /* 66% */
|
||||
--text-dim: var(--color-9); /* 53% */
|
||||
|
||||
/* ── Accent ────────────────────────────────────────────────────── */
|
||||
/* ── Accent — peak chroma step, palette-driven ─────────────────── */
|
||||
|
||||
--accent: var(--green-5);
|
||||
--accent-hover: var(--green-4);
|
||||
--on-accent: var(--gray-12);
|
||||
--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);
|
||||
--accent: var(--color-8); /* 58%, peak chroma */
|
||||
--accent-hover: var(--color-7); /* 66% */
|
||||
--on-accent: var(--color-16);
|
||||
--accent-focus: oklch(58% 0.15 var(--palette-hue) / 0.35);
|
||||
--accent-subtle: oklch(58% 0.15 var(--palette-hue) / 0.10);
|
||||
--accent-underline: oklch(58% 0.15 var(--palette-hue) / 0.45);
|
||||
--accent-hover-underline: oklch(66% 0.15 var(--palette-hue) / 0.55);
|
||||
|
||||
/* ── Links ─────────────────────────────────────────────────────── */
|
||||
/* Blue — web convention. Accent (green) reserved for UI chrome. */
|
||||
/* ── Links — fixed blue hue, not palette-driven ─────────────────
|
||||
Blue is the web convention. Accent is palette-tinted 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);
|
||||
--link: oklch(65% 0.15 250);
|
||||
--link-hover: oklch(72% 0.15 250);
|
||||
--link-underline: oklch(65% 0.08 250);
|
||||
--link-hover-underline: oklch(72% 0.10 250);
|
||||
--link-focus: oklch(65% 0.06 250);
|
||||
|
||||
/* Secondary accents — reachable as named aliases */
|
||||
--accent-blue: var(--blue-5);
|
||||
--accent-red: var(--red-7);
|
||||
--accent-orange: var(--yellow-6);
|
||||
/* Secondary accents — fixed hues, not palette-driven */
|
||||
--accent-blue: oklch(65% 0.15 250); /* matches --link */
|
||||
--accent-red: oklch(65% 0.18 25); /* matches --error */
|
||||
--accent-orange: oklch(75% 0.15 80); /* matches --warn */
|
||||
|
||||
/* ── Border ────────────────────────────────────────────────────── */
|
||||
|
||||
--border: var(--gray-11); /* 37% lightness — visible against 10% bg */
|
||||
--border-subtle: var(--gray-12); /* 31% lightness — very subtle */
|
||||
--border: var(--color-14); /* ~20% lightness */
|
||||
--border-subtle: var(--color-15); /* ~16% lightness */
|
||||
--border-width: 1px;
|
||||
--outline-width: 2px;
|
||||
|
||||
|
|
@ -121,12 +129,12 @@
|
|||
--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);
|
||||
--h1-color: var(--color-2);
|
||||
--h2-color: var(--color-3);
|
||||
--h3-color: var(--color-3);
|
||||
--h4-color: var(--color-5);
|
||||
--h5-color: var(--color-5);
|
||||
--h6-color: var(--color-7);
|
||||
|
||||
/* ── Spacing aliases ─────────────────────────────────────────────
|
||||
Open Props sizes: --size-1 (.25rem), --size-2 (.5rem), --size-3 (1rem),
|
||||
|
|
@ -174,16 +182,16 @@
|
|||
|
||||
/* ── 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);
|
||||
--diff-add-bg: color-mix(in oklch, var(--ok) 10%, transparent);
|
||||
--diff-remove-bg: color-mix(in oklch, var(--error) 10%, transparent);
|
||||
--diff-remove-text: oklch(88% 0.06 25);
|
||||
--diff-hunk-bg: color-mix(in oklch, var(--info) 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);
|
||||
--ai-generated-border: color-mix(in oklch, var(--ok) 25%, transparent);
|
||||
--ai-assisted-border: color-mix(in oklch, var(--info) 20%, transparent);
|
||||
--ai-mixed-border: color-mix(in oklch, var(--warn) 30%, transparent);
|
||||
|
||||
/* ── Rhythm ─────────────────────────────────────────────────────── */
|
||||
|
||||
|
|
@ -207,39 +215,39 @@
|
|||
|
||||
/* ── Inline element tokens ─────────────────────────────────────── */
|
||||
|
||||
--selection: color-mix(in oklch, var(--blue-4) 25%, transparent);
|
||||
--mark-bg: color-mix(in oklch, var(--yellow-6) 20%, transparent);
|
||||
--selection: oklch(65% 0.08 250 / 0.30);
|
||||
--mark-bg: oklch(45% 0.10 80 / 0.40);
|
||||
--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-11) 50%, transparent);
|
||||
--table-stripe: color-mix(in oklch, var(--color-15) 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-selected: color-mix(in oklch, var(--accent) 20%, transparent);
|
||||
--input-px: var(--space-4);
|
||||
--input-py: var(--space-3);
|
||||
--disabled-opacity: 0.5;
|
||||
|
||||
/* ── State colors ─────────────────────────────────────────────────── */
|
||||
/* ── State colors — fixed hues, harmonized oklch ─────────────────── */
|
||||
|
||||
--ok: var(--green-5);
|
||||
--warn: var(--yellow-5);
|
||||
--error: var(--red-7);
|
||||
--info: var(--blue-5);
|
||||
--blocked: var(--gray-5);
|
||||
--ok: oklch(75% 0.15 145); /* green */
|
||||
--warn: oklch(75% 0.15 80); /* amber */
|
||||
--error: oklch(75% 0.15 25); /* red */
|
||||
--info: oklch(75% 0.15 250); /* blue */
|
||||
--blocked: var(--color-9);
|
||||
|
||||
--error-active: var(--red-9);
|
||||
--error-focus: color-mix(in oklch, var(--red-7) 38%, transparent);
|
||||
--error-active: oklch(65% 0.18 25);
|
||||
--error-focus: oklch(65% 0.06 25);
|
||||
|
||||
/* ── Component tokens ─────────────────────────────────────────────── */
|
||||
|
||||
--track-bg: var(--surface-2); /* progress / meter background */
|
||||
--modal-overlay: color-mix(in oklch, var(--gray-12) 80%, transparent);
|
||||
--modal-overlay: color-mix(in oklch, var(--color-16) 80%, transparent);
|
||||
--modal-backdrop: blur(0.375rem);
|
||||
--accordion-active: var(--accent-hover);
|
||||
|
||||
|
|
@ -252,19 +260,19 @@
|
|||
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);
|
||||
--task-done: var(--ok);
|
||||
--task-blocked: var(--error);
|
||||
--task-wip: var(--warn);
|
||||
--task-todo: var(--color-9);
|
||||
|
||||
--callout-info: var(--blue-5);
|
||||
--callout-warn: var(--yellow-5);
|
||||
--callout-error: var(--red-5);
|
||||
--callout-note: var(--gray-5);
|
||||
--callout-info: var(--info);
|
||||
--callout-warn: var(--warn);
|
||||
--callout-error: var(--error);
|
||||
--callout-note: var(--color-9);
|
||||
|
||||
--session-bg: var(--surface-1);
|
||||
--wikilink: var(--blue-4);
|
||||
--redacted: var(--gray-8);
|
||||
--wikilink: var(--link);
|
||||
--redacted: var(--color-11);
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -277,58 +285,45 @@
|
|||
: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);
|
||||
--surface: var(--color-1); /* 98% */
|
||||
--surface-1: var(--color-2); /* 97% */
|
||||
--surface-2: var(--color-3); /* 93% */
|
||||
--surface-card: var(--color-1);
|
||||
--surface-hover: var(--color-2);
|
||||
|
||||
--text: var(--gray-11); /* 18% — dark but not pure black */
|
||||
--text-2: var(--gray-11); /* 37% */
|
||||
--text-3: var(--gray-8); /* 53% */
|
||||
--text-dim: var(--gray-6); /* 63% */
|
||||
--text: var(--color-14); /* 20% */
|
||||
--text-2: var(--color-12); /* 35% */
|
||||
--text-3: var(--color-10); /* 49% */
|
||||
--text-dim: var(--color-8); /* 58% */
|
||||
|
||||
--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);
|
||||
--accent: var(--color-9); /* 53% — slightly darker for contrast on light */
|
||||
--accent-hover: var(--color-10);
|
||||
--on-accent: var(--color-1);
|
||||
|
||||
--border: var(--gray-3); /* 80% — visible on near-white */
|
||||
--border-subtle: var(--gray-2); /* 88% — very subtle */
|
||||
--border: var(--color-4); /* 84% */
|
||||
--border-subtle: var(--color-3); /* 93% */
|
||||
|
||||
--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);
|
||||
--link: oklch(45% 0.15 250);
|
||||
--link-hover: oklch(38% 0.15 250);
|
||||
--link-underline: oklch(45% 0.08 250);
|
||||
--link-hover-underline: oklch(38% 0.10 250);
|
||||
--link-focus: oklch(45% 0.06 250);
|
||||
|
||||
--h1-color: var(--gray-12);
|
||||
--h2-color: var(--gray-11);
|
||||
--h3-color: var(--gray-10);
|
||||
--h4-color: var(--gray-12);
|
||||
--h5-color: var(--gray-11);
|
||||
--h6-color: var(--gray-10);
|
||||
--h1-color: var(--color-16);
|
||||
--h2-color: var(--color-15);
|
||||
--h3-color: var(--color-14);
|
||||
--h4-color: var(--color-13);
|
||||
--h5-color: var(--color-12);
|
||||
--h6-color: var(--color-11);
|
||||
|
||||
--mark-bg: color-mix(in oklch, var(--yellow-6) 15%, var(--surface));
|
||||
--mark-color: var(--gray-12);
|
||||
--selection: color-mix(in oklch, var(--blue-8) 20%, transparent);
|
||||
--ok: oklch(40% 0.15 145);
|
||||
--warn: oklch(40% 0.15 80);
|
||||
--error: oklch(40% 0.15 25);
|
||||
--info: oklch(40% 0.15 250);
|
||||
|
||||
--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);
|
||||
--mark-bg: oklch(92% 0.08 80);
|
||||
--mark-color: var(--color-15);
|
||||
--selection: oklch(80% 0.06 250);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -84,9 +84,7 @@ figcaption,
|
|||
button,
|
||||
input,
|
||||
select,
|
||||
textarea,
|
||||
hgroup > p,
|
||||
hgroup > small {
|
||||
textarea {
|
||||
font-family: var(--font-ui);
|
||||
}
|
||||
|
||||
|
|
@ -169,7 +167,6 @@ ul {
|
|||
|
||||
/* Nested lists: reduce spacing */
|
||||
:where(dl, ol, ul) :where(dl, ol, ul) {
|
||||
margin: 0;
|
||||
margin-top: calc(var(--type-space) * 0.25);
|
||||
}
|
||||
|
||||
|
|
@ -326,8 +323,8 @@ tfoot td {
|
|||
}
|
||||
|
||||
/* Striped tables (class-based but useful) */
|
||||
table.striped tbody tr:nth-child(odd) th,
|
||||
table.striped tbody tr:nth-child(odd) td {
|
||||
[data-table="striped"] tbody tr:nth-child(odd) th,
|
||||
[data-table="striped"] tbody tr:nth-child(odd) td {
|
||||
background-color: var(--table-stripe);
|
||||
}
|
||||
|
||||
|
|
@ -410,7 +407,7 @@ pre[class*="language-"] {
|
|||
.token.prolog,
|
||||
.token.doctype,
|
||||
.token.cdata {
|
||||
color: var(--gray-6); /* muted: ~55% lightness */
|
||||
color: var(--gray-6); /* TODO: map to semantic token — no alias for gray-6 (between --text-3: gray-5 and --text-dim: gray-7) */
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
|
|
@ -420,19 +417,19 @@ pre[class*="language-"] {
|
|||
|
||||
.token.tag,
|
||||
.token.deleted {
|
||||
color: var(--red-4); /* HTML tags, deleted code */
|
||||
color: var(--red-4); /* TODO: map to semantic token — no alias for red-4 (--error=red-7, --callout-error=red-5; syntax highlight needs lighter shade) */
|
||||
}
|
||||
|
||||
.token.attr-name,
|
||||
.token.namespace {
|
||||
color: var(--yellow-4); /* attribute names */
|
||||
color: var(--yellow-4); /* TODO: map to semantic token — no alias for yellow-4 (--warn=yellow-5 is close but one step darker) */
|
||||
}
|
||||
|
||||
.token.string,
|
||||
.token.attr-value,
|
||||
.token.char,
|
||||
.token.inserted {
|
||||
color: var(--green-4); /* strings, values */
|
||||
color: var(--accent-hover); /* strings, values — --accent-hover = var(--green-4) */
|
||||
}
|
||||
|
||||
.token.number,
|
||||
|
|
@ -449,7 +446,7 @@ pre[class*="language-"] {
|
|||
|
||||
.token.keyword,
|
||||
.token.atrule {
|
||||
color: var(--blue-4); /* keywords, @rules */
|
||||
color: var(--link-hover); /* keywords, @rules — --link-hover = var(--blue-4) */
|
||||
}
|
||||
|
||||
.token.function,
|
||||
|
|
@ -458,7 +455,7 @@ pre[class*="language-"] {
|
|||
}
|
||||
|
||||
.token.property {
|
||||
color: var(--blue-5); /* object properties */
|
||||
color: var(--info); /* object properties — --info = var(--blue-5) */
|
||||
}
|
||||
|
||||
.token.operator,
|
||||
|
|
@ -473,7 +470,7 @@ pre[class*="language-"] {
|
|||
|
||||
.token.important,
|
||||
.token.variable {
|
||||
color: var(--yellow-5); /* !important, variables */
|
||||
color: var(--warn); /* !important, variables — --warn = var(--yellow-5) */
|
||||
font-weight: var(--font-weight-5);
|
||||
}
|
||||
|
||||
|
|
@ -485,20 +482,20 @@ pre[class*="language-"] {
|
|||
.token.comment,
|
||||
.token.prolog,
|
||||
.token.doctype,
|
||||
.token.cdata { color: var(--gray-6); }
|
||||
.token.cdata { color: var(--gray-6); /* TODO: map to semantic token — no alias for gray-6 in light mode */ }
|
||||
|
||||
.token.punctuation { color: var(--gray-8); }
|
||||
.token.punctuation { color: var(--gray-8); /* TODO: map to semantic token — no alias for gray-8 */ }
|
||||
|
||||
.token.tag,
|
||||
.token.deleted { color: var(--red-8); }
|
||||
.token.deleted { color: var(--red-8); /* TODO: map to semantic token — no alias for red-8 */ }
|
||||
|
||||
.token.attr-name,
|
||||
.token.namespace { color: var(--yellow-9); }
|
||||
.token.namespace { color: var(--yellow-9); /* TODO: map to semantic token — no alias for yellow-9 */ }
|
||||
|
||||
.token.string,
|
||||
.token.attr-value,
|
||||
.token.char,
|
||||
.token.inserted { color: var(--green-8); }
|
||||
.token.inserted { color: var(--green-8); /* TODO: map to semantic token — no alias for green-8 */ }
|
||||
|
||||
.token.number,
|
||||
.token.boolean,
|
||||
|
|
@ -509,21 +506,21 @@ pre[class*="language-"] {
|
|||
.token.builtin { color: var(--teal-8); }
|
||||
|
||||
.token.keyword,
|
||||
.token.atrule { color: var(--blue-8); }
|
||||
.token.atrule { color: var(--blue-8); /* TODO: map to semantic token — no alias for blue-8 */ }
|
||||
|
||||
.token.function,
|
||||
.token.class-name { color: var(--cyan-9); }
|
||||
|
||||
.token.property { color: var(--blue-9); }
|
||||
.token.property { color: var(--blue-9); /* TODO: map to semantic token — no alias for blue-9 */ }
|
||||
|
||||
.token.operator,
|
||||
.token.entity,
|
||||
.token.url { color: var(--gray-8); }
|
||||
.token.url { color: var(--gray-8); /* TODO: map to semantic token — no alias for gray-8 in light mode */ }
|
||||
|
||||
.token.regex { color: var(--orange-7); }
|
||||
|
||||
.token.important,
|
||||
.token.variable { color: var(--yellow-9); }
|
||||
.token.variable { color: var(--yellow-9); /* TODO: map to semantic token — no alias for yellow-9 */ }
|
||||
}
|
||||
|
||||
/* ── Details / Summary ─────────────────────────────────────────────── */
|
||||
|
|
@ -603,7 +600,7 @@ dialog {
|
|||
align-items: center;
|
||||
justify-content: center;
|
||||
width: inherit;
|
||||
min-width: 100%;
|
||||
min-width: auto;
|
||||
height: inherit;
|
||||
min-height: 100%;
|
||||
padding: 0;
|
||||
|
|
|
|||
|
|
@ -701,7 +701,7 @@ dialog:not([open]) {
|
|||
|
||||
/* Backdrop (modal mode only — showModal()) */
|
||||
dialog::backdrop {
|
||||
background: color-mix(in oklch, var(--gray-15) 70%, transparent);
|
||||
background: var(--modal-overlay);
|
||||
backdrop-filter: blur(4px);
|
||||
-webkit-backdrop-filter: blur(4px);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -398,12 +398,12 @@
|
|||
|
||||
[data-diff-line="added"] {
|
||||
background: var(--diff-add-bg);
|
||||
color: var(--green-3);
|
||||
color: var(--green-3); /* TODO: map to semantic token — no alias for green-3 (--accent-hover=green-4 is one step darker) */
|
||||
}
|
||||
|
||||
[data-diff-line="added"]::before {
|
||||
content: "+";
|
||||
color: var(--green-5);
|
||||
color: var(--ok); /* --ok = var(--green-5) */
|
||||
}
|
||||
|
||||
[data-diff-line="removed"] {
|
||||
|
|
@ -413,7 +413,7 @@
|
|||
|
||||
[data-diff-line="removed"]::before {
|
||||
content: "−";
|
||||
color: var(--red-6);
|
||||
color: var(--red-6); /* TODO: map to semantic token — no alias for red-6 (--error=red-7, --callout-error=red-5) */
|
||||
}
|
||||
|
||||
[data-diff-line="context"] {
|
||||
|
|
@ -497,12 +497,12 @@
|
|||
/* Light mode adjustments */
|
||||
@media (prefers-color-scheme: light) {
|
||||
[data-redacted] {
|
||||
background: var(--gray-15);
|
||||
background: var(--gray-15); /* TODO: map to semantic token — no alias for absolute black; needed for redaction bar in light mode */
|
||||
}
|
||||
[data-redacted="reveal"]:hover,
|
||||
[data-redacted="reveal"]:focus {
|
||||
background: var(--gray-1);
|
||||
color: var(--gray-15);
|
||||
background: var(--surface-1); /* light mode: --surface-1 = var(--gray-1) */
|
||||
color: var(--gray-15); /* TODO: map to semantic token — no alias for absolute black text in light mode */
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -545,33 +545,33 @@
|
|||
══════════════════════════════════════════════════════════════════════════ */
|
||||
|
||||
/* Subtle accent on AI-generated sections — light left border indicator */
|
||||
[ai-disclosure] {
|
||||
[data-ai-disclosure] {
|
||||
border-left: var(--border-size-2) solid transparent;
|
||||
padding-left: var(--space-3);
|
||||
}
|
||||
|
||||
[ai-disclosure="ai-generated"] {
|
||||
[data-ai-disclosure="ai-generated"] {
|
||||
border-left-color: var(--ai-generated-border);
|
||||
}
|
||||
|
||||
[ai-disclosure="ai-assisted"] {
|
||||
[data-ai-disclosure="ai-assisted"] {
|
||||
border-left-color: var(--ai-assisted-border);
|
||||
}
|
||||
|
||||
/* Autonomous — more distinct: full accent treatment */
|
||||
[ai-disclosure="autonomous"] {
|
||||
[data-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"] {
|
||||
[data-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) "]";
|
||||
[data-ai-disclosure][data-show-disclosure]::after {
|
||||
content: " [" attr(data-ai-disclosure) "]";
|
||||
font-family: var(--font-mono);
|
||||
font-size: var(--text-xs);
|
||||
color: var(--text-dim);
|
||||
|
|
|
|||
|
|
@ -48,82 +48,6 @@
|
|||
padding-inline: var(--space-5);
|
||||
}
|
||||
|
||||
/* Grid layout with responsive stacking */
|
||||
[data-layout="grid-2"] {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
gap: var(--space-4);
|
||||
}
|
||||
|
||||
@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: var(--space-5);
|
||||
}
|
||||
|
||||
[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: var(--space-3) 0;
|
||||
text-align: center;
|
||||
border-right: var(--border-width) 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: var(--border-width) solid var(--border-subtle);
|
||||
}
|
||||
}
|
||||
|
||||
/* Inline definition lists */
|
||||
dl[data-layout="inline"] {
|
||||
display: grid;
|
||||
|
|
@ -247,10 +171,10 @@ dl[data-layout="inline"] dd {
|
|||
/* 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-color: var(--gray-10); /* TODO: map to semantic token — no alias for gray-10 (--border=gray-11; high-contrast needs one step higher) */
|
||||
--border-color-subtle: var(--border-subtle); /* --border-subtle = var(--gray-12) */
|
||||
--text-primary: var(--gray-0); /* TODO: map to semantic token — no alias for gray-0 (--text=gray-1 in dark; high-contrast needs brightest white) */
|
||||
--text-secondary: var(--text-2); /* --text-2 = var(--gray-3) */
|
||||
--border-width: var(--border-size-2);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -571,7 +571,7 @@
|
|||
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
|
||||
var(--surface-1, var(--surface)) 0deg
|
||||
);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
|
|
|||
|
|
@ -57,12 +57,12 @@
|
|||
.chroma .sr,
|
||||
.chroma .s1,
|
||||
.chroma .ss {
|
||||
color: var(--green-4);
|
||||
color: var(--accent-hover); /* --accent-hover = var(--green-4) */
|
||||
}
|
||||
|
||||
/* LiteralStringEscape — \n \t etc — slightly lighter to distinguish */
|
||||
.chroma .se {
|
||||
color: var(--green-3);
|
||||
color: var(--green-3); /* TODO: map to semantic token — no alias for green-3 (--accent-hover=green-4 is one step darker) */
|
||||
}
|
||||
|
||||
/* ── Comments ────────────────────────────────────────────────────────── */
|
||||
|
|
@ -103,7 +103,7 @@
|
|||
.chroma .nf,
|
||||
.chroma .nx,
|
||||
.chroma .py {
|
||||
color: var(--blue-3);
|
||||
color: var(--blue-3); /* TODO: map to semantic token — no alias for blue-3 (--link-hover=blue-4 is one step darker) */
|
||||
}
|
||||
|
||||
/* ── Operators / Punctuation ─────────────────────────────────────────── */
|
||||
|
|
@ -117,14 +117,14 @@
|
|||
/* ── Error ───────────────────────────────────────────────────────────── */
|
||||
|
||||
.chroma .err {
|
||||
color: var(--red-4);
|
||||
color: var(--red-4); /* TODO: map to semantic token — no alias for red-4 (--error=red-7 is much darker; syntax error highlight needs lighter shade) */
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
/* ── Generic diffs / emphasis ────────────────────────────────────────── */
|
||||
|
||||
.chroma .gd { color: var(--red-4); }
|
||||
.chroma .gi { color: var(--green-4); }
|
||||
.chroma .gd { color: var(--red-4); /* TODO: map to semantic token — no alias for red-4; see --diff-remove-text=red-2 but that's even lighter */ }
|
||||
.chroma .gi { color: var(--accent-hover); /* --accent-hover = var(--green-4) */ }
|
||||
.chroma .ge { font-style: italic; }
|
||||
.chroma .gs { font-weight: bold; }
|
||||
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@ body {
|
|||
|
||||
/* ── Hero ──────────────────────────────────────────────────────────── */
|
||||
/* Landing page hero block. Usually <header data-layout="hero">. */
|
||||
/* Base hero — 09-landing.css overrides for full landing pages */
|
||||
[data-layout="hero"] {
|
||||
text-align: center;
|
||||
padding: var(--space-8) var(--space-5);
|
||||
|
|
@ -541,8 +542,8 @@ main[data-layout="prose"],
|
|||
/* Print styles */
|
||||
@media print {
|
||||
[data-layout="report"] {
|
||||
--surface: var(--gray-0);
|
||||
--text: var(--gray-15);
|
||||
--surface: var(--gray-0); /* TODO: map to semantic token — overriding --surface for print; no alias for gray-0 as "print-white" */
|
||||
--text: var(--gray-15); /* TODO: map to semantic token — overriding --text for print; no alias for gray-15 as "print-black" */
|
||||
font-size: 11pt;
|
||||
}
|
||||
|
||||
|
|
|
|||
233
static/palette-test.html
Normal file
233
static/palette-test.html
Normal file
|
|
@ -0,0 +1,233 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>ASW Palette Explorer</title>
|
||||
<link rel="stylesheet" href="https://unpkg.com/open-props/open-props.min.css">
|
||||
<style>
|
||||
* { box-sizing: border-box; margin: 0; }
|
||||
|
||||
body {
|
||||
font-family: system-ui, sans-serif;
|
||||
background: oklch(12% 0.01 250);
|
||||
color: oklch(85% 0.02 250);
|
||||
padding: 2rem;
|
||||
max-width: 900px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
h1 { font-size: 1.5rem; font-weight: 400; margin-bottom: 0.5rem; }
|
||||
h2 { font-size: 1.1rem; font-weight: 400; margin: 2rem 0 1rem; color: oklch(70% 0.02 250); }
|
||||
p { line-height: 1.6; margin-bottom: 1rem; color: oklch(75% 0.02 250); }
|
||||
code { font-family: monospace; background: oklch(18% 0.01 250); padding: 0.15em 0.4em; border-radius: 3px; }
|
||||
|
||||
/* ── Controls ─────────────────────────── */
|
||||
.controls {
|
||||
display: flex; gap: 1.5rem; flex-wrap: wrap;
|
||||
padding: 1.5rem; margin: 1.5rem 0;
|
||||
background: oklch(16% 0.01 250);
|
||||
border-radius: 8px;
|
||||
}
|
||||
.controls label { display: flex; flex-direction: column; gap: 0.3rem; font-size: 0.85rem; }
|
||||
.controls input[type="range"] { width: 200px; }
|
||||
.controls .val { font-family: monospace; font-size: 0.8rem; color: oklch(65% 0.02 250); }
|
||||
|
||||
/* ── Palette strip ────────────────────── */
|
||||
.palette {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(16, 1fr);
|
||||
gap: 2px;
|
||||
margin: 1rem 0;
|
||||
}
|
||||
.swatch {
|
||||
aspect-ratio: 1;
|
||||
border-radius: 4px;
|
||||
display: flex;
|
||||
align-items: end;
|
||||
justify-content: center;
|
||||
font-size: 0.65rem;
|
||||
font-family: monospace;
|
||||
padding: 0.2rem;
|
||||
}
|
||||
.swatch.light-text { color: oklch(95% 0.01 0); }
|
||||
.swatch.dark-text { color: oklch(15% 0.01 0); }
|
||||
|
||||
/* ── Live demo ────────────────────────── */
|
||||
.demo {
|
||||
padding: 2rem;
|
||||
border-radius: 8px;
|
||||
margin: 1.5rem 0;
|
||||
}
|
||||
.demo h3 { font-size: 1.2rem; font-weight: 400; margin-bottom: 0.75rem; }
|
||||
.demo p { margin-bottom: 0.75rem; }
|
||||
.demo a { text-decoration: underline; text-underline-offset: 2px; }
|
||||
.demo .muted { opacity: 0.7; font-size: 0.9rem; }
|
||||
.demo .accent-pill {
|
||||
display: inline-block;
|
||||
padding: 0.3em 0.8em;
|
||||
border-radius: 100px;
|
||||
font-size: 0.85rem;
|
||||
margin: 0.25rem;
|
||||
}
|
||||
|
||||
/* ── Ludo's dark mode spec ─────────────── */
|
||||
.ludo-spec {
|
||||
margin: 2rem 0;
|
||||
padding: 1.5rem;
|
||||
border: 1px solid oklch(25% 0.02 250);
|
||||
border-radius: 8px;
|
||||
}
|
||||
.ludo-spec dt { font-weight: 500; margin-top: 0.75rem; }
|
||||
.ludo-spec dd { margin-left: 0; color: oklch(70% 0.02 250); }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<h1>ASW Palette Explorer</h1>
|
||||
<p>Open Props gives you 16 oklch steps from one <code>--palette-hue</code> value. Drag the slider — the whole palette shifts.</p>
|
||||
|
||||
<div class="controls">
|
||||
<label>
|
||||
Hue <span class="val" id="hue-val">250</span>
|
||||
<input type="range" id="hue" min="0" max="360" value="250">
|
||||
</label>
|
||||
<label>
|
||||
Chroma <span class="val" id="chroma-val">0.15</span>
|
||||
<input type="range" id="chroma" min="0" max="40" value="15">
|
||||
</label>
|
||||
<label>
|
||||
Hue rotate <span class="val" id="rotate-val">0</span>
|
||||
<input type="range" id="rotate" min="0" max="30" value="0">
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<h2>The 16 steps — <code>--color-1</code> to <code>--color-16</code></h2>
|
||||
<div class="palette" id="palette"></div>
|
||||
|
||||
<h2>Your dark mode mapped to this palette</h2>
|
||||
<div class="demo" id="demo">
|
||||
<h3>On the Craft of Invisible Systems</h3>
|
||||
<p>There is a particular quality to systems that work well. They recede. The thermostat that holds a room at precisely the right temperature.</p>
|
||||
<p><a href="#" id="demo-link">A link in blue — the OG HTML blue</a></p>
|
||||
<p class="muted">Muted secondary text for metadata and captions.</p>
|
||||
<div style="margin-top: 1rem;">
|
||||
<span class="accent-pill" id="pill-ok">OK</span>
|
||||
<span class="accent-pill" id="pill-warn">Warn</span>
|
||||
<span class="accent-pill" id="pill-error">Error</span>
|
||||
<span class="accent-pill" id="pill-info">Info</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h2>What this means for ASW</h2>
|
||||
<dl class="ludo-spec">
|
||||
<dt><code>--surface</code> = <code>--color-16</code></dt>
|
||||
<dd>10% lightness — body background. Currently <code>--gray-12</code> (#030507)</dd>
|
||||
|
||||
<dt><code>--surface-1</code> = <code>--color-15</code></dt>
|
||||
<dd>16% lightness — cards, sidebars</dd>
|
||||
|
||||
<dt><code>--text</code> = <code>--color-3</code></dt>
|
||||
<dd>93% lightness — primary text, easy on the eyes (not pure white)</dd>
|
||||
|
||||
<dt><code>--text-2</code> = <code>--color-5</code></dt>
|
||||
<dd>80% lightness — secondary text</dd>
|
||||
|
||||
<dt><code>--text-3</code> = <code>--color-7</code></dt>
|
||||
<dd>66% lightness — muted text</dd>
|
||||
|
||||
<dt><code>--link</code> = blue at hue 250, chroma pushed</dt>
|
||||
<dd>Links stay blue regardless of palette hue — the OG HTML convention</dd>
|
||||
|
||||
<dt><code>--accent</code> = <code>--color-8</code></dt>
|
||||
<dd>58% lightness, peak chroma — the most vivid step in the palette</dd>
|
||||
</dl>
|
||||
|
||||
<p>Change the hue above: 250 = indigo (current), 220 = blue, 145 = green, 45 = amber, 0 = red, 330 = pink. The whole surface/text system shifts. Links stay blue.</p>
|
||||
|
||||
<script>
|
||||
// oklch palette definition (matching Open Props)
|
||||
const steps = [
|
||||
{ l: 98, cm: 0.03 }, // 1
|
||||
{ l: 97, cm: 0.06 }, // 2
|
||||
{ l: 93, cm: 0.10 }, // 3
|
||||
{ l: 93, cm: 0.12 }, // 4 (corrected: OP uses 84 but let's be accurate)
|
||||
{ l: 80, cm: 0.16 }, // 5
|
||||
{ l: 71, cm: 0.19 }, // 6
|
||||
{ l: 66, cm: 0.20 }, // 7
|
||||
{ l: 58, cm: 0.21 }, // 8 ← peak chroma
|
||||
{ l: 53, cm: 0.20 }, // 9
|
||||
{ l: 49, cm: 0.19 }, // 10
|
||||
{ l: 42, cm: 0.17 }, // 11
|
||||
{ l: 35, cm: 0.15 }, // 12
|
||||
{ l: 27, cm: 0.12 }, // 13
|
||||
{ l: 20, cm: 0.09 }, // 14
|
||||
{ l: 16, cm: 0.07 }, // 15
|
||||
{ l: 10, cm: 0.05 }, // 16
|
||||
];
|
||||
|
||||
// Fix step 4 to match actual OP
|
||||
steps[3].l = 84;
|
||||
|
||||
function color(step, hue, chroma, rotate) {
|
||||
const h = hue + rotate * (step - 1);
|
||||
const c = chroma * steps[step - 1].cm;
|
||||
const l = steps[step - 1].l;
|
||||
return `oklch(${l}% ${c.toFixed(4)} ${h})`;
|
||||
}
|
||||
|
||||
function update() {
|
||||
const hue = +document.getElementById('hue').value;
|
||||
const chroma = +document.getElementById('chroma').value / 100;
|
||||
const rotate = +document.getElementById('rotate').value;
|
||||
|
||||
document.getElementById('hue-val').textContent = hue;
|
||||
document.getElementById('chroma-val').textContent = chroma.toFixed(2);
|
||||
document.getElementById('rotate-val').textContent = rotate;
|
||||
|
||||
// Palette strip
|
||||
const pal = document.getElementById('palette');
|
||||
pal.innerHTML = '';
|
||||
for (let i = 1; i <= 16; i++) {
|
||||
const c = color(i, hue, chroma, rotate);
|
||||
const div = document.createElement('div');
|
||||
div.className = 'swatch ' + (i <= 8 ? 'dark-text' : 'light-text');
|
||||
div.style.background = c;
|
||||
div.textContent = i;
|
||||
pal.appendChild(div);
|
||||
}
|
||||
|
||||
// Demo: Ludo's dark mode
|
||||
const demo = document.getElementById('demo');
|
||||
const surface = color(16, hue, chroma, rotate);
|
||||
const text = color(3, hue, chroma, rotate);
|
||||
const textMuted = color(7, hue, chroma, rotate);
|
||||
// Links stay blue — fixed hue 250
|
||||
const link = `oklch(65% 0.15 250)`;
|
||||
|
||||
demo.style.background = surface;
|
||||
demo.style.color = text;
|
||||
demo.querySelector('h3').style.color = color(2, hue, chroma, rotate);
|
||||
demo.querySelector('.muted').style.color = textMuted;
|
||||
demo.querySelector('a').style.color = link;
|
||||
|
||||
// State pills — these use FIXED hues, not the palette hue
|
||||
const pill = (id, h) => {
|
||||
const el = document.getElementById(id);
|
||||
el.style.background = `oklch(25% 0.04 ${h})`;
|
||||
el.style.color = `oklch(75% 0.15 ${h})`;
|
||||
};
|
||||
pill('pill-ok', 145);
|
||||
pill('pill-warn', 80);
|
||||
pill('pill-error', 25);
|
||||
pill('pill-info', 250);
|
||||
}
|
||||
|
||||
document.getElementById('hue').addEventListener('input', update);
|
||||
document.getElementById('chroma').addEventListener('input', update);
|
||||
document.getElementById('rotate').addEventListener('input', update);
|
||||
update();
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
Loading…
Add table
Add a link
Reference in a new issue