domma-cms 0.96.0 → 0.97.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/admin/css/admin.css +1 -1
- package/admin/js/lib/menu-drag.js +1 -0
- package/admin/js/lib/sidebar-arrange.js +7 -0
- package/admin/js/lib/sidebar-renderer.js +3 -3
- package/admin/js/templates/docs/usage-navigation.html +22 -0
- package/admin/js/views/menu-editor.js +12 -12
- package/package.json +1 -1
package/admin/css/admin.css
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
.dashboard-layout{display:flex;flex-direction:column;height:100vh;min-height:100vh;overflow:hidden}.dashboard-wrapper{display:flex;flex:1;min-height:0;overflow:hidden}.dashboard-main{flex:1;min-width:0;overflow-y:auto}#admin-sidebar.dashboard-sidebar{display:flex;flex-direction:column;flex-shrink:0;overflow:hidden}#admin-sidebar .dm-admin-sidebar{flex:1;min-height:0;overflow-y:auto;overscroll-behavior:contain;scrollbar-width:thin;scrollbar-color:var(--dm-border) transparent}#admin-sidebar .dm-admin-sidebar::-webkit-scrollbar{width:8px}#admin-sidebar .dm-admin-sidebar::-webkit-scrollbar-track{background:transparent}#admin-sidebar .dm-admin-sidebar::-webkit-scrollbar-thumb{background:var(--dm-border);border-radius:4px}#admin-sidebar .dm-admin-sidebar::-webkit-scrollbar-thumb:hover{background:var(--dm-text-muted)}.view-container{padding:1.5rem 2rem;max-width:1200px}.view-container:has(>.dm-plugin-shell){max-width:100%}.view-header{display:flex;align-items:center;justify-content:space-between;margin-bottom:1.5rem;gap:1rem}.view-header h1{font-size:1.5rem;font-weight:700;margin:0;display:flex;align-items:center;gap:.5rem}.view-header-actions{display:flex;gap:.75rem;flex-wrap:wrap}.view-header-actions .btn-primary,.view-header-actions .btn-success,.view-header-actions .btn-danger{margin-left:.5rem}.stat-card .card-body{display:flex;align-items:center;gap:1rem}.stat-icon{width:44px;height:44px;border-radius:8px;background:color-mix(in srgb,var(--dm-primary) 14%,transparent);color:var(--dm-primary, #5b8cff);display:flex;align-items:center;justify-content:center;font-size:1.25rem;flex-shrink:0}.stat-icon--success{background:color-mix(in srgb,var(--dm-success) 15%,transparent);color:var(--dm-success)}.stat-icon--warning{background:color-mix(in srgb,var(--dm-warning) 15%,transparent);color:var(--dm-warning)}.stat-value{font-size:1.75rem;font-weight:700;line-height:1}.stat-label{font-size:.8rem;color:var(--dm-text-muted, #888);margin-top:.25rem}.toolbar{display:flex;align-items:center;gap:.75rem}.form-check-label{display:flex;align-items:center;gap:.5rem;cursor:pointer;font-size:.9rem}.form-hint{display:block;font-size:.8rem;color:var(--dm-text-muted, #888);margin-top:.25rem}.dashboard-main:has(#editor-meta-tabs){overflow:hidden}.view-container:has(#editor-meta-tabs){display:flex;flex-direction:column;height:calc(100dvh - 60px);max-width:100%;padding-bottom:0}.view-container:has(#editor-meta-tabs)>.dm-plugin-shell{flex:1;min-height:0;display:flex;flex-direction:column}.view-container:has(#editor-meta-tabs)>.dm-plugin-shell>.dm-plugin-banner,.view-container:has(#editor-meta-tabs) .pex-bar{flex:none}.view-container:has(#editor-meta-tabs)>.dm-plugin-shell>.dm-plugin-body{flex:1;min-height:0;display:flex;flex-direction:column}.view-container:has(#block-editor-body){max-width:100%}.view-container:has(#ep-editor-tabs){max-width:100%}.ep-editor-grid{display:grid;grid-template-columns:minmax(0,1.25fr) minmax(0,1fr) minmax(0,1.3fr);gap:1rem;align-items:start}.ep-editor-grid>.ep-tryit-col,.ep-editor-grid>.ep-results-col{position:sticky;top:1rem;display:flex;flex-direction:column;gap:1rem;min-width:0}@media(max-width:1500px){.ep-editor-grid{grid-template-columns:minmax(0,1fr) minmax(0,1fr)}.ep-editor-grid>:first-child{grid-column:1 / -1}.ep-editor-grid>.ep-tryit-col,.ep-editor-grid>.ep-results-col{position:static}}@media(max-width:1024px){.ep-editor-grid{grid-template-columns:minmax(0,1fr)}}#editor-meta-tabs{flex:1;min-height:0;display:flex;flex-direction:column}#editor-meta-tabs .tab-content{flex:1;min-height:0;overflow:hidden}#editor-meta-tabs .tab-panel{height:100%;overflow-y:auto}#editor-meta-tabs .tab-panel:has(.editor-card),#live-preview-panel{overflow:hidden}.live-preview-bar{display:flex;align-items:center;gap:var(--dm-space-4);flex-wrap:wrap;padding:var(--dm-space-2) 0;border-bottom:1px solid var(--dm-border);margin-bottom:var(--dm-space-2)}.live-preview-widths{display:inline-flex;border:1px solid var(--dm-border);border-radius:var(--dm-radius-sm);overflow:hidden}.live-preview-width{display:inline-flex;align-items:center;justify-content:center;padding:.3rem .55rem;border:none;background:transparent;color:inherit;cursor:pointer;line-height:1}.live-preview-width+.live-preview-width{border-left:1px solid var(--dm-border)}.live-preview-width:hover{background:var(--dm-hover-bg)}.live-preview-width.active{background:var(--dm-active-bg)}.live-preview-status{flex:1 1 auto;font-size:.8rem;opacity:.75}.live-preview-actions{display:flex;gap:var(--dm-space-1)}.live-preview-wrap{display:flex;flex-direction:column;height:100%;min-height:0}.live-preview-wrap>.live-preview-bar{flex:none}.live-preview-stage{display:flex;justify-content:center;flex:1;min-height:0;overflow:auto;background:var(--dm-background-alt);border-radius:var(--dm-radius-md)}.page-live-preview-frame{display:block;width:100%;max-width:100%;height:100%;border:none;border-radius:6px;background:var(--dm-background);transition:max-width .18s ease}.page-live-preview-frame[data-width="1024"]{max-width:1024px}.page-live-preview-frame[data-width="390"]{max-width:390px}.page-live-preview-frame[data-width="1024"],.page-live-preview-frame[data-width="390"]{border-left:1px solid var(--dm-border);border-right:1px solid var(--dm-border)}.editor-card{display:flex;flex-direction:column;height:100%}.editor-card .card-body{display:flex;flex-direction:column;flex:1;min-height:0;padding:0!important}.editor-toolbar{display:flex;align-items:center;gap:2px;padding:6px 10px;border-bottom:1px solid var(--dm-border, rgba(255, 255, 255, .08));flex-wrap:wrap;flex-shrink:0}.editor-toolbar-btn{background:none;border:none;color:var(--dm-text-muted, #888);padding:6px 8px;border-radius:4px;cursor:pointer;display:flex;align-items:center;transition:color .15s,background .15s}.editor-toolbar-btn:hover{color:var(--dm-text, #eee);background:var(--dm-hover-bg)}.editor-toolbar-sep{width:1px;height:20px;background:var(--dm-border, rgba(255, 255, 255, .08));margin:0 4px;flex-shrink:0}.editor-toolbar-right{margin-left:auto;display:flex;align-items:center;gap:2px}.editor-view-btn{background:none;border:none;color:var(--dm-text-muted, #888);padding:6px 8px;border-radius:4px;cursor:pointer;display:flex;align-items:center;transition:color .15s,background .15s}.editor-view-btn:hover{color:var(--dm-text, #eee);background:var(--dm-hover-bg)}.editor-view-btn.active{color:var(--dm-primary, #5b8cff);background:color-mix(in srgb,var(--dm-primary) 14%,transparent)}.editor-body{display:flex;flex:1;min-height:0;--dm-editor-split: 50%}@media(min-width:769px){.editor-body:not(.editor-mode-write):not(.editor-mode-preview) .editor-pane--write{flex:0 0 var(--dm-editor-split, 50%)}.editor-body:not(.editor-mode-write):not(.editor-mode-preview) .editor-pane--preview{flex:1 1 0}}.editor-pane{flex:1;display:flex;flex-direction:column;min-width:0}.editor-pane--write,.editor-pane--preview{overflow:hidden}.editor-pane--write{flex-direction:row}.editor-line-numbers{padding:1rem .6rem 1rem .75rem;background:var(--dm-background-alt, rgba(0, 0, 0, .15));border-right:1px solid var(--dm-border, rgba(255, 255, 255, .08));color:var(--dm-text-muted, #666);font-family:Fira Code,Courier New,monospace;font-size:.9rem;line-height:1.6;text-align:right;user-select:none;white-space:pre;overflow:hidden;flex-shrink:0;min-width:2.5rem}.editor-line-numbers--foldable{padding:1rem 0;min-width:3rem;white-space:normal;text-align:left;display:flex;flex-direction:column}.editor-line-number-row{display:flex;align-items:center;justify-content:flex-end;padding-right:.6rem;gap:.15rem}.fold-toggle{display:inline-flex;align-items:center;justify-content:center;width:1em;font-size:.6rem;cursor:default;color:transparent}.fold-toggle--open,.fold-toggle--folded{cursor:pointer;color:var(--dm-text-muted, #666);transition:color .1s}.fold-toggle--open:hover,.fold-toggle--folded:hover{color:var(--dm-primary, #4a9eff)}.editor-line-num{min-width:1.5rem;text-align:right}.editor-mode-write .editor-pane--preview,.editor-mode-write .editor-divider,.editor-mode-preview .editor-pane--write,.editor-mode-preview .editor-divider{display:none}.editor-divider{width:7px;background:linear-gradient(to right,transparent 0,transparent 3px,var(--dm-border, rgba(255,255,255,.08)) 3px,var(--dm-border, rgba(255,255,255,.08)) 4px,transparent 4px,transparent 100%);cursor:col-resize;flex-shrink:0;touch-action:none;transition:background .12s ease}.editor-divider:hover,.editor-divider:focus-visible,.editor-divider.is-dragging{background:linear-gradient(to right,transparent 0,transparent 2px,var(--dm-primary, #5b8cff) 2px,var(--dm-primary, #5b8cff) 5px,transparent 5px,transparent 100%);outline:none}.editor-body.is-resizing .editor-pane{pointer-events:none}.editor-body.is-resizing{cursor:col-resize;user-select:none}.editor-textarea{flex:1;resize:none;border:none;border-radius:0;background:transparent;font-family:Fira Code,Courier New,monospace;font-size:.9rem;padding:1rem;outline:none;color:inherit;line-height:1.6}#editor-body .editor-textarea,#editor-body .editor-line-numbers{font-family:var(--pe-font, "Fira Code", "Courier New", monospace);font-size:var(--pe-size, .9rem);line-height:var(--pe-line, 1.6)}#editor-body.pe-nowrap .editor-textarea{white-space:pre;overflow-x:auto}.editor-preview{flex:1;display:block;width:100%;border:none;background:var(--dm-background)}.editor-fullscreen{position:fixed;inset:0;z-index:1000;border-radius:0;margin:0}.editor-fullscreen .card-body{height:100vh}.media-picker-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(120px,1fr));gap:.75rem;max-height:400px;overflow-y:auto;padding:.25rem}.media-picker-item{cursor:pointer;border:2px solid transparent;border-radius:6px;overflow:hidden;transition:border-color .15s}.media-picker-item:hover{border-color:var(--dm-primary, #5b8cff)}.media-picker-item img{width:100%;height:80px;object-fit:cover;display:block}.media-picker-item span{display:block;font-size:.75rem;padding:4px 6px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.docs-body h3{margin-top:1.25rem;margin-bottom:.5rem}.docs-body p{margin-bottom:.5rem;line-height:1.6}.docs-body ol,.docs-body ul{margin-bottom:.75rem;padding-left:1.25rem}.docs-body li{margin-bottom:.25rem}.docs-body hr{margin:1.25rem 0;border-color:var(--dm-border, rgba(255, 255, 255, .08))}.docs-body .table{margin-bottom:.75rem}.docs-body h2{margin-top:1.75rem;margin-bottom:.6rem;padding-bottom:.3rem;border-bottom:1px solid var(--dm-border)}.docs-body h2:first-child{margin-top:0}.docs-body blockquote{margin:.75rem 0;padding:.5rem .9rem;border-left:3px solid var(--dm-primary);background:var(--dm-surface);border-radius:var(--dm-radius, 6px)}.docs-body pre{margin-bottom:.75rem;overflow-x:auto}.pg-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(260px,1fr));gap:1rem;margin-top:1.5rem}.pg-grid>.card.pg-card{display:block;margin:0;text-decoration:none}.pg-card h3{margin-top:0}.pg-card .text-muted,.pg-card-pages{margin-bottom:0}.pg-card-pages{margin-top:.5rem;font-size:.8rem;color:var(--dm-text-muted)}.pg-actions{display:flex;gap:.5rem;flex-wrap:wrap}.pg-meta{margin-bottom:.75rem}.pg-pages{display:flex;flex-wrap:wrap;gap:.35rem;margin-bottom:1rem}.pg-body{max-width:80ch}.nav-items-header,.nav-item-row{display:flex;gap:.5rem;align-items:center;padding:.35rem .75rem}.nav-items-header{border-bottom:1px solid var(--dm-border, rgba(255,255,255,.08));padding-bottom:.4rem;margin-bottom:.25rem}.nav-item-row{border-bottom:1px solid var(--dm-border, rgba(255,255,255,.04))}.nav-item-row:last-child{border-bottom:none}.nav-col-indent{width:18px;flex-shrink:0;color:var(--dm-text-muted, #888);text-align:center;font-size:.85rem}.nav-col-main{flex:2;min-width:0}.nav-col-icon{flex:0 0 90px}.nav-col-parent{flex:2;min-width:0}.nav-col-action{flex-shrink:0}.nav-item-row--child{background:color-mix(in srgb,var(--dm-text) 3%,transparent)}.nav-col-action{display:flex;align-items:center;gap:.25rem}.nav-item-row--hidden{opacity:.45}.nav-item-row--hidden .item-text,.nav-item-row--hidden .footer-link-text{text-decoration:line-through}.btn-toggle-hidden{color:var(--dm-text-muted, #888)}.btn-toggle-hidden.active{color:var(--dm-warning, #f59e0b)}.fb-field-card.fb-drag-over{outline:2px dashed var(--dm-primary, #6366f1);outline-offset:-2px}.btn-ghost span[data-icon=trash]{color:var(--dm-danger, #dc2626)}.view-container:has(.fb-fields-layout){max-width:none}.fb-fields-layout{display:grid;grid-template-columns:minmax(0,6fr) minmax(320px,4fr);gap:1.25rem;align-items:start}.fb-preview-pane{position:sticky;top:1rem;min-width:0}@media(max-width:1100px){.fb-fields-layout{grid-template-columns:1fr}.fb-preview-pane{position:static}}.toggle-label{display:flex;align-items:center;gap:.4rem;font-size:.9rem;cursor:pointer;margin-right:1rem}.preset-toggles{display:flex;flex-wrap:wrap;margin-top:.75rem}.presets-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:1rem}@media(max-width:900px){.presets-grid{grid-template-columns:repeat(2,1fr)}}@media(max-width:600px){.presets-grid{grid-template-columns:1fr}}.card-header{padding:.5rem 1rem}.card-header h2{margin:0;font-size:.9rem;font-weight:600;letter-spacing:.02em}.preset-card .card-header{display:flex;align-items:center;justify-content:space-between}.preset-card .card-header h3{margin:0;font-size:1rem}.media-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(180px,1fr));gap:1rem}.media-card{background:var(--dm-card-bg, rgba(255,255,255,.04));border:1px solid var(--dm-border, rgba(255,255,255,.08));border-radius:8px;overflow:hidden}.media-preview{height:130px;display:flex;align-items:center;justify-content:center;background:#0003;overflow:hidden}.media-thumb{width:100%;height:100%;object-fit:cover}.media-thumb--file{font-size:2rem;color:var(--dm-text-muted, #888)}.media-info{padding:.5rem .75rem;display:flex;flex-direction:column;gap:.15rem}.media-name{font-size:.8rem;font-weight:500;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;cursor:default}.media-rename-input{width:100%;font-size:.8rem;font-weight:500;padding:.1rem .25rem;border:1px solid var(--dm-primary, #7c6af7);border-radius:3px;background:var(--dm-input-bg, transparent);color:inherit;outline:none}.media-size{font-size:.75rem;color:var(--dm-text-muted, #888)}.media-actions{padding:.5rem .75rem;display:flex;gap:.4rem;border-top:1px solid var(--dm-border, rgba(255,255,255,.08))}#admin-topbar{height:60px;display:flex;align-items:center;gap:1rem;padding:0 1.25rem;background:var(--dm-navbar-bg, rgba(0,0,0,.3));border-bottom:1px solid var(--dm-border, rgba(255,255,255,.08));position:sticky;top:0;z-index:200;flex-shrink:0}.topbar-brand{display:flex;align-items:center;gap:.5rem;font-weight:700;font-size:.95rem;color:inherit;flex-shrink:0;margin-right:.5rem}.topbar-brand span[data-icon],.topbar-brand svg{color:var(--dm-primary, #5b8cff);width:22px;height:22px}.topbar-brand-text{opacity:.85}.topbar-brand-logo{height:28px;width:auto;display:inline-block;vertical-align:middle;margin-right:.4em;object-fit:contain}.topbar-user{display:flex;align-items:center;gap:.6rem;flex:1}.topbar-user-name{font-size:.875rem;font-weight:500}.topbar-avatar{width:1.75rem;height:1.75rem;border-radius:50%;object-fit:cover;flex-shrink:0}.topbar-role-badge{font-size:.7rem;font-weight:600;letter-spacing:.04em;text-transform:uppercase;padding:.15rem .45rem;border-radius:4px}.topbar-role-badge--admin{background:color-mix(in srgb,var(--dm-primary) 15%,transparent);color:var(--dm-primary)}.topbar-role-badge--manager{background:color-mix(in srgb,var(--dm-success) 15%,transparent);color:var(--dm-success)}.topbar-role-badge--editor{background:color-mix(in srgb,var(--dm-warning) 15%,transparent);color:var(--dm-warning)}.topbar-role-badge--subscriber{background:color-mix(in srgb,var(--dm-text-muted) 15%,transparent);color:var(--dm-text-muted)}.topbar-actions{display:flex;align-items:center;gap:.5rem;flex-shrink:0}.topbar-action-link{display:flex;align-items:center;gap:.35rem;font-size:.875rem;color:var(--dm-text-muted, #888);text-decoration:none;padding:.4rem .65rem;border-radius:6px;transition:color .15s,background .15s}.topbar-action-link:hover{color:var(--dm-text, #eee);background:var(--dm-hover-bg)}.topbar-action-link span[data-icon],.topbar-action-link svg{width:16px;height:16px}.topbar-signout{display:flex;align-items:center;gap:.35rem;font-size:.875rem}.topbar-signout span[data-icon],.topbar-signout svg{width:16px;height:16px}.login-wrap{position:fixed;inset:0;display:flex;align-items:center;justify-content:center;padding:1rem;background:var(--dm-background, #0f1117);z-index:100;overflow-y:auto}.login-card{width:100%;max-width:460px}.ob-done-icon{font-size:3rem;color:var(--dm-success);margin-bottom:1rem;text-align:center}.btn-skip{display:block;text-align:center;margin-top:.75rem;font-size:.85rem;color:var(--dm-text-muted, #888);text-decoration:none}.btn-skip:hover{text-decoration:underline}.theme-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:.6rem}.theme-swatch{border:2px solid var(--dm-border, rgba(255,255,255,.1));border-radius:8px;overflow:hidden;cursor:pointer;transition:border-color .15s,transform .1s}.theme-swatch:hover{border-color:var(--dm-primary, #5b8cff);transform:translateY(-1px)}.theme-swatch.selected{border-color:var(--dm-primary, #5b8cff);box-shadow:0 0 0 2px var(--dm-primary, #5b8cff)}.theme-swatch-preview{height:52px;position:relative;display:flex;align-items:flex-end;padding:.35rem}.theme-swatch-accent{width:28px;height:6px;border-radius:3px}.theme-swatch-label{display:flex;justify-content:space-between;align-items:center;padding:.3rem .45rem;font-size:.7rem;background:var(--dm-card-bg, rgba(255,255,255,.04))}.theme-swatch-mode{color:var(--dm-text-muted, #888);font-size:.65rem}.login-logo{display:flex;align-items:center;gap:.75rem;margin-bottom:1.75rem;font-size:1.5rem}.login-logo span[data-icon]{font-size:2rem;color:var(--dm-primary, #5b8cff)}.login-logo h1{margin:0;font-size:1.5rem;font-weight:700}.login-card [hidden]{display:none!important}.login-heading{font-size:1.1rem;font-weight:600;margin-bottom:1.25rem}.login-rules{margin:.25rem 0 .75rem;padding-left:1.1rem;color:var(--dm-danger);font-size:.85rem}.login-rules li+li{margin-top:.2rem}.login-small{font-size:.8rem;margin-top:.75rem}.login-icon-warn{color:var(--dm-warning)}.pwf{position:relative;display:block}.pwf>input{width:100%;padding-right:2.5rem}.pwf-toggle{position:absolute;top:50%;right:.35rem;transform:translateY(-50%);display:inline-flex;align-items:center;justify-content:center;width:2rem;height:2rem;padding:0;border:0;border-radius:var(--dm-radius-sm);background:transparent;color:var(--dm-text-muted);cursor:pointer}.pwf-toggle:hover,.pwf-toggle:focus-visible{color:var(--dm-text);background:var(--dm-hover-bg)}.pwf-toggle svg{width:16px;height:16px}.pwf-toggle [data-icon=eye-off],.pwf.is-shown .pwf-toggle [data-icon=eye]{display:none}.pwf.is-shown .pwf-toggle [data-icon=eye-off]{display:inline-block}.pwf-caps{display:block;margin-top:.25rem;color:var(--dm-warning);font-size:.8rem}.pwf-caps[hidden]{display:none}.btn-block{width:100%}.plugins-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(300px,1fr));gap:1rem}.plugin-card{display:flex;flex-direction:column;--plugin-accent: var(--dm-primary, #5b8cff);position:relative;overflow:hidden;background-image:radial-gradient(120% 90% at 100% 0%,color-mix(in srgb,var(--plugin-accent) 13%,transparent) 0%,color-mix(in srgb,var(--plugin-accent) 4%,transparent) 42%,transparent 72%)}.plugin-card .plugin-icon{background:color-mix(in srgb,var(--plugin-accent) 16%,transparent);color:var(--plugin-accent)}.plugin-watermark{position:absolute;top:-34px;right:-30px;width:148px;height:148px;display:block;color:var(--plugin-accent);opacity:.09;pointer-events:none;z-index:0}.plugin-card>.card-body,.plugin-card>.plugin-footer{position:relative;z-index:1}.plugin-card:has(.badge-secondary) .plugin-watermark{opacity:.05}@media(prefers-reduced-motion:no-preference){.plugin-card{transition:background-image .2s ease}}.plugin-card .card-body{flex:1}.plugin-header{display:flex;align-items:flex-start;gap:.75rem;margin-bottom:.75rem;flex-wrap:wrap}.plugin-icon{width:40px;height:40px;border-radius:8px;background:color-mix(in srgb,var(--dm-primary) 14%,transparent);color:var(--dm-primary, #5b8cff);display:flex;align-items:center;justify-content:center;flex-shrink:0}.plugin-meta{flex:1 1 140px;min-width:0}.plugin-name{font-weight:600;margin-bottom:.15rem}.plugin-version{font-size:.75rem;color:var(--dm-text-muted, #888)}.plugin-desc{font-size:.875rem;color:var(--dm-text-muted, #888);margin-bottom:1rem}.plugin-footer{display:flex;align-items:center;justify-content:space-between;padding:.75rem 1rem;border-top:1px solid var(--dm-border, rgba(255,255,255,.08))}.plugin-footer-actions{display:flex;align-items:center;gap:.5rem}#admin-sidebar .sidebar-link{position:relative!important}#admin-sidebar .sidebar-badge{position:absolute!important;right:.75rem!important;top:50%!important;transform:translateY(-50%)!important;margin-left:0!important;padding-left:.45rem!important;padding-right:.45rem!important}#admin-sidebar .sidebar-text{padding-right:2rem!important}#admin-sidebar.sidebar-dark{background:var(--dm-surface);border-color:var(--dm-border)}#admin-sidebar.sidebar-dark .sidebar-header{background:var(--dm-surface-raised);border-color:var(--dm-border)}#admin-sidebar.sidebar-dark .sidebar-header-title{color:var(--dm-text)}#admin-sidebar.sidebar-dark .sidebar-link{color:var(--dm-text-muted)}#admin-sidebar.sidebar-dark .sidebar-link:hover{color:var(--dm-text);background:var(--dm-surface-overlay)}#admin-sidebar.sidebar-dark .sidebar-link.active{color:var(--dm-primary);background:color-mix(in srgb,var(--dm-primary) 14%,transparent);border-left-color:var(--dm-primary)}#admin-sidebar.sidebar-dark .sidebar-heading{color:var(--dm-text-muted)}#admin-sidebar.sidebar-dark .sidebar-divider{background:var(--dm-border)}#admin-sidebar.sidebar-dark .sidebar-footer{background:var(--dm-surface-raised);border-color:var(--dm-border)}.sidebar-heading--collapsible{display:flex!important;align-items:center;justify-content:space-between;cursor:pointer;user-select:none}.sidebar-heading-toggle{display:flex;align-items:center;opacity:.5;flex-shrink:0;transition:transform .2s ease}.sidebar-heading--collapsible.is-collapsed .sidebar-heading-toggle{transform:rotate(-90deg)}.mt-3{margin-top:.75rem}.mt-4{margin-top:1rem}.mb-2{margin-bottom:.5rem}.mb-3{margin-bottom:.75rem}.mb-4{margin-bottom:1rem}.p-0{padding:0!important}.text-muted{color:var(--dm-text-muted, #888)}@media(max-width:768px){.view-container{padding:1rem}.editor-body{flex-direction:column}.editor-divider{width:auto;height:1px;cursor:default;background:var(--dm-border, rgba(255,255,255,.08))}}.image-editor{display:flex;flex-direction:column;gap:0}.image-editor-toolbar{display:flex;flex-direction:row;align-items:center;gap:.25rem;padding:.5rem .75rem;border-bottom:1px solid var(--dm-border, rgba(255, 255, 255, .1))}.image-editor-sep{display:inline-block;width:1px;height:1.5rem;background:var(--dm-border, rgba(255, 255, 255, .15));margin:0 .25rem;flex-shrink:0}.editor-toolbar-btn.active{color:var(--dm-primary, #7c6af7);background:color-mix(in srgb,var(--dm-primary, #7c6af7) 15%,transparent)}.editor-toolbar-caret{font-size:.6rem;line-height:1;margin-left:2px;opacity:.6}.editor-toolbar-dropdown{position:absolute;z-index:1000;background:var(--dm-surface, #1e1e2e);border:1px solid var(--dm-border, rgba(255, 255, 255, .1));border-radius:8px;box-shadow:0 8px 24px #0006;padding:4px;min-width:160px;max-height:70vh;overflow-y:auto}.editor-toolbar-dropdown-heading{padding:6px 10px 3px;color:var(--dm-text-muted, #8a8a9a);font-size:.66rem;text-transform:uppercase;letter-spacing:.06em}.editor-toolbar-dropdown-item{display:flex;align-items:center;gap:8px;width:100%;text-align:left;background:none;border:none;color:var(--dm-text, #ddd);padding:7px 10px;border-radius:5px;cursor:pointer;font-size:.85rem;transition:background .12s,color .12s}.editor-toolbar-dropdown-item:hover{background:var(--dm-hover-bg);color:var(--dm-text, #fff)}.editor-toolbar-dropdown-item span[data-icon],.editor-toolbar-dropdown-item svg{width:15px;height:15px;flex-shrink:0;opacity:.75}.editor-toolbar{position:relative}.editor-effects-dropdown-menu{position:absolute;top:100%;z-index:1000;background:var(--dm-surface, #1e1e2e);border:1px solid var(--dm-border, rgba(255, 255, 255, .1));border-radius:8px;box-shadow:0 8px 24px #0006;padding:6px;min-width:180px;max-height:340px;overflow-y:auto}.editor-effects-category{padding:6px 8px 3px;font-size:.7rem;font-weight:700;letter-spacing:.07em;text-transform:uppercase;color:var(--dm-text-muted, #888)}.editor-effects-item{display:block;width:100%;text-align:left;background:none;border:none;color:var(--dm-text, #ddd);padding:6px 10px;border-radius:5px;cursor:pointer;font-size:.85rem;transition:background .12s,color .12s}.editor-effects-item:hover{background:var(--dm-hover-bg);color:var(--dm-text, #fff)}.editor-icon-picker{position:absolute;z-index:1000;background:var(--dm-surface, #1e1e2e);border:1px solid var(--dm-border, rgba(255, 255, 255, .1));border-radius:8px;box-shadow:0 8px 24px #0006;padding:8px;width:320px}.editor-icon-picker-search{width:100%;margin-bottom:8px;font-size:.8rem}.editor-spacer-picker{position:absolute;z-index:9999;background:var(--dm-surface, #1e1e2e);border:1px solid var(--dm-border, #333);border-radius:8px;padding:12px;width:240px;box-shadow:0 8px 24px #00000073}.editor-spacer-picker-label{font-size:11px;font-weight:600;text-transform:uppercase;letter-spacing:.05em;color:var(--dm-text-muted, #888);margin-bottom:10px}.editor-spacer-picker-row{display:flex;align-items:center;gap:10px;margin-bottom:12px}.editor-spacer-slider{flex:1;accent-color:var(--dm-primary, #6366f1);cursor:pointer}.editor-spacer-slider-value{font-size:13px;font-weight:600;min-width:38px;text-align:right;color:var(--dm-text, #cdd6f4)}.editor-spacer-insert-btn{width:100%}.editor-icon-picker-size-row{display:flex;align-items:center;gap:8px;padding:0 8px 8px}.editor-icon-picker-size-row label{font-size:11px;color:var(--dm-text-muted, #888);white-space:nowrap}.editor-icon-picker-size{width:70px;font-size:12px;padding:3px 6px}.editor-icon-picker-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(52px,1fr));gap:2px;max-height:280px;overflow-y:auto}.editor-icon-picker-item{display:flex;flex-direction:column;align-items:center;justify-content:center;padding:6px 2px;border-radius:5px;cursor:pointer;background:none;border:none;color:var(--dm-text, #ddd);font-size:.58rem;text-align:center;gap:4px;overflow:hidden;transition:background .12s,color .12s}.editor-icon-picker-item:hover{background:var(--dm-hover-bg);color:var(--dm-text, #fff)}.editor-icon-picker-item span[data-icon],.editor-icon-picker-item svg{width:16px;height:16px;flex-shrink:0}.editor-icon-picker-item>span:last-child{max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;line-height:1.2}.editor-icon-picker-empty{grid-column:1 / -1;text-align:center;color:var(--dm-text-muted, #888);font-size:.8rem;padding:1.5rem}.image-editor-canvas{min-height:320px;max-height:520px;background:#111;overflow:hidden;display:flex;align-items:center;justify-content:center}.image-editor-canvas img{display:block;max-width:100%;max-height:520px}.image-editor-resize{display:flex;flex-direction:row;align-items:center;gap:.5rem;padding:.6rem .75rem;border-top:1px solid var(--dm-border, rgba(255, 255, 255, .1));font-size:.85rem}.image-editor-resize label{font-weight:600;color:var(--dm-text-muted, #888);font-size:.8rem}.image-editor-resize .form-input{width:5rem;padding:.25rem .5rem;font-size:.85rem}.image-editor-footer{display:flex;flex-direction:row;align-items:center;justify-content:space-between;padding:.75rem;border-top:1px solid var(--dm-border, rgba(255, 255, 255, .1));gap:.5rem}.image-editor-effects{border-top:1px solid var(--dm-border, rgba(255, 255, 255, .1))}.image-editor-tab-bar{display:flex;flex-direction:row;overflow-x:auto;border-bottom:1px solid var(--dm-border, rgba(255, 255, 255, .1));scrollbar-width:none}.image-editor-tab-bar::-webkit-scrollbar{display:none}.image-editor-tab-btn{display:inline-flex;align-items:center;gap:.35rem;padding:.5rem .85rem;font-size:.8rem;font-weight:500;border:none;border-bottom:2px solid transparent;background:transparent;cursor:pointer;color:var(--dm-text-muted, #888);white-space:nowrap;transition:color .15s,border-color .15s;flex-shrink:0}.image-editor-tab-btn:hover{color:var(--dm-text, #eee)}.image-editor-tab-btn.active{color:var(--dm-primary, #7c6af7);border-bottom-color:var(--dm-primary, #7c6af7)}.image-editor-tab-panel{padding:.75rem;max-height:200px;overflow-y:auto}.ie-presets-grid{display:flex;flex-wrap:wrap;gap:.35rem;margin-bottom:.5rem}.ie-preset-btn.active{color:var(--dm-primary, #7c6af7);background:color-mix(in srgb,var(--dm-primary, #7c6af7) 15%,transparent);border-color:var(--dm-primary, #7c6af7)}.ie-server-note{font-size:.73rem;color:var(--dm-text-muted, #888);font-style:italic;margin:.25rem 0 0;line-height:1.4}.ie-slider-row{display:flex;align-items:center;gap:.5rem;margin-bottom:.4rem}.ie-slider-label{width:6rem;font-size:.8rem;color:var(--dm-text-muted, #888);font-weight:600;flex-shrink:0}.ie-slider{flex:1;accent-color:var(--dm-primary, #7c6af7);cursor:pointer}.ie-slider-val{width:3rem;font-size:.8rem;text-align:right;color:var(--dm-text, #eee);flex-shrink:0}.ie-select{flex:1;font-size:.85rem;padding:.25rem .5rem}.ie-colour-input{width:40px;height:28px;padding:0;border:1px solid var(--dm-border, rgba(255, 255, 255, .15));border-radius:4px;cursor:pointer;background:transparent;flex-shrink:0}.ie-wm-preview-row{display:flex;align-items:center;gap:.5rem;margin:.4rem 0}.ie-wm-preview-img{width:48px;height:48px;object-fit:contain;border-radius:4px;background:var(--dm-surface-raised, rgba(255, 255, 255, .06));flex-shrink:0}.ie-wm-preview-name{font-size:.8rem;flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--dm-text, #eee)}.ie-media-picker{padding:.25rem 0}.ie-media-picker-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(80px,1fr));gap:.5rem;max-height:300px;overflow-y:auto}.ie-media-thumb{display:flex;flex-direction:column;align-items:center;gap:.25rem;padding:.4rem;border-radius:6px;cursor:pointer;border:2px solid transparent;transition:border-color .15s,background .15s}.ie-media-thumb:hover{background:var(--dm-surface-raised, rgba(255, 255, 255, .08));border-color:var(--dm-primary, #7c6af7)}.ie-media-thumb img{width:72px;height:72px;object-fit:cover;border-radius:4px}.ie-media-thumb-name{font-size:.7rem;color:var(--dm-text-muted, #888);text-align:center;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:72px}.dm-slideover-left,.dm-slideover-right{width:min(40rem,95vw)!important;min-width:min(36rem,100vw)!important;max-width:100vw!important}.dm-slideover-resizer{position:absolute;top:0;bottom:0;width:6px;cursor:col-resize;z-index:2;background:transparent}.dm-slideover-right>.dm-slideover-resizer{left:0}.dm-slideover-left>.dm-slideover-resizer{right:0}.dm-slideover-resizer:hover,.is-resizing>.dm-slideover-resizer{background:var(--dm-primary);opacity:.7}.dm-slideover.is-resizing{user-select:none;transition:none!important}.dm-slideover-header{display:flex;align-items:center;justify-content:space-between;padding:1rem 1.25rem;border-bottom:1px solid var(--dm-border, #333);flex-shrink:0}.dm-slideover-title{margin:0;font-size:1rem;font-weight:600}.dm-slideover-close{padding:.2rem .35rem!important;line-height:1;font-size:.75rem}.dm-slideover-body{flex:1;overflow:auto;overscroll-behavior:contain;min-height:0;padding:1.5rem!important;box-sizing:border-box}.dm-slideover-body:empty{flex:0 0 auto;padding:0!important}.dm-slideover>div:not(.dm-slideover-header):not(.dm-slideover-body):not(.dm-slideover-close){padding:1.5rem!important;box-sizing:border-box;flex:1 1 auto;min-height:0;overflow:auto;overscroll-behavior:contain}.dm-slideover-body,.dm-slideover>div:not(.dm-slideover-header):not(.dm-slideover-close){scrollbar-width:thin;scrollbar-color:var(--dm-border) transparent}.dm-slideover-body::-webkit-scrollbar,.dm-slideover>div:not(.dm-slideover-header):not(.dm-slideover-close)::-webkit-scrollbar{width:8px;height:8px}.dm-slideover-body::-webkit-scrollbar-track,.dm-slideover>div:not(.dm-slideover-header):not(.dm-slideover-close)::-webkit-scrollbar-track{background:transparent}.dm-slideover-body::-webkit-scrollbar-thumb,.dm-slideover>div:not(.dm-slideover-header):not(.dm-slideover-close)::-webkit-scrollbar-thumb{background:var(--dm-border);border-radius:4px}.dm-slideover-body::-webkit-scrollbar-thumb:hover,.dm-slideover>div:not(.dm-slideover-header):not(.dm-slideover-close)::-webkit-scrollbar-thumb:hover{background:var(--dm-text-muted)}.dm-slideover-body>div{padding-left:0!important;padding-right:0!important}.dm-slideover-body>button.btn:last-child{margin-top:.5rem}.dconfig-textarea{font-family:monospace;min-height:100px;resize:vertical}.dm-editor-line-numbers{white-space:pre}.dm-code-inline{font-family:Fira Code,Courier New,monospace;font-size:.82em;padding:.15em .35em;border-radius:3px;background:var(--dm-background-alt, rgba(0, 0, 0, .18));color:var(--dm-text, inherit);border:1px solid var(--dm-border, rgba(255, 255, 255, .08))}.dm-code-block{font-family:Fira Code,Courier New,monospace;font-size:.82rem;line-height:1.6;padding:.65rem .9rem;border-radius:6px;background:var(--dm-background-alt, rgba(0, 0, 0, .18));color:var(--dm-text, inherit);border:1px solid var(--dm-border, rgba(255, 255, 255, .08));white-space:pre;overflow-x:auto;display:block;margin:.4rem 0}.tabs-centered{text-align:center}.tabs-centered .tab-list{display:inline-flex}.tabs-centered .tab-content{text-align:left}@media(max-width:768px){.view-header{flex-direction:column;align-items:flex-start}.theme-grid{grid-template-columns:repeat(2,1fr)}.nav-item-row{flex-wrap:wrap}.nav-col-icon,.nav-col-parent{display:none}#admin-topbar{padding:0 .75rem}.topbar-brand-text{display:none}.image-editor-toolbar{flex-wrap:wrap}}#topbar-bell{position:relative}.topbar-action-link[hidden],.topbar-bell-badge[hidden]{display:none}.topbar-bell-badge{position:absolute;top:2px;right:2px;min-width:16px;height:16px;padding:0 4px;background:var(--dm-danger, #dc2626);color:var(--dm-danger-text, #fff);font-size:10px;font-weight:700;line-height:16px;border-radius:9999px;text-align:center;pointer-events:none}.cb-scaffolder{padding:1rem 1.1rem;background:var(--dm-background-alt);border:1px solid var(--dm-primary);border-radius:8px;color:var(--dm-text)}.cb-scaffolder-head{display:flex;align-items:center;gap:.5rem;margin-bottom:.5rem}.cb-scaffolder-head .cb-icon{flex-shrink:0;color:var(--dm-primary)}.cb-scaffolder-head h2{margin:0;font-size:1.05rem;font-weight:700;color:var(--dm-text)}.cb-scaffolder-blurb{margin:0 0 .75rem;font-size:.88rem;line-height:1.5;color:var(--dm-text-muted)}.cb-recipe-list{display:flex;flex-direction:column;gap:.5rem}.cb-recipe-card{display:flex;align-items:flex-start;gap:.75rem;text-align:left;padding:.75rem 1rem;background:var(--dm-surface);border:1px solid var(--dm-border);border-radius:6px;cursor:pointer;transition:border-color .12s;width:100%;color:var(--dm-text)}.cb-recipe-card:hover{border-color:var(--dm-primary)}.cb-recipe-card .cb-icon{flex-shrink:0;font-size:1.5rem;color:var(--dm-primary);margin-top:.1rem}.cb-recipe-meta{flex:1}.cb-recipe-name{font-weight:600;margin-bottom:.15rem;font-size:.95rem;color:var(--dm-text)}.cb-recipe-desc{font-size:.83rem;line-height:1.45;color:var(--dm-text-muted)}.cb-apply-panel{padding:1rem 1.1rem;background:var(--dm-surface);border:1px solid var(--dm-primary);border-radius:8px;color:var(--dm-text)}.cb-apply-head{display:flex;align-items:center;gap:.5rem;margin-bottom:.5rem}.cb-apply-head .cb-icon{color:var(--dm-primary);font-size:1.4rem}.cb-apply-head h3{margin:0;font-size:1rem;font-weight:600;color:var(--dm-text)}.cb-apply-desc,.cb-apply-hint{margin:.25rem 0 .75rem;font-size:.85rem;line-height:1.5;color:var(--dm-text-muted)}.cb-apply-hint{font-size:.75rem;margin-top:.2rem}.cb-apply-field{margin-bottom:.6rem}.cb-apply-field label{display:block;font-size:.82rem;font-weight:600;margin-bottom:.2rem;color:var(--dm-text)}.cb-apply-field input{width:100%;padding:.4rem .55rem;border:1px solid var(--dm-border);border-radius:4px;font-size:.88rem;background:var(--dm-surface);color:var(--dm-text)}.cb-apply-status{margin:.5rem 0;font-size:.85rem;min-height:1.2rem;color:var(--dm-text)}.cb-apply-status.cb-error{color:var(--dm-danger, #dc2626)}.cb-apply-buttons{display:flex;gap:.5rem;justify-content:flex-end;margin-top:.5rem}.cb-success-panel{padding:1rem 1.1rem;background:var(--dm-surface);border:1px solid var(--dm-success, #16a34a);border-radius:8px;color:var(--dm-text)}.cb-success-panel .cb-icon{color:var(--dm-success, #16a34a);font-size:1.4rem}.cb-success-summary{margin:.25rem 0 .5rem;padding-left:1.2rem;font-size:.86rem;line-height:1.6;color:var(--dm-text)}.cb-success-warning{margin:.5rem 0;padding:.5rem .75rem;background:var(--dm-background-alt);border-left:3px solid var(--dm-warning, #eab308);border-radius:0 4px 4px 0;font-size:.82rem;color:var(--dm-text-muted)}.cb-success-snippet-label{margin:0 0 .25rem;font-size:.82rem;font-weight:600;color:var(--dm-text)}.cb-success-actions{display:flex;gap:.5rem;margin-top:.5rem;flex-wrap:wrap}.cb-code{position:relative}.cb-code pre{background:var(--dm-background-alt);color:var(--dm-text);display:block;padding:.6rem 2.4rem .6rem .75rem;white-space:pre;overflow-x:auto;margin:0;border-radius:6px;font-size:.82em;font-family:monospace;line-height:1.45}.cb-code .cb-copy{position:absolute;top:.35rem;right:.35rem;background:none;border:none;cursor:pointer;opacity:.45;padding:.2rem;line-height:1;color:var(--dm-text)}.cb-code .cb-copy:hover{opacity:1}.cb-intro{padding:.75rem 1rem;border-left:3px solid var(--dm-primary);background:var(--dm-background-alt);border-radius:0 6px 6px 0}.cb-intro p{margin:0;font-size:.92rem;line-height:1.5;color:var(--dm-text)}.cb-tutorial-link{display:flex;align-items:center;gap:.6rem;padding:.65rem .85rem;border:1px solid var(--dm-border);border-radius:6px;text-decoration:none;color:var(--dm-text);font-size:.88rem;transition:border-color .12s}.cb-tutorial-link:hover{border-color:var(--dm-primary)}.cb-tutorial-link .cb-icon{flex-shrink:0;color:var(--dm-primary)}.cb-tutorial-link .cb-arrow{color:var(--dm-text-muted);font-size:1.1rem;margin-left:auto}.menu-tree-row{display:grid;grid-template-columns:26px 1.4fr 1.4fr .9fr .7fr .9fr repeat(6,auto);gap:6px;align-items:center;padding:4px 0;transition:opacity .15s ease}.menu-tree-row--hidden{opacity:.5}.menu-tree-row--tool .me-tool-badge{margin-left:.4rem;font-size:.7rem;vertical-align:middle}.menu-tree-row--default .me-row-label{font-style:italic;opacity:.8}.menu-tree-grip{cursor:grab;color:var(--dm-text-muted)}.menu-tree-grip:hover{color:var(--dm-text)}.menu-tree{padding:8px 0}.menu-tree-row--separator{display:grid;grid-template-columns:26px minmax(80px,1fr) repeat(7,auto);gap:6px;align-items:center;padding:2px 0;opacity:.85}.menu-tree-row--separator:hover{opacity:1}.menu-tree-row--separator .me-sep-line{display:flex;align-items:center;gap:10px;width:100%}.menu-tree-row--separator .me-sep-line:before,.menu-tree-row--separator .me-sep-line:after{content:"";flex:1;border-top:1px dashed var(--dm-border, rgba(128, 128, 128, .55))}.menu-tree-row--separator .me-sep-label{font-size:.66rem;font-weight:700;letter-spacing:.09em;text-transform:uppercase;color:var(--dm-text-muted, #8a8a8a);white-space:nowrap}.dm-admin-sidebar .sidebar-divider{border:0;border-top:1px solid var(--dm-border, rgba(128, 128, 128, .5));margin:.5rem .75rem;opacity:.8}.dm-admin-sidebar .sidebar-spacer--xs{height:var(--dm-space-1, .25rem)}.dm-admin-sidebar .sidebar-spacer--sm{height:var(--dm-space-2, .5rem)}.dm-admin-sidebar .sidebar-spacer--md{height:var(--dm-space-4, 1rem)}.dm-admin-sidebar .sidebar-spacer--lg{height:var(--dm-space-6, 1.5rem)}.dm-admin-sidebar .sidebar-spacer--xl{height:var(--dm-space-10, 2.5rem)}.dm-admin-sidebar .sidebar-spacer--flex{flex:1 1 auto;min-height:var(--dm-space-4, 1rem)}.dm-admin-sidebar--has-flex-spacer{display:flex;flex-direction:column;min-height:100%}.menu-tree-row--spacer{display:grid;grid-template-columns:26px minmax(80px,1fr) repeat(7,auto);gap:6px;align-items:center;padding:2px 0;opacity:.85}.menu-tree-row--spacer:hover{opacity:1}.menu-tree-row--spacer .me-spacer-line{display:flex;align-items:center;gap:8px;width:100%}.menu-tree-row--spacer .me-spacer-line:before,.menu-tree-row--spacer .me-spacer-line:after{content:"";flex:1;border-top:1px dotted var(--dm-border, rgba(128, 128, 128, .55))}.menu-tree-row--spacer .me-spacer-label{font-size:.66rem;font-weight:700;letter-spacing:.09em;text-transform:uppercase;color:var(--dm-text-muted, #8a8a8a);white-space:nowrap}.menu-tree-row--spacer .me-spacer-size{width:auto;min-width:5.5rem;height:26px;padding:0 .35rem;font-size:.75rem}.menu-tree-row .me-icon-wrap{display:flex;gap:2px}.menu-tree-row .me-icon-wrap .me-icon{flex:1;min-width:0}.menu-tree-row .me-icon-wrap .me-icon-pick{flex-shrink:0;padding:.2rem .45rem;font-size:.85em}.dm-admin-sidebar{display:flex;flex-direction:column;gap:2px;padding:8px 0;font-size:.875rem}.dm-admin-sidebar details{margin:0}.dm-admin-sidebar details>summary{list-style:none;cursor:pointer;display:flex;align-items:center;gap:.5rem;padding:.4rem .75rem;border-radius:4px;user-select:none;font-size:.78rem;font-weight:600;text-transform:uppercase;letter-spacing:.05em;color:var(--dm-text-muted, #888)}.dm-admin-sidebar details details>summary{font-size:.875rem;font-weight:500;text-transform:none;letter-spacing:0;color:inherit}.dm-admin-sidebar .dm-menu-badge{font-size:.7rem;font-weight:600}.dm-admin-sidebar details>summary::-webkit-details-marker{display:none}.dm-admin-sidebar details>summary:after{content:"\25b8";margin-left:auto;transition:transform .15s ease;color:var(--dm-text-muted, #999);font-size:.85em}.dm-admin-sidebar details[open]>summary:after{transform:rotate(90deg)}.dm-admin-sidebar details>div{padding-left:1rem;border-left:1px solid var(--dm-border-light, rgba(0, 0, 0, .08));margin-left:.95rem}.dm-admin-sidebar .sidebar-link{display:flex;align-items:center;gap:.5rem;padding:.35rem .75rem;text-decoration:none;color:var(--dm-text, inherit);border-radius:4px}.dm-admin-sidebar .sidebar-link:hover,.dm-admin-sidebar details>summary:hover{background:var(--dm-hover-bg, rgba(0, 0, 0, .05))}.dm-admin-sidebar .sidebar-link.active{background:var(--dm-active-bg, rgba(0, 0, 0, .08));font-weight:600}.dm-admin-sidebar .sidebar-text{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.dm-admin-sidebar [data-icon]{flex-shrink:0}.dm-admin-sidebar-header{position:sticky;top:0;z-index:2;background:var(--dm-surface);display:flex;align-items:center;gap:.5rem;padding:.65rem .85rem;margin:0 0 .5rem;font-weight:600;font-size:.95rem;letter-spacing:.01em;color:var(--dm-text, inherit);border-bottom:1px solid var(--dm-border-light, rgba(0, 0, 0, .08))}.dm-admin-sidebar--dark .dm-admin-sidebar-header{background:#1a1d24}.dm-admin-sidebar--light .dm-admin-sidebar-header{background:#fff}.dm-admin-sidebar-header [data-icon]{color:var(--dm-text-muted, #999)}.dm-admin-sidebar .sidebar-badge{margin-left:auto;padding:0 .4rem;min-width:1.25rem;height:1.1rem;line-height:1.1rem;text-align:center;font-size:.7rem;font-weight:600;border-radius:999px;background:var(--dm-active-bg, rgba(0, 0, 0, .12));color:var(--dm-text-muted, #888)}.dm-admin-sidebar .sidebar-link.active .sidebar-badge{background:var(--dm-primary, #4a86e8);color:var(--dm-primary-text, #fff)}.dm-admin-sidebar .sidebar-children{overflow:hidden;transition:max-height .22s ease,opacity .18s ease}.dm-admin-sidebar details:not([open])>.sidebar-children{opacity:0}.dm-admin-sidebar{position:relative}.dm-admin-sidebar-handle{position:absolute;top:0;right:0;width:6px;height:100%;cursor:col-resize;background:transparent;z-index:10;transition:background .15s}.dm-admin-sidebar-handle:hover,.dm-admin-sidebar-handle:active{background:var(--dm-primary, #4a86e8);opacity:.35}.dm-admin-sidebar--dark{background:#1a1d24;color:#e3e6eb}.dm-admin-sidebar--dark .sidebar-link,.dm-admin-sidebar--dark summary{color:#e3e6eb}.dm-admin-sidebar--dark .sidebar-link:hover,.dm-admin-sidebar--dark details>summary:hover{background:#ffffff0f}.dm-admin-sidebar--dark .sidebar-link.active{background:#4a86e840}.dm-admin-sidebar--dark .sidebar-badge{background:#ffffff1f;color:#cbd0d8}.dm-admin-sidebar--light{background:#fff;color:#1a1d24;border-right:1px solid rgba(0,0,0,.08)}.dm-admin-sidebar--light .sidebar-link,.dm-admin-sidebar--light summary{color:#1a1d24}.dm-admin-sidebar--light .sidebar-link:hover,.dm-admin-sidebar--light details>summary:hover{background:#0000000a}.dm-admin-sidebar--light .sidebar-link.active{background:#4a86e826}.dm-admin-sidebar--transparent{background:transparent}.page-header{display:flex;align-items:center;justify-content:space-between;gap:1rem;flex-wrap:wrap;margin:0 0 1.25rem;padding-bottom:.75rem;border-bottom:1px solid var(--dm-border-light, rgba(0, 0, 0, .08))}.page-header h2{margin:0;display:flex;align-items:center;gap:.5rem;font-size:1.4rem;line-height:1.2}.page-header h2 [data-icon]{color:var(--dm-text-muted, #888)}.header-actions{display:flex;align-items:center;gap:.5rem;flex-wrap:wrap}.card+.card,.card+p,p+.card,.card+.toolbar,.toolbar+.card,.card+.grid{margin-top:1rem}.toolbar{display:flex;align-items:center;gap:.5rem;flex-wrap:wrap;margin:0 0 1rem}.btn+.btn,.btn+a.btn,a.btn+.btn,a.btn+a.btn{margin-left:.35rem}[style*=inline-flex] .btn+.btn,[style*=inline-flex] .btn+a.btn,[style*=inline-flex] a.btn+.btn{margin-left:0}.card-body>[id$=-form],.card-body>form{margin:.25rem 0}.card-header{display:flex;align-items:center;gap:.5rem}.card-header h3{margin:0;font-size:1.05rem}.card-header [data-icon]{color:var(--dm-text-muted, #888)}.page-header+p.text-muted{margin:-.5rem 0 1rem}.dm-pe-grid{gap:.75rem 1rem}.dm-pe-grid .form-group{display:flex;flex-direction:column;gap:.25rem;margin:0}.dm-pe-grid .form-group.col-span-2{grid-column:1 / -1}.dm-pe-grid label{font-size:.85rem;font-weight:600;color:var(--dm-text, inherit)}.dm-pe-grid label .required{color:var(--dm-danger, #c33);margin-left:2px}.dm-pe-grid .form-hint{font-size:.75rem;color:var(--dm-text-muted, #888);margin-top:.1rem}.dm-pe-grid .form-input{width:100%;padding:.4rem .6rem}.dm-pe-grid textarea.form-input{resize:vertical;min-height:2.5rem}.dm-menu-badge{display:inline-block;margin-left:6px;padding:1px 7px;font-size:.7em;font-weight:700;line-height:1.4;border-radius:999px;background:var(--dm-text-muted);color:var(--dm-text-inverse, #fff);vertical-align:middle}.menu-tree-row--slim{display:grid;grid-template-columns:26px 1fr auto repeat(9,auto);gap:6px;align-items:center}.menu-tree-row--slim .me-row-label{font-weight:600}.menu-tree-row--slim .me-row-url{color:var(--dm-text-muted);font-size:.85em}.me-pages-picker{display:flex;gap:6px;align-items:center;margin-bottom:6px}.me-pages-picker .form-input{flex:1;min-width:0}.me-colour-control{display:flex;gap:6px;align-items:center}.me-colour-control .me-colour-hex{width:48px;height:32px;padding:2px;flex:none}.me-bind-summary{padding:.6rem .8rem;border:1px solid var(--dm-border, rgba(128, 128, 128, .35));border-radius:var(--dm-radius-md, 6px);background:color-mix(in srgb,var(--dm-text) 4%,transparent);font-size:.9em}.me-bind-summary code{font-size:.9em}.me-item-form{display:flex;flex-direction:column;gap:10px;padding:4px 2px}.me-item-form .form-field{display:flex;flex-direction:column;gap:4px}.me-item-form .form-label{font-size:.85em;color:var(--dm-text-muted)}.me-form-section{margin:12px 0 2px;padding-top:10px;border-top:1px solid var(--dm-border-light, rgba(0,0,0,.15));font-size:.78em;text-transform:uppercase;letter-spacing:.06em;color:var(--dm-text-muted)}.me-item-form .me-form-section:first-child{margin-top:0;padding-top:0;border-top:0}.me-item-form .me-colour-hex{width:48px;height:32px;padding:2px}.me-item-form .me-field-grid{display:grid;grid-template-columns:1fr 1fr;gap:10px}.me-item-form .me-field-grid .form-field{margin:0}.me-item-form .me-icon-field{display:flex;align-items:center;gap:8px}.me-item-form .me-icon-field .form-input{flex:1}.me-item-form .me-icon-preview{width:24px;height:24px;flex:0 0 auto;display:inline-flex;align-items:center;justify-content:center;color:var(--dm-text-muted)}#admin-sidebar.dm-menu-floating{border:1px solid var(--dm-border);border-radius:var(--dm-radius-md, 8px);box-shadow:var(--dm-shadow-lg);overflow:hidden}@media(max-width:768px){#admin-sidebar.dm-menu-floating{position:static!important;inset:auto!important;max-height:none!important;transform:none!important}.dashboard-wrapper{padding-left:0!important;padding-right:0!important}}[data-logic-section]{border:1px solid var(--dm-border);border-radius:var(--dm-radius-md, 6px);padding:.9rem 1rem 1rem;margin-bottom:1rem;background:color-mix(in srgb,var(--dm-text) 3%,transparent)}[data-logic-section] .fb-logic-cond-row,[data-logic-section] .fb-logic-val-rule{padding:.55rem .65rem;border-radius:var(--dm-radius-sm, 4px);border:1px solid var(--dm-border);background:var(--dm-surface, transparent)}[data-logic-section] .fb-logic-cond-row:last-of-type,[data-logic-section] .fb-logic-val-rule:last-of-type{margin-bottom:.75rem}[data-logic-section]>.btn{margin-top:.15rem}[data-logic-section] textarea{min-height:5rem}.project-filter-notice{display:flex;align-items:center;gap:.4rem;flex-wrap:wrap;margin:0 0 1rem;padding:.6rem .85rem;border:1px solid var(--dm-border);border-left:3px solid var(--dm-info, var(--dm-primary));border-radius:var(--dm-radius-md, 6px);background:color-mix(in srgb,var(--dm-info, var(--dm-primary)) 6%,transparent);font-size:.85rem;color:var(--dm-text-muted)}.project-filter-notice a{color:var(--dm-primary);font-weight:600}.ctx-help{display:inline-flex;align-items:center;justify-content:center;width:1.05rem;height:1.05rem;margin-left:.35rem;padding:0;border:1px solid var(--dm-border-dark, var(--dm-border));border-radius:var(--dm-radius-full, 9999px);background:transparent;color:var(--dm-text-muted);font-size:.68rem;font-weight:700;line-height:1;cursor:pointer;vertical-align:middle;flex-shrink:0}.ctx-help:hover,.ctx-help:focus-visible{border-color:var(--dm-primary);color:var(--dm-primary);outline:none}.card-header h3 .ctx-help{align-self:center}.ctx-preview-card{position:sticky;top:1rem}@media(max-width:1100px){.ctx-workspace>.col-8,.ctx-workspace>.col-4{flex:0 0 auto;width:100%}.ctx-preview-card{position:static}}.dm-plugin-shell{border:1px solid var(--dm-border);border-radius:var(--dm-radius-lg, 12px);background:var(--dm-surface);overflow:hidden}.dm-plugin-banner{display:flex;align-items:center;justify-content:space-between;gap:1rem;flex-wrap:wrap;padding:.7rem 1rem;background:var(--dm-background-alt);border-bottom:1px solid var(--dm-border)}.dm-plugin-banner-identity{display:flex;align-items:center;gap:.55rem;min-width:0;margin-right:auto}.dm-plugin-banner-actions{display:flex;align-items:center;gap:.25rem;flex:0 0 auto;margin-right:.15rem;padding-right:.4rem;border-right:1px solid var(--dm-border)}.dm-plugin-banner-action{padding:.25rem .4rem;line-height:1;color:var(--dm-text-muted)}.dm-plugin-banner-action:hover{color:var(--dm-primary)}.dm-plugin-banner-icon{display:inline-flex;align-items:center;color:var(--dm-primary);flex:0 0 auto}.dm-plugin-banner-name{margin:0;font-size:1.05rem;font-weight:600;letter-spacing:.01em;color:var(--dm-text);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.dm-activity{display:inline-flex;align-items:center;flex:0 0 auto;margin-left:.35rem}.dm-activity domma-loader{display:inline-block;line-height:0}.dm-activity[hidden]{display:none!important}#admin-topbar>.dm-activity{margin:0 .75rem 0 0}.dm-plugin-banner-parent{font-weight:500;color:var(--dm-text-muted)}.dm-plugin-banner-sep{margin:0 .4rem;color:var(--dm-text-muted)}.dm-plugin-banner-facts{display:flex;align-items:center;gap:.4rem;flex-wrap:wrap}.dm-plugin-fact{font-size:.72rem;line-height:1.6;padding:1px 8px;border-radius:999px;border:1px solid var(--dm-border);color:var(--dm-text-muted);background:var(--dm-surface);white-space:nowrap}.dm-plugin-fact--version{font-variant-numeric:tabular-nums;color:var(--dm-text)}.dm-plugin-fact--licence.is-included{color:var(--dm-info);border-color:var(--dm-info)}.dm-plugin-fact--licence.is-licensed{color:var(--dm-success);border-color:var(--dm-success)}.dm-plugin-fact--expiry{font-variant-numeric:tabular-nums}.dm-plugin-fact--expiry.is-warning{color:var(--dm-warning);border-color:var(--dm-warning)}.dm-plugin-fact--expiry.is-danger{color:var(--dm-danger);border-color:var(--dm-danger)}.dm-plugin-body{padding:1rem}.dm-plugin-body .card.dm-plugin-unwrap{border:0;background:none;box-shadow:none;margin:0}.dm-plugin-body .card.dm-plugin-unwrap>.card-body{padding:0}.dm-plugin-body>.p-4{padding:0}@media(max-width:640px){.dm-plugin-banner{align-items:flex-start;flex-direction:column;gap:.5rem}.dm-plugin-body{padding:.75rem}}.analytics-filter{max-width:240px}.dm-help-btn{display:inline-flex;align-items:center;justify-content:center;vertical-align:middle;margin-left:.3rem;padding:0;border:0;background:none;line-height:1;color:var(--dm-text-muted);opacity:.75;cursor:pointer}.dm-help-btn:hover,.dm-help-btn:focus-visible{color:var(--dm-primary);opacity:1}.dm-help-pop{position:fixed;z-index:10050;max-width:300px;padding:.6rem .75rem;background:var(--dm-surface, var(--dm-background));color:var(--dm-text);border:1px solid var(--dm-border);border-radius:var(--dm-radius-md);box-shadow:0 8px 24px #00000040;font-size:.85rem;line-height:1.45;text-align:left;font-weight:400}.dm-help-pop strong{display:block;margin-bottom:.2rem;font-weight:600}.dm-help-pop p{margin:0}.dm-admin-sidebar .sidebar-badge[data-badge-label]{cursor:help}.dm-admin-sidebar .sidebar-badge--danger,.dm-admin-sidebar .sidebar-link.active .sidebar-badge--danger{background:var(--dm-danger, #dc2626);color:#fff}.dm-admin-sidebar .sidebar-badge--live{background:color-mix(in srgb,var(--dm-success, #16a34a) 20%,transparent);color:var(--dm-success, #16a34a)}#admin-sidebar .sidebar-badge--live{padding-left:1.05rem!important}#admin-sidebar summary>.sidebar-badge--sum{position:static!important;transform:none!important;margin-left:auto!important;margin-right:.45rem;text-transform:none;letter-spacing:0}#admin-sidebar summary:has(>.sidebar-badge--sum):after{margin-left:0}#admin-sidebar details[open]>summary>.sidebar-badge--sum{display:none}.dm-admin-sidebar .sidebar-badge--live:before{content:"";position:absolute;left:.4rem;top:50%;width:.4rem;height:.4rem;margin-top:-.2rem;border-radius:50%;background:currentColor;animation:dm-badge-pulse 2s ease-in-out infinite}@keyframes dm-badge-pulse{50%{opacity:.35}}@media(prefers-reduced-motion:reduce){.dm-admin-sidebar .sidebar-badge--live:before{animation:none}}.dm-badge-pop{width:290px;max-width:calc(100vw - 16px);font-size:.8rem;pointer-events:none}.dm-badge-pop-title{display:block;font-size:.85rem}.dm-badge-pop-sub{margin:.1rem 0 .5rem;color:var(--dm-text-muted)}.dm-badge-pop-rows{display:grid;grid-template-columns:1fr auto;gap:.2rem .75rem;margin:0 0 .5rem;padding:.45rem 0;border-top:1px solid var(--dm-border);border-bottom:1px solid var(--dm-border)}.dm-badge-pop-rows dt{color:var(--dm-text-muted)}.dm-badge-pop-rows dd{margin:0;text-align:right;font-weight:600;font-variant-numeric:tabular-nums}.dm-badge-pop-items{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:.4rem}.dm-badge-pop-items li{display:flex;flex-direction:column;min-width:0}.dm-badge-pop-text{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.dm-badge-pop-meta{font-size:.72rem;color:var(--dm-text-muted)}.dm-badge-pop .is-danger,.dm-badge-pop li.is-danger .dm-badge-pop-meta{color:var(--dm-danger, #dc2626)}.dm-badge-pop-empty{margin:0;color:var(--dm-text-muted)}.dm-plugin-body,.dm-slideover{font-family:var(--dm-font-sans, inherit)}.dm-plugin-body :is(button,input,select,textarea,.btn,.form-input,.form-select,.form-textarea),.dm-slideover :is(button,input,select,textarea,.btn,.form-input,.form-select,.form-textarea){font-family:inherit}.dm-plugin-body :is(input,select,textarea,.form-input,.form-select,.form-textarea):not(.form-input-lg),.dm-slideover :is(input,select,textarea,.form-input,.form-select,.form-textarea):not(.form-input-lg){font-size:var(--dm-text-sm)}.dm-plugin-body .form-input-lg{font-size:var(--dm-text-base)}.dm-plugin-body :is(.font-mono,code,pre,kbd),.dm-slideover :is(.font-mono,code,pre,kbd){font-family:var(--dm-font-mono, monospace)}.dm-plugin-body .form-label,.dm-slideover .form-label{font-size:var(--dm-text-sm)}.related-box{display:flex;flex-direction:column;gap:.6rem;border-top:1px solid var(--dm-border);padding-top:.75rem}.related-box[hidden]{display:none}.related-head{display:flex;align-items:center;gap:.4rem}.related-head strong{flex:1}.related-list{list-style:none;margin:.3rem 0 0;padding:0;display:flex;flex-direction:column;gap:.25rem}.related-list li{display:flex;flex-direction:column}.related-list li.is-past{opacity:.7}.related-meta,.related-note,.related-loading{color:var(--dm-text-muted);font-size:var(--dm-text-xs);margin:0}.login-challenge{display:flex;flex-direction:column;gap:.6rem;margin-bottom:.75rem}.login-challenge #challenge-code{font-size:1.25rem;letter-spacing:.2em;text-align:center}.login-trust{display:flex;align-items:center;gap:.45rem;font-size:.875rem}.login-enrol{display:flex;flex-direction:column;align-items:center;gap:.6rem;margin-bottom:1rem}.login-enrol img{background:#fff;padding:.5rem;border-radius:.5rem}.login-secret{display:flex;flex-direction:column;align-items:center;gap:.25rem;text-align:center}.login-secret code{font-size:.95rem;letter-spacing:.08em;word-break:break-all}.usx-secret{display:flex;flex-direction:column;gap:.75rem;padding:1rem}.usx-secret-link{display:block;padding:.6rem .75rem;border:1px solid var(--dm-border);border-radius:var(--dm-radius-sm);background:var(--dm-background-alt);word-break:break-all;font-size:.8rem;user-select:all}.usx-secret-actions{display:flex;align-items:center;justify-content:flex-end;gap:.5rem}.usx-secret-actions .btn{display:inline-flex;align-items:center;gap:.35rem}.usx-secret-note{margin-right:auto;color:var(--dm-success)}.usx-secret-foot{color:var(--dm-text-muted);font-size:.8rem;margin:0}.uex-reset{display:flex;flex-wrap:wrap;align-items:center;gap:.35rem .5rem;margin-top:.5rem}.uex-reset>small:first-child{flex-basis:100%;color:var(--dm-text-muted)}.uex-reset .btn{display:inline-flex;align-items:center;gap:.35rem}.uex-reset-open{flex-basis:100%;color:var(--dm-info)}
|
|
1
|
+
.dashboard-layout{display:flex;flex-direction:column;height:100vh;min-height:100vh;overflow:hidden}.dashboard-wrapper{display:flex;flex:1;min-height:0;overflow:hidden}.dashboard-main{flex:1;min-width:0;overflow-y:auto}#admin-sidebar.dashboard-sidebar{display:flex;flex-direction:column;flex-shrink:0;overflow:hidden}#admin-sidebar .dm-admin-sidebar{flex:1;min-height:0;overflow-y:auto;overscroll-behavior:contain;scrollbar-width:thin;scrollbar-color:var(--dm-border) transparent}#admin-sidebar .dm-admin-sidebar::-webkit-scrollbar{width:8px}#admin-sidebar .dm-admin-sidebar::-webkit-scrollbar-track{background:transparent}#admin-sidebar .dm-admin-sidebar::-webkit-scrollbar-thumb{background:var(--dm-border);border-radius:4px}#admin-sidebar .dm-admin-sidebar::-webkit-scrollbar-thumb:hover{background:var(--dm-text-muted)}.view-container{padding:1.5rem 2rem;max-width:1200px}.view-container:has(>.dm-plugin-shell){max-width:100%}.view-header{display:flex;align-items:center;justify-content:space-between;margin-bottom:1.5rem;gap:1rem}.view-header h1{font-size:1.5rem;font-weight:700;margin:0;display:flex;align-items:center;gap:.5rem}.view-header-actions{display:flex;gap:.75rem;flex-wrap:wrap}.view-header-actions .btn-primary,.view-header-actions .btn-success,.view-header-actions .btn-danger{margin-left:.5rem}.stat-card .card-body{display:flex;align-items:center;gap:1rem}.stat-icon{width:44px;height:44px;border-radius:8px;background:color-mix(in srgb,var(--dm-primary) 14%,transparent);color:var(--dm-primary, #5b8cff);display:flex;align-items:center;justify-content:center;font-size:1.25rem;flex-shrink:0}.stat-icon--success{background:color-mix(in srgb,var(--dm-success) 15%,transparent);color:var(--dm-success)}.stat-icon--warning{background:color-mix(in srgb,var(--dm-warning) 15%,transparent);color:var(--dm-warning)}.stat-value{font-size:1.75rem;font-weight:700;line-height:1}.stat-label{font-size:.8rem;color:var(--dm-text-muted, #888);margin-top:.25rem}.toolbar{display:flex;align-items:center;gap:.75rem}.form-check-label{display:flex;align-items:center;gap:.5rem;cursor:pointer;font-size:.9rem}.form-hint{display:block;font-size:.8rem;color:var(--dm-text-muted, #888);margin-top:.25rem}.dashboard-main:has(#editor-meta-tabs){overflow:hidden}.view-container:has(#editor-meta-tabs){display:flex;flex-direction:column;height:calc(100dvh - 60px);max-width:100%;padding-bottom:0}.view-container:has(#editor-meta-tabs)>.dm-plugin-shell{flex:1;min-height:0;display:flex;flex-direction:column}.view-container:has(#editor-meta-tabs)>.dm-plugin-shell>.dm-plugin-banner,.view-container:has(#editor-meta-tabs) .pex-bar{flex:none}.view-container:has(#editor-meta-tabs)>.dm-plugin-shell>.dm-plugin-body{flex:1;min-height:0;display:flex;flex-direction:column}.view-container:has(#block-editor-body){max-width:100%}.view-container:has(#ep-editor-tabs){max-width:100%}.ep-editor-grid{display:grid;grid-template-columns:minmax(0,1.25fr) minmax(0,1fr) minmax(0,1.3fr);gap:1rem;align-items:start}.ep-editor-grid>.ep-tryit-col,.ep-editor-grid>.ep-results-col{position:sticky;top:1rem;display:flex;flex-direction:column;gap:1rem;min-width:0}@media(max-width:1500px){.ep-editor-grid{grid-template-columns:minmax(0,1fr) minmax(0,1fr)}.ep-editor-grid>:first-child{grid-column:1 / -1}.ep-editor-grid>.ep-tryit-col,.ep-editor-grid>.ep-results-col{position:static}}@media(max-width:1024px){.ep-editor-grid{grid-template-columns:minmax(0,1fr)}}#editor-meta-tabs{flex:1;min-height:0;display:flex;flex-direction:column}#editor-meta-tabs .tab-content{flex:1;min-height:0;overflow:hidden}#editor-meta-tabs .tab-panel{height:100%;overflow-y:auto}#editor-meta-tabs .tab-panel:has(.editor-card),#live-preview-panel{overflow:hidden}.live-preview-bar{display:flex;align-items:center;gap:var(--dm-space-4);flex-wrap:wrap;padding:var(--dm-space-2) 0;border-bottom:1px solid var(--dm-border);margin-bottom:var(--dm-space-2)}.live-preview-widths{display:inline-flex;border:1px solid var(--dm-border);border-radius:var(--dm-radius-sm);overflow:hidden}.live-preview-width{display:inline-flex;align-items:center;justify-content:center;padding:.3rem .55rem;border:none;background:transparent;color:inherit;cursor:pointer;line-height:1}.live-preview-width+.live-preview-width{border-left:1px solid var(--dm-border)}.live-preview-width:hover{background:var(--dm-hover-bg)}.live-preview-width.active{background:var(--dm-active-bg)}.live-preview-status{flex:1 1 auto;font-size:.8rem;opacity:.75}.live-preview-actions{display:flex;gap:var(--dm-space-1)}.live-preview-wrap{display:flex;flex-direction:column;height:100%;min-height:0}.live-preview-wrap>.live-preview-bar{flex:none}.live-preview-stage{display:flex;justify-content:center;flex:1;min-height:0;overflow:auto;background:var(--dm-background-alt);border-radius:var(--dm-radius-md)}.page-live-preview-frame{display:block;width:100%;max-width:100%;height:100%;border:none;border-radius:6px;background:var(--dm-background);transition:max-width .18s ease}.page-live-preview-frame[data-width="1024"]{max-width:1024px}.page-live-preview-frame[data-width="390"]{max-width:390px}.page-live-preview-frame[data-width="1024"],.page-live-preview-frame[data-width="390"]{border-left:1px solid var(--dm-border);border-right:1px solid var(--dm-border)}.editor-card{display:flex;flex-direction:column;height:100%}.editor-card .card-body{display:flex;flex-direction:column;flex:1;min-height:0;padding:0!important}.editor-toolbar{display:flex;align-items:center;gap:2px;padding:6px 10px;border-bottom:1px solid var(--dm-border, rgba(255, 255, 255, .08));flex-wrap:wrap;flex-shrink:0}.editor-toolbar-btn{background:none;border:none;color:var(--dm-text-muted, #888);padding:6px 8px;border-radius:4px;cursor:pointer;display:flex;align-items:center;transition:color .15s,background .15s}.editor-toolbar-btn:hover{color:var(--dm-text, #eee);background:var(--dm-hover-bg)}.editor-toolbar-sep{width:1px;height:20px;background:var(--dm-border, rgba(255, 255, 255, .08));margin:0 4px;flex-shrink:0}.editor-toolbar-right{margin-left:auto;display:flex;align-items:center;gap:2px}.editor-view-btn{background:none;border:none;color:var(--dm-text-muted, #888);padding:6px 8px;border-radius:4px;cursor:pointer;display:flex;align-items:center;transition:color .15s,background .15s}.editor-view-btn:hover{color:var(--dm-text, #eee);background:var(--dm-hover-bg)}.editor-view-btn.active{color:var(--dm-primary, #5b8cff);background:color-mix(in srgb,var(--dm-primary) 14%,transparent)}.editor-body{display:flex;flex:1;min-height:0;--dm-editor-split: 50%}@media(min-width:769px){.editor-body:not(.editor-mode-write):not(.editor-mode-preview) .editor-pane--write{flex:0 0 var(--dm-editor-split, 50%)}.editor-body:not(.editor-mode-write):not(.editor-mode-preview) .editor-pane--preview{flex:1 1 0}}.editor-pane{flex:1;display:flex;flex-direction:column;min-width:0}.editor-pane--write,.editor-pane--preview{overflow:hidden}.editor-pane--write{flex-direction:row}.editor-line-numbers{padding:1rem .6rem 1rem .75rem;background:var(--dm-background-alt, rgba(0, 0, 0, .15));border-right:1px solid var(--dm-border, rgba(255, 255, 255, .08));color:var(--dm-text-muted, #666);font-family:Fira Code,Courier New,monospace;font-size:.9rem;line-height:1.6;text-align:right;user-select:none;white-space:pre;overflow:hidden;flex-shrink:0;min-width:2.5rem}.editor-line-numbers--foldable{padding:1rem 0;min-width:3rem;white-space:normal;text-align:left;display:flex;flex-direction:column}.editor-line-number-row{display:flex;align-items:center;justify-content:flex-end;padding-right:.6rem;gap:.15rem}.fold-toggle{display:inline-flex;align-items:center;justify-content:center;width:1em;font-size:.6rem;cursor:default;color:transparent}.fold-toggle--open,.fold-toggle--folded{cursor:pointer;color:var(--dm-text-muted, #666);transition:color .1s}.fold-toggle--open:hover,.fold-toggle--folded:hover{color:var(--dm-primary, #4a9eff)}.editor-line-num{min-width:1.5rem;text-align:right}.editor-mode-write .editor-pane--preview,.editor-mode-write .editor-divider,.editor-mode-preview .editor-pane--write,.editor-mode-preview .editor-divider{display:none}.editor-divider{width:7px;background:linear-gradient(to right,transparent 0,transparent 3px,var(--dm-border, rgba(255,255,255,.08)) 3px,var(--dm-border, rgba(255,255,255,.08)) 4px,transparent 4px,transparent 100%);cursor:col-resize;flex-shrink:0;touch-action:none;transition:background .12s ease}.editor-divider:hover,.editor-divider:focus-visible,.editor-divider.is-dragging{background:linear-gradient(to right,transparent 0,transparent 2px,var(--dm-primary, #5b8cff) 2px,var(--dm-primary, #5b8cff) 5px,transparent 5px,transparent 100%);outline:none}.editor-body.is-resizing .editor-pane{pointer-events:none}.editor-body.is-resizing{cursor:col-resize;user-select:none}.editor-textarea{flex:1;resize:none;border:none;border-radius:0;background:transparent;font-family:Fira Code,Courier New,monospace;font-size:.9rem;padding:1rem;outline:none;color:inherit;line-height:1.6}#editor-body .editor-textarea,#editor-body .editor-line-numbers{font-family:var(--pe-font, "Fira Code", "Courier New", monospace);font-size:var(--pe-size, .9rem);line-height:var(--pe-line, 1.6)}#editor-body.pe-nowrap .editor-textarea{white-space:pre;overflow-x:auto}.editor-preview{flex:1;display:block;width:100%;border:none;background:var(--dm-background)}.editor-fullscreen{position:fixed;inset:0;z-index:1000;border-radius:0;margin:0}.editor-fullscreen .card-body{height:100vh}.media-picker-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(120px,1fr));gap:.75rem;max-height:400px;overflow-y:auto;padding:.25rem}.media-picker-item{cursor:pointer;border:2px solid transparent;border-radius:6px;overflow:hidden;transition:border-color .15s}.media-picker-item:hover{border-color:var(--dm-primary, #5b8cff)}.media-picker-item img{width:100%;height:80px;object-fit:cover;display:block}.media-picker-item span{display:block;font-size:.75rem;padding:4px 6px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.docs-body h3{margin-top:1.25rem;margin-bottom:.5rem}.docs-body p{margin-bottom:.5rem;line-height:1.6}.docs-body ol,.docs-body ul{margin-bottom:.75rem;padding-left:1.25rem}.docs-body li{margin-bottom:.25rem}.docs-body hr{margin:1.25rem 0;border-color:var(--dm-border, rgba(255, 255, 255, .08))}.docs-body .table{margin-bottom:.75rem}.docs-body h2{margin-top:1.75rem;margin-bottom:.6rem;padding-bottom:.3rem;border-bottom:1px solid var(--dm-border)}.docs-body h2:first-child{margin-top:0}.docs-body blockquote{margin:.75rem 0;padding:.5rem .9rem;border-left:3px solid var(--dm-primary);background:var(--dm-surface);border-radius:var(--dm-radius, 6px)}.docs-body pre{margin-bottom:.75rem;overflow-x:auto}.pg-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(260px,1fr));gap:1rem;margin-top:1.5rem}.pg-grid>.card.pg-card{display:block;margin:0;text-decoration:none}.pg-card h3{margin-top:0}.pg-card .text-muted,.pg-card-pages{margin-bottom:0}.pg-card-pages{margin-top:.5rem;font-size:.8rem;color:var(--dm-text-muted)}.pg-actions{display:flex;gap:.5rem;flex-wrap:wrap}.pg-meta{margin-bottom:.75rem}.pg-pages{display:flex;flex-wrap:wrap;gap:.35rem;margin-bottom:1rem}.pg-body{max-width:80ch}.nav-items-header,.nav-item-row{display:flex;gap:.5rem;align-items:center;padding:.35rem .75rem}.nav-items-header{border-bottom:1px solid var(--dm-border, rgba(255,255,255,.08));padding-bottom:.4rem;margin-bottom:.25rem}.nav-item-row{border-bottom:1px solid var(--dm-border, rgba(255,255,255,.04))}.nav-item-row:last-child{border-bottom:none}.nav-col-indent{width:18px;flex-shrink:0;color:var(--dm-text-muted, #888);text-align:center;font-size:.85rem}.nav-col-main{flex:2;min-width:0}.nav-col-icon{flex:0 0 90px}.nav-col-parent{flex:2;min-width:0}.nav-col-action{flex-shrink:0}.nav-item-row--child{background:color-mix(in srgb,var(--dm-text) 3%,transparent)}.nav-col-action{display:flex;align-items:center;gap:.25rem}.nav-item-row--hidden{opacity:.45}.nav-item-row--hidden .item-text,.nav-item-row--hidden .footer-link-text{text-decoration:line-through}.btn-toggle-hidden{color:var(--dm-text-muted, #888)}.btn-toggle-hidden.active{color:var(--dm-warning, #f59e0b)}.fb-field-card.fb-drag-over{outline:2px dashed var(--dm-primary, #6366f1);outline-offset:-2px}.btn-ghost span[data-icon=trash]{color:var(--dm-danger, #dc2626)}.view-container:has(.fb-fields-layout){max-width:none}.fb-fields-layout{display:grid;grid-template-columns:minmax(0,6fr) minmax(320px,4fr);gap:1.25rem;align-items:start}.fb-preview-pane{position:sticky;top:1rem;min-width:0}@media(max-width:1100px){.fb-fields-layout{grid-template-columns:1fr}.fb-preview-pane{position:static}}.toggle-label{display:flex;align-items:center;gap:.4rem;font-size:.9rem;cursor:pointer;margin-right:1rem}.preset-toggles{display:flex;flex-wrap:wrap;margin-top:.75rem}.presets-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:1rem}@media(max-width:900px){.presets-grid{grid-template-columns:repeat(2,1fr)}}@media(max-width:600px){.presets-grid{grid-template-columns:1fr}}.card-header{padding:.5rem 1rem}.card-header h2{margin:0;font-size:.9rem;font-weight:600;letter-spacing:.02em}.preset-card .card-header{display:flex;align-items:center;justify-content:space-between}.preset-card .card-header h3{margin:0;font-size:1rem}.media-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(180px,1fr));gap:1rem}.media-card{background:var(--dm-card-bg, rgba(255,255,255,.04));border:1px solid var(--dm-border, rgba(255,255,255,.08));border-radius:8px;overflow:hidden}.media-preview{height:130px;display:flex;align-items:center;justify-content:center;background:#0003;overflow:hidden}.media-thumb{width:100%;height:100%;object-fit:cover}.media-thumb--file{font-size:2rem;color:var(--dm-text-muted, #888)}.media-info{padding:.5rem .75rem;display:flex;flex-direction:column;gap:.15rem}.media-name{font-size:.8rem;font-weight:500;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;cursor:default}.media-rename-input{width:100%;font-size:.8rem;font-weight:500;padding:.1rem .25rem;border:1px solid var(--dm-primary, #7c6af7);border-radius:3px;background:var(--dm-input-bg, transparent);color:inherit;outline:none}.media-size{font-size:.75rem;color:var(--dm-text-muted, #888)}.media-actions{padding:.5rem .75rem;display:flex;gap:.4rem;border-top:1px solid var(--dm-border, rgba(255,255,255,.08))}#admin-topbar{height:60px;display:flex;align-items:center;gap:1rem;padding:0 1.25rem;background:var(--dm-navbar-bg, rgba(0,0,0,.3));border-bottom:1px solid var(--dm-border, rgba(255,255,255,.08));position:sticky;top:0;z-index:200;flex-shrink:0}.topbar-brand{display:flex;align-items:center;gap:.5rem;font-weight:700;font-size:.95rem;color:inherit;flex-shrink:0;margin-right:.5rem}.topbar-brand span[data-icon],.topbar-brand svg{color:var(--dm-primary, #5b8cff);width:22px;height:22px}.topbar-brand-text{opacity:.85}.topbar-brand-logo{height:28px;width:auto;display:inline-block;vertical-align:middle;margin-right:.4em;object-fit:contain}.topbar-user{display:flex;align-items:center;gap:.6rem;flex:1}.topbar-user-name{font-size:.875rem;font-weight:500}.topbar-avatar{width:1.75rem;height:1.75rem;border-radius:50%;object-fit:cover;flex-shrink:0}.topbar-role-badge{font-size:.7rem;font-weight:600;letter-spacing:.04em;text-transform:uppercase;padding:.15rem .45rem;border-radius:4px}.topbar-role-badge--admin{background:color-mix(in srgb,var(--dm-primary) 15%,transparent);color:var(--dm-primary)}.topbar-role-badge--manager{background:color-mix(in srgb,var(--dm-success) 15%,transparent);color:var(--dm-success)}.topbar-role-badge--editor{background:color-mix(in srgb,var(--dm-warning) 15%,transparent);color:var(--dm-warning)}.topbar-role-badge--subscriber{background:color-mix(in srgb,var(--dm-text-muted) 15%,transparent);color:var(--dm-text-muted)}.topbar-actions{display:flex;align-items:center;gap:.5rem;flex-shrink:0}.topbar-action-link{display:flex;align-items:center;gap:.35rem;font-size:.875rem;color:var(--dm-text-muted, #888);text-decoration:none;padding:.4rem .65rem;border-radius:6px;transition:color .15s,background .15s}.topbar-action-link:hover{color:var(--dm-text, #eee);background:var(--dm-hover-bg)}.topbar-action-link span[data-icon],.topbar-action-link svg{width:16px;height:16px}.topbar-signout{display:flex;align-items:center;gap:.35rem;font-size:.875rem}.topbar-signout span[data-icon],.topbar-signout svg{width:16px;height:16px}.login-wrap{position:fixed;inset:0;display:flex;align-items:center;justify-content:center;padding:1rem;background:var(--dm-background, #0f1117);z-index:100;overflow-y:auto}.login-card{width:100%;max-width:460px}.ob-done-icon{font-size:3rem;color:var(--dm-success);margin-bottom:1rem;text-align:center}.btn-skip{display:block;text-align:center;margin-top:.75rem;font-size:.85rem;color:var(--dm-text-muted, #888);text-decoration:none}.btn-skip:hover{text-decoration:underline}.theme-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:.6rem}.theme-swatch{border:2px solid var(--dm-border, rgba(255,255,255,.1));border-radius:8px;overflow:hidden;cursor:pointer;transition:border-color .15s,transform .1s}.theme-swatch:hover{border-color:var(--dm-primary, #5b8cff);transform:translateY(-1px)}.theme-swatch.selected{border-color:var(--dm-primary, #5b8cff);box-shadow:0 0 0 2px var(--dm-primary, #5b8cff)}.theme-swatch-preview{height:52px;position:relative;display:flex;align-items:flex-end;padding:.35rem}.theme-swatch-accent{width:28px;height:6px;border-radius:3px}.theme-swatch-label{display:flex;justify-content:space-between;align-items:center;padding:.3rem .45rem;font-size:.7rem;background:var(--dm-card-bg, rgba(255,255,255,.04))}.theme-swatch-mode{color:var(--dm-text-muted, #888);font-size:.65rem}.login-logo{display:flex;align-items:center;gap:.75rem;margin-bottom:1.75rem;font-size:1.5rem}.login-logo span[data-icon]{font-size:2rem;color:var(--dm-primary, #5b8cff)}.login-logo h1{margin:0;font-size:1.5rem;font-weight:700}.login-card [hidden]{display:none!important}.login-heading{font-size:1.1rem;font-weight:600;margin-bottom:1.25rem}.login-rules{margin:.25rem 0 .75rem;padding-left:1.1rem;color:var(--dm-danger);font-size:.85rem}.login-rules li+li{margin-top:.2rem}.login-small{font-size:.8rem;margin-top:.75rem}.login-icon-warn{color:var(--dm-warning)}.pwf{position:relative;display:block}.pwf>input{width:100%;padding-right:2.5rem}.pwf-toggle{position:absolute;top:50%;right:.35rem;transform:translateY(-50%);display:inline-flex;align-items:center;justify-content:center;width:2rem;height:2rem;padding:0;border:0;border-radius:var(--dm-radius-sm);background:transparent;color:var(--dm-text-muted);cursor:pointer}.pwf-toggle:hover,.pwf-toggle:focus-visible{color:var(--dm-text);background:var(--dm-hover-bg)}.pwf-toggle svg{width:16px;height:16px}.pwf-toggle [data-icon=eye-off],.pwf.is-shown .pwf-toggle [data-icon=eye]{display:none}.pwf.is-shown .pwf-toggle [data-icon=eye-off]{display:inline-block}.pwf-caps{display:block;margin-top:.25rem;color:var(--dm-warning);font-size:.8rem}.pwf-caps[hidden]{display:none}.btn-block{width:100%}.plugins-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(300px,1fr));gap:1rem}.plugin-card{display:flex;flex-direction:column;--plugin-accent: var(--dm-primary, #5b8cff);position:relative;overflow:hidden;background-image:radial-gradient(120% 90% at 100% 0%,color-mix(in srgb,var(--plugin-accent) 13%,transparent) 0%,color-mix(in srgb,var(--plugin-accent) 4%,transparent) 42%,transparent 72%)}.plugin-card .plugin-icon{background:color-mix(in srgb,var(--plugin-accent) 16%,transparent);color:var(--plugin-accent)}.plugin-watermark{position:absolute;top:-34px;right:-30px;width:148px;height:148px;display:block;color:var(--plugin-accent);opacity:.09;pointer-events:none;z-index:0}.plugin-card>.card-body,.plugin-card>.plugin-footer{position:relative;z-index:1}.plugin-card:has(.badge-secondary) .plugin-watermark{opacity:.05}@media(prefers-reduced-motion:no-preference){.plugin-card{transition:background-image .2s ease}}.plugin-card .card-body{flex:1}.plugin-header{display:flex;align-items:flex-start;gap:.75rem;margin-bottom:.75rem;flex-wrap:wrap}.plugin-icon{width:40px;height:40px;border-radius:8px;background:color-mix(in srgb,var(--dm-primary) 14%,transparent);color:var(--dm-primary, #5b8cff);display:flex;align-items:center;justify-content:center;flex-shrink:0}.plugin-meta{flex:1 1 140px;min-width:0}.plugin-name{font-weight:600;margin-bottom:.15rem}.plugin-version{font-size:.75rem;color:var(--dm-text-muted, #888)}.plugin-desc{font-size:.875rem;color:var(--dm-text-muted, #888);margin-bottom:1rem}.plugin-footer{display:flex;align-items:center;justify-content:space-between;padding:.75rem 1rem;border-top:1px solid var(--dm-border, rgba(255,255,255,.08))}.plugin-footer-actions{display:flex;align-items:center;gap:.5rem}#admin-sidebar .sidebar-link{position:relative!important}#admin-sidebar .sidebar-badge{position:absolute!important;right:.75rem!important;top:50%!important;transform:translateY(-50%)!important;margin-left:0!important;padding-left:.45rem!important;padding-right:.45rem!important}#admin-sidebar .sidebar-text{padding-right:2rem!important}#admin-sidebar.sidebar-dark{background:var(--dm-surface);border-color:var(--dm-border)}#admin-sidebar.sidebar-dark .sidebar-header{background:var(--dm-surface-raised);border-color:var(--dm-border)}#admin-sidebar.sidebar-dark .sidebar-header-title{color:var(--dm-text)}#admin-sidebar.sidebar-dark .sidebar-link{color:var(--dm-text-muted)}#admin-sidebar.sidebar-dark .sidebar-link:hover{color:var(--dm-text);background:var(--dm-surface-overlay)}#admin-sidebar.sidebar-dark .sidebar-link.active{color:var(--dm-primary);background:color-mix(in srgb,var(--dm-primary) 14%,transparent);border-left-color:var(--dm-primary)}#admin-sidebar.sidebar-dark .sidebar-heading{color:var(--dm-text-muted)}#admin-sidebar.sidebar-dark .sidebar-divider{background:var(--dm-border)}#admin-sidebar.sidebar-dark .sidebar-footer{background:var(--dm-surface-raised);border-color:var(--dm-border)}.sidebar-heading--collapsible{display:flex!important;align-items:center;justify-content:space-between;cursor:pointer;user-select:none}.sidebar-heading-toggle{display:flex;align-items:center;opacity:.5;flex-shrink:0;transition:transform .2s ease}.sidebar-heading--collapsible.is-collapsed .sidebar-heading-toggle{transform:rotate(-90deg)}.mt-3{margin-top:.75rem}.mt-4{margin-top:1rem}.mb-2{margin-bottom:.5rem}.mb-3{margin-bottom:.75rem}.mb-4{margin-bottom:1rem}.p-0{padding:0!important}.text-muted{color:var(--dm-text-muted, #888)}@media(max-width:768px){.view-container{padding:1rem}.editor-body{flex-direction:column}.editor-divider{width:auto;height:1px;cursor:default;background:var(--dm-border, rgba(255,255,255,.08))}}.image-editor{display:flex;flex-direction:column;gap:0}.image-editor-toolbar{display:flex;flex-direction:row;align-items:center;gap:.25rem;padding:.5rem .75rem;border-bottom:1px solid var(--dm-border, rgba(255, 255, 255, .1))}.image-editor-sep{display:inline-block;width:1px;height:1.5rem;background:var(--dm-border, rgba(255, 255, 255, .15));margin:0 .25rem;flex-shrink:0}.editor-toolbar-btn.active{color:var(--dm-primary, #7c6af7);background:color-mix(in srgb,var(--dm-primary, #7c6af7) 15%,transparent)}.editor-toolbar-caret{font-size:.6rem;line-height:1;margin-left:2px;opacity:.6}.editor-toolbar-dropdown{position:absolute;z-index:1000;background:var(--dm-surface, #1e1e2e);border:1px solid var(--dm-border, rgba(255, 255, 255, .1));border-radius:8px;box-shadow:0 8px 24px #0006;padding:4px;min-width:160px;max-height:70vh;overflow-y:auto}.editor-toolbar-dropdown-heading{padding:6px 10px 3px;color:var(--dm-text-muted, #8a8a9a);font-size:.66rem;text-transform:uppercase;letter-spacing:.06em}.editor-toolbar-dropdown-item{display:flex;align-items:center;gap:8px;width:100%;text-align:left;background:none;border:none;color:var(--dm-text, #ddd);padding:7px 10px;border-radius:5px;cursor:pointer;font-size:.85rem;transition:background .12s,color .12s}.editor-toolbar-dropdown-item:hover{background:var(--dm-hover-bg);color:var(--dm-text, #fff)}.editor-toolbar-dropdown-item span[data-icon],.editor-toolbar-dropdown-item svg{width:15px;height:15px;flex-shrink:0;opacity:.75}.editor-toolbar{position:relative}.editor-effects-dropdown-menu{position:absolute;top:100%;z-index:1000;background:var(--dm-surface, #1e1e2e);border:1px solid var(--dm-border, rgba(255, 255, 255, .1));border-radius:8px;box-shadow:0 8px 24px #0006;padding:6px;min-width:180px;max-height:340px;overflow-y:auto}.editor-effects-category{padding:6px 8px 3px;font-size:.7rem;font-weight:700;letter-spacing:.07em;text-transform:uppercase;color:var(--dm-text-muted, #888)}.editor-effects-item{display:block;width:100%;text-align:left;background:none;border:none;color:var(--dm-text, #ddd);padding:6px 10px;border-radius:5px;cursor:pointer;font-size:.85rem;transition:background .12s,color .12s}.editor-effects-item:hover{background:var(--dm-hover-bg);color:var(--dm-text, #fff)}.editor-icon-picker{position:absolute;z-index:1000;background:var(--dm-surface, #1e1e2e);border:1px solid var(--dm-border, rgba(255, 255, 255, .1));border-radius:8px;box-shadow:0 8px 24px #0006;padding:8px;width:320px}.editor-icon-picker-search{width:100%;margin-bottom:8px;font-size:.8rem}.editor-spacer-picker{position:absolute;z-index:9999;background:var(--dm-surface, #1e1e2e);border:1px solid var(--dm-border, #333);border-radius:8px;padding:12px;width:240px;box-shadow:0 8px 24px #00000073}.editor-spacer-picker-label{font-size:11px;font-weight:600;text-transform:uppercase;letter-spacing:.05em;color:var(--dm-text-muted, #888);margin-bottom:10px}.editor-spacer-picker-row{display:flex;align-items:center;gap:10px;margin-bottom:12px}.editor-spacer-slider{flex:1;accent-color:var(--dm-primary, #6366f1);cursor:pointer}.editor-spacer-slider-value{font-size:13px;font-weight:600;min-width:38px;text-align:right;color:var(--dm-text, #cdd6f4)}.editor-spacer-insert-btn{width:100%}.editor-icon-picker-size-row{display:flex;align-items:center;gap:8px;padding:0 8px 8px}.editor-icon-picker-size-row label{font-size:11px;color:var(--dm-text-muted, #888);white-space:nowrap}.editor-icon-picker-size{width:70px;font-size:12px;padding:3px 6px}.editor-icon-picker-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(52px,1fr));gap:2px;max-height:280px;overflow-y:auto}.editor-icon-picker-item{display:flex;flex-direction:column;align-items:center;justify-content:center;padding:6px 2px;border-radius:5px;cursor:pointer;background:none;border:none;color:var(--dm-text, #ddd);font-size:.58rem;text-align:center;gap:4px;overflow:hidden;transition:background .12s,color .12s}.editor-icon-picker-item:hover{background:var(--dm-hover-bg);color:var(--dm-text, #fff)}.editor-icon-picker-item span[data-icon],.editor-icon-picker-item svg{width:16px;height:16px;flex-shrink:0}.editor-icon-picker-item>span:last-child{max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;line-height:1.2}.editor-icon-picker-empty{grid-column:1 / -1;text-align:center;color:var(--dm-text-muted, #888);font-size:.8rem;padding:1.5rem}.image-editor-canvas{min-height:320px;max-height:520px;background:#111;overflow:hidden;display:flex;align-items:center;justify-content:center}.image-editor-canvas img{display:block;max-width:100%;max-height:520px}.image-editor-resize{display:flex;flex-direction:row;align-items:center;gap:.5rem;padding:.6rem .75rem;border-top:1px solid var(--dm-border, rgba(255, 255, 255, .1));font-size:.85rem}.image-editor-resize label{font-weight:600;color:var(--dm-text-muted, #888);font-size:.8rem}.image-editor-resize .form-input{width:5rem;padding:.25rem .5rem;font-size:.85rem}.image-editor-footer{display:flex;flex-direction:row;align-items:center;justify-content:space-between;padding:.75rem;border-top:1px solid var(--dm-border, rgba(255, 255, 255, .1));gap:.5rem}.image-editor-effects{border-top:1px solid var(--dm-border, rgba(255, 255, 255, .1))}.image-editor-tab-bar{display:flex;flex-direction:row;overflow-x:auto;border-bottom:1px solid var(--dm-border, rgba(255, 255, 255, .1));scrollbar-width:none}.image-editor-tab-bar::-webkit-scrollbar{display:none}.image-editor-tab-btn{display:inline-flex;align-items:center;gap:.35rem;padding:.5rem .85rem;font-size:.8rem;font-weight:500;border:none;border-bottom:2px solid transparent;background:transparent;cursor:pointer;color:var(--dm-text-muted, #888);white-space:nowrap;transition:color .15s,border-color .15s;flex-shrink:0}.image-editor-tab-btn:hover{color:var(--dm-text, #eee)}.image-editor-tab-btn.active{color:var(--dm-primary, #7c6af7);border-bottom-color:var(--dm-primary, #7c6af7)}.image-editor-tab-panel{padding:.75rem;max-height:200px;overflow-y:auto}.ie-presets-grid{display:flex;flex-wrap:wrap;gap:.35rem;margin-bottom:.5rem}.ie-preset-btn.active{color:var(--dm-primary, #7c6af7);background:color-mix(in srgb,var(--dm-primary, #7c6af7) 15%,transparent);border-color:var(--dm-primary, #7c6af7)}.ie-server-note{font-size:.73rem;color:var(--dm-text-muted, #888);font-style:italic;margin:.25rem 0 0;line-height:1.4}.ie-slider-row{display:flex;align-items:center;gap:.5rem;margin-bottom:.4rem}.ie-slider-label{width:6rem;font-size:.8rem;color:var(--dm-text-muted, #888);font-weight:600;flex-shrink:0}.ie-slider{flex:1;accent-color:var(--dm-primary, #7c6af7);cursor:pointer}.ie-slider-val{width:3rem;font-size:.8rem;text-align:right;color:var(--dm-text, #eee);flex-shrink:0}.ie-select{flex:1;font-size:.85rem;padding:.25rem .5rem}.ie-colour-input{width:40px;height:28px;padding:0;border:1px solid var(--dm-border, rgba(255, 255, 255, .15));border-radius:4px;cursor:pointer;background:transparent;flex-shrink:0}.ie-wm-preview-row{display:flex;align-items:center;gap:.5rem;margin:.4rem 0}.ie-wm-preview-img{width:48px;height:48px;object-fit:contain;border-radius:4px;background:var(--dm-surface-raised, rgba(255, 255, 255, .06));flex-shrink:0}.ie-wm-preview-name{font-size:.8rem;flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--dm-text, #eee)}.ie-media-picker{padding:.25rem 0}.ie-media-picker-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(80px,1fr));gap:.5rem;max-height:300px;overflow-y:auto}.ie-media-thumb{display:flex;flex-direction:column;align-items:center;gap:.25rem;padding:.4rem;border-radius:6px;cursor:pointer;border:2px solid transparent;transition:border-color .15s,background .15s}.ie-media-thumb:hover{background:var(--dm-surface-raised, rgba(255, 255, 255, .08));border-color:var(--dm-primary, #7c6af7)}.ie-media-thumb img{width:72px;height:72px;object-fit:cover;border-radius:4px}.ie-media-thumb-name{font-size:.7rem;color:var(--dm-text-muted, #888);text-align:center;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:72px}.dm-slideover-left,.dm-slideover-right{width:min(40rem,95vw)!important;min-width:min(36rem,100vw)!important;max-width:100vw!important}.dm-slideover-resizer{position:absolute;top:0;bottom:0;width:6px;cursor:col-resize;z-index:2;background:transparent}.dm-slideover-right>.dm-slideover-resizer{left:0}.dm-slideover-left>.dm-slideover-resizer{right:0}.dm-slideover-resizer:hover,.is-resizing>.dm-slideover-resizer{background:var(--dm-primary);opacity:.7}.dm-slideover.is-resizing{user-select:none;transition:none!important}.dm-slideover-header{display:flex;align-items:center;justify-content:space-between;padding:1rem 1.25rem;border-bottom:1px solid var(--dm-border, #333);flex-shrink:0}.dm-slideover-title{margin:0;font-size:1rem;font-weight:600}.dm-slideover-close{padding:.2rem .35rem!important;line-height:1;font-size:.75rem}.dm-slideover-body{flex:1;overflow:auto;overscroll-behavior:contain;min-height:0;padding:1.5rem!important;box-sizing:border-box}.dm-slideover-body:empty{flex:0 0 auto;padding:0!important}.dm-slideover>div:not(.dm-slideover-header):not(.dm-slideover-body):not(.dm-slideover-close){padding:1.5rem!important;box-sizing:border-box;flex:1 1 auto;min-height:0;overflow:auto;overscroll-behavior:contain}.dm-slideover-body,.dm-slideover>div:not(.dm-slideover-header):not(.dm-slideover-close){scrollbar-width:thin;scrollbar-color:var(--dm-border) transparent}.dm-slideover-body::-webkit-scrollbar,.dm-slideover>div:not(.dm-slideover-header):not(.dm-slideover-close)::-webkit-scrollbar{width:8px;height:8px}.dm-slideover-body::-webkit-scrollbar-track,.dm-slideover>div:not(.dm-slideover-header):not(.dm-slideover-close)::-webkit-scrollbar-track{background:transparent}.dm-slideover-body::-webkit-scrollbar-thumb,.dm-slideover>div:not(.dm-slideover-header):not(.dm-slideover-close)::-webkit-scrollbar-thumb{background:var(--dm-border);border-radius:4px}.dm-slideover-body::-webkit-scrollbar-thumb:hover,.dm-slideover>div:not(.dm-slideover-header):not(.dm-slideover-close)::-webkit-scrollbar-thumb:hover{background:var(--dm-text-muted)}.dm-slideover-body>div{padding-left:0!important;padding-right:0!important}.dm-slideover-body>button.btn:last-child{margin-top:.5rem}.dconfig-textarea{font-family:monospace;min-height:100px;resize:vertical}.dm-editor-line-numbers{white-space:pre}.dm-code-inline{font-family:Fira Code,Courier New,monospace;font-size:.82em;padding:.15em .35em;border-radius:3px;background:var(--dm-background-alt, rgba(0, 0, 0, .18));color:var(--dm-text, inherit);border:1px solid var(--dm-border, rgba(255, 255, 255, .08))}.dm-code-block{font-family:Fira Code,Courier New,monospace;font-size:.82rem;line-height:1.6;padding:.65rem .9rem;border-radius:6px;background:var(--dm-background-alt, rgba(0, 0, 0, .18));color:var(--dm-text, inherit);border:1px solid var(--dm-border, rgba(255, 255, 255, .08));white-space:pre;overflow-x:auto;display:block;margin:.4rem 0}.tabs-centered{text-align:center}.tabs-centered .tab-list{display:inline-flex}.tabs-centered .tab-content{text-align:left}@media(max-width:768px){.view-header{flex-direction:column;align-items:flex-start}.theme-grid{grid-template-columns:repeat(2,1fr)}.nav-item-row{flex-wrap:wrap}.nav-col-icon,.nav-col-parent{display:none}#admin-topbar{padding:0 .75rem}.topbar-brand-text{display:none}.image-editor-toolbar{flex-wrap:wrap}}#topbar-bell{position:relative}.topbar-action-link[hidden],.topbar-bell-badge[hidden]{display:none}.topbar-bell-badge{position:absolute;top:2px;right:2px;min-width:16px;height:16px;padding:0 4px;background:var(--dm-danger, #dc2626);color:var(--dm-danger-text, #fff);font-size:10px;font-weight:700;line-height:16px;border-radius:9999px;text-align:center;pointer-events:none}.cb-scaffolder{padding:1rem 1.1rem;background:var(--dm-background-alt);border:1px solid var(--dm-primary);border-radius:8px;color:var(--dm-text)}.cb-scaffolder-head{display:flex;align-items:center;gap:.5rem;margin-bottom:.5rem}.cb-scaffolder-head .cb-icon{flex-shrink:0;color:var(--dm-primary)}.cb-scaffolder-head h2{margin:0;font-size:1.05rem;font-weight:700;color:var(--dm-text)}.cb-scaffolder-blurb{margin:0 0 .75rem;font-size:.88rem;line-height:1.5;color:var(--dm-text-muted)}.cb-recipe-list{display:flex;flex-direction:column;gap:.5rem}.cb-recipe-card{display:flex;align-items:flex-start;gap:.75rem;text-align:left;padding:.75rem 1rem;background:var(--dm-surface);border:1px solid var(--dm-border);border-radius:6px;cursor:pointer;transition:border-color .12s;width:100%;color:var(--dm-text)}.cb-recipe-card:hover{border-color:var(--dm-primary)}.cb-recipe-card .cb-icon{flex-shrink:0;font-size:1.5rem;color:var(--dm-primary);margin-top:.1rem}.cb-recipe-meta{flex:1}.cb-recipe-name{font-weight:600;margin-bottom:.15rem;font-size:.95rem;color:var(--dm-text)}.cb-recipe-desc{font-size:.83rem;line-height:1.45;color:var(--dm-text-muted)}.cb-apply-panel{padding:1rem 1.1rem;background:var(--dm-surface);border:1px solid var(--dm-primary);border-radius:8px;color:var(--dm-text)}.cb-apply-head{display:flex;align-items:center;gap:.5rem;margin-bottom:.5rem}.cb-apply-head .cb-icon{color:var(--dm-primary);font-size:1.4rem}.cb-apply-head h3{margin:0;font-size:1rem;font-weight:600;color:var(--dm-text)}.cb-apply-desc,.cb-apply-hint{margin:.25rem 0 .75rem;font-size:.85rem;line-height:1.5;color:var(--dm-text-muted)}.cb-apply-hint{font-size:.75rem;margin-top:.2rem}.cb-apply-field{margin-bottom:.6rem}.cb-apply-field label{display:block;font-size:.82rem;font-weight:600;margin-bottom:.2rem;color:var(--dm-text)}.cb-apply-field input{width:100%;padding:.4rem .55rem;border:1px solid var(--dm-border);border-radius:4px;font-size:.88rem;background:var(--dm-surface);color:var(--dm-text)}.cb-apply-status{margin:.5rem 0;font-size:.85rem;min-height:1.2rem;color:var(--dm-text)}.cb-apply-status.cb-error{color:var(--dm-danger, #dc2626)}.cb-apply-buttons{display:flex;gap:.5rem;justify-content:flex-end;margin-top:.5rem}.cb-success-panel{padding:1rem 1.1rem;background:var(--dm-surface);border:1px solid var(--dm-success, #16a34a);border-radius:8px;color:var(--dm-text)}.cb-success-panel .cb-icon{color:var(--dm-success, #16a34a);font-size:1.4rem}.cb-success-summary{margin:.25rem 0 .5rem;padding-left:1.2rem;font-size:.86rem;line-height:1.6;color:var(--dm-text)}.cb-success-warning{margin:.5rem 0;padding:.5rem .75rem;background:var(--dm-background-alt);border-left:3px solid var(--dm-warning, #eab308);border-radius:0 4px 4px 0;font-size:.82rem;color:var(--dm-text-muted)}.cb-success-snippet-label{margin:0 0 .25rem;font-size:.82rem;font-weight:600;color:var(--dm-text)}.cb-success-actions{display:flex;gap:.5rem;margin-top:.5rem;flex-wrap:wrap}.cb-code{position:relative}.cb-code pre{background:var(--dm-background-alt);color:var(--dm-text);display:block;padding:.6rem 2.4rem .6rem .75rem;white-space:pre;overflow-x:auto;margin:0;border-radius:6px;font-size:.82em;font-family:monospace;line-height:1.45}.cb-code .cb-copy{position:absolute;top:.35rem;right:.35rem;background:none;border:none;cursor:pointer;opacity:.45;padding:.2rem;line-height:1;color:var(--dm-text)}.cb-code .cb-copy:hover{opacity:1}.cb-intro{padding:.75rem 1rem;border-left:3px solid var(--dm-primary);background:var(--dm-background-alt);border-radius:0 6px 6px 0}.cb-intro p{margin:0;font-size:.92rem;line-height:1.5;color:var(--dm-text)}.cb-tutorial-link{display:flex;align-items:center;gap:.6rem;padding:.65rem .85rem;border:1px solid var(--dm-border);border-radius:6px;text-decoration:none;color:var(--dm-text);font-size:.88rem;transition:border-color .12s}.cb-tutorial-link:hover{border-color:var(--dm-primary)}.cb-tutorial-link .cb-icon{flex-shrink:0;color:var(--dm-primary)}.cb-tutorial-link .cb-arrow{color:var(--dm-text-muted);font-size:1.1rem;margin-left:auto}.menu-tree-row{display:grid;grid-template-columns:26px 1.4fr 1.4fr .9fr .7fr .9fr repeat(6,auto);gap:6px;align-items:center;padding:4px 0;transition:opacity .15s ease}.menu-tree-row--hidden{opacity:.5}.menu-tree-row--tool .me-tool-badge{margin-left:.4rem;font-size:.7rem;vertical-align:middle}.menu-tree-row--default .me-row-label{font-style:italic;opacity:.8}.menu-tree-grip{cursor:grab;color:var(--dm-text-muted)}.menu-tree-grip:hover{color:var(--dm-text)}.menu-tree{padding:8px 0}.menu-tree-row--separator{display:grid;grid-template-columns:26px minmax(80px,1fr) repeat(7,auto);gap:6px;align-items:center;padding:2px 0;opacity:.85}.menu-tree-row--separator:hover{opacity:1}.menu-tree-row--separator .me-sep-line{display:flex;align-items:center;gap:10px;width:100%}.menu-tree-row--separator .me-sep-line:before,.menu-tree-row--separator .me-sep-line:after{content:"";flex:1;border-top:1px dashed var(--dm-border, rgba(128, 128, 128, .55))}.menu-tree-row--separator .me-sep-label{font-size:.66rem;font-weight:700;letter-spacing:.09em;text-transform:uppercase;color:var(--dm-text-muted, #8a8a8a);white-space:nowrap}.dm-admin-sidebar .sidebar-divider{border:0;border-top:1px solid var(--dm-border, rgba(128, 128, 128, .5));margin:.5rem .75rem;opacity:.8}.dm-admin-sidebar .sidebar-spacer--xs{height:var(--dm-space-1, .25rem)}.dm-admin-sidebar .sidebar-spacer--sm{height:var(--dm-space-2, .5rem)}.dm-admin-sidebar .sidebar-spacer--md{height:var(--dm-space-4, 1rem)}.dm-admin-sidebar .sidebar-spacer--lg{height:var(--dm-space-6, 1.5rem)}.dm-admin-sidebar .sidebar-spacer--xl{height:var(--dm-space-10, 2.5rem)}.dm-admin-sidebar .sidebar-spacer--flex{flex:1 1 auto;min-height:var(--dm-space-4, 1rem)}.dm-admin-sidebar--has-flex-spacer{display:flex;flex-direction:column;min-height:100%}.menu-tree-row--spacer{display:grid;grid-template-columns:26px minmax(80px,1fr) repeat(7,auto);gap:6px;align-items:center;padding:2px 0;opacity:.85}.menu-tree-row--spacer:hover{opacity:1}.menu-tree-row--spacer .me-spacer-line{display:flex;align-items:center;gap:8px;width:100%}.menu-tree-row--spacer .me-spacer-line:before,.menu-tree-row--spacer .me-spacer-line:after{content:"";flex:1;border-top:1px dotted var(--dm-border, rgba(128, 128, 128, .55))}.menu-tree-row--spacer .me-spacer-label{font-size:.66rem;font-weight:700;letter-spacing:.09em;text-transform:uppercase;color:var(--dm-text-muted, #8a8a8a);white-space:nowrap}.menu-tree-row--spacer .me-spacer-size{width:auto;min-width:5.5rem;height:26px;padding:0 .35rem;font-size:.75rem}.menu-tree-row .me-icon-wrap{display:flex;gap:2px}.menu-tree-row .me-icon-wrap .me-icon{flex:1;min-width:0}.menu-tree-row .me-icon-wrap .me-icon-pick{flex-shrink:0;padding:.2rem .45rem;font-size:.85em}.dm-admin-sidebar{display:flex;flex-direction:column;gap:2px;padding:8px 0;font-size:.875rem}.dm-admin-sidebar details{margin:0}.dm-admin-sidebar details>summary{list-style:none;cursor:pointer;display:flex;align-items:center;gap:.5rem;padding:.4rem .75rem;border-radius:4px;user-select:none;font-size:.78rem;font-weight:600;text-transform:uppercase;letter-spacing:.05em;color:var(--dm-text-muted, #888)}.dm-admin-sidebar details details>summary{font-size:.875rem;font-weight:500;text-transform:none;letter-spacing:0;color:inherit}.dm-admin-sidebar .dm-menu-badge{font-size:.7rem;font-weight:600}.dm-admin-sidebar details>summary::-webkit-details-marker{display:none}.dm-admin-sidebar details>summary:after{content:"\25b8";margin-left:auto;transition:transform .15s ease;color:var(--dm-text-muted, #999);font-size:.85em}.dm-admin-sidebar details[open]>summary:after{transform:rotate(90deg)}.dm-admin-sidebar details>div{padding-left:1rem;border-left:1px solid var(--dm-border-light, rgba(0, 0, 0, .08));margin-left:.95rem}.dm-admin-sidebar .sidebar-link{display:flex;align-items:center;gap:.5rem;padding:.35rem .75rem;text-decoration:none;color:var(--dm-text, inherit);border-radius:4px}.dm-admin-sidebar .sidebar-link:hover,.dm-admin-sidebar details>summary:hover{background:var(--dm-hover-bg, rgba(0, 0, 0, .05))}.dm-admin-sidebar .sidebar-link.active{background:var(--dm-active-bg, rgba(0, 0, 0, .08));font-weight:600}.dm-admin-sidebar .sidebar-text{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.dm-admin-sidebar [data-icon]{flex-shrink:0}.dm-admin-sidebar-header{position:sticky;top:0;z-index:2;background:var(--dm-surface);display:flex;align-items:center;gap:.5rem;padding:.65rem .85rem;margin:0 0 .5rem;font-weight:600;font-size:.95rem;letter-spacing:.01em;color:var(--dm-text, inherit);border-bottom:1px solid var(--dm-border-light, rgba(0, 0, 0, .08))}.dm-admin-sidebar--dark .dm-admin-sidebar-header{background:#1a1d24}.dm-admin-sidebar--light .dm-admin-sidebar-header{background:#fff}.dm-admin-sidebar-header [data-icon]{color:var(--dm-text-muted, #999)}.dm-admin-sidebar-header .dm-admin-sidebar-arrange{margin-left:auto;padding:.2rem .35rem;color:var(--dm-text-muted, #999);line-height:1}.dm-admin-sidebar-header .dm-admin-sidebar-arrange:hover,.dm-admin-sidebar-header .dm-admin-sidebar-arrange:focus-visible{color:var(--dm-text)}.dm-admin-sidebar.is-arranging>:not(.dm-admin-sidebar-header):not(.sb-arrange):not(style){display:none!important}.dm-admin-sidebar.is-arranging .dm-admin-sidebar-arrange{display:none}.sb-arrange{box-sizing:border-box;max-width:100vw;padding:0 .5rem 1rem;animation:sb-arrange-in .18s cubic-bezier(.2,.8,.2,1)}@keyframes sb-arrange-in{0%{opacity:0;transform:translateY(-4px)}to{opacity:1;transform:none}}.sb-arrange-bar{position:sticky;top:2.6rem;z-index:2;display:flex;align-items:center;gap:.4rem;padding:.4rem .25rem;background:inherit}.sb-arrange-title{font-weight:600;margin-right:auto}.sb-arrange-hint{margin:0 .25rem .5rem;font-size:.78rem;line-height:1.35;color:var(--dm-text-muted)}.sb-arr-row{display:flex;align-items:center;gap:.45rem;padding:.35rem .4rem .35rem calc(.4rem + var(--sb-arr-depth, 0) * 1rem);border-radius:var(--dm-radius-sm, 4px);cursor:grab;user-select:none;font-size:.9rem}.sb-arr-row:hover{background:color-mix(in srgb,var(--dm-text) 6%,transparent)}.sb-arr-row:focus-visible{outline:2px solid var(--dm-primary);outline-offset:-2px}.sb-arr-row--folder .sb-arr-text{font-weight:600}.sb-arr-row--hidden .sb-arr-text,.sb-arr-row--hidden .sb-arr-icon{opacity:.45;text-decoration:line-through}.sb-arr-row--structural .sb-arr-text{font-size:.75rem;text-transform:uppercase;letter-spacing:.05em;color:var(--dm-text-muted)}.sb-arr-grip{color:var(--dm-text-muted);flex:none}.sb-arr-icon{width:16px;flex:none}.sb-arr-text{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.sb-arr-hide{flex:none;display:inline-flex;padding:.15rem;border:0;border-radius:var(--dm-radius-sm, 4px);background:transparent;color:var(--dm-text-muted);cursor:pointer}.sb-arr-hide:hover,.sb-arr-hide:focus-visible{color:var(--dm-text);background:color-mix(in srgb,var(--dm-text) 8%,transparent)}.sb-arr-lock{flex:none;color:var(--dm-text-muted);opacity:.6}.dm-admin-sidebar .sidebar-badge{margin-left:auto;padding:0 .4rem;min-width:1.25rem;height:1.1rem;line-height:1.1rem;text-align:center;font-size:.7rem;font-weight:600;border-radius:999px;background:var(--dm-active-bg, rgba(0, 0, 0, .12));color:var(--dm-text-muted, #888)}.dm-admin-sidebar .sidebar-link.active .sidebar-badge{background:var(--dm-primary, #4a86e8);color:var(--dm-primary-text, #fff)}.dm-admin-sidebar .sidebar-children{overflow:hidden;transition:max-height .22s ease,opacity .18s ease}.dm-admin-sidebar details:not([open])>.sidebar-children{opacity:0}.dm-admin-sidebar{position:relative}.dm-admin-sidebar-handle{position:absolute;top:0;right:0;width:6px;height:100%;cursor:col-resize;background:transparent;z-index:10;transition:background .15s}.dm-admin-sidebar-handle:hover,.dm-admin-sidebar-handle:active{background:var(--dm-primary, #4a86e8);opacity:.35}.dm-admin-sidebar--dark{background:#1a1d24;color:#e3e6eb}.dm-admin-sidebar--dark .sidebar-link,.dm-admin-sidebar--dark summary{color:#e3e6eb}.dm-admin-sidebar--dark .sidebar-link:hover,.dm-admin-sidebar--dark details>summary:hover{background:#ffffff0f}.dm-admin-sidebar--dark .sidebar-link.active{background:#4a86e840}.dm-admin-sidebar--dark .sidebar-badge{background:#ffffff1f;color:#cbd0d8}.dm-admin-sidebar--light{background:#fff;color:#1a1d24;border-right:1px solid rgba(0,0,0,.08)}.dm-admin-sidebar--light .sidebar-link,.dm-admin-sidebar--light summary{color:#1a1d24}.dm-admin-sidebar--light .sidebar-link:hover,.dm-admin-sidebar--light details>summary:hover{background:#0000000a}.dm-admin-sidebar--light .sidebar-link.active{background:#4a86e826}.dm-admin-sidebar--transparent{background:transparent}.page-header{display:flex;align-items:center;justify-content:space-between;gap:1rem;flex-wrap:wrap;margin:0 0 1.25rem;padding-bottom:.75rem;border-bottom:1px solid var(--dm-border-light, rgba(0, 0, 0, .08))}.page-header h2{margin:0;display:flex;align-items:center;gap:.5rem;font-size:1.4rem;line-height:1.2}.page-header h2 [data-icon]{color:var(--dm-text-muted, #888)}.header-actions{display:flex;align-items:center;gap:.5rem;flex-wrap:wrap}.card+.card,.card+p,p+.card,.card+.toolbar,.toolbar+.card,.card+.grid{margin-top:1rem}.toolbar{display:flex;align-items:center;gap:.5rem;flex-wrap:wrap;margin:0 0 1rem}.btn+.btn,.btn+a.btn,a.btn+.btn,a.btn+a.btn{margin-left:.35rem}[style*=inline-flex] .btn+.btn,[style*=inline-flex] .btn+a.btn,[style*=inline-flex] a.btn+.btn{margin-left:0}.card-body>[id$=-form],.card-body>form{margin:.25rem 0}.card-header{display:flex;align-items:center;gap:.5rem}.card-header h3{margin:0;font-size:1.05rem}.card-header [data-icon]{color:var(--dm-text-muted, #888)}.page-header+p.text-muted{margin:-.5rem 0 1rem}.dm-pe-grid{gap:.75rem 1rem}.dm-pe-grid .form-group{display:flex;flex-direction:column;gap:.25rem;margin:0}.dm-pe-grid .form-group.col-span-2{grid-column:1 / -1}.dm-pe-grid label{font-size:.85rem;font-weight:600;color:var(--dm-text, inherit)}.dm-pe-grid label .required{color:var(--dm-danger, #c33);margin-left:2px}.dm-pe-grid .form-hint{font-size:.75rem;color:var(--dm-text-muted, #888);margin-top:.1rem}.dm-pe-grid .form-input{width:100%;padding:.4rem .6rem}.dm-pe-grid textarea.form-input{resize:vertical;min-height:2.5rem}.dm-menu-badge{display:inline-block;margin-left:6px;padding:1px 7px;font-size:.7em;font-weight:700;line-height:1.4;border-radius:999px;background:var(--dm-text-muted);color:var(--dm-text-inverse, #fff);vertical-align:middle}.menu-tree-row--slim{display:grid;grid-template-columns:26px 1fr auto repeat(9,auto);gap:6px;align-items:center}.menu-tree-row--slim .me-row-label{font-weight:600}.menu-tree-row--slim .me-row-url{color:var(--dm-text-muted);font-size:.85em}.me-pages-picker{display:flex;gap:6px;align-items:center;margin-bottom:6px}.me-pages-picker .form-input{flex:1;min-width:0}.me-colour-control{display:flex;gap:6px;align-items:center}.me-colour-control .me-colour-hex{width:48px;height:32px;padding:2px;flex:none}.me-bind-summary{padding:.6rem .8rem;border:1px solid var(--dm-border, rgba(128, 128, 128, .35));border-radius:var(--dm-radius-md, 6px);background:color-mix(in srgb,var(--dm-text) 4%,transparent);font-size:.9em}.me-bind-summary code{font-size:.9em}.me-item-form{display:flex;flex-direction:column;gap:10px;padding:4px 2px}.me-item-form .form-field{display:flex;flex-direction:column;gap:4px}.me-item-form .form-label{font-size:.85em;color:var(--dm-text-muted)}.me-form-section{margin:12px 0 2px;padding-top:10px;border-top:1px solid var(--dm-border-light, rgba(0,0,0,.15));font-size:.78em;text-transform:uppercase;letter-spacing:.06em;color:var(--dm-text-muted)}.me-item-form .me-form-section:first-child{margin-top:0;padding-top:0;border-top:0}.me-item-form .me-colour-hex{width:48px;height:32px;padding:2px}.me-item-form .me-field-grid{display:grid;grid-template-columns:1fr 1fr;gap:10px}.me-item-form .me-field-grid .form-field{margin:0}.me-item-form .me-icon-field{display:flex;align-items:center;gap:8px}.me-item-form .me-icon-field .form-input{flex:1}.me-item-form .me-icon-preview{width:24px;height:24px;flex:0 0 auto;display:inline-flex;align-items:center;justify-content:center;color:var(--dm-text-muted)}#admin-sidebar.dm-menu-floating{border:1px solid var(--dm-border);border-radius:var(--dm-radius-md, 8px);box-shadow:var(--dm-shadow-lg);overflow:hidden}@media(max-width:768px){#admin-sidebar.dm-menu-floating{position:static!important;inset:auto!important;max-height:none!important;transform:none!important}.dashboard-wrapper{padding-left:0!important;padding-right:0!important}}[data-logic-section]{border:1px solid var(--dm-border);border-radius:var(--dm-radius-md, 6px);padding:.9rem 1rem 1rem;margin-bottom:1rem;background:color-mix(in srgb,var(--dm-text) 3%,transparent)}[data-logic-section] .fb-logic-cond-row,[data-logic-section] .fb-logic-val-rule{padding:.55rem .65rem;border-radius:var(--dm-radius-sm, 4px);border:1px solid var(--dm-border);background:var(--dm-surface, transparent)}[data-logic-section] .fb-logic-cond-row:last-of-type,[data-logic-section] .fb-logic-val-rule:last-of-type{margin-bottom:.75rem}[data-logic-section]>.btn{margin-top:.15rem}[data-logic-section] textarea{min-height:5rem}.project-filter-notice{display:flex;align-items:center;gap:.4rem;flex-wrap:wrap;margin:0 0 1rem;padding:.6rem .85rem;border:1px solid var(--dm-border);border-left:3px solid var(--dm-info, var(--dm-primary));border-radius:var(--dm-radius-md, 6px);background:color-mix(in srgb,var(--dm-info, var(--dm-primary)) 6%,transparent);font-size:.85rem;color:var(--dm-text-muted)}.project-filter-notice a{color:var(--dm-primary);font-weight:600}.ctx-help{display:inline-flex;align-items:center;justify-content:center;width:1.05rem;height:1.05rem;margin-left:.35rem;padding:0;border:1px solid var(--dm-border-dark, var(--dm-border));border-radius:var(--dm-radius-full, 9999px);background:transparent;color:var(--dm-text-muted);font-size:.68rem;font-weight:700;line-height:1;cursor:pointer;vertical-align:middle;flex-shrink:0}.ctx-help:hover,.ctx-help:focus-visible{border-color:var(--dm-primary);color:var(--dm-primary);outline:none}.card-header h3 .ctx-help{align-self:center}.ctx-preview-card{position:sticky;top:1rem}@media(max-width:1100px){.ctx-workspace>.col-8,.ctx-workspace>.col-4{flex:0 0 auto;width:100%}.ctx-preview-card{position:static}}.dm-plugin-shell{border:1px solid var(--dm-border);border-radius:var(--dm-radius-lg, 12px);background:var(--dm-surface);overflow:hidden}.dm-plugin-banner{display:flex;align-items:center;justify-content:space-between;gap:1rem;flex-wrap:wrap;padding:.7rem 1rem;background:var(--dm-background-alt);border-bottom:1px solid var(--dm-border)}.dm-plugin-banner-identity{display:flex;align-items:center;gap:.55rem;min-width:0;margin-right:auto}.dm-plugin-banner-actions{display:flex;align-items:center;gap:.25rem;flex:0 0 auto;margin-right:.15rem;padding-right:.4rem;border-right:1px solid var(--dm-border)}.dm-plugin-banner-action{padding:.25rem .4rem;line-height:1;color:var(--dm-text-muted)}.dm-plugin-banner-action:hover{color:var(--dm-primary)}.dm-plugin-banner-icon{display:inline-flex;align-items:center;color:var(--dm-primary);flex:0 0 auto}.dm-plugin-banner-name{margin:0;font-size:1.05rem;font-weight:600;letter-spacing:.01em;color:var(--dm-text);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.dm-activity{display:inline-flex;align-items:center;flex:0 0 auto;margin-left:.35rem}.dm-activity domma-loader{display:inline-block;line-height:0}.dm-activity[hidden]{display:none!important}#admin-topbar>.dm-activity{margin:0 .75rem 0 0}.dm-plugin-banner-parent{font-weight:500;color:var(--dm-text-muted)}.dm-plugin-banner-sep{margin:0 .4rem;color:var(--dm-text-muted)}.dm-plugin-banner-facts{display:flex;align-items:center;gap:.4rem;flex-wrap:wrap}.dm-plugin-fact{font-size:.72rem;line-height:1.6;padding:1px 8px;border-radius:999px;border:1px solid var(--dm-border);color:var(--dm-text-muted);background:var(--dm-surface);white-space:nowrap}.dm-plugin-fact--version{font-variant-numeric:tabular-nums;color:var(--dm-text)}.dm-plugin-fact--licence.is-included{color:var(--dm-info);border-color:var(--dm-info)}.dm-plugin-fact--licence.is-licensed{color:var(--dm-success);border-color:var(--dm-success)}.dm-plugin-fact--expiry{font-variant-numeric:tabular-nums}.dm-plugin-fact--expiry.is-warning{color:var(--dm-warning);border-color:var(--dm-warning)}.dm-plugin-fact--expiry.is-danger{color:var(--dm-danger);border-color:var(--dm-danger)}.dm-plugin-body{padding:1rem}.dm-plugin-body .card.dm-plugin-unwrap{border:0;background:none;box-shadow:none;margin:0}.dm-plugin-body .card.dm-plugin-unwrap>.card-body{padding:0}.dm-plugin-body>.p-4{padding:0}@media(max-width:640px){.dm-plugin-banner{align-items:flex-start;flex-direction:column;gap:.5rem}.dm-plugin-body{padding:.75rem}}.analytics-filter{max-width:240px}.dm-help-btn{display:inline-flex;align-items:center;justify-content:center;vertical-align:middle;margin-left:.3rem;padding:0;border:0;background:none;line-height:1;color:var(--dm-text-muted);opacity:.75;cursor:pointer}.dm-help-btn:hover,.dm-help-btn:focus-visible{color:var(--dm-primary);opacity:1}.dm-help-pop{position:fixed;z-index:10050;max-width:300px;padding:.6rem .75rem;background:var(--dm-surface, var(--dm-background));color:var(--dm-text);border:1px solid var(--dm-border);border-radius:var(--dm-radius-md);box-shadow:0 8px 24px #00000040;font-size:.85rem;line-height:1.45;text-align:left;font-weight:400}.dm-help-pop strong{display:block;margin-bottom:.2rem;font-weight:600}.dm-help-pop p{margin:0}.dm-admin-sidebar .sidebar-badge[data-badge-label]{cursor:help}.dm-admin-sidebar .sidebar-badge--danger,.dm-admin-sidebar .sidebar-link.active .sidebar-badge--danger{background:var(--dm-danger, #dc2626);color:#fff}.dm-admin-sidebar .sidebar-badge--live{background:color-mix(in srgb,var(--dm-success, #16a34a) 20%,transparent);color:var(--dm-success, #16a34a)}#admin-sidebar .sidebar-badge--live{padding-left:1.05rem!important}#admin-sidebar summary>.sidebar-badge--sum{position:static!important;transform:none!important;margin-left:auto!important;margin-right:.45rem;text-transform:none;letter-spacing:0}#admin-sidebar summary:has(>.sidebar-badge--sum):after{margin-left:0}#admin-sidebar details[open]>summary>.sidebar-badge--sum{display:none}.dm-admin-sidebar .sidebar-badge--live:before{content:"";position:absolute;left:.4rem;top:50%;width:.4rem;height:.4rem;margin-top:-.2rem;border-radius:50%;background:currentColor;animation:dm-badge-pulse 2s ease-in-out infinite}@keyframes dm-badge-pulse{50%{opacity:.35}}@media(prefers-reduced-motion:reduce){.dm-admin-sidebar .sidebar-badge--live:before{animation:none}}.dm-badge-pop{width:290px;max-width:calc(100vw - 16px);font-size:.8rem;pointer-events:none}.dm-badge-pop-title{display:block;font-size:.85rem}.dm-badge-pop-sub{margin:.1rem 0 .5rem;color:var(--dm-text-muted)}.dm-badge-pop-rows{display:grid;grid-template-columns:1fr auto;gap:.2rem .75rem;margin:0 0 .5rem;padding:.45rem 0;border-top:1px solid var(--dm-border);border-bottom:1px solid var(--dm-border)}.dm-badge-pop-rows dt{color:var(--dm-text-muted)}.dm-badge-pop-rows dd{margin:0;text-align:right;font-weight:600;font-variant-numeric:tabular-nums}.dm-badge-pop-items{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:.4rem}.dm-badge-pop-items li{display:flex;flex-direction:column;min-width:0}.dm-badge-pop-text{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.dm-badge-pop-meta{font-size:.72rem;color:var(--dm-text-muted)}.dm-badge-pop .is-danger,.dm-badge-pop li.is-danger .dm-badge-pop-meta{color:var(--dm-danger, #dc2626)}.dm-badge-pop-empty{margin:0;color:var(--dm-text-muted)}.dm-plugin-body,.dm-slideover{font-family:var(--dm-font-sans, inherit)}.dm-plugin-body :is(button,input,select,textarea,.btn,.form-input,.form-select,.form-textarea),.dm-slideover :is(button,input,select,textarea,.btn,.form-input,.form-select,.form-textarea){font-family:inherit}.dm-plugin-body :is(input,select,textarea,.form-input,.form-select,.form-textarea):not(.form-input-lg),.dm-slideover :is(input,select,textarea,.form-input,.form-select,.form-textarea):not(.form-input-lg){font-size:var(--dm-text-sm)}.dm-plugin-body .form-input-lg{font-size:var(--dm-text-base)}.dm-plugin-body :is(.font-mono,code,pre,kbd),.dm-slideover :is(.font-mono,code,pre,kbd){font-family:var(--dm-font-mono, monospace)}.dm-plugin-body .form-label,.dm-slideover .form-label{font-size:var(--dm-text-sm)}.related-box{display:flex;flex-direction:column;gap:.6rem;border-top:1px solid var(--dm-border);padding-top:.75rem}.related-box[hidden]{display:none}.related-head{display:flex;align-items:center;gap:.4rem}.related-head strong{flex:1}.related-list{list-style:none;margin:.3rem 0 0;padding:0;display:flex;flex-direction:column;gap:.25rem}.related-list li{display:flex;flex-direction:column}.related-list li.is-past{opacity:.7}.related-meta,.related-note,.related-loading{color:var(--dm-text-muted);font-size:var(--dm-text-xs);margin:0}.login-challenge{display:flex;flex-direction:column;gap:.6rem;margin-bottom:.75rem}.login-challenge #challenge-code{font-size:1.25rem;letter-spacing:.2em;text-align:center}.login-trust{display:flex;align-items:center;gap:.45rem;font-size:.875rem}.login-enrol{display:flex;flex-direction:column;align-items:center;gap:.6rem;margin-bottom:1rem}.login-enrol img{background:#fff;padding:.5rem;border-radius:.5rem}.login-secret{display:flex;flex-direction:column;align-items:center;gap:.25rem;text-align:center}.login-secret code{font-size:.95rem;letter-spacing:.08em;word-break:break-all}.usx-secret{display:flex;flex-direction:column;gap:.75rem;padding:1rem}.usx-secret-link{display:block;padding:.6rem .75rem;border:1px solid var(--dm-border);border-radius:var(--dm-radius-sm);background:var(--dm-background-alt);word-break:break-all;font-size:.8rem;user-select:all}.usx-secret-actions{display:flex;align-items:center;justify-content:flex-end;gap:.5rem}.usx-secret-actions .btn{display:inline-flex;align-items:center;gap:.35rem}.usx-secret-note{margin-right:auto;color:var(--dm-success)}.usx-secret-foot{color:var(--dm-text-muted);font-size:.8rem;margin:0}.uex-reset{display:flex;flex-wrap:wrap;align-items:center;gap:.35rem .5rem;margin-top:.5rem}.uex-reset>small:first-child{flex-basis:100%;color:var(--dm-text-muted)}.uex-reset .btn{display:inline-flex;align-items:center;gap:.35rem}.uex-reset-open{flex-basis:100%;color:var(--dm-info)}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{applyDrop as d,isWithin as l}from"./menu-tree.js";import{isStructural as c}from"./menu-editor-arrange.js";const p={before:"above",after:"below",into:"into"};export function dropRow(o,r,u,f){const i=f==="after"?o.find(t=>t.parentId===u):null,n=i?i.id!==r&&d(o,r,i.id,"above"):d(o,r,u,p[f]);if(n){const t=o.find(e=>e.id===r);t&&(t.touched=!0)}return n}export function sortableMenuRows(o,r,u,{items:f,handle:i=null}){return typeof E.sortable!="function"?null:E.sortable(o,{items:f,handle:i,nest:!0,accepts(n,t,e){const s=r();return!(l(s,t.dataset.id,n.dataset.id)||e==="into"&&c(s.find(a=>a.id===t.dataset.id)))},onDrop({key:n,targetKey:t,zone:e}){return dropRow(r(),n,t,e)?(u(),!0):!1}})}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import{api as S}from"../api.js";import{flatten as D,nest as k}from"./menu-rows.js";import{ensureLockedTools as N,isLockedUrl as R,placeTools as T}from"./sidebar-grouping.js";import{indentRow as z,moveRow as L,outdentRow as M}from"./menu-editor-arrange.js";import{sortableMenuRows as O}from"./menu-drag.js";const $="admin-sidebar",g=n=>String(n??"").replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""");export function canArrange(n=[]){return n.includes("menus")||n.includes("menus.update")}export function arrangeButtonMarkup(){return'<button type="button" class="btn btn-sm btn-ghost dm-admin-sidebar-arrange" title="Arrange the sidebar - drag items to move them or put them in folders" aria-label="Arrange the sidebar"><span data-icon="grip-vertical" data-icon-size="16"></span></button>'}function j(n){const s=new Set,l=new Set,d=r=>{for(const o of n.filter(m=>m.parentId===r))!o.type&&R(o.url)&&!l.has(o.url)&&(l.add(o.url),s.add(o.id)),d(o.id)};return d(null),s}function I(n){const s=j(n),l=new Set(n.map(o=>o.parentId).filter(Boolean)),d=[],r=(o,m)=>{for(const e of n.filter(i=>i.parentId===o)){const i=` style="--sb-arr-depth:${m}"`;if(e.type==="separator"||e.type==="spacer"){d.push(`<div class="sb-arr-row sb-arr-row--structural" data-id="${g(e.id)}" tabindex="0"${i}>
|
|
2
|
+
<span class="sb-arr-grip" data-icon="grip-vertical" data-icon-size="14"></span>
|
|
3
|
+
<span class="sb-arr-text">${e.type==="separator"?"Separator":"Spacer"}</span></div>`);continue}const w=l.has(e.id),a=e.text||e.tool?.label||"(no label)",b=s.has(e.id)?'<span class="sb-arr-lock" data-icon="lock" data-icon-size="14" title="Always shown - it can be moved, not hidden"></span>':`<button type="button" class="sb-arr-hide" aria-pressed="${e.hidden?"true":"false"}" title="${e.hidden?"Hidden - click to show":"Hide"}" aria-label="${e.hidden?"Show":"Hide"} ${g(a)}"><span data-icon="${e.hidden?"eye-off":"eye"}" data-icon-size="14"></span></button>`;d.push(`<div class="sb-arr-row${w?" sb-arr-row--folder":""}${e.hidden?" sb-arr-row--hidden":""}" data-id="${g(e.id)}" tabindex="0" aria-label="${g(a)}"${i}>
|
|
4
|
+
<span class="sb-arr-grip" data-icon="grip-vertical" data-icon-size="14"></span>
|
|
5
|
+
${e.icon?`<span class="sb-arr-icon" data-icon="${g(e.icon)}" data-icon-size="16"></span>`:'<span class="sb-arr-icon"></span>'}
|
|
6
|
+
<span class="sb-arr-text">${g(a)}</span>
|
|
7
|
+
${b}</div>`),r(e.id,m+1)}};return r(null,0),d.join("")}export async function startArrange(n){const s=n.querySelector(".dm-admin-sidebar");if(!s||s.classList.contains("is-arranging"))return;let l,d;try{[l,d]=await Promise.all([S.menus.get($),H.get("/api/sidebar/registered-items").catch(()=>[])])}catch{E.toast("Could not load the sidebar menu to arrange.",{type:"error"});return}if(!l){E.toast("There is no admin sidebar menu to arrange yet - create one in Content > Menus.",{type:"warning"});return}let r=D(N(T(l.items||[],d||[],{forEditor:!0}),{leaveInHiddenFolders:!0}));const o=JSON.stringify(k(r)),m=()=>JSON.stringify(k(r))!==o,e=document.createElement("div");e.className="sb-arrange",e.setAttribute("role","region"),e.setAttribute("aria-label","Arrange the sidebar");const i=document.createElement("div");i.className="sb-arrange-bar",i.append(Object.assign(document.createElement("span"),{className:"sb-arrange-title",textContent:"Arrange"}),Object.assign(document.createElement("button"),{type:"button",className:"btn btn-sm btn-ghost sb-arrange-cancel",textContent:"Cancel"}),Object.assign(document.createElement("button"),{type:"button",className:"btn btn-sm btn-primary sb-arrange-done",textContent:"Done"}));const w=Object.assign(document.createElement("p"),{className:"sb-arrange-hint",textContent:"Drag an item to move it. Drop it on the middle of another to put it inside. The eye hides or shows it. Alt+arrow keys move the focused item."}),a=document.createElement("div");a.className="sb-arrange-list",e.append(i,w,a);const b=()=>{const p=document.createRange();p.selectNodeContents(a),a.replaceChildren(p.createContextualFragment(I(r))),Domma.icons.scan(a)},A=p=>requestAnimationFrame(()=>a.querySelector(`.sb-arr-row[data-id="${CSS.escape(p)}"]`)?.focus());e.style.width=`${Math.max(Math.round(s.getBoundingClientRect().width),240)}px`,s.classList.add("is-arranging"),s.querySelector(".dm-admin-sidebar-header")?.after(e),b();const f=O(a,()=>r,b,{items:".sb-arr-row",handle:null});return new Promise(p=>{let h=!1;const v=t=>{f?.destroy(),document.removeEventListener("keydown",C,!0),e.remove(),s.classList.remove("is-arranging"),t?document.dispatchEvent(new CustomEvent("dm:sidebar-rebuild")):s.querySelector(".dm-admin-sidebar-arrange")?.focus(),p(t)},x=async()=>{h||m()&&!await E.confirm("Leave Arrange without saving? Your moves will be lost.",{title:"Discard changes?",confirmText:"Discard",cancelText:"Keep arranging"})||v(!1)},q=async()=>{if(!h){if(!m()){v(!1);return}h=!0,i.querySelectorAll("button").forEach(t=>{t.disabled=!0});try{const t=await S.menus.get($);await S.menus.update($,{...t,items:k(r)}),E.toast("Sidebar arranged.",{type:"success"}),v(!0)}catch(t){h=!1,i.querySelectorAll("button").forEach(u=>{u.disabled=!1}),E.toast(`Could not save the sidebar: ${t?.message||t}`,{type:"error"})}}};i.querySelector(".sb-arrange-cancel").addEventListener("click",x),i.querySelector(".sb-arrange-done").addEventListener("click",q),a.addEventListener("click",t=>{const u=t.target.closest(".sb-arr-hide");if(!u)return;const c=r.find(y=>y.id===u.closest(".sb-arr-row")?.dataset.id);c&&(c.hidden=!c.hidden,c.touched=!0,b(),A(c.id))}),a.addEventListener("keydown",t=>{const u=t.target.closest(".sb-arr-row");if(!u||t.target!==u||!t.altKey)return;const c=u.dataset.id,y={ArrowUp:()=>L(r,c,-1),ArrowDown:()=>L(r,c,1),ArrowRight:()=>z(r,c),ArrowLeft:()=>M(r,c)};y[t.key]&&(t.preventDefault(),y[t.key]()&&(f?f.animate(b):b(),A(c)))});function C(t){t.key!=="Escape"||f?.dragging||!e.contains(document.activeElement)&&document.activeElement!==document.body||(t.preventDefault(),t.stopPropagation(),setTimeout(x,0))}document.addEventListener("keydown",C,!0),a.querySelector(".sb-arr-row")?.focus()})}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{api as
|
|
2
|
-
<summary${v}>${e} <span class="sidebar-text">${s}</span>${
|
|
1
|
+
import{api as g}from"../api.js";import{isPathAllowed as te}from"./admin-scope.js";import{colourToCss as K,applyFloat as ne,applyHighlight as se,itemHighlightAttrs as ie}from"/public/js/menu-decor.mjs?v=20260918-item-highlight";import{placeTools as oe,ensureLockedTools as ae,managePluginsItem as re,stripItemByUrl as le,insertFoldersBeforeSystem as ce,pruneEmptyToolsFolder as de,sidebarStateKey as ue,canAny as _,filterByPermission as me,MANAGE_PLUGINS_URL as V}from"./sidebar-grouping.js";import{arrangeButtonMarkup as fe,canArrange as ge,startArrange as pe}from"./sidebar-arrange.js";function p(t){return String(t??"").replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")}const he=[{text:"Dashboard",url:"#/",icon:"home"},{text:"Menus",url:"#/menus",icon:"menu",permission:"menus"}];async function be(t){if(!_(t,"projects"))return[];let n=[];try{n=await g.projects.listWithCounts()}catch{return[]}if(!Array.isArray(n))return[];const i=[{key:"pages",text:"Pages",icon:"file-text",path:"/pages"},{key:"collections",text:"Collections",icon:"database",path:"/collections"},{key:"forms",text:"Forms",icon:"layout",path:"/forms"},{key:"actions",text:"Actions",icon:"zap",path:"/actions"},{key:"menus",text:"Menus",icon:"menu",path:"/menus"},{key:"blocks",text:"Blocks",icon:"box",path:"/blocks"},{key:"components",text:"Components",icon:"component",path:"/components"},{key:"views",text:"Views",icon:"eye",path:"/views"},{key:"roles",text:"Roles",icon:"shield",path:"/roles"},{key:"users",text:"Users",icon:"users",path:"/users"},{key:"apis",text:"APIs",icon:"code",path:"/apis"}];return n.map(e=>{const l="#/projects/"+encodeURIComponent(e.slug),r=e.counts||{},a=[{text:"Overview",url:l,icon:e.icon||"folder"}];for(const u of i){const m=Number(r[u.key])||0;m<=0||a.push({text:`${u.text} (${m})`,url:l+u.path,icon:u.icon})}a.push({text:"Settings",url:l+"/settings",icon:"settings"});const c=e.enabled===!1;return{text:e.name||e.slug,key:`project.${e.slug}`,icon:e.icon||"folder",items:a,...c&&{colour:"neutral",badge:{text:"off"}}}})}function ye(t,n){for(const i of t)if(!i.hidden&&(i.key==="projects"||!i.key&&(i.text||"").toLowerCase()==="projects")){i.items=Array.isArray(i.items)?i.items.slice():[],i.items.push(...n);return}}function G(t,n){const i=Y.includes(n.tone)?n.tone:"info",e=n.label||String(n.count);n.details?R.set(t,n.details):R.delete(t);const s=!n.inventory&&w.some(l=>l.url===t&&!l.inventory)?" data-live":"";return`<span class="sidebar-badge sidebar-badge--${i}" data-count-for="${p(t)}"${s} data-badge-label="${p(e)}" aria-label="${p(e)}">${p(String(n.count))}</span>`}function J(t){for(const n of t.querySelectorAll("details")){const i=n.querySelector(":scope > summary");if(!i)continue;let e=0,s=!1;const l=[];for(const m of n.querySelectorAll(":scope > .sidebar-children .sidebar-badge[data-live]")){const v=Number(m.textContent)||0;v&&(e+=v,s||(s=m.classList.contains("sidebar-badge--danger")),l.push({text:m.closest("a")?.querySelector(".sidebar-text")?.textContent.trim()??"",meta:m.dataset.badgeLabel,tone:m.classList.contains("sidebar-badge--danger")?"danger":void 0}))}const r=`folder:${n.dataset.stateKey||i.textContent.trim()}`;let a=i.querySelector(":scope > .sidebar-badge--sum");if(!e){a?.remove(),R.delete(r);continue}a||(a=document.createElement("span"),i.querySelector(".sidebar-text")?.after(a));const c=i.querySelector(".sidebar-text")?.textContent.trim()||"This folder",u=l.map(m=>`${m.text}: ${m.meta}`).join(" \xB7 ");a.className=`sidebar-badge sidebar-badge--sum sidebar-badge--${s?"danger":"info"}`,a.dataset.countFor=r,a.dataset.badgeLabel=u,a.setAttribute("aria-label",u),a.textContent=String(e),R.set(r,{title:c,items:l})}}const R=new Map;function ve(t,n){if(!t.url||!n)return"";const i=n[t.url];return!i||!(i.count>0)?"":G(t.url,i)}const Y=["info","attention","danger","live"],xe={"#/pages":["page","pages"],"#/media":["file in the media library","files in the media library"],"#/menus":["menu","menus"],"#/context-menus":["context menu","context menus"],"#/theme":["element override in the theme","element overrides in the theme"],"#/collections":["collection","collections"],"#/forms":["form","forms"],"#/views":["view","views"],"#/actions":["action","actions"],"#/blocks":["block","blocks"],"#/components":["component","components"],"#/users":["user","users"],"#/plugins":["plugin installed","plugins installed"],"#/system/notifications":["unread notification","unread notifications"]};function O(t,{fallbackLabel:n="",tone:i="info"}={}){const e=Number(typeof t=="object"&&t!==null?t.count:t);if(!Number.isFinite(e)||e<0)return null;const s=typeof t?.label=="string"&&t.label||(n?`${e} - ${n}`:String(e)),l={count:Math.round(e),label:s,tone:Y.includes(t?.tone)?t.tone:i};return t?.details&&typeof t.details=="object"&&(l.details=t.details),t?.inventory===!0&&(l.inventory=!0),l}function Q(t,n,i=null){if(t&&t.type==="separator")return'<hr class="sidebar-divider">';if(t&&t.type==="spacer"){const y=["xs","sm","md","lg","xl","flex"].includes(t.size)?t.size:"md";return`<div class="sidebar-spacer sidebar-spacer--${p(y)}" aria-hidden="true"></div>`}const e=t.icon?`<span data-icon="${p(t.icon)}"></span>`:"",s=p(t.text||""),l=t.url?p(t.url):"",r=Array.isArray(t.items)&&t.items.length>0,a=t.colour?K(t.colour):"",c=ie(t),u=[c.hover&&` data-menu-item-hover="${p(c.hover)}"`,c.active&&` data-menu-item-active="${p(c.active)}"`].filter(Boolean).join(""),m=[a&&`color:${p(a)}`,c.accent&&`--dm-menu-highlight:${p(c.accent)}`].filter(Boolean).join(";"),v=m?` style="${m}"`:"";let x="";if(t.badge&&t.badge.text!=null&&t.badge.text!==""){const y=t.badge.variant?K(t.badge.variant):"";x=`<span class="dm-menu-badge"${y?` style="background:${p(y)};color:var(--dm-text-inverse,#fff)"`:""}>${p(String(t.badge.text))}</span>`}if(r){const y=ue(t,i),L=S.get(y)!==!1,A=t.items.map(E=>Q(E,n,y)).join("");return`<details data-state-key="${p(y)}"${L?" open":""}>
|
|
2
|
+
<summary${v}>${e} <span class="sidebar-text">${s}</span>${x}</summary>
|
|
3
3
|
<div class="sidebar-children">${A}</div>
|
|
4
|
-
</details>`}return`<a href="${l}" class="sidebar-link" data-url="${l}"${v}${u}>${e} <span class="sidebar-text">${s}</span>${ge(t,n)}${C}</a>`}async function be(t=[],n=[],i=null){const e=d=>d.then(h=>Array.isArray(h)?h.length:Array.isArray(h?.entries)?h.entries.length:0).catch(()=>0);w=xe(t,i);const s=new Set(w.map(d=>d.url)),l={pages:"#/pages",media:"#/media",menus:"#/menus","context-menus":"#/context-menus",theme:"#/theme",collections:"#/collections",forms:"#/forms",views:"#/views",actions:"#/actions",blocks:"#/blocks",components:"#/components",users:"#/users",plugins:"#/plugins",notifications:"#/system/notifications"},r=(d,h)=>q(n,d)&&!s.has(l[d])?h():Promise.resolve(0),[a,c,u,m,v,C,y,E,A,N,T,I,U,R]=await Promise.all([r("pages",()=>e(p.pages.list())),r("media",()=>e(p.media.list())),r("menus",()=>e(p.menus.list())),r("context-menus",()=>e(p.contextMenus.list())),r("theme",()=>p.theme.get().then(d=>(d?.overrides||[]).length).catch(()=>0)),r("collections",()=>e(p.collections.list())),r("forms",()=>e(p.forms.list())),r("views",()=>e(p.views.list())),r("actions",()=>e(p.actions.list())),r("blocks",()=>e(p.blocks.list())),r("components",()=>e(p.components.list())),r("users",()=>e(p.users.list())),r("plugins",()=>e(p.plugins.list())),r("notifications",()=>p.system?.notifications?.unreadCount?.().then(d=>d?.count??0).catch(()=>0)??Promise.resolve(0))]),P={};await Promise.all(w.map(async d=>{const h=await Q(d);h&&(P[d.url]=h)}));const k={"#/pages":a,"#/media":c,"#/menus":u,"#/context-menus":m,"#/theme":v,"#/collections":C,"#/forms":y,"#/views":E,"#/actions":A,"#/blocks":N,"#/components":T,"#/users":I,"#/plugins":U,"#/system/notifications":R},x={};for(const[d,h]of Object.entries(k)){if(s.has(d))continue;const[_,z]=he[d]??["item","items"],L=O(h);L&&(x[d]={...L,label:`${L.count} ${L.count===1?_:z}`})}return{...x,...P}}let w=[];const ye="dm:sidebar-count",ve=6e4;function xe(t=[],n=null){const i=[],e=s=>{if(s&&!(n&&typeof s.url=="string"&&s.url.startsWith("#/")&&!ee(n,s.url.slice(1)))){s.url&&typeof s.countUrl=="string"&&s.countUrl&&i.push({url:s.url,countUrl:s.countUrl,text:s.text||"",countLabel:s.countLabel||"",inventory:s.inventory===!0});for(const l of[...s.children||[],...s.items||[]])e(l)}};for(const s of t??[])e(s?.item??s);return i}async function Q(t){try{const n=new Date,i=`${n.getFullYear()}-${String(n.getMonth()+1).padStart(2,"0")}-${String(n.getDate()).padStart(2,"0")}`,e=t.countUrl+(t.countUrl.includes("?")?"&":"?")+`today=${i}`;return O(await H.get(e),{fallbackLabel:t.countLabel||t.text})}catch{return null}}function Z(t,n,i){const e=[...t.querySelectorAll("a.sidebar-link")].find(l=>l.dataset.url===n);if(!e)return;const s=e.querySelector(".sidebar-badge[data-count-for]");if(!i||!(i.count>0))s?.remove();else{const l=document.createRange();l.selectNodeContents(e);const r=l.createContextualFragment(V(n,i)).firstElementChild;s?s.replaceWith(r):e.querySelector(".sidebar-text")?.after(r)}W.set(n,i),G(t)}const W=new Map;async function D(t,n=null){const i=n?w.filter(e=>e.url===n):w;await Promise.all(i.map(async e=>{const s=await Q(e),l=W.get(e.url);JSON.stringify(l??null)!==JSON.stringify(s)&&Z(t,e.url,s)}))}function $e(t){t.dataset.liveCounts||(t.dataset.liveCounts="1",window.addEventListener(ye,n=>{const i=n.detail||{};if(i.url)if(i.count!==void 0){const e=w.find(s=>s.url===i.url);Z(t,i.url,O(i,{fallbackLabel:e?.countLabel||e?.text||""}))}else D(t,i.url)}),setInterval(()=>{!document.hidden&&document.body.contains(t)&&D(t)},ve),document.addEventListener("visibilitychange",()=>{document.hidden||D(t)}),Ce(t))}function Se(t,n,i){const e=(r,a,c)=>{const u=document.createElement(r);return a&&(u.className=a),c!=null&&(u.textContent=String(c)),u};if(!i){t.textContent=n;return}t.appendChild(e("strong","dm-badge-pop-title",i.title||n)),(i.rows?.length||!i.items?.length)&&t.appendChild(e("p","dm-badge-pop-sub",n));const s=Array.isArray(i.rows)?i.rows.slice(0,6):[];if(s.length){const r=e("dl","dm-badge-pop-rows");for(const a of s)r.appendChild(e("dt",null,a.label)),r.appendChild(e("dd",a.tone==="danger"?"is-danger":null,a.value));t.appendChild(r)}const l=Array.isArray(i.items)?i.items.slice(0,6):[];if(l.length){const r=e("ul","dm-badge-pop-items");for(const a of l){const c=e("li",a.tone==="danger"?"is-danger":null);c.appendChild(e("span","dm-badge-pop-text",a.text)),a.meta&&c.appendChild(e("span","dm-badge-pop-meta",a.meta)),r.appendChild(c)}t.appendChild(r)}else i.empty&&t.appendChild(e("p","dm-badge-pop-empty",i.empty))}function Ce(t){let n=null,i=null;const e=()=>{clearTimeout(i),n?.remove(),n=null},s=l=>{e();const r=l?.dataset.badgeLabel;r&&(i=setTimeout(()=>{n=document.createElement("div"),n.className="dm-help-pop dm-badge-pop",n.setAttribute("role","tooltip"),Se(n,r,F.get(l.dataset.countFor)),document.body.appendChild(n);const a=l.getBoundingClientRect(),c=n.getBoundingClientRect(),u=Math.min(a.right+10,innerWidth-c.width-8);n.style.left=`${Math.max(8,u)}px`,n.style.top=`${Math.max(8,Math.min(a.top+a.height/2-c.height/2,innerHeight-c.height-8))}px`},150))};t.addEventListener("mouseover",l=>{const r=l.target.closest?.(".sidebar-badge[data-badge-label]");r&&s(r)}),t.addEventListener("mouseout",l=>{l.target.closest?.(".sidebar-badge[data-badge-label]")&&e()}),t.addEventListener("focusin",l=>{const r=l.target.closest?.("a, summary")?.querySelector(":scope > .sidebar-badge[data-badge-label]:not([hidden])");r?s(r):e()}),t.addEventListener("focusout",e),window.addEventListener("scroll",e,!0),window.addEventListener("hashchange",e)}async function we(t=[]){if(!q(t,"settings"))return"Admin";try{const n=await p.settings.get();return n?.adminBrand?.title||n?.title||"Admin"}catch{return"Admin"}}export async function renderAdminSidebar({mount:t,permissions:n,adminScope:i=null}){const e=$(t).get(0);if(!e)return;let s,l=null,r=null,a=null,c=null,u=null;try{const o=await p.get("/sidebar/menu");s=Array.isArray(o?.items)?o.items:null,l=o?.variant||null,r=o?.position||null,a=o?.style||null,c=o?.float||null,u=o?.highlight||null}catch{s=null}(!s||!s.some(o=>o&&(!o.hidden||o.restricted)))&&(console.warn("[admin-sidebar] No admin-sidebar menu found; using fallback tree"),s=me.slice());let m=[];try{m=await H.get("/api/sidebar/registered-items")||[]}catch{}s=re(s,K),s=ie(s,m.filter(o=>(o?.item??o)?.url!==K)),s=oe(s),s=le(s,[ae()]);const v=await fe(n);v.length&&pe(s,v),s=ue(s,n,i),s=ce(s);const[C,y]=await Promise.all([be(m.filter(o=>q(n,o?.item?.permission)),n,i).catch(()=>({})),we(n)]),E=l?` dm-admin-sidebar--${g(l)}`:"";function A(o,b="px"){if(o==null)return o;const f=String(o).trim();return/^\d+(\.\d+)?$/.test(f)?`${f}${b}`:f}let N="";if(a){const o=[];a.fontFamily&&o.push(`font-family: ${a.fontFamily}, sans-serif`),a.fontSize&&o.push(`font-size: ${A(a.fontSize)}`),a.fontWeight&&o.push(`font-weight: ${a.fontWeight}`),a.letterSpacing&&o.push(`letter-spacing: ${A(a.letterSpacing,"em")}`);const b=[];if(o.length&&b.push(`#admin-sidebar .dm-admin-sidebar, #admin-sidebar .dm-admin-sidebar .sidebar-link, #admin-sidebar .dm-admin-sidebar summary, #admin-sidebar .dm-admin-sidebar .sidebar-text { ${o.join("; ")} }`),a.iconSize){const f=A(a.iconSize);b.push(`#admin-sidebar .dm-admin-sidebar [data-icon], #admin-sidebar .dm-admin-sidebar [data-icon] svg { width: ${f} !important; height: ${f} !important; }`)}b.length&&(N=`<style data-admin-sidebar-style>${b.join(" ")}</style>`)}const T=`<div class="dm-admin-sidebar-header"><span data-icon="layout"></span> ${g(y)}</div>`,I=s.some(o=>o&&o.type==="spacer"&&o.size==="flex")?" dm-admin-sidebar--has-flex-spacer":"",U=`${N}<nav class="dm-admin-sidebar${E}${I}">${T}${s.map(o=>Y(o,C)).join("")}</nav>`,R=document.createRange();R.selectNodeContents(e);const P=R.createContextualFragment(U);e.replaceChildren(P),Domma.icons.scan(e);for(const o of w)W.set(o.url,C[o.url]??null);G(e),$e(e);const k=Number.parseInt(S.get("sidebar.width"),10);Number.isFinite(k)&&k>=180&&k<=480&&(e.style.width=k+"px"),e.removeAttribute("data-menu-hover"),e.removeAttribute("data-menu-active"),e.style.removeProperty("--dm-menu-highlight"),ne(e,{highlight:u});const x=document.querySelector(".dashboard-wrapper");if(["position","top","bottom","left","right","zIndex","maxHeight","transform"].forEach(o=>{e.style[o]=""}),e.classList.remove("dm-menu-floating"),x&&(x.style.paddingLeft="",x.style.paddingRight=""),r==="floating"){te(e,{position:"floating",float:c||{}});const b=c&&c.anchor||"TL",f=Number.isFinite(Number(c?.offsetX))?Number(c.offsetX):16,j=e.getBoundingClientRect().width||k||260;if(x){const B=Math.round(j+f*2)+"px";b==="R"||b==="TR"||b==="BR"?x.style.paddingRight=B:x.style.paddingLeft=B}}const d=document.createElement("div");d.className="dm-admin-sidebar-handle",d.setAttribute("aria-label","Resize sidebar"),e.appendChild(d),e.querySelectorAll("details").forEach(o=>{o.addEventListener("toggle",function(){const b=this.getAttribute("data-state-key");b&&S.set(b,this.open);const f=this.querySelector(":scope > .sidebar-children");if(f)if(this.open){const j=f.scrollHeight;f.style.maxHeight="0",requestAnimationFrame(()=>{f.style.maxHeight=j+"px",f.addEventListener("transitionend",function B(){f.style.maxHeight="none",f.removeEventListener("transitionend",B)})})}else{const j=f.scrollHeight;f.style.maxHeight=j+"px",requestAnimationFrame(()=>{f.style.maxHeight="0"})}})});let h=!1,_=0,z=0;d.addEventListener("mousedown",o=>{h=!0,_=o.clientX,z=e.getBoundingClientRect().width,document.body.style.cursor="col-resize",document.body.style.userSelect="none",o.preventDefault()}),e.dataset.resizeWired||(e.dataset.resizeWired="1",document.addEventListener("mousemove",o=>e.__dmResize?.move(o)),document.addEventListener("mouseup",()=>e.__dmResize?.up()),M.subscribe("router:afterChange",()=>e.__dmSetActive?.())),e.__dmResize={move(o){if(!h)return;const b=Math.max(180,Math.min(480,z+(o.clientX-_)));e.style.width=b+"px"},up(){h&&(h=!1,document.body.style.cursor="",document.body.style.userSelect="",S.set("sidebar.width",parseInt(e.style.width,10)))}};function L(){const o=location.hash||"#/";$(e).find(".sidebar-link").removeClass("active"),$(e).find(`.sidebar-link[data-url="${o}"]`).addClass("active")}L(),e.__dmSetActive=L}
|
|
4
|
+
</details>`}return`<a href="${l}" class="sidebar-link" data-url="${l}"${v}${u}>${e} <span class="sidebar-text">${s}</span>${ve(t,n)}${x}</a>`}async function $e(t=[],n=[],i=null){const e=d=>d.then(h=>Array.isArray(h)?h.length:Array.isArray(h?.entries)?h.entries.length:0).catch(()=>0);w=we(t,i);const s=new Set(w.map(d=>d.url)),l={pages:"#/pages",media:"#/media",menus:"#/menus","context-menus":"#/context-menus",theme:"#/theme",collections:"#/collections",forms:"#/forms",views:"#/views",actions:"#/actions",blocks:"#/blocks",components:"#/components",users:"#/users",plugins:"#/plugins",notifications:"#/system/notifications"},r=(d,h)=>_(n,d)&&!s.has(l[d])?h():Promise.resolve(0),[a,c,u,m,v,x,y,L,A,E,z,q,T,I]=await Promise.all([r("pages",()=>e(g.pages.list())),r("media",()=>e(g.media.list())),r("menus",()=>e(g.menus.list())),r("context-menus",()=>e(g.contextMenus.list())),r("theme",()=>g.theme.get().then(d=>(d?.overrides||[]).length).catch(()=>0)),r("collections",()=>e(g.collections.list())),r("forms",()=>e(g.forms.list())),r("views",()=>e(g.views.list())),r("actions",()=>e(g.actions.list())),r("blocks",()=>e(g.blocks.list())),r("components",()=>e(g.components.list())),r("users",()=>e(g.users.list())),r("plugins",()=>e(g.plugins.list())),r("notifications",()=>g.system?.notifications?.unreadCount?.().then(d=>d?.count??0).catch(()=>0)??Promise.resolve(0))]),j={};await Promise.all(w.map(async d=>{const h=await Z(d);h&&(j[d.url]=h)}));const U={"#/pages":a,"#/media":c,"#/menus":u,"#/context-menus":m,"#/theme":v,"#/collections":x,"#/forms":y,"#/views":L,"#/actions":A,"#/blocks":E,"#/components":z,"#/users":q,"#/plugins":T,"#/system/notifications":I},C={};for(const[d,h]of Object.entries(U)){if(s.has(d))continue;const[N,B]=xe[d]??["item","items"],k=O(h);k&&(C[d]={...k,label:`${k.count} ${k.count===1?N:B}`})}return{...C,...j}}let w=[];const Se="dm:sidebar-count",Ce=6e4;function we(t=[],n=null){const i=[],e=s=>{if(s&&!(n&&typeof s.url=="string"&&s.url.startsWith("#/")&&!te(n,s.url.slice(1)))){s.url&&typeof s.countUrl=="string"&&s.countUrl&&i.push({url:s.url,countUrl:s.countUrl,text:s.text||"",countLabel:s.countLabel||"",inventory:s.inventory===!0});for(const l of[...s.children||[],...s.items||[]])e(l)}};for(const s of t??[])e(s?.item??s);return i}async function Z(t){try{const n=new Date,i=`${n.getFullYear()}-${String(n.getMonth()+1).padStart(2,"0")}-${String(n.getDate()).padStart(2,"0")}`,e=t.countUrl+(t.countUrl.includes("?")?"&":"?")+`today=${i}`;return O(await H.get(e),{fallbackLabel:t.countLabel||t.text})}catch{return null}}function ee(t,n,i){const e=[...t.querySelectorAll("a.sidebar-link")].find(l=>l.dataset.url===n);if(!e)return;const s=e.querySelector(".sidebar-badge[data-count-for]");if(!i||!(i.count>0))s?.remove();else{const l=document.createRange();l.selectNodeContents(e);const r=l.createContextualFragment(G(n,i)).firstElementChild;s?s.replaceWith(r):e.querySelector(".sidebar-text")?.after(r)}W.set(n,i),J(t)}const W=new Map;async function D(t,n=null){const i=n?w.filter(e=>e.url===n):w;await Promise.all(i.map(async e=>{const s=await Z(e),l=W.get(e.url);JSON.stringify(l??null)!==JSON.stringify(s)&&ee(t,e.url,s)}))}function Ae(t){t.dataset.liveCounts||(t.dataset.liveCounts="1",window.addEventListener(Se,n=>{const i=n.detail||{};if(i.url)if(i.count!==void 0){const e=w.find(s=>s.url===i.url);ee(t,i.url,O(i,{fallbackLabel:e?.countLabel||e?.text||""}))}else D(t,i.url)}),setInterval(()=>{!document.hidden&&document.body.contains(t)&&D(t)},Ce),document.addEventListener("visibilitychange",()=>{document.hidden||D(t)}),Le(t))}function ke(t,n,i){const e=(r,a,c)=>{const u=document.createElement(r);return a&&(u.className=a),c!=null&&(u.textContent=String(c)),u};if(!i){t.textContent=n;return}t.appendChild(e("strong","dm-badge-pop-title",i.title||n)),(i.rows?.length||!i.items?.length)&&t.appendChild(e("p","dm-badge-pop-sub",n));const s=Array.isArray(i.rows)?i.rows.slice(0,6):[];if(s.length){const r=e("dl","dm-badge-pop-rows");for(const a of s)r.appendChild(e("dt",null,a.label)),r.appendChild(e("dd",a.tone==="danger"?"is-danger":null,a.value));t.appendChild(r)}const l=Array.isArray(i.items)?i.items.slice(0,6):[];if(l.length){const r=e("ul","dm-badge-pop-items");for(const a of l){const c=e("li",a.tone==="danger"?"is-danger":null);c.appendChild(e("span","dm-badge-pop-text",a.text)),a.meta&&c.appendChild(e("span","dm-badge-pop-meta",a.meta)),r.appendChild(c)}t.appendChild(r)}else i.empty&&t.appendChild(e("p","dm-badge-pop-empty",i.empty))}function Le(t){let n=null,i=null;const e=()=>{clearTimeout(i),n?.remove(),n=null},s=l=>{e();const r=l?.dataset.badgeLabel;r&&(i=setTimeout(()=>{n=document.createElement("div"),n.className="dm-help-pop dm-badge-pop",n.setAttribute("role","tooltip"),ke(n,r,R.get(l.dataset.countFor)),document.body.appendChild(n);const a=l.getBoundingClientRect(),c=n.getBoundingClientRect(),u=Math.min(a.right+10,innerWidth-c.width-8);n.style.left=`${Math.max(8,u)}px`,n.style.top=`${Math.max(8,Math.min(a.top+a.height/2-c.height/2,innerHeight-c.height-8))}px`},150))};t.addEventListener("mouseover",l=>{const r=l.target.closest?.(".sidebar-badge[data-badge-label]");r&&s(r)}),t.addEventListener("mouseout",l=>{l.target.closest?.(".sidebar-badge[data-badge-label]")&&e()}),t.addEventListener("focusin",l=>{const r=l.target.closest?.("a, summary")?.querySelector(":scope > .sidebar-badge[data-badge-label]:not([hidden])");r?s(r):e()}),t.addEventListener("focusout",e),window.addEventListener("scroll",e,!0),window.addEventListener("hashchange",e)}async function Ee(t=[]){if(!_(t,"settings"))return"Admin";try{const n=await g.settings.get();return n?.adminBrand?.title||n?.title||"Admin"}catch{return"Admin"}}export async function renderAdminSidebar({mount:t,permissions:n,adminScope:i=null}){const e=$(t).get(0);if(!e)return;let s,l=null,r=null,a=null,c=null,u=null;try{const o=await g.get("/sidebar/menu");s=Array.isArray(o?.items)?o.items:null,l=o?.variant||null,r=o?.position||null,a=o?.style||null,c=o?.float||null,u=o?.highlight||null}catch{s=null}(!s||!s.some(o=>o&&(!o.hidden||o.restricted)))&&(console.warn("[admin-sidebar] No admin-sidebar menu found; using fallback tree"),s=he.slice());let m=[];try{m=await H.get("/api/sidebar/registered-items")||[]}catch{}s=le(s,V),s=oe(s,m.filter(o=>(o?.item??o)?.url!==V)),s=ae(s),s=ce(s,[re()]);const v=await be(n);v.length&&ye(s,v),s=me(s,n,i),s=de(s);const[x,y]=await Promise.all([$e(m.filter(o=>_(n,o?.item?.permission)),n,i).catch(()=>({})),Ee(n)]),L=l?` dm-admin-sidebar--${p(l)}`:"";function A(o,b="px"){if(o==null)return o;const f=String(o).trim();return/^\d+(\.\d+)?$/.test(f)?`${f}${b}`:f}let E="";if(a){const o=[];a.fontFamily&&o.push(`font-family: ${a.fontFamily}, sans-serif`),a.fontSize&&o.push(`font-size: ${A(a.fontSize)}`),a.fontWeight&&o.push(`font-weight: ${a.fontWeight}`),a.letterSpacing&&o.push(`letter-spacing: ${A(a.letterSpacing,"em")}`);const b=[];if(o.length&&b.push(`#admin-sidebar .dm-admin-sidebar, #admin-sidebar .dm-admin-sidebar .sidebar-link, #admin-sidebar .dm-admin-sidebar summary, #admin-sidebar .dm-admin-sidebar .sidebar-text { ${o.join("; ")} }`),a.iconSize){const f=A(a.iconSize);b.push(`#admin-sidebar .dm-admin-sidebar [data-icon], #admin-sidebar .dm-admin-sidebar [data-icon] svg { width: ${f} !important; height: ${f} !important; }`)}b.length&&(E=`<style data-admin-sidebar-style>${b.join(" ")}</style>`)}const z=ge(n)?fe():"",q=`<div class="dm-admin-sidebar-header"><span data-icon="layout"></span> ${p(y)}${z}</div>`,T=s.some(o=>o&&o.type==="spacer"&&o.size==="flex")?" dm-admin-sidebar--has-flex-spacer":"",I=`${E}<nav class="dm-admin-sidebar${L}${T}">${q}${s.map(o=>Q(o,x)).join("")}</nav>`,j=document.createRange();j.selectNodeContents(e);const U=j.createContextualFragment(I);e.replaceChildren(U),Domma.icons.scan(e),e.querySelector(".dm-admin-sidebar-arrange")?.addEventListener("click",()=>pe(e));for(const o of w)W.set(o.url,x[o.url]??null);J(e),Ae(e);const C=Number.parseInt(S.get("sidebar.width"),10);Number.isFinite(C)&&C>=180&&C<=480&&(e.style.width=C+"px"),e.removeAttribute("data-menu-hover"),e.removeAttribute("data-menu-active"),e.style.removeProperty("--dm-menu-highlight"),se(e,{highlight:u});const d=document.querySelector(".dashboard-wrapper");if(["position","top","bottom","left","right","zIndex","maxHeight","transform"].forEach(o=>{e.style[o]=""}),e.classList.remove("dm-menu-floating"),d&&(d.style.paddingLeft="",d.style.paddingRight=""),r==="floating"){ne(e,{position:"floating",float:c||{}});const b=c&&c.anchor||"TL",f=Number.isFinite(Number(c?.offsetX))?Number(c.offsetX):16,F=e.getBoundingClientRect().width||C||260;if(d){const P=Math.round(F+f*2)+"px";b==="R"||b==="TR"||b==="BR"?d.style.paddingRight=P:d.style.paddingLeft=P}}const h=document.createElement("div");h.className="dm-admin-sidebar-handle",h.setAttribute("aria-label","Resize sidebar"),e.appendChild(h),e.querySelectorAll("details").forEach(o=>{o.addEventListener("toggle",function(){const b=this.getAttribute("data-state-key");b&&S.set(b,this.open);const f=this.querySelector(":scope > .sidebar-children");if(f)if(this.open){const F=f.scrollHeight;f.style.maxHeight="0",requestAnimationFrame(()=>{f.style.maxHeight=F+"px",f.addEventListener("transitionend",function P(){f.style.maxHeight="none",f.removeEventListener("transitionend",P)})})}else{const F=f.scrollHeight;f.style.maxHeight=F+"px",requestAnimationFrame(()=>{f.style.maxHeight="0"})}})});let N=!1,B=0,k=0;h.addEventListener("mousedown",o=>{N=!0,B=o.clientX,k=e.getBoundingClientRect().width,document.body.style.cursor="col-resize",document.body.style.userSelect="none",o.preventDefault()}),e.dataset.resizeWired||(e.dataset.resizeWired="1",document.addEventListener("mousemove",o=>e.__dmResize?.move(o)),document.addEventListener("mouseup",()=>e.__dmResize?.up()),M.subscribe("router:afterChange",()=>e.__dmSetActive?.())),e.__dmResize={move(o){if(!N)return;const b=Math.max(180,Math.min(480,k+(o.clientX-B)));e.style.width=b+"px"},up(){N&&(N=!1,document.body.style.cursor="",document.body.style.userSelect="",S.set("sidebar.width",parseInt(e.style.width,10)))}};function X(){const o=location.hash||"#/";$(e).find(".sidebar-link").removeClass("active"),$(e).find(`.sidebar-link[data-url="${o}"]`).addClass("active")}X(),e.__dmSetActive=X}
|
|
@@ -88,6 +88,28 @@
|
|
|
88
88
|
open or closed on its own, so closing Tools > Core does not close a project that is also
|
|
89
89
|
called Core.</p>
|
|
90
90
|
|
|
91
|
+
<h3>Arrange the sidebar in place</h3>
|
|
92
|
+
<p>You can also rearrange the sidebar without leaving the page you are on. Click the six-dot
|
|
93
|
+
button at the top of the sidebar, beside the site name, to turn on <strong>Arrange</strong>.
|
|
94
|
+
The sidebar then lists every item as a row, including hidden ones (dimmed and struck through),
|
|
95
|
+
and clicking a row no longer opens it.</p>
|
|
96
|
+
<ul>
|
|
97
|
+
<li><strong>Move</strong> - drag a row. A line shows where it will land.</li>
|
|
98
|
+
<li><strong>Put inside a folder</strong> - drop it on the middle of another row; an outline
|
|
99
|
+
shows it going in. Dropping on the line just under a folder puts it at the top of that
|
|
100
|
+
folder.</li>
|
|
101
|
+
<li><strong>Hide or show</strong> - the eye at the end of a row. A padlock means the item
|
|
102
|
+
can be moved but not hidden.</li>
|
|
103
|
+
<li><strong>Keyboard</strong> - with a row focused, Alt+Up and Alt+Down move it,
|
|
104
|
+
Alt+Right puts it inside the row above, Alt+Left takes it out of its folder.</li>
|
|
105
|
+
<li><strong>Done</strong> saves and redraws the sidebar. <strong>Cancel</strong> or Esc leaves
|
|
106
|
+
it as it was, asking first if you moved anything.</li>
|
|
107
|
+
</ul>
|
|
108
|
+
<p>Arrange changes the same <code>admin-sidebar</code> menu as the Menus editor, so it changes
|
|
109
|
+
the sidebar for everyone; each person still sees only what their role allows. Renaming items,
|
|
110
|
+
changing icons, badges or who can see an item, and adding links is done in the Menus editor.
|
|
111
|
+
The button is shown to users who may edit menus.</p>
|
|
112
|
+
|
|
91
113
|
<p>Right-click menus on public pages are a separate feature: <strong>Content > Context
|
|
92
114
|
Menus</strong>.</p>
|
|
93
115
|
|
|
@@ -1,25 +1,25 @@
|
|
|
1
|
-
import{api as
|
|
2
|
-
<div class="menu-tree-row menu-tree-row--separator" data-id="${
|
|
1
|
+
import{api as C}from"../api.js";import{colourToCss as wt,HIGHLIGHT_HOVER as tt,HIGHLIGHT_ACTIVE as nt,HIGHLIGHT_HOVER_LABELS as ot,HIGHLIGHT_ACTIVE_LABELS as at}from"/public/js/menu-decor.mjs?v=20260918-item-highlight";import{openIconPicker as kt}from"../lib/card-builder.js";import{sortableMenuRows as St}from"../lib/menu-drag.js";import{placeTools as $t,ensureLockedTools as xt,isLockedUrl as Et,groupKeyFor as At,slugify as Lt,GROUP_ICON as _t,TOOLS_FOLDER_KEY as Ct}from"../lib/sidebar-grouping.js";import{flatten as it,nest as Ht,uid as Ee}from"../lib/menu-rows.js";import{addBannerAction as Be}from"../lib/plugin-chrome.js";import{helpPopovers as It}from"../lib/help-popover.js";import{onceClosed as Rt,openMenuAt as ze,sidebarCount as Tt}from"../lib/tool-kit.js";import{addChild as jt,bindingFrom as Dt,duplicateRow as Nt,indentRow as Ot,insertBelow as Pt,isStructural as oe,menuFromForm as Ft,menuProblems as st,moveRow as lt,outdentRow as Bt,siblingsOf as zt,snapshot as Ae}from"../lib/menu-editor-arrange.js";import{fmtDateTime as Mt}from"../lib/dates.js";const Kt=760,Wt="admin-sidebar",qt=/^\/menus\/(new|edit\/[^?#]+)(\?.*)?$/;function y(t){return String(t||"").replace(/&/g,"&").replace(/"/g,""").replace(/</g,"<")}const Le=t=>String(t??"").replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""");function Ut(t,d){let s=0,l=d.find(i=>i.id===t);for(;l&&l.parentId;)s++,l=d.find(i=>i.id===l.parentId);return s}function rt(t){const d=new Set,s=new Set,l=i=>{for(const g of t.filter(k=>k.parentId===i))!g.type&&Et(g.url)&&!s.has(g.url)&&(s.add(g.url),d.add(g.id)),l(g.id)};return l(null),d}const Me='<button type="button" class="btn btn-sm btn-ghost mex-kebab" aria-label="Actions" title="Actions (right-click, or Shift+F10)">\u22EE</button>';function Gt(t,d,s=!1){const l=s?rt(d):new Set,i=[];function g(k){for(const f of d.filter(N=>N.parentId===k)){const _=`style="margin-left:${Ut(f.id,d)*28}px"`;if(f.type==="separator"){i.push(`
|
|
2
|
+
<div class="menu-tree-row menu-tree-row--separator" data-id="${f.id}" tabindex="0" ${_}>
|
|
3
3
|
<span class="menu-tree-grip" data-icon="grip-vertical" data-icon-size="18" title="Drag to move"></span>
|
|
4
4
|
<span class="me-sep-line"><span class="me-sep-label">Separator</span></span>
|
|
5
5
|
${Me}
|
|
6
|
-
</div>`);continue}if(
|
|
7
|
-
<div class="menu-tree-row menu-tree-row--spacer" data-id="${
|
|
6
|
+
</div>`);continue}if(f.type==="spacer"){const ee=["xs","sm","md","lg","xl","flex"].map(O=>`<option value="${O}"${(f.size||"md")===O?" selected":""}>${O==="flex"?"flexible":O}</option>`).join("");i.push(`
|
|
7
|
+
<div class="menu-tree-row menu-tree-row--spacer" data-id="${f.id}" tabindex="0" ${_}>
|
|
8
8
|
<span class="menu-tree-grip" data-icon="grip-vertical" data-icon-size="18" title="Drag to move"></span>
|
|
9
9
|
<span class="me-spacer-line">
|
|
10
10
|
<span class="me-spacer-label">Spacer</span>
|
|
11
|
-
<select class="form-input me-spacer-size" title="Spacer size - flexible fills the leftover room" aria-label="Spacer size">${
|
|
11
|
+
<select class="form-input me-spacer-size" title="Spacer size - flexible fills the leftover room" aria-label="Spacer size">${ee}</select>
|
|
12
12
|
</span>
|
|
13
13
|
${Me}
|
|
14
|
-
</div>`);continue}const
|
|
15
|
-
<div class="menu-tree-row menu-tree-row--slim${
|
|
14
|
+
</div>`);continue}const V=f.badge&&(f.badge.text||f.badge.countFrom)?`<span class="dm-menu-badge">${y(String(f.badge.text||"#"))}</span>`:"",A=f.tool,h=A&&(A.persisted||f.touched),B=A?A.orphan?' <span class="badge badge-secondary me-tool-badge" title="A placeholder for a Tool that is not enabled - it returns here when it is">Not enabled</span>':` <span class="badge badge-secondary me-tool-badge" title="${h?"A Tool, placed here by this menu":"A Tool in its default place - move or edit it to place it here"}">${y(A.source||"Tool")}${h?"":" \xB7 default"}</span>`:"",ae=l.has(f.id),Z=wt(f.colour),z=Z?` style="color:${y(Z)}"`:"",ie=ae?'<button type="button" class="btn btn-sm btn-ghost" disabled title="Always shown - it can be moved, not hidden" aria-label="Always shown"><span data-icon="lock"></span></button>':`<button type="button" class="btn btn-sm btn-ghost me-hidden ${f.hidden?"active":""}" title="${f.hidden?"Hidden - click to show":"Hide"}" aria-label="${f.hidden?"Show":"Hide"}" aria-pressed="${f.hidden?"true":"false"}"><span data-icon="${f.hidden?"eye-off":"eye"}"></span></button>`;i.push(`
|
|
15
|
+
<div class="menu-tree-row menu-tree-row--slim${f.hidden?" menu-tree-row--hidden":""}${A?" menu-tree-row--tool":""}${A&&!h?" menu-tree-row--default":""}" data-id="${f.id}" tabindex="0" ${_}>
|
|
16
16
|
<span class="menu-tree-grip" data-icon="grip-vertical" data-icon-size="18" title="Drag to move"></span>
|
|
17
|
-
<span class="me-row-label${!
|
|
18
|
-
<span class="me-row-url">${
|
|
17
|
+
<span class="me-row-label${!f.text&&!A?" mex-untitled":""}"${z}>${y(f.text||A?.label||"(no label - click to add one)")}${V}${B}</span>
|
|
18
|
+
<span class="me-row-url">${y(f.url||"")}</span>
|
|
19
19
|
${ie}
|
|
20
20
|
<button type="button" class="btn btn-sm btn-ghost me-edit" title="Edit" aria-label="Edit"><span data-icon="edit"></span></button>
|
|
21
21
|
${Me}
|
|
22
|
-
</div>`),h(m.id)}}h(null),t.innerHTML=i.join("")||'<p class="mex-note">No items yet - Add item, or right-click an item for more.</p>',I.scan(t)}function $(t,r={},...l){const s=document.createElement(t);Object.assign(s,r);for(const i of l)i!=null&&s.append(i);return s}function D(t,r,l){const s=$("label",{className:"form-field"},$("span",{className:"form-label",textContent:t}),r);return l&&s.append($("small",{className:"form-hint",textContent:l,style:"display:block;font-size:.78em;opacity:.7;margin-top:.25rem;line-height:1.35"})),s}function Jt(t,r){const l=[["","- Everyone -"],["public","Public - anyone, incl. logged-out"],...(r||[]).map(i=>[i.name,`${i.label||i.name} and above`]),...(r||[]).filter(i=>i.level!==0).map(i=>[`=${i.name}`,`${i.label||i.name} only`]),["private","Private - super-admin only"]];t&&!l.some(([i])=>i===t)&&l.push([t,`${t} (custom)`]);const s=Q(l,t||"");return s.name="visibility",s}function Q(t,r){const l=$("select",{className:"form-select"});return t.forEach(([s,i])=>l.add(new Option(i,s))),l.value=r??"",l}function _e(t,r){const l=typeof r=="string"&&r.startsWith("#"),s=Q([["","- none -"],["primary","primary"],["success","success"],["danger","danger"],["warning","warning"],["info","info"],["neutral","neutral"],["__custom__","Custom\u2026"]],l?"__custom__":r||""),i=$("input",{type:"color",className:"form-input me-colour-hex",value:l?r:"#000000"});i.style.display=l?"":"none",s.addEventListener("change",()=>{i.style.display=s.value==="__custom__"?"":"none"});const h=D(t,s);return h.append(i),h._read=()=>s.value==="__custom__"?i.value:s.value,h}function Zt(t,r){const l=$("input",{className:"form-input me-icon",name:"icon",value:r||""}),s=$("span",{className:"me-icon-preview"});r&&s.setAttribute("data-icon",r);const i=$("button",{type:"button",className:"btn btn-sm btn-ghost",textContent:"Browse\u2026"}),h=b=>{b?s.setAttribute("data-icon",b):s.removeAttribute("data-icon"),Domma.icons.scan(s.parentNode||s)};return i.addEventListener("click",()=>St(b=>{l.value=b,h(b)})),l.addEventListener("input",()=>h(l.value.trim())),D(t,$("div",{className:"me-icon-field"},l,i,s))}function Ce(...t){return $("div",{className:"me-field-grid"},...t)}async function Qt(t,r,l,s,i){const h=t.text||t.tool?.label||"",b=c=>$("h4",{className:"me-form-section",textContent:c}),m=D("Label",$("input",{className:"form-input",name:"text",value:t.text||""}),"The text shown for this item."),j=$("input",{className:"form-input",name:"url",value:t.url||""}),x=D("URL",j,t.tool||t.locked?"A Tool's address is its identity, so it cannot be changed here.":"Where it links. Must start with /, #, https://, or mailto: . Leave blank for a parent that only groups sub-items.");(t.tool||t.locked)&&(j.readOnly=!0);const C=Zt("Icon",t.icon||""),L=Jt(t.visibility||"",s),v=D("Visibility",L,t.locked?"Always in the sidebar for everyone who may use it, so it cannot be restricted here.":'Who can see this item. "Role and above" shows it to that role and anyone more senior; "Role only" shows it to holders of that role alone (and the super-admin). Blank = everyone.');t.locked&&(L.disabled=!0);const z=Q([["","- no permission gate -"],...(r||[]).map(c=>[c.key,c.label||c.key])],t.permission||"");z.name="permission";const ae=D("Permission",z,t.tool||t.locked?"A Tool is guarded by its own permission, which always applies.":"Hide unless the viewer holds this specific permission. Independent of Visibility - both must pass.");(t.tool||t.locked)&&(z.disabled=!0);const ee=D("Badge text",$("input",{className:"form-input",name:"badgeText",value:t.badge?.text||""})),W=Q([["","- none -"],...(l||[]).map(c=>[c.slug,c.title||c.slug])],t.badge?.countFrom||"");W.name="badgeCount";const ie=D("Badge count from",W,"Show a live count of this collection\u2019s entries as the badge."),te=_e("Badge colour",t.badge?.variant||""),P=Q([["link","Link"],["pill","Pill"]],t.pill?"pill":"link");P.name="renderAs";const He=D("Render as",P,"Pill draws the item as a rounded chip. Pill styling applies to top-level navbar items."),K=D("Pill style",Q([["filled","Filled"],["outline","Outline"]],t.pill?.style||"filled"));K.querySelector("select").name="pillStyle";const me=_e("Pill colour",t.pill?.variant||""),se=$("div",{className:"me-pill-wrap"},Ce(K,me));se.style.display=t.pill?"":"none",P.addEventListener("change",()=>{se.style.display=P.value==="pill"?"":"none"});const p=_e("Text colour",t.colour||""),N=Q([["","- use the menu default -"],...tt.map(c=>[c,ot[c]||c])],t.highlight?.hover||"");N.name="hlHover";const le=D("Hover effect",N,"Overrides the menu-wide hover effect for this item only."),pe=Q([["","- use the menu default -"],...nt.map(c=>[c,at[c]||c])],t.highlight?.active||"");pe.name="hlActive";const be=D("When selected",pe,"How this item is marked when it points at the page being viewed."),F=_e("Highlight colour",t.highlight?.accent||""),A=$("button",{className:"btn btn-primary",textContent:"Apply",title:"Apply to the item (Ctrl+Enter) - Save the menu to keep it"}),q=$("div",{className:"me-item-form"},b("Link"),m,x,C,b("Access"),Ce(v,ae),b("Badge"),Ce(ee,te),ie,b("Appearance"),He,se,p,b("Highlighting"),Ce(le,be),F,A),y=E.slideover({title:h?`Edit ${Le(h)}`:"Edit menu item",size:"lg",position:"right"});y.element.appendChild(q);const Y=()=>JSON.stringify([...q.querySelectorAll("input, select, textarea")].map(c=>c.type==="checkbox"?c.checked:c.value)),ne=Y();let U=!1,re=!1;Rt(y);const ye=y.close.bind(y);y.close=async c=>{if(!U&&c!==!0&&Y()!==ne){if(re)return;re=!0;const G=await E.confirm("Discard the changes to this item?");if(re=!1,!G)return}return U=!0,ye()},q.addEventListener("keydown",c=>{(c.ctrlKey||c.metaKey)&&c.key==="Enter"&&(c.preventDefault(),A.click())}),y.open();const fe=y.element.closest(".dm-slideover")||y.element.querySelector(".dm-slideover")||y.element;fe.style.setProperty("width",Kt+"px","important"),fe.style.setProperty("max-width","95vw","important"),Domma.icons.scan(q);const _=c=>q.querySelector(`[name="${c}"]`)?.value||"";A.addEventListener("click",()=>{t.text=_("text"),t.icon=_("icon"),t.locked||(t.visibility=_("visibility")),!t.tool&&!t.locked?(t.url=_("url"),t.permission=_("permission")):t.touched=!0;const c=_("badgeText"),G=_("badgeCount"),oe=te._read();if(t.badge=c||G?{...c&&{text:c},...G&&{countFrom:G},...oe&&{variant:oe}}:null,_("renderAs")==="pill"){const he=me._read();t.pill={style:_("pillStyle")||"filled",...he&&{variant:he}}}else t.pill=null;t.colour=p._read();const ce=_("hlHover"),de=_("hlActive"),ue=F._read();t.highlight=ce||de||ue?{...ce&&{hover:ce},...de&&{active:de},...ue&&{accent:ue}}:null,U=!0,y.close(!0),i()})}let B=null,dt=!1;function en(){dt||!window.R?.use||(dt=!0,R.use((t,r,l)=>{const s=r?.path||"";return!(Ut.test(s)&&(t?.path||"")!==s)||!B?.dirty()?l():E.confirm(`You have unsaved changes to the menu "${Le(B.name())}". Leave anyway? They are kept as a draft for your next visit.`).then(h=>{h?l():history.replaceState(null,"",`#${s}`)})}),M.subscribe("router:afterChange",({to:t}={})=>{if(B&&(t?.path||"")!==B.path){const r=B;B=null,r.dispose()}}))}function ut(t,r){const l=t.querySelector(".dm-plugin-banner-name"),s=l?.querySelector(".dm-plugin-banner-sep");if(!(!l||!s)){for(;s.nextSibling;)s.nextSibling.remove();l.appendChild(document.createTextNode(r))}}export const menuEditorView={templateUrl:"/admin/js/templates/menu-editor.html",async onMount(t){if(en(),B){const e=B;B=null,e.dispose()}const r=[],l=e=>(r.push(e),e);let s=!1;const i=t.get(0).querySelector(".mex")||t.get(0),h=()=>!s&&i.isConnected,b=location.hash.replace(/^#/,""),m=location.hash.match(/^#\/menus\/edit\/([^?#]+)/),j=m?decodeURIComponent(m[1]):null,x=!j,C=`menu-editor.draft.${j||"new"}`,L=E.loader(t.get(0),{type:"dots"});let v,z,ae,ee,W,ie,te;try{if(x)v={slug:"",name:"",description:"",items:[]};else try{v=await T.menus.get(j)}catch(e){E.toast(`Failed to load menu: ${e.message||e}`,{type:"error"}),location.hash="#/menus";return}[z,ae,ee,W,ie,te]=await Promise.all([T.projects.list().catch(()=>[]),H.get("/api/auth/permissions-registry").catch(()=>({resources:[]})),T.collections.list().catch(()=>[]),T.get("/collections/roles/entries?limit=100").catch(()=>null),T.menuLocations.registry().catch(()=>[]),T.pages.list().catch(()=>[])])}finally{L.destroy()}if(!i.isConnected)return;const He=(Array.isArray(W)?W:W?.entries||[]).map(e=>({name:e.data?.name,label:e.data?.label,level:e.data?.level??99})).filter(e=>e.name).sort((e,n)=>n.level-e.level),K=!x&&j===qt;let me=[];if(K&&(me=await H.get("/api/sidebar/registered-items").catch(()=>(E.toast("Could not load the Tools - they are not shown, and saving keeps their places as they are.",{type:"warning",duration:8e3}),[])),!i.isConnected))return;const se=e=>st(K?xt($t(e||[],me,{forEditor:!0}),{leaveInHiddenFolders:!0}):e);let p=se(v.items);const N=M.observable(!1),le=M.observable(!1),pe=M.observable(""),be=M.observable(0);let F="";const A=i.querySelector("#me-items-list");function q(){Xt(A,p,K),be.value=p.filter(e=>!Z(e)).length}const y=()=>{q(),V()},Y=()=>K?ct(p):new Set,ne=e=>p.find(n=>n.id===e);function U(e){requestAnimationFrame(()=>A.querySelector(`.menu-tree-row[data-id="${CSS.escape(e)}"]`)?.focus())}function re(e){const n=g=>p.find(d=>!d.type&&!d.url&&!d.tool&&(d.key||"").toLowerCase()===g)||p.find(d=>!d.type&&!d.url&&!d.tool&&!d.key&&(d.text||"").toLowerCase()===g);let a=n(String(e.tool.folder||"").toLowerCase())||n(Ht);const f=String(e.tool.group||"").trim();if(a&&f){const g=Lt(a.key||_t(a.text),f),d=u=>u!==e&&!u.type&&!u.url&&!u.tool;let k=p.find(u=>d(u)&&(u.key||"").toLowerCase()===g)||p.find(u=>d(u)&&u.parentId===a.id&&(!u.key||u.key.toLowerCase()===g)&&(u.text||"").toLowerCase()===f.toLowerCase());k||([k]=st([{text:f,key:g,icon:Ct,synthesised:!0}],a.id),p.push(k)),a=k}e.parentId=a?a.id:null,p.splice(p.indexOf(e),1),p.push(e),Object.assign(e,{text:e.tool.defaults.text,icon:e.tool.defaults.icon,visibility:"",hidden:!1,badge:null,pill:null,colour:"",highlight:null,touched:!1}),e.tool={...e.tool,persisted:!1}}const ye=e=>!Y().has(e.id)&&!(e.tool&&!e.tool.orphan);async function fe(e){const n=ne(e);if(!n||!ye(n))return;const a=u=>{let J=u;for(;J;){if(J.id===e)return!0;J=p.find(O=>O.id===J.parentId)}return!1},f=p.filter(u=>u.id!==e&&a(u));if(f.length&&!await E.confirm(`Remove "${Le(n.text||n.type||"this item")}" and the ${f.length} item${f.length===1?"":"s"} beneath it?`))return;const g=Y(),d=f.filter(u=>u.tool),k=f.filter(u=>!u.tool&&g.has(u.id));p=p.filter(u=>!a(u)||d.includes(u)||k.includes(u));for(const u of k)u.parentId=n.parentId??null;for(const u of d)u.tool.orphan?u.parentId=n.parentId??null:re(u);y()}function _(e){const n=ne(e);!n||Z(n)||Y().has(e)||(n.hidden=!n.hidden,n.touched=!0,y())}function c(e){const n=ne(e);!n||Z(n)||(n.locked=K&&Y().has(n.id),Qt(n,ae.resources||[],ee,He,()=>{y(),U(e)}))}function G(e){const n={id:xe(),parentId:null,...e==="separator"?{type:e}:e==="spacer"?{type:e,size:"md"}:{text:"",url:"/",icon:"",visibility:"",permission:"",hidden:!1,bundled:!1}};p.push(n),y(),Z(n)?U(n.id):c(n.id)}const oe=e=>n=>{e(n)&&(y(),U(n))},ce=oe(e=>rt(p,e,-1)),de=oe(e=>rt(p,e,1)),ue=oe(e=>Pt(p,e)),he=oe(e=>zt(p,e));function mt(e){const n=ne(e);if(!n)return[];const a=Z(n),f=Y().has(e),g=Mt(p,e),d=g.findIndex(O=>O.id===e),k=n.tool,u=k&&(k.persisted||n.touched),J=O=>()=>{const ge=Ft(p,e,O,xe());y(),ge&&!Z(ge)?c(ge.id):ge&&U(ge.id)};return[{header:a?n.type==="separator"?"Separator":"Spacer":n.text||k?.label||"(untitled)"},...a?[]:[{label:"Edit\u2026",icon:"edit",action:()=>c(e)}],{type:"divider"},{label:"Add item below",icon:"plus",action:J("item")},{label:"Add sub-item",icon:"corner-down-right",disabled:a,action:()=>{const O=jt(p,e,xe());y(),O&&c(O.id)}},{label:"Add separator below",icon:"minus",action:J("separator")},{label:"Add spacer below",icon:"move",action:J("spacer")},{type:"divider"},{label:"Move up",icon:"arrow-up",shortcut:"Alt+\u2191",disabled:d<=0,action:()=>ce(e)},{label:"Move down",icon:"arrow-down",shortcut:"Alt+\u2193",disabled:d<0||d>=g.length-1,action:()=>de(e)},{label:"Indent",icon:"chevron-right",shortcut:"Alt+\u2192",disabled:d<=0||Z(g[d-1]),action:()=>ue(e)},{label:"Outdent",icon:"chevron-left",shortcut:"Alt+\u2190",disabled:n.parentId==null,action:()=>he(e)},{type:"divider"},...a?[]:[{label:n.hidden?"Show":"Hide",icon:n.hidden?"eye":"eye-off",disabled:f,action:()=>_(e)}],{label:"Duplicate",icon:"copy",disabled:!!k,action:()=>{const O=Ot(p,e,xe);y(),O&&U(O.id)}},...k&&!k.orphan&&u?[{label:"Back to its default place",icon:"rotate-ccw",action:()=>{re(n),y()}}]:[],{label:f?"Remove - always in the sidebar":k&&!k.orphan?"Remove - a Tool is hidden, not removed":"Remove\u2026",icon:"trash",danger:!0,disabled:!ye(n),action:()=>fe(e)}]}const pt=E.contextMenu(A,{cursor:"glyph",match:".menu-tree-row",inherit:!1,density:"compact",items:e=>mt(e.dataset.id)});l(()=>pt?.destroy?.());const ft=Yt(A,()=>p,y);l(()=>ft?.destroy());const We=e=>{const n=e.target.closest(".menu-tree-row");if(!n)return;const a=n.dataset.id;if(e.target.closest(".mex-kebab")){ze(e.target.closest(".mex-kebab"));return}if(e.target.closest(".me-hidden")){_(a);return}if(e.target.closest(".me-edit")){c(a);return}e.target.closest("select, .menu-tree-grip, button")||c(a)},Ke=e=>{const n=e.target.closest(".menu-tree-row");if(!n||e.target!==n){n&&e.key==="F10"&&e.shiftKey&&(e.preventDefault(),ze(n));return}const a=n.dataset.id;if(e.key==="F10"&&e.shiftKey)e.preventDefault(),ze(n);else if(e.key==="Enter")e.preventDefault(),c(a);else if(e.key==="Delete")e.preventDefault(),fe(a);else if(e.altKey&&e.key==="ArrowUp")e.preventDefault(),ce(a);else if(e.altKey&&e.key==="ArrowDown")e.preventDefault(),de(a);else if(e.altKey&&e.key==="ArrowRight")e.preventDefault(),ue(a);else if(e.altKey&&e.key==="ArrowLeft")e.preventDefault(),he(a);else if(e.key==="ArrowDown"||e.key==="ArrowUp"){const f=[...A.querySelectorAll(".menu-tree-row")],g=f.indexOf(n)+(e.key==="ArrowDown"?1:-1);f[g]&&(e.preventDefault(),f[g].focus())}},qe=e=>{if(!e.target.matches(".me-spacer-size"))return;const n=ne(e.target.closest(".menu-tree-row")?.dataset.id);n&&(n.size=e.target.value,V())};A.addEventListener("click",We),A.addEventListener("keydown",Ke),A.addEventListener("change",qe),l(()=>{A.removeEventListener("click",We),A.removeEventListener("keydown",Ke),A.removeEventListener("change",qe)});const o=e=>t.find(e),we=o("#me-float-accent"),Ie=o("#me-float-accent-hex"),Te=()=>{Ie.get(0).style.display=we.val()==="__custom__"?"":"none"},ht=()=>we.val()==="__custom__"?Ie.val():we.val(),ke=o("#me-highlight-accent"),Re=o("#me-highlight-accent-hex"),Ue=()=>{Re.get(0).style.display=ke.val()==="__custom__"?"":"none"},vt=()=>ke.val()==="__custom__"?Re.val():ke.val(),Ge=()=>{const e=o("#me-position").val()==="floating";o(".dm-float-field").each(function(){this.style.display=e?"":"none"}),e&&Te();const n=o("#me-orientation").val()==="vertical";o(".dm-vertical-field").each(function(){this.style.display=n?"":"none"});const a=!!(o("#me-float-collapsible").get(0)||{}).checked;o(".dm-float-collapsed-field").each(function(){this.style.display=e&&a?"":"none"})},Ve=(e,n,a,f)=>{const g=o(e).get(0);g&&(g.innerHTML="",g.add(new Option(f,"")),n.forEach(d=>g.add(new Option(a[d]||d,d))))};Ve("#me-highlight-hover",tt,ot,"- theme default -"),Ve("#me-highlight-active",nt,at,"- theme default -");const De=o("#me-bind-slot"),je=o("#me-bind-projects"),Se=o("#me-bind-pages");De.html('<option value="">- not bound -</option>'+(ie||[]).map(e=>`<option value="${w(e.slot)}">${w(e.label||e.slot)} (${w(e.slot)})</option>`).join("")),je.html(z.map(e=>`<option value="${w(e.slug)}">${w(e.name||e.slug)}</option>`).join("")),o("#me-bind-page-pick").html('<option value="">- pick a page -</option>'+te.map(e=>{const n=e.urlPath||e.url||"";return n?`<option value="${w(n)}">${w(e.title||n)} - ${w(n)}</option>`:""}).join(""));const Ye=()=>Nt({slot:De.val(),projects:Array.from(je.get(0).selectedOptions).map(e=>e.value),pagesText:Se.val()});function Ne(){const e=Ye(),n=o("#me-bind-summary");if(!e){n.html('<span class="text-muted">Not bound - this menu renders only where it is mapped or placed by a shortcode.</span>');return}const a=[];e.projects.length&&a.push(`pages in ${e.projects.map(d=>`<code>${w(d)}</code>`).join(", ")}`),e.pages.length&&a.push(`pages matching ${e.pages.map(d=>`<code>${w(d)}</code>`).join(", ")}`);const f=e.pages.filter(d=>!/^\/[^\s?#*]*(\/\*)?$|^\/\*$/.test(d)),g=f.length?`<div class="text-danger" style="margin-top:.4rem">Not valid page patterns: ${f.map(d=>`<code>${w(d)}</code>`).join(", ")}</div>`:"";n.html(a.length?`Takes over the <code>${w(e.slot)}</code> slot on ${a.join(" and ")}.${g}`:`<span class="text-warning">Slot <code>${w(e.slot)}</code> selected but no project or page chosen - the binding will never match.</span>`)}const{getProjectFromHash:gt}=await import("../lib/project-context.js");if(!h())return;const bt=x?gt():null;o("#me-project").html('<option value="">- none -</option>'+z.map(e=>`<option value="${w(e.slug)}">${w(e.name||e.slug)}</option>`).join(""));function Oe(e){p=se(e.items),o("#me-variant").val(e.variant||""),o("#me-position").val(e.position||"");const n=o("#me-appearOnHover").get(0);n&&(n.checked=e.appearOnHover===!0),o("#me-float-anchor").val(e.float?.anchor||"TL"),o("#me-float-offsetX").val(e.float?.offsetX??""),o("#me-float-offsetY").val(e.float?.offsetY??""),o("#me-float-width").val(e.float?.width??""),o("#me-float-radius").val(e.float?.radius??""),o("#me-float-shadow").val(e.float?.shadow||""),o("#me-float-opacity").val(e.float?.opacity??""),o("#me-float-title").val(e.float?.title||"");for(const[d,k]of[["#me-float-collapsible",e.float?.collapsible],["#me-float-collapsed",e.float?.collapsed],["#me-float-movable",e.float?.movable],["#me-float-resizable",e.float?.resizable]]){const u=o(d).get(0);u&&(u.checked=k===!0)}const a=e.float?.accent||"";we.val(a.startsWith("#")?"__custom__":a),a.startsWith("#")&&Ie.val(a),Te(),o("#me-orientation").val(e.orientation||""),o("#me-align").val(e.align||""),o("#me-side").val(e.side||"left"),o("#me-highlight-hover").val(e.highlight?.hover||""),o("#me-highlight-active").val(e.highlight?.active||"");const f=e.highlight?.accent||"";ke.val(f.startsWith("#")?"__custom__":f),f.startsWith("#")&&Re.val(f),Ue(),o("#me-fontFamily").val(e.style?.fontFamily||""),o("#me-fontSize").val(e.style?.fontSize||""),o("#me-fontWeight").val(e.style?.fontWeight||""),o("#me-letterSpacing").val(e.style?.letterSpacing||""),o("#me-iconSize").val(e.style?.iconSize||""),De.val(e.binding?.slot||"");const g=new Set(e.binding?.projects||[]);Array.from(je.get(0).options).forEach(d=>{d.selected=g.has(d.value)}),Se.val((e.binding?.pages||[]).join(`
|
|
23
|
-
`)),o("#me-slug").val(e.slug||""),o("#me-name").val(e.name||""),o("#me-description").val(e.description||""),o("#me-project").val(e.meta?.project||
|
|
22
|
+
</div>`),g(f.id)}}g(null),t.innerHTML=i.join("")||'<p class="mex-note">No items yet - Add item, or right-click an item for more.</p>',I.scan(t)}function $(t,d={},...s){const l=document.createElement(t);Object.assign(l,d);for(const i of s)i!=null&&l.append(i);return l}function T(t,d,s){const l=$("label",{className:"form-field"},$("span",{className:"form-label",textContent:t}),d);return s&&l.append($("small",{className:"form-hint",textContent:s,style:"display:block;font-size:.78em;opacity:.7;margin-top:.25rem;line-height:1.35"})),l}function Vt(t,d){const s=[["","- Everyone -"],["public","Public - anyone, incl. logged-out"],...(d||[]).map(i=>[i.name,`${i.label||i.name} and above`]),...(d||[]).filter(i=>i.level!==0).map(i=>[`=${i.name}`,`${i.label||i.name} only`]),["private","Private - super-admin only"]];t&&!s.some(([i])=>i===t)&&s.push([t,`${t} (custom)`]);const l=Q(s,t||"");return l.name="visibility",l}function Q(t,d){const s=$("select",{className:"form-select"});return t.forEach(([l,i])=>s.add(new Option(i,l))),s.value=d??"",s}function _e(t,d){const s=typeof d=="string"&&d.startsWith("#"),l=Q([["","- none -"],["primary","primary"],["success","success"],["danger","danger"],["warning","warning"],["info","info"],["neutral","neutral"],["__custom__","Custom\u2026"]],s?"__custom__":d||""),i=$("input",{type:"color",className:"form-input me-colour-hex",value:s?d:"#000000"});i.style.display=s?"":"none",l.addEventListener("change",()=>{i.style.display=l.value==="__custom__"?"":"none"});const g=T(t,l);return g.append(i),g._read=()=>l.value==="__custom__"?i.value:l.value,g}function Yt(t,d){const s=$("input",{className:"form-input me-icon",name:"icon",value:d||""}),l=$("span",{className:"me-icon-preview"});d&&l.setAttribute("data-icon",d);const i=$("button",{type:"button",className:"btn btn-sm btn-ghost",textContent:"Browse\u2026"}),g=k=>{k?l.setAttribute("data-icon",k):l.removeAttribute("data-icon"),Domma.icons.scan(l.parentNode||l)};return i.addEventListener("click",()=>kt(k=>{s.value=k,g(k)})),s.addEventListener("input",()=>g(s.value.trim())),T(t,$("div",{className:"me-icon-field"},s,i,l))}function Ce(...t){return $("div",{className:"me-field-grid"},...t)}async function Xt(t,d,s,l,i){const g=t.text||t.tool?.label||"",k=r=>$("h4",{className:"me-form-section",textContent:r}),f=T("Label",$("input",{className:"form-input",name:"text",value:t.text||""}),"The text shown for this item."),N=$("input",{className:"form-input",name:"url",value:t.url||""}),_=T("URL",N,t.tool||t.locked?"A Tool's address is its identity, so it cannot be changed here.":"Where it links. Must start with /, #, https://, or mailto: . Leave blank for a parent that only groups sub-items.");(t.tool||t.locked)&&(N.readOnly=!0);const V=Yt("Icon",t.icon||""),A=Vt(t.visibility||"",l),h=T("Visibility",A,t.locked?"Always in the sidebar for everyone who may use it, so it cannot be restricted here.":'Who can see this item. "Role and above" shows it to that role and anyone more senior; "Role only" shows it to holders of that role alone (and the super-admin). Blank = everyone.');t.locked&&(A.disabled=!0);const B=Q([["","- no permission gate -"],...(d||[]).map(r=>[r.key,r.label||r.key])],t.permission||"");B.name="permission";const ae=T("Permission",B,t.tool||t.locked?"A Tool is guarded by its own permission, which always applies.":"Hide unless the viewer holds this specific permission. Independent of Visibility - both must pass.");(t.tool||t.locked)&&(B.disabled=!0);const Z=T("Badge text",$("input",{className:"form-input",name:"badgeText",value:t.badge?.text||""})),z=Q([["","- none -"],...(s||[]).map(r=>[r.slug,r.title||r.slug])],t.badge?.countFrom||"");z.name="badgeCount";const ie=T("Badge count from",z,"Show a live count of this collection\u2019s entries as the badge."),ee=_e("Badge colour",t.badge?.variant||""),O=Q([["link","Link"],["pill","Pill"]],t.pill?"pill":"link");O.name="renderAs";const He=T("Render as",O,"Pill draws the item as a rounded chip. Pill styling applies to top-level navbar items."),K=T("Pill style",Q([["filled","Filled"],["outline","Outline"]],t.pill?.style||"filled"));K.querySelector("select").name="pillStyle";const me=_e("Pill colour",t.pill?.variant||""),se=$("div",{className:"me-pill-wrap"},Ce(K,me));se.style.display=t.pill?"":"none",O.addEventListener("change",()=>{se.style.display=O.value==="pill"?"":"none"});const m=_e("Text colour",t.colour||""),j=Q([["","- use the menu default -"],...tt.map(r=>[r,ot[r]||r])],t.highlight?.hover||"");j.name="hlHover";const le=T("Hover effect",j,"Overrides the menu-wide hover effect for this item only."),pe=Q([["","- use the menu default -"],...nt.map(r=>[r,at[r]||r])],t.highlight?.active||"");pe.name="hlActive";const be=T("When selected",pe,"How this item is marked when it points at the page being viewed."),P=_e("Highlight colour",t.highlight?.accent||""),x=$("button",{className:"btn btn-primary",textContent:"Apply",title:"Apply to the item (Ctrl+Enter) - Save the menu to keep it"}),W=$("div",{className:"me-item-form"},k("Link"),f,_,V,k("Access"),Ce(h,ae),k("Badge"),Ce(Z,ee),ie,k("Appearance"),He,se,m,k("Highlighting"),Ce(le,be),P,x),b=E.slideover({title:g?`Edit ${Le(g)}`:"Edit menu item",size:"lg",position:"right"});b.element.appendChild(W);const Y=()=>JSON.stringify([...W.querySelectorAll("input, select, textarea")].map(r=>r.type==="checkbox"?r.checked:r.value)),te=Y();let q=!1,re=!1;Rt(b);const ye=b.close.bind(b);b.close=async r=>{if(!q&&r!==!0&&Y()!==te){if(re)return;re=!0;const U=await E.confirm("Discard the changes to this item?");if(re=!1,!U)return}return q=!0,ye()},W.addEventListener("keydown",r=>{(r.ctrlKey||r.metaKey)&&r.key==="Enter"&&(r.preventDefault(),x.click())}),b.open();const fe=b.element.closest(".dm-slideover")||b.element.querySelector(".dm-slideover")||b.element;fe.style.setProperty("width",Kt+"px","important"),fe.style.setProperty("max-width","95vw","important"),Domma.icons.scan(W);const L=r=>W.querySelector(`[name="${r}"]`)?.value||"";x.addEventListener("click",()=>{t.text=L("text"),t.icon=L("icon"),t.locked||(t.visibility=L("visibility")),!t.tool&&!t.locked?(t.url=L("url"),t.permission=L("permission")):t.touched=!0;const r=L("badgeText"),U=L("badgeCount"),ne=ee._read();if(t.badge=r||U?{...r&&{text:r},...U&&{countFrom:U},...ne&&{variant:ne}}:null,L("renderAs")==="pill"){const he=me._read();t.pill={style:L("pillStyle")||"filled",...he&&{variant:he}}}else t.pill=null;t.colour=m._read();const ce=L("hlHover"),de=L("hlActive"),ue=P._read();t.highlight=ce||de||ue?{...ce&&{hover:ce},...de&&{active:de},...ue&&{accent:ue}}:null,q=!0,b.close(!0),i()})}let F=null,ct=!1;function Jt(){ct||!window.R?.use||(ct=!0,R.use((t,d,s)=>{const l=d?.path||"";return!(qt.test(l)&&(t?.path||"")!==l)||!F?.dirty()?s():E.confirm(`You have unsaved changes to the menu "${Le(F.name())}". Leave anyway? They are kept as a draft for your next visit.`).then(g=>{g?s():history.replaceState(null,"",`#${l}`)})}),M.subscribe("router:afterChange",({to:t}={})=>{if(F&&(t?.path||"")!==F.path){const d=F;F=null,d.dispose()}}))}function dt(t,d){const s=t.querySelector(".dm-plugin-banner-name"),l=s?.querySelector(".dm-plugin-banner-sep");if(!(!s||!l)){for(;l.nextSibling;)l.nextSibling.remove();s.appendChild(document.createTextNode(d))}}export const menuEditorView={templateUrl:"/admin/js/templates/menu-editor.html",async onMount(t){if(Jt(),F){const e=F;F=null,e.dispose()}const d=[],s=e=>(d.push(e),e);let l=!1;const i=t.get(0).querySelector(".mex")||t.get(0),g=()=>!l&&i.isConnected,k=location.hash.replace(/^#/,""),f=location.hash.match(/^#\/menus\/edit\/([^?#]+)/),N=f?decodeURIComponent(f[1]):null,_=!N,V=`menu-editor.draft.${N||"new"}`,A=E.loader(t.get(0),{type:"dots"});let h,B,ae,Z,z,ie,ee;try{if(_)h={slug:"",name:"",description:"",items:[]};else try{h=await C.menus.get(N)}catch(e){E.toast(`Failed to load menu: ${e.message||e}`,{type:"error"}),location.hash="#/menus";return}[B,ae,Z,z,ie,ee]=await Promise.all([C.projects.list().catch(()=>[]),H.get("/api/auth/permissions-registry").catch(()=>({resources:[]})),C.collections.list().catch(()=>[]),C.get("/collections/roles/entries?limit=100").catch(()=>null),C.menuLocations.registry().catch(()=>[]),C.pages.list().catch(()=>[])])}finally{A.destroy()}if(!i.isConnected)return;const He=(Array.isArray(z)?z:z?.entries||[]).map(e=>({name:e.data?.name,label:e.data?.label,level:e.data?.level??99})).filter(e=>e.name).sort((e,n)=>n.level-e.level),K=!_&&N===Wt;let me=[];if(K&&(me=await H.get("/api/sidebar/registered-items").catch(()=>(E.toast("Could not load the Tools - they are not shown, and saving keeps their places as they are.",{type:"warning",duration:8e3}),[])),!i.isConnected))return;const se=e=>it(K?xt($t(e||[],me,{forEditor:!0}),{leaveInHiddenFolders:!0}):e);let m=se(h.items);const j=M.observable(!1),le=M.observable(!1),pe=M.observable(""),be=M.observable(0);let P="";const x=i.querySelector("#me-items-list");function W(){Gt(x,m,K),be.value=m.filter(e=>!oe(e)).length}const b=()=>{W(),G()},Y=()=>K?rt(m):new Set,te=e=>m.find(n=>n.id===e);function q(e){requestAnimationFrame(()=>x.querySelector(`.menu-tree-row[data-id="${CSS.escape(e)}"]`)?.focus())}function re(e){const n=v=>m.find(c=>!c.type&&!c.url&&!c.tool&&(c.key||"").toLowerCase()===v)||m.find(c=>!c.type&&!c.url&&!c.tool&&!c.key&&(c.text||"").toLowerCase()===v);let a=n(String(e.tool.folder||"").toLowerCase())||n(Ct);const p=String(e.tool.group||"").trim();if(a&&p){const v=At(a.key||Lt(a.text),p),c=u=>u!==e&&!u.type&&!u.url&&!u.tool;let w=m.find(u=>c(u)&&(u.key||"").toLowerCase()===v)||m.find(u=>c(u)&&u.parentId===a.id&&(!u.key||u.key.toLowerCase()===v)&&(u.text||"").toLowerCase()===p.toLowerCase());w||([w]=it([{text:p,key:v,icon:_t,synthesised:!0}],a.id),m.push(w)),a=w}e.parentId=a?a.id:null,m.splice(m.indexOf(e),1),m.push(e),Object.assign(e,{text:e.tool.defaults.text,icon:e.tool.defaults.icon,visibility:"",hidden:!1,badge:null,pill:null,colour:"",highlight:null,touched:!1}),e.tool={...e.tool,persisted:!1}}const ye=e=>!Y().has(e.id)&&!(e.tool&&!e.tool.orphan);async function fe(e){const n=te(e);if(!n||!ye(n))return;const a=u=>{let J=u;for(;J;){if(J.id===e)return!0;J=m.find(D=>D.id===J.parentId)}return!1},p=m.filter(u=>u.id!==e&&a(u));if(p.length&&!await E.confirm(`Remove "${Le(n.text||n.type||"this item")}" and the ${p.length} item${p.length===1?"":"s"} beneath it?`))return;const v=Y(),c=p.filter(u=>u.tool),w=p.filter(u=>!u.tool&&v.has(u.id));m=m.filter(u=>!a(u)||c.includes(u)||w.includes(u));for(const u of w)u.parentId=n.parentId??null;for(const u of c)u.tool.orphan?u.parentId=n.parentId??null:re(u);b()}function L(e){const n=te(e);!n||oe(n)||Y().has(e)||(n.hidden=!n.hidden,n.touched=!0,b())}function r(e){const n=te(e);!n||oe(n)||(n.locked=K&&Y().has(n.id),Xt(n,ae.resources||[],Z,He,()=>{b(),q(e)}))}function U(e){const n={id:Ee(),parentId:null,...e==="separator"?{type:e}:e==="spacer"?{type:e,size:"md"}:{text:"",url:"/",icon:"",visibility:"",permission:"",hidden:!1,bundled:!1}};m.push(n),b(),oe(n)?q(n.id):r(n.id)}const ne=e=>n=>{e(n)&&(b(),q(n))},ce=ne(e=>lt(m,e,-1)),de=ne(e=>lt(m,e,1)),ue=ne(e=>Ot(m,e)),he=ne(e=>Bt(m,e));function ut(e){const n=te(e);if(!n)return[];const a=oe(n),p=Y().has(e),v=zt(m,e),c=v.findIndex(D=>D.id===e),w=n.tool,u=w&&(w.persisted||n.touched),J=D=>()=>{const ge=Pt(m,e,D,Ee());b(),ge&&!oe(ge)?r(ge.id):ge&&q(ge.id)};return[{header:a?n.type==="separator"?"Separator":"Spacer":n.text||w?.label||"(untitled)"},...a?[]:[{label:"Edit\u2026",icon:"edit",action:()=>r(e)}],{type:"divider"},{label:"Add item below",icon:"plus",action:J("item")},{label:"Add sub-item",icon:"corner-down-right",disabled:a,action:()=>{const D=jt(m,e,Ee());b(),D&&r(D.id)}},{label:"Add separator below",icon:"minus",action:J("separator")},{label:"Add spacer below",icon:"move",action:J("spacer")},{type:"divider"},{label:"Move up",icon:"arrow-up",shortcut:"Alt+\u2191",disabled:c<=0,action:()=>ce(e)},{label:"Move down",icon:"arrow-down",shortcut:"Alt+\u2193",disabled:c<0||c>=v.length-1,action:()=>de(e)},{label:"Indent",icon:"chevron-right",shortcut:"Alt+\u2192",disabled:c<=0||oe(v[c-1]),action:()=>ue(e)},{label:"Outdent",icon:"chevron-left",shortcut:"Alt+\u2190",disabled:n.parentId==null,action:()=>he(e)},{type:"divider"},...a?[]:[{label:n.hidden?"Show":"Hide",icon:n.hidden?"eye":"eye-off",disabled:p,action:()=>L(e)}],{label:"Duplicate",icon:"copy",disabled:!!w,action:()=>{const D=Nt(m,e,Ee);b(),D&&q(D.id)}},...w&&!w.orphan&&u?[{label:"Back to its default place",icon:"rotate-ccw",action:()=>{re(n),b()}}]:[],{label:p?"Remove - always in the sidebar":w&&!w.orphan?"Remove - a Tool is hidden, not removed":"Remove\u2026",icon:"trash",danger:!0,disabled:!ye(n),action:()=>fe(e)}]}const mt=E.contextMenu(x,{cursor:"glyph",match:".menu-tree-row",inherit:!1,density:"compact",items:e=>ut(e.dataset.id)});s(()=>mt?.destroy?.());const pt=St(x,()=>m,b,{items:".menu-tree-row",handle:".menu-tree-grip"});s(()=>pt?.destroy());const Ke=e=>{const n=e.target.closest(".menu-tree-row");if(!n)return;const a=n.dataset.id;if(e.target.closest(".mex-kebab")){ze(e.target.closest(".mex-kebab"));return}if(e.target.closest(".me-hidden")){L(a);return}if(e.target.closest(".me-edit")){r(a);return}e.target.closest("select, .menu-tree-grip, button")||r(a)},We=e=>{const n=e.target.closest(".menu-tree-row");if(!n||e.target!==n){n&&e.key==="F10"&&e.shiftKey&&(e.preventDefault(),ze(n));return}const a=n.dataset.id;if(e.key==="F10"&&e.shiftKey)e.preventDefault(),ze(n);else if(e.key==="Enter")e.preventDefault(),r(a);else if(e.key==="Delete")e.preventDefault(),fe(a);else if(e.altKey&&e.key==="ArrowUp")e.preventDefault(),ce(a);else if(e.altKey&&e.key==="ArrowDown")e.preventDefault(),de(a);else if(e.altKey&&e.key==="ArrowRight")e.preventDefault(),ue(a);else if(e.altKey&&e.key==="ArrowLeft")e.preventDefault(),he(a);else if(e.key==="ArrowDown"||e.key==="ArrowUp"){const p=[...x.querySelectorAll(".menu-tree-row")],v=p.indexOf(n)+(e.key==="ArrowDown"?1:-1);p[v]&&(e.preventDefault(),p[v].focus())}},qe=e=>{if(!e.target.matches(".me-spacer-size"))return;const n=te(e.target.closest(".menu-tree-row")?.dataset.id);n&&(n.size=e.target.value,G())};x.addEventListener("click",Ke),x.addEventListener("keydown",We),x.addEventListener("change",qe),s(()=>{x.removeEventListener("click",Ke),x.removeEventListener("keydown",We),x.removeEventListener("change",qe)});const o=e=>t.find(e),we=o("#me-float-accent"),Ie=o("#me-float-accent-hex"),Re=()=>{Ie.get(0).style.display=we.val()==="__custom__"?"":"none"},ft=()=>we.val()==="__custom__"?Ie.val():we.val(),ke=o("#me-highlight-accent"),Te=o("#me-highlight-accent-hex"),Ue=()=>{Te.get(0).style.display=ke.val()==="__custom__"?"":"none"},ht=()=>ke.val()==="__custom__"?Te.val():ke.val(),Ge=()=>{const e=o("#me-position").val()==="floating";o(".dm-float-field").each(function(){this.style.display=e?"":"none"}),e&&Re();const n=o("#me-orientation").val()==="vertical";o(".dm-vertical-field").each(function(){this.style.display=n?"":"none"});const a=!!(o("#me-float-collapsible").get(0)||{}).checked;o(".dm-float-collapsed-field").each(function(){this.style.display=e&&a?"":"none"})},Ve=(e,n,a,p)=>{const v=o(e).get(0);v&&(v.innerHTML="",v.add(new Option(p,"")),n.forEach(c=>v.add(new Option(a[c]||c,c))))};Ve("#me-highlight-hover",tt,ot,"- theme default -"),Ve("#me-highlight-active",nt,at,"- theme default -");const je=o("#me-bind-slot"),De=o("#me-bind-projects"),Se=o("#me-bind-pages");je.html('<option value="">- not bound -</option>'+(ie||[]).map(e=>`<option value="${y(e.slot)}">${y(e.label||e.slot)} (${y(e.slot)})</option>`).join("")),De.html(B.map(e=>`<option value="${y(e.slug)}">${y(e.name||e.slug)}</option>`).join("")),o("#me-bind-page-pick").html('<option value="">- pick a page -</option>'+ee.map(e=>{const n=e.urlPath||e.url||"";return n?`<option value="${y(n)}">${y(e.title||n)} - ${y(n)}</option>`:""}).join(""));const Ye=()=>Dt({slot:je.val(),projects:Array.from(De.get(0).selectedOptions).map(e=>e.value),pagesText:Se.val()});function Ne(){const e=Ye(),n=o("#me-bind-summary");if(!e){n.html('<span class="text-muted">Not bound - this menu renders only where it is mapped or placed by a shortcode.</span>');return}const a=[];e.projects.length&&a.push(`pages in ${e.projects.map(c=>`<code>${y(c)}</code>`).join(", ")}`),e.pages.length&&a.push(`pages matching ${e.pages.map(c=>`<code>${y(c)}</code>`).join(", ")}`);const p=e.pages.filter(c=>!/^\/[^\s?#*]*(\/\*)?$|^\/\*$/.test(c)),v=p.length?`<div class="text-danger" style="margin-top:.4rem">Not valid page patterns: ${p.map(c=>`<code>${y(c)}</code>`).join(", ")}</div>`:"";n.html(a.length?`Takes over the <code>${y(e.slot)}</code> slot on ${a.join(" and ")}.${v}`:`<span class="text-warning">Slot <code>${y(e.slot)}</code> selected but no project or page chosen - the binding will never match.</span>`)}const{getProjectFromHash:vt}=await import("../lib/project-context.js");if(!g())return;const gt=_?vt():null;o("#me-project").html('<option value="">- none -</option>'+B.map(e=>`<option value="${y(e.slug)}">${y(e.name||e.slug)}</option>`).join(""));function Oe(e){m=se(e.items),o("#me-variant").val(e.variant||""),o("#me-position").val(e.position||"");const n=o("#me-appearOnHover").get(0);n&&(n.checked=e.appearOnHover===!0),o("#me-float-anchor").val(e.float?.anchor||"TL"),o("#me-float-offsetX").val(e.float?.offsetX??""),o("#me-float-offsetY").val(e.float?.offsetY??""),o("#me-float-width").val(e.float?.width??""),o("#me-float-radius").val(e.float?.radius??""),o("#me-float-shadow").val(e.float?.shadow||""),o("#me-float-opacity").val(e.float?.opacity??""),o("#me-float-title").val(e.float?.title||"");for(const[c,w]of[["#me-float-collapsible",e.float?.collapsible],["#me-float-collapsed",e.float?.collapsed],["#me-float-movable",e.float?.movable],["#me-float-resizable",e.float?.resizable]]){const u=o(c).get(0);u&&(u.checked=w===!0)}const a=e.float?.accent||"";we.val(a.startsWith("#")?"__custom__":a),a.startsWith("#")&&Ie.val(a),Re(),o("#me-orientation").val(e.orientation||""),o("#me-align").val(e.align||""),o("#me-side").val(e.side||"left"),o("#me-highlight-hover").val(e.highlight?.hover||""),o("#me-highlight-active").val(e.highlight?.active||"");const p=e.highlight?.accent||"";ke.val(p.startsWith("#")?"__custom__":p),p.startsWith("#")&&Te.val(p),Ue(),o("#me-fontFamily").val(e.style?.fontFamily||""),o("#me-fontSize").val(e.style?.fontSize||""),o("#me-fontWeight").val(e.style?.fontWeight||""),o("#me-letterSpacing").val(e.style?.letterSpacing||""),o("#me-iconSize").val(e.style?.iconSize||""),je.val(e.binding?.slot||"");const v=new Set(e.binding?.projects||[]);Array.from(De.get(0).options).forEach(c=>{c.selected=v.has(c.value)}),Se.val((e.binding?.pages||[]).join(`
|
|
23
|
+
`)),o("#me-slug").val(e.slug||""),o("#me-name").val(e.name||""),o("#me-description").val(e.description||""),o("#me-project").val(e.meta?.project||gt||""),Ge(),Ne(),W()}const ve=e=>!!(o(e).get(0)||{}).checked;function $e(){const e={variant:o("#me-variant").val(),position:o("#me-position").val(),appearOnHover:ve("#me-appearOnHover"),floatAnchor:o("#me-float-anchor").val(),floatOffsetX:o("#me-float-offsetX").val(),floatOffsetY:o("#me-float-offsetY").val(),floatWidth:o("#me-float-width").val(),floatRadius:o("#me-float-radius").val(),floatShadow:o("#me-float-shadow").val(),floatAccent:ft(),floatOpacity:o("#me-float-opacity").val(),floatTitle:o("#me-float-title").val(),floatCollapsible:ve("#me-float-collapsible"),floatCollapsed:ve("#me-float-collapsed"),floatMovable:ve("#me-float-movable"),floatResizable:ve("#me-float-resizable"),highlightHover:o("#me-highlight-hover").val(),highlightActive:o("#me-highlight-active").val(),highlightAccent:ht(),orientation:o("#me-orientation").val(),align:o("#me-align").val(),side:o("#me-side").val(),fontFamily:o("#me-fontFamily").val(),fontSize:o("#me-fontSize").val(),fontWeight:o("#me-fontWeight").val(),letterSpacing:o("#me-letterSpacing").val(),iconSize:o("#me-iconSize").val()},n={slug:o("#me-slug").val(),name:o("#me-name").val(),description:o("#me-description").val(),project:o("#me-project").val()};return Ft(e,n,Ye(),Ht(m),h.meta||{})}let Xe=!1,Pe=null;function G(){if(!P)return;const e=$e();Pe=e,j.value=Ae(e)!==P,pe.value=j.peek()||Xe?st(e).join(" "):""}const xe=e=>{e.target.closest("#me-items-list")||(e.target.matches("#me-position, #me-orientation, #me-float-collapsible")&&Ge(),e.target.matches("#me-float-accent")&&Re(),e.target.matches("#me-highlight-accent")&&Ue(),e.target.closest("#me-binding")&&Ne(),G())};i.addEventListener("input",xe),i.addEventListener("change",xe),s(()=>{i.removeEventListener("input",xe),i.removeEventListener("change",xe)}),o("#me-bind-page-add").on("click",()=>{const e=o("#me-bind-page-pick").val();if(!e)return;const n=Se.val().split(`
|
|
24
24
|
`).map(a=>a.trim()).filter(Boolean);n.includes(e)||n.push(e),Se.val(n.join(`
|
|
25
|
-
`)),Ne(),
|
|
25
|
+
`)),Ne(),G()}),Oe(h),P=Ae($e()),G();const Je=()=>{try{S.remove?S.remove(V):S.set(V,null)}catch{}};async function Fe(){if(le.peek())return;const e=$e(),n=st(e);if(n.length){Xe=!0,G(),E.toast(n.join(" "),{type:"warning",duration:7e3});return}le.value=!0;try{if(_)await C.menus.create(e);else if(e.slug!==h.slug){await C.menus.create(e);const a=await C.menuLocations.get();let p=!1;for(const[v,c]of Object.entries(a))c===h.slug&&(a[v]=e.slug,p=!0);p&&await C.menuLocations.save(a),await C.menus.remove(h.slug)}else await C.menus.update(h.slug,e);if(P=Ae(e),j.value=!1,Je(),Tt("#/menus"),E.toast("Saved.",{type:"success"}),_||e.slug!==h.slug)location.hash="#/menus/edit/"+encodeURIComponent(e.slug);else{h={...h,...e};for(const a of m)a.tool&&a.touched&&(a.tool={...a.tool,persisted:!0});W(),P=Ae($e()),G(),dt(t.get(0),e.name||e.slug)}if(K)try{document.dispatchEvent(new CustomEvent("dm:sidebar-rebuild"))}catch{}}catch(a){E.toast(`Save failed: ${a.message||a}`,{type:"error"})}finally{le.value=!1}}async function bt(){!j.peek()||!await E.confirm("Throw away the changes you have not saved?")||(Oe(h),G())}E.tabs(o("#me-tabs").get(0));const yt=M.applyBindings({dirty:j,saving:le,problems:pe,itemCount:be},i,{methods:{save:()=>Fe(),discard:()=>bt(),addItem:()=>U("item"),addSeparator:()=>U("separator"),addSpacer:()=>U("spacer")}});s(()=>yt.dispose()),s(It(i,{position:"bottom"})),dt(t.get(0),_?"New menu":h.name||h.slug),Be(t,{id:"menu-editor-back",icon:"arrow-left",title:"All menus",onClick:()=>{location.hash="#/menus"}}),Be(t,{id:"menu-editor-locations",icon:"map-pin",title:"Menu locations",onClick:()=>{location.hash="#/menu-locations"}}),Be(t,{id:"menu-editor-save",icon:"save",title:"Save (Ctrl+S)",onClick:()=>Fe()});const Qe=e=>{if(!(!(e.ctrlKey||e.metaKey)||e.key!=="s")){if(e.preventDefault(),e.stopImmediatePropagation(),document.querySelector(".me-item-form")?.offsetParent){E.toast("Apply the item first (Ctrl+Enter), then Save.",{type:"info"});return}Fe()}};document.addEventListener("keydown",Qe,!0),s(()=>document.removeEventListener("keydown",Qe,!0));const Ze=()=>{if(!(!j.peek()||!Pe))try{S.set(V,{menu:Pe,base:P,at:new Date().toISOString()})}catch{}},et=e=>{j.peek()&&(Ze(),e.preventDefault(),e.returnValue="")};window.addEventListener("beforeunload",et),s(()=>window.removeEventListener("beforeunload",et)),F={path:k,dirty:()=>j.peek(),name:()=>o("#me-name").val()||h.name||h.slug||"new menu",dispose(){l=!0,Ze(),d.splice(0).reverse().forEach(e=>{try{e()}catch{}})}},I.scan(i);let X=null;try{X=S.get(V)}catch{}if(X?.menu){Je();const e=X.base&&X.base!==P,n=X.at?` (${Mt(X.at)})`:"",a=_?"the new menu you started":`the menu "${Le(h.name||h.slug)}"`,p=e?`You left unsaved changes to ${a}${n}, but the saved menu has changed since. Restore your version anyway?`:`You left unsaved changes to ${a}${n}. Restore them?`;await E.confirm(p)&&g()&&(Oe({...X.menu,meta:{...h.meta||{},...X.menu.meta||{}}}),G())}}};
|