diff --git a/apps/blog/src/app/(main)/main-client-layout.tsx b/apps/blog/src/app/(main)/main-client-layout.tsx index 8f5051a..38e0f42 100644 --- a/apps/blog/src/app/(main)/main-client-layout.tsx +++ b/apps/blog/src/app/(main)/main-client-layout.tsx @@ -52,7 +52,7 @@ export default function MainClientLayout({ 평소엔 sr-only로 숨기고 포커스되면 좌상단에 노출한다. */} 본문으로 건너뛰기 diff --git a/apps/blog/src/app/global.css b/apps/blog/src/app/global.css index 20bfb68..cd70226 100644 --- a/apps/blog/src/app/global.css +++ b/apps/blog/src/app/global.css @@ -1,10 +1,11 @@ @import 'tailwindcss'; -/* === 디자인 토큰 (#94) === - 의미 기반 색 토큰의 단일 출처. 컴포넌트는 bg-[var(--color-brand)] 형태의 - arbitrary 유틸리티로 참조한다(이 프로젝트의 Turbopack+v4 빌드에서 @theme는 - 유틸리티를 생성하지 않아, 코드베이스가 이미 쓰는 arbitrary value 방식으로 통일). */ -:root { +/* === 디자인 토큰 (#94, #120) === + Tailwind v4 @theme로 의미 기반 색 토큰을 정의한다. 각 토큰은 bg-brand/text-ink/ + border-border 등 깔끔한 유틸리티로 생성되며, :root에 CSS 변수로도 노출된다. + (#94에서 @theme가 안 된다고 본 것은 빌드 산출물의 minify된 값(#00ff00→#0f0)을 + minify 전 문자열로 grep한 오진이었음 — #120에서 정정하고 arbitrary value를 제거함) */ +@theme { /* 브랜드 액센트(인디고) 스케일. */ --color-brand: #6366f1; /* 비텍스트 액센트(포커스 링 등) */ --color-brand-strong: #4f46e5; /* 브랜드 위 흰 텍스트용 — 대비 AA(6.3:1) 확보 */ diff --git a/apps/blog/src/components/badge.tsx b/apps/blog/src/components/badge.tsx index 424cb98..5dc2fbf 100644 --- a/apps/blog/src/components/badge.tsx +++ b/apps/blog/src/components/badge.tsx @@ -29,7 +29,7 @@ export function Badge({ href, children, onClick, color = 'secondary', active }: 'md:px-[12px] md:py-[6px]', 'whitespace-nowrap', color === 'primary' - ? 'bg-[var(--color-brand-strong)] text-white' + ? 'bg-brand-strong text-white' : 'bg-gray-100 text-gray-700', 'hover:brightness-95 active:brightness-90', )} diff --git a/apps/blog/src/components/dropdown-menu.tsx b/apps/blog/src/components/dropdown-menu.tsx index 8177042..0ae6915 100644 --- a/apps/blog/src/components/dropdown-menu.tsx +++ b/apps/blog/src/components/dropdown-menu.tsx @@ -151,7 +151,7 @@ export function DropdownMenu({ title, items, leftOffset = 0, ...option }: Dropdo id={listId} ref={dropdownBodyRef} className={classNames( - 'absolute top-6 bg-[var(--color-ink)] z-50 px-2 py-4 flex-col transition-all duration-300', + 'absolute top-6 bg-ink z-50 px-2 py-4 flex-col transition-all duration-300', 'rounded-b-lg drop-shadow-2xl', visible ? 'block' : 'hidden' )} diff --git a/apps/blog/src/components/introduce-card.tsx b/apps/blog/src/components/introduce-card.tsx index 1bbeaef..aa06fb3 100644 --- a/apps/blog/src/components/introduce-card.tsx +++ b/apps/blog/src/components/introduce-card.tsx @@ -3,7 +3,7 @@ import classNames from 'classnames'; export function IntroduceCard() { // 데스크톱 첫 화면 밀도 확보를 위해 상단 마진을 md:mt-30(120px)에서 절반 수준(60px)으로 축소한다. 모바일(mt-7.5)은 유지. return ( -
+
{/* === INTRODUCE CARD LEFT Bar === */}
diff --git a/apps/blog/src/components/main-header.tsx b/apps/blog/src/components/main-header.tsx index dc666b9..4a3f6c7 100644 --- a/apps/blog/src/components/main-header.tsx +++ b/apps/blog/src/components/main-header.tsx @@ -17,7 +17,7 @@ export function MainHeader({ seriesList, tags }: MainHeaderProps) { className={classNames( 'blog-main-header', 'relative z-50', - 'bg-[var(--color-ink)] text-white', + 'bg-ink text-white', 'h-[60px] md:h-[128px]', )} > diff --git a/apps/blog/src/components/mobile-sidebar.tsx b/apps/blog/src/components/mobile-sidebar.tsx index fb61dec..97af953 100644 --- a/apps/blog/src/components/mobile-sidebar.tsx +++ b/apps/blog/src/components/mobile-sidebar.tsx @@ -130,7 +130,7 @@ export function MobileSidebar({ seriesList, tags }: MobileSidebarProps) { {/* ------------------------------------------------------ */} {/* SIDEBAR HEADER */} {/* ------------------------------------------------------ */} -
+
diff --git a/apps/blog/src/components/post-card.tsx b/apps/blog/src/components/post-card.tsx index af881fe..02c958c 100644 --- a/apps/blog/src/components/post-card.tsx +++ b/apps/blog/src/components/post-card.tsx @@ -35,7 +35,7 @@ export function PostCard({ post, showSeriesBadge = true }: PostCardProps) { key={post.route} onClick={onCardClick} // hover 시 배경/보더/포인터로 카드 전체가 클릭 가능함을 시각적으로 알린다. - className="px-3 py-3 mb-[30px] rounded-lg border border-transparent cursor-pointer transition-all duration-200 hover:bg-[var(--color-surface-muted)] hover:border-[var(--color-border)]" + className="px-3 py-3 mb-[30px] rounded-lg border border-transparent cursor-pointer transition-all duration-200 hover:bg-surface-muted hover:border-border" > {/* === POST TITLE AND LINK === */} {/* 제목 Link는 키보드 포커스/새 탭 열기 등 접근성을 위해 실제 로 유지한다. */} diff --git a/apps/blog/src/components/post-detail/copy-button.tsx b/apps/blog/src/components/post-detail/copy-button.tsx index 782ad72..9ba50ec 100644 --- a/apps/blog/src/components/post-detail/copy-button.tsx +++ b/apps/blog/src/components/post-detail/copy-button.tsx @@ -50,7 +50,7 @@ export function CopyButton({ getContent }: CopyButtonProps) { // p-3로 키워 터치 타겟을 약 44px 확보(아이콘 20px + 패딩 24px). 'absolute right-5 top-5 p-3 rounded-md opacity-80 hover:opacity-90 active:opacity-100', // 키보드 포커스 시 시각적 표시(focus-visible ring)로 접근성을 높인다. - 'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--color-brand)]', + 'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-brand', classes.copyBtn )} onClick={handleCopy} diff --git a/apps/blog/src/components/post-detail/post-navigator.tsx b/apps/blog/src/components/post-detail/post-navigator.tsx index 972872c..78de307 100644 --- a/apps/blog/src/components/post-detail/post-navigator.tsx +++ b/apps/blog/src/components/post-detail/post-navigator.tsx @@ -14,7 +14,7 @@ export function PostNavigator({ mode, post }: PostNavigatorProps) { href={post.route} className={classNames( 'group/navigator', - 'flex bg-[var(--color-surface-muted)] p-3 rounded-md gap-5 items-center grow basis-0 min-w-0 cursor-pointer', + 'flex bg-surface-muted p-3 rounded-md gap-5 items-center grow basis-0 min-w-0 cursor-pointer', mode === 'prev' ? 'flex-row' : 'flex-row-reverse', )} > diff --git a/apps/blog/src/components/post-detail/post-recommendation.tsx b/apps/blog/src/components/post-detail/post-recommendation.tsx index f5831c4..70a326f 100644 --- a/apps/blog/src/components/post-detail/post-recommendation.tsx +++ b/apps/blog/src/components/post-detail/post-recommendation.tsx @@ -34,7 +34,7 @@ export function PostRecommendation({ currentPost }: PostRecommendationProps) { {post.series.title} diff --git a/apps/blog/src/components/post-detail/share-buttons.tsx b/apps/blog/src/components/post-detail/share-buttons.tsx index fba4060..2ef5875 100644 --- a/apps/blog/src/components/post-detail/share-buttons.tsx +++ b/apps/blog/src/components/post-detail/share-buttons.tsx @@ -15,7 +15,7 @@ export interface ShareButtonsProps { const buttonClass = classNames( 'flex items-center justify-center p-2.5 rounded-md text-gray-500', 'hover:text-black hover:bg-gray-100 active:bg-gray-200', - 'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--color-brand)]', + 'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-brand', ); export function ShareButtons({ url, title }: ShareButtonsProps) { diff --git a/apps/blog/src/components/search/search-modal.tsx b/apps/blog/src/components/search/search-modal.tsx index 3fcc81d..5eb4038 100644 --- a/apps/blog/src/components/search/search-modal.tsx +++ b/apps/blog/src/components/search/search-modal.tsx @@ -93,7 +93,7 @@ export function SearchModal() { return ( // 배경 오버레이(클릭 시 닫힘)
{/* 모달 본체(내부 클릭은 닫힘 전파 차단) */} @@ -107,7 +107,7 @@ export function SearchModal() { onKeyDown={onKeyDown} > {/* 검색 입력 영역 */} -
+
setActiveIndex(idx)} className={classNames( - 'block border-b border-[var(--color-border-subtle)] px-4 py-3', + 'block border-b border-border-subtle px-4 py-3', idx === activeIndex ? 'bg-gray-100' : 'bg-white', )} >
{doc.series && ( - + {doc.series} )} diff --git a/apps/blog/src/components/series-detail/series-detail.tsx b/apps/blog/src/components/series-detail/series-detail.tsx index a6908ba..3811e94 100644 --- a/apps/blog/src/components/series-detail/series-detail.tsx +++ b/apps/blog/src/components/series-detail/series-detail.tsx @@ -53,7 +53,7 @@ export async function SeriesDetail({ series }: SeriesDetailProps) { 'transition-all duration-200 ease-in-out', active ? // 활성 시리즈: 브랜드 액센트(흰 텍스트 대비 AA)로 현재 위치를 강조한다. - 'bg-[var(--color-brand-strong)] text-white' + 'bg-brand-strong text-white' : // 비활성 시리즈: 옅은 배경 + hover 강조로 클릭 가능함을 알린다. 'bg-gray-100 text-gray-700 hover:bg-gray-200', )}