Vier Sachen an derselben Slide.
BREITE AUS DEM INHALT. Sie stand als feste 470 in der Zeichenfunktion,
gemessen fuer Beschriftungen mit "senden", und liess ein Drittel
Leerraum rechts. Sie kommt jetzt aus dem laengsten Eintrag. Dabei
kippte die Zeichnung von quer auf hochkant, und ein hochkantes Bild
richtet sich nach der Hoehe: bei den alten 940 px wurde der Kasten
1093 hoch und lief in die Ueberschrift. Jetzt 680.
Gerechnet ist die Breite am sichtbaren Blatt und nicht am Kasten -- der
ist um den Stapelrand groesser als das, was man sieht, und mit seiner
Oberkante gerechnet stand die Zeichnung noch einmal 60 px zu hoch.
OBEN OHNE VERB. Wer das Menue ueber das Pluszeichen geoeffnet hat,
weiss, dass er etwas schickt; "Dokument senden", "Fotos und Videos
senden", "Audio senden", "Kontakt teilen" schreiben es viermal daneben.
Jetzt stehen dort die Dinge: Dokumente, Medien, Audio, Kontakt. Unten
bleibt das Verb, weil es etwas hinzufuegt -- "Termin" allein waere ein
Anhang, "Termin erstellen" ist eine Handlung. Das ist eine Abweichung
vom Composer und steht als solche in POST-6.md 4.
DIE EINGABEZEILE IST ZURUECK. Sie war weggenommen worden mit der
Begruendung, die Slide zeige ja, was man anhaengen kann. Das stimmte
nur, solange man wusste, worauf man schaut: ohne das Feld ist die Karte
eine Liste im Nichts. Das Pluszeichen traegt jetzt die gruene Marke wie
ein gedruecktes Element, der Zeiger steht darauf, und das Menue klappt
nach oben auf -- so wie im Werkzeug.
TEILEN STATT TELEFONHOERER. Ein Hoerer sagt "anrufen"; bei "Kontakt"
wird eine Karte weitergegeben. ShareNetwork aus demselben
Phosphor-bold-Satz, entnommen aus @phosphor-icons/react im
Website-Repo statt abgemalt. "phone" stand danach nirgends mehr und ist
aus der Tabelle heraus: 19 Zeichen, jedes in Gebrauch.
Das Bewegtbild ist nicht betroffen, es nutzt das Nachrichtenmenue.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01U7RZ6ZpLD8Dp84Rtt4KHfv
Vier Unsplash-Aufnahmen unter assets/eigene, die avatarKreis() nimmt,
sobald sie da sind -- vorher stand dort das Kuerzel. Nur Menschen
bekommen eins, Projektkanal und Gruppe behalten ihr Sinnbild.
portrait-sk Sandra Koch unsplash.com/photos/SJvDxw0azqw
portrait-mb Maike Berger unsplash.com/photos/ZAo0cKz_IKM
portrait-tw Tobias Wagner unsplash.com/photos/TTdJV-K1IUg
portrait-ms Michael Schuster unsplash.com/photos/7YVZYZeITc8
Ausgewaehlt nicht nach Gesicht, sondern nach Unterscheidbarkeit im Kreis
von 42 px: dort zaehlt der Gesamtwert und die Silhouette. Die vier
decken hell, mittelhell, dunkel und mittel ab, dazu kurze Locken,
schulterlang, Schiebermuetze mit Bart, kurz und glatt.
WAS DARAN OFFEN BLEIBT, UND ZWAR WISSENTLICH
Die Unsplash-Lizenz deckt das Urheberrecht des Fotografen, kein Model
Release. Ein fremdes Gesicht als "Sandra Koch, Projektleitung" auf dem
Firmenkanal beruehrt 22 KUG und die DSGVO. Ein Zwischenstand wich
deshalb auf erzeugte Gesichter aus (StyleGAN2) und ist zugunsten echter
Aufnahmen zurueckgenommen worden. Rechtssicher waere nur
model-released Stock. Steht in POST-6.md 4.
Geprueft ist jede der vier Seiten einzeln: Unsplash-Lizenz vermerkt,
keine KI-Kennzeichnung, benannter Fotograf, Datum zwischen 2017 und
2023.
DREI FALLEN
Von 56 Suchtreffern waren 32 Profilbilder der Fotografen, nicht deren
Aufnahmen -- ein figure img greift das Avatarbild des Urhebers mit ab,
und die sehen aus wie Portraits, weil sie welche sind. Zwei davon
waren schon eingesetzt, bevor es beim Aufschreiben der Herkunft
auffiel. Erkennbar an photo- gegen profile- in der URL.
Zwei gegenlaeufige Teilstuecke in einem Pfad loeschen ihren Ueberlapp
weg, und ein Rechteck in Zeichnungsgroesse trifft nicht, was darueber
hinaussteht. Beides gehoert zum Band davor, beides fiel erst hier auf.
Zuschnitt braucht keinen Fuellton: ein Business-Portrait hat Luft ueber
dem Kopf. Skaliert mit lanczos plus leichtem unsharp, 320 x 320 JPEG --
was beim Verkleinern an Schaerfe verlorengeht, holt keine
Renderqualitaet zurueck.
Bewegtbild neu gebaut, die Avatare stehen auch darin.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01U7RZ6ZpLD8Dp84Rtt4KHfv
Der Knick sass 70 Einheiten vor der Plattenkante und lag damit mitten
auf dem Bildschirm -- das sah aus wie ein Spruchband, das jemand
daraufgeklebt und in der Mitte geknickt hat. Ein Band knickt nicht um
nichts: der Knick gehoert an die Kante, weil dort etwas ist, worum es
sich legen kann.
Jetzt knickt es genau dort um, wo die Platte aufhoert, laeuft dahinter
weiter und kommt an ihrer Kante wieder hervor: tiefer, weil es
umgeschlagen ist, niedriger, weil es wegfuehrt, flacher getont, weil man
von dort seine Unterseite sieht.
Die Stelle wird nicht gerechnet. Beide Stuecke reichen absichtlich weit
in die Platte hinein, und zwei Masken schneiden sie an deren Kante ab --
bandSilhouette die vordere Flaeche innen, bandAussen die Stuecke
draussen. Der Knick sitzt damit immer auf der Kante, auch wenn sich die
Platten einmal verschieben.
Zwei Fehler steckten in der Naht dazwischen, beide erst im erzeugten
SVG und beim Auszaehlen der Pixel sichtbar:
Beide Masken kamen aus derselben Kontur, aber die innere trug einen
schwarzen Strich darauf und war damit um eine halbe Haarlinie kleiner
als die aeussere gross war. In der Luecke war das Band von beiden
Seiten halb durchsichtig -- ein blasser Streifen genau im Falz. Die
Falzkante kommt jetzt als eigener Strich darueber.
Die Abdunklung lag auf einem Rechteck 0 0 W H. Die Stuecke stehen
ausserhalb von 0..W und wurden nie getroffen, waren also heller als
das Band daneben -- verkehrt herum fuer etwas, das weiter hinten
liegt. Nachgemessen quer ueber die Naht: Stueck 125, Band 132.
Der Lichtabfall ist auf die Haelfte zurueckgenommen (0,80 -> 0,42):
zusammen mit dem dunkleren Stueck wurde daraus sonst ein brauner
Schatten statt eines Bandes.
Ohne die zwei Festlichkeiten des klassischen Spruchbands: keine Zacken,
kein Bogen. Ein gewoelbtes Band ueber einer flachen Oberflaeche sieht
nach Urkunde aus.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01U7RZ6ZpLD8Dp84Rtt4KHfv
Auf allem stand no-store -- im Server und noch einmal in preloadAssets().
Der Browser durfte also nichts behalten, und jeder Reload lud die vollen
Assets neu: 3 MB Screenshots, 3,3 MB Mockups, Schriften, Bibliotheken.
Am schlimmsten in uebersicht.html. Die laedt die sechs Projekte als
iframes, und weil keiner etwas behalten durfte, holte sich jeder iframe
dieselben Dateien noch einmal: 38,1 MB in 435 Anfragen.
uebersicht.html erster Aufruf 38,1 MB -> 2,2 MB
uebersicht.html Reload 32,8 MB -> 1,9 MB
post6.html Reload 5,4 MB -> 0,3 MB
Die Absicht hinter no-store war richtig: ein Bild, das unter demselben
Namen ausgetauscht wird, muss sofort ankommen. no-cache leistet das
billiger -- der Browser behaelt seine Kopie, fragt aber vor jeder
Benutzung nach. Nachgeprueft: unveraendert antwortet der Server mit 304
und 0 Bytes, nach einem touch mit 200 und der vollen Datei.
Seite, Stand und Auskuenfte (/bilder, /state) bleiben bei no-store. Die
sind klein und duerfen nie aus einer Kopie kommen.
Die eine Zeile stand in allen sieben Projektdateien.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01U7RZ6ZpLD8Dp84Rtt4KHfv
Die Website macht ihre Bewegungen mit gsap 3.14.2. Uebernommen sind die
Kurven, nicht das Paket: was GSAP darueber hinaus kann -- Zeitleisten,
ScrollTrigger, MotionPath -- setzt voraus, dass etwas laeuft. Hier
laeuft nichts, animChat(i, t) bekommt seinen Fortschritt von aussen und
ist damit selbst schon die Zeitleiste. Ein paused timeline mit
.progress(t) waere dieselbe Konstruktion mit 70 KB darunter, und ein
Easing ist eine Zeile.
Zwei der Kurven waren ohnehin GSAPs: daempfen ist Wort fuer Wort
power2.inOut, rueck ist back.out(1,70158). Die Namen stehen jetzt
daneben, dazu kommen raus (power2.out) und knall (expo.out).
Der Zeiger fuhr auf power2.inOut, also langsam an, in der Mitte
schnell, wieder abbremsend -- die Bewegung eines Schlittens. Eine
Hand ist sofort schnell und wird zum Ziel hin langsam.
Und er fuhr auf der Geraden. Jetzt auf einer quadratischen Bezier,
Stuetzpunkt 13 % der Strecke quer nach aussen, vom Verlauf weg. Rund
27 px Ausbuchtung auf 410 px Weg: es faellt nicht auf, das ist der
Punkt.
Der Klickring geht auf zwei Kurven, Radius auf expo.out und die
Deckung linear hinterher. Beides auf derselben sah aus wie eine
Blase, die sich aufblaest.
Der Anlauf ist von 0,6 s auf 0,18 s geschrumpft. Am Ende steht das
Bild eine halbe Sekunde still, damit man das Ergebnis liest; lief
vorn nochmal eine halbe, waren das ueber den Schleifenstoss hinweg
1,2 von 6 Sekunden Stillstand am Stueck.
MP4 neu gebaut, Werte unveraendert: H.264, 1080x1350, 30 fps, 6,0 s,
stumme AAC-Spur. Geprueft ist das an Kontaktabzuegen ueber die 180
Bilder, nicht am Lauf.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01U7RZ6ZpLD8Dp84Rtt4KHfv
Vorher lief es ueber die ganze Zeichnung hinaus und endete an der
Bildkante, quer zur eigenen Laufrichtung abgeschnitten -- das ist das
Zeichen fuer ein Ende, so liest sich ein Aufkleber. Jetzt bricht es an
einer senkrechten Plattenkante ab, waehrend es mit 13 Grad ankommt, und
das ist keines: dort laeuft es hinter die Platte, um den Stapel herum.
Beschnitten wird an der Silhouette beider Ausschnitte. Damit macht es
die Website nach, die ihr Band am Rand des Telefons abschneidet ("so
the ends cut off like real tape"), und der Gegensatz "absperren oder
beschneiden", den der Kommentar hier behauptete, faellt weg: die
Silhouette beider Platten ist die ganze Sache.
Drei Dinge tragen es, keines verbiegt die Form:
die Schnittkante ist die Plattenkante und steht schraeg zum Band
sie ist weicher als eine Linie und haerter als die Platten (1,1)
die letzten 56 Einheiten verlieren Licht, mit dem Hoehepunkt als
Plateau davor -- auf der Kante selbst blendet die Maske schon aus
Der Verlauf steht dafuer in den Koordinaten der Zeichnung statt in
denen des gedrehten Bandes: er soll parallel zu der Kante stehen, an
der er endet.
Mit weg sind zwei Kommentarbloecke, von denen einer einen Stand
beschrieb, der einen Commit vorher zurueckgenommen worden war, und mit
ihnen WEB.bandKnick und WEB.bandSpitze.
Geprueft ueber beide Wege, Browser-Screenshot und html-to-image: die
Maske ueberlebt den Export, das Bild ist identisch.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01U7RZ6ZpLD8Dp84Rtt4KHfv
Zwei Anlaeufe haben die Form verbogen: erst die Enden zur Spitze verjuengt,
dann um eine Knickstelle gekippt. Das erste sah aus wie eine Schleife, das
zweite wie eine Welle. Ein Absperrband ist flach und straff -- was ihm gefehlt
hat, war Woelbung, nicht ein Knick.
Jetzt quer ueber die Hoehe ein Verlauf von #F8C64A ueber #F1B729 nach #D89F1B,
knapp unter der Oberkante ein Glanzlicht, und zu beiden Enden hin 20 % Abdunkeln.
Die untere Laengskante ist einen Pixel dicker als die obere, weil sie im
Schatten der Woelbung liegt. Die Form bleibt das Rechteck, das sie auf der
Website ist.
Helm und Schrift stehen weiterhin einmal und mittig.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Es war ein Rechteck mit gleichmaessig durchlaufender Schrift und las sich damit
als Aufkleber auf der Flaeche, nicht als Band darueber.
Jetzt laufen die Aussenkanten zur Mitte zusammen (10 % der Bandhoehe je Kante),
die Knickflaechen sind dunkler (#D6A11E statt #F1B729), an der Knickstelle
steht eine Kante, und die dunklen Laengskanten folgen dem Knick mit statt
darueber zu schweben.
Ein erster Anlauf knickte bei 21 % der Laenge und mit 17 % Verjuengung -- das
sah aus wie eine Schleife. Bei 12 % und 10 % bleibt die Mitte flach und nur die
Enden fuehren weg.
Helm und Schrift stehen einmal, mittig auf der geraden Flaeche. Wiederholt und
am linken Rand beginnend passte der Satz zu einem endlosen Band; auf einem,
dessen Enden sichtbar wegknicken, gehoert er in die Mitte.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
avatarKreis() zeigt ein Foto, sobald eines unter
assets/eigene/portrait-<kuerzel>.<endung> liegt -- portrait-sk, portrait-mb,
portrait-tw, portrait-ms -- rund beschnitten, mit demselben Rand wie der
Kuerzelkreis. Ist keines da, steht wie bisher das Kuerzel im Kreis. Hochladen
geht ueber "Eigene Bilder" in der Seite; preloadAssets() holt alles aus
assets/eigene ohnehin mit, der Export bekommt sie damit als Daten-URL.
Mit einem Testbild durchgefahren und wieder entfernt.
Keine Fotos im Repo, und zwar mit Absicht: das Pitch-Paket laedt seine
Portraits von Unsplash -- vier Aufnahmen echter, erkennbarer Menschen. Die
Lizenz deckt das Foto, nicht das Recht am eigenen Bild. Ein fremdes Gesicht als
"Sandra Koch, Projektleitung" in einen oeffentlichen Beitrag zu setzen, ist
etwas anderes als ein Klickdummy fuer einen Kundentermin.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Projektkanal, Gruppe und Direktnachricht tragen jetzt dieselbe Marke -- Flaeche
#DCFCE4, Rand #B7EDC6, Zeichen #148134 -- in der Liste wie im Verlauf. Vorher
trug der Kanal Lila, die Gruppe Grau und jede Person ihre eigene Farbe: vier
Familien in einer Liste, und keine sagte etwas, das die Zeile nicht schon sagt.
Die Kuerzel unterscheiden die Personen, dafuer braucht es keine vier Farbtoene.
Dazu die Symbolgewichtung zurueck auf bold, diesmal gemessen statt geschaetzt.
Der Tausch von Feather auf Phosphor hat keinen Hexwert angefasst, sah aber
trotzdem anders aus -- zu Recht: duennere Formen haben weniger voll gedeckte
Pixel, das liest sich blasser. Im Kanalsymbol, Ausschnitt 44 x 44:
Feather, wie es vorher war 59 volle Pixel, Deckung 180
Phosphor regular 23 volle Pixel, Deckung 151 (16 % zu blass)
Phosphor bold 62 volle Pixel, Deckung 192 ( 6 % darueber)
Ich hatte auf regular zurueckgestellt, weil es "im Menue leichter aussah".
Geschaetzt statt gemessen, und daneben. Wer eine optische Staerke beurteilt,
zaehlt Pixel.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Getauscht sind nur die Formen, kein einziger Farbwert -- Plakettengruen
#148134, Lila der Projekte #691CD4, Grau der Nadel #9C9CA3 sind vor und nach
dem Wechsel identisch. Was sich geaendert hatte, war die Strichstaerke: bold
sind gefuellte fette Formen, und die lesen sich neben demselben Text dunkler
als duenne Striche. Das sieht aus wie eine andere Farbe, ist aber keine.
regular trifft die optische Staerke, die Feather dort hatte.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Der Feather-Satz steckt in so ziemlich jeder Oberflaeche der letzten Jahre; man
erkennt ihn sofort wieder, und damit sieht eine Zeichnung aus wie jede andere.
Am deutlichsten war das am Gruppensymbol.
Phosphor ist dieselbe Familie von Strichsymbolen, nur mit eigener Handschrift:
runder, gleichmaessiger, andere Metaphern (UsersThree statt Users,
PaperPlaneRight statt Send, CaretDown statt ChevronDown). Es ist dasselbe
Paket, das die Website benutzt -- @phosphor-icons/react steht neben
lucide-react in ihrer package.json -- also keine dritte Handschrift im Haus.
Die 19 Pfade sind direkt aus dem installierten Paket gezogen und nicht
abgeschrieben: Gewichtung bold, Zeichenflaeche 256 x 256. Regular war neben dem
Text zu leicht. Anders als bei Feather sind es gefuellte Formen, ikon() faerbt
deshalb ueber fill statt ueber stroke; der Parameter fuer die Strichstaerke
faellt weg. FEATHER und feather() sind raus.
Der vorige Versuch tauschte nur das eine Gruppensymbol gegen zwei ueberlappende
Scheiben. Das war keine Antwort auf die Frage: die Frage war der Satz, nicht
das einzelne Zeichen.
Nebenbei: anhangKarte() und uiKachel() hatten einen Parameter namens "ikon" und
verdeckten damit die neue Funktion. Heisst jetzt "zeichen".
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Der Punkt fuer Ungelesenes war violett und leer. Violett ist im Produkt die
Farbe der Projekte -- das Kanalsymbol in derselben Zeile traegt sie schon, und
ein zweites violettes Zeichen daneben konkurriert damit, statt etwas anderes zu
sagen. Ein farbloser Punkt sagt ausserdem nur "da war was". Jetzt gruen, mit
der Zahl der ungelesenen Nachrichten darin, wie in jedem Messenger, den ein
Betrieb kennt. Die Uhrzeit derselben Zeile faerbt mit.
Die Zahlen (3, 2, 1) stehen nicht in der Quelle, dort ist unread ein
Wahrheitswert. Sie sind die einzigen erfundenen Werte im Post und stehen so in
POST-6.md.
Die Gruppe trug FeatherUsers -- das Zwei-Personen-Piktogramm, das in jeder
zweiten Oberflaeche steckt und danach aussieht. Jetzt zwei ueberlappende
Avatarscheiben, wie Teams und Linear sie an derselben Stelle zeigen; sie
sprechen dieselbe Sprache wie die Kuerzelkreise der Direktnachrichten daneben.
Ohne Buchstaben, weil die Mitglieder nirgends benannt sind.
Dabei gefunden: nach dem Vergroessern des Ausschnitts auf Slide 2 hatte ich
kollision.mjs mit Argument 1 laufen lassen -- das ist Slide 1. Auf Slide 2 ragte
das hinterste, gedrehte Blatt des Stapels fuenf Einheiten unter den Kasten.
stapelRand() rechnet den Ueberstand fuer die unskalierte Groesse, die
Skalierung vergroessert ihn mit. Der Kasten kommt jetzt aus dem skalierten
Stapel.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Es nahm dieselbe gedaempfte Kurve wie alles andere, ueber 0,8 Sekunden. Die
Deckung war darin nach fuenf Bildern fertig, waehrend die Skalierung noch eine
halbe Sekunde von 0,96 auf 1,00 weiterlief. Zu sehen war davon fast nichts, zu
spueren war es als Haenger -- und zwar genau in dem Moment, in dem geklickt
wird.
Jetzt rueck statt daempfen und ueber 0,34 statt 0,40 der Laufzeit: drei Bilder
Aufblenden, ein ganz leichtes Ueberschwingen, dann Ruhe. Die Deckung laeuft
dafuer mit Faktor 2,5 statt 4,5, sonst waeren es zwei Bilder und es knallte.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
"Versende mehr als nur Textnachrichten: Dokumente, Fotos, Sprachnachrichten."
Drei Beispiele sagen, worum es geht; die vollstaendige Liste steht im Bild
daneben.
Zu spezifisch war an der alten Fassung nicht das Aufzaehlen, sondern das
Durchdeklinieren ("... Soll daraus etwas werden: Termin oder Aufgabe."). Ich
habe daraufhin zweimal in die andere Richtung uebersteuert und gar nichts mehr
genannt. Ein Fliesstext auf einer Feature-Slide erklaert das Feature: er
umschreibt es nicht und handelt es auch nicht in vier Woertern ab.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Was das Feature kann, in einem Satz. Die Eintraege stehen im Bild und muessen
daneben weder aufgezaehlt noch erklaert werden.
Davor drei Fassungen, die alle daneben lagen: erst die Aufzaehlung samt
Erklaerung ("Dokument, Fotos, Sprachnachricht, Kontakt. Soll daraus etwas
werden: Termin oder Aufgabe."), dann zwei Versuche, es allgemeiner zu fassen,
die sprachlich verstiegen waren. Ein Fliesstext auf einer Feature-Slide
erklaert das Feature, er formuliert es nicht aus.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Der Satz fuehrt die Ueberschrift "Nicht nur Text." weiter und benennt dabei
nichts Einzelnes. Vorher stand dort die Aufzaehlung der Menueeintraege, danach
kurz eine Fassung ueber die zwei Haelften des Menues -- beides sagte, was
drinsteht, statt zu sagen, worum es geht.
Gemessen mit fliess.mjs im Schnitt des Fliesstextes und nicht in dem der
Ueberschrift, weil das eine andere Groesse und ein anderes Gewicht ist: 780 px
von 830 verfuegbaren, also eine Zeile. Eine Zwischenfassung ("... alles, was
sonst noch zum Projekt gehoert.") kam auf 903 px und liess "gehoert." allein
in der zweiten Zeile stehen.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Dort stand "Dokument, Fotos, Sprachnachricht, Kontakt. Soll daraus etwas
werden: Termin oder Aufgabe." Damit stand die Liste doppelt -- im Bild und
daneben -- und wer sie mitschreibt, legt sich zugleich darauf fest, was
drinsteht. Aendert sich das Menue, luegt der Satz.
Jetzt "Was du teilst und was du erstellst, bleibt am Projekt." Das sind die
zwei Haelften, die das Menue selbst zieht: ueber dem Trenner steht, was man
sendet und teilt, darunter, was man erstellt. Beide Verben stehen so in den
Eintraegen.
Der Textblock wird dadurch eine Zeile kuerzer, die Luft zur Zeichnung waechst
von 155 auf 199. Die Zeichnung bleibt, wie sie ist: sie steht mit 96 und 97 px
schon knapp an der Schutzzone und kann nicht mehr breiter werden.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Zusammengeschrieben und nicht mit Bindestrich, weil die Breite entscheidet:
"Chat-Nachrichten werden" misst 916 px und laeuft ueber die 896 der
Schutzzone, "Chatnachrichten werden" sind 879. Beide Schreibweisen sind
korrekt.
Ebenfalls verworfen: "Aus Chat-Nachrichten werden" (1063 px) und "Aus
Chatnachrichten werden" (1027 px) -- mit "Aus" passt die Zeile nicht mehr,
ohne bleibt der Satz vollstaendig.
Nach dem Einsetzen am gerenderten Blatt nachgezaehlt statt nur gerechnet:
zwei Zeilen zu 879 und 733 px, Gesamthoehe 158 = zweimal die Zeilenhoehe.
Kein Umbruch.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
"Aus Nachrichten werden / Aufgaben im Projekt." statt "Getippt, / und schon im
Projekt." -- die Aussage steht damit in der Ueberschrift statt nur im Bild.
Mit breite.mjs gemessen, bevor sie in die Datei kam: 860 px in der ersten und
733 in der zweiten Zeile bei 896 erlaubten. "Aufgaben im richtigen Projekt."
waere mit 1067 px uebergelaufen.
Die Beschreibung faellt weg. Die Ueberschrift sagt es, die Bewegung zeigt es,
und die Systemzeile im Bild bestaetigt es -- ein Satz darunter waere die dritte
Stelle fuer dieselbe Aussage.
Die gut hundert Pixel, die dadurch frei werden, gehen an die Zeichnung: visW
von 700 auf 776, mittig bei visLeft 152. Luft zum Text 118, derselbe Wert wie
auf Slide 1.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Beide waren ungefaehr gleich gross und lasen sich damit als gleichwertig. Sie
sind es nicht: der Ausschnitt traegt das Produkt, die Plaettchen tragen nur
die Ausgangslage.
Platz war da. Gemessen endet die linke Haelfte samt Leitung bei x = 344, der
Kasten begann erst bei 464 -- also 120 Einheiten ungenutzt. Der Kasten steht
jetzt bei 388 und ist um 1,28 skaliert; die Zeichnung wird dadurch nur
geringfuegig kleiner, das Verhaeltnis aendert sich um rund ein Drittel.
Die Projektnummer misst dadurch wieder 15,8 px statt 12,4. Sie ist der Beleg
fuer den Fliesstext ("Jeder Kanal haengt an seiner Projektnummer") und muss
lesbar bleiben.
visBottom von 120 auf 70: die Zeichnung sass sonst hoch, mit 204 px Leere
unten und nur 99 zum Text. Jetzt 154 und 149, also in einer Reihe mit Slide 3
und 4.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
animAbspielen rechnete performance.now() - ANIM_T[i] * dauer, damit die
Vorschau dort weiterlaeuft, wo der Regler steht. ANIM_T[i] ist aber undefined,
solange der Regler nie bewegt wurde: daraus wird NaN, der Fortschritt wird
NaN, und animT() liefert wegen seines eigenen "|| 0" brav wieder 0. Die
Vorschau stand still, ohne dass in der Konsole etwas auftauchte.
Bemerkt wurde es nicht, weil jede Pruefung vorher animSetzen() aufgerufen
hatte, um irgendetwas zu messen -- und damit genau den Zustand herstellte, in
dem es funktioniert. Ein Pruefskript, das den Anfangszustand anfasst, prueft
ihn nicht mehr.
animSetzen weist NaN jetzt zusaetzlich mit Number.isFinite ab, damit so ein
Wert gar nicht erst in den Stand kommt. In allen sechs Projekten nachgezogen.
Der Export war davon nicht betroffen; der Weg ueber POST /anim ist noch einmal
vom Knopf bis zur fertigen Datei durchgefahren worden.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Duenner half nicht, im Beitrag sah es aus wie vorher. Die Slide braucht ihn
auch nicht: sie besteht aus drei Nachrichten, die aufeinander folgen, und die
Aufgabenkarte ist das einzige Element mit einer gelben Marke ("Offen") -- der
Blick geht ohnehin dorthin. Ein Rahmen sagt nochmal, was die Anordnung schon
sagt, und kostet dafuer die Ruhe der Flaeche.
Mit ihm faellt letzterAnhang weg: blase() merkte sich die Lage der zuletzt
gezeichneten Anhangkarte, damit der Rahmen nicht aus einer zweiten Rechnung
kommt. Das liest jetzt niemand mehr.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Sechs Pixel waren plump -- er trug mehr Farbe als die Karte, auf die er zeigen
soll, und im Profilraster wurde daraus ein gelber Balken. Jetzt drei.
Vier Alternativen geprueft und gerendert: ganz weg, ein weicher Schein, eine
gelbe Kante links, ein duenner Ring. Jede zusaetzlich auf Feed-Breite (480 px)
heruntergerechnet, weil dort entschieden wird, ob eine Linie noch etwas sagt.
Duenner als drei haelt das nicht aus: bei 480 px sind drei Pixel noch gut
einer, darunter verschwindet die Linie.
Der duenne Ring gewinnt, weil er als einziger die Aufgabe des alten behaelt,
naemlich auf genau diese Karte zu zeigen. "Weg" nimmt der Slide ihren Zeiger,
Schein und Kante markieren einen Zustand statt hinzuweisen.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Sie hatte einen Anlauf, der links vor dem Nullpunkt begann -- ein Rest aus der
Fassung, in der die Zeichnung ueber zwei Slides lief und auf Slide 1 schon
sichtbar war. Die ist laengst zurueckgenommen; ohne Nachbarslide kam das
Stueck aus dem Nichts und versprach einen Zusammenhang, den es nicht gibt.
Jetzt beginnt sie bei "Angebot" und endet bei "Materialliste", also an beiden
Enden an etwas.
Die Raender werden dadurch gleichmaessiger: 99 links zu 107 rechts statt 92 zu
106.
Dazu drei Stellen, die noch den zweiseitigen Aufbau beschrieben, obwohl er
nicht mehr existiert: der Kommentar am Slide-Eintrag sprach von einem
negativen visLeft (er ist 92), die Slide-Tabelle in POST-6.md behauptete "die
Leitung beginnt schon auf Slide 1", und ein Absatz erklaerte die Sonderregel
fuer die Slide-Kante. Ausserdem ein doppelter Kommentar in visKanaele.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Ein Klick auf den Kopf klappt sie zu, dann bleiben 40 px und der Canvas hat
den Platz. Sie ist dafuer ein <details> mit dem Kopf als <summary> -- damit
ist die ganze Zeile die Trefferflaeche und die Tastaturbedienung kommt von
selbst, statt dass ein eigener Knopf eine zweite Flaeche fuer dieselbe Sache
aufmacht.
Ob sie offen ist, merkt sich der Browser je Projekt im localStorage und nicht
der Projektstand: das ist eine Vorliebe und keine Gestaltung, in
state/<projekt>.json wuerde sie bei jedem einen Diff machen.
In allen sechs Projekten nachgezogen. Im Streifenmodus faellt sie weiterhin
ganz weg, die Uebersicht zeigt alle sieben Rahmen unveraendert, und der
Bildexport laeuft wie vorher.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Geprueft im laufenden Team-Chat: an jeder Nachricht haengt ein Menue mit
Reagieren, Antworten, Im Thread antworten, Anpinnen, Aufgabe erstellen,
Bearbeiten, Loeschen. Das ist die Funktion, die die Website meint mit "Aus
'mach das mal' wird mit einem Klick eine echte Aufgabe".
Die Animation zeigt jetzt genau das: Tobias' Nachricht anfassen, der Pfeil
erscheint an ihr, Menue auf, "Aufgabe erstellen", die Aufgabenkarte klappt in
der Nachricht auf, die Systemzeile bestaetigt sie im Projekt.
Tobias' Nachricht und keine andere: die Aufgabenkarte aus der Quelle traegt
"Tobias Wagner · offen" als Zustaendigkeit. An einer fremden Nachricht muesste
der Name erfunden werden. So bleiben alle vier Felder der Karte genau die aus
GeneralTeamChatPage.tsx.
Der Vorgaenger nahm das Menue hinter dem Pluszeichen. Das war sauber belegt --
Datei, Zeile, Grep ueber beide Repos, dazu die Staging-API, die eine Aufgabe
nur mit contact/company/lead/project verknuepft und eine Nachricht als Bezug
gar nicht kennt -- und trotzdem falsch. Ein Pitch-Paket vom Juli belegt, was im
Juli gebaut war, nicht was das Produkt heute kann. Wo eine Aussage der Website
keine Entsprechung im vorliegenden Code hat, ist das ein Grund nachzufragen und
nicht, die Aussage auf den Code zu biegen. Steht so in POST-6.md §6.
Sechs statt acht Sekunden: das Tippen faellt mit dem richtigen Weg weg.
Instagram nimmt je Carousel-Element drei bis sechzig Sekunden an, die Laenge
richtet sich also allein nach dem Ablauf.
Dazu in den Bausteinen: fuenf Symbole fuer das Menue, und eine Blase kann eine
zweite Anhangkarte tragen, die ueber einen Anteil aufklappt -- aufgedeckt per
clipPath, nicht gestaucht.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Die erste Fassung hatte den Ablauf im Kreis: getippt wurde "Danke. Ich habe
dazu direkt eine Aufgabe erstellt.", abgeschickt -- und *danach* wuchs an
dieser Nachricht eine Aufgabenkarte. Sie meldete also eine Aufgabe, die es
noch gar nicht gab, und wurde anschliessend selbst zu einer.
Nachgesehen in GeneralTeamChatPage.tsx: eine Aufgabe entsteht ueber das Menue
hinter dem Pluszeichen ("Aufgabe erstellen", Zeile 275). Das Ergebnis ist
Nachricht m4 -- Text UND angehaengte Aufgabenkarte in einem -- gefolgt von der
Systemzeile m5. Ein Kontextmenue an einer bestehenden Nachricht gibt es dort
nicht; eine Umwandlung "Nachricht -> Aufgabe" zu zeigen waere eine Funktion,
die wir nicht haben.
Jetzt also: Notiz tippen, Pluszeichen, "Aufgabe erstellen" waehlen, und beides
geht zusammen als eine Nachricht raus, danach die Bestaetigung im Projekt. Der
Satz im Perfekt stimmt damit auch -- wenn die Nachricht ankommt, haengt die
Aufgabe daran.
Am Ende wird nichts mehr zurueckgenommen. Der Vorgaenger blendete die neue
Nachricht wieder aus, damit der Schleifenstoss unsichtbar wird; das sah aus,
als loesche sich eine abgeschickte Nachricht von selbst. Eine Schleife darf
springen, eine Nachricht darf nicht verschwinden.
Dazu ein Mauszeiger, der die Bedienung erzaehlt -- ohne ihn geht ein Menue
auf und man weiss nicht, warum -- und acht statt fuenf Sekunden: der Ablauf
hat jetzt fuenf Schritte, und jeder braucht seinen Moment.
Was ein Standbild traegt, traegt eine Animation nicht automatisch mit: auf
Slide 3 liest sich dieselbe Nachricht einwandfrei, weil dort ein Zustand steht
und keine Reihenfolge.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Jedes Projekt hat jetzt unter dem Canvas einen Bereich "Animation", im selben
Fenster. Er zeigt jede Animation als echtes Blatt in Vorschau, mit Zeitregler,
Abspielen und "MP4 exportieren".
Eine Animation ist keine Slide. Sie steht in ANIMS und nicht in SLIDES, liegt
also nicht im Streifen, taucht in der Slide-Auswahl nicht auf und wird vom
Bildexport nicht angefasst. Im Carousel ist sie ein eigenes Element, und ob
sie mitkommt, entscheidet sich beim Posten. Ein erster Anlauf machte sie zur
sechsten Slide; damit war sie in der Zaehlung und im ZIP mit drin.
Der Export laeuft ueber den neuen Endpunkt POST /anim in serve.py. Er startet
animation.mjs in einem eigenen Faden, die Seite fragt den Stand ueber
GET /anim?id= ab und zeigt Fortschritt und Pfad. Ein Browser kann kein MP4
schreiben, und eine offene Anfrage ueber zwei Minuten geht nicht -- zumal sich
animation.mjs waehrenddessen selbst Seiten von diesem Server holt.
Aufgenommen wird im neuen Modus ?nur=anim&k=<key>: dort zeigt die Seite allein
das Blatt der Animation, in 1080 x 1350 an 0,0. Damit entfaellt jede
Ausschnittsrechnung und mit ihr die Falle, dass ein zu schmales Fenster ein
leeres Bild liefert.
Als erstes Beispiel post6-animChat, fuenf Sekunden: die Antwort wird Zeichen
fuer Zeichen getippt, abgeschickt, waechst als Blase in den Verlauf, die
Aufgabenkarte klappt auf, die Systemzeile bestaetigt, alles blendet zurueck
auf den Anfang. Getippt wird VERLAUF[3].text, also die Nachricht, die im
Werkzeug an dieser Stelle ohnehin folgt.
H.264 High, yuv420p, 1080 x 1350, 30 fps, stumme AAC-Spur, +faststart: das
nimmt Instagram fuer ein animiertes Element im Carousel an. GIF nicht, das
landet als Standbild. Ein Video im Carousel wird auch kein Reel, das passiert
nur bei einem einzeln geposteten Video.
Nebenbei:
- post4, post5 und post6 trugen im Panel noch den Kopf ihrer Vorlage.
- video/README.md und video/bauen.mjs behaupteten, ffmpeg sei hier nicht
installiert. Stimmt seit 9.0.1 nicht mehr; die Bildsequenz bleibt dort
trotzdem, mit Begruendung.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Zwei Nachbesserungen an Post 6: eine Slide mehr und Zeichnungen, die nicht
mehr flach aussehen.
DIE FUENFTE SLIDE KOMMT VON DER WEBSITE
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, verwischt, und darueber ein
Absperrband aus dem Bau -- gedreht um -13 Grad, in accent-yellow F1B729 mit
Kanten in 171106, darauf immer wieder Schutzhelm und BALD VERFUEGBAR.
Ein Zwischenstand hatte hier einen selbst erfundenen gelben Aufkleber
"In Arbeit". Das war eine zweite Bildsprache neben einer vorhandenen.
Uebernommen 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 fuer eigene und FFFFFF mit Rand E9E7E5
fuer fremde, der warme Grund hsl(30 17% 95.5%). Ueberschrift und Fliesstext
ebenso: "Der Chat fuer unterwegs wird gerade gebaut."
Das Geraet selbst ist eine bewusste Abweichung. Die Website zeichnet nur
einen hellen Umriss, border 4px D1D5DB; auf einer Slide, die selbst hell ist,
faellt der in sich zusammen und sieht nach Platzhalter aus. Hier steht ein
richtiges Geraet: dunkler Korpus, heller Grat, Schirm eingelassen, Insel und
Tasten. Die Abweichung betrifft den Rahmen, nicht den Inhalt. Verwischt wird
schwaecher als dort -- auf der Website liegt das Handy gross neben Fliesstext
und darf unlesbar sein, hier ist es klein, und bei voller Staerke blieb Brei.
DIE TIEFE
Zwei Anlaeufe waren falsch. Der erste legte graue Flaechen hinter die
Elemente: das nimmt den Zeichnungen ihre Durchsichtigkeit und setzt einen
Kasten auf den Punktgrund, der dort nicht hingehoert. Wieder raus, die
Zeichnungen sind wieder durchsichtig.
Der zweite waren bessere Schatten allein. Richtig, aber zu wenig. Die
Schatten des Produkts sind in ui/theme.css gestaffelt und nicht einlagig:
--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 zwei
feDropShadow im selben Filter. Vorher stand dort einer mit dy 7.
Gebracht hat es der Stapel. post1.html hat ihn als Bildrahmen im CSS, fuer
Screenshots; hier ist er in SVG nachgebaut, mit denselben Werten:
.sheet-mid rotate(-2.4deg) translate(-2.2%, 3%) scale(.975)
.sheet-back rotate( 3.2deg) translate( 3%, 5.5%) scale(.95)
Er gibt Tiefe, die ein Schatten allein nicht schafft, und sagt, dass hinter
der einen Ansicht weitere liegen. Die hinteren Blaetter 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, und nicht auf
Slide 4, die eine Ueberlagerung ist.
AUS DER QUELLE NACHGEHOLT
Beim gruendlichen Durchgang durch GeneralTeamChatPage.tsx sind drei Dinge
aufgefallen, die vorher fehlten oder falsch waren:
- Die Datumsmarke "Heute · 30.07.2026" ueber dem ersten Beitrag und die Zeile
"Maike Berger schreibt gerade ..." ueber dem Eingabefeld. Beides gibt der
Unterhaltung Struktur, ohne eine Flaeche zu behaupten.
- Der offene Kanal ist grau hinterlegt mit Rand und shadow-sm, nicht violett.
- Die Blase muss so breit sein, wie ihr Anhang es braucht. Vorher richtete
sie sich nur nach dem Fliesstext, und "Materialliste pruefen · faellig
31.07.2026" wurde abgeschnitten -- an einer Stelle, an der der Titel die
Aussage traegt.
ZWEI FALLEN
Gedrehte Blaetter ragen aus dem Kasten. Das hinterste steht um 3,2 Grad
gedreht und um 3 und 5,5 Prozent verschoben; seine Ecken lagen bis zu 24 px
ausserhalb der 92-px-Schutzzone. Der Ueberstand wird jetzt gerechnet:
stapelRand() schickt die vier Ecken durch dieselbe Kette wie das Blatt.
getBBox() kennt keine Beschneidung. Das Absperrband war erst auf die 175 %
der Website gezogen und am Geraet abgeschnitten -- im Bild richtig, in der
Messung ein Ueberstand von 146 px, den es nicht gab. Es ist jetzt nur so
lang, wie es bei -13 Grad quer ueber das Geraet sein muss.
GEPRUEFT
Raender 93 / 227 / 110 / 140 / 350, Luft 116 / 79 / 190 / 141 / 77 px, alle
Ueberschriften innerhalb der Schutzzone, 214 CSS-Regeln, Konsole ohne Fehler,
fuenf PNGs aus dem echten Ausgabeweg bei 2160 x 2700. Downloads blieb leer,
der Projektstand unveraendert.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Nummer 5 im Redaktionsplan, erscheint Mi 26.08. Carousel, vier Slides,
Theme modern, Variante hell, Punktgrund.
DER BEITRAG
1 Bueero und Baustelle, endlich im selben Chat. Liste und Verlauf
2 Ein Kanal pro Projekt. die Chatliste gross
3 Foto rein, Aufgabe raus. Fotos, Aufgabe, Bestaetigung
4 Nicht nur Text. das Menue hinterm Plus
Slide 3 ist der Kern und keine Konstruktion: im Werkzeug folgen die drei
Nachrichten genau so aufeinander. Tobias schickt die Baustellenfotos, darauf
eine Nachricht mit angehaengter Aufgabe, darauf die Systemzeile
"Aufgabe Materialliste pruefen im Projekt erstellt". Die letzte Zeile macht
den Unterschied -- die Aufgabe liegt danach im Projekt, nicht nur im Verlauf.
Das ist woertlich der Auftrag des Redaktionsplans.
Vier Slides statt fuenf. Der fuenfte Punkt waere DSGVO und deutsche Server
gewesen, und dafuer gibt es keinen Bildschirm. Eine Behauptung ohne Bild
gehoert in die Bildunterschrift, dort steht sie woertlich wie auf der Website.
WOHER ES KOMMT
Alles aus components/general/GeneralTeamChatPage.tsx des Pitch-Pakets: die
acht Kanaele aus CHATS, der Verlauf aus INITIAL_MESSAGES, der Aufbau einer
Zeile und einer Blase aus der Quelle selbst, die Filterzeile aus dem Typ
ChatFilter, das Plus-Menue aus Composer. Symbole aus @subframe/core, Farben
aus ui/theme.css.
Vom Chat gibt es nur eine Fassung, unter /allgemein/team-chat -- anders als
bei der Pipeline mit ihren vier eigenen SHK-Bildschirmen. Die Inhalte darin
sind trotzdem aus dem Gewerk: Waermepumpe Mueller, Montagetermin,
Baustellenfotos.
WO BEWUSST ABGEWICHEN WIRD
- Slide 1 zeigt drei von sechs Nachrichten, Slide 2 fuenf von acht Kanaelen.
Ein Chat und eine Liste scrollen beide. Slide 2 behaelt alle drei Sorten:
Projektkanal, Direktnachricht, Gruppe.
- Die Bildergalerie ist eine Anhangkarte, kein Bild. Im Werkzeug laedt
GalleryPreview zwei Fotos von Unsplash. Fremde Fotos in einen Beitrag zu
setzen, der von der eigenen Baustelle spricht, waere eine Behauptung ueber
Material, das wir nicht haben.
DREI FALLEN
Die Listenzeile hat drei Zeilen, nicht zwei. Der erste Nachbau schob Nadel
und Ungelesen-Punkt neben die Vorschau, wo sie an den Text stiessen -- und
die Zuordnung fehlte ganz. Das war nicht nur Layout: der Fliesstext
behauptete "Jeder Kanal haengt an seiner Projektnummer", und die Nummer war
nirgends zu sehen. Im Original steht sie als dritte Zeile.
Eine feste Obergrenze fuer die Blasenbreite hat ein Zitat gekuerzt. Fuer die
Titelslide musste sie klein sein, damit die Unterhaltung neben die Liste
passt; auf Slide 3 stand deshalb "Materialliste pruefen · faelli..." Die
Grenze haengt jetzt an der Spalte, in der die Blase steht.
Beinahe haette ich ein Zitat ohne Grund gekuerzt. Die Website-Ueberschrift
lautet "Bueero und Baustelle, endlich im selben Chat." Das "endlich" war
gestrichen mit der Begruendung, die Zeile laufe sonst ueber die Schutzzone --
und diese Begruendung sogar mit einer Zahl versehen, die nicht gemessen war.
Nachgemessen sind es 818 px von 896 erlaubten: sie passt. Das Wort ist wieder
drin.
GEPRUEFT
Luft 102 / 61 / 254 / 141 px, alle Zeichnungen innerhalb der 92-px-
Schutzzone, breiteste Ueberschriftzeile 818 von 896, 214 CSS-Regeln
vollstaendig, Konsole ohne Fehler, vier PNGs aus dem echten Ausgabeweg bei
2160 x 2700. Downloads blieb leer, der Projektstand unveraendert.
Die Pruefskripte im Sitzungsordner waren geloescht und sind neu angelegt,
diesmal mit gemeinsamem CDP-Kern: pruef.mjs misst ueber getBBox die
tatsaechlich gezeichnete Flaeche und die Breite jeder Ueberschriftzeile,
schuss.mjs rendert einzelne Slides, breite.mjs misst eine Formulierung, bevor
sie in die Datei kommt, export.mjs faehrt den Ausgabeweg und faengt /save ab.
NEBENBEI
Die Projektliste steht jetzt achtmal im Repo, einmal je Post-Seite plus
uebersicht.html, dort zusaetzlich in PROJEKTE. Post 6 ist ueberall
eingetragen. Wichtig fuer den offenen Tab: der Eintrag steht im Markup und
entsteht nicht zur Laufzeit -- eine Seite, die schon geladen war, zeigt ihn
erst nach dem Neuladen.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>