Files
sure/app/components/goals/status_pill_component.rb
Guillem Arias b47e3478b7 ux(goals): catch-up rework, dark-mode pill contrast, color disclosure, stepper continue-right
- catch_up alert: title now leads with the new info (delta) and body
  states the required rate. Was "Save $1,000/mo to catch up" + "Currently
  $750/mo behind" — confusingly double-stated. Now "Behind by $750/mo" +
  "Save $1,000/mo to stay on track for {date}." Locale keys swap the
  %{amount}/%{delta} placement.

- Goals::StatusPillComponent: each variant carries a theme-dark: text
  override so the dark-700 text doesn't disappear against the dark-mode
  tinted surface. Verified in dark mode: Paused pill text is now
  rgb(231,231,231) (gray-200) instead of rgb(54,54,54) (gray-700).
  Pre-existing token contrast fix tracked at we-promise/sure#1736 stays
  the long-term path; this is the local workaround that doesn't drop
  4.5:1 in either theme.

- New goals/_color_picker.html.erb partial: <details> disclosure with
  current-color preview in the summary + swatch grid in the popover.
  Mirrors the categories form's pen-icon-overlay pattern in spirit
  (collapsed by default; user clicks to expand). Both _form_edit and
  _form_stepper render the partial; the stepper's hidden color field is
  replaced by the visible disclosure.

- Stepper footer: change `justify-between` to `flex items-center` plus
  `ml-auto` on the Continue wrapper. Continue now sits right-aligned in
  step 1 (where Back is hidden) and stays right in step 2 with Back
  taking the left edge.
2026-05-11 21:00:47 +02:00

42 lines
1.5 KiB
Ruby

class Goals::StatusPillComponent < ApplicationComponent
# Text colors here intentionally use palette steps (green/yellow/gray-700)
# instead of the `text-success` / `text-warning` / `text-secondary` tokens
# because the functional tokens drop below WCAG 1.4.3 4.5:1 on tinted
# surfaces in light mode (~2.88:1 / 3.0:1 / 4.16:1). Each variant carries
# a theme-dark: override so the dark-700 text doesn't disappear against
# the dark-mode tinted surface. Local override only; revert once
# we-promise/sure#1736 lands token-level fixes.
VARIANTS = {
on_track: { classes: "bg-green-500/10 text-green-700 theme-dark:text-green-300", icon: "circle-check" },
behind: { classes: "bg-yellow-500/10 text-yellow-700 theme-dark:text-yellow-300", icon: "triangle-alert" },
reached: { classes: "bg-green-500/10 text-green-700 theme-dark:text-green-300", icon: "star" },
no_target_date: { classes: "bg-surface-inset text-gray-700 theme-dark:text-gray-200", icon: "infinity" },
paused: { classes: "bg-surface-inset text-gray-700 theme-dark:text-gray-200", icon: "pause" },
archived: { classes: "bg-surface-inset text-gray-700 theme-dark:text-gray-200", icon: "archive" }
}.freeze
def initialize(goal:)
@goal = goal
end
def status_key
@goal.display_status
end
def variant
VARIANTS.fetch(status_key, VARIANTS[:no_target_date])
end
def label
I18n.t("goals.status.#{status_key}")
end
def classes
variant[:classes]
end
def icon_name
variant[:icon]
end
end