first commit
This commit is contained in:
@@ -0,0 +1,97 @@
|
||||
'use client'
|
||||
|
||||
import { signOut } from 'next-auth/react'
|
||||
import Link from 'next/link'
|
||||
import { usePathname } from 'next/navigation'
|
||||
import { LayoutDashboard, Users, Settings, LogOut, Menu, X } from 'lucide-react'
|
||||
import { useState } from 'react'
|
||||
|
||||
export default function AdminLayout({ children }: { children: React.ReactNode }) {
|
||||
const pathname = usePathname()
|
||||
const [sidebarOpen, setSidebarOpen] = useState(false)
|
||||
|
||||
const navigation = [
|
||||
{ name: 'Dashboard', href: '/admin', icon: LayoutDashboard },
|
||||
{ name: 'Kullanıcılar', href: '/admin/users', icon: Users },
|
||||
{ name: 'Ayarlar', href: '/admin/settings', icon: Settings },
|
||||
]
|
||||
|
||||
return (
|
||||
<div className="min-h-screen bg-gray-50 dark:bg-gray-900 flex">
|
||||
{/* Mobile sidebar backdrop */}
|
||||
{sidebarOpen && (
|
||||
<div
|
||||
className="fixed inset-0 z-40 bg-gray-900/80 lg:hidden"
|
||||
onClick={() => setSidebarOpen(false)}
|
||||
/>
|
||||
)}
|
||||
|
||||
{/* Sidebar */}
|
||||
<div className={`
|
||||
fixed inset-y-0 left-0 z-50 w-64 bg-white dark:bg-gray-950 border-r border-gray-200 dark:border-gray-800
|
||||
transform transition-transform duration-200 ease-in-out lg:translate-x-0 lg:static lg:inset-0
|
||||
${sidebarOpen ? 'translate-x-0' : '-translate-x-full'}
|
||||
`}>
|
||||
<div className="h-full flex flex-col">
|
||||
<div className="h-16 flex items-center px-6 border-b border-gray-200 dark:border-gray-800">
|
||||
<h1 className="text-lg font-bold text-gray-900 dark:text-white">Admin Paneli</h1>
|
||||
<button
|
||||
className="ml-auto lg:hidden text-gray-500"
|
||||
onClick={() => setSidebarOpen(false)}
|
||||
>
|
||||
<X className="h-5 w-5" />
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<nav className="flex-1 px-4 py-6 space-y-1 overflow-y-auto">
|
||||
{navigation.map((item) => {
|
||||
const isActive = pathname.endsWith(item.href)
|
||||
return (
|
||||
<Link
|
||||
key={item.name}
|
||||
href={item.href}
|
||||
className={`
|
||||
flex items-center px-3 py-2.5 text-sm font-medium rounded-md transition-colors
|
||||
${isActive
|
||||
? 'bg-gray-100 dark:bg-gray-800 text-gray-900 dark:text-white'
|
||||
: 'text-gray-600 dark:text-gray-400 hover:bg-gray-50 dark:hover:bg-gray-800 hover:text-gray-900 dark:hover:text-white'}
|
||||
`}
|
||||
>
|
||||
<item.icon className={`mr-3 flex-shrink-0 h-5 w-5 ${isActive ? 'text-gray-900 dark:text-white' : 'text-gray-400'}`} />
|
||||
{item.name}
|
||||
</Link>
|
||||
)
|
||||
})}
|
||||
</nav>
|
||||
|
||||
<div className="p-4 border-t border-gray-200 dark:border-gray-800">
|
||||
<button
|
||||
onClick={() => signOut({ callbackUrl: '/' })}
|
||||
className="flex w-full items-center px-3 py-2.5 text-sm font-medium text-red-600 dark:text-red-400 rounded-md hover:bg-red-50 dark:hover:bg-red-950/30 transition-colors"
|
||||
>
|
||||
<LogOut className="mr-3 h-5 w-5" />
|
||||
Çıkış Yap
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Main content */}
|
||||
<div className="flex-1 flex flex-col min-w-0 overflow-hidden">
|
||||
<header className="h-16 flex items-center lg:hidden bg-white dark:bg-gray-950 border-b border-gray-200 dark:border-gray-800 px-4">
|
||||
<button
|
||||
onClick={() => setSidebarOpen(true)}
|
||||
className="text-gray-500 hover:text-gray-900 dark:hover:text-white focus:outline-none"
|
||||
>
|
||||
<Menu className="h-6 w-6" />
|
||||
</button>
|
||||
<span className="ml-4 text-lg font-bold text-gray-900 dark:text-white">Admin Paneli</span>
|
||||
</header>
|
||||
|
||||
<main className="flex-1 overflow-y-auto p-4 sm:p-6 lg:p-8">
|
||||
{children}
|
||||
</main>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
import { auth } from '@/lib/auth'
|
||||
|
||||
export default async function AdminDashboardPage() {
|
||||
const session = await auth()
|
||||
|
||||
return (
|
||||
<div className="space-y-6">
|
||||
<div>
|
||||
<h2 className="text-2xl font-bold tracking-tight text-gray-900 dark:text-white">Dashboard</h2>
|
||||
<p className="text-gray-500 dark:text-gray-400 mt-2">
|
||||
Hoş geldiniz, {session?.user?.name || session?.user?.email}. İşte projenizin genel görünümü.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-4">
|
||||
{/* Placeholder Stat Cards */}
|
||||
{[
|
||||
{ name: 'Toplam Kullanıcı', stat: '1,245' },
|
||||
{ name: 'Aktif Oturumlar', stat: '42' },
|
||||
{ name: 'Yeni Kayıtlar', stat: '8' },
|
||||
{ name: 'Sistem Durumu', stat: 'Online' },
|
||||
].map((item) => (
|
||||
<div
|
||||
key={item.name}
|
||||
className="overflow-hidden rounded-lg bg-white dark:bg-gray-950 border border-gray-200 dark:border-gray-800 px-4 py-5 shadow-sm sm:p-6"
|
||||
>
|
||||
<dt className="truncate text-sm font-medium text-gray-500 dark:text-gray-400">{item.name}</dt>
|
||||
<dd className="mt-1 text-3xl font-semibold tracking-tight text-gray-900 dark:text-white">
|
||||
{item.stat}
|
||||
</dd>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
<div className="rounded-lg bg-white dark:bg-gray-950 border border-gray-200 dark:border-gray-800 shadow-sm">
|
||||
<div className="p-6">
|
||||
<h3 className="text-lg font-medium text-gray-900 dark:text-white">Son Aktiviteler</h3>
|
||||
<div className="mt-4 border-t border-gray-100 dark:border-gray-800">
|
||||
<div className="py-4 text-sm text-gray-500">
|
||||
Henüz aktivite kaydı bulunmuyor.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
import type { Metadata } from "next";
|
||||
import { Archivo } from "next/font/google";
|
||||
import { NextIntlClientProvider } from 'next-intl';
|
||||
import { getMessages, setRequestLocale } from 'next-intl/server';
|
||||
import { notFound } from 'next/navigation';
|
||||
import { routing } from '@/i18n/routing';
|
||||
import "../globals.css";
|
||||
|
||||
const archivo = Archivo({
|
||||
subsets: ["latin"],
|
||||
variable: "--font-archivo",
|
||||
display: "swap",
|
||||
});
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: {
|
||||
default: "AyrisLegal — Hukuki Düşünce Ortağınız",
|
||||
template: "%s | AyrisLegal",
|
||||
},
|
||||
description:
|
||||
"AyrisLegal, solo ve küçük büro avukatları için yapay zeka destekli hukuki asistanıdır. Dosya analizi, çok turlu hukuki sohbet ve emsal karar arama tek bir platformda.",
|
||||
keywords: ["avukat yazılımı", "hukuki yapay zeka", "emsal karar arama", "hukuk ofisi yönetim", "AyrisLegal"],
|
||||
authors: [{ name: "ayris.tech", url: "https://ayris.tech" }],
|
||||
creator: "ayris.tech",
|
||||
openGraph: {
|
||||
type: "website",
|
||||
locale: "tr_TR",
|
||||
siteName: "AyrisLegal",
|
||||
title: "AyrisLegal — Hukuki Düşünce Ortağınız",
|
||||
description:
|
||||
"Pasif araştırma değil, aktif düşünce ortağı. Avukatlar için yapay zeka destekli hukuki asistan.",
|
||||
},
|
||||
twitter: {
|
||||
card: "summary_large_image",
|
||||
title: "AyrisLegal — Hukuki Düşünce Ortağınız",
|
||||
description:
|
||||
"Pasif araştırma değil, aktif düşünce ortağı. Avukatlar için yapay zeka destekli hukuki asistan.",
|
||||
},
|
||||
robots: {
|
||||
index: true,
|
||||
follow: true,
|
||||
},
|
||||
};
|
||||
|
||||
export function generateStaticParams() {
|
||||
return routing.locales.map((locale) => ({locale}));
|
||||
}
|
||||
|
||||
export default async function RootLayout({
|
||||
children,
|
||||
params
|
||||
}: Readonly<{
|
||||
children: React.ReactNode;
|
||||
params: Promise<{ locale: string }>;
|
||||
}>) {
|
||||
const { locale } = await params;
|
||||
|
||||
if (!routing.locales.includes(locale as any)) {
|
||||
notFound();
|
||||
}
|
||||
|
||||
setRequestLocale(locale);
|
||||
const messages = await getMessages();
|
||||
|
||||
return (
|
||||
<html
|
||||
lang={locale}
|
||||
className={`${archivo.variable} h-full antialiased`}
|
||||
>
|
||||
<body className="min-h-full flex flex-col" suppressHydrationWarning>
|
||||
<NextIntlClientProvider messages={messages}>
|
||||
{children}
|
||||
</NextIntlClientProvider>
|
||||
</body>
|
||||
</html>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
'use client'
|
||||
|
||||
import { useState } from 'react'
|
||||
import { signIn } from 'next-auth/react'
|
||||
import { useRouter } from 'next/navigation'
|
||||
|
||||
export default function LoginPage() {
|
||||
const router = useRouter()
|
||||
const [email, setEmail] = useState('')
|
||||
const [password, setPassword] = useState('')
|
||||
const [error, setError] = useState('')
|
||||
const [loading, setLoading] = useState(false)
|
||||
|
||||
const handleSubmit = async (e: React.FormEvent) => {
|
||||
e.preventDefault()
|
||||
setLoading(true)
|
||||
setError('')
|
||||
|
||||
const result = await signIn('credentials', {
|
||||
redirect: false,
|
||||
email,
|
||||
password,
|
||||
})
|
||||
|
||||
if (result?.error) {
|
||||
setError('Geçersiz e-posta veya şifre')
|
||||
setLoading(false)
|
||||
} else {
|
||||
router.push('/admin')
|
||||
router.refresh()
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="min-h-screen flex items-center justify-center bg-gray-50 dark:bg-gray-900 px-4">
|
||||
<div className="w-full max-w-md bg-white dark:bg-gray-800 rounded-xl shadow-lg border border-gray-100 dark:border-gray-800 overflow-hidden">
|
||||
<div className="p-8">
|
||||
<div className="text-center mb-8">
|
||||
<h1 className="text-2xl font-bold text-gray-900 dark:text-white">Admin Girişi</h1>
|
||||
<p className="text-sm text-gray-500 mt-2">Yönetim paneline erişmek için giriş yapın</p>
|
||||
</div>
|
||||
|
||||
{error && (
|
||||
<div className="bg-red-50 text-red-600 p-3 rounded-md text-sm mb-6 border border-red-100">
|
||||
{error}
|
||||
</div>
|
||||
)}
|
||||
|
||||
<form onSubmit={handleSubmit} className="space-y-5">
|
||||
<div>
|
||||
<label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1" htmlFor="email">
|
||||
E-posta
|
||||
</label>
|
||||
<input
|
||||
id="email"
|
||||
type="email"
|
||||
value={email}
|
||||
onChange={(e) => setEmail(e.target.value)}
|
||||
required
|
||||
className="w-full px-4 py-2 border border-gray-300 dark:border-gray-700 rounded-md focus:ring-2 focus:ring-blue-500 focus:border-blue-500 bg-white dark:bg-gray-900 text-gray-900 dark:text-white transition-colors"
|
||||
placeholder="admin@ayris.tech"
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1" htmlFor="password">
|
||||
Şifre
|
||||
</label>
|
||||
<input
|
||||
id="password"
|
||||
type="password"
|
||||
value={password}
|
||||
onChange={(e) => setPassword(e.target.value)}
|
||||
required
|
||||
className="w-full px-4 py-2 border border-gray-300 dark:border-gray-700 rounded-md focus:ring-2 focus:ring-blue-500 focus:border-blue-500 bg-white dark:bg-gray-900 text-gray-900 dark:text-white transition-colors"
|
||||
placeholder="••••••••"
|
||||
/>
|
||||
</div>
|
||||
<button
|
||||
type="submit"
|
||||
disabled={loading}
|
||||
className="w-full bg-blue-600 hover:bg-blue-700 text-white font-medium py-2.5 px-4 rounded-md transition-colors disabled:opacity-70 disabled:cursor-not-allowed"
|
||||
>
|
||||
{loading ? 'Giriş yapılıyor...' : 'Giriş Yap'}
|
||||
</button>
|
||||
</form>
|
||||
|
||||
<div className="mt-6 text-center text-xs text-gray-400">
|
||||
Demo credentials: admin@ayris.tech / admin
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,513 @@
|
||||
'use client'
|
||||
|
||||
import { useRef, useState } from 'react'
|
||||
import Link from 'next/link'
|
||||
import { motion, useInView } from 'framer-motion'
|
||||
import ContactForm from '@/components/contact-form'
|
||||
|
||||
/* ─── Design system tokens (Classical) ────────────────────────────────── */
|
||||
const T = {
|
||||
bg: '#f3f2f2',
|
||||
surface: '#eae9e9',
|
||||
text: '#201f1d',
|
||||
divider: 'rgba(32,31,29,0.16)',
|
||||
accent: '#b68235',
|
||||
accentDark: '#7d5411',
|
||||
neutral100: '#f8f4f4',
|
||||
fontHead: '"Sora", sans-serif',
|
||||
fontBody: '"Inter", sans-serif',
|
||||
radiusMd: '4px',
|
||||
radiusLg: '7px',
|
||||
shadowSm: '0 1px 2px rgba(45,43,43,0.14)',
|
||||
shadowMd: '0 3px 10px rgba(45,43,43,0.16)',
|
||||
}
|
||||
|
||||
/* ─── Reveal animation ─────────────────────────────────────────────────── */
|
||||
function Reveal({ children, className = '', delay = 0 }: {
|
||||
children: React.ReactNode; className?: string; delay?: number
|
||||
}) {
|
||||
const ref = useRef<HTMLDivElement>(null)
|
||||
const inView = useInView(ref, { once: true, margin: '-80px' })
|
||||
return (
|
||||
<motion.div
|
||||
ref={ref}
|
||||
initial={{ opacity: 0, y: 28 }}
|
||||
animate={inView ? { opacity: 1, y: 0 } : { opacity: 0, y: 28 }}
|
||||
transition={{ duration: 0.7, ease: [0.25, 0.46, 0.45, 0.94], delay }}
|
||||
className={className}
|
||||
>
|
||||
{children}
|
||||
</motion.div>
|
||||
)
|
||||
}
|
||||
|
||||
/* ─── Rail nav ──────────────────────────────────────────────────────────── */
|
||||
const RAIL_ITEMS = [
|
||||
{ id: '02', href: '#is-akisi', label: '02' },
|
||||
{ id: '03', href: '#farklilasim', label: '03' },
|
||||
{ id: '04', href: '#ozellikler', label: '04' },
|
||||
{ id: '05', href: '#fiyatlandirma', label: '05' },
|
||||
{ id: '06', href: '#guven', label: '06' },
|
||||
{ id: '07', href: '#iletisim', label: '07' },
|
||||
]
|
||||
|
||||
/* ─── Component ─────────────────────────────────────────────────────────── */
|
||||
export default function HomePage() {
|
||||
return (
|
||||
<div style={{ background: T.bg, color: T.text, fontFamily: T.fontBody, minHeight: '100vh', position: 'relative' }}>
|
||||
|
||||
{/* ── Inline fonts ── */}
|
||||
<style>{`
|
||||
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600&family=Sora:wght@300;400;500;600&display=swap');
|
||||
* { box-sizing: border-box; }
|
||||
body { margin: 0; }
|
||||
a { color: ${T.accent}; text-underline-offset: 3px; }
|
||||
:focus-visible { outline: 2px solid ${T.accent}; outline-offset: 2px; }
|
||||
::selection { background: rgba(182,130,53,0.25); }
|
||||
.rail-link { text-decoration: none; writing-mode: vertical-rl; font-size: 11px; letter-spacing: 0.08em; transition: color .2s; font-family: ${T.fontHead}; }
|
||||
.hr-line { height: 1px; border: 0; background: ${T.divider}; margin: 0; }
|
||||
.plate { filter: sepia(0.22) saturate(0.82) contrast(1.05); box-sizing: border-box; border: 6px solid ${T.surface}; outline: 1px solid ${T.divider}; }
|
||||
.btn-primary { display: inline-flex; align-items: center; justify-content: center; gap: 6px; cursor: pointer; text-decoration: none; font-family: ${T.fontHead}; font-weight: 600; font-size: 14px; color: ${T.accent}; background: transparent; border: 1px solid ${T.accent}; padding: 9px 16px; border-radius: ${T.radiusMd}; transition: background .15s; }
|
||||
.btn-primary:hover { background: rgba(182,130,53,0.1); }
|
||||
.btn-ghost { display: inline-flex; align-items: center; justify-content: center; gap: 6px; cursor: pointer; text-decoration: none; font-family: ${T.fontHead}; font-weight: 600; font-size: 14px; color: ${T.accent}; background: transparent; border: none; padding: 9px 4px; border-radius: ${T.radiusMd}; transition: background .15s; }
|
||||
.btn-ghost:hover { background: rgba(182,130,53,0.08); }
|
||||
.btn-primary-lg { display: inline-flex; align-items: center; justify-content: center; gap: 6px; cursor: pointer; text-decoration: none; font-family: ${T.fontHead}; font-weight: 600; font-size: 15px; color: ${T.accent}; background: transparent; border: 1px solid ${T.accent}; padding: 13px 24px; border-radius: ${T.radiusMd}; transition: background .15s; width: 100%; }
|
||||
.btn-primary-lg:hover { background: rgba(182,130,53,0.1); }
|
||||
.card-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 20px; }
|
||||
.card { display: flex; flex-direction: column; gap: 9px; padding: 13.8px; border-radius: ${T.radiusMd}; background: transparent; border: 1px solid ${T.divider}; box-shadow: ${T.shadowSm}; }
|
||||
.card-kicker { font-size: 10px; letter-spacing: 0.1em; text-transform: uppercase; color: ${T.accent}; }
|
||||
.card-title { font-family: ${T.fontHead}; font-weight: 600; font-size: 17px; line-height: 1.2; margin: 0; }
|
||||
.card-body { margin: 0; font-size: 13px; opacity: 0.8; }
|
||||
.field > label { display: block; font-size: 12px; margin-bottom: 5px; color: rgba(32,31,29,0.7); }
|
||||
.legal-input { width: 100%; min-height: 36px; padding: 6px 10px; font-family: ${T.fontBody}; font-size: 14px; color: ${T.text}; background: transparent; border: 1px solid ${T.divider}; border-radius: ${T.radiusMd}; transition: border-color .15s; }
|
||||
.legal-input:hover { border-color: rgba(32,31,29,0.45); }
|
||||
.legal-input:focus { outline: none; border-color: ${T.accent}; }
|
||||
.tag-outline { display: inline-flex; align-items: center; font-size: 10.5px; letter-spacing: 0.02em; padding: 3px 10px; border-radius: 3px; border: 1px solid ${T.accent}; color: ${T.accent}; }
|
||||
@media (max-width: 900px) { .rail-fixed { display: none !important; } .hero-badges { display: none !important; } .card-grid { grid-template-columns: 1fr; } }
|
||||
@media (max-width: 700px) { .hero-two-col { grid-template-columns: 1fr !important; } .contact-two-col { grid-template-columns: 1fr !important; } }
|
||||
`}</style>
|
||||
|
||||
{/* ── Left rail ── */}
|
||||
<div
|
||||
className="rail-fixed"
|
||||
style={{ position: 'fixed', left: '22px', top: 0, bottom: 0, width: '26px', display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center', gap: '26px', zIndex: 20 }}
|
||||
>
|
||||
{RAIL_ITEMS.map(item => (
|
||||
<a key={item.id} href={item.href} className="rail-link" style={{ color: 'rgba(32,31,29,0.4)', fontWeight: 400 }}
|
||||
onMouseEnter={e => { e.currentTarget.style.color = T.accentDark; e.currentTarget.style.fontWeight = '600' }}
|
||||
onMouseLeave={e => { e.currentTarget.style.color = 'rgba(32,31,29,0.4)'; e.currentTarget.style.fontWeight = '400' }}
|
||||
>
|
||||
{item.label}
|
||||
</a>
|
||||
))}
|
||||
</div>
|
||||
|
||||
{/* ══════════════════════════════ NAV ═════════════════════════════ */}
|
||||
<nav style={{
|
||||
position: 'sticky', top: 0, zIndex: 30,
|
||||
display: 'flex', alignItems: 'center', justifyContent: 'space-between',
|
||||
flexWrap: 'wrap', gap: '16px',
|
||||
padding: '14px clamp(20px,6vw,64px)',
|
||||
borderBottom: `1px solid ${T.divider}`,
|
||||
background: T.bg,
|
||||
backdropFilter: 'blur(10px)',
|
||||
}}>
|
||||
<div style={{ display: 'flex', alignItems: 'center', gap: '10px' }}>
|
||||
<span style={{ fontFamily: T.fontHead, fontSize: '19px', textTransform: 'uppercase', display: 'flex', gap: '4px' }}>
|
||||
<span style={{ fontWeight: 400, letterSpacing: '0.22em' }}>AYRIS</span>
|
||||
<span style={{ fontWeight: 500, letterSpacing: '0.35em' }}>LEGAL</span>
|
||||
</span>
|
||||
</div>
|
||||
<div style={{ display: 'flex', alignItems: 'center', gap: '24px', flexWrap: 'wrap' }}>
|
||||
<a href="#farklilasim" style={{ color: 'inherit', textDecoration: 'none', fontSize: '14px', fontFamily: T.fontBody }}
|
||||
onMouseEnter={e => (e.currentTarget.style.color = T.accent)}
|
||||
onMouseLeave={e => (e.currentTarget.style.color = 'inherit')}
|
||||
>Farklılaşım</a>
|
||||
<a href="#ozellikler" style={{ color: 'inherit', textDecoration: 'none', fontSize: '14px', fontFamily: T.fontBody }}
|
||||
onMouseEnter={e => (e.currentTarget.style.color = T.accent)}
|
||||
onMouseLeave={e => (e.currentTarget.style.color = 'inherit')}
|
||||
>Özellikler</a>
|
||||
<a href="#fiyatlandirma" style={{ color: 'inherit', textDecoration: 'none', fontSize: '14px', fontFamily: T.fontBody }}
|
||||
onMouseEnter={e => (e.currentTarget.style.color = T.accent)}
|
||||
onMouseLeave={e => (e.currentTarget.style.color = 'inherit')}
|
||||
>Fiyatlandırma</a>
|
||||
<a href="#iletisim" className="btn-primary">Demo Talep Et</a>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
{/* ══════════════════════════════ HERO ════════════════════════════ */}
|
||||
<section style={{ maxWidth: '1240px', margin: '0 auto', padding: 'clamp(64px,11vw,132px) clamp(20px,6vw,72px) clamp(48px,7vw,80px)', position: 'relative', overflow: 'hidden' }}>
|
||||
<Reveal>
|
||||
<span style={{ display: 'inline-block', fontSize: '13px', letterSpacing: '0.1em', textTransform: 'uppercase', color: T.accentDark, borderBottom: `1px solid ${T.accent}`, paddingBottom: '4px', marginBottom: '26px' }}>
|
||||
Madde 01 — Değer Önermesi
|
||||
</span>
|
||||
</Reveal>
|
||||
<div className="hero-two-col" style={{ display: 'grid', gridTemplateColumns: 'minmax(0,7fr) minmax(0,5fr)', gap: '56px', alignItems: 'center' }}>
|
||||
<div>
|
||||
<Reveal delay={0.05}>
|
||||
<h1 style={{ fontFamily: T.fontHead, fontWeight: 400, fontSize: 'clamp(46px,7.4vw,96px)', lineHeight: 0.98, letterSpacing: '-0.015em', margin: 0, marginLeft: '-0.03em', marginBottom: '0' }}>
|
||||
<span style={{ display: 'block' }}>Dosyanızı okur,</span>
|
||||
<span style={{ display: 'block' }}>sizinle <em style={{ fontStyle: 'italic', color: T.accentDark }}>tartışır.</em></span>
|
||||
</h1>
|
||||
</Reveal>
|
||||
<Reveal delay={0.12}>
|
||||
<p style={{ fontSize: 'clamp(17px,1.7vw,20px)', lineHeight: 1.65, maxWidth: '52ch', margin: '30px 0 0', color: 'rgba(32,31,29,0.82)', fontFamily: T.fontBody }}>
|
||||
AyrisLegal, yüklediğiniz dava dosyasını analiz eden, içtihat bulan ve dilekçe taslağı çıkaran bir yapay zeka çalışma ortağı — pasif bir arama motoru değil, dosya üzerinde sizinle muhakeme eden bir meslektaş.
|
||||
</p>
|
||||
</Reveal>
|
||||
<Reveal delay={0.18}>
|
||||
<div style={{ display: 'flex', gap: '14px', flexWrap: 'wrap', marginTop: '36px', alignItems: 'center' }}>
|
||||
<a href="#iletisim" className="btn-primary" style={{ fontSize: '15px', padding: '13px 24px' }}>Demo Talep Et</a>
|
||||
<a href="#farklilasim" className="btn-ghost" style={{ fontSize: '15px' }}>Nasıl çalışır ↓</a>
|
||||
</div>
|
||||
<p style={{ fontSize: '13px', marginTop: '24px', color: 'rgba(32,31,29,0.6)', fontFamily: T.fontBody }}>
|
||||
Şu an erken erişim aşamasındayız — kurucu ekiple doğrudan görüşün.
|
||||
</p>
|
||||
</Reveal>
|
||||
</div>
|
||||
|
||||
{/* Hero right: mock UI badges + plate */}
|
||||
<div style={{ position: 'relative' }}>
|
||||
<div className="hero-badges" style={{ position: 'absolute', top: '-18px', right: '6px', zIndex: 2, background: T.bg, border: `1px solid ${T.divider}`, borderRadius: T.radiusMd, padding: '8px 14px', fontSize: '12.5px', boxShadow: T.shadowSm, transform: 'rotate(-2deg)', fontFamily: T.fontBody }}>
|
||||
İçtihat bulundu · 3 emsal
|
||||
</div>
|
||||
<div className="hero-badges" style={{ position: 'absolute', bottom: '-16px', left: '-14px', zIndex: 2, background: T.bg, border: `1px solid ${T.divider}`, borderRadius: T.radiusMd, padding: '8px 14px', fontSize: '12.5px', boxShadow: T.shadowSm, transform: 'rotate(2deg)', fontFamily: T.fontBody }}>
|
||||
Dilekçe taslağı hazır
|
||||
</div>
|
||||
{/* Placeholder plate */}
|
||||
<div className="plate" style={{ width: '100%', aspectRatio: '4/5', background: T.surface, display: 'flex', flexDirection: 'column', gap: '12px', padding: '24px', justifyContent: 'center' }}>
|
||||
{['Dava dosyası yüklendi', 'AI analiz ediyor…', 'Argüman değerlendirmesi', 'Emsal: Yargıtay 2024/1234', 'Dilekçe taslağı oluşturuldu'].map((step, i) => (
|
||||
<div key={i} style={{ padding: '10px 14px', borderRadius: T.radiusMd, background: T.bg, border: `1px solid ${T.divider}`, fontSize: '13px', color: i === 4 ? T.accentDark : 'rgba(32,31,29,0.75)', fontFamily: T.fontBody, display: 'flex', alignItems: 'center', gap: '10px' }}>
|
||||
<span style={{ width: '18px', height: '18px', borderRadius: '50%', background: i === 4 ? T.accent : T.divider, display: 'inline-flex', alignItems: 'center', justifyContent: 'center', fontSize: '10px', color: i === 4 ? '#fff' : 'rgba(32,31,29,0.5)', flexShrink: 0, fontFamily: T.fontHead }}>
|
||||
{i + 1}
|
||||
</span>
|
||||
{step}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* ══════════════════════════════ STATS ═══════════════════════════ */}
|
||||
<section style={{ maxWidth: '1240px', margin: '0 auto', padding: '0 clamp(20px,6vw,72px) clamp(56px,8vw,88px)', display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(180px,1fr))', borderTop: `1px solid ${T.divider}`, borderBottom: `1px solid ${T.divider}` }}>
|
||||
{[
|
||||
{ value: '01', label: 'Sabit fiyat, tüm avukatlara' },
|
||||
{ value: '40.000 TL', label: 'Yıllık, gizli ücret yok' },
|
||||
{ value: '%100', label: "Veri Türkiye'de kalır" },
|
||||
{ value: '7/24', label: 'Dosyanızla çalışan ortak' },
|
||||
].map((s, i, arr) => (
|
||||
<Reveal key={s.label} delay={i * 0.05}>
|
||||
<div style={{ padding: '28px 20px', borderRight: i < arr.length - 1 ? `1px solid ${T.divider}` : undefined, textAlign: 'center' }}>
|
||||
<div style={{ fontFamily: T.fontHead, fontWeight: 400, fontSize: 'clamp(30px,4vw,44px)', color: T.accentDark }}>{s.value}</div>
|
||||
<div style={{ fontSize: '13px', marginTop: '6px', color: 'rgba(32,31,29,0.65)', letterSpacing: '0.02em' }}>{s.label}</div>
|
||||
</div>
|
||||
</Reveal>
|
||||
))}
|
||||
</section>
|
||||
|
||||
{/* ══════════════════════════════ PROBLEM ═════════════════════════ */}
|
||||
<section id="is-akisi" style={{ maxWidth: '1240px', margin: '0 auto', padding: 'clamp(48px,8vw,96px) clamp(20px,6vw,72px)' }}>
|
||||
<Reveal>
|
||||
<span style={{ display: 'block', fontSize: '13px', letterSpacing: '0.08em', textTransform: 'uppercase', color: T.accentDark, marginBottom: '14px' }}>
|
||||
Madde 02 — Bugünün iş akışı
|
||||
</span>
|
||||
<h2 style={{ fontFamily: T.fontHead, fontWeight: 400, fontSize: 'clamp(30px,3.6vw,44px)', margin: '0 0 44px', letterSpacing: '-0.008em', maxWidth: '24ch' }}>
|
||||
Dosya, arama, şablon, tekrar.
|
||||
</h2>
|
||||
</Reveal>
|
||||
<div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit,minmax(280px,1fr))', gap: 0, borderTop: `1px solid ${T.divider}` }}>
|
||||
<Reveal delay={0.05}>
|
||||
<div style={{ padding: '32px 28px 32px 0', borderRight: `1px solid ${T.divider}` }}>
|
||||
<span style={{ fontFamily: T.fontHead, fontSize: '15px', color: 'rgba(32,31,29,0.45)' }}>01 / Bugün</span>
|
||||
<p style={{ fontSize: '15.5px', lineHeight: 1.7, margin: '14px 0 0', textAlign: 'justify', hyphens: 'auto', color: 'rgba(32,31,29,0.78)' } as React.CSSProperties}>
|
||||
Dosya incelemesi bir programda, içtihat araması ayrı bir siteye açılan sekmede, dilekçe taslağı eski bir Word şablonunda. Her adımda bağlam yeniden kurulur, saatler kaybolur.
|
||||
</p>
|
||||
</div>
|
||||
</Reveal>
|
||||
<Reveal delay={0.1}>
|
||||
<div style={{ padding: '32px 0 32px 28px' }}>
|
||||
<span style={{ fontFamily: T.fontHead, fontSize: '15px', color: T.accentDark }}>02 / AyrisLegal ile</span>
|
||||
<p style={{ fontSize: '15.5px', lineHeight: 1.7, margin: '14px 0 0', textAlign: 'justify', hyphens: 'auto', color: 'rgba(32,31,29,0.78)' } as React.CSSProperties}>
|
||||
Tek bir çalışma alanı: dosyanızı yükleyin, AyrisLegal ile tartışın, içtihat bulun, dilekçe taslağı üretin — hepsi aynı ekranda, bağlamı hiç kaybetmeden.
|
||||
</p>
|
||||
</div>
|
||||
</Reveal>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<hr className="hr-line" style={{ maxWidth: '1240px', margin: '0 auto' }} />
|
||||
|
||||
{/* ══════════════════════════════ DIFFERENTIATOR ══════════════════ */}
|
||||
<section id="farklilasim" style={{ maxWidth: '1240px', margin: '0 auto', padding: 'clamp(56px,9vw,108px) clamp(20px,6vw,72px)' }}>
|
||||
<Reveal>
|
||||
<span style={{ display: 'block', fontSize: '13px', letterSpacing: '0.08em', textTransform: 'uppercase', color: T.accentDark, marginBottom: '14px' }}>
|
||||
Madde 03 — Tartışma odaklı yapay zeka
|
||||
</span>
|
||||
</Reveal>
|
||||
<div className="hero-two-col" style={{ display: 'grid', gridTemplateColumns: 'minmax(0,5fr) minmax(0,7fr)', gap: '56px', alignItems: 'center' }}>
|
||||
<Reveal delay={0.05}>
|
||||
<div>
|
||||
<h2 style={{ fontFamily: T.fontHead, fontWeight: 400, fontSize: 'clamp(28px,3.2vw,40px)', margin: '0 0 20px', letterSpacing: '-0.008em', maxWidth: '16ch' }}>
|
||||
Bulmakla yetinmez, sizinle tartışır.
|
||||
</h2>
|
||||
<p style={{ fontSize: '15.5px', lineHeight: 1.7, margin: '0 0 16px', maxWidth: '46ch', textAlign: 'justify', hyphens: 'auto', color: 'rgba(32,31,29,0.78)' } as React.CSSProperties}>
|
||||
Çoğu hukuk yazılımı özet çıkarır ya da anahtar kelimeyle arar. AyrisLegal dosyanızdaki argümanı okur, zayıf noktasını sorar, karşı görüş üretir, sizi ikna etmeye çalışır — ya da ikna olur.
|
||||
</p>
|
||||
<p style={{ fontSize: '13px', margin: 0, color: 'rgba(32,31,29,0.58)' }}>
|
||||
Aşağıdaki görsel, bu tartışmanın nasıl göründüğünü gösteren temsili bir tasarımdır.
|
||||
</p>
|
||||
</div>
|
||||
</Reveal>
|
||||
|
||||
{/* Chat simulation */}
|
||||
<Reveal delay={0.1}>
|
||||
<div className="plate" style={{ margin: 0, padding: '28px', display: 'flex', flexDirection: 'column', gap: '14px' }}>
|
||||
{/* Lawyer message */}
|
||||
<div style={{ alignSelf: 'flex-end', maxWidth: '78%', background: T.bg, border: `1px solid ${T.divider}`, borderRadius: `${T.radiusMd} ${T.radiusMd} 4px ${T.radiusMd}`, padding: '14px 16px' }}>
|
||||
<div style={{ fontSize: '11px', letterSpacing: '0.06em', textTransform: 'uppercase', color: 'rgba(32,31,29,0.55)', marginBottom: '6px' }}>Avukat</div>
|
||||
<p style={{ margin: 0, fontSize: '14.5px', lineHeight: 1.6, fontFamily: T.fontBody }}>Müvekkilin haklı olduğunu düşünüyorum, mülkiyet devri geçerli.</p>
|
||||
</div>
|
||||
{/* AyrisLegal response */}
|
||||
<div style={{ alignSelf: 'flex-start', maxWidth: '82%', background: T.surface, border: `1px solid ${T.accent}`, borderRadius: `${T.radiusMd} ${T.radiusMd} ${T.radiusMd} 4px`, padding: '14px 16px' }}>
|
||||
<div style={{ display: 'flex', alignItems: 'center', gap: '8px', marginBottom: '6px' }}>
|
||||
<span style={{ fontSize: '11px', letterSpacing: '0.06em', textTransform: 'uppercase', color: T.accentDark }}>AyrisLegal</span>
|
||||
<span className="tag-outline" style={{ fontSize: '10.5px' }}>İtiraz</span>
|
||||
</div>
|
||||
<p style={{ margin: 0, fontSize: '14.5px', lineHeight: 1.6, fontFamily: T.fontBody }}>Devir tarihinde tapuda şerh var — bu, iyi niyet iddianızı zayıflatabilir. Şerhin kaldırılış tarihini kontrol ettiniz mi?</p>
|
||||
</div>
|
||||
{/* Lawyer reply */}
|
||||
<div style={{ alignSelf: 'flex-end', maxWidth: '78%', background: T.bg, border: `1px solid ${T.divider}`, borderRadius: `${T.radiusMd} ${T.radiusMd} 4px ${T.radiusMd}`, padding: '14px 16px' }}>
|
||||
<p style={{ margin: 0, fontSize: '14.5px', lineHeight: 1.6, fontFamily: T.fontBody }}>Haklısınız — 3 emsal kararla bu noktayı destekleyelim.</p>
|
||||
</div>
|
||||
</div>
|
||||
</Reveal>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<hr className="hr-line" style={{ maxWidth: '1240px', margin: '0 auto' }} />
|
||||
|
||||
{/* ══════════════════════════════ FEATURES ════════════════════════ */}
|
||||
<section id="ozellikler" style={{ maxWidth: '1240px', margin: '0 auto', padding: 'clamp(56px,9vw,108px) clamp(20px,6vw,72px)' }}>
|
||||
<Reveal>
|
||||
<span style={{ display: 'block', fontSize: '13px', letterSpacing: '0.08em', textTransform: 'uppercase', color: T.accentDark, marginBottom: '14px' }}>
|
||||
Madde 04 — Platform
|
||||
</span>
|
||||
<h2 style={{ fontFamily: T.fontHead, fontWeight: 400, fontSize: 'clamp(30px,3.6vw,44px)', margin: '0 0 40px', letterSpacing: '-0.008em' }}>
|
||||
Bir avukatın ihtiyaç duyduğu şeyler.
|
||||
</h2>
|
||||
</Reveal>
|
||||
<div className="card-grid">
|
||||
{/* Main feature — spans 2 cols */}
|
||||
<Reveal>
|
||||
<div className="card" style={{ gridColumn: 'span 2' }}>
|
||||
<span className="card-kicker">AI tartışma ortağı</span>
|
||||
<h3 className="card-title" style={{ fontSize: '26px' }}>Argümanınızı sınar, meslektaş gibi</h3>
|
||||
<p className="card-body">Zayıf noktaları sorar, karşı görüş üretir, sizi zorlar — pasif özet değil, aktif muhakeme. AyrisLegal'ın temel farkı budur.</p>
|
||||
</div>
|
||||
</Reveal>
|
||||
<Reveal delay={0.05}>
|
||||
<div className="card">
|
||||
<span className="card-kicker">Dosya analizi</span>
|
||||
<h3 className="card-title">Dava dosyasını okur</h3>
|
||||
<p className="card-body">Olay örgüsünü, tarafları ve hukuki dayanakları çıkarır.</p>
|
||||
</div>
|
||||
</Reveal>
|
||||
<Reveal delay={0.1}>
|
||||
<div className="card">
|
||||
<span className="card-kicker">İçtihat arama</span>
|
||||
<h3 className="card-title">Bağlama uygun emsal bulur</h3>
|
||||
<p className="card-body">Anahtar kelime eşleşmesiyle değil, hukuki benzerlikle emsal kararları bulur.</p>
|
||||
</div>
|
||||
</Reveal>
|
||||
<Reveal delay={0.12}>
|
||||
<div className="card">
|
||||
<span className="card-kicker">Dilekçe taslağı</span>
|
||||
<h3 className="card-title">Tartışmayı taslağa döker</h3>
|
||||
<p className="card-body">Vardığınız sonucu, düzenlenebilir bir dilekçe taslağına dönüştürür.</p>
|
||||
</div>
|
||||
</Reveal>
|
||||
<Reveal delay={0.15}>
|
||||
<div className="card">
|
||||
<span className="card-kicker" style={{ display: 'flex', alignItems: 'center', gap: '8px' }}>
|
||||
Büro paylaşımı <span className="tag-outline">Yakında</span>
|
||||
</span>
|
||||
<h3 className="card-title">Ekip çalışması</h3>
|
||||
<p className="card-body">Dosya ve tartışma geçmişini büro içindeki meslektaşlarınızla paylaşın.</p>
|
||||
</div>
|
||||
</Reveal>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<hr className="hr-line" style={{ maxWidth: '1240px', margin: '0 auto' }} />
|
||||
|
||||
{/* ══════════════════════════════ PRICING ═════════════════════════ */}
|
||||
<section id="fiyatlandirma" style={{ maxWidth: '1240px', margin: '0 auto', padding: 'clamp(56px,9vw,108px) clamp(20px,6vw,72px)' }}>
|
||||
<Reveal>
|
||||
<span style={{ display: 'block', fontSize: '13px', letterSpacing: '0.08em', textTransform: 'uppercase', color: T.accentDark, marginBottom: '14px', textAlign: 'center' }}>
|
||||
Madde 05 — Fiyatlandırma
|
||||
</span>
|
||||
<h2 style={{ fontFamily: T.fontHead, fontWeight: 400, fontSize: 'clamp(30px,3.6vw,44px)', margin: '0 0 44px', textAlign: 'center', letterSpacing: '-0.008em' }}>
|
||||
İhtiyacınıza uygun modeller.
|
||||
</h2>
|
||||
</Reveal>
|
||||
|
||||
<div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(320px, 1fr))', gap: '32px', maxWidth: '960px', margin: '0 auto' }}>
|
||||
|
||||
{/* ── Bireysel ── */}
|
||||
<Reveal delay={0.08}>
|
||||
<div style={{ display: 'flex', border: `1px solid ${T.divider}`, borderRadius: T.radiusLg, boxShadow: T.shadowMd, overflow: 'hidden', height: '100%' }}>
|
||||
<div style={{ width: '34px', background: T.neutral100, display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'space-evenly', borderRight: `1px solid ${T.divider}`, padding: '20px 0' }}>
|
||||
{['01','02','03','04','05'].map(t => (
|
||||
<span key={t} style={{ fontSize: '11px', color: T.accentDark, writingMode: 'vertical-rl', fontFamily: T.fontHead }}>{t}</span>
|
||||
))}
|
||||
</div>
|
||||
<div style={{ flex: 1, padding: '40px 36px', textAlign: 'center', display: 'flex', flexDirection: 'column' }}>
|
||||
<p style={{ margin: 0, fontFamily: T.fontHead, fontWeight: 400, fontSize: 'clamp(42px,5vw,56px)', lineHeight: 1 }}>40.000 TL</p>
|
||||
<p style={{ margin: '6px 0 0', fontSize: '14px', letterSpacing: '0.06em', textTransform: 'uppercase', color: 'rgba(32,31,29,0.6)' }}>Bireysel Avukat / Yıl</p>
|
||||
<p style={{ fontSize: '15px', lineHeight: 1.6, margin: '20px auto 0', color: 'rgba(32,31,29,0.78)', fontFamily: T.fontBody }}>
|
||||
Serbest çalışan avukatlar için tasarlanmış yapay zeka çalışma ortağı.
|
||||
</p>
|
||||
<hr className="hr-line" style={{ margin: '24px 0' }} />
|
||||
<ul style={{ listStyle: 'none', margin: '0 0 auto 0', padding: 0, display: 'flex', flexDirection: 'column', gap: '12px', textAlign: 'left' }}>
|
||||
{['Sınırsız dosya analizi', 'AI tartışma ortağı', 'İçtihat arama', 'Dilekçe taslağı üretimi'].map(item => (
|
||||
<li key={item} style={{ display: 'flex', gap: '10px', fontSize: '14.5px', fontFamily: T.fontBody }}>
|
||||
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke={T.accent} strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round" style={{ flexShrink: 0, marginTop: '2px' }}>
|
||||
<polyline points="20 6 9 17 4 12" />
|
||||
</svg>
|
||||
{item}
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
<a href="#iletisim" className="btn-primary-lg" style={{ marginTop: '26px' }}>Demo Talep Et</a>
|
||||
</div>
|
||||
</div>
|
||||
</Reveal>
|
||||
|
||||
{/* ── Büro ── */}
|
||||
<Reveal delay={0.15}>
|
||||
<div style={{ display: 'flex', border: `1px solid ${T.accent}`, borderRadius: T.radiusLg, boxShadow: T.shadowMd, overflow: 'hidden', height: '100%', position: 'relative' }}>
|
||||
<div style={{ position: 'absolute', top: 0, left: 0, right: 0, background: T.accent, color: '#fff', fontSize: '11px', letterSpacing: '0.1em', textTransform: 'uppercase', textAlign: 'center', padding: '4px', fontFamily: T.fontHead, fontWeight: 600 }}>Ekip Çalışması</div>
|
||||
<div style={{ width: '34px', background: 'rgba(182,130,53,0.05)', display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'space-evenly', borderRight: `1px solid ${T.divider}`, padding: '40px 0 20px' }}>
|
||||
{['01','02','03','04','05'].map(t => (
|
||||
<span key={t} style={{ fontSize: '11px', color: T.accentDark, writingMode: 'vertical-rl', fontFamily: T.fontHead }}>{t}</span>
|
||||
))}
|
||||
</div>
|
||||
<div style={{ flex: 1, padding: '56px 36px 40px', textAlign: 'center', display: 'flex', flexDirection: 'column' }}>
|
||||
<p style={{ margin: 0, fontFamily: T.fontHead, fontWeight: 400, fontSize: 'clamp(32px,4vw,42px)', lineHeight: 1.1, color: T.accentDark, marginTop: '6px' }}>Hukuk Bürosu</p>
|
||||
<p style={{ margin: '10px 0 0', fontSize: '14px', letterSpacing: '0.06em', textTransform: 'uppercase', color: 'rgba(32,31,29,0.6)' }}>Özel Fiyatlandırma</p>
|
||||
<p style={{ fontSize: '15px', lineHeight: 1.6, margin: '20px auto 0', color: 'rgba(32,31,29,0.78)', fontFamily: T.fontBody }}>
|
||||
Tüm ekibiniz için paylaşımlı çalışma alanı, dosya yönetimi ve özel entegrasyonlar.
|
||||
</p>
|
||||
<hr className="hr-line" style={{ margin: '24px 0' }} />
|
||||
<ul style={{ listStyle: 'none', margin: '0 0 auto 0', padding: 0, display: 'flex', flexDirection: 'column', gap: '12px', textAlign: 'left' }}>
|
||||
{['Tüm bireysel özellikler', 'Ekip içi dosya paylaşımı', 'Ortak içtihat havuzu', 'Kurucu ekiple özel destek'].map(item => (
|
||||
<li key={item} style={{ display: 'flex', gap: '10px', fontSize: '14.5px', fontFamily: T.fontBody }}>
|
||||
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke={T.accentDark} strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round" style={{ flexShrink: 0, marginTop: '2px' }}>
|
||||
<polyline points="20 6 9 17 4 12" />
|
||||
</svg>
|
||||
{item}
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
<a href="#iletisim" className="btn-primary-lg" style={{ marginTop: '26px', background: T.accent, color: '#fff', border: 'none' }}
|
||||
onMouseEnter={e => (e.currentTarget.style.background = T.accentDark)}
|
||||
onMouseLeave={e => (e.currentTarget.style.background = T.accent)}
|
||||
>İletişime Geçin</a>
|
||||
</div>
|
||||
</div>
|
||||
</Reveal>
|
||||
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<hr className="hr-line" style={{ maxWidth: '1240px', margin: '0 auto' }} />
|
||||
|
||||
{/* ══════════════════════════════ TRUST ═══════════════════════════ */}
|
||||
<section id="guven" style={{ maxWidth: '1240px', margin: '0 auto', padding: 'clamp(56px,9vw,108px) clamp(20px,6vw,72px)' }}>
|
||||
<Reveal>
|
||||
<span style={{ display: 'block', fontSize: '13px', letterSpacing: '0.08em', textTransform: 'uppercase', color: T.accentDark, marginBottom: '14px' }}>
|
||||
Madde 06 — Güven ve veri güvenliği
|
||||
</span>
|
||||
<h2 style={{ fontFamily: T.fontHead, fontWeight: 400, fontSize: 'clamp(30px,3.6vw,44px)', margin: '0 0 16px', letterSpacing: '-0.008em' }}>
|
||||
Dosyalarınız sizin kalır.
|
||||
</h2>
|
||||
<p style={{ fontSize: '15.5px', lineHeight: 1.7, maxWidth: '60ch', margin: '0 0 40px', color: 'rgba(32,31,29,0.78)', fontFamily: T.fontBody }}>
|
||||
Bir dava dosyası, bir avukatın elindeki en hassas belgedir. AyrisLegal'ı bu bilinçle kuruyoruz.
|
||||
</p>
|
||||
</Reveal>
|
||||
<div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit,minmax(240px,1fr))', gap: 0, borderTop: `1px solid ${T.divider}` }}>
|
||||
{[
|
||||
{
|
||||
icon: <svg width="26" height="26" viewBox="0 0 24 24" fill="none" stroke={T.accent} strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"><path d="M12 2 L20 5 V11 C20 16 16.5 19.5 12 21 C7.5 19.5 4 16 4 11 V5 Z"/><path d="M9 12 l2.2 2.2 L15.5 9.5"/></svg>,
|
||||
title: "KVKK'ya uyumlu",
|
||||
desc: 'Kişisel verilerin korunması mevzuatına uygun işleme ve saklama.',
|
||||
},
|
||||
{
|
||||
icon: <svg width="26" height="26" viewBox="0 0 24 24" fill="none" stroke={T.accent} strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"><rect x="3" y="4" width="18" height="6" rx="1.5"/><rect x="3" y="14" width="18" height="6" rx="1.5"/><line x1="7" y1="7" x2="7" y2="7"/><line x1="7" y1="17" x2="7" y2="17"/></svg>,
|
||||
title: "Sunucular Türkiye'de",
|
||||
desc: "Verileriniz yurt dışına çıkmaz — Ayris Tech'in self-hosted altyapı felsefesiyle.",
|
||||
},
|
||||
{
|
||||
icon: <svg width="26" height="26" viewBox="0 0 24 24" fill="none" stroke={T.accent} strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"><rect x="5" y="10" width="14" height="10" rx="1.5"/><path d="M8 10 V7 a4 4 0 0 1 8 0 v3"/></svg>,
|
||||
title: 'Dosyanız modelleri eğitmez',
|
||||
desc: 'Yüklediğiniz belgeler yalnızca sizin analizinizde kullanılır.',
|
||||
},
|
||||
].map((item, i, arr) => (
|
||||
<Reveal key={item.title} delay={i * 0.08}>
|
||||
<div style={{ padding: '28px 24px 0', borderRight: i < arr.length - 1 ? `1px solid ${T.divider}` : undefined }}>
|
||||
{item.icon}
|
||||
<h3 style={{ fontFamily: T.fontHead, fontWeight: 400, fontSize: '19px', margin: '12px 0 6px' }}>{item.title}</h3>
|
||||
<p style={{ fontSize: '14.5px', lineHeight: 1.6, margin: 0, color: 'rgba(32,31,29,0.78)', fontFamily: T.fontBody }}>{item.desc}</p>
|
||||
</div>
|
||||
</Reveal>
|
||||
))}
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<hr className="hr-line" style={{ maxWidth: '1240px', margin: '0 auto' }} />
|
||||
|
||||
{/* ══════════════════════════════ CONTACT ═════════════════════════ */}
|
||||
<section id="iletisim" style={{ maxWidth: '1240px', margin: '0 auto', padding: 'clamp(56px,9vw,108px) clamp(20px,6vw,72px)' }}>
|
||||
<Reveal>
|
||||
<span style={{ display: 'block', fontSize: '13px', letterSpacing: '0.08em', textTransform: 'uppercase', color: T.accentDark, marginBottom: '14px' }}>
|
||||
Madde 07 — Erken erişim
|
||||
</span>
|
||||
</Reveal>
|
||||
<div className="contact-two-col" style={{ display: 'grid', gridTemplateColumns: 'minmax(0,5fr) minmax(0,7fr)', gap: '48px' }}>
|
||||
<Reveal delay={0.05}>
|
||||
<div>
|
||||
<h2 style={{ fontFamily: T.fontHead, fontWeight: 400, fontSize: 'clamp(28px,3.2vw,38px)', margin: '0 0 16px', letterSpacing: '-0.008em' }}>
|
||||
Şu an müşteri referansı göstermiyoruz — kasıtlı olarak.
|
||||
</h2>
|
||||
<p style={{ fontSize: '15.5px', lineHeight: 1.7, margin: 0, textAlign: 'justify', hyphens: 'auto', color: 'rgba(32,31,29,0.78)', fontFamily: T.fontBody } as React.CSSProperties}>
|
||||
AyrisLegal yeni. Sahte ya da ödünç yorumlar yerine dürüst olmayı seçtik: platformu kurucu ekiple birlikte, doğrudan geri bildiriminizle şekillendiriyoruz. Demo talep edin, ilk kullanan avukatlardan biri olun.
|
||||
</p>
|
||||
<div style={{ marginTop: '32px', display: 'flex', alignItems: 'center', gap: '14px' }}>
|
||||
<div style={{ width: '48px', height: '48px', border: `1px solid ${T.accent}`, borderRadius: '50%', display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center', fontFamily: T.fontHead, fontSize: '8px', color: T.accentDark, textAlign: 'center', lineHeight: 1.2, flexShrink: 0, textTransform: 'uppercase' }}>
|
||||
<span style={{ fontWeight: 400, letterSpacing: '0.22em' }}>AYRIS</span>
|
||||
<span style={{ fontWeight: 500, letterSpacing: '0.35em' }}>LEGAL</span>
|
||||
</div>
|
||||
<span style={{ fontSize: '12.5px', color: 'rgba(32,31,29,0.6)', fontFamily: T.fontBody }}>Kurucu ekip mührü</span>
|
||||
</div>
|
||||
</div>
|
||||
</Reveal>
|
||||
<Reveal delay={0.1}>
|
||||
<ContactForm />
|
||||
</Reveal>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* ══════════════════════════════ FOOTER ══════════════════════════ */}
|
||||
<footer style={{ maxWidth: '1240px', margin: '0 auto', padding: '28px clamp(20px,6vw,72px) 40px', display: 'flex', justifyContent: 'space-between', flexWrap: 'wrap', gap: '12px', fontSize: '13px', color: 'rgba(32,31,29,0.6)', borderTop: `1px solid ${T.divider}`, fontFamily: T.fontBody }}>
|
||||
<span>AyrisLegal, Ayris Tech'in bir ürünüdür.</span>
|
||||
<span>
|
||||
© {new Date().getFullYear()} AyrisLegal ·{' '}
|
||||
<a href="https://ayris.tech" target="_blank" rel="noopener noreferrer" style={{ color: 'rgba(32,31,29,0.6)' }}>
|
||||
Created by ayris.tech
|
||||
</a>
|
||||
</span>
|
||||
</footer>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
import { handlers } from "@/lib/auth"
|
||||
|
||||
export const { GET, POST } = handlers
|
||||
@@ -0,0 +1,82 @@
|
||||
import { NextRequest, NextResponse } from 'next/server'
|
||||
|
||||
const EMAIL_REGEX = /^[^\s@]+@[^\s@]+\.[^\s@]+$/
|
||||
|
||||
// Basit in-memory rate limiting (MVP — production'da Redis kullan)
|
||||
const ipRequestMap = new Map<string, { count: number; resetAt: number }>()
|
||||
const RATE_LIMIT = 5 // maksimum istek
|
||||
const WINDOW_MS = 60_000 // 1 dakika
|
||||
|
||||
function checkRateLimit(ip: string): boolean {
|
||||
const now = Date.now()
|
||||
const entry = ipRequestMap.get(ip)
|
||||
|
||||
if (!entry || now > entry.resetAt) {
|
||||
ipRequestMap.set(ip, { count: 1, resetAt: now + WINDOW_MS })
|
||||
return true
|
||||
}
|
||||
|
||||
if (entry.count >= RATE_LIMIT) return false
|
||||
|
||||
entry.count++
|
||||
return true
|
||||
}
|
||||
|
||||
export async function POST(request: NextRequest) {
|
||||
try {
|
||||
// IP tespiti
|
||||
const forwarded = request.headers.get('x-forwarded-for')
|
||||
const ip = forwarded ? forwarded.split(',')[0].trim() : 'unknown'
|
||||
|
||||
// Rate limit
|
||||
if (!checkRateLimit(ip)) {
|
||||
return NextResponse.json(
|
||||
{ success: false, error: 'Çok fazla istek. Lütfen bir dakika bekleyip tekrar deneyin.' },
|
||||
{ status: 429 }
|
||||
)
|
||||
}
|
||||
|
||||
const body = await request.json()
|
||||
const { name, email, barNo, message, _hp } = body
|
||||
|
||||
// Honeypot kontrolü
|
||||
if (_hp) {
|
||||
// Bot — 200 döndür ama işleme
|
||||
return NextResponse.json({ success: true })
|
||||
}
|
||||
|
||||
// Zorunlu alan doğrulaması
|
||||
if (!name || typeof name !== 'string' || name.trim().length < 2) {
|
||||
return NextResponse.json(
|
||||
{ success: false, error: 'Ad Soyad zorunludur (en az 2 karakter).' },
|
||||
{ status: 400 }
|
||||
)
|
||||
}
|
||||
|
||||
if (!email || typeof email !== 'string' || !EMAIL_REGEX.test(email.trim())) {
|
||||
return NextResponse.json(
|
||||
{ success: false, error: 'Geçerli bir e-posta adresi giriniz.' },
|
||||
{ status: 400 }
|
||||
)
|
||||
}
|
||||
|
||||
// MVP: Konsola yaz
|
||||
// TODO: Resend/SendGrid veya Prisma leads tablosu eklenebilir
|
||||
console.log('[AyrisLegal] 🎯 Yeni Demo Talebi:', {
|
||||
timestamp: new Date().toISOString(),
|
||||
name: name.trim(),
|
||||
email: email.trim().toLowerCase(),
|
||||
barNo: barNo?.trim() || null,
|
||||
message: message?.trim() || null,
|
||||
ip,
|
||||
})
|
||||
|
||||
return NextResponse.json({ success: true }, { status: 200 })
|
||||
} catch (err) {
|
||||
console.error('[AyrisLegal] Contact API hatası:', err)
|
||||
return NextResponse.json(
|
||||
{ success: false, error: 'Sunucu hatası oluştu.' },
|
||||
{ status: 500 }
|
||||
)
|
||||
}
|
||||
}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 25 KiB |
+198
@@ -0,0 +1,198 @@
|
||||
@import "tailwindcss";
|
||||
@import "tw-animate-css";
|
||||
@import "shadcn/tailwind.css";
|
||||
|
||||
@custom-variant dark (&:is(.dark *));
|
||||
|
||||
@theme inline {
|
||||
--color-background: var(--background);
|
||||
--color-foreground: var(--foreground);
|
||||
--font-sans: var(--font-archivo);
|
||||
--font-mono: var(--font-geist-mono);
|
||||
--font-heading: var(--font-archivo);
|
||||
--color-sidebar-ring: var(--sidebar-ring);
|
||||
--color-sidebar-border: var(--sidebar-border);
|
||||
--color-sidebar-accent-foreground: var(--sidebar-accent-foreground);
|
||||
--color-sidebar-accent: var(--sidebar-accent);
|
||||
--color-sidebar-primary-foreground: var(--sidebar-primary-foreground);
|
||||
--color-sidebar-primary: var(--sidebar-primary);
|
||||
--color-sidebar-foreground: var(--sidebar-foreground);
|
||||
--color-sidebar: var(--sidebar);
|
||||
--color-chart-5: var(--chart-5);
|
||||
--color-chart-4: var(--chart-4);
|
||||
--color-chart-3: var(--chart-3);
|
||||
--color-chart-2: var(--chart-2);
|
||||
--color-chart-1: var(--chart-1);
|
||||
--color-ring: var(--ring);
|
||||
--color-input: var(--input);
|
||||
--color-border: var(--border);
|
||||
--color-destructive: var(--destructive);
|
||||
--color-accent-foreground: var(--accent-foreground);
|
||||
--color-accent: var(--accent);
|
||||
--color-muted-foreground: var(--muted-foreground);
|
||||
--color-muted: var(--muted);
|
||||
--color-secondary-foreground: var(--secondary-foreground);
|
||||
--color-secondary: var(--secondary);
|
||||
--color-primary-foreground: var(--primary-foreground);
|
||||
--color-primary: var(--primary);
|
||||
--color-popover-foreground: var(--popover-foreground);
|
||||
--color-popover: var(--popover);
|
||||
--color-card-foreground: var(--card-foreground);
|
||||
--color-card: var(--card);
|
||||
--radius-sm: calc(var(--radius) * 0.6);
|
||||
--radius-md: calc(var(--radius) * 0.8);
|
||||
--radius-lg: var(--radius);
|
||||
--radius-xl: calc(var(--radius) * 1.4);
|
||||
--radius-2xl: calc(var(--radius) * 1.8);
|
||||
--radius-3xl: calc(var(--radius) * 2.2);
|
||||
--radius-4xl: calc(var(--radius) * 2.6);
|
||||
}
|
||||
|
||||
/* ─── AyrisLegal Marka Renk Sistemi (Lacivert + Teal) ─────────────── */
|
||||
:root {
|
||||
/* Lacivert (navy) arka plan / teal vurgu — dark-first marka */
|
||||
--background: oklch(0.18 0.055 243); /* Derin lacivert */
|
||||
--foreground: oklch(0.95 0.012 240); /* Neredeyse beyaz */
|
||||
|
||||
--card: oklch(0.22 0.05 243); /* Biraz açık lacivert kart */
|
||||
--card-foreground: oklch(0.95 0.012 240);
|
||||
|
||||
--popover: oklch(0.22 0.05 243);
|
||||
--popover-foreground: oklch(0.95 0.012 240);
|
||||
|
||||
/* Teal ana renk */
|
||||
--primary: oklch(0.63 0.14 183); /* Teal */
|
||||
--primary-foreground: oklch(0.98 0.008 183);
|
||||
|
||||
--secondary: oklch(0.28 0.05 243); /* Orta lacivert */
|
||||
--secondary-foreground: oklch(0.90 0.012 240);
|
||||
|
||||
--muted: oklch(0.25 0.04 243);
|
||||
--muted-foreground: oklch(0.60 0.035 240);
|
||||
|
||||
--accent: oklch(0.68 0.13 183); /* Açık teal vurgu */
|
||||
--accent-foreground: oklch(0.18 0.055 243);
|
||||
|
||||
--destructive: oklch(0.577 0.245 27.325);
|
||||
|
||||
--border: oklch(0.32 0.045 243);
|
||||
--input: oklch(0.28 0.045 243);
|
||||
--ring: oklch(0.63 0.14 183); /* Teal focus ring */
|
||||
|
||||
--chart-1: oklch(0.63 0.14 183);
|
||||
--chart-2: oklch(0.55 0.12 200);
|
||||
--chart-3: oklch(0.45 0.09 220);
|
||||
--chart-4: oklch(0.38 0.07 230);
|
||||
--chart-5: oklch(0.30 0.05 240);
|
||||
|
||||
--radius: 0.75rem;
|
||||
|
||||
--sidebar: oklch(0.20 0.055 243);
|
||||
--sidebar-foreground: oklch(0.90 0.012 240);
|
||||
--sidebar-primary: oklch(0.63 0.14 183);
|
||||
--sidebar-primary-foreground: oklch(0.98 0.008 183);
|
||||
--sidebar-accent: oklch(0.25 0.05 243);
|
||||
--sidebar-accent-foreground: oklch(0.90 0.012 240);
|
||||
--sidebar-border: oklch(0.30 0.045 243);
|
||||
--sidebar-ring: oklch(0.63 0.14 183);
|
||||
}
|
||||
|
||||
/* Admin/login sayfaları için açık tema (opsiyonel override) */
|
||||
.light {
|
||||
--background: oklch(0.98 0.005 240);
|
||||
--foreground: oklch(0.18 0.055 243);
|
||||
--card: oklch(1 0 0);
|
||||
--card-foreground: oklch(0.18 0.055 243);
|
||||
--popover: oklch(1 0 0);
|
||||
--popover-foreground: oklch(0.18 0.055 243);
|
||||
--primary: oklch(0.55 0.14 183);
|
||||
--primary-foreground: oklch(0.98 0.008 183);
|
||||
--secondary: oklch(0.93 0.02 240);
|
||||
--secondary-foreground: oklch(0.22 0.05 243);
|
||||
--muted: oklch(0.95 0.015 240);
|
||||
--muted-foreground: oklch(0.50 0.04 240);
|
||||
--accent: oklch(0.90 0.06 183);
|
||||
--accent-foreground: oklch(0.25 0.05 243);
|
||||
--destructive: oklch(0.577 0.245 27.325);
|
||||
--border: oklch(0.88 0.02 240);
|
||||
--input: oklch(0.88 0.02 240);
|
||||
--ring: oklch(0.55 0.14 183);
|
||||
}
|
||||
|
||||
@layer base {
|
||||
* {
|
||||
@apply border-border outline-ring/50;
|
||||
}
|
||||
body {
|
||||
@apply bg-background text-foreground;
|
||||
}
|
||||
html {
|
||||
@apply font-sans;
|
||||
scroll-behavior: smooth;
|
||||
}
|
||||
}
|
||||
|
||||
/* ─── AyrisLegal Premium Background Effects ─────────────────────────── */
|
||||
|
||||
.orb {
|
||||
position: fixed;
|
||||
border-radius: 50%;
|
||||
filter: blur(110px);
|
||||
pointer-events: none;
|
||||
z-index: 0;
|
||||
will-change: transform;
|
||||
}
|
||||
|
||||
.orb-1 {
|
||||
width: 700px;
|
||||
height: 700px;
|
||||
background: radial-gradient(circle, rgba(45,212,191,0.22) 0%, transparent 70%);
|
||||
top: -180px;
|
||||
left: -120px;
|
||||
animation: orb-float 14s ease-in-out infinite;
|
||||
}
|
||||
|
||||
.orb-2 {
|
||||
width: 550px;
|
||||
height: 550px;
|
||||
background: radial-gradient(circle, rgba(99,102,241,0.16) 0%, transparent 70%);
|
||||
top: 38%;
|
||||
right: -120px;
|
||||
animation: orb-float 18s ease-in-out infinite reverse;
|
||||
animation-delay: -6s;
|
||||
}
|
||||
|
||||
.orb-3 {
|
||||
width: 420px;
|
||||
height: 420px;
|
||||
background: radial-gradient(circle, rgba(45,212,191,0.12) 0%, transparent 70%);
|
||||
bottom: 15%;
|
||||
left: 28%;
|
||||
animation: orb-float 11s ease-in-out infinite;
|
||||
animation-delay: -9s;
|
||||
}
|
||||
|
||||
@keyframes orb-float {
|
||||
0%, 100% { transform: translate(0, 0) scale(1); }
|
||||
33% { transform: translate(35px, -50px) scale(1.06); }
|
||||
66% { transform: translate(-25px, 25px) scale(0.95); }
|
||||
}
|
||||
|
||||
.grid-overlay {
|
||||
position: fixed;
|
||||
inset: 0;
|
||||
background-image:
|
||||
linear-gradient(rgba(255,255,255,0.022) 1px, transparent 1px),
|
||||
linear-gradient(90deg, rgba(255,255,255,0.022) 1px, transparent 1px);
|
||||
background-size: 60px 60px;
|
||||
pointer-events: none;
|
||||
z-index: 0;
|
||||
}
|
||||
|
||||
/* Gradient text utility */
|
||||
.text-gradient-teal {
|
||||
background: linear-gradient(135deg, #2DD4BF 0%, #67E8F9 100%);
|
||||
-webkit-background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
background-clip: text;
|
||||
}
|
||||
Reference in New Issue
Block a user