Remove all button
This commit is contained in:
		@@ -96,6 +96,38 @@ def delete_hero_photo():
 | 
				
			|||||||
        return {"status": "ok"}
 | 
					        return {"status": "ok"}
 | 
				
			||||||
    return {"error": "File not found"}, 404
 | 
					    return {"error": "File not found"}, 404
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@app.route("/api/gallery/delete_all", methods=["POST"])
 | 
				
			||||||
 | 
					def delete_all_gallery_photos():
 | 
				
			||||||
 | 
					    """Delete all gallery photos from disk and YAML."""
 | 
				
			||||||
 | 
					    gallery_dir = PHOTOS_DIR / "gallery"
 | 
				
			||||||
 | 
					    deleted = 0
 | 
				
			||||||
 | 
					    # Remove all files in gallery folder
 | 
				
			||||||
 | 
					    for file in gallery_dir.glob("*"):
 | 
				
			||||||
 | 
					        if file.is_file():
 | 
				
			||||||
 | 
					            file.unlink()
 | 
				
			||||||
 | 
					            deleted += 1
 | 
				
			||||||
 | 
					    # Clear YAML gallery images
 | 
				
			||||||
 | 
					    data = load_yaml(GALLERY_YAML)
 | 
				
			||||||
 | 
					    data["gallery"]["images"] = []
 | 
				
			||||||
 | 
					    save_yaml(data, GALLERY_YAML)
 | 
				
			||||||
 | 
					    return jsonify({"status": "ok", "deleted": deleted})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@app.route("/api/hero/delete_all", methods=["POST"])
 | 
				
			||||||
 | 
					def delete_all_hero_photos():
 | 
				
			||||||
 | 
					    """Delete all hero photos from disk and YAML."""
 | 
				
			||||||
 | 
					    hero_dir = PHOTOS_DIR / "hero"
 | 
				
			||||||
 | 
					    deleted = 0
 | 
				
			||||||
 | 
					    # Remove all files in hero folder
 | 
				
			||||||
 | 
					    for file in hero_dir.glob("*"):
 | 
				
			||||||
 | 
					        if file.is_file():
 | 
				
			||||||
 | 
					            file.unlink()
 | 
				
			||||||
 | 
					            deleted += 1
 | 
				
			||||||
 | 
					    # Clear YAML hero images
 | 
				
			||||||
 | 
					    data = load_yaml(GALLERY_YAML)
 | 
				
			||||||
 | 
					    data["hero"]["images"] = []
 | 
				
			||||||
 | 
					    save_yaml(data, GALLERY_YAML)
 | 
				
			||||||
 | 
					    return jsonify({"status": "ok", "deleted": deleted})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@app.route("/photos/<section>/<path:filename>")
 | 
					@app.route("/photos/<section>/<path:filename>")
 | 
				
			||||||
def photos(section, filename):
 | 
					def photos(section, filename):
 | 
				
			||||||
    """Serve uploaded photos from disk."""
 | 
					    """Serve uploaded photos from disk."""
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -3,8 +3,6 @@
 | 
				
			|||||||
<head>
 | 
					<head>
 | 
				
			||||||
  <meta charset="UTF-8">
 | 
					  <meta charset="UTF-8">
 | 
				
			||||||
  <title>Photo WebUI</title>
 | 
					  <title>Photo WebUI</title>
 | 
				
			||||||
 | 
					 | 
				
			||||||
  <!-- Link to your CSS in the package -->
 | 
					 | 
				
			||||||
  <link rel="stylesheet" href="{{ url_for('static', filename='style/style.css') }}">
 | 
					  <link rel="stylesheet" href="{{ url_for('static', filename='style/style.css') }}">
 | 
				
			||||||
</head>
 | 
					</head>
 | 
				
			||||||
<body>
 | 
					<body>
 | 
				
			||||||
