As an expert developer and tutor could you rate these files' code and then provide these files after improvement?

// localStorage.js

import { validate as validateUUID } from 'uuid';
import { Project } from './project.js';
import { Todo } from './todo.js';

/**
 * Manages saving and loading projects to and from localStorage.
 */
export class StorageManager {
    /**
     * Save projects to localStorage.
     * @param {Project[]} projects – Array of Project instances.
     */
    static saveProjects(projects) {
        try {
            const serializedProjects = JSON.stringify(projects);
            localStorage.setItem('projects', serializedProjects);
        } catch (error) {
            console.error(`Error saving to localStorage: ${error}`);
        }
    }

    /**
     * Loads projects from localStorage.
     * @returns {Project[]} Array of Project instances.
     */
    static loadProjects() {
        try {
            const serializedProjects = localStorage.getItem('projects');
            if (!serializedProjects) return [];

            const projectsData = JSON.parse(serializedProjects);

            return projectsData.map(validateAndConstructProject).filter((project) => project !== null);
        } catch (error) {
            console.error(`Failed to load projects from localStorage: ${error}`);
            // Optional: clean corrupted data
            localStorage.removeItem('projects');
            alert('Stored data was corrupted and has been reset.');
            // Return an empty array or default projects
            return [];
        }
    }
}

function validateAndConstructProject(projectData) {
    if (!projectData.name || typeof projectData.name !== 'string') {
        console.error(`Invalid project data: ${projectData}`);
        return null; // Skip invalid project
    }

    const project = new Project(projectData.name);

    if (Array.isArray(projectData.todos)) {
        project.todos = projectData.todos.map(validateAndConstructTodo).filter((todo) => todo !== null); // Remove invalid todos
    }

    return project;
}

function validateAndConstructTodo(todoData) {
    // Validate dueDate
    if (!todoData.title || !todoData.dueDate || !isValidDate(todoData.dueDate)) {
        console.error(`Invalid due date (or title) for todo: ${todoData.dueDate} in project: ${projectData.name}`);
        // todoData.dueDate = new Date().toISOString().split('T')[0]; // Assign current date if invalid
        return null; // Skip invalid todos
    }

    if (todoData.id && !validateUUID(todoData.id)) {
        console.error(`Invalid UUID for todo: ${todoData.id}`);
        return null;
    }

    // Reconstruct Todo instance
    const todo = new Todo(
        todoData.title,
        todoData.dueDate,
        todoData.description,
        todoData.priority,
        todoData.tags,
        todoData.notes,
        todoData.id // Pass the existing ID
    );

    // Restore completion status
    todo.completed = todoData.completed ?? false;

    // // Reconstruct checklist if any
// if (Array.isArray(todoData.checklist)) {
//     todoData.checklist.forEach((item, index) => {
//         try {
//             todo.addChecklistItem(item.text);
//             todo.toggleChecklistItem(index); // Set completed status if necessary
//             if (item.completed) {
//                 todo.toggleChecklistItem(index);
//             }
//         } catch (chkError) {
//             console.error('Error reconstructing checklist item:', chkError);
//         }
//     });
// }

    // Reconstruct subtasks if any
    if (Array.isArray(todoData.subtasks)) {
        todo.subtasks = todoData.subtasks.map((subtaskData) => {
            const subtask = new Todo(
                subtaskData.title,
                subtaskData.dueDate,
                subtaskData.description,
                subtaskData.priority,
                subtaskData.tags,
                subtaskData.notes,
                subtaskData.id
            );
            subtask.completed = subtaskData.completed ?? false;
            return subtask;
        }).filter((subtask) => subtask !== null); // Remove invalid subtasks
    }

    // todo.recurrence = todoData.recurrence || null;
    return todo;
}

function isValidDate(date) {
    return !isNaN(Date.parse(date));
}

// domUtils.js

/**
 * Utility function to create a DOM element with specified attributes and classes.
 * @param {string} tag – The HTML tag to create.
 * @param {Object} attributes – Key-value pairs of attributes to set.
 * @param {Array<string>} classes – Array of class names to add.
 * @param {HTMLElement[]} children – Array of child elements to append.
 * @returns {HTMLElement} The created DOM element.
 */
export function createElement(tag, attributes = {}, classes = [], children = []) {
    const element = document.createElement(tag);
    Object.entries(attributes).forEach(([attr, value]) => {
        element.setAttribute(attr, value);
    });
    classes.forEach((cls) => element.classList.add(cls));
    children.forEach((child) => element.appendChild(child));
    return element;
}

/**
 * Clears all child elements from a given DOM element.
 * @param {HTMLElement} element – The parent element to clear.
 */
export function clearElement(element) {
    if (!(element instanceof HTMLElement)) {
        console.error('Provided parameter is not a valid DOM element');
        return;
    }
    element.innerHTML = '';
}

/**
 * Toggles a class on a DOM element based on a condition.
 * @param {HTMLElement} element – The element to toggle the class on.
 * @param {string} className – The class to toggle.
 * @param {boolean} condition – Condition to add or remove the class.
 */
export function toggleClass(element, className, condition) {
    if (!(element instanceof HTMLElement)) {
        console.error('Provided parameter is not a valid DOM element');
        return;
    }
    element.classList.toggle(className, condition);
}

// app.js

import { Project } from './project.js';
import { Todo } from './todo.js';
import { StorageManager } from './localStorage.js';
import { renderTodos, renderProjects } from './ui.js';

/**
 * Application state encapsulated in an object.
 */
const state = {
  /** @type {Project[]} */
  projects: [],
  /** @type {number} */
  currentProjectIndex: 0
};

/**
 * Getter for the application state.
 * Returns a deep copy to prevent direct mutation.
 * @returns {Object} The current state.
 */
export function getState() {
  return JSON.parse(JSON.stringify(state));
  // return state;
  // {
  //   ...state,
  //   projects: state.projects.map((project) => ({
  //     ...project,
  //     todos: project.todos.map((todo) => ({ ...todo })), // Returns shallow copies of todos
      //   {
      //   // Ensures each todo is an instance of Todo
      //   if (!(todo instanceof Todo)) {
      //     return new Todo(
      //       todo.title,
      //       todo.dueDate,
      //       todo.description,
      //       todo.priority,
      //       todo.tags,
      //       todo.notes,
      //       todo.id
      //     );
      //   }
      //   return todo;
      // }),
    // })),
    // currentProjectIndex: state.currentProjectIndex,
  // };
}

/**
 * Gets the index of the current project.
 * @returns {number} The current project index.
 */
export function getCurrentProjectIndex() {
  return state.currentProjectIndex;
}

/**
 * Gets the current project instance.
 * @returns {Project} The current project.
 */
export function getCurrentProject() {
  return state.projects[state.currentProjectIndex];
}

/**
 * Sets the current project index and renders its todos.
 * @param {number} index – The index of the project to set as current.
 */
export function setCurrentProjectIndex(index) {
  if (index >= 0 && index < state.projects.length) {
    state.currentProjectIndex = index;
    renderTodos(state.projects[index]);
  } else {
    console.error('Invalid project index.');
  }
}

