From 6a4e54414c618e3a6b866d9519d6d8b4bf6e60eb Mon Sep 17 00:00:00 2001 From: Claude Date: Sun, 31 May 2026 20:44:19 +0000 Subject: [PATCH 1/3] fix: correct CSS bundle descriptions to match actual bundle contents MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Essential includes all core/ modules (tokens, reset, layout, states, motion, etc.) — not just reset + tokens. Optimal adds color palette, forms, and legacy support. Full adds components and utilities on top. Updated both the WP settings page (class-admin.php) and the Bricks admin SPA (BundleTab.svelte) + rebuilt assets. https://claude.ai/code/session_01DU3r3kT7GqH7w7jeadV2DT --- plugins/SLASHED-for-WP/includes/class-admin.php | 6 +++--- .../bricks/admin-app/src/components/BundleTab.svelte | 6 +++--- .../integrations/bricks/assets/admin-app/app.js | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/plugins/SLASHED-for-WP/includes/class-admin.php b/plugins/SLASHED-for-WP/includes/class-admin.php index fd4bcaec..3b8aec1c 100644 --- a/plugins/SLASHED-for-WP/includes/class-admin.php +++ b/plugins/SLASHED-for-WP/includes/class-admin.php @@ -104,9 +104,9 @@ public function render_page() { __( 'Essential — reset + design tokens only', 'slashed' ), - 'optimal' => __( 'Optimal — + layout, typography, states, forms (recommended)', 'slashed' ), - 'full' => __( 'Full — + utilities layer', 'slashed' ), + 'essential' => __( 'Essential — core layer only: tokens, reset, layout, states, motion', 'slashed' ), + 'optimal' => __( 'Optimal — + color palette, forms, legacy support (recommended)', 'slashed' ), + 'full' => __( 'Full — + components + utilities', 'slashed' ), ); foreach ( $bundles as $value => $label ) : ?> diff --git a/plugins/SLASHED-for-WP/integrations/bricks/admin-app/src/components/BundleTab.svelte b/plugins/SLASHED-for-WP/integrations/bricks/admin-app/src/components/BundleTab.svelte index 4d9f1135..de9148bb 100644 --- a/plugins/SLASHED-for-WP/integrations/bricks/admin-app/src/components/BundleTab.svelte +++ b/plugins/SLASHED-for-WP/integrations/bricks/admin-app/src/components/BundleTab.svelte @@ -48,9 +48,9 @@

Choose which SLASHED CSS bundle to load on the frontend and in builder canvases. diff --git a/plugins/SLASHED-for-WP/integrations/bricks/assets/admin-app/app.js b/plugins/SLASHED-for-WP/integrations/bricks/assets/admin-app/app.js index 0d81e3eb..c6e03924 100644 --- a/plugins/SLASHED-for-WP/integrations/bricks/assets/admin-app/app.js +++ b/plugins/SLASHED-for-WP/integrations/bricks/assets/admin-app/app.js @@ -8,7 +8,7 @@ var Rn=Object.defineProperty;var pr=e=>{throw TypeError(e)};var Mn=(e,t,s)=>t in grouped by category.

