style(stats): add bg-surface to cards/pills/tabs, reorder tabs

- Add bg-surface background to roast stats, consumption, and country pill cards
- Update tab CSS: bg-surface background, hover:border-accent/40 instead of bg-surface-alt
- Add hover:border-accent/40 to clickable country pill buttons
- Make Roasts the first and default tab on the stats page
This commit is contained in:
Jon Seager 2026-02-08 16:47:30 +00:00
parent 4fd72d654a
commit ccbd229d75
No known key found for this signature in database
4 changed files with 18 additions and 18 deletions

View file

@ -17,14 +17,14 @@ use crate::presentation::web::templates::{
}; };
const TABS: &[Tab] = &[ const TABS: &[Tab] = &[
Tab {
key: "roasters",
label: "Roasters",
},
Tab { Tab {
key: "roasts", key: "roasts",
label: "Roasts", label: "Roasts",
}, },
Tab {
key: "roasters",
label: "Roasters",
},
Tab { Tab {
key: "cups", key: "cups",
label: "Cups", label: "Cups",
@ -42,7 +42,7 @@ pub(crate) struct StatsQuery {
} }
fn default_type() -> String { fn default_type() -> String {
"roasters".to_string() "roasts".to_string()
} }
#[tracing::instrument(skip(state, cookies, headers, stats_query))] #[tracing::instrument(skip(state, cookies, headers, stats_query))]

View file

@ -342,13 +342,13 @@ input.input-field[type="number"] {
font-weight: 500; font-weight: 500;
cursor: pointer; cursor: pointer;
border: 1px solid var(--border); border: 1px solid var(--border);
background: none; background-color: var(--surface);
transition: background-color 150ms ease, color 150ms ease, border-color 150ms ease; transition: background-color 150ms ease, color 150ms ease, border-color 150ms ease;
color: var(--accent); color: var(--accent);
} }
.tab:not(.tab-active):hover { .tab:not(.tab-active):hover {
background-color: var(--surface-alt); border-color: color-mix(in srgb, var(--accent) 40%, transparent);
} }
.tab-active { .tab-active {

View file

@ -27,17 +27,17 @@
<h2 class="text-lg font-semibold text-text">Roast Stats</h2> <h2 class="text-lg font-semibold text-text">Roast Stats</h2>
</div> </div>
<div class="grid gap-3 sm:grid-cols-3"> <div class="grid gap-3 sm:grid-cols-3">
<div class="flex flex-col items-center gap-1 rounded-lg border p-4"> <div class="flex flex-col items-center gap-1 rounded-lg border bg-surface p-4">
{{ icons::map("h-6 w-6 text-accent") }} {{ icons::map("h-6 w-6 text-accent") }}
<span class="text-lg font-bold text-text">{{ roast_summary.unique_origins }}</span> <span class="text-lg font-bold text-text">{{ roast_summary.unique_origins }}</span>
<span class="text-sm font-medium text-accent">Origins</span> <span class="text-sm font-medium text-accent">Origins</span>
</div> </div>
<div class="flex flex-col items-center gap-1 rounded-lg border p-4"> <div class="flex flex-col items-center gap-1 rounded-lg border bg-surface p-4">
{{ icons::location("h-6 w-6 text-accent") }} {{ icons::location("h-6 w-6 text-accent") }}
<span class="text-lg font-bold text-text truncate max-w-full">{% match roast_summary.top_origin %}{% when Some with (v) %}{{ v }}{% when None %}&mdash;{% endmatch %}</span> <span class="text-lg font-bold text-text truncate max-w-full">{% match roast_summary.top_origin %}{% when Some with (v) %}{{ v }}{% when None %}&mdash;{% endmatch %}</span>
<span class="text-sm font-medium text-accent">Top Origin</span> <span class="text-sm font-medium text-accent">Top Origin</span>
</div> </div>
<div class="flex flex-col items-center gap-1 rounded-lg border p-4"> <div class="flex flex-col items-center gap-1 rounded-lg border bg-surface p-4">
{{ icons::fire("h-6 w-6 text-accent") }} {{ icons::fire("h-6 w-6 text-accent") }}
<span class="text-lg font-bold text-text truncate max-w-full">{% match roast_summary.top_roaster %}{% when Some with (v) %}{{ v }}{% when None %}&mdash;{% endmatch %}</span> <span class="text-lg font-bold text-text truncate max-w-full">{% match roast_summary.top_roaster %}{% when Some with (v) %}{{ v }}{% when None %}&mdash;{% endmatch %}</span>
<span class="text-sm font-medium text-accent">Top Roaster</span> <span class="text-sm font-medium text-accent">Top Roaster</span>
@ -66,22 +66,22 @@
<h2 class="text-lg font-semibold text-text">Consumption</h2> <h2 class="text-lg font-semibold text-text">Consumption</h2>
</div> </div>
<div class="grid grid-cols-2 gap-3 sm:grid-cols-4"> <div class="grid grid-cols-2 gap-3 sm:grid-cols-4">
<div class="flex flex-col items-center gap-1 rounded-lg border p-4"> <div class="flex flex-col items-center gap-1 rounded-lg border bg-surface p-4">
{{ icons::coffee_bean("h-6 w-6 text-accent") }} {{ icons::coffee_bean("h-6 w-6 text-accent") }}
<span class="text-lg font-bold text-text">{{ consumption_30d_weight }}</span> <span class="text-lg font-bold text-text">{{ consumption_30d_weight }}</span>
<span class="text-sm font-medium text-accent">Last 30 Days</span> <span class="text-sm font-medium text-accent">Last 30 Days</span>
</div> </div>
<div class="flex flex-col items-center gap-1 rounded-lg border p-4"> <div class="flex flex-col items-center gap-1 rounded-lg border bg-surface p-4">
{{ icons::coffee_bean("h-6 w-6 text-accent") }} {{ icons::coffee_bean("h-6 w-6 text-accent") }}
<span class="text-lg font-bold text-text">{{ consumption_all_time_weight }}</span> <span class="text-lg font-bold text-text">{{ consumption_all_time_weight }}</span>
<span class="text-sm font-medium text-accent">All Time</span> <span class="text-sm font-medium text-accent">All Time</span>
</div> </div>
<div class="flex flex-col items-center gap-1 rounded-lg border p-4"> <div class="flex flex-col items-center gap-1 rounded-lg border bg-surface p-4">
{{ icons::beaker("h-6 w-6 text-accent") }} {{ icons::beaker("h-6 w-6 text-accent") }}
<span class="text-lg font-bold text-text">{{ consumption.brews_last_30_days }}</span> <span class="text-lg font-bold text-text">{{ consumption.brews_last_30_days }}</span>
<span class="text-sm font-medium text-accent">Brews (30d)</span> <span class="text-sm font-medium text-accent">Brews (30d)</span>
</div> </div>
<div class="flex flex-col items-center gap-1 rounded-lg border p-4"> <div class="flex flex-col items-center gap-1 rounded-lg border bg-surface p-4">
{{ icons::beaker("h-6 w-6 text-accent") }} {{ icons::beaker("h-6 w-6 text-accent") }}
<span class="text-lg font-bold text-text">{{ consumption.brews_all_time }}</span> <span class="text-lg font-bold text-text">{{ consumption.brews_all_time }}</span>
<span class="text-sm font-medium text-accent">Brews (All Time)</span> <span class="text-sm font-medium text-accent">Brews (All Time)</span>
@ -132,7 +132,7 @@
<div class="mb-5"><div class="h-5 w-28 rounded bg-surface-alt"></div></div> <div class="mb-5"><div class="h-5 w-28 rounded bg-surface-alt"></div></div>
<div class="grid gap-3 sm:grid-cols-3"> <div class="grid gap-3 sm:grid-cols-3">
{% for _ in 0..3 %} {% for _ in 0..3 %}
<div class="flex flex-col items-center gap-1 rounded-lg border p-4"> <div class="flex flex-col items-center gap-1 rounded-lg border bg-surface p-4">
<div class="h-6 w-6 rounded-full bg-surface-alt"></div> <div class="h-6 w-6 rounded-full bg-surface-alt"></div>
<div class="h-5 w-10 rounded bg-surface-alt"></div> <div class="h-5 w-10 rounded bg-surface-alt"></div>
<div class="h-4 w-16 rounded bg-surface-alt"></div> <div class="h-4 w-16 rounded bg-surface-alt"></div>
@ -145,7 +145,7 @@
<div class="mb-5"><div class="h-5 w-32 rounded bg-surface-alt"></div></div> <div class="mb-5"><div class="h-5 w-32 rounded bg-surface-alt"></div></div>
<div class="grid grid-cols-2 gap-3 sm:grid-cols-4"> <div class="grid grid-cols-2 gap-3 sm:grid-cols-4">
{% for _ in 0..4 %} {% for _ in 0..4 %}
<div class="flex flex-col items-center gap-1 rounded-lg border p-4"> <div class="flex flex-col items-center gap-1 rounded-lg border bg-surface p-4">
<div class="h-6 w-6 rounded-full bg-surface-alt"></div> <div class="h-6 w-6 rounded-full bg-surface-alt"></div>
<div class="h-5 w-12 rounded bg-surface-alt"></div> <div class="h-5 w-12 rounded bg-surface-alt"></div>
<div class="h-4 w-20 rounded bg-surface-alt"></div> <div class="h-4 w-20 rounded bg-surface-alt"></div>

View file

@ -24,7 +24,7 @@
{% for entry in geo_stats.entries %} {% for entry in geo_stats.entries %}
{% if !entry.iso_code.is_empty() %} {% if !entry.iso_code.is_empty() %}
<button type="button" <button type="button"
class="inline-flex shrink-0 snap-start items-center rounded-full border text-sm transition cursor-pointer" class="inline-flex shrink-0 snap-start items-center rounded-full border bg-surface text-sm transition cursor-pointer hover:border-accent/40"
data-iso="{{ entry.iso_code|lower }}" data-iso="{{ entry.iso_code|lower }}"
onclick="const map = document.querySelector('world-map'); const iso = this.dataset.iso; const cur = map.getAttribute('data-selected'); if (cur === iso) { map.removeAttribute('data-selected'); } else { map.setAttribute('data-selected', iso); } document.querySelectorAll('[data-iso]').forEach(b => b.classList.toggle('bg-accent-subtle', b.dataset.iso === map.getAttribute('data-selected')));"> onclick="const map = document.querySelector('world-map'); const iso = this.dataset.iso; const cur = map.getAttribute('data-selected'); if (cur === iso) { map.removeAttribute('data-selected'); } else { map.setAttribute('data-selected', iso); } document.querySelectorAll('[data-iso]').forEach(b => b.classList.toggle('bg-accent-subtle', b.dataset.iso === map.getAttribute('data-selected')));">
<span class="inline-flex items-center gap-1.5 py-1.5 pl-3 pr-2"> <span class="inline-flex items-center gap-1.5 py-1.5 pl-3 pr-2">
@ -36,7 +36,7 @@
<span class="border-l py-1.5 pl-2 pr-3 font-semibold text-highlight">{{ entry.count }}</span> <span class="border-l py-1.5 pl-2 pr-3 font-semibold text-highlight">{{ entry.count }}</span>
</button> </button>
{% else %} {% else %}
<div class="inline-flex shrink-0 snap-start items-center rounded-full border text-sm"> <div class="inline-flex shrink-0 snap-start items-center rounded-full border bg-surface text-sm">
<span class="inline-flex items-center gap-1.5 py-1.5 pl-3 pr-2"> <span class="inline-flex items-center gap-1.5 py-1.5 pl-3 pr-2">
<span class="text-text whitespace-nowrap">{{ entry.country_name }}</span> <span class="text-text whitespace-nowrap">{{ entry.country_name }}</span>
</span> </span>