// export function selectProject(index) {
//   if (index => 0 && index < projectsArray.length) {
//     currentProjectIndex = index;
//     renderTodos(projectsArray[index]);
//   } else {
//     console.error('Invalid project index');
//   }
// }

/**
 * Initializes the application by loading projects and rendering them.
 */
export function initializeApp() {
  // Load existing projects from localStorage on startup
  const loadedProjects = StorageManager.loadProjects();

  if (loadedProjects.length > 0) {
    state.projects = loadedProjects;
  } else {
    // Create a default project if none exist
    const defaultProject = new Project('Default Project');
    state.projects.push(defaultProject);
    StorageManager.saveProjects(state.projects);
  }

  // Render the loaded or default projects
  renderProjects(state.projects);
  // renderTodos(getCurrentProject());
  setCurrentProjectIndex(0);
}

/**
 * Adds a new todo to the current project
 * @param {string} title – The title of the todo.
 * @param {string} description – The description of the todo.
 * @param {string} dueDate – The due date of the todo.
 * @param {string} priority – The priority of the todo.
 * @param  {string[]} tags – Tags associated with the todo.
 */
export function addTodo(title, dueDate, description, priority, tags = []) {
  const currentProject = getCurrentProject(); // Use selected project

  if (!currentProject) {
    console.error('No current project selected');
    return;
  }

  try {
    const newTodo = new Todo(title, dueDate, description, priority, tags);
    currentProject.addTodo(newTodo);
    // Save updated projects to localStorage
    StorageManager.saveProjects(state.projects);

    // Render todos for the current project
    renderTodos(currentProject);
  } catch (error) {
    console.error('Error adding todo:', error);
  }
  // return newTodo; // Return the created Todo object
}

/**
 * Adds a new project to the application.
 * @param {string} projectName – The name of the new project.
 */
export function addProject(projectName) {
  if (!projectName || typeof projectName !== 'string') {
    console.error('Invalid project name');
    return;
  }
  try {
    const newProject = new Project(projectName);
    state.projects.push(newProject);
    // Save updated projects to localStorage
    StorageManager.saveProjects(state.projects);

    // Re-render the projects list
    renderProjects(state.projects);
  } catch (error) {
    console.error('Error adding project:', error);
  }
}

/**
 * Updates the existing todo in the current project.
 * @param {Todo} updatedTodo – The todo instance with updated details.
 */
export function updateTodo(updatedTodo) {
  const currentProject = getCurrentProject();
  if (!currentProject) {
    console.error('No current project selected.');
    return;
  }

  try {
    const success = currentProject.updateTodo(updatedTodo);
    if (success) {
      StorageManager.saveProjects(state.projects);
      renderTodos(currentProject);
    }

  } catch (error) {
    console.error('Error updating todo:', error);
  }
}

/**
 * Toggles the completion status of a todo.
 * @param {string} todoId - The ID of the todo to toggle.
 */
export function toggleTodoCompletion(todoId) {
  const currentProject = getCurrentProject();
  const todo = currentProject.getTodoById(todoId);
  if (todo) {
      todo.toggleCompletion();
      StorageManager.saveProjects(state.projects);
  } else {
      console.error(`Todo with ID ${todoId} not found.`);
  }
}

// todo.js

import { v4 as uuidv4 } from 'uuid'; // Ensure you have installed the `uuid` package via npm

const PRIORITY_LEVELS = {
    LOW: 'low',
    MEDIUM: 'medium',
    HIGH: 'high',
};

/**
 * Represents a single Todo item.
 */
export class Todo {
    /**
     * Creates a new Todo instance.
     * @param {string} title – The title of the todo.
     * @param {string} dueDate – The due date of the todo in YYYY-MM-DD format.
     * @param {string} [description=''] – The description of the todo.
     * @param {string} [priority='low'] – The priority level ('low', 'medium', 'high').
     * @param {string[]} [tags=[]] – Tags associated with the todo.
     * @param {string} [notes=''] – Additional notes for the todo.
     * @param {string} [id] – Unique identifier for the todo.
     */
    constructor(title, dueDate, description = '', priority = 'low', tags = [], notes = '', id = uuidv4()) {
        // Data Validation
        if (!title || typeof title !== 'string') {
            throw new Error('Title is required and must be a string.');
        }
        if (!dueDate || isNaN(Date.parse(dueDate))) {
            throw new Error('A valid Due Date is required');
        }
        if (!Object.values(PRIORITY_LEVELS).includes(priority)) {
            throw new Error(`Priority must be one of ${Object.values(PRIORITY_LEVELS).join(', ')}.`);
        }

        Object.defineProperty(this, 'id', {
            value: id,
            writable: false,
            enumerable: true,
        });

        // this.id = id; // Robust unique ID generation
        this.title = title;
        this.dueDate = dueDate;
        this.description = description;
        this.priority = priority;
        this.tags = tags;
        this.notes = notes;
        this.completed = false; // Track completion status
        this.subtasks = []; // Array to hold subtasks if needed
        this.recurrence = null; // For recurring tasks
        this.checklist = [];
    }

    /**
     * Toggle the completion status of todo.
     * @returns {Todo} The updated todo instance.
     */
    toggleCompletion() {
        this.completed = !this.completed;
        console.log(`Todo "${this.title}" completed status toggled to: ${this.completed}`);
        return this;
    }

    /**
     * Add a subtask to the todo.
     * @param {Todo} subtask – The subtask to add.
     */
    addSubtask(subtask) {
        if (subtask instanceof Todo) {
            this.subtasks.push(subtask);
        } else {
            throw new Error('Subtask must be an instance of Todo.');
        }
    }

    /**
     * Remove a subtask from the todo by ID.
     * @param {string} subtaskId – The ID of the subtask to remove.
     */
    removeSubtask(subtaskId) {
        this.subtasks = this.subtasks.filter((st) => st.id !== subtaskId);
    }

    /**
     * Adds an item to the checklist.
     * @param {string} item - The checklist item to add.
     */
    addCheckListItem(item) {
        if (typeof item === 'string' && item.trim() !== '') {
            this.checklist.push({ text: item, completed: false });
        } else {
            throw new Error('Checklist item must be a non-empty string.');
        }
    }

    /**
     * Toggles the completion status of a checklist item.
     * @param {number} index - The index of the checklist item to toggle.
     */
    toggleCheckListItem(index) {
        if (index >= 0 && index < this.checklist.length) {
            this.checklist[index].completed = !this.checklist[index].completed;
        } else {
            throw new Error('Invalid checklist item index.');
        }
    }
}

// project.js

import { Todo } from './todo.js';

/**
 * Represents a project containing multiple todos.
 */
export class Project {
    /**
     * Creates a new Project instance.
     * @param {string} name – The name of the project.
     */
    constructor(name) {
        if (!name || typeof name !== 'string' || name.trim() === '') {
            throw new Error('Project name is required and must be a non-empty string.');
        }

        this.name = name;
        /** @type {Todo[]} */
        this.todos = []; // Array to hold todos
    }