@@ -12,10 +10,10 @@
 | 
				
			|||||||
  <div class="nav-bar">
 | 
					  <div class="nav-bar">
 | 
				
			||||||
    <div class="content-inner nav">
 | 
					    <div class="content-inner nav">
 | 
				
			||||||
      <div class="nav-cta">
 | 
					      <div class="nav-cta">
 | 
				
			||||||
				  	<div class="arrow">
 | 
					        <div class="arrow">→</div>
 | 
				
			||||||
             →
 | 
					        <a class="button" href="#" target="_blank">
 | 
				
			||||||
            </div>
 | 
					          <span id="step">🚀 Build !<i class="fa-solid fa-envelope"></i></span>
 | 
				
			||||||
              <a class="button" href="#" target="_blank"><span id="step">🚀 Build !<i class="fa-solid fa-envelope"></i></span></a>
 | 
					        </a>
 | 
				
			||||||
      </div>
 | 
					      </div>
 | 
				
			||||||
      <input type="checkbox" id="nav-check">
 | 
					      <input type="checkbox" id="nav-check">
 | 
				
			||||||
      <div class="nav-header">
 | 
					      <div class="nav-header">
 | 
				
			||||||
@@ -23,7 +21,6 @@
 | 
				
			|||||||
          <img src="{{ url_for('static', filename='img/logo.svg') }}">
 | 
					          <img src="{{ url_for('static', filename='img/logo.svg') }}">
 | 
				
			||||||
        </div>
 | 
					        </div>
 | 
				
			||||||
      </div>
 | 
					      </div>
 | 
				
			||||||
 | 
					 | 
				
			||||||
      <div class="nav-btn">
 | 
					      <div class="nav-btn">
 | 
				
			||||||
        <label for="nav-check">
 | 
					        <label for="nav-check">
 | 
				
			||||||
          <span></span>
 | 
					          <span></span>
 | 
				
			||||||
@@ -31,16 +28,13 @@
 | 
				
			|||||||
          <span></span>
 | 
					          <span></span>
 | 
				
			||||||
        </label>
 | 
					        </label>
 | 
				
			||||||
      </div>
 | 
					      </div>
 | 
				
			||||||
			  
 | 
					 | 
				
			||||||
      <div class="nav-links">
 | 
					      <div class="nav-links">
 | 
				
			||||||
        <ul class="nav-list">
 | 
					        <ul class="nav-list">
 | 
				
			||||||
          <li class="nav-item appear2"><a href="#">Site info</a>
 | 
					          <li class="nav-item appear2"><a href="#">Site info</a>
 | 
				
			||||||
          <li class="nav-item appear2"><a href="#qui-suis-je">Theme info</a>
 | 
					          <li class="nav-item appear2"><a href="#qui-suis-je">Theme info</a>
 | 
				
			||||||
          <li class="nav-item appear2"><a href="#mariages">Gallery</a>
 | 
					          <li class="nav-item appear2"><a href="#mariages">Gallery</a>
 | 
				
			||||||
        </ul>
 | 
					        </ul>
 | 
				
			||||||
				  
 | 
					 | 
				
			||||||
      </div>
 | 
					      </div>
 | 
				
			||||||
 | 
					 | 
				
			||||||
    </div>
 | 
					    </div>
 | 
				
			||||||
  </div>
 | 
					  </div>
 | 
				
			||||||
  <!-- Toast container for notifications -->
 | 
					  <!-- Toast container for notifications -->
 | 
				
			||||||
