@stacksjs/stx
Version:
A performant UI Framework. Powered by Bun.
994 lines (894 loc) • 82.1 kB
JavaScript
// @bun
var I=import.meta.require;var _X=`
<script>
(function() {
'use strict';
// Skip if already initialized or not in Craft environment
if (window.__craftBridgeInitialized) return;
window.__craftBridgeInitialized = true;
// Message ID counter
let messageId = 0;
const generateId = () => 'msg_' + Date.now() + '_' + (++messageId);
// Pending requests
const pending = new Map();
// Event listeners
const eventListeners = new Map();
// Configuration
const config = {
debug: false,
timeout: 30000
};
// Send message to native
function send(message) {
const json = JSON.stringify(message);
if (config.debug) {
console.log('[Craft Bridge] Sending:', message.method, message.params);
}
// iOS WKWebView
if (window.webkit?.messageHandlers?.craft) {
window.webkit.messageHandlers.craft.postMessage(message);
return true;
}
// Android WebView
if (window.CraftBridge) {
window.CraftBridge.postMessage(json);
return true;
}
// Electron IPC
if (window.craftIPC) {
window.craftIPC.send('bridge-message', message);
return true;
}
return false;
}
// Make a request and wait for response
function request(method, params) {
return new Promise((resolve, reject) => {
const id = generateId();
const timeout = setTimeout(() => {
pending.delete(id);
reject(new Error('Request timeout: ' + method));
}, config.timeout);
pending.set(id, { resolve, reject, timeout });
const sent = send({
id,
type: 'request',
method,
params
});
if (!sent) {
clearTimeout(timeout);
pending.delete(id);
// Return gracefully if not in Craft environment
resolve(undefined);
}
});
}
// Handle incoming messages
function handleMessage(event) {
let data;
try {
data = event.detail || (typeof event.data === 'string' ? JSON.parse(event.data) : event.data);
} catch (e) {
return;
}
if (!data || !data.id) return;
if (config.debug) {
console.log('[Craft Bridge] Received:', data);
}
if (data.type === 'response') {
const req = pending.get(data.id);
if (req) {
clearTimeout(req.timeout);
pending.delete(data.id);
if (data.error) {
req.reject(new Error(data.error.message));
} else {
req.resolve(data.result);
}
}
} else if (data.type === 'event' && data.method) {
const listeners = eventListeners.get(data.method) || [];
listeners.forEach(fn => fn(data.params));
}
}
// Listen for messages
window.addEventListener('message', handleMessage);
window.addEventListener('craft-bridge-message', handleMessage);
// Check if running in Craft
function isCraft() {
return !!(
window.webkit?.messageHandlers?.craft ||
window.CraftBridge ||
window.craftIPC
);
}
// Subscribe to events
function on(event, callback) {
if (!eventListeners.has(event)) {
eventListeners.set(event, []);
}
eventListeners.get(event).push(callback);
return () => {
const listeners = eventListeners.get(event);
const idx = listeners.indexOf(callback);
if (idx > -1) listeners.splice(idx, 1);
};
}
// Build the craft API object
window.craft = {
// Meta
isCraft,
on,
config,
// Window API
window: {
show: () => request('window.show'),
hide: () => request('window.hide'),
close: () => request('window.close'),
minimize: () => request('window.minimize'),
maximize: () => request('window.maximize'),
restore: () => request('window.restore'),
focus: () => request('window.focus'),
blur: () => request('window.blur'),
setTitle: (title) => request('window.setTitle', { title }),
setSize: (width, height) => request('window.setSize', { width, height }),
setPosition: (x, y) => request('window.setPosition', { x, y }),
setFullscreen: (fullscreen) => request('window.setFullscreen', { fullscreen }),
setAlwaysOnTop: (alwaysOnTop) => request('window.setAlwaysOnTop', { alwaysOnTop }),
getSize: () => request('window.getSize'),
getPosition: () => request('window.getPosition'),
isFullscreen: () => request('window.isFullscreen'),
isMaximized: () => request('window.isMaximized'),
isMinimized: () => request('window.isMinimized'),
isVisible: () => request('window.isVisible'),
center: () => request('window.center'),
toggleFullscreen: () => request('window.toggleFullscreen'),
startDrag: () => request('window.startDrag'),
},
// System Tray/Menubar API
tray: {
setTitle: (title) => request('tray.setTitle', { title }),
setTooltip: (tooltip) => request('tray.setTooltip', { tooltip }),
setIcon: (icon) => request('tray.setIcon', { icon }),
setMenu: (menu) => request('tray.setMenu', { menu }),
show: () => request('tray.show'),
hide: () => request('tray.hide'),
onClick: (callback) => on('tray.click', callback),
onDoubleClick: (callback) => on('tray.doubleClick', callback),
onRightClick: (callback) => on('tray.rightClick', callback),
},
// App API
app: {
quit: () => request('app.quit'),
hide: () => request('app.hide'),
show: () => request('app.show'),
focus: () => request('app.focus'),
getInfo: () => request('app.getInfo'),
getVersion: () => request('app.getVersion'),
getName: () => request('app.getName'),
getPath: (name) => request('app.getPath', { name }),
isDarkMode: () => request('app.isDarkMode'),
getLocale: () => request('app.getLocale'),
setBadge: (badge) => request('app.setBadge', { badge }),
hideDockIcon: () => request('app.hideDockIcon'),
showDockIcon: () => request('app.showDockIcon'),
notify: (options) => request('app.notify', options),
registerShortcut: (accelerator, callback) => {
const id = generateId();
on('shortcut.' + id, callback);
return request('app.registerShortcut', { accelerator, id });
},
unregisterShortcut: (accelerator) => request('app.unregisterShortcut', { accelerator }),
},
// Dialog API
dialog: {
openFile: (options) => request('dialog.openFile', options),
openFolder: (options) => request('dialog.openFolder', options),
saveFile: (options) => request('dialog.saveFile', options),
showAlert: (options) => request('dialog.showAlert', options),
showConfirm: (options) => request('dialog.showConfirm', options),
showPrompt: (options) => request('dialog.showPrompt', options),
showColorPicker: (options) => request('dialog.showColorPicker', options),
},
// Clipboard API
clipboard: {
writeText: (text) => request('clipboard.writeText', { text }),
readText: () => request('clipboard.readText'),
writeHTML: (html) => request('clipboard.writeHTML', { html }),
readHTML: () => request('clipboard.readHTML'),
clear: () => request('clipboard.clear'),
},
// File System API (limited for security)
fs: {
readFile: (path, encoding) => request('fs.readFile', { path, encoding }),
writeFile: (path, content, encoding) => request('fs.writeFile', { path, content, encoding }),
exists: (path) => request('fs.exists', { path }),
stat: (path) => request('fs.stat', { path }),
readDir: (path) => request('fs.readDir', { path }),
createDir: (path, recursive) => request('fs.createDir', { path, recursive }),
remove: (path, recursive) => request('fs.remove', { path, recursive }),
},
// Process/Shell API (limited for security)
process: {
exec: (command, options) => request('process.exec', { command, ...options }),
spawn: (command, args, options) => request('process.spawn', { command, args, ...options }),
env: () => request('process.env'),
cwd: () => request('process.cwd'),
platform: () => request('process.platform'),
},
// Native component helpers
components: {
createSidebar: (config) => request('component.createSidebar', config),
createFileBrowser: (config) => request('component.createFileBrowser', config),
createSplitView: (config) => request('component.createSplitView', config),
updateComponent: (id, props) => request('component.update', { componentId: id, props }),
destroyComponent: (id) => request('component.destroy', { componentId: id }),
}
};
// Dispatch ready event
window.dispatchEvent(new CustomEvent('craft:ready', { detail: { isCraft: isCraft() } }));
if (config.debug) {
console.log('[Craft Bridge] Initialized, isCraft:', isCraft());
}
})();
</script>
`;function u(U={}){let{debug:X=!1,timeout:$=30000}=U;return`
<script>
(function() {
'use strict';
// Skip if already initialized or not in Craft environment
if (window.__craftBridgeInitialized) return;
window.__craftBridgeInitialized = true;
// Message ID counter
let messageId = 0;
const generateId = () => 'msg_' + Date.now() + '_' + (++messageId);
// Pending requests
const pending = new Map();
// Event listeners
const eventListeners = new Map();
// Configuration
const config = {
debug: false,
timeout: 30000
};
// Send message to native
function send(message) {
const json = JSON.stringify(message);
if (config.debug) {
console.log('[Craft Bridge] Sending:', message.method, message.params);
}
// iOS WKWebView
if (window.webkit?.messageHandlers?.craft) {
window.webkit.messageHandlers.craft.postMessage(message);
return true;
}
// Android WebView
if (window.CraftBridge) {
window.CraftBridge.postMessage(json);
return true;
}
// Electron IPC
if (window.craftIPC) {
window.craftIPC.send('bridge-message', message);
return true;
}
return false;
}
// Make a request and wait for response
function request(method, params) {
return new Promise((resolve, reject) => {
const id = generateId();
const timeout = setTimeout(() => {
pending.delete(id);
reject(new Error('Request timeout: ' + method));
}, config.timeout);
pending.set(id, { resolve, reject, timeout });
const sent = send({
id,
type: 'request',
method,
params
});
if (!sent) {
clearTimeout(timeout);
pending.delete(id);
// Return gracefully if not in Craft environment
resolve(undefined);
}
});
}
// Handle incoming messages
function handleMessage(event) {
let data;
try {
data = event.detail || (typeof event.data === 'string' ? JSON.parse(event.data) : event.data);
} catch (e) {
return;
}
if (!data || !data.id) return;
if (config.debug) {
console.log('[Craft Bridge] Received:', data);
}
if (data.type === 'response') {
const req = pending.get(data.id);
if (req) {
clearTimeout(req.timeout);
pending.delete(data.id);
if (data.error) {
req.reject(new Error(data.error.message));
} else {
req.resolve(data.result);
}
}
} else if (data.type === 'event' && data.method) {
const listeners = eventListeners.get(data.method) || [];
listeners.forEach(fn => fn(data.params));
}
}
// Listen for messages
window.addEventListener('message', handleMessage);
window.addEventListener('craft-bridge-message', handleMessage);
// Check if running in Craft
function isCraft() {
return !!(
window.webkit?.messageHandlers?.craft ||
window.CraftBridge ||
window.craftIPC
);
}
// Subscribe to events
function on(event, callback) {
if (!eventListeners.has(event)) {
eventListeners.set(event, []);
}
eventListeners.get(event).push(callback);
return () => {
const listeners = eventListeners.get(event);
const idx = listeners.indexOf(callback);
if (idx > -1) listeners.splice(idx, 1);
};
}
// Build the craft API object
window.craft = {
// Meta
isCraft,
on,
config,
// Window API
window: {
show: () => request('window.show'),
hide: () => request('window.hide'),
close: () => request('window.close'),
minimize: () => request('window.minimize'),
maximize: () => request('window.maximize'),
restore: () => request('window.restore'),
focus: () => request('window.focus'),
blur: () => request('window.blur'),
setTitle: (title) => request('window.setTitle', { title }),
setSize: (width, height) => request('window.setSize', { width, height }),
setPosition: (x, y) => request('window.setPosition', { x, y }),
setFullscreen: (fullscreen) => request('window.setFullscreen', { fullscreen }),
setAlwaysOnTop: (alwaysOnTop) => request('window.setAlwaysOnTop', { alwaysOnTop }),
getSize: () => request('window.getSize'),
getPosition: () => request('window.getPosition'),
isFullscreen: () => request('window.isFullscreen'),
isMaximized: () => request('window.isMaximized'),
isMinimized: () => request('window.isMinimized'),
isVisible: () => request('window.isVisible'),
center: () => request('window.center'),
toggleFullscreen: () => request('window.toggleFullscreen'),
startDrag: () => request('window.startDrag'),
},
// System Tray/Menubar API
tray: {
setTitle: (title) => request('tray.setTitle', { title }),
setTooltip: (tooltip) => request('tray.setTooltip', { tooltip }),
setIcon: (icon) => request('tray.setIcon', { icon }),
setMenu: (menu) => request('tray.setMenu', { menu }),
show: () => request('tray.show'),
hide: () => request('tray.hide'),
onClick: (callback) => on('tray.click', callback),
onDoubleClick: (callback) => on('tray.doubleClick', callback),
onRightClick: (callback) => on('tray.rightClick', callback),
},
// App API
app: {
quit: () => request('app.quit'),
hide: () => request('app.hide'),
show: () => request('app.show'),
focus: () => request('app.focus'),
getInfo: () => request('app.getInfo'),
getVersion: () => request('app.getVersion'),
getName: () => request('app.getName'),
getPath: (name) => request('app.getPath', { name }),
isDarkMode: () => request('app.isDarkMode'),
getLocale: () => request('app.getLocale'),
setBadge: (badge) => request('app.setBadge', { badge }),
hideDockIcon: () => request('app.hideDockIcon'),
showDockIcon: () => request('app.showDockIcon'),
notify: (options) => request('app.notify', options),
registerShortcut: (accelerator, callback) => {
const id = generateId();
on('shortcut.' + id, callback);
return request('app.registerShortcut', { accelerator, id });
},
unregisterShortcut: (accelerator) => request('app.unregisterShortcut', { accelerator }),
},
// Dialog API
dialog: {
openFile: (options) => request('dialog.openFile', options),
openFolder: (options) => request('dialog.openFolder', options),
saveFile: (options) => request('dialog.saveFile', options),
showAlert: (options) => request('dialog.showAlert', options),
showConfirm: (options) => request('dialog.showConfirm', options),
showPrompt: (options) => request('dialog.showPrompt', options),
showColorPicker: (options) => request('dialog.showColorPicker', options),
},
// Clipboard API
clipboard: {
writeText: (text) => request('clipboard.writeText', { text }),
readText: () => request('clipboard.readText'),
writeHTML: (html) => request('clipboard.writeHTML', { html }),
readHTML: () => request('clipboard.readHTML'),
clear: () => request('clipboard.clear'),
},
// File System API (limited for security)
fs: {
readFile: (path, encoding) => request('fs.readFile', { path, encoding }),
writeFile: (path, content, encoding) => request('fs.writeFile', { path, content, encoding }),
exists: (path) => request('fs.exists', { path }),
stat: (path) => request('fs.stat', { path }),
readDir: (path) => request('fs.readDir', { path }),
createDir: (path, recursive) => request('fs.createDir', { path, recursive }),
remove: (path, recursive) => request('fs.remove', { path, recursive }),
},
// Process/Shell API (limited for security)
process: {
exec: (command, options) => request('process.exec', { command, ...options }),
spawn: (command, args, options) => request('process.spawn', { command, args, ...options }),
env: () => request('process.env'),
cwd: () => request('process.cwd'),
platform: () => request('process.platform'),
},
// Native component helpers
components: {
createSidebar: (config) => request('component.createSidebar', config),
createFileBrowser: (config) => request('component.createFileBrowser', config),
createSplitView: (config) => request('component.createSplitView', config),
updateComponent: (id, props) => request('component.update', { componentId: id, props }),
destroyComponent: (id) => request('component.destroy', { componentId: id }),
}
};
// Dispatch ready event
window.dispatchEvent(new CustomEvent('craft:ready', { detail: { isCraft: isCraft() } }));
if (config.debug) {
console.log('[Craft Bridge] Initialized, isCraft:', isCraft());
}
})();
</script>
`.replace("debug: false,",`debug: ${X},`).replace("timeout: 30000",`timeout: ${$}`)}function LX(){return!1}function AX(U,X={}){let $=/@craft(?:\(([\s\S]*?)\))?/g;return U.replace($,(q,Y)=>{let J={};if(Y)try{J=JSON.parse(Y.replace(/'/g,'"'))}catch{try{J=Function(`return ${Y}`)()}catch{console.warn(`[stx] Invalid @craft config: ${Y}`)}}return u(J)})}function h(U,X={}){if(U.includes("__craftBridgeInitialized"))return U;let $=u(X);if(U.includes("</head>"))return U.replace("</head>",`${$}
</head>`);if(U.includes("<body"))return U.replace(/(<body[^>]*>)/,`$1
${$}`);return $+U}var QU=new Map([["craft-button",{name:"Button",zigType:"craft.Button",props:[{name:"variant",type:"string",required:!1,default:"primary"},{name:"disabled",type:"boolean",required:!1,default:!1},{name:"onclick",type:"callback",required:!1}],children:"single"}],["craft-text-input",{name:"TextInput",zigType:"craft.TextInput",props:[{name:"value",type:"string",required:!1,default:""},{name:"placeholder",type:"string",required:!1},{name:"disabled",type:"boolean",required:!1,default:!1},{name:"onchange",type:"callback",required:!1}],children:"none"}],["craft-textarea",{name:"TextArea",zigType:"craft.TextArea",props:[{name:"value",type:"string",required:!1,default:""},{name:"placeholder",type:"string",required:!1},{name:"rows",type:"number",required:!1,default:3},{name:"disabled",type:"boolean",required:!1,default:!1}],children:"none"}],["craft-checkbox",{name:"Checkbox",zigType:"craft.Checkbox",props:[{name:"checked",type:"boolean",required:!1,default:!1},{name:"label",type:"string",required:!1},{name:"disabled",type:"boolean",required:!1,default:!1},{name:"onchange",type:"callback",required:!1}],children:"none"}],["craft-select",{name:"Select",zigType:"craft.Select",props:[{name:"value",type:"string",required:!1},{name:"options",type:"array",required:!0},{name:"disabled",type:"boolean",required:!1,default:!1},{name:"onchange",type:"callback",required:!1}],children:"none"}],["craft-slider",{name:"Slider",zigType:"craft.Slider",props:[{name:"value",type:"number",required:!1,default:0},{name:"min",type:"number",required:!1,default:0},{name:"max",type:"number",required:!1,default:100},{name:"step",type:"number",required:!1,default:1},{name:"onchange",type:"callback",required:!1}],children:"none"}],["craft-toggle",{name:"Toggle",zigType:"craft.Toggle",props:[{name:"checked",type:"boolean",required:!1,default:!1},{name:"disabled",type:"boolean",required:!1,default:!1},{name:"onchange",type:"callback",required:!1}],children:"none"}],["craft-modal",{name:"Modal",zigType:"craft.Modal",props:[{name:"open",type:"boolean",required:!1,default:!1},{name:"title",type:"string",required:!1},{name:"closable",type:"boolean",required:!1,default:!0},{name:"onclose",type:"callback",required:!1}],children:"multiple"}],["craft-alert",{name:"Alert",zigType:"craft.Alert",props:[{name:"variant",type:"string",required:!1,default:"info"},{name:"title",type:"string",required:!1},{name:"dismissible",type:"boolean",required:!1,default:!1}],children:"single"}],["craft-progress",{name:"ProgressBar",zigType:"craft.ProgressBar",props:[{name:"value",type:"number",required:!1,default:0},{name:"max",type:"number",required:!1,default:100},{name:"indeterminate",type:"boolean",required:!1,default:!1}],children:"none"}],["craft-spinner",{name:"Spinner",zigType:"craft.Spinner",props:[{name:"size",type:"number",required:!1,default:24}],children:"none"}],["craft-avatar",{name:"Avatar",zigType:"craft.Avatar",props:[{name:"src",type:"string",required:!1},{name:"alt",type:"string",required:!1},{name:"size",type:"number",required:!1,default:40}],children:"none"}],["craft-badge",{name:"Badge",zigType:"craft.Badge",props:[{name:"variant",type:"string",required:!1,default:"default"}],children:"single"}],["craft-card",{name:"Card",zigType:"craft.Card",props:[{name:"padding",type:"number",required:!1,default:16}],children:"multiple"}],["craft-accordion",{name:"Accordion",zigType:"craft.Accordion",props:[{name:"title",type:"string",required:!0},{name:"open",type:"boolean",required:!1,default:!1}],children:"multiple"}],["craft-tabs",{name:"TabView",zigType:"craft.TabView",props:[{name:"activeTab",type:"number",required:!1,default:0},{name:"ontabchange",type:"callback",required:!1}],children:"multiple"}],["craft-tooltip",{name:"Tooltip",zigType:"craft.Tooltip",props:[{name:"content",type:"string",required:!0},{name:"position",type:"string",required:!1,default:"top"}],children:"single"}],["craft-date-picker",{name:"DatePicker",zigType:"craft.DatePicker",props:[{name:"value",type:"string",required:!1},{name:"min",type:"string",required:!1},{name:"max",type:"string",required:!1},{name:"onchange",type:"callback",required:!1}],children:"none"}],["craft-time-picker",{name:"TimePicker",zigType:"craft.TimePicker",props:[{name:"value",type:"string",required:!1},{name:"onchange",type:"callback",required:!1}],children:"none"}],["craft-color-picker",{name:"ColorPicker",zigType:"craft.ColorPicker",props:[{name:"value",type:"color",required:!1,default:"#000000"},{name:"onchange",type:"callback",required:!1}],children:"none"}],["craft-data-table",{name:"DataTable",zigType:"craft.DataTable",props:[{name:"data",type:"array",required:!0},{name:"columns",type:"array",required:!0},{name:"sortable",type:"boolean",required:!1,default:!1},{name:"paginated",type:"boolean",required:!1,default:!1}],children:"none"}],["craft-virtual-list",{name:"VirtualList",zigType:"craft.VirtualList",props:[{name:"items",type:"array",required:!0},{name:"itemHeight",type:"number",required:!1,default:48},{name:"renderItem",type:"callback",required:!0}],children:"none"}],["craft-tree-view",{name:"TreeView",zigType:"craft.TreeView",props:[{name:"data",type:"object",required:!0},{name:"expandable",type:"boolean",required:!1,default:!0}],children:"none"}]]);async function OX(U,X={}){let $=performance.now(),q={target:X.target||"universal",format:X.format||"zig",optimize:X.optimize??!0,treeShake:X.treeShake??!0,hotReload:X.hotReload??!1,debug:X.debug??!1,sourceMaps:X.sourceMaps??!1,bundle:X.bundle??!0,minify:X.minify??!1,components:X.components||QU},Y=typeof U==="string"?GU(U):U,J=WU(Y.tree,q),G=EU(J),Q=q.treeShake?VU(J,G):J,K=new Map;if(q.target==="universal"){let B=["macos","windows","linux","ios","android"];for(let H of B){let O=D(Q,{...q,target:H});K.set(H,O)}}else{let B=D(Q,q);K.set(q.target,B)}let W=IU(Q,q,K),_=MU(Y,Q,q),L={compilationTime:performance.now()-$,totalComponents:S(Y.tree),nativeComponents:y(Q),webComponents:S(Y.tree)-y(Q),bundleSize:W.length,treeShakenSize:q.treeShake?wU(J,Q):W.length,warnings:[],errors:[]},A;if(q.sourceMaps)A=RU(Y,Q);return{code:W,platformCode:K,dependencies:G,manifest:_,sourceMaps:A,stats:L}}function GU(U){let X={type:"fragment",children:[]},$=U.match(/<body[^>]*>([\s\S]*?)<\/body>/i),q=$?$[1]:U;return g(q,X),{id:c(),hash:r(U),tree:X,scripts:jU(U),styles:kU(U),staticParts:new Map,dynamicParts:new Map,dependencies:[],metadata:{hasSlots:!1,hasDynamicContent:U.includes("{{"),hasEventHandlers:U.includes("onclick")||U.includes("onchange"),hasAsyncContent:!1,componentCount:0,maxDepth:0,estimatedSize:U.length}}}function g(U,X){let $=/<(@?[\w-]+)([^>]*)(?:\/>|>([\s\S]*?)<\/\1>)/g,q;while((q=$.exec(U))!==null){let[,Y,J,G]=q,Q=Y.startsWith("@craft-"),K={type:Q?"component":"element",tag:Q?Y.slice(1):Y,props:KU(J),children:[],componentName:Q?Y.slice(1):void 0};if(G){let W=G.replace(/<[^>]+>/g,"").trim();if(W)K.children=K.children??[],K.children.push({type:"text",text:W});g(G,K)}X.children=X.children??[],X.children.push(K)}}function KU(U){let X={},$=/([\w-:@]+)(?:=["']([^"']*)["'])?/g,q;while((q=$.exec(U))!==null){let[,Y,J]=q;X[Y]=J??!0}return X}function WU(U,X){return m(U,X)}function m(U,X){let $=U.componentName?X.components?.get(U.componentName):void 0,q="craft.View";if($)q=$.zigType;else if(U.type==="text")q="craft.Text";else if(U.tag)q=ZU(U.tag);let Y={};if(U.props)for(let[K,W]of Object.entries(U.props))Y[K]=_U(W);let J=[];if(U.children)for(let K of U.children)J.push(m(K,X));let G=new Map;if(U.props){for(let[K,W]of Object.entries(U.props))if(K.startsWith("on")&&typeof W==="string")G.set(K.slice(2).toLowerCase(),W)}let Q=AU(U);return{type:LU(U,$),zigType:q,props:Y,children:J,events:G,styles:Q,id:U.hydrationKey,key:U.props?.key}}function ZU(U){return{div:"craft.View",span:"craft.Text",p:"craft.Text",h1:"craft.Text",h2:"craft.Text",h3:"craft.Text",h4:"craft.Text",h5:"craft.Text",h6:"craft.Text",button:"craft.Button",input:"craft.TextInput",textarea:"craft.TextArea",select:"craft.Select",img:"craft.Image",a:"craft.Link",ul:"craft.List",ol:"craft.List",li:"craft.ListItem",form:"craft.Form",label:"craft.Label",nav:"craft.View",header:"craft.View",footer:"craft.View",main:"craft.View",section:"craft.View",article:"craft.View",aside:"craft.View"}[U.toLowerCase()]||"craft.View"}function _U(U){if(typeof U==="string"){if(U.startsWith("{{")&&U.endsWith("}}"))return{type:"binding",path:U.slice(2,-2).trim()};if(U.includes("(")&&U.includes(")"))return{type:"callback",handler:U};return{type:"literal",value:U}}if(typeof U==="number"||typeof U==="boolean")return{type:"literal",value:U};return{type:"literal",value:String(U)}}function LU(U,X){if(X){let q=X.name.toLowerCase();if(q.includes("button"))return"button";if(q.includes("input")||q.includes("text"))return"input";if(q.includes("image")||q.includes("avatar"))return"image";if(q.includes("list")||q.includes("table"))return"list";if(q.includes("scroll"))return"scroll";return"custom"}if(U.type==="text")return"text";let $=U.tag?.toLowerCase();if($==="button")return"button";if($==="input"||$==="textarea")return"input";if($==="img")return"image";if($==="ul"||$==="ol")return"list";return"view"}function AU(U){let X=U.props?.style,$={},q={};if(X){let Y=X.split(";").filter(Boolean);for(let J of Y){let[G,Q]=J.split(":").map((K)=>K.trim());if(!G||!Q)continue;switch(G){case"display":$.display=Q;break;case"flex-direction":$.flexDirection=Q;break;case"justify-content":$.justifyContent=BU(Q);break;case"align-items":$.alignItems=OU(Q);break;case"gap":$.gap=Number.parseInt(Q,10);break;case"padding":$.padding=Number.parseInt(Q,10);break;case"margin":$.margin=Number.parseInt(Q,10);break;case"width":$.width=Q==="auto"?"auto":Number.parseInt(Q,10);break;case"height":$.height=Q==="auto"?"auto":Number.parseInt(Q,10);break;case"background-color":case"background":q.backgroundColor=Q;break;case"border-color":q.borderColor=Q;break;case"border-width":q.borderWidth=Number.parseInt(Q,10);break;case"border-radius":q.borderRadius=Number.parseInt(Q,10);break;case"opacity":q.opacity=Number.parseFloat(Q);break}}}return{layout:$,appearance:q}}function BU(U){return{"flex-start":"start","flex-end":"end",center:"center","space-between":"between","space-around":"around"}[U]||"start"}function OU(U){return{"flex-start":"start","flex-end":"end",center:"center",stretch:"stretch"}[U]||"start"}function EU(U){let X=[],$=new Set;function q(Y,J){let G=Y.id||c();if($.has(G))return;$.add(G);let Q={id:G,type:"component",path:Y.zigType,dependencies:J?[J]:[],size:d(Y),isStatic:HU(Y)};X.push(Q);for(let K of Y.children)q(K,G)}return q(U),X}function d(U){let X=100;return X+=Object.keys(U.props).length*20,X+=U.events.size*50,X}function HU(U){for(let X of Object.values(U.props))if(X.type!=="literal")return!1;return U.events.size===0}function VU(U,X){return U}function wU(U,X){let $=0;function q(Y){$+=d(Y);for(let J of Y.children)q(J)}return q(X),$}function D(U,X){switch(X.format){case"zig":return f(U,X);case"typescript":return FU(U,X);case"json":return JSON.stringify(U,null,X.minify?0:2);default:return f(U,X)}}function f(U,X){let $=[];return $.push("// Auto-generated by stx compiler"),$.push("// Target: "+X.target),$.push(""),$.push('const std = @import("std");'),$.push('const craft = @import("craft");'),$.push(""),$.push("pub fn render(allocator: std.mem.Allocator) !craft.Element {"),$.push(" return try build(allocator);"),$.push("}"),$.push(""),s(U,$,0),$.join(`
`)}function s(U,X,$){let q=" ".repeat($);if($===0)X.push("fn build(allocator: std.mem.Allocator) !craft.Element {");let Y=`node_${$}`;X.push(`${q} var ${Y} = try ${U.zigType}.init(allocator);`);for(let[J,G]of Object.entries(U.props))if(G.type==="literal"){let Q=typeof G.value==="string"?`"${G.value}"`:String(G.value);X.push(`${q} ${Y}.set${bU(J)}(${Q});`)}for(let J=0;J<U.children.length;J++){let G=U.children[J];if(G.type==="text"){let Q=G.props.text?.type==="literal"?String(G.props.text.value):"";X.push(`${q} try ${Y}.addChild(try craft.Text.init(allocator, "${Q}"));`)}else s(G,X,$+1),X.push(`${q} try ${Y}.addChild(node_${$+1});`)}if($===0)X.push(` return ${Y}.element();`),X.push("}")}function FU(U,X){let $=[];return $.push("// Auto-generated by stx compiler"),$.push("// Target: "+X.target),$.push(""),$.push('import { Craft } from "@stacksjs/craft";'),$.push(""),$.push("export function render(): Craft.Element {"),$.push(" return "+l(U,1)+";"),$.push("}"),$.join(`
`)}function l(U,X){let $=" ".repeat(X),q=[];for(let[Q,K]of Object.entries(U.props))if(K.type==="literal"){let W=typeof K.value==="string"?`"${K.value}"`:String(K.value);q.push(`${Q}: ${W}`)}let Y=q.length>0?`{ ${q.join(", ")} }`:"{}",J=U.children.map((Q)=>Q.type==="text"?`"${Q.props.text?.type==="literal"?Q.props.text.value:""}"`:l(Q,X+1)),G=J.length>0?`,
${$} [${J.join(`,
${$} `)}]`:"";return`Craft.create("${U.zigType}", ${Y}${G})`}function IU(U,X,$){if(X.target==="universal"){let q=[];q.push("// Universal entry point"),q.push("");for(let[Y,J]of $)q.push(`// --- ${Y.toUpperCase()} ---`),q.push(`#if ${Y.toUpperCase()}`),q.push(J),q.push("#endif"),q.push("");return q.join(`
`)}return $.get(X.target)||D(U,X)}function MU(U,X,$){let q=[];function Y(J){q.push({name:J.zigType,hash:r(JSON.stringify(J.props)),props:Object.keys(J.props),events:Array.from(J.events.keys()),slots:[],isNative:J.zigType.startsWith("craft.")});for(let G of J.children)Y(G)}return Y(X),{version:"1.0.0",components:q,entry:U.id,assets:[],styles:U.styles}}function RU(U,X){return JSON.stringify({version:3,file:"output.zig",sources:["input.stx"],mappings:""})}var zU=0;function c(){return`id_${++zU}`}function r(U){let X=0;for(let $=0;$<U.length;$++){let q=U.charCodeAt($);X=(X<<5)-X+q,X=X&X}return Math.abs(X).toString(36)}function bU(U){return U.charAt(0).toUpperCase()+U.slice(1)}function jU(U){let X=[],$=/<script[^>]*>([\s\S]*?)<\/script>/gi,q;while((q=$.exec(U))!==null)X.push(q[1]);return X}function kU(U){let X=[],$=/<style[^>]*>([\s\S]*?)<\/style>/gi,q;while((q=$.exec(U))!==null)X.push(q[1]);return X}function S(U){let X=U.type==="component"?1:0;if(U.children)for(let $ of U.children)X+=S($);return X}function y(U){let X=U.zigType.startsWith("craft.")?1:0;for(let $ of U.children)X+=y($);return X}function EX(U){return{start:async()=>{console.log("[craft-compiler] Hot reload server started")},stop:async()=>{console.log("[craft-compiler] Hot reload server stopped")},notifyChange:(X)=>{console.log(`[craft-compiler] File changed: ${X}`)}}}var N={button:{nativeType:"craft-button",fallbackTag:"button",fallbackClasses:"craft-button",nativeProps:["variant","size","disabled","loading"]},"text-input":{nativeType:"craft-text-input",fallbackTag:"input",fallbackClasses:"craft-text-input",nativeProps:["placeholder","value","type","disabled","readonly"]},textarea:{nativeType:"craft-textarea",fallbackTag:"textarea",fallbackClasses:"craft-textarea",nativeProps:["placeholder","value","rows","disabled","readonly"]},checkbox:{nativeType:"craft-checkbox",fallbackTag:"input",fallbackClasses:"craft-checkbox",nativeProps:["checked","disabled","label"],render:(U,X)=>{let $=U.checked?"checked":"",q=U.disabled?"disabled":"";return`<label class="craft-checkbox-wrapper">
<input type="checkbox" class="craft-checkbox" ${$} ${q}>
<span class="craft-checkbox-label">${X||U.label||""}</span>
</label>`}},radio:{nativeType:"craft-radio",fallbackTag:"input",fallbackClasses:"craft-radio",nativeProps:["checked","disabled","name","value","label"]},select:{nativeType:"craft-select",fallbackTag:"select",fallbackClasses:"craft-select",nativeProps:["value","disabled","options","placeholder"]},slider:{nativeType:"craft-slider",fallbackTag:"input",fallbackClasses:"craft-slider",nativeProps:["value","min","max","step","disabled"],render:(U,X)=>{let $=U.min??0,q=U.max??100,Y=U.step??1,J=U.value??50,G=U.disabled?"disabled":"";return`<input type="range" class="craft-slider" min="${$}" max="${q}" step="${Y}" value="${J}" ${G}>`}},label:{nativeType:"craft-label",fallbackTag:"span",fallbackClasses:"craft-label",nativeProps:["text","for"]},badge:{nativeType:"craft-badge",fallbackTag:"span",fallbackClasses:"craft-badge",nativeProps:["variant","size"]},avatar:{nativeType:"craft-avatar",fallbackTag:"div",fallbackClasses:"craft-avatar",nativeProps:["src","alt","size","fallback"],render:(U,X)=>{let $=U.size||40,q=U.src,Y=String(U.alt||""),J=U.fallback||(Y?Y.charAt(0).toUpperCase():"?");if(q)return`<img class="craft-avatar" src="${q}" alt="${Y}" style="width:${$}px;height:${$}px;border-radius:50%">`;return`<div class="craft-avatar craft-avatar-fallback" style="width:${$}px;height:${$}px;border-radius:50%;display:flex;align-items:center;justify-content:center">${J}</div>`}},progress:{nativeType:"craft-progress",fallbackTag:"div",fallbackClasses:"craft-progress",nativeProps:["value","max","variant"],render:(U,X)=>{let $=Number(U.value)||0,q=Number(U.max)||100;return`<div class="craft-progress"><div class="craft-progress-bar" style="width:${Math.min(100,Math.max(0,$/q*100))}%"></div></div>`}},spinner:{nativeType:"craft-spinner",fallbackTag:"div",fallbackClasses:"craft-spinner",nativeProps:["size"],render:(U,X)=>{let $=U.size||24;return`<div class="craft-spinner" style="width:${$}px;height:${$}px"></div>`}},card:{nativeType:"craft-card",fallbackTag:"div",fallbackClasses:"craft-card",nativeProps:["title","subtitle","variant"]},modal:{nativeType:"craft-modal",fallbackTag:"dialog",fallbackClasses:"craft-modal",nativeProps:["open","title","closable","size"],render:(U,X)=>{let $=U.open?"open":"",q=U.title||"";return`<dialog class="craft-modal" ${$}>
<div class="craft-modal-content">
${q?`<div class="craft-modal-header"><h2>${q}</h2></div>`:""}
<div class="craft-modal-body">${X}</div>
</div>
</dialog>`}},tabs:{nativeType:"craft-tabs",fallbackTag:"div",fallbackClasses:"craft-tabs",nativeProps:["activeTab","tabs"]},accordion:{nativeType:"craft-accordion",fallbackTag:"details",fallbackClasses:"craft-accordion",nativeProps:["open","title"],render:(U,X)=>{let $=U.open?"open":"",q=U.title||"Details";return`<details class="craft-accordion" ${$}>
<summary class="craft-accordion-header">${q}</summary>
<div class="craft-accordion-content">${X}</div>
</details>`}},divider:{nativeType:"craft-divider",fallbackTag:"hr",fallbackClasses:"craft-divider",nativeProps:["orientation","variant"]},table:{nativeType:"craft-table",fallbackTag:"table",fallbackClasses:"craft-table",nativeProps:["columns","rows","sortable","selectable"]},list:{nativeType:"craft-list",fallbackTag:"ul",fallbackClasses:"craft-list",nativeProps:["items","selectable"]},tree:{nativeType:"craft-tree",fallbackTag:"div",fallbackClasses:"craft-tree",nativeProps:["nodes","expandable","selectable"]},alert:{nativeType:"craft-alert",fallbackTag:"div",fallbackClasses:"craft-alert",nativeProps:["variant","title","dismissible"],render:(U,X)=>{let $=U.variant||"info",q=U.title||"";return`<div class="craft-alert craft-alert-${$}" role="alert">
${q?`<div class="craft-alert-title">${q}</div>`:""}
<div class="craft-alert-content">${X}</div>
</div>`}},toast:{nativeType:"craft-toast",fallbackTag:"div",fallbackClasses:"craft-toast",nativeProps:["variant","duration","position"]},tooltip:{nativeType:"craft-tooltip",fallbackTag:"span",fallbackClasses:"craft-tooltip",nativeProps:["content","position"],render:(U,X)=>{let $=U.content||"",q=U.position||"top";return`<span class="craft-tooltip" data-tooltip="${$}" data-position="${q}">${X}</span>`}},menu:{nativeType:"craft-menu",fallbackTag:"nav",fallbackClasses:"craft-menu",nativeProps:["items","orientation"]},breadcrumb:{nativeType:"craft-breadcrumb",fallbackTag:"nav",fallbackClasses:"craft-breadcrumb",nativeProps:["items","separator"]},pagination:{nativeType:"craft-pagination",fallbackTag:"nav",fallbackClasses:"craft-pagination",nativeProps:["total","page","pageSize"]},"code-editor":{nativeType:"craft-code-editor",fallbackTag:"textarea",fallbackClasses:"craft-code-editor",nativeProps:["value","language","theme","readonly","lineNumbers"]},"file-browser":{nativeType:"craft-file-browser",fallbackTag:"div",fallbackClasses:"craft-file-browser",nativeProps:["path","showHidden","selectable"]},"color-picker":{nativeType:"craft-color-picker",fallbackTag:"input",fallbackClasses:"craft-color-picker",nativeProps:["value","format"],render:(U,X)=>{return`<input type="color" class="craft-color-picker" value="${U.value||"#000000"}">`}},"date-picker":{nativeType:"craft-date-picker",fallbackTag:"input",fallbackClasses:"craft-date-picker",nativeProps:["value","min","max","format"],render:(U,X)=>{let $=U.value||"",q=U.min||"",Y=U.max||"";return`<input type="date" class="craft-date-picker" value="${$}" min="${q}" max="${Y}">`}},"time-picker":{nativeType:"craft-time-picker",fallbackTag:"input",fallbackClasses:"craft-time-picker",nativeProps:["value","min","max","step"],render:(U,X)=>{return`<input type="time" class="craft-time-picker" value="${U.value||""}">`}}},i=`
<style id="craft-component-styles">
/* Craft Component Base Styles */
.craft-button {
display: inline-flex;
align-items: center;
justify-content: center;
padding: 8px 16px;
border: none;
border-radius: 6px;
font-family: inherit;
font-size: 14px;
font-weight: 500;
cursor: pointer;
transition: all 0.2s ease;
background: var(--craft-primary, #3b82f6);
color: white;
}
.craft-button:hover { opacity: 0.9; }
.craft-button:disabled { opacity: 0.5; cursor: not-allowed; }
.craft-button-secondary { background: var(--craft-secondary, #6b7280); }
.craft-button-outline { background: transparent; border: 1px solid currentColor; color: var(--craft-primary, #3b82f6); }
.craft-text-input, .craft-textarea, .craft-select {
padding: 8px 12px;
border: 1px solid var(--craft-border, #d1d5db);
border-radius: 6px;
font-family: inherit;
font-size: 14px;
background: var(--craft-bg, #fff);
color: var(--craft-text, #1f2937);
transition: border-color 0.2s ease;
}
.craft-text-input:focus, .craft-textarea:focus, .craft-select:focus {
outline: none;
border-color: var(--craft-primary, #3b82f6);
box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1);
}
.craft-checkbox-wrapper {
display: inline-flex;
align-items: center;
gap: 8px;
cursor: pointer;
}
.craft-checkbox {
width: 18px;
height: 18px;
cursor: pointer;
}
.craft-slider {
width: 100%;
height: 6px;
border-radius: 3px;
cursor: pointer;
}
.craft-badge {
display: inline-flex;
align-items: center;
padding: 2px 8px;
border-radius: 9999px;
font-size: 12px;
font-weight: 500;
background: var(--craft-primary, #3b82f6);
color: white;
}
.craft-avatar {
display: inline-flex;
align-items: center;
justify-content: center;
background: var(--craft-secondary, #6b7280);
color: white;
font-weight: 600;
overflow: hidden;
}
.craft-avatar img { width: 100%; height: 100%; object-fit: cover; }
.craft-progress {
width: 100%;
height: 8px;
background: var(--craft-border, #e5e7eb);
border-radius: 4px;
overflow: hidden;
}
.craft-progress-bar {
height: 100%;
background: var(--craft-primary, #3b82f6);
transition: width 0.3s ease;
}
.craft-spinner {
border: 2px solid var(--craft-border, #e5e7eb);
border-top-color: var(--craft-primary, #3b82f6);
border-radius: 50%;
animation: craft-spin 0.8s linear infinite;
}
@keyframes craft-spin { to { transform: rotate(360deg); } }
.craft-card {
background: var(--craft-bg, #fff);
border: 1px solid var(--craft-border, #e5e7eb);
border-radius: 8px;
padding: 16px;
box-shadow: 0 1px 3px rgba(0,0,0,0.1);
}
.craft-modal {
border: none;
border-radius: 12px;
padding: 0;
max-width: 90vw;
max-height: 90vh;
box-shadow: 0 25px 50px -12px rgba(0,0,0,0.25);
}
.craft-modal::backdrop { background: rgba(0,0,0,0.5); }
.craft-modal-header {
padding: 16px 20px;
border-bottom: 1px solid var(--craft-border, #e5e7eb);
}
.craft-modal-header h2 { margin: 0; font-size: 18px; }
.craft-modal-body { padding: 20px; }
.craft-accordion {
border: 1px solid var(--craft-border, #e5e7eb);
border-radius: 6px;
overflow: hidden;
}
.craft-accordion-header {
padding: 12px 16px;
cursor: pointer;
font-weight: 500;
background: var(--craft-bg-secondary, #f9fafb);
}
.craft-accordion-content { padding: 16px; }
.craft-divider {
border: none;
border-top: 1px solid var(--craft-border, #e5e7eb);
margin: 16px 0;
}
.craft-alert {
padding: 12px 16px;
border-radius: 6px;
border-left: 4px solid;
}
.craft-alert-info { background: #eff6ff; border-color: #3b82f6; color: #1e40af; }
.craft-alert-success { background: #f0fdf4; border-color: #22c55e; color: #166534; }
.craft-alert-warning { background: #fffbeb; border-color: #f59e0b; color: #92400e; }
.craft-alert-error { background: #fef2f2; border-color: #ef4444; color: #991b1b; }
.craft-alert-title { font-weight: 600; margin-bottom: 4px; }
.craft-tooltip {
position: relative;
cursor: help;
}
.craft-tooltip::after {
content: attr(data-tooltip);
position: absolute;
bottom: 100%;
left: 50%;
transform: translateX(-50%);
padding: 4px 8px;
background: #1f2937;
color: white;
font-size: 12px;
border-radius: 4px;
white-space: nowrap;
opacity: 0;
pointer-events: none;
transition: opacity 0.2s;
}
.craft-tooltip:hover::after { opacity: 1; }
.craft-table {
width: 100%;
border-collapse: collapse;
}
.craft-table th, .craft-table td {
padding: 12px;
text-align: left;
border-bottom: 1px solid var(--craft-border, #e5e7eb);
}
.craft-table th { font-weight: 600; background: var(--craft-bg-secondary, #f9fafb); }
.craft-list {
list-style: none;
padding: 0;
margin: 0;
}
.craft-list li {
padding: 12px;
border-bottom: 1px solid var(--craft-border, #e5e7eb);
}
.craft-list li:last-child { border-bottom: none; }
.craft-code-editor {
font-family: 'SF Mono', 'Fira Code', monospace;
font-size: 13px;
line-height: 1.5;
padding: 12px;
background: #1e1e1e;
color: #d4d4d4;
border-radius: 6px;
resize: vertical;
}
/* Dark mode support */
@media (prefers-color-scheme: dark) {
.craft-text-input, .craft-textarea, .craft-select, .craft-card {
background: #1f2937;
color: #f3f4f6;
border-color: #374151;
}
.craft-modal {
background: #1f2937;
color: #f3f4f6;
}
.craft-accordion-header { background: #374151; }
.craft-table th { background: #374151; }
}
</style>
`;function a(U,X={}){let{classPrefix:$="craft"}=X;if(!U.includes("craft-component-styles"))if(U.includes("</head>"))U=U.replace("</head>",`
<style id="craft-component-styles">
/* Craft Component Base Styles */
.craft-button {
display: inline-flex;
align-items: center;
justify-content: center;
padding: 8px 16px;
border: none;
border-radius: 6px;
font-family: inherit;
font-size: 14px;
font-weight: 500;
cursor: pointer;
transition: all 0.2s ease;
background: var(--craft-primary, #3b82f6);
color: white;
}
.craft-button:hover { opacity: 0.9; }
.craft-button:disabled { opacity: 0.5; cursor: not-allowed; }
.craft-button-secondary { background: var(--craft-secondary, #6b7280); }
.craft-button-outline { background: transparent; border: 1px solid currentColor; color: var(--craft-primary, #3b82f6); }
.craft-text-input, .craft-textarea, .craft-select {
padding: 8px 12px;
border: 1px solid var(--craft-border, #d1d5db);
border-radius: 6px;
font-family: inherit;
font-size: 14px;
background: var(--craft-bg, #fff);
color: var(--craft-text, #1f2937);
transition: border-color 0.2s ease;
}
.craft-text-input:focus, .craft-textarea:focus, .craft-select:focus {
outline: none;
border-color: var(--craft-primary, #3b82f6);
box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1);
}
.craft-checkbox-wrapper {
display: inline-flex;
align-items: center;
gap: 8px;
cursor: pointer;
}
.craft-checkbox {
width: 18px;
height: 18px;
cursor: pointer;
}
.craft-slider {
width: 100%;
height: 6px;
border-radius: 3px;
cursor: pointer;
}
.craft-badge {
display: inline-flex;
align-items: center;
padding: 2px 8px;
border-radius: 9999px;
font-size: 12px;
font-weight: 500;
background: var(--craft-primary, #3b82f6);
color: white;
}
.craft-avatar {
display: inline-flex;
align-items: center;
justify-content: center;
background: var(--craft-secondary, #6b7280);
color: white;
font-weight: 600;
overflow: hidden;
}
.craft-avatar img { width: 100%; height: 100%; object-fit: cover; }
.craft-progress {
width: 100%;
height: 8px;
background: var(--craft-border, #e5e7eb);
border-radius: 4px;
overflow: hidden;
}
.craft-progress-bar {
height: 100%;
background: var(--craft-primary, #3b82f6);
transition: width 0.3s ease;
}
.craft-spinner {
border: 2px solid var(--craft-border, #e5e7eb);
border-top-color: var(--craft-primary, #3b82f6);
border-radius: 50%;
animation: craft-spin 0.8s linear infinite;
}
@keyframes craft-spin { to { transform: rotate(360deg); } }
.craft-card {
background: var(--craft-bg, #fff);
border: 1px solid var(--craft-border, #e5e7eb);
border-radius: 8px;
padding: 16px;
box-shadow: 0 1px 3px rgba(0,0,0,0.1);
}
.craft-modal {
border: none;
border-radius: 12px;
padding: 0;
max-width: 90vw;
max-height: 90vh;
box-shadow: 0 25px 50px -12px rgba(0,0,0,0.25);
}
.craft-modal::backdrop { background: rgba(0,0,0,0.5); }
.craft-modal-header {
padding: 16px 20px;
border-bottom: 1px solid var(--craft-border, #e5e7eb);
}
.craft-modal-header h2 { margin: 0; font-size: 18px; }
.craft-modal-body { padding: 20px; }
.craft-accordion {
border: 1px solid var(--craft-border, #e5e7eb);
border-radius: 6px;
overflow: hidden;
}
.craft-accordion-header {
padding: 12px 16px;
cursor: pointer;
font-weight: 500;
background: var(--craft-bg-secondary, #f9fafb);
}
.craft-accordion-content { padding: 16px; }
.craft-divider {
border: none;
border-top: 1px solid var(--craft-border, #e5e7eb);
margin: 16px 0;
}
.craft-alert {
padding: 12px 16px;
border-radius: 6px;
border-left: 4px solid;
}
.craft-alert-info { background: #eff6ff; border-color: #3b82f6; color: #1e40af; }
.craft-alert-success { background: #f0fdf4; border-color: #22c55e; color: #166534; }
.craft-alert-warning { background: #fffbeb; border-color: #f59e0b; color: #92400e; }
.craft-alert-error { background: #fef2f2; border-color: #ef4444; color: #991b1b; }
.craft-alert-title { font-weight: 600; margin-bottom: 4px; }
.craft-tooltip {
position: relative;
cursor: help;
}
.craft-tooltip::after {
content: attr(data-tooltip);
position: absolute;
bottom: 100%;
left: 50%;
transform: translateX(-50%);
padding: 4px 8px;
background: #1f2937;
color: white;
font-size: 12px;
border-radius: 4px;
white-space: nowrap;
opacity: 0;
pointer-events: none;
transition: opacity 0.2s;
}
.craft-tooltip:hover::after { opacity: 1; }
.craft-table {
width: 100%;
border-collapse: collapse;
}
.craft-table th, .craft-table td {
padding: 12px;
text-align: left;
border-bottom: 1px solid var(--craft-border, #e5e7eb);
}
.craft-table th { font-weight: 600; background: var(--craft-bg-secondary, #f9fafb); }
.craft-list {
list-style: none;
padding: 0;
margin: 0;
}
.craft-list li {
padding: 12px;
border-bottom: 1px solid var(--craft-border, #e5e7eb);
}
.craft-list li:last-child { border-bottom: none; }
.craft-code-editor {
font-family: 'SF Mono', 'Fira Code', monospace;
font-size: 13px;
line-height: 1.5;
padding: 12px;
background: #1e1e1e;
color: #d4d4d4;
border-radius: 6px;
resize: vertical;
}
/* Dark mode support */
@media (prefers-color-scheme: dark) {
.craft-text-input, .craft-textarea, .craft-selec