Skip to content

feat(budget): quoted amount as single muted value + vendor on second line#1454

Merged
steilerDev merged 3 commits into
betafrom
feat/1449-quoted-amount-vendor-line-rework
May 17, 2026
Merged

feat(budget): quoted amount as single muted value + vendor on second line#1454
steilerDev merged 3 commits into
betafrom
feat/1449-quoted-amount-vendor-line-rework

Conversation

@steilerDev
Copy link
Copy Markdown
Owner

Summary

  • Introduces --color-text-quoted design token (CSS) and applies it in BudgetLineCard and InvoiceGroup to render invoiced/quoted amounts in a visually distinct muted color, clearly distinguishing them from actual spend
  • Moves vendor detail to a dedicated second line in InvoiceGroup for improved readability and visual hierarchy
  • Adds vendorDetail.invoicedAmount i18n key to English and German (Rechnungsbetrag) locale files
  • Adds BudgetLineCard.test.tsx (new file, 95%+ coverage) and updates InvoiceGroup.test.tsx and E2E assertions in budget-vat-quotation-fixes.spec.ts

Notes

  • ±5% range indicator: The per-item ±5% tolerance indicator was removed from BudgetLineCard only (in scope for feat(budget): quoted amount as single value with quoted-text color + vendor on second line #1449). The CostBreakdownTable on the /budget overview page is unchanged — that is tracked as a separate follow-up.
  • Style Guide wiki entry: The --color-text-quoted token entry was authored by ux-designer in commit 52fcbc3d but the actual wiki page content edit was lost (local edit not pushed to the wiki submodule). A separate wiki housekeeping PR is needed to document the token in the Style Guide page post-merge.

Fixes #1449

Test plan

  • Unit tests pass — BudgetLineCard.test.tsx and InvoiceGroup.test.tsx (95%+ coverage)
  • E2E assertions updated in budget-vat-quotation-fixes.spec.ts
  • Pre-commit hook quality gates pass
  • --color-text-quoted token renders correctly in light and dark mode

Co-Authored-By: Claude Opus 4.7 (1M context) noreply@anthropic.com

Frank Steiler and others added 3 commits May 17, 2026 14:15
…er memory (issue #1449)

Co-Authored-By: Claude ux-designer (Sonnet 4.6) <noreply@anthropic.com>
…line

Display invoiced/quoted amount in budget line cards using a muted color
(--color-text-quoted token) to visually distinguish it from actual spend.
Vendor detail is now rendered on a dedicated second line in InvoiceGroup
for improved readability.

Fixes #1449

Co-Authored-By: Claude dev-team-lead (Sonnet 4.6) <noreply@anthropic.com>
Co-Authored-By: Claude ux-designer (Sonnet 4.5) <noreply@anthropic.com>
Co-Authored-By: Claude frontend-developer (Haiku 4.5) <noreply@anthropic.com>
Co-Authored-By: Claude qa-integration-tester (Sonnet 4.5) <noreply@anthropic.com>
Co-Authored-By: Claude e2e-test-engineer (Sonnet 4.5) <noreply@anthropic.com>
Co-Authored-By: Claude translator (Sonnet 4.5) <noreply@anthropic.com>
The previous Assert 5 scoped not.toContainText(' – ') to the entire
budget section, but BudgetCostOverview legitimately renders planned-cost
ranges (e.g. €600.00 – €720.00) when a budget line has a non-zero
confidence margin. Narrowed the assertion to the invoiceGroup locator,
which is the precise target for the issue #1449 regression guard.

Co-Authored-By: Claude dev-team-lead (Sonnet 4.6) <noreply@anthropic.com>
Co-Authored-By: Claude e2e-test-engineer (Sonnet 4.6) <noreply@anthropic.com>
Copy link
Copy Markdown
Owner Author

@steilerDev steilerDev left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[product-architect]

Reviewed scope, tokens, contracts, and test parity for the single-value quoted-amount + vendor-line rework.

1. Backend / contract impact — None. git diff origin/beta...HEAD -- shared/ server/ returns zero lines. Display-only.

2. No silent semantic changes — Confirmed. BudgetOverviewPage.tsx and CostBreakdownTable.tsx are untouched (diff = 0 lines). The ±5% band removal and amountValueQuoted styling are scoped strictly to BudgetLineCard and InvoiceGroup (work-item / household-item budget sections). CostBreakdownTable retains its own range logic — correctly tracked as a separate follow-up per PR body.

3. Token placement--color-text-quoted is defined in tokens.css in both :root (gray-500) and [data-theme='dark'] (slate-200) blocks, no hex literals. The dark-mode override that previously lived inline in BudgetLineCard.module.css is correctly removed in favor of the token. Token is also documented in wiki/Style-Guide.md line 143 with WCAG AA contrast verified — the PR body claim that the wiki entry is missing is stale (it landed in commit 52fcbc3).

4. Test parity — All production lines have corresponding tests:

  • BudgetLineCard.tsx (2/4 lines): new BudgetLineCard.test.tsx (471 lines)
  • InvoiceGroup.tsx (15/13 lines): InvoiceGroup.test.tsx adds 7 new assertions covering quotation single-value, no en-dash, invoiceIdentity wrapper, status-badge sibling, null-vendor path, and amountValueQuoted class toggling
  • E2E budget-vat-quotation-fixes.spec.ts updated to assert €500.00 and no separator anywhere in the InvoiceGroup

5. No regressions to other invoice statusesamountValueQuoted class is only applied when invoiceStatus === 'quotation'; paid/draft/etc. branches retain amountValue styling unchanged. amountValueMuted (cancelled, strikethrough) is untouched. The wiki submodule bump (b76a9e0a → c587406b) is for ADR-029 from #1440/#1441, not part of this PR's scope but harmless.

Bonus quality improvement: InvoiceGroup.module.css migrated from hardcoded values (0.75rem, 0.9375rem, 0.25rem) to design tokens (--spacing-3, --font-size-base, --radius-sm). Aligns with the token-usage policy in CLAUDE.md.

VERDICT: APPROVED

Copy link
Copy Markdown
Owner Author

@steilerDev steilerDev left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[ux-designer]

PR #1454 — Visual spec compliance review for issue #1449 (quoted-amount + vendor line rework).


Token implementation — --color-text-quoted

Confirmed in tokens.css:

  • Light (:root): var(--color-gray-500) (#6b7280) — 4.6:1 on --color-bg-primary. Passes WCAG AA.
  • Dark ([data-theme="dark"]): var(--color-slate-200) (#94a3b8) — 5.8:1 on --color-bg-primary dark. Passes WCAG AA.
  • Both placements are correctly in the existing text-color blocks.

BudgetLineCard.module.css migration

.amountQuoted and .quotedLabel both migrated to var(--color-text-quoted). The four manual [data-theme='dark'] overrides are correctly removed — the semantic token handles both modes automatically.

InvoiceGroup.module.css — token migration and .amountValueQuoted

All previously hardcoded values (0.375rem, 0.75rem 1rem, 0.5rem, 1rem, 0.125rem, 0.9375rem, 0.25rem, 0.75rem, 1.5rem, 0.2s ease-out, 1.5rem icon size, etc.) are correctly replaced with design tokens. .amountValueQuoted rule is added as a colour-only modifier (color: var(--color-text-quoted)) and applied via className concatenation — correct pattern.

Layout structure — .invoiceIdentity

flex-direction: column; gap: var(--spacing-0-5) wraps the invoice link and conditional vendor span. The status badge is a sibling of .invoiceIdentity inside .invoiceInfo, matching the ASCII mockup from the spec. align-items: flex-start on .invoiceInfo ensures top-alignment as the identity grows taller.

Vendor name font-size

.vendorName correctly uses var(--font-size-xs) per spec.

Accessibility

aria-label on the group uses Invoice ${number} from ${vendorName}: N budget lines, €X <amountLabel> — vendor is included when present, omitted when null. No regression.

Responsive

Mobile breakpoint (≤767px) already handled: .toggleBtn min-height: 44px, .headerContent stacks to column. The .invoiceIdentity column layout is narrower on mobile but requires no additional breakpoint rule.

i18n

t('vendorDetail.invoicedAmount') replaces the hardcoded 'Invoiced' string in both InvoiceGroup.tsx and BudgetLineCard.tsx. Keys added to both en/budget.json and de/budget.json.

Pre-existing informational note (non-blocking)

font-weight literals (400/500/600) remain throughout InvoiceGroup.module.css — token equivalents exist (--font-weight-normal/medium/semibold). These are pre-existing and not introduced by this PR; flag for a general cleanup pass, not this PR.


Wiki / Style Guide follow-up (non-blocking)

Commit 52fcbc3d (the earlier spec commit) appeared to add a --color-text-quoted Style Guide entry but the wiki content edit was lost — only the submodule pointer moved. This PR's submodule bump (c587406b) does include the entry at line 143 of Style-Guide.md, so the wiki documentation is now correct. No separate follow-up PR is needed; the content is present. I acknowledge the earlier confusion and confirm the wiki is in the correct state.


All spec requirements are met. Token adherence, dark mode, layout, accessibility, and i18n are correctly implemented.

VERDICT: APPROVED

Copy link
Copy Markdown
Owner Author

@steilerDev steilerDev left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[product-owner]

Verified PR #1454 against issue #1449 acceptance criteria.

Acceptance criteria — all met:

  1. AC #1 (quoted amount as single value on WI page) — PASS. BudgetLineCard.tsx line 49 now renders formatCurrency(line.actualCost) unconditionally; the * 0.95 / * 1.05 template-literal range is removed.
  2. AC #2 (--color-text-quoted token applied) — PASS. BudgetLineCard.module.css .amountQuoted and .quotedLabel both use var(--color-text-quoted); theme-specific overrides removed in favor of the semantic token.
  3. AC #3 (non-quotation display unchanged) — PASS. The non-quotation branch in both BudgetLineCard and InvoiceGroup still renders formatCurrency(line.actualCost) / formatCurrency(itemizedTotal) with .amountInvoiced / .amountValue classes.
  4. AC #4 (vendor on second line) — PASS. InvoiceGroup.tsx introduces .invoiceIdentity flex-column wrapper containing the invoice link on line 1 and .vendorName on line 2; status badge stays on the same row as the identity block.
  5. AC #5 (vendor smaller font) — PASS. .vendorName font-size changed from --font-size-sm to --font-size-xs, smaller than .invoiceNumber (--font-weight: 600, base size).
  6. AC #6 (no second line when vendor null) — PASS. {vendorName && <span className={styles.vendorName}>...} short-circuits cleanly inside .invoiceIdentity.

Out-of-scope guardrails: BudgetOverviewPage and CostBreakdownTable untouched (verified via git diff --name-only).

Bonus i18n fix: vendorDetail.invoicedAmount key added to both en/budget.json ("Invoiced Amount") and de/budget.json ("Rechnungsbetrag"), replacing the hardcoded 'Invoiced Amount' literal in BudgetLineCard.tsx and InvoiceGroup.tsx. Glossary-compliant.

E2E budget-vat-quotation-fixes.spec.ts updated to assert single €500.00 value and absence of any range separator — good regression pin against both old broken states.

VERDICT: APPROVED

@steilerDev steilerDev merged commit a2cb4c6 into beta May 17, 2026
28 of 30 checks passed
@steilerDev steilerDev deleted the feat/1449-quoted-amount-vendor-line-rework branch May 17, 2026 15:16
@github-actions
Copy link
Copy Markdown
Contributor

🎉 This PR is included in version 2.6.0-beta.22 🎉

The release is available on GitHub release

Your semantic-release bot 📦🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant