maverick-wave 4.9.4 → 4.11.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.
Files changed (117) hide show
  1. package/.claude/skills/maverick-wave/SKILL.md +112 -12
  2. package/.claude/skills/maverick-wave/references/components.md +152 -4
  3. package/.claude/skills/maverick-wave/references/forms.md +26 -0
  4. package/.claude/skills/maverick-wave/references/javascript.md +34 -27
  5. package/.claude/skills/maverick-wave/references/layout.md +38 -3
  6. package/.claude/skills/maverick-wave/references/theming.md +33 -7
  7. package/CHANGELOG.md +6 -0
  8. package/README.md +79 -4
  9. package/index.html +16 -0
  10. package/maverick-wave.min.css +3 -3
  11. package/maverick-wave.min.js +1 -1
  12. package/package.json +2 -2
  13. package/src/js/main.js +71 -1
  14. package/src/partials/accordions-container.html +5 -0
  15. package/src/partials/alerts-container.html +5 -0
  16. package/src/partials/avatars-container.html +5 -0
  17. package/src/partials/badges-container.html +114 -0
  18. package/src/partials/blog-posts-container.html +5 -0
  19. package/src/partials/breadcrumbs-container.html +1 -1
  20. package/src/partials/button-bar-container.html +5 -0
  21. package/src/partials/buttons-container.html +84 -0
  22. package/src/partials/calendar-container.html +1 -1
  23. package/src/partials/cards-container.html +5 -0
  24. package/src/partials/code-container.html +6 -0
  25. package/src/partials/colors-container.html +1 -1
  26. package/src/partials/coming-soon-container.html +4 -0
  27. package/src/partials/divider-container.html +4 -0
  28. package/src/partials/dropdown-container.html +119 -0
  29. package/src/partials/empty-state-container.html +5 -0
  30. package/src/partials/form-container.html +5 -0
  31. package/src/partials/form-elements-container.html +5 -0
  32. package/src/partials/form-field-container.html +5 -0
  33. package/src/partials/gallery-container.html +5 -0
  34. package/src/partials/get-started-container.html +16 -4
  35. package/src/partials/header-container.html +6 -2
  36. package/src/partials/header-utilities-container.html +8 -2
  37. package/src/partials/html-lists-container.html +5 -0
  38. package/src/partials/info-container.html +4 -0
  39. package/src/partials/input-group-container.html +5 -0
  40. package/src/partials/item-lists-container.html +5 -0
  41. package/src/partials/kanban-container.html +1 -1
  42. package/src/partials/kbd-container.html +63 -0
  43. package/src/partials/meta-info-container.html +5 -0
  44. package/src/partials/pagination-container.html +1 -1
  45. package/src/partials/panels-container.html +4 -0
  46. package/src/partials/progress-container.html +4 -0
  47. package/src/partials/ratings-container.html +1 -1
  48. package/src/partials/skeleton-container.html +5 -0
  49. package/src/partials/spinners-container.html +5 -1
  50. package/src/partials/stepper-container.html +4 -0
  51. package/src/partials/tables-container.html +7 -0
  52. package/src/partials/tabs-container.html +35 -13
  53. package/src/partials/tags-container.html +5 -0
  54. package/src/partials/tiles-container.html +1 -1
  55. package/src/partials/typography-container.html +5 -0
  56. package/src/partials/utilities-container.html +153 -0
  57. package/src/scss/abstracts/_mixins.scss +176 -0
  58. package/src/scss/abstracts/_variables.scss +193 -5
  59. package/src/scss/base/_base.scss +103 -2
  60. package/src/scss/base/_reset.scss +43 -1
  61. package/src/scss/base/_typography.scss +47 -0
  62. package/src/scss/components/_accordions.scss +11 -1
  63. package/src/scss/components/_alerts.scss +3 -3
  64. package/src/scss/components/_avatars.scss +27 -6
  65. package/src/scss/components/_badge.scss +157 -0
  66. package/src/scss/components/_blog-post.scss +10 -7
  67. package/src/scss/components/_breadcrumbs.scss +11 -2
  68. package/src/scss/components/_button-bar.scss +9 -2
  69. package/src/scss/components/_buttons.scss +133 -17
  70. package/src/scss/components/_calendar.scss +13 -2
  71. package/src/scss/components/_cards.scss +12 -5
  72. package/src/scss/components/_code.scss +15 -0
  73. package/src/scss/components/_coming-soon.scss +5 -2
  74. package/src/scss/components/_content-slider.scss +1 -1
  75. package/src/scss/components/_dropdown.scss +219 -0
  76. package/src/scss/components/_gallery.scss +17 -8
  77. package/src/scss/components/_index.scss +3 -0
  78. package/src/scss/components/_info.scss +14 -8
  79. package/src/scss/components/_kanban.scss +40 -6
  80. package/src/scss/components/_kbd.scss +43 -0
  81. package/src/scss/components/_lists.scss +26 -23
  82. package/src/scss/components/_modals.scss +71 -6
  83. package/src/scss/components/_pagination.scss +4 -3
  84. package/src/scss/components/_panels.scss +13 -14
  85. package/src/scss/components/_progress.scss +1 -1
  86. package/src/scss/components/_segmented.scss +8 -4
  87. package/src/scss/components/_stepper.scss +3 -3
  88. package/src/scss/components/_tables.scss +5 -8
  89. package/src/scss/components/_tabs.scss +22 -3
  90. package/src/scss/components/_tags.scss +1 -2
  91. package/src/scss/components/_techstack-bucket.scss +8 -5
  92. package/src/scss/components/_theme-toggle.scss +16 -8
  93. package/src/scss/components/_tiles.scss +14 -4
  94. package/src/scss/components/_timelines.scss +9 -6
  95. package/src/scss/components/_toasts.scss +1 -1
  96. package/src/scss/form-elements/_checkbox.scss +2 -1
  97. package/src/scss/form-elements/_form.scss +2 -2
  98. package/src/scss/form-elements/_input-group.scss +30 -1
  99. package/src/scss/form-elements/_input.scss +10 -10
  100. package/src/scss/form-elements/_login.scss +1 -1
  101. package/src/scss/form-elements/_radio.scss +4 -3
  102. package/src/scss/form-elements/_select.scss +9 -10
  103. package/src/scss/form-elements/_slider.scss +11 -11
  104. package/src/scss/form-elements/_textarea.scss +5 -8
  105. package/src/scss/form-elements/_toggle.scss +6 -5
  106. package/src/scss/layout/_footer.scss +14 -7
  107. package/src/scss/layout/_header.scss +18 -17
  108. package/src/scss/layout/_home.scss +1 -1
  109. package/src/scss/layout/_main.scss +6 -6
  110. package/src/scss/layout/_section.scss +7 -4
  111. package/src/scss/utilities/_accessibility.scss +38 -0
  112. package/src/scss/utilities/_aspect.scss +27 -0
  113. package/src/scss/utilities/_display.scss +52 -0
  114. package/src/scss/utilities/_elevation.scss +16 -0
  115. package/src/scss/utilities/_index.scss +2 -0
  116. package/src/scss/utilities/_text.scss +63 -0
  117. package/src/scss/utilities/_touch-targets.scss +63 -0
