Redesign station cards with compact layout, improved typography, and expandable details
Some checks failed
linter / quality (push) Has been cancelled
tests / ci (8.3) (push) Has been cancelled
tests / ci (8.4) (push) Has been cancelled
tests / ci (8.5) (push) Has been cancelled

- Reduce header size and weight, convert all-caps brand names to title case
- Replace address line with distance-only in collapsed state, move brand label to expanded section
- Apply monospace font to pricing, reduce size and weight across labels
- Move badge list and full details into expandable section
- Normalize font weights throughout (semibold for headings, medium for labels)
- Create `.pill` component class with `.is-active` state for consistent filter styling
- Apply pill styling to SearchBar filters, StationList sort buttons, and brand filter
- Add `name` attributes to fuel type and radius selects
- Update package dependencies (@tailwindcss/node, @tailwindcss/oxide, @rolldown/*)
This commit is contained in:
Ovidiu U
2026-04-22 11:23:05 +01:00
parent dd9bd95657
commit 8335f49fd6
5 changed files with 281 additions and 293 deletions

View File

@@ -13,18 +13,15 @@
>
<div class="flex justify-between items-start gap-3">
<div class="space-y-0.5 min-w-0 flex-1">
<p v-if="brandLabel" class="text-[10px] font-black uppercase tracking-widest text-zinc-500">
{{ brandLabel }}
</p>
<h4 class="font-bold text-lg text-zinc-800 truncate">{{ station.name }}</h4>
<h4 class="font-semibold text-sm text-zinc-800 truncate">{{ displayName }}</h4>
<template v-if="!expanded">
<p class="text-xs text-zinc-500 flex items-center gap-1">
<iconify-icon class="text-xs" icon="lucide:map-pin"></iconify-icon>
<span class="truncate">{{ locationLine }}</span>
<span>{{ distanceMiles }} mi</span>
</p>
<p v-if="updatedAgo" :class="[priceColor, 'text-xs flex items-center gap-1 font-semibold']">
<p v-if="updatedAgo" :class="[priceColor, 'text-xs flex items-center gap-1']">
<iconify-icon class="text-xs" icon="lucide:clock"></iconify-icon>
<span>Updated {{ updatedAgo }}</span>
<span>{{ updatedAgo }}</span>
</p>
</template>
</div>
@@ -38,14 +35,14 @@
>
<iconify-icon class="text-lg" icon="lucide:navigation"></iconify-icon>
</a>
<div class="text-right shrink-0">
<div :class="priceColor" class="text-xl font-black">
{{ station.price }}<span class="text-sm font-bold uppercase ml-0.5">p</span>
<div class="text-right shrink-0 font-mono font-medium">
<div :class="priceColor" class="text-zinc-900 tabular-nums">
{{ station.price }}p
</div>
<p :class="priceColor" class="text-[10px] font-bold uppercase tracking-wider">
<p :class="priceColor" class="text-[10px]">
{{ statusLabel }}
</p>
<p v-if="priceDelta" :class="priceDeltaColor" class="text-[10px] font-bold mt-0.5">
<p v-if="priceDelta" :class="priceDeltaColor" class="text-[11px] font-semibold mt-0.5">
{{ priceDelta }}
</p>
</div>
@@ -60,6 +57,10 @@
leave-to-class="opacity-0"
>
<div v-if="expanded" class="border-t border-zinc-200 pt-3 space-y-3">
<p v-if="brandLabel" class="text-[10px] font-black uppercase tracking-widest text-zinc-500">
{{ brandLabel }}
</p>
<div v-if="badges.length" class="flex flex-wrap gap-1.5">
<span
v-for="badge in badges"
@@ -207,9 +208,10 @@ const statusLabel = computed(() => reliabilityInfo.value.label)
const distanceMiles = computed(() => (props.station.distance_km * 0.621371).toFixed(1))
const locationLine = computed(() => {
const parts = [props.station.address, `${distanceMiles.value} mi`].filter(Boolean)
return parts.join(' • ')
const displayName = computed(() => {
const name = props.station.name ?? ''
if (name !== name.toUpperCase()) return name
return name.toLowerCase().replace(/\b\w/g, c => c.toUpperCase())
})
const fullAddress = computed(() => {