    /**
     * Add a new Todo to the project.
     * @param {Todo} todo – The todo instance to add.
     * @returns {boolean} True if added successfully, false otherwise.
     */
    addTodo(todo) {
        if (!(todo instanceof Todo)) {
            console.error('Only instances of Todo can be added.');
            return false;
        }
        if (this.todos.find((t) => t.id === todo.id)) {
            console.warn(`Todo with ID ${todo.id} already exists in the project.`);
            return false;
        }
        this.todos.push(todo);
        return true;
    }

    /**
     * Remove a todo by its ID.
     * @param {string} todoId – The ID of the todo to remove.
     */
    removeTodo(todoId) {
        const initialLength = this.todos.length;
        this.todos = this.todos.filter((t) => t.id !== todoId); // Remove the todo
        if (this.todos.length === initialLength) {
            console.warn(`Todo with ID ${todoId} not found.`);
            return false;
        }
        return true;
    }

    /**
     * Get a todo by its ID.
     * @param {string} todoId – The ID of the todo to retrieve.
     * @returns {Todo|null} The todo instance or null if not found.
     */
    getTodoById(todoId) {
        return this.todos.find((t) => t.id === todoId) || null;
    }

    /**
     * Update a todo's details.
     * @param {Todo} updatedTodo – The updated Todo instance.
     * @returns {boolean} True if updated successfully, false otherwise.
     */
    updateTodo(updatedTodo) {
        const index = this.todos.findIndex((t) => t.id === updatedTodo.id);
        if (index !== -1) {
            this.todos[index] = updatedTodo;
            return true;
        } else {
            console.error(`Todo with ID ${updatedTodo.id} not found.`);
            return false;
        }
    }

    /**
     * Toggle completion status of a todo by its ID.
     * @param {string} todoId – The ID of the todo to toggle.
     * @returns {boolean} True if toggled successfully, false otherwise.
     */
    toggleTodoCompletion(todoId) {
        const todo = this.getTodoById(todoId);
        if (todo) {
            todo.toggleCompletion();
            return true;
        } 
        console.error(`Todo with ID ${todoId} not found.`);
        return false;
    }

    /**
     * Get all completed todos.
     * @returns {Todo[]} Array of completed todos.
     */
    getCompletedTodos() {
        return this.todos.filter((todo) => todo.completed);
    }

    /**
     * Get all incomplete todos.
     * @returns {Todo[]} Array of incomplete todos.
     */
    getIncompleteTodos() {
        return this.todos.filter((todo) => !todo.completed);
    }

    /**
     * Sorts todos based on a comparator function.
     * @param {Function} comparator - Comparator function to sort todos.
     */
    sortTodos(comparator) {
        if (typeof comparator !== 'function') {
            console.error('Comparator must be a function.');
            return;
        }
        this.todos.sort(comparator);
    }
}

// index.js

import './styles/main.css';
import '@fortawesome/fontawesome-free/css/all.min.css';
import { initializeApp } from './app.js';
import { initializeUI, setupEventListeners } from './ui.js';

/**
 * Initializes the application.
 */
function init() {
    try{
        // Initialize the application state and render projects
        initializeApp();

        // Initialize UI interactions and event listeners
        initializeUI();

        // Set up additional event listeners
        setupEventListeners();
    } catch (error) {
        console.error('Failed to initialize the application:', error);
    }
}

// Initialize the application on DOMContentLoaded
document.addEventListener('DOMContentLoaded', init);

<!-- index.html -->

<!DOCTYPE html>
<html lang="en">
<head>
    <!-- Meta Tags for Character Set and Responsive Design -->
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>To-Do List App</title>
    <meta name="description" content="A simple and effective to-do list application">

    <!-- Google Fonts -->
    <link href="https://fonts.googleapis.com/css2?family=Roboto:wght@400;500;700&display=swap" rel="stylesheet">
    
    <!-- Font Awesome for Icons -->
     <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.2/css/all.min.css" integrity="sha512-HK5fgLBL+xXOPQ6ZG/7eAs69/Gk+IrWnrFJf5G5Y7dBTfjBTD22gg8p6BiEm8qpGk7tCq+IIn6bz8RF13X0Yw==" crossorigin="anonymous" />

    <!-- Include CSS -->
    <!-- <link rel="stylesheet" href="main.css"> -->
     <!-- The CSS will be injected by Webpack -->

    <!-- Include SortableJS -->
    <script type="module" src="https://cdn.jsdelivr.net/npm/sortablejs@1.14.0/Sortable.min.js" defer></script>
</head>
<body>
    <header>
        <button id="theme-toggle" aria-label="Toggle Dark Mode">
            <i class="fas fa-moon"></i>
        </button>
        <button id="sidebar-toggle" aria-label="Toggle Sidebar">
            <i class="fas fa-bars">
            </i>
        </button>
    </header>
    
    <div class="wrapper">
        <!-- Sidebar -->
         <aside id="sidebar" class="sidebar" role="complementary" aria-label="Project Sidebar">
            <h2>Projects</h2>
            <ul id="project-list">
                <!-- Projects will be rendered here -->
            </ul>
            <form id="add-project">
                <label for="project-name" class="visually-hidden">New Project Name</label>
                <input type="text" id="project-name" required aria-required="true" placeholder="New Project Name">

                <button type="submit" id="add-project-button" class="btn" tabindex="0" aria-label="Add Project">Add Project</button>
            </form>
            
         </aside>

         <!-- Main Content -->
         <main id="app" role="main">
            <h1>To-Do List</h1>

            <div id="todo-container">
                <h2>Todos</h2>
                <!-- Todos will be rendered here -->
            </div>

            <form id="add-todo-form">
                <div id="add-todo">
                    <label for="todo-title" class="visually-hidden">Title</label>
                    <input type="text" id="todo-title" name="todo-title" placeholder="Title" required aria-required="true" autofocus>

                    <label for="todo-due-date" class="visually-hidden">Due Date</label>
                    <input type="date" id="todo-due-date" required aria-required="true">
                    
                    <label for="todo-description" class="visually-hidden">Description</label>
                    <input type="text" id="todo-description" placeholder="Description">
                    
                    <label for="todo-tags">Tags</label>
                    <input type="text" id="todo-tags" placeholder="Enter tags separated by commas">

                    <label for="todo-priority" class="visually-hidden">Priority</label>
                    <select id="todo-priority" aria-label="Priority">
                        <option value="low">Low</option>
                        <option value="medium">Medium</option>
                        <option value="high">High</option>
                    </select>

                    <button type="submit" id="add-todo-button" class="btn" aria-label="Add Todo">Add Todo</button>
                </div>
            </form>

            <!-- Edit Task Modal -->
             <div id="edit-task-modal" class="modal" role="dialog" aria-modal="true" aria-hidden="true" aria-labelledby="edit-task-title">
                <div class="modal-content">

                    <button class="close-button" aria-label="Close Modal">&times;</button>
                    <h2 id="edit-task-title">Edit task</h2>

                    <label for="edit-title" class="visually-hidden">Title:</label>
                    <input type="text" id="edit-title" required aria-required="true">
                    
                    <label for="edit-due-date" class="visually-hidden">Due Date:</label>
                    <input type="date" id="edit-due-date">
                    
                    <label for="edit-description" class="visually-hidden">Description:</label>
                    <input type="text" id="edit-description">

                    <label for="edit-tags" class="visually-hidden">Tags:</label>
                    <input type="text" id="edit-tags" placeholder="Enter tags separated by commas">

                    <label for="edit-priority" class="visually-hidden">Priority:</label>
                    <select id="edit-priority" aria-label="Edit Priority">
                        <option value="low">Low</option>
                        <option value="medium">Medium</option>
                        <option value="high">High</option>
                    </select>

                    <button id="save-changes-button" class="btn" aria-label="Save Changes">Save changes</button>
                    <button id="cancel-button" class="btn" aria-label="Cancel Editing">Cancel</button>
                </div>
             </div>
        </main>
    </div>
    <div id="toast-container" aria-live="polite" aria-atomic="true"></div>

    <!-- <script src=".dist/bundle.js"></script> -->
    <!-- <script src="./src/app.js" defer></script> -->
    <!-- <script type="module" src="./src/index.js" defer></script> -->
     <!-- Include the bundled JavaScript file -->
     <!-- <script src="bundle.js"></script> -->
