Compare commits

...

2 Commits

Author SHA1 Message Date
Atash03 922c786dc9 fix: address 2026-04-11 16:57:20 +05:00
Atash03 60f4855b06 make image preview dialog 2026-04-11 16:53:15 +05:00
5 changed files with 170 additions and 63 deletions

2
dist/styles.css vendored

File diff suppressed because one or more lines are too long

View File

@ -229,38 +229,27 @@
<h2 class="text-3xl md:text-4xl lg:text-5xl font-black text-on-surface mb-8 md:mb-12 lg:mb-16 tracking-tight" data-i18n="completed_projects">Реализованные проекты</h2>
<div class="grid grid-cols-1 lg:grid-cols-2 gap-px bg-outline-variant overflow-hidden">
<!-- Project 1: Water Treatment Plant -->
<div class="group relative bg-background overflow-hidden aspect-video lg:aspect-square">
<div class="carousel absolute inset-0" data-autoplay="4000">
<img class="carousel-slide active w-full h-full object-cover" loading="lazy" decoding="async" src="public/tejen_1.webp" alt="Tejen water treatment plant 1" />
<img class="carousel-slide w-full h-full object-cover" loading="lazy" decoding="async" src="public/tejen_2.webp" alt="Tejen water treatment plant 2" />
<img class="carousel-slide w-full h-full object-cover" loading="lazy" decoding="async" src="public/tejen_3.webp" alt="Tejen water treatment plant 3" />
<img class="carousel-slide w-full h-full object-cover" loading="lazy" decoding="async" src="public/tejen_4.webp" alt="Tejen water treatment plant 4" />
<img class="carousel-slide w-full h-full object-cover" loading="lazy" decoding="async" src="public/tejen_5.webp" alt="Tejen water treatment plant 5" />
<img class="carousel-slide w-full h-full object-cover" loading="lazy" decoding="async" src="public/tejen_6.webp" alt="Tejen water treatment plant 6" />
<img class="carousel-slide w-full h-full object-cover" loading="lazy" decoding="async" src="public/tejen_7.webp" alt="Tejen water treatment plant 7" />
<button class="carousel-prev" aria-label="Previous">&lsaquo;</button>
<button class="carousel-next" aria-label="Next">&rsaquo;</button>
<div class="carousel-dots"></div>
</div>
<div
class="absolute inset-0 bg-primary/80 opacity-0 group-hover:opacity-100 transition-opacity duration-500 p-4 md:p-8 lg:p-12 flex flex-col justify-end text-on-primary z-20">
<h4 class="text-xl md:text-2xl lg:text-3xl font-bold mb-2" data-i18n="project1_title">Водоочистное сооружение в г. Теджен</h4>
<p class="text-sm opacity-90" data-i18n="project1_desc">Строительство водоочистного сооружения мощностью 30 000 м³ в сутки в городе Теджен Ахалского велаята — завершён 2024 г.</p>
<div class="group relative bg-background overflow-hidden aspect-video lg:aspect-square cursor-pointer"
data-lightbox
data-lightbox-images='["public/tejen_1.webp","public/tejen_2.webp","public/tejen_3.webp","public/tejen_4.webp","public/tejen_5.webp","public/tejen_6.webp","public/tejen_7.webp"]'
data-lightbox-title="project1_title"
data-lightbox-desc="project1_desc">
<img class="w-full h-full object-cover transition-transform duration-500 group-hover:scale-105" loading="lazy" decoding="async" src="public/tejen_1.webp" alt="Tejen water treatment plant" />
<div class="absolute inset-x-0 bottom-0 bg-gradient-to-t from-black/70 via-black/30 to-transparent p-4 md:p-8 lg:p-12 flex flex-col justify-end z-10 pointer-events-none">
<h4 class="text-xl md:text-2xl lg:text-3xl font-bold text-white mb-1" data-i18n="project1_title">Водоочистное сооружение в г. Теджен</h4>
<p class="text-sm text-white/80" data-i18n="project1_desc">Строительство водоочистного сооружения мощностью 30 000 м³ в сутки в городе Теджен Ахалского велаята — завершён 2024 г.</p>
</div>
</div>
<!-- Project 2: Power Supply System -->
<div class="group relative bg-background overflow-hidden aspect-video lg:aspect-square">
<div class="carousel absolute inset-0" data-autoplay="4000">
<img class="carousel-slide active w-full h-full object-cover" loading="lazy" decoding="async" src="public/electric_1.webp" alt="Power supply infrastructure 1" />
<img class="carousel-slide w-full h-full object-cover" loading="lazy" decoding="async" src="public/electric_2.webp" alt="Power supply infrastructure 2" />
<button class="carousel-prev" aria-label="Previous">&lsaquo;</button>
<button class="carousel-next" aria-label="Next">&rsaquo;</button>
<div class="carousel-dots"></div>
</div>
<div
class="absolute inset-0 bg-primary/80 opacity-0 group-hover:opacity-100 transition-opacity duration-500 p-4 md:p-8 lg:p-12 flex flex-col justify-end text-on-primary z-20">
<h4 class="text-xl md:text-2xl lg:text-3xl font-bold mb-2" data-i18n="project2_title">Электроснабжение водоочистного сооружения</h4>
<p class="text-sm opacity-90" data-i18n="project2_desc">Строительно-монтажные работы по внешней системе электроснабжения водоочистного сооружения мощностью 30 000 м³ в сутки в г. Теджен — завершён 2026 г.</p>
<div class="group relative bg-background overflow-hidden aspect-video lg:aspect-square cursor-pointer"
data-lightbox
data-lightbox-images='["public/electric_1.webp","public/electric_2.webp"]'
data-lightbox-title="project2_title"
data-lightbox-desc="project2_desc">
<img class="w-full h-full object-cover transition-transform duration-500 group-hover:scale-105" loading="lazy" decoding="async" src="public/electric_1.webp" alt="Power supply infrastructure" />
<div class="absolute inset-x-0 bottom-0 bg-gradient-to-t from-black/70 via-black/30 to-transparent p-4 md:p-8 lg:p-12 flex flex-col justify-end z-10 pointer-events-none">
<h4 class="text-xl md:text-2xl lg:text-3xl font-bold text-white mb-1" data-i18n="project2_title">Электроснабжение водоочистного сооружения</h4>
<p class="text-sm text-white/80" data-i18n="project2_desc">Строительно-монтажные работы по внешней системе электроснабжения водоочистного сооружения мощностью 30 000 м³ в сутки в г. Теджен — завершён 2026 г.</p>
</div>
</div>
</div>
@ -280,14 +269,22 @@
<h3 class="text-xl md:text-2xl lg:text-3xl font-black mt-2 mb-4 uppercase tracking-tight" data-i18n="current1_title">Водоочистное сооружение в Бабадайханском районе</h3>
<p class="text-primary-fixed leading-relaxed" data-i18n="current1_desc">Строительство водоочистного сооружения мощностью 20 000 м³ в сутки в Бабадайханском районе Ахалского велаята (Туркменистан).</p>
</div>
<div class="relative aspect-video overflow-hidden">
<img class="w-full h-full object-cover" loading="lazy" decoding="async" src="public/babdayhan.webp" alt="Babadayhan water treatment plant" />
<div class="group/img relative aspect-video overflow-hidden cursor-pointer"
data-lightbox
data-lightbox-images='["public/babdayhan.webp"]'
data-lightbox-title="current1_title"
data-lightbox-desc="current1_desc">
<img class="w-full h-full object-cover transition-transform duration-500 group-hover/img:scale-105" loading="lazy" decoding="async" src="public/babdayhan.webp" alt="Babadayhan water treatment plant" />
</div>
</div>
<!-- Current Project 2: carousel left, text right -->
<div class="grid grid-cols-1 lg:grid-cols-2 gap-8 md:gap-12 items-center">
<div class="relative aspect-video overflow-hidden order-2 lg:order-1">
<img class="w-full h-full object-cover" loading="lazy" decoding="async" src="public/garashsyzlyk.webp" alt="Garashsyzlyk water supply" />
<div class="group/img relative aspect-video overflow-hidden order-2 lg:order-1 cursor-pointer"
data-lightbox
data-lightbox-images='["public/garashsyzlyk.webp"]'
data-lightbox-title="current2_title"
data-lightbox-desc="current2_desc">
<img class="w-full h-full object-cover transition-transform duration-500 group-hover/img:scale-105" loading="lazy" decoding="async" src="public/garashsyzlyk.webp" alt="Garashsyzlyk water supply" />
</div>
<div class="order-1 lg:order-2">
<span class="text-xs uppercase font-bold tracking-widest text-primary-fixed/60" data-i18n="current2_status">Статус: В процессе</span>
@ -308,7 +305,7 @@
<span class="material-symbols-outlined text-primary text-3xl">location_on</span>
<div>
<h5 class="font-bold text-on-surface uppercase text-xs tracking-widest mb-2" data-i18n="address_label">Юридический адрес</h5>
<p class="text-sm md:text-lg text-on-surface-variant" data-i18n-html="address_text">Ашхабад, Туркменистан</p>
<p class="text-sm md:text-lg text-on-surface-variant" data-i18n-html="address_text">Туркменистан, Ашхабад, Беркарарлыкский район, улица Г. Гулиева (2127), дом 64</p>
</div>
</div>
<div class="flex gap-6">
@ -386,7 +383,8 @@
<div>
<h5 class="text-primary font-bold mb-6 uppercase text-xs tracking-widest" data-i18n="footer_contact">Контакты</h5>
<p class="text-sm text-[#2a3439]/60 font-['Inter'] tracking-wide" data-i18n-html="footer_contact_info">
Ашхабад, Туркменистан<br />
Туркменистан, Ашхабад, Беркарарлыкский район,<br />
ул. Г. Гулиева (2127), дом 64<br />
info@netijelibinyat.com<br />
+993 12 753506
</p>
@ -405,8 +403,31 @@
</div>
</footer>
<!-- Lightbox -->
<div id="lightbox" class="lightbox fixed inset-0 z-[80] flex items-center justify-center p-4 md:p-8 bg-black/80">
<div id="lightbox-content" class="relative w-full max-w-5xl max-h-[90vh] flex flex-col">
<div id="lightbox-counter" class="absolute top-4 left-4 z-20 text-white/90 text-sm font-bold bg-black/50 backdrop-blur-sm px-3 py-1.5 rounded-sm"></div>
<button id="lightbox-close" class="absolute top-4 right-4 z-20 w-10 h-10 flex items-center justify-center text-white/90 hover:text-white bg-black/50 hover:bg-black/70 backdrop-blur-sm rounded-sm transition-colors" aria-label="Close">
<span class="material-symbols-outlined">close</span>
</button>
<div class="relative flex-1 min-h-0 flex items-center justify-center bg-black rounded-t-sm overflow-hidden">
<img id="lightbox-image" class="max-w-full max-h-[calc(90vh-5rem)] object-contain select-none" draggable="false" alt="" />
<button id="lightbox-prev" class="absolute left-3 top-1/2 -translate-y-1/2 w-11 h-11 md:w-12 md:h-12 flex items-center justify-center bg-black/40 hover:bg-black/60 text-white/90 hover:text-white backdrop-blur-sm rounded-sm transition-colors" aria-label="Previous">
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><path d="M15 18l-6-6 6-6"/></svg>
</button>
<button id="lightbox-next" class="absolute right-3 top-1/2 -translate-y-1/2 w-11 h-11 md:w-12 md:h-12 flex items-center justify-center bg-black/40 hover:bg-black/60 text-white/90 hover:text-white backdrop-blur-sm rounded-sm transition-colors" aria-label="Next">
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><path d="M9 18l6-6-6-6"/></svg>
</button>
</div>
<div class="bg-white p-4 md:p-6 rounded-b-sm">
<h4 id="lightbox-title" class="text-base md:text-lg font-bold text-on-surface"></h4>
<p id="lightbox-desc" class="text-sm text-on-surface-variant mt-1"></p>
</div>
</div>
</div>
<script src="js/i18n.js"></script>
<script src="js/carousel.js"></script>
<script src="js/lightbox.js"></script>
<script>
const drawer = document.getElementById('mobile-drawer');
const backdrop = document.getElementById('drawer-backdrop');