`);function Vo(e,t){je(t,!0);const s=ve.inventory?.variables??[],a={color:"Colors",text:"Typography",font:"Typography",leading:"Typography",tracking:"Typography",body:"Typography",heading:"Typography",h1:"Typography",h2:"Typography",h3:"Typography",h4:"Typography",h5:"Typography",h6:"Typography",prose:"Typography",code:"Typography",optical:"Typography",line:"Typography",space:"Spacing",gap:"Spacing",gutter:"Spacing",component:"Spacing",section:"Spacing",flow:"Spacing",safe:"Spacing",header:"Spacing",sticky:"Spacing",size:"Sizing",aspect:"Sizing",ratio:"Sizing",touch:"Sizing",container:"Layout",stack:"Layout",cluster:"Layout",sidebar:"Layout",switcher:"Layout",grid:"Layout",cover:"Layout",frame:"Layout",reel:"Layout",imposter:"Layout",bento:"Layout",box:"Layout",center:"Layout",content:"Layout",breakout:"Layout",divider:"Layout",field:"Layout",border:"Borders",stroke:"Borders",radius:"Radius",shadow:"Shadows",blur:"Effects",opacity:"Effects",gradient:"Effects",mask:"Effects",perspective:"Effects",drop:"Effects",contrast:"Effects",duration:"Motion",ease:"Motion",transition:"Motion",motion:"Motion",animation:"Motion",icon:"Icons",z:"Z-Index",is:"States",current:"States",focus:"Focus",caret:"Focus",scroll:"Scroll",scrollbar:"Scroll",print:"Print",truncate:"Misc"},n=["Colors","Typography","Spacing","Sizing","Layout","Borders","Radius","Shadows","Effects","Motion","Icons","Z-Index","States","Focus","Scroll","Print","Misc"];function i(b){let x=b;x.startsWith("--sf-")&&(x=x.slice(5));const h=x.indexOf("-"),y=h===-1?x:x.slice(0,h);return a[y]||"Misc"}function l(b){const x={};for(const y of b){const S=i(y);x[S]||(x[S]=[]),x[S].push(y)}const h=[];for(const y of n)x[y]?.length&&(x[y].sort(),h.push({category:y,items:x[y]}));for(const y of Object.keys(x))!n.includes(y)&&x[y]?.length&&(x[y].sort(),h.push({category:y,items:x[y]}));return h}const d=l(s);let o=Ke({});function v(b){o[b]=!o[b]}var _=Mo(),p=c(_),f=c(p),m=u(p,4);fe(m,17,()=>d,({category:b,items:x})=>b,(b,x)=>{let h=()=>r(x).category,y=()=>r(x).items;var S=Ro(),A=c(S),F=c(A),H=c(F),j=u(F,2),z=c(j),L=u(j,2),T=c(L),M=u(A,2);{var P=q=>{var $=Fo();fe($,20,y,k=>k,(k,R)=>{var U=zo(),Q=c(U),K=c(Q);I(()=>V(K,R)),E(k,U)}),E(q,$)};me(M,q=>{o[h()]&&q(P)})}I(()=>{ee(A,"aria-expanded",o[h()]?"true":"false"),V(H,o[h()]?"▼":"▶"),V(z,h()),V(T,`(${y().length??""})`)}),ge("click",A,()=>v(h())),E(b,S)}),I(()=>V(f,`CSS Variables (${s.length??""})`)),E(e,_),Te()}Be(["click"]);var Do=C('
  • '),Lo=C(''),Po=C('
  • '),Oo=C(''),Io=C('

    All utility and state classes declared in the active SLASHED bundle.

    ');function qo(e,t){je(t,!0);const s=ve.inventory?.sf_classes??[],a=ve.inventory?.is_classes??[];let n=ue(!1),i=ue(!1);var l=Io(),d=c(l),o=c(d),v=u(d,4),_=c(v),p=c(_),f=c(p),m=u(p,4),b=c(m),x=u(_,2);{var h=T=>{var M=Lo();fe(M,20,()=>s,P=>P,(P,q)=>{var $=Do(),k=c($),R=c(k);I(()=>V(R,`.${q??""}`)),E(P,$)}),E(T,M)};me(x,T=>{r(n)&&T(h)})}var y=u(v,2),S=c(y),A=c(S),F=c(A),H=u(A,4),j=c(H),z=u(S,2);{var L=T=>{var M=Oo();fe(M,20,()=>a,P=>P,(P,q)=>{var $=Po(),k=c($),R=c(k);I(()=>V(R,`.${q??""}`)),E(P,$)}),E(T,M)};me(z,T=>{r(i)&&T(L)})}I(()=>{V(o,`Registered Classes (${s.length+a.length})`),ee(_,"aria-expanded",r(n)?"true":"false"),V(f,r(n)?"▼":"▶"),V(b,`(${s.length??""})`),ee(S,"aria-expanded",r(i)?"true":"false"),V(F,r(i)?"▼":"▶"),V(j,`(${a.length??""})`)}),ge("click",_,()=>X(n,!r(n))),ge("click",S,()=>X(i,!r(i))),E(e,l),Te()}Be(["click"]);async function ja(e,t){const{url:s,nonce:a}=ve.rest;if(!s)return console.info("[slashed-admin] (dev) would POST",e,t),{ok:!0,dev:!0};const n=await fetch(s+e,{method:"POST",credentials:"same-origin",headers:{"Content-Type":"application/json","X-WP-Nonce":a},body:JSON.stringify(t)});if(!n.ok){const i=await n.text();throw new Error(i||`HTTP ${n.status}`)}return n.json()}function zr(e,t){return ja("/tokens",{section:e,values:t})}function Fr(e){return ja("/tokens/reset",{section:e})}function Ko(e){return ja("/settings",e)}async function Bo(){const{url:e,nonce:t}=ve.rest;if(!e)return console.info("[slashed-admin] (dev) would GET /tokens/export"),{schema_version:"1",tokens:{},plugin_settings:{},dev:!0};const s=await fetch(e+"/tokens/export",{credentials:"same-origin",headers:{"X-WP-Nonce":t}});if(!s.ok)throw new Error(await s.text()||`HTTP ${s.status}`);return s.json()}function No(e){return ja("/tokens/import",e)}var Ho=C(`

    When enabled, hovering a SLASHED class in the Bricks class manager shows a short description of what it does. Powered by data/classes-hints.json.

    `),Uo=C('
    Show class hints in Bricks editor Bricks

    Enable the Bricks integration in SLASHED Settings to use this feature.

    '),Go=C('Saved'),Wo=C(' '),Xo=C(`

    Bundle Info

    The SLASHED CSS bundle is loaded automatically on the frontend and in the block editor canvas. The inventory is parsed from whichever bundle is active and drives the variable pickers, - class autocomplete, and color palette in any active builder integration.

    Variables registered
    Classes registered

    Plugin Settings

    Choose which SLASHED CSS bundle to load on the frontend and in builder canvases.

    Override the HTML root font-size. Use this when your theme or builder forces a root font-size + class autocomplete, and color palette in any active builder integration.

    Variables registered
    Classes registered

    Plugin Settings

    Choose which SLASHED CSS bundle to load on the frontend and in builder canvases.

    Override the HTML root font-size. Use this when your theme or builder forces a root font-size that conflicts with rem-based framework values.

    `);function Yo(e,t){je(t,!0);let s=ue(Ke(ve.pluginSettings?.css_bundle??"optimal")),a=ue(Ke(ve.pluginSettings?.html_font_size??"")),n=ue(Ke(ve.pluginSettings?.show_class_hints??!1)),i=ue(!1),l=ue(!1),d=ue(""),o=null;const v=w(()=>ve.activeIntegrations?.bricks??!0);async function _(){X(i,!0),X(l,!1),X(d,"");try{await Ko({css_bundle:r(s),html_font_size:r(a),show_class_hints:r(n)}),X(l,!0),o&&clearTimeout(o),o=setTimeout(()=>{X(l,!1),o=null},3e3)}catch(N){X(d,N.message||"Save failed",!0)}finally{X(i,!1)}}var p=Xo(),f=u(c(p),4),m=u(c(f),2),b=c(m),x=u(m,4),h=c(x),y=u(f,4),S=u(c(y),2),A=c(S);A.value=A.__value="essential";var F=u(A);F.value=F.__value="optimal";var H=u(F);H.value=H.__value="full";var j=u(y,2),z=u(c(j),2),L=c(z);L.value=L.__value="";var T=u(L);T.value=T.__value="100";var M=u(T);M.value=M.__value="62.5";var P=u(j,2);{var q=N=>{var ae=Ho(),re=c(ae),ne=c(re);_l(ne,()=>r(n),le=>X(n,le)),E(N,ae)},$=N=>{var ae=Uo();E(N,ae)};me(P,N=>{r(v)?N(q):N($,-1)})}var k=u(P,2),R=c(k),U=c(R),Q=u(R,2);{var K=N=>{var ae=Go();E(N,ae)};me(Q,N=>{r(l)&&N(K)})}var B=u(Q,2);{var O=N=>{var ae=Wo(),re=c(ae);I(()=>V(re,r(d))),E(N,ae)};me(B,N=>{r(d)&&N(O)})}I(()=>{V(b,ve.inventory?.variables?.length??0),V(h,(ve.inventory?.sf_classes?.length??0)+(ve.inventory?.is_classes?.length??0)),R.disabled=r(i),V(U,r(i)?"Saving...":"Save Settings")}),ba(S,()=>r(s),N=>X(s,N)),ba(z,()=>r(a),N=>X(a,N)),ge("click",R,_),E(e,p),Te()}Be(["click"]);const Rr=22.5,Zo=95;function zn(e,t){if(e<=0||t<=0)return null;const s=Zo-Rr,a=(t-e)/s,n=parseFloat(a.toFixed(6)),i=parseFloat(e.toFixed(4)),l=parseFloat(t.toFixed(4));return`clamp(${i}rem, calc(${n} * (100vw - ${Rr}rem) + ${i}rem), ${l}rem)`}function Mr(e){const t=parseFloat(e);if(isNaN(t))return"0";let s=t.toFixed(6).replace(/0+$/,"").replace(/\.$/,"");return s===""?"0":s}function Me(e){return e!=null&&e!==""}function Jo(e){const t=[],s=["primary","secondary","tertiary","action","neutral","base"];for(const i of s){const l=`brand_${i}`;Me(e[l])&&t.push(`--sf-color-${i}-light: ${e[l]};`)}const a=["success","warning","error","info","danger"];for(const i of a){const l=`status_${i}`;Me(e[l])&&t.push(`--sf-color-${i}-light: ${e[l]};`)}if(e.dark_overrides_enabled!=="0"){for(const i of s){const l=`brand_dark_${i}`;Me(e[l])&&t.push(`--sf-color-${i}-dark: ${e[l]};`)}for(const i of a){const l=`status_dark_${i}`;Me(e[l])&&t.push(`--sf-color-${i}-dark: ${e[l]};`)}}return t}function Qo(e){const t=[],s=["body","heading","mono","display","humanist","geometric","slab"];for(const n of s){const i=`font_${n}`;Me(e[i])&&t.push(`--sf-font-${n}: ${e[i]};`)}Me(e.text_scale)&&t.push(`--sf-text-scale: ${e.text_scale};`),Me(e.text_display_scale)&&t.push(`--sf-text-display-scale: ${e.text_display_scale};`);const a=["2xs","xs","s","m","l","xl","2xl","3xl","4xl","display-s","display-m","display-l"];for(const n of a){const i=`size_${n}_min`,l=`size_${n}_max`,d=e[i],o=e[l];if(Me(d)&&Me(o)){const v=zn(parseFloat(d),parseFloat(o));v&&t.push(`--sf-text-${n}: ${v};`)}}return t}function ec(e){const t=[];Me(e.space_scale)&&t.push(`--sf-space-scale: ${e.space_scale};`);const s=["2xs","xs","s","m","l","xl","2xl","3xl","4xl"];for(const n of s){const i=e[`space_${n}_min`],l=e[`space_${n}_max`];if(Me(i)&&Me(l)){const d=zn(parseFloat(i),parseFloat(l));d&&t.push(`--sf-space-${n}: calc(${d} * var(--sf-space-scale));`)}}const a={gutter:"--sf-space-gutter",gap:"--sf-gap",content_gap:"--sf-content-gap",component_pad:"--sf-component-pad",section_pad:"--sf-section-pad"};for(const[n,i]of Object.entries(a))Me(e[n])&&t.push(`${i}: ${e[n]};`);return t}function tc(e){const t=[];return Me(e.radius_scale)&&t.push(`--sf-radius-scale: ${e.radius_scale};`),t}function sc(e){const t=[];return Me(e.shadow_strength)&&t.push(`--sf-shadow-strength: calc(${e.shadow_strength} + var(--sf-is-dark) * 0.17);`),Me(e.glow_color)&&t.push(`--sf-shadow-glow-color: ${e.glow_color};`),t}function ac(e){const t=[];Me(e.motion_scale)&&t.push(`--sf-motion-scale: ${e.motion_scale};`);const s=["instant","fast","normal","slow","slower"];for(const a of s){const n=`duration_${a}`;Me(e[n])&&t.push(`--sf-duration-${a}: calc(${e[n]}ms * var(--sf-motion-scale));`)}return t}function rc(e){const t=[],s=["below","base","raised","low","mid","high","top","max"];for(const a of s)Me(e[a])&&t.push(`--sf-z-${a}: ${parseInt(e[a],10)};`);return t}function nc(e){const t=[],s={contrast_bias:"--sf-contrast-bias",contrast_threshold:"--sf-contrast-threshold",opacity_disabled:"--sf-opacity-disabled"};for(const[n,i]of Object.entries(s))Me(e[n])&&t.push(`${i}: ${Mr(e[n])};`);const a={focus_ring_width:"--sf-focus-ring-width",focus_ring_offset:"--sf-focus-ring-offset"};for(const[n,i]of Object.entries(a))Me(e[n])&&t.push(`${i}: ${Mr(e[n])}px;`);return Me(e.focus_ring_style)&&["solid","dashed","dotted","double","none"].includes(e.focus_ring_style)&&t.push(`--sf-focus-ring-style: ${e.focus_ring_style};`),t}function fr(e){const t=[];if(e.colors&&typeof e.colors=="object"&&t.push(...Jo(e.colors)),e.typography&&typeof e.typography=="object"&&t.push(...Qo(e.typography)),e.spacing&&typeof e.spacing=="object"&&t.push(...ec(e.spacing)),e.radius&&typeof e.radius=="object"&&t.push(...tc(e.radius)),e.shadows&&typeof e.shadows=="object"&&t.push(...sc(e.shadows)),e.motion&&typeof e.motion=="object"&&t.push(...ac(e.motion)),e.zindex&&typeof e.zindex=="object"&&t.push(...rc(e.zindex)),e.contrast&&typeof e.contrast=="object"&&t.push(...nc(e.contrast)),t.length===0)return"";let s=`@layer slashed.overrides { :root { `;for(const a of t)s+=` ${a} From bade0e651c35944d490f1a1e80b6615752bf9370 Mon Sep 17 00:00:00 2001 From: Claude Date: Sun, 31 May 2026 20:53:56 +0000 Subject: [PATCH 2/3] fix: guard Gutenberg enqueue_frontend_styles against Bricks builder panel When both integrations are active (unified plugin), the Gutenberg enqueue hook had no bricks_is_builder_main() guard, so it loaded the SLASHED CSS framework on the Bricks editor page even though the Core and Bricks enqueue classes correctly skipped it. The universal resets (margin/padding, svg display:block, button font:inherit, etc.) then bled into the Bricks builder chrome, causing deformed icons in the panel UI. https://claude.ai/code/session_01DU3r3kT7GqH7w7jeadV2DT --- .../integrations/gutenberg/includes/class-enqueue.php | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/plugins/SLASHED-for-WP/integrations/gutenberg/includes/class-enqueue.php b/plugins/SLASHED-for-WP/integrations/gutenberg/includes/class-enqueue.php index c0003103..1c87cff6 100644 --- a/plugins/SLASHED-for-WP/integrations/gutenberg/includes/class-enqueue.php +++ b/plugins/SLASHED-for-WP/integrations/gutenberg/includes/class-enqueue.php @@ -62,8 +62,16 @@ public function enqueue_editor_styles() { /** * Load SLASHED CSS on the public frontend. + * + * Skips the Bricks builder-panel context when Bricks is active: + * loading CSS resets into the builder chrome breaks Bricks' icons. + * The same guard lives in Slashed_Core_Enqueue::enqueue_frontend(). */ public function enqueue_frontend_styles() { + if ( function_exists( 'bricks_is_builder_main' ) && bricks_is_builder_main() ) { + return; + } + $css_url = slashed_gutenberg_get_css_url(); if ( '' === $css_url ) { return; From 50dcfeb41be12f45e100ee7c4edae53b385999e3 Mon Sep 17 00:00:00 2001 From: Claude Date: Sun, 31 May 2026 20:58:06 +0000 Subject: [PATCH 3/3] fix: add dark_mode field to Bricks color entries to enable dark mode toggle MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bricks only activates its dark-mode toggle element when at least one color in the Color Manager has a dark_mode variant. SLASHED color entries previously only had hex + raw fields, so the toggle was permanently inert. Adding dark_mode: { hex, raw } with the same var() reference as light mode is sufficient — SLASHED's CSS custom properties already switch to their dark values when data-brx-theme="dark" is set on (bridged by the inline rule in class-enqueue.php). Bricks just needed to see the dark_mode field present to unlock the toggle. https://claude.ai/code/session_01DU3r3kT7GqH7w7jeadV2DT --- .../bricks/includes/class-colors.php | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/plugins/SLASHED-for-WP/integrations/bricks/includes/class-colors.php b/plugins/SLASHED-for-WP/integrations/bricks/includes/class-colors.php index 5634d824..08c6c0f9 100644 --- a/plugins/SLASHED-for-WP/integrations/bricks/includes/class-colors.php +++ b/plugins/SLASHED-for-WP/integrations/bricks/includes/class-colors.php @@ -250,10 +250,19 @@ private function vars_to_palette_colors( $palette_slug, $vars, $hex_map ) { $hex_fallback = isset( $hex_map[ $var ] ) ? $hex_map[ $var ] : '#808080'; $colors[] = array( - 'id' => self::PALETTE_ID_PREFIX . $palette_slug . '-' . $this->slugify( $key ), - 'name' => $this->humanize_key( $key ), - 'hex' => $hex_fallback, - 'raw' => 'var(' . $var . ')', + 'id' => self::PALETTE_ID_PREFIX . $palette_slug . '-' . $this->slugify( $key ), + 'name' => $this->humanize_key( $key ), + 'hex' => $hex_fallback, + 'raw' => 'var(' . $var . ')', + // Bricks only enables its dark-mode toggle element when at least + // one palette color has a dark_mode entry. SLASHED's CSS custom + // properties resolve to their dark-mode value automatically when + // data-brx-theme="dark" is set (bridged by the inline rule in + // class-enqueue.php), so both modes can reference the same var(). + 'dark_mode' => array( + 'hex' => $hex_fallback, + 'raw' => 'var(' . $var . ')', + ), ); } return $colors;