bluedither 1.0.14 → 1.0.16
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/dist/bluedither-tuner.js +17 -17
- package/fine-tuner/dev-middleware.js +37 -8
- package/fine-tuner/inject.js +95 -6
- package/package.json +1 -1
package/dist/bluedither-tuner.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
(()=>{var
|
|
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">×</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(
|
|
10
|
-
<span class="bd-tuner-label">${
|
|
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
|
|
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">${
|
|
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="${
|
|
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="${
|
|
22
|
-
`;let l=c.querySelector(".bd-tuner-px-num"),
|
|
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">${
|
|
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="${
|
|
28
|
-
`;let l=c.querySelector(".bd-tuner-slider"),
|
|
29
|
-
<span class="bd-tuner-label">${
|
|
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="${
|
|
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=
|
|
35
|
-
<span class="bd-tuner-label">${
|
|
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(
|
|
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(
|
|
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 (
|
|
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
|
-
|
|
104
|
-
|
|
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/fine-tuner/inject.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* BlueDither Tuner — Injectable Loader
|
|
3
3
|
*
|
|
4
4
|
* Drop this script into ANY page to get the tuner overlay.
|
|
5
|
-
*
|
|
5
|
+
* On load: reads tokens.json, applies CSS vars + shader params (so saved changes persist).
|
|
6
6
|
* "Commit Changes" saves via dev middleware → sidecar → File System API → download.
|
|
7
7
|
*
|
|
8
8
|
* Usage:
|
|
@@ -31,11 +31,102 @@
|
|
|
31
31
|
defaults = structuredClone(tokens);
|
|
32
32
|
}
|
|
33
33
|
|
|
34
|
+
// ── Apply saved tokens to the page ──
|
|
35
|
+
// This makes "Commit Changes" persist across page reloads.
|
|
36
|
+
const root = document.documentElement;
|
|
37
|
+
const t = tokens;
|
|
38
|
+
|
|
39
|
+
function pxToClamp(px) {
|
|
40
|
+
const dw = t.layout?.designWidth || 1364;
|
|
41
|
+
const maxRem = px / 16;
|
|
42
|
+
const vw = (px / dw) * 100;
|
|
43
|
+
const minRem = maxRem * 0.55;
|
|
44
|
+
return `clamp(${minRem.toFixed(4)}rem, ${vw.toFixed(4)}vw, ${maxRem.toFixed(4)}rem)`;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// Colors
|
|
48
|
+
if (t.colors) {
|
|
49
|
+
if (t.colors.background) root.style.setProperty('--bd-bg', t.colors.background);
|
|
50
|
+
if (t.colors.primary) root.style.setProperty('--bd-primary', t.colors.primary);
|
|
51
|
+
if (t.colors.text) root.style.setProperty('--bd-text', t.colors.text);
|
|
52
|
+
if (t.colors.ctaBackground) root.style.setProperty('--bd-cta-bg', t.colors.ctaBackground);
|
|
53
|
+
if (t.colors.ctaText) root.style.setProperty('--bd-cta-text', t.colors.ctaText);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// Typography
|
|
57
|
+
if (t.typography) {
|
|
58
|
+
if (t.typography.primaryFont) root.style.setProperty('--bd-font-primary', t.typography.primaryFont);
|
|
59
|
+
if (t.typography.secondaryFont) root.style.setProperty('--bd-font-secondary', t.typography.secondaryFont);
|
|
60
|
+
if (t.typography.headline) {
|
|
61
|
+
root.style.setProperty('--bd-headline-size', pxToClamp(t.typography.headline.referencePx));
|
|
62
|
+
root.style.setProperty('--bd-headline-lh', pxToClamp(t.typography.headline.lineHeightPx));
|
|
63
|
+
}
|
|
64
|
+
if (t.typography.subHeadline) {
|
|
65
|
+
root.style.setProperty('--bd-sub-size', pxToClamp(t.typography.subHeadline.referencePx));
|
|
66
|
+
root.style.setProperty('--bd-sub-lh', pxToClamp(t.typography.subHeadline.lineHeightPx));
|
|
67
|
+
}
|
|
68
|
+
if (t.typography.logo) {
|
|
69
|
+
root.style.setProperty('--bd-logo-size', pxToClamp(t.typography.logo.referencePx));
|
|
70
|
+
root.style.setProperty('--bd-logo-lh', pxToClamp(t.typography.logo.lineHeightPx));
|
|
71
|
+
}
|
|
72
|
+
if (t.typography.navItem) {
|
|
73
|
+
root.style.setProperty('--bd-nav-size', pxToClamp(t.typography.navItem.referencePx));
|
|
74
|
+
root.style.setProperty('--bd-nav-lh', pxToClamp(t.typography.navItem.lineHeightPx));
|
|
75
|
+
}
|
|
76
|
+
if (t.typography.ctaButton) {
|
|
77
|
+
root.style.setProperty('--bd-cta-size', pxToClamp(t.typography.ctaButton.referencePx));
|
|
78
|
+
root.style.setProperty('--bd-cta-lh', pxToClamp(t.typography.ctaButton.lineHeightPx));
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// Spacing
|
|
83
|
+
if (t.spacing) {
|
|
84
|
+
if (t.spacing.headerPaddingX) root.style.setProperty('--bd-header-px', pxToClamp(t.spacing.headerPaddingX));
|
|
85
|
+
if (t.spacing.headerPaddingY) root.style.setProperty('--bd-header-py', pxToClamp(t.spacing.headerPaddingY));
|
|
86
|
+
if (t.spacing.heroPaddingTop) root.style.setProperty('--bd-hero-pt', pxToClamp(t.spacing.heroPaddingTop));
|
|
87
|
+
if (t.spacing.heroPaddingBottom) root.style.setProperty('--bd-hero-pb', pxToClamp(t.spacing.heroPaddingBottom));
|
|
88
|
+
if (t.spacing.heroPaddingX) root.style.setProperty('--bd-hero-px', pxToClamp(t.spacing.heroPaddingX));
|
|
89
|
+
if (t.spacing.navGap) root.style.setProperty('--bd-nav-gap', pxToClamp(t.spacing.navGap));
|
|
90
|
+
if (t.spacing.ctaPaddingX) root.style.setProperty('--bd-cta-px', pxToClamp(t.spacing.ctaPaddingX));
|
|
91
|
+
if (t.spacing.ctaPaddingY) root.style.setProperty('--bd-cta-py', pxToClamp(t.spacing.ctaPaddingY));
|
|
92
|
+
if (t.spacing.ctaBorderRadius != null) root.style.setProperty('--bd-cta-radius', `${(t.spacing.ctaBorderRadius / 16).toFixed(4)}rem`);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
// Opacity
|
|
96
|
+
if (t.opacity) {
|
|
97
|
+
if (t.opacity.navLinks != null) root.style.setProperty('--bd-nav-opacity', t.opacity.navLinks);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
// Shader — wait for __BD_SHADER__ to be available, then update
|
|
101
|
+
if (t.shader || t.colors) {
|
|
102
|
+
const applyShader = () => {
|
|
103
|
+
const shader = window.__BD_SHADER__;
|
|
104
|
+
if (!shader) return false;
|
|
105
|
+
const params = {};
|
|
106
|
+
if (t.colors?.shaderFront) params.colorFront = t.colors.shaderFront;
|
|
107
|
+
if (t.colors?.shaderBack) params.colorBack = t.colors.shaderBack;
|
|
108
|
+
if (t.shader?.shape) params.shape = t.shader.shape;
|
|
109
|
+
if (t.shader?.type) params.type = t.shader.type;
|
|
110
|
+
if (t.shader?.speed != null) params.speed = t.shader.speed;
|
|
111
|
+
if (t.shader?.scale != null) params.scale = t.shader.scale;
|
|
112
|
+
if (t.shader?.size != null) params.size = t.shader.size;
|
|
113
|
+
if (t.shader?.rotation != null) params.rotation = t.shader.rotation;
|
|
114
|
+
shader.updateParams(params);
|
|
115
|
+
return true;
|
|
116
|
+
};
|
|
117
|
+
|
|
118
|
+
// Try immediately, then poll briefly (shader may init after this script)
|
|
119
|
+
if (!applyShader()) {
|
|
120
|
+
let attempts = 0;
|
|
121
|
+
const interval = setInterval(() => {
|
|
122
|
+
if (applyShader() || ++attempts > 20) clearInterval(interval);
|
|
123
|
+
}, 100);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
34
127
|
// Inject into globals for the tuner
|
|
35
128
|
window.__BD_TOKENS__ = tokens;
|
|
36
129
|
window.__BD_DEFAULTS__ = defaults;
|
|
37
|
-
|
|
38
|
-
// Signal that we're in injectable mode (tuner will use commitTokens cascade)
|
|
39
130
|
window.__BD_TUNER_SERVER_MODE__ = true;
|
|
40
131
|
|
|
41
132
|
// Load tuner CSS
|
|
@@ -47,9 +138,7 @@
|
|
|
47
138
|
style.textContent = css;
|
|
48
139
|
document.head.appendChild(style);
|
|
49
140
|
}
|
|
50
|
-
} catch {
|
|
51
|
-
// CSS will be inlined in the bundled version
|
|
52
|
-
}
|
|
141
|
+
} catch {}
|
|
53
142
|
|
|
54
143
|
// Load and execute tuner script
|
|
55
144
|
const tunerScript = document.createElement('script');
|