</body>
</html>


// ui.js
import {
     getCurrentProject,
     getState,
     setCurrentProjectIndex,
     toggleTodoCompletion,
     updateTodo,
     addTodo,
     addProject
    } from './app.js';
import { StorageManager } from './localStorage.js';
import { Todo } from './todo.js';
import Sortable from 'sortablejs';
import { createElement, clearElement, toggleClass } from './domUtils.js';

/**
 * Render the list of projects in the sidebar.
 * @param {Array} projects - Array of Project instances.
 */
export function renderProjects(projects) {
    const projectContainer = document.querySelector('#project-list');
    clearElement(projectContainer); // Clear existing projects

    const fragment = document.createDocumentFragment();

    projects.forEach((project, index) => {
        const projectElement = createElement('li', {
            'data-index': index,
            'tabindex': 0,
            'role': 'button',
            'aria-label': `Select project ${project.name}`
        }, [`project-item`], [
            document.createTextNode(project.name),
            // Uncomment below to add an icon
            createElement('i', { class: 'fas fa-folder' })
        ]);
        // projectElement.textContent = project.name;
        // projectElement.classList.add('project-item');
        // projectElement.setAttribute('data-index', index);
        // projectElement.setAttribute('tabindex', '0'); // Make focusable
        // projectElement.setAttribute('role', 'button');

        fragment.appendChild(projectElement);
    });

    projectContainer.appendChild(fragment);

    highlightSelectedProject(getState().currentProjectIndex);
}

/**
 * Highlight the selected project in the sidebar.
 * @param {number} index – Index of the selected project.
 */
function highlightSelectedProject(index) {
    const items = document.querySelectorAll('#project-list li')
    items.forEach((item, i) => {
        toggleClass(item, 'selected', i === index);
    });
}

/**
 * Render the todos for the selected project.
 * @param {Project} project – The Project instance whose todos are to be rendered.
 */
export function renderTodos(project) {
    const todoContainer = document.querySelector('#todo-container');
    clearElement(todoContainer); // Clear existing todos

    if (!project || !project.todos) {
        console.error('Invalid project or no todos available');
        return;
    }

    const fragment = document.createDocumentFragment();

    project.todos.forEach((todo) => {
        const todoElement = createTodoElement(todo);
        fragment.appendChild(todoElement);
    });

    todoContainer.appendChild(fragment);
}

/**
 * Create a DOM element for a single todo item.
 * @param {Todo} todo – The todo item to create an element for.
 * @returns {HTMLElement} The DOM element representing the todo.
 */
function createTodoElement(todo) {
    const todoElement = createElement('div', {
        'data-id': todo.id,
    }, ['todo-item', `priority-${todo.priority}`], []);

    // Todo checkbox
    const checkbox = createElement('input', {
        type: 'checkbox',
        // checked: todo.completed,
        'aria-label': `Mark "${todo.title}" as completed`
    }, [], []);
    checkbox.addEventListener('change', () => handleTodoCompletionChange(todo));
    // {
    //     // console.log('Before toggleCompletion:', todo); // Debugging
    //     if (typeof todo.toggleCompletion === 'function') {
    //         // todo.toggleCompletion();
    //         toggleTodoCompletion(todo.id);
    //         updateTodoStatus(todo);
    //     } else {
    //         console.error('toggleCompletion is not a function on todo:', todo);
    //     }
    // });

    todoElement.appendChild(checkbox);

    // Todo info (Title and Due Date)
    const todoInfo = createElement('span', {}, ['todo-info'], [
        document.createTextNode(`${todo.title} – Due: ${todo.dueDate}`)
    ]);
    // todoInfo.textContent = `${todo.title} – Due: ${todo.dueDate}`;
    // todoInfo.classList.add('todo-info');
    // todoElement.appendChild(todoInfo);

    // Tags
    // if (todo.tags && todo.tags.length > 0) {
    const tagsContainer = createTagsContainer(todo.tags);

    // Action Buttons Container
    const actionsContainer = createElement('div', {}, ['actions-container'], [
        createActionButton('edit-button', 'fas fa-edit', 'Edit Todo'),
        createActionButton('delete-button', 'fas fa-trash', 'Delete Todo')
    ]);

    // actionsContainer.classList.add('actions-container');

    // // Edit button
    // const editButton = createButton({ iconClass: 'fas fa-edit', ariaLabel: 'Edit Todo' }, 'edit-button');
    // actionsContainer.appendChild(editButton);

    // // Delete button
    // const deleteButton = createButton({ iconClass: 'fas fa-trash', ariaLabel: 'Delete Todo' }, 'delete-button');
    // actionsContainer.appendChild(deleteButton);

    // // Apply priority-based styling
    // todoElement.classList.add(`priority-${todo.priority}`);

    // Toggle completed class
    if (todo.completed) {
        todoElement.classList.add('completed');
    }

    // Append all elements to todoElement
    todoElement.append(checkbox, todoInfo, tagsContainer, actionsContainer);
    return todoElement;
}

/**
 * Creates the tags container for a todo.
 * @param {Array<string>} tags – Array of tags.
 * @returns {HTMLElement} The tags container element.
 */
function createTagsContainer(tags) {
    if (!tags || tags.length === 0) return document.createDocumentFragment();

    const tagsContainer = createElement('div', {}, ['tags-container'], []);
    tags.forEach((tag) => {
        const tagElement = createElement('span', {}, ['tag'], [
            document.createTextNode(tag)
        ]);
        tagsContainer.appendChild(tagElement);
    })
    return tagsContainer;
}

/**
 * Handles the change event for todo completion checkbox.
 * @param {Todo} todo - The todo item being changed.
 */
function handleTodoCompletionChange(todo) {
    toggleTodoCompletion(todo.id);
    const currentProject = getCurrentProject();
    // renderTodos(currentProject);
    updateTodoStatus(todo);
    showToast(`Todo "${todo.title}" marked as ${todo.completed ? 'completed' : 'incomplete'}`);
}

/**
 * Handle updating the todo's completion status
 * @param {Todo} todo – The todo item to update.
 */
