maverick-wave 5.12.0 → 5.13.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 +63 -8
- package/.claude/skills/mw-maverick-wave/examples/static-landing-page.md +6 -3
- package/.claude/skills/mw-maverick-wave/references/components.md +41 -27
- package/.claude/skills/mw-maverick-wave/references/javascript.md +27 -26
- package/.claude/skills/mw-maverick-wave/references/layout.md +12 -6
- package/.claude/skills/mw-maverick-wave/references/theming.md +59 -4
- package/CHANGELOG.md +12 -0
- package/README.md +45 -5
- package/index.html +5 -4
- package/maverick-wave.min.css +4 -4
- package/maverick-wave.min.js +1 -1
- package/package.json +2 -2
- package/src/js/main.js +67 -20
- package/src/partials/buttons-container.html +2 -1
- package/src/partials/get-started-container.html +52 -3
- package/src/partials/parallax-container.html +8 -5
- package/src/partials/tabs-container.html +1 -1
- package/src/partials/typography-container.html +3 -0
- package/src/scss/abstracts/_functions.scss +50 -0
- package/src/scss/abstracts/_mixins.scss +33 -0
- package/src/scss/base/_typography.scss +4 -21
- package/src/scss/components/_buttons.scss +1 -1
- package/src/scss/components/_content-slider.scss +16 -8
- package/src/scss/components/_dropdown.scss +1 -1
- package/src/scss/components/_gallery.scss +13 -2
- package/src/scss/components/_lang-switch.scss +1 -1
- package/src/scss/components/_segmented.scss +4 -0
- package/src/scss/layout/_header.scss +3 -2
- package/src/scss/layout/_parallax.scss +15 -1
- package/src/scss/layout/_section.scss +2 -10
- package/src/scss/utilities/_touch-targets.scss +22 -16
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(){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 a.classList.remove("mw-theme-light","mw-theme-dark");const s=window.matchMedia("(prefers-color-scheme: light)"),l=window.CSS&&CSS.supports("color","light-dark(#000, #fff)"),i=()=>l&&s.matches,d=localStorage.getItem("mw-theme");let u=d?"light"===d:i();const m=n=>{o.classList.add("mw-theme-switching"),a.classList.toggle("mw-theme-light",n),a.classList.toggle("mw-theme-dark",!n),o.offsetHeight,o.classList.remove("mw-theme-switching"),e(t,n),r&&(r.className=n?"fas fa-sun":"fas fa-moon")};m(u),s.addEventListener("change",()=>{localStorage.getItem("mw-theme")||(u=i(),m(u),n())}),t.addEventListener("click",()=>{u=!u,m(u),localStorage.setItem("mw-theme",u?"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}();
|
|
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,u=0,m=!1;n.addEventListener("touchstart",e=>{m=1===e.touches.length,m&&(d=e.touches[0].clientX,u=e.touches[0].clientY)},{passive:!0}),n.addEventListener("touchcancel",()=>m=!1),n.addEventListener("touchend",e=>{if(!m)return;m=!1;const t=e.changedTouches[0].clientX-d,n=e.changedTouches[0].clientY-u;Math.abs(t)<50||Math.abs(t)<=Math.abs(n)||i(l+(t<0?1:-1))},{passive:!0}),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 a.classList.remove("mw-theme-light","mw-theme-dark");const s=window.matchMedia("(prefers-color-scheme: light)"),l=window.CSS&&CSS.supports("color","light-dark(#000, #fff)"),i=()=>l&&s.matches,d=localStorage.getItem("mw-theme");let u=d?"light"===d:i();const m=n=>{o.classList.add("mw-theme-switching"),a.classList.toggle("mw-theme-light",n),a.classList.toggle("mw-theme-dark",!n),o.offsetHeight,o.classList.remove("mw-theme-switching"),e(t,n),r&&(r.className=n?"fas fa-sun":"fas fa-moon")};m(u),s.addEventListener("change",()=>{localStorage.getItem("mw-theme")||(u=i(),m(u),n())}),t.addEventListener("click",()=>{u=!u,m(u),localStorage.setItem("mw-theme",u?"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=document.documentElement.clientHeight,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),{passive:!0})}(),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&&i()){const e=document.createElement("div");e.className="mw-localhost-indicator-pulse",t.prepend(e)}}(),function(){if(!i())return;const e=document.querySelector('meta[name="viewport"]'),t=e&&e.getAttribute("content")||"";if(/viewport-fit\s*=\s*cover/.test(t))return;console.warn('MaverickWave: <meta name="viewport"> is missing viewport-fit=cover. env(safe-area-inset-*) resolves to 0 without it, so notched phones lose the gutter, the nav panel and the modal padding that expect it.')}(),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?d(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(u),document.querySelectorAll("[data-calendar]").forEach(m),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(){const e=window.location.hostname;return"localhost"===e||"127.0.0.1"===e||e.includes("192.168.")}function d(e){e&&("DIALOG"===e.tagName?e.showModal():e.classList.add("mw-modal-open"))}function u(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 m(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=>d(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.13.0",
|
|
4
4
|
"config": {
|
|
5
|
-
"version_short": "5.
|
|
5
|
+
"version_short": "5.13"
|
|
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
|
@@ -33,6 +33,7 @@
|
|
|
33
33
|
initTabs();
|
|
34
34
|
initAlerts();
|
|
35
35
|
initLocalhostIndicator();
|
|
36
|
+
warnMissingViewportFit();
|
|
36
37
|
initFormSliders();
|
|
37
38
|
initModals();
|
|
38
39
|
initHeaderLoginButton();
|
|
@@ -287,17 +288,42 @@
|
|
|
287
288
|
if (nextBtn)
|
|
288
289
|
nextBtn.addEventListener('click', () => goToSlide(current + 1));
|
|
289
290
|
|
|
290
|
-
// Optional: Swipe support
|
|
291
|
+
// Optional: Swipe support. The dominant axis decides, not the horizontal
|
|
292
|
+
// distance alone - a finger scrolling the page down drifts sideways as it
|
|
293
|
+
// goes, and 50px of that is not a swipe. Passive because neither handler
|
|
294
|
+
// cancels the gesture, and without the flag the browser waits for them
|
|
295
|
+
// before it may scroll.
|
|
291
296
|
let startX = 0;
|
|
297
|
+
let startY = 0;
|
|
298
|
+
let swiping = false;
|
|
299
|
+
|
|
292
300
|
track.addEventListener(
|
|
293
301
|
'touchstart',
|
|
294
|
-
(e) =>
|
|
302
|
+
(e) => {
|
|
303
|
+
// A second finger is a pinch or a two-hand hold, never a swipe
|
|
304
|
+
swiping = e.touches.length === 1;
|
|
305
|
+
if (!swiping) return;
|
|
306
|
+
startX = e.touches[0].clientX;
|
|
307
|
+
startY = e.touches[0].clientY;
|
|
308
|
+
},
|
|
309
|
+
{ passive: true }
|
|
310
|
+
);
|
|
311
|
+
|
|
312
|
+
track.addEventListener('touchcancel', () => (swiping = false));
|
|
313
|
+
|
|
314
|
+
track.addEventListener(
|
|
315
|
+
'touchend',
|
|
316
|
+
(e) => {
|
|
317
|
+
if (!swiping) return;
|
|
318
|
+
swiping = false;
|
|
319
|
+
const deltaX = e.changedTouches[0].clientX - startX;
|
|
320
|
+
const deltaY = e.changedTouches[0].clientY - startY;
|
|
321
|
+
if (Math.abs(deltaX) < 50) return;
|
|
322
|
+
if (Math.abs(deltaX) <= Math.abs(deltaY)) return;
|
|
323
|
+
goToSlide(current + (deltaX < 0 ? 1 : -1));
|
|
324
|
+
},
|
|
325
|
+
{ passive: true }
|
|
295
326
|
);
|
|
296
|
-
track.addEventListener('touchend', (e) => {
|
|
297
|
-
const delta = e.changedTouches[0].clientX - startX;
|
|
298
|
-
if (delta > 50) goToSlide(current - 1);
|
|
299
|
-
if (delta < -50) goToSlide(current + 1);
|
|
300
|
-
});
|
|
301
327
|
|
|
302
328
|
goToSlide(0);
|
|
303
329
|
}
|
|
@@ -674,7 +700,11 @@
|
|
|
674
700
|
|
|
675
701
|
const update = () => {
|
|
676
702
|
queued = false;
|
|
677
|
-
|
|
703
|
+
// The layout viewport, not innerHeight: on a phone that one is the visual
|
|
704
|
+
// viewport and grows by up to a hundred pixels as the URL bar slides away
|
|
705
|
+
// mid-scroll, which steps every layer at once. clientHeight only moves on
|
|
706
|
+
// a real resize.
|
|
707
|
+
const viewport = document.documentElement.clientHeight;
|
|
678
708
|
// Every read before the first write, or each write makes the next read
|
|
679
709
|
// lay the page out again - a reflow per layer per frame.
|
|
680
710
|
const values = layers.map((layer) => progress(layer, viewport));
|
|
@@ -839,7 +869,8 @@
|
|
|
839
869
|
}
|
|
840
870
|
}
|
|
841
871
|
});
|
|
842
|
-
}, 100)
|
|
872
|
+
}, 100),
|
|
873
|
+
{ passive: true }
|
|
843
874
|
);
|
|
844
875
|
}
|
|
845
876
|
|
|
@@ -975,26 +1006,42 @@
|
|
|
975
1006
|
}
|
|
976
1007
|
|
|
977
1008
|
// ===== Utility Functions =====
|
|
1009
|
+
function isLocalhost() {
|
|
1010
|
+
const host = window.location.hostname;
|
|
1011
|
+
return (
|
|
1012
|
+
host === 'localhost' || host === '127.0.0.1' || host.includes('192.168.')
|
|
1013
|
+
);
|
|
1014
|
+
}
|
|
1015
|
+
|
|
978
1016
|
function initLocalhostIndicator() {
|
|
979
1017
|
const activated = document.querySelector(
|
|
980
1018
|
'.mw-localhost-indicator-activated'
|
|
981
1019
|
);
|
|
982
1020
|
const header = document.querySelector('.mw-header');
|
|
983
1021
|
|
|
984
|
-
if (activated) {
|
|
985
|
-
const
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
window.location.hostname.includes('192.168.');
|
|
989
|
-
|
|
990
|
-
if (isLocalhost) {
|
|
991
|
-
const indicator = document.createElement('div');
|
|
992
|
-
indicator.className = 'mw-localhost-indicator-pulse';
|
|
993
|
-
header.prepend(indicator);
|
|
994
|
-
}
|
|
1022
|
+
if (activated && isLocalhost()) {
|
|
1023
|
+
const indicator = document.createElement('div');
|
|
1024
|
+
indicator.className = 'mw-localhost-indicator-pulse';
|
|
1025
|
+
header.prepend(indicator);
|
|
995
1026
|
}
|
|
996
1027
|
}
|
|
997
1028
|
|
|
1029
|
+
// iOS resolves every safe-area inset to 0 without it, so the gutter, the nav
|
|
1030
|
+
// panel and the modals lose their cutout budget - silently, hence the warning.
|
|
1031
|
+
function warnMissingViewportFit() {
|
|
1032
|
+
if (!isLocalhost()) return;
|
|
1033
|
+
|
|
1034
|
+
const meta = document.querySelector('meta[name="viewport"]');
|
|
1035
|
+
const content = meta ? meta.getAttribute('content') || '' : '';
|
|
1036
|
+
if (/viewport-fit\s*=\s*cover/.test(content)) return;
|
|
1037
|
+
|
|
1038
|
+
console.warn(
|
|
1039
|
+
'MaverickWave: <meta name="viewport"> is missing viewport-fit=cover. ' +
|
|
1040
|
+
'env(safe-area-inset-*) resolves to 0 without it, so notched phones ' +
|
|
1041
|
+
'lose the gutter, the nav panel and the modal padding that expect it.'
|
|
1042
|
+
);
|
|
1043
|
+
}
|
|
1044
|
+
|
|
998
1045
|
// ===== Form Sliders =====
|
|
999
1046
|
function initFormSliders() {
|
|
1000
1047
|
document.querySelectorAll('.mw-slider-container').forEach((wrapper) => {
|
|
@@ -267,5 +267,6 @@
|
|
|
267
267
|
WCAG 2.5.8 puts the floor at 24px, and that is a floor, not a goal.
|
|
268
268
|
<code>mw-btn-mini</code> keeps its 18px circle - it sits in tag rows and table
|
|
269
269
|
cells where a bigger one would shift the layout - and grows its hit area to
|
|
270
|
-
28px instead
|
|
270
|
+
28px instead, as does a kanban action button on its 32px box. Nothing to
|
|
271
|
+
switch on; resize this page or open it on a phone.
|
|
271
272
|
</p>
|
|
@@ -56,7 +56,8 @@
|
|
|
56
56
|
<html lang="en">
|
|
57
57
|
<head>
|
|
58
58
|
<meta charset="UTF-8">
|
|
59
|
-
<
|
|
59
|
+
<!-- viewport-fit=cover is what makes env(safe-area-inset-*) resolve on a notched phone -->
|
|
60
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover">
|
|
60
61
|
<title>My MaverickWave Project</title>
|
|
61
62
|
<!-- Framework CSS -->
|
|
62
63
|
<link rel="stylesheet" href="path/to/maverick-wave.min.css">
|
|
@@ -200,9 +201,57 @@ body {
|
|
|
200
201
|
<i class="fas fa-exclamation-triangle mw-mr-1"></i>
|
|
201
202
|
Without <code>base</code> every component renders without colors - it
|
|
202
203
|
carries the <code>:root</code> custom properties. A subset like the
|
|
203
|
-
one above compiles to roughly
|
|
204
|
-
kB /
|
|
204
|
+
one above compiles to roughly 113 kB raw / 17 kB gzipped, against 281
|
|
205
|
+
kB / 40 kB for the full build.
|
|
205
206
|
</p>
|
|
207
|
+
|
|
208
|
+
<h5 class="mw-mt-4">Mixins and Functions</h5>
|
|
209
|
+
<p>
|
|
210
|
+
<code>abstracts</code> brings these into your own rules. They exist on
|
|
211
|
+
the SCSS path only - the compiled CSS carries none of them.
|
|
212
|
+
</p>
|
|
213
|
+
<ul class="mw-list">
|
|
214
|
+
<li>
|
|
215
|
+
<code>fluid($min, $max, $from: 'xs', $to: 'md')</code> - a clamp
|
|
216
|
+
between two sizes. Each end is a key of <code>$font-sizes</code> or
|
|
217
|
+
a plain rem/px length, so a hero that does not sit on the scale
|
|
218
|
+
still gets one. The rem term is the point: a vw-only clamp ignores
|
|
219
|
+
the reader's font size. The default range stops at <code>md</code>,
|
|
220
|
+
a headline passes <code>$to: 'xl'</code>.
|
|
221
|
+
</li>
|
|
222
|
+
<li>
|
|
223
|
+
<code>media-up($bp)</code> / <code>media-down($bp)</code> - the
|
|
224
|
+
<code>$breakpoints</code> map as a query.
|
|
225
|
+
</li>
|
|
226
|
+
<li>
|
|
227
|
+
<code>touch-context($bp: 'md')</code> - coarse pointer
|
|
228
|
+
<em>or</em> narrow viewport, the condition every target-size rule in
|
|
229
|
+
the framework hangs under.
|
|
230
|
+
</li>
|
|
231
|
+
<li>
|
|
232
|
+
<code>touch-floor($size: 2.75rem)</code> - that condition plus a
|
|
233
|
+
<code>min-height</code>. Not for a link inside a sentence: WCAG
|
|
234
|
+
2.5.8 exempts those, and a <code>min-height</code> there pushes the
|
|
235
|
+
lines of the paragraph apart.
|
|
236
|
+
</li>
|
|
237
|
+
<li>
|
|
238
|
+
<code>hit-area($grow: 6px)</code> - grows the hit area through
|
|
239
|
+
<code>::after</code> without touching the silhouette, for a control
|
|
240
|
+
whose size is the design. Neighbours need a gap of at least twice
|
|
241
|
+
<code>$grow</code>, or two hit areas overlap.
|
|
242
|
+
</li>
|
|
243
|
+
</ul>
|
|
244
|
+
<pre
|
|
245
|
+
class="mw-code-block"
|
|
246
|
+
><code>@use 'maverick-wave/src/scss/abstracts' as *;
|
|
247
|
+
|
|
248
|
+
.hero h1 {
|
|
249
|
+
font-size: fluid(1.95rem, 4.2rem, $to: 'xl');
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
.my-close-button {
|
|
253
|
+
@include touch-floor;
|
|
254
|
+
}</code></pre>
|
|
206
255
|
</div>
|
|
207
256
|
</div>
|
|
208
257
|
|
|
@@ -53,10 +53,13 @@
|
|
|
53
53
|
element the page content is a <strong>sibling</strong> of - the section around
|
|
54
54
|
a hero, not the hero itself - because that is what sticky and the sibling
|
|
55
55
|
selector need. Everything after it gets the page background and a layer above,
|
|
56
|
-
or the pinned picture shows through.
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
56
|
+
or the pinned picture shows through. The section right after it also gets an
|
|
57
|
+
upward shadow, so it reads as sliding over the picture rather than cutting it
|
|
58
|
+
off. That one carries fixed values instead of the elevation ramp: it lands on
|
|
59
|
+
the picture, not on a theme surface, and the light theme's shadows are cut for
|
|
60
|
+
paper and vanish there. Pair it with <code>mw-header-reveal</code> on the
|
|
61
|
+
header and the page opens on the picture alone: the bar stays away for the
|
|
62
|
+
first 130px of scroll and has ridden in by 420px.
|
|
60
63
|
</p>
|
|
61
64
|
<p class="mw-text-muted mw-text-measure mw-mb-6">
|
|
62
65
|
Add <code>mw-parallax-rise</code> next to it and the picture lifts by
|
|
@@ -73,7 +76,7 @@
|
|
|
73
76
|
</h4>
|
|
74
77
|
<p class="mw-text-muted mw-text-measure mw-mb-6">
|
|
75
78
|
The band before the components section on this page: it keeps its place in the
|
|
76
|
-
flow and moves at a
|
|
79
|
+
flow and moves at a fifth of your scrolling, so picture and text are still
|
|
77
80
|
going while the next section closes in from below. Pinning is the same move
|
|
78
81
|
with the tempo at zero.
|
|
79
82
|
<code>--mw-parallax-slow-travel</code> (<code>45vh</code>) is the dial and
|
|
@@ -46,7 +46,7 @@
|
|
|
46
46
|
</p>
|
|
47
47
|
<ul>
|
|
48
48
|
<li>Built with SCSS for better organization and maintainability</li>
|
|
49
|
-
<li>Optimized file size (
|
|
49
|
+
<li>Optimized file size (about 40KB minified and gzipped)</li>
|
|
50
50
|
<li>
|
|
51
51
|
Compatible with all modern browsers (Chrome, Firefox, Safari, Edge)
|
|
52
52
|
</li>
|
|
@@ -3,6 +3,9 @@
|
|
|
3
3
|
The heading scale, the body text and everything the framework sets on bare
|
|
4
4
|
elements. Headings carry <code>text-wrap: balance</code> and a touch of
|
|
5
5
|
negative tracking, paragraphs <code>text-wrap: pretty</code>.
|
|
6
|
+
<code>h1</code> and <code>h2</code> interpolate between 375px and 768px
|
|
7
|
+
instead of stepping at a breakpoint - a phone and a desktop keep the sizes
|
|
8
|
+
they had, the widths in between grow with the viewport.
|
|
6
9
|
</p>
|
|
7
10
|
|
|
8
11
|
<div class="mw-grid-2-lg">
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
@use 'sass:list';
|
|
2
2
|
@use 'sass:map';
|
|
3
|
+
@use 'sass:math';
|
|
4
|
+
@use 'sass:meta';
|
|
3
5
|
@use 'variables' as v;
|
|
4
6
|
|
|
5
7
|
// Function to get a color from the colors map
|
|
@@ -12,6 +14,54 @@
|
|
|
12
14
|
@return map.get(v.$font-sizes, $key);
|
|
13
15
|
}
|
|
14
16
|
|
|
17
|
+
// Interpolates between two sizes, clamped at both ends. Each end is a key of
|
|
18
|
+
// $font-sizes or a plain rem/px length, because a hero rarely sits on the scale
|
|
19
|
+
// and the alternative is a hand-written clamp - which is where the vw-only form
|
|
20
|
+
// creeps back in. The default range stops at 'md' because that is where the
|
|
21
|
+
// stepped sizes it replaces reached their largest value - running it to 'xl'
|
|
22
|
+
// would shrink every heading on a desktop, so a headline passes $to itself.
|
|
23
|
+
// Only the slope is in vw: a size in vw alone ignores the reader's font size and
|
|
24
|
+
// stops responding to zoom, the rem term is what keeps that alive.
|
|
25
|
+
@function fluid($min, $max, $from: 'xs', $to: 'md') {
|
|
26
|
+
$min-rem: _to-rem($min, 'min');
|
|
27
|
+
$max-rem: _to-rem($max, 'max');
|
|
28
|
+
$vw-from: math.div(map.get(v.$breakpoints, $from), 16px);
|
|
29
|
+
$vw-to: math.div(map.get(v.$breakpoints, $to), 16px);
|
|
30
|
+
|
|
31
|
+
$slope: math.div($max-rem - $min-rem, $vw-to - $vw-from);
|
|
32
|
+
$intercept: $min-rem - $slope * $vw-from;
|
|
33
|
+
|
|
34
|
+
@return clamp(
|
|
35
|
+
#{$min-rem}rem,
|
|
36
|
+
#{_round4($intercept)}rem + #{_round4($slope * 100)}vw,
|
|
37
|
+
#{$max-rem}rem
|
|
38
|
+
);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
@function _to-rem($value, $end) {
|
|
42
|
+
@if meta.type-of($value) == 'string' {
|
|
43
|
+
$mapped: map.get(v.$font-sizes, $value);
|
|
44
|
+
@if $mapped == null {
|
|
45
|
+
@error "fluid(): #{$end} '#{$value}' is not a key of $font-sizes.";
|
|
46
|
+
}
|
|
47
|
+
@return math.div($mapped, 1rem);
|
|
48
|
+
}
|
|
49
|
+
@if math.is-unitless($value) {
|
|
50
|
+
@error "fluid(): #{$end} #{$value} needs a unit - 1.95rem or 31px.";
|
|
51
|
+
}
|
|
52
|
+
@if math.unit($value) == 'rem' {
|
|
53
|
+
@return math.div($value, 1rem);
|
|
54
|
+
}
|
|
55
|
+
@if math.unit($value) == 'px' {
|
|
56
|
+
@return math.div($value, 16px);
|
|
57
|
+
}
|
|
58
|
+
@error "fluid(): #{$end} must be rem or px, got #{$value}.";
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
@function _round4($n) {
|
|
62
|
+
@return math.div(math.round($n * 10000), 10000);
|
|
63
|
+
}
|
|
64
|
+
|
|
15
65
|
// Function to get a font weight from the font-weights map
|
|
16
66
|
@function font-weight($key) {
|
|
17
67
|
@return map.get(v.$font-weights, $key);
|
|
@@ -149,6 +149,39 @@
|
|
|
149
149
|
-webkit-tap-highlight-color: transparent;
|
|
150
150
|
}
|
|
151
151
|
|
|
152
|
+
// Coarse *or* narrow, because a tablet in landscape is wide and still
|
|
153
|
+
// finger-operated. Named so a consumer can put their own control under the same
|
|
154
|
+
// condition instead of guessing it.
|
|
155
|
+
@mixin touch-context($breakpoint: 'md') {
|
|
156
|
+
@media (pointer: coarse), (width <= #{breakpoint($breakpoint)}) {
|
|
157
|
+
@content;
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
// WCAG 2.5.8 floor for a control that is a line of text under a pointer and a
|
|
162
|
+
// target under a thumb. Not for a link inside a sentence - those are exempt, and
|
|
163
|
+
// a min-height there pushes the lines of the paragraph apart.
|
|
164
|
+
@mixin touch-floor($size: 2.75rem) {
|
|
165
|
+
@include touch-context {
|
|
166
|
+
min-height: $size;
|
|
167
|
+
@content;
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
// Grows the hit area without touching the silhouette - for a control whose size
|
|
172
|
+
// is the design: a 9px gallery dot, an 18px mini button. Neighbours need a gap
|
|
173
|
+
// of at least twice $grow, or two hit areas overlap and a tap lands on the one
|
|
174
|
+
// next door. Takes ::after, so it is out for anything carrying a `data-tooltip`.
|
|
175
|
+
@mixin hit-area($grow: 6px) {
|
|
176
|
+
position: relative;
|
|
177
|
+
|
|
178
|
+
&::after {
|
|
179
|
+
content: '';
|
|
180
|
+
position: absolute;
|
|
181
|
+
inset: -#{$grow};
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
|
|
152
185
|
// One shape for every scroll container and the page itself
|
|
153
186
|
@mixin scrollbar($thumb: var(--mw-text-muted-color), $track: transparent) {
|
|
154
187
|
scrollbar-width: thin;
|
|
@@ -44,31 +44,14 @@
|
|
|
44
44
|
letter-spacing: -0.01em;
|
|
45
45
|
}
|
|
46
46
|
|
|
47
|
-
//
|
|
48
|
-
//
|
|
49
|
-
// column is a third of the screen before the first line of copy.
|
|
47
|
+
// The clamp ends where the two steps it replaces ended, so a phone and a
|
|
48
|
+
// desktop are unchanged and only the widths between them move.
|
|
50
49
|
h1 {
|
|
51
|
-
font-size:
|
|
52
|
-
|
|
53
|
-
@include media-up('sm') {
|
|
54
|
-
font-size: font-size('4xl');
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
@include media-up('md') {
|
|
58
|
-
font-size: font-size('5xl');
|
|
59
|
-
}
|
|
50
|
+
font-size: fluid('3xl', '5xl');
|
|
60
51
|
}
|
|
61
52
|
|
|
62
53
|
h2 {
|
|
63
|
-
font-size:
|
|
64
|
-
|
|
65
|
-
@include media-up('sm') {
|
|
66
|
-
font-size: font-size('3xl');
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
@include media-up('md') {
|
|
70
|
-
font-size: font-size('4xl');
|
|
71
|
-
}
|
|
54
|
+
font-size: fluid('2xl', '4xl');
|
|
72
55
|
}
|
|
73
56
|
|
|
74
57
|
h3 {
|
|
@@ -9,21 +9,29 @@
|
|
|
9
9
|
border-radius: radius('md');
|
|
10
10
|
overflow: hidden;
|
|
11
11
|
|
|
12
|
+
// The slider caps at 600px, so past a tablet the viewport no longer says how
|
|
13
|
+
// much room it has. Named, so a query cannot resolve to a container above.
|
|
14
|
+
container: mw-slider / inline-size;
|
|
15
|
+
|
|
12
16
|
// Heights variables for consistency
|
|
13
17
|
$height-lg: 370px;
|
|
14
18
|
$height-md: 320px;
|
|
15
19
|
$height-sm: 250px;
|
|
16
20
|
|
|
21
|
+
// The slider widths the old viewport steps landed on, not the breakpoints
|
|
22
|
+
$wide: 560px;
|
|
23
|
+
$mid: 420px;
|
|
24
|
+
|
|
17
25
|
&-base {
|
|
18
26
|
position: relative;
|
|
19
27
|
width: 100%;
|
|
20
28
|
height: $height-sm;
|
|
21
29
|
|
|
22
|
-
@
|
|
30
|
+
@container mw-slider (width >= #{$mid}) {
|
|
23
31
|
height: $height-md;
|
|
24
32
|
}
|
|
25
33
|
|
|
26
|
-
@
|
|
34
|
+
@container mw-slider (width >= #{$wide}) {
|
|
27
35
|
height: $height-lg;
|
|
28
36
|
}
|
|
29
37
|
}
|
|
@@ -43,11 +51,11 @@
|
|
|
43
51
|
height: $height-sm;
|
|
44
52
|
pointer-events: none;
|
|
45
53
|
|
|
46
|
-
@
|
|
54
|
+
@container mw-slider (width >= #{$mid}) {
|
|
47
55
|
height: $height-md;
|
|
48
56
|
}
|
|
49
57
|
|
|
50
|
-
@
|
|
58
|
+
@container mw-slider (width >= #{$wide}) {
|
|
51
59
|
height: $height-lg;
|
|
52
60
|
}
|
|
53
61
|
}
|
|
@@ -86,11 +94,11 @@
|
|
|
86
94
|
z-index: z-index('menu');
|
|
87
95
|
width: 100%;
|
|
88
96
|
|
|
89
|
-
@
|
|
97
|
+
@container mw-slider (width >= #{$mid}) {
|
|
90
98
|
grid-template-columns: repeat(3, 1fr);
|
|
91
99
|
}
|
|
92
100
|
|
|
93
|
-
@
|
|
101
|
+
@container mw-slider (width >= #{$wide}) {
|
|
94
102
|
gap: spacing('3');
|
|
95
103
|
padding: spacing('3');
|
|
96
104
|
}
|
|
@@ -106,11 +114,11 @@
|
|
|
106
114
|
z-index: z-index('menu');
|
|
107
115
|
width: 100%;
|
|
108
116
|
|
|
109
|
-
@
|
|
117
|
+
@container mw-slider (width >= #{$mid}) {
|
|
110
118
|
grid-template-columns: repeat(2, 1fr);
|
|
111
119
|
}
|
|
112
120
|
|
|
113
|
-
@
|
|
121
|
+
@container mw-slider (width >= #{$wide}) {
|
|
114
122
|
gap: spacing('3');
|
|
115
123
|
padding: spacing('3');
|
|
116
124
|
}
|
|
@@ -257,7 +257,7 @@
|
|
|
257
257
|
// A menu opened by a thumb needs rows a thumb can hit, and the room to show
|
|
258
258
|
// them - so it takes the trigger's full width rather than a 200px column
|
|
259
259
|
// floating beside it.
|
|
260
|
-
@
|
|
260
|
+
@include touch-context('sm') {
|
|
261
261
|
.mw-dropdown-menu {
|
|
262
262
|
min-width: max(100%, 240px);
|
|
263
263
|
}
|