chore(release): redesign UI tokens and publish styles 0.8.26, ui 0.8.86

Visual-only redesign ("instrument panel"): cool graphite neutrals for light
and dark, layered hairline elevation, larger radii, a mono token for
eyebrows/data, keycap-style solid and secondary buttons, recessed input
wells and tab tracks, a stronger dialog, and a theme-driven focus outline.
No props, outputs or behaviour change.

Also records the already-published csr 0.8.42, styles 0.8.25 and ui 0.8.85
changes (optional chaining/nullish in the reactive runtime, shared
theme/accent cookie sync, BackToTop hidden attribute).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
ClintchizandClaude Opus 5.5 committed 2026-09-30 12:00:27 +05:30
1 parent f4eaf416be
commit 1179fc2810
16 files changed
+322 -108

No files matched your search

+5
View File
@@ -36,6 +36,7 @@ component BackToTop {
data-show-label='{showLabel ? "true" : "false"}'
data-progress='{showProgress ? "true" : "false"}'
data-show='{alwaysVisible || visible}'
hidden='{!alwaysVisible && !visible}'
class='wrn-back-to-top {class}'
style='--wrn-back-to-top-progress: {progress}%;'
@window:scroll='visible = window.scrollY >= threshold; progress = Math.min(100, Math.max(0, Math.round((window.scrollY / Math.max(1, document.documentElement.scrollHeight - window.innerHeight)) * 100)))'
@@ -58,6 +59,10 @@ component BackToTop {
}
style {
.wrn-back-to-top[hidden] {
display: none;
}
.wrn-back-to-top {
--back-accent: var(--wrn-color-primary);
--back-accent-hover: var(--wrn-color-primary-hover);
+3 -3
View File
@@ -377,9 +377,9 @@ component Card {
width: 100%;
min-width: 0;
border: 1px solid var(--wrn-color-border);
border-radius: var(--wrn-radius-md);
border-radius: var(--wrn-radius);
background: var(--wrn-color-surface);
box-shadow: none;
box-shadow: var(--wrn-shadow-1);
transition:
transform var(--wrn-motion-base) var(--wrn-ease-emphasized),
border-color var(--wrn-motion-base) ease,
@@ -404,7 +404,7 @@ component Card {
align-items: center;
justify-content: space-between;
padding: 0.85rem var(--wrn-card-padding);
background: var(--wrn-color-surface-2);
background: var(--wrn-color-surface-soft, var(--wrn-color-surface-2));
color: var(--wrn-color-muted);
font-size: 0.875rem;
}
+6 -2
View File
@@ -223,7 +223,9 @@ component Tabs {
padding: 0.25rem;
border: 1px solid var(--wrn-color-border);
border-radius: var(--wrn-radius-md);
background: var(--wrn-color-surface-soft);
background: var(--wrn-color-surface-muted, var(--wrn-color-surface-soft));
/* Recessed track; the selected tab sits proud of it like a keycap. */
box-shadow: inset 0 1px 2px rgb(0 0 0 / 0.05);
/* A long tablist scrolls rather than wrapping into an unusable stack. */
overflow-x: auto;
}
@@ -279,7 +281,9 @@ component Tabs {
background: var(--wrn-color-surface);
/* Small text on the accent alone misses 4.5:1, so it blends toward the text colour. */
color: color-mix(in srgb, var(--tabs-accent) 72%, var(--wrn-color-text));
box-shadow: var(--wrn-shadow-1);
box-shadow:
0 0 0 1px color-mix(in srgb, var(--wrn-color-border) 80%, transparent),
var(--wrn-shadow-1);
}
.wrn-tabs__tab[aria-disabled="true"] {
+43 -11
View File
@@ -205,9 +205,10 @@ label: string = "Button"
font-size: 0.875rem;
font-weight: 600;
line-height: 1;
letter-spacing: -0.006em;
border: 1px solid transparent;
border-radius: var(--wrn-radius-sm);
padding: 0 0.75rem;
padding: 0 0.875rem;
cursor: pointer;
text-decoration: none;
min-height: var(--wrn-control-height, 2.5rem);
@@ -219,10 +220,10 @@ label: string = "Button"
transform var(--wrn-motion-base) var(--wrn-ease-emphasized);
}
.wrn-btn:active {
transform: scale(0.98);
transform: translateY(1px);
}
.wrn-btn:focus-visible {
outline: 2px solid var(--wrn-color-primary);
outline: 2px solid color-mix(in srgb, var(--wrn-btn-color) 80%, transparent);
outline-offset: 2px;
}
.wrn-btn--color-primary {
@@ -254,23 +255,48 @@ label: string = "Button"
.wrn-btn--default,
.wrn-btn--solid,
.wrn-btn--primary {
/* Keycap: a lit top edge and a weighted bottom border give solid actions
a physical press; :active drops the key 1px and flattens the edge. */
color: var(--wrn-btn-contrast);
background: var(--wrn-btn-color);
box-shadow: var(--wrn-shadow-sm);
background: linear-gradient(
180deg,
color-mix(in srgb, var(--wrn-btn-color) 92%, white),
var(--wrn-btn-color)
);
border-color: color-mix(in srgb, var(--wrn-btn-color) 82%, black);
border-bottom-color: color-mix(in srgb, var(--wrn-btn-color) 64%, black);
box-shadow:
var(--wrn-highlight-edge, inset 0 1px 0 rgb(255 255 255 / 0.2)),
0 1px 2px color-mix(in srgb, var(--wrn-btn-color) 30%, transparent);
}
.wrn-btn--variant-default:hover,
.wrn-btn--variant-solid:hover,
.wrn-btn--default:hover,
.wrn-btn--solid:hover,
.wrn-btn--primary:hover {
background: color-mix(in srgb, var(--wrn-btn-color) 84%, black);
box-shadow: var(--wrn-shadow-sm);
background: linear-gradient(
180deg,
color-mix(in srgb, var(--wrn-btn-color) 94%, white),
color-mix(in srgb, var(--wrn-btn-color) 88%, black)
);
box-shadow:
var(--wrn-highlight-edge, inset 0 1px 0 rgb(255 255 255 / 0.2)),
0 2px 6px -1px color-mix(in srgb, var(--wrn-btn-color) 38%, transparent);
}
.wrn-btn--variant-default:active,
.wrn-btn--variant-solid:active,
.wrn-btn--default:active,
.wrn-btn--solid:active,
.wrn-btn--primary:active {
background: color-mix(in srgb, var(--wrn-btn-color) 86%, black);
box-shadow: inset 0 1px 2px rgb(0 0 0 / 0.18);
}
.wrn-btn--variant-outline,
.wrn-btn--outline {
color: var(--wrn-btn-color);
background: transparent;
border-color: color-mix(in srgb, var(--wrn-btn-color) 55%, var(--wrn-color-border));
background: var(--wrn-color-surface);
border-color: color-mix(in srgb, var(--wrn-btn-color) 40%, var(--wrn-color-border));
box-shadow: var(--wrn-shadow-1);
}
.wrn-btn--variant-outline:hover,
.wrn-btn--outline:hover {
@@ -304,9 +330,15 @@ label: string = "Button"
}
.wrn-btn--variant-secondary,
.wrn-btn--secondary {
/* Neutral keycap: surface body with the same machined edge. */
color: var(--wrn-color-text);
background: color-mix(in srgb, var(--wrn-btn-color) 10%, var(--wrn-color-surface));
border-color: color-mix(in srgb, var(--wrn-btn-color) 24%, var(--wrn-color-border));
background: linear-gradient(
180deg,
var(--wrn-color-surface),
color-mix(in srgb, var(--wrn-btn-color) 5%, var(--wrn-color-surface-soft, var(--wrn-color-surface)))
);
border-color: var(--wrn-color-border);
border-bottom-color: var(--wrn-color-border-strong, var(--wrn-color-border));
box-shadow: var(--wrn-shadow-1);
}
.wrn-btn--variant-secondary:hover,
+13 -3
View File
@@ -295,9 +295,14 @@ component Input {
border-radius: var(--wrn-radius-sm, 6px);
box-shadow: none;
}
.wrn-next--field:not([data-invalid="true"]) :where(input, textarea, select):hover:not(:disabled):not(:focus-visible) {
border-color: var(--wrn-color-input-border-hover, var(--wrn-color-border-strong));
}
.wrn-next--field :where(input, textarea, select):focus-visible {
border-color: var(--wrn-color-primary);
box-shadow: 0 0 0 3px color-mix(in srgb, var(--wrn-color-primary) 16%, transparent);
box-shadow:
inset 0 1px 2px rgb(0 0 0 / 0.04),
0 0 0 3px color-mix(in srgb, var(--wrn-color-primary) 18%, transparent);
}
.wrn-next--field textarea {
resize: vertical;
@@ -349,12 +354,17 @@ component Input {
min-width: 0;
}
.wrn-next__field-control > :is(input, textarea, select) {
/* Recessed well: the inverse of the raised keycap button. */
padding-inline: 0.85rem;
border-color: var(--wrn-color-border);
border-color: var(--wrn-color-input-border, var(--wrn-color-border));
border-radius: var(--wrn-radius-sm);
background: var(--wrn-color-surface);
background: var(--wrn-color-input-background, var(--wrn-color-surface));
box-shadow: inset 0 1px 2px rgb(0 0 0 / 0.04);
font-size: 0.8125rem;
}
.wrn-next__field-control > :is(input, textarea)::placeholder {
color: var(--wrn-color-input-placeholder, var(--wrn-color-muted));
}
.wrn-next__field-control[data-has-icon="true"][data-icon-position="start"] > :is(input, textarea, select) {
padding-inline-start: 2.5rem;
}
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@wrnexus/ui",
"version": "0.8.84",
"version": "0.8.86",
"private": true,
"type": "module",
"main": "src/index.ts",
@@ -8,6 +8,20 @@ import { Window } from "happy-dom";
const source = (name: string) => readFileSync(uiComponentPath(name), "utf8");
describe("account shell UI regressions", () => {
test("BackToTop is hidden in server HTML unless explicitly always visible", async () => {
for (const alwaysVisible of [false, true]) {
const html = await renderComponent(source("BackToTop"), { alwaysVisible });
const server = new Window();
try {
server.document.body.innerHTML = html;
expect(server.document.querySelector(".wrn-back-to-top")?.hasAttribute("hidden")).toBe(
!alwaysVisible,
);
} finally {
await server.happyDOM.close();
}
}
});
test("Drawer has a self-contained close icon and a compact centered mobile header", async () => {
const dom = mountHtml(
await renderComponent(source("Drawer"), { title: "Account center", open: true, duration: 0 }),
+24 -22
View File
@@ -111,8 +111,8 @@
transition-duration: 0.01ms !important;
}
}
:where(button, a):focus-visible {
outline: 2px solid var(--wrn-color-primary);
:where(button, a, summary):focus-visible {
outline: 2px solid var(--wrn-color-focus);
outline-offset: 2px;
}
/* --- Component-system foundations --------------------------------------- */
@@ -122,15 +122,15 @@
}
.wrn-type--display {
font-size: clamp(2.25rem, 7vw, 4.75rem);
line-height: 1.02;
font-weight: 800;
letter-spacing: -0.04em;
line-height: 1;
font-weight: 750;
letter-spacing: -0.045em;
}
.wrn-type--heading {
font-size: clamp(1.25rem, 2vw, 1.75rem);
line-height: 1.1;
font-weight: 600;
letter-spacing: -0.025em;
line-height: 1.15;
font-weight: 650;
letter-spacing: -0.028em;
}
.wrn-type--lead {
font-size: clamp(1.05rem, 2vw, 1.25rem);
@@ -172,8 +172,8 @@
}
.wrn-label {
color: var(--wrn-color-text);
font-size: 0.875rem;
font-weight: 650;
font-size: 0.8125rem;
font-weight: 600;
line-height: 1.4;
}
.wrn-required,
@@ -210,23 +210,24 @@
display: grid;
place-items: center;
padding: 1rem;
background: rgb(0 0 0 / 0.55);
backdrop-filter: blur(4px);
background: rgb(12 13 16 / 0.52);
backdrop-filter: blur(6px);
}
.wrn-dialog {
width: min(100%, 32rem);
max-height: calc(100dvh - 2rem);
overflow: auto;
padding: clamp(1.25rem, 4vw, 2rem);
padding: clamp(1.25rem, 4vw, 1.75rem);
color: var(--wrn-color-text);
background: var(--wrn-color-surface);
border: 1px solid var(--wrn-color-border);
border-radius: var(--wrn-radius);
box-shadow: var(--wrn-shadow-1);
border-radius: var(--wrn-radius-lg);
box-shadow: var(--wrn-shadow-3);
}
.wrn-dialog__title {
margin: 0;
font-size: 1.35rem;
font-size: 1.25rem;
font-weight: 650;
line-height: 1.25;
}
.wrn-dialog__description {
@@ -287,10 +288,11 @@
box-shadow: var(--wrn-shadow-1);
}
.wrn-eyebrow {
color: var(--wrn-color-primary);
font-size: 0.75rem;
font-weight: 750;
letter-spacing: 0.1em;
color: var(--wrn-color-primary-text);
font-family: var(--wrn-font-mono, monospace);
font-size: 0.6875rem;
font-weight: 600;
letter-spacing: 0.08em;
text-transform: uppercase;
}
.wrn-auth-card > .wrn-eyebrow {
@@ -579,8 +581,8 @@
}
.wrn-well,
.wrn-inset-panel {
background: var(--wrn-color-surface-2);
box-shadow: inset 0 1px 2px rgb(0 0 0 / 0.06);
background: var(--wrn-color-surface-soft);
box-shadow: inset 0 1px 2px rgb(0 0 0 / 0.05);
}
.wrn-scroll-area {
max-width: 100%;