bluedither 1.0.14 → 1.0.15

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,4 +1,4 @@
1
- (()=>{var p=structuredClone(window.__BD_TOKENS__||JSON.parse(document.querySelector('script[type="application/json"][data-bluedither-tokens]')?.textContent||"{}")),N=structuredClone(window.__BD_DEFAULTS__||JSON.parse(document.querySelector('script[type="application/json"][data-bluedither-defaults]')?.textContent||"{}")),j=!!(window.__BD_TOKENS__&&window.__BD_DEFAULTS__)||!!window.__BD_TUNER_SERVER_MODE__,$=["Arial","Arial Black","Bebas Neue Pro","Consolas","Courier New","Georgia","Helvetica","Impact","Lucida Console","Segoe UI","Tahoma","Times New Roman","Trebuchet MS","Verdana","SF Pro Display","SF Mono","Cascadia Code","Menlo","Monaco"],H=["Bebas Neue","Space Mono","Inter","Roboto","Roboto Mono","Roboto Condensed","Open Sans","Montserrat","Lato","Oswald","Raleway","Poppins","Nunito","Playfair Display","Merriweather","Source Sans 3","Source Code Pro","PT Sans","PT Serif","PT Mono","Ubuntu","Ubuntu Mono","Fira Sans","Fira Code","Fira Mono","Work Sans","Noto Sans","Noto Serif","DM Sans","DM Serif Display","DM Mono","IBM Plex Sans","IBM Plex Mono","IBM Plex Serif","JetBrains Mono","Inconsolata","Space Grotesk","Archivo","Archivo Black","Barlow","Barlow Condensed","Lexend","Outfit","Sora","Manrope","Bitter","Crimson Text","Libre Baskerville","Abril Fatface","Anton","Permanent Marker","Righteous","Orbitron","Teko","Rubik","Quicksand","Cabin","Karla","Josefin Sans","Comfortaa","Fredoka","Geologica","Instrument Sans","Instrument Serif"],A=[...new Set([...$,...H])].sort();function v(n,t,e){let i=t.split("."),o=n;for(let d=0;d<i.length-1;d++)o=o[i[d]];o[i[i.length-1]]=e}function E(n,t){return t.split(".").reduce((e,i)=>e?.[i],n)}function k(n,t){document.documentElement.style.setProperty(n,t)}function S(n,t){let e=window.__BD_SHADER__;e&&e.updateParams({[n]:t})}function U(n){let t=p.layout.designWidth,e=n/16,i=n/t*100;return`clamp(${(e*.55).toFixed(4)}rem, ${i.toFixed(4)}vw, ${e.toFixed(4)}rem)`}function R(n){let t="bd-gf-"+n.replace(/\s+/g,"-").toLowerCase();if(document.getElementById(t))return;let e=document.createElement("link");e.id=t,e.rel="stylesheet",e.href=`https://fonts.googleapis.com/css2?family=${encodeURIComponent(n)}:wght@400;700&display=swap`,document.head.appendChild(e)}var x=document.createElement("div");x.id="bd-tuner";var M=document.createElement("button");M.id="bd-tuner-toggle";M.textContent="Tuner";M.onclick=()=>x.classList.remove("collapsed");document.body.appendChild(x);document.body.appendChild(M);x.innerHTML=`
1
+ (()=>{var m=structuredClone(window.__BD_TOKENS__||JSON.parse(document.querySelector('script[type="application/json"][data-bluedither-tokens]')?.textContent||"{}")),A=structuredClone(window.__BD_DEFAULTS__||JSON.parse(document.querySelector('script[type="application/json"][data-bluedither-defaults]')?.textContent||"{}")),O=!!(window.__BD_TOKENS__&&window.__BD_DEFAULTS__)||!!window.__BD_TUNER_SERVER_MODE__,z=["Arial","Arial Black","Bebas Neue Pro","Consolas","Courier New","Georgia","Helvetica","Impact","Lucida Console","Segoe UI","Tahoma","Times New Roman","Trebuchet MS","Verdana","SF Pro Display","SF Mono","Cascadia Code","Menlo","Monaco"],j=["Bebas Neue","Space Mono","Inter","Roboto","Roboto Mono","Roboto Condensed","Open Sans","Montserrat","Lato","Oswald","Raleway","Poppins","Nunito","Playfair Display","Merriweather","Source Sans 3","Source Code Pro","PT Sans","PT Serif","PT Mono","Ubuntu","Ubuntu Mono","Fira Sans","Fira Code","Fira Mono","Work Sans","Noto Sans","Noto Serif","DM Sans","DM Serif Display","DM Mono","IBM Plex Sans","IBM Plex Mono","IBM Plex Serif","JetBrains Mono","Inconsolata","Space Grotesk","Archivo","Archivo Black","Barlow","Barlow Condensed","Lexend","Outfit","Sora","Manrope","Bitter","Crimson Text","Libre Baskerville","Abril Fatface","Anton","Permanent Marker","Righteous","Orbitron","Teko","Rubik","Quicksand","Cabin","Karla","Josefin Sans","Comfortaa","Fredoka","Geologica","Instrument Sans","Instrument Serif"],q=[...new Set([...z,...j])].sort();function v(n,r,e){let i=r.split("."),t=n;for(let d=0;d<i.length-1;d++)t=t[i[d]];t[i[i.length-1]]=e}function L(n,r){return r.split(".").reduce((e,i)=>e?.[i],n)}function k(n,r){document.documentElement.style.setProperty(n,r)}function S(n,r){let e=window.__BD_SHADER__;e&&e.updateParams({[n]:r})}function I(n){let r=m.layout.designWidth,e=n/16,i=n/r*100;return`clamp(${(e*.55).toFixed(4)}rem, ${i.toFixed(4)}vw, ${e.toFixed(4)}rem)`}function $(n){let r="bd-gf-"+n.replace(/\s+/g,"-").toLowerCase();if(document.getElementById(r))return;let e=document.createElement("link");e.id=r,e.rel="stylesheet",e.href=`https://fonts.googleapis.com/css2?family=${encodeURIComponent(n)}:wght@400;700&display=swap`,document.head.appendChild(e)}var x=document.createElement("div");x.id="bd-tuner";var P=document.createElement("button");P.id="bd-tuner-toggle";P.textContent="Tuner";P.onclick=()=>x.classList.remove("collapsed");document.body.appendChild(x);document.body.appendChild(P);x.innerHTML=`
2
2
  <div class="bd-tuner-title">
3
3
  <span>BlueDither Tuner</span>
4
4
  <div style="display:flex;gap:8px;align-items:center;">
@@ -6,37 +6,37 @@
6
6
  <button id="bd-tuner-close" title="Close">&times;</button>
7
7
  </div>
8
8
  </div>
9
- `;x.querySelector("#bd-tuner-close").onclick=()=>x.classList.add("collapsed");x.querySelector("#bd-tuner-reset").onclick=async()=>{confirm("Reset all tokens to defaults?")&&(Object.assign(p,structuredClone(N)),await I(),location.reload())};function T(n){let t=document.createElement("div");return t.className="bd-tuner-section",t.innerHTML=`<div class="bd-tuner-section-label">${n}</div>`,x.appendChild(t),t}function C(n,t,e,i,o){let d=E(p,e)||"#000000",a=document.createElement("div");a.className="bd-tuner-row",a.innerHTML=`
10
- <span class="bd-tuner-label">${t}</span>
9
+ `;x.querySelector("#bd-tuner-close").onclick=()=>x.classList.add("collapsed");x.querySelector("#bd-tuner-reset").onclick=async()=>{confirm("Reset all tokens to defaults?")&&(Object.assign(m,structuredClone(A)),await H(),location.reload())};function E(n){let r=document.createElement("div");return r.className="bd-tuner-section",r.innerHTML=`<div class="bd-tuner-section-label">${n}</div>`,x.appendChild(r),r}function C(n,r,e,i,t){let d=L(m,e)||"#000000",a=document.createElement("div");a.className="bd-tuner-row",a.innerHTML=`
10
+ <span class="bd-tuner-label">${r}</span>
11
11
  <span class="bd-tuner-input"><input type="color" value="${d.substring(0,7)}"></span>
12
12
  <span class="bd-tuner-value">${d.substring(0,7)}</span>
13
- `;let s=a.querySelector("input"),c=a.querySelector(".bd-tuner-value");return s.addEventListener("input",l=>{let m=l.target.value;v(p,e,m),c.textContent=m,i&&k(i,m),o&&o(m)}),n.appendChild(a),{setValue(l){v(p,e,l),s.value=l.substring(0,7),c.textContent=l.substring(0,7),i&&k(i,l)}}}function f(n,t,e,i,o,d,a){let s=E(p,e),c=document.createElement("div");c.className="bd-tuner-row bd-tuner-row-stacked",c.innerHTML=`
13
+ `;let s=a.querySelector("input"),c=a.querySelector(".bd-tuner-value");return s.addEventListener("input",l=>{let b=l.target.value;v(m,e,b),c.textContent=b,i&&k(i,b),t&&t(b)}),n.appendChild(a),{setValue(l){v(m,e,l),s.value=l.substring(0,7),c.textContent=l.substring(0,7),i&&k(i,l)}}}function g(n,r,e,i,t,d,a){let s=L(m,e),c=document.createElement("div");c.className="bd-tuner-row bd-tuner-row-stacked",c.innerHTML=`
14
14
  <div class="bd-tuner-row-top">
15
- <span class="bd-tuner-label">${t}</span>
15
+ <span class="bd-tuner-label">${r}</span>
16
16
  <div class="bd-tuner-px-input-wrap">
17
- <input type="number" class="bd-tuner-px-num" value="${s}" min="${i}" max="${o}" step="${d}">
17
+ <input type="number" class="bd-tuner-px-num" value="${s}" min="${i}" max="${t}" step="${d}">
18
18
  <span class="bd-tuner-unit">px</span>
19
19
  </div>
20
20
  </div>
21
- <input type="range" class="bd-tuner-slider" min="${i}" max="${o}" step="${d}" value="${s}">
22
- `;let l=c.querySelector(".bd-tuner-px-num"),m=c.querySelector(".bd-tuner-slider");function u(r){if(r=Math.max(i,Math.min(o,r)),v(p,e,r),l.value=r,m.value=r,a){let w=U(r);(Array.isArray(a)?a:[a]).forEach(g=>k(g,w))}}l.addEventListener("input",r=>u(parseFloat(r.target.value)||0)),m.addEventListener("input",r=>u(parseFloat(r.target.value))),l.addEventListener("keydown",r=>{if(r.key==="ArrowUp"||r.key==="ArrowDown"){r.preventDefault();let w=r.shiftKey?10:1,g=(r.key==="ArrowUp"?d:-d)*w;u(parseFloat(l.value)+g)}}),n.appendChild(c)}function P(n,t,e,i,o,d,a){let s=E(p,e),c=document.createElement("div");c.className="bd-tuner-row bd-tuner-row-stacked",c.innerHTML=`
21
+ <input type="range" class="bd-tuner-slider" min="${i}" max="${t}" step="${d}" value="${s}">
22
+ `;let l=c.querySelector(".bd-tuner-px-num"),b=c.querySelector(".bd-tuner-slider");function p(o){if(o=Math.max(i,Math.min(t,o)),v(m,e,o),l.value=o,b.value=o,a){let w=I(o);(Array.isArray(a)?a:[a]).forEach(f=>k(f,w))}}l.addEventListener("input",o=>p(parseFloat(o.target.value)||0)),b.addEventListener("input",o=>p(parseFloat(o.target.value))),l.addEventListener("keydown",o=>{if(o.key==="ArrowUp"||o.key==="ArrowDown"){o.preventDefault();let w=o.shiftKey?10:1,f=(o.key==="ArrowUp"?d:-d)*w;p(parseFloat(l.value)+f)}}),n.appendChild(c)}function M(n,r,e,i,t,d,a){let s=L(m,e),c=document.createElement("div");c.className="bd-tuner-row bd-tuner-row-stacked",c.innerHTML=`
23
23
  <div class="bd-tuner-row-top">
24
- <span class="bd-tuner-label">${t}</span>
24
+ <span class="bd-tuner-label">${r}</span>
25
25
  <span class="bd-tuner-value">${s}</span>
26
26
  </div>
27
- <input type="range" class="bd-tuner-slider" min="${i}" max="${o}" step="${d}" value="${s}">
28
- `;let l=c.querySelector(".bd-tuner-slider"),m=c.querySelector(".bd-tuner-value");l.addEventListener("input",u=>{let r=parseFloat(u.target.value);v(p,e,r),m.textContent=r,a&&a(r)}),n.appendChild(c)}function B(n,t,e,i){let o=E(p,e),d=document.createElement("div");d.className="bd-tuner-row",d.innerHTML=`
29
- <span class="bd-tuner-label">${t}</span>
27
+ <input type="range" class="bd-tuner-slider" min="${i}" max="${t}" step="${d}" value="${s}">
28
+ `;let l=c.querySelector(".bd-tuner-slider"),b=c.querySelector(".bd-tuner-value");l.addEventListener("input",p=>{let o=parseFloat(p.target.value);v(m,e,o),b.textContent=o,a&&a(o)}),n.appendChild(c)}function B(n,r,e,i){let t=L(m,e),d=document.createElement("div");d.className="bd-tuner-row",d.innerHTML=`
29
+ <span class="bd-tuner-label">${r}</span>
30
30
  <span class="bd-tuner-input bd-tuner-font-input">
31
- <input type="text" class="bd-tuner-font-search" value="${o}" placeholder="Search fonts...">
31
+ <input type="text" class="bd-tuner-font-search" value="${t}" placeholder="Search fonts...">
32
32
  <div class="bd-tuner-font-dropdown"></div>
33
33
  </span>
34
- `;let a=d.querySelector(".bd-tuner-font-search"),s=d.querySelector(".bd-tuner-font-dropdown"),c=m=>$.some(u=>u.toLowerCase()===m.toLowerCase());function l(m=""){let u=A.filter(r=>r.toLowerCase().includes(m.toLowerCase())).slice(0,20);s.innerHTML=u.map(r=>{let w=c(r)?' <span style="opacity:0.4;font-size:9px">SYSTEM</span>':"";return`<div class="bd-tuner-font-option" data-font="${r}" style="font-family:'${r}',system-ui">${r}${w}</div>`}).join(""),u.filter(r=>!c(r)).forEach(R),s.querySelectorAll(".bd-tuner-font-option").forEach(r=>{r.addEventListener("mousedown",w=>{w.preventDefault();let g=r.dataset.font;a.value=g,v(p,e,g),c(g)||R(g),k(i,`"${g}", system-ui, sans-serif`),s.classList.remove("open")})})}a.addEventListener("focus",()=>{l(a.value),s.classList.add("open")}),a.addEventListener("input",()=>{l(a.value),s.classList.add("open")}),a.addEventListener("blur",()=>{setTimeout(()=>s.classList.remove("open"),150)}),a.addEventListener("keydown",m=>{if(m.key==="Enter"){let u=a.value.trim();u&&(v(p,e,u),c(u)||R(u),k(i,`"${u}", system-ui, sans-serif`),s.classList.remove("open"),a.blur())}}),n.appendChild(d)}function D(n,t,e,i,o){let d=E(p,e),a=document.createElement("div");a.className="bd-tuner-row bd-tuner-row-stacked",a.innerHTML=`
35
- <span class="bd-tuner-label">${t}</span>
34
+ `;let a=d.querySelector(".bd-tuner-font-search"),s=d.querySelector(".bd-tuner-font-dropdown"),c=b=>z.some(p=>p.toLowerCase()===b.toLowerCase());function l(b=""){let p=q.filter(o=>o.toLowerCase().includes(b.toLowerCase())).slice(0,20);s.innerHTML=p.map(o=>{let w=c(o)?' <span style="opacity:0.4;font-size:9px">SYSTEM</span>':"";return`<div class="bd-tuner-font-option" data-font="${o}" style="font-family:'${o}',system-ui">${o}${w}</div>`}).join(""),p.filter(o=>!c(o)).forEach($),s.querySelectorAll(".bd-tuner-font-option").forEach(o=>{o.addEventListener("mousedown",w=>{w.preventDefault();let f=o.dataset.font;a.value=f,v(m,e,f),c(f)||$(f),k(i,`"${f}", system-ui, sans-serif`),s.classList.remove("open")})})}a.addEventListener("focus",()=>{l(a.value),s.classList.add("open")}),a.addEventListener("input",()=>{l(a.value),s.classList.add("open")}),a.addEventListener("blur",()=>{setTimeout(()=>s.classList.remove("open"),150)}),a.addEventListener("keydown",b=>{if(b.key==="Enter"){let p=a.value.trim();p&&(v(m,e,p),c(p)||$(p),k(i,`"${p}", system-ui, sans-serif`),s.classList.remove("open"),a.blur())}}),n.appendChild(d)}function N(n,r,e,i,t){let d=L(m,e),a=document.createElement("div");a.className="bd-tuner-row bd-tuner-row-stacked",a.innerHTML=`
35
+ <span class="bd-tuner-label">${r}</span>
36
36
  <div class="bd-tuner-segmented">
37
37
  ${i.map(s=>`<button class="bd-tuner-seg-btn${s===d?" active":""}" data-val="${s}">${s}</button>`).join("")}
38
38
  </div>
39
- `,a.querySelectorAll(".bd-tuner-seg-btn").forEach(s=>{s.addEventListener("click",()=>{a.querySelectorAll(".bd-tuner-seg-btn").forEach(l=>l.classList.remove("active")),s.classList.add("active");let c=s.dataset.val;v(p,e,c),o&&o(c)})}),n.appendChild(a)}var _=T("Colors");C(_,"Background","colors.background","--bd-color-background");var O;C(_,"Primary","colors.primary","--bd-color-primary",n=>{O.setValue(n),S("colorFront",n)});C(_,"Text","colors.text","--bd-color-text");C(_,"CTA Background","colors.ctaBackground","--bd-color-cta-bg");C(_,"CTA Text","colors.ctaText","--bd-color-cta-text");O=C(_,"Shader Front","colors.shaderFront",null,n=>S("colorFront",n));var y=T("Typography");B(y,"Primary Font","typography.primaryFont","--bd-font-primary");B(y,"Secondary Font","typography.secondaryFont","--bd-font-secondary");f(y,"Headline Size","typography.headline.referencePx",32,300,1,"--bd-headline-size");f(y,"Headline LH","typography.headline.lineHeightPx",24,280,1,"--bd-headline-lh");f(y,"Sub Size","typography.subHeadline.referencePx",10,48,1,"--bd-subheadline-size");f(y,"Sub LH","typography.subHeadline.lineHeightPx",12,80,1,"--bd-subheadline-lh");f(y,"Logo Size","typography.logo.referencePx",12,80,1,"--bd-logo-size");f(y,"Nav Size","typography.navItem.referencePx",10,48,1,"--bd-nav-size");var h=T("Spacing");f(h,"Header Pad X","spacing.headerPaddingX",0,80,1,"--bd-header-px");f(h,"Header Pad Y","spacing.headerPaddingY",0,60,1,"--bd-header-py");f(h,"Hero Pad Top","spacing.heroPaddingTop",0,120,1,"--bd-hero-pt");f(h,"Hero Pad Bottom","spacing.heroPaddingBottom",0,120,1,"--bd-hero-pb");f(h,"Hero Pad X","spacing.heroPaddingX",0,120,1,"--bd-hero-px");f(h,"Nav Gap","spacing.navGap",0,100,1,"--bd-nav-gap");f(h,"CTA Pad X","spacing.ctaPaddingX",0,60,1,"--bd-cta-px");f(h,"CTA Pad Y","spacing.ctaPaddingY",0,30,1,"--bd-cta-py");f(h,"CTA Radius","spacing.ctaBorderRadius",0,32,1,"--bd-cta-radius");var L=T("Shader");D(L,"Shape","shader.shape",["warp","simplex","dots","wave","ripple","swirl","sphere"],n=>S("shape",n));D(L,"Dither Type","shader.type",["random","2x2","4x4","8x8"],n=>S("type",n));P(L,"Speed","shader.speed",0,2,.01,n=>S("speed",n));P(L,"Scale","shader.scale",.1,5,.01,n=>S("scale",n));P(L,"Dither Size","shader.size",.5,10,.1,n=>S("size",n));var q=T("Opacity");P(q,"Nav Links","opacity.navLinks",0,1,.01,n=>k("--bd-nav-opacity",n));var b=document.createElement("button");b.id="bd-tuner-commit";b.textContent="Commit Changes";var F=null;async function I(){let n=JSON.stringify(p,null,2);try{let o=await fetch("/__bluedither/commit",{method:"POST",headers:{"Content-Type":"application/json"},body:n});if(o.ok&&(await o.json()).ok)return"saved"}catch{}try{let o=await fetch("http://localhost:3344/commit",{method:"POST",headers:{"Content-Type":"application/json"},body:n});if(o.ok&&(await o.json()).ok)return"saved"}catch{}if(j)try{let o=await fetch("/commit",{method:"POST",headers:{"Content-Type":"application/json"},body:n});if(o.ok&&(await o.json()).ok)return"saved"}catch{}if(window.showSaveFilePicker)try{F||(F=await window.showSaveFilePicker({suggestedName:"tokens.json",types:[{description:"JSON",accept:{"application/json":[".json"]}}]}));let o=await F.createWritable();return await o.write(n),await o.close(),"saved"}catch(o){if(o.name==="AbortError")return"cancelled";F=null}let t=new Blob([n],{type:"application/json"}),e=URL.createObjectURL(t),i=document.createElement("a");return i.href=e,i.download="tokens.json",i.click(),URL.revokeObjectURL(e),"downloaded"}b.onclick=async()=>{b.textContent="Exporting...",b.disabled=!0;try{if(window.__BD_SERVER_MODE__){let t=await(await fetch("/commit",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(p,null,2)})).json();if(!t.ok)throw new Error(t.error);b.textContent="Committed!"}else{let n=new Blob([JSON.stringify(p,null,2)],{type:"application/json"}),t=URL.createObjectURL(n),e=document.createElement("a");e.href=t,e.download="tokens.json",e.click(),URL.revokeObjectURL(t),b.textContent="Downloaded!"}b.classList.add("success"),setTimeout(()=>{b.textContent=window.__BD_SERVER_MODE__?"Commit Changes":"Export Tokens",b.classList.remove("success"),b.disabled=!1},2e3)}catch(n){b.textContent="Error: "+n.message,b.disabled=!1,setTimeout(()=>{b.textContent=window.__BD_SERVER_MODE__?"Commit Changes":"Export Tokens"},3e3)}};window.__BD_SERVER_MODE__||(b.textContent="Export Tokens");x.appendChild(b);var z=document.createElement("style");z.textContent=`/* =============================================
39
+ `,a.querySelectorAll(".bd-tuner-seg-btn").forEach(s=>{s.addEventListener("click",()=>{a.querySelectorAll(".bd-tuner-seg-btn").forEach(l=>l.classList.remove("active")),s.classList.add("active");let c=s.dataset.val;v(m,e,c),t&&t(c)})}),n.appendChild(a)}var T=E("Colors");C(T,"Background","colors.background","--bd-color-background");var D;C(T,"Primary","colors.primary","--bd-color-primary",n=>{D.setValue(n),S("colorFront",n)});C(T,"Text","colors.text","--bd-color-text");C(T,"CTA Background","colors.ctaBackground","--bd-color-cta-bg");C(T,"CTA Text","colors.ctaText","--bd-color-cta-text");D=C(T,"Shader Front","colors.shaderFront",null,n=>S("colorFront",n));var y=E("Typography");B(y,"Primary Font","typography.primaryFont","--bd-font-primary");B(y,"Secondary Font","typography.secondaryFont","--bd-font-secondary");g(y,"Headline Size","typography.headline.referencePx",32,300,1,"--bd-headline-size");g(y,"Headline LH","typography.headline.lineHeightPx",24,280,1,"--bd-headline-lh");g(y,"Sub Size","typography.subHeadline.referencePx",10,48,1,"--bd-subheadline-size");g(y,"Sub LH","typography.subHeadline.lineHeightPx",12,80,1,"--bd-subheadline-lh");g(y,"Logo Size","typography.logo.referencePx",12,80,1,"--bd-logo-size");g(y,"Nav Size","typography.navItem.referencePx",10,48,1,"--bd-nav-size");var h=E("Spacing");g(h,"Header Pad X","spacing.headerPaddingX",0,80,1,"--bd-header-px");g(h,"Header Pad Y","spacing.headerPaddingY",0,60,1,"--bd-header-py");g(h,"Hero Pad Top","spacing.heroPaddingTop",0,120,1,"--bd-hero-pt");g(h,"Hero Pad Bottom","spacing.heroPaddingBottom",0,120,1,"--bd-hero-pb");g(h,"Hero Pad X","spacing.heroPaddingX",0,120,1,"--bd-hero-px");g(h,"Nav Gap","spacing.navGap",0,100,1,"--bd-nav-gap");g(h,"CTA Pad X","spacing.ctaPaddingX",0,60,1,"--bd-cta-px");g(h,"CTA Pad Y","spacing.ctaPaddingY",0,30,1,"--bd-cta-py");g(h,"CTA Radius","spacing.ctaBorderRadius",0,32,1,"--bd-cta-radius");var F=E("Shader");N(F,"Shape","shader.shape",["warp","simplex","dots","wave","ripple","swirl","sphere"],n=>S("shape",n));N(F,"Dither Type","shader.type",["random","2x2","4x4","8x8"],n=>S("type",n));M(F,"Speed","shader.speed",0,2,.01,n=>S("speed",n));M(F,"Scale","shader.scale",.1,5,.01,n=>S("scale",n));M(F,"Dither Size","shader.size",.5,10,.1,n=>S("size",n));var U=E("Opacity");M(U,"Nav Links","opacity.navLinks",0,1,.01,n=>k("--bd-nav-opacity",n));var u=document.createElement("button");u.id="bd-tuner-commit";u.textContent="Commit Changes";var _=null;async function H(){let n=JSON.stringify(m,null,2);try{let t=await fetch("/__bluedither/commit",{method:"POST",headers:{"Content-Type":"application/json"},body:n});if(t.ok&&(await t.json()).ok)return"saved"}catch{}try{let t=await fetch("http://localhost:3344/commit",{method:"POST",headers:{"Content-Type":"application/json"},body:n});if(t.ok&&(await t.json()).ok)return"saved"}catch{}if(O)try{let t=await fetch("/commit",{method:"POST",headers:{"Content-Type":"application/json"},body:n});if(t.ok&&(await t.json()).ok)return"saved"}catch{}if(window.showSaveFilePicker)try{_||(_=await window.showSaveFilePicker({suggestedName:"tokens.json",types:[{description:"JSON",accept:{"application/json":[".json"]}}]}));let t=await _.createWritable();return await t.write(n),await t.close(),"saved"}catch(t){if(t.name==="AbortError")return"cancelled";_=null}let r=new Blob([n],{type:"application/json"}),e=URL.createObjectURL(r),i=document.createElement("a");return i.href=e,i.download="tokens.json",i.click(),URL.revokeObjectURL(e),"downloaded"}u.onclick=async()=>{u.textContent="Saving...",u.disabled=!0;try{let n=await H();if(n==="cancelled"){u.textContent="Commit Changes",u.disabled=!1;return}u.textContent=n==="saved"?"Saved!":"Downloaded!",u.classList.add("success"),setTimeout(()=>{u.textContent="Commit Changes",u.classList.remove("success"),u.disabled=!1},2e3)}catch(n){u.textContent="Error: "+n.message,u.disabled=!1,setTimeout(()=>{u.textContent="Commit Changes"},3e3)}};x.appendChild(u);var R=document.createElement("style");R.textContent=`/* =============================================
40
40
  BlueDither Fine-Tuner \u2014 Overlay Panel v2
41
41
  ============================================= */
42
42
 
@@ -398,4 +398,4 @@
398
398
  background: rgba(255, 255, 255, 0.1);
399
399
  border-radius: 2px;
400
400
  }
401
- `;document.head.appendChild(z);})();
401
+ `;document.head.appendChild(R);})();
@@ -81,8 +81,40 @@ export function bluedither() {
81
81
  return {
82
82
  name: 'bluedither-tuner',
83
83
  configureServer(server) {
84
- server.middlewares.use((req, res, next) => {
85
- if (!handleRequest(req, res)) next();
84
+ server.middlewares.use(ENDPOINT, (req, res, next) => {
85
+ if (req.method === 'OPTIONS') {
86
+ res.writeHead(204, {
87
+ 'Access-Control-Allow-Origin': '*',
88
+ 'Access-Control-Allow-Methods': 'POST, OPTIONS',
89
+ 'Access-Control-Allow-Headers': 'Content-Type',
90
+ });
91
+ res.end();
92
+ return;
93
+ }
94
+ if (req.method === 'POST') {
95
+ let body = '';
96
+ req.on('data', chunk => { body += chunk; });
97
+ req.on('end', () => {
98
+ try {
99
+ JSON.parse(body);
100
+ const tokensPath = findTokensPath();
101
+ writeFileSync(tokensPath, body);
102
+ res.writeHead(200, {
103
+ 'Content-Type': 'application/json',
104
+ 'Access-Control-Allow-Origin': '*',
105
+ });
106
+ res.end('{"ok":true}');
107
+ } catch (e) {
108
+ res.writeHead(500, {
109
+ 'Content-Type': 'application/json',
110
+ 'Access-Control-Allow-Origin': '*',
111
+ });
112
+ res.end(JSON.stringify({ error: e.message }));
113
+ }
114
+ });
115
+ return;
116
+ }
117
+ next();
86
118
  });
87
119
  },
88
120
  };
@@ -99,12 +131,9 @@ export function blueditherMiddleware() {
99
131
  };
100
132
  }
101
133
 
102
- /**
103
- * Raw handler for custom Node http servers:
104
- * import { blueditherHandler } from './bluedither/dev-middleware.js'
105
- * // In your request handler:
106
- * if (!blueditherHandler(req, res)) { /* your normal handling */ }
107
- */
134
+ // Raw handler for custom Node http servers:
135
+ // import { blueditherHandler } from './bluedither/dev-middleware.js'
136
+ // if (!blueditherHandler(req, res)) { yourNormalHandling() }
108
137
  export { handleRequest as blueditherHandler };
109
138
 
110
139
  export default bluedither;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bluedither",
3
- "version": "1.0.14",
3
+ "version": "1.0.15",
4
4
  "description": "A bold, dithered-shader hero theme for Claude Code — skill + fine-tuner",
5
5
  "type": "module",
6
6
  "bin": {