Refactor and redesign law firm demo page with new layout

This commit is contained in:
2025-06-07 22:21:11 +02:00
parent 5e5237ab10
commit eb0dfff3a9
7 changed files with 237 additions and 134 deletions

View File

@@ -1,34 +1,23 @@
import type { Metadata } from "next";
import { Geist, Geist_Mono } from "next/font/google";
import "./globals.css"; import "./globals.css";
import {Inter} from "next/font/google";
import Navbar from "@/components/Navbar";
import Footer from "@/components/Footer";
const geistSans = Geist({ const inter = Inter({subsets: ["latin"]});
variable: "--font-geist-sans",
subsets: ["latin"],
});
const geistMono = Geist_Mono({ export const metadata = {
variable: "--font-geist-mono", title: "Kanzlei Mustermann",
subsets: ["latin"], description: "Kompetente Rechtsberatung in allen Lebenslagen",
});
export const metadata: Metadata = {
title: "Create Next App",
description: "Generated by create next app",
}; };
export default function RootLayout({ export default function RootLayout({children}: { children: React.ReactNode }) {
children, return (
}: Readonly<{ <html lang="de">
children: React.ReactNode; <body className={inter.className}>
}>) { <Navbar/>
return ( <main>{children}</main>
<html lang="en"> <Footer/>
<body </body>
className={`${geistSans.variable} ${geistMono.variable} antialiased`} </html>
> );
{children}
</body>
</html>
);
} }

View File

