Fix Choices.js theme specificity — chain .choices + !important

The b0d3829 overrides lost the cascade battle: the Choices.js CDN CSS
loads AFTER custom.css (inside the modal partial near </body>), so the
CDN's same-specificity rules won by load order. Dropdown still showed
white background + light-grey text in dark mode.

Fix: chain the root `.choices` class to every override (specificity
0,2,0 → 0,3,0) and add !important to color + background + border
properties that Choices.js hardcodes most aggressively. Now the
theme tokens always win regardless of load order.

Visual effect: dropdown option hover state now matches the selected
"Month(s)" button aesthetic (--bg-card-hover subtle lift with
--text-primary text) per Konrad's feedback.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Konrad du Plessis 2026-04-22 23:34:06 +02:00
parent b0d382987b
commit 8ea8955b30

View File

@ -1530,18 +1530,24 @@ body, .card, .modal-content, .form-control, .form-select,
own design tokens so the multi-select picker matches every other card and
input on the page. All tokens auto-switch between dark (:root) and light
(:root.light) themes no duplicate blocks needed.
Specificity note: the Choices.js CDN CSS loads AFTER custom.css (inside the
modal partial, near </body>). Every rule below chains the root `.choices`
class to beat the CDN's same-class selectors, and uses !important on the
two properties Choices.js hardcodes most aggressively (color + background)
so dark/light theme tokens always win.
*/
/* Container — the outer wrapper that replaces the native <select> */
.choices {
.choices.choices {
margin-bottom: 0;
}
/* Closed-state input area (where chips and the placeholder/search sit) */
.choices__inner {
background: var(--bg-inset);
color: var(--text-primary);
border: 1px solid var(--border-default);
.choices .choices__inner {
background: var(--bg-inset) !important;
color: var(--text-primary) !important;
border: 1px solid var(--border-default) !important;
border-radius: 0.5rem;
padding: 0.4rem 0.55rem;
min-height: 2.55rem;
@ -1549,94 +1555,97 @@ body, .card, .modal-content, .form-control, .form-select,
}
.choices.is-focused .choices__inner,
.choices.is-open .choices__inner {
border-color: var(--accent);
border-color: var(--accent) !important;
box-shadow: 0 0 0 0.15rem rgba(232, 133, 26, 0.18);
}
/* The cloned search input typed into when the dropdown is open */
.choices__input {
.choices .choices__input {
background: transparent !important;
color: var(--text-primary) !important;
font-size: 0.925rem;
}
.choices__input::placeholder {
color: var(--text-tertiary);
.choices .choices__input::placeholder {
color: var(--text-tertiary) !important;
}
/* Dropdown popup — the list of choices */
.choices__list--dropdown,
.choices__list[aria-expanded] {
background: var(--bg-card);
border: 1px solid var(--border-default);
.choices .choices__list--dropdown,
.choices .choices__list[aria-expanded] {
background: var(--bg-card) !important;
border: 1px solid var(--border-default) !important;
border-radius: 0.5rem;
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.28);
margin-top: 4px;
z-index: 2000;
color: var(--text-primary) !important;
}
/* Individual option rows in the dropdown */
.choices__list--dropdown .choices__item,
.choices__list[aria-expanded] .choices__item {
color: var(--text-primary);
/* Individual option rows in the dropdown — default state */
.choices .choices__list--dropdown .choices__item,
.choices .choices__list[aria-expanded] .choices__item {
color: var(--text-primary) !important;
background: transparent !important;
padding: 0.5rem 0.75rem;
font-size: 0.9rem;
}
/* Hovered / keyboard-highlighted option */
.choices__list--dropdown .choices__item--selectable.is-highlighted,
.choices__list[aria-expanded] .choices__item--selectable.is-highlighted {
background: var(--bg-card-hover);
color: var(--text-primary);
/* Hovered / keyboard-highlighted option — matches the "Month button selected" look */
.choices .choices__list--dropdown .choices__item--selectable.is-highlighted,
.choices .choices__list[aria-expanded] .choices__item--selectable.is-highlighted {
background: var(--bg-card-hover) !important;
color: var(--text-primary) !important;
}
/* The trailing "Press to select" hint */
.choices__list--dropdown .choices__item--selectable.is-highlighted::after,
.choices__list[aria-expanded] .choices__item--selectable.is-highlighted::after {
.choices .choices__list--dropdown .choices__item--selectable.is-highlighted::after,
.choices .choices__list[aria-expanded] .choices__item--selectable.is-highlighted::after {
color: var(--accent);
opacity: 0.9;
}
/* Disabled / placeholder-style rows (e.g. "No matches found") */
.choices__list--dropdown .choices__item--disabled,
.choices__list[aria-expanded] .choices__item--disabled {
color: var(--text-tertiary);
.choices .choices__list--dropdown .choices__item--disabled,
.choices .choices__list[aria-expanded] .choices__item--disabled {
color: var(--text-tertiary) !important;
}
/* Placeholder text in the input area when nothing is selected */
.choices__placeholder {
color: var(--text-tertiary);
.choices .choices__placeholder {
color: var(--text-tertiary) !important;
opacity: 1;
}
/* Selected chips in multi-select mode (visible when items are chosen) */
.choices__list--multiple .choices__item {
background: var(--accent);
border: 1px solid var(--accent);
color: #fff;
.choices .choices__list--multiple .choices__item {
background: var(--accent) !important;
border: 1px solid var(--accent) !important;
color: #fff !important;
font-size: 0.82rem;
font-weight: 500;
padding: 0.2rem 0.6rem;
margin: 0.15rem 0.25rem 0.15rem 0;
border-radius: 999px;
}
.choices__list--multiple .choices__item.is-highlighted {
background: var(--accent-hover);
border-color: var(--accent-hover);
.choices .choices__list--multiple .choices__item.is-highlighted {
background: var(--accent-hover) !important;
border-color: var(--accent-hover) !important;
}
/* The × button on each selected chip */
.choices__list--multiple .choices__button {
.choices .choices__list--multiple .choices__button {
border-left: 1px solid rgba(255, 255, 255, 0.4);
margin: 0 0 0 0.5rem;
padding-left: 0.5rem;
opacity: 0.85;
}
.choices__list--multiple .choices__button:hover {
.choices .choices__list--multiple .choices__button:hover {
opacity: 1;
}
/* No-results / no-choices message */
.choices__list .choices__item--no-results,
.choices__list .choices__item--no-choices {
color: var(--text-tertiary);
.choices .choices__list .choices__item--no-results,
.choices .choices__list .choices__item--no-choices {
color: var(--text-tertiary) !important;
font-style: italic;
background: transparent !important;
}