Kundenportal-Bühne: Gruppe „Weitere Funktionen“, Unterpunkte als Stichpunkte

Wunsch des Inhabers: Die drei Funktionen heißen als Gruppe „Weitere Funktionen“ und
beschreiben sich in drei Stichpunkten statt in einem Satz (Liste der Bühne und Karten
der Wisch-Reihe). Der Bedienhinweis der Heatmap („Zeigen Sie mit der Maus …“ bzw.
„Tippen Sie …“) steht jetzt im Hinweis unter dem MacBook und in der Karte.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
rootandClaude Opus 5.5 committed 2026-10-04 15:02:04 +00:00
1 parent 72275db9fa
commit f0bced164b
4 files changed
+131 -36

No files matched your search

+53 -14
View File
@@ -55,9 +55,12 @@ type DemoArt = "termin" | "heatmap" | "pinnwand";
type Funktion = {
id: string;
titel: string;
unterschrift: string;
/** Abweichende Unterschrift in der Wisch-Reihe (dort gibt es keine Maus). */
unterschriftHandy?: string;
/** Ein Satz unter dem Titel (Portal-Stationen); die Funktionen haben stattdessen Stichpunkte. */
unterschrift?: string;
/** Stichpunkte unter dem Titel (die drei Funktionen, Wunsch des Inhabers 2026-10-04). */
stichpunkte?: string[];
/** Bedienhinweis zur Live-Demo, je nachdem, ob es eine Maus gibt (nur Website-Analyse). */
bedienhinweis?: { maus: string; tippen: string };
/** Desktop-Bild; Demo-Stationen zeigen stattdessen die Website, "Als App" hat keines (dort blendet das Fenster aus). */
desktop?: { name: string; alt: string };
handy: { name: string; alt: string };
@@ -116,7 +119,7 @@ const FUNKTIONEN: Funktion[] = [
{
id: "terminplaner",
titel: "Terminplaner",
unterschrift: "Gäste buchen auf Ihrer Website – die Termine sehen Sie im Portal und auf Wunsch im Google Kalender.",
stichpunkte: ["Gäste buchen direkt auf Ihrer Website", "Termine und Anfragen im Portal", "Kalender-Abo, z. B. Google Kalender"],
demo: "termin",
adresse: "salon-schnittstelle.example",
beschreibung:
@@ -131,8 +134,8 @@ const FUNKTIONEN: Funktion[] = [
{
id: "website-analyse",
titel: "Website-Analyse",
unterschrift: "Sehen Sie, wohin Ihre Besucher klicken. Zeigen Sie mit der Maus auf die Seite.",
unterschriftHandy: "Sehen Sie, wohin Ihre Besucher klicken. Tippen Sie auf eine Stelle der Seite.",
stichpunkte: ["Heatmap: wohin Besucher klicken", "Aufrufe, Herkunft und Geräte", "Im Wartungs-Abo enthalten"],
bedienhinweis: { maus: "Zeigen Sie mit der Maus auf die Seite.", tippen: "Tippen Sie auf eine Stelle der Seite." },
demo: "heatmap",
adresse: "boulderhalle-ueberhang.example",
beschreibung:
@@ -145,7 +148,7 @@ const FUNKTIONEN: Funktion[] = [
{
id: "news-pinnwand",
titel: "News-Pinnwand",
unterschrift: "Neuigkeiten mit Text und Foto, vom Handy direkt auf Ihre Website.",
stichpunkte: ["Text und Foto, vom Handy aus", "Hängt direkt auf Ihrer Website", "Laufzeit je Zettel wählbar"],
demo: "pinnwand",
adresse: "musterbach.example",
beschreibung: "Beispiel-Website einer Ortsgemeinde mit einer Pinnwand, an der ein neuer Zettel aufgehängt wird",
@@ -171,7 +174,7 @@ const LETZTER = FUNKTIONEN.length - 1;
/** Stationen vor "Als App": normale Schritte und längere Demo-Schritte (bestimmen die Scrollstrecke der Hülle). */
const ANZAHL_DEMO = FUNKTIONEN.filter((f) => f.demo).length;
const ANZAHL_NORMAL = LETZTER - ANZAHL_DEMO;
const GRUPPE_TITEL = "Funktionen zum Dazubuchen";
const GRUPPE_TITEL = "Weitere Funktionen";
// ── Demos (eigener Chunk, erst geladen, wenn die Bühne die Station fast erreicht) ──────────────────────
@@ -214,6 +217,36 @@ const INERT = (parseInt(version, 10) >= 19 ? { inert: true } : { inert: "" }) as
const beispielText = (f: Funktion) => `Erfundenes Beispiel · ${f.adresse}`;
/**
* Unterschrift einer Station: ein Satz oder Stichpunkte. In der Liste steckt sie in einem <button> (nur Phrasing-Inhalt
* erlaubt), darum sind die Stichpunkte dort Blöcke aus <span>; das versteckte Komma trennt sie für Screenreader.
*/
const Unterschrift = ({ f }: { f: Funktion }) =>
f.stichpunkte ? (
<>
{f.stichpunkte.map((p, i) => (
<span key={p} className="kp-stichpunkt">
{p}
{i < f.stichpunkte!.length - 1 ? <span className="sr-only">, </span> : null}
</span>
))}
</>
) : (
<>{f.unterschrift}</>
);
/** Unterschrift in den Karten der Wisch-Reihe (außerhalb eines Knopfs): Satz oder echte Liste. */
const KartenUnterschrift = ({ f }: { f: Funktion }) =>
f.stichpunkte ? (
<ul className="wk-muted kp-karte__punkte">
{f.stichpunkte.map((p) => (
<li key={p}>{p}</li>
))}
</ul>
) : (
<p className="wk-muted kp-karte__text">{f.unterschrift}</p>
);
const SCHRITTE = [
{ nr: 1, text: "Kennenlernen" },
{ nr: 2, text: "Angebot mit Preis" },
@@ -400,8 +433,9 @@ const Buehne = () => {
>
<span className="kp-eintrag__punkt" aria-hidden="true" />
<span className="kp-eintrag__titel">{f.titel}</span>
{/* ohne Maus (Tablet) heißt es „Tippen Sie“ statt „Zeigen Sie mit der Maus“ */}
<span className="kp-eintrag__text">{!fein && f.unterschriftHandy ? f.unterschriftHandy : f.unterschrift}</span>
<span className="kp-eintrag__text">
<Unterschrift f={f} />
</span>
</button>
);
if (!f.demo) return <li key={f.id}>{eintrag}</li>;
@@ -484,7 +518,11 @@ const Buehne = () => {
data-an={f.demo === aktivDemo ? "ja" : "nein"}
aria-hidden={f.demo !== aktivDemo || undefined}
>
{beispielText(f)}
{/* Website-Analyse: statt der Adresse (steht in der Safari-Leiste) der Bedienhinweis, damit es eine Zeile bleibt;
ohne Maus (Tablet quer) heißt es „Tippen Sie“ statt „Zeigen Sie mit der Maus“ */}
{f.bedienhinweis
? `Erfundenes Beispiel · ${fein ? f.bedienhinweis.maus : f.bedienhinweis.tippen}`
: beispielText(f)}
</p>
))}
</div>
@@ -543,7 +581,7 @@ const LangeKarte = ({ f }: { f: Funktion }) => {
</div>
</HandyRahmen>
<h3 className="wk-h3 kp-karte__titel">{f.titel}</h3>
<p className="wk-muted kp-karte__text">{f.unterschrift}</p>
<KartenUnterschrift f={f} />
</div>
);
};
@@ -569,8 +607,9 @@ const DemoKarteRahmen = ({
</HandyRahmen>
</div>
<h3 className="wk-h3 kp-karte__titel">{f.titel}</h3>
<p className="wk-muted kp-karte__text">{f.unterschriftHandy ?? f.unterschrift}</p>
<KartenUnterschrift f={f} />
<p className="kp-karte__beispiel">{beispielText(f)}</p>
{f.bedienhinweis ? <p className="kp-karte__bedienen">{f.bedienhinweis.tippen}</p> : null}
{nachher}
</div>
);
@@ -650,7 +689,7 @@ const HandyReihe = () => (
<div key={f.id} className="kp-karte">
<HandyRahmen className="kp-karte__handy" bild={handyBild(f.handy.name, f.handy.alt, "250px")} />
<h3 className="wk-h3 kp-karte__titel">{f.titel}</h3>
<p className="wk-muted kp-karte__text">{f.unterschrift}</p>
<KartenUnterschrift f={f} />
</div>
);
})}
+48 -1
View File
@@ -114,6 +114,22 @@
.kp-eintrag[aria-current="step"] .kp-eintrag__titel {
color: var(--fg);
}
/* Stichpunkte der drei Funktionen: je Punkt eine Zeile mit kleinem runden Punkt davor */
.kp-stichpunkt {
position: relative;
display: block;
padding-left: 0.95em;
}
.kp-stichpunkt::before {
content: "";
position: absolute;
left: 0.15em;
top: calc(0.7em - 2px);
width: 4px;
height: 4px;
border-radius: 50%;
background: currentColor;
}
/* kleiner roter Punkt als Marker der aktiven Funktion (hängt im Rand links vom Text) */
.kp-eintrag__punkt {
position: absolute;
@@ -178,7 +194,7 @@
}
}
/* Gruppe "Funktionen zum Dazubuchen": die drei Demo-Stationen mit kleiner Überschrift darüber */
/* Gruppe "Weitere Funktionen": die drei Demo-Stationen mit kleiner Überschrift darüber */
.kp-gruppe[data-erste="ja"] {
margin-top: 10px;
}
@@ -375,6 +391,37 @@
.kp-karte__text {
max-width: 26ch;
}
/* Stichpunkte in den Karten: linksbündige Liste, als Block in der Kartenmitte */
.kp-karte__punkte {
display: flex;
flex-direction: column;
align-items: flex-start;
gap: 2px;
margin: 0;
padding: 0;
list-style: none;
text-align: left;
}
.kp-karte__punkte li {
position: relative;
padding-left: 0.95em;
}
.kp-karte__punkte li::before {
content: "";
position: absolute;
left: 0.15em;
top: calc(0.7em - 2px);
width: 4px;
height: 4px;
border-radius: 50%;
background: currentColor;
}
.kp-karte__bedienen {
margin: 0.35rem 0 0;
font-size: var(--fs-small);
font-weight: 600;
color: var(--fg);
}
/* Demo-Karten: die Website läuft im Handy, darunter Hinweis aufs erfundene Beispiel (Heatmap: zusätzlich die Diagnose) */
.kp-karte__geraet {