function updateTodoStatus(todo) {
    // StorageManager.saveProjects(getState().projects);
    const todoElement = document.querySelector(`.todo-item[data-id="${todo.id}"]`);
    if (!todoElement) return;
    

    // if (todo.completed) {
    //     console.log(`Adding 'completed' class to todo: ${todo.title}`);
    //     todoElement.classList.add('completed');
    // } else {
    //     todoElement.classList.remove('completed');
    // }
    toggleClass(todoElement, 'completed', todo.completed);
    const checkbox = todoElement.querySelector('input[type="checkbox"');
    if (checkbox) checkbox.checked = todo.completed;
}

/**
 * Create a button element with optional icon and text.
 * @param {Object} options – Options for the button.
 * @param {string} [options.iconClass] – Font Awesome icon classes.
 * @param {string} [options.text] – Text content for the button.
 * @param {string} className – Additional class names for the button.
 * @returns {HTMLElement} The created button element.
 */
function createActionButton(className, iconClass, ariaLabel) {
    const button = createElement('button', {
        'class': className,
        'aria-label': ariaLabel
    }, [], [
        createElement('i', { class: iconClass }, [], [])
    ]);
    // button.textContent = text;
    // button.classList.add(className);
    // button.setAttribute('aria-label', ariaLabel);

    // if (iconClass) {
    //     const icon = document.createElement('i');
    //     icon.className = iconClass;
    //     button.appendChild(icon);
    // }

    // if (text) {
    //     const textNode = document.createTextNode(text);
    //     button.appendChild(textNode);
    // }

    return button;
}

/**
 * Highlight the selected project when selected via keyboard.
 * @param {number} index – Index of the selected project.
 */
function highlightProjectSelection(index) {
    highlightSelectedProject(index);
    const currentProject = getState().projects[index];
    renderTodos(currentProject);
}

/**
 * Set up interactions for todo items (edit, delete, toggle completion).
 */
export function setupTodoInteraction() {
    const todoContainer = document.querySelector('#todo-container');

    // Handle edit, delete and toggle completion using event delegation
    todoContainer.addEventListener('click', (event) => {
        const target = event.target.closest('.edit-button, .delete-button');
        if (!target) return;

        const todoElement = target.closest('.todo-item');
        if (!todoElement) return;

        const todoId = todoElement.getAttribute('data-id');
        const currentProject = getCurrentProject();
        const todo = currentProject.getTodoById(todoId);

        if (!todo) {
            showToast(`Todo with ID: ${todoId} not found`, 'error');
            return;
        }

        if (target.matches('.edit-button')) {
            showEditForm(todo);
        } else if (target.matches('.delete-button')) {
            handleDeleteTodo(todoId, currentProject);
        }
    });

    // // Handling checkbox changes
    // todoContainer.addEventListener('change', (event) => {
    //     if (event.target.type === 'checkbox') {
    //         const todoElement = event.target.closest('.todo-item');
    //         if (!todoElement) return;

    //         const todoId = todoElement.getAttribute('data-id');
    //         const currentProject = getCurrentProject();
    //         const todo = currentProject.getTodoById(todoId);

    //         if (!todo) {
    //             console.error(`Todo with ID: ${todoId} not found.`);
    //             return;
    //         }

    //         if (typeof todo.toggleCompletion === 'function') {
    //             todo.toggleCompletion();
    //             updateTodoStatus(todo);
    //         } else {
    //             console.error('toggleCompletion is not a function on todo:', todo);
    //         }
    //     }
    // });
}

/**
 * Handle deleting a todo.
 * @param {string} todoId – ID of the todo to delete.
 * @param {Project} project – The project containing the todo.
 */
function handleDeleteTodo(todoId, project) {
    if (confirm('Are you sure you want to delete this task?')) {
        project.removeTodo(todoId);
        StorageManager.saveProjects(getState().projects);
        renderTodos(project);
    }
}

/**
 * Show the edit form modal with the current task data.
 * @param {Todo} todo – The todo to edit.
 */
function showEditForm(todo) {
    // Fill in the form with current todo data
    setUpEditModal(todo);

    const modal = document.querySelector('#edit-task-modal');
    if (!modal) {
        console.error('Edit Task Modal not found in the DOM.');
        return;
    }

    openEditModal(modal);
    setUpModalEventHandlers(todo, modal);
}


/**
 * Set up the edit modal form with todo information
 * @param {Todo} todo - The todo being edited
 */
function setUpEditModal(todo) {
    setValue('#edit-title', todo.title);
    setValue('#edit-due-date', todo.dueDate);
    setValue('#edit-description', todo.description);
    setValue('#edit-priority', todo.priority);
    setValue('#edit-tags', todo.tags.join(', '));
}

/**
 * Set up initial modal state and Classes
 * @param {HTMLElement} modal
 */
function openEditModal(modal) {
    modal.style.display = 'block';
    modal.setAttribute('aria-hidden', 'false');
    modal.querySelector('#edit-title').focus();
    document.body.classList.add('modal-open'); // Prevent background scrolling
}

/**
 * Attach necessary event handlers for modal actions
 * @param {Todo} todo - Todo being edited
 * @param {HTMLElement} modal
 */
function setUpModalEventHandlers(todo, modal) {
    const saveButton = document.querySelector('#save-changes-button');
    const cancelButton = document.querySelector('#cancel-button');
    const closeButton = document.querySelector('.close-button');

    /**
     * Function to close the edit modal.
     */
    const closeModal = () => {
        // const modal = document.querySelector('#edit-task-modal');
        if (modal) {
            modal.style.display = 'none';
            modal.setAttribute('aria-hidden', 'true');
            document.body.classList.remove('modal-open');
            removeModalHandlers(saveButton, cancelButton, closeButton, closeModal, saveChangesHandler);
        }
    };

    /**
     * Handle saving changes to a todo.
     * @param {Todo} todo – The todo being edited.
     */
    const saveChangesHandler = () => {
        const [title, dueDate, description, priority, tags] = getUpdatedTodoData();

        if (!title || !dueDate) {
            showToast('Title and Due Date are required.', 'error');
            return;
        }

        updateTodoObject(todo, { title, dueDate, description, priority, tags });
        updateTodoInState(todo, closeModal);
    };

    // Add event listeners
    saveButton.addEventListener('click', saveChangesHandler);
    cancelButton.addEventListener('click', closeModal);
    closeButton.addEventListener('click', closeModal);
    window.addEventListener('keydown', escKeyHandler(closeModal));
    window.addEventListener('click', outsideClickHandler(modal, closeModal));
}

/**
 * Remove all event handlers from the modal elements
 */
function removeModalHandlers(saveButton, cancelButton, closeButton, closeModal, saveChangesHandler) {
    // Remove event listeners to prevent duplicate handlers
    saveButton.removeEventListener('click', saveChangesHandler);
    cancelButton.removeEventListener('click', closeModal);
    closeButton.removeEventListener('click', closeModal);
    window.removeEventListener('keydown', escKeyHandler(closeModal));
    window.removeEventListener('click', outsideClickHandler(closeModal));
}

/**
 * Get user input values from modal
 * @returns {Array} Array of updated values from the modal input fields
 */
