This commit is contained in:
Andras Schmelczer 2026-05-06 23:13:58 +01:00
parent 94f9c0d594
commit 5c3b87f2d5
69 changed files with 1334 additions and 213 deletions

View file

@ -281,8 +281,8 @@ const INSPECT_JOURNEYS: JourneyInstructionPreset[] = [
bestMinutes: 29,
legs: [
{ mode: 'Victoria', from: 'Oxford Circus Underground Station', to: 'Victoria', minutes: 4 },
{ mode: 'District', from: 'Victoria', to: 'Earl\'s Court', minutes: 10 },
{ mode: 'walk', from: 'Earl\'s Court', to: 'SW5 9AA', minutes: 7 },
{ mode: 'District', from: 'Victoria', to: "Earl's Court", minutes: 10 },
{ mode: 'walk', from: "Earl's Court", to: 'SW5 9AA', minutes: 7 },
],
},
];
@ -478,8 +478,7 @@ function FilterPreviewRow({
<span
className={`w-fit shrink-0 rounded-md px-2.5 py-1 text-xs font-bold leading-none ${style.chip}`}
>
+
<span className="font-mono tabular-nums">{withoutCount.toLocaleString()}</span>
+<span className="font-mono tabular-nums">{withoutCount.toLocaleString()}</span>
{' without this filter'}
</span>
</div>
@ -946,75 +945,73 @@ function ScoutScreen({ isActive }: { isActive: boolean }) {
<div
className={`overflow-hidden transition-all duration-500 ease-out ${
isTableRevealed
? 'mt-3 max-h-64 opacity-100 sm:mt-4'
: 'mt-0 max-h-0 opacity-0'
isTableRevealed ? 'mt-3 max-h-64 opacity-100 sm:mt-4' : 'mt-0 max-h-0 opacity-0'
}`}
aria-hidden={!isTableRevealed}
>
<div className="relative z-10 shrink-0 overflow-hidden rounded-lg border border-warm-200 bg-white shadow-xl shadow-navy-950/10 ring-1 ring-white/80 dark:border-navy-700 dark:bg-navy-900/70 dark:ring-white/5 dark:backdrop-blur-sm">
<div className="flex items-center justify-between gap-3 border-b border-warm-200 bg-gradient-to-r from-white via-emerald-50/80 to-white px-3 py-1.5 text-navy-950 dark:border-navy-700 dark:from-navy-900/90 dark:via-emerald-900/20 dark:to-navy-900/90 dark:text-warm-100 sm:px-4 sm:py-2">
<div className="flex min-w-0 items-center gap-2">
<span className="flex h-6 w-6 shrink-0 items-center justify-center rounded-md bg-emerald-600 text-white shadow-sm shadow-emerald-900/20 dark:bg-emerald-400 dark:text-navy-950 sm:h-7 sm:w-7">
<DownloadIcon className="h-3.5 w-3.5" />
</span>
<span className="min-w-0 truncate text-xs font-black sm:text-sm">
{t('home.showcaseStep4FileName')}
</span>
</div>
<span className="shrink-0 rounded-full border border-emerald-200 bg-emerald-50 px-2 py-0.5 text-[10px] font-black text-emerald-800 dark:border-emerald-500/30 dark:bg-emerald-500/10 dark:text-emerald-200 sm:text-xs">
Top 3
</span>
</div>
<div className="grid grid-cols-[1.25fr_0.85fr_0.9fr_1fr] border-b border-warm-200 bg-warm-50 text-[10px] font-black uppercase text-warm-500 dark:border-navy-700 dark:bg-navy-950/45 dark:text-warm-400 sm:text-xs">
{[
t('home.showcaseStep4ColPostcode'),
t('home.showcaseStep4ColScore'),
t('home.showcaseStep4ColCommute'),
t('home.showcaseStep4ColPrice'),
].map((heading) => (
<div
key={heading}
className="truncate border-r border-warm-200 px-2 py-1.5 last:border-r-0 dark:border-navy-700 sm:px-3 sm:py-2"
>
{heading}
</div>
))}
</div>
{scoutRows.map((row, index) => (
<div
key={row.postcode}
className={`grid grid-cols-[1.25fr_0.85fr_0.9fr_1fr] text-[11px] font-semibold text-navy-950 dark:text-warm-100 sm:text-sm ${
index % 2 === 0
? 'bg-white dark:bg-navy-900/55'
: 'bg-warm-50/70 dark:bg-navy-950/35'
}`}
>
<div className="flex min-w-0 items-center gap-1.5 border-r border-warm-200 px-2 py-1.5 dark:border-navy-700 sm:px-3 sm:py-2.5">
<span className="flex h-5 w-5 shrink-0 items-center justify-center rounded-md bg-emerald-50 text-[10px] font-black text-emerald-700 dark:bg-emerald-500/10 dark:text-emerald-300">
{index + 1}
</span>
<span className="truncate font-black">{row.postcode}</span>
</div>
<div className="min-w-0 border-r border-warm-200 px-2 py-1.5 dark:border-navy-700 sm:px-3 sm:py-2.5">
<div className="flex items-center gap-2">
<span className="shrink-0 font-black text-emerald-700 dark:text-emerald-300">
{row.score}
<div className="flex items-center justify-between gap-3 border-b border-warm-200 bg-gradient-to-r from-white via-emerald-50/80 to-white px-3 py-1.5 text-navy-950 dark:border-navy-700 dark:from-navy-900/90 dark:via-emerald-900/20 dark:to-navy-900/90 dark:text-warm-100 sm:px-4 sm:py-2">
<div className="flex min-w-0 items-center gap-2">
<span className="flex h-6 w-6 shrink-0 items-center justify-center rounded-md bg-emerald-600 text-white shadow-sm shadow-emerald-900/20 dark:bg-emerald-400 dark:text-navy-950 sm:h-7 sm:w-7">
<DownloadIcon className="h-3.5 w-3.5" />
</span>
<span className="hidden h-1.5 min-w-0 flex-1 overflow-hidden rounded-full bg-warm-200 dark:bg-navy-700 sm:block">
<span
className="block h-full rounded-full bg-emerald-500 dark:bg-emerald-300"
style={{ width: row.score }}
/>
<span className="min-w-0 truncate text-xs font-black sm:text-sm">
{t('home.showcaseStep4FileName')}
</span>
</div>
<span className="shrink-0 rounded-full border border-emerald-200 bg-emerald-50 px-2 py-0.5 text-[10px] font-black text-emerald-800 dark:border-emerald-500/30 dark:bg-emerald-500/10 dark:text-emerald-200 sm:text-xs">
Top 3
</span>
</div>
<div className="truncate border-r border-warm-200 px-2 py-1.5 dark:border-navy-700 sm:px-3 sm:py-2.5">
{row.commute}
<div className="grid grid-cols-[1.25fr_0.85fr_0.9fr_1fr] border-b border-warm-200 bg-warm-50 text-[10px] font-black uppercase text-warm-500 dark:border-navy-700 dark:bg-navy-950/45 dark:text-warm-400 sm:text-xs">
{[
t('home.showcaseStep4ColPostcode'),
t('home.showcaseStep4ColScore'),
t('home.showcaseStep4ColCommute'),
t('home.showcaseStep4ColPrice'),
].map((heading) => (
<div
key={heading}
className="truncate border-r border-warm-200 px-2 py-1.5 last:border-r-0 dark:border-navy-700 sm:px-3 sm:py-2"
>
{heading}
</div>
))}
</div>
<div className="truncate px-2 py-1.5 font-black sm:px-3 sm:py-2.5">{row.price}</div>
</div>
))}
{scoutRows.map((row, index) => (
<div
key={row.postcode}
className={`grid grid-cols-[1.25fr_0.85fr_0.9fr_1fr] text-[11px] font-semibold text-navy-950 dark:text-warm-100 sm:text-sm ${
index % 2 === 0
? 'bg-white dark:bg-navy-900/55'
: 'bg-warm-50/70 dark:bg-navy-950/35'
}`}
>
<div className="flex min-w-0 items-center gap-1.5 border-r border-warm-200 px-2 py-1.5 dark:border-navy-700 sm:px-3 sm:py-2.5">
<span className="flex h-5 w-5 shrink-0 items-center justify-center rounded-md bg-emerald-50 text-[10px] font-black text-emerald-700 dark:bg-emerald-500/10 dark:text-emerald-300">
{index + 1}
</span>
<span className="truncate font-black">{row.postcode}</span>
</div>
<div className="min-w-0 border-r border-warm-200 px-2 py-1.5 dark:border-navy-700 sm:px-3 sm:py-2.5">
<div className="flex items-center gap-2">
<span className="shrink-0 font-black text-emerald-700 dark:text-emerald-300">
{row.score}
</span>
<span className="hidden h-1.5 min-w-0 flex-1 overflow-hidden rounded-full bg-warm-200 dark:bg-navy-700 sm:block">
<span
className="block h-full rounded-full bg-emerald-500 dark:bg-emerald-300"
style={{ width: row.score }}
/>
</span>
</div>
</div>
<div className="truncate border-r border-warm-200 px-2 py-1.5 dark:border-navy-700 sm:px-3 sm:py-2.5">
{row.commute}
</div>
<div className="truncate px-2 py-1.5 font-black sm:px-3 sm:py-2.5">{row.price}</div>
</div>
))}
</div>
</div>
@ -1262,10 +1259,7 @@ export default function HomePage({
if (!scroller) return;
const start = scroller.scrollTop;
const end =
start +
target.getBoundingClientRect().top -
scroller.getBoundingClientRect().top +
24;
start + target.getBoundingClientRect().top - scroller.getBoundingClientRect().top + 24;
const distance = end - start;
const duration = 1200;
let startTime: number;
@ -1364,9 +1358,7 @@ export default function HomePage({
{/* Our philosophy */}
<div className={`${HOME_SECTION_CONTAINER_CLASS} pt-12 md:pt-20 pb-4`}>
<h2 className={`${HOME_SECTION_HEADING_CLASS} mb-6`}>
{t('home.ourPhilosophy')}
</h2>
<h2 className={`${HOME_SECTION_HEADING_CLASS} mb-6`}>{t('home.ourPhilosophy')}</h2>
<div className="space-y-4 text-base md:text-lg leading-relaxed text-warm-700 dark:text-warm-300">
<p>{t('home.philosophyP1')}</p>
<p>{highlightBrandText(t('home.philosophyP2'))}</p>