prototype(#53): palette candidates as runtime token swaps

Throwaway. Tokenises the theme's literal colours so candidate palettes can be
swapped in the browser, adds three candidates (Plum Noir one-metal, two-metal
pewter, two-metal plus a champagne inset), a WCAG checker, a seeder and the
screenshots they are judged on.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-07-31 16:31:41 +02:00
co-authored by Claude Opus 5
parent cfef363107
commit ea36116e62
48 changed files with 743 additions and 393 deletions
+78 -78
View File
@@ -1,13 +1,13 @@
.btn-primary {
--bs-btn-bg: #5a4a1a;
--bs-btn-border-color: #a8893f;
--bs-btn-bg: var(--wg-gold-plate);
--bs-btn-border-color: var(--wg-gold-soft);
--bs-btn-color: #f0e6d8;
--bs-btn-hover-bg: #6a5720;
--bs-btn-hover-border-color: #c2a35a;
--bs-btn-hover-color: #fff4dd;
--bs-btn-hover-bg: var(--wg-gold-plate-hover);
--bs-btn-hover-border-color: var(--wg-gold);
--bs-btn-hover-color: var(--wg-gold-hi);
--bs-btn-active-bg: #493914;
--bs-btn-active-border-color: #c2a35a;
background-image: linear-gradient(to bottom, #5a4a1a 0%, #473914 100%);
--bs-btn-active-border-color: var(--wg-gold);
background-image: linear-gradient(to bottom, var(--wg-gold-plate) 0%, var(--wg-gold-plate-deep) 100%);
box-shadow:
inset 0 1px 0 rgba(255, 255, 255, 0.06),
0 2px 8px rgba(0, 0, 0, 0.24);
@@ -15,7 +15,7 @@
.btn-primary:hover,
.btn-primary:focus {
background-image: linear-gradient(to bottom, #6a5720 0%, #53431a 100%);
background-image: linear-gradient(to bottom, var(--wg-gold-plate-hover) 0%, var(--wg-gold-plate-mid) 100%);
}
.btn-secondary,
@@ -23,13 +23,13 @@
.btn-ghost,
.btn-outline-secondary {
--bs-btn-color: #d8cec0;
--bs-btn-bg: rgba(8, 7, 10, 0.12);
--bs-btn-border-color: rgba(216, 194, 138, 0.28);
--bs-btn-bg: rgba(var(--wg-bg-deepest-rgb), 0.12);
--bs-btn-border-color: rgba(var(--wg-ledger-ink-rgb), 0.28);
--bs-btn-hover-color: var(--wg-text);
--bs-btn-hover-bg: rgba(194, 163, 90, 0.075);
--bs-btn-hover-border-color: rgba(216, 194, 138, 0.44);
--bs-btn-active-bg: rgba(194, 163, 90, 0.12);
--bs-btn-active-border-color: rgba(216, 194, 138, 0.5);
--bs-btn-hover-bg: rgba(var(--wg-gold-rgb), 0.075);
--bs-btn-hover-border-color: rgba(var(--wg-ledger-ink-rgb), 0.44);
--bs-btn-active-bg: rgba(var(--wg-gold-rgb), 0.12);
--bs-btn-active-border-color: rgba(var(--wg-ledger-ink-rgb), 0.5);
background-image: linear-gradient(
to bottom,
rgba(255, 244, 221, 0.018),
@@ -39,36 +39,36 @@
}
.btn-light {
--bs-btn-hover-bg: rgba(194, 163, 90, 0.09);
--bs-btn-hover-border-color: rgba(216, 194, 138, 0.5);
--bs-btn-active-bg: rgba(194, 163, 90, 0.15);
--bs-btn-active-border-color: rgba(216, 194, 138, 0.56);
--bs-btn-hover-bg: rgba(var(--wg-gold-rgb), 0.09);
--bs-btn-hover-border-color: rgba(var(--wg-ledger-ink-rgb), 0.5);
--bs-btn-active-bg: rgba(var(--wg-gold-rgb), 0.15);
--bs-btn-active-border-color: rgba(var(--wg-ledger-ink-rgb), 0.56);
}
// core's guest sign-up prompt ships btn-warning/btn-info: remap to the
// theme's two button voices (dark gold plate + ghost)
.guest-cta-alert .btn-warning {
--bs-btn-bg: #5a4a1a;
--bs-btn-border-color: #a8893f;
--bs-btn-bg: var(--wg-gold-plate);
--bs-btn-border-color: var(--wg-gold-soft);
--bs-btn-color: #f0e6d8;
--bs-btn-hover-bg: #6a5720;
--bs-btn-hover-border-color: #c2a35a;
--bs-btn-hover-color: #fff4dd;
--bs-btn-hover-bg: var(--wg-gold-plate-hover);
--bs-btn-hover-border-color: var(--wg-gold);
--bs-btn-hover-color: var(--wg-gold-hi);
--bs-btn-active-bg: #493914;
--bs-btn-active-border-color: #c2a35a;
--bs-btn-active-color: #fff4dd;
background-image: linear-gradient(to bottom, #5a4a1a 0%, #473914 100%);
--bs-btn-active-border-color: var(--wg-gold);
--bs-btn-active-color: var(--wg-gold-hi);
background-image: linear-gradient(to bottom, var(--wg-gold-plate) 0%, var(--wg-gold-plate-deep) 100%);
}
.guest-cta-alert .btn-info {
--bs-btn-color: #d8cec0;
--bs-btn-bg: rgba(8, 7, 10, 0.12);
--bs-btn-border-color: rgba(216, 194, 138, 0.28);
--bs-btn-bg: rgba(var(--wg-bg-deepest-rgb), 0.12);
--bs-btn-border-color: rgba(var(--wg-ledger-ink-rgb), 0.28);
--bs-btn-hover-color: var(--wg-text);
--bs-btn-hover-bg: rgba(194, 163, 90, 0.075);
--bs-btn-hover-border-color: rgba(216, 194, 138, 0.44);
--bs-btn-active-bg: rgba(194, 163, 90, 0.12);
--bs-btn-active-border-color: rgba(216, 194, 138, 0.5);
--bs-btn-hover-bg: rgba(var(--wg-gold-rgb), 0.075);
--bs-btn-hover-border-color: rgba(var(--wg-ledger-ink-rgb), 0.44);
--bs-btn-active-bg: rgba(var(--wg-gold-rgb), 0.12);
--bs-btn-active-border-color: rgba(var(--wg-ledger-ink-rgb), 0.5);
--bs-btn-active-color: var(--wg-text);
background-image: none;
}
@@ -84,12 +84,12 @@
.modal-footer .btn[data-bs-dismiss="modal"],
.modal-footer .btn[data-dismiss="modal"] {
--bs-btn-color: #d8cec0;
--bs-btn-bg: rgba(8, 7, 10, 0.16);
--bs-btn-border-color: rgba(216, 194, 138, 0.34);
--bs-btn-hover-color: #fff4dd;
--bs-btn-hover-bg: rgba(194, 163, 90, 0.09);
--bs-btn-hover-border-color: rgba(216, 194, 138, 0.52);
--bs-btn-active-bg: rgba(194, 163, 90, 0.13);
--bs-btn-bg: rgba(var(--wg-bg-deepest-rgb), 0.16);
--bs-btn-border-color: rgba(var(--wg-ledger-ink-rgb), 0.34);
--bs-btn-hover-color: var(--wg-gold-hi);
--bs-btn-hover-bg: rgba(var(--wg-gold-rgb), 0.09);
--bs-btn-hover-border-color: rgba(var(--wg-ledger-ink-rgb), 0.52);
--bs-btn-active-bg: rgba(var(--wg-gold-rgb), 0.13);
background-image: linear-gradient(
to bottom,
rgba(255, 244, 221, 0.024),
@@ -115,7 +115,7 @@
[component="topic/quickreply/container"] .card,
[component="topic/quickreply/container"] .card-body {
background-color: rgba(18, 15, 22, 0.96) !important;
border-color: rgba(194, 163, 90, 0.18) !important;
border-color: rgba(var(--wg-gold-rgb), 0.18) !important;
color: var(--wg-text) !important;
}
@@ -147,17 +147,17 @@ input[type="number"].form-control::-webkit-outer-spin-button {
.form-check-input[role="switch"] {
background-color: rgba(255, 244, 221, 0.08) !important;
background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='%23d8c28a'/%3e%3c/svg%3e") !important;
border-color: rgba(216, 194, 138, 0.26) !important;
border-color: rgba(var(--wg-ledger-ink-rgb), 0.26) !important;
box-shadow:
inset 0 1px 2px rgba(0, 0, 0, 0.48),
0 0 0 1px rgba(8, 7, 10, 0.46) !important;
0 0 0 1px rgba(var(--wg-bg-deepest-rgb), 0.46) !important;
cursor: pointer;
}
.form-switch .form-check-input:hover,
.form-check-input[role="switch"]:hover {
background-color: rgba(255, 244, 221, 0.12) !important;
border-color: rgba(216, 194, 138, 0.38) !important;
border-color: rgba(var(--wg-ledger-ink-rgb), 0.38) !important;
}
.form-switch .form-check-input:checked,
@@ -172,10 +172,10 @@ input[type="number"].form-control::-webkit-outer-spin-button {
.form-switch .form-check-input:focus,
.form-check-input[role="switch"]:focus {
border-color: rgba(216, 194, 138, 0.5) !important;
border-color: rgba(var(--wg-ledger-ink-rgb), 0.5) !important;
box-shadow:
inset 0 1px 2px rgba(0, 0, 0, 0.42),
0 0 0 1px rgba(194, 163, 90, 0.3) !important;
0 0 0 1px rgba(var(--wg-gold-rgb), 0.3) !important;
}
.quick-reply .card,
@@ -213,7 +213,7 @@ input[type="number"].form-control::-webkit-outer-spin-button {
.composer input:focus,
.composer .CodeMirror-focused {
background-color: rgba(255, 255, 255, 0.04) !important;
border-color: rgba(194, 163, 90, 0.5) !important;
border-color: rgba(var(--wg-gold-rgb), 0.5) !important;
box-shadow:
inset 0 1px 0 rgba(255, 255, 255, 0.026),
0 0 0 1px var(--wg-focus) !important;
@@ -250,17 +250,17 @@ table[component="notification/table"],
li[component="post"] .content table {
--bs-table-bg: transparent;
--bs-table-color: var(--wg-text-soft);
--bs-table-border-color: rgba(194, 163, 90, 0.16);
--bs-table-striped-bg: rgba(194, 163, 90, 0.035);
--bs-table-border-color: rgba(var(--wg-gold-rgb), 0.16);
--bs-table-striped-bg: rgba(var(--wg-gold-rgb), 0.035);
--bs-table-striped-color: var(--wg-text-soft);
--bs-table-hover-bg: rgba(194, 163, 90, 0.04);
--bs-table-hover-bg: rgba(var(--wg-gold-rgb), 0.04);
--bs-table-hover-color: var(--wg-text);
color: var(--wg-text-soft) !important;
}
// classless markdown tables in posts don't get Bootstrap's .table variables
li[component="post"] .content table :where(th, td) {
border-color: rgba(194, 163, 90, 0.16);
border-color: rgba(var(--wg-gold-rgb), 0.16);
}
table[component="notification/table"] :where(th, td, label) {
@@ -277,7 +277,7 @@ li[component="post"] .content table thead :where(th, td) {
}
table[component="notification/table"] tbody tr {
border-color: rgba(194, 163, 90, 0.1) !important;
border-color: rgba(var(--wg-gold-rgb), 0.1) !important;
}
table[component="notification/table"] a[data-type] {
@@ -296,13 +296,13 @@ table[component="notification/table"] a[data-type] {
table[component="notification/table"] a[data-type]:hover,
table[component="notification/table"] a[data-type]:focus {
background-color: rgba(194, 163, 90, 0.075);
background-color: rgba(var(--wg-gold-rgb), 0.075);
color: var(--wg-text);
}
.tool-modal {
background: transparent !important;
border-color: rgba(194, 163, 90, 0.16) !important;
border-color: rgba(var(--wg-gold-rgb), 0.16) !important;
}
.tool-modal .bootstrap-tagsinput {
@@ -316,7 +316,7 @@ table[component="notification/table"] a[data-type]:focus {
linear-gradient(
to bottom,
transparent calc(100% - 1px),
rgba(194, 163, 90, 0.055) calc(100% - 1px)
rgba(var(--wg-gold-rgb), 0.055) calc(100% - 1px)
),
rgba(12, 10, 15, 0.92) !important;
background-size:
@@ -337,10 +337,10 @@ table[component="notification/table"] a[data-type]:focus {
padding: 0.2rem 0.48rem !important;
background: linear-gradient(
to bottom,
rgba(216, 194, 138, 0.13),
rgba(var(--wg-ledger-ink-rgb), 0.13),
rgba(70, 45, 52, 0.28)
) !important;
border: 1px solid rgba(194, 163, 90, 0.3) !important;
border: 1px solid rgba(var(--wg-gold-rgb), 0.3) !important;
border-radius: 3px !important;
color: #e5d6b5 !important;
font-family: var(--wg-font-ui);
@@ -370,7 +370,7 @@ table[component="notification/table"] a[data-type]:focus {
rgba(23, 19, 28, 0.99),
rgba(12, 10, 15, 0.99)
) !important;
border: 1px solid rgba(194, 163, 90, 0.22) !important;
border: 1px solid rgba(var(--wg-gold-rgb), 0.22) !important;
border-radius: 4px;
box-shadow: 0 12px 24px rgba(0, 0, 0, 0.42);
}
@@ -399,13 +399,13 @@ table[component="notification/table"] a[data-type]:focus {
linear-gradient(
to bottom,
transparent calc(100% - 1px),
rgba(194, 163, 90, 0.055) calc(100% - 1px)
rgba(var(--wg-gold-rgb), 0.055) calc(100% - 1px)
),
var(--wg-velvet-panel) !important;
background-size:
100% var(--wg-ledger-line),
auto;
border-color: rgba(194, 163, 90, 0.18) !important;
border-color: rgba(var(--wg-gold-rgb), 0.18) !important;
color: var(--wg-text-soft) !important;
}
@@ -447,7 +447,7 @@ table[component="notification/table"] a[data-type]:focus {
.composer .title-container input:focus,
.composer .title-container .form-control:focus {
border-color: rgba(194, 163, 90, 0.5) !important;
border-color: rgba(var(--wg-gold-rgb), 0.5) !important;
box-shadow: none !important;
}
@@ -457,7 +457,7 @@ table[component="notification/table"] a[data-type]:focus {
.quick-reply .btn,
[component="topic/quickreply/container"] .btn {
color: var(--wg-text-soft) !important;
border-color: rgba(194, 163, 90, 0.12) !important;
border-color: rgba(var(--wg-gold-rgb), 0.12) !important;
}
.composer .formatting-bar .btn:hover,
@@ -480,14 +480,14 @@ table[component="notification/table"] a[data-type]:focus {
rgba(23, 19, 28, 0.98),
rgba(13, 12, 17, 0.99)
) !important;
border-color: rgba(194, 163, 90, 0.16) !important;
border-color: rgba(var(--wg-gold-rgb), 0.16) !important;
color: var(--wg-text-soft) !important;
}
.nav-tabs,
.nav-pills,
.list-group {
border-color: rgba(194, 163, 90, 0.12) !important;
border-color: rgba(var(--wg-gold-rgb), 0.12) !important;
}
.nav-tabs .nav-link,
@@ -499,8 +499,8 @@ table[component="notification/table"] a[data-type]:focus {
.nav-tabs .nav-link.active,
.nav-pills .nav-link.active,
.list-group-item.active {
background: rgba(194, 163, 90, 0.12) !important;
border-color: rgba(194, 163, 90, 0.26) !important;
background: rgba(var(--wg-gold-rgb), 0.12) !important;
border-color: rgba(var(--wg-gold-rgb), 0.26) !important;
color: var(--wg-text) !important;
}
@@ -510,7 +510,7 @@ table[component="notification/table"] a[data-type]:focus {
rgba(24, 20, 29, 0.98),
rgba(17, 15, 21, 0.99)
) !important;
border: 1px solid rgba(194, 163, 90, 0.16) !important;
border: 1px solid rgba(var(--wg-gold-rgb), 0.16) !important;
border-radius: 8px;
box-shadow: 0 12px 30px rgba(0, 0, 0, 0.34);
}
@@ -542,21 +542,21 @@ table[component="notification/table"] a[data-type]:focus {
.page-link {
background: rgba(255, 255, 255, 0.018);
border-color: rgba(194, 163, 90, 0.1);
border-color: rgba(var(--wg-gold-rgb), 0.1);
color: var(--wg-text-soft);
}
.page-link:hover,
.page-link:focus,
.active > .page-link {
background: rgba(194, 163, 90, 0.12);
border-color: rgba(194, 163, 90, 0.25);
background: rgba(var(--wg-gold-rgb), 0.12);
border-color: rgba(var(--wg-gold-rgb), 0.25);
color: var(--wg-text);
}
.tooltip-inner {
background: #221c24 !important;
border: 1px solid rgba(194, 163, 90, 0.65) !important;
border: 1px solid rgba(var(--wg-gold-rgb), 0.65) !important;
border-radius: 6px !important;
color: var(--wg-text) !important;
box-shadow:
@@ -576,7 +576,7 @@ table[component="notification/table"] a[data-type]:focus {
rgba(20, 18, 25, 0.96),
rgba(13, 12, 17, 0.98)
) !important;
border-color: rgba(194, 163, 90, 0.12) !important;
border-color: rgba(var(--wg-gold-rgb), 0.12) !important;
color: var(--wg-text-soft) !important;
}
@@ -593,10 +593,10 @@ table[component="notification/table"] a[data-type]:focus {
[component="sidebar/right"] .nav-link[aria-current="page"],
.bottombar-nav .nav-link.active,
.bottombar-nav .nav-link[aria-current="page"] {
background: rgba(194, 163, 90, 0.1) !important;
background: rgba(var(--wg-gold-rgb), 0.1) !important;
color: var(--wg-text) !important;
box-shadow:
inset 0 0 0 1px rgba(194, 163, 90, 0.12),
inset 0 0 0 1px rgba(var(--wg-gold-rgb), 0.12),
inset 0 1px 0 rgba(255, 244, 221, 0.035);
}
@@ -629,14 +629,14 @@ table[component="notification/table"] a[data-type]:focus {
.page-flags [component="flags/filters"] .btn-warning {
--bs-btn-color: var(--wg-text-soft);
--bs-btn-bg: rgba(8, 7, 10, 0.12);
--bs-btn-border-color: rgba(216, 194, 138, 0.28);
--bs-btn-bg: rgba(var(--wg-bg-deepest-rgb), 0.12);
--bs-btn-border-color: rgba(var(--wg-ledger-ink-rgb), 0.28);
--bs-btn-hover-color: var(--wg-text);
--bs-btn-hover-bg: rgba(194, 163, 90, 0.09);
--bs-btn-hover-border-color: rgba(216, 194, 138, 0.46);
--bs-btn-hover-bg: rgba(var(--wg-gold-rgb), 0.09);
--bs-btn-hover-border-color: rgba(var(--wg-ledger-ink-rgb), 0.46);
--bs-btn-active-color: var(--wg-text);
--bs-btn-active-bg: rgba(194, 163, 90, 0.12);
--bs-btn-active-border-color: rgba(216, 194, 138, 0.5);
--bs-btn-active-bg: rgba(var(--wg-gold-rgb), 0.12);
--bs-btn-active-border-color: rgba(var(--wg-ledger-ink-rgb), 0.5);
background-image: linear-gradient(
to bottom,
rgba(255, 244, 221, 0.018),