Redesign Startseite nach Claude-Design-Entwurf: Foto-Hero (Unsplash) mit Gradient-Overlay + Live-Card, Stat-Tiles, Alarm-Band mit Smartphone-Foto; /bildnachweis + Footer-Link (Credits Woblick/Matveev)
This commit is contained in:
@@ -0,0 +1,29 @@
|
||||
---
|
||||
import Base from '../layouts/Base.astro';
|
||||
const credits = [
|
||||
{use:'Startseite – Hero', author:'Kevin Woblick', handle:'@kovah', authorUrl:'https://unsplash.com/@kovah',
|
||||
photoUrl:'https://unsplash.com/photos/a-white-wall-with-three-air-conditioners-on-it-JkHSdaYRiUI', title:'Air Conditioning'},
|
||||
{use:'Startseite – Alarm-Sektion', author:'Andrey Matveev', handle:'@zelebb', authorUrl:'https://unsplash.com/@zelebb',
|
||||
photoUrl:'https://unsplash.com/photos/a-hand-holds-a-smartphone-showing-notifications-QGKCe8C3D8g', title:'Smartphone mit Benachrichtigungen'},
|
||||
];
|
||||
---
|
||||
<Base title="Bildnachweis – Kühlfinder" description="Fotonachweise und Lizenzangaben für die auf Kühlfinder verwendeten Bilder.">
|
||||
<section class="wrap" style="max-width:780px;margin-top:2rem">
|
||||
<span class="kicker"><span class="u"></span>Credits</span>
|
||||
<h1 style="margin:.3rem 0 .6rem">Bildnachweis</h1>
|
||||
<p class="muted">Die verwendeten Fotos stammen von <a href="https://unsplash.com/license" rel="noopener" target="_blank">Unsplash</a> und stehen unter der kostenlosen Unsplash-Lizenz. Eine Nennung ist nicht verpflichtend – wir tun es trotzdem, um die Fotograf:innen zu würdigen.</p>
|
||||
<div class="creditlist">
|
||||
{credits.map(c => (
|
||||
<div class="card creditrow">
|
||||
<div><strong>{c.title}</strong><div class="muted" style="font-size:.85rem">Verwendung: {c.use}</div></div>
|
||||
<div class="muted" style="font-size:.9rem">Foto: <a href={c.authorUrl} rel="noopener" target="_blank">{c.author} ({c.handle})</a> · <a href={c.photoUrl} rel="noopener" target="_blank">Original auf Unsplash ↗</a></div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
<p class="note" style="margin-top:1.2rem">Hinweis: Aktuell werden die Bilder über das Unsplash-CDN eingebunden. Für eine vollständig DSGVO-konforme, selbst gehostete Variante können die Dateien lokal unter <code>/public/img/</code> abgelegt und von dort ausgeliefert werden.</p>
|
||||
</section>
|
||||
</Base>
|
||||
<style>
|
||||
.creditlist{display:flex;flex-direction:column;gap:.8rem;margin-top:1rem}
|
||||
.creditrow{display:flex;flex-direction:column;gap:.4rem}
|
||||
</style>
|
||||
+75
-34
@@ -9,31 +9,47 @@ const jsonld = {'@context':'https://schema.org','@type':'WebSite',name:'Kühlfin
|
||||
const Pin='<svg viewBox="0 0 24 24" width="22" height="22" fill="none" stroke="currentColor" stroke-width="1.7"><path d="M12 21s7-5.6 7-11a7 7 0 1 0-14 0c0 5.4 7 11 7 11Z"/><circle cx="12" cy="10" r="2.5"/></svg>';
|
||||
const Compass='<svg viewBox="0 0 24 24" width="22" height="22" fill="none" stroke="currentColor" stroke-width="1.7"><circle cx="12" cy="12" r="9"/><path d="m15.5 8.5-2 5-5 2 2-5 5-2Z"/></svg>';
|
||||
const Bell='<svg viewBox="0 0 24 24" width="22" height="22" fill="none" stroke="currentColor" stroke-width="1.7"><path d="M6 9a6 6 0 1 1 12 0c0 5 2 6 2 6H4s2-1 2-6Z"/><path d="M10 19a2 2 0 0 0 4 0"/></svg>';
|
||||
// Unsplash (kostenlose Lizenz) – Credits unter /bildnachweis
|
||||
const IMG_HERO='https://images.unsplash.com/photo-1649711895336-20ff39db62f8?w=1680&q=70&auto=format&fit=crop';
|
||||
const IMG_PHONE='https://images.unsplash.com/photo-1752218804012-3e7db92274ec?w=1000&q=70&auto=format&fit=crop';
|
||||
---
|
||||
<Base title="Kühlfinder – Wo gibt es gerade ein Klimagerät? Live-Verfügbarkeit (DE/AT/CH/NL/PL/DK)" description="Live-Bestand von Klimageräten in Baumärkten & Elektromärkten in Deutschland und Nachbarländern, plus Online, Amazon & eBay – mit Prognose, Preis-Check gegen Wucher und Alarm.">
|
||||
<section class="hero"><div class="wrap">
|
||||
<section class="wrap herowrap">
|
||||
<WeatherBanner />
|
||||
<span class="eyebrow" style="margin-top:1rem"><span class="dot ok live"></span>Live-Verfügbarkeit · eigener Scraper</span>
|
||||
<h1>Wo gibt es gerade ein Klimagerät?</h1>
|
||||
<p class="lead">Bei Hitze ist alles vergriffen. Kühlfinder prüft <strong>Preise live direkt bei Händlern</strong> und zeigt ehrlich, wo geprüft ist – plus Standort-Abdeckung, Preis-Check gegen Wucher und Alarm. <em>Die nächste Hitzewelle kommt bestimmt.</em></p>
|
||||
<form class="herobar" action="/karte" method="get">
|
||||
<input name="plz" inputmode="numeric" placeholder="PLZ oder Ort …" aria-label="PLZ oder Ort" />
|
||||
<button class="btn" type="submit" data-umami-event="hero_plz_suche">Verfügbarkeit zeigen</button>
|
||||
<a class="btn ghost" href="/karte" id="locbtn" data-umami-event="hero_naehe">In meiner Nähe</a>
|
||||
</form>
|
||||
<div class="livewrap reveal">
|
||||
<div class="pills">
|
||||
<span class="pill-stat"><b class="num" id="p-ac">…</b> Live-Preise geprüft</span>
|
||||
<span class="pill-stat"><b class="num" id="p-total" data-count="0">…</b> Märkte (Abdeckung)</span>
|
||||
<span class="pill-stat"><b class="num">6</b> Länder · <span id="p-chains">…</span> Ketten</span>
|
||||
</div>
|
||||
<div class="livecard card">
|
||||
<div class="lc-head"><span class="dot ok live"></span> Live geprüfte Preise</div>
|
||||
<ul class="livelist" id="livelist"><li class="skel" style="height:40px"></li><li class="skel" style="height:40px"></li><li class="skel" style="height:40px"></li></ul>
|
||||
<a class="btn sm" href="/karte">Alle auf der Karte →</a>
|
||||
<div class="hero-card reveal">
|
||||
<div class="hero-photo" style={`background-image:url('${IMG_HERO}')`}></div>
|
||||
<div class="hero-veil"></div>
|
||||
<div class="hero-inner">
|
||||
<div class="hero-left">
|
||||
<span class="eyebrow"><span class="dot ok live"></span><strong class="livetag">LIVE</strong> <span><b class="num" id="p-ac">…</b> Preise direkt bei Händlern geprüft</span></span>
|
||||
<h1>Die nächste Hitze­welle kommt bestimmt.</h1>
|
||||
<p class="lead">Wir helfen dir, in Hitzephasen schnellstmöglich an ein <strong>verfügbares, gutes</strong> Klimagerät zu kommen – mit Live-Preisen, Preis-Check gegen Wucher und Alarm.</p>
|
||||
<form class="herobar" action="/karte" method="get">
|
||||
<input name="plz" inputmode="numeric" placeholder="PLZ oder Ort …" aria-label="PLZ oder Ort" />
|
||||
<button class="btn" type="submit" data-umami-event="hero_plz_suche">Geräte finden</button>
|
||||
<a class="btn ghost" href="/karte" id="locbtn" data-umami-event="hero_naehe">In meiner Nähe</a>
|
||||
</form>
|
||||
<div class="herofeat">
|
||||
<span><svg viewBox="0 0 24 24" width="15" height="15" fill="none" stroke="currentColor" stroke-width="1.7"><circle cx="12" cy="12" r="9"/><path d="M12 7v5l3 2"/></svg> Echtzeit-Verfügbarkeit</span>
|
||||
<span><svg viewBox="0 0 24 24" width="15" height="15" fill="none" stroke="currentColor" stroke-width="1.7"><circle cx="12" cy="12" r="9"/><path d="M3 12h18M12 3c2.5 2.5 2.5 15 0 18M12 3c-2.5 2.5-2.5 15 0 18"/></svg> 6 Länder</span>
|
||||
<span><svg viewBox="0 0 24 24" width="15" height="15" fill="none" stroke="currentColor" stroke-width="1.7"><path d="M20 6 9 17l-5-5"/></svg> Preis-Check gegen Wucher</span>
|
||||
<span><svg viewBox="0 0 24 24" width="15" height="15" fill="none" stroke="currentColor" stroke-width="1.7"><path d="M18 8a6 6 0 0 0-12 0c0 7-3 9-3 9h18s-3-2-3-9"/><path d="M13.7 21a2 2 0 0 1-3.4 0"/></svg> Alarm & Preiswecker</span>
|
||||
</div>
|
||||
</div>
|
||||
<aside class="hero-live card">
|
||||
<div class="lc-head"><strong>Gerade live geprüft</strong><span class="dot ok live"></span></div>
|
||||
<ul class="livelist" id="livelist"><li class="skel" style="height:44px"></li><li class="skel" style="height:44px"></li><li class="skel" style="height:44px"></li></ul>
|
||||
<a class="btn sm ghost" href="/karte">Alle Live-Funde ansehen →</a>
|
||||
</aside>
|
||||
</div>
|
||||
</div>
|
||||
</div></section>
|
||||
<div class="stat-tiles reveal">
|
||||
<div class="stile"><div class="st-l">Live-Preise geprüft</div><div class="num st-n" id="p-ac2">…</div><div class="st-s">direkt bei Händlern</div></div>
|
||||
<div class="stile"><div class="st-l">Märkte (Abdeckung)</div><div class="num st-n" id="p-total" data-count="0">…</div><div class="st-s">Demo-Datensatz</div></div>
|
||||
<div class="stile"><div class="st-l">Ketten</div><div class="num st-n" id="p-chains">…</div><div class="st-s">Bau- & Elektromärkte</div></div>
|
||||
<div class="stile"><div class="st-l">Länder</div><div class="num st-n">6</div><div class="st-s">DE·AT·CH·NL·PL·DK</div></div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="wrap">
|
||||
<div class="features">
|
||||
@@ -43,6 +59,16 @@ const Bell='<svg viewBox="0 0 24 24" width="22" height="22" fill="none" stroke="
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="wrap"><div class="alarmband reveal">
|
||||
<div class="ab-photo" style={`background-image:url('${IMG_PHONE}')`} role="img" aria-label="Smartphone mit Push-Benachrichtigung"></div>
|
||||
<div class="ab-text">
|
||||
<span class="kicker"><span class="u"></span>Sei der Erste</span>
|
||||
<h2 style="margin:.3rem 0 .4rem">Wir sagen Bescheid, sobald es verfügbar ist.</h2>
|
||||
<p class="muted" style="max-width:34rem">Verfügbarkeits-Alarm und Preiswecker für ein oder mehrere Wunschgeräte – per Mail oder Telegram. So musst du nicht ständig selbst nachschauen.</p>
|
||||
<div class="bandcta"><a class="btn" href="/alarm" data-umami-event="alarm_cta_home">Alarm einrichten</a><a class="btn ghost" href="/pro">Pro: Echtzeit ohne Verzögerung</a></div>
|
||||
</div>
|
||||
</div></section>
|
||||
|
||||
<section class="wrap"><div class="band reveal">
|
||||
<div>
|
||||
<h2>Vergriffen? Wir warnen vor Wucher.</h2>
|
||||
@@ -88,21 +114,34 @@ const Bell='<svg viewBox="0 0 24 24" width="22" height="22" fill="none" stroke="
|
||||
</div></section>
|
||||
</Base>
|
||||
<style>
|
||||
.hero{background:var(--grad-hero);padding:3.4rem 0 2.8rem}
|
||||
.hero h1{font-size:clamp(2.3rem,6vw,4rem);max-width:18ch;margin-top:.6rem}
|
||||
.hero .lead{font-size:1.15rem;max-width:48rem;color:var(--ink-2)}
|
||||
.hero .lead em{color:var(--petrol-deep);font-style:normal;font-weight:600}
|
||||
.herobar{display:flex;gap:.6rem;margin:1.4rem 0 1.4rem;max-width:640px;flex-wrap:wrap}
|
||||
.herobar input{flex:1;min-width:180px;font-family:var(--font-body);font-size:1rem;padding:.85rem 1.1rem;border:1px solid var(--line);border-radius:999px;background:#fff;box-shadow:var(--shadow-card)}
|
||||
.herowrap{margin-top:1.4rem}
|
||||
.hero-card{position:relative;border-radius:22px;overflow:hidden;box-shadow:0 1px 2px rgba(20,40,60,.05),0 18px 48px rgba(20,40,60,.10);min-height:480px}
|
||||
.hero-photo{position:absolute;inset:0;background-size:cover;background-position:center;transform:scale(1.02)}
|
||||
.hero-veil{position:absolute;inset:0;background:linear-gradient(100deg,var(--light) 0%,color-mix(in oklab,var(--light) 94%,transparent) 34%,color-mix(in oklab,var(--light) 55%,transparent) 56%,transparent 80%)}
|
||||
.hero-inner{position:relative;display:grid;grid-template-columns:1.15fr .85fr;gap:2rem;padding:2.4rem 2.4rem 2.4rem;align-items:start}
|
||||
.hero-left h1{font-size:clamp(2.2rem,5.2vw,3.7rem);line-height:1.05;letter-spacing:-.02em;max-width:14ch;margin:.7rem 0 0}
|
||||
.hero-left .lead{font-size:1.12rem;max-width:30rem;color:var(--ink-2);margin-top:.9rem}
|
||||
.livetag{color:var(--ok-dot);font-size:.7rem;letter-spacing:.08em;font-weight:700}
|
||||
.herobar{display:flex;gap:.6rem;margin:1.3rem 0 1.1rem;max-width:560px;flex-wrap:wrap}
|
||||
.herobar input{flex:1;min-width:180px;font-family:var(--font-body);font-size:1rem;padding:.85rem 1.1rem;border:1px solid var(--line);border-radius:12px;background:#fff;box-shadow:var(--shadow-card)}
|
||||
.herobar input:focus{border-color:var(--petrol)}
|
||||
.livewrap{display:grid;grid-template-columns:1fr 320px;gap:1.2rem;align-items:start;margin-top:.4rem}
|
||||
.pills{display:flex;gap:.6rem;flex-wrap:wrap;align-content:start}
|
||||
.livecard{display:flex;flex-direction:column;gap:.6rem;padding:1rem}
|
||||
.lc-head{display:flex;align-items:center;gap:.5rem;font-weight:600;font-size:.9rem}
|
||||
.livelist{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:.1rem}
|
||||
.livelist li{display:flex;justify-content:space-between;align-items:center;gap:.5rem;padding:.45rem .1rem;border-bottom:1px solid var(--line);font-size:.88rem}
|
||||
.herofeat{display:flex;flex-wrap:wrap;gap:.55rem 1.4rem;font-size:.86rem;color:var(--ink-2)}
|
||||
.herofeat span{display:inline-flex;align-items:center;gap:.45rem}.herofeat svg{color:var(--petrol-deep)}
|
||||
.hero-live{display:flex;flex-direction:column;gap:.5rem;padding:1.1rem;justify-self:end;width:100%;max-width:340px;background:rgba(255,255,255,.92);backdrop-filter:blur(4px)}
|
||||
.lc-head{display:flex;align-items:center;justify-content:space-between;gap:.5rem;font-size:.95rem}
|
||||
.livelist{list-style:none;margin:0;padding:0;display:flex;flex-direction:column}
|
||||
.livelist li{display:flex;justify-content:space-between;align-items:center;gap:.5rem;padding:.6rem .1rem;border-top:1px solid var(--line);font-size:.88rem}
|
||||
.livelist li:first-child{border-top:none}
|
||||
.livelist .lm{font-weight:600}.livelist .lc{font-size:.78rem;color:var(--slate)}
|
||||
.livelist .lp{font-family:var(--mono);font-size:.82rem;color:var(--petrol-deep)}
|
||||
.livelist .lp{font-family:var(--mono);font-size:.82rem;color:var(--petrol-deep);font-weight:600}
|
||||
.stat-tiles{display:grid;grid-template-columns:repeat(4,1fr);gap:.9rem;margin-top:1rem}
|
||||
.stile{background:var(--card);border:1px solid var(--line);border-radius:14px;padding:1rem 1.1rem;box-shadow:var(--shadow-card)}
|
||||
.st-l{font-size:.82rem;color:var(--slate)}
|
||||
.st-n{font-size:1.9rem;letter-spacing:-.02em;margin-top:.35rem;font-variant-numeric:tabular-nums}
|
||||
.st-s{font-size:.76rem;color:var(--slate);margin-top:.2rem}
|
||||
.alarmband{display:grid;grid-template-columns:.9fr 1.1fr;gap:1.5rem;align-items:center;background:var(--petrol-soft);border-radius:20px;overflow:hidden}
|
||||
.ab-photo{min-height:260px;background-size:cover;background-position:center}
|
||||
.ab-text{padding:1.8rem 1.8rem 1.8rem 0}
|
||||
section.wrap{margin-top:2.8rem}
|
||||
.features{display:grid;grid-template-columns:repeat(3,1fr);gap:1rem}
|
||||
.features .feature{text-decoration:none;color:var(--ink)}.features h3{margin:.2rem 0}
|
||||
@@ -117,7 +156,8 @@ const Bell='<svg viewBox="0 0 24 24" width="22" height="22" fill="none" stroke="
|
||||
.cflag{display:inline-flex;align-items:center;gap:.5rem;background:var(--card);border:1px solid var(--line);border-radius:999px;padding:.45rem .9rem;box-shadow:var(--shadow-card);font-size:.9rem;font-weight:500}
|
||||
.split{display:grid;grid-template-columns:1fr 1fr;gap:1rem}.card.warm{background:var(--warm-bg)}
|
||||
.steps{margin:.4rem 0 0;padding-left:1.2rem}.steps li{margin:.3rem 0}
|
||||
@media(max-width:860px){.livewrap{grid-template-columns:1fr}.features,.cards3,.split{grid-template-columns:1fr}.band{grid-template-columns:1fr}}
|
||||
@media(max-width:960px){.stat-tiles{grid-template-columns:repeat(2,1fr)}}
|
||||
@media(max-width:860px){.hero-inner{grid-template-columns:1fr}.hero-live{max-width:none;justify-self:stretch}.hero-veil{background:linear-gradient(180deg,color-mix(in oklab,var(--light) 90%,transparent),color-mix(in oklab,var(--light) 96%,transparent))}.features,.cards3,.split{grid-template-columns:1fr}.band{grid-template-columns:1fr}.alarmband{grid-template-columns:1fr}.ab-text{padding:0 1.5rem 1.6rem}.ab-photo{min-height:200px}}
|
||||
</style>
|
||||
<script>
|
||||
const euro=(n,c)=>n==null?'–':new Intl.NumberFormat('de-DE',{style:'currency',currency:c||'EUR',maximumFractionDigits:0}).format(n);
|
||||
@@ -132,6 +172,7 @@ const Bell='<svg viewBox="0 0 24 24" width="22" height="22" fill="none" stroke="
|
||||
fetch(CRAWLER+'/api/live').then(r=>r.json()).then(d=>{
|
||||
const offers=(d.offers||[]).filter(o=>o.price);
|
||||
document.getElementById('p-ac').textContent=offers.length;
|
||||
const ac2=document.getElementById('p-ac2'); if(ac2) ac2.textContent=offers.length;
|
||||
document.getElementById('livelist').innerHTML = offers.slice(0,6).map(o=>`<li><span><span class="lm">${o.chain}</span> <span class="lc">${o.name}</span></span><span class="lp">${euro(o.price)}</span></li>`).join('') || '<li class="lc">Crawler startet – gleich wieder reinschauen.</li>';
|
||||
}).catch(()=>{document.getElementById('p-ac').textContent='–';document.getElementById('livelist').innerHTML='<li class="lc">Live-Preise gerade nicht erreichbar.</li>';});
|
||||
</script>
|
||||
|
||||
Reference in New Issue
Block a user