diff --git a/app.js b/app.js
new file mode 100644
index 0000000..aac0b59
--- /dev/null
+++ b/app.js
@@ -0,0 +1,232 @@
+const DAY_NAMES = ["일", "월", "화", "수", "목", "금", "토"];
+
+/* ── State ── */
+let selectedDate = new Date();
+let weekOffset = 0;
+let todos = loadTodos();
+
+/* ── DOM Elements ── */
+const currentDateEl = document.getElementById("currentDate");
+const weekDaysEl = document.getElementById("weekDays");
+const prevWeekBtn = document.getElementById("prevWeek");
+const nextWeekBtn = document.getElementById("nextWeek");
+const todoForm = document.getElementById("todoForm");
+const todoInput = document.getElementById("todoInput");
+const todoList = document.getElementById("todoList");
+const todoCountEl = document.getElementById("todoCount");
+const themeToggleBtn = document.getElementById("themeToggle");
+
+/* ── LocalStorage ── */
+function loadTodos() {
+ try {
+ return JSON.parse(localStorage.getItem("todos")) || {};
+ } catch {
+ return {};
+ }
+}
+
+function saveTodos() {
+ localStorage.setItem("todos", JSON.stringify(todos));
+}
+
+/* ── Date Helpers ── */
+function formatDateKey(date) {
+ const y = date.getFullYear();
+ const m = String(date.getMonth() + 1).padStart(2, "0");
+ const d = String(date.getDate()).padStart(2, "0");
+ return `${y}-${m}-${d}`;
+}
+
+function isSameDay(a, b) {
+ return formatDateKey(a) === formatDateKey(b);
+}
+
+function getWeekDates(offset) {
+ const today = new Date();
+ const dayOfWeek = today.getDay();
+
+ // 선택된 주의 일요일 날짜 계산
+ const sunday = new Date(today);
+ sunday.setDate(today.getDate() - dayOfWeek + offset * 7);
+
+ // 선택된 주의 날짜 설정
+ const dates = [];
+ for (let i = 0; i < 7; i++) {
+ const date = new Date(sunday);
+ date.setDate(sunday.getDate() + i);
+ dates.push(date);
+ }
+ return dates;
+}
+
+function formatDisplayDate(date) {
+ const y = date.getFullYear();
+ const m = date.getMonth() + 1;
+ const d = date.getDate();
+ const day = DAY_NAMES[date.getDay()];
+ return `${y}년 ${m}월 ${d}일 ${day}요일`;
+}
+
+/* ── Render: Week Navigation ── */
+function renderWeek() {
+ const weekDates = getWeekDates(weekOffset);
+ const today = new Date();
+
+ weekDaysEl.innerHTML = "";
+
+ weekDates.forEach((date) => {
+ const dateKey = formatDateKey(date);
+ const todoCount = (todos[dateKey] || []).length;
+ const isSelected = isSameDay(date, selectedDate);
+ const isToday = isSameDay(date, today);
+
+ const li = document.createElement("li");
+ li.className = "week-nav__day";
+ if (isSelected) li.classList.add("week-nav__day--selected");
+ if (isToday) li.classList.add("week-nav__day--today");
+
+ const dayName = document.createElement("span");
+ dayName.className = "week-nav__day-name";
+ dayName.textContent = DAY_NAMES[date.getDay()];
+
+ const dayNumber = document.createElement("span");
+ dayNumber.className = "week-nav__day-number";
+ dayNumber.textContent = date.getDate();
+
+ const dayCount = document.createElement("span");
+ dayCount.className = "week-nav__day-count";
+ dayCount.textContent = todoCount > 0 ? `${todoCount}개` : "";
+
+ li.appendChild(dayName);
+ li.appendChild(dayNumber);
+ li.appendChild(dayCount);
+
+ li.addEventListener("click", () => {
+ selectedDate = new Date(date);
+ render();
+ });
+
+ weekDaysEl.appendChild(li);
+ });
+}
+
+/* ── Render: Todo List ── */
+function renderTodos() {
+ const dateKey = formatDateKey(selectedDate);
+ const currentTodos = todos[dateKey] || [];
+
+ todoCountEl.textContent = `${currentTodos.length}개`;
+ todoList.innerHTML = "";
+
+ if (currentTodos.length === 0) {
+ const emptyLi = document.createElement("li");
+ emptyLi.className = "todo-list__empty";
+ emptyLi.textContent = "할 일이 없습니다";
+ todoList.appendChild(emptyLi);
+ return;
+ }
+
+ currentTodos.forEach((todo, index) => {
+ const li = document.createElement("li");
+ li.className = "todo-item";
+ if (todo.done) li.classList.add("todo-item--done");
+
+ const checkbox = document.createElement("button");
+ checkbox.className = "todo-item__checkbox";
+ checkbox.setAttribute("aria-label", "완료 토글");
+ checkbox.addEventListener("click", () => toggleTodo(dateKey, index));
+
+ const text = document.createElement("span");
+ text.className = "todo-item__text";
+ text.textContent = todo.text;
+
+ const deleteBtn = document.createElement("button");
+ deleteBtn.className = "todo-item__delete";
+ deleteBtn.setAttribute("aria-label", "삭제");
+ deleteBtn.textContent = "×";
+ deleteBtn.addEventListener("click", () => deleteTodo(dateKey, index));
+
+ li.appendChild(checkbox);
+ li.appendChild(text);
+ li.appendChild(deleteBtn);
+ todoList.appendChild(li);
+ });
+}
+
+/* ── Render All ── */
+function render() {
+ currentDateEl.textContent = formatDisplayDate(selectedDate);
+ renderWeek();
+ renderTodos();
+}
+
+/* ── Todo Actions ── */
+function addTodo(text) {
+ const dateKey = formatDateKey(selectedDate);
+ if (!todos[dateKey]) {
+ todos[dateKey] = [];
+ }
+ todos[dateKey].push({ text, done: false });
+ saveTodos();
+ render();
+}
+
+function toggleTodo(dateKey, index) {
+ todos[dateKey][index].done = !todos[dateKey][index].done;
+ saveTodos();
+ render();
+}
+
+function deleteTodo(dateKey, index) {
+ todos[dateKey].splice(index, 1);
+ if (todos[dateKey].length === 0) {
+ delete todos[dateKey];
+ }
+ saveTodos();
+ render();
+}
+
+/* ── Dark Mode ── */
+function loadTheme() {
+ const savedTheme = localStorage.getItem("theme");
+ if (savedTheme === "dark") {
+ document.body.classList.add("dark");
+ themeToggleBtn.textContent = "\u2600\uFE0F";
+ }
+}
+
+function toggleTheme() {
+ const isDark = document.body.classList.toggle("dark");
+ themeToggleBtn.textContent = isDark ? "\u2600\uFE0F" : "\uD83C\uDF19";
+ localStorage.setItem("theme", isDark ? "dark" : "light");
+}
+
+/* ── Event Listeners ── */
+themeToggleBtn.addEventListener("click", toggleTheme);
+
+todoForm.addEventListener("submit", (e) => {
+ // 불필요한 페이지 새로고침 방지 및 현재 UI 유지
+ e.preventDefault();
+
+ // 공백 문자열만 입력 시 등록 안되도록 공백 제거
+ const text = todoInput.value.trim();
+ if (text) {
+ addTodo(text);
+ todoInput.value = "";
+ todoInput.focus();
+ }
+});
+
+prevWeekBtn.addEventListener("click", () => {
+ weekOffset--;
+ render();
+});
+
+nextWeekBtn.addEventListener("click", () => {
+ weekOffset++;
+ render();
+});
+
+/* ── Init ── */
+loadTheme();
+render();
diff --git a/index.html b/index.html
new file mode 100644
index 0000000..9902e17
--- /dev/null
+++ b/index.html
@@ -0,0 +1,60 @@
+
+
+
+
+
+ Todo가 미래다
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/style.css b/style.css
new file mode 100644
index 0000000..6d1d47f
--- /dev/null
+++ b/style.css
@@ -0,0 +1,428 @@
+/* Reset & Base */
+* {
+ margin: 0;
+ padding: 0;
+ box-sizing: border-box;
+}
+
+body {
+ font-family: 'Pretendard', -apple-system, BlinkMacSystemFont, sans-serif;
+ background-color: #f5f5f7;
+ color: #1d1d1f;
+ min-height: 100vh;
+ display: flex;
+ justify-content: center;
+ align-items: flex-start;
+ padding: 40px 16px;
+}
+
+/* App Container */
+.app {
+ width: 100%;
+ max-width: 480px;
+ display: flex;
+ flex-direction: column;
+ gap: 24px;
+}
+
+/* Header */
+.header {
+ display: flex;
+ flex-direction: column;
+ gap: 4px;
+}
+
+.header__top {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+}
+
+.header__title {
+ font-size: 32px;
+ font-weight: 700;
+ color: #1d1d1f;
+}
+
+/* Theme Toggle */
+.theme-toggle {
+ background: none;
+ border: none;
+ font-size: 24px;
+ cursor: pointer;
+ padding: 4px;
+ border-radius: 8px;
+ transition: background-color 0.2s;
+ line-height: 1;
+}
+
+.theme-toggle:hover {
+ background-color: #e8e8ed;
+}
+
+.header__date {
+ font-size: 14px;
+ color: #86868b;
+ font-weight: 400;
+}
+
+/* Week Navigation */
+.week-nav {
+ display: flex;
+ align-items: center;
+ gap: 8px;
+}
+
+.week-nav__btn {
+ background: none;
+ border: none;
+ font-size: 16px;
+ color: #86868b;
+ cursor: pointer;
+ padding: 8px;
+ border-radius: 8px;
+ transition: background-color 0.2s;
+ flex-shrink: 0;
+}
+
+.week-nav__btn:hover {
+ background-color: #e8e8ed;
+}
+
+.week-nav__days {
+ display: flex;
+ flex: 1;
+ gap: 4px;
+ list-style: none;
+}
+
+.week-nav__day {
+ flex: 1;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ gap: 4px;
+ padding: 10px 4px;
+ border-radius: 12px;
+ cursor: pointer;
+ transition: background-color 0.2s;
+}
+
+.week-nav__day:hover {
+ background-color: #e8e8ed;
+}
+
+.week-nav__day--selected {
+ background-color: #1d1d1f;
+ color: #ffffff;
+}
+
+.week-nav__day--selected:hover {
+ background-color: #333336;
+}
+
+.week-nav__day--today {
+ position: relative;
+}
+
+.week-nav__day--today::after {
+ content: '';
+ width: 5px;
+ height: 5px;
+ background-color: #ff3b30;
+ border-radius: 50%;
+ position: absolute;
+ top: 4px;
+ right: 8px;
+}
+
+.week-nav__day-name {
+ font-size: 11px;
+ font-weight: 500;
+ color: #86868b;
+}
+
+.week-nav__day--selected .week-nav__day-name {
+ color: #a1a1a6;
+}
+
+.week-nav__day-number {
+ font-size: 16px;
+ font-weight: 600;
+}
+
+.week-nav__day-count {
+ font-size: 10px;
+ font-weight: 500;
+ color: #86868b;
+ min-height: 14px;
+}
+
+.week-nav__day--selected .week-nav__day-count {
+ color: #a1a1a6;
+}
+
+/* Todo Section */
+.todo-section {
+ display: flex;
+ flex-direction: column;
+ gap: 16px;
+}
+
+.todo-section__header {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+}
+
+.todo-section__count {
+ font-size: 18px;
+ font-weight: 600;
+ color: #1d1d1f;
+}
+
+/* Todo Form */
+.todo-form {
+ display: flex;
+ gap: 8px;
+}
+
+.todo-form__input {
+ flex: 1;
+ padding: 12px 16px;
+ border: 1px solid #d2d2d7;
+ border-radius: 12px;
+ font-size: 14px;
+ font-family: inherit;
+ outline: none;
+ transition: border-color 0.2s;
+ background-color: #ffffff;
+}
+
+.todo-form__input:focus {
+ border-color: #1d1d1f;
+}
+
+.todo-form__btn {
+ padding: 12px 20px;
+ background-color: #1d1d1f;
+ color: #ffffff;
+ border: none;
+ border-radius: 12px;
+ font-size: 14px;
+ font-weight: 600;
+ font-family: inherit;
+ cursor: pointer;
+ transition: background-color 0.2s;
+ flex-shrink: 0;
+}
+
+.todo-form__btn:hover {
+ background-color: #333336;
+}
+
+/* Todo List */
+.todo-list {
+ display: flex;
+ flex-direction: column;
+ gap: 8px;
+ list-style: none;
+}
+
+.todo-item {
+ display: flex;
+ align-items: center;
+ gap: 12px;
+ padding: 14px 16px;
+ background-color: #ffffff;
+ border-radius: 12px;
+ transition: opacity 0.2s;
+}
+
+.todo-item--done {
+ opacity: 0.5;
+}
+
+.todo-item__checkbox {
+ width: 22px;
+ height: 22px;
+ border: 2px solid #d2d2d7;
+ border-radius: 50%;
+ cursor: pointer;
+ flex-shrink: 0;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ transition: all 0.2s;
+ background: none;
+ padding: 0;
+}
+
+.todo-item__checkbox:hover {
+ border-color: #1d1d1f;
+}
+
+.todo-item--done .todo-item__checkbox {
+ background-color: #1d1d1f;
+ border-color: #1d1d1f;
+}
+
+.todo-item--done .todo-item__checkbox::after {
+ content: '✓';
+ color: #ffffff;
+ font-size: 12px;
+ font-weight: 700;
+}
+
+.todo-item__text {
+ flex: 1;
+ font-size: 14px;
+ font-weight: 400;
+ word-break: break-word;
+}
+
+.todo-item--done .todo-item__text {
+ text-decoration: line-through;
+ color: #86868b;
+}
+
+.todo-item__delete {
+ background: none;
+ border: none;
+ font-size: 18px;
+ color: #d2d2d7;
+ cursor: pointer;
+ padding: 4px;
+ line-height: 1;
+ transition: color 0.2s;
+}
+
+.todo-item__delete:hover {
+ color: #ff3b30;
+}
+
+/* Empty State */
+.todo-list__empty {
+ text-align: center;
+ padding: 40px 0;
+ color: #86868b;
+ font-size: 14px;
+}
+
+/* Dark Mode */
+body.dark {
+ background-color: #1c1c1e;
+ color: #f5f5f7;
+}
+
+body.dark .header__title {
+ color: #f5f5f7;
+}
+
+body.dark .theme-toggle:hover {
+ background-color: #3a3a3c;
+}
+
+body.dark .week-nav__btn {
+ color: #a1a1a6;
+}
+
+body.dark .week-nav__btn:hover {
+ background-color: #3a3a3c;
+}
+
+body.dark .week-nav__day:hover {
+ background-color: #3a3a3c;
+}
+
+body.dark .week-nav__day--selected {
+ background-color: #f5f5f7;
+ color: #1c1c1e;
+}
+
+body.dark .week-nav__day--selected:hover {
+ background-color: #e5e5e7;
+}
+
+body.dark .week-nav__day--selected .week-nav__day-name {
+ color: #86868b;
+}
+
+body.dark .week-nav__day--selected .week-nav__day-count {
+ color: #86868b;
+}
+
+body.dark .todo-section__count {
+ color: #f5f5f7;
+}
+
+body.dark .todo-form__input {
+ background-color: #2c2c2e;
+ border-color: #3a3a3c;
+ color: #f5f5f7;
+}
+
+body.dark .todo-form__input:focus {
+ border-color: #f5f5f7;
+}
+
+body.dark .todo-form__btn {
+ background-color: #f5f5f7;
+ color: #1c1c1e;
+}
+
+body.dark .todo-form__btn:hover {
+ background-color: #e5e5e7;
+}
+
+body.dark .todo-item {
+ background-color: #2c2c2e;
+}
+
+body.dark .todo-item__checkbox {
+ border-color: #48484a;
+}
+
+body.dark .todo-item__checkbox:hover {
+ border-color: #f5f5f7;
+}
+
+body.dark .todo-item--done .todo-item__checkbox {
+ background-color: #f5f5f7;
+ border-color: #f5f5f7;
+}
+
+body.dark .todo-item--done .todo-item__checkbox::after {
+ color: #1c1c1e;
+}
+
+body.dark .todo-item__text {
+ color: #f5f5f7;
+}
+
+body.dark .todo-item__delete {
+ color: #48484a;
+}
+
+/* Responsive */
+@media (max-width: 480px) {
+ body {
+ padding: 24px 12px;
+ }
+
+ .header__title {
+ font-size: 28px;
+ }
+
+ .week-nav__day {
+ padding: 8px 2px;
+ }
+
+ .week-nav__day-number {
+ font-size: 14px;
+ }
+
+ .week-nav__day-name {
+ font-size: 10px;
+ }
+}