From 7e50feeca4fe6cbbc6190d818c3867ac8ba70823 Mon Sep 17 00:00:00 2001 From: Guillem Arias Date: Mon, 11 May 2026 21:36:24 +0200 Subject: [PATCH] fix(goals): theme-aware avatar text contrast; compact picker popup Avatar letter/icon now uses `--avatar-color` CSS variable + the new `.goal-avatar` class. Light mode darkens the text to 55% color + 45% black so pale palette entries (cyan-300, green-300) stay readable on the 10%-mix tint over white (~4.5:1). Dark mode reverts to the full brand color via [data-theme="dark"] .goal-avatar override so the text doesn't disappear against the near-black tinted surface. Verified live: #805dee renders as a darker oklab in light mode and full rgb(128,93,238) in dark mode. Picker popup compacted: - 80 (320px) wide, max-h-[60vh] overflow-y-auto so it never spills off-screen. - Anchored below the avatar + horizontally centered to it (top-full left-1/2 -translate-x-1/2) so it doesn't drift off to the right edge of the form on narrow modals. - Icon grid max-h-40 (160px, ~5 rows) with the in-house `scrollbar` utility for a thin gray thumb that works in both themes. - Section headers (Color / Icon) styled `uppercase tracking-wide` for visual hierarchy. Verified popup at 320x310px in edit modal, no vertical overflow. --- app/assets/tailwind/application.css | 14 ++++++++++++++ .../goals/avatar_component.html.erb | 4 ++-- app/views/goals/_color_picker.html.erb | 19 ++++++++++--------- 3 files changed, 26 insertions(+), 11 deletions(-) diff --git a/app/assets/tailwind/application.css b/app/assets/tailwind/application.css index 3d868c741..ddbda9b04 100644 --- a/app/assets/tailwind/application.css +++ b/app/assets/tailwind/application.css @@ -188,6 +188,20 @@ scrollbar-width:none } +/* Tinted-bg + colored-content avatar used by Goals::AvatarComponent and + the goals color/icon picker. Theme-aware text color: light mode darkens + the letter/icon so pale palette entries (cyan-300, green-300, etc.) keep + ~4.5:1 contrast against the 10%-mix tint over white. Dark mode reverts + to the full color so the letter doesn't disappear against the near-black + surface. */ +.goal-avatar { + background-color: color-mix(in oklab, var(--avatar-color) 10%, transparent); + color: color-mix(in oklab, var(--avatar-color) 55%, black); +} +[data-theme="dark"] .goal-avatar { + color: var(--avatar-color); +} + .invite_code [data-clipboard-target="iconDefault"], .invite_code [data-clipboard-target="iconSuccess"] { transition: opacity 0.2s; diff --git a/app/components/goals/avatar_component.html.erb b/app/components/goals/avatar_component.html.erb index 7cb9d7a09..f91284c68 100644 --- a/app/components/goals/avatar_component.html.erb +++ b/app/components/goals/avatar_component.html.erb @@ -1,5 +1,5 @@ -