Files
einfach-produktiv/app/lebensuhr/page.tsx
T
Marco fff2467d19 Lebensuhr: replace plain data table with a clock-scale timeline
A horizontal dotted line with each age/time pair on it reads as an
actual clock scale instead of a bare two-column table needing a
caption to explain itself. Same bg-bg-muted rounded-card treatment
already used by the AGB sidebar and the blog author box.
2026-08-26 15:26:36 +00:00

325 lines
15 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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";
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>
);
}
// 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.
function IconSunrise() {
return (
<svg width="44" height="40" viewBox="0 0 44 40" fill="none">
<line x1="4" y1="30" x2="40" y2="30" stroke="#f6a701" strokeWidth="2" strokeLinecap="round" />
<path d="M13 30a9 9 0 0 1 18 0" stroke="#f6a701" strokeWidth="2" strokeLinecap="round" />
<line x1="22" y1="4" x2="22" y2="10" stroke="#f6a701" strokeWidth="2" strokeLinecap="round" />
<line x1="9" y1="10" x2="13" y2="14" stroke="#f6a701" strokeWidth="2" strokeLinecap="round" />
<line x1="35" y1="10" x2="31" y2="14" stroke="#f6a701" strokeWidth="2" strokeLinecap="round" />
</svg>
);
}
function IconGrowthBars() {
return (
<svg width="44" height="40" viewBox="0 0 44 40" fill="none">
<line x1="4" y1="36" x2="40" y2="36" stroke="#f6a701" strokeWidth="2" strokeLinecap="round" />
<rect x="7" y="25" width="7" height="11" rx="1" stroke="#f6a701" strokeWidth="2" />
<rect x="18.5" y="16" width="7" height="20" rx="1" stroke="#f6a701" strokeWidth="2" />
<rect x="30" y="6" width="7" height="30" rx="1" stroke="#f6a701" strokeWidth="2" />
</svg>
);
}
function IconSunHigh() {
return (
<svg width="40" height="40" viewBox="0 0 40 40" fill="none">
<circle cx="20" cy="20" r="8" stroke="#f6a701" strokeWidth="2" />
<line x1="20" y1="2" x2="20" y2="7" stroke="#f6a701" strokeWidth="2" strokeLinecap="round" />
<line x1="20" y1="33" x2="20" y2="38" stroke="#f6a701" strokeWidth="2" strokeLinecap="round" />
<line x1="2" y1="20" x2="7" y2="20" stroke="#f6a701" strokeWidth="2" strokeLinecap="round" />
<line x1="33" y1="20" x2="38" y2="20" stroke="#f6a701" strokeWidth="2" strokeLinecap="round" />
<line x1="7" y1="7" x2="10.5" y2="10.5" stroke="#f6a701" strokeWidth="2" strokeLinecap="round" />
<line x1="29.5" y1="29.5" x2="33" y2="33" stroke="#f6a701" strokeWidth="2" strokeLinecap="round" />
<line x1="33" y1="7" x2="29.5" y2="10.5" stroke="#f6a701" strokeWidth="2" strokeLinecap="round" />
<line x1="10.5" y1="29.5" x2="7" y2="33" stroke="#f6a701" strokeWidth="2" strokeLinecap="round" />
</svg>
);
}
// 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>
);
}
const phases = [
{
icon: <IconSunrise />,
title: "Der Morgen: Ausprobieren",
desc: "Man probiert aus, lernt, macht Fehler, entdeckt Interessen. Man muss noch nicht alles perfekt können.",
},
{
icon: <IconGrowthBars />,
title: "Der Vormittag: Aufbauen",
desc: "Jetzt wird gebaut Gewohnheiten, Beziehungen, Fähigkeiten. Ein Leben, das sich nach dem eigenen anfühlt.",
},
{
icon: <IconSunHigh />,
title: "Der Nachmittag: Stärken",
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: <IconSunrise />,
title: "Der Abend: Weitergeben",
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>
<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>
{/* A timeline, not a data table — same "bg-bg-muted rounded card"
treatment the AGB sidebar and the blog author box use, but
shaped like an actual clock scale (dots on a line) since
that reads instantly, where a bare two-column table needed
a caption to explain itself. */}
<div className="bg-bg-muted rounded-xl px-6 py-10 sm:px-10 -mx-[var(--layout-padding-x)] sm:mx-0">
<div className="overflow-x-auto">
<div className="relative flex items-center min-w-[36rem] sm:min-w-0 px-2">
<div className="absolute left-0 right-0 h-px bg-border" aria-hidden />
{lebensuhrRows.map(([alter, uhrzeit]) => (
<div key={alter} className="relative flex-1 flex flex-col items-center gap-2">
<p className="text-body-sm font-semibold text-text-primary whitespace-nowrap">{uhrzeit}</p>
<span className="size-3 rounded-full bg-brand ring-4 ring-bg-muted" />
<p className="text-body-sm text-text-muted">{alter}</p>
</div>
))}
</div>
</div>
<p className="text-center text-body-sm text-text-muted mt-6">Alter in Jahren, bei 90 gelebten Jahren</p>
</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="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 />
</>
);
}