webupdate
This commit is contained in:
@@ -69,6 +69,126 @@
|
||||
.stat-item i {
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
/* Skeleton Loading Animation */
|
||||
.skeleton-item {
|
||||
background: #f8fafc;
|
||||
border-radius: 12px;
|
||||
overflow: hidden;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.skeleton-preview {
|
||||
width: 100%;
|
||||
aspect-ratio: 1;
|
||||
background: linear-gradient(
|
||||
90deg,
|
||||
#f0f0f0 25%,
|
||||
#e0e0e0 50%,
|
||||
#f0f0f0 75%
|
||||
);
|
||||
background-size: 200% 100%;
|
||||
animation: skeleton-shimmer 1.5s infinite;
|
||||
}
|
||||
|
||||
.skeleton-info {
|
||||
padding: 12px;
|
||||
}
|
||||
|
||||
.skeleton-name {
|
||||
height: 14px;
|
||||
background: linear-gradient(
|
||||
90deg,
|
||||
#f0f0f0 25%,
|
||||
#e0e0e0 50%,
|
||||
#f0f0f0 75%
|
||||
);
|
||||
background-size: 200% 100%;
|
||||
animation: skeleton-shimmer 1.5s infinite;
|
||||
border-radius: 4px;
|
||||
margin-bottom: 8px;
|
||||
width: 80%;
|
||||
}
|
||||
|
||||
.skeleton-meta {
|
||||
height: 12px;
|
||||
background: linear-gradient(
|
||||
90deg,
|
||||
#f0f0f0 25%,
|
||||
#e0e0e0 50%,
|
||||
#f0f0f0 75%
|
||||
);
|
||||
background-size: 200% 100%;
|
||||
animation: skeleton-shimmer 1.5s infinite;
|
||||
border-radius: 4px;
|
||||
width: 50%;
|
||||
}
|
||||
|
||||
@keyframes skeleton-shimmer {
|
||||
0% {
|
||||
background-position: 200% 0;
|
||||
}
|
||||
100% {
|
||||
background-position: -200% 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Lazy loading image placeholder - instant load, no delay */
|
||||
.media-item .item-preview img {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.media-item .item-preview img.loaded {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.media-item .item-preview {
|
||||
background: #f0f0f0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
/* Loading indicator at bottom */
|
||||
.load-more-indicator {
|
||||
text-align: center;
|
||||
padding: 20px;
|
||||
color: #666;
|
||||
display: none;
|
||||
}
|
||||
|
||||
.load-more-indicator.visible {
|
||||
display: block;
|
||||
}
|
||||
|
||||
/* Fixed toolbar styles when scrolling */
|
||||
.media-library-page {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.media-library-toolbar {
|
||||
background: white;
|
||||
transition: box-shadow 0.2s ease;
|
||||
}
|
||||
|
||||
.media-library-toolbar.fixed-toolbar {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
z-index: 1000;
|
||||
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.15);
|
||||
border-radius: 0 !important;
|
||||
border-top-left-radius: 0 !important;
|
||||
border-top-right-radius: 0 !important;
|
||||
}
|
||||
|
||||
/* Placeholder to prevent content jump when toolbar becomes fixed */
|
||||
.toolbar-placeholder {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.toolbar-placeholder.visible {
|
||||
display: block;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
@@ -162,6 +282,14 @@
|
||||
>
|
||||
<i class="bi bi-folder-plus"></i> New Folder
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
class="btn btn-outline-danger"
|
||||
id="deleteSelectedBtnTop"
|
||||
style="display: none"
|
||||
>
|
||||
<i class="bi bi-trash"></i> Delete Selected
|
||||
</button>
|
||||
<div class="divider"></div>
|
||||
<div class="search-box">
|
||||
<i class="bi bi-search"></i>
|
||||
@@ -430,14 +558,105 @@
|
||||
let sortBy = localStorage.getItem("mediaLibrarySort") || "date";
|
||||
let searchQuery = "";
|
||||
let draggedItem = null;
|
||||
let isLoading = false;
|
||||
|
||||
// Initialize
|
||||
document.addEventListener("DOMContentLoaded", () => {
|
||||
initViewMode();
|
||||
showSkeletonLoading();
|
||||
loadContent();
|
||||
bindEvents();
|
||||
setupStickyToolbar();
|
||||
});
|
||||
|
||||
function setupStickyToolbar() {
|
||||
const toolbar = document.querySelector(".media-library-toolbar");
|
||||
const mediaLibraryPage = document.querySelector(".media-library-page");
|
||||
|
||||
if (!toolbar || !mediaLibraryPage) return;
|
||||
|
||||
// Create placeholder element to prevent content jump
|
||||
const placeholder = document.createElement("div");
|
||||
placeholder.className = "toolbar-placeholder";
|
||||
toolbar.parentNode.insertBefore(placeholder, toolbar.nextSibling);
|
||||
|
||||
// Store original toolbar dimensions
|
||||
const toolbarHeight = toolbar.offsetHeight;
|
||||
placeholder.style.height = toolbarHeight + "px";
|
||||
|
||||
// Get the sidebar width for proper left offset
|
||||
const sidebarWidth = 250; // matches --sidebar-width in CSS
|
||||
const mainContentPadding = 30; // matches main-content padding
|
||||
|
||||
function handleScroll() {
|
||||
const pageRect = mediaLibraryPage.getBoundingClientRect();
|
||||
const pageTop = pageRect.top;
|
||||
|
||||
// When the media-library-page scrolls past the top, fix the toolbar
|
||||
if (pageTop <= 0) {
|
||||
if (!toolbar.classList.contains("fixed-toolbar")) {
|
||||
toolbar.classList.add("fixed-toolbar");
|
||||
placeholder.classList.add("visible");
|
||||
// Set the width and left position
|
||||
toolbar.style.left = sidebarWidth + mainContentPadding + "px";
|
||||
toolbar.style.right = mainContentPadding + "px";
|
||||
}
|
||||
} else {
|
||||
if (toolbar.classList.contains("fixed-toolbar")) {
|
||||
toolbar.classList.remove("fixed-toolbar");
|
||||
placeholder.classList.remove("visible");
|
||||
toolbar.style.left = "";
|
||||
toolbar.style.right = "";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
window.addEventListener("scroll", handleScroll, { passive: true });
|
||||
// Initial check
|
||||
handleScroll();
|
||||
}
|
||||
|
||||
function showSkeletonLoading() {
|
||||
const content = document.getElementById("mediaContent");
|
||||
let skeletonHtml = "";
|
||||
for (let i = 0; i < 12; i++) {
|
||||
skeletonHtml += `
|
||||
<div class="media-item skeleton-item">
|
||||
<div class="skeleton-preview"></div>
|
||||
<div class="skeleton-info">
|
||||
<div class="skeleton-name"></div>
|
||||
<div class="skeleton-meta"></div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
content.innerHTML = skeletonHtml;
|
||||
}
|
||||
|
||||
function getFilteredFolders() {
|
||||
let filteredFolders = folders.filter((f) =>
|
||||
currentFolder ? f.parentId === currentFolder : f.parentId === null,
|
||||
);
|
||||
if (searchQuery) {
|
||||
filteredFolders = filteredFolders.filter((f) =>
|
||||
f.name.toLowerCase().includes(searchQuery),
|
||||
);
|
||||
}
|
||||
return filteredFolders;
|
||||
}
|
||||
|
||||
function getFilteredFiles() {
|
||||
let filteredFiles = files;
|
||||
if (searchQuery) {
|
||||
filteredFiles = filteredFiles.filter(
|
||||
(f) =>
|
||||
f.originalName.toLowerCase().includes(searchQuery) ||
|
||||
f.filename.toLowerCase().includes(searchQuery),
|
||||
);
|
||||
}
|
||||
return filteredFiles;
|
||||
}
|
||||
|
||||
function initViewMode() {
|
||||
const content = document.getElementById("mediaContent");
|
||||
content.classList.remove("grid-view", "list-view");
|
||||
@@ -538,11 +757,16 @@
|
||||
if (e.key === "Enter") confirmRename();
|
||||
});
|
||||
|
||||
// Delete selected
|
||||
// Delete selected (bottom button)
|
||||
document
|
||||
.getElementById("deleteSelectedBtn")
|
||||
.addEventListener("click", deleteSelected);
|
||||
|
||||
// Delete selected (top button)
|
||||
document
|
||||
.getElementById("deleteSelectedBtnTop")
|
||||
.addEventListener("click", deleteSelected);
|
||||
|
||||
// Back button
|
||||
document
|
||||
.getElementById("backBtn")
|
||||
@@ -569,7 +793,11 @@
|
||||
}
|
||||
|
||||
async function loadContent() {
|
||||
isLoading = true;
|
||||
displayedCount = 0;
|
||||
|
||||
try {
|
||||
// Load folders and files in parallel
|
||||
const [foldersRes, filesRes] = await Promise.all([
|
||||
fetch("/api/admin/folders", { credentials: "include" }),
|
||||
fetch(
|
||||
@@ -588,22 +816,34 @@
|
||||
folders = foldersData.folders || [];
|
||||
files = filesData.files || [];
|
||||
|
||||
updateStats();
|
||||
// Render content immediately (first batch)
|
||||
renderContent();
|
||||
updateBreadcrumb();
|
||||
|
||||
// Update stats in background (non-blocking)
|
||||
updateStatsAsync();
|
||||
} catch (error) {
|
||||
console.error("Error loading media:", error);
|
||||
showToast("Failed to load media", "error");
|
||||
document.getElementById("mediaContent").innerHTML = `
|
||||
<div class="empty-state">
|
||||
<i class="bi bi-exclamation-circle"></i>
|
||||
<h5>Failed to load media</h5>
|
||||
<p>Please try refreshing the page</p>
|
||||
</div>
|
||||
`;
|
||||
} finally {
|
||||
isLoading = false;
|
||||
}
|
||||
}
|
||||
|
||||
function updateStats() {
|
||||
// Count all folders
|
||||
function updateStatsAsync() {
|
||||
// Update folder count immediately from current data
|
||||
document.getElementById("folderCount").textContent = `${
|
||||
folders.length
|
||||
} folder${folders.length !== 1 ? "s" : ""}`;
|
||||
|
||||
// Need to get total file count
|
||||
// Fetch total file stats in background
|
||||
fetch("/api/admin/uploads", { credentials: "include" })
|
||||
.then((res) => res.json())
|
||||
.then((data) => {
|
||||
@@ -618,32 +858,18 @@
|
||||
);
|
||||
document.getElementById("totalSize").textContent =
|
||||
formatFileSize(totalBytes) + " used";
|
||||
})
|
||||
.catch(() => {
|
||||
// Silently fail - stats are not critical
|
||||
});
|
||||
}
|
||||
|
||||
function renderContent() {
|
||||
const content = document.getElementById("mediaContent");
|
||||
|
||||
// Filter folders for current directory
|
||||
let filteredFolders = folders.filter((f) =>
|
||||
currentFolder ? f.parentId === currentFolder : f.parentId === null,
|
||||
);
|
||||
let filteredFiles = files;
|
||||
|
||||
// Apply search
|
||||
if (searchQuery) {
|
||||
filteredFolders = filteredFolders.filter((f) =>
|
||||
f.name.toLowerCase().includes(searchQuery),
|
||||
);
|
||||
filteredFiles = filteredFiles.filter(
|
||||
(f) =>
|
||||
f.originalName.toLowerCase().includes(searchQuery) ||
|
||||
f.filename.toLowerCase().includes(searchQuery),
|
||||
);
|
||||
}
|
||||
|
||||
// Sort files
|
||||
filteredFiles = sortFiles(filteredFiles);
|
||||
// Get filtered content
|
||||
const filteredFolders = getFilteredFolders();
|
||||
const filteredFiles = sortFiles(getFilteredFiles());
|
||||
|
||||
if (filteredFolders.length === 0 && filteredFiles.length === 0) {
|
||||
content.innerHTML = `
|
||||
@@ -671,9 +897,7 @@
|
||||
);
|
||||
html += `
|
||||
<div class="media-item folder-item ${isSelected ? "selected" : ""}"
|
||||
data-type="folder" data-id="${
|
||||
folder.id
|
||||
}" data-name="${escapeHtml(folder.name)}"
|
||||
data-type="folder" data-id="${folder.id}" data-name="${escapeHtml(folder.name)}"
|
||||
draggable="true">
|
||||
<div class="item-checkbox">
|
||||
<input type="checkbox" ${isSelected ? "checked" : ""}>
|
||||
@@ -697,7 +921,7 @@
|
||||
`;
|
||||
});
|
||||
|
||||
// Files
|
||||
// Files - use data-src for lazy loading
|
||||
filteredFiles.forEach((file) => {
|
||||
const isSelected = selectedItems.some(
|
||||
(s) => s.type === "file" && s.id === file.id,
|
||||
@@ -705,22 +929,17 @@
|
||||
html += `
|
||||
<div class="media-item file-item ${isSelected ? "selected" : ""}"
|
||||
data-type="file" data-id="${file.id}" data-path="${file.path}"
|
||||
data-name="${escapeHtml(file.originalName)}" data-size="${
|
||||
file.size
|
||||
}"
|
||||
data-name="${escapeHtml(file.originalName)}" data-size="${file.size}"
|
||||
draggable="true">
|
||||
<div class="item-checkbox">
|
||||
<input type="checkbox" ${isSelected ? "checked" : ""}>
|
||||
</div>
|
||||
<div class="item-preview">
|
||||
<img src="${file.path}" alt="${escapeHtml(
|
||||
file.originalName,
|
||||
)}" loading="lazy">
|
||||
<img data-src="${file.path}" alt="${escapeHtml(file.originalName)}"
|
||||
src="data:image/gif;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs=">
|
||||
</div>
|
||||
<div class="item-info">
|
||||
<span class="item-name" title="${escapeHtml(
|
||||
file.originalName,
|
||||
)}">${escapeHtml(file.originalName)}</span>
|
||||
<span class="item-name" title="${escapeHtml(file.originalName)}">${escapeHtml(file.originalName)}</span>
|
||||
<span class="item-meta">${formatFileSize(file.size)}</span>
|
||||
</div>
|
||||
<div class="item-actions">
|
||||
@@ -740,6 +959,61 @@
|
||||
|
||||
content.innerHTML = html;
|
||||
bindItemEvents();
|
||||
|
||||
// Setup lazy loading for images
|
||||
setupLazyLoading();
|
||||
}
|
||||
|
||||
function setupLazyLoading() {
|
||||
const PRELOAD_COUNT = 50; // Preload first 50 images immediately
|
||||
const images = document.querySelectorAll(".item-preview img[data-src]");
|
||||
|
||||
// Preload first 50 images immediately
|
||||
images.forEach((img, index) => {
|
||||
if (index < PRELOAD_COUNT) {
|
||||
const src = img.dataset.src;
|
||||
if (src) {
|
||||
img.src = src;
|
||||
img.classList.add("loaded");
|
||||
img.onerror = () => {
|
||||
img.src =
|
||||
'data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" width="100" height="100"><rect fill="%23f0f0f0" width="100" height="100"/><text x="50%" y="50%" text-anchor="middle" dy=".3em" fill="%23999" font-size="12">No preview</text></svg>';
|
||||
};
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Use Intersection Observer for lazy loading remaining images with large margin
|
||||
const imageObserver = new IntersectionObserver(
|
||||
(entries, observer) => {
|
||||
entries.forEach((entry) => {
|
||||
if (entry.isIntersecting) {
|
||||
const img = entry.target;
|
||||
const src = img.dataset.src;
|
||||
if (src) {
|
||||
img.src = src;
|
||||
img.classList.add("loaded");
|
||||
img.onerror = () => {
|
||||
img.src =
|
||||
'data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" width="100" height="100"><rect fill="%23f0f0f0" width="100" height="100"/><text x="50%" y="50%" text-anchor="middle" dy=".3em" fill="%23999" font-size="12">No preview</text></svg>';
|
||||
};
|
||||
observer.unobserve(img);
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
{
|
||||
rootMargin: "500px", // Load images 500px before they appear
|
||||
threshold: 0,
|
||||
},
|
||||
);
|
||||
|
||||
// Only observe images after the first 50
|
||||
images.forEach((img, index) => {
|
||||
if (index >= PRELOAD_COUNT && !img.classList.contains("loaded")) {
|
||||
imageObserver.observe(img);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function bindItemEvents() {
|
||||
@@ -859,14 +1133,17 @@
|
||||
const count = selectedItems.length;
|
||||
const countEl = document.getElementById("selectedCount");
|
||||
const deleteBtn = document.getElementById("deleteSelectedBtn");
|
||||
const deleteBtnTop = document.getElementById("deleteSelectedBtnTop");
|
||||
|
||||
if (count > 0) {
|
||||
countEl.style.display = "inline-flex";
|
||||
countEl.querySelector(".count").textContent = count;
|
||||
deleteBtn.style.display = "inline-flex";
|
||||
deleteBtnTop.style.display = "inline-flex";
|
||||
} else {
|
||||
countEl.style.display = "none";
|
||||
deleteBtn.style.display = "none";
|
||||
deleteBtnTop.style.display = "none";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -25,10 +25,10 @@
|
||||
/>
|
||||
|
||||
<!-- Modern Theme CSS -->
|
||||
<link rel="stylesheet" href="/assets/css/modern-theme.css?v=fix33" />
|
||||
<link rel="stylesheet" href="/assets/css/modern-theme.css?v=fix35" />
|
||||
<link
|
||||
rel="stylesheet"
|
||||
href="/assets/css/mobile-fixes.css?v=20260118fix30"
|
||||
href="/assets/css/mobile-fixes.css?v=20260120fix2"
|
||||
/>
|
||||
|
||||
<style>
|
||||
@@ -608,7 +608,7 @@
|
||||
</div>
|
||||
|
||||
<div class="footer-bottom">
|
||||
<p>© 2026 Sky Art Shop. All rights reserved.</p>
|
||||
<p>© 2026 PromptTech-Solution. Designed and Developed by: PromptTech-Solution</p>
|
||||
<p>
|
||||
Made with
|
||||
<i class="bi bi-heart-fill" style="color: var(--primary-pink)"></i>
|
||||
|
||||
@@ -148,34 +148,96 @@ body {
|
||||
}
|
||||
}
|
||||
|
||||
/* All mobile devices - Slide-in menu from right (half screen) */
|
||||
@media (max-width: 768px) {
|
||||
/* Hide close button on desktop */
|
||||
.nav-menu-close {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
/* All mobile and tablet devices - Slide-in menu from right */
|
||||
@media (max-width: 1024px) {
|
||||
/* Show close button on mobile/tablet */
|
||||
.nav-menu-close {
|
||||
display: flex !important;
|
||||
}
|
||||
|
||||
.navbar {
|
||||
position: relative !important;
|
||||
}
|
||||
|
||||
/* Show hamburger menu on tablets */
|
||||
.nav-mobile-toggle {
|
||||
display: flex !important;
|
||||
flex-direction: column;
|
||||
gap: 5px;
|
||||
padding: 10px;
|
||||
background: none;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
z-index: 1001;
|
||||
}
|
||||
|
||||
.nav-mobile-toggle span {
|
||||
display: block;
|
||||
width: 26px;
|
||||
height: 3px;
|
||||
background: var(--text-primary, #202023);
|
||||
border-radius: 2px;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
/* Hamburger to X animation when active */
|
||||
.nav-mobile-toggle.active span:nth-child(1) {
|
||||
transform: rotate(45deg) translate(5px, 5px);
|
||||
}
|
||||
|
||||
.nav-mobile-toggle.active span:nth-child(2) {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.nav-mobile-toggle.active span:nth-child(3) {
|
||||
transform: rotate(-45deg) translate(7px, -6px);
|
||||
}
|
||||
|
||||
/* Menu overlay - dark background when menu is open */
|
||||
.nav-menu-overlay {
|
||||
position: fixed !important;
|
||||
top: 0 !important;
|
||||
left: 0 !important;
|
||||
right: 0 !important;
|
||||
bottom: 0 !important;
|
||||
background: rgba(0, 0, 0, 0.5) !important;
|
||||
opacity: 0 !important;
|
||||
visibility: hidden !important;
|
||||
transition: opacity 0.3s ease, visibility 0.3s ease !important;
|
||||
z-index: 998 !important;
|
||||
}
|
||||
|
||||
.nav-menu-overlay.active {
|
||||
opacity: 1 !important;
|
||||
visibility: visible !important;
|
||||
}
|
||||
|
||||
.nav-menu {
|
||||
position: fixed !important;
|
||||
top: 0 !important;
|
||||
right: 0 !important;
|
||||
left: auto !important;
|
||||
bottom: 0 !important;
|
||||
width: 50% !important;
|
||||
min-width: 200px !important;
|
||||
max-width: 300px !important;
|
||||
width: 320px !important;
|
||||
max-width: 80% !important;
|
||||
height: 100vh !important;
|
||||
height: 100dvh !important; /* Dynamic viewport height for mobile browsers */
|
||||
flex-direction: column !important;
|
||||
background: #ffffff !important;
|
||||
padding: 80px 20px 30px !important;
|
||||
gap: 4px !important;
|
||||
padding: 100px 24px 30px !important;
|
||||
gap: 8px !important;
|
||||
transform: translateX(100%) !important;
|
||||
opacity: 1 !important;
|
||||
visibility: hidden !important;
|
||||
transition: transform 0.3s ease, visibility 0.3s ease !important;
|
||||
z-index: 999 !important;
|
||||
overflow-y: auto !important;
|
||||
box-shadow: -4px 0 20px rgba(0, 0, 0, 0.1) !important;
|
||||
box-shadow: -4px 0 30px rgba(0, 0, 0, 0.2) !important;
|
||||
box-sizing: border-box !important;
|
||||
}
|
||||
|
||||
@@ -184,6 +246,30 @@ body {
|
||||
visibility: visible !important;
|
||||
}
|
||||
|
||||
/* Close button for mobile/tablet menu */
|
||||
.nav-menu-close {
|
||||
position: absolute !important;
|
||||
top: 24px !important;
|
||||
right: 24px !important;
|
||||
width: 44px !important;
|
||||
height: 44px !important;
|
||||
background: #f5f5f5 !important;
|
||||
border: none !important;
|
||||
border-radius: 50% !important;
|
||||
font-size: 24px !important;
|
||||
color: #333 !important;
|
||||
cursor: pointer !important;
|
||||
display: flex !important;
|
||||
align-items: center !important;
|
||||
justify-content: center !important;
|
||||
transition: background 0.2s ease !important;
|
||||
z-index: 1000 !important;
|
||||
}
|
||||
|
||||
.nav-menu-close:hover {
|
||||
background: #e0e0e0 !important;
|
||||
}
|
||||
|
||||
.nav-menu li {
|
||||
list-style: none !important;
|
||||
margin: 0 !important;
|
||||
@@ -193,12 +279,12 @@ body {
|
||||
.nav-link {
|
||||
display: block !important;
|
||||
width: 100% !important;
|
||||
padding: 14px 16px !important;
|
||||
padding: 16px 20px !important;
|
||||
text-align: left !important;
|
||||
font-size: 1rem !important;
|
||||
font-size: 1.1rem !important;
|
||||
font-weight: 500 !important;
|
||||
color: #333 !important;
|
||||
border-radius: 8px !important;
|
||||
border-radius: 10px !important;
|
||||
text-decoration: none !important;
|
||||
transition: background 0.15s ease !important;
|
||||
}
|
||||
@@ -215,6 +301,82 @@ body {
|
||||
.nav-link::after {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
/* Prevent body scroll when menu is open */
|
||||
body.nav-menu-open {
|
||||
overflow: hidden !important;
|
||||
}
|
||||
}
|
||||
|
||||
/* Smaller phones (max-width: 576px) - smaller menu width */
|
||||
@media (max-width: 576px) {
|
||||
.nav-menu {
|
||||
width: 280px !important;
|
||||
max-width: 85% !important;
|
||||
padding: 90px 20px 30px !important;
|
||||
}
|
||||
|
||||
.nav-link {
|
||||
padding: 14px 16px !important;
|
||||
font-size: 1rem !important;
|
||||
}
|
||||
|
||||
.nav-menu-close {
|
||||
top: 20px !important;
|
||||
right: 20px !important;
|
||||
width: 40px !important;
|
||||
height: 40px !important;
|
||||
font-size: 20px !important;
|
||||
}
|
||||
}
|
||||
|
||||
/* iPad and Tablets (768px - 1024px) - Larger buttons for touch */
|
||||
@media (min-width: 768px) and (max-width: 1024px) {
|
||||
/* Larger mobile menu for tablets */
|
||||
.nav-menu {
|
||||
width: 380px !important;
|
||||
max-width: 70% !important;
|
||||
padding: 100px 28px 40px !important;
|
||||
}
|
||||
|
||||
/* Bigger menu links for iPad */
|
||||
.nav-menu .nav-link {
|
||||
padding: 20px 24px !important;
|
||||
font-size: 1.25rem !important;
|
||||
font-weight: 500 !important;
|
||||
border-radius: 12px !important;
|
||||
margin-bottom: 4px !important;
|
||||
}
|
||||
|
||||
/* Larger close button for tablets */
|
||||
.nav-menu-close {
|
||||
top: 28px !important;
|
||||
right: 28px !important;
|
||||
width: 52px !important;
|
||||
height: 52px !important;
|
||||
font-size: 28px !important;
|
||||
}
|
||||
|
||||
/* Larger hamburger button */
|
||||
.nav-mobile-toggle {
|
||||
padding: 12px !important;
|
||||
}
|
||||
|
||||
.nav-mobile-toggle span {
|
||||
width: 28px !important;
|
||||
height: 3px !important;
|
||||
}
|
||||
|
||||
/* Larger navbar action buttons for tablets */
|
||||
.nav-icon-btn {
|
||||
width: 48px !important;
|
||||
height: 48px !important;
|
||||
font-size: 1.4rem !important;
|
||||
}
|
||||
|
||||
.nav-actions {
|
||||
gap: 12px !important;
|
||||
}
|
||||
}
|
||||
|
||||
/* === iPad Mini (768px) === */
|
||||
@@ -442,6 +604,13 @@ body {
|
||||
max-width: 100% !important;
|
||||
overflow: hidden !important;
|
||||
box-sizing: border-box !important;
|
||||
flex: 1 !important;
|
||||
display: flex !important;
|
||||
flex-direction: column !important;
|
||||
}
|
||||
|
||||
.product-footer {
|
||||
margin-top: auto !important;
|
||||
}
|
||||
|
||||
.product-name {
|
||||
@@ -485,6 +654,18 @@ body {
|
||||
overflow: hidden !important;
|
||||
box-sizing: border-box !important;
|
||||
background: #ffffff !important;
|
||||
display: flex !important;
|
||||
flex-direction: column !important;
|
||||
}
|
||||
|
||||
.product-info {
|
||||
flex: 1 !important;
|
||||
display: flex !important;
|
||||
flex-direction: column !important;
|
||||
}
|
||||
|
||||
.product-footer {
|
||||
margin-top: auto !important;
|
||||
}
|
||||
|
||||
.product-image {
|
||||
@@ -530,6 +711,18 @@ body {
|
||||
min-width: 0 !important;
|
||||
box-sizing: border-box !important;
|
||||
background: #ffffff !important;
|
||||
display: flex !important;
|
||||
flex-direction: column !important;
|
||||
}
|
||||
|
||||
.product-info {
|
||||
flex: 1 !important;
|
||||
display: flex !important;
|
||||
flex-direction: column !important;
|
||||
}
|
||||
|
||||
.product-footer {
|
||||
margin-top: auto !important;
|
||||
}
|
||||
|
||||
.product-image {
|
||||
@@ -2185,13 +2378,23 @@ body {
|
||||
}
|
||||
}
|
||||
|
||||
/* === GLOBAL PRODUCT CARD FIX - Remove pink divider === */
|
||||
/* === GLOBAL PRODUCT CARD FIX - Remove pink divider & Align footer === */
|
||||
.product-card {
|
||||
display: flex !important;
|
||||
flex-direction: column !important;
|
||||
background: #ffffff !important;
|
||||
}
|
||||
|
||||
.product-info {
|
||||
flex: 1 !important;
|
||||
display: flex !important;
|
||||
flex-direction: column !important;
|
||||
}
|
||||
|
||||
.product-footer {
|
||||
margin-top: auto !important;
|
||||
}
|
||||
|
||||
.product-image {
|
||||
background: #ffffff !important;
|
||||
margin: 0 !important;
|
||||
@@ -2203,4 +2406,206 @@ body {
|
||||
display: block !important;
|
||||
margin: 0 !important;
|
||||
padding: 0 !important;
|
||||
}
|
||||
|
||||
/* ============================================
|
||||
UNIVERSAL IMAGE CONTAINMENT FIXES
|
||||
Ensures consistent image sizing across all devices
|
||||
============================================ */
|
||||
|
||||
/* === SHOP PAGE: Product Grid Image Standardization === */
|
||||
/* All product card images - standardized box with aspect ratio */
|
||||
.products-grid .product-card {
|
||||
display: flex !important;
|
||||
flex-direction: column !important;
|
||||
width: 100% !important;
|
||||
max-width: 100% !important;
|
||||
box-sizing: border-box !important;
|
||||
}
|
||||
|
||||
.products-grid .product-image {
|
||||
position: relative !important;
|
||||
width: 100% !important;
|
||||
max-width: 100% !important;
|
||||
aspect-ratio: 1 / 1 !important;
|
||||
overflow: hidden !important;
|
||||
flex-shrink: 0 !important;
|
||||
background: #ffffff !important;
|
||||
}
|
||||
|
||||
.products-grid .product-image img {
|
||||
position: absolute !important;
|
||||
top: 0 !important;
|
||||
left: 0 !important;
|
||||
width: 100% !important;
|
||||
height: 100% !important;
|
||||
object-fit: cover !important;
|
||||
object-position: center !important;
|
||||
}
|
||||
|
||||
/* === PRODUCT DETAIL PAGE: Main Image Standardization === */
|
||||
/* Desktop/Large screens */
|
||||
.product-detail .main-image {
|
||||
position: relative !important;
|
||||
width: 100% !important;
|
||||
max-width: 100% !important;
|
||||
aspect-ratio: 1 / 1 !important;
|
||||
overflow: hidden !important;
|
||||
border-radius: var(--radius-lg) !important;
|
||||
background: var(--bg-white, #ffffff) !important;
|
||||
}
|
||||
|
||||
.product-detail .main-image img {
|
||||
position: absolute !important;
|
||||
top: 0 !important;
|
||||
left: 0 !important;
|
||||
width: 100% !important;
|
||||
height: 100% !important;
|
||||
object-fit: cover !important;
|
||||
object-position: center !important;
|
||||
}
|
||||
|
||||
/* Ensure gallery doesn't overflow */
|
||||
.product-detail .product-gallery {
|
||||
width: 100% !important;
|
||||
max-width: 100% !important;
|
||||
overflow: hidden !important;
|
||||
box-sizing: border-box !important;
|
||||
}
|
||||
|
||||
/* === TABLET SPECIFIC (iPad, iPad Air, iPad Pro) === */
|
||||
@media (min-width: 768px) and (max-width: 1024px) {
|
||||
/* Product Detail Page - Tablet */
|
||||
.product-detail {
|
||||
display: grid !important;
|
||||
grid-template-columns: 1fr 1fr !important;
|
||||
gap: var(--spacing-xl, 24px) !important;
|
||||
width: 100% !important;
|
||||
max-width: 100% !important;
|
||||
box-sizing: border-box !important;
|
||||
}
|
||||
|
||||
.product-detail .product-gallery {
|
||||
position: relative !important;
|
||||
width: 100% !important;
|
||||
max-width: 100% !important;
|
||||
overflow: hidden !important;
|
||||
}
|
||||
|
||||
.product-detail .main-image {
|
||||
position: relative !important;
|
||||
width: 100% !important;
|
||||
max-width: 100% !important;
|
||||
height: 0 !important;
|
||||
padding-bottom: 100% !important;
|
||||
aspect-ratio: unset !important;
|
||||
overflow: hidden !important;
|
||||
border-radius: var(--radius-lg, 12px) !important;
|
||||
background: #ffffff !important;
|
||||
}
|
||||
|
||||
.product-detail .main-image img {
|
||||
position: absolute !important;
|
||||
top: 0 !important;
|
||||
left: 0 !important;
|
||||
width: 100% !important;
|
||||
height: 100% !important;
|
||||
object-fit: cover !important;
|
||||
object-position: center !important;
|
||||
}
|
||||
|
||||
.product-detail .product-details {
|
||||
width: 100% !important;
|
||||
max-width: 100% !important;
|
||||
box-sizing: border-box !important;
|
||||
overflow-wrap: break-word !important;
|
||||
}
|
||||
|
||||
/* Container overflow prevention */
|
||||
.container {
|
||||
max-width: 100% !important;
|
||||
overflow-x: hidden !important;
|
||||
box-sizing: border-box !important;
|
||||
}
|
||||
}
|
||||
|
||||
/* === SMALL TABLET / Large Phone (600px - 768px) === */
|
||||
@media (min-width: 600px) and (max-width: 767px) {
|
||||
.product-detail {
|
||||
display: block !important;
|
||||
width: 100% !important;
|
||||
max-width: 100% !important;
|
||||
}
|
||||
|
||||
.product-detail .product-gallery {
|
||||
width: 100% !important;
|
||||
max-width: 100% !important;
|
||||
margin-bottom: var(--spacing-lg, 16px) !important;
|
||||
}
|
||||
|
||||
.product-detail .main-image {
|
||||
position: relative !important;
|
||||
width: 100% !important;
|
||||
max-width: 100% !important;
|
||||
height: 0 !important;
|
||||
padding-bottom: 100% !important;
|
||||
aspect-ratio: unset !important;
|
||||
overflow: hidden !important;
|
||||
border-radius: var(--radius-lg, 12px) !important;
|
||||
}
|
||||
|
||||
.product-detail .main-image img {
|
||||
position: absolute !important;
|
||||
top: 0 !important;
|
||||
left: 0 !important;
|
||||
width: 100% !important;
|
||||
height: 100% !important;
|
||||
object-fit: cover !important;
|
||||
object-position: center !important;
|
||||
}
|
||||
}
|
||||
|
||||
/* === MOBILE (up to 600px) === */
|
||||
@media (max-width: 599px) {
|
||||
.product-detail .main-image {
|
||||
position: relative !important;
|
||||
width: 100% !important;
|
||||
max-width: 100% !important;
|
||||
height: 0 !important;
|
||||
padding-bottom: 100% !important;
|
||||
aspect-ratio: unset !important;
|
||||
overflow: hidden !important;
|
||||
}
|
||||
|
||||
.product-detail .main-image img {
|
||||
position: absolute !important;
|
||||
top: 0 !important;
|
||||
left: 0 !important;
|
||||
width: 100% !important;
|
||||
height: 100% !important;
|
||||
object-fit: cover !important;
|
||||
object-position: center !important;
|
||||
}
|
||||
}
|
||||
|
||||
/* === LARGE DESKTOP (1025px+) === */
|
||||
@media (min-width: 1025px) {
|
||||
.product-detail .main-image {
|
||||
position: relative !important;
|
||||
width: 100% !important;
|
||||
max-width: 600px !important;
|
||||
aspect-ratio: 1 / 1 !important;
|
||||
overflow: hidden !important;
|
||||
border-radius: var(--radius-lg, 12px) !important;
|
||||
}
|
||||
|
||||
.product-detail .main-image img {
|
||||
position: absolute !important;
|
||||
top: 0 !important;
|
||||
left: 0 !important;
|
||||
width: 100% !important;
|
||||
height: 100% !important;
|
||||
object-fit: cover !important;
|
||||
object-position: center !important;
|
||||
}
|
||||
}
|
||||
@@ -370,10 +370,10 @@ body {
|
||||
transition: var(--transition-fast);
|
||||
}
|
||||
|
||||
/* Mobile Navigation - Slide from Right (Half Screen) */
|
||||
@media (max-width: 992px) {
|
||||
/* Mobile Navigation - Slide from Right (all devices up to 1024px including iPads) */
|
||||
@media (max-width: 1024px) {
|
||||
.nav-mobile-toggle {
|
||||
display: flex;
|
||||
display: flex !important;
|
||||
}
|
||||
|
||||
.nav-menu {
|
||||
@@ -381,14 +381,13 @@ body {
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
width: 50%;
|
||||
min-width: 200px;
|
||||
max-width: 300px;
|
||||
width: 320px;
|
||||
max-width: 80%;
|
||||
flex-direction: column;
|
||||
background: var(--bg-white);
|
||||
padding: 80px var(--spacing-lg) var(--spacing-xl);
|
||||
gap: var(--spacing-xs);
|
||||
box-shadow: -4px 0 20px rgba(0, 0, 0, 0.1);
|
||||
box-shadow: -4px 0 20px rgba(0, 0, 0, 0.15);
|
||||
transform: translateX(100%);
|
||||
visibility: hidden;
|
||||
transition: transform 0.3s ease, visibility 0.3s ease;
|
||||
@@ -402,9 +401,10 @@ body {
|
||||
|
||||
.nav-link {
|
||||
width: 100%;
|
||||
padding: var(--spacing-sm) var(--spacing-md);
|
||||
padding: var(--spacing-md) var(--spacing-lg);
|
||||
text-align: left;
|
||||
border-radius: var(--radius-sm);
|
||||
font-size: 1.1rem;
|
||||
}
|
||||
|
||||
.nav-link:hover {
|
||||
@@ -828,6 +828,9 @@ body {
|
||||
|
||||
.product-info {
|
||||
padding: var(--spacing-lg);
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.product-category {
|
||||
@@ -883,6 +886,7 @@ body {
|
||||
justify-content: space-between;
|
||||
padding: var(--spacing-md) var(--spacing-lg);
|
||||
border-top: 1px solid var(--border-light);
|
||||
margin-top: auto;
|
||||
}
|
||||
|
||||
.product-stock {
|
||||
|
||||
@@ -405,14 +405,14 @@
|
||||
background: #f3f0ff;
|
||||
}
|
||||
|
||||
/* Responsive Design */
|
||||
/* Responsive Design - Mobile & Tablet (up to 1024px includes all iPads) */
|
||||
@media (max-width: 1024px) {
|
||||
.navbar-menu {
|
||||
display: none;
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
.mobile-toggle {
|
||||
display: flex;
|
||||
display: flex !important;
|
||||
}
|
||||
|
||||
.navbar-brand {
|
||||
@@ -423,6 +423,17 @@
|
||||
.navbar-actions {
|
||||
margin-left: 16px;
|
||||
}
|
||||
|
||||
/* Wider mobile menu for tablets */
|
||||
.mobile-menu {
|
||||
width: 350px;
|
||||
max-width: 85%;
|
||||
}
|
||||
|
||||
.mobile-link {
|
||||
padding: 16px 20px;
|
||||
font-size: 17px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 640px) {
|
||||
@@ -456,13 +467,88 @@
|
||||
right: -16px;
|
||||
}
|
||||
}
|
||||
|
||||
/* Tablet-specific (iPad) enhancements - portrait and landscape */
|
||||
@media (min-width: 641px) and (max-width: 1024px) {
|
||||
.navbar-wrapper {
|
||||
padding: 0 24px;
|
||||
height: 72px;
|
||||
}
|
||||
|
||||
.brand-logo {
|
||||
width: 52px;
|
||||
height: 52px;
|
||||
}
|
||||
|
||||
.brand-name {
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
/* Larger hamburger menu for tablets */
|
||||
.mobile-toggle {
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
padding: 12px;
|
||||
}
|
||||
|
||||
.toggle-line {
|
||||
width: 26px;
|
||||
height: 3px;
|
||||
}
|
||||
|
||||
/* Wider mobile menu for tablets */
|
||||
.mobile-menu {
|
||||
width: 380px;
|
||||
max-width: 75%;
|
||||
padding: 24px;
|
||||
}
|
||||
|
||||
.mobile-menu-header {
|
||||
padding-bottom: 20px;
|
||||
margin-bottom: 28px;
|
||||
}
|
||||
|
||||
.mobile-brand {
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
.mobile-close {
|
||||
font-size: 28px;
|
||||
width: 44px;
|
||||
height: 44px;
|
||||
}
|
||||
|
||||
.mobile-link {
|
||||
padding: 18px 24px;
|
||||
font-size: 18px;
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
.mobile-menu-list li {
|
||||
margin-bottom: 6px;
|
||||
}
|
||||
|
||||
/* Larger action buttons for tablets */
|
||||
.action-btn {
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
font-size: 24px;
|
||||
}
|
||||
|
||||
.action-badge {
|
||||
min-width: 20px;
|
||||
height: 20px;
|
||||
font-size: 12px;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Mobile Navbar Fixes
|
||||
* Ensures hamburger menu, cart, and wishlist are visible on mobile devices
|
||||
* Ensures hamburger menu, cart, and wishlist are visible on mobile/tablet devices
|
||||
*/
|
||||
|
||||
/* Mobile hamburger menu - always visible on small screens */
|
||||
@media (max-width: 768px) {
|
||||
/* Mobile/Tablet hamburger menu - visible on screens up to 1024px (includes iPads) */
|
||||
@media (max-width: 1024px) {
|
||||
.mobile-toggle {
|
||||
display: flex !important;
|
||||
flex-direction: column;
|
||||
@@ -676,8 +762,17 @@
|
||||
}
|
||||
}
|
||||
|
||||
/* Tablet adjustments */
|
||||
@media (min-width: 769px) and (max-width: 1024px) {
|
||||
/* Desktop - hide mobile elements (only on screens larger than 1024px) */
|
||||
@media (min-width: 1025px) {
|
||||
.mobile-toggle {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
.mobile-menu,
|
||||
.mobile-menu-overlay {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
.navbar-actions {
|
||||
gap: 16px;
|
||||
}
|
||||
@@ -691,18 +786,6 @@
|
||||
}
|
||||
}
|
||||
|
||||
/* Desktop - hide mobile elements */
|
||||
@media (min-width: 769px) {
|
||||
.mobile-toggle {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
.mobile-menu,
|
||||
.mobile-menu-overlay {
|
||||
display: none !important;
|
||||
}
|
||||
}
|
||||
|
||||
/* Accessibility improvements */
|
||||
.action-btn:focus,
|
||||
.mobile-toggle:focus,
|
||||
|
||||
BIN
website/public/assets/images/prompttech-copyright.png
Normal file
BIN
website/public/assets/images/prompttech-copyright.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 26 KiB |
@@ -41,19 +41,67 @@ const SkyArtShop = {
|
||||
});
|
||||
}
|
||||
|
||||
// Mobile menu toggle
|
||||
// Mobile/Tablet menu toggle
|
||||
if (mobileToggle && navMenu) {
|
||||
// Create overlay element for background dimming
|
||||
let overlay = document.querySelector(".nav-menu-overlay");
|
||||
if (!overlay) {
|
||||
overlay = document.createElement("div");
|
||||
overlay.className = "nav-menu-overlay";
|
||||
document.body.appendChild(overlay);
|
||||
}
|
||||
|
||||
// Create close button inside menu
|
||||
let closeBtn = navMenu.querySelector(".nav-menu-close");
|
||||
if (!closeBtn) {
|
||||
closeBtn = document.createElement("button");
|
||||
closeBtn.className = "nav-menu-close";
|
||||
closeBtn.innerHTML = '<i class="bi bi-x-lg"></i>';
|
||||
closeBtn.setAttribute("aria-label", "Close menu");
|
||||
navMenu.insertBefore(closeBtn, navMenu.firstChild);
|
||||
}
|
||||
|
||||
// Function to open menu
|
||||
const openMenu = () => {
|
||||
navMenu.classList.add("open");
|
||||
mobileToggle.classList.add("active");
|
||||
overlay.classList.add("active");
|
||||
document.body.classList.add("nav-menu-open");
|
||||
};
|
||||
|
||||
// Function to close menu
|
||||
const closeMenu = () => {
|
||||
navMenu.classList.remove("open");
|
||||
mobileToggle.classList.remove("active");
|
||||
overlay.classList.remove("active");
|
||||
document.body.classList.remove("nav-menu-open");
|
||||
};
|
||||
|
||||
// Toggle button click
|
||||
mobileToggle.addEventListener("click", (e) => {
|
||||
e.stopPropagation();
|
||||
navMenu.classList.toggle("open");
|
||||
mobileToggle.classList.toggle("active");
|
||||
if (navMenu.classList.contains("open")) {
|
||||
closeMenu();
|
||||
} else {
|
||||
openMenu();
|
||||
}
|
||||
});
|
||||
|
||||
// Close button click
|
||||
closeBtn.addEventListener("click", (e) => {
|
||||
e.stopPropagation();
|
||||
closeMenu();
|
||||
});
|
||||
|
||||
// Overlay click to close
|
||||
overlay.addEventListener("click", () => {
|
||||
closeMenu();
|
||||
});
|
||||
|
||||
// Close menu when clicking a link
|
||||
navMenu.querySelectorAll(".nav-link").forEach((link) => {
|
||||
link.addEventListener("click", () => {
|
||||
navMenu.classList.remove("open");
|
||||
mobileToggle.classList.remove("active");
|
||||
closeMenu();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -64,12 +112,11 @@ const SkyArtShop = {
|
||||
!navMenu.contains(e.target) &&
|
||||
!mobileToggle.contains(e.target)
|
||||
) {
|
||||
navMenu.classList.remove("open");
|
||||
mobileToggle.classList.remove("active");
|
||||
closeMenu();
|
||||
}
|
||||
});
|
||||
|
||||
// Close menu when touching outside (for mobile)
|
||||
// Close menu when touching outside (for mobile/tablet)
|
||||
document.addEventListener(
|
||||
"touchstart",
|
||||
(e) => {
|
||||
@@ -78,12 +125,18 @@ const SkyArtShop = {
|
||||
!navMenu.contains(e.target) &&
|
||||
!mobileToggle.contains(e.target)
|
||||
) {
|
||||
navMenu.classList.remove("open");
|
||||
mobileToggle.classList.remove("active");
|
||||
closeMenu();
|
||||
}
|
||||
},
|
||||
{ passive: true },
|
||||
);
|
||||
|
||||
// Close menu on escape key
|
||||
document.addEventListener("keydown", (e) => {
|
||||
if (e.key === "Escape" && navMenu.classList.contains("open")) {
|
||||
closeMenu();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Set active nav link
|
||||
|
||||
@@ -25,13 +25,10 @@
|
||||
/>
|
||||
|
||||
<!-- Modern Theme CSS -->
|
||||
<link rel="stylesheet" href="/assets/css/modern-theme.css?v=fix35" />
|
||||
<link
|
||||
rel="stylesheet"
|
||||
href="/assets/css/modern-theme.css?v=fix33"
|
||||
/>
|
||||
<link
|
||||
rel="stylesheet"
|
||||
href="/assets/css/mobile-fixes.css?v=20260118fix10"
|
||||
href="/assets/css/mobile-fixes.css?v=20260120fix2"
|
||||
/>
|
||||
|
||||
<style>
|
||||
@@ -885,11 +882,14 @@
|
||||
</p>
|
||||
<form
|
||||
class="newsletter-form"
|
||||
id="blogNewsletterForm"
|
||||
style="max-width: 500px; margin: 0 auto; display: flex; gap: 12px"
|
||||
>
|
||||
<input
|
||||
type="email"
|
||||
id="blogNewsletterEmail"
|
||||
placeholder="Enter your email"
|
||||
required
|
||||
style="
|
||||
flex: 1;
|
||||
padding: 16px 24px;
|
||||
@@ -898,7 +898,13 @@
|
||||
font-size: 1rem;
|
||||
"
|
||||
/>
|
||||
<button type="submit" class="btn btn-primary">Subscribe</button>
|
||||
<button
|
||||
type="submit"
|
||||
class="btn btn-primary"
|
||||
id="blogNewsletterBtn"
|
||||
>
|
||||
Subscribe
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
</section>
|
||||
@@ -921,15 +927,63 @@
|
||||
collaging stationery. Quality products for all your creative
|
||||
needs.
|
||||
</p>
|
||||
<div class="footer-social" id="footerSocialLinks">
|
||||
<a href="#" class="social-link" id="footerFacebook" style="display:none;"><i class="bi bi-facebook"></i></a>
|
||||
<a href="#" class="social-link" id="footerInstagram" style="display:none;"><i class="bi bi-instagram"></i></a>
|
||||
<a href="#" class="social-link" id="footerTwitter" style="display:none;"><i class="bi bi-twitter-x"></i></a>
|
||||
<a href="#" class="social-link" id="footerYoutube" style="display:none;"><i class="bi bi-youtube"></i></a>
|
||||
<a href="#" class="social-link" id="footerPinterest" style="display:none;"><i class="bi bi-pinterest"></i></a>
|
||||
<a href="#" class="social-link" id="footerTiktok" style="display:none;"><i class="bi bi-tiktok"></i></a>
|
||||
<a href="#" class="social-link" id="footerWhatsapp" style="display:none;"><i class="bi bi-whatsapp"></i></a>
|
||||
<a href="#" class="social-link" id="footerLinkedin" style="display:none;"><i class="bi bi-linkedin"></i></a>
|
||||
<div class="footer-social" id="footerSocialLinks">
|
||||
<a
|
||||
href="#"
|
||||
class="social-link"
|
||||
id="footerFacebook"
|
||||
style="display: none"
|
||||
><i class="bi bi-facebook"></i
|
||||
></a>
|
||||
<a
|
||||
href="#"
|
||||
class="social-link"
|
||||
id="footerInstagram"
|
||||
style="display: none"
|
||||
><i class="bi bi-instagram"></i
|
||||
></a>
|
||||
<a
|
||||
href="#"
|
||||
class="social-link"
|
||||
id="footerTwitter"
|
||||
style="display: none"
|
||||
><i class="bi bi-twitter-x"></i
|
||||
></a>
|
||||
<a
|
||||
href="#"
|
||||
class="social-link"
|
||||
id="footerYoutube"
|
||||
style="display: none"
|
||||
><i class="bi bi-youtube"></i
|
||||
></a>
|
||||
<a
|
||||
href="#"
|
||||
class="social-link"
|
||||
id="footerPinterest"
|
||||
style="display: none"
|
||||
><i class="bi bi-pinterest"></i
|
||||
></a>
|
||||
<a
|
||||
href="#"
|
||||
class="social-link"
|
||||
id="footerTiktok"
|
||||
style="display: none"
|
||||
><i class="bi bi-tiktok"></i
|
||||
></a>
|
||||
<a
|
||||
href="#"
|
||||
class="social-link"
|
||||
id="footerWhatsapp"
|
||||
style="display: none"
|
||||
><i class="bi bi-whatsapp"></i
|
||||
></a>
|
||||
<a
|
||||
href="#"
|
||||
class="social-link"
|
||||
id="footerLinkedin"
|
||||
style="display: none"
|
||||
><i class="bi bi-linkedin"></i
|
||||
></a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -966,7 +1020,7 @@
|
||||
</div>
|
||||
|
||||
<div class="footer-bottom">
|
||||
<p>© 2026 Sky Art Shop. All rights reserved.</p>
|
||||
<p>© 2026 PromptTech-Solution. Designed and Developed by: PromptTech-Solution</p>
|
||||
<p>
|
||||
Made with
|
||||
<i class="bi bi-heart-fill" style="color: var(--primary-pink)"></i>
|
||||
@@ -1373,6 +1427,61 @@
|
||||
document.addEventListener("keydown", (e) => {
|
||||
if (e.key === "Escape") closeBlogDetail();
|
||||
});
|
||||
|
||||
// Newsletter form handler
|
||||
document
|
||||
.getElementById("blogNewsletterForm")
|
||||
?.addEventListener("submit", async function (e) {
|
||||
e.preventDefault();
|
||||
|
||||
const emailInput = document.getElementById("blogNewsletterEmail");
|
||||
const submitBtn = document.getElementById("blogNewsletterBtn");
|
||||
const email = emailInput.value.trim();
|
||||
|
||||
if (!email) {
|
||||
SkyArtShop.showNotification(
|
||||
"Please enter your email address.",
|
||||
"error",
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
const originalBtnText = submitBtn.innerHTML;
|
||||
submitBtn.disabled = true;
|
||||
submitBtn.innerHTML = "Subscribing...";
|
||||
|
||||
try {
|
||||
const response = await fetch("/api/newsletter/subscribe", {
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
body: JSON.stringify({ email, source: "blog" }),
|
||||
});
|
||||
|
||||
const data = await response.json();
|
||||
|
||||
if (data.success) {
|
||||
SkyArtShop.showNotification(
|
||||
data.message || "Successfully subscribed!",
|
||||
"success",
|
||||
);
|
||||
emailInput.value = "";
|
||||
} else {
|
||||
SkyArtShop.showNotification(
|
||||
data.message || "Failed to subscribe. Please try again.",
|
||||
"error",
|
||||
);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Newsletter error:", error);
|
||||
SkyArtShop.showNotification(
|
||||
"Failed to subscribe. Please try again later.",
|
||||
"error",
|
||||
);
|
||||
} finally {
|
||||
submitBtn.disabled = false;
|
||||
submitBtn.innerHTML = originalBtnText;
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
<script src="/assets/js/accessibility.js"></script>
|
||||
|
||||
@@ -22,8 +22,8 @@
|
||||
/>
|
||||
|
||||
<!-- Modern Theme CSS -->
|
||||
<link rel="stylesheet" href="/assets/css/modern-theme.css?v=fix33" />
|
||||
<link rel="stylesheet" href="/assets/css/mobile-fixes.css?v=20260118c" />
|
||||
<link rel="stylesheet" href="/assets/css/modern-theme.css?v=fix35" />
|
||||
<link rel="stylesheet" href="/assets/css/mobile-fixes.css?v=20260120fix2" />
|
||||
|
||||
<style>
|
||||
.checkout-container {
|
||||
@@ -640,7 +640,7 @@
|
||||
</div>
|
||||
|
||||
<div class="footer-bottom">
|
||||
<p>© 2026 Sky Art Shop. All rights reserved.</p>
|
||||
<p>© 2026 PromptTech-Solution. Designed and Developed by: PromptTech-Solution</p>
|
||||
<p>
|
||||
Made with
|
||||
<i class="bi bi-heart-fill" style="color: var(--primary-pink)"></i>
|
||||
|
||||
@@ -25,10 +25,10 @@
|
||||
/>
|
||||
|
||||
<!-- Modern Theme CSS -->
|
||||
<link rel="stylesheet" href="/assets/css/modern-theme.css?v=fix33" />
|
||||
<link rel="stylesheet" href="/assets/css/modern-theme.css?v=fix35" />
|
||||
<link
|
||||
rel="stylesheet"
|
||||
href="/assets/css/mobile-fixes.css?v=20260118fix10"
|
||||
href="/assets/css/mobile-fixes.css?v=20260120fix2"
|
||||
/>
|
||||
|
||||
<style>
|
||||
@@ -671,7 +671,7 @@
|
||||
</div>
|
||||
|
||||
<div class="footer-bottom">
|
||||
<p>© 2026 Sky Art Shop. All rights reserved.</p>
|
||||
<p>© 2026 PromptTech-Solution. Designed and Developed by: PromptTech-Solution</p>
|
||||
<p>
|
||||
Made with
|
||||
<i class="bi bi-heart-fill" style="color: var(--primary-pink)"></i>
|
||||
@@ -835,16 +835,62 @@
|
||||
|
||||
document
|
||||
.getElementById("contactForm")
|
||||
.addEventListener("submit", function (e) {
|
||||
.addEventListener("submit", async function (e) {
|
||||
e.preventDefault();
|
||||
|
||||
// Show success notification
|
||||
SkyArtShop.showNotification(
|
||||
"Message sent successfully! We'll get back to you soon.",
|
||||
);
|
||||
const form = this;
|
||||
const submitBtn = form.querySelector('button[type="submit"]');
|
||||
const originalBtnText = submitBtn.innerHTML;
|
||||
|
||||
// Reset form
|
||||
this.reset();
|
||||
// Get form data
|
||||
const name = document.getElementById("name").value.trim();
|
||||
const email = document.getElementById("email").value.trim();
|
||||
const subject = document.getElementById("subject").value.trim();
|
||||
const message = document.getElementById("message").value.trim();
|
||||
|
||||
// Validation
|
||||
if (!name || !email || !subject || !message) {
|
||||
SkyArtShop.showNotification("Please fill in all fields.", "error");
|
||||
return;
|
||||
}
|
||||
|
||||
// Disable button and show loading
|
||||
submitBtn.disabled = true;
|
||||
submitBtn.innerHTML =
|
||||
'<i class="bi bi-hourglass-split"></i> Sending...';
|
||||
|
||||
try {
|
||||
const response = await fetch("/api/contact", {
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
body: JSON.stringify({ name, email, subject, message }),
|
||||
});
|
||||
|
||||
const data = await response.json();
|
||||
|
||||
if (data.success) {
|
||||
SkyArtShop.showNotification(
|
||||
data.message ||
|
||||
"Message sent successfully! We'll get back to you soon.",
|
||||
"success",
|
||||
);
|
||||
form.reset();
|
||||
} else {
|
||||
SkyArtShop.showNotification(
|
||||
data.message || "Failed to send message. Please try again.",
|
||||
"error",
|
||||
);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Contact form error:", error);
|
||||
SkyArtShop.showNotification(
|
||||
"Failed to send message. Please try again later.",
|
||||
"error",
|
||||
);
|
||||
} finally {
|
||||
submitBtn.disabled = false;
|
||||
submitBtn.innerHTML = originalBtnText;
|
||||
}
|
||||
});
|
||||
</script>
|
||||
<script src="/assets/js/accessibility.js"></script>
|
||||
|
||||
@@ -25,8 +25,8 @@
|
||||
/>
|
||||
|
||||
<!-- Modern Theme CSS -->
|
||||
<link rel="stylesheet" href="/assets/css/modern-theme.css?v=fix33" />
|
||||
<link rel="stylesheet" href="/assets/css/mobile-fixes.css?v=20260118c" />
|
||||
<link rel="stylesheet" href="/assets/css/modern-theme.css?v=fix35" />
|
||||
<link rel="stylesheet" href="/assets/css/mobile-fixes.css?v=20260120fix2" />
|
||||
|
||||
<style>
|
||||
.faq-container {
|
||||
@@ -252,7 +252,7 @@
|
||||
</div>
|
||||
|
||||
<div class="footer-bottom">
|
||||
<p>© 2026 Sky Art Shop. All rights reserved.</p>
|
||||
<p>© 2026 PromptTech-Solution. Designed and Developed by: PromptTech-Solution</p>
|
||||
<p>
|
||||
Made with
|
||||
<i class="bi bi-heart-fill" style="color: var(--primary-pink)"></i>
|
||||
|
||||
@@ -25,20 +25,59 @@
|
||||
/>
|
||||
|
||||
<!-- Modern Theme CSS -->
|
||||
<link rel="stylesheet" href="/assets/css/modern-theme.css?v=fix33" />
|
||||
<link
|
||||
rel="stylesheet"
|
||||
href="/assets/css/mobile-fixes.css?v=20260119touch"
|
||||
/>
|
||||
<link rel="stylesheet" href="/assets/css/modern-theme.css?v=fix35" />
|
||||
<link rel="stylesheet" href="/assets/css/mobile-fixes.css?v=20260120fix2" />
|
||||
|
||||
<style>
|
||||
/* Blog Grid for Get Inspired Section - Match Blog Page */
|
||||
/* Get Inspired Section - Black subtitle text */
|
||||
#get-inspired .section-subtitle {
|
||||
color: var(--text-primary) !important;
|
||||
}
|
||||
|
||||
/* Stay Connected Section - Black subtitle text */
|
||||
#newsletter-section .section-subtitle {
|
||||
color: var(--text-primary) !important;
|
||||
}
|
||||
|
||||
/* Blog Grid for Get Inspired Section - Horizontal Scroll */
|
||||
#inspirationGrid.blog-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
gap: var(--spacing-lg);
|
||||
max-width: 1100px;
|
||||
margin: 0 auto;
|
||||
display: flex !important;
|
||||
flex-wrap: nowrap !important;
|
||||
overflow-x: auto !important;
|
||||
overflow-y: hidden !important;
|
||||
scroll-behavior: smooth;
|
||||
-webkit-overflow-scrolling: touch;
|
||||
scroll-snap-type: x mandatory;
|
||||
gap: 20px;
|
||||
padding: 8px 0 16px 0;
|
||||
max-width: none;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
#inspirationGrid.blog-grid::-webkit-scrollbar {
|
||||
height: 8px;
|
||||
}
|
||||
|
||||
#inspirationGrid.blog-grid::-webkit-scrollbar-track {
|
||||
background: rgba(255, 255, 255, 0.5);
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
#inspirationGrid.blog-grid::-webkit-scrollbar-thumb {
|
||||
background: var(--primary-pink-dark, #fcb1d8);
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
#inspirationGrid.blog-grid::-webkit-scrollbar-thumb:hover {
|
||||
background: var(--primary-pink, #ffd0d0);
|
||||
}
|
||||
|
||||
/* Blog cards in horizontal scroll */
|
||||
#inspirationGrid.blog-grid .blog-card {
|
||||
flex: 0 0 320px;
|
||||
min-width: 320px;
|
||||
max-width: 320px;
|
||||
scroll-snap-align: start;
|
||||
}
|
||||
|
||||
/* Blog Card Styles for Get Inspired Section */
|
||||
@@ -157,15 +196,21 @@
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
/* Tablet - Blog cards horizontal scroll */
|
||||
@media (max-width: 992px) {
|
||||
#inspirationGrid.blog-grid {
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
#inspirationGrid.blog-grid .blog-card {
|
||||
flex: 0 0 280px;
|
||||
min-width: 280px;
|
||||
max-width: 280px;
|
||||
}
|
||||
}
|
||||
|
||||
/* Mobile - Blog cards horizontal scroll */
|
||||
@media (max-width: 576px) {
|
||||
#inspirationGrid.blog-grid {
|
||||
grid-template-columns: 1fr;
|
||||
#inspirationGrid.blog-grid .blog-card {
|
||||
flex: 0 0 240px;
|
||||
min-width: 240px;
|
||||
max-width: 240px;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -307,7 +352,7 @@
|
||||
<section
|
||||
class="section"
|
||||
id="featured-products"
|
||||
style="background: var(--primary-pink-light)"
|
||||
style="background: var(--primary-pink-light); padding: 30px 0"
|
||||
>
|
||||
<div class="container">
|
||||
<div class="section-header">
|
||||
@@ -336,7 +381,7 @@
|
||||
<section
|
||||
class="section inspiration-section"
|
||||
id="get-inspired"
|
||||
style="background: var(--accent-pink)"
|
||||
style="background: var(--accent-pink); padding: 30px 0"
|
||||
>
|
||||
<div class="container">
|
||||
<div class="section-header">
|
||||
@@ -362,10 +407,10 @@
|
||||
<section
|
||||
class="section"
|
||||
id="about-preview"
|
||||
style="background: var(--primary-pink-dark); padding: 0; margin: 0"
|
||||
style="background: var(--primary-pink-light); padding: 0; margin: 0"
|
||||
>
|
||||
<div class="container">
|
||||
<div class="about-content">
|
||||
<div class="about-content" style="padding: 10px 0">
|
||||
<div class="about-text">
|
||||
<h2 id="aboutTitle">About Sky Art Shop</h2>
|
||||
<div id="aboutDescription">
|
||||
@@ -407,13 +452,8 @@
|
||||
<!-- Newsletter -->
|
||||
<section
|
||||
class="section"
|
||||
style="
|
||||
background: linear-gradient(
|
||||
135deg,
|
||||
var(--primary-pink-light) 0%,
|
||||
var(--primary-pink) 100%
|
||||
);
|
||||
"
|
||||
id="newsletter-section"
|
||||
style="background: var(--accent-pink); padding: 40px 0"
|
||||
>
|
||||
<div class="container">
|
||||
<div class="text-center">
|
||||
@@ -424,11 +464,14 @@
|
||||
</p>
|
||||
<form
|
||||
class="newsletter-form"
|
||||
id="homeNewsletterForm"
|
||||
style="max-width: 500px; margin: 0 auto; display: flex; gap: 12px"
|
||||
>
|
||||
<input
|
||||
type="email"
|
||||
id="homeNewsletterEmail"
|
||||
placeholder="Enter your email"
|
||||
required
|
||||
style="
|
||||
flex: 1;
|
||||
padding: 16px 24px;
|
||||
@@ -437,7 +480,13 @@
|
||||
font-size: 1rem;
|
||||
"
|
||||
/>
|
||||
<button type="submit" class="btn btn-primary">Subscribe</button>
|
||||
<button
|
||||
type="submit"
|
||||
class="btn btn-primary"
|
||||
id="homeNewsletterBtn"
|
||||
>
|
||||
Subscribe
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
@@ -519,6 +568,10 @@
|
||||
><i class="bi bi-linkedin"></i
|
||||
></a>
|
||||
</div>
|
||||
<p style="margin-top: 12px; font-size: 0.85rem; opacity: 0.9">
|
||||
© 2026 PromptTech-Solution.<br />Designed and Developed by:
|
||||
PromptTech-Solution
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="footer-column">
|
||||
@@ -554,7 +607,7 @@
|
||||
</div>
|
||||
|
||||
<div class="footer-bottom">
|
||||
<p>© 2026 Sky Art Shop. All rights reserved.</p>
|
||||
<p>© 2026 PromptTech-Solution. Designed and Developed by: PromptTech-Solution</p>
|
||||
<p>
|
||||
Made with
|
||||
<i class="bi bi-heart-fill" style="color: var(--primary-pink)"></i>
|
||||
@@ -1010,6 +1063,61 @@
|
||||
heroSlider.innerHTML =
|
||||
slidesHtml + `<div class="slider-nav">${dotsHtml}</div>` + arrowsHtml;
|
||||
}
|
||||
|
||||
// Newsletter form handler
|
||||
document
|
||||
.getElementById("homeNewsletterForm")
|
||||
?.addEventListener("submit", async function (e) {
|
||||
e.preventDefault();
|
||||
|
||||
const emailInput = document.getElementById("homeNewsletterEmail");
|
||||
const submitBtn = document.getElementById("homeNewsletterBtn");
|
||||
const email = emailInput.value.trim();
|
||||
|
||||
if (!email) {
|
||||
SkyArtShop.showNotification(
|
||||
"Please enter your email address.",
|
||||
"error",
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
const originalBtnText = submitBtn.innerHTML;
|
||||
submitBtn.disabled = true;
|
||||
submitBtn.innerHTML = "Subscribing...";
|
||||
|
||||
try {
|
||||
const response = await fetch("/api/newsletter/subscribe", {
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
body: JSON.stringify({ email, source: "home" }),
|
||||
});
|
||||
|
||||
const data = await response.json();
|
||||
|
||||
if (data.success) {
|
||||
SkyArtShop.showNotification(
|
||||
data.message || "Successfully subscribed!",
|
||||
"success",
|
||||
);
|
||||
emailInput.value = "";
|
||||
} else {
|
||||
SkyArtShop.showNotification(
|
||||
data.message || "Failed to subscribe. Please try again.",
|
||||
"error",
|
||||
);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Newsletter error:", error);
|
||||
SkyArtShop.showNotification(
|
||||
"Failed to subscribe. Please try again later.",
|
||||
"error",
|
||||
);
|
||||
} finally {
|
||||
submitBtn.disabled = false;
|
||||
submitBtn.innerHTML = originalBtnText;
|
||||
}
|
||||
});
|
||||
</script>
|
||||
<script src="/assets/js/accessibility.js"></script>
|
||||
</body>
|
||||
|
||||
@@ -27,11 +27,11 @@
|
||||
<!-- Modern Theme CSS -->
|
||||
<link
|
||||
rel="stylesheet"
|
||||
href="/assets/css/modern-theme.css?v=fix33"
|
||||
href="/assets/css/modern-theme.css?v=fix35"
|
||||
/>
|
||||
<link
|
||||
rel="stylesheet"
|
||||
href="/assets/css/mobile-fixes.css?v=20260118fix10"
|
||||
href="/assets/css/mobile-fixes.css?v=20260120fix2"
|
||||
/>
|
||||
|
||||
<style>
|
||||
@@ -567,7 +567,7 @@
|
||||
</div>
|
||||
|
||||
<div class="footer-bottom">
|
||||
<p>© 2026 Sky Art Shop. All rights reserved.</p>
|
||||
<p>© 2026 PromptTech-Solution. Designed and Developed by: PromptTech-Solution</p>
|
||||
<p>
|
||||
Made with
|
||||
<i class="bi bi-heart-fill" style="color: var(--primary-pink)"></i>
|
||||
|
||||
@@ -22,8 +22,8 @@
|
||||
/>
|
||||
|
||||
<!-- Modern Theme CSS -->
|
||||
<link rel="stylesheet" href="/assets/css/modern-theme.css?v=fix33" />
|
||||
<link rel="stylesheet" href="/assets/css/mobile-fixes.css?v=fix32" />
|
||||
<link rel="stylesheet" href="/assets/css/modern-theme.css?v=fix35" />
|
||||
<link rel="stylesheet" href="/assets/css/mobile-fixes.css?v=20260120fix2" />
|
||||
|
||||
<style>
|
||||
.policy-container {
|
||||
@@ -278,7 +278,7 @@
|
||||
</div>
|
||||
|
||||
<div class="footer-bottom">
|
||||
<p>© 2026 Sky Art Shop. All rights reserved.</p>
|
||||
<p>© 2026 PromptTech-Solution. Designed and Developed by: PromptTech-Solution</p>
|
||||
<p>
|
||||
Made with
|
||||
<i class="bi bi-heart-fill" style="color: var(--primary-pink)"></i>
|
||||
|
||||
@@ -22,8 +22,8 @@
|
||||
/>
|
||||
|
||||
<!-- Modern Theme CSS -->
|
||||
<link rel="stylesheet" href="/assets/css/modern-theme.css?v=fix34" />
|
||||
<link rel="stylesheet" href="/assets/css/mobile-fixes.css?v=20260119fix3" />
|
||||
<link rel="stylesheet" href="/assets/css/modern-theme.css?v=fix35" />
|
||||
<link rel="stylesheet" href="/assets/css/mobile-fixes.css?v=20260120fix2" />
|
||||
|
||||
<style>
|
||||
/* Product page breadcrumb - force single line */
|
||||
@@ -121,6 +121,64 @@
|
||||
}
|
||||
}
|
||||
|
||||
/* Tablet: iPad, iPad Air, iPad Pro (768px - 1024px) */
|
||||
@media (min-width: 769px) and (max-width: 1024px) {
|
||||
.product-detail {
|
||||
display: grid !important;
|
||||
grid-template-columns: 1fr 1fr !important;
|
||||
gap: var(--spacing-xl) !important;
|
||||
width: 100% !important;
|
||||
max-width: 100% !important;
|
||||
box-sizing: border-box !important;
|
||||
}
|
||||
|
||||
.product-gallery {
|
||||
position: relative !important;
|
||||
width: 100% !important;
|
||||
max-width: 100% !important;
|
||||
overflow: hidden !important;
|
||||
}
|
||||
|
||||
.main-image {
|
||||
position: relative !important;
|
||||
width: 100% !important;
|
||||
max-width: 100% !important;
|
||||
height: 0 !important;
|
||||
padding-bottom: 100% !important;
|
||||
overflow: hidden !important;
|
||||
border-radius: var(--radius-lg) !important;
|
||||
background: #ffffff !important;
|
||||
}
|
||||
|
||||
.main-image img {
|
||||
position: absolute !important;
|
||||
top: 0 !important;
|
||||
left: 0 !important;
|
||||
width: 100% !important;
|
||||
height: 100% !important;
|
||||
object-fit: cover !important;
|
||||
object-position: center !important;
|
||||
}
|
||||
|
||||
.product-details {
|
||||
width: 100% !important;
|
||||
max-width: 100% !important;
|
||||
box-sizing: border-box !important;
|
||||
}
|
||||
|
||||
.product-details h1,
|
||||
#productName {
|
||||
font-size: 1.5rem !important;
|
||||
word-break: break-word !important;
|
||||
overflow-wrap: break-word !important;
|
||||
}
|
||||
|
||||
.container {
|
||||
max-width: 100% !important;
|
||||
overflow-x: hidden !important;
|
||||
}
|
||||
}
|
||||
|
||||
.product-detail {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
@@ -134,8 +192,11 @@
|
||||
}
|
||||
|
||||
.main-image {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
aspect-ratio: 1;
|
||||
max-width: 100%;
|
||||
height: 0;
|
||||
padding-bottom: 100%; /* 1:1 aspect ratio */
|
||||
border-radius: var(--radius-lg);
|
||||
overflow: hidden;
|
||||
background: var(--bg-white);
|
||||
@@ -143,12 +204,79 @@
|
||||
}
|
||||
|
||||
.main-image img {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
object-position: center;
|
||||
transition: var(--transition-smooth);
|
||||
}
|
||||
|
||||
/* Gallery Navigation Arrows */
|
||||
.gallery-arrow {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
width: 44px;
|
||||
height: 44px;
|
||||
background: rgba(255, 255, 255, 0.9);
|
||||
border: none;
|
||||
border-radius: 50%;
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 1.2rem;
|
||||
color: var(--text-primary);
|
||||
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.15);
|
||||
transition: all 0.2s ease;
|
||||
z-index: 10;
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.main-image:hover .gallery-arrow {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.gallery-arrow:hover {
|
||||
background: white;
|
||||
box-shadow: 0 4px 15px rgba(0, 0, 0, 0.2);
|
||||
transform: translateY(-50%) scale(1.1);
|
||||
}
|
||||
|
||||
.gallery-arrow.prev {
|
||||
left: 12px;
|
||||
}
|
||||
|
||||
.gallery-arrow.next {
|
||||
right: 12px;
|
||||
}
|
||||
|
||||
.gallery-arrow:disabled {
|
||||
opacity: 0.3;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
/* Mobile: always show arrows */
|
||||
@media (max-width: 768px) {
|
||||
.gallery-arrow {
|
||||
opacity: 1;
|
||||
width: 36px;
|
||||
height: 36px;
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
.gallery-arrow.prev {
|
||||
left: 8px;
|
||||
}
|
||||
|
||||
.gallery-arrow.next {
|
||||
right: 8px;
|
||||
}
|
||||
}
|
||||
|
||||
.thumbnail-gallery {
|
||||
display: flex;
|
||||
gap: var(--spacing-sm);
|
||||
@@ -679,11 +807,25 @@
|
||||
<!-- Gallery -->
|
||||
<div class="product-gallery">
|
||||
<div class="main-image">
|
||||
<button
|
||||
class="gallery-arrow prev"
|
||||
id="galleryPrev"
|
||||
aria-label="Previous image"
|
||||
>
|
||||
<i class="bi bi-chevron-left"></i>
|
||||
</button>
|
||||
<img
|
||||
src="https://images.unsplash.com/photo-1513519245088-0e12902e35a6?w=800&q=80"
|
||||
alt="Product"
|
||||
id="mainImage"
|
||||
/>
|
||||
<button
|
||||
class="gallery-arrow next"
|
||||
id="galleryNext"
|
||||
aria-label="Next image"
|
||||
>
|
||||
<i class="bi bi-chevron-right"></i>
|
||||
</button>
|
||||
</div>
|
||||
<div class="thumbnail-gallery" id="thumbnailGallery">
|
||||
<!-- Thumbnails loaded via JS -->
|
||||
@@ -939,7 +1081,10 @@
|
||||
</div>
|
||||
|
||||
<div class="footer-bottom">
|
||||
<p>© 2026 Sky Art Shop. All rights reserved.</p>
|
||||
<p>
|
||||
© 2026 PromptTech-Solution. Designed and Developed by:
|
||||
PromptTech-Solution
|
||||
</p>
|
||||
<p>
|
||||
Made with
|
||||
<i class="bi bi-heart-fill" style="color: var(--primary-pink)"></i>
|
||||
@@ -1260,8 +1405,76 @@
|
||||
.forEach((t) => t.classList.remove("active"));
|
||||
thumb.classList.add("active");
|
||||
mainImage.src = thumb.dataset.image;
|
||||
updateArrowState();
|
||||
});
|
||||
});
|
||||
|
||||
// Gallery arrow navigation
|
||||
let currentImageIndex = 0;
|
||||
const galleryPrev = document.getElementById("galleryPrev");
|
||||
const galleryNext = document.getElementById("galleryNext");
|
||||
|
||||
function updateArrowState() {
|
||||
const thumbnails = thumbnailGallery.querySelectorAll(".thumbnail");
|
||||
thumbnails.forEach((thumb, index) => {
|
||||
if (thumb.classList.contains("active")) {
|
||||
currentImageIndex = index;
|
||||
}
|
||||
});
|
||||
|
||||
// Update button states
|
||||
if (galleryPrev) galleryPrev.disabled = currentImageIndex === 0;
|
||||
if (galleryNext)
|
||||
galleryNext.disabled =
|
||||
currentImageIndex === thumbnails.length - 1;
|
||||
|
||||
// Hide arrows if only one image
|
||||
if (thumbnails.length <= 1) {
|
||||
if (galleryPrev) galleryPrev.style.display = "none";
|
||||
if (galleryNext) galleryNext.style.display = "none";
|
||||
}
|
||||
}
|
||||
|
||||
function navigateGallery(direction) {
|
||||
const thumbnails = thumbnailGallery.querySelectorAll(".thumbnail");
|
||||
if (thumbnails.length === 0) return;
|
||||
|
||||
currentImageIndex += direction;
|
||||
if (currentImageIndex < 0) currentImageIndex = 0;
|
||||
if (currentImageIndex >= thumbnails.length)
|
||||
currentImageIndex = thumbnails.length - 1;
|
||||
|
||||
const targetThumb = thumbnails[currentImageIndex];
|
||||
thumbnails.forEach((t) => t.classList.remove("active"));
|
||||
targetThumb.classList.add("active");
|
||||
mainImage.src = targetThumb.dataset.image;
|
||||
|
||||
// Scroll thumbnail into view
|
||||
targetThumb.scrollIntoView({
|
||||
behavior: "smooth",
|
||||
block: "nearest",
|
||||
inline: "center",
|
||||
});
|
||||
|
||||
updateArrowState();
|
||||
}
|
||||
|
||||
if (galleryPrev) {
|
||||
galleryPrev.addEventListener("click", (e) => {
|
||||
e.preventDefault();
|
||||
navigateGallery(-1);
|
||||
});
|
||||
}
|
||||
|
||||
if (galleryNext) {
|
||||
galleryNext.addEventListener("click", (e) => {
|
||||
e.preventDefault();
|
||||
navigateGallery(1);
|
||||
});
|
||||
}
|
||||
|
||||
// Initialize arrow state
|
||||
updateArrowState();
|
||||
}
|
||||
|
||||
// Color options
|
||||
|
||||
@@ -25,8 +25,8 @@
|
||||
/>
|
||||
|
||||
<!-- Modern Theme CSS -->
|
||||
<link rel="stylesheet" href="/assets/css/modern-theme.css?v=fix33" />
|
||||
<link rel="stylesheet" href="/assets/css/mobile-fixes.css?v=fix32" />
|
||||
<link rel="stylesheet" href="/assets/css/modern-theme.css?v=fix35" />
|
||||
<link rel="stylesheet" href="/assets/css/mobile-fixes.css?v=20260120fix2" />
|
||||
|
||||
<style>
|
||||
.policy-container {
|
||||
@@ -292,7 +292,7 @@
|
||||
</div>
|
||||
|
||||
<div class="footer-bottom">
|
||||
<p>© 2026 Sky Art Shop. All rights reserved.</p>
|
||||
<p>© 2026 PromptTech-Solution. Designed and Developed by: PromptTech-Solution</p>
|
||||
<p>
|
||||
Made with
|
||||
<i class="bi bi-heart-fill" style="color: var(--primary-pink)"></i>
|
||||
|
||||
@@ -22,8 +22,8 @@
|
||||
/>
|
||||
|
||||
<!-- Modern Theme CSS -->
|
||||
<link rel="stylesheet" href="/assets/css/modern-theme.css?v=fix33" />
|
||||
<link rel="stylesheet" href="/assets/css/mobile-fixes.css?v=fix32" />
|
||||
<link rel="stylesheet" href="/assets/css/modern-theme.css?v=fix35" />
|
||||
<link rel="stylesheet" href="/assets/css/mobile-fixes.css?v=20260120fix2" />
|
||||
|
||||
<style>
|
||||
.policy-container {
|
||||
@@ -331,7 +331,7 @@
|
||||
</div>
|
||||
|
||||
<div class="footer-bottom">
|
||||
<p>© 2026 Sky Art Shop. All rights reserved.</p>
|
||||
<p>© 2026 PromptTech-Solution. Designed and Developed by: PromptTech-Solution</p>
|
||||
<p>
|
||||
Made with
|
||||
<i class="bi bi-heart-fill" style="color: var(--primary-pink)"></i>
|
||||
|
||||
@@ -22,8 +22,8 @@
|
||||
/>
|
||||
|
||||
<!-- Modern Theme CSS -->
|
||||
<link rel="stylesheet" href="/assets/css/modern-theme.css?v=fix34" />
|
||||
<link rel="stylesheet" href="/assets/css/mobile-fixes.css?v=20260119fix1" />
|
||||
<link rel="stylesheet" href="/assets/css/modern-theme.css?v=fix35" />
|
||||
<link rel="stylesheet" href="/assets/css/mobile-fixes.css?v=20260120fix2" />
|
||||
<style>
|
||||
/* Mobile & Tablet: Shop page layout fixes */
|
||||
@media (max-width: 992px) {
|
||||
@@ -541,7 +541,10 @@
|
||||
</div>
|
||||
|
||||
<div class="footer-bottom">
|
||||
<p>© 2026 Sky Art Shop. All rights reserved.</p>
|
||||
<p>
|
||||
© 2026 PromptTech-Solution. Designed and Developed by:
|
||||
PromptTech-Solution
|
||||
</p>
|
||||
<p>
|
||||
Made with
|
||||
<i class="bi bi-heart-fill" style="color: var(--primary-pink)"></i>
|
||||
|
||||
Reference in New Issue
Block a user