@@ -53,9 +47,12 @@
 | 
				
			|||||||
    <div class="upload-section">
 | 
					    <div class="upload-section">
 | 
				
			||||||
      <h2>Title Carrousel</h2>
 | 
					      <h2>Title Carrousel</h2>
 | 
				
			||||||
      <p> Select photos to display in the Title Carrousel</p>
 | 
					      <p> Select photos to display in the Title Carrousel</p>
 | 
				
			||||||
      <label for="upload-hero" class="custom-upload-btn">
 | 
					      <div class="upload-actions-row">
 | 
				
			||||||
 | 
					        <label for="upload-hero" class="up-btn">
 | 
				
			||||||
          📸 Upload photos
 | 
					          📸 Upload photos
 | 
				
			||||||
        </label>
 | 
					        </label>
 | 
				
			||||||
 | 
					        <button id="remove-all-hero" class="up-btn">🗑 Remove All</button>
 | 
				
			||||||
 | 
					      </div>
 | 
				
			||||||
      <input type="file" id="upload-hero" accept=".png,.jpg,.jpeg,.webp" multiple hidden>
 | 
					      <input type="file" id="upload-hero" accept=".png,.jpg,.jpeg,.webp" multiple hidden>
 | 
				
			||||||
      <div id="hero"></div>
 | 
					      <div id="hero"></div>
 | 
				
			||||||
    </div>
 | 
					    </div>
 | 
				
			||||||
