migrate accent colours from HSL to oklch, inject theme into admin

Phase 1: Replace hex_to_hsl with hex_to_oklch in CSSGenerator, output
--t-accent-l/c/h instead of --t-accent-h/s/l. All 46 HSL accent
references across theme-semantic.css, theme-layer2-attributes.css, and
shop/components.css replaced with oklch/color-mix equivalents. Dead
style*= attribute selectors for button variants replaced with proper
class-based selectors. Added color-scheme: light/dark to mood output.

Phase 2: Add LoadTheme plug to admin pipeline, extend AdminLayoutHook
with theme_settings and generated_css assigns, add font preloads and
generated CSS injection to admin_root.html.heex. No visual changes to
admin yet — .themed wrapper added in next phase.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
jamey
2026-02-20 23:53:42 +00:00
parent eb65b11e4d
commit 285aafa0b5
10 changed files with 169 additions and 115 deletions

View File

@@ -131,7 +131,7 @@
/* ── Product prices (shared between cards and PDP) ── */
.product-price--sale {
color: hsl(var(--t-accent-h) var(--t-accent-s) var(--t-accent-l));
color: var(--t-accent);
}
.product-price--compare {
@@ -254,7 +254,7 @@
.hero-pre-title {
font-family: var(--t-font-heading);
font-weight: var(--t-heading-weight);
color: hsl(var(--t-accent-h) var(--t-accent-s) var(--t-accent-l));
color: var(--t-accent);
font-size: var(--t-heading-display);
margin-bottom: 1rem;
}
@@ -398,7 +398,7 @@
}
.accent-link {
color: var(--t-accent-text, hsl(var(--t-accent-h) var(--t-accent-s) 38%));
color: var(--t-accent-text);
text-decoration: none;
cursor: pointer;
font-size: var(--t-text-small);
@@ -457,7 +457,7 @@
.collection-empty-link {
display: inline-block;
margin-top: 1rem;
color: var(--t-text-accent, hsl(var(--t-accent-h) var(--t-accent-s) var(--t-accent-l)));
color: var(--t-text-accent, var(--t-accent));
text-decoration: underline;
}
@@ -518,7 +518,7 @@
}
.pdp-thumbnail-active {
border: 2px solid hsl(var(--t-accent-h) var(--t-accent-s) var(--t-accent-l));
border: 2px solid var(--t-accent);
}
/* ── Variant selector ── */
@@ -556,8 +556,8 @@
padding: 0;
&[aria-pressed="true"] {
border-color: hsl(var(--t-accent-h) var(--t-accent-s) var(--t-accent-l));
--tw-ring-color: hsl(var(--t-accent-h) var(--t-accent-s) var(--t-accent-l));
border-color: var(--t-accent);
--tw-ring-color: var(--t-accent);
}
}
@@ -572,8 +572,8 @@
cursor: pointer;
&[aria-pressed="true"] {
border-color: hsl(var(--t-accent-h) var(--t-accent-s) var(--t-accent-l));
background: hsl(var(--t-accent-h) var(--t-accent-s) var(--t-accent-l) / 0.1);
border-color: var(--t-accent);
background: color-mix(in oklch, var(--t-accent) 10%, transparent);
}
}
@@ -654,7 +654,7 @@
}
.atc-btn {
background-color: hsl(var(--t-accent-h) var(--t-accent-s) var(--t-accent-l));
background-color: var(--t-accent);
color: var(--t-text-inverse);
border-radius: var(--t-radius-button);
border: none;
@@ -762,7 +762,7 @@
/* ── Announcement bar ── */
.announcement-bar {
background-color: var(--t-accent-button, hsl(var(--t-accent-h) var(--t-accent-s) 42%));
background-color: var(--t-accent-button);
color: var(--t-text-inverse);
text-align: center;
padding: 0.5rem 1rem;
@@ -867,7 +867,7 @@
position: absolute;
top: -4px;
right: -4px;
background: hsl(var(--t-accent-h) var(--t-accent-s) var(--t-accent-l));
background: var(--t-accent);
color: var(--t-text-inverse);
font-size: var(--t-text-caption);
font-weight: 600;
@@ -889,7 +889,7 @@
&[aria-current="page"] {
color: var(--t-text-primary);
border-bottom-color: hsl(var(--t-accent-h) var(--t-accent-s) var(--t-accent-l));
border-bottom-color: var(--t-accent);
}
}
@@ -943,9 +943,9 @@
}
&[aria-current="page"] {
color: hsl(var(--t-accent-h) var(--t-accent-s) calc(var(--t-accent-l) - 15%));
color: color-mix(in oklch, var(--t-accent) 80%, black);
font-weight: 600;
background-color: hsl(var(--t-accent-h) var(--t-accent-s) var(--t-accent-l) / 0.1);
background-color: color-mix(in oklch, var(--t-accent) 10%, transparent);
& svg {
width: 1.5rem;
@@ -1273,7 +1273,7 @@
padding: 0.75rem 1.5rem;
font-weight: 600;
transition: all 0.2s ease;
background: var(--t-accent-button, hsl(var(--t-accent-h) var(--t-accent-s) 42%));
background: var(--t-accent-button);
color: var(--t-text-inverse);
border-radius: var(--t-radius-button);
border: none;
@@ -1692,7 +1692,7 @@
/* ── Accent email link ── */
.accent-email {
color: hsl(var(--t-accent-h) var(--t-accent-s) var(--t-accent-l));
color: var(--t-accent);
}
/* ── Card shared styles (info, tracking, newsletter, social cards) ── */
@@ -1767,7 +1767,7 @@
align-items: center;
gap: 0.5rem;
margin-bottom: 0.5rem;
color: hsl(var(--t-accent-h) var(--t-accent-s) var(--t-accent-l));
color: var(--t-accent);
text-decoration: none;
& svg {
@@ -1879,7 +1879,7 @@
.trust-badge-icon {
flex-shrink: 0;
margin-top: 0.125rem;
color: hsl(var(--t-accent-h) var(--t-accent-s) var(--t-accent-l));
color: var(--t-accent);
& svg {
width: 1.25rem;