function getUpdatedTodoData() {
    const updatedTitle = document.querySelector('#edit-title').value.trim();
    const updatedDueDate = document.querySelector('#edit-due-date').value;
    const updatedDescription = document.querySelector('#edit-description').value.trim();
    const updatedPriority = document.querySelector('#edit-priority').value;
    const updatedTagsInput = document.querySelector('#edit-tags').value;
    const updatedTags = updatedTagsInput.split(',').map((tag) => tag.trim()).filter((tag) => tag);

    return [updatedTitle, updatedDueDate, updatedDescription, updatedPriority, updatedTags];
}

/**
 * Update a Todo object with current values.
 * @param {Todo} todo - The todo object to update.
 * @param {Object} updates - Updated field values.
 */
function updateTodoObject(todo, { title, dueDate, description, priority, tags }) {
    // Update todo properties
    todo.title = title;
    todo.dueDate = dueDate;
    todo.description = description;
    todo.priority = priority;
    todo.tags = tags;
}

/**
 * Persist updates to todo and close modal
 * @param {Todo} todo - The todo being updated
 * @param {Function} closeModal - Function to close the modal
 */
function updateTodoInState(todo, closeModal) {
    try {
            updateTodo(todo); // Update in state and save
            closeModal();
            showToast('Todo updated successfully.');
        } catch (error) {
            console.error('Error updating todo:', error);
            showToast('Failed to update todo.', 'error');
        }
}

/**
 * Handles Escape key event to close the modal.
 * @param {Function} closeModal - The modal's close function.
 * @returns {Function} The event handler function.
 */
function escKeyHandler(closeModal) {
    return (event) => {
        if (event.key === 'Escape') {
            closeModal();
        }
    };
}

/**
 * Handles click outside modal to close it.
 * @param {HTMLElement} modal - The modal element.
 * @param {Function} closeModal - The modal's close function.
 * @returns {Function} The event handler function.
 */
function outsideClickHandler(modal, closeModal) {
    // const modal = document.querySelector('#edit-task-modal');
    return (event) => {
        if (event.target === modal) {
            closeModal();
        }
    }
}

/**
 * Initialize UI interactions.
 */
export function initializeUI() {
    setupProjectSelection();
    setupTodoInteraction();
    setupSidebarToggle();
    setupFormValidation();
    setupDragAndDrop();
    setupThemeToggle();
}

/**
 * Setup project selection interactions.
 */
export function setupProjectSelection() {
    const projectContainer = document.querySelector('#project-list');

    projectContainer.addEventListener('click', (event) => {
        const projectItem = event.target.closest('li.project-item');
        if (projectItem) {
            const index = parseInt(event.target.getAttribute('data-index', 10));
            if (!isNaN(index)) {
                setCurrentProjectIndex(index);
                highlightProjectSelection(index);
            } else {
                showToast('Invalid project selection.', 'error');
            }
        }
    });

    // Accessibility: Allow selection via keyboard
    projectContainer.addEventListener('keydown', (event) => {
        if (event.key === 'Enter' && event.target.matches('li.project-item')) {
            const index = parseInt(event.target.getAttribute('data-index'), 10);
            if (!isNaN(index)) {
                setCurrentProjectIndex(index);
                highlightProjectSelection(index);
            } else {
                showToast('Invalid project selection.', 'error');
            }
        }
    });
}

/**
 * Function to handle adding a new todo.
 */
function handleAddTodo() {
    try {
        const title = getElementValue('#todo-title').trim();
        const dueDate = getElementValue('#todo-due-date');
        const description = getElementValue('#todo-description').trim();
        const priority = getElementValue('#todo-priority');
        const tagsInput = getElementValue('#todo-tags');
        const tags = tagsInput.split(',').map((tag) => tag.trim()).filter((tag) => tag);

        if (title && dueDate) { // Ensure title and due date are provided
            addTodo(title, dueDate, description, priority, tags); // Call function to add a new todo
            clearTodoInputs();
            showToast('Todo added successfully.');
        } else {
            showToast('Please fill in both title and due date.', 'error'); // Alert if fields are empty
        }
    } catch (error) {
        console.error('Error adding todo:', error);
    }
}

/**
 * Function to handle adding a new project.
 */
function handleAddProject() {
    try {
        const projectName = document.querySelector('#project-name').value.trim();

        // Call function to add a new project
        if (projectName) {
            addProject(projectName);
            setValue('#project-name', ''); // Clear input field
        } else {
            showToast('Please enter a project name.') // Alert if project name is empty
        }
    } catch (error) {
        console.error('Error adding project:', error);
    }
}

/**
 * Function to clear todo input fields
 */
function clearTodoInputs() {
    setValue('#todo-title', ''); // Clear input field after adding
    setValue('#todo-due-date', '');
    setValue('#todo-description', '');
    setValue('#todo-priority', 'low'); // Reset priority to default
    setValue('#todo-tags', '');
}

// // Function to show alert messages
// function showAlert(message) {
//     const alertBox = document.createElement('div');
//     alertBox.classList.add('alert');
//     alertBox.textContent = message;

//     const main = document.querySelector('main');
//     main.appendChild(alertBox);

//     // alertBox.style.display = 'block';
//     setTimeout(() => {
//         // alertBox.style.display = 'none';
//         alertBox.classList.add('fade-out');
//         alertBox.addEventListener('transitionend', () => {
//             alertBox.remove();
//         });
//     }, 3000);
// }

/**
 * Get the value of an input element.
 * @param {string} selector - The CSS selector for the element.
 * @returns {string} The value of the element.
 */
function getElementValue(selector) {
    return document.querySelector(selector).value;
}

/**
 * Set the value of an input element.
 * @param {string} selector - The CSS selector for the element.
 * @param {string} value - The value to set.
 */
function setValue(selector, value) {
    document.querySelector(selector).value = value;
}

/**
 * Set up event listeners for the application.
 */
export function setupEventListeners() {
    document.addEventListener('click', (event) => {
        if (event.target.matches('#add-todo-button') || event.target.closest('#add-todo-button')) {
            handleAddTodo();
        }
        if (event.target.matches('#add-project-button') || event.target.closest('#add-project-button')) {
            handleAddProject();
        }
    });

    // Accessibility: Allow form submission via Enter key
    const addTodoForm = document.querySelector('#add-todo-form');
    if (addTodoForm) {
        addTodoForm.addEventListener('submit', (e) => {
            e.preventDefault();
            handleAddTodo();
        });
    }

    const addProjectForm = document.querySelector('#add-project');
    if (addProjectForm) {
        addProjectForm.addEventListener('submit', (e) => {
            e.preventDefault();
            handleAddProject();
        });
    }
}

/**
 * Setup sidebar toggle interactions.
 */
export function setupSidebarToggle() {
    const sidebar = document.querySelector('.sidebar');
    const toggleButton = document.querySelector('#sidebar-toggle');

    if (!sidebar || !toggleButton) {
        console.error('Sidebar or toggle button not found');
        return;
    }

    toggleButton.addEventListener('click', () => {
        const isCollapsed = sidebar.classList.toggle('collapsed');
        toggleButton.setAttribute('aria-expanded', !isCollapsed);
        showToast(`Sidebar ${isCollapsed ?  'collapsed' : 'expanded'}.`);
    });
}

