maverick-wave 5.3.0 → 5.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.
- package/.claude/skills/mw-maverick-wave/SKILL.md +13 -4
- package/.claude/skills/mw-maverick-wave/examples/static-landing-page.md +2 -2
- package/.claude/skills/mw-maverick-wave/references/components.md +4 -0
- package/.claude/skills/mw-maverick-wave/references/javascript.md +1 -0
- package/.claude/skills/mw-maverick-wave/references/layout.md +65 -0
- package/.claude/skills/mw-maverick-wave/references/theming.md +6 -0
- package/CHANGELOG.md +7 -0
- package/README.md +2 -2
- package/index.html +34 -3
- package/maverick-wave.min.css +4 -2
- package/maverick-wave.min.js +1 -1
- package/package.json +2 -2
- package/src/js/main.js +82 -11
- package/src/partials/home-container.html +2 -0
- package/src/partials/parallax-container.html +114 -0
- package/src/scss/abstracts/_variables.scss +4 -0
- package/src/scss/base/_base.scss +1 -0
- package/src/scss/layout/_header-reveal.scss +100 -0
- package/src/scss/layout/_index.scss +4 -0
- package/src/scss/layout/_main.scss +17 -2
- package/src/scss/layout/_parallax.scss +158 -0
package/maverick-wave.min.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
!function(){"use strict";function e(e,t){e&&(e.classList.toggle("mw-active",t),t||e.classList.remove("active"))}function t(e){return!!e&&(e.classList.contains("mw-active")||e.classList.contains("active"))}function n(){const e=Array.from(document.querySelectorAll(".color-swatch")),t=e.map(e=>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"),n=e.match(/color\(srgb\s+([\d.]+)\s+([\d.]+)\s+([\d.]+)(?:\s*\/\s*([\d.]+))?\)/);if(n){const e="#"+t(255*n[1])+t(255*n[2])+t(255*n[3]),a=void 0===n[4]?1:parseFloat(n[4]);return(a<1?`${e} / ${a}`:e).toUpperCase()}const a=e.match(/rgba?\((\d+),\s*(\d+),\s*(\d+)(?:,\s*([\d.]+))?\)/);if(!a)return e;const o="#"+t(a[1])+t(a[2])+t(a[3]),r=void 0===a[4]?1:parseFloat(a[4]);return(r<1?`${o} / ${r}`:o).toUpperCase()}(window.getComputedStyle(e).backgroundColor));e.forEach((e,n)=>{const a=e.parentElement.querySelector(".mw-text-muted");a&&(a.textContent=t[n])})}function a(e){const t=e.querySelector(".mw-tabs-nav-item.mw-active, .mw-tabs-nav-item.active");t?(e.style.setProperty("--mw-tabs-marker-x",t.offsetLeft+"px"),e.style.setProperty("--mw-tabs-marker-w",t.offsetWidth),e.style.setProperty("--mw-tabs-marker-y",t.offsetTop+"px"),e.style.setProperty("--mw-tabs-marker-h",t.offsetHeight),e.setAttribute("data-mw-tabs-marker","")):e.removeAttribute("data-mw-tabs-marker")}function o(e){const t=e.getAttribute("data-tab");return t?document.getElementById(t):null}function r(e){const n=t(e);e.setAttribute("aria-selected",String(n)),e.tabIndex=n?0:-1}function c(t,n){t.forEach(t=>{const a=t===n;e(t,a),e(o(t),a),r(t)});const c=n.closest(".mw-tabs-nav");c&&a(c)}function s(e){e&&("DIALOG"===e.tagName?e.showModal():e.classList.add("mw-modal-open"))}function l(e){const t=Array.from(e.querySelectorAll(".mw-kanban-column")),n=e.querySelector(".mw-kanban-composer"),a=e.querySelector(".mw-kanban-card-template"),o=e.dataset.kanbanPrefix||"MW",r=n.querySelector(".mw-kanban-composer-title"),c=n.querySelector(".mw-kanban-composer-text"),s=n.querySelector(".mw-kanban-composer-priority"),l=n.querySelector(".mw-kanban-composer-assignee");let i=null;function d(){t.forEach(function(e,n){const a=e.querySelectorAll(".mw-kanban-card"),o=e.querySelector(".mw-kanban-count");o&&(o.textContent=a.length),e.querySelectorAll("[data-kanban-move]").forEach(function(e){const a=n+parseInt(e.dataset.kanbanMove,10);e.disabled=a<0||a>=t.length})})}function u(e,t){const n=e.querySelector(t);return n?n.textContent.replace(/\s+/g," ").trim():""}function m(e,t){w(),i=t||null,r.value=t?u(t,".mw-kanban-card-title"):"",c.value=t?u(t,".mw-kanban-card-text"):"",s.value=t?function(e){const t=e.querySelector(".mw-card-ribbon");if(!t)return"";const n=Array.from(t.classList).find(function(e){return 0===e.indexOf("mw-card-addon-")});return n?n.replace("mw-card-addon-",""):""}(t):"",l.value=t?function(e){const t=e.querySelector(".mw-avatar-initials");return t?t.textContent.trim():""}(t):"",t?(t.classList.add("mw-kanban-editing"),t.before(n)):e.querySelector(".mw-kanban-column-body").prepend(n),n.classList.add("mw-active"),r.focus()}function w(){n.classList.remove("mw-active"),i&&i.classList.remove("mw-kanban-editing"),i=null}function f(){const t=r.value.trim();if(!t)return void r.focus();const u=i||a.content.firstElementChild.cloneNode(!0);if(u.querySelector(".mw-kanban-card-title").textContent=t,u.querySelector(".mw-kanban-card-text").textContent=c.value.trim(),function(e,t){const n=e.querySelector(".mw-card-ribbon");if(n&&n.remove(),!t||!t.value)return;const a=document.createElement("div");a.className="mw-card-ribbon mw-card-addon-"+t.value,a.textContent=t.textContent,e.prepend(a)}(u,s.selectedOptions[0]),function(e,t){const n=e.querySelector(".mw-kanban-card-actions"),a=n.querySelector(".mw-avatar");if(!t)return void(a&&a.remove());const o=a||document.createElement("div");o.className="mw-avatar mw-avatar-xs mw-avatar-initials",o.textContent=t,a||n.prepend(o)}(u,l.value),!i){const t=function(){const t=Array.from(e.querySelectorAll(".mw-kanban-card-id")).map(function(e){return parseInt(e.textContent.split("-").pop(),10)||0});return o+"-"+(Math.max(0,...t)+1)}();u.classList.add("mw-kanban-card-in"),u.querySelector(".mw-kanban-card-id").textContent=t,u.querySelectorAll("[aria-label]").forEach(function(e){e.setAttribute("aria-label",e.getAttribute("aria-label").replace(/[A-Z]+-\d+/,t))}),n.before(u)}w(),d()}const g=["mw-kanban-card-moved-forward","mw-kanban-card-moved-back"];e.addEventListener("click",function(e){const n=e.target.closest("[data-kanban-move]");if(n){if(function(e,n){const a=e.closest(".mw-kanban-column"),o=t[t.indexOf(a)+n];o&&(o.querySelector(".mw-kanban-column-body").appendChild(e),e.classList.remove.apply(e.classList,g),e.offsetWidth,e.classList.add(n>0?g[0]:g[1]),d())}(n.closest(".mw-kanban-card"),parseInt(n.dataset.kanbanMove,10)),n.disabled){const e=n.parentElement.querySelector("[data-kanban-move]:not(:disabled)");e&&e.focus()}return}const a=e.target.closest(".mw-kanban-edit");if(a){const e=a.closest(".mw-kanban-card");return void m(e.closest(".mw-kanban-column"),e)}const o=e.target.closest(".mw-kanban-delete");if(o){const e=o.closest(".mw-kanban-card");return e===i&&w(),e.remove(),void d()}const r=e.target.closest(".mw-kanban-add");r?m(r.closest(".mw-kanban-column"),null):e.target.closest(".mw-kanban-composer-cancel")&&w()}),n.addEventListener("submit",function(e){e.preventDefault(),f()}),n.addEventListener("keydown",function(e){"Escape"===e.key&&w()}),d()}function i(e){const t=e.querySelector(".mw-calendar-grid"),n=e.querySelector(".mw-calendar-title");if(!t)return;const a="week"===e.dataset.calendar,o=function(e){if(!e)return{};try{return JSON.parse(e)}catch(e){return{}}}(e.dataset.calendarMarkers),r=e.dataset.calendarLocale||document.documentElement.lang||void 0,c=new Date;c.setHours(0,0,0,0);let s=e.dataset.calendarDate?new Date(e.dataset.calendarDate+"T00:00:00"):new Date(c),l=e.dataset.calendarSelected||"";function i(e){const t=new Date(e);return t.setDate(t.getDate()-(t.getDay()+6)%7),t}function d(e){return e.getFullYear()+"-"+String(e.getMonth()+1).padStart(2,"0")+"-"+String(e.getDate()).padStart(2,"0")}function u(){if(!a)return s.toLocaleDateString(r,{month:"long",year:"numeric"});const e=i(s),t=new Date(e);t.setDate(t.getDate()+6);const n=e.toLocaleDateString(r,{day:"numeric",month:e.getMonth()===t.getMonth()?void 0:"short"}),o=t.toLocaleDateString(r,{day:"numeric",month:"short",year:"numeric"});return"Week "+function(e){const t=i(e);t.setDate(t.getDate()+3);const n=i(new Date(t.getFullYear(),0,4));return n.setDate(n.getDate()+3),1+Math.round((t-n)/6048e5)}(e)+" · "+n+" - "+o}function m(e){const t=e.getDay();return 0===t||6===t}function w(e,t){const n=d(e),s=document.createElement("button");s.type="button",s.className="mw-calendar-day",s.tabIndex=-1,s.dataset.calendarDay=n,s.setAttribute("aria-pressed",n===l?"true":"false"),s.setAttribute("aria-label",e.toLocaleDateString(r,{weekday:"long",day:"numeric",month:"long",year:"numeric"})),m(e)&&s.classList.add("mw-calendar-weekend"),a||e.getMonth()===t||s.classList.add("mw-calendar-adjacent"),n===d(c)&&(s.classList.add("mw-calendar-today"),s.setAttribute("aria-current","date")),n===l&&s.classList.add("mw-selected");const i=document.createElement("span");i.className="mw-calendar-date",i.textContent=e.getDate(),s.appendChild(i);const u=[].concat(o[n]||[]);if(u.length){const e=document.createElement("span");e.className="mw-calendar-dots",u.forEach(function(t){const n=document.createElement("span");n.className=t?"mw-calendar-dot mw-calendar-dot-"+t:"mw-calendar-dot",e.appendChild(n)}),s.appendChild(e)}return s}function f(){const e=s.getMonth(),o=a?7:42,c=i(a?s:new Date(s.getFullYear(),e,1));t.innerHTML="",function(){const e=i(new Date);for(let n=0;n<7;n++){const n=document.createElement("div");n.className="mw-calendar-weekday",m(e)&&n.classList.add("mw-calendar-weekend"),n.setAttribute("aria-hidden","true"),n.textContent=e.toLocaleDateString(r,{weekday:"short"}),t.appendChild(n),e.setDate(e.getDate()+1)}}();for(let n=0;n<o;n++)t.appendChild(w(c,e)),c.setDate(c.getDate()+1);n&&(n.textContent=u()),function(){const e=t.querySelector(".mw-selected")||t.querySelector(".mw-calendar-today")||t.querySelector(".mw-calendar-day:not(.mw-calendar-adjacent)")||t.querySelector(".mw-calendar-day");e&&(e.tabIndex=0)}()}e.addEventListener("click",function(n){const o=n.target.closest("[data-calendar-nav]");if(o)return r=parseInt(o.dataset.calendarNav,10),a?s.setDate(s.getDate()+7*r):s=new Date(s.getFullYear(),s.getMonth()+r,1),void f();var r;const c=n.target.closest(".mw-calendar-day");var i;c&&!c.disabled&&(i=c.dataset.calendarDay,l=i===l?"":i,t.querySelectorAll(".mw-calendar-day").forEach(function(e){const t=e.dataset.calendarDay===l;e.classList.toggle("mw-selected",t),e.setAttribute("aria-pressed",t?"true":"false")}),e.dispatchEvent(new CustomEvent("mw-calendar-select",{bubbles:!0,detail:{date:l}})))}),t.addEventListener("keydown",function(e){const n={ArrowLeft:-1,ArrowRight:1,ArrowUp:-7,ArrowDown:7}[e.key];if(!n)return;const a=e.target.closest(".mw-calendar-day");if(!a)return;e.preventDefault();const o=new Date(a.dataset.calendarDay+"T00:00:00");o.setDate(o.getDate()+n),function(e){const n=d(e);let a=t.querySelector('[data-calendar-day="'+n+'"]');a||(s=new Date(e),f(),a=t.querySelector('[data-calendar-day="'+n+'"]')),a&&(t.querySelectorAll(".mw-calendar-day").forEach(function(e){e.tabIndex=-1}),a.tabIndex=0,a.focus())}(o)}),f()}document.addEventListener("DOMContentLoaded",function(){document.querySelectorAll(".mw-gallery").forEach(e=>{const t=e.closest(".mw-gallery-container")||e.parentElement;t&&function(e,t){const n=t.querySelector(".mw-gallery-track");if(!n||!n.children.length)return;const a=n.children,o=e.querySelector(".mw-gallery-dots"),r=e.querySelector(".mw-gallery-desc"),c=t.querySelector(".mw-gallery-navi-prev"),s=t.querySelector(".mw-gallery-navi-next");let l=0;function i(e){const t=a.length;l=(e+t)%t,n.style.transform=`translateX(-${100*l}%)`,o&&o.querySelectorAll(".mw-gallery-dot").forEach((e,t)=>{e.classList.toggle("mw-active",t===l)}),r&&(r.textContent=a[l].dataset.desc||"")}if(o)for(let e=0;e<a.length;e++){const t=document.createElement("button");t.type="button",t.className="mw-gallery-dot"+(0===e?" mw-active":""),t.setAttribute("aria-label","Go to slide "+(e+1)),t.addEventListener("click",()=>i(e)),o.appendChild(t)}c&&c.addEventListener("click",()=>i(l-1)),s&&s.addEventListener("click",()=>i(l+1));let d=0;n.addEventListener("touchstart",e=>d=e.touches[0].clientX),n.addEventListener("touchend",e=>{const t=e.changedTouches[0].clientX-d;t>50&&i(l-1),t<-50&&i(l+1)}),i(0)}(t,e)}),function(){const t=document.querySelector(".mw-theme-toggle");if(!t)return;const a=document.body,o=document.documentElement,r=t.querySelector(".mw-theme-toggle-slider i"),c=getComputedStyle(document.documentElement).getPropertyValue("--mw-internal-theme-mode").trim()||"switchable";if("switchable"!==c)return console.log(`Theme mode fixed to: ${c}. Disabling toggle.`),r&&(r.className="light"===c?"fas fa-sun":"fas fa-moon"),e(t,"light"===c),t.style.opacity="0.4",t.style.pointerEvents="none",t.style.cursor="default",t.setAttribute("aria-disabled","true"),localStorage.removeItem("mw-theme"),void("dark"===c&&a.classList.remove("mw-theme-light"));let s="light"===localStorage.getItem("mw-theme");const l=n=>{o.classList.add("mw-theme-switching"),a.classList.toggle("mw-theme-light",n),o.offsetHeight,o.classList.remove("mw-theme-switching"),e(t,n),r&&(r.className=n?"fas fa-sun":"fas fa-moon")};l(s),t.addEventListener("click",()=>{s=!s,l(s),localStorage.setItem("mw-theme",s?"light":"dark"),n()})}(),n(),document.querySelectorAll(".mw-accordion-header").forEach(n=>{const a="BUTTON"===n.tagName;a&&n.setAttribute("aria-expanded",String(t(n))),n.addEventListener("click",function(){const n=!t(this);e(this,n),e(this.nextElementSibling,n),a&&this.setAttribute("aria-expanded",String(n))})}),function(){const e=document.querySelector(".mw-menu-btn"),t=document.querySelector(".mw-navbar");if(!e||!t)return;const n="BUTTON"===e.tagName;function a(a){e.classList.toggle("open",a),t.classList.toggle("open",a),n&&e.setAttribute("aria-expanded",String(a))}function o(e){e.preventDefault(),e.stopPropagation(),a(!t.classList.contains("open"))}e.addEventListener("click",o),e.addEventListener("touchstart",o,{passive:!1}),document.addEventListener("click",function(n){t.classList.contains("open")&&(t.contains(n.target)||e.contains(n.target)||a(!1))}),document.addEventListener("keydown",function(n){"Escape"===n.key&&t.classList.contains("open")&&(a(!1),e.focus())})}(),function(){const e=document.querySelectorAll(".mw-progress-fill");if(!e.length)return;const t=CSS.supports("animation-timeline","view()"),n=e=>e.dataset.value?e.dataset.value+"%":e.style.width,a=[];if(e.forEach(e=>{const o=n(e);o&&(e.style.setProperty("--mw-progress-value",o),t?e.classList.add("mw-progress-driven"):a.push(e))}),t)return;const o=new IntersectionObserver((e,t)=>{e.forEach(e=>{e.isIntersecting&&(e.target.style.width=n(e.target),t.unobserve(e.target))})},{root:null,threshold:.2});a.forEach(e=>o.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 n=document.querySelector(".mw-menu-btn"),a=document.querySelector(".mw-navbar");n&&a&&(n.classList.remove("open"),a.classList.remove("open"))})}),function(){const t=document.querySelectorAll("section[id]"),n=document.querySelectorAll(".mw-navbar-link");if(0===t.length||0===n.length)return;function a(){const e=parseFloat(getComputedStyle(document.documentElement).scrollPaddingTop);return(Number.isNaN(e)?0:e)+2}window.addEventListener("scroll",function(e,t){let n;return function(){const a=this,o=arguments;clearTimeout(n),n=setTimeout(()=>e.apply(a,o),t)}}(function(){let o="";const r=a();t.forEach(e=>{const t=e.offsetTop-r,n=e.clientHeight;scrollY>=t&&scrollY<t+n&&(o=e.getAttribute("id"))}),n.forEach(t=>{e(t,!1);const n=t.getAttribute("href");if(n){const a=n.indexOf("#");if(-1!==a){n.substring(a+1)===o&&e(t,!0)}}})},100))}(),document.querySelectorAll(".mw-tabs-nav").forEach(e=>{const t=Array.from(e.querySelectorAll(".mw-tabs-nav-item"));if(!t.length)return;const n=!!e.closest(".mw-tabs-vertical");e.setAttribute("role","tablist"),n&&e.setAttribute("aria-orientation","vertical"),t.forEach((e,a)=>{const s=o(e);e.setAttribute("role","tab"),e.id||(e.id=(s?s.id:"mw-tab-"+a)+"-tab"),s&&(e.setAttribute("aria-controls",s.id),s.setAttribute("role","tabpanel"),s.setAttribute("aria-labelledby",e.id)),r(e),e.addEventListener("click",()=>c(t,e)),e.addEventListener("keydown",e=>{const o=function(e,t,n,a){const o=t?"ArrowUp":"ArrowLeft",r=t?"ArrowDown":"ArrowRight";return e.key===o?(a-1+n)%n:e.key===r?(a+1)%n:"Home"===e.key?0:"End"===e.key?n-1:null}(e,n,t.length,a);null!==o&&(e.preventDefault(),c(t,t[o]),t[o].focus())})}),a(e);const s=new ResizeObserver(()=>a(e));s.observe(e),t.forEach(e=>s.observe(e))}),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"),n=e.querySelector(".mw-slider-value");if(!t||!n)return;const a=()=>{const e=Number(t.value),a=Number(t.max)||100,o=Math.round(e/a*100);t.style.setProperty("--value",o+"%"),n.classList.contains("mw-slider-numeric")?n.setAttribute("data-value",e):n.setAttribute("data-value",o)};t.addEventListener("input",a),a()}),document.addEventListener("click",e=>{const t=e.target.closest(".mw-modal-close");if(t){const e=t.closest("dialog.mw-modal");if(e)return void e.close();const n=t.closest(".mw-modal-overlay");return void(n&&n.classList.remove("mw-modal-open"))}const n=e.target.closest("[data-mw-modal]");var a;n?s(document.getElementById(n.dataset.mwModal)):e.target.matches("dialog.mw-modal[open]")&&(!("closedBy"in(a=e.target))||null===a.getAttribute("closedby"))&&e.target.close()}),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(t=>{const n=t.querySelectorAll(".mw-image-slider-overlay-image"),a=t.querySelectorAll("button[data-index]");if(!n.length||!a.length)return;let o=0;function r(){n.forEach(t=>{e(t,parseInt(t.dataset.index)===o)}),a.forEach(t=>{e(t,parseInt(t.dataset.index)===o)})}function c(e){o=e,r()}a.forEach(e=>{e.addEventListener("click",()=>{c(parseInt(e.dataset.index))})}),r()}),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"]'),n=e.querySelector(".mw-checkbox");t&&n&&(t.checked&&e.classList.add("mw-selected"),e.addEventListener("click",function(e){e.target!==t&&e.target.closest(".mw-checkbox")!==n&&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}}))}),n.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)}),document.querySelectorAll(".mw-kanban").forEach(l),document.querySelectorAll("[data-calendar]").forEach(i),function(){function e(e){document.querySelectorAll(".mw-dropdown[open]").forEach(t=>{t!==e&&t.removeAttribute("open")})}document.addEventListener("click",function(t){const n=t.target.closest(".mw-dropdown");e(n),n&&t.target.closest(".mw-dropdown-item")&&n.removeAttribute("open")}),document.addEventListener("keydown",function(e){if("Escape"!==e.key)return;const t=document.querySelector(".mw-dropdown[open]");if(!t)return;t.removeAttribute("open");const n=t.querySelector("summary");n&&n.focus()})}(),document.querySelectorAll(".mw-lang-switch").forEach(t=>{const n=t.querySelectorAll("[data-mw-lang]"),a=t.querySelector("summary"),o=t.querySelector("summary .mw-flag"),r=t.querySelector("summary .mw-lang-switch-code");n.forEach(c=>{c.addEventListener("click",function(){const s=c.dataset.mwLang,l=c.querySelector(".mw-lang-switch-name"),i=l?l.textContent.trim():s;n.forEach(t=>{e(t,t===c),t===c?t.setAttribute("aria-current","true"):t.removeAttribute("aria-current")}),r&&(r.textContent=s);const d=c.querySelector(".mw-flag");o&&d&&(o.className=d.className),a&&a.setAttribute("aria-label","Language: "+i),t.dispatchEvent(new CustomEvent("mw-language-change",{bubbles:!0,detail:{lang:s,name:i}}))})})})}),window.toggleCheckbox=function(e){const t=e.querySelector('input[type="checkbox"]');if(!t)return;const n=t.checked;t.checked=!n,t.checked?e.classList.add("mw-selected"):e.classList.remove("mw-selected"),e.dispatchEvent(new CustomEvent("checkboxToggle",{detail:{checked:t.checked,item:e}}))},window.mwOpenModal=e=>s(document.getElementById(e)),window.mwCloseModal=e=>{var t;(t=document.getElementById(e))&&("DIALOG"===t.tagName?t.close():t.classList.remove("mw-modal-open"))}}();
|
|
1
|
+
!function(){"use strict";function e(e,t){e&&(e.classList.toggle("mw-active",t),t||e.classList.remove("active"))}function t(e){return!!e&&(e.classList.contains("mw-active")||e.classList.contains("active"))}function n(){const e=Array.from(document.querySelectorAll(".color-swatch")),t=e.map(e=>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"),n=e.match(/color\(srgb\s+([\d.]+)\s+([\d.]+)\s+([\d.]+)(?:\s*\/\s*([\d.]+))?\)/);if(n){const e="#"+t(255*n[1])+t(255*n[2])+t(255*n[3]),a=void 0===n[4]?1:parseFloat(n[4]);return(a<1?`${e} / ${a}`:e).toUpperCase()}const a=e.match(/rgba?\((\d+),\s*(\d+),\s*(\d+)(?:,\s*([\d.]+))?\)/);if(!a)return e;const o="#"+t(a[1])+t(a[2])+t(a[3]),r=void 0===a[4]?1:parseFloat(a[4]);return(r<1?`${o} / ${r}`:o).toUpperCase()}(window.getComputedStyle(e).backgroundColor));e.forEach((e,n)=>{const a=e.parentElement.querySelector(".mw-text-muted");a&&(a.textContent=t[n])})}function a(){const e=parseFloat(getComputedStyle(document.documentElement).scrollPaddingTop);return Number.isNaN(e)?0:e}document.addEventListener("DOMContentLoaded",function(){document.querySelectorAll(".mw-gallery").forEach(e=>{const t=e.closest(".mw-gallery-container")||e.parentElement;t&&function(e,t){const n=t.querySelector(".mw-gallery-track");if(!n||!n.children.length)return;const a=n.children,o=e.querySelector(".mw-gallery-dots"),r=e.querySelector(".mw-gallery-desc"),c=t.querySelector(".mw-gallery-navi-prev"),s=t.querySelector(".mw-gallery-navi-next");let l=0;function i(e){const t=a.length;l=(e+t)%t,n.style.transform=`translateX(-${100*l}%)`,o&&o.querySelectorAll(".mw-gallery-dot").forEach((e,t)=>{e.classList.toggle("mw-active",t===l)}),r&&(r.textContent=a[l].dataset.desc||"")}if(o)for(let e=0;e<a.length;e++){const t=document.createElement("button");t.type="button",t.className="mw-gallery-dot"+(0===e?" mw-active":""),t.setAttribute("aria-label","Go to slide "+(e+1)),t.addEventListener("click",()=>i(e)),o.appendChild(t)}c&&c.addEventListener("click",()=>i(l-1)),s&&s.addEventListener("click",()=>i(l+1));let d=0;n.addEventListener("touchstart",e=>d=e.touches[0].clientX),n.addEventListener("touchend",e=>{const t=e.changedTouches[0].clientX-d;t>50&&i(l-1),t<-50&&i(l+1)}),i(0)}(t,e)}),function(){const t=document.querySelector(".mw-theme-toggle");if(!t)return;const a=document.body,o=document.documentElement,r=t.querySelector(".mw-theme-toggle-slider i"),c=getComputedStyle(document.documentElement).getPropertyValue("--mw-internal-theme-mode").trim()||"switchable";if("switchable"!==c)return console.log(`Theme mode fixed to: ${c}. Disabling toggle.`),r&&(r.className="light"===c?"fas fa-sun":"fas fa-moon"),e(t,"light"===c),t.style.opacity="0.4",t.style.pointerEvents="none",t.style.cursor="default",t.setAttribute("aria-disabled","true"),localStorage.removeItem("mw-theme"),void("dark"===c&&a.classList.remove("mw-theme-light"));let s="light"===localStorage.getItem("mw-theme");const l=n=>{o.classList.add("mw-theme-switching"),a.classList.toggle("mw-theme-light",n),o.offsetHeight,o.classList.remove("mw-theme-switching"),e(t,n),r&&(r.className=n?"fas fa-sun":"fas fa-moon")};l(s),t.addEventListener("click",()=>{s=!s,l(s),localStorage.setItem("mw-theme",s?"light":"dark"),n()})}(),n(),document.querySelectorAll(".mw-accordion-header").forEach(n=>{const a="BUTTON"===n.tagName;a&&n.setAttribute("aria-expanded",String(t(n))),n.addEventListener("click",function(){const n=!t(this);e(this,n),e(this.nextElementSibling,n),a&&this.setAttribute("aria-expanded",String(n))})}),function(){const e=document.querySelector(".mw-menu-btn"),t=document.querySelector(".mw-navbar");if(!e||!t)return;const n="BUTTON"===e.tagName;function a(a){e.classList.toggle("open",a),t.classList.toggle("open",a),n&&e.setAttribute("aria-expanded",String(a))}function o(e){e.preventDefault(),e.stopPropagation(),a(!t.classList.contains("open"))}e.addEventListener("click",o),e.addEventListener("touchstart",o,{passive:!1}),document.addEventListener("click",function(n){t.classList.contains("open")&&(t.contains(n.target)||e.contains(n.target)||a(!1))}),document.addEventListener("keydown",function(n){"Escape"===n.key&&t.classList.contains("open")&&(a(!1),e.focus())})}(),function(){const e=document.querySelectorAll(".mw-progress-fill");if(!e.length)return;const t=CSS.supports("animation-timeline","view()"),n=e=>e.dataset.value?e.dataset.value+"%":e.style.width,a=[];if(e.forEach(e=>{const o=n(e);o&&(e.style.setProperty("--mw-progress-value",o),t?e.classList.add("mw-progress-driven"):a.push(e))}),t)return;const o=new IntersectionObserver((e,t)=>{e.forEach(e=>{e.isIntersecting&&(e.target.style.width=n(e.target),t.unobserve(e.target))})},{root:null,threshold:.2});a.forEach(e=>o.observe(e))}(),function(){function e(e){const t=e.style.position,n="sticky"===getComputedStyle(e).position;n&&(e.style.position="static");const a=e.getBoundingClientRect().top+window.scrollY;return n&&(e.style.position=t),a}function t(e){const t=window.scrollY,n=e-t;if(!n)return;const a=Math.min(1400,420+.35*Math.abs(n)),r=performance.now(),c={};function s(e){if(o!==c)return;const l=Math.min(1,(e-r)/a),i=l<.5?4*l*l*l:1-Math.pow(-2*l+2,3)/2;window.scrollTo({top:t+n*i,behavior:"instant"}),l<1?requestAnimationFrame(s):o=null}o=c,requestAnimationFrame(s)}document.querySelectorAll('a[href^="#"]').forEach(n=>{n.addEventListener("click",function(n){const o=this.getAttribute("href");if("#"===o)return;const r=document.querySelector(o);if(!r)return;const c=document.querySelector(".mw-menu-btn"),s=document.querySelector(".mw-navbar");c&&s&&(c.classList.remove("open"),s.classList.remove("open")),n.preventDefault();const l=Math.max(0,e(r)-a());r.hasAttribute("tabindex")||r.setAttribute("tabindex","-1"),r.focus({preventScroll:!0}),window.matchMedia("(prefers-reduced-motion: reduce)").matches?window.scrollTo({top:l,behavior:"instant"}):t(l),history.replaceState(null,"",o)})})}(),function(){const t=document.querySelectorAll("section[id]"),n=document.querySelectorAll(".mw-navbar-link");if(0===t.length||0===n.length)return;window.addEventListener("scroll",function(e,t){let n;return function(){const a=this,o=arguments;clearTimeout(n),n=setTimeout(()=>e.apply(a,o),t)}}(function(){let o="";const r=a()+2;t.forEach(e=>{const t=e.offsetTop-r,n=e.clientHeight;scrollY>=t&&scrollY<t+n&&(o=e.getAttribute("id"))}),n.forEach(t=>{e(t,!1);const n=t.getAttribute("href");if(n){const a=n.indexOf("#");if(-1!==a){n.substring(a+1)===o&&e(t,!0)}}})},100))}(),document.querySelectorAll(".mw-tabs-nav").forEach(e=>{const t=Array.from(e.querySelectorAll(".mw-tabs-nav-item"));if(!t.length)return;const n=!!e.closest(".mw-tabs-vertical");e.setAttribute("role","tablist"),n&&e.setAttribute("aria-orientation","vertical"),t.forEach((e,a)=>{const o=c(e);e.setAttribute("role","tab"),e.id||(e.id=(o?o.id:"mw-tab-"+a)+"-tab"),o&&(e.setAttribute("aria-controls",o.id),o.setAttribute("role","tabpanel"),o.setAttribute("aria-labelledby",e.id)),s(e),e.addEventListener("click",()=>l(t,e)),e.addEventListener("keydown",e=>{const o=function(e,t,n,a){const o=t?"ArrowUp":"ArrowLeft",r=t?"ArrowDown":"ArrowRight";return e.key===o?(a-1+n)%n:e.key===r?(a+1)%n:"Home"===e.key?0:"End"===e.key?n-1:null}(e,n,t.length,a);null!==o&&(e.preventDefault(),l(t,t[o]),t[o].focus())})}),r(e);const a=new ResizeObserver(()=>r(e));a.observe(e),t.forEach(e=>a.observe(e))}),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"),n=e.querySelector(".mw-slider-value");if(!t||!n)return;const a=()=>{const e=Number(t.value),a=Number(t.max)||100,o=Math.round(e/a*100);t.style.setProperty("--value",o+"%"),n.classList.contains("mw-slider-numeric")?n.setAttribute("data-value",e):n.setAttribute("data-value",o)};t.addEventListener("input",a),a()}),document.addEventListener("click",e=>{const t=e.target.closest(".mw-modal-close");if(t){const e=t.closest("dialog.mw-modal");if(e)return void e.close();const n=t.closest(".mw-modal-overlay");return void(n&&n.classList.remove("mw-modal-open"))}const n=e.target.closest("[data-mw-modal]");var a;n?i(document.getElementById(n.dataset.mwModal)):e.target.matches("dialog.mw-modal[open]")&&(!("closedBy"in(a=e.target))||null===a.getAttribute("closedby"))&&e.target.close()}),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(t=>{const n=t.querySelectorAll(".mw-image-slider-overlay-image"),a=t.querySelectorAll("button[data-index]");if(!n.length||!a.length)return;let o=0;function r(){n.forEach(t=>{e(t,parseInt(t.dataset.index)===o)}),a.forEach(t=>{e(t,parseInt(t.dataset.index)===o)})}function c(e){o=e,r()}a.forEach(e=>{e.addEventListener("click",()=>{c(parseInt(e.dataset.index))})}),r()}),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"]'),n=e.querySelector(".mw-checkbox");t&&n&&(t.checked&&e.classList.add("mw-selected"),e.addEventListener("click",function(e){e.target!==t&&e.target.closest(".mw-checkbox")!==n&&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}}))}),n.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)}),document.querySelectorAll(".mw-kanban").forEach(d),document.querySelectorAll("[data-calendar]").forEach(u),function(){function e(e){document.querySelectorAll(".mw-dropdown[open]").forEach(t=>{t!==e&&t.removeAttribute("open")})}document.addEventListener("click",function(t){const n=t.target.closest(".mw-dropdown");e(n),n&&t.target.closest(".mw-dropdown-item")&&n.removeAttribute("open")}),document.addEventListener("keydown",function(e){if("Escape"!==e.key)return;const t=document.querySelector(".mw-dropdown[open]");if(!t)return;t.removeAttribute("open");const n=t.querySelector("summary");n&&n.focus()})}(),document.querySelectorAll(".mw-lang-switch").forEach(t=>{const n=t.querySelectorAll("[data-mw-lang]"),a=t.querySelector("summary"),o=t.querySelector("summary .mw-flag"),r=t.querySelector("summary .mw-lang-switch-code");n.forEach(c=>{c.addEventListener("click",function(){const s=c.dataset.mwLang,l=c.querySelector(".mw-lang-switch-name"),i=l?l.textContent.trim():s;n.forEach(t=>{e(t,t===c),t===c?t.setAttribute("aria-current","true"):t.removeAttribute("aria-current")}),r&&(r.textContent=s);const d=c.querySelector(".mw-flag");o&&d&&(o.className=d.className),a&&a.setAttribute("aria-label","Language: "+i),t.dispatchEvent(new CustomEvent("mw-language-change",{bubbles:!0,detail:{lang:s,name:i}}))})})})}),window.toggleCheckbox=function(e){const t=e.querySelector('input[type="checkbox"]');if(!t)return;const n=t.checked;t.checked=!n,t.checked?e.classList.add("mw-selected"):e.classList.remove("mw-selected"),e.dispatchEvent(new CustomEvent("checkboxToggle",{detail:{checked:t.checked,item:e}}))};let o=null;function r(e){const t=e.querySelector(".mw-tabs-nav-item.mw-active, .mw-tabs-nav-item.active");t?(e.style.setProperty("--mw-tabs-marker-x",t.offsetLeft+"px"),e.style.setProperty("--mw-tabs-marker-w",t.offsetWidth),e.style.setProperty("--mw-tabs-marker-y",t.offsetTop+"px"),e.style.setProperty("--mw-tabs-marker-h",t.offsetHeight),e.setAttribute("data-mw-tabs-marker","")):e.removeAttribute("data-mw-tabs-marker")}function c(e){const t=e.getAttribute("data-tab");return t?document.getElementById(t):null}function s(e){const n=t(e);e.setAttribute("aria-selected",String(n)),e.tabIndex=n?0:-1}function l(t,n){t.forEach(t=>{const a=t===n;e(t,a),e(c(t),a),s(t)});const a=n.closest(".mw-tabs-nav");a&&r(a)}function i(e){e&&("DIALOG"===e.tagName?e.showModal():e.classList.add("mw-modal-open"))}function d(e){const t=Array.from(e.querySelectorAll(".mw-kanban-column")),n=e.querySelector(".mw-kanban-composer"),a=e.querySelector(".mw-kanban-card-template"),o=e.dataset.kanbanPrefix||"MW",r=n.querySelector(".mw-kanban-composer-title"),c=n.querySelector(".mw-kanban-composer-text"),s=n.querySelector(".mw-kanban-composer-priority"),l=n.querySelector(".mw-kanban-composer-assignee");let i=null;function d(){t.forEach(function(e,n){const a=e.querySelectorAll(".mw-kanban-card"),o=e.querySelector(".mw-kanban-count");o&&(o.textContent=a.length),e.querySelectorAll("[data-kanban-move]").forEach(function(e){const a=n+parseInt(e.dataset.kanbanMove,10);e.disabled=a<0||a>=t.length})})}function u(e,t){const n=e.querySelector(t);return n?n.textContent.replace(/\s+/g," ").trim():""}function m(e,t){w(),i=t||null,r.value=t?u(t,".mw-kanban-card-title"):"",c.value=t?u(t,".mw-kanban-card-text"):"",s.value=t?function(e){const t=e.querySelector(".mw-card-ribbon");if(!t)return"";const n=Array.from(t.classList).find(function(e){return 0===e.indexOf("mw-card-addon-")});return n?n.replace("mw-card-addon-",""):""}(t):"",l.value=t?function(e){const t=e.querySelector(".mw-avatar-initials");return t?t.textContent.trim():""}(t):"",t?(t.classList.add("mw-kanban-editing"),t.before(n)):e.querySelector(".mw-kanban-column-body").prepend(n),n.classList.add("mw-active"),r.focus()}function w(){n.classList.remove("mw-active"),i&&i.classList.remove("mw-kanban-editing"),i=null}function f(){const t=r.value.trim();if(!t)return void r.focus();const u=i||a.content.firstElementChild.cloneNode(!0);if(u.querySelector(".mw-kanban-card-title").textContent=t,u.querySelector(".mw-kanban-card-text").textContent=c.value.trim(),function(e,t){const n=e.querySelector(".mw-card-ribbon");if(n&&n.remove(),!t||!t.value)return;const a=document.createElement("div");a.className="mw-card-ribbon mw-card-addon-"+t.value,a.textContent=t.textContent,e.prepend(a)}(u,s.selectedOptions[0]),function(e,t){const n=e.querySelector(".mw-kanban-card-actions"),a=n.querySelector(".mw-avatar");if(!t)return void(a&&a.remove());const o=a||document.createElement("div");o.className="mw-avatar mw-avatar-xs mw-avatar-initials",o.textContent=t,a||n.prepend(o)}(u,l.value),!i){const t=function(){const t=Array.from(e.querySelectorAll(".mw-kanban-card-id")).map(function(e){return parseInt(e.textContent.split("-").pop(),10)||0});return o+"-"+(Math.max(0,...t)+1)}();u.classList.add("mw-kanban-card-in"),u.querySelector(".mw-kanban-card-id").textContent=t,u.querySelectorAll("[aria-label]").forEach(function(e){e.setAttribute("aria-label",e.getAttribute("aria-label").replace(/[A-Z]+-\d+/,t))}),n.before(u)}w(),d()}const h=["mw-kanban-card-moved-forward","mw-kanban-card-moved-back"];e.addEventListener("click",function(e){const n=e.target.closest("[data-kanban-move]");if(n){if(function(e,n){const a=e.closest(".mw-kanban-column"),o=t[t.indexOf(a)+n];o&&(o.querySelector(".mw-kanban-column-body").appendChild(e),e.classList.remove.apply(e.classList,h),e.offsetWidth,e.classList.add(n>0?h[0]:h[1]),d())}(n.closest(".mw-kanban-card"),parseInt(n.dataset.kanbanMove,10)),n.disabled){const e=n.parentElement.querySelector("[data-kanban-move]:not(:disabled)");e&&e.focus()}return}const a=e.target.closest(".mw-kanban-edit");if(a){const e=a.closest(".mw-kanban-card");return void m(e.closest(".mw-kanban-column"),e)}const o=e.target.closest(".mw-kanban-delete");if(o){const e=o.closest(".mw-kanban-card");return e===i&&w(),e.remove(),void d()}const r=e.target.closest(".mw-kanban-add");r?m(r.closest(".mw-kanban-column"),null):e.target.closest(".mw-kanban-composer-cancel")&&w()}),n.addEventListener("submit",function(e){e.preventDefault(),f()}),n.addEventListener("keydown",function(e){"Escape"===e.key&&w()}),d()}function u(e){const t=e.querySelector(".mw-calendar-grid"),n=e.querySelector(".mw-calendar-title");if(!t)return;const a="week"===e.dataset.calendar,o=function(e){if(!e)return{};try{return JSON.parse(e)}catch(e){return{}}}(e.dataset.calendarMarkers),r=e.dataset.calendarLocale||document.documentElement.lang||void 0,c=new Date;c.setHours(0,0,0,0);let s=e.dataset.calendarDate?new Date(e.dataset.calendarDate+"T00:00:00"):new Date(c),l=e.dataset.calendarSelected||"";function i(e){const t=new Date(e);return t.setDate(t.getDate()-(t.getDay()+6)%7),t}function d(e){return e.getFullYear()+"-"+String(e.getMonth()+1).padStart(2,"0")+"-"+String(e.getDate()).padStart(2,"0")}function u(){if(!a)return s.toLocaleDateString(r,{month:"long",year:"numeric"});const e=i(s),t=new Date(e);t.setDate(t.getDate()+6);const n=e.toLocaleDateString(r,{day:"numeric",month:e.getMonth()===t.getMonth()?void 0:"short"}),o=t.toLocaleDateString(r,{day:"numeric",month:"short",year:"numeric"});return"Week "+function(e){const t=i(e);t.setDate(t.getDate()+3);const n=i(new Date(t.getFullYear(),0,4));return n.setDate(n.getDate()+3),1+Math.round((t-n)/6048e5)}(e)+" · "+n+" - "+o}function m(e){const t=e.getDay();return 0===t||6===t}function w(e,t){const n=d(e),s=document.createElement("button");s.type="button",s.className="mw-calendar-day",s.tabIndex=-1,s.dataset.calendarDay=n,s.setAttribute("aria-pressed",n===l?"true":"false"),s.setAttribute("aria-label",e.toLocaleDateString(r,{weekday:"long",day:"numeric",month:"long",year:"numeric"})),m(e)&&s.classList.add("mw-calendar-weekend"),a||e.getMonth()===t||s.classList.add("mw-calendar-adjacent"),n===d(c)&&(s.classList.add("mw-calendar-today"),s.setAttribute("aria-current","date")),n===l&&s.classList.add("mw-selected");const i=document.createElement("span");i.className="mw-calendar-date",i.textContent=e.getDate(),s.appendChild(i);const u=[].concat(o[n]||[]);if(u.length){const e=document.createElement("span");e.className="mw-calendar-dots",u.forEach(function(t){const n=document.createElement("span");n.className=t?"mw-calendar-dot mw-calendar-dot-"+t:"mw-calendar-dot",e.appendChild(n)}),s.appendChild(e)}return s}function f(){const e=s.getMonth(),o=a?7:42,c=i(a?s:new Date(s.getFullYear(),e,1));t.innerHTML="",function(){const e=i(new Date);for(let n=0;n<7;n++){const n=document.createElement("div");n.className="mw-calendar-weekday",m(e)&&n.classList.add("mw-calendar-weekend"),n.setAttribute("aria-hidden","true"),n.textContent=e.toLocaleDateString(r,{weekday:"short"}),t.appendChild(n),e.setDate(e.getDate()+1)}}();for(let n=0;n<o;n++)t.appendChild(w(c,e)),c.setDate(c.getDate()+1);n&&(n.textContent=u()),function(){const e=t.querySelector(".mw-selected")||t.querySelector(".mw-calendar-today")||t.querySelector(".mw-calendar-day:not(.mw-calendar-adjacent)")||t.querySelector(".mw-calendar-day");e&&(e.tabIndex=0)}()}e.addEventListener("click",function(n){const o=n.target.closest("[data-calendar-nav]");if(o)return r=parseInt(o.dataset.calendarNav,10),a?s.setDate(s.getDate()+7*r):s=new Date(s.getFullYear(),s.getMonth()+r,1),void f();var r;const c=n.target.closest(".mw-calendar-day");var i;c&&!c.disabled&&(i=c.dataset.calendarDay,l=i===l?"":i,t.querySelectorAll(".mw-calendar-day").forEach(function(e){const t=e.dataset.calendarDay===l;e.classList.toggle("mw-selected",t),e.setAttribute("aria-pressed",t?"true":"false")}),e.dispatchEvent(new CustomEvent("mw-calendar-select",{bubbles:!0,detail:{date:l}})))}),t.addEventListener("keydown",function(e){const n={ArrowLeft:-1,ArrowRight:1,ArrowUp:-7,ArrowDown:7}[e.key];if(!n)return;const a=e.target.closest(".mw-calendar-day");if(!a)return;e.preventDefault();const o=new Date(a.dataset.calendarDay+"T00:00:00");o.setDate(o.getDate()+n),function(e){const n=d(e);let a=t.querySelector('[data-calendar-day="'+n+'"]');a||(s=new Date(e),f(),a=t.querySelector('[data-calendar-day="'+n+'"]')),a&&(t.querySelectorAll(".mw-calendar-day").forEach(function(e){e.tabIndex=-1}),a.tabIndex=0,a.focus())}(o)}),f()}["wheel","touchstart"].forEach(e=>{window.addEventListener(e,()=>o=null,{passive:!0})}),window.mwOpenModal=e=>i(document.getElementById(e)),window.mwCloseModal=e=>{var t;(t=document.getElementById(e))&&("DIALOG"===t.tagName?t.close():t.classList.remove("mw-modal-open"))}}();
|
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "maverick-wave",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.4.0",
|
|
4
4
|
"config": {
|
|
5
|
-
"version_short": "5.
|
|
5
|
+
"version_short": "5.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
|
@@ -531,7 +531,65 @@
|
|
|
531
531
|
}
|
|
532
532
|
|
|
533
533
|
// ===== Smooth Scrolling =====
|
|
534
|
+
// Where an anchor jump lands: scroll-padding-top, read per run because the
|
|
535
|
+
// ribbon grows on small screens and can be dismissed
|
|
536
|
+
function anchorOffset() {
|
|
537
|
+
const padding = parseFloat(
|
|
538
|
+
getComputedStyle(document.documentElement).scrollPaddingTop
|
|
539
|
+
);
|
|
540
|
+
return Number.isNaN(padding) ? 0 : padding;
|
|
541
|
+
}
|
|
542
|
+
|
|
543
|
+
// Anything the user does with the wheel or a finger outranks a running glide
|
|
544
|
+
let glide = null;
|
|
545
|
+
['wheel', 'touchstart'].forEach((type) => {
|
|
546
|
+
window.addEventListener(type, () => (glide = null), { passive: true });
|
|
547
|
+
});
|
|
548
|
+
|
|
534
549
|
function initSmoothScrolling() {
|
|
550
|
+
// A sticky target reports where it is pinned, not where it sits in the flow,
|
|
551
|
+
// and pinned is the top of the screen - so the browser's own jump moved the
|
|
552
|
+
// page by the header offset and stopped there. offsetTop follows it to the
|
|
553
|
+
// pin as well, so the position is taken with the pinning switched off. No
|
|
554
|
+
// paint happens in between, the style is back before the frame ends.
|
|
555
|
+
function documentTop(el) {
|
|
556
|
+
const inline = el.style.position;
|
|
557
|
+
const pinned = getComputedStyle(el).position === 'sticky';
|
|
558
|
+
if (pinned) el.style.position = 'static';
|
|
559
|
+
const y = el.getBoundingClientRect().top + window.scrollY;
|
|
560
|
+
if (pinned) el.style.position = inline;
|
|
561
|
+
return y;
|
|
562
|
+
}
|
|
563
|
+
|
|
564
|
+
function glideTo(targetY) {
|
|
565
|
+
const startY = window.scrollY;
|
|
566
|
+
const distance = targetY - startY;
|
|
567
|
+
if (!distance) return;
|
|
568
|
+
|
|
569
|
+
// Scaled, or a jump to the next section takes as long as one across the
|
|
570
|
+
// whole page; capped, or that one crawls
|
|
571
|
+
const duration = Math.min(1400, 420 + Math.abs(distance) * 0.35);
|
|
572
|
+
const start = performance.now();
|
|
573
|
+
const token = {};
|
|
574
|
+
glide = token;
|
|
575
|
+
|
|
576
|
+
function step(now) {
|
|
577
|
+
if (glide !== token) return;
|
|
578
|
+
const t = Math.min(1, (now - start) / duration);
|
|
579
|
+
const eased = t < 0.5 ? 4 * t * t * t : 1 - Math.pow(-2 * t + 2, 3) / 2;
|
|
580
|
+
// 'instant', or the smooth scroll-behavior in the stylesheet animates
|
|
581
|
+
// every single step of this animation on top of it
|
|
582
|
+
window.scrollTo({
|
|
583
|
+
top: startY + distance * eased,
|
|
584
|
+
behavior: 'instant',
|
|
585
|
+
});
|
|
586
|
+
if (t < 1) requestAnimationFrame(step);
|
|
587
|
+
else glide = null;
|
|
588
|
+
}
|
|
589
|
+
|
|
590
|
+
requestAnimationFrame(step);
|
|
591
|
+
}
|
|
592
|
+
|
|
535
593
|
document.querySelectorAll('a[href^="#"]').forEach((anchor) => {
|
|
536
594
|
anchor.addEventListener('click', function (e) {
|
|
537
595
|
const targetId = this.getAttribute('href');
|
|
@@ -546,6 +604,28 @@
|
|
|
546
604
|
menuBtn.classList.remove('open');
|
|
547
605
|
nav.classList.remove('open');
|
|
548
606
|
}
|
|
607
|
+
|
|
608
|
+
e.preventDefault();
|
|
609
|
+
const target = Math.max(0, documentTop(targetElement) - anchorOffset());
|
|
610
|
+
|
|
611
|
+
// The browser moves focus on an anchor jump of its own; preventDefault
|
|
612
|
+
// takes that away, and a skip link that only scrolls leaves the next Tab
|
|
613
|
+
// back where it started. -1 keeps the target out of the tab order.
|
|
614
|
+
if (!targetElement.hasAttribute('tabindex')) {
|
|
615
|
+
targetElement.setAttribute('tabindex', '-1');
|
|
616
|
+
}
|
|
617
|
+
targetElement.focus({ preventScroll: true });
|
|
618
|
+
|
|
619
|
+
if (window.matchMedia('(prefers-reduced-motion: reduce)').matches) {
|
|
620
|
+
window.scrollTo({ top: target, behavior: 'instant' });
|
|
621
|
+
} else {
|
|
622
|
+
glideTo(target);
|
|
623
|
+
}
|
|
624
|
+
|
|
625
|
+
// replaceState and not the default hash change: the glide is the
|
|
626
|
+
// navigation, and a history entry per section link buries the page the
|
|
627
|
+
// user arrived from
|
|
628
|
+
history.replaceState(null, '', targetId);
|
|
549
629
|
});
|
|
550
630
|
});
|
|
551
631
|
}
|
|
@@ -557,21 +637,12 @@
|
|
|
557
637
|
|
|
558
638
|
if (sections.length === 0 || navLinks.length === 0) return;
|
|
559
639
|
|
|
560
|
-
// Measured against scroll-padding-top, the same value an anchor jump lands on,
|
|
561
|
-
// and read per run - the ribbon grows on small screens and can be dismissed
|
|
562
|
-
function scrollOffset() {
|
|
563
|
-
const padding = parseFloat(
|
|
564
|
-
getComputedStyle(document.documentElement).scrollPaddingTop
|
|
565
|
-
);
|
|
566
|
-
// +2 absorbs subpixel rounding between the jump and the scroll position.
|
|
567
|
-
return (Number.isNaN(padding) ? 0 : padding) + 2;
|
|
568
|
-
}
|
|
569
|
-
|
|
570
640
|
window.addEventListener(
|
|
571
641
|
'scroll',
|
|
572
642
|
debounce(function () {
|
|
573
643
|
let current = '';
|
|
574
|
-
|
|
644
|
+
// +2 absorbs subpixel rounding between the jump and the scroll position
|
|
645
|
+
const offset = anchorOffset() + 2;
|
|
575
646
|
|
|
576
647
|
sections.forEach((section) => {
|
|
577
648
|
const sectionTop = section.offsetTop - offset;
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
<h3 class="mw-section-subtitle">Parallax</h3>
|
|
2
|
+
<p class="mw-text-muted mw-text-measure mw-mb-6">
|
|
3
|
+
Two ways to play a picture against the scroll, both on the browser's scroll
|
|
4
|
+
timeline - no listener, and no
|
|
5
|
+
<code>background-attachment: fixed</code>, which iOS ignores. The image lives
|
|
6
|
+
in its own <code>mw-parallax-media</code> layer, as an
|
|
7
|
+
<code><img></code> or as a div with a background image. Where scroll
|
|
8
|
+
timelines are missing, or with <code>prefers-reduced-motion</code>, the
|
|
9
|
+
picture stands still and nothing else changes.
|
|
10
|
+
</p>
|
|
11
|
+
|
|
12
|
+
<h4 class="mw-text-medium mw-mb-2">
|
|
13
|
+
Drift - <code>mw-parallax</code>, the picture moves slower than the page
|
|
14
|
+
</h4>
|
|
15
|
+
<p class="mw-text-muted mw-text-measure mw-mb-6">
|
|
16
|
+
How far it travels is <code>--mw-parallax-depth</code> (<code>10vh</code> by
|
|
17
|
+
default); the layer overhangs the block by exactly that much, so no edge is
|
|
18
|
+
ever uncovered. <code>mw-parallax-dimmed</code> turns the picture down and the
|
|
19
|
+
text light.
|
|
20
|
+
</p>
|
|
21
|
+
|
|
22
|
+
<div class="mw-grid-1 mw-gap-6 mw-mb-6">
|
|
23
|
+
<div class="mw-parallax mw-parallax-dimmed">
|
|
24
|
+
<img
|
|
25
|
+
class="mw-parallax-media"
|
|
26
|
+
src="images/slider-field.svg"
|
|
27
|
+
alt=""
|
|
28
|
+
loading="lazy"
|
|
29
|
+
/>
|
|
30
|
+
<div class="mw-parallax-content mw-text-center">
|
|
31
|
+
<h3>Scroll past me</h3>
|
|
32
|
+
<p class="mw-mb-0">The field moves slower than the page does.</p>
|
|
33
|
+
</div>
|
|
34
|
+
</div>
|
|
35
|
+
|
|
36
|
+
<div class="mw-parallax" style="--mw-parallax-depth: 20vh">
|
|
37
|
+
<img
|
|
38
|
+
class="mw-parallax-media"
|
|
39
|
+
src="images/gallery-mountain.svg"
|
|
40
|
+
alt="Mountain range"
|
|
41
|
+
loading="lazy"
|
|
42
|
+
/>
|
|
43
|
+
</div>
|
|
44
|
+
</div>
|
|
45
|
+
|
|
46
|
+
<h4 class="mw-text-medium mw-mb-2">
|
|
47
|
+
Reveal - <code>mw-parallax-sticky</code>, the picture stays and the page rides
|
|
48
|
+
over it
|
|
49
|
+
</h4>
|
|
50
|
+
<p class="mw-text-muted mw-text-measure mw-mb-6">
|
|
51
|
+
The home section of this page does it: the block pins itself to the top of the
|
|
52
|
+
screen and everything after it slides up over the picture. It goes on whatever
|
|
53
|
+
element the page content is a <strong>sibling</strong> of - the section around
|
|
54
|
+
a hero, not the hero itself - because that is what sticky and the sibling
|
|
55
|
+
selector need. Everything after it gets the page background and a layer above,
|
|
56
|
+
or the pinned picture shows through. Pair it with
|
|
57
|
+
<code>mw-header-reveal</code> on the header and the page opens on the picture
|
|
58
|
+
alone: the bar stays away for the first 130px of scroll and has ridden in by
|
|
59
|
+
420px.
|
|
60
|
+
</p>
|
|
61
|
+
<p class="mw-text-muted mw-text-measure mw-mb-6">
|
|
62
|
+
Add <code>mw-parallax-rise</code> next to it and the picture lifts by
|
|
63
|
+
<code>12vh</code> while the text stays where it is - a pinned block does not
|
|
64
|
+
travel through the viewport, so that layer runs on the document's own scroll
|
|
65
|
+
instead. <code>--mw-parallax-depth</code> is the dial, here as everywhere.
|
|
66
|
+
</p>
|
|
67
|
+
|
|
68
|
+
<h4 class="mw-text-medium mw-mb-2">
|
|
69
|
+
Pattern - <code>mw-parallax-pattern</code>, a second layer that makes the
|
|
70
|
+
movement visible
|
|
71
|
+
</h4>
|
|
72
|
+
<p class="mw-text-muted mw-text-measure mw-mb-6">
|
|
73
|
+
The travel is vertical, so only an edge across it - a rule, a grid, a hatch -
|
|
74
|
+
ever shows it. A gradient has none and slides without looking like it moves.
|
|
75
|
+
Add a second <code>mw-parallax-media</code> carrying
|
|
76
|
+
<code>mw-parallax-pattern</code>: it travels a third of the distance, and it
|
|
77
|
+
is the difference between the two layers that reads as depth. In a hero the
|
|
78
|
+
pattern comes from <code>$mw-hero-pattern</code>, the way the picture comes
|
|
79
|
+
from <code>$mw-hero-image</code>; anywhere else set
|
|
80
|
+
<code>--mw-parallax-pattern-image</code> on it.
|
|
81
|
+
</p>
|
|
82
|
+
|
|
83
|
+
<div class="mw-parallax mw-parallax-dimmed mw-mb-6">
|
|
84
|
+
<div class="mw-parallax-media parallax-demo-ground"></div>
|
|
85
|
+
<div class="mw-parallax-media mw-parallax-pattern parallax-demo-lines"></div>
|
|
86
|
+
<div class="mw-parallax-content mw-text-center">
|
|
87
|
+
<h3>The grid drifts, the gradient holds</h3>
|
|
88
|
+
<p class="mw-mb-0">
|
|
89
|
+
Both layers move. Only the one with edges tells you so.
|
|
90
|
+
</p>
|
|
91
|
+
</div>
|
|
92
|
+
</div>
|
|
93
|
+
|
|
94
|
+
<div class="mw-code-block">
|
|
95
|
+
<div class="mw-code-block-header">
|
|
96
|
+
<span class="mw-code-block-filename">index.html</span>
|
|
97
|
+
<span class="mw-code-block-language">HTML</span>
|
|
98
|
+
</div>
|
|
99
|
+
<div class="mw-code-container">
|
|
100
|
+
<pre><code><header class="mw-header mw-header-reveal">...</header>
|
|
101
|
+
|
|
102
|
+
<main class="mw-main">
|
|
103
|
+
<section class="mw-section mw-parallax-sticky mw-parallax-rise">
|
|
104
|
+
<div class="mw-container mw-parallax">
|
|
105
|
+
<div class="mw-parallax-media"></div>
|
|
106
|
+
<div class="mw-parallax-media mw-parallax-pattern"></div>
|
|
107
|
+
<div class="mw-hero">...</div>
|
|
108
|
+
</div>
|
|
109
|
+
</section>
|
|
110
|
+
|
|
111
|
+
<section class="mw-section">...</section>
|
|
112
|
+
</main></code></pre>
|
|
113
|
+
</div>
|
|
114
|
+
</div>
|
|
@@ -4,6 +4,10 @@ $mw-theme-mode: 'switchable' !default; // 'dark', 'light', or 'switchable'
|
|
|
4
4
|
|
|
5
5
|
$mw-hero-image: url('https://images.unsplash.com/photo-1591638462868-19cfad9c49d1?q=80&w=1300&auto=format&fit=crop') !default;
|
|
6
6
|
|
|
7
|
+
// A second, flatter layer over the image - see mw-parallax-pattern. Fine lines
|
|
8
|
+
// or a grid, because a gradient has no edge across the travel to show it moving.
|
|
9
|
+
$mw-hero-pattern: none !default;
|
|
10
|
+
|
|
7
11
|
// Fixed to the light end rather than theme-bound: the photo does not change with
|
|
8
12
|
// the theme, so its ink must not either. Use --mw-light-text-color on a bright one.
|
|
9
13
|
$mw-hero-text-color: var(--mw-dark-text-color) !default;
|
package/src/scss/base/_base.scss
CHANGED
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
@layer mw.layout {
|
|
2
|
+
// For a page that opens on a full-bleed picture and wants nothing on top of
|
|
3
|
+
// it: the bar starts above the screen and rides in over the first stretch of
|
|
4
|
+
// scroll. Inside the @supports, so a browser without scroll timelines gets a
|
|
5
|
+
// normal header rather than none at all.
|
|
6
|
+
//
|
|
7
|
+
// Its own file, and not next to .mw-header: that one uses the `animation`
|
|
8
|
+
// shorthand, which a consumer bundler folds together with a timeline into a
|
|
9
|
+
// declaration no browser accepts.
|
|
10
|
+
@supports (animation-timeline: scroll()) {
|
|
11
|
+
@media (prefers-reduced-motion: no-preference) {
|
|
12
|
+
.mw-header-reveal {
|
|
13
|
+
animation-name: mw-header-reveal;
|
|
14
|
+
animation-timing-function: var(--mw-ease-out);
|
|
15
|
+
animation-fill-mode: both;
|
|
16
|
+
animation-timeline: scroll(root);
|
|
17
|
+
animation-range: 0 420px;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
// The ribbon is glued under the bar, so it has to leave and arrive with
|
|
21
|
+
// it - left behind it would hang alone at the top of an otherwise clean
|
|
22
|
+
// hero. No class of its own: a ribbon on a page with a revealing header
|
|
23
|
+
// has no other sensible behaviour.
|
|
24
|
+
body:has(.mw-header-reveal)
|
|
25
|
+
.mw-announcement:not(.mw-announcement-static) {
|
|
26
|
+
animation-name: mw-announcement-reveal;
|
|
27
|
+
animation-timing-function: var(--mw-ease-out);
|
|
28
|
+
animation-fill-mode: both;
|
|
29
|
+
animation-timeline: scroll(root);
|
|
30
|
+
animation-range: 0 420px;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// Both cover the height of the pair, or the shorter traveller arrives first
|
|
36
|
+
// and the two come in as two things instead of one block. Without a ribbon
|
|
37
|
+
// that height is just the bar's.
|
|
38
|
+
.mw-header-reveal {
|
|
39
|
+
--mw-header-reveal-offset: var(--mw-header-height);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
body:has(.mw-announcement:not(.mw-announcement-static)) .mw-header-reveal {
|
|
43
|
+
--mw-header-reveal-offset: calc(
|
|
44
|
+
var(--mw-header-height) + var(--mw-announcement-height)
|
|
45
|
+
);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// A keyboard reaches the chrome long before the first scroll does, and a focus
|
|
49
|
+
// ring on something that is off screen is WCAG 2.4.11 - so focus brings it
|
|
50
|
+
// back, either half of the pair pulling in the other. `!important` is the one
|
|
51
|
+
// author declaration that outranks a running animation; dropping
|
|
52
|
+
// `animation-name` instead leaves the element stuck on its last value, because
|
|
53
|
+
// a restarted scroll timeline only catches up on the next scroll.
|
|
54
|
+
body:has(.mw-header-reveal:focus-within, .mw-announcement:focus-within) {
|
|
55
|
+
.mw-header-reveal {
|
|
56
|
+
top: 0 !important;
|
|
57
|
+
opacity: 1 !important;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
.mw-announcement:not(.mw-announcement-static) {
|
|
61
|
+
transform: none !important;
|
|
62
|
+
opacity: 1 !important;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// `top` and not a transform: the off-canvas drawer inside the bar is
|
|
67
|
+
// position: fixed, and a transform on the header would make it the drawer's
|
|
68
|
+
// containing block - at every value, the resting one included.
|
|
69
|
+
// The wait sits in the keyframes and not in the range, because a range that
|
|
70
|
+
// starts past 0 leaves the bar in its resting state below that point - so the
|
|
71
|
+
// header would be visible for exactly the stretch it should stay away for.
|
|
72
|
+
@keyframes mw-header-reveal {
|
|
73
|
+
0%,
|
|
74
|
+
30% {
|
|
75
|
+
top: calc(-1 * var(--mw-header-reveal-offset));
|
|
76
|
+
opacity: 0;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
100% {
|
|
80
|
+
top: 0;
|
|
81
|
+
opacity: 1;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// The ribbon holds nothing fixed, so it can use the cheaper transform
|
|
86
|
+
@keyframes mw-announcement-reveal {
|
|
87
|
+
0%,
|
|
88
|
+
30% {
|
|
89
|
+
transform: translateY(
|
|
90
|
+
calc(-1 * (var(--mw-header-height) + var(--mw-announcement-height)))
|
|
91
|
+
);
|
|
92
|
+
opacity: 0;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
100% {
|
|
96
|
+
transform: translateY(0);
|
|
97
|
+
opacity: 1;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
}
|
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
@forward 'footer';
|
|
2
2
|
@forward 'grid';
|
|
3
3
|
@forward 'header';
|
|
4
|
+
@forward 'header-reveal';
|
|
4
5
|
@forward 'home';
|
|
5
6
|
@forward 'main';
|
|
6
7
|
@forward 'page-header';
|
|
7
8
|
@forward 'section';
|
|
9
|
+
|
|
10
|
+
// Last on purpose: mw-parallax-sticky has to beat the `position: relative`
|
|
11
|
+
@forward 'parallax';
|
|
@@ -41,12 +41,27 @@
|
|
|
41
41
|
transition: var(--mw-transition);
|
|
42
42
|
}
|
|
43
43
|
|
|
44
|
-
// ...so the content has to sit above it
|
|
45
|
-
|
|
44
|
+
// ...so the content has to sit above it - except the parallax layer,
|
|
45
|
+
// which is the one thing that belongs underneath
|
|
46
|
+
> *:not(.mw-parallax-media) {
|
|
46
47
|
position: relative;
|
|
47
48
|
z-index: z-index('card');
|
|
48
49
|
}
|
|
49
50
|
|
|
51
|
+
// Add `mw-parallax` here and a `.mw-parallax-media` child and the picture
|
|
52
|
+
// becomes its own layer, free to drift or to stay pinned. It reads the
|
|
53
|
+
// same token, so the image is still configured in one place - and a
|
|
54
|
+
// second media element carrying `mw-parallax-pattern` takes the other.
|
|
55
|
+
&:has(> .mw-parallax-media) {
|
|
56
|
+
background-image: none;
|
|
57
|
+
|
|
58
|
+
--mw-parallax-pattern-image: var(--mw-hero-pattern);
|
|
59
|
+
|
|
60
|
+
> .mw-parallax-media:not(.mw-parallax-pattern) {
|
|
61
|
+
background-image: var(--mw-hero-background);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
50
65
|
// The same shadow the scroll cue already carries: the light theme lifts
|
|
51
66
|
// the photo to brightness(1.1) and pale ink alone stops holding its edge
|
|
52
67
|
h1,
|