maverick-wave 3.3.1 → 3.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- !function(){"use strict";function e(){document.querySelectorAll(".color-swatch").forEach(e=>{const t=function(e){if(!e||"transparent"===e)return"#000000";const t=e=>Math.max(0,Math.min(255,Math.round(e))).toString(16).padStart(2,"0"),c=e.match(/color\(srgb\s+([\d.]+)\s+([\d.]+)\s+([\d.]+)(?:\s*\/\s*([\d.]+))?\)/);if(c){const e="#"+t(255*c[1])+t(255*c[2])+t(255*c[3]),o=void 0===c[4]?1:parseFloat(c[4]);return(o<1?`${e} / ${o}`:e).toUpperCase()}const o=e.match(/rgba?\((\d+),\s*(\d+),\s*(\d+)(?:,\s*([\d.]+))?\)/);if(!o)return e;const n="#"+t(o[1])+t(o[2])+t(o[3]),s=void 0===o[4]?1:parseFloat(o[4]);return(s<1?`${n} / ${s}`:n).toUpperCase()}(window.getComputedStyle(e).backgroundColor),c=e.parentElement.querySelector(".mw-text-muted");c&&(c.textContent=t)})}document.addEventListener("DOMContentLoaded",function(){!function(){const e=document.querySelector(".mw-gallery-track");if(e){const t=document.querySelector(".mw-gallery-dots"),c=e.children,o=document.querySelector(".mw-gallery-desc"),n=document.querySelector(".mw-gallery-navi-prev"),s=document.querySelector(".mw-gallery-navi-next"),l=document.querySelector(".mw-gallery");let r=0;function a(){const t=l.offsetWidth;e.style.transform=`translateX(-${r*t}px)`}function i(e){const t=c.length;r=(e+t)%t,a(),document.querySelectorAll(".mw-gallery-dot").forEach((e,t)=>{e.classList.toggle("mw-active",t===r)}),o.textContent=c[r].dataset.desc}function d(){for(let e=0;e<c.length;e++){const c=document.createElement("span");c.className="mw-gallery-dot"+(0===e?" mw-active":""),c.addEventListener("click",()=>i(e)),t.appendChild(c)}}n.addEventListener("click",()=>i(r-1)),s.addEventListener("click",()=>i(r+1)),window.addEventListener("resize",a);let u=0;e.addEventListener("touchstart",e=>u=e.touches[0].clientX),e.addEventListener("touchend",e=>{const t=e.changedTouches[0].clientX-u;t>50&&i(r-1),t<-50&&i(r+1)}),d(),a()}}(),function(){const t=document.querySelector(".mw-theme-toggle");if(!t)return;const c=document.body,o=t.querySelector(".mw-theme-toggle-slider i"),n=getComputedStyle(document.documentElement).getPropertyValue("--mw-internal-theme-mode").trim()||"switchable";if("switchable"!==n)return console.log(`Theme mode fixed to: ${n}. Disabling toggle.`),o&&(o.className="light"===n?"fas fa-sun":"fas fa-moon"),"light"===n?t.classList.add("active"):t.classList.remove("active"),t.style.opacity="0.4",t.style.pointerEvents="none",t.style.cursor="default",t.setAttribute("aria-disabled","true"),localStorage.removeItem("mw-theme"),void("dark"===n&&c.classList.remove("mw-theme-light"));let s="light"===localStorage.getItem("mw-theme");const l=e=>{c.classList.toggle("mw-theme-light",e),t.classList.toggle("active",e),o&&(o.className=e?"fas fa-sun":"fas fa-moon")};l(s),t.addEventListener("click",()=>{s=!s,l(s),localStorage.setItem("mw-theme",s?"light":"dark"),setTimeout(e,400)})}(),e(),document.querySelectorAll(".mw-accordion-header").forEach(e=>{e.addEventListener("click",function(){this.classList.toggle("active");const e=this.nextElementSibling;e&&e.classList.toggle("active")})}),function(){const e=document.querySelector(".mw-menu-btn"),t=document.querySelector(".mw-navbar");if(!e||!t)return;function c(c){c.preventDefault(),c.stopPropagation(),e.classList.toggle("open"),t.classList.toggle("open")}e.addEventListener("click",c),e.addEventListener("touchstart",c,{passive:!1})}(),function(){const e=document.querySelectorAll(".mw-progress-fill");if(!e.length)return;const t=new IntersectionObserver((e,t)=>{e.forEach(e=>{if(!e.isIntersecting)return;const c=e.target,o=c.dataset.value||0;c.style.width=o+"%",t.unobserve(c)})},{root:null,threshold:.2});e.forEach(e=>t.observe(e))}(),document.querySelectorAll('a[href^="#"]').forEach(e=>{e.addEventListener("click",function(e){const t=this.getAttribute("href");if("#"===t)return;if(!document.querySelector(t))return;const c=document.querySelector(".mw-menu-btn"),o=document.querySelector(".mw-navbar");c&&o&&(c.classList.remove("open"),o.classList.remove("open"))})}),function(){const e=document.querySelectorAll("section[id]"),t=document.querySelectorAll(".mw-navbar-link");if(0===e.length||0===t.length)return;window.addEventListener("scroll",function(e,t){let c;return function(){const o=this,n=arguments;clearTimeout(c),c=setTimeout(()=>e.apply(o,n),t)}}(function(){let c="";e.forEach(e=>{const t=e.offsetTop-100,o=e.clientHeight;scrollY>=t&&scrollY<t+o&&(c=e.getAttribute("id"))}),t.forEach(e=>{e.classList.remove("active");const t=e.getAttribute("href");if(t){const o=t.indexOf("#");if(-1!==o){t.substring(o+1)===c&&e.classList.add("active")}}})},100))}(),document.querySelectorAll(".mw-tabs-nav-item").forEach(e=>{e.addEventListener("click",function(){const e=this.closest(".mw-tabs");if(!e)return;e.querySelectorAll(".mw-tabs-nav-item").forEach(e=>{e.classList.remove("active")}),this.classList.add("active");const t=this.getAttribute("data-tab");if(!t)return;e.querySelectorAll(".mw-tabs-panel").forEach(e=>{e.classList.remove("active")});const c=document.getElementById(t);c&&c.classList.add("active")})}),document.querySelectorAll(".mw-alert-close").forEach(e=>{e.addEventListener("click",function(){const e=this.closest(".mw-alert");e&&(e.classList.add("mw-alert-closing"),setTimeout(()=>{e.classList.add("mw-alert-closed")},300))})}),function(){const e=document.querySelector(".mw-localhost-indicator-activated"),t=document.querySelector(".mw-header");if(e){if("localhost"===window.location.hostname||"127.0.0.1"===window.location.hostname||window.location.hostname.includes("192.168.")){const e=document.createElement("div");e.className="mw-localhost-indicator-pulse",t.prepend(e)}}}(),document.querySelectorAll(".mw-slider-container").forEach(e=>{const t=e.querySelector(".mw-slider"),c=e.querySelector(".mw-slider-value");if(!t||!c)return;const o=()=>{const e=Number(t.value),o=Number(t.max)||100,n=Math.round(e/o*100);t.style.setProperty("--value",n+"%"),c.classList.contains("mw-slider-numeric")?c.setAttribute("data-value",e):c.setAttribute("data-value",n)};t.addEventListener("input",o),o()}),document.querySelectorAll(".mw-modal-close").forEach(e=>{e.addEventListener("click",function(){const e=this.closest(".mw-modal-overlay");e&&e.classList.remove("mw-modal-open")})}),function(){const e=document.getElementById("login-button");e&&e.addEventListener("click",function(){const e=this.querySelector("i");e.classList.contains("fa-lock")?(e.classList.remove("fa-lock"),e.classList.add("fa-lock-open")):(e.classList.remove("fa-lock-open"),e.classList.add("fa-lock"))})}(),document.querySelectorAll(".mw-image-slider").forEach(e=>{const t=e.querySelectorAll(".mw-image-slider-overlay-image"),c=e.querySelectorAll("button[data-index]");if(!t.length||!c.length)return;let o=0;function n(){t.forEach(e=>{const t=parseInt(e.dataset.index);e.classList.toggle("active",t===o)}),c.forEach(e=>{const t=parseInt(e.dataset.index);e.classList.toggle("active",t===o)})}function s(e){o=e,n()}c.forEach(e=>{e.addEventListener("click",()=>{s(parseInt(e.dataset.index))})}),n()}),document.querySelectorAll(".mw-item-list-checkbox, .mw-item-list-checkbox-scroll").forEach(e=>{e.querySelectorAll("li").forEach(e=>{const t=e.querySelector('input[type="checkbox"]'),c=e.querySelector(".mw-checkbox");t&&c&&(t.checked&&e.classList.add("mw-selected"),e.addEventListener("click",function(e){e.target!==t&&e.target.closest(".mw-checkbox")!==c&&toggleCheckbox(this)}),t.addEventListener("change",function(){const e=this.closest("li");this.checked?e.classList.add("mw-selected"):e.classList.remove("mw-selected"),e.dispatchEvent(new CustomEvent("checkboxToggle",{detail:{checked:this.checked,item:e}}))}),c.addEventListener("click",function(e){setTimeout(()=>{const e=this.closest("li");this.querySelector('input[type="checkbox"]').checked?e.classList.add("mw-selected"):e.classList.remove("mw-selected")},0)}))})}),document.addEventListener("checkboxToggle",function(e){console.log("Checkbox toggled:",e.detail.checked,e.detail.item)})}),window.toggleCheckbox=function(e){const t=e.querySelector('input[type="checkbox"]');if(!t)return;const c=t.checked;t.checked=!c,t.checked?e.classList.add("mw-selected"):e.classList.remove("mw-selected"),e.dispatchEvent(new CustomEvent("checkboxToggle",{detail:{checked:t.checked,item:e}}))}}();
1
+ !function(){"use strict";function e(){document.querySelectorAll(".color-swatch").forEach(e=>{const t=function(e){if(!e||"transparent"===e)return"#000000";const t=e=>Math.max(0,Math.min(255,Math.round(e))).toString(16).padStart(2,"0"),c=e.match(/color\(srgb\s+([\d.]+)\s+([\d.]+)\s+([\d.]+)(?:\s*\/\s*([\d.]+))?\)/);if(c){const e="#"+t(255*c[1])+t(255*c[2])+t(255*c[3]),o=void 0===c[4]?1:parseFloat(c[4]);return(o<1?`${e} / ${o}`:e).toUpperCase()}const o=e.match(/rgba?\((\d+),\s*(\d+),\s*(\d+)(?:,\s*([\d.]+))?\)/);if(!o)return e;const n="#"+t(o[1])+t(o[2])+t(o[3]),s=void 0===o[4]?1:parseFloat(o[4]);return(s<1?`${n} / ${s}`:n).toUpperCase()}(window.getComputedStyle(e).backgroundColor),c=e.parentElement.querySelector(".mw-text-muted");c&&(c.textContent=t)})}document.addEventListener("DOMContentLoaded",function(){document.querySelectorAll(".mw-gallery").forEach(e=>{const t=e.closest(".mw-gallery-container")||e.parentElement;t&&function(e,t){const c=t.querySelector(".mw-gallery-track");if(!c||!c.children.length)return;const o=c.children,n=e.querySelector(".mw-gallery-dots"),s=e.querySelector(".mw-gallery-desc"),l=t.querySelector(".mw-gallery-navi-prev"),r=t.querySelector(".mw-gallery-navi-next");let a=0;function i(e){const t=o.length;a=(e+t)%t,c.style.transform=`translateX(-${100*a}%)`,n&&n.querySelectorAll(".mw-gallery-dot").forEach((e,t)=>{e.classList.toggle("mw-active",t===a)}),s&&(s.textContent=o[a].dataset.desc||"")}if(n)for(let e=0;e<o.length;e++){const t=document.createElement("span");t.className="mw-gallery-dot"+(0===e?" mw-active":""),t.addEventListener("click",()=>i(e)),n.appendChild(t)}l&&l.addEventListener("click",()=>i(a-1)),r&&r.addEventListener("click",()=>i(a+1));let d=0;c.addEventListener("touchstart",e=>d=e.touches[0].clientX),c.addEventListener("touchend",e=>{const t=e.changedTouches[0].clientX-d;t>50&&i(a-1),t<-50&&i(a+1)}),i(0)}(t,e)}),function(){const t=document.querySelector(".mw-theme-toggle");if(!t)return;const c=document.body,o=t.querySelector(".mw-theme-toggle-slider i"),n=getComputedStyle(document.documentElement).getPropertyValue("--mw-internal-theme-mode").trim()||"switchable";if("switchable"!==n)return console.log(`Theme mode fixed to: ${n}. Disabling toggle.`),o&&(o.className="light"===n?"fas fa-sun":"fas fa-moon"),"light"===n?t.classList.add("active"):t.classList.remove("active"),t.style.opacity="0.4",t.style.pointerEvents="none",t.style.cursor="default",t.setAttribute("aria-disabled","true"),localStorage.removeItem("mw-theme"),void("dark"===n&&c.classList.remove("mw-theme-light"));let s="light"===localStorage.getItem("mw-theme");const l=e=>{c.classList.toggle("mw-theme-light",e),t.classList.toggle("active",e),o&&(o.className=e?"fas fa-sun":"fas fa-moon")};l(s),t.addEventListener("click",()=>{s=!s,l(s),localStorage.setItem("mw-theme",s?"light":"dark"),setTimeout(e,400)})}(),e(),document.querySelectorAll(".mw-accordion-header").forEach(e=>{e.addEventListener("click",function(){this.classList.toggle("active");const e=this.nextElementSibling;e&&e.classList.toggle("active")})}),function(){const e=document.querySelector(".mw-menu-btn"),t=document.querySelector(".mw-navbar");if(!e||!t)return;function c(){e.classList.remove("open"),t.classList.remove("open")}function o(c){c.preventDefault(),c.stopPropagation(),e.classList.toggle("open"),t.classList.toggle("open")}e.addEventListener("click",o),e.addEventListener("touchstart",o,{passive:!1}),document.addEventListener("click",function(o){t.classList.contains("open")&&(t.contains(o.target)||e.contains(o.target)||c())}),document.addEventListener("keydown",function(e){"Escape"===e.key&&c()})}(),function(){const e=document.querySelectorAll(".mw-progress-fill");if(!e.length)return;const t=new IntersectionObserver((e,t)=>{e.forEach(e=>{if(!e.isIntersecting)return;const c=e.target,o=c.dataset.value||0;c.style.width=o+"%",t.unobserve(c)})},{root:null,threshold:.2});e.forEach(e=>t.observe(e))}(),document.querySelectorAll('a[href^="#"]').forEach(e=>{e.addEventListener("click",function(e){const t=this.getAttribute("href");if("#"===t)return;if(!document.querySelector(t))return;const c=document.querySelector(".mw-menu-btn"),o=document.querySelector(".mw-navbar");c&&o&&(c.classList.remove("open"),o.classList.remove("open"))})}),function(){const e=document.querySelectorAll("section[id]"),t=document.querySelectorAll(".mw-navbar-link");if(0===e.length||0===t.length)return;window.addEventListener("scroll",function(e,t){let c;return function(){const o=this,n=arguments;clearTimeout(c),c=setTimeout(()=>e.apply(o,n),t)}}(function(){let c="";e.forEach(e=>{const t=e.offsetTop-100,o=e.clientHeight;scrollY>=t&&scrollY<t+o&&(c=e.getAttribute("id"))}),t.forEach(e=>{e.classList.remove("active");const t=e.getAttribute("href");if(t){const o=t.indexOf("#");if(-1!==o){t.substring(o+1)===c&&e.classList.add("active")}}})},100))}(),document.querySelectorAll(".mw-tabs-nav-item").forEach(e=>{e.addEventListener("click",function(){const e=this.closest(".mw-tabs");if(!e)return;e.querySelectorAll(".mw-tabs-nav-item").forEach(e=>{e.classList.remove("active")}),this.classList.add("active");const t=this.getAttribute("data-tab");if(!t)return;e.querySelectorAll(".mw-tabs-panel").forEach(e=>{e.classList.remove("active")});const c=document.getElementById(t);c&&c.classList.add("active")})}),document.querySelectorAll(".mw-alert-close").forEach(e=>{e.addEventListener("click",function(){const e=this.closest(".mw-alert");e&&(e.classList.add("mw-alert-closing"),setTimeout(()=>{e.classList.add("mw-alert-closed")},300))})}),function(){const e=document.querySelector(".mw-localhost-indicator-activated"),t=document.querySelector(".mw-header");if(e){if("localhost"===window.location.hostname||"127.0.0.1"===window.location.hostname||window.location.hostname.includes("192.168.")){const e=document.createElement("div");e.className="mw-localhost-indicator-pulse",t.prepend(e)}}}(),document.querySelectorAll(".mw-slider-container").forEach(e=>{const t=e.querySelector(".mw-slider"),c=e.querySelector(".mw-slider-value");if(!t||!c)return;const o=()=>{const e=Number(t.value),o=Number(t.max)||100,n=Math.round(e/o*100);t.style.setProperty("--value",n+"%"),c.classList.contains("mw-slider-numeric")?c.setAttribute("data-value",e):c.setAttribute("data-value",n)};t.addEventListener("input",o),o()}),document.querySelectorAll(".mw-modal-close").forEach(e=>{e.addEventListener("click",function(){const e=this.closest(".mw-modal-overlay");e&&e.classList.remove("mw-modal-open")})}),function(){const e=document.getElementById("login-button");e&&e.addEventListener("click",function(){const e=this.querySelector("i");e.classList.contains("fa-lock")?(e.classList.remove("fa-lock"),e.classList.add("fa-lock-open")):(e.classList.remove("fa-lock-open"),e.classList.add("fa-lock"))})}(),document.querySelectorAll(".mw-image-slider").forEach(e=>{const t=e.querySelectorAll(".mw-image-slider-overlay-image"),c=e.querySelectorAll("button[data-index]");if(!t.length||!c.length)return;let o=0;function n(){t.forEach(e=>{const t=parseInt(e.dataset.index);e.classList.toggle("active",t===o)}),c.forEach(e=>{const t=parseInt(e.dataset.index);e.classList.toggle("active",t===o)})}function s(e){o=e,n()}c.forEach(e=>{e.addEventListener("click",()=>{s(parseInt(e.dataset.index))})}),n()}),document.querySelectorAll(".mw-item-list-checkbox, .mw-item-list-checkbox-scroll").forEach(e=>{e.querySelectorAll("li").forEach(e=>{const t=e.querySelector('input[type="checkbox"]'),c=e.querySelector(".mw-checkbox");t&&c&&(t.checked&&e.classList.add("mw-selected"),e.addEventListener("click",function(e){e.target!==t&&e.target.closest(".mw-checkbox")!==c&&toggleCheckbox(this)}),t.addEventListener("change",function(){const e=this.closest("li");this.checked?e.classList.add("mw-selected"):e.classList.remove("mw-selected"),e.dispatchEvent(new CustomEvent("checkboxToggle",{detail:{checked:this.checked,item:e}}))}),c.addEventListener("click",function(e){setTimeout(()=>{const e=this.closest("li");this.querySelector('input[type="checkbox"]').checked?e.classList.add("mw-selected"):e.classList.remove("mw-selected")},0)}))})}),document.addEventListener("checkboxToggle",function(e){console.log("Checkbox toggled:",e.detail.checked,e.detail.item)})}),window.toggleCheckbox=function(e){const t=e.querySelector('input[type="checkbox"]');if(!t)return;const c=t.checked;t.checked=!c,t.checked?e.classList.add("mw-selected"):e.classList.remove("mw-selected"),e.dispatchEvent(new CustomEvent("checkboxToggle",{detail:{checked:t.checked,item:e}}))}}();
package/package.json CHANGED
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "name": "maverick-wave",
3
- "version": "3.3.1",
3
+ "version": "3.4.0",
4
4
  "config": {
5
- "version_short": "3.3"
5
+ "version_short": "3.4"
6
6
  },
