MBO-Tech-IT-Webseite/docs/superpowers/plans/2026-04-02-website-erweiter...

764 lines
26 KiB
Markdown

# Website-Erweiterung Implementation Plan
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
**Goal:** Zwei neue Service-Karten, eine DSGVO/GoBD/Paperless-Sektion und drei Spezialeffekte (Scroll-Reveal, Typewriter, Counter) zur bestehenden MBO-Tech-IT Next.js Website hinzufügen.
**Architecture:** Alle Effekte werden mit nativen Web-APIs (Intersection Observer, requestAnimationFrame) ohne externe Packages implementiert. Neue Komponenten folgen dem bestehenden Muster (Tailwind, dark theme, orange/blau Akzente). `"use client"` nur wo Browser-APIs benötigt werden.
**Tech Stack:** Next.js 14 (App Router), TypeScript, Tailwind CSS, Intersection Observer API
---
## Dateiübersicht
| Aktion | Datei | Zweck |
|--------|-------|-------|
| Create | `components/ScrollReveal.tsx` | Wiederverwendbarer Wrapper mit Intersection Observer |
| Create | `hooks/useTypewriter.ts` | Hook für Typewriter-Effekt |
| Create | `components/StatsBar.tsx` | Animierte Statistik-Leiste mit Counter |
| Create | `components/PaperlessSection.tsx` | DSGVO & GoBD mit Paperless Sektion |
| Modify | `components/Services.tsx` | 2 neue Karten (WLAN, WebApps) + ScrollReveal |
| Modify | `components/Hero.tsx` | Typewriter-Effekt integrieren |
| Modify | `app/page.tsx` | StatsBar + PaperlessSection einbinden |
---
## Task 1: ScrollReveal-Komponente
**Files:**
- Create: `components/ScrollReveal.tsx`
- [ ] **Step 1: Komponente erstellen**
```tsx
// components/ScrollReveal.tsx
"use client";
import { useEffect, useRef, useState } from "react";
interface ScrollRevealProps {
children: React.ReactNode;
delay?: number;
className?: string;
}
export default function ScrollReveal({ children, delay = 0, className = "" }: ScrollRevealProps) {
const ref = useRef<HTMLDivElement>(null);
const [visible, setVisible] = useState(false);
useEffect(() => {
const el = ref.current;
if (!el) return;
const observer = new IntersectionObserver(
([entry]) => {
if (entry.isIntersecting) {
setVisible(true);
observer.disconnect();
}
},
{ threshold: 0.1 }
);
observer.observe(el);
return () => observer.disconnect();
}, []);
return (
<div
ref={ref}
className={className}
style={{
opacity: visible ? 1 : 0,
transform: visible ? "translateY(0)" : "translateY(24px)",
transition: `opacity 500ms ease-out ${delay}ms, transform 500ms ease-out ${delay}ms`,
}}
>
{children}
</div>
);
}
```
- [ ] **Step 2: Dev-Server starten und Datei prüfen**
```bash
npm run dev
```
Öffne http://localhost:3000 — Seite soll unverändert aussehen (Komponente noch nicht eingebunden).
- [ ] **Step 3: Commit**
```bash
git add components/ScrollReveal.tsx
git commit -m "feat: add ScrollReveal component with Intersection Observer"
```
---
## Task 2: useTypewriter Hook
**Files:**
- Create: `hooks/useTypewriter.ts`
- [ ] **Step 1: `hooks/` Ordner anlegen und Hook erstellen**
```bash
mkdir -p hooks
```
```ts
// hooks/useTypewriter.ts
"use client";
import { useEffect, useState } from "react";
export function useTypewriter(words: string[], typingSpeed = 80, deletingSpeed = 40, pauseMs = 2000) {
const [displayed, setDisplayed] = useState("");
const [wordIndex, setWordIndex] = useState(0);
const [isDeleting, setIsDeleting] = useState(false);
useEffect(() => {
const current = words[wordIndex % words.length];
const timeout = setTimeout(() => {
if (!isDeleting) {
setDisplayed(current.slice(0, displayed.length + 1));
if (displayed.length + 1 === current.length) {
setTimeout(() => setIsDeleting(true), pauseMs);
}
} else {
setDisplayed(current.slice(0, displayed.length - 1));
if (displayed.length - 1 === 0) {
setIsDeleting(false);
setWordIndex((i) => i + 1);
}
}
}, isDeleting ? deletingSpeed : typingSpeed);
return () => clearTimeout(timeout);
}, [displayed, isDeleting, wordIndex, words, typingSpeed, deletingSpeed, pauseMs]);
return displayed;
}
```
- [ ] **Step 2: Commit**
```bash
git add hooks/useTypewriter.ts
git commit -m "feat: add useTypewriter hook"
```
---
## Task 3: Hero — Typewriter-Effekt integrieren
**Files:**
- Modify: `components/Hero.tsx`
- [ ] **Step 1: Hero.tsx anpassen**
Ersetze die gesamte Datei `components/Hero.tsx` mit folgendem Inhalt:
```tsx
// components/Hero.tsx
"use client";
import { useTypewriter } from "@/hooks/useTypewriter";
export default function Hero() {
const typed = useTypewriter(["Professionell.", "DSGVO-konform.", "Zuverlässig.", "Skalierbar."]);
return (
<section className="relative min-h-screen flex items-center justify-center overflow-hidden">
{/* Background grid */}
<div className="absolute inset-0 bg-grid opacity-50" />
{/* Radial gradient glow */}
<div className="absolute inset-0 bg-[radial-gradient(ellipse_at_center,rgba(249,115,22,0.10)_0%,transparent_65%)]" />
{/* Floating orbs */}
<div className="absolute top-1/4 left-1/4 w-72 h-72 bg-orange-500/5 rounded-full blur-3xl animate-pulse-slow" />
<div className="absolute bottom-1/4 right-1/4 w-80 h-80 bg-blue-600/5 rounded-full blur-3xl animate-pulse-slow" />
<div className="relative z-10 max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 text-center">
{/* Tagline badge */}
<div className="inline-flex items-center gap-2 px-5 py-2 rounded-full border border-orange-500/40 bg-orange-500/10 text-orange-400 text-xs font-black tracking-[0.3em] uppercase mb-8">
<span className="w-1.5 h-1.5 bg-orange-400 rounded-full animate-pulse" />
Digital Denken. Lokal Handeln.
</div>
{/* Headline */}
<h1 className="text-5xl sm:text-6xl lg:text-7xl font-black text-white leading-tight mb-6 tracking-tight">
Ihre IT-Infrastruktur.{" "}
<span className="text-gradient">
{typed}
<span className="animate-pulse">|</span>
</span>
<br />
Skalierbar. Zuverlässig.
</h1>
{/* Subheadline */}
<p className="text-xl sm:text-2xl text-slate-400 max-w-3xl mx-auto mb-4 leading-relaxed">
Von Docker-Containern über Kubernetes-Cluster bis hin zu
Proxmox-Virtualisierung auf Hetzner Cloud &mdash; wir bringen Ihre
IT auf das nächste Level.
</p>
{/* Tech pills */}
<div className="flex flex-wrap items-center justify-center gap-3 mb-10">
{["Docker", "Kubernetes", "Proxmox", "Hetzner Cloud", "Linux"].map((tech) => (
<span
key={tech}
className="px-3 py-1 rounded-md bg-gray-900 border border-gray-700 text-slate-300 text-sm font-mono"
>
{tech}
</span>
))}
</div>
{/* CTAs */}
<div className="flex flex-col sm:flex-row items-center justify-center gap-4">
<a href="#contact" className="btn-primary w-full sm:w-auto px-8 py-4 text-lg">
Projekt anfragen
</a>
<a href="#services" className="btn-secondary w-full sm:w-auto px-8 py-4 text-lg">
Services ansehen
</a>
</div>
{/* Scroll indicator */}
<div className="absolute bottom-8 left-1/2 -translate-x-1/2 flex flex-col items-center gap-2 text-slate-600">
<span className="text-xs font-bold tracking-[0.3em] uppercase">Scroll</span>
<div className="w-px h-12 bg-gradient-to-b from-slate-600 to-transparent" />
</div>
</div>
</section>
);
}
```
- [ ] **Step 2: Im Browser prüfen**
Öffne http://localhost:3000 — der Hero-Text soll zwischen "Professionell.", "DSGVO-konform.", "Zuverlässig.", "Skalierbar." wechseln mit Cursor `|`.
- [ ] **Step 3: Commit**
```bash
git add components/Hero.tsx hooks/useTypewriter.ts
git commit -m "feat: add typewriter effect to Hero headline"
```
---
## Task 4: StatsBar — Animierte Statistiken
**Files:**
- Create: `components/StatsBar.tsx`
- [ ] **Step 1: Komponente erstellen**
```tsx
// components/StatsBar.tsx
"use client";
import { useEffect, useRef, useState } from "react";
const stats = [
{ value: 30, suffix: "+", label: "Jahre IT-Erfahrung", accent: "orange" },
{ value: 99, suffix: "%", label: "Server-Uptime", accent: "blue" },
{ value: 50, suffix: "+", label: "Abgeschlossene Projekte", accent: "orange" },
{ value: 24, suffix: "h", label: "Support-Reaktionszeit", accent: "blue" },
];
function Counter({ value, suffix, accent }: { value: number; suffix: string; accent: string }) {
const [count, setCount] = useState(0);
const ref = useRef<HTMLSpanElement>(null);
const started = useRef(false);
useEffect(() => {
const el = ref.current;
if (!el) return;
const observer = new IntersectionObserver(
([entry]) => {
if (entry.isIntersecting && !started.current) {
started.current = true;
const duration = 1500;
const start = performance.now();
const tick = (now: number) => {
const progress = Math.min((now - start) / duration, 1);
const eased = 1 - Math.pow(1 - progress, 3);
setCount(Math.floor(eased * value));
if (progress < 1) requestAnimationFrame(tick);
};
requestAnimationFrame(tick);
observer.disconnect();
}
},
{ threshold: 0.3 }
);
observer.observe(el);
return () => observer.disconnect();
}, [value]);
const color = accent === "orange" ? "text-orange-400" : "text-blue-400";
return (
<span ref={ref} className={`text-4xl sm:text-5xl font-black ${color}`}>
{count}{suffix}
</span>
);
}
export default function StatsBar() {
return (
<section className="py-12 px-4 sm:px-6 lg:px-8 relative">
<div className="absolute inset-0 bg-[#111925]" />
<div className="max-w-7xl mx-auto relative">
<div className="grid grid-cols-2 lg:grid-cols-4 gap-8">
{stats.map((stat) => (
<div key={stat.label} className="text-center">
<Counter value={stat.value} suffix={stat.suffix} accent={stat.accent} />
<p className="text-slate-500 text-sm mt-1">{stat.label}</p>
</div>
))}
</div>
</div>
</section>
);
}
```
- [ ] **Step 2: StatsBar in `app/page.tsx` einbinden**
Füge den Import und die Komponente in `app/page.tsx` ein. Die Datei soll danach so aussehen:
```tsx
// app/page.tsx
import Header from "@/components/Header";
import Hero from "@/components/Hero";
import TaglineBanner from "@/components/TaglineBanner";
import StatsBar from "@/components/StatsBar";
import Services from "@/components/Services";
import Technologies from "@/components/Technologies";
import DataSovereignty from "@/components/DataSovereignty";
import PaperlessSection from "@/components/PaperlessSection";
import About from "@/components/About";
import Contact from "@/components/Contact";
import Footer from "@/components/Footer";
export default function Home() {
return (
<main className="min-h-screen bg-[#18212f]">
<Header />
<Hero />
<TaglineBanner />
<StatsBar />
<Services />
<TaglineBanner />
<PaperlessSection />
<DataSovereignty />
<TaglineBanner />
<Technologies />
<About />
<TaglineBanner />
<Contact />
<Footer />
</main>
);
}
```
**Hinweis:** `PaperlessSection` existiert noch nicht — TypeScript wird einen Fehler werfen. Das ist normal, wir erstellen sie in Task 6.
- [ ] **Step 3: Im Browser prüfen**
Öffne http://localhost:3000 — nach dem Hero soll die dunkle StatsBar erscheinen. Beim Scrollen dazu zählen die Zahlen hoch.
- [ ] **Step 4: Commit**
```bash
git add components/StatsBar.tsx app/page.tsx
git commit -m "feat: add animated StatsBar with counter effect"
```
---
## Task 5: Services — 2 neue Karten + ScrollReveal
**Files:**
- Modify: `components/Services.tsx`
- [ ] **Step 1: `services`-Array in `Services.tsx` um 2 Einträge erweitern**
Füge am Ende des `services`-Arrays (nach dem Kubernetes-Eintrag, vor der schließenden `]`) folgende zwei Objekte ein:
```ts
{
icon: (
<svg viewBox="0 0 24 24" className="w-8 h-8" fill="currentColor">
<path d="M1 6l5 4-5 4V6zm7 0h14v2H8V6zm0 5h14v2H8v-2zm0 5h14v2H8v-2z" />
<path d="M5.828 7l-1.414 1.414L6.586 10.6 4.414 12.8l1.414 1.4L10 10.6 5.828 7z" opacity=".6"/>
<path d="M19 3H5a2 2 0 00-2 2v1h2V5h14v14H5v-1H3v1a2 2 0 002 2h14a2 2 0 002-2V5a2 2 0 00-2-2z"/>
<circle cx="4" cy="12" r="3"/>
<path d="M4 10.5A1.5 1.5 0 115.5 12 1.5 1.5 0 014 10.5z" fill="#18212f"/>
</svg>
),
title: "WLAN & Netzwerk",
description:
"Professionelle WLAN-Planung, Installation und Troubleshooting für Privat- und Gewerbekunden. Mesh-Netzwerke, Access Points und hartnäckige Netzwerkprobleme — auch in schwierigen Gebäuden.",
features: ["WLAN-Planung & Installation", "Mesh-Netzwerke", "Netzwerk-Troubleshooting", "Privat- & Gewerbekunden"],
accent: "orange",
},
{
icon: (
<svg viewBox="0 0 24 24" className="w-8 h-8" fill="currentColor">
<path d="M9.4 16.6L4.8 12l4.6-4.6L8 6l-6 6 6 6 1.4-1.4zm5.2 0l4.6-4.6-4.6-4.6L16 6l6 6-6 6-1.4-1.4z"/>
</svg>
),
title: "Individuelle Webanwendungen",
description:
"Maßgeschneiderte Web-Apps für spezielle Geschäftsanforderungen. Von Kundenportalen über interne Tools bis zu Buchungssystemen — entwickelt auf Ihre Prozesse zugeschnitten.",
features: ["Maßgeschneiderte Entwicklung", "Kundenportale & Tools", "API-Integrationen", "Moderner Tech-Stack"],
accent: "blue",
},
```
- [ ] **Step 2: ScrollReveal in die Karten-Schleife integrieren**
Füge am Anfang der Datei den Import hinzu:
```tsx
import ScrollReveal from "@/components/ScrollReveal";
```
Ändere dann die Karten-Schleife in der `return`-Anweisung von:
```tsx
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
{services.map((service) => {
const c = colorMap[service.accent as keyof typeof colorMap];
return (
<div
key={service.title}
className={`group p-6 rounded-2xl bg-gray-900 border ${c.border} transition-all duration-300 hover:-translate-y-1 hover:shadow-xl ${c.shadow}`}
>
```
zu:
```tsx
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
{services.map((service, index) => {
const c = colorMap[service.accent as keyof typeof colorMap];
return (
<ScrollReveal key={service.title} delay={index * 75}>
<div
className={`group p-6 rounded-2xl bg-gray-900 border ${c.border} transition-all duration-300 hover:-translate-y-1 hover:shadow-xl ${c.shadow}`}
>
```
Und die schließende `</div>` der Karte wird zu `</div></ScrollReveal>`. Die vollständige `return`-Schleife sieht dann so aus:
```tsx
{services.map((service, index) => {
const c = colorMap[service.accent as keyof typeof colorMap];
return (
<ScrollReveal key={service.title} delay={index * 75}>
<div
className={`group p-6 rounded-2xl bg-gray-900 border ${c.border} transition-all duration-300 hover:-translate-y-1 hover:shadow-xl ${c.shadow}`}
>
<div className={`w-14 h-14 rounded-xl ${c.iconBg} ${c.icon} flex items-center justify-center mb-5`}>
{service.icon}
</div>
<h3 className="text-xl font-bold text-white mb-3">{service.title}</h3>
<p className="text-slate-400 text-sm leading-relaxed mb-5">{service.description}</p>
<ul className="space-y-2">
{service.features.map((feature) => (
<li key={feature} className="flex items-center gap-2 text-sm text-slate-300">
<span className={`w-1.5 h-1.5 rounded-full ${c.dot} flex-shrink-0`} />
{feature}
</li>
))}
</ul>
</div>
</ScrollReveal>
);
})}
```
- [ ] **Step 3: Im Browser prüfen**
http://localhost:3000 → Services-Bereich soll 8 Karten zeigen, die beim Scrollen gestaffelt einfahren.
- [ ] **Step 4: Commit**
```bash
git add components/Services.tsx
git commit -m "feat: add WLAN and WebApps service cards with scroll-reveal"
```
---
## Task 6: PaperlessSection — DSGVO & GoBD
**Files:**
- Create: `components/PaperlessSection.tsx`
- [ ] **Step 1: Komponente erstellen**
```tsx
// components/PaperlessSection.tsx
import ScrollReveal from "@/components/ScrollReveal";
const requirements = [
{
accent: "orange",
title: "DSGVO-konforme Archivierung",
text: "Alle Dokumente bleiben auf Ihrer eigenen Infrastruktur — in Deutschland oder bei Hetzner. Kein Zugriff durch Drittanbieter, keine US-Cloud. Vollständig DSGVO-konform.",
},
{
accent: "blue",
title: "GoBD-Anforderungen erfüllt",
text: "Revisionssichere, unveränderliche Ablage steuerrelevanter Belege. Paperless-ngx protokolliert alle Änderungen und erfüllt die Anforderungen der GoBD an die digitale Buchführung.",
},
{
accent: "orange",
title: "Selbstgehostet & unter Kontrolle",
text: "Betrieb auf Ihrem eigenen Server oder auf einem deutschen Hetzner-VPS. Sie haben die volle Kontrolle über Ihre Daten — heute, morgen und in 10 Jahren.",
},
];
const services = [
"Installation & Konfiguration von Paperless-ngx",
"Einrichtung automatischer Dokumentenerkennung (OCR)",
"Migration bestehender Dokumentenarchive",
"Schulung & Dokumentation für Ihr Team",
];
const colorMap = {
orange: {
border: "border-orange-500/20 hover:border-orange-500/50",
dot: "bg-orange-400",
dotBg: "bg-orange-500/10",
},
blue: {
border: "border-blue-500/20 hover:border-blue-500/50",
dot: "bg-blue-400",
dotBg: "bg-blue-500/10",
},
};
export default function PaperlessSection() {
return (
<section id="paperless" className="py-24 px-4 sm:px-6 lg:px-8 relative">
<div className="absolute inset-0 bg-[#111925]" />
<div className="absolute inset-0 bg-grid opacity-20" />
<div className="absolute inset-0 bg-[radial-gradient(ellipse_at_top_right,rgba(34,197,94,0.04)_0%,transparent_60%)]" />
<div className="max-w-7xl mx-auto relative">
{/* Header */}
<ScrollReveal>
<div className="text-center mb-16">
<span className="text-orange-400 font-mono text-xs font-bold tracking-[0.25em] uppercase">
Compliance & Dokumentenmanagement
</span>
<h2 className="text-4xl sm:text-5xl font-black text-white mt-3 mb-4">
DSGVO & GoBD mit{" "}
<span className="text-gradient-orange">Paperless-ngx</span>
</h2>
<p className="text-slate-400 text-lg max-w-2xl mx-auto">
Digitale Dokumentenverwaltung, die rechtssicher ist DSGVO-konform,
GoBD-tauglich, selbstgehostet. Kein Abo, keine US-Cloud, volle Kontrolle.
</p>
</div>
</ScrollReveal>
{/* What is Paperless */}
<ScrollReveal delay={100}>
<div className="mb-12 p-6 rounded-2xl bg-gray-900 border border-orange-500/20 flex flex-col md:flex-row gap-6 items-start">
<div className="flex-shrink-0 w-14 h-14 rounded-xl bg-orange-500/10 text-orange-400 flex items-center justify-center">
<svg className="w-7 h-7" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z" />
</svg>
</div>
<div>
<h3 className="text-white font-bold text-lg mb-2">Was ist Paperless-ngx?</h3>
<p className="text-slate-400 text-sm leading-relaxed">
Paperless-ngx ist ein Open-Source Dokumentenmanagementsystem (DMS), das Ihre Papierflut digitalisiert
und durchsuchbar macht. Rechnungen, Verträge, Briefe automatisch per OCR erkannt, kategorisiert und
archiviert. Betrieben auf Ihrer eigenen Infrastruktur, ohne Abhängigkeit von Cloud-Anbietern.
</p>
<div className="flex flex-wrap gap-2 mt-3">
{["Open Source", "Self-Hosted", "OCR", "Volltextsuche", "Automatische Tags"].map((tag) => (
<span key={tag} className="px-3 py-1 rounded-full bg-orange-500/10 border border-orange-500/20 text-orange-400 text-xs font-mono">
{tag}
</span>
))}
</div>
</div>
</div>
</ScrollReveal>
{/* Requirements grid */}
<div className="grid md:grid-cols-3 gap-6 mb-16">
{requirements.map((req, index) => {
const c = colorMap[req.accent as keyof typeof colorMap];
return (
<ScrollReveal key={req.title} delay={index * 100}>
<div className={`p-6 rounded-2xl bg-gray-900 border ${c.border} transition-all duration-300 h-full`}>
<div className={`w-2 h-2 rounded-full ${c.dot} mb-4`} />
<h3 className="text-white font-bold text-base mb-3">{req.title}</h3>
<p className="text-slate-400 text-sm leading-relaxed">{req.text}</p>
</div>
</ScrollReveal>
);
})}
</div>
{/* Divider */}
<div className="flex items-center gap-6 mb-12">
<div className="flex-1 h-px bg-gradient-to-r from-transparent via-gray-700 to-transparent" />
<div className="px-6 py-2 rounded-full border border-orange-500/40 bg-orange-500/5 text-orange-400 text-sm font-black tracking-wider whitespace-nowrap">
Unser Leistungsumfang
</div>
<div className="flex-1 h-px bg-gradient-to-r from-transparent via-gray-700 to-transparent" />
</div>
{/* Services list */}
<ScrollReveal delay={100}>
<div className="grid sm:grid-cols-2 gap-4 mb-16">
{services.map((item) => (
<div key={item} className="flex items-center gap-3 p-4 rounded-xl bg-gray-900 border border-gray-800">
<div className="w-5 h-5 rounded-full bg-orange-500 flex items-center justify-center flex-shrink-0">
<svg className="w-3 h-3 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={3} d="M5 13l4 4L19 7" />
</svg>
</div>
<span className="text-slate-300 text-sm">{item}</span>
</div>
))}
</div>
</ScrollReveal>
{/* CTA */}
<ScrollReveal delay={150}>
<div className="p-8 rounded-2xl border border-orange-500/30 bg-orange-500/5 text-center">
<p className="text-orange-400 font-black text-sm tracking-[0.2em] uppercase mb-2">
Compliance leicht gemacht
</p>
<p className="text-white text-xl font-bold mb-2">
DSGVO & GoBD ohne Kompromisse.
</p>
<p className="text-slate-400 text-sm max-w-xl mx-auto mb-6">
Wir richten Paperless-ngx auf Ihrer Infrastruktur ein, migrieren
Ihre bestehenden Dokumente und schulen Ihr Team. Rechtssicher,
selbstgehostet, dauerhaft unter Ihrer Kontrolle.
</p>
<a href="#contact" className="btn-primary inline-flex px-8 py-3 text-sm">
Jetzt Beratung anfragen
</a>
</div>
</ScrollReveal>
</div>
</section>
);
}
```
- [ ] **Step 2: Im Browser prüfen**
http://localhost:3000 → Zwischen Services und DataSovereignty soll die neue Paperless-Sektion erscheinen mit dunkelgrauem Hintergrund, 3 Anforderungskarten und CTA.
- [ ] **Step 3: Commit**
```bash
git add components/PaperlessSection.tsx
git commit -m "feat: add PaperlessSection with DSGVO/GoBD content"
```
---
## Task 7: page.tsx — PaperlessSection finalisieren
**Files:**
- Modify: `app/page.tsx`
Nach Task 4 wurde `PaperlessSection` bereits in `page.tsx` importiert. In Task 6 wurde die Komponente erstellt.
- [ ] **Step 1: Prüfen dass page.tsx korrekt ist**
`app/page.tsx` soll exakt so aussehen (wurde bereits in Task 4 geschrieben):
```tsx
import Header from "@/components/Header";
import Hero from "@/components/Hero";
import TaglineBanner from "@/components/TaglineBanner";
import StatsBar from "@/components/StatsBar";
import Services from "@/components/Services";
import Technologies from "@/components/Technologies";
import DataSovereignty from "@/components/DataSovereignty";
import PaperlessSection from "@/components/PaperlessSection";
import About from "@/components/About";
import Contact from "@/components/Contact";
import Footer from "@/components/Footer";
export default function Home() {
return (
<main className="min-h-screen bg-[#18212f]">
<Header />
<Hero />
<TaglineBanner />
<StatsBar />
<Services />
<TaglineBanner />
<PaperlessSection />
<DataSovereignty />
<TaglineBanner />
<Technologies />
<About />
<TaglineBanner />
<Contact />
<Footer />
</main>
);
}
```
Falls noch nicht so, jetzt anpassen.
- [ ] **Step 2: Finaler Check im Browser**
http://localhost:3000 — vollständige Seite prüfen:
- Hero: Typewriter läuft ✓
- StatsBar: Zahlen zählen hoch beim Scrollen ✓
- Services: 8 Karten, gleiten beim Scrollen ein ✓
- PaperlessSection: erscheint nach Services ✓
- Keine TypeScript/Console-Fehler ✓
- [ ] **Step 3: Finaler Commit**
```bash
git add app/page.tsx
git commit -m "feat: wire up all new sections in page layout"
```
---
## Self-Review Ergebnis
- **Spec-Abdeckung:** Alle 7 Anforderungen (2 Karten, 1 Sektion, 3 Effekte, page.tsx) haben Tasks ✓
- **Keine Platzhalter:** Alle Code-Blöcke sind vollständig ✓
- **Typ-Konsistenz:** `ScrollReveal` wird in Tasks 5 und 6 identisch verwendet ✓
- **useTypewriter:** Hook gibt `string` zurück, wird in Hero als `{typed}` eingesetzt ✓