Cut /lebensuhr over to the page builder
Content recreated as a Pages document (11 blocks: intro prose, the symbolic clock icon, the "24h" prose, the Alter/Uhrzeit table, more prose, the 4-phase step row, the "Zinseszins" quote, more prose, the 3-question checklist, closing prose, the CTA card) — verified via a temporary alternate slug against the live catch-all route before switching it back to `lebensuhr` and removing the static file. The static app/lebensuhr/page.tsx is now gone; /lebensuhr resolves through app/[slug]/page.tsx.
This commit is contained in:
@@ -1,324 +0,0 @@
|
||||
import type { Metadata } from "next";
|
||||
import Link from "next/link";
|
||||
import { Reveal, RevealGroup, RevealItem } from "../components/Reveal";
|
||||
import { Footer } from "../components/Footer";
|
||||
import { StepArrow } from "../components/StepArrow";
|
||||
import { STEP_ICONS } from "../components/icons/StepIcons";
|
||||
|
||||
const title = "Die Lebensuhr: Wie spät ist es in deinem Leben?";
|
||||
const description =
|
||||
"Wie spät ist es eigentlich in deinem Leben? Die Lebensuhr zeigt dir, wo du gerade stehst – und was in dieser Phase wirklich zählt.";
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title,
|
||||
description,
|
||||
alternates: { canonical: "/lebensuhr" },
|
||||
openGraph: {
|
||||
title,
|
||||
description,
|
||||
url: "/lebensuhr",
|
||||
type: "article",
|
||||
},
|
||||
twitter: {
|
||||
title,
|
||||
description,
|
||||
},
|
||||
};
|
||||
|
||||
// Same "H2 with brand underline" treatment RichText.tsx's heading
|
||||
// converter uses for CMS-driven content — this page is hand-written (no
|
||||
// Payload post backs it, it lives at the plain /lebensuhr slug, not
|
||||
// /blog/…), so the styling is copied by hand instead of shared.
|
||||
function H2({ children }: { children: React.ReactNode }) {
|
||||
return (
|
||||
<h2
|
||||
className="font-semibold text-h-small text-text-primary mt-4 first:mt-0"
|
||||
style={{ fontFamily: "var(--font-lora)" }}
|
||||
>
|
||||
{children}
|
||||
<span className="block h-[0.125rem] w-8 bg-brand mt-2" aria-hidden />
|
||||
</h2>
|
||||
);
|
||||
}
|
||||
|
||||
function P({ children }: { children: React.ReactNode }) {
|
||||
return <p className="text-body text-text-body">{children}</p>;
|
||||
}
|
||||
|
||||
// Same visual language as RichText.tsx's Quote component (Caveat script +
|
||||
// brand divider) — copied rather than imported since that component is
|
||||
// tied to the CMS quoteLabel prop this static page has no use for.
|
||||
function Quote({ children }: { children: React.ReactNode }) {
|
||||
return (
|
||||
<div className="relative flex items-start gap-6 w-full my-2">
|
||||
<div className="w-px self-stretch bg-brand shrink-0" />
|
||||
<p className="text-text-primary text-[1.75rem] leading-[1.1] flex-1" style={{ fontFamily: "var(--font-caveat)" }}>
|
||||
{children}
|
||||
</p>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
// Purely symbolic — no numbers, no data, just a clock silhouette above the
|
||||
// headline. The earlier clock-face attempts all tried to carry the actual
|
||||
// age/time data (see git history) and never quite worked; this one carries
|
||||
// nothing, so there's nothing to get wrong. Hands fixed at ~10:10 (the
|
||||
// classic symmetric watch-ad position), not "now".
|
||||
function IconClockSymbol() {
|
||||
return (
|
||||
<svg width="48" height="48" viewBox="0 0 48 48" fill="none" aria-hidden="true">
|
||||
<circle cx="24" cy="24" r="21" stroke="#f6a701" strokeWidth="2" />
|
||||
{[0, 30, 60, 90, 120, 150, 180, 210, 240, 270, 300, 330].map((deg) => {
|
||||
const rad = (deg * Math.PI) / 180;
|
||||
const x1 = 24 + 16 * Math.sin(rad), y1 = 24 - 16 * Math.cos(rad);
|
||||
const x2 = 24 + 18.5 * Math.sin(rad), y2 = 24 - 18.5 * Math.cos(rad);
|
||||
return <line key={deg} x1={x1} y1={y1} x2={x2} y2={y2} stroke="#f6a701" strokeWidth="1.5" strokeLinecap="round" />;
|
||||
})}
|
||||
<line x1="24" y1="24" x2="17" y2="15" stroke="#f6a701" strokeWidth="2" strokeLinecap="round" />
|
||||
<line x1="24" y1="24" x2="32" y2="15" stroke="#f6a701" strokeWidth="2" strokeLinecap="round" />
|
||||
<circle cx="24" cy="24" r="1.8" fill="#f6a701" />
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
|
||||
// Same "icon-above-text, StepArrow-connected" row /7-tage-klarheits-check's
|
||||
// "So funktioniert" section and /todo-cards's/newsletter's own "How it
|
||||
// works" sections use — reused here for the four life phases instead of
|
||||
// stacking them as plain H3 blocks.
|
||||
// Same checkmark used by /7-tage-klarheits-check's "Das erwartet dich"
|
||||
// checklist.
|
||||
function Check() {
|
||||
return (
|
||||
<svg width="18" height="18" viewBox="0 0 18 18" fill="none" className="shrink-0 mt-1">
|
||||
<path d="M3 9.5l4 4L15 4" stroke="#f6a701" strokeWidth="2.2" strokeLinecap="round" strokeLinejoin="round" />
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
|
||||
// Age boundaries — same 90-year scale as lebensuhrRows below (age/90 =
|
||||
// time/24), picked so "Vormittag" ends exactly at 12:00 (age 45), which
|
||||
// also happens to line up with "Mittag" as the literal midpoint between
|
||||
// Vormittag and Nachmittag. Independent of lebensuhrRows (different
|
||||
// breakpoints), not derived from it.
|
||||
const phases = [
|
||||
{
|
||||
icon: STEP_ICONS.sunrise(),
|
||||
title: "Der Morgen: Ausprobieren",
|
||||
ageRange: "ca. 0–25 Jahre",
|
||||
desc: "Man probiert aus, lernt, macht Fehler, entdeckt Interessen. Man muss noch nicht alles perfekt können.",
|
||||
},
|
||||
{
|
||||
icon: STEP_ICONS.growthBars(),
|
||||
title: "Der Vormittag: Aufbauen",
|
||||
ageRange: "ca. 25–45 Jahre",
|
||||
desc: "Jetzt wird gebaut – Gewohnheiten, Beziehungen, Fähigkeiten. Ein Leben, das sich nach dem eigenen anfühlt.",
|
||||
},
|
||||
{
|
||||
icon: STEP_ICONS.sunHigh(),
|
||||
title: "Der Nachmittag: Stärken",
|
||||
ageRange: "ca. 45–65 Jahre",
|
||||
desc: "Nicht alles neu, sondern das Bestehende wird stärker: Erfahrung zahlt sich aus, Entscheidungen fallen leichter.",
|
||||
},
|
||||
{
|
||||
// Same icon as the morning — a rising and a setting sun both show as
|
||||
// the same arc-above-the-horizon silhouette, rays above it.
|
||||
icon: STEP_ICONS.sunrise(),
|
||||
title: "Der Abend: Weitergeben",
|
||||
ageRange: "ca. 65–90 Jahre",
|
||||
desc: "Weniger Wachstum, mehr Bedeutung – weiterzugeben, was man aufgebaut hat.",
|
||||
},
|
||||
];
|
||||
|
||||
const questions = [
|
||||
"Wie spät ist es gerade in meinem Leben?",
|
||||
"Was passt eigentlich zu dieser Tageszeit?",
|
||||
"Und welche Aufgabe schleppe ich noch mit mir herum, obwohl sie zu einer früheren Stunde gehört?",
|
||||
];
|
||||
|
||||
const lebensuhrRows: [string, string][] = [
|
||||
["10", "02:40 Uhr"],
|
||||
["20", "05:20 Uhr"],
|
||||
["30", "08:00 Uhr"],
|
||||
["40", "10:40 Uhr"],
|
||||
["50", "13:20 Uhr"],
|
||||
["60", "16:00 Uhr"],
|
||||
["70", "18:40 Uhr"],
|
||||
["80", "21:20 Uhr"],
|
||||
];
|
||||
|
||||
export default function LebensuhrPage() {
|
||||
return (
|
||||
<>
|
||||
<main className="flex flex-col flex-1 bg-bg-base">
|
||||
<Reveal className="flex flex-col gap-4 items-start pt-10 pb-8 px-[var(--layout-padding-x)] w-full max-w-[48rem] mx-auto">
|
||||
<p className="flex items-center gap-2 text-body-sm text-text-muted">
|
||||
<Link href="/" className="hover:text-brand transition-colors">Startseite</Link>
|
||||
<span>›</span>
|
||||
<span className="text-text-primary">Lebensuhr</span>
|
||||
</p>
|
||||
<p
|
||||
className="font-semibold text-[clamp(2.25rem,1.393rem+1.786vw,3rem)] text-text-primary leading-[1.15]"
|
||||
style={{ fontFamily: "var(--font-playfair)" }}
|
||||
>
|
||||
Die Lebensuhr: Wie spät ist es eigentlich in deinem Leben?
|
||||
</p>
|
||||
</Reveal>
|
||||
|
||||
<Reveal delay={0.1} className="w-full max-w-[48rem] mx-auto px-[var(--layout-padding-x)] pb-14 flex flex-col gap-5">
|
||||
<P>Wie spät ist es eigentlich in deinem Leben?</P>
|
||||
<P>Keine philosophische Frage. Eine überraschend praktische.</P>
|
||||
<P>
|
||||
Wir planen unsere Tage bis auf die Stunde. Wir blocken Meetings, setzen Erinnerungen und
|
||||
schreiben To-do-Listen. Aber kaum jemand weiß, wie er seine aktuelle Lebensphase eigentlich
|
||||
nutzen möchte.
|
||||
</P>
|
||||
|
||||
<H2>Die Lebensuhr: Dein Leben in 24 Stunden</H2>
|
||||
<IconClockSymbol />
|
||||
<P>
|
||||
Stell dir vor, dein ganzes Leben wäre auf einen einzigen Tag mit 24 Stunden komprimiert.
|
||||
Wirst du 90 Jahre alt, sieht das ungefähr so aus:
|
||||
</P>
|
||||
|
||||
{/* Still a real table (explicit "Alter"/"Uhrzeit" headers — a
|
||||
dot-on-a-line version tried here first read ambiguous
|
||||
without them, and forced a horizontal scroll on mobile for
|
||||
no gain). Dressed up with the same bg-bg-muted rounded card
|
||||
the AGB sidebar and blog author box use, brand-colored
|
||||
header, and zebra rows instead of a bare bordered table. */}
|
||||
<div className="bg-bg-muted rounded-xl overflow-hidden">
|
||||
<table className="w-full text-left border-collapse">
|
||||
<thead>
|
||||
<tr className="border-b-2 border-brand">
|
||||
<th className="py-3 pl-6 pr-4 font-semibold text-body-sm text-text-primary uppercase tracking-wide">Alter</th>
|
||||
<th className="py-3 pr-6 font-semibold text-body-sm text-text-primary uppercase tracking-wide">Uhrzeit</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{lebensuhrRows.map(([alter, uhrzeit], i) => (
|
||||
<tr key={alter} className={i % 2 === 1 ? "bg-bg-base/60" : undefined}>
|
||||
<td className="py-2.5 pl-6 pr-4 text-body text-text-body">{alter}</td>
|
||||
<td className="py-2.5 pr-6 font-semibold text-body text-text-primary">{uhrzeit}</td>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<P>Und? Wie spät ist es gerade bei dir?</P>
|
||||
|
||||
<H2>Warum die Lebensuhr mehr zeigt als dein Alter</H2>
|
||||
<P>
|
||||
Viele Menschen haben gar nicht das Gefühl, zu wenig Zeit zu haben. Sie haben das Gefühl,
|
||||
nicht dort zu sein, wo sie sein wollten. Zwei verschiedene Dinge. Man kann morgens schon
|
||||
erschöpft sein oder abends voller Energie – die Uhr sagt nichts darüber, wie du dich fühlst,
|
||||
nur wie viel Tag noch vor dir liegt.
|
||||
</P>
|
||||
<P>Die spannendere Frage lautet deshalb: Lebst du gerade so, wie es zu deiner Tageszeit passt?</P>
|
||||
<P>
|
||||
Die Lebensuhr ist dabei kein Fahrplan. Sie schreibt dir nichts vor, nur weil du an einem
|
||||
bestimmten Punkt stehst – manche fangen mit 45 nochmal komplett neu an, manche bauen mit 60
|
||||
ihr erstes eigenes Ding auf. Sie zeigt eine Tendenz, keine Vorschrift, und sie bewertet auch
|
||||
nicht, ob du "weiter" bist als andere. Sie zeigt nur, welche Art von Aufgabe in deiner
|
||||
aktuellen Phase gut zu dir passen könnte. Ein Vormittag ist schließlich auch nicht besser als
|
||||
ein Abend – nur anders.
|
||||
</P>
|
||||
|
||||
<H2>Was zu welcher Lebensphase passt</H2>
|
||||
<P>
|
||||
Diese Zuordnungen halten sich nicht strikt an die Uhr – manchmal probiert man am Nachmittag
|
||||
nochmal etwas komplett Neues aus, manchmal gibt man schon morgens etwas weiter. Sie sind ein
|
||||
Muster, kein Gesetz: Nimm dir davon, was zu deiner Situation passt.
|
||||
</P>
|
||||
</Reveal>
|
||||
|
||||
{/* Full-width StepArrow row — same pattern as /7-tage-klarheits-check's
|
||||
"So funktioniert" section, reused here for the four life phases
|
||||
instead of stacking them as plain headings. */}
|
||||
<section className="bg-bg-muted w-full py-10 lg:py-14">
|
||||
<div className="px-8 lg:px-[5rem] max-w-[1280px] mx-auto">
|
||||
<RevealGroup className="flex flex-col lg:flex-row items-center lg:items-start gap-8 lg:gap-2 w-full">
|
||||
{phases.flatMap((phase, i) => [
|
||||
<RevealItem key={phase.title} className="group flex flex-col items-center gap-4 lg:gap-5 flex-1 min-w-0">
|
||||
<div className="flex items-center justify-center w-16 h-14 shrink-0 transition-transform duration-300 group-hover:scale-110">
|
||||
{phase.icon}
|
||||
</div>
|
||||
<div className="flex flex-col gap-1 text-center">
|
||||
<p className="font-semibold text-text-primary text-[1rem]">{phase.title}</p>
|
||||
<p className="font-semibold text-[0.75rem] text-brand">{phase.ageRange}</p>
|
||||
<p className="text-[0.875rem] text-text-muted leading-[1.5]">{phase.desc}</p>
|
||||
</div>
|
||||
</RevealItem>,
|
||||
i < phases.length - 1 ? (
|
||||
<div key={`arrow-${i}`} className="flex items-center justify-center shrink-0 lg:mt-5">
|
||||
<StepArrow className="w-8 h-8 rotate-90 lg:w-10 lg:h-4 lg:rotate-0" />
|
||||
</div>
|
||||
) : null,
|
||||
])}
|
||||
</RevealGroup>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<Reveal delay={0.1} className="w-full max-w-[48rem] mx-auto px-[var(--layout-padding-x)] pt-10 pb-14 flex flex-col gap-5">
|
||||
<Quote>
|
||||
Wer am Nachmittag immer wieder bei null anfängt, verschenkt oft das Wertvollste, was er
|
||||
besitzt – den Zinseszins des eigenen Lebens.
|
||||
</Quote>
|
||||
|
||||
<H2>Produktivität beginnt mit der richtigen Lebensphase</H2>
|
||||
<P>
|
||||
Wir behandeln oft jede Lebensphase gleich – immer schneller, immer mehr, immer weiter. Dabei
|
||||
erwarten wir von einem Abend dieselbe Dynamik wie von einem frühen Morgen. Das funktioniert
|
||||
weder an einem einzigen Tag noch in einem ganzen Leben.
|
||||
</P>
|
||||
<P>
|
||||
Produktivität bedeutet für mich deshalb etwas anderes: das Richtige zur richtigen Zeit zu
|
||||
tun. Nicht ständig neu anzufangen, wenn es Zeit wäre, etwas wachsen zu lassen. Nicht
|
||||
krampfhaft festzuhalten, wenn es Zeit wäre, loszulassen. Und nicht auf "den richtigen
|
||||
Moment" warten – du lebst bereits in ihm.
|
||||
</P>
|
||||
|
||||
<H2>Drei Fragen für deine persönliche Lebensuhr</H2>
|
||||
<P>Schau heute Abend noch mal auf deine Uhr. Nicht die am Handgelenk – deine Lebensuhr.</P>
|
||||
<ul className="flex flex-col gap-3">
|
||||
{questions.map((q) => (
|
||||
<li key={q} className="flex items-start gap-3">
|
||||
<Check />
|
||||
<p className="text-body text-text-body">{q}</p>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
<P>
|
||||
Vielleicht zeigt dir die Lebensuhr heute nicht, dass du dich beeilen musst – sondern dass
|
||||
genau jetzt die richtige Zeit für das ist, was vor dir liegt. Manchmal reicht das schon, um
|
||||
den nächsten Schritt klarer zu gehen.
|
||||
</P>
|
||||
|
||||
{/* Same bordered CTA-card treatment as the blog's "Passend dazu"
|
||||
link — more click surface and visibility than a plain inline
|
||||
text link. */}
|
||||
<Link
|
||||
href="/7-tage-klarheits-check"
|
||||
className="group flex items-center justify-between gap-4 border border-border rounded-md px-6 py-5 mt-2 hover:border-brand transition-colors"
|
||||
>
|
||||
<div className="flex flex-col gap-1">
|
||||
<p className="font-bold text-[0.8125rem] text-brand">Nächster Schritt:</p>
|
||||
<p className="font-semibold text-body text-text-primary" style={{ fontFamily: "var(--font-lora)" }}>
|
||||
7-Tage-Klarheits-Check
|
||||
</p>
|
||||
<p className="text-body-sm text-text-muted">Ein ruhiger Einstieg, sieben Tage lang.</p>
|
||||
</div>
|
||||
<svg
|
||||
viewBox="0 0 20 20"
|
||||
className="size-4 shrink-0 text-text-primary transition-transform duration-200 group-hover:translate-x-1"
|
||||
fill="none"
|
||||
aria-hidden="true"
|
||||
>
|
||||
<path d="M4 10h12m0 0-5-5m5 5-5 5" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" />
|
||||
</svg>
|
||||
</Link>
|
||||
</Reveal>
|
||||
</main>
|
||||
<Footer />
|
||||
</>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user