@cometchat/card-builder
Advanced tools
| export default function App(): import("react/jsx-runtime").JSX.Element; |
| import type { MessageData } from '../types/schema'; | ||
| import type { CardVariable } from '../config/builder-config'; | ||
| export interface ApiTemplate { | ||
| id: string; | ||
| name: string; | ||
| description?: string; | ||
| schemaVersion: string; | ||
| messageData: MessageData; | ||
| thumbnail?: string; | ||
| createdBy?: string; | ||
| createdAt: number; | ||
| updatedAt: number; | ||
| } | ||
| export interface ApiListMeta { | ||
| previous?: { | ||
| affix: string; | ||
| createdAt: number; | ||
| }; | ||
| current: { | ||
| limit: number; | ||
| count: number; | ||
| }; | ||
| next?: { | ||
| affix: string; | ||
| createdAt: number; | ||
| }; | ||
| } | ||
| export interface ApiError { | ||
| code: string; | ||
| message: string; | ||
| details?: string[]; | ||
| } | ||
| export declare function listTemplates(params?: { | ||
| limit?: number; | ||
| affix?: 'prepend' | 'append'; | ||
| createdAt?: number; | ||
| search?: string; | ||
| }): Promise<{ | ||
| data: ApiTemplate[]; | ||
| meta: ApiListMeta; | ||
| }>; | ||
| export declare function getTemplate(id: string): Promise<{ | ||
| data: ApiTemplate; | ||
| }>; | ||
| export declare function createTemplate(body: { | ||
| name: string; | ||
| description?: string; | ||
| messageData: MessageData; | ||
| thumbnail?: string; | ||
| createdBy?: string; | ||
| }): Promise<{ | ||
| data: ApiTemplate; | ||
| }>; | ||
| export declare function updateTemplate(id: string, body: { | ||
| name?: string; | ||
| description?: string; | ||
| messageData?: MessageData; | ||
| }): Promise<{ | ||
| data: ApiTemplate; | ||
| }>; | ||
| export declare function deleteTemplate(id: string): Promise<{ | ||
| data: { | ||
| success: boolean; | ||
| }; | ||
| }>; | ||
| export declare function listVariables(): Promise<{ | ||
| data: CardVariable[]; | ||
| }>; | ||
| export declare function createVariable(variable: CardVariable): Promise<{ | ||
| data: CardVariable; | ||
| }>; | ||
| export declare function updateVariableApi(name: string, variable: CardVariable): Promise<{ | ||
| data: CardVariable; | ||
| }>; | ||
| export declare function deleteVariable(name: string): Promise<{ | ||
| data: { | ||
| success: boolean; | ||
| }; | ||
| }>; |
| @import "https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@20..48,100..700,0..1,-50..200";.bb-root .tl-container{max-width:61.4286rem;margin:0 auto;padding:4.57143rem 1.71429rem}.bb-root .tl-header{text-align:center;margin-bottom:3.14286rem}.bb-root .tl-logo{background:var(--accent-primary);color:#fff;border-radius:.85714rem;justify-content:center;align-items:center;width:3.42857rem;height:3.42857rem;margin:0 auto 1.14286rem;font-size:1.14286rem;font-weight:800;display:flex}.bb-root .tl-title{color:var(--text-primary);font-size:1.14286rem;font-weight:700}.bb-root .tl-subtitle{color:var(--text-secondary);margin-top:.42857rem;font-size:1rem}.bb-root .tl-actions{gap:.71429rem;margin-bottom:2.57143rem;display:flex}.bb-root .tl-search{flex:1}.bb-root .tl-section{margin-bottom:2.57143rem}.bb-root .tl-section-title{color:#141414;margin-bottom:.85714rem;font-size:1rem;font-weight:600}.bb-root .tl-grid{grid-template-columns:repeat(auto-fill,minmax(13.5714rem,1fr));gap:.71429rem;display:grid}.bb-root .tl-card{text-align:left;box-shadow:none;background:#fff;border:1px solid #e9eaeb;border-radius:.57143rem;padding:1.14286rem;transition:all .15s}.bb-root .tl-card:hover{border-color:var(--accent-primary);box-shadow:var(--shadow-sm)}.bb-root .tl-card-badge{text-transform:uppercase;letter-spacing:.5px;color:var(--accent-primary);margin-bottom:.42857rem;font-size:.78571rem;font-weight:700}.bb-root .tl-card-name{color:#141414;font-size:1rem;font-weight:600}.bb-root .tl-card-desc{color:#727272;margin-top:.14286rem;font-size:.85714rem}.bb-root .tl-card-date{color:#bfbfbc;margin-top:.28571rem;font-size:.78571rem}.bb-root .tl-card{position:relative}.bb-root .tl-card-delete{width:1.57143rem;height:1.57143rem;color:var(--text-tertiary);cursor:pointer;opacity:0;background:0 0;border:none;border-radius:.28571rem;justify-content:center;align-items:center;font-size:1rem;transition:all .15s;display:flex;position:absolute;top:.57143rem;right:.57143rem}.bb-root .tl-card:hover .tl-card-delete{opacity:1}.bb-root .tl-card-delete:hover{color:#dc2626;background:#fee2e2}.bb-root .tl-pagination{justify-content:space-between;align-items:center;margin-top:1.14286rem;display:flex}.bb-root .tl-loading{text-align:center;color:var(--text-tertiary);padding:2.85714rem 1.42857rem;font-size:.92857rem}.bb-root .topbar{background:var(--bg-primary);border-bottom:1px solid var(--border-subtle);flex-shrink:0;justify-content:space-between;align-items:center;height:4rem;padding:0 1.42857rem;display:flex;position:relative}.bb-root .topbar-left{align-items:center;gap:.85714rem;display:flex}.bb-root .topbar-back{border-radius:var(--radius-sm);color:var(--text-secondary);padding:.28571rem .42857rem;font-size:1.28571rem}.bb-root .topbar-back:hover{background:var(--bg-tertiary);color:var(--text-primary)}.bb-root .topbar-logo{align-items:center;gap:.57143rem;display:flex}.bb-root .topbar-logo-icon{background:var(--accent-primary);color:#fff;border-radius:.42857rem;justify-content:center;align-items:center;width:1.71429rem;height:1.71429rem;font-size:.64286rem;font-weight:800;display:flex}.bb-root .topbar-logo span{color:var(--text-primary);letter-spacing:-.3px;font-size:1.14286rem;font-weight:600}.bb-root .topbar-sep{background:var(--border-medium);width:1px;height:1.14286rem}.bb-root .topbar-title{color:var(--text-secondary);font-size:1rem;font-weight:500}.bb-root .topbar-name{border-radius:var(--radius-sm);min-width:10rem;max-width:14.2857rem;color:var(--text-primary);box-shadow:none;background:0 0;border:1px solid #0000;padding:.42857rem .57143rem;font-size:1rem;font-weight:500}.bb-root .topbar-name:hover{border-color:var(--border-medium)}.bb-root .topbar-name:focus{border-color:var(--accent-primary)}.bb-root .topbar-dirty{color:var(--accent-primary);font-size:.57143rem}.bb-root .topbar-right{align-items:center;gap:.57143rem;display:flex}.bb-root .topbar-btn{color:#414651;background:#fff;border-radius:.57143rem;outline:1px solid #d5d7da;align-items:center;gap:.42857rem;height:2.57143rem;padding:0 1.14286rem;font-size:1rem;font-weight:600;line-height:1.333;transition:all .15s;display:flex}.bb-root .topbar-btn:hover{background:#f5f5f5}.bb-root .topbar-toast{color:#fff;background:var(--success);z-index:2000;border-radius:.57143rem;align-items:center;gap:.57143rem;padding:.85714rem 1.42857rem;font-size:1rem;font-weight:500;display:flex;position:fixed;bottom:1.71429rem;left:50%;transform:translate(-50%);box-shadow:0 .28571rem .85714rem #00000026}.bb-root .modal-subtitle{color:var(--text-secondary);text-transform:uppercase;letter-spacing:.5px;margin:.85714rem 0 .57143rem;font-size:.78571rem;font-weight:600}.bb-root .modal-field{margin-bottom:.85714rem}.bb-root .modal-label{color:var(--text-secondary);margin-bottom:.42857rem;font-size:.85714rem;font-weight:500;display:block}.bb-root .topbar-btn-icon{border-radius:var(--radius-sm);width:2.28571rem;height:2.28571rem;color:var(--text-secondary);justify-content:center;align-items:center;font-size:1.14286rem;transition:all .15s;display:flex}.bb-root .topbar-btn-icon:hover:not(:disabled){background:var(--bg-tertiary);color:var(--text-primary)}.bb-root .topbar-btn-icon:disabled{opacity:.3;cursor:default}.bb-root .topbar-btn-warn{color:#d97706;background:#fffbeb;border-color:#fcd34d}.bb-root .topbar-btn-warn:hover{background:#fef3c7}.bb-root .topbar-errors{border:1px solid var(--border-subtle);border-radius:var(--radius-lg);z-index:100;min-width:20rem;max-height:14.2857rem;box-shadow:var(--shadow-lg);background:#fff;margin-top:.57143rem;padding:.57143rem;font-size:.85714rem;position:absolute;top:100%;right:0;overflow-y:auto}.bb-root .topbar-error-item{border-radius:.28571rem;flex-direction:column;gap:.14286rem;padding:.42857rem .57143rem;display:flex}.bb-root .topbar-error-item:hover{background:#fef3c7}.bb-root .topbar-error-path{font-family:var(--font-mono);color:#d97706;font-size:.71429rem}.bb-root .topbar-dropdown{position:relative}.bb-root .topbar-dropdown-menu{background:var(--bg-primary);border:1px solid var(--border-subtle);border-radius:var(--radius-md);z-index:100;min-width:12.8571rem;box-shadow:var(--shadow-lg);margin-top:.42857rem;padding:.28571rem;position:absolute;top:100%;right:0}.bb-root .topbar-dropdown-item{width:100%;color:var(--text-primary);border-radius:var(--radius-sm);cursor:pointer;text-align:left;background:0 0;border:none;align-items:center;gap:.57143rem;padding:.57143rem .85714rem;font-size:.92857rem;font-weight:400;display:flex}.bb-root .topbar-dropdown-item:hover{background:var(--bg-tertiary)}.bb-root .left-panel{background:var(--bg-primary);border-right:1px solid var(--border-subtle);flex-direction:column;flex-shrink:0;width:22.8571rem;min-width:18.5714rem;max-width:28.5714rem;font-size:1rem;display:flex;overflow:hidden}.bb-root .lp-header{padding:.85714rem .85714rem .57143rem}.bb-root .lp-tabs{background:var(--bg-tertiary);border-radius:.57143rem;grid-template-columns:1fr 1fr;gap:.14286rem;padding:.21429rem;display:grid}.bb-root .lp-tab{height:2.57143rem;color:var(--text-secondary);background:0 0;border-radius:.42857rem;justify-content:center;align-items:center;gap:.42857rem;font-size:.92857rem;font-weight:500;transition:all .15s;display:flex}.bb-root .lp-tab:hover{color:var(--text-primary)}.bb-root .lp-tab.active{background:var(--bg-primary);color:var(--text-primary);box-shadow:0 1px .21429rem #00000014}.bb-root .lp-search-wrap{padding:0 .85714rem .57143rem;position:relative}.bb-root .lp-search-icon{color:var(--text-muted);pointer-events:none;margin-top:-.28571rem;position:absolute;top:50%;left:1.57143rem;transform:translateY(-50%)}.bb-root .lp-search{border:1px solid var(--border-subtle);width:100%;height:2.57143rem;color:var(--text-primary);background:#fafafa;border-radius:.57143rem;padding:0 2.28571rem 0 2.57143rem;font-size:.92857rem;transition:all .15s}.bb-root .lp-search::placeholder{color:var(--text-muted)}.bb-root .lp-search:focus{background:var(--bg-primary);border-color:var(--accent-primary);outline:none;box-shadow:0 0 0 .14286rem #6852d614}.bb-root .lp-search-clear{background:var(--border-medium);width:1.42857rem;height:1.42857rem;color:var(--text-secondary);border-radius:50%;justify-content:center;align-items:center;margin-top:-.28571rem;transition:background .15s;display:flex;position:absolute;top:50%;right:1.42857rem;transform:translateY(-50%)}.bb-root .lp-search-clear:hover{background:var(--text-muted);color:var(--text-primary)}.bb-root .lp-content{flex:1;padding:.28571rem .57143rem .85714rem;overflow-y:auto}.bb-root .lp-group{margin-bottom:.14286rem}.bb-root .lp-group-header{width:100%;color:var(--text-secondary);cursor:pointer;border-radius:.57143rem;align-items:center;gap:.57143rem;padding:.71429rem;font-size:.92857rem;font-weight:600;transition:all .15s;display:flex}.bb-root .lp-group-header:hover{background:var(--bg-tertiary);color:var(--text-primary)}.bb-root .lp-group-header.open{color:var(--text-primary);background:var(--bg-tertiary);font-weight:600}.bb-root .lp-group-header.open .lp-group-icon{color:var(--text-primary)}.bb-root .lp-group-icon{color:var(--text-secondary);transition:color .15s}.bb-root .lp-group-label{text-align:left;flex:1}.bb-root .lp-group-count{color:var(--text-secondary);font-variant-numeric:tabular-nums;font-size:.78571rem;font-weight:500}.bb-root .lp-group-header.open .lp-group-count{color:var(--text-secondary)}.bb-root .lp-group-chevron{color:var(--text-muted);transition:transform .2s,color .15s}.bb-root .lp-group-chevron.collapsed{transform:rotate(-90deg)}.bb-root .lp-group-header.open .lp-group-chevron{color:var(--text-secondary)}.bb-root .lp-group-items{flex-direction:column;gap:.14286rem;margin-left:1.28571rem;padding:.57143rem 0 .28571rem;display:flex;position:relative}.bb-root .lp-group-items:before{content:"";background:var(--border-subtle);width:1px;position:absolute;top:0;bottom:2rem;left:0}.bb-root .lp-item{text-align:left;border:1px solid #0000;border-radius:.57143rem;align-items:center;gap:.71429rem;width:calc(100% - .85714rem);margin-left:.85714rem;padding:.57143rem .71429rem;transition:all .15s;display:flex;position:relative}.bb-root .lp-item:before{content:"";background:var(--border-subtle);width:.85714rem;height:1px;position:absolute;top:50%;left:-.85714rem}.bb-root .lp-item:hover{background:var(--bg-hover);border-color:var(--border-subtle)}.bb-root .lp-item-icon-wrap{background:var(--bg-tertiary);width:2rem;height:2rem;color:var(--text-secondary);border-radius:.42857rem;flex-shrink:0;justify-content:center;align-items:center;display:flex}.bb-root .lp-item-title{color:var(--text-primary);white-space:nowrap;text-overflow:ellipsis;font-size:13px;font-weight:500;overflow:hidden}.bb-root .lp-item--component{align-items:flex-start}.bb-root .lp-item-info{flex-direction:column;flex:1;gap:.14286rem;min-width:0;display:flex}.bb-root .lp-item-sub{color:var(--text-secondary);white-space:nowrap;text-overflow:ellipsis;font-size:12px;line-height:1.3;overflow:hidden}.bb-root .lp-empty{text-align:center;flex-direction:column;justify-content:center;align-items:center;padding:2.85714rem 1.42857rem;display:flex}.bb-root .lp-empty-icon{color:var(--border-medium);margin-bottom:.57143rem}.bb-root .lp-empty-title{color:var(--text-secondary);font-size:.92857rem;font-weight:500}.bb-root .lp-empty-sub{color:var(--text-muted);margin-top:.28571rem;font-size:.85714rem}.bb-root .lp-footer{border-top:1px dashed var(--border-subtle);padding:.71429rem}.bb-root .lp-footer-drop{border:1px dashed var(--border-subtle);color:var(--text-secondary);cursor:pointer;border-radius:.57143rem;justify-content:center;align-items:center;gap:.42857rem;padding:.71429rem;font-size:.89286rem;font-weight:500;transition:all .15s;display:flex}.bb-root .lp-footer-drop:hover{border-color:var(--border-medium);color:var(--text-primary);background:var(--bg-tertiary)}.bb-root .canvas{background:var(--bg-secondary);flex-direction:column;flex:1;display:flex;position:relative;overflow:hidden}.bb-root .canvas-area{background:radial-gradient(circle at 1px 1px,#d4d4d8 1px,#0000 0) 0 0/1rem 1rem;flex:1;justify-content:center;align-items:center;padding:2.28571rem 1.71429rem;display:flex;overflow:auto}.bb-root .phone-frame{background:#fff;border-radius:24px;flex-direction:column;flex-shrink:0;width:340px;height:700px;max-height:700px;display:flex;position:relative;overflow:hidden;box-shadow:0 0 0 1px #0000000f,0 2px 4px #0000000a,0 12px 32px #00000014,0 32px 64px #0000000f}.bb-root .phone-frame:before{content:none}.bb-root .phone-screen{background:#fafafa;flex-direction:column;height:100%;margin-top:0;display:flex;overflow:hidden}.bb-root .chat-header{background:#fff;border-bottom:1px solid #0000000f;align-items:center;padding:20px 16px 14px;display:flex}.bb-root .chat-back-btn{color:var(--text-secondary);opacity:.6;padding:2px 4px;font-size:20px}.bb-root .chat-user{flex:1;align-items:center;gap:10px;margin-left:10px;display:flex}.bb-root .chat-avatar{color:#fff;background:linear-gradient(135deg,#6852d6,#8b7ae8);border-radius:50%;justify-content:center;align-items:center;width:36px;height:36px;font-size:14px;font-weight:600;display:flex;box-shadow:0 2px 8px #6852d64d}.bb-root .chat-name{color:var(--text-primary);letter-spacing:-.01em;font-size:14px;font-weight:600}.bb-root .chat-messages{background:#fafafa;flex-direction:column;flex:1;gap:12px;min-height:0;padding:16px;display:flex;overflow:hidden auto}.bb-root .message-date{text-align:center;color:var(--text-tertiary);-webkit-backdrop-filter:blur(.57143rem);backdrop-filter:blur(.57143rem);letter-spacing:.02em;background:#fffc;border-radius:.85714rem;align-self:center;padding:.35714rem .85714rem;font-size:.78571rem;font-weight:500}.bb-root .bubble-preview{flex-shrink:0;align-self:flex-start;width:100%;min-height:50px;position:relative;overflow:visible}.bb-root .canvas-bubble{border-radius:16px 16px 16px 4px;flex-direction:column;gap:2px;display:flex;overflow:visible;box-shadow:0 1px 2px #0000000f,0 1px 3px #0000000a}.bb-root .canvas-empty{color:var(--text-tertiary);text-align:center;border:.14286rem dashed var(--border-medium);background-color:#fff;border-radius:1.14286rem;flex-direction:column;justify-content:center;align-items:center;gap:.85714rem;margin:auto .85714rem;padding:2.28571rem 1.42857rem;font-size:.92857rem;display:flex}.bb-root .canvas-empty-template-btn{background:var(--bg-tertiary);border:1px solid var(--border-subtle);color:#404040;cursor:pointer;border-radius:.57143rem;margin-top:.85714rem;padding:.57143rem 1.14286rem;font-size:.92857rem;font-weight:600;transition:all .15s}.bb-root .canvas-empty-template-btn:hover{border-color:var(--accent-primary);background:var(--accent-light);color:var(--accent-primary)}.bb-root .canvas-empty-circle{background:#f5f5f5;border-radius:50%;justify-content:center;align-items:center;width:3.42857rem;height:3.42857rem;display:flex}.bb-root .canvas-empty-plus{color:#a3a3a3;font-size:1.71429rem;font-weight:300}.bb-root .canvas-empty-title{color:var(--text-primary);font-size:1rem;font-weight:600}.bb-root .canvas-empty-sub{color:#404040;font-size:.92857rem}.bb-root .chat-input-area{background:#fff;border-top:1px solid #0000000f;align-items:center;gap:10px;padding:10px 14px;display:flex}.bb-root .chat-input{border:1px solid var(--border-subtle);color:var(--text-primary);background:#f5f6f7;border-radius:20px;flex:1;padding:9px 16px;font-size:13px}.bb-root .chat-send-btn{background:var(--accent-primary);color:#fff;border-radius:50%;justify-content:center;align-items:center;width:34px;height:34px;font-size:13px;transition:transform .15s,box-shadow .15s;display:flex;box-shadow:0 2px 8px #6852d64d}.bb-root .chat-send-btn:hover{transform:scale(1.05);box-shadow:0 4px 12px #6852d666}.bb-root .el-wrapper{cursor:pointer;border-radius:4px;width:100%;transition:all .12s;position:relative;overflow:visible}.bb-root .el-wrapper:hover{background:#6852d60a}.bb-root .el-wrapper.selected{outline:2px solid var(--accent-primary);outline-offset:-2px;background:#6852d60a}.bb-root .el-wrapper.multi-selected{outline:2px dashed var(--accent-primary);outline-offset:-2px;background:#6852d60a}.bb-root .el-controls-portal{z-index:9999;background:#fff;border-radius:.57143rem;flex-direction:row;gap:.14286rem;padding:.21429rem;display:flex;box-shadow:0 .14286rem .85714rem #0000001f,0 0 0 1px #0000000a}.bb-root .preview-mode .el-controls-portal{display:none}.bb-root .el-ctrl-btn{width:1.85714rem;height:1.85714rem;color:var(--text-secondary);border-radius:.35714rem;justify-content:center;align-items:center;font-size:.92857rem;transition:all .12s;display:flex}.bb-root .el-ctrl-btn:hover{background:var(--bg-tertiary);color:var(--text-primary)}.bb-root .el-ctrl-btn.danger:hover{color:#dc2626;background:#fee2e2}.bb-root .el-wrap-menu{border:1px solid var(--border-subtle);z-index:1001;background:#fff;border-radius:.71429rem;min-width:10rem;margin-bottom:.28571rem;padding:.28571rem;position:absolute;bottom:100%;right:0;box-shadow:0 .57143rem 1.71429rem #0000001f}.bb-root .el-wrap-option{text-align:left;color:var(--text-secondary);white-space:nowrap;border-radius:.42857rem;width:100%;padding:.5rem .85714rem;font-size:.85714rem}.bb-root .el-wrap-option:hover{background:var(--accent-light);color:var(--accent-primary)}.bb-root .canvas-breadcrumbs{border-bottom:1px solid var(--border-subtle);background:#fff;flex-wrap:wrap;align-items:center;gap:.14286rem;padding:.42857rem 1.14286rem;font-size:.85714rem;display:flex}.bb-root .canvas-bc-sep{color:var(--text-muted);margin:0 .14286rem;font-size:.71429rem}.bb-root .canvas-bc-item{color:var(--text-secondary);font-size:.78571rem;font-family:var(--font-mono);border-radius:.28571rem;padding:.14286rem .57143rem}.bb-root .canvas-bc-item:hover{background:var(--bg-tertiary);color:var(--text-primary)}.bb-root .canvas-bc-item.active{color:var(--accent-primary);background:var(--accent-light)}.bb-root .multi-select-bar{border:1px solid var(--border-subtle);z-index:100;background:#fff;border-radius:.85714rem;align-items:center;gap:.57143rem;padding:.57143rem 1.14286rem;font-size:.92857rem;display:flex;position:absolute;bottom:4.28571rem;left:50%;transform:translate(-50%);box-shadow:0 .57143rem 1.71429rem #0000001f}.bb-root .multi-select-bar span{color:var(--text-secondary);white-space:nowrap}.bb-root .multi-select-bar button{background:var(--accent-light);color:var(--accent-primary);white-space:nowrap;border-radius:.42857rem;padding:.42857rem .85714rem;font-size:.85714rem;font-weight:600;transition:all .15s}.bb-root .multi-select-bar button:hover{background:var(--accent-primary);color:#fff}.bb-root .canvas-bubble ::-webkit-scrollbar{height:3px}.bb-root .canvas-bubble ::-webkit-scrollbar-track{background:0 0}.bb-root .canvas-bubble ::-webkit-scrollbar-thumb{background:#00000026;border-radius:2px}.bb-root .canvas-toolbar{border-top:1px solid var(--border-subtle);background:#fff;flex-shrink:0;justify-content:center;align-items:center;gap:.28571rem;padding:.42857rem .85714rem;font-size:.85714rem;display:flex}.bb-root .canvas-tool-btn{width:2rem;height:2rem;color:var(--text-secondary);border-radius:.42857rem;justify-content:center;align-items:center;font-size:1rem;transition:all .12s;display:flex}.bb-root .canvas-tool-btn:hover{background:var(--bg-tertiary);color:var(--text-primary)}.bb-root .canvas-tool-btn.active{background:var(--accent-light);color:var(--accent-primary)}.bb-root .canvas-tool-label{color:var(--text-secondary);text-align:center;min-width:2.57143rem;font-size:.78571rem}.bb-root .canvas-tool-sep{background:var(--border-medium);width:1px;height:1.14286rem;margin:0 .28571rem}.bb-root .preview-mode .el-wrapper{cursor:default}.bb-root .preview-mode .el-wrapper:hover{background:0 0}.bb-root .preview-mode .el-wrapper.selected,.bb-root .preview-mode .el-wrapper.multi-selected{background:0 0;outline:none}.bb-root .preview-mode .canvas-breadcrumbs,.bb-root .preview-mode .multi-select-bar{display:none}.bb-root .json-preview-panel{background:var(--bg-primary);border-left:1px solid var(--border-subtle);z-index:60;flex-direction:column;width:27.1429rem;display:flex;position:absolute;top:0;bottom:0;right:0;box-shadow:-.28571rem 0 1.71429rem #0000000f}.bb-root .json-preview-header{border-bottom:1px solid var(--border-subtle);color:var(--text-primary);background:var(--bg-secondary);align-items:center;gap:.57143rem;padding:.85714rem 1.14286rem;font-size:.92857rem;font-weight:600;display:flex}.bb-root .json-preview-header span{flex:1}.bb-root .json-preview-header button{width:2rem;height:2rem;color:var(--text-secondary);background:0 0;border:none;border-radius:.28571rem;justify-content:center;align-items:center;font-size:1rem;display:flex}.bb-root .json-preview-header button:hover{background:var(--bg-tertiary);color:var(--text-primary)}.bb-root .json-preview-code{font-family:var(--font-mono);color:var(--text-primary);white-space:pre;tab-size:2;background:var(--bg-primary);flex:1;margin:0;padding:1.14286rem;font-size:.85714rem;line-height:1.6;overflow:auto}.bb-root .el-context-menu{background:var(--bg-primary);border:1px solid var(--border-subtle);border-radius:.71429rem;min-width:11.4286rem;padding:.28571rem;font-size:.85714rem;box-shadow:0 .57143rem 1.71429rem #0000001f}.bb-root .el-ctx-item{text-align:left;width:100%;color:var(--text-secondary);white-space:nowrap;border-radius:.42857rem;padding:.42857rem .85714rem;display:block}.bb-root .el-ctx-item:hover{background:var(--bg-tertiary);color:var(--text-primary)}.bb-root .el-ctx-item.danger:hover{color:#dc2626;background:#fee2e2}.bb-root .el-ctx-sep{background:var(--border-subtle);height:1px;margin:.28571rem 0}.bb-root .canvas-side-toolbar{z-index:50;flex-direction:column;align-items:center;gap:1.71429rem;display:flex;position:absolute;top:50%;right:.85714rem;transform:translateY(-50%)}.bb-root .canvas-side-group{border:1px solid var(--border-subtle);background:#fff;border-radius:.85714rem;flex-direction:column;padding:.28571rem;display:flex;box-shadow:0 1px .21429rem #0000000f}.bb-root .canvas-side-btn{width:2.57143rem;height:2.57143rem;color:var(--text-secondary);border-radius:.57143rem;justify-content:center;align-items:center;transition:all .15s;display:flex}.bb-root .canvas-side-btn:hover{background:var(--bg-tertiary);color:var(--text-primary)}.bb-root .canvas-side-btn.active{background:var(--accent-light);color:var(--accent-primary)}.bb-root .canvas.read-only .canvas-area{pointer-events:none}.bb-root .canvas.read-only .canvas-area *{pointer-events:none;-webkit-user-select:none;user-select:none;cursor:default!important}.bb-root .canvas.read-only .chat-messages{pointer-events:auto;overflow-y:auto}.bb-root .canvas.read-only .canvas-side-toolbar{display:none}.bb-root .prop-field--row{align-items:flex-start;gap:.85714rem;display:flex}.bb-root .prop-field--row>.prop-label{flex-shrink:0;width:7.14286rem;margin-bottom:0;padding-top:.57143rem}.bb-root .prop-field--row>.prop-field-input{flex:1;min-width:0}.bb-root .prop-color-row{align-items:center;gap:.71429rem;display:flex}.bb-root .prop-color-pair{align-items:center;gap:.42857rem;display:flex}.bb-root .prop-color-circle{cursor:pointer;border:1px solid var(--border-subtle);border-radius:.57143rem;flex-shrink:0;width:2.28571rem;height:2.28571rem;transition:border-color .15s;position:relative}.bb-root .prop-color-circle:hover{border-color:var(--border-medium)}.bb-root .prop-color-circle input[type=color]{cursor:pointer;opacity:0;border:none;border-radius:.57143rem;width:100%;height:100%;padding:0;position:absolute;top:0;left:0}.bb-root .prop-color-tag{-webkit-user-select:none;user-select:none;border-radius:.28571rem;padding:.21429rem .42857rem;font-size:.71429rem;font-weight:600;line-height:1}.bb-root .prop-color-tag--light{background:var(--bg-tertiary);color:var(--text-secondary);border:1px solid var(--border-subtle)}.bb-root .prop-color-tag--dark{color:#adb5bd;background:#1a1a1a;border:1px solid #495057}.bb-root .prop-color-clear{width:1.71429rem;height:1.71429rem;color:var(--text-tertiary);background:var(--bg-tertiary);border:1px solid var(--border-subtle);cursor:pointer;border-radius:.42857rem;justify-content:center;align-items:center;font-size:.85714rem;transition:all .15s;display:flex}.bb-root .prop-color-clear:hover{color:#dc2626;background:#fef2f2;border-color:#fecaca}.bb-root .prop-padding-row{align-items:center;gap:.42857rem;display:flex}.bb-root .prop-padding-row input{flex:1}.bb-root .prop-padding-toggle{border:1px solid var(--border-subtle);width:40px;height:40px;color:var(--text-muted);background:var(--bg-primary);cursor:pointer;border-radius:.57143rem;flex-shrink:0;justify-content:center;align-items:center;transition:all .15s;display:flex}.bb-root .prop-padding-toggle:hover{background:var(--bg-tertiary);color:var(--text-primary);border-color:var(--border-medium)}.bb-root .prop-padding-toggle.active{background:var(--accent-light);color:var(--accent-primary);border-color:#6852d64d}.bb-root .prop-padding-grid{grid-template-columns:1fr 1fr;gap:.57143rem;margin-top:.57143rem;display:grid}.bb-root .prop-padding-grid label{color:var(--text-secondary);text-transform:uppercase;letter-spacing:.5px;margin-bottom:.28571rem;font-size:.75rem;font-weight:500;display:block}.bb-root .prop-select-wrap{position:relative}.bb-root .prop-select-wrap select{appearance:none;padding-right:2.28571rem}.bb-root .prop-select-arrow{pointer-events:none;color:var(--text-muted);position:absolute;top:50%;right:.71429rem;transform:translateY(-50%)}.bb-root .prop-input-number{-moz-appearance:textfield}.bb-root .prop-input-number::-webkit-outer-spin-button{-webkit-appearance:none;margin:0}.bb-root .prop-input-number::-webkit-inner-spin-button{-webkit-appearance:none;margin:0}.bb-root .prop-color-section{flex-direction:column;gap:.57143rem;display:flex}.bb-root .prop-color-swatch-row{align-items:center;gap:.71429rem;display:flex}.bb-root .prop-color-swatch{cursor:pointer;border:1px solid var(--border-subtle);border-radius:.57143rem;flex-shrink:0;width:40px;height:40px;transition:border-color .15s;position:relative}.bb-root .prop-color-swatch input[type=color]{cursor:pointer;opacity:0;border:none;border-radius:.57143rem;width:100%;height:100%;padding:0;position:absolute;top:0;left:0}.bb-root .prop-input-hex{flex:1;font-size:13px}.bb-root .prop-padding-wrap{flex-direction:column;gap:.57143rem;width:100%;display:flex}.bb-root .prop-padding-wrap .prop-padding-grid{margin-left:0}.bb-root .prop-align-group{border:1px solid var(--border-subtle);border-radius:.57143rem;display:flex;overflow:hidden}.bb-root .prop-align-btn{background:var(--bg-primary);height:40px;color:var(--text-secondary);border-right:1px solid var(--border-subtle);flex:1;justify-content:center;align-items:center;transition:all .15s;display:flex}.bb-root .prop-align-btn:last-child{border-right:none}.bb-root .prop-align-btn:hover{background:var(--bg-tertiary);color:var(--text-primary)}.bb-root .prop-align-btn.active{background:var(--accent-light);color:var(--accent-primary)}.bb-root .prop-switch{cursor:pointer;align-items:center;gap:.85714rem;padding:.42857rem 0;display:flex}.bb-root .prop-switch-track{background:var(--border-medium);border-radius:.71429rem;flex-shrink:0;width:2.57143rem;height:1.42857rem;transition:background .2s;position:relative}.bb-root .prop-switch-track.on{background:var(--accent-primary)}.bb-root .prop-switch-thumb{background:#fff;border-radius:50%;width:1.14286rem;height:1.14286rem;transition:transform .2s;position:absolute;top:.14286rem;left:.14286rem;box-shadow:0 1px .21429rem #00000026}.bb-root .prop-switch-track.on .prop-switch-thumb{transform:translate(1.14286rem)}.bb-root .prop-switch-label{width:7.14286rem;color:var(--text-tertiary);flex-shrink:0;font-size:13px;font-weight:400}.bb-root .prop-image-preview{object-fit:cover;border:1px solid var(--border-subtle);border-radius:.57143rem;width:100%;max-height:8.57143rem;margin:.28571rem 0 .57143rem}.bb-root .prop-section-header{align-items:center;gap:.57143rem;margin-top:.57143rem;padding:.57143rem 0;display:flex}.bb-root .prop-section-header .material-symbols-outlined{color:var(--text-muted)}.bb-root .prop-color-header{justify-content:space-between;align-items:center;margin-bottom:1.14286rem;display:flex}.bb-root .prop-color-field{align-items:flex-start;gap:.85714rem;margin-bottom:.85714rem;display:flex}.bb-root .prop-color-field-label{width:7.14286rem;color:var(--text-tertiary);flex-shrink:0;padding-top:.57143rem;font-size:13px;font-weight:400}.bb-root .prop-color-field-input{flex:1;align-items:center;gap:.71429rem;min-width:0;display:flex}.bb-root .prop-image-upload-placeholder{border:.14286rem dashed var(--border-medium);background:var(--bg-tertiary);cursor:pointer;border-radius:.57143rem;flex-direction:column;justify-content:center;align-items:center;width:100%;height:8.57143rem;margin-bottom:.85714rem;transition:all .15s;display:flex}.bb-root .prop-image-upload-placeholder:hover{border-color:var(--accent-primary);background:var(--accent-light)}.bb-root .prop-image-upload-icon{color:var(--text-muted);margin-bottom:.57143rem}.bb-root .prop-image-upload-placeholder:hover .prop-image-upload-icon{color:var(--accent-primary)}.bb-root .prop-image-upload-text{color:var(--text-secondary);font-size:.92857rem;font-weight:500}.bb-root .prop-image-upload-hint{color:var(--text-muted);margin-top:.14286rem;font-size:.78571rem}.bb-root .prop-image-preview-container{border:1px solid var(--border-subtle);cursor:pointer;border-radius:.57143rem;width:100%;height:12.8571rem;margin-bottom:.85714rem;position:relative;overflow:hidden}.bb-root .prop-image-preview-container:hover .prop-image-preview-overlay{opacity:1}.bb-root .prop-image-preview-img{object-fit:contain;background:var(--bg-tertiary);width:100%;height:100%}.bb-root .prop-image-preview-overlay{color:#fff;opacity:0;background:#0000004d;justify-content:center;align-items:center;gap:.42857rem;font-size:.85714rem;font-weight:500;transition:opacity .15s;display:flex;position:absolute;inset:0}.bb-root .prop-image-modal-backdrop{z-index:9999;-webkit-backdrop-filter:blur(.28571rem);backdrop-filter:blur(.28571rem);background:#000000b3;justify-content:center;align-items:center;padding:2.28571rem;display:flex;position:fixed;inset:0}.bb-root .prop-image-modal{background:#fff;border-radius:.85714rem;max-width:90vw;max-height:90vh;position:relative;overflow:hidden;box-shadow:0 1.42857rem 4.28571rem #0000004d}.bb-root .prop-image-modal-img{object-fit:contain;max-width:90vw;max-height:80vh;display:block}.bb-root .prop-image-modal-close{color:#fff;background:#00000080;border-radius:.57143rem;justify-content:center;align-items:center;width:2.57143rem;height:2.57143rem;transition:background .15s;display:flex;position:absolute;top:.85714rem;right:.85714rem}.bb-root .prop-image-modal-close:hover{background:#000000b3}.bb-root .prop-image-modal-footer{color:#fff;background:linear-gradient(#0000,#0009);justify-content:space-between;align-items:center;padding:.85714rem 1.14286rem;font-size:.85714rem;display:flex;position:absolute;bottom:0;left:0;right:0}.bb-root .prop-image-modal-close-btn{color:#fff;background:#fff3;border-radius:.57143rem;align-items:center;gap:.42857rem;padding:.42857rem .85714rem;font-size:.85714rem;font-weight:500;transition:background .15s;display:flex}.bb-root .prop-image-modal-close-btn:hover{background:#ffffff4d}.bb-root .notif-help-box{background:var(--bg-tertiary);color:var(--text-secondary);border-radius:.57143rem;align-items:flex-start;gap:.57143rem;padding:.85714rem;font-size:.89286rem;line-height:1.5;display:flex}.bb-root .notif-help-icon{color:var(--text-muted);flex-shrink:0;margin-top:1px}.bb-root .var-header{justify-content:space-between;align-items:center;display:flex}.bb-root .var-add-btn{background:var(--accent-primary);color:#fff;border-radius:.57143rem;align-items:center;gap:.28571rem;padding:.57143rem 1rem;font-size:.92857rem;font-weight:600;transition:background .15s;display:flex}.bb-root .var-add-btn:hover{background:var(--accent-secondary)}.bb-root .var-empty{text-align:center;flex-direction:column;align-items:center;padding:2.28571rem 1.14286rem;display:flex}.bb-root .var-empty-icon{background:var(--bg-tertiary);width:3.42857rem;height:3.42857rem;color:var(--text-muted);border-radius:1.71429rem;justify-content:center;align-items:center;margin-bottom:.85714rem;display:flex}.bb-root .var-empty-title{color:var(--text-secondary);font-size:.92857rem;font-weight:500}.bb-root .var-empty-sub{color:var(--text-muted);margin-top:.28571rem;font-size:.85714rem}.bb-root .var-count{text-transform:uppercase;letter-spacing:.5px;color:var(--text-secondary);margin-bottom:.85714rem;font-size:.78571rem;font-weight:600}.bb-root .var-list{flex-direction:column;gap:.71429rem;display:flex}.bb-root .var-item{border:1px solid var(--border-subtle);background:#fff;border-radius:.85714rem;transition:border-color .15s,box-shadow .15s;position:relative;overflow:hidden}.bb-root .var-item:hover{border-color:#6852d633;box-shadow:0 1px .21429rem #0000000a}.bb-root .var-item-top{align-items:center;gap:.71429rem;padding:.85714rem 1rem .57143rem;display:flex}.bb-root .var-item-icon{background:var(--accent-light);width:1.71429rem;height:1.71429rem;color:var(--accent-primary);border-radius:.42857rem;flex-shrink:0;justify-content:center;align-items:center;display:flex}.bb-root .var-item-name{color:var(--text-primary);background:#00000008;border-radius:.28571rem;flex:1;padding:.14286rem .57143rem;font-size:.92857rem;font-weight:600}.bb-root .var-item-delete{width:2rem;height:2rem;color:var(--text-muted);opacity:1;border-radius:.57143rem;flex-shrink:0;justify-content:center;align-items:center;transition:all .15s;display:flex}.bb-root .var-item:hover .var-item-delete{color:var(--text-muted)}.bb-root .var-item-delete:hover{background:#fef2f2;color:#dc2626!important}.bb-root .var-item-details{flex-direction:column;gap:.28571rem;padding:0 1rem .85714rem;display:flex}.bb-root .var-item-detail{color:var(--text-secondary);align-items:center;gap:.42857rem;font-size:.85714rem;display:flex}.bb-root .var-item-detail .material-symbols-outlined{color:var(--text-muted)}.bb-root .var-item-category{text-transform:uppercase;letter-spacing:.5px;color:var(--accent-primary);background:var(--accent-light);border-radius:.71429rem;align-self:flex-start;margin-top:.28571rem;padding:.14286rem .57143rem;font-size:.71429rem;font-weight:600}.bb-root .var-delete-overlay{z-index:10;-webkit-backdrop-filter:blur(.14286rem);backdrop-filter:blur(.14286rem);color:var(--text-primary);background:#fffffff2;border:1px solid #fecaca;border-radius:.85714rem;flex-direction:column;justify-content:center;align-items:center;gap:.57143rem;font-size:.85714rem;font-weight:500;display:flex;position:absolute;inset:0}.bb-root .var-delete-icon{color:#dc2626}.bb-root .var-delete-actions{gap:.57143rem;margin-top:.28571rem;display:flex}.bb-root .var-delete-confirm{color:#fff;background:#dc2626;border-radius:.57143rem;padding:.42857rem 1rem;font-size:.85714rem;font-weight:600}.bb-root .var-delete-confirm:hover{background:#b91c1c}.bb-root .var-delete-cancel{border:1px solid var(--border-subtle);color:var(--text-secondary);border-radius:.57143rem;padding:.42857rem 1rem;font-size:.85714rem;font-weight:500}.bb-root .var-delete-cancel:hover{background:var(--bg-tertiary)}.bb-root .var-form{background:#6852d605;border:1px solid #6852d633;border-radius:.85714rem;margin-bottom:.85714rem;padding:1.14286rem}.bb-root .var-form-title{color:var(--text-primary);margin-bottom:.85714rem;font-size:.92857rem;font-weight:600}.bb-root .var-form-actions{gap:.57143rem;margin-top:.85714rem;display:flex}.bb-root .var-form-btn-primary{background:var(--accent-primary);color:#fff;border-radius:.57143rem;padding:.57143rem 1.14286rem;font-size:.85714rem;font-weight:600;transition:background .15s}.bb-root .var-form-btn-primary:hover{background:var(--accent-secondary)}.bb-root .var-form-btn-secondary{border:1px solid var(--border-subtle);color:var(--text-secondary);border-radius:.57143rem;padding:.57143rem 1.14286rem;font-size:.85714rem;font-weight:500;transition:background .15s}.bb-root .var-form-btn-secondary:hover{background:var(--bg-tertiary)}.bb-root .tree-root{font-size:13px}.bb-root .tree-item{text-align:left;width:100%;color:var(--text-secondary);cursor:pointer;border-radius:.57143rem;align-items:center;gap:.42857rem;min-height:2.28571rem;padding:.42857rem .57143rem;transition:all .15s;display:flex;position:relative}.bb-root .tree-item:hover{background:var(--bg-tertiary);color:var(--text-primary)}.bb-root .tree-item.selected{background:var(--bg-tertiary);color:var(--text-primary);transition:none}.bb-root .tree-item:active{background:var(--bg-tertiary);color:var(--text-primary)}.bb-root .tree-item.multi-selected{background:var(--accent-light);color:var(--accent-primary);outline:1px dashed var(--accent-primary);outline-offset:-1px}.bb-root .tree-item.drop-target{outline:.14286rem dashed var(--accent-primary);outline-offset:-.14286rem}.bb-root .tree-item.flash{background:var(--bg-tertiary)}@keyframes tree-flash{0%{background:var(--bg-tertiary)}to{background:0 0}}.bb-root .tree-chevron{width:1.14286rem;height:1.14286rem;color:var(--text-muted);cursor:pointer;border-radius:.28571rem;flex-shrink:0;justify-content:center;align-items:center;transition:color .15s;display:flex}.bb-root .tree-chevron:hover,.bb-root .tree-item.selected .tree-chevron{color:var(--text-primary)}.bb-root .tree-spacer{flex-shrink:0;width:1.14286rem}.bb-root .tree-icon-box{border:1px solid var(--border-subtle);background:var(--bg-primary);width:1.71429rem;height:1.71429rem;color:var(--text-secondary);border-radius:.28571rem;flex-shrink:0;justify-content:center;align-items:center;transition:all .15s;display:flex}.bb-root .tree-item:hover .tree-icon-box{border-color:var(--border-medium)}.bb-root .tree-item.selected .tree-icon-box,.bb-root .tree-item.flash .tree-icon-box{border-color:var(--border-medium);background:var(--bg-tertiary);color:var(--text-primary)}.bb-root .tree-type{font-family:Satoshi,-apple-system,BlinkMacSystemFont,Segoe UI,sans-serif;font-size:12px;font-weight:500}.bb-root .tree-type.is-container{font-weight:600}.bb-root .tree-item.selected .tree-type{color:var(--text-primary)}.bb-root .tree-label{color:var(--text-tertiary);text-overflow:ellipsis;white-space:nowrap;flex:1;font-size:.78571rem;overflow:hidden}.bb-root .tree-badge{background:var(--bg-tertiary);color:var(--text-tertiary);border-radius:.57143rem;flex-shrink:0;margin-left:auto;padding:1px .35714rem;font-size:.64286rem}.bb-root .tree-item.selected .tree-badge{background:var(--border-subtle);color:var(--text-secondary)}.bb-root .tree-error-dot{background:#dc2626;border-radius:50%;flex-shrink:0;width:.42857rem;height:.42857rem;margin-left:auto}.bb-root .tree-badge+.tree-error-dot,.bb-root .tree-error-dot+.tree-badge{margin-left:.28571rem}.bb-root .tree-children{position:relative}.bb-root .tree-children:before{content:"";background:var(--border-subtle);width:1px;position:absolute;top:0;bottom:.85714rem;left:1.35714rem}.bb-root .tree-empty{color:var(--text-tertiary);flex-direction:column;align-items:center;gap:.57143rem;padding:1.71429rem;font-size:.92857rem;display:flex}.bb-root .tree-drag-overlay{background:var(--bg-primary);opacity:.9;border-radius:.57143rem;box-shadow:0 .28571rem .85714rem #00000026}.bb-root .tree-node{touch-action:none}.bb-root .tree-drop-gap{height:.28571rem;transition:height .1s;position:relative}.bb-root .tree-drop-gap.active{height:.57143rem}.bb-root .tree-drop-gap .tree-drop-line{background:0 0;border-radius:1px;height:.14286rem;transition:background .1s}.bb-root .tree-drop-gap.active .tree-drop-line{background:var(--accent-primary)}.bb-root .tree-search-wrap{margin-bottom:.57143rem;position:relative}.bb-root .tree-search-icon{color:var(--text-muted);pointer-events:none;position:absolute;top:50%;left:.71429rem;transform:translateY(-50%)}.bb-root .tree-search{border:1px solid var(--border-subtle);width:100%;color:var(--text-primary);background:#fafafa;border-radius:.57143rem;padding:.57143rem 2rem .57143rem 2.28571rem;font-size:.85714rem}.bb-root .tree-search:focus{border-color:var(--accent-primary);background:var(--bg-primary);outline:none}.bb-root .tree-search::placeholder{color:var(--text-muted)}.bb-root .tree-search-clear{width:1.42857rem;height:1.42857rem;color:var(--text-tertiary);background:var(--border-medium);border-radius:50%;justify-content:center;align-items:center;transition:all .15s;display:flex;position:absolute;top:50%;right:.57143rem;transform:translateY(-50%)}.bb-root .tree-search-clear:hover{color:var(--text-primary);background:var(--text-muted)}.bb-root .right-panel{background:var(--bg-primary);border-left:1px solid var(--border-subtle);flex-direction:column;flex-shrink:0;width:22.8571rem;min-width:18.5714rem;max-width:28.5714rem;font-size:14px;display:flex;overflow:hidden}.bb-root .rp-tabs{border-bottom:1px solid var(--border-subtle);flex-shrink:0;padding:0 .57143rem;display:flex;overflow:hidden}.bb-root .rp-tab{color:var(--text-secondary);white-space:nowrap;background:0 0;flex:1;justify-content:center;align-items:center;padding:.85714rem .57143rem;font-size:.89286rem;font-weight:500;transition:color .15s;display:flex;position:relative}.bb-root .rp-tab:hover{color:var(--text-primary)}.bb-root .rp-tab.active{color:var(--accent-primary);font-weight:500}.bb-root .rp-tab-indicator{background:var(--accent-primary);border-radius:1px;height:.14286rem;position:absolute;bottom:0;left:.57143rem;right:.57143rem}.bb-root .rp-content{flex:1;padding:1.42857rem 1.14286rem;overflow-y:auto}.bb-root .rp-empty{color:var(--text-tertiary);text-align:center;flex-direction:column;justify-content:center;align-items:center;gap:.85714rem;padding:3.42857rem 1.71429rem;display:flex}.bb-root .rp-empty-icon{color:var(--border-medium);font-size:3.42857rem}.bb-root .prop-group{margin-bottom:0;padding-bottom:0}.bb-root .prop-group:last-child{border-bottom:none}.bb-root .prop-group-title{color:var(--text-primary);margin-bottom:1.14286rem;font-size:14px;font-weight:600}.bb-root .prop-field{margin-bottom:.85714rem}.bb-root .prop-label{color:var(--text-tertiary);margin-bottom:.42857rem;font-size:13px;font-weight:400;display:block}.bb-root .prop-row{align-items:center;gap:.57143rem;display:flex}.bb-root .prop-row .prop-label{flex-shrink:0;width:7.14286rem;margin-bottom:0}.bb-root .prop-badge{background:var(--accent-light);color:var(--accent-primary);text-transform:uppercase;letter-spacing:.5px;border-radius:.28571rem;margin-bottom:1.14286rem;padding:.28571rem .71429rem;font-size:.78571rem;font-weight:600;display:inline-block}.bb-root .prop-error-summary{color:#dc2626;background:#fef2f2;border:1px solid #fecaca;border-radius:.28571rem;margin-bottom:.85714rem;padding:.42857rem .71429rem;font-size:.85714rem;font-weight:500}.bb-root .prop-field-error input,.bb-root .prop-field-error textarea,.bb-root .prop-field-error select{box-shadow:0 0 0 1px #fecaca;border-color:#dc2626!important}.bb-root .prop-field-error-hint{color:#dc2626;margin-left:.42857rem;font-size:.78571rem;font-weight:400}.bb-root .prop-color-swatch{border:1px solid var(--border-subtle);cursor:pointer;border-radius:.57143rem;flex-shrink:0;width:40px;height:40px;transition:border-color .15s}.bb-root .prop-color-swatch:hover{border-color:var(--border-medium)}.bb-root .prop-toggle-group{border:1px solid var(--border-subtle);border-radius:.57143rem;display:flex;overflow:hidden}.bb-root .prop-toggle-btn{background:var(--bg-primary);height:2.85714rem;color:var(--text-secondary);border-right:1px solid var(--border-subtle);flex:1;justify-content:center;align-items:center;transition:all .15s;display:flex}.bb-root .prop-toggle-btn:last-child{border-right:none}.bb-root .prop-toggle-btn:hover{background:var(--bg-tertiary);color:var(--text-primary)}.bb-root .prop-toggle-btn.active{background:var(--accent-light);color:var(--accent-primary)}.bb-root .prop-mode-toggle{border:1px solid var(--border-subtle);border-radius:.57143rem;display:flex;overflow:hidden}.bb-root .prop-mode-btn{background:var(--bg-primary);width:2.57143rem;height:2.57143rem;color:var(--text-muted);border-right:1px solid var(--border-subtle);justify-content:center;align-items:center;transition:all .15s;display:flex}.bb-root .prop-mode-btn:last-child{border-right:none}.bb-root .prop-mode-btn:hover{background:var(--bg-tertiary);color:var(--text-primary)}.bb-root .prop-mode-btn.active{background:var(--accent-light);color:var(--accent-primary)}.bb-root .prop-section-divider{background:var(--border-subtle);height:1px;margin:1.14286rem 0}.bb-root .empty-state{text-align:center;flex-direction:column;justify-content:center;align-items:center;padding:2.28571rem 1.14286rem;display:flex}.bb-root .empty-state-icon{background:var(--bg-tertiary);width:3.42857rem;height:3.42857rem;color:var(--text-muted);border-radius:50%;justify-content:center;align-items:center;margin-bottom:.85714rem;display:flex}.bb-root .empty-state-title{color:#525252;font-size:13px;font-weight:500}.bb-root .empty-state-sub{color:#a3a3a3;max-width:14.2857rem;margin-top:.28571rem;font-size:12px;line-height:1.5}.bb-root .shortcuts-overlay{z-index:10000;-webkit-backdrop-filter:blur(.28571rem);backdrop-filter:blur(.28571rem);background:#0006;justify-content:center;align-items:center;display:flex;position:fixed;inset:0}.bb-root .shortcuts-panel{background:#fff;border-radius:1.14286rem;width:22.8571rem;padding:0;overflow:hidden;box-shadow:0 1.14286rem 3.42857rem #0003}.bb-root .shortcuts-header{border-bottom:1px solid var(--border-subtle);color:var(--text-primary);justify-content:space-between;align-items:center;padding:1.14286rem 1.42857rem;font-size:1rem;font-weight:600;display:flex}.bb-root .shortcuts-close{width:1.71429rem;height:1.71429rem;color:var(--text-tertiary);border-radius:.42857rem;justify-content:center;align-items:center;font-size:1.14286rem;display:flex}.bb-root .shortcuts-close:hover{background:var(--bg-tertiary);color:var(--text-primary)}.bb-root .shortcuts-list{padding:.85714rem 1.42857rem 1.14286rem}.bb-root .shortcut-row{border-bottom:1px solid var(--border-subtle);justify-content:space-between;align-items:center;padding:.57143rem 0;display:flex}.bb-root .shortcut-row:last-child{border-bottom:none}.bb-root .shortcut-action{color:var(--text-secondary);font-size:.92857rem}.bb-root .shortcut-keys{font-family:var(--font-mono);background:var(--bg-tertiary);color:var(--text-primary);border:1px solid var(--border-subtle);border-radius:.28571rem;padding:.21429rem .57143rem;font-size:.78571rem;font-weight:500}.bb-root .editor-root{background:var(--bg-secondary);flex-direction:column;width:100%;height:100%;font-family:Satoshi,-apple-system,BlinkMacSystemFont,Segoe UI,sans-serif;display:flex}.bb-root .editor-panels{flex:1;display:flex;overflow:hidden}:root{--bg-primary:#fff;--bg-secondary:#f5f5f5;--bg-tertiary:#f5f5f5;--bg-elevated:#fff;--bg-hover:#fafafa;--bg-active:#f3f0ff;--accent-primary:#6852d6;--accent-secondary:#7c6be6;--accent-light:#f3f0ff;--accent-gradient:linear-gradient(135deg, #6852d6 0%, #7c6be6 100%);--accent-glow:#6852d633;--text-primary:#141414;--text-secondary:#727272;--text-tertiary:#414651;--text-muted:#bfbfbc;--border-subtle:#e9eaeb;--border-medium:#d5d7da;--border-accent:#6852d64d;--success:#10b981;--warning:#f59e0b;--error:#d92d20;--shadow-sm:0 1px .14286rem #0000000d;--shadow-md:0 .28571rem .42857rem #00000012;--shadow-lg:0 .71429rem 1.78571rem #0000001a;--radius-sm:.57143rem;--radius-md:.57143rem;--radius-lg:.85714rem;--radius-xl:1.14286rem;--font-sans:"Satoshi", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;--font-mono:"SF Mono", "Fira Code", monospace}.bb-root .material-symbols-outlined{font-variation-settings:"FILL" 0, "wght" 400, "GRAD" 0, "opsz" 20;-webkit-user-select:none;user-select:none}.bb-root,.bb-root *{box-sizing:border-box;margin:0;padding:0}.bb-root,.bb-root,.bb-root #root{width:100%;height:100%}.bb-root,.bb-root *,.bb-root :before,.bb-root :after{font-family:Satoshi,-apple-system,BlinkMacSystemFont,Segoe UI,sans-serif}.bb-root{font-family:var(--font-sans);background:var(--bg-secondary);color:var(--text-primary);-webkit-font-smoothing:antialiased;font-size:clamp(14px,.95vw,28px);line-height:1.5}.bb-root ::-webkit-scrollbar{width:.42857rem;height:.42857rem}.bb-root ::-webkit-scrollbar-track{background:0 0}.bb-root ::-webkit-scrollbar-thumb{background:var(--border-medium);border-radius:.21429rem}.bb-root ::-webkit-scrollbar-thumb:hover{background:var(--text-tertiary)}.bb-root button{cursor:pointer;color:inherit;font:inherit;background:0 0;border:none}.bb-root input,.bb-root textarea,.bb-root select{box-sizing:border-box;border:1px solid var(--border-medium);width:100%;height:40px;color:var(--text-primary);background:#fff;border-radius:.57143rem;outline:none;padding:.71429rem .85714rem;font-family:inherit;font-size:13px;font-weight:500;line-height:1.5;transition:border-color .15s}.bb-root textarea{height:auto}.bb-root input:focus,.bb-root textarea:focus,.bb-root select:focus{border-color:var(--accent-primary)}.bb-root input::placeholder,.bb-root textarea::placeholder{color:var(--text-muted);font-weight:400}.bb-root select{appearance:none;cursor:pointer;padding-right:2rem}.bb-root input[type=checkbox]{width:1.14286rem;height:1.14286rem;accent-color:var(--accent-primary)}.bb-root input[type=color]{border:1px solid var(--border-medium);border-radius:var(--radius-sm);background:var(--bg-secondary);cursor:pointer;width:2.85714rem;height:2.57143rem;padding:.14286rem}.bb-root input[type=color]::-webkit-color-swatch-wrapper{padding:.14286rem}.bb-root input[type=color]::-webkit-color-swatch{border:none;border-radius:.28571rem}.bb-root textarea{resize:vertical;min-height:4.28571rem} | ||
| /*$vite$:1*/ |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
| import './Canvas.css'; | ||
| export declare const Canvas: import("react").NamedExoticComponent<object>; |
| export declare const CanvasViewToggle: import("react").NamedExoticComponent<{ | ||
| platform: "ios" | "android"; | ||
| setPlatform: (p: "ios" | "android") => void; | ||
| darkMode: boolean; | ||
| setDarkMode: (d: boolean) => void; | ||
| }>; |
| interface Props { | ||
| onClose: () => void; | ||
| /** Called after credentials are saved (for Send flow) */ | ||
| onSaved?: () => void; | ||
| /** Title override */ | ||
| title?: string; | ||
| /** Label for the save button. Default: "Save & Continue" */ | ||
| saveLabel?: string; | ||
| } | ||
| export declare const CredentialsModal: import("react").NamedExoticComponent<Props>; | ||
| export {}; |
| import './EditorLayout.css'; | ||
| export declare const EditorLayout: import("react").NamedExoticComponent<object>; |
| import './ElementTree.css'; | ||
| export declare function ElementTree(): import("react/jsx-runtime").JSX.Element; |
| import './LeftPanel.css'; | ||
| export declare const LeftPanel: import("react").NamedExoticComponent<object>; |
| export declare const NotificationPreview: import("react").NamedExoticComponent<{ | ||
| platform: "ios" | "android"; | ||
| }>; |
| import type { CardAction } from '../../types/schema'; | ||
| interface Props { | ||
| action: CardAction; | ||
| onChange: (action: CardAction) => void; | ||
| } | ||
| export declare const ActionEditor: import("react").NamedExoticComponent<Props>; | ||
| export {}; |
| import './PropertyEditors.css'; | ||
| export declare const CardStyleEditor: import("react").NamedExoticComponent<object>; |
| import type { CardElement } from '../../types/schema'; | ||
| import './PropertyEditors.css'; | ||
| interface Props { | ||
| element: CardElement; | ||
| onUpdate: (updates: Partial<CardElement>) => void; | ||
| } | ||
| export declare const ElementPropertyEditor: import("react").NamedExoticComponent<Props>; | ||
| export {}; |
| import type { IconRef } from '../../types/schema'; | ||
| interface Props { | ||
| value: IconRef | string | undefined; | ||
| onChange: (v: IconRef | undefined) => void; | ||
| } | ||
| export declare const IconPicker: import("react").NamedExoticComponent<Props>; | ||
| export {}; |
| import './PropertyEditors.css'; | ||
| export declare const NotificationEditor: import("react").NamedExoticComponent<object>; |
| import './PropertyEditors.css'; | ||
| export declare const VariableEditor: import("react").NamedExoticComponent<object>; |
| interface VariableInputProps { | ||
| value: string; | ||
| onChange: (v: string) => void; | ||
| placeholder?: string; | ||
| multiline?: boolean; | ||
| rows?: number; | ||
| style?: React.CSSProperties; | ||
| } | ||
| export declare const VariableInput: import("react").NamedExoticComponent<VariableInputProps>; | ||
| export {}; |
| import type { CardElement } from '../../types/schema'; | ||
| interface ElementRendererProps { | ||
| element: CardElement; | ||
| path: number[]; | ||
| selectedPath: number[] | null; | ||
| selectedPaths: number[][]; | ||
| onSelect: (path: number[] | null) => void; | ||
| onToggleSelect: (path: number[]) => void; | ||
| onMove: (path: number[], direction: 'up' | 'down') => void; | ||
| onRemove: (path: number[]) => void; | ||
| onWrap: (path: number[], wrapperType: 'row' | 'column' | 'grid') => void; | ||
| onUnwrap: (path: number[]) => void; | ||
| onDuplicate: (path: number[]) => void; | ||
| isFirst: boolean; | ||
| isLast: boolean; | ||
| inRow?: boolean; | ||
| colorMode?: 'light' | 'dark'; | ||
| } | ||
| export declare const ElementRenderer: import("react").NamedExoticComponent<ElementRendererProps>; | ||
| export {}; |
| import './RightPanel.css'; | ||
| export declare const RightPanel: import("react").NamedExoticComponent<object>; |
| import './ShortcutsPanel.css'; | ||
| export declare const ShortcutsPanel: import("react").NamedExoticComponent<object>; |
| import './TemplateLibrary.css'; | ||
| export declare const TemplateLibrary: import("react").NamedExoticComponent<object>; |
| import './TopBar.css'; | ||
| export declare const TopBar: import("react").NamedExoticComponent<object>; |
| import type { ReactNode, ButtonHTMLAttributes } from 'react'; | ||
| type ButtonVariant = 'primary' | 'secondary' | 'danger' | 'link'; | ||
| interface ButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> { | ||
| variant?: ButtonVariant; | ||
| children: ReactNode; | ||
| } | ||
| export declare const Button: import("react").NamedExoticComponent<ButtonProps>; | ||
| export {}; |
| import type { ColorValue } from '../../types/schema'; | ||
| /** | ||
| * Color section with light/dark toggle header + color fields. | ||
| * Usage: | ||
| * ``` | ||
| * <ColorSection> | ||
| * {(mode) => ( | ||
| * <> | ||
| * <ColorField label="Background" value={el.backgroundColor} onChange={(v) => onUpdate({ backgroundColor: v })} mode={mode} /> | ||
| * <ColorField label="Border" value={el.borderColor} onChange={(v) => onUpdate({ borderColor: v })} mode={mode} /> | ||
| * </> | ||
| * )} | ||
| * </ColorSection> | ||
| * ``` | ||
| */ | ||
| export declare function ColorSection({ children }: { | ||
| children: (mode: 'light' | 'dark') => React.ReactNode; | ||
| }): import("react/jsx-runtime").JSX.Element; | ||
| /** | ||
| * Single color field: label + swatch + hex input. | ||
| * Respects light/dark mode to show/edit the correct side of a ColorValue. | ||
| */ | ||
| export declare function ColorField({ label, value, onChange, fallback, transparentValue, mode, }: { | ||
| label: string; | ||
| value: ColorValue | undefined; | ||
| onChange: (v: ColorValue | undefined) => void; | ||
| fallback?: string; | ||
| transparentValue?: ColorValue; | ||
| mode?: 'light' | 'dark'; | ||
| }): import("react/jsx-runtime").JSX.Element; |
| interface EmptyStateProps { | ||
| icon: string; | ||
| title: string; | ||
| subtitle: string; | ||
| } | ||
| export declare const EmptyState: import("react").NamedExoticComponent<EmptyStateProps>; | ||
| export {}; |
| interface MaterialIconProps { | ||
| icon: string; | ||
| size?: number; | ||
| filled?: boolean; | ||
| className?: string; | ||
| style?: React.CSSProperties; | ||
| } | ||
| export declare const MaterialIcon: import("react").NamedExoticComponent<MaterialIconProps>; | ||
| export {}; |
| import type { ReactNode, CSSProperties } from 'react'; | ||
| interface ModalProps { | ||
| title: string; | ||
| onClose: () => void; | ||
| children: ReactNode; | ||
| footer?: ReactNode; | ||
| width?: number; | ||
| style?: CSSProperties; | ||
| } | ||
| export declare const Modal: import("react").NamedExoticComponent<ModalProps>; | ||
| export {}; |
| /** | ||
| * Unified app credentials state. | ||
| * | ||
| * Priority: | ||
| * 1. Props (highest) — passed via mountCardBuilder → read-only, non-editable | ||
| * 2. User-entered — set via App Credentials modal → editable (token cannot be set here) | ||
| * 3. Env vars (lowest, dev only) — from .env, set via builderConfig in App.tsx | ||
| * | ||
| * Note: `token` can only come from props or env (never user-entered). | ||
| */ | ||
| export interface AppCredentials { | ||
| appId: string; | ||
| region: string; | ||
| token: string; | ||
| apiKey: string; | ||
| } | ||
| /** Initialize credentials from mount props (highest priority, read-only) */ | ||
| export declare function initCredentials(appId?: string, region?: string, token?: string, apiKey?: string, lock?: boolean): void; | ||
| /** | ||
| * Get resolved credentials (props > user-entered). | ||
| * Each field is resolved independently — props field wins if non-empty. | ||
| */ | ||
| export declare function getCredentials(): AppCredentials; | ||
| /** Whether credentials were provided via props (should be non-editable) */ | ||
| export declare function isProvidedByProps(): boolean; | ||
| /** Whether we have enough credentials for template API calls (appId + token) */ | ||
| export declare function hasApiCredentials(): boolean; | ||
| /** Whether we have enough credentials for sending messages (appId + region + apiKey) */ | ||
| export declare function hasSendCredentials(): boolean; | ||
| /** Legacy: whether all credentials are configured */ | ||
| export declare function hasCredentials(): boolean; | ||
| /** Update user-entered credentials (only works if not provided by props) */ | ||
| export declare function setCredentials(creds: Partial<AppCredentials>): void; | ||
| /** Get user-entered credentials (for displaying in the modal) */ | ||
| export declare function getUserCredentials(): AppCredentials; | ||
| /** Subscribe to credential changes */ | ||
| export declare function subscribeCredentials(fn: () => void): () => void; | ||
| /** Reset credentials (used on destroy) */ | ||
| export declare function resetCredentials(): void; | ||
| /** | ||
| * React hook: reactively reports whether template/variable (apimgmt) APIs are usable | ||
| * (appId + bearer token). Use this to hide token-requiring UI when no token is present. | ||
| */ | ||
| export declare function useHasApiCredentials(): boolean; |
| import type { CardMessage } from '../types/schema'; | ||
| export interface CardVariable { | ||
| /** Variable name used in {{name}} tokens, e.g. 'user.name' */ | ||
| name: string; | ||
| /** Human-readable label shown in the picker */ | ||
| label?: string; | ||
| /** Short description */ | ||
| description?: string; | ||
| /** Category for grouping in the picker */ | ||
| category?: string; | ||
| } | ||
| export interface NotificationConfig { | ||
| /** App name shown in the notification preview */ | ||
| appName?: string; | ||
| /** App icon URL shown in the notification preview */ | ||
| appIcon?: string; | ||
| /** Show the Data key-value editor in the notification tab */ | ||
| enableData?: boolean; | ||
| /** Show the push notification phone preview in the canvas. Default: true */ | ||
| showPreview?: boolean; | ||
| /** Called when notification title or body changes */ | ||
| onNotificationChange?: (notification: { | ||
| title: string; | ||
| body: string; | ||
| }) => void; | ||
| /** Called when notification data changes */ | ||
| onNotificationDataChange?: (data: Record<string, string>) => void; | ||
| } | ||
| /** Which channels the builder supports */ | ||
| export type BuilderChannels = 'inapp' | 'push' | 'both'; | ||
| /** Module-level config accessible by components */ | ||
| export declare const builderConfig: { | ||
| appId?: string; | ||
| region?: string; | ||
| token?: string; | ||
| onSave?: (json: CardMessage, name: string, description: string) => void; | ||
| onChange?: (json: CardMessage) => void; | ||
| hideTopBar?: boolean; | ||
| hideTemplateLibrary?: boolean; | ||
| channels?: BuilderChannels; | ||
| /** Whether channels was explicitly provided by the host app (vs defaulted to 'both') */ | ||
| channelsExplicit?: boolean; | ||
| /** Show the variable editor tab for creating/managing variables. Default: true */ | ||
| enableVariableEditor?: boolean; | ||
| notification?: NotificationConfig; | ||
| /** Enable the built-in variable creation/management UI. Default: false */ | ||
| enableVariableManager?: boolean; | ||
| /** Show the canvas toolbar (zoom, dark mode, preview, JSON). Default: false */ | ||
| showCanvasToolbar?: boolean; | ||
| /** Hide the left panel (elements & components palette). Default: false */ | ||
| /** Disable all editing interactions — read-only preview mode. Default: false */ | ||
| readOnly?: boolean; | ||
| hideElementPalette?: boolean; | ||
| /** Hide the right panel (tree, element properties, card settings). Default: false */ | ||
| hidePropertyPanel?: boolean; | ||
| }; |
| export interface ComponentTemplate { | ||
| name: string; | ||
| category: string; | ||
| icon: string; | ||
| description: string; | ||
| elements: Record<string, unknown>[]; | ||
| } | ||
| export declare const COMPONENT_TEMPLATES: ComponentTemplate[]; | ||
| export declare const COMPONENT_CATEGORIES: string[]; | ||
| export declare const COMPONENT_TEMPLATE_NAMES: readonly ["Product Card", "Order Confirmation", "Announcement", "Quick Reply Buttons", "Order Tracking", "Event Card", "Feedback", "Data Table", "Carousel"]; | ||
| export type ComponentTemplateName = typeof COMPONENT_TEMPLATE_NAMES[number]; |
| import type { CardElement } from '../types/schema'; | ||
| export declare const ELEMENT_DEFAULTS: Map<string, () => CardElement>; | ||
| export declare const ELEMENT_PALETTE: { | ||
| readonly Layout: readonly ["row", "column", "grid", "accordion", "tabs"]; | ||
| readonly Content: readonly ["text", "image", "icon", "avatar", "badge", "divider", "spacer", "chip", "markdown", "codeBlock"]; | ||
| readonly 'Data Display': readonly ["table", "progressBar"]; | ||
| readonly Actions: readonly ["button", "iconButton", "link"]; | ||
| }; |
| export interface IconEntry { | ||
| name: string; | ||
| label: string; | ||
| url: string; | ||
| category: string; | ||
| } | ||
| export declare const ICON_LIBRARY: IconEntry[]; | ||
| export declare const ICON_MAP: Map<string, IconEntry>; | ||
| export declare const ICON_CATEGORIES: string[]; | ||
| /** Resolve an icon name to its URL. Returns the name as-is if it's already a URL. */ | ||
| export declare function resolveIconUrl(nameOrUrl: string): string; |
| import type { UIKitColorMode } from './uikit-theme'; | ||
| /** Build a flat token map from UIKit theme colors */ | ||
| export declare function buildTokensFromUIKit(colors: UIKitColorMode): Record<string, string>; | ||
| export declare const THEME_TOKENS: Record<string, string>; | ||
| export declare const DARK_THEME_TOKENS: Record<string, string>; | ||
| export declare let THEME_TOKEN_NAMES: string[]; | ||
| export declare function setActiveTheme(dark: boolean): void; | ||
| /** Sync active theme tokens from the UIKit theme store */ | ||
| export declare function syncThemeTokens(lightColors: UIKitColorMode, darkColors: UIKitColorMode, isDark: boolean): void; | ||
| export declare function resolveColor(value: string | undefined, fallback?: string): string; | ||
| export declare const TEXT_VARIANT_STYLES: Record<string, React.CSSProperties>; |
| export declare function hexToRgb(hex: string): { | ||
| r: number; | ||
| g: number; | ||
| b: number; | ||
| }; | ||
| export declare function rgbToHex(r: number, g: number, b: number): string; | ||
| export declare const SHADE_KEYS: readonly [50, 100, 200, 300, 400, 500, 600, 700, 800, 900]; | ||
| export declare function generateExtendedPrimary(primary: string): { | ||
| light: Record<number, string>; | ||
| dark: Record<number, string>; | ||
| }; | ||
| export declare function generateSpacingScale(baseUnit?: number, steps?: number): Record<string, number>; | ||
| export declare function generatePadding(scale: Record<string, number>): Record<string, number>; | ||
| export declare function generateRadius(scale: Record<string, number>): Record<string, number>; | ||
| export interface UIKitColorMode { | ||
| primary: string; | ||
| extendedPrimary: Record<number, string>; | ||
| neutral: Record<number, string>; | ||
| alert: { | ||
| info: string; | ||
| warning: string; | ||
| success: string; | ||
| error: string; | ||
| }; | ||
| staticColors: { | ||
| black: string; | ||
| white: string; | ||
| }; | ||
| sendBubble: { | ||
| background: string; | ||
| text: string; | ||
| textHighlight: string; | ||
| link: string; | ||
| timestamp: string; | ||
| icon: string; | ||
| }; | ||
| receiveBubble: { | ||
| background: string; | ||
| text: string; | ||
| textHighlight: string; | ||
| link: string; | ||
| timestamp: string; | ||
| icon: string; | ||
| }; | ||
| } | ||
| export interface UIKitTheme { | ||
| name: string; | ||
| version: string; | ||
| spacing: { | ||
| baseUnit: number; | ||
| scale: Record<string, number>; | ||
| padding: Record<string, number>; | ||
| radius: Record<string, number>; | ||
| }; | ||
| typography: { | ||
| fontFamily: string; | ||
| scale: Record<string, { | ||
| size: number; | ||
| lineHeight: number; | ||
| weight?: string; | ||
| }>; | ||
| weights: { | ||
| bold: string; | ||
| medium: string; | ||
| regular: string; | ||
| }; | ||
| }; | ||
| colors: { | ||
| light: UIKitColorMode; | ||
| dark: UIKitColorMode; | ||
| }; | ||
| } | ||
| export declare function createDefaultTheme(): UIKitTheme; |
| export declare function useKeyboardShortcuts(): void; |
| import type { CardMessage, ElementType } from './types/schema'; | ||
| import type { ComponentTemplateName } from './config/component-templates'; | ||
| import type { CardVariable, NotificationConfig, BuilderChannels } from './config/builder-config'; | ||
| import './index.css'; | ||
| export type { CardVariable } from './config/builder-config'; | ||
| export type { NotificationConfig, BuilderChannels } from './config/builder-config'; | ||
| export interface CardBuilderOptions { | ||
| /** CometChat app ID (required for template save/load APIs) */ | ||
| appId?: string; | ||
| /** App region — us, eu, etc. (required for template save/load APIs) */ | ||
| region?: string; | ||
| /** Bearer token — legacy; no longer used for template save/load auth (apiKey is). */ | ||
| token?: string; | ||
| /** CometChat REST API Key (required for template save/load and sending messages) */ | ||
| apiKey?: string; | ||
| /** Existing card JSON to load for editing */ | ||
| card?: CardMessage; | ||
| /** Initial notification title (only used when channels includes push). */ | ||
| notificationTitle?: string; | ||
| /** Initial notification body (only used when channels includes push). */ | ||
| notificationBody?: string; | ||
| /** Template name */ | ||
| templateName?: string; | ||
| /** Called when user clicks Save */ | ||
| onSave?: (json: CardMessage, name: string, description: string) => void; | ||
| /** Called whenever the card JSON changes (any edit). Use for real-time sync. */ | ||
| onChange?: (json: CardMessage) => void; | ||
| /** Available variables for {{placeholder}} insertion in text/URL fields */ | ||
| variables?: CardVariable[]; | ||
| /** Hide the top toolbar (save, export, import, undo/redo, template name). Default: false */ | ||
| hideTopBar?: boolean; | ||
| /** Hide the template library view — go straight to editor. Default: false */ | ||
| hideTemplateLibrary?: boolean; | ||
| /** Disable all editing interactions — read-only preview mode. Default: false */ | ||
| readOnly?: boolean; | ||
| /** Show the variable editor tab for creating/managing variables in the builder. Default: true */ | ||
| enableVariableEditor?: boolean; | ||
| /** Which channels to show: 'inapp', 'push', or 'both' (default). */ | ||
| channels?: BuilderChannels; | ||
| /** Push notification preview config (app name, icon). Only used when channels is 'push' or 'both'. */ | ||
| notification?: NotificationConfig; | ||
| /** Element types to hide from the palette (e.g. ['codeBlock', 'table', 'markdown']) */ | ||
| hiddenElements?: ElementType[]; | ||
| /** Component template names to hide from the palette (e.g. ['Product Card', 'Data Table']) */ | ||
| hiddenComponents?: ComponentTemplateName[]; | ||
| /** Hide the left panel (elements & components palette). Default: false */ | ||
| hideElementPalette?: boolean; | ||
| /** Hide the right panel (tree, element properties, card settings). Default: false */ | ||
| hidePropertyPanel?: boolean; | ||
| /** Show the canvas toolbar (zoom, dark mode, preview, JSON). Default: false */ | ||
| showCanvasToolbar?: boolean; | ||
| } | ||
| export interface CardBuilderInstance { | ||
| loadCard: (card: CardMessage, name?: string) => void; | ||
| getCardJSON: () => CardMessage; | ||
| setVariables: (variables: CardVariable[]) => void; | ||
| setChannels: (channels: BuilderChannels) => void; | ||
| setCanvasView: (view: 'card' | 'notification') => void; | ||
| setReadOnly: (readOnly: boolean) => void; | ||
| /** Hide specific element types from the palette. Pass element type names (e.g. 'codeBlock', 'table'). */ | ||
| setHiddenElements: (types: ElementType[]) => void; | ||
| /** Hide specific component templates from the palette. Pass template names (e.g. 'Product Card'). */ | ||
| setHiddenComponents: (names: ComponentTemplateName[]) => void; | ||
| /** Show or hide the left panel at runtime. */ | ||
| setHideElementPalette: (hide: boolean) => void; | ||
| /** Show or hide the right panel at runtime. */ | ||
| setHidePropertyPanel: (hide: boolean) => void; | ||
| /** Show or hide the canvas toolbar at runtime. */ | ||
| setShowCanvasToolbar: (show: boolean) => void; | ||
| /** Set notification title at runtime. */ | ||
| setNotificationTitle: (title: string) => void; | ||
| /** Set notification body at runtime. */ | ||
| setNotificationBody: (body: string) => void; | ||
| /** Set API key at runtime. */ | ||
| setApiKey: (apiKey: string) => void; | ||
| destroy: () => void; | ||
| } | ||
| export { builderConfig } from './config/builder-config'; | ||
| export declare function mountCardBuilder(container: HTMLElement, options: CardBuilderOptions): CardBuilderInstance; | ||
| export type { CardMessage, ElementType } from './types/schema'; | ||
| export type { ComponentTemplateName } from './config/component-templates'; |
| import type { CardElement, CardStyle, CardMessage, Template, ElementType, MessageData } from '../types/schema'; | ||
| import type { ComponentTemplateName } from '../config/component-templates'; | ||
| import { type CardVariable } from '../config/builder-config'; | ||
| export interface BuilderState { | ||
| templateId: string | null; | ||
| templateName: string; | ||
| templateDescription: string; | ||
| body: CardElement[]; | ||
| style: CardStyle; | ||
| fallbackText: string; | ||
| notificationTitle: string; | ||
| notificationBody: string; | ||
| notificationData: Array<{ | ||
| key: string; | ||
| value: string; | ||
| }>; | ||
| /** Custom message type for CometChat message structure (e.g. 'product', 'order') */ | ||
| messageType: string; | ||
| notificationEnabled: boolean; | ||
| /** Which view the canvas shows: card editor or notification preview */ | ||
| canvasView: 'card' | 'notification'; | ||
| /** Which channels are available */ | ||
| channels: 'inapp' | 'push' | 'both'; | ||
| /** Whether channels was explicitly set (vs default) */ | ||
| channelsExplicit: boolean; | ||
| /** Read-only mode — disables all editing interactions */ | ||
| readOnly: boolean; | ||
| selectedPath: number[] | null; | ||
| selectedPaths: number[][]; | ||
| isDirty: boolean; | ||
| useThemePlaceholders: boolean; | ||
| /** Element types hidden from the palette */ | ||
| hiddenElements: Set<ElementType>; | ||
| /** Component template names hidden from the palette */ | ||
| hiddenComponents: Set<ComponentTemplateName>; | ||
| view: 'library' | 'editor'; | ||
| clipboard: CardElement | null; | ||
| showTemplatePicker: boolean; | ||
| /** Hide the left panel (elements & components palette) */ | ||
| hideElementPalette: boolean; | ||
| /** Hide the right panel (tree, element properties, card settings) */ | ||
| hidePropertyPanel: boolean; | ||
| /** Show the canvas toolbar (zoom, dark mode, preview, JSON). Default: false */ | ||
| showCanvasToolbar: boolean; | ||
| /** Show the variable editor tab. Default: true */ | ||
| enableVariableEditor: boolean; | ||
| variables: CardVariable[]; | ||
| history: { | ||
| body: CardElement[]; | ||
| style: CardStyle; | ||
| }[]; | ||
| historyIndex: number; | ||
| templates: Template[]; | ||
| templatesLoading: boolean; | ||
| templatesMeta: { | ||
| previous?: { | ||
| affix: string; | ||
| createdAt: number; | ||
| }; | ||
| next?: { | ||
| affix: string; | ||
| createdAt: number; | ||
| }; | ||
| } | null; | ||
| setView: (view: 'library' | 'editor') => void; | ||
| setShowTemplatePicker: (show: boolean) => void; | ||
| setHideElementPalette: (hide: boolean) => void; | ||
| setHidePropertyPanel: (hide: boolean) => void; | ||
| setShowCanvasToolbar: (show: boolean) => void; | ||
| setEnableVariableEditor: (enable: boolean) => void; | ||
| selectElement: (path: number[] | null) => void; | ||
| toggleSelectElement: (path: number[]) => void; | ||
| addElement: (element: CardElement, parentPath?: number[]) => void; | ||
| updateElement: (path: number[], updates: Partial<CardElement>) => void; | ||
| removeElement: (path: number[]) => void; | ||
| moveElement: (path: number[], direction: 'up' | 'down') => void; | ||
| updateStyle: (settings: Partial<CardStyle>) => void; | ||
| setFallbackText: (text: string) => void; | ||
| setNotificationTitle: (text: string) => void; | ||
| setNotificationBody: (text: string) => void; | ||
| setMessageType: (type: string) => void; | ||
| setNotificationData: (data: Array<{ | ||
| key: string; | ||
| value: string; | ||
| }>) => void; | ||
| setNotificationEnabled: (enabled: boolean) => void; | ||
| setCanvasView: (view: 'card' | 'notification') => void; | ||
| setChannels: (channels: 'inapp' | 'push' | 'both') => void; | ||
| setReadOnly: (readOnly: boolean) => void; | ||
| setHiddenElements: (types: ElementType[]) => void; | ||
| setHiddenComponents: (names: ComponentTemplateName[]) => void; | ||
| setUseThemePlaceholders: (use: boolean) => void; | ||
| setVariables: (variables: CardVariable[]) => void; | ||
| addVariable: (variable: CardVariable) => void; | ||
| updateVariable: (index: number, variable: CardVariable) => void; | ||
| removeVariable: (index: number) => void; | ||
| setTemplateName: (name: string) => void; | ||
| setTemplateDescription: (desc: string) => void; | ||
| loadCard: (card: CardMessage, templateId?: string, name?: string, desc?: string) => void; | ||
| loadTemplate: (template: Template) => void; | ||
| newCard: () => void; | ||
| getCardJSON: (opts?: { | ||
| stripEmpty?: boolean; | ||
| }) => CardMessage; | ||
| /** Get the full CometChat message structure wrapping the card (used when channels not set) */ | ||
| getMessageJSON: () => MessageData; | ||
| setTemplates: (templates: Template[]) => void; | ||
| fetchTemplates: (search?: string) => Promise<void>; | ||
| fetchNextPage: () => Promise<void>; | ||
| fetchPrevPage: () => Promise<void>; | ||
| saveTemplate: () => Promise<void>; | ||
| deleteTemplate: (id: string) => Promise<void>; | ||
| reorderElement: (fromPath: number[], toPath: number[], toIndex: number) => void; | ||
| moveElementToPath: (fromPath: number[], toParentPath: number[], toIndex: number) => void; | ||
| wrapElement: (path: number[], wrapperType: 'row' | 'column' | 'grid') => void; | ||
| unwrapElement: (path: number[]) => void; | ||
| wrapSelected: (wrapperType: 'row' | 'column' | 'grid') => void; | ||
| duplicateElement: (path: number[]) => void; | ||
| copyElement: (path: number[]) => void; | ||
| pasteElement: (targetPath?: number[]) => void; | ||
| undo: () => void; | ||
| redo: () => void; | ||
| canUndo: () => boolean; | ||
| canRedo: () => boolean; | ||
| clearAll: () => void; | ||
| } | ||
| export declare const DEFAULT_STYLE: CardStyle; | ||
| export declare const useBuilderStore: import("zustand").UseBoundStore<import("zustand").StoreApi<BuilderState>>; |
| export type Padding = number | { | ||
| top?: number; | ||
| right?: number; | ||
| bottom?: number; | ||
| left?: number; | ||
| }; | ||
| export type SizeOrPercentage = number | string; | ||
| export type ColorValue = { | ||
| light: string; | ||
| dark: string; | ||
| } | 'transparent'; | ||
| /** Resolve a ColorValue to a hex string for the given mode. Returns 'transparent' for "transparent". */ | ||
| export declare function resolveColor(cv: ColorValue | undefined, mode?: 'light' | 'dark'): string | undefined; | ||
| /** Create a ColorValue from a single hex (same for both modes). */ | ||
| export declare function colorVal(hex: string): ColorValue; | ||
| /** Create a ColorValue with distinct light/dark values. */ | ||
| export declare function colorValLD(light?: string, dark?: string): ColorValue; | ||
| export interface OpenUrlAction { | ||
| type: 'openUrl'; | ||
| url: string; | ||
| openIn?: 'browser' | 'webview'; | ||
| } | ||
| export interface ChatWithUserAction { | ||
| type: 'chatWithUser'; | ||
| uid: string; | ||
| } | ||
| export interface ChatWithGroupAction { | ||
| type: 'chatWithGroup'; | ||
| guid: string; | ||
| } | ||
| export interface SendMessageAction { | ||
| type: 'sendMessage'; | ||
| text: string; | ||
| receiverUid?: string; | ||
| receiverGuid?: string; | ||
| } | ||
| export interface CopyToClipboardAction { | ||
| type: 'copyToClipboard'; | ||
| value: string; | ||
| } | ||
| export interface DownloadFileAction { | ||
| type: 'downloadFile'; | ||
| url: string; | ||
| filename?: string; | ||
| } | ||
| export interface InitiateCallAction { | ||
| type: 'initiateCall'; | ||
| uid?: string; | ||
| guid?: string; | ||
| callType: 'audio' | 'video'; | ||
| } | ||
| export interface ApiCallAction { | ||
| type: 'apiCall'; | ||
| url: string; | ||
| method?: 'GET' | 'POST' | 'PUT' | 'DELETE'; | ||
| headers?: Record<string, string>; | ||
| body?: Record<string, unknown>; | ||
| } | ||
| export interface CustomCallbackAction { | ||
| type: 'customCallback'; | ||
| } | ||
| export type CardAction = OpenUrlAction | ChatWithUserAction | ChatWithGroupAction | SendMessageAction | CopyToClipboardAction | DownloadFileAction | InitiateCallAction | ApiCallAction | CustomCallbackAction; | ||
| export declare const ACTION_TYPES: readonly ["openUrl", "chatWithUser", "chatWithGroup", "sendMessage", "copyToClipboard", "downloadFile", "initiateCall", "apiCall", "customCallback"]; | ||
| export type ActionType = typeof ACTION_TYPES[number]; | ||
| /** Reference to an icon. Use 'name' for built-in icons, 'url' for custom icon URLs. If both present, url takes precedence. */ | ||
| export interface IconRef { | ||
| name?: string; | ||
| url?: string; | ||
| } | ||
| export interface TextElement { | ||
| id: string; | ||
| type: 'text'; | ||
| content: string; | ||
| variant?: 'title' | 'heading1' | 'heading2' | 'heading3' | 'heading4' | 'body' | 'caption1' | 'caption2'; | ||
| color?: ColorValue; | ||
| align?: 'left' | 'center' | 'right' | 'justify'; | ||
| fontWeight?: 'regular' | 'medium' | 'bold'; | ||
| maxLines?: number; | ||
| padding?: Padding; | ||
| } | ||
| export interface ImageElement { | ||
| id: string; | ||
| type: 'image'; | ||
| url: string; | ||
| altText?: string; | ||
| fit?: 'cover' | 'contain' | 'fill'; | ||
| width?: SizeOrPercentage; | ||
| height?: SizeOrPercentage; | ||
| borderRadius?: number; | ||
| padding?: Padding; | ||
| } | ||
| export interface IconElement { | ||
| id: string; | ||
| type: 'icon'; | ||
| name?: string; | ||
| url?: string; | ||
| size?: number; | ||
| color?: ColorValue; | ||
| backgroundColor?: ColorValue; | ||
| borderRadius?: number; | ||
| padding?: number; | ||
| } | ||
| export interface AvatarElement { | ||
| id: string; | ||
| type: 'avatar'; | ||
| imageUrl?: string; | ||
| fallbackInitials?: string; | ||
| size?: number; | ||
| borderRadius?: number; | ||
| backgroundColor?: ColorValue; | ||
| fontSize?: number; | ||
| fontWeight?: 'regular' | 'medium' | 'bold'; | ||
| } | ||
| export interface BadgeElement { | ||
| id: string; | ||
| type: 'badge'; | ||
| text: string; | ||
| color?: ColorValue; | ||
| size?: number; | ||
| backgroundColor?: ColorValue; | ||
| borderColor?: ColorValue; | ||
| borderWidth?: number; | ||
| borderRadius?: number; | ||
| padding?: Padding; | ||
| fontSize?: number; | ||
| } | ||
| export interface DividerElement { | ||
| id: string; | ||
| type: 'divider'; | ||
| color?: ColorValue; | ||
| thickness?: number; | ||
| margin?: number; | ||
| } | ||
| export interface SpacerElement { | ||
| id: string; | ||
| type: 'spacer'; | ||
| height: number; | ||
| } | ||
| export interface ChipElement { | ||
| id: string; | ||
| type: 'chip'; | ||
| text: string; | ||
| color?: ColorValue; | ||
| icon?: IconRef; | ||
| backgroundColor?: ColorValue; | ||
| borderColor?: ColorValue; | ||
| borderWidth?: number; | ||
| borderRadius?: number; | ||
| padding?: Padding; | ||
| fontSize?: number; | ||
| } | ||
| export interface ProgressBarElement { | ||
| id: string; | ||
| type: 'progressBar'; | ||
| value: number; | ||
| color?: ColorValue; | ||
| trackColor?: ColorValue; | ||
| height?: number; | ||
| label?: string; | ||
| borderRadius?: number; | ||
| labelFontSize?: number; | ||
| labelColor?: ColorValue; | ||
| } | ||
| export interface CodeBlockElement { | ||
| id: string; | ||
| type: 'codeBlock'; | ||
| content: string; | ||
| language?: string; | ||
| backgroundColor?: ColorValue; | ||
| textColor?: ColorValue; | ||
| padding?: Padding; | ||
| borderRadius?: number; | ||
| fontSize?: number; | ||
| languageLabelFontSize?: number; | ||
| languageLabelColor?: ColorValue; | ||
| } | ||
| export interface MarkdownElement { | ||
| id: string; | ||
| type: 'markdown'; | ||
| content: string; | ||
| baseFontSize?: number; | ||
| linkColor?: ColorValue; | ||
| color?: ColorValue; | ||
| lineHeight?: number; | ||
| } | ||
| export interface RowElement { | ||
| id: string; | ||
| type: 'row'; | ||
| items: CardElement[]; | ||
| gap?: number; | ||
| align?: 'start' | 'center' | 'end' | 'spaceBetween' | 'spaceAround'; | ||
| crossAlign?: 'start' | 'center' | 'end'; | ||
| wrap?: boolean; | ||
| scrollable?: boolean; | ||
| peek?: number; | ||
| snap?: 'item' | 'free'; | ||
| padding?: Padding; | ||
| backgroundColor?: ColorValue; | ||
| borderRadius?: number; | ||
| borderColor?: ColorValue; | ||
| borderWidth?: number; | ||
| } | ||
| export interface ColumnElement { | ||
| id: string; | ||
| type: 'column'; | ||
| items: CardElement[]; | ||
| gap?: number; | ||
| align?: 'start' | 'center' | 'end' | 'stretch'; | ||
| crossAlign?: 'start' | 'center' | 'end'; | ||
| padding?: Padding; | ||
| backgroundColor?: ColorValue; | ||
| borderRadius?: number; | ||
| borderColor?: ColorValue; | ||
| borderWidth?: number; | ||
| } | ||
| export interface GridElement { | ||
| id: string; | ||
| type: 'grid'; | ||
| items: CardElement[]; | ||
| columns?: 2 | 3 | 4; | ||
| gap?: number; | ||
| padding?: Padding; | ||
| backgroundColor?: ColorValue; | ||
| borderRadius?: number; | ||
| borderColor?: ColorValue; | ||
| borderWidth?: number; | ||
| } | ||
| export interface AccordionElement { | ||
| id: string; | ||
| type: 'accordion'; | ||
| header: string; | ||
| headerIcon?: IconRef; | ||
| body: CardElement[]; | ||
| expandedByDefault?: boolean; | ||
| border?: boolean; | ||
| padding?: Padding; | ||
| fontSize?: number; | ||
| fontWeight?: 'regular' | 'medium' | 'bold'; | ||
| borderRadius?: number; | ||
| } | ||
| export interface TabsElement { | ||
| id: string; | ||
| type: 'tabs'; | ||
| tabs: { | ||
| label: string; | ||
| content: CardElement[]; | ||
| }[]; | ||
| defaultActiveTab?: number; | ||
| tabAlign?: 'start' | 'center' | 'stretch'; | ||
| tabPadding?: Padding; | ||
| contentPadding?: Padding; | ||
| fontSize?: number; | ||
| } | ||
| export interface ButtonElement { | ||
| id: string; | ||
| type: 'button'; | ||
| label: string; | ||
| action: CardAction; | ||
| backgroundColor?: ColorValue; | ||
| textColor?: ColorValue; | ||
| borderColor?: ColorValue; | ||
| borderWidth?: number; | ||
| borderRadius?: number; | ||
| icon?: IconRef; | ||
| iconPosition?: 'left' | 'right'; | ||
| size?: number; | ||
| fullWidth?: boolean; | ||
| padding?: Padding; | ||
| fontSize?: number; | ||
| } | ||
| export interface IconButtonElement { | ||
| id: string; | ||
| type: 'iconButton'; | ||
| icon: IconRef; | ||
| action: CardAction; | ||
| size?: number; | ||
| color?: ColorValue; | ||
| backgroundColor?: ColorValue; | ||
| borderRadius?: number; | ||
| } | ||
| export interface LinkElement { | ||
| id: string; | ||
| type: 'link'; | ||
| text: string; | ||
| action: CardAction; | ||
| color?: ColorValue; | ||
| underline?: boolean; | ||
| fontSize?: number; | ||
| } | ||
| export interface TableElement { | ||
| id: string; | ||
| type: 'table'; | ||
| columns: string[]; | ||
| rows: string[][]; | ||
| headerBackgroundColor?: ColorValue; | ||
| border?: boolean; | ||
| stripedRows?: boolean; | ||
| cellPadding?: number; | ||
| fontSize?: number; | ||
| stripedRowColor?: ColorValue; | ||
| borderColor?: ColorValue; | ||
| } | ||
| export type CardElement = TextElement | ImageElement | IconElement | AvatarElement | BadgeElement | DividerElement | SpacerElement | ChipElement | ProgressBarElement | CodeBlockElement | MarkdownElement | RowElement | ColumnElement | GridElement | AccordionElement | TabsElement | ButtonElement | IconButtonElement | LinkElement | TableElement; | ||
| export type ElementType = CardElement['type']; | ||
| export interface CardStyle { | ||
| background: ColorValue; | ||
| borderRadius?: number; | ||
| borderColor?: ColorValue; | ||
| borderWidth?: number; | ||
| padding?: Padding; | ||
| } | ||
| export interface CardMessage { | ||
| version: '1.0'; | ||
| body: CardElement[]; | ||
| style: CardStyle; | ||
| fallbackText: string; | ||
| } | ||
| export interface MessageData { | ||
| category: string; | ||
| type: string; | ||
| data: { | ||
| text: string; | ||
| card: CardMessage; | ||
| }; | ||
| } | ||
| export interface Template { | ||
| id: string; | ||
| name: string; | ||
| description?: string; | ||
| schemaVersion?: string; | ||
| messageData: MessageData; | ||
| thumbnail?: string; | ||
| createdBy?: string; | ||
| createdAt: number; | ||
| updatedAt: number; | ||
| } | ||
| export declare function isContainerElement(el: CardElement): el is RowElement | ColumnElement | GridElement | AccordionElement; | ||
| export declare function getContainerChildren(el: CardElement): CardElement[] | null; |
| import type { CardElement } from '../types/schema'; | ||
| export interface FieldError { | ||
| field: string; | ||
| message: string; | ||
| } | ||
| /** Returns field-level validation errors for a single element. */ | ||
| export declare function getElementErrors(el: CardElement): FieldError[]; | ||
| /** Quick check: does this element have any errors? Useful for tree indicators. */ | ||
| export declare function hasElementErrors(el: CardElement): boolean; |
| export declare function generateId(type: string): string; | ||
| import type { CardElement } from '../types/schema'; | ||
| /** Recursively assign IDs to all elements that don't have one */ | ||
| export declare function assignIds(elements: CardElement[]): CardElement[]; |
| export declare function setPortalRoot(el: HTMLElement): void; | ||
| export declare function getPortalRoot(): HTMLElement; |
| import type { CardMessage } from '../types/schema'; | ||
| export interface ValidationError { | ||
| path: string; | ||
| message: string; | ||
| } | ||
| export declare function validateCard(card: CardMessage): ValidationError[]; |
+1
-1
| { | ||
| "name": "@cometchat/card-builder", | ||
| "version": "2.0.0", | ||
| "version": "2.0.1", | ||
| "type": "module", | ||
@@ -5,0 +5,0 @@ "main": "dist/card-builder.umd.js", |
Sorry, the diff of this file is too big to display
| @import "https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@20..48,100..700,0..1,-50..200";.bb-root .tl-container{max-width:61.4286rem;margin:0 auto;padding:4.57143rem 1.71429rem}.bb-root .tl-header{text-align:center;margin-bottom:3.14286rem}.bb-root .tl-logo{background:var(--accent-primary);color:#fff;border-radius:.85714rem;justify-content:center;align-items:center;width:3.42857rem;height:3.42857rem;margin:0 auto 1.14286rem;font-size:1.14286rem;font-weight:800;display:flex}.bb-root .tl-title{color:var(--text-primary);font-size:1.14286rem;font-weight:700}.bb-root .tl-subtitle{color:var(--text-secondary);margin-top:.42857rem;font-size:1rem}.bb-root .tl-actions{gap:.71429rem;margin-bottom:2.57143rem;display:flex}.bb-root .tl-search{flex:1}.bb-root .tl-section{margin-bottom:2.57143rem}.bb-root .tl-section-title{color:#141414;margin-bottom:.85714rem;font-size:1rem;font-weight:600}.bb-root .tl-grid{grid-template-columns:repeat(auto-fill,minmax(13.5714rem,1fr));gap:.71429rem;display:grid}.bb-root .tl-card{text-align:left;box-shadow:none;background:#fff;border:1px solid #e9eaeb;border-radius:.57143rem;padding:1.14286rem;transition:all .15s}.bb-root .tl-card:hover{border-color:var(--accent-primary);box-shadow:var(--shadow-sm)}.bb-root .tl-card-badge{text-transform:uppercase;letter-spacing:.5px;color:var(--accent-primary);margin-bottom:.42857rem;font-size:.78571rem;font-weight:700}.bb-root .tl-card-name{color:#141414;font-size:1rem;font-weight:600}.bb-root .tl-card-desc{color:#727272;margin-top:.14286rem;font-size:.85714rem}.bb-root .tl-card-date{color:#bfbfbc;margin-top:.28571rem;font-size:.78571rem}.bb-root .tl-card{position:relative}.bb-root .tl-card-delete{width:1.57143rem;height:1.57143rem;color:var(--text-tertiary);cursor:pointer;opacity:0;background:0 0;border:none;border-radius:.28571rem;justify-content:center;align-items:center;font-size:1rem;transition:all .15s;display:flex;position:absolute;top:.57143rem;right:.57143rem}.bb-root .tl-card:hover .tl-card-delete{opacity:1}.bb-root .tl-card-delete:hover{color:#dc2626;background:#fee2e2}.bb-root .tl-pagination{justify-content:space-between;align-items:center;margin-top:1.14286rem;display:flex}.bb-root .tl-loading{text-align:center;color:var(--text-tertiary);padding:2.85714rem 1.42857rem;font-size:.92857rem}.bb-root .topbar{background:var(--bg-primary);border-bottom:1px solid var(--border-subtle);flex-shrink:0;justify-content:space-between;align-items:center;height:4rem;padding:0 1.42857rem;display:flex;position:relative}.bb-root .topbar-left{align-items:center;gap:.85714rem;display:flex}.bb-root .topbar-back{border-radius:var(--radius-sm);color:var(--text-secondary);padding:.28571rem .42857rem;font-size:1.28571rem}.bb-root .topbar-back:hover{background:var(--bg-tertiary);color:var(--text-primary)}.bb-root .topbar-logo{align-items:center;gap:.57143rem;display:flex}.bb-root .topbar-logo-icon{background:var(--accent-primary);color:#fff;border-radius:.42857rem;justify-content:center;align-items:center;width:1.71429rem;height:1.71429rem;font-size:.64286rem;font-weight:800;display:flex}.bb-root .topbar-logo span{color:var(--text-primary);letter-spacing:-.3px;font-size:1.14286rem;font-weight:600}.bb-root .topbar-sep{background:var(--border-medium);width:1px;height:1.14286rem}.bb-root .topbar-title{color:var(--text-secondary);font-size:1rem;font-weight:500}.bb-root .topbar-name{border-radius:var(--radius-sm);min-width:10rem;max-width:14.2857rem;color:var(--text-primary);box-shadow:none;background:0 0;border:1px solid #0000;padding:.42857rem .57143rem;font-size:1rem;font-weight:500}.bb-root .topbar-name:hover{border-color:var(--border-medium)}.bb-root .topbar-name:focus{border-color:var(--accent-primary)}.bb-root .topbar-dirty{color:var(--accent-primary);font-size:.57143rem}.bb-root .topbar-right{align-items:center;gap:.57143rem;display:flex}.bb-root .topbar-btn{color:#414651;background:#fff;border-radius:.57143rem;outline:1px solid #d5d7da;align-items:center;gap:.42857rem;height:2.57143rem;padding:0 1.14286rem;font-size:1rem;font-weight:600;line-height:1.333;transition:all .15s;display:flex}.bb-root .topbar-btn:hover{background:#f5f5f5}.bb-root .topbar-toast{color:#fff;background:var(--success);z-index:2000;border-radius:.57143rem;align-items:center;gap:.57143rem;padding:.85714rem 1.42857rem;font-size:1rem;font-weight:500;display:flex;position:fixed;bottom:1.71429rem;left:50%;transform:translate(-50%);box-shadow:0 .28571rem .85714rem #00000026}.bb-root .modal-subtitle{color:var(--text-secondary);text-transform:uppercase;letter-spacing:.5px;margin:.85714rem 0 .57143rem;font-size:.78571rem;font-weight:600}.bb-root .modal-field{margin-bottom:.85714rem}.bb-root .modal-label{color:var(--text-secondary);margin-bottom:.42857rem;font-size:.85714rem;font-weight:500;display:block}.bb-root .topbar-btn-icon{border-radius:var(--radius-sm);width:2.28571rem;height:2.28571rem;color:var(--text-secondary);justify-content:center;align-items:center;font-size:1.14286rem;transition:all .15s;display:flex}.bb-root .topbar-btn-icon:hover:not(:disabled){background:var(--bg-tertiary);color:var(--text-primary)}.bb-root .topbar-btn-icon:disabled{opacity:.3;cursor:default}.bb-root .topbar-btn-warn{color:#d97706;background:#fffbeb;border-color:#fcd34d}.bb-root .topbar-btn-warn:hover{background:#fef3c7}.bb-root .topbar-errors{border:1px solid var(--border-subtle);border-radius:var(--radius-lg);z-index:100;min-width:20rem;max-height:14.2857rem;box-shadow:var(--shadow-lg);background:#fff;margin-top:.57143rem;padding:.57143rem;font-size:.85714rem;position:absolute;top:100%;right:0;overflow-y:auto}.bb-root .topbar-error-item{border-radius:.28571rem;flex-direction:column;gap:.14286rem;padding:.42857rem .57143rem;display:flex}.bb-root .topbar-error-item:hover{background:#fef3c7}.bb-root .topbar-error-path{font-family:var(--font-mono);color:#d97706;font-size:.71429rem}.bb-root .topbar-dropdown{position:relative}.bb-root .topbar-dropdown-menu{background:var(--bg-primary);border:1px solid var(--border-subtle);border-radius:var(--radius-md);z-index:100;min-width:12.8571rem;box-shadow:var(--shadow-lg);margin-top:.42857rem;padding:.28571rem;position:absolute;top:100%;right:0}.bb-root .topbar-dropdown-item{width:100%;color:var(--text-primary);border-radius:var(--radius-sm);cursor:pointer;text-align:left;background:0 0;border:none;align-items:center;gap:.57143rem;padding:.57143rem .85714rem;font-size:.92857rem;font-weight:400;display:flex}.bb-root .topbar-dropdown-item:hover{background:var(--bg-tertiary)}.bb-root .left-panel{background:var(--bg-primary);border-right:1px solid var(--border-subtle);flex-direction:column;flex-shrink:0;width:22.8571rem;min-width:18.5714rem;max-width:28.5714rem;font-size:1rem;display:flex;overflow:hidden}.bb-root .lp-header{padding:.85714rem .85714rem .57143rem}.bb-root .lp-tabs{background:var(--bg-tertiary);border-radius:.57143rem;grid-template-columns:1fr 1fr;gap:.14286rem;padding:.21429rem;display:grid}.bb-root .lp-tab{height:2.57143rem;color:var(--text-secondary);background:0 0;border-radius:.42857rem;justify-content:center;align-items:center;gap:.42857rem;font-size:.92857rem;font-weight:500;transition:all .15s;display:flex}.bb-root .lp-tab:hover{color:var(--text-primary)}.bb-root .lp-tab.active{background:var(--bg-primary);color:var(--text-primary);box-shadow:0 1px .21429rem #00000014}.bb-root .lp-search-wrap{padding:0 .85714rem .57143rem;position:relative}.bb-root .lp-search-icon{color:var(--text-muted);pointer-events:none;margin-top:-.28571rem;position:absolute;top:50%;left:1.57143rem;transform:translateY(-50%)}.bb-root .lp-search{border:1px solid var(--border-subtle);width:100%;height:2.57143rem;color:var(--text-primary);background:#fafafa;border-radius:.57143rem;padding:0 2.28571rem 0 2.57143rem;font-size:.92857rem;transition:all .15s}.bb-root .lp-search::placeholder{color:var(--text-muted)}.bb-root .lp-search:focus{background:var(--bg-primary);border-color:var(--accent-primary);outline:none;box-shadow:0 0 0 .14286rem #6852d614}.bb-root .lp-search-clear{background:var(--border-medium);width:1.42857rem;height:1.42857rem;color:var(--text-secondary);border-radius:50%;justify-content:center;align-items:center;margin-top:-.28571rem;transition:background .15s;display:flex;position:absolute;top:50%;right:1.42857rem;transform:translateY(-50%)}.bb-root .lp-search-clear:hover{background:var(--text-muted);color:var(--text-primary)}.bb-root .lp-content{flex:1;padding:.28571rem .57143rem .85714rem;overflow-y:auto}.bb-root .lp-group{margin-bottom:.14286rem}.bb-root .lp-group-header{width:100%;color:var(--text-secondary);cursor:pointer;border-radius:.57143rem;align-items:center;gap:.57143rem;padding:.71429rem;font-size:.92857rem;font-weight:600;transition:all .15s;display:flex}.bb-root .lp-group-header:hover{background:var(--bg-tertiary);color:var(--text-primary)}.bb-root .lp-group-header.open{color:var(--text-primary);background:var(--bg-tertiary);font-weight:600}.bb-root .lp-group-header.open .lp-group-icon{color:var(--text-primary)}.bb-root .lp-group-icon{color:var(--text-secondary);transition:color .15s}.bb-root .lp-group-label{text-align:left;flex:1}.bb-root .lp-group-count{color:var(--text-secondary);font-variant-numeric:tabular-nums;font-size:.78571rem;font-weight:500}.bb-root .lp-group-header.open .lp-group-count{color:var(--text-secondary)}.bb-root .lp-group-chevron{color:var(--text-muted);transition:transform .2s,color .15s}.bb-root .lp-group-chevron.collapsed{transform:rotate(-90deg)}.bb-root .lp-group-header.open .lp-group-chevron{color:var(--text-secondary)}.bb-root .lp-group-items{flex-direction:column;gap:.14286rem;margin-left:1.28571rem;padding:.57143rem 0 .28571rem;display:flex;position:relative}.bb-root .lp-group-items:before{content:"";background:var(--border-subtle);width:1px;position:absolute;top:0;bottom:2rem;left:0}.bb-root .lp-item{text-align:left;border:1px solid #0000;border-radius:.57143rem;align-items:center;gap:.71429rem;width:calc(100% - .85714rem);margin-left:.85714rem;padding:.57143rem .71429rem;transition:all .15s;display:flex;position:relative}.bb-root .lp-item:before{content:"";background:var(--border-subtle);width:.85714rem;height:1px;position:absolute;top:50%;left:-.85714rem}.bb-root .lp-item:hover{background:var(--bg-hover);border-color:var(--border-subtle)}.bb-root .lp-item-icon-wrap{background:var(--bg-tertiary);width:2rem;height:2rem;color:var(--text-secondary);border-radius:.42857rem;flex-shrink:0;justify-content:center;align-items:center;display:flex}.bb-root .lp-item-title{color:var(--text-primary);white-space:nowrap;text-overflow:ellipsis;font-size:13px;font-weight:500;overflow:hidden}.bb-root .lp-item--component{align-items:flex-start}.bb-root .lp-item-info{flex-direction:column;flex:1;gap:.14286rem;min-width:0;display:flex}.bb-root .lp-item-sub{color:var(--text-secondary);white-space:nowrap;text-overflow:ellipsis;font-size:12px;line-height:1.3;overflow:hidden}.bb-root .lp-empty{text-align:center;flex-direction:column;justify-content:center;align-items:center;padding:2.85714rem 1.42857rem;display:flex}.bb-root .lp-empty-icon{color:var(--border-medium);margin-bottom:.57143rem}.bb-root .lp-empty-title{color:var(--text-secondary);font-size:.92857rem;font-weight:500}.bb-root .lp-empty-sub{color:var(--text-muted);margin-top:.28571rem;font-size:.85714rem}.bb-root .lp-footer{border-top:1px dashed var(--border-subtle);padding:.71429rem}.bb-root .lp-footer-drop{border:1px dashed var(--border-subtle);color:var(--text-secondary);cursor:pointer;border-radius:.57143rem;justify-content:center;align-items:center;gap:.42857rem;padding:.71429rem;font-size:.89286rem;font-weight:500;transition:all .15s;display:flex}.bb-root .lp-footer-drop:hover{border-color:var(--border-medium);color:var(--text-primary);background:var(--bg-tertiary)}.bb-root .canvas{background:var(--bg-secondary);flex-direction:column;flex:1;display:flex;position:relative;overflow:hidden}.bb-root .canvas-area{background:radial-gradient(circle at 1px 1px,#d4d4d8 1px,#0000 0) 0 0/1rem 1rem;flex:1;justify-content:center;align-items:center;padding:2.28571rem 1.71429rem;display:flex;overflow:auto}.bb-root .phone-frame{background:#fff;border-radius:24px;flex-direction:column;flex-shrink:0;width:340px;height:700px;max-height:700px;display:flex;position:relative;overflow:hidden;box-shadow:0 0 0 1px #0000000f,0 2px 4px #0000000a,0 12px 32px #00000014,0 32px 64px #0000000f}.bb-root .phone-frame:before{content:none}.bb-root .phone-screen{background:#fafafa;flex-direction:column;height:100%;margin-top:0;display:flex;overflow:hidden}.bb-root .chat-header{background:#fff;border-bottom:1px solid #0000000f;align-items:center;padding:20px 16px 14px;display:flex}.bb-root .chat-back-btn{color:var(--text-secondary);opacity:.6;padding:2px 4px;font-size:20px}.bb-root .chat-user{flex:1;align-items:center;gap:10px;margin-left:10px;display:flex}.bb-root .chat-avatar{color:#fff;background:linear-gradient(135deg,#6852d6,#8b7ae8);border-radius:50%;justify-content:center;align-items:center;width:36px;height:36px;font-size:14px;font-weight:600;display:flex;box-shadow:0 2px 8px #6852d64d}.bb-root .chat-name{color:var(--text-primary);letter-spacing:-.01em;font-size:14px;font-weight:600}.bb-root .chat-messages{background:#fafafa;flex-direction:column;flex:1;gap:12px;min-height:0;padding:16px;display:flex;overflow:hidden auto}.bb-root .message-date{text-align:center;color:var(--text-tertiary);-webkit-backdrop-filter:blur(.57143rem);backdrop-filter:blur(.57143rem);letter-spacing:.02em;background:#fffc;border-radius:.85714rem;align-self:center;padding:.35714rem .85714rem;font-size:.78571rem;font-weight:500}.bb-root .bubble-preview{flex-shrink:0;align-self:flex-start;width:100%;min-height:50px;position:relative;overflow:visible}.bb-root .canvas-bubble{border-radius:16px 16px 16px 4px;flex-direction:column;gap:2px;display:flex;overflow:visible;box-shadow:0 1px 2px #0000000f,0 1px 3px #0000000a}.bb-root .canvas-empty{color:var(--text-tertiary);text-align:center;border:.14286rem dashed var(--border-medium);background-color:#fff;border-radius:1.14286rem;flex-direction:column;justify-content:center;align-items:center;gap:.85714rem;margin:auto .85714rem;padding:2.28571rem 1.42857rem;font-size:.92857rem;display:flex}.bb-root .canvas-empty-template-btn{background:var(--bg-tertiary);border:1px solid var(--border-subtle);color:#404040;cursor:pointer;border-radius:.57143rem;margin-top:.85714rem;padding:.57143rem 1.14286rem;font-size:.92857rem;font-weight:600;transition:all .15s}.bb-root .canvas-empty-template-btn:hover{border-color:var(--accent-primary);background:var(--accent-light);color:var(--accent-primary)}.bb-root .canvas-empty-circle{background:#f5f5f5;border-radius:50%;justify-content:center;align-items:center;width:3.42857rem;height:3.42857rem;display:flex}.bb-root .canvas-empty-plus{color:#a3a3a3;font-size:1.71429rem;font-weight:300}.bb-root .canvas-empty-title{color:var(--text-primary);font-size:1rem;font-weight:600}.bb-root .canvas-empty-sub{color:#404040;font-size:.92857rem}.bb-root .chat-input-area{background:#fff;border-top:1px solid #0000000f;align-items:center;gap:10px;padding:10px 14px;display:flex}.bb-root .chat-input{border:1px solid var(--border-subtle);color:var(--text-primary);background:#f5f6f7;border-radius:20px;flex:1;padding:9px 16px;font-size:13px}.bb-root .chat-send-btn{background:var(--accent-primary);color:#fff;border-radius:50%;justify-content:center;align-items:center;width:34px;height:34px;font-size:13px;transition:transform .15s,box-shadow .15s;display:flex;box-shadow:0 2px 8px #6852d64d}.bb-root .chat-send-btn:hover{transform:scale(1.05);box-shadow:0 4px 12px #6852d666}.bb-root .el-wrapper{cursor:pointer;border-radius:4px;width:100%;transition:all .12s;position:relative;overflow:visible}.bb-root .el-wrapper:hover{background:#6852d60a}.bb-root .el-wrapper.selected{outline:2px solid var(--accent-primary);outline-offset:-2px;background:#6852d60a}.bb-root .el-wrapper.multi-selected{outline:2px dashed var(--accent-primary);outline-offset:-2px;background:#6852d60a}.bb-root .el-controls-portal{z-index:9999;background:#fff;border-radius:.57143rem;flex-direction:row;gap:.14286rem;padding:.21429rem;display:flex;box-shadow:0 .14286rem .85714rem #0000001f,0 0 0 1px #0000000a}.bb-root .preview-mode .el-controls-portal{display:none}.bb-root .el-ctrl-btn{width:1.85714rem;height:1.85714rem;color:var(--text-secondary);border-radius:.35714rem;justify-content:center;align-items:center;font-size:.92857rem;transition:all .12s;display:flex}.bb-root .el-ctrl-btn:hover{background:var(--bg-tertiary);color:var(--text-primary)}.bb-root .el-ctrl-btn.danger:hover{color:#dc2626;background:#fee2e2}.bb-root .el-wrap-menu{border:1px solid var(--border-subtle);z-index:1001;background:#fff;border-radius:.71429rem;min-width:10rem;margin-bottom:.28571rem;padding:.28571rem;position:absolute;bottom:100%;right:0;box-shadow:0 .57143rem 1.71429rem #0000001f}.bb-root .el-wrap-option{text-align:left;color:var(--text-secondary);white-space:nowrap;border-radius:.42857rem;width:100%;padding:.5rem .85714rem;font-size:.85714rem}.bb-root .el-wrap-option:hover{background:var(--accent-light);color:var(--accent-primary)}.bb-root .canvas-breadcrumbs{border-bottom:1px solid var(--border-subtle);background:#fff;flex-wrap:wrap;align-items:center;gap:.14286rem;padding:.42857rem 1.14286rem;font-size:.85714rem;display:flex}.bb-root .canvas-bc-sep{color:var(--text-muted);margin:0 .14286rem;font-size:.71429rem}.bb-root .canvas-bc-item{color:var(--text-secondary);font-size:.78571rem;font-family:var(--font-mono);border-radius:.28571rem;padding:.14286rem .57143rem}.bb-root .canvas-bc-item:hover{background:var(--bg-tertiary);color:var(--text-primary)}.bb-root .canvas-bc-item.active{color:var(--accent-primary);background:var(--accent-light)}.bb-root .multi-select-bar{border:1px solid var(--border-subtle);z-index:100;background:#fff;border-radius:.85714rem;align-items:center;gap:.57143rem;padding:.57143rem 1.14286rem;font-size:.92857rem;display:flex;position:absolute;bottom:4.28571rem;left:50%;transform:translate(-50%);box-shadow:0 .57143rem 1.71429rem #0000001f}.bb-root .multi-select-bar span{color:var(--text-secondary);white-space:nowrap}.bb-root .multi-select-bar button{background:var(--accent-light);color:var(--accent-primary);white-space:nowrap;border-radius:.42857rem;padding:.42857rem .85714rem;font-size:.85714rem;font-weight:600;transition:all .15s}.bb-root .multi-select-bar button:hover{background:var(--accent-primary);color:#fff}.bb-root .canvas-bubble ::-webkit-scrollbar{height:3px}.bb-root .canvas-bubble ::-webkit-scrollbar-track{background:0 0}.bb-root .canvas-bubble ::-webkit-scrollbar-thumb{background:#00000026;border-radius:2px}.bb-root .canvas-toolbar{border-top:1px solid var(--border-subtle);background:#fff;flex-shrink:0;justify-content:center;align-items:center;gap:.28571rem;padding:.42857rem .85714rem;font-size:.85714rem;display:flex}.bb-root .canvas-tool-btn{width:2rem;height:2rem;color:var(--text-secondary);border-radius:.42857rem;justify-content:center;align-items:center;font-size:1rem;transition:all .12s;display:flex}.bb-root .canvas-tool-btn:hover{background:var(--bg-tertiary);color:var(--text-primary)}.bb-root .canvas-tool-btn.active{background:var(--accent-light);color:var(--accent-primary)}.bb-root .canvas-tool-label{color:var(--text-secondary);text-align:center;min-width:2.57143rem;font-size:.78571rem}.bb-root .canvas-tool-sep{background:var(--border-medium);width:1px;height:1.14286rem;margin:0 .28571rem}.bb-root .preview-mode .el-wrapper{cursor:default}.bb-root .preview-mode .el-wrapper:hover{background:0 0}.bb-root .preview-mode .el-wrapper.selected,.bb-root .preview-mode .el-wrapper.multi-selected{background:0 0;outline:none}.bb-root .preview-mode .canvas-breadcrumbs,.bb-root .preview-mode .multi-select-bar{display:none}.bb-root .json-preview-panel{background:var(--bg-primary);border-left:1px solid var(--border-subtle);z-index:60;flex-direction:column;width:27.1429rem;display:flex;position:absolute;top:0;bottom:0;right:0;box-shadow:-.28571rem 0 1.71429rem #0000000f}.bb-root .json-preview-header{border-bottom:1px solid var(--border-subtle);color:var(--text-primary);background:var(--bg-secondary);align-items:center;gap:.57143rem;padding:.85714rem 1.14286rem;font-size:.92857rem;font-weight:600;display:flex}.bb-root .json-preview-header span{flex:1}.bb-root .json-preview-header button{width:2rem;height:2rem;color:var(--text-secondary);background:0 0;border:none;border-radius:.28571rem;justify-content:center;align-items:center;font-size:1rem;display:flex}.bb-root .json-preview-header button:hover{background:var(--bg-tertiary);color:var(--text-primary)}.bb-root .json-preview-code{font-family:var(--font-mono);color:var(--text-primary);white-space:pre;tab-size:2;background:var(--bg-primary);flex:1;margin:0;padding:1.14286rem;font-size:.85714rem;line-height:1.6;overflow:auto}.bb-root .el-context-menu{background:var(--bg-primary);border:1px solid var(--border-subtle);border-radius:.71429rem;min-width:11.4286rem;padding:.28571rem;font-size:.85714rem;box-shadow:0 .57143rem 1.71429rem #0000001f}.bb-root .el-ctx-item{text-align:left;width:100%;color:var(--text-secondary);white-space:nowrap;border-radius:.42857rem;padding:.42857rem .85714rem;display:block}.bb-root .el-ctx-item:hover{background:var(--bg-tertiary);color:var(--text-primary)}.bb-root .el-ctx-item.danger:hover{color:#dc2626;background:#fee2e2}.bb-root .el-ctx-sep{background:var(--border-subtle);height:1px;margin:.28571rem 0}.bb-root .canvas-side-toolbar{z-index:50;flex-direction:column;align-items:center;gap:1.71429rem;display:flex;position:absolute;top:50%;right:.85714rem;transform:translateY(-50%)}.bb-root .canvas-side-group{border:1px solid var(--border-subtle);background:#fff;border-radius:.85714rem;flex-direction:column;padding:.28571rem;display:flex;box-shadow:0 1px .21429rem #0000000f}.bb-root .canvas-side-btn{width:2.57143rem;height:2.57143rem;color:var(--text-secondary);border-radius:.57143rem;justify-content:center;align-items:center;transition:all .15s;display:flex}.bb-root .canvas-side-btn:hover{background:var(--bg-tertiary);color:var(--text-primary)}.bb-root .canvas-side-btn.active{background:var(--accent-light);color:var(--accent-primary)}.bb-root .canvas.read-only .canvas-area{pointer-events:none}.bb-root .canvas.read-only .canvas-area *{pointer-events:none;-webkit-user-select:none;user-select:none;cursor:default!important}.bb-root .canvas.read-only .chat-messages{pointer-events:auto;overflow-y:auto}.bb-root .canvas.read-only .canvas-side-toolbar{display:none}.bb-root .prop-field--row{align-items:flex-start;gap:.85714rem;display:flex}.bb-root .prop-field--row>.prop-label{flex-shrink:0;width:7.14286rem;margin-bottom:0;padding-top:.57143rem}.bb-root .prop-field--row>.prop-field-input{flex:1;min-width:0}.bb-root .prop-color-row{align-items:center;gap:.71429rem;display:flex}.bb-root .prop-color-pair{align-items:center;gap:.42857rem;display:flex}.bb-root .prop-color-circle{cursor:pointer;border:1px solid var(--border-subtle);border-radius:.57143rem;flex-shrink:0;width:2.28571rem;height:2.28571rem;transition:border-color .15s;position:relative}.bb-root .prop-color-circle:hover{border-color:var(--border-medium)}.bb-root .prop-color-circle input[type=color]{cursor:pointer;opacity:0;border:none;border-radius:.57143rem;width:100%;height:100%;padding:0;position:absolute;top:0;left:0}.bb-root .prop-color-tag{-webkit-user-select:none;user-select:none;border-radius:.28571rem;padding:.21429rem .42857rem;font-size:.71429rem;font-weight:600;line-height:1}.bb-root .prop-color-tag--light{background:var(--bg-tertiary);color:var(--text-secondary);border:1px solid var(--border-subtle)}.bb-root .prop-color-tag--dark{color:#adb5bd;background:#1a1a1a;border:1px solid #495057}.bb-root .prop-color-clear{width:1.71429rem;height:1.71429rem;color:var(--text-tertiary);background:var(--bg-tertiary);border:1px solid var(--border-subtle);cursor:pointer;border-radius:.42857rem;justify-content:center;align-items:center;font-size:.85714rem;transition:all .15s;display:flex}.bb-root .prop-color-clear:hover{color:#dc2626;background:#fef2f2;border-color:#fecaca}.bb-root .prop-padding-row{align-items:center;gap:.42857rem;display:flex}.bb-root .prop-padding-row input{flex:1}.bb-root .prop-padding-toggle{border:1px solid var(--border-subtle);width:40px;height:40px;color:var(--text-muted);background:var(--bg-primary);cursor:pointer;border-radius:.57143rem;flex-shrink:0;justify-content:center;align-items:center;transition:all .15s;display:flex}.bb-root .prop-padding-toggle:hover{background:var(--bg-tertiary);color:var(--text-primary);border-color:var(--border-medium)}.bb-root .prop-padding-toggle.active{background:var(--accent-light);color:var(--accent-primary);border-color:#6852d64d}.bb-root .prop-padding-grid{grid-template-columns:1fr 1fr;gap:.57143rem;margin-top:.57143rem;display:grid}.bb-root .prop-padding-grid label{color:var(--text-secondary);text-transform:uppercase;letter-spacing:.5px;margin-bottom:.28571rem;font-size:.75rem;font-weight:500;display:block}.bb-root .prop-select-wrap{position:relative}.bb-root .prop-select-wrap select{appearance:none;padding-right:2.28571rem}.bb-root .prop-select-arrow{pointer-events:none;color:var(--text-muted);position:absolute;top:50%;right:.71429rem;transform:translateY(-50%)}.bb-root .prop-input-number{-moz-appearance:textfield}.bb-root .prop-input-number::-webkit-outer-spin-button{-webkit-appearance:none;margin:0}.bb-root .prop-input-number::-webkit-inner-spin-button{-webkit-appearance:none;margin:0}.bb-root .prop-color-section{flex-direction:column;gap:.57143rem;display:flex}.bb-root .prop-color-swatch-row{align-items:center;gap:.71429rem;display:flex}.bb-root .prop-color-swatch{cursor:pointer;border:1px solid var(--border-subtle);border-radius:.57143rem;flex-shrink:0;width:40px;height:40px;transition:border-color .15s;position:relative}.bb-root .prop-color-swatch input[type=color]{cursor:pointer;opacity:0;border:none;border-radius:.57143rem;width:100%;height:100%;padding:0;position:absolute;top:0;left:0}.bb-root .prop-input-hex{flex:1;font-size:13px}.bb-root .prop-padding-wrap{flex-direction:column;gap:.57143rem;width:100%;display:flex}.bb-root .prop-padding-wrap .prop-padding-grid{margin-left:0}.bb-root .prop-align-group{border:1px solid var(--border-subtle);border-radius:.57143rem;display:flex;overflow:hidden}.bb-root .prop-align-btn{background:var(--bg-primary);height:40px;color:var(--text-secondary);border-right:1px solid var(--border-subtle);flex:1;justify-content:center;align-items:center;transition:all .15s;display:flex}.bb-root .prop-align-btn:last-child{border-right:none}.bb-root .prop-align-btn:hover{background:var(--bg-tertiary);color:var(--text-primary)}.bb-root .prop-align-btn.active{background:var(--accent-light);color:var(--accent-primary)}.bb-root .prop-switch{cursor:pointer;align-items:center;gap:.85714rem;padding:.42857rem 0;display:flex}.bb-root .prop-switch-track{background:var(--border-medium);border-radius:.71429rem;flex-shrink:0;width:2.57143rem;height:1.42857rem;transition:background .2s;position:relative}.bb-root .prop-switch-track.on{background:var(--accent-primary)}.bb-root .prop-switch-thumb{background:#fff;border-radius:50%;width:1.14286rem;height:1.14286rem;transition:transform .2s;position:absolute;top:.14286rem;left:.14286rem;box-shadow:0 1px .21429rem #00000026}.bb-root .prop-switch-track.on .prop-switch-thumb{transform:translate(1.14286rem)}.bb-root .prop-switch-label{width:7.14286rem;color:var(--text-tertiary);flex-shrink:0;font-size:13px;font-weight:400}.bb-root .prop-image-preview{object-fit:cover;border:1px solid var(--border-subtle);border-radius:.57143rem;width:100%;max-height:8.57143rem;margin:.28571rem 0 .57143rem}.bb-root .prop-section-header{align-items:center;gap:.57143rem;margin-top:.57143rem;padding:.57143rem 0;display:flex}.bb-root .prop-section-header .material-symbols-outlined{color:var(--text-muted)}.bb-root .prop-color-header{justify-content:space-between;align-items:center;margin-bottom:1.14286rem;display:flex}.bb-root .prop-color-field{align-items:flex-start;gap:.85714rem;margin-bottom:.85714rem;display:flex}.bb-root .prop-color-field-label{width:7.14286rem;color:var(--text-tertiary);flex-shrink:0;padding-top:.57143rem;font-size:13px;font-weight:400}.bb-root .prop-color-field-input{flex:1;align-items:center;gap:.71429rem;min-width:0;display:flex}.bb-root .prop-image-upload-placeholder{border:.14286rem dashed var(--border-medium);background:var(--bg-tertiary);cursor:pointer;border-radius:.57143rem;flex-direction:column;justify-content:center;align-items:center;width:100%;height:8.57143rem;margin-bottom:.85714rem;transition:all .15s;display:flex}.bb-root .prop-image-upload-placeholder:hover{border-color:var(--accent-primary);background:var(--accent-light)}.bb-root .prop-image-upload-icon{color:var(--text-muted);margin-bottom:.57143rem}.bb-root .prop-image-upload-placeholder:hover .prop-image-upload-icon{color:var(--accent-primary)}.bb-root .prop-image-upload-text{color:var(--text-secondary);font-size:.92857rem;font-weight:500}.bb-root .prop-image-upload-hint{color:var(--text-muted);margin-top:.14286rem;font-size:.78571rem}.bb-root .prop-image-preview-container{border:1px solid var(--border-subtle);cursor:pointer;border-radius:.57143rem;width:100%;height:12.8571rem;margin-bottom:.85714rem;position:relative;overflow:hidden}.bb-root .prop-image-preview-container:hover .prop-image-preview-overlay{opacity:1}.bb-root .prop-image-preview-img{object-fit:contain;background:var(--bg-tertiary);width:100%;height:100%}.bb-root .prop-image-preview-overlay{color:#fff;opacity:0;background:#0000004d;justify-content:center;align-items:center;gap:.42857rem;font-size:.85714rem;font-weight:500;transition:opacity .15s;display:flex;position:absolute;inset:0}.bb-root .prop-image-modal-backdrop{z-index:9999;-webkit-backdrop-filter:blur(.28571rem);backdrop-filter:blur(.28571rem);background:#000000b3;justify-content:center;align-items:center;padding:2.28571rem;display:flex;position:fixed;inset:0}.bb-root .prop-image-modal{background:#fff;border-radius:.85714rem;max-width:90vw;max-height:90vh;position:relative;overflow:hidden;box-shadow:0 1.42857rem 4.28571rem #0000004d}.bb-root .prop-image-modal-img{object-fit:contain;max-width:90vw;max-height:80vh;display:block}.bb-root .prop-image-modal-close{color:#fff;background:#00000080;border-radius:.57143rem;justify-content:center;align-items:center;width:2.57143rem;height:2.57143rem;transition:background .15s;display:flex;position:absolute;top:.85714rem;right:.85714rem}.bb-root .prop-image-modal-close:hover{background:#000000b3}.bb-root .prop-image-modal-footer{color:#fff;background:linear-gradient(#0000,#0009);justify-content:space-between;align-items:center;padding:.85714rem 1.14286rem;font-size:.85714rem;display:flex;position:absolute;bottom:0;left:0;right:0}.bb-root .prop-image-modal-close-btn{color:#fff;background:#fff3;border-radius:.57143rem;align-items:center;gap:.42857rem;padding:.42857rem .85714rem;font-size:.85714rem;font-weight:500;transition:background .15s;display:flex}.bb-root .prop-image-modal-close-btn:hover{background:#ffffff4d}.bb-root .notif-help-box{background:var(--bg-tertiary);color:var(--text-secondary);border-radius:.57143rem;align-items:flex-start;gap:.57143rem;padding:.85714rem;font-size:.89286rem;line-height:1.5;display:flex}.bb-root .notif-help-icon{color:var(--text-muted);flex-shrink:0;margin-top:1px}.bb-root .var-header{justify-content:space-between;align-items:center;display:flex}.bb-root .var-add-btn{background:var(--accent-primary);color:#fff;border-radius:.57143rem;align-items:center;gap:.28571rem;padding:.57143rem 1rem;font-size:.92857rem;font-weight:600;transition:background .15s;display:flex}.bb-root .var-add-btn:hover{background:var(--accent-secondary)}.bb-root .var-empty{text-align:center;flex-direction:column;align-items:center;padding:2.28571rem 1.14286rem;display:flex}.bb-root .var-empty-icon{background:var(--bg-tertiary);width:3.42857rem;height:3.42857rem;color:var(--text-muted);border-radius:1.71429rem;justify-content:center;align-items:center;margin-bottom:.85714rem;display:flex}.bb-root .var-empty-title{color:var(--text-secondary);font-size:.92857rem;font-weight:500}.bb-root .var-empty-sub{color:var(--text-muted);margin-top:.28571rem;font-size:.85714rem}.bb-root .var-count{text-transform:uppercase;letter-spacing:.5px;color:var(--text-secondary);margin-bottom:.85714rem;font-size:.78571rem;font-weight:600}.bb-root .var-list{flex-direction:column;gap:.71429rem;display:flex}.bb-root .var-item{border:1px solid var(--border-subtle);background:#fff;border-radius:.85714rem;transition:border-color .15s,box-shadow .15s;position:relative;overflow:hidden}.bb-root .var-item:hover{border-color:#6852d633;box-shadow:0 1px .21429rem #0000000a}.bb-root .var-item-top{align-items:center;gap:.71429rem;padding:.85714rem 1rem .57143rem;display:flex}.bb-root .var-item-icon{background:var(--accent-light);width:1.71429rem;height:1.71429rem;color:var(--accent-primary);border-radius:.42857rem;flex-shrink:0;justify-content:center;align-items:center;display:flex}.bb-root .var-item-name{color:var(--text-primary);background:#00000008;border-radius:.28571rem;flex:1;padding:.14286rem .57143rem;font-size:.92857rem;font-weight:600}.bb-root .var-item-delete{width:2rem;height:2rem;color:var(--text-muted);opacity:1;border-radius:.57143rem;flex-shrink:0;justify-content:center;align-items:center;transition:all .15s;display:flex}.bb-root .var-item:hover .var-item-delete{color:var(--text-muted)}.bb-root .var-item-delete:hover{background:#fef2f2;color:#dc2626!important}.bb-root .var-item-details{flex-direction:column;gap:.28571rem;padding:0 1rem .85714rem;display:flex}.bb-root .var-item-detail{color:var(--text-secondary);align-items:center;gap:.42857rem;font-size:.85714rem;display:flex}.bb-root .var-item-detail .material-symbols-outlined{color:var(--text-muted)}.bb-root .var-item-category{text-transform:uppercase;letter-spacing:.5px;color:var(--accent-primary);background:var(--accent-light);border-radius:.71429rem;align-self:flex-start;margin-top:.28571rem;padding:.14286rem .57143rem;font-size:.71429rem;font-weight:600}.bb-root .var-delete-overlay{z-index:10;-webkit-backdrop-filter:blur(.14286rem);backdrop-filter:blur(.14286rem);color:var(--text-primary);background:#fffffff2;border:1px solid #fecaca;border-radius:.85714rem;flex-direction:column;justify-content:center;align-items:center;gap:.57143rem;font-size:.85714rem;font-weight:500;display:flex;position:absolute;inset:0}.bb-root .var-delete-icon{color:#dc2626}.bb-root .var-delete-actions{gap:.57143rem;margin-top:.28571rem;display:flex}.bb-root .var-delete-confirm{color:#fff;background:#dc2626;border-radius:.57143rem;padding:.42857rem 1rem;font-size:.85714rem;font-weight:600}.bb-root .var-delete-confirm:hover{background:#b91c1c}.bb-root .var-delete-cancel{border:1px solid var(--border-subtle);color:var(--text-secondary);border-radius:.57143rem;padding:.42857rem 1rem;font-size:.85714rem;font-weight:500}.bb-root .var-delete-cancel:hover{background:var(--bg-tertiary)}.bb-root .var-form{background:#6852d605;border:1px solid #6852d633;border-radius:.85714rem;margin-bottom:.85714rem;padding:1.14286rem}.bb-root .var-form-title{color:var(--text-primary);margin-bottom:.85714rem;font-size:.92857rem;font-weight:600}.bb-root .var-form-actions{gap:.57143rem;margin-top:.85714rem;display:flex}.bb-root .var-form-btn-primary{background:var(--accent-primary);color:#fff;border-radius:.57143rem;padding:.57143rem 1.14286rem;font-size:.85714rem;font-weight:600;transition:background .15s}.bb-root .var-form-btn-primary:hover{background:var(--accent-secondary)}.bb-root .var-form-btn-secondary{border:1px solid var(--border-subtle);color:var(--text-secondary);border-radius:.57143rem;padding:.57143rem 1.14286rem;font-size:.85714rem;font-weight:500;transition:background .15s}.bb-root .var-form-btn-secondary:hover{background:var(--bg-tertiary)}.bb-root .tree-root{font-size:13px}.bb-root .tree-item{text-align:left;width:100%;color:var(--text-secondary);cursor:pointer;border-radius:.57143rem;align-items:center;gap:.42857rem;min-height:2.28571rem;padding:.42857rem .57143rem;transition:all .15s;display:flex;position:relative}.bb-root .tree-item:hover{background:var(--bg-tertiary);color:var(--text-primary)}.bb-root .tree-item.selected{background:var(--bg-tertiary);color:var(--text-primary);transition:none}.bb-root .tree-item:active{background:var(--bg-tertiary);color:var(--text-primary)}.bb-root .tree-item.multi-selected{background:var(--accent-light);color:var(--accent-primary);outline:1px dashed var(--accent-primary);outline-offset:-1px}.bb-root .tree-item.drop-target{outline:.14286rem dashed var(--accent-primary);outline-offset:-.14286rem}.bb-root .tree-item.flash{background:var(--bg-tertiary)}@keyframes tree-flash{0%{background:var(--bg-tertiary)}to{background:0 0}}.bb-root .tree-chevron{width:1.14286rem;height:1.14286rem;color:var(--text-muted);cursor:pointer;border-radius:.28571rem;flex-shrink:0;justify-content:center;align-items:center;transition:color .15s;display:flex}.bb-root .tree-chevron:hover,.bb-root .tree-item.selected .tree-chevron{color:var(--text-primary)}.bb-root .tree-spacer{flex-shrink:0;width:1.14286rem}.bb-root .tree-icon-box{border:1px solid var(--border-subtle);background:var(--bg-primary);width:1.71429rem;height:1.71429rem;color:var(--text-secondary);border-radius:.28571rem;flex-shrink:0;justify-content:center;align-items:center;transition:all .15s;display:flex}.bb-root .tree-item:hover .tree-icon-box{border-color:var(--border-medium)}.bb-root .tree-item.selected .tree-icon-box,.bb-root .tree-item.flash .tree-icon-box{border-color:var(--border-medium);background:var(--bg-tertiary);color:var(--text-primary)}.bb-root .tree-type{font-family:Satoshi,-apple-system,BlinkMacSystemFont,Segoe UI,sans-serif;font-size:12px;font-weight:500}.bb-root .tree-type.is-container{font-weight:600}.bb-root .tree-item.selected .tree-type{color:var(--text-primary)}.bb-root .tree-label{color:var(--text-tertiary);text-overflow:ellipsis;white-space:nowrap;flex:1;font-size:.78571rem;overflow:hidden}.bb-root .tree-badge{background:var(--bg-tertiary);color:var(--text-tertiary);border-radius:.57143rem;flex-shrink:0;margin-left:auto;padding:1px .35714rem;font-size:.64286rem}.bb-root .tree-item.selected .tree-badge{background:var(--border-subtle);color:var(--text-secondary)}.bb-root .tree-error-dot{background:#dc2626;border-radius:50%;flex-shrink:0;width:.42857rem;height:.42857rem;margin-left:auto}.bb-root .tree-badge+.tree-error-dot,.bb-root .tree-error-dot+.tree-badge{margin-left:.28571rem}.bb-root .tree-children{position:relative}.bb-root .tree-children:before{content:"";background:var(--border-subtle);width:1px;position:absolute;top:0;bottom:.85714rem;left:1.35714rem}.bb-root .tree-empty{color:var(--text-tertiary);flex-direction:column;align-items:center;gap:.57143rem;padding:1.71429rem;font-size:.92857rem;display:flex}.bb-root .tree-drag-overlay{background:var(--bg-primary);opacity:.9;border-radius:.57143rem;box-shadow:0 .28571rem .85714rem #00000026}.bb-root .tree-node{touch-action:none}.bb-root .tree-drop-gap{height:.28571rem;transition:height .1s;position:relative}.bb-root .tree-drop-gap.active{height:.57143rem}.bb-root .tree-drop-gap .tree-drop-line{background:0 0;border-radius:1px;height:.14286rem;transition:background .1s}.bb-root .tree-drop-gap.active .tree-drop-line{background:var(--accent-primary)}.bb-root .tree-search-wrap{margin-bottom:.57143rem;position:relative}.bb-root .tree-search-icon{color:var(--text-muted);pointer-events:none;position:absolute;top:50%;left:.71429rem;transform:translateY(-50%)}.bb-root .tree-search{border:1px solid var(--border-subtle);width:100%;color:var(--text-primary);background:#fafafa;border-radius:.57143rem;padding:.57143rem 2rem .57143rem 2.28571rem;font-size:.85714rem}.bb-root .tree-search:focus{border-color:var(--accent-primary);background:var(--bg-primary);outline:none}.bb-root .tree-search::placeholder{color:var(--text-muted)}.bb-root .tree-search-clear{width:1.42857rem;height:1.42857rem;color:var(--text-tertiary);background:var(--border-medium);border-radius:50%;justify-content:center;align-items:center;transition:all .15s;display:flex;position:absolute;top:50%;right:.57143rem;transform:translateY(-50%)}.bb-root .tree-search-clear:hover{color:var(--text-primary);background:var(--text-muted)}.bb-root .right-panel{background:var(--bg-primary);border-left:1px solid var(--border-subtle);flex-direction:column;flex-shrink:0;width:22.8571rem;min-width:18.5714rem;max-width:28.5714rem;font-size:14px;display:flex;overflow:hidden}.bb-root .rp-tabs{border-bottom:1px solid var(--border-subtle);flex-shrink:0;padding:0 .57143rem;display:flex;overflow:hidden}.bb-root .rp-tab{color:var(--text-secondary);white-space:nowrap;background:0 0;flex:1;justify-content:center;align-items:center;padding:.85714rem .57143rem;font-size:.89286rem;font-weight:500;transition:color .15s;display:flex;position:relative}.bb-root .rp-tab:hover{color:var(--text-primary)}.bb-root .rp-tab.active{color:var(--accent-primary);font-weight:500}.bb-root .rp-tab-indicator{background:var(--accent-primary);border-radius:1px;height:.14286rem;position:absolute;bottom:0;left:.57143rem;right:.57143rem}.bb-root .rp-content{flex:1;padding:1.42857rem 1.14286rem;overflow-y:auto}.bb-root .rp-empty{color:var(--text-tertiary);text-align:center;flex-direction:column;justify-content:center;align-items:center;gap:.85714rem;padding:3.42857rem 1.71429rem;display:flex}.bb-root .rp-empty-icon{color:var(--border-medium);font-size:3.42857rem}.bb-root .prop-group{margin-bottom:0;padding-bottom:0}.bb-root .prop-group:last-child{border-bottom:none}.bb-root .prop-group-title{color:var(--text-primary);margin-bottom:1.14286rem;font-size:14px;font-weight:600}.bb-root .prop-field{margin-bottom:.85714rem}.bb-root .prop-label{color:var(--text-tertiary);margin-bottom:.42857rem;font-size:13px;font-weight:400;display:block}.bb-root .prop-row{align-items:center;gap:.57143rem;display:flex}.bb-root .prop-row .prop-label{flex-shrink:0;width:7.14286rem;margin-bottom:0}.bb-root .prop-badge{background:var(--accent-light);color:var(--accent-primary);text-transform:uppercase;letter-spacing:.5px;border-radius:.28571rem;margin-bottom:1.14286rem;padding:.28571rem .71429rem;font-size:.78571rem;font-weight:600;display:inline-block}.bb-root .prop-error-summary{color:#dc2626;background:#fef2f2;border:1px solid #fecaca;border-radius:.28571rem;margin-bottom:.85714rem;padding:.42857rem .71429rem;font-size:.85714rem;font-weight:500}.bb-root .prop-field-error input,.bb-root .prop-field-error textarea,.bb-root .prop-field-error select{box-shadow:0 0 0 1px #fecaca;border-color:#dc2626!important}.bb-root .prop-field-error-hint{color:#dc2626;margin-left:.42857rem;font-size:.78571rem;font-weight:400}.bb-root .prop-color-swatch{border:1px solid var(--border-subtle);cursor:pointer;border-radius:.57143rem;flex-shrink:0;width:40px;height:40px;transition:border-color .15s}.bb-root .prop-color-swatch:hover{border-color:var(--border-medium)}.bb-root .prop-toggle-group{border:1px solid var(--border-subtle);border-radius:.57143rem;display:flex;overflow:hidden}.bb-root .prop-toggle-btn{background:var(--bg-primary);height:2.85714rem;color:var(--text-secondary);border-right:1px solid var(--border-subtle);flex:1;justify-content:center;align-items:center;transition:all .15s;display:flex}.bb-root .prop-toggle-btn:last-child{border-right:none}.bb-root .prop-toggle-btn:hover{background:var(--bg-tertiary);color:var(--text-primary)}.bb-root .prop-toggle-btn.active{background:var(--accent-light);color:var(--accent-primary)}.bb-root .prop-mode-toggle{border:1px solid var(--border-subtle);border-radius:.57143rem;display:flex;overflow:hidden}.bb-root .prop-mode-btn{background:var(--bg-primary);width:2.57143rem;height:2.57143rem;color:var(--text-muted);border-right:1px solid var(--border-subtle);justify-content:center;align-items:center;transition:all .15s;display:flex}.bb-root .prop-mode-btn:last-child{border-right:none}.bb-root .prop-mode-btn:hover{background:var(--bg-tertiary);color:var(--text-primary)}.bb-root .prop-mode-btn.active{background:var(--accent-light);color:var(--accent-primary)}.bb-root .prop-section-divider{background:var(--border-subtle);height:1px;margin:1.14286rem 0}.bb-root .empty-state{text-align:center;flex-direction:column;justify-content:center;align-items:center;padding:2.28571rem 1.14286rem;display:flex}.bb-root .empty-state-icon{background:var(--bg-tertiary);width:3.42857rem;height:3.42857rem;color:var(--text-muted);border-radius:50%;justify-content:center;align-items:center;margin-bottom:.85714rem;display:flex}.bb-root .empty-state-title{color:#525252;font-size:13px;font-weight:500}.bb-root .empty-state-sub{color:#a3a3a3;max-width:14.2857rem;margin-top:.28571rem;font-size:12px;line-height:1.5}.bb-root .shortcuts-overlay{z-index:10000;-webkit-backdrop-filter:blur(.28571rem);backdrop-filter:blur(.28571rem);background:#0006;justify-content:center;align-items:center;display:flex;position:fixed;inset:0}.bb-root .shortcuts-panel{background:#fff;border-radius:1.14286rem;width:22.8571rem;padding:0;overflow:hidden;box-shadow:0 1.14286rem 3.42857rem #0003}.bb-root .shortcuts-header{border-bottom:1px solid var(--border-subtle);color:var(--text-primary);justify-content:space-between;align-items:center;padding:1.14286rem 1.42857rem;font-size:1rem;font-weight:600;display:flex}.bb-root .shortcuts-close{width:1.71429rem;height:1.71429rem;color:var(--text-tertiary);border-radius:.42857rem;justify-content:center;align-items:center;font-size:1.14286rem;display:flex}.bb-root .shortcuts-close:hover{background:var(--bg-tertiary);color:var(--text-primary)}.bb-root .shortcuts-list{padding:.85714rem 1.42857rem 1.14286rem}.bb-root .shortcut-row{border-bottom:1px solid var(--border-subtle);justify-content:space-between;align-items:center;padding:.57143rem 0;display:flex}.bb-root .shortcut-row:last-child{border-bottom:none}.bb-root .shortcut-action{color:var(--text-secondary);font-size:.92857rem}.bb-root .shortcut-keys{font-family:var(--font-mono);background:var(--bg-tertiary);color:var(--text-primary);border:1px solid var(--border-subtle);border-radius:.28571rem;padding:.21429rem .57143rem;font-size:.78571rem;font-weight:500}.bb-root .editor-root{background:var(--bg-secondary);flex-direction:column;width:100%;height:100%;font-family:Satoshi,-apple-system,BlinkMacSystemFont,Segoe UI,sans-serif;display:flex}.bb-root .editor-panels{flex:1;display:flex;overflow:hidden}:root{--bg-primary:#fff;--bg-secondary:#f5f5f5;--bg-tertiary:#f5f5f5;--bg-elevated:#fff;--bg-hover:#fafafa;--bg-active:#f3f0ff;--accent-primary:#6852d6;--accent-secondary:#7c6be6;--accent-light:#f3f0ff;--accent-gradient:linear-gradient(135deg, #6852d6 0%, #7c6be6 100%);--accent-glow:#6852d633;--text-primary:#141414;--text-secondary:#727272;--text-tertiary:#414651;--text-muted:#bfbfbc;--border-subtle:#e9eaeb;--border-medium:#d5d7da;--border-accent:#6852d64d;--success:#10b981;--warning:#f59e0b;--error:#d92d20;--shadow-sm:0 1px .14286rem #0000000d;--shadow-md:0 .28571rem .42857rem #00000012;--shadow-lg:0 .71429rem 1.78571rem #0000001a;--radius-sm:.57143rem;--radius-md:.57143rem;--radius-lg:.85714rem;--radius-xl:1.14286rem;--font-sans:"Satoshi", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;--font-mono:"SF Mono", "Fira Code", monospace}.bb-root .material-symbols-outlined{font-variation-settings:"FILL" 0, "wght" 400, "GRAD" 0, "opsz" 20;-webkit-user-select:none;user-select:none}.bb-root,.bb-root *{box-sizing:border-box;margin:0;padding:0}.bb-root,.bb-root,.bb-root #root{width:100%;height:100%}.bb-root,.bb-root *,.bb-root :before,.bb-root :after{font-family:Satoshi,-apple-system,BlinkMacSystemFont,Segoe UI,sans-serif}.bb-root{font-family:var(--font-sans);background:var(--bg-secondary);color:var(--text-primary);-webkit-font-smoothing:antialiased;font-size:clamp(14px,.95vw,28px);line-height:1.5}.bb-root ::-webkit-scrollbar{width:.42857rem;height:.42857rem}.bb-root ::-webkit-scrollbar-track{background:0 0}.bb-root ::-webkit-scrollbar-thumb{background:var(--border-medium);border-radius:.21429rem}.bb-root ::-webkit-scrollbar-thumb:hover{background:var(--text-tertiary)}.bb-root button{cursor:pointer;color:inherit;font:inherit;background:0 0;border:none}.bb-root input,.bb-root textarea,.bb-root select{box-sizing:border-box;border:1px solid var(--border-medium);width:100%;height:40px;color:var(--text-primary);background:#fff;border-radius:.57143rem;outline:none;padding:.71429rem .85714rem;font-family:inherit;font-size:13px;font-weight:500;line-height:1.5;transition:border-color .15s}.bb-root textarea{height:auto}.bb-root input:focus,.bb-root textarea:focus,.bb-root select:focus{border-color:var(--accent-primary)}.bb-root input::placeholder,.bb-root textarea::placeholder{color:var(--text-muted);font-weight:400}.bb-root select{appearance:none;cursor:pointer;padding-right:2rem}.bb-root input[type=checkbox]{width:1.14286rem;height:1.14286rem;accent-color:var(--accent-primary)}.bb-root input[type=color]{border:1px solid var(--border-medium);border-radius:var(--radius-sm);background:var(--bg-secondary);cursor:pointer;width:2.85714rem;height:2.57143rem;padding:.14286rem}.bb-root input[type=color]::-webkit-color-swatch-wrapper{padding:.14286rem}.bb-root input[type=color]::-webkit-color-swatch{border:none;border-radius:.28571rem}.bb-root textarea{resize:vertical;min-height:4.28571rem} |
| <!doctype html> | ||
| <html lang="en"> | ||
| <head> | ||
| <meta charset="UTF-8" /> | ||
| <link rel="icon" type="image/svg+xml" href="/favicon.svg" /> | ||
| <meta name="viewport" content="width=device-width, initial-scale=1.0" /> | ||
| <link rel="preconnect" href="https://fonts.googleapis.com" /> | ||
| <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin /> | ||
| <link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@20..48,100..700,0..1,-50..200" rel="stylesheet" /> | ||
| <link href="https://api.fontshare.com/v2/css?f[]=satoshi@300,400,500,600,700&display=swap" rel="stylesheet" /> | ||
| <title>bubble-builder</title> | ||
| <style>.bb-root, .bb-root, .bb-root #root { height: 100%; width: 100%; margin: 0; padding: 0; overflow: hidden; }</style> | ||
| <script type="module" crossorigin src="/assets/index-bg5Sfjsd.js"></script> | ||
| <link rel="stylesheet" crossorigin href="/assets/index-D9-G0mBH.css"> | ||
| </head> | ||
| <body> | ||
| <div id="root"></div> | ||
| </body> | ||
| </html> |
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
Minified code
QualityThis package contains minified code. This may be harmless in some cases where minified code is included in packaged libraries, however packages on npm should not minify code.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
Minified code
QualityThis package contains minified code. This may be harmless in some cases where minified code is included in packaged libraries, however packages on npm should not minify code.
Found 1 instance in 1 package
1353595
129.04%48
585.71%27160
1245.89%3
50%7
40%