Charaktergeschichten von den Shop-Karten getrennt: eigene volle-Breite Boxen oben, reine Foto/Preis-Karten darunter
Bisher stand die persönliche Charaktergeschichte (Hallo-ich-bin-Text) direkt in derselben Karte wie Foto und Kaufinfos. Jetzt zweigeteilt: - Oben: jede Geschichte in einer eigenen, vollen Breite Karte (character-stories/.character-story), übereinander gestapelt. - Darunter: eine Kartenreihe wie im Shop-Grid, die für Charaktere mit echtem Produkt direkt die vorhandene ProductCard-Komponente wiederverwendet (Foto, Badges, Preis, Kurzbeschreibung — 1:1 wie überall sonst im Shop), für Charaktere ohne Produkt ein passender Platzhalter im gleichen Kartenstil. Keine Geschichten mehr in dieser Reihe. Verifiziert per Puppeteer: alle drei Geschichten-Boxen ohne Preis, alle drei Shop-Karten ohne Geschichtstext, HasiDog-Karte zeigt echten Preis (42,00 € durchgestrichen, 25,00 €) über die wiederverwendete ProductCard- Komponente.
This commit is contained in:
@@ -50,27 +50,43 @@ const weitere = alleProdukte.filter((p) => !zugeordneteSlugs.has(p.slug));
|
||||
</div>
|
||||
|
||||
{characterEntries.length > 0 ? (
|
||||
<>
|
||||
{/* Die persönlichen Charaktergeschichten stehen als eigene, volle Breite Boxen ÜBER der
|
||||
Kartenreihe — getrennt von den "Shop"-Karten darunter, die nur Foto/Preis/Infos zeigen. */}
|
||||
<section class="section-tight">
|
||||
<div class="container grid grid-3">
|
||||
{characterEntries.map(({ char, product }) => (
|
||||
<div class="card character-card">
|
||||
<div class="product-media">
|
||||
{product && product.bilder && product.bilder.length > 0 ? (
|
||||
<img class="product-photo" src={product.bilder[0]} alt={product.name[lang]} loading="lazy" />
|
||||
) : (
|
||||
<div class="img-placeholder" role="img" aria-label={product ? product.name[lang] : char.name[lang]}></div>
|
||||
)}
|
||||
</div>
|
||||
<div class="container character-stories">
|
||||
{characterEntries.map(({ char }) => (
|
||||
<div class="card character-story">
|
||||
{char.vorstellung && <span class="eyebrow">{char.vorstellung[lang].split("\n")[0]}</span>}
|
||||
<h3>{product ? <a href={`/ch/produkt/${product.slug}/`}>{product.name[lang]}</a> : char.name[lang]}</h3>
|
||||
<p class="character-card-desc">{char.vorstellung ? char.vorstellung[lang].split("\n")[1] : (product ? product.beschreibung[lang] : t.shop.subcategoryEmpty)}</p>
|
||||
<h3>{char.name[lang]}</h3>
|
||||
<p>{char.vorstellung ? char.vorstellung[lang].split("\n")[1] : ""}</p>
|
||||
{char.mehrLink && (
|
||||
<a class="btn btn-outline btn-sm character-more-btn" href={char.mehrLink} target="_blank" rel="noopener">da →</a>
|
||||
<a class="btn btn-outline btn-sm" href={char.mehrLink} target="_blank" rel="noopener">da →</a>
|
||||
)}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Kartenreihe wie im Shop-Grid — nur Foto, Preis und Kaufinfos, keine Geschichten. */}
|
||||
<section class="section-tight">
|
||||
<div class="container grid grid-3">
|
||||
{characterEntries.map(({ char, product }) =>
|
||||
product ? (
|
||||
<ProductCard product={product} lang={lang} />
|
||||
) : (
|
||||
<div class="card character-card">
|
||||
<div class="product-media">
|
||||
<div class="img-placeholder" role="img" aria-label={char.name[lang]}></div>
|
||||
</div>
|
||||
<h3>{char.name[lang]}</h3>
|
||||
<p class="character-card-desc">{t.shop.subcategoryEmpty}</p>
|
||||
</div>
|
||||
)
|
||||
)}
|
||||
</div>
|
||||
</section>
|
||||
</>
|
||||
) : (
|
||||
<section class="section-tight">
|
||||
<div class="container">
|
||||
|
||||
@@ -50,27 +50,43 @@ const weitere = alleProdukte.filter((p) => !zugeordneteSlugs.has(p.slug));
|
||||
</div>
|
||||
|
||||
{characterEntries.length > 0 ? (
|
||||
<>
|
||||
{/* Die persönlichen Charaktergeschichten stehen als eigene, volle Breite Boxen ÜBER der
|
||||
Kartenreihe — getrennt von den "Shop"-Karten darunter, die nur Foto/Preis/Infos zeigen. */}
|
||||
<section class="section-tight">
|
||||
<div class="container grid grid-3">
|
||||
{characterEntries.map(({ char, product }) => (
|
||||
<div class="card character-card">
|
||||
<div class="product-media">
|
||||
{product && product.bilder && product.bilder.length > 0 ? (
|
||||
<img class="product-photo" src={product.bilder[0]} alt={product.name[lang]} loading="lazy" />
|
||||
) : (
|
||||
<div class="img-placeholder" role="img" aria-label={product ? product.name[lang] : char.name[lang]}></div>
|
||||
)}
|
||||
</div>
|
||||
<div class="container character-stories">
|
||||
{characterEntries.map(({ char }) => (
|
||||
<div class="card character-story">
|
||||
{char.vorstellung && <span class="eyebrow">{char.vorstellung[lang].split("\n")[0]}</span>}
|
||||
<h3>{product ? <a href={`/en/produkt/${product.slug}/`}>{product.name[lang]}</a> : char.name[lang]}</h3>
|
||||
<p class="character-card-desc">{char.vorstellung ? char.vorstellung[lang].split("\n")[1] : (product ? product.beschreibung[lang] : t.shop.subcategoryEmpty)}</p>
|
||||
<h3>{char.name[lang]}</h3>
|
||||
<p>{char.vorstellung ? char.vorstellung[lang].split("\n")[1] : ""}</p>
|
||||
{char.mehrLink && (
|
||||
<a class="btn btn-outline btn-sm character-more-btn" href={char.mehrLink} target="_blank" rel="noopener">here →</a>
|
||||
<a class="btn btn-outline btn-sm" href={char.mehrLink} target="_blank" rel="noopener">here →</a>
|
||||
)}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Kartenreihe wie im Shop-Grid — nur Foto, Preis und Kaufinfos, keine Geschichten. */}
|
||||
<section class="section-tight">
|
||||
<div class="container grid grid-3">
|
||||
{characterEntries.map(({ char, product }) =>
|
||||
product ? (
|
||||
<ProductCard product={product} lang={lang} />
|
||||
) : (
|
||||
<div class="card character-card">
|
||||
<div class="product-media">
|
||||
<div class="img-placeholder" role="img" aria-label={char.name[lang]}></div>
|
||||
</div>
|
||||
<h3>{char.name[lang]}</h3>
|
||||
<p class="character-card-desc">{t.shop.subcategoryEmpty}</p>
|
||||
</div>
|
||||
)
|
||||
)}
|
||||
</div>
|
||||
</section>
|
||||
</>
|
||||
) : (
|
||||
<section class="section-tight">
|
||||
<div class="container">
|
||||
|
||||
@@ -50,27 +50,43 @@ const weitere = alleProdukte.filter((p) => !zugeordneteSlugs.has(p.slug));
|
||||
</div>
|
||||
|
||||
{characterEntries.length > 0 ? (
|
||||
<>
|
||||
{/* Die persönlichen Charaktergeschichten stehen als eigene, volle Breite Boxen ÜBER der
|
||||
Kartenreihe — getrennt von den "Shop"-Karten darunter, die nur Foto/Preis/Infos zeigen. */}
|
||||
<section class="section-tight">
|
||||
<div class="container grid grid-3">
|
||||
{characterEntries.map(({ char, product }) => (
|
||||
<div class="card character-card">
|
||||
<div class="product-media">
|
||||
{product && product.bilder && product.bilder.length > 0 ? (
|
||||
<img class="product-photo" src={product.bilder[0]} alt={product.name[lang]} loading="lazy" />
|
||||
) : (
|
||||
<div class="img-placeholder" role="img" aria-label={product ? product.name[lang] : char.name[lang]}></div>
|
||||
)}
|
||||
</div>
|
||||
<div class="container character-stories">
|
||||
{characterEntries.map(({ char }) => (
|
||||
<div class="card character-story">
|
||||
{char.vorstellung && <span class="eyebrow">{char.vorstellung[lang].split("\n")[0]}</span>}
|
||||
<h3>{product ? <a href={`/fr/produkt/${product.slug}/`}>{product.name[lang]}</a> : char.name[lang]}</h3>
|
||||
<p class="character-card-desc">{char.vorstellung ? char.vorstellung[lang].split("\n")[1] : (product ? product.beschreibung[lang] : t.shop.subcategoryEmpty)}</p>
|
||||
<h3>{char.name[lang]}</h3>
|
||||
<p>{char.vorstellung ? char.vorstellung[lang].split("\n")[1] : ""}</p>
|
||||
{char.mehrLink && (
|
||||
<a class="btn btn-outline btn-sm character-more-btn" href={char.mehrLink} target="_blank" rel="noopener">ici →</a>
|
||||
<a class="btn btn-outline btn-sm" href={char.mehrLink} target="_blank" rel="noopener">ici →</a>
|
||||
)}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Kartenreihe wie im Shop-Grid — nur Foto, Preis und Kaufinfos, keine Geschichten. */}
|
||||
<section class="section-tight">
|
||||
<div class="container grid grid-3">
|
||||
{characterEntries.map(({ char, product }) =>
|
||||
product ? (
|
||||
<ProductCard product={product} lang={lang} />
|
||||
) : (
|
||||
<div class="card character-card">
|
||||
<div class="product-media">
|
||||
<div class="img-placeholder" role="img" aria-label={char.name[lang]}></div>
|
||||
</div>
|
||||
<h3>{char.name[lang]}</h3>
|
||||
<p class="character-card-desc">{t.shop.subcategoryEmpty}</p>
|
||||
</div>
|
||||
)
|
||||
)}
|
||||
</div>
|
||||
</section>
|
||||
</>
|
||||
) : (
|
||||
<section class="section-tight">
|
||||
<div class="container">
|
||||
|
||||
@@ -50,27 +50,43 @@ const weitere = alleProdukte.filter((p) => !zugeordneteSlugs.has(p.slug));
|
||||
</div>
|
||||
|
||||
{characterEntries.length > 0 ? (
|
||||
<>
|
||||
{/* Die persönlichen Charaktergeschichten stehen als eigene, volle Breite Boxen ÜBER der
|
||||
Kartenreihe — getrennt von den "Shop"-Karten darunter, die nur Foto/Preis/Infos zeigen. */}
|
||||
<section class="section-tight">
|
||||
<div class="container grid grid-3">
|
||||
{characterEntries.map(({ char, product }) => (
|
||||
<div class="card character-card">
|
||||
<div class="product-media">
|
||||
{product && product.bilder && product.bilder.length > 0 ? (
|
||||
<img class="product-photo" src={product.bilder[0]} alt={product.name[lang]} loading="lazy" />
|
||||
) : (
|
||||
<div class="img-placeholder" role="img" aria-label={product ? product.name[lang] : char.name[lang]}></div>
|
||||
)}
|
||||
</div>
|
||||
<div class="container character-stories">
|
||||
{characterEntries.map(({ char }) => (
|
||||
<div class="card character-story">
|
||||
{char.vorstellung && <span class="eyebrow">{char.vorstellung[lang].split("\n")[0]}</span>}
|
||||
<h3>{product ? <a href={`/produkt/${product.slug}/`}>{product.name[lang]}</a> : char.name[lang]}</h3>
|
||||
<p class="character-card-desc">{char.vorstellung ? char.vorstellung[lang].split("\n")[1] : (product ? product.beschreibung[lang] : t.shop.subcategoryEmpty)}</p>
|
||||
<h3>{char.name[lang]}</h3>
|
||||
<p>{char.vorstellung ? char.vorstellung[lang].split("\n")[1] : ""}</p>
|
||||
{char.mehrLink && (
|
||||
<a class="btn btn-outline btn-sm character-more-btn" href={char.mehrLink} target="_blank" rel="noopener">hier →</a>
|
||||
<a class="btn btn-outline btn-sm" href={char.mehrLink} target="_blank" rel="noopener">hier →</a>
|
||||
)}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Kartenreihe wie im Shop-Grid — nur Foto, Preis und Kaufinfos, keine Geschichten. */}
|
||||
<section class="section-tight">
|
||||
<div class="container grid grid-3">
|
||||
{characterEntries.map(({ char, product }) =>
|
||||
product ? (
|
||||
<ProductCard product={product} lang={lang} />
|
||||
) : (
|
||||
<div class="card character-card">
|
||||
<div class="product-media">
|
||||
<div class="img-placeholder" role="img" aria-label={char.name[lang]}></div>
|
||||
</div>
|
||||
<h3>{char.name[lang]}</h3>
|
||||
<p class="character-card-desc">{t.shop.subcategoryEmpty}</p>
|
||||
</div>
|
||||
)
|
||||
)}
|
||||
</div>
|
||||
</section>
|
||||
</>
|
||||
) : (
|
||||
<section class="section-tight">
|
||||
<div class="container">
|
||||
|
||||
+10
-6
@@ -804,16 +804,20 @@ a:focus-visible, button:focus-visible {
|
||||
noch mehr Produkte derselben Reihe kommen (Charakter-Familie), egal wie viele es am Ende sind. */
|
||||
.more-variants-label { text-transform: uppercase; letter-spacing: 0.08em; color: var(--c-text-muted); margin-bottom: 0.8rem; }
|
||||
|
||||
/* Charakter-Karten auf den Tier-Familien-Seiten (z.B. HasiDog/HasiGott/Mama Hase unter "Hase") —
|
||||
exakt dieselbe Karten-Optik wie die Produktkarten im Shop-Grid (Foto oben, Text darunter in
|
||||
voller Breite), nur mit persönlichem Charaktertext statt Produktbeschreibung. */
|
||||
/* Persönliche Charaktergeschichten (Hallo-ich-bin-Texte) auf den Tier-Familien-Seiten — eigene,
|
||||
volle Breite Karten übereinander gestapelt, GETRENNT von den Shop-Karten darunter (die zeigen
|
||||
nur noch Foto/Preis/Kaufinfos, keine Geschichten). */
|
||||
.character-stories { display: flex; flex-direction: column; gap: 1rem; margin-bottom: 2.2rem; }
|
||||
.character-story { padding: 1.6rem 1.8rem; }
|
||||
.character-story h3 { margin: 0.15rem 0 0.6rem; font-size: 1.3rem; }
|
||||
.character-story p { margin: 0 0 0.8em; color: var(--c-text-muted); }
|
||||
|
||||
/* Charakter-Karten ohne zugeordnetes Produkt (noch kein Foto/Preis) — gleiche Optik wie die
|
||||
echten Produktkarten (ProductCard.astro), damit die Reihe einheitlich aussieht. */
|
||||
.character-card { display: flex; flex-direction: column; gap: 0.6rem; padding: 1rem; }
|
||||
.character-card .product-media { position: relative; }
|
||||
.character-card h3 { font-size: 1.15rem; margin: 0.1rem 0 0; }
|
||||
.character-card h3 a { color: inherit; transition: color 0.2s var(--ease); }
|
||||
.character-card h3 a:hover { color: var(--c-accent); }
|
||||
.character-card-desc { margin: 0; color: var(--c-text-muted); font-size: 0.92rem; }
|
||||
.character-more-btn { margin-top: auto; align-self: flex-start; }
|
||||
|
||||
/* Hauptkategorie-Überschrift zwischen den Unterkategorie-Chips und der eigentlichen
|
||||
Produktreihe auf der Kategorie-Seite — macht klar, welche Hauptkategorie man gerade
|
||||
|
||||
Reference in New Issue
Block a user