Update: Aktuelle Änderungen
Deploy Portfolio / deploy (push) Successful in 26s

This commit is contained in:
2026-05-10 13:05:00 +02:00
parent 6f9e92c55f
commit 4b2300234c
37 changed files with 814 additions and 80 deletions
+8
View File
@@ -0,0 +1,8 @@
{
"recommendations": [
"esbenp.prettier-vscode",
"dbaeumer.vscode-eslint",
"ms-dotnettools.csdevkit",
"bradlc.vscode-tailwindcss"
]
}
+30
View File
@@ -0,0 +1,30 @@
{
"editor.formatOnSave": true,
"editor.defaultFormatter": "esbenp.prettier-vscode",
"prettier.printWidth": 120,
"editor.rulers": [120],
"editor.codeActionsOnSave": {
"source.fixAll.eslint": "always",
"source.organizeImports": "always"
},
"javascript.format.semicolons": "insert",
"typescript.format.semicolons": "insert",
"typescript.format.insertSpaceAfterCommaDelimiter": true,
"typescript.tsdk": "node_modules/typescript/lib",
"typescript.enablePromptUseWorkspaceTsdk": true,
"explorer.compactFolders": false,
"editor.bracketPairColorization.enabled": true,
"editor.guides.bracketPairs": "active",
"files.insertFinalNewline": true,
"files.trimTrailingWhitespace": true,
"files.autoSave": "onFocusChange",
"editor.linkedEditing": true,
"search.exclude": {
"**/node_modules": true,
"**/dist": true,
"**/pnpm-lock.yaml": true
},
"files.watcherExclude": {
"**/node_modules/*/**": true
}
}
+41 -2
View File
@@ -64,11 +64,50 @@
\@writefile{lol}{\contentsline {lstlisting}{\numberline {17}Vollständige App.tsx mit Tailwind-Styling}{9}{lstlisting.17}\protected@file@percent }
\BKM@entry{id=19,dest={73756273656374696F6E2E312E3135},srcline={406}}{5C3337365C3337375C303030545C303030615C303030695C3030306C5C303030775C303030695C3030306E5C303030645C3030302D5C3030304B5C3030306C5C303030615C303030735C303030735C303030655C3030306E5C3030305C3034305C303030695C3030306D5C3030305C3034305C3030305C3333345C303030625C303030655C303030725C303030625C3030306C5C303030695C303030635C3030306B}
\BKM@entry{id=20,dest={73756273656374696F6E2E312E3136},srcline={430}}{5C3337365C3337375C3030305A5C303030755C303030735C303030615C3030306D5C3030306D5C303030655C3030306E5C303030665C303030615C303030735C303030735C303030755C3030306E5C30303067}
\BKM@entry{id=21,dest={73656374696F6E2E32},srcline={5}}{5C3337365C3337375C303030535C303030745C303030795C3030306C5C303030695C3030306E5C303030675C3030305C3034305C3030306D5C303030695C303030745C3030305C3034305C303030545C303030615C303030695C3030306C5C303030775C303030695C3030306E5C303030645C3030305C3034305C303030435C303030535C303030535C3030305C3034305C303030755C3030306E5C303030645C3030305C3034305C303030555C303030725C303030625C303030615C3030306E5C303030695C303030735C303030745C3030302D5C303030535C303030635C303030685C303030725C303030695C303030665C303030745C303030615C303030725C30303074}
\BKM@entry{id=22,dest={73756273656374696F6E2E322E31},srcline={10}}{5C3337365C3337375C303030535C303030635C303030685C303030725C303030695C303030665C303030745C303030615C303030725C303030745C3030305C3034305C303030555C303030725C303030625C303030615C3030306E5C303030695C303030735C303030745C3030305C3034305C303030695C3030306E5C303030735C303030745C303030615C3030306C5C3030306C5C303030695C303030655C303030725C303030655C3030306E}
\@writefile{toc}{\contentsline {subsection}{\numberline {1.15}Tailwind-Klassen im Überblick}{11}{subsection.1.15}\protected@file@percent }
\@writefile{lot}{\contentsline {table}{\numberline {1}{\ignorespaces Verwendete Tailwind-Klassen und ihre Bedeutung}}{11}{table.1}\protected@file@percent }
\@writefile{toc}{\contentsline {subsection}{\numberline {1.16}Zusammenfassung}{11}{subsection.1.16}\protected@file@percent }
\global\@namedef{scr@dte@section@lastmaxnumwidth}{10.22392pt}
\@writefile{toc}{\contentsline {section}{\numberline {2}Styling mit Tailwind CSS und Urbanist-Schriftart}{11}{section.2}\protected@file@percent }
\newlabel{sec:step02}{{2}{11}{Styling mit Tailwind CSS und Urbanist-Schriftart}{section.2}{}}
\BKM@entry{id=23,dest={73756273656374696F6E2E322E32},srcline={28}}{5C3337365C3337375C303030495C3030306E5C303030645C303030655C303030785C3030302E5C303030635C303030735C303030735C3030305C3034305C3034305C3032335C3030305C3034305C303030445C303030615C303030735C3030305C3034305C303030485C303030655C303030725C3030307A5C303030735C303030745C3030305C3337345C303030635C3030306B5C3030305C3034305C303030645C303030655C303030735C3030305C3034305C303030535C303030745C303030795C3030306C5C303030695C3030306E5C303030675C30303073}
\BKM@entry{id=24,dest={73756273756273656374696F6E2E322E322E31},srcline={32}}{5C3337365C3337375C303030545C303030615C303030695C3030306C5C303030775C303030695C3030306E5C303030645C3030305C3034305C303030495C3030306D5C303030705C3030306F5C303030725C30303074}
\BKM@entry{id=25,dest={73756273756273656374696F6E2E322E322E32},srcline={46}}{5C3337365C3337375C303030535C303030635C303030685C303030725C303030695C303030665C303030745C303030615C303030725C303030745C3030302D5C303030445C303030655C303030665C303030695C3030306E5C303030695C303030745C303030695C3030306F5C3030306E5C303030655C3030306E5C3030305C3034305C3030305C3035305C303030355C3030305C3034305C303030535C303030635C303030685C3030306E5C303030695C303030745C303030745C303030655C3030305C303531}
\@writefile{toc}{\contentsline {subsection}{\numberline {2.1}Schriftart Urbanist installieren}{12}{subsection.2.1}\protected@file@percent }
\@writefile{lol}{\contentsline {lstlisting}{\numberline {18}Schriftart-Dateien ins Public-Verzeichnis kopieren}{12}{lstlisting.18}\protected@file@percent }
\@writefile{toc}{\contentsline {subsection}{\numberline {2.2}Index.css Das Herzstück des Stylings}{12}{subsection.2.2}\protected@file@percent }
\@writefile{toc}{\contentsline {subsubsection}{\numberline {2.2.1}Tailwind Import}{12}{subsubsection.2.2.1}\protected@file@percent }
\@writefile{lol}{\contentsline {lstlisting}{\numberline {19}Tailwind CSS importieren}{12}{lstlisting.19}\protected@file@percent }
\@writefile{toc}{\contentsline {subsubsection}{\numberline {2.2.2}Schriftart-Definitionen (5 Schnitte)}{12}{subsubsection.2.2.2}\protected@file@percent }
\@writefile{lol}{\contentsline {lstlisting}{\numberline {20}Urbanist Regular (400)}{12}{lstlisting.20}\protected@file@percent }
\BKM@entry{id=26,dest={73756273756273656374696F6E2E322E322E33},srcline={78}}{5C3337365C3337375C303030545C303030615C303030695C3030306C5C303030775C303030695C3030306E5C303030645C3030305C3034305C303030545C303030685C303030655C3030306D5C30303065}
\BKM@entry{id=27,dest={73756273756273656374696F6E2E322E322E34},srcline={103}}{5C3337365C3337375C303030425C303030615C303030735C303030655C3030302D5C3030304C5C303030615C303030795C303030655C303030725C3030305C3034305C3030305C3035305C303030675C3030306C5C3030306F5C303030625C303030615C3030306C5C303030655C3030305C3034305C303030535C303030745C303030695C3030306C5C303030655C3030305C303531}
\@writefile{toc}{\contentsline {subsubsection}{\numberline {2.2.3}Tailwind Theme}{13}{subsubsection.2.2.3}\protected@file@percent }
\@writefile{lol}{\contentsline {lstlisting}{\numberline {21}Tailwind Custom Theme}{13}{lstlisting.21}\protected@file@percent }
\BKM@entry{id=28,dest={73756273756273656374696F6E2E322E322E35},srcline={134}}{5C3337365C3337375C303030435C303030755C303030735C303030745C3030306F5C3030306D5C3030305C3034305C303030535C303030635C303030725C3030306F5C3030306C5C3030306C5C303030625C303030615C303030725C3030305C3034305C3030305C3035305C303030575C303030655C303030625C3030304B5C303030695C303030745C3030305C303531}
\@writefile{toc}{\contentsline {subsubsection}{\numberline {2.2.4}Base-Layer (globale Stile)}{14}{subsubsection.2.2.4}\protected@file@percent }
\@writefile{lol}{\contentsline {lstlisting}{\numberline {22}Globale Stile}{14}{lstlisting.22}\protected@file@percent }
\@writefile{toc}{\contentsline {subsubsection}{\numberline {2.2.5}Custom Scrollbar (WebKit)}{14}{subsubsection.2.2.5}\protected@file@percent }
\@writefile{lol}{\contentsline {lstlisting}{\numberline {23}Scrollbar für Chrome, Edge, Safari}{14}{lstlisting.23}\protected@file@percent }
\BKM@entry{id=29,dest={73756273756273656374696F6E2E322E322E36},srcline={168}}{5C3337365C3337375C303030465C303030695C303030725C303030655C303030665C3030306F5C303030785C3030305C3034305C303030535C303030635C303030725C3030306F5C3030306C5C3030306C5C303030625C303030615C30303072}
\BKM@entry{id=30,dest={73756273756273656374696F6E2E322E322E37},srcline={184}}{5C3337365C3337375C303030485C303030695C3030306C5C303030665C303030735C3030306B5C3030306C5C303030615C303030735C303030735C303030655C3030303A5C3030305C3034305C303030535C303030635C303030725C3030306F5C3030306C5C3030306C5C303030625C303030615C303030725C3030305C3034305C303030615C303030755C303030735C303030625C3030306C5C303030655C3030306E5C303030645C303030655C3030306E}
\BKM@entry{id=31,dest={73756273656374696F6E2E322E33},srcline={194}}{5C3337365C3337375C303030415C303030705C303030705C3030302E5C303030745C303030735C303030785C3030305C3034305C3034305C3032335C3030305C3034305C303030445C303030695C303030655C3030305C3034305C303030525C303030655C303030615C303030635C303030745C3030302D5C3030304B5C3030306F5C3030306D5C303030705C3030306F5C3030306E5C303030655C3030306E5C303030745C303030655C3030305C3034305C303030655C303030725C3030306B5C3030306C5C3030305C3334345C303030725C30303074}
\@writefile{toc}{\contentsline {subsubsection}{\numberline {2.2.6}Firefox Scrollbar}{15}{subsubsection.2.2.6}\protected@file@percent }
\@writefile{lol}{\contentsline {lstlisting}{\numberline {24}Scrollbar für Firefox}{15}{lstlisting.24}\protected@file@percent }
\@writefile{toc}{\contentsline {subsubsection}{\numberline {2.2.7}Hilfsklasse: Scrollbar ausblenden}{15}{subsubsection.2.2.7}\protected@file@percent }
\@writefile{lol}{\contentsline {lstlisting}{\numberline {25}Hilfsklasse für Karussells}{15}{lstlisting.25}\protected@file@percent }
\@writefile{toc}{\contentsline {subsection}{\numberline {2.3}App.tsx Die React-Komponente erklärt}{16}{subsection.2.3}\protected@file@percent }
\@writefile{lol}{\contentsline {lstlisting}{\numberline {26}Vollständige App.tsx mit Zeilen-Erklärung}{16}{lstlisting.26}\protected@file@percent }
\BKM@entry{id=32,dest={73756273656374696F6E2E322E34},srcline={298}}{5C3337365C3337375C303030565C303030655C303030725C303030775C303030655C3030306E5C303030645C303030655C303030745C303030655C3030305C3034305C303030545C303030615C303030695C3030306C5C303030775C303030695C3030306E5C303030645C3030302D5C3030304B5C3030306C5C303030615C303030735C303030735C303030655C3030306E5C3030305C3034305C3034305C3032335C3030305C3034305C303030435C303030685C303030655C303030615C303030745C3030305C3034305C303030535C303030685C303030655C303030655C30303074}
\BKM@entry{id=33,dest={73756273656374696F6E2E322E35},srcline={319}}{5C3337365C3337375C303030535C303030635C303030725C3030306F5C3030306C5C3030306C5C303030625C303030615C3030306C5C3030306B5C303030655C3030306E5C3030302D5C303030445C303030655C303030625C303030755C303030675C303030675C303030695C3030306E5C30303067}
\@writefile{toc}{\contentsline {subsection}{\numberline {2.4}Verwendete Tailwind-Klassen Cheat Sheet}{17}{subsection.2.4}\protected@file@percent }
\@writefile{toc}{\contentsline {subsection}{\numberline {2.5}Scrollbalken-Debugging}{17}{subsection.2.5}\protected@file@percent }
\BKM@entry{id=34,dest={73756273656374696F6E2E322E36},srcline={332}}{5C3337365C3337375C3030305A5C303030755C303030735C303030615C3030306D5C3030306D5C303030655C3030306E5C303030665C303030615C303030735C303030735C303030755C3030306E5C30303067}
\@writefile{lot}{\contentsline {table}{\numberline {2}{\ignorespaces Alle verwendeten Tailwind-Klassen und ihre CSS-Entsprechung}}{18}{table.2}\protected@file@percent }
\@writefile{toc}{\contentsline {subsection}{\numberline {2.6}Zusammenfassung}{18}{subsection.2.6}\protected@file@percent }
\global\@namedef{scr@dte@section@lastmaxnumwidth}{11.00392pt}
\global\@namedef{scr@dte@subsection@lastmaxnumwidth}{24.0359pt}
\global\@namedef{scr@dte@subsubsection@lastmaxnumwidth}{31.59589pt}
\@writefile{toc}{\providecommand\tocbasic@end@toc@file{}\tocbasic@end@toc@file}
\gdef \@abspage@last{11}
\gdef \@abspage@last{18}
+8 -7
View File
@@ -1,7 +1,7 @@
# Fdb version 4
["pdflatex"] 1778409221.6939 "/home/computer/projects/portfolio/LateX/main.tex" "main.pdf" "main" 1778409224.03226 0
["pdflatex"] 1778411054.56546 "/home/computer/projects/portfolio/LateX/main.tex" "main.pdf" "main" 1778411057.3055 0
"/etc/texmf/web2c/texmf.cnf" 1776891072.07073 475 c0e671620eb5563b2130f56340a5fde8 ""
"/home/computer/projects/portfolio/LateX/main.tex" 1778409221.01333 8396 4f4bd82e84b1e25f8274c80491791102 ""
"/home/computer/projects/portfolio/LateX/main.tex" 1778411051.84094 8414 d1ecf6b8e77592a2889b97b94798576e ""
"/usr/share/texlive/texmf-dist/fonts/enc/dvips/fira/fir_d4q673.enc" 1570828436 2978 6d777d1174162fa94ff58f36782f4570 ""
"/usr/share/texlive/texmf-dist/fonts/enc/dvips/fira/fir_d67aat.enc" 1570828436 3385 21a7e8c8dac3c39de5acda2c56e7bd7e ""
"/usr/share/texlive/texmf-dist/fonts/enc/dvips/fira/fir_iln36p.enc" 1570828436 3071 cfa92ee28d698dd9275559d9d1c3a233 ""
@@ -135,11 +135,12 @@
"/usr/share/texmf/web2c/texmf.cnf" 1707919699 40399 f2c302f7d2af602abb742093540a5834 ""
"/var/lib/texmf/fonts/map/pdftex/updmap/pdftex.map" 1776891108.46284 5472669 54eaf61a88b6b7896ebd0dac973cb29c ""
"/var/lib/texmf/web2c/pdftex/pdflatex.fmt" 1776891271 8211336 7fc26d317f030a4855527787ba3b41d3 ""
"main.aux" 1778409223.91367 15222 ca27fab1cc30a69e09bcd5796577f506 "pdflatex"
"main.out" 1778409223.40897 0 d41d8cd98f00b204e9800998ecf8427e "pdflatex"
"main.tex" 1778409221.01333 8396 4f4bd82e84b1e25f8274c80491791102 ""
"main.toc" 1778409223.91911 2167 181c0708885a22a17af11f2fe239c4aa "pdflatex"
"step_01.tex" 1778409222.33081 16873 849f7324d1ba6ca1a4fae21affb01045 ""
"main.aux" 1778411057.18364 24185 8c70758ff147f882c604e92ef18579e6 "pdflatex"
"main.out" 1778411056.39673 0 d41d8cd98f00b204e9800998ecf8427e "pdflatex"
"main.tex" 1778411051.84094 8414 d1ecf6b8e77592a2889b97b94798576e ""
"main.toc" 1778411057.18964 3573 19bac1bdadf043e704947752a639658f "pdflatex"
"step_01.tex" 1778409267.87284 16873 849f7324d1ba6ca1a4fae21affb01045 ""
"step_02.tex" 1778411039.2544 14666 74b399f74ef0a4874d9ab397d186df94 ""
(generated)
"main.aux"
"main.log"
+6
View File
@@ -269,6 +269,12 @@ INPUT /usr/share/texlive/texmf-dist/fonts/tfm/public/fira/FiraSans-Regular-osf-t
INPUT /usr/share/texlive/texmf-dist/fonts/vf/public/fira/FiraSans-Regular-osf-ts1.vf
INPUT /usr/share/texlive/texmf-dist/fonts/tfm/public/fira/FiraSans-Regular-osf-ts1--base.tfm
INPUT /usr/share/texlive/texmf-dist/fonts/enc/dvips/fira/fir_d67aat.enc
INPUT ./step_02.tex
INPUT ./step_02.tex
INPUT step_02.tex
INPUT /usr/share/texlive/texmf-dist/fonts/tfm/public/fira/FiraMono-Bold-tosf-t1.tfm
INPUT /usr/share/texlive/texmf-dist/fonts/vf/public/fira/FiraMono-Bold-tosf-t1.vf
INPUT /usr/share/texlive/texmf-dist/fonts/tfm/public/fira/FiraMono-Bold-tosf-t1--base.tfm
INPUT main.aux
INPUT ./main.out
INPUT ./main.out
+36 -12
View File
@@ -1,4 +1,4 @@
This is pdfTeX, Version 3.141592653-2.6-1.40.25 (TeX Live 2023/Debian) (preloaded format=pdflatex 2026.4.22) 10 MAY 2026 12:33
This is pdfTeX, Version 3.141592653-2.6-1.40.25 (TeX Live 2023/Debian) (preloaded format=pdflatex 2026.4.22) 10 MAY 2026 13:04
entering extended mode
restricted \write18 enabled.
file:line:error style messages enabled.
@@ -837,7 +837,31 @@ Underfull \hbox (badness 10000) in paragraph at lines 419--420
[]|\T1/FiraSans-OsF/regular/n/12 (+20) Hintergrund-Weichzeichner (Glass-
[]
) [11] (./main.aux)
) (./step_02.tex [11]
LaTeX Font Info: Font shape `T1/FiraMono-TOsF/b/n' in size <12> not available
(Font) Font shape `T1/FiraMono-TOsF/bold/n' tried instead on input line 21.
LaTeX Font Info: Font shape `T1/FiraMono-TOsF/bold/n' will be
(Font) scaled to size 10.79993pt on input line 21.
[12]
Overfull \hbox (0.81635pt too wide) in paragraph at lines 90--91
[]\T1/FiraMono-TOsF/regular/n/12 @theme \T1/FiraSans-OsF/regular/n/12 (-20) ^^U Tail-wind 4 Di-rek-ti-ve zum Er-wei-tern/-Über-schrei-ben des Standard-Themes
[]
[13]
Overfull \hbox (7.81894pt too wide) in paragraph at lines 127--128
[]\T1/FiraMono-TOsF/regular/n/12 -webkit-font-smoothing: antialiased \T1/FiraSans-OsF/regular/n/12 (-20) ^^U Glät-tet Schrift auf ma-cOS/i-OS (WebKit-
[]
[14]
Overfull \hbox (13.98355pt too wide) in paragraph at lines 162--163
[]\T1/FiraMono-TOsF/regular/n/12 linear-gradient(180deg, #8dff69, #6fe047) \T1/FiraSans-OsF/regular/n/12 (-20) ^^U Farb-ver-lauf von hell-grün (oben)
[]
[15] [16]
LaTeX Warning: `h' float specifier changed to `ht'.
[17]) [18] (./main.aux)
***********
LaTeX2e <2023-11-01> patch level 1
L3 programming layer <2024-01-22>
@@ -846,18 +870,18 @@ Package rerunfilecheck Info: File `main.out' has not changed.
(rerunfilecheck) Checksum: D41D8CD98F00B204E9800998ECF8427E;0.
)
Here is how much of TeX's memory you used:
20017 strings out of 474222
343740 string characters out of 5748733
2677975 words of memory out of 5000000
41658 multiletter control sequences out of 15000+600000
681250 words of font info for 147 fonts, out of 8000000 for 9000
20336 strings out of 474222
348419 string characters out of 5748733
2740975 words of memory out of 5000000
41759 multiletter control sequences out of 15000+600000
684542 words of font info for 165 fonts, out of 8000000 for 9000
1141 hyphenation exceptions out of 8191
108i,10n,107p,10939b,2200s stack positions out of 10000i,1000n,20000p,200000b,200000s
</usr/share/texlive/texmf-dist/fonts/type1/public/fira/FiraMono-Bold.pfb></usr/share/texlive/texmf-dist/fonts/type1/public/fira/FiraMono-Oblique.pfb></usr/share/texlive/texmf-dist/fonts/type1/public/fira/FiraMono-Regular.pfb></usr/share/texlive/texmf-dist/fonts/type1/public/fira/FiraSans-Bold.pfb></usr/share/texlive/texmf-dist/fonts/type1/public/fira/FiraSans-Regular.pfb>
Output written on main.pdf (11 pages, 257340 bytes).
Output written on main.pdf (18 pages, 294224 bytes).
PDF statistics:
460 PDF objects out of 1000 (max. 8388607)
431 compressed objects within 5 object streams
250 named destinations out of 1000 (max. 500000)
45217 words of extra memory for PDF output out of 51595 (max. 10000000)
770 PDF objects out of 1000 (max. 8388607)
731 compressed objects within 8 object streams
440 named destinations out of 1000 (max. 500000)
45841 words of extra memory for PDF output out of 51595 (max. 10000000)
BIN
View File
Binary file not shown.
Binary file not shown.
+1
View File
@@ -246,6 +246,7 @@
% KAPITEL EINBINDEN
% ============================================
\input{step_01.tex}
\input{step_02.tex}
% Weitere Kapitel folgen hier:
% \input{step_02.tex}
+14
View File
@@ -19,4 +19,18 @@
\contentsline {subsection}{\numberline {1.14}Vollständiger Code: App.tsx mit Tailwind}{9}{subsection.1.14}%
\contentsline {subsection}{\numberline {1.15}Tailwind-Klassen im Überblick}{11}{subsection.1.15}%
\contentsline {subsection}{\numberline {1.16}Zusammenfassung}{11}{subsection.1.16}%
\contentsline {section}{\numberline {2}Styling mit Tailwind CSS und Urbanist-Schriftart}{11}{section.2}%
\contentsline {subsection}{\numberline {2.1}Schriftart Urbanist installieren}{12}{subsection.2.1}%
\contentsline {subsection}{\numberline {2.2}Index.css Das Herzstück des Stylings}{12}{subsection.2.2}%
\contentsline {subsubsection}{\numberline {2.2.1}Tailwind Import}{12}{subsubsection.2.2.1}%
\contentsline {subsubsection}{\numberline {2.2.2}Schriftart-Definitionen (5 Schnitte)}{12}{subsubsection.2.2.2}%
\contentsline {subsubsection}{\numberline {2.2.3}Tailwind Theme}{13}{subsubsection.2.2.3}%
\contentsline {subsubsection}{\numberline {2.2.4}Base-Layer (globale Stile)}{14}{subsubsection.2.2.4}%
\contentsline {subsubsection}{\numberline {2.2.5}Custom Scrollbar (WebKit)}{14}{subsubsection.2.2.5}%
\contentsline {subsubsection}{\numberline {2.2.6}Firefox Scrollbar}{15}{subsubsection.2.2.6}%
\contentsline {subsubsection}{\numberline {2.2.7}Hilfsklasse: Scrollbar ausblenden}{15}{subsubsection.2.2.7}%
\contentsline {subsection}{\numberline {2.3}App.tsx Die React-Komponente erklärt}{16}{subsection.2.3}%
\contentsline {subsection}{\numberline {2.4}Verwendete Tailwind-Klassen Cheat Sheet}{17}{subsection.2.4}%
\contentsline {subsection}{\numberline {2.5}Scrollbalken-Debugging}{17}{subsection.2.5}%
\contentsline {subsection}{\numberline {2.6}Zusammenfassung}{18}{subsection.2.6}%
\providecommand \tocbasic@end@toc@file {}\tocbasic@end@toc@file
+341
View File
@@ -0,0 +1,341 @@
% ============================================
% STEP 02: STYLING MIT TAILWIND & URBANIST
% ============================================
\section{Styling mit Tailwind CSS und Urbanist-Schriftart}
\label{sec:step02}
In diesem Schritt gestalten wir unsere Portfolio-Seite mit Tailwind CSS, binden eine eigene Schriftart ein und erstellen einen benutzerdefinierten Scrollbalken. Jede Zeile Code wird ausführlich erklärt.
\subsection{Schriftart Urbanist installieren}
Urbanist ist eine moderne, serifenlose Schriftart von Google Fonts mit 18 verschiedene Schnitten (Thin bis Black, jeweils normal und italic). Wir verwenden fünf Grundschnitte.
\textbf{Schritt 1: Schriftart-Dateien ins Projekt kopieren}
\begin{lstlisting}[language=Bash, caption={Schriftart-Dateien ins Public-Verzeichnis kopieren}]
cd ~/projects/portfolio
cp -r Urbanist apps/web/public/Urbanist
\end{lstlisting}
\textbf{Warum \texttt{public/}?}
\begin{itemize}
\item Alles im \texttt{public/}-Ordner wird von Vite unverändert übernommen
\item Dateien sind unter \texttt{/Urbanist/static/...} im Browser erreichbar
\item Kein Import nötig direkter Pfad in CSS
\end{itemize}
\subsection{Index.css Das Herzstück des Stylings}
Die Datei \texttt{apps/web/src/index.css} vereint Tailwind, Schriftarten und Custom-Styles. Hier jede Zeile im Detail erklärt.
\subsubsection{Tailwind Import}
\begin{lstlisting}[language=CSS, caption={Tailwind CSS importieren}]
@import "tailwindcss";
\end{lstlisting}
\textbf{Erklärung:}
\begin{itemize}
\item \texttt{@import} CSS-Regel zum Importieren anderer Stylesheets
\item \texttt{"tailwindcss"} Lädt alle Tailwind-Basis-Styles, Komponenten und Utilities
\item In Tailwind 4 \textbf{kein} \texttt{@tailwind base/components/utilities} mehr!
\item Diese einzige Zeile ersetzt Hunderte von handgeschriebenen CSS-Zeilen
\end{itemize}
\subsubsection{Schriftart-Definitionen (5 Schnitte)}
\begin{lstlisting}[language=CSS, caption={Urbanist Regular (400)}]
@font-face {
font-family: "Urbanist";
src: url("/Urbanist/static/Urbanist-Regular.ttf") format("truetype");
font-weight: 400;
font-style: normal;
font-display: swap;
}
\end{lstlisting}
\textbf{Zeile für Zeile:}
\begin{itemize}
\item \texttt{@font-face} CSS-At-Regel zum Definieren einer eigenen Schriftart
\item \texttt{font-family: "Urbanist"} Der Name, unter dem wir die Schrift später verwenden (z.B. in \texttt{font-family: var(--font-display)})
\item \texttt{src: url("/Urbanist/...")} Pfad zur Schriftdatei. Beginnt mit \texttt{/}, ist also relativ zur Domain-Root
\item \texttt{format("truetype")} Sagt dem Browser, welches Format die Datei hat (.ttf = TrueType)
\item \texttt{font-weight: 400} Diesen Schnitt für normale Textstärke verwenden (400 = Regular)
\item \texttt{font-style: normal} Kein Kursiv (italic wäre \texttt{font-style: italic})
\item \texttt{font-display: swap} WICHTIG! Zeigt sofort Text in einer Ersatzschrift an und tauscht sie aus, sobald Urbanist geladen ist. Verhindert "Flash of Invisible Text" (FOIT)
\end{itemize}
\textbf{Die 5 definierten Schnitte:}
\begin{enumerate}
\item \texttt{Urbanist-Light.ttf} Gewicht 300 (dünn, für Fließtext)
\item \texttt{Urbanist-Regular.ttf} Gewicht 400 (normal, Standard)
\item \texttt{Urbanist-Medium.ttf} Gewicht 500 (halbfett)
\item \texttt{Urbanist-SemiBold.ttf} Gewicht 600 (fast fett)
\item \texttt{Urbanist-Bold.ttf} Gewicht 700 (fett, für Überschriften)
\end{enumerate}
\subsubsection{Tailwind Theme}
\begin{lstlisting}[language=CSS, caption={Tailwind Custom Theme}]
@theme {
--font-display: "Urbanist", sans-serif;
--breakpoint-3xl: 1920px;
--color-primary: #8dff69;
}
\end{lstlisting}
\textbf{Zeile für Zeile:}
\begin{itemize}
\item \texttt{@theme} Tailwind 4 Direktive zum Erweitern/Überschreiben des Standard-Themes
\item \texttt{--font-display: "Urbanist", sans-serif} Definiert eine neue Schrift-Klasse \texttt{font-display}. \texttt{sans-serif} ist der Fallback, falls Urbanist nicht lädt
\item \texttt{--breakpoint-3xl: 1920px} Neuer Breakpoint für sehr große Bildschirme. Nutzbar als \texttt{3xl:text-7xl}
\item \texttt{--color-primary: \#8dff69} Definiert eine neue Farbe \texttt{primary} (helles Grün). Nutzbar als \texttt{text-primary}, \texttt{bg-primary}, \texttt{border-primary}, etc.
\end{itemize}
\textbf{Verwendung der Custom-Properties in Tailwind:}
\begin{itemize}
\item \texttt{font-display} in \texttt{font-family: var(--font-display)}
\item \texttt{3xl} als Breakpoint: \texttt{3xl:grid-cols-4}
\item \texttt{primary} als Farbe: \texttt{text-primary}, \texttt{bg-primary/50}, \texttt{border-primary}
\end{itemize}
\subsubsection{Base-Layer (globale Stile)}
\begin{lstlisting}[language=CSS, caption={Globale Stile}]
@layer base {
html {
font-family: var(--font-display);
scroll-behavior: smooth;
}
body {
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
background-color: #000000;
color: #ffffff;
overflow-x: hidden;
}
}
\end{lstlisting}
\textbf{Zeile für Zeile:}
\begin{itemize}
\item \texttt{@layer base} Tailwinds "base"-Layer. Styles hier haben niedrigste Spezifität und können von Utilities überschrieben werden
\item \texttt{font-family: var(--font-display)} Setzt Urbanist als Standardschrift für die gesamte Seite
\item \texttt{scroll-behavior: smooth} Sanftes Scrollen bei Ankerlinks (z.B. \texttt{\#projekte})
\item \texttt{-webkit-font-smoothing: antialiased} Glättet Schrift auf macOS/iOS (WebKit-Browser)
\item \texttt{-moz-osx-font-smoothing: grayscale} Gleiches für Firefox auf macOS
\item \texttt{background-color: \#000000} Schwarzer Hintergrund
\item \texttt{color: \#ffffff} Weiße Schrift als Standard
\item \texttt{overflow-x: hidden} Verhindert horizontales Scrollen (wichtig für Animationen, die über den Rand hinausgehen)
\end{itemize}
\subsubsection{Custom Scrollbar (WebKit)}
\begin{lstlisting}[language=CSS, caption={Scrollbar für Chrome, Edge, Safari}]
::-webkit-scrollbar {
width: 16px;
}
::-webkit-scrollbar-track {
background: #1a1a1a;
}
::-webkit-scrollbar-thumb {
background: linear-gradient(180deg, #8dff69, #6fe047);
border-radius: 8px;
}
::-webkit-scrollbar-thumb:hover {
background: linear-gradient(180deg, #a8ff8d, #5bc92e);
}
\end{lstlisting}
\textbf{Zeile für Zeile:}
\begin{itemize}
\item \texttt{::-webkit-scrollbar} Pseudo-Element für die gesamte Scrollbar (Breite, Hintergrund)
\item \texttt{width: 16px} Breite der Scrollbar. Größer = dickerer Balken
\item \texttt{::-webkit-scrollbar-track} Der "Hintergrund" der Scrollbar (die Schiene)
\item \texttt{background: \#1a1a1a} Dunkelgrauer Track (fast schwarz)
\item \texttt{::-webkit-scrollbar-thumb} Der bewegliche "Griff" der Scrollbar
\item \texttt{linear-gradient(180deg, \#8dff69, \#6fe047)} Farbverlauf von hellgrün (oben) nach dunkelgrün (unten). \texttt{180deg} = von oben nach unten
\item \texttt{border-radius: 8px} Abgerundete Ecken am Griff
\item \texttt{::-webkit-scrollbar-thumb:hover} Wenn die Maus über dem Griff ist
\item \texttt{\#a8ff8d, \#5bc92e} Hellere Grüntöne beim Hover für visuelles Feedback
\end{itemize}
\subsubsection{Firefox Scrollbar}
\begin{lstlisting}[language=CSS, caption={Scrollbar für Firefox}]
* {
scrollbar-width: auto;
scrollbar-color: #6fe047 #1a1a1a;
}
\end{lstlisting}
\textbf{Erklärung:}
\begin{itemize}
\item Firefox unterstützt \texttt{::-webkit-scrollbar} \textbf{nicht}
\item \texttt{scrollbar-width: auto} Normale Breite (Alternative: \texttt{thin})
\item \texttt{scrollbar-color: GRIFF SCHIENE} Erste Farbe = Griff, zweite Farbe = Schiene
\end{itemize}
\subsubsection{Hilfsklasse: Scrollbar ausblenden}
\begin{lstlisting}[language=CSS, caption={Hilfsklasse für Karussells}]
.hide-scrollbar::-webkit-scrollbar {
display: none;
}
\end{lstlisting}
Für horizontale Karussells der Inhalt scrollt, aber die Scrollbar ist unsichtbar.
\subsection{App.tsx Die React-Komponente erklärt}
\begin{lstlisting}[language=TypeScript, caption={Vollständige App.tsx mit Zeilen-Erklärung}]
function App() {
return (
// Äußerster Container
// min-h-screen: mindestens Bildschirmhöhe (wichtig für zentrierte Inhalte)
// bg-black: schwarzer Hintergrund
// text-white: weiße Schrift als Basis
// p-8: 32px Innenabstand auf allen Seiten
<div className="min-h-screen bg-black text-white p-8">
{/* Zentrierte Content-Box */}
{/* text-center: zentriert Text und Inline-Elemente */}
{/* max-w-2xl: maximale Breite 672px */}
{/* mx-auto: automatischer horizontaler Margin = zentriert die Box */}
{/* pt-20: 80px Abstand nach oben (Padding-Top) */}
<div className="text-center max-w-2xl mx-auto pt-20">
{/* Kategorie-Badge: Kleine Beschriftung ÜBER der Überschrift */}
{/* text-primary: verwendet unsere Custom-Farbe #8dff69 */}
{/* text-sm: kleinere Schriftgröße (14px) */}
{/* font-medium: halbfette Schrift (Gewicht 500) */}
{/* tracking-widest: sehr breite Buchstabenabstände */}
{/* uppercase: GROSSBUCHSTABEN */}
<span className="text-primary text-sm font-medium tracking-widest uppercase">
Full-Stack Entwickler
</span>
{/* Hauptüberschrift: Dein Name */}
{/* text-7xl: sehr große Schrift (72px) */}
{/* font-bold: fette Schrift (Gewicht 700) */}
{/* mt-4: 16px Abstand nach oben */}
{/* mb-6: 24px Abstand nach unten */}
{/* leading-tight: enger Zeilenabstand (1.25) */}
<h1 className="text-7xl font-bold mt-4 mb-6 leading-tight">
Robert Bretz
</h1>
{/* Beschreibungstext */}
{/* text-xl: etwas größerer Text (20px) */}
{/* text-gray-400: graue Schrift (gedämpfter als weiß) */}
{/* max-w-lg: maximale Breite 512px (schmaler = besser lesbar) */}
{/* leading-relaxed: lockerer Zeilenabstand (1.625) */}
<p className="text-xl text-gray-400 max-w-lg mx-auto leading-relaxed">
Ich baue moderne Webanwendungen mit React, .NET und Docker.
Minimalistisch, schnell und zuverlässig.
</p>
{/* Button-Gruppe */}
{/* mt-10: 40px Abstand nach oben */}
{/* flex: Flexbox-Layout */}
{/* gap-4: 16px Abstand zwischen den Buttons */}
{/* justify-center: Buttons horizontal zentrieren */}
<div className="mt-10 flex gap-4 justify-center">
{/* Button "Projekte" */}
{/* px-6: 24px horizontaler Innenabstand */}
{/* py-3: 12px vertikaler Innenabstand */}
{/* bg-primary: Hintergrund in Custom-Farbe #8dff69 */}
{/* text-black: schwarze Schrift auf grünem Grund */}
{/* font-semibold: halbfette Schrift (Gewicht 600) */}
{/* rounded-full: komplett runde Ecken (Pillenform) */}
{/* hover:opacity-80: beim Hover auf 80% Deckkraft */}
{/* transition: sanfter Übergang */}
<a href="#" className="px-6 py-3 bg-primary text-black font-semibold rounded-full hover:opacity-80 transition">
Projekte
</a>
{/* Button "Kontakt" */}
{/* border border-gray-700: dunkelgrauer Rahmen statt Hintergrund */}
{/* text-gray-300: hellgraue Schrift */}
{/* hover:border-primary: Rahmen wird grün beim Hover */}
{/* hover:text-primary: Schrift wird grün beim Hover */}
<a href="#" className="px-6 py-3 border border-gray-700 text-gray-300 font-semibold rounded-full hover:border-primary hover:text-primary transition">
Kontakt
</a>
</div>
</div>
{/* SCROLL-TEST: Erzwingt Scrollen für den Custom Scrollbar */}
{/* mt-20: 80px Abstand nach oben */}
{/* space-y-8: 32px Abstand zwischen den Kind-Elementen */}
{/* max-w-2xl: gleiche maximale Breite wie oben */}
<div className="mt-20 space-y-8 max-w-2xl mx-auto">
{/* JavaScript: Erstelle 5 Test-Blöcke */}
{/* [...Array(5)]: Array mit 5 leeren Plätzen */}
{/* .map((_, i): für jedes Element, _ = ignorierter Wert, i = Index (0-4) */}
{[...Array(5)].map((_, i) => (
<div
key={i}
className="h-64 bg-gray-900 rounded-xl flex items-center justify-center text-gray-500 text-2xl"
>
Sektion {i + 1}
</div>
))}
</div>
</div>
);
}
export default App;
\end{lstlisting}
\subsection{Verwendete Tailwind-Klassen Cheat Sheet}
\begin{table}[h]
\centering
\caption{Alle verwendeten Tailwind-Klassen und ihre CSS-Entsprechung}
\begin{tabular}{@{}llp{5cm}@{}}
\toprule
\textbf{Klasse} & \textbf{CSS-Entsprechung} & \textbf{Erklärung} \\
\midrule
\texttt{min-h-screen} & \texttt{min-height: 100vh} & Mindestens Bildschirmhöhe \\
\texttt{bg-black} & \texttt{background: \#000} & Schwarzer Hintergrund \\
\texttt{text-white} & \texttt{color: \#fff} & Weiße Schrift \\
\texttt{p-8} & \texttt{padding: 2rem} & 32px Innenabstand \\
\texttt{text-center} & \texttt{text-align: center} & Text zentrieren \\
\texttt{max-w-2xl} & \texttt{max-width: 42rem} & Max 672px breit \\
\texttt{mx-auto} & \texttt{margin-left/right: auto} & Horizontal zentrieren \\
\texttt{pt-20} & \texttt{padding-top: 5rem} & 80px oben \\
\bottomrule
\end{tabular}
\end{table}
\subsection{Scrollbalken-Debugging}
\textbf{Problem: "Ich sehe den Scrollbalken nicht!"}
\textbf{Ursache:} Der Scrollbalken erscheint nur, wenn die Seite tatsächlich scrollbar ist. Bei kurzen Inhalten (nur Name + Buttons) passt alles auf eine Bildschirmseite kein Scrollbalken nötig.
\textbf{Lösungen:}
\begin{enumerate}
\item Browser-Fenster vertikal verkleinern
\item Genug Test-Inhalt einfügen (5 große Divs wie im Code oben)
\item Mit \texttt{overflow-y: scroll} einen permanenten Scrollbalken erzwingen
\end{enumerate}
\subsection{Zusammenfassung}
In diesem Schritt haben wir:
\begin{itemize}
\item Die Schriftart Urbanist mit 5 Schnitten eingebunden
\item Ein Tailwind Custom-Theme mit eigener Farbe und Breakpoint definiert
\item Globale Stile im \texttt{@layer base} gesetzt
\item Einen benutzerdefinierten Scrollbalken mit Farbverlauf erstellt
\item Jede Zeile der \texttt{App.tsx} und \texttt{index.css} ausführlich dokumentiert
\end{itemize}
+93
View File
@@ -0,0 +1,93 @@
Copyright 2021 The Urbanist Project Authors (https://github.com/coreyhu/Urbanist)
This Font Software is licensed under the SIL Open Font License, Version 1.1.
This license is copied below, and is also available with a FAQ at:
https://openfontlicense.org
-----------------------------------------------------------
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
-----------------------------------------------------------
PREAMBLE
The goals of the Open Font License (OFL) are to stimulate worldwide
development of collaborative font projects, to support the font creation
efforts of academic and linguistic communities, and to provide a free and
open framework in which fonts may be shared and improved in partnership
with others.
The OFL allows the licensed fonts to be used, studied, modified and
redistributed freely as long as they are not sold by themselves. The
fonts, including any derivative works, can be bundled, embedded,
redistributed and/or sold with any software provided that any reserved
names are not used by derivative works. The fonts and derivatives,
however, cannot be released under any other type of license. The
requirement for fonts to remain under this license does not apply
to any document created using the fonts or their derivatives.
DEFINITIONS
"Font Software" refers to the set of files released by the Copyright
Holder(s) under this license and clearly marked as such. This may
include source files, build scripts and documentation.
"Reserved Font Name" refers to any names specified as such after the
copyright statement(s).
"Original Version" refers to the collection of Font Software components as
distributed by the Copyright Holder(s).
"Modified Version" refers to any derivative made by adding to, deleting,
or substituting -- in part or in whole -- any of the components of the
Original Version, by changing formats or by porting the Font Software to a
new environment.
"Author" refers to any designer, engineer, programmer, technical
writer or other person who contributed to the Font Software.
PERMISSION & CONDITIONS
Permission is hereby granted, free of charge, to any person obtaining
a copy of the Font Software, to use, study, copy, merge, embed, modify,
redistribute, and sell modified and unmodified copies of the Font
Software, subject to the following conditions:
1) Neither the Font Software nor any of its individual components,
in Original or Modified Versions, may be sold by itself.
2) Original or Modified Versions of the Font Software may be bundled,
redistributed and/or sold with any software, provided that each copy
contains the above copyright notice and this license. These can be
included either as stand-alone text files, human-readable headers or
in the appropriate machine-readable metadata fields within text or
binary files as long as those fields can be easily viewed by the user.
3) No Modified Version of the Font Software may use the Reserved Font
Name(s) unless explicit written permission is granted by the corresponding
Copyright Holder. This restriction only applies to the primary font name as
presented to the users.
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
Software shall not be used to promote, endorse or advertise any
Modified Version, except to acknowledge the contribution(s) of the
Copyright Holder(s) and the Author(s) or with their explicit written
permission.
5) The Font Software, modified or unmodified, in part or in whole,
must be distributed entirely under this license, and must not be
distributed under any other license. The requirement for fonts to
remain under this license does not apply to any document created
using the Font Software.
TERMINATION
This license becomes null and void if any of the above conditions are
not met.
DISCLAIMER
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
OTHER DEALINGS IN THE FONT SOFTWARE.
+81
View File
@@ -0,0 +1,81 @@
Urbanist Variable Font
======================
This download contains Urbanist as both variable fonts and static fonts.
Urbanist is a variable font with this axis:
wght
This means all the styles are contained in these files:
Urbanist-VariableFont_wght.ttf
Urbanist-Italic-VariableFont_wght.ttf
If your app fully supports variable fonts, you can now pick intermediate styles
that arent available as static fonts. Not all apps support variable fonts, and
in those cases you can use the static font files for Urbanist:
static/Urbanist-Thin.ttf
static/Urbanist-ExtraLight.ttf
static/Urbanist-Light.ttf
static/Urbanist-Regular.ttf
static/Urbanist-Medium.ttf
static/Urbanist-SemiBold.ttf
static/Urbanist-Bold.ttf
static/Urbanist-ExtraBold.ttf
static/Urbanist-Black.ttf
static/Urbanist-ThinItalic.ttf
static/Urbanist-ExtraLightItalic.ttf
static/Urbanist-LightItalic.ttf
static/Urbanist-Italic.ttf
static/Urbanist-MediumItalic.ttf
static/Urbanist-SemiBoldItalic.ttf
static/Urbanist-BoldItalic.ttf
static/Urbanist-ExtraBoldItalic.ttf
static/Urbanist-BlackItalic.ttf
Get started
-----------
1. Install the font files you want to use
2. Use your app's font picker to view the font family and all the
available styles
Learn more about variable fonts
-------------------------------
https://developers.google.com/web/fundamentals/design-and-ux/typography/variable-fonts
https://variablefonts.typenetwork.com
https://medium.com/variable-fonts
In desktop apps
https://theblog.adobe.com/can-variable-fonts-illustrator-cc
https://helpx.adobe.com/nz/photoshop/using/fonts.html#variable_fonts
Online
https://developers.google.com/fonts/docs/getting_started
https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Fonts/Variable_Fonts_Guide
https://developer.microsoft.com/en-us/microsoft-edge/testdrive/demos/variable-fonts
Installing fonts
MacOS: https://support.apple.com/en-us/HT201749
Linux: https://www.google.com/search?q=how+to+install+a+font+on+gnu%2Blinux
Windows: https://support.microsoft.com/en-us/help/314960/how-to-install-or-remove-a-font-in-windows
Android Apps
https://developers.google.com/fonts/docs/android
https://developer.android.com/guide/topics/ui/look-and-feel/downloadable-fonts
License
-------
Please read the full license text (OFL.txt) to understand the permissions,
restrictions and requirements for usage, redistribution, and modification.
You can use them in your products & projects print or digital,
commercial or otherwise.
This isn't legal advice, please consider consulting a lawyer and see the full
license for all details.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+27 -56
View File
@@ -1,64 +1,35 @@
function App() {
return (
<div className="min-h-screen bg-gradient-to-br from-slate-900 via-purple-900 to-slate-900 text-white p-8">
<div className="max-w-4xl mx-auto">
<header className="text-center mb-16 pt-20">
{/* Animierter Hintergrund-Badge */}
<span className="inline-block px-4 py-1 rounded-full bg-emerald-500/20 text-emerald-300 text-sm font-medium mb-4 animate-pulse">
🔥 Portfolio 2026
</span>
<h1 className="text-7xl font-bold mb-4 bg-gradient-to-r from-emerald-400 via-cyan-400 to-purple-400 text-transparent bg-clip-text">
Mein Portfolio
</h1>
<p className="text-xl text-gray-300">
Full-Stack Entwickler & DevOps Enthusiast
</p>
</header>
{/* Cards mit Hover-Effekten */}
<div className="grid grid-cols-1 md:grid-cols-3 gap-6">
<div className="group bg-white/5 backdrop-blur rounded-xl p-8 text-center hover:bg-white/10 transition-all duration-300 border border-white/10 hover:border-emerald-500 hover:scale-105 cursor-pointer">
<span className="text-5xl block mb-4">🚀</span>
<h2 className="text-2xl font-semibold group-hover:text-emerald-400 transition-colors">
Projekte
</h2>
<p className="text-gray-400 mt-2">React, .NET, Docker</p>
</div>
<div className="group bg-white/5 backdrop-blur rounded-xl p-8 text-center hover:bg-white/10 transition-all duration-300 border border-white/10 hover:border-cyan-500 hover:scale-105 cursor-pointer">
<span className="text-5xl block mb-4">🛠</span>
<h2 className="text-2xl font-semibold group-hover:text-cyan-400 transition-colors">
Skills
</h2>
<p className="text-gray-400 mt-2">TypeScript, C#, SQL</p>
</div>
<div className="group bg-white/5 backdrop-blur rounded-xl p-8 text-center hover:bg-white/10 transition-all duration-300 border border-white/10 hover:border-purple-500 hover:scale-105 cursor-pointer">
<span className="text-5xl block mb-4">📫</span>
<h2 className="text-2xl font-semibold group-hover:text-purple-400 transition-colors">
Kontakt
</h2>
<p className="text-gray-400 mt-2">Immer erreichbar</p>
</div>
<div className="min-h-screen bg-black text-white p-8">
<div className="text-center max-w-2xl mx-auto pt-20">
<span className="text-primary text-sm font-medium tracking-widest uppercase">Full-Stack Entwickler</span>
<h1 className="text-7xl font-bold mt-4 mb-6 leading-tight">Robert Bretz</h1>
<p className="text-xl text-gray-400 max-w-lg mx-auto leading-relaxed">
Ich baue moderne Webanwendungen mit React, .NET und Docker. Minimalistisch, schnell und zuverlässig.
</p>
<div className="mt-10 flex gap-4 justify-center">
<a
href="#"
className="px-6 py-3 bg-primary text-black font-semibold rounded-full hover:opacity-80 transition"
>
Projekte
</a>
<a
href="#"
className="px-6 py-3 border border-gray-700 text-gray-300 font-semibold rounded-full hover:border-primary hover:text-primary transition"
>
Kontakt
</a>
</div>
</div>
{/* Test-Sektion für Farben */}
<div className="mt-16 p-8 bg-white/5 rounded-xl backdrop-blur border border-white/10">
<h3 className="text-xl font-bold mb-4">🎨 Tailwind Farb-Test</h3>
<div className="flex flex-wrap gap-2">
{[
"bg-red-500", "bg-orange-500", "bg-yellow-500", "bg-green-500",
"bg-emerald-500", "bg-cyan-500", "bg-blue-500", "bg-purple-500",
"bg-pink-500", "bg-rose-500"
].map((color) => (
<div
key={color}
className={`w-12 h-12 rounded-lg ${color} hover:scale-125 transition-transform cursor-pointer`}
title={color}
/>
))}
{/* SCROLL-TEST: Diese Blöcke erzwingen Scrollen */}
<div className="mt-20 space-y-8 max-w-2xl mx-auto">
{[...Array(5)].map((_, i) => (
<div key={i} className="h-64 bg-gray-900 rounded-xl flex items-center justify-center text-gray-500 text-2xl">
Sektion {i + 1}
</div>
</div>
))}
</div>
</div>
);
+96
View File
@@ -1 +1,97 @@
@import "tailwindcss";
/* ============================================
URBANIST SCHRIFTART
============================================ */
@font-face {
font-family: "Urbanist";
src: url("/Urbanist/static/Urbanist-Regular.ttf") format("truetype");
font-weight: 400;
font-style: normal;
font-display: swap;
}
@font-face {
font-family: "Urbanist";
src: url("/Urbanist/static/Urbanist-Light.ttf") format("truetype");
font-weight: 300;
font-style: normal;
font-display: swap;
}
@font-face {
font-family: "Urbanist";
src: url("/Urbanist/static/Urbanist-Medium.ttf") format("truetype");
font-weight: 500;
font-style: normal;
font-display: swap;
}
@font-face {
font-family: "Urbanist";
src: url("/Urbanist/static/Urbanist-SemiBold.ttf") format("truetype");
font-weight: 600;
font-style: normal;
font-display: swap;
}
@font-face {
font-family: "Urbanist";
src: url("/Urbanist/static/Urbanist-Bold.ttf") format("truetype");
font-weight: 700;
font-style: normal;
font-display: swap;
}
/* ============================================
TAILWIND THEME
============================================ */
@theme {
--font-display: "Urbanist", sans-serif;
--breakpoint-3xl: 1920px;
--color-primary: #8dff69;
}
@layer base {
html {
font-family: var(--font-display);
scroll-behavior: smooth;
}
body {
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
background-color: #000000;
color: #ffffff;
overflow-x: hidden;
}
/* Custom Scrollbar */
::-webkit-scrollbar {
width: 16px;
}
::-webkit-scrollbar-track {
background: #1a1a1a;
}
::-webkit-scrollbar-thumb {
background: linear-gradient(180deg, #8dff69, #6fe047);
border-radius: 8px;
}
::-webkit-scrollbar-thumb:hover {
background: linear-gradient(180deg, #a8ff8d, #5bc92e);
}
/* Firefox Scrollbar */
* {
scrollbar-width: auto;
scrollbar-color: #6fe047 #1a1a1a;
}
/* Hide Scrollbar for Carousel */
.hide-scrollbar::-webkit-scrollbar {
display: none;
}
}
+4
View File
@@ -9,5 +9,9 @@
"devDependencies": {
"@tailwindcss/vite": "^4.3.0",
"tailwindcss": "^4.3.0"
},
"dependencies": {
"lucide-react": "^1.14.0",
"react-icons": "^5.6.0"
}
}
+25
View File
@@ -7,6 +7,13 @@ settings:
importers:
.:
dependencies:
lucide-react:
specifier: ^1.14.0
version: 1.14.0(react@19.2.6)
react-icons:
specifier: ^5.6.0
version: 5.6.0(react@19.2.6)
devDependencies:
'@tailwindcss/vite':
specifier: ^4.3.0
@@ -837,6 +844,11 @@ packages:
lru-cache@5.1.1:
resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==}
lucide-react@1.14.0:
resolution: {integrity: sha512-+1mdWcfSJVUsaTIjN9zoezmUhfXo5l0vP7ekBMPo3jcS/aIkxHnXqAPsByszMZx/Y8oQBRJxJx5xg+RH3urzxA==}
peerDependencies:
react: ^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0
magic-string@0.30.21:
resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==}
@@ -902,6 +914,11 @@ packages:
peerDependencies:
react: ^19.2.6
react-icons@5.6.0:
resolution: {integrity: sha512-RH93p5ki6LfOiIt0UtDyNg/cee+HLVR6cHHtW3wALfo+eOHTp8RnU2kRkI6E+H19zMIs03DyxUG/GfZMOGvmiA==}
peerDependencies:
react: '*'
react@19.2.6:
resolution: {integrity: sha512-sfWGGfavi0xr8Pg0sVsyHMAOziVYKgPLNrS7ig+ivMNb3wbCBw3KxtflsGBAwD3gYQlE/AEZsTLgToRrSCjb0Q==}
engines: {node: '>=0.10.0'}
@@ -1767,6 +1784,10 @@ snapshots:
dependencies:
yallist: 3.1.1
lucide-react@1.14.0(react@19.2.6):
dependencies:
react: 19.2.6
magic-string@0.30.21:
dependencies:
'@jridgewell/sourcemap-codec': 1.5.5
@@ -1823,6 +1844,10 @@ snapshots:
react: 19.2.6
scheduler: 0.27.0
react-icons@5.6.0(react@19.2.6):
dependencies:
react: 19.2.6
react@19.2.6: {}
rolldown@1.0.0-rc.18: