From 9490050690831466c729cb7c3a374b561db40e73 Mon Sep 17 00:00:00 2001 From: Clemens Hering Date: Wed, 19 Nov 2025 21:54:51 +0100 Subject: [PATCH] intitial --- valtrix-web/.gitea/workflows/deploy.yaml | 107 +++++ valtrix-web/Caddyfile | 20 + valtrix-web/Dockerfile | 34 ++ valtrix-web/datenschutz-en.html | 96 ++++ valtrix-web/datenschutz.html | 96 ++++ valtrix-web/deploy/valtrix-web.contaier | 35 ++ valtrix-web/impressum-en.html | 73 +++ valtrix-web/impressum.html | 59 +++ valtrix-web/index-en.html | 146 ++++++ valtrix-web/index.html | 147 ++++++ valtrix-web/logo_ideas.html | 141 ++++++ valtrix-web/script.js | 27 ++ valtrix-web/style.css | 559 +++++++++++++++++++++++ 13 files changed, 1540 insertions(+) create mode 100644 valtrix-web/.gitea/workflows/deploy.yaml create mode 100644 valtrix-web/Caddyfile create mode 100644 valtrix-web/Dockerfile create mode 100644 valtrix-web/datenschutz-en.html create mode 100644 valtrix-web/datenschutz.html create mode 100644 valtrix-web/deploy/valtrix-web.contaier create mode 100644 valtrix-web/impressum-en.html create mode 100644 valtrix-web/impressum.html create mode 100644 valtrix-web/index-en.html create mode 100644 valtrix-web/index.html create mode 100644 valtrix-web/logo_ideas.html create mode 100644 valtrix-web/script.js create mode 100644 valtrix-web/style.css diff --git a/valtrix-web/.gitea/workflows/deploy.yaml b/valtrix-web/.gitea/workflows/deploy.yaml new file mode 100644 index 0000000..4ae1fa5 --- /dev/null +++ b/valtrix-web/.gitea/workflows/deploy.yaml @@ -0,0 +1,107 @@ +name: Build and Deploy Container + +on: + push: + branches: + - main + - develop + +env: # global: unkritische, strukturgebende Variablen + TARGET_HOST: host.containers.internal + TARGET_USER: traefik + APP_DIR: /home/traefik/valtrix-web + CONTAINER_NAME: valtrix-web + QUADLET_FILE: ./deploy/valtrix-web.container + +jobs: + build_and_deploy: + runs-on: ubuntu-latest + env: # Job-spezifisch: Secrets und sensible Werte + SSH_PRIVATE_KEY: ${{ secrets.SSH_PRIVATE_KEY }} + SSH_KNOWN_HOSTS: ${{ secrets.SSH_KNOWN_HOSTS }} + + steps: + - name: Pre-clean Git global config (avoid https→ssh rewrite) + shell: bash + run: | + set -euo pipefail + echo "Cleaning up global git config" + git config --global --unset-all core.sshCommand || true + for key in $(git config --global --get-regexp '^url\\..*\\.insteadof$' 2>/dev/null | awk '{print $1}'); do + if echo "$key" | grep -qi 'gitea\\.smb-corp\\.de'; then + git config --global --unset-all "$key" || true + fi + done + + - name: Setup SSH for git/scp + shell: bash + run: | + install -m 700 -d ~/.ssh + printf "%s\n" "$SSH_PRIVATE_KEY" > ~/.ssh/id_ed25519 + chmod 600 ~/.ssh/id_ed25519 + printf "%s\n" "$SSH_KNOWN_HOSTS" > ~/.ssh/known_hosts || true + chmod 644 ~/.ssh/known_hosts + # Ensure host keys exist + (ssh-keygen -F "$TARGET_HOST" >/dev/null || ssh-keyscan -H "$TARGET_HOST" >> ~/.ssh/known_hosts) || true + (ssh-keygen -F gitea.smb-corp.de >/dev/null || ssh-keyscan -H gitea.smb-corp.de >> ~/.ssh/known_hosts) || true + + - name: Checkout Repository + uses: actions/checkout@v4 + + - name: Copy repository to target host (atomic replace) + shell: bash + run: | + set -euo pipefail + TMP_DIR="$APP_DIR.tmp.$(date +%s)" + ssh -i ~/.ssh/id_ed25519 $TARGET_USER@$TARGET_HOST "mkdir -p '$TMP_DIR'" + scp -r -i ~/.ssh/id_ed25519 ./* $TARGET_USER@$TARGET_HOST:$TMP_DIR/ + ssh -i ~/.ssh/id_ed25519 $TARGET_USER@$TARGET_HOST " + set -euo pipefail; + if [ -d '$APP_DIR' ]; then rm -rf '$APP_DIR'; fi; + mv '$TMP_DIR' '$APP_DIR' + " + + - name: Build container on target host + shell: bash + run: | + ssh -i ~/.ssh/id_ed25519 $TARGET_USER@$TARGET_HOST " + set -euo pipefail + export APP_DIR='$APP_DIR' CONTAINER_NAME='$CONTAINER_NAME' + cd \"\$APP_DIR\" + echo 'Building container: '\$CONTAINER_NAME 'in' \$APP_DIR + podman build -t \$CONTAINER_NAME:latest . + " + + - name: Backup existing Quadlet file + shell: bash + run: | + ssh -i ~/.ssh/id_ed25519 $TARGET_USER@$TARGET_HOST " + set -euo pipefail + export CONTAINER_NAME='$CONTAINER_NAME' + QFILE=~/.config/containers/systemd/\$CONTAINER_NAME.container + test -f \"\$QFILE\" && cp \"\$QFILE\" \"\$QFILE.bak\" || true + " + + - name: Replace Quadlet file and restart service + shell: bash + run: | + scp -i ~/.ssh/id_ed25519 "$QUADLET_FILE" $TARGET_USER@$TARGET_HOST:~/.config/containers/systemd/ + ssh -i ~/.ssh/id_ed25519 $TARGET_USER@$TARGET_HOST " + set -euo pipefail + export CONTAINER_NAME='$CONTAINER_NAME' + systemctl --user daemon-reload + systemctl --user restart \$CONTAINER_NAME.service + echo 'Service restarted: '\$CONTAINER_NAME + " + + - name: Verify deployment + shell: bash + run: | + ssh -i ~/.ssh/id_ed25519 $TARGET_USER@$TARGET_HOST " + set -euo pipefail + export CONTAINER_NAME='$CONTAINER_NAME' + echo 'Running containers:' + podman ps --filter \"name=\$CONTAINER_NAME\" --format \"table {{.Names}}\t{{.Image}}\t{{.Status}}\" + echo '--- Last 20 log lines ---' + podman logs \$CONTAINER_NAME --tail 20 || echo 'No logs available' + " \ No newline at end of file diff --git a/valtrix-web/Caddyfile b/valtrix-web/Caddyfile new file mode 100644 index 0000000..7695958 --- /dev/null +++ b/valtrix-web/Caddyfile @@ -0,0 +1,20 @@ +:80 { + # Set the root directory for the static site + root * /usr/share/caddy + + # Enable file server + file_server + + # Enable compression (gzip/zstd) + encode gzip zstd + + # Security headers (optional but recommended) + header { + # Enable HSTS + Strict-Transport-Security "max-age=31536000;" + # Disable MIME sniffing + X-Content-Type-Options "nosniff" + # XSS protection + X-XSS-Protection "1; mode=block" + } +} diff --git a/valtrix-web/Dockerfile b/valtrix-web/Dockerfile new file mode 100644 index 0000000..4fa2399 --- /dev/null +++ b/valtrix-web/Dockerfile @@ -0,0 +1,34 @@ +# Stage 1: Builder +# We use a lightweight Wolfi image to gather the files. +# In a real build process, this might involve 'npm run build', but for static files, +# we just copy them. Using a stage here allows for future extensibility. +FROM cgr.dev/chainguard/wolfi-base AS builder + +WORKDIR /app + +# Copy all files to the builder stage +COPY . . + +# Stage 2: Final +# Use the official Wolfi base image and install Caddy manually +# since the pre-built Caddy image requires authentication or is restricted. +FROM cgr.dev/chainguard/wolfi-base:latest + +# Install Caddy +RUN apk update && apk add caddy + +# Copy the Caddyfile +COPY Caddyfile /etc/caddy/Caddyfile + +# Copy the static site content from the builder stage +COPY --from=builder /app /usr/share/caddy + +# Expose ports +# 80 for HTTP +# 443 for HTTPS (and HTTP/3 over UDP) +EXPOSE 80 +EXPOSE 443 +EXPOSE 443/udp + +# Run Caddy +CMD ["caddy", "run", "--config", "/etc/caddy/Caddyfile", "--adapter", "caddyfile"] diff --git a/valtrix-web/datenschutz-en.html b/valtrix-web/datenschutz-en.html new file mode 100644 index 0000000..05bb9fa --- /dev/null +++ b/valtrix-web/datenschutz-en.html @@ -0,0 +1,96 @@ + + + + + + + Privacy Policy - Valtrix + + + + + + + +
+ +
+ + + + + + + \ No newline at end of file diff --git a/valtrix-web/datenschutz.html b/valtrix-web/datenschutz.html new file mode 100644 index 0000000..dfab787 --- /dev/null +++ b/valtrix-web/datenschutz.html @@ -0,0 +1,96 @@ + + + + + + + Datenschutzerklärung - Valtrix + + + + + + +
+ +
+ + + + + \ No newline at end of file diff --git a/valtrix-web/deploy/valtrix-web.contaier b/valtrix-web/deploy/valtrix-web.contaier new file mode 100644 index 0000000..84499af --- /dev/null +++ b/valtrix-web/deploy/valtrix-web.contaier @@ -0,0 +1,35 @@ +[Unit] +Description=Valtrix Web + +[Container] +Image=localhost/valtrix-web +ContainerName=valtrix-web +Network=edge +AutoUpdate=registry +Environment=TZ=Europe/Berlin + +#Traefik Labels +Label="traefik.enable=true" +Label="traefik.http.routers.valtrix-web.rule=Host(`web.valtrix.systems`)" +Label="traefik.http.services.valtrix-web.loadbalancer.server.port=3010" +Label="traefik.http.routers.valtrix-web.entrypoints=websecure" +Label="traefik.http.routers.valtrix-web.tls=true" +Label="traefik.http.routers.valtrix-web.tls.certresolver=le" + +Label="traefik.http.routers.valtrix-web-http.rule=Host(`web.valtrix.systems`)" +Label="traefik.http.routers.valtrix-web-http.entrypoints=web" +Label="traefik.http.routers.valtrix-web-http.middlewares=valtrix-web-redirect" +Label="traefik.http.middlewares.valtrix-web-redirect.redirectscheme.scheme=https" +Label="traefik.http.middlewares.valtrix-web-redirect.redirectscheme.permanent=true" +Label="traefik.http.routers.valtrix-web.middlewares=secure-headers@file" + +Label="traefik.http.middlewares.valtrix-web-sec.headers.customResponseHeaders.Content-Security-Policy=default-src 'self'; base-uri 'self'; object-src 'none'; frame-ancestors 'self'; img-src 'self' data:; style-src 'self' 'unsafe-inline'; script-src 'self'; script-src-elem 'self' 'unsafe-inline'; connect-src 'self' wss: https:; font-src 'self' data:; worker-src 'self' blob:;" +Label="traefik.http.routers.valtrix-web.middlewares=valtrix-web-sec@docker" +Label="traefik.http.routers.valtrix-web.middlewares=auth" +Label="traefik.http.middlewares.auth.basicauth.users=smb:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/" + +[Service] +Restart=on-failure + +[Install] +WantedBy=default.target \ No newline at end of file diff --git a/valtrix-web/impressum-en.html b/valtrix-web/impressum-en.html new file mode 100644 index 0000000..1518b38 --- /dev/null +++ b/valtrix-web/impressum-en.html @@ -0,0 +1,73 @@ + + + + + + + Imprint - Valtrix + + + + + + + +
+ +
+ + + + + + + \ No newline at end of file diff --git a/valtrix-web/impressum.html b/valtrix-web/impressum.html new file mode 100644 index 0000000..b869ad1 --- /dev/null +++ b/valtrix-web/impressum.html @@ -0,0 +1,59 @@ + + + + + + + Impressum - Valtrix + + + + + + +
+ +
+ + + + + \ No newline at end of file diff --git a/valtrix-web/index-en.html b/valtrix-web/index-en.html new file mode 100644 index 0000000..731e2ca --- /dev/null +++ b/valtrix-web/index-en.html @@ -0,0 +1,146 @@ + + + + + + + Valtrix - Security, AI & Cloud Solutions + + + + + + + + + + +
+
+

Security for the
Digital Future

+

We combine Security, AI, and Cloud into robust solutions for your business.

+ +
+
+
+ + +
+
+
+ Who We Are +

Innovation Meets Security

+
+
+
+

Valtrix stands for technological excellence. In an increasingly complex digital world, we provide + the protection and infrastructure you need to grow.

+

Our team of experts combines deep cybersecurity knowledge with state-of-the-art AI approaches and + scalable cloud architectures.

+
+
+ +
+
+
+
+
+ + +
+
+
+ Our Services +

Holistic IT Solutions

+
+
+
+
🛡️
+

Security

+

Proactive protection for your data and infrastructure. Penetration Testing, Audits, and + Secure-by-Design Architecture.

+
+
+
🤖
+

Artificial Intelligence

+

Tailored AI models and automation solutions that make your processes more efficient.

+
+
+
☁️
+

Cloud Computing

+

Scalable and secure cloud migrations, management, and optimization for AWS, Azure, and Google + Cloud.

+
+
+
+
+ + +
+
+
+ References +

Trust Through Performance

+
+
+ +
TechCorp Solutions
+
Global Finance AG
+
SecureNet Systems
+
Future AI Lab
+
+
+
+ + +
+
+
+ Contact +

Start Your Project

+
+
+
+

Let's Talk

+

Ready for the next step? Send us an email or give us a call.

+ info@valtrix.systems +

Musterstraße 123
10115 Berlin
Germany

+
+
+
+
+ + + + + + + + \ No newline at end of file diff --git a/valtrix-web/index.html b/valtrix-web/index.html new file mode 100644 index 0000000..2bdba06 --- /dev/null +++ b/valtrix-web/index.html @@ -0,0 +1,147 @@ + + + + + + + Valtrix - Security, AI & Cloud Solutions + + + + + + + + + + +
+
+

Sicherheit für die
Digitale Zukunft

+

Wir verbinden Security, AI und Cloud zu robusten Lösungen für Ihr Unternehmen.

+ +
+
+
+ + +
+
+
+ Wer wir sind +

Innovation trifft Sicherheit

+
+
+
+

Valtrix steht für technologische Exzellenz. In einer immer komplexer werdenden digitalen Welt + bieten wir Ihnen den Schutz und die Infrastruktur, die Sie benötigen, um zu wachsen.

+

Unser Team aus Experten vereint tiefgehendes Wissen in Cybersecurity mit modernsten KI-Ansätzen + und skalierbaren Cloud-Architekturen.

+
+
+ +
+
+
+
+
+ + +
+
+
+ Unsere Leistungen +

Ganzheitliche IT-Lösungen

+
+
+
+
🛡️
+

Security

+

Proaktiver Schutz für Ihre Daten und Infrastruktur. Penetration Testing, Audits und + Secure-by-Design Architektur.

+
+
+
🤖
+

Artificial Intelligence

+

Maßgeschneiderte KI-Modelle und Automatisierungslösungen, die Ihre Prozesse effizienter machen. +

+
+
+
☁️
+

Cloud Computing

+

Skalierbare und sichere Cloud-Migrationen, Management und Optimierung für AWS, Azure und Google + Cloud.

+
+
+
+
+ + +
+
+
+ Referenzen +

Vertrauen durch Leistung

+
+
+ +
TechCorp Solutions
+
Global Finance AG
+
SecureNet Systems
+
Future AI Lab
+
+
+
+ + +
+
+
+ Kontakt +

Starten Sie Ihr Projekt

+
+
+
+

Lassen Sie uns sprechen

+

Bereit für den nächsten Schritt? Schreiben Sie uns eine E-Mail oder rufen Sie an.

+ info@valtrix.systems +

Musterstraße 123
10115 Berlin
Deutschland

+
+
+
+
+ + + + + + + + \ No newline at end of file diff --git a/valtrix-web/logo_ideas.html b/valtrix-web/logo_ideas.html new file mode 100644 index 0000000..451f654 --- /dev/null +++ b/valtrix-web/logo_ideas.html @@ -0,0 +1,141 @@ + + + + + + + Valtrix Logo Concepts + + + + + + +

Logo Vorschläge