@@ -1,103 +1,128 @@
import Image from "next/image"; // app/page.tsx
'use client';
export default function Home() { import {motion} from 'framer-motion';
return ( import Link from 'next/link';
<div className="grid grid-rows-[20px_1fr_20px] items-center justify-items-center min-h-screen p-8 pb-20 gap-16 sm:p-20 font-[family-name:var(--font-geist-sans)]"> import Image from 'next/image';
<main className="flex flex-col gap-[32px] row-start-2 items-center sm:items-start">
<Image
className="dark:invert"
src="/next.svg"
alt="Next.js logo"
width={180}
height={38}
priority
/>
<ol className="list-inside list-decimal text-sm/6 text-center sm:text-left font-[family-name:var(--font-geist-mono)]">
<li className="mb-2 tracking-[-.01em]">
Get started by editing{" "}
<code className="bg-black/[.05] dark:bg-white/[.06] px-1 py-0.5 rounded font-[family-name:var(--font-geist-mono)] font-semibold">
app/page.tsx
</code>
.
</li>
<li className="tracking-[-.01em]">
Save and see your changes instantly.
</li>
</ol>
<div className="flex gap-4 items-center flex-col sm:flex-row"> export default function HomePage() {
<a return (
className="rounded-full border border-solid border-transparent transition-colors flex items-center justify-center bg-foreground text-background gap-2 hover:bg-[#383838] dark:hover:bg-[#ccc] font-medium text-sm sm:text-base h-10 sm:h-12 px-4 sm:px-5 sm:w-auto" <div className="flex flex-col min-h-screen">
href="https://vercel.com/new?utm_source=create-next-app&utm_medium=appdir-template-tw&utm_campaign=create-next-app" <motion.div
target="_blank" initial={{opacity: 0, y: 20}}
rel="noopener noreferrer" animate={{opacity: 1, y: 0}}
> transition={{duration: 0.6}}
<Image className="space-y-24 pt-32 pb-16 px-4 md:px-12 lg:px-24 bg-[#f9f9f9] text-gray-900"
className="dark:invert" >
src="/vercel.svg" {/* Hero Section mit Hintergrundbild */}
alt="Vercel logomark" <section className="relative text-center text-white h-[70vh] rounded-xl overflow-hidden shadow-lg">
width={20} <Image
height={20} src="/images/hero.jpeg"
/> alt="Anwaltskanzlei Hintergrund"
Deploy now fill
</a> className="object-cover brightness-[0.4]"
<a quality={90}
className="rounded-full border border-solid border-black/[.08] dark:border-white/[.145] transition-colors flex items-center justify-center hover:bg-[#f2f2f2] dark:hover:bg-[#1a1a1a] hover:border-transparent font-medium text-sm sm:text-base h-10 sm:h-12 px-4 sm:px-5 w-full sm:w-auto md:w-[158px]" />
href="https://nextjs.org/docs?utm_source=create-next-app&utm_medium=appdir-template-tw&utm_campaign=create-next-app" <div className="relative z-10 flex flex-col justify-center items-center h-full px-4">
target="_blank" <h1 className="text-4xl md:text-6xl font-bold mb-6">Ihre Kanzlei für Arbeits-, Familien- und
rel="noopener noreferrer" Vertragsrecht</h1>
> <p className="text-lg max-w-2xl text-gray-100">
Read our docs Persönliche Betreuung. Klare Kommunikation. Effektive Lösungen für Ihr Anliegen.
</a> </p>
<Link href="/kontakt">
<motion.button
whileHover={{scale: 1.05}}
whileTap={{scale: 0.95}}
className="mt-6 px-8 py-3 bg-blue-700 text-white rounded-xl shadow hover:bg-blue-800 transition"
>
Kontakt aufnehmen
</motion.button>
</Link>
</div>
</section>
{/* Divider */}
<div className="w-full h-[2px] bg-gray-300"/>
{/* Leistungen */}
<section>
<h2 className="text-3xl font-bold text-center mb-12">Unsere Schwerpunkte</h2>
<div className="grid md:grid-cols-3 gap-8">
{[
{
title: 'Arbeitsrecht',
desc: 'Kündigung, Abmahnung, Aufhebungsvertrag wir setzen Ihre Rechte durch.'
},
{
title: 'Familienrecht',
desc: 'Trennung, Scheidung, Unterhalt wir stehen Ihnen zur Seite.'
},
{
title: 'Vertragsrecht',
desc: 'Beratung & Gestaltung von Verträgen für Privatpersonen und Unternehmen.'
},
].map(({title, desc}) => (
<motion.div
key={title}
whileInView={{opacity: 1, y: 0}}
initial={{opacity: 0, y: 30}}
transition={{duration: 0.4}}
viewport={{once: true}}
className="bg-white p-6 rounded-xl shadow hover:shadow-md"
>
<h3 className="text-xl font-semibold mb-2">{title}</h3>
<p className="text-gray-600">{desc}</p>
</motion.div>
))}
</div>
</section>
{/* Divider */}
<div className="w-full h-[2px] bg-gray-300"/>
{/* Über die Kanzlei */}
<section className="max-w-4xl mx-auto text-center">
<h2 className="text-3xl font-bold mb-6">Über unsere Kanzlei</h2>
<p className="text-gray-700 text-lg">
Seit über 15 Jahren beraten und vertreten wir Mandantinnen und Mandanten aus ganz Deutschland.
Unsere Kanzlei steht für Kompetenz, Integrität und persönliche Betreuung. Wir nehmen uns Zeit
für Ihre Anliegen und entwickeln individuelle Strategien effizient und zielorientiert.
</p>
</section>
{/* Divider */}
<div className="w-full h-[2px] bg-gray-300"/>
{/* Vorteile */}
<section>
<h2 className="text-3xl font-bold text-center mb-10">Ihre Vorteile mit uns</h2>
<div className="grid md:grid-cols-3 gap-8 text-center">
{[
'Direkte & ehrliche Kommunikation',
'Schnelle Terminvergabe',
'Fachanwälte mit jahrelanger Erfahrung',
].map((vorteil) => (
<div key={vorteil} className="bg-white p-6 rounded-xl shadow">
<p className="text-gray-800 font-medium">{vorteil}</p>
</div>
))}
</div>
</section>
{/* Divider */}
<div className="w-full h-[2px] bg-gray-300"/>
{/* Call to Action */}
<section className="text-center">
<h2 className="text-2xl font-bold mb-4">Vereinbaren Sie jetzt ein unverbindliches Erstgespräch</h2>
<Link href="/kontakt">
<button
className="px-8 py-3 bg-blue-700 text-white rounded-xl hover:bg-blue-800 transition shadow">
Jetzt Termin sichern
</button>
</Link>
</section>
</motion.div>
</div> </div>
</main> );
<footer className="row-start-3 flex gap-[24px] flex-wrap items-center justify-center">
<a
className="flex items-center gap-2 hover:underline hover:underline-offset-4"
href="https://nextjs.org/learn?utm_source=create-next-app&utm_medium=appdir-template-tw&utm_campaign=create-next-app"
target="_blank"
rel="noopener noreferrer"
>
<Image
aria-hidden
src="/file.svg"
alt="File icon"
width={16}
height={16}
/>
Learn
</a>
<a
className="flex items-center gap-2 hover:underline hover:underline-offset-4"
href="https://vercel.com/templates?framework=next.js&utm_source=create-next-app&utm_medium=appdir-template-tw&utm_campaign=create-next-app"
target="_blank"
rel="noopener noreferrer"
>
<Image
aria-hidden
src="/window.svg"
alt="Window icon"
width={16}
height={16}
/>
Examples
</a>
<a
className="flex items-center gap-2 hover:underline hover:underline-offset-4"
href="https://nextjs.org?utm_source=create-next-app&utm_medium=appdir-template-tw&utm_campaign=create-next-app"
target="_blank"
rel="noopener noreferrer"
>
<Image
aria-hidden
src="/globe.svg"
alt="Globe icon"
width={16}
height={16}
/>
Go to nextjs.org
</a>
</footer>
</div>
);
} }

View File

@@ -0,0 +1,18 @@
import Link from 'next/link';
export default function Footer() {
return (
<footer
className="bg-white mt-auto py-10 px-6 md:px-12 lg:px-24 text-sm text-gray-600 border-t border-gray-200">
<div className="flex flex-col md:flex-row justify-between items-center gap-4">
<div>
<p>&copy; {new Date().getFullYear()} Kanzlei Mustermann. Alle Rechte vorbehalten.</p>
</div>
<div className="space-x-4">
<Link href="/impressum" className="hover:underline">Impressum</Link>
<Link href="/datenschutz" className="hover:underline">Datenschutz</Link>
</div>
</div>
</footer>
);
}

