mirror of
https://git.kh3group.com/georgebiri/khy_website.git
synced 2026-10-16 22:01:47 +00:00
Compare commits
3 commits
6b21abfe6a
...
d8d9f1a584
| Author | SHA1 | Date | |
|---|---|---|---|
| d8d9f1a584 | |||
| a0995281e6 | |||
| b0c6379ddd |
5 changed files with 210 additions and 2514 deletions
16
.drone.yml
16
.drone.yml
|
|
@ -3,11 +3,16 @@ type: docker
|
||||||
name: deploy
|
name: deploy
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: build
|
- name: install
|
||||||
image: node:18-alpine
|
image: node:18-alpine
|
||||||
commands:
|
commands:
|
||||||
- npm ci || npm install
|
- npm install -D tailwindcss@^3.4.0
|
||||||
- npm run build || npm build
|
|
||||||
|
- name: build-css
|
||||||
|
image: node:18-alpine
|
||||||
|
commands:
|
||||||
|
# Generate optimized CSS from src/input.css styles/main.css
|
||||||
|
- npx tailwindcss -i ./src/input.css -o ./styles/main.css --minify
|
||||||
|
|
||||||
- name: sync-files
|
- name: sync-files
|
||||||
image: alpine:latest
|
image: alpine:latest
|
||||||
|
|
@ -16,10 +21,9 @@ steps:
|
||||||
path: /host-target
|
path: /host-target
|
||||||
commands:
|
commands:
|
||||||
- cp -a . /host-target
|
- cp -a . /host-target
|
||||||
|
- chmod -R 755 /host-target
|
||||||
- chmod -R 777 /host-target
|
|
||||||
|
|
||||||
volumes:
|
volumes:
|
||||||
- name: website-data
|
- name: website-data
|
||||||
host:
|
host:
|
||||||
path: /root/khywebsite/data/html
|
path: /root/khy/data/html
|
||||||
|
|
|
||||||
90
index.html
90
index.html
|
|
@ -68,6 +68,62 @@
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Attention animation for projects button */
|
||||||
|
.attention-animation {
|
||||||
|
animation: attention-pulse 3s ease-in-out infinite;
|
||||||
|
position: relative;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.attention-animation::before {
|
||||||
|
content: "";
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: -100%;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
background: linear-gradient(
|
||||||
|
90deg,
|
||||||
|
transparent,
|
||||||
|
rgba(255, 255, 255, 0.2),
|
||||||
|
transparent
|
||||||
|
);
|
||||||
|
animation: shimmer 4s ease-in-out infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes attention-pulse {
|
||||||
|
0%,
|
||||||
|
100% {
|
||||||
|
transform: scale(1);
|
||||||
|
box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1),
|
||||||
|
0 2px 4px -1px rgba(0, 0, 0, 0.06);
|
||||||
|
}
|
||||||
|
50% {
|
||||||
|
transform: scale(1.02);
|
||||||
|
box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1),
|
||||||
|
0 4px 6px -2px rgba(0, 0, 0, 0.05);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes shimmer {
|
||||||
|
0% {
|
||||||
|
left: -100%;
|
||||||
|
}
|
||||||
|
50% {
|
||||||
|
left: 100%;
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
left: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.attention-animation:hover {
|
||||||
|
animation: none;
|
||||||
|
transform: scale(1.05);
|
||||||
|
box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1),
|
||||||
|
0 10px 10px -5px rgba(0, 0, 0, 0.04);
|
||||||
|
}
|
||||||
|
|
||||||
.product-card:hover {
|
.product-card:hover {
|
||||||
transform: translateY(-8px) scale(1.02);
|
transform: translateY(-8px) scale(1.02);
|
||||||
box-shadow: 0 20px 40px -12px rgba(0, 0, 0, 0.15);
|
box-shadow: 0 20px 40px -12px rgba(0, 0, 0, 0.15);
|
||||||
|
|
@ -334,11 +390,11 @@
|
||||||
<!-- Main Content -->
|
<!-- Main Content -->
|
||||||
<div class="grid grid-cols-1 lg:grid-cols-2 gap-28 items-center">
|
<div class="grid grid-cols-1 lg:grid-cols-2 gap-28 items-center">
|
||||||
<!-- Left Side - Image -->
|
<!-- Left Side - Image -->
|
||||||
<div class="relative">
|
<div id="hero-image" class="relative">
|
||||||
<img
|
<img
|
||||||
src="assets/images/our_story.jpg"
|
src="assets/images/our_story.jpg"
|
||||||
alt="Modern office interior"
|
alt="Modern office interior"
|
||||||
class="w-full h-auto rounded-lg"
|
class="w-full h-auto rounded-lg transition-opacity duration-300"
|
||||||
/>
|
/>
|
||||||
<!-- Navigation Arrow -->
|
<!-- Navigation Arrow -->
|
||||||
<div class="absolute top-1/2 right-4 transform -translate-y-1/2">
|
<div class="absolute top-1/2 right-4 transform -translate-y-1/2">
|
||||||
|
|
@ -361,6 +417,32 @@
|
||||||
</svg>
|
</svg>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- Carousel Indicators -->
|
||||||
|
<div
|
||||||
|
class="absolute bottom-4 left-1/2 transform -translate-x-1/2 flex space-x-2"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
id="carousel-indicator-0"
|
||||||
|
class="w-3 h-3 bg-white rounded-full opacity-100 transition-opacity duration-300 cursor-pointer"
|
||||||
|
></div>
|
||||||
|
<div
|
||||||
|
id="carousel-indicator-1"
|
||||||
|
class="w-3 h-3 bg-white rounded-full opacity-50 transition-opacity duration-300 cursor-pointer"
|
||||||
|
></div>
|
||||||
|
<div
|
||||||
|
id="carousel-indicator-2"
|
||||||
|
class="w-3 h-3 bg-white rounded-full opacity-50 transition-opacity duration-300 cursor-pointer"
|
||||||
|
></div>
|
||||||
|
<div
|
||||||
|
id="carousel-indicator-3"
|
||||||
|
class="w-3 h-3 bg-white rounded-full opacity-50 transition-opacity duration-300 cursor-pointer"
|
||||||
|
></div>
|
||||||
|
<div
|
||||||
|
id="carousel-indicator-4"
|
||||||
|
class="w-3 h-3 bg-white rounded-full opacity-50 transition-opacity duration-300 cursor-pointer"
|
||||||
|
></div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Right Side - Text Content -->
|
<!-- Right Side - Text Content -->
|
||||||
|
|
@ -386,7 +468,7 @@
|
||||||
|
|
||||||
<button
|
<button
|
||||||
id="projects-button"
|
id="projects-button"
|
||||||
class="bg-black bg-opacity-70 text-white font-playfair font-normal text-xl md:text-2xl lg:text-3xl leading-tight tracking-wider px-8 py-4 rounded-lg hover:bg-opacity-80 transition-all text-center max-w-sm"
|
class="bg-black bg-opacity-70 text-white font-playfair font-normal text-xl md:text-2xl lg:text-3xl leading-tight tracking-wider px-8 py-4 rounded-lg hover:bg-opacity-80 transition-all text-center max-w-sm attention-animation"
|
||||||
>
|
>
|
||||||
Explore past projects
|
Explore past projects
|
||||||
</button>
|
</button>
|
||||||
|
|
@ -985,6 +1067,6 @@
|
||||||
</div>
|
</div>
|
||||||
</footer>
|
</footer>
|
||||||
|
|
||||||
<script src="scripts/main.js?v=1.1"></script>
|
<script src="scripts/main.js?v=4.7"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,11 @@
|
||||||
{
|
{
|
||||||
|
"name": "khy-website",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"description": "KHY Furniture Website",
|
||||||
|
"scripts": {
|
||||||
|
"build": "npx tailwindcss -i ./src/input.css -o ./styles/main.css --minify",
|
||||||
|
"dev": "npx tailwindcss -i ./src/input.css -o ./styles/main.css --watch"
|
||||||
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"tailwindcss": "^3.4.17",
|
"tailwindcss": "^3.4.17",
|
||||||
"tailwindcss-textshadow": "^2.1.3"
|
"tailwindcss-textshadow": "^2.1.3"
|
||||||
|
|
|
||||||
124
scripts/main.js
124
scripts/main.js
|
|
@ -661,23 +661,6 @@ function initSite() {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
// Story arrow button functionality
|
|
||||||
const storyArrowButton = document.getElementById("story-arrow-button");
|
|
||||||
if (storyArrowButton) {
|
|
||||||
storyArrowButton.addEventListener("click", function () {
|
|
||||||
// You can customize this action - for now, let's scroll to the products section
|
|
||||||
const productsSection = document.getElementById("products");
|
|
||||||
if (productsSection) {
|
|
||||||
const headerHeight = 112;
|
|
||||||
const targetPosition = productsSection.offsetTop - headerHeight;
|
|
||||||
|
|
||||||
window.scrollTo({
|
|
||||||
top: targetPosition,
|
|
||||||
behavior: "smooth",
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// Product detail page functionality
|
// Product detail page functionality
|
||||||
(async function initProductDetail() {
|
(async function initProductDetail() {
|
||||||
|
|
@ -1737,6 +1720,111 @@ if (document.readyState === "loading") {
|
||||||
document.addEventListener("DOMContentLoaded", function () {
|
document.addEventListener("DOMContentLoaded", function () {
|
||||||
initQuoteBadge();
|
initQuoteBadge();
|
||||||
initAddToQuote();
|
initAddToQuote();
|
||||||
|
initHeroCarousel();
|
||||||
});
|
});
|
||||||
|
|
||||||
// Version: 4.2 - Moved Show Less button to end of blog post content
|
// Hero Carousel Functionality
|
||||||
|
function initHeroCarousel() {
|
||||||
|
const arrowButton = document.getElementById("story-arrow-button");
|
||||||
|
const heroImage = document.querySelector("#hero-image img");
|
||||||
|
|
||||||
|
if (!arrowButton || !heroImage) return;
|
||||||
|
|
||||||
|
// Carousel images array
|
||||||
|
const carouselImages = [
|
||||||
|
"assets/images/our_story.jpg",
|
||||||
|
"assets/images/first_homepage.jpg",
|
||||||
|
"assets/images/conference_room.jpg",
|
||||||
|
"assets/images/lounge_chair.jpg",
|
||||||
|
"assets/images/kitchen.JPG",
|
||||||
|
];
|
||||||
|
|
||||||
|
let currentImageIndex = 0;
|
||||||
|
let originalHeight = null;
|
||||||
|
|
||||||
|
// Function to capture original image height on first load
|
||||||
|
function captureOriginalHeight() {
|
||||||
|
if (!originalHeight) {
|
||||||
|
originalHeight = heroImage.offsetHeight;
|
||||||
|
console.log("Original image height captured:", originalHeight + "px");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Function to update image with fade transition
|
||||||
|
function updateImage(newIndex) {
|
||||||
|
const newImage = new Image();
|
||||||
|
newImage.onload = function () {
|
||||||
|
// Fade out current image
|
||||||
|
heroImage.style.opacity = "0";
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
// Change image source
|
||||||
|
heroImage.src = carouselImages[newIndex];
|
||||||
|
heroImage.alt = `Carousel image ${newIndex + 1}`;
|
||||||
|
|
||||||
|
// Apply original height to maintain uniformity
|
||||||
|
if (originalHeight && newIndex !== 0) {
|
||||||
|
heroImage.style.height = originalHeight + "px";
|
||||||
|
heroImage.style.objectFit = "cover";
|
||||||
|
} else if (newIndex === 0) {
|
||||||
|
// Reset to original for the first image
|
||||||
|
heroImage.style.height = "auto";
|
||||||
|
heroImage.style.objectFit = "initial";
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fade in new image
|
||||||
|
heroImage.style.opacity = "1";
|
||||||
|
|
||||||
|
// Update indicators
|
||||||
|
updateIndicators(newIndex);
|
||||||
|
}, 300);
|
||||||
|
};
|
||||||
|
newImage.src = carouselImages[newIndex];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Function to update carousel indicators
|
||||||
|
function updateIndicators(activeIndex) {
|
||||||
|
for (let i = 0; i < 5; i++) {
|
||||||
|
const indicator = document.getElementById(`carousel-indicator-${i}`);
|
||||||
|
if (indicator) {
|
||||||
|
indicator.style.opacity = i === activeIndex ? "1" : "0.5";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Arrow button click handler
|
||||||
|
arrowButton.addEventListener("click", (e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
e.stopPropagation();
|
||||||
|
currentImageIndex = (currentImageIndex + 1) % carouselImages.length;
|
||||||
|
updateImage(currentImageIndex);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Indicator click handlers
|
||||||
|
for (let i = 0; i < 5; i++) {
|
||||||
|
const indicator = document.getElementById(`carousel-indicator-${i}`);
|
||||||
|
if (indicator) {
|
||||||
|
indicator.addEventListener("click", (e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
e.stopPropagation();
|
||||||
|
currentImageIndex = i;
|
||||||
|
updateImage(currentImageIndex);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Capture original height after image loads
|
||||||
|
if (heroImage.complete) {
|
||||||
|
captureOriginalHeight();
|
||||||
|
} else {
|
||||||
|
heroImage.addEventListener("load", captureOriginalHeight);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Auto-advance carousel every 5 seconds
|
||||||
|
setInterval(() => {
|
||||||
|
currentImageIndex = (currentImageIndex + 1) % carouselImages.length;
|
||||||
|
updateImage(currentImageIndex);
|
||||||
|
}, 5000);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Version: 4.7 - Use original image height as standard for carousel uniformity
|
||||||
|
|
|
||||||
2487
styles/main.css
2487
styles/main.css
File diff suppressed because one or more lines are too long
Loading…
Add table
Add a link
Reference in a new issue