diff --git a/env.development b/env.development
new file mode 100644
index 0000000..c0e7760
--- /dev/null
+++ b/env.development
@@ -0,0 +1,3 @@
+VITE_API_BASE_URL=https://rolling-api.vercel.app
+VITE_KAKAO_JAVASCRIPT_KEY=96d45a096ca60ab6ab02381934d8931d
+VITE_KAKAO_MESSAGE_TEMPLATE_ID=123537
\ No newline at end of file
diff --git a/env.production b/env.production
new file mode 100644
index 0000000..e6e5ac0
--- /dev/null
+++ b/env.production
@@ -0,0 +1,3 @@
+VITE_API_BASE_URL=https://rolling-api.vercel.app
+VITE_KAKAO_JAVASCRIPT_KEY=17836dd1144957610d3ad75f6c352274
+VITE_KAKAO_MESSAGE_TEMPLATE_ID=123533
\ No newline at end of file
diff --git a/index.html b/index.html
index 6a716f4..fd0ef1f 100644
--- a/index.html
+++ b/index.html
@@ -1,10 +1,11 @@
-
+
+
Main Page;
+ return (
+
+
+
+
+
+
누구나 손쉽게, 온라인 롤링페이퍼를 만들 수 있어요
+
로그인 없이 자유롭게 만들어요.
+
+
+
+
+
+
+
+
+
+
+

+
+
+
+
서로에게 이모지로 감정을 표현해보세요
+
롤링 페이지에 이모지를 추가할 수 있어요.
+
+
+
+
+
+
+
+
+
+
+ );
}
export default MainPage;
diff --git a/src/styles/style.css b/src/styles/style.css
new file mode 100644
index 0000000..f42223d
--- /dev/null
+++ b/src/styles/style.css
@@ -0,0 +1,530 @@
+* {
+ margin: 20px opx;
+ padding: 0;
+ box-sizing: border-box;
+ font-family: 'Pretendard', -apple-system, BlinkMacSystemFont, 'Segoe UI',
+ Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
+}
+
+body {
+ background-color: #ffffff;
+ color: #333;
+}
+
+.container {
+ max-width: 1200px;
+ margin: 0 auto;
+ padding: 40px 20px;
+ transition: all 0.3s ease;
+ background-color: #f6f8ff;
+}
+
+.container:first-of-type {
+ padding-top: 100px; /* 헤더 높이 + 추가 여백 */
+}
+
+.container .empty-space {
+ height: 30px; /* 헤더 높이 */
+ background-color: #ffffff;
+ width: 100%;
+ margin: 0 auto;
+}
+
+/* Header Styles */
+.header {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ height: 62px;
+ position: fixed;
+ top: 0;
+ left: 0;
+ right: 0;
+ background-color: #fff;
+ z-index: 1000;
+ padding: 0 20px;
+ box-shadow: 0 2px 10px rgba(0, 0, 0, 0.05);
+}
+
+.container .header {
+ position: fixed;
+ width: 100%;
+ max-width: none;
+ left: 0;
+ transform: none;
+ padding: 0 20px;
+}
+
+.nav {
+ width: 100%;
+}
+
+.nav ul {
+ display: flex;
+ list-style: none;
+ width: 100%;
+}
+
+.nav ul li {
+ margin-right: 20px;
+}
+
+.nav ul li a {
+ text-decoration: none;
+ color: #333;
+ font-weight: 500;
+ transition: color 0.3s ease;
+}
+
+.nav ul li a:hover {
+ color: #8c4ff8;
+}
+
+.create-paper-btn {
+ background-color: #8c4ff8;
+ color: white;
+ border: none;
+ border-radius: 8px;
+ padding: 10px 20px;
+ font-size: 14px;
+ font-weight: 600;
+ cursor: pointer;
+ transition: background-color 0.3s ease;
+ width: 180px;
+ white-space: nowrap;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ text-align: center;
+}
+
+.create-paper-btn:hover {
+ background-color: #7a3dd6;
+}
+
+/* Point Sections */
+.point-section {
+ margin-bottom: 80px;
+}
+
+.point-badge {
+ display: inline-block;
+ background-color: #8c4ff8;
+ color: white;
+ font-weight: 600;
+ padding: 8px 16px;
+ border-radius: 20px;
+ margin-bottom: 20px;
+}
+
+.point-content h2 {
+ font-size: 28px;
+ font-weight: 700;
+ margin-bottom: 12px;
+ color: #333;
+}
+
+.point-content p {
+ font-size: 16px;
+ color: #666;
+ margin-bottom: 30px;
+}
+
+/* Cards Wrapper & Container */
+.cards-wrapper {
+ width: 100%;
+ overflow: hidden;
+ position: relative;
+}
+
+.cards-container {
+ display: flex;
+ gap: 20px;
+ overflow-x: auto;
+ padding: 10px 0;
+ position: relative;
+ scrollbar-width: none; /* Firefox */
+ -ms-overflow-style: none; /* IE and Edge */
+}
+
+.cards-container::-webkit-scrollbar {
+ display: none; /* Chrome, Safari, Opera */
+}
+
+.cards-container::-webkit-scrollbar-track {
+ background: transparent;
+}
+
+.cards-container::-webkit-scrollbar-thumb {
+ background-color: transparent;
+ border-radius: 6px;
+}
+
+.scroll-hint {
+ text-align: center;
+ font-size: 12px;
+ color: #999;
+ margin-top: 10px;
+ opacity: 0.7;
+ transition: opacity 0.5s ease;
+}
+
+/* Card Styles */
+.card {
+ background: white;
+ border-radius: 16px;
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.05);
+ width: 300px;
+ min-width: 300px;
+ padding: 20px;
+ display: flex;
+ flex-direction: column;
+ transition: transform 0.3s ease, box-shadow 0.3s ease;
+}
+
+.card:hover {
+ transform: translateY(-5px);
+ box-shadow: 0 8px 16px rgba(0, 0, 0, 0.1);
+}
+
+.card-header {
+ display: flex;
+ align-items: center;
+ margin-bottom: 15px;
+}
+
+.profile-img {
+ width: 40px;
+ height: 40px;
+ border-radius: 50%;
+ object-fit: cover;
+ margin-right: 12px;
+}
+
+.card-author {
+ display: flex;
+ flex-direction: column;
+}
+
+.card-author span:first-child {
+ font-weight: 600;
+ font-size: 14px;
+}
+
+.tag {
+ display: inline-block;
+ font-size: 12px;
+ padding: 2px 8px;
+ border-radius: 12px;
+ background-color: #e9f3ff;
+ color: #4a90e2;
+}
+
+.tag-purple {
+ background-color: #f0e7ff;
+ color: #8c4ff8;
+}
+
+.card-body {
+ flex-grow: 1;
+ margin-bottom: 15px;
+ font-size: 14px;
+ line-height: 1.5;
+}
+
+.card-footer {
+ font-size: 12px;
+ color: #999;
+}
+
+/* Add Card Button */
+.add-card {
+ background: white;
+ border-radius: 16px;
+ border: 2px dashed #ddd;
+ width: 300px;
+ min-width: 300px;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ cursor: pointer;
+}
+
+.add-icon {
+ font-size: 32px;
+ color: #999;
+}
+
+/* Reactions Section */
+.reactions-section {
+ margin-bottom: 80px;
+}
+
+.reactions-container {
+ position: relative;
+ width: fit-content;
+}
+
+.reaction-row {
+ display: flex;
+ gap: 10px;
+ margin-bottom: 10px;
+}
+
+.reaction-count {
+ display: flex;
+ align-items: center;
+ background: #f0f0f0;
+ border-radius: 20px;
+ padding: 6px 12px;
+ font-size: 14px;
+ font-weight: 500;
+}
+
+.emoji {
+ margin-right: 5px;
+}
+
+.reactions-dropdown {
+ position: absolute;
+ top: 100%;
+ left: 0;
+ background: white;
+ border-radius: 12px;
+ box-shadow: 0 4px 16px rgba(0, 0, 0, 0.1);
+ padding: 15px;
+ z-index: 10;
+ margin-top: 10px;
+ width: 300px;
+}
+
+/* Media Queries */
+/* 태블릿 디바이스 */
+@media (max-width: 1024px) {
+ .container {
+ max-width: 90%;
+ padding: 30px 15px;
+ }
+
+ .point-section {
+ margin-bottom: 60px;
+ }
+
+ .point-content h2 {
+ font-size: 26px;
+ }
+
+ .cards-wrapper {
+ width: 100%;
+ max-width: 100%;
+ overflow-x: auto;
+ padding-bottom: 15px;
+ margin: 0 auto;
+ }
+
+ .cards-container {
+ width: 100%;
+ padding: 10px 15px 5px;
+ display: grid;
+ grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
+ gap: 20px;
+ overflow-x: visible;
+ justify-content: center;
+ }
+
+ .card,
+ .add-card {
+ width: 100%;
+ min-width: auto;
+ max-width: 100%;
+ transition: transform 0.3s ease, box-shadow 0.3s ease;
+ }
+}
+
+/* 모바일 디바이스 */
+@media (max-width: 768px) {
+ .container {
+ padding: 20px 15px;
+ }
+
+ .container:first-of-type {
+ padding-top: 80px;
+ }
+
+ .header {
+ padding: 0 15px;
+ height: 60px;
+ }
+
+ .create-paper-btn {
+ font-size: 12px;
+ padding: 8px 15px;
+ width: 150px;
+ }
+
+ .point-badge {
+ padding: 6px 12px;
+ font-size: 14px;
+ }
+
+ .point-content h2 {
+ font-size: 22px;
+ margin-bottom: 10px;
+ }
+
+ .point-content p {
+ font-size: 14px;
+ margin-bottom: 20px;
+ }
+
+ .cards-wrapper {
+ margin: 0 auto;
+ width: 100%;
+ overflow-x: hidden;
+ overflow-y: visible;
+ padding-bottom: 10px;
+ scrollbar-width: none; /* Firefox */
+ -ms-overflow-style: none; /* IE and Edge */
+ }
+
+ .cards-wrapper::-webkit-scrollbar {
+ display: none; /* Chrome, Safari, Opera */
+ }
+
+ .cards-container {
+ display: flex;
+ flex-direction: column;
+ overflow-x: hidden;
+ padding: 0 15px 10px;
+ width: 100%;
+ max-width: 100%;
+ gap: 20px;
+ }
+
+ .card,
+ .add-card {
+ width: 100%;
+ min-width: auto;
+ max-width: 100%;
+ margin: 0 auto;
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
+ }
+
+ .reaction-row {
+ flex-wrap: wrap;
+ }
+
+ .reactions-dropdown {
+ width: 100%;
+ max-width: 280px;
+ }
+
+ /* 스크롤 인디케이터 스타일 */
+ .scroll-indicator {
+ margin: 15px auto 0;
+ width: 80%;
+ height: 4px;
+ background: #eee;
+ border-radius: 2px;
+ overflow: hidden;
+ }
+
+ .scroll-indicator span {
+ display: block;
+ height: 100%;
+ width: 33.33%;
+ background: #8c4ff8;
+ border-radius: 2px;
+ transition: transform 0.3s ease;
+ }
+
+ .cta-button {
+ padding: 12px 25px;
+ font-size: 14px;
+ width: 80%;
+ max-width: 300px;
+ }
+}
+
+/* CTA Section Styles */
+.cta-section {
+ text-align: center;
+ margin-bottom: 60px;
+}
+
+.cta-button {
+ background-color: #8c4ff8;
+ color: white;
+ border: none;
+ border-radius: 8px;
+ padding: 15px 30px;
+ font-size: 16px;
+ font-weight: 600;
+ cursor: pointer;
+ transition: all 0.3s ease;
+ box-shadow: 0 4px 12px rgba(140, 79, 248, 0.2);
+}
+
+.cta-button:hover {
+ background-color: #7a3dd6;
+ transform: translateY(-2px);
+ box-shadow: 0 6px 16px rgba(140, 79, 248, 0.3);
+}
+
+/* 작은 모바일 디바이스 */
+@media (max-width: 480px) {
+ .point-section {
+ margin-bottom: 40px;
+ }
+
+ .point-content h2 {
+ font-size: 20px;
+ }
+
+ .card,
+ .add-card {
+ width: 100%;
+ min-width: auto;
+ max-width: 100%;
+ padding: 15px;
+ margin: 0 auto;
+ border-radius: 14px;
+ }
+
+ .cards-wrapper {
+ padding: 0;
+ margin: 0 auto;
+ width: 100%;
+ scrollbar-width: none; /* Firefox */
+ -ms-overflow-style: none; /* IE and Edge */
+ }
+
+ .cards-wrapper::-webkit-scrollbar {
+ display: none; /* Chrome, Safari, Opera */
+ }
+
+ .cards-container {
+ width: 100%;
+ padding: 0 15px 10px;
+ gap: 15px;
+ }
+
+ .card-body {
+ font-size: 13px;
+ }
+
+ .reaction-count {
+ padding: 4px 10px;
+ font-size: 13px;
+ }
+
+ .scroll-indicator {
+ width: 90%;
+ margin: 10px auto 0;
+ }
+
+ .cta-button {
+ padding: 10px 20px;
+ font-size: 13px;
+ width: 90%;
+ }
+}
diff --git a/src/utils/script.js b/src/utils/script.js
new file mode 100644
index 0000000..8d05dd0
--- /dev/null
+++ b/src/utils/script.js
@@ -0,0 +1,170 @@
+document.addEventListener("DOMContentLoaded", function () {
+ // 모바일 메뉴 토글 기능
+ const mobileMenuBtn = document.querySelector(".mobile-menu-btn");
+ const navMenu = document.querySelector(".nav ul");
+ const createPaperBtnMobile = document.querySelector(".create-paper-btn");
+
+ if (mobileMenuBtn && navMenu) {
+ mobileMenuBtn.addEventListener("click", function () {
+ if (navMenu.style.display === "flex") {
+ navMenu.style.display = "none";
+ mobileMenuBtn.classList.remove("active");
+ } else {
+ navMenu.style.display = "flex";
+ navMenu.style.flexDirection = "column";
+ navMenu.style.position = "absolute";
+ navMenu.style.top = "60px";
+ navMenu.style.right = "20px";
+ navMenu.style.backgroundColor = "white";
+ navMenu.style.padding = "15px";
+ navMenu.style.borderRadius = "8px";
+ navMenu.style.boxShadow = "0 4px 12px rgba(0, 0, 0, 0.1)";
+ navMenu.style.zIndex = "100";
+ mobileMenuBtn.classList.add("active");
+ }
+ });
+ }
+
+ // 이모지 반응 토글 기능
+ const reactionsContainer = document.querySelector(".reactions-container");
+ const reactionsDropdown = document.querySelector(".reactions-dropdown");
+ const reactionAdd = document.querySelector(".reaction-add");
+
+ // 초기에는 드롭다운 숨기기
+ if (reactionsDropdown) {
+ reactionsDropdown.style.display = "none";
+ }
+
+ // 이모지 추가 버튼 클릭 시 드롭다운 토글
+ if (reactionAdd) {
+ reactionAdd.addEventListener("click", function (e) {
+ e.stopPropagation();
+ if (reactionsDropdown.style.display === "none") {
+ reactionsDropdown.style.display = "block";
+ } else {
+ reactionsDropdown.style.display = "none";
+ }
+ });
+ }
+
+ // 드롭다운 외부 클릭 시 닫기
+ document.addEventListener("click", function (event) {
+ if (reactionsContainer && !reactionsContainer.contains(event.target)) {
+ if (reactionsDropdown) {
+ reactionsDropdown.style.display = "none";
+ }
+ }
+ });
+
+ // 새 카드 추가 버튼 기능
+ const addCardButton = document.querySelector(".add-card");
+ if (addCardButton) {
+ addCardButton.addEventListener("click", function () {
+ alert("새 메시지를 작성할 수 있는 폼이 열립니다.");
+ // 실제 구현에서는 모달 폼을 열거나 페이지 이동 등의 기능 구현
+ });
+ }
+
+ // 이모지 반응 클릭 시 카운트 증가 (예시 기능)
+ const reactionCounts = document.querySelectorAll(".reaction-count");
+ reactionCounts.forEach(function (reaction) {
+ reaction.addEventListener("click", function (e) {
+ e.stopPropagation(); // 상위 이벤트 전파 방지
+ const countElement = this.querySelector("span:last-child");
+ if (countElement) {
+ let count = parseInt(countElement.textContent);
+ countElement.textContent = count + 1;
+ }
+ });
+ });
+
+ // CTA 버튼 클릭 이벤트
+ const ctaButton = document.querySelector(".cta-button");
+ if (ctaButton) {
+ ctaButton.addEventListener("click", function () {
+ window.location.href = "#"; // 실제 구현에서는 롤링페이퍼 목록 페이지로 이동
+ });
+ }
+
+ // 롤링페이퍼 만들기 버튼 클릭 이벤트
+ const createPaperBtn = document.querySelector(".create-paper-btn");
+ if (createPaperBtn) {
+ createPaperBtn.addEventListener("click", function () {
+ window.location.href = "#"; // 실제 구현에서는 롤링페이퍼 생성 페이지로 이동
+ });
+ }
+
+ // 반응형 디자인을 위한 추가 기능
+ function handleResize() {
+ // 화면 크기에 따라 동적으로 조정이 필요한 요소들 처리
+ const windowWidth = window.innerWidth;
+ const cardsContainer = document.querySelector(".cards-container");
+ const cardsWrapper = document.querySelector(".cards-wrapper");
+
+ // 모바일 메뉴 처리
+ if (windowWidth > 768) {
+ const navMenu = document.querySelector(".nav ul");
+ if (navMenu) {
+ navMenu.removeAttribute("style");
+ }
+ }
+
+ // 카드 컨테이너 스크롤 처리
+ if (cardsContainer && cardsWrapper) {
+ // 스크롤 인디케이터 추가 (모바일에서만)
+ if (windowWidth <= 768) {
+ if (!document.querySelector(".scroll-indicator")) {
+ const scrollIndicator = document.createElement("div");
+ scrollIndicator.className = "scroll-indicator";
+ const scrollIndicatorSpan = document.createElement("span");
+ scrollIndicator.appendChild(scrollIndicatorSpan);
+ cardsWrapper.after(scrollIndicator);
+ }
+ } else {
+ // 태블릿/데스크톱에서는 스크롤 표시기 제거
+ const scrollIndicator = document.querySelector(".scroll-indicator");
+ if (scrollIndicator) {
+ scrollIndicator.remove();
+ }
+ }
+ }
+ }
+
+ // 초기 로드 및 리사이즈 시 실행
+ handleResize();
+ window.addEventListener("resize", handleResize);
+
+ // 화면 방향 변경 감지
+ window.addEventListener("orientationchange", () => {
+ setTimeout(handleResize, 300); // 방향 변경 후 약간의 지연 시간을 두고 실행
+ });
+
+ // 카드 컨테이너 스크롤 이벤트
+ const cardsContainer = document.querySelector(".cards-container");
+ if (cardsContainer) {
+ cardsContainer.addEventListener("scroll", function () {
+ const scrollIndicator = document.querySelector(".scroll-indicator span");
+ if (scrollIndicator) {
+ const scrollPercentage =
+ (this.scrollLeft / (this.scrollWidth - this.clientWidth)) * 100;
+ scrollIndicator.style.width = scrollPercentage + "%";
+ }
+ });
+ }
+ // 카드 컨테이너 가로 스크롤 감추기이벤트
+ const cardsContainer = document.querySelector(".cards-container");
+ if (cardsContainer) {
+ // 모바일 환경에서 가로 스크롤 기능 비활성화
+ if (window.innerWidth <= 768) {
+ cardsContainer.style.overflowX = "hidden";
+ cardsContainer.style.overflowY = "auto";
+
+ // 스크롤 인디케이터 제거
+ const scrollIndicator = document.querySelector(".scroll-indicator");
+ if (scrollIndicator) {
+ scrollIndicator.style.display = "none";
+ }
+ } else {
+ }
+ }
+});