@@ -1 +1 @@
1
- !function(){"use strict";function e(e,t){e&&(e.classList.toggle("mw-active",t),t||e.classList.remove("active"))}function t(){document.querySelectorAll(".color-swatch").forEach(e=>{const t=function(e){if(!e||"transparent"===e)return"#000000";const t=e=>Math.max(0,Math.min(255,Math.round(e))).toString(16).padStart(2,"0"),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 c="#"+t(a[1])+t(a[2])+t(a[3]),o=void 0===a[4]?1:parseFloat(a[4]);return(o<1?`${c} / ${o}`:c).toUpperCase()}(window.getComputedStyle(e).backgroundColor),n=e.parentElement.querySelector(".mw-text-muted");n&&(n.textContent=t)})}function n(e){const t=Array.from(e.querySelectorAll(".mw-kanban-column")),n=e.querySelector(".mw-kanban-composer"),a=e.querySelector(".mw-kanban-card-template"),c=e.dataset.kanbanPrefix||"MW",o=n.querySelector(".mw-kanban-composer-title"),r=n.querySelector(".mw-kanban-composer-text"),l=n.querySelector(".mw-kanban-composer-priority"),s=n.querySelector(".mw-kanban-composer-assignee");let i=null;function d(){t.forEach(function(e,n){const a=e.querySelectorAll(".mw-kanban-card"),c=e.querySelector(".mw-kanban-count");c&&(c.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){f(),i=t||null,o.value=t?u(t,".mw-kanban-card-title"):"",r.value=t?u(t,".mw-kanban-card-text"):"",l.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):"",s.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"),o.focus()}function f(){n.classList.remove("mw-active"),i&&i.classList.remove("mw-kanban-editing"),i=null}function w(){const t=o.value.trim();if(!t)return void o.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=r.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,l.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 c=a||document.createElement("div");c.className="mw-avatar mw-avatar-xs mw-avatar-initials",c.textContent=t,a||n.prepend(c)}(u,s.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 c+"-"+(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)}f(),d()}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"),c=t[t.indexOf(a)+n];c&&(c.querySelector(".mw-kanban-column-body").appendChild(e),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 c=e.target.closest(".mw-kanban-delete");if(c){const e=c.closest(".mw-kanban-card");return e===i&&f(),e.remove(),void d()}const o=e.target.closest(".mw-kanban-add");o?m(o.closest(".mw-kanban-column"),null):e.target.closest(".mw-kanban-composer-cancel")&&f()}),n.addEventListener("submit",function(e){e.preventDefault(),w()}),n.addEventListener("keydown",function(e){"Escape"===e.key&&f()}),d()}function a(e){const t=e.querySelector(".mw-calendar-grid"),n=e.querySelector(".mw-calendar-title");if(!t)return;const a="week"===e.dataset.calendar,c=function(e){if(!e)return{};try{return JSON.parse(e)}catch(e){return{}}}(e.dataset.calendarMarkers),o=e.dataset.calendarLocale||document.documentElement.lang||void 0,r=new Date;r.setHours(0,0,0,0);let l=e.dataset.calendarDate?new Date(e.dataset.calendarDate+"T00:00:00"):new Date(r),s=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 l.toLocaleDateString(o,{month:"long",year:"numeric"});const e=i(l),t=new Date(e);t.setDate(t.getDate()+6);const n=e.toLocaleDateString(o,{day:"numeric",month:e.getMonth()===t.getMonth()?void 0:"short"}),c=t.toLocaleDateString(o,{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+" - "+c}function m(e){const t=e.getDay();return 0===t||6===t}function f(e,t){const n=d(e),l=document.createElement("button");l.type="button",l.className="mw-calendar-day",l.tabIndex=-1,l.dataset.calendarDay=n,l.setAttribute("aria-pressed",n===s?"true":"false"),l.setAttribute("aria-label",e.toLocaleDateString(o,{weekday:"long",day:"numeric",month:"long",year:"numeric"})),m(e)&&l.classList.add("mw-calendar-weekend"),a||e.getMonth()===t||l.classList.add("mw-calendar-adjacent"),n===d(r)&&(l.classList.add("mw-calendar-today"),l.setAttribute("aria-current","date")),n===s&&l.classList.add("mw-selected");const i=document.createElement("span");i.className="mw-calendar-date",i.textContent=e.getDate(),l.appendChild(i);const u=[].concat(c[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)}),l.appendChild(e)}return l}function w(){const e=l.getMonth(),c=a?7:42,r=i(a?l:new Date(l.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(o,{weekday:"short"}),t.appendChild(n),e.setDate(e.getDate()+1)}}();for(let n=0;n<c;n++)t.appendChild(f(r,e)),r.setDate(r.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 c=n.target.closest("[data-calendar-nav]");if(c)return o=parseInt(c.dataset.calendarNav,10),a?l.setDate(l.getDate()+7*o):l=new Date(l.getFullYear(),l.getMonth()+o,1),void w();var o;const r=n.target.closest(".mw-calendar-day");var i;r&&!r.disabled&&(i=r.dataset.calendarDay,s=i===s?"":i,t.querySelectorAll(".mw-calendar-day").forEach(function(e){const t=e.dataset.calendarDay===s;e.classList.toggle("mw-selected",t),e.setAttribute("aria-pressed",t?"true":"false")}),e.dispatchEvent(new CustomEvent("mw-calendar-select",{bubbles:!0,detail:{date:s}})))}),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 c=new Date(a.dataset.calendarDay+"T00:00:00");c.setDate(c.getDate()+n),function(e){const n=d(e);let a=t.querySelector('[data-calendar-day="'+n+'"]');a||(l=new Date(e),w(),a=t.querySelector('[data-calendar-day="'+n+'"]')),a&&(t.querySelectorAll(".mw-calendar-day").forEach(function(e){e.tabIndex=-1}),a.tabIndex=0,a.focus())}(c)}),w()}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,c=e.querySelector(".mw-gallery-dots"),o=e.querySelector(".mw-gallery-desc"),r=t.querySelector(".mw-gallery-navi-prev"),l=t.querySelector(".mw-gallery-navi-next");let s=0;function i(e){const t=a.length;s=(e+t)%t,n.style.transform=`translateX(-${100*s}%)`,c&&c.querySelectorAll(".mw-gallery-dot").forEach((e,t)=>{e.classList.toggle("mw-active",t===s)}),o&&(o.textContent=a[s].dataset.desc||"")}if(c)for(let e=0;e<a.length;e++){const t=document.createElement("span");t.className="mw-gallery-dot"+(0===e?" mw-active":""),t.addEventListener("click",()=>i(e)),c.appendChild(t)}r&&r.addEventListener("click",()=>i(s-1)),l&&l.addEventListener("click",()=>i(s+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(s-1),t<-50&&i(s+1)}),i(0)}(t,e)}),function(){const n=document.querySelector(".mw-theme-toggle");if(!n)return;const a=document.body,c=n.querySelector(".mw-theme-toggle-slider i"),o=getComputedStyle(document.documentElement).getPropertyValue("--mw-internal-theme-mode").trim()||"switchable";if("switchable"!==o)return console.log(`Theme mode fixed to: ${o}. Disabling toggle.`),c&&(c.className="light"===o?"fas fa-sun":"fas fa-moon"),e(n,"light"===o),n.style.opacity="0.4",n.style.pointerEvents="none",n.style.cursor="default",n.setAttribute("aria-disabled","true"),localStorage.removeItem("mw-theme"),void("dark"===o&&a.classList.remove("mw-theme-light"));let r="light"===localStorage.getItem("mw-theme");const l=t=>{a.classList.toggle("mw-theme-light",t),e(n,t),c&&(c.className=t?"fas fa-sun":"fas fa-moon")};l(r),n.addEventListener("click",()=>{r=!r,l(r),localStorage.setItem("mw-theme",r?"light":"dark"),setTimeout(t,400)})}(),t(),document.querySelectorAll(".mw-accordion-header").forEach(t=>{t.addEventListener("click",function(){const t=!((n=this)&&(n.classList.contains("mw-active")||n.classList.contains("active")));var n;e(this,t),e(this.nextElementSibling,t)})}),function(){const e=document.querySelector(".mw-menu-btn"),t=document.querySelector(".mw-navbar");if(!e||!t)return;function n(){e.classList.remove("open"),t.classList.remove("open")}function a(n){n.preventDefault(),n.stopPropagation(),e.classList.toggle("open"),t.classList.toggle("open")}e.addEventListener("click",a),e.addEventListener("touchstart",a,{passive:!1}),document.addEventListener("click",function(a){t.classList.contains("open")&&(t.contains(a.target)||e.contains(a.target)||n())}),document.addEventListener("keydown",function(e){"Escape"===e.key&&n()})}(),function(){const e=document.querySelectorAll(".mw-progress-fill");if(!e.length)return;const t=new IntersectionObserver((e,t)=>{e.forEach(e=>{if(!e.isIntersecting)return;const n=e.target,a=n.dataset.value||0;n.style.width=a+"%",t.unobserve(n)})},{root:null,threshold:.2});e.forEach(e=>t.observe(e))}(),document.querySelectorAll('a[href^="#"]').forEach(e=>{e.addEventListener("click",function(e){const t=this.getAttribute("href");if("#"===t)return;if(!document.querySelector(t))return;const 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;window.addEventListener("scroll",function(e,t){let n;return function(){const a=this,c=arguments;clearTimeout(n),n=setTimeout(()=>e.apply(a,c),t)}}(function(){let a="";t.forEach(e=>{const t=e.offsetTop-100,n=e.clientHeight;scrollY>=t&&scrollY<t+n&&(a=e.getAttribute("id"))}),n.forEach(t=>{e(t,!1);const n=t.getAttribute("href");if(n){const c=n.indexOf("#");if(-1!==c){n.substring(c+1)===a&&e(t,!0)}}})},100))}(),document.querySelectorAll(".mw-tabs-nav-item").forEach(t=>{t.addEventListener("click",function(){const t=this.closest(".mw-tabs");if(!t)return;t.querySelectorAll(".mw-tabs-nav-item").forEach(t=>{e(t,!1)}),e(this,!0);const n=this.getAttribute("data-tab");n&&(t.querySelectorAll(".mw-tabs-panel").forEach(t=>{e(t,!1)}),e(document.getElementById(n),!0))})}),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,c=Math.round(e/a*100);t.style.setProperty("--value",c+"%"),n.classList.contains("mw-slider-numeric")?n.setAttribute("data-value",e):n.setAttribute("data-value",c)};t.addEventListener("input",a),a()}),document.querySelectorAll(".mw-modal-close").forEach(e=>{e.addEventListener("click",function(){const e=this.closest(".mw-modal-overlay");e&&e.classList.remove("mw-modal-open")})}),function(){const e=document.getElementById("login-button");e&&e.addEventListener("click",function(){const e=this.querySelector("i");e.classList.contains("fa-lock")?(e.classList.remove("fa-lock"),e.classList.add("fa-lock-open")):(e.classList.remove("fa-lock-open"),e.classList.add("fa-lock"))})}(),document.querySelectorAll(".mw-image-slider").forEach(t=>{const n=t.querySelectorAll(".mw-image-slider-overlay-image"),a=t.querySelectorAll("button[data-index]");if(!n.length||!a.length)return;let c=0;function o(){n.forEach(t=>{e(t,parseInt(t.dataset.index)===c)}),a.forEach(t=>{e(t,parseInt(t.dataset.index)===c)})}function r(e){c=e,o()}a.forEach(e=>{e.addEventListener("click",()=>{r(parseInt(e.dataset.index))})}),o()}),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(n),document.querySelectorAll("[data-calendar]").forEach(a)}),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}}))}}();
1
+ !function(){"use strict";function e(e,t){e&&(e.classList.toggle("mw-active",t),t||e.classList.remove("active"))}function t(){document.querySelectorAll(".color-swatch").forEach(e=>{const t=function(e){if(!e||"transparent"===e)return"#000000";const t=e=>Math.max(0,Math.min(255,Math.round(e))).toString(16).padStart(2,"0"),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 c="#"+t(a[1])+t(a[2])+t(a[3]),o=void 0===a[4]?1:parseFloat(a[4]);return(o<1?`${c} / ${o}`:c).toUpperCase()}(window.getComputedStyle(e).backgroundColor),n=e.parentElement.querySelector(".mw-text-muted");n&&(n.textContent=t)})}function n(e){const t=Array.from(e.querySelectorAll(".mw-kanban-column")),n=e.querySelector(".mw-kanban-composer"),a=e.querySelector(".mw-kanban-card-template"),c=e.dataset.kanbanPrefix||"MW",o=n.querySelector(".mw-kanban-composer-title"),r=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"),c=e.querySelector(".mw-kanban-count");c&&(c.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){f(),i=t||null,o.value=t?u(t,".mw-kanban-card-title"):"",r.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"),o.focus()}function f(){n.classList.remove("mw-active"),i&&i.classList.remove("mw-kanban-editing"),i=null}function w(){const t=o.value.trim();if(!t)return void o.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=r.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 c=a||document.createElement("div");c.className="mw-avatar mw-avatar-xs mw-avatar-initials",c.textContent=t,a||n.prepend(c)}(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 c+"-"+(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)}f(),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"),c=t[t.indexOf(a)+n];c&&(c.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 c=e.target.closest(".mw-kanban-delete");if(c){const e=c.closest(".mw-kanban-card");return e===i&&f(),e.remove(),void d()}const o=e.target.closest(".mw-kanban-add");o?m(o.closest(".mw-kanban-column"),null):e.target.closest(".mw-kanban-composer-cancel")&&f()}),n.addEventListener("submit",function(e){e.preventDefault(),w()}),n.addEventListener("keydown",function(e){"Escape"===e.key&&f()}),d()}function a(e){const t=e.querySelector(".mw-calendar-grid"),n=e.querySelector(".mw-calendar-title");if(!t)return;const a="week"===e.dataset.calendar,c=function(e){if(!e)return{};try{return JSON.parse(e)}catch(e){return{}}}(e.dataset.calendarMarkers),o=e.dataset.calendarLocale||document.documentElement.lang||void 0,r=new Date;r.setHours(0,0,0,0);let s=e.dataset.calendarDate?new Date(e.dataset.calendarDate+"T00:00:00"):new Date(r),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(o,{month:"long",year:"numeric"});const e=i(s),t=new Date(e);t.setDate(t.getDate()+6);const n=e.toLocaleDateString(o,{day:"numeric",month:e.getMonth()===t.getMonth()?void 0:"short"}),c=t.toLocaleDateString(o,{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+" - "+c}function m(e){const t=e.getDay();return 0===t||6===t}function f(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(o,{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(r)&&(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(c[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 w(){const e=s.getMonth(),c=a?7:42,r=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(o,{weekday:"short"}),t.appendChild(n),e.setDate(e.getDate()+1)}}();for(let n=0;n<c;n++)t.appendChild(f(r,e)),r.setDate(r.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 c=n.target.closest("[data-calendar-nav]");if(c)return o=parseInt(c.dataset.calendarNav,10),a?s.setDate(s.getDate()+7*o):s=new Date(s.getFullYear(),s.getMonth()+o,1),void w();var o;const r=n.target.closest(".mw-calendar-day");var i;r&&!r.disabled&&(i=r.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 c=new Date(a.dataset.calendarDay+"T00:00:00");c.setDate(c.getDate()+n),function(e){const n=d(e);let a=t.querySelector('[data-calendar-day="'+n+'"]');a||(s=new Date(e),w(),a=t.querySelector('[data-calendar-day="'+n+'"]')),a&&(t.querySelectorAll(".mw-calendar-day").forEach(function(e){e.tabIndex=-1}),a.tabIndex=0,a.focus())}(c)}),w()}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,c=e.querySelector(".mw-gallery-dots"),o=e.querySelector(".mw-gallery-desc"),r=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}%)`,c&&c.querySelectorAll(".mw-gallery-dot").forEach((e,t)=>{e.classList.toggle("mw-active",t===l)}),o&&(o.textContent=a[l].dataset.desc||"")}if(c)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)),c.appendChild(t)}r&&r.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 n=document.querySelector(".mw-theme-toggle");if(!n)return;const a=document.body,c=n.querySelector(".mw-theme-toggle-slider i"),o=getComputedStyle(document.documentElement).getPropertyValue("--mw-internal-theme-mode").trim()||"switchable";if("switchable"!==o)return console.log(`Theme mode fixed to: ${o}. Disabling toggle.`),c&&(c.className="light"===o?"fas fa-sun":"fas fa-moon"),e(n,"light"===o),n.style.opacity="0.4",n.style.pointerEvents="none",n.style.cursor="default",n.setAttribute("aria-disabled","true"),localStorage.removeItem("mw-theme"),void("dark"===o&&a.classList.remove("mw-theme-light"));let r="light"===localStorage.getItem("mw-theme");const s=t=>{a.classList.toggle("mw-theme-light",t),e(n,t),c&&(c.className=t?"fas fa-sun":"fas fa-moon")};s(r),n.addEventListener("click",()=>{r=!r,s(r),localStorage.setItem("mw-theme",r?"light":"dark"),setTimeout(t,400)})}(),t(),document.querySelectorAll(".mw-accordion-header").forEach(t=>{t.addEventListener("click",function(){const t=!((n=this)&&(n.classList.contains("mw-active")||n.classList.contains("active")));var n;e(this,t),e(this.nextElementSibling,t)})}),function(){const e=document.querySelector(".mw-menu-btn"),t=document.querySelector(".mw-navbar");if(!e||!t)return;function n(){e.classList.remove("open"),t.classList.remove("open")}function a(n){n.preventDefault(),n.stopPropagation(),e.classList.toggle("open"),t.classList.toggle("open")}e.addEventListener("click",a),e.addEventListener("touchstart",a,{passive:!1}),document.addEventListener("click",function(a){t.classList.contains("open")&&(t.contains(a.target)||e.contains(a.target)||n())}),document.addEventListener("keydown",function(e){"Escape"===e.key&&n()})}(),function(){const e=document.querySelectorAll(".mw-progress-fill");if(!e.length)return;const t=new IntersectionObserver((e,t)=>{e.forEach(e=>{if(!e.isIntersecting)return;const n=e.target,a=n.dataset.value||0;n.style.width=a+"%",t.unobserve(n)})},{root:null,threshold:.2});e.forEach(e=>t.observe(e))}(),document.querySelectorAll('a[href^="#"]').forEach(e=>{e.addEventListener("click",function(e){const t=this.getAttribute("href");if("#"===t)return;if(!document.querySelector(t))return;const 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;window.addEventListener("scroll",function(e,t){let n;return function(){const a=this,c=arguments;clearTimeout(n),n=setTimeout(()=>e.apply(a,c),t)}}(function(){let a="";t.forEach(e=>{const t=e.offsetTop-100,n=e.clientHeight;scrollY>=t&&scrollY<t+n&&(a=e.getAttribute("id"))}),n.forEach(t=>{e(t,!1);const n=t.getAttribute("href");if(n){const c=n.indexOf("#");if(-1!==c){n.substring(c+1)===a&&e(t,!0)}}})},100))}(),document.querySelectorAll(".mw-tabs-nav-item").forEach(t=>{t.addEventListener("click",function(){const t=this.closest(".mw-tabs");if(!t)return;t.querySelectorAll(".mw-tabs-nav-item").forEach(t=>{e(t,!1)}),e(this,!0);const n=this.getAttribute("data-tab");n&&(t.querySelectorAll(".mw-tabs-panel").forEach(t=>{e(t,!1)}),e(document.getElementById(n),!0))})}),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,c=Math.round(e/a*100);t.style.setProperty("--value",c+"%"),n.classList.contains("mw-slider-numeric")?n.setAttribute("data-value",e):n.setAttribute("data-value",c)};t.addEventListener("input",a),a()}),document.querySelectorAll(".mw-modal-close").forEach(e=>{e.addEventListener("click",function(){const e=this.closest(".mw-modal-overlay");e&&e.classList.remove("mw-modal-open")})}),function(){const e=document.getElementById("login-button");e&&e.addEventListener("click",function(){const e=this.querySelector("i");e.classList.contains("fa-lock")?(e.classList.remove("fa-lock"),e.classList.add("fa-lock-open")):(e.classList.remove("fa-lock-open"),e.classList.add("fa-lock"))})}(),document.querySelectorAll(".mw-image-slider").forEach(t=>{const n=t.querySelectorAll(".mw-image-slider-overlay-image"),a=t.querySelectorAll("button[data-index]");if(!n.length||!a.length)return;let c=0;function o(){n.forEach(t=>{e(t,parseInt(t.dataset.index)===c)}),a.forEach(t=>{e(t,parseInt(t.dataset.index)===c)})}function r(e){c=e,o()}a.forEach(e=>{e.addEventListener("click",()=>{r(parseInt(e.dataset.index))})}),o()}),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(n),document.querySelectorAll("[data-calendar]").forEach(a),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()})}()}),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}}))}}();
package/package.json CHANGED
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "name": "maverick-wave",
3
- "version": "4.9.4",
3
+ "version": "4.11.0",
4
4
  "config": {
5
- "version_short": "4.9"
5
+ "version_short": "4.11"
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
@@ -39,8 +39,55 @@
39
39
  initCheckboxLists();
40
40
  initKanbanBoards();
41
41
  initCalendars();
42
+ initDropdowns();
42
43
  });
