build / build (push) Successful in 1m38s
Recovered work in progress that sat uncommitted since 2026-05: a SelectionBox renders as a plain div instead of a NuxtLink when locked, so a variant with only one choice reads as decided rather than clickable, and it reports aria-checked in that state. useProductContent gained the content lookups the details and index pages now use, the cookie banner says Schließen instead of Akzeptieren, the Über uns header entry is gone, and ProductCard's hover shadow no longer relies on a short-circuit that could yield a non-array.
419 lines
15 KiB
TypeScript
419 lines
15 KiB
TypeScript
// Product content keyed by cover type
|
||
// This content is displayed on product detail pages as storytelling modules
|
||
|
||
export type CoverType = "Hardcover" | "Softcover" | "Heft" | "Spiralbindung" | "Promo";
|
||
|
||
export interface FeatureModule {
|
||
eyebrow?: string;
|
||
headline: string;
|
||
subtitle?: string;
|
||
body: string;
|
||
image?: string;
|
||
imageRight?: boolean;
|
||
}
|
||
|
||
export interface UseCase {
|
||
icon: "pen" | "palette" | "clipboard" | "briefcase";
|
||
title: string;
|
||
description: string;
|
||
}
|
||
|
||
// =============================================================================
|
||
// FEATURE MODULES - Storytelling sections per cover type
|
||
// =============================================================================
|
||
|
||
export const FEATURE_MODULES: Record<CoverType, FeatureModule[]> = {
|
||
Hardcover: [
|
||
{
|
||
eyebrow: "Handarbeit",
|
||
headline: "Klassische Fadenheftung",
|
||
subtitle: "Strapazierfähig bei intensivem Gebrauch",
|
||
body: `Jedes Heft wird mit Singer-Stich-Heftung von Hand gebunden.
|
||
Das Ergebnis: Ein Notizbuch, das sich vollständig flach öffnen
|
||
lässt und auch nach Jahren intensiver Nutzung nicht auseinanderfällt.
|
||
Der rote Vorsatzbogen setzt einen dezenten Farbakzent –
|
||
Deine erste Begegnung beim Öffnen.`,
|
||
image: "/images/features/hardcover/binding-closeup.jpg",
|
||
imageRight: false,
|
||
},
|
||
{
|
||
eyebrow: "100% Recycling",
|
||
headline: "VIVUS 89 Papier",
|
||
subtitle: "Außergewöhnliche Schreibqualität",
|
||
body: `VIVUS 89 ist nicht irgendein Recyclingpapier.
|
||
Die matte, ungestrichene Oberfläche mit feiner Textur verhindert
|
||
Durchschlagen – selbst bei Füllfederhaltern und Aquarellfarben.
|
||
Mit 120g/qm und 1,2-fachem Volumen fühlt sich jede Seite
|
||
substanziell an, ohne starr zu wirken.`,
|
||
image: "/images/features/hardcover/paper-texture.jpg",
|
||
imageRight: true,
|
||
},
|
||
{
|
||
headline: "160 Seiten für Deine Ideen",
|
||
subtitle: "Raum für 3-6 Monate intensive Arbeit",
|
||
body: `160 Seiten bedeuten genug Platz für ein abgeschlossenes Projekt,
|
||
eine komplette Reise, oder ein Quartal Deines Bullet Journals.
|
||
Blanko-Seiten geben Dir absolute Freiheit: Skizzieren, Schreiben,
|
||
Collagieren – ohne Raster, das Deine Kreativität einschränkt.`,
|
||
image: "/images/features/hardcover/lifestyle-desk.jpg",
|
||
imageRight: false,
|
||
},
|
||
{
|
||
headline: "Kein Heft gleicht dem anderen",
|
||
subtitle: "13 einzigartige Mustervarianten",
|
||
body: `Jeder Einband wird individuell mit variierenden geometrischen
|
||
Mustern bedruckt. Die Kombination aus mattem Schwarz (300g/qm Karton)
|
||
und den Mustern macht Dein Heft unverwechselbar.`,
|
||
image: "/images/features/hardcover/cover-pattern.jpg",
|
||
imageRight: true,
|
||
},
|
||
{
|
||
eyebrow: "Made in Stuttgart",
|
||
headline: "Transparente Lieferkette",
|
||
subtitle: "Messbare Nachhaltigkeit",
|
||
body: `<strong>100% Recyclingpapier</strong> (FSC® C018175)<br>
|
||
<strong>CO₂-neutral</strong> produziert<br>
|
||
<strong>Blauer Engel + EU Ecolabel</strong> zertifiziert<br>
|
||
<strong>Hergestellt in Stuttgart</strong>, Deutschland<br><br>
|
||
Keine langen Transportwege, keine Ausbeutung, kein Greenwashing.
|
||
Nur ehrliches Handwerk mit messbaren Umweltstandards.`,
|
||
image: "/images/production/04.png",
|
||
imageRight: false,
|
||
},
|
||
],
|
||
|
||
Softcover: [
|
||
{
|
||
eyebrow: "Leicht & Flexibel",
|
||
headline: "Der tägliche Begleiter",
|
||
subtitle: "Passt in jede Tasche",
|
||
body: `Das Softcover ist Dein unkomplizierter Alltagsbegleiter.
|
||
Leicht, flexibel und robust – perfekt für unterwegs.
|
||
Die weiche Hülle schmiegt sich an und übersteht jeden Rucksack.`,
|
||
image: "/images/features/softcover/flexible-cover.jpg",
|
||
imageRight: false,
|
||
},
|
||
{
|
||
eyebrow: "100% Recycling",
|
||
headline: "VIVUS 89 Papier",
|
||
subtitle: "Dieselbe Qualität, leichteres Format",
|
||
body: `Auch im Softcover kommt unser bewährtes VIVUS 89 Recyclingpapier
|
||
zum Einsatz. 120g/qm für optimale Schreibqualität ohne Durchschlagen.
|
||
Perfekt für Füllfederhalter, Fineliner und Aquarellstifte.`,
|
||
image: "/images/features/softcover/paper-writing.jpg",
|
||
imageRight: true,
|
||
},
|
||
{
|
||
headline: "Praktische Steppstich-Bindung",
|
||
subtitle: "Liegt flach, bleibt offen",
|
||
body: `Die Steppstich-Bindung ermöglicht ein vollständiges Aufklappen.
|
||
Ideal zum Schreiben, Zeichnen und für alle, die beide Seiten
|
||
gleichzeitig nutzen möchten.`,
|
||
image: "/images/features/softcover/binding-detail.jpg",
|
||
imageRight: false,
|
||
},
|
||
{
|
||
eyebrow: "Made in Stuttgart",
|
||
headline: "Nachhaltig produziert",
|
||
subtitle: "Lokale Fertigung, globale Standards",
|
||
body: `<strong>FSC® zertifiziert</strong><br>
|
||
<strong>Blauer Engel</strong> Umweltzeichen<br>
|
||
<strong>CO₂-neutral</strong> hergestellt<br><br>
|
||
Kurze Wege, faire Produktion, messbare Nachhaltigkeit.`,
|
||
image: "/images/features/softcover/workshop.png",
|
||
imageRight: true,
|
||
},
|
||
],
|
||
|
||
Heft: [
|
||
{
|
||
eyebrow: "Kompakt & Praktisch",
|
||
headline: "Das klassische Notizheft",
|
||
subtitle: "Für schnelle Notizen und Ideen",
|
||
body: `Manchmal braucht man kein dickes Notizbuch – sondern ein
|
||
handliches Heft für den Moment. Perfekt für Meeting-Notizen,
|
||
Einkaufslisten oder spontane Skizzen.`,
|
||
image: "/images/features/heft/compact-size.jpg",
|
||
imageRight: false,
|
||
},
|
||
{
|
||
eyebrow: "100% Recycling",
|
||
headline: "Qualität im Kleinformat",
|
||
subtitle: "VIVUS 89 auch im Heft",
|
||
body: `Unser Recyclingpapier macht auch im kleinen Format keine
|
||
Kompromisse. Die gleiche Schreibqualität, die Du von unseren
|
||
größeren Notizbüchern kennst.`,
|
||
image: "/images/features/heft/paper-quality.jpg",
|
||
imageRight: true,
|
||
},
|
||
{
|
||
headline: "Ruckzuck-Heftung",
|
||
subtitle: "Einfach, aber solide",
|
||
body: `Die klassische Rückstich-Heftung hält Dein Heft zusammen
|
||
und ermöglicht ein flaches Aufklappen. Bewährt seit Generationen,
|
||
nachhaltig für die Zukunft.`,
|
||
image: "/images/features/heft/binding.jpg",
|
||
imageRight: false,
|
||
},
|
||
],
|
||
|
||
Spiralbindung: [
|
||
{
|
||
eyebrow: "360° Flexibilität",
|
||
headline: "Wire-O-Bindung",
|
||
subtitle: "Komplett umklappbar",
|
||
body: `Die Spiralbindung lässt sich vollständig umklappen –
|
||
ideal für beengte Arbeitsflächen. Schreibe auf einer Seite,
|
||
während die andere flach auf dem Tisch liegt.`,
|
||
image: "/images/features/spiral/360-flip.jpg",
|
||
imageRight: false,
|
||
},
|
||
{
|
||
eyebrow: "100% Recycling",
|
||
headline: "VIVUS 89 Papier",
|
||
subtitle: "Premium-Qualität, flexibles Format",
|
||
body: `Unser bewährtes Recyclingpapier in der praktischen
|
||
Spiralbindung. 120g/qm verhindern Durchschlagen –
|
||
auch bei intensiver Nutzung mit verschiedenen Stiften.`,
|
||
image: "/images/features/spiral/paper-texture.jpg",
|
||
imageRight: true,
|
||
},
|
||
{
|
||
headline: "Seiten heraustrennbar",
|
||
subtitle: "Perforation für sauberes Abtrennen",
|
||
body: `Jede Seite lässt sich sauber heraustrennen – perfekt,
|
||
wenn Du Notizen weitergeben oder Skizzen verschenken möchtest.
|
||
Die Mikroperforation sorgt für glatte Kanten.`,
|
||
image: "/images/features/spiral/tear-out.jpg",
|
||
imageRight: false,
|
||
},
|
||
{
|
||
eyebrow: "Made in Stuttgart",
|
||
headline: "Nachhaltig & Praktisch",
|
||
subtitle: "Das Beste aus beiden Welten",
|
||
body: `<strong>Recycling-Drahtbindung</strong><br>
|
||
<strong>FSC® zertifiziertes Papier</strong><br>
|
||
<strong>CO₂-neutral</strong> produziert<br><br>
|
||
Funktionalität trifft Nachhaltigkeit.`,
|
||
image: "/images/features/spiral/workshop.jpg",
|
||
imageRight: true,
|
||
},
|
||
],
|
||
|
||
Promo: [
|
||
{
|
||
eyebrow: "12 Wochen · 3 Monate",
|
||
headline: "Struktur für deinen Alltag",
|
||
subtitle: "Planung, Intention & Reflexion",
|
||
body: `Dieses Journaling Booklet im Format A5 sorgt für mehr Produktivität im Alltag.
|
||
Es beinhaltet Monats-, Wochen- und Tagesplanungen sowie inspirierenden Zitaten
|
||
für insgesamt 12 Wochen bzw. 3 Monate. Jeder Tag bietet Platz für eine
|
||
Tagesintention, den täglichen Aufgaben, dem Notieren von Mahlzeiten und der
|
||
Fitnessroutine. Darüber hinaus bietet es die Möglichkeit der eigene
|
||
Tagesreflexion. Als tägliche Begleiter soll es helfen, deine Zeit effektiv zu
|
||
managen, um mit mehr Klarheit und Struktur deine Ziele anzugehen.`,
|
||
imageRight: true,
|
||
},
|
||
{
|
||
eyebrow: "Gestaltet von mk rietzl",
|
||
headline: "VIVUS 89 Recyclingpapier",
|
||
subtitle: "Matt, 120g/qm, fliederfarbener Umschlag",
|
||
body: `Das Journaling Booklet wurde konzipiert und gestaltet von Michèle Rietzl
|
||
(mk rietzl). Es ist auf VIVUS 89 Recyclingpapier gedruckt. Die matte,
|
||
ungestrichene Oberfläche mit feiner Textur verhindert Durchschlagen – selbst bei
|
||
Füllfederhaltern und Aquarellfarben. Mit 120g/qm und 1,2-fachem Volumen fühlt
|
||
sich jede Seite substanziell an, ohne starr zu wirken. Der fliederfarbene
|
||
Umschlag sorgt für schlichte Farbakzente.`,
|
||
imageRight: false,
|
||
},
|
||
{
|
||
eyebrow: "Handgefertigt in Stuttgart",
|
||
headline: "Fadenbindung mit offenem Buchrücken",
|
||
subtitle: "Vollständiges Aufklappen zum Schreiben",
|
||
body: `Bei der Bindung handelt es sich um eine klassische Fadenbindung mit offenem
|
||
Buchrücken. Dies ermöglicht ein vollständiges Aufklappen, was sich ideal zum
|
||
Schreiben eignet. Die Booklets werden mit größter Sorgfalt in Stuttgart
|
||
produziert. Jedes Exemplar ist handgefertigt.`,
|
||
imageRight: true,
|
||
},
|
||
],
|
||
};
|
||
|
||
// =============================================================================
|
||
// TECHNICAL SPECS - Collapsible details per cover type
|
||
// =============================================================================
|
||
|
||
export const TECHNICAL_SPECS: Record<CoverType, Record<string, string>> = {
|
||
Hardcover: {
|
||
Format: "150 × 210 mm (A5)",
|
||
Seitenanzahl: "160 Seiten (80 Blatt)",
|
||
Papier: "VIVUS 89, 120g/qm, 100% Recycling",
|
||
Einband: "300g/qm Recyclingkarton",
|
||
Bindung: "Klassische Fadenheftung (Singer-Stich)",
|
||
Vorsatzpapier: "Rot durchgefärbt",
|
||
Zertifizierung: "FSC® C018175, Blauer Engel, EU Ecolabel",
|
||
Herstellung: "Stuttgart, Deutschland",
|
||
},
|
||
Softcover: {
|
||
Format: "150 × 210 mm (A5)",
|
||
Seitenanzahl: "96 Seiten (48 Blatt)",
|
||
Papier: "VIVUS 89, 120g/qm, 100% Recycling",
|
||
Einband: "250g/qm Recyclingkarton, flexibel",
|
||
Bindung: "Steppstich-Heftung",
|
||
Zertifizierung: "FSC® C018175, Blauer Engel, EU Ecolabel",
|
||
Herstellung: "Stuttgart, Deutschland",
|
||
},
|
||
Heft: {
|
||
Format: "148 × 210 mm (A5)",
|
||
Seitenanzahl: "20, 40 oder 60 Seiten",
|
||
Papier: "VIVUS 89, 120g/qm, 100% Recycling",
|
||
Einband: "200g/qm Recyclingkarton",
|
||
Bindung: "Rückstich-Heftung",
|
||
Zertifizierung: "FSC® C018175, Blauer Engel",
|
||
Herstellung: "Stuttgart, Deutschland",
|
||
},
|
||
Spiralbindung: {
|
||
Format: "150 × 210 mm (A5)",
|
||
Seitenanzahl: "120 Seiten (60 Blatt)",
|
||
Papier: "VIVUS 89, 120g/qm, 100% Recycling",
|
||
Einband: "300g/qm Recyclingkarton",
|
||
Bindung: "Wire-O-Bindung (Doppeldraht)",
|
||
Perforation: "Mikroperforation zum Heraustrennen",
|
||
Zertifizierung: "FSC® C018175, Blauer Engel, EU Ecolabel",
|
||
Herstellung: "Stuttgart, Deutschland",
|
||
},
|
||
Promo: {
|
||
Format: "150 × 210 mm (A5)",
|
||
Umfang: "12 Wochen / 3 Monate",
|
||
Layout: "Vorgedruckt (Tages-, Wochen- & Monatsplanung)",
|
||
Papier: "VIVUS 89, 120g/qm, 1,2-faches Volumen, ungestrichen matt",
|
||
Einband: "Fliederfarbener Softcover",
|
||
Bindung: "Fadenbindung mit offenem Buchrücken",
|
||
Herstellung: "Handgefertigt in Stuttgart",
|
||
},
|
||
};
|
||
|
||
// =============================================================================
|
||
// USE CASES - Same for all products
|
||
// =============================================================================
|
||
|
||
export const USE_CASES: UseCase[] = [
|
||
{
|
||
icon: "pen",
|
||
title: "Schreibprojekte",
|
||
description: "Romane, Tagebuch, Morning Pages",
|
||
},
|
||
{
|
||
icon: "palette",
|
||
title: "Mixed-Media",
|
||
description: "Aquarell, Collage, Skizzen",
|
||
},
|
||
{
|
||
icon: "clipboard",
|
||
title: "Sketchbook",
|
||
description: "Layouts ohne Raster",
|
||
},
|
||
{
|
||
icon: "briefcase",
|
||
title: "Arbeit & Studium",
|
||
description: "Meetings, Forschung, Konzepte",
|
||
},
|
||
];
|
||
|
||
// =============================================================================
|
||
// HELPER: Get cover type from product.cover.name
|
||
// =============================================================================
|
||
|
||
export function getCoverType(coverName?: string): CoverType {
|
||
if (!coverName) return "Hardcover";
|
||
const name = coverName.toLowerCase();
|
||
if (name.includes("heft")) return "Heft";
|
||
if (name.includes("hardcover")) return "Hardcover";
|
||
if (name.includes("softcover")) return "Softcover";
|
||
if (name.includes("spiral") || name.includes("wire")) return "Spiralbindung";
|
||
// Standalone promo bucket (cover named "Promo").
|
||
if (name.includes("promo")) return "Promo";
|
||
return "Hardcover"; // fallback
|
||
}
|
||
|
||
// =============================================================================
|
||
// COMPOSABLE
|
||
// =============================================================================
|
||
|
||
import type { Product } from "~/types";
|
||
|
||
export function useProductContent(
|
||
coverName: Ref<string | undefined> | ComputedRef<string | undefined>,
|
||
product?: Ref<Product | null> | ComputedRef<Product | null>
|
||
) {
|
||
const coverType = computed(() => getCoverType(coverName.value));
|
||
const featureModules = computed(() => FEATURE_MODULES[coverType.value] ?? []);
|
||
|
||
// Derive technical specs from product data when available
|
||
const technicalSpecs = computed(() => {
|
||
const baseSpecs = TECHNICAL_SPECS[coverType.value] ?? {};
|
||
const prod = product?.value;
|
||
|
||
if (!prod) return baseSpecs;
|
||
|
||
const derivedSpecs: Record<string, string> = {};
|
||
|
||
// Format from copyText
|
||
if (prod.cover?.copyText?.format) {
|
||
derivedSpecs["Format"] = prod.cover.copyText.format;
|
||
}
|
||
|
||
// Seitenanzahl from pages (skip for Promo/standalone — page count not relevant)
|
||
if (prod.pages?.name && coverType.value !== "Promo") {
|
||
derivedSpecs["Seitenanzahl"] = prod.pages.name;
|
||
} else if (prod.pages?.count && coverType.value !== "Promo") {
|
||
const sheets = Math.floor(prod.pages.count / 2);
|
||
derivedSpecs["Seitenanzahl"] = `${prod.pages.count} Seiten (${sheets} Blatt)`;
|
||
}
|
||
|
||
// Parse paper string: "VIVUS 89: 100% Recyclingpapier, ... Inhalt: 120g/qm, Einband: 300g/qm. Zertifizierung: ..."
|
||
if (prod.cover?.copyText?.paper) {
|
||
const paperText = prod.cover.copyText.paper;
|
||
|
||
// Extract paper name and description (before "Inhalt:")
|
||
const inhaltMatch = paperText.match(/^(.+?)(?:\s*Inhalt:|$)/);
|
||
if (inhaltMatch) {
|
||
derivedSpecs["Papier"] = inhaltMatch[1].trim().replace(/,\s*$/, "");
|
||
}
|
||
|
||
// Extract Inhalt (paper weight)
|
||
const inhaltWeightMatch = paperText.match(/Inhalt:\s*([^,]+)/);
|
||
if (inhaltWeightMatch) {
|
||
derivedSpecs["Papiergewicht"] = inhaltWeightMatch[1].trim();
|
||
}
|
||
|
||
// Extract Einband (cover weight)
|
||
const einbandMatch = paperText.match(/Einband:\s*([^.]+)/);
|
||
if (einbandMatch) {
|
||
derivedSpecs["Einband"] = einbandMatch[1].trim();
|
||
}
|
||
|
||
// Extract Zertifizierung
|
||
const zertMatch = paperText.match(/Zertifizierung:\s*(.+)$/);
|
||
if (zertMatch) {
|
||
derivedSpecs["Zertifizierung"] = zertMatch[1].trim();
|
||
}
|
||
}
|
||
|
||
// Bindung from cover binding
|
||
if (prod.cover?.binding) {
|
||
derivedSpecs["Bindung"] = prod.cover.binding;
|
||
}
|
||
|
||
// Merge: product data overrides base specs
|
||
return { ...baseSpecs, ...derivedSpecs };
|
||
});
|
||
|
||
return {
|
||
coverType,
|
||
featureModules,
|
||
technicalSpecs,
|
||
useCases: USE_CASES,
|
||
};
|
||
}
|