@skylivellc/lienzo-editor 0.11.0 → 0.11.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LienzoEditor-CXhUonso.js","names":["field","lienzoCss","isNode","_hoisted_1","_hoisted_2","_hoisted_3","_hoisted_4","_openBlock","_createElementBlock","_normalizeStyle","_withModifiers","_Fragment","_createElementVNode","_unref","_createTextVNode","_toDisplayString","_createCommentVNode","_renderList","_sfc_main","_hoisted_1","_hoisted_2","_hoisted_3","_hoisted_4","_hoisted_5","_hoisted_6","_hoisted_7","_hoisted_8","_hoisted_9","_hoisted_10","_hoisted_11","_hoisted_12","_hoisted_13","_hoisted_14","_openBlock","_createElementBlock","_normalizeStyle","_createCommentVNode","_Fragment","_renderList","_toDisplayString","_unref","_createElementVNode","_withModifiers","_createVNode","_createBlock","_sfc_main","_hoisted_1","_hoisted_2","_hoisted_3","_hoisted_4","_hoisted_5","_hoisted_6","_hoisted_7","_hoisted_8","_hoisted_9","_hoisted_10","_hoisted_11","_hoisted_12","_openBlock","_createElementBlock","_withModifiers","_unref","_toDisplayString","_createCommentVNode","_createElementVNode","_normalizeStyle","_createVNode","Overlay","_createBlock","ContextMenu","_sfc_main","_hoisted_1","_openBlock","_createElementBlock","_createElementVNode","_normalizeStyle","_unref","_sfc_main","_hoisted_1","_openBlock","_createElementBlock","_renderSlot","_sfc_main","_hoisted_1","_hoisted_2","_hoisted_3","_hoisted_4","_hoisted_5","_hoisted_6","_useModel","_openBlock","_createElementBlock","_unref","_createElementVNode","_toDisplayString","_createCommentVNode","_createVNode","_renderSlot","_sfc_main","_hoisted_1","_openBlock","_createBlock","Dialog","_unref","_isRef","_withCtx","_createElementVNode","_createVNode","Button","_createTextVNode","_toDisplayString","_sfc_main","_hoisted_1","_openBlock","_createElementBlock","_renderSlot","_sfc_main","_hoisted_1","_hoisted_2","_hoisted_3","_hoisted_4","_hoisted_5","_hoisted_6","_hoisted_7","_openBlock","_createBlock","Dialog","_unref","_withCtx","_createElementVNode","_createVNode","_toDisplayString","_createElementBlock","_Fragment","_renderList","IconButton","_createCommentVNode","_sfc_main","_hoisted_1","_hoisted_2","_hoisted_3","_hoisted_4","_hoisted_5","_openBlock","_createElementBlock","_createTextVNode","_toDisplayString","_renderSlot","_createCommentVNode","_sfc_main","_hoisted_1","_hoisted_2","_useModel","_withDirectives","_openBlock","_createElementBlock","_vModelText","_vModelDynamic","_sfc_main","_hoisted_1","_openBlock","_createBlock","Dialog","_unref","_isRef","_withCtx","_createElementVNode","_withModifiers","_createVNode","Field","TextInput","_createElementBlock","_Fragment","_renderList","_toDisplayString","Button","_createTextVNode","_sfc_main","_hoisted_1","_hoisted_2","_hoisted_3","_hoisted_4","_hoisted_5","_useModel","_openBlock","_createElementBlock","_createElementVNode","_toDisplayString","_createCommentVNode","_createVNode","Button","_withCtx","_createTextVNode","_unref","_createBlock","TextInput","_sfc_main","_hoisted_1","_hoisted_2","_hoisted_3","_hoisted_4","_useModel","_openBlock","_createElementBlock","_createElementVNode","_toDisplayString","_createCommentVNode","_sfc_main","_hoisted_1","_hoisted_2","_hoisted_3","_useModel","_openBlock","_createElementBlock","_toDisplayString","_createCommentVNode","_Fragment","_renderList","_sfc_main","_hoisted_1","_hoisted_2","_useModel","_openBlock","_createElementBlock","_createElementVNode","_toDisplayString","_sfc_main","_hoisted_1","_hoisted_2","_hoisted_3","_hoisted_4","_openBlock","_createElementBlock","_createVNode","SelectInput","_Fragment","_createBlock","TextInput","_unref","_createElementVNode","_renderList","_toDisplayString","_createCommentVNode","FieldControl","_sfc_main","_hoisted_1","unknown","_openBlock","_createBlock","FieldShell","_unref","_withCtx","_createVNode","TextInput","NumberInput","Toggle","SelectInput","_createElementVNode","_createElementBlock","_Fragment","_renderList","ImageField","ActionPicker","_sfc_main","_hoisted_1","_hoisted_2","_hoisted_3","_hoisted_4","_hoisted_5","_hoisted_6","_hoisted_7","_hoisted_8","_hoisted_9","_hoisted_10","_openBlock","_createBlock","Dialog","_unref","_isRef","_withCtx","_createElementVNode","_withModifiers","_createVNode","Field","TextInput","ImageField","_createElementBlock","_toDisplayString","_createCommentVNode","_Fragment","_renderList","FieldControl","Button","_createTextVNode","_sfc_main","_hoisted_1","_hoisted_2","_hoisted_3","_hoisted_4","_openBlock","_createBlock","Dialog","_unref","_isRef","_withCtx","_createElementBlock","_Fragment","_renderList","_createElementVNode","_toDisplayString","_createCommentVNode","_createVNode","Button","_createTextVNode","_sfc_main","_hoisted_1","_hoisted_2","_hoisted_3","_hoisted_4","_useModel","_openBlock","_createElementBlock","_createElementVNode","_createTextVNode","_toDisplayString","_sfc_main","_hoisted_1","_hoisted_2","_hoisted_3","_hoisted_4","_hoisted_5","_hoisted_6","_hoisted_7","_hoisted_8","_hoisted_9","_hoisted_10","_hoisted_11","_hoisted_12","_hoisted_13","_hoisted_14","_hoisted_15","_hoisted_16","_hoisted_17","_openBlock","_createBlock","Dialog","_unref","_isRef","_withCtx","_createElementVNode","_withModifiers","_toDisplayString","_createElementBlock","_Fragment","_renderList","_normalizeStyle","_createTextVNode","_createVNode","Button","_withDirectives","_vModelText","Field","SelectInput","RangeInput","_sfc_main","_hoisted_1","_hoisted_2","_hoisted_3","_openBlock","_createBlock","Dialog","_unref","_isRef","_withCtx","_createElementBlock","_Fragment","_renderList","_createElementVNode","_toDisplayString","_createCommentVNode","_createVNode","Button","_createTextVNode","_sfc_main","icons","catalog","_hoisted_1","_openBlock","_createElementBlock","_Fragment","_renderList","_createBlock","_resolveDynamicComponent","_mergeProps","_sfc_main","_openBlock","_createBlock","_resolveDynamicComponent","_unref","CatalogIcon","_sfc_main","_hoisted_1","_hoisted_2","_hoisted_3","_hoisted_4","_hoisted_5","_hoisted_6","_hoisted_7","_hoisted_8","_hoisted_9","_hoisted_10","_hoisted_11","_hoisted_12","_hoisted_13","ImageIcon","_openBlock","_createElementBlock","_createElementVNode","_Fragment","_renderList","_createBlock","_resolveDynamicComponent","_createTextVNode","_toDisplayString","_unref","_createVNode","CatalogIcon","_createCommentVNode","_normalizeStyle","_withDirectives","ElementIcon","_vShow","_vModelText","_sfc_main","_openBlock","_createElementBlock","_Fragment","_renderList","_createBlock","FieldControl","_unref","_sfc_main","_openBlock","_createElementBlock","_Fragment","_createVNode","Field","_unref","_withCtx","TextInput","ActionPicker","_sfc_main","_openBlock","_createElementBlock","_Fragment","_createVNode","Field","_unref","_withCtx","TextInput","_createBlock","SelectInput","_createCommentVNode","Toggle","_sfc_main","_hoisted_1","_hoisted_2","_hoisted_3","_openBlock","_createElementBlock","_Fragment","_createVNode","Field","_unref","_withCtx","TextInput","_createElementVNode","_renderList","CatalogIcon","_toDisplayString","_createCommentVNode","RangeInput","_sfc_main","_openBlock","_createElementBlock","_Fragment","_createVNode","ImageField","_unref","Field","_withCtx","TextInput","SelectInput","_sfc_main","_hoisted_1","_hoisted_2","_hoisted_3","_hoisted_4","_openBlock","_createElementBlock","_createElementVNode","_toDisplayString","_unref","_createVNode","Button","_withCtx","_createTextVNode","_Fragment","_renderList","ImageField","_sfc_main","_openBlock","_createElementBlock","_Fragment","_createVNode","Field","_unref","_withCtx","SelectInput","_createBlock","NumberInput","_createCommentVNode","PictureList","TextInput","_sfc_main","_openBlock","_createElementBlock","_Fragment","_createVNode","PictureList","Toggle","_unref","_createBlock","NumberInput","_createCommentVNode","Field","_withCtx","TextInput","_sfc_main","_hoisted_1","_hoisted_2","_hoisted_3","_hoisted_4","_hoisted_5","_hoisted_6","_useModel","_openBlock","_createElementBlock","_createElementVNode","_toDisplayString","_Fragment","_renderList","_unref","_normalizeStyle","_createTextVNode","_sfc_main","_hoisted_1","_hoisted_2","_hoisted_3","_hoisted_4","_hoisted_5","_hoisted_6","_hoisted_7","_hoisted_8","_hoisted_9","_hoisted_10","_openBlock","_createElementBlock","_Fragment","_createElementVNode","_toDisplayString","_unref","_renderList","_createBlock","Button","_withCtx","_createTextVNode","_createVNode","Field","TextInput","Toggle","SelectInput","_createCommentVNode","ColorPicker","ActionPicker","_sfc_main","_openBlock","_createElementBlock","_Fragment","_createVNode","Field","_unref","_withCtx","SelectInput","RangeInput","_sfc_main","_openBlock","_createElementBlock","_Fragment","_createVNode","Field","_unref","_withCtx","TextInput","_createBlock","ColorPicker","_createCommentVNode","SelectInput","_sfc_main","_openBlock","_createBlock","Field","_unref","_withCtx","_createVNode","TextInput","_sfc_main","_hoisted_1","_hoisted_2","_openBlock","_createElementBlock","_createElementVNode","_createTextVNode","_toDisplayString","_createVNode","_unref","_renderSlot","_sfc_main","_hoisted_1","_hoisted_2","_hoisted_3","_hoisted_4","_useModel","_openBlock","_createElementBlock","_createElementVNode","_unref","_Fragment","_renderList","_normalizeStyle","_createVNode","ColorPicker","Field","_withCtx","SelectInput","_createBlock","RangeInput","_createCommentVNode","_sfc_main","_hoisted_1","_hoisted_2","_hoisted_3","_hoisted_4","_openBlock","_createBlock","PanelSection","_unref","_withCtx","_createVNode","ColorPicker","_createElementVNode","_toDisplayString","SelectInput","GradientEditor","RangeInput","_createElementBlock","_createCommentVNode","_sfc_main","_hoisted_1","_hoisted_2","_openBlock","_createElementBlock","_Fragment","_createVNode","PanelSection","_unref","_withCtx","_createElementVNode","NumberInput","_createBlock","ColorPicker","_createCommentVNode","Field","SelectInput","RangeInput","_sfc_main","_hoisted_1","_hoisted_2","_openBlock","_createBlock","PanelSection","_unref","_withCtx","_createVNode","Field","SelectInput","_createElementBlock","RangeInput","_createCommentVNode","_createElementVNode","_toDisplayString","_sfc_main","_hoisted_1","_openBlock","_createElementBlock","_unref","_Fragment","_renderList","_createBlock","IconButton","_withCtx","_resolveDynamicComponent","_sfc_main","_hoisted_1","_hoisted_2","_hoisted_3","_openBlock","_createBlock","PanelSection","_unref","_withCtx","_createVNode","AlignButtons","_createElementVNode","NumberInput","Toggle","_toDisplayString","_createElementBlock","_Fragment","_createTextVNode","_createCommentVNode","_sfc_main","_hoisted_1","_hoisted_2","_hoisted_3","_hoisted_4","_hoisted_5","_hoisted_6","_hoisted_7","_hoisted_8","_openBlock","_createBlock","PanelSection","_unref","_withCtx","_createElementVNode","_createElementBlock","_Fragment","_renderList","_toDisplayString","_createVNode","NumberInput","SelectInput","IconButton","_resolveDynamicComponent","Toggle","_sfc_main","_hoisted_1","_hoisted_2","_hoisted_3","_openBlock","_createBlock","PanelSection","_unref","_withCtx","_createElementVNode","_createVNode","NumberInput","IconButton","Field","SelectInput","_toDisplayString","_sfc_main","_hoisted_1","_hoisted_2","_hoisted_3","_hoisted_4","_hoisted_5","TextContent","ImageContent","ButtonContent","VideoContent","ShapeContent","IconContent","NavbarContent","GalleryContent","SliderContent","FormFieldContent","FillStyle","TextStyle","FrameStyle","TransformStyle","MotionStyle","_openBlock","_createElementBlock","_createElementVNode","_toDisplayString","_createBlock","Button","_unref","_withCtx","_createTextVNode","_createCommentVNode","_createVNode","_Fragment","_resolveDynamicComponent","AppContent","_renderList","PositionSection","_sfc_main","_hoisted_1","_hoisted_2","_hoisted_3","_hoisted_4","_hoisted_5","_hoisted_6","_hoisted_7","_hoisted_8","_hoisted_9","_openBlock","_createElementBlock","_createElementVNode","_toDisplayString","_unref","_createVNode","Field","_withCtx","TextInput","Toggle","_Fragment","_renderList","_createBlock","Button","_createTextVNode","NumberInput","_createCommentVNode","ColorPicker","_sfc_main","_hoisted_1","_hoisted_2","_hoisted_3","_hoisted_4","_hoisted_5","_hoisted_6","_hoisted_7","_hoisted_8","_hoisted_9","_hoisted_10","FillStyle","TextStyle","FrameStyle","TransformStyle","MotionStyle","_openBlock","_createElementBlock","_createElementVNode","_toDisplayString","_unref","_createVNode","AlignButtons","IconButton","_withCtx","_Fragment","_renderList","_createBlock","_resolveDynamicComponent","_createCommentVNode","_sfc_main","_hoisted_1","_hoisted_2","_hoisted_3","_hoisted_4","_hoisted_5","_hoisted_6","_hoisted_7","_openBlock","_createElementBlock","_createElementVNode","_toDisplayString","_unref","_createBlock","IconButton","_withCtx","_createVNode","_createCommentVNode","Field","SelectInput","TextInput","Button","_createTextVNode","NumberInput","Toggle","ColorPicker","GradientEditor","_Fragment","ImageField","RangeInput","_sfc_main","_hoisted_1","_openBlock","_createBlock","MultiPanel","ElementPanel","ModalPanel","SectionPanel","_createElementBlock","_toDisplayString","_unref","_sfc_main","_hoisted_1","_hoisted_2","_hoisted_3","_hoisted_4","_hoisted_5","_hoisted_6","_hoisted_7","_hoisted_8","_hoisted_9","_hoisted_10","_hoisted_11","_openBlock","_createElementBlock","_createVNode","Field","_unref","_withCtx","TextInput","_createBlock","_createElementVNode","_createTextVNode","_toDisplayString","_Fragment","Button","_renderList","_createCommentVNode","_sfc_main","_hoisted_1","_hoisted_2","_hoisted_3","_hoisted_4","_hoisted_5","_openBlock","_createElementBlock","_createElementVNode","_toDisplayString","_unref","_createBlock","DesignPanel","PagePanel","_sfc_main","_hoisted_1","_hoisted_2","_hoisted_3","_hoisted_4","_hoisted_5","_hoisted_6","_openBlock","_createElementBlock","_createElementVNode","_toDisplayString","_unref","_Fragment","_renderList","_createCommentVNode","_createVNode","Button","_withCtx","_createTextVNode","_createBlock","_sfc_main","base","shell","canvas","panels","_hoisted_1","_hoisted_2","_hoisted_3","_openBlock","_createElementBlock","_Fragment","_renderList","_unref","_createElementVNode","_toDisplayString","_createVNode","_sfc_main","_openBlock","_createElementBlock","_unref","_toDisplayString","_createElementVNode","_createVNode","Button","_withCtx","_createTextVNode","_Fragment","Toolbar","LeftSidebar","_createBlock","Preview","Canvas","RightPanel","NewPageDialog","VersionsDialog","ThemeDialog","SiteDialog","SubmissionsDialog","ConflictDialog","MediaLibrary","Toasts","_sfc_main","CORE_TYPES","coreTypes","isCoreType","type","isModal","canvas","canvasesOf","document","findCanvas","id","boxOf","device","element","writeBox","box","canvasHeight","stacksOnMobile","newId","prefix","copyElement","copy","plain","offset","value","emptySection","MODAL_SIZES","emptyModal","HANDLES","ALIGNMENTS","clamp","max","min","snap","grid","clampBox","dragBox","percent","frameWidth","start","handle","delta","anchorsOf","x","y","frameHeight","others","left","width","nearest","best","edge","edges","target","targets","shift","threshold","snapToAnchors","next","guides","horizontal","vertical","anchors","alignInCanvas","where","alignTogether","boxes","right","top","bottom","distribute","order","a","axis","b","first","step","result","position","index","frontLayer","backLayer","fitHeight","lowest","stackForMobile","elements","factor","mobileWidth","reference","height","THEME_TOKENS","tokens","isThemeToken","PALETTES","FONTS","fontNote","font","MAX_WIDTHS","widthLabel","GRADIENT_PRESETS","swatch","theme","gradientCss","from","gradient","to","distance","channels","hex","r1","g1","b1","r2","g2","b2","nearestToken","linkToPalette","background","key","fontsHref","fonts","ALL","NO_TEXT","field$1","coreSpecs","t","navbarPresets","anchor","label","kindOf","spec","catalog","candidate","createElement","draft","insertable","appDraft","props","field","elementName","text","createHistory","entries","initial","cursor","move","snapshot","limit","en","es","packs","createTranslator","language","locale","chain","overrides","lookup","pack","format","params","template","name","match","english","build","parts","defaults","part","color","token","feature","title","plan","featured","price","lines","number","person","role","question","ask","answer","sections","SECTION_TEMPLATES","TEMPLATE_GROUPS","pages","PAGE_TEMPLATES","buildSectionTemplate","buildPageTemplate","section","createAutosave","state","shallowRef","read","saved","generation","timer","running","schedule","run","wait","sentIn","attempt","save","outcome","delay","failed","offlineRetry","online","work","task","failure","createPreviews","cache","queue","version","flush","batch","client","html","previewKey","CLIPBOARD_KEY","editorKey","useEditor","editor","inject","createEditor","i18n","reactive","parseSiteSettings","history","historyTick","previews","autosave","blankToNull","watch","syncSummary","computed","site","error","DocumentError","previous","canvases","modal","activeModal","view","currentCanvas","selection","selectedElements","activeElement","toastId","notify","toast","dismiss","tone","failureText","load","issueText","openPage","loadPage","adoptPage","parseDocument","page","summary","saveProblem","current","reloadPage","commit","restoreFrom","json","keepSelectionValid","canUndo","canRedo","ids","selectCanvas","canvasId","revealSection","select","clicked","elementId","family","additive","clearSelection","groupId","addElement","at","src","removeSelected","duplicateSelected","pasteInto","groups","copies","group","copySelected","paste","stored","parsesAsElement","layer","moving","ordered","align","distributeSelected","sharedTarget","fanOut","property","style","groupSelected","ungroupSelected","toggleLock","locking","nudge","dx","dy","placeElements","addSection","after","item","applyPageTemplate","duplicateSection","toRaw","removeSection","moveSection","other","setSectionGroup","mode","member","fitCanvas","generateMobile","addModal","openModal","removeModal","undo","redo","saveNow","publish","response","restoreVersion","problem","createPage","renamePage","slug","deletePage","updateSite","update","uploadAsset","body","file","refreshQuota","deleteAsset","asset","dialogModel","open","openLibrary","issue","seo","TYPING","typing","event","handleShortcut","selected","command","lienzo_default","frameCss","renderContext","renderDraft","context","renderPage","ref","preview","trustedHtml","escapeHtml","ESCAPES","char","domId","mountFrame","found","iframe","doc","View","sheet","created","css","pageSheet","rendered","patch","lookupOf","dialog","groupIdOf","stack","panel","button","node","nodes","markup","existing","reusable","stackId","elementNode","canvasNode","frameNode","hit","isNode$1","elementNodeHit","canvasHit","rectOf","measure","outer","frame","frameRect","w","h","_hoisted_1$47","_hoisted_2$38","_hoisted_3$33","_hoisted_4$27","ContextMenu_default","defineComponent","__emit","__props","emit","menu","many","grouped","locked","action","place","nextTick","onPointerDown","onKey","onMounted","onBeforeUnmount","openBlock","createElementBlock","normalizeStyle","_cache","withModifiers","Fragment","createElementVNode","unref","createTextVNode","toDisplayString","createCommentVNode","renderList","_hoisted_1$46","_hoisted_2$37","_hoisted_3$32","_hoisted_4$26","_hoisted_5$19","_hoisted_6$15","_hoisted_7$12","_hoisted_8$10","_hoisted_9$9","_hoisted_10$8","_hoisted_11$5","_hoisted_12$4","_hoisted_13$3","_hoisted_14$2","Overlay_default","rect","single","only","active","hoverRect","canvasOutline","guideFrame","stickies","stacked","metrics","sticky","createVNode","Plus","CopyPlus","Trash2","line","createBlock","Lock","$event","RotateCw","Copy","ArrowUpToLine","ArrowDownToLine","_hoisted_1$45","_hoisted_2$36","_hoisted_3$31","_hoisted_4$25","_hoisted_5$18","_hoisted_6$14","_hoisted_7$11","_hoisted_8$9","_hoisted_9$8","_hoisted_10$7","_hoisted_11$4","_hoisted_12$3","MIN_ZOOM","MAX_ZOOM","Canvas_default","__expose","stage","scaler","stageWidth","contentHeight","layout","hovered","live","rotation","hint","fitScale","scale","zoomPercent","zoomTo","stageEl","sheetEl","point","before","frameX","frameY","zoomBy","fitToStage","onWheel","onFrameWheel","spaceHeld","panning","pan","startPan","movePan","endPan","onStageKeyDown","onStageKeyUp","releaseSpace","onWindowKeyDown","onZoomShortcut","frozen","empty","scheduled","rendering","again","render","editing","gesture","relayout","release","capture","onGestureMove","end","finishGesture","events","startBoxGesture","movable","turned","angle","dragged","snapped","rects","apply","finished","elementById","center","onResize","onRotate","onRadius","switchPanel","finishEditing","onDoubleClick","kind","onKeyDown","menuAt","onContextMenu","inFrame","onPointerOver","inert","dropPoint","clientX","clientY","stageObserver","frameObserver","observer","entry","deviceName","_hoisted_1$44","Preview_default","size","createClient","fetcher","base","endpoint","args","method","route","isRecord","path","isForm","query","searchParams","init","xsrfHeader","headers","failureOf","message","status","isIssue","_hoisted_1$43","Button_default","renderSlot","_ctx","_hoisted_1$42","_hoisted_2$35","_hoisted_3$30","_hoisted_4$24","_hoisted_5$17","_hoisted_6$13","Dialog_default","\"open\"","\"openModifiers\"","useModel","heading","useId","sync","downOnBackdrop","pressed","X","_hoisted_1$41","ConflictDialog_default","isRef","withCtx","_hoisted_1$40","IconButton_default","_hoisted_1$39","_hoisted_2$34","_hoisted_3$29","_hoisted_4$23","_hoisted_5$16","_hoisted_6$12","_hoisted_7$10","MediaLibrary_default","input","uploading","UNITS","bytes","quota","used","upload","use","onPick","Upload","_hoisted_1$38","_hoisted_2$33","_hoisted_3$28","_hoisted_4$22","_hoisted_5$15","Field_default","_hoisted_1$37","_hoisted_2$32","TextInput_default","\"modelValue\"","\"modelModifiers\"","model","withDirectives","vModelText","vModelDynamic","_hoisted_1$36","NewPageDialog_default","form","now","address","issueAt","otherIssues","create","_hoisted_1$35","_hoisted_2$31","_hoisted_3$27","_hoisted_4$21","_hoisted_5$14","ImageField_default","pick","remove","_hoisted_1$34","_hoisted_2$30","_hoisted_3$26","_hoisted_4$20","NumberInput_default","raw","_hoisted_1$33","_hoisted_2$29","_hoisted_3$25","SelectInput_default","change","option","_hoisted_1$32","_hoisted_2$28","Toggle_default","CORE_ACTIONS","isCoreAction","defaultActionValue","_hoisted_1$31","_hoisted_2$27","_hoisted_3$24","_hoisted_4$19","ActionPicker_default","app","control","options","list","CORE_ACTION_TYPES","core","modals","setType","setValue","appValue","FieldControl_default","_hoisted_1$30","isAction","toggleChoice","on","chosen","_hoisted_1$29","_hoisted_2$26","_hoisted_3$23","_hoisted_4$18","_hoisted_5$13","_hoisted_6$11","_hoisted_7$9","_hoisted_8$8","_hoisted_9$7","_hoisted_10$6","SiteDialog_default","blank","fields","nullIfBlank","PATHS","setMeta","_hoisted_1$28","_hoisted_2$25","_hoisted_3$22","_hoisted_4$17","SubmissionsDialog_default","submissions","loading","date","labels","submission","_hoisted_1$27","_hoisted_2$24","_hoisted_3$21","_hoisted_4$16","RangeInput_default","_hoisted_1$26","_hoisted_2$23","_hoisted_3$20","_hoisted_4$15","_hoisted_5$12","_hoisted_6$10","_hoisted_7$8","_hoisted_8$7","_hoisted_9$6","_hoisted_10$5","_hoisted_11$3","_hoisted_12$2","_hoisted_13$2","_hoisted_14$1","_hoisted_15$1","_hoisted_16$1","_hoisted_17$1","ThemeDialog_default","HEX","issues","saving","valid","colors","widths","applyPalette","linkElements","colorOf","palette","_hoisted_1$25","_hoisted_2$22","_hoisted_3$19","VersionsDialog_default","versions","icons$1","TAGS","isNode","attr","parseIcons","icons","ICON_NAMES","_hoisted_1$24","CatalogIcon_default","resolveDynamicComponent","mergeProps","typeIcons","Type","AlignLeft","Image","MousePointerClick","Minus","Video","Square","Sparkles","Menu","Images","GalleryHorizontalEnd","TextCursorInput","Pilcrow","ListFilter","SquareCheck","ElementIcon_default","CircleHelp","_hoisted_1$23","_hoisted_2$21","_hoisted_3$18","_hoisted_4$14","_hoisted_5$11","_hoisted_6$9","_hoisted_7$7","_hoisted_8$6","_hoisted_9$5","_hoisted_10$4","_hoisted_11$2","_hoisted_12$1","_hoisted_13$1","_hoisted_14","_hoisted_15","_hoisted_16","_hoisted_17","_hoisted_18","_hoisted_19","_hoisted_20","_hoisted_21","_hoisted_22","_hoisted_23","_hoisted_24","_hoisted_25","_hoisted_26","_hoisted_27","_hoisted_28","_hoisted_29","_hoisted_30","_hoisted_31","_hoisted_32","_hoisted_33","_hoisted_34","_hoisted_35","_hoisted_36","_hoisted_37","_hoisted_38","_hoisted_39","_hoisted_40","_hoisted_41","_hoisted_42","_hoisted_43","_hoisted_44","_hoisted_45","_hoisted_46","_hoisted_47","_hoisted_48","_hoisted_49","_hoisted_50","_hoisted_51","_hoisted_52","LeftSidebar_default","tab","tabs","LayoutTemplate","Layers","PanelTop","contentTypes","formTypes","dragging","startDrag","moveDrag","held","moved","drop","spot","coreLabel","collapsed","toggleCollapsed","selectedIds","canvasSelected","layerLabel","toggleLocked","ChevronDown","Frame","ChevronUp","LockOpen","vShow","AppContent_default","set","ButtonContent_default","MAX_OPTIONS","FormFieldContent_default","inputTypes","optionsText","setOptions","_hoisted_1$22","_hoisted_2$20","_hoisted_3$17","IconContent_default","search","matches","term","SHAPES","shapeOptions","ImageContent_default","fits","_hoisted_1$21","_hoisted_2$19","_hoisted_3$16","_hoisted_4$13","MAX_PICTURES","PictureList_default","pictures","source","picture","add","GalleryContent_default","layouts","SliderContent_default","_hoisted_1$20","_hoisted_2$18","_hoisted_3$15","_hoisted_4$12","_hoisted_5$10","_hoisted_6$8","ColorPicker_default","custom","_hoisted_1$19","_hoisted_2$17","_hoisted_3$14","_hoisted_4$11","_hoisted_5$9","_hoisted_6$7","_hoisted_7$6","_hoisted_8$5","_hoisted_9$4","_hoisted_10$3","MAX_LINKS","NavbarContent_default","presets","scrollStyles","templates","positions","links","applyPreset","preset","addLink","removeLink","link","ShapeContent_default","TextContent_default","levels","level","VideoContent_default","_hoisted_1$18","_hoisted_2$16","PanelSection_default","_hoisted_1$17","_hoisted_2$15","_hoisted_3$13","_hoisted_4$10","GradientEditor_default","DEFAULT","_hoisted_1$16","_hoisted_2$14","_hoisted_3$12","_hoisted_4$9","FillStyle_default","setMode","_hoisted_1$15","_hoisted_2$13","FrameStyle_default","shadows","shadow","DEFAULT_SHADOW","setShadow","_hoisted_1$14","_hoisted_2$12","MotionStyle_default","entrances","scrolls","hovers","seconds","DEFAULT_ANIMATION","animation","setAnimation","_hoisted_1$13","AlignButtons_default","AlignStartVertical","AlignCenterVertical","AlignEndVertical","AlignStartHorizontal","AlignCenterHorizontal","AlignEndHorizontal","_hoisted_1$12","_hoisted_2$11","_hoisted_3$11","PositionSection_default","inherit","_hoisted_1$11","_hoisted_2$10","_hoisted_3$10","_hoisted_4$8","_hoisted_5$8","_hoisted_6$6","_hoisted_7$5","_hoisted_8$4","TextStyle_default","aligns","AlignCenter","AlignRight","weights","weight","cases","faces","_hoisted_1$10","_hoisted_2$9","_hoisted_3$9","TransformStyle_default","overflows","devices","RotateCcw","FoldHorizontal","FoldVertical","_hoisted_1$9","_hoisted_2$8","_hoisted_3$8","_hoisted_4$7","_hoisted_5$7","ElementPanel_default","coreContent","stylePanels","styles","declared","_hoisted_1$8","_hoisted_2$7","_hoisted_3$7","_hoisted_4$6","_hoisted_5$6","_hoisted_6$5","_hoisted_7$4","_hoisted_8$3","_hoisted_9$3","ModalPanel_default","applySize","setWidth","_hoisted_1$7","_hoisted_2$6","_hoisted_3$6","_hoisted_4$5","_hoisted_5$5","_hoisted_6$4","_hoisted_7$3","_hoisted_8$2","_hoisted_9$2","_hoisted_10$2","MultiPanel_default","count","shared","AlignHorizontalDistributeCenter","AlignVerticalDistributeCenter","_hoisted_1$6","_hoisted_2$5","_hoisted_3$5","_hoisted_4$4","_hoisted_5$4","_hoisted_6$3","_hoisted_7$2","SectionPanel_default","groupModes","flows","flowing","backgrounds","anchorInvalid","saveAnchor","taken","setBackground","setImage","image","_hoisted_1$5","DesignPanel_default","shown","_hoisted_1$4","_hoisted_2$4","_hoisted_3$4","_hoisted_4$3","_hoisted_5$3","_hoisted_6$2","_hoisted_7$1","_hoisted_8$1","_hoisted_9$1","_hoisted_10$1","_hoisted_11$1","PagePanel_default","slugIssues","isEmpty","saveAddress","_hoisted_1$3","_hoisted_2$3","_hoisted_3$3","_hoisted_4$2","_hoisted_5$2","RightPanel_default","_hoisted_1$2","_hoisted_2$2","_hoisted_3$2","_hoisted_4$1","_hoisted_5$1","_hoisted_6$1","_hoisted_7","_hoisted_8","_hoisted_9","_hoisted_10","_hoisted_11","_hoisted_12","_hoisted_13","Toolbar_default","time","publicUrl","choosePage","Monitor","Smartphone","Undo2","Redo2","PencilLine","Eye","History","editorCss","adopted","adoptEditorStyles","root","_hoisted_1$1","_hoisted_2$1","_hoisted_3$1","Toasts_default","_hoisted_1","_hoisted_2","_hoisted_3","_hoisted_4","_hoisted_5","_hoisted_6","LienzoEditor_default","inside","onPage","watchEffect"],"sources":["../src/model/document.ts","../src/model/geometry.ts","../src/model/theme.ts","../src/model/elements.ts","../src/model/history.ts","../src/i18n/en.ts","../src/i18n/es.ts","../src/i18n/index.ts","../src/model/templates.ts","../src/state/autosave.ts","../src/state/previews.ts","../src/state/editor.ts","../src/state/shortcuts.ts","../src/canvas/frameCss.ts","../src/canvas/render.ts","../src/canvas/frame.ts","../src/canvas/ContextMenu.vue","../src/canvas/ContextMenu.vue","../src/canvas/Overlay.vue","../src/canvas/Overlay.vue","../src/canvas/Canvas.vue","../src/canvas/Canvas.vue","../src/canvas/Preview.vue","../src/canvas/Preview.vue","../src/client.ts","../src/ui/Button.vue","../src/ui/Button.vue","../src/ui/Dialog.vue","../src/ui/Dialog.vue","../src/dialogs/ConflictDialog.vue","../src/dialogs/ConflictDialog.vue","../src/ui/IconButton.vue","../src/ui/IconButton.vue","../src/dialogs/MediaLibrary.vue","../src/dialogs/MediaLibrary.vue","../src/ui/Field.vue","../src/ui/Field.vue","../src/ui/TextInput.vue","../src/ui/TextInput.vue","../src/dialogs/NewPageDialog.vue","../src/dialogs/NewPageDialog.vue","../src/ui/ImageField.vue","../src/ui/ImageField.vue","../src/ui/NumberInput.vue","../src/ui/NumberInput.vue","../src/ui/SelectInput.vue","../src/ui/SelectInput.vue","../src/ui/Toggle.vue","../src/ui/Toggle.vue","../src/panels/actions.ts","../src/panels/ActionPicker.vue","../src/panels/ActionPicker.vue","../src/panels/FieldControl.vue","../src/panels/FieldControl.vue","../src/dialogs/SiteDialog.vue","../src/dialogs/SiteDialog.vue","../src/dialogs/SubmissionsDialog.vue","../src/dialogs/SubmissionsDialog.vue","../src/ui/RangeInput.vue","../src/ui/RangeInput.vue","../src/dialogs/ThemeDialog.vue","../src/dialogs/ThemeDialog.vue","../src/dialogs/VersionsDialog.vue","../src/dialogs/VersionsDialog.vue","../../core/dist/data.json","../src/model/icons.ts","../src/ui/CatalogIcon.vue","../src/ui/CatalogIcon.vue","../src/shell/typeIcons.ts","../src/shell/ElementIcon.vue","../src/shell/ElementIcon.vue","../src/shell/LeftSidebar.vue","../src/shell/LeftSidebar.vue","../src/panels/content/AppContent.vue","../src/panels/content/AppContent.vue","../src/panels/content/ButtonContent.vue","../src/panels/content/ButtonContent.vue","../src/panels/content/FormFieldContent.vue","../src/panels/content/FormFieldContent.vue","../src/panels/content/IconContent.vue","../src/panels/content/IconContent.vue","../src/panels/content/shapes.ts","../src/panels/content/ImageContent.vue","../src/panels/content/ImageContent.vue","../src/panels/content/PictureList.vue","../src/panels/content/PictureList.vue","../src/panels/content/GalleryContent.vue","../src/panels/content/GalleryContent.vue","../src/panels/content/SliderContent.vue","../src/panels/content/SliderContent.vue","../src/ui/ColorPicker.vue","../src/ui/ColorPicker.vue","../src/panels/content/NavbarContent.vue","../src/panels/content/NavbarContent.vue","../src/panels/content/ShapeContent.vue","../src/panels/content/ShapeContent.vue","../src/panels/content/TextContent.vue","../src/panels/content/TextContent.vue","../src/panels/content/VideoContent.vue","../src/panels/content/VideoContent.vue","../src/ui/PanelSection.vue","../src/ui/PanelSection.vue","../src/panels/GradientEditor.vue","../src/panels/GradientEditor.vue","../src/panels/style/FillStyle.vue","../src/panels/style/FillStyle.vue","../src/panels/style/FrameStyle.vue","../src/panels/style/FrameStyle.vue","../src/panels/style/MotionStyle.vue","../src/panels/style/MotionStyle.vue","../src/panels/AlignButtons.vue","../src/panels/AlignButtons.vue","../src/panels/style/PositionSection.vue","../src/panels/style/PositionSection.vue","../src/panels/style/TextStyle.vue","../src/panels/style/TextStyle.vue","../src/panels/style/TransformStyle.vue","../src/panels/style/TransformStyle.vue","../src/panels/ElementPanel.vue","../src/panels/ElementPanel.vue","../src/panels/ModalPanel.vue","../src/panels/ModalPanel.vue","../src/panels/MultiPanel.vue","../src/panels/MultiPanel.vue","../src/panels/SectionPanel.vue","../src/panels/SectionPanel.vue","../src/panels/DesignPanel.vue","../src/panels/DesignPanel.vue","../src/panels/PagePanel.vue","../src/panels/PagePanel.vue","../src/shell/RightPanel.vue","../src/shell/RightPanel.vue","../src/shell/Toolbar.vue","../src/shell/Toolbar.vue","../src/styles/base.css?inline","../src/styles/canvas.css?inline","../src/styles/shell.css?inline","../src/styles/panels.css?inline","../src/styles/index.ts","../src/ui/Toasts.vue","../src/ui/Toasts.vue","../src/LienzoEditor.vue","../src/LienzoEditor.vue"],"sourcesContent":["import type { Box, CoreElementType, Document, Element, Modal, Section } from '@skylivellc/lienzo-core';\n\n/** Lienzo designs every page twice: on a desktop frame and on a phone frame. */\nexport type Device = 'desktop' | 'mobile';\n\n/** Reference width of each frame, in design pixels. Desktop follows the theme's max width. */\nexport const MOBILE_WIDTH = 390;\n\n/** A section or a modal: both are free-layout canvases of elements. */\nexport type Canvas = Section | Modal;\n\nexport const CORE_TYPES = [\n 'heading', 'text', 'image', 'button', 'divider', 'video', 'shape', 'icon', 'navbar', 'gallery', 'slider',\n 'input', 'textarea', 'select', 'checkbox',\n] as const satisfies readonly CoreElementType[];\n\nconst coreTypes: ReadonlySet<string> = new Set(CORE_TYPES);\nexport const isCoreType = (type: string): type is CoreElementType => coreTypes.has(type);\n\nexport const isModal = (canvas: Canvas): canvas is Modal => 'title' in canvas;\n\nexport function canvasesOf(document: Document): Canvas[] {\n return [...document.sections, ...(document.modals ?? [])];\n}\n\nexport function findCanvas(document: Document, id: string): Canvas | undefined {\n return canvasesOf(document).find((canvas) => canvas.id === id);\n}\n\n/** The box edited on this device. A phone without its own box shows the desktop one. */\nexport function boxOf(element: Element, device: Device): Box {\n return device === 'desktop' ? element.layout.desktop : (element.layout.mobile ?? element.layout.desktop);\n}\n\nexport function writeBox(element: Element, device: Device, box: Box): void {\n if (device === 'desktop') {\n element.layout.desktop = box;\n } else {\n element.layout.mobile = box;\n }\n}\n\nexport function canvasHeight(canvas: Canvas, device: Device): number {\n return device === 'desktop' ? canvas.height.desktop : canvas.height.mobile;\n}\n\n/**\n * On a phone a canvas keeps free positions only when every element has its\n * own mobile box; otherwise core stacks its elements in reading order.\n */\nexport const stacksOnMobile = (canvas: Canvas): boolean => canvas.elements.some((element) => !element.layout.mobile);\n\n/** Ids are prefixed by kind so stored documents stay readable. */\nexport function newId(prefix: string): string {\n return `${prefix}-${Math.random().toString(36).slice(2, 9)}`;\n}\n\n/** A fresh copy of an element with a new id, nudged down so it does not hide the original. */\nexport function copyElement(element: Element, offset = 24): Element {\n const copy = plain(element);\n\n return {\n ...copy,\n id: newId(copy.type),\n layout: { ...copy.layout, desktop: { ...copy.layout.desktop, y: copy.layout.desktop.y + offset } },\n };\n}\n\n/** A deep copy as plain data, also out of a reactive proxy. Documents are JSON by definition. */\nexport function plain<T>(value: T): T {\n return JSON.parse(JSON.stringify(value)) as T;\n}\n\nexport function emptySection(): Section {\n return {\n id: newId('section'),\n height: { desktop: 520, mobile: 560 },\n background: { type: 'color', color: 'background', overlay: 0 },\n elements: [],\n };\n}\n\n/** Modal sizes with a fixed width. At full screen the design is made on 1200. */\nexport const MODAL_SIZES = [\n { key: 'sm', width: 420 },\n { key: 'md', width: 560 },\n { key: 'lg', width: 760 },\n { key: 'xl', width: 960 },\n { key: 'full', width: 1200 },\n] as const;\n\nexport function emptyModal(title: string): Modal {\n return {\n id: newId('modal'),\n title,\n size: 'md',\n show_title: true,\n width: MODAL_SIZES[1].width,\n height: { desktop: 320, mobile: 420 },\n background: { type: 'color', color: 'background' },\n elements: [],\n };\n}\n","import type { Box } from '@skylivellc/lienzo-core';\n\n/**\n * Layout math of the canvas, in design units: x and w are percent of the\n * frame width, y and h are design pixels. Pure, so the canvas gestures and\n * the panels share one copy and the tests drive it directly.\n */\n\nexport type Handle = 'nw' | 'n' | 'ne' | 'e' | 'se' | 's' | 'sw' | 'w';\nexport const HANDLES: readonly Handle[] = ['nw', 'n', 'ne', 'e', 'se', 's', 'sw', 'w'];\n\nexport type Alignment = 'left' | 'hcenter' | 'right' | 'top' | 'vmiddle' | 'bottom';\nexport const ALIGNMENTS: readonly Alignment[] = ['left', 'hcenter', 'right', 'top', 'vmiddle', 'bottom'];\n\n/** Guide lines that matched, in design pixels from the frame's left and top edges. */\nexport type Guides = { x: number[]; y: number[] };\n\nexport const clamp = (value: number, min: number, max: number): number => Math.min(max, Math.max(min, value));\n\n/** Rounds to a grid, 4 design pixels by default, so nothing sits on half a pixel. */\nexport const snap = (value: number, grid = 4): number => Math.round(value / grid) * grid;\n\n/** Keeps a box inside the ranges a document accepts, with room to bleed off the edges. */\nexport const clampBox = (box: Box): Box => ({\n x: clamp(box.x, -10, 110),\n y: clamp(box.y, -400, 3000),\n w: clamp(box.w, 0.5, 100),\n h: clamp(box.h, 1, 3000),\n});\n\n/**\n * The box after dragging by `delta` design pixels: the whole box when\n * `handle` is null, otherwise the edges that handle owns. x snaps to half a\n * percent and y to the 4px grid.\n */\nexport function dragBox(start: Box, delta: { x: number; y: number }, handle: Handle | null, frameWidth: number): Box {\n const percent = (value: number) => (value / frameWidth) * 100;\n const box = { ...start };\n\n if (handle === null) {\n box.x = snap(start.x + percent(delta.x), 0.5);\n box.y = snap(start.y + delta.y);\n } else {\n if (handle.includes('e')) {\n box.w = start.w + percent(delta.x);\n }\n if (handle.includes('s')) {\n box.h = snap(start.h + delta.y);\n }\n if (handle.includes('w')) {\n box.x = snap(start.x + percent(delta.x), 0.5);\n box.w = start.w - percent(delta.x);\n }\n if (handle.includes('n')) {\n box.y = snap(start.y + delta.y);\n box.h = snap(start.h - delta.y);\n }\n box.w = snap(box.w, 0.5);\n }\n\n return clampBox(box);\n}\n\n/** Edges and centers worth aligning to: the frame's, then every other element's. */\nexport type Anchors = { x: number[]; y: number[] };\n\nexport function anchorsOf(others: readonly Box[], frameWidth: number, frameHeight: number): Anchors {\n const x = [0, frameWidth / 2, frameWidth];\n const y = [0, frameHeight / 2, frameHeight];\n\n for (const box of others) {\n const left = (box.x / 100) * frameWidth;\n const width = (box.w / 100) * frameWidth;\n x.push(left, left + width / 2, left + width);\n y.push(box.y, box.y + box.h / 2, box.y + box.h);\n }\n\n return { x, y };\n}\n\n/** The smallest move that puts one of `edges` on one of `targets`, within `threshold`. */\nfunction nearest(edges: readonly number[], targets: readonly number[], threshold: number): { shift: number; line: number } | null {\n let best: { shift: number; line: number } | null = null;\n\n for (const edge of edges) {\n for (const target of targets) {\n const shift = target - edge;\n\n if (Math.abs(shift) <= threshold && (!best || Math.abs(shift) < Math.abs(best.shift))) {\n best = { shift, line: target };\n }\n }\n }\n\n return best;\n}\n\n/**\n * Pulls the box onto nearby anchors, like design tools do, and reports the\n * lines that matched. Moving snaps all three edges per axis; resizing snaps\n * only the edges the handle moves. Thresholds are in the units of each axis.\n */\nexport function snapToAnchors(\n box: Box,\n anchors: Anchors,\n frameWidth: number,\n threshold: { x: number; y: number },\n handle: Handle | null,\n): { box: Box; guides: Guides } {\n const next = { ...box };\n const left = (box.x / 100) * frameWidth;\n const width = (box.w / 100) * frameWidth;\n const guides: Guides = { x: [], y: [] };\n\n const horizontal = handle\n ? handle.includes('e') ? [left + width] : handle.includes('w') ? [left] : []\n : [left, left + width / 2, left + width];\n const vertical = handle\n ? handle.includes('s') ? [box.y + box.h] : handle.includes('n') ? [box.y] : []\n : [box.y, box.y + box.h / 2, box.y + box.h];\n\n const x = nearest(horizontal, anchors.x, threshold.x);\n const y = nearest(vertical, anchors.y, threshold.y);\n\n if (x) {\n const shift = (x.shift / frameWidth) * 100;\n guides.x.push(x.line);\n\n if (!handle) {\n next.x += shift;\n } else if (handle.includes('e')) {\n next.w += shift;\n } else {\n next.x += shift;\n next.w -= shift;\n }\n }\n\n if (y) {\n guides.y.push(y.line);\n\n if (!handle) {\n next.y += y.shift;\n } else if (handle.includes('s')) {\n next.h += y.shift;\n } else {\n next.y += y.shift;\n next.h -= y.shift;\n }\n }\n\n return { box: next, guides };\n}\n\n/** Aligns one box inside its canvas. */\nexport function alignInCanvas(box: Box, where: Alignment, canvasHeight: number): Box {\n switch (where) {\n case 'left':\n return { ...box, x: 0 };\n case 'hcenter':\n return { ...box, x: Math.round(((100 - box.w) / 2) * 2) / 2 };\n case 'right':\n return { ...box, x: 100 - box.w };\n case 'top':\n return { ...box, y: 0 };\n case 'vmiddle':\n return { ...box, y: snap((canvasHeight - box.h) / 2) };\n case 'bottom':\n return { ...box, y: snap(canvasHeight - box.h) };\n }\n}\n\n/** Aligns several boxes against the box that encloses all of them. */\nexport function alignTogether(boxes: readonly Box[], where: Alignment): Box[] {\n const left = Math.min(...boxes.map((box) => box.x));\n const right = Math.max(...boxes.map((box) => box.x + box.w));\n const top = Math.min(...boxes.map((box) => box.y));\n const bottom = Math.max(...boxes.map((box) => box.y + box.h));\n\n return boxes.map((box) => {\n switch (where) {\n case 'left':\n return { ...box, x: left };\n case 'hcenter':\n return { ...box, x: (left + right) / 2 - box.w / 2 };\n case 'right':\n return { ...box, x: right - box.w };\n case 'top':\n return { ...box, y: top };\n case 'vmiddle':\n return { ...box, y: snap((top + bottom) / 2 - box.h / 2) };\n case 'bottom':\n return { ...box, y: snap(bottom - box.h) };\n }\n });\n}\n\n/**\n * Spreads boxes evenly between the first and the last along one axis.\n * Needs three or more; returns the boxes in their original order.\n */\nexport function distribute(boxes: readonly Box[], axis: 'x' | 'y'): Box[] {\n if (boxes.length < 3) {\n return [...boxes];\n }\n\n const order = boxes.map((box, index) => ({ box, index })).sort((a, b) => a.box[axis] - b.box[axis]);\n const first = order[0]!.box[axis];\n const step = (order[order.length - 1]!.box[axis] - first) / (order.length - 1);\n const result = [...boxes];\n\n order.forEach(({ box, index }, position) => {\n if (position > 0 && position < order.length - 1) {\n const value = first + step * position;\n result[index] = { ...box, [axis]: axis === 'x' ? value : snap(value) };\n }\n });\n\n return result;\n}\n\n/** The layer that puts an element above (or below) every other one in its canvas. */\nexport function frontLayer(others: readonly number[]): number {\n return Math.min(999, Math.max(0, ...others) + 1);\n}\n\nexport function backLayer(others: readonly number[]): number {\n return Math.max(0, Math.min(1, ...others) - 1);\n}\n\n/** Canvas height that fits its content, with a margin below the lowest element. */\nexport function fitHeight(boxes: readonly Box[]): number {\n const bottom = boxes.reduce((lowest, box) => Math.max(lowest, box.y + box.h), 0);\n\n return Math.max(80, snap(bottom + 64));\n}\n\n/**\n * A phone layout from the desktop one: elements one below the other in\n * reading order (top to bottom, then left to right), 92% wide, heights scaled\n * with the width so proportions hold. Text never shrinks below its desktop\n * height, since it wraps into more lines.\n */\nexport function stackForMobile(\n elements: readonly { desktop: Box; text: boolean }[],\n reference: number,\n mobileWidth: number,\n): { boxes: Box[]; height: number } {\n const order = elements\n .map((element, index) => ({ ...element, index }))\n .sort((a, b) => a.desktop.y - b.desktop.y || a.desktop.x - b.desktop.x);\n const boxes: Box[] = new Array(elements.length);\n let top = 32;\n\n for (const element of order) {\n const width = 92;\n const factor = ((width / 100) * mobileWidth) / ((element.desktop.w / 100) * reference);\n const height = clamp(snap(element.desktop.h * (element.text ? Math.max(1, factor) : factor)), 24, 3000);\n\n boxes[element.index] = { x: 4, y: snap(top), w: width, h: height };\n top += height + 20;\n }\n\n return { boxes, height: clamp(snap(top + 12), 200, 4000) };\n}\n","import type { Document, Style, Theme, ThemeToken } from '@skylivellc/lienzo-core';\nimport type { MessageKey } from '../i18n/index.ts';\nimport { canvasesOf } from './document.ts';\n\nexport const THEME_TOKENS = ['primary', 'secondary', 'background', 'surface', 'text', 'muted'] as const satisfies readonly ThemeToken[];\n\nconst tokens: ReadonlySet<string> = new Set(THEME_TOKENS);\nexport const isThemeToken = (value: unknown): value is ThemeToken => typeof value === 'string' && tokens.has(value);\n\nexport type Palette = Pick<Theme, ThemeToken>;\n\nexport type Gradient = NonNullable<Style['gradient']>;\nexport type GradientPreset = { type: 'linear' | 'radial'; from: ThemeToken; to: ThemeToken; angle: number };\n\n/** Ready palettes, so nobody has to pick six colors blind. */\nexport const PALETTES: readonly { name: MessageKey; colors: Palette }[] = [\n { name: 'palette.blue', colors: { primary: '#2563eb', secondary: '#0f172a', background: '#ffffff', surface: '#f8fafc', text: '#0f172a', muted: '#64748b' } },\n { name: 'palette.mint', colors: { primary: '#0d9488', secondary: '#134e4a', background: '#ffffff', surface: '#f0fdfa', text: '#134e4a', muted: '#5f7470' } },\n { name: 'palette.sand', colors: { primary: '#b45309', secondary: '#1c1917', background: '#fffbf5', surface: '#f5eee4', text: '#1c1917', muted: '#78716c' } },\n { name: 'palette.indigo', colors: { primary: '#4f46e5', secondary: '#1e1b4b', background: '#ffffff', surface: '#f5f3ff', text: '#1e1b4b', muted: '#6b7280' } },\n { name: 'palette.graphite', colors: { primary: '#111827', secondary: '#374151', background: '#ffffff', surface: '#f3f4f6', text: '#111827', muted: '#6b7280' } },\n];\n\n/** Google fonts picked so that any pairing looks fine. Notes are message keys `font.<name>`. */\nexport const FONTS = ['Inter', 'Poppins', 'Montserrat', 'DM Sans', 'Work Sans', 'Nunito', 'Lora', 'Playfair Display', 'Merriweather', 'Source Sans 3'] as const;\nexport const fontNote = (font: (typeof FONTS)[number]): MessageKey => `font.${font}`;\n\nexport const MAX_WIDTHS = [1080, 1200, 1320, 1440] as const;\nexport const widthLabel = (width: (typeof MAX_WIDTHS)[number]): MessageKey => `theme.width.${width}`;\n\n/** Gradients suggested from the palette. */\nexport const GRADIENT_PRESETS: readonly { name: MessageKey; gradient: GradientPreset }[] = [\n { name: 'gradient.preset.primary', gradient: { type: 'linear', from: 'primary', to: 'secondary', angle: 135 } },\n { name: 'gradient.preset.soft', gradient: { type: 'linear', from: 'surface', to: 'background', angle: 160 } },\n { name: 'gradient.preset.halo', gradient: { type: 'radial', from: 'primary', to: 'background', angle: 0 } },\n { name: 'gradient.preset.night', gradient: { type: 'linear', from: 'secondary', to: 'primary', angle: 200 } },\n];\n\n/** The CSS color of a token or hex, for swatches in the editor chrome. */\nexport const swatch = (value: string | null | undefined, theme: Theme): string =>\n !value ? 'transparent' : isThemeToken(value) ? theme[value] : value;\n\n/** CSS background of a gradient, for preset swatches. */\nexport function gradientCss(gradient: Gradient, theme: Theme): string {\n const from = swatch(gradient.from, theme);\n const to = swatch(gradient.to, theme);\n\n return gradient.type === 'radial' ? `radial-gradient(circle at 50% 50%, ${from}, ${to})` : `linear-gradient(${gradient.angle ?? 135}deg, ${from}, ${to})`;\n}\n\nfunction distance(a: string, b: string): number {\n const channels = (hex: string) => [1, 3, 5].map((index) => parseInt(hex.slice(index, index + 2), 16));\n const [r1 = 0, g1 = 0, b1 = 0] = channels(a);\n const [r2 = 0, g2 = 0, b2 = 0] = channels(b);\n\n return (r1 - r2) ** 2 + (g1 - g2) ** 2 + (b1 - b2) ** 2;\n}\n\n/** The theme token closest to a loose hex color. */\nexport function nearestToken(value: string, theme: Theme): ThemeToken {\n if (!/^#[0-9a-fA-F]{6}$/.test(value)) {\n return 'text';\n }\n\n return [...THEME_TOKENS].sort((a, b) => distance(value.toLowerCase(), theme[a].toLowerCase()) - distance(value.toLowerCase(), theme[b].toLowerCase()))[0] ?? 'text';\n}\n\n/**\n * Moves fixed colors (canvas backgrounds, element color and background) to\n * the closest theme token, so the page follows the palette from now on.\n */\nexport function linkToPalette(document: Document, theme: Theme): void {\n for (const canvas of canvasesOf(document)) {\n const background = canvas.background.color;\n\n if (background && !isThemeToken(background)) {\n canvas.background.color = nearestToken(background, theme);\n }\n\n for (const element of canvas.elements) {\n for (const key of ['color', 'background'] as const) {\n const value = element.style[key];\n\n if (value && !isThemeToken(value)) {\n element.style[key] = nearestToken(value, theme);\n }\n }\n }\n }\n}\n\n/** Stylesheet URL that loads the theme fonts, the same request the public page makes. */\nexport function fontsHref(fonts: readonly string[]): string {\n const families = [...new Set(fonts)].map((font) => `family=${font.replaceAll(' ', '+')}:wght@300;400;500;600;700;800`).join('&');\n\n return `https://fonts.googleapis.com/css2?${families}&display=swap`;\n}\n","import type { AppElement, Catalog, CoreElement, CoreElementType, Element, ElementSpec, FieldValue, StyleGroup } from '@skylivellc/lienzo-core';\nimport type { MessageKey } from '../i18n/index.ts';\nimport { isCoreType, newId } from './document.ts';\nimport { snap } from './geometry.ts';\n\ntype Translate = (key: MessageKey, params?: Record<string, string | number>) => string;\n\ntype Draft = { box: { x: number; w: number; h: number }; props: CoreElement['props']; style: CoreElement['style'] };\n\ntype CoreSpec = {\n label: MessageKey;\n /** Form fields sit in their own palette group. */\n group: 'content' | 'form';\n /** Style panels the element shows. */\n styles: readonly StyleGroup[];\n /** The prop a double-click edits right on the canvas. */\n inline: 'text' | 'label' | null;\n /** A fresh element with a sensible look and copy in the editor's language. */\n create(t: Translate): Draft;\n};\n\nconst ALL: readonly StyleGroup[] = ['fill', 'text', 'border', 'effects', 'motion'];\nconst NO_TEXT: readonly StyleGroup[] = ['fill', 'border', 'effects', 'motion'];\n\nconst field = (type: 'input' | 'textarea' | 'select' | 'checkbox') => (t: Translate): Draft => ({\n box: { x: 10, w: 40, h: type === 'textarea' ? 120 : type === 'checkbox' ? 32 : 76 },\n props: {\n label: type === 'checkbox' ? t('default.checkbox') : t('default.field'),\n placeholder: type === 'select' ? '' : t('default.fieldPlaceholder'),\n required: type !== 'select',\n input_type: 'text',\n options: type === 'select' ? [t('default.option', { n: 1 }), t('default.option', { n: 2 })] : [],\n },\n style: { color: 'text', background: 'surface', border_color: 'muted', border_width: 1, font: 'body', size: 15, align: 'left', radius: 10, padding: 10 },\n});\n\n/** Everything the editor knows per core type. A new core type does not compile until it is listed here. */\nexport const coreSpecs = {\n heading: {\n label: 'type.heading', group: 'content', styles: ALL, inline: 'text',\n create: (t) => ({\n box: { x: 10, w: 40, h: 80 },\n props: { text: t('default.heading'), level: 1 },\n style: { color: 'text', font: 'heading', size: 44, weight: 700, align: 'left', line_height: 1.1 },\n }),\n },\n text: {\n label: 'type.text', group: 'content', styles: ALL, inline: 'text',\n create: (t) => ({\n box: { x: 10, w: 40, h: 96 },\n props: { text: t('default.text') },\n style: { color: 'muted', font: 'body', size: 18, weight: 400, align: 'left', line_height: 1.6 },\n }),\n },\n image: {\n label: 'type.image', group: 'content', styles: NO_TEXT, inline: null,\n create: () => ({ box: { x: 55, w: 35, h: 260 }, props: { src: '', alt: '' }, style: { radius: 16, object_fit: 'cover' } }),\n },\n button: {\n label: 'type.button', group: 'content', styles: ALL, inline: 'label',\n create: (t) => ({\n box: { x: 10, w: 18, h: 52 },\n props: { label: t('default.button'), action: { type: 'url', value: '' } },\n style: { background: 'primary', color: 'background', font: 'body', size: 16, weight: 600, align: 'center', radius: 12 },\n }),\n },\n divider: {\n label: 'type.divider', group: 'content', styles: NO_TEXT, inline: null,\n create: () => ({ box: { x: 10, w: 80, h: 2 }, props: {}, style: { color: 'muted' } }),\n },\n video: {\n label: 'type.video', group: 'content', styles: ALL, inline: null,\n create: (t) => ({ box: { x: 30, w: 40, h: 260 }, props: { url: '', alt: t('default.video') }, style: { radius: 16 } }),\n },\n shape: {\n label: 'type.shape', group: 'content', styles: ALL, inline: null,\n create: () => ({ box: { x: 10, w: 20, h: 160 }, props: { shape: 'rectangle' }, style: { background: 'primary', radius: 16, opacity: 1 } }),\n },\n icon: {\n label: 'type.icon', group: 'content', styles: ALL, inline: null,\n create: () => ({ box: { x: 10, w: 5, h: 56 }, props: { icon: 'heart', stroke: 2 }, style: { color: 'primary' } }),\n },\n navbar: {\n label: 'type.navbar', group: 'content', styles: ALL, inline: null,\n create: (t) => ({ box: { x: 0, w: 100, h: 72 }, ...navbarPresets(t)[0]! }),\n },\n gallery: {\n label: 'type.gallery', group: 'content', styles: ALL, inline: null,\n create: () => ({ box: { x: 6, w: 88, h: 320 }, props: { images: [], layout: 'grid', columns: 3 }, style: { radius: 8 } }),\n },\n slider: {\n label: 'type.slider', group: 'content', styles: ALL, inline: null,\n create: () => ({ box: { x: 6, w: 88, h: 380 }, props: { images: [], arrows: true, dots: true, autoplay: false, interval: 5 }, style: { radius: 8 } }),\n },\n input: { label: 'type.input', group: 'form', styles: ALL, inline: null, create: field('input') },\n textarea: { label: 'type.textarea', group: 'form', styles: ALL, inline: null, create: field('textarea') },\n select: { label: 'type.select', group: 'form', styles: ALL, inline: null, create: field('select') },\n checkbox: { label: 'type.checkbox', group: 'form', styles: ALL, inline: null, create: field('checkbox') },\n} satisfies Record<CoreElementType, CoreSpec>;\n\n/** Ready-made menus: a starting point, then edited link by link like any element. */\nexport function navbarPresets(t: Translate): { name: MessageKey; props: CoreElement['props']; style: CoreElement['style'] }[] {\n const anchor = (label: MessageKey) => ({ label: t(label), action: { type: 'anchor', value: '' } });\n\n return [\n {\n name: 'navbar.preset.split',\n props: { brand: t('default.brand'), layout: 'split', links: [anchor('default.link.features'), anchor('default.link.about'), anchor('default.link.contact')] },\n style: { background: 'background', color: 'text', font: 'body', size: 16, weight: 600, padding: 20 },\n },\n {\n name: 'navbar.preset.center',\n props: { brand: '', layout: 'center', links: [anchor('default.link.home'), anchor('default.link.features'), anchor('default.link.about'), anchor('default.link.contact')] },\n style: { background: 'surface', color: 'text', font: 'body', size: 16, weight: 500, padding: 18 },\n },\n {\n name: 'navbar.preset.dark',\n props: { brand: t('default.brand'), layout: 'split', links: [anchor('default.link.features'), { label: t('default.link.start'), action: { type: 'anchor', value: '' } }] },\n style: { background: 'secondary', color: 'background', font: 'heading', size: 16, weight: 600, padding: 20 },\n },\n {\n name: 'navbar.preset.pill',\n props: { brand: t('default.brand'), layout: 'split', template: 'pill', links: [anchor('default.link.features'), anchor('default.link.about'), anchor('default.link.contact')] },\n style: { background: 'surface', color: 'text', font: 'body', size: 15, weight: 600, padding: 16 },\n },\n {\n name: 'navbar.preset.card',\n props: { brand: t('default.brand'), layout: 'split', template: 'card', links: [anchor('default.link.home'), anchor('default.link.features'), anchor('default.link.contact')] },\n style: { background: 'background', color: 'text', font: 'heading', size: 16, weight: 600, padding: 18 },\n },\n {\n name: 'navbar.preset.underline',\n props: { brand: t('default.brand'), layout: 'split', template: 'underline', links: [anchor('default.link.home'), anchor('default.link.features'), anchor('default.link.about'), anchor('default.link.contact')] },\n style: { background: 'background', color: 'text', font: 'body', size: 16, weight: 500, padding: 20 },\n },\n {\n name: 'navbar.preset.divided',\n props: { brand: '', layout: 'center', template: 'divided', links: [anchor('default.link.home'), anchor('default.link.features'), anchor('default.link.about'), anchor('default.link.contact')] },\n style: { background: 'surface', color: 'text', font: 'body', size: 15, weight: 500, padding: 16 },\n },\n ];\n}\n\n/** What an element is to the editor: built in, declared by the app, or from a plugin that is gone. */\nexport type ElementKind =\n | { kind: 'core'; element: CoreElement; spec: CoreSpec }\n | { kind: 'app'; element: AppElement; spec: ElementSpec }\n | { kind: 'opaque'; element: Element };\n\nexport function kindOf(element: Element, catalog: Catalog): ElementKind {\n if (isCoreType(element.type)) {\n return { kind: 'core', element: element as CoreElement, spec: coreSpecs[element.type] };\n }\n\n const spec = catalog.elements.find((candidate) => candidate.type === element.type);\n\n return spec ? { kind: 'app', element: element as AppElement, spec } : { kind: 'opaque', element };\n}\n\n/** An element type the palette can add. */\nexport type Insertable = { kind: 'core'; type: CoreElementType } | { kind: 'app'; spec: ElementSpec };\n\n/** A new element placed at `top` design pixels, sized and styled by its type. */\nexport function createElement(insertable: Insertable, top: number, t: Translate): Element {\n const draft = insertable.kind === 'core' ? coreSpecs[insertable.type].create(t) : appDraft(insertable.spec);\n const type = insertable.kind === 'core' ? insertable.type : insertable.spec.type;\n\n return {\n id: newId(type),\n type,\n z: 1,\n layout: { desktop: { ...draft.box, y: snap(top) }, mobile: null },\n props: draft.props,\n style: draft.style,\n };\n}\n\nfunction appDraft(spec: ElementSpec): { box: Draft['box']; props: Record<string, FieldValue>; style: CoreElement['style'] } {\n const props: Record<string, FieldValue> = {};\n\n for (const field of spec.fields) {\n if (field.kind !== 'image' && field.kind !== 'action' && field.default !== undefined) {\n props[field.key] = field.default;\n }\n }\n\n return { box: { x: 10, w: spec.size.w, h: spec.size.h }, props, style: {} };\n}\n\n/** A short name for layers: the element's own text when it has some, else its type. */\nexport function elementName(element: Element, label: string): string {\n const props: Record<string, unknown> = element.props;\n const text = [props.text, props.label, props.brand].find((value): value is string => typeof value === 'string' && value.trim() !== '');\n\n return text ? text.trim().slice(0, 28) : label;\n}\n","/**\n * Undo and redo over document snapshots (serialized JSON). Pushing a\n * snapshot equal to the current one is a no-op, so callers can push after\n * every gesture without checking whether anything changed.\n */\nexport type History = {\n /** Records a new state. Returns false when it equals the current one. */\n push(snapshot: string): boolean;\n /** The state to restore, or null at the edge of the history. */\n undo(): string | null;\n redo(): string | null;\n /** Forgets everything and starts again from `snapshot` (a page switch or a reload). */\n reset(snapshot: string): void;\n readonly canUndo: boolean;\n readonly canRedo: boolean;\n};\n\nexport function createHistory(initial: string, limit = 50): History {\n let entries = [initial];\n let cursor = 0;\n\n const move = (step: 1 | -1): string | null => {\n const next = cursor + step;\n\n if (next < 0 || next >= entries.length) {\n return null;\n }\n\n cursor = next;\n\n return entries[cursor] ?? null;\n };\n\n return {\n push(snapshot) {\n if (snapshot === entries[cursor]) {\n return false;\n }\n\n entries = [...entries.slice(0, cursor + 1), snapshot].slice(-limit);\n cursor = entries.length - 1;\n\n return true;\n },\n undo: () => move(-1),\n redo: () => move(1),\n reset(snapshot) {\n entries = [snapshot];\n cursor = 0;\n },\n get canUndo() {\n return cursor > 0;\n },\n get canRedo() {\n return cursor < entries.length - 1;\n },\n };\n}\n","/**\n * Every string the editor shows, in English (the fallback). Other packs are\n * typed `Messages`, so a missing or misspelled key does not compile.\n * `{name}` placeholders are filled by `t(key, { name })`.\n */\nexport const en = {\n // Loading\n 'load.loading': 'Loading the editor…',\n 'load.failed': \"Couldn't load the editor: {message}\",\n 'load.retry': 'Try again',\n 'load.invalidDraft': \"This page's draft can't be read ({issue}).\",\n 'load.offline': 'You seem to be offline.',\n\n // Toolbar\n 'toolbar.pageSelect': 'Page being edited',\n 'toolbar.newPage': 'Page',\n 'toolbar.newPageHint': 'Create another page',\n 'toolbar.desktop': 'Desktop',\n 'toolbar.mobile': 'Phone',\n 'toolbar.device': 'Device',\n 'toolbar.undo': 'Undo (Ctrl+Z)',\n 'toolbar.redo': 'Redo (Ctrl+Shift+Z)',\n 'toolbar.preview': 'Preview',\n 'toolbar.previewHint': 'See the page without the editor guides',\n 'toolbar.edit': 'Edit',\n 'toolbar.editHint': 'Back to editing',\n 'toolbar.versions': 'Versions',\n 'toolbar.versionsHint': 'Go back to a published version',\n 'toolbar.theme': 'Theme',\n 'toolbar.site': 'Site',\n 'toolbar.siteHint': 'Search engines, sharing and site details',\n 'toolbar.viewSite': 'View site',\n 'toolbar.publish': 'Publish',\n 'toolbar.publishing': 'Publishing…',\n 'status.published': 'Published',\n 'status.unpublished': 'Not published',\n\n // Saving\n 'save.idle': 'Changes save automatically',\n 'save.pending': 'Unsaved changes',\n 'save.saving': 'Saving…',\n 'save.saved': 'Draft saved {time}',\n 'save.offline': \"You're offline. Changes will save when the connection is back.\",\n 'save.failed': \"Couldn't save: {message}\",\n 'save.retry': 'Retry',\n 'save.invalid': 'Some values are not valid ({issue}). Fix them to keep saving.',\n 'save.conflict': 'This page was changed somewhere else',\n 'conflict.title': 'This page changed somewhere else',\n 'conflict.body': 'Someone saved a newer version of this page, maybe you in another tab. Reload it to keep editing. Changes made here since the last save will be lost.',\n 'conflict.reload': 'Reload the page',\n\n // Common\n 'common.duplicate': 'Duplicate',\n 'common.delete': 'Delete',\n 'common.cancel': 'Cancel',\n 'common.close': 'Close',\n 'common.remove': 'Remove',\n 'common.choose': 'Choose',\n 'common.add': 'Add',\n 'common.new': 'New',\n\n // Left sidebar\n 'tabs.elements': 'Elements',\n 'tabs.blocks': 'Blocks',\n 'tabs.layers': 'Layers',\n 'tabs.modals': 'Modals',\n 'tabs.media': 'Media',\n 'elements.addHint': 'Click to add it, or drag it onto the canvas',\n 'elements.app': 'From your app',\n 'elements.appHint': 'These elements show live data from your app.',\n 'elements.sectionsHint': 'A whole section, ready to edit. It lands at the end of the page.',\n 'elements.sections': 'Ready-made sections',\n 'elements.form': 'Form',\n 'elements.formHint': 'Fields are sent by a button whose action is \"Submit the form\". They must be in the same section or modal as the button.',\n 'layers.count': '{n} sections',\n 'layers.modal': 'Modal {title}',\n 'layers.section': 'Section {n}',\n 'layers.expand': 'Expand section',\n 'layers.collapse': 'Collapse section',\n 'layers.up': 'Move section up',\n 'layers.down': 'Move section down',\n 'layers.lock': 'Lock',\n 'layers.unlock': 'Unlock',\n 'layers.empty': 'No elements',\n 'modals.hint': 'A button with the \"Open a modal\" action opens them',\n 'modals.defaultTitle': 'More information',\n 'modals.titleLabel': 'Modal title',\n 'modals.delete': 'Delete modal',\n 'modals.elements': '{n} elements',\n 'modals.edit': 'Edit content',\n 'modals.empty': 'No modals yet.',\n 'media.hint': 'Drag an image onto the canvas or click to add it',\n 'media.upload': 'Upload',\n 'media.empty': \"You haven't uploaded any images yet.\",\n\n // Element types\n 'type.heading': 'Heading',\n 'type.text': 'Text',\n 'type.image': 'Image',\n 'type.button': 'Button',\n 'type.divider': 'Divider',\n 'type.video': 'Video',\n 'type.shape': 'Shape',\n 'type.icon': 'Icon',\n 'type.gallery': 'Gallery',\n 'type.slider': 'Slider',\n 'el.galleryItem': 'Picture {n}',\n 'el.gallery': 'Pictures',\n 'el.galleryAdd': 'Add a picture',\n 'el.sliderArrows': 'Arrows to move it',\n 'el.sliderDots': 'Dots under it',\n 'el.sliderAutoplay': 'Move by itself',\n 'el.sliderInterval': 'Seconds on each picture',\n 'el.galleryHint': 'They are shown in this order; the first one leads.',\n 'el.galleryLayout': 'Shown as',\n 'el.gallery.grid': 'Grid',\n 'el.gallery.strip': 'Strip that scrolls',\n 'el.galleryColumns': 'Columns',\n 'el.galleryRemove': 'Remove',\n 'type.navbar': 'Navigation bar',\n 'type.input': 'Text field',\n 'type.textarea': 'Long text field',\n 'type.select': 'Dropdown',\n 'type.checkbox': 'Checkbox',\n 'type.unknown': 'Unavailable element',\n\n // Canvas\n 'menu.copy': 'Copy',\n 'menu.paste': 'Paste',\n 'menu.lock': 'Lock',\n 'menu.unlock': 'Unlock',\n 'zoom.label': 'Zoom',\n 'zoom.in': 'Zoom in',\n 'zoom.out': 'Zoom out',\n 'zoom.fit': 'Fit to the window',\n 'zoom.actual': 'Actual size',\n 'canvas.title': 'Page canvas',\n 'canvas.editingModal': 'Editing the modal \"{title}\"',\n 'canvas.backToPage': 'Back to the page',\n 'canvas.emptyPage': 'Add a heading, a text and a button from the left panel, and arrange them by dragging.',\n 'canvas.emptyModal': 'Drag elements or fields here: this is the content of the modal.',\n 'canvas.toolbar': 'Element actions',\n 'canvas.front': 'Bring to front',\n 'canvas.back': 'Send to back',\n 'canvas.radius': 'Round the corners, now {n} px',\n 'canvas.rotate': 'Rotate, now {n}°. With Shift, in steps of 15°',\n 'canvas.resize': 'Resize ({handle})',\n 'canvas.corners': 'Corners {n} px',\n 'canvas.sticky': 'Sticky on scroll',\n 'canvas.emptyImage': 'Choose an image',\n 'canvas.emptyVideo': 'Paste a YouTube or Vimeo link',\n 'canvas.stacked': 'On phones this section stacks its elements by itself.',\n 'canvas.loadingPreview': 'Loading preview…',\n 'canvas.previewFailed': \"Couldn't load the preview\",\n 'canvas.invalid': 'The canvas shows the last valid version: {issue}',\n 'canvas.locked': 'Locked',\n\n // Right panel\n 'panel.design': 'Design',\n 'panel.page': 'Page',\n 'panel.nothing': 'Select a section or an element on the canvas.',\n 'multi.count': '{n} elements selected',\n 'multi.align': 'Align',\n 'multi.distribute': 'Distribute',\n 'multi.distributeX': 'Distribute horizontally',\n 'multi.distributeY': 'Distribute vertically',\n 'multi.distributeHint': 'Distributing needs three or more elements.',\n 'multi.group': 'Group',\n 'multi.ungroup': 'Ungroup',\n 'multi.lock': 'Lock or unlock',\n 'multi.menuHint': 'Right-click the selection to group, lock, reorder, duplicate or delete it.',\n 'multi.hint': 'Shift-click adds or removes elements from the selection. Grouped elements are selected together.',\n 'align.left': 'Align left',\n 'align.hcenter': 'Center horizontally',\n 'align.right': 'Align right',\n 'align.top': 'Align top',\n 'align.vmiddle': 'Center vertically',\n 'align.bottom': 'Align bottom',\n\n // Modal settings\n 'modal.heading': 'Modal',\n 'modal.title': 'Title',\n 'modal.showTitle': 'Show it at the top of the modal',\n 'modal.showTitleHint': 'Hidden, it still names the modal and screen readers still read it.',\n 'modal.size': 'Size',\n 'modal.size.sm': 'Small',\n 'modal.size.md': 'Medium',\n 'modal.size.lg': 'Large',\n 'modal.size.xl': 'Extra large',\n 'modal.size.full': 'Full screen',\n 'modal.width': 'Custom width',\n 'modal.fullHint': 'At full screen the modal fills the browser and is designed on 1200 px.',\n 'modal.background': 'Background color',\n\n // Section settings\n 'section.heading': 'Section',\n 'section.addAfter': 'Add a section below',\n 'section.duplicate': 'Duplicate section',\n 'canvas.emptySection': 'This section is empty: drag an element here.',\n 'section.delete': 'Delete section',\n 'section.shownAs': 'Shown as',\n 'section.alone': 'Regular section',\n 'section.tab': 'Tab of the previous group',\n 'section.step': 'Step of the previous group',\n 'section.groupLabel': 'Name of the tab or step',\n 'section.groupHint': 'Consecutive sections of the same group show one at a time, with a bar of tabs or steps.',\n 'section.stepLabel': 'Step {n}',\n 'section.anchor': 'Anchor id',\n 'section.anchorHint': 'Links with the \"Go to a section\" action use it.',\n 'section.fitHeight': 'Fit height to content',\n 'section.generateMobile': 'Generate phone layout',\n 'section.heightDesktop': 'Desktop height',\n 'section.heightMobile': 'Phone height',\n 'fill.video': 'Video',\n 'section.video': 'Video address',\n 'section.videoHint': 'An https link to an .mp4 or .webm file. It plays muted and on a loop.',\n 'section.poster': 'Image while the video loads',\n 'section.flow': 'Lay it out',\n 'section.flowHint': 'On its own, the section places its elements one after another and grows with them.',\n 'section.flow.free': 'By hand',\n 'section.flow.column': 'One under the other',\n 'section.flow.row': 'Side by side',\n 'section.flowGap': 'Space between',\n 'section.flowAlign': 'Alignment',\n 'section.align.start': 'To the start',\n 'section.align.center': 'Centred',\n 'section.align.end': 'To the end',\n 'section.align.between': 'Spread out',\n 'section.wide': 'Edge to edge',\n 'section.wideHint': \"The section spans the screen instead of the theme's width.\",\n 'section.background': 'Background',\n 'section.color': 'Section color',\n 'section.image': 'Background image',\n 'section.chooseImage': 'Choose image',\n 'section.parallax': 'Parallax effect on scroll',\n 'section.overlay': 'Darken the image',\n 'fill.color': 'Color',\n 'fill.gradient': 'Gradient',\n 'fill.image': 'Image',\n 'gradient.from': 'From',\n 'gradient.to': 'To',\n 'gradient.shape': 'Shape',\n 'gradient.linear': 'Linear',\n 'gradient.radial': 'Radial',\n 'gradient.angle': 'Angle',\n 'gradient.preset.primary': 'Primary',\n 'gradient.preset.soft': 'Soft',\n 'gradient.preset.halo': 'Halo',\n 'gradient.preset.night': 'Night',\n\n // Page settings\n 'page.title': 'Page title',\n 'page.address': 'Address',\n 'page.home': 'Home page',\n 'page.saveAddress': 'Save address',\n 'page.addressSaved': 'Address saved.',\n 'page.delete': 'Delete page',\n 'page.deleteConfirm': 'Delete the page \"{title}\"? This cannot be undone.',\n 'page.deleted': 'Page deleted.',\n 'page.templates': 'Start from a template',\n 'page.seoTitle': 'Title for search engines',\n 'page.seoTitleHint': \"It's what shows in the browser tab and on search engines.\",\n 'page.description': 'Description',\n 'page.shortcuts': 'Shortcuts',\n 'page.shortcutUndo': 'Ctrl+Z undoes, Ctrl+Shift+Z redoes',\n 'page.shortcutSave': 'Ctrl+S saves the draft',\n 'page.shortcutCopy': 'Ctrl+C, Ctrl+V and Ctrl+D copy, paste and duplicate',\n 'page.shortcutNudge': 'Arrow keys nudge the selection, with Shift they move it further',\n\n // New page\n 'newPage.title': 'New page',\n 'newPage.description': 'Each page lives at its own address on your site.',\n 'newPage.titleLabel': 'Title',\n 'newPage.slug': 'Address',\n 'newPage.slugPlaceholder': 'services',\n 'newPage.at': 'It will be at {url}',\n 'newPage.create': 'Create page',\n\n // Versions\n 'toolbar.submissions': 'Messages',\n 'toolbar.submissionsHint': 'What visitors sent through your forms',\n 'submissions.title': 'Form messages',\n 'submissions.description': 'What visitors sent through the forms on your pages, newest first.',\n 'submissions.empty': 'No messages yet.',\n 'submissions.more': 'Load more',\n 'submissions.from': '/{page} · {source}',\n 'submissions.failed': \"Couldn't load the messages: {message}\",\n 'submissions.checked': 'Yes',\n 'submissions.unchecked': 'No',\n 'versions.title': 'Published versions',\n 'versions.description': 'Every publish keeps the previous one. Restoring brings it back to the draft without touching what visitors see until you publish.',\n 'versions.by': 'Published by {name}',\n 'versions.restore': 'Restore',\n 'versions.restored': 'Version restored to the draft.',\n 'versions.empty': 'Nothing has been published yet.',\n\n // Publishing\n 'publish.done': 'Published.',\n 'publish.failed': \"Couldn't publish: {message}\",\n\n // Theme\n 'theme.title': 'Site theme',\n 'theme.description': 'Colors and fonts that every page uses.',\n 'theme.palettes': 'Palettes',\n 'theme.colors': 'Colors',\n 'theme.link': 'Link the elements to this palette',\n 'theme.linkHint': \"Elements with their own color don't follow the palette. This button moves them to the closest theme color.\",\n 'theme.headingFont': 'Heading font',\n 'theme.bodyFont': 'Body font',\n 'theme.radius': 'Corners',\n 'theme.maxWidth': 'Content max width',\n 'theme.width.1080': 'Narrow, 1080 px',\n 'theme.width.1200': 'Standard, 1200 px',\n 'theme.width.1320': 'Wide, 1320 px',\n 'theme.width.1440': 'Extra wide, 1440 px',\n 'theme.previewLabel': 'Theme preview',\n 'theme.previewHeading': 'Pages that look cared for',\n 'theme.previewText': 'This is how headings and text will look on your site.',\n 'theme.previewButton': 'Get started',\n 'theme.save': 'Save theme',\n 'theme.saved': 'Theme saved.',\n 'palette.blue': 'Classic blue',\n 'palette.mint': 'Mint',\n 'palette.sand': 'Sand',\n 'palette.indigo': 'Indigo',\n 'palette.graphite': 'Graphite',\n 'token.primary': 'Primary',\n 'token.secondary': 'Secondary',\n 'token.background': 'Background',\n 'token.surface': 'Surface',\n 'token.text': 'Text',\n 'token.muted': 'Muted text',\n 'font.Inter': 'Neutral and modern',\n 'font.Poppins': 'Geometric and friendly',\n 'font.Montserrat': 'Wide, good for headings',\n 'font.DM Sans': 'Clean and compact',\n 'font.Work Sans': 'Sober, very legible',\n 'font.Nunito': 'Rounded and warm',\n 'font.Lora': 'Classic serif',\n 'font.Playfair Display': 'Elegant serif',\n 'font.Merriweather': 'Sturdy serif',\n 'font.Source Sans 3': 'Institutional',\n\n // Site settings\n 'site.title': 'Site settings',\n 'site.description': 'What search engines and social networks see, and details about your site.',\n 'site.seoTitle': 'Default title for search engines',\n 'site.seoDescription': 'Default description',\n 'site.shareImage': 'Share image',\n 'site.shareImageHint': 'Shown when the link is pasted in a chat or a social network.',\n 'site.favicon': 'Browser icon',\n 'site.locale': 'Language of the published pages',\n 'site.details': 'Details',\n 'site.save': 'Save settings',\n 'site.saved': 'Settings saved.',\n\n // Media library\n 'library.title': 'Images',\n 'library.description': 'Photos and graphics, ready to use on any page.',\n 'library.upload': 'Upload image',\n 'library.uploading': 'Uploading…',\n 'library.formats': 'JPG, PNG, WebP, AVIF or SVG',\n 'library.use': 'Use {name}',\n 'library.delete': 'Delete {name}',\n 'library.uploadFailed': \"Couldn't upload the image: {message}\",\n 'library.deleteFailed': \"Couldn't delete the image: {message}\",\n 'library.quota': '{used} of {limit} used',\n\n // Element settings\n 'el.text': 'Text',\n 'el.accent': 'Part in another color',\n 'el.accentPlaceholder': 'Type the words to highlight',\n 'el.accentColor': 'Highlight color',\n 'el.level': 'Hierarchy',\n 'el.level.1': 'Main title',\n 'el.level.2': 'Section title',\n 'el.level.3': 'Subtitle',\n 'el.level.4': 'Small subtitle',\n 'el.image': 'Image',\n 'el.chooseFromLibrary': 'Choose from the library',\n 'el.imageUrl': 'or paste an https:// address',\n 'el.alt': 'Alternative text',\n 'el.altPlaceholder': \"What's in the image\",\n 'el.fit': 'Fit',\n 'el.fit.cover': 'Crop to fill',\n 'el.fit.contain': 'Show it whole',\n 'el.crop': 'Crop',\n 'el.shape': 'Shape',\n 'el.opacity': 'Opacity',\n 'shape.rectangle': 'Rectangle',\n 'shape.ellipse': 'Circle',\n 'shape.triangle': 'Triangle',\n 'shape.blob': 'Blob',\n 'shape.arch': 'Arch',\n 'shape.diagonal': 'Diagonal',\n 'shape.dots': 'Dot pattern',\n 'shape.grid': 'Grid pattern',\n 'el.videoUrl': 'Video link',\n 'el.videoHint': 'YouTube and Vimeo links work. The video loads only when the visitor reaches it.',\n 'el.buttonLabel': 'Button text',\n 'el.action': 'Action',\n 'action.none': 'No action',\n 'action.whatsapp': 'WhatsApp',\n 'action.phone': 'Call',\n 'action.email': 'Email',\n 'action.url': 'External link',\n 'action.anchor': 'Go to a section',\n 'action.modal': 'Open a modal',\n 'action.submit': 'Submit the form',\n 'action.page': 'Go to another page',\n 'action.top': 'Back to top',\n 'action.back': 'Go back',\n 'action.step_next': 'Next step',\n 'action.step_prev': 'Previous step',\n 'action.chooseModal': 'Select a modal',\n 'action.choosePage': 'Select a page',\n 'action.placeholder.whatsapp': '+15551234567',\n 'action.placeholder.phone': '+15551234567',\n 'action.placeholder.email': 'hello@example.com',\n 'action.placeholder.anchor': 'Section id',\n 'action.placeholder.url': 'https://…',\n 'action.submitHint': 'Sends the fields in this same section or modal.',\n 'el.presets': 'Presets',\n 'navbar.preset.split': 'Brand and links',\n 'navbar.preset.center': 'Centered',\n 'navbar.preset.dark': 'Dark',\n 'navbar.preset.pill': 'Pill',\n 'navbar.preset.card': 'Card',\n 'navbar.preset.underline': 'Underline',\n 'navbar.preset.divided': 'Divided',\n 'el.navbarTemplate': 'Template',\n 'el.navbarTemplate.plain': 'Plain',\n 'el.navbarTemplate.pill': 'Pill',\n 'el.navbarTemplate.card': 'Card',\n 'el.navbarTemplate.underline': 'Underline',\n 'el.navbarTemplate.divided': 'Divided',\n 'el.brand': 'Brand',\n 'el.brandPlaceholder': 'Your brand name',\n 'el.sticky': 'Stick to the top on scroll',\n 'el.scrollStyle': 'When scrolling',\n 'el.scroll.same': 'Stays the same',\n 'el.scroll.shadow': 'Gains a shadow',\n 'el.scroll.solid': 'Solid background and shadow',\n 'el.scroll.compact': 'Shrinks, solid and with a shadow',\n 'el.scrollBackground': 'Background once it scrolls',\n 'el.scrollColor': 'Text once it scrolls',\n 'el.scrollColorsHint': 'A bar that starts transparent over a photo needs its own colors once the page moves, or it turns invisible.',\n 'el.notSticky': 'Not sticky: the menu stays where you put it and scrolls away with the page.',\n 'el.layout': 'Layout',\n 'el.layout.split': 'Brand and links on each side',\n 'el.layout.left': 'All to the left',\n 'el.layout.center': 'All centered',\n 'el.links': 'Links',\n 'el.linkLabel': 'Link text',\n 'el.removeLink': 'Remove link',\n 'el.linksHint': 'On phones the links fold into a dropdown menu.',\n 'el.icon': 'Icon',\n 'el.iconSearch': 'Search: heart, calendar, phone…',\n 'el.noResults': 'No results.',\n 'el.stroke': 'Stroke width',\n 'el.fieldLabel': 'Label',\n 'el.inputType': 'Data type',\n 'el.inputType.text': 'Text',\n 'el.inputType.email': 'Email',\n 'el.inputType.tel': 'Phone',\n 'el.inputType.number': 'Number',\n 'el.inputType.date': 'Date',\n 'el.options': 'Options',\n 'el.optionsHint': 'One option per line.',\n 'el.placeholder': 'Help text',\n 'el.multiple': 'Several answers',\n 'el.required': 'Required',\n 'el.unknown': 'This element comes from a plugin that is not installed. It is kept as it is and cannot be edited.',\n\n // Style\n 'style.fill': 'Color and fill',\n 'style.color': 'Color',\n 'style.background': 'Background',\n 'style.backgroundType': 'Background type',\n 'style.backgroundColor': 'Background color',\n 'style.transparency': 'Transparency',\n 'style.glass': 'Glass',\n 'style.glassHint': 'Blurs what is behind. With a see-through background it gives a glass effect.',\n 'style.text': 'Text',\n 'style.fontHeading': 'Headings',\n 'style.fontBody': 'Body',\n 'style.size': 'Size',\n 'style.weight': 'Font weight',\n 'style.weight.300': 'Light',\n 'style.weight.400': 'Regular',\n 'style.weight.500': 'Medium',\n 'style.weight.600': 'Semibold',\n 'style.weight.700': 'Bold',\n 'style.weight.800': 'Extra bold',\n 'style.align.left': 'Left',\n 'style.align.center': 'Center',\n 'style.align.right': 'Right',\n 'style.sizeMobile': 'Size on phones',\n 'style.tracking': 'Letter spacing',\n 'style.case': 'Letters',\n 'style.case.none': 'As written',\n 'style.case.upper': 'UPPERCASE',\n 'style.case.lower': 'lowercase',\n 'style.case.title': 'Title Case',\n 'style.face': 'Face',\n 'style.face.solid': 'Solid',\n 'style.face.outline': 'Hollow',\n 'style.face.glow': 'Glowing',\n 'style.autoHeight': 'Grow with the text',\n 'style.autoHeightHint': 'The box takes the height its text needs, so a longer line never gets cropped.',\n 'style.lineHeight': 'Line height',\n 'style.frame': 'Frame',\n 'style.radius': 'Corners',\n 'style.padding': 'Padding',\n 'style.border': 'Border',\n 'style.layer': 'Layer',\n 'style.borderColor': 'Border color',\n 'style.shadow': 'Shadow',\n 'style.shadow.none': 'No shadow',\n 'style.shadow.sm': 'Subtle',\n 'style.shadow.md': 'Medium',\n 'style.shadow.lg': 'Strong',\n 'style.shadow.custom': 'Custom',\n 'style.customShadow': 'Custom shadow',\n 'style.shadowBlur': 'Blur',\n 'style.shadowSpread': 'Spread',\n 'style.shadowColor': 'Shadow color',\n 'style.shadowOpacity': 'Intensity',\n 'style.transform': 'Transform',\n 'style.rotate': 'Rotation',\n 'style.straighten': 'Straighten',\n 'style.flipX': 'Flip horizontally',\n 'style.flipY': 'Flip vertically',\n 'style.overflow': 'Content that overflows',\n 'style.overflow.visible': 'Fully visible',\n 'style.overflow.hidden': 'Clipped',\n 'style.overflow.scroll-x': 'Scrolls sideways',\n 'style.overflow.scroll-y': 'Scrolls down',\n 'style.visibleOn': 'Shown on',\n 'style.visible.all': 'All devices',\n 'style.visible.desktop': 'Desktop only',\n 'style.visible.mobile': 'Phone only',\n 'style.transformHint': 'On the canvas, rotate with the handle below the bottom corner and round the corners with the dot at the top. With Shift, rotation goes in steps of 15°.',\n 'style.motion': 'Motion',\n 'style.entrance': 'On appear',\n 'style.anim.none': 'No animation',\n 'style.anim.fade': 'Fade in',\n 'style.anim.up': 'Rise',\n 'style.anim.down': 'Drop',\n 'style.anim.left': 'Enter from the left',\n 'style.anim.right': 'Enter from the right',\n 'style.anim.zoom': 'Zoom in',\n 'style.delay': 'Delay',\n 'style.duration': 'Duration',\n 'style.anim.blur': 'Come into focus',\n 'style.anim.reveal': 'Wipe across',\n 'style.hover.sink': 'Press in',\n 'style.hover.tilt': 'Tilt',\n 'style.hover.glow': 'Glow',\n 'style.scroll': 'With the scroll',\n 'style.scrollHint': 'Moves while it crosses the screen, where the browser supports it.',\n 'style.scroll.none': 'Still',\n 'style.scroll.rise': 'Rise',\n 'style.scroll.drift': 'Drift sideways',\n 'style.scroll.zoom': 'Zoom in',\n 'el.navbarTemplate.floating': 'Floating',\n 'el.navbarTemplate.boxed': 'Boxed links',\n 'el.navbarTemplate.ribbon': 'Ribbon',\n 'el.navbarTemplate.outline': 'Outlined',\n 'el.navbarTemplate.minimal': 'Minimal',\n 'el.navbarTemplate.stack': 'Brand above the links',\n 'el.navbarTemplate.rail': 'Rail down the side',\n 'el.navbarPosition': 'Where it sticks',\n 'el.navbarPosition.top': 'Top of the screen',\n 'el.navbarPosition.bottom': 'Bottom of the screen',\n 'el.layout.right': 'Links first',\n 'el.navbarTemplate.tracked': 'Spaced out',\n 'style.hover': 'On hover',\n 'style.hover.none': 'Nothing',\n 'style.hover.lift': 'Lift',\n 'style.hover.grow': 'Grow',\n 'style.hover.fade': 'Dim',\n 'style.motionHint': 'Animations play in the preview and on the published site.',\n 'position.title': 'Position on {device}',\n 'position.desktop': 'desktop',\n 'position.mobile': 'phone',\n 'position.width': 'W',\n 'position.height': 'H',\n 'position.pinned': 'Fixed while scrolling',\n 'position.pinnedHint': 'It stays in place on the screen while the page scrolls, like a floating button or a bar.',\n 'position.own': 'Own position on phones.',\n 'position.inherit': 'Use the desktop position again',\n 'position.inherited': 'Uses the desktop position. Moving it here gives it its own; while any element uses the desktop one, the section stacks on phones.',\n 'color.custom': 'Custom',\n 'color.customLabel': '{label}, custom color',\n\n // Toasts\n 'toast.copied': 'Element copied.',\n 'toast.copiedMany': '{n} elements copied.',\n 'toast.copyFailed': \"Couldn't copy in this browser.\",\n 'toast.pasted': 'Pasted into this section.',\n 'toast.mobileGenerated': 'Phone layout generated. Adjust whatever you like.',\n 'toast.pageCreated': 'Page created.',\n 'toast.failed': 'Something went wrong: {message}',\n 'toast.dismiss': 'Dismiss',\n\n // Content of new elements\n 'default.heading': 'A heading that invites people in',\n 'default.text': 'Say in one sentence what makes you different.',\n 'default.button': 'Get started',\n 'default.video': 'Video',\n 'default.field': 'Name',\n 'default.fieldPlaceholder': 'Type here',\n 'default.checkbox': 'I agree to the processing of my data',\n 'default.option': 'Option {n}',\n 'default.brand': 'Your brand',\n 'default.link': 'Link',\n 'default.link.home': 'Home',\n 'default.link.features': 'Features',\n 'default.link.about': 'About',\n 'default.link.contact': 'Contact',\n 'default.link.start': 'Get started',\n\n // Templates\n 'template.group.open': 'Open the page',\n 'template.group.tell': 'Tell it',\n 'template.group.convince': 'Back it up',\n 'template.group.close': 'Close it',\n 'template.heroCentered': 'Centered opening',\n 'template.heroSlider': 'Opening with a slider',\n 'template.steps': 'How it works',\n 'template.gallery': 'Gallery',\n 'template.faq': 'Questions',\n 'template.logos': 'Logos',\n 'template.testimonial': 'What they said',\n 'template.stats': 'Numbers',\n 'template.team': 'Team',\n 'template.pricing': 'Plans',\n 'template.newsletter': 'Sign up for news',\n 'template.footerBig': 'Footer with columns',\n 'template.hero': 'Hero',\n 'template.features': 'Features',\n 'template.about': 'About',\n 'template.cta': 'Call to action',\n 'template.contact': 'Contact form',\n 'template.footer': 'Footer',\n 'pageTemplate.full': 'Complete page',\n 'pageTemplate.full.note': 'Hero, features, about, call to action and footer',\n 'pageTemplate.simple': 'Direct',\n 'pageTemplate.simple.note': 'Hero, features and a contact form',\n 'pageTemplate.landing': 'Single offer',\n 'pageTemplate.landing.note': 'Hero, call to action and a form',\n\n // Panels and dialogs\n 'position.x': 'X',\n 'position.y': 'Y',\n 'style.font': 'Font',\n 'style.align': 'Text alignment',\n 'gradient.presets': 'Suggested gradients',\n 'action.target': 'Destination',\n 'action.unknown': 'Unavailable action ({type})',\n 'el.linkN': 'Link {n}',\n 'el.videoPlaceholder': 'https://youtu.be/…',\n 'el.iconOptions': 'Available icons',\n 'page.homeHint': \"The home page lives at the root of the site, so its address doesn't change and it can't be deleted.\",\n 'section.anchorInvalid': 'Use letters, numbers, - or _, and an id no other section or modal has.',\n 'newPage.slugFallback': 'address',\n 'theme.hex': '{label}, hex code',\n 'site.localeHint': 'Two letters, optionally with the country: en, es, pt-BR.',\n};\n\nexport type MessageKey = keyof typeof en;\nexport type Messages = Record<MessageKey, string>;\n","import type { Messages } from './en.ts';\n\nexport const es: Messages = {\n 'load.loading': 'Cargando el editor...',\n 'load.failed': 'No se pudo cargar el editor: {message}',\n 'load.retry': 'Intentar de nuevo',\n 'load.invalidDraft': 'No se puede leer el borrador de esta página ({issue}).',\n 'load.offline': 'Parece que no hay conexión.',\n\n 'toolbar.pageSelect': 'Página que se edita',\n 'toolbar.newPage': 'Página',\n 'toolbar.newPageHint': 'Crear otra página',\n 'toolbar.desktop': 'Escritorio',\n 'toolbar.mobile': 'Celular',\n 'toolbar.device': 'Dispositivo',\n 'toolbar.undo': 'Deshacer, Ctrl+Z',\n 'toolbar.redo': 'Rehacer, Ctrl+Shift+Z',\n 'toolbar.preview': 'Vista previa',\n 'toolbar.previewHint': 'Ver la página sin las guías del editor',\n 'toolbar.edit': 'Editar',\n 'toolbar.editHint': 'Volver a editar',\n 'toolbar.versions': 'Versiones',\n 'toolbar.versionsHint': 'Volver a una versión publicada',\n 'toolbar.theme': 'Tema',\n 'toolbar.site': 'Sitio',\n 'toolbar.siteHint': 'Datos para buscadores, redes y el sitio',\n 'toolbar.viewSite': 'Ver sitio',\n 'toolbar.publish': 'Publicar',\n 'toolbar.publishing': 'Publicando...',\n 'status.published': 'Publicado',\n 'status.unpublished': 'Sin publicar',\n\n 'save.idle': 'Los cambios se guardan solos',\n 'save.pending': 'Cambios sin guardar',\n 'save.saving': 'Guardando...',\n 'save.saved': 'Borrador guardado {time}',\n 'save.offline': 'Sin conexión. Los cambios se guardarán cuando vuelva.',\n 'save.failed': 'No se pudo guardar: {message}',\n 'save.retry': 'Reintentar',\n 'save.invalid': 'Hay valores no válidos ({issue}). Corrígelos para seguir guardando.',\n 'save.conflict': 'Esta página se cambió en otro lugar',\n 'conflict.title': 'Esta página cambió en otro lugar',\n 'conflict.body': 'Alguien guardó una versión más nueva de esta página, quizá tú en otra pestaña. Recárgala para seguir editando. Lo que cambiaste aquí desde el último guardado se perderá.',\n 'conflict.reload': 'Recargar la página',\n\n 'common.duplicate': 'Duplicar',\n 'common.delete': 'Eliminar',\n 'common.cancel': 'Cancelar',\n 'common.close': 'Cerrar',\n 'common.remove': 'Quitar',\n 'common.choose': 'Elegir',\n 'common.add': 'Agregar',\n 'common.new': 'Nueva',\n\n 'tabs.elements': 'Elementos',\n 'tabs.blocks': 'Bloques',\n 'tabs.layers': 'Capas',\n 'tabs.modals': 'Ventanas',\n 'tabs.media': 'Medios',\n 'elements.addHint': 'Haz clic para agregarlo, o arrástralo al lienzo',\n 'elements.app': 'De tu aplicación',\n 'elements.appHint': 'Estos elementos muestran datos vivos de tu aplicación.',\n 'elements.sectionsHint': 'Una sección entera, lista para editar. Entra al final de la página.',\n 'elements.sections': 'Secciones listas',\n 'elements.form': 'Formulario',\n 'elements.formHint': 'Los campos se envían con un botón cuya acción sea «Enviar el formulario». Deben estar en la misma sección o ventana que el botón.',\n 'layers.count': '{n} secciones',\n 'layers.modal': 'Ventana {title}',\n 'layers.section': 'Sección {n}',\n 'layers.expand': 'Desplegar sección',\n 'layers.collapse': 'Plegar sección',\n 'layers.up': 'Subir sección',\n 'layers.down': 'Bajar sección',\n 'layers.lock': 'Bloquear',\n 'layers.unlock': 'Desbloquear',\n 'layers.empty': 'Sin elementos',\n 'modals.hint': 'Las abre un botón con la acción «Abrir una ventana»',\n 'modals.defaultTitle': 'Más información',\n 'modals.titleLabel': 'Título de la ventana',\n 'modals.delete': 'Eliminar ventana',\n 'modals.elements': '{n} elementos',\n 'modals.edit': 'Editar contenido',\n 'modals.empty': 'Todavía no hay ventanas.',\n 'media.hint': 'Arrastra una imagen al lienzo o haz clic para agregarla',\n 'media.upload': 'Subir',\n 'media.empty': 'Todavía no has subido imágenes.',\n\n 'type.heading': 'Título',\n 'type.text': 'Texto',\n 'type.image': 'Imagen',\n 'type.button': 'Botón',\n 'type.divider': 'Separador',\n 'type.video': 'Video',\n 'type.shape': 'Figura',\n 'type.icon': 'Icono',\n 'type.gallery': 'Galería',\n 'type.slider': 'Deslizador',\n 'el.galleryItem': 'Imagen {n}',\n 'el.gallery': 'Imágenes',\n 'el.galleryAdd': 'Agregar una imagen',\n 'el.sliderArrows': 'Flechas para moverlo',\n 'el.sliderDots': 'Puntos debajo',\n 'el.sliderAutoplay': 'Que se mueva solo',\n 'el.sliderInterval': 'Segundos en cada imagen',\n 'el.galleryHint': 'Se muestran en este orden; la primera abre.',\n 'el.galleryLayout': 'Se muestra como',\n 'el.gallery.grid': 'Cuadrícula',\n 'el.gallery.strip': 'Tira que se desliza',\n 'el.galleryColumns': 'Columnas',\n 'el.galleryRemove': 'Quitar',\n 'type.navbar': 'Menú de navegación',\n 'type.input': 'Campo de texto',\n 'type.textarea': 'Campo largo',\n 'type.select': 'Lista desplegable',\n 'type.checkbox': 'Casilla',\n 'type.unknown': 'Elemento no disponible',\n\n 'menu.copy': 'Copiar',\n 'menu.paste': 'Pegar',\n 'menu.lock': 'Bloquear',\n 'menu.unlock': 'Desbloquear',\n 'zoom.label': 'Zoom',\n 'zoom.in': 'Acercar',\n 'zoom.out': 'Alejar',\n 'zoom.fit': 'Ajustar a la ventana',\n 'zoom.actual': 'Tamaño real',\n 'canvas.title': 'Lienzo de la página',\n 'canvas.editingModal': 'Editando la ventana «{title}»',\n 'canvas.backToPage': 'Volver a la página',\n 'canvas.emptyPage': 'Agrega un título, un texto y un botón desde el panel izquierdo, y acomódalos arrastrando.',\n 'canvas.emptyModal': 'Arrastra elementos o campos aquí: es el contenido de la ventana.',\n 'canvas.toolbar': 'Acciones del elemento',\n 'canvas.front': 'Traer al frente',\n 'canvas.back': 'Enviar atrás',\n 'canvas.radius': 'Redondear esquinas, ahora {n} px',\n 'canvas.rotate': 'Girar, ahora {n}°. Con Mayús, de 15 en 15',\n 'canvas.resize': 'Redimensionar ({handle})',\n 'canvas.corners': 'Esquinas {n} px',\n 'canvas.sticky': 'Fijo al bajar',\n 'canvas.emptyImage': 'Elige una imagen',\n 'canvas.emptyVideo': 'Pega el enlace de YouTube o Vimeo',\n 'canvas.stacked': 'En celular esta sección apila sus elementos sola.',\n 'canvas.loadingPreview': 'Cargando vista previa...',\n 'canvas.previewFailed': 'No se pudo cargar la vista previa',\n 'canvas.invalid': 'El lienzo muestra la última versión válida: {issue}',\n 'canvas.locked': 'Bloqueado',\n\n 'panel.design': 'Diseño',\n 'panel.page': 'Página',\n 'panel.nothing': 'Selecciona una sección o un elemento del lienzo.',\n 'multi.count': '{n} elementos seleccionados',\n 'multi.align': 'Alinear',\n 'multi.distribute': 'Repartir',\n 'multi.distributeX': 'Repartir en horizontal',\n 'multi.distributeY': 'Repartir en vertical',\n 'multi.distributeHint': 'Repartir necesita tres elementos o más.',\n 'multi.group': 'Agrupar',\n 'multi.ungroup': 'Desagrupar',\n 'multi.lock': 'Bloquear o desbloquear',\n 'multi.menuHint': 'Haz clic derecho en la selección para agrupar, bloquear, reordenar, duplicar o eliminar.',\n 'multi.hint': 'Mayús y clic agrega o quita elementos de la selección. Los agrupados se seleccionan juntos.',\n 'align.left': 'Alinear a la izquierda',\n 'align.hcenter': 'Centrar horizontalmente',\n 'align.right': 'Alinear a la derecha',\n 'align.top': 'Alinear arriba',\n 'align.vmiddle': 'Centrar verticalmente',\n 'align.bottom': 'Alinear abajo',\n\n 'modal.heading': 'Ventana',\n 'modal.title': 'Título',\n 'modal.showTitle': 'Mostrarlo arriba de la ventana',\n 'modal.showTitleHint': 'Si lo ocultas sigue sirviendo para reconocer la ventana y para los lectores de pantalla.',\n 'modal.size': 'Tamaño',\n 'modal.size.sm': 'Pequeña',\n 'modal.size.md': 'Mediana',\n 'modal.size.lg': 'Grande',\n 'modal.size.xl': 'Muy grande',\n 'modal.size.full': 'Pantalla completa',\n 'modal.width': 'Ancho a medida',\n 'modal.fullHint': 'A pantalla completa la ventana ocupa todo el navegador y el diseño se hace sobre 1200 px.',\n 'modal.background': 'Color de fondo',\n\n 'section.heading': 'Sección',\n 'section.addAfter': 'Agregar una sección debajo',\n 'section.duplicate': 'Duplicar la sección',\n 'canvas.emptySection': 'Esta sección está vacía: arrastra un elemento aquí.',\n 'section.delete': 'Eliminar sección',\n 'section.shownAs': 'Se muestra como',\n 'section.alone': 'Sección normal',\n 'section.tab': 'Pestaña del grupo anterior',\n 'section.step': 'Paso del grupo anterior',\n 'section.groupLabel': 'Nombre de la pestaña o del paso',\n 'section.groupHint': 'Las secciones seguidas del mismo grupo se ven de a una, con su barra de pestañas o de pasos.',\n 'section.stepLabel': 'Paso {n}',\n 'section.anchor': 'Identificador para anclas',\n 'section.anchorHint': 'Lo usan los enlaces con la acción «Ir a una sección».',\n 'section.fitHeight': 'Ajustar alto al contenido',\n 'section.generateMobile': 'Generar vista de celular',\n 'section.heightDesktop': 'Alto escritorio',\n 'section.heightMobile': 'Alto celular',\n 'fill.video': 'Video',\n 'section.video': 'Dirección del video',\n 'section.videoHint': 'Un enlace https a un archivo .mp4 o .webm. Se reproduce en silencio y en bucle.',\n 'section.poster': 'Imagen mientras carga el video',\n 'section.flow': 'Acomodar',\n 'section.flowHint': 'Sola, la sección pone sus elementos uno tras otro y crece con ellos.',\n 'section.flow.free': 'A mano',\n 'section.flow.column': 'Uno debajo del otro',\n 'section.flow.row': 'Uno al lado del otro',\n 'section.flowGap': 'Separación',\n 'section.flowAlign': 'Alineación',\n 'section.align.start': 'Al inicio',\n 'section.align.center': 'Centrados',\n 'section.align.end': 'Al final',\n 'section.align.between': 'Repartidos',\n 'section.wide': 'De borde a borde',\n 'section.wideHint': 'La sección ocupa toda la pantalla en vez del ancho del tema.',\n 'section.background': 'Fondo',\n 'section.color': 'Color de la sección',\n 'section.image': 'Imagen de fondo',\n 'section.chooseImage': 'Elegir imagen',\n 'section.parallax': 'Efecto parallax al bajar',\n 'section.overlay': 'Oscurecer la imagen',\n 'fill.color': 'Color',\n 'fill.gradient': 'Degradado',\n 'fill.image': 'Imagen',\n 'gradient.from': 'Desde',\n 'gradient.to': 'Hasta',\n 'gradient.shape': 'Forma',\n 'gradient.linear': 'Lineal',\n 'gradient.radial': 'Circular',\n 'gradient.angle': 'Ángulo',\n 'gradient.preset.primary': 'Principal',\n 'gradient.preset.soft': 'Suave',\n 'gradient.preset.halo': 'Halo',\n 'gradient.preset.night': 'Noche',\n\n 'page.title': 'Título de la página',\n 'page.address': 'Dirección',\n 'page.home': 'Página de inicio',\n 'page.saveAddress': 'Guardar dirección',\n 'page.addressSaved': 'Dirección guardada.',\n 'page.delete': 'Borrar página',\n 'page.deleteConfirm': '¿Borrar la página «{title}»? No se puede deshacer.',\n 'page.deleted': 'Página borrada.',\n 'page.templates': 'Empezar con una plantilla',\n 'page.seoTitle': 'Título para buscadores',\n 'page.seoTitleHint': 'Es lo que se lee en la pestaña del navegador y en los buscadores.',\n 'page.description': 'Descripción',\n 'page.shortcuts': 'Atajos',\n 'page.shortcutUndo': 'Ctrl+Z deshace, Ctrl+Shift+Z rehace',\n 'page.shortcutSave': 'Ctrl+S guarda el borrador',\n 'page.shortcutCopy': 'Ctrl+C, Ctrl+V y Ctrl+D copian, pegan y duplican',\n 'page.shortcutNudge': 'Las flechas mueven la selección, con Mayús la mueven más',\n\n 'newPage.title': 'Nueva página',\n 'newPage.description': 'Cada página vive en su propia dirección dentro del sitio.',\n 'newPage.titleLabel': 'Título',\n 'newPage.slug': 'Dirección',\n 'newPage.slugPlaceholder': 'servicios',\n 'newPage.at': 'Quedará en {url}',\n 'newPage.create': 'Crear página',\n\n 'toolbar.submissions': 'Mensajes',\n 'toolbar.submissionsHint': 'Lo que los visitantes enviaron con tus formularios',\n 'submissions.title': 'Mensajes de formularios',\n 'submissions.description': 'Lo que los visitantes enviaron con los formularios de tus páginas, los más nuevos primero.',\n 'submissions.empty': 'Todavía no hay mensajes.',\n 'submissions.more': 'Cargar más',\n 'submissions.from': '/{page} · {source}',\n 'submissions.failed': 'No se pudieron cargar los mensajes: {message}',\n 'submissions.checked': 'Sí',\n 'submissions.unchecked': 'No',\n 'versions.title': 'Versiones publicadas',\n 'versions.description': 'Cada publicación guarda la anterior. Restaurar la trae al borrador, sin tocar lo que ven los visitantes hasta que publiques.',\n 'versions.by': 'Publicó {name}',\n 'versions.restore': 'Restaurar',\n 'versions.restored': 'Versión restaurada en el borrador.',\n 'versions.empty': 'Todavía no se ha publicado nada.',\n\n 'publish.done': 'Publicado.',\n 'publish.failed': 'No se pudo publicar: {message}',\n\n 'theme.title': 'Tema del sitio',\n 'theme.description': 'Colores y tipografías que usan todas las páginas.',\n 'theme.palettes': 'Paletas',\n 'theme.colors': 'Colores',\n 'theme.link': 'Enlazar los elementos a esta paleta',\n 'theme.linkHint': 'Los elementos con color propio no cambian al cambiar la paleta. Ese botón los pasa al color del tema más parecido.',\n 'theme.headingFont': 'Tipografía de títulos',\n 'theme.bodyFont': 'Tipografía de textos',\n 'theme.radius': 'Esquinas',\n 'theme.maxWidth': 'Ancho máximo del contenido',\n 'theme.width.1080': 'Angosto, 1080 px',\n 'theme.width.1200': 'Estándar, 1200 px',\n 'theme.width.1320': 'Amplio, 1320 px',\n 'theme.width.1440': 'Muy amplio, 1440 px',\n 'theme.previewLabel': 'Vista previa del tema',\n 'theme.previewHeading': 'Páginas que se ven cuidadas',\n 'theme.previewText': 'Así se verán los títulos y los textos de tu sitio.',\n 'theme.previewButton': 'Empezar',\n 'theme.save': 'Guardar tema',\n 'theme.saved': 'Tema guardado.',\n 'palette.blue': 'Azul clásico',\n 'palette.mint': 'Menta',\n 'palette.sand': 'Arena',\n 'palette.indigo': 'Índigo',\n 'palette.graphite': 'Grafito',\n 'token.primary': 'Principal',\n 'token.secondary': 'Secundario',\n 'token.background': 'Fondo',\n 'token.surface': 'Superficie',\n 'token.text': 'Texto',\n 'token.muted': 'Texto suave',\n 'font.Inter': 'Neutra y moderna',\n 'font.Poppins': 'Geométrica y amable',\n 'font.Montserrat': 'Amplia, buena para títulos',\n 'font.DM Sans': 'Limpia y compacta',\n 'font.Work Sans': 'Sobria, muy legible',\n 'font.Nunito': 'Redondeada y cercana',\n 'font.Lora': 'Serif clásica',\n 'font.Playfair Display': 'Serif elegante',\n 'font.Merriweather': 'Serif firme',\n 'font.Source Sans 3': 'Institucional',\n\n 'site.title': 'Ajustes del sitio',\n 'site.description': 'Lo que ven buscadores y redes, y los datos de tu sitio.',\n 'site.seoTitle': 'Título por defecto para buscadores',\n 'site.seoDescription': 'Descripción por defecto',\n 'site.shareImage': 'Imagen al compartir',\n 'site.shareImageHint': 'Es la que se ve al pegar el enlace en un chat o una red social.',\n 'site.favicon': 'Icono del navegador',\n 'site.locale': 'Idioma de las páginas publicadas',\n 'site.details': 'Datos',\n 'site.save': 'Guardar ajustes',\n 'site.saved': 'Ajustes guardados.',\n\n 'library.title': 'Imágenes',\n 'library.description': 'Las fotos y gráficos, listos para usar en cualquier página.',\n 'library.upload': 'Subir imagen',\n 'library.uploading': 'Subiendo...',\n 'library.formats': 'JPG, PNG, WebP, AVIF o SVG',\n 'library.use': 'Usar {name}',\n 'library.delete': 'Borrar {name}',\n 'library.uploadFailed': 'No se pudo subir la imagen: {message}',\n 'library.deleteFailed': 'No se pudo borrar la imagen: {message}',\n 'library.quota': '{used} de {limit} usados',\n\n 'el.text': 'Texto',\n 'el.accent': 'Parte en otro color',\n 'el.accentPlaceholder': 'Escribe aquí las palabras a resaltar',\n 'el.accentColor': 'Color del resalte',\n 'el.level': 'Jerarquía',\n 'el.level.1': 'Título principal',\n 'el.level.2': 'Título de sección',\n 'el.level.3': 'Subtítulo',\n 'el.level.4': 'Subtítulo pequeño',\n 'el.image': 'Imagen',\n 'el.chooseFromLibrary': 'Elegir de la biblioteca',\n 'el.imageUrl': 'o pega una dirección https://',\n 'el.alt': 'Texto alternativo',\n 'el.altPlaceholder': 'Qué se ve en la imagen',\n 'el.fit': 'Ajuste',\n 'el.fit.cover': 'Recortar para llenar',\n 'el.fit.contain': 'Mostrar completa',\n 'el.crop': 'Recorte',\n 'el.shape': 'Figura',\n 'el.opacity': 'Opacidad',\n 'shape.rectangle': 'Rectángulo',\n 'shape.ellipse': 'Círculo',\n 'shape.triangle': 'Triángulo',\n 'shape.blob': 'Mancha',\n 'shape.arch': 'Arco',\n 'shape.diagonal': 'Diagonal',\n 'shape.dots': 'Trama de puntos',\n 'shape.grid': 'Trama de rejilla',\n 'el.videoUrl': 'Enlace del video',\n 'el.videoHint': 'Acepta YouTube y Vimeo. El video se carga solo cuando el visitante llega a esa parte.',\n 'el.buttonLabel': 'Texto del botón',\n 'el.action': 'Acción',\n 'action.none': 'Sin acción',\n 'action.whatsapp': 'WhatsApp',\n 'action.phone': 'Llamar',\n 'action.email': 'Correo',\n 'action.url': 'Enlace externo',\n 'action.anchor': 'Ir a una sección',\n 'action.modal': 'Abrir una ventana',\n 'action.submit': 'Enviar el formulario',\n 'action.page': 'Ir a otra página',\n 'action.top': 'Volver arriba',\n 'action.back': 'Volver atrás',\n 'action.step_next': 'Paso siguiente',\n 'action.step_prev': 'Paso anterior',\n 'action.chooseModal': 'Selecciona una ventana',\n 'action.choosePage': 'Selecciona una página',\n 'action.placeholder.whatsapp': '+573001112233',\n 'action.placeholder.phone': '+573001112233',\n 'action.placeholder.email': 'hola@ejemplo.com',\n 'action.placeholder.anchor': 'id de la sección',\n 'action.placeholder.url': 'https://...',\n 'action.submitHint': 'Envía los campos que estén en esta misma sección o ventana.',\n 'el.presets': 'Prediseñados',\n 'navbar.preset.split': 'Marca y enlaces',\n 'navbar.preset.center': 'Centrado',\n 'navbar.preset.dark': 'Oscuro',\n 'navbar.preset.pill': 'Pastilla',\n 'navbar.preset.card': 'Tarjeta',\n 'navbar.preset.underline': 'Subrayado',\n 'navbar.preset.divided': 'Dividido',\n 'el.navbarTemplate': 'Plantilla',\n 'el.navbarTemplate.plain': 'Simple',\n 'el.navbarTemplate.pill': 'Pastilla',\n 'el.navbarTemplate.card': 'Tarjeta',\n 'el.navbarTemplate.underline': 'Subrayado',\n 'el.navbarTemplate.divided': 'Dividido',\n 'el.brand': 'Marca',\n 'el.brandPlaceholder': 'Nombre de tu marca',\n 'el.sticky': 'Fijar arriba al bajar la página',\n 'el.scrollStyle': 'Al bajar la página',\n 'el.scroll.same': 'Se queda igual',\n 'el.scroll.shadow': 'Gana sombra',\n 'el.scroll.solid': 'Fondo sólido y sombra',\n 'el.scroll.compact': 'Se encoge, sólido y con sombra',\n 'el.scrollBackground': 'Fondo al bajar',\n 'el.scrollColor': 'Texto al bajar',\n 'el.scrollColorsHint': 'Una barra que empieza transparente sobre una foto necesita sus propios colores al bajar, o se vuelve invisible.',\n 'el.notSticky': 'Sin fijar, el menú se queda donde lo pusiste y se va con el desplazamiento.',\n 'el.layout': 'Distribución',\n 'el.layout.split': 'Marca y enlaces a los lados',\n 'el.layout.left': 'Todo a la izquierda',\n 'el.layout.center': 'Todo centrado',\n 'el.links': 'Enlaces',\n 'el.linkLabel': 'Texto del enlace',\n 'el.removeLink': 'Quitar enlace',\n 'el.linksHint': 'En celular los enlaces se recogen en un menú desplegable.',\n 'el.icon': 'Icono',\n 'el.iconSearch': 'Buscar: heart, calendar, phone...',\n 'el.noResults': 'Sin resultados.',\n 'el.stroke': 'Grosor del trazo',\n 'el.fieldLabel': 'Etiqueta',\n 'el.inputType': 'Tipo de dato',\n 'el.inputType.text': 'Texto',\n 'el.inputType.email': 'Correo',\n 'el.inputType.tel': 'Teléfono',\n 'el.inputType.number': 'Número',\n 'el.inputType.date': 'Fecha',\n 'el.options': 'Opciones',\n 'el.optionsHint': 'Una opción por línea.',\n 'el.placeholder': 'Texto de ayuda',\n 'el.multiple': 'Varias respuestas',\n 'el.required': 'Obligatorio',\n 'el.unknown': 'Este elemento viene de un complemento que no está instalado. Se conserva tal cual y no se puede editar.',\n\n 'style.fill': 'Color y fondo',\n 'style.color': 'Color',\n 'style.background': 'Fondo',\n 'style.backgroundType': 'Tipo de fondo',\n 'style.backgroundColor': 'Color de fondo',\n 'style.transparency': 'Transparencia',\n 'style.glass': 'Vidrio',\n 'style.glassHint': 'Desenfoca lo que queda detrás. Con el fondo semitransparente da el efecto de vidrio.',\n 'style.text': 'Texto',\n 'style.fontHeading': 'Títulos',\n 'style.fontBody': 'Texto',\n 'style.size': 'Tamaño',\n 'style.weight': 'Grosor de la letra',\n 'style.weight.300': 'Ligero',\n 'style.weight.400': 'Normal',\n 'style.weight.500': 'Medio',\n 'style.weight.600': 'Semi negrita',\n 'style.weight.700': 'Negrita',\n 'style.weight.800': 'Extra negrita',\n 'style.align.left': 'Izquierda',\n 'style.align.center': 'Centro',\n 'style.align.right': 'Derecha',\n 'style.sizeMobile': 'Tamaño en celular',\n 'style.tracking': 'Espacio entre letras',\n 'style.case': 'Letras',\n 'style.case.none': 'Como se escribió',\n 'style.case.upper': 'MAYÚSCULAS',\n 'style.case.lower': 'minúsculas',\n 'style.case.title': 'Tipo Título',\n 'style.face': 'Trazo',\n 'style.face.solid': 'Lleno',\n 'style.face.outline': 'Hueco',\n 'style.face.glow': 'Con resplandor',\n 'style.autoHeight': 'Crecer con el texto',\n 'style.autoHeightHint': 'La caja toma el alto que su texto necesita, así una línea larga nunca se corta.',\n 'style.lineHeight': 'Interlineado',\n 'style.frame': 'Marco',\n 'style.radius': 'Esquinas',\n 'style.padding': 'Relleno',\n 'style.border': 'Borde',\n 'style.layer': 'Capa',\n 'style.borderColor': 'Color del borde',\n 'style.shadow': 'Sombra',\n 'style.shadow.none': 'Sin sombra',\n 'style.shadow.sm': 'Sutil',\n 'style.shadow.md': 'Media',\n 'style.shadow.lg': 'Marcada',\n 'style.shadow.custom': 'A medida',\n 'style.customShadow': 'Sombra a medida',\n 'style.shadowBlur': 'Difuminado',\n 'style.shadowSpread': 'Extensión',\n 'style.shadowColor': 'Color de la sombra',\n 'style.shadowOpacity': 'Intensidad',\n 'style.transform': 'Transformar',\n 'style.rotate': 'Giro',\n 'style.straighten': 'Enderezar',\n 'style.flipX': 'Voltear en horizontal',\n 'style.flipY': 'Voltear en vertical',\n 'style.overflow': 'Contenido que se sale',\n 'style.overflow.visible': 'Se ve completo',\n 'style.overflow.hidden': 'Se recorta',\n 'style.overflow.scroll-x': 'Se desliza a los lados',\n 'style.overflow.scroll-y': 'Se desliza hacia abajo',\n 'style.visibleOn': 'Se ve en',\n 'style.visible.all': 'Todos los dispositivos',\n 'style.visible.desktop': 'Solo escritorio',\n 'style.visible.mobile': 'Solo celular',\n 'style.transformHint': 'En el lienzo giras con el tirador de la esquina de abajo y redondeas con el punto de arriba. Con Mayús el giro va de 15 en 15.',\n 'style.motion': 'Movimiento',\n 'style.entrance': 'Al aparecer',\n 'style.anim.none': 'Sin animación',\n 'style.anim.fade': 'Aparecer',\n 'style.anim.up': 'Subir',\n 'style.anim.down': 'Bajar',\n 'style.anim.left': 'Entrar desde la izquierda',\n 'style.anim.right': 'Entrar desde la derecha',\n 'style.anim.zoom': 'Acercarse',\n 'style.delay': 'Espera',\n 'style.duration': 'Duración',\n 'style.anim.blur': 'Enfocarse',\n 'style.anim.reveal': 'Barrido',\n 'style.hover.sink': 'Hundir',\n 'style.hover.tilt': 'Inclinar',\n 'style.hover.glow': 'Resplandor',\n 'style.scroll': 'Con el scroll',\n 'style.scrollHint': 'Se mueve mientras cruza la pantalla, donde el navegador lo permita.',\n 'style.scroll.none': 'Quieto',\n 'style.scroll.rise': 'Subir',\n 'style.scroll.drift': 'Derivar de lado',\n 'style.scroll.zoom': 'Acercarse',\n 'el.navbarTemplate.floating': 'Flotante',\n 'el.navbarTemplate.boxed': 'Enlaces en caja',\n 'el.navbarTemplate.ribbon': 'Cinta',\n 'el.navbarTemplate.outline': 'Con contorno',\n 'el.navbarTemplate.minimal': 'Mínima',\n 'el.navbarTemplate.stack': 'Marca sobre los enlaces',\n 'el.navbarTemplate.rail': 'Columna al costado',\n 'el.navbarPosition': 'Dónde se queda fija',\n 'el.navbarPosition.top': 'Arriba de la pantalla',\n 'el.navbarPosition.bottom': 'Abajo de la pantalla',\n 'el.layout.right': 'Enlaces primero',\n 'el.navbarTemplate.tracked': 'Espaciado',\n 'style.hover': 'Al pasar el cursor',\n 'style.hover.none': 'Nada',\n 'style.hover.lift': 'Levantar',\n 'style.hover.grow': 'Agrandar',\n 'style.hover.fade': 'Atenuar',\n 'style.motionHint': 'La animación se ve en la vista previa y en el sitio publicado.',\n 'position.title': 'Posición en {device}',\n 'position.desktop': 'escritorio',\n 'position.mobile': 'celular',\n 'position.width': 'An',\n 'position.height': 'Al',\n 'position.pinned': 'Fijo al desplazar',\n 'position.pinnedHint': 'Se queda en su sitio en la pantalla mientras la página se desplaza, como un botón flotante o una barra.',\n 'position.own': 'Posición propia en celular.',\n 'position.inherit': 'Volver a heredar de escritorio',\n 'position.inherited': 'Hereda la posición de escritorio. Al moverlo aquí toma una propia; mientras alguno herede, la sección se apila en celular.',\n 'color.custom': 'Propio',\n 'color.customLabel': '{label}, color propio',\n\n 'toast.copied': 'Elemento copiado.',\n 'toast.copiedMany': '{n} elementos copiados.',\n 'toast.copyFailed': 'No se pudo copiar en este navegador.',\n 'toast.pasted': 'Pegado en esta sección.',\n 'toast.mobileGenerated': 'Vista de celular generada. Ajusta lo que quieras.',\n 'toast.pageCreated': 'Página creada.',\n 'toast.failed': 'Algo salió mal: {message}',\n 'toast.dismiss': 'Descartar',\n\n 'default.heading': 'Un título que invite a quedarse',\n 'default.text': 'Cuenta en una frase qué te hace distinto.',\n 'default.button': 'Empezar',\n 'default.video': 'Video',\n 'default.field': 'Nombre',\n 'default.fieldPlaceholder': 'Escribe aquí',\n 'default.checkbox': 'Acepto el tratamiento de mis datos',\n 'default.option': 'Opción {n}',\n 'default.brand': 'Tu marca',\n 'default.link': 'Enlace',\n 'default.link.home': 'Inicio',\n 'default.link.features': 'Características',\n 'default.link.about': 'Nosotros',\n 'default.link.contact': 'Contacto',\n 'default.link.start': 'Empezar',\n\n 'template.group.open': 'Abrir la página',\n 'template.group.tell': 'Contarlo',\n 'template.group.convince': 'Respaldarlo',\n 'template.group.close': 'Cerrarlo',\n 'template.heroCentered': 'Portada centrada',\n 'template.heroSlider': 'Portada con deslizador',\n 'template.steps': 'Cómo funciona',\n 'template.gallery': 'Galería',\n 'template.faq': 'Preguntas',\n 'template.logos': 'Logos',\n 'template.testimonial': 'Lo que dijeron',\n 'template.stats': 'Números',\n 'template.team': 'Equipo',\n 'template.pricing': 'Planes',\n 'template.newsletter': 'Suscripción',\n 'template.footerBig': 'Pie con columnas',\n 'template.hero': 'Portada',\n 'template.features': 'Características',\n 'template.about': 'Nosotros',\n 'template.cta': 'Llamada a la acción',\n 'template.contact': 'Formulario de contacto',\n 'template.footer': 'Pie de página',\n 'pageTemplate.full': 'Página completa',\n 'pageTemplate.full.note': 'Portada, características, nosotros, llamada a la acción y pie',\n 'pageTemplate.simple': 'Directa',\n 'pageTemplate.simple.note': 'Portada, características y formulario de contacto',\n 'pageTemplate.landing': 'Una sola oferta',\n 'pageTemplate.landing.note': 'Portada, llamada a la acción y formulario',\n\n 'position.x': 'X',\n 'position.y': 'Y',\n 'style.font': 'Tipografía',\n 'style.align': 'Alineación del texto',\n 'gradient.presets': 'Degradados sugeridos',\n 'action.target': 'Destino',\n 'action.unknown': 'Acción no disponible ({type})',\n 'el.linkN': 'Enlace {n}',\n 'el.videoPlaceholder': 'https://youtu.be/…',\n 'el.iconOptions': 'Iconos disponibles',\n 'page.homeHint': 'La página de inicio vive en la raíz del sitio: su dirección no cambia y no se puede borrar.',\n 'section.anchorInvalid': 'Usa letras, números, - o _, y un identificador que no tenga otra sección o ventana.',\n 'newPage.slugFallback': 'direccion',\n 'theme.hex': '{label}, código hex',\n 'site.localeHint': 'Dos letras, y si quieres el país: en, es, pt-BR.',\n};\n","import type { Localized } from '@skylivellc/lienzo-core';\nimport { en, type MessageKey, type Messages } from './en.ts';\nimport { es } from './es.ts';\n\nexport { en, es };\nexport type { MessageKey, Messages };\n\n/** Packs shipped with the editor. Apps add or override locales through the `messages` prop. */\nexport const packs: Readonly<Record<string, Messages>> = { en, es };\n\n/** Extra or overriding strings, by locale. A partial pack falls back to English per key. */\nexport type MessageOverrides = Readonly<Record<string, Partial<Messages>>>;\n\nexport type Translator = {\n locale: string;\n t(key: MessageKey, params?: Readonly<Record<string, string | number>>): string;\n /** Text the app declared in its catalog, in the editor's locale. */\n localized(text: Localized): string;\n};\n\n/** `es-MX` reads `es-MX`, then `es`, then English, for each key. */\nexport function createTranslator(locale: string, overrides: MessageOverrides = {}): Translator {\n const language = locale.split('-')[0] ?? locale;\n const chain: Partial<Messages>[] = [\n overrides[locale] ?? {},\n packs[locale] ?? {},\n overrides[language] ?? {},\n packs[language] ?? {},\n overrides.en ?? {},\n ];\n const lookup = (key: MessageKey): string => chain.find((pack) => pack[key] !== undefined)?.[key] ?? en[key];\n\n return {\n locale,\n t: (key, params) => format(lookup(key), params),\n localized: (text) => text[locale] ?? text[language] ?? text.en,\n };\n}\n\nexport function format(template: string, params?: Readonly<Record<string, string | number>>): string {\n return params ? template.replace(/\\{(\\w+)\\}/g, (match, name: string) => (name in params ? String(params[name]) : match)) : template;\n}\n","import type { Box, CoreElement, CoreElementType, Section } from '@skylivellc/lienzo-core';\nimport { createTranslator, type MessageKey } from '../i18n/index.ts';\nimport { newId } from './document.ts';\nimport { coreSpecs } from './elements.ts';\n\n/**\n * Ready-made sections and pages. They are only a starting point: they are\n * made of ordinary elements, edited like any other. Colors are theme tokens\n * so they follow the palette. Copy is neutral English, meant to be replaced.\n */\ntype Part = { type: CoreElementType; box: Box; props?: CoreElement['props']; style?: CoreElement['style'] };\n\nconst english = createTranslator('en').t;\n\nfunction build(height: number, background: Section['background'], parts: readonly Part[]): Section {\n return {\n id: newId('section'),\n height: { desktop: height, mobile: Math.round(height * 1.3) },\n background,\n elements: parts.map((part, index) => {\n const defaults = coreSpecs[part.type].create(english);\n\n return {\n id: newId(part.type),\n type: part.type,\n z: index + 1,\n layout: { desktop: { ...part.box }, mobile: null },\n props: { ...defaults.props, ...part.props },\n style: { ...defaults.style, ...part.style },\n };\n }),\n };\n}\n\nconst color = (token: string): Section['background'] => ({ type: 'color', color: token });\n\nconst field = { color: 'secondary', background: 'background', border_width: 1, border_color: 'muted', radius: 12, padding: 12 } as const;\n\nconst feature = (y: number, icon: string, title: string, text: string): Part[] => [\n { type: 'icon', box: { x: 43, y: y + 2, w: 3.5, h: 40 }, props: { icon, stroke: 2 }, style: { color: 'primary' } },\n { type: 'heading', box: { x: 49, y, w: 42, h: 30 }, props: { text: title, level: 3 }, style: { color: 'secondary', font: 'heading', size: 20, weight: 700, line_height: 1.3 } },\n { type: 'text', box: { x: 49, y: y + 32, w: 42, h: 44 }, props: { text }, style: { color: 'muted', size: 15, line_height: 1.5 } },\n];\n\n\nconst plan = (x: number, name: string, price: string, lines: string, featured: boolean): Part[] => [\n { type: 'shape', box: { x: x - 1.5, y: 150, w: 29, h: 330 }, props: { shape: 'rectangle' }, style: { background: featured ? 'secondary' : 'surface', radius: 18 } },\n { type: 'heading', box: { x, y: 182, w: 26, h: 34 }, props: { text: name, level: 3 }, style: { color: featured ? 'background' : 'secondary', font: 'heading', size: 19, weight: 700 } },\n { type: 'heading', box: { x, y: 220, w: 26, h: 56 }, props: { text: price, level: 3 }, style: { color: featured ? 'background' : 'secondary', font: 'heading', size: 40, weight: 700 } },\n { type: 'text', box: { x, y: 288, w: 26, h: 120 }, props: { text: lines }, style: { color: featured ? 'background' : 'muted', size: 15, line_height: 1.8, opacity: featured ? 0.85 : 1 } },\n {\n type: 'button', box: { x, y: 414, w: 26, h: 48 },\n props: { label: 'Choose this one', action: { type: 'anchor', value: '' } },\n style: { background: featured ? 'background' : 'primary', color: featured ? 'secondary' : 'background', radius: 12, weight: 600, size: 15 },\n },\n];\n\nconst step = (x: number, number: string, title: string, text: string): Part[] => [\n { type: 'heading', box: { x, y: 150, w: 26, h: 60 }, props: { text: number, level: 3 }, style: { color: 'primary', font: 'heading', size: 46, weight: 700 } },\n { type: 'heading', box: { x, y: 216, w: 26, h: 34 }, props: { text: title, level: 3 }, style: { color: 'secondary', font: 'heading', size: 19, weight: 700 } },\n { type: 'text', box: { x, y: 254, w: 26, h: 90 }, props: { text }, style: { color: 'muted', size: 15, line_height: 1.6 } },\n];\n\nconst person = (x: number, name: string, role: string): Part[] => [\n { type: 'image', box: { x, y: 150, w: 20, h: 200 }, props: { src: '', alt: name }, style: { radius: 16, object_fit: 'cover' } },\n { type: 'heading', box: { x, y: 362, w: 20, h: 30 }, props: { text: name, level: 3 }, style: { color: 'secondary', font: 'heading', size: 17, weight: 700 } },\n { type: 'text', box: { x, y: 394, w: 20, h: 28 }, props: { text: role }, style: { color: 'muted', size: 14 } },\n];\n\nconst question = (y: number, ask: string, answer: string): Part[] => [\n { type: 'heading', box: { x: 6, y, w: 42, h: 32 }, props: { text: ask, level: 3 }, style: { color: 'secondary', font: 'heading', size: 18, weight: 700 } },\n { type: 'text', box: { x: 52, y, w: 42, h: 76 }, props: { text: answer }, style: { color: 'muted', size: 15, line_height: 1.6 } },\n { type: 'divider', box: { x: 6, y: y + 88, w: 88, h: 2 }, props: {}, style: { color: 'muted', opacity: 0.25 } },\n];\n\nconst sections = {\n hero: () => build(680, color('background'), [\n { type: 'shape', box: { x: 52, y: 120, w: 42, h: 400 }, props: { shape: 'blob' }, style: { background: 'surface' } },\n { type: 'image', box: { x: 50, y: 96, w: 40, h: 380 }, props: { src: '', alt: 'Product photo' }, style: { radius: 22, object_fit: 'cover', shadow: 'lg' } },\n {\n type: 'heading', box: { x: 6, y: 140, w: 40, h: 180 },\n props: { text: 'Build something people remember', level: 1 },\n style: { color: 'secondary', font: 'heading', size: 48, weight: 700, line_height: 1.1 },\n },\n {\n type: 'text', box: { x: 6, y: 336, w: 36, h: 90 },\n props: { text: \"Tell visitors what you offer, who it is for and what happens next, in two short lines.\" },\n style: { color: 'muted', size: 18, line_height: 1.6 },\n },\n {\n type: 'button', box: { x: 6, y: 456, w: 16, h: 54 },\n props: { label: 'Get started', action: { type: 'anchor', value: '' } },\n style: { background: 'primary', color: 'background', radius: 14, weight: 600 },\n },\n ]),\n features: () => build(460, color('surface'), [\n { type: 'shape', box: { x: 39, y: 72, w: 56, h: 316 }, props: { shape: 'rectangle' }, style: { background: 'background', radius: 24, shadow: 'sm' } },\n { type: 'heading', box: { x: 6, y: 92, w: 30, h: 70 }, props: { text: 'What we do', level: 2 }, style: { color: 'secondary', font: 'heading', size: 38, weight: 700 } },\n {\n type: 'text', box: { x: 6, y: 172, w: 28, h: 110 },\n props: { text: 'Three reasons people choose us, each in a single sentence.' },\n style: { color: 'muted', size: 17, line_height: 1.6 },\n },\n ...feature(100, 'star', 'Clear from the start', 'You know what you get and what it costs before anything begins.'),\n ...feature(190, 'clock', 'On time', 'We agree on dates up front and keep you posted at every step.'),\n ...feature(280, 'heart', 'Here afterwards', 'Questions after the work is done get the same attention.'),\n ]),\n about: () => build(480, color('background'), [\n { type: 'image', box: { x: 6, y: 80, w: 32, h: 320 }, props: { src: '', alt: 'Our team' }, style: { radius: 22, object_fit: 'cover' } },\n { type: 'heading', box: { x: 44, y: 90, w: 40, h: 70 }, props: { text: 'Who we are', level: 2 }, style: { color: 'secondary', font: 'heading', size: 38, weight: 700 } },\n {\n type: 'text', box: { x: 44, y: 172, w: 40, h: 80 },\n props: { text: 'A small team that cares about the details. The same people follow your project from the first call to the last.' },\n style: { color: 'muted', size: 17, line_height: 1.6 },\n },\n { type: 'heading', box: { x: 44, y: 284, w: 20, h: 50 }, props: { text: '12 years', level: 3 }, style: { color: 'primary', font: 'heading', size: 32, weight: 700 } },\n { type: 'text', box: { x: 44, y: 336, w: 20, h: 40 }, props: { text: 'in business' }, style: { color: 'muted', size: 15 } },\n { type: 'heading', box: { x: 66, y: 284, w: 24, h: 50 }, props: { text: '1,200+', level: 3 }, style: { color: 'primary', font: 'heading', size: 32, weight: 700 } },\n { type: 'text', box: { x: 66, y: 336, w: 24, h: 40 }, props: { text: 'happy customers' }, style: { color: 'muted', size: 15 } },\n ]),\n cta: () => build(300, color('primary'), [\n {\n type: 'heading', box: { x: 6, y: 80, w: 48, h: 110 },\n props: { text: 'Ready to get started?', level: 2 },\n style: { color: 'background', font: 'heading', size: 34, weight: 700, line_height: 1.15 },\n },\n {\n type: 'text', box: { x: 6, y: 196, w: 40, h: 56 },\n props: { text: 'It takes two minutes to tell us what you need, and we answer the same day.' },\n style: { color: 'background', size: 16, line_height: 1.6, opacity: 0.9 },\n },\n {\n type: 'button', box: { x: 66, y: 110, w: 28, h: 56 },\n props: { label: 'Contact us', action: { type: 'anchor', value: '' } },\n style: { background: 'background', color: 'primary', radius: 14, weight: 700 },\n },\n ]),\n contact: () => build(520, color('surface'), [\n { type: 'heading', box: { x: 6, y: 80, w: 32, h: 120 }, props: { text: 'Get in touch', level: 2 }, style: { color: 'secondary', font: 'heading', size: 38, weight: 700 } },\n {\n type: 'text', box: { x: 6, y: 190, w: 30, h: 110 },\n props: { text: \"Leave your details and we'll get back to you within one business day.\" },\n style: { color: 'muted', size: 17, line_height: 1.6 },\n },\n { type: 'input', box: { x: 44, y: 80, w: 24, h: 78 }, props: { label: 'Name', placeholder: 'Your name', required: true, input_type: 'text' }, style: field },\n { type: 'input', box: { x: 70, y: 80, w: 24, h: 78 }, props: { label: 'Email', placeholder: 'you@example.com', required: true, input_type: 'email' }, style: field },\n {\n type: 'select', box: { x: 44, y: 172, w: 50, h: 78 },\n props: { label: 'Topic', placeholder: '', required: true, options: ['General question', 'Pricing', 'Support', 'Other'] },\n style: field,\n },\n { type: 'textarea', box: { x: 44, y: 264, w: 50, h: 110 }, props: { label: 'Message', placeholder: 'Optional', required: false }, style: field },\n { type: 'checkbox', box: { x: 44, y: 388, w: 50, h: 34 }, props: { label: 'I agree to be contacted about my request', required: true }, style: { color: 'muted', size: 14 } },\n {\n type: 'button', box: { x: 44, y: 434, w: 50, h: 54 },\n props: { label: 'Send', action: { type: 'submit', value: '' } },\n style: { background: 'primary', color: 'background', radius: 14, weight: 700, size: 17 },\n },\n ]),\n footer: () => build(280, color('secondary'), [\n { type: 'heading', box: { x: 6, y: 64, w: 26, h: 50 }, props: { text: 'Your brand', level: 3 }, style: { color: 'background', font: 'heading', size: 24, weight: 700 } },\n {\n type: 'text', box: { x: 6, y: 122, w: 26, h: 100 },\n props: { text: 'Street and number\\nCity, Country' },\n style: { color: 'background', size: 15, line_height: 1.7, opacity: 0.75 },\n },\n {\n type: 'text', box: { x: 38, y: 64, w: 26, h: 160 },\n props: { text: 'Hours\\nMonday to Friday, 9:00 to 18:00\\nSaturday, 9:00 to 13:00' },\n style: { color: 'background', size: 15, line_height: 1.8, opacity: 0.75 },\n },\n {\n type: 'button', box: { x: 70, y: 64, w: 24, h: 48 },\n props: { label: 'Contact us', action: { type: 'anchor', value: '' } },\n style: { background: 'primary', color: 'background', radius: 12, weight: 600 },\n },\n ]),\n\n heroCentered: () => build(620, color('background'), [\n {\n type: 'heading', box: { x: 18, y: 170, w: 64, h: 150 },\n props: { text: 'One line that says what you do', level: 1 },\n style: { color: 'secondary', font: 'heading', size: 52, weight: 700, align: 'center', line_height: 1.1 },\n },\n {\n type: 'text', box: { x: 26, y: 336, w: 48, h: 80 },\n props: { text: 'A second line for who it is for and what they get.' },\n style: { color: 'muted', size: 18, align: 'center', line_height: 1.6 },\n },\n {\n type: 'button', box: { x: 34, y: 440, w: 15, h: 54 },\n props: { label: 'Get started', action: { type: 'anchor', value: '' } },\n style: { background: 'primary', color: 'background', radius: 14, weight: 700, size: 16 },\n },\n {\n type: 'button', box: { x: 51, y: 440, w: 15, h: 54 },\n props: { label: 'See how it works', action: { type: 'anchor', value: '' } },\n style: { background: '', color: 'secondary', border_width: 1, border_color: 'muted', radius: 14, weight: 600, size: 16 },\n },\n ]),\n heroSlider: () => build(640, color('surface'), [\n {\n type: 'heading', box: { x: 6, y: 180, w: 38, h: 160 },\n props: { text: 'Show the work, not a promise', level: 1 },\n style: { color: 'secondary', font: 'heading', size: 46, weight: 700, line_height: 1.1 },\n },\n {\n type: 'text', box: { x: 6, y: 356, w: 32, h: 80 },\n props: { text: 'Pictures move by themselves, or the reader moves them.' },\n style: { color: 'muted', size: 17, line_height: 1.6 },\n },\n { type: 'slider', box: { x: 46, y: 120, w: 48, h: 400 }, props: { images: [], autoplay: true, interval: 5 }, style: { radius: 20, object_fit: 'cover' } },\n ]),\n logos: () => build(300, color('background'), [\n {\n type: 'text', box: { x: 6, y: 72, w: 88, h: 34 },\n props: { text: 'Teams that work with us' },\n style: { color: 'muted', size: 15, align: 'center' },\n },\n { type: 'gallery', box: { x: 6, y: 128, w: 88, h: 110 }, props: { images: [], layout: 'strip' }, style: { radius: 8 } },\n ]),\n testimonial: () => build(460, color('secondary'), [\n {\n type: 'heading', box: { x: 12, y: 130, w: 76, h: 170 },\n props: { text: '\"They shipped in three weeks what we had been postponing for a year.\"', level: 2 },\n style: { color: 'background', font: 'heading', size: 36, weight: 700, align: 'center', line_height: 1.3 },\n },\n {\n type: 'text', box: { x: 26, y: 326, w: 48, h: 60 },\n props: { text: 'Name Surname, role at Company' },\n style: { color: 'background', size: 15, align: 'center', opacity: 0.75 },\n },\n ]),\n stats: () => ({\n ...build(340, color('surface'), [\n { type: 'heading', box: { x: 6, y: 0, w: 100, h: 44 }, props: { text: 'Three numbers worth knowing', level: 2 }, style: { color: 'secondary', font: 'heading', size: 30, weight: 700 } },\n { type: 'heading', box: { x: 6, y: 80, w: 28, h: 80 }, props: { text: '600', level: 3 }, style: { color: 'primary', font: 'heading', size: 54, weight: 700 } },\n { type: 'heading', box: { x: 36, y: 80, w: 28, h: 80 }, props: { text: '23 %', level: 3 }, style: { color: 'primary', font: 'heading', size: 54, weight: 700 } },\n { type: 'heading', box: { x: 66, y: 80, w: 28, h: 80 }, props: { text: '0', level: 3 }, style: { color: 'primary', font: 'heading', size: 54, weight: 700 } },\n ]),\n flow: 'row' as const,\n flow_gap: 32,\n flow_align: 'between' as const,\n }),\n gallery: () => ({\n ...build(520, color('background'), [\n { type: 'heading', box: { x: 6, y: 0, w: 60, h: 46 }, props: { text: 'A look at the work', level: 2 }, style: { color: 'secondary', font: 'heading', size: 32, weight: 700 } },\n { type: 'gallery', box: { x: 6, y: 80, w: 88, h: 320 }, props: { images: [], layout: 'grid', columns: 3 }, style: { radius: 12 } },\n ]),\n flow: 'column' as const,\n flow_gap: 24,\n }),\n steps: () => build(440, color('background'), [\n { type: 'heading', box: { x: 6, y: 72, w: 60, h: 46 }, props: { text: 'How it works', level: 2 }, style: { color: 'secondary', font: 'heading', size: 32, weight: 700 } },\n ...step(6, '1', 'You write to us', 'Tell us what you need and when you need it.'),\n ...step(37, '2', 'We answer with a plan', 'A date, a price and what is included.'),\n ...step(68, '3', 'We start', 'You see progress every week, not at the end.'),\n ]),\n pricing: () => build(560, color('background'), [\n { type: 'heading', box: { x: 6, y: 72, w: 60, h: 46 }, props: { text: 'Plans', level: 2 }, style: { color: 'secondary', font: 'heading', size: 32, weight: 700 } },\n ...plan(8, 'Start', '$19', 'One site\\nOne editor\\nEmail support', false),\n ...plan(38, 'Studio', '$49', 'Five sites\\nFive editors\\nSupport in a day', true),\n ...plan(68, 'Agency', '$99', 'Sites without a limit\\nYour own domain\\nSupport in an hour', false),\n ]),\n team: () => build(500, color('surface'), [\n { type: 'heading', box: { x: 6, y: 72, w: 60, h: 46 }, props: { text: 'Who you will work with', level: 2 }, style: { color: 'secondary', font: 'heading', size: 32, weight: 700 } },\n ...person(6, 'Name Surname', 'What they do'),\n ...person(29, 'Name Surname', 'What they do'),\n ...person(52, 'Name Surname', 'What they do'),\n ...person(75, 'Name Surname', 'What they do'),\n ]),\n faq: () => build(620, color('background'), [\n { type: 'heading', box: { x: 6, y: 72, w: 60, h: 46 }, props: { text: 'Questions people ask', level: 2 }, style: { color: 'secondary', font: 'heading', size: 32, weight: 700 } },\n ...question(160, 'How long does it take?', 'Two to four weeks, counted from the day the content is ready.'),\n ...question(270, 'What do you need from me?', 'Texts, pictures and someone who can decide.'),\n ...question(380, 'Can I edit it later?', 'Yes. The site is yours and it is edited here, without us.'),\n ...question(490, 'What if I do not like it?', 'You see it before it is published, and we change it.'),\n ]),\n newsletter: () => build(360, color('primary'), [\n {\n type: 'heading', box: { x: 6, y: 110, w: 42, h: 90 },\n props: { text: 'News, once a month', level: 2 },\n style: { color: 'background', font: 'heading', size: 34, weight: 700, line_height: 1.2 },\n },\n {\n type: 'text', box: { x: 6, y: 208, w: 36, h: 60 },\n props: { text: 'What we made, what we learned. Nothing else.' },\n style: { color: 'background', size: 16, opacity: 0.85 },\n },\n {\n type: 'input', box: { x: 52, y: 140, w: 28, h: 78 },\n props: { label: 'Email', placeholder: 'you@example.com', required: true, input_type: 'email' },\n style: { color: 'background', background: '', border_width: 1, border_color: 'background', radius: 12, padding: 14 },\n },\n {\n type: 'button', box: { x: 82, y: 156, w: 12, h: 50 },\n props: { label: 'Sign up', action: { type: 'submit', value: '' } },\n style: { background: 'background', color: 'primary', radius: 12, weight: 700, size: 15 },\n },\n ]),\n footerBig: () => build(420, color('secondary'), [\n { type: 'heading', box: { x: 6, y: 72, w: 24, h: 46 }, props: { text: 'Your brand', level: 3 }, style: { color: 'background', font: 'heading', size: 26, weight: 700 } },\n {\n type: 'text', box: { x: 6, y: 128, w: 24, h: 90 },\n props: { text: 'One line about what you do and where you are.' },\n style: { color: 'background', size: 15, line_height: 1.6, opacity: 0.7 },\n },\n { type: 'text', box: { x: 38, y: 72, w: 18, h: 150 }, props: { text: 'Site\\nHome\\nWork\\nPrices\\nContact' }, style: { color: 'background', size: 15, line_height: 2, opacity: 0.8 } },\n { type: 'text', box: { x: 58, y: 72, w: 18, h: 150 }, props: { text: 'Company\\nAbout us\\nTeam\\nNews' }, style: { color: 'background', size: 15, line_height: 2, opacity: 0.8 } },\n { type: 'text', box: { x: 78, y: 72, w: 18, h: 150 }, props: { text: 'Write to us\\nhello@example.com\\n+00 000 000 0000' }, style: { color: 'background', size: 15, line_height: 2, opacity: 0.8 } },\n { type: 'divider', box: { x: 6, y: 300, w: 88, h: 2 }, props: {}, style: { color: 'background', opacity: 0.25 } },\n { type: 'text', box: { x: 6, y: 324, w: 50, h: 40 }, props: { text: 'All rights reserved' }, style: { color: 'background', size: 13, opacity: 0.6 } },\n ]),\n} satisfies Record<string, () => Section>;\n\nexport type SectionTemplateKey = keyof typeof sections;\n\nexport type TemplateGroup = 'open' | 'tell' | 'convince' | 'close';\n\nexport const SECTION_TEMPLATES: readonly { key: SectionTemplateKey; name: MessageKey; group: TemplateGroup }[] = [\n { key: 'hero', name: 'template.hero', group: 'open' },\n { key: 'heroCentered', name: 'template.heroCentered', group: 'open' },\n { key: 'heroSlider', name: 'template.heroSlider', group: 'open' },\n { key: 'features', name: 'template.features', group: 'tell' },\n { key: 'about', name: 'template.about', group: 'tell' },\n { key: 'steps', name: 'template.steps', group: 'tell' },\n { key: 'gallery', name: 'template.gallery', group: 'tell' },\n { key: 'faq', name: 'template.faq', group: 'tell' },\n { key: 'logos', name: 'template.logos', group: 'convince' },\n { key: 'testimonial', name: 'template.testimonial', group: 'convince' },\n { key: 'stats', name: 'template.stats', group: 'convince' },\n { key: 'team', name: 'template.team', group: 'convince' },\n { key: 'pricing', name: 'template.pricing', group: 'convince' },\n { key: 'cta', name: 'template.cta', group: 'close' },\n { key: 'newsletter', name: 'template.newsletter', group: 'close' },\n { key: 'contact', name: 'template.contact', group: 'close' },\n { key: 'footer', name: 'template.footer', group: 'close' },\n { key: 'footerBig', name: 'template.footerBig', group: 'close' },\n];\n\nexport const TEMPLATE_GROUPS: readonly { key: TemplateGroup; name: MessageKey }[] = [\n { key: 'open', name: 'template.group.open' },\n { key: 'tell', name: 'template.group.tell' },\n { key: 'convince', name: 'template.group.convince' },\n { key: 'close', name: 'template.group.close' },\n];\n\nconst pages = {\n full: ['hero', 'features', 'about', 'cta', 'footer'],\n simple: ['hero', 'features', 'contact', 'footer'],\n landing: ['hero', 'cta', 'contact', 'footer'],\n} as const satisfies Record<string, readonly SectionTemplateKey[]>;\n\nexport type PageTemplateKey = keyof typeof pages;\n\nexport const PAGE_TEMPLATES: readonly { key: PageTemplateKey; name: MessageKey; note: MessageKey }[] = [\n { key: 'full', name: 'pageTemplate.full', note: 'pageTemplate.full.note' },\n { key: 'simple', name: 'pageTemplate.simple', note: 'pageTemplate.simple.note' },\n { key: 'landing', name: 'pageTemplate.landing', note: 'pageTemplate.landing.note' },\n];\n\nexport const buildSectionTemplate = (key: SectionTemplateKey): Section => sections[key]();\n\nexport const buildPageTemplate = (key: PageTemplateKey): Section[] => pages[key].map((section) => sections[section]());\n","import type { Issue } from '@skylivellc/lienzo-core';\nimport { shallowRef, type ShallowRef } from 'vue';\nimport type { Failure } from '../client.ts';\n\n/** Where the draft stands against the server. Exactly one of these at a time. */\nexport type SaveState =\n | { kind: 'saved'; at: Date | null }\n | { kind: 'pending' }\n | { kind: 'saving' }\n /** The network is down; retries on its own. */\n | { kind: 'offline' }\n /** The server failed; retries on the next change or on demand. */\n | { kind: 'failed'; message: string }\n /** The server rejected some values; retries on the next change. */\n | { kind: 'invalid'; issues: Issue[]; message: string }\n /** Someone else saved first. Nothing is saved again until the page reloads. */\n | { kind: 'conflict' };\n\nexport type Outcome = { ok: true } | { ok: false; failure: Failure };\n\nexport type AutosaveOptions<T> = {\n /** A detached copy of everything autosaved, as plain data. */\n read(): T;\n /** Sends a copy taken by `read`. */\n save(value: T): Promise<Outcome>;\n delay?: number;\n offlineRetry?: number;\n};\n\nexport type Autosave = {\n readonly state: ShallowRef<SaveState>;\n /** Something may have changed: saves `delay` ms after the last call, if the snapshot differs from the saved one. */\n changed(): void;\n /** Saves now and waits. True when everything is saved. */\n flush(): Promise<boolean>;\n /** Flushes, then runs `task` while no autosave can start, so writes never interleave. */\n exclusive<T>(task: () => Promise<T>): Promise<T>;\n /** Starts over from what `read` gives now, known to be on the server (after a load or a reload). A save still in flight no longer counts. */\n reset(): void;\n dispose(): void;\n};\n\n/**\n * Debounced saving with one write in flight at a time. A change during a\n * save is saved right after it. A failure keeps the draft and says why;\n * offline retries every few seconds, a conflict stops for good.\n */\nexport function createAutosave<T>({ read, save, delay = 1500, offlineRetry = 5000 }: AutosaveOptions<T>): Autosave {\n const state = shallowRef<SaveState>({ kind: 'saved', at: null });\n const key = () => JSON.stringify(read());\n let saved = key();\n /** Bumped by `reset`, so the outcome of a save sent before it is ignored. */\n let generation = 0;\n let timer: ReturnType<typeof setTimeout> | undefined;\n let running: Promise<unknown> | null = null;\n\n const schedule = (wait: number) => {\n clearTimeout(timer);\n timer = setTimeout(() => void run(), wait);\n };\n\n async function run(): Promise<boolean> {\n clearTimeout(timer);\n\n while (running) {\n await running;\n }\n\n if (state.value.kind === 'conflict') {\n return false;\n }\n\n const value = read();\n const snapshot = JSON.stringify(value);\n\n if (snapshot === saved) {\n if (state.value.kind !== 'saved') {\n state.value = { kind: 'saved', at: new Date() };\n }\n\n return true;\n }\n\n state.value = { kind: 'saving' };\n const sentIn = generation;\n const attempt = save(value);\n running = attempt;\n const outcome = await attempt.finally(() => {\n running = null;\n });\n\n if (sentIn !== generation) {\n return false;\n }\n\n if (outcome.ok) {\n saved = snapshot;\n\n if (key() === saved) {\n state.value = { kind: 'saved', at: new Date() };\n\n return true;\n }\n\n state.value = { kind: 'pending' };\n schedule(delay);\n\n return false;\n }\n\n state.value = failed(outcome.failure);\n\n if (state.value.kind === 'offline') {\n schedule(offlineRetry);\n }\n\n return false;\n }\n\n const online = () => {\n if (state.value.kind === 'offline') {\n void run();\n }\n };\n\n if (typeof window !== 'undefined') {\n window.addEventListener('online', online);\n }\n\n return {\n state,\n changed() {\n if (state.value.kind === 'conflict' || state.value.kind === 'saving') {\n return;\n }\n\n if (key() === saved) {\n clearTimeout(timer);\n if (state.value.kind !== 'saved') {\n state.value = { kind: 'saved', at: new Date() };\n }\n\n return;\n }\n\n if (state.value.kind !== 'offline') {\n state.value = { kind: 'pending' };\n }\n schedule(delay);\n },\n flush: run,\n async exclusive(task) {\n await run();\n\n while (running) {\n await running;\n }\n\n const work = task();\n running = work;\n\n try {\n return await work;\n } finally {\n running = null;\n }\n },\n reset() {\n clearTimeout(timer);\n generation++;\n saved = key();\n state.value = { kind: 'saved', at: null };\n },\n dispose() {\n clearTimeout(timer);\n if (typeof window !== 'undefined') {\n window.removeEventListener('online', online);\n }\n },\n };\n}\n\nfunction failed(failure: Failure): SaveState {\n switch (failure.kind) {\n case 'offline':\n return { kind: 'offline' };\n case 'conflict':\n return { kind: 'conflict' };\n case 'invalid':\n return { kind: 'invalid', issues: failure.issues, message: failure.message };\n case 'http':\n return { kind: 'failed', message: failure.message };\n }\n}\n","import type { AppElement } from '@skylivellc/lienzo-core';\nimport { shallowRef, type ShallowRef } from 'vue';\nimport type { Client } from '../client.ts';\n\nexport type Preview = { status: 'loading' } | { status: 'ready'; html: string } | { status: 'failed' };\n\nexport type Previews = {\n /** The preview for this element's type and props, fetching it on a miss. */\n get(element: AppElement): Preview;\n /** Bumps whenever a preview arrives, so the canvas knows to render again. */\n readonly version: ShallowRef<number>;\n};\n\n/**\n * HTML of app elements, rendered by the backend. Cached by type and props:\n * moving, resizing or restyling an element never refetches, since box and\n * style live on the wrapper core renders around it. Misses are batched into\n * one `POST /preview` per `wait` ms.\n */\nexport function createPreviews(client: Client, wait = 250): Previews {\n const cache = new Map<string, Preview>();\n const queue = new Map<string, { id: string; type: string; props: Record<string, unknown> }>();\n const version = shallowRef(0);\n let timer: ReturnType<typeof setTimeout> | undefined;\n\n async function flush() {\n const batch = [...queue.entries()];\n queue.clear();\n\n const result = await client('POST /preview', { elements: batch.map(([, element]) => element) });\n\n for (const [key, element] of batch) {\n const html = result.ok ? result.value[element.id] : undefined;\n cache.set(key, html === undefined ? { status: 'failed' } : { status: 'ready', html });\n }\n\n version.value++;\n }\n\n return {\n version,\n get(element) {\n const key = previewKey(element);\n const cached = cache.get(key);\n\n if (cached) {\n return cached;\n }\n\n cache.set(key, { status: 'loading' });\n queue.set(key, { id: element.id, type: element.type, props: { ...element.props } });\n clearTimeout(timer);\n timer = setTimeout(() => void flush(), wait);\n\n return { status: 'loading' };\n },\n };\n}\n\n/** Type plus props with sorted keys, so equal props share one preview whatever their key order. */\nexport function previewKey(element: Pick<AppElement, 'type' | 'props'>): string {\n const props = Object.keys(element.props).sort().map((key) => [key, element.props[key]]);\n\n return JSON.stringify([element.type, props]);\n}\n","import {\n DocumentError,\n parseDocument,\n parseSiteSettings,\n type Catalog,\n type Document,\n type Element,\n type Issue,\n type Modal,\n type Parsed,\n type Section,\n type Seo,\n type SiteSettings,\n type Theme,\n} from '@skylivellc/lienzo-core';\nimport type { Asset, PageState, PageSummary, PageVersion, SiteUpdate, Workspace } from '@skylivellc/lienzo-core/protocol';\nimport { computed, inject, reactive, shallowRef, toRaw, watch, type InjectionKey, type WritableComputedRef } from 'vue';\nimport type { Client, Failure } from '../client.ts';\nimport type { Translator } from '../i18n/index.ts';\nimport {\n boxOf,\n canvasesOf,\n canvasHeight,\n copyElement,\n emptyModal,\n emptySection,\n findCanvas,\n isModal,\n MOBILE_WIDTH,\n newId,\n plain,\n stacksOnMobile,\n writeBox,\n type Canvas,\n type Device,\n} from '../model/document.ts';\nimport { createElement, kindOf, type Insertable } from '../model/elements.ts';\nimport {\n alignInCanvas,\n alignTogether,\n backLayer,\n clampBox,\n distribute,\n fitHeight,\n frontLayer,\n snap,\n stackForMobile,\n type Alignment,\n} from '../model/geometry.ts';\nimport { createHistory } from '../model/history.ts';\nimport { buildPageTemplate, type PageTemplateKey } from '../model/templates.ts';\nimport { createAutosave } from './autosave.ts';\nimport { createPreviews } from './previews.ts';\n\n/** What the canvas shows: the page's sections, or one modal's content. */\nexport type View = { kind: 'page' } | { kind: 'modal'; id: string };\n\n/**\n * What is selected. Elements always belong to one canvas; the active one is\n * the element the settings panel edits (the last one clicked).\n */\nexport type Selection =\n | { kind: 'none' }\n | { kind: 'canvas'; canvas: string }\n | { kind: 'elements'; canvas: string; ids: string[]; active: string };\n\nexport type Dialog = 'newPage' | 'versions' | 'theme' | 'site' | 'submissions' | 'conflict' | null;\n\nexport type Toast = { id: number; tone: 'info' | 'error'; text: string };\n\n/** The page being edited, minus its draft. */\nexport type OpenPage = { id: number; slug: string; title: string; publishedAt: string | null; seo: { title: string; description: string }; versions: PageVersion[] };\n\nexport type Load = { kind: 'loading' } | { kind: 'failed'; message: string } | { kind: 'empty' } | { kind: 'ready' };\n\nconst CLIPBOARD_KEY = 'lienzo-editor-clipboard';\n\nexport type EditorDeps = { client: Client; i18n: Translator };\n\nexport type Editor = ReturnType<typeof createEditor>;\n\nexport const editorKey: InjectionKey<Editor> = Symbol('lienzo-editor');\n\nexport function useEditor(): Editor {\n const editor = inject(editorKey);\n\n if (!editor) {\n throw new Error('useEditor() outside <LienzoEditor>');\n }\n\n return editor;\n}\n\nexport type EditorState = {\n load: Load;\n workspace: Workspace;\n page: OpenPage | null;\n draft: Document;\n revision: number;\n device: Device;\n view: View;\n selection: Selection;\n previewing: boolean;\n dialog: Dialog;\n /** The media library, open on top of anything else; picking calls `onPick`. */\n library: { onPick: ((ref: string) => void) | null } | null;\n /** Theme being edited in the theme dialog: the canvas shows it live until saved or cancelled. */\n themeDraft: Theme | null;\n /** Visible panel per tab or step group on the canvas. */\n panels: Record<string, number>;\n /** Canvas zoom, or null to fit the stage width. */\n zoom: number | null;\n /** Issues of a draft that does not parse, so the canvas shows the last good render. */\n renderIssues: Issue[];\n publishing: boolean;\n toasts: Toast[];\n};\n\n/**\n * All editor state and the operations on it. Panels and canvas gestures\n * edit the draft in place and call `commit` to record an undo step;\n * structural changes (adding, removing, moving things) go through these methods.\n */\nexport function createEditor({ client, i18n }: EditorDeps) {\n const t = i18n.t;\n const state = reactive<EditorState>({\n load: { kind: 'loading' },\n workspace: {\n site: parseSiteSettings({ name: 'Lienzo' }),\n meta: {},\n publicUrl: null,\n pages: [],\n catalog: { elements: [], actions: [] },\n assets: [],\n quota: { used: 0, limit: 0 },\n },\n page: null,\n draft: { sections: [] },\n revision: 0,\n device: 'desktop',\n view: { kind: 'page' },\n selection: { kind: 'none' },\n previewing: false,\n dialog: null,\n library: null,\n themeDraft: null,\n panels: {},\n zoom: null,\n renderIssues: [],\n publishing: false,\n toasts: [],\n });\n\n const history = createHistory('');\n const historyTick = shallowRef(0);\n const previews = createPreviews(client);\n\n /** Everything autosaved: the open page's title, SEO and draft. */\n const autosave = createAutosave({\n read: () => plain({ page: state.page?.id ?? null, title: state.page?.title ?? '', seo: state.page?.seo ?? { title: '', description: '' }, draft: state.draft }),\n async save(value) {\n if (value.page === null) {\n return { ok: true };\n }\n\n const result = await client('PUT /pages/:id', { id: value.page }, {\n baseRevision: state.revision,\n title: value.title,\n seo: blankToNull(value.seo),\n draft: value.draft,\n });\n\n // Another page may have opened meanwhile; its revision is not this one's.\n if (state.page?.id !== value.page) {\n return { ok: true };\n }\n\n if (result.ok) {\n state.revision = result.value.revision;\n\n return { ok: true };\n }\n\n if (result.failure.kind === 'conflict') {\n state.dialog = 'conflict';\n }\n\n return result;\n },\n });\n\n watch(() => [state.page?.title, state.page?.seo, state.draft], () => autosave.changed(), { deep: true });\n // The page list follows title edits of the open page.\n watch(() => state.page?.title, syncSummary);\n\n const catalog = computed<Catalog>(() => state.workspace.catalog);\n /**\n * Site settings as core renders them, with the theme being edited, if any.\n * A half-typed color does not parse; the last valid settings stay until it does.\n */\n const site = computed<Parsed<SiteSettings>>((previous) => {\n try {\n return parseSiteSettings({ ...state.workspace.site, theme: state.themeDraft ?? state.workspace.site.theme });\n } catch (error) {\n if (error instanceof DocumentError && previous) {\n return previous;\n }\n\n throw error;\n }\n });\n const theme = computed<Theme>(() => site.value.theme);\n\n /** Canvases on screen: the page's sections, or the open modal. */\n const canvases = computed<Canvas[]>(() => {\n if (state.view.kind === 'modal') {\n const modal = state.draft.modals?.find((candidate) => candidate.id === (state.view.kind === 'modal' ? state.view.id : ''));\n\n return modal ? [modal] : [];\n }\n\n return state.draft.sections;\n });\n\n const activeModal = computed<Modal | null>(() => {\n const view = state.view;\n\n return view.kind === 'modal' ? (state.draft.modals?.find((modal) => modal.id === view.id) ?? null) : null;\n });\n\n /** The canvas new elements go to: the selected one, else the first on screen. */\n const currentCanvas = computed<Canvas | null>(() => {\n const selection = state.selection;\n const selected = selection.kind === 'none' ? null : findCanvas(state.draft, selection.canvas);\n\n return selected ?? canvases.value[0] ?? null;\n });\n\n const selectedElements = computed<Element[]>(() => {\n const selection = state.selection;\n\n if (selection.kind !== 'elements') {\n return [];\n }\n\n return findCanvas(state.draft, selection.canvas)?.elements.filter((element) => selection.ids.includes(element.id)) ?? [];\n });\n\n const activeElement = computed<Element | null>(() => {\n const selection = state.selection;\n\n return selection.kind === 'elements' ? (selectedElements.value.find((element) => element.id === selection.active) ?? null) : null;\n });\n\n /** Design width of the frame on screen. */\n const frameWidth = computed(() => {\n const modal = activeModal.value;\n\n if (state.device === 'mobile') {\n return MOBILE_WIDTH;\n }\n\n return modal ? modal.width + (modal.size === 'full' ? 0 : 32) : theme.value.max_width;\n });\n\n let toastId = 0;\n\n function notify(text: string, tone: Toast['tone'] = 'info') {\n const toast = { id: ++toastId, tone, text };\n state.toasts.push(toast);\n setTimeout(() => dismiss(toast.id), tone === 'error' ? 8000 : 3500);\n }\n\n function dismiss(id: number) {\n state.toasts = state.toasts.filter((toast) => toast.id !== id);\n }\n\n const failureText = (failure: Failure): string => (failure.kind === 'offline' ? t('load.offline') : failure.message);\n\n async function load() {\n state.load = { kind: 'loading' };\n const result = await client('GET /');\n\n if (!result.ok) {\n state.load = { kind: 'failed', message: failureText(result.failure) };\n\n return;\n }\n\n try {\n parseSiteSettings(result.value.site);\n } catch (error) {\n if (error instanceof DocumentError) {\n state.load = { kind: 'failed', message: issueText(error.issues[0]) };\n\n return;\n }\n\n throw error;\n }\n\n state.workspace = result.value;\n const first = result.value.pages[0];\n\n if (!first) {\n state.load = { kind: 'empty' };\n state.dialog = 'newPage';\n\n return;\n }\n\n await openPage(first.id);\n }\n\n /** Loads a page into the editor, replacing the draft and its history. */\n async function loadPage(id: number): Promise<boolean> {\n const result = await client('GET /pages/:id', { id });\n\n if (!result.ok) {\n state.load = { kind: 'failed', message: failureText(result.failure) };\n\n return false;\n }\n\n return adoptPage(result.value);\n }\n\n function adoptPage(page: PageState): boolean {\n let draft: Document;\n\n try {\n draft = plain(parseDocument(page.draft, catalog.value));\n } catch (error) {\n if (error instanceof DocumentError) {\n state.load = { kind: 'failed', message: t('load.invalidDraft', { issue: issueText(error.issues[0]) }) };\n\n return false;\n }\n\n throw error;\n }\n\n state.page = {\n id: page.id,\n slug: page.slug,\n title: page.title,\n publishedAt: page.publishedAt,\n seo: { title: page.seo.title ?? '', description: page.seo.description ?? '' },\n versions: page.versions,\n };\n state.draft = draft;\n state.revision = page.revision;\n state.view = { kind: 'page' };\n state.selection = draft.sections[0] ? { kind: 'canvas', canvas: draft.sections[0].id } : { kind: 'none' };\n state.panels = {};\n state.load = { kind: 'ready' };\n history.reset(JSON.stringify(draft));\n historyTick.value++;\n autosave.reset();\n syncSummary();\n\n return true;\n }\n\n /** Keeps the page list in step with the open page's title, address and publish date. */\n function syncSummary() {\n const page = state.page;\n\n if (!page) {\n return;\n }\n\n state.workspace.pages = state.workspace.pages.map((summary): PageSummary =>\n summary.id === page.id ? { id: page.id, slug: page.slug, title: page.title, publishedAt: page.publishedAt } : summary);\n }\n\n /** Switching pages saves what is pending first; if that fails, the editor stays put. */\n async function openPage(id: number) {\n if (state.page?.id === id) {\n return;\n }\n\n if (state.page && !(await autosave.flush())) {\n notify(t('save.failed', { message: saveProblem() }), 'error');\n\n return;\n }\n\n await loadPage(id);\n }\n\n function saveProblem(): string {\n const current = autosave.state.value;\n\n switch (current.kind) {\n case 'offline':\n return t('load.offline');\n case 'failed':\n case 'invalid':\n return current.message;\n case 'conflict':\n return t('save.conflict');\n default:\n return '';\n }\n }\n\n async function reloadPage() {\n if (state.page) {\n state.dialog = null;\n await loadPage(state.page.id);\n }\n }\n\n /** Records the draft after a discrete edit, for undo. Saving follows the draft by itself. */\n function commit() {\n if (history.push(JSON.stringify(state.draft))) {\n historyTick.value++;\n }\n }\n\n function restoreFrom(json: string | null) {\n if (json === null) {\n return;\n }\n\n state.draft = JSON.parse(json) as Document;\n historyTick.value++;\n keepSelectionValid();\n }\n\n const canUndo = computed(() => historyTick.value >= 0 && history.canUndo);\n const canRedo = computed(() => historyTick.value >= 0 && history.canRedo);\n\n /** After undo or a restore, drops selected things that no longer exist. */\n function keepSelectionValid() {\n const selection = state.selection;\n\n if (selection.kind === 'none') {\n return;\n }\n\n const canvas = findCanvas(state.draft, selection.canvas);\n\n if (!canvas) {\n state.selection = { kind: 'none' };\n } else if (selection.kind === 'elements') {\n const ids = selection.ids.filter((id) => canvas.elements.some((element) => element.id === id));\n state.selection = ids.length === 0\n ? { kind: 'canvas', canvas: canvas.id }\n : { kind: 'elements', canvas: canvas.id, ids, active: ids.includes(selection.active) ? selection.active : ids[0]! };\n }\n\n if (state.view.kind === 'modal' && !activeModal.value) {\n state.view = { kind: 'page' };\n }\n }\n\n function selectCanvas(canvasId: string) {\n state.selection = { kind: 'canvas', canvas: canvasId };\n revealSection(canvasId);\n }\n\n /** Selects an element (and its group). With `additive`, toggles it in the current selection. */\n function select(canvasId: string, elementId: string, additive = false) {\n const canvas = findCanvas(state.draft, canvasId);\n const clicked = canvas?.elements.find((element) => element.id === elementId);\n\n if (!canvas || !clicked) {\n return;\n }\n\n const family = clicked.group ? canvas.elements.filter((element) => element.group === clicked.group).map((element) => element.id) : [elementId];\n const current = state.selection.kind === 'elements' && state.selection.canvas === canvasId ? state.selection.ids : [];\n const ids = !additive\n ? family\n : current.includes(elementId)\n ? current.filter((id) => !family.includes(id))\n : [...new Set([...current, ...family])];\n\n state.selection = ids.length === 0\n ? { kind: 'canvas', canvas: canvasId }\n : { kind: 'elements', canvas: canvasId, ids, active: ids.includes(elementId) ? elementId : ids[0]! };\n revealSection(canvasId);\n }\n\n function clearSelection() {\n const selection = state.selection;\n state.selection = selection.kind === 'elements' ? { kind: 'canvas', canvas: selection.canvas } : selection;\n }\n\n /** A section inside a tab or step group shows its panel when selected. */\n function revealSection(canvasId: string) {\n const sections = state.draft.sections;\n const index = sections.findIndex((section) => section.id === canvasId);\n const groupId = sections[index]?.group?.id;\n\n if (index < 0 || !groupId) {\n return;\n }\n\n let start = index;\n\n while (start > 0 && sections[start - 1]?.group?.id === groupId) {\n start--;\n }\n\n state.panels = { ...state.panels, [groupId]: index - start };\n }\n\n /** Adds an element to the current canvas, or at a drop point in a given canvas. */\n function addElement(insertable: Insertable, at?: { canvas: string; x: number; y: number }, src?: string) {\n const target = at ? findCanvas(state.draft, at.canvas) : currentCanvas.value;\n\n if (!target) {\n return;\n }\n\n const element = createElement(insertable, at ? at.y : target.elements.length * 24 + 40, t);\n\n if (src) {\n element.props = { ...element.props, src };\n }\n\n if (at) {\n element.layout.desktop = { ...element.layout.desktop, x: Math.round(at.x * 2) / 2, y: snap(at.y) };\n }\n\n element.z = target.elements.length + 1;\n target.elements.push(element);\n state.selection = { kind: 'elements', canvas: target.id, ids: [element.id], active: element.id };\n commit();\n }\n\n function removeSelected() {\n const selection = state.selection;\n\n if (selection.kind !== 'elements') {\n return;\n }\n\n const canvas = findCanvas(state.draft, selection.canvas);\n\n if (canvas) {\n canvas.elements = canvas.elements.filter((element) => !selection.ids.includes(element.id) || element.locked === true);\n state.selection = { kind: 'canvas', canvas: canvas.id };\n commit();\n }\n }\n\n function duplicateSelected() {\n const selection = state.selection;\n const canvas = selection.kind === 'elements' ? findCanvas(state.draft, selection.canvas) : undefined;\n\n if (!canvas || selectedElements.value.length === 0) {\n return;\n }\n\n pasteInto(canvas, selectedElements.value);\n }\n\n /** Copies get new ids, their own groups and the top layers, so they never tie back to the originals. */\n function pasteInto(canvas: Canvas, elements: readonly Element[]) {\n const groups = new Map<string, string>();\n const top = Math.max(0, ...canvas.elements.map((element) => element.z));\n const copies = elements.map((element, index) => {\n const copy = copyElement(element);\n const group = copy.group ? (groups.get(copy.group) ?? groups.set(copy.group, newId('group')).get(copy.group)) : null;\n\n return { ...copy, group, z: Math.min(999, top + index + 1) };\n });\n canvas.elements.push(...copies);\n state.selection = { kind: 'elements', canvas: canvas.id, ids: copies.map((copy) => copy.id), active: copies[0]!.id };\n commit();\n }\n\n /** The clipboard lives in the browser, so it works across sections and pages. */\n function copySelected() {\n const elements = selectedElements.value;\n\n if (elements.length === 0) {\n return;\n }\n\n try {\n window.localStorage.setItem(CLIPBOARD_KEY, JSON.stringify(elements));\n notify(elements.length === 1 ? t('toast.copied') : t('toast.copiedMany', { n: elements.length }));\n } catch {\n notify(t('toast.copyFailed'), 'error');\n }\n }\n\n function paste() {\n const target = currentCanvas.value;\n let elements: Element[] = [];\n\n try {\n const stored: unknown = JSON.parse(window.localStorage.getItem(CLIPBOARD_KEY) ?? '[]');\n elements = Array.isArray(stored) ? stored.filter((candidate) => parsesAsElement(candidate, catalog.value)) : [];\n } catch {\n elements = [];\n }\n\n if (!target || elements.length === 0) {\n return;\n }\n\n pasteInto(target, elements);\n notify(t('toast.pasted'));\n }\n\n /** Everything selected moves, keeping the order it had between them. */\n function layer(step: 'front' | 'back') {\n const elements = selectedElements.value;\n const canvas = currentCanvas.value;\n\n if (elements.length === 0 || !canvas) {\n return;\n }\n\n const moving = new Set(elements.map((element) => element.id));\n const others = canvas.elements.filter((element) => !moving.has(element.id)).map((element) => element.z);\n const ordered = [...elements].sort((a, b) => a.z - b.z);\n\n ordered.forEach((element, index) => {\n element.z = step === 'front' ? frontLayer(others) + index : backLayer(others) - (ordered.length - 1 - index);\n });\n\n commit();\n }\n\n /** One element aligns inside its canvas; several align against their joint box. */\n function align(where: Alignment) {\n const elements = selectedElements.value;\n const canvas = currentCanvas.value;\n\n if (elements.length === 0 || !canvas) {\n return;\n }\n\n if (elements.length === 1) {\n writeBox(elements[0]!, state.device, alignInCanvas(boxOf(elements[0]!, state.device), where, canvasHeight(canvas, state.device)));\n } else {\n alignTogether(elements.map((element) => boxOf(element, state.device)), where)\n .forEach((box, index) => writeBox(elements[index]!, state.device, box));\n }\n\n commit();\n }\n\n function distributeSelected(axis: 'x' | 'y') {\n const elements = selectedElements.value;\n\n distribute(elements.map((element) => boxOf(element, state.device)), axis)\n .forEach((box, index) => writeBox(elements[index]!, state.device, box));\n commit();\n }\n\n /**\n * The active element, with its style and props writing to every selected\n * element. A panel bound to it edits one or many without knowing which.\n */\n function sharedTarget(): Element | null {\n const elements = selectedElements.value;\n const first = activeElement.value ?? elements[0] ?? null;\n\n if (!first || elements.length < 2) {\n return first;\n }\n\n const fanOut = <T extends object>(key: 'style' | 'props') => new Proxy(first[key] as T, {\n set(_target, property, value) {\n elements.forEach((element) => Reflect.set(element[key] as object, property, value));\n\n return true;\n },\n deleteProperty(_target, property) {\n elements.forEach((element) => Reflect.deleteProperty(element[key] as object, property));\n\n return true;\n },\n });\n\n const style = fanOut('style');\n const props = fanOut('props');\n\n return new Proxy(first, {\n get: (target, property) => (property === 'style' ? style : property === 'props' ? props : Reflect.get(target, property)),\n set(_target, property, value) {\n elements.forEach((element) => Reflect.set(element, property, value));\n\n return true;\n },\n });\n }\n\n function groupSelected() {\n const id = newId('group');\n selectedElements.value.forEach((element) => (element.group = id));\n commit();\n }\n\n function ungroupSelected() {\n selectedElements.value.forEach((element) => (element.group = null));\n commit();\n }\n\n function toggleLock() {\n const elements = selectedElements.value;\n const locking = elements.some((element) => !element.locked);\n elements.forEach((element) => (element.locked = locking));\n commit();\n }\n\n /** Arrow keys: 1 design pixel down or up, 0.5% across; callers pass ten steps with Shift. Like dragging, not where phones stack. */\n function nudge(dx: number, dy: number) {\n const canvas = currentCanvas.value;\n\n if (!canvas || (state.device === 'mobile' && stacksOnMobile(canvas))) {\n return;\n }\n\n const elements = selectedElements.value.filter((element) => !element.locked);\n\n for (const element of elements) {\n const box = boxOf(element, state.device);\n writeBox(element, state.device, clampBox({ ...box, x: box.x + dx * 0.5, y: box.y + dy }));\n }\n\n if (elements.length > 0) {\n commit();\n }\n }\n\n /** Writes boxes a canvas gesture produced, then records one undo step. */\n function placeElements(boxes: readonly { id: string; box: Element['layout']['desktop'] }[]) {\n const canvas = currentCanvas.value;\n\n for (const { id, box } of boxes) {\n const element = canvas?.elements.find((candidate) => candidate.id === id);\n\n if (element) {\n writeBox(element, state.device, box);\n }\n }\n\n commit();\n }\n\n /** `after` inserta la nueva sección justo debajo de esa; sin él, al final. */\n function addSection(section: Section = emptySection(), after?: string) {\n const at = after === undefined ? -1 : state.draft.sections.findIndex((item) => item.id === after);\n\n if (at === -1) {\n state.draft.sections.push(section);\n } else {\n state.draft.sections.splice(at + 1, 0, section);\n }\n\n state.view = { kind: 'page' };\n state.selection = { kind: 'canvas', canvas: section.id };\n commit();\n }\n\n /** Starts the page from a full template, replacing its sections. */\n function applyPageTemplate(key: PageTemplateKey) {\n const sections = buildPageTemplate(key);\n state.draft.sections = sections;\n state.selection = { kind: 'canvas', canvas: sections[0]!.id };\n commit();\n }\n\n /** A copy of the section right below it, with fresh ids so nothing collides. */\n function duplicateSection(id: string) {\n const section = state.draft.sections.find((item) => item.id === id);\n\n if (!section) {\n return;\n }\n\n const copy: Section = {\n ...structuredClone(toRaw(section)),\n id: newId('section'),\n elements: structuredClone(toRaw(section.elements)).map((element) => ({ ...element, id: newId(element.type) })),\n };\n\n addSection(copy, id);\n }\n\n function removeSection(id: string) {\n if (state.draft.sections.length <= 1) {\n return;\n }\n\n state.draft.sections = state.draft.sections.filter((section) => section.id !== id);\n state.selection = { kind: 'canvas', canvas: state.draft.sections[0]!.id };\n commit();\n }\n\n function moveSection(index: number, step: -1 | 1) {\n const sections = state.draft.sections;\n const target = index + step;\n const [moving, other] = [sections[index], sections[target]];\n\n if (!moving || !other) {\n return;\n }\n\n sections.splice(index, 1, other);\n sections.splice(target, 1, moving);\n commit();\n }\n\n /**\n * Chains a section to the one before it as a tab or a step. When the one\n * before is not grouped yet, the group starts with both. A group has one\n * type, so choosing tabs or steps sets it for the whole group. An empty\n * label renders as \"Tab n\" or \"Step n\" by position.\n */\n function setSectionGroup(section: Section, mode: 'alone' | 'tabs' | 'steps') {\n const sections = state.draft.sections;\n const index = sections.indexOf(section);\n\n if (mode === 'alone') {\n section.group = null;\n commit();\n\n return;\n }\n\n const previous = sections[index - 1];\n const id = previous?.group?.id || newId('group');\n\n if (previous && !previous.group?.id) {\n previous.group = { id, type: mode, label: '' };\n }\n\n section.group = { id, type: mode, label: section.group?.id === id ? (section.group.label ?? '') : '' };\n sections.filter((candidate) => candidate.group?.id === id).forEach((member) => {\n member.group = { ...member.group, id, type: mode };\n });\n commit();\n }\n\n function fitCanvas(canvas: Canvas) {\n canvas.height.desktop = Math.min(isModal(canvas) ? 2000 : 3000, fitHeight(canvas.elements.map((element) => element.layout.desktop)));\n commit();\n }\n\n /** Gives every element of the canvas its own phone box, stacked in reading order. */\n function generateMobile(canvas: Canvas) {\n const reference = isModal(canvas) ? canvas.width : theme.value.max_width;\n const { boxes, height } = stackForMobile(\n canvas.elements.map((element) => ({ desktop: element.layout.desktop, text: element.type === 'text' })),\n reference,\n MOBILE_WIDTH,\n );\n\n canvas.elements.forEach((element, index) => (element.layout.mobile = boxes[index] ?? null));\n canvas.height.mobile = Math.min(isModal(canvas) ? 2400 : 4000, height);\n commit();\n notify(t('toast.mobileGenerated'));\n }\n\n function addModal() {\n const modal = emptyModal(t('modals.defaultTitle'));\n state.draft.modals = [...(state.draft.modals ?? []), modal];\n commit();\n openModal(modal.id);\n }\n\n function openModal(id: string | null) {\n state.view = id ? { kind: 'modal', id } : { kind: 'page' };\n state.selection = id ? { kind: 'canvas', canvas: id } : state.draft.sections[0] ? { kind: 'canvas', canvas: state.draft.sections[0].id } : { kind: 'none' };\n }\n\n function removeModal(id: string) {\n state.draft.modals = (state.draft.modals ?? []).filter((modal) => modal.id !== id);\n\n if (state.view.kind === 'modal' && state.view.id === id) {\n openModal(null);\n }\n\n commit();\n }\n\n const undo = () => restoreFrom(history.undo());\n const redo = () => restoreFrom(history.redo());\n\n /** Saves now; the toolbar shows how it went. */\n async function saveNow() {\n await autosave.flush();\n }\n\n async function publish() {\n const page = state.page;\n\n if (!page || state.publishing) {\n return;\n }\n\n state.publishing = true;\n\n try {\n if (!(await autosave.flush())) {\n notify(t('publish.failed', { message: saveProblem() }), 'error');\n\n return;\n }\n\n const result = await autosave.exclusive(async () => {\n const response = await client('POST /pages/:id/publish', { id: page.id }, { revision: state.revision });\n\n if (response.ok) {\n page.publishedAt = response.value.publishedAt;\n page.versions = response.value.versions;\n }\n\n return response;\n });\n\n if (!result.ok) {\n if (result.failure.kind === 'conflict') {\n state.dialog = 'conflict';\n } else {\n notify(t('publish.failed', { message: failureText(result.failure) }), 'error');\n }\n\n return;\n }\n\n syncSummary();\n notify(t('publish.done'));\n } finally {\n state.publishing = false;\n }\n }\n\n /** Brings a published version back into the draft. Undo returns to what was there. */\n async function restoreVersion(version: number) {\n const page = state.page;\n\n if (!page) {\n return;\n }\n\n // The new draft and revision land before any autosave can run again.\n const problem = await autosave.exclusive(async (): Promise<string | null> => {\n const result = await client('POST /pages/:id/versions/:version/restore', { id: page.id, version });\n\n if (!result.ok) {\n return failureText(result.failure);\n }\n\n try {\n state.draft = plain(parseDocument(result.value.draft, catalog.value));\n } catch (error) {\n if (error instanceof DocumentError) {\n return issueText(error.issues[0]);\n }\n\n throw error;\n }\n\n state.revision = result.value.revision;\n page.versions = result.value.versions;\n autosave.reset();\n\n return null;\n });\n\n if (problem !== null) {\n notify(t('toast.failed', { message: problem }), 'error');\n\n return;\n }\n\n commit();\n keepSelectionValid();\n state.dialog = null;\n notify(t('versions.restored'));\n }\n\n async function createPage(title: string, slug: string): Promise<Issue[]> {\n if (state.page && !(await autosave.flush())) {\n return [{ path: 'title', code: 'type', message: saveProblem() }];\n }\n\n const result = await client('POST /pages', { title, slug });\n\n if (!result.ok) {\n return result.failure.kind === 'invalid' ? result.failure.issues : [{ path: 'title', code: 'type', message: failureText(result.failure) }];\n }\n\n state.workspace.pages = [...state.workspace.pages, { id: result.value.id, slug: result.value.slug, title: result.value.title, publishedAt: result.value.publishedAt }];\n adoptPage(result.value);\n state.dialog = null;\n notify(t('toast.pageCreated'));\n\n return [];\n }\n\n /** Saves a new address for the open page. Returns the problems, if any. */\n async function renamePage(slug: string): Promise<Issue[]> {\n const page = state.page;\n\n if (!page) {\n return [];\n }\n\n const result = await autosave.exclusive(async () => {\n const response = await client('PUT /pages/:id', { id: page.id }, { baseRevision: state.revision, title: page.title, slug });\n\n if (response.ok) {\n state.revision = response.value.revision;\n page.slug = slug;\n }\n\n return response;\n });\n\n if (!result.ok) {\n if (result.failure.kind === 'conflict') {\n state.dialog = 'conflict';\n }\n\n return result.failure.kind === 'invalid' ? result.failure.issues : [{ path: 'slug', code: 'type', message: failureText(result.failure) }];\n }\n\n syncSummary();\n notify(t('page.addressSaved'));\n\n return [];\n }\n\n async function deletePage() {\n const page = state.page;\n\n if (!page) {\n return;\n }\n\n const result = await autosave.exclusive(async () => {\n const response = await client('DELETE /pages/:id', { id: page.id });\n\n if (response.ok) {\n state.page = null;\n }\n\n return response;\n });\n\n if (!result.ok) {\n notify(t('toast.failed', { message: failureText(result.failure) }), 'error');\n\n return;\n }\n\n state.workspace.pages = state.workspace.pages.filter((summary) => summary.id !== page.id);\n notify(t('page.deleted'));\n const next = state.workspace.pages[0];\n\n if (next) {\n await loadPage(next.id);\n } else {\n state.load = { kind: 'empty' };\n }\n }\n\n /** Saves site settings. Returns the problems, if any. */\n async function updateSite(update: SiteUpdate): Promise<Issue[]> {\n const result = await client('PUT /site', update);\n\n if (!result.ok) {\n return result.failure.kind === 'invalid' ? result.failure.issues : [{ path: '', code: 'type', message: failureText(result.failure) }];\n }\n\n state.workspace = { ...result.value, pages: state.workspace.pages };\n\n return [];\n }\n\n async function uploadAsset(file: File): Promise<Asset | null> {\n const body = new FormData();\n body.append('file', file);\n const result = await client('POST /assets', body);\n\n if (!result.ok) {\n notify(t('library.uploadFailed', { message: failureText(result.failure) }), 'error');\n\n return null;\n }\n\n state.workspace.assets = [result.value, ...state.workspace.assets];\n void refreshQuota();\n\n return result.value;\n }\n\n async function deleteAsset(asset: Asset) {\n const result = await client('DELETE /assets/:id', { id: asset.id });\n\n if (!result.ok) {\n notify(t('library.deleteFailed', { message: failureText(result.failure) }), 'error');\n\n return;\n }\n\n state.workspace.assets = state.workspace.assets.filter((candidate) => candidate.id !== asset.id);\n void refreshQuota();\n }\n\n /** The backend measures the quota (bytes, files, whatever it counts), so ask it again. */\n async function refreshQuota() {\n const result = await client('GET /');\n\n if (result.ok) {\n state.workspace.quota = result.value.quota;\n }\n }\n\n /** `v-model:open` for a dialog: open while `state.dialog` names it; closing clears it. */\n function dialogModel(name: Exclude<Dialog, null>): WritableComputedRef<boolean> {\n return computed({\n get: () => state.dialog === name,\n set: (open) => {\n if (open) {\n state.dialog = name;\n } else if (state.dialog === name) {\n state.dialog = null;\n }\n },\n });\n }\n\n function openLibrary(onPick: ((ref: string) => void) | null = null) {\n state.library = { onPick };\n }\n\n return {\n state,\n i18n,\n t,\n client,\n previews,\n saveState: autosave.state,\n catalog,\n site,\n theme,\n canvases,\n activeModal,\n currentCanvas,\n selectedElements,\n activeElement,\n frameWidth,\n canUndo,\n canRedo,\n kindOf: (element: Element) => kindOf(element, catalog.value),\n notify,\n failureText,\n dismiss,\n load,\n openPage,\n reloadPage,\n commit,\n undo,\n redo,\n select,\n selectCanvas,\n clearSelection,\n addElement,\n removeSelected,\n duplicateSelected,\n copySelected,\n paste,\n layer,\n align,\n distributeSelected,\n sharedTarget,\n groupSelected,\n ungroupSelected,\n toggleLock,\n nudge,\n placeElements,\n addSection,\n duplicateSection,\n applyPageTemplate,\n removeSection,\n moveSection,\n setSectionGroup,\n fitCanvas,\n generateMobile,\n addModal,\n openModal,\n removeModal,\n saveNow,\n publish,\n restoreVersion,\n createPage,\n renamePage,\n deletePage,\n updateSite,\n uploadAsset,\n deleteAsset,\n openLibrary,\n dialogModel,\n dispose: () => autosave.dispose(),\n };\n}\n\nexport const issueText = (issue: Issue | undefined): string => (issue ? `${issue.path}: ${issue.message}` : '');\n\nconst blankToNull = (seo: { title: string; description: string }): Seo => ({\n title: seo.title.trim() === '' ? null : seo.title,\n description: seo.description.trim() === '' ? null : seo.description,\n});\n\n/**\n * Pasted data comes from local storage, which anything could have written,\n * possibly another site with other app elements: only what this catalog parses goes in.\n */\nfunction parsesAsElement(value: unknown, catalog: Catalog): value is Element {\n try {\n parseDocument({ sections: [{ ...emptySection(), elements: [value] }] }, catalog);\n\n return true;\n } catch (error) {\n if (error instanceof DocumentError) {\n return false;\n }\n\n throw error;\n }\n}\n\n","import type { Editor } from './editor.ts';\n\nconst TYPING = new Set(['INPUT', 'TEXTAREA', 'SELECT']);\n\n/** Whether a key event belongs to a text control, where keys mean typing. */\nfunction typing(event: KeyboardEvent): boolean {\n const target = event.composedPath()[0];\n\n if (!target || typeof (target as Partial<HTMLElement>).tagName !== 'string') {\n return false;\n }\n\n const element = target as HTMLElement;\n\n return TYPING.has(element.tagName) || element.isContentEditable;\n}\n\n/**\n * Editor shortcuts: Escape, Delete, arrows, and Ctrl/Cmd with C, V, D, Z,\n * Shift+Z and S. Keys typed into a field are left alone. The canvas iframe and the host\n * page both send their key events here.\n */\nexport function handleShortcut(editor: Editor, event: KeyboardEvent): void {\n if (typing(event) || editor.state.dialog !== null || editor.state.library !== null || editor.state.previewing) {\n return;\n }\n\n const selected = editor.state.selection.kind === 'elements';\n const command = event.metaKey || event.ctrlKey;\n const key = event.key.toLowerCase();\n\n if (!command) {\n switch (event.key) {\n case 'Escape':\n editor.clearSelection();\n\n return;\n case 'Delete':\n case 'Backspace':\n if (!selected) {\n return;\n }\n\n event.preventDefault();\n editor.removeSelected();\n\n return;\n case 'ArrowLeft':\n case 'ArrowRight':\n case 'ArrowUp':\n case 'ArrowDown': {\n if (!selected) {\n return;\n }\n\n const step = event.shiftKey ? 10 : 1;\n event.preventDefault();\n editor.nudge(\n event.key === 'ArrowLeft' ? -step : event.key === 'ArrowRight' ? step : 0,\n event.key === 'ArrowUp' ? -step : event.key === 'ArrowDown' ? step : 0,\n );\n\n return;\n }\n default:\n return;\n }\n }\n\n switch (key) {\n case 'c':\n editor.copySelected();\n\n return;\n case 'v':\n editor.paste();\n\n return;\n case 'd':\n event.preventDefault();\n editor.duplicateSelected();\n\n return;\n case 'z':\n event.preventDefault();\n if (event.shiftKey) {\n editor.redo();\n } else {\n editor.undo();\n }\n\n return;\n case 'y':\n event.preventDefault();\n editor.redo();\n\n return;\n case 's':\n event.preventDefault();\n void editor.saveNow();\n\n return;\n default:\n return;\n }\n}\n","/**\n * Editor-only rules layered over `lienzo.css` inside the canvas iframe. They\n * change behavior, never looks: links and embeds go inert, sticky navbars\n * and parallax images stay in place, and empty media show what to do.\n */\nexport const frameCss = `\nhtml,body{margin:0}\nbody{overflow:hidden}\n.lz-el{cursor:default;user-select:none;-webkit-user-select:none}\n.lz-el[contenteditable]{cursor:text;user-select:text;-webkit-user-select:text;outline:none}\n.lz-el iframe,.lz-el input,.lz-el select,.lz-el textarea,.lz-el summary,.lz-el a,.lz-el button{pointer-events:none}\n.lz-navbar[data-sticky]{position:absolute;translate:none;left:calc(var(--x) * 1%);top:calc(var(--y) * var(--u));width:calc(var(--w) * 1%)}\n@container lz (max-width:640px){\n.lz-frame:not([data-stack]) .lz-navbar[data-sticky]{left:calc(var(--mx) * 1%);top:calc(var(--my) * var(--u));width:calc(var(--mw) * 1%)}\n.lz-frame[data-stack] .lz-navbar[data-sticky]{position:static;width:auto}\n}\n.lz-parallax>.lz-bg{position:absolute}\n.lz-stack-nav button{cursor:pointer}\nimg.lz-el[src=\"\"]::before,.lz-video:empty::before{position:absolute;inset:0;display:grid;place-items:center;padding:8px;text-align:center;border:1px dashed #94a3b8;border-radius:inherit;background:#f8fafc;color:#64748b;font:12px/1.3 system-ui,sans-serif}\nimg.lz-el[src=\"\"]::before{content:var(--lze-empty-image)}\n.lz-frame[data-stack] img.lz-el[src=\"\"]{position:relative;min-height:120px}\n.lz-video:empty::before{content:var(--lze-empty-video)}\n.lze-app-placeholder{display:grid;place-items:center;height:100%;padding:8px;text-align:center;border:1px dashed #94a3b8;border-radius:inherit;background:#f8fafc;color:#64748b;font:12px/1.3 system-ui,sans-serif}\n.lze-app-placeholder[data-status=loading]{animation:lze-pulse 1.2s ease-in-out infinite}\n@keyframes lze-pulse{50%{opacity:.55}}\nbody[data-lze-modal] .lz-section,body[data-lze-modal] .lz-stack,body[data-lze-modal] .lz-notice{display:none}\nbody[data-lze-modal] dialog.lz-modal[data-lze-open]{display:block;position:static;margin:16px auto;max-height:none;overflow:visible;box-shadow:0 12px 40px rgba(15,23,42,.18)}\nbody[data-lze-modal] dialog.lz-modal[data-lze-open][data-size=full]{margin:0}\n`;\n","import {\n DocumentError,\n parseDocument,\n renderPage,\n trustedHtml,\n type AppElement,\n type Catalog,\n type Document,\n type Issue,\n type Parsed,\n type RenderedPage,\n type SiteSettings,\n} from '@skylivellc/lienzo-core';\nimport type { Asset } from '@skylivellc/lienzo-core/protocol';\nimport type { Editor } from '../state/editor.ts';\nimport type { Preview } from '../state/previews.ts';\n\nexport type RenderContext = {\n catalog: Catalog;\n site: Parsed<SiteSettings>;\n assets: readonly Asset[];\n slug: string;\n publicUrl: string | null;\n preview(element: AppElement): Preview;\n /** Placeholder texts for app elements whose preview is not there yet. */\n labels: { loading: string; failed: string };\n};\n\n/** What rendering needs from the editor: the canvas and the preview read the same. */\nexport function renderContext(editor: Editor): RenderContext {\n return {\n catalog: editor.catalog.value,\n site: editor.site.value,\n assets: editor.state.workspace.assets,\n slug: editor.state.page?.slug ?? '',\n publicUrl: editor.state.workspace.publicUrl,\n preview: (element) => editor.previews.get(element),\n labels: { loading: editor.t('canvas.loadingPreview'), failed: editor.t('canvas.previewFailed') },\n };\n}\n\nexport type Rendered = { ok: true; page: RenderedPage } | { ok: false; issues: Issue[] };\n\n/**\n * The page through core, exactly as the public page renders it: `edit` for\n * the canvas (no runtime, no entrance animations, placeholders for missing\n * plugins), `public` for the preview. App elements show the HTML the backend\n * rendered for the same props, or a placeholder while it loads. A draft that\n * does not parse reports its issues instead of rendering.\n */\nexport async function renderDraft(draft: Document, context: RenderContext, mode: 'edit' | 'public'): Promise<Rendered> {\n let document: Parsed<Document>;\n\n try {\n document = parseDocument(draft, context.catalog);\n } catch (error) {\n if (error instanceof DocumentError) {\n return { ok: false, issues: error.issues };\n }\n\n throw error;\n }\n\n const page = await renderPage({\n document,\n catalog: context.catalog,\n site: context.site,\n page: { slug: context.slug, seo: {}, url: new URL(context.slug, context.publicUrl ?? 'https://example.invalid/').href },\n base: '',\n mode,\n host: {\n media: (ref) => {\n const asset = context.assets.find((candidate) => candidate.ref === ref);\n\n return asset ? { url: asset.url, thumb: asset.thumb, width: asset.width, height: asset.height } : null;\n },\n // App actions resolve on the backend; in the editor their links go nowhere.\n action: () => '#',\n appElement: (element) => {\n const preview = context.preview(element);\n\n return preview.status === 'ready'\n ? trustedHtml(preview.html)\n : trustedHtml(`<div class=\"lze-app-placeholder\" data-status=\"${preview.status}\">${escapeHtml(preview.status === 'loading' ? context.labels.loading : context.labels.failed)}</div>`);\n },\n form: null,\n },\n });\n\n return { ok: true, page };\n}\n\nconst ESCAPES: Readonly<Record<string, string>> = { '&': '&amp;', '<': '&lt;', '>': '&gt;', '\"': '&quot;', \"'\": '&#039;' };\n\nexport const escapeHtml = (value: string): string => value.replace(/[&<>\"']/g, (char) => ESCAPES[char] ?? char);\n\n/** Core's rule for ids in HTML and CSS, so the canvas finds what it rendered. */\nexport const domId = (id: string): string => id.replace(/[^A-Za-z0-9_-]/g, '') || 'x';\n","import lienzoCss from '@skylivellc/lienzo-core/lienzo.css?raw';\nimport type { Box, Document as Draft } from '@skylivellc/lienzo-core';\nimport { canvasesOf, type Device } from '../model/document.ts';\nimport { frameCss } from './frameCss.ts';\nimport { domId } from './render.ts';\n\n/** A rectangle in the iframe document, in CSS pixels of the design frame. */\nexport type Rect = { x: number; y: number; w: number; h: number };\n\n/** Where a canvas sits on screen and how its design units map to pixels. */\nexport type CanvasMetrics = {\n /** The canvas's `.lz-frame`: the box element positions are relative to. */\n frame: Rect;\n /** Pixels per design pixel vertically (`--u`). */\n unit: number;\n /** The section or the modal dialog, for outlines. */\n outer: Rect;\n};\n\nexport type Layout = {\n canvases: ReadonlyMap<string, CanvasMetrics>;\n elements: ReadonlyMap<string, Rect>;\n};\n\nexport type FrameView = {\n /** The modal shown instead of the page, or null for the page. */\n modal: string | null;\n /** Visible panel per tab or step group. */\n panels: Readonly<Record<string, number>>;\n fontsHref: string;\n emptyImage: string;\n emptyVideo: string;\n};\n\n/** Which canvas or element a rendered node belongs to, by the id core gave it. */\ntype Lookup = { canvases: Map<string, string>; elements: Map<string, { canvas: string; element: string }> };\n\n/**\n * The canvas iframe: a blank same-origin document holding `lienzo.css`, the\n * editor overrides and the page body core rendered. `update` patches only\n * the top-level blocks whose markup changed, so untouched sections keep\n * their DOM (no video reloads, no image flashes) while one is edited.\n */\nexport function mountFrame(iframe: HTMLIFrameElement) {\n const found = iframe.contentDocument;\n\n if (!found) {\n throw new Error('The canvas iframe has no document');\n }\n\n const doc: globalThis.Document = found;\n\n doc.open();\n doc.write('<!DOCTYPE html><html><head><meta charset=\"utf-8\"></head><body class=\"lz-page\"></body></html>');\n doc.close();\n\n const View = doc.defaultView?.CSSStyleSheet ?? CSSStyleSheet;\n const sheet = (css: string) => {\n const created = new View();\n created.replaceSync(css);\n\n return created;\n };\n const pageSheet = sheet('');\n doc.adoptedStyleSheets = [sheet(lienzoCss), pageSheet, sheet(frameCss)];\n\n const fonts = doc.createElement('link');\n fonts.rel = 'stylesheet';\n doc.head.append(fonts);\n\n const body = doc.body;\n let rendered = new Map<string, string>();\n let lookup: Lookup = { canvases: new Map(), elements: new Map() };\n\n function update(html: string, css: string, document: Draft, view: FrameView) {\n pageSheet.replaceSync(css);\n\n if (fonts.href !== view.fontsHref) {\n fonts.href = view.fontsHref;\n }\n\n body.style.setProperty('--lze-empty-image', JSON.stringify(view.emptyImage));\n body.style.setProperty('--lze-empty-video', JSON.stringify(view.emptyVideo));\n patch(html);\n lookup = lookupOf(document);\n\n body.toggleAttribute('data-lze-modal', view.modal !== null);\n body.querySelectorAll('dialog.lz-modal').forEach((dialog) => {\n dialog.toggleAttribute('data-lze-open', view.modal !== null && dialog.id === `m-${domId(view.modal)}`);\n });\n\n body.querySelectorAll<HTMLElement>('.lz-stack').forEach((stack) => {\n const groupId = groupIdOf(stack.id, document);\n const index = groupId === null ? 0 : (view.panels[groupId] ?? 0);\n stack.querySelectorAll(':scope > .lz-stack-panels > .lz-stack-panel').forEach((panel, position) => panel.toggleAttribute('data-on', position === index));\n stack.querySelectorAll(':scope > .lz-stack-nav > button').forEach((button, position) => button.setAttribute('aria-pressed', String(position === index)));\n });\n }\n\n /**\n * Replaces only the top-level blocks whose markup changed, keyed by their\n * id. Moving or restyling an element changes the stylesheet, not the\n * markup, so most edits replace nothing at all.\n */\n function patch(html: string) {\n const template = doc.createElement('template');\n template.innerHTML = html;\n const current = new Map([...body.children].map((node) => [node.id, node]));\n const next = new Map<string, string>();\n const nodes = [...template.content.children].map((node) => {\n const markup = node.outerHTML;\n const existing = current.get(node.id);\n const reusable = existing !== undefined && node.id !== '' && rendered.get(node.id) === markup;\n next.set(node.id, markup);\n\n return reusable ? existing : doc.importNode(node, true);\n });\n\n nodes.forEach((node, index) => {\n if (body.children[index] !== node) {\n body.insertBefore(node, body.children[index] ?? null);\n }\n });\n\n while (body.children.length > nodes.length) {\n body.lastElementChild?.remove();\n }\n\n // Gestures move elements with inline custom properties; the stylesheet is the truth again.\n body.querySelectorAll('.lz-el[style]').forEach((node) => node.removeAttribute('style'));\n rendered = next;\n }\n\n function groupIdOf(stackId: string, document: Draft): string | null {\n const section = document.sections.find((candidate) => candidate.group?.id && `g-${domId(candidate.group.id)}` === stackId);\n\n return section?.group?.id ?? null;\n }\n\n function lookupOf(document: Draft): Lookup {\n const next: Lookup = { canvases: new Map(), elements: new Map() };\n\n for (const canvas of canvasesOf(document)) {\n next.canvases.set(domId(canvas.id), canvas.id);\n\n for (const element of canvas.elements) {\n next.elements.set(domId(element.id), { canvas: canvas.id, element: element.id });\n }\n }\n\n return next;\n }\n\n const elementNode = (id: string) => doc.getElementById(`e-${domId(id)}`);\n\n /** The section, or the modal dialog, of a canvas. */\n const canvasNode = (id: string): HTMLElement | null => doc.getElementById(`s-${domId(id)}`) ?? doc.getElementById(`m-${domId(id)}`);\n\n const frameNode = (id: string): HTMLElement | null => canvasNode(id)?.querySelector<HTMLElement>('.lz-frame') ?? null;\n\n /** What a node in the canvas belongs to: an element (innermost first), else a canvas. */\n function hit(target: EventTarget | null): { canvas: string; element: string | null; node: HTMLElement } | null {\n const start = isNode(target) ? (target.nodeType === 1 ? (target as globalThis.Element) : target.parentElement) : null;\n const elementNodeHit = start?.closest<HTMLElement>('.lz-el');\n const element = elementNodeHit ? lookup.elements.get(elementNodeHit.id.slice(2)) : undefined;\n\n if (elementNodeHit && element) {\n return { canvas: element.canvas, element: element.element, node: elementNodeHit };\n }\n\n const canvasHit = start?.closest<HTMLElement>('.lz-section, dialog.lz-modal');\n const canvas = canvasHit ? lookup.canvases.get(canvasHit.id.slice(2)) : undefined;\n\n return canvasHit && canvas ? { canvas, element: null, node: canvasHit } : null;\n }\n\n const rectOf = (node: HTMLElement): Rect => {\n const box = node.getBoundingClientRect();\n\n return { x: box.left + doc.documentElement.scrollLeft, y: box.top + doc.documentElement.scrollTop, w: box.width, h: box.height };\n };\n\n /**\n * Measures every visible canvas and element. Element boxes come from\n * offsets inside their frame, which ignore transforms, so a rotated\n * element measures as its unrotated box (the overlay rotates it back).\n */\n function measure(document: Draft, device: Device): Layout {\n const canvases = new Map<string, CanvasMetrics>();\n const elements = new Map<string, Rect>();\n\n for (const canvas of canvasesOf(document)) {\n const outer = canvasNode(canvas.id);\n const frame = frameNode(canvas.id);\n\n if (!outer || !frame || frame.offsetParent === null) {\n continue;\n }\n\n const frameRect = rectOf(frame);\n const height = device === 'desktop' ? canvas.height.desktop : canvas.height.mobile;\n canvases.set(canvas.id, { frame: frameRect, unit: frame.hasAttribute('data-stack') && device === 'mobile' ? frameRect.w / 390 : frameRect.h / height, outer: rectOf(outer) });\n\n for (const element of canvas.elements) {\n const node = elementNode(element.id);\n\n if (node && node.offsetParent !== null) {\n elements.set(element.id, { x: frameRect.x + node.offsetLeft, y: frameRect.y + node.offsetTop, w: node.offsetWidth, h: node.offsetHeight });\n }\n }\n }\n\n return { canvases, elements };\n }\n\n /** Moves an element on screen during a gesture, before the document changes. */\n function preview(id: string, device: Device, box: Box) {\n const node = elementNode(id);\n const [x, y, w, h] = device === 'desktop' ? ['--x', '--y', '--w', '--h'] : ['--mx', '--my', '--mw', '--mh'];\n node?.style.setProperty(x, String(box.x));\n node?.style.setProperty(y, String(box.y));\n node?.style.setProperty(w, String(box.w));\n node?.style.setProperty(h, String(box.h));\n }\n\n return {\n doc,\n update,\n measure,\n hit,\n preview,\n /** Sets one custom property on an element during a gesture (rotation, corners). */\n previewVar: (id: string, name: string, value: number) => elementNode(id)?.style.setProperty(name, String(value)),\n contentHeight: () => doc.documentElement.scrollHeight,\n };\n}\n\nexport type CanvasFrame = ReturnType<typeof mountFrame>;\n\n/** Nodes from the iframe belong to another realm, so `instanceof Node` would be false. */\nconst isNode = (value: EventTarget | null): value is Node => value !== null && typeof (value as Partial<Node>).nodeType === 'number';\n","<script setup lang=\"ts\">\nimport { computed, nextTick, onBeforeUnmount, onMounted, ref, watch } from 'vue';\nimport { ALIGNMENTS } from '../model/geometry.ts';\nimport { useEditor } from '../state/editor.ts';\n\n/**\n * The menu a right click opens on the canvas. It carries the actions that\n * apply to what is selected, so the right panel keeps only the settings of\n * the element.\n */\nconst props = defineProps<{ at: { x: number; y: number } }>();\nconst emit = defineEmits<{ close: [] }>();\n\nconst editor = useEditor();\nconst t = editor.t;\nconst menu = ref<HTMLElement>();\nconst position = ref({ ...props.at });\n\nconst selection = computed(() => editor.selectedElements.value);\nconst many = computed(() => selection.value.length > 1);\nconst grouped = computed(() => selection.value.some((element) => element.group));\nconst locked = computed(() => selection.value.some((element) => element.locked));\n\nfunction run(action: () => void) {\n action();\n emit('close');\n}\n\n/** Keeps the menu inside the window, like any native one. */\nasync function place() {\n await nextTick();\n const box = menu.value?.getBoundingClientRect();\n\n if (!box) {\n return;\n }\n\n position.value = {\n x: Math.min(props.at.x, window.innerWidth - box.width - 8),\n y: Math.min(props.at.y, window.innerHeight - box.height - 8),\n };\n}\n\nwatch(() => props.at, place, { immediate: true });\n\nfunction onPointerDown(event: PointerEvent) {\n if (!menu.value?.contains(event.target as Node)) {\n emit('close');\n }\n}\n\nconst onKey = (event: KeyboardEvent) => event.key === 'Escape' && emit('close');\n\nonMounted(() => {\n window.addEventListener('pointerdown', onPointerDown, true);\n window.addEventListener('keydown', onKey);\n window.addEventListener('resize', () => emit('close'));\n menu.value?.focus();\n});\n\nonBeforeUnmount(() => {\n window.removeEventListener('pointerdown', onPointerDown, true);\n window.removeEventListener('keydown', onKey);\n});\n</script>\n\n<template>\n <div\n ref=\"menu\"\n class=\"lze-context\"\n role=\"menu\"\n tabindex=\"-1\"\n :style=\"{ left: `${position.x}px`, top: `${position.y}px` }\"\n @contextmenu.prevent\n >\n <template v-if=\"selection.length\">\n <button type=\"button\" role=\"menuitem\" @click=\"run(editor.copySelected)\">\n {{ t('menu.copy') }}<kbd>⌘C</kbd>\n </button>\n <button type=\"button\" role=\"menuitem\" @click=\"run(editor.duplicateSelected)\">\n {{ t('common.duplicate') }}<kbd>⌘D</kbd>\n </button>\n <button type=\"button\" role=\"menuitem\" @click=\"run(editor.paste)\">\n {{ t('menu.paste') }}<kbd>⌘V</kbd>\n </button>\n\n <hr />\n\n <button type=\"button\" role=\"menuitem\" @click=\"run(() => editor.layer('front'))\">{{ t('canvas.front') }}</button>\n <button type=\"button\" role=\"menuitem\" @click=\"run(() => editor.layer('back'))\">{{ t('canvas.back') }}</button>\n\n <hr />\n\n <button v-if=\"many\" type=\"button\" role=\"menuitem\" @click=\"run(editor.groupSelected)\">\n {{ t('multi.group') }}<kbd>⌘G</kbd>\n </button>\n <button v-if=\"grouped\" type=\"button\" role=\"menuitem\" @click=\"run(editor.ungroupSelected)\">\n {{ t('multi.ungroup') }}\n </button>\n <button type=\"button\" role=\"menuitem\" @click=\"run(editor.toggleLock)\">\n {{ locked ? t('menu.unlock') : t('menu.lock') }}\n </button>\n\n <template v-if=\"many\">\n <hr />\n <p class=\"lze-context-label\">{{ t('multi.align') }}</p>\n <div class=\"lze-context-row\">\n <button\n v-for=\"where in ALIGNMENTS\"\n :key=\"where\"\n type=\"button\"\n role=\"menuitem\"\n :title=\"t(`align.${where}`)\"\n :aria-label=\"t(`align.${where}`)\"\n @click=\"run(() => editor.align(where))\"\n >\n <span class=\"lze-context-align\" :data-align=\"where\" aria-hidden=\"true\" />\n </button>\n </div>\n <template v-if=\"selection.length > 2\">\n <button type=\"button\" role=\"menuitem\" @click=\"run(() => editor.distributeSelected('x'))\">{{ t('multi.distributeX') }}</button>\n <button type=\"button\" role=\"menuitem\" @click=\"run(() => editor.distributeSelected('y'))\">{{ t('multi.distributeY') }}</button>\n </template>\n </template>\n\n <hr />\n\n <button type=\"button\" role=\"menuitem\" class=\"lze-context-danger\" @click=\"run(editor.removeSelected)\">\n {{ t('common.delete') }}<kbd>⌫</kbd>\n </button>\n </template>\n\n <template v-else>\n <button type=\"button\" role=\"menuitem\" @click=\"run(editor.paste)\">\n {{ t('menu.paste') }}<kbd>⌘V</kbd>\n </button>\n <button type=\"button\" role=\"menuitem\" @click=\"run(() => (editor.state.zoom = null))\">{{ t('zoom.fit') }}</button>\n <button type=\"button\" role=\"menuitem\" @click=\"run(() => (editor.state.zoom = 1))\">{{ t('zoom.actual') }}</button>\n </template>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport { computed, nextTick, onBeforeUnmount, onMounted, ref, watch } from 'vue';\nimport { ALIGNMENTS } from '../model/geometry.ts';\nimport { useEditor } from '../state/editor.ts';\n\n/**\n * The menu a right click opens on the canvas. It carries the actions that\n * apply to what is selected, so the right panel keeps only the settings of\n * the element.\n */\nconst props = defineProps<{ at: { x: number; y: number } }>();\nconst emit = defineEmits<{ close: [] }>();\n\nconst editor = useEditor();\nconst t = editor.t;\nconst menu = ref<HTMLElement>();\nconst position = ref({ ...props.at });\n\nconst selection = computed(() => editor.selectedElements.value);\nconst many = computed(() => selection.value.length > 1);\nconst grouped = computed(() => selection.value.some((element) => element.group));\nconst locked = computed(() => selection.value.some((element) => element.locked));\n\nfunction run(action: () => void) {\n action();\n emit('close');\n}\n\n/** Keeps the menu inside the window, like any native one. */\nasync function place() {\n await nextTick();\n const box = menu.value?.getBoundingClientRect();\n\n if (!box) {\n return;\n }\n\n position.value = {\n x: Math.min(props.at.x, window.innerWidth - box.width - 8),\n y: Math.min(props.at.y, window.innerHeight - box.height - 8),\n };\n}\n\nwatch(() => props.at, place, { immediate: true });\n\nfunction onPointerDown(event: PointerEvent) {\n if (!menu.value?.contains(event.target as Node)) {\n emit('close');\n }\n}\n\nconst onKey = (event: KeyboardEvent) => event.key === 'Escape' && emit('close');\n\nonMounted(() => {\n window.addEventListener('pointerdown', onPointerDown, true);\n window.addEventListener('keydown', onKey);\n window.addEventListener('resize', () => emit('close'));\n menu.value?.focus();\n});\n\nonBeforeUnmount(() => {\n window.removeEventListener('pointerdown', onPointerDown, true);\n window.removeEventListener('keydown', onKey);\n});\n</script>\n\n<template>\n <div\n ref=\"menu\"\n class=\"lze-context\"\n role=\"menu\"\n tabindex=\"-1\"\n :style=\"{ left: `${position.x}px`, top: `${position.y}px` }\"\n @contextmenu.prevent\n >\n <template v-if=\"selection.length\">\n <button type=\"button\" role=\"menuitem\" @click=\"run(editor.copySelected)\">\n {{ t('menu.copy') }}<kbd>⌘C</kbd>\n </button>\n <button type=\"button\" role=\"menuitem\" @click=\"run(editor.duplicateSelected)\">\n {{ t('common.duplicate') }}<kbd>⌘D</kbd>\n </button>\n <button type=\"button\" role=\"menuitem\" @click=\"run(editor.paste)\">\n {{ t('menu.paste') }}<kbd>⌘V</kbd>\n </button>\n\n <hr />\n\n <button type=\"button\" role=\"menuitem\" @click=\"run(() => editor.layer('front'))\">{{ t('canvas.front') }}</button>\n <button type=\"button\" role=\"menuitem\" @click=\"run(() => editor.layer('back'))\">{{ t('canvas.back') }}</button>\n\n <hr />\n\n <button v-if=\"many\" type=\"button\" role=\"menuitem\" @click=\"run(editor.groupSelected)\">\n {{ t('multi.group') }}<kbd>⌘G</kbd>\n </button>\n <button v-if=\"grouped\" type=\"button\" role=\"menuitem\" @click=\"run(editor.ungroupSelected)\">\n {{ t('multi.ungroup') }}\n </button>\n <button type=\"button\" role=\"menuitem\" @click=\"run(editor.toggleLock)\">\n {{ locked ? t('menu.unlock') : t('menu.lock') }}\n </button>\n\n <template v-if=\"many\">\n <hr />\n <p class=\"lze-context-label\">{{ t('multi.align') }}</p>\n <div class=\"lze-context-row\">\n <button\n v-for=\"where in ALIGNMENTS\"\n :key=\"where\"\n type=\"button\"\n role=\"menuitem\"\n :title=\"t(`align.${where}`)\"\n :aria-label=\"t(`align.${where}`)\"\n @click=\"run(() => editor.align(where))\"\n >\n <span class=\"lze-context-align\" :data-align=\"where\" aria-hidden=\"true\" />\n </button>\n </div>\n <template v-if=\"selection.length > 2\">\n <button type=\"button\" role=\"menuitem\" @click=\"run(() => editor.distributeSelected('x'))\">{{ t('multi.distributeX') }}</button>\n <button type=\"button\" role=\"menuitem\" @click=\"run(() => editor.distributeSelected('y'))\">{{ t('multi.distributeY') }}</button>\n </template>\n </template>\n\n <hr />\n\n <button type=\"button\" role=\"menuitem\" class=\"lze-context-danger\" @click=\"run(editor.removeSelected)\">\n {{ t('common.delete') }}<kbd>⌫</kbd>\n </button>\n </template>\n\n <template v-else>\n <button type=\"button\" role=\"menuitem\" @click=\"run(editor.paste)\">\n {{ t('menu.paste') }}<kbd>⌘V</kbd>\n </button>\n <button type=\"button\" role=\"menuitem\" @click=\"run(() => (editor.state.zoom = null))\">{{ t('zoom.fit') }}</button>\n <button type=\"button\" role=\"menuitem\" @click=\"run(() => (editor.state.zoom = 1))\">{{ t('zoom.actual') }}</button>\n </template>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport { ArrowDownToLine, ArrowUpToLine, Copy, CopyPlus, Lock, Plus, RotateCw, Trash2 } from '@lucide/vue';\nimport { computed } from 'vue';\nimport { HANDLES, type Guides, type Handle } from '../model/geometry.ts';\nimport { useEditor } from '../state/editor.ts';\nimport type { CanvasMetrics, Layout, Rect } from './frame.ts';\n\n/**\n * Editing adornments drawn over the canvas iframe in the same design pixels:\n * selection boxes, handles, guides, the element toolbar. They are scaled\n * back up (`--inv`) so they keep their screen size at any zoom.\n */\nconst props = defineProps<{\n layout: Layout;\n scale: number;\n hovered: string | null;\n guides: { canvas: string; lines: Guides } | null;\n /** Elements whose box a gesture is changing, drawn from the live box. */\n live: ReadonlyMap<string, Rect>;\n /** Canvases where elements cannot be dragged (stacked on phones). */\n frozen: ReadonlySet<string>;\n /** An angle being dragged, shown before the document has it. */\n rotation: { id: string; value: number } | null;\n}>();\nconst emit = defineEmits<{\n resize: [event: PointerEvent, handle: Handle];\n rotate: [event: PointerEvent];\n radius: [event: PointerEvent];\n generateMobile: [canvas: string];\n}>();\nconst editor = useEditor();\nconst t = editor.t;\n\nconst rectOf = (id: string): Rect | undefined => props.live.get(id) ?? props.layout.elements.get(id);\n\nconst boxes = computed(() => editor.selectedElements.value.flatMap((element) => {\n const rect = rectOf(element.id);\n\n return rect ? [{ element, rect, rotate: props.rotation?.id === element.id ? props.rotation.value : (element.style.rotate ?? 0) }] : [];\n}));\n\nconst single = computed(() => {\n const only = boxes.value.length === 1 ? boxes.value[0] : undefined;\n const selection = editor.state.selection;\n\n if (!only || only.element.locked || selection.kind !== 'elements' || props.frozen.has(selection.canvas) || editor.kindOf(only.element).kind === 'opaque') {\n return null;\n }\n\n return only;\n});\n\nconst active = computed(() => {\n const element = editor.activeElement.value;\n const rect = element ? rectOf(element.id) : undefined;\n\n return element && rect ? { element, rect } : null;\n});\n\nconst hoverRect = computed(() => {\n const selected = editor.selectedElements.value.some((element) => element.id === props.hovered);\n\n return props.hovered && !selected ? (props.layout.elements.get(props.hovered) ?? null) : null;\n});\n\nconst canvasOutline = computed<CanvasMetrics | null>(() => {\n const selection = editor.state.selection;\n\n return selection.kind === 'canvas' ? (props.layout.canvases.get(selection.canvas) ?? null) : null;\n});\n\nconst guideFrame = computed(() => (props.guides ? props.layout.canvases.get(props.guides.canvas) ?? null : null));\n\n/** Sticky navbars get a badge: on the canvas they stay put, on the page they follow the scroll. */\nconst stickies = computed(() => editor.canvases.value.flatMap((canvas) => canvas.elements\n .filter((element) => element.type === 'navbar' && (element.props as { sticky?: boolean | null }).sticky === true)\n .flatMap((element) => {\n const rect = props.layout.elements.get(element.id);\n\n return rect ? [{ id: element.id, rect }] : [];\n })));\n\nconst stacked = computed(() => [...props.frozen].flatMap((id) => {\n const metrics = props.layout.canvases.get(id);\n\n return metrics ? [{ id, rect: metrics.outer }] : [];\n}));\n\n/**\n * El borde de cada sección de la página: ahí aparece el control para meter\n * otra debajo o quitar esta. No se dibuja dentro de una ventana.\n */\nconst edges = computed(() => (editor.activeModal.value ? [] : editor.state.draft.sections.flatMap((section) => {\n const metrics = props.layout.canvases.get(section.id);\n\n return metrics\n ? [{\n id: section.id,\n rect: metrics.outer,\n label: (section.group?.label ?? '').trim() || `#${section.id}`,\n empty: section.elements.length === 0,\n }]\n : [];\n})));\n\nconst place = (rect: Rect) => ({ left: `${rect.x}px`, top: `${rect.y}px`, width: `${rect.w}px`, height: `${rect.h}px` });\n</script>\n\n<template>\n <div class=\"lze-overlay\" :style=\"{ '--inv': String(1 / scale) }\">\n <div v-if=\"canvasOutline\" class=\"lze-canvas-outline\" :style=\"place(canvasOutline.outer)\" />\n\n <div v-if=\"hoverRect\" class=\"lze-hover\" :style=\"place(hoverRect)\" />\n\n <div v-for=\"sticky in stickies\" :key=\"sticky.id\" class=\"lze-badge\" :style=\"{ left: `${sticky.rect.x}px`, top: `${sticky.rect.y}px` }\">{{ t('canvas.sticky') }}</div>\n\n <div v-for=\"item in stacked\" :key=\"item.id\" class=\"lze-stacked\" :style=\"{ left: `${item.rect.x}px`, top: `${item.rect.y}px` }\">\n <span>{{ t('canvas.stacked') }}</span>\n <button type=\"button\" class=\"lze-btn\" @pointerdown.stop @click=\"emit('generateMobile', item.id)\">{{ t('section.generateMobile') }}</button>\n </div>\n\n <button\n v-for=\"edge in edges\"\n :key=\"`chip-${edge.id}`\"\n type=\"button\"\n class=\"lze-section-chip\"\n :data-current=\"editor.state.selection.kind === 'canvas' && editor.state.selection.canvas === edge.id\"\n :style=\"{ left: `${edge.rect.x}px`, top: `${edge.rect.y}px` }\"\n @pointerdown.stop\n @click=\"editor.selectCanvas(edge.id)\"\n >\n {{ edge.label }}\n </button>\n\n <p\n v-for=\"edge in edges.filter((item) => item.empty)\"\n :key=\"`empty-${edge.id}`\"\n class=\"lze-section-empty\"\n :style=\"{ left: `${edge.rect.x + edge.rect.w / 2}px`, top: `${edge.rect.y + edge.rect.h / 2}px` }\"\n >\n {{ t('canvas.emptySection') }}\n </p>\n\n <div\n v-for=\"edge in edges\"\n :key=\"`edge-${edge.id}`\"\n class=\"lze-edge\"\n :style=\"{ left: `${edge.rect.x + edge.rect.w / 2}px`, top: `${edge.rect.y + edge.rect.h}px` }\"\n @pointerdown.stop\n >\n <button type=\"button\" class=\"lze-icon-btn\" :title=\"t('section.addAfter')\" :aria-label=\"t('section.addAfter')\" @click=\"editor.addSection(undefined, edge.id)\">\n <Plus :size=\"15\" aria-hidden=\"true\" />\n </button>\n <button type=\"button\" class=\"lze-icon-btn\" :title=\"t('section.duplicate')\" :aria-label=\"t('section.duplicate')\" @click=\"editor.duplicateSection(edge.id)\">\n <CopyPlus :size=\"15\" aria-hidden=\"true\" />\n </button>\n <button\n v-if=\"editor.state.draft.sections.length > 1\"\n type=\"button\"\n class=\"lze-icon-btn\"\n data-tone=\"danger\"\n :title=\"t('section.delete')\"\n :aria-label=\"t('section.delete')\"\n @click=\"editor.removeSection(edge.id)\"\n >\n <Trash2 :size=\"15\" aria-hidden=\"true\" />\n </button>\n </div>\n\n <template v-if=\"guides && guideFrame\">\n <div\n v-for=\"line in guides.lines.x\"\n :key=\"`x${line}`\"\n class=\"lze-guide\"\n data-axis=\"x\"\n :style=\"{ left: `${guideFrame.frame.x + line}px`, top: `${guideFrame.frame.y}px`, height: `${guideFrame.frame.h}px` }\"\n />\n <div\n v-for=\"line in guides.lines.y\"\n :key=\"`y${line}`\"\n class=\"lze-guide\"\n data-axis=\"y\"\n :style=\"{ top: `${guideFrame.frame.y + line * guideFrame.unit}px`, left: `${guideFrame.frame.x}px`, width: `${guideFrame.frame.w}px` }\"\n />\n </template>\n\n <div\n v-for=\"box in boxes\"\n :key=\"box.element.id\"\n class=\"lze-selection\"\n :data-locked=\"box.element.locked === true\"\n :style=\"{ ...place(box.rect), transform: box.rotate ? `rotate(${box.rotate}deg)` : undefined }\"\n >\n <Lock v-if=\"box.element.locked\" class=\"lze-lock\" :size=\"12\" aria-hidden=\"true\" />\n </div>\n\n <div v-if=\"single\" class=\"lze-handles\" :style=\"{ ...place(single.rect), transform: single.rotate ? `rotate(${single.rotate}deg)` : undefined }\">\n <button\n v-for=\"handle in HANDLES\"\n :key=\"handle\"\n type=\"button\"\n class=\"lze-handle\"\n :data-handle=\"handle\"\n :aria-label=\"t('canvas.resize', { handle })\"\n tabindex=\"-1\"\n @pointerdown.stop.prevent=\"emit('resize', $event, handle)\"\n />\n <button\n v-if=\"single.element.type !== 'divider'\"\n type=\"button\"\n class=\"lze-radius\"\n :title=\"t('canvas.radius', { n: single.element.style.radius ?? 0 })\"\n :aria-label=\"t('canvas.radius', { n: single.element.style.radius ?? 0 })\"\n @pointerdown.stop.prevent=\"emit('radius', $event)\"\n />\n <button\n type=\"button\"\n class=\"lze-rotate\"\n :title=\"t('canvas.rotate', { n: single.element.style.rotate ?? 0 })\"\n :aria-label=\"t('canvas.rotate', { n: single.element.style.rotate ?? 0 })\"\n @pointerdown.stop.prevent=\"emit('rotate', $event)\"\n >\n <RotateCw :size=\"13\" aria-hidden=\"true\" />\n </button>\n </div>\n\n <div\n v-if=\"active && live.size === 0\"\n class=\"lze-element-bar\"\n role=\"toolbar\"\n :aria-label=\"t('canvas.toolbar')\"\n :data-below=\"active.rect.y < 56 / scale\"\n :style=\"{ left: `${active.rect.x}px`, top: `${active.rect.y < 56 / scale ? active.rect.y + active.rect.h : active.rect.y}px` }\"\n @pointerdown.stop\n >\n <button type=\"button\" class=\"lze-icon-btn\" :title=\"t('common.duplicate')\" :aria-label=\"t('common.duplicate')\" @click=\"editor.duplicateSelected()\"><Copy :size=\"16\" aria-hidden=\"true\" /></button>\n <button type=\"button\" class=\"lze-icon-btn\" :title=\"t('canvas.front')\" :aria-label=\"t('canvas.front')\" @click=\"editor.layer('front')\"><ArrowUpToLine :size=\"16\" aria-hidden=\"true\" /></button>\n <button type=\"button\" class=\"lze-icon-btn\" :title=\"t('canvas.back')\" :aria-label=\"t('canvas.back')\" @click=\"editor.layer('back')\"><ArrowDownToLine :size=\"16\" aria-hidden=\"true\" /></button>\n <span class=\"lze-divider\" aria-hidden=\"true\" />\n <button type=\"button\" class=\"lze-icon-btn\" data-tone=\"danger\" :title=\"t('common.delete')\" :aria-label=\"t('common.delete')\" @click=\"editor.removeSelected()\"><Trash2 :size=\"16\" aria-hidden=\"true\" /></button>\n </div>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport { ArrowDownToLine, ArrowUpToLine, Copy, CopyPlus, Lock, Plus, RotateCw, Trash2 } from '@lucide/vue';\nimport { computed } from 'vue';\nimport { HANDLES, type Guides, type Handle } from '../model/geometry.ts';\nimport { useEditor } from '../state/editor.ts';\nimport type { CanvasMetrics, Layout, Rect } from './frame.ts';\n\n/**\n * Editing adornments drawn over the canvas iframe in the same design pixels:\n * selection boxes, handles, guides, the element toolbar. They are scaled\n * back up (`--inv`) so they keep their screen size at any zoom.\n */\nconst props = defineProps<{\n layout: Layout;\n scale: number;\n hovered: string | null;\n guides: { canvas: string; lines: Guides } | null;\n /** Elements whose box a gesture is changing, drawn from the live box. */\n live: ReadonlyMap<string, Rect>;\n /** Canvases where elements cannot be dragged (stacked on phones). */\n frozen: ReadonlySet<string>;\n /** An angle being dragged, shown before the document has it. */\n rotation: { id: string; value: number } | null;\n}>();\nconst emit = defineEmits<{\n resize: [event: PointerEvent, handle: Handle];\n rotate: [event: PointerEvent];\n radius: [event: PointerEvent];\n generateMobile: [canvas: string];\n}>();\nconst editor = useEditor();\nconst t = editor.t;\n\nconst rectOf = (id: string): Rect | undefined => props.live.get(id) ?? props.layout.elements.get(id);\n\nconst boxes = computed(() => editor.selectedElements.value.flatMap((element) => {\n const rect = rectOf(element.id);\n\n return rect ? [{ element, rect, rotate: props.rotation?.id === element.id ? props.rotation.value : (element.style.rotate ?? 0) }] : [];\n}));\n\nconst single = computed(() => {\n const only = boxes.value.length === 1 ? boxes.value[0] : undefined;\n const selection = editor.state.selection;\n\n if (!only || only.element.locked || selection.kind !== 'elements' || props.frozen.has(selection.canvas) || editor.kindOf(only.element).kind === 'opaque') {\n return null;\n }\n\n return only;\n});\n\nconst active = computed(() => {\n const element = editor.activeElement.value;\n const rect = element ? rectOf(element.id) : undefined;\n\n return element && rect ? { element, rect } : null;\n});\n\nconst hoverRect = computed(() => {\n const selected = editor.selectedElements.value.some((element) => element.id === props.hovered);\n\n return props.hovered && !selected ? (props.layout.elements.get(props.hovered) ?? null) : null;\n});\n\nconst canvasOutline = computed<CanvasMetrics | null>(() => {\n const selection = editor.state.selection;\n\n return selection.kind === 'canvas' ? (props.layout.canvases.get(selection.canvas) ?? null) : null;\n});\n\nconst guideFrame = computed(() => (props.guides ? props.layout.canvases.get(props.guides.canvas) ?? null : null));\n\n/** Sticky navbars get a badge: on the canvas they stay put, on the page they follow the scroll. */\nconst stickies = computed(() => editor.canvases.value.flatMap((canvas) => canvas.elements\n .filter((element) => element.type === 'navbar' && (element.props as { sticky?: boolean | null }).sticky === true)\n .flatMap((element) => {\n const rect = props.layout.elements.get(element.id);\n\n return rect ? [{ id: element.id, rect }] : [];\n })));\n\nconst stacked = computed(() => [...props.frozen].flatMap((id) => {\n const metrics = props.layout.canvases.get(id);\n\n return metrics ? [{ id, rect: metrics.outer }] : [];\n}));\n\n/**\n * El borde de cada sección de la página: ahí aparece el control para meter\n * otra debajo o quitar esta. No se dibuja dentro de una ventana.\n */\nconst edges = computed(() => (editor.activeModal.value ? [] : editor.state.draft.sections.flatMap((section) => {\n const metrics = props.layout.canvases.get(section.id);\n\n return metrics\n ? [{\n id: section.id,\n rect: metrics.outer,\n label: (section.group?.label ?? '').trim() || `#${section.id}`,\n empty: section.elements.length === 0,\n }]\n : [];\n})));\n\nconst place = (rect: Rect) => ({ left: `${rect.x}px`, top: `${rect.y}px`, width: `${rect.w}px`, height: `${rect.h}px` });\n</script>\n\n<template>\n <div class=\"lze-overlay\" :style=\"{ '--inv': String(1 / scale) }\">\n <div v-if=\"canvasOutline\" class=\"lze-canvas-outline\" :style=\"place(canvasOutline.outer)\" />\n\n <div v-if=\"hoverRect\" class=\"lze-hover\" :style=\"place(hoverRect)\" />\n\n <div v-for=\"sticky in stickies\" :key=\"sticky.id\" class=\"lze-badge\" :style=\"{ left: `${sticky.rect.x}px`, top: `${sticky.rect.y}px` }\">{{ t('canvas.sticky') }}</div>\n\n <div v-for=\"item in stacked\" :key=\"item.id\" class=\"lze-stacked\" :style=\"{ left: `${item.rect.x}px`, top: `${item.rect.y}px` }\">\n <span>{{ t('canvas.stacked') }}</span>\n <button type=\"button\" class=\"lze-btn\" @pointerdown.stop @click=\"emit('generateMobile', item.id)\">{{ t('section.generateMobile') }}</button>\n </div>\n\n <button\n v-for=\"edge in edges\"\n :key=\"`chip-${edge.id}`\"\n type=\"button\"\n class=\"lze-section-chip\"\n :data-current=\"editor.state.selection.kind === 'canvas' && editor.state.selection.canvas === edge.id\"\n :style=\"{ left: `${edge.rect.x}px`, top: `${edge.rect.y}px` }\"\n @pointerdown.stop\n @click=\"editor.selectCanvas(edge.id)\"\n >\n {{ edge.label }}\n </button>\n\n <p\n v-for=\"edge in edges.filter((item) => item.empty)\"\n :key=\"`empty-${edge.id}`\"\n class=\"lze-section-empty\"\n :style=\"{ left: `${edge.rect.x + edge.rect.w / 2}px`, top: `${edge.rect.y + edge.rect.h / 2}px` }\"\n >\n {{ t('canvas.emptySection') }}\n </p>\n\n <div\n v-for=\"edge in edges\"\n :key=\"`edge-${edge.id}`\"\n class=\"lze-edge\"\n :style=\"{ left: `${edge.rect.x + edge.rect.w / 2}px`, top: `${edge.rect.y + edge.rect.h}px` }\"\n @pointerdown.stop\n >\n <button type=\"button\" class=\"lze-icon-btn\" :title=\"t('section.addAfter')\" :aria-label=\"t('section.addAfter')\" @click=\"editor.addSection(undefined, edge.id)\">\n <Plus :size=\"15\" aria-hidden=\"true\" />\n </button>\n <button type=\"button\" class=\"lze-icon-btn\" :title=\"t('section.duplicate')\" :aria-label=\"t('section.duplicate')\" @click=\"editor.duplicateSection(edge.id)\">\n <CopyPlus :size=\"15\" aria-hidden=\"true\" />\n </button>\n <button\n v-if=\"editor.state.draft.sections.length > 1\"\n type=\"button\"\n class=\"lze-icon-btn\"\n data-tone=\"danger\"\n :title=\"t('section.delete')\"\n :aria-label=\"t('section.delete')\"\n @click=\"editor.removeSection(edge.id)\"\n >\n <Trash2 :size=\"15\" aria-hidden=\"true\" />\n </button>\n </div>\n\n <template v-if=\"guides && guideFrame\">\n <div\n v-for=\"line in guides.lines.x\"\n :key=\"`x${line}`\"\n class=\"lze-guide\"\n data-axis=\"x\"\n :style=\"{ left: `${guideFrame.frame.x + line}px`, top: `${guideFrame.frame.y}px`, height: `${guideFrame.frame.h}px` }\"\n />\n <div\n v-for=\"line in guides.lines.y\"\n :key=\"`y${line}`\"\n class=\"lze-guide\"\n data-axis=\"y\"\n :style=\"{ top: `${guideFrame.frame.y + line * guideFrame.unit}px`, left: `${guideFrame.frame.x}px`, width: `${guideFrame.frame.w}px` }\"\n />\n </template>\n\n <div\n v-for=\"box in boxes\"\n :key=\"box.element.id\"\n class=\"lze-selection\"\n :data-locked=\"box.element.locked === true\"\n :style=\"{ ...place(box.rect), transform: box.rotate ? `rotate(${box.rotate}deg)` : undefined }\"\n >\n <Lock v-if=\"box.element.locked\" class=\"lze-lock\" :size=\"12\" aria-hidden=\"true\" />\n </div>\n\n <div v-if=\"single\" class=\"lze-handles\" :style=\"{ ...place(single.rect), transform: single.rotate ? `rotate(${single.rotate}deg)` : undefined }\">\n <button\n v-for=\"handle in HANDLES\"\n :key=\"handle\"\n type=\"button\"\n class=\"lze-handle\"\n :data-handle=\"handle\"\n :aria-label=\"t('canvas.resize', { handle })\"\n tabindex=\"-1\"\n @pointerdown.stop.prevent=\"emit('resize', $event, handle)\"\n />\n <button\n v-if=\"single.element.type !== 'divider'\"\n type=\"button\"\n class=\"lze-radius\"\n :title=\"t('canvas.radius', { n: single.element.style.radius ?? 0 })\"\n :aria-label=\"t('canvas.radius', { n: single.element.style.radius ?? 0 })\"\n @pointerdown.stop.prevent=\"emit('radius', $event)\"\n />\n <button\n type=\"button\"\n class=\"lze-rotate\"\n :title=\"t('canvas.rotate', { n: single.element.style.rotate ?? 0 })\"\n :aria-label=\"t('canvas.rotate', { n: single.element.style.rotate ?? 0 })\"\n @pointerdown.stop.prevent=\"emit('rotate', $event)\"\n >\n <RotateCw :size=\"13\" aria-hidden=\"true\" />\n </button>\n </div>\n\n <div\n v-if=\"active && live.size === 0\"\n class=\"lze-element-bar\"\n role=\"toolbar\"\n :aria-label=\"t('canvas.toolbar')\"\n :data-below=\"active.rect.y < 56 / scale\"\n :style=\"{ left: `${active.rect.x}px`, top: `${active.rect.y < 56 / scale ? active.rect.y + active.rect.h : active.rect.y}px` }\"\n @pointerdown.stop\n >\n <button type=\"button\" class=\"lze-icon-btn\" :title=\"t('common.duplicate')\" :aria-label=\"t('common.duplicate')\" @click=\"editor.duplicateSelected()\"><Copy :size=\"16\" aria-hidden=\"true\" /></button>\n <button type=\"button\" class=\"lze-icon-btn\" :title=\"t('canvas.front')\" :aria-label=\"t('canvas.front')\" @click=\"editor.layer('front')\"><ArrowUpToLine :size=\"16\" aria-hidden=\"true\" /></button>\n <button type=\"button\" class=\"lze-icon-btn\" :title=\"t('canvas.back')\" :aria-label=\"t('canvas.back')\" @click=\"editor.layer('back')\"><ArrowDownToLine :size=\"16\" aria-hidden=\"true\" /></button>\n <span class=\"lze-divider\" aria-hidden=\"true\" />\n <button type=\"button\" class=\"lze-icon-btn\" data-tone=\"danger\" :title=\"t('common.delete')\" :aria-label=\"t('common.delete')\" @click=\"editor.removeSelected()\"><Trash2 :size=\"16\" aria-hidden=\"true\" /></button>\n </div>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport type { Box } from '@skylivellc/lienzo-core';\nimport { computed, nextTick, onBeforeUnmount, onMounted, ref, shallowRef, toRaw, watch } from 'vue';\nimport { boxOf, canvasHeight, findCanvas, stacksOnMobile, type Device } from '../model/document.ts';\nimport { anchorsOf, clamp, clampBox, dragBox, snapToAnchors, type Anchors, type Guides, type Handle } from '../model/geometry.ts';\nimport { fontsHref } from '../model/theme.ts';\nimport { issueText, useEditor } from '../state/editor.ts';\nimport { handleShortcut } from '../state/shortcuts.ts';\nimport { mountFrame, type CanvasFrame, type CanvasMetrics, type Layout, type Rect } from './frame.ts';\nimport ContextMenu from './ContextMenu.vue';\nimport Overlay from './Overlay.vue';\nimport { domId, renderContext, renderDraft } from './render.ts';\n\n/**\n * The editing canvas: the page rendered by core inside an iframe at its\n * design width (the theme's max width, 390 on phones, or an open modal's\n * width), scaled to fit, with the overlay on top. Gestures move elements by\n * setting their custom properties directly and write the document once, when they end.\n */\nconst editor = useEditor();\nconst t = editor.t;\nconst stage = ref<HTMLElement>();\nconst sheet = ref<HTMLElement>();\nconst scaler = ref<HTMLElement>();\nconst iframe = ref<HTMLIFrameElement>();\nconst stageWidth = ref(0);\nconst contentHeight = ref(320);\nconst layout = shallowRef<Layout>({ canvases: new Map(), elements: new Map() });\nconst hovered = ref<string | null>(null);\nconst guides = shallowRef<{ canvas: string; lines: Guides } | null>(null);\nconst live = shallowRef<ReadonlyMap<string, Rect>>(new Map());\n/** The angle a rotate gesture shows before it is written. */\nconst rotation = shallowRef<{ id: string; value: number } | null>(null);\nconst hint = ref<string | null>(null);\nlet frame: CanvasFrame | null = null;\n\nconst PADDING = 24;\nconst MIN_ZOOM = 0.1;\nconst MAX_ZOOM = 4;\n/** Zoom that fits the stage, used until someone zooms by hand. */\nconst fitScale = computed(() => clamp((stageWidth.value - PADDING * 2) / editor.frameWidth.value, MIN_ZOOM, 1));\nconst scale = computed(() => editor.state.zoom ?? fitScale.value);\nconst zoomPercent = computed(() => Math.round(scale.value * 100));\n\n/**\n * Zooms around a point of the stage, so what is under the pointer stays\n * under it. Without a point, around the middle of what is visible.\n */\nasync function zoomTo(value: number, at?: { x: number; y: number }) {\n const stageEl = stage.value;\n const sheetEl = sheet.value;\n const next = clamp(value, MIN_ZOOM, MAX_ZOOM);\n\n if (!stageEl || !sheetEl) {\n editor.state.zoom = next;\n\n return;\n }\n\n const box = stageEl.getBoundingClientRect();\n const point = at ?? { x: box.left + box.width / 2, y: box.top + box.height / 2 };\n const before = sheetEl.getBoundingClientRect();\n const frameX = (point.x - before.left) / scale.value;\n const frameY = (point.y - before.top) / scale.value;\n\n editor.state.zoom = next;\n await nextTick();\n\n const after = sheetEl.getBoundingClientRect();\n stageEl.scrollLeft += after.left + frameX * next - point.x;\n stageEl.scrollTop += after.top + frameY * next - point.y;\n}\n\nconst zoomBy = (factor: number, at?: { x: number; y: number }) => zoomTo(scale.value * factor, at);\nconst fitToStage = () => (editor.state.zoom = null);\n\n/** Ctrl or Cmd with the wheel zooms; the wheel alone scrolls the stage. */\nfunction onWheel(event: WheelEvent) {\n if (!event.ctrlKey && !event.metaKey) {\n return;\n }\n\n event.preventDefault();\n void zoomBy(Math.exp(-event.deltaY / 400), { x: event.clientX, y: event.clientY });\n}\n\n/** The same gesture over the page itself: its events never leave the iframe. */\nfunction onFrameWheel(event: WheelEvent) {\n const box = iframe.value?.getBoundingClientRect();\n\n if ((!event.ctrlKey && !event.metaKey) || !box) {\n return;\n }\n\n event.preventDefault();\n void zoomBy(Math.exp(-event.deltaY / 400), {\n x: box.left + event.clientX * scale.value,\n y: box.top + event.clientY * scale.value,\n });\n}\n\n/** Space held, or the middle button, drags the view without moving anything. */\nconst spaceHeld = ref(false);\nconst panning = ref(false);\nlet pan: { pointer: number; x: number; y: number; left: number; top: number; factor: number } | null = null;\n\n/**\n * Starts a pan. `factor` turns the event's pixels into stage pixels: 1 over\n * the stage, and the zoom over the page, whose events carry frame pixels.\n */\nfunction startPan(event: PointerEvent, factor = 1): boolean {\n const stageEl = stage.value;\n\n if (!stageEl || (!spaceHeld.value && event.button !== 1)) {\n return false;\n }\n\n event.preventDefault();\n pan = {\n pointer: event.pointerId,\n x: event.clientX * factor,\n y: event.clientY * factor,\n left: stageEl.scrollLeft,\n top: stageEl.scrollTop,\n factor,\n };\n panning.value = true;\n (event.currentTarget as Element | null)?.setPointerCapture?.(event.pointerId);\n\n return true;\n}\n\nfunction movePan(event: PointerEvent) {\n const stageEl = stage.value;\n\n if (!pan || !stageEl || pan.pointer !== event.pointerId) {\n return;\n }\n\n stageEl.scrollLeft = pan.left - (event.clientX * pan.factor - pan.x);\n stageEl.scrollTop = pan.top - (event.clientY * pan.factor - pan.y);\n}\n\nfunction endPan(event: PointerEvent) {\n if (pan && pan.pointer === event.pointerId) {\n pan = null;\n panning.value = false;\n }\n}\n\nfunction onStageKeyDown(event: KeyboardEvent) {\n if (event.code === 'Space' && !spaceHeld.value) {\n const target = event.target as HTMLElement | null;\n\n if (target?.closest('input, textarea, select, [contenteditable=\"true\"]')) {\n return;\n }\n\n spaceHeld.value = true;\n event.preventDefault();\n }\n}\n\nconst onStageKeyUp = (event: KeyboardEvent) => {\n if (event.code === 'Space') {\n spaceHeld.value = false;\n }\n};\n\nconst releaseSpace = () => {\n spaceHeld.value = false;\n};\n\nfunction onWindowKeyDown(event: KeyboardEvent) {\n if (onZoomShortcut(event)) {\n return;\n }\n\n onStageKeyDown(event);\n}\n\n/** Ctrl o Cmd con +, -, 0 y 1, como en las herramientas de diseño. */\nfunction onZoomShortcut(event: KeyboardEvent): boolean {\n if (!event.ctrlKey && !event.metaKey) {\n return false;\n }\n\n if (event.key === '+' || event.key === '=') {\n void zoomBy(1.25);\n } else if (event.key === '-') {\n void zoomBy(0.8);\n } else if (event.key === '0') {\n fitToStage();\n } else if (event.key === '1') {\n void zoomTo(1);\n } else {\n return false;\n }\n\n event.preventDefault();\n\n return true;\n}\n\n/** On phones, a canvas where some element has no phone box stacks: its elements cannot be dragged there. */\n/** A canvas nobody can drag in: stacked on phones, or laying itself out. */\nconst frozen = computed<ReadonlySet<string>>(() => new Set(editor.canvases.value\n .filter((canvas) => ('flow' in canvas && canvas.flow && canvas.flow !== 'free') || (editor.state.device === 'mobile' && stacksOnMobile(canvas)))\n .map((canvas) => canvas.id)));\n\nconst empty = computed(() => editor.canvases.value.every((canvas) => canvas.elements.length === 0));\n\n\nlet scheduled = 0;\nlet rendering = false;\nlet again = false;\n\nfunction schedule() {\n if (!scheduled) {\n scheduled = requestAnimationFrame(() => {\n scheduled = 0;\n void render();\n });\n }\n}\n\nasync function render() {\n // A render now would undo a gesture's live custom properties or the text being typed.\n if (!frame || rendering || editing || gesture) {\n again = true;\n\n return;\n }\n\n rendering = true;\n\n try {\n // Raw data: parsing walks every value, and the deep watcher already tracks changes.\n const draft = toRaw(editor.state.draft);\n const result = await renderDraft(draft, renderContext(editor), 'edit');\n\n if (!result.ok) {\n editor.state.renderIssues = result.issues;\n\n return;\n }\n\n editor.state.renderIssues = [];\n frame.update(result.page.body, result.page.css, draft, {\n modal: editor.state.view.kind === 'modal' ? editor.state.view.id : null,\n panels: editor.state.panels,\n fontsHref: fontsHref([editor.theme.value.heading_font, editor.theme.value.body_font]),\n emptyImage: t('canvas.emptyImage'),\n emptyVideo: t('canvas.emptyVideo'),\n });\n relayout();\n } finally {\n rendering = false;\n\n if (again) {\n again = false;\n schedule();\n }\n }\n}\n\nfunction relayout() {\n if (frame) {\n contentHeight.value = frame.contentHeight();\n layout.value = frame.measure(editor.state.draft, editor.state.device);\n }\n}\n\nwatch(() => editor.state.draft, schedule, { deep: true });\nwatch([editor.site, () => editor.state.workspace.assets, editor.previews.version, () => editor.state.view, () => editor.state.panels], schedule);\nwatch([() => editor.state.device, () => editor.frameWidth.value], () => nextTick(relayout));\n\n\ntype Item = { id: string; start: Box };\n\ntype Gesture =\n | {\n kind: 'box';\n handle: Handle | null;\n canvas: string;\n origin: { x: number; y: number };\n /** Event pixels to frame pixels: 1 inside the iframe, 1/scale from the overlay. */\n factor: number;\n metrics: CanvasMetrics;\n anchors: Anchors;\n target: Item;\n others: Item[];\n boxes: Map<string, Box>;\n }\n | { kind: 'rotate'; id: string; center: { x: number; y: number }; startAngle: number; from: number; value: number }\n | { kind: 'radius'; id: string; origin: number; factor: number; unit: number; from: number; value: number };\n\nlet gesture: Gesture | null = null;\nlet release: (() => void) | null = null;\n\n/** Captures the pointer on `node` and routes its moves to the current gesture until it ends. */\nfunction capture(node: HTMLElement | SVGElement, event: PointerEvent) {\n node.setPointerCapture(event.pointerId);\n const move = (next: Event) => onGestureMove(next as PointerEvent);\n const end = () => finishGesture();\n const events = ['pointerup', 'pointercancel', 'lostpointercapture'] as const;\n node.addEventListener('pointermove', move);\n events.forEach((name) => node.addEventListener(name, end));\n release = () => {\n node.removeEventListener('pointermove', move);\n events.forEach((name) => node.removeEventListener(name, end));\n };\n}\n\nfunction startBoxGesture(event: PointerEvent, node: HTMLElement | SVGElement, handle: Handle | null, factor: number) {\n const selection = editor.state.selection;\n\n if (selection.kind !== 'elements' || frozen.value.has(selection.canvas)) {\n return;\n }\n\n const canvas = findCanvas(editor.state.draft, selection.canvas);\n const metrics = layout.value.canvases.get(selection.canvas);\n const device = editor.state.device;\n const active = editor.activeElement.value;\n\n if (!canvas || !metrics || !active || active.locked || editor.kindOf(active).kind === 'opaque') {\n return;\n }\n\n const movable = handle ? [active] : editor.selectedElements.value.filter((element) => !element.locked);\n const ids = new Set(movable.map((element) => element.id));\n\n gesture = {\n kind: 'box',\n handle,\n canvas: canvas.id,\n origin: { x: event.clientX, y: event.clientY },\n factor,\n metrics,\n anchors: anchorsOf(canvas.elements.filter((element) => !ids.has(element.id)).map((element) => boxOf(element, device)), metrics.frame.w, canvasHeight(canvas, device)),\n target: { id: active.id, start: { ...boxOf(active, device) } },\n others: movable.filter((element) => element.id !== active.id).map((element) => ({ id: element.id, start: { ...boxOf(element, device) } })),\n boxes: new Map(),\n };\n capture(node, event);\n}\n\nfunction onGestureMove(event: PointerEvent) {\n const current = gesture;\n\n if (!current || !frame) {\n return;\n }\n\n if (current.kind === 'rotate') {\n const turned = current.from + (angle(current.center, event) - current.startAngle);\n current.value = clamp(event.shiftKey ? Math.round(turned / 15) * 15 : Math.round(turned), -180, 180);\n frame.previewVar(current.id, '--rot', current.value);\n rotation.value = { id: current.id, value: current.value };\n hint.value = `${current.value}°`;\n\n return;\n }\n\n if (current.kind === 'radius') {\n const delta = ((event.clientX - current.origin) * current.factor) / current.unit;\n current.value = Math.round(clamp(current.from + delta, 0, 200));\n frame.previewVar(current.id, '--r', current.value);\n hint.value = t('canvas.corners', { n: current.value });\n\n return;\n }\n\n const { metrics, handle, target } = current;\n const dx = (event.clientX - current.origin.x) * current.factor;\n const dy = ((event.clientY - current.origin.y) * current.factor) / metrics.unit;\n const dragged = dragBox(target.start, { x: dx, y: dy }, handle, metrics.frame.w);\n const threshold = { x: 6 / scale.value, y: 6 / (scale.value * metrics.unit) };\n const snapped = snapToAnchors(dragged, current.anchors, metrics.frame.w, threshold, handle);\n const device = editor.state.device;\n const rects = new Map<string, Rect>();\n const apply = (id: string, box: Box) => {\n current.boxes.set(id, box);\n frame?.preview(id, device, box);\n rects.set(id, {\n x: metrics.frame.x + (box.x / 100) * metrics.frame.w,\n y: metrics.frame.y + box.y * metrics.unit,\n w: (box.w / 100) * metrics.frame.w,\n h: box.h * metrics.unit,\n });\n };\n\n apply(target.id, snapped.box);\n\n for (const other of current.others) {\n apply(other.id, clampBox({ ...other.start, x: other.start.x + snapped.box.x - target.start.x, y: other.start.y + snapped.box.y - target.start.y }));\n }\n\n live.value = rects;\n guides.value = snapped.guides.x.length || snapped.guides.y.length ? { canvas: current.canvas, lines: snapped.guides } : null;\n hint.value = handle\n ? `${Math.round((snapped.box.w * metrics.frame.w) / 100)} × ${Math.round(snapped.box.h)} px`\n : `x ${snapped.box.x.toFixed(1)}% · y ${Math.round(snapped.box.y)} px`;\n}\n\nfunction finishGesture() {\n const finished = gesture;\n gesture = null;\n release?.();\n release = null;\n hint.value = null;\n guides.value = null;\n\n if (finished?.kind === 'box' && finished.boxes.size > 0) {\n editor.placeElements([...finished.boxes].map(([id, box]) => ({ id, box })));\n } else if (finished && finished.kind !== 'box' && finished.value !== finished.from) {\n const element = elementById(finished.id);\n\n if (element) {\n element.style[finished.kind === 'rotate' ? 'rotate' : 'radius'] = finished.value;\n editor.commit();\n }\n }\n\n live.value = new Map();\n rotation.value = null;\n schedule();\n}\n\nfunction elementById(id: string) {\n return editor.selectedElements.value.find((element) => element.id === id);\n}\n\nconst angle = (center: { x: number; y: number }, event: PointerEvent) => (Math.atan2(event.clientY - center.y, event.clientX - center.x) * 180) / Math.PI;\n\nfunction onResize(event: PointerEvent, handle: Handle) {\n startBoxGesture(event, event.currentTarget as HTMLElement, handle, 1 / scale.value);\n}\n\nfunction onRotate(event: PointerEvent) {\n const element = editor.activeElement.value;\n const rect = element ? layout.value.elements.get(element.id) : undefined;\n const sheet = scaler.value?.getBoundingClientRect();\n\n if (!element || !rect || !sheet) {\n return;\n }\n\n const center = { x: sheet.left + (rect.x + rect.w / 2) * scale.value, y: sheet.top + (rect.y + rect.h / 2) * scale.value };\n const from = element.style.rotate ?? 0;\n gesture = { kind: 'rotate', id: element.id, center, startAngle: angle(center, event), from, value: from };\n capture(event.currentTarget as HTMLElement, event);\n}\n\nfunction onRadius(event: PointerEvent) {\n const element = editor.activeElement.value;\n const selection = editor.state.selection;\n const metrics = selection.kind === 'elements' ? layout.value.canvases.get(selection.canvas) : undefined;\n\n if (!element || !metrics) {\n return;\n }\n\n const from = element.style.radius ?? 0;\n gesture = { kind: 'radius', id: element.id, origin: event.clientX, factor: 1 / scale.value, unit: metrics.unit, from, value: from };\n capture(event.currentTarget as HTMLElement, event);\n}\n\n\nlet editing: { node: HTMLElement; canvas: string; id: string; prop: 'text' | 'label' } | null = null;\n\n/** Tab and step bars switch panels in the editor too; the runtime does not run here. */\nfunction switchPanel(target: EventTarget | null): boolean {\n const button = (target as Partial<HTMLElement> | null)?.closest?.('.lz-stack-nav > button[data-go]');\n const stack = button?.closest('.lz-stack');\n const index = Number(button?.getAttribute('data-go'));\n const section = stack ? editor.state.draft.sections.find((candidate) => candidate.group?.id && `g-${domId(candidate.group.id)}` === stack.id) : undefined;\n\n if (!section?.group?.id || !Number.isInteger(index)) {\n return false;\n }\n\n editor.state.panels = { ...editor.state.panels, [section.group.id]: index };\n\n return true;\n}\n\nfunction onPointerDown(event: PointerEvent) {\n if (startPan(event, scale.value)) {\n return;\n }\n\n if (!frame || event.button !== 0) {\n return;\n }\n\n if (editing && editing.node.contains(event.target as Node)) {\n return;\n }\n\n finishEditing();\n\n if (switchPanel(event.target)) {\n return;\n }\n\n const hit = frame.hit(event.target);\n\n if (!hit) {\n editor.clearSelection();\n\n return;\n }\n\n if (hit.element === null) {\n editor.selectCanvas(hit.canvas);\n\n return;\n }\n\n event.preventDefault();\n editor.select(hit.canvas, hit.element, event.shiftKey);\n const selection = editor.state.selection;\n\n if (selection.kind === 'elements' && selection.ids.includes(hit.element) && !event.shiftKey) {\n startBoxGesture(event, hit.node, null, 1);\n }\n}\n\nfunction onDoubleClick(event: MouseEvent) {\n const hit = frame?.hit(event.target);\n const element = hit?.element ? findCanvas(editor.state.draft, hit.canvas)?.elements.find((candidate) => candidate.id === hit.element) : undefined;\n const kind = element ? editor.kindOf(element) : null;\n\n if (!hit || !element || kind?.kind !== 'core' || !kind.spec.inline || element.locked || editor.state.previewing) {\n return;\n }\n\n const node = hit.node;\n editing = { node, canvas: hit.canvas, id: element.id, prop: kind.spec.inline };\n node.setAttribute('contenteditable', 'plaintext-only');\n node.focus();\n node.ownerDocument.getSelection()?.selectAllChildren(node);\n node.addEventListener('blur', finishEditing, { once: true });\n}\n\nfunction finishEditing() {\n const current = editing;\n\n if (!current) {\n return;\n }\n\n editing = null;\n const text = current.node.innerText.trim();\n current.node.removeAttribute('contenteditable');\n const element = findCanvas(editor.state.draft, current.canvas)?.elements.find((candidate) => candidate.id === current.id);\n\n if (element) {\n (element.props as Record<string, unknown>)[current.prop] = text;\n editor.commit();\n }\n\n schedule();\n}\n\nfunction onKeyDown(event: KeyboardEvent) {\n if (editing) {\n if ((event.key === 'Enter' && !event.shiftKey) || event.key === 'Escape') {\n event.preventDefault();\n editing.node.blur();\n }\n\n return;\n }\n\n if (onZoomShortcut(event)) {\n return;\n }\n\n handleShortcut(editor, event);\n}\n\n/** Where the context menu is open, in window coordinates. */\nconst menuAt = ref<{ x: number; y: number } | null>(null);\n\n/**\n * A right click opens the menu for what is under it, selecting it first when\n * it was not part of the selection, the way design tools do.\n */\nfunction onContextMenu(event: MouseEvent, inFrame: boolean) {\n const hit = inFrame ? frame?.hit(event.target) : null;\n\n if (inFrame) {\n const selected = editor.state.selection.kind === 'elements' ? editor.state.selection.ids : [];\n\n if (hit?.element && !selected.includes(hit.element)) {\n editor.select(hit.canvas, hit.element, false);\n } else if (hit && !hit.element) {\n editor.selectCanvas(hit.canvas);\n }\n }\n\n event.preventDefault();\n const box = inFrame ? iframe.value?.getBoundingClientRect() : null;\n menuAt.value = box\n ? { x: box.left + event.clientX * scale.value, y: box.top + event.clientY * scale.value }\n : { x: event.clientX, y: event.clientY };\n}\n\nfunction onPointerOver(event: PointerEvent) {\n const hit = frame?.hit(event.target);\n hovered.value = hit?.element ?? null;\n}\n\n/** Links, buttons and forms on the canvas never navigate or submit. */\nconst inert = (event: Event) => {\n if (!editing) {\n event.preventDefault();\n }\n};\n\n/**\n * Where a drop from the palette lands: the canvas under the pointer and the\n * position inside it, in design units. Null outside every canvas.\n */\nfunction dropPoint(clientX: number, clientY: number): { canvas: string; x: number; y: number } | null {\n const box = iframe.value?.getBoundingClientRect();\n\n if (!frame || !box || clientX < box.left || clientX > box.right || clientY < box.top || clientY > box.bottom) {\n return null;\n }\n\n const x = (clientX - box.left) / scale.value;\n const y = (clientY - box.top) / scale.value;\n const hit = frame.hit(frame.doc.elementFromPoint(x, y));\n const metrics = hit ? layout.value.canvases.get(hit.canvas) : undefined;\n\n if (!hit || !metrics) {\n return null;\n }\n\n return {\n canvas: hit.canvas,\n x: clamp(((x - metrics.frame.x) / metrics.frame.w) * 100, 0, 90),\n y: clamp((y - metrics.frame.y) / metrics.unit, 0, 3000),\n };\n}\n\ndefineExpose({ dropPoint });\n\n\nlet stageObserver: ResizeObserver | null = null;\nlet frameObserver: ResizeObserver | null = null;\n\nonMounted(() => {\n if (!iframe.value || !stage.value) {\n return;\n }\n\n frame = mountFrame(iframe.value);\n const doc = frame.doc;\n doc.addEventListener('pointerdown', onPointerDown);\n doc.addEventListener('dblclick', onDoubleClick);\n doc.addEventListener('keydown', onKeyDown);\n doc.addEventListener('pointerover', onPointerOver);\n doc.addEventListener('contextmenu', (event) => onContextMenu(event as MouseEvent, true));\n doc.addEventListener('wheel', onFrameWheel, { passive: false });\n doc.addEventListener('pointermove', movePan);\n doc.addEventListener('pointerup', endPan);\n doc.addEventListener('pointercancel', endPan);\n doc.documentElement.addEventListener('pointerleave', () => (hovered.value = null));\n doc.addEventListener('click', inert, true);\n doc.addEventListener('submit', inert, true);\n\n const FrameObserver = doc.defaultView?.ResizeObserver ?? ResizeObserver;\n const observer = new FrameObserver(() => relayout());\n observer.observe(doc.body);\n frameObserver = observer;\n doc.addEventListener('keyup', onStageKeyUp);\n stageObserver = new ResizeObserver(([entry]) => {\n stageWidth.value = entry?.contentRect.width ?? 0;\n });\n stageObserver.observe(stage.value);\n window.addEventListener('keydown', onWindowKeyDown);\n window.addEventListener('keyup', onStageKeyUp);\n window.addEventListener('blur', releaseSpace);\n schedule();\n});\n\nonBeforeUnmount(() => {\n window.removeEventListener('keydown', onWindowKeyDown);\n window.removeEventListener('keyup', onStageKeyUp);\n window.removeEventListener('blur', releaseSpace);\n cancelAnimationFrame(scheduled);\n stageObserver?.disconnect();\n frameObserver?.disconnect();\n release?.();\n});\n\nfunction generateMobile(id: string) {\n const canvas = findCanvas(editor.state.draft, id);\n\n if (canvas) {\n editor.generateMobile(canvas);\n }\n}\n\nconst deviceName = (device: Device) => (device === 'desktop' ? t('toolbar.desktop') : t('toolbar.mobile'));\n</script>\n\n<template>\n <div\n ref=\"stage\"\n class=\"lze-stage\"\n :data-space=\"panning ? 'panning' : spaceHeld ? 'on' : undefined\"\n @pointerdown=\"startPan($event)\"\n @pointerdown.self=\"editor.clearSelection()\"\n @pointermove=\"movePan\"\n @pointerup=\"endPan\"\n @pointercancel=\"endPan\"\n @wheel=\"onWheel\"\n @contextmenu=\"onContextMenu($event, false)\"\n >\n <p v-if=\"editor.state.renderIssues.length\" class=\"lze-render-issue\" role=\"alert\">\n {{ t('canvas.invalid', { issue: issueText(editor.state.renderIssues[0]) }) }}\n </p>\n <div v-if=\"editor.activeModal.value\" class=\"lze-modal-banner\">\n <span>{{ t('canvas.editingModal', { title: editor.activeModal.value.title }) }}</span>\n <button type=\"button\" class=\"lze-btn\" @click=\"editor.openModal(null)\">{{ t('canvas.backToPage') }}</button>\n </div>\n <div\n ref=\"sheet\"\n class=\"lze-sheet\"\n :data-device=\"editor.state.device\"\n :aria-label=\"deviceName(editor.state.device)\"\n :style=\"{ width: `${editor.frameWidth.value * scale}px`, height: `${contentHeight * scale}px` }\"\n >\n <div ref=\"scaler\" class=\"lze-scaler\" :style=\"{ width: `${editor.frameWidth.value}px`, transform: `scale(${scale})` }\">\n <iframe ref=\"iframe\" class=\"lze-frame\" :title=\"t('canvas.title')\" :style=\"{ width: `${editor.frameWidth.value}px`, height: `${contentHeight}px` }\" />\n <Overlay\n :layout=\"layout\"\n :scale=\"scale\"\n :hovered=\"hovered\"\n :guides=\"guides\"\n :live=\"live\"\n :rotation=\"rotation\"\n :frozen=\"frozen\"\n @resize=\"onResize\"\n @rotate=\"onRotate\"\n @radius=\"onRadius\"\n @generate-mobile=\"generateMobile\"\n />\n </div>\n </div>\n <p v-if=\"empty\" class=\"lze-empty-hint\">{{ editor.activeModal.value ? t('canvas.emptyModal') : t('canvas.emptyPage') }}</p>\n <p v-if=\"hint\" class=\"lze-hint-bubble\" aria-live=\"polite\">{{ hint }}</p>\n\n <ContextMenu v-if=\"menuAt\" :at=\"menuAt\" @close=\"menuAt = null\" />\n\n <div class=\"lze-zoom\" role=\"group\" :aria-label=\"t('zoom.label')\">\n <button type=\"button\" class=\"lze-zoom-btn\" :title=\"t('zoom.out')\" :aria-label=\"t('zoom.out')\" @click=\"zoomBy(0.8)\">−</button>\n <button type=\"button\" class=\"lze-zoom-value\" :title=\"t('zoom.fit')\" @click=\"fitToStage()\">{{ zoomPercent }}%</button>\n <button type=\"button\" class=\"lze-zoom-btn\" :title=\"t('zoom.in')\" :aria-label=\"t('zoom.in')\" @click=\"zoomBy(1.25)\">+</button>\n <button type=\"button\" class=\"lze-zoom-btn\" :title=\"t('zoom.actual')\" :aria-label=\"t('zoom.actual')\" @click=\"zoomTo(1)\">1:1</button>\n </div>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport type { Box } from '@skylivellc/lienzo-core';\nimport { computed, nextTick, onBeforeUnmount, onMounted, ref, shallowRef, toRaw, watch } from 'vue';\nimport { boxOf, canvasHeight, findCanvas, stacksOnMobile, type Device } from '../model/document.ts';\nimport { anchorsOf, clamp, clampBox, dragBox, snapToAnchors, type Anchors, type Guides, type Handle } from '../model/geometry.ts';\nimport { fontsHref } from '../model/theme.ts';\nimport { issueText, useEditor } from '../state/editor.ts';\nimport { handleShortcut } from '../state/shortcuts.ts';\nimport { mountFrame, type CanvasFrame, type CanvasMetrics, type Layout, type Rect } from './frame.ts';\nimport ContextMenu from './ContextMenu.vue';\nimport Overlay from './Overlay.vue';\nimport { domId, renderContext, renderDraft } from './render.ts';\n\n/**\n * The editing canvas: the page rendered by core inside an iframe at its\n * design width (the theme's max width, 390 on phones, or an open modal's\n * width), scaled to fit, with the overlay on top. Gestures move elements by\n * setting their custom properties directly and write the document once, when they end.\n */\nconst editor = useEditor();\nconst t = editor.t;\nconst stage = ref<HTMLElement>();\nconst sheet = ref<HTMLElement>();\nconst scaler = ref<HTMLElement>();\nconst iframe = ref<HTMLIFrameElement>();\nconst stageWidth = ref(0);\nconst contentHeight = ref(320);\nconst layout = shallowRef<Layout>({ canvases: new Map(), elements: new Map() });\nconst hovered = ref<string | null>(null);\nconst guides = shallowRef<{ canvas: string; lines: Guides } | null>(null);\nconst live = shallowRef<ReadonlyMap<string, Rect>>(new Map());\n/** The angle a rotate gesture shows before it is written. */\nconst rotation = shallowRef<{ id: string; value: number } | null>(null);\nconst hint = ref<string | null>(null);\nlet frame: CanvasFrame | null = null;\n\nconst PADDING = 24;\nconst MIN_ZOOM = 0.1;\nconst MAX_ZOOM = 4;\n/** Zoom that fits the stage, used until someone zooms by hand. */\nconst fitScale = computed(() => clamp((stageWidth.value - PADDING * 2) / editor.frameWidth.value, MIN_ZOOM, 1));\nconst scale = computed(() => editor.state.zoom ?? fitScale.value);\nconst zoomPercent = computed(() => Math.round(scale.value * 100));\n\n/**\n * Zooms around a point of the stage, so what is under the pointer stays\n * under it. Without a point, around the middle of what is visible.\n */\nasync function zoomTo(value: number, at?: { x: number; y: number }) {\n const stageEl = stage.value;\n const sheetEl = sheet.value;\n const next = clamp(value, MIN_ZOOM, MAX_ZOOM);\n\n if (!stageEl || !sheetEl) {\n editor.state.zoom = next;\n\n return;\n }\n\n const box = stageEl.getBoundingClientRect();\n const point = at ?? { x: box.left + box.width / 2, y: box.top + box.height / 2 };\n const before = sheetEl.getBoundingClientRect();\n const frameX = (point.x - before.left) / scale.value;\n const frameY = (point.y - before.top) / scale.value;\n\n editor.state.zoom = next;\n await nextTick();\n\n const after = sheetEl.getBoundingClientRect();\n stageEl.scrollLeft += after.left + frameX * next - point.x;\n stageEl.scrollTop += after.top + frameY * next - point.y;\n}\n\nconst zoomBy = (factor: number, at?: { x: number; y: number }) => zoomTo(scale.value * factor, at);\nconst fitToStage = () => (editor.state.zoom = null);\n\n/** Ctrl or Cmd with the wheel zooms; the wheel alone scrolls the stage. */\nfunction onWheel(event: WheelEvent) {\n if (!event.ctrlKey && !event.metaKey) {\n return;\n }\n\n event.preventDefault();\n void zoomBy(Math.exp(-event.deltaY / 400), { x: event.clientX, y: event.clientY });\n}\n\n/** The same gesture over the page itself: its events never leave the iframe. */\nfunction onFrameWheel(event: WheelEvent) {\n const box = iframe.value?.getBoundingClientRect();\n\n if ((!event.ctrlKey && !event.metaKey) || !box) {\n return;\n }\n\n event.preventDefault();\n void zoomBy(Math.exp(-event.deltaY / 400), {\n x: box.left + event.clientX * scale.value,\n y: box.top + event.clientY * scale.value,\n });\n}\n\n/** Space held, or the middle button, drags the view without moving anything. */\nconst spaceHeld = ref(false);\nconst panning = ref(false);\nlet pan: { pointer: number; x: number; y: number; left: number; top: number; factor: number } | null = null;\n\n/**\n * Starts a pan. `factor` turns the event's pixels into stage pixels: 1 over\n * the stage, and the zoom over the page, whose events carry frame pixels.\n */\nfunction startPan(event: PointerEvent, factor = 1): boolean {\n const stageEl = stage.value;\n\n if (!stageEl || (!spaceHeld.value && event.button !== 1)) {\n return false;\n }\n\n event.preventDefault();\n pan = {\n pointer: event.pointerId,\n x: event.clientX * factor,\n y: event.clientY * factor,\n left: stageEl.scrollLeft,\n top: stageEl.scrollTop,\n factor,\n };\n panning.value = true;\n (event.currentTarget as Element | null)?.setPointerCapture?.(event.pointerId);\n\n return true;\n}\n\nfunction movePan(event: PointerEvent) {\n const stageEl = stage.value;\n\n if (!pan || !stageEl || pan.pointer !== event.pointerId) {\n return;\n }\n\n stageEl.scrollLeft = pan.left - (event.clientX * pan.factor - pan.x);\n stageEl.scrollTop = pan.top - (event.clientY * pan.factor - pan.y);\n}\n\nfunction endPan(event: PointerEvent) {\n if (pan && pan.pointer === event.pointerId) {\n pan = null;\n panning.value = false;\n }\n}\n\nfunction onStageKeyDown(event: KeyboardEvent) {\n if (event.code === 'Space' && !spaceHeld.value) {\n const target = event.target as HTMLElement | null;\n\n if (target?.closest('input, textarea, select, [contenteditable=\"true\"]')) {\n return;\n }\n\n spaceHeld.value = true;\n event.preventDefault();\n }\n}\n\nconst onStageKeyUp = (event: KeyboardEvent) => {\n if (event.code === 'Space') {\n spaceHeld.value = false;\n }\n};\n\nconst releaseSpace = () => {\n spaceHeld.value = false;\n};\n\nfunction onWindowKeyDown(event: KeyboardEvent) {\n if (onZoomShortcut(event)) {\n return;\n }\n\n onStageKeyDown(event);\n}\n\n/** Ctrl o Cmd con +, -, 0 y 1, como en las herramientas de diseño. */\nfunction onZoomShortcut(event: KeyboardEvent): boolean {\n if (!event.ctrlKey && !event.metaKey) {\n return false;\n }\n\n if (event.key === '+' || event.key === '=') {\n void zoomBy(1.25);\n } else if (event.key === '-') {\n void zoomBy(0.8);\n } else if (event.key === '0') {\n fitToStage();\n } else if (event.key === '1') {\n void zoomTo(1);\n } else {\n return false;\n }\n\n event.preventDefault();\n\n return true;\n}\n\n/** On phones, a canvas where some element has no phone box stacks: its elements cannot be dragged there. */\n/** A canvas nobody can drag in: stacked on phones, or laying itself out. */\nconst frozen = computed<ReadonlySet<string>>(() => new Set(editor.canvases.value\n .filter((canvas) => ('flow' in canvas && canvas.flow && canvas.flow !== 'free') || (editor.state.device === 'mobile' && stacksOnMobile(canvas)))\n .map((canvas) => canvas.id)));\n\nconst empty = computed(() => editor.canvases.value.every((canvas) => canvas.elements.length === 0));\n\n\nlet scheduled = 0;\nlet rendering = false;\nlet again = false;\n\nfunction schedule() {\n if (!scheduled) {\n scheduled = requestAnimationFrame(() => {\n scheduled = 0;\n void render();\n });\n }\n}\n\nasync function render() {\n // A render now would undo a gesture's live custom properties or the text being typed.\n if (!frame || rendering || editing || gesture) {\n again = true;\n\n return;\n }\n\n rendering = true;\n\n try {\n // Raw data: parsing walks every value, and the deep watcher already tracks changes.\n const draft = toRaw(editor.state.draft);\n const result = await renderDraft(draft, renderContext(editor), 'edit');\n\n if (!result.ok) {\n editor.state.renderIssues = result.issues;\n\n return;\n }\n\n editor.state.renderIssues = [];\n frame.update(result.page.body, result.page.css, draft, {\n modal: editor.state.view.kind === 'modal' ? editor.state.view.id : null,\n panels: editor.state.panels,\n fontsHref: fontsHref([editor.theme.value.heading_font, editor.theme.value.body_font]),\n emptyImage: t('canvas.emptyImage'),\n emptyVideo: t('canvas.emptyVideo'),\n });\n relayout();\n } finally {\n rendering = false;\n\n if (again) {\n again = false;\n schedule();\n }\n }\n}\n\nfunction relayout() {\n if (frame) {\n contentHeight.value = frame.contentHeight();\n layout.value = frame.measure(editor.state.draft, editor.state.device);\n }\n}\n\nwatch(() => editor.state.draft, schedule, { deep: true });\nwatch([editor.site, () => editor.state.workspace.assets, editor.previews.version, () => editor.state.view, () => editor.state.panels], schedule);\nwatch([() => editor.state.device, () => editor.frameWidth.value], () => nextTick(relayout));\n\n\ntype Item = { id: string; start: Box };\n\ntype Gesture =\n | {\n kind: 'box';\n handle: Handle | null;\n canvas: string;\n origin: { x: number; y: number };\n /** Event pixels to frame pixels: 1 inside the iframe, 1/scale from the overlay. */\n factor: number;\n metrics: CanvasMetrics;\n anchors: Anchors;\n target: Item;\n others: Item[];\n boxes: Map<string, Box>;\n }\n | { kind: 'rotate'; id: string; center: { x: number; y: number }; startAngle: number; from: number; value: number }\n | { kind: 'radius'; id: string; origin: number; factor: number; unit: number; from: number; value: number };\n\nlet gesture: Gesture | null = null;\nlet release: (() => void) | null = null;\n\n/** Captures the pointer on `node` and routes its moves to the current gesture until it ends. */\nfunction capture(node: HTMLElement | SVGElement, event: PointerEvent) {\n node.setPointerCapture(event.pointerId);\n const move = (next: Event) => onGestureMove(next as PointerEvent);\n const end = () => finishGesture();\n const events = ['pointerup', 'pointercancel', 'lostpointercapture'] as const;\n node.addEventListener('pointermove', move);\n events.forEach((name) => node.addEventListener(name, end));\n release = () => {\n node.removeEventListener('pointermove', move);\n events.forEach((name) => node.removeEventListener(name, end));\n };\n}\n\nfunction startBoxGesture(event: PointerEvent, node: HTMLElement | SVGElement, handle: Handle | null, factor: number) {\n const selection = editor.state.selection;\n\n if (selection.kind !== 'elements' || frozen.value.has(selection.canvas)) {\n return;\n }\n\n const canvas = findCanvas(editor.state.draft, selection.canvas);\n const metrics = layout.value.canvases.get(selection.canvas);\n const device = editor.state.device;\n const active = editor.activeElement.value;\n\n if (!canvas || !metrics || !active || active.locked || editor.kindOf(active).kind === 'opaque') {\n return;\n }\n\n const movable = handle ? [active] : editor.selectedElements.value.filter((element) => !element.locked);\n const ids = new Set(movable.map((element) => element.id));\n\n gesture = {\n kind: 'box',\n handle,\n canvas: canvas.id,\n origin: { x: event.clientX, y: event.clientY },\n factor,\n metrics,\n anchors: anchorsOf(canvas.elements.filter((element) => !ids.has(element.id)).map((element) => boxOf(element, device)), metrics.frame.w, canvasHeight(canvas, device)),\n target: { id: active.id, start: { ...boxOf(active, device) } },\n others: movable.filter((element) => element.id !== active.id).map((element) => ({ id: element.id, start: { ...boxOf(element, device) } })),\n boxes: new Map(),\n };\n capture(node, event);\n}\n\nfunction onGestureMove(event: PointerEvent) {\n const current = gesture;\n\n if (!current || !frame) {\n return;\n }\n\n if (current.kind === 'rotate') {\n const turned = current.from + (angle(current.center, event) - current.startAngle);\n current.value = clamp(event.shiftKey ? Math.round(turned / 15) * 15 : Math.round(turned), -180, 180);\n frame.previewVar(current.id, '--rot', current.value);\n rotation.value = { id: current.id, value: current.value };\n hint.value = `${current.value}°`;\n\n return;\n }\n\n if (current.kind === 'radius') {\n const delta = ((event.clientX - current.origin) * current.factor) / current.unit;\n current.value = Math.round(clamp(current.from + delta, 0, 200));\n frame.previewVar(current.id, '--r', current.value);\n hint.value = t('canvas.corners', { n: current.value });\n\n return;\n }\n\n const { metrics, handle, target } = current;\n const dx = (event.clientX - current.origin.x) * current.factor;\n const dy = ((event.clientY - current.origin.y) * current.factor) / metrics.unit;\n const dragged = dragBox(target.start, { x: dx, y: dy }, handle, metrics.frame.w);\n const threshold = { x: 6 / scale.value, y: 6 / (scale.value * metrics.unit) };\n const snapped = snapToAnchors(dragged, current.anchors, metrics.frame.w, threshold, handle);\n const device = editor.state.device;\n const rects = new Map<string, Rect>();\n const apply = (id: string, box: Box) => {\n current.boxes.set(id, box);\n frame?.preview(id, device, box);\n rects.set(id, {\n x: metrics.frame.x + (box.x / 100) * metrics.frame.w,\n y: metrics.frame.y + box.y * metrics.unit,\n w: (box.w / 100) * metrics.frame.w,\n h: box.h * metrics.unit,\n });\n };\n\n apply(target.id, snapped.box);\n\n for (const other of current.others) {\n apply(other.id, clampBox({ ...other.start, x: other.start.x + snapped.box.x - target.start.x, y: other.start.y + snapped.box.y - target.start.y }));\n }\n\n live.value = rects;\n guides.value = snapped.guides.x.length || snapped.guides.y.length ? { canvas: current.canvas, lines: snapped.guides } : null;\n hint.value = handle\n ? `${Math.round((snapped.box.w * metrics.frame.w) / 100)} × ${Math.round(snapped.box.h)} px`\n : `x ${snapped.box.x.toFixed(1)}% · y ${Math.round(snapped.box.y)} px`;\n}\n\nfunction finishGesture() {\n const finished = gesture;\n gesture = null;\n release?.();\n release = null;\n hint.value = null;\n guides.value = null;\n\n if (finished?.kind === 'box' && finished.boxes.size > 0) {\n editor.placeElements([...finished.boxes].map(([id, box]) => ({ id, box })));\n } else if (finished && finished.kind !== 'box' && finished.value !== finished.from) {\n const element = elementById(finished.id);\n\n if (element) {\n element.style[finished.kind === 'rotate' ? 'rotate' : 'radius'] = finished.value;\n editor.commit();\n }\n }\n\n live.value = new Map();\n rotation.value = null;\n schedule();\n}\n\nfunction elementById(id: string) {\n return editor.selectedElements.value.find((element) => element.id === id);\n}\n\nconst angle = (center: { x: number; y: number }, event: PointerEvent) => (Math.atan2(event.clientY - center.y, event.clientX - center.x) * 180) / Math.PI;\n\nfunction onResize(event: PointerEvent, handle: Handle) {\n startBoxGesture(event, event.currentTarget as HTMLElement, handle, 1 / scale.value);\n}\n\nfunction onRotate(event: PointerEvent) {\n const element = editor.activeElement.value;\n const rect = element ? layout.value.elements.get(element.id) : undefined;\n const sheet = scaler.value?.getBoundingClientRect();\n\n if (!element || !rect || !sheet) {\n return;\n }\n\n const center = { x: sheet.left + (rect.x + rect.w / 2) * scale.value, y: sheet.top + (rect.y + rect.h / 2) * scale.value };\n const from = element.style.rotate ?? 0;\n gesture = { kind: 'rotate', id: element.id, center, startAngle: angle(center, event), from, value: from };\n capture(event.currentTarget as HTMLElement, event);\n}\n\nfunction onRadius(event: PointerEvent) {\n const element = editor.activeElement.value;\n const selection = editor.state.selection;\n const metrics = selection.kind === 'elements' ? layout.value.canvases.get(selection.canvas) : undefined;\n\n if (!element || !metrics) {\n return;\n }\n\n const from = element.style.radius ?? 0;\n gesture = { kind: 'radius', id: element.id, origin: event.clientX, factor: 1 / scale.value, unit: metrics.unit, from, value: from };\n capture(event.currentTarget as HTMLElement, event);\n}\n\n\nlet editing: { node: HTMLElement; canvas: string; id: string; prop: 'text' | 'label' } | null = null;\n\n/** Tab and step bars switch panels in the editor too; the runtime does not run here. */\nfunction switchPanel(target: EventTarget | null): boolean {\n const button = (target as Partial<HTMLElement> | null)?.closest?.('.lz-stack-nav > button[data-go]');\n const stack = button?.closest('.lz-stack');\n const index = Number(button?.getAttribute('data-go'));\n const section = stack ? editor.state.draft.sections.find((candidate) => candidate.group?.id && `g-${domId(candidate.group.id)}` === stack.id) : undefined;\n\n if (!section?.group?.id || !Number.isInteger(index)) {\n return false;\n }\n\n editor.state.panels = { ...editor.state.panels, [section.group.id]: index };\n\n return true;\n}\n\nfunction onPointerDown(event: PointerEvent) {\n if (startPan(event, scale.value)) {\n return;\n }\n\n if (!frame || event.button !== 0) {\n return;\n }\n\n if (editing && editing.node.contains(event.target as Node)) {\n return;\n }\n\n finishEditing();\n\n if (switchPanel(event.target)) {\n return;\n }\n\n const hit = frame.hit(event.target);\n\n if (!hit) {\n editor.clearSelection();\n\n return;\n }\n\n if (hit.element === null) {\n editor.selectCanvas(hit.canvas);\n\n return;\n }\n\n event.preventDefault();\n editor.select(hit.canvas, hit.element, event.shiftKey);\n const selection = editor.state.selection;\n\n if (selection.kind === 'elements' && selection.ids.includes(hit.element) && !event.shiftKey) {\n startBoxGesture(event, hit.node, null, 1);\n }\n}\n\nfunction onDoubleClick(event: MouseEvent) {\n const hit = frame?.hit(event.target);\n const element = hit?.element ? findCanvas(editor.state.draft, hit.canvas)?.elements.find((candidate) => candidate.id === hit.element) : undefined;\n const kind = element ? editor.kindOf(element) : null;\n\n if (!hit || !element || kind?.kind !== 'core' || !kind.spec.inline || element.locked || editor.state.previewing) {\n return;\n }\n\n const node = hit.node;\n editing = { node, canvas: hit.canvas, id: element.id, prop: kind.spec.inline };\n node.setAttribute('contenteditable', 'plaintext-only');\n node.focus();\n node.ownerDocument.getSelection()?.selectAllChildren(node);\n node.addEventListener('blur', finishEditing, { once: true });\n}\n\nfunction finishEditing() {\n const current = editing;\n\n if (!current) {\n return;\n }\n\n editing = null;\n const text = current.node.innerText.trim();\n current.node.removeAttribute('contenteditable');\n const element = findCanvas(editor.state.draft, current.canvas)?.elements.find((candidate) => candidate.id === current.id);\n\n if (element) {\n (element.props as Record<string, unknown>)[current.prop] = text;\n editor.commit();\n }\n\n schedule();\n}\n\nfunction onKeyDown(event: KeyboardEvent) {\n if (editing) {\n if ((event.key === 'Enter' && !event.shiftKey) || event.key === 'Escape') {\n event.preventDefault();\n editing.node.blur();\n }\n\n return;\n }\n\n if (onZoomShortcut(event)) {\n return;\n }\n\n handleShortcut(editor, event);\n}\n\n/** Where the context menu is open, in window coordinates. */\nconst menuAt = ref<{ x: number; y: number } | null>(null);\n\n/**\n * A right click opens the menu for what is under it, selecting it first when\n * it was not part of the selection, the way design tools do.\n */\nfunction onContextMenu(event: MouseEvent, inFrame: boolean) {\n const hit = inFrame ? frame?.hit(event.target) : null;\n\n if (inFrame) {\n const selected = editor.state.selection.kind === 'elements' ? editor.state.selection.ids : [];\n\n if (hit?.element && !selected.includes(hit.element)) {\n editor.select(hit.canvas, hit.element, false);\n } else if (hit && !hit.element) {\n editor.selectCanvas(hit.canvas);\n }\n }\n\n event.preventDefault();\n const box = inFrame ? iframe.value?.getBoundingClientRect() : null;\n menuAt.value = box\n ? { x: box.left + event.clientX * scale.value, y: box.top + event.clientY * scale.value }\n : { x: event.clientX, y: event.clientY };\n}\n\nfunction onPointerOver(event: PointerEvent) {\n const hit = frame?.hit(event.target);\n hovered.value = hit?.element ?? null;\n}\n\n/** Links, buttons and forms on the canvas never navigate or submit. */\nconst inert = (event: Event) => {\n if (!editing) {\n event.preventDefault();\n }\n};\n\n/**\n * Where a drop from the palette lands: the canvas under the pointer and the\n * position inside it, in design units. Null outside every canvas.\n */\nfunction dropPoint(clientX: number, clientY: number): { canvas: string; x: number; y: number } | null {\n const box = iframe.value?.getBoundingClientRect();\n\n if (!frame || !box || clientX < box.left || clientX > box.right || clientY < box.top || clientY > box.bottom) {\n return null;\n }\n\n const x = (clientX - box.left) / scale.value;\n const y = (clientY - box.top) / scale.value;\n const hit = frame.hit(frame.doc.elementFromPoint(x, y));\n const metrics = hit ? layout.value.canvases.get(hit.canvas) : undefined;\n\n if (!hit || !metrics) {\n return null;\n }\n\n return {\n canvas: hit.canvas,\n x: clamp(((x - metrics.frame.x) / metrics.frame.w) * 100, 0, 90),\n y: clamp((y - metrics.frame.y) / metrics.unit, 0, 3000),\n };\n}\n\ndefineExpose({ dropPoint });\n\n\nlet stageObserver: ResizeObserver | null = null;\nlet frameObserver: ResizeObserver | null = null;\n\nonMounted(() => {\n if (!iframe.value || !stage.value) {\n return;\n }\n\n frame = mountFrame(iframe.value);\n const doc = frame.doc;\n doc.addEventListener('pointerdown', onPointerDown);\n doc.addEventListener('dblclick', onDoubleClick);\n doc.addEventListener('keydown', onKeyDown);\n doc.addEventListener('pointerover', onPointerOver);\n doc.addEventListener('contextmenu', (event) => onContextMenu(event as MouseEvent, true));\n doc.addEventListener('wheel', onFrameWheel, { passive: false });\n doc.addEventListener('pointermove', movePan);\n doc.addEventListener('pointerup', endPan);\n doc.addEventListener('pointercancel', endPan);\n doc.documentElement.addEventListener('pointerleave', () => (hovered.value = null));\n doc.addEventListener('click', inert, true);\n doc.addEventListener('submit', inert, true);\n\n const FrameObserver = doc.defaultView?.ResizeObserver ?? ResizeObserver;\n const observer = new FrameObserver(() => relayout());\n observer.observe(doc.body);\n frameObserver = observer;\n doc.addEventListener('keyup', onStageKeyUp);\n stageObserver = new ResizeObserver(([entry]) => {\n stageWidth.value = entry?.contentRect.width ?? 0;\n });\n stageObserver.observe(stage.value);\n window.addEventListener('keydown', onWindowKeyDown);\n window.addEventListener('keyup', onStageKeyUp);\n window.addEventListener('blur', releaseSpace);\n schedule();\n});\n\nonBeforeUnmount(() => {\n window.removeEventListener('keydown', onWindowKeyDown);\n window.removeEventListener('keyup', onStageKeyUp);\n window.removeEventListener('blur', releaseSpace);\n cancelAnimationFrame(scheduled);\n stageObserver?.disconnect();\n frameObserver?.disconnect();\n release?.();\n});\n\nfunction generateMobile(id: string) {\n const canvas = findCanvas(editor.state.draft, id);\n\n if (canvas) {\n editor.generateMobile(canvas);\n }\n}\n\nconst deviceName = (device: Device) => (device === 'desktop' ? t('toolbar.desktop') : t('toolbar.mobile'));\n</script>\n\n<template>\n <div\n ref=\"stage\"\n class=\"lze-stage\"\n :data-space=\"panning ? 'panning' : spaceHeld ? 'on' : undefined\"\n @pointerdown=\"startPan($event)\"\n @pointerdown.self=\"editor.clearSelection()\"\n @pointermove=\"movePan\"\n @pointerup=\"endPan\"\n @pointercancel=\"endPan\"\n @wheel=\"onWheel\"\n @contextmenu=\"onContextMenu($event, false)\"\n >\n <p v-if=\"editor.state.renderIssues.length\" class=\"lze-render-issue\" role=\"alert\">\n {{ t('canvas.invalid', { issue: issueText(editor.state.renderIssues[0]) }) }}\n </p>\n <div v-if=\"editor.activeModal.value\" class=\"lze-modal-banner\">\n <span>{{ t('canvas.editingModal', { title: editor.activeModal.value.title }) }}</span>\n <button type=\"button\" class=\"lze-btn\" @click=\"editor.openModal(null)\">{{ t('canvas.backToPage') }}</button>\n </div>\n <div\n ref=\"sheet\"\n class=\"lze-sheet\"\n :data-device=\"editor.state.device\"\n :aria-label=\"deviceName(editor.state.device)\"\n :style=\"{ width: `${editor.frameWidth.value * scale}px`, height: `${contentHeight * scale}px` }\"\n >\n <div ref=\"scaler\" class=\"lze-scaler\" :style=\"{ width: `${editor.frameWidth.value}px`, transform: `scale(${scale})` }\">\n <iframe ref=\"iframe\" class=\"lze-frame\" :title=\"t('canvas.title')\" :style=\"{ width: `${editor.frameWidth.value}px`, height: `${contentHeight}px` }\" />\n <Overlay\n :layout=\"layout\"\n :scale=\"scale\"\n :hovered=\"hovered\"\n :guides=\"guides\"\n :live=\"live\"\n :rotation=\"rotation\"\n :frozen=\"frozen\"\n @resize=\"onResize\"\n @rotate=\"onRotate\"\n @radius=\"onRadius\"\n @generate-mobile=\"generateMobile\"\n />\n </div>\n </div>\n <p v-if=\"empty\" class=\"lze-empty-hint\">{{ editor.activeModal.value ? t('canvas.emptyModal') : t('canvas.emptyPage') }}</p>\n <p v-if=\"hint\" class=\"lze-hint-bubble\" aria-live=\"polite\">{{ hint }}</p>\n\n <ContextMenu v-if=\"menuAt\" :at=\"menuAt\" @close=\"menuAt = null\" />\n\n <div class=\"lze-zoom\" role=\"group\" :aria-label=\"t('zoom.label')\">\n <button type=\"button\" class=\"lze-zoom-btn\" :title=\"t('zoom.out')\" :aria-label=\"t('zoom.out')\" @click=\"zoomBy(0.8)\">−</button>\n <button type=\"button\" class=\"lze-zoom-value\" :title=\"t('zoom.fit')\" @click=\"fitToStage()\">{{ zoomPercent }}%</button>\n <button type=\"button\" class=\"lze-zoom-btn\" :title=\"t('zoom.in')\" :aria-label=\"t('zoom.in')\" @click=\"zoomBy(1.25)\">+</button>\n <button type=\"button\" class=\"lze-zoom-btn\" :title=\"t('zoom.actual')\" :aria-label=\"t('zoom.actual')\" @click=\"zoomTo(1)\">1:1</button>\n </div>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport { onBeforeUnmount, onMounted, ref, shallowRef, toRaw, watch } from 'vue';\nimport { clamp } from '../model/geometry.ts';\nimport { useEditor } from '../state/editor.ts';\nimport { renderContext, renderDraft } from './render.ts';\n\n/**\n * The page as visitors get it: the complete public document from core,\n * runtime included (tabs, modals, sticky navbar, animations), in an iframe at\n * the device width so viewport units and fixed positions behave as on a phone.\n */\nconst editor = useEditor();\nconst stage = ref<HTMLElement>();\nconst html = shallowRef('');\nconst size = ref({ width: 0, height: 0 });\nlet observer: ResizeObserver | null = null;\n\nasync function render() {\n const result = await renderDraft(toRaw(editor.state.draft), renderContext(editor), 'public');\n\n if (result.ok) {\n html.value = result.page.html;\n }\n}\n\nwatch([() => editor.state.draft, editor.previews.version], render, { deep: true, immediate: true });\n\nonMounted(() => {\n observer = new ResizeObserver(([entry]) => {\n size.value = { width: entry?.contentRect.width ?? 0, height: entry?.contentRect.height ?? 0 };\n });\n\n if (stage.value) {\n observer.observe(stage.value);\n }\n});\nonBeforeUnmount(() => observer?.disconnect());\n\nconst scale = () => clamp((size.value.width - 48) / editor.frameWidth.value, 0.1, 1);\n</script>\n\n<template>\n <div ref=\"stage\" class=\"lze-stage lze-preview\">\n <div class=\"lze-sheet\" :style=\"{ width: `${editor.frameWidth.value * scale()}px`, height: `${size.height - 48}px` }\">\n <iframe\n class=\"lze-frame\"\n :title=\"editor.t('toolbar.preview')\"\n :srcdoc=\"html\"\n :style=\"{ width: `${editor.frameWidth.value}px`, height: `${(size.height - 48) / scale()}px`, transform: `scale(${scale()})` }\"\n />\n </div>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport { onBeforeUnmount, onMounted, ref, shallowRef, toRaw, watch } from 'vue';\nimport { clamp } from '../model/geometry.ts';\nimport { useEditor } from '../state/editor.ts';\nimport { renderContext, renderDraft } from './render.ts';\n\n/**\n * The page as visitors get it: the complete public document from core,\n * runtime included (tabs, modals, sticky navbar, animations), in an iframe at\n * the device width so viewport units and fixed positions behave as on a phone.\n */\nconst editor = useEditor();\nconst stage = ref<HTMLElement>();\nconst html = shallowRef('');\nconst size = ref({ width: 0, height: 0 });\nlet observer: ResizeObserver | null = null;\n\nasync function render() {\n const result = await renderDraft(toRaw(editor.state.draft), renderContext(editor), 'public');\n\n if (result.ok) {\n html.value = result.page.html;\n }\n}\n\nwatch([() => editor.state.draft, editor.previews.version], render, { deep: true, immediate: true });\n\nonMounted(() => {\n observer = new ResizeObserver(([entry]) => {\n size.value = { width: entry?.contentRect.width ?? 0, height: entry?.contentRect.height ?? 0 };\n });\n\n if (stage.value) {\n observer.observe(stage.value);\n }\n});\nonBeforeUnmount(() => observer?.disconnect());\n\nconst scale = () => clamp((size.value.width - 48) / editor.frameWidth.value, 0.1, 1);\n</script>\n\n<template>\n <div ref=\"stage\" class=\"lze-stage lze-preview\">\n <div class=\"lze-sheet\" :style=\"{ width: `${editor.frameWidth.value * scale()}px`, height: `${size.height - 48}px` }\">\n <iframe\n class=\"lze-frame\"\n :title=\"editor.t('toolbar.preview')\"\n :srcdoc=\"html\"\n :style=\"{ width: `${editor.frameWidth.value}px`, height: `${(size.height - 48) / scale()}px`, transform: `scale(${scale()})` }\"\n />\n </div>\n </div>\n</template>\n","import type { Issue } from '@skylivellc/lienzo-core';\nimport type { Protocol, Route } from '@skylivellc/lienzo-core/protocol';\n\n/** Why a request did not succeed. Every caller handles each kind, so none is ever silent. */\nexport type Failure =\n | { kind: 'offline' }\n | { kind: 'conflict'; message: string; revision: number }\n | { kind: 'invalid'; message: string; issues: Issue[] }\n | { kind: 'http'; status: number; message: string };\n\nexport type Result<T> = { ok: true; value: T } | { ok: false; failure: Failure };\n\n/** `'PUT /pages/:id/versions/:version'` → `'id' | 'version'`. */\ntype ParamNames<P extends string> = P extends `${string}:${infer Name}/${infer Rest}`\n ? Name | ParamNames<`/${Rest}`>\n : P extends `${string}:${infer Name}`\n ? Name\n : never;\n\nexport type Params<R extends Route> = { [K in ParamNames<R>]: string | number };\nexport type Body<R extends Route> = 'req' extends keyof Protocol[R] ? Protocol[R]['req' & keyof Protocol[R]] : undefined;\nexport type Response<R extends Route> = Protocol[R]['res'];\n\ntype BodyArgs<R extends Route> = undefined extends Body<R> ? [body?: Body<R>] : [body: Body<R>];\n\n/** A route call: params only when the path has some, a body only when the route takes one. */\nexport type Client = <R extends Route>(\n route: R,\n ...args: [ParamNames<R>] extends [never] ? BodyArgs<R> : [params: Params<R>, ...BodyArgs<R>]\n) => Promise<Result<Response<R>>>;\n\nexport type ClientOptions = {\n endpoint: string;\n headers?: Record<string, string>;\n fetch?: typeof fetch;\n};\n\n/**\n * Typed fetch over the protocol. Never retries writes and never throws:\n * a 409 becomes `conflict`, a 422 `invalid`, a network error `offline`.\n * Laravel's `XSRF-TOKEN` cookie is echoed as `X-XSRF-TOKEN`, like axios does,\n * so session-authenticated backends need no extra setup.\n */\nexport function createClient({ endpoint, headers = {}, fetch: fetcher = globalThis.fetch.bind(globalThis) }: ClientOptions): Client {\n const base = endpoint.replace(/\\/+$/, '');\n\n return async (route, ...args) => {\n const [method = 'GET', template = '/'] = route.split(' ');\n const [params, body]: [Record<string, unknown>, unknown] = template.includes(':')\n ? [isRecord(args[0]) ? args[0] : {}, args[1]]\n : [{}, args[0]];\n const path = template.replace(/:([a-z]+)/g, (_, name: string) => encodeURIComponent(String(params[name] ?? '')));\n const isForm = typeof FormData !== 'undefined' && body instanceof FormData;\n const query = method === 'GET' && body && typeof body === 'object' && !isForm ? searchParams(body) : '';\n const init: RequestInit = {\n method,\n credentials: 'same-origin',\n headers: {\n Accept: 'application/json',\n ...(body !== undefined && method !== 'GET' && !isForm ? { 'Content-Type': 'application/json' } : {}),\n ...xsrfHeader(),\n ...headers,\n },\n ...(body !== undefined && method !== 'GET' ? { body: isForm ? body : JSON.stringify(body) } : {}),\n };\n\n let response: globalThis.Response;\n\n try {\n response = await fetcher(`${base}${path === '/' ? '' : path}${query}`, init);\n } catch {\n return { ok: false, failure: { kind: 'offline' } };\n }\n\n const json: unknown = response.status === 204 ? null : await response.json().catch(() => null);\n\n if (response.ok) {\n // The backend implements the protocol; documents and settings inside are parsed again where they are used.\n return { ok: true, value: json as Response<typeof route> };\n }\n\n return { ok: false, failure: failureOf(response.status, json) };\n };\n}\n\nfunction failureOf(status: number, json: unknown): Failure {\n const message = isRecord(json) && typeof json.message === 'string' ? json.message : `HTTP ${status}`;\n\n if (status === 409 && isRecord(json) && typeof json.revision === 'number') {\n return { kind: 'conflict', message, revision: json.revision };\n }\n\n if (status === 422) {\n const issues = isRecord(json) && Array.isArray(json.issues) ? json.issues.filter(isIssue) : [];\n\n return { kind: 'invalid', message, issues };\n }\n\n return { kind: 'http', status, message };\n}\n\nfunction searchParams(body: object): string {\n const entries = Object.entries(body).filter(([, value]) => value !== undefined && value !== null);\n\n return entries.length === 0 ? '' : `?${new URLSearchParams(entries.map(([key, value]) => [key, String(value)]))}`;\n}\n\nfunction xsrfHeader(): Record<string, string> {\n const match = typeof document === 'undefined' ? null : /(?:^|;\\s*)XSRF-TOKEN=([^;]+)/.exec(document.cookie);\n\n return match?.[1] ? { 'X-XSRF-TOKEN': decodeURIComponent(match[1]) } : {};\n}\n\nconst isIssue = (value: unknown): value is Issue =>\n isRecord(value) && typeof value.path === 'string' && typeof value.message === 'string' && typeof value.code === 'string';\n\nconst isRecord = (value: unknown): value is Record<string, unknown> => typeof value === 'object' && value !== null && !Array.isArray(value);\n","<script setup lang=\"ts\">\n/** Text button of the editor chrome. `primary` is the one main action of a place. */\nwithDefaults(defineProps<{ variant?: 'primary' | 'outline' | 'ghost' | 'danger'; size?: 'sm' | 'md'; disabled?: boolean; title?: string }>(), {\n variant: 'outline',\n size: 'sm',\n disabled: false,\n title: undefined,\n});\n</script>\n\n<template>\n <button type=\"button\" class=\"lze-btn\" :data-variant=\"variant\" :data-size=\"size\" :disabled=\"disabled\" :title=\"title\"><slot /></button>\n</template>\n","<script setup lang=\"ts\">\n/** Text button of the editor chrome. `primary` is the one main action of a place. */\nwithDefaults(defineProps<{ variant?: 'primary' | 'outline' | 'ghost' | 'danger'; size?: 'sm' | 'md'; disabled?: boolean; title?: string }>(), {\n variant: 'outline',\n size: 'sm',\n disabled: false,\n title: undefined,\n});\n</script>\n\n<template>\n <button type=\"button\" class=\"lze-btn\" :data-variant=\"variant\" :data-size=\"size\" :disabled=\"disabled\" :title=\"title\"><slot /></button>\n</template>\n","<script setup lang=\"ts\">\nimport { X } from '@lucide/vue';\nimport { onMounted, ref, useId, watch } from 'vue';\nimport { useEditor } from '../state/editor.ts';\n\n/**\n * A modal dialog on the native `<dialog>`: focus trap, Escape and the top\n * layer for free, and it stays inside the editor's shadow root when there is one.\n */\nconst open = defineModel<boolean>('open', { required: true });\nwithDefaults(defineProps<{ title: string; description?: string; size?: 'md' | 'lg' | 'xl' }>(), { description: undefined, size: 'md' });\nconst dialog = ref<HTMLDialogElement>();\nconst heading = useId();\nconst { t } = useEditor();\n\nfunction sync() {\n if (open.value && !dialog.value?.open) {\n dialog.value?.showModal();\n } else if (!open.value && dialog.value?.open) {\n dialog.value.close();\n }\n}\n\nwatch(open, sync);\n\n/** A click closes on the backdrop only if it also started there, not when a text selection ends outside. */\nlet downOnBackdrop = false;\nconst pressed = (event: PointerEvent) => (downOnBackdrop = event.target === event.currentTarget);\nconst clicked = (event: MouseEvent) => {\n if (downOnBackdrop && event.target === event.currentTarget) {\n open.value = false;\n }\n};\nonMounted(sync);\n</script>\n\n<template>\n <dialog ref=\"dialog\" class=\"lze-dialog\" :data-size=\"size\" :aria-labelledby=\"heading\" @close=\"open = false\" @pointerdown=\"pressed\" @click=\"clicked\">\n <div class=\"lze-dialog-body\">\n <header class=\"lze-dialog-head\">\n <div>\n <h2 :id=\"heading\">{{ title }}</h2>\n <p v-if=\"description\" class=\"lze-hint\">{{ description }}</p>\n </div>\n <button type=\"button\" class=\"lze-icon-btn\" :aria-label=\"t('common.close')\" @click=\"open = false\"><X :size=\"16\" aria-hidden=\"true\" /></button>\n </header>\n <slot v-if=\"open\" />\n </div>\n </dialog>\n</template>\n","<script setup lang=\"ts\">\nimport { X } from '@lucide/vue';\nimport { onMounted, ref, useId, watch } from 'vue';\nimport { useEditor } from '../state/editor.ts';\n\n/**\n * A modal dialog on the native `<dialog>`: focus trap, Escape and the top\n * layer for free, and it stays inside the editor's shadow root when there is one.\n */\nconst open = defineModel<boolean>('open', { required: true });\nwithDefaults(defineProps<{ title: string; description?: string; size?: 'md' | 'lg' | 'xl' }>(), { description: undefined, size: 'md' });\nconst dialog = ref<HTMLDialogElement>();\nconst heading = useId();\nconst { t } = useEditor();\n\nfunction sync() {\n if (open.value && !dialog.value?.open) {\n dialog.value?.showModal();\n } else if (!open.value && dialog.value?.open) {\n dialog.value.close();\n }\n}\n\nwatch(open, sync);\n\n/** A click closes on the backdrop only if it also started there, not when a text selection ends outside. */\nlet downOnBackdrop = false;\nconst pressed = (event: PointerEvent) => (downOnBackdrop = event.target === event.currentTarget);\nconst clicked = (event: MouseEvent) => {\n if (downOnBackdrop && event.target === event.currentTarget) {\n open.value = false;\n }\n};\nonMounted(sync);\n</script>\n\n<template>\n <dialog ref=\"dialog\" class=\"lze-dialog\" :data-size=\"size\" :aria-labelledby=\"heading\" @close=\"open = false\" @pointerdown=\"pressed\" @click=\"clicked\">\n <div class=\"lze-dialog-body\">\n <header class=\"lze-dialog-head\">\n <div>\n <h2 :id=\"heading\">{{ title }}</h2>\n <p v-if=\"description\" class=\"lze-hint\">{{ description }}</p>\n </div>\n <button type=\"button\" class=\"lze-icon-btn\" :aria-label=\"t('common.close')\" @click=\"open = false\"><X :size=\"16\" aria-hidden=\"true\" /></button>\n </header>\n <slot v-if=\"open\" />\n </div>\n </dialog>\n</template>\n","<script setup lang=\"ts\">\nimport { useEditor } from '../state/editor.ts';\nimport Button from '../ui/Button.vue';\nimport Dialog from '../ui/Dialog.vue';\n\n/** Someone saved this page elsewhere: the only way on is to reload it. */\nconst editor = useEditor();\nconst open = editor.dialogModel('conflict');\n</script>\n\n<template>\n <Dialog v-model:open=\"open\" :title=\"editor.t('conflict.title')\" :description=\"editor.t('conflict.body')\">\n <div class=\"lze-dialog-actions\">\n <Button variant=\"primary\" size=\"md\" @click=\"editor.reloadPage()\">{{ editor.t('conflict.reload') }}</Button>\n <Button size=\"md\" @click=\"open = false\">{{ editor.t('common.close') }}</Button>\n </div>\n </Dialog>\n</template>\n","<script setup lang=\"ts\">\nimport { useEditor } from '../state/editor.ts';\nimport Button from '../ui/Button.vue';\nimport Dialog from '../ui/Dialog.vue';\n\n/** Someone saved this page elsewhere: the only way on is to reload it. */\nconst editor = useEditor();\nconst open = editor.dialogModel('conflict');\n</script>\n\n<template>\n <Dialog v-model:open=\"open\" :title=\"editor.t('conflict.title')\" :description=\"editor.t('conflict.body')\">\n <div class=\"lze-dialog-actions\">\n <Button variant=\"primary\" size=\"md\" @click=\"editor.reloadPage()\">{{ editor.t('conflict.reload') }}</Button>\n <Button size=\"md\" @click=\"open = false\">{{ editor.t('common.close') }}</Button>\n </div>\n </Dialog>\n</template>\n","<script setup lang=\"ts\">\n/** Square icon button with a tooltip; `active` shows a pressed state, like design tools. */\nwithDefaults(defineProps<{ label: string; active?: boolean; disabled?: boolean; tone?: 'default' | 'danger' }>(), { active: undefined, disabled: false, tone: 'default' });\n</script>\n\n<template>\n <button type=\"button\" class=\"lze-icon-btn\" :data-tone=\"tone\" :title=\"label\" :aria-label=\"label\" :aria-pressed=\"active\" :disabled=\"disabled\"><slot /></button>\n</template>\n","<script setup lang=\"ts\">\n/** Square icon button with a tooltip; `active` shows a pressed state, like design tools. */\nwithDefaults(defineProps<{ label: string; active?: boolean; disabled?: boolean; tone?: 'default' | 'danger' }>(), { active: undefined, disabled: false, tone: 'default' });\n</script>\n\n<template>\n <button type=\"button\" class=\"lze-icon-btn\" :data-tone=\"tone\" :title=\"label\" :aria-label=\"label\" :aria-pressed=\"active\" :disabled=\"disabled\"><slot /></button>\n</template>\n","<script setup lang=\"ts\">\nimport type { Asset } from '@skylivellc/lienzo-core/protocol';\nimport { Trash2, Upload } from '@lucide/vue';\nimport { computed, ref } from 'vue';\nimport { useEditor } from '../state/editor.ts';\nimport Dialog from '../ui/Dialog.vue';\nimport IconButton from '../ui/IconButton.vue';\n\n/**\n * The site's images: upload, pick and delete. Opened by whoever needs an\n * image (`state.library.onPick`); opened on its own, picking adds an image element.\n */\nconst editor = useEditor();\nconst t = editor.t;\nconst input = ref<HTMLInputElement>();\nconst uploading = ref(false);\n\nconst open = computed({\n get: () => editor.state.library !== null,\n set: (value) => {\n if (!value) {\n editor.state.library = null;\n }\n },\n});\n\nconst UNITS = ['byte', 'kilobyte', 'megabyte', 'gigabyte'] as const;\n\n/** Bytes in the largest unit that keeps the number at or above 1, in the editor's language. */\nfunction bytes(value: number): string {\n const step = Math.min(UNITS.length - 1, Math.max(0, Math.floor(Math.log(Math.max(value, 1)) / Math.log(1024))));\n\n return new Intl.NumberFormat(editor.i18n.locale, { style: 'unit', unit: UNITS[step], unitDisplay: 'short', maximumFractionDigits: 1 }).format(value / 1024 ** step);\n}\n\nconst quota = computed(() => {\n const { used, limit } = editor.state.workspace.quota;\n\n return limit > 0 ? t('library.quota', { used: bytes(used), limit: bytes(limit) }) : null;\n});\n\nasync function upload(event: Event) {\n const file = (event.target as HTMLInputElement).files?.[0];\n\n if (!file) {\n return;\n }\n\n uploading.value = true;\n await editor.uploadAsset(file);\n uploading.value = false;\n\n if (input.value) {\n input.value.value = '';\n }\n}\n\nfunction use(asset: Asset) {\n const onPick = editor.state.library?.onPick;\n\n if (onPick) {\n onPick(asset.ref);\n } else {\n editor.addElement({ kind: 'core', type: 'image' }, undefined, asset.ref);\n }\n\n open.value = false;\n}\n</script>\n\n<template>\n <Dialog v-model:open=\"open\" :title=\"t('library.title')\" :description=\"t('library.description')\" size=\"lg\">\n <div class=\"lze-asset-grid\">\n <button type=\"button\" class=\"lze-upload-tile\" :disabled=\"uploading\" @click=\"input?.click()\">\n <Upload :size=\"20\" aria-hidden=\"true\" />\n <strong>{{ uploading ? t('library.uploading') : t('library.upload') }}</strong>\n <span class=\"lze-hint\">{{ t('library.formats') }}</span>\n </button>\n <input ref=\"input\" type=\"file\" class=\"lze-file-input\" tabindex=\"-1\" aria-hidden=\"true\" accept=\".jpg,.jpeg,.png,.webp,.avif,.svg\" @change=\"upload\" />\n <figure v-for=\"asset in editor.state.workspace.assets\" :key=\"asset.id\" class=\"lze-asset\">\n <button type=\"button\" class=\"lze-asset-use\" :aria-label=\"t('library.use', { name: asset.name })\" @click=\"use(asset)\">\n <img :src=\"asset.thumb\" :alt=\"asset.name\" loading=\"lazy\" />\n <figcaption>{{ asset.name }}</figcaption>\n </button>\n <IconButton class=\"lze-asset-delete\" tone=\"danger\" :label=\"t('library.delete', { name: asset.name })\" @click=\"editor.deleteAsset(asset)\">\n <Trash2 :size=\"14\" aria-hidden=\"true\" />\n </IconButton>\n </figure>\n </div>\n <p v-if=\"editor.state.workspace.assets.length === 0\" class=\"lze-hint\">{{ t('media.empty') }}</p>\n <p v-if=\"quota\" class=\"lze-hint\">{{ quota }}</p>\n </Dialog>\n</template>\n","<script setup lang=\"ts\">\nimport type { Asset } from '@skylivellc/lienzo-core/protocol';\nimport { Trash2, Upload } from '@lucide/vue';\nimport { computed, ref } from 'vue';\nimport { useEditor } from '../state/editor.ts';\nimport Dialog from '../ui/Dialog.vue';\nimport IconButton from '../ui/IconButton.vue';\n\n/**\n * The site's images: upload, pick and delete. Opened by whoever needs an\n * image (`state.library.onPick`); opened on its own, picking adds an image element.\n */\nconst editor = useEditor();\nconst t = editor.t;\nconst input = ref<HTMLInputElement>();\nconst uploading = ref(false);\n\nconst open = computed({\n get: () => editor.state.library !== null,\n set: (value) => {\n if (!value) {\n editor.state.library = null;\n }\n },\n});\n\nconst UNITS = ['byte', 'kilobyte', 'megabyte', 'gigabyte'] as const;\n\n/** Bytes in the largest unit that keeps the number at or above 1, in the editor's language. */\nfunction bytes(value: number): string {\n const step = Math.min(UNITS.length - 1, Math.max(0, Math.floor(Math.log(Math.max(value, 1)) / Math.log(1024))));\n\n return new Intl.NumberFormat(editor.i18n.locale, { style: 'unit', unit: UNITS[step], unitDisplay: 'short', maximumFractionDigits: 1 }).format(value / 1024 ** step);\n}\n\nconst quota = computed(() => {\n const { used, limit } = editor.state.workspace.quota;\n\n return limit > 0 ? t('library.quota', { used: bytes(used), limit: bytes(limit) }) : null;\n});\n\nasync function upload(event: Event) {\n const file = (event.target as HTMLInputElement).files?.[0];\n\n if (!file) {\n return;\n }\n\n uploading.value = true;\n await editor.uploadAsset(file);\n uploading.value = false;\n\n if (input.value) {\n input.value.value = '';\n }\n}\n\nfunction use(asset: Asset) {\n const onPick = editor.state.library?.onPick;\n\n if (onPick) {\n onPick(asset.ref);\n } else {\n editor.addElement({ kind: 'core', type: 'image' }, undefined, asset.ref);\n }\n\n open.value = false;\n}\n</script>\n\n<template>\n <Dialog v-model:open=\"open\" :title=\"t('library.title')\" :description=\"t('library.description')\" size=\"lg\">\n <div class=\"lze-asset-grid\">\n <button type=\"button\" class=\"lze-upload-tile\" :disabled=\"uploading\" @click=\"input?.click()\">\n <Upload :size=\"20\" aria-hidden=\"true\" />\n <strong>{{ uploading ? t('library.uploading') : t('library.upload') }}</strong>\n <span class=\"lze-hint\">{{ t('library.formats') }}</span>\n </button>\n <input ref=\"input\" type=\"file\" class=\"lze-file-input\" tabindex=\"-1\" aria-hidden=\"true\" accept=\".jpg,.jpeg,.png,.webp,.avif,.svg\" @change=\"upload\" />\n <figure v-for=\"asset in editor.state.workspace.assets\" :key=\"asset.id\" class=\"lze-asset\">\n <button type=\"button\" class=\"lze-asset-use\" :aria-label=\"t('library.use', { name: asset.name })\" @click=\"use(asset)\">\n <img :src=\"asset.thumb\" :alt=\"asset.name\" loading=\"lazy\" />\n <figcaption>{{ asset.name }}</figcaption>\n </button>\n <IconButton class=\"lze-asset-delete\" tone=\"danger\" :label=\"t('library.delete', { name: asset.name })\" @click=\"editor.deleteAsset(asset)\">\n <Trash2 :size=\"14\" aria-hidden=\"true\" />\n </IconButton>\n </figure>\n </div>\n <p v-if=\"editor.state.workspace.assets.length === 0\" class=\"lze-hint\">{{ t('media.empty') }}</p>\n <p v-if=\"quota\" class=\"lze-hint\">{{ quota }}</p>\n </Dialog>\n</template>\n","<script setup lang=\"ts\">\n/** A labelled control with an optional hint and error. Put the control in the default slot with `:id=\"id\"`. */\ndefineProps<{ label: string; id?: string; hint?: string; error?: string | null }>();\n</script>\n\n<template>\n <div class=\"lze-field\">\n <label v-if=\"id\" class=\"lze-label\" :for=\"id\">{{ label }}<slot name=\"aside\" /></label>\n <span v-else class=\"lze-label\">{{ label }}<slot name=\"aside\" /></span>\n <slot />\n <p v-if=\"error\" class=\"lze-error\" role=\"alert\">{{ error }}</p>\n <p v-else-if=\"hint\" class=\"lze-hint\">{{ hint }}</p>\n </div>\n</template>\n","<script setup lang=\"ts\">\n/** A labelled control with an optional hint and error. Put the control in the default slot with `:id=\"id\"`. */\ndefineProps<{ label: string; id?: string; hint?: string; error?: string | null }>();\n</script>\n\n<template>\n <div class=\"lze-field\">\n <label v-if=\"id\" class=\"lze-label\" :for=\"id\">{{ label }}<slot name=\"aside\" /></label>\n <span v-else class=\"lze-label\">{{ label }}<slot name=\"aside\" /></span>\n <slot />\n <p v-if=\"error\" class=\"lze-error\" role=\"alert\">{{ error }}</p>\n <p v-else-if=\"hint\" class=\"lze-hint\">{{ hint }}</p>\n </div>\n</template>\n","<script setup lang=\"ts\">\n/**\n * Single or multi-line text. `commit` fires on change (blur or Enter), which\n * is when callers record an undo step; the model updates on every keystroke.\n */\nconst model = defineModel<string | null | undefined>({ required: true });\nwithDefaults(defineProps<{ id?: string; placeholder?: string; maxlength?: number; rows?: number; label?: string; type?: string }>(), {\n id: undefined,\n placeholder: undefined,\n maxlength: undefined,\n rows: 0,\n label: undefined,\n type: 'text',\n});\nconst emit = defineEmits<{ commit: [] }>();\n</script>\n\n<template>\n <textarea v-if=\"rows > 0\" :id=\"id\" v-model=\"model\" class=\"lze-input\" :rows=\"rows\" :maxlength=\"maxlength\" :placeholder=\"placeholder\" :aria-label=\"label\" @change=\"emit('commit')\" />\n <input v-else :id=\"id\" v-model=\"model\" class=\"lze-input\" :type=\"type\" :maxlength=\"maxlength\" :placeholder=\"placeholder\" :aria-label=\"label\" @change=\"emit('commit')\" />\n</template>\n","<script setup lang=\"ts\">\n/**\n * Single or multi-line text. `commit` fires on change (blur or Enter), which\n * is when callers record an undo step; the model updates on every keystroke.\n */\nconst model = defineModel<string | null | undefined>({ required: true });\nwithDefaults(defineProps<{ id?: string; placeholder?: string; maxlength?: number; rows?: number; label?: string; type?: string }>(), {\n id: undefined,\n placeholder: undefined,\n maxlength: undefined,\n rows: 0,\n label: undefined,\n type: 'text',\n});\nconst emit = defineEmits<{ commit: [] }>();\n</script>\n\n<template>\n <textarea v-if=\"rows > 0\" :id=\"id\" v-model=\"model\" class=\"lze-input\" :rows=\"rows\" :maxlength=\"maxlength\" :placeholder=\"placeholder\" :aria-label=\"label\" @change=\"emit('commit')\" />\n <input v-else :id=\"id\" v-model=\"model\" class=\"lze-input\" :type=\"type\" :maxlength=\"maxlength\" :placeholder=\"placeholder\" :aria-label=\"label\" @change=\"emit('commit')\" />\n</template>\n","<script setup lang=\"ts\">\nimport type { Issue } from '@skylivellc/lienzo-core';\nimport { computed, reactive, useId, watch } from 'vue';\nimport { useEditor } from '../state/editor.ts';\nimport Button from '../ui/Button.vue';\nimport Dialog from '../ui/Dialog.vue';\nimport Field from '../ui/Field.vue';\nimport TextInput from '../ui/TextInput.vue';\n\n/** Creates a page at its own address; the backend checks the address is free. */\nconst editor = useEditor();\nconst t = editor.t;\nconst ids = { title: useId(), slug: useId() };\nconst open = editor.dialogModel('newPage');\n\nconst form = reactive({ title: '', slug: '', issues: [] as Issue[], creating: false });\nwatch(open, (now) => {\n if (now) {\n Object.assign(form, { title: '', slug: '', issues: [], creating: false });\n }\n});\n\n/** Where the page will live, resolved against the site root like the published links. */\nconst address = computed(() => {\n const slug = form.slug.trim() || t('newPage.slugFallback');\n\n return editor.state.workspace.publicUrl ? new URL(slug, editor.state.workspace.publicUrl).href : `/${slug}`;\n});\n\nconst issueAt = (path: string) => form.issues.filter((issue) => issue.path === path).map((issue) => issue.message).join(' ') || null;\nconst otherIssues = computed(() => form.issues.filter((issue) => issue.path !== 'title' && issue.path !== 'slug'));\n\nasync function create() {\n form.creating = true;\n form.issues = await editor.createPage(form.title.trim(), form.slug.trim());\n form.creating = false;\n}\n</script>\n\n<template>\n <Dialog v-model:open=\"open\" :title=\"t('newPage.title')\" :description=\"t('newPage.description')\">\n <form class=\"lze-stack\" novalidate @submit.prevent=\"create\">\n <Field :id=\"ids.title\" :label=\"t('newPage.titleLabel')\" :error=\"issueAt('title')\">\n <TextInput :id=\"ids.title\" v-model=\"form.title\" :maxlength=\"120\" />\n </Field>\n <Field :id=\"ids.slug\" :label=\"t('newPage.slug')\" :error=\"issueAt('slug')\" :hint=\"t('newPage.at', { url: address })\">\n <TextInput :id=\"ids.slug\" v-model=\"form.slug\" :maxlength=\"120\" :placeholder=\"t('newPage.slugPlaceholder')\" />\n </Field>\n <p v-for=\"issue in otherIssues\" :key=\"issue.path + issue.message\" class=\"lze-error\" role=\"alert\">{{ issue.message }}</p>\n <div class=\"lze-dialog-actions\">\n <Button variant=\"primary\" size=\"md\" type=\"submit\" :disabled=\"form.creating\">{{ t('newPage.create') }}</Button>\n <Button size=\"md\" @click=\"open = false\">{{ t('common.cancel') }}</Button>\n </div>\n </form>\n </Dialog>\n</template>\n","<script setup lang=\"ts\">\nimport type { Issue } from '@skylivellc/lienzo-core';\nimport { computed, reactive, useId, watch } from 'vue';\nimport { useEditor } from '../state/editor.ts';\nimport Button from '../ui/Button.vue';\nimport Dialog from '../ui/Dialog.vue';\nimport Field from '../ui/Field.vue';\nimport TextInput from '../ui/TextInput.vue';\n\n/** Creates a page at its own address; the backend checks the address is free. */\nconst editor = useEditor();\nconst t = editor.t;\nconst ids = { title: useId(), slug: useId() };\nconst open = editor.dialogModel('newPage');\n\nconst form = reactive({ title: '', slug: '', issues: [] as Issue[], creating: false });\nwatch(open, (now) => {\n if (now) {\n Object.assign(form, { title: '', slug: '', issues: [], creating: false });\n }\n});\n\n/** Where the page will live, resolved against the site root like the published links. */\nconst address = computed(() => {\n const slug = form.slug.trim() || t('newPage.slugFallback');\n\n return editor.state.workspace.publicUrl ? new URL(slug, editor.state.workspace.publicUrl).href : `/${slug}`;\n});\n\nconst issueAt = (path: string) => form.issues.filter((issue) => issue.path === path).map((issue) => issue.message).join(' ') || null;\nconst otherIssues = computed(() => form.issues.filter((issue) => issue.path !== 'title' && issue.path !== 'slug'));\n\nasync function create() {\n form.creating = true;\n form.issues = await editor.createPage(form.title.trim(), form.slug.trim());\n form.creating = false;\n}\n</script>\n\n<template>\n <Dialog v-model:open=\"open\" :title=\"t('newPage.title')\" :description=\"t('newPage.description')\">\n <form class=\"lze-stack\" novalidate @submit.prevent=\"create\">\n <Field :id=\"ids.title\" :label=\"t('newPage.titleLabel')\" :error=\"issueAt('title')\">\n <TextInput :id=\"ids.title\" v-model=\"form.title\" :maxlength=\"120\" />\n </Field>\n <Field :id=\"ids.slug\" :label=\"t('newPage.slug')\" :error=\"issueAt('slug')\" :hint=\"t('newPage.at', { url: address })\">\n <TextInput :id=\"ids.slug\" v-model=\"form.slug\" :maxlength=\"120\" :placeholder=\"t('newPage.slugPlaceholder')\" />\n </Field>\n <p v-for=\"issue in otherIssues\" :key=\"issue.path + issue.message\" class=\"lze-error\" role=\"alert\">{{ issue.message }}</p>\n <div class=\"lze-dialog-actions\">\n <Button variant=\"primary\" size=\"md\" type=\"submit\" :disabled=\"form.creating\">{{ t('newPage.create') }}</Button>\n <Button size=\"md\" @click=\"open = false\">{{ t('common.cancel') }}</Button>\n </div>\n </form>\n </Dialog>\n</template>\n","<script setup lang=\"ts\">\nimport { computed } from 'vue';\nimport { useEditor } from '../state/editor.ts';\nimport Button from './Button.vue';\nimport TextInput from './TextInput.vue';\n\n/**\n * An image reference (`media:<id>` from the library, or an https URL) with a\n * thumbnail, a library picker and a remove button. `url` adds a field to paste an address.\n */\nconst model = defineModel<string | null | undefined>({ required: true });\nconst props = withDefaults(defineProps<{ label: string; url?: boolean; choose?: string; thumb?: 'wide' | 'icon' }>(), { url: false, choose: undefined, thumb: 'wide' });\nconst emit = defineEmits<{ commit: [] }>();\nconst editor = useEditor();\n\nconst preview = computed(() => {\n const value = model.value;\n\n if (!value) {\n return null;\n }\n\n return value.startsWith('media:') ? (editor.state.workspace.assets.find((asset) => asset.ref === value)?.thumb ?? null) : value;\n});\n\n/** The address field shows pasted URLs only; a library pick is shown by its thumbnail. */\nconst address = computed(() => (model.value && !model.value.startsWith('media:') ? model.value : ''));\n\nfunction pick() {\n editor.openLibrary((ref) => {\n model.value = ref;\n emit('commit');\n });\n}\n\nfunction remove() {\n model.value = null;\n emit('commit');\n}\n</script>\n\n<template>\n <div class=\"lze-field\" role=\"group\" :aria-label=\"props.label\">\n <span class=\"lze-label\">{{ props.label }}</span>\n <div v-if=\"preview\" class=\"lze-image-preview\" :data-thumb=\"thumb\"><img :src=\"preview\" alt=\"\" /></div>\n <div class=\"lze-row\">\n <Button @click=\"pick\">{{ choose ?? editor.t('el.chooseFromLibrary') }}</Button>\n <Button v-if=\"model\" variant=\"ghost\" @click=\"remove\">{{ editor.t('common.remove') }}</Button>\n </div>\n <TextInput\n v-if=\"url\"\n :model-value=\"address\"\n type=\"url\"\n :maxlength=\"500\"\n :placeholder=\"editor.t('el.imageUrl')\"\n :label=\"editor.t('el.imageUrl')\"\n @update:model-value=\"model = $event\"\n @commit=\"emit('commit')\"\n />\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport { computed } from 'vue';\nimport { useEditor } from '../state/editor.ts';\nimport Button from './Button.vue';\nimport TextInput from './TextInput.vue';\n\n/**\n * An image reference (`media:<id>` from the library, or an https URL) with a\n * thumbnail, a library picker and a remove button. `url` adds a field to paste an address.\n */\nconst model = defineModel<string | null | undefined>({ required: true });\nconst props = withDefaults(defineProps<{ label: string; url?: boolean; choose?: string; thumb?: 'wide' | 'icon' }>(), { url: false, choose: undefined, thumb: 'wide' });\nconst emit = defineEmits<{ commit: [] }>();\nconst editor = useEditor();\n\nconst preview = computed(() => {\n const value = model.value;\n\n if (!value) {\n return null;\n }\n\n return value.startsWith('media:') ? (editor.state.workspace.assets.find((asset) => asset.ref === value)?.thumb ?? null) : value;\n});\n\n/** The address field shows pasted URLs only; a library pick is shown by its thumbnail. */\nconst address = computed(() => (model.value && !model.value.startsWith('media:') ? model.value : ''));\n\nfunction pick() {\n editor.openLibrary((ref) => {\n model.value = ref;\n emit('commit');\n });\n}\n\nfunction remove() {\n model.value = null;\n emit('commit');\n}\n</script>\n\n<template>\n <div class=\"lze-field\" role=\"group\" :aria-label=\"props.label\">\n <span class=\"lze-label\">{{ props.label }}</span>\n <div v-if=\"preview\" class=\"lze-image-preview\" :data-thumb=\"thumb\"><img :src=\"preview\" alt=\"\" /></div>\n <div class=\"lze-row\">\n <Button @click=\"pick\">{{ choose ?? editor.t('el.chooseFromLibrary') }}</Button>\n <Button v-if=\"model\" variant=\"ghost\" @click=\"remove\">{{ editor.t('common.remove') }}</Button>\n </div>\n <TextInput\n v-if=\"url\"\n :model-value=\"address\"\n type=\"url\"\n :maxlength=\"500\"\n :placeholder=\"editor.t('el.imageUrl')\"\n :label=\"editor.t('el.imageUrl')\"\n @update:model-value=\"model = $event\"\n @commit=\"emit('commit')\"\n />\n </div>\n</template>\n","<script setup lang=\"ts\">\n/** Compact number field: short label on the left, unit on the right. Empty means \"not set\". */\nconst model = defineModel<number | null | undefined>({ required: true });\nconst props = defineProps<{ label: string; min?: number; max?: number; step?: number; suffix?: string; disabled?: boolean }>();\nconst emit = defineEmits<{ commit: [] }>();\n\nfunction input(event: Event) {\n const raw = (event.target as HTMLInputElement).value;\n const value = Number(raw);\n\n if (raw === '') {\n model.value = undefined;\n } else if (Number.isFinite(value)) {\n model.value = Math.min(props.max ?? Infinity, Math.max(props.min ?? -Infinity, value));\n }\n}\n</script>\n\n<template>\n <label class=\"lze-number\">\n <span class=\"lze-number-label\">{{ label }}</span>\n <input type=\"number\" :value=\"model ?? ''\" :min=\"min\" :max=\"max\" :step=\"step\" :disabled=\"disabled\" @input=\"input\" @change=\"emit('commit')\" />\n <span v-if=\"suffix\" class=\"lze-number-suffix\">{{ suffix }}</span>\n </label>\n</template>\n","<script setup lang=\"ts\">\n/** Compact number field: short label on the left, unit on the right. Empty means \"not set\". */\nconst model = defineModel<number | null | undefined>({ required: true });\nconst props = defineProps<{ label: string; min?: number; max?: number; step?: number; suffix?: string; disabled?: boolean }>();\nconst emit = defineEmits<{ commit: [] }>();\n\nfunction input(event: Event) {\n const raw = (event.target as HTMLInputElement).value;\n const value = Number(raw);\n\n if (raw === '') {\n model.value = undefined;\n } else if (Number.isFinite(value)) {\n model.value = Math.min(props.max ?? Infinity, Math.max(props.min ?? -Infinity, value));\n }\n}\n</script>\n\n<template>\n <label class=\"lze-number\">\n <span class=\"lze-number-label\">{{ label }}</span>\n <input type=\"number\" :value=\"model ?? ''\" :min=\"min\" :max=\"max\" :step=\"step\" :disabled=\"disabled\" @input=\"input\" @change=\"emit('commit')\" />\n <span v-if=\"suffix\" class=\"lze-number-suffix\">{{ suffix }}</span>\n </label>\n</template>\n","<script setup lang=\"ts\" generic=\"T extends string | number\">\n/** Native select over typed options; the model keeps the option's own type. */\nconst model = defineModel<T | null | undefined>({ required: true });\nconst props = defineProps<{ options: readonly { value: T; label: string }[]; id?: string; label?: string; placeholder?: string; compact?: boolean }>();\nconst emit = defineEmits<{ commit: [] }>();\n\nfunction change(event: Event) {\n const index = (event.target as HTMLSelectElement).selectedIndex - (props.placeholder ? 1 : 0);\n const option = props.options[index];\n\n if (option) {\n model.value = option.value;\n emit('commit');\n }\n}\n</script>\n\n<template>\n <select :id=\"id\" class=\"lze-select\" :data-compact=\"compact\" :aria-label=\"label\" @change=\"change\">\n <option v-if=\"placeholder\" value=\"\" disabled :selected=\"model === null || model === undefined || model === ''\">{{ placeholder }}</option>\n <option v-for=\"option in options\" :key=\"option.value\" :selected=\"option.value === model\">{{ option.label }}</option>\n </select>\n</template>\n","<script setup lang=\"ts\" generic=\"T extends string | number\">\n/** Native select over typed options; the model keeps the option's own type. */\nconst model = defineModel<T | null | undefined>({ required: true });\nconst props = defineProps<{ options: readonly { value: T; label: string }[]; id?: string; label?: string; placeholder?: string; compact?: boolean }>();\nconst emit = defineEmits<{ commit: [] }>();\n\nfunction change(event: Event) {\n const index = (event.target as HTMLSelectElement).selectedIndex - (props.placeholder ? 1 : 0);\n const option = props.options[index];\n\n if (option) {\n model.value = option.value;\n emit('commit');\n }\n}\n</script>\n\n<template>\n <select :id=\"id\" class=\"lze-select\" :data-compact=\"compact\" :aria-label=\"label\" @change=\"change\">\n <option v-if=\"placeholder\" value=\"\" disabled :selected=\"model === null || model === undefined || model === ''\">{{ placeholder }}</option>\n <option v-for=\"option in options\" :key=\"option.value\" :selected=\"option.value === model\">{{ option.label }}</option>\n </select>\n</template>\n","<script setup lang=\"ts\">\n/** Checkbox with its label. Toggling is a discrete edit, so it commits right away. */\nconst model = defineModel<boolean | null | undefined>({ required: true });\ndefineProps<{ label: string }>();\nconst emit = defineEmits<{ commit: [] }>();\n</script>\n\n<template>\n <label class=\"lze-toggle\">\n <input type=\"checkbox\" :checked=\"model === true\" @change=\"model = ($event.target as HTMLInputElement).checked; emit('commit')\" />\n <span>{{ label }}</span>\n </label>\n</template>\n","<script setup lang=\"ts\">\n/** Checkbox with its label. Toggling is a discrete edit, so it commits right away. */\nconst model = defineModel<boolean | null | undefined>({ required: true });\ndefineProps<{ label: string }>();\nconst emit = defineEmits<{ commit: [] }>();\n</script>\n\n<template>\n <label class=\"lze-toggle\">\n <input type=\"checkbox\" :checked=\"model === true\" @change=\"model = ($event.target as HTMLInputElement).checked; emit('commit')\" />\n <span>{{ label }}</span>\n </label>\n</template>\n","import type { CoreActionType, Field } from '@skylivellc/lienzo-core';\nimport type { MessageKey } from '../i18n/index.ts';\n\n/** How the value of a core action is edited, by what core does with it. */\ntype ValueControl =\n | { kind: 'none' }\n | { kind: 'submit' }\n | { kind: 'text'; placeholder: MessageKey }\n | { kind: 'anchor' }\n | { kind: 'modal' }\n | { kind: 'page' };\n\n/** The value control of each core action. Labels are `action.<type>`; core's own order is the picker's. */\nexport const CORE_ACTIONS = {\n none: { kind: 'none' },\n whatsapp: { kind: 'text', placeholder: 'action.placeholder.whatsapp' },\n phone: { kind: 'text', placeholder: 'action.placeholder.phone' },\n email: { kind: 'text', placeholder: 'action.placeholder.email' },\n url: { kind: 'text', placeholder: 'action.placeholder.url' },\n anchor: { kind: 'anchor' },\n modal: { kind: 'modal' },\n submit: { kind: 'submit' },\n page: { kind: 'page' },\n top: { kind: 'none' },\n back: { kind: 'none' },\n step_next: { kind: 'none' },\n step_prev: { kind: 'none' },\n} as const satisfies Record<CoreActionType, ValueControl>;\n\nexport const isCoreAction = (type: string): type is CoreActionType => Object.hasOwn(CORE_ACTIONS, type);\n\n/** An app action's value is stored as a string in `action.value`; this is its starting value. */\nexport function defaultActionValue(field: Exclude<Field, { kind: 'action' }> | null): string {\n if (!field || field.kind === 'image') {\n return '';\n }\n\n return field.default === undefined ? '' : String(field.default);\n}\n","<script setup lang=\"ts\">\nimport { CORE_ACTION_TYPES, type Action, type FieldValue } from '@skylivellc/lienzo-core';\nimport { computed, useId } from 'vue';\nimport { useEditor } from '../state/editor.ts';\nimport SelectInput from '../ui/SelectInput.vue';\nimport TextInput from '../ui/TextInput.vue';\nimport { CORE_ACTIONS, defaultActionValue, isCoreAction } from './actions.ts';\nimport FieldControl from './FieldControl.vue';\n\n/**\n * What a click does: a core action or one the app registered, plus the value\n * it needs (a modal, a page, a number...). Used by buttons, menu links and\n * app fields of kind `action`. Emits a whole new action on every change.\n */\nconst props = defineProps<{ modelValue: Action | null | undefined; label: string }>();\nconst emit = defineEmits<{ 'update:modelValue': [action: { type: string; value: string }]; commit: [] }>();\nconst editor = useEditor();\nconst t = editor.t;\nconst sections = useId();\n\nconst type = computed(() => props.modelValue?.type || 'none');\nconst value = computed(() => props.modelValue?.value ?? '');\nconst app = computed(() => editor.catalog.value.actions.find((spec) => spec.type === type.value) ?? null);\nconst control = computed(() => (isCoreAction(type.value) ? CORE_ACTIONS[type.value] : null));\n\n/** Core actions first, then the app's; an action whose plugin is gone stays listed so it is not lost silently. */\nconst options = computed(() => {\n const list = [\n ...CORE_ACTION_TYPES.map((core) => ({ value: core, label: t(`action.${core}`) })),\n ...editor.catalog.value.actions.map((spec) => ({ value: spec.type, label: editor.i18n.localized(spec.label) })),\n ];\n\n return list.some((option) => option.value === type.value) ? list : [...list, { value: type.value, label: t('action.unknown', { type: type.value }) }];\n});\n\nconst modals = computed(() => (editor.state.draft.modals ?? []).map((modal) => ({ value: modal.id, label: modal.title })));\n// Core turns a page action into `/<slug>`; the home page has no slug, so it is written as `/`.\nconst pages = computed(() => editor.state.workspace.pages.map((page) => ({ value: page.slug || '/', label: page.slug ? `${page.title} /${page.slug}` : page.title })));\n\nfunction setType(next: string) {\n const spec = editor.catalog.value.actions.find((candidate) => candidate.type === next);\n // Switching between core actions keeps the value: a number typed for WhatsApp also works to call.\n emit('update:modelValue', { type: next, value: spec ? defaultActionValue(spec.value) : value.value });\n emit('commit');\n}\n\nfunction setValue(next: FieldValue | undefined) {\n emit('update:modelValue', { type: type.value, value: next === null || next === undefined || typeof next === 'object' ? '' : String(next) });\n}\n\n/** App action values live in a string; the field control wants them in the field's own type. */\nconst appValue = computed((): FieldValue => {\n const field = app.value?.value;\n\n if (field?.kind === 'number') {\n return value.value === '' ? field.default : Number(value.value);\n }\n\n if (field?.kind === 'toggle') {\n return value.value === '' ? field.default : value.value === 'true';\n }\n\n return value.value;\n});\n</script>\n\n<template>\n <div class=\"lze-field\">\n <SelectInput :model-value=\"type\" :options=\"options\" :label=\"label\" @update:model-value=\"setType(String($event ?? 'none'))\" />\n <template v-if=\"control\">\n <TextInput\n v-if=\"control.kind === 'text'\"\n :model-value=\"value\"\n :maxlength=\"300\"\n :placeholder=\"t(control.placeholder)\"\n :label=\"t('action.target')\"\n @update:model-value=\"setValue($event)\"\n @commit=\"emit('commit')\"\n />\n <template v-else-if=\"control.kind === 'anchor'\">\n <TextInput\n :model-value=\"value\"\n :maxlength=\"300\"\n :placeholder=\"t('action.placeholder.anchor')\"\n :label=\"t('action.placeholder.anchor')\"\n :list=\"sections\"\n @update:model-value=\"setValue($event)\"\n @commit=\"emit('commit')\"\n />\n <datalist :id=\"sections\">\n <option v-for=\"section in editor.state.draft.sections\" :key=\"section.id\" :value=\"section.id\" />\n </datalist>\n </template>\n <SelectInput\n v-else-if=\"control.kind === 'modal'\"\n :model-value=\"value\"\n :options=\"modals\"\n :label=\"t('action.chooseModal')\"\n :placeholder=\"t('action.chooseModal')\"\n @update:model-value=\"setValue($event)\"\n @commit=\"emit('commit')\"\n />\n <SelectInput\n v-else-if=\"control.kind === 'page'\"\n :model-value=\"value\"\n :options=\"pages\"\n :label=\"t('action.choosePage')\"\n :placeholder=\"t('action.choosePage')\"\n @update:model-value=\"setValue($event)\"\n @commit=\"emit('commit')\"\n />\n <p v-else-if=\"control.kind === 'submit'\" class=\"lze-hint\">{{ t('action.submitHint') }}</p>\n </template>\n <FieldControl\n v-else-if=\"app?.value\"\n :field=\"app.value\"\n :model-value=\"appValue\"\n @update:model-value=\"setValue($event)\"\n @commit=\"emit('commit')\"\n />\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport { CORE_ACTION_TYPES, type Action, type FieldValue } from '@skylivellc/lienzo-core';\nimport { computed, useId } from 'vue';\nimport { useEditor } from '../state/editor.ts';\nimport SelectInput from '../ui/SelectInput.vue';\nimport TextInput from '../ui/TextInput.vue';\nimport { CORE_ACTIONS, defaultActionValue, isCoreAction } from './actions.ts';\nimport FieldControl from './FieldControl.vue';\n\n/**\n * What a click does: a core action or one the app registered, plus the value\n * it needs (a modal, a page, a number...). Used by buttons, menu links and\n * app fields of kind `action`. Emits a whole new action on every change.\n */\nconst props = defineProps<{ modelValue: Action | null | undefined; label: string }>();\nconst emit = defineEmits<{ 'update:modelValue': [action: { type: string; value: string }]; commit: [] }>();\nconst editor = useEditor();\nconst t = editor.t;\nconst sections = useId();\n\nconst type = computed(() => props.modelValue?.type || 'none');\nconst value = computed(() => props.modelValue?.value ?? '');\nconst app = computed(() => editor.catalog.value.actions.find((spec) => spec.type === type.value) ?? null);\nconst control = computed(() => (isCoreAction(type.value) ? CORE_ACTIONS[type.value] : null));\n\n/** Core actions first, then the app's; an action whose plugin is gone stays listed so it is not lost silently. */\nconst options = computed(() => {\n const list = [\n ...CORE_ACTION_TYPES.map((core) => ({ value: core, label: t(`action.${core}`) })),\n ...editor.catalog.value.actions.map((spec) => ({ value: spec.type, label: editor.i18n.localized(spec.label) })),\n ];\n\n return list.some((option) => option.value === type.value) ? list : [...list, { value: type.value, label: t('action.unknown', { type: type.value }) }];\n});\n\nconst modals = computed(() => (editor.state.draft.modals ?? []).map((modal) => ({ value: modal.id, label: modal.title })));\n// Core turns a page action into `/<slug>`; the home page has no slug, so it is written as `/`.\nconst pages = computed(() => editor.state.workspace.pages.map((page) => ({ value: page.slug || '/', label: page.slug ? `${page.title} /${page.slug}` : page.title })));\n\nfunction setType(next: string) {\n const spec = editor.catalog.value.actions.find((candidate) => candidate.type === next);\n // Switching between core actions keeps the value: a number typed for WhatsApp also works to call.\n emit('update:modelValue', { type: next, value: spec ? defaultActionValue(spec.value) : value.value });\n emit('commit');\n}\n\nfunction setValue(next: FieldValue | undefined) {\n emit('update:modelValue', { type: type.value, value: next === null || next === undefined || typeof next === 'object' ? '' : String(next) });\n}\n\n/** App action values live in a string; the field control wants them in the field's own type. */\nconst appValue = computed((): FieldValue => {\n const field = app.value?.value;\n\n if (field?.kind === 'number') {\n return value.value === '' ? field.default : Number(value.value);\n }\n\n if (field?.kind === 'toggle') {\n return value.value === '' ? field.default : value.value === 'true';\n }\n\n return value.value;\n});\n</script>\n\n<template>\n <div class=\"lze-field\">\n <SelectInput :model-value=\"type\" :options=\"options\" :label=\"label\" @update:model-value=\"setType(String($event ?? 'none'))\" />\n <template v-if=\"control\">\n <TextInput\n v-if=\"control.kind === 'text'\"\n :model-value=\"value\"\n :maxlength=\"300\"\n :placeholder=\"t(control.placeholder)\"\n :label=\"t('action.target')\"\n @update:model-value=\"setValue($event)\"\n @commit=\"emit('commit')\"\n />\n <template v-else-if=\"control.kind === 'anchor'\">\n <TextInput\n :model-value=\"value\"\n :maxlength=\"300\"\n :placeholder=\"t('action.placeholder.anchor')\"\n :label=\"t('action.placeholder.anchor')\"\n :list=\"sections\"\n @update:model-value=\"setValue($event)\"\n @commit=\"emit('commit')\"\n />\n <datalist :id=\"sections\">\n <option v-for=\"section in editor.state.draft.sections\" :key=\"section.id\" :value=\"section.id\" />\n </datalist>\n </template>\n <SelectInput\n v-else-if=\"control.kind === 'modal'\"\n :model-value=\"value\"\n :options=\"modals\"\n :label=\"t('action.chooseModal')\"\n :placeholder=\"t('action.chooseModal')\"\n @update:model-value=\"setValue($event)\"\n @commit=\"emit('commit')\"\n />\n <SelectInput\n v-else-if=\"control.kind === 'page'\"\n :model-value=\"value\"\n :options=\"pages\"\n :label=\"t('action.choosePage')\"\n :placeholder=\"t('action.choosePage')\"\n @update:model-value=\"setValue($event)\"\n @commit=\"emit('commit')\"\n />\n <p v-else-if=\"control.kind === 'submit'\" class=\"lze-hint\">{{ t('action.submitHint') }}</p>\n </template>\n <FieldControl\n v-else-if=\"app?.value\"\n :field=\"app.value\"\n :model-value=\"appValue\"\n @update:model-value=\"setValue($event)\"\n @commit=\"emit('commit')\"\n />\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport type { Action, Field, FieldValue } from '@skylivellc/lienzo-core';\nimport { computed, useId } from 'vue';\nimport { useEditor } from '../state/editor.ts';\nimport FieldShell from '../ui/Field.vue';\nimport ImageField from '../ui/ImageField.vue';\nimport NumberInput from '../ui/NumberInput.vue';\nimport SelectInput from '../ui/SelectInput.vue';\nimport TextInput from '../ui/TextInput.vue';\nimport Toggle from '../ui/Toggle.vue';\nimport ActionPicker from './ActionPicker.vue';\n\n/**\n * One control for a field the app declared (app element props, site fields,\n * app action values). The control and the value's type follow the field's kind.\n */\nconst props = defineProps<{ field: Field; modelValue: FieldValue | undefined }>();\nconst emit = defineEmits<{ 'update:modelValue': [value: FieldValue]; commit: [] }>();\nconst editor = useEditor();\nconst id = useId();\nconst label = computed(() => editor.i18n.localized(props.field.label));\n\ntype Of<K extends Field['kind']> = Extract<Field, { kind: K }>;\ntype Control =\n | { kind: 'text'; field: Of<'text'>; value: string }\n | { kind: 'number'; field: Of<'number'>; value: number }\n | { kind: 'toggle'; field: Of<'toggle'>; value: boolean }\n | { kind: 'choice'; field: Of<'choice'>; value: string }\n | { kind: 'choices'; field: Of<'choice'>; value: string[] }\n | { kind: 'image'; field: Of<'image'>; value: string | null }\n | { kind: 'action'; field: Of<'action'>; value: Action | null };\n\nconst isAction = (value: unknown): value is Action => typeof value === 'object' && value !== null;\n\n/** The field with its current value in the field's own type; a missing or mistyped value shows the default. */\nconst control = computed((): Control => {\n const field = props.field;\n const value = props.modelValue;\n\n switch (field.kind) {\n case 'text':\n return { kind: 'text', field, value: typeof value === 'string' ? value : (field.default ?? '') };\n case 'number':\n return { kind: 'number', field, value: typeof value === 'number' ? value : field.default };\n case 'toggle':\n return { kind: 'toggle', field, value: typeof value === 'boolean' ? value : field.default };\n case 'choice': {\n if (field.multiple === true) {\n const chosen = Array.isArray(value) ? value : Array.isArray(field.default) ? field.default : [];\n\n return { kind: 'choices', field, value: chosen.filter((item) => field.options.some((option) => option.value === item)) };\n }\n\n return { kind: 'choice', field, value: typeof value === 'string' ? value : typeof field.default === 'string' ? field.default : '' };\n }\n case 'image':\n return { kind: 'image', field, value: typeof value === 'string' && value !== '' ? value : null };\n case 'action':\n return { kind: 'action', field, value: isAction(value) ? value : null };\n default: {\n const unknown: never = field;\n\n return unknown;\n }\n }\n});\n\n/** One box per option; the stored value keeps the order the options are declared in. */\nfunction toggleChoice(field: Of<'choice'>, chosen: readonly string[], option: string, on: boolean) {\n const next = on ? [...chosen, option] : chosen.filter((item) => item !== option);\n\n update(field.options.map((candidate) => candidate.value).filter((value) => next.includes(value)));\n}\n\nfunction update(value: FieldValue | undefined) {\n if (value !== undefined) {\n emit('update:modelValue', value);\n }\n}\n</script>\n\n<template>\n <FieldShell v-if=\"control.kind === 'text'\" :id=\"id\" :label=\"label\">\n <TextInput :id=\"id\" :model-value=\"control.value\" :maxlength=\"control.field.max\" :rows=\"control.field.multiline ? 4 : 0\" @update:model-value=\"update($event ?? '')\" @commit=\"emit('commit')\" />\n </FieldShell>\n <NumberInput\n v-else-if=\"control.kind === 'number'\"\n :model-value=\"control.value\"\n :label=\"label\"\n :min=\"control.field.min\"\n :max=\"control.field.max\"\n :step=\"control.field.step\"\n @update:model-value=\"update($event ?? undefined)\"\n @commit=\"emit('commit')\"\n />\n <Toggle v-else-if=\"control.kind === 'toggle'\" :model-value=\"control.value\" :label=\"label\" @update:model-value=\"update($event === true)\" @commit=\"emit('commit')\" />\n <FieldShell v-else-if=\"control.kind === 'choice'\" :id=\"id\" :label=\"label\">\n <SelectInput\n :id=\"id\"\n :model-value=\"control.value\"\n :options=\"control.field.options.map((option) => ({ value: option.value, label: editor.i18n.localized(option.label) }))\"\n @update:model-value=\"update($event ?? undefined)\"\n @commit=\"emit('commit')\"\n />\n </FieldShell>\n <FieldShell v-else-if=\"control.kind === 'choices'\" :label=\"label\">\n <div class=\"lze-choices\">\n <Toggle\n v-for=\"option in control.field.options\"\n :key=\"option.value\"\n :model-value=\"control.value.includes(option.value)\"\n :label=\"editor.i18n.localized(option.label)\"\n @update:model-value=\"toggleChoice(control.field, control.value, option.value, $event === true)\"\n @commit=\"emit('commit')\"\n />\n </div>\n </FieldShell>\n <ImageField v-else-if=\"control.kind === 'image'\" :model-value=\"control.value\" :label=\"label\" url @update:model-value=\"update($event ?? null)\" @commit=\"emit('commit')\" />\n <FieldShell v-else :label=\"label\">\n <ActionPicker :model-value=\"control.value\" :label=\"label\" @update:model-value=\"update($event)\" @commit=\"emit('commit')\" />\n </FieldShell>\n</template>\n","<script setup lang=\"ts\">\nimport type { Action, Field, FieldValue } from '@skylivellc/lienzo-core';\nimport { computed, useId } from 'vue';\nimport { useEditor } from '../state/editor.ts';\nimport FieldShell from '../ui/Field.vue';\nimport ImageField from '../ui/ImageField.vue';\nimport NumberInput from '../ui/NumberInput.vue';\nimport SelectInput from '../ui/SelectInput.vue';\nimport TextInput from '../ui/TextInput.vue';\nimport Toggle from '../ui/Toggle.vue';\nimport ActionPicker from './ActionPicker.vue';\n\n/**\n * One control for a field the app declared (app element props, site fields,\n * app action values). The control and the value's type follow the field's kind.\n */\nconst props = defineProps<{ field: Field; modelValue: FieldValue | undefined }>();\nconst emit = defineEmits<{ 'update:modelValue': [value: FieldValue]; commit: [] }>();\nconst editor = useEditor();\nconst id = useId();\nconst label = computed(() => editor.i18n.localized(props.field.label));\n\ntype Of<K extends Field['kind']> = Extract<Field, { kind: K }>;\ntype Control =\n | { kind: 'text'; field: Of<'text'>; value: string }\n | { kind: 'number'; field: Of<'number'>; value: number }\n | { kind: 'toggle'; field: Of<'toggle'>; value: boolean }\n | { kind: 'choice'; field: Of<'choice'>; value: string }\n | { kind: 'choices'; field: Of<'choice'>; value: string[] }\n | { kind: 'image'; field: Of<'image'>; value: string | null }\n | { kind: 'action'; field: Of<'action'>; value: Action | null };\n\nconst isAction = (value: unknown): value is Action => typeof value === 'object' && value !== null;\n\n/** The field with its current value in the field's own type; a missing or mistyped value shows the default. */\nconst control = computed((): Control => {\n const field = props.field;\n const value = props.modelValue;\n\n switch (field.kind) {\n case 'text':\n return { kind: 'text', field, value: typeof value === 'string' ? value : (field.default ?? '') };\n case 'number':\n return { kind: 'number', field, value: typeof value === 'number' ? value : field.default };\n case 'toggle':\n return { kind: 'toggle', field, value: typeof value === 'boolean' ? value : field.default };\n case 'choice': {\n if (field.multiple === true) {\n const chosen = Array.isArray(value) ? value : Array.isArray(field.default) ? field.default : [];\n\n return { kind: 'choices', field, value: chosen.filter((item) => field.options.some((option) => option.value === item)) };\n }\n\n return { kind: 'choice', field, value: typeof value === 'string' ? value : typeof field.default === 'string' ? field.default : '' };\n }\n case 'image':\n return { kind: 'image', field, value: typeof value === 'string' && value !== '' ? value : null };\n case 'action':\n return { kind: 'action', field, value: isAction(value) ? value : null };\n default: {\n const unknown: never = field;\n\n return unknown;\n }\n }\n});\n\n/** One box per option; the stored value keeps the order the options are declared in. */\nfunction toggleChoice(field: Of<'choice'>, chosen: readonly string[], option: string, on: boolean) {\n const next = on ? [...chosen, option] : chosen.filter((item) => item !== option);\n\n update(field.options.map((candidate) => candidate.value).filter((value) => next.includes(value)));\n}\n\nfunction update(value: FieldValue | undefined) {\n if (value !== undefined) {\n emit('update:modelValue', value);\n }\n}\n</script>\n\n<template>\n <FieldShell v-if=\"control.kind === 'text'\" :id=\"id\" :label=\"label\">\n <TextInput :id=\"id\" :model-value=\"control.value\" :maxlength=\"control.field.max\" :rows=\"control.field.multiline ? 4 : 0\" @update:model-value=\"update($event ?? '')\" @commit=\"emit('commit')\" />\n </FieldShell>\n <NumberInput\n v-else-if=\"control.kind === 'number'\"\n :model-value=\"control.value\"\n :label=\"label\"\n :min=\"control.field.min\"\n :max=\"control.field.max\"\n :step=\"control.field.step\"\n @update:model-value=\"update($event ?? undefined)\"\n @commit=\"emit('commit')\"\n />\n <Toggle v-else-if=\"control.kind === 'toggle'\" :model-value=\"control.value\" :label=\"label\" @update:model-value=\"update($event === true)\" @commit=\"emit('commit')\" />\n <FieldShell v-else-if=\"control.kind === 'choice'\" :id=\"id\" :label=\"label\">\n <SelectInput\n :id=\"id\"\n :model-value=\"control.value\"\n :options=\"control.field.options.map((option) => ({ value: option.value, label: editor.i18n.localized(option.label) }))\"\n @update:model-value=\"update($event ?? undefined)\"\n @commit=\"emit('commit')\"\n />\n </FieldShell>\n <FieldShell v-else-if=\"control.kind === 'choices'\" :label=\"label\">\n <div class=\"lze-choices\">\n <Toggle\n v-for=\"option in control.field.options\"\n :key=\"option.value\"\n :model-value=\"control.value.includes(option.value)\"\n :label=\"editor.i18n.localized(option.label)\"\n @update:model-value=\"toggleChoice(control.field, control.value, option.value, $event === true)\"\n @commit=\"emit('commit')\"\n />\n </div>\n </FieldShell>\n <ImageField v-else-if=\"control.kind === 'image'\" :model-value=\"control.value\" :label=\"label\" url @update:model-value=\"update($event ?? null)\" @commit=\"emit('commit')\" />\n <FieldShell v-else :label=\"label\">\n <ActionPicker :model-value=\"control.value\" :label=\"label\" @update:model-value=\"update($event)\" @commit=\"emit('commit')\" />\n </FieldShell>\n</template>\n","<script setup lang=\"ts\">\nimport type { FieldValue, Issue } from '@skylivellc/lienzo-core';\nimport { computed, reactive, useId, watch } from 'vue';\nimport { plain } from '../model/document.ts';\nimport FieldControl from '../panels/FieldControl.vue';\nimport { useEditor } from '../state/editor.ts';\nimport Button from '../ui/Button.vue';\nimport Dialog from '../ui/Dialog.vue';\nimport Field from '../ui/Field.vue';\nimport ImageField from '../ui/ImageField.vue';\nimport TextInput from '../ui/TextInput.vue';\n\n/**\n * Site-wide settings: search engine defaults, share image, favicon, language,\n * and whatever site fields the app declares (stored in `meta`).\n */\nconst editor = useEditor();\nconst t = editor.t;\nconst ids = { seoTitle: useId(), seoDescription: useId(), locale: useId() };\nconst open = editor.dialogModel('site');\n\nconst blank = () => {\n const site = editor.state.workspace.site;\n\n return {\n seoTitle: site.seo.title ?? '',\n seoDescription: site.seo.description ?? '',\n ogImage: site.og_image,\n favicon: site.favicon,\n locale: site.locale,\n meta: plain(editor.state.workspace.meta),\n issues: [] as Issue[],\n saving: false,\n };\n};\nconst form = reactive(blank());\nwatch(open, (now) => now && Object.assign(form, blank()));\n\nconst fields = computed(() => editor.catalog.value.siteFields ?? []);\nconst nullIfBlank = (value: string | null | undefined) => (value && value.trim() !== '' ? value : null);\n\nconst PATHS = ['seo.title', 'seo.description', 'og_image', 'favicon', 'locale'];\nconst issueAt = (path: string) => form.issues.filter((issue) => issue.path === path).map((issue) => issue.message).join(' ') || null;\nconst otherIssues = computed(() => form.issues.filter((issue) => !PATHS.includes(issue.path) && !issue.path.startsWith('meta.')));\n\nfunction setMeta(key: string, value: FieldValue) {\n form.meta = { ...form.meta, [key]: value };\n}\n\nasync function save() {\n form.saving = true;\n form.issues = await editor.updateSite({\n seo: { title: nullIfBlank(form.seoTitle), description: nullIfBlank(form.seoDescription) },\n og_image: nullIfBlank(form.ogImage),\n favicon: nullIfBlank(form.favicon),\n locale: form.locale.trim(),\n meta: form.meta,\n });\n form.saving = false;\n\n if (form.issues.length === 0) {\n open.value = false;\n editor.notify(t('site.saved'));\n }\n}\n</script>\n\n<template>\n <Dialog v-model:open=\"open\" :title=\"t('site.title')\" :description=\"t('site.description')\" size=\"lg\">\n <form class=\"lze-stack\" novalidate @submit.prevent=\"save\">\n <Field :id=\"ids.seoTitle\" :label=\"t('site.seoTitle')\" :error=\"issueAt('seo.title')\">\n <TextInput :id=\"ids.seoTitle\" v-model=\"form.seoTitle\" :maxlength=\"120\" />\n </Field>\n <Field :id=\"ids.seoDescription\" :label=\"t('site.seoDescription')\" :error=\"issueAt('seo.description')\">\n <TextInput :id=\"ids.seoDescription\" v-model=\"form.seoDescription\" :rows=\"3\" :maxlength=\"300\" />\n </Field>\n <div class=\"lze-grid-2\">\n <div class=\"lze-field\">\n <ImageField v-model=\"form.ogImage\" :label=\"t('site.shareImage')\" :choose=\"t('common.choose')\" />\n <p v-if=\"issueAt('og_image')\" class=\"lze-error\" role=\"alert\">{{ issueAt('og_image') }}</p>\n <p v-else class=\"lze-hint\">{{ t('site.shareImageHint') }}</p>\n </div>\n <div class=\"lze-field\">\n <ImageField v-model=\"form.favicon\" :label=\"t('site.favicon')\" :choose=\"t('common.choose')\" thumb=\"icon\" />\n <p v-if=\"issueAt('favicon')\" class=\"lze-error\" role=\"alert\">{{ issueAt('favicon') }}</p>\n </div>\n </div>\n <Field :id=\"ids.locale\" :label=\"t('site.locale')\" :hint=\"t('site.localeHint')\" :error=\"issueAt('locale')\">\n <TextInput :id=\"ids.locale\" v-model=\"form.locale\" :maxlength=\"5\" placeholder=\"en\" />\n </Field>\n <section v-if=\"fields.length > 0\" class=\"lze-stack lze-divided\">\n <h3 class=\"lze-label\">{{ t('site.details') }}</h3>\n <div v-for=\"field in fields\" :key=\"field.key\" class=\"lze-field\">\n <FieldControl :field=\"field\" :model-value=\"form.meta[field.key]\" @update:model-value=\"setMeta(field.key, $event)\" />\n <p v-if=\"issueAt(`meta.${field.key}`)\" class=\"lze-error\" role=\"alert\">{{ issueAt(`meta.${field.key}`) }}</p>\n </div>\n </section>\n <p v-for=\"issue in otherIssues\" :key=\"issue.path + issue.message\" class=\"lze-error\" role=\"alert\">{{ issue.path ? `${issue.path}: ` : '' }}{{ issue.message }}</p>\n <div class=\"lze-dialog-actions\">\n <Button variant=\"primary\" size=\"md\" type=\"submit\" :disabled=\"form.saving\">{{ t('site.save') }}</Button>\n <Button size=\"md\" @click=\"open = false\">{{ t('common.cancel') }}</Button>\n </div>\n </form>\n </Dialog>\n</template>\n","<script setup lang=\"ts\">\nimport type { FieldValue, Issue } from '@skylivellc/lienzo-core';\nimport { computed, reactive, useId, watch } from 'vue';\nimport { plain } from '../model/document.ts';\nimport FieldControl from '../panels/FieldControl.vue';\nimport { useEditor } from '../state/editor.ts';\nimport Button from '../ui/Button.vue';\nimport Dialog from '../ui/Dialog.vue';\nimport Field from '../ui/Field.vue';\nimport ImageField from '../ui/ImageField.vue';\nimport TextInput from '../ui/TextInput.vue';\n\n/**\n * Site-wide settings: search engine defaults, share image, favicon, language,\n * and whatever site fields the app declares (stored in `meta`).\n */\nconst editor = useEditor();\nconst t = editor.t;\nconst ids = { seoTitle: useId(), seoDescription: useId(), locale: useId() };\nconst open = editor.dialogModel('site');\n\nconst blank = () => {\n const site = editor.state.workspace.site;\n\n return {\n seoTitle: site.seo.title ?? '',\n seoDescription: site.seo.description ?? '',\n ogImage: site.og_image,\n favicon: site.favicon,\n locale: site.locale,\n meta: plain(editor.state.workspace.meta),\n issues: [] as Issue[],\n saving: false,\n };\n};\nconst form = reactive(blank());\nwatch(open, (now) => now && Object.assign(form, blank()));\n\nconst fields = computed(() => editor.catalog.value.siteFields ?? []);\nconst nullIfBlank = (value: string | null | undefined) => (value && value.trim() !== '' ? value : null);\n\nconst PATHS = ['seo.title', 'seo.description', 'og_image', 'favicon', 'locale'];\nconst issueAt = (path: string) => form.issues.filter((issue) => issue.path === path).map((issue) => issue.message).join(' ') || null;\nconst otherIssues = computed(() => form.issues.filter((issue) => !PATHS.includes(issue.path) && !issue.path.startsWith('meta.')));\n\nfunction setMeta(key: string, value: FieldValue) {\n form.meta = { ...form.meta, [key]: value };\n}\n\nasync function save() {\n form.saving = true;\n form.issues = await editor.updateSite({\n seo: { title: nullIfBlank(form.seoTitle), description: nullIfBlank(form.seoDescription) },\n og_image: nullIfBlank(form.ogImage),\n favicon: nullIfBlank(form.favicon),\n locale: form.locale.trim(),\n meta: form.meta,\n });\n form.saving = false;\n\n if (form.issues.length === 0) {\n open.value = false;\n editor.notify(t('site.saved'));\n }\n}\n</script>\n\n<template>\n <Dialog v-model:open=\"open\" :title=\"t('site.title')\" :description=\"t('site.description')\" size=\"lg\">\n <form class=\"lze-stack\" novalidate @submit.prevent=\"save\">\n <Field :id=\"ids.seoTitle\" :label=\"t('site.seoTitle')\" :error=\"issueAt('seo.title')\">\n <TextInput :id=\"ids.seoTitle\" v-model=\"form.seoTitle\" :maxlength=\"120\" />\n </Field>\n <Field :id=\"ids.seoDescription\" :label=\"t('site.seoDescription')\" :error=\"issueAt('seo.description')\">\n <TextInput :id=\"ids.seoDescription\" v-model=\"form.seoDescription\" :rows=\"3\" :maxlength=\"300\" />\n </Field>\n <div class=\"lze-grid-2\">\n <div class=\"lze-field\">\n <ImageField v-model=\"form.ogImage\" :label=\"t('site.shareImage')\" :choose=\"t('common.choose')\" />\n <p v-if=\"issueAt('og_image')\" class=\"lze-error\" role=\"alert\">{{ issueAt('og_image') }}</p>\n <p v-else class=\"lze-hint\">{{ t('site.shareImageHint') }}</p>\n </div>\n <div class=\"lze-field\">\n <ImageField v-model=\"form.favicon\" :label=\"t('site.favicon')\" :choose=\"t('common.choose')\" thumb=\"icon\" />\n <p v-if=\"issueAt('favicon')\" class=\"lze-error\" role=\"alert\">{{ issueAt('favicon') }}</p>\n </div>\n </div>\n <Field :id=\"ids.locale\" :label=\"t('site.locale')\" :hint=\"t('site.localeHint')\" :error=\"issueAt('locale')\">\n <TextInput :id=\"ids.locale\" v-model=\"form.locale\" :maxlength=\"5\" placeholder=\"en\" />\n </Field>\n <section v-if=\"fields.length > 0\" class=\"lze-stack lze-divided\">\n <h3 class=\"lze-label\">{{ t('site.details') }}</h3>\n <div v-for=\"field in fields\" :key=\"field.key\" class=\"lze-field\">\n <FieldControl :field=\"field\" :model-value=\"form.meta[field.key]\" @update:model-value=\"setMeta(field.key, $event)\" />\n <p v-if=\"issueAt(`meta.${field.key}`)\" class=\"lze-error\" role=\"alert\">{{ issueAt(`meta.${field.key}`) }}</p>\n </div>\n </section>\n <p v-for=\"issue in otherIssues\" :key=\"issue.path + issue.message\" class=\"lze-error\" role=\"alert\">{{ issue.path ? `${issue.path}: ` : '' }}{{ issue.message }}</p>\n <div class=\"lze-dialog-actions\">\n <Button variant=\"primary\" size=\"md\" type=\"submit\" :disabled=\"form.saving\">{{ t('site.save') }}</Button>\n <Button size=\"md\" @click=\"open = false\">{{ t('common.cancel') }}</Button>\n </div>\n </form>\n </Dialog>\n</template>\n","<script setup lang=\"ts\">\nimport type { Submission } from '@skylivellc/lienzo-core/protocol';\nimport { computed, ref, watch } from 'vue';\nimport { canvasesOf } from '../model/document.ts';\nimport { domId } from '../canvas/render.ts';\nimport { useEditor } from '../state/editor.ts';\nimport Button from '../ui/Button.vue';\nimport Dialog from '../ui/Dialog.vue';\n\n/** Form submissions, read through the protocol a page of results at a time. */\nconst editor = useEditor();\nconst t = editor.t;\nconst open = editor.dialogModel('submissions');\nconst submissions = ref<Submission[]>([]);\nconst next = ref<string | null>(null);\nconst loading = ref(false);\nconst date = new Intl.DateTimeFormat(editor.i18n.locale, { dateStyle: 'medium', timeStyle: 'short' });\n\nasync function load(cursor: string | null) {\n loading.value = true;\n const result = await editor.client('GET /submissions', cursor ? { cursor } : undefined);\n loading.value = false;\n\n if (!result.ok) {\n editor.notify(t('submissions.failed', { message: editor.failureText(result.failure) }), 'error');\n\n return;\n }\n\n submissions.value = cursor ? [...submissions.value, ...result.value.data] : result.value.data;\n next.value = result.value.next;\n}\n\nwatch(open, (now) => {\n if (now) {\n void load(null);\n }\n});\n\n/** Fields arrive keyed by element id; the open page's field labels read better where they match. */\nconst labels = computed(() => new Map(canvasesOf(editor.state.draft).flatMap((canvas) => canvas.elements)\n .flatMap((element): [string, string][] => {\n const label = (element.props as { label?: unknown }).label;\n\n return typeof label === 'string' && label.trim() !== '' ? [[domId(element.id), label.trim()]] : [];\n })));\n</script>\n\n<template>\n <Dialog v-model:open=\"open\" :title=\"t('submissions.title')\" :description=\"t('submissions.description')\" size=\"lg\">\n <ul v-if=\"submissions.length > 0\" class=\"lze-rows\">\n <li v-for=\"submission in submissions\" :key=\"submission.id\" class=\"lze-submission\">\n <p class=\"lze-hint\">{{ date.format(new Date(submission.createdAt)) }} · {{ t('submissions.from', { page: submission.page, source: submission.source }) }}</p>\n <dl>\n <template v-for=\"(value, name) in submission.fields\" :key=\"name\">\n <dt>{{ labels.get(String(name)) ?? name }}</dt>\n <dd>{{ typeof value === 'boolean' ? t(value ? 'submissions.checked' : 'submissions.unchecked') : value }}</dd>\n </template>\n </dl>\n </li>\n </ul>\n <p v-else-if=\"!loading\" class=\"lze-hint\">{{ t('submissions.empty') }}</p>\n <div v-if=\"next\" class=\"lze-dialog-actions\">\n <Button :disabled=\"loading\" @click=\"load(next)\">{{ t('submissions.more') }}</Button>\n </div>\n </Dialog>\n</template>\n","<script setup lang=\"ts\">\nimport type { Submission } from '@skylivellc/lienzo-core/protocol';\nimport { computed, ref, watch } from 'vue';\nimport { canvasesOf } from '../model/document.ts';\nimport { domId } from '../canvas/render.ts';\nimport { useEditor } from '../state/editor.ts';\nimport Button from '../ui/Button.vue';\nimport Dialog from '../ui/Dialog.vue';\n\n/** Form submissions, read through the protocol a page of results at a time. */\nconst editor = useEditor();\nconst t = editor.t;\nconst open = editor.dialogModel('submissions');\nconst submissions = ref<Submission[]>([]);\nconst next = ref<string | null>(null);\nconst loading = ref(false);\nconst date = new Intl.DateTimeFormat(editor.i18n.locale, { dateStyle: 'medium', timeStyle: 'short' });\n\nasync function load(cursor: string | null) {\n loading.value = true;\n const result = await editor.client('GET /submissions', cursor ? { cursor } : undefined);\n loading.value = false;\n\n if (!result.ok) {\n editor.notify(t('submissions.failed', { message: editor.failureText(result.failure) }), 'error');\n\n return;\n }\n\n submissions.value = cursor ? [...submissions.value, ...result.value.data] : result.value.data;\n next.value = result.value.next;\n}\n\nwatch(open, (now) => {\n if (now) {\n void load(null);\n }\n});\n\n/** Fields arrive keyed by element id; the open page's field labels read better where they match. */\nconst labels = computed(() => new Map(canvasesOf(editor.state.draft).flatMap((canvas) => canvas.elements)\n .flatMap((element): [string, string][] => {\n const label = (element.props as { label?: unknown }).label;\n\n return typeof label === 'string' && label.trim() !== '' ? [[domId(element.id), label.trim()]] : [];\n })));\n</script>\n\n<template>\n <Dialog v-model:open=\"open\" :title=\"t('submissions.title')\" :description=\"t('submissions.description')\" size=\"lg\">\n <ul v-if=\"submissions.length > 0\" class=\"lze-rows\">\n <li v-for=\"submission in submissions\" :key=\"submission.id\" class=\"lze-submission\">\n <p class=\"lze-hint\">{{ date.format(new Date(submission.createdAt)) }} · {{ t('submissions.from', { page: submission.page, source: submission.source }) }}</p>\n <dl>\n <template v-for=\"(value, name) in submission.fields\" :key=\"name\">\n <dt>{{ labels.get(String(name)) ?? name }}</dt>\n <dd>{{ typeof value === 'boolean' ? t(value ? 'submissions.checked' : 'submissions.unchecked') : value }}</dd>\n </template>\n </dl>\n </li>\n </ul>\n <p v-else-if=\"!loading\" class=\"lze-hint\">{{ t('submissions.empty') }}</p>\n <div v-if=\"next\" class=\"lze-dialog-actions\">\n <Button :disabled=\"loading\" @click=\"load(next)\">{{ t('submissions.more') }}</Button>\n </div>\n </Dialog>\n</template>\n","<script setup lang=\"ts\">\n/** Slider with its label and current value; moves live, commits when released. */\nconst model = defineModel<number | null | undefined>({ required: true });\nwithDefaults(defineProps<{ label: string; min: number; max: number; step?: number; fallback?: number; format?: (value: number) => string }>(), {\n step: 1,\n fallback: 0,\n format: (value: number) => String(value),\n});\nconst emit = defineEmits<{ commit: [] }>();\n</script>\n\n<template>\n <label class=\"lze-range\">\n <span class=\"lze-label\">{{ label }} <span class=\"lze-muted\">{{ format(model ?? fallback) }}</span></span>\n <input type=\"range\" :min=\"min\" :max=\"max\" :step=\"step\" :value=\"model ?? fallback\" @input=\"model = Number(($event.target as HTMLInputElement).value)\" @change=\"emit('commit')\" />\n </label>\n</template>\n","<script setup lang=\"ts\">\n/** Slider with its label and current value; moves live, commits when released. */\nconst model = defineModel<number | null | undefined>({ required: true });\nwithDefaults(defineProps<{ label: string; min: number; max: number; step?: number; fallback?: number; format?: (value: number) => string }>(), {\n step: 1,\n fallback: 0,\n format: (value: number) => String(value),\n});\nconst emit = defineEmits<{ commit: [] }>();\n</script>\n\n<template>\n <label class=\"lze-range\">\n <span class=\"lze-label\">{{ label }} <span class=\"lze-muted\">{{ format(model ?? fallback) }}</span></span>\n <input type=\"range\" :min=\"min\" :max=\"max\" :step=\"step\" :value=\"model ?? fallback\" @input=\"model = Number(($event.target as HTMLInputElement).value)\" @change=\"emit('commit')\" />\n </label>\n</template>\n","<script setup lang=\"ts\">\nimport type { Issue, Theme, ThemeToken } from '@skylivellc/lienzo-core';\nimport { computed, reactive, ref, useId, watch } from 'vue';\nimport { plain } from '../model/document.ts';\nimport { FONTS, fontNote, fontsHref, linkToPalette, MAX_WIDTHS, PALETTES, THEME_TOKENS, widthLabel, type Palette } from '../model/theme.ts';\nimport { useEditor } from '../state/editor.ts';\nimport Button from '../ui/Button.vue';\nimport Dialog from '../ui/Dialog.vue';\nimport Field from '../ui/Field.vue';\nimport RangeInput from '../ui/RangeInput.vue';\nimport SelectInput from '../ui/SelectInput.vue';\n\n/**\n * Edits the site theme. While open, every valid change goes to\n * `state.themeDraft`, so the canvas previews it; saving stores it, closing drops it.\n */\nconst editor = useEditor();\nconst t = editor.t;\nconst ids = { heading: useId(), body: useId(), width: useId() };\nconst HEX = /^#[0-9a-fA-F]{6}$/;\n\nconst open = editor.dialogModel('theme');\n\n/** The form keeps what is typed, even a half-written hex; only valid colors reach the canvas. */\nconst form = reactive<Theme>(plain(editor.state.workspace.site.theme));\nconst issues = ref<Issue[]>([]);\nconst saving = ref(false);\n\nconst valid = computed((): Theme => {\n const saved = editor.state.workspace.site.theme;\n const colors = Object.fromEntries(THEME_TOKENS.map((token) => [token, HEX.test(form[token]) ? form[token] : saved[token]])) as Palette;\n\n return { ...form, ...colors };\n});\n\nwatch(open, (now) => {\n if (now) {\n Object.assign(form, plain(editor.state.workspace.site.theme));\n issues.value = [];\n }\n\n editor.state.themeDraft = now ? plain(valid.value) : null;\n}, { immediate: true });\n\nwatch(valid, (theme) => {\n if (open.value) {\n editor.state.themeDraft = plain(theme);\n }\n});\n\nconst fonts = FONTS.map((font) => ({ value: font, label: `${font} · ${t(fontNote(font))}` }));\nconst widths = MAX_WIDTHS.map((width) => ({ value: width, label: t(widthLabel(width)) }));\n\nfunction applyPalette(colors: Palette) {\n Object.assign(form, colors);\n}\n\nfunction linkElements() {\n linkToPalette(editor.state.draft, valid.value);\n editor.commit();\n}\n\nasync function save() {\n saving.value = true;\n issues.value = await editor.updateSite({ theme: valid.value });\n saving.value = false;\n\n if (issues.value.length === 0) {\n open.value = false;\n editor.notify(t('theme.saved'));\n }\n}\n\nconst colorOf = (token: ThemeToken) => valid.value[token];\n</script>\n\n<template>\n <Dialog v-model:open=\"open\" :title=\"t('theme.title')\" :description=\"t('theme.description')\" size=\"xl\">\n <link rel=\"stylesheet\" :href=\"fontsHref([valid.heading_font, valid.body_font])\" />\n <form class=\"lze-stack\" novalidate @submit.prevent=\"save\">\n <section class=\"lze-field\">\n <h3 class=\"lze-label\">{{ t('theme.palettes') }}</h3>\n <div class=\"lze-row\">\n <button v-for=\"palette in PALETTES\" :key=\"palette.name\" type=\"button\" class=\"lze-palette-choice\" @click=\"applyPalette(palette.colors)\">\n <span class=\"lze-row\" aria-hidden=\"true\">\n <span v-for=\"token in ['primary', 'secondary', 'surface'] as const\" :key=\"token\" class=\"lze-dot\" :style=\"{ background: palette.colors[token] }\" />\n </span>\n {{ t(palette.name) }}\n </button>\n </div>\n </section>\n\n <section class=\"lze-field\">\n <div class=\"lze-heading\">\n <h3 class=\"lze-label\">{{ t('theme.colors') }}</h3>\n <Button @click=\"linkElements\">{{ t('theme.link') }}</Button>\n </div>\n <p class=\"lze-hint\">{{ t('theme.linkHint') }}</p>\n <div class=\"lze-theme-colors\">\n <div v-for=\"token in THEME_TOKENS\" :key=\"token\" class=\"lze-theme-color\">\n <span>{{ t(`token.${token}`) }}</span>\n <input v-model=\"form[token]\" class=\"lze-input lze-hex\" maxlength=\"7\" spellcheck=\"false\" :aria-label=\"t('theme.hex', { label: t(`token.${token}`) })\" />\n <input type=\"color\" :value=\"colorOf(token)\" :aria-label=\"t(`token.${token}`)\" @input=\"form[token] = ($event.target as HTMLInputElement).value\" />\n </div>\n </div>\n </section>\n\n <section class=\"lze-grid-2\">\n <Field :id=\"ids.heading\" :label=\"t('theme.headingFont')\">\n <SelectInput :id=\"ids.heading\" :model-value=\"form.heading_font\" :options=\"fonts\" @update:model-value=\"form.heading_font = $event ?? form.heading_font\" />\n </Field>\n <Field :id=\"ids.body\" :label=\"t('theme.bodyFont')\">\n <SelectInput :id=\"ids.body\" :model-value=\"form.body_font\" :options=\"fonts\" @update:model-value=\"form.body_font = $event ?? form.body_font\" />\n </Field>\n </section>\n\n <section class=\"lze-grid-2\">\n <RangeInput :model-value=\"form.radius\" :label=\"t('theme.radius')\" :min=\"0\" :max=\"40\" :step=\"2\" :format=\"(value) => `${value} px`\" @update:model-value=\"form.radius = $event ?? form.radius\" />\n <Field :id=\"ids.width\" :label=\"t('theme.maxWidth')\">\n <SelectInput :id=\"ids.width\" :model-value=\"form.max_width\" :options=\"widths\" @update:model-value=\"form.max_width = $event ?? form.max_width\" />\n </Field>\n </section>\n\n <section\n class=\"lze-theme-preview\"\n :aria-label=\"t('theme.previewLabel')\"\n :style=\"{ background: valid.surface, color: valid.text, borderRadius: `${valid.radius}px` }\"\n >\n <p class=\"lze-theme-preview-heading\" :style=\"{ fontFamily: `'${valid.heading_font}', sans-serif` }\">{{ t('theme.previewHeading') }}</p>\n <p :style=\"{ fontFamily: `'${valid.body_font}', sans-serif`, color: valid.muted }\">{{ t('theme.previewText') }}</p>\n <span\n class=\"lze-theme-preview-button\"\n :style=\"{ background: valid.primary, color: valid.background, borderRadius: `${valid.radius}px`, fontFamily: `'${valid.body_font}', sans-serif` }\"\n >\n {{ t('theme.previewButton') }}\n </span>\n </section>\n\n <p v-for=\"issue in issues\" :key=\"issue.path + issue.message\" class=\"lze-error\" role=\"alert\">{{ issue.path ? `${issue.path}: ` : '' }}{{ issue.message }}</p>\n <div class=\"lze-dialog-actions\">\n <Button variant=\"primary\" size=\"md\" type=\"submit\" :disabled=\"saving\">{{ t('theme.save') }}</Button>\n <Button size=\"md\" @click=\"open = false\">{{ t('common.cancel') }}</Button>\n </div>\n </form>\n </Dialog>\n</template>\n","<script setup lang=\"ts\">\nimport type { Issue, Theme, ThemeToken } from '@skylivellc/lienzo-core';\nimport { computed, reactive, ref, useId, watch } from 'vue';\nimport { plain } from '../model/document.ts';\nimport { FONTS, fontNote, fontsHref, linkToPalette, MAX_WIDTHS, PALETTES, THEME_TOKENS, widthLabel, type Palette } from '../model/theme.ts';\nimport { useEditor } from '../state/editor.ts';\nimport Button from '../ui/Button.vue';\nimport Dialog from '../ui/Dialog.vue';\nimport Field from '../ui/Field.vue';\nimport RangeInput from '../ui/RangeInput.vue';\nimport SelectInput from '../ui/SelectInput.vue';\n\n/**\n * Edits the site theme. While open, every valid change goes to\n * `state.themeDraft`, so the canvas previews it; saving stores it, closing drops it.\n */\nconst editor = useEditor();\nconst t = editor.t;\nconst ids = { heading: useId(), body: useId(), width: useId() };\nconst HEX = /^#[0-9a-fA-F]{6}$/;\n\nconst open = editor.dialogModel('theme');\n\n/** The form keeps what is typed, even a half-written hex; only valid colors reach the canvas. */\nconst form = reactive<Theme>(plain(editor.state.workspace.site.theme));\nconst issues = ref<Issue[]>([]);\nconst saving = ref(false);\n\nconst valid = computed((): Theme => {\n const saved = editor.state.workspace.site.theme;\n const colors = Object.fromEntries(THEME_TOKENS.map((token) => [token, HEX.test(form[token]) ? form[token] : saved[token]])) as Palette;\n\n return { ...form, ...colors };\n});\n\nwatch(open, (now) => {\n if (now) {\n Object.assign(form, plain(editor.state.workspace.site.theme));\n issues.value = [];\n }\n\n editor.state.themeDraft = now ? plain(valid.value) : null;\n}, { immediate: true });\n\nwatch(valid, (theme) => {\n if (open.value) {\n editor.state.themeDraft = plain(theme);\n }\n});\n\nconst fonts = FONTS.map((font) => ({ value: font, label: `${font} · ${t(fontNote(font))}` }));\nconst widths = MAX_WIDTHS.map((width) => ({ value: width, label: t(widthLabel(width)) }));\n\nfunction applyPalette(colors: Palette) {\n Object.assign(form, colors);\n}\n\nfunction linkElements() {\n linkToPalette(editor.state.draft, valid.value);\n editor.commit();\n}\n\nasync function save() {\n saving.value = true;\n issues.value = await editor.updateSite({ theme: valid.value });\n saving.value = false;\n\n if (issues.value.length === 0) {\n open.value = false;\n editor.notify(t('theme.saved'));\n }\n}\n\nconst colorOf = (token: ThemeToken) => valid.value[token];\n</script>\n\n<template>\n <Dialog v-model:open=\"open\" :title=\"t('theme.title')\" :description=\"t('theme.description')\" size=\"xl\">\n <link rel=\"stylesheet\" :href=\"fontsHref([valid.heading_font, valid.body_font])\" />\n <form class=\"lze-stack\" novalidate @submit.prevent=\"save\">\n <section class=\"lze-field\">\n <h3 class=\"lze-label\">{{ t('theme.palettes') }}</h3>\n <div class=\"lze-row\">\n <button v-for=\"palette in PALETTES\" :key=\"palette.name\" type=\"button\" class=\"lze-palette-choice\" @click=\"applyPalette(palette.colors)\">\n <span class=\"lze-row\" aria-hidden=\"true\">\n <span v-for=\"token in ['primary', 'secondary', 'surface'] as const\" :key=\"token\" class=\"lze-dot\" :style=\"{ background: palette.colors[token] }\" />\n </span>\n {{ t(palette.name) }}\n </button>\n </div>\n </section>\n\n <section class=\"lze-field\">\n <div class=\"lze-heading\">\n <h3 class=\"lze-label\">{{ t('theme.colors') }}</h3>\n <Button @click=\"linkElements\">{{ t('theme.link') }}</Button>\n </div>\n <p class=\"lze-hint\">{{ t('theme.linkHint') }}</p>\n <div class=\"lze-theme-colors\">\n <div v-for=\"token in THEME_TOKENS\" :key=\"token\" class=\"lze-theme-color\">\n <span>{{ t(`token.${token}`) }}</span>\n <input v-model=\"form[token]\" class=\"lze-input lze-hex\" maxlength=\"7\" spellcheck=\"false\" :aria-label=\"t('theme.hex', { label: t(`token.${token}`) })\" />\n <input type=\"color\" :value=\"colorOf(token)\" :aria-label=\"t(`token.${token}`)\" @input=\"form[token] = ($event.target as HTMLInputElement).value\" />\n </div>\n </div>\n </section>\n\n <section class=\"lze-grid-2\">\n <Field :id=\"ids.heading\" :label=\"t('theme.headingFont')\">\n <SelectInput :id=\"ids.heading\" :model-value=\"form.heading_font\" :options=\"fonts\" @update:model-value=\"form.heading_font = $event ?? form.heading_font\" />\n </Field>\n <Field :id=\"ids.body\" :label=\"t('theme.bodyFont')\">\n <SelectInput :id=\"ids.body\" :model-value=\"form.body_font\" :options=\"fonts\" @update:model-value=\"form.body_font = $event ?? form.body_font\" />\n </Field>\n </section>\n\n <section class=\"lze-grid-2\">\n <RangeInput :model-value=\"form.radius\" :label=\"t('theme.radius')\" :min=\"0\" :max=\"40\" :step=\"2\" :format=\"(value) => `${value} px`\" @update:model-value=\"form.radius = $event ?? form.radius\" />\n <Field :id=\"ids.width\" :label=\"t('theme.maxWidth')\">\n <SelectInput :id=\"ids.width\" :model-value=\"form.max_width\" :options=\"widths\" @update:model-value=\"form.max_width = $event ?? form.max_width\" />\n </Field>\n </section>\n\n <section\n class=\"lze-theme-preview\"\n :aria-label=\"t('theme.previewLabel')\"\n :style=\"{ background: valid.surface, color: valid.text, borderRadius: `${valid.radius}px` }\"\n >\n <p class=\"lze-theme-preview-heading\" :style=\"{ fontFamily: `'${valid.heading_font}', sans-serif` }\">{{ t('theme.previewHeading') }}</p>\n <p :style=\"{ fontFamily: `'${valid.body_font}', sans-serif`, color: valid.muted }\">{{ t('theme.previewText') }}</p>\n <span\n class=\"lze-theme-preview-button\"\n :style=\"{ background: valid.primary, color: valid.background, borderRadius: `${valid.radius}px`, fontFamily: `'${valid.body_font}', sans-serif` }\"\n >\n {{ t('theme.previewButton') }}\n </span>\n </section>\n\n <p v-for=\"issue in issues\" :key=\"issue.path + issue.message\" class=\"lze-error\" role=\"alert\">{{ issue.path ? `${issue.path}: ` : '' }}{{ issue.message }}</p>\n <div class=\"lze-dialog-actions\">\n <Button variant=\"primary\" size=\"md\" type=\"submit\" :disabled=\"saving\">{{ t('theme.save') }}</Button>\n <Button size=\"md\" @click=\"open = false\">{{ t('common.cancel') }}</Button>\n </div>\n </form>\n </Dialog>\n</template>\n","<script setup lang=\"ts\">\nimport { computed } from 'vue';\nimport { useEditor } from '../state/editor.ts';\nimport Button from '../ui/Button.vue';\nimport Dialog from '../ui/Dialog.vue';\n\n/** Published versions of the open page, newest first as the backend sends them. */\nconst editor = useEditor();\nconst t = editor.t;\nconst open = editor.dialogModel('versions');\nconst versions = computed(() => editor.state.page?.versions ?? []);\nconst date = new Intl.DateTimeFormat(editor.i18n.locale, { dateStyle: 'medium', timeStyle: 'short' });\n</script>\n\n<template>\n <Dialog v-model:open=\"open\" :title=\"t('versions.title')\" :description=\"t('versions.description')\" size=\"lg\">\n <ul v-if=\"versions.length > 0\" class=\"lze-rows\">\n <li v-for=\"version in versions\" :key=\"version.id\" class=\"lze-row-item\">\n <div>\n <p>{{ date.format(new Date(version.createdAt)) }}</p>\n <p v-if=\"version.by\" class=\"lze-hint\">{{ t('versions.by', { name: version.by }) }}</p>\n </div>\n <Button @click=\"editor.restoreVersion(version.id)\">{{ t('versions.restore') }}</Button>\n </li>\n </ul>\n <p v-else class=\"lze-hint\">{{ t('versions.empty') }}</p>\n </Dialog>\n</template>\n","<script setup lang=\"ts\">\nimport { computed } from 'vue';\nimport { useEditor } from '../state/editor.ts';\nimport Button from '../ui/Button.vue';\nimport Dialog from '../ui/Dialog.vue';\n\n/** Published versions of the open page, newest first as the backend sends them. */\nconst editor = useEditor();\nconst t = editor.t;\nconst open = editor.dialogModel('versions');\nconst versions = computed(() => editor.state.page?.versions ?? []);\nconst date = new Intl.DateTimeFormat(editor.i18n.locale, { dateStyle: 'medium', timeStyle: 'short' });\n</script>\n\n<template>\n <Dialog v-model:open=\"open\" :title=\"t('versions.title')\" :description=\"t('versions.description')\" size=\"lg\">\n <ul v-if=\"versions.length > 0\" class=\"lze-rows\">\n <li v-for=\"version in versions\" :key=\"version.id\" class=\"lze-row-item\">\n <div>\n <p>{{ date.format(new Date(version.createdAt)) }}</p>\n <p v-if=\"version.by\" class=\"lze-hint\">{{ t('versions.by', { name: version.by }) }}</p>\n </div>\n <Button @click=\"editor.restoreVersion(version.id)\">{{ t('versions.restore') }}</Button>\n </li>\n </ul>\n <p v-else class=\"lze-hint\">{{ t('versions.empty') }}</p>\n </Dialog>\n</template>\n","{\n \"elementTypes\": [\n \"heading\",\n \"text\",\n \"image\",\n \"button\",\n \"divider\",\n \"video\",\n \"shape\",\n \"icon\",\n \"navbar\",\n \"gallery\",\n \"slider\",\n \"input\",\n \"textarea\",\n \"select\",\n \"checkbox\"\n ],\n \"fieldTypes\": [\n \"input\",\n \"textarea\",\n \"select\",\n \"checkbox\"\n ],\n \"themeTokens\": [\n \"primary\",\n \"secondary\",\n \"background\",\n \"surface\",\n \"text\",\n \"muted\"\n ],\n \"defaultTheme\": {\n \"primary\": \"#2563eb\",\n \"secondary\": \"#0f172a\",\n \"background\": \"#ffffff\",\n \"surface\": \"#f8fafc\",\n \"text\": \"#0f172a\",\n \"muted\": \"#64748b\",\n \"heading_font\": \"Inter\",\n \"body_font\": \"Inter\",\n \"radius\": 12,\n \"max_width\": 1200\n },\n \"opaquePropsMaxBytes\": 16384,\n \"styleTable\": {\n \"color\": {\n \"var\": \"c\",\n \"kind\": \"color\"\n },\n \"background\": {\n \"var\": \"bg\",\n \"kind\": \"color\"\n },\n \"font\": {\n \"attr\": \"font\",\n \"kind\": \"enum\"\n },\n \"size\": {\n \"var\": \"fs\",\n \"kind\": \"num\"\n },\n \"size_mobile\": {\n \"var\": \"fms\",\n \"kind\": \"num\"\n },\n \"tracking\": {\n \"var\": \"ls\",\n \"kind\": \"num\"\n },\n \"text_case\": {\n \"attr\": \"case\",\n \"kind\": \"enum\",\n \"skip\": \"none\"\n },\n \"text_style\": {\n \"attr\": \"text\",\n \"kind\": \"enum\",\n \"skip\": \"solid\"\n },\n \"auto_height\": {\n \"attr\": \"auto\",\n \"kind\": \"flag\"\n },\n \"weight\": {\n \"var\": \"fw\",\n \"kind\": \"num\"\n },\n \"align\": {\n \"attr\": \"align\",\n \"kind\": \"enum\"\n },\n \"line_height\": {\n \"var\": \"lh\",\n \"kind\": \"num\"\n },\n \"radius\": {\n \"var\": \"r\",\n \"kind\": \"num\"\n },\n \"border_width\": {\n \"var\": \"bw\",\n \"kind\": \"num\",\n \"skip\": 0\n },\n \"border_color\": {\n \"var\": \"bc\",\n \"kind\": \"color\"\n },\n \"padding\": {\n \"var\": \"p\",\n \"kind\": \"num\"\n },\n \"opacity\": {\n \"var\": \"op\",\n \"kind\": \"num\"\n },\n \"shadow\": {\n \"attr\": \"shadow\",\n \"kind\": \"enum\",\n \"skip\": \"none\"\n },\n \"shadow_custom\": {\n \"group\": {\n \"x\": {\n \"var\": \"shx\",\n \"kind\": \"num\"\n },\n \"y\": {\n \"var\": \"shy\",\n \"kind\": \"num\"\n },\n \"blur\": {\n \"var\": \"shb\",\n \"kind\": \"num\"\n },\n \"spread\": {\n \"var\": \"shs\",\n \"kind\": \"num\"\n },\n \"color\": {\n \"var\": \"shc\",\n \"kind\": \"color\"\n },\n \"opacity\": {\n \"var\": \"sha\",\n \"kind\": \"num\"\n }\n }\n },\n \"object_fit\": {\n \"attr\": \"fit\",\n \"kind\": \"enum\"\n },\n \"gradient\": {\n \"group\": {\n \"type\": {\n \"attr\": \"fill\",\n \"kind\": \"enum\",\n \"default\": \"linear\"\n },\n \"from\": {\n \"var\": \"g1\",\n \"kind\": \"color\"\n },\n \"to\": {\n \"var\": \"g2\",\n \"kind\": \"color\"\n },\n \"angle\": {\n \"var\": \"ga\",\n \"kind\": \"num\"\n }\n },\n \"requires\": [\n \"from\",\n \"to\"\n ]\n },\n \"background_opacity\": {\n \"var\": \"ba\",\n \"kind\": \"num\"\n },\n \"blur\": {\n \"var\": \"blur\",\n \"kind\": \"num\",\n \"skip\": 0\n },\n \"rotate\": {\n \"var\": \"rot\",\n \"kind\": \"num\",\n \"skip\": 0\n },\n \"flip_x\": {\n \"attr\": \"flip-x\",\n \"kind\": \"flag\"\n },\n \"flip_y\": {\n \"attr\": \"flip-y\",\n \"kind\": \"flag\"\n },\n \"clip\": {\n \"attr\": \"clip\",\n \"kind\": \"flag\"\n },\n \"pinned\": {\n \"attr\": \"pin\",\n \"kind\": \"flag\"\n },\n \"overflow\": {\n \"attr\": \"overflow\",\n \"kind\": \"enum\"\n },\n \"visible_on\": {\n \"attr\": \"visible\",\n \"kind\": \"enum\",\n \"skip\": \"all\"\n },\n \"accent_color\": {\n \"var\": \"ac\",\n \"kind\": \"color\"\n },\n \"scroll_background\": {\n \"var\": \"sbgc\",\n \"kind\": \"color\"\n },\n \"scroll_color\": {\n \"var\": \"sfgc\",\n \"kind\": \"color\"\n },\n \"hover\": {\n \"attr\": \"hover\",\n \"kind\": \"enum\",\n \"skip\": \"none\"\n },\n \"scroll\": {\n \"attr\": \"scroll\",\n \"kind\": \"enum\",\n \"skip\": \"none\"\n },\n \"animation\": {\n \"group\": {\n \"type\": {\n \"attr\": \"anim\",\n \"kind\": \"enum\",\n \"skip\": \"none\"\n },\n \"delay\": {\n \"var\": \"ad\",\n \"kind\": \"num\"\n },\n \"duration\": {\n \"var\": \"adur\",\n \"kind\": \"num\"\n }\n }\n }\n },\n \"actions\": {\n \"none\": {\n \"kind\": \"none\"\n },\n \"submit\": {\n \"kind\": \"submit\"\n },\n \"whatsapp\": {\n \"kind\": \"link\",\n \"prefix\": \"https://wa.me/\",\n \"keep\": \"0-9\"\n },\n \"phone\": {\n \"kind\": \"link\",\n \"prefix\": \"tel:\",\n \"keep\": \"0-9+\"\n },\n \"email\": {\n \"kind\": \"link\",\n \"prefix\": \"mailto:\"\n },\n \"url\": {\n \"kind\": \"link\",\n \"prefix\": \"\",\n \"requires\": \"https://\"\n },\n \"anchor\": {\n \"kind\": \"link\",\n \"prefix\": \"#s-\",\n \"keep\": \"a-zA-Z0-9_-\"\n },\n \"page\": {\n \"kind\": \"link\",\n \"prefix\": \"/\",\n \"keep\": \"a-z0-9-\",\n \"lower\": true,\n \"trim\": \"-\",\n \"base\": true\n },\n \"modal\": {\n \"kind\": \"behavior\",\n \"attr\": \"modal\",\n \"value\": \"id\"\n },\n \"top\": {\n \"kind\": \"behavior\",\n \"attr\": \"top\",\n \"value\": null\n },\n \"back\": {\n \"kind\": \"behavior\",\n \"attr\": \"back\",\n \"value\": null\n },\n \"step_next\": {\n \"kind\": \"behavior\",\n \"attr\": \"step\",\n \"value\": \"next\"\n },\n \"step_prev\": {\n \"kind\": \"behavior\",\n \"attr\": \"step\",\n \"value\": \"prev\"\n }\n },\n \"messages\": {\n \"en\": {\n \"close\": \"Close\",\n \"menu\": \"Open the menu\",\n \"sections\": \"Sections\",\n \"step\": \"Step {n}\",\n \"tab\": \"Tab {n}\",\n \"choose\": \"Choose an option\",\n \"submit\": \"Send\",\n \"icon\": \"Icon\",\n \"video\": \"Video\",\n \"previous\": \"Previous\",\n \"next\": \"Next\",\n \"slide\": \"Picture {n}\",\n \"unavailable\": \"This element needs a plugin that is not installed\"\n },\n \"es\": {\n \"close\": \"Cerrar\",\n \"menu\": \"Abrir el menú\",\n \"sections\": \"Secciones\",\n \"step\": \"Paso {n}\",\n \"tab\": \"Pestaña {n}\",\n \"choose\": \"Elige una opción\",\n \"submit\": \"Enviar\",\n \"icon\": \"Icono\",\n \"video\": \"Video\",\n \"previous\": \"Anterior\",\n \"next\": \"Siguiente\",\n \"slide\": \"Imagen {n}\",\n \"unavailable\": \"Este elemento necesita un complemento que no está instalado\"\n }\n },\n \"icons\": {\n \"activity\": [\n [\n \"path\",\n {\n \"d\": \"M22 12h-2.48a2 2 0 0 0-1.93 1.46l-2.35 8.36a.25.25 0 0 1-.48 0L9.24 2.18a.25.25 0 0 0-.48 0l-2.35 8.36A2 2 0 0 1 4.49 12H2\"\n }\n ]\n ],\n \"arrow-right\": [\n [\n \"path\",\n {\n \"d\": \"M5 12h14\"\n }\n ],\n [\n \"path\",\n {\n \"d\": \"m12 5 7 7-7 7\"\n }\n ]\n ],\n \"arrow-up-right\": [\n [\n \"path\",\n {\n \"d\": \"M7 7h10v10\"\n }\n ],\n [\n \"path\",\n {\n \"d\": \"M7 17 17 7\"\n }\n ]\n ],\n \"award\": [\n [\n \"path\",\n {\n \"d\": \"m15.477 12.89 1.515 8.526a.5.5 0 0 1-.81.47l-3.58-2.687a1 1 0 0 0-1.197 0l-3.586 2.686a.5.5 0 0 1-.81-.469l1.514-8.526\"\n }\n ],\n [\n \"circle\",\n {\n \"cx\": \"12\",\n \"cy\": \"8\",\n \"r\": \"6\"\n }\n ]\n ],\n \"badge-check\": [\n [\n \"path\",\n {\n \"d\": \"M3.85 8.62a4 4 0 0 1 4.78-4.77 4 4 0 0 1 6.74 0 4 4 0 0 1 4.78 4.78 4 4 0 0 1 0 6.74 4 4 0 0 1-4.77 4.78 4 4 0 0 1-6.75 0 4 4 0 0 1-4.78-4.77 4 4 0 0 1 0-6.76Z\"\n }\n ],\n [\n \"path\",\n {\n \"d\": \"m16 9-5.5 5.5L8 12\"\n }\n ]\n ],\n \"baby\": [\n [\n \"path\",\n {\n \"d\": \"M10 16c.5.3 1.2.5 2 .5s1.5-.2 2-.5\"\n }\n ],\n [\n \"path\",\n {\n \"d\": \"M15 12h.01\"\n }\n ],\n [\n \"path\",\n {\n \"d\": \"M19.38 6.813A9 9 0 0 1 20.8 10.2a2 2 0 0 1 0 3.6 9 9 0 0 1-17.6 0 2 2 0 0 1 0-3.6A9 9 0 0 1 12 3c2 0 3.5 1.1 3.5 2.5s-.9 2.5-2 2.5c-.8 0-1.5-.4-1.5-1\"\n }\n ],\n [\n \"path\",\n {\n \"d\": \"M9 12h.01\"\n }\n ]\n ],\n \"banknote\": [\n [\n \"rect\",\n {\n \"width\": \"20\",\n \"height\": \"12\",\n \"x\": \"2\",\n \"y\": \"6\",\n \"rx\": \"2\"\n }\n ],\n [\n \"circle\",\n {\n \"cx\": \"12\",\n \"cy\": \"12\",\n \"r\": \"2\"\n }\n ],\n [\n \"path\",\n {\n \"d\": \"M6 12h.01M18 12h.01\"\n }\n ]\n ],\n \"bone\": [\n [\n \"path\",\n {\n \"d\": \"M17 10c.7-.7 1.69 0 2.5 0a2.5 2.5 0 1 0 0-5 .5.5 0 0 1-.5-.5 2.5 2.5 0 1 0-5 0c0 .81.7 1.8 0 2.5l-7 7c-.7.7-1.69 0-2.5 0a2.5 2.5 0 0 0 0 5c.28 0 .5.22.5.5a2.5 2.5 0 1 0 5 0c0-.81-.7-1.8 0-2.5Z\"\n }\n ]\n ],\n \"brush\": [\n [\n \"path\",\n {\n \"d\": \"m11 10 3 3\"\n }\n ],\n [\n \"path\",\n {\n \"d\": \"M6.5 21A3.5 3.5 0 1 0 3 17.5a2.62 2.62 0 0 1-.708 1.792A1 1 0 0 0 3 21z\"\n }\n ],\n [\n \"path\",\n {\n \"d\": \"M9.969 17.031 21.378 5.624a1 1 0 0 0-3.002-3.002L6.967 14.031\"\n }\n ]\n ],\n \"bus\": [\n [\n \"path\",\n {\n \"d\": \"M8 6v6\"\n }\n ],\n [\n \"path\",\n {\n \"d\": \"M15 6v6\"\n }\n ],\n [\n \"path\",\n {\n \"d\": \"M2 12h19.6\"\n }\n ],\n [\n \"path\",\n {\n \"d\": \"M18 18h3s.5-1.7.8-2.8c.1-.4.2-.8.2-1.2 0-.4-.1-.8-.2-1.2l-1.4-5C20.1 6.8 19.1 6 18 6H4a2 2 0 0 0-2 2v10h3\"\n }\n ],\n [\n \"circle\",\n {\n \"cx\": \"7\",\n \"cy\": \"18\",\n \"r\": \"2\"\n }\n ],\n [\n \"path\",\n {\n \"d\": \"M9 18h5\"\n }\n ],\n [\n \"circle\",\n {\n \"cx\": \"16\",\n \"cy\": \"18\",\n \"r\": \"2\"\n }\n ]\n ],\n \"calendar\": [\n [\n \"path\",\n {\n \"d\": \"M8 2v3\"\n }\n ],\n [\n \"path\",\n {\n \"d\": \"M16 2v3\"\n }\n ],\n [\n \"rect\",\n {\n \"x\": \"3\",\n \"y\": \"3\",\n \"width\": \"18\",\n \"height\": \"18\",\n \"rx\": \"2\"\n }\n ],\n [\n \"path\",\n {\n \"d\": \"M3 9h18\"\n }\n ]\n ],\n \"calendar-check\": [\n [\n \"path\",\n {\n \"d\": \"M8 2v3\"\n }\n ],\n [\n \"path\",\n {\n \"d\": \"M16 2v3\"\n }\n ],\n [\n \"rect\",\n {\n \"x\": \"3\",\n \"y\": \"3\",\n \"width\": \"18\",\n \"height\": \"18\",\n \"rx\": \"2\"\n }\n ],\n [\n \"path\",\n {\n \"d\": \"M3 9h18\"\n }\n ],\n [\n \"path\",\n {\n \"d\": \"m9 15 2 2 4-4\"\n }\n ]\n ],\n \"calendar-days\": [\n [\n \"path\",\n {\n \"d\": \"M8 2v3\"\n }\n ],\n [\n \"path\",\n {\n \"d\": \"M16 2v3\"\n }\n ],\n [\n \"rect\",\n {\n \"x\": \"3\",\n \"y\": \"3\",\n \"width\": \"18\",\n \"height\": \"18\",\n \"rx\": \"2\"\n }\n ],\n [\n \"path\",\n {\n \"d\": \"M3 9h18\"\n }\n ],\n [\n \"path\",\n {\n \"d\": \"M8 13h.01\"\n }\n ],\n [\n \"path\",\n {\n \"d\": \"M12 13h.01\"\n }\n ],\n [\n \"path\",\n {\n \"d\": \"M16 13h.01\"\n }\n ],\n [\n \"path\",\n {\n \"d\": \"M8 17h.01\"\n }\n ],\n [\n \"path\",\n {\n \"d\": \"M12 17h.01\"\n }\n ],\n [\n \"path\",\n {\n \"d\": \"M16 17h.01\"\n }\n ]\n ],\n \"camera\": [\n [\n \"path\",\n {\n \"d\": \"M13.997 4a2 2 0 0 1 1.76 1.05l.486.9A2 2 0 0 0 18.003 7H20a2 2 0 0 1 2 2v9a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V9a2 2 0 0 1 2-2h1.997a2 2 0 0 0 1.759-1.048l.489-.904A2 2 0 0 1 10.004 4z\"\n }\n ],\n [\n \"circle\",\n {\n \"cx\": \"12\",\n \"cy\": \"13\",\n \"r\": \"3\"\n }\n ]\n ],\n \"car\": [\n [\n \"path\",\n {\n \"d\": \"M19 17h2c.6 0 1-.4 1-1v-3c0-.9-.7-1.7-1.5-1.9C18.7 10.6 16 10 16 10s-1.3-1.4-2.2-2.3c-.5-.4-1.1-.7-1.8-.7H5c-.6 0-1.1.4-1.4.9l-1.4 2.9A3.7 3.7 0 0 0 2 12v4c0 .6.4 1 1 1h2\"\n }\n ],\n [\n \"circle\",\n {\n \"cx\": \"7\",\n \"cy\": \"17\",\n \"r\": \"2\"\n }\n ],\n [\n \"path\",\n {\n \"d\": \"M9 17h6\"\n }\n ],\n [\n \"circle\",\n {\n \"cx\": \"17\",\n \"cy\": \"17\",\n \"r\": \"2\"\n }\n ]\n ],\n \"check\": [\n [\n \"path\",\n {\n \"d\": \"M20 6 9 17l-5-5\"\n }\n ]\n ],\n \"chevron-right\": [\n [\n \"path\",\n {\n \"d\": \"m9 18 6-6-6-6\"\n }\n ]\n ],\n \"circle-check\": [\n [\n \"circle\",\n {\n \"cx\": \"12\",\n \"cy\": \"12\",\n \"r\": \"10\"\n }\n ],\n [\n \"path\",\n {\n \"d\": \"m16 9-5.5 5.5L8 12\"\n }\n ]\n ],\n \"clipboard-list\": [\n [\n \"rect\",\n {\n \"width\": \"8\",\n \"height\": \"4\",\n \"x\": \"8\",\n \"y\": \"2\",\n \"rx\": \"1\",\n \"ry\": \"1\"\n }\n ],\n [\n \"path\",\n {\n \"d\": \"M16 4h2a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h2\"\n }\n ],\n [\n \"path\",\n {\n \"d\": \"M12 11h4\"\n }\n ],\n [\n \"path\",\n {\n \"d\": \"M12 16h4\"\n }\n ],\n [\n \"path\",\n {\n \"d\": \"M8 11h.01\"\n }\n ],\n [\n \"path\",\n {\n \"d\": \"M8 16h.01\"\n }\n ]\n ],\n \"clock\": [\n [\n \"circle\",\n {\n \"cx\": \"12\",\n \"cy\": \"12\",\n \"r\": \"10\"\n }\n ],\n [\n \"path\",\n {\n \"d\": \"M12 6v6l4 2\"\n }\n ]\n ],\n \"coffee\": [\n [\n \"path\",\n {\n \"d\": \"M10 2v2\"\n }\n ],\n [\n \"path\",\n {\n \"d\": \"M14 2v2\"\n }\n ],\n [\n \"path\",\n {\n \"d\": \"M16 8a1 1 0 0 1 1 1v8a4 4 0 0 1-4 4H7a4 4 0 0 1-4-4V9a1 1 0 0 1 1-1h14a4 4 0 1 1 0 8h-1\"\n }\n ],\n [\n \"path\",\n {\n \"d\": \"M6 2v2\"\n }\n ]\n ],\n \"credit-card\": [\n [\n \"rect\",\n {\n \"width\": \"20\",\n \"height\": \"14\",\n \"x\": \"2\",\n \"y\": \"5\",\n \"rx\": \"2\"\n }\n ],\n [\n \"line\",\n {\n \"x1\": \"2\",\n \"x2\": \"22\",\n \"y1\": \"10\",\n \"y2\": \"10\"\n }\n ],\n [\n \"path\",\n {\n \"d\": \"M6 14h2\"\n }\n ]\n ],\n \"droplet\": [\n [\n \"path\",\n {\n \"d\": \"M12 22a7 7 0 0 0 7-7c0-2-1-3.9-3-5.5s-3.5-4-4-6.5c-.5 2.5-2 4.9-4 6.5C6 11.1 5 13 5 15a7 7 0 0 0 7 7z\"\n }\n ]\n ],\n \"file-text\": [\n [\n \"path\",\n {\n \"d\": \"M6 22a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h8a2.4 2.4 0 0 1 1.704.706l3.588 3.588A2.4 2.4 0 0 1 20 8v12a2 2 0 0 1-2 2z\"\n }\n ],\n [\n \"path\",\n {\n \"d\": \"M14 2v5a1 1 0 0 0 1 1h5\"\n }\n ],\n [\n \"path\",\n {\n \"d\": \"M10 9H8\"\n }\n ],\n [\n \"path\",\n {\n \"d\": \"M16 13H8\"\n }\n ],\n [\n \"path\",\n {\n \"d\": \"M16 17H8\"\n }\n ]\n ],\n \"gift\": [\n [\n \"path\",\n {\n \"d\": \"M12 7v14\"\n }\n ],\n [\n \"path\",\n {\n \"d\": \"M20 11v8a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2v-8\"\n }\n ],\n [\n \"path\",\n {\n \"d\": \"M7.5 7a1 1 0 0 1 0-5A4.8 8 0 0 1 12 7a4.8 8 0 0 1 4.5-5 1 1 0 0 1 0 5\"\n }\n ],\n [\n \"rect\",\n {\n \"x\": \"3\",\n \"y\": \"7\",\n \"width\": \"18\",\n \"height\": \"4\",\n \"rx\": \"1\"\n }\n ]\n ],\n \"globe\": [\n [\n \"circle\",\n {\n \"cx\": \"12\",\n \"cy\": \"12\",\n \"r\": \"10\"\n }\n ],\n [\n \"path\",\n {\n \"d\": \"M12 2a14.5 14.5 0 0 0 0 20 14.5 14.5 0 0 0 0-20\"\n }\n ],\n [\n \"path\",\n {\n \"d\": \"M2 12h20\"\n }\n ]\n ],\n \"hand-heart\": [\n [\n \"path\",\n {\n \"d\": \"M11 14h2a2 2 0 0 0 0-4h-3c-.6 0-1.1.2-1.4.6L3 16\"\n }\n ],\n [\n \"path\",\n {\n \"d\": \"m14.45 13.39 5.05-4.694C20.196 8 21 6.85 21 5.75a2.75 2.75 0 0 0-4.797-1.837.276.276 0 0 1-.406 0A2.75 2.75 0 0 0 11 5.75c0 1.2.802 2.248 1.5 2.946L16 11.95\"\n }\n ],\n [\n \"path\",\n {\n \"d\": \"m2 15 6 6\"\n }\n ],\n [\n \"path\",\n {\n \"d\": \"m7 20 1.6-1.4c.3-.4.8-.6 1.4-.6h4c1.1 0 2.1-.4 2.8-1.2l4.6-4.4a1 1 0 0 0-2.75-2.91\"\n }\n ]\n ],\n \"heart\": [\n [\n \"path\",\n {\n \"d\": \"M2 9.5a5.5 5.5 0 0 1 9.591-3.676.56.56 0 0 0 .818 0A5.49 5.49 0 0 1 22 9.5c0 2.29-1.5 4-3 5.5l-5.492 5.313a2 2 0 0 1-3 .019L5 15c-1.5-1.5-3-3.2-3-5.5\"\n }\n ]\n ],\n \"heart-pulse\": [\n [\n \"path\",\n {\n \"d\": \"M2 9.5a5.5 5.5 0 0 1 9.591-3.676.56.56 0 0 0 .818 0A5.49 5.49 0 0 1 22 9.5c0 2.29-1.5 4-3 5.5l-5.492 5.313a2 2 0 0 1-3 .019L5 15c-1.5-1.5-3-3.2-3-5.5\"\n }\n ],\n [\n \"path\",\n {\n \"d\": \"M3.22 13H9.5l.5-1 2 4.5 2-7 1.5 3.5h5.27\"\n }\n ]\n ],\n \"house\": [\n [\n \"path\",\n {\n \"d\": \"M15 21v-8a1 1 0 0 0-1-1h-4a1 1 0 0 0-1 1v8\"\n }\n ],\n [\n \"path\",\n {\n \"d\": \"M3 10a2 2 0 0 1 .709-1.528l7-6a2 2 0 0 1 2.582 0l7 6A2 2 0 0 1 21 10v9a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z\"\n }\n ]\n ],\n \"image\": [\n [\n \"rect\",\n {\n \"width\": \"18\",\n \"height\": \"18\",\n \"x\": \"3\",\n \"y\": \"3\",\n \"rx\": \"2\",\n \"ry\": \"2\"\n }\n ],\n [\n \"circle\",\n {\n \"cx\": \"9\",\n \"cy\": \"9\",\n \"r\": \"2\"\n }\n ],\n [\n \"path\",\n {\n \"d\": \"m21 15-3.086-3.086a2 2 0 0 0-2.828 0L6 21\"\n }\n ]\n ],\n \"leaf\": [\n [\n \"path\",\n {\n \"d\": \"M11 20a10 10 0 0010-10 25.9 25.9 0 00-1.04-7.281 1 1 0 00-1.755-.325C15.833 5.5 13 5.5 9.8 6.1A7 7 0 0011 20\"\n }\n ],\n [\n \"path\",\n {\n \"d\": \"M2 21a5 5 0 012.911-4.544C7.613 15.212 8.351 15.24 11 13\"\n }\n ]\n ],\n \"lightbulb\": [\n [\n \"path\",\n {\n \"d\": \"M15 14c.2-1 .7-1.7 1.5-2.5 1-.9 1.5-2.2 1.5-3.5A6 6 0 0 0 6 8c0 1 .2 2.2 1.5 3.5.7.7 1.3 1.5 1.5 2.5\"\n }\n ],\n [\n \"path\",\n {\n \"d\": \"M9 18h6\"\n }\n ],\n [\n \"path\",\n {\n \"d\": \"M10 22h4\"\n }\n ]\n ],\n \"mail\": [\n [\n \"path\",\n {\n \"d\": \"m22 7-8.991 5.727a2 2 0 0 1-2.009 0L2 7\"\n }\n ],\n [\n \"rect\",\n {\n \"x\": \"2\",\n \"y\": \"4\",\n \"width\": \"20\",\n \"height\": \"16\",\n \"rx\": \"2\"\n }\n ]\n ],\n \"map-pin\": [\n [\n \"path\",\n {\n \"d\": \"M20 10c0 4.993-5.539 10.193-7.399 11.799a1 1 0 0 1-1.202 0C9.539 20.193 4 14.993 4 10a8 8 0 0 1 16 0\"\n }\n ],\n [\n \"circle\",\n {\n \"cx\": \"12\",\n \"cy\": \"10\",\n \"r\": \"3\"\n }\n ]\n ],\n \"message-circle\": [\n [\n \"path\",\n {\n \"d\": \"M2.992 16.342a2 2 0 0 1 .094 1.167l-1.065 3.29a1 1 0 0 0 1.236 1.168l3.413-.998a2 2 0 0 1 1.099.092 10 10 0 1 0-4.777-4.719\"\n }\n ]\n ],\n \"microscope\": [\n [\n \"path\",\n {\n \"d\": \"M6 18h8\"\n }\n ],\n [\n \"path\",\n {\n \"d\": \"M3 22h18\"\n }\n ],\n [\n \"path\",\n {\n \"d\": \"M14 22a7 7 0 1 0 0-14h-1\"\n }\n ],\n [\n \"path\",\n {\n \"d\": \"M9 14h2\"\n }\n ],\n [\n \"path\",\n {\n \"d\": \"M9 12a2 2 0 0 1-2-2V6h6v4a2 2 0 0 1-2 2Z\"\n }\n ],\n [\n \"path\",\n {\n \"d\": \"M12 6V3a1 1 0 0 0-1-1H9a1 1 0 0 0-1 1v3\"\n }\n ]\n ],\n \"moon\": [\n [\n \"path\",\n {\n \"d\": \"M20.985 12.486a9 9 0 1 1-9.473-9.472c.405-.022.617.46.402.803a6 6 0 0 0 8.268 8.268c.344-.215.825-.004.803.401\"\n }\n ]\n ],\n \"percent\": [\n [\n \"line\",\n {\n \"x1\": \"19\",\n \"x2\": \"5\",\n \"y1\": \"5\",\n \"y2\": \"19\"\n }\n ],\n [\n \"circle\",\n {\n \"cx\": \"6.5\",\n \"cy\": \"6.5\",\n \"r\": \"2.5\"\n }\n ],\n [\n \"circle\",\n {\n \"cx\": \"17.5\",\n \"cy\": \"17.5\",\n \"r\": \"2.5\"\n }\n ]\n ],\n \"phone\": [\n [\n \"path\",\n {\n \"d\": \"M13.832 16.568a1 1 0 0 0 1.213-.303l.355-.465A2 2 0 0 1 17 15h3a2 2 0 0 1 2 2v3a2 2 0 0 1-2 2A18 18 0 0 1 2 4a2 2 0 0 1 2-2h3a2 2 0 0 1 2 2v3a2 2 0 0 1-.8 1.6l-.468.351a1 1 0 0 0-.292 1.233 14 14 0 0 0 6.392 6.384\"\n }\n ]\n ],\n \"pill\": [\n [\n \"path\",\n {\n \"d\": \"m10.5 20.5 10-10a4.95 4.95 0 1 0-7-7l-10 10a4.95 4.95 0 1 0 7 7Z\"\n }\n ],\n [\n \"path\",\n {\n \"d\": \"m8.5 8.5 7 7\"\n }\n ]\n ],\n \"play\": [\n [\n \"path\",\n {\n \"d\": \"M5 5a2 2 0 0 1 3.008-1.728l11.997 6.998a2 2 0 0 1 .003 3.458l-12 7A2 2 0 0 1 5 19z\"\n }\n ]\n ],\n \"quote\": [\n [\n \"path\",\n {\n \"d\": \"M16 3a2 2 0 0 0-2 2v6a2 2 0 0 0 2 2 1 1 0 0 1 1 1v1a2 2 0 0 1-2 2 1 1 0 0 0-1 1v2a1 1 0 0 0 1 1 6 6 0 0 0 6-6V5a2 2 0 0 0-2-2z\"\n }\n ],\n [\n \"path\",\n {\n \"d\": \"M5 3a2 2 0 0 0-2 2v6a2 2 0 0 0 2 2 1 1 0 0 1 1 1v1a2 2 0 0 1-2 2 1 1 0 0 0-1 1v2a1 1 0 0 0 1 1 6 6 0 0 0 6-6V5a2 2 0 0 0-2-2z\"\n }\n ]\n ],\n \"scissors\": [\n [\n \"circle\",\n {\n \"cx\": \"6\",\n \"cy\": \"6\",\n \"r\": \"3\"\n }\n ],\n [\n \"path\",\n {\n \"d\": \"M8.12 8.12 12 12\"\n }\n ],\n [\n \"path\",\n {\n \"d\": \"M20 4 8.12 15.88\"\n }\n ],\n [\n \"circle\",\n {\n \"cx\": \"6\",\n \"cy\": \"18\",\n \"r\": \"3\"\n }\n ],\n [\n \"path\",\n {\n \"d\": \"M14.8 14.8 20 20\"\n }\n ]\n ],\n \"send\": [\n [\n \"path\",\n {\n \"d\": \"M14.536 21.686a.5.5 0 0 0 .937-.024l6.5-19a.496.496 0 0 0-.635-.635l-19 6.5a.5.5 0 0 0-.024.937l7.93 3.18a2 2 0 0 1 1.112 1.11z\"\n }\n ],\n [\n \"path\",\n {\n \"d\": \"m21.854 2.147-10.94 10.939\"\n }\n ]\n ],\n \"share-2\": [\n [\n \"circle\",\n {\n \"cx\": \"18\",\n \"cy\": \"5\",\n \"r\": \"3\"\n }\n ],\n [\n \"circle\",\n {\n \"cx\": \"6\",\n \"cy\": \"12\",\n \"r\": \"3\"\n }\n ],\n [\n \"circle\",\n {\n \"cx\": \"18\",\n \"cy\": \"19\",\n \"r\": \"3\"\n }\n ],\n [\n \"line\",\n {\n \"x1\": \"8.59\",\n \"x2\": \"15.42\",\n \"y1\": \"13.51\",\n \"y2\": \"17.49\"\n }\n ],\n [\n \"line\",\n {\n \"x1\": \"15.41\",\n \"x2\": \"8.59\",\n \"y1\": \"6.51\",\n \"y2\": \"10.49\"\n }\n ]\n ],\n \"shield-check\": [\n [\n \"path\",\n {\n \"d\": \"M20 13c0 5-3.5 7.5-7.66 8.95a1 1 0 0 1-.67-.01C7.5 20.5 4 18 4 13V6a1 1 0 0 1 1-1c2 0 4.5-1.2 6.24-2.72a1.17 1.17 0 0 1 1.52 0C14.51 3.81 17 5 19 5a1 1 0 0 1 1 1z\"\n }\n ],\n [\n \"path\",\n {\n \"d\": \"m9 12 2 2 4-4\"\n }\n ]\n ],\n \"sparkles\": [\n [\n \"path\",\n {\n \"d\": \"M11.017 2.814a1 1 0 0 1 1.966 0l1.051 5.558a2 2 0 0 0 1.594 1.594l5.558 1.051a1 1 0 0 1 0 1.966l-5.558 1.051a2 2 0 0 0-1.594 1.594l-1.051 5.558a1 1 0 0 1-1.966 0l-1.051-5.558a2 2 0 0 0-1.594-1.594l-5.558-1.051a1 1 0 0 1 0-1.966l5.558-1.051a2 2 0 0 0 1.594-1.594z\"\n }\n ],\n [\n \"path\",\n {\n \"d\": \"M20 2v4\"\n }\n ],\n [\n \"path\",\n {\n \"d\": \"M22 4h-4\"\n }\n ],\n [\n \"circle\",\n {\n \"cx\": \"4\",\n \"cy\": \"20\",\n \"r\": \"2\"\n }\n ]\n ],\n \"star\": [\n [\n \"path\",\n {\n \"d\": \"M11.525 2.295a.53.53 0 0 1 .95 0l2.31 4.679a2.123 2.123 0 0 0 1.595 1.16l5.166.756a.53.53 0 0 1 .294.904l-3.736 3.638a2.123 2.123 0 0 0-.611 1.878l.882 5.14a.53.53 0 0 1-.771.56l-4.618-2.428a2.122 2.122 0 0 0-1.973 0L6.396 21.01a.53.53 0 0 1-.77-.56l.881-5.139a2.122 2.122 0 0 0-.611-1.879L2.16 9.795a.53.53 0 0 1 .294-.906l5.165-.755a2.122 2.122 0 0 0 1.597-1.16z\"\n }\n ]\n ],\n \"stethoscope\": [\n [\n \"path\",\n {\n \"d\": \"M11 2v2\"\n }\n ],\n [\n \"path\",\n {\n \"d\": \"M5 2v2\"\n }\n ],\n [\n \"path\",\n {\n \"d\": \"M5 3H4a2 2 0 0 0-2 2v4a6 6 0 0 0 12 0V5a2 2 0 0 0-2-2h-1\"\n }\n ],\n [\n \"path\",\n {\n \"d\": \"M8 15a6 6 0 0 0 12 0v-3\"\n }\n ],\n [\n \"circle\",\n {\n \"cx\": \"20\",\n \"cy\": \"10\",\n \"r\": \"2\"\n }\n ]\n ],\n \"sun\": [\n [\n \"circle\",\n {\n \"cx\": \"12\",\n \"cy\": \"12\",\n \"r\": \"4\"\n }\n ],\n [\n \"path\",\n {\n \"d\": \"M12 2v2\"\n }\n ],\n [\n \"path\",\n {\n \"d\": \"M12 20v2\"\n }\n ],\n [\n \"path\",\n {\n \"d\": \"m4.93 4.93 1.41 1.41\"\n }\n ],\n [\n \"path\",\n {\n \"d\": \"m17.66 17.66 1.41 1.41\"\n }\n ],\n [\n \"path\",\n {\n \"d\": \"M2 12h2\"\n }\n ],\n [\n \"path\",\n {\n \"d\": \"M20 12h2\"\n }\n ],\n [\n \"path\",\n {\n \"d\": \"m6.34 17.66-1.41 1.41\"\n }\n ],\n [\n \"path\",\n {\n \"d\": \"m19.07 4.93-1.41 1.41\"\n }\n ]\n ],\n \"syringe\": [\n [\n \"path\",\n {\n \"d\": \"m18 2 4 4\"\n }\n ],\n [\n \"path\",\n {\n \"d\": \"m17 7 3-3\"\n }\n ],\n [\n \"path\",\n {\n \"d\": \"M19 9 8.7 19.3c-1 1-2.5 1-3.4 0l-.6-.6c-1-1-1-2.5 0-3.4L15 5\"\n }\n ],\n [\n \"path\",\n {\n \"d\": \"m9 11 4 4\"\n }\n ],\n [\n \"path\",\n {\n \"d\": \"m5 19-3 3\"\n }\n ],\n [\n \"path\",\n {\n \"d\": \"m14 4 6 6\"\n }\n ]\n ],\n \"thumbs-up\": [\n [\n \"path\",\n {\n \"d\": \"M15 5.88 14 10h5.83a2 2 0 0 1 1.92 2.56l-2.33 8A2 2 0 0 1 17.5 22H4a2 2 0 0 1-2-2v-8a2 2 0 0 1 2-2h2.76a2 2 0 0 0 1.79-1.11L12 2a3.13 3.13 0 0 1 3 3.88Z\"\n }\n ],\n [\n \"path\",\n {\n \"d\": \"M7 10v12\"\n }\n ]\n ],\n \"timer\": [\n [\n \"line\",\n {\n \"x1\": \"10\",\n \"x2\": \"14\",\n \"y1\": \"2\",\n \"y2\": \"2\"\n }\n ],\n [\n \"line\",\n {\n \"x1\": \"12\",\n \"x2\": \"15\",\n \"y1\": \"14\",\n \"y2\": \"11\"\n }\n ],\n [\n \"circle\",\n {\n \"cx\": \"12\",\n \"cy\": \"14\",\n \"r\": \"8\"\n }\n ]\n ],\n \"user\": [\n [\n \"path\",\n {\n \"d\": \"M19 21v-2a4 4 0 0 0-4-4H9a4 4 0 0 0-4 4v2\"\n }\n ],\n [\n \"circle\",\n {\n \"cx\": \"12\",\n \"cy\": \"7\",\n \"r\": \"4\"\n }\n ]\n ],\n \"users\": [\n [\n \"path\",\n {\n \"d\": \"M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2\"\n }\n ],\n [\n \"path\",\n {\n \"d\": \"M16 3.128a4 4 0 0 1 0 7.744\"\n }\n ],\n [\n \"path\",\n {\n \"d\": \"M22 21v-2a4 4 0 0 0-3-3.87\"\n }\n ],\n [\n \"circle\",\n {\n \"cx\": \"9\",\n \"cy\": \"7\",\n \"r\": \"4\"\n }\n ]\n ],\n \"video\": [\n [\n \"path\",\n {\n \"d\": \"m16 13 5.223 3.482a.5.5 0 0 0 .777-.416V7.87a.5.5 0 0 0-.752-.432L16 10.5\"\n }\n ],\n [\n \"rect\",\n {\n \"x\": \"2\",\n \"y\": \"6\",\n \"width\": \"14\",\n \"height\": \"12\",\n \"rx\": \"2\"\n }\n ]\n ],\n \"wallet\": [\n [\n \"path\",\n {\n \"d\": \"M19 7V4a1 1 0 0 0-1-1H5a2 2 0 0 0 0 4h15a1 1 0 0 1 1 1v4h-3a2 2 0 0 0 0 4h3a1 1 0 0 0 1-1v-2a1 1 0 0 0-1-1\"\n }\n ],\n [\n \"path\",\n {\n \"d\": \"M3 5v14a2 2 0 0 0 2 2h15a1 1 0 0 0 1-1v-4\"\n }\n ]\n ],\n \"wifi\": [\n [\n \"path\",\n {\n \"d\": \"M12 20h.01\"\n }\n ],\n [\n \"path\",\n {\n \"d\": \"M2 8.82a15 15 0 0 1 20 0\"\n }\n ],\n [\n \"path\",\n {\n \"d\": \"M5 12.859a10 10 0 0 1 14 0\"\n }\n ],\n [\n \"path\",\n {\n \"d\": \"M8.5 16.429a5 5 0 0 1 7 0\"\n }\n ]\n ],\n \"at-sign\": [\n [\n \"circle\",\n {\n \"cx\": \"12\",\n \"cy\": \"12\",\n \"r\": \"4\"\n }\n ],\n [\n \"path\",\n {\n \"d\": \"M16 8v5a3 3 0 0 0 6 0v-1a10 10 0 1 0-4 8\"\n }\n ]\n ]\n }\n}\n","import { icons as catalog } from '@skylivellc/lienzo-core/data.json';\n\n/** One stroke of a catalog icon, as core renders it. */\nexport type IconNode = readonly [tag: 'path' | 'circle' | 'rect' | 'line', attrs: Readonly<Record<string, string>>];\n\nconst TAGS: ReadonlySet<string> = new Set(['path', 'circle', 'rect', 'line']);\n\nconst isNode = (value: unknown): value is IconNode =>\n Array.isArray(value) && value.length === 2 && typeof value[0] === 'string' && TAGS.has(value[0])\n && typeof value[1] === 'object' && value[1] !== null && Object.values(value[1]).every((attr) => typeof attr === 'string');\n\nfunction parseIcons(input: unknown): ReadonlyMap<string, readonly IconNode[]> {\n const entries = typeof input === 'object' && input !== null ? Object.entries(input) : [];\n\n return new Map(entries.flatMap(([name, nodes]): [string, IconNode[]][] => (Array.isArray(nodes) && nodes.every(isNode) ? [[name, nodes]] : [])));\n}\n\n/** Lienzo's icon catalog (lucide strokes), the same one public pages draw from. */\nexport const icons = parseIcons(catalog);\nexport const ICON_NAMES: readonly string[] = [...icons.keys()];\n","<script setup lang=\"ts\">\nimport { computed } from 'vue';\nimport { icons } from '../model/icons.ts';\n\n/** An icon from Lienzo's icon catalog (the same strokes the page renders), for pickers and app elements. */\nconst props = withDefaults(defineProps<{ name: string; size?: number; stroke?: number }>(), { size: 18, stroke: 2 });\nconst nodes = computed(() => icons.get(props.name) ?? []);\n</script>\n\n<template>\n <svg :width=\"size\" :height=\"size\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" :stroke-width=\"stroke\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\">\n <component :is=\"node[0]\" v-for=\"(node, index) in nodes\" :key=\"index\" v-bind=\"node[1]\" />\n </svg>\n</template>\n","<script setup lang=\"ts\">\nimport { computed } from 'vue';\nimport { icons } from '../model/icons.ts';\n\n/** An icon from Lienzo's icon catalog (the same strokes the page renders), for pickers and app elements. */\nconst props = withDefaults(defineProps<{ name: string; size?: number; stroke?: number }>(), { size: 18, stroke: 2 });\nconst nodes = computed(() => icons.get(props.name) ?? []);\n</script>\n\n<template>\n <svg :width=\"size\" :height=\"size\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" :stroke-width=\"stroke\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\">\n <component :is=\"node[0]\" v-for=\"(node, index) in nodes\" :key=\"index\" v-bind=\"node[1]\" />\n </svg>\n</template>\n","import type { CoreElementType } from '@skylivellc/lienzo-core';\nimport {\n AlignLeft,\n GalleryHorizontalEnd,\n Image,\n Images,\n ListFilter,\n Menu,\n Minus,\n MousePointerClick,\n Pilcrow,\n Sparkles,\n Square,\n SquareCheck,\n TextCursorInput,\n Type,\n Video,\n} from '@lucide/vue';\nimport type { Component } from 'vue';\n\n/** Icon per core type, so the palette and the layers read at a glance. */\nexport const typeIcons: Record<CoreElementType, Component> = {\n heading: Type,\n text: AlignLeft,\n image: Image,\n button: MousePointerClick,\n divider: Minus,\n video: Video,\n shape: Square,\n icon: Sparkles,\n navbar: Menu,\n gallery: Images,\n slider: GalleryHorizontalEnd,\n input: TextCursorInput,\n textarea: Pilcrow,\n select: ListFilter,\n checkbox: SquareCheck,\n};\n","<script setup lang=\"ts\">\nimport type { Element } from '@skylivellc/lienzo-core';\nimport { CircleHelp } from '@lucide/vue';\nimport { computed } from 'vue';\nimport { useEditor } from '../state/editor.ts';\nimport CatalogIcon from '../ui/CatalogIcon.vue';\nimport { typeIcons } from './typeIcons.ts';\n\n/** The icon of an element's type: lucide for core types, the catalog icon the app chose for its own. */\nconst props = withDefaults(defineProps<{ element: Element; size?: number }>(), { size: 14 });\nconst editor = useEditor();\nconst kind = computed(() => editor.kindOf(props.element));\n</script>\n\n<template>\n <component :is=\"typeIcons[kind.element.type]\" v-if=\"kind.kind === 'core'\" :size=\"size\" aria-hidden=\"true\" />\n <CatalogIcon v-else-if=\"kind.kind === 'app'\" :name=\"kind.spec.icon\" :size=\"size\" />\n <CircleHelp v-else :size=\"size\" aria-hidden=\"true\" />\n</template>\n","<script setup lang=\"ts\">\nimport type { Element } from '@skylivellc/lienzo-core';\nimport { CircleHelp } from '@lucide/vue';\nimport { computed } from 'vue';\nimport { useEditor } from '../state/editor.ts';\nimport CatalogIcon from '../ui/CatalogIcon.vue';\nimport { typeIcons } from './typeIcons.ts';\n\n/** The icon of an element's type: lucide for core types, the catalog icon the app chose for its own. */\nconst props = withDefaults(defineProps<{ element: Element; size?: number }>(), { size: 14 });\nconst editor = useEditor();\nconst kind = computed(() => editor.kindOf(props.element));\n</script>\n\n<template>\n <component :is=\"typeIcons[kind.element.type]\" v-if=\"kind.kind === 'core'\" :size=\"size\" aria-hidden=\"true\" />\n <CatalogIcon v-else-if=\"kind.kind === 'app'\" :name=\"kind.spec.icon\" :size=\"size\" />\n <CircleHelp v-else :size=\"size\" aria-hidden=\"true\" />\n</template>\n","<script setup lang=\"ts\">\nimport type { CoreElementType } from '@skylivellc/lienzo-core';\nimport { ChevronDown, ChevronUp, Frame, Image as ImageIcon, Layers, LayoutTemplate, Lock, LockOpen, PanelTop, Plus, Trash2 } from '@lucide/vue';\nimport { computed, ref } from 'vue';\nimport { CORE_TYPES, isModal } from '../model/document.ts';\nimport { coreSpecs, elementName, type Insertable } from '../model/elements.ts';\nimport { buildSectionTemplate, SECTION_TEMPLATES, TEMPLATE_GROUPS } from '../model/templates.ts';\nimport { useEditor } from '../state/editor.ts';\nimport CatalogIcon from '../ui/CatalogIcon.vue';\nimport ElementIcon from './ElementIcon.vue';\nimport { typeIcons } from './typeIcons.ts';\n\n/** Left sidebar: what to add, the layer tree, the modals, and the media library. */\nconst props = defineProps<{ dropPoint: (clientX: number, clientY: number) => { canvas: string; x: number; y: number } | null }>();\nconst editor = useEditor();\nconst t = editor.t;\n\ntype Tab = 'elements' | 'blocks' | 'layers' | 'modals' | 'media';\nconst tab = ref<Tab>('elements');\nconst tabs = [\n { key: 'elements', label: 'tabs.elements', icon: Plus },\n { key: 'blocks', label: 'tabs.blocks', icon: LayoutTemplate },\n { key: 'layers', label: 'tabs.layers', icon: Layers },\n { key: 'modals', label: 'tabs.modals', icon: PanelTop },\n { key: 'media', label: 'tabs.media', icon: ImageIcon },\n] as const;\n\nconst contentTypes = CORE_TYPES.filter((type) => coreSpecs[type].group === 'content');\nconst formTypes = CORE_TYPES.filter((type) => coreSpecs[type].group === 'form');\n\n\nconst dragging = ref<{ insertable: Insertable; src?: string; label: string; x: number; y: number; moved: boolean } | null>(null);\n\nfunction startDrag(event: PointerEvent, insertable: Insertable, label: string, src?: string) {\n if (event.button !== 0) {\n return;\n }\n\n dragging.value = { insertable, src, label, x: event.clientX, y: event.clientY, moved: false };\n (event.currentTarget as HTMLElement).setPointerCapture(event.pointerId);\n}\n\nfunction moveDrag(event: PointerEvent) {\n const held = dragging.value;\n\n if (held) {\n const moved = held.moved || Math.hypot(event.clientX - held.x, event.clientY - held.y) > 4;\n dragging.value = { ...held, x: event.clientX, y: event.clientY, moved };\n }\n}\n\n/** Dropped on a canvas, the element is born right there; a plain click adds it to the current canvas. */\nfunction drop(event: PointerEvent) {\n const held = dragging.value;\n dragging.value = null;\n\n if (!held) {\n return;\n }\n\n const spot = held.moved ? props.dropPoint(event.clientX, event.clientY) : null;\n\n if (held.moved && !spot) {\n return;\n }\n\n editor.addElement(held.insertable, spot ?? undefined, held.src);\n}\n\n/** Keyboard activation (a click with no pointer behind it) adds the element; pointers go through the drag. */\nfunction pressed(event: MouseEvent, insertable: Insertable, src?: string) {\n if (event.detail === 0) {\n editor.addElement(insertable, undefined, src);\n }\n}\n\nconst coreLabel = (type: CoreElementType) => t(coreSpecs[type].label);\n\n\nconst collapsed = ref<string[]>([]);\n\nfunction toggleCollapsed(id: string) {\n collapsed.value = collapsed.value.includes(id) ? collapsed.value.filter((item) => item !== id) : [...collapsed.value, id];\n}\n\nconst selectedIds = computed(() => (editor.state.selection.kind === 'elements' ? editor.state.selection.ids : []));\nconst canvasSelected = (id: string) => editor.state.selection.kind === 'canvas' && editor.state.selection.canvas === id;\n\nfunction layerLabel(element: Parameters<typeof elementName>[0]): string {\n const kind = editor.kindOf(element);\n\n return elementName(element, kind.kind === 'core' ? t(kind.spec.label) : kind.kind === 'app' ? editor.i18n.localized(kind.spec.label) : t('type.unknown'));\n}\n\nfunction toggleLocked(element: { locked?: boolean | null }) {\n element.locked = !element.locked;\n editor.commit();\n}\n\nconst modals = computed(() => editor.state.draft.modals ?? []);\n</script>\n\n<template>\n <aside class=\"lze-sidebar lze-left\">\n <div class=\"lze-tabs\" role=\"tablist\">\n <button\n v-for=\"item in tabs\"\n :key=\"item.key\"\n type=\"button\"\n role=\"tab\"\n :aria-selected=\"tab === item.key\"\n @click=\"tab = item.key\"\n >\n <component :is=\"item.icon\" :size=\"16\" aria-hidden=\"true\" />{{ t(item.label) }}\n </button>\n </div>\n\n <div v-if=\"tab === 'elements'\" class=\"lze-scroll lze-stack\" role=\"tabpanel\">\n <div class=\"lze-palette\">\n <button\n v-for=\"type in contentTypes\"\n :key=\"type\"\n type=\"button\"\n class=\"lze-palette-item\"\n :title=\"t('elements.addHint')\"\n @pointerdown=\"startDrag($event, { kind: 'core', type }, coreLabel(type))\"\n @click=\"pressed($event, { kind: 'core', type })\"\n @pointermove=\"moveDrag\"\n @pointerup=\"drop\"\n @pointercancel=\"dragging = null\"\n >\n <component :is=\"typeIcons[type]\" :size=\"16\" aria-hidden=\"true\" />{{ coreLabel(type) }}\n </button>\n </div>\n\n <template v-if=\"editor.catalog.value.elements.length\">\n <p class=\"lze-group-title\">{{ t('elements.app') }}</p>\n <div class=\"lze-palette\">\n <button\n v-for=\"spec in editor.catalog.value.elements\"\n :key=\"spec.type\"\n type=\"button\"\n class=\"lze-palette-item\"\n :title=\"t('elements.addHint')\"\n @pointerdown=\"startDrag($event, { kind: 'app', spec }, editor.i18n.localized(spec.label))\"\n @click=\"pressed($event, { kind: 'app', spec })\"\n @pointermove=\"moveDrag\"\n @pointerup=\"drop\"\n @pointercancel=\"dragging = null\"\n >\n <CatalogIcon :name=\"spec.icon\" :size=\"16\" />{{ editor.i18n.localized(spec.label) }}\n </button>\n </div>\n <p class=\"lze-hint\">{{ t('elements.appHint') }}</p>\n </template>\n\n <p class=\"lze-group-title\">{{ t('elements.form') }}</p>\n <div class=\"lze-palette\">\n <button\n v-for=\"type in formTypes\"\n :key=\"type\"\n type=\"button\"\n class=\"lze-palette-item\"\n :title=\"t('elements.addHint')\"\n @pointerdown=\"startDrag($event, { kind: 'core', type }, coreLabel(type))\"\n @click=\"pressed($event, { kind: 'core', type })\"\n @pointermove=\"moveDrag\"\n @pointerup=\"drop\"\n @pointercancel=\"dragging = null\"\n >\n <component :is=\"typeIcons[type]\" :size=\"16\" aria-hidden=\"true\" />{{ coreLabel(type) }}\n </button>\n </div>\n <p class=\"lze-hint\">{{ t('elements.formHint') }}</p>\n </div>\n\n <div v-else-if=\"tab === 'blocks'\" class=\"lze-scroll lze-stack\" role=\"tabpanel\">\n <p class=\"lze-hint\">{{ t('elements.sectionsHint') }}</p>\n <div v-for=\"group in TEMPLATE_GROUPS\" :key=\"group.key\" class=\"lze-list\">\n <p class=\"lze-group-label\">{{ t(group.name) }}</p>\n <button\n v-for=\"template in SECTION_TEMPLATES.filter((item) => item.group === group.key)\"\n :key=\"template.key\"\n type=\"button\"\n class=\"lze-list-item\"\n @click=\"editor.addSection(buildSectionTemplate(template.key))\"\n >\n {{ t(template.name) }}\n </button>\n </div>\n </div>\n\n <div v-else-if=\"tab === 'layers'\" class=\"lze-scroll\" role=\"tabpanel\">\n <div class=\"lze-heading lze-pad\">\n <span class=\"lze-muted\">{{ editor.activeModal.value ? t('layers.modal', { title: editor.activeModal.value.title }) : t('layers.count', { n: editor.state.draft.sections.length }) }}</span>\n <button v-if=\"!editor.activeModal.value\" type=\"button\" class=\"lze-btn\" data-variant=\"ghost\" @click=\"editor.addSection()\"><Plus :size=\"14\" aria-hidden=\"true\" />{{ t('common.new') }}</button>\n </div>\n <div v-for=\"(canvas, index) in editor.canvases.value\" :key=\"canvas.id\" class=\"lze-layer-group\">\n <div class=\"lze-layer-row\" :data-selected=\"canvasSelected(canvas.id)\">\n <button type=\"button\" class=\"lze-icon-btn\" :aria-label=\"collapsed.includes(canvas.id) ? t('layers.expand') : t('layers.collapse')\" @click=\"toggleCollapsed(canvas.id)\">\n <ChevronDown :size=\"14\" :style=\"{ transform: collapsed.includes(canvas.id) ? 'rotate(-90deg)' : undefined }\" aria-hidden=\"true\" />\n </button>\n <button type=\"button\" class=\"lze-layer-name\" @click=\"editor.selectCanvas(canvas.id)\">\n <Frame :size=\"14\" aria-hidden=\"true\" />\n <span>{{ isModal(canvas) ? canvas.title : t('layers.section', { n: index + 1 }) }}</span>\n <span class=\"lze-muted\">{{ canvas.elements.length }}</span>\n </button>\n <span v-if=\"!isModal(canvas)\" class=\"lze-layer-actions\">\n <button type=\"button\" class=\"lze-icon-btn\" :aria-label=\"t('layers.up')\" :disabled=\"index === 0\" @click=\"editor.moveSection(index, -1)\"><ChevronUp :size=\"14\" aria-hidden=\"true\" /></button>\n <button type=\"button\" class=\"lze-icon-btn\" :aria-label=\"t('layers.down')\" :disabled=\"index === editor.canvases.value.length - 1\" @click=\"editor.moveSection(index, 1)\"><ChevronDown :size=\"14\" aria-hidden=\"true\" /></button>\n </span>\n </div>\n <div v-show=\"!collapsed.includes(canvas.id)\" class=\"lze-layer-children\">\n <div v-for=\"element in canvas.elements\" :key=\"element.id\" class=\"lze-layer-row\" :data-selected=\"selectedIds.includes(element.id)\">\n <button type=\"button\" class=\"lze-layer-name\" @click=\"editor.select(canvas.id, element.id, $event.shiftKey)\">\n <ElementIcon :element=\"element\" />\n <span>{{ layerLabel(element) }}</span>\n </button>\n <button\n type=\"button\"\n class=\"lze-icon-btn lze-lock-toggle\"\n :data-locked=\"element.locked === true\"\n :title=\"element.locked ? t('layers.unlock') : t('layers.lock')\"\n :aria-label=\"element.locked ? t('layers.unlock') : t('layers.lock')\"\n @click=\"toggleLocked(element)\"\n >\n <Lock v-if=\"element.locked\" :size=\"12\" aria-hidden=\"true\" />\n <LockOpen v-else :size=\"12\" aria-hidden=\"true\" />\n </button>\n </div>\n <p v-if=\"canvas.elements.length === 0\" class=\"lze-hint lze-pad\">{{ t('layers.empty') }}</p>\n </div>\n </div>\n </div>\n\n <div v-else-if=\"tab === 'modals'\" class=\"lze-scroll\" role=\"tabpanel\">\n <div class=\"lze-heading lze-pad\">\n <span class=\"lze-hint\">{{ t('modals.hint') }}</span>\n <button type=\"button\" class=\"lze-btn\" data-variant=\"ghost\" @click=\"editor.addModal()\"><Plus :size=\"14\" aria-hidden=\"true\" />{{ t('common.new') }}</button>\n </div>\n <div class=\"lze-stack lze-pad\">\n <div v-for=\"modal in modals\" :key=\"modal.id\" class=\"lze-card\" :data-active=\"editor.state.view.kind === 'modal' && editor.state.view.id === modal.id\">\n <div class=\"lze-row\">\n <input v-model=\"modal.title\" class=\"lze-input\" maxlength=\"120\" :aria-label=\"t('modals.titleLabel')\" @change=\"editor.commit()\" />\n <button type=\"button\" class=\"lze-icon-btn\" data-tone=\"danger\" :aria-label=\"t('modals.delete')\" @click=\"editor.removeModal(modal.id)\"><Trash2 :size=\"14\" aria-hidden=\"true\" /></button>\n </div>\n <div class=\"lze-heading\">\n <span class=\"lze-muted\">{{ t('modals.elements', { n: modal.elements.length }) }}</span>\n <button type=\"button\" class=\"lze-btn\" @click=\"editor.openModal(editor.state.view.kind === 'modal' && editor.state.view.id === modal.id ? null : modal.id)\">\n {{ editor.state.view.kind === 'modal' && editor.state.view.id === modal.id ? t('common.close') : t('modals.edit') }}\n </button>\n </div>\n </div>\n <p v-if=\"modals.length === 0\" class=\"lze-hint\">{{ t('modals.empty') }}</p>\n </div>\n </div>\n\n <div v-else class=\"lze-scroll\" role=\"tabpanel\">\n <div class=\"lze-heading lze-pad\">\n <span class=\"lze-hint\">{{ t('media.hint') }}</span>\n <button type=\"button\" class=\"lze-btn\" data-variant=\"ghost\" @click=\"editor.openLibrary()\"><Plus :size=\"14\" aria-hidden=\"true\" />{{ t('media.upload') }}</button>\n </div>\n <div class=\"lze-media-grid lze-pad\">\n <button\n v-for=\"asset in editor.state.workspace.assets\"\n :key=\"asset.id\"\n type=\"button\"\n class=\"lze-media-item\"\n :title=\"asset.name\"\n @pointerdown=\"startDrag($event, { kind: 'core', type: 'image' }, asset.name, asset.ref)\"\n @click=\"pressed($event, { kind: 'core', type: 'image' }, asset.ref)\"\n @pointermove=\"moveDrag\"\n @pointerup=\"drop\"\n @pointercancel=\"dragging = null\"\n >\n <img :src=\"asset.thumb\" :alt=\"asset.name\" loading=\"lazy\" draggable=\"false\" />\n </button>\n <p v-if=\"editor.state.workspace.assets.length === 0\" class=\"lze-hint\">{{ t('media.empty') }}</p>\n </div>\n </div>\n\n <p v-if=\"dragging?.moved\" class=\"lze-drag-ghost\" :style=\"{ left: `${dragging.x + 12}px`, top: `${dragging.y + 12}px` }\">{{ dragging.label }}</p>\n </aside>\n</template>\n","<script setup lang=\"ts\">\nimport type { CoreElementType } from '@skylivellc/lienzo-core';\nimport { ChevronDown, ChevronUp, Frame, Image as ImageIcon, Layers, LayoutTemplate, Lock, LockOpen, PanelTop, Plus, Trash2 } from '@lucide/vue';\nimport { computed, ref } from 'vue';\nimport { CORE_TYPES, isModal } from '../model/document.ts';\nimport { coreSpecs, elementName, type Insertable } from '../model/elements.ts';\nimport { buildSectionTemplate, SECTION_TEMPLATES, TEMPLATE_GROUPS } from '../model/templates.ts';\nimport { useEditor } from '../state/editor.ts';\nimport CatalogIcon from '../ui/CatalogIcon.vue';\nimport ElementIcon from './ElementIcon.vue';\nimport { typeIcons } from './typeIcons.ts';\n\n/** Left sidebar: what to add, the layer tree, the modals, and the media library. */\nconst props = defineProps<{ dropPoint: (clientX: number, clientY: number) => { canvas: string; x: number; y: number } | null }>();\nconst editor = useEditor();\nconst t = editor.t;\n\ntype Tab = 'elements' | 'blocks' | 'layers' | 'modals' | 'media';\nconst tab = ref<Tab>('elements');\nconst tabs = [\n { key: 'elements', label: 'tabs.elements', icon: Plus },\n { key: 'blocks', label: 'tabs.blocks', icon: LayoutTemplate },\n { key: 'layers', label: 'tabs.layers', icon: Layers },\n { key: 'modals', label: 'tabs.modals', icon: PanelTop },\n { key: 'media', label: 'tabs.media', icon: ImageIcon },\n] as const;\n\nconst contentTypes = CORE_TYPES.filter((type) => coreSpecs[type].group === 'content');\nconst formTypes = CORE_TYPES.filter((type) => coreSpecs[type].group === 'form');\n\n\nconst dragging = ref<{ insertable: Insertable; src?: string; label: string; x: number; y: number; moved: boolean } | null>(null);\n\nfunction startDrag(event: PointerEvent, insertable: Insertable, label: string, src?: string) {\n if (event.button !== 0) {\n return;\n }\n\n dragging.value = { insertable, src, label, x: event.clientX, y: event.clientY, moved: false };\n (event.currentTarget as HTMLElement).setPointerCapture(event.pointerId);\n}\n\nfunction moveDrag(event: PointerEvent) {\n const held = dragging.value;\n\n if (held) {\n const moved = held.moved || Math.hypot(event.clientX - held.x, event.clientY - held.y) > 4;\n dragging.value = { ...held, x: event.clientX, y: event.clientY, moved };\n }\n}\n\n/** Dropped on a canvas, the element is born right there; a plain click adds it to the current canvas. */\nfunction drop(event: PointerEvent) {\n const held = dragging.value;\n dragging.value = null;\n\n if (!held) {\n return;\n }\n\n const spot = held.moved ? props.dropPoint(event.clientX, event.clientY) : null;\n\n if (held.moved && !spot) {\n return;\n }\n\n editor.addElement(held.insertable, spot ?? undefined, held.src);\n}\n\n/** Keyboard activation (a click with no pointer behind it) adds the element; pointers go through the drag. */\nfunction pressed(event: MouseEvent, insertable: Insertable, src?: string) {\n if (event.detail === 0) {\n editor.addElement(insertable, undefined, src);\n }\n}\n\nconst coreLabel = (type: CoreElementType) => t(coreSpecs[type].label);\n\n\nconst collapsed = ref<string[]>([]);\n\nfunction toggleCollapsed(id: string) {\n collapsed.value = collapsed.value.includes(id) ? collapsed.value.filter((item) => item !== id) : [...collapsed.value, id];\n}\n\nconst selectedIds = computed(() => (editor.state.selection.kind === 'elements' ? editor.state.selection.ids : []));\nconst canvasSelected = (id: string) => editor.state.selection.kind === 'canvas' && editor.state.selection.canvas === id;\n\nfunction layerLabel(element: Parameters<typeof elementName>[0]): string {\n const kind = editor.kindOf(element);\n\n return elementName(element, kind.kind === 'core' ? t(kind.spec.label) : kind.kind === 'app' ? editor.i18n.localized(kind.spec.label) : t('type.unknown'));\n}\n\nfunction toggleLocked(element: { locked?: boolean | null }) {\n element.locked = !element.locked;\n editor.commit();\n}\n\nconst modals = computed(() => editor.state.draft.modals ?? []);\n</script>\n\n<template>\n <aside class=\"lze-sidebar lze-left\">\n <div class=\"lze-tabs\" role=\"tablist\">\n <button\n v-for=\"item in tabs\"\n :key=\"item.key\"\n type=\"button\"\n role=\"tab\"\n :aria-selected=\"tab === item.key\"\n @click=\"tab = item.key\"\n >\n <component :is=\"item.icon\" :size=\"16\" aria-hidden=\"true\" />{{ t(item.label) }}\n </button>\n </div>\n\n <div v-if=\"tab === 'elements'\" class=\"lze-scroll lze-stack\" role=\"tabpanel\">\n <div class=\"lze-palette\">\n <button\n v-for=\"type in contentTypes\"\n :key=\"type\"\n type=\"button\"\n class=\"lze-palette-item\"\n :title=\"t('elements.addHint')\"\n @pointerdown=\"startDrag($event, { kind: 'core', type }, coreLabel(type))\"\n @click=\"pressed($event, { kind: 'core', type })\"\n @pointermove=\"moveDrag\"\n @pointerup=\"drop\"\n @pointercancel=\"dragging = null\"\n >\n <component :is=\"typeIcons[type]\" :size=\"16\" aria-hidden=\"true\" />{{ coreLabel(type) }}\n </button>\n </div>\n\n <template v-if=\"editor.catalog.value.elements.length\">\n <p class=\"lze-group-title\">{{ t('elements.app') }}</p>\n <div class=\"lze-palette\">\n <button\n v-for=\"spec in editor.catalog.value.elements\"\n :key=\"spec.type\"\n type=\"button\"\n class=\"lze-palette-item\"\n :title=\"t('elements.addHint')\"\n @pointerdown=\"startDrag($event, { kind: 'app', spec }, editor.i18n.localized(spec.label))\"\n @click=\"pressed($event, { kind: 'app', spec })\"\n @pointermove=\"moveDrag\"\n @pointerup=\"drop\"\n @pointercancel=\"dragging = null\"\n >\n <CatalogIcon :name=\"spec.icon\" :size=\"16\" />{{ editor.i18n.localized(spec.label) }}\n </button>\n </div>\n <p class=\"lze-hint\">{{ t('elements.appHint') }}</p>\n </template>\n\n <p class=\"lze-group-title\">{{ t('elements.form') }}</p>\n <div class=\"lze-palette\">\n <button\n v-for=\"type in formTypes\"\n :key=\"type\"\n type=\"button\"\n class=\"lze-palette-item\"\n :title=\"t('elements.addHint')\"\n @pointerdown=\"startDrag($event, { kind: 'core', type }, coreLabel(type))\"\n @click=\"pressed($event, { kind: 'core', type })\"\n @pointermove=\"moveDrag\"\n @pointerup=\"drop\"\n @pointercancel=\"dragging = null\"\n >\n <component :is=\"typeIcons[type]\" :size=\"16\" aria-hidden=\"true\" />{{ coreLabel(type) }}\n </button>\n </div>\n <p class=\"lze-hint\">{{ t('elements.formHint') }}</p>\n </div>\n\n <div v-else-if=\"tab === 'blocks'\" class=\"lze-scroll lze-stack\" role=\"tabpanel\">\n <p class=\"lze-hint\">{{ t('elements.sectionsHint') }}</p>\n <div v-for=\"group in TEMPLATE_GROUPS\" :key=\"group.key\" class=\"lze-list\">\n <p class=\"lze-group-label\">{{ t(group.name) }}</p>\n <button\n v-for=\"template in SECTION_TEMPLATES.filter((item) => item.group === group.key)\"\n :key=\"template.key\"\n type=\"button\"\n class=\"lze-list-item\"\n @click=\"editor.addSection(buildSectionTemplate(template.key))\"\n >\n {{ t(template.name) }}\n </button>\n </div>\n </div>\n\n <div v-else-if=\"tab === 'layers'\" class=\"lze-scroll\" role=\"tabpanel\">\n <div class=\"lze-heading lze-pad\">\n <span class=\"lze-muted\">{{ editor.activeModal.value ? t('layers.modal', { title: editor.activeModal.value.title }) : t('layers.count', { n: editor.state.draft.sections.length }) }}</span>\n <button v-if=\"!editor.activeModal.value\" type=\"button\" class=\"lze-btn\" data-variant=\"ghost\" @click=\"editor.addSection()\"><Plus :size=\"14\" aria-hidden=\"true\" />{{ t('common.new') }}</button>\n </div>\n <div v-for=\"(canvas, index) in editor.canvases.value\" :key=\"canvas.id\" class=\"lze-layer-group\">\n <div class=\"lze-layer-row\" :data-selected=\"canvasSelected(canvas.id)\">\n <button type=\"button\" class=\"lze-icon-btn\" :aria-label=\"collapsed.includes(canvas.id) ? t('layers.expand') : t('layers.collapse')\" @click=\"toggleCollapsed(canvas.id)\">\n <ChevronDown :size=\"14\" :style=\"{ transform: collapsed.includes(canvas.id) ? 'rotate(-90deg)' : undefined }\" aria-hidden=\"true\" />\n </button>\n <button type=\"button\" class=\"lze-layer-name\" @click=\"editor.selectCanvas(canvas.id)\">\n <Frame :size=\"14\" aria-hidden=\"true\" />\n <span>{{ isModal(canvas) ? canvas.title : t('layers.section', { n: index + 1 }) }}</span>\n <span class=\"lze-muted\">{{ canvas.elements.length }}</span>\n </button>\n <span v-if=\"!isModal(canvas)\" class=\"lze-layer-actions\">\n <button type=\"button\" class=\"lze-icon-btn\" :aria-label=\"t('layers.up')\" :disabled=\"index === 0\" @click=\"editor.moveSection(index, -1)\"><ChevronUp :size=\"14\" aria-hidden=\"true\" /></button>\n <button type=\"button\" class=\"lze-icon-btn\" :aria-label=\"t('layers.down')\" :disabled=\"index === editor.canvases.value.length - 1\" @click=\"editor.moveSection(index, 1)\"><ChevronDown :size=\"14\" aria-hidden=\"true\" /></button>\n </span>\n </div>\n <div v-show=\"!collapsed.includes(canvas.id)\" class=\"lze-layer-children\">\n <div v-for=\"element in canvas.elements\" :key=\"element.id\" class=\"lze-layer-row\" :data-selected=\"selectedIds.includes(element.id)\">\n <button type=\"button\" class=\"lze-layer-name\" @click=\"editor.select(canvas.id, element.id, $event.shiftKey)\">\n <ElementIcon :element=\"element\" />\n <span>{{ layerLabel(element) }}</span>\n </button>\n <button\n type=\"button\"\n class=\"lze-icon-btn lze-lock-toggle\"\n :data-locked=\"element.locked === true\"\n :title=\"element.locked ? t('layers.unlock') : t('layers.lock')\"\n :aria-label=\"element.locked ? t('layers.unlock') : t('layers.lock')\"\n @click=\"toggleLocked(element)\"\n >\n <Lock v-if=\"element.locked\" :size=\"12\" aria-hidden=\"true\" />\n <LockOpen v-else :size=\"12\" aria-hidden=\"true\" />\n </button>\n </div>\n <p v-if=\"canvas.elements.length === 0\" class=\"lze-hint lze-pad\">{{ t('layers.empty') }}</p>\n </div>\n </div>\n </div>\n\n <div v-else-if=\"tab === 'modals'\" class=\"lze-scroll\" role=\"tabpanel\">\n <div class=\"lze-heading lze-pad\">\n <span class=\"lze-hint\">{{ t('modals.hint') }}</span>\n <button type=\"button\" class=\"lze-btn\" data-variant=\"ghost\" @click=\"editor.addModal()\"><Plus :size=\"14\" aria-hidden=\"true\" />{{ t('common.new') }}</button>\n </div>\n <div class=\"lze-stack lze-pad\">\n <div v-for=\"modal in modals\" :key=\"modal.id\" class=\"lze-card\" :data-active=\"editor.state.view.kind === 'modal' && editor.state.view.id === modal.id\">\n <div class=\"lze-row\">\n <input v-model=\"modal.title\" class=\"lze-input\" maxlength=\"120\" :aria-label=\"t('modals.titleLabel')\" @change=\"editor.commit()\" />\n <button type=\"button\" class=\"lze-icon-btn\" data-tone=\"danger\" :aria-label=\"t('modals.delete')\" @click=\"editor.removeModal(modal.id)\"><Trash2 :size=\"14\" aria-hidden=\"true\" /></button>\n </div>\n <div class=\"lze-heading\">\n <span class=\"lze-muted\">{{ t('modals.elements', { n: modal.elements.length }) }}</span>\n <button type=\"button\" class=\"lze-btn\" @click=\"editor.openModal(editor.state.view.kind === 'modal' && editor.state.view.id === modal.id ? null : modal.id)\">\n {{ editor.state.view.kind === 'modal' && editor.state.view.id === modal.id ? t('common.close') : t('modals.edit') }}\n </button>\n </div>\n </div>\n <p v-if=\"modals.length === 0\" class=\"lze-hint\">{{ t('modals.empty') }}</p>\n </div>\n </div>\n\n <div v-else class=\"lze-scroll\" role=\"tabpanel\">\n <div class=\"lze-heading lze-pad\">\n <span class=\"lze-hint\">{{ t('media.hint') }}</span>\n <button type=\"button\" class=\"lze-btn\" data-variant=\"ghost\" @click=\"editor.openLibrary()\"><Plus :size=\"14\" aria-hidden=\"true\" />{{ t('media.upload') }}</button>\n </div>\n <div class=\"lze-media-grid lze-pad\">\n <button\n v-for=\"asset in editor.state.workspace.assets\"\n :key=\"asset.id\"\n type=\"button\"\n class=\"lze-media-item\"\n :title=\"asset.name\"\n @pointerdown=\"startDrag($event, { kind: 'core', type: 'image' }, asset.name, asset.ref)\"\n @click=\"pressed($event, { kind: 'core', type: 'image' }, asset.ref)\"\n @pointermove=\"moveDrag\"\n @pointerup=\"drop\"\n @pointercancel=\"dragging = null\"\n >\n <img :src=\"asset.thumb\" :alt=\"asset.name\" loading=\"lazy\" draggable=\"false\" />\n </button>\n <p v-if=\"editor.state.workspace.assets.length === 0\" class=\"lze-hint\">{{ t('media.empty') }}</p>\n </div>\n </div>\n\n <p v-if=\"dragging?.moved\" class=\"lze-drag-ghost\" :style=\"{ left: `${dragging.x + 12}px`, top: `${dragging.y + 12}px` }\">{{ dragging.label }}</p>\n </aside>\n</template>\n","<script setup lang=\"ts\">\nimport type { AppElement, ElementSpec, FieldValue } from '@skylivellc/lienzo-core';\nimport { useEditor } from '../../state/editor.ts';\nimport FieldControl from '../FieldControl.vue';\n\n/** An app element's content, one control per field it declares. */\nconst props = defineProps<{ element: AppElement; spec: ElementSpec }>();\nconst editor = useEditor();\n\nfunction set(key: string, value: FieldValue) {\n props.element.props = { ...props.element.props, [key]: value };\n}\n</script>\n\n<template>\n <FieldControl\n v-for=\"field in spec.fields\"\n :key=\"field.key\"\n :field=\"field\"\n :model-value=\"element.props[field.key]\"\n @update:model-value=\"set(field.key, $event)\"\n @commit=\"editor.commit()\"\n />\n</template>\n","<script setup lang=\"ts\">\nimport type { AppElement, ElementSpec, FieldValue } from '@skylivellc/lienzo-core';\nimport { useEditor } from '../../state/editor.ts';\nimport FieldControl from '../FieldControl.vue';\n\n/** An app element's content, one control per field it declares. */\nconst props = defineProps<{ element: AppElement; spec: ElementSpec }>();\nconst editor = useEditor();\n\nfunction set(key: string, value: FieldValue) {\n props.element.props = { ...props.element.props, [key]: value };\n}\n</script>\n\n<template>\n <FieldControl\n v-for=\"field in spec.fields\"\n :key=\"field.key\"\n :field=\"field\"\n :model-value=\"element.props[field.key]\"\n @update:model-value=\"set(field.key, $event)\"\n @commit=\"editor.commit()\"\n />\n</template>\n","<script setup lang=\"ts\">\nimport type { CoreElement } from '@skylivellc/lienzo-core';\nimport { useId } from 'vue';\nimport { useEditor } from '../../state/editor.ts';\nimport Field from '../../ui/Field.vue';\nimport TextInput from '../../ui/TextInput.vue';\nimport ActionPicker from '../ActionPicker.vue';\n\ndefineProps<{ element: CoreElement }>();\nconst editor = useEditor();\nconst t = editor.t;\nconst id = useId();\n</script>\n\n<template>\n <Field :id=\"id\" :label=\"t('el.buttonLabel')\">\n <TextInput :id=\"id\" v-model=\"element.props.label\" :maxlength=\"80\" @commit=\"editor.commit()\" />\n </Field>\n <Field :label=\"t('el.action')\">\n <ActionPicker v-model=\"element.props.action\" :label=\"t('el.action')\" @commit=\"editor.commit()\" />\n </Field>\n</template>\n","<script setup lang=\"ts\">\nimport type { CoreElement } from '@skylivellc/lienzo-core';\nimport { useId } from 'vue';\nimport { useEditor } from '../../state/editor.ts';\nimport Field from '../../ui/Field.vue';\nimport TextInput from '../../ui/TextInput.vue';\nimport ActionPicker from '../ActionPicker.vue';\n\ndefineProps<{ element: CoreElement }>();\nconst editor = useEditor();\nconst t = editor.t;\nconst id = useId();\n</script>\n\n<template>\n <Field :id=\"id\" :label=\"t('el.buttonLabel')\">\n <TextInput :id=\"id\" v-model=\"element.props.label\" :maxlength=\"80\" @commit=\"editor.commit()\" />\n </Field>\n <Field :label=\"t('el.action')\">\n <ActionPicker v-model=\"element.props.action\" :label=\"t('el.action')\" @commit=\"editor.commit()\" />\n </Field>\n</template>\n","<script setup lang=\"ts\">\nimport type { CoreElement } from '@skylivellc/lienzo-core';\nimport { ref, useId } from 'vue';\nimport { useEditor } from '../../state/editor.ts';\nimport Field from '../../ui/Field.vue';\nimport SelectInput from '../../ui/SelectInput.vue';\nimport TextInput from '../../ui/TextInput.vue';\nimport Toggle from '../../ui/Toggle.vue';\n\nconst MAX_OPTIONS = 30;\n\n/** Form fields: text, long text, dropdown and checkbox. */\nconst props = defineProps<{ element: CoreElement }>();\nconst editor = useEditor();\nconst t = editor.t;\nconst ids = { label: useId(), type: useId(), options: useId(), placeholder: useId() };\nconst inputTypes = (['text', 'email', 'tel', 'number', 'date'] as const).map((value) => ({ value, label: t(`el.inputType.${value}`) }));\n\n/** Options are typed one per line. The text stays as typed, so a new empty line is not swallowed. */\nconst optionsText = ref((props.element.props.options ?? []).join('\\n'));\n\nfunction setOptions(text: string | null | undefined) {\n optionsText.value = text ?? '';\n props.element.props.options = optionsText.value.split('\\n').map((option) => option.trim()).filter(Boolean).slice(0, MAX_OPTIONS);\n}\n</script>\n\n<template>\n <Field :id=\"ids.label\" :label=\"t('el.fieldLabel')\">\n <TextInput :id=\"ids.label\" v-model=\"element.props.label\" :maxlength=\"120\" @commit=\"editor.commit()\" />\n </Field>\n <Field v-if=\"element.type === 'input'\" :id=\"ids.type\" :label=\"t('el.inputType')\">\n <SelectInput :id=\"ids.type\" :model-value=\"element.props.input_type ?? 'text'\" :options=\"inputTypes\" @update:model-value=\"element.props.input_type = $event\" @commit=\"editor.commit()\" />\n </Field>\n <Field v-if=\"element.type === 'select'\" :id=\"ids.options\" :label=\"t('el.options')\" :hint=\"t('el.optionsHint')\">\n <TextInput :id=\"ids.options\" :model-value=\"optionsText\" :rows=\"4\" @update:model-value=\"setOptions\" @commit=\"editor.commit()\" />\n </Field>\n <Toggle v-if=\"element.type === 'select'\" v-model=\"element.props.multiple\" :label=\"t('el.multiple')\" @commit=\"editor.commit()\" />\n <Field v-if=\"element.type !== 'checkbox' && !(element.type === 'select' && element.props.multiple)\" :id=\"ids.placeholder\" :label=\"t('el.placeholder')\">\n <TextInput :id=\"ids.placeholder\" v-model=\"element.props.placeholder\" :maxlength=\"120\" @commit=\"editor.commit()\" />\n </Field>\n <Toggle v-model=\"element.props.required\" :label=\"t('el.required')\" @commit=\"editor.commit()\" />\n</template>\n","<script setup lang=\"ts\">\nimport type { CoreElement } from '@skylivellc/lienzo-core';\nimport { ref, useId } from 'vue';\nimport { useEditor } from '../../state/editor.ts';\nimport Field from '../../ui/Field.vue';\nimport SelectInput from '../../ui/SelectInput.vue';\nimport TextInput from '../../ui/TextInput.vue';\nimport Toggle from '../../ui/Toggle.vue';\n\nconst MAX_OPTIONS = 30;\n\n/** Form fields: text, long text, dropdown and checkbox. */\nconst props = defineProps<{ element: CoreElement }>();\nconst editor = useEditor();\nconst t = editor.t;\nconst ids = { label: useId(), type: useId(), options: useId(), placeholder: useId() };\nconst inputTypes = (['text', 'email', 'tel', 'number', 'date'] as const).map((value) => ({ value, label: t(`el.inputType.${value}`) }));\n\n/** Options are typed one per line. The text stays as typed, so a new empty line is not swallowed. */\nconst optionsText = ref((props.element.props.options ?? []).join('\\n'));\n\nfunction setOptions(text: string | null | undefined) {\n optionsText.value = text ?? '';\n props.element.props.options = optionsText.value.split('\\n').map((option) => option.trim()).filter(Boolean).slice(0, MAX_OPTIONS);\n}\n</script>\n\n<template>\n <Field :id=\"ids.label\" :label=\"t('el.fieldLabel')\">\n <TextInput :id=\"ids.label\" v-model=\"element.props.label\" :maxlength=\"120\" @commit=\"editor.commit()\" />\n </Field>\n <Field v-if=\"element.type === 'input'\" :id=\"ids.type\" :label=\"t('el.inputType')\">\n <SelectInput :id=\"ids.type\" :model-value=\"element.props.input_type ?? 'text'\" :options=\"inputTypes\" @update:model-value=\"element.props.input_type = $event\" @commit=\"editor.commit()\" />\n </Field>\n <Field v-if=\"element.type === 'select'\" :id=\"ids.options\" :label=\"t('el.options')\" :hint=\"t('el.optionsHint')\">\n <TextInput :id=\"ids.options\" :model-value=\"optionsText\" :rows=\"4\" @update:model-value=\"setOptions\" @commit=\"editor.commit()\" />\n </Field>\n <Toggle v-if=\"element.type === 'select'\" v-model=\"element.props.multiple\" :label=\"t('el.multiple')\" @commit=\"editor.commit()\" />\n <Field v-if=\"element.type !== 'checkbox' && !(element.type === 'select' && element.props.multiple)\" :id=\"ids.placeholder\" :label=\"t('el.placeholder')\">\n <TextInput :id=\"ids.placeholder\" v-model=\"element.props.placeholder\" :maxlength=\"120\" @commit=\"editor.commit()\" />\n </Field>\n <Toggle v-model=\"element.props.required\" :label=\"t('el.required')\" @commit=\"editor.commit()\" />\n</template>\n","<script setup lang=\"ts\">\nimport type { CoreElement } from '@skylivellc/lienzo-core';\nimport { computed, ref, useId } from 'vue';\nimport { ICON_NAMES } from '../../model/icons.ts';\nimport { useEditor } from '../../state/editor.ts';\nimport CatalogIcon from '../../ui/CatalogIcon.vue';\nimport Field from '../../ui/Field.vue';\nimport RangeInput from '../../ui/RangeInput.vue';\nimport TextInput from '../../ui/TextInput.vue';\n\nconst props = defineProps<{ element: CoreElement }>();\nconst editor = useEditor();\nconst t = editor.t;\nconst id = useId();\nconst search = ref('');\n\nconst matches = computed(() => {\n const term = search.value.trim().toLowerCase();\n\n return term ? ICON_NAMES.filter((name) => name.includes(term)) : ICON_NAMES;\n});\n\nfunction pick(name: string) {\n props.element.props.icon = name;\n editor.commit();\n}\n</script>\n\n<template>\n <Field :id=\"id\" :label=\"t('el.icon')\">\n <TextInput :id=\"id\" v-model=\"search\" type=\"search\" :placeholder=\"t('el.iconSearch')\" />\n <div class=\"lze-icon-grid\" role=\"group\" :aria-label=\"t('el.iconOptions')\">\n <button\n v-for=\"name in matches\"\n :key=\"name\"\n type=\"button\"\n class=\"lze-icon-choice\"\n :title=\"name\"\n :aria-label=\"name\"\n :aria-pressed=\"element.props.icon === name\"\n @click=\"pick(name)\"\n >\n <CatalogIcon :name=\"name\" :size=\"20\" />\n </button>\n <p v-if=\"matches.length === 0\" class=\"lze-hint\">{{ t('el.noResults') }}</p>\n </div>\n </Field>\n <RangeInput v-model=\"element.props.stroke\" :label=\"t('el.stroke')\" :min=\"0.5\" :max=\"4\" :step=\"0.25\" :fallback=\"2\" @commit=\"editor.commit()\" />\n</template>\n","<script setup lang=\"ts\">\nimport type { CoreElement } from '@skylivellc/lienzo-core';\nimport { computed, ref, useId } from 'vue';\nimport { ICON_NAMES } from '../../model/icons.ts';\nimport { useEditor } from '../../state/editor.ts';\nimport CatalogIcon from '../../ui/CatalogIcon.vue';\nimport Field from '../../ui/Field.vue';\nimport RangeInput from '../../ui/RangeInput.vue';\nimport TextInput from '../../ui/TextInput.vue';\n\nconst props = defineProps<{ element: CoreElement }>();\nconst editor = useEditor();\nconst t = editor.t;\nconst id = useId();\nconst search = ref('');\n\nconst matches = computed(() => {\n const term = search.value.trim().toLowerCase();\n\n return term ? ICON_NAMES.filter((name) => name.includes(term)) : ICON_NAMES;\n});\n\nfunction pick(name: string) {\n props.element.props.icon = name;\n editor.commit();\n}\n</script>\n\n<template>\n <Field :id=\"id\" :label=\"t('el.icon')\">\n <TextInput :id=\"id\" v-model=\"search\" type=\"search\" :placeholder=\"t('el.iconSearch')\" />\n <div class=\"lze-icon-grid\" role=\"group\" :aria-label=\"t('el.iconOptions')\">\n <button\n v-for=\"name in matches\"\n :key=\"name\"\n type=\"button\"\n class=\"lze-icon-choice\"\n :title=\"name\"\n :aria-label=\"name\"\n :aria-pressed=\"element.props.icon === name\"\n @click=\"pick(name)\"\n >\n <CatalogIcon :name=\"name\" :size=\"20\" />\n </button>\n <p v-if=\"matches.length === 0\" class=\"lze-hint\">{{ t('el.noResults') }}</p>\n </div>\n </Field>\n <RangeInput v-model=\"element.props.stroke\" :label=\"t('el.stroke')\" :min=\"0.5\" :max=\"4\" :step=\"0.25\" :fallback=\"2\" @commit=\"editor.commit()\" />\n</template>\n","import type { CoreProps } from '@skylivellc/lienzo-core';\nimport type { Translator } from '../../i18n/index.ts';\n\ntype Shape = NonNullable<CoreProps['shape']>;\n\nconst SHAPES = ['rectangle', 'ellipse', 'triangle', 'blob', 'arch', 'diagonal', 'dots', 'grid'] as const satisfies readonly Shape[];\n\n/** Shapes of a shape element, which are also the crops of an image. */\nexport const shapeOptions = (t: Translator['t']): { value: Shape; label: string }[] => SHAPES.map((value) => ({ value, label: t(`shape.${value}`) }));\n","<script setup lang=\"ts\">\nimport type { CoreElement } from '@skylivellc/lienzo-core';\nimport { useId } from 'vue';\nimport { useEditor } from '../../state/editor.ts';\nimport Field from '../../ui/Field.vue';\nimport ImageField from '../../ui/ImageField.vue';\nimport SelectInput from '../../ui/SelectInput.vue';\nimport TextInput from '../../ui/TextInput.vue';\nimport { shapeOptions } from './shapes.ts';\n\ndefineProps<{ element: CoreElement }>();\nconst editor = useEditor();\nconst t = editor.t;\nconst ids = { alt: useId(), fit: useId(), crop: useId() };\nconst fits = (['cover', 'contain'] as const).map((value) => ({ value, label: t(`el.fit.${value}`) }));\n</script>\n\n<template>\n <ImageField v-model=\"element.props.src\" :label=\"t('el.image')\" url @commit=\"editor.commit()\" />\n <Field :id=\"ids.alt\" :label=\"t('el.alt')\">\n <TextInput :id=\"ids.alt\" v-model=\"element.props.alt\" :maxlength=\"200\" :placeholder=\"t('el.altPlaceholder')\" @commit=\"editor.commit()\" />\n </Field>\n <Field :id=\"ids.fit\" :label=\"t('el.fit')\">\n <SelectInput :id=\"ids.fit\" v-model=\"element.style.object_fit\" :options=\"fits\" @commit=\"editor.commit()\" />\n </Field>\n <Field :id=\"ids.crop\" :label=\"t('el.crop')\">\n <SelectInput :id=\"ids.crop\" v-model=\"element.props.shape\" :options=\"shapeOptions(t)\" @commit=\"editor.commit()\" />\n </Field>\n</template>\n","<script setup lang=\"ts\">\nimport type { CoreElement } from '@skylivellc/lienzo-core';\nimport { useId } from 'vue';\nimport { useEditor } from '../../state/editor.ts';\nimport Field from '../../ui/Field.vue';\nimport ImageField from '../../ui/ImageField.vue';\nimport SelectInput from '../../ui/SelectInput.vue';\nimport TextInput from '../../ui/TextInput.vue';\nimport { shapeOptions } from './shapes.ts';\n\ndefineProps<{ element: CoreElement }>();\nconst editor = useEditor();\nconst t = editor.t;\nconst ids = { alt: useId(), fit: useId(), crop: useId() };\nconst fits = (['cover', 'contain'] as const).map((value) => ({ value, label: t(`el.fit.${value}`) }));\n</script>\n\n<template>\n <ImageField v-model=\"element.props.src\" :label=\"t('el.image')\" url @commit=\"editor.commit()\" />\n <Field :id=\"ids.alt\" :label=\"t('el.alt')\">\n <TextInput :id=\"ids.alt\" v-model=\"element.props.alt\" :maxlength=\"200\" :placeholder=\"t('el.altPlaceholder')\" @commit=\"editor.commit()\" />\n </Field>\n <Field :id=\"ids.fit\" :label=\"t('el.fit')\">\n <SelectInput :id=\"ids.fit\" v-model=\"element.style.object_fit\" :options=\"fits\" @commit=\"editor.commit()\" />\n </Field>\n <Field :id=\"ids.crop\" :label=\"t('el.crop')\">\n <SelectInput :id=\"ids.crop\" v-model=\"element.props.shape\" :options=\"shapeOptions(t)\" @commit=\"editor.commit()\" />\n </Field>\n</template>\n","<script setup lang=\"ts\">\nimport type { CoreElement } from '@skylivellc/lienzo-core';\nimport { computed } from 'vue';\nimport { useEditor } from '../../state/editor.ts';\nimport Button from '../../ui/Button.vue';\nimport ImageField from '../../ui/ImageField.vue';\n\nconst MAX_PICTURES = 24;\n\n/** The pictures of a gallery or a slider: one field per slot, in the order shown. */\nconst props = defineProps<{ element: CoreElement }>();\nconst editor = useEditor();\nconst t = editor.t;\nconst pictures = computed(() => props.element.props.images ?? []);\n\nfunction set(index: number, source: string | null | undefined) {\n props.element.props.images = pictures.value.map((picture, at) => (at === index ? source ?? '' : picture));\n}\n\nfunction add() {\n props.element.props.images = [...pictures.value, ''];\n editor.commit();\n}\n\nfunction remove(index: number) {\n props.element.props.images = pictures.value.filter((_, at) => at !== index);\n editor.commit();\n}\n</script>\n\n<template>\n <div class=\"lze-field\">\n <div class=\"lze-heading\">\n <span class=\"lze-label\">{{ t('el.gallery') }}</span>\n <Button :disabled=\"pictures.length >= MAX_PICTURES\" @click=\"add\">{{ t('el.galleryAdd') }}</Button>\n </div>\n <div v-for=\"(picture, index) in pictures\" :key=\"index\" class=\"lze-row lze-nowrap\">\n <ImageField\n :model-value=\"picture\"\n :label=\"t('el.galleryItem', { n: index + 1 })\"\n url\n class=\"lze-grow\"\n @update:model-value=\"set(index, $event)\"\n @commit=\"editor.commit()\"\n />\n <Button variant=\"danger\" @click=\"remove(index)\">{{ t('el.galleryRemove') }}</Button>\n </div>\n <p class=\"lze-hint\">{{ t('el.galleryHint') }}</p>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport type { CoreElement } from '@skylivellc/lienzo-core';\nimport { computed } from 'vue';\nimport { useEditor } from '../../state/editor.ts';\nimport Button from '../../ui/Button.vue';\nimport ImageField from '../../ui/ImageField.vue';\n\nconst MAX_PICTURES = 24;\n\n/** The pictures of a gallery or a slider: one field per slot, in the order shown. */\nconst props = defineProps<{ element: CoreElement }>();\nconst editor = useEditor();\nconst t = editor.t;\nconst pictures = computed(() => props.element.props.images ?? []);\n\nfunction set(index: number, source: string | null | undefined) {\n props.element.props.images = pictures.value.map((picture, at) => (at === index ? source ?? '' : picture));\n}\n\nfunction add() {\n props.element.props.images = [...pictures.value, ''];\n editor.commit();\n}\n\nfunction remove(index: number) {\n props.element.props.images = pictures.value.filter((_, at) => at !== index);\n editor.commit();\n}\n</script>\n\n<template>\n <div class=\"lze-field\">\n <div class=\"lze-heading\">\n <span class=\"lze-label\">{{ t('el.gallery') }}</span>\n <Button :disabled=\"pictures.length >= MAX_PICTURES\" @click=\"add\">{{ t('el.galleryAdd') }}</Button>\n </div>\n <div v-for=\"(picture, index) in pictures\" :key=\"index\" class=\"lze-row lze-nowrap\">\n <ImageField\n :model-value=\"picture\"\n :label=\"t('el.galleryItem', { n: index + 1 })\"\n url\n class=\"lze-grow\"\n @update:model-value=\"set(index, $event)\"\n @commit=\"editor.commit()\"\n />\n <Button variant=\"danger\" @click=\"remove(index)\">{{ t('el.galleryRemove') }}</Button>\n </div>\n <p class=\"lze-hint\">{{ t('el.galleryHint') }}</p>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport type { CoreElement } from '@skylivellc/lienzo-core';\nimport { useId } from 'vue';\nimport { useEditor } from '../../state/editor.ts';\nimport Field from '../../ui/Field.vue';\nimport NumberInput from '../../ui/NumberInput.vue';\nimport SelectInput from '../../ui/SelectInput.vue';\nimport TextInput from '../../ui/TextInput.vue';\nimport PictureList from './PictureList.vue';\n\n/** A gallery is a list of pictures, laid out as a grid or as a strip. */\nconst props = defineProps<{ element: CoreElement }>();\nconst editor = useEditor();\nconst t = editor.t;\nconst ids = { layout: useId(), alt: useId() };\nconst layouts = (['grid', 'strip'] as const).map((value) => ({ value, label: t(`el.gallery.${value}`) }));\n</script>\n\n<template>\n <Field :id=\"ids.layout\" :label=\"t('el.galleryLayout')\">\n <SelectInput :id=\"ids.layout\" :model-value=\"element.props.layout ?? 'grid'\" :options=\"layouts\" @update:model-value=\"element.props.layout = $event\" @commit=\"editor.commit()\" />\n </Field>\n <NumberInput\n v-if=\"(element.props.layout ?? 'grid') === 'grid'\"\n :model-value=\"element.props.columns ?? 3\"\n :label=\"t('el.galleryColumns')\"\n :min=\"1\"\n :max=\"6\"\n @update:model-value=\"element.props.columns = $event ?? 3\"\n @commit=\"editor.commit()\"\n />\n <PictureList :element=\"element\" />\n <Field :id=\"ids.alt\" :label=\"t('el.alt')\">\n <TextInput :id=\"ids.alt\" v-model=\"element.props.alt\" :maxlength=\"200\" :placeholder=\"t('el.altPlaceholder')\" @commit=\"editor.commit()\" />\n </Field>\n</template>\n","<script setup lang=\"ts\">\nimport type { CoreElement } from '@skylivellc/lienzo-core';\nimport { useId } from 'vue';\nimport { useEditor } from '../../state/editor.ts';\nimport Field from '../../ui/Field.vue';\nimport NumberInput from '../../ui/NumberInput.vue';\nimport SelectInput from '../../ui/SelectInput.vue';\nimport TextInput from '../../ui/TextInput.vue';\nimport PictureList from './PictureList.vue';\n\n/** A gallery is a list of pictures, laid out as a grid or as a strip. */\nconst props = defineProps<{ element: CoreElement }>();\nconst editor = useEditor();\nconst t = editor.t;\nconst ids = { layout: useId(), alt: useId() };\nconst layouts = (['grid', 'strip'] as const).map((value) => ({ value, label: t(`el.gallery.${value}`) }));\n</script>\n\n<template>\n <Field :id=\"ids.layout\" :label=\"t('el.galleryLayout')\">\n <SelectInput :id=\"ids.layout\" :model-value=\"element.props.layout ?? 'grid'\" :options=\"layouts\" @update:model-value=\"element.props.layout = $event\" @commit=\"editor.commit()\" />\n </Field>\n <NumberInput\n v-if=\"(element.props.layout ?? 'grid') === 'grid'\"\n :model-value=\"element.props.columns ?? 3\"\n :label=\"t('el.galleryColumns')\"\n :min=\"1\"\n :max=\"6\"\n @update:model-value=\"element.props.columns = $event ?? 3\"\n @commit=\"editor.commit()\"\n />\n <PictureList :element=\"element\" />\n <Field :id=\"ids.alt\" :label=\"t('el.alt')\">\n <TextInput :id=\"ids.alt\" v-model=\"element.props.alt\" :maxlength=\"200\" :placeholder=\"t('el.altPlaceholder')\" @commit=\"editor.commit()\" />\n </Field>\n</template>\n","<script setup lang=\"ts\">\nimport type { CoreElement } from '@skylivellc/lienzo-core';\nimport { useId } from 'vue';\nimport { useEditor } from '../../state/editor.ts';\nimport Field from '../../ui/Field.vue';\nimport NumberInput from '../../ui/NumberInput.vue';\nimport TextInput from '../../ui/TextInput.vue';\nimport Toggle from '../../ui/Toggle.vue';\nimport PictureList from './PictureList.vue';\n\n/** A slider shows one picture at a time, and says how a reader moves it. */\ndefineProps<{ element: CoreElement }>();\nconst editor = useEditor();\nconst t = editor.t;\nconst ids = { alt: useId() };\n</script>\n\n<template>\n <PictureList :element=\"element\" />\n <Toggle :model-value=\"element.props.arrows !== false\" :label=\"t('el.sliderArrows')\" @update:model-value=\"element.props.arrows = $event; editor.commit()\" />\n <Toggle :model-value=\"element.props.dots !== false\" :label=\"t('el.sliderDots')\" @update:model-value=\"element.props.dots = $event; editor.commit()\" />\n <Toggle :model-value=\"element.props.autoplay === true\" :label=\"t('el.sliderAutoplay')\" @update:model-value=\"element.props.autoplay = $event; editor.commit()\" />\n <NumberInput\n v-if=\"element.props.autoplay === true\"\n :model-value=\"element.props.interval ?? 5\"\n :label=\"t('el.sliderInterval')\"\n :min=\"2\"\n :max=\"12\"\n @update:model-value=\"element.props.interval = $event ?? 5\"\n @commit=\"editor.commit()\"\n />\n <Field :id=\"ids.alt\" :label=\"t('el.alt')\">\n <TextInput :id=\"ids.alt\" v-model=\"element.props.alt\" :maxlength=\"200\" :placeholder=\"t('el.altPlaceholder')\" @commit=\"editor.commit()\" />\n </Field>\n</template>\n","<script setup lang=\"ts\">\nimport type { CoreElement } from '@skylivellc/lienzo-core';\nimport { useId } from 'vue';\nimport { useEditor } from '../../state/editor.ts';\nimport Field from '../../ui/Field.vue';\nimport NumberInput from '../../ui/NumberInput.vue';\nimport TextInput from '../../ui/TextInput.vue';\nimport Toggle from '../../ui/Toggle.vue';\nimport PictureList from './PictureList.vue';\n\n/** A slider shows one picture at a time, and says how a reader moves it. */\ndefineProps<{ element: CoreElement }>();\nconst editor = useEditor();\nconst t = editor.t;\nconst ids = { alt: useId() };\n</script>\n\n<template>\n <PictureList :element=\"element\" />\n <Toggle :model-value=\"element.props.arrows !== false\" :label=\"t('el.sliderArrows')\" @update:model-value=\"element.props.arrows = $event; editor.commit()\" />\n <Toggle :model-value=\"element.props.dots !== false\" :label=\"t('el.sliderDots')\" @update:model-value=\"element.props.dots = $event; editor.commit()\" />\n <Toggle :model-value=\"element.props.autoplay === true\" :label=\"t('el.sliderAutoplay')\" @update:model-value=\"element.props.autoplay = $event; editor.commit()\" />\n <NumberInput\n v-if=\"element.props.autoplay === true\"\n :model-value=\"element.props.interval ?? 5\"\n :label=\"t('el.sliderInterval')\"\n :min=\"2\"\n :max=\"12\"\n @update:model-value=\"element.props.interval = $event ?? 5\"\n @commit=\"editor.commit()\"\n />\n <Field :id=\"ids.alt\" :label=\"t('el.alt')\">\n <TextInput :id=\"ids.alt\" v-model=\"element.props.alt\" :maxlength=\"200\" :placeholder=\"t('el.altPlaceholder')\" @commit=\"editor.commit()\" />\n </Field>\n</template>\n","<script setup lang=\"ts\">\nimport { computed } from 'vue';\nimport { isThemeToken, swatch, THEME_TOKENS } from '../model/theme.ts';\nimport { useEditor } from '../state/editor.ts';\n\n/**\n * Picking a theme color keeps it linked: when the palette changes, the page\n * follows. A custom hex is the way out, not the way in.\n */\nconst model = defineModel<string | null | undefined>({ required: true });\ndefineProps<{ label: string }>();\nconst emit = defineEmits<{ commit: [] }>();\nconst editor = useEditor();\nconst custom = computed(() => (model.value && !isThemeToken(model.value) ? model.value : '#2563eb'));\n\nfunction pick(value: string) {\n model.value = value;\n emit('commit');\n}\n</script>\n\n<template>\n <div class=\"lze-field\">\n <span class=\"lze-label\">{{ label }}</span>\n <div class=\"lze-swatches\" role=\"group\" :aria-label=\"label\">\n <button\n v-for=\"token in THEME_TOKENS\"\n :key=\"token\"\n type=\"button\"\n class=\"lze-swatch\"\n :style=\"{ background: swatch(token, editor.theme.value) }\"\n :title=\"editor.t(`token.${token}`)\"\n :aria-label=\"editor.t(`token.${token}`)\"\n :aria-pressed=\"model === token\"\n @click=\"pick(token)\"\n />\n <label class=\"lze-swatch-custom\" :data-active=\"!!model && !isThemeToken(model)\" :title=\"editor.t('color.custom')\">\n <input type=\"color\" :value=\"custom\" :aria-label=\"editor.t('color.customLabel', { label })\" @input=\"model = ($event.target as HTMLInputElement).value\" @change=\"emit('commit')\" />\n {{ editor.t('color.custom') }}\n </label>\n </div>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport { computed } from 'vue';\nimport { isThemeToken, swatch, THEME_TOKENS } from '../model/theme.ts';\nimport { useEditor } from '../state/editor.ts';\n\n/**\n * Picking a theme color keeps it linked: when the palette changes, the page\n * follows. A custom hex is the way out, not the way in.\n */\nconst model = defineModel<string | null | undefined>({ required: true });\ndefineProps<{ label: string }>();\nconst emit = defineEmits<{ commit: [] }>();\nconst editor = useEditor();\nconst custom = computed(() => (model.value && !isThemeToken(model.value) ? model.value : '#2563eb'));\n\nfunction pick(value: string) {\n model.value = value;\n emit('commit');\n}\n</script>\n\n<template>\n <div class=\"lze-field\">\n <span class=\"lze-label\">{{ label }}</span>\n <div class=\"lze-swatches\" role=\"group\" :aria-label=\"label\">\n <button\n v-for=\"token in THEME_TOKENS\"\n :key=\"token\"\n type=\"button\"\n class=\"lze-swatch\"\n :style=\"{ background: swatch(token, editor.theme.value) }\"\n :title=\"editor.t(`token.${token}`)\"\n :aria-label=\"editor.t(`token.${token}`)\"\n :aria-pressed=\"model === token\"\n @click=\"pick(token)\"\n />\n <label class=\"lze-swatch-custom\" :data-active=\"!!model && !isThemeToken(model)\" :title=\"editor.t('color.custom')\">\n <input type=\"color\" :value=\"custom\" :aria-label=\"editor.t('color.customLabel', { label })\" @input=\"model = ($event.target as HTMLInputElement).value\" @change=\"emit('commit')\" />\n {{ editor.t('color.custom') }}\n </label>\n </div>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport type { CoreElement } from '@skylivellc/lienzo-core';\nimport { computed, useId } from 'vue';\nimport { plain } from '../../model/document.ts';\nimport { navbarPresets } from '../../model/elements.ts';\nimport { useEditor } from '../../state/editor.ts';\nimport Button from '../../ui/Button.vue';\nimport ColorPicker from '../../ui/ColorPicker.vue';\nimport Field from '../../ui/Field.vue';\nimport SelectInput from '../../ui/SelectInput.vue';\nimport TextInput from '../../ui/TextInput.vue';\nimport Toggle from '../../ui/Toggle.vue';\nimport ActionPicker from '../ActionPicker.vue';\n\nconst MAX_LINKS = 8;\n\nconst props = defineProps<{ element: CoreElement }>();\nconst editor = useEditor();\nconst t = editor.t;\nconst ids = { brand: useId(), scroll: useId(), layout: useId(), template: useId(), position: useId() };\nconst presets = navbarPresets(t);\nconst scrollStyles = (['same', 'shadow', 'solid', 'compact'] as const).map((value) => ({ value, label: t(`el.scroll.${value}`) }));\nconst templates = (['plain', 'pill', 'card', 'underline', 'divided', 'floating', 'boxed', 'tracked', 'ribbon', 'outline', 'minimal', 'stack', 'rail'] as const).map((value) => ({ value, label: t(`el.navbarTemplate.${value}`) }));\nconst layouts = (['split', 'left', 'center', 'right'] as const).map((value) => ({ value, label: t(`el.layout.${value}`) }));\nconst positions = (['top', 'bottom'] as const).map((value) => ({ value, label: t(`el.navbarPosition.${value}`) }));\nconst links = computed(() => props.element.props.links ?? []);\n\n/** A preset replaces the menu's content and look, never its position or size. */\nfunction applyPreset(preset: (typeof presets)[number]) {\n props.element.props = { ...props.element.props, ...plain(preset.props) };\n props.element.style = { ...props.element.style, ...plain(preset.style) };\n editor.commit();\n}\n\nfunction addLink() {\n props.element.props.links = [...links.value, { label: t('default.link'), action: { type: 'anchor', value: '' } }];\n editor.commit();\n}\n\nfunction removeLink(index: number) {\n props.element.props.links = links.value.filter((_, position) => position !== index);\n editor.commit();\n}\n</script>\n\n<template>\n <div class=\"lze-field\">\n <span class=\"lze-label\">{{ t('el.presets') }}</span>\n <div class=\"lze-row\">\n <Button v-for=\"preset in presets\" :key=\"preset.name\" @click=\"applyPreset(preset)\">{{ t(preset.name) }}</Button>\n </div>\n </div>\n <Field :id=\"ids.brand\" :label=\"t('el.brand')\">\n <TextInput :id=\"ids.brand\" v-model=\"element.props.brand\" :maxlength=\"60\" :placeholder=\"t('el.brandPlaceholder')\" @commit=\"editor.commit()\" />\n </Field>\n <Toggle v-model=\"element.props.sticky\" :label=\"t('el.sticky')\" @commit=\"editor.commit()\" />\n <Field v-if=\"element.props.sticky\" :id=\"ids.scroll\" :label=\"t('el.scrollStyle')\">\n <SelectInput :id=\"ids.scroll\" :model-value=\"element.props.scroll_style ?? 'same'\" :options=\"scrollStyles\" @update:model-value=\"element.props.scroll_style = $event\" @commit=\"editor.commit()\" />\n </Field>\n <template v-if=\"element.props.sticky\">\n <Field :id=\"ids.position\" :label=\"t('el.navbarPosition')\">\n <SelectInput :id=\"ids.position\" :model-value=\"element.props.position ?? 'top'\" :options=\"positions\" @update:model-value=\"element.props.position = $event\" @commit=\"editor.commit()\" />\n </Field>\n <ColorPicker v-model=\"element.style.scroll_background\" :label=\"t('el.scrollBackground')\" @commit=\"editor.commit()\" />\n <ColorPicker v-model=\"element.style.scroll_color\" :label=\"t('el.scrollColor')\" @commit=\"editor.commit()\" />\n <p class=\"lze-hint\">{{ t('el.scrollColorsHint') }}</p>\n </template>\n <p v-else class=\"lze-hint\">{{ t('el.notSticky') }}</p>\n <Field :id=\"ids.layout\" :label=\"t('el.layout')\">\n <SelectInput :id=\"ids.layout\" :model-value=\"element.props.layout ?? 'split'\" :options=\"layouts\" @update:model-value=\"element.props.layout = $event\" @commit=\"editor.commit()\" />\n </Field>\n <Field :id=\"ids.template\" :label=\"t('el.navbarTemplate')\">\n <SelectInput :id=\"ids.template\" :model-value=\"element.props.template ?? 'plain'\" :options=\"templates\" @update:model-value=\"element.props.template = $event\" @commit=\"editor.commit()\" />\n </Field>\n <div class=\"lze-field\">\n <div class=\"lze-heading\">\n <span class=\"lze-label\">{{ t('el.links') }}</span>\n <Button :disabled=\"links.length >= MAX_LINKS\" @click=\"addLink\">{{ t('common.add') }}</Button>\n </div>\n <fieldset v-for=\"(link, index) in links\" :key=\"index\" class=\"lze-link-card\">\n <legend>{{ t('el.linkN', { n: index + 1 }) }}</legend>\n <div class=\"lze-row lze-nowrap\">\n <TextInput v-model=\"link.label\" :maxlength=\"40\" :label=\"t('el.linkLabel')\" @commit=\"editor.commit()\" />\n <Button variant=\"danger\" @click=\"removeLink(index)\">{{ t('el.removeLink') }}</Button>\n </div>\n <ActionPicker v-model=\"link.action\" :label=\"t('el.action')\" @commit=\"editor.commit()\" />\n </fieldset>\n <p class=\"lze-hint\">{{ t('el.linksHint') }}</p>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport type { CoreElement } from '@skylivellc/lienzo-core';\nimport { computed, useId } from 'vue';\nimport { plain } from '../../model/document.ts';\nimport { navbarPresets } from '../../model/elements.ts';\nimport { useEditor } from '../../state/editor.ts';\nimport Button from '../../ui/Button.vue';\nimport ColorPicker from '../../ui/ColorPicker.vue';\nimport Field from '../../ui/Field.vue';\nimport SelectInput from '../../ui/SelectInput.vue';\nimport TextInput from '../../ui/TextInput.vue';\nimport Toggle from '../../ui/Toggle.vue';\nimport ActionPicker from '../ActionPicker.vue';\n\nconst MAX_LINKS = 8;\n\nconst props = defineProps<{ element: CoreElement }>();\nconst editor = useEditor();\nconst t = editor.t;\nconst ids = { brand: useId(), scroll: useId(), layout: useId(), template: useId(), position: useId() };\nconst presets = navbarPresets(t);\nconst scrollStyles = (['same', 'shadow', 'solid', 'compact'] as const).map((value) => ({ value, label: t(`el.scroll.${value}`) }));\nconst templates = (['plain', 'pill', 'card', 'underline', 'divided', 'floating', 'boxed', 'tracked', 'ribbon', 'outline', 'minimal', 'stack', 'rail'] as const).map((value) => ({ value, label: t(`el.navbarTemplate.${value}`) }));\nconst layouts = (['split', 'left', 'center', 'right'] as const).map((value) => ({ value, label: t(`el.layout.${value}`) }));\nconst positions = (['top', 'bottom'] as const).map((value) => ({ value, label: t(`el.navbarPosition.${value}`) }));\nconst links = computed(() => props.element.props.links ?? []);\n\n/** A preset replaces the menu's content and look, never its position or size. */\nfunction applyPreset(preset: (typeof presets)[number]) {\n props.element.props = { ...props.element.props, ...plain(preset.props) };\n props.element.style = { ...props.element.style, ...plain(preset.style) };\n editor.commit();\n}\n\nfunction addLink() {\n props.element.props.links = [...links.value, { label: t('default.link'), action: { type: 'anchor', value: '' } }];\n editor.commit();\n}\n\nfunction removeLink(index: number) {\n props.element.props.links = links.value.filter((_, position) => position !== index);\n editor.commit();\n}\n</script>\n\n<template>\n <div class=\"lze-field\">\n <span class=\"lze-label\">{{ t('el.presets') }}</span>\n <div class=\"lze-row\">\n <Button v-for=\"preset in presets\" :key=\"preset.name\" @click=\"applyPreset(preset)\">{{ t(preset.name) }}</Button>\n </div>\n </div>\n <Field :id=\"ids.brand\" :label=\"t('el.brand')\">\n <TextInput :id=\"ids.brand\" v-model=\"element.props.brand\" :maxlength=\"60\" :placeholder=\"t('el.brandPlaceholder')\" @commit=\"editor.commit()\" />\n </Field>\n <Toggle v-model=\"element.props.sticky\" :label=\"t('el.sticky')\" @commit=\"editor.commit()\" />\n <Field v-if=\"element.props.sticky\" :id=\"ids.scroll\" :label=\"t('el.scrollStyle')\">\n <SelectInput :id=\"ids.scroll\" :model-value=\"element.props.scroll_style ?? 'same'\" :options=\"scrollStyles\" @update:model-value=\"element.props.scroll_style = $event\" @commit=\"editor.commit()\" />\n </Field>\n <template v-if=\"element.props.sticky\">\n <Field :id=\"ids.position\" :label=\"t('el.navbarPosition')\">\n <SelectInput :id=\"ids.position\" :model-value=\"element.props.position ?? 'top'\" :options=\"positions\" @update:model-value=\"element.props.position = $event\" @commit=\"editor.commit()\" />\n </Field>\n <ColorPicker v-model=\"element.style.scroll_background\" :label=\"t('el.scrollBackground')\" @commit=\"editor.commit()\" />\n <ColorPicker v-model=\"element.style.scroll_color\" :label=\"t('el.scrollColor')\" @commit=\"editor.commit()\" />\n <p class=\"lze-hint\">{{ t('el.scrollColorsHint') }}</p>\n </template>\n <p v-else class=\"lze-hint\">{{ t('el.notSticky') }}</p>\n <Field :id=\"ids.layout\" :label=\"t('el.layout')\">\n <SelectInput :id=\"ids.layout\" :model-value=\"element.props.layout ?? 'split'\" :options=\"layouts\" @update:model-value=\"element.props.layout = $event\" @commit=\"editor.commit()\" />\n </Field>\n <Field :id=\"ids.template\" :label=\"t('el.navbarTemplate')\">\n <SelectInput :id=\"ids.template\" :model-value=\"element.props.template ?? 'plain'\" :options=\"templates\" @update:model-value=\"element.props.template = $event\" @commit=\"editor.commit()\" />\n </Field>\n <div class=\"lze-field\">\n <div class=\"lze-heading\">\n <span class=\"lze-label\">{{ t('el.links') }}</span>\n <Button :disabled=\"links.length >= MAX_LINKS\" @click=\"addLink\">{{ t('common.add') }}</Button>\n </div>\n <fieldset v-for=\"(link, index) in links\" :key=\"index\" class=\"lze-link-card\">\n <legend>{{ t('el.linkN', { n: index + 1 }) }}</legend>\n <div class=\"lze-row lze-nowrap\">\n <TextInput v-model=\"link.label\" :maxlength=\"40\" :label=\"t('el.linkLabel')\" @commit=\"editor.commit()\" />\n <Button variant=\"danger\" @click=\"removeLink(index)\">{{ t('el.removeLink') }}</Button>\n </div>\n <ActionPicker v-model=\"link.action\" :label=\"t('el.action')\" @commit=\"editor.commit()\" />\n </fieldset>\n <p class=\"lze-hint\">{{ t('el.linksHint') }}</p>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport type { CoreElement } from '@skylivellc/lienzo-core';\nimport { useId } from 'vue';\nimport { useEditor } from '../../state/editor.ts';\nimport Field from '../../ui/Field.vue';\nimport RangeInput from '../../ui/RangeInput.vue';\nimport SelectInput from '../../ui/SelectInput.vue';\nimport { shapeOptions } from './shapes.ts';\n\ndefineProps<{ element: CoreElement }>();\nconst editor = useEditor();\nconst t = editor.t;\nconst id = useId();\n</script>\n\n<template>\n <Field :id=\"id\" :label=\"t('el.shape')\">\n <SelectInput :id=\"id\" v-model=\"element.props.shape\" :options=\"shapeOptions(t)\" @commit=\"editor.commit()\" />\n </Field>\n <RangeInput\n v-model=\"element.style.opacity\"\n :label=\"t('el.opacity')\"\n :min=\"0.1\"\n :max=\"1\"\n :step=\"0.05\"\n :fallback=\"1\"\n :format=\"(value) => `${Math.round(value * 100)}%`\"\n @commit=\"editor.commit()\"\n />\n</template>\n","<script setup lang=\"ts\">\nimport type { CoreElement } from '@skylivellc/lienzo-core';\nimport { useId } from 'vue';\nimport { useEditor } from '../../state/editor.ts';\nimport Field from '../../ui/Field.vue';\nimport RangeInput from '../../ui/RangeInput.vue';\nimport SelectInput from '../../ui/SelectInput.vue';\nimport { shapeOptions } from './shapes.ts';\n\ndefineProps<{ element: CoreElement }>();\nconst editor = useEditor();\nconst t = editor.t;\nconst id = useId();\n</script>\n\n<template>\n <Field :id=\"id\" :label=\"t('el.shape')\">\n <SelectInput :id=\"id\" v-model=\"element.props.shape\" :options=\"shapeOptions(t)\" @commit=\"editor.commit()\" />\n </Field>\n <RangeInput\n v-model=\"element.style.opacity\"\n :label=\"t('el.opacity')\"\n :min=\"0.1\"\n :max=\"1\"\n :step=\"0.05\"\n :fallback=\"1\"\n :format=\"(value) => `${Math.round(value * 100)}%`\"\n @commit=\"editor.commit()\"\n />\n</template>\n","<script setup lang=\"ts\">\nimport type { CoreElement } from '@skylivellc/lienzo-core';\nimport { useId } from 'vue';\nimport { useEditor } from '../../state/editor.ts';\nimport ColorPicker from '../../ui/ColorPicker.vue';\nimport Field from '../../ui/Field.vue';\nimport SelectInput from '../../ui/SelectInput.vue';\nimport TextInput from '../../ui/TextInput.vue';\n\n/** Heading and text: the copy, a highlighted part, and for headings their level. */\ndefineProps<{ element: CoreElement }>();\nconst editor = useEditor();\nconst t = editor.t;\nconst ids = { text: useId(), accent: useId(), level: useId() };\nconst levels = ([1, 2, 3, 4] as const).map((level) => ({ value: level, label: t(`el.level.${level}`) }));\n</script>\n\n<template>\n <Field :id=\"ids.text\" :label=\"t('el.text')\">\n <TextInput :id=\"ids.text\" v-model=\"element.props.text\" :rows=\"3\" :maxlength=\"2000\" @commit=\"editor.commit()\" />\n </Field>\n <Field :id=\"ids.accent\" :label=\"t('el.accent')\">\n <TextInput :id=\"ids.accent\" v-model=\"element.props.accent\" :maxlength=\"120\" :placeholder=\"t('el.accentPlaceholder')\" @commit=\"editor.commit()\" />\n </Field>\n <ColorPicker v-if=\"element.props.accent\" v-model=\"element.style.accent_color\" :label=\"t('el.accentColor')\" @commit=\"editor.commit()\" />\n <Field v-if=\"element.type === 'heading'\" :id=\"ids.level\" :label=\"t('el.level')\">\n <SelectInput :id=\"ids.level\" v-model=\"element.props.level\" :options=\"levels\" @commit=\"editor.commit()\" />\n </Field>\n</template>\n","<script setup lang=\"ts\">\nimport type { CoreElement } from '@skylivellc/lienzo-core';\nimport { useId } from 'vue';\nimport { useEditor } from '../../state/editor.ts';\nimport ColorPicker from '../../ui/ColorPicker.vue';\nimport Field from '../../ui/Field.vue';\nimport SelectInput from '../../ui/SelectInput.vue';\nimport TextInput from '../../ui/TextInput.vue';\n\n/** Heading and text: the copy, a highlighted part, and for headings their level. */\ndefineProps<{ element: CoreElement }>();\nconst editor = useEditor();\nconst t = editor.t;\nconst ids = { text: useId(), accent: useId(), level: useId() };\nconst levels = ([1, 2, 3, 4] as const).map((level) => ({ value: level, label: t(`el.level.${level}`) }));\n</script>\n\n<template>\n <Field :id=\"ids.text\" :label=\"t('el.text')\">\n <TextInput :id=\"ids.text\" v-model=\"element.props.text\" :rows=\"3\" :maxlength=\"2000\" @commit=\"editor.commit()\" />\n </Field>\n <Field :id=\"ids.accent\" :label=\"t('el.accent')\">\n <TextInput :id=\"ids.accent\" v-model=\"element.props.accent\" :maxlength=\"120\" :placeholder=\"t('el.accentPlaceholder')\" @commit=\"editor.commit()\" />\n </Field>\n <ColorPicker v-if=\"element.props.accent\" v-model=\"element.style.accent_color\" :label=\"t('el.accentColor')\" @commit=\"editor.commit()\" />\n <Field v-if=\"element.type === 'heading'\" :id=\"ids.level\" :label=\"t('el.level')\">\n <SelectInput :id=\"ids.level\" v-model=\"element.props.level\" :options=\"levels\" @commit=\"editor.commit()\" />\n </Field>\n</template>\n","<script setup lang=\"ts\">\nimport type { CoreElement } from '@skylivellc/lienzo-core';\nimport { useId } from 'vue';\nimport { useEditor } from '../../state/editor.ts';\nimport Field from '../../ui/Field.vue';\nimport TextInput from '../../ui/TextInput.vue';\n\ndefineProps<{ element: CoreElement }>();\nconst editor = useEditor();\nconst t = editor.t;\nconst id = useId();\n</script>\n\n<template>\n <Field :id=\"id\" :label=\"t('el.videoUrl')\" :hint=\"t('el.videoHint')\">\n <TextInput :id=\"id\" v-model=\"element.props.url\" type=\"url\" :maxlength=\"500\" :placeholder=\"t('el.videoPlaceholder')\" @commit=\"editor.commit()\" />\n </Field>\n</template>\n","<script setup lang=\"ts\">\nimport type { CoreElement } from '@skylivellc/lienzo-core';\nimport { useId } from 'vue';\nimport { useEditor } from '../../state/editor.ts';\nimport Field from '../../ui/Field.vue';\nimport TextInput from '../../ui/TextInput.vue';\n\ndefineProps<{ element: CoreElement }>();\nconst editor = useEditor();\nconst t = editor.t;\nconst id = useId();\n</script>\n\n<template>\n <Field :id=\"id\" :label=\"t('el.videoUrl')\" :hint=\"t('el.videoHint')\">\n <TextInput :id=\"id\" v-model=\"element.props.url\" type=\"url\" :maxlength=\"500\" :placeholder=\"t('el.videoPlaceholder')\" @commit=\"editor.commit()\" />\n </Field>\n</template>\n","<script setup lang=\"ts\">\nimport { ChevronDown } from '@lucide/vue';\n\n/** Collapsible block of the settings panel; the title stays visible when closed. */\nwithDefaults(defineProps<{ title: string; open?: boolean }>(), { open: true });\n</script>\n\n<template>\n <details class=\"lze-panel-section\" :open=\"open\">\n <summary>{{ title }}<ChevronDown :size=\"14\" aria-hidden=\"true\" /></summary>\n <div class=\"lze-panel-body\"><slot /></div>\n </details>\n</template>\n","<script setup lang=\"ts\">\nimport { ChevronDown } from '@lucide/vue';\n\n/** Collapsible block of the settings panel; the title stays visible when closed. */\nwithDefaults(defineProps<{ title: string; open?: boolean }>(), { open: true });\n</script>\n\n<template>\n <details class=\"lze-panel-section\" :open=\"open\">\n <summary>{{ title }}<ChevronDown :size=\"14\" aria-hidden=\"true\" /></summary>\n <div class=\"lze-panel-body\"><slot /></div>\n </details>\n</template>\n","<script setup lang=\"ts\">\nimport { computed, useId } from 'vue';\nimport { GRADIENT_PRESETS, gradientCss, type Gradient } from '../model/theme.ts';\nimport { useEditor } from '../state/editor.ts';\nimport ColorPicker from '../ui/ColorPicker.vue';\nimport Field from '../ui/Field.vue';\nimport RangeInput from '../ui/RangeInput.vue';\nimport SelectInput from '../ui/SelectInput.vue';\n\n/** A gradient of an element fill or a section background: presets, two colors, shape and angle. */\nconst model = defineModel<Gradient | null | undefined>({ required: true });\nconst emit = defineEmits<{ commit: [] }>();\nconst editor = useEditor();\nconst t = editor.t;\nconst id = useId();\n\n/** What a gradient starts as when it is first created. */\nconst DEFAULT: Gradient = { type: 'linear', from: 'primary', to: 'secondary', angle: 135 };\nconst current = computed(() => ({ ...DEFAULT, ...model.value }));\n\nfunction set<K extends keyof Gradient>(key: K, value: Gradient[K]) {\n model.value = { ...current.value, [key]: value };\n}\n\nfunction apply(preset: Gradient) {\n model.value = { ...preset };\n emit('commit');\n}\n</script>\n\n<template>\n <div class=\"lze-stack\">\n <div class=\"lze-gradient-presets\" role=\"group\" :aria-label=\"t('gradient.presets')\">\n <button\n v-for=\"preset in GRADIENT_PRESETS\"\n :key=\"preset.name\"\n type=\"button\"\n class=\"lze-gradient-preset\"\n :style=\"{ background: gradientCss(preset.gradient, editor.theme.value) }\"\n :title=\"t(preset.name)\"\n :aria-label=\"t(preset.name)\"\n @click=\"apply(preset.gradient)\"\n />\n </div>\n <ColorPicker :model-value=\"current.from\" :label=\"t('gradient.from')\" @update:model-value=\"set('from', $event)\" @commit=\"emit('commit')\" />\n <ColorPicker :model-value=\"current.to\" :label=\"t('gradient.to')\" @update:model-value=\"set('to', $event)\" @commit=\"emit('commit')\" />\n <div class=\"lze-grid-2\">\n <Field :id=\"id\" :label=\"t('gradient.shape')\">\n <SelectInput\n :id=\"id\"\n :model-value=\"current.type\"\n :options=\"[{ value: 'linear', label: t('gradient.linear') }, { value: 'radial', label: t('gradient.radial') }] as const\"\n @update:model-value=\"set('type', $event)\"\n @commit=\"emit('commit')\"\n />\n </Field>\n <RangeInput\n v-if=\"current.type === 'linear'\"\n :model-value=\"current.angle\"\n :label=\"t('gradient.angle')\"\n :min=\"0\"\n :max=\"360\"\n :step=\"5\"\n :fallback=\"135\"\n :format=\"(value) => `${value}°`\"\n @update:model-value=\"set('angle', $event)\"\n @commit=\"emit('commit')\"\n />\n </div>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport { computed, useId } from 'vue';\nimport { GRADIENT_PRESETS, gradientCss, type Gradient } from '../model/theme.ts';\nimport { useEditor } from '../state/editor.ts';\nimport ColorPicker from '../ui/ColorPicker.vue';\nimport Field from '../ui/Field.vue';\nimport RangeInput from '../ui/RangeInput.vue';\nimport SelectInput from '../ui/SelectInput.vue';\n\n/** A gradient of an element fill or a section background: presets, two colors, shape and angle. */\nconst model = defineModel<Gradient | null | undefined>({ required: true });\nconst emit = defineEmits<{ commit: [] }>();\nconst editor = useEditor();\nconst t = editor.t;\nconst id = useId();\n\n/** What a gradient starts as when it is first created. */\nconst DEFAULT: Gradient = { type: 'linear', from: 'primary', to: 'secondary', angle: 135 };\nconst current = computed(() => ({ ...DEFAULT, ...model.value }));\n\nfunction set<K extends keyof Gradient>(key: K, value: Gradient[K]) {\n model.value = { ...current.value, [key]: value };\n}\n\nfunction apply(preset: Gradient) {\n model.value = { ...preset };\n emit('commit');\n}\n</script>\n\n<template>\n <div class=\"lze-stack\">\n <div class=\"lze-gradient-presets\" role=\"group\" :aria-label=\"t('gradient.presets')\">\n <button\n v-for=\"preset in GRADIENT_PRESETS\"\n :key=\"preset.name\"\n type=\"button\"\n class=\"lze-gradient-preset\"\n :style=\"{ background: gradientCss(preset.gradient, editor.theme.value) }\"\n :title=\"t(preset.name)\"\n :aria-label=\"t(preset.name)\"\n @click=\"apply(preset.gradient)\"\n />\n </div>\n <ColorPicker :model-value=\"current.from\" :label=\"t('gradient.from')\" @update:model-value=\"set('from', $event)\" @commit=\"emit('commit')\" />\n <ColorPicker :model-value=\"current.to\" :label=\"t('gradient.to')\" @update:model-value=\"set('to', $event)\" @commit=\"emit('commit')\" />\n <div class=\"lze-grid-2\">\n <Field :id=\"id\" :label=\"t('gradient.shape')\">\n <SelectInput\n :id=\"id\"\n :model-value=\"current.type\"\n :options=\"[{ value: 'linear', label: t('gradient.linear') }, { value: 'radial', label: t('gradient.radial') }] as const\"\n @update:model-value=\"set('type', $event)\"\n @commit=\"emit('commit')\"\n />\n </Field>\n <RangeInput\n v-if=\"current.type === 'linear'\"\n :model-value=\"current.angle\"\n :label=\"t('gradient.angle')\"\n :min=\"0\"\n :max=\"360\"\n :step=\"5\"\n :fallback=\"135\"\n :format=\"(value) => `${value}°`\"\n @update:model-value=\"set('angle', $event)\"\n @commit=\"emit('commit')\"\n />\n </div>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport type { Element } from '@skylivellc/lienzo-core';\nimport { computed } from 'vue';\nimport { useEditor } from '../../state/editor.ts';\nimport ColorPicker from '../../ui/ColorPicker.vue';\nimport PanelSection from '../../ui/PanelSection.vue';\nimport RangeInput from '../../ui/RangeInput.vue';\nimport SelectInput from '../../ui/SelectInput.vue';\nimport GradientEditor from '../GradientEditor.vue';\n\nconst props = defineProps<{ element: Element }>();\nconst editor = useEditor();\nconst t = editor.t;\nconst percent = (value: number) => `${Math.round(value * 100)}%`;\n\n/** The fill is a color or a gradient; switching to the gradient keeps the color for when it comes back. */\nconst mode = computed(() => (props.element.style.gradient ? 'gradient' : 'color'));\n\nfunction setMode(next: 'color' | 'gradient' | null | undefined) {\n const style = props.element.style;\n style.gradient = next === 'gradient' ? (style.gradient ?? { type: 'linear', from: style.background ?? 'primary', to: 'secondary', angle: 135 }) : null;\n editor.commit();\n}\n</script>\n\n<template>\n <PanelSection :title=\"t('style.fill')\">\n <ColorPicker v-model=\"element.style.color\" :label=\"t('style.color')\" @commit=\"editor.commit()\" />\n <div class=\"lze-heading\">\n <span class=\"lze-label\">{{ t('style.background') }}</span>\n <SelectInput\n :model-value=\"mode\"\n compact\n :label=\"t('style.backgroundType')\"\n :options=\"[{ value: 'color', label: t('fill.color') }, { value: 'gradient', label: t('fill.gradient') }] as const\"\n @update:model-value=\"setMode\"\n />\n </div>\n <ColorPicker v-if=\"mode === 'color'\" v-model=\"element.style.background\" :label=\"t('style.backgroundColor')\" @commit=\"editor.commit()\" />\n <GradientEditor v-else v-model=\"element.style.gradient\" @commit=\"editor.commit()\" />\n <div class=\"lze-grid-2\">\n <RangeInput v-model=\"element.style.background_opacity\" :label=\"t('style.transparency')\" :min=\"0\" :max=\"1\" :step=\"0.05\" :fallback=\"1\" :format=\"percent\" @commit=\"editor.commit()\" />\n <RangeInput v-model=\"element.style.blur\" :label=\"t('style.glass')\" :min=\"0\" :max=\"40\" :format=\"(value) => `${value} px`\" @commit=\"editor.commit()\" />\n </div>\n <p v-if=\"element.style.blur\" class=\"lze-hint\">{{ t('style.glassHint') }}</p>\n </PanelSection>\n</template>\n","<script setup lang=\"ts\">\nimport type { Element } from '@skylivellc/lienzo-core';\nimport { computed } from 'vue';\nimport { useEditor } from '../../state/editor.ts';\nimport ColorPicker from '../../ui/ColorPicker.vue';\nimport PanelSection from '../../ui/PanelSection.vue';\nimport RangeInput from '../../ui/RangeInput.vue';\nimport SelectInput from '../../ui/SelectInput.vue';\nimport GradientEditor from '../GradientEditor.vue';\n\nconst props = defineProps<{ element: Element }>();\nconst editor = useEditor();\nconst t = editor.t;\nconst percent = (value: number) => `${Math.round(value * 100)}%`;\n\n/** The fill is a color or a gradient; switching to the gradient keeps the color for when it comes back. */\nconst mode = computed(() => (props.element.style.gradient ? 'gradient' : 'color'));\n\nfunction setMode(next: 'color' | 'gradient' | null | undefined) {\n const style = props.element.style;\n style.gradient = next === 'gradient' ? (style.gradient ?? { type: 'linear', from: style.background ?? 'primary', to: 'secondary', angle: 135 }) : null;\n editor.commit();\n}\n</script>\n\n<template>\n <PanelSection :title=\"t('style.fill')\">\n <ColorPicker v-model=\"element.style.color\" :label=\"t('style.color')\" @commit=\"editor.commit()\" />\n <div class=\"lze-heading\">\n <span class=\"lze-label\">{{ t('style.background') }}</span>\n <SelectInput\n :model-value=\"mode\"\n compact\n :label=\"t('style.backgroundType')\"\n :options=\"[{ value: 'color', label: t('fill.color') }, { value: 'gradient', label: t('fill.gradient') }] as const\"\n @update:model-value=\"setMode\"\n />\n </div>\n <ColorPicker v-if=\"mode === 'color'\" v-model=\"element.style.background\" :label=\"t('style.backgroundColor')\" @commit=\"editor.commit()\" />\n <GradientEditor v-else v-model=\"element.style.gradient\" @commit=\"editor.commit()\" />\n <div class=\"lze-grid-2\">\n <RangeInput v-model=\"element.style.background_opacity\" :label=\"t('style.transparency')\" :min=\"0\" :max=\"1\" :step=\"0.05\" :fallback=\"1\" :format=\"percent\" @commit=\"editor.commit()\" />\n <RangeInput v-model=\"element.style.blur\" :label=\"t('style.glass')\" :min=\"0\" :max=\"40\" :format=\"(value) => `${value} px`\" @commit=\"editor.commit()\" />\n </div>\n <p v-if=\"element.style.blur\" class=\"lze-hint\">{{ t('style.glassHint') }}</p>\n </PanelSection>\n</template>\n","<script setup lang=\"ts\">\nimport type { Element, Style } from '@skylivellc/lienzo-core';\nimport { computed, useId } from 'vue';\nimport { useEditor } from '../../state/editor.ts';\nimport ColorPicker from '../../ui/ColorPicker.vue';\nimport Field from '../../ui/Field.vue';\nimport NumberInput from '../../ui/NumberInput.vue';\nimport PanelSection from '../../ui/PanelSection.vue';\nimport RangeInput from '../../ui/RangeInput.vue';\nimport SelectInput from '../../ui/SelectInput.vue';\n\ntype Shadow = NonNullable<Style['shadow_custom']>;\n\nconst props = defineProps<{ element: Element }>();\nconst editor = useEditor();\nconst t = editor.t;\nconst id = useId();\n\nconst shadows = (['none', 'sm', 'md', 'lg', 'custom'] as const).map((shadow) => ({ value: shadow, label: t(`style.shadow.${shadow}`) }));\n\n/** What a custom shadow starts as the first time it is edited. */\nconst DEFAULT_SHADOW: Shadow = { x: 0, y: 12, blur: 32, spread: 0, color: 'secondary', opacity: 0.2 };\nconst shadow = computed(() => ({ ...DEFAULT_SHADOW, ...props.element.style.shadow_custom }));\n\nfunction setShadow<K extends keyof Shadow>(key: K, value: Shadow[K]) {\n props.element.style.shadow_custom = { ...shadow.value, [key]: value };\n}\n</script>\n\n<template>\n <PanelSection :title=\"t('style.frame')\">\n <div class=\"lze-grid-2\">\n <NumberInput v-model=\"element.style.radius\" :label=\"t('style.radius')\" :min=\"0\" :max=\"999\" suffix=\"px\" @commit=\"editor.commit()\" />\n <NumberInput v-model=\"element.style.padding\" :label=\"t('style.padding')\" :min=\"0\" :max=\"80\" suffix=\"px\" @commit=\"editor.commit()\" />\n <NumberInput v-model=\"element.style.border_width\" :label=\"t('style.border')\" :min=\"0\" :max=\"12\" suffix=\"px\" @commit=\"editor.commit()\" />\n <NumberInput\n :model-value=\"element.z\"\n :label=\"t('style.layer')\"\n :min=\"0\"\n :max=\"999\"\n @update:model-value=\"element.z = $event ?? element.z\"\n @commit=\"editor.commit()\"\n />\n </div>\n <ColorPicker v-if=\"element.style.border_width\" v-model=\"element.style.border_color\" :label=\"t('style.borderColor')\" @commit=\"editor.commit()\" />\n <Field :id=\"id\" :label=\"t('style.shadow')\">\n <SelectInput :id=\"id\" :model-value=\"element.style.shadow ?? 'none'\" :options=\"shadows\" @update:model-value=\"element.style.shadow = $event\" @commit=\"editor.commit()\" />\n </Field>\n </PanelSection>\n <PanelSection v-if=\"element.style.shadow === 'custom'\" :title=\"t('style.customShadow')\">\n <div class=\"lze-grid-2\">\n <NumberInput :model-value=\"shadow.x\" :label=\"t('position.x')\" :min=\"-100\" :max=\"100\" suffix=\"px\" @update:model-value=\"setShadow('x', $event)\" @commit=\"editor.commit()\" />\n <NumberInput :model-value=\"shadow.y\" :label=\"t('position.y')\" :min=\"-100\" :max=\"100\" suffix=\"px\" @update:model-value=\"setShadow('y', $event)\" @commit=\"editor.commit()\" />\n <NumberInput :model-value=\"shadow.blur\" :label=\"t('style.shadowBlur')\" :min=\"0\" :max=\"200\" suffix=\"px\" @update:model-value=\"setShadow('blur', $event)\" @commit=\"editor.commit()\" />\n <NumberInput :model-value=\"shadow.spread\" :label=\"t('style.shadowSpread')\" :min=\"-50\" :max=\"100\" suffix=\"px\" @update:model-value=\"setShadow('spread', $event)\" @commit=\"editor.commit()\" />\n </div>\n <ColorPicker :model-value=\"shadow.color\" :label=\"t('style.shadowColor')\" @update:model-value=\"setShadow('color', $event)\" @commit=\"editor.commit()\" />\n <RangeInput\n :model-value=\"shadow.opacity\"\n :label=\"t('style.shadowOpacity')\"\n :min=\"0\"\n :max=\"1\"\n :step=\"0.05\"\n :format=\"(value) => `${Math.round(value * 100)}%`\"\n @update:model-value=\"setShadow('opacity', $event)\"\n @commit=\"editor.commit()\"\n />\n </PanelSection>\n</template>\n","<script setup lang=\"ts\">\nimport type { Element, Style } from '@skylivellc/lienzo-core';\nimport { computed, useId } from 'vue';\nimport { useEditor } from '../../state/editor.ts';\nimport ColorPicker from '../../ui/ColorPicker.vue';\nimport Field from '../../ui/Field.vue';\nimport NumberInput from '../../ui/NumberInput.vue';\nimport PanelSection from '../../ui/PanelSection.vue';\nimport RangeInput from '../../ui/RangeInput.vue';\nimport SelectInput from '../../ui/SelectInput.vue';\n\ntype Shadow = NonNullable<Style['shadow_custom']>;\n\nconst props = defineProps<{ element: Element }>();\nconst editor = useEditor();\nconst t = editor.t;\nconst id = useId();\n\nconst shadows = (['none', 'sm', 'md', 'lg', 'custom'] as const).map((shadow) => ({ value: shadow, label: t(`style.shadow.${shadow}`) }));\n\n/** What a custom shadow starts as the first time it is edited. */\nconst DEFAULT_SHADOW: Shadow = { x: 0, y: 12, blur: 32, spread: 0, color: 'secondary', opacity: 0.2 };\nconst shadow = computed(() => ({ ...DEFAULT_SHADOW, ...props.element.style.shadow_custom }));\n\nfunction setShadow<K extends keyof Shadow>(key: K, value: Shadow[K]) {\n props.element.style.shadow_custom = { ...shadow.value, [key]: value };\n}\n</script>\n\n<template>\n <PanelSection :title=\"t('style.frame')\">\n <div class=\"lze-grid-2\">\n <NumberInput v-model=\"element.style.radius\" :label=\"t('style.radius')\" :min=\"0\" :max=\"999\" suffix=\"px\" @commit=\"editor.commit()\" />\n <NumberInput v-model=\"element.style.padding\" :label=\"t('style.padding')\" :min=\"0\" :max=\"80\" suffix=\"px\" @commit=\"editor.commit()\" />\n <NumberInput v-model=\"element.style.border_width\" :label=\"t('style.border')\" :min=\"0\" :max=\"12\" suffix=\"px\" @commit=\"editor.commit()\" />\n <NumberInput\n :model-value=\"element.z\"\n :label=\"t('style.layer')\"\n :min=\"0\"\n :max=\"999\"\n @update:model-value=\"element.z = $event ?? element.z\"\n @commit=\"editor.commit()\"\n />\n </div>\n <ColorPicker v-if=\"element.style.border_width\" v-model=\"element.style.border_color\" :label=\"t('style.borderColor')\" @commit=\"editor.commit()\" />\n <Field :id=\"id\" :label=\"t('style.shadow')\">\n <SelectInput :id=\"id\" :model-value=\"element.style.shadow ?? 'none'\" :options=\"shadows\" @update:model-value=\"element.style.shadow = $event\" @commit=\"editor.commit()\" />\n </Field>\n </PanelSection>\n <PanelSection v-if=\"element.style.shadow === 'custom'\" :title=\"t('style.customShadow')\">\n <div class=\"lze-grid-2\">\n <NumberInput :model-value=\"shadow.x\" :label=\"t('position.x')\" :min=\"-100\" :max=\"100\" suffix=\"px\" @update:model-value=\"setShadow('x', $event)\" @commit=\"editor.commit()\" />\n <NumberInput :model-value=\"shadow.y\" :label=\"t('position.y')\" :min=\"-100\" :max=\"100\" suffix=\"px\" @update:model-value=\"setShadow('y', $event)\" @commit=\"editor.commit()\" />\n <NumberInput :model-value=\"shadow.blur\" :label=\"t('style.shadowBlur')\" :min=\"0\" :max=\"200\" suffix=\"px\" @update:model-value=\"setShadow('blur', $event)\" @commit=\"editor.commit()\" />\n <NumberInput :model-value=\"shadow.spread\" :label=\"t('style.shadowSpread')\" :min=\"-50\" :max=\"100\" suffix=\"px\" @update:model-value=\"setShadow('spread', $event)\" @commit=\"editor.commit()\" />\n </div>\n <ColorPicker :model-value=\"shadow.color\" :label=\"t('style.shadowColor')\" @update:model-value=\"setShadow('color', $event)\" @commit=\"editor.commit()\" />\n <RangeInput\n :model-value=\"shadow.opacity\"\n :label=\"t('style.shadowOpacity')\"\n :min=\"0\"\n :max=\"1\"\n :step=\"0.05\"\n :format=\"(value) => `${Math.round(value * 100)}%`\"\n @update:model-value=\"setShadow('opacity', $event)\"\n @commit=\"editor.commit()\"\n />\n </PanelSection>\n</template>\n","<script setup lang=\"ts\">\nimport type { Element, Style } from '@skylivellc/lienzo-core';\nimport { computed, useId } from 'vue';\nimport { useEditor } from '../../state/editor.ts';\nimport Field from '../../ui/Field.vue';\nimport PanelSection from '../../ui/PanelSection.vue';\nimport RangeInput from '../../ui/RangeInput.vue';\nimport SelectInput from '../../ui/SelectInput.vue';\n\ntype Animation = NonNullable<Style['animation']>;\n\nconst props = defineProps<{ element: Element }>();\nconst editor = useEditor();\nconst t = editor.t;\nconst ids = { entrance: useId(), hover: useId(), scroll: useId() };\n\nconst entrances = (['none', 'fade', 'up', 'down', 'left', 'right', 'zoom', 'blur', 'reveal'] as const).map((value) => ({ value, label: t(`style.anim.${value}`) }));\nconst scrolls = (['none', 'rise', 'drift', 'zoom'] as const).map((value) => ({ value, label: t(`style.scroll.${value}`) }));\nconst hovers = (['none', 'lift', 'grow', 'fade', 'sink', 'tilt', 'glow'] as const).map((value) => ({ value, label: t(`style.hover.${value}`) }));\nconst seconds = (value: number) => `${value} s`;\n\n/** What the entrance starts as the first time it is edited. */\nconst DEFAULT_ANIMATION: Animation = { type: 'none', delay: 0, duration: 0.7 };\nconst animation = computed(() => ({ ...DEFAULT_ANIMATION, ...props.element.style.animation }));\n\nfunction setAnimation<K extends keyof Animation>(key: K, value: Animation[K]) {\n props.element.style.animation = { ...animation.value, [key]: value };\n}\n</script>\n\n<template>\n <PanelSection :title=\"t('style.motion')\" :open=\"false\">\n <Field :id=\"ids.entrance\" :label=\"t('style.entrance')\">\n <SelectInput :id=\"ids.entrance\" :model-value=\"animation.type\" :options=\"entrances\" @update:model-value=\"setAnimation('type', $event)\" @commit=\"editor.commit()\" />\n </Field>\n <div v-if=\"animation.type !== 'none'\" class=\"lze-grid-2\">\n <RangeInput :model-value=\"animation.delay\" :label=\"t('style.delay')\" :min=\"0\" :max=\"2\" :step=\"0.1\" :format=\"seconds\" @update:model-value=\"setAnimation('delay', $event)\" @commit=\"editor.commit()\" />\n <RangeInput\n :model-value=\"animation.duration\"\n :label=\"t('style.duration')\"\n :min=\"0.2\"\n :max=\"2\"\n :step=\"0.1\"\n :fallback=\"0.7\"\n :format=\"seconds\"\n @update:model-value=\"setAnimation('duration', $event)\"\n @commit=\"editor.commit()\"\n />\n </div>\n <Field :id=\"ids.scroll\" :label=\"t('style.scroll')\" :hint=\"t('style.scrollHint')\">\n <SelectInput :id=\"ids.scroll\" :model-value=\"element.style.scroll ?? 'none'\" :options=\"scrolls\" @update:model-value=\"element.style.scroll = $event\" @commit=\"editor.commit()\" />\n </Field>\n <Field :id=\"ids.hover\" :label=\"t('style.hover')\">\n <SelectInput :id=\"ids.hover\" :model-value=\"element.style.hover ?? 'none'\" :options=\"hovers\" @update:model-value=\"element.style.hover = $event\" @commit=\"editor.commit()\" />\n </Field>\n <p class=\"lze-hint\">{{ t('style.motionHint') }}</p>\n </PanelSection>\n</template>\n","<script setup lang=\"ts\">\nimport type { Element, Style } from '@skylivellc/lienzo-core';\nimport { computed, useId } from 'vue';\nimport { useEditor } from '../../state/editor.ts';\nimport Field from '../../ui/Field.vue';\nimport PanelSection from '../../ui/PanelSection.vue';\nimport RangeInput from '../../ui/RangeInput.vue';\nimport SelectInput from '../../ui/SelectInput.vue';\n\ntype Animation = NonNullable<Style['animation']>;\n\nconst props = defineProps<{ element: Element }>();\nconst editor = useEditor();\nconst t = editor.t;\nconst ids = { entrance: useId(), hover: useId(), scroll: useId() };\n\nconst entrances = (['none', 'fade', 'up', 'down', 'left', 'right', 'zoom', 'blur', 'reveal'] as const).map((value) => ({ value, label: t(`style.anim.${value}`) }));\nconst scrolls = (['none', 'rise', 'drift', 'zoom'] as const).map((value) => ({ value, label: t(`style.scroll.${value}`) }));\nconst hovers = (['none', 'lift', 'grow', 'fade', 'sink', 'tilt', 'glow'] as const).map((value) => ({ value, label: t(`style.hover.${value}`) }));\nconst seconds = (value: number) => `${value} s`;\n\n/** What the entrance starts as the first time it is edited. */\nconst DEFAULT_ANIMATION: Animation = { type: 'none', delay: 0, duration: 0.7 };\nconst animation = computed(() => ({ ...DEFAULT_ANIMATION, ...props.element.style.animation }));\n\nfunction setAnimation<K extends keyof Animation>(key: K, value: Animation[K]) {\n props.element.style.animation = { ...animation.value, [key]: value };\n}\n</script>\n\n<template>\n <PanelSection :title=\"t('style.motion')\" :open=\"false\">\n <Field :id=\"ids.entrance\" :label=\"t('style.entrance')\">\n <SelectInput :id=\"ids.entrance\" :model-value=\"animation.type\" :options=\"entrances\" @update:model-value=\"setAnimation('type', $event)\" @commit=\"editor.commit()\" />\n </Field>\n <div v-if=\"animation.type !== 'none'\" class=\"lze-grid-2\">\n <RangeInput :model-value=\"animation.delay\" :label=\"t('style.delay')\" :min=\"0\" :max=\"2\" :step=\"0.1\" :format=\"seconds\" @update:model-value=\"setAnimation('delay', $event)\" @commit=\"editor.commit()\" />\n <RangeInput\n :model-value=\"animation.duration\"\n :label=\"t('style.duration')\"\n :min=\"0.2\"\n :max=\"2\"\n :step=\"0.1\"\n :fallback=\"0.7\"\n :format=\"seconds\"\n @update:model-value=\"setAnimation('duration', $event)\"\n @commit=\"editor.commit()\"\n />\n </div>\n <Field :id=\"ids.scroll\" :label=\"t('style.scroll')\" :hint=\"t('style.scrollHint')\">\n <SelectInput :id=\"ids.scroll\" :model-value=\"element.style.scroll ?? 'none'\" :options=\"scrolls\" @update:model-value=\"element.style.scroll = $event\" @commit=\"editor.commit()\" />\n </Field>\n <Field :id=\"ids.hover\" :label=\"t('style.hover')\">\n <SelectInput :id=\"ids.hover\" :model-value=\"element.style.hover ?? 'none'\" :options=\"hovers\" @update:model-value=\"element.style.hover = $event\" @commit=\"editor.commit()\" />\n </Field>\n <p class=\"lze-hint\">{{ t('style.motionHint') }}</p>\n </PanelSection>\n</template>\n","<script setup lang=\"ts\">\nimport { AlignCenterHorizontal, AlignCenterVertical, AlignEndHorizontal, AlignEndVertical, AlignStartHorizontal, AlignStartVertical } from '@lucide/vue';\nimport type { Component } from 'vue';\nimport { ALIGNMENTS, type Alignment } from '../model/geometry.ts';\nimport { useEditor } from '../state/editor.ts';\nimport IconButton from '../ui/IconButton.vue';\n\n/** The six alignments: one element aligns in its canvas, several against each other. */\nconst editor = useEditor();\n\nconst icons: Record<Alignment, Component> = {\n left: AlignStartVertical,\n hcenter: AlignCenterVertical,\n right: AlignEndVertical,\n top: AlignStartHorizontal,\n vmiddle: AlignCenterHorizontal,\n bottom: AlignEndHorizontal,\n};\n</script>\n\n<template>\n <div class=\"lze-row\" role=\"group\" :aria-label=\"editor.t('multi.align')\">\n <IconButton v-for=\"where in ALIGNMENTS\" :key=\"where\" :label=\"editor.t(`align.${where}`)\" @click=\"editor.align(where)\">\n <component :is=\"icons[where]\" :size=\"16\" aria-hidden=\"true\" />\n </IconButton>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport { AlignCenterHorizontal, AlignCenterVertical, AlignEndHorizontal, AlignEndVertical, AlignStartHorizontal, AlignStartVertical } from '@lucide/vue';\nimport type { Component } from 'vue';\nimport { ALIGNMENTS, type Alignment } from '../model/geometry.ts';\nimport { useEditor } from '../state/editor.ts';\nimport IconButton from '../ui/IconButton.vue';\n\n/** The six alignments: one element aligns in its canvas, several against each other. */\nconst editor = useEditor();\n\nconst icons: Record<Alignment, Component> = {\n left: AlignStartVertical,\n hcenter: AlignCenterVertical,\n right: AlignEndVertical,\n top: AlignStartHorizontal,\n vmiddle: AlignCenterHorizontal,\n bottom: AlignEndHorizontal,\n};\n</script>\n\n<template>\n <div class=\"lze-row\" role=\"group\" :aria-label=\"editor.t('multi.align')\">\n <IconButton v-for=\"where in ALIGNMENTS\" :key=\"where\" :label=\"editor.t(`align.${where}`)\" @click=\"editor.align(where)\">\n <component :is=\"icons[where]\" :size=\"16\" aria-hidden=\"true\" />\n </IconButton>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport type { Box, Element } from '@skylivellc/lienzo-core';\nimport { computed } from 'vue';\nimport { boxOf, writeBox } from '../../model/document.ts';\nimport { clampBox } from '../../model/geometry.ts';\nimport { useEditor } from '../../state/editor.ts';\nimport NumberInput from '../../ui/NumberInput.vue';\nimport PanelSection from '../../ui/PanelSection.vue';\nimport Toggle from '../../ui/Toggle.vue';\nimport AlignButtons from '../AlignButtons.vue';\n\n/** Where the element sits on the device being edited. On a phone it may follow the desktop box. */\nconst props = defineProps<{ element: Element }>();\nconst editor = useEditor();\nconst t = editor.t;\nconst device = computed(() => editor.state.device);\nconst box = computed(() => boxOf(props.element, device.value));\n\nfunction set(key: keyof Box, value: number | null | undefined) {\n if (typeof value === 'number') {\n writeBox(props.element, device.value, clampBox({ ...box.value, [key]: value }));\n }\n}\n\nfunction inherit() {\n props.element.layout.mobile = null;\n editor.commit();\n}\n</script>\n\n<template>\n <PanelSection :title=\"t('position.title', { device: t(device === 'desktop' ? 'position.desktop' : 'position.mobile') })\" :open=\"false\">\n <AlignButtons />\n <div class=\"lze-grid-2\">\n <NumberInput :model-value=\"box.x\" :label=\"t('position.x')\" suffix=\"%\" :step=\"0.5\" @update:model-value=\"set('x', $event)\" @commit=\"editor.commit()\" />\n <NumberInput :model-value=\"box.y\" :label=\"t('position.y')\" @update:model-value=\"set('y', $event)\" @commit=\"editor.commit()\" />\n <NumberInput :model-value=\"box.w\" :label=\"t('position.width')\" suffix=\"%\" :step=\"0.5\" @update:model-value=\"set('w', $event)\" @commit=\"editor.commit()\" />\n <NumberInput :model-value=\"box.h\" :label=\"t('position.height')\" @update:model-value=\"set('h', $event)\" @commit=\"editor.commit()\" />\n </div>\n <Toggle v-model=\"element.style.pinned\" :label=\"t('position.pinned')\" @commit=\"editor.commit()\" />\n <p class=\"lze-hint\">{{ t('position.pinnedHint') }}</p>\n <p v-if=\"device === 'mobile'\" class=\"lze-hint\">\n <template v-if=\"element.layout.mobile\">\n {{ t('position.own') }}\n <button type=\"button\" class=\"lze-link\" @click=\"inherit\">{{ t('position.inherit') }}</button>\n </template>\n <template v-else>{{ t('position.inherited') }}</template>\n </p>\n </PanelSection>\n</template>\n","<script setup lang=\"ts\">\nimport type { Box, Element } from '@skylivellc/lienzo-core';\nimport { computed } from 'vue';\nimport { boxOf, writeBox } from '../../model/document.ts';\nimport { clampBox } from '../../model/geometry.ts';\nimport { useEditor } from '../../state/editor.ts';\nimport NumberInput from '../../ui/NumberInput.vue';\nimport PanelSection from '../../ui/PanelSection.vue';\nimport Toggle from '../../ui/Toggle.vue';\nimport AlignButtons from '../AlignButtons.vue';\n\n/** Where the element sits on the device being edited. On a phone it may follow the desktop box. */\nconst props = defineProps<{ element: Element }>();\nconst editor = useEditor();\nconst t = editor.t;\nconst device = computed(() => editor.state.device);\nconst box = computed(() => boxOf(props.element, device.value));\n\nfunction set(key: keyof Box, value: number | null | undefined) {\n if (typeof value === 'number') {\n writeBox(props.element, device.value, clampBox({ ...box.value, [key]: value }));\n }\n}\n\nfunction inherit() {\n props.element.layout.mobile = null;\n editor.commit();\n}\n</script>\n\n<template>\n <PanelSection :title=\"t('position.title', { device: t(device === 'desktop' ? 'position.desktop' : 'position.mobile') })\" :open=\"false\">\n <AlignButtons />\n <div class=\"lze-grid-2\">\n <NumberInput :model-value=\"box.x\" :label=\"t('position.x')\" suffix=\"%\" :step=\"0.5\" @update:model-value=\"set('x', $event)\" @commit=\"editor.commit()\" />\n <NumberInput :model-value=\"box.y\" :label=\"t('position.y')\" @update:model-value=\"set('y', $event)\" @commit=\"editor.commit()\" />\n <NumberInput :model-value=\"box.w\" :label=\"t('position.width')\" suffix=\"%\" :step=\"0.5\" @update:model-value=\"set('w', $event)\" @commit=\"editor.commit()\" />\n <NumberInput :model-value=\"box.h\" :label=\"t('position.height')\" @update:model-value=\"set('h', $event)\" @commit=\"editor.commit()\" />\n </div>\n <Toggle v-model=\"element.style.pinned\" :label=\"t('position.pinned')\" @commit=\"editor.commit()\" />\n <p class=\"lze-hint\">{{ t('position.pinnedHint') }}</p>\n <p v-if=\"device === 'mobile'\" class=\"lze-hint\">\n <template v-if=\"element.layout.mobile\">\n {{ t('position.own') }}\n <button type=\"button\" class=\"lze-link\" @click=\"inherit\">{{ t('position.inherit') }}</button>\n </template>\n <template v-else>{{ t('position.inherited') }}</template>\n </p>\n </PanelSection>\n</template>\n","<script setup lang=\"ts\">\nimport type { Element } from '@skylivellc/lienzo-core';\nimport { AlignCenter, AlignLeft, AlignRight } from '@lucide/vue';\nimport { useEditor } from '../../state/editor.ts';\nimport IconButton from '../../ui/IconButton.vue';\nimport NumberInput from '../../ui/NumberInput.vue';\nimport PanelSection from '../../ui/PanelSection.vue';\nimport SelectInput from '../../ui/SelectInput.vue';\nimport Toggle from '../../ui/Toggle.vue';\n\nconst props = defineProps<{ element: Element }>();\nconst editor = useEditor();\nconst t = editor.t;\n\nconst fonts = [{ value: 'heading', label: 'style.fontHeading' }, { value: 'body', label: 'style.fontBody' }] as const;\nconst aligns = [\n { value: 'left', label: 'style.align.left', icon: AlignLeft },\n { value: 'center', label: 'style.align.center', icon: AlignCenter },\n { value: 'right', label: 'style.align.right', icon: AlignRight },\n] as const;\nconst weights = ([300, 400, 500, 600, 700, 800] as const).map((weight) => ({ value: weight, label: t(`style.weight.${weight}`) }));\nconst cases = (['none', 'upper', 'lower', 'title'] as const).map((value) => ({ value, label: t(`style.case.${value}`) }));\nconst faces = (['solid', 'outline', 'glow'] as const).map((value) => ({ value, label: t(`style.face.${value}`) }));\n\nfunction set<K extends 'font' | 'align'>(key: K, value: Element['style'][K]) {\n props.element.style[key] = value;\n editor.commit();\n}\n</script>\n\n<template>\n <PanelSection :title=\"t('style.text')\">\n <div class=\"lze-tabs-inline\" role=\"group\" :aria-label=\"t('style.font')\">\n <button\n v-for=\"font in fonts\"\n :key=\"font.value\"\n type=\"button\"\n :aria-pressed=\"(element.style.font ?? 'body') === font.value\"\n @click=\"set('font', font.value)\"\n >\n {{ t(font.label) }}\n </button>\n </div>\n <div class=\"lze-grid-2\">\n <NumberInput v-model=\"element.style.size\" :label=\"t('style.size')\" :min=\"8\" :max=\"240\" suffix=\"px\" @commit=\"editor.commit()\" />\n <SelectInput v-model=\"element.style.weight\" :options=\"weights\" :label=\"t('style.weight')\" :placeholder=\"t('style.weight')\" @commit=\"editor.commit()\" />\n </div>\n <div class=\"lze-grid-2\">\n <NumberInput\n v-model=\"element.style.size_mobile\"\n :label=\"t('style.sizeMobile')\"\n :min=\"8\"\n :max=\"240\"\n suffix=\"px\"\n :placeholder=\"String(element.style.size ?? '')\"\n @commit=\"editor.commit()\"\n />\n <NumberInput v-model=\"element.style.tracking\" :label=\"t('style.tracking')\" :min=\"-0.05\" :max=\"0.5\" :step=\"0.01\" @commit=\"editor.commit()\" />\n </div>\n <div class=\"lze-grid-2\">\n <SelectInput v-model=\"element.style.text_case\" :options=\"cases\" :label=\"t('style.case')\" @commit=\"editor.commit()\" />\n <SelectInput v-model=\"element.style.text_style\" :options=\"faces\" :label=\"t('style.face')\" @commit=\"editor.commit()\" />\n </div>\n <div class=\"lze-row\">\n <div class=\"lze-row\" role=\"group\" :aria-label=\"t('style.align')\">\n <IconButton\n v-for=\"align in aligns\"\n :key=\"align.value\"\n :label=\"t(align.label)\"\n :active=\"(element.style.align ?? 'left') === align.value\"\n @click=\"set('align', align.value)\"\n >\n <component :is=\"align.icon\" :size=\"16\" aria-hidden=\"true\" />\n </IconButton>\n </div>\n <NumberInput v-model=\"element.style.line_height\" class=\"lze-grow\" :label=\"t('style.lineHeight')\" :min=\"0.8\" :max=\"3\" :step=\"0.05\" @commit=\"editor.commit()\" />\n </div>\n <Toggle v-model=\"element.style.auto_height\" :label=\"t('style.autoHeight')\" @commit=\"editor.commit()\" />\n <p class=\"lze-hint\">{{ t('style.autoHeightHint') }}</p>\n </PanelSection>\n</template>\n","<script setup lang=\"ts\">\nimport type { Element } from '@skylivellc/lienzo-core';\nimport { AlignCenter, AlignLeft, AlignRight } from '@lucide/vue';\nimport { useEditor } from '../../state/editor.ts';\nimport IconButton from '../../ui/IconButton.vue';\nimport NumberInput from '../../ui/NumberInput.vue';\nimport PanelSection from '../../ui/PanelSection.vue';\nimport SelectInput from '../../ui/SelectInput.vue';\nimport Toggle from '../../ui/Toggle.vue';\n\nconst props = defineProps<{ element: Element }>();\nconst editor = useEditor();\nconst t = editor.t;\n\nconst fonts = [{ value: 'heading', label: 'style.fontHeading' }, { value: 'body', label: 'style.fontBody' }] as const;\nconst aligns = [\n { value: 'left', label: 'style.align.left', icon: AlignLeft },\n { value: 'center', label: 'style.align.center', icon: AlignCenter },\n { value: 'right', label: 'style.align.right', icon: AlignRight },\n] as const;\nconst weights = ([300, 400, 500, 600, 700, 800] as const).map((weight) => ({ value: weight, label: t(`style.weight.${weight}`) }));\nconst cases = (['none', 'upper', 'lower', 'title'] as const).map((value) => ({ value, label: t(`style.case.${value}`) }));\nconst faces = (['solid', 'outline', 'glow'] as const).map((value) => ({ value, label: t(`style.face.${value}`) }));\n\nfunction set<K extends 'font' | 'align'>(key: K, value: Element['style'][K]) {\n props.element.style[key] = value;\n editor.commit();\n}\n</script>\n\n<template>\n <PanelSection :title=\"t('style.text')\">\n <div class=\"lze-tabs-inline\" role=\"group\" :aria-label=\"t('style.font')\">\n <button\n v-for=\"font in fonts\"\n :key=\"font.value\"\n type=\"button\"\n :aria-pressed=\"(element.style.font ?? 'body') === font.value\"\n @click=\"set('font', font.value)\"\n >\n {{ t(font.label) }}\n </button>\n </div>\n <div class=\"lze-grid-2\">\n <NumberInput v-model=\"element.style.size\" :label=\"t('style.size')\" :min=\"8\" :max=\"240\" suffix=\"px\" @commit=\"editor.commit()\" />\n <SelectInput v-model=\"element.style.weight\" :options=\"weights\" :label=\"t('style.weight')\" :placeholder=\"t('style.weight')\" @commit=\"editor.commit()\" />\n </div>\n <div class=\"lze-grid-2\">\n <NumberInput\n v-model=\"element.style.size_mobile\"\n :label=\"t('style.sizeMobile')\"\n :min=\"8\"\n :max=\"240\"\n suffix=\"px\"\n :placeholder=\"String(element.style.size ?? '')\"\n @commit=\"editor.commit()\"\n />\n <NumberInput v-model=\"element.style.tracking\" :label=\"t('style.tracking')\" :min=\"-0.05\" :max=\"0.5\" :step=\"0.01\" @commit=\"editor.commit()\" />\n </div>\n <div class=\"lze-grid-2\">\n <SelectInput v-model=\"element.style.text_case\" :options=\"cases\" :label=\"t('style.case')\" @commit=\"editor.commit()\" />\n <SelectInput v-model=\"element.style.text_style\" :options=\"faces\" :label=\"t('style.face')\" @commit=\"editor.commit()\" />\n </div>\n <div class=\"lze-row\">\n <div class=\"lze-row\" role=\"group\" :aria-label=\"t('style.align')\">\n <IconButton\n v-for=\"align in aligns\"\n :key=\"align.value\"\n :label=\"t(align.label)\"\n :active=\"(element.style.align ?? 'left') === align.value\"\n @click=\"set('align', align.value)\"\n >\n <component :is=\"align.icon\" :size=\"16\" aria-hidden=\"true\" />\n </IconButton>\n </div>\n <NumberInput v-model=\"element.style.line_height\" class=\"lze-grow\" :label=\"t('style.lineHeight')\" :min=\"0.8\" :max=\"3\" :step=\"0.05\" @commit=\"editor.commit()\" />\n </div>\n <Toggle v-model=\"element.style.auto_height\" :label=\"t('style.autoHeight')\" @commit=\"editor.commit()\" />\n <p class=\"lze-hint\">{{ t('style.autoHeightHint') }}</p>\n </PanelSection>\n</template>\n","<script setup lang=\"ts\">\nimport type { Element } from '@skylivellc/lienzo-core';\nimport { FoldHorizontal, FoldVertical, RotateCcw } from '@lucide/vue';\nimport { useId } from 'vue';\nimport { useEditor } from '../../state/editor.ts';\nimport Field from '../../ui/Field.vue';\nimport IconButton from '../../ui/IconButton.vue';\nimport NumberInput from '../../ui/NumberInput.vue';\nimport PanelSection from '../../ui/PanelSection.vue';\nimport SelectInput from '../../ui/SelectInput.vue';\n\nconst props = defineProps<{ element: Element }>();\nconst editor = useEditor();\nconst t = editor.t;\nconst ids = { overflow: useId(), visible: useId() };\n\nconst overflows = (['visible', 'hidden', 'scroll-x', 'scroll-y'] as const).map((value) => ({ value, label: t(`style.overflow.${value}`) }));\nconst devices = (['all', 'desktop', 'mobile'] as const).map((value) => ({ value, label: t(`style.visible.${value}`) }));\n\nfunction set<K extends 'rotate' | 'flip_x' | 'flip_y'>(key: K, value: Element['style'][K]) {\n props.element.style[key] = value;\n editor.commit();\n}\n</script>\n\n<template>\n <PanelSection :title=\"t('style.transform')\" :open=\"false\">\n <div class=\"lze-row\">\n <NumberInput v-model=\"element.style.rotate\" class=\"lze-grow\" :label=\"t('style.rotate')\" :min=\"-180\" :max=\"180\" suffix=\"°\" @commit=\"editor.commit()\" />\n <IconButton :label=\"t('style.straighten')\" @click=\"set('rotate', 0)\"><RotateCcw :size=\"16\" aria-hidden=\"true\" /></IconButton>\n <IconButton :label=\"t('style.flipX')\" :active=\"element.style.flip_x === true\" @click=\"set('flip_x', !element.style.flip_x)\">\n <FoldHorizontal :size=\"16\" aria-hidden=\"true\" />\n </IconButton>\n <IconButton :label=\"t('style.flipY')\" :active=\"element.style.flip_y === true\" @click=\"set('flip_y', !element.style.flip_y)\">\n <FoldVertical :size=\"16\" aria-hidden=\"true\" />\n </IconButton>\n </div>\n <div class=\"lze-grid-2\">\n <Field :id=\"ids.overflow\" :label=\"t('style.overflow')\">\n <SelectInput\n :id=\"ids.overflow\"\n :model-value=\"element.style.overflow ?? (element.style.clip ? 'hidden' : 'visible')\"\n :options=\"overflows\"\n @update:model-value=\"element.style.overflow = $event\"\n @commit=\"editor.commit()\"\n />\n </Field>\n <Field :id=\"ids.visible\" :label=\"t('style.visibleOn')\">\n <SelectInput\n :id=\"ids.visible\"\n :model-value=\"element.style.visible_on ?? 'all'\"\n :options=\"devices\"\n @update:model-value=\"element.style.visible_on = $event\"\n @commit=\"editor.commit()\"\n />\n </Field>\n </div>\n <p class=\"lze-hint\">{{ t('style.transformHint') }}</p>\n </PanelSection>\n</template>\n","<script setup lang=\"ts\">\nimport type { Element } from '@skylivellc/lienzo-core';\nimport { FoldHorizontal, FoldVertical, RotateCcw } from '@lucide/vue';\nimport { useId } from 'vue';\nimport { useEditor } from '../../state/editor.ts';\nimport Field from '../../ui/Field.vue';\nimport IconButton from '../../ui/IconButton.vue';\nimport NumberInput from '../../ui/NumberInput.vue';\nimport PanelSection from '../../ui/PanelSection.vue';\nimport SelectInput from '../../ui/SelectInput.vue';\n\nconst props = defineProps<{ element: Element }>();\nconst editor = useEditor();\nconst t = editor.t;\nconst ids = { overflow: useId(), visible: useId() };\n\nconst overflows = (['visible', 'hidden', 'scroll-x', 'scroll-y'] as const).map((value) => ({ value, label: t(`style.overflow.${value}`) }));\nconst devices = (['all', 'desktop', 'mobile'] as const).map((value) => ({ value, label: t(`style.visible.${value}`) }));\n\nfunction set<K extends 'rotate' | 'flip_x' | 'flip_y'>(key: K, value: Element['style'][K]) {\n props.element.style[key] = value;\n editor.commit();\n}\n</script>\n\n<template>\n <PanelSection :title=\"t('style.transform')\" :open=\"false\">\n <div class=\"lze-row\">\n <NumberInput v-model=\"element.style.rotate\" class=\"lze-grow\" :label=\"t('style.rotate')\" :min=\"-180\" :max=\"180\" suffix=\"°\" @commit=\"editor.commit()\" />\n <IconButton :label=\"t('style.straighten')\" @click=\"set('rotate', 0)\"><RotateCcw :size=\"16\" aria-hidden=\"true\" /></IconButton>\n <IconButton :label=\"t('style.flipX')\" :active=\"element.style.flip_x === true\" @click=\"set('flip_x', !element.style.flip_x)\">\n <FoldHorizontal :size=\"16\" aria-hidden=\"true\" />\n </IconButton>\n <IconButton :label=\"t('style.flipY')\" :active=\"element.style.flip_y === true\" @click=\"set('flip_y', !element.style.flip_y)\">\n <FoldVertical :size=\"16\" aria-hidden=\"true\" />\n </IconButton>\n </div>\n <div class=\"lze-grid-2\">\n <Field :id=\"ids.overflow\" :label=\"t('style.overflow')\">\n <SelectInput\n :id=\"ids.overflow\"\n :model-value=\"element.style.overflow ?? (element.style.clip ? 'hidden' : 'visible')\"\n :options=\"overflows\"\n @update:model-value=\"element.style.overflow = $event\"\n @commit=\"editor.commit()\"\n />\n </Field>\n <Field :id=\"ids.visible\" :label=\"t('style.visibleOn')\">\n <SelectInput\n :id=\"ids.visible\"\n :model-value=\"element.style.visible_on ?? 'all'\"\n :options=\"devices\"\n @update:model-value=\"element.style.visible_on = $event\"\n @commit=\"editor.commit()\"\n />\n </Field>\n </div>\n <p class=\"lze-hint\">{{ t('style.transformHint') }}</p>\n </PanelSection>\n</template>\n","<script setup lang=\"ts\">\nimport type { CoreElementType, Element, StyleGroup } from '@skylivellc/lienzo-core';\nimport { computed, type Component } from 'vue';\nimport { useEditor } from '../state/editor.ts';\nimport Button from '../ui/Button.vue';\nimport AppContent from './content/AppContent.vue';\nimport ButtonContent from './content/ButtonContent.vue';\nimport FormFieldContent from './content/FormFieldContent.vue';\nimport IconContent from './content/IconContent.vue';\nimport ImageContent from './content/ImageContent.vue';\nimport GalleryContent from './content/GalleryContent.vue';\nimport SliderContent from './content/SliderContent.vue';\nimport NavbarContent from './content/NavbarContent.vue';\nimport ShapeContent from './content/ShapeContent.vue';\nimport TextContent from './content/TextContent.vue';\nimport VideoContent from './content/VideoContent.vue';\nimport FillStyle from './style/FillStyle.vue';\nimport FrameStyle from './style/FrameStyle.vue';\nimport MotionStyle from './style/MotionStyle.vue';\nimport PositionSection from './style/PositionSection.vue';\nimport TextStyle from './style/TextStyle.vue';\nimport TransformStyle from './style/TransformStyle.vue';\n\n/** Settings of the one selected element: its content, its look, and where it sits. */\nconst props = defineProps<{ element: Element }>();\nconst editor = useEditor();\nconst t = editor.t;\n\n/** Content controls per core type. A divider has none. */\nconst coreContent = {\n heading: TextContent,\n text: TextContent,\n image: ImageContent,\n button: ButtonContent,\n divider: null,\n video: VideoContent,\n shape: ShapeContent,\n icon: IconContent,\n navbar: NavbarContent,\n gallery: GalleryContent,\n slider: SliderContent,\n input: FormFieldContent,\n textarea: FormFieldContent,\n select: FormFieldContent,\n checkbox: FormFieldContent,\n} satisfies Record<CoreElementType, Component | null>;\n\n/** Style panels, in the order they are shown. An element shows the ones its type declares. */\nconst stylePanels = {\n fill: FillStyle,\n text: TextStyle,\n border: FrameStyle,\n effects: TransformStyle,\n motion: MotionStyle,\n} satisfies Record<StyleGroup, Component>;\n\nconst kind = computed(() => editor.kindOf(props.element));\n\nconst title = computed(() => {\n const current = kind.value;\n\n return current.kind === 'core' ? t(current.spec.label) : current.kind === 'app' ? editor.i18n.localized(current.spec.label) : t('type.unknown');\n});\n\nconst styles = computed(() => {\n const current = kind.value;\n const declared: readonly StyleGroup[] = current.kind === 'opaque' ? [] : current.spec.styles;\n\n return (Object.keys(stylePanels) as StyleGroup[]).filter((group) => declared.includes(group)).map((group) => ({ group, panel: stylePanels[group] }));\n});\n</script>\n\n<template>\n <div class=\"lze-stack\">\n <div class=\"lze-heading\">\n <h2 class=\"lze-panel-title\">{{ title }}</h2>\n <div class=\"lze-row lze-nowrap\">\n <Button v-if=\"kind.kind !== 'opaque'\" @click=\"editor.duplicateSelected()\">{{ t('common.duplicate') }}</Button>\n <Button variant=\"danger\" @click=\"editor.removeSelected()\">{{ t('common.delete') }}</Button>\n </div>\n </div>\n <p v-if=\"kind.kind === 'opaque'\" class=\"lze-hint\">{{ t('el.unknown') }}</p>\n <template v-else>\n <component :is=\"coreContent[kind.element.type]\" v-if=\"kind.kind === 'core' && coreContent[kind.element.type]\" :element=\"kind.element\" />\n <AppContent v-else-if=\"kind.kind === 'app'\" :element=\"kind.element\" :spec=\"kind.spec\" />\n <component :is=\"style.panel\" v-for=\"style in styles\" :key=\"style.group\" :element=\"element\" />\n <PositionSection :element=\"element\" />\n </template>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport type { CoreElementType, Element, StyleGroup } from '@skylivellc/lienzo-core';\nimport { computed, type Component } from 'vue';\nimport { useEditor } from '../state/editor.ts';\nimport Button from '../ui/Button.vue';\nimport AppContent from './content/AppContent.vue';\nimport ButtonContent from './content/ButtonContent.vue';\nimport FormFieldContent from './content/FormFieldContent.vue';\nimport IconContent from './content/IconContent.vue';\nimport ImageContent from './content/ImageContent.vue';\nimport GalleryContent from './content/GalleryContent.vue';\nimport SliderContent from './content/SliderContent.vue';\nimport NavbarContent from './content/NavbarContent.vue';\nimport ShapeContent from './content/ShapeContent.vue';\nimport TextContent from './content/TextContent.vue';\nimport VideoContent from './content/VideoContent.vue';\nimport FillStyle from './style/FillStyle.vue';\nimport FrameStyle from './style/FrameStyle.vue';\nimport MotionStyle from './style/MotionStyle.vue';\nimport PositionSection from './style/PositionSection.vue';\nimport TextStyle from './style/TextStyle.vue';\nimport TransformStyle from './style/TransformStyle.vue';\n\n/** Settings of the one selected element: its content, its look, and where it sits. */\nconst props = defineProps<{ element: Element }>();\nconst editor = useEditor();\nconst t = editor.t;\n\n/** Content controls per core type. A divider has none. */\nconst coreContent = {\n heading: TextContent,\n text: TextContent,\n image: ImageContent,\n button: ButtonContent,\n divider: null,\n video: VideoContent,\n shape: ShapeContent,\n icon: IconContent,\n navbar: NavbarContent,\n gallery: GalleryContent,\n slider: SliderContent,\n input: FormFieldContent,\n textarea: FormFieldContent,\n select: FormFieldContent,\n checkbox: FormFieldContent,\n} satisfies Record<CoreElementType, Component | null>;\n\n/** Style panels, in the order they are shown. An element shows the ones its type declares. */\nconst stylePanels = {\n fill: FillStyle,\n text: TextStyle,\n border: FrameStyle,\n effects: TransformStyle,\n motion: MotionStyle,\n} satisfies Record<StyleGroup, Component>;\n\nconst kind = computed(() => editor.kindOf(props.element));\n\nconst title = computed(() => {\n const current = kind.value;\n\n return current.kind === 'core' ? t(current.spec.label) : current.kind === 'app' ? editor.i18n.localized(current.spec.label) : t('type.unknown');\n});\n\nconst styles = computed(() => {\n const current = kind.value;\n const declared: readonly StyleGroup[] = current.kind === 'opaque' ? [] : current.spec.styles;\n\n return (Object.keys(stylePanels) as StyleGroup[]).filter((group) => declared.includes(group)).map((group) => ({ group, panel: stylePanels[group] }));\n});\n</script>\n\n<template>\n <div class=\"lze-stack\">\n <div class=\"lze-heading\">\n <h2 class=\"lze-panel-title\">{{ title }}</h2>\n <div class=\"lze-row lze-nowrap\">\n <Button v-if=\"kind.kind !== 'opaque'\" @click=\"editor.duplicateSelected()\">{{ t('common.duplicate') }}</Button>\n <Button variant=\"danger\" @click=\"editor.removeSelected()\">{{ t('common.delete') }}</Button>\n </div>\n </div>\n <p v-if=\"kind.kind === 'opaque'\" class=\"lze-hint\">{{ t('el.unknown') }}</p>\n <template v-else>\n <component :is=\"coreContent[kind.element.type]\" v-if=\"kind.kind === 'core' && coreContent[kind.element.type]\" :element=\"kind.element\" />\n <AppContent v-else-if=\"kind.kind === 'app'\" :element=\"kind.element\" :spec=\"kind.spec\" />\n <component :is=\"style.panel\" v-for=\"style in styles\" :key=\"style.group\" :element=\"element\" />\n <PositionSection :element=\"element\" />\n </template>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport type { Modal } from '@skylivellc/lienzo-core';\nimport { useId } from 'vue';\nimport { MODAL_SIZES } from '../model/document.ts';\nimport { useEditor } from '../state/editor.ts';\nimport Button from '../ui/Button.vue';\nimport ColorPicker from '../ui/ColorPicker.vue';\nimport Field from '../ui/Field.vue';\nimport NumberInput from '../ui/NumberInput.vue';\nimport TextInput from '../ui/TextInput.vue';\nimport Toggle from '../ui/Toggle.vue';\n\n/** Settings of the modal being edited. */\nconst props = defineProps<{ modal: Modal }>();\nconst editor = useEditor();\nconst t = editor.t;\nconst id = useId();\n\nfunction applySize(size: (typeof MODAL_SIZES)[number]) {\n props.modal.size = size.key;\n props.modal.width = size.width;\n editor.commit();\n}\n\n/** Typing a width leaves the presets. */\nfunction setWidth(width: number | null | undefined) {\n if (typeof width === 'number') {\n props.modal.width = width;\n props.modal.size = 'custom';\n }\n}\n</script>\n\n<template>\n <div class=\"lze-stack\">\n <h2 class=\"lze-panel-title\">{{ t('modal.heading') }}</h2>\n <Field :id=\"id\" :label=\"t('modal.title')\">\n <TextInput :id=\"id\" v-model=\"modal.title\" :maxlength=\"120\" @commit=\"editor.commit()\" />\n <Toggle v-model=\"modal.show_title\" :label=\"t('modal.showTitle')\" @commit=\"editor.commit()\" />\n <p class=\"lze-hint\">{{ t('modal.showTitleHint') }}</p>\n </Field>\n <div class=\"lze-field\">\n <span class=\"lze-label\">{{ t('modal.size') }}</span>\n <div class=\"lze-row\" role=\"group\" :aria-label=\"t('modal.size')\">\n <Button\n v-for=\"size in MODAL_SIZES\"\n :key=\"size.key\"\n :variant=\"modal.size === size.key ? 'primary' : 'outline'\"\n :aria-pressed=\"modal.size === size.key\"\n @click=\"applySize(size)\"\n >\n {{ t(`modal.size.${size.key}`) }}\n </Button>\n </div>\n </div>\n <div class=\"lze-field\">\n <NumberInput\n :model-value=\"modal.width\"\n :label=\"t('modal.width')\"\n :min=\"280\"\n :max=\"1200\"\n suffix=\"px\"\n :disabled=\"modal.size === 'full'\"\n @update:model-value=\"setWidth\"\n @commit=\"editor.commit()\"\n />\n <p v-if=\"modal.size === 'full'\" class=\"lze-hint\">{{ t('modal.fullHint') }}</p>\n </div>\n <Button @click=\"editor.fitCanvas(modal)\">{{ t('section.fitHeight') }}</Button>\n <div class=\"lze-field\">\n <NumberInput\n :model-value=\"modal.height.desktop\"\n :label=\"t('section.heightDesktop')\"\n :min=\"80\"\n :max=\"2000\"\n @update:model-value=\"modal.height.desktop = $event ?? modal.height.desktop\"\n @commit=\"editor.commit()\"\n />\n <NumberInput\n :model-value=\"modal.height.mobile\"\n :label=\"t('section.heightMobile')\"\n :min=\"80\"\n :max=\"2400\"\n @update:model-value=\"modal.height.mobile = $event ?? modal.height.mobile\"\n @commit=\"editor.commit()\"\n />\n </div>\n <ColorPicker v-model=\"modal.background.color\" :label=\"t('modal.background')\" @commit=\"editor.commit()\" />\n <Button @click=\"editor.openModal(null)\">{{ t('canvas.backToPage') }}</Button>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport type { Modal } from '@skylivellc/lienzo-core';\nimport { useId } from 'vue';\nimport { MODAL_SIZES } from '../model/document.ts';\nimport { useEditor } from '../state/editor.ts';\nimport Button from '../ui/Button.vue';\nimport ColorPicker from '../ui/ColorPicker.vue';\nimport Field from '../ui/Field.vue';\nimport NumberInput from '../ui/NumberInput.vue';\nimport TextInput from '../ui/TextInput.vue';\nimport Toggle from '../ui/Toggle.vue';\n\n/** Settings of the modal being edited. */\nconst props = defineProps<{ modal: Modal }>();\nconst editor = useEditor();\nconst t = editor.t;\nconst id = useId();\n\nfunction applySize(size: (typeof MODAL_SIZES)[number]) {\n props.modal.size = size.key;\n props.modal.width = size.width;\n editor.commit();\n}\n\n/** Typing a width leaves the presets. */\nfunction setWidth(width: number | null | undefined) {\n if (typeof width === 'number') {\n props.modal.width = width;\n props.modal.size = 'custom';\n }\n}\n</script>\n\n<template>\n <div class=\"lze-stack\">\n <h2 class=\"lze-panel-title\">{{ t('modal.heading') }}</h2>\n <Field :id=\"id\" :label=\"t('modal.title')\">\n <TextInput :id=\"id\" v-model=\"modal.title\" :maxlength=\"120\" @commit=\"editor.commit()\" />\n <Toggle v-model=\"modal.show_title\" :label=\"t('modal.showTitle')\" @commit=\"editor.commit()\" />\n <p class=\"lze-hint\">{{ t('modal.showTitleHint') }}</p>\n </Field>\n <div class=\"lze-field\">\n <span class=\"lze-label\">{{ t('modal.size') }}</span>\n <div class=\"lze-row\" role=\"group\" :aria-label=\"t('modal.size')\">\n <Button\n v-for=\"size in MODAL_SIZES\"\n :key=\"size.key\"\n :variant=\"modal.size === size.key ? 'primary' : 'outline'\"\n :aria-pressed=\"modal.size === size.key\"\n @click=\"applySize(size)\"\n >\n {{ t(`modal.size.${size.key}`) }}\n </Button>\n </div>\n </div>\n <div class=\"lze-field\">\n <NumberInput\n :model-value=\"modal.width\"\n :label=\"t('modal.width')\"\n :min=\"280\"\n :max=\"1200\"\n suffix=\"px\"\n :disabled=\"modal.size === 'full'\"\n @update:model-value=\"setWidth\"\n @commit=\"editor.commit()\"\n />\n <p v-if=\"modal.size === 'full'\" class=\"lze-hint\">{{ t('modal.fullHint') }}</p>\n </div>\n <Button @click=\"editor.fitCanvas(modal)\">{{ t('section.fitHeight') }}</Button>\n <div class=\"lze-field\">\n <NumberInput\n :model-value=\"modal.height.desktop\"\n :label=\"t('section.heightDesktop')\"\n :min=\"80\"\n :max=\"2000\"\n @update:model-value=\"modal.height.desktop = $event ?? modal.height.desktop\"\n @commit=\"editor.commit()\"\n />\n <NumberInput\n :model-value=\"modal.height.mobile\"\n :label=\"t('section.heightMobile')\"\n :min=\"80\"\n :max=\"2400\"\n @update:model-value=\"modal.height.mobile = $event ?? modal.height.mobile\"\n @commit=\"editor.commit()\"\n />\n </div>\n <ColorPicker v-model=\"modal.background.color\" :label=\"t('modal.background')\" @commit=\"editor.commit()\" />\n <Button @click=\"editor.openModal(null)\">{{ t('canvas.backToPage') }}</Button>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport type { StyleGroup } from '@skylivellc/lienzo-core';\nimport { AlignHorizontalDistributeCenter, AlignVerticalDistributeCenter } from '@lucide/vue';\nimport { computed, type Component } from 'vue';\nimport { useEditor } from '../state/editor.ts';\nimport IconButton from '../ui/IconButton.vue';\nimport AlignButtons from './AlignButtons.vue';\nimport FillStyle from './style/FillStyle.vue';\nimport FrameStyle from './style/FrameStyle.vue';\nimport MotionStyle from './style/MotionStyle.vue';\nimport TextStyle from './style/TextStyle.vue';\nimport TransformStyle from './style/TransformStyle.vue';\n\n/**\n * Settings of several selected elements at once. Only what is visual lives\n * here; grouping, locking, order, duplicating and deleting are in the menu a\n * right click opens on the canvas.\n */\nconst editor = useEditor();\nconst t = editor.t;\nconst count = computed(() => editor.selectedElements.value.length);\n\nconst stylePanels = {\n fill: FillStyle,\n text: TextStyle,\n border: FrameStyle,\n effects: TransformStyle,\n motion: MotionStyle,\n} satisfies Record<StyleGroup, Component>;\n\n/** What every selected element understands: changing it changes all of them. */\nconst shared = computed(() => {\n const groups = editor.selectedElements.value.map((element) => {\n const kind = editor.kindOf(element);\n\n return kind.kind === 'opaque' ? [] : kind.spec.styles;\n });\n\n return (Object.keys(stylePanels) as StyleGroup[])\n .filter((group) => groups.length > 0 && groups.every((declared) => declared.includes(group)))\n .map((group) => ({ group, panel: stylePanels[group] }));\n});\n\n/** One object that writes to the whole selection. */\nconst target = computed(() => editor.sharedTarget());\n</script>\n\n<template>\n <div class=\"lze-stack\">\n <h2 class=\"lze-panel-title\">{{ t('multi.count', { n: count }) }}</h2>\n <div class=\"lze-field\">\n <span class=\"lze-label\">{{ t('multi.align') }}</span>\n <AlignButtons />\n </div>\n <div class=\"lze-field\">\n <span class=\"lze-label\">{{ t('multi.distribute') }}</span>\n <div class=\"lze-row\">\n <IconButton :label=\"t('multi.distributeX')\" :disabled=\"count < 3\" @click=\"editor.distributeSelected('x')\">\n <AlignHorizontalDistributeCenter :size=\"16\" aria-hidden=\"true\" />\n </IconButton>\n <IconButton :label=\"t('multi.distributeY')\" :disabled=\"count < 3\" @click=\"editor.distributeSelected('y')\">\n <AlignVerticalDistributeCenter :size=\"16\" aria-hidden=\"true\" />\n </IconButton>\n </div>\n <p class=\"lze-hint\">{{ t('multi.distributeHint') }}</p>\n </div>\n <template v-if=\"target\">\n <component :is=\"style.panel\" v-for=\"style in shared\" :key=\"style.group\" :element=\"target\" />\n </template>\n <p class=\"lze-hint\">{{ t('multi.menuHint') }}</p>\n <p class=\"lze-hint\">{{ t('multi.hint') }}</p>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport type { StyleGroup } from '@skylivellc/lienzo-core';\nimport { AlignHorizontalDistributeCenter, AlignVerticalDistributeCenter } from '@lucide/vue';\nimport { computed, type Component } from 'vue';\nimport { useEditor } from '../state/editor.ts';\nimport IconButton from '../ui/IconButton.vue';\nimport AlignButtons from './AlignButtons.vue';\nimport FillStyle from './style/FillStyle.vue';\nimport FrameStyle from './style/FrameStyle.vue';\nimport MotionStyle from './style/MotionStyle.vue';\nimport TextStyle from './style/TextStyle.vue';\nimport TransformStyle from './style/TransformStyle.vue';\n\n/**\n * Settings of several selected elements at once. Only what is visual lives\n * here; grouping, locking, order, duplicating and deleting are in the menu a\n * right click opens on the canvas.\n */\nconst editor = useEditor();\nconst t = editor.t;\nconst count = computed(() => editor.selectedElements.value.length);\n\nconst stylePanels = {\n fill: FillStyle,\n text: TextStyle,\n border: FrameStyle,\n effects: TransformStyle,\n motion: MotionStyle,\n} satisfies Record<StyleGroup, Component>;\n\n/** What every selected element understands: changing it changes all of them. */\nconst shared = computed(() => {\n const groups = editor.selectedElements.value.map((element) => {\n const kind = editor.kindOf(element);\n\n return kind.kind === 'opaque' ? [] : kind.spec.styles;\n });\n\n return (Object.keys(stylePanels) as StyleGroup[])\n .filter((group) => groups.length > 0 && groups.every((declared) => declared.includes(group)))\n .map((group) => ({ group, panel: stylePanels[group] }));\n});\n\n/** One object that writes to the whole selection. */\nconst target = computed(() => editor.sharedTarget());\n</script>\n\n<template>\n <div class=\"lze-stack\">\n <h2 class=\"lze-panel-title\">{{ t('multi.count', { n: count }) }}</h2>\n <div class=\"lze-field\">\n <span class=\"lze-label\">{{ t('multi.align') }}</span>\n <AlignButtons />\n </div>\n <div class=\"lze-field\">\n <span class=\"lze-label\">{{ t('multi.distribute') }}</span>\n <div class=\"lze-row\">\n <IconButton :label=\"t('multi.distributeX')\" :disabled=\"count < 3\" @click=\"editor.distributeSelected('x')\">\n <AlignHorizontalDistributeCenter :size=\"16\" aria-hidden=\"true\" />\n </IconButton>\n <IconButton :label=\"t('multi.distributeY')\" :disabled=\"count < 3\" @click=\"editor.distributeSelected('y')\">\n <AlignVerticalDistributeCenter :size=\"16\" aria-hidden=\"true\" />\n </IconButton>\n </div>\n <p class=\"lze-hint\">{{ t('multi.distributeHint') }}</p>\n </div>\n <template v-if=\"target\">\n <component :is=\"style.panel\" v-for=\"style in shared\" :key=\"style.group\" :element=\"target\" />\n </template>\n <p class=\"lze-hint\">{{ t('multi.menuHint') }}</p>\n <p class=\"lze-hint\">{{ t('multi.hint') }}</p>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport type { Section } from '@skylivellc/lienzo-core';\nimport { Trash2 } from '@lucide/vue';\nimport { computed, ref, useId, watch } from 'vue';\nimport { findCanvas } from '../model/document.ts';\nimport { useEditor } from '../state/editor.ts';\nimport Button from '../ui/Button.vue';\nimport ColorPicker from '../ui/ColorPicker.vue';\nimport Field from '../ui/Field.vue';\nimport IconButton from '../ui/IconButton.vue';\nimport ImageField from '../ui/ImageField.vue';\nimport NumberInput from '../ui/NumberInput.vue';\nimport RangeInput from '../ui/RangeInput.vue';\nimport SelectInput from '../ui/SelectInput.vue';\nimport TextInput from '../ui/TextInput.vue';\nimport Toggle from '../ui/Toggle.vue';\nimport GradientEditor from './GradientEditor.vue';\n\n/** Settings of the selected section. */\nconst props = defineProps<{ section: Section }>();\nconst editor = useEditor();\nconst t = editor.t;\nconst ids = { group: useId(), label: useId(), anchor: useId(), background: useId(), video: useId(), flow: useId() };\n\nconst groupModes = [\n { value: 'alone', label: t('section.alone') },\n { value: 'tabs', label: t('section.tab') },\n { value: 'steps', label: t('section.step') },\n] as const;\nconst flows = (['free', 'column', 'row'] as const).map((value) => ({ value, label: t(`section.flow.${value}`) }));\nconst aligns = (['start', 'center', 'end', 'between'] as const).map((value) => ({ value, label: t(`section.align.${value}`) }));\nconst flowing = computed(() => (props.section.flow ?? 'free') !== 'free');\nconst backgrounds = (['color', 'gradient', 'image', 'video'] as const).map((value) => ({ value, label: t(`fill.${value}`) }));\n\n/**\n * The id is what selection and anchor links point at, so it changes when the\n * field is committed, and only to an id an anchor can use and no other canvas has.\n */\nconst anchor = ref(props.section.id);\nconst anchorInvalid = ref(false);\nwatch(() => props.section.id, (id) => (anchor.value = id));\n\nfunction saveAnchor() {\n const next = anchor.value.trim();\n const taken = next !== props.section.id && findCanvas(editor.state.draft, next) !== undefined;\n anchorInvalid.value = !/^[a-zA-Z0-9_-]{1,40}$/.test(next) || taken;\n\n if (anchorInvalid.value || next === props.section.id) {\n return;\n }\n\n props.section.id = next;\n editor.selectCanvas(next);\n editor.commit();\n}\n\nfunction setBackground(type: Section['background']['type'] | null | undefined) {\n const background = props.section.background;\n\n if (!type) {\n return;\n }\n\n background.type = type;\n\n if (type === 'gradient') {\n background.gradient ??= { type: 'linear', from: 'primary', to: 'secondary', angle: 135 };\n }\n\n editor.commit();\n}\n\nfunction setImage(image: string | null | undefined) {\n props.section.background.image = image ?? null;\n\n // The image is the poster of a video background, so that one stays as it is.\n if (props.section.background.type !== 'video') {\n props.section.background.type = image ? 'image' : 'color';\n }\n}\n</script>\n\n<template>\n <div class=\"lze-stack\">\n <div class=\"lze-heading\">\n <h2 class=\"lze-panel-title\">{{ t('section.heading') }}</h2>\n <IconButton v-if=\"editor.state.draft.sections.length > 1\" :label=\"t('section.delete')\" tone=\"danger\" @click=\"editor.removeSection(section.id)\">\n <Trash2 :size=\"16\" aria-hidden=\"true\" />\n </IconButton>\n </div>\n <Field :id=\"ids.group\" :label=\"t('section.shownAs')\" :hint=\"t('section.groupHint')\">\n <SelectInput :id=\"ids.group\" :model-value=\"section.group?.type ?? 'alone'\" :options=\"groupModes\" @update:model-value=\"editor.setSectionGroup(section, $event ?? 'alone')\" />\n <TextInput v-if=\"section.group\" v-model=\"section.group.label\" :maxlength=\"60\" :placeholder=\"t('section.groupLabel')\" :label=\"t('section.groupLabel')\" @commit=\"editor.commit()\" />\n </Field>\n <Field :id=\"ids.anchor\" :label=\"t('section.anchor')\" :hint=\"t('section.anchorHint')\" :error=\"anchorInvalid ? t('section.anchorInvalid') : null\">\n <TextInput :id=\"ids.anchor\" v-model=\"anchor\" :maxlength=\"40\" @commit=\"saveAnchor\" />\n </Field>\n <div class=\"lze-row\">\n <Button @click=\"editor.fitCanvas(section)\">{{ t('section.fitHeight') }}</Button>\n <Button @click=\"editor.generateMobile(section)\">{{ t('section.generateMobile') }}</Button>\n </div>\n <div class=\"lze-field\">\n <NumberInput\n :model-value=\"section.height.desktop\"\n :label=\"t('section.heightDesktop')\"\n :min=\"80\"\n :max=\"3000\"\n @update:model-value=\"section.height.desktop = $event ?? section.height.desktop\"\n @commit=\"editor.commit()\"\n />\n <NumberInput\n :model-value=\"section.height.mobile\"\n :label=\"t('section.heightMobile')\"\n :min=\"80\"\n :max=\"4000\"\n @update:model-value=\"section.height.mobile = $event ?? section.height.mobile\"\n @commit=\"editor.commit()\"\n />\n </div>\n <Field :id=\"ids.flow\" :label=\"t('section.flow')\" :hint=\"t('section.flowHint')\">\n <SelectInput :id=\"ids.flow\" :model-value=\"section.flow ?? 'free'\" :options=\"flows\" @update:model-value=\"section.flow = $event\" @commit=\"editor.commit()\" />\n </Field>\n <div v-if=\"flowing\" class=\"lze-grid-2\">\n <NumberInput\n :model-value=\"section.flow_gap ?? 24\"\n :label=\"t('section.flowGap')\"\n :min=\"0\"\n :max=\"160\"\n suffix=\"px\"\n @update:model-value=\"section.flow_gap = $event ?? 24\"\n @commit=\"editor.commit()\"\n />\n <SelectInput :model-value=\"section.flow_align ?? 'start'\" :options=\"aligns\" :label=\"t('section.flowAlign')\" @update:model-value=\"section.flow_align = $event\" @commit=\"editor.commit()\" />\n </div>\n <Toggle v-model=\"section.wide\" :label=\"t('section.wide')\" @commit=\"editor.commit()\" />\n <p class=\"lze-hint\">{{ t('section.wideHint') }}</p>\n <Field :id=\"ids.background\" :label=\"t('section.background')\">\n <SelectInput :id=\"ids.background\" :model-value=\"section.background.type\" :options=\"backgrounds\" @update:model-value=\"setBackground\" />\n </Field>\n <ColorPicker v-if=\"section.background.type === 'color'\" v-model=\"section.background.color\" :label=\"t('section.color')\" @commit=\"editor.commit()\" />\n <GradientEditor v-else-if=\"section.background.type === 'gradient'\" v-model=\"section.background.gradient\" @commit=\"editor.commit()\" />\n <template v-else>\n <Field v-if=\"section.background.type === 'video'\" :id=\"ids.video\" :label=\"t('section.video')\" :hint=\"t('section.videoHint')\">\n <TextInput :id=\"ids.video\" v-model=\"section.background.video\" :maxlength=\"500\" placeholder=\"https://…/video.mp4\" @commit=\"editor.commit()\" />\n </Field>\n <ImageField\n :model-value=\"section.background.image\"\n :label=\"section.background.type === 'video' ? t('section.poster') : t('section.image')\"\n :choose=\"t('section.chooseImage')\"\n @update:model-value=\"setImage\"\n @commit=\"editor.commit()\"\n />\n <Toggle v-model=\"section.background.parallax\" :label=\"t('section.parallax')\" @commit=\"editor.commit()\" />\n <RangeInput\n v-model=\"section.background.overlay\"\n :label=\"t('section.overlay')\"\n :min=\"0\"\n :max=\"0.8\"\n :step=\"0.05\"\n :format=\"(value) => `${Math.round(value * 100)}%`\"\n @commit=\"editor.commit()\"\n />\n </template>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport type { Section } from '@skylivellc/lienzo-core';\nimport { Trash2 } from '@lucide/vue';\nimport { computed, ref, useId, watch } from 'vue';\nimport { findCanvas } from '../model/document.ts';\nimport { useEditor } from '../state/editor.ts';\nimport Button from '../ui/Button.vue';\nimport ColorPicker from '../ui/ColorPicker.vue';\nimport Field from '../ui/Field.vue';\nimport IconButton from '../ui/IconButton.vue';\nimport ImageField from '../ui/ImageField.vue';\nimport NumberInput from '../ui/NumberInput.vue';\nimport RangeInput from '../ui/RangeInput.vue';\nimport SelectInput from '../ui/SelectInput.vue';\nimport TextInput from '../ui/TextInput.vue';\nimport Toggle from '../ui/Toggle.vue';\nimport GradientEditor from './GradientEditor.vue';\n\n/** Settings of the selected section. */\nconst props = defineProps<{ section: Section }>();\nconst editor = useEditor();\nconst t = editor.t;\nconst ids = { group: useId(), label: useId(), anchor: useId(), background: useId(), video: useId(), flow: useId() };\n\nconst groupModes = [\n { value: 'alone', label: t('section.alone') },\n { value: 'tabs', label: t('section.tab') },\n { value: 'steps', label: t('section.step') },\n] as const;\nconst flows = (['free', 'column', 'row'] as const).map((value) => ({ value, label: t(`section.flow.${value}`) }));\nconst aligns = (['start', 'center', 'end', 'between'] as const).map((value) => ({ value, label: t(`section.align.${value}`) }));\nconst flowing = computed(() => (props.section.flow ?? 'free') !== 'free');\nconst backgrounds = (['color', 'gradient', 'image', 'video'] as const).map((value) => ({ value, label: t(`fill.${value}`) }));\n\n/**\n * The id is what selection and anchor links point at, so it changes when the\n * field is committed, and only to an id an anchor can use and no other canvas has.\n */\nconst anchor = ref(props.section.id);\nconst anchorInvalid = ref(false);\nwatch(() => props.section.id, (id) => (anchor.value = id));\n\nfunction saveAnchor() {\n const next = anchor.value.trim();\n const taken = next !== props.section.id && findCanvas(editor.state.draft, next) !== undefined;\n anchorInvalid.value = !/^[a-zA-Z0-9_-]{1,40}$/.test(next) || taken;\n\n if (anchorInvalid.value || next === props.section.id) {\n return;\n }\n\n props.section.id = next;\n editor.selectCanvas(next);\n editor.commit();\n}\n\nfunction setBackground(type: Section['background']['type'] | null | undefined) {\n const background = props.section.background;\n\n if (!type) {\n return;\n }\n\n background.type = type;\n\n if (type === 'gradient') {\n background.gradient ??= { type: 'linear', from: 'primary', to: 'secondary', angle: 135 };\n }\n\n editor.commit();\n}\n\nfunction setImage(image: string | null | undefined) {\n props.section.background.image = image ?? null;\n\n // The image is the poster of a video background, so that one stays as it is.\n if (props.section.background.type !== 'video') {\n props.section.background.type = image ? 'image' : 'color';\n }\n}\n</script>\n\n<template>\n <div class=\"lze-stack\">\n <div class=\"lze-heading\">\n <h2 class=\"lze-panel-title\">{{ t('section.heading') }}</h2>\n <IconButton v-if=\"editor.state.draft.sections.length > 1\" :label=\"t('section.delete')\" tone=\"danger\" @click=\"editor.removeSection(section.id)\">\n <Trash2 :size=\"16\" aria-hidden=\"true\" />\n </IconButton>\n </div>\n <Field :id=\"ids.group\" :label=\"t('section.shownAs')\" :hint=\"t('section.groupHint')\">\n <SelectInput :id=\"ids.group\" :model-value=\"section.group?.type ?? 'alone'\" :options=\"groupModes\" @update:model-value=\"editor.setSectionGroup(section, $event ?? 'alone')\" />\n <TextInput v-if=\"section.group\" v-model=\"section.group.label\" :maxlength=\"60\" :placeholder=\"t('section.groupLabel')\" :label=\"t('section.groupLabel')\" @commit=\"editor.commit()\" />\n </Field>\n <Field :id=\"ids.anchor\" :label=\"t('section.anchor')\" :hint=\"t('section.anchorHint')\" :error=\"anchorInvalid ? t('section.anchorInvalid') : null\">\n <TextInput :id=\"ids.anchor\" v-model=\"anchor\" :maxlength=\"40\" @commit=\"saveAnchor\" />\n </Field>\n <div class=\"lze-row\">\n <Button @click=\"editor.fitCanvas(section)\">{{ t('section.fitHeight') }}</Button>\n <Button @click=\"editor.generateMobile(section)\">{{ t('section.generateMobile') }}</Button>\n </div>\n <div class=\"lze-field\">\n <NumberInput\n :model-value=\"section.height.desktop\"\n :label=\"t('section.heightDesktop')\"\n :min=\"80\"\n :max=\"3000\"\n @update:model-value=\"section.height.desktop = $event ?? section.height.desktop\"\n @commit=\"editor.commit()\"\n />\n <NumberInput\n :model-value=\"section.height.mobile\"\n :label=\"t('section.heightMobile')\"\n :min=\"80\"\n :max=\"4000\"\n @update:model-value=\"section.height.mobile = $event ?? section.height.mobile\"\n @commit=\"editor.commit()\"\n />\n </div>\n <Field :id=\"ids.flow\" :label=\"t('section.flow')\" :hint=\"t('section.flowHint')\">\n <SelectInput :id=\"ids.flow\" :model-value=\"section.flow ?? 'free'\" :options=\"flows\" @update:model-value=\"section.flow = $event\" @commit=\"editor.commit()\" />\n </Field>\n <div v-if=\"flowing\" class=\"lze-grid-2\">\n <NumberInput\n :model-value=\"section.flow_gap ?? 24\"\n :label=\"t('section.flowGap')\"\n :min=\"0\"\n :max=\"160\"\n suffix=\"px\"\n @update:model-value=\"section.flow_gap = $event ?? 24\"\n @commit=\"editor.commit()\"\n />\n <SelectInput :model-value=\"section.flow_align ?? 'start'\" :options=\"aligns\" :label=\"t('section.flowAlign')\" @update:model-value=\"section.flow_align = $event\" @commit=\"editor.commit()\" />\n </div>\n <Toggle v-model=\"section.wide\" :label=\"t('section.wide')\" @commit=\"editor.commit()\" />\n <p class=\"lze-hint\">{{ t('section.wideHint') }}</p>\n <Field :id=\"ids.background\" :label=\"t('section.background')\">\n <SelectInput :id=\"ids.background\" :model-value=\"section.background.type\" :options=\"backgrounds\" @update:model-value=\"setBackground\" />\n </Field>\n <ColorPicker v-if=\"section.background.type === 'color'\" v-model=\"section.background.color\" :label=\"t('section.color')\" @commit=\"editor.commit()\" />\n <GradientEditor v-else-if=\"section.background.type === 'gradient'\" v-model=\"section.background.gradient\" @commit=\"editor.commit()\" />\n <template v-else>\n <Field v-if=\"section.background.type === 'video'\" :id=\"ids.video\" :label=\"t('section.video')\" :hint=\"t('section.videoHint')\">\n <TextInput :id=\"ids.video\" v-model=\"section.background.video\" :maxlength=\"500\" placeholder=\"https://…/video.mp4\" @commit=\"editor.commit()\" />\n </Field>\n <ImageField\n :model-value=\"section.background.image\"\n :label=\"section.background.type === 'video' ? t('section.poster') : t('section.image')\"\n :choose=\"t('section.chooseImage')\"\n @update:model-value=\"setImage\"\n @commit=\"editor.commit()\"\n />\n <Toggle v-model=\"section.background.parallax\" :label=\"t('section.parallax')\" @commit=\"editor.commit()\" />\n <RangeInput\n v-model=\"section.background.overlay\"\n :label=\"t('section.overlay')\"\n :min=\"0\"\n :max=\"0.8\"\n :step=\"0.05\"\n :format=\"(value) => `${Math.round(value * 100)}%`\"\n @commit=\"editor.commit()\"\n />\n </template>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport { computed } from 'vue';\nimport { findCanvas, isModal } from '../model/document.ts';\nimport { useEditor } from '../state/editor.ts';\nimport ElementPanel from './ElementPanel.vue';\nimport ModalPanel from './ModalPanel.vue';\nimport MultiPanel from './MultiPanel.vue';\nimport SectionPanel from './SectionPanel.vue';\n\n/** The Design tab: settings of whatever is selected. */\nconst editor = useEditor();\n\nconst shown = computed(() => {\n const selection = editor.state.selection;\n\n if (selection.kind === 'elements') {\n const element = editor.activeElement.value;\n\n return editor.selectedElements.value.length > 1 ? { kind: 'multi' as const } : element ? { kind: 'element' as const, element } : { kind: 'none' as const };\n }\n\n const canvas = selection.kind === 'canvas' ? findCanvas(editor.state.draft, selection.canvas) : undefined;\n\n if (!canvas) {\n return { kind: 'none' as const };\n }\n\n return isModal(canvas) ? { kind: 'modal' as const, modal: canvas } : { kind: 'section' as const, section: canvas };\n});\n</script>\n\n<template>\n <MultiPanel v-if=\"shown.kind === 'multi'\" />\n <ElementPanel v-else-if=\"shown.kind === 'element'\" :key=\"shown.element.id\" :element=\"shown.element\" />\n <ModalPanel v-else-if=\"shown.kind === 'modal'\" :key=\"shown.modal.id\" :modal=\"shown.modal\" />\n <SectionPanel v-else-if=\"shown.kind === 'section'\" :key=\"shown.section.id\" :section=\"shown.section\" />\n <p v-else class=\"lze-hint\">{{ editor.t('panel.nothing') }}</p>\n</template>\n","<script setup lang=\"ts\">\nimport { computed } from 'vue';\nimport { findCanvas, isModal } from '../model/document.ts';\nimport { useEditor } from '../state/editor.ts';\nimport ElementPanel from './ElementPanel.vue';\nimport ModalPanel from './ModalPanel.vue';\nimport MultiPanel from './MultiPanel.vue';\nimport SectionPanel from './SectionPanel.vue';\n\n/** The Design tab: settings of whatever is selected. */\nconst editor = useEditor();\n\nconst shown = computed(() => {\n const selection = editor.state.selection;\n\n if (selection.kind === 'elements') {\n const element = editor.activeElement.value;\n\n return editor.selectedElements.value.length > 1 ? { kind: 'multi' as const } : element ? { kind: 'element' as const, element } : { kind: 'none' as const };\n }\n\n const canvas = selection.kind === 'canvas' ? findCanvas(editor.state.draft, selection.canvas) : undefined;\n\n if (!canvas) {\n return { kind: 'none' as const };\n }\n\n return isModal(canvas) ? { kind: 'modal' as const, modal: canvas } : { kind: 'section' as const, section: canvas };\n});\n</script>\n\n<template>\n <MultiPanel v-if=\"shown.kind === 'multi'\" />\n <ElementPanel v-else-if=\"shown.kind === 'element'\" :key=\"shown.element.id\" :element=\"shown.element\" />\n <ModalPanel v-else-if=\"shown.kind === 'modal'\" :key=\"shown.modal.id\" :modal=\"shown.modal\" />\n <SectionPanel v-else-if=\"shown.kind === 'section'\" :key=\"shown.section.id\" :section=\"shown.section\" />\n <p v-else class=\"lze-hint\">{{ editor.t('panel.nothing') }}</p>\n</template>\n","<script setup lang=\"ts\">\nimport type { Issue } from '@skylivellc/lienzo-core';\nimport { computed, ref, useId, watch } from 'vue';\nimport { PAGE_TEMPLATES } from '../model/templates.ts';\nimport { useEditor } from '../state/editor.ts';\nimport Button from '../ui/Button.vue';\nimport Field from '../ui/Field.vue';\nimport TextInput from '../ui/TextInput.vue';\n\n/** The Page tab: title, address, search engine text, templates and shortcuts. Title and SEO save with the draft. */\nconst editor = useEditor();\nconst t = editor.t;\nconst ids = { title: useId(), slug: useId(), seoTitle: useId(), description: useId() };\nconst page = computed(() => editor.state.page);\n\nconst slug = ref(page.value?.slug ?? '');\nconst slugIssues = ref<Issue[]>([]);\nconst saving = ref(false);\nwatch(() => page.value?.id, () => {\n slug.value = page.value?.slug ?? '';\n slugIssues.value = [];\n});\n\nconst isEmpty = computed(() => editor.state.draft.sections.every((section) => section.elements.length === 0));\n\nasync function saveAddress() {\n saving.value = true;\n slugIssues.value = await editor.renamePage(slug.value.trim());\n saving.value = false;\n}\n\nfunction deletePage() {\n if (page.value && window.confirm(t('page.deleteConfirm', { title: page.value.title }))) {\n void editor.deletePage();\n }\n}\n</script>\n\n<template>\n <div v-if=\"page\" class=\"lze-stack\">\n <Field :id=\"ids.title\" :label=\"t('page.title')\">\n <TextInput :id=\"ids.title\" v-model=\"page.title\" :maxlength=\"120\" />\n </Field>\n <Field v-if=\"page.slug === ''\" :label=\"t('page.address')\" :hint=\"t('page.homeHint')\">\n <p class=\"lze-slug-static\"><span class=\"lze-slug-root\" aria-hidden=\"true\">/</span>{{ t('page.home') }}</p>\n </Field>\n <template v-else>\n <Field :id=\"ids.slug\" :label=\"t('page.address')\" :error=\"slugIssues.map((issue) => issue.message).join(' ') || null\">\n <div class=\"lze-slug\">\n <span aria-hidden=\"true\">/</span>\n <TextInput :id=\"ids.slug\" v-model=\"slug\" :maxlength=\"120\" :placeholder=\"t('newPage.slugPlaceholder')\" />\n </div>\n </Field>\n <div class=\"lze-row\">\n <Button :disabled=\"saving || slug.trim() === page.slug\" @click=\"saveAddress\">{{ t('page.saveAddress') }}</Button>\n <Button variant=\"danger\" @click=\"deletePage\">{{ t('page.delete') }}</Button>\n </div>\n </template>\n <div v-if=\"isEmpty\" class=\"lze-field lze-divided\">\n <span class=\"lze-label\">{{ t('page.templates') }}</span>\n <button v-for=\"template in PAGE_TEMPLATES\" :key=\"template.key\" type=\"button\" class=\"lze-choice\" @click=\"editor.applyPageTemplate(template.key)\">\n <strong>{{ t(template.name) }}</strong>\n <span class=\"lze-hint\">{{ t(template.note) }}</span>\n </button>\n </div>\n <Field :id=\"ids.seoTitle\" :label=\"t('page.seoTitle')\" :hint=\"t('page.seoTitleHint')\">\n <TextInput :id=\"ids.seoTitle\" v-model=\"page.seo.title\" :maxlength=\"120\" />\n </Field>\n <Field :id=\"ids.description\" :label=\"t('page.description')\">\n <TextInput :id=\"ids.description\" v-model=\"page.seo.description\" :rows=\"3\" :maxlength=\"300\" />\n </Field>\n <div class=\"lze-field lze-divided\">\n <span class=\"lze-label\">{{ t('page.shortcuts') }}</span>\n <ul class=\"lze-shortcuts lze-hint\">\n <li>{{ t('page.shortcutUndo') }}</li>\n <li>{{ t('page.shortcutSave') }}</li>\n <li>{{ t('page.shortcutCopy') }}</li>\n <li>{{ t('page.shortcutNudge') }}</li>\n </ul>\n </div>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport type { Issue } from '@skylivellc/lienzo-core';\nimport { computed, ref, useId, watch } from 'vue';\nimport { PAGE_TEMPLATES } from '../model/templates.ts';\nimport { useEditor } from '../state/editor.ts';\nimport Button from '../ui/Button.vue';\nimport Field from '../ui/Field.vue';\nimport TextInput from '../ui/TextInput.vue';\n\n/** The Page tab: title, address, search engine text, templates and shortcuts. Title and SEO save with the draft. */\nconst editor = useEditor();\nconst t = editor.t;\nconst ids = { title: useId(), slug: useId(), seoTitle: useId(), description: useId() };\nconst page = computed(() => editor.state.page);\n\nconst slug = ref(page.value?.slug ?? '');\nconst slugIssues = ref<Issue[]>([]);\nconst saving = ref(false);\nwatch(() => page.value?.id, () => {\n slug.value = page.value?.slug ?? '';\n slugIssues.value = [];\n});\n\nconst isEmpty = computed(() => editor.state.draft.sections.every((section) => section.elements.length === 0));\n\nasync function saveAddress() {\n saving.value = true;\n slugIssues.value = await editor.renamePage(slug.value.trim());\n saving.value = false;\n}\n\nfunction deletePage() {\n if (page.value && window.confirm(t('page.deleteConfirm', { title: page.value.title }))) {\n void editor.deletePage();\n }\n}\n</script>\n\n<template>\n <div v-if=\"page\" class=\"lze-stack\">\n <Field :id=\"ids.title\" :label=\"t('page.title')\">\n <TextInput :id=\"ids.title\" v-model=\"page.title\" :maxlength=\"120\" />\n </Field>\n <Field v-if=\"page.slug === ''\" :label=\"t('page.address')\" :hint=\"t('page.homeHint')\">\n <p class=\"lze-slug-static\"><span class=\"lze-slug-root\" aria-hidden=\"true\">/</span>{{ t('page.home') }}</p>\n </Field>\n <template v-else>\n <Field :id=\"ids.slug\" :label=\"t('page.address')\" :error=\"slugIssues.map((issue) => issue.message).join(' ') || null\">\n <div class=\"lze-slug\">\n <span aria-hidden=\"true\">/</span>\n <TextInput :id=\"ids.slug\" v-model=\"slug\" :maxlength=\"120\" :placeholder=\"t('newPage.slugPlaceholder')\" />\n </div>\n </Field>\n <div class=\"lze-row\">\n <Button :disabled=\"saving || slug.trim() === page.slug\" @click=\"saveAddress\">{{ t('page.saveAddress') }}</Button>\n <Button variant=\"danger\" @click=\"deletePage\">{{ t('page.delete') }}</Button>\n </div>\n </template>\n <div v-if=\"isEmpty\" class=\"lze-field lze-divided\">\n <span class=\"lze-label\">{{ t('page.templates') }}</span>\n <button v-for=\"template in PAGE_TEMPLATES\" :key=\"template.key\" type=\"button\" class=\"lze-choice\" @click=\"editor.applyPageTemplate(template.key)\">\n <strong>{{ t(template.name) }}</strong>\n <span class=\"lze-hint\">{{ t(template.note) }}</span>\n </button>\n </div>\n <Field :id=\"ids.seoTitle\" :label=\"t('page.seoTitle')\" :hint=\"t('page.seoTitleHint')\">\n <TextInput :id=\"ids.seoTitle\" v-model=\"page.seo.title\" :maxlength=\"120\" />\n </Field>\n <Field :id=\"ids.description\" :label=\"t('page.description')\">\n <TextInput :id=\"ids.description\" v-model=\"page.seo.description\" :rows=\"3\" :maxlength=\"300\" />\n </Field>\n <div class=\"lze-field lze-divided\">\n <span class=\"lze-label\">{{ t('page.shortcuts') }}</span>\n <ul class=\"lze-shortcuts lze-hint\">\n <li>{{ t('page.shortcutUndo') }}</li>\n <li>{{ t('page.shortcutSave') }}</li>\n <li>{{ t('page.shortcutCopy') }}</li>\n <li>{{ t('page.shortcutNudge') }}</li>\n </ul>\n </div>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport { ref } from 'vue';\nimport DesignPanel from '../panels/DesignPanel.vue';\nimport PagePanel from '../panels/PagePanel.vue';\nimport { useEditor } from '../state/editor.ts';\n\n/** Right sidebar: settings of what is selected, or of the page. */\nconst editor = useEditor();\nconst tab = ref<'design' | 'page'>('design');\n</script>\n\n<template>\n <aside class=\"lze-sidebar lze-right\">\n <div class=\"lze-tabs\" role=\"tablist\">\n <button type=\"button\" role=\"tab\" :aria-selected=\"tab === 'design'\" @click=\"tab = 'design'\">{{ editor.t('panel.design') }}</button>\n <button type=\"button\" role=\"tab\" :aria-selected=\"tab === 'page'\" @click=\"tab = 'page'\">{{ editor.t('panel.page') }}</button>\n </div>\n <div class=\"lze-scroll lze-pad\" role=\"tabpanel\">\n <DesignPanel v-if=\"tab === 'design'\" />\n <PagePanel v-else />\n </div>\n </aside>\n</template>\n","<script setup lang=\"ts\">\nimport { ref } from 'vue';\nimport DesignPanel from '../panels/DesignPanel.vue';\nimport PagePanel from '../panels/PagePanel.vue';\nimport { useEditor } from '../state/editor.ts';\n\n/** Right sidebar: settings of what is selected, or of the page. */\nconst editor = useEditor();\nconst tab = ref<'design' | 'page'>('design');\n</script>\n\n<template>\n <aside class=\"lze-sidebar lze-right\">\n <div class=\"lze-tabs\" role=\"tablist\">\n <button type=\"button\" role=\"tab\" :aria-selected=\"tab === 'design'\" @click=\"tab = 'design'\">{{ editor.t('panel.design') }}</button>\n <button type=\"button\" role=\"tab\" :aria-selected=\"tab === 'page'\" @click=\"tab = 'page'\">{{ editor.t('panel.page') }}</button>\n </div>\n <div class=\"lze-scroll lze-pad\" role=\"tabpanel\">\n <DesignPanel v-if=\"tab === 'design'\" />\n <PagePanel v-else />\n </div>\n </aside>\n</template>\n","<script setup lang=\"ts\">\nimport { Eye, History, Monitor, PencilLine, Plus, Redo2, Smartphone, Undo2 } from '@lucide/vue';\nimport { computed } from 'vue';\nimport Button from '../ui/Button.vue';\nimport { issueText, useEditor } from '../state/editor.ts';\n\n/** The editor's top bar: which page, how saving goes, the device, and publishing. */\nconst editor = useEditor();\nconst t = editor.t;\nconst page = computed(() => editor.state.page);\n\nconst time = new Intl.DateTimeFormat(editor.i18n.locale, { hour: '2-digit', minute: '2-digit' });\n\nconst status = computed((): { text: string; tone: 'muted' | 'warning' | 'danger'; retry: boolean } => {\n const save = editor.saveState.value;\n\n switch (save.kind) {\n case 'saved':\n return { text: save.at ? t('save.saved', { time: time.format(save.at) }) : t('save.idle'), tone: 'muted', retry: false };\n case 'pending':\n return { text: t('save.pending'), tone: 'muted', retry: false };\n case 'saving':\n return { text: t('save.saving'), tone: 'muted', retry: false };\n case 'offline':\n return { text: t('save.offline'), tone: 'warning', retry: true };\n case 'failed':\n return { text: t('save.failed', { message: save.message }), tone: 'danger', retry: true };\n case 'invalid':\n return { text: t('save.invalid', { issue: issueText(save.issues[0]) || save.message }), tone: 'danger', retry: false };\n case 'conflict':\n return { text: t('save.conflict'), tone: 'danger', retry: false };\n }\n});\n\nconst publicUrl = computed(() => {\n const base = editor.state.workspace.publicUrl;\n\n return base && page.value ? new URL(page.value.slug, base.endsWith('/') ? base : `${base}/`).href : null;\n});\n\n/** When the switch is refused (the pending save failed), the select goes back to the open page. */\nasync function choosePage(event: Event) {\n const select = event.target as HTMLSelectElement;\n await editor.openPage(Number(select.value));\n select.value = String(editor.state.page?.id ?? '');\n}\n</script>\n\n<template>\n <header class=\"lze-toolbar\">\n <div class=\"lze-toolbar-group\">\n <strong class=\"lze-site-name\">{{ editor.state.workspace.site.name }}</strong>\n <select v-if=\"page\" class=\"lze-select lze-page-select\" :aria-label=\"t('toolbar.pageSelect')\" :value=\"page.id\" @change=\"choosePage\">\n <option v-for=\"item in editor.state.workspace.pages\" :key=\"item.id\" :value=\"item.id\">{{ item.title }}{{ item.slug ? ` /${item.slug}` : '' }}</option>\n </select>\n <Button variant=\"ghost\" :title=\"t('toolbar.newPageHint')\" @click=\"editor.state.dialog = 'newPage'\"><Plus :size=\"16\" aria-hidden=\"true\" />{{ t('toolbar.newPage') }}</Button>\n <span v-if=\"page\" class=\"lze-badge-status\" :data-published=\"page.publishedAt !== null\">{{ page.publishedAt ? t('status.published') : t('status.unpublished') }}</span>\n <span class=\"lze-save-status\" :data-tone=\"status.tone\" data-testid=\"save-status\" aria-live=\"polite\">{{ status.text }}</span>\n <Button v-if=\"status.retry\" variant=\"ghost\" @click=\"editor.saveNow()\">{{ t('save.retry') }}</Button>\n <Button v-if=\"editor.saveState.value.kind === 'conflict'\" variant=\"primary\" @click=\"editor.reloadPage()\">{{ t('conflict.reload') }}</Button>\n </div>\n\n <div class=\"lze-toolbar-group\">\n <div class=\"lze-segmented\" role=\"group\" :aria-label=\"t('toolbar.device')\">\n <button\n v-for=\"option in (['desktop', 'mobile'] as const)\"\n :key=\"option\"\n type=\"button\"\n :title=\"option === 'desktop' ? t('toolbar.desktop') : t('toolbar.mobile')\"\n :aria-label=\"option === 'desktop' ? t('toolbar.desktop') : t('toolbar.mobile')\"\n :aria-pressed=\"editor.state.device === option\"\n @click=\"editor.state.device = option\"\n >\n <Monitor v-if=\"option === 'desktop'\" :size=\"16\" aria-hidden=\"true\" />\n <Smartphone v-else :size=\"16\" aria-hidden=\"true\" />\n </button>\n </div>\n <button type=\"button\" class=\"lze-icon-btn\" :title=\"t('toolbar.undo')\" :aria-label=\"t('toolbar.undo')\" :disabled=\"!editor.canUndo.value\" @click=\"editor.undo()\"><Undo2 :size=\"16\" aria-hidden=\"true\" /></button>\n <button type=\"button\" class=\"lze-icon-btn\" :title=\"t('toolbar.redo')\" :aria-label=\"t('toolbar.redo')\" :disabled=\"!editor.canRedo.value\" @click=\"editor.redo()\"><Redo2 :size=\"16\" aria-hidden=\"true\" /></button>\n <Button variant=\"ghost\" :title=\"editor.state.previewing ? t('toolbar.editHint') : t('toolbar.previewHint')\" @click=\"editor.state.previewing = !editor.state.previewing\">\n <PencilLine v-if=\"editor.state.previewing\" :size=\"16\" aria-hidden=\"true\" />\n <Eye v-else :size=\"16\" aria-hidden=\"true\" />\n {{ editor.state.previewing ? t('toolbar.edit') : t('toolbar.preview') }}\n </Button>\n <Button v-if=\"page?.versions.length\" variant=\"ghost\" :title=\"t('toolbar.versionsHint')\" @click=\"editor.state.dialog = 'versions'\"><History :size=\"16\" aria-hidden=\"true\" />{{ t('toolbar.versions') }}</Button>\n <Button variant=\"ghost\" :title=\"t('toolbar.submissionsHint')\" @click=\"editor.state.dialog = 'submissions'\">{{ t('toolbar.submissions') }}</Button>\n <Button variant=\"ghost\" @click=\"editor.state.dialog = 'theme'\">{{ t('toolbar.theme') }}</Button>\n <Button variant=\"ghost\" :title=\"t('toolbar.siteHint')\" @click=\"editor.state.dialog = 'site'\">{{ t('toolbar.site') }}</Button>\n <a v-if=\"publicUrl\" class=\"lze-btn\" :href=\"publicUrl\" target=\"_blank\" rel=\"noopener noreferrer\">{{ t('toolbar.viewSite') }}</a>\n <Button variant=\"primary\" :disabled=\"editor.state.publishing || !page\" @click=\"editor.publish()\">\n {{ editor.state.publishing ? t('toolbar.publishing') : t('toolbar.publish') }}\n </Button>\n </div>\n </header>\n</template>\n","<script setup lang=\"ts\">\nimport { Eye, History, Monitor, PencilLine, Plus, Redo2, Smartphone, Undo2 } from '@lucide/vue';\nimport { computed } from 'vue';\nimport Button from '../ui/Button.vue';\nimport { issueText, useEditor } from '../state/editor.ts';\n\n/** The editor's top bar: which page, how saving goes, the device, and publishing. */\nconst editor = useEditor();\nconst t = editor.t;\nconst page = computed(() => editor.state.page);\n\nconst time = new Intl.DateTimeFormat(editor.i18n.locale, { hour: '2-digit', minute: '2-digit' });\n\nconst status = computed((): { text: string; tone: 'muted' | 'warning' | 'danger'; retry: boolean } => {\n const save = editor.saveState.value;\n\n switch (save.kind) {\n case 'saved':\n return { text: save.at ? t('save.saved', { time: time.format(save.at) }) : t('save.idle'), tone: 'muted', retry: false };\n case 'pending':\n return { text: t('save.pending'), tone: 'muted', retry: false };\n case 'saving':\n return { text: t('save.saving'), tone: 'muted', retry: false };\n case 'offline':\n return { text: t('save.offline'), tone: 'warning', retry: true };\n case 'failed':\n return { text: t('save.failed', { message: save.message }), tone: 'danger', retry: true };\n case 'invalid':\n return { text: t('save.invalid', { issue: issueText(save.issues[0]) || save.message }), tone: 'danger', retry: false };\n case 'conflict':\n return { text: t('save.conflict'), tone: 'danger', retry: false };\n }\n});\n\nconst publicUrl = computed(() => {\n const base = editor.state.workspace.publicUrl;\n\n return base && page.value ? new URL(page.value.slug, base.endsWith('/') ? base : `${base}/`).href : null;\n});\n\n/** When the switch is refused (the pending save failed), the select goes back to the open page. */\nasync function choosePage(event: Event) {\n const select = event.target as HTMLSelectElement;\n await editor.openPage(Number(select.value));\n select.value = String(editor.state.page?.id ?? '');\n}\n</script>\n\n<template>\n <header class=\"lze-toolbar\">\n <div class=\"lze-toolbar-group\">\n <strong class=\"lze-site-name\">{{ editor.state.workspace.site.name }}</strong>\n <select v-if=\"page\" class=\"lze-select lze-page-select\" :aria-label=\"t('toolbar.pageSelect')\" :value=\"page.id\" @change=\"choosePage\">\n <option v-for=\"item in editor.state.workspace.pages\" :key=\"item.id\" :value=\"item.id\">{{ item.title }}{{ item.slug ? ` /${item.slug}` : '' }}</option>\n </select>\n <Button variant=\"ghost\" :title=\"t('toolbar.newPageHint')\" @click=\"editor.state.dialog = 'newPage'\"><Plus :size=\"16\" aria-hidden=\"true\" />{{ t('toolbar.newPage') }}</Button>\n <span v-if=\"page\" class=\"lze-badge-status\" :data-published=\"page.publishedAt !== null\">{{ page.publishedAt ? t('status.published') : t('status.unpublished') }}</span>\n <span class=\"lze-save-status\" :data-tone=\"status.tone\" data-testid=\"save-status\" aria-live=\"polite\">{{ status.text }}</span>\n <Button v-if=\"status.retry\" variant=\"ghost\" @click=\"editor.saveNow()\">{{ t('save.retry') }}</Button>\n <Button v-if=\"editor.saveState.value.kind === 'conflict'\" variant=\"primary\" @click=\"editor.reloadPage()\">{{ t('conflict.reload') }}</Button>\n </div>\n\n <div class=\"lze-toolbar-group\">\n <div class=\"lze-segmented\" role=\"group\" :aria-label=\"t('toolbar.device')\">\n <button\n v-for=\"option in (['desktop', 'mobile'] as const)\"\n :key=\"option\"\n type=\"button\"\n :title=\"option === 'desktop' ? t('toolbar.desktop') : t('toolbar.mobile')\"\n :aria-label=\"option === 'desktop' ? t('toolbar.desktop') : t('toolbar.mobile')\"\n :aria-pressed=\"editor.state.device === option\"\n @click=\"editor.state.device = option\"\n >\n <Monitor v-if=\"option === 'desktop'\" :size=\"16\" aria-hidden=\"true\" />\n <Smartphone v-else :size=\"16\" aria-hidden=\"true\" />\n </button>\n </div>\n <button type=\"button\" class=\"lze-icon-btn\" :title=\"t('toolbar.undo')\" :aria-label=\"t('toolbar.undo')\" :disabled=\"!editor.canUndo.value\" @click=\"editor.undo()\"><Undo2 :size=\"16\" aria-hidden=\"true\" /></button>\n <button type=\"button\" class=\"lze-icon-btn\" :title=\"t('toolbar.redo')\" :aria-label=\"t('toolbar.redo')\" :disabled=\"!editor.canRedo.value\" @click=\"editor.redo()\"><Redo2 :size=\"16\" aria-hidden=\"true\" /></button>\n <Button variant=\"ghost\" :title=\"editor.state.previewing ? t('toolbar.editHint') : t('toolbar.previewHint')\" @click=\"editor.state.previewing = !editor.state.previewing\">\n <PencilLine v-if=\"editor.state.previewing\" :size=\"16\" aria-hidden=\"true\" />\n <Eye v-else :size=\"16\" aria-hidden=\"true\" />\n {{ editor.state.previewing ? t('toolbar.edit') : t('toolbar.preview') }}\n </Button>\n <Button v-if=\"page?.versions.length\" variant=\"ghost\" :title=\"t('toolbar.versionsHint')\" @click=\"editor.state.dialog = 'versions'\"><History :size=\"16\" aria-hidden=\"true\" />{{ t('toolbar.versions') }}</Button>\n <Button variant=\"ghost\" :title=\"t('toolbar.submissionsHint')\" @click=\"editor.state.dialog = 'submissions'\">{{ t('toolbar.submissions') }}</Button>\n <Button variant=\"ghost\" @click=\"editor.state.dialog = 'theme'\">{{ t('toolbar.theme') }}</Button>\n <Button variant=\"ghost\" :title=\"t('toolbar.siteHint')\" @click=\"editor.state.dialog = 'site'\">{{ t('toolbar.site') }}</Button>\n <a v-if=\"publicUrl\" class=\"lze-btn\" :href=\"publicUrl\" target=\"_blank\" rel=\"noopener noreferrer\">{{ t('toolbar.viewSite') }}</a>\n <Button variant=\"primary\" :disabled=\"editor.state.publishing || !page\" @click=\"editor.publish()\">\n {{ editor.state.publishing ? t('toolbar.publishing') : t('toolbar.publish') }}\n </Button>\n </div>\n </header>\n</template>\n","/* Editor chrome. Everything is under .lze-root so a host page's CSS and ours never meet. */\n.lze-root {\n --lze-bg: #f3f4f6;\n --lze-panel: #ffffff;\n --lze-fg: #0f172a;\n --lze-muted: #64748b;\n --lze-border: #e2e8f0;\n --lze-hover: #f1f5f9;\n --lze-active: #e8eefc;\n --lze-accent: #2563eb;\n --lze-accent-fg: #ffffff;\n --lze-danger: #dc2626;\n --lze-success: #15803d;\n --lze-warning: #b45309;\n --lze-radius: 8px;\n --lze-font: ui-sans-serif, system-ui, -apple-system, 'Segoe UI', sans-serif;\n /* Canvas adornments sit on top of any site, so they use one fixed, high-contrast blue. */\n --lze-select: #2563eb;\n --lze-guide: #ec4899;\n\n all: initial;\n box-sizing: border-box;\n display: grid;\n grid-template-rows: auto minmax(0, 1fr);\n height: 100%;\n min-height: 480px;\n background: var(--lze-bg);\n color: var(--lze-fg);\n font: 13px/1.45 var(--lze-font);\n -webkit-font-smoothing: antialiased;\n}\n/*\n * Host pages style bare elements (resets, `p { ... }`). Inside the editor every\n * element starts from the browser defaults instead; SVG keeps its attributes.\n * Zero specificity, so every class rule below still wins.\n */\n.lze-root :where(*:not(svg, svg *)) { all: revert; box-sizing: border-box; }\n.lze-root :where(*::before, *::after) { box-sizing: border-box; }\n.lze-root :where(h1, h2, h3, p, figure) { margin: 0; }\n.lze-root :where(button, input, select, textarea) { font: inherit; color: inherit; }\n.lze-root :focus-visible { outline: 2px solid var(--lze-accent); outline-offset: 1px; }\n.lze-muted, .lze-hint { color: var(--lze-muted); }\n.lze-hint { font-size: 12px; }\n.lze-error { color: var(--lze-danger); font-size: 12px; }\n\n.lze-btn {\n display: inline-flex; align-items: center; justify-content: center; gap: 6px;\n height: 32px; padding: 0 12px; border-radius: var(--lze-radius);\n border: 1px solid var(--lze-border); background: var(--lze-panel); color: var(--lze-fg);\n font-weight: 500; white-space: nowrap; cursor: pointer; text-decoration: none;\n}\n.lze-btn[data-size='md'] { height: 36px; padding: 0 14px; }\n.lze-btn:hover:not(:disabled) { background: var(--lze-hover); }\n.lze-btn:disabled { opacity: .5; cursor: default; }\n.lze-btn[data-variant='primary'] { background: var(--lze-accent); border-color: var(--lze-accent); color: var(--lze-accent-fg); }\n.lze-btn[data-variant='primary']:hover:not(:disabled) { background: color-mix(in srgb, var(--lze-accent) 88%, black); }\n.lze-btn[data-variant='ghost'] { border-color: transparent; background: transparent; }\n.lze-btn[data-variant='danger'] { color: var(--lze-danger); }\n\n.lze-icon-btn {\n display: inline-grid; place-items: center; flex: none; width: 32px; height: 32px; padding: 0;\n border: 1px solid transparent; border-radius: var(--lze-radius); background: transparent; color: var(--lze-muted); cursor: pointer;\n}\n.lze-icon-btn:hover:not(:disabled) { background: var(--lze-hover); color: var(--lze-fg); }\n.lze-icon-btn[aria-pressed='true'] { border-color: var(--lze-fg); background: var(--lze-active); color: var(--lze-fg); }\n.lze-icon-btn[data-tone='danger'] { color: var(--lze-danger); }\n.lze-icon-btn:disabled { opacity: .4; cursor: default; }\n\n.lze-field { display: grid; gap: 7px; }\n.lze-label { font-size: 12px; font-weight: 600; color: var(--lze-fg); }\n.lze-input, .lze-select {\n width: 100%; min-height: 32px; padding: 6px 8px; border: 1px solid var(--lze-border); border-radius: 6px;\n background: var(--lze-panel); color: var(--lze-fg);\n}\n.lze-input:focus, .lze-select:focus { outline: none; border-color: var(--lze-accent); box-shadow: 0 0 0 2px color-mix(in srgb, var(--lze-accent) 20%, transparent); }\ntextarea.lze-input { resize: vertical; line-height: 1.4; }\n.lze-select[data-compact='true'] { min-height: 26px; width: auto; padding: 2px 6px; font-size: 12px; }\n\n.lze-number {\n display: flex; align-items: center; gap: 6px; height: 32px; padding: 0 8px;\n border: 1px solid var(--lze-border); border-radius: 6px; background: var(--lze-panel);\n}\n.lze-number:focus-within { border-color: var(--lze-accent); }\n.lze-number input { width: 100%; min-width: 0; border: 0; background: transparent; text-align: right; outline: none; }\n.lze-number-label, .lze-number-suffix { flex: none; font-size: 11px; color: var(--lze-muted); }\n\n.lze-toggle { display: flex; align-items: center; gap: 8px; cursor: pointer; }\n.lze-toggle input { width: 16px; height: 16px; margin: 0; accent-color: var(--lze-fg); }\n\n.lze-range { display: grid; gap: 4px; }\n.lze-range input { width: 100%; accent-color: var(--lze-fg); }\n\n.lze-swatches { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; }\n.lze-swatch { width: 26px; height: 26px; padding: 0; border-radius: 999px; border: 1px solid rgb(15 23 42 / .12); cursor: pointer; }\n.lze-swatch[aria-pressed='true'] { outline: 2px solid var(--lze-fg); outline-offset: 2px; }\n.lze-swatch-custom { display: inline-flex; align-items: center; gap: 4px; padding: 2px 8px 2px 3px; border: 1px solid var(--lze-border); border-radius: 999px; font-size: 12px; color: var(--lze-muted); cursor: pointer; }\n.lze-swatch-custom[data-active='true'] { outline: 2px solid var(--lze-fg); outline-offset: 2px; }\n.lze-swatch-custom input { width: 20px; height: 20px; padding: 0; border: 0; border-radius: 999px; background: none; cursor: pointer; }\n\n.lze-panel-section { border-top: 1px solid var(--lze-border); padding-top: 4px; }\n.lze-panel-section > summary {\n display: flex; align-items: center; justify-content: space-between; padding: 8px 0; list-style: none;\n font-size: 12px; font-weight: 600; color: var(--lze-muted); cursor: pointer; user-select: none;\n}\n.lze-panel-section > summary::-webkit-details-marker { display: none; }\n.lze-panel-section > summary:hover { color: var(--lze-fg); }\n.lze-panel-section[open] > summary svg { transform: rotate(180deg); }\n.lze-panel-body { display: grid; gap: 10px; padding: 2px 0 12px; }\n\n.lze-dialog {\n width: min(520px, calc(100vw - 32px)); max-height: calc(100dvh - 48px); padding: 0;\n border: 1px solid var(--lze-border); border-radius: 12px; background: var(--lze-panel); color: var(--lze-fg);\n box-shadow: 0 24px 64px rgb(15 23 42 / .24); font: 13px/1.45 var(--lze-font);\n}\n.lze-dialog[data-size='lg'] { width: min(720px, calc(100vw - 32px)); }\n.lze-dialog[data-size='xl'] { width: min(880px, calc(100vw - 32px)); }\n.lze-dialog::backdrop { background: rgb(15 23 42 / .45); }\n.lze-dialog-body { display: grid; gap: 16px; padding: 20px; }\n.lze-dialog-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 12px; }\n.lze-dialog-head h2 { font-size: 16px; font-weight: 650; }\n.lze-dialog-actions { display: flex; flex-wrap: wrap; gap: 8px; }\n\n.lze-toasts { position: fixed; z-index: 2147483000; right: 16px; bottom: 16px; display: grid; gap: 8px; max-width: min(420px, calc(100vw - 32px)); }\n.lze-toast {\n display: flex; align-items: center; gap: 8px; padding: 8px 8px 8px 14px; border-radius: 10px;\n background: var(--lze-fg); color: var(--lze-panel); box-shadow: 0 12px 32px rgb(15 23 42 / .24);\n}\n.lze-toast[data-tone='error'] { background: var(--lze-danger); }\n.lze-toast span { flex: 1; }\n.lze-toast .lze-icon-btn { color: inherit; width: 26px; height: 26px; }\n.lze-toast .lze-icon-btn:hover { background: rgb(255 255 255 / .15); color: inherit; }\n\n.lze-grid-2 { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }\n.lze-grid-4 { display: grid; grid-template-columns: repeat(4, 1fr); gap: 6px; }\n.lze-row { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }\n.lze-stack { display: grid; gap: 16px; }\n.lze-heading { display: flex; align-items: center; justify-content: space-between; gap: 8px; font-size: 13px; font-weight: 650; }\n.lze-link { padding: 0; border: 0; background: none; color: inherit; text-decoration: underline; cursor: pointer; }\n",".lze-stage { position: relative; overflow: auto; padding: 24px; overscroll-behavior: contain; }\n.lze-stage[data-space], .lze-stage[data-space] * { cursor: grab !important; }\n.lze-stage[data-space='panning'], .lze-stage[data-space='panning'] * { cursor: grabbing !important; }\n.lze-context {\n position: fixed; z-index: 2147483100; min-width: 208px; padding: 6px; border: 1px solid var(--lze-border);\n border-radius: 10px; background: var(--lze-panel); box-shadow: 0 12px 32px rgb(15 23 42 / .18); font-size: 13px;\n}\n.lze-context:focus { outline: none; }\n.lze-context > button {\n display: flex; align-items: center; justify-content: space-between; gap: 16px; width: 100%; padding: 7px 10px;\n border: 0; border-radius: 6px; background: transparent; color: var(--lze-fg); font: inherit; text-align: left; cursor: pointer;\n}\n.lze-context > button:hover, .lze-context > button:focus-visible { background: var(--lze-hover); }\n.lze-context .lze-context-danger { color: var(--lze-danger); }\n.lze-context kbd { color: var(--lze-muted); font: inherit; font-size: 11px; }\n.lze-context hr { margin: 5px 6px; border: 0; border-top: 1px solid var(--lze-border); }\n.lze-context-label { margin: 6px 10px 2px; color: var(--lze-muted); font-size: 11px; }\n.lze-context-row { display: flex; gap: 2px; padding: 0 6px 4px; }\n.lze-context-row button {\n display: grid; place-items: center; width: 32px; height: 28px; border: 0; border-radius: 6px;\n background: transparent; color: var(--lze-fg); cursor: pointer;\n}\n.lze-context-row button:hover { background: var(--lze-hover); }\n/* Cada icono de alinear es una línea y una caja contra ella. */\n.lze-context-align { position: relative; display: block; width: 16px; height: 16px; }\n.lze-context-align::before { content: ''; position: absolute; background: var(--lze-fg); }\n.lze-context-align::after { content: ''; position: absolute; background: var(--lze-muted); border-radius: 1px; }\n.lze-context-align[data-align='left']::before { left: 0; top: 0; bottom: 0; width: 1.5px; }\n.lze-context-align[data-align='left']::after { left: 3px; top: 4px; width: 11px; height: 8px; }\n.lze-context-align[data-align='hcenter']::before { left: 7.25px; top: 0; bottom: 0; width: 1.5px; }\n.lze-context-align[data-align='hcenter']::after { left: 2.5px; top: 4px; width: 11px; height: 8px; }\n.lze-context-align[data-align='right']::before { right: 0; top: 0; bottom: 0; width: 1.5px; }\n.lze-context-align[data-align='right']::after { right: 3px; top: 4px; width: 11px; height: 8px; }\n.lze-context-align[data-align='top']::before { top: 0; left: 0; right: 0; height: 1.5px; }\n.lze-context-align[data-align='top']::after { top: 3px; left: 4px; height: 11px; width: 8px; }\n.lze-context-align[data-align='vmiddle']::before { top: 7.25px; left: 0; right: 0; height: 1.5px; }\n.lze-context-align[data-align='vmiddle']::after { top: 2.5px; left: 4px; height: 11px; width: 8px; }\n.lze-context-align[data-align='bottom']::before { bottom: 0; left: 0; right: 0; height: 1.5px; }\n.lze-context-align[data-align='bottom']::after { bottom: 3px; left: 4px; height: 11px; width: 8px; }\n\n.lze-zoom {\n position: sticky; z-index: 25; bottom: 0; float: right; display: inline-flex; align-items: center; gap: 2px;\n margin-top: 12px; padding: 4px; border: 1px solid var(--lze-border); border-radius: 999px;\n background: var(--lze-panel); box-shadow: 0 6px 18px rgb(15 23 42 / .12);\n}\n.lze-zoom button { border: 0; border-radius: 999px; background: transparent; color: var(--lze-fg); cursor: pointer; font: inherit; }\n.lze-zoom-btn { width: 28px; height: 28px; font-size: 15px; line-height: 1; }\n.lze-zoom-value { min-width: 54px; height: 28px; font-size: 12px; font-weight: 600; font-variant-numeric: tabular-nums; }\n.lze-zoom button:hover { background: var(--lze-hover); }\n.lze-sheet { position: relative; margin: 0 auto; border-radius: 10px; background: var(--lze-panel); box-shadow: 0 1px 3px rgb(15 23 42 / .08), 0 12px 40px rgb(15 23 42 / .08); }\n.lze-sheet[data-device='mobile'] { border-radius: 18px; }\n.lze-scaler { position: absolute; top: 0; left: 0; transform-origin: 0 0; }\n.lze-frame { display: block; border: 0; background: transparent; }\n.lze-preview .lze-sheet { overflow: hidden; }\n.lze-preview .lze-frame { transform-origin: 0 0; }\n.lze-empty-hint { margin: 16px auto 0; max-width: 520px; text-align: center; color: var(--lze-muted); }\n.lze-hint-bubble { position: fixed; z-index: 2147483000; left: 50%; bottom: 24px; transform: translateX(-50%); padding: 4px 10px; border-radius: 6px; background: var(--lze-fg); color: var(--lze-panel); font-size: 12px; font-weight: 600; font-variant-numeric: tabular-nums; pointer-events: none; }\n.lze-render-issue, .lze-modal-banner {\n display: flex; align-items: center; justify-content: space-between; gap: 8px; max-width: 900px; margin: 0 auto 12px; padding: 8px 12px;\n border: 1px solid var(--lze-border); border-radius: var(--lze-radius); background: var(--lze-panel);\n}\n.lze-render-issue { border-color: var(--lze-danger); color: var(--lze-danger); }\n.lze-modal-banner { border-color: var(--lze-fg); font-weight: 600; }\n\n.lze-overlay { position: absolute; inset: 0; pointer-events: none; --line: calc(1px * var(--inv)); }\n.lze-overlay > * { position: absolute; }\n.lze-canvas-outline { outline: calc(2px * var(--inv)) solid var(--lze-select); outline-offset: calc(-2px * var(--inv)); box-shadow: inset 0 0 0 calc(4px * var(--inv)) rgb(255 255 255 / .7); }\n.lze-hover { outline: var(--line) solid var(--lze-select); }\n/* A white halo keeps the blue line visible on a blue site. */\n.lze-selection { outline: calc(2px * var(--inv)) solid var(--lze-select); outline-offset: var(--line); box-shadow: 0 0 0 calc(4px * var(--inv)) rgb(255 255 255 / .7); }\n.lze-selection[data-locked='true'] { outline-style: dashed; }\n.lze-lock { position: absolute; top: calc(-18px * var(--inv)); right: 0; width: calc(12px * var(--inv)); height: calc(12px * var(--inv)); color: var(--lze-select); }\n.lze-handles { pointer-events: none; }\n.lze-handle, .lze-radius, .lze-rotate { position: absolute; pointer-events: auto; padding: 0; touch-action: none; }\n.lze-handle {\n width: calc(11px * var(--inv)); height: calc(11px * var(--inv)); margin: calc(-5.5px * var(--inv));\n border: var(--line) solid #fff; border-radius: 999px; background: var(--lze-select);\n}\n.lze-handle[data-handle^='n'] { top: 0; }\n.lze-handle[data-handle^='s'] { top: 100%; }\n.lze-handle[data-handle='e'], .lze-handle[data-handle='w'] { top: 50%; }\n.lze-handle[data-handle$='w'] { left: 0; }\n.lze-handle[data-handle$='e'] { left: 100%; }\n.lze-handle[data-handle='n'], .lze-handle[data-handle='s'] { left: 50%; }\n.lze-handle[data-handle='nw'], .lze-handle[data-handle='se'] { cursor: nwse-resize; }\n.lze-handle[data-handle='ne'], .lze-handle[data-handle='sw'] { cursor: nesw-resize; }\n.lze-handle[data-handle='n'], .lze-handle[data-handle='s'] { cursor: ns-resize; }\n.lze-handle[data-handle='e'], .lze-handle[data-handle='w'] { cursor: ew-resize; }\n.lze-radius {\n top: calc(10px * var(--inv)); left: calc(10px * var(--inv)); width: calc(14px * var(--inv)); height: calc(14px * var(--inv));\n border: calc(2px * var(--inv)) solid var(--lze-select); border-radius: 999px; background: #fff; cursor: ew-resize;\n}\n.lze-rotate {\n top: calc(100% + 10px * var(--inv)); left: calc(100% + 10px * var(--inv)); display: grid; place-items: center;\n width: calc(24px * var(--inv)); height: calc(24px * var(--inv)); border: var(--line) solid var(--lze-select); border-radius: 999px;\n background: #fff; color: var(--lze-select); cursor: grab;\n}\n.lze-rotate svg { width: calc(13px * var(--inv)); height: calc(13px * var(--inv)); }\n.lze-guide { background: var(--lze-guide); }\n.lze-guide[data-axis='x'] { width: var(--line); }\n.lze-guide[data-axis='y'] { height: var(--line); }\n.lze-badge { transform: translateY(-100%) scale(var(--inv)); transform-origin: 0 100%; margin-top: -4px; padding: 2px 6px; border-radius: 4px; background: var(--lze-select); color: #fff; font-size: 11px; font-weight: 600; white-space: nowrap; }\n/* Each section says which one it is, and a click selects it. */\n.lze-section-chip {\n position: absolute; z-index: 5; transform: scale(var(--inv)) translateY(-100%); transform-origin: 0 100%;\n margin-top: -4px; padding: 2px 8px; border: 1px solid var(--lze-border); border-radius: 999px;\n background: var(--lze-panel); color: var(--lze-muted); font: 600 11px/1.6 var(--lze-font);\n white-space: nowrap; cursor: pointer; pointer-events: auto; opacity: .5; transition: opacity .15s ease;\n}\n\n.lze-section-chip:hover, .lze-section-chip[data-current='true'] { opacity: 1; color: var(--lze-fg); }\n.lze-section-chip[data-current='true'] { border-color: var(--lze-select); color: var(--lze-select); }\n\n/* A section with nothing in it says so, where the eye already is. */\n.lze-section-empty {\n position: absolute; z-index: 4; transform: scale(var(--inv)) translate(-50%, -50%); transform-origin: 0 0;\n margin: 0; padding: 6px 14px; border-radius: 999px; background: rgb(255 255 255 / .82);\n color: var(--lze-muted); font: 500 12px/1.4 var(--lze-font); white-space: nowrap;\n}\n\n/* El control del borde entre secciones: discreto, y claro al pasar por encima. */\n.lze-edge {\n position: absolute; z-index: 6; display: flex; gap: 4px; padding: 3px;\n transform: scale(var(--inv)) translate(-50%, -50%); transform-origin: 0 0;\n border: 1px solid var(--lze-border); border-radius: 999px; background: var(--lze-surface);\n box-shadow: 0 6px 18px rgb(15 23 42 / .14); pointer-events: auto; opacity: .22; transition: opacity .15s ease;\n}\n\n.lze-edge:hover, .lze-edge:focus-within { opacity: 1; }\n\n.lze-stacked {\n display: flex; align-items: center; gap: 8px; justify-content: space-between; padding: 6px 8px; pointer-events: auto;\n transform: scale(var(--inv)); transform-origin: 0 0; width: auto !important; max-width: none;\n background: rgb(255 255 255 / .95); border-bottom: 1px solid var(--lze-border); font-size: 12px; color: var(--lze-fg);\n}\n.lze-element-bar {\n display: flex; align-items: center; gap: 2px; padding: 3px; pointer-events: auto;\n transform-origin: 0 0; transform: scale(var(--inv)) translateY(calc(-100% - 10px));\n border: 1px solid var(--lze-border); border-radius: 10px; background: var(--lze-panel); box-shadow: 0 8px 24px rgb(15 23 42 / .14);\n}\n.lze-element-bar[data-below='true'] { transform: scale(var(--inv)) translateY(14px); }\n.lze-divider { width: 1px; height: 20px; margin: 0 2px; background: var(--lze-border); }\n",".lze-center { display: grid; place-content: center; justify-items: center; gap: 12px; grid-row: 1 / -1; padding: 32px; text-align: center; color: var(--lze-muted); }\n\n.lze-toolbar {\n display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 8px;\n padding: 8px 12px; border-bottom: 1px solid var(--lze-border); background: var(--lze-panel);\n}\n.lze-toolbar-group { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; min-width: 0; }\n.lze-site-name { max-width: 180px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 14px; }\n.lze-page-select { width: auto; max-width: 220px; }\n.lze-badge-status { padding: 2px 8px; border-radius: 999px; font-size: 11px; font-weight: 600; background: #fef3c7; color: var(--lze-warning); }\n.lze-badge-status[data-published='true'] { background: #dcfce7; color: var(--lze-success); }\n.lze-save-status { font-size: 12px; color: var(--lze-muted); max-width: 360px; }\n.lze-save-status[data-tone='warning'] { color: var(--lze-warning); }\n.lze-save-status[data-tone='danger'] { color: var(--lze-danger); }\n.lze-segmented { display: inline-flex; padding: 2px; border: 1px solid var(--lze-border); border-radius: var(--lze-radius); background: var(--lze-bg); }\n.lze-segmented button { display: grid; place-items: center; width: 32px; height: 26px; border: 0; border-radius: 6px; background: transparent; color: var(--lze-muted); cursor: pointer; }\n.lze-segmented button[aria-pressed='true'] { background: var(--lze-panel); color: var(--lze-fg); box-shadow: 0 1px 2px rgb(15 23 42 / .08); }\n\n.lze-body { display: grid; grid-template-columns: clamp(272px, 19vw, 352px) minmax(0, 1fr) clamp(312px, 22vw, 408px); min-height: 0; }\n.lze-main { position: relative; min-width: 0; min-height: 0; display: grid; }\n.lze-sidebar { display: flex; flex-direction: column; min-height: 0; background: var(--lze-panel); }\n.lze-left { border-right: 1px solid var(--lze-border); }\n.lze-right { border-left: 1px solid var(--lze-border); }\n.lze-scroll { flex: 1; min-height: 0; overflow-y: auto; }\n.lze-pad { padding: 16px; }\n.lze-left > .lze-scroll.lze-stack { padding: 16px; align-content: start; }\n\n.lze-tabs { display: flex; gap: 2px; padding: 10px 8px; border-bottom: 1px solid var(--lze-border); }\n.lze-tabs button {\n flex: 1; display: flex; flex-direction: column; align-items: center; gap: 2px; padding: 6px 2px; min-width: 0;\n border: 0; border-radius: 6px; background: transparent; color: var(--lze-muted); font-size: 11px; font-weight: 600; cursor: pointer;\n}\n.lze-tabs button span, .lze-tabs button { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }\n.lze-right .lze-tabs button { flex-direction: row; justify-content: center; font-size: 13px; }\n.lze-tabs button:hover { color: var(--lze-fg); }\n.lze-tabs button[aria-selected='true'] { background: var(--lze-hover); color: var(--lze-fg); }\n\n.lze-group-title { margin-top: 4px; font-size: 12px; font-weight: 600; color: var(--lze-muted); }\n.lze-palette { display: grid; grid-template-columns: repeat(auto-fill, minmax(100px, 1fr)); gap: 8px; }\n.lze-palette-item {\n display: flex; align-items: center; gap: 10px; padding: 11px 12px; min-width: 0;\n border: 1px solid var(--lze-border); border-radius: var(--lze-radius); background: var(--lze-panel); color: var(--lze-muted);\n font-size: 13px; font-weight: 500; text-align: left; cursor: grab; touch-action: none; user-select: none;\n}\n.lze-palette-item:hover { border-color: var(--lze-fg); color: var(--lze-fg); background: var(--lze-hover); }\n.lze-palette-item svg { flex: none; }\n.lze-list { display: grid; gap: 6px; }\n.lze-group-label { margin: 10px 0 2px; font-size: 11px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; color: var(--lze-muted); }\n.lze-group-label:first-child { margin-top: 0; }\n.lze-list-item { padding: 11px 12px; border: 1px solid var(--lze-border); border-radius: var(--lze-radius); background: var(--lze-panel); color: var(--lze-muted); font-size: 13px; font-weight: 500; text-align: left; cursor: pointer; }\n.lze-list-item:hover { border-color: var(--lze-fg); color: var(--lze-fg); }\n.lze-drag-ghost { position: fixed; z-index: 2147483000; pointer-events: none; padding: 6px 10px; border: 1px solid var(--lze-fg); border-radius: var(--lze-radius); background: var(--lze-panel); font-size: 12px; font-weight: 600; box-shadow: 0 8px 24px rgb(15 23 42 / .18); }\n\n.lze-layer-group { padding: 0 8px 2px; }\n.lze-layer-row { display: flex; align-items: center; gap: 2px; border-radius: 6px; color: var(--lze-muted); }\n.lze-layer-row:hover { background: var(--lze-hover); }\n.lze-layer-row[data-selected='true'] { background: var(--lze-active); color: var(--lze-fg); }\n.lze-layer-row .lze-icon-btn { width: 24px; height: 24px; }\n.lze-layer-name { flex: 1; display: flex; align-items: center; gap: 8px; min-width: 0; padding: 6px 4px; border: 0; background: transparent; color: inherit; text-align: left; cursor: pointer; }\n.lze-layer-name span:first-of-type { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }\n.lze-layer-actions { display: flex; opacity: 0; }\n.lze-layer-row:hover .lze-layer-actions, .lze-layer-row:focus-within .lze-layer-actions { opacity: 1; }\n.lze-layer-children { margin-left: 16px; padding-left: 4px; border-left: 1px solid var(--lze-border); }\n.lze-lock-toggle { opacity: 0; }\n.lze-lock-toggle[data-locked='true'], .lze-layer-row:hover .lze-lock-toggle, .lze-lock-toggle:focus-visible { opacity: 1; }\n\n.lze-card { display: grid; gap: 10px; padding: 12px; border: 1px solid var(--lze-border); border-radius: var(--lze-radius); }\n.lze-card[data-active='true'] { border-color: var(--lze-fg); background: var(--lze-hover); }\n\n.lze-media-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; align-content: start; }\n.lze-media-item { height: 96px; padding: 0; overflow: hidden; border: 1px solid var(--lze-border); border-radius: var(--lze-radius); background: var(--lze-bg); cursor: grab; touch-action: none; }\n.lze-media-item:hover { border-color: var(--lze-fg); }\n.lze-media-item img { width: 100%; height: 100%; object-fit: contain; }\n\n@media (max-width: 1100px) {\n .lze-body { grid-template-columns: 236px minmax(0, 1fr) 292px; }\n}\n","/* Settings panels and dialogs. */\n.lze-panel-title { font-size: 13px; font-weight: 650; }\n.lze-grow { flex: 1; min-width: 0; }\n.lze-nowrap { flex-wrap: nowrap; }\n.lze-divided { padding-top: 12px; border-top: 1px solid var(--lze-border); }\n\n.lze-image-preview { overflow: hidden; border: 1px solid var(--lze-border); border-radius: var(--lze-radius); background: var(--lze-bg); }\n.lze-image-preview img { display: block; width: 100%; height: 96px; object-fit: contain; }\n.lze-image-preview[data-thumb='icon'] { width: fit-content; padding: 6px; }\n.lze-image-preview[data-thumb='icon'] img { width: 40px; height: 40px; }\n\n.lze-tabs-inline { display: flex; gap: 4px; padding: 3px; border-radius: var(--lze-radius); background: var(--lze-bg); }\n.lze-tabs-inline button { flex: 1; padding: 5px 8px; border: 0; border-radius: 6px; background: transparent; color: var(--lze-muted); font-size: 12px; font-weight: 500; cursor: pointer; }\n.lze-tabs-inline button:hover { color: var(--lze-fg); }\n.lze-tabs-inline button[aria-pressed='true'] { background: var(--lze-panel); color: var(--lze-fg); box-shadow: 0 1px 2px rgb(15 23 42 / .08); }\n\n.lze-gradient-presets { display: flex; flex-wrap: wrap; gap: 6px; }\n.lze-gradient-preset { width: 48px; height: 28px; padding: 0; border: 1px solid rgb(15 23 42 / .12); border-radius: 6px; cursor: pointer; }\n.lze-gradient-preset:hover { outline: 2px solid var(--lze-fg); outline-offset: 1px; }\n\n.lze-link-card { display: grid; gap: 8px; margin: 0; padding: 8px; border: 1px solid var(--lze-border); border-radius: var(--lze-radius); }\n.lze-link-card legend { padding: 0 4px; font-size: 11px; color: var(--lze-muted); }\n\n.lze-icon-grid { display: grid; grid-template-columns: repeat(6, 1fr); gap: 4px; max-height: 192px; padding: 6px; overflow-y: auto; border: 1px solid var(--lze-border); border-radius: var(--lze-radius); }\n.lze-icon-grid .lze-hint { grid-column: 1 / -1; padding: 8px 0; text-align: center; }\n.lze-icon-choice { display: grid; place-items: center; aspect-ratio: 1; padding: 0; border: 0; border-radius: 6px; background: transparent; color: var(--lze-muted); cursor: pointer; }\n.lze-icon-choice:hover { background: var(--lze-hover); color: var(--lze-fg); }\n.lze-icon-choice[aria-pressed='true'] { background: var(--lze-active); color: var(--lze-fg); }\n\n.lze-slug { display: flex; align-items: center; gap: 6px; font-family: ui-monospace, monospace; color: var(--lze-muted); }\n.lze-slug-static { display: flex; gap: 6px; padding: 6px 8px; border: 1px solid var(--lze-border); border-radius: 6px; color: var(--lze-muted); }\n.lze-slug-root { font-family: ui-monospace, monospace; }\n.lze-choice { display: grid; gap: 2px; padding: 8px 10px; border: 1px solid var(--lze-border); border-radius: var(--lze-radius); background: var(--lze-panel); color: inherit; text-align: left; cursor: pointer; }\n.lze-choice:hover { border-color: var(--lze-fg); background: var(--lze-hover); }\n.lze-shortcuts { display: grid; gap: 4px; margin: 0; padding-left: 16px; }\n\n.lze-rows { display: grid; gap: 8px; margin: 0; padding: 0; list-style: none; }\n.lze-row-item { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 8px 12px; border: 1px solid var(--lze-border); border-radius: var(--lze-radius); }\n\n.lze-palette-choice { display: inline-flex; align-items: center; gap: 8px; padding: 6px 12px; border: 1px solid var(--lze-border); border-radius: var(--lze-radius); background: var(--lze-panel); color: inherit; cursor: pointer; }\n.lze-palette-choice:hover { border-color: var(--lze-fg); background: var(--lze-hover); }\n.lze-palette-choice .lze-row { gap: 3px; }\n.lze-dot { width: 14px; height: 14px; border-radius: 999px; border: 1px solid rgb(15 23 42 / .12); }\n.lze-theme-colors { display: grid; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); gap: 8px; }\n.lze-theme-color { display: flex; align-items: center; gap: 8px; padding: 6px 10px; border: 1px solid var(--lze-border); border-radius: var(--lze-radius); }\n.lze-theme-color span { flex: 1; }\n.lze-theme-color .lze-hex { width: 84px; min-height: 28px; padding: 3px 6px; font-family: ui-monospace, monospace; font-size: 12px; }\n.lze-theme-color input[type='color'] { width: 32px; height: 32px; padding: 0; border: 1px solid var(--lze-border); border-radius: 6px; background: none; cursor: pointer; }\n.lze-theme-preview { display: grid; gap: 10px; padding: 20px; border: 1px solid var(--lze-border); }\n.lze-theme-preview-heading { font-size: 24px; font-weight: 700; line-height: 1.2; }\n.lze-theme-preview-button { width: fit-content; padding: 8px 16px; font-weight: 600; }\n\n.lze-file-input { display: none; }\n.lze-asset-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 12px; }\n.lze-upload-tile {\n display: grid; place-items: center; align-content: center; gap: 4px; height: 128px; padding: 8px;\n border: 2px dashed var(--lze-border); border-radius: var(--lze-radius); background: var(--lze-panel); color: var(--lze-muted); text-align: center; cursor: pointer;\n}\n.lze-upload-tile:hover:not(:disabled) { border-color: var(--lze-fg); color: var(--lze-fg); }\n.lze-upload-tile:disabled { cursor: progress; }\n.lze-asset { position: relative; height: 128px; margin: 0; overflow: hidden; border: 1px solid var(--lze-border); border-radius: var(--lze-radius); }\n.lze-asset:hover { border-color: var(--lze-fg); }\n.lze-asset-use { display: flex; flex-direction: column; width: 100%; height: 100%; padding: 0; border: 0; background: var(--lze-bg); color: inherit; cursor: pointer; }\n.lze-asset-use img { flex: 1; min-height: 0; width: 100%; object-fit: contain; }\n.lze-asset-use figcaption { padding: 4px 8px; overflow: hidden; background: var(--lze-panel); font-size: 11px; color: var(--lze-muted); text-align: left; white-space: nowrap; text-overflow: ellipsis; }\n.lze-asset .lze-asset-delete { position: absolute; top: 6px; right: 6px; width: 28px; height: 28px; background: rgb(255 255 255 / .92); opacity: 0; }\n.lze-asset:hover .lze-asset-delete, .lze-asset .lze-asset-delete:focus-visible { opacity: 1; }\n\n.lze-submission { display: grid; gap: 6px; padding: 10px 0; border-bottom: 1px solid var(--lze-border); }\n.lze-submission dl { display: grid; grid-template-columns: minmax(96px, max-content) 1fr; gap: 4px 12px; margin: 0; }\n.lze-submission dt { color: var(--lze-muted); }\n.lze-submission dd { margin: 0; white-space: pre-wrap; overflow-wrap: anywhere; }\n\n/* A choice field that takes several values: one box per option. */\n.lze-choices { display: grid; gap: 6px; }\n","import base from './base.css?inline';\nimport canvas from './canvas.css?inline';\nimport shell from './shell.css?inline';\nimport panels from './panels.css?inline';\n\n/** All chrome CSS as one string, adopted by the document or shadow root the editor renders in. */\nexport const editorCss = [base, shell, canvas, panels].join('\\n');\n\nconst adopted = new WeakMap<Document | ShadowRoot, CSSStyleSheet>();\n\n/**\n * Adds the editor's stylesheet to the root `node` renders in, once. A\n * constructed stylesheet works the same in a document and in a shadow root\n * (the custom element), and needs no `<style>` tag a strict CSP would block.\n */\nexport function adoptEditorStyles(node: Node): void {\n const root = node.getRootNode();\n\n if (!(root instanceof Document || root instanceof ShadowRoot) || adopted.has(root)) {\n return;\n }\n\n const sheet = new CSSStyleSheet();\n sheet.replaceSync(editorCss);\n adopted.set(root, sheet);\n root.adoptedStyleSheets = [...root.adoptedStyleSheets, sheet];\n}\n","<script setup lang=\"ts\">\nimport { X } from '@lucide/vue';\nimport { useEditor } from '../state/editor.ts';\n\n/** Short notices in a corner; errors stay longer and are announced assertively. */\nconst editor = useEditor();\n</script>\n\n<template>\n <div class=\"lze-toasts\">\n <div v-for=\"toast in editor.state.toasts\" :key=\"toast.id\" class=\"lze-toast\" :data-tone=\"toast.tone\" :role=\"toast.tone === 'error' ? 'alert' : 'status'\">\n <span>{{ toast.text }}</span>\n <button type=\"button\" class=\"lze-icon-btn\" :aria-label=\"editor.t('toast.dismiss')\" @click=\"editor.dismiss(toast.id)\"><X :size=\"14\" aria-hidden=\"true\" /></button>\n </div>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport { X } from '@lucide/vue';\nimport { useEditor } from '../state/editor.ts';\n\n/** Short notices in a corner; errors stay longer and are announced assertively. */\nconst editor = useEditor();\n</script>\n\n<template>\n <div class=\"lze-toasts\">\n <div v-for=\"toast in editor.state.toasts\" :key=\"toast.id\" class=\"lze-toast\" :data-tone=\"toast.tone\" :role=\"toast.tone === 'error' ? 'alert' : 'status'\">\n <span>{{ toast.text }}</span>\n <button type=\"button\" class=\"lze-icon-btn\" :aria-label=\"editor.t('toast.dismiss')\" @click=\"editor.dismiss(toast.id)\"><X :size=\"14\" aria-hidden=\"true\" /></button>\n </div>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport { onBeforeUnmount, onMounted, provide, ref, watchEffect } from 'vue';\nimport Canvas from './canvas/Canvas.vue';\nimport Preview from './canvas/Preview.vue';\nimport { createClient } from './client.ts';\nimport ConflictDialog from './dialogs/ConflictDialog.vue';\nimport MediaLibrary from './dialogs/MediaLibrary.vue';\nimport NewPageDialog from './dialogs/NewPageDialog.vue';\nimport SiteDialog from './dialogs/SiteDialog.vue';\nimport SubmissionsDialog from './dialogs/SubmissionsDialog.vue';\nimport ThemeDialog from './dialogs/ThemeDialog.vue';\nimport VersionsDialog from './dialogs/VersionsDialog.vue';\nimport { createTranslator, type MessageOverrides } from './i18n/index.ts';\nimport { fontsHref } from './model/theme.ts';\nimport LeftSidebar from './shell/LeftSidebar.vue';\nimport RightPanel from './shell/RightPanel.vue';\nimport Toolbar from './shell/Toolbar.vue';\nimport { createEditor, editorKey } from './state/editor.ts';\nimport { handleShortcut } from './state/shortcuts.ts';\nimport { adoptEditorStyles } from './styles/index.ts';\nimport Button from './ui/Button.vue';\nimport Toasts from './ui/Toasts.vue';\n\n/**\n * The Lienzo editor. Give it the protocol `endpoint` of a backend (see\n * `@skylivellc/lienzo-core/protocol`); everything else is optional. Props are\n * read once, when the editor mounts.\n */\n/**\n * Hosts give the element a `style` or classes of their own, as the README\n * asks. Without this, Vue would copy them onto the editor's root, where an\n * inherited `display: block` replaces its grid: the body then grows to the\n * height of its content and the canvas can no longer scroll.\n */\ndefineOptions({ inheritAttrs: false });\n\nconst props = defineProps<{\n /** Base URL of the protocol, for example `/admin/site/lienzo`. */\n endpoint: string;\n /** Language of the editor itself. Defaults to English. */\n locale?: string;\n /** Extra or overriding strings by locale; partial packs fall back to English per key. */\n messages?: MessageOverrides;\n /** Extra request headers, such as a bearer token. Session cookies and Laravel's XSRF token work without any. */\n headers?: Record<string, string>;\n /** A fetch implementation to use instead of the global one. */\n fetch?: typeof fetch;\n}>();\n\nconst i18n = createTranslator(props.locale ?? 'en', props.messages);\nconst editor = createEditor({\n client: createClient({ endpoint: props.endpoint, headers: props.headers, fetch: props.fetch }),\n i18n,\n});\nprovide(editorKey, editor);\n\nconst root = ref<HTMLElement>();\nconst canvas = ref<InstanceType<typeof Canvas>>();\nconst dropPoint = (x: number, y: number) => canvas.value?.dropPoint(x, y) ?? null;\n\n/** Shortcuts work wherever focus is, unless it is inside another part of the host page. */\nfunction onKeyDown(event: KeyboardEvent) {\n const inside = event.composedPath().some((target) => target === root.value);\n const onPage = event.target === document.body || event.target === document.documentElement;\n\n if ((inside || onPage) && editor.state.load.kind === 'ready') {\n handleShortcut(editor, event);\n }\n}\n\n/**\n * Theme fonts in the host document too: the theme dialog previews them in the\n * chrome, and fonts declared inside a shadow root do not load.\n */\nlet fonts: HTMLLinkElement | null = null;\n\nwatchEffect(() => {\n const theme = editor.theme.value;\n\n if (editor.state.load.kind !== 'ready' || typeof document === 'undefined') {\n return;\n }\n\n fonts ??= document.head.appendChild(Object.assign(document.createElement('link'), { rel: 'stylesheet' }));\n fonts.href = fontsHref([theme.heading_font, theme.body_font]);\n});\n\nonMounted(() => {\n if (root.value) {\n adoptEditorStyles(root.value);\n }\n\n window.addEventListener('keydown', onKeyDown);\n void editor.load();\n});\n\nonBeforeUnmount(() => {\n window.removeEventListener('keydown', onKeyDown);\n fonts?.remove();\n editor.dispose();\n});\n</script>\n\n<template>\n <div ref=\"root\" class=\"lze-root\" :lang=\"i18n.locale\">\n <div v-if=\"editor.state.load.kind === 'loading'\" class=\"lze-center\">{{ editor.t('load.loading') }}</div>\n <div v-else-if=\"editor.state.load.kind === 'failed'\" class=\"lze-center\" role=\"alert\">\n <p>{{ editor.t('load.failed', { message: editor.state.load.message }) }}</p>\n <Button @click=\"editor.load()\">{{ editor.t('load.retry') }}</Button>\n </div>\n <div v-else-if=\"editor.state.load.kind === 'empty'\" class=\"lze-center\">\n <Button variant=\"primary\" @click=\"editor.state.dialog = 'newPage'\">{{ editor.t('newPage.title') }}</Button>\n </div>\n <template v-else>\n <Toolbar />\n <div class=\"lze-body\">\n <LeftSidebar :drop-point=\"dropPoint\" />\n <main class=\"lze-main\">\n <Preview v-if=\"editor.state.previewing\" />\n <Canvas v-else ref=\"canvas\" />\n </main>\n <RightPanel />\n </div>\n </template>\n <NewPageDialog />\n <VersionsDialog />\n <ThemeDialog />\n <SiteDialog />\n <SubmissionsDialog />\n <ConflictDialog />\n <MediaLibrary />\n <Toasts />\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport { onBeforeUnmount, onMounted, provide, ref, watchEffect } from 'vue';\nimport Canvas from './canvas/Canvas.vue';\nimport Preview from './canvas/Preview.vue';\nimport { createClient } from './client.ts';\nimport ConflictDialog from './dialogs/ConflictDialog.vue';\nimport MediaLibrary from './dialogs/MediaLibrary.vue';\nimport NewPageDialog from './dialogs/NewPageDialog.vue';\nimport SiteDialog from './dialogs/SiteDialog.vue';\nimport SubmissionsDialog from './dialogs/SubmissionsDialog.vue';\nimport ThemeDialog from './dialogs/ThemeDialog.vue';\nimport VersionsDialog from './dialogs/VersionsDialog.vue';\nimport { createTranslator, type MessageOverrides } from './i18n/index.ts';\nimport { fontsHref } from './model/theme.ts';\nimport LeftSidebar from './shell/LeftSidebar.vue';\nimport RightPanel from './shell/RightPanel.vue';\nimport Toolbar from './shell/Toolbar.vue';\nimport { createEditor, editorKey } from './state/editor.ts';\nimport { handleShortcut } from './state/shortcuts.ts';\nimport { adoptEditorStyles } from './styles/index.ts';\nimport Button from './ui/Button.vue';\nimport Toasts from './ui/Toasts.vue';\n\n/**\n * The Lienzo editor. Give it the protocol `endpoint` of a backend (see\n * `@skylivellc/lienzo-core/protocol`); everything else is optional. Props are\n * read once, when the editor mounts.\n */\n/**\n * Hosts give the element a `style` or classes of their own, as the README\n * asks. Without this, Vue would copy them onto the editor's root, where an\n * inherited `display: block` replaces its grid: the body then grows to the\n * height of its content and the canvas can no longer scroll.\n */\ndefineOptions({ inheritAttrs: false });\n\nconst props = defineProps<{\n /** Base URL of the protocol, for example `/admin/site/lienzo`. */\n endpoint: string;\n /** Language of the editor itself. Defaults to English. */\n locale?: string;\n /** Extra or overriding strings by locale; partial packs fall back to English per key. */\n messages?: MessageOverrides;\n /** Extra request headers, such as a bearer token. Session cookies and Laravel's XSRF token work without any. */\n headers?: Record<string, string>;\n /** A fetch implementation to use instead of the global one. */\n fetch?: typeof fetch;\n}>();\n\nconst i18n = createTranslator(props.locale ?? 'en', props.messages);\nconst editor = createEditor({\n client: createClient({ endpoint: props.endpoint, headers: props.headers, fetch: props.fetch }),\n i18n,\n});\nprovide(editorKey, editor);\n\nconst root = ref<HTMLElement>();\nconst canvas = ref<InstanceType<typeof Canvas>>();\nconst dropPoint = (x: number, y: number) => canvas.value?.dropPoint(x, y) ?? null;\n\n/** Shortcuts work wherever focus is, unless it is inside another part of the host page. */\nfunction onKeyDown(event: KeyboardEvent) {\n const inside = event.composedPath().some((target) => target === root.value);\n const onPage = event.target === document.body || event.target === document.documentElement;\n\n if ((inside || onPage) && editor.state.load.kind === 'ready') {\n handleShortcut(editor, event);\n }\n}\n\n/**\n * Theme fonts in the host document too: the theme dialog previews them in the\n * chrome, and fonts declared inside a shadow root do not load.\n */\nlet fonts: HTMLLinkElement | null = null;\n\nwatchEffect(() => {\n const theme = editor.theme.value;\n\n if (editor.state.load.kind !== 'ready' || typeof document === 'undefined') {\n return;\n }\n\n fonts ??= document.head.appendChild(Object.assign(document.createElement('link'), { rel: 'stylesheet' }));\n fonts.href = fontsHref([theme.heading_font, theme.body_font]);\n});\n\nonMounted(() => {\n if (root.value) {\n adoptEditorStyles(root.value);\n }\n\n window.addEventListener('keydown', onKeyDown);\n void editor.load();\n});\n\nonBeforeUnmount(() => {\n window.removeEventListener('keydown', onKeyDown);\n fonts?.remove();\n editor.dispose();\n});\n</script>\n\n<template>\n <div ref=\"root\" class=\"lze-root\" :lang=\"i18n.locale\">\n <div v-if=\"editor.state.load.kind === 'loading'\" class=\"lze-center\">{{ editor.t('load.loading') }}</div>\n <div v-else-if=\"editor.state.load.kind === 'failed'\" class=\"lze-center\" role=\"alert\">\n <p>{{ editor.t('load.failed', { message: editor.state.load.message }) }}</p>\n <Button @click=\"editor.load()\">{{ editor.t('load.retry') }}</Button>\n </div>\n <div v-else-if=\"editor.state.load.kind === 'empty'\" class=\"lze-center\">\n <Button variant=\"primary\" @click=\"editor.state.dialog = 'newPage'\">{{ editor.t('newPage.title') }}</Button>\n </div>\n <template v-else>\n <Toolbar />\n <div class=\"lze-body\">\n <LeftSidebar :drop-point=\"dropPoint\" />\n <main class=\"lze-main\">\n <Preview v-if=\"editor.state.previewing\" />\n <Canvas v-else ref=\"canvas\" />\n </main>\n <RightPanel />\n </div>\n </template>\n <NewPageDialog />\n <VersionsDialog />\n <ThemeDialog />\n <SiteDialog />\n <SubmissionsDialog />\n <ConflictDialog />\n <MediaLibrary />\n <Toasts />\n </div>\n</template>\n"],"mappings":"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"}