diff --git a/.gitignore b/.gitignore index d663edd..6fafe04 100644 --- a/.gitignore +++ b/.gitignore @@ -1,23 +1,22 @@ -# Java -*.class -*.log -*.jar -*.war -*.ear -# Build directories -target/ -build/ -out/ -bin/ -# Editor temporary files -*.swp -*~ -# IDE files -.idea/ -.vscode/ -*.iml -*.iws -*.ipr -# Other -.DS_Store -Thumbs.db \ No newline at end of file +# Python +__pycache__/ +*.py[cod] +*.egg-info/ +.venv/ +venv/ +env/ + +# OS +.DS_Store + +# IDE +.vscode/ +.idea/ + +# Env +.env + +# Caches +.pytest_cache/ +.mypy_cache/ + diff --git a/DEPLOYMENT.md b/DEPLOYMENT.md new file mode 100644 index 0000000..652697d --- /dev/null +++ b/DEPLOYMENT.md @@ -0,0 +1,154 @@ +# πŸš€ GitHub Pages Deployment Guide + +This guide will walk you through deploying your Singly Linked List Game to GitHub Pages. + +## Prerequisites + +- A GitHub account +- Git installed on your computer +- Basic knowledge of Git commands + +## Step-by-Step Deployment + +### 1. Create a New Repository + +1. Go to [GitHub](https://github.com) and sign in +2. Click the "+" icon in the top right corner +3. Select "New repository" +4. Name your repository (e.g., `singly-linked-list-game`) +5. Make it **Public** (required for free GitHub Pages) +6. Don't initialize with README (we already have one) +7. Click "Create repository" + +### 2. Upload Your Files + +#### Option A: Using GitHub Web Interface +1. In your new repository, click "uploading an existing file" +2. Drag and drop all your project files: + - `index.html` + - `styles.css` + - `script.js` + - `README.md` + - `.gitignore` +3. Add a commit message: "Initial commit: Singly Linked List Game" +4. Click "Commit changes" + +#### Option B: Using Git Command Line +```bash +# Clone the repository +git clone https://github.com/yourusername/singly-linked-list-game.git +cd singly-linked-list-game + +# Copy your project files to this directory +# (index.html, styles.css, script.js, README.md, .gitignore) + +# Add all files +git add . + +# Commit +git commit -m "Initial commit: Singly Linked List Game" + +# Push to GitHub +git push origin main +``` + +### 3. Enable GitHub Pages + +1. Go to your repository on GitHub +2. Click on **Settings** tab +3. Scroll down to **Pages** section (or click "Pages" in the left sidebar) +4. Under **Source**, select "Deploy from a branch" +5. Under **Branch**, select `main` (or `master`) +6. Click **Save** + +### 4. Wait for Deployment + +- GitHub will automatically build and deploy your site +- This usually takes 1-5 minutes +- You'll see a green checkmark when deployment is complete + +### 5. Access Your Game + +Your game will be available at: +``` +https://yourusername.github.io/singly-linked-list-game +``` + +## 🎯 Custom Domain (Optional) + +If you want to use a custom domain: + +1. In the Pages settings, enter your domain in the "Custom domain" field +2. Add a CNAME record in your domain provider's DNS settings +3. Point it to `yourusername.github.io` + +## πŸ”„ Updating Your Game + +To update your game after making changes: + +### Using GitHub Web Interface +1. Navigate to the file you want to edit +2. Click the pencil icon to edit +3. Make your changes +4. Commit with a descriptive message + +### Using Git Command Line +```bash +# Pull latest changes +git pull origin main + +# Make your changes to files + +# Add and commit +git add . +git commit -m "Update: [describe your changes]" + +# Push to GitHub +git push origin main +``` + +## πŸ› Troubleshooting + +### Common Issues + +**Page not loading:** +- Check if the repository is public +- Verify all files are in the root directory +- Wait a few minutes for deployment to complete + +**Game not working:** +- Check browser console for JavaScript errors +- Ensure all file paths are correct +- Verify all files were uploaded + +**Styling issues:** +- Check if CSS file was uploaded correctly +- Verify file names match exactly (case-sensitive) + +### Getting Help + +- Check the [GitHub Pages documentation](https://pages.github.com/) +- Look for error messages in the Actions tab +- Verify your repository settings + +## πŸ“± Testing + +After deployment, test your game on: +- Desktop browsers (Chrome, Firefox, Safari, Edge) +- Mobile devices +- Different screen sizes +- Various browsers + +## πŸŽ‰ Success! + +Once deployed, you can: +- Share your game with friends and students +- Use it in educational settings +- Showcase your programming skills +- Contribute to open source education + +--- + +**Happy Deploying! πŸš€** + +Your Singly Linked List Game will be live on the web and accessible to anyone with an internet connection! diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..656e8d6 --- /dev/null +++ b/LICENSE @@ -0,0 +1,23 @@ +MIT License + +Copyright (c) 2025 + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + + diff --git a/README.md b/README.md index 866e27f..19f63ec 100644 --- a/README.md +++ b/README.md @@ -1,88 +1,46 @@ -# Hacktoberfest Projects Repository - -Welcome to the **Hacktoberfest Projects** repository! This is a place where developers can upload and showcase their full stack projects. Whether you're an experienced developer or just starting, feel free to contribute your projects and help others learn. - -## Table of Contents - -- [About the Repository](#about-the-repository) -- [How to Get Started](#how-to-get-started) -- [How to Contribute](#how-to-contribute) -- [Past Contributors](#contributors) -- [License](#license) - -## About the Repository - -This repository collects full stack projects using popular technologies like: - -- **Frontend**: HTML, CSS, JavaScript, React, Angular, Vue.js, etc. -- **Backend**: PHP, Go, Node.js, Express, Django, etc. -- **Databases**: MongoDB, PostgreSQL, MySQL, etc. - -Each project is designed to be easy to set up and customize, offering a great resource for developers of all levels. - -## How to Get Started - -Follow these steps to start using this repository: - -1. **Clone the repository** - - ```bash - git clone https://github.com/gitsofaryan/Hacktoberfest-Projects-2024.git - cd Hacktoberfest-Projects-2024 - -2. Explore projects: Look through the folders to find projects that interest you. - -3. Run a project: Each project has a README file with instructions on how to set it up and run. - - -## How to Contribute -We welcome your contributions! Here’s how to add your project to the repository: - -### Steps to Contribute - -1. Fork the repository: Click the "Fork" button at the top of the page. - -2. Create a new branch for your project: - -```bash -git checkout -b your-project-name -``` - -3. Add your project: Create a new folder for your project and include: - -- Your source code -- A README file with instructions for setup and running the project -- Any other important files (e.g., images, config files) - -4. Commit your changes: - -```bash -git add . -git commit -m "Added my project: Your Project Name" -``` - -5. Push to your branch: -```bash -git push origin your-project-name -``` - -6. Create a Pull Request: Go back to the original repository and click "New Pull Request." - -## Pull Request Guidelines - -- Make sure your README clearly explains how to set up and run your project. -- Follow best coding practices. -- Provide a brief description of your project in the Pull Request. - -[![Contributors](https://img.shields.io/github/contributors/gitsofaryan/Hacktoberfest-Projects-2025?style=for-the-badge)](https://github.com/gitsofaryan/Hacktoberfest-Projects-2025/graphs/contributors) - - -

- - Contributors - -

- -See the full list of contributors and their contributions on the [`GitHub Contributors Graph`](https://github.com/gitsofaryan/Hacktoberfest-Projects-2025/graphs/contributors). - -### Thank you for contributing to the Hacktoberfest Projects repository! We’re excited to see your projects and hope this helps you grow as a developer. Happy coding! +## Godseye OSINT Toolkit (MVP) + +Godseye is a privacy-respecting, public-data OSINT toolkit. It aggregates open sources like crt.sh (certificate transparency), Wayback Machine, and GitHub to help investigate domains and usernames. + +### Features (MVP) +- Domain enrichment: subdomains via crt.sh, historical URLs via Wayback Machine +- Username enrichment: presence checks on popular platforms + GitHub profile summary +- HTTP API (FastAPI) and CLI (Typer) + +### Quickstart + +1) Python 3.10+ + +2) Create a virtual environment and install deps +```bash +python -m venv .venv +. .venv/Scripts/activate # Windows PowerShell: . .venv/Scripts/Activate.ps1 +pip install -r requirements.txt +``` + +3) (Optional) Configure environment variables +Copy `.env.example` to `.env` and add tokens if you have them. + +4) Run the CLI +```bash +python -m godseye.cli domain example.com +python -m godseye.cli username torvalds +``` + +5) Run the API +```bash +uvicorn godseye.api.main:app --reload +# Open: http://127.0.0.1:8000/docs +``` + +### Environment variables +- `GITHUB_TOKEN` (optional): increases GitHub rate limits for user lookups. + +### Notes +- Only public sources are used. Respect rate limits and each source's ToS. +- Results are best-effort and may contain inaccuracies. Always verify critical findings. + +### License +MIT + + diff --git a/index.html b/index.html new file mode 100644 index 0000000..223823d --- /dev/null +++ b/index.html @@ -0,0 +1,70 @@ + + + + + + Notion-Style Todo App + + + + +
+
+

Smart Todo

+

Organize your life, one task at a time

+
+ +
+ +
+ + + +
+
+ +
+
+ + + + + +
+
+ +
+
+ 0 + Total +
+
+ 0 + Pending +
+
+ 0 + Completed +
+
+ + +
+ + + diff --git a/index1.html b/index1.html new file mode 100644 index 0000000..e69de29 diff --git a/script.js b/script.js new file mode 100644 index 0000000..6ad6b56 --- /dev/null +++ b/script.js @@ -0,0 +1,245 @@ +class TodoApp { + constructor() { + this.todos = JSON.parse(localStorage.getItem('todos')) || []; + this.filteredTodos = [...this.todos]; + this.currentFilter = 'all'; + this.searchQuery = ''; + + this.initializeElements(); + this.bindEvents(); + this.renderTodos(); + this.updateStats(); + } + + initializeElements() { + this.todoInput = document.getElementById('todoInput'); + this.addBtn = document.getElementById('addBtn'); + this.todoList = document.getElementById('todoList'); + this.searchInput = document.getElementById('searchInput'); + this.prioritySelect = document.getElementById('prioritySelect'); + this.categorySelect = document.getElementById('categorySelect'); + this.dueDateInput = document.getElementById('dueDateInput'); + this.filterBtns = document.querySelectorAll('.filter-btn'); + } + + bindEvents() { + this.addBtn.addEventListener('click', () => this.addTodo()); + this.todoInput.addEventListener('keypress', (e) => { + if (e.key === 'Enter') this.addTodo(); + }); + + this.searchInput.addEventListener('input', (e) => { + this.searchQuery = e.target.value.toLowerCase(); + this.filterTodos(); + }); + + this.filterBtns.forEach(btn => { + btn.addEventListener('click', (e) => { + this.setActiveFilter(e.target.dataset.filter); + }); + }); + + // Set default due date to tomorrow + const tomorrow = new Date(); + tomorrow.setDate(tomorrow.getDate() + 1); + this.dueDateInput.value = tomorrow.toISOString().split('T')[0]; + } + + setActiveFilter(filter) { + this.currentFilter = filter; + this.filterBtns.forEach(btn => { + btn.classList.toggle('active', btn.dataset.filter === filter); + }); + this.filterTodos(); + } + + filterTodos() { + this.filteredTodos = this.todos.filter(todo => { + const matchesSearch = todo.text.toLowerCase().includes(this.searchQuery); + const matchesFilter = this.currentFilter === 'all' || + (this.currentFilter === 'pending' && !todo.completed) || + (this.currentFilter === 'completed' && todo.completed); + return matchesSearch && matchesFilter; + }); + this.renderTodos(); + } + + addTodo() { + const todoText = this.todoInput.value.trim(); + if (todoText === '') return; + + const todo = { + id: Date.now(), + text: todoText, + completed: false, + priority: this.prioritySelect.value, + category: this.categorySelect.value, + dueDate: this.dueDateInput.value, + createdAt: new Date().toISOString() + }; + + this.todos.push(todo); + this.saveTodos(); + this.filterTodos(); + this.updateStats(); + this.todoInput.value = ''; + this.todoInput.focus(); + } + + toggleTodo(id) { + const todo = this.todos.find(t => t.id === id); + if (todo) { + todo.completed = !todo.completed; + this.saveTodos(); + this.filterTodos(); + this.updateStats(); + } + } + + editTodo(id) { + const todo = this.todos.find(t => t.id === id); + if (!todo) return; + + const newText = prompt('Edit todo:', todo.text); + if (newText !== null && newText.trim() !== '') { + todo.text = newText.trim(); + this.saveTodos(); + this.filterTodos(); + } + } + + deleteTodo(id) { + if (confirm('Are you sure you want to delete this todo?')) { + this.todos = this.todos.filter(t => t.id !== id); + this.saveTodos(); + this.filterTodos(); + this.updateStats(); + } + } + + saveTodos() { + localStorage.setItem('todos', JSON.stringify(this.todos)); + } + + updateStats() { + const total = this.todos.length; + const completed = this.todos.filter(t => t.completed).length; + const pending = total - completed; + + document.getElementById('totalCount').textContent = total; + document.getElementById('completedCount').textContent = completed; + document.getElementById('pendingCount').textContent = pending; + } + + renderTodos() { + this.todoList.innerHTML = ''; + + if (this.filteredTodos.length === 0) { + const emptyState = this.searchQuery || this.currentFilter !== 'all' + ? 'No todos match your search/filter criteria.' + : 'No todos yet. Add one above!'; + + this.todoList.innerHTML = ` +
+ +

${emptyState}

+
+ `; + return; + } + + this.filteredTodos.forEach(todo => { + const li = document.createElement('li'); + li.className = `todo-item ${todo.completed ? 'completed' : ''}`; + + const dueDate = new Date(todo.dueDate); + const today = new Date(); + const tomorrow = new Date(today); + tomorrow.setDate(tomorrow.getDate() + 1); + + const isOverdue = !todo.completed && dueDate < today && dueDate.toDateString() !== today.toDateString(); + + li.innerHTML = ` +
+ ${this.escapeHtml(todo.text)} +
+
+ + + ${todo.priority} + + + + ${todo.category} + + + + ${this.formatDate(todo.dueDate)} + ${isOverdue ? ' ' : ''} + + + + ${this.formatRelativeTime(todo.createdAt)} + +
+
+ + + +
+ `; + + this.todoList.appendChild(li); + }); + } + + formatDate(dateString) { + const date = new Date(dateString); + const today = new Date(); + const tomorrow = new Date(today); + tomorrow.setDate(tomorrow.getDate() + 1); + + if (date.toDateString() === today.toDateString()) { + return 'Today'; + } else if (date.toDateString() === tomorrow.toDateString()) { + return 'Tomorrow'; + } else { + return date.toLocaleDateString('en-US', { + month: 'short', + day: 'numeric', + year: date.getFullYear() !== today.getFullYear() ? 'numeric' : undefined + }); + } + } + + formatRelativeTime(dateString) { + const date = new Date(dateString); + const now = new Date(); + const diffInMinutes = Math.floor((now - date) / (1000 * 60)); + + if (diffInMinutes < 1) return 'Just now'; + if (diffInMinutes < 60) return `${diffInMinutes}m ago`; + if (diffInMinutes < 1440) return `${Math.floor(diffInMinutes / 60)}h ago`; + return `${Math.floor(diffInMinutes / 1440)}d ago`; + } + + escapeHtml(text) { + const div = document.createElement('div'); + div.textContent = text; + return div.innerHTML; + } +} + +// Initialize the app when the page loads +document.addEventListener('DOMContentLoaded', () => { + window.todoApp = new TodoApp(); +}); diff --git a/style.css b/style.css new file mode 100644 index 0000000..a1ea8b5 --- /dev/null +++ b/style.css @@ -0,0 +1,429 @@ +* { + margin: 0; + padding: 0; + box-sizing: border-box; +} + +:root { + --primary-color: #6366f1; + --primary-dark: #4f46e5; + --secondary-color: #8b5cf6; + --accent-color: #06b6d4; + --success-color: #10b981; + --warning-color: #f59e0b; + --danger-color: #ef4444; + --text-primary: #1f2937; + --text-secondary: #6b7280; + --bg-primary: #ffffff; + --bg-secondary: #f9fafb; + --border-color: #e5e7eb; + --shadow-sm: 0 1px 2px 0 rgba(0, 0, 0, 0.05); + --shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.1); + --shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.1); + --shadow-xl: 0 20px 25px -5px rgba(0, 0, 0, 0.1); +} + +body { + font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; + background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); + min-height: 100vh; + color: var(--text-primary); + line-height: 1.6; +} + +.container { + max-width: 900px; + margin: 2rem auto; + padding: 0 1rem; +} + +.app-header { + text-align: center; + margin-bottom: 2rem; +} + +.app-header h1 { + font-size: 2.5rem; + font-weight: 800; + background: linear-gradient(135deg, #4f46e5, #7c3aed); + -webkit-background-clip: text; + -webkit-text-fill-color: transparent; + background-clip: text; + margin-bottom: 0.5rem; + filter: brightness(0.8) contrast(1.2); +} + +.app-header h1 i { + margin-right: 0.5rem; + color: var(--primary-color); +} + +.subtitle { + color: var(--text-secondary); + font-size: 1.1rem; + font-weight: 500; +} + +.search-section { + background: rgba(255, 255, 255, 0.1); + backdrop-filter: blur(10px); + border-radius: 16px; + padding: 1.5rem; + margin-bottom: 2rem; + border: 1px solid rgba(255, 255, 255, 0.2); +} + +.search-box { + position: relative; + margin-bottom: 1rem; +} + +.search-box i { + position: absolute; + left: 1rem; + top: 50%; + transform: translateY(-50%); + color: var(--text-secondary); +} + +#searchInput { + width: 100%; + padding: 1rem 1rem 1rem 3rem; + border: none; + border-radius: 12px; + background: rgba(255, 255, 255, 0.9); + font-size: 1rem; + transition: all 0.3s ease; +} + +#searchInput:focus { + outline: none; + background: white; + box-shadow: var(--shadow-lg); +} + +.filter-buttons { + display: flex; + gap: 0.5rem; + flex-wrap: wrap; +} + +.filter-btn { + padding: 0.5rem 1rem; + border: none; + border-radius: 8px; + background: rgba(255, 255, 255, 0.2); + color: white; + cursor: pointer; + font-weight: 500; + transition: all 0.3s ease; +} + +.filter-btn:hover { + background: rgba(255, 255, 255, 0.3); +} + +.filter-btn.active { + background: var(--primary-color); + color: white; +} + +.input-section { + background: rgba(255, 255, 255, 0.1); + backdrop-filter: blur(10px); + border-radius: 16px; + padding: 1.5rem; + margin-bottom: 2rem; + border: 1px solid rgba(255, 255, 255, 0.2); +} + +.input-row { + display: grid; + grid-template-columns: 2fr 1fr 1fr 1fr auto; + gap: 1rem; + align-items: center; +} + +#todoInput { + padding: 1rem; + border: none; + border-radius: 12px; + background: rgba(255, 255, 255, 0.9); + font-size: 1rem; + transition: all 0.3s ease; +} + +#todoInput:focus { + outline: none; + background: white; + box-shadow: var(--shadow-lg); +} + +#prioritySelect, #categorySelect, #dueDateInput { + padding: 1rem; + border: none; + border-radius: 12px; + background: rgba(255, 255, 255, 0.9); + font-size: 1rem; + cursor: pointer; + transition: all 0.3s ease; +} + +#prioritySelect:focus, #categorySelect:focus, #dueDateInput:focus { + outline: none; + background: white; + box-shadow: var(--shadow-lg); +} + +#addBtn { + padding: 1rem 1.5rem; + background: linear-gradient(135deg, var(--primary-color), var(--secondary-color)); + color: white; + border: none; + border-radius: 12px; + cursor: pointer; + font-size: 1rem; + font-weight: 600; + transition: all 0.3s ease; + display: flex; + align-items: center; + gap: 0.5rem; +} + +#addBtn:hover { + transform: translateY(-2px); + box-shadow: var(--shadow-xl); +} + +.stats-section { + display: grid; + grid-template-columns: repeat(3, 1fr); + gap: 1rem; + margin-bottom: 2rem; +} + +.stat-item { + background: rgba(255, 255, 255, 0.1); + backdrop-filter: blur(10px); + border-radius: 12px; + padding: 1.5rem; + text-align: center; + border: 1px solid rgba(255, 255, 255, 0.2); + transition: transform 0.3s ease; +} + +.stat-item:hover { + transform: translateY(-4px); +} + +.stat-number { + display: block; + font-size: 2rem; + font-weight: 800; + color: white; + margin-bottom: 0.5rem; +} + +.stat-label { + color: rgba(255, 255, 255, 0.8); + font-weight: 500; + text-transform: uppercase; + letter-spacing: 0.5px; + font-size: 0.875rem; +} + +#todoList { + list-style: none; +} + +.todo-item { + background: rgba(255, 255, 255, 0.95); + backdrop-filter: blur(10px); + border-radius: 16px; + padding: 1.5rem; + margin-bottom: 1rem; + border: 1px solid rgba(255, 255, 255, 0.2); + transition: all 0.3s ease; + position: relative; + overflow: hidden; +} + +.todo-item::before { + content: ''; + position: absolute; + left: 0; + top: 0; + bottom: 0; + width: 4px; + background: var(--primary-color); + transition: all 0.3s ease; +} + +.todo-item:hover { + transform: translateY(-4px); + box-shadow: var(--shadow-xl); +} + +.todo-item.completed::before { + background: var(--success-color); +} + +.todo-item.completed { + opacity: 0.8; +} + +.todo-item.completed .todo-text { + text-decoration: line-through; + color: var(--text-secondary); +} + +.todo-header { + display: flex; + align-items: center; + gap: 1rem; + margin-bottom: 1rem; +} + +.todo-text { + flex: 1; + font-size: 1.1rem; + font-weight: 500; + color: var(--text-primary); +} + +.todo-meta { + display: flex; + gap: 1rem; + margin-bottom: 1rem; + flex-wrap: wrap; +} + +.meta-item { + display: flex; + align-items: center; + gap: 0.5rem; + font-size: 0.875rem; + color: var(--text-secondary); +} + +.priority-badge { + padding: 0.25rem 0.75rem; + border-radius: 20px; + font-size: 0.75rem; + font-weight: 600; + text-transform: uppercase; + letter-spacing: 0.5px; +} + +.priority-low { + background: #dbeafe; + color: #1e40af; +} + +.priority-medium { + background: #fef3c7; + color: #92400e; +} + +.priority-high { + background: #fee2e2; + color: #991b1b; +} + +.category-badge { + padding: 0.25rem 0.75rem; + border-radius: 20px; + font-size: 0.75rem; + font-weight: 600; + background: var(--accent-color); + color: white; +} + +.todo-actions { + display: flex; + gap: 0.75rem; + justify-content: flex-end; +} + +.complete-btn, .edit-btn, .delete-btn { + padding: 0.75rem 1rem; + border: none; + border-radius: 8px; + cursor: pointer; + font-size: 0.875rem; + font-weight: 500; + transition: all 0.3s ease; + display: flex; + align-items: center; + gap: 0.5rem; +} + +.complete-btn { + background: var(--success-color); + color: white; +} + +.complete-btn:hover { + background: #059669; + transform: translateY(-2px); +} + +.edit-btn { + background: var(--warning-color); + color: white; +} + +.edit-btn:hover { + background: #d97706; + transform: translateY(-2px); +} + +.delete-btn { + background: var(--danger-color); + color: white; +} + +.delete-btn:hover { + background: #dc2626; + transform: translateY(-2px); +} + +.empty-state { + text-align: center; + padding: 3rem; + color: rgba(255, 255, 255, 0.8); +} + +.empty-state i { + font-size: 3rem; + margin-bottom: 1rem; + opacity: 0.5; +} + +@media (max-width: 768px) { + .container { + margin: 1rem; + } + + .input-row { + grid-template-columns: 1fr; + gap: 1rem; + } + + .stats-section { + grid-template-columns: 1fr; + } + + .todo-meta { + flex-direction: column; + gap: 0.5rem; + } + + .todo-actions { + flex-direction: column; + } + + .filter-buttons { + justify-content: center; + } +} diff --git a/styles.css b/styles.css new file mode 100644 index 0000000..dedded6 --- /dev/null +++ b/styles.css @@ -0,0 +1,367 @@ +* { + margin: 0; + padding: 0; + box-sizing: border-box; +} + +body { + font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; + background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); + min-height: 100vh; + color: #333; +} + +.container { + max-width: 1200px; + margin: 0 auto; + padding: 20px; +} + +header { + text-align: center; + margin-bottom: 30px; + color: white; +} + +header h1 { + font-size: 2.5rem; + font-weight: 700; + margin-bottom: 10px; + text-shadow: 0 2px 4px rgba(0,0,0,0.3); +} + +header p { + font-size: 1.1rem; + opacity: 0.9; + font-weight: 300; +} + +.game-controls { + display: flex; + justify-content: center; + align-items: center; + gap: 20px; + margin-bottom: 30px; + flex-wrap: wrap; +} + +.btn { + padding: 12px 24px; + border: none; + border-radius: 8px; + font-size: 1rem; + font-weight: 500; + cursor: pointer; + transition: all 0.3s ease; + text-transform: uppercase; + letter-spacing: 0.5px; +} + +.btn-primary { + background: linear-gradient(45deg, #ff6b6b, #ee5a24); + color: white; + box-shadow: 0 4px 15px rgba(255, 107, 107, 0.4); +} + +.btn-primary:hover { + transform: translateY(-2px); + box-shadow: 0 6px 20px rgba(255, 107, 107, 0.6); +} + +.btn-secondary { + background: linear-gradient(45deg, #4ecdc4, #44a08d); + color: white; + box-shadow: 0 4px 15px rgba(78, 205, 196, 0.4); +} + +.btn-secondary:hover { + transform: translateY(-2px); + box-shadow: 0 6px 20px rgba(78, 205, 196, 0.6); +} + +.btn-success { + background: linear-gradient(45deg, #2ecc71, #27ae60); + color: white; + box-shadow: 0 4px 15px rgba(46, 204, 113, 0.4); +} + +.btn-success:hover { + transform: translateY(-2px); + box-shadow: 0 6px 20px rgba(46, 204, 113, 0.6); +} + +.score-display { + display: flex; + gap: 20px; + color: white; + font-weight: 600; + font-size: 1.1rem; +} + +.game-area { + display: grid; + grid-template-columns: 2fr 1fr; + gap: 30px; + margin-bottom: 30px; +} + +.linked-list-visualization { + background: rgba(255, 255, 255, 0.95); + border-radius: 16px; + padding: 30px; + box-shadow: 0 8px 32px rgba(0, 0, 0, 0.1); + backdrop-filter: blur(10px); + min-height: 400px; + display: flex; + align-items: center; + justify-content: center; +} + +.linked-list-container { + display: flex; + align-items: center; + gap: 15px; + flex-wrap: wrap; + justify-content: center; +} + +.node { + display: flex; + align-items: center; + background: linear-gradient(45deg, #667eea, #764ba2); + color: white; + padding: 15px 20px; + border-radius: 12px; + font-weight: 600; + font-size: 1.1rem; + box-shadow: 0 4px 15px rgba(102, 126, 234, 0.3); + position: relative; + transition: all 0.3s ease; +} + +.node:hover { + transform: scale(1.05); + box-shadow: 0 6px 20px rgba(102, 126, 234, 0.4); +} + +.arrow { + font-size: 1.5rem; + color: #667eea; + font-weight: bold; +} + +.null-pointer { + color: #e74c3c; + font-weight: bold; + font-size: 1.2rem; +} + +.game-panel { + display: flex; + flex-direction: column; + gap: 20px; +} + +.operation-panel, .input-panel, .feedback-panel { + background: rgba(255, 255, 255, 0.95); + border-radius: 16px; + padding: 20px; + box-shadow: 0 8px 32px rgba(0, 0, 0, 0.1); + backdrop-filter: blur(10px); +} + +.operation-panel h3, .input-panel h3, .feedback-panel h3 { + margin-bottom: 15px; + color: #333; + font-weight: 600; +} + +.operation-buttons { + display: grid; + grid-template-columns: 1fr 1fr; + gap: 10px; +} + +.op-btn { + padding: 12px 16px; + border: 2px solid #667eea; + background: white; + color: #667eea; + border-radius: 8px; + cursor: pointer; + transition: all 0.3s ease; + font-weight: 500; +} + +.op-btn:hover, .op-btn.active { + background: #667eea; + color: white; + transform: translateY(-2px); +} + +.op-btn:disabled { + opacity: 0.5; + cursor: not-allowed; + transform: none; +} + +.input-group { + display: flex; + gap: 10px; +} + +.input-group input { + flex: 1; + padding: 12px; + border: 2px solid #ddd; + border-radius: 8px; + font-size: 1rem; + transition: border-color 0.3s ease; +} + +.input-group input:focus { + outline: none; + border-color: #667eea; +} + +.feedback-text { + min-height: 60px; + padding: 15px; + border-radius: 8px; + font-weight: 500; +} + +.feedback-text.success { + background: #d4edda; + color: #155724; + border: 1px solid #c3e6cb; +} + +.feedback-text.error { + background: #f8d7da; + color: #721c24; + border: 1px solid #f5c6cb; +} + +.feedback-text.info { + background: #d1ecf1; + color: #0c5460; + border: 1px solid #bee5eb; +} + +.tutorial-modal { + display: none; + position: fixed; + z-index: 1000; + left: 0; + top: 0; + width: 100%; + height: 100%; + background-color: rgba(0, 0, 0, 0.5); + backdrop-filter: blur(5px); +} + +.modal-content { + background-color: white; + margin: 5% auto; + padding: 30px; + border-radius: 16px; + width: 90%; + max-width: 600px; + max-height: 80vh; + overflow-y: auto; + box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3); + position: relative; +} + +.close { + color: #aaa; + float: right; + font-size: 28px; + font-weight: bold; + cursor: pointer; + position: absolute; + right: 20px; + top: 20px; +} + +.close:hover { + color: #000; +} + +.tutorial-content h3 { + color: #667eea; + margin: 20px 0 10px 0; + font-size: 1.2rem; +} + +.tutorial-content ul { + margin-left: 20px; + margin-bottom: 15px; +} + +.tutorial-content li { + margin-bottom: 5px; +} + +.tutorial-content p { + line-height: 1.6; + margin-bottom: 15px; +} + +/* Responsive Design */ +@media (max-width: 768px) { + .game-area { + grid-template-columns: 1fr; + } + + .game-controls { + flex-direction: column; + gap: 15px; + } + + .score-display { + flex-direction: column; + gap: 10px; + text-align: center; + } + + .operation-buttons { + grid-template-columns: 1fr; + } + + .input-group { + flex-direction: column; + } + + header h1 { + font-size: 2rem; + } + + .container { + padding: 15px; + } +} + +/* Animation for nodes */ +@keyframes nodeAppear { + from { + opacity: 0; + transform: scale(0.8); + } + to { + opacity: 1; + transform: scale(1); + } +} + +.node { + animation: nodeAppear 0.5s ease-out; +} + +/* Highlight effect for active operations */ +.highlight { + background: linear-gradient(45deg, #f39c12, #e67e22) !important; + transform: scale(1.1); + box-shadow: 0 8px 25px rgba(243, 156, 18, 0.5) !important; +}