Compare commits
No commits in common. "d9641b04850c5b1eae75d9ba42ece60f54f2fb3c" and "376bfb2364f94efef6d1ef6cbbbd9c04b4386f72" have entirely different histories.
d9641b0485
...
376bfb2364
10 changed files with 248 additions and 398 deletions
File diff suppressed because one or more lines are too long
|
|
@ -3,7 +3,6 @@
|
||||||
* ASW semantic layer — builds on Open Props
|
* ASW semantic layer — builds on Open Props
|
||||||
*
|
*
|
||||||
* Open Props (imported in main.css) provides the base scales:
|
* 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
|
* --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
|
* --size-1…15, --font-size-0…8, --font-weight-1…9
|
||||||
* --font-lineheight-0…5, --radius-1…6, --shadow-1…6
|
* --font-lineheight-0…5, --radius-1…6, --shadow-1…6
|
||||||
|
|
@ -17,8 +16,8 @@
|
||||||
* 4. A handful of precise values without direct OP equivalents
|
* 4. A handful of precise values without direct OP equivalents
|
||||||
*
|
*
|
||||||
* To theme ASW:
|
* To theme ASW:
|
||||||
* Set --palette-hue in your own CSS to shift all color-N surfaces/text.
|
* Override semantic aliases at :root in your own CSS.
|
||||||
* Override semantic aliases at :root for finer control.
|
* Use Open Props base tokens (--gray-*, --green-*, --size-*) as values.
|
||||||
*
|
*
|
||||||
* Lineage: absorbed patterns from Pico CSS, Open Props, Charts.css.
|
* Lineage: absorbed patterns from Pico CSS, Open Props, Charts.css.
|
||||||
*/
|
*/
|
||||||
|
|
@ -32,64 +31,57 @@
|
||||||
|
|
||||||
/* ══════════════════════════════════════════════════════════════════
|
/* ══════════════════════════════════════════════════════════════════
|
||||||
DARK THEME (default)
|
DARK THEME (default)
|
||||||
Using Open Props oklch --color-N 16-step palette.
|
Using Open Props oklch gray scale — perceptually uniform steps.
|
||||||
Set --palette-hue to tint all surfaces and text. Example:
|
Set --gray-hue to tint all surfaces. Example:
|
||||||
Trentuna: --palette-hue: 45 (warm amber tint)
|
Trentuna: --gray-hue: 45 (warm amber tint)
|
||||||
vigilio-garden: --palette-hue: 150 (subtle green tint)
|
vigilio-garden: --gray-hue: 150 (subtle green tint)
|
||||||
══════════════════════════════════════════════════════════════════ */
|
══════════════════════════════════════════════════════════════════ */
|
||||||
|
|
||||||
:root {
|
:root {
|
||||||
|
|
||||||
/* ── Palette controls ───────────────────────────────────────────────
|
/* ── Surfaces ──────────────────────────────────────────────────── */
|
||||||
--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;
|
|
||||||
|
|
||||||
/* ── Surfaces — dark end of the 16-step scale ─────────────────── */
|
--surface: var(--gray-12); /* deepest background (oklch 10%) */
|
||||||
|
--surface-1: var(--gray-11); /* cards, sidebars (oklch 18%) */
|
||||||
--surface: var(--color-16); /* ~10% lightness */
|
--surface-2: var(--gray-10); /* hover, raised elements (oklch 25%) */
|
||||||
--surface-1: var(--color-15); /* ~16% */
|
|
||||||
--surface-2: var(--color-14); /* ~20% */
|
|
||||||
--surface-card: var(--surface-1);
|
--surface-card: var(--surface-1);
|
||||||
--surface-hover: var(--surface-2);
|
--surface-hover: var(--surface-2);
|
||||||
|
|
||||||
/* ── Text — light end of the scale ────────────────────────────── */
|
/* ── Text ──────────────────────────────────────────────────────── */
|
||||||
|
|
||||||
--text: var(--color-3); /* 93% lightness */
|
--text: var(--gray-1); /* primary (95% lightness) */
|
||||||
--text-2: var(--color-5); /* 80% */
|
--text-2: var(--gray-3); /* secondary (80%) */
|
||||||
--text-3: var(--color-7); /* 66% */
|
--text-3: var(--gray-5); /* muted (68%) */
|
||||||
--text-dim: var(--color-9); /* 53% */
|
--text-dim: var(--gray-7); /* dim (58%) */
|
||||||
|
|
||||||
/* ── Accent — peak chroma step, palette-driven ─────────────────── */
|
/* ── Accent ────────────────────────────────────────────────────── */
|
||||||
|
|
||||||
--accent: var(--color-8); /* 58%, peak chroma */
|
--accent: var(--green-5);
|
||||||
--accent-hover: var(--color-7); /* 66% */
|
--accent-hover: var(--green-4);
|
||||||
--on-accent: var(--color-16);
|
--on-accent: var(--gray-12);
|
||||||
--accent-focus: oklch(58% 0.15 var(--palette-hue) / 0.35);
|
--accent-focus: color-mix(in oklch, var(--green-5) 35%, transparent);
|
||||||
--accent-subtle: oklch(58% 0.15 var(--palette-hue) / 0.10);
|
--accent-subtle: color-mix(in oklch, var(--green-5) 10%, transparent);
|
||||||
--accent-underline: oklch(58% 0.15 var(--palette-hue) / 0.45);
|
--accent-underline: color-mix(in oklch, var(--green-5) 45%, transparent);
|
||||||
--accent-hover-underline: oklch(66% 0.15 var(--palette-hue) / 0.55);
|
--accent-hover-underline: color-mix(in oklch, var(--green-5) 55%, transparent);
|
||||||
|
|
||||||
/* ── Links — fixed blue hue, not palette-driven ─────────────────
|
/* ── Links ─────────────────────────────────────────────────────── */
|
||||||
Blue is the web convention. Accent is palette-tinted UI chrome. */
|
/* Blue — web convention. Accent (green) reserved for UI chrome. */
|
||||||
|
|
||||||
--link: oklch(65% 0.15 250);
|
--link: var(--blue-5); /* #339af0 */
|
||||||
--link-hover: oklch(72% 0.15 250);
|
--link-hover: var(--blue-4); /* #4dabf7 */
|
||||||
--link-underline: oklch(65% 0.08 250);
|
--link-underline: color-mix(in oklch, var(--blue-5) 40%, transparent);
|
||||||
--link-hover-underline: oklch(72% 0.10 250);
|
--link-hover-underline: color-mix(in oklch, var(--blue-5) 55%, transparent);
|
||||||
--link-focus: oklch(65% 0.06 250);
|
--link-focus: color-mix(in oklch, var(--blue-5) 35%, transparent);
|
||||||
|
|
||||||
/* Secondary accents — fixed hues, not palette-driven */
|
/* Secondary accents — reachable as named aliases */
|
||||||
--accent-blue: oklch(65% 0.15 250); /* matches --link */
|
--accent-blue: var(--blue-5);
|
||||||
--accent-red: oklch(65% 0.18 25); /* matches --error */
|
--accent-red: var(--red-7);
|
||||||
--accent-orange: oklch(75% 0.15 80); /* matches --warn */
|
--accent-orange: var(--yellow-6);
|
||||||
|
|
||||||
/* ── Border ────────────────────────────────────────────────────── */
|
/* ── Border ────────────────────────────────────────────────────── */
|
||||||
|
|
||||||
--border: var(--color-14); /* ~20% lightness */
|
--border: var(--gray-11); /* 37% lightness — visible against 10% bg */
|
||||||
--border-subtle: var(--color-15); /* ~16% lightness */
|
--border-subtle: var(--gray-12); /* 31% lightness — very subtle */
|
||||||
--border-width: 1px;
|
--border-width: 1px;
|
||||||
--outline-width: 2px;
|
--outline-width: 2px;
|
||||||
|
|
||||||
|
|
@ -129,12 +121,12 @@
|
||||||
--h5-weight: var(--font-weight-6); /* 600 */
|
--h5-weight: var(--font-weight-6); /* 600 */
|
||||||
--h6-weight: var(--font-weight-6);
|
--h6-weight: var(--font-weight-6);
|
||||||
|
|
||||||
--h1-color: var(--color-2);
|
--h1-color: var(--text);
|
||||||
--h2-color: var(--color-3);
|
--h2-color: var(--text);
|
||||||
--h3-color: var(--color-3);
|
--h3-color: var(--text);
|
||||||
--h4-color: var(--color-5);
|
--h4-color: var(--text-2);
|
||||||
--h5-color: var(--color-5);
|
--h5-color: var(--text-2);
|
||||||
--h6-color: var(--color-7);
|
--h6-color: var(--text-3);
|
||||||
|
|
||||||
/* ── Spacing aliases ─────────────────────────────────────────────
|
/* ── Spacing aliases ─────────────────────────────────────────────
|
||||||
Open Props sizes: --size-1 (.25rem), --size-2 (.5rem), --size-3 (1rem),
|
Open Props sizes: --size-1 (.25rem), --size-2 (.5rem), --size-3 (1rem),
|
||||||
|
|
@ -182,16 +174,16 @@
|
||||||
|
|
||||||
/* ── Diff viewer tokens ──────────────────────────────────────────── */
|
/* ── Diff viewer tokens ──────────────────────────────────────────── */
|
||||||
|
|
||||||
--diff-add-bg: color-mix(in oklch, var(--ok) 10%, transparent);
|
--diff-add-bg: color-mix(in oklch, var(--green-5) 10%, transparent);
|
||||||
--diff-remove-bg: color-mix(in oklch, var(--error) 10%, transparent);
|
--diff-remove-bg: color-mix(in oklch, var(--red-7) 10%, transparent);
|
||||||
--diff-remove-text: oklch(88% 0.06 25);
|
--diff-remove-text: var(--red-2);
|
||||||
--diff-hunk-bg: color-mix(in oklch, var(--info) 7%, transparent);
|
--diff-hunk-bg: color-mix(in oklch, var(--blue-4) 7%, transparent);
|
||||||
|
|
||||||
/* ── AI-disclosure border tokens ────────────────────────────────── */
|
/* ── AI-disclosure border tokens ────────────────────────────────── */
|
||||||
|
|
||||||
--ai-generated-border: color-mix(in oklch, var(--ok) 25%, transparent);
|
--ai-generated-border: color-mix(in oklch, var(--green-5) 25%, transparent);
|
||||||
--ai-assisted-border: color-mix(in oklch, var(--info) 20%, transparent);
|
--ai-assisted-border: color-mix(in oklch, var(--blue-4) 20%, transparent);
|
||||||
--ai-mixed-border: color-mix(in oklch, var(--warn) 30%, transparent);
|
--ai-mixed-border: color-mix(in oklch, var(--yellow-6) 30%, transparent);
|
||||||
|
|
||||||
/* ── Rhythm ─────────────────────────────────────────────────────── */
|
/* ── Rhythm ─────────────────────────────────────────────────────── */
|
||||||
|
|
||||||
|
|
@ -215,39 +207,39 @@
|
||||||
|
|
||||||
/* ── Inline element tokens ─────────────────────────────────────── */
|
/* ── Inline element tokens ─────────────────────────────────────── */
|
||||||
|
|
||||||
--selection: oklch(65% 0.08 250 / 0.30);
|
--selection: color-mix(in oklch, var(--blue-4) 25%, transparent);
|
||||||
--mark-bg: oklch(45% 0.10 80 / 0.40);
|
--mark-bg: color-mix(in oklch, var(--yellow-6) 20%, transparent);
|
||||||
--mark-color: var(--accent-orange);
|
--mark-color: var(--accent-orange);
|
||||||
--kbd-bg: var(--text);
|
--kbd-bg: var(--text);
|
||||||
--kbd-color: var(--surface);
|
--kbd-color: var(--surface);
|
||||||
--code-color: var(--text-2);
|
--code-color: var(--text-2);
|
||||||
--table-stripe: color-mix(in oklch, var(--color-15) 50%, transparent);
|
--table-stripe: color-mix(in oklch, var(--gray-11) 50%, transparent);
|
||||||
|
|
||||||
/* ── Form tokens ─────────────────────────────────────────────────── */
|
/* ── Form tokens ─────────────────────────────────────────────────── */
|
||||||
|
|
||||||
--input-bg: var(--surface-1);
|
--input-bg: var(--surface-1);
|
||||||
--input-border: var(--border);
|
--input-border: var(--border);
|
||||||
--input-active-bg: var(--surface);
|
--input-active-bg: var(--surface);
|
||||||
--input-selected: color-mix(in oklch, var(--accent) 20%, transparent);
|
--input-selected: color-mix(in oklch, var(--green-5) 20%, transparent);
|
||||||
--input-px: var(--space-4);
|
--input-px: var(--space-4);
|
||||||
--input-py: var(--space-3);
|
--input-py: var(--space-3);
|
||||||
--disabled-opacity: 0.5;
|
--disabled-opacity: 0.5;
|
||||||
|
|
||||||
/* ── State colors — fixed hues, harmonized oklch ─────────────────── */
|
/* ── State colors ─────────────────────────────────────────────────── */
|
||||||
|
|
||||||
--ok: oklch(75% 0.15 145); /* green */
|
--ok: var(--green-5);
|
||||||
--warn: oklch(75% 0.15 80); /* amber */
|
--warn: var(--yellow-5);
|
||||||
--error: oklch(75% 0.15 25); /* red */
|
--error: var(--red-7);
|
||||||
--info: oklch(75% 0.15 250); /* blue */
|
--info: var(--blue-5);
|
||||||
--blocked: var(--color-9);
|
--blocked: var(--gray-5);
|
||||||
|
|
||||||
--error-active: oklch(65% 0.18 25);
|
--error-active: var(--red-9);
|
||||||
--error-focus: oklch(65% 0.06 25);
|
--error-focus: color-mix(in oklch, var(--red-7) 38%, transparent);
|
||||||
|
|
||||||
/* ── Component tokens ─────────────────────────────────────────────── */
|
/* ── Component tokens ─────────────────────────────────────────────── */
|
||||||
|
|
||||||
--track-bg: var(--surface-2); /* progress / meter background */
|
--track-bg: var(--surface-2); /* progress / meter background */
|
||||||
--modal-overlay: color-mix(in oklch, var(--color-16) 80%, transparent);
|
--modal-overlay: color-mix(in oklch, var(--gray-12) 80%, transparent);
|
||||||
--modal-backdrop: blur(0.375rem);
|
--modal-backdrop: blur(0.375rem);
|
||||||
--accordion-active: var(--accent-hover);
|
--accordion-active: var(--accent-hover);
|
||||||
|
|
||||||
|
|
@ -260,19 +252,19 @@
|
||||||
Propose additions to Open Props: data-task, data-callout, data-session.
|
Propose additions to Open Props: data-task, data-callout, data-session.
|
||||||
══════════════════════════════════════════════════════════════════ */
|
══════════════════════════════════════════════════════════════════ */
|
||||||
|
|
||||||
--task-done: var(--ok);
|
--task-done: var(--green-5);
|
||||||
--task-blocked: var(--error);
|
--task-blocked: var(--red-5);
|
||||||
--task-wip: var(--warn);
|
--task-wip: var(--yellow-5);
|
||||||
--task-todo: var(--color-9);
|
--task-todo: var(--gray-5);
|
||||||
|
|
||||||
--callout-info: var(--info);
|
--callout-info: var(--blue-5);
|
||||||
--callout-warn: var(--warn);
|
--callout-warn: var(--yellow-5);
|
||||||
--callout-error: var(--error);
|
--callout-error: var(--red-5);
|
||||||
--callout-note: var(--color-9);
|
--callout-note: var(--gray-5);
|
||||||
|
|
||||||
--session-bg: var(--surface-1);
|
--session-bg: var(--surface-1);
|
||||||
--wikilink: var(--link);
|
--wikilink: var(--blue-4);
|
||||||
--redacted: var(--color-11);
|
--redacted: var(--gray-8);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -285,45 +277,58 @@
|
||||||
:root {
|
:root {
|
||||||
color-scheme: light;
|
color-scheme: light;
|
||||||
|
|
||||||
--surface: var(--color-1); /* 98% */
|
--surface: var(--gray-0); /* 99% lightness */
|
||||||
--surface-1: var(--color-2); /* 97% */
|
--surface-1: var(--gray-1); /* 95% */
|
||||||
--surface-2: var(--color-3); /* 93% */
|
--surface-2: var(--gray-2); /* 88% */
|
||||||
--surface-card: var(--color-1);
|
--surface-card: var(--gray-0);
|
||||||
--surface-hover: var(--color-2);
|
--surface-hover: var(--gray-1);
|
||||||
|
|
||||||
--text: var(--color-14); /* 20% */
|
--text: var(--gray-11); /* 18% — dark but not pure black */
|
||||||
--text-2: var(--color-12); /* 35% */
|
--text-2: var(--gray-11); /* 37% */
|
||||||
--text-3: var(--color-10); /* 49% */
|
--text-3: var(--gray-8); /* 53% */
|
||||||
--text-dim: var(--color-8); /* 58% */
|
--text-dim: var(--gray-6); /* 63% */
|
||||||
|
|
||||||
--accent: var(--color-9); /* 53% — slightly darker for contrast on light */
|
--accent: var(--green-8);
|
||||||
--accent-hover: var(--color-10);
|
--accent-hover: var(--green-9);
|
||||||
--on-accent: var(--color-1);
|
--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(--color-4); /* 84% */
|
--border: var(--gray-3); /* 80% — visible on near-white */
|
||||||
--border-subtle: var(--color-3); /* 93% */
|
--border-subtle: var(--gray-2); /* 88% — very subtle */
|
||||||
|
|
||||||
--link: oklch(45% 0.15 250);
|
--link: var(--blue-8); /* #1971c2 */
|
||||||
--link-hover: oklch(38% 0.15 250);
|
--link-hover: var(--blue-7); /* #1c7ed6 */
|
||||||
--link-underline: oklch(45% 0.08 250);
|
--link-underline: color-mix(in oklch, var(--blue-8) 40%, transparent);
|
||||||
--link-hover-underline: oklch(38% 0.10 250);
|
--link-hover-underline: color-mix(in oklch, var(--blue-8) 55%, transparent);
|
||||||
--link-focus: oklch(45% 0.06 250);
|
--link-focus: color-mix(in oklch, var(--blue-8) 35%, transparent);
|
||||||
|
|
||||||
--h1-color: var(--color-16);
|
--h1-color: var(--gray-12);
|
||||||
--h2-color: var(--color-15);
|
--h2-color: var(--gray-11);
|
||||||
--h3-color: var(--color-14);
|
--h3-color: var(--gray-10);
|
||||||
--h4-color: var(--color-13);
|
--h4-color: var(--gray-12);
|
||||||
--h5-color: var(--color-12);
|
--h5-color: var(--gray-11);
|
||||||
--h6-color: var(--color-11);
|
--h6-color: var(--gray-10);
|
||||||
|
|
||||||
--ok: oklch(40% 0.15 145);
|
--mark-bg: color-mix(in oklch, var(--yellow-6) 15%, var(--surface));
|
||||||
--warn: oklch(40% 0.15 80);
|
--mark-color: var(--gray-12);
|
||||||
--error: oklch(40% 0.15 25);
|
--selection: color-mix(in oklch, var(--blue-8) 20%, transparent);
|
||||||
--info: oklch(40% 0.15 250);
|
|
||||||
|
|
||||||
--mark-bg: oklch(92% 0.08 80);
|
--code-color: var(--text-3);
|
||||||
--mark-color: var(--color-15);
|
--table-stripe: color-mix(in oklch, var(--gray-8) 4%, transparent);
|
||||||
--selection: oklch(80% 0.06 250);
|
|
||||||
|
--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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -84,7 +84,9 @@ figcaption,
|
||||||
button,
|
button,
|
||||||
input,
|
input,
|
||||||
select,
|
select,
|
||||||
textarea {
|
textarea,
|
||||||
|
hgroup > p,
|
||||||
|
hgroup > small {
|
||||||
font-family: var(--font-ui);
|
font-family: var(--font-ui);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -167,6 +169,7 @@ ul {
|
||||||
|
|
||||||
/* Nested lists: reduce spacing */
|
/* Nested lists: reduce spacing */
|
||||||
:where(dl, ol, ul) :where(dl, ol, ul) {
|
:where(dl, ol, ul) :where(dl, ol, ul) {
|
||||||
|
margin: 0;
|
||||||
margin-top: calc(var(--type-space) * 0.25);
|
margin-top: calc(var(--type-space) * 0.25);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -323,8 +326,8 @@ tfoot td {
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Striped tables (class-based but useful) */
|
/* Striped tables (class-based but useful) */
|
||||||
[data-table="striped"] tbody tr:nth-child(odd) th,
|
table.striped tbody tr:nth-child(odd) th,
|
||||||
[data-table="striped"] tbody tr:nth-child(odd) td {
|
table.striped tbody tr:nth-child(odd) td {
|
||||||
background-color: var(--table-stripe);
|
background-color: var(--table-stripe);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -407,7 +410,7 @@ pre[class*="language-"] {
|
||||||
.token.prolog,
|
.token.prolog,
|
||||||
.token.doctype,
|
.token.doctype,
|
||||||
.token.cdata {
|
.token.cdata {
|
||||||
color: var(--gray-6); /* TODO: map to semantic token — no alias for gray-6 (between --text-3: gray-5 and --text-dim: gray-7) */
|
color: var(--gray-6); /* muted: ~55% lightness */
|
||||||
font-style: italic;
|
font-style: italic;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -417,19 +420,19 @@ pre[class*="language-"] {
|
||||||
|
|
||||||
.token.tag,
|
.token.tag,
|
||||||
.token.deleted {
|
.token.deleted {
|
||||||
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) */
|
color: var(--red-4); /* HTML tags, deleted code */
|
||||||
}
|
}
|
||||||
|
|
||||||
.token.attr-name,
|
.token.attr-name,
|
||||||
.token.namespace {
|
.token.namespace {
|
||||||
color: var(--yellow-4); /* TODO: map to semantic token — no alias for yellow-4 (--warn=yellow-5 is close but one step darker) */
|
color: var(--yellow-4); /* attribute names */
|
||||||
}
|
}
|
||||||
|
|
||||||
.token.string,
|
.token.string,
|
||||||
.token.attr-value,
|
.token.attr-value,
|
||||||
.token.char,
|
.token.char,
|
||||||
.token.inserted {
|
.token.inserted {
|
||||||
color: var(--accent-hover); /* strings, values — --accent-hover = var(--green-4) */
|
color: var(--green-4); /* strings, values */
|
||||||
}
|
}
|
||||||
|
|
||||||
.token.number,
|
.token.number,
|
||||||
|
|
@ -446,7 +449,7 @@ pre[class*="language-"] {
|
||||||
|
|
||||||
.token.keyword,
|
.token.keyword,
|
||||||
.token.atrule {
|
.token.atrule {
|
||||||
color: var(--link-hover); /* keywords, @rules — --link-hover = var(--blue-4) */
|
color: var(--blue-4); /* keywords, @rules */
|
||||||
}
|
}
|
||||||
|
|
||||||
.token.function,
|
.token.function,
|
||||||
|
|
@ -455,7 +458,7 @@ pre[class*="language-"] {
|
||||||
}
|
}
|
||||||
|
|
||||||
.token.property {
|
.token.property {
|
||||||
color: var(--info); /* object properties — --info = var(--blue-5) */
|
color: var(--blue-5); /* object properties */
|
||||||
}
|
}
|
||||||
|
|
||||||
.token.operator,
|
.token.operator,
|
||||||
|
|
@ -470,7 +473,7 @@ pre[class*="language-"] {
|
||||||
|
|
||||||
.token.important,
|
.token.important,
|
||||||
.token.variable {
|
.token.variable {
|
||||||
color: var(--warn); /* !important, variables — --warn = var(--yellow-5) */
|
color: var(--yellow-5); /* !important, variables */
|
||||||
font-weight: var(--font-weight-5);
|
font-weight: var(--font-weight-5);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -482,20 +485,20 @@ pre[class*="language-"] {
|
||||||
.token.comment,
|
.token.comment,
|
||||||
.token.prolog,
|
.token.prolog,
|
||||||
.token.doctype,
|
.token.doctype,
|
||||||
.token.cdata { color: var(--gray-6); /* TODO: map to semantic token — no alias for gray-6 in light mode */ }
|
.token.cdata { color: var(--gray-6); }
|
||||||
|
|
||||||
.token.punctuation { color: var(--gray-8); /* TODO: map to semantic token — no alias for gray-8 */ }
|
.token.punctuation { color: var(--gray-8); }
|
||||||
|
|
||||||
.token.tag,
|
.token.tag,
|
||||||
.token.deleted { color: var(--red-8); /* TODO: map to semantic token — no alias for red-8 */ }
|
.token.deleted { color: var(--red-8); }
|
||||||
|
|
||||||
.token.attr-name,
|
.token.attr-name,
|
||||||
.token.namespace { color: var(--yellow-9); /* TODO: map to semantic token — no alias for yellow-9 */ }
|
.token.namespace { color: var(--yellow-9); }
|
||||||
|
|
||||||
.token.string,
|
.token.string,
|
||||||
.token.attr-value,
|
.token.attr-value,
|
||||||
.token.char,
|
.token.char,
|
||||||
.token.inserted { color: var(--green-8); /* TODO: map to semantic token — no alias for green-8 */ }
|
.token.inserted { color: var(--green-8); }
|
||||||
|
|
||||||
.token.number,
|
.token.number,
|
||||||
.token.boolean,
|
.token.boolean,
|
||||||
|
|
@ -506,21 +509,21 @@ pre[class*="language-"] {
|
||||||
.token.builtin { color: var(--teal-8); }
|
.token.builtin { color: var(--teal-8); }
|
||||||
|
|
||||||
.token.keyword,
|
.token.keyword,
|
||||||
.token.atrule { color: var(--blue-8); /* TODO: map to semantic token — no alias for blue-8 */ }
|
.token.atrule { color: var(--blue-8); }
|
||||||
|
|
||||||
.token.function,
|
.token.function,
|
||||||
.token.class-name { color: var(--cyan-9); }
|
.token.class-name { color: var(--cyan-9); }
|
||||||
|
|
||||||
.token.property { color: var(--blue-9); /* TODO: map to semantic token — no alias for blue-9 */ }
|
.token.property { color: var(--blue-9); }
|
||||||
|
|
||||||
.token.operator,
|
.token.operator,
|
||||||
.token.entity,
|
.token.entity,
|
||||||
.token.url { color: var(--gray-8); /* TODO: map to semantic token — no alias for gray-8 in light mode */ }
|
.token.url { color: var(--gray-8); }
|
||||||
|
|
||||||
.token.regex { color: var(--orange-7); }
|
.token.regex { color: var(--orange-7); }
|
||||||
|
|
||||||
.token.important,
|
.token.important,
|
||||||
.token.variable { color: var(--yellow-9); /* TODO: map to semantic token — no alias for yellow-9 */ }
|
.token.variable { color: var(--yellow-9); }
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ── Details / Summary ─────────────────────────────────────────────── */
|
/* ── Details / Summary ─────────────────────────────────────────────── */
|
||||||
|
|
@ -600,7 +603,7 @@ dialog {
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
width: inherit;
|
width: inherit;
|
||||||
min-width: auto;
|
min-width: 100%;
|
||||||
height: inherit;
|
height: inherit;
|
||||||
min-height: 100%;
|
min-height: 100%;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
|
|
|
||||||
|
|
@ -701,7 +701,7 @@ dialog:not([open]) {
|
||||||
|
|
||||||
/* Backdrop (modal mode only — showModal()) */
|
/* Backdrop (modal mode only — showModal()) */
|
||||||
dialog::backdrop {
|
dialog::backdrop {
|
||||||
background: var(--modal-overlay);
|
background: color-mix(in oklch, var(--gray-15) 70%, transparent);
|
||||||
backdrop-filter: blur(4px);
|
backdrop-filter: blur(4px);
|
||||||
-webkit-backdrop-filter: blur(4px);
|
-webkit-backdrop-filter: blur(4px);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -398,12 +398,12 @@
|
||||||
|
|
||||||
[data-diff-line="added"] {
|
[data-diff-line="added"] {
|
||||||
background: var(--diff-add-bg);
|
background: var(--diff-add-bg);
|
||||||
color: var(--green-3); /* TODO: map to semantic token — no alias for green-3 (--accent-hover=green-4 is one step darker) */
|
color: var(--green-3);
|
||||||
}
|
}
|
||||||
|
|
||||||
[data-diff-line="added"]::before {
|
[data-diff-line="added"]::before {
|
||||||
content: "+";
|
content: "+";
|
||||||
color: var(--ok); /* --ok = var(--green-5) */
|
color: var(--green-5);
|
||||||
}
|
}
|
||||||
|
|
||||||
[data-diff-line="removed"] {
|
[data-diff-line="removed"] {
|
||||||
|
|
@ -413,7 +413,7 @@
|
||||||
|
|
||||||
[data-diff-line="removed"]::before {
|
[data-diff-line="removed"]::before {
|
||||||
content: "−";
|
content: "−";
|
||||||
color: var(--red-6); /* TODO: map to semantic token — no alias for red-6 (--error=red-7, --callout-error=red-5) */
|
color: var(--red-6);
|
||||||
}
|
}
|
||||||
|
|
||||||
[data-diff-line="context"] {
|
[data-diff-line="context"] {
|
||||||
|
|
@ -497,12 +497,12 @@
|
||||||
/* Light mode adjustments */
|
/* Light mode adjustments */
|
||||||
@media (prefers-color-scheme: light) {
|
@media (prefers-color-scheme: light) {
|
||||||
[data-redacted] {
|
[data-redacted] {
|
||||||
background: var(--gray-15); /* TODO: map to semantic token — no alias for absolute black; needed for redaction bar in light mode */
|
background: var(--gray-15);
|
||||||
}
|
}
|
||||||
[data-redacted="reveal"]:hover,
|
[data-redacted="reveal"]:hover,
|
||||||
[data-redacted="reveal"]:focus {
|
[data-redacted="reveal"]:focus {
|
||||||
background: var(--surface-1); /* light mode: --surface-1 = var(--gray-1) */
|
background: var(--gray-1);
|
||||||
color: var(--gray-15); /* TODO: map to semantic token — no alias for absolute black text in light mode */
|
color: var(--gray-15);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -545,33 +545,33 @@
|
||||||
══════════════════════════════════════════════════════════════════════════ */
|
══════════════════════════════════════════════════════════════════════════ */
|
||||||
|
|
||||||
/* Subtle accent on AI-generated sections — light left border indicator */
|
/* Subtle accent on AI-generated sections — light left border indicator */
|
||||||
[data-ai-disclosure] {
|
[ai-disclosure] {
|
||||||
border-left: var(--border-size-2) solid transparent;
|
border-left: var(--border-size-2) solid transparent;
|
||||||
padding-left: var(--space-3);
|
padding-left: var(--space-3);
|
||||||
}
|
}
|
||||||
|
|
||||||
[data-ai-disclosure="ai-generated"] {
|
[ai-disclosure="ai-generated"] {
|
||||||
border-left-color: var(--ai-generated-border);
|
border-left-color: var(--ai-generated-border);
|
||||||
}
|
}
|
||||||
|
|
||||||
[data-ai-disclosure="ai-assisted"] {
|
[ai-disclosure="ai-assisted"] {
|
||||||
border-left-color: var(--ai-assisted-border);
|
border-left-color: var(--ai-assisted-border);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Autonomous — more distinct: full accent treatment */
|
/* Autonomous — more distinct: full accent treatment */
|
||||||
[data-ai-disclosure="autonomous"] {
|
[ai-disclosure="autonomous"] {
|
||||||
border-left-color: var(--accent);
|
border-left-color: var(--accent);
|
||||||
border-left-width: var(--border-size-2);
|
border-left-width: var(--border-size-2);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Mixed — yellow/amber to signal blended provenance */
|
/* Mixed — yellow/amber to signal blended provenance */
|
||||||
[data-ai-disclosure="mixed"] {
|
[ai-disclosure="mixed"] {
|
||||||
border-left-color: var(--ai-mixed-border);
|
border-left-color: var(--ai-mixed-border);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Disclosure badge — optional ::after label for verbose mode */
|
/* Disclosure badge — optional ::after label for verbose mode */
|
||||||
[data-ai-disclosure][data-show-disclosure]::after {
|
[ai-disclosure][data-show-disclosure]::after {
|
||||||
content: " [" attr(data-ai-disclosure) "]";
|
content: " [" attr(ai-disclosure) "]";
|
||||||
font-family: var(--font-mono);
|
font-family: var(--font-mono);
|
||||||
font-size: var(--text-xs);
|
font-size: var(--text-xs);
|
||||||
color: var(--text-dim);
|
color: var(--text-dim);
|
||||||
|
|
|
||||||
|
|
@ -48,6 +48,82 @@
|
||||||
padding-inline: var(--space-5);
|
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 */
|
/* Inline definition lists */
|
||||||
dl[data-layout="inline"] {
|
dl[data-layout="inline"] {
|
||||||
display: grid;
|
display: grid;
|
||||||
|
|
@ -171,10 +247,10 @@ dl[data-layout="inline"] dd {
|
||||||
/* Increase contrast for high-contrast preference */
|
/* Increase contrast for high-contrast preference */
|
||||||
@media (prefers-contrast: more) {
|
@media (prefers-contrast: more) {
|
||||||
:root {
|
:root {
|
||||||
--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: var(--gray-10);
|
||||||
--border-color-subtle: var(--border-subtle); /* --border-subtle = var(--gray-12) */
|
--border-color-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-primary: var(--gray-0);
|
||||||
--text-secondary: var(--text-2); /* --text-2 = var(--gray-3) */
|
--text-secondary: var(--gray-3);
|
||||||
--border-width: var(--border-size-2);
|
--border-width: var(--border-size-2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -571,7 +571,7 @@
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
background: conic-gradient(
|
background: conic-gradient(
|
||||||
var(--color, var(--chart-color-1)) 0deg calc(var(--size, 0.5) * 360deg),
|
var(--color, var(--chart-color-1)) 0deg calc(var(--size, 0.5) * 360deg),
|
||||||
var(--surface-1, var(--surface)) 0deg
|
var(--surface-1, var(--gray-15)) 0deg
|
||||||
);
|
);
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
|
|
||||||
|
|
@ -57,12 +57,12 @@
|
||||||
.chroma .sr,
|
.chroma .sr,
|
||||||
.chroma .s1,
|
.chroma .s1,
|
||||||
.chroma .ss {
|
.chroma .ss {
|
||||||
color: var(--accent-hover); /* --accent-hover = var(--green-4) */
|
color: var(--green-4);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* LiteralStringEscape — \n \t etc — slightly lighter to distinguish */
|
/* LiteralStringEscape — \n \t etc — slightly lighter to distinguish */
|
||||||
.chroma .se {
|
.chroma .se {
|
||||||
color: var(--green-3); /* TODO: map to semantic token — no alias for green-3 (--accent-hover=green-4 is one step darker) */
|
color: var(--green-3);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ── Comments ────────────────────────────────────────────────────────── */
|
/* ── Comments ────────────────────────────────────────────────────────── */
|
||||||
|
|
@ -103,7 +103,7 @@
|
||||||
.chroma .nf,
|
.chroma .nf,
|
||||||
.chroma .nx,
|
.chroma .nx,
|
||||||
.chroma .py {
|
.chroma .py {
|
||||||
color: var(--blue-3); /* TODO: map to semantic token — no alias for blue-3 (--link-hover=blue-4 is one step darker) */
|
color: var(--blue-3);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ── Operators / Punctuation ─────────────────────────────────────────── */
|
/* ── Operators / Punctuation ─────────────────────────────────────────── */
|
||||||
|
|
@ -117,14 +117,14 @@
|
||||||
/* ── Error ───────────────────────────────────────────────────────────── */
|
/* ── Error ───────────────────────────────────────────────────────────── */
|
||||||
|
|
||||||
.chroma .err {
|
.chroma .err {
|
||||||
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) */
|
color: var(--red-4);
|
||||||
background: transparent;
|
background: transparent;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ── Generic diffs / emphasis ────────────────────────────────────────── */
|
/* ── Generic diffs / emphasis ────────────────────────────────────────── */
|
||||||
|
|
||||||
.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 .gd { color: var(--red-4); }
|
||||||
.chroma .gi { color: var(--accent-hover); /* --accent-hover = var(--green-4) */ }
|
.chroma .gi { color: var(--green-4); }
|
||||||
.chroma .ge { font-style: italic; }
|
.chroma .ge { font-style: italic; }
|
||||||
.chroma .gs { font-weight: bold; }
|
.chroma .gs { font-weight: bold; }
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -31,7 +31,6 @@ body {
|
||||||
|
|
||||||
/* ── Hero ──────────────────────────────────────────────────────────── */
|
/* ── Hero ──────────────────────────────────────────────────────────── */
|
||||||
/* Landing page hero block. Usually <header data-layout="hero">. */
|
/* Landing page hero block. Usually <header data-layout="hero">. */
|
||||||
/* Base hero — 09-landing.css overrides for full landing pages */
|
|
||||||
[data-layout="hero"] {
|
[data-layout="hero"] {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
padding: var(--space-8) var(--space-5);
|
padding: var(--space-8) var(--space-5);
|
||||||
|
|
@ -542,8 +541,8 @@ main[data-layout="prose"],
|
||||||
/* Print styles */
|
/* Print styles */
|
||||||
@media print {
|
@media print {
|
||||||
[data-layout="report"] {
|
[data-layout="report"] {
|
||||||
--surface: var(--gray-0); /* TODO: map to semantic token — overriding --surface for print; no alias for gray-0 as "print-white" */
|
--surface: var(--gray-0);
|
||||||
--text: var(--gray-15); /* TODO: map to semantic token — overriding --text for print; no alias for gray-15 as "print-black" */
|
--text: var(--gray-15);
|
||||||
font-size: 11pt;
|
font-size: 11pt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,233 +0,0 @@
|
||||||
<!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