467 Stellen. Nicht durch einen anderen Strich ersetzt, sondern durch das
Satzzeichen, das an der jeweiligen Stelle richtig ist: Doppelpunkt, wo eine
Erlaeuterung folgt; Komma, wo der Satz weiterlaeuft; Punkt, wo zwei
Hauptsaetze aneinanderstiessen. Ein Halbgeviertstrich waere nur derselbe
Griff mit kuerzerem Strich gewesen.
Regelbasiert ersetzt und danach nachgeprueft, weil eine Regel allein nicht
reicht. Gefunden und einzeln korrigiert:
- Eingeschobene Saetze mit Strichpaar. Nur der oeffnende Strich passte ins
Muster, der schliessende blieb als "—," stehen. Drei Stellen, jetzt mit
Klammern oder als eigener Satz.
- Doppelte Doppelpunkte, wo beide Striche eines Paars zu Doppelpunkten wurden
("Globale Regeln: Schrift, Groessen, Abstaende: kommen aus HiveGrid").
Sieben Stellen in Doku und Oberflaeche, jetzt in Klammern.
- Pfade, denen ein Komma statt eines Doppelpunkts folgte.
- Ausgerichtete Kommentartabellen, in denen der Strich eine Spalte war.
Nicht angefasst: drei Geviertstriche, die keine Prosa sind, sondern
Tabellenplatzhalter fuer "kein Wert" (Trichter, Auftraege, Kunden). Dort ist
der Strich die Angabe selbst; ihn zu entfernen liesse leere Zellen zurueck.
tsc, lint, build, verify:carbon und verify:layout laufen sauber.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QPeZNwSeU7qG3RRCwaxEZX
86 lines
3.3 KiB
TypeScript
86 lines
3.3 KiB
TypeScript
"use client";
|
|
|
|
import React from "react";
|
|
import { FeatherDownload, FeatherRefreshCw, FeatherShare2 } from "@subframe/core";
|
|
import { useToast } from "../../context/ToastContext";
|
|
|
|
/**
|
|
* Kopf einer Analyse-Seite: Titel, Einordnung, Seitenaktionen.
|
|
* Die Aktionen sind im Prototyp bewusst folgenlos (Toast statt Export),
|
|
* siehe HANDOVER.md, Abschnitt "Was noch Logik braucht".
|
|
*/
|
|
export function PageHeader({
|
|
titel,
|
|
beschreibung,
|
|
aktionen,
|
|
/**
|
|
* Aktualisieren, Export und Teilen. Auf Seiten ohne Inhalt gibt es nichts zu
|
|
* aktualisieren oder zu exportieren, dort schaltet man sie ab, statt
|
|
* Schaltflächen anzubieten, die ins Leere greifen.
|
|
*/
|
|
standardAktionen = true,
|
|
}: {
|
|
titel: string;
|
|
beschreibung: string;
|
|
aktionen?: React.ReactNode;
|
|
standardAktionen?: boolean;
|
|
}) {
|
|
const { zeigeToast } = useToast();
|
|
|
|
/**
|
|
* Unter `sm` tragen die beiden beschrifteten Knöpfe nur ihr Icon.
|
|
* Nebeneinander brauchen "Aktualisieren" und "Export" rund 240 px. Das ist
|
|
* mehr, als bei 375 px neben dem Titel überhaupt vorhanden ist. Die Beschriftung
|
|
* entfällt, `aria-label` bleibt: Für die Sprachausgabe ändert sich nichts.
|
|
*/
|
|
const knopf =
|
|
"flex h-9 w-9 flex-none items-center justify-center gap-2 rounded-md border border-solid " +
|
|
"border-border-default bg-white text-[13px] font-medium text-text-neutral-secondary " +
|
|
"hover:bg-neutral-50 sm:w-auto sm:px-3";
|
|
|
|
return (
|
|
// Unter `sm` untereinander: Titel und Aktionen nebeneinander lassen für den
|
|
// Titel keine 130 px übrig, er zerfiele in vier Zeilen, während die Knöpfe
|
|
// aus dem Bild laufen.
|
|
<div className="flex flex-col items-stretch gap-4 px-4 pb-6 pt-6 sm:flex-row sm:flex-wrap sm:items-start sm:justify-between sm:px-6">
|
|
<div className="flex min-w-0 flex-col gap-0">
|
|
<h1 className="break-words text-[22px] font-semibold leading-tight tracking-[-0.02em] text-text-neutral-primary">
|
|
{titel}
|
|
</h1>
|
|
<p className="text-[13px] leading-relaxed text-text-neutral-tertiary">{beschreibung}</p>
|
|
</div>
|
|
|
|
<div className="dv-no-print flex flex-none items-center gap-2">
|
|
{aktionen}
|
|
{standardAktionen ? (
|
|
<>
|
|
<button
|
|
onClick={() => zeigeToast("Ansicht aktualisiert", "Demo-Daten, Stichtag 30.07.2026")}
|
|
className={knopf}
|
|
aria-label="Ansicht aktualisieren"
|
|
>
|
|
<FeatherRefreshCw className="text-[15px]" />
|
|
<span className="hidden sm:inline">Aktualisieren</span>
|
|
</button>
|
|
<button
|
|
onClick={() => zeigeToast("Export vorgemerkt", "PDF/CSV folgt in der Umsetzung")}
|
|
className={knopf}
|
|
aria-label="Ansicht exportieren"
|
|
>
|
|
<FeatherDownload className="text-[15px]" />
|
|
<span className="hidden sm:inline">Export</span>
|
|
</button>
|
|
<button
|
|
onClick={() => zeigeToast("Link kopiert", "Teilen wird serverseitig umgesetzt")}
|
|
className="flex h-9 w-9 flex-none items-center justify-center rounded-md border border-solid border-border-default bg-white text-text-neutral-tertiary hover:bg-neutral-50"
|
|
aria-label="Ansicht teilen"
|
|
>
|
|
<FeatherShare2 className="text-[15px]" />
|
|
</button>
|
|
</>
|
|
) : null}
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|