From e391eeb832ebcc45b9a603f6ca8b064db835f006 Mon Sep 17 00:00:00 2001 From: mstfyldz Date: Wed, 12 Aug 2026 17:48:08 +0300 Subject: [PATCH] =?UTF-8?q?refactor(v2):=20design-taste=20skiliyle=20marka?= =?UTF-8?q?=20renklerine=20(k=C4=B1rm=C4=B1z=C4=B1/zinc)=20ge=C3=A7i=C5=9F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Referans olarak gösterilen görsellerdeki turuncu/lacivert palet başka bir şirkete ait olduğu için tamamen kaldırıldı, AyrisLegal'ın kendi kırmızı aksanına (#E61919) sadık kalındı. Inline style yerine Tailwind utility'lerine, emoji yerine lucide-react ikonlarına geçildi. Hero ortadan hizalı yerine asimetrik split düzene, alt özellik şeridi ise "3 eşit kart" yerine bento grid'e dönüştürüldü. Spring physics tabanlı Framer Motion reveal + magnetic CTA butonu eklendi. --- app/[locale]/v2/page.tsx | 843 ++++++++++++++++++++------------------- 1 file changed, 433 insertions(+), 410 deletions(-) diff --git a/app/[locale]/v2/page.tsx b/app/[locale]/v2/page.tsx index 05798db..c46a2dc 100644 --- a/app/[locale]/v2/page.tsx +++ b/app/[locale]/v2/page.tsx @@ -1,26 +1,22 @@ 'use client' -import { useRef, useState } from 'react' -import { motion, useInView } from 'framer-motion' +import React, { useRef, useState } from 'react' +import { motion, useInView, useMotionValue, useTransform, useSpring } from 'framer-motion' +import { + ArrowRight, FileText, Search, MessageSquare, ShieldCheck, Cloud, Lock, + CheckCircle2, Sparkles, Scale, GraduationCap, AlertTriangle, + FolderOpen, Landmark, Users2, ChevronRight, +} from 'lucide-react' import ContactFormV2 from '@/components/contact-form-v2' -/* ─── Design tokens (Modern SaaS / warm & rounded) ─────────────────────── */ -const T = { - bg: '#FFFFFF', - bgSoft: '#FFF8F1', - ink: '#0B1220', - inkSoft: 'rgba(11,18,32,0.62)', - inkFaint: 'rgba(11,18,32,0.42)', - orange: '#F2600C', - orangeDark:'#D94E00', - orangeSoft:'#FFEDD9', - navy: '#16223D', - navySoft: '#EEF2FB', - green: '#0F9D6E', - greenSoft: '#E4F7EF', - border: 'rgba(11,18,32,0.08)', - fontHead: '"Archivo", sans-serif', -} +/* ───────────────────────────────────────────────────────────────────────── + Brand tokens — AyrisLegal kırmızısı (#E61919) tek aksan renk, nötr taban + zinc skalası. Referans görsellerdeki turuncu/lacivert paletle kasıtlı + olarak hiçbir ortak nokta yok (başka bir şirketin kimliği). + ───────────────────────────────────────────────────────────────────────── */ +const ACCENT = '#E61919' +const ACCENT_DARK = '#B8140F' +const ACCENT_SOFT = '#FDEEEC' function Reveal({ children, className = '', delay = 0 }: { children: React.ReactNode; className?: string; delay?: number @@ -30,9 +26,9 @@ function Reveal({ children, className = '', delay = 0 }: { return ( {children} @@ -40,17 +36,71 @@ function Reveal({ children, className = '', delay = 0 }: { ) } -/* ─── Mock "browser window" chrome wrapper ─────────────────────────────── */ -function BrowserFrame({ children, width = '100%' }: { children: React.ReactNode; width?: string }) { +/* Magnetic CTA — useMotionValue/useTransform dışında hiçbir React state + kullanmıyor (skill kuralı: sürekli hover animasyonu için useState yasak). */ +function MagneticButton({ href, children, variant = 'solid' }: { + href: string; children: React.ReactNode; variant?: 'solid' | 'outline' +}) { + const x = useMotionValue(0) + const y = useMotionValue(0) + const springX = useSpring(x, { stiffness: 150, damping: 15, mass: 0.5 }) + const springY = useSpring(y, { stiffness: 150, damping: 15, mass: 0.5 }) + const tx = useTransform(springX, v => v) + const ty = useTransform(springY, v => v) + + const handleMove = (e: React.MouseEvent) => { + const rect = e.currentTarget.getBoundingClientRect() + x.set((e.clientX - rect.left - rect.width / 2) * 0.25) + y.set((e.clientY - rect.top - rect.height / 2) * 0.25) + } + const handleLeave = () => { x.set(0); y.set(0) } + + const base = 'inline-flex items-center justify-center gap-2 rounded-full px-7 py-3.5 text-[15px] font-semibold transition-colors active:scale-[0.98]' + const style = variant === 'solid' + ? { background: ACCENT, color: '#fff' } + : { background: '#fff', color: '#18181B', border: '1.5px solid rgb(228 228 231)' } + return ( -
-
- - - - ayrislegal.com + { if (variant === 'solid') (e.currentTarget as HTMLElement).style.background = ACCENT_DARK }} + onMouseOut={e => { if (variant === 'solid') (e.currentTarget as HTMLElement).style.background = ACCENT }} + > + {children} + + ) +} + +/* Sürekli nabız atan "canlı" gösterge — izole, memoized, parent'ı + yeniden render etmez (performance guardrail). */ +const LivePulse = React.memo(function LivePulse() { + return ( + + + + + ) +}) + +function BrowserFrame({ children }: { children: React.ReactNode }) { + return ( +
+
+ + + + ayrislegal.com
-
{children}
+
{children}
) } @@ -66,160 +116,158 @@ export default function HomePageV2() { const [pricingYearly, setPricingYearly] = useState(true) return ( -
+
{/* ══════════════════════════════ NAV ═════════════════════════════ */} -