/**
 * Setup form validation for add todo form.
 */
function setupFormValidation() {
    const todoTitleInput = document.querySelector('#todo-title');

    if(todoTitleInput) {
        todoTitleInput.addEventListener('input', () => {
            if (todoTitleInput.value.trim() === '') {
                todoTitleInput.classList.add('invalid');
                todoTitleInput.setCustomValidity('Title is required.');
            } else {
                todoTitleInput.classList.remove('invalid');
                todoTitleInput.setCustomValidity('');
            }
        });
    }
}

/**
 * Setup drag and drop functionality for todo.
 */
export function setupDragAndDrop() {
    const todoContainer = document.querySelector('#todo-container');

    if (todoContainer) {
        new Sortable(todoContainer, {
            animation: 150,
            onEnd: function(/** Event */ evt) {
                // const itemEl = evt.item; // dragged HTMLElement
                const fromIndex = evt.oldIndex;
                const toIndex = evt.newIndex;
                updateTodoOrder(fromIndex, toIndex);
                showToast('Todo order updated.');
            },
        });
    }
}

/**
 * Update the order of todos after drag and drop.
 * @param {number} fromIndex – The original index of the dragged todo.
 * @param {number} toIndex – The new index of the dragged todo.
 */
function updateTodoOrder(fromIndex, toIndex) {
    const currentProject = getCurrentProject();
    if (!currentProject) {
        showToast('No project selected.', 'error');
        return;
    }

    const movedTodo = currentProject.todos.splice(fromIndex, 1)[0];
    currentProject.todos.splice(toIndex, 0, movedTodo);
    StorageManager.saveProjects(getState().projects);
}

/**
 * Function to show toast messages.
 * @param {string} message – The message to display.
 * @param {string} [type='info'] – The type of the message for styling purposes.
 */
function showToast(message, type = 'info') {
    const toastContainer = document.querySelector('#toast-container');
    const toast = createElement('div', {}, [`toast`, `toast-${type}`], [
        document.createTextNode(message)
    ]);

    toastContainer.appendChild(toast);

    setTimeout(() => {
        toast.classList.add('fade-out');
        toast.addEventListener('transitionend', () => {
            toast.remove();
        });
    }, 4000);
}

/**
 * Setup theme toggle functionality.
 */
export function setupThemeToggle() {
    const themeToggle = document.querySelector('#theme-toggle');

    if (!themeToggle) return;

    themeToggle.addEventListener('click', () => {
        const currentTheme = document.documentElement.getAttribute('data-theme');
        const newTheme = currentTheme === 'dark' ? 'light' : 'dark';
        document.documentElement.setAttribute('data-theme', newTheme);
        localStorage.setItem('theme', newTheme);
        updateThemeIcon(newTheme);
        showToast(`Switched to ${newTheme} mode.`);
    });

    // On load, set theme from localStorage
    const savedTheme = localStorage.getItem('theme') || 'light';
    document.documentElement.setAttribute('data-theme', savedTheme);
    updateThemeIcon(savedTheme);
}

/**
 * Updates the theme toggle icon based on the current theme.
 * @param {string} theme - The current theme ('light' or 'dark').
 */
function updateThemeIcon(theme) {
    const themeToggle = document.querySelector('#theme-toggle');

    if (!themeToggle) return;

    const icon = themeToggle.querySelector('i');
    if (theme === 'dark') {
        icon.className = 'fas fa-sun';
    } else {
        icon.className  = 'fas fa-moon'
    }
}

/* main.css */
/* @import "~@fortawsome/fontawesome-free/css/all.min.css"; */

/* CSS Variables for consistent theming */
:root {
    /* Light theme colors */
    --primary-color: #4CAF60;
    --secondary-color: #f9f9f9;
    --accent-color: #FFC107;
    --text-color: #212121;
    --background-color: #FFFFFF;
    --modal-background: rgba(0, 0, 0, 0.4);
    --button-hover-color: #218838;
    --button-bg-color: var(--primary-color);
    --button-text-color: #fff;
    --selected-project-font-weight: bold;
    --font-family: 'Roboto', Arial, Helvetica, sans-serif;
}

[data-theme="dark"] {
    --background-color: #121212;
    --text-color: #FFFFFF;
    --secondary-color: #1e1e1e;
    --accent-color: #bb86fc;
    --modal-background: rgba(255, 255, 255, 0.1);
    --button-hover-color: #1c7430;
}

/* Global Box Sizing and Reset */
*, *::before, *::after {
    box-sizing: border-box;
    margin: 0;
    padding: 0;
}

/* Base Styles */
body {
    font-family: var(--font-family);
    background-color: var(--background-color);
    padding: 1.25rem; /* 20px */
    color: var(--text-color);
    /* background: linear-gradient(135deg, #153677, #4e085f); */
    /* color: white; */
    transition: background-color 0.3s color 0.3s;
}

.wrapper {
    display: flex; /* Use flexbox for layout */
    flex-wrap: wrap;
}


/* Sidebar Styling */
.sidebar {
    width: 20vw;
    min-height: 100vh;
    background-color: var(--secondary-color);
    padding: 1.25rem;
    position: fixed;
    overflow-y: auto;
    transition: transform 0.3s ease;
    z-index: 1000;
}

.sidebar.collapsed {
    transform: translateX(-100%);
}

.sidebar h2 {
    margin-top: 0;
    color: var(--text-color);
}

.sidebar ul {
    list-style-type: none;
    padding: 0;
}

.sidebar ul li {
    margin: 0.625rem 0;
}

.sidebar ul li.project-item {
    padding: 0.5rem;
    border-radius: 0.25rem;
    cursor: pointer;
    transition: background-color 0.3s ease;
    outline: none;
    
    display: flex;
    justify-content: space-between;
    align-items: center;
}

.sidebar ul li.project-item:hover,
.sidebar ul li.project-item:focus {
    background-color: var(--accent-color);
}

.sidebar ul li.project-item.selected {
    font-weight: var(--selected-project-font-weight);
    background-color: var(--accent-color);
    border-left: 4px solid --primary-color;
}

/* Sidebar Toggle Button */
.sidebar-toggle {
    position: fixed;
    top: 10px;
    left: 10px;
    background: var(--button-bg-color);
    color: var(--button-text-color);
    border: none;
    border-radius: 0.3125rem;
    cursor: pointer;
    padding: 0.5rem;
    z-index: 1001;
    transition: background-color 0.3s ease;
}

.sidebar-toggle:hover,
.sidebar-toggle:focus {
    background-color: var(--button-hover-color);
    outline: none;
}

/* Main Content Styling */
#app {
    flex: 1;
    /* max-width: 600px; */
    margin-left: 22vw; /* Slightly more then sidebar width for spacing */
    /* background: linear-gradient(135deg, #153677, #4e085f); */
    padding: 1.25rem;
    border-radius: 0.625rem;
    background-color: var(--background-color);
    min-height: 100vh;
    box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
    transition: margin-left 0.3s ease, background-color 0.3s, box-shadow 0.3s;
}

.sidebar.collapsed + #app {
    margin-left: 2rem;
}

