Skip to content

feat(appearance): tinge o fundo com a cor de destaque (14 presets + personalizada) - #66

Merged
johnlaff merged 2 commits into
mainfrom
feat/accent-background-tint
Jul 22, 2026
Merged

feat(appearance): tinge o fundo com a cor de destaque (14 presets + personalizada)#66
johnlaff merged 2 commits into
mainfrom
feat/accent-background-tint

Conversation

@johnlaff

Copy link
Copy Markdown
Owner

O que

Quando você escolhe uma cor de destaque (um dos 14 presets ou uma cor personalizada) e não há preset arquitetônico ativo, o fundo do app passa a receber um tint sutil dessa cor — a mesma linguagem que os presets arquitetônicos já usavam, agora estendida à cor de destaque. Um toggle "Fundo tingido pela cor de destaque" (ligado por padrão, em Configurações → Aparência) liga/desliga o efeito.

Por quê

Antes, só os presets arquitetônicos tingiam o fundo; a cor de destaque deixava o fundo neutro. A personalização ficava pela metade — o accent aparecia nos botões e realces, mas não no ambiente.

Como funciona

Uma única regra CSS deriva a matiz do --primary via relative color:

oklch(from var(--primary) 0.98 clamp(0, c, 0.012) h)

Isso serve os 14 presets e a cor personalizada de uma vez (o --primary já é a cor escolhida em ambos os casos). A lightness é fixada no valor do tema neutro e o chroma é clampado, então o contraste não se move o suficiente para quebrar o AA. O preset arquitetônico mantém precedência sobre o fundo (:not([data-preset])), e @supports dá fallback seguro — engines sem relative color ficam nos tokens neutros, nunca com um --background inválido.

O toggle persiste em localStorage (padrão idêntico ao "Grid de prancha"), aplicado antes da hidratação pelo script anti-flash. Sob um preset ativo o toggle fica desabilitado, com o motivo e o caminho de reativação (aria-describedby).

WCAG AA — como garantimos

  • Teste (src/lib/__tests__/background-tint.test.ts): varre as 360 matizes × 7 chromas de origem exigindo ≥ 4.5:1 em todo par texto/superfície (fg/bg, muted/bg, fg/card, muted/card), e casa as constantes com o globals.css para travar drift entre teste e folha de estilo.
  • Medido no CSS renderizado (pior caso, âmbar): claro fg/bg 18.6 · mut/bg 5.7 · mut/card 6.1; escuro fg/bg 19.0 · mut/bg 7.7 · mut/card 6.9.
  • No claro, o --muted-foreground é levemente escurecido no modo tingido (única erosão real de contraste); no escuro o valor neutro já passa com folga.

Também neste PR

  • Remove tokens --sidebar-* mortos (nenhum componente os referenciava).
  • Corrige o overflow horizontal do seletor de Densidade a 320px (reflow, WCAG 1.4.10): os botões flex-1 ganham min-w-0 + truncate, evitando que "Confortável" empurre a linha para fora da tela em larguras estreitas.

Como verificar

  1. Configurações → Aparência → escolha uma cor de destaque → o fundo tinge de leve; troque a cor → o tint acompanha.
  2. Desmarque "Fundo tingido pela cor de destaque" → o fundo volta ao neutro.
  3. Ative um preset arquitetônico → o toggle fica desabilitado (o preset manda no fundo).
  4. npm test inclui o gate de AA (background-tint.test.ts).

johnlaff added 2 commits July 22, 2026 13:32
…ersonalizada)

Quando uma cor de destaque está ativa e não há preset arquitetônico, o fundo
(--background/--card) recebe um tint sutil derivado da matiz da cor, via CSS
relative color — uma única regra serve os 14 presets e a cor personalizada.
Um toggle "Fundo tingido pela cor de destaque" (ligado por padrão) controla o
efeito; sob um preset arquitetônico ele fica desabilitado, com instrução de
como reativar.

A lightness é fixada nos valores do tema neutro e o chroma é clampado, então o
contraste WCAG AA é preservado em toda matiz — um teste varre as 360 matizes e
casa as constantes com o globals.css (trava contra drift). @supports garante
fallback seguro em engines sem relative color.

Também:
- remove tokens --sidebar-* mortos (nenhum componente os referenciava)
- corrige overflow horizontal do seletor de Densidade a 320px (reflow WCAG 1.4.10)
O react-doctor@latest passou a tratar no-ref-current-in-render como erro,
quebrando o CI do repo — o gate roda @latest (sem pin) e o último verde do
main é anterior ao bump. Os 3 pontos (dashboard, histórico, use-supabase-query)
são o padrão latest-ref legítimo: ref.current recebe o valor/handler mais
recente em render para um listener/effect assinar uma vez. São falsos-positivos;
adiciona react-doctor-disable-next-line justificado em cada, no estilo já usado
no projeto.
@johnlaff
johnlaff merged commit 0d145ea into main Jul 22, 2026
1 check passed
@johnlaff
johnlaff deleted the feat/accent-background-tint branch July 22, 2026 16:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant