Spaces:
Running
Running
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>ElectroCatalog - Electrical Components Inventory</title> | |
| <script src="https://cdn.tailwindcss.com"></script> | |
| <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css"> | |
| <style> | |
| /* Custom styles that can't be done with Tailwind */ | |
| .product-card:hover .product-actions { | |
| opacity: 1; | |
| } | |
| .gradient-bg { | |
| background: linear-gradient(135deg, var(--gradient-start), var(--gradient-end)); | |
| } | |
| /* Animation for modal */ | |
| @keyframes fadeIn { | |
| from { opacity: 0; transform: translateY(20px); } | |
| to { opacity: 1; transform: translateY(0); } | |
| } | |
| .modal-animation { | |
| animation: fadeIn 0.3s ease-out forwards; | |
| } | |
| </style> | |
| </head> | |
| <body class="bg-gray-100 font-sans"> | |
| <!-- Header --> | |
| <header class="bg-blue-600 text-white shadow-lg"> | |
| <div class="container mx-auto px-4 py-4 flex justify-between items-center"> | |
| <div class="flex items-center space-x-2"> | |
| <i class="fas fa-bolt text-2xl"></i> | |
| <h1 class="text-2xl font-bold">ElectroCatalog</h1> | |
| </div> | |
| <button id="add-product-btn" class="bg-white text-blue-600 px-4 py-2 rounded-lg font-medium hover:bg-blue-50 transition"> | |
| <i class="fas fa-plus mr-2"></i>Add Product | |
| </button> | |
| </div> | |
| </header> | |
| <!-- Main Content --> | |
| <main class="container mx-auto px-4 py-8"> | |
| <!-- Search and Filter Section --> | |
| <div class="bg-white rounded-lg shadow-md p-6 mb-8"> | |
| <div class="flex flex-col md:flex-row md:items-center md:justify-between gap-4"> | |
| <div class="relative flex-grow"> | |
| <input type="text" id="search-input" placeholder="Search products..." | |
| class="w-full pl-10 pr-4 py-2 border rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500"> | |
| <i class="fas fa-search absolute left-3 top-3 text-gray-400"></i> | |
| </div> | |
| <div class="flex flex-col sm:flex-row gap-3"> | |
| <select id="category-filter" class="px-4 py-2 border rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500"> | |
| <option value="">All Categories</option> | |
| <option value="cables">Cables</option> | |
| <option value="components">Components</option> | |
| <option value="sensors">Sensors</option> | |
| </select> | |
| <select id="box-filter" class="px-4 py-2 border rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500"> | |
| <option value="">All Boxes</option> | |
| <!-- Box options will be populated by JavaScript --> | |
| </select> | |
| <button id="reset-filters" class="px-4 py-2 bg-gray-200 rounded-lg hover:bg-gray-300 transition"> | |
| <i class="fas fa-filter-circle-xmark mr-2"></i>Reset | |
| </button> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Categories Navigation --> | |
| <div class="flex overflow-x-auto mb-8 pb-2 scrollbar-hide"> | |
| <button class="category-btn px-6 py-2 mx-1 rounded-full bg-white shadow hover:bg-blue-50 transition whitespace-nowrap" data-category="all"> | |
| All Products | |
| </button> | |
| <button class="category-btn px-6 py-2 mx-1 rounded-full bg-white shadow hover:bg-blue-50 transition whitespace-nowrap" data-category="cables"> | |
| <i class="fas fa-ethernet mr-2"></i>Cables | |
| </button> | |
| <button class="category-btn px-6 py-2 mx-1 rounded-full bg-white shadow hover:bg-blue-50 transition whitespace-nowrap" data-category="components"> | |
| <i class="fas fa-microchip mr-2"></i>Components | |
| </button> | |
| <button class="category-btn px-6 py-2 mx-1 rounded-full bg-white shadow hover:bg-blue-50 transition whitespace-nowrap" data-category="sensors"> | |
| <i class="fas fa-temperature-three-quarters mr-2"></i>Sensors | |
| </button> | |
| </div> | |
| <!-- Products Grid --> | |
| <div id="products-container" class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-6"> | |
| <!-- Products will be loaded here by JavaScript --> | |
| </div> | |
| <!-- Empty State --> | |
| <div id="empty-state" class="hidden text-center py-12"> | |
| <i class="fas fa-box-open text-5xl text-gray-300 mb-4"></i> | |
| <h3 class="text-xl font-medium text-gray-500">No products found</h3> | |
| <p class="text-gray-400 mt-2">Try adjusting your search or filters</p> | |
| <button id="add-first-product" class="mt-4 px-6 py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700 transition"> | |
| <i class="fas fa-plus mr-2"></i>Add Your First Product | |
| </button> | |
| </div> | |
| </main> | |
| <!-- Add/Edit Product Modal --> | |
| <div id="product-modal" class="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50 hidden"> | |
| <div class="bg-white rounded-lg shadow-xl w-full max-w-md mx-4 modal-animation"> | |
| <div class="flex justify-between items-center border-b p-4"> | |
| <h3 class="text-lg font-semibold" id="modal-title">Add New Product</h3> | |
| <button id="close-modal" class="text-gray-500 hover:text-gray-700"> | |
| <i class="fas fa-times"></i> | |
| </button> | |
| </div> | |
| <form id="product-form" class="p-6"> | |
| <input type="hidden" id="product-id"> | |
| <!-- Preview Image --> | |
| <div class="mb-6"> | |
| <div id="image-preview" class="w-full h-48 rounded-lg bg-gray-100 flex items-center justify-center overflow-hidden mb-2"> | |
| <span class="text-gray-400">Product Image</span> | |
| </div> | |
| <input type="file" id="product-image" accept="image/*" class="hidden"> | |
| <button type="button" id="upload-btn" class="w-full py-2 bg-gray-100 rounded-lg hover:bg-gray-200 transition"> | |
| <i class="fas fa-upload mr-2"></i>Upload Image | |
| </button> | |
| </div> | |
| <!-- Form Fields --> | |
| <div class="space-y-4"> | |
| <div> | |
| <label for="product-name" class="block text-sm font-medium text-gray-700 mb-1">Product Name</label> | |
| <input type="text" id="product-name" required | |
| class="w-full px-4 py-2 border rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500"> | |
| </div> | |
| <div> | |
| <label for="product-category" class="block text-sm font-medium text-gray-700 mb-1">Category</label> | |
| <select id="product-category" required | |
| class="w-full px-4 py-2 border rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500"> | |
| <option value="">Select a category</option> | |
| <option value="cables">Cables</option> | |
| <option value="components">Components</option> | |
| <option value="sensors">Sensors</option> | |
| </select> | |
| </div> | |
| <div> | |
| <label for="product-description" class="block text-sm font-medium text-gray-700 mb-1">Description</label> | |
| <textarea id="product-description" rows="3" | |
| class="w-full px-4 py-2 border rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500"></textarea> | |
| </div> | |
| <div class="grid grid-cols-2 gap-4"> | |
| <div> | |
| <label for="product-quantity" class="block text-sm font-medium text-gray-700 mb-1">Quantity</label> | |
| <input type="number" id="product-quantity" min="0" required | |
| class="w-full px-4 py-2 border rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500"> | |
| </div> | |
| <div> | |
| <label for="product-box" class="block text-sm font-medium text-gray-700 mb-1">Box Number</label> | |
| <input type="text" id="product-box" | |
| class="w-full px-4 py-2 border rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500"> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Form Actions --> | |
| <div class="flex justify-end space-x-3 mt-6 pt-4 border-t"> | |
| <button type="button" id="cancel-btn" class="px-4 py-2 bg-gray-200 rounded-lg hover:bg-gray-300 transition"> | |
| Cancel | |
| </button> | |
| <button type="submit" class="px-6 py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700 transition"> | |
| Save Product | |
| </button> | |
| </div> | |
| </form> | |
| </div> | |
| </div> | |
| <!-- Quantity Adjustment Modal --> | |
| <div id="quantity-modal" class="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50 hidden"> | |
| <div class="bg-white rounded-lg shadow-xl w-full max-w-sm mx-4 modal-animation"> | |
| <div class="flex justify-between items-center border-b p-4"> | |
| <h3 class="text-lg font-semibold">Adjust Quantity</h3> | |
| <button id="close-qty-modal" class="text-gray-500 hover:text-gray-700"> | |
| <i class="fas fa-times"></i> | |
| </button> | |
| </div> | |
| <div class="p-6"> | |
| <div class="flex items-center justify-between mb-6"> | |
| <button id="decrease-qty" class="w-12 h-12 rounded-full bg-red-100 text-red-600 hover:bg-red-200 transition flex items-center justify-center"> | |
| <i class="fas fa-minus"></i> | |
| </button> | |
| <div class="text-center"> | |
| <div class="text-3xl font-bold" id="current-qty">0</div> | |
| <div class="text-sm text-gray-500">Current Quantity</div> | |
| </div> | |
| <button id="increase-qty" class="w-12 h-12 rounded-full bg-green-100 text-green-600 hover:bg-green-200 transition flex items-center justify-center"> | |
| <i class="fas fa-plus"></i> | |
| </button> | |
| </div> | |
| <div class="flex justify-end space-x-3 mt-6 pt-4 border-t"> | |
| <button type="button" id="cancel-qty-btn" class="px-4 py-2 bg-gray-200 rounded-lg hover:bg-gray-300 transition"> | |
| Cancel | |
| </button> | |
| <button type="button" id="save-qty-btn" class="px-6 py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700 transition"> | |
| Save | |
| </button> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <script> | |
| // Database simulation using localStorage | |
| const DB_KEY = 'electroCatalogProducts'; | |
| // Generate a random gradient for product cards | |
| function generateGradient() { | |
| const colors = [ | |
| ['#FF9A9E', '#FAD0C4'], | |
| ['#A18CD1', '#FBC2EB'], | |
| ['#FFC3A0', '#FFAFBD'], | |
| ['#6A11CB', '#2575FC'], | |
| ['#11998E', '#38EF7D'], | |
| ['#FF512F', '#DD2476'], | |
| ['#1A2980', '#26D0CE'], | |
| ['#4776E6', '#8E54E9'] | |
| ]; | |
| const randomColors = colors[Math.floor(Math.random() * colors.length)]; | |
| return { | |
| start: randomColors[0], | |
| end: randomColors[1] | |
| }; | |
| } | |
| // Initialize the app | |
| document.addEventListener('DOMContentLoaded', function() { | |
| // Load products from localStorage | |
| loadProducts(); | |
| // Set up event listeners | |
| setupEventListeners(); | |
| // Update box filter options | |
| updateBoxFilter(); | |
| }); | |
| // Load products from localStorage | |
| function loadProducts() { | |
| const products = getProducts(); | |
| renderProducts(products); | |
| } | |
| // Get all products from localStorage | |
| function getProducts() { | |
| const productsJSON = localStorage.getItem(DB_KEY); | |
| return productsJSON ? JSON.parse(productsJSON) : []; | |
| } | |
| // Save products to localStorage | |
| function saveProducts(products) { | |
| localStorage.setItem(DB_KEY, JSON.stringify(products)); | |
| } | |
| // Render products to the page | |
| function renderProducts(products) { | |
| const container = document.getElementById('products-container'); | |
| const emptyState = document.getElementById('empty-state'); | |
| container.innerHTML = ''; | |
| if (products.length === 0) { | |
| container.classList.add('hidden'); | |
| emptyState.classList.remove('hidden'); | |
| return; | |
| } | |
| container.classList.remove('hidden'); | |
| emptyState.classList.add('hidden'); | |
| products.forEach(product => { | |
| const productCard = createProductCard(product); | |
| container.appendChild(productCard); | |
| }); | |
| } | |
| // Create a product card element | |
| function createProductCard(product) { | |
| const card = document.createElement('div'); | |
| card.className = 'bg-white rounded-lg shadow-md overflow-hidden hover:shadow-lg transition relative'; | |
| card.dataset.id = product.id; | |
| card.dataset.category = product.category; | |
| card.dataset.box = product.box || ''; | |
| // Set gradient background | |
| card.style.setProperty('--gradient-start', product.gradient.start); | |
| card.style.setProperty('--gradient-end', product.gradient.end); | |
| card.innerHTML = ` | |
| <div class="gradient-bg h-32 flex items-center justify-center"> | |
| ${product.image ? | |
| `<img src="${product.image}" alt="${product.name}" class="h-full w-full object-contain p-4">` : | |
| `<i class="fas fa-box-open text-5xl text-white opacity-70"></i>`} | |
| </div> | |
| <div class="p-4"> | |
| <div class="flex justify-between items-start"> | |
| <h3 class="font-semibold text-lg truncate">${product.name}</h3> | |
| <span class="bg-blue-100 text-blue-800 text-xs px-2 py-1 rounded-full">${product.category}</span> | |
| </div> | |
| <p class="text-gray-600 text-sm mt-2 line-clamp-2">${product.description || 'No description'}</p> | |
| <div class="mt-4 flex justify-between items-center"> | |
| <div> | |
| <span class="text-gray-500 text-sm">Qty:</span> | |
| <span class="font-medium ml-1">${product.quantity}</span> | |
| </div> | |
| ${product.box ? | |
| `<div class="flex items-center"> | |
| <i class="fas fa-box text-gray-500 mr-1"></i> | |
| <span class="text-gray-700">${product.box}</span> | |
| </div>` : ''} | |
| </div> | |
| </div> | |
| <div class="product-actions absolute top-2 right-2 opacity-0 transition-opacity duration-200"> | |
| <button class="edit-btn bg-white p-2 rounded-full shadow hover:bg-blue-50 text-blue-600 mr-1" title="Edit"> | |
| <i class="fas fa-pen"></i> | |
| </button> | |
| <button class="qty-btn bg-white p-2 rounded-full shadow hover:bg-blue-50 text-green-600" title="Adjust Quantity"> | |
| <i class="fas fa-calculator"></i> | |
| </button> | |
| </div> | |
| `; | |
| // Add event listeners to action buttons | |
| card.querySelector('.edit-btn').addEventListener('click', () => openEditModal(product.id)); | |
| card.querySelector('.qty-btn').addEventListener('click', () => openQuantityModal(product.id)); | |
| return card; | |
| } | |
| // Set up all event listeners | |
| function setupEventListeners() { | |
| // Add product button | |
| document.getElementById('add-product-btn').addEventListener('click', openAddModal); | |
| document.getElementById('add-first-product').addEventListener('click', openAddModal); | |
| // Modal close buttons | |
| document.getElementById('close-modal').addEventListener('click', closeModal); | |
| document.getElementById('cancel-btn').addEventListener('click', closeModal); | |
| document.getElementById('close-qty-modal').addEventListener('click', closeQuantityModal); | |
| document.getElementById('cancel-qty-btn').addEventListener('click', closeQuantityModal); | |
| // Image upload | |
| document.getElementById('upload-btn').addEventListener('click', () => { | |
| document.getElementById('product-image').click(); | |
| }); | |
| document.getElementById('product-image').addEventListener('change', function(e) { | |
| const file = e.target.files[0]; | |
| if (file) { | |
| const reader = new FileReader(); | |
| reader.onload = function(event) { | |
| document.getElementById('image-preview').innerHTML = | |
| `<img src="${event.target.result}" class="w-full h-full object-contain" alt="Preview">`; | |
| }; | |
| reader.readAsDataURL(file); | |
| } | |
| }); | |
| // Product form submission | |
| document.getElementById('product-form').addEventListener('submit', handleFormSubmit); | |
| // Quantity adjustment | |
| document.getElementById('increase-qty').addEventListener('click', () => adjustQuantity(1)); | |
| document.getElementById('decrease-qty').addEventListener('click', () => adjustQuantity(-1)); | |
| document.getElementById('save-qty-btn').addEventListener('click', saveQuantity); | |
| // Search and filter | |
| document.getElementById('search-input').addEventListener('input', filterProducts); | |
| document.getElementById('category-filter').addEventListener('change', filterProducts); | |
| document.getElementById('box-filter').addEventListener('change', filterProducts); | |
| document.getElementById('reset-filters').addEventListener('click', resetFilters); | |
| // Category buttons | |
| document.querySelectorAll('.category-btn').forEach(btn => { | |
| btn.addEventListener('click', function() { | |
| const category = this.dataset.category; | |
| filterByCategory(category); | |
| }); | |
| }); | |
| } | |
| // Open modal to add new product | |
| function openAddModal() { | |
| document.getElementById('modal-title').textContent = 'Add New Product'; | |
| document.getElementById('product-form').reset(); | |
| document.getElementById('product-id').value = ''; | |
| document.getElementById('image-preview').innerHTML = '<span class="text-gray-400">Product Image</span>'; | |
| document.getElementById('product-modal').classList.remove('hidden'); | |
| } | |
| // Open modal to edit product | |
| function openEditModal(productId) { | |
| const products = getProducts(); | |
| const product = products.find(p => p.id === productId); | |
| if (product) { | |
| document.getElementById('modal-title').textContent = 'Edit Product'; | |
| document.getElementById('product-id').value = product.id; | |
| document.getElementById('product-name').value = product.name; | |
| document.getElementById('product-category').value = product.category; | |
| document.getElementById('product-description').value = product.description || ''; | |
| document.getElementById('product-quantity').value = product.quantity; | |
| document.getElementById('product-box').value = product.box || ''; | |
| // Set image preview if exists | |
| const imagePreview = document.getElementById('image-preview'); | |
| if (product.image) { | |
| imagePreview.innerHTML = `<img src="${product.image}" class="w-full h-full object-contain" alt="Preview">`; | |
| } else { | |
| imagePreview.innerHTML = '<span class="text-gray-400">Product Image</span>'; | |
| } | |
| document.getElementById('product-modal').classList.remove('hidden'); | |
| } | |
| } | |
| // Close the product modal | |
| function closeModal() { | |
| document.getElementById('product-modal').classList.add('hidden'); | |
| } | |
| // Handle form submission (add/edit product) | |
| function handleFormSubmit(e) { | |
| e.preventDefault(); | |
| const productId = document.getElementById('product-id').value; | |
| const name = document.getElementById('product-name').value.trim(); | |
| const category = document.getElementById('product-category').value; | |
| const description = document.getElementById('product-description').value.trim(); | |
| const quantity = parseInt(document.getElementById('product-quantity').value); | |
| const box = document.getElementById('product-box').value.trim(); | |
| // Get image data if uploaded | |
| const imageInput = document.getElementById('product-image'); | |
| let image = ''; | |
| if (imageInput.files.length > 0) { | |
| const file = imageInput.files[0]; | |
| const reader = new FileReader(); | |
| reader.onload = function(event) { | |
| image = event.target.result; | |
| saveProductData(productId, name, category, description, quantity, box, image); | |
| }; | |
| reader.readAsDataURL(file); | |
| } else { | |
| // If editing and no new image selected, keep existing image | |
| if (productId) { | |
| const products = getProducts(); | |
| const existingProduct = products.find(p => p.id === productId); | |
| image = existingProduct ? existingProduct.image : ''; | |
| } | |
| saveProductData(productId, name, category, description, quantity, box, image); | |
| } | |
| } | |
| // Save product data to database | |
| function saveProductData(id, name, category, description, quantity, box, image) { | |
| const products = getProducts(); | |
| if (id) { | |
| // Update existing product | |
| const index = products.findIndex(p => p.id === id); | |
| if (index !== -1) { | |
| products[index] = { | |
| ...products[index], | |
| name, | |
| category, | |
| description, | |
| quantity, | |
| box, | |
| image: image || products[index].image | |
| }; | |
| } | |
| } else { | |
| // Add new product | |
| const newProduct = { | |
| id: Date.now().toString(), | |
| name, | |
| category, | |
| description, | |
| quantity, | |
| box, | |
| image, | |
| gradient: generateGradient() | |
| }; | |
| products.push(newProduct); | |
| } | |
| saveProducts(products); | |
| renderProducts(products); | |
| updateBoxFilter(); | |
| closeModal(); | |
| } | |
| // Open quantity adjustment modal | |
| function openQuantityModal(productId) { | |
| const products = getProducts(); | |
| const product = products.find(p => p.id === productId); | |
| if (product) { | |
| document.getElementById('quantity-modal').dataset.productId = productId; | |
| document.getElementById('current-qty').textContent = product.quantity; | |
| document.getElementById('quantity-modal').classList.remove('hidden'); | |
| } | |
| } | |
| // Close quantity modal | |
| function closeQuantityModal() { | |
| document.getElementById('quantity-modal').classList.add('hidden'); | |
| } | |
| // Adjust quantity in the modal | |
| function adjustQuantity(change) { | |
| const qtyElement = document.getElementById('current-qty'); | |
| let currentQty = parseInt(qtyElement.textContent); | |
| currentQty += change; | |
| // Don't allow negative quantities | |
| if (currentQty < 0) currentQty = 0; | |
| qtyElement.textContent = currentQty; | |
| } | |
| // Save the adjusted quantity | |
| function saveQuantity() { | |
| const productId = document.getElementById('quantity-modal').dataset.productId; | |
| const newQuantity = parseInt(document.getElementById('current-qty').textContent); | |
| const products = getProducts(); | |
| const product = products.find(p => p.id === productId); | |
| if (product) { | |
| product.quantity = newQuantity; | |
| saveProducts(products); | |
| renderProducts(products); | |
| } | |
| closeQuantityModal(); | |
| } | |
| // Filter products by search and filters | |
| function filterProducts() { | |
| const searchTerm = document.getElementById('search-input').value.toLowerCase(); | |
| const category = document.getElementById('category-filter').value; | |
| const box = document.getElementById('box-filter').value; | |
| const products = getProducts(); | |
| let filtered = [...products]; | |
| // Apply search filter | |
| if (searchTerm) { | |
| filtered = filtered.filter(product => | |
| product.name.toLowerCase().includes(searchTerm) || | |
| (product.description && product.description.toLowerCase().includes(searchTerm)) | |
| ); | |
| } | |
| // Apply category filter | |
| if (category) { | |
| filtered = filtered.filter(product => product.category === category); | |
| } | |
| // Apply box filter | |
| if (box) { | |
| filtered = filtered.filter(product => product.box === box); | |
| } | |
| renderProducts(filtered); | |
| } | |
| // Filter by category from buttons | |
| function filterByCategory(category) { | |
| document.getElementById('category-filter').value = category === 'all' ? '' : category; | |
| filterProducts(); | |
| } | |
| // Reset all filters | |
| function resetFilters() { | |
| document.getElementById('search-input').value = ''; | |
| document.getElementById('category-filter').value = ''; | |
| document.getElementById('box-filter').value = ''; | |
| filterProducts(); | |
| } | |
| // Update box filter options based on existing products | |
| function updateBoxFilter() { | |
| const products = getProducts(); | |
| const boxes = [...new Set(products.map(p => p.box).filter(box => box))].sort(); | |
| const boxFilter = document.getElementById('box-filter'); | |
| // Keep the first option (All Boxes) | |
| while (boxFilter.options.length > 1) { | |
| boxFilter.remove(1); | |
| } | |
| // Add box options | |
| boxes.forEach(box => { | |
| const option = document.createElement('option'); | |
| option.value = box; | |
| option.textContent = box; | |
| boxFilter.appendChild(option); | |
| }); | |
| } | |
| </script> | |
| <p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - 🧬 <a href="https://enzostvs-deepsite.hf.space?remix=mukoshi/katalog-2-better" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body> | |
| </html> |