diff --git a/app/globals.css b/app/globals.css index 9907359..59ad48b 100644 --- a/app/globals.css +++ b/app/globals.css @@ -134,21 +134,32 @@ p { margin-top: 20px; } -.latest-grid { +.latest-carousel { display: grid; - grid-template-columns: 1.2fr 0.8fr; - gap: 14px; - margin-top: 14px; + gap: 12px; + margin-top: 12px; } -.latest-card { +.carousel-window { + position: relative; + width: 100%; + overflow: hidden; border: 1px solid rgba(148, 163, 184, 0.2); border-radius: 16px; - overflow: hidden; background: rgba(255, 255, 255, 0.02); +} + +.carousel-track { + display: flex; + transition: transform 500ms ease; + width: 100%; +} + +.carousel-slide { + min-width: 100%; display: grid; - grid-template-columns: 1fr 1fr; - min-height: 240px; + grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); + align-items: stretch; } .latest-cover { @@ -168,67 +179,6 @@ p { gap: 6px; } -.latest-rail { - display: grid; - gap: 8px; - max-height: 320px; - overflow: auto; - padding-right: 4px; -} - -.rail-item { - width: 100%; - display: grid; - grid-template-columns: 76px 1fr; - gap: 10px; - padding: 8px; - border-radius: 12px; - border: 1px solid rgba(148, 163, 184, 0.16); - background: rgba(255, 255, 255, 0.01); - cursor: pointer; - color: inherit; -} - -.rail-item.active { - border-color: var(--accent); - background: rgba(34, 211, 238, 0.08); -} - -.rail-thumb { - width: 100%; - height: 64px; - border-radius: 10px; - overflow: hidden; - background: rgba(14, 165, 233, 0.06); -} - -.rail-thumb img { - width: 100%; - height: 100%; - object-fit: cover; -} - -.rail-fallback { - width: 100%; - height: 100%; - background: linear-gradient(110deg, rgba(34, 211, 238, 0.1), rgba(14, 165, 233, 0.1)); -} - -.rail-text { - display: grid; - gap: 4px; - text-align: left; -} - -.rail-title { - font-weight: 600; -} - -.rail-sub { - color: var(--muted); - font-size: 13px; -} - .dot-row { display: flex; gap: 6px; diff --git a/app/listings/page.tsx b/app/listings/page.tsx index 2473d6a..8f11a07 100644 --- a/app/listings/page.tsx +++ b/app/listings/page.tsx @@ -1,6 +1,7 @@ 'use client'; import Link from 'next/link'; +import dynamic from 'next/dynamic'; import { useEffect, useMemo, useRef, useState } from 'react'; import { useI18n } from '../components/I18nProvider'; @@ -47,25 +48,10 @@ function haversineKm(a: LatLng, b: LatLng) { return 2 * R * Math.atan2(Math.sqrt(h), Math.sqrt(1 - h)); } -async function loadLeaflet(): Promise { - if (typeof window === 'undefined') return Promise.reject(); - if ((window as any).L) return (window as any).L; - const linkId = 'leaflet-css'; - if (!document.getElementById(linkId)) { - const link = document.createElement('link'); - link.id = linkId; - link.rel = 'stylesheet'; - link.href = 'https://unpkg.com/leaflet@1.9.4/dist/leaflet.css'; - document.head.appendChild(link); - } - try { - const mod = await import('leaflet'); - (window as any).L = mod; - return mod; - } catch (err) { - return Promise.reject(err); - } -} +const LeafletWrapper = dynamic(async () => { + const L = await import('leaflet'); + return L; +}, { ssr: false }); function ListingsMap({ listings, @@ -88,7 +74,7 @@ function ListingsMap({ useEffect(() => { let cancelled = false; - loadLeaflet() + LeafletWrapper .then((L) => { if (cancelled) return; setReady(true); diff --git a/app/page.tsx b/app/page.tsx index 5ccc609..6b78bd6 100644 --- a/app/page.tsx +++ b/app/page.tsx @@ -127,48 +127,37 @@ export default function HomePage() { ) : !activeListing ? (

{t('mapNoResults')}

) : ( -
setPaused(true)} onMouseLeave={() => setPaused(false)}> -
- {activeListing.coverImage ? ( - {activeListing.title} - ) : ( -
- )} -
- - {activeListing.city}, {activeListing.region} - -

{activeListing.title}

-

{activeListing.teaser}

-
- - {t('openListing')} - -
-
-
-
- {latest.map((item, idx) => ( - - ))} -
- {latest.map((_, idx) => ( - setActiveIndex(idx)} /> +
setPaused(true)} onMouseLeave={() => setPaused(false)}> +
+
+ {latest.map((item) => ( +
+ {item.coverImage ? ( + {item.title} + ) : ( +
+ )} +
+ + {item.city}, {item.region} + +

{item.title}

+

{item.teaser}

+
+ + {t('openListing')} + +
+
+
))}
+
+ {latest.map((_, idx) => ( + setActiveIndex(idx)} /> + ))} +
)}