From ba6e486e14bb0ab46922a84917a13f1d743679cc Mon Sep 17 00:00:00 2001 From: Marco Date: Tue, 25 Aug 2026 13:16:40 +0000 Subject: [PATCH] Revert Der Eine. mockup redesign, keep only 2 targeted changes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The full mockup-driven redesign (Banner/Lifestyle sections, restyled Focus/Why/Pricing) was more than asked for — reverted back to the pre-redesign version (Hero/Focus/Why exactly match commit 13fb37e), with only the two changes actually requested applied on top: - Focus.tsx ("Was kann er?"): dropped the product photo, plain text section now — a second product shot here was redundant with Hero's own. - Pricing.tsx (bottom price/buy bar) replaced by PasstDazu.tsx, a "Passt dazu" cross-sell card linking to ToDo-Karten — same markup as blog/[slug]/page.tsx's own related-product card, hardcoded to "todo-karten" the same way Hero.tsx hardcodes "stift-kugelschreiber". Kept the Payload product.image/gallery repointed at the mockup-derived photos (ids 88/89) rather than reverting those too — the previous gallery was mismatched stock photos of a different-colored pen, an independent correction from the layout redesign. --- app/der-eine/components/Banner.tsx | 28 ------- app/der-eine/components/Focus.tsx | 92 ++++++++------------- app/der-eine/components/Hero.tsx | 65 +++++++++++---- app/der-eine/components/Lifestyle.tsx | 22 ----- app/der-eine/components/PasstDazu.tsx | 56 +++++++++++++ app/der-eine/components/Pricing.tsx | 111 -------------------------- app/der-eine/components/Why.tsx | 43 +++------- app/der-eine/page.tsx | 14 ++-- public/der-eine-lifestyle.png | Bin 463042 -> 0 bytes 9 files changed, 155 insertions(+), 276 deletions(-) delete mode 100644 app/der-eine/components/Banner.tsx delete mode 100644 app/der-eine/components/Lifestyle.tsx create mode 100644 app/der-eine/components/PasstDazu.tsx delete mode 100644 app/der-eine/components/Pricing.tsx delete mode 100644 public/der-eine-lifestyle.png diff --git a/app/der-eine/components/Banner.tsx b/app/der-eine/components/Banner.tsx deleted file mode 100644 index 809a30c..0000000 --- a/app/der-eine/components/Banner.tsx +++ /dev/null @@ -1,28 +0,0 @@ -import Image from "next/image"; -import { Reveal } from "../../components/Reveal"; - -// A full-bleed yellow tagline strip between Hero and the "Warum" section — -// no equivalent banner/CTA-strip component exists elsewhere on the site -// (checked), so the container itself is new, but reuses two real sitewide -// building blocks instead of inventing them: the --font-caveat handwritten -// typeface (Divider.tsx/About.tsx) and /icon-separator-right.svg (also -// Divider.tsx's own "Leichtigkeit" sparkle icon), rotated to point down-right. -export function Banner() { - return ( -
- -
- -
-

- Ein guter Stift. -
- Mehr muss er nicht sein. -

-
-
- ); -} diff --git a/app/der-eine/components/Focus.tsx b/app/der-eine/components/Focus.tsx index f12ffb4..70c13b4 100644 --- a/app/der-eine/components/Focus.tsx +++ b/app/der-eine/components/Focus.tsx @@ -1,69 +1,41 @@ -import { Reveal, RevealGroup, RevealItem } from "../../components/Reveal"; +import { Reveal } from "../../components/Reveal"; -// Simple stroke-only line icons — no matching /public asset existed for -// these concepts (checked: pencil/pen/sparkle/shield), so these are drawn -// fresh rather than upscaling a raster crop from the mockup, same reasoning -// as Hero.tsx's own IconCheck (crisp at any size, recolorable). -function IconPencil() { - return ( - - - - - ); -} - -function IconPen() { - return ( - - - - - ); -} - -function IconSparkle() { - return ( - - - - ); -} - -function IconShield() { - return ( - - - - ); -} - -// This page's single feature enumeration (Hero has no bullet list anymore). -// Same card shape as todo-cards/components/HowItWorks.tsx — icon on top, -// centered, RevealGroup/RevealItem stagger, identical title/description -// typography (font-semibold text-body / text-body-sm text-text-primary) — -// reused here instead of a one-off layout, for visual consistency with the -// rest of the site. 4 cards instead of HowItWorks' 3 numbered steps, no -// connecting arrows (these are independent facts, not a sequence). +// "Was kann er?" section's full four-item breakdown (build, engraving, +// size, use case), each with its own one-line explanation rather than a +// bare phrase. const items = [ - { icon: IconPencil, title: "Metallgehäuse", desc: "Robust, wertig und angenehm in der Hand." }, - { icon: IconPen, title: "Schwarze Mine", desc: "Klassische Kugelschreibermine für ein sauberes Schriftbild." }, - { icon: IconSparkle, title: "Lasergravur", desc: "„Der Eine.“ und „einfach produktiv.“" }, - { icon: IconShield, title: "Passt überall rein", desc: "Kompakt und leicht – für Tasche, Etui, Notizbuch." }, + { title: "Metallgehäuse", desc: "Robust, wertig und angenehm in der Hand." }, + { title: "Lasergravur", desc: "„Der Eine.“ auf der einen Seite. „einfach produktiv.“ auf der anderen." }, + { title: "Kompakt", desc: "Passt ans Notizbuch, auf den Schreibtisch oder in die Tasche." }, + { title: "Für jeden Tag", desc: "Für Notizen, Gedanken, Listen und alles, was du lieber aufschreibst, bevor du es wieder vergisst." }, ]; +// No product photo here (removed 2026-08-25 — feedback: another product +// shot in this section was redundant with Hero's own gallery). Plain +// full-width text block instead of the earlier photo+text two-column +// layout. export function Focus() { return ( -
- - {items.map(({ icon: Icon, title, desc }) => ( - - -

{title}

-

{desc}

-
- ))} -
+
+ +

