Skip to content

Commit 8a5919a

Browse files
MinsungIMclaude
andcommitted
feat(home): 디자인 토큰 본격 적용 + 홈페이지 Hero·KPI·서비스 카드 리디자인
.aidocs/design.md(Revolut 스타일) 토큰을 사이트 코드에 1차 매핑하고, 시안(.aidocs/sample.pen Home)에 맞춰 홈페이지 hero/features/KPI를 다시 짠다. - src/css/custom.css: design.md 토큰을 CSS 변수(--smk-*)로 정의(canvas·surface·hairline·ink·accent·radius·spacing), Infima primary를 cobalt violet(#494fdf)으로 교체, 폰트 패밀리 변수(Geist display + Inter body) 적용 - docusaurus.config.ts: Geist/Inter Google Fonts preconnect + stylesheet headTags 추가 - src/pages/index.tsx + index.module.css: 홈 Hero 재작성 — 다크 캔버스 풀블리드 + eyebrow pill + display 88px(clamp) 두 줄 헤드라인 + dual CTA(흰 pill primary / outline secondary). HomepageKPI 마운트 - src/components/HomepageFeatures: 4대 서비스 카드에 accent 컬러 칩(teal/pink/warning/light-green) + 번호 + design.md feature-card-light(흰 카드 + hairline-light + rounded-lg) 적용 - src/components/HomepageKPI: 신규 — 2026 목표 4-up 그리드(30+/20+/20m/0.70). 마지막 셀은 plan-card-featured(cobalt violet)로 강조. 항상 다크 캔버스(테마와 무관한 two-mode 밴드 alternation) 모든 컬러·타이포·spacing은 --smk-* 토큰을 통해서만 참조. design.md가 단일 출처라는 룰(CONTRIBUTING.md §8) 정합. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent c94ffdf commit 8a5919a

8 files changed

Lines changed: 528 additions & 60 deletions

File tree

docusaurus.config.ts

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,31 @@ const config: Config = {
2525

2626
onBrokenLinks: 'throw',
2727

28+
headTags: [
29+
{
30+
tagName: 'link',
31+
attributes: {
32+
rel: 'preconnect',
33+
href: 'https://fonts.googleapis.com',
34+
},
35+
},
36+
{
37+
tagName: 'link',
38+
attributes: {
39+
rel: 'preconnect',
40+
href: 'https://fonts.gstatic.com',
41+
crossorigin: 'anonymous',
42+
},
43+
},
44+
{
45+
tagName: 'link',
46+
attributes: {
47+
rel: 'stylesheet',
48+
href: 'https://fonts.googleapis.com/css2?family=Geist:wght@400;500;600;700&family=Inter:wght@400;500;600;700&display=swap',
49+
},
50+
},
51+
],
52+
2853
i18n: {
2954
defaultLocale: 'ko',
3055
locales: ['ko', 'en'],

src/components/HomepageFeatures/index.tsx

Lines changed: 38 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,44 +3,68 @@ import clsx from 'clsx';
33
import Heading from '@theme/Heading';
44
import styles from './styles.module.css';
55

6+
type AccentKey = 'teal' | 'pink' | 'warning' | 'light-green';
7+
68
type FeatureItem = {
9+
number: string;
710
title: string;
811
description: ReactNode;
12+
accent: AccentKey;
913
};
1014

1115
const FeatureList: FeatureItem[] = [
1216
{
17+
number: '01',
1318
title: '모아보기',
19+
accent: 'teal',
1420
description: (
15-
<>긴 방송에서 하이라이트 장면을 멀티모달 LLM 으로 자동 선별합니다.</>
21+
<>긴 방송에서 하이라이트 장면을 멀티모달 LLM으로 자동 선별합니다.</>
1622
),
1723
},
1824
{
25+
number: '02',
1926
title: '리믹스',
27+
accent: 'pink',
2028
description: (
2129
<>본편 영상을 숏폼·요약본으로 재구성합니다. 자막·장면 분석 기반.</>
2230
),
2331
},
2432
{
33+
number: '03',
2534
title: '광고',
35+
accent: 'warning',
2636
description: (
2737
<>콘텐츠 맥락에 가장 어울리는 광고를 매칭합니다. 임베딩·검색 기반.</>
2838
),
2939
},
3040
{
41+
number: '04',
3142
title: 'Batch',
43+
accent: 'light-green',
3244
description: (
3345
<>방송 아카이브를 야간 배치로 일괄 분석합니다. 재처리·재인덱싱 파이프라인.</>
3446
),
3547
},
3648
];
3749

38-
function Feature({title, description}: FeatureItem) {
50+
const chipClassByAccent: Record<AccentKey, string> = {
51+
teal: styles.chipTeal,
52+
pink: styles.chipPink,
53+
warning: styles.chipWarning,
54+
'light-green': styles.chipLightGreen,
55+
};
56+
57+
function Feature({number, title, description, accent}: FeatureItem) {
3958
return (
40-
<div className={clsx('col col--3')}>
41-
<div className="text--center padding-horiz--md">
42-
<Heading as="h3">{title}</Heading>
43-
<p>{description}</p>
59+
<div className={clsx('col col--3', styles.cardCol)}>
60+
<div className={styles.card}>
61+
<div className={clsx(styles.chip, chipClassByAccent[accent])}>
62+
{number}
63+
</div>
64+
<Heading as="h3" className={styles.cardTitle}>
65+
{title}
66+
</Heading>
67+
<p className={styles.cardDescription}>{description}</p>
4468
</div>
4569
</div>
4670
);
@@ -50,6 +74,14 @@ export default function HomepageFeatures(): ReactNode {
5074
return (
5175
<section className={styles.features}>
5276
<div className="container">
77+
<div className={styles.sectionHeader}>
78+
<Heading as="h2" className={styles.sectionTitle}>
79+
4대 AI 서비스
80+
</Heading>
81+
<p className={styles.sectionSubtitle}>
82+
멀티모달 LLM 위에 방송 도메인 4가지 서비스를 제공합니다.
83+
</p>
84+
</div>
5385
<div className="row">
5486
{FeatureList.map((props, idx) => (
5587
<Feature key={idx} {...props} />
Lines changed: 102 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,106 @@
1+
/* 4대 AI 서비스 섹션 — design.md `feature-card-light` 패턴 */
2+
13
.features {
4+
padding: var(--smk-s-section) 0;
5+
width: 100%;
6+
}
7+
8+
.sectionHeader {
9+
margin-bottom: var(--smk-s-xxxl);
10+
}
11+
12+
.sectionTitle {
13+
font-family: var(--smk-font-display);
14+
font-size: 48px;
15+
font-weight: 500;
16+
line-height: 1.1;
17+
letter-spacing: -0.96px;
18+
color: var(--smk-ink);
19+
margin: 0 0 var(--smk-s-md) 0;
20+
}
21+
22+
.sectionSubtitle {
23+
font-family: var(--smk-font-body);
24+
font-size: 18px;
25+
line-height: 1.5;
26+
color: var(--smk-mute);
27+
max-width: 640px;
28+
margin: 0;
29+
}
30+
31+
.cardCol {
32+
margin-bottom: var(--smk-s-xl);
33+
}
34+
35+
.card {
36+
background: var(--smk-surface-card);
37+
border: 1px solid var(--smk-hairline-light);
38+
border-radius: var(--smk-r-lg);
39+
padding: var(--smk-s-xxl);
40+
display: flex;
41+
flex-direction: column;
42+
gap: var(--smk-s-lg);
43+
height: 100%;
44+
}
45+
46+
.chip {
47+
width: 48px;
48+
height: 48px;
49+
border-radius: var(--smk-r-md);
250
display: flex;
351
align-items: center;
4-
padding: 2rem 0;
5-
width: 100%;
52+
justify-content: center;
53+
color: var(--smk-on-dark);
54+
font-family: var(--smk-font-display);
55+
font-size: 18px;
56+
font-weight: 600;
57+
}
58+
59+
.chipTeal {
60+
background: var(--smk-accent-teal);
61+
}
62+
.chipPink {
63+
background: var(--smk-accent-pink);
64+
}
65+
.chipWarning {
66+
background: var(--smk-accent-warning);
67+
}
68+
.chipLightGreen {
69+
background: var(--smk-accent-light-green);
70+
}
71+
72+
.cardTitle {
73+
font-family: var(--smk-font-display);
74+
font-size: 24px;
75+
font-weight: 500;
76+
line-height: 1.3;
77+
color: var(--smk-ink);
78+
margin: 0;
79+
}
80+
81+
.cardDescription {
82+
font-family: var(--smk-font-body);
83+
font-size: 15px;
84+
line-height: 1.5;
85+
color: var(--smk-body);
86+
margin: 0;
87+
}
88+
89+
/* 다크 모드 — Infima dark canvas와 어울리도록 surface/text 조정 */
90+
[data-theme='dark'] .card {
91+
background: var(--smk-surface-elevated);
92+
border-color: var(--smk-hairline-dark);
93+
}
94+
95+
[data-theme='dark'] .cardTitle,
96+
[data-theme='dark'] .sectionTitle {
97+
color: var(--smk-on-dark);
98+
}
99+
100+
[data-theme='dark'] .cardDescription {
101+
color: var(--smk-on-dark-mute);
102+
}
103+
104+
[data-theme='dark'] .sectionSubtitle {
105+
color: var(--smk-on-dark-mute);
6106
}
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
import type {ReactNode} from 'react';
2+
import clsx from 'clsx';
3+
import Heading from '@theme/Heading';
4+
import styles from './styles.module.css';
5+
6+
type KPIItem = {
7+
value: string;
8+
label: string;
9+
note: string;
10+
featured?: boolean;
11+
};
12+
13+
const KPIList: KPIItem[] = [
14+
{
15+
value: '30+',
16+
label: '오픈소스 기여',
17+
note: 'PR · Issue · Dataset (누적)',
18+
},
19+
{
20+
value: '20+',
21+
label: '기술 블로그',
22+
note: '격주 게시 (누적)',
23+
},
24+
{
25+
value: '20m',
26+
label: '추론 처리',
27+
note: '1시간 방송 → 20분 이하',
28+
},
29+
{
30+
value: '0.70',
31+
label: '장면 분류 F1',
32+
note: '40-60분 콘텐츠 기준',
33+
featured: true,
34+
},
35+
];
36+
37+
function KPICell({value, label, note, featured}: KPIItem) {
38+
return (
39+
<div className={clsx('col col--3', styles.cellCol)}>
40+
<div className={clsx(styles.cell, featured && styles.cellFeatured)}>
41+
<div className={styles.value}>{value}</div>
42+
<div className={styles.label}>{label}</div>
43+
<div className={styles.note}>{note}</div>
44+
</div>
45+
</div>
46+
);
47+
}
48+
49+
export default function HomepageKPI(): ReactNode {
50+
return (
51+
<section className={styles.kpiBand}>
52+
<div className="container">
53+
<div className={styles.sectionHeader}>
54+
<Heading as="h2" className={styles.sectionTitle}>
55+
2026년 목표
56+
</Heading>
57+
<p className={styles.sectionSubtitle}>
58+
오픈소스 생태계 기여와 기술 블로그를 통한 공개 산출물 — 그리고 추론 성능 목표.
59+
</p>
60+
</div>
61+
<div className="row">
62+
{KPIList.map((item, idx) => (
63+
<KPICell key={idx} {...item} />
64+
))}
65+
</div>
66+
</div>
67+
</section>
68+
);
69+
}
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
/* 2026년 목표 KPI 섹션 — design.md `plan-card` + `plan-card-featured` 패턴
2+
light/dark 테마와 무관하게 항상 다크 캔버스(두 모드 밴드 alternation) */
3+
4+
.kpiBand {
5+
background: var(--smk-canvas-dark);
6+
padding: var(--smk-s-section) 0;
7+
color: var(--smk-on-dark);
8+
}
9+
10+
.sectionHeader {
11+
margin-bottom: var(--smk-s-xxxl);
12+
}
13+
14+
.sectionTitle {
15+
font-family: var(--smk-font-display);
16+
font-size: 48px;
17+
font-weight: 500;
18+
line-height: 1.1;
19+
letter-spacing: -0.96px;
20+
color: var(--smk-on-dark);
21+
margin: 0 0 var(--smk-s-md) 0;
22+
}
23+
24+
.sectionSubtitle {
25+
font-family: var(--smk-font-body);
26+
font-size: 18px;
27+
line-height: 1.5;
28+
color: var(--smk-on-dark-mute);
29+
max-width: 640px;
30+
margin: 0;
31+
}
32+
33+
.cellCol {
34+
margin-bottom: var(--smk-s-xl);
35+
}
36+
37+
.cell {
38+
background: var(--smk-surface-elevated);
39+
border-radius: var(--smk-r-lg);
40+
padding: var(--smk-s-xxl);
41+
display: flex;
42+
flex-direction: column;
43+
gap: var(--smk-s-md);
44+
height: 100%;
45+
}
46+
47+
.cellFeatured {
48+
background: var(--smk-primary);
49+
}
50+
51+
.value {
52+
font-family: var(--smk-font-display);
53+
font-size: 64px;
54+
font-weight: 500;
55+
line-height: 1;
56+
letter-spacing: -1.28px;
57+
color: var(--smk-on-dark);
58+
}
59+
60+
.label {
61+
font-family: var(--smk-font-body);
62+
font-size: 14px;
63+
font-weight: 600;
64+
color: var(--smk-on-dark);
65+
}
66+
67+
.note {
68+
font-family: var(--smk-font-body);
69+
font-size: 13px;
70+
color: var(--smk-on-dark-mute);
71+
}
72+
73+
@media screen and (max-width: 996px) {
74+
.sectionTitle {
75+
font-size: 36px;
76+
letter-spacing: -0.72px;
77+
}
78+
.value {
79+
font-size: 48px;
80+
letter-spacing: -0.96px;
81+
}
82+
}

0 commit comments

Comments
 (0)