From c0165919b3fc98b26fe0069341c2d43d5b8b823d Mon Sep 17 00:00:00 2001 From: Will Miao Date: Sat, 10 Oct 2026 20:41:10 +0800 Subject: [PATCH] fix(theme): readable on-accent text color and unified accent aliases MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Solid-accent buttons used the page text color (--lora-text) or white, which falls below WCAG AA on the mid-bright accent (L 52-72%) in every theme/preset — e.g. ~1.7:1 in dark+solarized, making primary buttons hard to read. Add --color-accent-contrast (dark, low-chroma, same hue, derived per preset) aliased as --text-on-accent, and switch ~90 accent-background selectors (primary/confirm buttons, nav items, chips, badges, checkmarks) to it. Also define the previously dangling --lora-accent-l/c/h, --lora-accent-hover and --lora-accent-light aliases (fixing ~40 dead declarations), replace the hardcoded rgba(--lora-accent-rgb, 79 70 229) fallbacks with oklch channel syntax, and add the missing margin above .template-custom-input in settings. --- static/css/base.css | 16 ++++++++ static/css/components/alphabet-bar.css | 4 +- static/css/components/banner.css | 6 +-- static/css/components/batch-import-modal.css | 6 +-- static/css/components/bulk.css | 2 +- static/css/components/card.css | 4 +- .../css/components/download-batch-summary.css | 2 +- static/css/components/duplicates.css | 4 +- static/css/components/filter-indicator.css | 2 +- static/css/components/header.css | 4 +- static/css/components/import-modal.css | 4 +- static/css/components/initialization.css | 2 +- .../css/components/lora-modal/lora-modal.css | 4 +- .../css/components/lora-modal/preset-tags.css | 2 +- static/css/components/lora-modal/showcase.css | 8 ++-- static/css/components/lora-modal/tag.css | 2 +- .../components/lora-modal/triggerwords.css | 2 +- static/css/components/lora-modal/versions.css | 4 +- static/css/components/menu.css | 10 ++--- static/css/components/modal/_base.css | 10 ++--- .../css/components/modal/download-modal.css | 4 +- static/css/components/modal/help-modal.css | 10 ++--- .../css/components/modal/settings-modal.css | 41 ++++++++++--------- static/css/components/modal/support-modal.css | 4 +- static/css/components/modal/update-modal.css | 14 +++---- static/css/components/recipe-modal.css | 6 +-- static/css/components/search-filter.css | 18 ++++---- static/css/components/shared.css | 2 +- .../css/components/shared/edit-metadata.css | 4 +- static/css/components/sidebar.css | 2 +- static/css/components/toast.css | 4 +- static/css/layout.css | 12 +++--- static/css/onboarding.css | 6 +-- static/css/tokens/colors.css | 7 ++++ 34 files changed, 129 insertions(+), 103 deletions(-) diff --git a/static/css/base.css b/static/css/base.css index 22e351bf..d51e64fc 100644 --- a/static/css/base.css +++ b/static/css/base.css @@ -64,6 +64,14 @@ body { --border-color: var(--border-base); --lora-accent: var(--color-accent); + /* Channel aliases: referenced across components (oklch tints, focus + rings); previously undeclared, so those declarations silently dropped. */ + --lora-accent-l: var(--color-accent-l); + --lora-accent-c: var(--color-accent-c); + --lora-accent-h: var(--color-accent-h); + --lora-accent-hover: var(--color-accent-hover); + --lora-accent-light: var(--color-accent-subtle); + --text-on-accent: var(--color-accent-contrast); --lora-surface: var(--bg-elevated); --lora-surface-solid: var(--bg-elevated-solid); --lora-border: var(--border-subtle); @@ -93,6 +101,14 @@ body { --border-color: var(--border-base); --lora-accent: var(--color-accent); + /* Channel aliases: referenced across components (oklch tints, focus + rings); previously undeclared, so those declarations silently dropped. */ + --lora-accent-l: var(--color-accent-l); + --lora-accent-c: var(--color-accent-c); + --lora-accent-h: var(--color-accent-h); + --lora-accent-hover: var(--color-accent-hover); + --lora-accent-light: var(--color-accent-subtle); + --text-on-accent: var(--color-accent-contrast); --lora-surface: var(--bg-elevated); --lora-surface-solid: var(--bg-elevated-solid); --lora-border: var(--border-subtle); diff --git a/static/css/components/alphabet-bar.css b/static/css/components/alphabet-bar.css index a53c9268..27d32345 100644 --- a/static/css/components/alphabet-bar.css +++ b/static/css/components/alphabet-bar.css @@ -105,14 +105,14 @@ .letter-chip:hover { background: var(--lora-accent); - color: white; + color: var(--text-on-accent); transform: scale(1.1); box-shadow: var(--shadow-md); } .letter-chip.active { background: var(--lora-accent); - color: white; + color: var(--text-on-accent); border-color: var(--lora-accent); } diff --git a/static/css/components/banner.css b/static/css/components/banner.css index 298465bf..6cff9810 100644 --- a/static/css/components/banner.css +++ b/static/css/components/banner.css @@ -80,7 +80,7 @@ /* Primary Action Button */ .banner-action-primary { background: var(--lora-accent); - color: white; + color: var(--text-on-accent); border-color: var(--lora-accent); } @@ -99,7 +99,7 @@ .banner-action-secondary:hover { background: var(--lora-accent); - color: white; + color: var(--text-on-accent); border-color: var(--lora-accent); transform: translateY(-1px); box-shadow: var(--shadow-md); @@ -114,7 +114,7 @@ .banner-action-tertiary:hover { background: var(--lora-accent); - color: white; + color: var(--text-on-accent); transform: translateY(-1px); } diff --git a/static/css/components/batch-import-modal.css b/static/css/components/batch-import-modal.css index 70dd811a..2ef0d549 100644 --- a/static/css/components/batch-import-modal.css +++ b/static/css/components/batch-import-modal.css @@ -93,7 +93,7 @@ content: '\f00c'; font-family: 'Font Awesome 6 Free', sans-serif; font-weight: 900; - color: var(--lora-text); + color: var(--text-on-accent); font-size: 12px; } @@ -120,7 +120,7 @@ white-space: nowrap; padding: 8px 16px; background: var(--lora-accent); - color: var(--lora-text); + color: var(--text-on-accent); border: none; border-radius: var(--border-radius-xs); cursor: pointer; @@ -134,7 +134,7 @@ /* Dark theme adjustments for input-with-button */ [data-theme="dark"] .input-with-button button { background: var(--lora-accent); - color: var(--lora-text); + color: var(--text-on-accent); } [data-theme="dark"] .input-with-button button:hover { diff --git a/static/css/components/bulk.css b/static/css/components/bulk.css index 35d01a7c..e1dd0048 100644 --- a/static/css/components/bulk.css +++ b/static/css/components/bulk.css @@ -13,7 +13,7 @@ width: 24px; height: 24px; background: var(--lora-accent); - color: white; + color: var(--text-on-accent); border-radius: 50%; display: flex; align-items: center; diff --git a/static/css/components/card.css b/static/css/components/card.css index 1f526c8e..73b35fb1 100644 --- a/static/css/components/card.css +++ b/static/css/components/card.css @@ -245,7 +245,7 @@ .show-content-btn { background: var(--lora-accent); - color: white; + color: var(--text-on-accent); border: none; border-radius: var(--border-radius-xs); padding: 4px var(--space-1); @@ -805,7 +805,7 @@ body.hide-card-version .hl-badge { top: 8px; right: 8px; background: var(--lora-accent); - color: white; + color: var(--text-on-accent); border-radius: var(--border-radius-xs); padding: 3px 6px; font-size: 0.75em; diff --git a/static/css/components/download-batch-summary.css b/static/css/components/download-batch-summary.css index bff608e9..ceaacd0b 100644 --- a/static/css/components/download-batch-summary.css +++ b/static/css/components/download-batch-summary.css @@ -45,7 +45,7 @@ align-items: center; gap: var(--space-1); background: var(--lora-accent, #4f46e5); - color: #fff; + color: var(--text-on-accent); border: none; border-radius: var(--border-radius-sm); padding: var(--space-2) var(--space-3); diff --git a/static/css/components/duplicates.css b/static/css/components/duplicates.css index fdcd772b..2edc8869 100644 --- a/static/css/components/duplicates.css +++ b/static/css/components/duplicates.css @@ -277,7 +277,7 @@ top: 10px; left: 10px; background: oklch(var(--color-accent-l) var(--color-accent-c) var(--color-accent-h)); - color: white; + color: var(--text-on-accent); font-size: 12px; padding: 2px 6px; border-radius: var(--border-radius-xs); @@ -616,7 +616,7 @@ html[data-theme="dark"] .help-tooltip { /* Make the active duplicates button more prominent */ #findDuplicatesBtn.active { background: var(--lora-accent); - color: white; + color: var(--text-on-accent); border-color: var(--lora-accent); box-shadow: 0 0 0 2px oklch(var(--color-accent-l) var(--color-accent-c) var(--color-accent-h) / 0.25); position: relative; diff --git a/static/css/components/filter-indicator.css b/static/css/components/filter-indicator.css index d3da000f..cb0989aa 100644 --- a/static/css/components/filter-indicator.css +++ b/static/css/components/filter-indicator.css @@ -4,7 +4,7 @@ align-items: center; gap: 6px; background: var(--lora-accent); - color: white; + color: var(--text-on-accent); border-radius: var(--border-radius-xs); padding: 4px 10px; transition: var(--transition-base); diff --git a/static/css/components/header.css b/static/css/components/header.css index 32f1342e..40a61d77 100644 --- a/static/css/components/header.css +++ b/static/css/components/header.css @@ -104,7 +104,7 @@ .nav-item.active { background-color: var(--lora-accent); - color: white; + color: var(--text-on-accent); } /* Header search - Centered with VS Code command palette style */ @@ -354,7 +354,7 @@ .header-controls>div:hover { background: var(--lora-accent); - color: white; + color: var(--text-on-accent); transform: translateY(-2px); } diff --git a/static/css/components/import-modal.css b/static/css/components/import-modal.css index 81cf1fe5..172cc633 100644 --- a/static/css/components/import-modal.css +++ b/static/css/components/import-modal.css @@ -69,7 +69,7 @@ .toggle-btn.active { background: var(--lora-accent); - color: var(--lora-text); + color: var(--text-on-accent); } .toggle-btn:hover:not(.active) { @@ -433,7 +433,7 @@ white-space: nowrap; padding: 8px 16px; background: var(--lora-accent); - color: var(--lora-text); + color: var(--text-on-accent); border: none; border-radius: var(--border-radius-xs); cursor: pointer; diff --git a/static/css/components/initialization.css b/static/css/components/initialization.css index f8e165ab..dc4ff849 100644 --- a/static/css/components/initialization.css +++ b/static/css/components/initialization.css @@ -125,7 +125,7 @@ .stage-item.active .stage-icon { background: var(--lora-accent); - color: white; + color: var(--text-on-accent); } .stage-item.completed .stage-icon { diff --git a/static/css/components/lora-modal/lora-modal.css b/static/css/components/lora-modal/lora-modal.css index cc2b77d9..be37e127 100644 --- a/static/css/components/lora-modal/lora-modal.css +++ b/static/css/components/lora-modal/lora-modal.css @@ -473,7 +473,7 @@ .modal-content .back-to-top:hover { background: var(--lora-accent); - color: white; + color: var(--text-on-accent); transform: translateY(-2px); } @@ -1262,7 +1262,7 @@ .creator-placeholder { background: var(--lora-accent); - color: white; + color: var(--text-on-accent); display: flex; align-items: center; justify-content: center; diff --git a/static/css/components/lora-modal/preset-tags.css b/static/css/components/lora-modal/preset-tags.css index c11d4f76..a7ee06fa 100644 --- a/static/css/components/lora-modal/preset-tags.css +++ b/static/css/components/lora-modal/preset-tags.css @@ -56,7 +56,7 @@ .add-preset-btn { padding: calc(var(--space-1) * 0.5) var(--space-2); background: var(--lora-accent); - color: var(--lora-text); + color: var(--text-on-accent); border: none; border-radius: var(--border-radius-xs); cursor: pointer; diff --git a/static/css/components/lora-modal/showcase.css b/static/css/components/lora-modal/showcase.css index d093fa10..1afe3d73 100644 --- a/static/css/components/lora-modal/showcase.css +++ b/static/css/components/lora-modal/showcase.css @@ -330,7 +330,7 @@ .showcase-layout-toggle .layout-toggle-btn.active { background: var(--lora-accent); - color: var(--lora-text); + color: var(--text-on-accent); } /* Vertical list layout (showcase_layout = vertical): every example stacked @@ -446,7 +446,7 @@ .media-control-btn.set-preview-btn:hover { background: var(--lora-accent); - color: white; + color: var(--text-on-accent); border-color: var(--lora-accent); } @@ -805,7 +805,7 @@ .select-files-btn { background: var(--lora-accent); - color: var(--lora-text); + color: var(--text-on-accent); border: none; border-radius: var(--border-radius-xs); padding: var(--space-2) var(--space-3); @@ -891,7 +891,7 @@ .setup-settings-btn { margin-top: var(--space-2); background: var(--lora-accent) !important; - color: var(--lora-text) !important; + color: var(--text-on-accent) !important; } .setup-settings-btn:hover { diff --git a/static/css/components/lora-modal/tag.css b/static/css/components/lora-modal/tag.css index 4ee49d43..921c4941 100644 --- a/static/css/components/lora-modal/tag.css +++ b/static/css/components/lora-modal/tag.css @@ -62,7 +62,7 @@ .model-tag-more { background: var(--lora-accent); - color: var(--lora-text); + color: var(--text-on-accent); border-radius: var(--border-radius-xs); padding: 2px 8px; font-size: 0.75em; diff --git a/static/css/components/lora-modal/triggerwords.css b/static/css/components/lora-modal/triggerwords.css index e44b93c3..b4b1a860 100644 --- a/static/css/components/lora-modal/triggerwords.css +++ b/static/css/components/lora-modal/triggerwords.css @@ -140,7 +140,7 @@ .token-badge { background: var(--lora-accent); - color: white; + color: var(--text-on-accent); font-size: 0.7em; padding: 2px 5px; border-radius: 8px; diff --git a/static/css/components/lora-modal/versions.css b/static/css/components/lora-modal/versions.css index bbec690d..13873736 100644 --- a/static/css/components/lora-modal/versions.css +++ b/static/css/components/lora-modal/versions.css @@ -66,7 +66,7 @@ .versions-toolbar-btn-primary { background: var(--lora-accent); - color: #fff; + color: var(--text-on-accent); border-color: color-mix(in oklch, var(--lora-accent) 70%, transparent); } @@ -345,7 +345,7 @@ .version-action-primary { background: var(--lora-accent); - color: #fff; + color: var(--text-on-accent); border-color: color-mix(in oklch, var(--lora-accent) 65%, transparent); } diff --git a/static/css/components/menu.css b/static/css/components/menu.css index ed3f61bb..24833c52 100644 --- a/static/css/components/menu.css +++ b/static/css/components/menu.css @@ -24,7 +24,7 @@ .context-menu-item:hover, .context-menu-item:focus-visible { background-color: var(--lora-accent); - color: var(--lora-text); + color: var(--text-on-accent); outline: none; } @@ -78,7 +78,7 @@ the accent background would otherwise wash the muted colour out. */ .context-menu-item:hover .context-menu-count, .context-menu-item:focus-visible .context-menu-count { - color: var(--lora-text); + color: var(--text-on-accent); opacity: 0.8; } @@ -212,7 +212,7 @@ .nsfw-level-btn.active { background: var(--lora-accent); - color: white; + color: var(--text-on-accent); border-color: var(--lora-accent); } @@ -251,7 +251,7 @@ .node-item:hover { background-color: var(--lora-accent); - color: var(--lora-text); + color: var(--text-on-accent); } .node-icon-indicator { @@ -282,7 +282,7 @@ .send-all-item:hover { background-color: var(--lora-accent); - color: var(--lora-text); + color: var(--text-on-accent); } .send-all-item i { diff --git a/static/css/components/modal/_base.css b/static/css/components/modal/_base.css index 5161f913..85349d15 100644 --- a/static/css/components/modal/_base.css +++ b/static/css/components/modal/_base.css @@ -114,7 +114,7 @@ body.modal-open { /* Style for exclude button - different from delete button */ .exclude-btn, .confirm-btn { background: var(--lora-accent, #4f46e5); - color: white; + color: var(--text-on-accent); } .cancel-btn:hover, @@ -187,7 +187,7 @@ body.modal-open { gap: 8px; padding: var(--space-1) var(--space-2); background-color: var(--lora-accent); - color: var(--lora-text); + color: var(--text-on-accent); border: none; border-radius: var(--border-radius-sm); cursor: pointer; @@ -198,7 +198,7 @@ body.modal-open { .primary-btn:hover, .primary-btn:focus-visible { background-color: oklch(from var(--lora-accent) l c h / 85%); - color: var(--lora-text); + color: var(--text-on-accent); outline: none; } @@ -229,7 +229,7 @@ body.modal-open { opacity: 0.5; cursor: not-allowed; background-color: var(--lora-accent); - color: var(--lora-text); + color: var(--text-on-accent); pointer-events: none; } @@ -668,7 +668,7 @@ button:disabled, content: '\f00c'; font-family: 'Font Awesome 6 Free', sans-serif; font-weight: 900; - color: var(--lora-text); + color: var(--text-on-accent); font-size: 12px; } diff --git a/static/css/components/modal/download-modal.css b/static/css/components/modal/download-modal.css index 0258942c..ac36b216 100644 --- a/static/css/components/modal/download-modal.css +++ b/static/css/components/modal/download-modal.css @@ -373,7 +373,7 @@ .create-folder-form button.confirm { background: var(--lora-accent); - color: white; + color: var(--text-on-accent); border-color: var(--lora-accent); } @@ -1139,7 +1139,7 @@ .routing-override-option.active { background: var(--lora-accent); - color: white; + color: var(--text-on-accent); border-color: var(--lora-accent); opacity: 1; cursor: default; diff --git a/static/css/components/modal/help-modal.css b/static/css/components/modal/help-modal.css index 2ae44a2e..710ff44a 100644 --- a/static/css/components/modal/help-modal.css +++ b/static/css/components/modal/help-modal.css @@ -144,7 +144,7 @@ font-size: 0.7em; font-weight: 600; background-color: var(--lora-accent); - color: var(--lora-text); + color: var(--text-on-accent); padding: 2px 6px; border-radius: 10px; margin-left: 8px; @@ -171,7 +171,7 @@ .replay-tutorial-btn .new-content-badge { display: none; background-color: rgba(255, 255, 255, 0.22); - color: #fff; + color: var(--text-on-accent); box-shadow: none; margin-left: 2px; } @@ -227,7 +227,7 @@ font-size: 0.75em; font-weight: 500; background-color: var(--lora-accent); - color: var(--lora-text); + color: var(--text-on-accent); padding: 4px 8px; border-radius: 12px; margin-left: 10px; @@ -306,7 +306,7 @@ cursor: pointer; transition: var(--transition-base); background-color: var(--lora-accent); - color: white; + color: var(--text-on-accent); text-decoration: none; border: none; } @@ -343,7 +343,7 @@ cursor: pointer; transition: var(--transition-base); background-color: var(--lora-accent); - color: white; + color: var(--text-on-accent); border: none; } diff --git a/static/css/components/modal/settings-modal.css b/static/css/components/modal/settings-modal.css index 5b979d43..5fcfe834 100644 --- a/static/css/components/modal/settings-modal.css +++ b/static/css/components/modal/settings-modal.css @@ -15,7 +15,7 @@ .settings-toggle:hover { background: var(--lora-accent); - color: white; + color: var(--text-on-accent); transform: translateY(-2px); } @@ -86,13 +86,13 @@ } .settings-nav-item:hover { - background: rgba(var(--lora-accent-rgb, 79, 70, 229), 0.1); + background: oklch(var(--lora-accent-l) var(--lora-accent-c) var(--lora-accent-h) / 0.1); color: var(--lora-accent); } .settings-nav-item.active { background: var(--lora-accent); - color: white; + color: var(--text-on-accent); font-weight: 600; } @@ -160,7 +160,7 @@ .settings-search-input:focus { border-color: var(--lora-accent); outline: none; - box-shadow: 0 0 0 2px rgba(var(--lora-accent-rgb, 79, 70, 229), 0.1); + box-shadow: 0 0 0 2px oklch(var(--lora-accent-l) var(--lora-accent-c) var(--lora-accent-h) / 0.1); } .settings-search-input::placeholder { @@ -193,7 +193,7 @@ /* Search Highlight Styles */ .settings-search-highlight { - background-color: rgba(var(--lora-accent-rgb, 79, 70, 229), 0.3); + background-color: oklch(var(--lora-accent-l) var(--lora-accent-c) var(--lora-accent-h) / 0.3); color: var(--lora-accent); padding: 0 2px; border-radius: 2px; @@ -265,7 +265,7 @@ } .settings-action-link:focus-visible { - box-shadow: 0 0 0 2px rgba(var(--lora-accent-rgb, 79, 70, 229), 0.2); + box-shadow: 0 0 0 2px oklch(var(--lora-accent-l) var(--lora-accent-c) var(--lora-accent-h) / 0.2); } /* Settings Links */ @@ -296,7 +296,7 @@ .settings-link:hover { background: var(--lora-accent); - color: white; + color: var(--text-on-accent); transform: translateY(-2px); } @@ -364,7 +364,7 @@ .api-key-input input:focus { border-color: var(--lora-accent); outline: none; - box-shadow: 0 0 0 2px rgba(var(--lora-accent-rgb, 79, 70, 229), 0.1); + box-shadow: 0 0 0 2px oklch(var(--lora-accent-l) var(--lora-accent-c) var(--lora-accent-h) / 0.1); } .api-key-input .toggle-visibility { @@ -491,7 +491,7 @@ .text-input-wrapper input:focus { border-color: var(--lora-accent); outline: none; - box-shadow: 0 0 0 2px rgba(var(--lora-accent-rgb, 79, 70, 229), 0.1); + box-shadow: 0 0 0 2px oklch(var(--lora-accent-l) var(--lora-accent-c) var(--lora-accent-h) / 0.1); } /* Dark theme specific adjustments */ @@ -577,7 +577,7 @@ .base-model-skip-search:focus { border-color: var(--lora-accent); outline: none; - box-shadow: 0 0 0 2px rgba(var(--lora-accent-rgb, 79, 70, 229), 0.1); + box-shadow: 0 0 0 2px oklch(var(--lora-accent-l) var(--lora-accent-c) var(--lora-accent-h) / 0.1); } .base-model-skip-list { @@ -602,7 +602,7 @@ .base-model-skip-option:hover { border-color: var(--lora-accent); - background-color: rgba(var(--lora-accent-rgb, 79, 70, 229), 0.05); + background-color: oklch(var(--lora-accent-l) var(--lora-accent-c) var(--lora-accent-h) / 0.05); } .base-model-skip-option input { @@ -623,7 +623,7 @@ .priority-tags-input:focus { border-color: var(--lora-accent); outline: none; - box-shadow: 0 0 0 2px rgba(var(--lora-accent-rgb, 79, 70, 229), 0.1); + box-shadow: 0 0 0 2px oklch(var(--lora-accent-l) var(--lora-accent-c) var(--lora-accent-h) / 0.1); } .priority-tags-item { @@ -681,7 +681,7 @@ .priority-tags-example code { font-family: var(--font-mono); - background-color: rgba(var(--lora-accent-rgb, 79, 70, 229), 0.12); + background-color: oklch(var(--lora-accent-l) var(--lora-accent-c) var(--lora-accent-h) / 0.12); padding: 2px 6px; border-radius: var(--border-radius-xs); display: inline-block; @@ -1268,7 +1268,7 @@ input:checked + .toggle-slider:before { gap: 6px; padding: 6px 12px; background: var(--lora-accent); - color: white; + color: var(--text-on-accent); border: none; border-radius: var(--border-radius-xs); cursor: pointer; @@ -1315,7 +1315,7 @@ input:checked + .toggle-slider:before { .path-value-input:focus { border-color: var(--lora-accent); outline: none; - box-shadow: 0 0 0 2px rgba(var(--lora-accent-rgb, 79, 70, 229), 0.1); + box-shadow: 0 0 0 2px oklch(var(--lora-accent-l) var(--lora-accent-c) var(--lora-accent-h) / 0.1); } .remove-mapping-btn { @@ -1442,7 +1442,7 @@ input:checked + .toggle-slider:before { .placeholder-tag { display: inline-block; background: var(--lora-accent); - color: white; + color: var(--text-on-accent); padding: 2px 6px; border-radius: 3px; font-family: var(--font-mono); @@ -1468,6 +1468,9 @@ input:checked + .toggle-slider:before { .template-custom-input { width: 96%; + /* Space from the label/apply-button row above; the row has no bottom + margin, so without this the input sits flush against the button. */ + margin-top: var(--space-1); padding: 6px 10px; border-radius: var(--border-radius-xs); border: 1px solid var(--border-color); @@ -1482,7 +1485,7 @@ input:checked + .toggle-slider:before { .template-custom-input:focus { border-color: var(--lora-accent); outline: none; - box-shadow: 0 0 0 2px rgba(var(--lora-accent-rgb, 79, 70, 229), 0.1); + box-shadow: 0 0 0 2px oklch(var(--lora-accent-l) var(--lora-accent-c) var(--lora-accent-h) / 0.1); } .template-custom-input::placeholder { @@ -1646,7 +1649,7 @@ input:checked + .toggle-slider:before { .extra-folder-path-row .path-controls .extra-folder-path-input:focus { border-color: var(--lora-accent); outline: none; - box-shadow: 0 0 0 2px rgba(var(--lora-accent-rgb, 79, 70, 229), 0.1); + box-shadow: 0 0 0 2px oklch(var(--lora-accent-l) var(--lora-accent-c) var(--lora-accent-h) / 0.1); } .extra-folder-path-row .path-controls .extra-folder-path-input.has-error { @@ -1713,7 +1716,7 @@ input:checked + .toggle-slider:before { #settingsModal .browse-path-btn:hover { background: var(--lora-accent); - color: white; + color: var(--text-on-accent); } /* Inset variant (static path fields): the button floats inside the right diff --git a/static/css/components/modal/support-modal.css b/static/css/components/modal/support-modal.css index 78e81367..b1921f57 100644 --- a/static/css/components/modal/support-modal.css +++ b/static/css/components/modal/support-modal.css @@ -105,7 +105,7 @@ .social-link:hover { background: var(--lora-accent); - color: white; + color: var(--text-on-accent); transform: translateY(-2px); } @@ -253,7 +253,7 @@ } .social-link:hover .civitai-icon { - color: white; /* Icon color changes to white on hover */ + color: var(--text-on-accent); /* Icon color flips to the on-accent foreground on hover */ } /* Enhanced hover visual feedback */ diff --git a/static/css/components/modal/update-modal.css b/static/css/components/modal/update-modal.css index bcc0b572..9e0050b2 100644 --- a/static/css/components/modal/update-modal.css +++ b/static/css/components/modal/update-modal.css @@ -42,7 +42,7 @@ padding: 0 0.4rem; border-radius: 999px; background: var(--lora-accent); - color: #fff; + color: var(--text-on-accent); font-size: 0.75rem; font-weight: 600; align-items: center; @@ -163,7 +163,7 @@ .update-link:hover { background: var(--lora-accent); - color: white; + color: var(--text-on-accent); transform: translateY(-2px); } @@ -274,7 +274,7 @@ .changelog-item .latest-badge { background-color: var(--lora-accent); - color: white; + color: var(--text-on-accent); padding: 2px 8px; border-radius: 12px; font-size: 0.75em; @@ -384,12 +384,12 @@ .channel-btn.active { background: var(--lora-accent, #4285F4); - color: #fff; + color: var(--text-on-accent); box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2); } .channel-btn.active i { - color: #fff; + color: var(--text-on-accent); } .channel-btn i { @@ -456,7 +456,7 @@ border: none; border-radius: 6px; background: var(--lora-accent, #4285F4); - color: #fff; + color: var(--text-on-accent); cursor: pointer; font-size: 0.9em; font-weight: 500; @@ -614,7 +614,7 @@ .banner-history-action.banner-history-action-primary { background: var(--lora-accent); border-color: var(--lora-accent); - color: #fff; + color: var(--text-on-accent); } .banner-history-action.banner-history-action-secondary { diff --git a/static/css/components/recipe-modal.css b/static/css/components/recipe-modal.css index 843256af..2cfd2aa4 100644 --- a/static/css/components/recipe-modal.css +++ b/static/css/components/recipe-modal.css @@ -423,7 +423,7 @@ .source-url-save-btn { background: var(--lora-accent); - color: white; + color: var(--text-on-accent); } .source-url-cancel-btn:hover { @@ -1268,7 +1268,7 @@ .reconnect-confirm-btn { background: var(--lora-accent); - color: white; + color: var(--text-on-accent); } .reconnect-cancel-btn:hover { @@ -1517,7 +1517,7 @@ .resource-action.primary { background: var(--lora-accent); - color: white; + color: var(--text-on-accent); border-color: var(--lora-accent); } diff --git a/static/css/components/search-filter.css b/static/css/components/search-filter.css index 0ff159b5..91925fb3 100644 --- a/static/css/components/search-filter.css +++ b/static/css/components/search-filter.css @@ -129,7 +129,7 @@ top: -6px; right: -6px; background-color: var(--lora-accent); - color: white; + color: var(--text-on-accent); width: 16px; height: 16px; border-radius: 50%; @@ -213,7 +213,7 @@ .filter-search-input:focus { outline: none; border-color: var(--lora-accent); - box-shadow: 0 0 0 2px rgba(var(--lora-accent-rgb, 76, 175, 80), 0.15); + box-shadow: 0 0 0 2px oklch(var(--lora-accent-l) var(--lora-accent-c) var(--lora-accent-h) / 0.15); } .filter-empty-state { @@ -257,7 +257,7 @@ .filter-tag.active { background-color: var(--lora-accent); - color: white; + color: var(--text-on-accent); border-color: var(--lora-accent); } @@ -309,7 +309,7 @@ .tag-filter.active .tag-count { background: rgba(255, 255, 255, 0.3); - color: white; + color: var(--text-on-accent); } .tags-loading, .tags-error, .no-tags { @@ -493,7 +493,7 @@ .search-option-tag.active { background-color: var(--lora-accent); - color: white; + color: var(--text-on-accent); border-color: var(--lora-accent); } @@ -537,12 +537,12 @@ } .filter-preset.active .preset-name { - color: white; + color: var(--text-on-accent); font-weight: 600; } .filter-preset.active .preset-delete-btn { - color: white; + color: var(--text-on-accent); opacity: 0; } @@ -552,7 +552,7 @@ .filter-preset.active .preset-delete-btn:hover { opacity: 1; - color: white; + color: var(--text-on-accent); } .preset-name { @@ -743,7 +743,7 @@ .tag-logic-option.active { background-color: var(--lora-accent); - color: white; + color: var(--text-on-accent); opacity: 1; } diff --git a/static/css/components/shared.css b/static/css/components/shared.css index 64bdb27e..f3a1f34a 100644 --- a/static/css/components/shared.css +++ b/static/css/components/shared.css @@ -3,7 +3,7 @@ display: inline-flex; align-items: center; background: var(--lora-accent); - color: var(--lora-text); + color: var(--text-on-accent); padding: 4px 8px; border-radius: var(--border-radius-xs); font-size: 0.8em; diff --git a/static/css/components/shared/edit-metadata.css b/static/css/components/shared/edit-metadata.css index f13071ef..064413b2 100644 --- a/static/css/components/shared/edit-metadata.css +++ b/static/css/components/shared/edit-metadata.css @@ -257,7 +257,7 @@ body.reorder-drag-active * { .append-tags-btn, .replace-tags-btn { background: var(--lora-accent) !important; - color: white !important; + color: var(--text-on-accent) !important; border-color: var(--lora-accent) !important; } @@ -271,7 +271,7 @@ body.reorder-drag-active * { /* Specific styling for bulk tag action buttons */ .bulk-append-tags-btn { background: var(--lora-accent) !important; - color: white !important; + color: var(--text-on-accent) !important; border-color: var(--lora-accent) !important; } diff --git a/static/css/components/sidebar.css b/static/css/components/sidebar.css index 82007ea4..983ee674 100644 --- a/static/css/components/sidebar.css +++ b/static/css/components/sidebar.css @@ -140,7 +140,7 @@ } .sidebar-hidden-indicator:hover i { - color: white; + color: var(--text-on-accent); } /* Subtle breathing animation for first-time discovery */ diff --git a/static/css/components/toast.css b/static/css/components/toast.css index b13bd08e..a392f0cf 100644 --- a/static/css/components/toast.css +++ b/static/css/components/toast.css @@ -1,7 +1,7 @@ /* Update toast animation for trigger word copy */ .toast.toast-copy { background: var(--lora-accent); - color: white; + color: var(--text-on-accent); border: none; padding: 8px 16px; font-size: 0.9em; @@ -98,7 +98,7 @@ .toast-action-btn:hover { background: var(--lora-accent); - color: #fff; + color: var(--text-on-accent); } .toast-countdown { diff --git a/static/css/layout.css b/static/css/layout.css index c28d191b..130ad517 100644 --- a/static/css/layout.css +++ b/static/css/layout.css @@ -159,7 +159,7 @@ body.sticky-controls .sticky-topbar { .control-group button.favorite-filter.active { background: var(--lora-accent); - color: white; + color: var(--text-on-accent); } .control-group button.favorite-filter i { @@ -174,17 +174,17 @@ body.sticky-controls .sticky-topbar { .control-group button.update-filter.active { background: var(--lora-accent); - color: white; + color: var(--text-on-accent); } .control-group button.update-filter.active i { - color: white; + color: var(--text-on-accent); } .update-filter-group .dropdown-main.update-filter.active + .dropdown-toggle { background: var(--lora-accent); border-color: var(--lora-accent); - color: white; + color: var(--text-on-accent); } .update-filter-group .dropdown-main.update-filter.active + .dropdown-toggle i { @@ -194,7 +194,7 @@ body.sticky-controls .sticky-topbar { /* Active state for buttons that can be toggled */ .control-group button.active { background: var(--lora-accent); - color: white; + color: var(--text-on-accent); border-color: var(--lora-accent); } @@ -540,7 +540,7 @@ body.sticky-controls .sticky-topbar { .back-to-top:hover { background: var(--lora-accent); - color: white; + color: var(--text-on-accent); transform: translateY(-2px); box-shadow: var(--shadow-md); } diff --git a/static/css/onboarding.css b/static/css/onboarding.css index 95903008..d0dc8750 100644 --- a/static/css/onboarding.css +++ b/static/css/onboarding.css @@ -110,13 +110,13 @@ .onboarding-btn:hover { background: var(--lora-accent); - color: var(--lora-text); + color: var(--text-on-accent); border-color: var(--lora-accent); } .onboarding-btn.primary { background: var(--lora-accent); - color: var(--lora-text); + color: var(--text-on-accent); border-color: var(--lora-accent); } @@ -189,7 +189,7 @@ .language-option.selected { border-color: var(--lora-accent); background: var(--lora-accent); - color: var(--lora-text); + color: var(--text-on-accent); } .language-flag { diff --git a/static/css/tokens/colors.css b/static/css/tokens/colors.css index 61d95094..5ce73c7a 100644 --- a/static/css/tokens/colors.css +++ b/static/css/tokens/colors.css @@ -24,6 +24,13 @@ --color-accent-border: oklch(var(--color-accent-l) var(--color-accent-c) var(--color-accent-h) / 0.25); --color-accent-transparent: oklch(var(--color-accent-l) var(--color-accent-c) var(--color-accent-h) / 0.6); + /* Text/icon color on top of a solid accent background. The accent is a + mid-to-bright color (L 52-72%) in every theme/preset, so a dark, + low-chroma color of the same hue reads far better than white or the + page text color (WCAG: dark on L60% accent ≈ 4.4:1, white ≈ 3.5:1). + Derived from --color-accent-h so every preset picks it up. */ + --color-accent-contrast: oklch(20% 0.02 var(--color-accent-h)); + --color-warning: oklch(var(--color-warning-l) var(--color-warning-c) var(--color-warning-h)); --color-warning-bg: oklch(var(--color-warning-l) var(--color-warning-c) var(--color-warning-h) / 0.15); --color-warning-border: oklch(var(--color-warning-l) var(--color-warning-c) var(--color-warning-h) / 0.3);