From 0d32bb70ec3ce7359bf36477a08f99bf1b51f995 Mon Sep 17 00:00:00 2001 From: Guillem Arias Fauste Date: Mon, 4 May 2026 21:47:01 +0200 Subject: [PATCH] chore(design-system): swap raw gray classes for semantic tokens across remaining views (#1655) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * chore(design-system): swap raw gray classes for semantic tokens across remaining views Finalizes the raw-color sweep started in #1652 (settings) and continued in #1654 (holdings). Covers accounts, budgets, chats, pages, imports, provider integrations (mercury, lunchflow, sophtron, enable_banking, coinstats), auth flows (password reset, MFA, registrations), shared layouts, and selected DS component hover states. 35 files, ~56 line changes. Mappings (matching the patterns established in the prior sweeps): - text-white bg-gray-900 hover:bg-gray-800 (with optional focus:ring-gray-900) -> text-inverse button-bg-primary hover:button-bg-primary-hover -> focus:ring-button-bg-primary - text-gray-500 / 600 / 700 -> text-secondary - text-gray-800 -> text-primary - text-gray-400 -> text-subdued - hover:text-gray-700 / hover:text-gray-100 -> hover:text-primary - bg-gray-50 / 100 / 200 (standalone) -> bg-surface-inset - bg-gray-500/5 -> bg-gray-tint-5 - bg-gray-500/10 -> bg-gray-tint-10 - bg-gray-900 (decorative active states) -> bg-inverse - hover:bg-gray-50 / 100 (standalone) -> hover:bg-surface-inset - hover:bg-gray-300 -> hover:bg-surface-inset-hover - bg-white hover:bg-gray-100 -> bg-container hover:bg-container-hover - border-gray-300 -> border-secondary - focus:border-gray-200 -> focus:border-secondary - focus-within:border-gray-900 -> focus-within:border-primary - DS::Buttonish outline / ghost / icon hover: hover:bg-gray-100 theme-dark:hover:bg-gray-700 -> hover:bg-container-inset-hover Left intentionally raw, with rationale: - bg-gray-300 / bg-gray-400 decorative dots and avatar circles. The raw value reads OK against both bg-container variants; no semantic "neutral indicator" token exists. Same pattern as #1652 / #1654. - bg-gray-400/20 theme-dark:bg-gray-500/20 (onboardings/trial). Custom alpha tint with no equivalent token. - bg-white theme-dark:bg-gray-700 (DS::Tabs active pill, budgets tabs). Custom tab-pill pattern; gray-700 in dark mode (one shade lighter than page bg-gray-900) is intentional for visibility. - bg-gray-100 theme-dark:bg-gray-700 (DS::Toggle base bg). Closest match (bg-container-inset-hover) is semantically a hover state. - DS::Buttonish secondary variant gray-200/300/700/600 pattern. Same pattern as #1654 holdings; needs button-bg-secondary-strong from that PR. Will swap in a follow-up after #1654 merges. - disabled:bg-gray-500 theme-dark:disabled:bg-gray-400 on inverse buttons (DS::Buttonish primary, enable_banking, coinstats). Custom disabled state for the inverse pair; no token. - text-gray-300 SVG stroke (shared/_progress_circle). - bg-white text-gray-900 (layouts/print). Print contexts intentionally light regardless of theme. - bg-gray-800 / border-gray-700 / text-white / hover:text-gray-100 (impersonation_sessions/_super_admin_bar). Admin overlay styled to remain dark in both modes; not a theme-aware component. Files covered by other in-flight PRs were skipped to avoid rebase conflicts: chats/_ai_consent's fg-inverse swap (#1626), shared/_text_tooltip and shared/_money_field tooltip pills (#1626), investments/_value_tooltip (#1626), components/DS/tooltip (#1626). * fix(design-system): keep changelog avatar text raw to preserve dark-mode contrast The changelog avatar fallback (when @release_notes[:avatar] is missing) sits inside the "decorative + raw" exception list — bg-gray-300 stays fixed across themes since no semantic neutral-indicator token exists. The earlier sweep partially themed the pair: bg-gray-300 stayed raw but text-gray-600 became text-secondary. text-secondary resolves to gray-300 in dark mode, which matches the bg → text became invisible against its own background. Reverting only the text class to text-gray-600 restores the original fixed-light placeholder behavior. Both classes raw, both themes readable. * fix(design-system): address review feedback on raw-color-sweep-finalize Six issues caught by CodeRabbit + Codex review: 1. focus:ring-button-bg-primary silently emits no CSS (×6 files). button-bg-primary is a custom @utility, not a theme color, so Tailwind's ring-{name} resolution finds no --color-button-bg-primary. Replaces with focus:ring-gray-900 theme-dark:focus:ring-white — same color flip as the button bg, but resolved through theme colors so the ring actually renders. Files: lunchflow/mercury/sophtron _api_error + _setup_required, coinstats_items/new. 2. accounts/show/_activity.html.erb: focus-within:ring-gray-100 was dead (no ring-width on the parent). Removed. 3. import/confirms/show.html.erb: uniform hover:bg-surface-inset-hover applied to both active and inactive step indicators created a jarring dark-to-light flip on the active step (bg-inverse → bg-surface-inset-hover). Now hover follows the resting state: active uses hover:bg-inverse-hover, inactive uses hover:bg-surface-inset-hover. 4. password_resets/new.html.erb: bg-white left raw alongside the migrated hover:bg-surface-inset. Swapped to bg-container so dark mode flips properly. 5. registrations/new.html.erb + password_validator_controller.js: view now uses bg-surface-inset on password strength block lines, but the Stimulus controller still toggled bg-gray-200 on validate. Updated controller to add/remove bg-surface-inset matching the view, so unmet states reset to the tokenized class instead of leaving raw gray-200 stuck on the element. --- app/components/DS/buttonish.rb | 6 +++--- .../controllers/password_validator_controller.js | 4 ++-- app/views/accounts/_tax_treatment_badge.html.erb | 2 +- app/views/accounts/new/_container.html.erb | 2 +- app/views/accounts/new/_method_selector.html.erb | 2 +- app/views/accounts/show/_activity.html.erb | 2 +- .../budget_categories/_allocation_progress.erb | 6 +++--- .../budget_categories/_budget_category.html.erb | 2 +- app/views/budgets/_budget_donut.html.erb | 2 +- app/views/categories/_form.html.erb | 2 +- app/views/chats/_ai_consent.html.erb | 2 +- app/views/chats/_ai_greeting.html.erb | 2 +- app/views/coinstats_items/new.html.erb | 4 ++-- app/views/enable_banking_items/new.html.erb | 6 +++--- app/views/family_merchants/merge.html.erb | 2 +- app/views/import/cleans/show.html.erb | 2 +- app/views/import/confirms/show.html.erb | 2 +- app/views/imports/_importing.html.erb | 2 +- app/views/imports/_pdf_import.html.erb | 14 +++++++------- app/views/imports/_table.html.erb | 4 ++-- app/views/imports/new.html.erb | 4 ++-- app/views/layouts/auth.html.erb | 2 +- app/views/layouts/shared/_breadcrumbs.html.erb | 4 ++-- app/views/layouts/shared/_page_header.html.erb | 2 +- app/views/lunchflow_items/_api_error.html.erb | 2 +- app/views/lunchflow_items/_setup_required.html.erb | 2 +- app/views/mercury_items/_api_error.html.erb | 2 +- app/views/mercury_items/_setup_required.html.erb | 2 +- app/views/mfa/new.html.erb | 2 +- app/views/password_resets/new.html.erb | 2 +- app/views/registrations/new.html.erb | 10 +++++----- app/views/shared/_badge.html.erb | 2 +- app/views/sophtron_items/_setup_required.html.erb | 2 +- app/views/transfer_matches/new.html.erb | 4 ++-- app/views/valuations/index.html.erb | 2 +- 35 files changed, 57 insertions(+), 57 deletions(-) diff --git a/app/components/DS/buttonish.rb b/app/components/DS/buttonish.rb index e85169191..bd8894be6 100644 --- a/app/components/DS/buttonish.rb +++ b/app/components/DS/buttonish.rb @@ -17,15 +17,15 @@ class DS::Buttonish < DesignSystemComponent icon_classes: "text-secondary" }, outline_destructive: { - container_classes: "text-destructive border border-secondary bg-transparent hover:bg-gray-100 theme-dark:hover:bg-gray-700", + container_classes: "text-destructive border border-secondary bg-transparent hover:bg-container-inset-hover", icon_classes: "text-secondary" }, ghost: { - container_classes: "text-primary bg-transparent hover:bg-gray-100 theme-dark:hover:bg-gray-700", + container_classes: "text-primary bg-transparent hover:bg-container-inset-hover", icon_classes: "text-secondary" }, icon: { - container_classes: "hover:bg-gray-100 theme-dark:hover:bg-gray-700", + container_classes: "hover:bg-container-inset-hover", icon_classes: "text-secondary" }, icon_inverse: { diff --git a/app/javascript/controllers/password_validator_controller.js b/app/javascript/controllers/password_validator_controller.js index 4de9c6fd1..76cca812e 100644 --- a/app/javascript/controllers/password_validator_controller.js +++ b/app/javascript/controllers/password_validator_controller.js @@ -52,11 +52,11 @@ export default class extends Controller { // Update block lines sequentially based on total requirements met this.blockLineTargets.forEach((line, index) => { if (index < requirementsMet) { - line.classList.remove("bg-gray-200"); + line.classList.remove("bg-surface-inset"); line.classList.add("bg-green-600"); } else { line.classList.remove("bg-green-600"); - line.classList.add("bg-gray-200"); + line.classList.add("bg-surface-inset"); } }); } diff --git a/app/views/accounts/_tax_treatment_badge.html.erb b/app/views/accounts/_tax_treatment_badge.html.erb index 070e870ba..cd3823271 100644 --- a/app/views/accounts/_tax_treatment_badge.html.erb +++ b/app/views/accounts/_tax_treatment_badge.html.erb @@ -9,7 +9,7 @@ when :tax_advantaged "bg-purple-500/10 text-purple-600 theme-dark:text-purple-400" else - "bg-gray-500/10 text-secondary" + "bg-gray-tint-10 text-secondary" end %> "> diff --git a/app/views/accounts/new/_container.html.erb b/app/views/accounts/new/_container.html.erb index 67697da50..387a59f14 100644 --- a/app/views/accounts/new/_container.html.erb +++ b/app/views/accounts/new/_container.html.erb @@ -2,7 +2,7 @@ <%= render DS::Dialog.new do |dialog| %>
-
+
<% if back_path %> <%= render DS::Link.new( diff --git a/app/views/accounts/new/_method_selector.html.erb b/app/views/accounts/new/_method_selector.html.erb index f98fef36c..ac3c31909 100644 --- a/app/views/accounts/new/_method_selector.html.erb +++ b/app/views/accounts/new/_method_selector.html.erb @@ -10,7 +10,7 @@ <% end %> <% end %>> <%# Manual entry option %> - <%= link_to path, class: "flex items-center gap-4 w-full text-center text-primary focus:outline-hidden focus:bg-surface border border-transparent focus:border focus:border-gray-200 px-2 hover:bg-surface rounded-lg p-2" do %> + <%= link_to path, class: "flex items-center gap-4 w-full text-center text-primary focus:outline-hidden focus:bg-surface border border-transparent focus:border focus:border-secondary px-2 hover:bg-surface rounded-lg p-2" do %> <%= icon("keyboard") %> diff --git a/app/views/accounts/show/_activity.html.erb b/app/views/accounts/show/_activity.html.erb index 76de75102..a36407a1f 100644 --- a/app/views/accounts/show/_activity.html.erb +++ b/app/views/accounts/show/_activity.html.erb @@ -44,7 +44,7 @@ data: { controller: "auto-submit-form" } do |form| %>
-
+
<%= icon("search") %> <%= hidden_field_tag :account_id, @account.id %> <%= form.search_field :search, diff --git a/app/views/budget_categories/_allocation_progress.erb b/app/views/budget_categories/_allocation_progress.erb index af854fe00..bd162f5e0 100644 --- a/app/views/budget_categories/_allocation_progress.erb +++ b/app/views/budget_categories/_allocation_progress.erb @@ -5,7 +5,7 @@ <% if budget.available_to_allocate.negative? %>
<% else %> -
">
+
">
<% end %> <% if budget.available_to_allocate.negative? %> @@ -23,11 +23,11 @@

-
+
<% if budget.available_to_allocate.negative? %>
<% else %> -
+
<% end %>
diff --git a/app/views/budget_categories/_budget_category.html.erb b/app/views/budget_categories/_budget_category.html.erb index fc93282af..ff209f009 100644 --- a/app/views/budget_categories/_budget_category.html.erb +++ b/app/views/budget_categories/_budget_category.html.erb @@ -68,7 +68,7 @@ <%= format_money(budget_category.budgeted_spending_money) %> <% if budget_category.inherits_parent_budget? %> - <%= t("reports.budget_performance.shared") %> + <%= t("reports.budget_performance.shared") %> <% end %>
<% if budget_category.suggested_daily_spending.present? %> diff --git a/app/views/budgets/_budget_donut.html.erb b/app/views/budgets/_budget_donut.html.erb index 8879d9bfc..8e0520b37 100644 --- a/app/views/budgets/_budget_donut.html.erb +++ b/app/views/budgets/_budget_donut.html.erb @@ -4,7 +4,7 @@
<% if budget.initialized? %> -
+
Spent
diff --git a/app/views/categories/_form.html.erb b/app/views/categories/_form.html.erb index 1f3e5fbeb..1577f8eb4 100644 --- a/app/views/categories/_form.html.erb +++ b/app/views/categories/_form.html.erb @@ -14,7 +14,7 @@
">
-

Color

+

Color

<% Category::COLORS.each do |color| %>