Das KonzeptThe concept
Die Seite erzählt eine einzige Idee, und zwar mit ihrer eigenen Bauweise: zwei Ebenen, eine Schnittstelle. Hinten liegt eine dunkle Code-Ebene mit Raster und echten Snippets, vorne stehen helle Editorial-Karten mit Serifen-Überschriften. Dazwischen bricht der Code immer wieder durch die schöne Oberfläche.
The site tells a single idea, and it tells it through its own construction: two layers, one interface. Behind sits a dark code layer with a grid and real snippets, in front stand light editorial cards with serif headlines. And the code keeps breaking through that polished surface.
Das ist keine Dekoration, sondern die Berufsbeschreibung. Wirtschaftsinformatik heißt, zwischen diesen beiden Welten zu übersetzen, und statt das in einen Satz über mich zu schreiben, macht es die Seite vor: Kanten sind angefressen, Karten korrumpieren, Text läuft an den Rissen als Code weiter.
That is not decoration but the job description. Business informatics means translating between those two worlds, and instead of writing a sentence about myself, the site demonstrates it: edges are eaten away, cards corrupt, text continues as code where it tears open.
Die gesamte Deko ist JS-generiert und seeded: Ein Zufallsgenerator mit festem Startwert erzeugt Risse, Pixel und Glyphen pro Seitenaufruf neu, aber pro Neuaufbau identisch. Deshalb bleibt beim Sprachwechsel die komplette Deko exakt stehen und nur der Text blendet. Ohne das würfelt jeder Wechsel alles neu und das Geflacker macht ihn unruhig.
All decoration is JS-generated and seeded: a random generator with a fixed seed produces tears, pixels and glyphs anew per page load but identically per rebuild. That is why the entire decoration stays exactly in place during a language switch and only the text fades. Without it, every switch reshuffles everything and the flicker makes it restless.
Was drinstecktWhat is in it
EffekteEffects
- Decode-Intro. Der Name im Kopf entsteht aus grünen Mono-Glyphen, flackert und löst sich von links nach rechts auf. Jede Sektionsüberschrift wiederholt das im Kleinen, sobald man sie hereinscrollt.
- Decode intro. The name in the header forms out of green mono glyphs, flickers and resolves left to right. Every section heading repeats that in miniature as you scroll it into view.
- Scroll-Reveal. Sektionen faden mit leichtem Anstieg ein. Wiederholbar: Verlässt eine Sektion den Viewport ganz, läuft der Effekt beim nächsten Mal erneut.
- Scroll reveal. Sections fade in with a slight rise. Repeatable: once a section leaves the viewport entirely, the effect runs again next time.
- Maus-Spotlight. Ein akzentfarbener Schein folgt dem Zeiger und hellt per mix-blend-mode: screen nur Dunkles auf. Papier und Text bleiben unberührt, die Code-Ebene und die Risse leuchten mit.
- Mouse spotlight. An accent-colored glow follows the pointer and, via mix-blend-mode: screen, brightens only dark areas. Paper and text stay untouched while the code layer and the tears light up.
- Rasterglut. Neben dem Schein glimmen unter dem Zeiger auch die Rasterlinien der Code-Ebene selbst auf, und die Code-Schnipsel in seiner Nähe werden kurz lesbar. Ein Canvas hinter dem Papier malt nur die Linienstücke im Umkreis, der Effekt kostet deshalb keine Bildrate. Die dunklen Fenster in den Karten tragen eigene kleine Canvases, pixelgenau ausgerichtet, damit die Glut über deren Kanten hinweg fluchtet.
- Grid glow. Next to the glow, the grid lines of the code layer themselves light up under the pointer, and the code snippets near it briefly become readable. A canvas behind the paper draws only the line segments within reach, so the effect costs no frame rate. The dark windows inside the cards carry their own small canvases, pixel-aligned so the glow lines up across their edges.
- Pixel-Risse. Hero, Erfahrung, Ausbildung, Skills, Projekte und Kontakt haben aufgerissene Kanten mit Rinnsalen, Tropfen und Pools. Jede Risstiefe wird aus den echten Elementpositionen gedeckelt, damit nie Inhalt weggeschnitten wird.
- Pixel tears. Hero, experience, education, skills, projects and contact have torn edges with trickles, drips and pools. Every tear depth is capped from the real element positions so content never gets cut off.
- Korrumpierte Karte. Die Projektkarte über diese Website ist selbst befallen: rechte Hälfte dunkel, Zeichen kippen laufend in grüne Mono-Glyphen, alle sieben Sekunden ein Zucken.
- Corrupted card. The project card about this website is infected itself: right half dark, characters constantly flipping into green mono glyphs, a twitch every seven seconds.
Zwei Easter EggsTwo easter eggs
- Die Schach-Ecke. Fünf spielbare Rätsel in aufsteigender Schwierigkeit, von Matt in 1 bis zu Philidors ersticktem Matt in 4. Drag & Drop oder Klick-Klick, Schwarz antwortet gescriptet und animiert, nach drei Fehlversuchen gibt es einen Hinweis. Jede Stellung ist handverifiziert: Jede Antwort ist erzwungen oder alle Alternativen sind ebenfalls matt.
- The chess corner. Five playable puzzles in ascending difficulty, from mate in 1 to Philidor's smothered mate in 4. Drag and drop or click-click, Black responds with scripted animated moves, and after three failed attempts you get a hint. Every position is hand-verified: each response is forced, or every alternative is also mate.
- ai_takeover.exe. Der Button in der Fußzeile startet eine KI-Übernahme: bis zu 4.000 Pixel fluten die Seite, sämtliche Texte korrumpieren zeichenweise, eine Prozentzahl zählt hoch, und bei 100 % tippt sich ein KI-Log mit einer Pointe ins Bild. Danach stellt sich alles zeichengenau wieder her, weil die Originaltexte vorher in einer Map gesichert werden.
- ai_takeover.exe. The footer button starts an AI takeover: up to 4,000 pixels flood the page, all texts corrupt character by character, a percentage counts up, and at 100% an AI log types itself onto the screen with a punchline. Afterwards everything restores character-perfect, because the original texts were saved into a map beforehand.
Zwei Sprachen, ein PflegeortTwo languages, one source
Deutsch steht im HTML, Englisch in einem Wörterbuch im Skript, das per CSS-Selektor tauscht. Ein Pflegeort, drei Auslieferungen: Die Seite hat drei sehr verschiedene Leser, und nur einer davon führt JavaScript aus.
German sits in the HTML, English in a dictionary in the script that swaps by CSS selector. One place to edit, three things shipped: this site has three very different readers, and only one of them runs JavaScript.
- Der Leser mit Browser. Sichtbare Karten lösen sich in bis zu 180 Partikel auf, gut die Hälfte davon grüne Code-Glyphen. Nach 240 Millisekunden steht die Karte auf unsichtbar, genau dort wird getauscht, dann kommt sie in 50-Millisekunden-Staffeln zurück und die Überschriften decodieren neu. Damit dabei nichts springt, wird jede Karte vorher auf die größere der beiden Sprachhöhen genagelt.
- The reader with a browser. Visible cards dissolve into up to 180 particles, more than half of them green code glyphs. At 240 milliseconds the card sits at invisible, which is exactly when the text is swapped, then it returns in 50-millisecond stages while the headings decode anew. So that nothing jumps, every card is pinned beforehand to the taller of the two language heights.
- Der Leser ohne JavaScript. /en war lange nur eine Umschreibung auf dieselbe deutsche Datei. Im Browser sah das englisch aus, für LinkedIn, Slack und die meisten KI-Crawler lag dort aber deutsches Roh-HTML mit deutschem Titel, dazu ein Canonical auf /, während die hreflang-Tags Englisch behaupteten. Solche Widersprüche löst Google zugunsten des Canonicals auf, die englische Fassung rankt dann nie. Heute baut ein Node-Skript aus dem deutschen Original echte englische Dateien, für die Startseite und für alle Projektseiten.
- The reader without JavaScript. /en was long just a rewrite onto the same German file. In a browser it looked English, but LinkedIn, Slack and most AI crawlers found raw German HTML with a German title there, plus a canonical pointing at /, while the hreflang tags claimed English. Google resolves contradictions like that in favor of the canonical, so the English version never ranks. Today a Node script builds real English files out of the German original, for the home page and for all project pages.
- Der Generator ist zugleich der Test. Er zieht das Wörterbuch aus dem Original und dupliziert nichts, und er bricht laut ab, sobald einer seiner Selektoren ins Leere greift. Genau das passiert beim Umsortieren zweier Blöcke, wenn ein nth-of-type still auf den falschen zeigt. Früher fiel so ein Bruch erst live auf, jetzt vor dem Commit.
- The generator doubles as the test. It pulls the dictionary out of the original, duplicating nothing, and fails loudly the moment one of its selectors grabs at nothing. Which is what happens when two blocks get reordered and an nth-of-type quietly points at the wrong one. That break used to surface only in production, now before the commit.
- Der Leser ohne CSS. Die Projektseiten tragen beide Sprachen nebeneinander im HTML, das CSS blendet die jeweils andere aus. Das erspart die Umsortier-Fallen des Wörterbuchs, ergibt ohne Stylesheet aber einen Text, in dem sich deutsche und englische Sätze abwechseln, und die Diagrammwerte entstehen ohnehin erst per JavaScript aus data-n. Deshalb liegt neben jeder Seite eine Markdown-Fassung: einsprachig, Balken als Aufzählung, Matrizen als Tabelle.
- The reader without CSS. The project pages carry both languages side by side in the HTML and the CSS hides the other one. That avoids the reordering traps of the dictionary, but without a stylesheet it reads as German and English sentences alternating, and the chart values only come into being through JavaScript from data-n anyway. So next to every page sits a Markdown version: single-language, bars as a list, matrices as a table.
Wie sie betrieben wirdHow it runs
Stack und AuslieferungStack and delivery
- Vercel als Hosting, angebunden an GitHub: Ein Push auf main ist das Deployment. Kein Build-Schritt, weil es nichts zu bauen gibt.
- Vercel for hosting, wired to GitHub: a push to main is the deployment. No build step, because there is nothing to build.
- Zwei Domains, clemenshoeller.at und clemenshöller.at. Alle Nebenvarianten inklusive www und der Punycode-Fassung laufen als dauerhafte Weiterleitung auf die Hauptdomain, wobei der Pfad erhalten bleibt.
- Two domains, clemenshoeller.at and clemenshöller.at. All secondary variants including www and the punycode version run as permanent redirects to the main domain, preserving the path.
- Sprach-URLs: / ist deutsch, /en englisch, beide als eigene Datei aus derselben Quelle generiert. Der Pfad gewinnt über die gemerkte Sprachwahl, damit ein geteilter Link richtig aufmacht.
- Language URLs: / is German, /en English, each shipped as its own file generated from the same source. The path wins over the remembered language choice, so a shared link opens correctly.
- Deeplinks auf einzelne Projekte: /#gvc springt zur Projektsektion und öffnet direkt das passende Fenster. Praktisch für Bewerbungen.
- Deep links to individual projects: /#gvc jumps to the projects section and opens the matching panel directly. Useful for applications.
- Eigene Projektseiten unter /projekte/, je eine pro Projektkarte, erreichbar über „Mehr erfahren“ im Projekt-Fenster. Sie teilen sich ein Stylesheet und ein Skript und tragen dieselben Effekte wie die Startseite.
- Dedicated project pages under /projekte/, one per project card, reachable through “Read more” in the project panel. They share one stylesheet and one script and carry the same effects as the home page.
- Eigene 404-Seite im selben Zwei-Ebenen-Look, mit gekürzter Navigation, eigenem Sprach-Wörterbuch und derselben Wechsel-Choreografie.
- A custom 404 page in the same two-layer look, with a shortened navigation, its own language dictionary and the same switching choreography.
SicherheitSecurity
Die Seite setzt Security-Header, unter anderem nosniff, eine strenge Referrer-Policy, X-Frame-Options gegen Einbettung, eine Permissions-Policy, die Kamera, Mikrofon und Standort abschaltet, und eine Content Security Policy, die alle Quellen auf die eigene Domain begrenzt. Das ist der Grund, warum es hier keine Chart-Library und keine geladenen Schriften gibt: Die Diagramme auf den Projektseiten sind HTML und CSS, die Schriften kommen aus dem System.
The site sets security headers, among them nosniff, a strict referrer policy, X-Frame-Options against embedding, a permissions policy that switches off camera, microphone and location, and a content security policy restricting all sources to the site's own domain. That is why there is no chart library and no loaded fonts here: the diagrams on the project pages are HTML and CSS, and the typefaces come from the system.
Wie sie gefunden wirdHow it gets found
Die Seite ist bewusst offen für Maschinen gebaut, und zwar für zwei Sorten: klassische Suchmaschinen und Sprachmodelle, die für Recruiter recherchieren.
The site is deliberately built to be open to machines, of two kinds: classic search engines and language models researching on behalf of recruiters.
- llms.txt im Wurzelverzeichnis fasst Profil, Skills, Projekte, Dokumente und Kontakt in einer maschinenlesbaren Datei zusammen. Wenn ein Modell diese Seite liest, muss es die Kernfakten nicht aus der Deko herausklauben.
- llms.txt in the root sums up profile, skills, projects, documents and contact in one machine-readable file. When a model reads this site, it does not have to dig the core facts out of the decoration.
- sitemap.xml mit allen Seiten, Dokumenten und beiden Sprachfassungen, jeweils mit hreflang-Verweisen aufeinander.
- sitemap.xml with all pages, documents and both language versions, each with hreflang references to the other.
- Strukturierte Daten als JSON-LD: Person, Rolle, Arbeitgeber, Ausbildung und Themen auf der Startseite, wissenschaftliche Arbeit je Projektseite.
- Structured data as JSON-LD: person, role, employer, education and topics on the home page, and a scholarly-article record per project page.
- Eine permissive robots.txt. Kein Ausschluss von KI-Crawlern, weil genau das hier der Punkt ist.
- A permissive robots.txt. No exclusion of AI crawlers, because that is exactly the point here.
- Favicon als echte Dateien in vier Formaten statt als data-URI. Google konnte die eingebettete Variante nicht crawlen, und ohne gecrawltes Favicon steht in den Suchergebnissen nur ein grauer Platzhalter.
- Favicon as real files in four formats instead of a data URI. Google could not crawl the embedded variant, and without a crawled favicon the search results only show a grey placeholder.
Was mich das gelehrt hatWhat it taught me
Vor allem, dass die Details die Arbeit sind. Eine Karte, die beim Sprachwechsel um vier Pixel springt, fällt sofort auf. Ein Riss, der zwei Prozent zu tief geht, frisst eine Textzeile. Ein Decode-Effekt, dessen Mono-Glyphen breiter sind als die Serifen, lässt eine Überschrift kurz zweizeilig umbrechen und die ganze Karte hüpfen. Nichts davon steht in einem Tutorial, alles davon merkt man erst, wenn man es sich hundertmal ansieht.
Above all that the details are the work. A card that jumps four pixels during a language switch is immediately noticeable. A tear that goes two percent too deep eats a line of text. A decode effect whose mono glyphs are wider than the serifs makes a heading briefly wrap onto two lines and the whole card hop. None of that is in a tutorial, and all of it only shows up once you have looked at it a hundred times.
Und dass „ohne Framework“ keine Härteprüfung ist, sondern eine Entscheidung mit Konsequenzen: Man schreibt mehr selbst, versteht dafür jede Zeile, und die Seite lädt in einem einzigen Request.
And that "no framework" is not a test of toughness but a decision with consequences: you write more yourself, in exchange you understand every line, and the page loads in a single request.
Verwandte ProjekteRelated projects
Die Projekte hängen stärker zusammen, als die Kacheln auf der Startseite vermuten lassen. Hier stehen alle anderen, sortiert nach Nähe zu diesem Projekt:
These projects connect more tightly than the tiles on the home page suggest. Here are all the others, sorted by how closely they relate to this one: