diff --git a/public/files/alexdaichendt.jpg b/public/files/alexdaichendt.jpg new file mode 100644 index 0000000..8afc9ec Binary files /dev/null and b/public/files/alexdaichendt.jpg differ diff --git a/src/assets/me.jpg b/src/assets/me.jpg new file mode 100644 index 0000000..8afc9ec Binary files /dev/null and b/src/assets/me.jpg differ diff --git a/src/assets/projects/discretizeui/demo.png b/src/assets/projects/discretizeui/demo.png new file mode 100644 index 0000000..e002d83 Binary files /dev/null and b/src/assets/projects/discretizeui/demo.png differ diff --git a/src/assets/projects/discretizeui/languages.png b/src/assets/projects/discretizeui/languages.png new file mode 100644 index 0000000..61c5dc0 Binary files /dev/null and b/src/assets/projects/discretizeui/languages.png differ diff --git a/src/assets/projects/discretizeui/tooltip.png b/src/assets/projects/discretizeui/tooltip.png new file mode 100644 index 0000000..620437e Binary files /dev/null and b/src/assets/projects/discretizeui/tooltip.png differ diff --git a/src/assets/projects/optimizer/Discretize-Gear-Optimizer-08-05-2025_11_52_AM.png b/src/assets/projects/optimizer/Discretize-Gear-Optimizer-08-05-2025_11_52_AM.png new file mode 100644 index 0000000..6ddfaef Binary files /dev/null and b/src/assets/projects/optimizer/Discretize-Gear-Optimizer-08-05-2025_11_52_AM.png differ diff --git a/src/assets/projects/optimizer/Discretize-Gear-Optimizer-08-05-2025_11_53_AM.png b/src/assets/projects/optimizer/Discretize-Gear-Optimizer-08-05-2025_11_53_AM.png new file mode 100644 index 0000000..7772428 Binary files /dev/null and b/src/assets/projects/optimizer/Discretize-Gear-Optimizer-08-05-2025_11_53_AM.png differ diff --git a/src/assets/projects/optimizer/Discretize-Gear-Optimizer-08-05-2025_11_54_AM.png b/src/assets/projects/optimizer/Discretize-Gear-Optimizer-08-05-2025_11_54_AM.png new file mode 100644 index 0000000..67e405f Binary files /dev/null and b/src/assets/projects/optimizer/Discretize-Gear-Optimizer-08-05-2025_11_54_AM.png differ diff --git a/src/assets/projects/optimizer/Discretize-Gear-Optimizer-08-05-2025_11_55_AM.png b/src/assets/projects/optimizer/Discretize-Gear-Optimizer-08-05-2025_11_55_AM.png new file mode 100644 index 0000000..ae93465 Binary files /dev/null and b/src/assets/projects/optimizer/Discretize-Gear-Optimizer-08-05-2025_11_55_AM.png differ diff --git a/src/assets/projects/videovault/dashboard.png b/src/assets/projects/videovault/dashboard.png new file mode 100644 index 0000000..a6da330 Binary files /dev/null and b/src/assets/projects/videovault/dashboard.png differ diff --git a/src/assets/projects/videovault/edit.png b/src/assets/projects/videovault/edit.png new file mode 100644 index 0000000..5ed0e8b Binary files /dev/null and b/src/assets/projects/videovault/edit.png differ diff --git a/src/assets/projects/videovault/frontpage.png b/src/assets/projects/videovault/frontpage.png new file mode 100644 index 0000000..3ba456c Binary files /dev/null and b/src/assets/projects/videovault/frontpage.png differ diff --git a/src/assets/projects/videovault/player.png b/src/assets/projects/videovault/player.png new file mode 100644 index 0000000..4532b25 Binary files /dev/null and b/src/assets/projects/videovault/player.png differ diff --git a/src/components/BaseHead.astro b/src/components/BaseHead.astro index 9ad5d9b..57bb16b 100644 --- a/src/components/BaseHead.astro +++ b/src/components/BaseHead.astro @@ -1,6 +1,4 @@ --- -// Import the global.css file here so that it is included on -// all pages through the use of the component. import "../styles/global.css"; import ubuntuRegularWoff2 from "@fontsource/ubuntu/files/ubuntu-latin-400-normal.woff2?url"; import ubuntuBoldWoff2 from "@fontsource/ubuntu/files/ubuntu-latin-700-normal.woff2?url"; @@ -63,3 +61,59 @@ const { title, description, image = "/blog-placeholder-1.jpg" } = Astro.props; + + + diff --git a/src/components/Carousel.astro b/src/components/Carousel.astro new file mode 100644 index 0000000..8ef2067 --- /dev/null +++ b/src/components/Carousel.astro @@ -0,0 +1,233 @@ +--- +import type { ImageMetadata } from "astro"; +import { Icon } from "astro-icon/components"; + +interface Props { + images: { + src: ImageMetadata; + alt: string; + }[]; +} + +const { images } = Astro.props; + +const carouselId = `carousel-${Math.random().toString(36).slice(2, 11)}`; +const helpId = `${carouselId}-help`; +--- + +
+ + + + + + + + + + + + +
+
+ + +

