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) { %>
+

+ <% } %>
+
+
+ <% for (let i = 0; i < avatars.length; i++) { %>
+
+ <% } %>
+
+
+
+
+
+ <%= it.name ?? '' %>
+ <%= it.quote ?? '' %>
+
+
+<%= tag %>>
+
+
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"){
+