43
44
 
45
+ // ===== Dropdowns =====
46
+ //
47
+ // The menu is a <details>, so opening, closing, the keyboard and the state a
48
+ // screen reader reads out are all the browser's job already. Two things it
49
+ // does not do, because no markup can express them: close when the click lands
50
+ // somewhere else, and close on Escape.
51
+ //
52
+ // Delegated to the document rather than bound per dropdown, so a menu added
53
+ // to the page later works without being initialised.
54
+ function initDropdowns() {
55
+ function closeAll(except) {
56
+ document.querySelectorAll('.mw-dropdown[open]').forEach((dropdown) => {
57
+ if (dropdown !== except) dropdown.removeAttribute('open');
58
+ });
59
+ }
60
+
61
+ document.addEventListener('click', function (event) {
62
+ const dropdown = event.target.closest('.mw-dropdown');
63
+
64
+ // Only one menu open at a time - opening a second while the first is
65
+ // still up reads as two menus fighting over the same click
66
+ closeAll(dropdown);
67
+
68
+ if (!dropdown) return;
69
+
70
+ // A choice inside the menu closes it. Anything the item does itself -
71
+ // navigating, submitting - still runs; this only takes the menu away.
72
+ if (event.target.closest('.mw-dropdown-item')) {
73
+ dropdown.removeAttribute('open');
74
+ }
75
+ });
76
+
77
+ document.addEventListener('keydown', function (event) {
78
+ if (event.key !== 'Escape') return;
79
+
80
+ const open = document.querySelector('.mw-dropdown[open]');
81
+ if (!open) return;
82
+
83
+ open.removeAttribute('open');
84
+ // Focus goes back to what opened it, or it is left on a menu that is no
85
+ // longer there and the next Tab starts from the top of the page
86
+ const trigger = open.querySelector('summary');
87
+ if (trigger) trigger.focus();
88
+ });
89
+ }
90
+
44
91
  // ===== Checkbox Lists =====
