Zurück zum Blog

Aug. 2026 · 9 Min. Lesezeit

Die Bausteine dieser Website

Im August 2026 habe ich mein Portfolio neu gebaut. Dieser Katalog zeigt jedes UI-Element als lebendes Beispiel — und begründet, warum es so aussieht.

Im August 2026 habe ich dieses Portfolio von Grund auf neu gebaut. Vorher gab es zwei Quellen für dieselben Farben, einen Light Mode, der auf der Startseite gar nicht funktionierte, und 654 Zeilen Canvas-Code für einen Hintergrund. Der Umbau hat das auf einen Satz Tokens und eine Handvoll Bausteine zusammengezogen.

Dieser Beitrag ist der Katalog dazu. Jede Ebene zeigt links das echte Element — keine Abbildung, sondern dieselbe Komponente, die auch der Rest der Seite verwendet. Wechselst du oben rechts das Theme, wechseln die Beispiele mit. Rechts steht, warum das Element so gebaut ist.

  • --bg
  • --surface
  • --elevated
  • --border
  • --text
  • --muted
  • --accent

src/app/globals.css

01

Farbtokens statt Farbwerte

Farben stehen an genau einer Stelle: als CSS-Variablen im Wurzel-Selektor, ein zweites Mal überschrieben für das dunkle Theme. Tailwind liest sie über rgb(var(--surface) / <alpha-value>), damit Abstufungen wie bg-surface/80 weiter funktionieren.

Der Gewinn zeigt sich im Komponentencode: dort steht bg-surface text-textkein einziges dark:. Vorher waren es 54 solcher Präfixe, und jeder war eine Stelle, an der ein Element in nur einem Theme richtig aussah.

Die Werte sind nicht nach Gefühl gewählt. Der schlechteste Kontrast von Fließtext über den farbigen Flächen im Hintergrund liegt bei 6,7:1 im dunklen und 7,5:1 im hellen Theme — gemessen am hellsten Punkt jeder Fläche, nicht am Durchschnitt.

Eyebrow

Überschrift

Fließtext in 16 px, so gesetzt, dass eine Zeile bequem gelesen wird.

Nebentext für Datum, Ort und Quellen.

src/design-system/index.ts

02

Eine Schriftskala, die mitwächst

Die alte Version hatte die Tailwind-Skala global vergrößert: text-base waren 19 px statt 16 px. Auf dem Desktop fiel das kaum auf, auf dem Handy wirkte jede Seite aufgeblasen und Überschriften brachen an unpassenden Stellen um.

Jetzt gilt wieder die Standardskala, und nur die drei Display-Größen sind fluide: clamp(2.25rem, 6vw, 4rem) für die Seitenüberschrift. Zwischen Handy und großem Monitor skaliert sie stufenlos, ohne dass für jede Breite eine eigene Regel nötig wäre.

Die Monospace-Schrift trägt Datumsangaben, Kategorien und kleine Marken. Sie markiert Technisches und hält es zugleich vom Fließtext getrennt.

Projekte ansehenKontakt aufnehmenBlogmin-height 44 px

src/design-system/index.ts

03

Drei Knöpfe, ein Fokus-Stil

Mehr als drei Schaltflächen-Varianten braucht eine Portfolio-Seite nicht: eine für die Hauptaktion, eine für alles Gleichrangige, eine für Navigation im Header.

Alle drei haben min-height: 44px. Das ist die Größe, die eine Fingerkuppe zuverlässig trifft — die häufigste Ursache für Fehlklicks auf Mobilgeräten sind zu kleine Ziele, nicht zu kleine Schrift.

Den Fokusrahmen definiert eine einzige Regel für alles Interaktive, gespeist aus --ring. Wer mit der Tastatur navigiert, sieht überall denselben Rahmen, und keine neue Komponente kann ihn vergessen.

Redis mit Hochverfügbarkeit

Automatisiertes Deployment auf Kubernetes, Failover über Sentinel.

  • Redis
  • K8s
  • Helm
GitHub

src/components/sections/projects.tsx

04

Projektkarte

Eine Karte trägt Titel, zwei bis drei Sätze Ergebnis, den Stack als Chips und die Links. Mehr nicht — wer Projekte überfliegt, liest Titel und Stack, alles andere ist Beiwerk.

Anfangs war die erste Kachel doppelt so groß wie die übrigen. Das sah dynamischer aus, hat aber eine Rangfolge behauptet, die es nicht gibt: alle Projekte sind gleich echt. Jetzt sind alle Kacheln gleich groß, das Raster ist ruhig, und die Reihenfolge allein setzt den Schwerpunkt.

