diff --git a/POST-6.md b/POST-6.md
index 13860c5..4eceda1 100644
--- a/POST-6.md
+++ b/POST-6.md
@@ -8,8 +8,8 @@ Hell, Theme `modern`, Punktgrund, Text zentriert — dieselbe Anlage wie Post 4
und 5. Datei `post6.html`, Stand in `state/post6.json`, erreichbar über das
Projektmenü jeder Seite und über `uebersicht.html`.
-**Vier Slides.** Fünf waren erlaubt; der fünfte Punkt wäre DSGVO und deutsche
-Server gewesen, und dafür gibt es keinen Bildschirm. Er steht in der
+**Fünf Slides.** DSGVO und deutsche Server hätten einen sechsten Punkt
+ergeben, dafür gibt es aber keinen Bildschirm. Der steht in der
Bildunterschrift, wo eine Aussage ohne Bild hingehört.
---
@@ -22,6 +22,7 @@ Bildunterschrift, wo eine Aussage ohne Bild hingehört.
| 2 | Die Kanäle | Ein Kanal **pro Projekt.** | Die Chatliste groß: Projektkanäle, Direktnachrichten, Gruppe |
| 3 | Die Aufgabe | Foto rein, **Aufgabe raus.** | Baustellenfotos, die Aufgabe daraus, die Bestätigung im Projekt |
| 4 | Das Pluszeichen | Nicht nur **Text.** | Das Menü hinter dem Plus im Eingabefeld |
+| 5 | Bald verfügbar | Der Chat für unterwegs **wird gerade gebaut.** | Das Handy-Mockup der Website, verwischt, mit Absperrband |
**Slide 3 ist der Kern.** Der Redaktionsplan verlangt „Foto rein, Aufgabe
raus", und genau das liegt im Werkzeug als Abfolge vor: Tobias schickt die
@@ -110,14 +111,14 @@ Beitrag zu setzen, der von der eigenen Baustelle spricht, wäre eine Behauptung
| | |
|---|---|
-| Slides | 4 |
+| Slides | 5 |
| Format | 1080 × 1350, Ausgabe zweifach: 2160 × 2700 |
-| Luft zwischen Text und Zeichnung | 102 / 61 / 254 / 141 px (Grenze 40) |
+| Luft zwischen Text und Zeichnung | 116 / 79 / 190 / 141 / 77 px (Grenze 40) |
| Zeichnung ragt über die Seite | nein, alle innerhalb der 92-px-Schutzzone |
| Breiteste Überschriftzeile | 818 px von 896 |
| Stylesheet vollständig | 214 Regeln, `[data-edit]` vorhanden |
| Konsole | keine Fehler |
-| Ausgabeweg | geprüft, `01-chat-hell.png` bis `04-menue-hell.png` |
+| Ausgabeweg | geprüft, `01-chat-hell.png` bis `05-handy-hell.png` |
Geprüft wird mit den Hilfsskripten aus dem Sitzungsordner: `pruef.mjs` misst
über `getBBox()` die tatsächlich gezeichnete Fläche je Slide und die Breite
@@ -127,7 +128,94 @@ Ausgabeweg und fängt `/save` ab.
---
-## 6. Drei Fallen aus diesem Bau
+## 5a. Slide 5 kommt von der Website, nicht von mir
+
+**Das Gerät ist eine bewusste Abweichung.** Die Website zeichnet nur einen
+hellen Umriss (`border: 4px solid #D1D5DB`). Auf einer Slide, die selbst hell
+ist, fällt der in sich zusammen und sieht nach Platzhalter aus. Hier steht
+deshalb ein richtiges Gerät: dunkler Korpus, heller Grat, Schirm eingelassen,
+Tasten an der Seite. Die Abweichung betrifft den Rahmen, nicht den Inhalt. Der
+Schirm wird auch schwächer verwischt als dort: auf der Website liegt das Handy
+groß neben Fließtext und darf unlesbar sein, hier ist es klein, und bei voller
+Stärke blieb nur Brei.
+
+**Die App gibt es noch nicht, und die Website sagt das bereits.** In
+`components/sections/ChatDemoSection.tsx` steht unter der Fahne `comingSoon`
+genau dieser Zustand: ein Handy-Mockup, das mit `blur(3px) saturate(0.92)`
+verwischt wird, und darüber ein **Absperrband** aus dem Bau, gedreht um
+**-13°**, in `--accent-yellow` `#F1B729` mit Kanten in `#171106`, darauf immer
+wieder Schutzhelm und **BALD VERFÜGBAR**.
+
+Ein Zwischenstand hatte hier einen selbst erfundenen gelben Aufkleber
+„In Arbeit". Das war eine eigene Bildsprache neben einer vorhandenen.
+Übernommen ist jetzt die der Website, samt Winkel, Farben und Wortlaut.
+
+Auch der Inhalt des Schirms kommt von dort und **nicht** aus dem Pitch-Paket:
+Heizungsprojekt Schulz, „4 Mitglieder · 2 online", die vier Nachrichten aus
+`seedMessages`, die Blasenfarben `#0D6E6E` für eigene und `#FFFFFF` mit Rand
+`#E9E7E5` für fremde, der warme Grund `hsl(30 17% 95.5%)`. Auf der Website
+steht dieses Handy für den mobilen Chat, also zeigt es hier dasselbe.
+
+Überschrift und Fließtext sind ebenfalls die der Website: „Der Chat für
+unterwegs wird gerade gebaut." und „Die mobile App legen wir gerade auf die
+Baustelle. Am Desktop bist du schon voll dabei, die Version fürs Handy folgt
+in Kürze." Der Em-Dash der Vorlage ist durch ein Komma ersetzt, `rules.md` §4.
+
+---
+
+## 5b. Woher die Tiefe kommt
+
+Zwei Anläufe waren falsch, bevor es saß.
+
+**Erster Versuch: graue Flächen hinter die Elemente.** Das nimmt den
+Zeichnungen ihre Durchsichtigkeit und setzt einen Kasten auf den Punktgrund,
+der dort nicht hingehört. Wieder raus.
+
+**Zweiter Versuch: nur bessere Schatten.** Richtig, aber zu wenig. Die
+Schatten des Produkts sind in `ui/theme.css` **gestaffelt** und nicht
+einlagig, und das war tatsächlich ein Fehler im ersten Nachbau:
+
+```
+--shadow-sm 0 1px 2px rgb(0 0 0 / .08)
+--shadow-md 0 4px 16px -2px + 0 2px 4px -1px
+--shadow-lg 0 12px 32px -4px + 0 4px 8px -2px
+```
+
+Zwei Lagen, weil eine allein nicht beides kann: die enge dunkle Kante setzt
+das Element auf die Fläche, die weite helle hebt es davon ab. In SVG zwei
+`feDropShadow` im selben Filter. Vorher stand dort einer mit `dy 7` und
+`stdDeviation 10`.
+
+**Was es gebracht hat: der Stapel.** `post1.html` hat ihn als Bildrahmen
+`stapel` im CSS, für Screenshots. Hier ist er in SVG nachgebaut, mit genau
+denselben Werten, damit die Reihe zusammenpasst:
+
+```
+.sheet-mid rotate(-2.4deg) translate(-2.2%, 3%) scale(.975)
+.sheet-back rotate( 3.2deg) translate( 3%, 5.5%) scale(.95)
+```
+
+Er trägt zwei Aufgaben: er gibt Tiefe, die ein Schatten allein nicht schafft,
+und er sagt, dass hinter der einen Ansicht weitere liegen. Die hinteren
+Blätter sind deshalb **leer** — Andeutung, keine Kopie.
+
+Auf Slide 1 und 2 liegt er, weil dort ein Bildschirm zu sehen ist. Auf Slide 3
+nicht: ein Ausschnitt aus einer Unterhaltung ist kein Blatt, dort tragen die
+Blasen ihre eigene Erhebung. Slide 4 ist eine Überlagerung und trägt
+`--shadow-overlay`.
+
+Dazu zwei Dinge aus der Quelle, die der Unterhaltung Struktur geben, ohne eine
+Fläche zu behaupten: die Datumsmarke **Heute · 30.07.2026** über dem ersten
+Beitrag und die Zeile **„Maike Berger schreibt gerade …"** über dem
+Eingabefeld. Beides steht so in `GeneralTeamChatPage.tsx`.
+
+Nebenbei richtiggestellt: **der offene Kanal ist grau hinterlegt, nicht
+violett.** Im Original steht dort `bg-surface-neutral-primary` mit Rand und
+`shadow-sm`.
+
+---
+
+## 6. Fünf Fallen aus diesem Bau
**Die Listenzeile hat drei Zeilen, nicht zwei.** Der erste Anlauf setzte Titel
und Vorschau untereinander und schob Nadel und Ungelesen-Punkt rechts neben
@@ -150,6 +238,21 @@ Nachgemessen sind es 818 px von 896 erlaubten: sie passt. Das Wort ist wieder
drin. Dafür gibt es jetzt `breite.mjs`, das eine Formulierung misst, bevor sie
in die Datei kommt.
+**Gedrehte Blätter ragen aus dem Kasten.** Der Stapel dreht das hinterste
+Blatt um 3,2° und verschiebt es um 3 % und 5,5 % der eigenen Größe. Die Ecken
+stehen damit über das vordere Blatt hinaus, und die Zeichnung lag bis zu 24 px
+außerhalb der 92-px-Schutzzone. Der Überstand wird jetzt gerechnet statt
+geschätzt: `stapelRand()` schickt die vier Ecken durch dieselbe Kette wie das
+Blatt und nimmt den größten Wert. `stapelKasten()` macht den Kasten
+entsprechend größer.
+
+**`getBBox()` kennt keine Beschneidung.** Das Absperrband war zuerst auf die
+175 % der Website gezogen und per `clip-path` am Gerät abgeschnitten. Im Bild
+stimmte das, die Randmessung meldete aber einen Überstand von 146 px, den es
+gar nicht gab: `getBBox()` liefert die Geometrie, nicht das Sichtbare. Das
+Band ist jetzt nur so lang, wie es bei -13° quer über das Gerät sein muss,
+also `B / cos(13°)` plus Zugabe. Messung und Bild sagen wieder dasselbe.
+
**Das Prüfskript nahm eine leere Slide auf.** `schuss.mjs` stellte für eine
einzelne Slide ein Fenster von 1400 px. Im durchgehenden Blatt liegt Seite 3
aber bei x = 2160, und `captureBeyondViewport` fing das nicht zuverlässig ab.
diff --git a/README.md b/README.md
index 6481cf5..eb694ab 100644
--- a/README.md
+++ b/README.md
@@ -26,7 +26,7 @@ Downloads landen direkt in `~/Downloads`, ohne Browser-Dialog.
| Post 3 · Verbinden statt ersetzen | `post3.html` | Einzelbild, Theme `modern`, erscheint 17.08. | |
| Post 4 · Workflow-Engine | `post4.html` | Carousel, 4 Slides, Theme `modern`, erscheint 19.08. | [`POST-4.md`](./POST-4.md) |
| Post 5 · Projektmanagement | `post5.html` | Carousel, 5 Slides, Theme `modern`, erscheint 21.08. | [`POST-5.md`](./POST-5.md) |
-| Post 6 · Team-Chat | `post6.html` | Carousel, 4 Slides, Theme `modern`, erscheint 26.08. | [`POST-6.md`](./POST-6.md) |
+| Post 6 · Team-Chat | `post6.html` | Carousel, 5 Slides, Theme `modern`, erscheint 26.08. | [`POST-6.md`](./POST-6.md) |
**Alle Streifen nebeneinander** zeigt `uebersicht.html`, erreichbar über
*Projekt → Alle Projekte im Streifen*. Die Seite baut die Slides nicht selbst
@@ -224,6 +224,7 @@ Baustellenfotos.
| 2 | die Chatliste groß: Projektkanäle, Direktnachrichten, Gruppe |
| 3 | Fotos, die Aufgabe daraus, die Bestätigung im Projekt |
| 4 | das Menü hinter dem Plus im Eingabefeld |
+| 5 | das Handy-Mockup der Website, verwischt, mit Absperrband |
**Slide 3 ist der Kern**, und sie ist keine Konstruktion: im Werkzeug folgen
die drei Nachrichten genau so aufeinander. Tobias schickt die Baustellenfotos,
@@ -231,9 +232,26 @@ darauf eine Nachricht mit angehängter Aufgabe, darauf die Systemzeile
„Aufgabe „Materialliste prüfen" im Projekt erstellt". Die letzte Zeile macht
den Unterschied: die Aufgabe liegt danach im Projekt, nicht nur im Verlauf.
-**Vier Slides, nicht fünf.** Der fünfte Punkt wäre DSGVO und deutsche Server
-gewesen. Dafür gibt es keinen Bildschirm, und eine Behauptung ohne Bild gehört
-in die Bildunterschrift.
+**Slide 5 kommt von der Website, nicht aus dem Pitch-Paket.** Die App gibt es
+noch nicht, und `ChatDemoSection.tsx` hat den Zustand bereits: ein Handy-Mockup
+mit `blur(3px)` und darüber ein **Absperrband** aus dem Bau, -13° gedreht, in
+`#F1B729` mit Kanten in `#171106`, darauf Schutzhelm und „BALD VERFÜGBAR".
+Auch Inhalt, Blasenfarben, Überschrift und Fließtext sind die der Website. Ein
+Zwischenstand hatte hier einen selbst erfundenen Aufkleber; das war eine eigene
+Bildsprache neben einer vorhandenen.
+
+**Die Tiefe kommt aus dem Stapel und gestaffelten Schatten, nicht aus
+Flächen.** Ein Zwischenstand legte graue Flächen hinter die Elemente; das nimmt
+den Zeichnungen ihre Durchsichtigkeit und setzt einen Kasten auf den
+Punktgrund. Stattdessen zweierlei: die echten Schatten aus `ui/theme.css`, die
+dort **gestaffelt** sind (enge dunkle Kante plus weite helle, in SVG zwei
+`feDropShadow` im selben Filter), und der **Stapel** aus `post1.html`, in SVG
+nachgebaut mit denselben Winkeln, die dort im CSS stehen. Die hinteren Blätter
+sind leer: Andeutung, keine Kopie. Auf Slide 1 und 2, wo ein Bildschirm zu
+sehen ist; nicht auf Slide 3, wo ein Ausschnitt einer Unterhaltung steht.
+
+Dazu die Datumsmarke und die Zeile „Maike Berger schreibt gerade …" aus der
+Quelle, die der Unterhaltung Struktur geben, ohne eine Fläche zu behaupten.
**Die Bildergalerie ist eine Anhangkarte, kein Bild.** Im Werkzeug lädt
`GalleryPreview` zwei Fotos von Unsplash. Fremde Fotos in einen Beitrag zu
diff --git a/post6.html b/post6.html
index 804f100..696c7f7 100644
--- a/post6.html
+++ b/post6.html
@@ -1305,7 +1305,7 @@ if (location.search.indexOf("nur=streifen") >= 0)
eyebrow: "Team-Chat",
head: 'Büro und Baustelle, endlich im selben Chat.',
body: "",
- vis: "chat", visW: 896, visLeft: 92, visBottom: 120,
+ vis: "chat", visW: 948, visLeft: 66, visBottom: 120,
},
{
/* Der Fliesstext ist das Merkmal "Themen-Kanäle" von der Website,
@@ -1316,7 +1316,7 @@ if (location.search.indexOf("nur=streifen") >= 0)
eyebrow: "Die Kanäle",
head: 'Ein Kanal pro Projekt.',
body: "Projektkanäle, Direktnachrichten, Gruppen. Jeder Kanal hängt an seiner Projektnummer.",
- vis: "kanaele", visW: 620, visLeft: 230, visBottom: 120,
+ vis: "kanaele", visW: 672, visLeft: 204, visBottom: 120,
},
{
/* Der Satz aus dem Redaktionsplan: "Foto rein, Aufgabe raus." Die
@@ -1337,6 +1337,22 @@ if (location.search.indexOf("nur=streifen") >= 0)
body: "Dokument, Fotos, Sprachnachricht, Kontakt. Und wenn daraus etwas werden soll: Termin oder Aufgabe.",
vis: "menue", visW: 800, visLeft: 140, visBottom: 120,
},
+ {
+ /* Ein Ausblick, kein Beleg. Die App gibt es noch nicht -- deshalb steht
+ die Marke "In Arbeit" ueber dem Geraet, und der Fliesstext sagt es
+ geradeheraus. Auf dem Schirm ist nichts Neues: dieselben zwei
+ Nachrichten wie auf Slide 1, nur schmaler gesetzt.
+
+ "Im Buero am Rechner, auf der Baustelle am Handy" steht als Merkmal
+ "Desktop & Mobile" auf der Website. Der Satz beschreibt das Ziel,
+ nicht den heutigen Stand -- deshalb ist er hier nicht zitiert. */
+ key: "handy", type: "feature",
+ layouts: [{ id: "standard", label: "Standard" }],
+ eyebrow: "Bald verfügbar",
+ head: 'Der Chat für unterwegs wird gerade gebaut.',
+ body: "Die mobile App legen wir gerade auf die Baustelle. Am Desktop bist du schon voll dabei, die Version fürs Handy folgt in Kürze.",
+ vis: "handy", visW: 358, visLeft: 361, visBottom: 120,
+ },
];
/* Vorlage für eine selbst angelegte Slide. Sie startet bewusst mit Text
@@ -1482,10 +1498,45 @@ if (location.search.indexOf("nur=streifen") >= 0)
mit beschnitten (lib/chamfer.ts der Website). Die doppelte id in
mehreren Blaettern stoert nicht: alle Filter sind gleich, und url(#..)
nimmt den ersten. */
+ /* Die Schatten des Produkts, aufgeloest aus ui/theme.css. Sie sind
+ gestaffelt und nicht einlagig -- genau daran hing es, dass die
+ Zeichnungen flach aussahen:
+
+ --shadow-sm 0 1px 2px rgb(0 0 0 / .08)
+ --shadow-md 0 4px 16px -2px + 0 2px 4px -1px
+ --shadow-lg 0 12px 32px -4px + 0 4px 8px -2px
+
+ Zwei Lagen, weil eine allein nicht beides kann: die enge dunkle Kante
+ setzt das Element auf die Flaeche, die weite helle hebt es davon ab. In
+ SVG heisst das zwei feDropShadow hintereinander im selben Filter.
+
+ Der negative Spread der CSS-Fassung (-2px, -4px) laesst sich in SVG nicht
+ nachbilden; er wird ueber eine etwas kleinere Streuung angenaehert. */
+ /* Wie wfSvg, aber mit Rand: der Inhalt wird um `rand` verschoben und der
+ Kasten entsprechend groesser. Damit liegt eine Flaeche, die bei -rand
+ beginnt, genau auf der Kante des Kastens -- und die Randmessung sieht
+ wieder, was wirklich dasteht. */
+ const svgMitRand = (b, h, rand, inhalt) =>
+ wfSvg(b + 2 * rand, h + 2 * rand,
+ '' + inhalt + '');
+
const SCHATTEN_DEFS =
- '' +
- '';
+ '' +
+ '' +
+ '' +
+ '' +
+ '' +
+ '' +
+ '' +
+ '' +
+ '' +
+ '' +
+ '' +
+ '' +
+ '' +
+ '' +
+ '' +
+ '';
// Eine Karte: Flaeche, Haarlinie, Schatten. Das ist die Grundform des Themes.
const karteFlaeche = (x, y, w, h, c, fuell) =>
@@ -1822,6 +1873,8 @@ if (location.search.indexOf("nur=streifen") >= 0)
und der