diff --git a/client/components/MobileTrackerRow.jsx b/client/components/MobileTrackerRow.jsx
index 45c763a..a259257 100644
--- a/client/components/MobileTrackerRow.jsx
+++ b/client/components/MobileTrackerRow.jsx
@@ -108,7 +108,7 @@ function EditableCell({ row, field, threshold, defaultPaymentDate, refresh }) {
onChange={e => setValue(e.target.value)}
onBlur={commit}
onKeyDown={onKeyDown}
- className="h-7 w-28 text-right font-mono text-sm bg-background/80 border-border/60"
+ className="tracker-number h-7 w-28 text-right text-sm font-medium bg-background/80 border-border/60"
/>
);
}
@@ -118,7 +118,7 @@ function EditableCell({ row, field, threshold, defaultPaymentDate, refresh }) {
onClick={startEdit}
title={`Click to edit ${field === 'amount' ? 'payment amount' : 'paid date'}`}
className={cn(
- 'cursor-pointer rounded-md px-1.5 py-0.5 text-sm font-mono',
+ 'tracker-number cursor-pointer rounded-md px-1.5 py-0.5 text-sm font-semibold',
'transition-all duration-150 hover:bg-accent hover:ring-1 hover:ring-border',
isEmpty && 'text-muted-foreground',
mismatch && 'text-amber-500',
@@ -185,7 +185,7 @@ export const MobileTrackerRow = React.memo(function MobileTrackerRow({ row, year
type="button"
onClick={() => onEditBill?.(row)}
className={cn(
- 'min-w-0 truncate text-left text-sm font-semibold leading-tight text-foreground',
+ 'min-w-0 truncate text-left text-[15px] font-semibold leading-tight text-foreground',
'underline-offset-2 transition-colors hover:text-primary hover:underline',
isSkipped && 'line-through',
)}
@@ -206,7 +206,7 @@ export const MobileTrackerRow = React.memo(function MobileTrackerRow({ row, year
Due
-
{fmtDate(row.due_date)}
+
{fmtDate(row.due_date)}
Category
@@ -214,13 +214,13 @@ export const MobileTrackerRow = React.memo(function MobileTrackerRow({ row, year
Expected
-
+
{fmt(threshold)}
Remaining
-
0 ? 'text-foreground' : 'text-emerald-500')}>
+
0 ? 'text-foreground' : 'text-emerald-300')}>
{fmt(remaining)}
@@ -230,11 +230,11 @@ export const MobileTrackerRow = React.memo(function MobileTrackerRow({ row, year
Paid
- {row.total_paid > 0 ? fmt(row.total_paid) : '—'}
+ {row.total_paid > 0 ? fmt(row.total_paid) : '—'}
Date
- {row.last_paid_date ? fmtDate(row.last_paid_date) : '—'}
+ {row.last_paid_date ? fmtDate(row.last_paid_date) : '—'}
@@ -245,7 +245,7 @@ export const MobileTrackerRow = React.memo(function MobileTrackerRow({ row, year
ref={amountRef}
type="number" min="0" step="0.01"
defaultValue={threshold}
- className="h-8 w-24 text-right font-mono text-sm bg-background/70 border-border/60"
+ className="tracker-number h-8 w-24 text-right text-sm font-medium bg-background/70 border-border/60"
title="Payment amount"
aria-label={`${row.name} payment amount`}
/>
diff --git a/client/index.css b/client/index.css
index 4334029..809323a 100644
--- a/client/index.css
+++ b/client/index.css
@@ -150,6 +150,14 @@
@apply surface overflow-hidden shadow-sm;
}
+ .tracker-number {
+ font-family: Inter, Roboto, ui-sans-serif, system-ui, sans-serif;
+ font-variant-numeric: tabular-nums lining-nums;
+ font-feature-settings: "tnum" 1, "lnum" 1;
+ -webkit-font-smoothing: auto;
+ text-rendering: optimizeLegibility;
+ }
+
/* Custom Scrollbar */
.scrollbar-thin {
scrollbar-width: thin;
diff --git a/client/pages/TrackerPage.jsx b/client/pages/TrackerPage.jsx
index 384e990..35a1b11 100644
--- a/client/pages/TrackerPage.jsx
+++ b/client/pages/TrackerPage.jsx
@@ -477,7 +477,7 @@ function PaymentProgress({ row, threshold, onOpen, onMarkFullAmount, compact = f
title="View payment history"
>
- 0 ? 'text-emerald-500' : 'text-muted-foreground')}>
+ 0 ? 'text-emerald-300' : 'text-muted-foreground/85')}>
{amountLabel}
{summary.count > 1 && (
@@ -1456,7 +1456,7 @@ function Row({ row, year, month, refresh, index, onEditBill }) {
target="_blank"
rel="noreferrer"
className={cn(
- 'font-medium text-sm leading-tight transition-colors',
+ 'text-[15px] font-semibold leading-tight text-foreground transition-colors',
'hover:underline decoration-muted-foreground/50 underline-offset-2',
isSkipped && 'line-through',
)}
@@ -1464,7 +1464,7 @@ function Row({ row, year, month, refresh, index, onEditBill }) {
{row.name}
) : (
-
+
{row.name}
)}
@@ -1478,7 +1478,7 @@ function Row({ row, year, month, refresh, index, onEditBill }) {
{row.category_name && (
-
{row.category_name}
+
{row.category_name}
)}
{/* Monthly notes shown inline under the bill name */}
{row.monthly_notes && (
@@ -1492,7 +1492,7 @@ function Row({ row, year, month, refresh, index, onEditBill }) {
{/* Due */}
-
+
{editingDue ? (
) : (
@@ -1521,7 +1521,7 @@ function Row({ row, year, month, refresh, index, onEditBill }) {
{/* Expected / Actual — shows actual_amount in amber when it overrides the template */}
-
+
{editingExpected ? (
) : effectiveActual != null ? (
{/* Previous month paid */}
-
+
{row.previous_month_paid > 0 ? fmt(row.previous_month_paid) : '—'}
@@ -1586,11 +1586,11 @@ function Row({ row, year, month, refresh, index, onEditBill }) {
{/* Paid date */}
-
+
setPaymentLedgerOpen(true)}
- className="rounded-md px-1.5 py-0.5 font-mono transition-colors hover:bg-accent hover:text-foreground"
+ className="tracker-number rounded-md px-1.5 py-0.5 font-medium transition-colors hover:bg-accent hover:text-foreground"
title="View payment history"
>
{row.last_paid_date ? fmtDate(row.last_paid_date) : '—'}
@@ -1650,7 +1650,7 @@ function Row({ row, year, month, refresh, index, onEditBill }) {
ref={amountRef}
type="number" min="0" step="0.01"
defaultValue={summary.remaining || threshold}
- className="h-7 w-20 text-right font-mono text-sm bg-background/50 border-border/50"
+ className="tracker-number h-7 w-20 text-right text-sm font-medium bg-background/50 border-border/50"
title="Payment amount"
/>
) : (
-
+
{row.name}
)}
@@ -1888,7 +1888,7 @@ function MobileTrackerRow({ row, year, month, refresh, index, onEditBill }) {
Due
-
{fmtDate(row.due_date)}
+
{fmtDate(row.due_date)}
Category
@@ -1896,19 +1896,19 @@ function MobileTrackerRow({ row, year, month, refresh, index, onEditBill }) {
Expected
-
+
{fmt(threshold)}
Last Month
-
+
{fmt(row.previous_month_paid)}
Remaining
-
0 ? 'text-foreground' : 'text-emerald-500')}>
+
0 ? 'text-foreground' : 'text-emerald-300')}>
{fmt(remaining)}
@@ -1922,14 +1922,14 @@ function MobileTrackerRow({ row, year, month, refresh, index, onEditBill }) {
Paid
- {row.total_paid > 0 ? fmt(row.total_paid) : '—'}
+ {row.total_paid > 0 ? fmt(row.total_paid) : '—'}
Date
setPaymentLedgerOpen(true)}
- className="rounded font-mono text-foreground underline-offset-2 hover:underline"
+ className="tracker-number rounded font-medium text-foreground underline-offset-2 hover:underline"
>
{row.last_paid_date ? fmtDate(row.last_paid_date) : '—'}
{summary.count > 1 && ({summary.count})}
@@ -1953,7 +1953,7 @@ function MobileTrackerRow({ row, year, month, refresh, index, onEditBill }) {
ref={amountRef}
type="number" min="0" step="0.01"
defaultValue={summary.remaining || threshold}
- className="h-8 w-24 text-right font-mono text-sm bg-background/70 border-border/60"
+ className="tracker-number h-8 w-24 text-right text-sm font-medium bg-background/70 border-border/60"
title="Payment amount"
aria-label={`${row.name} payment amount`}
/>
diff --git a/package.json b/package.json
index 91d9f06..3568b18 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "bill-tracker",
- "version": "0.28.4.3",
+ "version": "0.28.4.4",
"description": "Monthly bill tracking system",
"main": "server.js",
"scripts": {