cleanup: stats KPI cards — extract 4 inline styles into reusable classes

The six-tile overview grid at the top of the Statistik tab built
each KPI card as a four-property inline-styled div:

  <div style="background: var(--bg-elevated); border: 1px solid
              var(--border-soft); border-radius: 6px; padding: 12px;">
    <div style="font-size: 11px; color: var(--text-secondary);
                text-transform: uppercase; letter-spacing: 0.5px;">
    <div style="font-size: 22px; font-weight: 600; margin-top: 4px;">
    <div style="font-size: 12px; color: var(--text-secondary);
                margin-top: 4px;">

Each card repeated the same ~250 chars of inline styling. Card hover
state, number alignment, future polish all required editing the
renderer.

Extracted to .stats-kpi-card + .stats-kpi-label + .stats-kpi-value
+ .stats-kpi-sub. Added two enhancements while at it:
- subtle hover state (purple-tint border + 1px lift) so the cards
  feel interactive in line with the rest of the apps language
- font-variant-numeric: tabular-nums on values + subs so the
  numbers align properly across the six-tile grid

Also stats-no-root for the "Download folder not found" fallback
that grid-column-spans across all 6 columns.

The remaining 22 inline styles in renderer-stats (top-streamers
bar list, activity calendar, size buckets) come in subsequent
iterations.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
xRangerDE 2026-05-11 04:50:23 +02:00
parent 3905b73751
commit 874f64c1ba
2 changed files with 50 additions and 5 deletions

View File

@ -44,7 +44,7 @@ function renderStatsSummary(stats: ArchiveStats): void {
if (!grid) return;
if (!stats.rootExists) {
applyHtml(grid, `<div style="grid-column: 1 / -1; color: var(--text-secondary);">${escapeStatsHtml(UI_TEXT.static.statsNoRoot)}</div>`);
applyHtml(grid, `<div class="stats-no-root">${escapeStatsHtml(UI_TEXT.static.statsNoRoot)}</div>`);
return;
}
@ -58,10 +58,10 @@ function renderStatsSummary(stats: ArchiveStats): void {
];
applyHtml(grid, cards.map((c) => `
<div style="background: var(--bg-elevated); border: 1px solid var(--border-soft); border-radius: 6px; padding: 12px;">
<div style="font-size: 11px; color: var(--text-secondary); text-transform: uppercase; letter-spacing: 0.5px;">${escapeStatsHtml(c.label)}</div>
<div style="font-size: 22px; font-weight: 600; margin-top: 4px;">${escapeStatsHtml(c.value)}</div>
${c.sub ? `<div style="font-size: 12px; color: var(--text-secondary); margin-top: 4px;">${escapeStatsHtml(c.sub)}</div>` : ''}
<div class="stats-kpi-card">
<div class="stats-kpi-label">${escapeStatsHtml(c.label)}</div>
<div class="stats-kpi-value">${escapeStatsHtml(c.value)}</div>
${c.sub ? `<div class="stats-kpi-sub">${escapeStatsHtml(c.sub)}</div>` : ''}
</div>
`).join(''));
}

View File

@ -2208,6 +2208,51 @@ select option {
color: #9146ff;
}
/* ============================================
STATS DASHBOARD KPI CARDS
============================================
Six-tile overview grid at the top of the Statistik tab. Each card
shows a label (uppercase track), a big value, and an optional
secondary line (e.g. byte-size total under the count). */
.stats-kpi-card {
background: var(--bg-elevated);
border: 1px solid var(--border-soft);
border-radius: 6px;
padding: 12px;
transition: border-color 0.18s, transform 0.18s;
}
.stats-kpi-card:hover {
border-color: rgba(145, 70, 255, 0.4);
transform: translateY(-1px);
}
.stats-kpi-label {
font-size: 11px;
color: var(--text-secondary);
text-transform: uppercase;
letter-spacing: 0.5px;
}
.stats-kpi-value {
font-size: 22px;
font-weight: 600;
margin-top: 4px;
font-variant-numeric: tabular-nums;
}
.stats-kpi-sub {
font-size: 12px;
color: var(--text-secondary);
margin-top: 4px;
font-variant-numeric: tabular-nums;
}
.stats-no-root {
grid-column: 1 / -1;
color: var(--text-secondary);
}
/* Old generic scrollbar rules were dead superseded by the
purple-themed *::-webkit-scrollbar block further down the file.
Removed to avoid confusion when someone greps for scrollbar styles. */