Files
jaengseung-made/app/page.tsx
gahusb 22c9a2f2de design: 홈페이지 서비스 그리드 균형 복원 + Supanova 카드 디자인 강화
[균형 복원]
- PROOF_SERVICES: 1개 → 3개 (쟁승메이드 + AI 사주 분석 + AI 자동화 키트)
  로또·주식 제거로 생긴 3열 그리드 공백 해결
- SUBSCRIPTION_SERVICES: 3개 → 4개 (AI 사주 분석 추가)
  4열 그리드에 맞게 복원

[Supanova 디자인 강화 — 마케터·UX·상품 전문가 관점]
- 서비스 카드에 아이콘(SVG) + 1줄 설명 추가: 가격만 있던 카드 → "나에게 왜 필요한가" 즉시 이해
- flex-col 레이아웃으로 카드 높이 통일, 설명이 중간을 채우는 구조
- hover 시 -translate-y-1 + shadow-lg로 클릭 유도 강화
- PROOF_SERVICES 카드: accentColor별 컬러 배지 + 배경 글로우 + hover 효과 추가
- Hero 우측 패널: 1개 → 3개 서비스 표시, 배지 색상을 서비스별로 분리

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-28 14:12:00 +09:00

756 lines
45 KiB
TypeScript

'use client';
import { useState } from 'react';
import Link from 'next/link';
import ContactModal from './components/ContactModal';
/* ──────────────────────────────────────────────
Spring easing: cubic-bezier(0.16, 1, 0.3, 1)
모든 인터랙티브 요소에 일관 적용
─────────────────────────────────────────────── */
const TRUST_POINTS = [
{
id: 'contract',
size: 'lg', // 2-col span
icon: (
<svg className="w-7 h-7" fill="none" stroke="currentColor" viewBox="0 0 24 24" strokeWidth={1.5}>
<path strokeLinecap="round" strokeLinejoin="round" d="M9 12h3.75M9 15h3.75M9 18h3.75m3 .75H18a2.25 2.25 0 002.25-2.25V6.108c0-1.135-.845-2.098-1.976-2.192a48.424 48.424 0 00-1.123-.08m-5.801 0c-.065.21-.1.433-.1.664 0 .414.336.75.75.75h4.5a.75.75 0 00.75-.75 2.25 2.25 0 00-.1-.664m-5.8 0A2.251 2.251 0 0113.5 2.25H15c1.012 0 1.867.668 2.15 1.586m-5.8 0c-.376.023-.75.05-1.124.08C9.095 4.01 8.25 4.973 8.25 6.108V8.25m0 0H4.875c-.621 0-1.125.504-1.125 1.125v11.25c0 .621.504 1.125 1.125 1.125h9.75c.621 0 1.125-.504 1.125-1.125V9.375c0-.621-.504-1.125-1.125-1.125H8.25z" />
</svg>
),
label: '계약서 먼저, 개발 나중',
desc: '구두 약속 없습니다. 계약금 30%, 중도금, 잔금으로 단계별 진행. 납기 지연 시 하루 10만 원 자동 감면.',
accent: 'blue',
highlight: '납기 지연 → 하루 10만원 패널티',
},
{
id: 'source',
size: 'sm',
icon: (
<svg className="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24" strokeWidth={1.5}>
<path strokeLinecap="round" strokeLinejoin="round" d="M17.25 6.75L22.5 12l-5.25 5.25m-10.5 0L1.5 12l5.25-5.25m7.5-3l-4.5 16.5" />
</svg>
),
label: '소스코드 100% 인도',
desc: '납품 후 모든 소스코드를 전달합니다. 락인 없음.',
accent: 'violet',
highlight: null,
},
{
id: 'as',
size: 'sm',
icon: (
<svg className="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24" strokeWidth={1.5}>
<path strokeLinecap="round" strokeLinejoin="round" d="M9 12.75L11.25 15 15 9.75m-3-7.036A11.959 11.959 0 013.598 6 11.99 11.99 0 003 9.749c0 5.592 3.824 10.29 9 11.623 5.176-1.332 9-6.03 9-11.622 0-1.31-.21-2.571-.598-3.751h-.152c-3.196 0-6.1-1.248-8.25-3.285z" />
</svg>
),
label: '1개월 무상 AS',
desc: '납품 후 1개월간 버그 수정 무료. 평생 유지보수 계약도 가능.',
accent: 'emerald',
highlight: null,
},
{
id: 'reply',
size: 'sm',
icon: (
<svg className="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24" strokeWidth={1.5}>
<path strokeLinecap="round" strokeLinejoin="round" d="M12 6v6h4.5m4.5 0a9 9 0 11-18 0 9 9 0 0118 0z" />
</svg>
),
label: '24시간 이내 견적',
desc: '문의 후 평균 3.8시간 이내 답변. 주말·공휴일 포함.',
accent: 'amber',
highlight: null,
},
{
id: 'report',
size: 'sm',
icon: (
<svg className="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24" strokeWidth={1.5}>
<path strokeLinecap="round" strokeLinejoin="round" d="M3 13.125C3 12.504 3.504 12 4.125 12h2.25c.621 0 1.125.504 1.125 1.125v6.75C7.5 20.496 6.996 21 6.375 21h-2.25A1.125 1.125 0 013 19.875v-6.75zM9.75 8.625c0-.621.504-1.125 1.125-1.125h2.25c.621 0 1.125.504 1.125 1.125v11.25c0 .621-.504 1.125-1.125 1.125h-2.25a1.125 1.125 0 01-1.125-1.125V8.625zM16.5 4.125c0-.621.504-1.125 1.125-1.125h2.25C20.496 3 21 3.504 21 4.125v15.75c0 .621-.504 1.125-1.125 1.125h-2.25a1.125 1.125 0 01-1.125-1.125V4.125z" />
</svg>
),
label: '주 1회 진행 보고',
desc: '매주 개발 현황을 공유합니다. 중간에 사라지는 일 없음.',
accent: 'cyan',
highlight: null,
},
];
const PROOF_SERVICES = [
{
name: '쟁승메이드 (이 사이트)',
badge: '지금 보시는 중',
desc: '로그인·결제·AI 사주·관리자까지 1인 풀스택 개발. 이 사이트 자체가 포트폴리오입니다.',
href: '/freelance',
color: 'from-blue-500/20 to-blue-600/5',
dot: 'bg-blue-400',
tag: '풀스택 · Next.js · Supabase',
accentColor: 'text-blue-400',
},
{
name: 'AI 사주 분석 서비스',
badge: '운영 중',
desc: '생년월일 입력 → AI가 사주팔자 12가지 항목을 즉시 분석. 4,900원 단건 결제.',
href: '/saju',
color: 'from-violet-500/20 to-violet-600/5',
dot: 'bg-violet-400',
tag: 'AI · Gemini · 토스페이먼츠',
accentColor: 'text-violet-400',
},
{
name: 'AI 자동화 월 구독 키트',
badge: 'NEW',
desc: '업무 일지·이메일·SNS 등 6가지 자동화 도구 월 구독. 매달 새 도구 추가.',
href: '/services/ai-kit',
color: 'from-indigo-500/20 to-cyan-600/5',
dot: 'bg-indigo-400',
tag: '월 구독 · AI 자동화 · 19,900원',
accentColor: 'text-indigo-400',
},
];
const SUBSCRIPTION_SERVICES = [
{
id: 'ai-kit',
href: '/services/ai-kit',
color: '#4f46e5',
bg: '#eef2ff',
border: '#c7d2fe',
label: 'AI AUTOMATION KIT',
title: 'AI 자동화 키트',
desc: '업무 일지·이메일·SNS 등 6종 도구로 월 27시간 되찾기',
price: '19,900원/월',
type: '월 구독',
badge: 'NEW',
badgeColor: 'bg-indigo-600',
icon: (
<svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24" strokeWidth={1.5}>
<path strokeLinecap="round" strokeLinejoin="round" d="M13 10V3L4 14h7v7l9-11h-7z" />
</svg>
),
},
{
id: 'automation',
href: '/services/automation',
color: '#0891b2',
bg: '#cffafe',
border: '#a5f3fc',
label: 'AI · RPA AUTOMATION',
title: '업무 자동화',
desc: '엑셀·보고서·이메일 반복 업무를 코드로 없애드립니다',
price: '5만원~',
type: '프로젝트',
badge: 'HOT',
badgeColor: 'bg-cyan-600',
icon: (
<svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24" strokeWidth={1.5}>
<path strokeLinecap="round" strokeLinejoin="round" d="M9.594 3.94c.09-.542.56-.94 1.11-.94h2.593c.55 0 1.02.398 1.11.94l.213 1.281c.063.374.313.686.645.87.074.04.147.083.22.127.325.196.72.257 1.075.124l1.217-.456a1.125 1.125 0 011.37.49l1.296 2.247a1.125 1.125 0 01-.26 1.431l-1.003.827c-.293.241-.438.613-.43.992a7.723 7.723 0 010 .255c-.008.378.137.75.43.991l1.004.827c.424.35.534.955.26 1.43l-1.298 2.247a1.125 1.125 0 01-1.369.491l-1.217-.456c-.355-.133-.75-.072-1.076.124a6.47 6.47 0 01-.22.128c-.331.183-.581.495-.644.869l-.213 1.281c-.09.543-.56.94-1.11.94h-2.594c-.55 0-1.019-.398-1.11-.94l-.213-1.281c-.062-.374-.312-.686-.644-.87a6.52 6.52 0 01-.22-.127c-.325-.196-.72-.257-1.076-.124l-1.217.456a1.125 1.125 0 01-1.369-.49l-1.297-2.247a1.125 1.125 0 01.26-1.431l1.004-.827c.292-.24.437-.613.43-.991a6.932 6.932 0 010-.255c.007-.38-.138-.751-.43-.992l-1.004-.827a1.125 1.125 0 01-.26-1.43l1.297-2.247a1.125 1.125 0 011.37-.491l1.216.456c.356.133.751.072 1.076-.124.072-.044.146-.086.22-.128.332-.183.582-.495.644-.869l.214-1.28z" />
<path strokeLinecap="round" strokeLinejoin="round" d="M15 12a3 3 0 11-6 0 3 3 0 016 0z" />
</svg>
),
},
{
id: 'prompt',
href: '/services/prompt',
color: '#7c3aed',
bg: '#ede9fe',
border: '#ddd6fe',
label: 'PROMPT ENGINEERING',
title: '프롬프트 엔지니어링',
desc: 'ChatGPT·Claude 전용 업무 최적화 프롬프트 패키지',
price: '9,900원~',
type: '패키지',
badge: 'SALE',
badgeColor: 'bg-red-500',
icon: (
<svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24" strokeWidth={1.5}>
<path strokeLinecap="round" strokeLinejoin="round" d="M9.663 17h4.673M12 3v1m6.364 1.636l-.707.707M21 12h-1M4 12H3m3.343-5.657l-.707-.707m2.828 9.9a5 5 0 117.072 0l-.548.547A3.374 3.374 0 0014 18.469V19a2 2 0 11-4 0v-.531c0-.895-.356-1.754-.988-2.386l-.548-.547z" />
</svg>
),
},
{
id: 'saju',
href: '/saju',
color: '#db2777',
bg: '#fdf2f8',
border: '#fbcfe8',
label: 'AI SAJU ANALYSIS',
title: 'AI 사주 분석',
desc: '생년월일 입력 → AI가 사주팔자 12항목 즉시 분석',
price: '4,900원/건',
type: '단건 구매',
badge: null,
badgeColor: '',
icon: (
<svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24" strokeWidth={1.5}>
<path strokeLinecap="round" strokeLinejoin="round" d="M5 3v4M3 5h4M6 17v4m-2-2h4m5-16l2.286 6.857L21 12l-5.714 2.143L13 21l-2.286-6.857L5 12l5.714-2.143L13 3z" />
</svg>
),
},
];
const TECH_STACK = [
'Python', 'Java', 'Spring Boot', 'Next.js', 'React', 'TypeScript',
'PostgreSQL', 'Redis', 'Docker', 'AWS', 'Telegram API', 'FastAPI',
'Node.js', 'Supabase', 'Vercel', 'Git',
];
const STATS = [
{ value: '47+', label: '납품 완료' },
{ value: '7년', label: '개발 경력' },
{ value: '24h', label: '평균 견적 응답' },
{ value: '1개월', label: '무상 AS' },
];
export default function Home() {
const [modalOpen, setModalOpen] = useState(false);
return (
<div className="min-h-full bg-[#f1f5f9]">
<ContactModal
isOpen={modalOpen}
onClose={() => setModalOpen(false)}
service="외주 개발 문의"
checklist={[
'개발하고 싶은 서비스를 간략히 설명해주세요',
'희망 납품 일정과 예산 범위',
'참고할 만한 사이트나 레퍼런스',
'현재 운영 중인 시스템이 있다면 함께 알려주세요',
]}
accentColor="text-[#5ba4ff]"
headerFrom="#04102b"
headerTo="#0a2060"
/>
{/* ════════════════════════════════
SECTION 1 — HERO (Split layout)
════════════════════════════════ */}
<section className="relative overflow-hidden bg-[#04102b] px-6 py-16 lg:px-12 lg:py-20">
{/* 배경 그리드 */}
<div
className="absolute inset-0 opacity-[0.035]"
style={{
backgroundImage:
'linear-gradient(#4f8ef7 1px, transparent 1px), linear-gradient(90deg, #4f8ef7 1px, transparent 1px)',
backgroundSize: '48px 48px',
}}
/>
{/* 배경 글로우 */}
<div className="absolute top-0 right-0 w-[600px] h-[600px] rounded-full bg-blue-600/10 blur-[120px] -translate-y-1/3 translate-x-1/3 pointer-events-none" />
<div className="absolute bottom-0 left-1/4 w-[400px] h-[400px] rounded-full bg-violet-600/8 blur-[100px] translate-y-1/2 pointer-events-none" />
<div className="relative max-w-6xl mx-auto">
<div className="grid lg:grid-cols-[1fr_380px] gap-12 items-center">
{/* ── 좌측: 메인 카피 ── */}
<div>
{/* 뱃지 라인 */}
<div className="flex flex-wrap items-center gap-2 mb-6">
<div className="inline-flex items-center gap-2 bg-emerald-400/10 border border-emerald-400/20 text-emerald-300 text-xs font-semibold px-4 py-1.5 rounded-full tracking-wide">
<span className="w-1.5 h-1.5 rounded-full bg-emerald-400 animate-pulse" />
</div>
<div className="inline-flex items-center gap-1.5 bg-cyan-400/10 border border-cyan-400/20 text-cyan-300 text-xs font-semibold px-3 py-1.5 rounded-full tracking-wide">
<svg className="w-3 h-3" fill="none" stroke="currentColor" viewBox="0 0 24 24" strokeWidth={2.5}><path strokeLinecap="round" strokeLinejoin="round" d="M9.813 15.904L9 18.75l-.813-2.846a4.5 4.5 0 00-3.09-3.09L2.25 12l2.846-.813a4.5 4.5 0 003.09-3.09L9 5.25l.813 2.846a4.5 4.5 0 003.09 3.09L15.75 12l-2.846.813a4.5 4.5 0 00-3.09 3.09z" /></svg>
AI
</div>
</div>
<h1
className="text-4xl md:text-5xl lg:text-6xl font-extrabold text-white leading-[1.15] tracking-tight mb-6"
style={{ wordBreak: 'keep-all' }}
>
<br />
<span
className="text-transparent bg-clip-text"
style={{
backgroundImage: 'linear-gradient(135deg, #5ba4ff 0%, #818cf8 60%, #a78bfa 100%)',
}}
>
</span>
<br />
</h1>
<p
className="text-blue-200/60 text-base md:text-lg leading-relaxed mb-4 max-w-lg"
style={{ wordBreak: 'keep-all' }}
>
, , , 1 AS까지 .
</p>
<div className="flex items-start gap-2.5 bg-cyan-400/8 border border-cyan-400/15 rounded-xl px-4 py-3 mb-8 max-w-lg">
<svg className="w-4 h-4 text-cyan-400 flex-shrink-0 mt-0.5" fill="none" stroke="currentColor" viewBox="0 0 24 24" strokeWidth={2}><path strokeLinecap="round" strokeLinejoin="round" d="M9.813 15.904L9 18.75l-.813-2.846a4.5 4.5 0 00-3.09-3.09L2.25 12l2.846-.813a4.5 4.5 0 003.09-3.09L9 5.25l.813 2.846a4.5 4.5 0 003.09 3.09L15.75 12l-2.846.813a4.5 4.5 0 00-3.09 3.09z" /></svg>
<p className="text-cyan-200/70 text-sm leading-relaxed" style={{ wordBreak: 'keep-all' }}>
<span className="text-cyan-300 font-bold">AI </span> , , · AI로 . .
</p>
</div>
{/* CTA */}
<div className="flex flex-wrap gap-3 mb-10">
<button
onClick={() => setModalOpen(true)}
className="inline-flex items-center gap-2.5 bg-[#1a56db] hover:bg-[#1e4fc2] active:scale-[0.98] text-white px-7 py-3.5 rounded-xl font-bold text-sm shadow-lg shadow-blue-900/40"
style={{ transition: 'all 0.4s cubic-bezier(0.16, 1, 0.3, 1)' }}
>
<svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24" strokeWidth={2}>
<path strokeLinecap="round" strokeLinejoin="round" d="M8 12h.01M12 12h.01M16 12h.01M21 12c0 4.418-4.03 8-9 8a9.863 9.863 0 01-4.255-.949L3 20l1.395-3.72C3.512 15.042 3 13.574 3 12c0-4.418 4.03-8 9-8s9 3.582 9 8z" />
</svg>
(24h )
</button>
<Link
href="/freelance"
className="inline-flex items-center gap-2 bg-white/5 border border-white/10 text-blue-200 hover:bg-white/10 px-6 py-3.5 rounded-xl font-semibold text-sm"
style={{ transition: 'all 0.4s cubic-bezier(0.16, 1, 0.3, 1)' }}
>
</Link>
</div>
{/* Stats */}
<div
className="grid grid-cols-4 gap-px bg-white/5 rounded-2xl overflow-hidden border border-white/8"
style={{ fontVariantNumeric: 'tabular-nums' }}
>
{STATS.map((s) => (
<div key={s.label} className="bg-[#071540]/60 px-4 py-4 text-center">
<div className="text-xl md:text-2xl font-extrabold text-white tracking-tight">{s.value}</div>
<div className="text-blue-300/50 text-[11px] mt-0.5 font-medium leading-tight" style={{ wordBreak: 'keep-all' }}>{s.label}</div>
</div>
))}
</div>
</div>
{/* ── 우측: 신뢰 카드 ── */}
<div className="hidden lg:block">
<div className="bg-white/5 border border-white/10 rounded-2xl p-5 backdrop-blur-sm">
<div className="flex items-center justify-between mb-4">
<span className="text-white/50 text-xs font-semibold uppercase tracking-widest"> </span>
<span className="flex items-center gap-1.5 text-emerald-400 text-xs font-bold">
<span className="w-1.5 h-1.5 rounded-full bg-emerald-400 animate-pulse" />
LIVE
</span>
</div>
<div className="space-y-2">
{PROOF_SERVICES.map((s) => (
<Link
key={s.name}
href={s.href}
className="flex items-center gap-3 bg-white/5 hover:bg-white/10 border border-white/8 rounded-xl p-3 group"
style={{ transition: 'all 0.3s ease-out' }}
>
<div className={`w-2 h-2 rounded-full flex-shrink-0 ${s.dot} animate-pulse`} />
<div className="flex-1 min-w-0">
<div className="text-white font-semibold text-xs leading-tight">{s.name}</div>
<div className="text-white/30 text-[10px] mt-0.5 truncate">{s.tag}</div>
</div>
<span className={`text-[9px] font-bold px-1.5 py-0.5 rounded-full flex-shrink-0 ${s.badge === 'NEW' ? 'text-indigo-300 bg-indigo-400/15 border border-indigo-400/25' : s.badge === '운영 중' ? 'text-violet-300 bg-violet-400/15 border border-violet-400/25' : 'text-emerald-400 bg-emerald-400/10 border border-emerald-400/20'}`}>{s.badge}</span>
</Link>
))}
</div>
<div className="mt-4 pt-4 border-t border-white/8 text-center">
<p className="text-white/30 text-xs"> </p>
<a href="https://jaengseung-made.com" className="text-blue-400 text-xs font-semibold mt-0.5 block hover:text-blue-300 transition">
jaengseung-made.com
</a>
</div>
</div>
{/* 연락처 */}
<div className="mt-3 grid grid-cols-2 gap-2">
<a href="mailto:bgg8988@gmail.com"
className="flex items-center gap-2 bg-white/5 border border-white/8 rounded-xl px-3 py-2.5 hover:bg-white/10 transition group">
<svg className="w-3.5 h-3.5 text-blue-400 flex-shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24" strokeWidth={2}>
<path strokeLinecap="round" strokeLinejoin="round" d="M21.75 6.75v10.5a2.25 2.25 0 01-2.25 2.25h-15a2.25 2.25 0 01-2.25-2.25V6.75m19.5 0A2.25 2.25 0 0019.5 4.5h-15a2.25 2.25 0 00-2.25 2.25m19.5 0v.243a2.25 2.25 0 01-1.07 1.916l-7.5 4.615a2.25 2.25 0 01-2.36 0L3.32 8.91a2.25 2.25 0 01-1.07-1.916V6.75" />
</svg>
<span className="text-white/50 text-[11px] truncate">bgg8988@gmail.com</span>
</a>
<a href="tel:01039071392"
className="flex items-center gap-2 bg-white/5 border border-white/8 rounded-xl px-3 py-2.5 hover:bg-white/10 transition">
<svg className="w-3.5 h-3.5 text-blue-400 flex-shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24" strokeWidth={2}>
<path strokeLinecap="round" strokeLinejoin="round" d="M2.25 6.75c0 8.284 6.716 15 15 15h2.25a2.25 2.25 0 002.25-2.25v-1.372c0-.516-.351-.966-.852-1.091l-4.423-1.106c-.44-.11-.902.055-1.173.417l-.97 1.293c-.282.376-.769.542-1.21.38a12.035 12.035 0 01-7.143-7.143c-.162-.441.004-.928.38-1.21l1.293-.97c.363-.271.527-.734.417-1.173L6.963 3.102a1.125 1.125 0 00-1.091-.852H4.5A2.25 2.25 0 002.25 4.5v2.25z" />
</svg>
<span className="text-white/50 text-[11px]">010-3907-1392</span>
</a>
</div>
</div>
</div>
</div>
</section>
{/* ════════════════════════════════
SECTION 2 — 신뢰 증거 Bento Grid
════════════════════════════════ */}
<section className="px-6 py-16 lg:px-12 lg:py-20">
<div className="max-w-5xl mx-auto">
<div className="mb-10">
<p className="text-[#1a56db] text-xs font-bold uppercase tracking-widest mb-2">WHY US</p>
<h2
className="text-2xl md:text-4xl font-extrabold text-[#04102b] tracking-tight leading-tight"
style={{ wordBreak: 'keep-all', textWrap: 'balance' } as React.CSSProperties}
>
, ,<br />
</h2>
<p className="text-slate-500 text-sm mt-3 max-w-lg" style={{ wordBreak: 'keep-all' }}>
?<br />
.
</p>
</div>
{/* Bento Grid */}
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
{/* 계약서 — 가장 큰 카드 (lg에서 2열 차지) */}
<div className="lg:col-span-2 bg-gradient-to-br from-[#04102b] to-[#0a1f5c] rounded-2xl p-7 relative overflow-hidden border border-blue-900/40">
<div className="absolute right-0 top-0 w-48 h-48 rounded-full bg-blue-500/10 blur-3xl -translate-y-1/3 translate-x-1/4 pointer-events-none" />
<div className="relative">
<div className="w-12 h-12 rounded-xl bg-blue-400/15 border border-blue-400/20 flex items-center justify-center text-blue-400 mb-5">
<svg className="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24" strokeWidth={1.5}>
<path strokeLinecap="round" strokeLinejoin="round" d="M9 12h3.75M9 15h3.75M9 18h3.75m3 .75H18a2.25 2.25 0 002.25-2.25V6.108c0-1.135-.845-2.098-1.976-2.192a48.424 48.424 0 00-1.123-.08m-5.801 0c-.065.21-.1.433-.1.664 0 .414.336.75.75.75h4.5a.75.75 0 00.75-.75 2.25 2.25 0 00-.1-.664m-5.8 0A2.251 2.251 0 0113.5 2.25H15c1.012 0 1.867.668 2.15 1.586m-5.8 0c-.376.023-.75.05-1.124.08C9.095 4.01 8.25 4.973 8.25 6.108V8.25m0 0H4.875c-.621 0-1.125.504-1.125 1.125v11.25c0 .621.504 1.125 1.125 1.125h9.75c.621 0 1.125-.504 1.125-1.125V9.375c0-.621-.504-1.125-1.125-1.125H8.25z" />
</svg>
</div>
<h3 className="text-white text-xl font-extrabold mb-2"> , </h3>
<p className="text-blue-200/50 text-sm leading-relaxed mb-5" style={{ wordBreak: 'keep-all' }}>
30%, , . . .
</p>
<div className="inline-flex items-center gap-2.5 bg-red-500/15 border border-red-400/25 rounded-xl px-4 py-2.5">
<svg className="w-4 h-4 text-red-400 flex-shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24" strokeWidth={2}>
<path strokeLinecap="round" strokeLinejoin="round" d="M12 9v3.75m-9.303 3.376c-.866 1.5.217 3.374 1.948 3.374h14.71c1.73 0 2.813-1.874 1.948-3.374L13.949 3.378c-.866-1.5-3.032-1.5-3.898 0L2.697 16.126zM12 15.75h.007v.008H12v-.008z" />
</svg>
<span className="text-red-300 text-sm font-bold"> 10 </span>
</div>
</div>
</div>
{/* 소스코드 */}
<div className="bg-white rounded-2xl p-6 border border-slate-200 shadow-sm hover:shadow-md hover:shadow-violet-100 hover:-translate-y-0.5"
style={{ transition: 'all 0.4s cubic-bezier(0.16, 1, 0.3, 1)' }}>
<div className="w-10 h-10 rounded-xl bg-violet-50 border border-violet-200 flex items-center justify-center text-violet-600 mb-4">
<svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24" strokeWidth={1.5}>
<path strokeLinecap="round" strokeLinejoin="round" d="M17.25 6.75L22.5 12l-5.25 5.25m-10.5 0L1.5 12l5.25-5.25m7.5-3l-4.5 16.5" />
</svg>
</div>
<h3 className="font-extrabold text-[#04102b] text-base mb-2"> 100% </h3>
<p className="text-slate-500 text-sm leading-relaxed" style={{ wordBreak: 'keep-all' }}> . .</p>
<div className="mt-4 inline-block text-xs font-bold text-violet-600 bg-violet-50 border border-violet-200 px-2 py-1 rounded-lg"> </div>
</div>
{/* 1개월 AS */}
<div className="bg-white rounded-2xl p-6 border border-slate-200 shadow-sm hover:shadow-md hover:shadow-emerald-100 hover:-translate-y-0.5"
style={{ transition: 'all 0.4s cubic-bezier(0.16, 1, 0.3, 1)' }}>
<div className="w-10 h-10 rounded-xl bg-emerald-50 border border-emerald-200 flex items-center justify-center text-emerald-600 mb-4">
<svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24" strokeWidth={1.5}>
<path strokeLinecap="round" strokeLinejoin="round" d="M9 12.75L11.25 15 15 9.75m-3-7.036A11.959 11.959 0 013.598 6 11.99 11.99 0 003 9.749c0 5.592 3.824 10.29 9 11.623 5.176-1.332 9-6.03 9-11.622 0-1.31-.21-2.571-.598-3.751h-.152c-3.196 0-6.1-1.248-8.25-3.285z" />
</svg>
</div>
<h3 className="font-extrabold text-[#04102b] text-base mb-2">1 AS</h3>
<p className="text-slate-500 text-sm leading-relaxed" style={{ wordBreak: 'keep-all' }}> 1 . .</p>
<div className="mt-4 inline-block text-xs font-bold text-emerald-600 bg-emerald-50 border border-emerald-200 px-2 py-1 rounded-lg"> </div>
</div>
{/* 주 1회 보고 */}
<div className="bg-white rounded-2xl p-6 border border-slate-200 shadow-sm hover:shadow-md hover:shadow-cyan-100 hover:-translate-y-0.5"
style={{ transition: 'all 0.4s cubic-bezier(0.16, 1, 0.3, 1)' }}>
<div className="w-10 h-10 rounded-xl bg-cyan-50 border border-cyan-200 flex items-center justify-center text-cyan-600 mb-4">
<svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24" strokeWidth={1.5}>
<path strokeLinecap="round" strokeLinejoin="round" d="M3 13.125C3 12.504 3.504 12 4.125 12h2.25c.621 0 1.125.504 1.125 1.125v6.75C7.5 20.496 6.996 21 6.375 21h-2.25A1.125 1.125 0 013 19.875v-6.75zM9.75 8.625c0-.621.504-1.125 1.125-1.125h2.25c.621 0 1.125.504 1.125 1.125v11.25c0 .621-.504 1.125-1.125 1.125h-2.25a1.125 1.125 0 01-1.125-1.125V8.625zM16.5 4.125c0-.621.504-1.125 1.125-1.125h2.25C20.496 3 21 3.504 21 4.125v15.75c0 .621-.504 1.125-1.125 1.125h-2.25a1.125 1.125 0 01-1.125-1.125V4.125z" />
</svg>
</div>
<h3 className="font-extrabold text-[#04102b] text-base mb-2"> 1 </h3>
<p className="text-slate-500 text-sm leading-relaxed" style={{ wordBreak: 'keep-all' }}> . .</p>
<div className="mt-4 inline-block text-xs font-bold text-cyan-600 bg-cyan-50 border border-cyan-200 px-2 py-1 rounded-lg"> </div>
</div>
</div>
{/* 외주 CTA */}
<div className="mt-6">
<Link
href="/freelance"
className="group flex items-center justify-between bg-white border-2 border-[#1a56db]/20 hover:border-[#1a56db]/50 hover:bg-[#f0f5ff] rounded-2xl px-7 py-5"
style={{ transition: 'all 0.4s cubic-bezier(0.16, 1, 0.3, 1)' }}
>
<div>
<div className="font-extrabold text-[#04102b] text-base"> · </div>
<div className="text-slate-500 text-sm mt-0.5"> 47 · 6 </div>
</div>
<div className="w-10 h-10 rounded-xl bg-[#1a56db] flex items-center justify-center text-white flex-shrink-0 group-hover:scale-110"
style={{ transition: 'transform 0.4s cubic-bezier(0.16, 1, 0.3, 1)' }}>
<svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24" strokeWidth={2}>
<path strokeLinecap="round" strokeLinejoin="round" d="M13.5 4.5L21 12m0 0l-7.5 7.5M21 12H3" />
</svg>
</div>
</Link>
</div>
</div>
</section>
{/* ════════════════════════════════
SECTION 3 — "직접 만든 서비스가 증거"
════════════════════════════════ */}
<section className="relative bg-[#04102b] px-6 py-16 lg:px-12 lg:py-20 overflow-hidden">
<div className="absolute inset-0 opacity-[0.03]"
style={{ backgroundImage: 'radial-gradient(circle at 1px 1px, #4f8ef7 1px, transparent 0)', backgroundSize: '32px 32px' }} />
<div className="absolute right-0 top-1/2 w-96 h-96 rounded-full bg-blue-500/8 blur-3xl -translate-y-1/2 translate-x-1/3 pointer-events-none" />
<div className="relative max-w-5xl mx-auto">
<div className="text-center mb-10">
<p className="text-blue-400/70 text-xs font-bold uppercase tracking-widest mb-2">PROOF OF WORK</p>
<h2 className="text-2xl md:text-4xl font-extrabold text-white tracking-tight" style={{ wordBreak: 'keep-all' }}>
URL로
</h2>
<p className="text-blue-200/40 text-sm mt-3 max-w-lg mx-auto" style={{ wordBreak: 'keep-all' }}>
. .
</p>
</div>
<div className="grid md:grid-cols-3 gap-4">
{PROOF_SERVICES.map((s) => (
<Link
key={s.name}
href={s.href}
className={`relative bg-gradient-to-br ${s.color} border border-white/10 rounded-2xl p-6 hover:border-white/30 hover:-translate-y-1 group overflow-hidden`}
style={{ transition: 'all 0.4s cubic-bezier(0.16, 1, 0.3, 1)' }}
>
{/* 배경 글로우 */}
<div className={`absolute top-0 right-0 w-24 h-24 rounded-full blur-2xl opacity-20 pointer-events-none ${s.dot}`}
style={{ background: 'currentColor' }} />
<div className="relative">
<div className="flex items-center gap-2 mb-5">
<div className={`w-2 h-2 rounded-full ${s.dot} animate-pulse`} />
<span className={`text-xs font-extrabold uppercase tracking-wider ${s.accentColor} opacity-70`}>{s.badge}</span>
</div>
<h3 className="text-white font-extrabold text-base mb-2 leading-snug" style={{ wordBreak: 'keep-all' }}>{s.name}</h3>
<p className="text-white/40 text-xs leading-relaxed mb-5" style={{ wordBreak: 'keep-all' }}>{s.desc}</p>
<div className="flex items-center justify-between">
<span className="text-white/30 text-[10px] font-medium">{s.tag}</span>
<span className={`${s.accentColor} opacity-60 group-hover:opacity-100 text-xs font-bold flex items-center gap-1`} style={{ transition: 'opacity 0.3s ease' }}>
</span>
</div>
</div>
</Link>
))}
</div>
</div>
</section>
{/* ════════════════════════════════
SECTION 4 — 구독/설치형 서비스 (보조)
════════════════════════════════ */}
<section className="px-6 py-16 lg:px-12 lg:py-20">
<div className="max-w-5xl mx-auto">
{/* 레이블 분리 */}
<div className="flex items-center gap-4 mb-6">
<div className="h-px flex-1 bg-slate-200" />
<div className="flex items-center gap-2">
<div className="w-1.5 h-1.5 rounded-full bg-slate-300" />
<p className="text-slate-400 text-xs font-bold uppercase tracking-widest"> · </p>
<div className="w-1.5 h-1.5 rounded-full bg-slate-300" />
</div>
<div className="h-px flex-1 bg-slate-200" />
</div>
<p className="text-center text-slate-500 text-sm mb-8" style={{ wordBreak: 'keep-all' }}>
, .<br />
"이런 걸 만들어드릴 수 있습니다" .
</p>
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-3">
{SUBSCRIPTION_SERVICES.map((svc) => (
<Link
key={svc.id}
href={svc.href}
className="bg-white rounded-2xl border border-slate-200 p-5 hover:shadow-lg hover:-translate-y-1 relative group flex flex-col"
style={{ transition: 'all 0.4s cubic-bezier(0.16, 1, 0.3, 1)' }}
>
{svc.badge && (
<span className={`absolute top-3 right-3 ${svc.badgeColor} text-white text-[10px] font-bold px-1.5 py-0.5 rounded-md`}>{svc.badge}</span>
)}
{/* 아이콘 */}
<div
className="w-10 h-10 rounded-xl flex items-center justify-center mb-4 flex-shrink-0"
style={{ backgroundColor: svc.bg, border: `1px solid ${svc.border}`, color: svc.color }}
>
{svc.icon}
</div>
{/* 라벨 */}
<div className="text-[10px] font-bold mb-1 tracking-wider" style={{ color: svc.color }}>{svc.label}</div>
{/* 제목 */}
<div className="font-extrabold text-[#04102b] text-sm mb-2" style={{ wordBreak: 'keep-all' }}>{svc.title}</div>
{/* 설명 */}
<p className="text-slate-400 text-[11px] leading-relaxed mb-3 flex-1" style={{ wordBreak: 'keep-all' }}>{svc.desc}</p>
{/* 가격 + 유형 */}
<div className="flex items-center justify-between mb-3">
<span className="font-extrabold text-sm" style={{ color: svc.color }}>{svc.price}</span>
<span className="text-[10px] px-1.5 py-0.5 rounded-md font-bold" style={{ color: svc.color, backgroundColor: svc.bg, border: `1px solid ${svc.border}` }}>{svc.type}</span>
</div>
<div className="pt-3 border-t border-slate-100 text-[#1a56db] text-xs font-semibold group-hover:gap-2 flex items-center gap-1" style={{ transition: 'gap 0.3s ease' }}>
<span></span>
</div>
</Link>
))}
</div>
</div>
</section>
{/* ════════════════════════════════
SECTION 4.5 — 무료 체험 후기 수집 배너
════════════════════════════════ */}
<section className="px-6 py-6 lg:px-12">
<div className="max-w-5xl mx-auto">
<div className="relative bg-gradient-to-r from-cyan-950 to-blue-950 border border-cyan-500/20 rounded-2xl px-7 py-5 overflow-hidden">
<div className="absolute right-0 top-0 w-64 h-full opacity-10 pointer-events-none">
<div className="w-full h-full bg-gradient-to-l from-cyan-400 to-transparent" />
</div>
<div className="relative flex flex-col sm:flex-row items-start sm:items-center justify-between gap-4">
<div className="flex items-start gap-3">
<div className="w-9 h-9 rounded-xl bg-cyan-400/15 border border-cyan-400/25 flex items-center justify-center flex-shrink-0 mt-0.5">
<svg className="w-4.5 h-4.5 text-cyan-400" fill="none" stroke="currentColor" viewBox="0 0 24 24" strokeWidth={2}>
<path strokeLinecap="round" strokeLinejoin="round" d="M12 9v3.75m-9.303 3.376c-.866 1.5.217 3.374 1.948 3.374h14.71c1.73 0 2.813-1.874 1.948-3.374L13.949 3.378c-.866-1.5-3.032-1.5-3.898 0L2.697 16.126zM12 15.75h.007v.008H12v-.008z" />
</svg>
</div>
<div>
<div className="flex items-center gap-2 mb-0.5">
<span className="text-xs font-extrabold bg-red-500 text-white px-2 py-0.5 rounded-md"> 3</span>
<span className="text-cyan-300 text-xs font-bold uppercase tracking-wider"> · </span>
</div>
<p className="text-white font-extrabold text-base leading-snug" style={{ wordBreak: 'keep-all' }}>
AI
</p>
<p className="text-cyan-200/50 text-xs mt-1" style={{ wordBreak: 'keep-all' }}>
ChatGPT 1 . <span className="text-cyan-300 font-bold">2 </span>
</p>
</div>
</div>
<a
href="https://open.kakao.com/o/s9stoNvb"
target="_blank"
rel="noopener noreferrer"
className="flex-shrink-0 inline-flex items-center gap-2 bg-cyan-400 hover:bg-cyan-300 text-cyan-950 font-extrabold text-sm px-5 py-2.5 rounded-xl"
style={{ transition: 'all 0.3s cubic-bezier(0.16, 1, 0.3, 1)' }}
>
</a>
</div>
</div>
</div>
</section>
{/* ════════════════════════════════
SECTION 5 — 기술 스택 마퀴
════════════════════════════════ */}
<section className="py-10 overflow-hidden border-y border-slate-200 bg-white">
<div className="flex gap-6 animate-marquee whitespace-nowrap" style={{ width: 'max-content' }}>
{[...TECH_STACK, ...TECH_STACK].map((tech, i) => (
<span
key={`${tech}-${i}`}
className="inline-flex items-center gap-2 text-slate-400 text-sm font-semibold"
>
<span className="w-1 h-1 rounded-full bg-slate-300" />
{tech}
</span>
))}
</div>
<style>{`
@keyframes marquee {
0% { transform: translateX(0); }
100% { transform: translateX(-50%); }
}
.animate-marquee {
animation: marquee 20s linear infinite;
}
`}</style>
</section>
{/* ════════════════════════════════
SECTION 5.5 — 콘텐츠 / 인사이트
════════════════════════════════ */}
<section className="px-6 py-12 lg:px-12 bg-white border-y border-slate-100">
<div className="max-w-5xl mx-auto">
<div className="flex items-end justify-between mb-6">
<div>
<p className="text-[#1a56db] text-xs font-bold uppercase tracking-widest mb-1">INSIGHTS</p>
<h2 className="text-xl md:text-2xl font-extrabold text-[#04102b]">AI </h2>
</div>
<a
href="https://blog.naver.com"
target="_blank"
rel="noopener noreferrer"
className="text-xs font-semibold text-slate-400 hover:text-[#1a56db] transition flex items-center gap-1"
>
</a>
</div>
<div className="grid sm:grid-cols-2 lg:grid-cols-3 gap-4">
{[
{ tag: '업무 자동화', title: '업무 자동화 외주 맡기기 전에 반드시 확인할 5가지', desc: '계약서, 소스코드 인도, 납기 명시. 피해의 90%는 이 세 가지 없어서 생깁니다.', color: 'bg-cyan-50 border-cyan-100', tagColor: 'text-cyan-600 bg-cyan-100' },
{ tag: 'ChatGPT 활용', title: 'ChatGPT 프롬프트 잘 쓰는 법 — RCTF 공식', desc: 'Role·Context·Task·Format 네 가지를 넣으면 답변 퀄리티가 3배 올라갑니다.', color: 'bg-violet-50 border-violet-100', tagColor: 'text-violet-600 bg-violet-100' },
{ tag: '개발자 부업', title: '대기업 현직 개발자가 부업 6개월 해본 솔직한 후기', desc: '잘 된 점, 힘든 점, 현실적인 수익까지. 포장 없이 공유합니다.', color: 'bg-blue-50 border-blue-100', tagColor: 'text-blue-600 bg-blue-100' },
].map((post) => (
<div key={post.title} className={`rounded-2xl border p-5 ${post.color} hover:-translate-y-0.5 transition-transform`}>
<span className={`text-xs font-bold px-2 py-0.5 rounded-md ${post.tagColor}`}>{post.tag}</span>
<h3 className="font-extrabold text-[#04102b] text-sm mt-3 mb-2 leading-snug" style={{ wordBreak: 'keep-all' }}>{post.title}</h3>
<p className="text-slate-500 text-xs leading-relaxed" style={{ wordBreak: 'keep-all' }}>{post.desc}</p>
<div className="mt-3 text-xs font-semibold text-[#1a56db] flex items-center gap-1">
</div>
</div>
))}
</div>
<p className="text-center text-slate-400 text-xs mt-4">
</p>
</div>
</section>
{/* ════════════════════════════════
SECTION 6 — 최종 CTA
════════════════════════════════ */}
<section className="px-6 py-16 lg:px-12 lg:py-20">
<div className="max-w-3xl mx-auto">
<div className="relative bg-gradient-to-br from-[#04102b] to-[#0a1f5c] rounded-3xl border border-blue-900/40 px-8 py-12 text-center overflow-hidden">
<div className="absolute inset-0 opacity-[0.03]"
style={{ backgroundImage: 'linear-gradient(#4f8ef7 1px, transparent 1px), linear-gradient(90deg, #4f8ef7 1px, transparent 1px)', backgroundSize: '40px 40px' }} />
<div className="absolute top-0 right-1/4 w-64 h-64 rounded-full bg-blue-500/10 blur-3xl pointer-events-none" />
<div className="relative">
<div className="inline-flex items-center gap-2 bg-emerald-400/10 border border-emerald-400/20 text-emerald-300 text-xs font-semibold px-4 py-1.5 rounded-full mb-5">
<span className="w-1.5 h-1.5 rounded-full bg-emerald-400 animate-pulse" />
</div>
<h2
className="text-2xl md:text-3xl font-extrabold text-white mb-3 tracking-tight leading-tight"
style={{ wordBreak: 'keep-all', textWrap: 'balance' } as React.CSSProperties}
>
</h2>
<p className="text-blue-200/40 text-sm mb-8 leading-relaxed" style={{ wordBreak: 'keep-all' }}>
, , .<br />
24 .
</p>
<div className="flex flex-col sm:flex-row items-center justify-center gap-3">
<button
onClick={() => setModalOpen(true)}
className="inline-flex items-center gap-2.5 bg-[#1a56db] hover:bg-[#1e4fc2] active:scale-[0.98] text-white px-8 py-4 rounded-xl font-bold text-base shadow-xl shadow-blue-900/40"
style={{ transition: 'all 0.4s cubic-bezier(0.16, 1, 0.3, 1)' }}
>
( )
</button>
<div className="flex items-center gap-4 text-blue-200/30 text-xs">
<span>bgg8988@gmail.com</span>
<span>·</span>
<span>010-3907-1392</span>
</div>
</div>
</div>
</div>
</div>
</section>
</div>
);
}