fix(oberflaeche): Kopfleiste einzeilig halten, Demo-Uhr feststellen

Zwei Mängel, die erst in den aufgenommenen Bildern auffielen.

Auf Handybreite brach die Kopfleiste um und drängte den Namen der
Anwendung in die zweite Zeile, mitten zwischen die Menüpunkte. Sie bleibt
jetzt auf allen Breiten einzeilig; wird es eng, scrollt die Navigation
waagerecht.

Das Tagesdatum auf der Startseite wird serverseitig gerendert, weshalb
Playwrights Uhr nicht griff — die Bilder hätten sich täglich geändert. In
der Screenshot-Instanz (DEMO_MODUS=true) steht die Uhr jetzt fest. Reine
Funktionen bekommen den Zeitpunkt weiterhin als Parameter; src/server/
zeitgeber.ts ist die eine Stelle, an der er entsteht.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Florian Wilde
2026-09-10 14:36:35 +02:00
co-authored by Claude Opus 5
parent cf28ec19f5
commit 6d04bc2c1c
4 changed files with 154 additions and 7 deletions
+3 -2
View File
@@ -10,10 +10,11 @@ import { wochenKapazitaet } from '@/lib/bereich'
import { alsDatum, alsDauer } from '@/lib/zeit'
import { verlangeAnmeldung } from '@/server/berechtigung'
import { db } from '@/server/db'
import { jetzt } from '@/server/zeitgeber'
export default async function StartSeite() {
const benutzer = await verlangeAnmeldung('/')
const jetzt = new Date()
const heute = jetzt()
const bereiche = await db.bereich.findMany({
where: { aktiv: true },
@@ -26,7 +27,7 @@ export default async function StartSeite() {
<div className="flex flex-col gap-8">
<header>
<h1 className="text-2xl font-semibold tracking-tight">Guten Tag, {anrede}</h1>
<p className="text-gedaempft-vordergrund mt-1 text-sm">{alsDatum(jetzt)}</p>
<p className="text-gedaempft-vordergrund mt-1 text-sm">{alsDatum(heute)}</p>
</header>
<section className="flex flex-col gap-4">
+13 -5
View File
@@ -35,12 +35,20 @@ export function Kopfleiste({
return (
<header className="border-rand bg-karte border-b">
<div className="mx-auto flex w-full max-w-5xl flex-wrap items-center gap-x-6 gap-y-3 px-4 py-3">
<Link href="/" className="text-base font-semibold tracking-tight">
{/*
Bewusst eine einzige Zeile auf allen Breiten: Wird es eng, scrollt die
Navigation waagerecht, statt umzubrechen und den Namen der Anwendung in
die zweite Zeile zu drängen.
*/}
<div className="mx-auto flex w-full max-w-5xl items-center gap-3 px-4 py-3 sm:gap-6">
<Link href="/" className="shrink-0 text-base font-semibold tracking-tight">
Planer
</Link>
<nav aria-label="Hauptnavigation" className="flex flex-1 flex-wrap gap-1">
<nav
aria-label="Hauptnavigation"
className="flex min-w-0 flex-1 gap-1 overflow-x-auto"
>
{sichtbar.map((eintrag) => {
const aktiv =
eintrag.pfad === '/' ? pfad === '/' : pfad.startsWith(eintrag.pfad)
@@ -50,7 +58,7 @@ export function Kopfleiste({
href={eintrag.pfad}
aria-current={aktiv ? 'page' : undefined}
className={cn(
'rounded-md px-3 py-1.5 text-sm transition-colors',
'shrink-0 rounded-md px-3 py-1.5 text-sm whitespace-nowrap transition-colors',
aktiv
? 'bg-gedaempft text-vordergrund font-medium'
: 'text-gedaempft-vordergrund hover:bg-gedaempft hover:text-vordergrund',
@@ -65,7 +73,7 @@ export function Kopfleiste({
})}
</nav>
<div className="flex items-center gap-1">
<div className="flex shrink-0 items-center gap-1">
<FarbschemaKnopf />
<span
className="text-gedaempft-vordergrund hidden text-xs sm:inline"
+20
View File
@@ -0,0 +1,20 @@
import 'server-only'
import { umgebung } from '@/server/umgebung'
/**
* Die aktuelle Zeit — für alles, was serverseitig gerendert wird.
*
* Reine Funktionen in src/lib bekommen den Zeitpunkt weiterhin als Parameter.
* Hier steht nur die eine Stelle, an der er entsteht.
*
* In der Screenshot-Instanz (DEMO_MODUS=true) steht die Uhr fest. Sonst würde
* sich in jedem Bild das Tagesdatum ändern und die Bilder wären bei jedem Lauf
* neu, ohne dass sich etwas Sichtbares geändert hätte.
*/
/** Dienstag, 17. März 2026, 09:20 Uhr in Europe/Berlin. */
export const DEMO_ZEITPUNKT = new Date('2026-03-17T08:20:00.000Z')
export function jetzt(): Date {
return umgebung().DEMO_MODUS ? DEMO_ZEITPUNKT : new Date()
}