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:
2026-06-28 16:51:38 +00:00
parent 1ed5a7bebe
commit b84feefc5a
3 changed files with 105 additions and 35 deletions
+1 -1
View File
@@ -59,7 +59,7 @@ import '../styles/global.css';
<p class="note"><strong>Transparenz:</strong> Einige Links sind Affiliate-Links kaufst du darüber, erhalten wir ggf. eine Provision, für dich ändert sich der Preis nicht. Empfehlungen basieren auf Nutzungsfall, Technik, Testquellen und redaktioneller Einschätzung nicht auf Provision.</p>
<p class="note">Preise und Verfügbarkeit ändern sich während Hitzewellen sehr schnell. Wir halten Daten so aktuell wie möglich, geben aber keine Garantie. Bitte beim Händler final prüfen.</p>
<p class="note"><a href="/rechner">Klima-Rechner</a> · <a href="/soforthilfe">Hitze-Soforthilfe</a> · <a href="/klimaanlage-installieren">Fest installieren</a> · <a href="/portasplit">PortaSplit</a> · <a href="/hitzeschutz">Hitzeschutz</a> · <a href="/prognose">Prognose-Methodik</a></p>
<p class="note"><a href="/transparenz">Transparenz &amp; Methodik</a> · <a href="/impressum">Impressum</a> · <a href="/datenschutz">Datenschutz</a> · © {new Date().getFullYear()} Kühlfinder</p>
<p class="note"><a href="/transparenz">Transparenz &amp; Methodik</a> · <a href="/bildnachweis">Bildnachweis</a> · <a href="/impressum">Impressum</a> · <a href="/datenschutz">Datenschutz</a> · © {new Date().getFullYear()} Kühlfinder</p>
</div></footer>
</body>
</html>
+29
View File
@@ -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>
+71 -30
View File
@@ -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&nbsp;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>
<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>&nbsp;<span><b class="num" id="p-ac">…</b>&nbsp;Preise direkt bei Händlern geprüft</span></span>
<h1>Die nächste Hitze&shy;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">Verfügbarkeit zeigen</button>
<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="livewrap reveal">
<div class="pills">
<span class="pill-stat"><b class="num" id="p-ac">…</b>&nbsp;Live-Preise geprüft</span>
<span class="pill-stat"><b class="num" id="p-total" data-count="0">…</b>&nbsp;Märkte (Abdeckung)</span>
<span class="pill-stat"><b class="num">6</b>&nbsp;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="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 &amp; Preiswecker</span>
</div>
</div>
</div></section>
<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 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- &amp; 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 Wunsch­gerä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>