maverick-wave 5.3.0 → 5.5.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/angular-services.md +91 -0
- package/.claude/skills/mw-maverick-wave/examples/static-landing-page.md +5 -4
- package/.claude/skills/mw-maverick-wave/references/components.md +7 -0
- package/.claude/skills/mw-maverick-wave/references/javascript.md +20 -2
- package/.claude/skills/mw-maverick-wave/references/layout.md +81 -10
- package/.claude/skills/mw-maverick-wave/references/theming.md +10 -0
- package/CHANGELOG.md +18 -0
- package/CLAUDE.md +1 -1
- package/README.md +3 -4
- package/index.html +291 -3
- package/maverick-wave.min.css +6 -4
- package/maverick-wave.min.js +1 -1
- package/package.json +2 -2
- package/scripts/verify.js +4 -7
- package/src/js/main.js +237 -11
- package/src/partials/documentation-container.html +4 -0
- package/src/partials/footer-container.html +3 -0
- package/src/partials/history-container.html +67 -0
- package/src/partials/home-container.html +2 -0
- package/src/partials/palette-container.html +142 -0
- package/src/partials/parallax-container.html +114 -0
- package/src/scss/abstracts/_mixins.scss +6 -5
- package/src/scss/abstracts/_variables.scss +4 -0
- package/src/scss/base/_base.scss +1 -0
- package/src/scss/base/_reset.scss +4 -1
- package/src/scss/components/_accordions.scss +31 -7
- package/src/scss/components/_toasts.scss +1 -1
- package/src/scss/form-elements/_slider.scss +5 -23
- package/src/scss/layout/_header-reveal.scss +133 -0
- package/src/scss/layout/_index.scss +4 -0
- package/src/scss/layout/_main.scss +17 -2
- package/src/scss/layout/_parallax.scss +178 -0
- package/src/scss/utilities/_reveal.scss +22 -0
- package/.impeccable/config.local.json +0 -5
- package/.impeccable/hook.cache.json +0 -75
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(){if(CSS.supports("animation-timeline","view()"))return;if(window.matchMedia("(prefers-reduced-motion: reduce)").matches)return;const e=document.querySelectorAll(".mw-reveal, .mw-reveal-stagger > *");if(!e.length)return;const t=e=>{const t=e.parentElement;if(!t||!t.classList.contains("mw-reveal-stagger"))return 0;const n=getComputedStyle(t).gridTemplateColumns.split(" ").length;return[...t.children].indexOf(e)%n*90},n=new IntersectionObserver((e,n)=>{e.forEach(e=>{e.isIntersecting&&(n.unobserve(e.target),e.target.style.animationDelay=t(e.target)+"ms",e.target.classList.replace("mw-reveal-hidden","mw-reveal-run"))})},{threshold:.15});e.forEach(e=>{e.getBoundingClientRect().top<window.innerHeight||(e.classList.add("mw-reveal-hidden"),n.observe(e))})}(),function(){const e=document.querySelector(".mw-header-reveal");if(!e)return;if(CSS.supports("animation-timeline","scroll()"))return;if(window.matchMedia("(prefers-reduced-motion: reduce)").matches)return;const t=document.querySelector(".mw-announcement:not(.mw-announcement-static)"),n=270;let a=null;const o=()=>{const o=window.scrollY<n;o!==a&&(a=o,e.classList.toggle("mw-header-away",o),t&&t.classList.toggle("mw-announcement-away",o))};o(),requestAnimationFrame(()=>{e.classList.add("mw-header-driven"),t&&t.classList.add("mw-announcement-driven")}),window.addEventListener("scroll",o,{passive:!0})}(),function(){if(CSS.supports("animation-timeline","view()"))return;if(window.matchMedia("(prefers-reduced-motion: reduce)").matches)return;const e=document.querySelectorAll(".mw-parallax-media");if(!e.length)return;const t=[...e].map(e=>(e.classList.add("mw-parallax-driven"),{el:e,pinned:Boolean(e.closest(".mw-parallax-sticky"))})),n=e=>Math.min(1,Math.max(0,e)),a=(e,t)=>{if(e.pinned)return n(window.scrollY/t);const a=e.el.getBoundingClientRect();return n((t-a.top)/(t+a.height))};let o=!1;const r=()=>{o=!1;const e=window.innerHeight,n=t.map(t=>a(t,e));t.forEach((e,t)=>e.el.style.setProperty("--mw-parallax-progress",n[t]))},c=()=>{o||(o=!0,requestAnimationFrame(r))};r(),window.addEventListener("scroll",c,{passive:!0}),window.addEventListener("resize",c,{passive:!0})}(),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(2e3,600+.5*Math.abs(n)),r={};o=r;let c=null;function s(e){if(o!==r)return;null===c&&(c=e);const l=Math.min(1,(e-c)/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}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"))},window.mwRefreshColorSwatches=n}();
|
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "maverick-wave",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.5.0",
|
|
4
4
|
"config": {
|
|
5
|
-
"version_short": "5.
|
|
5
|
+
"version_short": "5.5"
|
|
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/scripts/verify.js
CHANGED
|
@@ -22,13 +22,10 @@ const CSS = path.join(ROOT, 'dist', 'maverick-wave.min.css');
|
|
|
22
22
|
const HTML = path.join(ROOT, 'dist', 'index.html');
|
|
23
23
|
const JS = path.join(ROOT, 'src', 'js', 'main.js');
|
|
24
24
|
|
|
25
|
-
// Everything that documents classes:
|
|
26
|
-
//
|
|
27
|
-
//
|
|
28
|
-
const DOCS =
|
|
29
|
-
path.join(ROOT, '.claude', 'commands', 'mw.md'),
|
|
30
|
-
...filesWithExt(path.join(ROOT, '.claude', 'skills'), '.md'),
|
|
31
|
-
];
|
|
25
|
+
// Everything that documents classes: every markdown file of the maverick-wave
|
|
26
|
+
// skill. Collected by walking the tree, so a new reference or example file is
|
|
27
|
+
// covered without touching this list.
|
|
28
|
+
const DOCS = filesWithExt(path.join(ROOT, '.claude', 'skills'), '.md');
|
|
32
29
|
|
|
33
30
|
// Tokens read by JavaScript or reserved for consumers, so "unused in CSS" is fine.
|
|
34
31
|
// warning/info have no solid button variant, but every status offers the same
|
package/src/js/main.js
CHANGED
|
@@ -25,6 +25,9 @@
|
|
|
25
25
|
initAccordions();
|
|
26
26
|
initMobileNav();
|
|
27
27
|
initProgressBars();
|
|
28
|
+
initReveals();
|
|
29
|
+
initHeaderReveal();
|
|
30
|
+
initParallax();
|
|
28
31
|
initSmoothScrolling();
|
|
29
32
|
initScrollSpy();
|
|
30
33
|
initTabs();
|
|
@@ -530,8 +533,213 @@
|
|
|
530
533
|
driven.forEach((bar) => obs.observe(bar));
|
|
531
534
|
}
|
|
532
535
|
|
|
536
|
+
// ===== Scroll Reveal =====
|
|
537
|
+
|
|
538
|
+
// The cards ride the browser's own view timeline where there is one
|
|
539
|
+
// (_reveal.scss). Firefox has none, so there an observer stands in: hide what
|
|
540
|
+
// is still below the fold, run the same keyframes when it arrives.
|
|
541
|
+
function initReveals() {
|
|
542
|
+
if (CSS.supports('animation-timeline', 'view()')) return;
|
|
543
|
+
if (window.matchMedia('(prefers-reduced-motion: reduce)').matches) return;
|
|
544
|
+
|
|
545
|
+
const targets = document.querySelectorAll(
|
|
546
|
+
'.mw-reveal, .mw-reveal-stagger > *'
|
|
547
|
+
);
|
|
548
|
+
if (!targets.length) return;
|
|
549
|
+
|
|
550
|
+
// The wave the grid draws in CSS, rebuilt from the column count the browser
|
|
551
|
+
// actually rendered - cheaper than restating every grid's stagger cycle a
|
|
552
|
+
// second time, and right on a phone where the grid collapses to one column.
|
|
553
|
+
const staggerDelay = (el) => {
|
|
554
|
+
const grid = el.parentElement;
|
|
555
|
+
if (!grid || !grid.classList.contains('mw-reveal-stagger')) return 0;
|
|
556
|
+
const columns =
|
|
557
|
+
getComputedStyle(grid).gridTemplateColumns.split(' ').length;
|
|
558
|
+
return ([...grid.children].indexOf(el) % columns) * 90;
|
|
559
|
+
};
|
|
560
|
+
|
|
561
|
+
const obs = new IntersectionObserver(
|
|
562
|
+
(entries, observer) => {
|
|
563
|
+
entries.forEach((entry) => {
|
|
564
|
+
if (!entry.isIntersecting) return;
|
|
565
|
+
observer.unobserve(entry.target);
|
|
566
|
+
entry.target.style.animationDelay = staggerDelay(entry.target) + 'ms';
|
|
567
|
+
entry.target.classList.replace('mw-reveal-hidden', 'mw-reveal-run');
|
|
568
|
+
});
|
|
569
|
+
},
|
|
570
|
+
{ threshold: 0.15 }
|
|
571
|
+
);
|
|
572
|
+
|
|
573
|
+
targets.forEach((el) => {
|
|
574
|
+
// Whatever is on screen already has passed its entry range in a browser
|
|
575
|
+
// with timelines too, so it stays put instead of fading in after load
|
|
576
|
+
if (el.getBoundingClientRect().top < window.innerHeight) return;
|
|
577
|
+
el.classList.add('mw-reveal-hidden');
|
|
578
|
+
obs.observe(el);
|
|
579
|
+
});
|
|
580
|
+
}
|
|
581
|
+
|
|
582
|
+
// Same story for the header that rides in over the first stretch of scroll
|
|
583
|
+
// (_header-reveal.scss). A toggle and not a scrub: mapping scroll to progress
|
|
584
|
+
// by hand would cost a rAF loop for a bar that is only ever in one of two
|
|
585
|
+
// places anyway.
|
|
586
|
+
function initHeaderReveal() {
|
|
587
|
+
const header = document.querySelector('.mw-header-reveal');
|
|
588
|
+
if (!header) return;
|
|
589
|
+
if (CSS.supports('animation-timeline', 'scroll()')) return;
|
|
590
|
+
if (window.matchMedia('(prefers-reduced-motion: reduce)').matches) return;
|
|
591
|
+
|
|
592
|
+
const ribbon = document.querySelector(
|
|
593
|
+
'.mw-announcement:not(.mw-announcement-static)'
|
|
594
|
+
);
|
|
595
|
+
|
|
596
|
+
// The CSS range holds the bar away for the first 30% of 420px and has it
|
|
597
|
+
// fully in at the end - halfway through what is left is the closest a
|
|
598
|
+
// single threshold gets to that.
|
|
599
|
+
const threshold = 270;
|
|
600
|
+
let away = null;
|
|
601
|
+
|
|
602
|
+
const update = () => {
|
|
603
|
+
const next = window.scrollY < threshold;
|
|
604
|
+
if (next === away) return;
|
|
605
|
+
away = next;
|
|
606
|
+
header.classList.toggle('mw-header-away', next);
|
|
607
|
+
if (ribbon) ribbon.classList.toggle('mw-announcement-away', next);
|
|
608
|
+
};
|
|
609
|
+
|
|
610
|
+
update();
|
|
611
|
+
|
|
612
|
+
// A frame later, or the bar starts at the top and slides away in front of
|
|
613
|
+
// the reader - the transition would be armed before it is in position.
|
|
614
|
+
requestAnimationFrame(() => {
|
|
615
|
+
header.classList.add('mw-header-driven');
|
|
616
|
+
if (ribbon) ribbon.classList.add('mw-announcement-driven');
|
|
617
|
+
});
|
|
618
|
+
|
|
619
|
+
window.addEventListener('scroll', update, { passive: true });
|
|
620
|
+
}
|
|
621
|
+
|
|
622
|
+
// And the parallax layers (_parallax.scss), the one of the four that needs a
|
|
623
|
+
// frame loop: the picture does not arrive somewhere, it is somewhere else at
|
|
624
|
+
// every scroll position. Only the progress is written, the travel stays in
|
|
625
|
+
// CSS where the depth variants can still reach it.
|
|
626
|
+
function initParallax() {
|
|
627
|
+
if (CSS.supports('animation-timeline', 'view()')) return;
|
|
628
|
+
if (window.matchMedia('(prefers-reduced-motion: reduce)').matches) return;
|
|
629
|
+
|
|
630
|
+
const media = document.querySelectorAll('.mw-parallax-media');
|
|
631
|
+
if (!media.length) return;
|
|
632
|
+
|
|
633
|
+
// A pinned block never travels through the viewport, so its own timeline
|
|
634
|
+
// would stand still - the CSS plays it against the document's first screen
|
|
635
|
+
// instead, and so does this.
|
|
636
|
+
const layers = [...media].map((el) => {
|
|
637
|
+
el.classList.add('mw-parallax-driven');
|
|
638
|
+
return { el, pinned: Boolean(el.closest('.mw-parallax-sticky')) };
|
|
639
|
+
});
|
|
640
|
+
|
|
641
|
+
const clamp = (value) => Math.min(1, Math.max(0, value));
|
|
642
|
+
|
|
643
|
+
// What view() hands the animation over its cover pass: 0 when the top edge
|
|
644
|
+
// touches the bottom of the screen, 1 when the bottom edge leaves at the
|
|
645
|
+
// top. Clamped, because the fill holds a layer at whichever end is off
|
|
646
|
+
// screen.
|
|
647
|
+
const progress = (layer, viewport) => {
|
|
648
|
+
if (layer.pinned) return clamp(window.scrollY / viewport);
|
|
649
|
+
const rect = layer.el.getBoundingClientRect();
|
|
650
|
+
return clamp((viewport - rect.top) / (viewport + rect.height));
|
|
651
|
+
};
|
|
652
|
+
|
|
653
|
+
let queued = false;
|
|
654
|
+
|
|
655
|
+
const update = () => {
|
|
656
|
+
queued = false;
|
|
657
|
+
const viewport = window.innerHeight;
|
|
658
|
+
// Every read before the first write, or each write makes the next read
|
|
659
|
+
// lay the page out again - a reflow per layer per frame.
|
|
660
|
+
const values = layers.map((layer) => progress(layer, viewport));
|
|
661
|
+
layers.forEach((layer, i) =>
|
|
662
|
+
layer.el.style.setProperty('--mw-parallax-progress', values[i])
|
|
663
|
+
);
|
|
664
|
+
};
|
|
665
|
+
|
|
666
|
+
const request = () => {
|
|
667
|
+
if (queued) return;
|
|
668
|
+
queued = true;
|
|
669
|
+
requestAnimationFrame(update);
|
|
670
|
+
};
|
|
671
|
+
|
|
672
|
+
update();
|
|
673
|
+
window.addEventListener('scroll', request, { passive: true });
|
|
674
|
+
window.addEventListener('resize', request, { passive: true });
|
|
675
|
+
}
|
|
676
|
+
|
|
533
677
|
// ===== Smooth Scrolling =====
|
|
678
|
+
// Where an anchor jump lands: scroll-padding-top, read per run because the
|
|
679
|
+
// ribbon grows on small screens and can be dismissed
|
|
680
|
+
function anchorOffset() {
|
|
681
|
+
const padding = parseFloat(
|
|
682
|
+
getComputedStyle(document.documentElement).scrollPaddingTop
|
|
683
|
+
);
|
|
684
|
+
return Number.isNaN(padding) ? 0 : padding;
|
|
685
|
+
}
|
|
686
|
+
|
|
687
|
+
// Anything the user does with the wheel or a finger outranks a running glide
|
|
688
|
+
let glide = null;
|
|
689
|
+
['wheel', 'touchstart'].forEach((type) => {
|
|
690
|
+
window.addEventListener(type, () => (glide = null), { passive: true });
|
|
691
|
+
});
|
|
692
|
+
|
|
534
693
|
function initSmoothScrolling() {
|
|
694
|
+
// A sticky target reports where it is pinned, not where it sits in the flow,
|
|
695
|
+
// and pinned is the top of the screen - so the browser's own jump moved the
|
|
696
|
+
// page by the header offset and stopped there. offsetTop follows it to the
|
|
697
|
+
// pin as well, so the position is taken with the pinning switched off. No
|
|
698
|
+
// paint happens in between, the style is back before the frame ends.
|
|
699
|
+
function documentTop(el) {
|
|
700
|
+
const inline = el.style.position;
|
|
701
|
+
const pinned = getComputedStyle(el).position === 'sticky';
|
|
702
|
+
if (pinned) el.style.position = 'static';
|
|
703
|
+
const y = el.getBoundingClientRect().top + window.scrollY;
|
|
704
|
+
if (pinned) el.style.position = inline;
|
|
705
|
+
return y;
|
|
706
|
+
}
|
|
707
|
+
|
|
708
|
+
function glideTo(targetY) {
|
|
709
|
+
const startY = window.scrollY;
|
|
710
|
+
const distance = targetY - startY;
|
|
711
|
+
if (!distance) return;
|
|
712
|
+
|
|
713
|
+
// Scaled, or a jump to the next section takes as long as one across the
|
|
714
|
+
// whole page; capped, or that one crawls
|
|
715
|
+
const duration = Math.min(2000, 600 + Math.abs(distance) * 0.5);
|
|
716
|
+
const token = {};
|
|
717
|
+
glide = token;
|
|
718
|
+
|
|
719
|
+
// The clock starts on the first rendered frame and not on the click. The
|
|
720
|
+
// page can sit still for a few hundred ms between the two - a clock
|
|
721
|
+
// started at the click hands that time to the easing, and the scroll
|
|
722
|
+
// opens by jumping most of the way at once.
|
|
723
|
+
let start = null;
|
|
724
|
+
|
|
725
|
+
function step(now) {
|
|
726
|
+
if (glide !== token) return;
|
|
727
|
+
if (start === null) start = now;
|
|
728
|
+
const t = Math.min(1, (now - start) / duration);
|
|
729
|
+
const eased = t < 0.5 ? 4 * t * t * t : 1 - Math.pow(-2 * t + 2, 3) / 2;
|
|
730
|
+
// 'instant', or the smooth scroll-behavior in the stylesheet animates
|
|
731
|
+
// every single step of this animation on top of it
|
|
732
|
+
window.scrollTo({
|
|
733
|
+
top: startY + distance * eased,
|
|
734
|
+
behavior: 'instant',
|
|
735
|
+
});
|
|
736
|
+
if (t < 1) requestAnimationFrame(step);
|
|
737
|
+
else glide = null;
|
|
738
|
+
}
|
|
739
|
+
|
|
740
|
+
requestAnimationFrame(step);
|
|
741
|
+
}
|
|
742
|
+
|
|
535
743
|
document.querySelectorAll('a[href^="#"]').forEach((anchor) => {
|
|
536
744
|
anchor.addEventListener('click', function (e) {
|
|
537
745
|
const targetId = this.getAttribute('href');
|
|
@@ -546,6 +754,30 @@
|
|
|
546
754
|
menuBtn.classList.remove('open');
|
|
547
755
|
nav.classList.remove('open');
|
|
548
756
|
}
|
|
757
|
+
|
|
758
|
+
e.preventDefault();
|
|
759
|
+
const target = Math.max(0, documentTop(targetElement) - anchorOffset());
|
|
760
|
+
|
|
761
|
+
// The browser moves focus on an anchor jump of its own; preventDefault
|
|
762
|
+
// takes that away, and a skip link that only scrolls leaves the next Tab
|
|
763
|
+
// back where it started. -1 keeps the target out of the tab order.
|
|
764
|
+
if (!targetElement.hasAttribute('tabindex')) {
|
|
765
|
+
targetElement.setAttribute('tabindex', '-1');
|
|
766
|
+
}
|
|
767
|
+
targetElement.focus({ preventScroll: true });
|
|
768
|
+
|
|
769
|
+
// Not `behavior: 'smooth'`: the browser's own curve takes no duration,
|
|
770
|
+
// and the one it picks cannot be slowed down.
|
|
771
|
+
if (window.matchMedia('(prefers-reduced-motion: reduce)').matches) {
|
|
772
|
+
window.scrollTo({ top: target, behavior: 'instant' });
|
|
773
|
+
} else {
|
|
774
|
+
glideTo(target);
|
|
775
|
+
}
|
|
776
|
+
|
|
777
|
+
// replaceState and not the default hash change: the glide is the
|
|
778
|
+
// navigation, and a history entry per section link buries the page the
|
|
779
|
+
// user arrived from
|
|
780
|
+
history.replaceState(null, '', targetId);
|
|
549
781
|
});
|
|
550
782
|
});
|
|
551
783
|
}
|
|
@@ -557,21 +789,12 @@
|
|
|
557
789
|
|
|
558
790
|
if (sections.length === 0 || navLinks.length === 0) return;
|
|
559
791
|
|
|
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
792
|
window.addEventListener(
|
|
571
793
|
'scroll',
|
|
572
794
|
debounce(function () {
|
|
573
795
|
let current = '';
|
|
574
|
-
|
|
796
|
+
// +2 absorbs subpixel rounding between the jump and the scroll position
|
|
797
|
+
const offset = anchorOffset() + 2;
|
|
575
798
|
|
|
576
799
|
sections.forEach((section) => {
|
|
577
800
|
const sectionTop = section.offsetTop - offset;
|
|
@@ -846,6 +1069,9 @@
|
|
|
846
1069
|
|
|
847
1070
|
window.mwOpenModal = (id) => openModal(document.getElementById(id));
|
|
848
1071
|
window.mwCloseModal = (id) => closeModal(document.getElementById(id));
|
|
1072
|
+
// The swatch hex labels read the computed colour, so anything that changes a
|
|
1073
|
+
// root colour at runtime has to ask for them to be read again
|
|
1074
|
+
window.mwRefreshColorSwatches = updateColorSwatchHexValues;
|
|
849
1075
|
|
|
850
1076
|
// ===== Login Button =====
|
|
851
1077
|
function initHeaderLoginButton() {
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
<div class="mw-timeline-simple mw-my-6">
|
|
2
|
+
<div class="mw-timeline-simple-step mw-active">
|
|
3
|
+
<div class="mw-timeline-simple-date">2026-09-11</div>
|
|
4
|
+
<div class="mw-timeline-simple-content">
|
|
5
|
+
<div class="mw-card mw-card-simple">
|
|
6
|
+
<h3 class="mw-card-title">v5.0.0</h3>
|
|
7
|
+
<p>
|
|
8
|
+
Everything the framework ships moved into a cascade layer, so vendor
|
|
9
|
+
CSS loaded next to it stops winning selector fights by accident. The
|
|
10
|
+
source got a full pass while it was open anyway.
|
|
11
|
+
</p>
|
|
12
|
+
</div>
|
|
13
|
+
</div>
|
|
14
|
+
</div>
|
|
15
|
+
|
|
16
|
+
<div class="mw-timeline-simple-step">
|
|
17
|
+
<div class="mw-timeline-simple-date">2026-08-19</div>
|
|
18
|
+
<div class="mw-timeline-simple-content">
|
|
19
|
+
<div class="mw-card mw-card-simple">
|
|
20
|
+
<h3 class="mw-card-title">v4.0.0</h3>
|
|
21
|
+
<p>
|
|
22
|
+
The calendar arrived in three shapes - month, week and compact - and
|
|
23
|
+
pagination was reframed to sit next to it without looking borrowed.
|
|
24
|
+
</p>
|
|
25
|
+
</div>
|
|
26
|
+
</div>
|
|
27
|
+
</div>
|
|
28
|
+
|
|
29
|
+
<div class="mw-timeline-simple-step">
|
|
30
|
+
<div class="mw-timeline-simple-date">2026-04-04</div>
|
|
31
|
+
<div class="mw-timeline-simple-content">
|
|
32
|
+
<div class="mw-card mw-card-simple">
|
|
33
|
+
<h3 class="mw-card-title">v3.0.0</h3>
|
|
34
|
+
<p>
|
|
35
|
+
Claude Code joined the workflow: more components, more form elements,
|
|
36
|
+
and a pile of small fixes it spotted along the way.
|
|
37
|
+
</p>
|
|
38
|
+
</div>
|
|
39
|
+
</div>
|
|
40
|
+
</div>
|
|
41
|
+
|
|
42
|
+
<div class="mw-timeline-simple-step">
|
|
43
|
+
<div class="mw-timeline-simple-date">2025-06-09</div>
|
|
44
|
+
<div class="mw-timeline-simple-content">
|
|
45
|
+
<div class="mw-card mw-card-simple">
|
|
46
|
+
<h3 class="mw-card-title">v2.0.0</h3>
|
|
47
|
+
<p>
|
|
48
|
+
The grid was rebuilt from scratch, with modals, pagination, item lists
|
|
49
|
+
and the first real form layer put on top of it.
|
|
50
|
+
</p>
|
|
51
|
+
</div>
|
|
52
|
+
</div>
|
|
53
|
+
</div>
|
|
54
|
+
|
|
55
|
+
<div class="mw-timeline-simple-step">
|
|
56
|
+
<div class="mw-timeline-simple-date">2025-04-30</div>
|
|
57
|
+
<div class="mw-timeline-simple-content">
|
|
58
|
+
<div class="mw-card mw-card-simple">
|
|
59
|
+
<h3 class="mw-card-title">v1.3.0</h3>
|
|
60
|
+
<p>
|
|
61
|
+
Let's say initial release - grid, header and a first handful of
|
|
62
|
+
components, published as they were.
|
|
63
|
+
</p>
|
|
64
|
+
</div>
|
|
65
|
+
</div>
|
|
66
|
+
</div>
|
|
67
|
+
</div>
|