feat(home): Deep Field 다크 캔버스 재조립 + 운영 실증 카피
- HERO/SHOWCASE/PROCESS/PROOF/SOFTWARE+CTA 5섹션 다크(--jsm-dark-bg) 재구성 - HeroField WebGL 배경 + -mt-16/pt-16로 상단 라이트 띠 제거 (PublicShell 무수정) - "생각을 동작하는 소프트웨어로." 거대 타이포(clamp, -0.04em) - 경력·소속 표현 전면 제거 → "24시간 돌아가는 실서비스 직접 설계·운영" 신뢰 축 - CountUp 카운트업 스탯 + 스크롤 큐 keyframes(motion-safe 가드) - layout metadata·jsonLd 카피 동일 톤 교체 (jobTitle "소프트웨어 엔지니어") Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
76
app/components/deepfield/CountUp.tsx
Normal file
76
app/components/deepfield/CountUp.tsx
Normal file
@@ -0,0 +1,76 @@
|
||||
'use client';
|
||||
|
||||
import { useEffect, useRef, useState } from 'react';
|
||||
|
||||
interface Props {
|
||||
/** 카운트업 목표 숫자 */
|
||||
to: number;
|
||||
/** 숫자 앞에 붙는 고정 텍스트 (예: 없음) */
|
||||
prefix?: string;
|
||||
/** 숫자 뒤에 붙는 고정 텍스트 (예: '+') */
|
||||
suffix?: string;
|
||||
/** 애니메이션 길이(ms) — 기본 600 */
|
||||
duration?: number;
|
||||
className?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* IntersectionObserver 진입 시 0 → to 로 카운트업.
|
||||
* prefers-reduced-motion이면 즉시 최종값 표시(연출 생략).
|
||||
* transform/opacity가 아닌 textContent 변경이라 레이아웃 안정 위해 tabular-nums 권장.
|
||||
*/
|
||||
export default function CountUp({ to, prefix = '', suffix = '', duration = 600, className }: Props) {
|
||||
const ref = useRef<HTMLSpanElement>(null);
|
||||
const [value, setValue] = useState(0);
|
||||
|
||||
useEffect(() => {
|
||||
const el = ref.current;
|
||||
if (!el) return;
|
||||
|
||||
let rafId = 0;
|
||||
let started = false;
|
||||
const reduced = window.matchMedia('(prefers-reduced-motion: reduce)').matches;
|
||||
|
||||
const run = () => {
|
||||
// reduced-motion: 즉시 최종값 (연출 생략)
|
||||
if (reduced) {
|
||||
setValue(to);
|
||||
return;
|
||||
}
|
||||
const start = performance.now();
|
||||
const tick = (now: number) => {
|
||||
const t = Math.min((now - start) / duration, 1);
|
||||
// easeOutCubic — 끝에서 부드럽게 안착
|
||||
const eased = 1 - Math.pow(1 - t, 3);
|
||||
setValue(Math.round(eased * to));
|
||||
if (t < 1) rafId = requestAnimationFrame(tick);
|
||||
};
|
||||
rafId = requestAnimationFrame(tick);
|
||||
};
|
||||
|
||||
const io = new IntersectionObserver(
|
||||
(entries) => {
|
||||
if (entries[0]?.isIntersecting && !started) {
|
||||
started = true;
|
||||
run();
|
||||
io.disconnect();
|
||||
}
|
||||
},
|
||||
{ threshold: 0.4 },
|
||||
);
|
||||
io.observe(el);
|
||||
|
||||
return () => {
|
||||
io.disconnect();
|
||||
if (rafId) cancelAnimationFrame(rafId);
|
||||
};
|
||||
}, [to, duration]);
|
||||
|
||||
return (
|
||||
<span ref={ref} className={className} style={{ fontVariantNumeric: 'tabular-nums' }}>
|
||||
{prefix}
|
||||
{value.toLocaleString('ko-KR')}
|
||||
{suffix}
|
||||
</span>
|
||||
);
|
||||
}
|
||||
@@ -253,6 +253,20 @@ body {
|
||||
mask-image: linear-gradient(to right, transparent, black 8%, black 92%, transparent);
|
||||
}
|
||||
|
||||
/* ─── Deep Field 히어로 스크롤 큐 (가는 세로선 안의 점 미세 바운스) ─── */
|
||||
@keyframes df-scroll-cue {
|
||||
0%, 100% { transform: translateY(0); opacity: 0.35; }
|
||||
50% { transform: translateY(8px); opacity: 1; }
|
||||
}
|
||||
.df-scroll-dot {
|
||||
animation: none;
|
||||
}
|
||||
@media (prefers-reduced-motion: no-preference) {
|
||||
.df-scroll-dot {
|
||||
animation: df-scroll-cue 1.8s cubic-bezier(0.16, 1, 0.3, 1) infinite;
|
||||
}
|
||||
}
|
||||
|
||||
/* Scrollbar styling */
|
||||
::-webkit-scrollbar {
|
||||
width: 6px;
|
||||
|
||||
@@ -10,7 +10,7 @@ export const metadata: Metadata = {
|
||||
template: "%s | 쟁승메이드",
|
||||
},
|
||||
description:
|
||||
"7년차 대기업 백엔드 개발자가 직접 설계하고 만듭니다. 맞춤 소프트웨어 외주 개발과 검증된 완성 소프트웨어를 제공하는 쟁승메이드.",
|
||||
"24시간 돌아가는 실서비스를 직접 설계·운영하는 개발 스튜디오. 맞춤 외주 개발과 검증된 완성 소프트웨어.",
|
||||
keywords: [
|
||||
"외주 개발",
|
||||
"소프트웨어 개발",
|
||||
@@ -28,7 +28,7 @@ export const metadata: Metadata = {
|
||||
siteName: "쟁승메이드",
|
||||
title: "외주 개발 · 완성 소프트웨어 | 쟁승메이드",
|
||||
description:
|
||||
"7년차 대기업 백엔드 개발자가 직접 설계·개발·운영합니다. 맞춤 외주 개발과 검증된 완성 소프트웨어를 제공하는 쟁승메이드.",
|
||||
"24시간 돌아가는 실서비스를 직접 설계·운영하는 개발 스튜디오. 맞춤 외주 개발과 검증된 완성 소프트웨어.",
|
||||
images: [
|
||||
{
|
||||
url: "https://jaengseung-made.com/og-image.png",
|
||||
@@ -42,7 +42,7 @@ export const metadata: Metadata = {
|
||||
card: "summary_large_image",
|
||||
title: "외주 개발 · 완성 소프트웨어 | 쟁승메이드",
|
||||
description:
|
||||
"7년차 대기업 백엔드 개발자가 직접 만듭니다. 맞춤 외주 개발과 검증된 완성 소프트웨어를 제공합니다.",
|
||||
"24시간 돌아가는 실서비스를 직접 설계·운영하는 개발 스튜디오. 맞춤 외주 개발과 검증된 완성 소프트웨어.",
|
||||
},
|
||||
robots: {
|
||||
index: true,
|
||||
@@ -59,19 +59,18 @@ const jsonLd = {
|
||||
'@id': 'https://jaengseung-made.com/#person',
|
||||
name: '박재오',
|
||||
url: 'https://jaengseung-made.com',
|
||||
jobTitle: '백엔드 개발자 · 외주 개발 전문가',
|
||||
worksFor: { '@type': 'Organization', name: '대기업 재직 중' },
|
||||
jobTitle: '소프트웨어 엔지니어',
|
||||
email: 'bgg8988@gmail.com',
|
||||
telephone: '010-3907-1392',
|
||||
knowsAbout: ['Python', 'Java', 'Spring Boot', 'Next.js', '외주 개발', '웹사이트 제작', '업무 자동화', 'API 설계'],
|
||||
description: '7년차 대기업 백엔드 개발자. 맞춤 소프트웨어 외주 개발과 검증된 완성 소프트웨어를 직접 설계·개발·운영합니다.',
|
||||
description: '24시간 돌아가는 실서비스를 직접 설계·운영합니다. 맞춤 소프트웨어 외주 개발과 검증된 완성 소프트웨어를 제공합니다.',
|
||||
},
|
||||
{
|
||||
'@type': 'LocalBusiness',
|
||||
'@id': 'https://jaengseung-made.com/#business',
|
||||
name: '쟁승메이드',
|
||||
url: 'https://jaengseung-made.com',
|
||||
description: '7년차 대기업 백엔드 개발자가 직접 설계·개발·운영하는 외주 개발 · 완성 소프트웨어 스토어.',
|
||||
description: '24시간 돌아가는 실서비스를 직접 설계·운영하는 외주 개발 · 완성 소프트웨어 스토어.',
|
||||
email: 'bgg8988@gmail.com',
|
||||
telephone: '010-3907-1392',
|
||||
priceRange: '₩',
|
||||
@@ -88,7 +87,7 @@ const jsonLd = {
|
||||
'@type': 'Service',
|
||||
name: '외주 개발',
|
||||
url: 'https://jaengseung-made.com/outsourcing',
|
||||
description: '7년차 백엔드 개발자의 1:1 맞춤 소프트웨어 개발 외주. 자동화·API·웹/모바일 등 사이트 한정가로 제공.',
|
||||
description: '1:1 맞춤 소프트웨어 개발 외주. 자동화·API·웹/모바일 등 사이트 한정가로 제공.',
|
||||
serviceType: 'Custom Software Development',
|
||||
provider: { '@id': 'https://jaengseung-made.com/#business' },
|
||||
areaServed: '대한민국',
|
||||
|
||||
822
app/page.tsx
822
app/page.tsx
@@ -2,8 +2,16 @@ import Link from 'next/link';
|
||||
import { createAdminClient } from '@/lib/supabase/admin';
|
||||
import { getListedProducts, type ProductRow } from '@/lib/supabase/product-files';
|
||||
|
||||
// 쟁승메이드 메인 — 외주 개발 + 완성 소프트웨어 2축 랜딩 (서버 컴포넌트)
|
||||
// PublicShell이 TopNav(h-16)·푸터·main 배경을 제공하므로 여기서는 콘텐츠 섹션만 렌더한다.
|
||||
import HeroField from './components/deepfield/HeroField';
|
||||
import ShowcaseGrid from './components/deepfield/ShowcaseGrid';
|
||||
import ScrollReveal from './components/deepfield/ScrollReveal';
|
||||
import CountUp from './components/deepfield/CountUp';
|
||||
import { SHOWCASE_SLOTS } from '@/lib/showcase';
|
||||
|
||||
// 쟁승메이드 메인 — Deep Field 다크 캔버스 (서버 컴포넌트)
|
||||
// PublicShell이 TopNav(h-16, 다크 인지)·푸터(navy)·main 배경(라이트)을 제공한다.
|
||||
// 이 페이지는 자기 풀-블리드 다크 배경을 소유하여 main의 라이트 배경을 덮는다.
|
||||
// 히어로를 -mt-16 + pt-16으로 끌어올려 pt-16로 인한 상단 16px 라이트 띠를 제거한다.
|
||||
|
||||
// 소프트웨어 진열 섹션이 DB 조회를 포함하므로 항상 최신 목록을 보여준다.
|
||||
export const dynamic = 'force-dynamic';
|
||||
@@ -18,15 +26,7 @@ const PROCESS = [
|
||||
{ n: '04', t: '납품·배포 지원', d: '검수 후 30일 무상 하자보수로 안정화까지 책임집니다.' },
|
||||
];
|
||||
|
||||
const STATS = [
|
||||
{ v: '7년차', l: '대기업 백엔드 개발 경력' },
|
||||
{ v: '15+', l: '직접 운영 중인 서비스' },
|
||||
{ v: '기획→배포', l: '원스톱 단독 진행' },
|
||||
];
|
||||
|
||||
const STACK = ['Python', 'Java', 'Spring', 'Next.js', 'AI 연동'];
|
||||
|
||||
const PORTFOLIO = [
|
||||
const PROOF = [
|
||||
{
|
||||
t: '주식 자동매매 시스템',
|
||||
d: '텔레그램과 연동해 실시간으로 주문을 집행하고 체결·손익 리포트를 자동 전송합니다.',
|
||||
@@ -78,52 +78,69 @@ export default async function Home() {
|
||||
const hasProducts = featuredProducts.length > 0;
|
||||
|
||||
return (
|
||||
<>
|
||||
{/* ─── 1. Hero ─── */}
|
||||
<section className="border-b" style={{ borderColor: 'var(--jsm-line)' }}>
|
||||
<div className="max-w-6xl mx-auto px-6 lg:px-8 py-24 lg:py-32">
|
||||
<div className="max-w-3xl">
|
||||
// 풀-블리드 다크 캔버스 — main의 라이트 배경을 덮는다.
|
||||
<div style={{ background: 'var(--jsm-dark-bg)', color: 'var(--jsm-dark-ink)' }}>
|
||||
{/* ─────────────────── 1. HERO ─────────────────── */}
|
||||
{/* -mt-16 pt-16: 고정 헤더 아래로 끌어올려 상단 라이트 띠 제거 + 풀 뷰포트 확보 */}
|
||||
<section className="relative -mt-16 flex min-h-[100svh] items-center overflow-hidden">
|
||||
<HeroField className="absolute inset-0" />
|
||||
{/* 콘텐츠 가독성용 하단 스크림 (radial 광원 위 텍스트 대비) */}
|
||||
<div
|
||||
aria-hidden
|
||||
className="pointer-events-none absolute inset-0"
|
||||
style={{
|
||||
background:
|
||||
'linear-gradient(to bottom, rgba(7,13,26,0.55) 0%, transparent 28%, transparent 60%, rgba(7,13,26,0.75) 100%)',
|
||||
}}
|
||||
/>
|
||||
<div className="relative z-10 mx-auto w-full max-w-6xl px-6 pt-28 pb-24 lg:px-8 lg:pt-32">
|
||||
<div className="max-w-4xl">
|
||||
<span
|
||||
className="inline-block text-xs font-semibold mb-6 px-2.5 py-1 rounded"
|
||||
style={{
|
||||
color: 'var(--jsm-accent)',
|
||||
background: 'var(--jsm-accent-soft)',
|
||||
...KOR_BODY,
|
||||
}}
|
||||
className="mb-7 inline-flex items-center gap-2 font-mono text-[11px] uppercase tracking-[0.22em]"
|
||||
style={{ color: 'var(--jsm-accent-bright)' }}
|
||||
>
|
||||
<span
|
||||
className="inline-block h-1 w-1 rounded-full"
|
||||
style={{ background: 'var(--jsm-accent-bright)' }}
|
||||
/>
|
||||
외주 개발 · 완성 소프트웨어
|
||||
</span>
|
||||
<h1
|
||||
className="text-4xl sm:text-5xl lg:text-[3.5rem] font-bold leading-[1.2] break-keep"
|
||||
style={{ color: 'var(--jsm-ink)', ...KOR_TIGHT }}
|
||||
className="font-bold break-keep"
|
||||
style={{
|
||||
color: 'var(--jsm-dark-ink)',
|
||||
fontSize: 'clamp(2.6rem, 8vw, 5.75rem)',
|
||||
lineHeight: 1.04,
|
||||
letterSpacing: '-0.04em',
|
||||
}}
|
||||
>
|
||||
필요한 소프트웨어,
|
||||
<br className="hidden sm:block" /> 만들어 드리거나{' '}
|
||||
<span style={{ color: 'var(--jsm-accent)' }}>이미 만들어 두었습니다.</span>
|
||||
생각을
|
||||
<br />
|
||||
동작하는 소프트웨어로
|
||||
<span style={{ color: 'var(--jsm-accent-bright)' }}>.</span>
|
||||
</h1>
|
||||
<p
|
||||
className="mt-7 text-lg lg:text-xl leading-relaxed break-keep max-w-2xl"
|
||||
style={{ color: 'var(--jsm-ink-soft)', ...KOR_BODY }}
|
||||
className="mt-8 max-w-2xl break-keep text-lg leading-relaxed lg:text-xl"
|
||||
style={{ color: 'var(--jsm-dark-soft)', ...KOR_BODY }}
|
||||
>
|
||||
7년차 대기업 백엔드 개발자가 직접 설계·개발·운영합니다. 맞춤 외주 개발과
|
||||
검증된 완성 소프트웨어 중 필요한 쪽을 선택하세요.
|
||||
24시간 돌아가는 실서비스를 직접 설계하고 운영합니다. 외주 개발도, 완성
|
||||
소프트웨어도 — 같은 손으로.
|
||||
</p>
|
||||
<div className="mt-10 flex flex-col sm:flex-row gap-3">
|
||||
<div className="mt-11 flex flex-col gap-3 sm:flex-row">
|
||||
<Link
|
||||
href="/outsourcing#contact"
|
||||
className="inline-flex items-center justify-center gap-2 px-6 py-3.5 rounded-lg font-semibold text-white transition-colors duration-150"
|
||||
className="inline-flex items-center justify-center gap-2 rounded-lg px-6 py-3.5 font-semibold text-white transition-transform duration-200 hover:translate-y-[-1px]"
|
||||
style={{ background: 'var(--jsm-accent)', ...KOR_BODY }}
|
||||
>
|
||||
프로젝트 문의하기
|
||||
프로젝트 문의
|
||||
<ArrowRight />
|
||||
</Link>
|
||||
<Link
|
||||
href="/products"
|
||||
className="inline-flex items-center justify-center gap-2 px-6 py-3.5 rounded-lg font-semibold border transition-colors duration-150 hover:bg-[var(--jsm-surface-alt)]"
|
||||
className="inline-flex items-center justify-center gap-2 rounded-lg border px-6 py-3.5 font-semibold transition-colors duration-200 hover:bg-[var(--jsm-dark-surface)]"
|
||||
style={{
|
||||
color: 'var(--jsm-ink)',
|
||||
borderColor: 'var(--jsm-line)',
|
||||
background: 'var(--jsm-surface)',
|
||||
color: 'var(--jsm-dark-ink)',
|
||||
borderColor: 'var(--jsm-dark-line)',
|
||||
...KOR_BODY,
|
||||
}}
|
||||
>
|
||||
@@ -132,327 +149,349 @@ export default async function Home() {
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* ─── 2. 2축 서비스 ─── */}
|
||||
<section style={{ background: 'var(--jsm-surface-alt)' }}>
|
||||
<div className="max-w-6xl mx-auto px-6 lg:px-8 py-20 lg:py-28">
|
||||
<div className="grid md:grid-cols-2 gap-6">
|
||||
{/* 외주 개발 */}
|
||||
<Link
|
||||
href="/outsourcing"
|
||||
className="group block rounded-2xl p-9 lg:p-11 border transition-colors duration-200 hover:border-[var(--jsm-accent)]"
|
||||
style={{ background: 'var(--jsm-surface)', borderColor: 'var(--jsm-line)' }}
|
||||
>
|
||||
<span
|
||||
className="text-xs font-semibold uppercase tracking-wider"
|
||||
style={{ color: 'var(--jsm-accent)' }}
|
||||
>
|
||||
Custom
|
||||
</span>
|
||||
<h2
|
||||
className="mt-3 text-2xl font-bold break-keep"
|
||||
style={{ color: 'var(--jsm-ink)', ...KOR_TIGHT }}
|
||||
>
|
||||
외주 개발
|
||||
</h2>
|
||||
<p
|
||||
className="mt-3 leading-relaxed break-keep"
|
||||
style={{ color: 'var(--jsm-ink-soft)', ...KOR_BODY }}
|
||||
>
|
||||
기획부터 배포·운영까지 한 사람이 책임집니다. 웹 서비스, API, 업무 자동화,
|
||||
봇 개발까지 필요한 형태로 만들어 드립니다.
|
||||
</p>
|
||||
<span
|
||||
className="mt-6 inline-flex items-center gap-1.5 text-sm font-semibold transition-colors duration-150 group-hover:text-[var(--jsm-accent-hover)]"
|
||||
style={{ color: 'var(--jsm-accent)', ...KOR_BODY }}
|
||||
>
|
||||
외주 개발 알아보기
|
||||
<ArrowRight />
|
||||
</span>
|
||||
</Link>
|
||||
|
||||
{/* 완성 소프트웨어 */}
|
||||
<Link
|
||||
href="/products"
|
||||
className="group block rounded-2xl p-9 lg:p-11 border transition-colors duration-200 hover:border-[var(--jsm-accent)]"
|
||||
style={{ background: 'var(--jsm-surface)', borderColor: 'var(--jsm-line)' }}
|
||||
>
|
||||
<span
|
||||
className="text-xs font-semibold uppercase tracking-wider"
|
||||
style={{ color: 'var(--jsm-accent)' }}
|
||||
>
|
||||
Ready-made
|
||||
</span>
|
||||
<h2
|
||||
className="mt-3 text-2xl font-bold break-keep"
|
||||
style={{ color: 'var(--jsm-ink)', ...KOR_TIGHT }}
|
||||
>
|
||||
완성 소프트웨어
|
||||
</h2>
|
||||
<p
|
||||
className="mt-3 leading-relaxed break-keep"
|
||||
style={{ color: 'var(--jsm-ink-soft)', ...KOR_BODY }}
|
||||
>
|
||||
입금 확인 후 바로 다운로드해 사용합니다. 제가 직접 운영하며 검증한 도구만
|
||||
정리해 제공합니다.
|
||||
</p>
|
||||
<span
|
||||
className="mt-6 inline-flex items-center gap-1.5 text-sm font-semibold transition-colors duration-150 group-hover:text-[var(--jsm-accent-hover)]"
|
||||
style={{ color: 'var(--jsm-accent)', ...KOR_BODY }}
|
||||
>
|
||||
소프트웨어 둘러보기
|
||||
<ArrowRight />
|
||||
</span>
|
||||
</Link>
|
||||
</div>
|
||||
{/* 스크롤 큐 — 가는 세로선 + 점 미세 바운스 (motion-safe 가드는 CSS) */}
|
||||
<div
|
||||
aria-hidden
|
||||
className="absolute bottom-7 left-1/2 z-10 flex -translate-x-1/2 flex-col items-center gap-2"
|
||||
>
|
||||
<span
|
||||
className="block h-9 w-px"
|
||||
style={{
|
||||
background:
|
||||
'linear-gradient(to bottom, transparent, var(--jsm-dark-line))',
|
||||
}}
|
||||
/>
|
||||
<span
|
||||
className="df-scroll-dot block h-1.5 w-1.5 rounded-full"
|
||||
style={{ background: 'var(--jsm-accent-bright)' }}
|
||||
/>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* ─── 3. 개발 프로세스 ─── */}
|
||||
<section id="process" style={{ background: 'var(--jsm-bg)' }}>
|
||||
<div className="max-w-6xl mx-auto px-6 lg:px-8 py-20 lg:py-28">
|
||||
<div className="max-w-2xl">
|
||||
{/* ─────────────────── 2. SHOWCASE ─────────────────── */}
|
||||
<section className="border-t" style={{ borderColor: 'var(--jsm-dark-line)' }}>
|
||||
<div className="mx-auto max-w-6xl px-6 py-24 lg:px-8 lg:py-32">
|
||||
<ScrollReveal>
|
||||
<p
|
||||
className="text-xs font-semibold uppercase tracking-wider mb-3"
|
||||
style={{ color: 'var(--jsm-accent)' }}
|
||||
className="mb-3 font-mono text-[11px] uppercase tracking-[0.22em]"
|
||||
style={{ color: 'var(--jsm-accent-bright)' }}
|
||||
>
|
||||
Process
|
||||
showcase
|
||||
</p>
|
||||
<h2
|
||||
className="text-3xl lg:text-4xl font-bold break-keep"
|
||||
style={{ color: 'var(--jsm-ink)', ...KOR_TIGHT }}
|
||||
className="max-w-2xl break-keep text-3xl font-bold lg:text-[2.75rem] lg:leading-[1.12]"
|
||||
style={{ color: 'var(--jsm-dark-ink)', letterSpacing: '-0.03em' }}
|
||||
>
|
||||
상담부터 납품까지, 흐름이 분명합니다
|
||||
이런 걸 만들어 드립니다
|
||||
</h2>
|
||||
</div>
|
||||
<div className="mt-12 grid sm:grid-cols-2 lg:grid-cols-4 gap-px rounded-2xl overflow-hidden border" style={{ borderColor: 'var(--jsm-line)', background: 'var(--jsm-line)' }}>
|
||||
{PROCESS.map((s) => (
|
||||
<div key={s.n} className="p-7 lg:p-8" style={{ background: 'var(--jsm-surface)' }}>
|
||||
<span
|
||||
className="text-sm font-bold"
|
||||
style={{ color: 'var(--jsm-accent)', fontFamily: 'monospace' }}
|
||||
>
|
||||
{s.n}
|
||||
</span>
|
||||
<h3
|
||||
className="mt-4 text-lg font-bold break-keep"
|
||||
style={{ color: 'var(--jsm-ink)', ...KOR_TIGHT }}
|
||||
>
|
||||
{s.t}
|
||||
</h3>
|
||||
<p
|
||||
className="mt-2 text-sm leading-relaxed break-keep"
|
||||
style={{ color: 'var(--jsm-ink-soft)', ...KOR_BODY }}
|
||||
>
|
||||
{s.d}
|
||||
</p>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</ScrollReveal>
|
||||
|
||||
{/* ─── 4. 신뢰 요소 ─── */}
|
||||
<section style={{ background: 'var(--jsm-navy)' }}>
|
||||
<div className="max-w-6xl mx-auto px-6 lg:px-8 py-20 lg:py-24">
|
||||
<div className="grid sm:grid-cols-3 gap-10 sm:gap-8">
|
||||
{STATS.map((s) => (
|
||||
<div key={s.l}>
|
||||
<p
|
||||
className="text-3xl lg:text-4xl font-bold text-white"
|
||||
style={KOR_TIGHT}
|
||||
>
|
||||
{s.v}
|
||||
</p>
|
||||
<p
|
||||
className="mt-2 text-sm leading-relaxed break-keep text-white/60"
|
||||
style={KOR_BODY}
|
||||
>
|
||||
{s.l}
|
||||
</p>
|
||||
</div>
|
||||
))}
|
||||
<div className="mt-14">
|
||||
<ShowcaseGrid slots={SHOWCASE_SLOTS} variant="home" />
|
||||
</div>
|
||||
<div
|
||||
className="mt-12 pt-8 border-t flex flex-wrap items-center gap-x-3 gap-y-2"
|
||||
style={{ borderColor: 'rgba(255,255,255,0.1)' }}
|
||||
>
|
||||
<span className="text-xs uppercase tracking-wider text-white/40 mr-1">Stack</span>
|
||||
{STACK.map((s) => (
|
||||
<span
|
||||
key={s}
|
||||
className="text-sm text-white/80 px-3 py-1 rounded-full"
|
||||
style={{ background: 'rgba(255,255,255,0.06)', ...KOR_BODY }}
|
||||
>
|
||||
{s}
|
||||
</span>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* ─── 5. 포트폴리오 하이라이트 ─── */}
|
||||
<section id="portfolio" style={{ background: 'var(--jsm-surface-alt)' }}>
|
||||
<div className="max-w-6xl mx-auto px-6 lg:px-8 py-20 lg:py-28">
|
||||
<div className="max-w-2xl">
|
||||
<p
|
||||
className="text-xs font-semibold uppercase tracking-wider mb-3"
|
||||
style={{ color: 'var(--jsm-accent)' }}
|
||||
>
|
||||
Portfolio
|
||||
</p>
|
||||
<h2
|
||||
className="text-3xl lg:text-4xl font-bold break-keep"
|
||||
style={{ color: 'var(--jsm-ink)', ...KOR_TIGHT }}
|
||||
>
|
||||
실제로 운영 중인 시스템들
|
||||
</h2>
|
||||
<p
|
||||
className="mt-4 leading-relaxed break-keep"
|
||||
style={{ color: 'var(--jsm-ink-soft)', ...KOR_BODY }}
|
||||
>
|
||||
데모가 아니라 매일 돌아가는 서비스입니다. 같은 깊이로 의뢰하신 프로젝트를 만듭니다.
|
||||
</p>
|
||||
</div>
|
||||
<div className="mt-12 grid md:grid-cols-3 gap-6">
|
||||
{PORTFOLIO.map((p) => (
|
||||
<div
|
||||
key={p.t}
|
||||
className="flex flex-col rounded-2xl p-7 border"
|
||||
style={{ background: 'var(--jsm-surface)', borderColor: 'var(--jsm-line)' }}
|
||||
>
|
||||
<span
|
||||
className="self-start inline-flex items-center gap-1.5 text-[11px] font-semibold px-2.5 py-1 rounded-full mb-5"
|
||||
style={{ color: 'var(--jsm-accent)', background: 'var(--jsm-accent-soft)' }}
|
||||
>
|
||||
<span
|
||||
className="w-1.5 h-1.5 rounded-full"
|
||||
style={{ background: 'var(--jsm-accent)' }}
|
||||
/>
|
||||
직접 개발·운영 중
|
||||
</span>
|
||||
<h3
|
||||
className="text-lg font-bold break-keep"
|
||||
style={{ color: 'var(--jsm-ink)', ...KOR_TIGHT }}
|
||||
>
|
||||
{p.t}
|
||||
</h3>
|
||||
<p
|
||||
className="mt-2.5 text-sm leading-relaxed break-keep flex-1"
|
||||
style={{ color: 'var(--jsm-ink-soft)', ...KOR_BODY }}
|
||||
>
|
||||
{p.d}
|
||||
</p>
|
||||
<div className="mt-5 flex flex-wrap gap-1.5">
|
||||
{p.tags.map((tag) => (
|
||||
<span
|
||||
key={tag}
|
||||
className="text-xs px-2.5 py-1 rounded"
|
||||
style={{
|
||||
color: 'var(--jsm-ink-soft)',
|
||||
background: 'var(--jsm-surface-alt)',
|
||||
...KOR_BODY,
|
||||
}}
|
||||
>
|
||||
{tag}
|
||||
</span>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
<div className="mt-10">
|
||||
<div className="mt-10 flex justify-end">
|
||||
<Link
|
||||
href="/outsourcing#portfolio"
|
||||
className="inline-flex items-center gap-1.5 text-sm font-semibold transition-colors duration-150 hover:text-[var(--jsm-accent-hover)]"
|
||||
style={{ color: 'var(--jsm-accent)', ...KOR_BODY }}
|
||||
href="/outsourcing#showcase"
|
||||
className="inline-flex items-center gap-1.5 text-sm font-semibold transition-colors duration-150 hover:opacity-80"
|
||||
style={{ color: 'var(--jsm-accent-bright)', ...KOR_BODY }}
|
||||
>
|
||||
포트폴리오 자세히 보기
|
||||
전체 레퍼런스
|
||||
<ArrowRight />
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* ─── 6. 소프트웨어 진열 ─── */}
|
||||
{/* ─────────────────── 3. PROCESS ─────────────────── */}
|
||||
<section className="border-t" style={{ borderColor: 'var(--jsm-dark-line)' }}>
|
||||
<div className="mx-auto max-w-6xl px-6 py-24 lg:px-8 lg:py-32">
|
||||
<ScrollReveal>
|
||||
<p
|
||||
className="mb-3 font-mono text-[11px] uppercase tracking-[0.22em]"
|
||||
style={{ color: 'var(--jsm-accent-bright)' }}
|
||||
>
|
||||
process
|
||||
</p>
|
||||
<h2
|
||||
className="max-w-2xl break-keep text-3xl font-bold lg:text-[2.75rem] lg:leading-[1.12]"
|
||||
style={{ color: 'var(--jsm-dark-ink)', letterSpacing: '-0.03em' }}
|
||||
>
|
||||
상담부터 납품까지, 흐름이 분명합니다
|
||||
</h2>
|
||||
</ScrollReveal>
|
||||
|
||||
<div className="relative mt-14">
|
||||
{/* 단계 연결선 — draw 라인 (데스크톱 가로 관통) */}
|
||||
<ScrollReveal
|
||||
variant="draw"
|
||||
className="absolute left-0 right-0 top-7 hidden lg:block"
|
||||
>
|
||||
<span
|
||||
className="block h-px w-full"
|
||||
style={{
|
||||
background:
|
||||
'linear-gradient(to right, transparent, var(--jsm-dark-line) 12%, var(--jsm-dark-line) 88%, transparent)',
|
||||
}}
|
||||
/>
|
||||
</ScrollReveal>
|
||||
|
||||
<div className="grid gap-px sm:grid-cols-2 lg:grid-cols-4 lg:gap-6 lg:bg-transparent">
|
||||
{PROCESS.map((s, i) => (
|
||||
<ScrollReveal key={s.n} delay={i * 100}>
|
||||
<div
|
||||
className="relative h-full rounded-2xl border p-7 lg:p-8"
|
||||
style={{
|
||||
background: 'var(--jsm-dark-surface)',
|
||||
borderColor: 'var(--jsm-dark-line)',
|
||||
}}
|
||||
>
|
||||
<span
|
||||
className="relative z-10 inline-flex h-14 w-14 items-center justify-center rounded-full font-mono text-sm font-bold"
|
||||
style={{
|
||||
color: 'var(--jsm-accent-bright)',
|
||||
background: 'var(--jsm-dark-bg)',
|
||||
boxShadow: 'inset 0 0 0 1px var(--jsm-dark-line)',
|
||||
}}
|
||||
>
|
||||
{s.n}
|
||||
</span>
|
||||
<h3
|
||||
className="mt-5 break-keep text-lg font-bold"
|
||||
style={{ color: 'var(--jsm-dark-ink)', ...KOR_TIGHT }}
|
||||
>
|
||||
{s.t}
|
||||
</h3>
|
||||
<p
|
||||
className="mt-2 break-keep text-sm leading-relaxed"
|
||||
style={{ color: 'var(--jsm-dark-soft)', ...KOR_BODY }}
|
||||
>
|
||||
{s.d}
|
||||
</p>
|
||||
</div>
|
||||
</ScrollReveal>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* ─────────────────── 4. PROOF ─────────────────── */}
|
||||
<section className="border-t" style={{ borderColor: 'var(--jsm-dark-line)' }}>
|
||||
<div className="mx-auto max-w-6xl px-6 py-24 lg:px-8 lg:py-32">
|
||||
<ScrollReveal>
|
||||
<p
|
||||
className="mb-3 font-mono text-[11px] uppercase tracking-[0.22em]"
|
||||
style={{ color: 'var(--jsm-accent-bright)' }}
|
||||
>
|
||||
in production
|
||||
</p>
|
||||
<h2
|
||||
className="max-w-2xl break-keep text-3xl font-bold lg:text-[2.75rem] lg:leading-[1.12]"
|
||||
style={{ color: 'var(--jsm-dark-ink)', letterSpacing: '-0.03em' }}
|
||||
>
|
||||
데모가 아니라 매일 돌아가는 시스템
|
||||
</h2>
|
||||
<p
|
||||
className="mt-4 max-w-xl break-keep leading-relaxed"
|
||||
style={{ color: 'var(--jsm-dark-soft)', ...KOR_BODY }}
|
||||
>
|
||||
직접 개발하고 운영 중인 실서비스입니다. 같은 깊이로 의뢰하신 프로젝트를 만듭니다.
|
||||
</p>
|
||||
</ScrollReveal>
|
||||
|
||||
<div className="mt-14 grid gap-6 md:grid-cols-3">
|
||||
{PROOF.map((p, i) => (
|
||||
<ScrollReveal key={p.t} delay={i * 100}>
|
||||
<div
|
||||
className="flex h-full flex-col rounded-2xl border p-7"
|
||||
style={{
|
||||
background: 'var(--jsm-dark-surface)',
|
||||
borderColor: 'var(--jsm-dark-line)',
|
||||
}}
|
||||
>
|
||||
<span
|
||||
className="mb-5 inline-flex items-center gap-1.5 self-start rounded-full px-2.5 py-1 text-[11px] font-semibold"
|
||||
style={{
|
||||
color: 'var(--jsm-accent-bright)',
|
||||
background: 'rgba(96,165,250,0.12)',
|
||||
}}
|
||||
>
|
||||
<span
|
||||
className="h-1.5 w-1.5 rounded-full"
|
||||
style={{ background: 'var(--jsm-accent-bright)' }}
|
||||
/>
|
||||
직접 개발·운영 중
|
||||
</span>
|
||||
<h3
|
||||
className="break-keep text-lg font-bold"
|
||||
style={{ color: 'var(--jsm-dark-ink)', ...KOR_TIGHT }}
|
||||
>
|
||||
{p.t}
|
||||
</h3>
|
||||
<p
|
||||
className="mt-2.5 flex-1 break-keep text-sm leading-relaxed"
|
||||
style={{ color: 'var(--jsm-dark-soft)', ...KOR_BODY }}
|
||||
>
|
||||
{p.d}
|
||||
</p>
|
||||
<div className="mt-5 flex flex-wrap gap-1.5">
|
||||
{p.tags.map((tag) => (
|
||||
<span
|
||||
key={tag}
|
||||
className="rounded px-2.5 py-1 text-xs"
|
||||
style={{
|
||||
color: 'var(--jsm-dark-soft)',
|
||||
background: 'rgba(148,163,184,0.08)',
|
||||
...KOR_BODY,
|
||||
}}
|
||||
>
|
||||
{tag}
|
||||
</span>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</ScrollReveal>
|
||||
))}
|
||||
</div>
|
||||
|
||||
{/* 스탯 3종 — 카운트업 */}
|
||||
<ScrollReveal className="mt-14">
|
||||
<div
|
||||
className="grid grid-cols-1 gap-px overflow-hidden rounded-2xl border sm:grid-cols-3"
|
||||
style={{ borderColor: 'var(--jsm-dark-line)', background: 'var(--jsm-dark-line)' }}
|
||||
>
|
||||
<div className="px-8 py-10" style={{ background: 'var(--jsm-dark-bg)' }}>
|
||||
<p
|
||||
className="text-4xl font-bold lg:text-5xl"
|
||||
style={{ color: 'var(--jsm-dark-ink)', letterSpacing: '-0.03em' }}
|
||||
>
|
||||
<CountUp to={15} suffix="+" />
|
||||
</p>
|
||||
<p
|
||||
className="mt-2 break-keep text-sm"
|
||||
style={{ color: 'var(--jsm-dark-soft)', ...KOR_BODY }}
|
||||
>
|
||||
직접 운영 중인 실서비스
|
||||
</p>
|
||||
</div>
|
||||
<div className="px-8 py-10" style={{ background: 'var(--jsm-dark-bg)' }}>
|
||||
<p
|
||||
className="text-4xl font-bold lg:text-5xl"
|
||||
style={{ color: 'var(--jsm-dark-ink)', letterSpacing: '-0.03em' }}
|
||||
>
|
||||
24/7
|
||||
</p>
|
||||
<p
|
||||
className="mt-2 break-keep text-sm"
|
||||
style={{ color: 'var(--jsm-dark-soft)', ...KOR_BODY }}
|
||||
>
|
||||
무중단 운영
|
||||
</p>
|
||||
</div>
|
||||
<div className="px-8 py-10" style={{ background: 'var(--jsm-dark-bg)' }}>
|
||||
<p
|
||||
className="text-4xl font-bold lg:text-5xl"
|
||||
style={{ color: 'var(--jsm-dark-ink)', letterSpacing: '-0.03em' }}
|
||||
>
|
||||
원스톱
|
||||
</p>
|
||||
<p
|
||||
className="mt-2 break-keep text-sm"
|
||||
style={{ color: 'var(--jsm-dark-soft)', ...KOR_BODY }}
|
||||
>
|
||||
기획 → 배포 단독 진행
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</ScrollReveal>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* ─────────────────── 5. SOFTWARE + CTA ─────────────────── */}
|
||||
{/* Phase 2: products 테이블 기반 동적 진열. 0개이면 출시 준비 중 폴백. */}
|
||||
<section style={{ background: 'var(--jsm-bg)' }}>
|
||||
<div className="max-w-6xl mx-auto px-6 lg:px-8 py-20 lg:py-28">
|
||||
<section className="border-t" style={{ borderColor: 'var(--jsm-dark-line)' }}>
|
||||
<div className="mx-auto max-w-6xl px-6 py-24 lg:px-8 lg:py-32">
|
||||
{hasProducts ? (
|
||||
<>
|
||||
<div className="flex items-end justify-between mb-10">
|
||||
<div>
|
||||
<p
|
||||
className="text-xs font-semibold uppercase tracking-wider mb-3"
|
||||
style={{ color: 'var(--jsm-accent)' }}
|
||||
>
|
||||
Software
|
||||
</p>
|
||||
<h2
|
||||
className="text-3xl lg:text-4xl font-bold break-keep"
|
||||
style={{ color: 'var(--jsm-ink)', ...KOR_TIGHT }}
|
||||
>
|
||||
완성 소프트웨어
|
||||
</h2>
|
||||
</div>
|
||||
<Link
|
||||
href="/products"
|
||||
className="hidden sm:inline-flex items-center gap-1.5 text-sm font-semibold transition-colors duration-150 hover:text-[var(--jsm-accent-hover)] shrink-0"
|
||||
style={{ color: 'var(--jsm-accent)', ...KOR_BODY }}
|
||||
>
|
||||
전체 보기
|
||||
<ArrowRight />
|
||||
</Link>
|
||||
</div>
|
||||
<div className="grid md:grid-cols-3 gap-6">
|
||||
{featuredProducts.map((p) => (
|
||||
<ScrollReveal>
|
||||
<div className="flex items-end justify-between">
|
||||
<div>
|
||||
<p
|
||||
className="mb-3 font-mono text-[11px] uppercase tracking-[0.22em]"
|
||||
style={{ color: 'var(--jsm-accent-bright)' }}
|
||||
>
|
||||
software
|
||||
</p>
|
||||
<h2
|
||||
className="break-keep text-3xl font-bold lg:text-[2.75rem] lg:leading-[1.12]"
|
||||
style={{ color: 'var(--jsm-dark-ink)', letterSpacing: '-0.03em' }}
|
||||
>
|
||||
바로 쓰는 완성 소프트웨어
|
||||
</h2>
|
||||
</div>
|
||||
<Link
|
||||
key={p.id}
|
||||
href={`/products/${p.id}`}
|
||||
className="group flex flex-col rounded-2xl p-7 border transition-colors duration-200 hover:border-[var(--jsm-accent)]"
|
||||
style={{ background: 'var(--jsm-surface)', borderColor: 'var(--jsm-line)' }}
|
||||
href="/products"
|
||||
className="hidden shrink-0 items-center gap-1.5 text-sm font-semibold transition-colors duration-150 hover:opacity-80 sm:inline-flex"
|
||||
style={{ color: 'var(--jsm-accent-bright)', ...KOR_BODY }}
|
||||
>
|
||||
<h3
|
||||
className="text-lg font-bold break-keep"
|
||||
style={{ color: 'var(--jsm-ink)', ...KOR_TIGHT }}
|
||||
전체 보기
|
||||
<ArrowRight />
|
||||
</Link>
|
||||
</div>
|
||||
</ScrollReveal>
|
||||
|
||||
<div className="mt-14 grid gap-6 md:grid-cols-3">
|
||||
{featuredProducts.map((p, i) => (
|
||||
<ScrollReveal key={p.id} delay={i * 100}>
|
||||
{/* 라이트 카드가 다크 위에 떠 있는 대비 */}
|
||||
<Link
|
||||
href={`/products/${p.id}`}
|
||||
className="group flex h-full flex-col rounded-2xl p-7 shadow-[0_24px_60px_-24px_rgba(0,0,0,0.6)] transition-transform duration-300 hover:translate-y-[-2px]"
|
||||
style={{ background: 'var(--jsm-surface)' }}
|
||||
>
|
||||
{p.name}
|
||||
</h3>
|
||||
{p.description && (
|
||||
<p
|
||||
className="mt-2.5 text-sm leading-relaxed break-keep flex-1"
|
||||
style={{ color: 'var(--jsm-ink-soft)', ...KOR_BODY }}
|
||||
>
|
||||
{p.description}
|
||||
</p>
|
||||
)}
|
||||
<div
|
||||
className="mt-6 pt-5 flex items-center justify-between border-t"
|
||||
style={{ borderColor: 'var(--jsm-line)' }}
|
||||
>
|
||||
<span
|
||||
className="text-lg font-bold"
|
||||
<h3
|
||||
className="break-keep text-lg font-bold"
|
||||
style={{ color: 'var(--jsm-ink)', ...KOR_TIGHT }}
|
||||
>
|
||||
₩{p.price.toLocaleString('ko-KR')}
|
||||
</span>
|
||||
<span
|
||||
className="inline-flex items-center gap-1.5 text-sm font-semibold transition-colors duration-150 group-hover:text-[var(--jsm-accent-hover)]"
|
||||
style={{ color: 'var(--jsm-accent)', ...KOR_BODY }}
|
||||
{p.name}
|
||||
</h3>
|
||||
{p.description && (
|
||||
<p
|
||||
className="mt-2.5 flex-1 break-keep text-sm leading-relaxed"
|
||||
style={{ color: 'var(--jsm-ink-soft)', ...KOR_BODY }}
|
||||
>
|
||||
{p.description}
|
||||
</p>
|
||||
)}
|
||||
<div
|
||||
className="mt-6 flex items-center justify-between border-t pt-5"
|
||||
style={{ borderColor: 'var(--jsm-line)' }}
|
||||
>
|
||||
자세히
|
||||
<ArrowRight />
|
||||
</span>
|
||||
</div>
|
||||
</Link>
|
||||
<span
|
||||
className="text-lg font-bold"
|
||||
style={{ color: 'var(--jsm-ink)', ...KOR_TIGHT }}
|
||||
>
|
||||
₩{p.price.toLocaleString('ko-KR')}
|
||||
</span>
|
||||
<span
|
||||
className="inline-flex items-center gap-1.5 text-sm font-semibold transition-colors duration-150 group-hover:text-[var(--jsm-accent-hover)]"
|
||||
style={{ color: 'var(--jsm-accent)', ...KOR_BODY }}
|
||||
>
|
||||
자세히
|
||||
<ArrowRight />
|
||||
</span>
|
||||
</div>
|
||||
</Link>
|
||||
</ScrollReveal>
|
||||
))}
|
||||
</div>
|
||||
<div className="mt-8 sm:hidden">
|
||||
<Link
|
||||
href="/products"
|
||||
className="inline-flex items-center gap-1.5 text-sm font-semibold"
|
||||
style={{ color: 'var(--jsm-accent)', ...KOR_BODY }}
|
||||
style={{ color: 'var(--jsm-accent-bright)', ...KOR_BODY }}
|
||||
>
|
||||
전체 보기
|
||||
<ArrowRight />
|
||||
@@ -460,73 +499,90 @@ export default async function Home() {
|
||||
</div>
|
||||
</>
|
||||
) : (
|
||||
<div
|
||||
className="rounded-2xl border px-8 py-14 lg:px-14 lg:py-16 text-center"
|
||||
style={{ background: 'var(--jsm-surface)', borderColor: 'var(--jsm-line)' }}
|
||||
>
|
||||
<p
|
||||
className="text-xs font-semibold uppercase tracking-wider mb-3"
|
||||
style={{ color: 'var(--jsm-accent)' }}
|
||||
>
|
||||
Coming soon
|
||||
</p>
|
||||
<h2
|
||||
className="text-2xl lg:text-3xl font-bold break-keep"
|
||||
style={{ color: 'var(--jsm-ink)', ...KOR_TIGHT }}
|
||||
>
|
||||
검증된 완성 소프트웨어를 준비하고 있습니다
|
||||
</h2>
|
||||
<p
|
||||
className="mt-4 max-w-xl mx-auto leading-relaxed break-keep"
|
||||
style={{ color: 'var(--jsm-ink-soft)', ...KOR_BODY }}
|
||||
>
|
||||
직접 운영하며 다듬은 도구를 하나씩 다운로드 상품으로 공개할 예정입니다.
|
||||
출시 소식을 가장 먼저 받아보세요.
|
||||
</p>
|
||||
<Link
|
||||
href="/outsourcing#contact"
|
||||
className="mt-8 inline-flex items-center justify-center gap-2 px-6 py-3.5 rounded-lg font-semibold border transition-colors duration-150 hover:bg-[var(--jsm-surface-alt)]"
|
||||
<ScrollReveal>
|
||||
<div
|
||||
className="rounded-2xl border px-8 py-14 text-center lg:px-14 lg:py-16"
|
||||
style={{
|
||||
color: 'var(--jsm-ink)',
|
||||
borderColor: 'var(--jsm-line)',
|
||||
...KOR_BODY,
|
||||
background: 'var(--jsm-dark-surface)',
|
||||
borderColor: 'var(--jsm-dark-line)',
|
||||
}}
|
||||
>
|
||||
출시 소식 받기
|
||||
<ArrowRight />
|
||||
</Link>
|
||||
</div>
|
||||
<p
|
||||
className="mb-3 font-mono text-[11px] uppercase tracking-[0.22em]"
|
||||
style={{ color: 'var(--jsm-accent-bright)' }}
|
||||
>
|
||||
coming soon
|
||||
</p>
|
||||
<h2
|
||||
className="break-keep text-2xl font-bold lg:text-3xl"
|
||||
style={{ color: 'var(--jsm-dark-ink)', ...KOR_TIGHT }}
|
||||
>
|
||||
검증된 완성 소프트웨어를 준비하고 있습니다
|
||||
</h2>
|
||||
<p
|
||||
className="mx-auto mt-4 max-w-xl break-keep leading-relaxed"
|
||||
style={{ color: 'var(--jsm-dark-soft)', ...KOR_BODY }}
|
||||
>
|
||||
직접 운영하며 다듬은 도구를 하나씩 다운로드 상품으로 공개할 예정입니다. 출시
|
||||
소식을 가장 먼저 받아보세요.
|
||||
</p>
|
||||
<Link
|
||||
href="/outsourcing#contact"
|
||||
className="mt-8 inline-flex items-center justify-center gap-2 rounded-lg border px-6 py-3.5 font-semibold transition-colors duration-200 hover:bg-[var(--jsm-dark-surface)]"
|
||||
style={{
|
||||
color: 'var(--jsm-dark-ink)',
|
||||
borderColor: 'var(--jsm-dark-line)',
|
||||
...KOR_BODY,
|
||||
}}
|
||||
>
|
||||
출시 소식 받기
|
||||
<ArrowRight />
|
||||
</Link>
|
||||
</div>
|
||||
</ScrollReveal>
|
||||
)}
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* ─── 7. 최종 CTA ─── */}
|
||||
<section style={{ background: 'var(--jsm-navy)' }}>
|
||||
<div className="max-w-6xl mx-auto px-6 lg:px-8 py-24 lg:py-28">
|
||||
<div className="max-w-3xl">
|
||||
<h2
|
||||
className="text-3xl lg:text-[2.5rem] font-bold leading-tight text-white break-keep"
|
||||
style={KOR_TIGHT}
|
||||
{/* 최종 CTA 밴드 — accent bg */}
|
||||
<ScrollReveal className="mt-24 lg:mt-32">
|
||||
<div
|
||||
className="relative overflow-hidden rounded-3xl px-8 py-16 lg:px-16 lg:py-20"
|
||||
style={{ background: 'var(--jsm-accent)' }}
|
||||
>
|
||||
프로젝트, 이야기부터 시작하세요
|
||||
</h2>
|
||||
<p
|
||||
className="mt-5 text-lg leading-relaxed text-white/70 break-keep max-w-2xl"
|
||||
style={KOR_BODY}
|
||||
>
|
||||
아이디어 단계여도 괜찮습니다. 무료 상담에서 방향을 함께 잡아드립니다.
|
||||
</p>
|
||||
<Link
|
||||
href="/outsourcing#contact"
|
||||
className="mt-9 inline-flex items-center justify-center gap-2 px-7 py-4 rounded-lg font-semibold text-white transition-colors duration-150"
|
||||
style={{ background: 'var(--jsm-accent)', ...KOR_BODY }}
|
||||
>
|
||||
무료 상담 신청
|
||||
<ArrowRight />
|
||||
</Link>
|
||||
</div>
|
||||
{/* 광원 — radial 허용 */}
|
||||
<div
|
||||
aria-hidden
|
||||
className="pointer-events-none absolute inset-0"
|
||||
style={{
|
||||
backgroundImage:
|
||||
'radial-gradient(60% 80% at 85% 0%, rgba(96,165,250,0.45) 0%, transparent 55%)',
|
||||
}}
|
||||
/>
|
||||
<div className="relative max-w-3xl">
|
||||
<h2
|
||||
className="break-keep text-3xl font-bold leading-tight text-white lg:text-[2.5rem]"
|
||||
style={KOR_TIGHT}
|
||||
>
|
||||
프로젝트, 이야기부터 시작하세요
|
||||
</h2>
|
||||
<p
|
||||
className="mt-5 max-w-2xl break-keep text-lg leading-relaxed text-white/80"
|
||||
style={KOR_BODY}
|
||||
>
|
||||
아이디어 단계여도 괜찮습니다. 무료 상담에서 방향을 함께 잡아드립니다.
|
||||
</p>
|
||||
<Link
|
||||
href="/outsourcing#contact"
|
||||
className="mt-9 inline-flex items-center justify-center gap-2 rounded-lg bg-white px-7 py-4 font-semibold transition-transform duration-200 hover:translate-y-[-1px]"
|
||||
style={{ color: 'var(--jsm-accent)', ...KOR_BODY }}
|
||||
>
|
||||
무료 상담 신청
|
||||
<ArrowRight />
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
</ScrollReveal>
|
||||
</div>
|
||||
</section>
|
||||
</>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user