h1,
h2 {
    color: var(--text-color);
    font-weight: 500;
    margin-bottom: 1rem;
}

/* Todo Container Styling */
/* #project-list,  */
#todo-container {
    background: var(--background-color);
    padding: 0.625rem;
    border-radius: 0.3125rem;
    box-shadow: 0 0 0.625rem rgba(0, 0, 0, 0.1);
    margin-bottom: 1.25rem;
    transition: background 0.3s, box-shadow 0.3s;
}

.todo-item {
    display: flex;
    /* flex-direction: column; */
    justify-content: space-between;
    align-items: center;
    padding: 0.5rem;
    border-bottom: 1px solid #ddd;
    margin-bottom: 10px;
    border-radius: 5px;
    background-color: var(--secondary-color);
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
    transition: box-shadow 0.3s ease, background-color 0.3s;
}

.todo-item:hover {
    box-shadow: 0 3px 6px rgba(0, 0, 0, 0.2);
}

.todo-item:last-child {
    border-bottom: none;
}

.todo-item.completed .todo-info {
    text-decoration: line-through !important;
    color: #888 !important;
}

/* #project-list li {
    cursor: pointer;
} */

/* #project-list li.project-item {
    display: flex;
    justify-content: space-between;
    align-items: center;
} */

/* Forms and Inputs */
input, 
select {
    width: calc(100% - 20px);
    padding: 0.75rem;
    margin-bottom: 0.625rem;
    border: 1px solid #ccc;
    border-radius: 0.3125rem;
    transition: border-color 0.3s ease;
}

input:focus,
select:focus {
    border-color: var(--primary-color);
    outline: none;
}

button {
    padding: 0.5rem 0.75rem;
    background-color: var(--button-bg-color);
    color: var(--button-text-color);
    border: none;
    border-radius: 0.3125rem;
    cursor: pointer;
    transition: background-color 0.3s ease, transform 0.2 ease;
    /* margin-left: 0.3125rem; */
    font-weight: 500;
}

button:hover,
#project-list li:hover {
    background-color: var(--button-hover-color);
    transform: translateY(-2px);
    outline: none;
}

button:focus,
.project-item:focus {
    outline: 3px solid var(--primary-color);
    outline-offset: 2px;
}

/* Priority Classes */
.priority-high {
    color: red;
}

.priority-medium {
    color: goldenrod;
}

.priority-low {
    color: green;
}

/* #edit-task-modal {
    background-color: white;
    padding: 20px;
    border-radius: 5px;
} */

/* Modal Styling */
.modal {
    display: none; /* Hidden by default */
    position: fixed; /* Stay in place */
    z-index: 1002; /* Sit on top */
    left: 0;
    top: 0;
    width: 100%;
    height: 100%;
    overflow: auto; /* Enable scroll if needed */
    /* background-color: rgb(0, 0, 0);  Fallback color */
    background-color: var(--modal-background) /* Black w/ opacity */;
    transition: background-color 0.3s ease;
}

.modal-content {
    opacity: 0;
    transform: translateY(-50px);
    animation: modalIn 0.3s forwards;
    background-color: var(--background-color);
    margin: 10% auto; /* 10% from the top and centered */
    padding: 2rem;
    /* border: 1px solid #888; */
    width: 90%; /* Could be more or less, depending on screen size */
    max-width: 31.25rem; /* 500px */
    border-radius: 0.3125rem;
    position: relative;
    box-shadow: 0 5px 15px rgba(0, 0, 0, 0.3);
    transition: background-color 0.3s ease, box-shadow 0.3s ease;

    /* @media (min-width: 600px) {
        width: 60%;
    }

    @media (min-width: 900px) {
        width: 40%;
    } */
}

.modal-content h2 {
    margin-bottom: 1rem;
}

.modal-content input,
.modal-content select {
    width: 100%;
    margin-bottom: 1rem;
    padding: 0.75rem;
    border: 1px solid #ccc;
    border-radius: 5px;
}

.modal-content button {
    margin-right: 0.5rem;
}

/* Close Button */
.close-button {
    /* color: #aaa; */
    /* float: right; */
    position: absolute;
    top: 10px;
    right: 15px;
    font-size: 1.75rem;
    font-weight: bold;
    cursor: pointer;
    border: none;
    background: none;
    transition: color 0.3s ease;
}

.close-button:hover,
.close-button:focus {
    color: black;
    text-decoration: none;
    outline: none;
    /* cursor: pointer; */
}

.edit-button,
.delete-button {
    background: none;
    border: none;
    cursor: pointer;
    margin-left: 6px;
    /* position: relative; */
}

.edit-button i,
.delete-button i {
    font-size: 1rem;
    color: var(--text-color);
}

/* .selected {
    font-weight: bold;
} */

/* Animations */
@keyframes modalIn {
    to {
        opacity: 1;
        transform: translateY(0);
    }
}

.todo-item.fade-in {
    animation: fadeIn 0.5s forwards;
}

.todo-item.fade-out {
    animation: fadeOut 0.5s forwards;
}

@keyframes fadeIn {
    from { 
        opacity: 0; 
    }
    to {
        opacity: 1;
    }
}

@keyframes fadeOut {
    from {
        opacity: 1;
    }
    to {
        opacity: 0;
    }
}

/* Invalid Input Styling */
.invalid {
    border-color: red;
}

/* Toast Container Styling */
#toast-container {
    position: fixed;
    bottom: 20px;
    right: 20px;
    z-index: 1003;
}

.toast {
    background-color: #333;
    color: #fff;
    padding: 0.9375rem; /* 15px */
    margin-top: 0.625rem; /* 10px */
    border-radius: 0.3125rem;
    opacity: 0;
    animation: fadeInOut 4s forwards;
}

/* Toast Types */
.toast-info {
    background-color: #333;
}
.toast-success {
    background-color: #28a745;
}
.toast-error {
    background-color: #dc3545;
}

@keyframes fadeInOut {
    0% { opacity: 0; }
    10%, 90% { opacity: 1; }
    100% { opacity: 0; }
}

/* Tags Styling */
.tags-container {
    margin-top: 0.625rem;
}

.tag {
    display: inline-block;
    background-color: var(--accent-color);
    color: #fff;
    padding: 0.3125rem 0.625rem;
    border-radius: 0.3125rem;
    margin-right: 0.3125rem;
    font-size: 0.75rem;
}

/* Visually Hidden Class for Accessibility */
.visually-hidden {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
}

/* Responsive Design */
@media (max-width: 760px) {
    .sidebar {
        width: 100%;
        height: auto;
        position: relative;
        transform: translateX(0);
    }

    #app {
        margin-left: 0;
        max-width: 100%;
    }

    .modal-content {
        width: 95%;
    }
    
    #sidebar-toggle {
        top: 10px;
        left: auto;
        right: 10px;
    }
}

/* Scrollbar Styling for WebKit Browsers */
::-webkit-scrollbar {
    width: 8px;
}

::-webkit-scrollbar-track {
    background: var(--secondary-color);
}

::-webkit-scrollbar-thumb {
    background-color: var(--accent-color);
    border-radius: 10px;
    border: 2px solid --secondary-color;
}