Zwei neue Hase-Varianten (HasiGott, Mama Hase) + abwechselnde Foto/Text-Seite pro Familie; Hauptkategorie-Überschrift auf Kategorie-Seiten
- Zwei neue Unterkategorien unter "Hase" angelegt: "HasiGott" und "Mama Hase", jeweils mit eigenem Charaktertext, bereit für echte Produktfotos sobald VanVan sie im Adminbereich hinzufügt. - Neue Logik: Innerhalb einer Tier-Familie (gleicher Slug-Präfix, z.B. "hase-*") wechselt die Vorstellungsbox jetzt automatisch die Seite ab — 1. Mitglied Foto links/Text rechts (HasiDog, unverändert), 2. Mitglied Foto rechts/Text links (HasiGott), 3. wieder links (Mama Hase), und so weiter für alle künftigen Varianten. - Kategorie-Seiten (z.B. "DIY Plushies") zeigen jetzt eine Hauptkategorie-Überschrift zwischen der Unterkategorien-Chip-Reihe und der eigentlichen Produktreihe darunter. Verifiziert per Puppeteer gegen den echten Build: neue Seiten laden fehlerfrei, HasiDog bleibt korrekt "nicht gespiegelt" (1. Familienmitglied), Hauptkategorie-Überschrift sitzt an der richtigen Stelle.
This commit is contained in:
@@ -46,6 +46,36 @@
|
||||
},
|
||||
"mehrLink": "https://dogfather-universe.dogfather1608.workers.dev/hasidog.html"
|
||||
},
|
||||
{
|
||||
"slug": "hase-hasigott",
|
||||
"name": {
|
||||
"de": "Hase „HasiGott”",
|
||||
"en": "Bunny \"HasiGott\"",
|
||||
"ch": "Hase „HasiGott”",
|
||||
"fr": "Lapin « HasiGott »"
|
||||
},
|
||||
"vorstellung": {
|
||||
"de": "Hallo, ich bin HasiGott.\nIch bin der Größte, Weiseste und Kuscheligste von allen – zumindest behaupte ich das gerne selbst. Mit meinem selbstbewussten Lächeln bringe ich dich garantiert zum Schmunzeln.",
|
||||
"en": "Hello, I'm HasiGott.\nI'm the biggest, wisest and cuddliest of them all — or at least that's what I like to say myself. With my confident smile, I'm bound to bring one to your face too.",
|
||||
"ch": "Hoi, ig bi dr HasiGott.\nIg bi dr Gröscht, Wysischt und Kuschligscht vo allne – zumindescht behaupte ig das gern sälber. Mit mim sälbstbewusste Lächle bring ig di garantiert zum Schmunzle.",
|
||||
"fr": "Bonjour, je suis HasiGott.\nJe suis le plus grand, le plus sage et le plus câlin de tous — enfin, c'est ce que j'aime dire moi-même. Avec mon sourire plein d'assurance, je suis sûr de te faire sourire aussi."
|
||||
}
|
||||
},
|
||||
{
|
||||
"slug": "hase-mama",
|
||||
"name": {
|
||||
"de": "Hase „Mama Hase”",
|
||||
"en": "Bunny \"Mama Hase\"",
|
||||
"ch": "Hase „Mama Hase”",
|
||||
"fr": "Lapin « Maman Lapine »"
|
||||
},
|
||||
"vorstellung": {
|
||||
"de": "Hallo, ich bin Mama Hase.\nIch halte meine Familie mit ganz viel Liebe und einem offenen Herzen zusammen. Bei mir findest du immer ein warmes Plätzchen zum Ankuscheln.",
|
||||
"en": "Hello, I'm Mama Hase.\nI hold my family together with lots of love and an open heart. With me, you'll always find a warm spot to cuddle up.",
|
||||
"ch": "Hoi, ig bi d'Mama Hase.\nIg haltä mini Familie mit ganz viel Liebi und emenä offene Härz zäme. Bi mir findsch du immer es warms Plätzli zum Aakuschle.",
|
||||
"fr": "Bonjour, je suis Maman Lapine.\nJe tiens ma famille unie avec beaucoup d'amour et un cœur ouvert. Avec moi, tu trouveras toujours un coin douillet pour te blottir."
|
||||
}
|
||||
},
|
||||
{
|
||||
"slug": "wal-sam",
|
||||
"name": {
|
||||
|
||||
@@ -40,6 +40,9 @@ const items = productsByCategory(category.slug);
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
{items.length > 0 && (
|
||||
<h2 class="kategorie-section-label">{category.icon} {category.name[lang]}</h2>
|
||||
)}
|
||||
{items.length > 0 ? (
|
||||
<div class="grid grid-3">{items.map((p) => <ProductCard product={p} lang={lang} />)}</div>
|
||||
) : (
|
||||
|
||||
@@ -21,6 +21,14 @@ const sub = getSubcategory(kategorie!, unterkategorie!)!;
|
||||
const echtProdukte = productsByUnterkategorie(category.slug, sub.slug);
|
||||
const featured = echtProdukte[0];
|
||||
const weitere = echtProdukte.slice(1);
|
||||
|
||||
// Innerhalb einer Tier-Familie (gleicher Slug-Präfix vor dem ersten "-", z.B. "hase") wechselt
|
||||
// die Foto-/Text-Seite ab: 1. Mitglied Foto links, 2. Foto rechts, 3. wieder links, usw. — sorgt
|
||||
// für optische Abwechslung, sobald mehrere Varianten einer Serie eigene Seiten bekommen.
|
||||
const familyPrefix = sub.slug.split("-")[0];
|
||||
const familyMembers = category.subcategories?.filter((s) => s.slug.split("-")[0] === familyPrefix) ?? [];
|
||||
const familyIndex = familyMembers.findIndex((s) => s.slug === sub.slug);
|
||||
const introReverse = familyIndex % 2 === 1;
|
||||
---
|
||||
<Layout title={`${sub.name[lang]} – ${category.name[lang]}`} description={`${sub.name[lang]} bi Van's DIY & Bastelbedarf.`} lang={lang} path={`/shop/${category.slug}/${sub.slug}/`}>
|
||||
<div class="container">
|
||||
@@ -37,7 +45,7 @@ const weitere = echtProdukte.slice(1);
|
||||
|
||||
{featured ? (
|
||||
<section class="section-tight">
|
||||
<div class="container grid grid-2 intro">
|
||||
<div class={`container grid grid-2 intro ${introReverse ? "intro-reverse" : ""}`}>
|
||||
<a class="portrait-frame portrait" href={`/ch/produkt/${featured.slug}/`} aria-label={featured.name[lang]}>
|
||||
{featured.bilder && featured.bilder.length > 0 ? (
|
||||
<img class="product-photo" src={featured.bilder[0]} alt={featured.name[lang]} loading="lazy" />
|
||||
@@ -45,7 +53,7 @@ const weitere = echtProdukte.slice(1);
|
||||
<div class="img-placeholder" role="img" aria-label={featured.name[lang]}></div>
|
||||
)}
|
||||
</a>
|
||||
<div>
|
||||
<div class="intro-text">
|
||||
{sub.vorstellung && <span class="eyebrow">{sub.vorstellung[lang].split("\n")[0]}</span>}
|
||||
<h2><a href={`/ch/produkt/${featured.slug}/`}>{featured.name[lang]}</a></h2>
|
||||
<p class="lead">{sub.vorstellung ? sub.vorstellung[lang].split("\n")[1] : featured.beschreibung[lang]}</p>
|
||||
|
||||
@@ -40,6 +40,9 @@ const items = productsByCategory(category.slug);
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
{items.length > 0 && (
|
||||
<h2 class="kategorie-section-label">{category.icon} {category.name[lang]}</h2>
|
||||
)}
|
||||
{items.length > 0 ? (
|
||||
<div class="grid grid-3">{items.map((p) => <ProductCard product={p} lang={lang} />)}</div>
|
||||
) : (
|
||||
|
||||
@@ -21,6 +21,14 @@ const sub = getSubcategory(kategorie!, unterkategorie!)!;
|
||||
const echtProdukte = productsByUnterkategorie(category.slug, sub.slug);
|
||||
const featured = echtProdukte[0];
|
||||
const weitere = echtProdukte.slice(1);
|
||||
|
||||
// Innerhalb einer Tier-Familie (gleicher Slug-Präfix vor dem ersten "-", z.B. "hase") wechselt
|
||||
// die Foto-/Text-Seite ab: 1. Mitglied Foto links, 2. Foto rechts, 3. wieder links, usw. — sorgt
|
||||
// für optische Abwechslung, sobald mehrere Varianten einer Serie eigene Seiten bekommen.
|
||||
const familyPrefix = sub.slug.split("-")[0];
|
||||
const familyMembers = category.subcategories?.filter((s) => s.slug.split("-")[0] === familyPrefix) ?? [];
|
||||
const familyIndex = familyMembers.findIndex((s) => s.slug === sub.slug);
|
||||
const introReverse = familyIndex % 2 === 1;
|
||||
---
|
||||
<Layout title={`${sub.name[lang]} – ${category.name[lang]}`} description={`${sub.name[lang]} at Van's DIY & Bastelbedarf.`} lang={lang} path={`/shop/${category.slug}/${sub.slug}/`}>
|
||||
<div class="container">
|
||||
@@ -37,7 +45,7 @@ const weitere = echtProdukte.slice(1);
|
||||
|
||||
{featured ? (
|
||||
<section class="section-tight">
|
||||
<div class="container grid grid-2 intro">
|
||||
<div class={`container grid grid-2 intro ${introReverse ? "intro-reverse" : ""}`}>
|
||||
<a class="portrait-frame portrait" href={`/en/produkt/${featured.slug}/`} aria-label={featured.name[lang]}>
|
||||
{featured.bilder && featured.bilder.length > 0 ? (
|
||||
<img class="product-photo" src={featured.bilder[0]} alt={featured.name[lang]} loading="lazy" />
|
||||
@@ -45,7 +53,7 @@ const weitere = echtProdukte.slice(1);
|
||||
<div class="img-placeholder" role="img" aria-label={featured.name[lang]}></div>
|
||||
)}
|
||||
</a>
|
||||
<div>
|
||||
<div class="intro-text">
|
||||
{sub.vorstellung && <span class="eyebrow">{sub.vorstellung[lang].split("\n")[0]}</span>}
|
||||
<h2><a href={`/en/produkt/${featured.slug}/`}>{featured.name[lang]}</a></h2>
|
||||
<p class="lead">{sub.vorstellung ? sub.vorstellung[lang].split("\n")[1] : featured.beschreibung[lang]}</p>
|
||||
|
||||
@@ -40,6 +40,9 @@ const items = productsByCategory(category.slug);
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
{items.length > 0 && (
|
||||
<h2 class="kategorie-section-label">{category.icon} {category.name[lang]}</h2>
|
||||
)}
|
||||
{items.length > 0 ? (
|
||||
<div class="grid grid-3">{items.map((p) => <ProductCard product={p} lang={lang} />)}</div>
|
||||
) : (
|
||||
|
||||
@@ -21,6 +21,14 @@ const sub = getSubcategory(kategorie!, unterkategorie!)!;
|
||||
const echtProdukte = productsByUnterkategorie(category.slug, sub.slug);
|
||||
const featured = echtProdukte[0];
|
||||
const weitere = echtProdukte.slice(1);
|
||||
|
||||
// Innerhalb einer Tier-Familie (gleicher Slug-Präfix vor dem ersten "-", z.B. "hase") wechselt
|
||||
// die Foto-/Text-Seite ab: 1. Mitglied Foto links, 2. Foto rechts, 3. wieder links, usw. — sorgt
|
||||
// für optische Abwechslung, sobald mehrere Varianten einer Serie eigene Seiten bekommen.
|
||||
const familyPrefix = sub.slug.split("-")[0];
|
||||
const familyMembers = category.subcategories?.filter((s) => s.slug.split("-")[0] === familyPrefix) ?? [];
|
||||
const familyIndex = familyMembers.findIndex((s) => s.slug === sub.slug);
|
||||
const introReverse = familyIndex % 2 === 1;
|
||||
---
|
||||
<Layout title={`${sub.name[lang]} – ${category.name[lang]}`} description={`${sub.name[lang]} chez Van's DIY & Bastelbedarf.`} lang={lang} path={`/shop/${category.slug}/${sub.slug}/`}>
|
||||
<div class="container">
|
||||
@@ -37,7 +45,7 @@ const weitere = echtProdukte.slice(1);
|
||||
|
||||
{featured ? (
|
||||
<section class="section-tight">
|
||||
<div class="container grid grid-2 intro">
|
||||
<div class={`container grid grid-2 intro ${introReverse ? "intro-reverse" : ""}`}>
|
||||
<a class="portrait-frame portrait" href={`/fr/produkt/${featured.slug}/`} aria-label={featured.name[lang]}>
|
||||
{featured.bilder && featured.bilder.length > 0 ? (
|
||||
<img class="product-photo" src={featured.bilder[0]} alt={featured.name[lang]} loading="lazy" />
|
||||
@@ -45,7 +53,7 @@ const weitere = echtProdukte.slice(1);
|
||||
<div class="img-placeholder" role="img" aria-label={featured.name[lang]}></div>
|
||||
)}
|
||||
</a>
|
||||
<div>
|
||||
<div class="intro-text">
|
||||
{sub.vorstellung && <span class="eyebrow">{sub.vorstellung[lang].split("\n")[0]}</span>}
|
||||
<h2><a href={`/fr/produkt/${featured.slug}/`}>{featured.name[lang]}</a></h2>
|
||||
<p class="lead">{sub.vorstellung ? sub.vorstellung[lang].split("\n")[1] : featured.beschreibung[lang]}</p>
|
||||
|
||||
@@ -40,6 +40,9 @@ const items = productsByCategory(category.slug);
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
{items.length > 0 && (
|
||||
<h2 class="kategorie-section-label">{category.icon} {category.name[lang]}</h2>
|
||||
)}
|
||||
{items.length > 0 ? (
|
||||
<div class="grid grid-3">{items.map((p) => <ProductCard product={p} lang={lang} />)}</div>
|
||||
) : (
|
||||
|
||||
@@ -24,6 +24,14 @@ const sub = getSubcategory(kategorie!, unterkategorie!)!;
|
||||
const echtProdukte = productsByUnterkategorie(category.slug, sub.slug);
|
||||
const featured = echtProdukte[0];
|
||||
const weitere = echtProdukte.slice(1);
|
||||
|
||||
// Innerhalb einer Tier-Familie (gleicher Slug-Präfix vor dem ersten "-", z.B. "hase") wechselt
|
||||
// die Foto-/Text-Seite ab: 1. Mitglied Foto links, 2. Foto rechts, 3. wieder links, usw. — sorgt
|
||||
// für optische Abwechslung, sobald mehrere Varianten einer Serie eigene Seiten bekommen.
|
||||
const familyPrefix = sub.slug.split("-")[0];
|
||||
const familyMembers = category.subcategories?.filter((s) => s.slug.split("-")[0] === familyPrefix) ?? [];
|
||||
const familyIndex = familyMembers.findIndex((s) => s.slug === sub.slug);
|
||||
const introReverse = familyIndex % 2 === 1;
|
||||
---
|
||||
<Layout title={`${sub.name[lang]} – ${category.name[lang]}`} description={`${sub.name[lang]} bei Van's DIY & Bastelbedarf.`} lang={lang} path={`/shop/${category.slug}/${sub.slug}/`}>
|
||||
<div class="container">
|
||||
@@ -40,7 +48,7 @@ const weitere = echtProdukte.slice(1);
|
||||
|
||||
{featured ? (
|
||||
<section class="section-tight">
|
||||
<div class="container grid grid-2 intro">
|
||||
<div class={`container grid grid-2 intro ${introReverse ? "intro-reverse" : ""}`}>
|
||||
<a class="portrait-frame portrait" href={`/produkt/${featured.slug}/`} aria-label={featured.name[lang]}>
|
||||
{featured.bilder && featured.bilder.length > 0 ? (
|
||||
<img class="product-photo" src={featured.bilder[0]} alt={featured.name[lang]} loading="lazy" />
|
||||
@@ -48,7 +56,7 @@ const weitere = echtProdukte.slice(1);
|
||||
<div class="img-placeholder" role="img" aria-label={featured.name[lang]}></div>
|
||||
)}
|
||||
</a>
|
||||
<div>
|
||||
<div class="intro-text">
|
||||
{sub.vorstellung && <span class="eyebrow">{sub.vorstellung[lang].split("\n")[0]}</span>}
|
||||
<h2><a href={`/produkt/${featured.slug}/`}>{featured.name[lang]}</a></h2>
|
||||
<p class="lead">{sub.vorstellung ? sub.vorstellung[lang].split("\n")[1] : featured.beschreibung[lang]}</p>
|
||||
|
||||
+19
-1
@@ -608,7 +608,15 @@ a:focus-visible, button:focus-visible {
|
||||
.intro h2 a { color: inherit; transition: color 0.2s var(--ease); }
|
||||
.intro h2 a:hover { color: var(--c-accent); }
|
||||
.intro .portrait-frame.portrait { display: block; }
|
||||
@media (max-width: 800px) { .intro { grid-template-columns: 1fr; gap: 1.5rem; } }
|
||||
/* Wechselt innerhalb einer Tier-Familie ab: Foto links/rechts, Text jeweils gegenüber — sorgt
|
||||
für optische Abwechslung, sobald mehrere Varianten einer Serie eigene Seiten bekommen. */
|
||||
.intro-reverse { grid-template-columns: 1.15fr 0.85fr; }
|
||||
.intro-reverse .portrait-frame.portrait { order: 2; }
|
||||
.intro-reverse .intro-text { order: 1; }
|
||||
@media (max-width: 800px) {
|
||||
.intro { grid-template-columns: 1fr; gap: 1.5rem; }
|
||||
.intro-reverse .portrait-frame.portrait, .intro-reverse .intro-text { order: initial; }
|
||||
}
|
||||
/* Breiter als vorher (war 440px) + Seitenverhältnis nah am Originalfoto (900x1353 ≈ 2/3)
|
||||
statt 3/4 — vorher wurde oben/unten so stark beschnitten, dass das Plushie neben VanVan
|
||||
(Oktopus) nur noch als Ecke sichtbar war. So ist das ganze Foto inkl. beider Plushies zu sehen. */
|
||||
@@ -744,6 +752,16 @@ a:focus-visible, button:focus-visible {
|
||||
/* Überschrift über der "weitere Produkte"-Reihe auf Unterkategorie-Seiten — macht klar, dass da
|
||||
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; }
|
||||
|
||||
/* Hauptkategorie-Überschrift zwischen den Unterkategorie-Chips und der eigentlichen
|
||||
Produktreihe auf der Kategorie-Seite — macht klar, welche Hauptkategorie man gerade
|
||||
durchstöbert, fällt bewusst etwas mehr auf als die stille "Unterkategorien"-Beschriftung. */
|
||||
.kategorie-section-label {
|
||||
text-align: center;
|
||||
font-size: 1.3rem;
|
||||
color: var(--c-accent);
|
||||
margin: 2.2rem 0 1.3rem;
|
||||
}
|
||||
@media (max-width: 800px) { .shop-layout { grid-template-columns: 1fr; } }
|
||||
|
||||
/* Produktseite — großes Bild bekommt denselben edlen "Rahmen"-Look wie die Porträtfotos der
|
||||
|
||||
Reference in New Issue
Block a user