diff --git a/src/_data/navLinks.json b/src/_data/navLinks.json index 1bfd6cf..bc038a7 100644 --- a/src/_data/navLinks.json +++ b/src/_data/navLinks.json @@ -14,5 +14,9 @@ { "link":"https://play.mlut.style/", "text":"Sandbox" + }, + { + "link":"/showcase", + "text":"Showcase" } ] diff --git a/src/_data/users.json b/src/_data/users.json new file mode 100644 index 0000000..c417229 --- /dev/null +++ b/src/_data/users.json @@ -0,0 +1,58 @@ +[ + { + "id": 1, + "name": "John Smith", + "age": 31, + "avatar": ["/assets/avatars/Emily_Blunt-new.jpg", "/assets/avatars/Koshak_Koteevich.jpg"], + "quote": "Все, что человеческий разум способен понять и во что он способен поверить, достижимо." + }, + { + "id": 2, + "name": "Emily Blunt", + "age": 27, + "avatar": ["/assets/avatars/John_Smith-new.jpg", "/assets/avatars/Emily_Blunt-new.jpg", "/assets/avatars/Koshak_Koteevich.jpg"], + "quote": "Сложнее всего начать действовать, все остальное зависит только от упорства." + }, + { + "id": 3, + "name": "Koshak Koteevich", + "age": 18, + "avatar": ["/assets/avatars/Tigra_Leopardovich.jpg", "/assets/avatars/Emily_Blunt-new.jpg", "/assets/avatars/Koshak_Koteevich.jpg"], + "quote": "Неудача — это возможность начать заново, но уже более мудро." + }, + { + "id": 4, + "name": "Luna Lovegood", + "age": 21, + "avatar": ["/assets/avatars/orange-wood-table.jpg", "/assets/avatars/Koshak_Koteevich.jpg"], + "quote": "Если проблему можно решить, не стоит о ней беспокоиться. Сложнее всего начать действовать, все остальное зависит только от упорства." + }, + { + "id": 5, + "name": "Milana Clark", + "age": 39, + "avatar": ["/assets/avatars/Panda_Padlovna.jpg", "/assets/avatars/orange-wood-table.jpg", "/assets/avatars/Emily_Blunt-new.jpg", "/assets/avatars/Koshak_Koteevich.jpg"], + "quote": "Обстоятельства часто можно изменить, изменив свое отношение к ним." + }, + { + "id": 6, + "name": "Leopardovskiy Orange Apelsinovich", + "age": 26, + "avatar": ["/assets/avatars/Koshak_Koteevich.jpg", "/assets/avatars/Emily_Blunt-new.jpg"], + "quote": "Обстоятельства часто можно изменить, изменив свое отношение к ним." + }, + { + "id": 7, + "name": "Panda Padlovna", + "age": 45, + "avatar": ["/assets/avatars/Milana_Clark-new.jpg", "/assets/avatars/Koshak_Koteevich.jpg"], + "quote": "Вдохновение приходит только во время работы. Обстоятельства часто можно изменить, изменив свое отношение к ним." + }, + { + "id": 8, + "name": "Tigra Leopardovich", + "age": 35, + "avatar": ["/assets/avatars/Luna_Lovegood-new.jpg", "/assets/avatars/Emily_Blunt-new.jpg", "/assets/avatars/Koshak_Koteevich.jpg", "/assets/avatars/Panda_Padlovna.jpg"], + "quote": "Если проблему можно решить, не стоит о ней беспокоиться." + } + ] diff --git a/src/_includes/components/show-card.ejs b/src/_includes/components/show-card.ejs new file mode 100644 index 0000000..f023a94 --- /dev/null +++ b/src/_includes/components/show-card.ejs @@ -0,0 +1,43 @@ +<% + const tag = it.optTag ?? 'li'; + const avatars = it.avatar && Array.isArray(it.avatar) ? it.avatar : []; + const defaultAvatar = avatars[0] || ''; +%> + +<<%= tag %> class=""> + +
+ <% if (defaultAvatar) { %> + <%= it.name %> + <% } %> + +
+ <% for (let i = 0; i < avatars.length; i++) { %> + + <% } %> +
+ + +
+
+ <%= it.name ?? '' %> + <%= it.quote ?? '' %> +
+
+> + + diff --git a/src/assets/avatars/Emily_Blunt-new.jpg b/src/assets/avatars/Emily_Blunt-new.jpg new file mode 100644 index 0000000..21a1442 Binary files /dev/null and b/src/assets/avatars/Emily_Blunt-new.jpg differ diff --git a/src/assets/avatars/John_Smith-new.jpg b/src/assets/avatars/John_Smith-new.jpg new file mode 100644 index 0000000..e52cc58 Binary files /dev/null and b/src/assets/avatars/John_Smith-new.jpg differ diff --git a/src/assets/avatars/Koshak_Koteevich.jpg b/src/assets/avatars/Koshak_Koteevich.jpg new file mode 100644 index 0000000..c28da5c Binary files /dev/null and b/src/assets/avatars/Koshak_Koteevich.jpg differ diff --git a/src/assets/avatars/Luna_Lovegood-new.jpg b/src/assets/avatars/Luna_Lovegood-new.jpg new file mode 100644 index 0000000..a39e993 Binary files /dev/null and b/src/assets/avatars/Luna_Lovegood-new.jpg differ diff --git a/src/assets/avatars/Milana_Clark-new.jpg b/src/assets/avatars/Milana_Clark-new.jpg new file mode 100644 index 0000000..48b4e2d Binary files /dev/null and b/src/assets/avatars/Milana_Clark-new.jpg differ diff --git a/src/assets/avatars/Orange_Apelsinovich.jpg b/src/assets/avatars/Orange_Apelsinovich.jpg new file mode 100644 index 0000000..e49e54b Binary files /dev/null and b/src/assets/avatars/Orange_Apelsinovich.jpg differ diff --git a/src/assets/avatars/Panda_Padlovna.jpg b/src/assets/avatars/Panda_Padlovna.jpg new file mode 100644 index 0000000..7cbf5cc Binary files /dev/null and b/src/assets/avatars/Panda_Padlovna.jpg differ diff --git a/src/assets/avatars/Tigra_Leopardovich.jpg b/src/assets/avatars/Tigra_Leopardovich.jpg new file mode 100644 index 0000000..88de38d Binary files /dev/null and b/src/assets/avatars/Tigra_Leopardovich.jpg differ diff --git a/src/assets/avatars/orange-wood-table.jpg b/src/assets/avatars/orange-wood-table.jpg new file mode 100644 index 0000000..c56546e Binary files /dev/null and b/src/assets/avatars/orange-wood-table.jpg differ diff --git a/src/assets/img/arrow.svg b/src/assets/img/arrow.svg new file mode 100644 index 0000000..27f3198 --- /dev/null +++ b/src/assets/img/arrow.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/src/assets/script/hover-switch-image.js b/src/assets/script/hover-switch-image.js new file mode 100644 index 0000000..a233609 --- /dev/null +++ b/src/assets/script/hover-switch-image.js @@ -0,0 +1,162 @@ +document.addEventListener("DOMContentLoaded", () => { + // Медиа-запрос + const mediaQuery = window.matchMedia("(max-width: 769px)"); + + // Функция для получения текущего режима + const isMobile = () => mediaQuery.matches; + + // Находим все изображения + const images = document.querySelectorAll(".hover-switch-image"); + + images.forEach((img) => { + let imagesList = []; + try { + imagesList = JSON.parse(img.dataset.images); + } catch (e) {} + if (!imagesList.length) return; + + const originalSrc = imagesList[0]; + let currentIndex = 0; + + // DOM-элементы + const container = img.closest(".container"); + if (!container) return; + + const indicator = container.querySelector(".image-indicator"); + if (!indicator) return; + const dots = indicator.querySelectorAll(".indicator-dot"); + const totalImages = imagesList.length; + + const backBtn = container.querySelector(".back"); + const nextBtn = container.querySelector(".next"); + + // Функция обновления активной точки + const setActiveDot = (index) => { + dots.forEach((dot, i) => { + if (i === index) dot.classList.add("active"); + else dot.classList.remove("active"); + }); + }; + + // Функция обновления видимости кнопок в мобильном режиме + const updateMobileButtons = () => { + if (!backBtn || !nextBtn) return; + if (!isMobile()) return; // на десктопе кнопки скрыты + if (currentIndex === 0) { + backBtn.classList.add('D-n'); + nextBtn.classList.remove('D-n'); + } else if (currentIndex === totalImages - 1) { + backBtn.classList.remove('D-n'); + nextBtn.classList.add('D-n'); + } else { + backBtn.classList.remove('D-n'); + nextBtn.classList.remove('D-n'); + } + }; + + // Функция смены изображения + const setImageByIndex = (newIndex) => { + if (newIndex < 0) newIndex = 0; + if (newIndex >= totalImages) newIndex = totalImages - 1; + if (newIndex === currentIndex) return; + currentIndex = newIndex; + img.src = imagesList[currentIndex]; + setActiveDot(currentIndex); + if (isMobile()) { + updateMobileButtons(); + }; + }; + + // Сброс к первому изображению (при уходе мыши или смене режима) + const resetToFirst = () => { + setImageByIndex(0); + setActiveDot(0) + }; + + // --- Обработчики событий, общие для обоих режимов --- + + // Движение мыши – работает только на десктопе + img.addEventListener("mousemove", (e) => { + if (isMobile()) return; // игнорируем на мобильных + const rect = img.getBoundingClientRect(); + const x = e.clientX - rect.left; + const width = rect.width; + const ratio = x / width; + let newIndex = Math.floor(ratio * totalImages); + if (newIndex >= totalImages) newIndex = totalImages - 1; + if (newIndex !== currentIndex) { + setImageByIndex(newIndex); + } + }); + + // Показ индикатора (только на десктопе) + img.addEventListener("mouseenter", () => { + if (isMobile()) return; + indicator.classList.remove("D-n"); + setActiveDot(0); + if (img.src !== originalSrc) { + img.src = originalSrc; + currentIndex = 0; + } + }); + + // Скрытие индикатора и сброс (только на десктопе) + img.addEventListener("mouseleave", () => { + if (isMobile()) return; + indicator.classList.add("D-n"); + if (img.src !== originalSrc) { + img.src = originalSrc; + currentIndex = 0; + setActiveDot(0); + } + }); + + // Клик на кнопку "назад" + if (backBtn) { + backBtn.addEventListener("click", (e) => { + e.preventDefault(); + e.stopPropagation(); + if (!isMobile()) return; + setImageByIndex(currentIndex - 1); + }); + } + + // Клик на кнопку "вперёд" + if (nextBtn) { + nextBtn.addEventListener("click", (e) => { + e.preventDefault(); + e.stopPropagation(); + if (!isMobile()) return; + setImageByIndex(currentIndex + 1); + }); + } + + // --- Функция переключения режима при изменении ширины --- + const switchMode = () => { + if (isMobile()) { + // Мобильный режим: показываем индикатор и кнопки + indicator.classList.remove("D-n"); + if (backBtn) backBtn.classList.remove("D-n"); + if (nextBtn) nextBtn.classList.remove("D-n"); + resetToFirst(); + updateMobileButtons(); + } else { + // Десктопный режим: скрываем индикатор и кнопки + indicator.classList.add("D-n"); + if (backBtn) { + backBtn.classList.add("D-n"); + } + if (nextBtn) { + nextBtn.classList.add("D-n"); + } + resetToFirst(); + } + }; + + // Слушаем изменение ширины + mediaQuery.addEventListener("change", switchMode); + + // Первоначальная настройка + switchMode(); + }); +}); diff --git a/src/assets/style/style.scss b/src/assets/style/style.scss index 0317d62..80f50cf 100644 --- a/src/assets/style/style.scss +++ b/src/assets/style/style.scss @@ -41,6 +41,10 @@ html{ --ml-blueGray:rgb(236, 240, 246,0.5); --ml-gray200:#d1d5db; --ml-gray350:#cacacaa0; + // + --ml-castomWidth: calc(100% + 280px); + --ml-imageGradient: + repeating-linear-gradient(315deg, var(--ml-accent750) 0 1px, transparent 1px 6px ); } @@ -159,3 +163,18 @@ html{ } +// .gtc-auto-fit { +// grid-template-columns: repeat(auto-fit, minmax(320px, 1fr)); +// } + +.indicator-dot.active { + opacity: 1; + transform: scale(1.2); +} + +.webkit { + display: -webkit-box; + -webkit-box-orient: vertical; + -webkit-line-clamp: 2; + line-clamp: 2; +} \ No newline at end of file diff --git a/src/layouts/base.ejs b/src/layouts/base.ejs index bc7dc0f..80f6c9d 100644 --- a/src/layouts/base.ejs +++ b/src/layouts/base.ejs @@ -17,7 +17,7 @@ if (it.area === "main"){ - + mlut - make CSS exciting again! @@ -35,5 +35,6 @@ if (it.area === "main"){ + \ No newline at end of file diff --git a/src/showcase.ejs b/src/showcase.ejs new file mode 100644 index 0000000..f314bd0 --- /dev/null +++ b/src/showcase.ejs @@ -0,0 +1,29 @@ +--- +title: Showcase +layout: base.ejs +--- + +
+
+
+
+

Mlut is more than just CSS

+
+
+ +
+
+
+
+ + \ No newline at end of file