2 Commits

6 changed files with 40 additions and 24 deletions

View File

@@ -27,6 +27,12 @@ pm run start
- 함수 및 컴포넌트 JSDoc에 @see 필수 (호출 파일, 함수 또는 이벤트 이름, 목적 포함) - 함수 및 컴포넌트 JSDoc에 @see 필수 (호출 파일, 함수 또는 이벤트 이름, 목적 포함)
- 상태 정의, 이벤트 핸들러, 복잡한 JSX 로직에는 인라인 주석을 충분히 작성 - 상태 정의, 이벤트 핸들러, 복잡한 JSX 로직에는 인라인 주석을 충분히 작성
## 브랜드 색상 규칙
- 메인 컬러는 헤더 로고/프로필 기준의 보라 계열 `brand` 팔레트를 사용.
- 새 UI 작성 시 `indigo/purple/pink` 하드코딩 대신 `brand-*` 토큰 사용. 예: `bg-brand-500`, `text-brand-600`, `from-brand-500 to-brand-700`.
- 기본 액션 색(버튼/포커스)은 `primary`를 사용하고, `primary``app/globals.css``brand` 팔레트와 같은 톤으로 유지.
- 색상 변경이 필요하면 컴포넌트 개별 수정보다 먼저 `app/globals.css` 토큰을 수정.
## 설명 방식 ## 설명 방식
- 단계별로 짧게, 예시는 1개만. - 단계별로 짧게, 예시는 1개만.
- 사용자가 요청한 변경과 이유를 함께 설명. - 사용자가 요청한 변경과 이유를 함께 설명.

View File

