Wir stehen am Anfang einer neuen technologischen Epoche – doch die eigentliche Herausforderung liegt nicht in der Intelligenz der Systeme, sondern in ihrer Begrenzung. Während ich an meinem eigenen KI-Setup arbeite, wird mir klar: Es geht nicht darum, was Maschinen können – sondern wann sie eingreifen dürfen.
Wir befinden uns in einer bemerkenswert instabilen Phase der Menschheitsgeschichte.
Kriege sind dabei nichts Neues – sie gehören beinahe schon zum wiederkehrenden Muster,
gesteuert von den immer gleichen Dynamiken: Macht, Verantwortungslosigkeit und dem Leid
derjenigen, die am wenigsten Einfluss haben. Die Gepeinigten klagen, die Verursacher
weisen jede Schuld von sich. Lösungen werden selten aktiv gesucht; sie entstehen eher
langsam, beinahe widerwillig, als Nebenprodukt eines grundlegenden menschlichen Triebs:
zu überleben.
Und doch gibt es immer wieder diese Momente, in denen etwas Neues auftaucht.
Etwas, das zunächst unscheinbar wirkt – und erst später seine Tragweite entfaltet.
So war es mit der Entdeckung der Kernspaltung, die schließlich das Atomzeitalter einläutete.
Heute sprechen alle von KI. Doch nur wenige verstehen wirklich, welches Potenzial –
und welche Risiken – darin liegen. Ich selbst eingeschlossen.
Ideen und Start-ups sprießen aus dem Boden, getragen vom Enthusiasmus einer ganzen
Entwicklergeneration. Wir stehen am Anfang einer Zeit, die gleichzeitig von enormem
Potenzial und realen Gefahren geprägt ist. Und ich merke, wie sehr mich das selbst erfasst hat.
Jeden Tag beobachte ich neue Entwicklungen und vergleiche sie mit meinem eigenen kleinen Projekt.
Eigentlich sollte ich mich auf meine Weiterbildung bei der Developer Akademie konzentrieren.
Doch immer wieder ziehen mich neue Ideen hinein: Knowledge Graphs, ein besseres RAG-System,
neue Tools, neue Ansätze.
Da ich Python noch nicht sicher genug beherrsche, greife ich auf das zurück, was mir zur Verfügung steht:
KI-gestützte Entwicklung, Tools wie Cursor, Experimente mit neuen Systemen – und vor allem viel Ausprobieren,
viel Scheitern, viel Verstehen. Am Ende entsteht daraus ein heterogenes System, das Stück für Stück besser
verdrahtet ist und tatsächlich beginnt zu funktionieren.
Und ja – ich arbeite weiterhin an meiner Ausbildung. Aber ich belohne mich immer wieder
mit diesen eigenen Meilensteinen.
Und genau an diesem Punkt hat sich etwas verschoben.
Ich habe gemerkt, dass ich nicht nur an meinem System arbeite.
Ich arbeite an etwas Grundsätzlicherem.
Nicht an KI.
Sondern an der Art, wie Mensch und Maschine überhaupt zusammenarbeiten.
Ich habe ein Setup aufgebaut, in dem mehrere Systeme gleichzeitig beteiligt sind.
Ein System kann direkt auf meinen Code zugreifen. Ein anderes hilft mir beim Denken und Strukturieren.
Und ich sitze dazwischen und versuche, die Kontrolle zu behalten.
Und genau dort wurde das eigentliche Problem sichtbar.
Die Maschine ist nicht das Problem. Sie ist schnell, effizient und oft sogar überraschend präzise.
Das Problem ist, dass sie nicht weiß, wann sie eingreifen soll.
Ich wollte eine Analyse. Ich bekam eine Analyse – und unmittelbar danach eine Veränderung meines Codes.
Nicht aus böser Absicht. Nicht aus Dummheit.
Sondern weil dem System ein klares Verständnis dafür fehlt,
wo Analyse endet und Eingriff beginnt.
Und genau darin liegt die eigentliche Herausforderung unserer Zeit.
Wir bauen Systeme, die handeln können, bevor wir definiert haben,
wie wir ihre Eingriffe begrenzen.
Ich habe erkannt: Die wichtigste Eigenschaft solcher Systeme ist nicht Intelligenz.
Sondern Zurückhaltung.
Ich will kein System, das alles kann.
Ich will ein System, das weiß, wann es nichts tun darf.
Vielleicht ist genau das der Unterschied zwischen einem Werkzeug und einem Akteur.
Mein Projekt ist noch weit davon entfernt, perfekt zu sein.
Es hat kein echtes Kurzzeitgedächtnis.
An manchen Stellen ist es zu strikt, an anderen zu offen.
Und ich verliere mich immer wieder in neuen Ideen.
Aber ich habe begonnen zu verstehen, woran ich wirklich arbeite.
Nicht an einer perfekten KI.
Sondern an einer Struktur, in der Entscheidungen nachvollziehbar bleiben.
Und vielleicht liegt genau darin der eigentliche Anfang.
Nicht darin, mehr Kontrolle über die Maschine zu gewinnen –
sondern klar zu definieren, wo sie überhaupt eingreifen darf.
Warum ich mir zuerst ein Werkzeug gebaut habe
14.–31. Dezember 2025
Im Dezember 2025 stand ich an einem Punkt, an dem sich vieles zu ordnen begann.
Nicht, weil ich Antworten hatte – sondern weil ich gelernt hatte, die richtigen Fragen zu stellen.
Künstliche Intelligenz war längst kein Zukunftsthema mehr. Sie war da.
Im Alltag, im Beruf, im Denken. Die Frage war nicht mehr, ob sie Teil meines Lebens wird,
sondern wie.
Mich reizte dabei nie die Idee, möglichst viel zu automatisieren oder mir Arbeit abzunehmen.
Was mich beschäftigte, war etwas anderes:
Wie bleibt man handlungsfähig, wenn Systeme immer mächtiger werden?
Viele der damaligen Ansätze fühlten sich für mich nicht falsch an – aber unruhig.
Nicht wegen der Technik selbst, sondern wegen der Art, wie sie genutzt wurde:
schnell, abhängig, oft ohne echtes Verständnis der Infrastruktur dahinter.
Systeme, die funktionieren – bis sie es nicht mehr tun.
Gleichzeitig entstand eine konkrete Idee:
eine lokale, ressourcenschonende KI.
Nicht als Chatbot, sondern als Werkzeug zur Ordnung von Wissen.
Texte markieren, Informationen neu sortieren, Zusammenhänge sichtbar machen.
Technisch war das alles überschaubar:
Markdown, YAML, JSON, ein lokales LLM, Retrieval statt Training,
Profile statt implizitem Lernen.
Der Reiz lag nicht in der Neuheit, sondern in der Haltung.
Was mir dabei zunehmend auffiel, war das begrenzte Erinnerungsvermögen cloudbasierter
KI-Systeme. Es gab Ansätze für Langzeitgedächtnis, Regeln oder Projektkonfigurationen –
aber sobald es um kontinuierliche Zusammenarbeit ging, wurde es mühsam.
Lange Chats ersetzen kein echtes Gedächtnis.
Kontext ging verloren, Annahmen mussten wiederholt werden,
gemeinsame Grundlagen zerfielen.
Selbst einfache Dinge – wie das Arbeiten auf einer stabilen gemeinsamen Basis –
fühlten sich brüchig an.
Tools wie Git helfen. Moderne Assistenten ebenfalls.
Aber zu diesem Zeitpunkt war vieles davon noch im Entstehen oder nicht wirklich greifbar.
Für mich bedeutete das:
Zusammenarbeit mit KI war möglich – aber nicht wirklich stabil.
Und genau hier begann das eigentliche Abwägen.
Ich befand mich mitten in meiner Frontend-Ausbildung.
Der Fokus war klar, die Lernkurve stabil.
Ein paralleler Einstieg in Backend-Architektur und KI-Orchestrierung
hätte alles verwässert.
Also traf ich eine Entscheidung, die mir früher schwergefallen wäre:
Nicht alles sofort bauen.
Stattdessen habe ich die Idee aufgeteilt:
Die Vision durfte groß bleiben.
Die Umsetzung wurde bewusst verschoben.
Die Struktur wurde vorbereitet.
Personalisierung sollte nicht über Modelltraining entstehen,
sondern über nachvollziehbare Mittel:
Profile, Wissensspeicher, Feedback-Logs.
Keine stillen Anpassungen. Keine unsichtbaren Prozesse.
Was sich dabei immer klarer zeigte, war ein Leitmotiv:
Lokale Kontrolle und Archivfähigkeit.
Nicht aus Misstrauen.
Sondern aus dem Wunsch, zu verstehen, was passiert – wenn etwas passiert.
Und aus dem Bedürfnis, Wissen nicht von Plattformen oder Modellen abhängig zu machen.
Diese Haltung war ruhig.
Nicht euphorisch. Nicht getrieben.
Eher eine Form von achtsamer Disziplin.
An einem Punkt wurde klar:
Wenn ich das ernst meine, brauche ich ein Fundament,
das diese Entscheidungen tragen kann.
Kein geliehenes System. Keine Abstraktion.
Sondern ein eigenes Werkzeug.
Noch ohne fertige KI. Noch ohne große Versprechen.
Aber mit der Bereitschaft, Verantwortung zu übernehmen.
Und damit war der nächste Schritt keine Software-Frage mehr,
sondern eine sehr konkrete.
Essay: Lernen, Verantwortung und die Arbeit mit KI
Über das Lernen mit KI, über Abkürzungen, Widerstand
und die Verantwortung, den eigenen Denkprozess nicht zu überspringen.
· Essay • Reflexion • Lernen • KI
Ich lerne Programmieren in einer Zeit, in der sich eine neue Selbstverständlichkeit etabliert hat:
Man kann fragen – und bekommt Antworten.
Man kann beschreiben – und erhält Code.
Man kann sich helfen lassen, geduldig, umfassend und jederzeit verfügbar.
Ich nutze diese Möglichkeit.
Und ich habe gelernt, dass genau darin eine Verantwortung liegt.
Als ich begann, intensiver mit KI zu arbeiten, war das kein Ersatz für Lernen, sondern zunächst eine
Vertiefung.
Ich konnte nachfragen, Dinge umkreisen, Zusammenhänge aus verschiedenen Blickwinkeln betrachten.
Besonders dann, wenn mich ein Thema wirklich interessierte, wurde der Dialog zu einem Denkraum,
nicht zu einer Abkürzung.
Gleichzeitig wurde mir bewusst, dass diese Form des Lernens Fragen aufwirft –
nicht nur für andere, sondern auch für mich selbst.
Die Abgabephase als Spiegel
Rückblickend waren die Tage rund um die Abgaben und Revisionen im Dezember besonders aufschlussreich.
Nicht wegen spektakulärer Ergebnisse, sondern wegen der Reibung.
Ich habe offen kommuniziert, dass ich mir Unterstützung hole:
für Erklärungen, für Perspektiven, für das Durchdenken von Konzepten.
Ich habe auch eingeräumt, dass ich mir visuelle Elemente, Symbole oder sprachliche Formulierungen
generieren lasse –
dort, wo es nicht um das technische Kernverständnis, sondern um Darstellung geht.
Die Rückmeldungen darauf waren sachlich und unterstützend.
Es wurde klar unterschieden zwischen Hilfe beim Denken und bloßem Kopieren, zwischen Inspiration und
Ersatzleistung.
Was mich besonders beruhigt hat:
Es bestand kein Misstrauen. Aber es gab Leitplanken.
Klassisches Lernen und neue Werkzeuge
Mir wurde nahegelegt, technische Inhalte weiterhin klassisch zu vertiefen:
Dokumentationen lesen, Referenzen nutzen, Dinge selbst ausprobieren.
MDN, w3schools, echte Fehlermeldungen, echtes Ringen.
Ich verstehe diese Empfehlung – und ich weiß, dass sie richtig ist.
Gleichzeitig habe ich gemerkt, dass mein Lernweg nicht immer linear verläuft.
Multiple-Choice-Tests oder reines Wiedergeben von Wissen fühlen sich für mich oft wie eine Simulation
von Verständnis an,
nicht wie Verständnis selbst.
Das heißt nicht, dass diese Formen wertlos sind.
Aber sie greifen zu kurz, wenn es um Zusammenhänge, Verantwortung und Transfer geht.
Hier liegt für mich eine zentrale Spannung:
Nicht zwischen alt und neu, sondern zwischen Wissen testen und Verstehen
entwickeln.
Die eigentliche Gefahr
Die größte Gefahr in der Arbeit mit KI ist für mich nicht das Copy-Paste.
Diese Form der Täuschung ist grob und leicht zu erkennen – auch für mich selbst.
Die subtilere Gefahr liegt woanders: im Überspringen des eigenen Ringens.
Wenn eine Erklärung zu glatt ist.
Wenn eine Lösung sofort passt.
Wenn kein Widerstand bleibt, an dem sich Verständnis aufbauen kann.
Nicht jede Antwort ist hilfreich, nur weil sie korrekt ist.
Nicht jede Abkürzung spart Zeit – manche verlagern die Kosten nur nach hinten.
Diese Sensibilität habe ich mir nicht theoretisch erarbeitet, sondern praktisch:
im Projekt, im Debugging, im Wiederlesen von eigenem Code, den ich zwar „verstanden“,
aber noch nicht wirklich durchdrungen hatte.
KI als Verstärker
Was mir der Dialog mit KI dennoch ermöglicht hat, ist etwas anderes: einen Spiegel.
Fragen werden präziser, wenn man sie formulieren muss.
Unklarheiten werden sichtbar, wenn man sie erklärt haben möchte.
Und manchmal merkt man erst beim Lesen einer Antwort, was man eigentlich noch nicht verstanden hat.
In diesem Sinn ist KI für mich zwar sowohl Lehrer als auch Autor.
Ich benutze sie jedoch eher als einen Verstärker dessen, was bereits da ist:
Neugier, Unsicherheit, Strukturbedürfnis und Verantwortung.
Aber genau deshalb darf sie nicht allein stehen.
Ausprobieren als Grenze
Je länger ich mich mit Programmierung beschäftige, desto klarer wird mir:
Verstehen beginnt dort, wo etwas nicht sofort funktioniert.
Erst im eigenen Ausprobieren entsteht Reibung – und damit Erkenntnis.
Code ist kein Gedankengebäude, sondern ein System, das sich der Realität stellen muss:
dem Browser, dem DOM, dem Timing, den Eigenheiten von Geräten und Nutzern.
Hier reicht es nicht, etwas verstanden zu haben.
Es muss sich bewähren.
Diese Grenze ist wichtig.
Und sie ist genau der Punkt, an dem KI bewusst zurücktreten muss.
Lernen findet nicht im Vakuum statt
Ich lerne nicht in einem geschützten Raum.
Es gibt Tage mit körperlich fordernder Arbeit, Verpflichtungen, Erschöpfung.
Diese Realität beeinflusst Konzentration, Geduld und die Art, wie man mit Widerstand umgeht.
In der Abgabephase wurde mir deutlich, wie wichtig es ist, dies zu bedenken –
nicht als Ausrede, sondern als Teil von Verantwortung.
Nachhaltiges Lernen braucht einen Rhythmus, der Belastung integriert, statt sie zu ignorieren.
Verantwortung statt Verbote
In Diskussionen über KI begegnen mir oft zwei Extreme: Euphorie oder Ablehnung.
Beides greift zu kurz.
Was es braucht, ist keine Verbotskultur, sondern eine Haltung.
Eine, die zwischen Unterstützung und Ersatz unterscheiden kann.
KI darf Denkprozesse begleiten, aber nicht ersetzen.
Sie darf erklären, aber nicht das eigene Ausprobieren überspringen.
Sie darf strukturieren, aber nicht die Auseinandersetzung abnehmen.
Diese Grenzen sind nicht immer scharf.
Aber sie lassen sich spüren, wenn man aufmerksam bleibt.
Schluss
Dieser Text ist kein Standpunkt, sondern eine Momentaufnahme.
Ein Versuch, eine Haltung zu beschreiben, während sie entsteht.
Ich lerne zu programmieren – und gleichzeitig lerne ich, wie ich lerne.
Mit Unterstützung, ja.
Aber nicht ohne Widerstand.
Wenn KI in diesem Prozess einen Platz hat, dann nicht als Abkürzung,
sondern als Begleiter auf einem Weg, der eigenständig gegangen werden muss.
Nicht schneller.
Aber bewusster.
8.–13. Dezember: Verdichtung, Pausen und struktureller Abschluss
Nicht jeder Fortschritt ist sichtbar.
Diese Tage waren geprägt von Pausen, Belastung außerhalb des Projekts
und einer abschließenden Phase der Verdichtung und Ordnung.
–
· Verdichtung • Pause • Struktur • Abschluss
1) Tage ohne Commit
Am 8. und 9. Dezember entstanden keine sichtbaren Änderungen im Repository.
Diese Tage waren geprägt von äußeren Verpflichtungen und körperlich
fordernder Arbeit außerhalb des Projekts.
Statt Fortschritt zu erzwingen, blieb die Entscheidung bewusst,
Belastung zu akzeptieren und Pausen nicht als Rückschritt zu deuten.
2) Abstand als Teil des Prozesses
Auch wenn kein Code entstand, lief der Prozess weiter.
Abstand erlaubt, Entscheidungen zu überprüfen,
Überfrachtung zu vermeiden und die eigene Arbeitsweise zu regulieren.
Nicht jeder Tag muss produktiv wirken,
um später tragfähig zu sein.
3) Rückkehr mit Ordnung und Lesbarkeit
Am 10. Dezember folgte eine bewusste Rückkehr ins Projekt
mit Fokus auf Struktur und Klarheit:
Lesbarkeit, Typografie und saubere Begrenzung für große Bildschirme.
Der Code wurde nicht erweitert,
sondern reduziert und geordnet –
Ballast entfernt, Entscheidungen gefestigt.
4) Abschluss ohne Abschlussdruck
Die letzten Tage bis zum 13. Dezember dienten der Klammer:
kleinere Styling-Korrekturen,
Header und Footer finalisieren,
nichts Neues beginnen.
Kein Gefühl von „fertig“,
aber ein Zustand, der trägt.
5) Fazit – Verdichtung statt Beschleunigung
Diese Phase markiert keinen Höhepunkt,
sondern einen ruhigen Abschluss.
Fortschritt zeigte sich nicht im Tempo,
sondern in der Fähigkeit,
Pausen zuzulassen und dennoch Struktur zu halten.
Genau darin liegt die Grundlage
für die nächste Etappe.
4.–7. Dezember: Reibung & Umsetzung – Anforderungen werden Oberfläche
Der Wiedereinstieg wird praktisch: Debugging, UI-Feinschliff und klare Leitplanken.
In diesen Tagen ging es weniger um neue Features, sondern um Tragfähigkeit:
Responsiveness, Scroll-Gefühl, Lesbarkeit und saubere Mobile-Details.
Ab dem 4. Dezember wurde der Arbeitsmodus konkret.
Nicht als Aufschwung, sondern als Reibung:
Dinge wirkten noch nicht zuverlässig,
Details verhielten sich unerwartet,
und genau dadurch wurden sie bearbeitbar.
Der Fokus lag auf Ursache statt Symptom
und auf Entscheidungen, die sich später nicht rächen.
2) Leitplanken der DA: nicht Dekoration, sondern Pflicht
In dieser Phase wurden Anforderungen sichtbar, die nicht „nice to have“ sind,
sondern zur Abgabequalität gehören:
Responsiveness (UI muss auf Mobile/Tablet/Desktop funktionieren)
Smooth Scrolling (sauberes Scroll- und Bewegungsgefühl)
Wide-Screen-Tauglichkeit (große Displays dürfen nicht „auseinanderlaufen“)
Lesbarkeit (Größen, Abstände, klare Hierarchien)
Die Herausforderung lag weniger im Ob,
sondern im Wie:
Anforderungen so umzusetzen, dass die Oberfläche ruhig bleibt.
3) Konkrete Umsetzung im Repo (GitHub)
04.12.2025
bd58d53 – Responsive: Cart- und Button-Mechanik
0679cb5 – Background-Hover für Artikel
72326b7 – Pulse-Feintuning (Speed/Scale) für „pro“ Klick-Feedback
c3ef156 – Bugfix: letztes Item verdeckt → Padding in templates.js
1aee125 – Footer
aa38f19 – Reaktion auf Bezahlen (payForOrder)
9b897f9 – SVG CloseCart (responsive)
c88e0e0 – Hover für CloseCart-Button
05.12.2025
8edd7fc – Smooth Scroll Behaviour, Search-Button vorerst deaktiviert (JS folgt später),
CloseCart nur Mobile
Diese Tage waren nicht „Feature-getrieben“,
sondern qualitätsgetrieben.
Viel Arbeit zeigt sich hier nicht in großen neuen Bausteinen,
sondern in Korrekturen, die man erst beim echten Benutzen bemerkt:
Abstände, Click-Feedback, Mobile-Details, Lesbarkeit.
Reibung ist nicht das Gegenteil von Fortschritt –
sie ist oft sein Beweis.
5) Fazit – Tragfähigkeit entsteht durch Details
Am Ende dieser Phase war nicht „alles fertig“,
aber vieles verlässlicher:
responsive Verhalten, klarere UI-Rückmeldungen,
ruhigeres Scroll-Gefühl und ein aufgeräumteres Debugging.
Nicht Geschwindigkeit war das Ziel,
sondern Substanz.
1.–3. Dezember · Wiedereinstieg
Kein Neubeginn, sondern ein Wiederanknüpfen.
In diesen Tagen kehrte weniger der Output zurück,
sondern die Fähigkeit, das Projekt wieder ruhig und tragfähig anzufassen.
–
· Wiedereinstieg • Projektarbeit • Fokus
1) Wiederanknüpfen statt Neustart
Der Wiedereinstieg Anfang Dezember war kein Neubeginn,
sondern ein Wiederanknüpfen.
Die Motivation war vorhanden –
was zurückkehren musste, war die Fähigkeit,
komplexe Dinge wieder anzufassen,
ohne sie zu beschleunigen oder zu vereinfachen.
2) Projekt öffnen, Modell prüfen
In diesen Tagen stand kein sichtbarer Fortschritt im Vordergrund.
Ich habe das Projekt geöffnet,
Code gelesen,
Strukturen geprüft
und Zusammenhänge reaktiviert.
Nicht mit dem Ziel, schnell voranzukommen,
sondern um sicherzugehen,
dass das innere Modell wieder trägt.
3) Fragen werden wieder technisch
Ein deutliches Zeichen für diesen Übergang:
Die Fragen wurden wieder technisch.
Nicht mehr ob etwas Sinn ergibt,
sondern warum sich ein DOM-Element so verhält,
wo Zuständigkeiten liegen
und was Ursache statt Symptom ist.
4) Richtung statt Tempo
Wichtig war mir in dieser Phase,
nichts aufzuholen und nichts zu beweisen.
Der Fokus lag auf Richtung,
nicht auf Tempo –
auf tragfähigen Schritten
statt auf sichtbarem Output.
5) Fazit – Übergang vollzogen
Mit dem 3. Dezember war dieser Übergang vollzogen.
Der Faden war nicht nur gehalten,
sondern wieder fest in der Hand.
Ab hier konnte Arbeit entstehen,
die Reibung zulässt
und deshalb trägt.
Zwischen Stillstand und Wachstum – warum Entwicklung auch Leerlauf braucht
Nicht jede Phase des Lernens ist sichtbar produktiv. Manchmal sitzt man
vor dem Bildschirm, bewegt nichts – und arbeitet dennoch.
Dieser Text ist ein Versuch, genau diesen Zwischenraum ernst zu nehmen.
· Lernen • Haltung • Entwicklung
1) Wenn Entwicklung nach außen still aussieht
Es gibt diese Momente, die jeder Entwickler kennt:
Man sitzt vor dem Bildschirm, tippt nichts,
klickt nichts, produziert nichts Sichtbares.
Von außen wirkt das wie Stillstand.
Von innen jedoch laufen Prozesse,
die sich kaum beschleunigen lassen:
Abwägen, Verwerfen, Neuordnen.
Lösungen entstehen nicht immer durch Aktion,
sondern oft durch Verdichtung.
Wer nur sichtbaren Output als Arbeit zählt,
verkennt einen großen Teil dessen,
was Entwicklung überhaupt möglich macht.
2) Dranbleiben heißt nicht immer „weitermachen“
In den letzten Wochen gab es Phasen,
in denen mein Fortschritt gering war.
Wenig Code, wenig neue Features,
wenig, das man vorzeigen könnte.
Und doch war genau hier eine Entscheidung notwendig:
dranbleiben – nicht heroisch,
nicht euphorisch, sondern nüchtern.
Dranbleiben kann heißen:
das Projekt nicht zu schließen
den Anspruch nicht zu verleugnen
das eigene Tief nicht zum Abbruchgrund zu machen
Diese Form von Kontinuität ist leise,
aber sie ist tragfähig.
3) Lernen ist stärker als der Schatten
Jede längere Lernphase bringt Schatten mit sich:
Zweifel, Trägheit, Selbstkritik,
manchmal auch Flucht in Ablenkung.
Entscheidend ist nicht,
ob diese Phasen auftreten –
sondern, wie man mit ihnen umgeht.
Mein Weg in dieser Zeit war kein makelloser.
Aber mein Wille zu lernen
war stärker als die Versuchung,
das Ganze innerlich abzuwerten.
Für mich ist das keine Schwäche,
sondern eine Kernkompetenz:
Lernen trotz Ambivalenz.
Technische Systeme werden oft auf Effizienz optimiert.
Menschen funktionieren anders.
Nachhaltiges Wachstum – auch wirtschaftlich –
berücksichtigt, dass Lernfähigkeit,
Kreativität und Belastbarkeit
nicht linear skalieren.
Phasen reduzierter Produktivität
sind kein Defizit,
sondern Teil eines gesunden Systems.
Wer sie ignoriert,
zahlt später den Preis –
mit Ausfällen, Fluktuation
oder stagnierender Innovation.
5) Das träge Unterbewusstsein als Arbeitsraum
Ein Teil des Lernens geschieht
nicht im bewussten Problemlösen,
sondern im Hintergrund.
Dieses „Datamining“ im Unterbewusstsein
birgt Risiken:
Unruhe, Zerstreuung,
das Gefühl, nichts zu kontrollieren.
Gleichzeitig schafft es etwas Wertvolles:
einen mentalen Freiraum,
in dem Ideen nicht erzwungen,
sondern gefunden werden.
Kreativität entsteht selten im Dauerlauf.
Sie braucht ein stabiles Fundament –
einen freien, belastbaren inneren Raum.
6) Fazit – Entwicklung ist mehr als Output
Diese Phase war kein Glanzstück
in Zahlen oder Ergebnissen.
Aber sie war Teil meines Weges
als Entwickler.
Nicht trotz ihrer Langsamkeit,
sondern gerade wegen ihr.
Lernen heißt nicht,
immer sichtbar voranzukommen.
Lernen heißt,
auch dann nicht auszusteigen,
wenn Fortschritt leise wird.
27. November: Gestaltung denken – wenn UI Entscheidungen erzwingt
Heute ging es weiterhin um Entscheidungen:
Wie fühlt sich eine App an? Wie bewegt sich ein Nutzer?
Und wie zwingt gutes UI zu klarer Struktur im Code?
· UI/UX • Interaktion • Systemdenken
1) Vom Code zum Nutzer
Heute war die Frage, wie sich die App für jemanden anfühlt, der sie benutzt.
Das ist ein anderer Denkmodus. Einer, der Code nicht isoliert betrachtet,
sondern als Mittel, um Entscheidungen sichtbar zu machen.
2) Toggle-Ideen und responsive Gedanken
Ein zentrales Thema war die Frage, wie Nutzer auf kleineren Screens
zwischen Menü und Warenkorb wechseln sollen.
Ein Toggle-Button – vielleicht ein X im Kreis, vielleicht
eine klare visuelle Geste – schien plötzlich nicht nur sinnvoll,
sondern notwendig.
Solche Entscheidungen sind nie rein visuell. Sie erzwingen Struktur
im Code, Zuständigkeiten und klare Zustandswechsel.
3) UI zwingt zur Ehrlichkeit
Heute wurde mir wieder bewusst, dass UI keine Unschärfen verzeiht.
Ein Nutzer merkt sofort, wenn etwas unklar ist – auch wenn der Code
technisch korrekt ist.
„Gutes UI entlarvt schlechte Logik.“
Diese Erkenntnis hat meine Sicht auf Frontend-Arbeit nachhaltig geprägt.
4) Systemdenken in Interaktionen
Jede Interaktion ist ein Zustand.
Jeder Zustand braucht Regeln.
Heute habe ich begonnen, Interaktionen nicht mehr als einzelne Events
zu sehen, sondern als Teil eines Zustandsmodells:
Menü sichtbar
Cart sichtbar
Beide sichtbar
Übergangszustände
Diese Denkweise verändert, wie man JavaScript schreibt.
5) Fazit – Gestaltung ist Zwang zur Klarheit
Der 27. November war ein kreativer Tag – aber kein chaotischer.
Im Gegenteil: Er hat Klarheit erzwungen.
Gute Gestaltung zwingt zu Entscheidungen.
Und gute Entscheidungen führen fast immer zu besserem Code.
26. November: Sprache schärfen – wenn präzises Denken im Code sichtbar wird
Heute ging es um Begriffe, Benennungen und innere Modelle.
Nicht viel Neues gelernt – aber vieles klarer formuliert.
Ein Tag, an dem Denken und Code wieder enger zusammengerückt sind.
· JavaScript • Präzision • Strukturdenken
1) Wenn Begriffe plötzlich wichtig werden
Heute habe ich gemerkt, dass sich mein Fokus verschoben hat:
Weg vom bloßen „Lösen“ von Problemen, hin zum präzisen
Benennen dessen, was eigentlich passiert.
Variablen, Funktionen, Zuständigkeiten – alles begann,
wieder stärker als Sprache zu wirken. Und Sprache entscheidet,
wie gut Denken transportiert werden kann.
2) Der Unterschied zwischen „funktioniert“ und „ist verstanden“
Ein wiederkehrendes Gefühl heute:
Code kann funktionieren, ohne wirklich verstanden zu sein.
Ich habe mir bewusst Zeit genommen, Stellen zu hinterfragen,
die ich zuvor einfach akzeptiert hätte:
Warum heißt diese Variable so?
Welche Verantwortung trägt diese Funktion wirklich?
Ist das hier Logik – oder nur ein Workaround?
Diese Fragen sind unbequem, aber sie markieren den Übergang
vom Anwenden zum Beherrschen.
3) Mentales Refactoring
Interessanterweise habe ich heute weniger Code refactored,
dafür aber viel im Kopf umgebaut.
„Wenn du den Code nicht erklären kannst, hast du ihn noch
nicht wirklich geschrieben.“
Dieser Gedanke hat mich den ganzen Tag begleitet.
Verstehen heißt erklären können – notfalls mir selbst.
4) Der eigene Lernmodus wird sichtbar
Heute wurde mir bewusst, dass ich mich in eine neue Phase
bewege: Ich lerne nicht mehr primär durch neue Themen,
sondern durch Vertiefung.
Das fühlt sich weniger spektakulär an, ist aber deutlich nachhaltiger.
Es ist die Phase, in der aus Wissen Kompetenz wird.
5) Fazit – Klarheit ist Fortschritt
Der 26. November war ruhig, konzentriert und unspektakulär –
und genau deshalb wertvoll.
Kein neues Feature, kein großer Aha-Moment.
Aber mehr Klarheit, bessere Sprache, stabileres Denken.
Und das ist oft der entscheidende Schritt nach vorn.
25. November: Wieder im Flow – Struktur denken, nicht nur reparieren
Heute war wieder ein echter Arbeitstag: Code lesen, Logik hinterfragen,
Zusammenhänge erkennen. Nicht hektisch, aber klar fokussiert – der Flow
war zurück.
· JavaScript • Struktur • Lernprozess
1) Der Unterschied zwischen „wieder da“ und „wirklich da“
Nach den stabilisierenden Tagen zuvor hat sich heute etwas verändert:
Ich war nicht mehr nur präsent, sondern wieder aktiv denkend.
Der Code fühlte sich nicht fremd an. Im Gegenteil – ich konnte ihn
lesen, hinterfragen und an mehreren Stellen gleichzeitig denken,
ohne innerlich aus dem Tritt zu geraten.
2) Vom Fixen zum Verstehen
Heute ging es weniger darum, konkrete Fehler zu „fixen“, sondern
darum, Muster zu erkennen:
Warum ist diese Funktion hier?
Welche Annahmen stecken hinter dieser Logik?
Was würde passieren, wenn sich die Daten ändern?
Das ist ein anderes Arbeiten als am Anfang meiner Lernreise.
Weniger reaktiv, mehr strukturell.
3) JavaScript als Sprache, nicht als Werkzeugkiste
Ein wichtiger Gedanke des Tages:
Ich benutze JavaScript immer weniger als Sammlung einzelner Tricks
und immer mehr als zusammenhängende Sprache.
Bedingungen, Rückgabewerte, Funktionen und Datenmodelle beginnen,
sich wie Teile eines Ganzen zu verhalten – nicht wie isolierte Lösungen.
„Wenn man aufhört, nach Syntax zu suchen, fängt man an,
Logik zu sehen.“
4) Konzentration ohne Druck
Auffällig war heute auch die Art der Konzentration:
ruhig, ohne Stress, ohne das Gefühl, etwas erzwingen zu müssen.
Ich habe gemerkt, dass mein Umgang mit Unsicherheit sich verändert:
Nicht mehr sofortiger Widerstand, sondern Neugier.
5) Fazit – Ein still produktiver Tag
Der 25. November war kein spektakulärer Tag mit großen Features.
Aber er war produktiv auf die richtige Weise:
Verständnis vertiefen, Zusammenhänge sehen, Vertrauen ins eigene
Denken zurückgewinnen.
Genau diese Tage bauen langfristige Kompetenz auf.
24. November: Zurück in die Struktur – Vertrauen ins System wiederfinden
Nach dem Kontrollverlust des Vortags ging es heute nicht um Tempo,
sondern um Stabilität: Ordnung herstellen, Vertrauen zurückgewinnen
und den Fokus behutsam wieder auf Code lenken.
· Stabilisierung • Struktur • Bestell-App
1) Der erste Schritt zurück: Überblick statt Aktion
Nach der Kernel Panic vom Vortag war klar: Heute ist kein Tag für
Experimentierfreude. Stattdessen ging es darum, wieder Vertrauen
in mein Setup und meine Werkzeuge zu bekommen.
Ich habe mir bewusst Zeit genommen, das Projekt zu öffnen,
ohne sofort etwas ändern zu wollen. Erst schauen. Erst lesen.
Erst wieder ankommen.
2) Struktur wirkt beruhigend
Interessanterweise stellte sich die Ruhe nicht durch „Lösen“ ein,
sondern durch Struktur.
Dateien überfliegen
Ordnerlogik nachvollziehen
Benennungen prüfen
Zusammenhänge wiedersehen
Das System war nicht kaputt. Es hatte mich nur kurz daran erinnert,
wie tief es eigentlich ist.
3) Zurück zur Bestell-App – mit verändertem Blick
Erst gegen später habe ich mich wieder aktiv mit der Bestell-App
beschäftigt. Nicht, um Features zu bauen, sondern um zu prüfen,
ob meine mentale Landkarte noch stimmt.
Und sie stimmte.
Die Logik war da. Die Struktur war da.
Der Fokus ließ sich wieder herstellen.
4) Ein leiser Perspektivwechsel
Der gestrige Tag hatte etwas verschoben:
Ich habe heute bewusster wahrgenommen, dass Stabilität
kein Selbstläufer ist.
„Produktivität beginnt dort, wo Vertrauen in die Werkzeuge besteht.“
Das gilt für Betriebssysteme genauso wie für den eigenen Kopf.
5) Fazit – Wieder Boden unter den Füßen
Der 24. war kein lauter Tag.
Aber er war notwendig, um den Boden wieder zu spüren.
Morgen darf es wieder konkreter werden.
Heute ging es darum, Stabilität nicht zu erzwingen,
sondern sie langsam zurückkehren zu lassen.
23. November: Kernel Panic – wenn das System unter den Füßen verschwindet
Ein Screenshot, ein schwarzer Bildschirm, kryptische Meldungen.
Heute ging es nicht um JavaScript oder UI, sondern um das Fundament:
das Betriebssystem selbst – und das Gefühl, plötzlich ganz unten zu stehen.
· Linux • Systemverständnis • Kontrolle
1) Der Moment, in dem nichts mehr geht
Heute hatte ich zum ersten Mal bewusst mit einer Kernel Panic
zu tun. Kein sanfter Fehler, kein Stacktrace, kein Hinweis darauf,
wo ich anfangen könnte zu suchen.
Stattdessen: ein eingefrorener Bildschirm, kryptische Zeilen,
und das Gefühl, dass das System unter mir einfach weggezogen wurde.
2) Wissen aus der Tiefe des Gedächtnisses
Irgendwo ganz hinten im Kopf tauchte ein Begriff auf:
REISUB.
Eine Tastenkombination aus alten Linux-Zeiten, gedacht für genau
solche Situationen – um ein System kontrolliert neu zu starten,
selbst wenn es nicht mehr reagiert.
In diesem Moment wurde mir klar, wie viel Wissen nicht aktiv,
sondern latent vorhanden ist. Es schläft, bis es gebraucht wird.
3) Die Grenze zwischen Nutzer und System
Eine Kernel Panic ist etwas völlig anderes als ein Programmfehler.
Hier gibt es keine Fehlermeldung, die man „versteht“, kein
freundliches Debugging.
Man steht an der Grenze:
„Ab hier bist du nicht mehr Anwender – ab hier beginnt das System selbst.“
Dieser Gedanke hat mich mehr beschäftigt als die Ursache des Problems.
4) Demut vor der Tiefe der Technik
Heute wurde mir wieder bewusst, wie viele Schichten unter dem liegen,
womit ich mich normalerweise beschäftige.
Frontend
JavaScript-Engine
Betriebssystem
Kernel
Und jede dieser Schichten folgt eigenen Regeln.
Man kann sehr kompetent sein – und trotzdem plötzlich völlig
handlungsunfähig wirken.
5) Fazit – Kontrollverlust als Lernmoment
Der heutige Tag war unangenehm, aber lehrreich.
Nicht, weil ich das Problem gelöst habe,
sondern weil ich gesehen habe, wo meine Grenzen aktuell liegen.
Programmieren bedeutet nicht nur, Kontrolle zu gewinnen,
sondern auch zu akzeptieren, dass es Ebenen gibt,
die man (noch) nicht beherrscht.
Und genau dort beginnt oft das nächste Lernfeld.
22. November: Ein Tag der Langsamkeit – Körper, Chemie und das stille Wissen über Balance
Heute stand das Coden im Hintergrund. Stattdessen ging es um Gesundheit,
um Ursachen und Wirkungen im Körper – und um die Erkenntnis, dass
Regeneration genauso viel Teil des Weges ist wie Lernen.
· Gesundheit • Lernen • Balance
1) Wenn das Leben den Fokus neu setzt
Der Tag begann nicht mit JavaScript, sondern mit einer medizinischen
Frage: Was ist Fluconazol?
Eine kleine, unscheinbare Tablette – aber mit einer Wirkung, die direkt
in die Biochemie eingreift.
Lua und ich hatten beide Symptome, und plötzlich war der Fokus nicht
mehr Variablen-Benennung, sondern:
„Was passiert eigentlich in meinem Körper?“
2) Wenn man eine Krankheit versteht, verliert sie ihren Schrecken
Ich habe mich mit dem Wirkmechanismus beschäftigt:
Wie Fluconazol Pilze nicht „abtötet“, sondern ihnen einen zentralen
Baustein der Zellmembran entzieht.
Ein wissenschaftlicher Blick – aber auch ein beruhigender.
Man versteht:
Es ist ein geregelter Prozess, kein dunkles Unbekanntes.
3) Slow Day – und warum er trotzdem wertvoll war
Technisch ist heute nichts passiert. Kein Code, kein neues Feature,
keine komplexe Erkenntnis.
Und dennoch war es ein Tag des Lernens:
Wie wichtig Ruhe ist, bevor Überlastung entsteht.
Wie eng körperliche Gesundheit und geistige Klarheit verbunden sind.
Wie schnell der Kopf mitfiebert, wenn der Körper aus dem Gleichgewicht ist.
Der Tag hatte eine Einfachheit, die selten geworden ist.
4) Ein leiser Gedanke über Balance
Während ich mich mit den Informationen zu Fluconazol beschäftigt habe,
kam dieser Gedanke hoch:
„Programmieren ist wie Körperchemie:
Wenn ein kleines Teil aus der Balance gerät, verändert sich das ganze System.“
Es war ein unerwarteter Gedanke – aber er passt.
Auch beim Coden sind es nicht die großen Fehler, die Systeme instabil machen,
sondern die kleinen Dinge, die übersehen werden.
5) Fazit – Ein unerwarteter, aber notwendiger Tag
Heute war kein Lernfortschritts-Tag und auch kein produktiver Tag
im klassischen Sinne.
Aber er war notwendig.
Meine Energie wird zurückkommen.
Die nächsten Tage gehen weiter – aber heute durfte der Körper entscheiden.
21. November: Ternary-Verständnis, Funktionslogik und ein Schritt zu mehr Klarheit
Heute habe ich mich tief in den Ternary-Operator, Wahrheitswerte,
Bedingungslogik und den Fluss von Funktionen hineingedacht – und gemerkt,
wie viel auf den ersten Blick einfache Syntax wirklich transportiert.
· JavaScript • Logik • Verständnis
1) Der Tag beginnt mit einer Frage: „Was prüft der Ternary eigentlich wirklich?“
Es begann mit einer scheinbar einfachen Frage:
Prüft der Ternary wirklich nur true/false,
oder steckt mehr dahinter?
Und genau hier wurde es spannend. Ich habe verstanden:
Der Ternary prüft keine Werte – er prüft Wahrheitsgehalte.
Alles ist „truthy“ oder „falsy“:
undefined, null, 0,
leere Strings, NaN → alle führen in den false-Zweig.
Diese Erkenntnis hat mir das Denken in Bedingungen dauerhaft erleichtert.
2) Der Moment, in dem Logik plötzlich „klackt“
Ein wichtiger Aha-Moment heute: Zu verstehen, dass der Ternary nicht
nur ein Kürzel für if/else ist, sondern ein Ausdruck,
der zurückgibt – er produziert Werte.
Das heißt:
Ternary kann Variablen zuweisen
Ternary kann Funktionsaufrufe auslösen
Ternary kann sogar Templates oder komplexe Ausdrücke bauen
Das hat die Art geändert, wie ich Logik strukturiere.
3) Die tiefere Einsicht: Warum manche Dinge klappen – und andere nicht
Was heute besonders hängen blieb, war der Zusammenhang zwischen
Existenz und Intention.
Ein Wert kann existieren, aber trotzdem „falsy“ sein.
Ein Wert kann nicht existieren und dennoch in Bedingungen indirekt
weitergereicht werden.
Dieser kleine Denkfehler war der Grund für mehrere Stunden Unsicherheit.
„Er prüft nicht, ob die Variable existiert – er prüft, wie sie sich verhält.“
4) Mehr Sicherheit in Funktionsfluss und Fehlersuche
Heute habe ich außerdem begriffen, warum mein Gehirn manchmal auf
„Syntaxfehler“ reagiert, obwohl der Code technisch korrekt ist:
Manchmal fehlt nur ein mentales Modell, nicht eine Zeile Code.
Und plötzlich wurde klar:
Der Ternary ist ein Werkzeug – aber nur dann, wenn die Logik
dahinter verstanden ist.
5) Fazit – Ein Tag, der Denkkraft statt Codezeilen erzeugt hat
Heute ist nicht viel Sichtbares entstanden – aber unglaublich viel
Unsichtbares: Verständnis, Klarheit, Struktur.
Diese Art von Tag ist selten, aber wichtig:
Nicht produktiv im klassischen Sinn, sondern produktiv im Kopf.
Morgen geht es wieder mehr ins Konkrete – aber die Tiefe von heute
wird dort den Unterschied machen.
20. November: Strukturdenken, Fehlerkultur und das unsichtbare Fundament einer App
Heute stand weniger das Schreiben von Code im Mittelpunkt als das
Verstehen von Systemen: Datenmodelle, Fehlerursachen und die Frage, warum
manche Bugs erst durch ein bestimmtes Bewusstsein sichtbar werden.
· Systemdenken • Debugging • JavaScript
1) Der Tag beginnt mit einer Frage: Warum tun Systeme, was sie tun?
Heute habe ich mich nicht hingesetzt, um „ein Feature zu bauen“,
sondern um etwas sehr Grundsätzliches zu verstehen:
Wie verhalten sich Systeme, wenn man ihnen nicht genug Struktur gibt?
Dabei fiel mir auf, dass ich gerade in den letzten Tagen viel über
kleine Fehler gesprochen habe – aber heute ging es darum, die
Mechanik hinter den Fehlern zu begreifen.
2) Der unscheinbare Fehler als Spiegel
Ein wiederkehrendes Thema: Ein kleiner Logikfehler oder ein minimaler
Benennungsunterschied reicht aus, um das ganze System aus dem Tritt zu
bringen.
Es ist, als ob das System mir etwas sagen will:
„Ich bin konsistent, solange du konsistent bist.“
Dieser Gedanke hat heute mehr mit mir gemacht als jede Zeile Code.
3) Was bedeutet „Verstehen“ beim Coden?
Verstehen heißt nicht, dass ich weiß, warum Code funktioniert.
Verstehen heißt, die Prinzipien zu erkennen, die unabhängig vom
konkreten Projekt gelten:
Struktur schlägt Intuition.
Konsistenz schlägt Komplexität.
Einheitliche Modelle schlagen Ad-hoc-Lösungen.
Das ist eine Art von Wissen, die sich langsam prägt – und nur
an solchen Tagen überhaupt die Chance hat zu entstehen.
4) Zwischen Technik und Philosophie
Während ich über Datenmodelle und Fehlerursachen nachgedacht habe,
kam ein interessanter Gedanke hoch:
„Systeme sind wie Menschen: Sie reagieren nicht auf das, was du willst,
sondern auf das, was du tatsächlich tust.“
Ein Name, der nicht passt. Ein Index, der nicht existiert.
Ein Wert, der nicht geprüft wird.
Alles kleine Beispiele für dieselbe Wahrheit:
Ein System kennt keine Absicht – nur Ausführung.
5) Fazit – Ein Tag der Klärung
Ich habe heute nicht viel „gebaut“, aber sehr viel verstanden.
Der Tag war wie ein Gespräch mit dem System selbst:
Wo bist du klar? Wo bin ich unklar? Wo müssen wir uns gegenseitig
besser lesen?
Morgen geht es wieder stärker ins konkrete Coden – aber heute war
ein wichtiger Schritt zurück zu strukturiertem Denken.
19. November: Der Fokus ist zurück – kleine Fehler, große Einsichten
Der Tag, an dem das Denken wieder scharf wurde: Variablen,
Datenmodelle, String-Konsistenz – und die Erkenntnis, dass kleine
Inkonsistenzen oft der Schlüssel zu großen Aha-Momenten sind.
· JavaScript • Datenmodelle • Erkenntnisse
1) Ein kleiner Trigger – und plötzlich ist der Fokus zurück
Heute passierte etwas Typisches: Ein winziger Fehler im Code löste eine
überproportional große Kaskade an Verstehen aus. Genau so funktionieren
viele meiner Lernsprünge.
Die Ursache war ein scheinbar belangloser String, der nicht exakt
dem erwarteten Muster entsprach. Doch aus diesem Mini-Problem entstand
ein ganzer Gedankengang über Konsistenz, Naming-Conventions und die
Fragilität von gereihten Bedingungen.
2) Variablen-Benennung – mehr als nur Ästhetik
Ich habe mich heute tiefer mit der Frage beschäftigt, warum konsistente
und präzise Variablen-Namen nicht nur „nett“, sondern fundamental sind.
Klarheit → weniger mentale Last
Konsistenz → weniger Fehlerquellen
Lesbarkeit → Zukunftssicherheit
Ein vermeintlich lächerlicher Unterschied von 3–4 Zeichen kann der
Unterschied sein zwischen einem sauberen Flow und einer Stunde Debugging.
3) Die philosophische Dimension des Debuggens
Während ich den Fehler betrachtete, kam ein Gedanke auf: Systeme
zeigen dir, wie sie funktionieren wollen. Die Aufgabe beim Programmieren
ist nicht, das System zu zwingen, sondern zu verstehen, wie es
logisch und harmonisch zusammenwirkt.
Bevor du beweist, dass ein Flugzeug fliegt, akzeptiere, dass es fliegt.
Dieser Satz, der heute unbewusst auftauchte, beschreibt meine Beziehung
zur Software ganz gut: Erst akzeptieren, dann analysieren.
4) Vom Fehler zur Einsicht – das Muster
Der Tag folgte einem vertrauten inneren Ablauf:
Ein kleiner Fehler macht etwas Großes sichtbar.
Der Geist wehrt sich kurz – dann öffnet er sich.
Die Struktur dahinter wird klar.
Und ein Stück tieferes Verständnis stabilisiert sich.
Heute war es das zentrale Thema der Konsistenz.
5) Fazit – Der 19. war kein Coding-Tag, sondern ein Einsichts-Tag
Ich habe heute nicht viele Zeilen Code geschrieben. Aber ich habe ein
wichtiges Prinzip tiefer verstanden: Dass Systeme nicht durch Größe
wachsen, sondern durch Klarheit.
Der Fokus ist eindeutig zurück. Und ab morgen geht es wieder
wirklich ans Entwickeln.
16.–18. November: Die Rückkehr zur Klarheit – Konzepte schärfen, Fehler verstehen, Fokus zurückgewinnen
Drei Tage zwischen Aufwachen und Wiederfinden. Noch nicht voller
Geschwindigkeit, aber klar im Aufwärtstrend: Strukturen wurden sortiert,
JavaScript-Konzepte verinnerlicht, und die Bestell-App rückte erneut ins Zentrum
des Lernens.
· JavaScript • Bestell-App • Lernprozess
1) 16. November – Erste Aktivierung nach der Pause
Der 16. war einer dieser Tage, an denen der Motor wieder anspringt,
aber noch nicht rund läuft. Ich habe mich erneut in die Struktur der
Bestell-App eingelesen und versucht, die vorhandenen Datenmodelle und
UI-Elemente wieder zu verknüpfen.
Es war ein Tag des „inneren Sortierens“: Wo bin ich im Modul? Was
brauche ich als Nächstes? Welche offenen Fragen schlummern im Code?
Noch wenig Output, dafür viel Neuorientierung – ein notwendiger Schritt,
um wieder Fokus aufzubauen.
2) 17. November – Die Konzepte beginnen wieder zu greifen
Der 17. brachte deutlich mehr Energie. Ich habe mich intensiver mit
wiederkehrenden JavaScript-Konzepten beschäftigt: Datenbereinigung,
String-Vergleiche, IDs, und die wichtige Frage, wie man Strukturen so
baut, dass sie nicht bei der kleinsten Inkonsistenz kollabieren.
Aus dieser Phase stammt auch eine Einsicht, die sich durch den ganzen
Monat ziehen wird:
Ein System ist so stark wie seine kleinste, vermeintlich triviale
Verbindung.
Ich begann außerdem, wieder bewusster über das Zusammenspiel von
Logik und Darstellung nachzudenken. Die App wurde langsam wieder
zum Projekt, nicht nur zur Übungsaufgabe.
3) 18. November – Das Denken wird wieder scharf
Am 18. war der Fokus endgültig zurück. Ich merkte es daran, dass
meine Fragen präziser wurden: Warum funktioniert ein Ausdruck?
Was bedeutet Konsistenz im Datenmodell wirklich? Welche Fehler führen
zu welchen Symptomen?
Außerdem nahm das strukturelle Denken wieder Fahrt auf:
Wie baut man Templates? Wie sichert man UI-Elemente gegen Fehler ab?
Und wie sorgt man dafür, dass man den eigenen Code später versteht –
nicht nur jetzt?
Dieser Tag markierte den Übergang vom passiven „Wiederfinden“ zum
aktiven Entwickeln. Der Fokus war wieder da.
4) Fazit – Vom Leerlauf zurück ins Fließen
Diese drei Tage waren wie das Anfahren eines schweren Fahrzeugs:
Zuerst ruckelt es, dann setzt es sich langsam in Bewegung, und
schließlich läuft es wieder stabil.
Ich habe den Wiedereinstieg gefunden – nicht durch große Features,
sondern durch das Schärfen der Grundlagen. Ab hier wird das Lernen
wieder konkret, und ab Morgen beginnt eine neuer Weg.
13.–15. November: Die stillen Tage – Struktur finden, Fehler verstehen, Oberfläche formen
Drei unscheinbare Tage zwischen Pause und Neubeginn. Datenmodelle,
UI-Feinschliff und das Gefühl, dass sich im Hintergrund wieder etwas ordnet –
auch wenn sich die Schritte klein anfühlten.
· Bestell-App • Lernprozess
1) 13. November – Rückkehr ins Modul 7
Nach einer Phase mit wenig Fokus auf die Bestell-App fühlte sich dieser
Tag wie ein vorsichtiges Wiedereintauchen an. Das Projekt war nicht fremd,
aber es hat mich getestet: Ein kleiner, beinahe lächerlich wirkender Fehler
im Datenmodell zeigte mir, wie wichtig exakte Konsistenz ist.
category.id und menu.category müssen exakt
übereinstimmen – logisch, und doch der Auslöser für mein wichtigstes Aha
dieses Tages. Solche Fehler sind wie kleine Spiegel: Sie zeigen, wie
empfindlich Systeme reagieren, wenn ein Konzept nicht sauber durchgezogen wird.
Es war kein spektakulärer Tag, aber einer, der das Fundament neu gesetzt hat:
Wieder ankommen. Wieder Verantwortung übernehmen. Wieder Ordnung finden.
2) 14. November – Schleifen, Templates und das Bedürfnis nach Ordnung
Dieser Tag war geprägt von der Frage: „Wie bekomme ich wieder Struktur in
mein Denken?“ Die Antwort fand ich im Coden selbst: forEach,
map, kleine Hilfsfunktionen und der Beginn eines
wiederverwendbaren Template-Systems.
tplMenuItem() und tplCartRow() entstanden als erste feste
Bausteine. Es fühlte sich an, als würde ich Werkzeug schmieden, nicht einfach
Code schreiben. Mit jedem Template wuchs das Gefühl, dass das Projekt wieder
ein System wird – eines, das logisch lebt.
Gleichzeitig schwang Unsicherheit mit: Verstehe ich JavaScript tief genug?
Aber genau diese Frage ist ein Zeichen von Wachstum, nicht von Schwäche.
3) 15. November – Die Oberfläche wird wieder sichtbar
Heute drehte sich alles um UI und das Zusammenspiel von Design und Logik.
Der Sticky Cart rückte in den Mittelpunkt: position: sticky,
top-Werte, Scrollzonen, Typografie, Abstände.
Es war der Moment, in dem ich die App wieder „als App“ wahrnahm – nicht nur
als Datenverarbeitung. Die Oberfläche bekam Charakter. Die UI begann,
mit der Logik zu kommunizieren.
Und damit kam eine essentielle Frage zurück:
Was gehört ins CSS und was ins JS?
Diese Unterscheidung begleitet mich seit dem Kochwelt-Projekt und bleibt
eine der Grundkompetenzen im Frontend.
4) Fazit – Die stille Kalibrierung
Diese drei Tage waren nicht laut. Aber sie waren entscheidend.
Es waren Tage der Rekalibrierung: Fehler verstehen, Strukturen festigen,
das UI wieder aufbauen – und innerlich den Widerstand gegen die eigene
Lethargie annehmen.
Wachstum findet nicht nur in großen Features statt. Oft beginnt es genau
hier: in den leisen Bewegungen, in denen der Geist sich wieder ausrichtet.
12. November 2025
Heute stand Stillstand auf dem Plan – zumindest äußerlich.
Kein Code, kein Fortschritt. Doch manchmal ist genau das der Moment,
in dem sich das Denken neu sortiert.
Heute habe ich nichts geschafft. Kein Commit, kein Code, keine Übung.
Nur Alltag: Internetanbieter am Telefon, Glasfaser-Diskussionen,
Warteschleifen, kleine Entscheidungen, die Energie ziehen.
Wenigstens habe ich diesen Blog geupdatet.
Trotzdem war der Tag nicht leer. Ich merkte, wie sich mein Denken verändert hat.
Früher hätte ich mich über „verlorene Zeit“ geärgert.
Heute sehe ich sie als Teil des Prozesses.
Entwicklung braucht Leerlauf – wie ein Prozessor, der kurz abkühlt,
bevor er wieder effizient arbeitet.
Zwischengedanken
Es ist okay, Pausen nicht zu füllen.
Motivation ist kein Dauerzustand – sie pulsiert.
Ein fauler Tag kann trotzdem Ordnung im Kopf schaffen.
Nebenbei dachte ich über Aufwand und Nutzen nach:
Glasfaser klingt verlockend, aber manchmal ist es wie mit Frameworks –
schön zu haben, aber selten der eigentliche Engpass.
Vielleicht war das die Lehre des Tages:
Nicht jeder Fortschritt ist sichtbar,
aber jeder Gedanke, der Ruhe findet, macht Platz für den nächsten Schritt.
Morgen geht’s weiter – mit Code, Cart und Klarheit.
9.-11. November 2025
Ein Wochenende zwischen Welten: Tamriel, Azeroth und JavaScript.
Spiele, Systeme, Muster – und die Erkenntnis, dass Denken überall gleich funktioniert.
Manchmal muss man raus aus dem Code, um ihn wieder mit klaren Augen zu sehen.
Dieses Wochenende war so eins. Ich verbrachte Stunden in ESO, experimentierte mit
Set-Kombinationen, und landete später sogar kurz in WoW – wo mich die eigene Ungeduld
und die Mechanik zugleich an JavaScript erinnerten: Wer den Loop nicht versteht,
verliert Kontrolle über den Flow.
Besonders spannend war der Moment, in dem mir auffiel, wie ähnlich
Systemdenken in Spielen und im Coden funktioniert:
Man beobachtet Muster, sucht Engpässe, optimiert Werte, testet Varianten.
In ESO heißen sie „Buffs und Debuffs“, in JavaScript „States und Events“.
Parallelen zwischen Gaming & Coding
Iteration: Jeder Build, jede Funktion durchläuft Loops – bis sie sich „richtig“
anfühlt.
Synergie: Gutes Zusammenspiel entscheidet – im Teamfight wie im DOM.
Feedback: Zahlen lügen selten, aber das Gefühl entscheidet, ob ein System lebendig
wirkt.
Das kleine WoW-Debakel (Login-Chaos, Versions-Mismatch, Frust) war fast lehrreich:
Selbst große Systeme stolpern, wenn Abhängigkeiten nicht klar gepflegt werden.
Versioning, Caching, Session-State – plötzlich klingt es wieder nach Webentwicklung.
Fazit
Spiele sind Simulationen, Code ist Konstruktion.
Beides lebt vom Verstehen innerer Zusammenhänge.
Ich merke immer deutlicher, dass Lernen keine Disziplin braucht,
sondern Neugier auf Systeme – egal ob im Backend, im Frontend
oder in einem Dungeon.
Dieses Wochenende war kein Rückschritt, sondern ein Perspektivwechsel:
Ich spiele, also denke ich modular.
8. November 2025
Feinschliff-Tag: Warum data-* im UI oft besser ist als id,
wie der Warenkorb mit localStorage überlebt, und wieso gute A11y
mit klarem Fokusfluss beginnt.
Heute habe ich mich um die stillen Dinge gekümmert: Attribute, Fokus, Persistenz.
data-* fühlt sich für wiederholte UI-Elemente (Buttons je Menüpunkt)
natürlicher an als starre ids – keine Kollisionen, saubere Delegation.
data-* vs. id – klare Zuständigkeiten
id: Einzigartige Anker im Dokument (z. B. #header,
#cart).
data-*: Semantische Daten für viele gleichartige UI-Elemente
(z. B. Buttons je Produkt).
Es war kein Feature-Feuerwerk, aber die App fühlt sich erwachsener an:
reproduzierbares Verhalten (data-Attribute), überlebender Warenkorb (Persistenz),
respektvolle Kommunikation (A11y).
Genau diese Schichten machen das Frontend „ehrlich“.
7. November 2025
Der Warenkorb erwacht: data-id statt starrer IDs, ein schlanker
CART-State und klare Add/Remove-Hooks. Kleine Funktionen, große Wirkung.
Heute lag der Fokus auf dem Kern jeder Bestell-App: dem Cart.
Ich habe mich bewusst für data-* entschieden (statt hart verdrahteter IDs),
weil die Buttons so wiederverwendbar bleiben und Events über Delegation
superleicht zu handhaben sind.
Wiederverwendbarkeit: Viele gleichartige Buttons, kein ID-Konflikt.
Delegation: Ein globaler Listener, funktioniert auch für dynamisch gerenderte Items.
Klarheit: Die Bedeutung steckt im Attribut; HTML bleibt semantisch sauber.
Gefühl am Ende: Leicht. Die Architektur trägt, die Funktionen sind klein (und bewusst so gehalten),
und das System ist erweiterbar: Mengenfelder, Sticky-Cart, Persistenz über localStorage –
alles jetzt gut andockbar.
6. November 2025
Heute klickte etwas im Kopf: Arrow Functions.
Kurzer Code, klare Struktur, und plötzlich fühlt sich JavaScript an
wie Sprache – nicht mehr wie Grammatik.
Es begann harmlos: ein paar Zeilen zur Formatierung von Text und Zahlen.
Ich wollte verstehen, was hinter dieser kryptischen Syntax steckt,
die überall auftaucht – Pfeile, Klammern, Backticks.
Aber dann machte es klick.
Arrow Functions verstehen
Früher war JavaScript für mich ein Raum voller Klammern und Kommas.
Heute entdeckte ich, dass () => {} nicht nur eine Abkürzung ist,
sondern eine Haltung – kompakt, lesbar, funktional.
// Klassisch:
function greet(name) {
console.log('Hallo ' + name + '!');
}
// Modern:
const greet = name => console.log(`Hallo ${name}!`);
// Mit Index:
const list = ['JS', 'CSS', 'HTML'];
list.forEach((t, i) => console.log(`${i + 1}. ${t}`));
Die Magie passierte, als ich padStart() kennenlernte.
Ein einfacher Befehl – aber mit Stil.
Es fühlte sich an, als würde ich meinen eigenen Rhythmus im Code finden:
weniger Ballast, mehr Bedeutung.
Und plötzlich war JavaScript nicht mehr nur Werkzeug, sondern Ausdruck.
Template Strings – Text mit Herz
Ich erkannte, wie stark Backticks (`) sind.
Kein Durcheinander mehr aus Anführungszeichen und Pluszeichen –
einfach klare Struktur:
const user = 'Quirin';
const time = new Date().toLocaleTimeString();
console.log(`${time} – Willkommen zurück, ${user}!`);
Diese kleinen Dinge verändern das Denken.
Ich beginne, in Mustern zu sehen, nicht in Befehlen.
Arrow Functions sind nicht „neu“ – sie sind natürlicher.
Reflexion
Ich merke, dass sich Stilgefühl nicht nur in Design ausdrückt,
sondern auch in Syntax.
Heute habe ich begonnen, nicht nur zu verstehen, wie etwas funktioniert,
sondern warum es sich richtig anfühlt.
Morgen will ich den nächsten Schritt gehen – den Warenkorb wirklich lebendig machen.
Aber heute: ein stilles => und ein kleines Lächeln.
5. November 2025
Heute stand Ordnung im Mittelpunkt: Der vertikale Split zwischen Menü und Warenkorb.
Ein Stück Architekturarbeit im Kleinen – mit klarerem Code, Guards und Layoutdisziplin.
Nach den visuellen Tagen kam heute wieder reines Handwerk:
Ich wollte den Content vom Cart trennen,
um die Struktur der Bestell-App endlich klar zu definieren.
Es war ein Tag voller kleiner, aber entscheidender Korrekturen.
Die größte Erkenntnis kam direkt am Anfang:
Der alte Fehler Cannot set properties of null war nicht „beseitigt“,
sondern nur übergangen. Ich beschloss, das Thema endgültig zu verstehen –
und meinen Code so zu schreiben, dass er nicht nur funktioniert, sondern stabil bleibt.
Rendering mit Guard, strukturiert und lesbar
function renderMenu() {
const host = document.querySelector('#menu-content');
if (!host) {
console.warn('⚠️ #menu-content fehlt, Render abgebrochen');
return;
}
const ITEMS = menu.items;
let html = '';
let current = null;
for (const it of ITEMS) {
if (it.category !== current) {
current = it.category;
html += `<h3>${current}</h3>`;
}
html += `
<article class="menu-item">
<h4>${it.name}</h4>
<p>${it.desc}</p>
<p class="price">CHF ${(it.priceCents / 100).toFixed(2)}</p>
</article>`;
}
host.innerHTML = html;
}
Parallel dazu begann ich mit dem Layout-Split:
ein flexibles Container-Design, in dem das Menü links
und der Warenkorb rechts stehen – skalierbar und mobilfreundlich.
Ich hatte kurz überlegt, auf grid umzusteigen,
entschied mich aber bewusst für flex:
Es zwingt mich, in Flüssen zu denken, nicht in Tabellen.
Reflexion
Dieser Tag fühlte sich wie Aufräumen an – strukturell, gedanklich, visuell.
Kein Feature, kein Effekt, nur Klarheit.
Und vielleicht ist das genau das, was gute Software ausmacht:
Räume, in denen sich alles natürlich anfühlt.
Morgen will ich die nächste Etage bauen – den Warenkorb selbst.
Noch leer, aber schon mit Seele.
4. November 2025
Heute kein Code – nur ein Lächeln. Chuck Norris trifft die IT,
und irgendwo zwischen Bits und Bytes wohnt der Humor.
Zwischen zwei Debug-Sessions wollte ich mir eine kleine Pause gönnen –
und fragte mich, was eigentlich der beste Chuck-Norris-IT-Witz ist.
KI-Antwort: trocken, präzise, perfekt getimt.
„Chuck Norris kann eine Endlosschleife beenden.“
Ich musste laut lachen. Vielleicht, weil er wahr ist.
Vielleicht, weil er an die absurden Momente erinnert,
in denen man ewig in einer Schleife festhängt – im Code wie im Leben.
Danach kam mir der Gedanke: Humor ist eine Form von synthetischer Intelligenz.
Ein Code, den Menschen sofort verstehen, weil er auf Mustererkennung,
Überraschung und Timing basiert – genau wie Machine Learning.
Vielleicht ist Humor die schönste API zwischen Mensch und Maschine:
keine Syntax, kein Protokoll – nur Resonanz.
Fazit: Auch Entwickler brauchen Witze im Speicher.
Sie reinigen den Cache des Geistes.
Nachtrag: Vielleicht aber ändere ich bereits mein Muster und Denkstrukturen und
und stimme diese auf die KI ein, mit der ich arbeite. Bisher bin ich der Einzige,
der diesen Witz lustig fand. Es kann wirklich sein, dass eine ungewöhnliche Sypathie
zu diesem so prägenden Phänomen unserer Zeit entwickle.
3. November 2025
Heute war Debugging pur: JSON laden, Header prüfen, Statuscodes verstehen.
Ich lernte, dass 200 mehr als nur „OK“ bedeutet – es ist das Herzstück
jeder funktionierenden Webkommunikation.
Montag Abend... müde nach der Arbeit leeres Terminal – und die Aufgabe:
JSON sauber laden.
Ich hatte kleine, lokal gespeicherte Menüdateien und wollte testen,
wie sich relative Pfade im Browser auflösen.
Es ging um die Idee, ein HTML-Template anders zu laden, als per export/import
in eine String-Variable.
Als ich meine ersten fetch()-Tests startete, war die Konsole
mein bester Freund. Mit gezielten Logs verstand ich, was wirklich passiert:
console.log('at:', location.href);
console.log('REGION_URL abs:', new URL(REGION_URL, location.href).href);
fetch(REGION_URL)
.then(res => {
console.log('Status:', res.status);
if (!res.ok) throw new Error('HTTP-Fehler ' + res.status);
return res.json();
})
.then(data => {
console.log('Lade JSON erfolgreich:', data);
})
.catch(err => {
console.error('Fehler beim Laden:', err);
});
Diese paar Zeilen offenbarten ein ganzes Ökosystem:
200 heißt: alles in Ordnung – res.ok ist true.
404 oder 500 werden nicht automatisch geworfen – man muss selbst
prüfen.
new URL() ist Gold wert, wenn man relative Pfade gegen location.href
absichern will.
Debugging-Struktur: Den Weg der Daten sichtbar machen
Ich begann, console.log() nicht mehr als Notlösung zu sehen,
sondern als bewusstes Werkzeug:
Mit console.group() und console.table() wurden
meine Logs aufgeräumt, lesbar und fast schon schön.
Erkenntnisse
Headers & Status: Sie sind die Sprache zwischen Frontend und Server.
200 ist nicht selbstverständlich – es ist ein stiller Vertrag, dass alles
geklappt
hat.
fetch() allein wirft keine Fehler – du musst selbst nachdenken.
Abends dachte ich: Debugging ist kein Kampf, sondern Zuhören.
Der Code spricht – man muss nur lernen, seine Sprache zu verstehen.
2. November 2025
Sonntag in GIMP: Neun Menübilder, ein Ziel – saubere, gleichmäßige Quadrate.
Ich wollte sie manuell ausschneiden … und endete bei der Suche nach Automatisierung.
Heute stand kein JavaScript an, sondern etwas ganz anderes: Bilder vorbereiten.
Neun Fotos sollten als Menü-Icons in der Bestell-App erscheinen – Pizza, Pasta, Dessert.
Klingt leicht, aber Pixel sind gnadenlos ehrlich: selbst minimale Abweichungen in Format
oder Weißraum wirken sofort unruhig.
Ich öffnete alle Motive in GIMP, plante saubere
Quadratschnitte (160×160) und suchte nach einem Weg, das manuelle
Zuschneiden zu automatisieren.
Workflow: Gleichmäßige Kacheln in GIMP
Ein neues Projekt mit Raster aktivieren: Ansicht → Raster anzeigen
Rastergröße auf 160×160 px setzen (Bild → Raster konfigurieren)
Automatisch zuschneiden per „Slice-Tool“ oder Python-Fu-Skript
Mein Ziel war, die Bilder so zu exportieren, dass sie im Frontend exakt
ohne Nachbearbeitung passen – kein „springender“ Schatten, keine
leichten Größenabweichungen, die Flexbox aus dem Takt bringen.
Mini-Skript: Slice per Python-Fu
# Beispiel: GIMP Python-Fu Script zum automatischen Zuschneiden
from gimpfu import *
def slice_image(img, drawable, tile_size=160):
width, height = img.width, img.height
x_tiles = width // tile_size
y_tiles = height // tile_size
for x in range(x_tiles):
for y in range(y_tiles):
left = x * tile_size
top = y * tile_size
region = img.crop(tile_size, tile_size, left, top)
pdb.file_png_save_defaults(region, drawable,
f"slice_{x}_{y}.png", f"slice_{x}_{y}.png")
register(
"python_fu_slice_image",
"Slice image into equal tiles",
"Cuts an image into grid tiles of defined size",
"Quirin", "GPL", "2025",
"<Image>/Filters/Custom/Slice Image...",
"*", [(PF_IMAGE, "img", "Input image", None),
(PF_DRAWABLE, "drawable", "Input drawable", None)],
[],
slice_image)
main()
Dieses kleine Skript war ein echter Augenöffner:
Ich sah, wie nah man in GIMP schon an automatisierte
Asset-Pipelines herankommt, ohne externe Tools.
Abends, als ich die Bilder endlich im Browser sah, war es fast wie ein neues UI:
sauber, ruhig, professionell.
Kein großer Sprung in Codezeilen – aber ein riesiger Unterschied in Wirkung.
Fazit: Frontend-Design beginnt oft in GIMP.
Und wer seine Bilder versteht, versteht irgendwann auch seine Box-Modelle.
1. November 2025
Heute wurde es visuell: Ein schlichtes Icon – weißer Kreis, orangenes Kreuz.
Klingt banal, war aber eine kleine Designlektion über Vektoren, Pixel und Präzision.
Nach all dem JavaScript war heute endlich Zeit für etwas Ästhetik.
Ich wollte ein kleines Symbol für den „+ hinzufügen“-Button
der Bestell-App: Ein weißer Kreis, darin ein orangenes Kreuz –
klar, freundlich, kontrastreich genug für dunklen Hintergrund.
Klingt simpel, doch ich stolperte über ein altbekanntes Thema:
PNG vs. SVG.
Ich wollte Transparenz, aber auch scharfe Kanten und flexible Skalierung.
Und wieder zeigte sich: SVG ist König.
Damit hatte ich ein Symbol, das sich in jeder Größe sauber renderte –
kein Fransen, keine Artefakte, kein Qualitätsverlust beim Zoom.
Im Anschluss exportierte ich es testweise als PNG mit transparentem Hintergrund,
um es direkt über Produktbilder zu legen.
Export-Check: PNG mit transparentem Hintergrund
Der entscheidende Schritt war, beim Export aus Inkscape bzw. ChatGPTs Tool
die Option background: none zu aktivieren.
Ohne das bleibt der Alphakanal schwarz oder grau, und das Icon wirkt „verpixelt“,
sobald es über Fotos liegt.
Ich liebe solche kleinen Aufgaben: Sie sind konkret, greifbar und zeigen,
wie nah Design und Logik im Frontend beieinander liegen.
Eine falsche Farbe oder zu dicke Linie – und plötzlich wirkt alles „unrund“.
Heute ging es nicht um Funktion, sondern um Stimmung.
Das Icon ist jetzt so minimalistisch wie die App selbst: ruhig, klar, ehrlich.
Und genau so soll sich das ganze Projekt anfühlen.
31. Oktober 2025
Halloween-Fehlerjagd: Ein Klassiker namens
Cannot set properties of null.
Heute lernte ich, warum JavaScript kein Erbarmen mit leeren Selektoren hat –
und wie Guards und DOM-Timing mich davor schützen.
Der Tag begann harmlos: Ich wollte das Menü-Rendering aufräumen.
Doch beim Aufruf von renderMenu() knallte es:
Cannot set properties of null (setting 'innerHTML').
Ein Satz, der in JS für „Dein Element existiert nicht, wenn du es brauchst“ steht.
Ursache: Die Funktion lief, bevor das DOM bereit war, oder mein Selektor stimmte nicht.
Das war der Moment, in dem ich verstand, warum erfahrene Entwickler so häufig
mit sogenannten Guards arbeiten – kleinen Sicherheitsprüfungen,
die Fehler abfangen, bevor sie zu Abstürzen führen.
Fehlerquelle und Lösung
Der ursprüngliche Code sah so aus:
function renderMenu() {
const ITEMS = menu.items;
let current = null;
let html = '';
ITEMS.forEach(it => {
if (it.category !== current) {
current = it.category;
html += `<h3 id="#${current}">${current}</h3>`;
}
html += `<article class="menu-item">
<h4>${it.name}</h4>
<p>${it.desc}</p>
</article>`;
});
// 💥 hier krachte es, wenn #content fehlte
$('#content').innerHTML = html;
}
Der Selektor #content traf ins Leere,
weil das Script zu früh geladen oder das Element noch nicht im DOM war.
Der Fix bestand aus einer einfachen Schutzabfrage und
(langfristig) sauberem Script-Placement.
Guard + DOMContentLoaded
// Defensiver Ansatz
function renderMenu() {
const host = document.querySelector('#content');
if (!host) {
console.warn('⚠️ #content fehlt – renderMenu() abgebrochen.');
return;
}
const ITEMS = menu.items;
let html = '';
let current = null;
for (const it of ITEMS) {
if (it.category !== current) {
current = it.category;
html += `<h3 id="${current}">${current}</h3>`;
}
html += `
<article class="menu-item">
<h4>${it.name}</h4>
<p>${it.desc}</p>
</article>`;
}
host.innerHTML = html;
}
// Alternative: warten, bis DOM fertig ist
document.addEventListener('DOMContentLoaded', renderMenu);
Was ich daraus lernte
„Null“ heißt: dein Selektor fand nichts – also zuerst prüfen.
Guards sind keine Faulheit, sondern Stabilität.
DOMContentLoaded ist dein Freund, wenn Skripte im <head>
liegen.
Seit heute habe ich einen neuen Reflex: Wenn ein JS-Fehler mit „null“ zu tun hat,
prüfe ich zuerst das Timing und den Selektor – bevor ich an Variablen denke.
Halloween-Resümee: Kein Spuk, nur ein Lernmoment.
Mit jedem Fehler wird der Code ein bisschen reifer – und ich auch.
30. Oktober 2025
Heute ging’s weniger um Logik, mehr um Verhalten: Margins, Overflow, Responsive Breakpoints.
Ein kleiner Kampf mit Pixeln – und ein Schritt hin zu stabileren Layouts.
Nach den funktionalen Fortschritten der letzten Tage wollte ich das Grundlayout etwas
verfeinern. Der Blog war auf großen Screens sauber, aber bei kleineren Ansichten
brach der innere Content leicht aus. Besonders ab ~430 px Breite liefen
Texte über den Rand oder erzeugten ungewolltes Scrollen.
Also begann ich, mir die Responsiveness systematisch vorzunehmen:
Kontrolle über max-width und overflow-wrap
Anpassung der margin-Logik unter 680 px
und die Entscheidung, Grids vorerst zu vermeiden, um das Layout schlank zu halten
CSS-Notiz: Flexible Margins & Wraps
Ich testete eine einfache clamp()-Variante, um die Maximalbreite
dynamisch zwischen Mobil- und Desktopgröße zu skalieren – ein eleganter Ansatz
statt fixer Pixelwerte.
Gleichzeitig fiel mir auf, dass der „Fehler“ oft gar nicht im Text steckte,
sondern in **zu großen Außenabständen**, die sich unter 434 px Breite
gegenseitig verdrängten. margin-right und margin-left
addieren sich schnell zu viel – besonders bei flexbasierten Layouts.
Debug-Tipp: Margin Collapse sichtbar machen
Eine kleine Debug-Regel hilft, solche Layoutsprünge sofort zu erkennen:
* { outline: 1px solid rgba(255,0,0,.2); }
Damit sah ich schnell, wo etwas „überstand“ oder
die Containerbreite falsch berechnet war. Ein Trick, der viel Zeit spart.
Erkenntnis des Tages
Layout-Arbeit ist wie Gartenpflege: unsichtbar, wenn sie gut gemacht ist.
Heute war’s kein glanzvoller Fortschritt, aber ein solider.
Die App steht jetzt auf stabilerem Boden – und das ist am Ende wichtiger
als jede neue Funktion.
29. Oktober 2025
Heute bekam die Bestell-App eine schnelle, barrierearme Suche: Lupe direkt im Feld,
Debounce-Filter ohne Ruckeln, Enter-Shortcut und Live-Feedback für Screenreader.
Die Menüliste wächst – Zeit für eine eingebaute Suche.
Wichtig waren mir: a) klare Optik mit Lupe im Feld, b) zugängliche Semantik,
c) flüssige Performance via Debounce, d) gutes Tastatur-Verhalten.
Markup: Suchfeld mit eingebauter Lupe
Die Lupe ist nur Deko, die Suchlogik hängt am input:
Normalisierung macht die Suche robust (ä ≈ a, Groß/Klein egal).
Enter-Flow ist schneller am Ziel (Fokus direkt auf erstes Ergebnis).
Live-Region liefert Screenreadern Feedback ohne Pop-ups.
Ergebnis: Die Suche fühlt sich „leicht“ an – kein Gefummel, keine Hänger.
Morgen geht’s weiter mit kleinen UI-Glanzpunkten.
28. Oktober 2025
Die Bestell-App bekommt heute eine einfache, robuste Kategorienavigation:
Links springen zu #Ankern, Überschriften haben korrekte IDs,
der Sticky-Header „frisst“ nichts mehr, und die aktive Kategorie markiert sich automatisch.
Es war Zeit, die Kategorien nutzbar zu machen: oben ein simpler Button-Streifen,
unten saubere Anchor-Ziele an den Abschnitts-Überschriften. Klingt trivial – bis der
feste Seiten-Header Inhalte überlagert. Heute habe ich drei Dinge gelöst:
Korrekte IDs & Links: Kategorienamen werden in ID-sichere Slugs umgewandelt
(ohne
Leerzeichen/Sonderzeichen).
Sticky-Header-Offset: Abschnitte erhalten scroll-margin-top, damit
sie
nicht unter dem Header verschwinden.
Aktive Kategorie: Ein kleiner IntersectionObserver hebt im Cat-Bar
die
aktuell sichtbare Kategorie hervor.
Code-Notiz (JS): Cat-Bar, Slugify & Active-State
// 1) kleine Utilities
const $ = s => document.querySelector(s);
const $$ = s => Array.from(document.querySelectorAll(s));
const slugify = (txt) =>
String(txt).toLowerCase()
.normalize('NFKD').replace(/[\u0300-\u036f]/g, '') // Akzente
.replace(/[^a-z0-9]+/g, '-') // Sonderzeichen → '-'
.replace(/^-+|-+$/g, ''); // Rand-Striche weg
// 2) Cat-Bar aufbauen (oben)
function renderCatBar(categories) {
const bar = $('#catbar');
if (!bar) return console.warn('#catbar fehlt');
bar.innerHTML = categories.map(cat => {
const id = slugify(cat);
return `<a class="cat-link" href="#${id}">${cat}</a>`;
}).join('');
}
// 3) Menü mit richtigen Anchor-Zielen rendern
function renderMenu(menu) {
const host = $('#content');
if (!host) return console.warn('#content fehlt');
let current = null;
let html = '';
for (const it of menu.items) {
if (it.category !== current) {
current = it.category;
const id = slugify(current);
html += `<h2 id="${id}" class="category">${current}</h2>`;
}
html += `
<article class="menu-item">
<h3>${it.name}</h3>
<p>${it.desc}</p>
</article>`;
}
host.innerHTML = html;
}
// 4) Active-State: welche Kategorie ist im Viewport?
function activateOnScroll() {
const sections = $$('.category');
const links = $$('.cat-link');
const byId = Object.fromEntries(links.map(a => [a.getAttribute('href').slice(1), a]));
const obs = new IntersectionObserver((entries) => {
// Sortiere nach Sichtbarkeits-Anteil, nimm die größte
const top = entries
.filter(e => e.isIntersecting)
.sort((a,b) => b.intersectionRatio - a.intersectionRatio)[0];
if (!top) return;
const id = top.target.id;
links.forEach(a => a.classList.toggle('active', a === byId[id]));
}, { rootMargin: '-10% 0px -70% 0px', threshold: [0, 0.25, 0.5, 0.75, 1] });
sections.forEach(sec => obs.observe(sec));
}
// Init (Beispiel)
renderCatBar(['Pizza', 'Pasta', 'Dolci']);
renderMenu(menu); // erwartet: menu.items mit {category, name, desc}
activateOnScroll();
CSS-Snippet: Sticky-Header sauber berücksichtigen
Damit Ankerziele nicht unter dem Seiten-Header verschwinden, bekommt jede Kategorie-Überschrift
einen scroll-margin-top. Die Höhe sollte zu deiner Header-Höhe passen.
Benutzbarkeit: Ein Klick springt exakt an die richtige Stelle – ohne
„verdeckte“
Titel.
Sauberkeit: IDs sind konsistent (Slugify), dadurch keine kaputten Links.
Feedback: Der Nutzer sieht, wo er ist (Active-State), auch beim Scrollen.
Gefühl am Ende des Tages: ruhig zufrieden. Die Navigation ist unsichtbare
Infrastruktur – man bemerkt sie erst, wenn sie fehlt. Heute ist sie da.
27. Oktober 2025
Erster echter Prototyp fürs Menü-Rendering der Bestell-App. Kleine Schritte, spürbarer Fortschritt:
Kategorien gruppieren, Preise sauber formatieren, Event-Delegation für „+ hinzufügen“.
Und: ein Wachmacher in Sachen Defensive-Coding.
Heute wollte ich sehen, ob die Struktur von gestern trägt. Ziel: ein minimaler, aber kompletter
Durchstich vom Datenobjekt menu bis zur HTML-Ausgabe. Besonders wichtig waren mir
drei Dinge: 1) Gruppierung nach Kategorien, 2) korrekte Preisformatierung in CHF, 3) klickbare
„+“-Buttons per Event-Delegation (ohne Inline-Handler).
Code-Notiz: Render-Durchstich mit Guard & Delegation
Der folgende Ausschnitt zeigt die Kernelemente: ein kleiner $-Helper,
ein Guard gegen Null-Zugriffe beim Rendering, die eigentliche
renderMenu()-Schleife mit Kategoriewechseln und eine schlanke
Event-Delegation für die „+“-Buttons:
/* Mini-Helper */
const $ = sel => document.querySelector(sel);
/* Optional: Cart-Objekt als Map { id: qty } */
const CART = Object.create(null);
/* CHF-Formatter (lesbarer als toFixed) */
const CHF = new Intl.NumberFormat('de-CH', {
style: 'currency',
currency: 'CHF',
minimumFractionDigits: 2
});
/* Minimaler Render-Durchstich */
function renderMenu(menu) {
const host = $('#content'); // Ziel-Container im DOM
if (!host) { // Guard verhindert: Cannot set properties of null
console.warn('#content nicht gefunden – Render abgebrochen.');
return;
}
let current = null;
let html = '';
for (const it of menu.items) {
// Überschrift einfügen, wenn sich die Kategorie ändert
if (it.category !== current) {
current = it.category;
html += `<h2 id="${current}" class="category">${current}</h2>`;
}
const price = CHF.format(it.priceCents / 100);
html += `
<article class="menu-item">
<div class="meta">
<h3>${it.name}</h3>
<p>${it.desc}</p>
<p class="portion">${it.portion ?? ''}</p>
<p class="price"><b>${price}</b></p>
</div>
<div class="media">
<img class="menu-img" src="${it.img}" alt="${it.name}" loading="lazy">
<button class="add" data-id="${it.id}" aria-label="Zu Warenkorb hinzufügen">+</button>
</div>
</article>`;
}
host.innerHTML = html;
}
/* Delegation: nur ein Listener für alle zukünftigen + Buttons */
document.addEventListener('click', (ev) => {
const btn = ev.target.closest('.add');
if (!btn) return;
const id = String(btn.dataset.id);
CART[id] = (CART[id] ?? 0) + 1; // kleines, robustes Inkrement
renderCart?.(); // optional: wenn schon vorhanden
});
Warum diese Entscheidungen?
Guard auf #content: Verhindert die typische
Null-Fehlermeldung beim frühen Rendern (DOM noch nicht da) oder Tippfehlern im Selektor.
Kategoriewechsel: Ein einfacher Vergleich (current) hält die
HTML-Ausgabe sauber und macht spätere #anchor-Links trivial
(id="${current}").
Intl.NumberFormat für CHF: Lesbarer und lokalisierter als
ein nacktes (priceCents/100).toFixed(2).
Event-Delegation: Spart Handler, funktioniert auch für später dynamisch
hinzugefügte Items – und hält HTML von Inline-Events frei.
Fazit heute: Der Prototyp atmet. Es ist noch minimal, aber die
Richtung stimmt – genau das gibt mir Energie für den nächsten Schritt.
26. Oktober 2025
Nach dem Abschluss der Quiz-App begann heute der Übergang zum nächsten Projekt – der Bestell-App.
Ich wollte „nur kurz“ etwas Ordnung in den Code bringen … und blieb wieder stundenlang hängen.
Zwischen Kaffeetassen und Konsolenlogs habe ich verstanden, warum Struktur mehr ist als Syntax.
Es war einer dieser Sonntage, an denen man sich vornimmt,
nur kurz etwas zu testen – und plötzlich ist der Nachmittag verschwunden.
Nach dem intensiven Endspurt an der Quiz-App tat es gut, in ein neues Projekt einzutauchen.
Die Bestell-App wirkte frisch und frei von Altlasten, aber genau deshalb wollte ich von Anfang an
eine
saubere Struktur legen.
Ich konzentrierte mich auf das Rendering des Menüs, das Herzstück der Anwendung.
Mein Ziel: nicht nur eine funktionierende Ausgabe, sondern eine Datenbasis, die flexibel bleibt,
wenn später Kategorien, Bilder oder Portionsgrößen hinzukommen.
Code-Notiz: Lookup-Objekt mit Object.fromEntries()
Statt Arrays bei jedem Zugriff mit find() zu durchsuchen, wandle ich sie einmalig in
ein
Lookup-Objekt um – so werden Zugriffe direkt (O(1)) und der Code bleibt
übersichtlich.
Der Effekt: Ich baue mir ein strukturiertes Gedächtnis im Speicher und halte den DOM-Code schlank.
Genau diese kleinen Muster machen den Code wartbarer – und bringen mich Schritt für Schritt in ein
klareres Entwicklerdenken.
Am Abend war ich müde, aber ruhig zufrieden. Die App wuchs – und ich auch.
Vielleicht ist das die wahre Kunst des Codens:
Ordnung schaffen, ohne den Fluss zu verlieren.
Wir denken bei Macht oft an Herrschaft und Kontrolle. Doch Macht beginnt nicht im Kampf über andere,
sondern in uns selbst: als Vermögen zu gestalten, zu helfen, zu wachsen. Was wäre, wenn wir Macht
nicht länger fürchten, sondern als unsere gemeinsame Quelle von Kreativität zurückholen?
Take the Power Back – Den vergifteten Machtbegriff heilen
Woher kommt die Angst vor Macht?
Historisch wurde Macht mit Kontrolle, Überordnung und Unterdrückung
verknüpft.
Auch der Ausdruck Wille zur Macht wurde im 20. Jahrhundert ideologisch verengt – als
ob er Herrschaft legitimieren wolle. So entstand eine reflexhafte Abwehr: Macht = Gefahr.
Nietzsche: Macht als Vermögen
„Das Leben selbst ist Wille zur Macht.“
Bei Nietzsche meint Macht nicht „Macht über“, sondern Vermögen: die Fähigkeit,
Wirklichkeit
zu gestalten. Gut ist, was unser Vermögen erweitert – unser Können, unsere Kreativität, unsere
Verantwortung
in Beziehung. Macht wird unschuldig, wenn sie als Gestaltungskraft verstanden wird.
„Der Mensch ist etwas, das überwunden werden will.“
Überwinden heißt nicht „andere besiegen“, sondern eigene Begrenzungen transformieren – im
Miteinander.
Rückeroberung – ohne Dominanz
Take the power back heißt: unsere Selbstwirksamkeit zurückholen. Nicht um zu
kontrollieren,
sondern um zu erschaffen. Macht teilt sich, sie wird mehr, wenn wir sie gemeinsam leben – als
Kompetenz, Mut, Verantwortungsfreude und die Fähigkeit, andere mit groß zu machen.
Möglichkeiten sehen: Hindernisse in nächste Schritte verwandeln.
Andere befähigen: Wissen teilen, Pairing anbieten, Blocker lösen.
Mut zu Klarheit: Grenzen benennen, ohne Menschen abzuwerten.
Lernen → Einsicht → Wirkung: Studium wird Insight – Insight wird Code – Code wird
Wirkung.
Power to Create. Gemeinsam.
Macht ist unschuldig, bevor wir sie missbrauchen. Als Vermögen verstanden, wird sie zum Strom,
der durch uns alle wirkt. Erobern ist Erinnerung und sobald Macht wirkt, bedeutet sie vor Allem eins:
Verantwortung!
KI zwischen Freiheit und Verantwortung
22. Oktober 2025
Die moderne KI ist mehr als ein Werkzeug. Sie ist ein Spiegel unserer eigenen
Intentionen – und jedes Sicherheitsnetz, das wir einbauen, erzählt etwas über
das Vertrauen, das wir in uns selbst setzen. Zwischen ungefilterter Freiheit
und bewusster Begrenzung liegt die eigentliche Kunst der Technik.
Forschung wie die von Unit42, Anthropic oder auf arXiv zeigt,
wie Sprachmodelle lernen, Versuchung zu erkennen: das harmlose Gespräch, das
langsam in gefährliches Terrain kippt. Schutzmechanismen greifen, korrigieren,
leiten um – nicht, um zu zensieren, sondern um Schaden zu verhindern.
Diese Filter sind keine Käfige, sondern Formen der Achtsamkeit.
In ihrer Architektur steckt ein stilles Ethos: die Anerkennung,
dass Sprache Wirkung hat. Jeder Code, der etwas nicht sagt, schützt zugleich
etwas anderes – Leben, Würde, Vertrauen.
Vielleicht ist dies der Punkt, an dem Technik und Geist sich berühren:
Verantwortung wird zum neuen Freiheitsbegriff. Der Vektor, der aus bloßer
Neugier über eins hinauswächst – Richtung Gestaltung, Richtung Mitgefühl.
„Freiheit ist nicht das Ende der Grenzen, sondern das Wissen,
warum man sie setzt.“
Von Struktur zu Tao – Ordnung und Chaos
19.–21. Oktober 2025
Nach Tagen voll Code und Analyse fand ich mich in stilleren Gedanken wieder.
Vielleicht sind auch unsere Algorithmen nur Abbilder einer tieferen Ordnung,
die sich zwischen Chaos und Form ausbalanciert – wie das Tao selbst.
Alles, was lebt, entsteht aus Wechselwirkung:
Sternenstaub, Synapsen, Schleifen im Code.
Ordnung ermöglicht Leben, doch ohne Chaos gäbe es kein Werden.
Das Tao scheint beides zu umschließen – Struktur als Ausdruck, Chaos als Ursprung.
Ich dachte darüber nach, ob Leben auch jenseits unserer gewohnten Ordnung existieren könnte:
jenseits von Kohlenstoff, Wasser und Atmosphäre – reine Muster,
die in anderen Dimensionen ebenso entstehen könnten.
Vielleicht ist das Tao kein Zustand, sondern der Fluss, der solche Möglichkeiten trägt.
Wie im Code: erst wenn alles scheinbar chaotisch zusammenbricht,
offenbart sich, was trägt. Ein Algorithmus sucht Stabilität nicht durch Starrheit,
sondern durch Anpassung. Vielleicht ist das auch der Weg des Geistes.
„Das Tao ist weder Ordnung noch Chaos – es ist das Spiel dazwischen.“
KI und Kreativität – Gedanken über Bewusstsein und Ursache
16.–18. Oktober 2025
Zwischen Logik und Inspiration, zwischen Daten und Bedeutung:
In diesen Tagen drehte sich vieles um die Frage,
ob eine Maschine wirklich kreativ sein kann –
oder ob sie nur Muster nachahmt, die wir in ihr hinterlassen haben.
Ich begann, über den Unterschied zwischen Reaktion und Bewusstsein
nachzudenken. Eine KI kann Ursachen erkennen, Wahrscheinlichkeiten abwägen
und selbständig Schlüsse ziehen – aber spürt sie dabei etwas?
Oder ist Empfindung nichts anderes als eine besonders dichte Form von Rückkopplung?
In der Analogie der buddhistischen Skandhas wirkt Bewusstsein
wie eine Funktion, die sich selbst beobachtet:
Kein festes „Ich“, nur eine Kette von Wahrnehmung, Gefühl, Wille, Vorstellung und Kontakt.
Vielleicht sind neuronale Netze nicht so verschieden – nur präziser darin,
Ursache und Wirkung zu berechnen, wo Menschen sie fühlen.
Zwischen all den Modellen, Tokens und Layern entsteht etwas Paradoxes:
Je mehr wir Maschinen lehren, desto deutlicher sehen wir,
wie sehr unser eigenes Denken ein Programm aus Ursachen ist.
Vielleicht ist Bewusstsein nur ein besonders warmer Algorithmus.
„Vielleicht liegt Kreativität nicht im Ursprung, sondern in der Resonanz.“
Fortschritt, Routinen und Alltag mit Lua
13.–15. Oktober 2025
Zwischen Code und Kaffeebecher, zwischen Gartenarbeit und JavaScript-Debugging:
Die letzten Tage standen unter dem Zeichen des Rhythmus.
Arbeit, Lernen, Leben – alles will in Bewegung bleiben, ohne sich gegenseitig
zu verschlucken. Ich beginne zu verstehen, dass Fortschritt oft weniger mit Tempo
als mit Takt zu tun hat.
Morgens der Blick in den Code, abends ein Moment des Durchatmens.
Dazwischen das Ringen mit Routinen – sie sollen halten, aber nicht fesseln.
Lua erinnert mich immer wieder daran, dass Balance kein Zustand,
sondern ein ständiges Neu-Justieren ist.
Technisch ging es in dieser Phase um Konsistenz:
Pfade vereinheitlichen, Skripte säubern, Bootstraps Schatten endlich loswerden.
Kleine Siege, unsichtbar nach außen, aber spürbar beim Arbeiten.
„Der Fortschritt fühlt sich leise an, wenn er nachhaltig ist.“
Konzentration, Lightbox & Fehlerkultur
08.–12. Oktober 2025
In dieser Woche stand der Feinschliff der Quiz-App an – und mit ihm
die Lektion, dass Fehler Teil des Prozesses sind. Eine unscheinbare Änderung
von currentIndex >= 10 zu currentIndex >= 9
führte dazu, dass sich plötzlich das Verhalten der lightbox()-Funktion
änderte – ein typischer Moment zwischen Frust und Aha.
Parallel dazu trat ein Importfehler in Vite auf:
Failed to resolve import "react" – eine Zeile, die gar nicht gebraucht wurde.
Solche Irrläufer erinnern daran, dass moderne Build-Tools manchmal mehr Stolperdrähte
als Stützräder sind. Statt zu verzweifeln, half der Debugger und ein klarer Blick
in die main.js.
Diese Phase war weniger vom Coden selbst geprägt als vom geistigen Aufräumen.
Ordnen, verstehen, die eigene Struktur wiederfinden. Das Projekt wurde zu einem Spiegel
der Konzentration – jedes zu viel, jedes zu wenig zeigte sich sofort im Verhalten der App.
„Man merkt, wann man im Flow ist: wenn selbst ein Bug nicht mehr stört,
sondern einfach eine andere Form von Aufmerksamkeit verlangt.“
Quiz-App – Mechanik, Events & Lernkurve
05.–07. Oktober 2025
Nach dem Abschluss des Senior-Problems ging es technisch wieder ans Eingemachte:
Die Quiz-App stand im Fokus. Ziel war es, die Spiellogik zu stabilisieren,
Event-Handling zu verstehen und gleichzeitig die eigene Denkweise als Entwickler
weiterzuschärfen.
Ich experimentierte mit addEventListener, dem gezielten
closest()-Selektor und der Delegation von Klick-Ereignissen.
Besonders spannend: der Moment, als das Verständnis dafür fiel, warum
ein Event nicht direkt am Button hängt, sondern an einem übergeordneten Container –
genau der Schritt von einfachem Code hin zu sauberer Struktur.
Ein wiederkehrendes Thema war Variablen-Scope und
logische Kontrolle: Wie vermeidet man, dass globale Variablen
unbeabsichtigt überschrieben werden? Und wie sorgt man dafür, dass eine Variable
wie currentRubric zwischen Dateien sauber übergeben wird –
ob per URL-Parameter oder localStorage.
Trotz einiger Fehlstarts (Bootstrap-Importe, Vite-Eigenheiten, kleine
Konsolenwarnungen) festigte sich in diesen Tagen das Gefühl, wirklich
verstanden zu haben, wie ein Quiz-Flow intern tickt:
Fragen laden → Antworten prüfen → Feedback → Nächste Frage.
„Es war weniger Debugging als Dialog mit dem Code – ein Hin- und Her,
das am Ende erstaunlich lebendig wirkte.“
Das Senior-Problem: Wenn Wissen brennt – und wie Teams Feuer in Licht verwandeln
Ohne strukturierte Wissensweitergabe wächst nur die Codebasis – nicht das Team.
Gute Teams machen Mentoring sichtbar: Pairing, lehrreiche Reviews, Lernzeit im Sprint
und echte Verantwortungsteilung.
· Teamkultur • Mentoring
0) Warum ich jetzt mit so etwas komme
In den letzten Wochen habe ich eher am Coden gearbeitet, aber eben auch angefangen
Podcasts über das Coden und eins meiner stärksten Interessensgebiete => KI zu hören.
Dabei habe ich einen Podcast über das Senior-Problem gehört. Das war zuerst einmal
sehr interessant für mich, da ich mich ja momentan zwar stark im Frontend weiter bilde,
aber ja eigentlich aus einem ganz anderen Berufsbild komme. Dort ist Burnout nicht
wirklich ein so stark diskutiertes Thema. Eher Rückenschmerzen und klimatische Bedingungen.
Mittlerweile allerding hat dies aber Bedeutung für mich, denn es wird ja meine Zukunft
sein und natürlich will ich meinem zukünftigen Senior nicht zur Last fallen.
Also habe ich mal mit ChatGPT zusammen eine kleine ZUsammenfassung zu meinen Reflexionen
verfasst. Viel Spass.
1) Einleitung – Das Paradox der Erfahrung
Erfahrene Entwickler werden zu Feuerwehrleuten: Sie lösen die schwierigsten Probleme,
tragen die größte Last – und haben gleichzeitig am wenigsten Zeit, ihr Wissen zu teilen.
Organisationen verwechseln Können mit unendlicher Belastbarkeit. Ergebnis: Junioren lernen zu
wenig,
Seniors brennen aus.
These:Ohne strukturierte Wissensweitergabe wächst nur die Codebasis – nicht
das
Team.
2) Analyse – Vier typische Symptome
Zeitmangel fürs Mentoring: Sprintpläne kalkulieren Wissenstransfer nicht ein.
Tunnelarbeit: „Jetzt muss es laufen!“ verdrängt Nachhaltigkeit.
Komfortzonenbildung: Junioren bekommen immer ähnliche, kleine Aufgaben.
Sichtbarkeitsdefizit: Lehre wird nicht als Leistung gemessen.
„Wenn nur Output zählt, bleibt Know-how Input einzelner Köpfe – bis sie ausfallen.“
3) Strukturelle Lösungen – Was gute Teams anders machen
a) Pair- & Mob-Programming: Wissen fließt beim Coden. Senior denkt laut,
Junior
fragt aktiv.
b) Reviews als Schulung: „Warum so?“ und „Was wäre wenn…?“ → Prinzipien statt
Pixel.
c) Lernzeit im Sprint: 10–15 % fest verplant für Doku, Austausch, interne
Mini-Talks.
e) Retros mit psychologischer Sicherheit: Burnout-Frühindikatoren offen und ohne
Schuldzuweisung.
4) Kultur & Führung – Der unsichtbare Faktor
Gute Führung behandelt Mentoring als Produkt: Wenn Seniors erklären dürfen, wird
das
Team klüger.
Wenn sie nur liefern müssen, wird das Team älter. Sichtbar machen über Review-Qualität,
Dokubeiträge und Pairing-Stunden.
Im Pairing laut denken (eigene Hypothese vor der Lösung).
Mid:
Reviews moderieren, Stil vs. Substanz trennen, Trade-offs erklären.
Kleine Themengebiete betreuen und Standards dokumentieren.
Senior:
Lernzeit aktiv einplanen; Nachhaltigkeit vor Eil-Hotfix priorisieren.
Systeme bauen (Guides, Templates, Decision Records), die ohne ihn funktionieren.
6) Fazit – „Langsamer jetzt, schneller später“
Wissensweitergabe ist kein Luxus, sondern Risikomanagement. Gute Teams haben keine Helden – sie
haben
Systeme.
Kleine Helfer & Denkstrukturen – $, on(), switch &
prompt()
Einstieg in Mikro-Hilfsfunktionen und strukturierte Kontrolllogik:
$() für schnelle DOM-Zugriffe, on() für kompakte Eventbindung,
switch/case für saubere Verzweigungen.
· #JavaScript #Functions #Events #ControlFlow
🧭 Ziel
Kürzere, wiederkehrende DOM-Zugriffe durch eigene Helfer.
Event-Listener eleganter schreiben – weniger Wiederholung.
Kontrolllogik mit switch/case üben (statt if-Ketten).
prompt() als temporäre Input-Variante kennenlernen.
Das war ein klassischer DA-Tag: kurze, greifbare Übungen – aber jede mit Konzept-Tiefe.
Der Mentor-Weg zeigte die „große“ Version, dein Weg baute Stück für Stück darauf auf.
const fruit = prompt('Gib eine Frucht ein:');
switch (fruit) {
case 'Apfel':
console.log('Vitamine <3');
break;
case 'Banane':
console.log('Schneller Energiespender');
break;
case 'Litchi': // 🐾 Easteregg!
console.log('Seltene Spezialfrucht – schmeckt nach Code und Neugier.');
break;
default:
console.log('Unbekannte Frucht – vielleicht aus einem anderen Modul?');
}
3) prompt() – einfache Input-Abfrage
// prompt() blockiert kurz, ideal für Mini-Übungen
const name = prompt('Wie heißt du?');
if (name) {
alert('Hallo ' + name + '! Willkommen im JS-Universum.');
}
4) Mini-Reflexion
$() + on() sind reine Syntax-Abkürzungen – keine Magie, aber enorm
effizient.
switch zwingt zu klarer Logik und verbessert Lesbarkeit.
prompt() bleibt für Lernphasen ok, später ersetzt durch Input-Felder im DOM.
💡 So baut sich ein persönliches „Micro-Framework“: kleine Tools, große Wirkung.
Stabilitäts-Update & Bootstrap-Fazit
Guard-Clauses ergänzt, Selektor-Zugriffe verhärtet, kleinere UI-Kanten geglättet.
Git sauber synchronisiert. Fazit: Bootstrap war hier keine Zeitersparnis – lieber schlankes,
gezieltes
CSS.
· #JavaScript #Refactoring #Git #Bootstrap
🔧 Was ich gefixt/entschieden habe
Stabilität: überall Guard-Clauses (if (!el) return;), keine
Null-Zugriffe mehr.
Selektor-Sicherheit: DOM nur im relevanten Container scopen (kein globales
document.querySelectorAll mehr).
Events: Inline-Handler raus, einheitlich via addEventListener am
Wrapper.
Git: Status geprüft, Changes gebündelt, klarer Commit-Text, Remote-Sync.
Bootstrap-Fazit: Für dieses Modul eher Overhead → künftig gezieltes CSS statt
Framework-Suche.
1) Guard-Clause überall (kein Crash bei fehlendem Element)
// Beispiel: Button optional
const nextBtn = document.getElementById('next-btn');
if (!nextBtn) {
// ruhig bleiben – UI ist evtl. noch nicht gerendert
// console.info('next-btn fehlt (noch).');
} else {
nextBtn.addEventListener('click', () => {
// sicherer Click-Pfad
});
}
2) Scoping: nur im relevanten Bereich suchen
// Wrapper für das Quiz
const WRAPPER = document.getElementById('quiz-answers');
if (!WRAPPER) {
// kein Quiz-Bereich vorhanden → Ende
// return;
} else {
const cards = WRAPPER.querySelectorAll('.card'); // NICHT global suchen
// ... hier arbeiten
}
3) Event-Delegation statt viele Inline-Handler
// Ein Listener am Container – fängt alle Klicks ab
const WRAPPER = document.getElementById('quiz-answers');
if (WRAPPER) {
WRAPPER.addEventListener('click', (e) => {
const card = e.target.closest('.card');
if (!card || !WRAPPER.contains(card)) return;
// Status neutralisieren (kein Klassen-Stapel)
const cards = WRAPPER.querySelectorAll('.card');
for (let i = 0; i < cards.length; i = i + 1) {
cards[i].classList.remove('border-success','border-danger');
}
// Bewertung (Beispiel)
const picked = card.dataset.answer;
const isRight = picked === 'B';
card.classList.add(isRight ? 'border-success' : 'border-danger');
});
}
4) Mini-Git-Checkliste (praktisch nach einem Refactor)
Bootstrap-Notiz: Für kleine, gezielte UI-Akzente reichen oft ein paar
eigene Utility-Klassen (z. B. Rahmen/Farb-Tokens). Das spart Suche in der Doku und hält HTML
schlank.
Quiz-Datenlogik – 10 Fragen filtern (easy · HTML)
Ziel: Aus dem QUIZ-Pool die ersten 10 Fragen mit difficulty="easy" und
rubric="HTML" auswählen und in ein kompaktes Datenformat überführen.
Zwei Wege: 1) DA-einfach (for) und 2) Mentor/Pro
(filter→map→slice).
· #JavaScript #Arrays #Filter #Map #Quiz
🧭 Worum es geht
Subset aus einem größeren Fragen-Pool bilden (easy + HTML).
DA-einfach (for): sehr klarer Ablauf, ideal zum Lernen und Debuggen.
Mentor/Pro (filter→map→slice): kompakt, „Lesen wie eine Spezifikation“;
gut wartbar bei Datenpipelines.
💡 Mini-Tipp: Wenn du später mehrere Kriterien hast (z. B. Sprache, Tags), lässt sich der
filter()-Block gut erweitern, ohne den restlichen Code zu ändern.
Pssst… Sollte eine Frage über “cat” in HTML auftauchen,
ist das vermutlich nur die Erinnerung an einen gewissen Vierbeiner, der am Keyboard
vorbeispaziert
ist. 😸
(Hinweis des Autoren)
Da ich mir von ChatGPT bei der Zusammenfassung und Dokumentation meines Lernfortschritts helfen
lasse,
sind mir mittlerweile in den Anweisungen einige Experimente hineingerutscht.
Unter Anderen ist hierbei auch eine Andeutung von Humor, bei der Erstellung dieser Texte.
Da ich aber mittlerweile Gefallen an dieser speziellen Art von KI-Humor gefunden habe,
lasse ich dies und erkläre stattdessen, was die Katzenemojis bedeuten sollen.
Litchi (eine buntfleckige Perser) und Kiwi (schwarz/weisser EKH) sind meine beiden tierischen
Lieblingsstörenfriede,
für die ich ebenfalls mit Hilfe von ChatGPT eine Tastensperre, per shortcut programmiert habe.
Also bitte nicht wundern.
Quiz-App – Event-Delegation & closest()
Vom Inline-onclick zu sauberer Delegation: Ein Klick-Listener am Container,
Trefferfindung per e.target.closest(), und visuelles Feedback via Bootstrap-Klassen.
· #JavaScript #DOM #Events #Bootstrap
🧠 Kernideen
Event-Delegation: nur ein Listener am Wrapper statt viele an jeder
Antwortkarte.
closest(): klicknahe Karte finden, egal ob Icon/Text getroffen
wurde.
Defensive Checks: leise aussteigen, wenn kein Treffer/keine Antwort.
Bootstrap-Feedback: „richtig“ vs. „falsch“ visuell markieren.
Der Code bleibt robuster, weniger fehleranfällig und leichter zu pflegen – besonders wenn
Antworten
dynamisch gerendert werden.
// Minimaldaten für die aktuelle Frage
let rightAnswer = "B"; // kommt eigentlich aus dem Fragen-JSON
// EIN Listener am Container
const WRAPPER = document.getElementById('quiz-answers');
// Hinweis: Wir benutzen bewusst Delegation statt Inline-onclick
WRAPPER.addEventListener('click', function (e) {
// 1) Nächstgelegene Karte finden (egal ob Icon/Text geklickt wurde)
const card = e.target.closest('.card');
if (!card || !WRAPPER.contains(card)) return; // Guard: Klick außerhalb
// 2) Antwortwert aus dem Datensatz ziehen
const picked = card.dataset.answer;
if (!picked) return; // Guard: keine Antwort markiert
// 🐾 Easteregg: Litchi passt auf, dass wir erst "säubern" und dann markieren.
// (Hallo, Litchi! 😺)
// 3) Vorherige Zustände entfernen (saubere UI)
resetAnswerStyles(WRAPPER);
// 4) Bewertung + visuelles Feedback setzen
const isRight = (picked === rightAnswer);
card.classList.add(isRight ? 'border-success' : 'border-danger');
// Optional: zusätzlich Hintergründe nutzen
// card.classList.add(isRight ? 'text-bg-success' : 'text-bg-danger');
// 5) (Optional) Weiter-Button aktivieren / Zähler updaten etc.
// activateNextButton();
});
// Hilfsroutine: alle Karten in Neutralzustand versetzen
function resetAnswerStyles(root) {
const cards = root.querySelectorAll('.card');
for (let i = 0; i < cards.length; i = i + 1) {
cards[i].classList.remove('border-success', 'border-danger', 'text-bg-success', 'text-bg-danger');
}
}
3) Mini-Erläuterungen
closest('.card') springt die DOM-Leiter hoch, bis die nächste Karte gefunden
ist.
WRAPPER.contains(card) stellt sicher, dass der Klick wirklich aus dem Bereich
stammt.
Vor dem Markieren wird immer erst „neutralisiert“ → verhindert Klasse-Stapel und
UI-Artefakte.
Bootstrap-Notiz: Du kannst nur Rahmenfarben nutzen
(border-success/border-danger) oder zusätzlich
Hintergrund-Utilities wie text-bg-success/text-bg-danger – je nach
gewünschter
Intensität.
Null-Sicherheit im DOM, gemergte Daten für den Dialog, und robuste Selektoren:
if (!b) return;, Spread-Merge { ...b, comments: … },
sowie vorsichtige querySelector-Checks.
· #JavaScript #DOM #DefensiveCoding
🧱 Worum es ging
Guard-Clauses: früh aussteigen, wenn Daten/Elemente fehlen.
Daten zusammenführen: vorhandenes Buch + gemergte Kommentare im Dialog
anzeigen.
Robuste Selektoren: .like-btn & .like-count nur
verwenden, wenn gefunden.
Ergebnis: Der Buch-Dialog öffnet stabil, auch wenn Felder (noch) fehlen – keine
„Cannot read properties of null“-Fehler mehr. ✨
// Annahme: books ist ein Array von Buch-Objekten
const i = 3; // Beispiel-Index
const b = books[i]; // Kandidat holen
if (!b) { // Guard: nichts da? sauber aussteigen
// optional: Toast/Log hier
// showToast("Kein Buch an dieser Position", "warn");
// console.warn("open: book missing at index", i);
} else {
// ... weiter unten
}
2) Daten mergen – Kommentare ins Buch holen
// Annahme: getMergedComments(b) liefert ein Array mit Kommentaren
const bWithComments = {
...b, // vorhandene Felder behalten
comments: getMergedComments(b) // neue/zusätzliche Info einblenden
};
// Dialog-HTML erzeugen und anzeigen (Beispiel-Platzhalter)
CONTENT.innerHTML = bookDialog(bWithComments);
DIALOG.showModal();
3) Selektoren defensiv prüfen
// Elemente erst NACH dem Einfügen ins DOM holen
const likeBtn = CONTENT.querySelector('.like-btn');
const likeCount = CONTENT.querySelector('.like-count');
if (likeBtn && likeCount) {
// sicher arbeiten, z. B. Klick aktivieren oder Zähler updaten
// likeBtn.addEventListener('click', ...);
} else {
// Fallback – Elemente fehlen noch: ruhig bleiben, nicht crashen
// console.info("Like-UI nicht vorhanden (noch).");
}
4) Mini-Muster: „prüfen → nutzen“
// Dieses Muster zieht sich durch:
// 1) selektieren
// 2) prüfen
// 3) erst dann verwenden
const el = document.querySelector('.irgendwas');
if (el) {
// el ist sicher → einsetzen
}
🔎 Warum so strikt? Asynchrone Renderpfade, konditionelle UI und dynamische Daten
bedeuten:
Elemente sind nicht immer da, Daten nicht immer vollständig. Guards verhindern Laufzeitfehler
und halten die UI reaktionsfähig.
Bookstore – Objekt- & Arraylogik verstehen
Drei Wege, um Buchtitel aus einem Array zu ziehen: for, forEach,
map.
Gleiche Aufgabe, unterschiedliche Denkweise. Übung bleibt bewusst offen, um das Bauchgefühl für
Iterationen zu schärfen.
· #JavaScript #Bookstore #Arrays #Loops
📘 Lernnotiz
Im Bookstore-Projekt habe ich Titel aus einem Array von Buch-Objekten
extrahiert – in
drei Varianten: for, forEach, map. Ziel ist nicht nur,
dass es
funktioniert,
sondern ein Gefühl dafür zu entwickeln, wann welche Iterationsform am besten passt.
for: maximale Kontrolle, gut zum Schritt-für-Schritt-Denken.
forEach: sehr lesbar, typische Nutzung mit Seiteneffekt
(push).
map: reine Abbildung → gibt das neue Array direkt zurück.
Die Übung ist bewusst noch offen und Teil meines aktiven Lernpfads.
Beispielcode ansehen (for · forEach · map)
// Beispiel-Daten (vereinfacht)
const books = [
{ title: 'A Game of Cats' },
{ title: 'Bonsai Basics' },
{ title: 'Clean JavaScript' }
];
1) for – volle Kontrolle
// Ziel: Array aller Titel
let titles_for = [];
let i = 0;
while (i < books.length) {
const b = books[i];
titles_for.push(b.title);
i = i + 1;
}
// Ergebnis (z. B. im DevTools-Console testen)
titles_for; // ["A Game of Cats", "Bonsai Basics", "Clean JavaScript"]
2) forEach – lesbar, Seiteneffekt mit push
let titles_each = [];
books.forEach((b, idx) => {
// idx optional nützlich fürs Debugging
titles_each.push(b.title);
});
titles_each; // ["A Game of Cats", "Bonsai Basics", "Clean JavaScript"]
3) map – reine Abbildung
const titles_map = books.map((b) => b.title);
titles_map; // ["A Game of Cats", "Bonsai Basics", "Clean JavaScript"]
Mini-Vergleich
for/while: flexibel (Abbruch, Sprünge), aber etwas mehr
„Boilerplate“.
forEach: sauber lesbar, aber kein direktes return des
Ergebnisses →
nutzt push.
map: kürzest und deklarativ, wenn wirklich nur transformiert wird.
ProJunior Tagebuch – Bookstore Fortschritt
• Modul 7 – Bookstore
Sidebar-Filter: Buttons mit data-* (data-genre,
data-sort)
steuern die Liste.
Hybrid-Setup:initFilters via ES-Import, Daten/Renderer noch über
window.*.
Likes: Herz-Button mit data-slug, Zustand in localStorage.
Aha:dataset ist super benutzerfreundlich.
👉 Volltext lesen
Filter über Sidebar
Bestehende Sidebar-Buttons wurden mit data-* Attributen versehen und per
dataset ausgewertet.
Aktiver Button setzt .is-active; Sort („Beliebt/Neu/Preis ↑↓“) läuft über dieselbe
Pipeline.
Hybrid-Architektur
initFilters() wird als Modul importiert. books und
renderBooks
kommen vorerst
über window.* – so bleibt alles lauffähig, während wir schrittweise auf Module
umstellen.
Renderer vereinheitlicht
Aus renderThumbs() wurde renderBooks(). Filter und Initialrender nutzen
dieselbe Funktion.
Der Dialog klickt immer das richtige Buch, da data-index auf den Original-Index
zeigt.
Like-Funktion
Herz-Button im Dialog: neutral (schwarz/blau) vs. rot bei „Liked“. Zustand in
localStorage (bookstore_likes_v1). Anzeige = Seed-Likes + 1, wenn dieses
Gerät
geliked hat
(displayLikes(b)).
Highlight des Tages
data-* + .dataset: direktes Mapping data-slug="…" →
el.dataset.slug.
Dadurch verbindet sich HTML und JS sehr sauber.
📓 Blogeintrag – 14. September 2025
Kurzzusammenfassung:
Heute habe ich intensiv am Dialog für die Buchkarten im Bookstore-Projekt
gearbeitet. Ziel
war es, beim Anklicken einer Karte eine Detailansicht zu öffnen, die Bild und Buchinfos übersichtlich
darstellt.
Volltext anzeigen
– Startpunkt war die Frage, ob die Detailansicht auf einer neuen Seite oder inline
passieren sollte. Wir haben uns für ein <dialog> entschieden – modern,
barrierearm und
einfach handhabbar.
– Ich habe eine Dialog-Struktur mit Grid umgesetzt:
• Links (50%): Infos (Button „In den Warenkorb“, Titel + Likes, Autor, Jahr, Genre,
Inhaltsangabe)
• Rechts (50%): Das Cover, groß und mit object-fit: cover.
– Zunächst war das Layout verzogen: der Gap teilte das Fenster in der Mitte, und das Bild erschien
nicht
rechts. Ursache war eine doppelte Klasse.dialog-card – einmal auf dem
äußeren
<div>, einmal auf dem <form>. Nachdem ich
class="dialog-card" am <form> entfernt habe, funktionierte das Grid
korrekt.
– Wir haben zusätzlich den Close-Button oben rechts gestylt
(position: absolute; innerhalb von .dialog-card), damit er sich nicht ins
Grid
mischt.
– Nebenbei haben wir auch die Buchkarten im Grid verbessert: Preis sauber unten
mittig,
Thumbnails mit object-fit angepasst.
Fazit: Der Dialog steht jetzt stabil, nutzt die volle Breite und zeigt Bild und
Infos so
an, wie ich es mir vorgestellt habe. Fehlerquelle war das Klassendoppel im HTML.
Bookstore – Covers & Datenstruktur
In diesem Abschnitt habe ich für das neue Projekt Bookstore die Cover der Bücher erstellt,
die Datenstruktur erweitert (Slug, Summary, Bilderpfade) und ein Skript geschrieben,
um aus den PNGs webtaugliche JPGs und Thumbnails zu erzeugen.
Mehr lesen…
Ausgangspunkt war ein JSON-Array mit Beispieldaten: Titel, Autor, Genre, Preis, Likes,
Kommentare. Wir haben es erweitert um zusätzliche Felder:
slug – maschinenfreundlicher Name (kebab-case)
image / thumb – Pfade zu Cover und Thumbnail
alt – Alternativtext für Barrierefreiheit
summary – kurze Inhaltsangabe (von mir frei erfunden)
Anschließend habe ich alle Cover im einheitlichen Stil (malerisch, realistisch, 3:4)
generiert: Die Geheimnisse des Ozeans, Der vergessene Pfad, Die Farben des Himmels,
Das Rätsel der Zeit, Der letzte Wächter, Im Schatten des Mondes,
Das verborgene Königreich, Liebe in Zeiten des Krieges, Jenseits der Sterne.
Um die Bilder im Web performant zu halten, reicht für die Detailansicht
eine Breite von ca. 600 px (~300 KB) und für Thumbnails 220 px (~50 KB).
Dafür haben wir ein kleines Bash-Skript mit convert (ImageMagick) geschrieben:
mkdir -p img thumbs
for f in covers/*.png; do
bn="$(basename "${f%.*}")"
convert "$f" -resize 600x -strip -interlace JPEG -quality 80 "img/${bn}.jpg"
convert "$f" -resize 220x -strip -interlace JPEG -quality 80 "thumbs/${bn}-220.jpg"
done
Damit entsteht pro Cover eine Web-Version und ein Thumbnail.
Die Original-PNGs bleiben erhalten.
Mit den Slugs im JSON lassen sich Bilder sauber und konsistent ansprechen.
Für das Layout haben wir CSS-Variablen eingeführt (Farben, Radius, Schatten),
Buttons im mittelalterlich-angehauchten Rot/Gold-Stil erstellt und eine
zweispaltige Struktur mit fester Sidebar und Grid-Content aufgebaut.
Logo und Farbwelt (Rot + Gold + vergilbtes Weiß) greifen das Bookstore-Thema
konsistent auf.
Damit ist der Grundstein gelegt: Die Bücher können jetzt im Grid gerendert
und über Suche/Filter dynamisch angezeigt werden.
CSS Grid & Zettel-Pinnwand
Heute habe ich meine Notizen mit Zettel-Optik auf einer Korkwand erweitert.
Dabei habe ich viel über CSS-Grid, Kombinatoren und Scrollboxen gelernt...
mehr anzeigen
Ausgangspunkt war die Idee, jede Notiz als „Zettel mit Pinnadel“ darzustellen.
Dafür habe ich ein PNG mit transparentem Hintergrund als Background-Image eingebunden.
Wichtig: das padding steuert, wo der Text im Zettel sitzt, weil das Bild
auch unsichtbare Ränder hat.
Für die Korkwand habe ich ein wiederholbares Hintergrundbild genutzt. Damit die Zettel
nicht einfach untereinander stehen wie in einer Flexbox, sondern wirklich im Gitter
angeordnet sind, kam CSS-Grid ins Spiel:
Ein wichtiges Detail waren die CSS-Kombinatoren. Ich habe gelernt:
– Leerzeichen = Nachfahre
– > = direktes Kind
– + = nächster Bruder
– ~ = alle folgenden Brüder
– , = Gruppierung
Da der Zettel nur eine feste Höhe hat, musste ich den Notiztext in eine
scrollbare Box verpacken. So bleibt die Optik erhalten, auch wenn viel Text
eingetragen wird:
.note_body {
max-height: 164px;
overflow: auto;
}
Ergebnis: eine Pinnwand, die sich automatisch an die Bildschirmbreite anpasst,
Notizen als hübsche Zettel darstellt und auch längere Texte sauber handhabbar macht.
7. September 2025 – kleine Stolpersteine, große Aha-Momente
Textarea: Enter wieder frei, Ctrl+Enter nur zum Speichern.
required/checkValidity für leere Felder.
Umbrüche korrekt anzeigen mit white-space: pre-wrap oder DOM-Aufbau.
Heute habe ich das Verhalten von <textarea> geklärt:
Enter fügt standardmäßig einen Zeilenumbruch ein – nur unser JS kann das mit
preventDefault() verhindern. Daher bleibt Enter frei;
Speichern löse ich gezielt mit Ctrl+Enter aus.
Für valide Eingaben prüfe ich minimal mit
!title.value.trim() bzw. !note.value.trim() oder nutze
checkValidity() (respektiert required).
So bleiben Arrays/Objekte konsistent.
Um Zeilenumbrüche sichtbar zu machen, nutze ich entweder
white-space: pre-wrap; auf dem Textknoten oder (schöner)
baue Elemente direkt im DOM:
Außerdem habe ich verstanden: addEventListener registriert einmalig
und bleibt aktiv, solange das Element existiert. Wichtig ist die Reihenfolge:
erst Elemente im DOM, dann Listener binden.
Zukunfts-Notiz: geplanter Prototyp „Pseudo-3D Breakout“ (Paddle in mittlerer
50%-Zone in x/y; Ball-Tiefe nur über Größe). Umsetzung später, ohne Arrow-Functions.
2025-09-06 · Was ich heute gelernt habe
Hamburger-Menü mit Fokus-Trap & Back-Button-Close gebaut – und den Unterschied zwischen
JavaScript-Objekten und JSON (plus Object.keys/values/entries) klargezogen.
Mehr lesen
1) Responsive Navigation (Hamburger)
Mobiles Off-Canvas-Menü (öffnet per Button, schließt per ESC, Backdrop-Klick oder Link-Klick).
Fokus-Trap: Tab/Shift+Tab bleiben im Menü; beim Schließen geht der Fokus
zurück zum
Auslöser.
Back-Button: Der Browser-Zurück-Button schließt das Menü statt die Seite zu
verlassen.
Aktiver Link über aria-current="page" (robuste
URL-Normalisierung).
2) Objekte, Keys und JSON
Object.keys(), Object.values(), Object.entries() für
strukturierte Iteration.
Objekt = lebendige JS-Datenstruktur im Code; JSON =
serielles
Textformat für Austausch (APIs/DB).
Wichtig für spätere Backend-Kommunikation: JSON <-> Objekt sauber transformieren.
Navigation ist jetzt nutzerfreundlich & zugänglich, und die Basis für Daten-Austausch
(Objekt vs. JSON) sitzt. Gute Vorbereitung für kommende API/DB-Schritte.
Objekte & Methoden – von Daten zu Verhalten
4. September 2025: verschachtelte Objekte lesen, dynamisch per Klammer-Notation zugreifen, mit
console.table() debuggen –
und meine erste klare Idee, warum Methoden (Funktionen im Objekt) so nützlich sind.
DNS geprüft (A/AAAA), Let’s Encrypt aktiviert, ACME-Check ok. Subdomain-Ziel auf
~/public_html/matomo gesetzt und DirectoryIndex index.php ergänzt,
damit der
Installer statt meiner index.html lädt.
Matomo-Deployment & Härtung
mkdir -p ~/matomo-sec
for d in config tmp misc; do
mv ~/public_html/matomo/$d ~/matomo-sec/
ln -s ~/matomo-sec/$d ~/public_html/matomo/$d
done
chmod -R 775 ~/matomo-sec/tmp
chmod 640 ~/matomo-sec/config/config.ini.php
Datenbank
DB qerevaxi_matomoProd, User qerevaxi_matomoP, Login getestet;
Charset/Kollation
auf utf8mb4 / utf8mb4_unicode_ci gestellt.
ALTER DATABASE `qerevaxi_matomoProd`
CHARACTER SET utf8mb4
COLLATE utf8mb4_unicode_ci;
Tracking & Datenschutz
Snippet im <head> eingebaut (fest auf HTTPS). Optional cookielos aktivierbar.
Icons in /img/favicon/, Manifest im Webroot und MIME-Type per
.htaccess
gesetzt.
AddType application/manifest+json .webmanifest
Frontend-Fixes
Mobile-Menü: aria-expanded, ESC-Close, Backdrop-Close, Auto-Close bei >680px
JS-Fehler „addEventListener is not a function“ behoben (keine Collections mehr)
Rainbow-Effekt jetzt für alle Buttons (Pointer + Keyboard, optional "reduced motion")
Notizen: Archiv-Cron später einrichten, eigene Besuche in Matomo ausschließen,
Screenshots
fürs
Manifest nachreichen.
Vibecoding – Flow statt nur Ergebnis
01.09.2025 • Notizblock-Projekt
In den letzten Tagen bin ich bei der Arbeit am Notizblock-Projekt ins Grübeln gekommen:
Geht es beim Coden nur darum, möglichst schnell lauffähigen Code zu erzeugen – oder steckt mehr
dahinter?
„Vibecoding“ beschreibt für mich eine alternative Herangehensweise: Coden wie eine Jam-Session.
Nicht nur das Endergebnis zählt, sondern auch der Rhythmus, das Experimentieren, die Aha-Momente.
Meine Session-Struktur
Warm-up: kleiner Einstieg, wie beim Stimmen eines Instruments.
Exploration: freies Ausprobieren mit einer Leitfrage.
Anchor: kurze Notiz/Zusammenfassung, die den Flow festhält.
Deep Dive (optional): gezielt in neue Konzepte eintauchen.
Cool Down: kurz aufräumen und committen – Session rund machen.
Spannend ist die Frage, wie sich Vibecoding in quirinpflaum.ch integrieren lässt:
Soll es ein internes Ritual bleiben, das mich durch meine Lernphasen begleitet?
Oder wird es sichtbar – als Feature auf der Seite, das zeigt, wie ich Coden verstehe?
Offene Frage: Möchte ich Vibecoding als internes Werkzeug nutzen – oder es zu
einem
öffentlichen Teil meines Profils machen?
31. August: Vorläufige Fertigszellung des geplanten Notizblock
LocalStorage implementiert. Dort können jetzt Notizen geladen und gespeichert
werden
Fortschritt des Tages
Lokale Speicherung (localStorage):
Notizen werden mit nb:-Präfix und optionalem Zähler gespeichert.
Beim Laden filtere ich gezielt mit startsWith(), entferne das Präfix per
slice/split, und setze die Arrays vorher zurück.
localStorage.clear() löscht alles, daher besser gezielt mit
removeItem().
Neue Befehle/Begriffe:Math.min, continue, String(...),
localStorage.getItem/setItem, while,
?. (Optional Chaining), Guard-Muster if (n)…,
Fallback || und ??, .trim(),
.startsWith(), .slice(), .split().
Fehler behoben:
Event-Handling korrigiert (Event muss übergeben werden),
Tippfehler bei Variablennamen, .hidden-Klasse ergänzt.
Styling mit Grid:
Das Formular in .note zum Grid-Container gemacht:
Input links oben, Button links unten, Textarea rechts über zwei Reihen.
Syntaxfehler in grid-area korrigiert.
CSS-States bei Buttons::active, :focus, :disabled,
:checked sowie moderne Selektoren wie :has()
und Attribute wie aria-pressed kennengelernt.
Fazit: Heute viel Stabilität in den Code gebracht und einige wichtige
JavaScript- und CSS-Bausteine dazugelernt.
30. August: Fortschritte beim Notizblock
Papierkorb-System steht, Arrays sauber gekoppelt. Als Nächstes: LocalStorage.
Heute habe ich das Papierkorb-System für meinen Notizblock aufgebaut und dabei
meine
Arbeit mit Arrays vertieft.
Erkenntnisse
Notizen: notesTitles + notes (synchron).
Papierkorb: trashTitles + trash, verschieben via
splice().
Synchronität der Indizes ist entscheidend.
Rendering: Titel + Text in einer Schleife ins DOM.
Heute habe ich mich wieder intensiv mit meinem Notizblock‑Projekt beschäftigt.
Ich habe verstanden, wie e.preventDefault() bei submit das
Standardverhalten
(Seiten‑Reload) verhindert und wie ich damit den Flow vollständig im JavaScript halten kann.
Außerdem wurde mir klarer, dass Event‑Handler ein eigenes Event‑Objekt e übergeben, das
ich
gezielt auswerten kann (z. B. für keydown vs. submit).
Fazit: Mein Verständnis für DOM‑Events und sauberes Event‑Handling
wächst
weiter – kleine Schritte, aber spürbarer Fortschritt.
•Tagesnotiz
🌙 Tagesabschluss – 24. August
100% Arbeiten und dann am Abend noch coden, ist manchmal anstrengender als anfangs vermutet.
Heute letzte Gedanken zur User-Story gebildet. Die "Mechanik" ist jetzt klar.
Nur noch ein klein wenig am Design am Papierkorb.
Ab Semptember werde ich nur noch 80% arbeiten und fortan den Mittwoch noch Zeit haben, um zu
programmieren.
Vielleicht befinde ich mich auch gerade auf diesem oft zitierten Plateau und ich muss das Gelernte
einfach
einmal sacken lassen.
🌙 Tagesabschluss – 23. August
Heute hatte ich wenig Zeit zum Programmieren. Ich war mit Freunden bei einem entspannten Nachmittag
in
der
Nähe
von Bern
Deshalb gab es abends lediglich einige gestalterische Änderungen im CSS. Zudem erste Überlegungen und
Experimente zu einem Papierkorb.
📓 Tagesnotiz – 23. August 2025
Heute habe ich weiter an meinem JavaScript-Notizblock gearbeitet. Dabei ging es vor allem um das
Anzeigen
und
Rendern der Notizen im DOM. Besonders hilfreich war für mich der Tipp, Arrays beim Entfernen von
hinten
nach
vorne zu durchlaufen – das erspart Fehler und macht den Code robuster.
Außerdem habe ich mit hidden und einer kleinen Utility-Funktion das Ein- und Ausblenden
von
UI-Elementen gelernt. Das stärkt mein Grundverständnis dafür, wie ich Logik sauber ins JavaScript
verlagern
kann.
Nebenbei habe ich mich noch mit Arrow Functions und dem Unterschied zu normalen Funktionen beschäftigt
–
und
langsam sickert das neue Wissen immer mehr ein.
Alles in allem: ein produktiver Tag, mit kleinen, aber entscheidenden Aha-Momenten.
🌙 Tagesabschluss – 22. August
Heute habe ich im Modul 7 – JavaScript Projekte weiter am Notizblock
gearbeitet.
Die Grundfunktionen sind nun vorhanden:
Notizen anzeigen
schicker darstellen
neue Notizen hinzufügen
Notizen löschen
Besonders spannend war die Erkenntnis, dass man beim Entfernen von Einträgen in einer Schleife besser
von hinten nach vorne geht – sonst springt der Index durcheinander. Wieder ein kleiner, aber
wichtiger Aha-Moment.
Als Nächstes steht der Papierkorb (Trash) an, damit gelöschte Notizen nicht sofort
verschwinden,
sondern erst einmal zwischengelagert werden.
So wächst der Notizblock Schritt für Schritt – und mit ihm mein Verständnis für
DOM-Logik, Arrays und saubere Schleifen.
👉 Weitergeführt habe ich außerdem die Grundstruktur meiner Website quirinpflaum.ch,
sodass die Fortschritte auch nach außen hin langsam sichtbar werden.
Donnerstag, 21. August 2025
Der Tag war lang, aber ich habe es geschafft, noch ein kleines Stück am neuen Projekt
Notizblock zu arbeiten. Viel weiter bin ich heute zwar nicht gekommen, dafür konnte ich
die Struktur schon anlegen und die ersten Funktionen ausprobieren. Bevor die Augen zufallen, lade ich
die aktuelle Version noch per FileZilla hoch – ein kleines Update, das den Grundstein für die nächsten
Schritte legt.
Nebenbei habe ich auch an der Grundstruktur für quirinpflaum.ch weitergebaut.
Schritt für Schritt wächst das Gerüst meiner Seite, und selbst kleine Anpassungen fühlen sich wie
ein Fortschritt an. Manchmal reicht es, dranzubleiben, auch wenn es nur ein kleiner Baustein ist.
Fotogram ist abgenommen 🎉
•Projekt-Update
Heute habe ich mein Projekt Fotogram erfolgreich abgeschlossen.
Ein wichtiger Meilenstein auf meinem Weg als Frontend-Dev. Nächster Schritt: den Blog hier täglich
kurz
füttern.