mirror of
https://git.kh3group.com/georgebiri/khy_website.git
synced 2026-10-16 22:51:47 +00:00
Compare commits
6 commits
195286e6c8
...
8c42edd511
| Author | SHA1 | Date | |
|---|---|---|---|
| 8c42edd511 | |||
| a648abe2d0 | |||
| 18cf5c8ed3 | |||
| 6caa3ee6c4 | |||
| d84c6196d1 | |||
| 7295bcba7e |
7 changed files with 1620 additions and 1566 deletions
BIN
assets/images/prod-catalog.jpg
Normal file
BIN
assets/images/prod-catalog.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 417 KiB |
1646
data/products.json
1646
data/products.json
File diff suppressed because it is too large
Load diff
|
|
@ -164,7 +164,7 @@
|
||||||
<!-- Background Image -->
|
<!-- Background Image -->
|
||||||
<div class="absolute inset-0 w-full h-full">
|
<div class="absolute inset-0 w-full h-full">
|
||||||
<img
|
<img
|
||||||
src="assets/images/potty.jpg"
|
src="assets/images/prod-catalog.jpg"
|
||||||
alt="Product catalog background"
|
alt="Product catalog background"
|
||||||
class="w-full h-full object-cover object-center"
|
class="w-full h-full object-cover object-center"
|
||||||
style="filter: blur(3px)"
|
style="filter: blur(3px)"
|
||||||
|
|
|
||||||
|
|
@ -194,71 +194,33 @@
|
||||||
<div
|
<div
|
||||||
class="flex flex-row md:flex-col gap-3 md:gap-4 w-full md:w-32 overflow-x-auto md:overflow-visible"
|
class="flex flex-row md:flex-col gap-3 md:gap-4 w-full md:w-32 overflow-x-auto md:overflow-visible"
|
||||||
>
|
>
|
||||||
<div
|
<!-- Thumbnail images will be populated dynamically -->
|
||||||
class="w-32 h-32 bg-floral-white rounded-lg overflow-hidden cursor-pointer"
|
|
||||||
>
|
|
||||||
<img
|
|
||||||
src="assets/images/outdoor_sofa_set.png"
|
|
||||||
alt="Outdoor sofa set"
|
|
||||||
class="w-full h-full object-cover"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
class="w-32 h-32 bg-floral-white rounded-lg overflow-hidden cursor-pointer"
|
|
||||||
>
|
|
||||||
<img
|
|
||||||
src="assets/images/outdoor_sofa_set.png"
|
|
||||||
alt="Outdoor sofa set 2"
|
|
||||||
class="w-full h-full object-cover"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
class="w-32 h-32 bg-floral-white rounded-lg overflow-hidden cursor-pointer"
|
|
||||||
>
|
|
||||||
<img
|
|
||||||
src="assets/images/outdoor_sofa_set.png"
|
|
||||||
alt="Stuart sofa"
|
|
||||||
class="w-full h-full object-cover"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
class="w-32 h-32 bg-floral-white rounded-lg overflow-hidden cursor-pointer"
|
|
||||||
>
|
|
||||||
<img
|
|
||||||
src="assets/images/outdoor_sofa_set.png"
|
|
||||||
alt="Maya sofa three seater"
|
|
||||||
class="w-full h-full object-cover"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Main Product Image -->
|
<!-- Main Product Image -->
|
||||||
<div
|
<div
|
||||||
class="w-full h-80 md:w-[500px] md:h-[500px] bg-floral-white rounded-lg overflow-hidden"
|
class="w-full h-80 md:w-[500px] md:h-[500px] bg-floral-white rounded-lg overflow-hidden"
|
||||||
>
|
>
|
||||||
<img
|
<!-- Main product image will be populated dynamically -->
|
||||||
src="assets/images/asgaard_sofa.png"
|
|
||||||
alt="Asgaard sofa"
|
|
||||||
class="w-full h-full object-cover"
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Right Section - Product Details -->
|
<!-- Right Section - Product Details -->
|
||||||
<div class="w-full md:w-[500px]">
|
<div class="w-full md:w-[500px]">
|
||||||
<!-- Product Title -->
|
<!-- Product Title -->
|
||||||
<h1 class="font-playfair font-normal text-4xl text-black mb-8">
|
<h1
|
||||||
Asgaard sofa
|
class="font-playfair font-normal text-4xl text-black mb-8"
|
||||||
|
id="product-title"
|
||||||
|
>
|
||||||
|
<!-- Product title will be populated dynamically -->
|
||||||
</h1>
|
</h1>
|
||||||
|
|
||||||
<!-- Product Description -->
|
<!-- Product Description -->
|
||||||
<p
|
<p
|
||||||
class="font-playfair font-normal text-sm text-black mb-12 max-w-md"
|
class="font-playfair font-normal text-sm text-black mb-12 max-w-md"
|
||||||
|
id="product-description"
|
||||||
>
|
>
|
||||||
Setting the bar as one of the loudest speakers in its class, the
|
<!-- Product description will be populated dynamically -->
|
||||||
Kilburn is a compact, stout-hearted hero with a well-balanced
|
|
||||||
audio which boasts a clear midrange and extended highs for a
|
|
||||||
sound.
|
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<!-- Size Options -->
|
<!-- Size Options -->
|
||||||
|
|
@ -269,36 +231,7 @@
|
||||||
Size
|
Size
|
||||||
</h3>
|
</h3>
|
||||||
<div class="grid grid-cols-6 gap-2" id="size-buttons-container">
|
<div class="grid grid-cols-6 gap-2" id="size-buttons-container">
|
||||||
<button
|
<!-- Size buttons will be populated dynamically -->
|
||||||
class="w-8 h-8 bg-uc-gold text-white font-playfair font-normal text-sm rounded flex items-center justify-center size-button"
|
|
||||||
>
|
|
||||||
L
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
class="w-8 h-8 bg-floral-white text-black font-playfair font-normal text-sm rounded flex items-center justify-center size-button"
|
|
||||||
>
|
|
||||||
XL
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
class="w-8 h-8 bg-floral-white text-black font-playfair font-normal text-sm rounded flex items-center justify-center size-button"
|
|
||||||
>
|
|
||||||
XS
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
class="w-8 h-8 bg-floral-white text-black font-playfair font-normal text-sm rounded flex items-center justify-center size-button"
|
|
||||||
>
|
|
||||||
S
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
class="w-8 h-8 bg-floral-white text-black font-playfair font-normal text-sm rounded flex items-center justify-center size-button"
|
|
||||||
>
|
|
||||||
M
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
class="w-8 h-8 bg-floral-white text-black font-playfair font-normal text-sm rounded flex items-center justify-center size-button"
|
|
||||||
>
|
|
||||||
2XL
|
|
||||||
</button>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
@ -309,42 +242,13 @@
|
||||||
>
|
>
|
||||||
Color
|
Color
|
||||||
</h3>
|
</h3>
|
||||||
<div class="flex gap-4">
|
<div class="flex gap-4" id="color-buttons-container">
|
||||||
<button
|
<!-- Color buttons will be populated dynamically -->
|
||||||
class="w-8 h-8 bg-purple-500 rounded-full border-2 border-black"
|
|
||||||
></button>
|
|
||||||
<button class="w-8 h-8 bg-black rounded-full"></button>
|
|
||||||
<button class="w-8 h-8 bg-uc-gold rounded-full"></button>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Quantity and Action Buttons -->
|
<!-- Quantity and Action Buttons -->
|
||||||
<div class="flex flex-col md:flex-row gap-4 md:gap-6 mb-8">
|
<div class="flex flex-col md:flex-row gap-4 md:gap-6 mb-8">
|
||||||
<!-- Quantity Selector -->
|
|
||||||
<div
|
|
||||||
class="inline-flex items-center justify-between w-[180px] h-[64px] min-h-[64px] bg-white border border-quick-silver rounded-[15px] px-4 box-border shadow-sm hover:shadow-md transition-all duration-200"
|
|
||||||
>
|
|
||||||
<button
|
|
||||||
id="qty-decr"
|
|
||||||
aria-label="Decrease quantity"
|
|
||||||
class="font-playfair font-light text-[20px] leading-none text-black w-8 h-8 flex items-center justify-center rounded-lg hover:bg-light-bg transition-colors cursor-pointer"
|
|
||||||
>
|
|
||||||
-
|
|
||||||
</button>
|
|
||||||
<span
|
|
||||||
id="qty-value"
|
|
||||||
class="font-playfair font-light text-[20px] leading-none text-black"
|
|
||||||
>1</span
|
|
||||||
>
|
|
||||||
<button
|
|
||||||
id="qty-incr"
|
|
||||||
aria-label="Increase quantity"
|
|
||||||
class="font-playfair font-light text-[20px] leading-none text-black w-8 h-8 flex items-center justify-center rounded-lg hover:bg-light-bg transition-colors cursor-pointer"
|
|
||||||
>
|
|
||||||
+
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Action Buttons -->
|
<!-- Action Buttons -->
|
||||||
<a
|
<a
|
||||||
href="contact.html"
|
href="contact.html"
|
||||||
|
|
@ -365,62 +269,7 @@
|
||||||
|
|
||||||
<!-- Product Metadata -->
|
<!-- Product Metadata -->
|
||||||
<div class="space-y-4">
|
<div class="space-y-4">
|
||||||
<div class="flex items-center">
|
<!-- Product metadata will be populated dynamically -->
|
||||||
<span
|
|
||||||
class="font-playfair font-normal text-base text-quick-silver w-20"
|
|
||||||
>Model No.</span
|
|
||||||
>
|
|
||||||
<span
|
|
||||||
class="font-playfair font-medium text-base text-quick-silver mx-2"
|
|
||||||
>:</span
|
|
||||||
>
|
|
||||||
<span
|
|
||||||
class="font-playfair font-normal text-base text-quick-silver"
|
|
||||||
>SS001</span
|
|
||||||
>
|
|
||||||
</div>
|
|
||||||
<div class="flex items-center">
|
|
||||||
<span
|
|
||||||
class="font-playfair font-normal text-base text-quick-silver w-20"
|
|
||||||
>Category</span
|
|
||||||
>
|
|
||||||
<span
|
|
||||||
class="font-playfair font-medium text-base text-quick-silver mx-2"
|
|
||||||
>:</span
|
|
||||||
>
|
|
||||||
<span
|
|
||||||
class="font-playfair font-normal text-base text-quick-silver"
|
|
||||||
>Sofas</span
|
|
||||||
>
|
|
||||||
</div>
|
|
||||||
<div class="flex items-center">
|
|
||||||
<span
|
|
||||||
class="font-playfair font-normal text-base text-quick-silver w-20"
|
|
||||||
>Tags</span
|
|
||||||
>
|
|
||||||
<span
|
|
||||||
class="font-playfair font-medium text-base text-quick-silver mx-2"
|
|
||||||
>:</span
|
|
||||||
>
|
|
||||||
<span
|
|
||||||
class="font-playfair font-normal text-base text-quick-silver"
|
|
||||||
>Sofa, Chair, Home, Shop</span
|
|
||||||
>
|
|
||||||
</div>
|
|
||||||
<div class="flex items-center">
|
|
||||||
<span
|
|
||||||
class="font-playfair font-normal text-base text-quick-silver w-20"
|
|
||||||
>Dimension</span
|
|
||||||
>
|
|
||||||
<span
|
|
||||||
class="font-playfair font-medium text-base text-quick-silver mx-2"
|
|
||||||
>:</span
|
|
||||||
>
|
|
||||||
<span
|
|
||||||
class="font-playfair font-normal text-base text-quick-silver"
|
|
||||||
>180cm x 85cm x 75cm</span
|
|
||||||
>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -439,45 +288,61 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Copy -->
|
<!-- Copy -->
|
||||||
<div class="max-w-5xl mx-auto space-y-6">
|
<div
|
||||||
<p
|
class="max-w-5xl mx-auto space-y-6"
|
||||||
class="font-playfair text-base leading-6 text-[#333333] text-justify"
|
id="product-description-content"
|
||||||
>
|
>
|
||||||
Embodying the raw, wayward spirit of rock ‘n’ roll, the Kilburn
|
<!-- Product description content will be populated dynamically -->
|
||||||
portable active stereo speaker takes the unmistakable look and
|
|
||||||
sound of Marshall, unplugs the chords, and takes the show on the
|
|
||||||
road.
|
|
||||||
</p>
|
|
||||||
<p
|
|
||||||
class="font-playfair text-base leading-6 text-[#333333] text-justify"
|
|
||||||
>
|
|
||||||
Weighing in under 7 pounds, the Kilburn is a lightweight piece of
|
|
||||||
vintage styled engineering. Setting the bar as one of the loudest
|
|
||||||
speakers in its class, the Kilburn is a compact, stout-hearted
|
|
||||||
hero with a well-balanced audio which boasts a clear midrange and
|
|
||||||
extended highs for a sound that is both articulate and pronounced.
|
|
||||||
The analogue knobs allow you to fine tune the controls to your
|
|
||||||
personal preferences while the guitar-influenced leather strap
|
|
||||||
enables easy and stylish travel.
|
|
||||||
</p>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Images -->
|
<!-- Images -->
|
||||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-8 mt-10">
|
<div class="relative mt-10">
|
||||||
<div class="rounded-[10px] bg-floral-white p-6">
|
<div
|
||||||
<img
|
class="grid grid-cols-1 md:grid-cols-2 gap-8"
|
||||||
src="assets/images/asgaard_sofa.png"
|
id="product-gallery-images"
|
||||||
alt="Sofa variant left"
|
>
|
||||||
class="w-full h-80 object-contain mx-auto"
|
<!-- Product gallery images will be populated dynamically -->
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div class="rounded-[10px] bg-floral-white p-6">
|
|
||||||
<img
|
|
||||||
src="assets/images/asgaard_sofa.png"
|
|
||||||
alt="Sofa variant right"
|
|
||||||
class="w-full h-80 object-contain mx-auto"
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
|
<!-- Back Arrow -->
|
||||||
|
<button
|
||||||
|
id="gallery-back-btn"
|
||||||
|
class="absolute top-1/2 left-0 transform -translate-y-1/2 bg-white border border-gray-300 rounded-full p-3 shadow-lg hover:shadow-xl transition-all duration-200 opacity-0 pointer-events-none"
|
||||||
|
style="display: none"
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
class="w-6 h-6 text-gray-600"
|
||||||
|
fill="none"
|
||||||
|
stroke="currentColor"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round"
|
||||||
|
stroke-width="2"
|
||||||
|
d="M15 19l-7-7 7-7"
|
||||||
|
></path>
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
<!-- Forward Arrow -->
|
||||||
|
<button
|
||||||
|
id="gallery-next-btn"
|
||||||
|
class="absolute top-1/2 right-0 transform -translate-y-1/2 bg-white border border-gray-300 rounded-full p-3 shadow-lg hover:shadow-xl transition-all duration-200 opacity-0 pointer-events-none"
|
||||||
|
style="display: none"
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
class="w-6 h-6 text-gray-600"
|
||||||
|
fill="none"
|
||||||
|
stroke="currentColor"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round"
|
||||||
|
stroke-width="2"
|
||||||
|
d="M9 5l7 7-7 7"
|
||||||
|
></path>
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
@ -648,6 +513,45 @@
|
||||||
</div>
|
</div>
|
||||||
</footer>
|
</footer>
|
||||||
|
|
||||||
|
<!-- Image Enlargement Modal -->
|
||||||
|
<div
|
||||||
|
id="image-modal"
|
||||||
|
class="fixed inset-0 bg-black bg-opacity-90 z-50 hidden flex items-center justify-center p-4 transition-opacity duration-300"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="relative max-w-7xl max-h-full w-full h-full flex items-center justify-center"
|
||||||
|
>
|
||||||
|
<!-- Close Button -->
|
||||||
|
<button
|
||||||
|
id="modal-close-btn"
|
||||||
|
class="absolute top-4 right-4 z-10 bg-white bg-opacity-20 hover:bg-opacity-30 text-white rounded-full p-3 transition-all duration-200 backdrop-blur-sm"
|
||||||
|
aria-label="Close modal"
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
class="w-6 h-6"
|
||||||
|
fill="none"
|
||||||
|
stroke="currentColor"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round"
|
||||||
|
stroke-width="2"
|
||||||
|
d="M6 18L18 6M6 6l12 12"
|
||||||
|
></path>
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<!-- Enlarged Image -->
|
||||||
|
<img
|
||||||
|
id="modal-image"
|
||||||
|
src=""
|
||||||
|
alt=""
|
||||||
|
class="w-[95vw] h-[95vh] object-contain rounded-lg shadow-2xl transform transition-transform duration-300 scale-95"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<script src="scripts/main.js?v=3.5"></script>
|
<script src="scripts/main.js?v=3.5"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
||||||
608
scripts/main.js
608
scripts/main.js
|
|
@ -55,27 +55,6 @@ function initSite() {
|
||||||
window.addEventListener("scroll", updateActiveLink);
|
window.addEventListener("scroll", updateActiveLink);
|
||||||
updateActiveLink();
|
updateActiveLink();
|
||||||
|
|
||||||
// Quantity controls on product detail page
|
|
||||||
(function initQuantityControls() {
|
|
||||||
const decr = document.getElementById("qty-decr");
|
|
||||||
const incr = document.getElementById("qty-incr");
|
|
||||||
const valueEl = document.getElementById("qty-value");
|
|
||||||
if (!decr || !incr || !valueEl) return; // Not on product detail page
|
|
||||||
|
|
||||||
function parseQty() {
|
|
||||||
const n = parseInt(valueEl.textContent || "1", 10);
|
|
||||||
return Number.isFinite(n) && n > 0 ? n : 1;
|
|
||||||
}
|
|
||||||
decr.addEventListener("click", () => {
|
|
||||||
const next = Math.max(1, parseQty() - 1);
|
|
||||||
valueEl.textContent = String(next);
|
|
||||||
});
|
|
||||||
incr.addEventListener("click", () => {
|
|
||||||
const next = parseQty() + 1;
|
|
||||||
valueEl.textContent = String(next);
|
|
||||||
});
|
|
||||||
})();
|
|
||||||
|
|
||||||
// Related products (dynamic)
|
// Related products (dynamic)
|
||||||
(async function initRelated() {
|
(async function initRelated() {
|
||||||
const grid = document.getElementById("related-grid");
|
const grid = document.getElementById("related-grid");
|
||||||
|
|
@ -222,10 +201,143 @@ function initSite() {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Product detail page functionality
|
// Image enlargement modal functionality (global)
|
||||||
(async function initProductDetail() {
|
function addImageEnlargementListeners() {
|
||||||
|
// Target both main product image AND gallery carousel images
|
||||||
|
const mainProductImage = document.querySelector(
|
||||||
|
".w-full.h-80.md\\:w-\\[500px\\].md\\:h-\\[500px\\] img[data-enlarge-src]"
|
||||||
|
);
|
||||||
|
const galleryImages = document.querySelectorAll(
|
||||||
|
"#product-gallery-images img[data-enlarge-src]"
|
||||||
|
);
|
||||||
|
const modal = document.getElementById("image-modal");
|
||||||
|
const modalImage = document.getElementById("modal-image");
|
||||||
|
const modalCloseBtn = document.getElementById("modal-close-btn");
|
||||||
|
|
||||||
|
console.log("Adding image enlargement listeners...");
|
||||||
|
console.log("Found main product image:", !!mainProductImage);
|
||||||
|
console.log("Found gallery images:", galleryImages.length);
|
||||||
|
console.log("Modal elements:", {
|
||||||
|
modal: !!modal,
|
||||||
|
modalImage: !!modalImage,
|
||||||
|
modalCloseBtn: !!modalCloseBtn,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!modal || !modalImage || !modalCloseBtn) {
|
||||||
|
console.log("Modal elements not found, skipping image enlargement setup");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add click listener to main product image
|
||||||
|
if (mainProductImage) {
|
||||||
|
console.log(
|
||||||
|
`Adding click listener to main product image:`,
|
||||||
|
mainProductImage.src
|
||||||
|
);
|
||||||
|
mainProductImage.removeEventListener("click", handleImageClick);
|
||||||
|
mainProductImage.addEventListener("click", handleImageClick);
|
||||||
|
} else {
|
||||||
|
console.log("Main product image not found");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add click listeners to gallery carousel images
|
||||||
|
galleryImages.forEach((img, index) => {
|
||||||
|
console.log(
|
||||||
|
`Adding click listener to gallery image ${index + 1}:`,
|
||||||
|
img.src
|
||||||
|
);
|
||||||
|
img.removeEventListener("click", handleImageClick);
|
||||||
|
img.addEventListener("click", handleImageClick);
|
||||||
|
});
|
||||||
|
|
||||||
|
function handleImageClick(e) {
|
||||||
|
console.log("Image clicked!", this.src);
|
||||||
|
const imageSrc = this.getAttribute("data-enlarge-src");
|
||||||
|
const imageAlt = this.getAttribute("alt");
|
||||||
|
|
||||||
|
console.log("Opening modal with image:", imageSrc);
|
||||||
|
modalImage.src = imageSrc;
|
||||||
|
modalImage.alt = imageAlt;
|
||||||
|
|
||||||
|
// Show modal with animation
|
||||||
|
modal.classList.remove("hidden");
|
||||||
|
document.body.style.overflow = "hidden"; // Prevent background scrolling
|
||||||
|
|
||||||
|
// Trigger animation after a brief delay
|
||||||
|
setTimeout(() => {
|
||||||
|
modalImage.classList.remove("scale-95");
|
||||||
|
modalImage.classList.add("scale-100");
|
||||||
|
}, 10);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Close modal functionality
|
||||||
|
function closeModal() {
|
||||||
|
// Animate out
|
||||||
|
modalImage.classList.remove("scale-100");
|
||||||
|
modalImage.classList.add("scale-95");
|
||||||
|
|
||||||
|
// Hide modal after animation
|
||||||
|
setTimeout(() => {
|
||||||
|
modal.classList.add("hidden");
|
||||||
|
document.body.style.overflow = ""; // Restore scrolling
|
||||||
|
}, 300);
|
||||||
|
}
|
||||||
|
|
||||||
|
modalCloseBtn.addEventListener("click", closeModal);
|
||||||
|
|
||||||
|
// Close modal when clicking outside the image
|
||||||
|
modal.addEventListener("click", function (e) {
|
||||||
|
if (e.target === modal) {
|
||||||
|
closeModal();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Close modal with Escape key
|
||||||
|
document.addEventListener("keydown", function (e) {
|
||||||
|
if (e.key === "Escape" && !modal.classList.contains("hidden")) {
|
||||||
|
closeModal();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Thumbnail click functionality (global)
|
||||||
|
function addThumbnailClickListeners() {
|
||||||
|
const thumbnails = document.querySelectorAll("[data-thumbnail-src]");
|
||||||
|
const mainImageContainer = document.querySelector(
|
||||||
|
".w-full.h-80.md\\:w-\\[500px\\].md\\:h-\\[500px\\]"
|
||||||
|
);
|
||||||
|
|
||||||
|
console.log("Adding thumbnail click listeners...");
|
||||||
|
console.log("Found thumbnails:", thumbnails.length);
|
||||||
|
console.log("Main image container:", !!mainImageContainer);
|
||||||
|
|
||||||
|
if (!mainImageContainer) {
|
||||||
|
console.log("Main image container not found");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
thumbnails.forEach((thumbnail, index) => {
|
||||||
|
thumbnail.addEventListener("click", function () {
|
||||||
|
const imageSrc = this.getAttribute("data-thumbnail-src");
|
||||||
|
console.log(`Thumbnail ${index + 1} clicked, switching to:`, imageSrc);
|
||||||
|
|
||||||
|
// Update the main product image
|
||||||
|
const mainImg = mainImageContainer.querySelector("img");
|
||||||
|
if (mainImg) {
|
||||||
|
mainImg.src = imageSrc;
|
||||||
|
mainImg.setAttribute("data-enlarge-src", imageSrc);
|
||||||
|
console.log("Main image updated to:", imageSrc);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Product detail page functionality
|
||||||
|
async function initProductDetail() {
|
||||||
console.log("Product detail script running...");
|
console.log("Product detail script running...");
|
||||||
|
console.log("Current URL:", window.location.href);
|
||||||
|
|
||||||
// Check if we're on the product detail page
|
// Check if we're on the product detail page
|
||||||
const productTitle = document.querySelector("h1");
|
const productTitle = document.querySelector("h1");
|
||||||
|
|
@ -233,6 +345,7 @@ function initSite() {
|
||||||
console.log("No h1 found, not on product detail page");
|
console.log("No h1 found, not on product detail page");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
console.log("Found h1 element:", productTitle);
|
||||||
|
|
||||||
// Get product ID from URL
|
// Get product ID from URL
|
||||||
const urlParams = new URLSearchParams(window.location.search);
|
const urlParams = new URLSearchParams(window.location.search);
|
||||||
|
|
@ -269,161 +382,112 @@ function initSite() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update product title (the main product title, not the breadcrumb)
|
// Update product title (the main product title, not the breadcrumb)
|
||||||
const allH1s = document.querySelectorAll("h1");
|
const productTitle = document.getElementById("product-title");
|
||||||
console.log("All H1 elements:", allH1s);
|
console.log("Product title element:", productTitle);
|
||||||
if (allH1s.length > 1) {
|
if (productTitle) {
|
||||||
const mainProductTitle = allH1s[1]; // The second h1 should be the product title
|
productTitle.textContent = product.name;
|
||||||
console.log("Main product title element:", mainProductTitle);
|
console.log("Updated product title to:", product.name);
|
||||||
if (mainProductTitle) {
|
|
||||||
mainProductTitle.textContent = product.name;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update product description - find by text content
|
// Update product description
|
||||||
const allParagraphs = document.querySelectorAll("p");
|
const productDescription = document.getElementById("product-description");
|
||||||
console.log("All paragraphs:", allParagraphs);
|
console.log("Product description element:", productDescription);
|
||||||
const descriptionEl = Array.from(allParagraphs).find(
|
if (productDescription) {
|
||||||
(p) =>
|
productDescription.textContent = product.description;
|
||||||
p.textContent &&
|
console.log("Updated product description to:", product.description);
|
||||||
p.textContent.includes(
|
}
|
||||||
"Setting the bar as one of the loudest speakers"
|
|
||||||
|
// Update main product image
|
||||||
|
const mainImageContainer = document.querySelector(
|
||||||
|
".w-full.h-80.md\\:w-\\[500px\\].md\\:h-\\[500px\\]"
|
||||||
|
);
|
||||||
|
console.log("Main image container:", mainImageContainer);
|
||||||
|
if (mainImageContainer) {
|
||||||
|
mainImageContainer.innerHTML = `
|
||||||
|
<img
|
||||||
|
src="${product.image}"
|
||||||
|
alt="${product.alt || product.name}"
|
||||||
|
class="w-full h-full object-cover cursor-pointer hover:opacity-90 transition-opacity"
|
||||||
|
data-enlarge-src="${product.image}"
|
||||||
|
/>
|
||||||
|
`;
|
||||||
|
console.log("Updated main image to:", product.image);
|
||||||
|
|
||||||
|
// Add image enlargement functionality to the main product image
|
||||||
|
setTimeout(() => {
|
||||||
|
addImageEnlargementListeners();
|
||||||
|
}, 100);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update thumbnail images
|
||||||
|
const thumbnailContainer = document.querySelector(
|
||||||
|
".flex.flex-row.md\\:flex-col.gap-3.md\\:gap-4"
|
||||||
|
);
|
||||||
|
console.log("Thumbnail container:", thumbnailContainer);
|
||||||
|
if (thumbnailContainer && product.images) {
|
||||||
|
thumbnailContainer.innerHTML = product.images
|
||||||
|
.slice(0, 4)
|
||||||
|
.map(
|
||||||
|
(img, index) => `
|
||||||
|
<div class="w-32 h-32 bg-floral-white rounded-lg overflow-hidden cursor-pointer hover:opacity-80 transition-opacity" data-thumbnail-src="${img}">
|
||||||
|
<img
|
||||||
|
src="${img}"
|
||||||
|
alt="${product.name} ${index + 1}"
|
||||||
|
class="w-full h-full object-cover"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
`
|
||||||
)
|
)
|
||||||
);
|
.join("");
|
||||||
console.log("Description element:", descriptionEl);
|
console.log("Updated thumbnails with", product.images.length, "images");
|
||||||
if (descriptionEl) {
|
|
||||||
descriptionEl.textContent = product.description;
|
// Add click event listeners to thumbnails
|
||||||
|
addThumbnailClickListeners();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update main product image - find by alt text
|
// Update size options
|
||||||
const allImages = document.querySelectorAll("img");
|
const sizeContainer = document.getElementById("size-buttons-container");
|
||||||
console.log("All images:", allImages);
|
console.log("Size container:", sizeContainer);
|
||||||
const mainImage = Array.from(allImages).find(
|
if (sizeContainer && product.sizes) {
|
||||||
(img) => img.alt && img.alt.includes("Asgaard sofa")
|
sizeContainer.innerHTML = product.sizes
|
||||||
);
|
.map(
|
||||||
console.log("Main image element:", mainImage);
|
(size, index) => `
|
||||||
if (mainImage) {
|
<button
|
||||||
mainImage.src = product.image;
|
class="w-8 h-8 ${
|
||||||
mainImage.alt = product.alt || product.name;
|
index === 0
|
||||||
|
? "bg-uc-gold text-white"
|
||||||
|
: "bg-floral-white text-black"
|
||||||
|
} font-playfair font-normal text-sm rounded flex items-center justify-center size-button"
|
||||||
|
>
|
||||||
|
${size}
|
||||||
|
</button>
|
||||||
|
`
|
||||||
|
)
|
||||||
|
.join("");
|
||||||
|
console.log("Updated size options with", product.sizes.length, "sizes");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update thumbnail images - find by alt text
|
// Update color options
|
||||||
if (product.images && product.images.length > 0) {
|
const colorContainer = document.getElementById("color-buttons-container");
|
||||||
const allImages = document.querySelectorAll("img");
|
console.log("Color container:", colorContainer);
|
||||||
const thumbnails = Array.from(allImages).filter(
|
if (colorContainer && product.colors) {
|
||||||
(img) =>
|
colorContainer.innerHTML = product.colors
|
||||||
img.alt &&
|
.map(
|
||||||
(img.alt.includes("Outdoor sofa set") ||
|
(color, index) => `
|
||||||
img.alt.includes("Stuart sofa") ||
|
<button
|
||||||
img.alt.includes("Maya sofa"))
|
class="w-8 h-8 rounded-full ${
|
||||||
|
index === 0 ? "border-2 border-black" : ""
|
||||||
|
}"
|
||||||
|
style="background-color: ${color}"
|
||||||
|
></button>
|
||||||
|
`
|
||||||
|
)
|
||||||
|
.join("");
|
||||||
|
console.log(
|
||||||
|
"Updated color options with",
|
||||||
|
product.colors.length,
|
||||||
|
"colors"
|
||||||
);
|
);
|
||||||
console.log("Thumbnail images found:", thumbnails);
|
|
||||||
product.images.forEach((imageSrc, index) => {
|
|
||||||
if (thumbnails[index]) {
|
|
||||||
thumbnails[index].src = imageSrc;
|
|
||||||
thumbnails[index].alt = product.alt || product.name;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update size options - use the specific size-button class
|
|
||||||
if (product.sizes) {
|
|
||||||
const sizeButtons = document.querySelectorAll(".size-button");
|
|
||||||
console.log("Size buttons found:", sizeButtons);
|
|
||||||
|
|
||||||
// Hide all size buttons first
|
|
||||||
sizeButtons.forEach((button) => {
|
|
||||||
button.style.display = "none";
|
|
||||||
});
|
|
||||||
|
|
||||||
// Show and update only the buttons we need
|
|
||||||
product.sizes.forEach((size, index) => {
|
|
||||||
if (sizeButtons[index]) {
|
|
||||||
sizeButtons[index].style.display = "flex";
|
|
||||||
sizeButtons[index].textContent = size;
|
|
||||||
sizeButtons[index].setAttribute("data-size", size);
|
|
||||||
// Set selected size
|
|
||||||
if (size === product.selectedSize) {
|
|
||||||
sizeButtons[index].classList.remove(
|
|
||||||
"bg-floral-white",
|
|
||||||
"text-black"
|
|
||||||
);
|
|
||||||
sizeButtons[index].classList.add("bg-uc-gold", "text-white");
|
|
||||||
sizeButtons[index].classList.add("selected");
|
|
||||||
} else {
|
|
||||||
sizeButtons[index].classList.remove(
|
|
||||||
"bg-uc-gold",
|
|
||||||
"text-white",
|
|
||||||
"selected"
|
|
||||||
);
|
|
||||||
sizeButtons[index].classList.add("bg-floral-white", "text-black");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Add click event listeners for size buttons
|
|
||||||
sizeButtons.forEach((button) => {
|
|
||||||
button.addEventListener("click", function () {
|
|
||||||
// Remove selected state from all size buttons
|
|
||||||
sizeButtons.forEach((btn) => {
|
|
||||||
btn.classList.remove("bg-uc-gold", "text-white", "selected");
|
|
||||||
btn.classList.add("bg-floral-white", "text-black");
|
|
||||||
});
|
|
||||||
|
|
||||||
// Add selected state to clicked button
|
|
||||||
this.classList.remove("bg-floral-white", "text-black");
|
|
||||||
this.classList.add("bg-uc-gold", "text-white", "selected");
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update color options - find only the rounded color buttons, not size buttons
|
|
||||||
if (product.colors) {
|
|
||||||
const allButtons = document.querySelectorAll("button");
|
|
||||||
const colorButtons = Array.from(allButtons).filter(
|
|
||||||
(button) =>
|
|
||||||
button.classList.contains("w-8") &&
|
|
||||||
button.classList.contains("h-8") &&
|
|
||||||
button.classList.contains("rounded-full") &&
|
|
||||||
!button.textContent // Color buttons should not have text content
|
|
||||||
);
|
|
||||||
console.log("Color buttons found:", colorButtons);
|
|
||||||
|
|
||||||
product.colors.forEach((color, index) => {
|
|
||||||
if (colorButtons[index]) {
|
|
||||||
colorButtons[index].style.backgroundColor = color.value;
|
|
||||||
colorButtons[index].setAttribute(
|
|
||||||
"data-color",
|
|
||||||
color.name || color.value
|
|
||||||
);
|
|
||||||
// Set selected color
|
|
||||||
if (color.selected) {
|
|
||||||
colorButtons[index].classList.add(
|
|
||||||
"border-2",
|
|
||||||
"border-black",
|
|
||||||
"selected"
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
colorButtons[index].classList.remove(
|
|
||||||
"border-2",
|
|
||||||
"border-black",
|
|
||||||
"selected"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Add click event listeners for color buttons
|
|
||||||
colorButtons.forEach((button) => {
|
|
||||||
button.addEventListener("click", function () {
|
|
||||||
// Remove selected state from all color buttons
|
|
||||||
colorButtons.forEach((btn) => {
|
|
||||||
btn.classList.remove("border-2", "border-black", "selected");
|
|
||||||
});
|
|
||||||
|
|
||||||
// Add selected state to clicked button
|
|
||||||
this.classList.add("border-2", "border-black", "selected");
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update product metadata - find by text content
|
// Update product metadata - find by text content
|
||||||
|
|
@ -450,20 +514,7 @@ function initSite() {
|
||||||
categoryLabel.parentElement.querySelector("span:last-child");
|
categoryLabel.parentElement.querySelector("span:last-child");
|
||||||
if (categoryValue) {
|
if (categoryValue) {
|
||||||
categoryValue.textContent =
|
categoryValue.textContent =
|
||||||
product.category.charAt(0).toUpperCase() +
|
product.category.charAt(0).toUpperCase() + product.category.slice(1);
|
||||||
product.category.slice(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Find and update Tags
|
|
||||||
const tagsLabel = Array.from(allSpans).find(
|
|
||||||
(span) => span.textContent === "Tags"
|
|
||||||
);
|
|
||||||
if (tagsLabel && product.tags) {
|
|
||||||
const tagsValue =
|
|
||||||
tagsLabel.parentElement.querySelector("span:last-child");
|
|
||||||
if (tagsValue) {
|
|
||||||
tagsValue.textContent = product.tags.join(", ");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -485,45 +536,161 @@ function initSite() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update description content
|
// Update description content
|
||||||
if (product.descriptionLong) {
|
const descriptionContainer = document.getElementById(
|
||||||
const descriptionContainer = document.querySelector(
|
"product-description-content"
|
||||||
".max-w-5xl.mx-auto.space-y-6"
|
);
|
||||||
|
console.log("Description content container:", descriptionContainer);
|
||||||
|
if (descriptionContainer && product.descriptionLong) {
|
||||||
|
descriptionContainer.innerHTML = product.descriptionLong
|
||||||
|
.map(
|
||||||
|
(paragraph) => `
|
||||||
|
<p class="font-playfair text-base leading-6 text-[#333333] text-justify">
|
||||||
|
${paragraph}
|
||||||
|
</p>
|
||||||
|
`
|
||||||
|
)
|
||||||
|
.join("");
|
||||||
|
console.log(
|
||||||
|
"Updated description content with",
|
||||||
|
product.descriptionLong.length,
|
||||||
|
"paragraphs"
|
||||||
);
|
);
|
||||||
if (descriptionContainer) {
|
|
||||||
const descriptionParagraphs =
|
|
||||||
descriptionContainer.querySelectorAll("p");
|
|
||||||
console.log("Description paragraphs found:", descriptionParagraphs);
|
|
||||||
|
|
||||||
// Update each paragraph with the product's description content
|
|
||||||
product.descriptionLong.forEach((paragraph, index) => {
|
|
||||||
if (descriptionParagraphs[index]) {
|
|
||||||
descriptionParagraphs[index].textContent = paragraph;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Update gallery images with carousel
|
||||||
|
const galleryContainer = document.getElementById("product-gallery-images");
|
||||||
|
const galleryBackBtn = document.getElementById("gallery-back-btn");
|
||||||
|
const galleryNextBtn = document.getElementById("gallery-next-btn");
|
||||||
|
console.log("Gallery container:", galleryContainer);
|
||||||
|
console.log("Product galleryPairs:", product.galleryPairs);
|
||||||
|
|
||||||
|
if (galleryContainer && product.galleryPairs) {
|
||||||
|
// galleryPairs is now a simple array of image paths
|
||||||
|
const allGalleryImages = product.galleryPairs;
|
||||||
|
console.log("All gallery images:", allGalleryImages);
|
||||||
|
|
||||||
|
// Store gallery images for carousel
|
||||||
|
window.currentGalleryImages = allGalleryImages;
|
||||||
|
window.currentGalleryIndex = 0;
|
||||||
|
|
||||||
|
console.log("About to call renderGalleryCarousel...");
|
||||||
|
// Render initial gallery view
|
||||||
|
renderGalleryCarousel();
|
||||||
|
|
||||||
|
// Show navigation arrows for looped carousel (always show if more than 2 images)
|
||||||
|
if (allGalleryImages.length > 2) {
|
||||||
|
galleryBackBtn.style.display = "block";
|
||||||
|
galleryNextBtn.style.display = "block";
|
||||||
|
} else {
|
||||||
|
galleryBackBtn.style.display = "none";
|
||||||
|
galleryNextBtn.style.display = "none";
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(
|
||||||
|
"Gallery carousel:",
|
||||||
|
allGalleryImages.length,
|
||||||
|
"gallery images total (sliding)"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function renderGalleryCarousel() {
|
||||||
|
console.log("renderGalleryCarousel called");
|
||||||
|
console.log("window.currentGalleryImages:", window.currentGalleryImages);
|
||||||
|
console.log("galleryContainer:", galleryContainer);
|
||||||
|
|
||||||
|
if (!window.currentGalleryImages || !galleryContainer) {
|
||||||
|
console.log(
|
||||||
|
"Early return: missing currentGalleryImages or galleryContainer"
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(
|
||||||
|
"Rendering gallery carousel with",
|
||||||
|
window.currentGalleryImages.length,
|
||||||
|
"images"
|
||||||
|
);
|
||||||
|
|
||||||
|
// Handle single image vs multiple images
|
||||||
|
if (window.currentGalleryImages.length === 1) {
|
||||||
|
// Single image - show only one image, hide arrows
|
||||||
|
const image1 = window.currentGalleryImages[0];
|
||||||
|
console.log("Rendering single image:", image1);
|
||||||
|
galleryContainer.innerHTML = `
|
||||||
|
<div class="rounded-[10px] bg-floral-white p-6 transition-all duration-1500 ease-out cursor-pointer hover:opacity-90" id="gallery-image-1">
|
||||||
|
<img
|
||||||
|
src="${image1}"
|
||||||
|
alt="${product.name} gallery"
|
||||||
|
class="w-full h-80 object-contain mx-auto"
|
||||||
|
data-enlarge-src="${image1}"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
|
||||||
|
// Hide arrows for single image
|
||||||
|
galleryBackBtn.style.display = "none";
|
||||||
|
galleryNextBtn.style.display = "none";
|
||||||
|
} else {
|
||||||
|
// Multiple images - show 2 images with carousel
|
||||||
|
const image1 = window.currentGalleryImages[window.currentGalleryIndex];
|
||||||
|
const image2Index =
|
||||||
|
(window.currentGalleryIndex + 1) % window.currentGalleryImages.length;
|
||||||
|
const image2 = window.currentGalleryImages[image2Index];
|
||||||
|
|
||||||
|
console.log("Rendering multiple images:", image1, image2);
|
||||||
|
|
||||||
|
galleryContainer.innerHTML = `
|
||||||
|
<div class="rounded-[10px] bg-floral-white p-6 transition-all duration-1500 ease-out cursor-pointer hover:opacity-90" id="gallery-image-1">
|
||||||
|
<img
|
||||||
|
src="${image1}"
|
||||||
|
alt="${product.name} gallery"
|
||||||
|
class="w-full h-80 object-contain mx-auto"
|
||||||
|
data-enlarge-src="${image1}"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div class="rounded-[10px] bg-floral-white p-6 transition-all duration-1500 ease-out cursor-pointer hover:opacity-90" id="gallery-image-2">
|
||||||
|
<img
|
||||||
|
src="${image2}"
|
||||||
|
alt="${product.name} gallery"
|
||||||
|
class="w-full h-80 object-contain mx-auto"
|
||||||
|
data-enlarge-src="${image2}"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
|
||||||
|
// Show arrows for multiple images
|
||||||
|
galleryBackBtn.style.display = "block";
|
||||||
|
galleryBackBtn.style.opacity = "1";
|
||||||
|
galleryBackBtn.style.pointerEvents = "auto";
|
||||||
|
|
||||||
|
galleryNextBtn.style.display = "block";
|
||||||
|
galleryNextBtn.style.opacity = "1";
|
||||||
|
galleryNextBtn.style.pointerEvents = "auto";
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add click event listeners to gallery images for enlargement
|
||||||
|
console.log("About to call addImageEnlargementListeners for gallery...");
|
||||||
|
addImageEnlargementListeners();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add click handlers for looped gallery carousel navigation
|
||||||
|
if (galleryBackBtn) {
|
||||||
|
galleryBackBtn.addEventListener("click", function () {
|
||||||
|
// Left arrow moves forward: if at last position, go to 0
|
||||||
|
window.currentGalleryIndex =
|
||||||
|
(window.currentGalleryIndex + 1) % window.currentGalleryImages.length;
|
||||||
|
renderGalleryCarousel();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Update gallery images
|
if (galleryNextBtn) {
|
||||||
if (product.galleryPairs) {
|
galleryNextBtn.addEventListener("click", function () {
|
||||||
// Find gallery images by alt text
|
// Right arrow moves backward: if at 0, go to last position
|
||||||
const allImages = document.querySelectorAll("img");
|
window.currentGalleryIndex =
|
||||||
const galleryImages = Array.from(allImages).filter(
|
window.currentGalleryIndex === 0
|
||||||
(img) =>
|
? window.currentGalleryImages.length - 1
|
||||||
img.alt &&
|
: window.currentGalleryIndex - 1;
|
||||||
(img.alt.includes("Sofa variant left") ||
|
renderGalleryCarousel();
|
||||||
img.alt.includes("Sofa variant right"))
|
|
||||||
);
|
|
||||||
console.log("Gallery images found:", galleryImages);
|
|
||||||
|
|
||||||
product.galleryPairs.forEach((pair, index) => {
|
|
||||||
if (galleryImages[index * 2]) {
|
|
||||||
galleryImages[index * 2].src = pair.left;
|
|
||||||
galleryImages[index * 2].alt = product.alt || product.name;
|
|
||||||
}
|
|
||||||
if (galleryImages[index * 2 + 1]) {
|
|
||||||
galleryImages[index * 2 + 1].src = pair.right;
|
|
||||||
galleryImages[index * 2 + 1].alt = product.alt || product.name;
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -608,7 +775,6 @@ function initSite() {
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Error loading product data:", error);
|
console.error("Error loading product data:", error);
|
||||||
}
|
}
|
||||||
})();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Product Comparison Page Functionality
|
// Product Comparison Page Functionality
|
||||||
|
|
@ -1001,6 +1167,8 @@ if (window.location.pathname.includes("product-detail.html")) {
|
||||||
"Product detail page detected, initializing compare functionality immediately"
|
"Product detail page detected, initializing compare functionality immediately"
|
||||||
);
|
);
|
||||||
initProductDetailCompare();
|
initProductDetailCompare();
|
||||||
|
// Also initialize product detail loading
|
||||||
|
initProductDetail();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Also try to initialize on DOMContentLoaded
|
// Also try to initialize on DOMContentLoaded
|
||||||
|
|
@ -1009,6 +1177,8 @@ document.addEventListener("DOMContentLoaded", function () {
|
||||||
if (window.location.pathname.includes("product-detail.html")) {
|
if (window.location.pathname.includes("product-detail.html")) {
|
||||||
console.log("Product detail page detected in DOMContentLoaded");
|
console.log("Product detail page detected in DOMContentLoaded");
|
||||||
initProductDetailCompare();
|
initProductDetailCompare();
|
||||||
|
// Also initialize product detail loading
|
||||||
|
initProductDetail();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -123,6 +123,11 @@ class ProductManager {
|
||||||
.join("");
|
.join("");
|
||||||
this.updateResultsCount();
|
this.updateResultsCount();
|
||||||
this.updatePagination();
|
this.updatePagination();
|
||||||
|
|
||||||
|
// Re-add image enlargement listeners after products are rendered
|
||||||
|
setTimeout(() => {
|
||||||
|
addImageEnlargementListeners();
|
||||||
|
}, 50);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create individual product card HTML
|
// Create individual product card HTML
|
||||||
|
|
@ -140,7 +145,8 @@ class ProductManager {
|
||||||
<img
|
<img
|
||||||
src="${product.image}"
|
src="${product.image}"
|
||||||
alt="${product.alt}"
|
alt="${product.alt}"
|
||||||
class="w-full h-full object-cover group-hover:scale-105 transition-transform duration-300"
|
class="w-full h-full object-cover group-hover:scale-105 transition-transform duration-300 cursor-pointer"
|
||||||
|
data-enlarge-src="${product.image}"
|
||||||
/>
|
/>
|
||||||
<!-- Hover Overlay -->
|
<!-- Hover Overlay -->
|
||||||
<div class="absolute inset-0 bg-dark-charcoal bg-opacity-70 opacity-0 group-hover:opacity-100 transition-opacity duration-300 flex items-center justify-center">
|
<div class="absolute inset-0 bg-dark-charcoal bg-opacity-70 opacity-0 group-hover:opacity-100 transition-opacity duration-300 flex items-center justify-center">
|
||||||
|
|
@ -454,7 +460,76 @@ class ProductManager {
|
||||||
// Initialize product manager
|
// Initialize product manager
|
||||||
const productManager = new ProductManager();
|
const productManager = new ProductManager();
|
||||||
|
|
||||||
|
// Image enlargement modal functionality
|
||||||
|
function addImageEnlargementListeners() {
|
||||||
|
const productImages = document.querySelectorAll(
|
||||||
|
"#product-grid img[data-enlarge-src]"
|
||||||
|
);
|
||||||
|
const modal = document.getElementById("image-modal");
|
||||||
|
const modalImage = document.getElementById("modal-image");
|
||||||
|
const modalCloseBtn = document.getElementById("modal-close-btn");
|
||||||
|
|
||||||
|
if (!modal || !modalImage || !modalCloseBtn) return;
|
||||||
|
|
||||||
|
productImages.forEach((img) => {
|
||||||
|
img.addEventListener("click", function (e) {
|
||||||
|
e.preventDefault(); // Prevent any default behavior
|
||||||
|
e.stopPropagation(); // Stop event bubbling to parent elements
|
||||||
|
|
||||||
|
const imageSrc = this.getAttribute("data-enlarge-src");
|
||||||
|
const imageAlt = this.getAttribute("alt");
|
||||||
|
|
||||||
|
modalImage.src = imageSrc;
|
||||||
|
modalImage.alt = imageAlt;
|
||||||
|
|
||||||
|
// Show modal with animation
|
||||||
|
modal.classList.remove("hidden");
|
||||||
|
document.body.style.overflow = "hidden"; // Prevent background scrolling
|
||||||
|
|
||||||
|
// Trigger animation after a brief delay
|
||||||
|
setTimeout(() => {
|
||||||
|
modalImage.classList.remove("scale-95");
|
||||||
|
modalImage.classList.add("scale-100");
|
||||||
|
}, 10);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// Close modal functionality
|
||||||
|
function closeModal() {
|
||||||
|
// Animate out
|
||||||
|
modalImage.classList.remove("scale-100");
|
||||||
|
modalImage.classList.add("scale-95");
|
||||||
|
|
||||||
|
// Hide modal after animation
|
||||||
|
setTimeout(() => {
|
||||||
|
modal.classList.add("hidden");
|
||||||
|
document.body.style.overflow = ""; // Restore scrolling
|
||||||
|
}, 300);
|
||||||
|
}
|
||||||
|
|
||||||
|
modalCloseBtn.addEventListener("click", closeModal);
|
||||||
|
|
||||||
|
// Close modal when clicking outside the image
|
||||||
|
modal.addEventListener("click", function (e) {
|
||||||
|
if (e.target === modal) {
|
||||||
|
closeModal();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Close modal with Escape key
|
||||||
|
document.addEventListener("keydown", function (e) {
|
||||||
|
if (e.key === "Escape" && !modal.classList.contains("hidden")) {
|
||||||
|
closeModal();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// Load products when DOM is ready
|
// Load products when DOM is ready
|
||||||
document.addEventListener("DOMContentLoaded", () => {
|
document.addEventListener("DOMContentLoaded", () => {
|
||||||
productManager.loadProducts();
|
productManager.loadProducts();
|
||||||
|
|
||||||
|
// Add image enlargement listeners after products are loaded
|
||||||
|
setTimeout(() => {
|
||||||
|
addImageEnlargementListeners();
|
||||||
|
}, 100);
|
||||||
});
|
});
|
||||||
|
|
|
||||||
263
styles/main.css
263
styles/main.css
|
|
@ -673,6 +673,10 @@ video {
|
||||||
top: 20rem;
|
top: 20rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.top-4 {
|
||||||
|
top: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
.z-10 {
|
.z-10 {
|
||||||
z-index: 10;
|
z-index: 10;
|
||||||
}
|
}
|
||||||
|
|
@ -779,10 +783,6 @@ video {
|
||||||
margin-top: 2.5rem;
|
margin-top: 2.5rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mt-2 {
|
|
||||||
margin-top: 0.5rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.mt-20 {
|
.mt-20 {
|
||||||
margin-top: 5rem;
|
margin-top: 5rem;
|
||||||
}
|
}
|
||||||
|
|
@ -791,10 +791,18 @@ video {
|
||||||
margin-top: 0.75rem;
|
margin-top: 0.75rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.mt-12 {
|
||||||
|
margin-top: 3rem;
|
||||||
|
}
|
||||||
|
|
||||||
.mt-6 {
|
.mt-6 {
|
||||||
margin-top: 1.5rem;
|
margin-top: 1.5rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.mt-2 {
|
||||||
|
margin-top: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
.box-border {
|
.box-border {
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
}
|
}
|
||||||
|
|
@ -883,22 +891,22 @@ video {
|
||||||
height: 24rem;
|
height: 24rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.h-\[22vh\] {
|
.h-\[145px\] {
|
||||||
height: 22vh;
|
height: 145px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.h-\[29vh\] {
|
.h-\[301px\] {
|
||||||
height: 29vh;
|
height: 301px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.h-\[446px\] {
|
||||||
|
height: 446px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.h-\[64px\] {
|
.h-\[64px\] {
|
||||||
height: 64px;
|
height: 64px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.h-\[6vh\] {
|
|
||||||
height: 6vh;
|
|
||||||
}
|
|
||||||
|
|
||||||
.h-auto {
|
.h-auto {
|
||||||
height: auto;
|
height: auto;
|
||||||
}
|
}
|
||||||
|
|
@ -915,6 +923,54 @@ video {
|
||||||
height: 100vh;
|
height: 100vh;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.h-\[320px\] {
|
||||||
|
height: 320px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.h-\[220px\] {
|
||||||
|
height: 220px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.h-\[100px\] {
|
||||||
|
height: 100px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.h-\[25vh\] {
|
||||||
|
height: 25vh;
|
||||||
|
}
|
||||||
|
|
||||||
|
.h-\[18vh\] {
|
||||||
|
height: 18vh;
|
||||||
|
}
|
||||||
|
|
||||||
|
.h-\[7vh\] {
|
||||||
|
height: 7vh;
|
||||||
|
}
|
||||||
|
|
||||||
|
.h-\[30vh\] {
|
||||||
|
height: 30vh;
|
||||||
|
}
|
||||||
|
|
||||||
|
.h-\[22vh\] {
|
||||||
|
height: 22vh;
|
||||||
|
}
|
||||||
|
|
||||||
|
.h-\[8vh\] {
|
||||||
|
height: 8vh;
|
||||||
|
}
|
||||||
|
|
||||||
|
.h-\[29vh\] {
|
||||||
|
height: 29vh;
|
||||||
|
}
|
||||||
|
|
||||||
|
.h-\[21vh\] {
|
||||||
|
height: 21vh;
|
||||||
|
}
|
||||||
|
|
||||||
|
.h-\[6vh\] {
|
||||||
|
height: 6vh;
|
||||||
|
}
|
||||||
|
|
||||||
.h-\[31vh\] {
|
.h-\[31vh\] {
|
||||||
height: 31vh;
|
height: 31vh;
|
||||||
}
|
}
|
||||||
|
|
@ -927,8 +983,12 @@ video {
|
||||||
height: 32vh;
|
height: 32vh;
|
||||||
}
|
}
|
||||||
|
|
||||||
.h-\[25vh\] {
|
.h-\[95vh\] {
|
||||||
height: 25vh;
|
height: 95vh;
|
||||||
|
}
|
||||||
|
|
||||||
|
.max-h-full {
|
||||||
|
max-height: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.min-h-\[64px\] {
|
.min-h-\[64px\] {
|
||||||
|
|
@ -1015,6 +1075,10 @@ video {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.w-\[95vw\] {
|
||||||
|
width: 95vw;
|
||||||
|
}
|
||||||
|
|
||||||
.max-w-2xl {
|
.max-w-2xl {
|
||||||
max-width: 42rem;
|
max-width: 42rem;
|
||||||
}
|
}
|
||||||
|
|
@ -1047,6 +1111,14 @@ video {
|
||||||
max-width: 20rem;
|
max-width: 20rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.max-w-4xl {
|
||||||
|
max-width: 56rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.max-w-full {
|
||||||
|
max-width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
.flex-1 {
|
.flex-1 {
|
||||||
flex: 1 1 0%;
|
flex: 1 1 0%;
|
||||||
}
|
}
|
||||||
|
|
@ -1070,6 +1142,18 @@ video {
|
||||||
transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
|
transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.scale-95 {
|
||||||
|
--tw-scale-x: .95;
|
||||||
|
--tw-scale-y: .95;
|
||||||
|
transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
|
||||||
|
}
|
||||||
|
|
||||||
|
.scale-100 {
|
||||||
|
--tw-scale-x: 1;
|
||||||
|
--tw-scale-y: 1;
|
||||||
|
transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
|
||||||
|
}
|
||||||
|
|
||||||
.transform {
|
.transform {
|
||||||
transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
|
transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
|
||||||
}
|
}
|
||||||
|
|
@ -1164,14 +1248,14 @@ video {
|
||||||
gap: 1.5rem;
|
gap: 1.5rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.gap-7 {
|
|
||||||
gap: 1.75rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.gap-8 {
|
.gap-8 {
|
||||||
gap: 2rem;
|
gap: 2rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.gap-7 {
|
||||||
|
gap: 1.75rem;
|
||||||
|
}
|
||||||
|
|
||||||
.space-x-10 > :not([hidden]) ~ :not([hidden]) {
|
.space-x-10 > :not([hidden]) ~ :not([hidden]) {
|
||||||
--tw-space-x-reverse: 0;
|
--tw-space-x-reverse: 0;
|
||||||
margin-right: calc(2.5rem * var(--tw-space-x-reverse));
|
margin-right: calc(2.5rem * var(--tw-space-x-reverse));
|
||||||
|
|
@ -1208,6 +1292,12 @@ video {
|
||||||
margin-bottom: calc(0.25rem * var(--tw-space-y-reverse));
|
margin-bottom: calc(0.25rem * var(--tw-space-y-reverse));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.space-y-16 > :not([hidden]) ~ :not([hidden]) {
|
||||||
|
--tw-space-y-reverse: 0;
|
||||||
|
margin-top: calc(4rem * calc(1 - var(--tw-space-y-reverse)));
|
||||||
|
margin-bottom: calc(4rem * var(--tw-space-y-reverse));
|
||||||
|
}
|
||||||
|
|
||||||
.space-y-2 > :not([hidden]) ~ :not([hidden]) {
|
.space-y-2 > :not([hidden]) ~ :not([hidden]) {
|
||||||
--tw-space-y-reverse: 0;
|
--tw-space-y-reverse: 0;
|
||||||
margin-top: calc(0.5rem * calc(1 - var(--tw-space-y-reverse)));
|
margin-top: calc(0.5rem * calc(1 - var(--tw-space-y-reverse)));
|
||||||
|
|
@ -1442,6 +1532,14 @@ video {
|
||||||
--tw-bg-opacity: 0.7;
|
--tw-bg-opacity: 0.7;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.bg-opacity-20 {
|
||||||
|
--tw-bg-opacity: 0.2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bg-opacity-90 {
|
||||||
|
--tw-bg-opacity: 0.9;
|
||||||
|
}
|
||||||
|
|
||||||
.object-contain {
|
.object-contain {
|
||||||
-o-object-fit: contain;
|
-o-object-fit: contain;
|
||||||
object-fit: contain;
|
object-fit: contain;
|
||||||
|
|
@ -1590,6 +1688,10 @@ video {
|
||||||
padding-right: 1.5rem;
|
padding-right: 1.5rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.pt-0 {
|
||||||
|
padding-top: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
.pt-12 {
|
.pt-12 {
|
||||||
padding-top: 3rem;
|
padding-top: 3rem;
|
||||||
}
|
}
|
||||||
|
|
@ -1860,6 +1962,12 @@ video {
|
||||||
box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
|
box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.shadow-2xl {
|
||||||
|
--tw-shadow: 0 25px 50px -12px rgb(0 0 0 / 0.25);
|
||||||
|
--tw-shadow-colored: 0 25px 50px -12px var(--tw-shadow-color);
|
||||||
|
box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
|
||||||
|
}
|
||||||
|
|
||||||
.blur {
|
.blur {
|
||||||
--tw-blur: blur(8px);
|
--tw-blur: blur(8px);
|
||||||
filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow);
|
filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow);
|
||||||
|
|
@ -1874,6 +1982,11 @@ video {
|
||||||
filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow);
|
filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.backdrop-blur-sm {
|
||||||
|
--tw-backdrop-blur: blur(4px);
|
||||||
|
backdrop-filter: var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia);
|
||||||
|
}
|
||||||
|
|
||||||
.transition {
|
.transition {
|
||||||
transition-property: color, background-color, border-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter, -webkit-text-decoration-color;
|
transition-property: color, background-color, border-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter, -webkit-text-decoration-color;
|
||||||
transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter;
|
transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter;
|
||||||
|
|
@ -1922,10 +2035,22 @@ video {
|
||||||
transition-duration: 300ms;
|
transition-duration: 300ms;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.duration-500 {
|
||||||
|
transition-duration: 500ms;
|
||||||
|
}
|
||||||
|
|
||||||
|
.duration-1000 {
|
||||||
|
transition-duration: 1000ms;
|
||||||
|
}
|
||||||
|
|
||||||
.ease-in-out {
|
.ease-in-out {
|
||||||
transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
|
transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.ease-out {
|
||||||
|
transition-timing-function: cubic-bezier(0, 0, 0.2, 1);
|
||||||
|
}
|
||||||
|
|
||||||
.hover\:-translate-y-0\.5:hover {
|
.hover\:-translate-y-0\.5:hover {
|
||||||
--tw-translate-y: -0.125rem;
|
--tw-translate-y: -0.125rem;
|
||||||
transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
|
transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
|
||||||
|
|
@ -1956,6 +2081,10 @@ video {
|
||||||
--tw-bg-opacity: 0.9;
|
--tw-bg-opacity: 0.9;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.hover\:bg-opacity-30:hover {
|
||||||
|
--tw-bg-opacity: 0.3;
|
||||||
|
}
|
||||||
|
|
||||||
.hover\:text-black:hover {
|
.hover\:text-black:hover {
|
||||||
--tw-text-opacity: 1;
|
--tw-text-opacity: 1;
|
||||||
color: rgb(0 0 0 / var(--tw-text-opacity, 1));
|
color: rgb(0 0 0 / var(--tw-text-opacity, 1));
|
||||||
|
|
@ -1985,6 +2114,10 @@ video {
|
||||||
opacity: 0.8;
|
opacity: 0.8;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.hover\:opacity-90:hover {
|
||||||
|
opacity: 0.9;
|
||||||
|
}
|
||||||
|
|
||||||
.hover\:shadow-lg:hover {
|
.hover\:shadow-lg:hover {
|
||||||
--tw-shadow: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1);
|
--tw-shadow: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1);
|
||||||
--tw-shadow-colored: 0 10px 15px -3px var(--tw-shadow-color), 0 4px 6px -4px var(--tw-shadow-color);
|
--tw-shadow-colored: 0 10px 15px -3px var(--tw-shadow-color), 0 4px 6px -4px var(--tw-shadow-color);
|
||||||
|
|
@ -2257,18 +2390,90 @@ video {
|
||||||
margin-left: 2rem;
|
margin-left: 2rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.lg\:mt-16 {
|
||||||
|
margin-top: 4rem;
|
||||||
|
}
|
||||||
|
|
||||||
.lg\:mt-8 {
|
.lg\:mt-8 {
|
||||||
margin-top: 2rem;
|
margin-top: 2rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.lg\:h-\[70vh\] {
|
||||||
|
height: 70vh;
|
||||||
|
}
|
||||||
|
|
||||||
|
.lg\:h-\[90vh\] {
|
||||||
|
height: 90vh;
|
||||||
|
}
|
||||||
|
|
||||||
|
.lg\:h-\[50vh\] {
|
||||||
|
height: 50vh;
|
||||||
|
}
|
||||||
|
|
||||||
|
.lg\:h-\[600px\] {
|
||||||
|
height: 600px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.lg\:h-\[500px\] {
|
||||||
|
height: 500px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.lg\:h-\[85vh\] {
|
||||||
|
height: 85vh;
|
||||||
|
}
|
||||||
|
|
||||||
|
.lg\:h-\[60vh\] {
|
||||||
|
height: 60vh;
|
||||||
|
}
|
||||||
|
|
||||||
.lg\:h-\[65vh\] {
|
.lg\:h-\[65vh\] {
|
||||||
height: 65vh;
|
height: 65vh;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.lg\:min-h-screen {
|
||||||
|
min-height: 100vh;
|
||||||
|
}
|
||||||
|
|
||||||
|
.lg\:min-h-\[90vh\] {
|
||||||
|
min-height: 90vh;
|
||||||
|
}
|
||||||
|
|
||||||
|
.lg\:min-h-\[100vh\] {
|
||||||
|
min-height: 100vh;
|
||||||
|
}
|
||||||
|
|
||||||
|
.lg\:min-h-\[150vh\] {
|
||||||
|
min-height: 150vh;
|
||||||
|
}
|
||||||
|
|
||||||
|
.lg\:min-h-\[900px\] {
|
||||||
|
min-height: 900px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.lg\:min-h-\[800px\] {
|
||||||
|
min-height: 800px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.lg\:min-h-\[700px\] {
|
||||||
|
min-height: 700px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.lg\:min-h-\[600px\] {
|
||||||
|
min-height: 600px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.lg\:min-h-\[60vh\] {
|
||||||
|
min-height: 60vh;
|
||||||
|
}
|
||||||
|
|
||||||
.lg\:min-h-\[65vh\] {
|
.lg\:min-h-\[65vh\] {
|
||||||
min-height: 65vh;
|
min-height: 65vh;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.lg\:min-h-\[80vh\] {
|
||||||
|
min-height: 80vh;
|
||||||
|
}
|
||||||
|
|
||||||
.lg\:w-36 {
|
.lg\:w-36 {
|
||||||
width: 9rem;
|
width: 9rem;
|
||||||
}
|
}
|
||||||
|
|
@ -2305,6 +2510,18 @@ video {
|
||||||
gap: 2rem;
|
gap: 2rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.lg\:space-y-10 > :not([hidden]) ~ :not([hidden]) {
|
||||||
|
--tw-space-y-reverse: 0;
|
||||||
|
margin-top: calc(2.5rem * calc(1 - var(--tw-space-y-reverse)));
|
||||||
|
margin-bottom: calc(2.5rem * var(--tw-space-y-reverse));
|
||||||
|
}
|
||||||
|
|
||||||
|
.lg\:space-y-6 > :not([hidden]) ~ :not([hidden]) {
|
||||||
|
--tw-space-y-reverse: 0;
|
||||||
|
margin-top: calc(1.5rem * calc(1 - var(--tw-space-y-reverse)));
|
||||||
|
margin-bottom: calc(1.5rem * var(--tw-space-y-reverse));
|
||||||
|
}
|
||||||
|
|
||||||
.lg\:space-y-4 > :not([hidden]) ~ :not([hidden]) {
|
.lg\:space-y-4 > :not([hidden]) ~ :not([hidden]) {
|
||||||
--tw-space-y-reverse: 0;
|
--tw-space-y-reverse: 0;
|
||||||
margin-top: calc(1rem * calc(1 - var(--tw-space-y-reverse)));
|
margin-top: calc(1rem * calc(1 - var(--tw-space-y-reverse)));
|
||||||
|
|
@ -2328,6 +2545,11 @@ video {
|
||||||
padding-top: 12rem;
|
padding-top: 12rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.lg\:text-2xl {
|
||||||
|
font-size: 1.5rem;
|
||||||
|
line-height: 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
.lg\:text-3xl {
|
.lg\:text-3xl {
|
||||||
font-size: 1.875rem;
|
font-size: 1.875rem;
|
||||||
line-height: 2.25rem;
|
line-height: 2.25rem;
|
||||||
|
|
@ -2348,6 +2570,11 @@ video {
|
||||||
line-height: 1.75rem;
|
line-height: 1.75rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.lg\:text-lg {
|
||||||
|
font-size: 1.125rem;
|
||||||
|
line-height: 1.75rem;
|
||||||
|
}
|
||||||
|
|
||||||
.lg\:leading-snug {
|
.lg\:leading-snug {
|
||||||
line-height: 1.375;
|
line-height: 1.375;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue