diff --git a/project/assets/styles/app.css b/project/assets/styles/app.css index 974a0ae..f4aa9ab 100644 --- a/project/assets/styles/app.css +++ b/project/assets/styles/app.css @@ -317,6 +317,55 @@ a { color: inherit; text-decoration: none; } .action-live:hover { background: rgba(255, 138, 91, 0.24); } .action svg { width: 15px; height: 15px; } +/* --- homelab ------------------------------------------------------------ */ + +.lab-grid { + display: grid; + grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); + gap: 18px; +} +.lab-card { + background: var(--surface); + border: 1px solid var(--line); + border-radius: var(--radius); + padding: 22px 22px 24px; + display: flex; + flex-direction: column; + transition: border-color 0.18s, transform 0.18s; +} +.lab-card:hover { border-color: var(--line-strong); transform: translateY(-3px); } +.lab-card--featured { + border-color: rgba(255, 138, 91, 0.4); + background: linear-gradient(160deg, var(--coral-soft), transparent 60%), var(--surface); + grid-column: 1 / -1; +} +.lab-head { + display: flex; + align-items: baseline; + gap: 12px; + margin-bottom: 12px; + flex-wrap: wrap; +} +.lab-name { + font-family: var(--display); + font-size: 1.12rem; + font-weight: 600; + color: var(--text); +} +.lab-tag { + font-family: var(--mono); + font-size: 0.72rem; + color: var(--coral); + background: var(--coral-soft); + border-radius: 6px; + padding: 3px 8px; +} +.lab-desc { color: var(--muted); font-size: 0.95rem; margin: 0; line-height: 1.55; } + +@media (min-width: 720px) { + .lab-card--featured .lab-desc { max-width: 68ch; } +} + /* --- webview modal (signature) ------------------------------------------ */ .webview { diff --git a/project/src/Controller/HomeController.php b/project/src/Controller/HomeController.php index 3807c20..7a13742 100644 --- a/project/src/Controller/HomeController.php +++ b/project/src/Controller/HomeController.php @@ -16,6 +16,7 @@ class HomeController extends AbstractController 'profile' => $content->profile(), 'technologies' => $content->technologies(), 'projects' => $content->projects(), + 'homelab' => $content->homelab(), ]); } } diff --git a/project/src/Portfolio/PortfolioContent.php b/project/src/Portfolio/PortfolioContent.php index f79efa6..20bb04d 100644 --- a/project/src/Portfolio/PortfolioContent.php +++ b/project/src/Portfolio/PortfolioContent.php @@ -48,6 +48,61 @@ final class PortfolioContent ]; } + /** + * Homelab — własna infrastruktura self-hosted. + * + * @return array{lead: string, services: list} + */ + public function homelab(): array + { + return [ + 'lead' => 'Cała powyższa infrastruktura działa na moim własnym serwerze fizycznym — od hypervisora, przez sieć i reverse proxy, aż po usługi, z których korzystam na co dzień. Wszystko postawione, skonfigurowane i utrzymywane samodzielnie.', + 'services' => [ + [ + 'name' => 'Proxmox VE', + 'role' => 'Hypervisor', + 'description' => 'Serwer fizyczny postawiony i skonfigurowany od zera. Zarządza maszynami wirtualnymi i kontenerami LXC — stanowi fundament całego homelaba.', + 'featured' => true, + ], + [ + 'name' => 'Traefik', + 'role' => 'Reverse proxy', + 'description' => 'Routing ruchu do poszczególnych usług oraz automatyczne zarządzanie certyfikatami TLS. Każdy serwis dostępny pod własną subdomeną po HTTPS.', + ], + [ + 'name' => 'VM z Dockerem', + 'role' => 'Konteneryzacja', + 'description' => 'Dedykowana maszyna wirtualna hostująca aplikacje w kontenerach Docker — spójne, powtarzalne środowisko uruchomieniowe dla self-hosted usług.', + ], + [ + 'name' => 'Home Assistant', + 'role' => 'Smart home', + 'description' => 'Centrum automatyki domowej — integracja urządzeń, scenariusze i sterowanie inteligentnym domem w jednym miejscu.', + ], + [ + 'name' => 'Gitea', + 'role' => 'Git hosting', + 'description' => 'Własny, lekki hosting repozytoriów Git. Prywatne repozytoria i pełna kontrola nad kodem bez zależności od zewnętrznych usług.', + ], + [ + 'name' => 'Immich', + 'role' => 'Zdjęcia', + 'description' => 'Prywatna galeria i backup zdjęć oraz filmów — self-hosted alternatywa dla chmury, z automatycznym uploadem z telefonu.', + ], + [ + 'name' => 'Nextcloud', + 'role' => 'Chmura plików', + 'description' => 'Osobista chmura na pliki, kalendarz i kontakty. Synchronizacja i współdzielenie danych na własnych warunkach.', + ], + [ + 'name' => 'Vaultwarden', + 'role' => 'Menedżer haseł', + 'description' => 'Self-hosted menedżer haseł kompatybilny z Bitwarden. Wszystkie sekrety trzymane lokalnie, pod pełną kontrolą.', + ], + ], + ]; + } + /** * Lista projektów. * diff --git a/project/templates/home/index.html.twig b/project/templates/home/index.html.twig index 662d947..c28d1d4 100644 --- a/project/templates/home/index.html.twig +++ b/project/templates/home/index.html.twig @@ -10,6 +10,7 @@ o mnie stack projekty [{{ projects|length }}] + homelab kontakt @@ -165,6 +166,28 @@ + + {# ---- HOMELAB ---- #} +
+
+
+

homelab

+

Własna infrastruktura, self-hosted

+

{{ homelab.lead }}

+
+
+ {% for service in homelab.services %} +
+
+ {{ service.name }} + {{ service.role }} +
+

{{ service.description }}

+
+ {% endfor %} +
+
+