7
7
  "description": "A lightweight, modern CSS framework for building responsive websites with elegance and speed.",
8
8
  "main": "src/js/main.js",
package/src/js/main.js CHANGED
@@ -119,64 +119,77 @@
119
119
 
120
120
  // ===== Gallery Component =====
121
121
  function initGalleries() {
122
- const track = document.querySelector('.mw-gallery-track');
122
+ document.querySelectorAll('.mw-gallery').forEach((gallery) => {
123
+ // Dots and caption sit next to .mw-gallery, not inside it, so the
124
+ // container is the scope — with the parent as a fallback, otherwise a
125
+ // markup without the wrapper would silently stay dead
126
+ const scope =
127
+ gallery.closest('.mw-gallery-container') || gallery.parentElement;
128
+ if (scope) initGallery(scope, gallery);
129
+ });
130
+ }
123
131
 
124
- if (track) {
125
- const dots = document.querySelector('.mw-gallery-dots');
126
- const slides = track.children;
127
- const descBox = document.querySelector('.mw-gallery-desc');
128
- const prevBtn = document.querySelector('.mw-gallery-navi-prev');
129
- const nextBtn = document.querySelector('.mw-gallery-navi-next');
130
- const sliderContainer = document.querySelector('.mw-gallery');
132
+ function initGallery(container, gallery) {
133
+ const track = gallery.querySelector('.mw-gallery-track');
134
+ if (!track || !track.children.length) return;
131
135
 
132
- let current = 0;
136
+ const slides = track.children;
133
137
 
134
- function updateSliderPosition() {
135
- const slideWidth = sliderContainer.offsetWidth;
136
- track.style.transform = `translateX(-${current * slideWidth}px)`;
137
- }
138
+ // Everything below the track is optional — a gallery may well ship
139
+ // without arrows, dots or a caption, and a missing one must not throw
140
+ const dotsBox = container.querySelector('.mw-gallery-dots');
141
+ const descBox = container.querySelector('.mw-gallery-desc');
142
+ const prevBtn = gallery.querySelector('.mw-gallery-navi-prev');
143
+ const nextBtn = gallery.querySelector('.mw-gallery-navi-next');
138
144
 
139
- function goToSlide(index) {
140
- const total = slides.length;
141
- current = (index + total) % total;
142
- updateSliderPosition();
145
+ let current = 0;
146
+
147
+ function goToSlide(index) {
148
+ const total = slides.length;
149
+ current = (index + total) % total;
143
150
 
144
- document.querySelectorAll('.mw-gallery-dot').forEach((dot, i) => {
151
+ // Percentages refer to the track's own width, which is one slide —
152
+ // so no measuring and nothing to recalculate on resize
153
+ track.style.transform = `translateX(-${current * 100}%)`;
154
+
155
+ if (dotsBox) {
156
+ dotsBox.querySelectorAll('.mw-gallery-dot').forEach((dot, i) => {
145
157
  dot.classList.toggle('mw-active', i === current);
146
158
  });
159
+ }
147
160
 
148
- descBox.textContent = slides[current].dataset.desc;
161
+ if (descBox) {
162
+ descBox.textContent = slides[current].dataset.desc || '';
149
163
  }
164
+ }
150
165
 
151
- function initDots() {
152
- for (let i = 0; i < slides.length; i++) {
153
- const dot = document.createElement('span');
154
- dot.className = 'mw-gallery-dot' + (i === 0 ? ' mw-active' : '');
155
- dot.addEventListener('click', () => goToSlide(i));
156
- dots.appendChild(dot);
157
- }
166
+ if (dotsBox) {
167
+ for (let i = 0; i < slides.length; i++) {
168
+ const dot = document.createElement('span');
169
+ dot.className = 'mw-gallery-dot' + (i === 0 ? ' mw-active' : '');
170
+ dot.addEventListener('click', () => goToSlide(i));
171
+ dotsBox.appendChild(dot);
158
172
  }
173
+ }
159
174
 
175
+ if (prevBtn)
160
176
  prevBtn.addEventListener('click', () => goToSlide(current - 1));
177
+ if (nextBtn)
161
178
  nextBtn.addEventListener('click', () => goToSlide(current + 1));
162
179
 
163
- window.addEventListener('resize', updateSliderPosition);
164
-
165
- // Optional: Swipe support
166
- let startX = 0;
167
- track.addEventListener(
168
- 'touchstart',
169
- (e) => (startX = e.touches[0].clientX)
170
- );
171
- track.addEventListener('touchend', (e) => {
172
- const delta = e.changedTouches[0].clientX - startX;
173
- if (delta > 50) goToSlide(current - 1);
174
- if (delta < -50) goToSlide(current + 1);
175
- });
180
+ // Optional: Swipe support
181
+ let startX = 0;
182
+ track.addEventListener(
183
+ 'touchstart',
184
+ (e) => (startX = e.touches[0].clientX)
185
+ );
186
+ track.addEventListener('touchend', (e) => {
187
+ const delta = e.changedTouches[0].clientX - startX;
188
+ if (delta > 50) goToSlide(current - 1);
189
+ if (delta < -50) goToSlide(current + 1);
190
+ });
176
191
 
177
- initDots();
178
- updateSliderPosition();
179
- }
192
+ goToSlide(0);
180
193
  }
181
194
 
182
195
  // ===== Theme Toggle =====
@@ -318,6 +331,11 @@
318
331
 
319
332
  if (!menuBtn || !navbar) return;
320
333
 
334
+ function closeMenu() {
335
+ menuBtn.classList.remove('open');
336
+ navbar.classList.remove('open');
337
+ }
338
+
321
339
  function toggleMenu(e) {
322
340
  e.preventDefault();
323
341
  e.stopPropagation();
@@ -328,6 +346,17 @@
328
346
  // Add multiple event listeners for better iOS compatibility
329
347
  menuBtn.addEventListener('click', toggleMenu);
330
348
  menuBtn.addEventListener('touchstart', toggleMenu, { passive: false });
349
+
350
+ // The scrim is a body pseudo-element, so its taps land on the document
351
+ document.addEventListener('click', function (e) {
352
+ if (!navbar.classList.contains('open')) return;
353
+ if (navbar.contains(e.target) || menuBtn.contains(e.target)) return;
354
+ closeMenu();
355
+ });
356
+
357
+ document.addEventListener('keydown', function (e) {
358
+ if (e.key === 'Escape') closeMenu();
359
+ });
331
360
  }
332
361
 
333
362
  // ===== Progress Bars =====
@@ -11,6 +11,24 @@
11
11
  <div class="mw-card mw-card-simple mw-p-2">Small padding</div>
12
12
  <div class="mw-card mw-card-simple mw-p-4 mw-mt-4">Medium padding</div>
13
13
  <div class="mw-card mw-card-simple mw-p-6 mw-mt-4">Large padding</div>
14
+
15
+ <h4 class="mw-mt-6 mw-mb-2">Auto Margins</h4>
16
+ <p class="mw-text-muted mw-text-sm mw-mb-3">
17
+ Every margin utility also takes <code>auto</code> &mdash;
18
+ <code>mw-mx-auto</code> centers a block, <code>mw-ml-auto</code> pushes a
19
+ flex item to the far side.
20
+ </p>
21
+
22
+ <div class="mw-card mw-card-simple mw-mb-4">
23
+ <div class="mw-card mw-card-simple mw-mx-auto" style="width: 60%">
24
+ mw-mx-auto
25
+ </div>
26
+ </div>
27
+
28
+ <div class="mw-card mw-card-simple mw-d-flex mw-items-center mw-gap-3">
29
+ <span>Left</span>
30
+ <span class="mw-tag mw-tag-primary mw-ml-auto">mw-ml-auto</span>
31
+ </div>
14
32
  </div>
15
33
 
16
34
  <div>
@@ -34,7 +52,7 @@
34
52
  </div>
35
53
  </div>
36
54
 
37
- <div class="mw-card mw-card-simple">
55
+ <div class="mw-card mw-card-simple mw-mb-4">
38
56
  <h4 class="mw-mb-2">Alignment</h4>
39
57
  <div
40
58
  class="mw-d-flex mw-justify-center mw-items-center mw-gap-3"
@@ -44,12 +62,26 @@
44
62
  <div class="mw-card mw-card-simple mw-p-2">Centered</div>
45
63
  </div>
46
64
  </div>
65
+
66
+ <div class="mw-card mw-card-simple">
67
+ <h4 class="mw-mb-2">Align Self</h4>
68
+ <p class="mw-text-muted mw-text-sm mw-mb-3">
69
+ <code>mw-items-*</code> sets the rule for the whole container,
70
+ <code>mw-self-*</code> lets a single child break out of it.
71
+ </p>
72
+ <div class="mw-d-flex mw-items-stretch mw-gap-3" style="height: 130px">
73
+ <div class="mw-card mw-card-simple mw-p-2">stretch</div>
74
+ <div class="mw-card mw-card-simple mw-p-2 mw-self-start">start</div>
75
+ <div class="mw-card mw-card-simple mw-p-2 mw-self-center">center</div>
76
+ <div class="mw-card mw-card-simple mw-p-2 mw-self-end">end</div>
77
+ </div>
78
+ </div>
47
79
  </div>
48
80
 
49
81
  <div>
50
82
  <h3 class="mw-mb-4">Gap Utilities</h3>
51
83
  <div class="mw-card mw-card-simple">
52
- <h4 class="mw-mb-3">Different Gap Sizes (from 0 - 10)</h4>
84
+ <h4 class="mw-mb-3">Different Gap Sizes (from 0 - 14)</h4>
53
85
 
54
86
  <div class="mw-mb-4">
55
87
  <p class="mw-mb-2">Small gap (gap-2)</p>
@@ -17,7 +17,7 @@ $secondary-color: #bb3110 !default;
17
17
  $success-color: #218838 !default;
18
18
  $warning-color: #d4a310 !default;
19
19
  // Darkened a little so light button text stays readable on the solid surface
20
- $danger-color: #c82333 !default;
20
+ $danger-color: #db182f !default;
21
21
  $info-color: #17a2b8 !default;
22
22
  $gray-color: #565656 !default;
23
23
  $dark-background: #0b111a !default;
@@ -67,7 +67,7 @@ $form-elements-background: #efefef !default;
67
67
  }
68
68
 
69
69
  // Uniform hover tone for every solid brand/status surface
70
- $hover-shift: 18%;
70
+ $hover-shift: 12%;
71
71
 
72
72
  // Base colors that don't change between themes.
73
73
  // Emitted as --mw-<key>.
@@ -14,17 +14,20 @@
14
14
  &-track {
15
15
  display: flex;
16
16
  transition: transform 0.3s ease;
17
- height: 100%;
17
+
18
+ @media (prefers-reduced-motion: reduce) {
19
+ transition: none;
20
+ }
18
21
  }
19
22
 
20
23
  &-slide {
21
24
  width: 100%;
22
25
  flex-shrink: 0;
23
- height: 100%;
26
+ aspect-ratio: var(--mw-gallery-ratio, 16 / 9);
24
27
 
25
28
  img {
26
29
  width: 100%;
27
- height: 580px;
30
+ height: 100%;
28
31
  object-fit: cover;
29
32
  display: block;
30
33
  }
@@ -34,32 +37,45 @@
34
37
  position: absolute;
35
38
  top: 50%;
36
39
  transform: translateY(-50%);
37
- color: rgba(23, 23, 23, 0.8); // fixed color
38
- background: rgba(240, 240, 240, 0.2); // fixed color
39
- border: none;
40
- font-size: font-size('5xl');
41
- cursor: pointer;
42
- z-index: z-index('menu');
43
- user-select: none;
44
- border-radius: radius('md');
40
+ width: 52px;
41
+ height: 92px;
45
42
  display: flex;
46
43
  align-items: center;
47
44
  justify-content: center;
48
- height: calc(580px * 0.9);
49
- width: 8%;
45
+ padding: spacing('0');
46
+ border: none;
47
+ border-radius: radius('md');
48
+ background: rgb(0 0 0 / 35%);
49
+ color: var(--mw-accent-text-color);
50
+ font-size: font-size('xl');
51
+ line-height: 1;
52
+ cursor: pointer;
53
+ z-index: z-index('lift');
54
+ user-select: none;
55
+ transition: var(--mw-transition);
56
+
57
+ &::before {
58
+ content: '';
59
+ position: absolute;
60
+ inset: -8px;
61
+ border-radius: inherit;
62
+ }
50
63
 
51
64
  &:hover {
52
- background: rgba(223, 223, 223, 0.4); // fixed color
65
+ background: rgb(0 0 0 / 80%);
66
+ }
67
+
68
+ &:focus-visible {
69
+ outline: 2px solid var(--mw-primary-color);
70
+ outline-offset: 2px;
53
71
  }
54
72
 
55
73
  &-prev {
56
- left: 3px;
57
- z-index: z-index('menu');
74
+ left: spacing('4');
58
75
  }
59
76
 
60
77
  &-next {
61
- right: 3px;
62
- z-index: z-index('menu');
78
+ right: spacing('4');
63
79
  }
64
80
  }
65
81
 
@@ -97,26 +113,8 @@
97
113
  }
98
114
  }
99
115
 
100
- @include media-down('lg') {
101
- .mw-gallery {
102
- &-slide img {
103
- height: 470px;
104
- }
105
- &-navi {
106
- font-size: font-size('3xl');
107
- height: calc(470px * 0.9);
108
- }
109
- }
110
- }
111
-
112
116
  @include media-down('md') {
113
117
  .mw-gallery {
114
- &-slide img {
115
- height: 380px;
116
- }
117
- &-navi {
118
- height: calc(380px * 0.9);
119
- }
120
118
  &-desc {
121
119
  font-size: font-size('sm');
122
120
  }
@@ -132,14 +130,12 @@
132
130
 
133
131
  @include media-down('sm') {
134
132
  .mw-gallery {
135
- &-slide img {
136
- height: 270px;
133
+ &-slide {
134
+ aspect-ratio: var(4 / 3);
137
135
  }
138
136
  &-navi {
139
- font-size: font-size('2xl');
140
- height: calc(270px * 0.9);
141
- border-radius: radius('sm');
142
- width: 11%;
137
+ width: 46px;
138
+ height: 88px;
143
139
  }
144
140
  &-desc {
145
141
  font-size: font-size('xs');
@@ -31,7 +31,7 @@
31
31
  box-shadow: 0 25px 50px var(--mw-shadow);
32
32
  max-width: 550px;
33
33
  width: 100%;
34
- max-height: 75vh;
34
+ max-height: 85dvh;
35
35
  display: flex;
36
36
  flex-direction: column;
37
37
  z-index: z-index('modal');
@@ -42,15 +42,15 @@
42
42
 
43
43
  &.mw-modal-sm {
44
44
  max-width: 370px;
45
- max-height: 70vh;
45
+ max-height: 80dvh;
46
46
  }
47
47
  &.mw-modal-lg {
48
48
  max-width: 680px;
49
- max-height: 80vh;
49
+ max-height: 90dvh;
50
50
  }
51
51
  &.mw-modal-xl {
52
52
  max-width: 900px;
53
- max-height: 85vh;
53
+ max-height: 92dvh;
54
54
  }
55
55
  }
56
56
 
@@ -15,10 +15,19 @@
15
15
  &-group {
16
16
  display: flex;
17
17
  flex-direction: column;
18
- padding: spacing('2');
19
- gap: spacing('1');
18
+ padding: spacing('4');
19
+ gap: spacing('2');
20
20
  border-radius: radius('sm');
21
21
  border: 2px solid var(--mw-border);
22
+
23
+ // Explicit hook for the heading, mirrors mw-modal-title
24
+ &-title {
25
+ font-size: font-size('md');
26
+ font-weight: font-weight('bold');
27
+ color: var(--mw-text-color);
28
+ line-height: 1.2;
29
+ margin: spacing('0') spacing('0') spacing('1') spacing('0');
30
+ }
22
31
  }
23
32
 
24
33
  label {