diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..73db97d
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,4 @@
+node_modules
+.DS_Store
+dist
+.vite
diff --git a/README.md b/README.md
index 1547226..db7d882 100644
--- a/README.md
+++ b/README.md
@@ -1,2 +1,36 @@
# Wikisite
-드립위키 사이트의 깃허브입니다.
+
+React.js로 구현한 드립위키 실험 프로젝트입니다. 위키의 기본적인 레이아웃과 주요 페이지의 초기 구조를 제공합니다.
+
+## 개발 환경 실행
+
+```bash
+npm install
+npm run dev
+```
+
+## 프로젝트 구조
+
+```
+Wikisite
+├── index.html
+├── package.json
+├── src
+│ ├── App.jsx
+│ ├── main.jsx
+│ ├── components
+│ ├── data
+│ ├── pages
+│ └── styles
+└── vite.config.js
+```
+
+## 제공되는 주요 페이지
+
+- **대문(Home)**: 소개 문구와 추천 문서 카드.
+- **최근 변경**: 더미 데이터를 기반으로 최근 편집 리스트 표시.
+- **랜덤 문서**: 랜덤으로 문서를 선택하여 요약을 보여줍니다.
+- **소개**: 위키의 목적과 참여 방법 안내.
+- **개별 문서**: 문서 제목과 요약을 보여주고 본문은 향후 작성을 위해 비워둡니다.
+
+향후 실제 데이터 연동, 검색 기능, 편집 기능 등을 추가해 위키 경험을 확장할 수 있습니다.
diff --git a/index.html b/index.html
new file mode 100644
index 0000000..2ad115c
--- /dev/null
+++ b/index.html
@@ -0,0 +1,13 @@
+
+
+
+
+
+ 드립위키
+
+
+
+
+
+
+
diff --git a/package.json b/package.json
new file mode 100644
index 0000000..68f23bf
--- /dev/null
+++ b/package.json
@@ -0,0 +1,21 @@
+{
+ "name": "wikisite",
+ "version": "0.1.0",
+ "private": true,
+ "type": "module",
+ "scripts": {
+ "dev": "vite",
+ "build": "vite build",
+ "preview": "vite preview"
+ },
+ "dependencies": {
+ "prop-types": "^15.8.1",
+ "react": "^18.2.0",
+ "react-dom": "^18.2.0",
+ "react-router-dom": "^6.22.3"
+ },
+ "devDependencies": {
+ "@vitejs/plugin-react": "^4.2.0",
+ "vite": "^5.2.0"
+ }
+}
diff --git a/public/vite.svg b/public/vite.svg
new file mode 100644
index 0000000..f59a58c
--- /dev/null
+++ b/public/vite.svg
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/App.jsx b/src/App.jsx
new file mode 100644
index 0000000..339aeec
--- /dev/null
+++ b/src/App.jsx
@@ -0,0 +1,25 @@
+import { Routes, Route, Navigate } from 'react-router-dom';
+import Layout from './components/Layout.jsx';
+import Home from './pages/Home.jsx';
+import RecentChanges from './pages/RecentChanges.jsx';
+import RandomPage from './pages/RandomPage.jsx';
+import About from './pages/About.jsx';
+import Page from './pages/Page.jsx';
+import wikiPages from './data/wikiPages.js';
+
+const App = () => {
+ return (
+
+
+ } />
+ } />
+ } />
+ } />
+ } />
+ } />
+
+
+ );
+};
+
+export default App;
diff --git a/src/components/Header.jsx b/src/components/Header.jsx
new file mode 100644
index 0000000..5ab2741
--- /dev/null
+++ b/src/components/Header.jsx
@@ -0,0 +1,32 @@
+import { NavLink } from 'react-router-dom';
+import styles from './Header.module.css';
+
+const Header = () => {
+ return (
+
+
+
📚
+
+
드립위키
+
모두가 참여하는 지식 저장소
+
+
+
+ (isActive ? styles.active : '')}>
+ 대문
+
+ (isActive ? styles.active : '')}>
+ 최근 변경
+
+ (isActive ? styles.active : '')}>
+ 랜덤 문서
+
+ (isActive ? styles.active : '')}>
+ 소개
+
+
+
+ );
+};
+
+export default Header;
diff --git a/src/components/Header.module.css b/src/components/Header.module.css
new file mode 100644
index 0000000..2aabb80
--- /dev/null
+++ b/src/components/Header.module.css
@@ -0,0 +1,65 @@
+.header {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ padding: 1.75rem min(1200px, 92vw);
+ margin: 0 auto;
+}
+
+.brand {
+ display: flex;
+ align-items: center;
+ gap: 1rem;
+}
+
+.logo {
+ font-size: 2.5rem;
+}
+
+.title {
+ font-size: 1.75rem;
+ margin: 0;
+ color: var(--color-text-primary);
+}
+
+.subtitle {
+ margin: 0;
+ color: var(--color-text-secondary);
+ font-size: 0.95rem;
+}
+
+.nav {
+ display: flex;
+ gap: 1rem;
+ font-weight: 600;
+}
+
+.nav a {
+ color: var(--color-text-secondary);
+ text-decoration: none;
+ padding: 0.5rem 0.75rem;
+ border-radius: 999px;
+ transition: background 0.2s ease, color 0.2s ease;
+}
+
+.nav a:hover {
+ background: var(--color-surface);
+ color: var(--color-text-primary);
+}
+
+.active {
+ background: var(--color-primary);
+ color: white !important;
+}
+
+@media (max-width: 720px) {
+ .header {
+ flex-direction: column;
+ align-items: flex-start;
+ gap: 1.25rem;
+ }
+
+ .nav {
+ flex-wrap: wrap;
+ }
+}
diff --git a/src/components/Layout.jsx b/src/components/Layout.jsx
new file mode 100644
index 0000000..9058185
--- /dev/null
+++ b/src/components/Layout.jsx
@@ -0,0 +1,26 @@
+import PropTypes from 'prop-types';
+import { Outlet } from 'react-router-dom';
+import Header from './Header.jsx';
+import Sidebar from './Sidebar.jsx';
+import styles from './Layout.module.css';
+
+const Layout = ({ children }) => {
+ return (
+
+
+
+
+ {children ?? }
+
+
+ © {new Date().getFullYear()} 드립위키. 모두의 지식이 모이는 곳.
+
+
+ );
+};
+
+Layout.propTypes = {
+ children: PropTypes.node
+};
+
+export default Layout;
diff --git a/src/components/Layout.module.css b/src/components/Layout.module.css
new file mode 100644
index 0000000..78db3bb
--- /dev/null
+++ b/src/components/Layout.module.css
@@ -0,0 +1,42 @@
+.appShell {
+ display: flex;
+ flex-direction: column;
+ min-height: 100vh;
+ background: var(--color-background);
+ color: var(--color-text-primary);
+}
+
+.body {
+ flex: 1;
+ display: grid;
+ grid-template-columns: 280px 1fr;
+ gap: 2rem;
+ width: min(1200px, 92vw);
+ margin: 2rem auto;
+}
+
+.content {
+ background: var(--color-surface);
+ border-radius: 16px;
+ padding: 2.5rem;
+ box-shadow: var(--shadow-elevation);
+}
+
+.footer {
+ margin-top: auto;
+ padding: 1.5rem 0;
+ text-align: center;
+ font-size: 0.875rem;
+ color: var(--color-text-secondary);
+ border-top: 1px solid var(--color-border);
+}
+
+@media (max-width: 960px) {
+ .body {
+ grid-template-columns: 1fr;
+ }
+
+ .content {
+ order: 2;
+ }
+}
diff --git a/src/components/Sidebar.jsx b/src/components/Sidebar.jsx
new file mode 100644
index 0000000..f9206be
--- /dev/null
+++ b/src/components/Sidebar.jsx
@@ -0,0 +1,48 @@
+import { NavLink } from 'react-router-dom';
+import wikiPages from '../data/wikiPages.js';
+import styles from './Sidebar.module.css';
+
+const Sidebar = () => {
+ return (
+
+
+
문서 탐색
+
+
+
+
주요 문서
+
+ {wikiPages.slice(0, 5).map((page) => (
+
+ (isActive ? styles.active : '')}>
+ {page.title}
+
+
+ ))}
+
+
+
+
바로가기
+
+
+ (isActive ? styles.active : '')}>
+ 최근 변경
+
+
+
+ (isActive ? styles.active : '')}>
+ 랜덤 문서
+
+
+
+ (isActive ? styles.active : '')}>
+ 위키 소개
+
+
+
+
+
+ );
+};
+
+export default Sidebar;
diff --git a/src/components/Sidebar.module.css b/src/components/Sidebar.module.css
new file mode 100644
index 0000000..cfa09e0
--- /dev/null
+++ b/src/components/Sidebar.module.css
@@ -0,0 +1,69 @@
+.sidebar {
+ background: var(--color-surface);
+ border-radius: 16px;
+ padding: 1.75rem;
+ box-shadow: var(--shadow-elevation);
+ position: sticky;
+ top: 2rem;
+ align-self: start;
+ height: fit-content;
+}
+
+.section + .section {
+ margin-top: 1.75rem;
+}
+
+.section h2 {
+ font-size: 1.1rem;
+ margin-bottom: 0.75rem;
+ color: var(--color-text-primary);
+}
+
+.searchInput {
+ width: 100%;
+ padding: 0.6rem 0.85rem;
+ border: 1px solid var(--color-border);
+ border-radius: 10px;
+ background: var(--color-background);
+ color: var(--color-text-secondary);
+}
+
+.searchInput::placeholder {
+ color: var(--color-text-tertiary);
+}
+
+.pageList,
+.links {
+ margin: 0;
+ padding: 0;
+ list-style: none;
+ display: grid;
+ gap: 0.5rem;
+}
+
+.pageList a,
+.links a {
+ color: var(--color-text-secondary);
+ text-decoration: none;
+ padding: 0.45rem 0.6rem;
+ border-radius: 8px;
+ transition: background 0.2s ease, color 0.2s ease;
+}
+
+.pageList a:hover,
+.links a:hover {
+ background: var(--color-background);
+ color: var(--color-text-primary);
+}
+
+.active {
+ background: var(--color-primary);
+ color: white !important;
+}
+
+@media (max-width: 960px) {
+ .sidebar {
+ position: static;
+ order: 1;
+ }
+}
diff --git a/src/data/wikiPages.js b/src/data/wikiPages.js
new file mode 100644
index 0000000..d471ecb
--- /dev/null
+++ b/src/data/wikiPages.js
@@ -0,0 +1,34 @@
+const wikiPages = [
+ {
+ slug: 'welcome',
+ title: '드립위키에 오신 것을 환영합니다',
+ summary:
+ '드립위키는 다양한 밈과 커뮤니티 이야기를 기록하고 공유하는 공간입니다. 자유롭게 문서를 만들고 수정해 주세요.'
+ },
+ {
+ slug: 'editing-guidelines',
+ title: '편집 가이드라인',
+ summary:
+ '모두가 즐겁게 참여할 수 있도록 편집 시 지켜야 할 기본 규칙과 스타일 가이드를 정리했습니다.'
+ },
+ {
+ slug: 'popular-memes',
+ title: '인기 있는 드립 모음',
+ summary:
+ '요즘 커뮤니티에서 화제가 되는 드립과 밈을 한눈에 정리했습니다. 이미지와 영상 링크도 함께 확인해 보세요.'
+ },
+ {
+ slug: 'community-history',
+ title: '커뮤니티 역사',
+ summary:
+ '드립 문화가 형성된 배경부터 현재까지의 주요 사건들을 연대기 순으로 정리했습니다.'
+ },
+ {
+ slug: 'faq',
+ title: '자주 묻는 질문',
+ summary:
+ '처음 방문한 사용자들이 궁금해하는 점들을 모아 답변했습니다. 계정, 문서 작성, 이미지 업로드 등 자주 묻는 질문을 확인하세요.'
+ }
+];
+
+export default wikiPages;
diff --git a/src/main.jsx b/src/main.jsx
new file mode 100644
index 0000000..9a057a4
--- /dev/null
+++ b/src/main.jsx
@@ -0,0 +1,13 @@
+import React from 'react';
+import ReactDOM from 'react-dom/client';
+import { BrowserRouter } from 'react-router-dom';
+import App from './App.jsx';
+import './styles/global.css';
+
+ReactDOM.createRoot(document.getElementById('root')).render(
+
+
+
+
+
+);
diff --git a/src/pages/About.jsx b/src/pages/About.jsx
new file mode 100644
index 0000000..998e14d
--- /dev/null
+++ b/src/pages/About.jsx
@@ -0,0 +1,30 @@
+import styles from './About.module.css';
+
+const About = () => {
+ return (
+
+
드립위키 소개
+
+ 드립위키는 커뮤니티 문화의 다양성을 존중하며, 그 순간의 웃음과 이야기를 기록하는 것이 목표입니다. 누구나 쉽게
+ 참여하고 정보를 공유할 수 있는 개방형 플랫폼을 지향합니다.
+
+
+ 우리의 목표
+
+ 커뮤니티 밈과 드립을 체계적으로 보존하기
+ 재미있고 유익한 정보로 누구나 참여할 수 있는 공간 만들기
+ 신뢰할 수 있는 출처와 편집 과정을 통해 정보의 정확성 유지하기
+
+
+
+ 참여하는 방법
+
+ 로그인 기능과 편집 도구는 곧 제공될 예정입니다. 그동안은 커뮤니티 게시판을 통해 새로운 아이디어와 피드백을 공유해
+ 주세요. 오픈 베타를 준비하며 여러분의 의견을 적극 반영하겠습니다.
+
+
+
+ );
+};
+
+export default About;
diff --git a/src/pages/About.module.css b/src/pages/About.module.css
new file mode 100644
index 0000000..188cfb8
--- /dev/null
+++ b/src/pages/About.module.css
@@ -0,0 +1,33 @@
+.about {
+ display: grid;
+ gap: 1.75rem;
+}
+
+.about h2 {
+ margin: 0;
+}
+
+.about p {
+ margin: 0;
+ color: var(--color-text-secondary);
+ line-height: 1.7;
+}
+
+section {
+ background: var(--color-background);
+ border-radius: 14px;
+ padding: 1.5rem;
+ border: 1px solid rgba(79, 70, 229, 0.08);
+}
+
+section h3 {
+ margin-top: 0;
+ margin-bottom: 0.75rem;
+}
+
+section ul {
+ margin: 0;
+ padding-left: 1.25rem;
+ color: var(--color-text-secondary);
+ line-height: 1.6;
+}
diff --git a/src/pages/Home.jsx b/src/pages/Home.jsx
new file mode 100644
index 0000000..fb9d8e3
--- /dev/null
+++ b/src/pages/Home.jsx
@@ -0,0 +1,40 @@
+import { Link } from 'react-router-dom';
+import wikiPages from '../data/wikiPages.js';
+import styles from './Home.module.css';
+
+const Home = () => {
+ return (
+
+
+ 드립과 이야기를 기록하는 열린 공간
+
+ 드립위키는 커뮤니티에서 탄생한 다양한 드립과 밈을 체계적으로 정리해 공유하는 위키입니다.
+ 누구나 자유롭게 문서를 만들고 편집하여, 우리만의 역사를 함께 만들어 갈 수 있어요.
+
+
+
+ 첫 문서 보기
+
+
+ 최근 변경 살펴보기
+
+
+
+
+
+ 추천 문서
+
+ {wikiPages.map((page) => (
+
+ {page.title}
+ {page.summary}
+ 문서 읽기 →
+
+ ))}
+
+
+
+ );
+};
+
+export default Home;
diff --git a/src/pages/Home.module.css b/src/pages/Home.module.css
new file mode 100644
index 0000000..cd1e59b
--- /dev/null
+++ b/src/pages/Home.module.css
@@ -0,0 +1,86 @@
+.home {
+ display: grid;
+ gap: 2.5rem;
+}
+
+.hero {
+ display: grid;
+ gap: 1.25rem;
+}
+
+.hero h2 {
+ margin: 0;
+ font-size: 2.4rem;
+ color: var(--color-text-primary);
+}
+
+.hero p {
+ margin: 0;
+ color: var(--color-text-secondary);
+ line-height: 1.7;
+}
+
+.ctaGroup {
+ display: flex;
+ gap: 1rem;
+ flex-wrap: wrap;
+}
+
+.primaryCta,
+.secondaryCta {
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ padding: 0.75rem 1.5rem;
+ border-radius: 999px;
+ text-decoration: none;
+ font-weight: 600;
+}
+
+.primaryCta {
+ background: var(--color-primary);
+ color: white;
+ box-shadow: 0 12px 24px rgba(79, 70, 229, 0.2);
+}
+
+.secondaryCta {
+ background: var(--color-background);
+ color: var(--color-text-primary);
+ border: 1px solid var(--color-border);
+}
+
+.featured h3 {
+ margin-bottom: 1rem;
+ color: var(--color-text-primary);
+}
+
+.cardGrid {
+ display: grid;
+ grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
+ gap: 1.25rem;
+}
+
+.card {
+ background: var(--color-background);
+ border-radius: 14px;
+ padding: 1.5rem;
+ border: 1px solid rgba(79, 70, 229, 0.08);
+ display: grid;
+ gap: 0.75rem;
+}
+
+.card h4 {
+ margin: 0;
+}
+
+.card p {
+ margin: 0;
+ color: var(--color-text-secondary);
+ line-height: 1.6;
+}
+
+.card a {
+ justify-self: flex-start;
+ color: var(--color-primary);
+ font-weight: 600;
+}
diff --git a/src/pages/Page.jsx b/src/pages/Page.jsx
new file mode 100644
index 0000000..ab3005d
--- /dev/null
+++ b/src/pages/Page.jsx
@@ -0,0 +1,41 @@
+import { useParams } from 'react-router-dom';
+import PropTypes from 'prop-types';
+import styles from './Page.module.css';
+
+const Page = ({ pages }) => {
+ const { slug } = useParams();
+ const page = pages.find((item) => item.slug === slug);
+
+ if (!page) {
+ return (
+
+
문서를 찾을 수 없습니다
+
요청한 문서는 아직 작성되지 않았습니다. 새로운 문서를 만들어 보는 건 어떨까요?
+
+ );
+ }
+
+ return (
+
+
+ {page.title}
+ {page.summary}
+
+
+ 문서 본문은 아직 준비 중입니다. 여러분이 첫 편집자가 되어 내용을 채워 주세요!
+
+
+ );
+};
+
+Page.propTypes = {
+ pages: PropTypes.arrayOf(
+ PropTypes.shape({
+ slug: PropTypes.string.isRequired,
+ title: PropTypes.string.isRequired,
+ summary: PropTypes.string.isRequired
+ })
+ ).isRequired
+};
+
+export default Page;
diff --git a/src/pages/Page.module.css b/src/pages/Page.module.css
new file mode 100644
index 0000000..981e865
--- /dev/null
+++ b/src/pages/Page.module.css
@@ -0,0 +1,37 @@
+.page {
+ display: grid;
+ gap: 2rem;
+}
+
+header h2 {
+ margin: 0;
+}
+
+.summary {
+ margin: 0.75rem 0 0;
+ color: var(--color-text-secondary);
+ line-height: 1.6;
+}
+
+.placeholder {
+ padding: 2rem;
+ border-radius: 16px;
+ border: 1px dashed rgba(79, 70, 229, 0.4);
+ background: rgba(79, 70, 229, 0.05);
+ color: var(--color-text-secondary);
+}
+
+.notFound {
+ text-align: center;
+ display: grid;
+ gap: 1rem;
+}
+
+.notFound h2 {
+ margin-bottom: 0;
+}
+
+.notFound p {
+ margin: 0;
+ color: var(--color-text-secondary);
+}
diff --git a/src/pages/RandomPage.jsx b/src/pages/RandomPage.jsx
new file mode 100644
index 0000000..4be0d12
--- /dev/null
+++ b/src/pages/RandomPage.jsx
@@ -0,0 +1,24 @@
+import { useMemo } from 'react';
+import { Link } from 'react-router-dom';
+import wikiPages from '../data/wikiPages.js';
+import styles from './RandomPage.module.css';
+
+const RandomPage = () => {
+ const page = useMemo(() => wikiPages[Math.floor(Math.random() * wikiPages.length)], []);
+
+ return (
+
+
랜덤 문서
+
+ {page.title}
+ {page.summary}
+
+ 문서 전체 읽기
+
+
+
새로고침(F5)을 눌러 다른 문서를 만나보세요!
+
+ );
+};
+
+export default RandomPage;
diff --git a/src/pages/RandomPage.module.css b/src/pages/RandomPage.module.css
new file mode 100644
index 0000000..6d9ff2d
--- /dev/null
+++ b/src/pages/RandomPage.module.css
@@ -0,0 +1,40 @@
+.randomPage {
+ display: grid;
+ gap: 1.5rem;
+}
+
+.randomPage h2 {
+ margin: 0;
+}
+
+article {
+ padding: 1.75rem;
+ border-radius: 14px;
+ border: 1px solid rgba(79, 70, 229, 0.1);
+ background: var(--color-background);
+ display: grid;
+ gap: 0.75rem;
+}
+
+article h3 {
+ margin: 0;
+}
+
+article p {
+ margin: 0;
+ color: var(--color-text-secondary);
+ line-height: 1.6;
+}
+
+.link {
+ justify-self: flex-start;
+ color: var(--color-primary);
+ font-weight: 600;
+ text-decoration: none;
+}
+
+.note {
+ margin: 0;
+ color: var(--color-text-tertiary);
+ font-size: 0.9rem;
+}
diff --git a/src/pages/RecentChanges.jsx b/src/pages/RecentChanges.jsx
new file mode 100644
index 0000000..ecb651a
--- /dev/null
+++ b/src/pages/RecentChanges.jsx
@@ -0,0 +1,49 @@
+import styles from './RecentChanges.module.css';
+
+const dummyChanges = [
+ {
+ page: '인기 있는 드립 모음',
+ user: 'wiki_master',
+ time: '5분 전',
+ summary: '최신 밈 추가 및 이미지 첨부'
+ },
+ {
+ page: '커뮤니티 역사',
+ user: 'historians',
+ time: '1시간 전',
+ summary: '2000년대 초반 커뮤니티 사건 보강'
+ },
+ {
+ page: '편집 가이드라인',
+ user: 'mod_team',
+ time: '어제',
+ summary: '욕설 사용 지침 업데이트'
+ }
+];
+
+const RecentChanges = () => {
+ return (
+
+ );
+};
+
+export default RecentChanges;
diff --git a/src/pages/RecentChanges.module.css b/src/pages/RecentChanges.module.css
new file mode 100644
index 0000000..88daeae
--- /dev/null
+++ b/src/pages/RecentChanges.module.css
@@ -0,0 +1,61 @@
+.recentChanges {
+ display: grid;
+ gap: 1.75rem;
+}
+
+header h2 {
+ margin: 0 0 0.5rem;
+ color: var(--color-text-primary);
+}
+
+header p {
+ margin: 0;
+ color: var(--color-text-secondary);
+}
+
+.changeList {
+ list-style: none;
+ margin: 0;
+ padding: 0;
+ display: grid;
+ gap: 1rem;
+}
+
+.item {
+ display: flex;
+ justify-content: space-between;
+ gap: 1rem;
+ padding: 1.25rem 1.5rem;
+ border-radius: 12px;
+ border: 1px solid rgba(15, 23, 42, 0.06);
+ background: var(--color-background);
+}
+
+.item h3 {
+ margin: 0;
+ color: var(--color-text-primary);
+}
+
+.item p {
+ margin: 0.35rem 0 0;
+ color: var(--color-text-secondary);
+}
+
+.meta {
+ display: grid;
+ justify-items: end;
+ gap: 0.35rem;
+ color: var(--color-text-tertiary);
+ font-size: 0.9rem;
+}
+
+@media (max-width: 640px) {
+ .item {
+ flex-direction: column;
+ }
+
+ .meta {
+ justify-items: start;
+ font-size: 0.85rem;
+ }
+}
diff --git a/src/styles/global.css b/src/styles/global.css
new file mode 100644
index 0000000..379f544
--- /dev/null
+++ b/src/styles/global.css
@@ -0,0 +1,30 @@
+:root {
+ --color-background: #f5f7fb;
+ --color-surface: #ffffff;
+ --color-primary: #4f46e5;
+ --color-text-primary: #1f2937;
+ --color-text-secondary: #4b5563;
+ --color-text-tertiary: #9ca3af;
+ --color-border: rgba(79, 70, 229, 0.12);
+ --shadow-elevation: 0 18px 35px rgba(15, 23, 42, 0.08);
+ font-family: 'Pretendard', 'Noto Sans KR', system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
+ background-color: var(--color-background);
+ color: var(--color-text-primary);
+}
+
+* {
+ box-sizing: border-box;
+}
+
+body {
+ margin: 0;
+ background: var(--color-background);
+}
+
+a {
+ color: inherit;
+}
+
+main {
+ min-height: 60vh;
+}
diff --git a/vite.config.js b/vite.config.js
new file mode 100644
index 0000000..d05fa59
--- /dev/null
+++ b/vite.config.js
@@ -0,0 +1,10 @@
+import { defineConfig } from 'vite';
+import react from '@vitejs/plugin-react';
+
+export default defineConfig({
+ plugins: [react()],
+ server: {
+ port: 5173,
+ open: true
+ }
+});