@@ -39,14 +39,14 @@ export default async function HomePage() {
<section className="container relative mx-auto max-w-7xl px-4 pt-12 md:pt-24 lg:pt-32"> <section className="container relative mx-auto max-w-7xl px-4 pt-12 md:pt-24 lg:pt-32">
<div className="flex flex-col items-center justify-center text-center"> <div className="flex flex-col items-center justify-center text-center">
{/* Badge */} {/* Badge */}
<div className="mb-6 inline-flex items-center rounded-full border border-indigo-200/50 bg-indigo-50/50 px-3 py-1 text-sm font-medium text-indigo-600 backdrop-blur-md dark:border-indigo-800/50 dark:bg-indigo-950/50 dark:text-indigo-300"> <div className="mb-6 inline-flex items-center rounded-full border border-brand-200/50 bg-brand-50/50 px-3 py-1 text-sm font-medium text-brand-600 backdrop-blur-md dark:border-brand-800/50 dark:bg-brand-900/50 dark:text-brand-300">
<span className="flex h-2 w-2 rounded-full bg-indigo-500 mr-2 animate-pulse"></span> <span className="mr-2 flex h-2 w-2 animate-pulse rounded-full bg-brand-500"></span>
The Future of Trading The Future of Trading
</div> </div>
<h1 className="font-heading text-4xl font-black tracking-tight text-foreground sm:text-6xl md:text-7xl lg:text-8xl"> <h1 className="font-heading text-4xl font-black tracking-tight text-foreground sm:text-6xl md:text-7xl lg:text-8xl">
<br className="hidden sm:block" /> <br className="hidden sm:block" />
<span className="text-transparent bg-clip-text bg-linear-to-r from-indigo-500 via-purple-500 to-pink-500 animate-gradient-x underline decoration-indigo-500/30 decoration-4 underline-offset-8"> <span className="animate-gradient-x bg-linear-to-r from-brand-500 via-brand-600 to-brand-700 bg-clip-text text-transparent underline decoration-brand-500/30 decoration-4 underline-offset-8">
</span> </span>
</h1> </h1>
@@ -63,7 +63,7 @@ export default async function HomePage() {
<Button <Button
asChild asChild
size="lg" size="lg"
className="h-14 rounded-full px-10 text-lg font-bold shadow-xl shadow-indigo-500/20 transition-all hover:scale-105 hover:shadow-indigo-500/40" className="h-14 rounded-full px-10 text-lg font-bold shadow-xl shadow-brand-500/20 transition-all hover:scale-105 hover:shadow-brand-500/40"
> >
<Link href={AUTH_ROUTES.DASHBOARD}> </Link> <Link href={AUTH_ROUTES.DASHBOARD}> </Link>
</Button> </Button>
@@ -71,7 +71,7 @@ export default async function HomePage() {
<Button <Button
asChild asChild
size="lg" size="lg"
className="h-14 rounded-full px-10 text-lg font-bold shadow-xl shadow-indigo-500/20 transition-all hover:scale-105 hover:shadow-indigo-500/40" className="h-14 rounded-full px-10 text-lg font-bold shadow-xl shadow-brand-500/20 transition-all hover:scale-105 hover:shadow-brand-500/40"
> >
<Link href={AUTH_ROUTES.LOGIN}> </Link> <Link href={AUTH_ROUTES.LOGIN}> </Link>
</Button> </Button>
@@ -92,7 +92,7 @@ export default async function HomePage() {
<div className="relative mt-16 w-full max-w-5xl"> <div className="relative mt-16 w-full max-w-5xl">
<div className="group relative aspect-video w-full overflow-hidden rounded-3xl border border-white/20 bg-linear-to-b from-white/10 to-transparent shadow-2xl backdrop-blur-2xl dark:border-white/10 dark:bg-black/20"> <div className="group relative aspect-video w-full overflow-hidden rounded-3xl border border-white/20 bg-linear-to-b from-white/10 to-transparent shadow-2xl backdrop-blur-2xl dark:border-white/10 dark:bg-black/20">
{/* Glow Effect */} {/* Glow Effect */}
<div className="absolute -inset-1 rounded-3xl bg-linear-to-r from-indigo-500 via-purple-500 to-pink-500 opacity-20 blur-2xl transition-opacity duration-500 group-hover:opacity-40" /> <div className="absolute -inset-1 rounded-3xl bg-linear-to-r from-brand-500 via-brand-600 to-brand-700 opacity-20 blur-2xl transition-opacity duration-500 group-hover:opacity-40" />
<SplineScene <SplineScene
sceneUrl="https://prod.spline.design/6Wq1Q7YGyM-iab9i/scene.splinecode" sceneUrl="https://prod.spline.design/6Wq1Q7YGyM-iab9i/scene.splinecode"
@@ -108,7 +108,7 @@ export default async function HomePage() {
<div className="mb-16 text-center"> <div className="mb-16 text-center">
<h2 className="font-heading text-3xl font-bold tracking-tight sm:text-4xl md:text-5xl"> <h2 className="font-heading text-3xl font-bold tracking-tight sm:text-4xl md:text-5xl">
,{" "} ,{" "}
<span className="text-indigo-500"> </span> <span className="text-brand-500"> </span>
</h2> </h2>
<p className="mt-4 text-lg text-muted-foreground"> <p className="mt-4 text-lg text-muted-foreground">
. .
@@ -119,7 +119,7 @@ export default async function HomePage() {
{/* Feature 1 */} {/* Feature 1 */}
<div className="group relative col-span-1 overflow-hidden rounded-3xl border border-border/50 bg-background/50 p-8 shadow-sm transition-all hover:shadow-xl hover:-translate-y-1 dark:bg-zinc-900/50 md:col-span-2"> <div className="group relative col-span-1 overflow-hidden rounded-3xl border border-border/50 bg-background/50 p-8 shadow-sm transition-all hover:shadow-xl hover:-translate-y-1 dark:bg-zinc-900/50 md:col-span-2">
<div className="relative z-10 flex flex-col justify-between h-full gap-6"> <div className="relative z-10 flex flex-col justify-between h-full gap-6">
<div className="h-14 w-14 flex items-center justify-center rounded-2xl bg-indigo-50 text-indigo-600 dark:bg-indigo-900/20 dark:text-indigo-400"> <div className="flex h-14 w-14 items-center justify-center rounded-2xl bg-brand-50 text-brand-600 dark:bg-brand-900/20 dark:text-brand-300">
<svg <svg
className="w-8 h-8" className="w-8 h-8"
fill="none" fill="none"
@@ -143,13 +143,13 @@ export default async function HomePage() {
</p> </p>
</div> </div>
</div> </div>
<div className="absolute top-0 right-0 h-64 w-64 translate-x-1/2 -translate-y-1/2 rounded-full bg-indigo-500/10 blur-3xl group-hover:bg-indigo-500/20 transition-all duration-500" /> <div className="absolute top-0 right-0 h-64 w-64 translate-x-1/2 -translate-y-1/2 rounded-full bg-brand-500/10 blur-3xl transition-all duration-500 group-hover:bg-brand-500/20" />
</div> </div>
{/* Feature 2 (Tall) */} {/* Feature 2 (Tall) */}
<div className="group relative col-span-1 row-span-2 overflow-hidden rounded-3xl border border-border/50 bg-background/50 p-8 shadow-sm transition-all hover:shadow-xl hover:-translate-y-1 dark:bg-zinc-900/50"> <div className="group relative col-span-1 row-span-2 overflow-hidden rounded-3xl border border-border/50 bg-background/50 p-8 shadow-sm transition-all hover:shadow-xl hover:-translate-y-1 dark:bg-zinc-900/50">
<div className="relative z-10 flex flex-col h-full gap-6"> <div className="relative z-10 flex flex-col h-full gap-6">
<div className="h-14 w-14 flex items-center justify-center rounded-2xl bg-purple-50 text-purple-600 dark:bg-purple-900/20 dark:text-purple-400"> <div className="flex h-14 w-14 items-center justify-center rounded-2xl bg-brand-50 text-brand-600 dark:bg-brand-900/20 dark:text-brand-300">
<svg <svg
className="w-8 h-8" className="w-8 h-8"
fill="none" fill="none"
@@ -179,19 +179,19 @@ export default async function HomePage() {
key={item} key={item}
className="flex items-center gap-3 text-sm font-medium text-foreground/80" className="flex items-center gap-3 text-sm font-medium text-foreground/80"
> >
<div className="h-2 w-2 rounded-full bg-purple-500" /> <div className="h-2 w-2 rounded-full bg-brand-500" />
{item} {item}
</div> </div>
))} ))}
</div> </div>
</div> </div>
<div className="absolute bottom-0 left-0 h-64 w-64 -translate-x-1/2 translate-y-1/2 rounded-full bg-purple-500/10 blur-3xl group-hover:bg-purple-500/20 transition-all duration-500" /> <div className="absolute bottom-0 left-0 h-64 w-64 -translate-x-1/2 translate-y-1/2 rounded-full bg-brand-500/10 blur-3xl transition-all duration-500 group-hover:bg-brand-500/20" />
</div> </div>
{/* Feature 3 */} {/* Feature 3 */}
<div className="group relative col-span-1 overflow-hidden rounded-3xl border border-border/50 bg-background/50 p-8 shadow-sm transition-all hover:shadow-xl hover:-translate-y-1 dark:bg-zinc-900/50 md:col-span-2"> <div className="group relative col-span-1 overflow-hidden rounded-3xl border border-border/50 bg-background/50 p-8 shadow-sm transition-all hover:shadow-xl hover:-translate-y-1 dark:bg-zinc-900/50 md:col-span-2">
<div className="relative z-10 flex flex-col justify-between h-full gap-6"> <div className="relative z-10 flex flex-col justify-between h-full gap-6">
<div className="h-14 w-14 flex items-center justify-center rounded-2xl bg-pink-50 text-pink-600 dark:bg-pink-900/20 dark:text-pink-400"> <div className="flex h-14 w-14 items-center justify-center rounded-2xl bg-brand-50 text-brand-600 dark:bg-brand-900/20 dark:text-brand-300">
<svg <svg
className="w-8 h-8" className="w-8 h-8"
fill="none" fill="none"
@@ -216,7 +216,7 @@ export default async function HomePage() {
</p> </p>
</div> </div>
</div> </div>
<div className="absolute bottom-0 right-0 h-40 w-40 translate-x-1/3 translate-y-1/3 rounded-full bg-pink-500/10 blur-3xl group-hover:bg-pink-500/20 transition-all duration-500" /> <div className="absolute right-0 bottom-0 h-40 w-40 translate-x-1/3 translate-y-1/3 rounded-full bg-brand-500/10 blur-3xl transition-all duration-500 group-hover:bg-brand-500/20" />
</div> </div>
</div> </div>
</section> </section>

View File

@@ -38,6 +38,16 @@
--color-popover: var(--popover); --color-popover: var(--popover);
--color-card-foreground: var(--card-foreground); --color-card-foreground: var(--card-foreground);
--color-card: var(--card); --color-card: var(--card);
--color-brand-50: oklch(0.97 0.02 294);
--color-brand-100: oklch(0.93 0.05 294);
--color-brand-200: oklch(0.87 0.1 294);
--color-brand-300: oklch(0.79 0.15 294);
--color-brand-400: oklch(0.7 0.2 294);
--color-brand-500: oklch(0.62 0.24 294);
--color-brand-600: oklch(0.56 0.26 294);
--color-brand-700: oklch(0.49 0.24 295);
--color-brand-800: oklch(0.4 0.2 296);
--color-brand-900: oklch(0.33 0.14 297);
--radius-sm: calc(var(--radius) - 4px); --radius-sm: calc(var(--radius) - 4px);
--radius-md: calc(var(--radius) - 2px); --radius-md: calc(var(--radius) - 2px);
--radius-lg: var(--radius); --radius-lg: var(--radius);
@@ -68,7 +78,7 @@
--card-foreground: oklch(0.145 0 0); --card-foreground: oklch(0.145 0 0);
--popover: oklch(1 0 0); --popover: oklch(1 0 0);
--popover-foreground: oklch(0.145 0 0); --popover-foreground: oklch(0.145 0 0);
--primary: oklch(0.205 0 0); --primary: oklch(0.56 0.26 294);
--primary-foreground: oklch(0.985 0 0); --primary-foreground: oklch(0.985 0 0);
--secondary: oklch(0.97 0 0); --secondary: oklch(0.97 0 0);
--secondary-foreground: oklch(0.205 0 0); --secondary-foreground: oklch(0.205 0 0);
@@ -79,7 +89,7 @@
--destructive: oklch(0.577 0.245 27.325); --destructive: oklch(0.577 0.245 27.325);
--border: oklch(0.922 0 0); --border: oklch(0.922 0 0);
--input: oklch(0.922 0 0); --input: oklch(0.922 0 0);
--ring: oklch(0.708 0 0); --ring: oklch(0.62 0.24 294);
--chart-1: oklch(0.646 0.222 41.116); --chart-1: oklch(0.646 0.222 41.116);
--chart-2: oklch(0.6 0.118 184.704); --chart-2: oklch(0.6 0.118 184.704);
--chart-3: oklch(0.398 0.07 227.392); --chart-3: oklch(0.398 0.07 227.392);
@@ -87,7 +97,7 @@
--chart-5: oklch(0.769 0.188 70.08); --chart-5: oklch(0.769 0.188 70.08);
--sidebar: oklch(0.985 0 0); --sidebar: oklch(0.985 0 0);
--sidebar-foreground: oklch(0.145 0 0); --sidebar-foreground: oklch(0.145 0 0);
--sidebar-primary: oklch(0.205 0 0); --sidebar-primary: oklch(0.56 0.26 294);
--sidebar-primary-foreground: oklch(0.985 0 0); --sidebar-primary-foreground: oklch(0.985 0 0);
--sidebar-accent: oklch(0.97 0 0); --sidebar-accent: oklch(0.97 0 0);
--sidebar-accent-foreground: oklch(0.205 0 0); --sidebar-accent-foreground: oklch(0.205 0 0);
@@ -102,8 +112,8 @@
--card-foreground: oklch(0.985 0 0); --card-foreground: oklch(0.985 0 0);
--popover: oklch(0.205 0 0); --popover: oklch(0.205 0 0);
--popover-foreground: oklch(0.985 0 0); --popover-foreground: oklch(0.985 0 0);
--primary: oklch(0.922 0 0); --primary: oklch(0.56 0.26 294);
--primary-foreground: oklch(0.205 0 0); --primary-foreground: oklch(0.985 0 0);
--secondary: oklch(0.269 0 0); --secondary: oklch(0.269 0 0);
--secondary-foreground: oklch(0.985 0 0); --secondary-foreground: oklch(0.985 0 0);
--muted: oklch(0.269 0 0); --muted: oklch(0.269 0 0);
@@ -113,7 +123,7 @@
--destructive: oklch(0.704 0.191 22.216); --destructive: oklch(0.704 0.191 22.216);
--border: oklch(1 0 0 / 10%); --border: oklch(1 0 0 / 10%);
--input: oklch(1 0 0 / 15%); --input: oklch(1 0 0 / 15%);
--ring: oklch(0.556 0 0); --ring: oklch(0.62 0.24 294);
--chart-1: oklch(0.488 0.243 264.376); --chart-1: oklch(0.488 0.243 264.376);
--chart-2: oklch(0.696 0.17 162.48); --chart-2: oklch(0.696 0.17 162.48);
--chart-3: oklch(0.769 0.188 70.08); --chart-3: oklch(0.769 0.188 70.08);
@@ -121,7 +131,7 @@
--chart-5: oklch(0.645 0.246 16.439); --chart-5: oklch(0.645 0.246 16.439);
--sidebar: oklch(0.205 0 0); --sidebar: oklch(0.205 0 0);
--sidebar-foreground: oklch(0.985 0 0); --sidebar-foreground: oklch(0.985 0 0);
--sidebar-primary: oklch(0.488 0.243 264.376); --sidebar-primary: oklch(0.56 0.26 294);
--sidebar-primary-foreground: oklch(0.985 0 0); --sidebar-primary-foreground: oklch(0.985 0 0);
--sidebar-accent: oklch(0.269 0 0); --sidebar-accent: oklch(0.269 0 0);
--sidebar-accent-foreground: oklch(0.985 0 0); --sidebar-accent-foreground: oklch(0.985 0 0);

View File

@@ -16,7 +16,7 @@ export function SplineScene({ sceneUrl, className }: SplineSceneProps) {
<div className={cn("relative h-full w-full", className)}> <div className={cn("relative h-full w-full", className)}>
{isLoading && ( {isLoading && (
<div className="absolute inset-0 flex items-center justify-center bg-zinc-100 dark:bg-zinc-900"> <div className="absolute inset-0 flex items-center justify-center bg-zinc-100 dark:bg-zinc-900">
<div className="h-10 w-10 animate-spin rounded-full border-4 border-zinc-200 border-t-indigo-500 dark:border-zinc-800" /> <div className="h-10 w-10 animate-spin rounded-full border-4 border-zinc-200 border-t-brand-500 dark:border-zinc-800" />
</div> </div>
)} )}
<Spline <Spline

View File

@@ -38,7 +38,7 @@ export function Header({ user, showDashboardLink = false }: HeaderProps) {
{/* ========== 좌측: 로고 영역 ========== */} {/* ========== 좌측: 로고 영역 ========== */}
<Link href={AUTH_ROUTES.HOME} className="flex items-center gap-2 group"> <Link href={AUTH_ROUTES.HOME} className="flex items-center gap-2 group">
<div className="flex h-9 w-9 items-center justify-center rounded-xl bg-primary/10 transition-transform duration-200 group-hover:scale-110"> <div className="flex h-9 w-9 items-center justify-center rounded-xl bg-primary/10 transition-transform duration-200 group-hover:scale-110">
<div className="h-5 w-5 rounded-lg bg-linear-to-br from-indigo-500 to-purple-600" /> <div className="h-5 w-5 rounded-lg bg-linear-to-br from-brand-500 to-brand-700" />
</div> </div>
<span className="text-xl font-bold tracking-tight text-foreground transition-colors group-hover:text-primary"> <span className="text-xl font-bold tracking-tight text-foreground transition-colors group-hover:text-primary">
AutoTrade AutoTrade

View File

@@ -44,7 +44,7 @@ export function UserMenu({ user }: UserMenuProps) {
<button className="flex items-center gap-2 outline-none"> <button className="flex items-center gap-2 outline-none">
<Avatar className="h-8 w-8 transition-opacity hover:opacity-80"> <Avatar className="h-8 w-8 transition-opacity hover:opacity-80">
<AvatarImage src={user.user_metadata?.avatar_url} /> <AvatarImage src={user.user_metadata?.avatar_url} />
<AvatarFallback className="bg-linear-to-br from-indigo-500 to-purple-600 text-white text-xs font-bold"> <AvatarFallback className="bg-linear-to-br from-brand-500 to-brand-700 text-white text-xs font-bold">
{user.email?.charAt(0).toUpperCase()} {user.email?.charAt(0).toUpperCase()}
</AvatarFallback> </AvatarFallback>
</Avatar> </Avatar>