unic / unic/ai-developer-hub

Color budget Variance and YTD Util. by sign / threshold (today they render in plain text)

Open
#58 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

a11y area:ux enhancement priority:low
Dominant language
HTML
Stars
0
Forks
0
PR merge metrics
No merged PRs in 30d

Description

Problem

Two prominent budget KPIs render as plain neutral text regardless of whether the value is favorable, neutral, or alarming:

  • "Variance" on /budget — currently shows -$28,743.84 in the same color as "Total Budget" and "Allocated".
  • "YTD Budget Util." on the dashboard — currently shows 108% in default text style even though the value is over 100% (i.e. budget already overrun for the year).

Other parts of the app already use semantic color: the Budget Alert banner, the over-100% workspace progress bars on /claude. The dashboard tiles and the FY card on /budget should match that vocabulary so an admin scanning the page can spot trouble at a glance — currently a 108% overspend looks identical to a 50% utilisation.

Evidence

Browser smoke test on /budget and / (2026-04-28). Screenshots saved under C:\Users\stude\AppData\Local\Temp\smoke-budget.png and smoke-dashboard.png (locally — feel free to recreate via the steps in the verification section).

Implicated components (find via grep on "Variance" and "YTD Budget"):

  • /budget summary card — likely under src/app/budget/ or src/components/.
  • Dashboard KPI tile — likely under src/app/page.tsx or src/components/dashboard*.

Proposed approach

  1. Decide the thresholds — propose:
    • Utilisation < 80% → default/muted-foreground.
    • 80%–100% → amber (text-amber-500 / shadcn warning palette).
    • > 100% → destructive red (text-destructive).
    • Variance: positive (under-spend) → muted/neutral; negative (over-spend) → destructive.
  2. Extract the threshold logic into one small helper (e.g. src/lib/budget-color.ts) that returns a Tailwind class string. Reuse it on both the dashboard KPI tile and the /budget FY card.
  3. Update both call sites to apply the class to the value's wrapping span.
  4. Add appropriate aria-label (e.g. \"Variance: -$28,743.84 (over budget)\") so screen-reader users get the semantic info that sighted users get from color — required for a11y and the reason this issue is also tagged a11y.
  5. Add a Vitest unit test for the helper covering boundaries (79.9, 80, 99.9, 100, 100.1).

Acceptance criteria

  • Variance value is colored red when negative, neutral when positive.
  • YTD Util. tile is colored amber at ≥80% and red at >100%.
  • Both elements include an aria-label describing the status in words, not only color.
  • One shared helper drives both call sites.
  • Unit tests cover the helper.
  • pnpm lint && pnpm typecheck && pnpm test pass.

Verification

  1. With seed data showing a 108% YTD utilisation: visit / → tile is red and screen-reader announces "over budget". Visit /budget → Variance row is red.
  2. Manually set utilisation to 75% (e.g. by inserting a smaller billed_costs total in dev) → tile becomes neutral.
  3. Manually set utilisation to 90% → tile becomes amber.

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by grepping for "Variance" and "YTD Budget" in src/app/budget/, src/app/page.tsx, and src/components/. Add the shared threshold behavior and accessible status labels described in the acceptance criteria, then cover the boundaries with a unit test and run pnpm lint && pnpm typecheck && pnpm test. Done means the dashboard and budget values use the expected neutral, amber, or red states for the verification scenarios.

Written by the indexing model from the issue text.

Assessment

Tech stack
tailwindcss, typescript
Domain
accessibility, frontend, testing
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Quiet
Clarity
Clearly specified
Newbie friendliness
72/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.