@@ -64,14 +61,16 @@
 | 
				
			|||||||
    <div class="upload-section">
 | 
					    <div class="upload-section">
 | 
				
			||||||
      <h2>Gallery</h2>
 | 
					      <h2>Gallery</h2>
 | 
				
			||||||
      <p> Select and tags photos to display in the Gallery</p>
 | 
					      <p> Select and tags photos to display in the Gallery</p>
 | 
				
			||||||
      <label for="upload-gallery" class="custom-upload-btn">
 | 
					      <div class="upload-actions-row">
 | 
				
			||||||
 | 
					        <label for="upload-gallery" class="up-btn">
 | 
				
			||||||
          📸 Upload photos
 | 
					          📸 Upload photos
 | 
				
			||||||
        </label>
 | 
					        </label>
 | 
				
			||||||
 | 
					        <button id="remove-all-gallery" class="up-btn">🗑 Remove All</button>
 | 
				
			||||||
 | 
					      </div>
 | 
				
			||||||
      <input type="file" id="upload-gallery" accept=".png,.jpg,.jpeg,.webp" multiple hidden>
 | 
					      <input type="file" id="upload-gallery" accept=".png,.jpg,.jpeg,.webp" multiple hidden>
 | 
				
			||||||
      <div id="gallery"></div>
 | 
					      <div id="gallery"></div>
 | 
				
			||||||
    </div>
 | 
					    </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    <!-- JS files for rendering, uploading, and actions -->
 | 
					 | 
				
			||||||
    <script src="{{ url_for('static', filename='js/main.js') }}"></script>
 | 
					    <script src="{{ url_for('static', filename='js/main.js') }}"></script>
 | 
				
			||||||
    <script src="{{ url_for('static', filename='js/upload.js') }}"></script>
 | 
					    <script src="{{ url_for('static', filename='js/upload.js') }}"></script>
 | 
				
			||||||
  </div>
 | 
					  </div>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -53,6 +53,12 @@ function renderGallery() {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    renderTags(i, img.tags || []);
 | 
					    renderTags(i, img.tags || []);
 | 
				
			||||||
  });
 | 
					  });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Show/hide Remove All button
 | 
				
			||||||
 | 
					  const removeAllBtn = document.getElementById('remove-all-gallery');
 | 
				
			||||||
 | 
					  if (removeAllBtn) {
 | 
				
			||||||
 | 
					    removeAllBtn.style.display = galleryImages.length > 0 ? 'inline-block' : 'none';
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// --- Render tags for a single image ---
 | 
					// --- Render tags for a single image ---
 | 
				
			||||||
@@ -60,11 +66,9 @@ function renderTags(imgIndex, tags) {
 | 
				
			|||||||
  const tagsDisplay = document.querySelector(`.tags-display[data-index="${imgIndex}"]`);
 | 
					  const tagsDisplay = document.querySelector(`.tags-display[data-index="${imgIndex}"]`);
 | 
				
			||||||
  const inputContainer = document.querySelector(`.tag-input[data-index="${imgIndex}"]`);
 | 
					  const inputContainer = document.querySelector(`.tag-input[data-index="${imgIndex}"]`);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // vider
 | 
					 | 
				
			||||||
  tagsDisplay.innerHTML = '';
 | 
					  tagsDisplay.innerHTML = '';
 | 
				
			||||||
  inputContainer.innerHTML = '';
 | 
					  inputContainer.innerHTML = '';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // --- rendre les tags (en haut) ---
 | 
					 | 
				
			||||||
  tags.forEach(tag => {
 | 
					  tags.forEach(tag => {
 | 
				
			||||||
    const span = document.createElement('span');
 | 
					    const span = document.createElement('span');
 | 
				
			||||||
    span.className = 'tag';
 | 
					    span.className = 'tag';
 | 
				
			||||||
@@ -83,13 +87,11 @@ function renderTags(imgIndex, tags) {
 | 
				
			|||||||
    tagsDisplay.appendChild(span);
 | 
					    tagsDisplay.appendChild(span);
 | 
				
			||||||
  });
 | 
					  });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // --- input (en bas) ---
 | 
					 | 
				
			||||||
  const input = document.createElement('input');
 | 
					  const input = document.createElement('input');
 | 
				
			||||||
  input.type = 'text';
 | 
					  input.type = 'text';
 | 
				
			||||||
  input.placeholder = 'Add tag...';
 | 
					  input.placeholder = 'Add tag...';
 | 
				
			||||||
  inputContainer.appendChild(input);
 | 
					  inputContainer.appendChild(input);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // suggestion box
 | 
					 | 
				
			||||||
  const suggestionBox = document.createElement('ul');
 | 
					  const suggestionBox = document.createElement('ul');
 | 
				
			||||||
  suggestionBox.className = 'suggestions';
 | 
					  suggestionBox.className = 'suggestions';
 | 
				
			||||||
  inputContainer.appendChild(suggestionBox);
 | 
					  inputContainer.appendChild(suggestionBox);
 | 
				
			||||||
@@ -210,11 +212,17 @@ function renderHero() {
 | 
				
			|||||||
        <div class="flex-item flex-end">
 | 
					        <div class="flex-item flex-end">
 | 
				
			||||||
          <button onclick="showDeleteModal('hero', ${i})">🗑 Delete</button>
 | 
					          <button onclick="showDeleteModal('hero', ${i})">🗑 Delete</button>
 | 
				
			||||||
        </div>
 | 
					        </div>
 | 
				
			||||||
 | 
					      </div>
 | 
				
			||||||
    `;
 | 
					    `;
 | 
				
			||||||
    container.appendChild(div);
 | 
					    container.appendChild(div);
 | 
				
			||||||
  });
 | 
					  });
 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Show/hide Remove All button
 | 
				
			||||||
 | 
					  const removeAllBtn = document.getElementById('remove-all-hero');
 | 
				
			||||||
 | 
					  if (removeAllBtn) {
 | 
				
			||||||
 | 
					    removeAllBtn.style.display = heroImages.length > 0 ? 'inline-block' : 'none';
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// --- Save gallery to server ---
 | 
					// --- Save gallery to server ---
 | 
				
			||||||
async function saveGallery() {
 | 
					async function saveGallery() {
 | 
				
			||||||
@@ -273,11 +281,19 @@ function showToast(message, type = "success", duration = 3000) {
 | 
				
			|||||||
  }, duration);
 | 
					  }, duration);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
let pendingDelete = null; // { type: 'gallery'|'hero', index: number }
 | 
					let pendingDelete = null; // { type: 'gallery'|'hero'|'gallery-all'|'hero-all', index: number|null }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// --- Show delete confirmation modal ---
 | 
					// --- Show delete confirmation modal ---
 | 
				
			||||||