+ Was kann er? +

+

+ Schreiben. Und das ziemlich gut. Metallgehäuse, angenehmes Gewicht und eine klassische Kugelschreibermine — kein besonderes Produktivitäts-Gadget, sondern einfach ein guter Stift, den du gern zur Hand nimmst. +

+
    + {items.map((item) => ( +
  • + {item.title} + {item.desc} +
  • + ))} +
+
); } diff --git a/app/der-eine/components/Hero.tsx b/app/der-eine/components/Hero.tsx index 086488e..5908698 100644 --- a/app/der-eine/components/Hero.tsx +++ b/app/der-eine/components/Hero.tsx @@ -6,10 +6,23 @@ import { getProductBySlug, getShippingSettings, getDefaultTaxRatePercent, getKle import { formatPrice, discountPercent } from "../../lib/format"; import { effectiveTaxRate } from "../../lib/cartTotals"; -// No feature bullet list here (unlike this page's earlier draft) — matches -// the mockup's minimal hero (headline, short 3-line description, price, -// buy button only). The material/engraving/size facts live in Focus.tsx's -// icon row instead, one enumeration point instead of two. +// The one bullet list on this page — after feedback that three separate +// lists across Hero/Focus/Pricing was too much, this is the single place +// features get enumerated, everywhere else stays prose. A subset of the +// "Was kann er?" section's four cards (Focus.tsx) — "Für jeden Tag" is a +// use case, not a build fact, so it's covered by the body copy instead. +const features = ["Massives Metallgehäuse", "Lasergravur: „Der Eine.“ & „einfach produktiv.“", "Kompakt genug für jede Tasche"]; + +// Same fix/reasoning as TodoKartenHero.tsx's IconCheck — icon-check.svg's +// fill can't be recolored from outside the SVG when loaded via /next/image, so this stays an inline stroke path per page. +function IconCheck() { + return ( + + + + ); +} // Same "compact early teaser + delivery-time repeated next to every buy // button" reasoning as TodoKartenHero.tsx. @@ -43,17 +56,34 @@ export async function Hero() {

-

- Der Eine. -

+
+

+ Der Eine. +

+

+ Für die eine Sache, die gerade zählt. +

+

- Der Kugelschreiber zu unseren ToDo-Karten. Aus Metall, mit schwarzer Mine und „Der Eine.“ auf der Seite. + Manchmal reicht ein Stift und ein Stück Papier. Der Eine. ist ein schlichter Kugelschreiber aus Metall — angenehm in der Hand, klein genug für die Tasche und gemacht für alles, was kurz raus aus dem Kopf und irgendwo hin muss.

+
    + {features.map((item) => ( +
  • + + {item} +
  • + ))} +
+
{product && (
@@ -80,7 +110,7 @@ export async function Hero() { {product && ( - {/* max-w cap, not the full lg:col-span-7 width — image/gallery are - still fairly small source crops (~594×370, ~480×230, taken - 2026-08-25 from the mockup design), so letting ProductGallery - stretch to the full column would still upscale noticeably. */} + {/* max-w cap, not the full lg:col-span-7 width — the source photos + are only 338×338px (checked directly against the Payload media + API, no larger size exists), so letting ProductGallery stretch + to the full column blows them up hard. Capping the display + width keeps the upscale factor small enough that it doesn't + look broken; it can't fix the underlying resolution, only hide + it. Real fix is new source photos, not a layout tweak. */} {product && product.gallery.length > 0 && (
diff --git a/app/der-eine/components/Lifestyle.tsx b/app/der-eine/components/Lifestyle.tsx deleted file mode 100644 index f750305..0000000 --- a/app/der-eine/components/Lifestyle.tsx +++ /dev/null @@ -1,22 +0,0 @@ -import Image from "next/image"; -import { Reveal } from "../../components/Reveal"; - -// Full-bleed desk photo (ToDo-Karten notepad + "Der Eine." + notebook) — -// a static /public asset, not a Payload product photo: it's page decoration -// showing the pen alongside another product, not a photo *of* this product -// alone, so it doesn't belong in Products.gallery (which ProductGallery.tsx -// treats as swappable thumbnails of just the pen itself). Cropped from the -// der-eine.png mockup, 2026-08-25. -export function Lifestyle() { - return ( - - Der Eine. neben den ToDo-Karten und einem Notizbuch auf dem Schreibtisch - - ); -} diff --git a/app/der-eine/components/PasstDazu.tsx b/app/der-eine/components/PasstDazu.tsx new file mode 100644 index 0000000..94f86cd --- /dev/null +++ b/app/der-eine/components/PasstDazu.tsx @@ -0,0 +1,56 @@ +import Image from "next/image"; +import Link from "next/link"; +import { Reveal } from "../../components/Reveal"; +import { getProductBySlug } from "../../lib/payload"; + +// Replaces the page's final price/buy bar entirely (explicit choice — +// Hero.tsx already has the primary buy CTA, this page doesn't need a +// second one at the very bottom too). Same "Passend dazu" card markup as +// blog/[slug]/page.tsx's own related-product card (that one is driven by +// Posts.relatedProduct, a per-post CMS field; this page hardcodes +// "todo-karten" directly, same as Hero.tsx already hardcodes +// "stift-kugelschreiber" — a fixed cross-sell, not a general relation). +export async function PasstDazu() { + const product = await getProductBySlug("todo-karten"); + if (!product?.href) return null; + + return ( +
+ + +
+ +
+
+

Passt dazu:

+
+
+

+ {product.name} +

+

{product.description}

+
+ + Entdecken + + +
+
+ +
+
+ ); +} diff --git a/app/der-eine/components/Pricing.tsx b/app/der-eine/components/Pricing.tsx deleted file mode 100644 index 29e4754..0000000 --- a/app/der-eine/components/Pricing.tsx +++ /dev/null @@ -1,111 +0,0 @@ -import Image from "next/image"; -import { AddToCartButton } from "../../components/AddToCartButton"; -import { Reveal } from "../../components/Reveal"; -import { getProductBySlug, getShippingSettings, getDefaultTaxRatePercent, getKleinunternehmer, getCartTrustBadges } from "../../lib/payload"; -import { formatPrice, discountPercent } from "../../lib/format"; -import { effectiveTaxRate } from "../../lib/cartTotals"; - -// Price/photo come from Payload (same "stift-kugelschreiber" product the -// shop/cart use), not a hardcoded literal — same reasoning as -// todo-cards/components/Pricing.tsx. Uses product.image (the mockup-derived -// hero crop, see media ids 88/89 uploaded 2026-08-25). -export async function Pricing() { - const [product, shipping, defaultTaxRate, kleinunternehmer, trustBadges] = await Promise.all([ - getProductBySlug("stift-kugelschreiber"), - getShippingSettings(), - getDefaultTaxRatePercent(), - getKleinunternehmer(), - getCartTrustBadges(), - ]); - if (!product) return null; - const discount = discountPercent(product.price, product.compareAtPrice); - const taxRate = effectiveTaxRate(product, defaultTaxRate); - const fullyOutOfStock = - !product.active || (product.variants.length > 0 ? product.variants.every((v) => v.outOfStock) : product.outOfStock); - const anyLowStock = product.active && (product.variants.length > 0 ? product.variants.some((v) => v.lowStock) : product.lowStock); - - return ( -
- -
- Der Eine. - {fullyOutOfStock ? ( - - Ausverkauft - - ) : ( - discount !== null && ( - - -{discount}% - - ) - )} -
- -
-

- Der Eine. -

-

Metall. Kugelschreiber. Für jeden Tag.

-
- -
-
-
- {discount !== null && ( -

{formatPrice(product.compareAtPrice!)}

- )} -

{formatPrice(product.price)}

-
-

- {kleinunternehmer - ? product.noShippingCost - ? "Keine Versandkosten" - : "zzgl. Versand" - : `inkl. ${taxRate}% MwSt. ${product.noShippingCost ? "– keine Versandkosten" : "zzgl. Versand"}`} -

- {!product.noShippingCost && ( -

- Lieferzeit: {shipping.totalDays.min}–{shipping.totalDays.max} Werktage innerhalb Deutschlands -

- )} -
- {anyLowStock &&

Nur noch wenige verfügbar

} - - {/* Same content (getCartTrustBadges()) and markup as /cart's - title-only row (CartContent.tsx) — reuses the real, - already-vetted badge copy ("Nachhaltig verpackt" etc.) - instead of inventing new text to pixel-match the mockup's - placeholder wording. */} - {trustBadges.length > 0 && ( -
- {trustBadges.map((badge) => ( -
- - {badge.title} -
- ))} -
- )} -
-
-
- ); -} diff --git a/app/der-eine/components/Why.tsx b/app/der-eine/components/Why.tsx index e06c52a..841674f 100644 --- a/app/der-eine/components/Why.tsx +++ b/app/der-eine/components/Why.tsx @@ -1,32 +1,15 @@ -import Image from "next/image"; import { Reveal } from "../../components/Reveal"; -import { getProductBySlug } from "../../lib/payload"; - -// The brand-story section explaining the product's name. Same photo+text -// layout as todo-cards/components/Focus.tsx (identical classes/structure, -// reused for visual consistency rather than a one-off design) — the photo -// is product.gallery[0], an engraving close-up ("einfach produktiv." on the -// pen barrel) uploaded specifically for this section, see the mockup-derived -// media uploaded 2026-08-25 (ids 88/89 replacing the earlier mismatched -// green-pen supplier photos). -export async function Why() { - const product = await getProductBySlug("stift-kugelschreiber"); - const photo = product?.gallery[0] ?? product?.image ?? null; +// Plays the same structural role as todo-cards/components/HowItWorks.tsx (a +// content section between Hero and the material/Pricing sections, matching +// the site's established product-page rhythm) — but this is the brand-story +// section explaining the product's name, so flowing prose fits better than +// this file's former 2×2 scenario grid (replaced 2026-08-25 alongside the +// Der Alltagsstift → Der Eine. rename). +export function Why() { return ( -
- {photo && ( - - Gravur „einfach produktiv.“ auf dem Stiftkorpus - - )} - +
+

- Unsere ToDo-Karten helfen dir, dich auf das zu konzentrieren, was heute wichtig ist. + Weil du nicht alles gleichzeitig machen kannst.

- Der Stift greift diese Idee auf. + Aufschreiben hilft dabei, aus all den Dingen im Kopf das herauszuholen, was gerade wichtig ist. Und manchmal ist das eben nur: die eine Sache.

- Auf der einen Seite steht „Der Eine.“, auf der anderen „einfach produktiv.“ + Daher steht auf der einen Seite des Stifts Der Eine. und auf der anderen einfach produktiv.

- Mehr Geschichte braucht es eigentlich nicht. + Mehr steckt eigentlich nicht dahinter. Und vielleicht ist genau das der Punkt.

diff --git a/app/der-eine/page.tsx b/app/der-eine/page.tsx index 16dd79e..ae3d36d 100644 --- a/app/der-eine/page.tsx +++ b/app/der-eine/page.tsx @@ -1,17 +1,15 @@ import type { Metadata } from "next"; import { Hero } from "./components/Hero"; -import { Banner } from "./components/Banner"; import { Why } from "./components/Why"; import { Focus } from "./components/Focus"; -import { Lifestyle } from "./components/Lifestyle"; -import { Pricing } from "./components/Pricing"; +import { PasstDazu } from "./components/PasstDazu"; import { Footer } from "../components/Footer"; import { getProductBySlug, getCompanySettings } from "../lib/payload"; import { buildProductSchema } from "../lib/structuredData"; -const title = "Der Eine. – Der Kugelschreiber zu unseren ToDo-Karten."; +const title = "Der Eine. – Für die eine Sache, die gerade zählt."; const description = - "Der Eine. ist ein Kugelschreiber aus Metall, mit schwarzer Mine und „Der Eine.“ auf der Seite — der Stift zu unseren ToDo-Karten."; + "Der Eine. ist ein schlichter Kugelschreiber aus Metall. Angenehm in der Hand, klein genug für die Tasche und gemacht für alles, was kurz raus aus dem Kopf und irgendwo hin muss."; export const metadata: Metadata = { title, @@ -46,11 +44,9 @@ export default async function DerEinePage() { )}
- - - - + +