diff --git a/Sprint-3/alarmclock/alarmclock.js b/Sprint-3/alarmclock/alarmclock.js index 6ca81cd3b..55d8be0fd 100644 --- a/Sprint-3/alarmclock/alarmclock.js +++ b/Sprint-3/alarmclock/alarmclock.js @@ -1,4 +1,15 @@ -function setAlarm() {} +function setAlarm() { + const seconds = parseInt(document.getElementById("alarmTime").value, 10); + + if (isNaN(seconds) || seconds < 0) { + alert("Please enter a valid number of seconds."); + return; + } + + setTimeout(playAlarm, seconds * 1000); +} + + // DO NOT EDIT BELOW HERE diff --git a/Sprint-3/alarmclock/index.html b/Sprint-3/alarmclock/index.html index 48e2e80d9..1ec2ab77b 100644 --- a/Sprint-3/alarmclock/index.html +++ b/Sprint-3/alarmclock/index.html @@ -1,20 +1,97 @@ - - - - - Title here - - -
-

Time Remaining: 00:00

- - - - - -
- - + + + + Alarm Timer + + + + +
00:00
+
+

Set Alarm

+ + + + +
+ + + + diff --git a/Sprint-3/alarmclock/package.json b/Sprint-3/alarmclock/package.json index b532c6908..137a12d2d 100644 --- a/Sprint-3/alarmclock/package.json +++ b/Sprint-3/alarmclock/package.json @@ -8,12 +8,12 @@ }, "repository": { "type": "git", - "url": "git+https://github.com/CodeYourFuture/CYF-Coursework-Template.git" + "url": "git+https://github.com/Elfredah?tab=repositories" }, "bugs": { - "url": "https://github.com/CodeYourFuture/CYF-Coursework-Template/issues" + "url": "https://github.com/issues/assigned" }, - "homepage": "https://github.com/CodeYourFuture/CYF-Coursework-Template#readme", + "homepage": "https://github.com/users/Elfredah/projects/4", "devDependencies": { "@testing-library/dom": "^8.19.0", "@testing-library/jest-dom": "^5.16.5", diff --git a/Sprint-3/quote-generator/index.html b/Sprint-3/quote-generator/index.html index 30b434bcf..19ecb48aa 100644 --- a/Sprint-3/quote-generator/index.html +++ b/Sprint-3/quote-generator/index.html @@ -1,15 +1,125 @@ - - - - Title here - - - -

hello there

-

-

- - + + + + Random Quote Generator + + + + +
+

"Your quote will appear here."

+

- Author

+
+ + + + + + diff --git a/Sprint-3/quote-generator/package.json b/Sprint-3/quote-generator/package.json index ddfcf15d4..1aafc368d 100644 --- a/Sprint-3/quote-generator/package.json +++ b/Sprint-3/quote-generator/package.json @@ -2,18 +2,18 @@ "name": "quote-generator", "version": "1.0.0", "license": "CC-BY-SA-4.0", - "description": "You must update this package", + "description": "Updated package", "scripts": { "test": "jest" }, "repository": { "type": "git", - "url": "git+https://github.com/CodeYourFuture/CYF-Coursework-Template.git" + "url": "git+https://github.com/Elfredah?tab=repositories" }, "bugs": { - "url": "https://github.com/CodeYourFuture/CYF-Coursework-Template/issues" + "url": "https://github.com/issues/assigned" }, - "homepage": "https://github.com/CodeYourFuture/CYF-Coursework-Template#readme", + "homepage": "https://github.com/users/Elfredah/projects/4", "devDependencies": { "@testing-library/dom": "^8.19.0", "@testing-library/jest-dom": "^5.16.5", diff --git a/Sprint-3/reading-list/README.md b/Sprint-3/reading-list app/README.md similarity index 100% rename from Sprint-3/reading-list/README.md rename to Sprint-3/reading-list app/README.md diff --git a/Sprint-3/reading-list app/index.html b/Sprint-3/reading-list app/index.html new file mode 100644 index 000000000..567507fe7 --- /dev/null +++ b/Sprint-3/reading-list app/index.html @@ -0,0 +1,120 @@ + + + + + + Reading List + + + + +

My Reading List

+ +
+ + + + + diff --git a/Sprint-3/reading-list/jest.setup.js b/Sprint-3/reading-list app/jest.setup.js similarity index 100% rename from Sprint-3/reading-list/jest.setup.js rename to Sprint-3/reading-list app/jest.setup.js diff --git a/Sprint-3/reading-list/package.json b/Sprint-3/reading-list app/package.json similarity index 60% rename from Sprint-3/reading-list/package.json rename to Sprint-3/reading-list app/package.json index d11906db8..b6dd9aa26 100644 --- a/Sprint-3/reading-list/package.json +++ b/Sprint-3/reading-list app/package.json @@ -2,18 +2,17 @@ "name": "readinglist", "version": "1.0.0", "license": "CC-BY-SA-4.0", - "description": "You must update this package", - "scripts": { + "description": "This is a readinf list app.": { "test": "jest" }, "repository": { "type": "git", - "url": "git+https://github.com/CodeYourFuture/CYF-Coursework-Template.git" + "url": "git+https://github.com/Elfredah?tab=repositories" }, "bugs": { - "url": "https://github.com/CodeYourFuture/CYF-Coursework-Template/issues" + "url": "https://github.com/issues/assigned" }, - "homepage": "https://github.com/CodeYourFuture/CYF-Coursework-Template#readme", + "homepage": "https://github.com/users/Elfredah/projects/4", "devDependencies": { "@testing-library/dom": "^8.19.0", "@testing-library/jest-dom": "^5.16.5", diff --git a/Sprint-3/reading-list/reading-list.png b/Sprint-3/reading-list app/reading-list.png similarity index 100% rename from Sprint-3/reading-list/reading-list.png rename to Sprint-3/reading-list app/reading-list.png diff --git a/Sprint-3/reading-list/script.js b/Sprint-3/reading-list app/script.js similarity index 100% rename from Sprint-3/reading-list/script.js rename to Sprint-3/reading-list app/script.js diff --git a/Sprint-3/reading-list app/script.test.js b/Sprint-3/reading-list app/script.test.js new file mode 100644 index 000000000..e91105f1f --- /dev/null +++ b/Sprint-3/reading-list app/script.test.js @@ -0,0 +1,70 @@ +const path = require("path"); +const { JSDOM } = require("jsdom"); + +let page = null; + +beforeEach(async () => { + page = await JSDOM.fromFile(path.join(__dirname, "index.html"), { + resources: "usable", + runScripts: "dangerously", + }); + + // Do this so students can use element.innerText which jsdom does not implement + Object.defineProperty(page.window.HTMLElement.prototype, "innerText", { + get() { + return this.textContent; + }, + set(value) { + this.textContent = value; + }, + }); + + // Wait for the DOM to be fully loaded + await new Promise((res) => { + page.window.document.addEventListener("load", res); + }); +}); + +afterEach(() => { + page = null; +}); + +describe("Reading list", () => { + test("renders a list of books with author and title", () => { + const readingList = page.window.document.querySelector("#reading-list"); + + expect(readingList).toHaveTextContent("The Design of Everyday Things"); + expect(readingList).toHaveTextContent("Don Norman"); + + expect(readingList).toHaveTextContent("The Most Human Human"); + expect(readingList).toHaveTextContent("Brian Christian"); + + expect(readingList).toHaveTextContent("The Pragmatic Programmer"); + expect(readingList).toHaveTextContent("Andrew Hunt"); + }); + + test("each book in the list has an image", () => { + const firstLi = page.window.document.querySelector("#reading-list > :first-child"); + const firstImage = firstLi.querySelector("img"); + expect(firstImage).toHaveAttribute("src", "https://blackwells.co.uk/jacket/l/9780465050659.jpg"); + + const secondLi = page.window.document.querySelector("#reading-list > :nth-child(2)"); + const secondImage = secondLi.querySelector("img"); + expect(secondImage).toHaveAttribute("src", "https://images-na.ssl-images-amazon.com/images/I/41m1rQjm5tL._SX322_BO1,204,203,200_.jpg"); + + const thirdLi = page.window.document.querySelector("#reading-list > :nth-child(3)"); + const thirdImage = thirdLi.querySelector("img"); + expect(thirdImage).toHaveAttribute("src", "https://blackwells.co.uk/jacket/l/9780135957059.jpg"); + }); + + test("background color changes depending on whether book has been read", () => { + const firstLi = page.window.document.querySelector("#reading-list > :first-child"); + expect(firstLi).toHaveStyle("background-color: red"); + + const secondLi = page.window.document.querySelector("#reading-list > :nth-child(2)"); + expect(secondLi).toHaveStyle("background-color: green"); + + const thirdLi = page.window.document.querySelector("#reading-list > :nth-child(3)"); + expect(thirdLi).toHaveStyle("background-color: green"); + }); +}); diff --git a/Sprint-3/reading-list/style.css b/Sprint-3/reading-list app/style.css similarity index 100% rename from Sprint-3/reading-list/style.css rename to Sprint-3/reading-list app/style.css diff --git a/Sprint-3/reading-list/index.html b/Sprint-3/reading-list/index.html deleted file mode 100644 index dbdb0f471..000000000 --- a/Sprint-3/reading-list/index.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - Title here - - -
- -
- - - diff --git a/Sprint-3/reading-list/script.test.js b/Sprint-3/reading-list/script.test.js deleted file mode 100644 index 4e3d7367d..000000000 --- a/Sprint-3/reading-list/script.test.js +++ /dev/null @@ -1,83 +0,0 @@ -const path = require("path"); -const { JSDOM } = require("jsdom"); -const { default: userEvent } = require("@testing-library/user-event"); - -let page = null; - -beforeEach(async () => { - page = await JSDOM.fromFile(path.join(__dirname, "index.html"), { - resources: "usable", - runScripts: "dangerously", - }); - - // do this so students can use element.innerText which jsdom does not implement - Object.defineProperty(page.window.HTMLElement.prototype, "innerText", { - get() { - return this.textContent; - }, - set(value) { - this.textContent = value; - }, - }); - - return new Promise((res) => { - page.window.document.addEventListener("load", res); - }); -}); - -afterEach(() => { - page = null; -}); - -describe("Reading list", () => { - test("renders a list of books with author and title", () => { - const readingList = page.window.document.querySelector("#reading-list"); - - expect(readingList).toHaveTextContent("The Design of Everyday Things"); - expect(readingList).toHaveTextContent("Don Norman"); - - expect(readingList).toHaveTextContent("The Most Human Human"); - expect(readingList).toHaveTextContent("Brian Christian"); - - expect(readingList).toHaveTextContent("The Pragmatic Programmer"); - expect(readingList).toHaveTextContent("Andrew Hunt"); - }); - test("each book in the list has an image", () => { - const firstLi = page.window.document.querySelector( - "#reading-list > :first-child" - ); - expect(firstLi).toContainHTML( - `` - ); - - const secondLi = page.window.document.querySelector( - "#reading-list > :nth-child(2)" - ); - expect(secondLi).toContainHTML( - `` - ); - - const thirdLi = page.window.document.querySelector( - "#reading-list > :nth-child(3)" - ); - expect(thirdLi).toContainHTML( - `` - ); - }); - test("background color changes depending on whether book has been read", () => { - const firstLi = page.window.document.querySelector( - "#reading-list > :first-child" - ); - expect(firstLi).toHaveStyle({ backgroundColor: "red" }); - - const secondLi = page.window.document.querySelector( - "#reading-list > :nth-child(2)" - ); - expect(secondLi).toHaveStyle({ backgroundColor: "green" }); - - const thirdLi = page.window.document.querySelector( - "#reading-list > :nth-child(3)" - ); - expect(thirdLi).toHaveStyle({ backgroundColor: "green" }); - }); -}); diff --git a/Sprint-3/slideshow/Image carousel.html b/Sprint-3/slideshow/Image carousel.html new file mode 100644 index 000000000..f9e8434e2 --- /dev/null +++ b/Sprint-3/slideshow/Image carousel.html @@ -0,0 +1,24 @@ + + + + + + Image Carousel + + + + + + + diff --git a/Sprint-3/slideshow/index.html b/Sprint-3/slideshow/index.html deleted file mode 100644 index 50f2eb1c0..000000000 --- a/Sprint-3/slideshow/index.html +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - Title here - - - - cat-pic - - - - diff --git a/Sprint-3/slideshow/slideshow.js b/Sprint-3/slideshow/slideshow.js index 063ceefb5..5a0708437 100644 --- a/Sprint-3/slideshow/slideshow.js +++ b/Sprint-3/slideshow/slideshow.js @@ -1,8 +1,61 @@ -const images = [ - "./assets/cute-cat-a.png", - "./assets/cute-cat-b.jpg", - "./assets/cute-cat-c.jpg", -]; +//const images = [ + // "./assets/cute-cat-a.png", + // "./assets/cute-cat-b.jpg", + // "./assets/cute-cat-c.jpg", +//]; -// Write your code here \ No newline at end of file +// Write your code here +// Image list stored in the assets folder +const images = [ + "./assets/cute-cat-a.png", // Image 1 + "./assets/cute-cat-b.jpg", // Image 2 + "./assets/cute-cat-c.jpg", // Image 3 + ]; + + let currentIndex = 0; + + // Get elements + const imgElement = document.getElementById("carousel-img"); + const backwardButton = document.getElementById("backward-btn"); + const forwardButton = document.getElementById("forward-btn"); + const autoBackwardButton = document.getElementById("auto-backward-btn"); + const autoForwardButton = document.getElementById("auto-forward-btn"); + + // Function to update the image based on the current index + function updateImage() { + imgElement.src = images[currentIndex]; // Set the image src to the current image in the array + } + + // Manual navigation - Backward + backwardButton.addEventListener("click", () => { + currentIndex = (currentIndex === 0) ? images.length - 1 : currentIndex - 1; + updateImage(); + }); + + // Manual navigation - Forward + forwardButton.addEventListener("click", () => { + currentIndex = (currentIndex === images.length - 1) ? 0 : currentIndex + 1; + updateImage(); + }); + + // Auto navigation - Backward + let autoBackwardInterval; + autoBackwardButton.addEventListener("click", () => { + clearInterval(autoBackwardInterval); // Stop any ongoing interval + autoBackwardInterval = setInterval(() => { + currentIndex = (currentIndex === 0) ? images.length - 1 : currentIndex - 1; + updateImage(); + }, 2000); // Change image every 2 seconds + }); + + // Auto navigation - Forward + let autoForwardInterval; + autoForwardButton.addEventListener("click", () => { + clearInterval(autoForwardInterval); // Stop any ongoing interval + autoForwardInterval = setInterval(() => { + currentIndex = (currentIndex === images.length - 1) ? 0 : currentIndex + 1; + updateImage(); + }, 2000); // Change image every 2 seconds + }); + \ No newline at end of file diff --git a/Sprint-3/slideshow/style.css b/Sprint-3/slideshow/style.css index 63cedf2d2..4fc08310c 100644 --- a/Sprint-3/slideshow/style.css +++ b/Sprint-3/slideshow/style.css @@ -1 +1,74 @@ /** Write your CSS in here **/ +/* General body styling */ +/* General body styling */ +body { + font-family: Arial, sans-serif; + background-color: #f7f7f7; + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + height: 100vh; + margin: 0; + } + + /* Container for the carousel */ + #carousel-container { + text-align: center; + background: linear-gradient(135deg, #ff7e5f, #feb47b); /* Soft gradient background */ + padding: 20px; + border-radius: 10px; + box-shadow: 0 5px 15px rgba(0, 0, 0, 0.2); + width: 80%; + max-width: 700px; + } + + /* Styling the images */ + img { + width: 100%; + max-width: 600px; + border-radius: 10px; + margin: 15px 0; + transition: transform 0.5s ease; + } + + /* Button styling */ + button { + background-color: #ff7e5f; + color: white; + border: none; + padding: 10px 20px; + font-size: 16px; + cursor: pointer; + border-radius: 5px; + margin: 5px; + transition: background-color 0.3s ease; + } + + button:hover { + background-color: #feb47b; + } + + /* Controls styling */ + #controls, #auto-controls { + display: flex; + justify-content: center; + margin-top: 20px; + } + + /* Responsiveness for smaller screens */ + @media (max-width: 600px) { + #carousel-container { + width: 95%; /* Makes the carousel container take most of the screen on small devices */ + } + + button { + padding: 8px 15px; /* Smaller button size for mobile */ + font-size: 14px; + } + + img { + max-width: 100%; /* Makes the image fit better on small screens */ + } + } + \ No newline at end of file diff --git a/Sprint-3/todo-list/index.html b/Sprint-3/todo-list/index.html index ee3ef64fd..0c9689b14 100644 --- a/Sprint-3/todo-list/index.html +++ b/Sprint-3/todo-list/index.html @@ -3,25 +3,52 @@ - Title here + Todo List -
-
- -
-
- - -
-
+
+

Todo List

+ + +
+
+ +
+
+ +
+
+ + +
+
+ + + + + +

Completed Tasks

+
+ + +
+ + +
+ diff --git a/Sprint-3/todo-list/package.json b/Sprint-3/todo-list/package.json index adf75c4df..d03f753e9 100644 --- a/Sprint-3/todo-list/package.json +++ b/Sprint-3/todo-list/package.json @@ -2,7 +2,7 @@ "name": "todo-list", "version": "1.0.0", "license": "CC-BY-SA-4.0", - "description": "You must update this package", + "description": "To do list", "scripts": { "test": "jest" }, diff --git a/Sprint-3/todo-list/script.js b/Sprint-3/todo-list/script.js index 61982a54f..70e4c9b19 100644 --- a/Sprint-3/todo-list/script.js +++ b/Sprint-3/todo-list/script.js @@ -23,3 +23,143 @@ function addNewTodo(event) { function deleteAllCompletedTodos() { // Write your code here... } + +document.addEventListener("DOMContentLoaded", () => { + const todoList = document.querySelector("#todo-list"); + const completedList = document.querySelector("#completed-list"); + const form = document.querySelector("#todo-form"); + const input = document.querySelector("#todoInput"); + const deadlineInput = document.querySelector("#todoDeadline"); + const removeAllCompletedBtn = document.querySelector("#remove-all-completed"); + + const completedForm = document.querySelector("#completed-form"); + const completedInput = document.querySelector("#completedInput"); + const removeAllCompletedTasksBtn = document.querySelector( + "#remove-all-completed-tasks" + ); + + const todos = []; + const completedTasks = []; + + // Function to calculate and display the countdown + const getDeadlineCountdown = (deadline) => { + const deadlineDate = new Date(deadline); + const today = new Date(); + const timeDiff = deadlineDate - today; + const daysLeft = Math.ceil(timeDiff / (1000 * 3600 * 24)); + return daysLeft; + }; + + // Function to create and display todos + const populateTodoList = () => { + todoList.innerHTML = ""; // Clear the current list + todos.forEach((todo, index) => { + const li = document.createElement("li"); + li.classList.toggle("completed", todo.completed); + li.innerHTML = `${todo.task} - + + + `; + + // Add event listener for check icon (to toggle strike-through) + li.querySelector(".fa-check").addEventListener("click", () => { + todo.completed = !todo.completed; + li.classList.toggle("completed", todo.completed); + if (todo.completed) { + completedTasks.push(todo); // Add to completed tasks + todos.splice(index, 1); // Remove from todos list + populateTodoList(); // Re-render the todo list + populateCompletedList(); // Re-render the completed list + } + }); + + // Add event listener for delete icon + li.querySelector(".fa-trash").addEventListener("click", () => { + todos.splice(index, 1); + populateTodoList(); // Re-render the list after deletion + }); + + // Add the deadline countdown if present + if (todo.deadline) { + const daysLeft = getDeadlineCountdown(todo.deadline); + li.innerHTML += ` Deadline: ${daysLeft} day(s) left`; + } + + todoList.appendChild(li); + }); + }; + + // Function to populate completed tasks list + const populateCompletedList = () => { + completedList.innerHTML = ""; // Clear the current list + completedTasks.forEach((task, index) => { + const li = document.createElement("li"); + li.innerHTML = `${task.task} - + + `; + + // Add event listener for delete icon in completed tasks + li.querySelector(".fa-trash").addEventListener("click", () => { + completedTasks.splice(index, 1); + populateCompletedList(); // Re-render the completed tasks list + }); + + completedList.appendChild(li); + }); + }; + + // Add a new todo to the list + form.addEventListener("submit", (event) => { + event.preventDefault(); + const todoText = input.value.trim(); + const deadline = deadlineInput.value; + + if (todoText === "") return; // Prevent adding empty todos + + const newTodo = { + task: todoText, + completed: false, + deadline: deadline || null + }; + + todos.push(newTodo); + input.value = ""; // Clear the input field + deadlineInput.value = ""; // Clear the date input + populateTodoList(); // Re-render the todo list + }); + + // Remove all completed tasks from todos + removeAllCompletedBtn.addEventListener("click", () => { + const completedTodos = todos.filter(todo => todo.completed); + completedTodos.forEach(todo => { + const index = todos.indexOf(todo); + todos.splice(index, 1); + }); + populateTodoList(); // Re-render the list after deletion + }); + + // Add a completed task to the completed list + completedForm.addEventListener("submit", (event) => { + event.preventDefault(); + const completedText = completedInput.value.trim(); + + if (completedText === "") return; // Prevent adding empty tasks + + const newCompletedTask = { + task: completedText + }; + + completedTasks.push(newCompletedTask); + completedInput.value = ""; // Clear the input field + populateCompletedList(); // Re-render the completed tasks list + }); + + // Remove all completed tasks + removeAllCompletedTasksBtn.addEventListener("click", () => { + completedTasks.length = 0; // Clear the completed tasks array + populateCompletedList(); // Re-render the completed tasks list + }); + + // Initial population of todo list + populateTodoList(); +}); diff --git a/Sprint-3/todo-list/script.test.js b/Sprint-3/todo-list/script.test.js index 13c897bf0..3d588b1aa 100644 --- a/Sprint-3/todo-list/script.test.js +++ b/Sprint-3/todo-list/script.test.js @@ -10,7 +10,7 @@ beforeEach(async () => { runScripts: "dangerously", }); - // do this so students can use element.innerText which jsdom does not implement + // This ensures that students can use element.innerText, which jsdom does not implement by default Object.defineProperty(page.window.HTMLElement.prototype, "innerText", { get() { return this.textContent; @@ -20,8 +20,9 @@ beforeEach(async () => { }, }); - return new Promise((res) => { - page.window.document.addEventListener("load", res); + // Wait for the page to load fully + return new Promise((resolve) => { + page.window.document.addEventListener("load", resolve); }); }); diff --git a/Sprint-3/todo-list/style.css b/Sprint-3/todo-list/style.css index 8b1378917..e2ca524b5 100644 --- a/Sprint-3/todo-list/style.css +++ b/Sprint-3/todo-list/style.css @@ -1 +1,142 @@ - +/* General reset for margin, padding */ +* { + margin: 0; + padding: 0; + box-sizing: border-box; + } + + body { + font-family: Arial, sans-serif; + background-color: #f4f4f9; + display: flex; + justify-content: center; + align-items: center; + min-height: 100vh; + color: #333; + } + + .container { + width: 100%; + max-width: 400px; + text-align: center; + background-color: #fff; + padding: 20px; + border-radius: 8px; + box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); + } + + h1 { + margin-bottom: 20px; + font-size: 2em; + } + + h2 { + font-size: 1.5em; + margin-top: 20px; + } + + form { + display: flex; + flex-direction: column; + width: 100%; + } + + input { + padding: 10px; + font-size: 1em; + border: 1px solid #ddd; + border-radius: 4px; + margin-bottom: 10px; + } + + button { + padding: 10px; + font-size: 1em; + border: none; + border-radius: 4px; + cursor: pointer; + transition: background-color 0.3s ease; + } + + button:hover { + background-color: #007bff; + color: white; + } + + button:active { + transform: scale(0.98); + } + + /* Todo List Container */ + #todo-list { + list-style: none; + padding-left: 0; + margin-top: 20px; + } + + li { + display: flex; + justify-content: space-between; + align-items: center; + padding: 12px; + border-bottom: 1px solid #ddd; + font-size: 1.2em; + background-color: #fafafa; + border-radius: 4px; + margin-bottom: 8px; + } + + li.completed { + text-decoration: line-through; + color: #aaa; + } + + span.badge { + display: inline-flex; + gap: 8px; + align-items: center; + } + + span i { + cursor: pointer; + font-size: 1.2em; + transition: color 0.3s ease; + } + + span i.fa-check { + color: #4caf50; + } + + span i.fa-trash { + color: #f44336; + } + + span i:hover { + color: #007bff; + } + + span i.fa-check:hover { + color: #388e3c; + } + + span i.fa-trash:hover { + color: #d32f2f; + } + + /* Responsive styling */ + @media (max-width: 600px) { + form { + width: 90%; + padding: 15px; + } + + input, + button { + font-size: 0.9em; + } + + li { + font-size: 1em; + } + } +