+ Carousel focused. Use Left and Right Arrow keys to change slides. Press T to + toggle wide mode. Press Escape to exit wide mode. +

+
+ + diff --git a/src/components/DarkModeToggle.astro b/src/components/DarkModeToggle.astro deleted file mode 100644 index b878712..0000000 --- a/src/components/DarkModeToggle.astro +++ /dev/null @@ -1,148 +0,0 @@ ---- - ---- - - - - - - diff --git a/src/components/Footer.astro b/src/components/Footer.astro deleted file mode 100644 index 6cee9c2..0000000 --- a/src/components/Footer.astro +++ /dev/null @@ -1,14 +0,0 @@ ---- -const today = new Date(); ---- - - - diff --git a/src/components/ImpressumContent.astro b/src/components/ImpressumContent.astro new file mode 100644 index 0000000..b142439 --- /dev/null +++ b/src/components/ImpressumContent.astro @@ -0,0 +1,275 @@ +--- +interface Props { + companyName?: string; + ownerName?: string; + address?: { + street?: string; + city?: string; + postalCode?: string; + country?: string; + }; + contact?: { + phone?: string; + email: string; + website: string; + }; + business?: { + vatId?: string; + registrationOffice?: string; + }; + responsiblePerson?: { + name: string; + address: { + street: string; + city: string; + postalCode: string; + country: string; + }; + }; +} + +const { + companyName, + ownerName, + address, + contact, + business, + responsiblePerson, +} = Astro.props; +--- + +
+
+

+ Diensteanbieter +

+
+
+
Firmenname:
+
+ {companyName} +
+
+
+
Inhaber:
+
+ {ownerName} +
+
+
+
Anschrift:
+
+ {address?.street}
+ {address?.postalCode} + {address?.city}
+ {address?.country} +
+
+
+
+ + +
+

+ Kontaktdaten +

+
+ { + contact?.phone && ( +
+
+ Telefon: +
+
+ {contact?.phone} +
+
+ ) + } +
+
E-Mail:
+
+ + {contact?.email} + +
+
+
+
Website:
+
+ + {contact?.website} + +
+
+
+
+ + + { + (business?.vatId || business?.registrationOffice) && ( +
+

+ Gewerbliche Angaben +

+
+ {business?.vatId && ( +
+
+ Umsatzsteuer-ID: +
+
+ {business.vatId} +
+ + gemäß § 27a Umsatzsteuergesetz + +
+
+ )} + {business.registrationOffice && ( +
+
+ Gewerbeanmeldung: +
+
+ {business?.registrationOffice} +
+
+ )} +
+
+ ) + } + + +
+

+ Verantwortlich für den Inhalt +

+
+
+ Verantwortlich nach § 55 Abs. 2 RStV: +
+
+ {responsiblePerson?.name}
+ {responsiblePerson?.address.street}
+ {responsiblePerson?.address.postalCode} + {responsiblePerson?.address.city}
+ {responsiblePerson?.address.country} +
+
+
+ + +
+

+ EU-Streitschlichtung +

+
+
+
+ Online-Streitbeilegung: +
+
+ Die Europäische Kommission stellt eine Plattform zur + Online-Streitbeilegung (OS) bereit:
+ + https://ec.europa.eu/consumers/odr/ + +
+
+
+
+ Verbraucherschlichtung: +
+
+ Wir sind nicht bereit oder verpflichtet, an Streitbeilegungsverfahren + vor einer Verbraucherschlichtungsstelle teilzunehmen. +
+
+
+
+ + +
+

+ Haftungsausschluss +

