diff --git a/app/components/mock/MockWindow.tsx b/app/components/mock/MockWindow.tsx
new file mode 100644
index 0000000..7d40c5b
--- /dev/null
+++ b/app/components/mock/MockWindow.tsx
@@ -0,0 +1,51 @@
+// 라이트 UI 목업의 공용 크롬 프레임 (서버 컴포넌트).
+// 실데이터 없이 "운영 중인 화면" 인상을 주는 craft 요소. --jsm-* 토큰만 사용.
+import type { ReactNode } from 'react';
+
+interface MockWindowProps {
+ /** 타이틀바 텍스트 — 파일/서비스명 느낌 (예: 'stock-report', 'realestate-match') */
+ title: string;
+ children: ReactNode;
+ className?: string;
+}
+
+export default function MockWindow({ title, children, className }: MockWindowProps) {
+ return (
+
+ {/* 타이틀바 — 신호등 + 모노 파일명 + 라이브 점 */}
+
+
+
+
+
+
+
+ {title}
+
+
+
+
+ live
+
+
+
+ {/* 본문 슬롯 */}
+
{children}
+
+ );
+}
diff --git a/app/components/mock/registry.ts b/app/components/mock/registry.ts
new file mode 100644
index 0000000..745a46a
--- /dev/null
+++ b/app/components/mock/registry.ts
@@ -0,0 +1,30 @@
+// 목업 스크린 레지스트리 — showcase 슬롯의 mock 키를 컴포넌트로 해석.
+import type { ComponentType } from 'react';
+
+import {
+ DashboardMock,
+ FeedMock,
+ MatchMock,
+ CommerceMock,
+ SiteMock,
+ BookingMock,
+} from './screens';
+
+export type MockKey =
+ | 'dashboard'
+ | 'feed'
+ | 'match'
+ | 'commerce'
+ | 'site'
+ | 'booking';
+
+export const MOCK_REGISTRY: Record = {
+ dashboard: DashboardMock,
+ feed: FeedMock,
+ match: MatchMock,
+ commerce: CommerceMock,
+ site: SiteMock,
+ booking: BookingMock,
+};
+
+export const MOCK_KEYS = Object.keys(MOCK_REGISTRY) as MockKey[];
diff --git a/app/components/mock/screens.tsx b/app/components/mock/screens.tsx
new file mode 100644
index 0000000..73a0f91
--- /dev/null
+++ b/app/components/mock/screens.tsx
@@ -0,0 +1,250 @@
+// 라이트 UI 목업 스크린 6종 (서버 컴포넌트, props 없음, 정적 마크업).
+// MockWindow 본문에 들어가 "운영 중인 화면" 인상을 만든다. 실데이터 0, --jsm-* 만.
+
+const ACCENT = 'var(--jsm-accent)';
+const INK = 'var(--jsm-ink)';
+const SOFT = 'var(--jsm-ink-soft)';
+const FAINT = 'var(--jsm-ink-faint)';
+const LINE = 'var(--jsm-line)';
+const ALT = 'var(--jsm-surface-alt)';
+const SOFTBG = 'var(--jsm-accent-soft)';
+
+/** 1. 대시보드 — 주식 리포트 톤: 스탯 3 + 막대 차트 */
+export function DashboardMock() {
+ const bars = [38, 54, 30, 62, 46, 72, 58];
+ return (
+
+
+
+
+ 오늘 손익
+
+
+ +2.4%
+
+
+
+
+
+
+ {bars.map((h, i) => (
+
+ ))}
+
+
+ );
+}
+
+/** 2. 피드 — 텔레그램 봇 톤: 메시지 버블 3 */
+export function FeedMock() {
+ const rows = [
+ { t: '09:01', m: '매수 체결 · 삼성전자 12,400', tag: '체결', on: true },
+ { t: '11:24', m: '목표가 도달 — 익절 알림', tag: '알림', on: false },
+ { t: '15:30', m: '일일 손익 리포트 전송 완료', tag: '리포트', on: false },
+ ];
+ return (
+
+ {rows.map((r) => (
+
+
+ {r.t}
+
+
+ {r.m}
+
+
+ {r.tag}
+
+
+ ))}
+
+ );
+}
+
+/** 3. 매칭 — 부동산 청약 톤: 필터칩 + 매칭률 리스트 3 */
+export function MatchMock() {
+ const chips = ['강남구', '85㎡↑', '신축'];
+ const rows = [
+ { n: '래미안 원베일리', s: '92%' },
+ { n: '디에이치 퍼스티어', s: '88%' },
+ { n: '아크로 포레스트', s: '81%' },
+ ];
+ return (
+
+
+ {chips.map((c, i) => (
+
+ {c}
+
+ ))}
+
+
+ {rows.map((r) => (
+
+
+ {r.n}
+
+
+ {r.s}
+
+
+ ))}
+
+
+ );
+}
+
+/** 4. 커머스 — 상품 그리드 4 + 장바구니 바 */
+export function CommerceMock() {
+ const items = [
+ { p: '₩28,000' },
+ { p: '₩45,000' },
+ { p: '₩19,000' },
+ { p: '₩36,000' },
+ ];
+ return (
+
+
+ {items.map((it, i) => (
+
+ ))}
+
+
+ 장바구니 3 · ₩128,000
+
+ 결제
+
+
+
+ );
+}
+
+/** 5. 사이트 — 기업/포트폴리오 와이어: 네비 + 헤드라인 + 카드 3 */
+export function SiteMock() {
+ return (
+
+
+
+
+
+
+
+ {[0, 1, 2].map((i) => (
+
+ ))}
+
+
+ );
+}
+
+/** 6. 예약 — 로컬 매장 톤: 주간 캘린더 + 슬롯 그리드 */
+export function BookingMock() {
+ const days = ['월', '화', '수', '목', '금', '토', '일'];
+ // 0=빈 1=예약됨(accent) 2=불가(alt)
+ const slots = [
+ 1, 0, 0, 1, 0, 2, 2,
+ 0, 1, 0, 0, 1, 1, 2,
+ 0, 0, 1, 0, 0, 1, 0,
+ ];
+ return (
+
+
+ {days.map((d) => (
+
+ {d}
+
+ ))}
+
+
+ {slots.map((s, i) => (
+
+ ))}
+
+
+ 예약 확정 · 금 19:00
+
+
+ );
+}