diff --git a/javascript/todo-list/index.html b/javascript/todo-list/index.html
new file mode 100644
index 0000000..ada2be2
--- /dev/null
+++ b/javascript/todo-list/index.html
@@ -0,0 +1,29 @@
+
+
+
+
+
+ Todo List
+
+
+
+
+ Todo List
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/javascript/todo-list/script.js b/javascript/todo-list/script.js
new file mode 100644
index 0000000..1d418b0
--- /dev/null
+++ b/javascript/todo-list/script.js
@@ -0,0 +1,122 @@
+(() => {
+ const STORAGE_KEY = 'todo.list.items.v1';
+
+ /** @type {{ id: string; text: string; completed: boolean }[]} */
+ let items = [];
+
+ const form = document.getElementById('todo-form');
+ const input = document.getElementById('todo-input');
+ const list = document.getElementById('todo-list');
+ const clearCompletedBtn = document.getElementById('clear-completed');
+
+ function load() {
+ try {
+ const raw = localStorage.getItem(STORAGE_KEY);
+ items = raw ? JSON.parse(raw) : [];
+ if (!Array.isArray(items)) items = [];
+ } catch { items = []; }
+ }
+
+ function save() {
+ localStorage.setItem(STORAGE_KEY, JSON.stringify(items));
+ }
+
+ function createItem(text) {
+ return { id: String(Date.now()) + Math.random().toString(36).slice(2), text, completed: false };
+ }
+
+ function render() {
+ list.innerHTML = '';
+ for (const item of items) {
+ const li = document.createElement('li');
+ li.className = 'todo-item';
+ li.dataset.id = item.id;
+
+ const checkbox = document.createElement('input');
+ checkbox.type = 'checkbox';
+ checkbox.className = 'todo-check';
+ checkbox.checked = item.completed;
+
+ const p = document.createElement('p');
+ p.className = 'todo-text' + (item.completed ? ' completed' : '');
+ p.textContent = item.text;
+
+ const del = document.createElement('button');
+ del.className = 'delete-btn';
+ del.type = 'button';
+ del.textContent = 'Delete';
+
+ li.appendChild(checkbox);
+ li.appendChild(p);
+ li.appendChild(del);
+ list.appendChild(li);
+ }
+ }
+
+ function addItem(text) {
+ const trimmed = text.trim();
+ if (!trimmed) return;
+ items.unshift(createItem(trimmed));
+ save();
+ render();
+ }
+
+ function deleteItem(id) {
+ items = items.filter(i => i.id !== id);
+ save();
+ render();
+ }
+
+ function toggleItem(id, completed) {
+ const item = items.find(i => i.id === id);
+ if (!item) return;
+ item.completed = completed;
+ save();
+ render();
+ }
+
+ function clearCompleted() {
+ items = items.filter(i => !i.completed);
+ save();
+ render();
+ }
+
+ form.addEventListener('submit', (e) => {
+ e.preventDefault();
+ addItem(input.value);
+ input.value = '';
+ input.focus();
+ });
+
+ list.addEventListener('click', (e) => {
+ const target = e.target;
+ if (!(target instanceof HTMLElement)) return;
+ const li = target.closest('.todo-item');
+ if (!li) return;
+ const id = li.dataset.id;
+ if (!id) return;
+ if (target.classList.contains('delete-btn')) {
+ deleteItem(id);
+ }
+ });
+
+ list.addEventListener('change', (e) => {
+ const target = e.target;
+ if (!(target instanceof HTMLInputElement)) return;
+ if (!target.classList.contains('todo-check')) return;
+ const li = target.closest('.todo-item');
+ if (!li) return;
+ const id = li.dataset.id;
+ if (!id) return;
+ toggleItem(id, target.checked);
+ });
+
+ clearCompletedBtn.addEventListener('click', () => {
+ clearCompleted();
+ });
+
+ load();
+ render();
+})();
+
+
diff --git a/javascript/todo-list/style.css b/javascript/todo-list/style.css
new file mode 100644
index 0000000..044f669
--- /dev/null
+++ b/javascript/todo-list/style.css
@@ -0,0 +1,88 @@
+:root {
+ --bg: #0f172a;
+ --panel: #111827;
+ --text: #e5e7eb;
+ --muted: #9ca3af;
+ --accent: #22c55e;
+ --danger: #ef4444;
+ --border: #1f2937;
+}
+
+* { box-sizing: border-box; }
+html, body { height: 100%; }
+body {
+ margin: 0;
+ font-family: ui-sans-serif, system-ui, -apple-system, Segoe UI, Roboto, Ubuntu, Cantarell, Noto Sans, Helvetica Neue, Arial, "Apple Color Emoji", "Segoe UI Emoji";
+ background: linear-gradient(180deg, #0b1023, #121a36 60%, #0b1023);
+ color: var(--text);
+ display: grid;
+ place-items: center;
+}
+
+.app {
+ width: 100%;
+ max-width: 720px;
+ padding: 24px;
+}
+
+.title { margin: 0 0 16px; font-weight: 700; letter-spacing: 0.3px; }
+
+.todo-form {
+ display: grid;
+ grid-template-columns: 1fr auto;
+ gap: 12px;
+ margin-bottom: 16px;
+}
+
+.todo-input {
+ padding: 12px 14px;
+ background: var(--panel);
+ border: 1px solid var(--border);
+ border-radius: 10px;
+ color: var(--text);
+ outline: none;
+}
+.todo-input::placeholder { color: var(--muted); }
+
+.add-btn, .clear-btn {
+ padding: 12px 16px;
+ border: 1px solid var(--border);
+ border-radius: 10px;
+ background: #0b1324;
+ color: var(--text);
+ cursor: pointer;
+}
+.add-btn:hover { background: #0e172e; }
+.clear-btn:hover { background: #0e172e; }
+
+.todo-list { list-style: none; padding: 0; margin: 0; display: grid; gap: 10px; }
+
+.todo-item {
+ display: grid;
+ grid-template-columns: auto 1fr auto;
+ align-items: center;
+ gap: 12px;
+ background: var(--panel);
+ border: 1px solid var(--border);
+ border-radius: 12px;
+ padding: 12px 14px;
+}
+
+.todo-check { width: 18px; height: 18px; cursor: pointer; }
+
+.todo-text { margin: 0; }
+.todo-text.completed { color: var(--muted); text-decoration: line-through; }
+
+.delete-btn {
+ background: transparent;
+ color: var(--danger);
+ border: 1px solid var(--border);
+ padding: 8px 10px;
+ border-radius: 8px;
+ cursor: pointer;
+}
+.delete-btn:hover { background: rgba(239, 68, 68, 0.08); }
+
+.footer { margin-top: 14px; display: flex; justify-content: flex-end; }
+
+