+ + +
+

+ Haftung für Inhalte +

+

+ Als Diensteanbieter sind wir gemäß § 7 Abs.1 TMG für eigene Inhalte auf + diesen Seiten nach den allgemeinen Gesetzen verantwortlich. Nach §§ 8 + bis 10 TMG sind wir als Diensteanbieter jedoch nicht unter der + Verpflichtung, übermittelte oder gespeicherte fremde Informationen zu + überwachen oder nach Umständen zu forschen, die auf eine rechtswidrige + Tätigkeit hinweisen. +

+
+ + +
+

+ Haftung für Links +

+

+ Unser Angebot enthält Links zu externen Websites Dritter, auf deren + Inhalte wir keinen Einfluss haben. Deshalb können wir für diese fremden + Inhalte auch keine Gewähr übernehmen. Für die Inhalte der verlinkten + Seiten ist stets der jeweilige Anbieter oder Betreiber der Seiten + verantwortlich. +

+
+ + +
+

+ Urheberrecht +

+

+ Die durch die Seitenbetreiber erstellten Inhalte und Werke auf diesen + Seiten unterliegen dem deutschen Urheberrecht. Die Vervielfältigung, + Bearbeitung, Verbreitung und jede Art der Verwertung außerhalb der + Grenzen des Urheberrechtes bedürfen der schriftlichen Zustimmung des + jeweiligen Autors bzw. Erstellers. +

+
+
+ + +
+

+ Letzte Aktualisierung: + {new Date().toLocaleDateString("de-DE")} + +

+
+
diff --git a/src/components/Logo.astro b/src/components/Logo.astro new file mode 100644 index 0000000..4c193a0 --- /dev/null +++ b/src/components/Logo.astro @@ -0,0 +1,168 @@ + + + diff --git a/src/components/NavMenu.astro b/src/components/NavMenu.astro deleted file mode 100644 index ab9e47e..0000000 --- a/src/components/NavMenu.astro +++ /dev/null @@ -1,85 +0,0 @@ ---- -import { Icon } from "astro-icon/components"; -import HeaderLink from "./HeaderLink.astro"; ---- - - - - -
-
- Home - Blog - Projects - Publications - Contact -
-
- - diff --git a/src/components/PageHeadline.astro b/src/components/PageHeadline.astro new file mode 100644 index 0000000..1fb1022 --- /dev/null +++ b/src/components/PageHeadline.astro @@ -0,0 +1,22 @@ +--- +interface Props { + title: string; + subtitle?: string; +} + +const { title, subtitle } = Astro.props; +--- + +
+

+ {title} +

+ { + subtitle && ( +

+ {subtitle} +

+ ) + } +
+
diff --git a/src/components/Picture.astro b/src/components/Picture.astro index 87e8213..54de063 100644 --- a/src/components/Picture.astro +++ b/src/components/Picture.astro @@ -3,7 +3,8 @@ import { Picture as AstroPicture } from "astro:assets"; --- diff --git a/src/components/ProjectSection.astro b/src/components/ProjectSection.astro new file mode 100644 index 0000000..29cc95e --- /dev/null +++ b/src/components/ProjectSection.astro @@ -0,0 +1,99 @@ +--- +import { Icon } from "astro-icon/components"; +import { type Project } from "../consts"; +import Carousel from "./Carousel.astro"; +import ThreeColumnSection from "./ThreeColumnSection.astro"; + +interface Props { + projects: Project[]; +} + +const { projects } = Astro.props; +--- + +{ + projects.map((project) => ( + + {/* ---------- LEFT: Project details ---------- */} +
+
+ {/* Title + optional company */} +

+ {project.title} + + {/* Duration */} +

+ + {project.duration} +

+

+ + {/* Description */} +

+ {project.description} +

+ + {/* Tech stack */} +
+ {project.tech_stack.map((tech) => ( + + {tech} + + ))} +
+ + {/* Deliverables (optional) */} + {project.deliverables?.length && ( +
    + {project.deliverables.map((item) => ( +
  • {item}
  • + ))} +
+ )} + + {/* Links */} +
+ {project.live_url && ( + + Live + + )} + {project.repo_url && ( + + Repo + + )} +
+
+
+ + {/* ---------- CENTER: Carousel ---------- */} +
+
+ +
+
+ + {/* ---------- RIGHT: Empty for now ---------- */} +