View File

@ -38,7 +38,7 @@ const translations = {
current2_status: "Статус: В процессе", current2_title: "Водоснабжение генгешлика Гарашызлык",
current2_desc: "Строительство системы водоснабжения генгешлика Гарашызлык в Теженском районе Ахалского велаята (Туркменистан).",
contacts_title: "Контакты", address_label: "Юридический адрес",
address_text: "Ашхабад, Туркменистан",
address_text: "Туркменистан, Ашхабад, Беркарарлыкский район, улица Г. Гулиева (2127), дом 64",
phones_label: "Телефоны",
phones_text: "+993 12 753506",
email_text: "info@netijelibinyat.com",
@ -50,7 +50,7 @@ const translations = {
footer_desc: "Строительная компания полного цикла. Качество, проверенное временем и проектами.",
footer_nav: "Навигация", footer_legal: "Правовая информация", footer_contact: "Контакты",
privacy_policy: "Политика конфиденциальности",
footer_contact_info: "Ашхабад, Туркменистан<br />info@netijelibinyat.com<br />+993 12 753506",
footer_contact_info: "Туркменистан, Ашхабад, Беркарарлыкский район,<br />ул. Г. Гулиева (2127), дом 64<br />info@netijelibinyat.com<br />+993 12 753506",
footer_copyright: "© 2021 Netijeli binyat. Все права защищены."
},
en: {
@ -92,7 +92,7 @@ const translations = {
current2_status: "Status: In Progress", current2_title: "Water Supply for Garashsyzlyk Gengeshlyk",
current2_desc: "Construction of the water supply system for Garashsyzlyk gengeshlyk in Tejen district, Ahal Velayat (Turkmenistan).",
contacts_title: "Contacts", address_label: "Legal address",
address_text: "Ashgabat, Turkmenistan",
address_text: "Turkmenistan, Ashgabat, Berkararlyk district, G. Guliyev street (2127), building 64",
phones_label: "Phones",
phones_text: "+993 12 753506",
email_text: "info@netijelibinyat.com",
@ -104,7 +104,7 @@ const translations = {
footer_desc: "Full-cycle construction company. Quality proven by time and projects.",
footer_nav: "Navigation", footer_legal: "Legal", footer_contact: "Contact",
privacy_policy: "Privacy Policy",
footer_contact_info: "Ashgabat, Turkmenistan<br />info@netijelibinyat.com<br />+993 12 753506",
footer_contact_info: "Turkmenistan, Ashgabat, Berkararlyk district,<br />G. Guliyev street (2127), building 64<br />info@netijelibinyat.com<br />+993 12 753506",
footer_copyright: "\u00A9 2021 Netijeli binyat. All rights reserved."
},
tk: {
@ -146,7 +146,7 @@ const translations = {
current2_status: "\u00ddagda\u00fd: Dowam ed\u00fd\u00e4r", current2_title: "Gara\u015fsyzlyk gen\u011fe\u015fligini\u0148 suw \u00fcpj\u00fcn\u00e7iligi",
current2_desc: "T\u00fcrkmenistanyng Ahal wela\u00fdatynyng Tejen etrabynda Gara\u015fsyzlyk gen\u011fe\u015fligini\u0148 suw \u00fcpj\u00fcn\u00e7ilik ulgamyny gurmak.",
contacts_title: "Habarla\u015fmak", address_label: "\u00dduridiki salgysy",
address_text: "A\u015fgabat, T\u00fcrkmenistan",
address_text: "T\u00fcrkmenistan, A\u015fgabat, Berkararlyk etraby, G. Guly\u00fdew k\u00f6\u00e7esi (2127), 64-nji ja\u00fd",
phones_label: "Telefonlar",
phones_text: "+993 12 753506",
email_text: "info@netijelibinyat.com",
@ -158,7 +158,7 @@ const translations = {
footer_desc: "Doly siklly gurlu\u015fyk kompani\u00fdasy. Wagt we taslamalar bilen subut edilen hil.",
footer_nav: "Nawigasi\u00fda", footer_legal: "Hukuk maglumatlary", footer_contact: "Habarla\u015fmak",
privacy_policy: "Gizlinlik sy\u00fdasaty",
footer_contact_info: "A\u015fgabat, T\u00fcrkmenistan<br />info@netijelibinyat.com<br />+993 12 753506",
footer_contact_info: "T\u00fcrkmenistan, A\u015fgabat, Berkararlyk etraby,<br />G. Guly\u00fdew k\u00f6\u00e7esi (2127), 64-nji ja\u00fd<br />info@netijelibinyat.com<br />+993 12 753506",
footer_copyright: "\u00a9 2021 Netijeli binyat. \u00c4hli hukuklar goralan."
}
};

98
js/lightbox.js Normal file
View File

@ -0,0 +1,98 @@
(function () {
const lightbox = document.getElementById('lightbox');
const content = document.getElementById('lightbox-content');
const image = document.getElementById('lightbox-image');
const title = document.getElementById('lightbox-title');
const desc = document.getElementById('lightbox-desc');
const counter = document.getElementById('lightbox-counter');
const prevBtn = document.getElementById('lightbox-prev');
const nextBtn = document.getElementById('lightbox-next');
const closeBtn = document.getElementById('lightbox-close');
let images = [];
let current = 0;
let touchStartX = 0;
function open(imgArray, titleKey, descKey) {
images = imgArray;
current = 0;
const lang = localStorage.getItem('lang') || 'ru';
title.textContent = translations[lang][titleKey] || '';
title.dataset.i18n = titleKey;
desc.textContent = translations[lang][descKey] || '';
desc.dataset.i18n = descKey;
updateImage();
updateNav();
lightbox.classList.add('open');
document.body.style.overflow = 'hidden';
}
function close() {
lightbox.classList.remove('open');
document.body.style.overflow = '';
}
function goTo(index) {
current = (index + images.length) % images.length;
updateImage();
}
function updateImage() {
image.src = images[current];
if (images.length > 1) {
counter.textContent = (current + 1) + ' / ' + images.length;
counter.style.display = '';
} else {
counter.style.display = 'none';
}
}
function updateNav() {
const multi = images.length > 1;
prevBtn.style.display = multi ? '' : 'none';
nextBtn.style.display = multi ? '' : 'none';
}
// Close handlers
closeBtn.addEventListener('click', close);
lightbox.addEventListener('click', function (e) {
if (e.target === lightbox) close();
});
content.addEventListener('click', function (e) {
e.stopPropagation();
});
// Navigation
prevBtn.addEventListener('click', function () { goTo(current - 1); });
nextBtn.addEventListener('click', function () { goTo(current + 1); });
// Keyboard
document.addEventListener('keydown', function (e) {
if (!lightbox.classList.contains('open')) return;
if (e.key === 'Escape') { close(); e.preventDefault(); }
if (e.key === 'ArrowLeft') { goTo(current - 1); e.preventDefault(); }
if (e.key === 'ArrowRight') { goTo(current + 1); e.preventDefault(); }
});
// Touch swipe
lightbox.addEventListener('touchstart', function (e) {
touchStartX = e.changedTouches[0].screenX;
}, { passive: true });
lightbox.addEventListener('touchend', function (e) {
var diff = touchStartX - e.changedTouches[0].screenX;
if (Math.abs(diff) > 50) {
goTo(diff > 0 ? current + 1 : current - 1);
}
});
// Initialize triggers
document.querySelectorAll('[data-lightbox]').forEach(function (el) {
el.addEventListener('click', function () {
var imgs = JSON.parse(el.dataset.lightboxImages);
open(imgs, el.dataset.lightboxTitle, el.dataset.lightboxDesc);
});
});
})();

View File

@ -90,28 +90,16 @@
.lang-btn { color: rgba(42, 52, 57, 0.4); }
.lang-btn.active { color: #3a5f94; background: rgba(58, 95, 148, 0.1); }
.carousel { position: relative; }
.carousel-slide { position: absolute; inset: 0; opacity: 0; transition: opacity 1s ease; }
.carousel-slide.active { opacity: 0.9; }
.carousel-prev, .carousel-next {
position: absolute; top: 50%; transform: translateY(-50%); z-index: 10;
width: 40px; height: 40px; background: rgba(255, 255, 255, 0.8); border: none;
font-size: 24px; line-height: 1; cursor: pointer; color: #2a3439;
opacity: 0; transition: opacity 0.3s;
/* Lightbox */
.lightbox {
opacity: 0;
pointer-events: none;
transition: opacity 0.25s ease;
}
.carousel:hover .carousel-prev, .carousel:hover .carousel-next { opacity: 1; }
.carousel-prev { left: 12px; }
.carousel-next { right: 12px; }
.carousel-prev:hover, .carousel-next:hover { background: #fff; }
.carousel-dots {
position: absolute; bottom: 12px; left: 50%; transform: translateX(-50%);
display: flex; gap: 6px; z-index: 10;
.lightbox.open {
opacity: 1;
pointer-events: auto;
}
.carousel-dot {
width: 8px; height: 8px; border-radius: 50%; border: none; cursor: pointer;
background: rgba(255, 255, 255, 0.5); transition: background 0.3s;
}
.carousel-dot.active { background: #fff; }
/* Mobile drawer */
.mobile-drawer { transform: translateX(100%); transition: transform 0.3s ease; }