45
92
  function initCheckboxLists() {
46
93
  const checkboxLists = document.querySelectorAll(
@@ -184,8 +231,13 @@
184
231
 
185
232
  if (dotsBox) {
186
233
  for (let i = 0; i < slides.length; i++) {
187
- const dot = document.createElement('span');
234
+ // A button, not a span: the dots are the only way to reach slide four
235
+ // directly, and as a span nothing focuses them and no screen reader
236
+ // says what they are.
237
+ const dot = document.createElement('button');
238
+ dot.type = 'button';
188
239
  dot.className = 'mw-gallery-dot' + (i === 0 ? ' mw-active' : '');
240
+ dot.setAttribute('aria-label', 'Go to slide ' + (i + 1));
189
241
  dot.addEventListener('click', () => goToSlide(i));
190
242
  dotsBox.appendChild(dot);
191
243
  }
@@ -790,12 +842,30 @@
790
842
  refresh();
791
843
  }
792
844
 
845
+ const MOVE_CLASSES = [
846
+ 'mw-kanban-card-moved-forward',
847
+ 'mw-kanban-card-moved-back',
848
+ ];
849
+
793
850
  function moveCard(card, offset) {
794
851
  const current = card.closest('.mw-kanban-column');
795
852
  const target = columns[columns.indexOf(current) + offset];
796
853
  if (!target) return;
797
854
 
798
855
  target.querySelector('.mw-kanban-column-body').appendChild(card);
856
+
857
+ // The card lands in a lane somewhere else on the board, so it says so on
858
+ // arrival and comes in from the side it was pushed from. Re-parenting it
859
+ // alone made it blink into the other column with no motion at all.
860
+ //
861
+ // Both classes come off first and the reflow is forced in between: an
862
+ // element that already carries the class it is being given again keeps
863
+ // the finished animation and plays nothing, so a second push in the same
864
+ // direction would be the silent one.
865
+ card.classList.remove.apply(card.classList, MOVE_CLASSES);
866
+ void card.offsetWidth;
867
+ card.classList.add(offset > 0 ? MOVE_CLASSES[0] : MOVE_CLASSES[1]);
868
+
799
869
  refresh();
800
870
  }
801
871
 
@@ -1,4 +1,9 @@
1
1
  <h3 class="mw-section-subtitle">Accordions</h3>
2
+ <p class="mw-text-muted mw-text-measure mw-mb-6">
3
+ Only as much content open as anyone needs at once. The header is the control
4
+ and the panel follows it in the DOM, which is what lets the whole thing run
5
+ off two state classes and no wrapper element.
6
+ </p>
2
7
 
3
8
  <div class="mw-accordion">
4
9
  <div class="mw-accordion-item">
@@ -1,4 +1,9 @@
1
1
  <h3 class="mw-section-subtitle">Alerts System</h3>
2
+ <p class="mw-text-muted mw-text-measure mw-mb-6">
3
+ A message that belongs to the page it sits on. The colour carries the severity
4
+ and the left rule repeats it, so the meaning survives where the tint does not.
5
+ The same markup inside a <code>mw-toast-stack</code> becomes a toast.
6
+ </p>
2
7
 
3
8
  <div class="mw-grid-2 mw-gap-4">
4
9
  <!-- Primary: System Notifications -->
@@ -1,4 +1,9 @@
1
1
  <h3 class="mw-section-subtitle">Avatars</h3>
2
+ <p class="mw-text-muted mw-text-measure mw-mb-6">
3
+ A picture or a pair of initials, in five sizes. The colour variants sit on the
4
+ border, so they still read over a photo; on an initials avatar they fill the
5
+ circle as well. Inside a group the overlap follows the avatar size.
6
+ </p>
2
7
 
3
8
  <div class="mw-grid-2">
4
9
  <div>
@@ -0,0 +1,114 @@
1
+ <h3 class="mw-section-subtitle">Badges</h3>
2
+
3
+ <p class="mw-text-muted mw-mb-6 mw-text-measure">
4
+ A badge is not a tag. A tag names something and sits in a row of its own kind;
5
+ a badge carries a count or a status and usually sits <em>on</em> something -
6
+ the number on a bell, the dot on an avatar. That is why it fills its colour
7
+ instead of tinting it, and why it comes with an anchor.
8
+ </p>
9
+
10
+ <div class="mw-grid-2 mw-gap-6">
11
+ <div>
12
+ <h3 class="mw-card-title mw-mb-4">Counts</h3>
13
+ <div class="mw-card mw-card-simple mw-grid-1 mw-gap-6">
14
+ <div>
15
+ <h5 class="mw-text-medium mw-mb-2">Colors</h5>
16
+ <div class="mw-d-flex mw-items-center mw-gap-3 mw-flex-wrap">
17
+ <span class="mw-badge">3</span>
18
+ <span class="mw-badge mw-badge-secondary">8</span>
19
+ <span class="mw-badge mw-badge-success">1</span>
20
+ <span class="mw-badge mw-badge-warning">4</span>
21
+ <span class="mw-badge mw-badge-danger">99+</span>
22
+ <span class="mw-badge mw-badge-info">12</span>
23
+ <span class="mw-badge mw-badge-muted">0</span>
24
+ <span class="mw-badge mw-badge-outline">new</span>
25
+ </div>
26
+ </div>
27
+ <div>
28
+ <h5 class="mw-text-medium mw-mb-2">Sizes</h5>
29
+ <div class="mw-d-flex mw-items-center mw-gap-3">
30
+ <span class="mw-badge mw-badge-sm">7</span>
31
+ <span class="mw-badge">7</span>
32
+ <span class="mw-badge mw-badge-lg">7</span>
33
+ </div>
34
+ <p class="mw-text-muted mw-text-sm mw-mt-3 mw-mb-0">
35
+ Round on one character, a pill from two on - a
36
+ <code>min-width</code> the padding grows past, the same rule an OS
37
+ badge follows. The digits are tabular, so a counter ticking 9 to 10
38
+ does not shift what sits beside it.
39
+ </p>
40
+ </div>
41
+ <div>
42
+ <h5 class="mw-text-medium mw-mb-2">Anchored to something</h5>
43
+ <div class="mw-d-flex mw-items-center mw-gap-6">
44
+ <span class="mw-badge-anchor">
45
+ <button class="mw-btn mw-btn-outline">
46
+ <i class="fas fa-inbox"></i> Inbox
47
+ </button>
48
+ <span class="mw-badge mw-badge-danger mw-badge-float">5</span>
49
+ </span>
50
+ <span class="mw-badge-anchor">
51
+ <i class="fas fa-bell mw-text-xl"></i>
52
+ <span class="mw-badge mw-badge-primary mw-badge-float mw-badge-sm"
53
+ >2</span
54
+ >
55
+ </span>
56
+ </div>
57
+ <p class="mw-text-muted mw-text-sm mw-mt-3 mw-mb-0">
58
+ <code>mw-badge-anchor</code> on the thing being badged,
59
+ <code>mw-badge-float</code> on the badge. It hangs off the corner and
60
+ carries a ring in the surface colour, so it reads as a separate object
61
+ rather than a blob on the icon.
62
+ </p>
63
+ </div>
64
+ </div>
65
+ </div>
66
+
67
+ <div>
68
+ <h3 class="mw-card-title mw-mb-4">Status</h3>
69
+ <div class="mw-card mw-card-simple mw-grid-1 mw-gap-6">
70
+ <div>
71
+ <h5 class="mw-text-medium mw-mb-2">Dot with a label</h5>
72
+ <div class="mw-grid-1 mw-gap-3">
73
+ <span class="mw-badge-status mw-badge-status-success">
74
+ <span class="mw-badge-dot"></span> Online
75
+ </span>
76
+ <span class="mw-badge-status mw-badge-status-warning">
77
+ <span class="mw-badge-dot"></span> Degraded
78
+ </span>
79
+ <span class="mw-badge-status mw-badge-status-danger">
80
+ <span class="mw-badge-dot mw-badge-pulse"></span> Incident
81
+ </span>
82
+ <span class="mw-badge-status mw-badge-status-muted">
83
+ <span class="mw-badge-dot"></span> Archived
84
+ </span>
85
+ </div>
86
+ </div>
87
+ <div>
88
+ <h5 class="mw-text-medium mw-mb-2">Live</h5>
89
+ <p class="mw-text-muted mw-text-sm mw-mb-0">
90
+ <code>mw-badge-pulse</code> adds a ring that grows out and fades. The
91
+ dot underneath never moves, so a column of them in a table stays
92
+ readable. For something actually running - a job, an open connection -
93
+ not for decoration.
94
+ </p>
95
+ </div>
96
+ <div>
97
+ <h5 class="mw-text-medium mw-mb-2">In a row</h5>
98
+ <div class="mw-row-split mw-row-split-center">
99
+ <span>Deployment #4812</span>
100
+ <span class="mw-badge-status mw-badge-status-success">
101
+ <span class="mw-badge-dot"></span> Passed
102
+ </span>
103
+ </div>
104
+ <hr class="mw-divider" />
105
+ <div class="mw-row-split mw-row-split-center">
106
+ <span>Deployment #4811</span>
107
+ <span class="mw-badge-status mw-badge-status-danger">
108
+ <span class="mw-badge-dot"></span> Failed
109
+ </span>
110
+ </div>
111
+ </div>
112
+ </div>
113
+ </div>
114
+ </div>
@@ -1,4 +1,9 @@
1
1
  <h3 class="mw-section-subtitle">Blog Posts</h3>
2
+ <p class="mw-text-muted mw-text-measure mw-mb-6">
3
+ A long-form article rather than a card: title, meta line, body and the way
4
+ back out. The gradient rule down the left edge is what makes it read as a page
5
+ instead of a panel.
6
+ </p>
2
7
 
3
8
  <div class="mw-blog-post mw-mt-9">
4
9
  <h2 class="mw-blog-post-title">
@@ -1,5 +1,5 @@
1
1
  <h3 class="mw-section-subtitle">Breadcrumbs</h3>
2
- <p class="mw-text-muted">
2
+ <p class="mw-text-muted mw-text-measure mw-mb-6">
3
3
  Modern skewed navigation breadcrumbs with overlapping design.
4
4
  </p>
5
5
 
@@ -1,4 +1,9 @@
1
1
  <h3 class="mw-section-subtitle">Button Bars</h3>
2
+ <p class="mw-text-muted mw-text-measure mw-mb-6">
3
+ A framed row of actions. Below 576px it stacks and every button takes the full
4
+ width. The colour variants style whatever is inside them, so a bar of five
5
+ buttons needs one class rather than five.
6
+ </p>
2
7
 
3
8
  <div class="mw-grid-stack-stretch">
4
9
  <div>
@@ -1,4 +1,9 @@
1
1
  <h3 class="mw-section-subtitle">Buttons</h3>
2
+ <p class="mw-text-muted mw-text-measure mw-mb-6">
3
+ Three emphasis levels: primary fills, outline draws a line, ghost does neither
4
+ until you point at it. Every variant dips a pixel when pressed - on touch that
5
+ press is the only feedback there is.
6
+ </p>
2
7
 
3
8
  <div class="mw-grid-1">
4
9
  <div>
@@ -31,6 +36,85 @@
31
36
  </div>
32
37
  </div>
33
38
 
39
+ <div>
40
+ <h3 class="mw-mb-4">Ghost, Icon &amp; Block</h3>
41
+ <div class="mw-card mw-card-simple mw-grid-1 mw-gap-6">
42
+ <div>
43
+ <h5 class="mw-text-medium mw-mb-2">Ghost</h5>
44
+ <div class="mw-d-flex mw-flex-wrap mw-items-center mw-gap-3">
45
+ <button type="button" class="mw-btn mw-btn-ghost">Rename</button>
46
+ <button type="button" class="mw-btn mw-btn-ghost mw-active">
47
+ Selected
48
+ </button>
49
+ <button type="button" class="mw-btn mw-btn-ghost mw-btn-ghost-danger">
50
+ Remove
51
+ </button>
52
+ </div>
53
+ <p class="mw-text-muted mw-text-sm mw-mt-3 mw-mb-0">
54
+ The third emphasis level: primary fills, outline draws a line, ghost
55
+ does neither until you point at it. For a toolbar or a card's own
56
+ actions, where five outlined boxes would fight the content under them.
57
+ Not <code>mw-btn-plain</code> - this keeps the shape, the padding and
58
+ the hit area, it just does not paint them at rest.
59
+ </p>
60
+ </div>
61
+ <div>
62
+ <h5 class="mw-text-medium mw-mb-2">Icon only</h5>
63
+ <div class="mw-d-flex mw-flex-wrap mw-items-center mw-gap-3">
64
+ <button
65
+ type="button"
66
+ class="mw-btn mw-btn-ghost mw-btn-icon mw-btn-sm"
67
+ aria-label="Edit"
68
+ data-tooltip="Edit"
69
+ >
70
+ <i class="fas fa-pen"></i>
71
+ </button>
72
+ <button
73
+ type="button"
74
+ class="mw-btn mw-btn-ghost mw-btn-icon"
75
+ aria-label="Duplicate"
76
+ data-tooltip="Duplicate"
77
+ >
78
+ <i class="fas fa-copy"></i>
79
+ </button>
80
+ <button
81
+ type="button"
82
+ class="mw-btn mw-btn-outline mw-btn-icon"
83
+ aria-label="Share"
84
+ data-tooltip="Share"
85
+ >
86
+ <i class="fas fa-share"></i>
87
+ </button>
88
+ <button
89
+ type="button"
90
+ class="mw-btn mw-btn-primary mw-btn-icon mw-btn-lg"
91
+ aria-label="Add"
92
+ data-tooltip="Add"
93
+ >
94
+ <i class="fas fa-plus"></i>
95
+ </button>
96
+ </div>
97
+ <p class="mw-text-muted mw-text-sm mw-mt-3 mw-mb-0">
98
+ <code>mw-btn-icon</code> makes the button square. Without it the
99
+ horizontal padding is the only thing setting the width, so an icon
100
+ button ends up wider than it is tall and a row of them lines up on
101
+ nothing. It always needs an <code>aria-label</code> - there is no text
102
+ to read out.
103
+ </p>
104
+ </div>
105
+ <div>
106
+ <h5 class="mw-text-medium mw-mb-2">Block</h5>
107
+ <button type="button" class="mw-btn mw-btn-primary mw-btn-block">
108
+ Sign in
109
+ </button>
110
+ <p class="mw-text-muted mw-text-sm mw-mt-3 mw-mb-0">
111
+ <code>mw-btn-block</code> takes the full width - the one action on a
112
+ sheet, a sign-in form, a narrow sidebar.
113
+ </p>
114
+ </div>
115
+ </div>
116
+ </div>
117
+
34
118
  <div>
35
119
  <h3 class="mw-mb-4">Button Sizes</h3>
36
120
  <div class="mw-card mw-card-simple">
@@ -1,5 +1,5 @@
1
1
  <h3 class="mw-section-subtitle">Calendar</h3>
2
- <p class="mw-text-muted">
2
+ <p class="mw-text-muted mw-text-measure mw-mb-6">
3
3
  Month, compact and week share every class - a week is seven cells instead of
4
4
  forty-two, <code>mw-calendar-compact</code> drops the dots and a third of the
5
5
  height. The status dots come in as
@@ -1,4 +1,9 @@
1
1
  <h3 class="mw-section-subtitle">Cards</h3>
2
+ <p class="mw-text-muted mw-text-measure mw-mb-6">
3
+ The framework's main container: a surface, padding, an optional image, a
4
+ header and a footer. The add-ons - badge, ribbon, title icon - all take their
5
+ colour from one <code>mw-card-addon-*</code> class on the card itself.
6
+ </p>
2
7
 
3
8
  <h3 class="mw-mb-4">Standard Cards</h3>
4
9
  <div class="mw-grid-3">
@@ -1,4 +1,10 @@
1
1
  <h3 class="mw-section-subtitle">Code</h3>
2
+ <p class="mw-text-muted mw-text-measure mw-mb-6">
3
+ Inline code gets a surface of its own so it reads as a quoted thing; blocks
4
+ get a filename bar and a terminal variant. The syntax colours are a fixed pair
5
+ of themes rather than brand tokens - code is easier to read in the colours an
6
+ editor already uses.
7
+ </p>
2
8
 
3
9
  <div class="mw-grid-2 mw-gap-5">
4
10
  <div>
@@ -2,7 +2,7 @@
2
2
 
3
3
  <!-- the hex code string is getting updated via javascript! -->
4
4
 
5
- <p class="mw-text-muted mw-mb-6">
5
+ <p class="mw-text-muted mw-text-measure mw-mb-6">
6
6
  These thirteen are the only colors you ever set. Everything else - hover
7
7
  tones, translucent backgrounds, borders, muted text, the card and footer
8
8
  surfaces, the ink variant the dark theme needs - is derived from them at
@@ -1,4 +1,8 @@
1
1
  <h3 class="mw-section-subtitle">Coming Soon Banner</h3>
2
+ <p class="mw-text-muted mw-text-measure mw-mb-6">
3
+ A placeholder for a section that is not built yet. Loud on purpose: the whole
4
+ point is that nobody ships it by accident.
5
+ </p>
2
6
 
3
7
  <div class="mw-coming-soon">
4
8
  <i class="mw-coming-soon-icon fas fa-tools"></i>
@@ -1,4 +1,8 @@
1
1
  <h3 class="mw-section-subtitle">Divider</h3>
2
+ <p class="mw-text-muted mw-text-measure mw-mb-6">
3
+ A rule between two things - horizontal or vertical, solid or dashed, in a
4
+ brand colour, or with a label sitting in the middle of it.
5
+ </p>
2
6
 
3
7
  <div class="mw-grid-2 mw-gap-6">
4
8
  <div>