af5956848b
The four phases (Morgen/Vormittag/Nachmittag/Abend) had no explicit tie back to age — readers had to infer it themselves from the clock metaphor. Added an approximate age range per phase, using the same age/90 = time/24 scale as the table (Vormittag ends exactly at 12:00 = age 45, which conveniently lines up with "Mittag").
392 lines
18 KiB
TypeScript
392 lines
18 KiB
TypeScript
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>
|
||
);
|
||
}
|
||
|
||
// 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: <IconSunrise />,
|
||
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: <IconGrowthBars />,
|
||
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: <IconSunHigh />,
|
||
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: <IconSunrise />,
|
||
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>
|
||
<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>
|
||
|
||
{/* Decorative companion to the table below, not a replacement for
|
||
it (a version that tried to carry the actual Alter/Uhrzeit
|
||
pairs on its own read ambiguous — see the table's own
|
||
comment) — just the 8 ages plotted at their proportional
|
||
clock position, so the "24 Stunden" framing above has an
|
||
actual clock to look at. Coordinates are hand-computed
|
||
(evenly spaced every 40°, since age/90 and time/24 are the
|
||
same proportion), not derived from lebensuhrRows — if the
|
||
rows above ever change, these need updating too. */}
|
||
<div className="flex justify-center py-2">
|
||
<svg viewBox="0 0 250 250" className="w-full max-w-[16rem] h-auto" aria-hidden="true">
|
||
<circle cx="125" cy="125" r="100" stroke="var(--color-border)" strokeWidth="1.5" fill="none" />
|
||
{[0, 30, 60, 90, 120, 150, 180, 210, 240, 270, 300, 330].map((deg) => {
|
||
const rad = (deg * Math.PI) / 180;
|
||
const x1 = 125 + 92 * Math.cos(rad), y1 = 125 + 92 * Math.sin(rad);
|
||
const x2 = 125 + 100 * Math.cos(rad), y2 = 125 + 100 * Math.sin(rad);
|
||
return <line key={deg} x1={x1} y1={y1} x2={x2} y2={y2} stroke="var(--color-border)" strokeWidth="1.5" />;
|
||
})}
|
||
{([
|
||
[10, 175.1, 65.2, 200.8, 34.6, "start"],
|
||
[20, 201.8, 111.5, 241.2, 104.5, "start"],
|
||
[30, 192.5, 164.0, 227.2, 184.0, "start"],
|
||
[40, 151.7, 198.3, 165.4, 235.9, "start"],
|
||
[50, 98.3, 198.3, 84.6, 235.9, "end"],
|
||
[60, 57.5, 164.0, 22.8, 184.0, "end"],
|
||
[70, 48.2, 111.5, 8.8, 104.5, "end"],
|
||
[80, 74.9, 65.2, 49.2, 34.6, "end"],
|
||
] as [number, number, number, number, number, "start" | "end"][]).map(([age, dx, dy, lx, ly, anchor]) => (
|
||
<g key={age}>
|
||
<line x1={dx} y1={dy} x2={lx} y2={ly} stroke="var(--color-border)" strokeWidth="1" />
|
||
<circle cx={dx} cy={dy} r="4" fill="var(--color-brand)" />
|
||
<text
|
||
x={lx}
|
||
y={ly}
|
||
textAnchor={anchor}
|
||
dominantBaseline="middle"
|
||
className="fill-text-muted"
|
||
style={{ fontSize: 12, fontWeight: 600 }}
|
||
>
|
||
{age}
|
||
</text>
|
||
</g>
|
||
))}
|
||
<text x="125" y="118" textAnchor="middle" className="fill-text-primary" style={{ fontFamily: "var(--font-caveat)", fontSize: 24 }}>
|
||
dein
|
||
</text>
|
||
<text x="125" y="142" textAnchor="middle" className="fill-text-primary" style={{ fontFamily: "var(--font-caveat)", fontSize: 24 }}>
|
||
Leben
|
||
</text>
|
||
</svg>
|
||
</div>
|
||
|
||
{/* 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 />
|
||
</>
|
||
);
|
||
}
|