Add /die-sieben — rebuilt from the old WordPress page, brand-voice copy

Free monthly ritual page, modeled on /todo-cards' conventions
(Reveal/RevealGroup, breadcrumb + text-display heading) but without a
product-style hero — this isn't a paid product, so no photo/price/buy
CTA. The WordPress original's monthly-changing "aktuelle Ausgabe",
printable template, and archive have no content model in this codebase
yet (nothing like a `Posts` collection for "editions") — this ships the
evergreen concept page only, with the existing Newsletter signup
standing in as the "stay in the loop" mechanism. Deferred to a memory
note rather than blocking this page on designing a new collection.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018unaXmuzVA8ct1b6WoyP1U
This commit is contained in:
Marco
2026-07-31 23:09:24 +00:00
parent 8b636bef25
commit aa491aa5fd
5 changed files with 234 additions and 0 deletions
+1
View File
@@ -88,6 +88,7 @@ not in a committed `.env`.
| `/konto/merkliste` | Wishlist (when `wishlistEnabled`, see "Feature toggles" below) |
| `/challenge` | "Mini-Challenge" tool |
| `/todo-cards` | "Todo-Karten" tool |
| `/die-sieben` | "Die Sieben" — free monthly ritual (evergreen concept page only; the WordPress original's monthly-changing edition/archive/template has no content model in this codebase yet, see `app/die-sieben/page.tsx`'s own comment) |
| `/newsletter` | Newsletter signup |
| `/versand` | Shipping policy (timeframes, costs) |
| `/impressum`, `/datenschutz`, `/agb`, `/widerruf` | Legal pages (from Payload, see `legal-pages` below) |
@@ -0,0 +1,52 @@
import Link from "next/link";
import { Reveal } from "../../components/Reveal";
// No product photo exists for this page (unlike /todo-cards, /lebensuhr) —
// this is a free monthly ritual, not something with packaging to shoot.
// Text + a Caveat-font quote carries the hero instead, same treatment
// RichText.tsx's Quote component already uses for a callout line.
export function DieSiebenHero() {
return (
<section className="bg-bg-base w-full">
<Reveal className="flex flex-col gap-6 items-start px-[var(--layout-padding-x)] pt-10 pb-12 sm:pt-12 sm:pb-16 max-w-[46rem] mx-auto text-center sm:items-center">
{/* Breadcrumb left-aligned regardless of the centered content
below, same "not part of the centered block" split as
/todo-cards's and /lebensuhr's own hero. */}
<p className="self-start flex items-center gap-2 text-body-sm text-text-muted">
<Link href="/" className="hover:text-brand transition-colors">
Startseite
</Link>
<span></span>
<Link href="/#werkzeuge" className="hover:text-brand transition-colors">
Werkzeuge
</Link>
<span></span>
<span className="text-text-primary">Die Sieben</span>
</p>
<div className="flex flex-col gap-3 items-center">
<p
className="font-semibold text-display text-text-primary"
style={{ fontFamily: "var(--font-lora)" }}
>
Die Sieben<span className="text-brand">.</span>
</p>
<p className="font-semibold text-h4 text-text-muted" style={{ fontFamily: "var(--font-lora)" }}>
Das Monatsritual von einfach produktiv
</p>
</div>
<p className="text-body text-text-body max-w-[32rem]">
Sieben kleine Dinge, die den Monat ein bisschen reicher machen.
</p>
<p
className="text-text-primary text-[1.75rem] leading-[1.2] mt-2"
style={{ fontFamily: "var(--font-caveat)" }}
>
&bdquo;Nicht alles, was zählt, steht auf einer ToDo-Liste.&ldquo;
</p>
</Reveal>
</section>
);
}
+30
View File
@@ -0,0 +1,30 @@
import { Reveal } from "../../components/Reveal";
export function Philosophie() {
return (
<section className="w-full bg-bg-muted">
<Reveal className="flex flex-col gap-6 items-start px-[var(--layout-padding-x)] py-14 sm:py-16 max-w-[42rem] mx-auto">
<p
className="font-semibold text-h-emphasis text-text-primary"
style={{ fontFamily: "var(--font-lora)" }}
>
Worum es geht
</p>
<p className="text-body text-text-body">
Am Ende eines Monats weiß ich meistens ziemlich genau, was ich erledigt habe. Was ich
eigentlich erlebt habe, weiß ich oft nicht mehr. Daraus ist Die Sieben entstanden.
</p>
<p className="text-body text-text-body">
Jeden Monat gibt es sieben kleine Einladungen kein Programm, kein Plan, den man
abarbeitet. Man nimmt sich, was passt. Den Rest lässt man liegen.
</p>
<p
className="font-semibold text-body text-text-primary border-l-2 border-brand pl-4"
>
Es geht nicht darum, möglichst viel zu erleben, sondern die Dinge bewusster
wahrzunehmen, die ohnehin schon da sind.
</p>
</Reveal>
</section>
);
}
@@ -0,0 +1,98 @@
import { Fragment } from "react";
import { Reveal, RevealGroup, RevealItem } from "../../components/Reveal";
import { StepArrow } from "../../components/StepArrow";
// Hand-drawn inline SVGs, brand-orange stroke — same convention as
// /lebensuhr's own icon set (IconEnvelope etc.), used here instead of a
// photo since there's no product to shoot for a free monthly ritual.
function IconHand() {
return (
<svg width="52" height="48" viewBox="0 0 52 48" fill="none">
<path
d="M14 22V8a4 4 0 0 1 8 0v10M22 18V6a4 4 0 0 1 8 0v12M30 18V9a4 4 0 0 1 8 0v17c0 9.4-7.6 17-17 17h-3c-6 0-9-2-12.5-7L2 24a4 4 0 0 1 6-5l6 5"
stroke="#f6a701"
strokeWidth="2"
strokeLinecap="round"
strokeLinejoin="round"
/>
</svg>
);
}
function IconEye() {
return (
<svg width="52" height="34" viewBox="0 0 52 34" fill="none">
<path
d="M2 17S12 2 26 2s24 15 24 15-10 15-24 15S2 17 2 17Z"
stroke="#f6a701"
strokeWidth="2"
strokeLinejoin="round"
/>
<circle cx="26" cy="17" r="7" stroke="#f6a701" strokeWidth="2" />
</svg>
);
}
function IconShare() {
return (
<svg width="44" height="48" viewBox="0 0 44 48" fill="none">
<circle cx="8" cy="24" r="6" stroke="#f6a701" strokeWidth="2" />
<circle cx="36" cy="8" r="6" stroke="#f6a701" strokeWidth="2" />
<circle cx="36" cy="40" r="6" stroke="#f6a701" strokeWidth="2" />
<path d="M13.5 21 30.5 11M13.5 27l17 10" stroke="#f6a701" strokeWidth="2" strokeLinecap="round" />
</svg>
);
}
const punkte = [
{
icon: <IconHand />,
title: "Nimm dir, was passt",
desc: "Eine Einladung, drei oder alle sieben es gibt kein Richtig oder Falsch dabei.",
},
{
icon: <IconEye />,
title: "Nichts zum Abhaken",
desc: "Die Sieben ist kein Programm. Es reicht, die Dinge bewusst wahrzunehmen.",
},
{
icon: <IconShare />,
title: "Teilen, wenn du magst",
desc: "Manche erzählen anderen von ihren Sieben nicht um sich zu messen, sondern um sich zu erinnern.",
},
];
export function SoFunktionierts() {
return (
<section className="w-full bg-bg-base flex flex-col gap-12 items-center py-14 sm:py-16 px-[var(--layout-padding-x)]">
<Reveal className="flex flex-col gap-2 items-center text-center">
<p
className="font-semibold text-h-emphasis text-text-primary"
style={{ fontFamily: "var(--font-lora)" }}
>
So läuft es ab
</p>
<p className="text-body text-text-muted">Jeden Monat neu. Ohne Verpflichtung.</p>
</Reveal>
<RevealGroup className="flex flex-col sm:flex-row gap-8 items-center sm:items-start w-full lg:px-[10rem]">
{punkte.map((punkt, i) => (
<Fragment key={punkt.title}>
<RevealItem className="group flex flex-col gap-4 items-center text-center flex-1 max-w-xs sm:max-w-none">
<div className="flex items-center justify-center h-14 transition-transform duration-300 group-hover:scale-110">
{punkt.icon}
</div>
<p className="font-semibold text-body text-text-primary">{punkt.title}</p>
<p className="text-body-sm text-text-primary text-center">{punkt.desc}</p>
</RevealItem>
{i < punkte.length - 1 && (
<div className="flex items-center justify-center shrink-0 sm:mt-[1.5rem]">
<StepArrow className="w-8 h-8 rotate-90 sm:w-10 sm:h-4 sm:rotate-0" />
</div>
)}
</Fragment>
))}
</RevealGroup>
</section>
);
}
+53
View File
@@ -0,0 +1,53 @@
import type { Metadata } from "next";
import { DieSiebenHero } from "./components/DieSiebenHero";
import { Philosophie } from "./components/Philosophie";
import { SoFunktionierts } from "./components/SoFunktionierts";
import { Footer } from "../components/Footer";
import { Newsletter } from "../components/Newsletter";
const title = "Die Sieben Das Monatsritual von einfach produktiv";
const description =
"Sieben kleine Dinge, die den Monat ein bisschen reicher machen. Kein Programm, keine Pflicht nur eine Einladung, bewusster wahrzunehmen, was ohnehin schon da ist.";
export const metadata: Metadata = {
title,
description,
alternates: {
canonical: "/die-sieben",
},
openGraph: {
title,
description,
url: "/die-sieben",
},
twitter: {
title,
description,
},
};
// Rebuilt from the old WordPress page of the same name — a free monthly
// ritual, not a product, so unlike /todo-cards or /lebensuhr there's no
// photo asset and no pricing/testimonials section here. The WordPress
// original also linked out to a monthly-changing "aktuelle Ausgabe" card,
// a printable template, and an archive of past months — none of that has
// a home in this codebase yet (no CMS collection backs it), so this build
// is the evergreen concept page only. Newsletter signup below stands in as
// the "stay in the loop" mechanism until/unless a real "monthly edition"
// content model gets built.
export default function DieSiebenPage() {
return (
<>
<main className="flex flex-col flex-1 bg-bg-base">
<DieSiebenHero />
<Philosophie />
<SoFunktionierts />
<Newsletter
title="Nicht verpassen, wenn eine neue Sieben erscheint"
description="Ich schreibe dir, sobald es die Sieben für den nächsten Monat gibt ohne Spam, jederzeit abbestellbar."
/>
</main>
<Footer />
</>
);
}