+ +
+ 1. Modern Minimal (Aktuell) +
Valtrix.
+
+ +
+ 2. Cyber Shield (Security Focus) +
+ + + + Valtrix +
+
+ +
+ 3. Tech Block (Modern SaaS) +
+
V
+ Valtrix +
+
+ +
+ 4. Terminal Code (Dev/Cloud) +
<Valtrix />
+
+ + + + \ No newline at end of file diff --git a/valtrix-web/script.js b/valtrix-web/script.js new file mode 100644 index 0000000..adb9dc8 --- /dev/null +++ b/valtrix-web/script.js @@ -0,0 +1,27 @@ +document.addEventListener('DOMContentLoaded', () => { + const mobileToggle = document.querySelector('.mobile-toggle'); + const navLinks = document.querySelector('.nav-links'); + + if (mobileToggle) { + mobileToggle.addEventListener('click', () => { + navLinks.classList.toggle('active'); + }); + } + + // Smooth scroll for anchor links + document.querySelectorAll('a[href^="#"]').forEach(anchor => { + anchor.addEventListener('click', function (e) { + e.preventDefault(); + const target = document.querySelector(this.getAttribute('href')); + if (target) { + target.scrollIntoView({ + behavior: 'smooth' + }); + // Close mobile menu on click + if (navLinks.classList.contains('active')) { + navLinks.classList.remove('active'); + } + } + }); + }); +}); diff --git a/valtrix-web/style.css b/valtrix-web/style.css new file mode 100644 index 0000000..97dd98f --- /dev/null +++ b/valtrix-web/style.css @@ -0,0 +1,559 @@ +/* Valtrix Design System */ +:root { + /* Colors */ + --bg-dark: #0a0f1c; + /* Deep Navy/Black */ + --bg-card: #111827; + /* Slightly lighter for cards */ + --primary: #00f2ff; + /* Cyan/Electric Blue */ + --secondary: #ffffff; + /* White */ + --text-main: #e5e7eb; + /* Light Gray for text */ + --text-muted: #9ca3af; + /* Muted Gray */ + --accent: #3b82f6; + /* Blue accent */ + + /* Typography */ + --font-main: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif; + + /* Spacing */ + --container-width: 1200px; + --header-height: 80px; +} + +* { + margin: 0; + padding: 0; + box-sizing: border-box; +} + +html { + scroll-behavior: smooth; +} + +body { + font-family: var(--font-main); + background-color: var(--bg-dark); + color: var(--text-main); + line-height: 1.6; + overflow-x: hidden; +} + +a { + text-decoration: none; + color: inherit; + transition: color 0.3s ease; +} + +ul { + list-style: none; +} + +/* Header */ +#header { + position: fixed; + top: 20px; + /* Floating effect */ + left: 50%; + transform: translateX(-50%); + width: 90%; + max-width: 1200px; + height: 70px; + background: rgba(10, 15, 28, 0.7); + backdrop-filter: blur(12px); + -webkit-backdrop-filter: blur(12px); + z-index: 1000; + border: 1px solid rgba(255, 255, 255, 0.08); + border-radius: 50px; + /* Pill shape */ + box-shadow: 0 10px 30px rgba(0, 0, 0, 0.2); + transition: all 0.3s ease; +} + +.header-content { + display: flex; + justify-content: space-between; + align-items: center; + height: 100%; + padding: 0 30px; + /* Inner padding */ + width: 100%; +} + +.logo { + font-size: 1.5rem; + font-weight: 700; + color: var(--secondary); + letter-spacing: -0.5px; +} + +.logo .dot { + color: var(--primary); + text-shadow: 0 0 10px var(--primary); +} + +.nav-links { + display: flex; + gap: 5px; + /* Smaller gap for pill items */ + background: rgba(255, 255, 255, 0.03); + padding: 5px; + border-radius: 30px; +} + +.nav-links a { + font-size: 0.9rem; + font-weight: 500; + color: var(--text-muted); + padding: 8px 20px; + border-radius: 20px; + transition: all 0.3s ease; +} + +/* Remove old underline effect */ +.nav-links a::after { + display: none; +} + +.nav-links a:hover { + color: var(--bg-dark); + background: var(--primary); + box-shadow: 0 0 15px rgba(0, 242, 255, 0.4); +} + +/* Hero Section */ +#hero { + min-height: 100vh; + min-height: 100dvh; + display: flex; + align-items: center; + position: relative; + overflow: hidden; + padding-top: 120px; + /* Ensure content clears the floating header */ + padding-bottom: 60px; +} + +.hero-content { + position: relative; + z-index: 2; + max-width: 1000px; + margin: 0 auto; + /* Center content */ + text-align: center; + /* Center text */ + padding: 0 20px; +} + +#hero h1 { + font-size: 5rem; + /* Larger */ + font-weight: 800; + margin-bottom: 30px; + line-height: 1.1; + letter-spacing: -2px; + background: linear-gradient(to bottom right, #fff, #9ca3af); + -webkit-background-clip: text; + background-clip: text; + -webkit-text-fill-color: transparent; + color: var(--secondary); +} + +@supports (-webkit-background-clip: text) { + #hero h1 { + color: transparent; + } +} + +.highlight { + color: var(--primary); + -webkit-text-fill-color: var(--primary); + text-shadow: 0 0 40px rgba(0, 242, 255, 0.4); + display: block; + /* Break line for emphasis */ +} + +#hero p { + font-size: 1.3rem; + color: var(--text-muted); + margin: 0 auto 50px; + /* Center and spacing */ + max-width: 700px; + line-height: 1.6; +} + +.hero-btns { + display: flex; + gap: 20px; + justify-content: center; + /* Center buttons */ +} + +/* Hero Background Animation */ +.hero-bg { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + background: radial-gradient(circle at 50% 50%, rgba(0, 242, 255, 0.08) 0%, transparent 60%); + z-index: 1; + pointer-events: none; +} + +/* About Section */ +.about-grid { + display: grid; + grid-template-columns: 1fr 1fr; + gap: 80px; + /* More breathing room */ + align-items: center; +} + +.about-text p { + margin-bottom: 24px; + color: var(--text-muted); + font-size: 1.15rem; + line-height: 1.8; +} + +.visual-box { + width: 100%; + height: 450px; + background: linear-gradient(135deg, var(--bg-card), #1f2937); + border-radius: 24px; + position: relative; + overflow: hidden; + border: 1px solid rgba(255, 255, 255, 0.05); + box-shadow: 0 20px 50px rgba(0, 0, 0, 0.3); +} + +.visual-box::before { + content: ''; + position: absolute; + top: -50%; + left: -50%; + width: 200%; + height: 200%; + background: conic-gradient(transparent, var(--primary), transparent 30%); + animation: rotate 8s linear infinite; + /* Slower, smoother animation */ + opacity: 0.15; +} + +@keyframes rotate { + 100% { + transform: rotate(360deg); + } +} + +/* Services Section */ +.services-grid { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(320px, 1fr)); + gap: 40px; +} + +.service-card { + background: rgba(17, 24, 39, 0.6); + /* More transparent */ + backdrop-filter: blur(10px); + -webkit-backdrop-filter: blur(10px); + padding: 48px 40px; + border-radius: 20px; + border: 1px solid rgba(255, 255, 255, 0.05); + transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1); +} + +.service-card:hover { + transform: translateY(-8px); + box-shadow: 0 20px 40px rgba(0, 0, 0, 0.4), 0 0 20px rgba(0, 242, 255, 0.1); + border-color: rgba(0, 242, 255, 0.3); + background: rgba(17, 24, 39, 0.8); +} + +.service-card .icon { + font-size: 3.5rem; + margin-bottom: 24px; + display: inline-block; + filter: drop-shadow(0 0 10px rgba(0, 242, 255, 0.2)); +} + +.service-card h3 { + font-size: 1.6rem; + margin-bottom: 16px; + color: var(--secondary); +} + +.service-card p { + color: var(--text-muted); + font-size: 1.05rem; + line-height: 1.7; +} + +/* References Section */ +.references-grid { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); + gap: 30px; + text-align: center; +} + +.ref-item { + background: rgba(255, 255, 255, 0.02); + padding: 40px 20px; + border-radius: 16px; + color: var(--text-muted); + font-weight: 600; + font-size: 1.1rem; + display: flex; + align-items: center; + justify-content: center; + border: 1px solid rgba(255, 255, 255, 0.05); + transition: all 0.3s ease; +} + +.ref-item:hover { + background: rgba(255, 255, 255, 0.05); + border-color: rgba(255, 255, 255, 0.1); + color: var(--secondary); +} + +/* Contact Section */ +.contact-wrapper { + display: flex; + justify-content: center; + text-align: center; +} + +.contact-info { + background: linear-gradient(180deg, var(--bg-card), #0f1522); + padding: 80px 40px; + border-radius: 24px; + border: 1px solid rgba(255, 255, 255, 0.05); + max-width: 700px; + width: 100%; + box-shadow: 0 20px 60px rgba(0, 0, 0, 0.4); +} + +.contact-link { + display: inline-block; + font-size: 2.5rem; + color: var(--primary); + margin: 40px 0; + font-weight: 700; + transition: transform 0.3s ease; +} + +.contact-link:hover { + transform: scale(1.05); + text-shadow: 0 0 30px rgba(0, 242, 255, 0.4); +} + +.btn-primary { + background: var(--primary); + color: var(--bg-dark); + box-shadow: 0 4px 15px rgba(0, 242, 255, 0.3); + position: relative; + z-index: 1; + border: 1px solid transparent; +} + +.btn-primary:hover { + transform: translateY(-2px); + box-shadow: 0 6px 20px rgba(0, 242, 255, 0.5); + background: #fff; + /* White on hover for clean look */ + color: var(--bg-dark); +} + +.address { + color: var(--text-muted); + font-style: normal; + font-size: 1.1rem; + line-height: 1.8; +} + +/* Legal Pages (Datenschutz/Impressum) */ +.legal-content { + max-width: 800px; + margin: 0 auto; +} + +.legal-content h1 { + margin-bottom: 40px; + font-size: 3rem; +} + +.legal-content h2 { + text-align: left; + margin-top: 60px; + margin-bottom: 24px; + font-size: 2rem; + border-bottom: 1px solid rgba(255, 255, 255, 0.1); + padding-bottom: 10px; +} + +.legal-content h3 { + margin-top: 32px; + margin-bottom: 16px; + color: var(--secondary); + font-size: 1.4rem; +} + +.legal-content p, +.legal-content ul { + color: var(--text-muted); + margin-bottom: 16px; + font-size: 1.05rem; + line-height: 1.8; +} + +.legal-content ul { + padding-left: 20px; + list-style: disc; +} + +.legal-content li { + margin-bottom: 8px; +} + +/* Footer */ +footer { + padding: 80px 0 40px; + border-top: 1px solid rgba(255, 255, 255, 0.05); + margin-top: 80px; + background: #05080f; +} + +.footer-content { + display: flex; + flex-direction: column; + align-items: center; + gap: 24px; +} + +.footer-logo { + font-size: 1.8rem; + font-weight: 700; + color: var(--secondary); +} + +.footer-links { + display: flex; + gap: 30px; +} + +.footer-links a { + color: var(--text-muted); + font-size: 0.95rem; + transition: color 0.3s ease; +} + +.footer-links a:hover { + color: var(--primary); +} + +.copyright { + color: rgba(255, 255, 255, 0.2); + font-size: 0.85rem; + margin-top: 24px; +} + +/* Mobile Responsive */ +@media (max-width: 768px) { + .section { + padding: 60px 0; + } + + #header { + top: 0; + left: 0; + transform: none; + width: 100%; + max-width: none; + border-radius: 0; + border: none; + border-bottom: 1px solid rgba(255, 255, 255, 0.05); + background: rgba(10, 15, 28, 0.95); + } + + .nav-links { + position: fixed; + top: 70px; + /* Match header height */ + left: 0; + width: 100%; + background: var(--bg-dark); + flex-direction: column; + padding: 40px; + gap: 15px; + text-align: center; + transform: translateY(-100%); + transition: transform 0.3s cubic-bezier(0.4, 0, 0.2, 1); + z-index: 999; + border-bottom: 1px solid rgba(255, 255, 255, 0.05); + opacity: 0; + pointer-events: none; + height: auto; + justify-content: flex-start; + border-radius: 0; + } + + .nav-links a { + width: 100%; + display: block; + background: rgba(255, 255, 255, 0.03); + } + + .nav-links.active { + transform: translateY(0); + opacity: 1; + pointer-events: all; + } + + .nav-links a { + font-size: 1.5rem; + /* Larger touch targets */ + font-weight: 600; + } + + #hero h1 { + font-size: 3rem; + } + + .about-grid { + grid-template-columns: 1fr; + gap: 40px; + } + + .visual-box { + height: 300px; + } + + .contact-link { + font-size: 1.5rem; + word-break: break-all; + } +} + +/* Mobile Toggle Button */ +.mobile-toggle { + background: none; + border: none; + color: var(--text-main); + font-size: 1.8rem; + cursor: pointer; + display: none; + padding: 5px; + line-height: 1; +} + +@media (max-width: 768px) { + .mobile-toggle { + display: block; + } +} \ No newline at end of file