View File

@@ -0,0 +1,27 @@
'use client';
import Link from 'next/link';
import {motion} from 'framer-motion';
export default function Navbar() {
return (
<motion.nav
initial={{y: -50, opacity: 0}}
animate={{y: 0, opacity: 1}}
transition={{duration: 0.5}}
className="fixed top-0 left-0 right-0 z-50 bg-white shadow-md py-4 px-6 md:px-12 lg:px-24 text-gray-900"
>
<div className="flex justify-between items-center">
<Link href="/">
<span className="text-xl font-bold text-blue-800">Kanzlei Mustermann</span>
</Link>
<div className="space-x-6 text-sm md:text-base">
<Link href="/">Start</Link>
<Link href="/ueber-uns">Über uns</Link>
<Link href="/impressum">Impressum</Link>
<Link href="/datenschutz">Datenschutz</Link>
</div>
</div>
</motion.nav>
);
}

View File

@@ -8,6 +8,7 @@
"name": "demo-1", "name": "demo-1",
"version": "0.1.0", "version": "0.1.0",
"dependencies": { "dependencies": {
"framer-motion": "^12.16.0",
"next": "15.3.3", "next": "15.3.3",
"react": "^19.0.0", "react": "^19.0.0",
"react-dom": "^19.0.0" "react-dom": "^19.0.0"
@@ -3306,6 +3307,33 @@
"url": "https://github.com/sponsors/ljharb" "url": "https://github.com/sponsors/ljharb"
} }
}, },
"node_modules/framer-motion": {
"version": "12.16.0",
"resolved": "https://registry.npmjs.org/framer-motion/-/framer-motion-12.16.0.tgz",
"integrity": "sha512-xryrmD4jSBQrS2IkMdcTmiS4aSKckbS7kLDCuhUn9110SQKG1w3zlq1RTqCblewg+ZYe+m3sdtzQA6cRwo5g8Q==",
"license": "MIT",
"dependencies": {
"motion-dom": "^12.16.0",
"motion-utils": "^12.12.1",
"tslib": "^2.4.0"
},
"peerDependencies": {
"@emotion/is-prop-valid": "*",
"react": "^18.0.0 || ^19.0.0",
"react-dom": "^18.0.0 || ^19.0.0"
},
"peerDependenciesMeta": {
"@emotion/is-prop-valid": {
"optional": true
},
"react": {
"optional": true
},
"react-dom": {
"optional": true
}
}
},
"node_modules/function-bind": { "node_modules/function-bind": {
"version": "1.1.2", "version": "1.1.2",
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
@@ -4578,6 +4606,21 @@
"url": "https://github.com/sponsors/isaacs" "url": "https://github.com/sponsors/isaacs"
} }
}, },
"node_modules/motion-dom": {
"version": "12.16.0",
"resolved": "https://registry.npmjs.org/motion-dom/-/motion-dom-12.16.0.tgz",
"integrity": "sha512-Z2nGwWrrdH4egLEtgYMCEN4V2qQt1qxlKy/uV7w691ztyA41Q5Rbn0KNGbsNVDZr9E8PD2IOQ3hSccRnB6xWzw==",
"license": "MIT",
"dependencies": {
"motion-utils": "^12.12.1"
}
},
"node_modules/motion-utils": {
"version": "12.12.1",
"resolved": "https://registry.npmjs.org/motion-utils/-/motion-utils-12.12.1.tgz",
"integrity": "sha512-f9qiqUHm7hWSLlNW8gS9pisnsN7CRFRD58vNjptKdsqFLpkVnX00TNeD6Q0d27V9KzT7ySFyK1TZ/DShfVOv6w==",
"license": "MIT"
},
"node_modules/ms": { "node_modules/ms": {
"version": "2.1.3", "version": "2.1.3",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",

View File

@@ -9,19 +9,20 @@
"lint": "next lint" "lint": "next lint"
}, },
"dependencies": { "dependencies": {
"framer-motion": "^12.16.0",
"next": "15.3.3",
"react": "^19.0.0", "react": "^19.0.0",
"react-dom": "^19.0.0", "react-dom": "^19.0.0"
"next": "15.3.3"
}, },
"devDependencies": { "devDependencies": {
"typescript": "^5", "@eslint/eslintrc": "^3",
"@tailwindcss/postcss": "^4",
"@types/node": "^20", "@types/node": "^20",
"@types/react": "^19", "@types/react": "^19",
"@types/react-dom": "^19", "@types/react-dom": "^19",
"@tailwindcss/postcss": "^4",
"tailwindcss": "^4",
"eslint": "^9", "eslint": "^9",
"eslint-config-next": "15.3.3", "eslint-config-next": "15.3.3",
"@eslint/eslintrc": "^3" "tailwindcss": "^4",
"typescript": "^5"
} }
} }

Binary file not shown.

After

Width:  |  Height:  |  Size: 350 KiB