Sie war als "Referenz fuer den Einbau" ausgeschildert. Das trifft es nicht: Wer den Prototyp einbaut, liest Code und Doku und kann sich keine gerenderte Seite ansehen — die Datei-Pfade und DESIGN-SYSTEM.md tun diese Arbeit ohnehin. Nuetzlich ist die Seite fuer die Abstimmung mit Menschen: Auf den Analyse-Seiten sieht man von jedem Baustein immer nur den Zustand, den die Daten gerade hergeben. Neu ausgeschildert, und die fehlenden Zustaende ergaenzt: - Seitenzustaende (laedt / leer / Fehler). In HiveGrid sind alle fuenf VMState-Zustaende Pflicht, im Prototyp ist keiner davon je zu sehen, weil die Demo-Daten immer liefern. Gestaltet werden muessen sie trotzdem — "laedt", "nichts gefunden" und "kaputt" sind drei verschiedene Aussagen. - Dashboard-Kacheln: Begruessung, WidgetKachel, reservierte Kachel. Das Dashboard benutzt nicht ChartCard, sondern einen eigenen Rahmen; bisher war der in der Galerie gar nicht vertreten. Zwei Fehler dabei gefunden und behoben: - Die Regelliste nannte noch den dunklen Tooltip (#393939). Seit Carbon v11 ist er hell (#ffffff auf #161616); im Code war das laengst umgestellt, auf dieser Seite nicht. Eine Referenzseite, die eine ueberholte Regel behauptet, ist schlimmer als keine. - Die Abschnittstexte beginnen mit einem Dateipfad, und ein Pfad ist ein Wort ohne Trennstelle. Bei 375 px lief "features/dashboard/components/layout/SeitenZustand.tsx" neun Pixel ueber den Rand — von verify:layout gefunden. Die Regel zu den Kartenhoehen aus dem letzten Commit steht jetzt auch hier. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QPeZNwSeU7qG3RRCwaxEZX
447 lines
19 KiB
TypeScript
447 lines
19 KiB
TypeScript
"use client";
|
|
|
|
import React from "react";
|
|
import { PageHeader } from "../components/layout/PageHeader";
|
|
import { PageContainer } from "../components/layout/PageContainer";
|
|
import { KPICard } from "../components/cards/KPICard";
|
|
import { ChartCard } from "../components/cards/ChartCard";
|
|
import { AlertList } from "../components/cards/AlertList";
|
|
import { StatZeile } from "../components/cards/StatZeile";
|
|
import { AreaVerlauf } from "../components/charts/AreaVerlauf";
|
|
import { BalkenVertikal } from "../components/charts/BalkenVertikal";
|
|
import { BalkenHorizontal } from "../components/charts/BalkenHorizontal";
|
|
import { Donut } from "../components/charts/Donut";
|
|
import { Trichter } from "../components/charts/Trichter";
|
|
import { AuslastungsBalken } from "../components/charts/AuslastungsBalken";
|
|
import { ChartLeer } from "../components/charts/ChartLeer";
|
|
import { ChartLegende } from "../components/charts/ChartLegende";
|
|
import { AuftragBadge, RechnungBadge } from "../components/tables/StatusBadge";
|
|
import { SeitenZustand } from "../components/layout/SeitenZustand";
|
|
import { WidgetKachel } from "../components/dashboard/WidgetKachel";
|
|
import { ReservierteKachel } from "../components/dashboard/ReservierteKachel";
|
|
import { Begruessung } from "../components/dashboard/Begruessung";
|
|
import type { VMState } from "../view-models";
|
|
import {
|
|
KATEGORIE_FARBEN,
|
|
MAX_KATEGORIEN,
|
|
PRIMAER_FARBE,
|
|
STATUS_FARBEN,
|
|
VERGLEICH_FARBE,
|
|
} from "../utils/chartTheme";
|
|
import {
|
|
formatEuro,
|
|
formatEuroAchse,
|
|
formatEuroKompakt,
|
|
formatProzent,
|
|
formatZahl,
|
|
} from "../utils/formatters";
|
|
import { DATENSATZ_INFO } from "../data/seed";
|
|
|
|
/** Beispieldaten, damit die Galerie unabhängig von Filtern immer etwas zeigt. */
|
|
const BEISPIEL_REIHE = Array.from({ length: 12 }, (_, i) => ({
|
|
datum: `2026-${String(i + 1).padStart(2, "0")}`,
|
|
label: ["Jan", "Feb", "Mär", "Apr", "Mai", "Jun", "Jul", "Aug", "Sep", "Okt", "Nov", "Dez"][i],
|
|
value: [148, 162, 171, 158, 166, 149, 152, 161, 189, 205, 198, 176][i] * 1000,
|
|
vergleich: [131, 140, 152, 146, 151, 138, 141, 149, 168, 181, 176, 158][i] * 1000,
|
|
}));
|
|
|
|
const BEISPIEL_KATEGORIEN = [
|
|
{ name: "Heizung", value: 842_000 },
|
|
{ name: "Sanitär", value: 486_000 },
|
|
{ name: "Photovoltaik", value: 421_000 },
|
|
{ name: "Klima & Lüftung", value: 268_000 },
|
|
{ name: "Elektro", value: 194_000 },
|
|
{ name: "Sonstiges", value: 61_000 },
|
|
];
|
|
|
|
export function KomponentenSeite() {
|
|
return (
|
|
<>
|
|
<PageHeader
|
|
titel="Komponenten & Regeln"
|
|
beschreibung="Jeder Baustein einzeln und in allen Zuständen — die Seite zum Draufzeigen in der Abstimmung."
|
|
/>
|
|
|
|
<PageContainer>
|
|
<Abschnitt
|
|
titel="Warum diese Seite existiert"
|
|
text="Auf den Analyse-Seiten sieht man von jedem Baustein immer nur den einen Zustand, den die Daten gerade hergeben — die Kennzahlenkarte mit steigendem Trend, das Diagramm mit Werten darin. Die anderen Zustände existieren trotzdem und müssen mitgestaltet werden. Diese Seite zeigt sie alle nebeneinander, damit man in der Abstimmung darauf zeigen kann, ohne erst einen Filter zu suchen, der den passenden Fall herstellt."
|
|
/>
|
|
<Hinweis text="Diese Seite ist kein Produktfeature. Sie gehört weder zu Dashboard noch zu Analytics, steht in der Seitenleiste unter dem Trenner und wandert beim Einbau nicht mit. Für die Umsetzung selbst sind die Datei-Pfade unter jedem Abschnitt und docs/DESIGN-SYSTEM.md maßgeblich — beides steht im Repo und braucht diese Seite nicht." />
|
|
|
|
<ChartCard
|
|
id="komp-farben"
|
|
titel="Farbpalette"
|
|
untertitel="IBM Carbon, kategoriale Palette (14 Farben) — Reihenfolge nie umsortieren"
|
|
hinweis="Die Reihenfolge ist auf Unterscheidbarkeit optimiert. Farben immer von vorne vergeben, nicht nach Geschmack auswählen."
|
|
>
|
|
<div className="flex flex-col gap-4">
|
|
<div className="flex flex-wrap gap-2">
|
|
{KATEGORIE_FARBEN.map((farbe, index) => (
|
|
<div key={farbe} className="flex w-[104px] flex-col gap-1">
|
|
<span className="h-10 w-full rounded-md" style={{ background: farbe }} />
|
|
<span className="text-[11px] font-medium text-text-neutral-secondary">
|
|
{index + 1}. {farbe}
|
|
</span>
|
|
</div>
|
|
))}
|
|
</div>
|
|
<div className="flex flex-wrap gap-4 border-t border-solid border-border-default pt-3">
|
|
{Object.entries(STATUS_FARBEN).map(([name, farbe]) => (
|
|
<span key={name} className="flex items-center gap-2 text-[12px] text-text-neutral-secondary">
|
|
<span className="h-4 w-4 rounded" style={{ background: farbe }} />
|
|
Status „{name}“ · {farbe}
|
|
</span>
|
|
))}
|
|
</div>
|
|
<p className="text-[12px] leading-relaxed text-text-neutral-tertiary">
|
|
Kategorien nutzen die Carbon-Palette, Statusaussagen die Ampelfarben. Beides nie
|
|
mischen: eine grüne Kategorie neben einem grünen Positiv-Status ist nicht mehr lesbar.
|
|
Maximal {MAX_KATEGORIEN} Segmente je Chart, der Rest wird zu „Sonstige“
|
|
zusammengefasst.
|
|
</p>
|
|
</div>
|
|
</ChartCard>
|
|
|
|
<Abschnitt titel="Kennzahlen-Karten" text="features/dashboard/components/cards/KPICard.tsx" />
|
|
<div className="grid grid-cols-2 gap-4 lg:grid-cols-4">
|
|
<KPICard
|
|
label="Mit Trend und Sparkline"
|
|
wert={formatEuro(238_412)}
|
|
zusatz="Zahlungseingang im Zeitraum"
|
|
trend={{ wert: 12.4, richtung: "up" }}
|
|
icon="Euro"
|
|
akzent="positiv"
|
|
verlauf={[42, 48, 45, 52, 58, 55, 63, 71]}
|
|
/>
|
|
<KPICard
|
|
label="Negativer Trend"
|
|
wert={formatProzent(58.2, 0)}
|
|
zusatz="Abschlussquote"
|
|
trend={{ wert: 6.1, richtung: "down" }}
|
|
icon="Target"
|
|
akzent="negativ"
|
|
/>
|
|
<KPICard
|
|
label="Kleiner ist besser"
|
|
wert="34,2 Tage"
|
|
zusatz="Ø Zahlungsdauer"
|
|
trend={{ wert: 8.3, richtung: "down" }}
|
|
icon="Clock"
|
|
akzent="positiv"
|
|
richtungGut="negativ"
|
|
/>
|
|
<KPICard
|
|
label="Ohne Trend"
|
|
wert={formatZahl(1900)}
|
|
zusatz="Vorgänge im Datensatz"
|
|
icon="ClipboardList"
|
|
akzent="neutral"
|
|
/>
|
|
</div>
|
|
<Hinweis text="richtungGut='negativ' dreht die Farblogik um: Bei Zahlungsdauer oder Reaktionszeit ist ein Rückgang gut. Ohne diesen Schalter würde die Karte eine Verbesserung rot einfärben." />
|
|
|
|
<div className="grid grid-cols-1 gap-4 xl:grid-cols-3">
|
|
<ChartCard
|
|
id="komp-area"
|
|
titel="Flächendiagramm mit Vergleich"
|
|
untertitel="components/charts/AreaVerlauf.tsx — für Zeitverläufe"
|
|
className="xl:col-span-2"
|
|
legende={
|
|
<ChartLegende
|
|
eintraege={[
|
|
{ name: "Aktuell", farbe: PRIMAER_FARBE },
|
|
{ name: "Vorjahr", farbe: VERGLEICH_FARBE, gestrichelt: true },
|
|
]}
|
|
/>
|
|
}
|
|
>
|
|
<AreaVerlauf
|
|
daten={BEISPIEL_REIHE}
|
|
formatWert={formatEuroKompakt}
|
|
formatAchse={formatEuroAchse}
|
|
zeigeVergleich
|
|
hoehe={220}
|
|
/>
|
|
</ChartCard>
|
|
|
|
<ChartCard
|
|
id="komp-donut"
|
|
titel="Ringdiagramm"
|
|
untertitel="components/charts/Donut.tsx — für Anteile"
|
|
>
|
|
<Donut daten={BEISPIEL_KATEGORIEN} formatWert={formatEuroKompakt} hoehe={200} />
|
|
</ChartCard>
|
|
</div>
|
|
|
|
<div className="grid grid-cols-1 gap-4 lg:grid-cols-3">
|
|
<ChartCard
|
|
id="komp-balken"
|
|
titel="Säulendiagramm"
|
|
untertitel="components/charts/BalkenVertikal.tsx — Mengen mit Nulllinie"
|
|
>
|
|
<BalkenVertikal
|
|
daten={BEISPIEL_REIHE.map((p) => ({ label: p.label, value: p.value / 1000 }))}
|
|
formatWert={(w) => formatZahl(w)}
|
|
hoehe={200}
|
|
nurGanzzahlen
|
|
/>
|
|
</ChartCard>
|
|
|
|
<ChartCard
|
|
id="komp-hbalken"
|
|
titel="Balkendiagramm (liegend)"
|
|
untertitel="components/charts/BalkenHorizontal.tsx — Rangfolgen"
|
|
>
|
|
<BalkenHorizontal
|
|
daten={BEISPIEL_KATEGORIEN}
|
|
formatWert={formatEuroKompakt}
|
|
einfarbig={false}
|
|
/>
|
|
</ChartCard>
|
|
|
|
<ChartCard
|
|
id="komp-trichter"
|
|
titel="Trichter"
|
|
untertitel="components/charts/Trichter.tsx — Stufen mit Übergangsquote"
|
|
>
|
|
<Trichter
|
|
stufen={[
|
|
{ name: "Anfrage", value: 1900 },
|
|
{ name: "Vor-Aufmaß", value: 1420 },
|
|
{ name: "Angebot", value: 1180 },
|
|
{ name: "Beauftragt", value: 690 },
|
|
{ name: "Abgeschlossen", value: 612 },
|
|
]}
|
|
formatWert={(w) => formatZahl(w)}
|
|
/>
|
|
</ChartCard>
|
|
</div>
|
|
|
|
<div className="grid grid-cols-1 gap-4 lg:grid-cols-3">
|
|
<ChartCard
|
|
id="komp-auslastung"
|
|
titel="Auslastungsbalken"
|
|
untertitel="components/charts/AuslastungsBalken.tsx — mit Ampel und 100-%-Marke"
|
|
>
|
|
<AuslastungsBalken
|
|
zeilen={[
|
|
{ name: "Thomas Krause", wert: 104, zusatz: "Meister · Heizung" },
|
|
{ name: "Dennis Meyer", wert: 92, zusatz: "Monteur · Sanitär" },
|
|
{ name: "Maike Schmidt", wert: 78, zusatz: "Monteur · Photovoltaik" },
|
|
{ name: "Kevin Wolf", wert: 54, zusatz: "Auszubildender · Elektro" },
|
|
]}
|
|
/>
|
|
</ChartCard>
|
|
|
|
<ChartCard
|
|
id="komp-alerts"
|
|
titel="Handlungsbedarf"
|
|
untertitel="components/cards/AlertList.tsx — nach Dringlichkeit sortiert"
|
|
>
|
|
<AlertList
|
|
eintraege={[
|
|
{
|
|
id: "a",
|
|
text: "25 überfällige Rechnungen",
|
|
detail: "Zahlungsziel überschritten",
|
|
betrag: 96_194,
|
|
aktion: "Mahnlauf starten",
|
|
art: "kritisch",
|
|
},
|
|
{
|
|
id: "b",
|
|
text: "32 Aufträge über Termin",
|
|
detail: "Ältester seit 99 Tagen fällig",
|
|
betrag: 148_600,
|
|
aktion: "Termine neu planen",
|
|
art: "warnung",
|
|
},
|
|
{
|
|
id: "c",
|
|
text: "23 Förderanträge in Bearbeitung",
|
|
detail: "Bescheid ausstehend",
|
|
betrag: 116_100,
|
|
aktion: "Status prüfen",
|
|
art: "hinweis",
|
|
},
|
|
]}
|
|
/>
|
|
</ChartCard>
|
|
|
|
<ChartCard
|
|
id="komp-leer"
|
|
titel="Leerzustand"
|
|
untertitel="components/charts/ChartLeer.tsx — greift, wenn Filter alles wegschneiden"
|
|
>
|
|
<ChartLeer hoehe={180} />
|
|
</ChartCard>
|
|
</div>
|
|
|
|
<Abschnitt
|
|
titel="Seitenzustände"
|
|
text="features/dashboard/components/layout/SeitenZustand.tsx — die vier Zustände außer „fertig“. Sie sind in HiveGrid Pflicht (VMState: idle · loading · ready · empty · error) und im laufenden Prototyp nie zu sehen, weil die Demo-Daten immer liefern. Gestaltet werden müssen sie trotzdem: „lädt“, „nichts gefunden“ und „kaputt“ sind drei verschiedene Aussagen und dürfen nicht gleich aussehen."
|
|
/>
|
|
<div className="grid grid-cols-1 gap-4 xl:grid-cols-3">
|
|
{([
|
|
["Lädt", { status: "loading" } as VMState<unknown>],
|
|
["Leer — Filter schneiden alles weg", { status: "empty" } as VMState<unknown>],
|
|
[
|
|
"Fehler",
|
|
{
|
|
status: "error",
|
|
error: { messageKey: "Zeitüberschreitung beim Laden der Kennzahlen" },
|
|
} as VMState<unknown>,
|
|
],
|
|
] as const).map(([titel, vm]) => (
|
|
<div key={titel} className="flex flex-col gap-2">
|
|
<span className="text-[12px] font-medium text-text-neutral-tertiary">{titel}</span>
|
|
{/* -mx-4: SeitenZustand bringt seinen eigenen Seitenrand mit, weil
|
|
er im Normalfall die ganze Seite füllt. Hier steht er in einer
|
|
Rasterspalte und braucht ihn nicht.
|
|
|
|
Ohne zusätzlichen Rahmen: Die Komponente hat bereits eine
|
|
gestrichelte Kante. Ein Kasten darum wäre ein zweiter Rahmen
|
|
und zeigte den Baustein anders, als er in der Anwendung
|
|
aussieht. */}
|
|
<div className="-mx-4 sm:-mx-6">
|
|
<SeitenZustand vm={vm} />
|
|
</div>
|
|
</div>
|
|
))}
|
|
</div>
|
|
|
|
<Abschnitt
|
|
titel="Dashboard-Kacheln"
|
|
text="features/dashboard/components/dashboard/ — das Dashboard benutzt nicht ChartCard, sondern einen eigenen Kachelrahmen. Gleiche Kante, gleiche Abstände, aber ohne das ⋯-Menü von Analytics; dafür mit Domänen-Icon, eigenem Zeitraum und Absprung. Der Grund steht in docs/SCOPE-ANALYTICS-DASHBOARD.md: In Analytics gilt ein Filter für alle Karten, im Dashboard trägt jede Kachel ihren eigenen."
|
|
/>
|
|
{/* Wie bei den Seitenzuständen: Die Begrüßung trägt ihren eigenen
|
|
Seitenrand, weil sie im Dashboard direkt auf der Seite steht. In der
|
|
Galerie liegt sie schon im Innenabstand des Containers und wäre
|
|
sonst doppelt eingerückt. */}
|
|
<div className="-mx-4 sm:-mx-6">
|
|
<Begruessung
|
|
anrede="Guten Tag"
|
|
name="Dejan"
|
|
datum="Donnerstag, 30. Juli"
|
|
rolle="Geschäftsführung"
|
|
lage="2 Punkte brauchen heute Ihre Aufmerksamkeit."
|
|
kritisch
|
|
/>
|
|
</div>
|
|
<div className="grid grid-cols-1 gap-4 lg:grid-cols-3">
|
|
<WidgetKachel
|
|
titel="Umsatz nach Gewerk"
|
|
untertitel="Zahlungseingang der letzten 30 Tage"
|
|
hinweis="Der Zeitraum steht im Kopf, weil es auf dem Dashboard keinen seitenweiten Filter gibt."
|
|
domaene="finance"
|
|
zeitraum="30_tage"
|
|
absprung="/analytics/finanzen"
|
|
className="lg:col-span-2"
|
|
>
|
|
<BalkenHorizontal
|
|
daten={BEISPIEL_KATEGORIEN.slice(0, 5)}
|
|
formatWert={formatEuroKompakt}
|
|
einfarbig={false}
|
|
/>
|
|
</WidgetKachel>
|
|
|
|
<ReservierteKachel
|
|
bereich={{
|
|
key: "hr",
|
|
domaene: "hr",
|
|
titel: "HR-Anträge",
|
|
beschreibung: "Offene Urlaubs- und Zeitkorrekturanträge.",
|
|
icon: "UserCheck",
|
|
quelle: "HR-Hub",
|
|
}}
|
|
/>
|
|
</div>
|
|
<Hinweis text="Die reservierte Kachel zeigt bewusst keine Zahl. „2 neue Anträge“ aus erfundenen Daten liest sich in einer Abnahme wie eine fertige Funktion — und irgendwann fragt jemand, warum die Zahl nie hochzählt. Die gestrichelte Kante sagt dasselbe ehrlicher: Hier kommt etwas hin, die Fläche ist dafür da." />
|
|
|
|
<ChartCard
|
|
id="komp-badges"
|
|
titel="Status-Kennzeichnung"
|
|
untertitel="components/tables/StatusBadge.tsx"
|
|
>
|
|
<div className="flex flex-col gap-4">
|
|
<div className="flex flex-wrap items-center gap-2">
|
|
<span className="w-24 text-[12px] text-text-neutral-tertiary">Auftrag</span>
|
|
<AuftragBadge status="anfrage" />
|
|
<AuftragBadge status="aufmass" />
|
|
<AuftragBadge status="angebot" />
|
|
<AuftragBadge status="beauftragt" />
|
|
<AuftragBadge status="in_arbeit" />
|
|
<AuftragBadge status="abgeschlossen" />
|
|
<AuftragBadge status="verloren" />
|
|
</div>
|
|
<div className="flex flex-wrap items-center gap-2">
|
|
<span className="w-24 text-[12px] text-text-neutral-tertiary">Rechnung</span>
|
|
<RechnungBadge status="entwurf" />
|
|
<RechnungBadge status="gestellt" />
|
|
<RechnungBadge status="bezahlt" />
|
|
<RechnungBadge status="ueberfaellig" />
|
|
</div>
|
|
<StatZeile
|
|
eintraege={[
|
|
{ label: "Aufträge", wert: formatZahl(DATENSATZ_INFO.auftraege), hinweis: "im Demo-Datensatz" },
|
|
{ label: "Rechnungen", wert: formatZahl(DATENSATZ_INFO.rechnungen) },
|
|
{ label: "Kunden", wert: formatZahl(DATENSATZ_INFO.kunden) },
|
|
{ label: "Zeiteinträge", wert: formatZahl(DATENSATZ_INFO.zeiteintraege) },
|
|
]}
|
|
/>
|
|
</div>
|
|
</ChartCard>
|
|
|
|
<ChartCard
|
|
id="komp-regeln"
|
|
titel="Regeln, die beim Einbau erhalten bleiben sollten"
|
|
untertitel="Ausführlich in docs/DESIGN-SYSTEM.md"
|
|
>
|
|
<ul className="flex flex-col gap-2.5">
|
|
{[
|
|
"Nur horizontale Gridlines in #e0e0e0. Vertikale Linien lenken vom Verlauf ab.",
|
|
"Achsenbeschriftungen 12 px in #525252, keine Tick-Marks, Achsenlinie #8d8d8d.",
|
|
"Ein Tooltip für alle Charts: weiße Fläche #ffffff, Text #161616, Schatten statt Rahmen — seit Carbon v11 hell, nicht mehr dunkel.",
|
|
"Maximal fünf Kategorien je Chart, alles darüber wird zu „Sonstige“ zusammengefasst.",
|
|
"Balkenabstand mindestens halbe Balkenbreite; Balken nie breiter als 48 px.",
|
|
"Zahlen rechtsbündig und in Tabellenziffern, Text linksbündig.",
|
|
"Karten: 16 px Innenabstand, 16 px Abstand zwischen Karten — innen nie größer als außen.",
|
|
"Jede Karte braucht einen Leerzustand. Filter können jedes Chart leer laufen lassen.",
|
|
"Karten einer Zeile nur strecken, wenn sie dieselbe Bauart haben. Ein Diagramm mit fester Höhe neben einer Balkenliste bleibt oben bündig — sonst wird aus einer Karte mit einem Balken eine 427 px hohe Fläche.",
|
|
].map((regel) => (
|
|
<li key={regel} className="flex gap-2.5 text-[13px] leading-relaxed text-text-neutral-secondary">
|
|
<span className="mt-1.5 h-1.5 w-1.5 flex-none rounded-full bg-neutral-400" />
|
|
{regel}
|
|
</li>
|
|
))}
|
|
</ul>
|
|
</ChartCard>
|
|
</PageContainer>
|
|
</>
|
|
);
|
|
}
|
|
|
|
function Abschnitt({ titel, text }: { titel: string; text: string }) {
|
|
return (
|
|
<div className="flex flex-col gap-1 pt-2">
|
|
<h2 className="text-[15px] font-semibold text-text-neutral-primary">{titel}</h2>
|
|
{/* break-words: Diese Absätze beginnen mit einem Dateipfad, und ein Pfad
|
|
ist ein einziges Wort ohne Trennstelle. Bei 375 px lief
|
|
"features/dashboard/components/layout/SeitenZustand.tsx" neun Pixel
|
|
über den Rand. */}
|
|
<p className="max-w-3xl break-words text-[13px] leading-relaxed text-text-neutral-tertiary">
|
|
{text}
|
|
</p>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
function Hinweis({ text }: { text: string }) {
|
|
return (
|
|
<p className="rounded-md border border-solid border-border-default bg-white px-3 py-2 text-[12px] leading-relaxed text-text-neutral-secondary">
|
|
{text}
|
|
</p>
|
|
);
|
|
}
|