Beim Überfahren ändert sich nur die Rahmenfarbe. Karten, die sich anheben oder vergrößern, lassen den Text springen — bei sechs Kacheln nebeneinander wird das schnell unruhig.

DevOps

  • Linux
  • Docker
  • K8s
  • Ansible

src/components/sections/skills.tsx

05

Technologien nach Aufgabe

Die Technologien standen zuerst neben den Projekten in derselben Reihe. Das las sich, als gehörten sie zusammen — tatsächlich beantworten sie eine andere Frage: nicht was habe ich gebaut, sondern womit arbeite ich.

Jetzt haben sie einen eigenen Abschnitt, eine Karte je Kategorie: DevOps, Datenbanken, Backend, Frontend, Werkzeuge. Die Gruppierung erzählt mehr als eine alphabetische Liste, weil sie den Schwerpunkt sichtbar macht.

Bewusst ohne Sterne oder Prozentbalken. Solche Bewertungen behaupten eine Genauigkeit, die niemand prüfen kann; die Einordnung liefern Werdegang und Projekte.

  1. Juli 2025 — heute

    DevOps Engineer

  2. Sept. 2022 — Juli 2025

    Ausbildung Systemintegration

src/components/sections/experience-timeline.tsx

06

Werdegang als Zeitstrahl

Der Werdegang ist die einzige Stelle, an der Reihenfolge tatsächlich Bedeutung trägt — also bekommt er die einzige Linie auf der Seite.

Zeiträume stehen in Monospace über der Position. Sie sind so kurz, dass sie auf jeder Breite in eine Zeile passen, und durch die feste Zeichenbreite stehen sie untereinander bündig.

Die Punkte sitzen auf der Linie und sind vom Vorlesen ausgenommen: sie tragen keine Information, die nicht schon im Text steht.

JH
  • Start
  • Projekte
  • Kontakt

src/components/header.tsx

07

Drei Wege durch eine Seite

Weil alles auf einer Seite liegt, gibt es drei Zugänge. Der Header führt zu Abschnitten und zum Lebenslauf. Unter 768 px wandern die Links ins Menü, sichtbar bleiben Marke, Theme, Sprache und der Lebenslauf-Knopf.

Rechts markiert die Punktleiste den aktuellen Abschnitt. Ein IntersectionObserver beobachtet dafür einen schmalen Streifen um die Bildschirmmitte — ohne diesen Streifen springt die Markierung bei langen Abschnitten hin und her. Ab 1024 px eingeblendet, darunter wäre sie nur im Weg.

Alle Ankerziele haben scroll-margin-top. Ohne das schiebt der klebende Header genau die Überschrift unter sich, zu der man gerade gesprungen ist.

Raster + Farbflächen

src/components/backgrounds/dot-grid.tsx

08

Hintergrund, der nicht stört

Der Vorgänger war ein Sternenfeld: 654 Zeilen Canvas, eine Zeichenschleife auf jeder Seite, spürbar auf dem Akku. Ersetzt hat ihn ein radial-gradient-Muster als Punktraster — reines CSS, keine Zeichenschleife.

Darüber ziehen drei Farbflächen langsam ihre Bahn. Animiert wird ausschließlich transform, also übernimmt der Compositor die Arbeit; Layout und Paint bleiben unberührt. Im dunklen Theme sind es tiefe statt heller Töne: sie färben den Grund, ohne ihn aufzuhellen, und der Text darüber bleibt lesbar.

Das Raster folgt beim Scrollen leicht versetzt, der weiche Schein folgt dem Zeiger — Letzteres nur bei pointer: fine, auf Touchgeräten wird der Listener gar nicht erst registriert. Bei prefers-reduced-motion: reduce steht alles still.

Was ich daraus mitgenommen habe

Der größte Effekt kam nicht von einer neuen Farbe, sondern davon, die Farben nur noch einmal zu definieren. Danach war jede weitere Entscheidung billig: ein zweites Theme kostet ein paar Zeilen, keine Durchsicht aller Komponenten.

Der zweitgrößte Effekt war Löschen. Ein ungenutztes 600-KB-Paket, ein zweiter Hero, ein ganzer Analytics-Stack, 40 % weniger Code als vorher — und die Seite kann seither mehr.

Der Code liegt offen: github.com/JahongirHabibov