style(mypage): 브랜드 블루 → 보라/슬레이트 일괄 토큰 마이그레이션

Liquid Glass 메인 surface와 톤 정렬:
- 본문 배경 #f0f5ff → slate-50
- 액센트 #1a56db → violet-600 (탭 active, 버튼, 링크)
- 카드 보더 #dbe8ff → slate-200
- 다크 카드(프로젝트 헤더) #04102b → #060e20 (kx-surface 일관)
- 강조 박스 blue-50/200 → violet-50/200
- 다크 위 텍스트 blue-300/60 → white/50 등
- 탭 button min-w-[100px] 추가 (모바일 wrap 시 텍스트 잘림 방지)

의미 색(emerald/orange/amber/red/rose/pink/cyan/sky)는 시그널이므로 보존.
프로젝트 헤더 in_progress 상태 핀은 sky 계열로 이전(브랜드 블루 잔존 제거).
Task 4에서 추가된 새 코드(AI 스튜디오 카드 등)도 함께 마이그레이션.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-04-28 04:08:35 +09:00
parent 4dfea6cdc8
commit dda7b0e16a

View File

@@ -268,8 +268,8 @@ export default function MyPage() {
if (loading) { if (loading) {
return ( return (
<div className="min-h-full flex items-center justify-center bg-[#f0f5ff]"> <div className="min-h-full flex items-center justify-center bg-slate-50">
<div className="w-8 h-8 border-2 border-blue-600 border-t-transparent rounded-full animate-spin" /> <div className="w-8 h-8 border-2 border-violet-600 border-t-transparent rounded-full animate-spin" />
</div> </div>
); );
} }
@@ -293,7 +293,7 @@ export default function MyPage() {
]; ];
return ( return (
<div className="min-h-full bg-[#f0f5ff]"> <div className="min-h-screen bg-slate-50">
{/* 텔레그램 가이드 모달 */} {/* 텔레그램 가이드 모달 */}
{showTelegramGuide && ( {showTelegramGuide && (
<TelegramGuideModal onClose={() => setShowTelegramGuide(false)} /> <TelegramGuideModal onClose={() => setShowTelegramGuide(false)} />
@@ -328,15 +328,15 @@ export default function MyPage() {
<div className="px-6 py-8 max-w-4xl mx-auto"> <div className="px-6 py-8 max-w-4xl mx-auto">
{/* 탭 */} {/* 탭 */}
<div className="flex flex-wrap gap-1 bg-white border border-[#dbe8ff] rounded-xl p-1 mb-6"> <div className="flex flex-wrap gap-1 bg-white border border-slate-200 rounded-xl p-1 mb-6">
{tabs.map((t) => ( {tabs.map((t) => (
<button <button
key={t.key} key={t.key}
onClick={() => setTab(t.key)} onClick={() => setTab(t.key)}
className={`flex-1 flex items-center justify-center gap-1.5 px-4 py-2 rounded-lg text-sm font-semibold transition-all ${ className={`flex-1 min-w-[100px] flex items-center justify-center gap-1.5 px-4 py-2 rounded-lg text-sm font-semibold transition-all ${
tab === t.key tab === t.key
? 'bg-[#1a56db] text-white shadow' ? 'bg-violet-600 text-white shadow'
: 'text-slate-500 hover:text-slate-700' : 'text-slate-500 hover:text-violet-600'
}`} }`}
> >
{t.label} {t.label}
@@ -356,25 +356,25 @@ export default function MyPage() {
{/* 내 정보 */} {/* 내 정보 */}
{tab === 'profile' && ( {tab === 'profile' && (
<div className="space-y-4"> <div className="space-y-4">
<div className="bg-white rounded-2xl border border-[#dbe8ff] p-6"> <div className="bg-white rounded-2xl border border-slate-200 p-6">
<h2 className="font-bold text-[#04102b] mb-4 flex items-center gap-2"> <h2 className="font-bold text-slate-900 mb-4 flex items-center gap-2">
<div className="w-1 h-5 bg-[#1a56db] rounded-full" /> <div className="w-1 h-5 bg-violet-600 rounded-full" />
</h2> </h2>
<div className="space-y-3"> <div className="space-y-3">
<div className="flex items-center justify-between py-3 border-b border-slate-100"> <div className="flex items-center justify-between py-3 border-b border-slate-100">
<span className="text-sm text-slate-500"></span> <span className="text-sm text-slate-500"></span>
<span className="text-sm font-semibold text-[#04102b]">{user.email}</span> <span className="text-sm font-semibold text-slate-900">{user.email}</span>
</div> </div>
<div className="flex items-center justify-between py-3 border-b border-slate-100"> <div className="flex items-center justify-between py-3 border-b border-slate-100">
<span className="text-sm text-slate-500"> </span> <span className="text-sm text-slate-500"> </span>
<span className="text-sm font-semibold text-[#04102b] capitalize"> <span className="text-sm font-semibold text-slate-900 capitalize">
{user.app_metadata?.provider === 'google' ? 'Google' : '이메일'} {user.app_metadata?.provider === 'google' ? 'Google' : '이메일'}
</span> </span>
</div> </div>
<div className="flex items-center justify-between py-3"> <div className="flex items-center justify-between py-3">
<span className="text-sm text-slate-500"></span> <span className="text-sm text-slate-500"></span>
<span className="text-sm font-semibold text-[#04102b]"> <span className="text-sm font-semibold text-slate-900">
{new Date(user.created_at).toLocaleDateString('ko-KR', { year: 'numeric', month: 'long', day: 'numeric' })} {new Date(user.created_at).toLocaleDateString('ko-KR', { year: 'numeric', month: 'long', day: 'numeric' })}
</span> </span>
</div> </div>
@@ -383,30 +383,30 @@ export default function MyPage() {
{/* 구독 중인 서비스 - 요약 (탭으로 유도) */} {/* 구독 중인 서비스 - 요약 (탭으로 유도) */}
{activeSubs.length > 0 && ( {activeSubs.length > 0 && (
<div className="bg-blue-50 rounded-2xl border border-blue-200 p-5 flex items-center justify-between gap-3"> <div className="bg-violet-50 rounded-2xl border border-violet-200 p-5 flex items-center justify-between gap-3">
<div className="flex items-center gap-3"> <div className="flex items-center gap-3">
<span className="text-2xl">🎟</span> <span className="text-2xl">🎟</span>
<div> <div>
<div className="text-sm font-bold text-[#04102b]"> <div className="text-sm font-bold text-slate-900">
</div> </div>
<div className="text-xs text-blue-600 mt-0.5"> <div className="text-xs text-violet-600 mt-0.5">
{Math.max(0, Math.ceil((new Date(activeSubs[0].expires_at).getTime() - Date.now()) / 86400000))} {Math.max(0, Math.ceil((new Date(activeSubs[0].expires_at).getTime() - Date.now()) / 86400000))}
{activeSubs[0].status === 'cancelled' && ' · 해지 예정'} {activeSubs[0].status === 'cancelled' && ' · 해지 예정'}
</div> </div>
</div> </div>
</div> </div>
<button onClick={() => setTab('subscription')} <button onClick={() => setTab('subscription')}
className="text-xs font-bold text-blue-700 bg-blue-100 hover:bg-blue-200 px-3 py-1.5 rounded-lg transition"> className="text-xs font-bold text-violet-700 bg-violet-100 hover:bg-violet-200 px-3 py-1.5 rounded-lg transition">
</button> </button>
</div> </div>
)} )}
{/* 텔레그램 연동 카드 */} {/* 텔레그램 연동 카드 */}
<div className="bg-white rounded-2xl border border-[#dbe8ff] p-6"> <div className="bg-white rounded-2xl border border-slate-200 p-6">
<h2 className="font-bold text-[#04102b] mb-4 flex items-center gap-2"> <h2 className="font-bold text-slate-900 mb-4 flex items-center gap-2">
<div className="w-1 h-5 bg-[#1a56db] rounded-full" /> <div className="w-1 h-5 bg-violet-600 rounded-full" />
<button <button
onClick={() => setShowTelegramGuide(true)} onClick={() => setShowTelegramGuide(true)}
@@ -428,7 +428,7 @@ export default function MyPage() {
</svg> </svg>
</div> </div>
<div> <div>
<div className="text-sm font-semibold text-[#04102b] flex items-center gap-1.5"> <div className="text-sm font-semibold text-slate-900 flex items-center gap-1.5">
<span className="w-2 h-2 rounded-full bg-emerald-400 inline-block" /> <span className="w-2 h-2 rounded-full bg-emerald-400 inline-block" />
</div> </div>
@@ -491,14 +491,14 @@ export default function MyPage() {
</svg> </svg>
</div> </div>
<div> <div>
<div className="text-sm font-semibold text-[#04102b]"> </div> <div className="text-sm font-semibold text-slate-900"> </div>
<div className="text-xs text-slate-500"> </div> <div className="text-xs text-slate-500"> </div>
</div> </div>
</div> </div>
<button <button
onClick={handleTelegramConnect} onClick={handleTelegramConnect}
disabled={telegramLinkState === 'generating'} disabled={telegramLinkState === 'generating'}
className="px-5 py-2.5 text-sm font-bold text-white bg-[#1a56db] hover:bg-[#1e4fc2] rounded-xl shadow-sm shadow-sky-200 transition disabled:opacity-60" className="px-5 py-2.5 text-sm font-bold text-white bg-violet-600 hover:bg-violet-500 rounded-xl shadow-sm shadow-sky-200 transition disabled:opacity-60"
> >
{telegramLinkState === 'generating' ? '생성 중...' : '텔레그램 연결하기'} {telegramLinkState === 'generating' ? '생성 중...' : '텔레그램 연결하기'}
</button> </button>
@@ -506,37 +506,37 @@ export default function MyPage() {
)} )}
</div> </div>
<div className="bg-white rounded-2xl border border-[#dbe8ff] p-6"> <div className="bg-white rounded-2xl border border-slate-200 p-6">
<h2 className="font-bold text-[#04102b] mb-4 flex items-center gap-2"> <h2 className="font-bold text-slate-900 mb-4 flex items-center gap-2">
<div className="w-1 h-5 bg-[#1a56db] rounded-full" /> <div className="w-1 h-5 bg-violet-600 rounded-full" />
</h2> </h2>
<div className="grid grid-cols-2 sm:grid-cols-3 gap-3"> <div className="grid grid-cols-2 sm:grid-cols-3 gap-3">
<Link href="/saju/input" className="flex items-center gap-3 p-4 rounded-xl border border-[#dbe8ff] hover:border-blue-300 hover:bg-blue-50/50 transition group"> <Link href="/saju/input" className="flex items-center gap-3 p-4 rounded-xl border border-slate-200 hover:border-violet-300 hover:bg-violet-50/50 transition group">
<div className="w-9 h-9 rounded-xl bg-violet-50 border border-violet-200 flex items-center justify-center flex-shrink-0"> <div className="w-9 h-9 rounded-xl bg-violet-50 border border-violet-200 flex items-center justify-center flex-shrink-0">
<svg className="w-5 h-5 text-violet-500" fill="none" stroke="currentColor" viewBox="0 0 24 24"> <svg className="w-5 h-5 text-violet-500" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={1.5} 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" /> <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={1.5} 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> </svg>
</div> </div>
<div> <div>
<div className="text-sm font-semibold text-[#04102b]"> </div> <div className="text-sm font-semibold text-slate-900"> </div>
<div className="text-xs text-slate-500"> </div> <div className="text-xs text-slate-500"> </div>
</div> </div>
</Link> </Link>
<Link href="/freelance" className="flex items-center gap-3 p-4 rounded-xl border border-[#dbe8ff] hover:border-blue-300 hover:bg-blue-50/50 transition group"> <Link href="/freelance" className="flex items-center gap-3 p-4 rounded-xl border border-slate-200 hover:border-violet-300 hover:bg-violet-50/50 transition group">
<div className="w-9 h-9 rounded-xl bg-blue-50 border border-blue-200 flex items-center justify-center flex-shrink-0"> <div className="w-9 h-9 rounded-xl bg-violet-50 border border-violet-200 flex items-center justify-center flex-shrink-0">
<svg className="w-5 h-5 text-blue-500" fill="none" stroke="currentColor" viewBox="0 0 24 24"> <svg className="w-5 h-5 text-violet-500" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={1.5} d="M21 13.255A23.931 23.931 0 0112 15c-3.183 0-6.22-.62-9-1.745M16 6V4a2 2 0 00-2-2h-4a2 2 0 00-2 2v2m4 6h.01M5 20h14a2 2 0 002-2V8a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z" /> <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={1.5} d="M21 13.255A23.931 23.931 0 0112 15c-3.183 0-6.22-.62-9-1.745M16 6V4a2 2 0 00-2-2h-4a2 2 0 00-2 2v2m4 6h.01M5 20h14a2 2 0 002-2V8a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z" />
</svg> </svg>
</div> </div>
<div> <div>
<div className="text-sm font-semibold text-[#04102b]"> </div> <div className="text-sm font-semibold text-slate-900"> </div>
<div className="text-xs text-slate-500"> </div> <div className="text-xs text-slate-500"> </div>
</div> </div>
</Link> </Link>
<Link <Link
href="/studio" href="/studio"
className="flex items-center gap-3 p-4 rounded-xl border border-[#dbe8ff] hover:border-blue-300 hover:bg-blue-50/50 transition group" className="flex items-center gap-3 p-4 rounded-xl border border-slate-200 hover:border-violet-300 hover:bg-violet-50/50 transition group"
> >
<div className="w-9 h-9 rounded-xl bg-violet-50 border border-violet-200 flex items-center justify-center flex-shrink-0"> <div className="w-9 h-9 rounded-xl bg-violet-50 border border-violet-200 flex items-center justify-center flex-shrink-0">
<svg className="w-5 h-5 text-violet-500" fill="none" stroke="currentColor" viewBox="0 0 24 24"> <svg className="w-5 h-5 text-violet-500" fill="none" stroke="currentColor" viewBox="0 0 24 24">
@@ -544,7 +544,7 @@ export default function MyPage() {
</svg> </svg>
</div> </div>
<div> <div>
<div className="text-sm font-semibold text-[#04102b]">AI </div> <div className="text-sm font-semibold text-slate-900">AI </div>
<div className="text-xs text-slate-500"> </div> <div className="text-xs text-slate-500"> </div>
</div> </div>
</Link> </Link>
@@ -573,13 +573,13 @@ export default function MyPage() {
const isActive = sub.status === 'active'; const isActive = sub.status === 'active';
return ( return (
<div key={sub.id} className={`bg-white rounded-2xl border p-6 ${isExpired ? 'border-slate-200 opacity-60' : isCancelled ? 'border-orange-200' : 'border-[#dbe8ff]'}`}> <div key={sub.id} className={`bg-white rounded-2xl border p-6 ${isExpired ? 'border-slate-200 opacity-60' : isCancelled ? 'border-orange-200' : 'border-slate-200'}`}>
{/* 헤더 */} {/* 헤더 */}
<div className="flex items-start justify-between mb-5"> <div className="flex items-start justify-between mb-5">
<div className="flex items-center gap-3"> <div className="flex items-center gap-3">
<span className="text-3xl">🎟</span> <span className="text-3xl">🎟</span>
<div> <div>
<div className="font-bold text-[#04102b] text-base"> <div className="font-bold text-slate-900 text-base">
{sub.product_id} {sub.product_id}
</div> </div>
<div className="text-xs text-slate-500 mt-0.5"> <div className="text-xs text-slate-500 mt-0.5">
@@ -600,7 +600,7 @@ export default function MyPage() {
<div className="grid grid-cols-2 gap-3 mb-5"> <div className="grid grid-cols-2 gap-3 mb-5">
<div className="bg-slate-50 rounded-xl p-3"> <div className="bg-slate-50 rounded-xl p-3">
<div className="text-xs text-slate-400 mb-1"></div> <div className="text-xs text-slate-400 mb-1"></div>
<div className="text-sm font-bold text-[#04102b]"> <div className="text-sm font-bold text-slate-900">
{expiresDate.toLocaleDateString('ko-KR', { year: 'numeric', month: 'long', day: 'numeric' })} {expiresDate.toLocaleDateString('ko-KR', { year: 'numeric', month: 'long', day: 'numeric' })}
</div> </div>
</div> </div>
@@ -616,7 +616,7 @@ export default function MyPage() {
{!isExpired && ( {!isExpired && (
<div className="flex items-center justify-between py-3 border-t border-slate-100 mb-4"> <div className="flex items-center justify-between py-3 border-t border-slate-100 mb-4">
<div> <div>
<div className="text-sm font-semibold text-[#04102b]"> </div> <div className="text-sm font-semibold text-slate-900"> </div>
<div className="text-xs text-slate-400 mt-0.5"> <div className="text-xs text-slate-400 mt-0.5">
{sub.auto_renew ? '만료 시 자동으로 갱신됩니다' : '만료 시 자동 갱신되지 않습니다'} {sub.auto_renew ? '만료 시 자동으로 갱신됩니다' : '만료 시 자동 갱신되지 않습니다'}
</div> </div>
@@ -642,7 +642,7 @@ export default function MyPage() {
{/* 액션 버튼 */} {/* 액션 버튼 */}
<div className="flex gap-2 flex-wrap"> <div className="flex gap-2 flex-wrap">
<a href="/freelance" <a href="/freelance"
className="flex-1 text-center py-2 text-sm font-bold text-white bg-[#1a56db] hover:bg-blue-700 rounded-xl transition shadow-sm"> className="flex-1 text-center py-2 text-sm font-bold text-white bg-violet-600 hover:bg-violet-700 rounded-xl transition shadow-sm">
</a> </a>
{isActive && ( {isActive && (
@@ -682,11 +682,11 @@ export default function MyPage() {
) : ( ) : (
<div className="grid md:grid-cols-2 gap-4"> <div className="grid md:grid-cols-2 gap-4">
{sajuRecords.map((rec) => ( {sajuRecords.map((rec) => (
<div key={rec.id} className="bg-white rounded-2xl border border-[#dbe8ff] p-5"> <div key={rec.id} className="bg-white rounded-2xl border border-slate-200 p-5">
<div className="flex items-start justify-between mb-3"> <div className="flex items-start justify-between mb-3">
<div> <div>
<div className="text-xs text-slate-400 mb-1">{new Date(rec.created_at).toLocaleDateString('ko-KR')}</div> <div className="text-xs text-slate-400 mb-1">{new Date(rec.created_at).toLocaleDateString('ko-KR')}</div>
<div className="font-bold text-[#04102b]"> <div className="font-bold text-slate-900">
{rec.saju_data?.birth_year ?? '?'}{' '} {rec.saju_data?.birth_year ?? '?'}{' '}
{rec.saju_data?.birth_month ?? '?'}{' '} {rec.saju_data?.birth_month ?? '?'}{' '}
{rec.saju_data?.birth_day ?? '?'} {rec.saju_data?.birth_day ?? '?'}
@@ -707,7 +707,7 @@ export default function MyPage() {
)} )}
<Link <Link
href={buildSajuResultUrl(rec)} href={buildSajuResultUrl(rec)}
className="block w-full text-center py-2 rounded-xl text-xs font-bold bg-[#04102b] hover:bg-[#0a1f5c] text-white transition" className="block w-full text-center py-2 rounded-xl text-xs font-bold bg-[#060e20] hover:bg-[#0a1f5c] text-white transition"
> >
{rec.is_paid && rec.interpretation ? 'AI 해석 다시 보기 →' : '결과 보기 →'} {rec.is_paid && rec.interpretation ? 'AI 해석 다시 보기 →' : '결과 보기 →'}
</Link> </Link>
@@ -730,9 +730,9 @@ export default function MyPage() {
linkLabel="서비스 보기" linkLabel="서비스 보기"
/> />
) : ( ) : (
<div className="bg-white rounded-2xl border border-[#dbe8ff] overflow-hidden"> <div className="bg-white rounded-2xl border border-slate-200 overflow-hidden">
<table className="w-full text-sm"> <table className="w-full text-sm">
<thead className="bg-[#f0f5ff] border-b border-[#dbe8ff]"> <thead className="bg-slate-50 border-b border-slate-200">
<tr> <tr>
<th className="px-5 py-3 text-left font-semibold text-slate-600"></th> <th className="px-5 py-3 text-left font-semibold text-slate-600"></th>
<th className="px-5 py-3 text-left font-semibold text-slate-600"></th> <th className="px-5 py-3 text-left font-semibold text-slate-600"></th>
@@ -743,8 +743,8 @@ export default function MyPage() {
<tbody> <tbody>
{payments.map((p, i) => ( {payments.map((p, i) => (
<tr key={p.id} className={i % 2 === 0 ? '' : 'bg-slate-50/50'}> <tr key={p.id} className={i % 2 === 0 ? '' : 'bg-slate-50/50'}>
<td className="px-5 py-3 font-medium text-[#04102b]">{p.product_name}</td> <td className="px-5 py-3 font-medium text-slate-900">{p.product_name}</td>
<td className="px-5 py-3 text-[#04102b]">{p.amount?.toLocaleString()}</td> <td className="px-5 py-3 text-slate-900">{p.amount?.toLocaleString()}</td>
<td className="px-5 py-3"> <td className="px-5 py-3">
<span className={`px-2 py-0.5 rounded-full text-xs font-bold ${ <span className={`px-2 py-0.5 rounded-full text-xs font-bold ${
p.status === 'paid' ? 'bg-emerald-50 text-emerald-600' : 'bg-slate-100 text-slate-500' p.status === 'paid' ? 'bg-emerald-50 text-emerald-600' : 'bg-slate-100 text-slate-500'
@@ -844,15 +844,15 @@ export default function MyPage() {
{tab === 'projects' && ( {tab === 'projects' && (
<div className="space-y-4"> <div className="space-y-4">
{projects.length === 0 ? ( {projects.length === 0 ? (
<div className="bg-white rounded-2xl border border-[#dbe8ff] p-8 text-center"> <div className="bg-white rounded-2xl border border-slate-200 p-8 text-center">
<div className="w-16 h-16 bg-blue-50 rounded-full flex items-center justify-center mx-auto mb-4"> <div className="w-16 h-16 bg-violet-50 rounded-full flex items-center justify-center mx-auto mb-4">
<svg className="w-8 h-8 text-[#1a56db]" fill="none" stroke="currentColor" viewBox="0 0 24 24"> <svg className="w-8 h-8 text-violet-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={1.5} d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2" /> <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={1.5} d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2" />
</svg> </svg>
</div> </div>
<h3 className="font-bold text-[#04102b] text-lg mb-2"> </h3> <h3 className="font-bold text-slate-900 text-lg mb-2"> </h3>
<p className="text-slate-500 text-sm mb-6 max-w-sm mx-auto"> .</p> <p className="text-slate-500 text-sm mb-6 max-w-sm mx-auto"> .</p>
<Link href="/freelance" className="inline-flex items-center gap-2 bg-[#1a56db] hover:bg-[#1e4fc2] text-white px-6 py-3 rounded-xl font-semibold text-sm transition"> <Link href="/freelance" className="inline-flex items-center gap-2 bg-violet-600 hover:bg-violet-500 text-white px-6 py-3 rounded-xl font-semibold text-sm transition">
</Link> </Link>
</div> </div>
@@ -865,18 +865,18 @@ export default function MyPage() {
const progressPct = totalSteps > 0 ? Math.round((completedSteps / totalSteps) * 100) : 0; const progressPct = totalSteps > 0 ? Math.round((completedSteps / totalSteps) * 100) : 0;
return ( return (
<div key={project.id} className="bg-white rounded-2xl border border-[#dbe8ff] overflow-hidden"> <div key={project.id} className="bg-white rounded-2xl border border-slate-200 overflow-hidden">
{/* 헤더 */} {/* 헤더 */}
<div className="bg-[#04102b] px-6 py-4 flex items-center justify-between" style={{ backgroundImage: 'repeating-linear-gradient(135deg, rgba(255,255,255,0.012) 0px, rgba(255,255,255,0.012) 1px, transparent 1px, transparent 40px)' }}> <div className="bg-[#060e20] px-6 py-4 flex items-center justify-between" style={{ backgroundImage: 'repeating-linear-gradient(135deg, rgba(255,255,255,0.012) 0px, rgba(255,255,255,0.012) 1px, transparent 1px, transparent 40px)' }}>
<div> <div>
<h3 className="font-bold text-white text-base">{project.title}</h3> <h3 className="font-bold text-white text-base">{project.title}</h3>
<p className="text-blue-300/60 text-xs mt-0.5"> <p className="text-white/50 text-xs mt-0.5">
{project.total > 0 ? `${project.total.toLocaleString()}` : '금액 협의 중'} · {new Date(project.created_at).toLocaleDateString('ko-KR')} {project.total > 0 ? `${project.total.toLocaleString()}` : '금액 협의 중'} · {new Date(project.created_at).toLocaleDateString('ko-KR')}
</p> </p>
</div> </div>
<span className={`text-xs font-bold px-3 py-1.5 rounded-full ${ <span className={`text-xs font-bold px-3 py-1.5 rounded-full ${
project.status === 'accepted' ? 'bg-emerald-400/20 text-emerald-300 border border-emerald-400/30' : project.status === 'accepted' ? 'bg-emerald-400/20 text-emerald-300 border border-emerald-400/30' :
project.status === 'in_progress' ? 'bg-blue-400/20 text-blue-300 border border-blue-400/30' : project.status === 'in_progress' ? 'bg-sky-400/20 text-sky-300 border border-sky-400/30' :
project.status === 'completed' ? 'bg-violet-400/20 text-violet-300 border border-violet-400/30' : project.status === 'completed' ? 'bg-violet-400/20 text-violet-300 border border-violet-400/30' :
'bg-slate-400/20 text-slate-300 border border-slate-400/30' 'bg-slate-400/20 text-slate-300 border border-slate-400/30'
}`}> }`}>
@@ -893,11 +893,11 @@ export default function MyPage() {
<div className="mb-6"> <div className="mb-6">
<div className="flex items-center justify-between mb-2"> <div className="flex items-center justify-between mb-2">
<span className="text-xs font-semibold text-slate-500"> </span> <span className="text-xs font-semibold text-slate-500"> </span>
<span className="text-xs font-bold text-[#1a56db]">{progressPct}% ({completedSteps}/{totalSteps})</span> <span className="text-xs font-bold text-violet-600">{progressPct}% ({completedSteps}/{totalSteps})</span>
</div> </div>
<div className="h-2 bg-slate-100 rounded-full overflow-hidden"> <div className="h-2 bg-slate-100 rounded-full overflow-hidden">
<div <div
className="h-full bg-[#1a56db] rounded-full transition-all duration-500" className="h-full bg-violet-600 rounded-full transition-all duration-500"
style={{ width: `${progressPct}%` }} style={{ width: `${progressPct}%` }}
/> />
</div> </div>
@@ -906,12 +906,12 @@ export default function MyPage() {
{/* 현재 진행 단계 */} {/* 현재 진행 단계 */}
{currentStep && ( {currentStep && (
<div className="bg-blue-50 border border-blue-200 rounded-xl p-4 mb-5"> <div className="bg-violet-50 border border-violet-200 rounded-xl p-4 mb-5">
<div className="flex items-center gap-2 mb-1"> <div className="flex items-center gap-2 mb-1">
<span className="w-2 h-2 rounded-full bg-blue-500 animate-pulse" /> <span className="w-2 h-2 rounded-full bg-violet-500 animate-pulse" />
<span className="text-xs font-bold text-blue-600"> </span> <span className="text-xs font-bold text-violet-600"> </span>
</div> </div>
<p className="font-bold text-[#04102b] text-sm">{currentStep.title}</p> <p className="font-bold text-slate-900 text-sm">{currentStep.title}</p>
{currentStep.note && ( {currentStep.note && (
<p className="text-slate-600 text-xs mt-1 leading-relaxed">{currentStep.note}</p> <p className="text-slate-600 text-xs mt-1 leading-relaxed">{currentStep.note}</p>
)} )}
@@ -926,7 +926,7 @@ export default function MyPage() {
{/* 아이콘 */} {/* 아이콘 */}
<div className={`w-8 h-8 rounded-full flex items-center justify-center flex-shrink-0 text-xs font-bold border-2 ${ <div className={`w-8 h-8 rounded-full flex items-center justify-center flex-shrink-0 text-xs font-bold border-2 ${
m.status === 'completed' ? 'bg-emerald-500 border-emerald-500 text-white' : m.status === 'completed' ? 'bg-emerald-500 border-emerald-500 text-white' :
m.status === 'in_progress'? 'bg-[#1a56db] border-[#1a56db] text-white' : m.status === 'in_progress'? 'bg-violet-600 border-violet-600 text-white' :
'bg-white border-slate-200 text-slate-400' 'bg-white border-slate-200 text-slate-400'
}`}> }`}>
{m.status === 'completed' ? ( {m.status === 'completed' ? (
@@ -946,7 +946,7 @@ export default function MyPage() {
<div className="flex items-center gap-2 py-1"> <div className="flex items-center gap-2 py-1">
<span className={`text-sm font-semibold ${ <span className={`text-sm font-semibold ${
m.status === 'completed' ? 'text-emerald-700' : m.status === 'completed' ? 'text-emerald-700' :
m.status === 'in_progress'? 'text-[#1a56db]' : m.status === 'in_progress'? 'text-violet-600' :
'text-slate-400' 'text-slate-400'
}`}>{m.title}</span> }`}>{m.title}</span>
{m.status === 'completed' && m.completed_at && ( {m.status === 'completed' && m.completed_at && (
@@ -971,20 +971,20 @@ export default function MyPage() {
)} )}
{/* 견적서 연결 폼 */} {/* 견적서 연결 폼 */}
<div className="bg-[#f0f5ff] rounded-2xl border border-[#dbe8ff] p-5"> <div className="bg-slate-50 rounded-2xl border border-slate-200 p-5">
<p className="text-sm font-bold text-[#04102b] mb-1"> </p> <p className="text-sm font-bold text-slate-900 mb-1"> </p>
<p className="text-xs text-slate-500 mb-3"> ? URL .</p> <p className="text-xs text-slate-500 mb-3"> ? URL .</p>
<form onSubmit={handleLinkProject} className="flex gap-2"> <form onSubmit={handleLinkProject} className="flex gap-2">
<input <input
value={linkToken} value={linkToken}
onChange={(e) => setLinkToken(e.target.value)} onChange={(e) => setLinkToken(e.target.value)}
placeholder="예: abc123xyz" placeholder="예: abc123xyz"
className="flex-1 px-4 py-2 bg-white border border-[#dbe8ff] rounded-xl text-sm focus:outline-none focus:border-blue-400 min-w-0" className="flex-1 px-4 py-2 bg-white border border-slate-200 rounded-xl text-sm focus:outline-none focus:border-violet-400 min-w-0"
/> />
<button <button
type="submit" type="submit"
disabled={linking || !linkToken.trim()} disabled={linking || !linkToken.trim()}
className="px-4 py-2 bg-[#1a56db] hover:bg-[#1e4fc2] text-white rounded-xl font-semibold text-sm disabled:opacity-50 transition flex-shrink-0" className="px-4 py-2 bg-violet-600 hover:bg-violet-500 text-white rounded-xl font-semibold text-sm disabled:opacity-50 transition flex-shrink-0"
> >
{linking ? '연결 중...' : '연결'} {linking ? '연결 중...' : '연결'}
</button> </button>
@@ -1012,12 +1012,12 @@ export default function MyPage() {
) : ( ) : (
<div className="space-y-3"> <div className="space-y-3">
{orders.map((o) => ( {orders.map((o) => (
<div key={o.id} className="bg-white rounded-2xl border border-[#dbe8ff] p-5"> <div key={o.id} className="bg-white rounded-2xl border border-slate-200 p-5">
<div className="flex items-start justify-between mb-2"> <div className="flex items-start justify-between mb-2">
<div className="font-bold text-[#04102b]">{o.service}</div> <div className="font-bold text-slate-900">{o.service}</div>
<span className={`text-xs font-bold px-2 py-1 rounded-lg ${ <span className={`text-xs font-bold px-2 py-1 rounded-lg ${
o.status === 'completed' ? 'bg-emerald-50 text-emerald-600 border border-emerald-200' : o.status === 'completed' ? 'bg-emerald-50 text-emerald-600 border border-emerald-200' :
o.status === 'in_progress' ? 'bg-blue-50 text-blue-600 border border-blue-200' : o.status === 'in_progress' ? 'bg-violet-50 text-violet-600 border border-violet-200' :
'bg-slate-100 text-slate-500' 'bg-slate-100 text-slate-500'
}`}> }`}>
{o.status === 'completed' ? '완료' : o.status === 'in_progress' ? '진행중' : '대기중'} {o.status === 'completed' ? '완료' : o.status === 'in_progress' ? '진행중' : '대기중'}
@@ -1042,13 +1042,13 @@ function EmptyState({
icon: string; title: string; desc: string; linkHref: string; linkLabel: string; icon: string; title: string; desc: string; linkHref: string; linkLabel: string;
}) { }) {
return ( return (
<div className="text-center py-16 bg-white rounded-2xl border border-[#dbe8ff]"> <div className="text-center py-16 bg-white rounded-2xl border border-slate-200">
<div className="text-5xl mb-4">{icon}</div> <div className="text-5xl mb-4">{icon}</div>
<div className="font-bold text-[#04102b] text-lg mb-2">{title}</div> <div className="font-bold text-slate-900 text-lg mb-2">{title}</div>
<div className="text-slate-500 text-sm mb-6">{desc}</div> <div className="text-slate-500 text-sm mb-6">{desc}</div>
<Link <Link
href={linkHref} href={linkHref}
className="inline-flex items-center gap-2 bg-[#1a56db] hover:bg-[#1e4fc2] text-white px-6 py-3 rounded-xl font-semibold text-sm transition-all shadow-lg shadow-blue-600/20" className="inline-flex items-center gap-2 bg-violet-600 hover:bg-violet-500 text-white px-6 py-3 rounded-xl font-semibold text-sm transition-all shadow-lg shadow-violet-600/20"
> >
{linkLabel} {linkLabel}
</Link> </Link>