function showDeleteModal(type, index) {
 | 
					function showDeleteModal(type, index = null) {
 | 
				
			||||||
  pendingDelete = { type, index };
 | 
					  pendingDelete = { type, index };
 | 
				
			||||||
 | 
					  const modalText = document.getElementById('delete-modal-text');
 | 
				
			||||||
 | 
					  if (type === 'gallery-all') {
 | 
				
			||||||
 | 
					    modalText.textContent = "Are you sure you want to delete ALL gallery images?";
 | 
				
			||||||
 | 
					  } else if (type === 'hero-all') {
 | 
				
			||||||
 | 
					    modalText.textContent = "Are you sure you want to delete ALL hero images?";
 | 
				
			||||||
 | 
					  } else {
 | 
				
			||||||
 | 
					    modalText.textContent = "Are you sure you want to delete this image?";
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
  document.getElementById('delete-modal').style.display = 'flex';
 | 
					  document.getElementById('delete-modal').style.display = 'flex';
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -294,18 +310,14 @@ async function confirmDelete() {
 | 
				
			|||||||
    await actuallyDeleteGalleryImage(pendingDelete.index);
 | 
					    await actuallyDeleteGalleryImage(pendingDelete.index);
 | 
				
			||||||
  } else if (pendingDelete.type === 'hero') {
 | 
					  } else if (pendingDelete.type === 'hero') {
 | 
				
			||||||
    await actuallyDeleteHeroImage(pendingDelete.index);
 | 
					    await actuallyDeleteHeroImage(pendingDelete.index);
 | 
				
			||||||
 | 
					  } else if (pendingDelete.type === 'gallery-all') {
 | 
				
			||||||
 | 
					    await actuallyDeleteAllGalleryImages();
 | 
				
			||||||
 | 
					  } else if (pendingDelete.type === 'hero-all') {
 | 
				
			||||||
 | 
					    await actuallyDeleteAllHeroImages();
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  hideDeleteModal();
 | 
					  hideDeleteModal();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
// --- Modal event listeners ---
 | 
					 | 
				
			||||||
document.addEventListener('DOMContentLoaded', () => {
 | 
					 | 
				
			||||||
  document.getElementById('delete-modal-close').onclick = hideDeleteModal;
 | 
					 | 
				
			||||||
  document.getElementById('delete-modal-cancel').onclick = hideDeleteModal;
 | 
					 | 
				
			||||||
  document.getElementById('delete-modal-confirm').onclick = confirmDelete;
 | 
					 | 
				
			||||||
});
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// --- Actual delete functions ---
 | 
					// --- Actual delete functions ---
 | 
				
			||||||
async function actuallyDeleteGalleryImage(index) {
 | 
					async function actuallyDeleteGalleryImage(index) {
 | 
				
			||||||
  const img = galleryImages[index];
 | 
					  const img = galleryImages[index];
 | 
				
			||||||
@@ -349,14 +361,51 @@ async function actuallyDeleteHeroImage(index) {
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// --- Modal event listeners ---
 | 
					// --- Bulk delete functions ---
 | 
				
			||||||
 | 
					async function actuallyDeleteAllGalleryImages() {
 | 
				
			||||||
 | 
					  try {
 | 
				
			||||||
 | 
					    const res = await fetch('/api/gallery/delete_all', { method: 'POST' });
 | 
				
			||||||
 | 
					    const data = await res.json();
 | 
				
			||||||
 | 
					    if (res.ok) {
 | 
				
			||||||
 | 
					      galleryImages = [];
 | 
				
			||||||
 | 
					      renderGallery();
 | 
				
			||||||
 | 
					      await saveGallery();
 | 
				
			||||||
 | 
					      showToast("✅ All gallery images removed!", "success");
 | 
				
			||||||
 | 
					    } else showToast("Error: " + data.error, "error");
 | 
				
			||||||
 | 
					  } catch(err) {
 | 
				
			||||||
 | 
					    console.error(err);
 | 
				
			||||||
 | 
					    showToast("Server error!", "error");
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					async function actuallyDeleteAllHeroImages() {
 | 
				
			||||||
 | 
					  try {
 | 
				
			||||||
 | 
					    const res = await fetch('/api/hero/delete_all', { method: 'POST' });
 | 
				
			||||||
 | 
					    const data = await res.json();
 | 
				
			||||||
 | 
					    if (res.ok) {
 | 
				
			||||||
 | 
					      heroImages = [];
 | 
				
			||||||
 | 
					      renderHero();
 | 
				
			||||||
 | 
					      await saveHero();
 | 
				
			||||||
 | 
					      showToast("✅ All hero images removed!", "success");
 | 
				
			||||||
 | 
					    } else showToast("Error: " + data.error, "error");
 | 
				
			||||||
 | 
					  } catch(err) {
 | 
				
			||||||
 | 
					    console.error(err);
 | 
				
			||||||
 | 
					    showToast("Server error!", "error");
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// --- Modal event listeners and bulk delete buttons ---
 | 
				
			||||||
document.addEventListener('DOMContentLoaded', () => {
 | 
					document.addEventListener('DOMContentLoaded', () => {
 | 
				
			||||||
  document.getElementById('delete-modal-close').onclick = hideDeleteModal;
 | 
					  document.getElementById('delete-modal-close').onclick = hideDeleteModal;
 | 
				
			||||||
  document.getElementById('delete-modal-cancel').onclick = hideDeleteModal;
 | 
					  document.getElementById('delete-modal-cancel').onclick = hideDeleteModal;
 | 
				
			||||||
  document.getElementById('delete-modal-confirm').onclick = confirmDelete;
 | 
					  document.getElementById('delete-modal-confirm').onclick = confirmDelete;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Bulk delete buttons
 | 
				
			||||||
 | 
					  const removeAllGalleryBtn = document.getElementById('remove-all-gallery');
 | 
				
			||||||
 | 
					  const removeAllHeroBtn = document.getElementById('remove-all-hero');
 | 
				
			||||||
 | 
					  if (removeAllGalleryBtn) removeAllGalleryBtn.onclick = () => showDeleteModal('gallery-all');
 | 
				
			||||||
 | 
					  if (removeAllHeroBtn) removeAllHeroBtn.onclick = () => showDeleteModal('hero-all');
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// --- Initialize ---
 | 
					// --- Initialize ---
 | 
				
			||||||
loadData();
 | 
					loadData();
 | 
				
			||||||
@@ -39,7 +39,6 @@ h1, h2 {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.upload-section label {
 | 
					.upload-section label {
 | 
				
			||||||
  margin-right: 20px;
 | 
					 | 
				
			||||||
  cursor: pointer;
 | 
					  cursor: pointer;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -108,7 +107,7 @@ h1, h2 {
 | 
				
			|||||||
/* Toast notifications */
 | 
					/* Toast notifications */
 | 
				
			||||||
#toast-container {
 | 
					#toast-container {
 | 
				
			||||||
  position: fixed;
 | 
					  position: fixed;
 | 
				
			||||||
  top: 1rem;
 | 
					  bottom: 1rem;
 | 
				
			||||||
  right: 1rem;
 | 
					  right: 1rem;
 | 
				
			||||||
  display: flex;
 | 
					  display: flex;
 | 
				
			||||||
  flex-direction: column;
 | 
					  flex-direction: column;
 | 
				
			||||||
@@ -120,12 +119,13 @@ h1, h2 {
 | 
				
			|||||||
  background: rgba(0,0,0,0.85);
 | 
					  background: rgba(0,0,0,0.85);
 | 
				
			||||||
  color: white;
 | 
					  color: white;
 | 
				
			||||||
  padding: 0.75rem 1.25rem;
 | 
					  padding: 0.75rem 1.25rem;
 | 
				
			||||||
  border-radius: 0.5rem;
 | 
					  border-radius: 30px;
 | 
				
			||||||
  box-shadow: 0 2px 8px rgba(0,0,0,0.3);
 | 
					  box-shadow: 0 2px 8px rgba(0,0,0,0.3);
 | 
				
			||||||
  opacity: 0;
 | 
					  opacity: 0;
 | 
				
			||||||
  transform: translateY(-20px);
 | 
					  transform: translateY(20px);
 | 
				
			||||||
  transition: opacity 0.5s ease, transform 0.5s ease;
 | 
					  transition: opacity 0.5s ease, transform 0.5s ease;
 | 
				
			||||||
  pointer-events: none;
 | 
					  pointer-events: none;
 | 
				
			||||||
 | 
					  backdrop-filter: blur(20px);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.toast.show {
 | 
					.toast.show {
 | 
				
			||||||
@@ -133,7 +133,7 @@ h1, h2 {
 | 
				
			|||||||
  transform: translateY(0);
 | 
					  transform: translateY(0);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.toast.success { background-color: #28a745; }
 | 
					.toast.success { background-color: #28a7468c; }
 | 
				
			||||||
.toast.error { background-color: #dc3545; }
 | 
					.toast.error { background-color: #dc3545; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Tags */
 | 
					/* Tags */
 | 
				
			||||||
@@ -351,7 +351,7 @@ h1, h2 {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Custom upload buttons */
 | 
					/* Custom upload buttons */
 | 
				
			||||||
.custom-upload-btn {
 | 
					.up-btn {
 | 
				
			||||||
  display: inline-block;
 | 
					  display: inline-block;
 | 
				
			||||||
  background: #09A0C1;
 | 
					  background: #09A0C1;
 | 
				
			||||||
  color: #fff;
 | 
					  color: #fff;
 | 
				
			||||||
@@ -363,9 +363,11 @@ h1, h2 {
 | 
				
			|||||||
  transition: all 0.1s ease;
 | 
					  transition: all 0.1s ease;
 | 
				
			||||||
  user-select: none;
 | 
					  user-select: none;
 | 
				
			||||||
  box-shadow: 0 4px 10px rgba(0,0,0,0.25);
 | 
					  box-shadow: 0 4px 10px rgba(0,0,0,0.25);
 | 
				
			||||||
 | 
					  font-size: 14px;
 | 
				
			||||||
 | 
					  border: none;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.custom-upload-btn:hover {
 | 
					.up-btn:hover {
 | 
				
			||||||
  background: #55c3ec;
 | 
					  background: #55c3ec;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -426,3 +428,31 @@ h1, h2 {
 | 
				
			|||||||
.modal-btn.danger:hover {
 | 
					.modal-btn.danger:hover {
 | 
				
			||||||
  background: #d32f2f;
 | 
					  background: #d32f2f;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Add this for horizontal alignment of upload and remove-all buttons */
 | 
				
			||||||
 | 
					.upload-actions-row {
 | 
				
			||||||
 | 
					  display: flex;
 | 
				
			||||||
 | 
					  align-items: center;
 | 
				
			||||||
 | 
					  gap: 16px;
 | 
				
			||||||
 | 
					  margin-bottom: 10px;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Style for Remove All buttons to match upload button look */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#remove-all-hero, #remove-all-gallery {
 | 
				
			||||||
 | 
					   background: rgb(121, 26, 19);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					#remove-all-gallery:hover,
 | 
				
			||||||
 | 
					#remove-all-hero:hover {
 | 
				
			||||||
 | 
					  background: #d32f2f;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Responsive: stack buttons vertically on small screens */
 | 
				
			||||||
 | 
					@media (max-width: 500px) {
 | 
				
			||||||
 | 
					  .upload-actions-row {
 | 
				
			||||||
 | 
					    flex-direction: column;
 | 
				
			||||||
 | 
					    align-items: stretch;
 | 
				
			||||||
 | 
					    gap: 8px;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
		Reference in New Issue
	
	Block a user