domma-cms 0.6.13 → 0.6.14
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/config/plugins.json +4 -0
- package/config/site.json +2 -2
- package/package.json +2 -2
- package/plugins/site-search/admin/templates/site-search.html +67 -0
- package/plugins/site-search/admin/views/site-search.js +45 -0
- package/plugins/site-search/config.js +10 -0
- package/plugins/site-search/plugin.js +188 -0
- package/plugins/site-search/plugin.json +37 -0
- package/plugins/site-search/public/inject-body.html +17 -0
- package/plugins/site-search/public/inject-head.html +1 -0
- package/plugins/site-search/public/search.css +1 -0
- package/plugins/site-search/public/search.js +1 -0
- package/public/css/site.css +1 -1
- package/server/services/markdown.js +35 -6
package/admin/css/admin.css
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
.dashboard-layout{display:flex;flex-direction:column;min-height:100vh}.dashboard-wrapper{display:flex;flex:1;min-height:0}.dashboard-main{flex:1;min-width:0;overflow-y:auto}.view-container{padding:1.5rem 2rem;max-width:1200px}.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:.5rem}.stat-card .card-body{display:flex;align-items:center;gap:1rem}.stat-icon{width:44px;height:44px;border-radius:8px;background:var(--primary-alpha, rgba(91,140,255,.15));color:var(--primary, #5b8cff);display:flex;align-items:center;justify-content:center;font-size:1.25rem;flex-shrink:0}.stat-icon--success{background:#34d39926;color:#34d399}.stat-icon--warning{background:#fbbf2426;color:#fbbf24}.stat-value{font-size:1.75rem;font-weight:700;line-height:1}.stat-label{font-size:.8rem;color:var(--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(--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}#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}.page-live-preview-frame{display:block;width:100%;height:calc(100vh - 180px);border:none;border-radius:6px}.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(--border-color, rgba(255, 255, 255, .08));flex-wrap:wrap;flex-shrink:0}.editor-toolbar-btn{background:none;border:none;color:var(--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(--text, #eee);background:#ffffff14}.editor-toolbar-sep{width:1px;height:20px;background:var(--border-color, 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(--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(--text, #eee);background:#ffffff14}.editor-view-btn.active{color:var(--primary, #5b8cff);background:var(--primary-alpha, rgba(91, 140, 255, .12))}.editor-body{display:flex;flex:1;min-height: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(--border-color, 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-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:1px;background:var(--border-color, rgba(255,255,255,.08));flex-shrink:0}.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-preview{flex:1;padding:1rem;overflow-y:auto;line-height:1.7}.editor-preview h1,.editor-preview h2,.editor-preview h3{margin-top:1.5rem}.editor-preview p{margin-bottom:.75rem}.editor-preview code{background:#ffffff0f;padding:.1em .3em;border-radius:3px;font-size:.9em}.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(--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(--border-color, rgba(255, 255, 255, .08))}.docs-body .table{margin-bottom:.75rem}.nav-items-header,.nav-item-row{display:flex;gap:.5rem;align-items:center;padding:.35rem .75rem}.nav-items-header{border-bottom:1px solid var(--border-color, rgba(255,255,255,.08));padding-bottom:.4rem;margin-bottom:.25rem}.nav-item-row{border-bottom:1px solid var(--border-color, rgba(255,255,255,.04))}.nav-item-row:last-child{border-bottom:none}.nav-col-indent{width:18px;flex-shrink:0;color:var(--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:#ffffff05}.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(--text-muted, #888)}.btn-toggle-hidden.active{color:var(--color-warning, #f59e0b)}.fb-field-card.fb-drag-over{outline:2px dashed var(--primary, #6366f1);outline-offset:-2px}.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(auto-fill,minmax(280px,1fr));gap:1rem}.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(--card-bg, rgba(255,255,255,.04));border:1px solid var(--border-color, 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(--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(--primary, #7c6af7);border-radius:3px;background:var(--input-bg, transparent);color:inherit;outline:none}.media-size{font-size:.75rem;color:var(--text-muted, #888)}.media-actions{padding:.5rem .75rem;display:flex;gap:.4rem;border-top:1px solid var(--border-color, rgba(255,255,255,.08))}#admin-topbar{height:60px;display:flex;align-items:center;gap:1rem;padding:0 1.25rem;background:var(--navbar-bg, rgba(0,0,0,.3));border-bottom:1px solid var(--border-color, 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(--primary, #5b8cff);width:22px;height:22px}.topbar-brand-text{opacity:.85}.topbar-user{display:flex;align-items:center;gap:.6rem;flex:1}.topbar-user-name{font-size:.875rem;font-weight:500}.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:#5b8cff26;color:#5b8cff}.topbar-role-badge--manager{background:#34d39926;color:#34d399}.topbar-role-badge--editor{background:#fbbf2426;color:#fbbf24}.topbar-role-badge--subscriber{background:#94a3b826;color:#94a3b8}.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(--text-muted, #888);text-decoration:none;padding:.4rem .65rem;border-radius:6px;transition:color .15s,background .15s}.topbar-action-link:hover{color:var(--text, #eee);background:#ffffff0f}.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(--body-bg, #0f1117);z-index:100;overflow-y:auto}.login-card{width:100%;max-width:460px}.ob-done-icon{font-size:3rem;color:#34d399;margin-bottom:1rem;text-align:center}.btn-skip{display:block;text-align:center;margin-top:.75rem;font-size:.85rem;color:var(--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(--border-color, rgba(255,255,255,.1));border-radius:8px;overflow:hidden;cursor:pointer;transition:border-color .15s,transform .1s}.theme-swatch:hover{border-color:var(--primary, #5b8cff);transform:translateY(-1px)}.theme-swatch.selected{border-color:var(--primary, #5b8cff);box-shadow:0 0 0 2px var(--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(--card-bg, rgba(255,255,255,.04))}.theme-swatch-mode{color:var(--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(--primary, #5b8cff)}.login-logo h1{margin:0;font-size:1.5rem;font-weight:700}.login-heading{font-size:1.1rem;font-weight:600;margin-bottom:1.25rem}.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-card .card-body{flex:1}.plugin-header{display:flex;align-items:flex-start;gap:.75rem;margin-bottom:.75rem}.plugin-icon{width:40px;height:40px;border-radius:8px;background:var(--primary-alpha, rgba(91,140,255,.15));color:var(--primary, #5b8cff);display:flex;align-items:center;justify-content:center;flex-shrink:0}.plugin-meta{flex:1;min-width:0}.plugin-name{font-weight:600;margin-bottom:.15rem}.plugin-version{font-size:.75rem;color:var(--text-muted, #888)}.plugin-desc{font-size:.875rem;color:var(--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(--border-color, rgba(255,255,255,.08))}#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:var(--dm-primary-alpha, rgba(91,140,255,.12));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(--text-muted, #888)}@media(max-width:768px){.view-container{padding:1rem}.editor-body{flex-direction:column}.editor-divider{width:auto;height:1px}}.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(--border, rgba(255, 255, 255, .1))}.image-editor-sep{display:inline-block;width:1px;height:1.5rem;background:var(--border, rgba(255, 255, 255, .15));margin:0 .25rem;flex-shrink:0}.editor-toolbar-btn.active{color:var(--primary, #7c6af7);background:color-mix(in srgb,var(--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(--border-color, rgba(255, 255, 255, .1));border-radius:8px;box-shadow:0 8px 24px #0006;padding:4px;min-width:160px}.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:#ffffff14;color:var(--dm-text-bright, #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(--border-color, 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:#ffffff14;color:var(--dm-text-bright, #fff)}.editor-icon-picker{position:absolute;z-index:1000;background:var(--dm-surface, #1e1e2e);border:1px solid var(--border-color, 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(--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:#ffffff14;color:var(--dm-text-bright, #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(--border, rgba(255, 255, 255, .1));font-size:.85rem}.image-editor-resize label{font-weight:600;color:var(--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(--border, rgba(255, 255, 255, .1));gap:.5rem}.image-editor-effects{border-top:1px solid var(--border, rgba(255, 255, 255, .1))}.image-editor-tab-bar{display:flex;flex-direction:row;overflow-x:auto;border-bottom:1px solid var(--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(--text-muted, #888);white-space:nowrap;transition:color .15s,border-color .15s;flex-shrink:0}.image-editor-tab-btn:hover{color:var(--text, #eee)}.image-editor-tab-btn.active{color:var(--primary, #7c6af7);border-bottom-color:var(--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(--primary, #7c6af7);background:color-mix(in srgb,var(--primary, #7c6af7) 15%,transparent);border-color:var(--primary, #7c6af7)}.ie-server-note{font-size:.73rem;color:var(--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(--text-muted, #888);font-weight:600;flex-shrink:0}.ie-slider{flex:1;accent-color:var(--primary, #7c6af7);cursor:pointer}.ie-slider-val{width:3rem;font-size:.8rem;text-align:right;color:var(--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(--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(--surface-2, 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(--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(--surface-2, rgba(255, 255, 255, .08));border-color:var(--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(--text-muted, #888);text-align:center;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:72px}.dm-slideover-header{display:flex;align-items:center;justify-content:space-between;padding:.75rem 1rem;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-y:auto;min-height:0}.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-surface-subtle, 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-surface-subtle, 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}
|
|
1
|
+
.dashboard-layout{display:flex;flex-direction:column;min-height:100vh}.dashboard-wrapper{display:flex;flex:1;min-height:0}.dashboard-main{flex:1;min-width:0;overflow-y:auto}.view-container{padding:1.5rem 2rem;max-width:1200px}.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:.5rem}.stat-card .card-body{display:flex;align-items:center;gap:1rem}.stat-icon{width:44px;height:44px;border-radius:8px;background:var(--primary-alpha, rgba(91,140,255,.15));color:var(--primary, #5b8cff);display:flex;align-items:center;justify-content:center;font-size:1.25rem;flex-shrink:0}.stat-icon--success{background:#34d39926;color:#34d399}.stat-icon--warning{background:#fbbf2426;color:#fbbf24}.stat-value{font-size:1.75rem;font-weight:700;line-height:1}.stat-label{font-size:.8rem;color:var(--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(--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}#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}.page-live-preview-frame{display:block;width:100%;height:calc(100vh - 180px);border:none;border-radius:6px}.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(--border-color, rgba(255, 255, 255, .08));flex-wrap:wrap;flex-shrink:0}.editor-toolbar-btn{background:none;border:none;color:var(--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(--text, #eee);background:#ffffff14}.editor-toolbar-sep{width:1px;height:20px;background:var(--border-color, 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(--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(--text, #eee);background:#ffffff14}.editor-view-btn.active{color:var(--primary, #5b8cff);background:var(--primary-alpha, rgba(91, 140, 255, .12))}.editor-body{display:flex;flex:1;min-height: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(--border-color, 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-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:1px;background:var(--border-color, rgba(255,255,255,.08));flex-shrink:0}.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-preview{flex:1;padding:1rem;overflow-y:auto;line-height:1.7}.editor-preview h1,.editor-preview h2,.editor-preview h3{margin-top:1.5rem}.editor-preview p{margin-bottom:.75rem}.editor-preview code{background:#ffffff0f;padding:.1em .3em;border-radius:3px;font-size:.9em}.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(--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(--border-color, rgba(255, 255, 255, .08))}.docs-body .table{margin-bottom:.75rem}.nav-items-header,.nav-item-row{display:flex;gap:.5rem;align-items:center;padding:.35rem .75rem}.nav-items-header{border-bottom:1px solid var(--border-color, rgba(255,255,255,.08));padding-bottom:.4rem;margin-bottom:.25rem}.nav-item-row{border-bottom:1px solid var(--border-color, rgba(255,255,255,.04))}.nav-item-row:last-child{border-bottom:none}.nav-col-indent{width:18px;flex-shrink:0;color:var(--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:#ffffff05}.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(--text-muted, #888)}.btn-toggle-hidden.active{color:var(--color-warning, #f59e0b)}.fb-field-card.fb-drag-over{outline:2px dashed var(--primary, #6366f1);outline-offset:-2px}.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(auto-fill,minmax(280px,1fr));gap:1rem}.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(--card-bg, rgba(255,255,255,.04));border:1px solid var(--border-color, 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(--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(--primary, #7c6af7);border-radius:3px;background:var(--input-bg, transparent);color:inherit;outline:none}.media-size{font-size:.75rem;color:var(--text-muted, #888)}.media-actions{padding:.5rem .75rem;display:flex;gap:.4rem;border-top:1px solid var(--border-color, rgba(255,255,255,.08))}#admin-topbar{height:60px;display:flex;align-items:center;gap:1rem;padding:0 1.25rem;background:var(--navbar-bg, rgba(0,0,0,.3));border-bottom:1px solid var(--border-color, 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(--primary, #5b8cff);width:22px;height:22px}.topbar-brand-text{opacity:.85}.topbar-user{display:flex;align-items:center;gap:.6rem;flex:1}.topbar-user-name{font-size:.875rem;font-weight:500}.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:#5b8cff26;color:#5b8cff}.topbar-role-badge--manager{background:#34d39926;color:#34d399}.topbar-role-badge--editor{background:#fbbf2426;color:#fbbf24}.topbar-role-badge--subscriber{background:#94a3b826;color:#94a3b8}.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(--text-muted, #888);text-decoration:none;padding:.4rem .65rem;border-radius:6px;transition:color .15s,background .15s}.topbar-action-link:hover{color:var(--text, #eee);background:#ffffff0f}.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(--body-bg, #0f1117);z-index:100;overflow-y:auto}.login-card{width:100%;max-width:460px}.ob-done-icon{font-size:3rem;color:#34d399;margin-bottom:1rem;text-align:center}.btn-skip{display:block;text-align:center;margin-top:.75rem;font-size:.85rem;color:var(--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(--border-color, rgba(255,255,255,.1));border-radius:8px;overflow:hidden;cursor:pointer;transition:border-color .15s,transform .1s}.theme-swatch:hover{border-color:var(--primary, #5b8cff);transform:translateY(-1px)}.theme-swatch.selected{border-color:var(--primary, #5b8cff);box-shadow:0 0 0 2px var(--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(--card-bg, rgba(255,255,255,.04))}.theme-swatch-mode{color:var(--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(--primary, #5b8cff)}.login-logo h1{margin:0;font-size:1.5rem;font-weight:700}.login-heading{font-size:1.1rem;font-weight:600;margin-bottom:1.25rem}.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-card .card-body{flex:1}.plugin-header{display:flex;align-items:flex-start;gap:.75rem;margin-bottom:.75rem}.plugin-icon{width:40px;height:40px;border-radius:8px;background:var(--primary-alpha, rgba(91,140,255,.15));color:var(--primary, #5b8cff);display:flex;align-items:center;justify-content:center;flex-shrink:0}.plugin-meta{flex:1;min-width:0}.plugin-name{font-weight:600;margin-bottom:.15rem}.plugin-version{font-size:.75rem;color:var(--text-muted, #888)}.plugin-desc{font-size:.875rem;color:var(--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(--border-color, rgba(255,255,255,.08))}#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:var(--dm-primary-alpha, rgba(91,140,255,.12));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(--text-muted, #888)}@media(max-width:768px){.view-container{padding:1rem}.editor-body{flex-direction:column}.editor-divider{width:auto;height:1px}}.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(--border, rgba(255, 255, 255, .1))}.image-editor-sep{display:inline-block;width:1px;height:1.5rem;background:var(--border, rgba(255, 255, 255, .15));margin:0 .25rem;flex-shrink:0}.editor-toolbar-btn.active{color:var(--primary, #7c6af7);background:color-mix(in srgb,var(--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(--border-color, rgba(255, 255, 255, .1));border-radius:8px;box-shadow:0 8px 24px #0006;padding:4px;min-width:160px}.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:#ffffff14;color:var(--dm-text-bright, #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(--border-color, 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:#ffffff14;color:var(--dm-text-bright, #fff)}.editor-icon-picker{position:absolute;z-index:1000;background:var(--dm-surface, #1e1e2e);border:1px solid var(--border-color, 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(--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:#ffffff14;color:var(--dm-text-bright, #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(--border, rgba(255, 255, 255, .1));font-size:.85rem}.image-editor-resize label{font-weight:600;color:var(--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(--border, rgba(255, 255, 255, .1));gap:.5rem}.image-editor-effects{border-top:1px solid var(--border, rgba(255, 255, 255, .1))}.image-editor-tab-bar{display:flex;flex-direction:row;overflow-x:auto;border-bottom:1px solid var(--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(--text-muted, #888);white-space:nowrap;transition:color .15s,border-color .15s;flex-shrink:0}.image-editor-tab-btn:hover{color:var(--text, #eee)}.image-editor-tab-btn.active{color:var(--primary, #7c6af7);border-bottom-color:var(--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(--primary, #7c6af7);background:color-mix(in srgb,var(--primary, #7c6af7) 15%,transparent);border-color:var(--primary, #7c6af7)}.ie-server-note{font-size:.73rem;color:var(--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(--text-muted, #888);font-weight:600;flex-shrink:0}.ie-slider{flex:1;accent-color:var(--primary, #7c6af7);cursor:pointer}.ie-slider-val{width:3rem;font-size:.8rem;text-align:right;color:var(--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(--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(--surface-2, 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(--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(--surface-2, rgba(255, 255, 255, .08));border-color:var(--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(--text-muted, #888);text-align:center;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:72px}.dm-slideover-header{display:flex;align-items:center;justify-content:space-between;padding:.75rem 1rem;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-y:auto;min-height:0}.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-surface-subtle, 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-surface-subtle, 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}}
|
package/config/plugins.json
CHANGED
package/config/site.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"tagline": "A nice little bloggy type thingy.",
|
|
4
4
|
"fontFamily": "Roboto",
|
|
5
5
|
"fontSize": 16,
|
|
6
|
-
"theme": "charcoal-
|
|
6
|
+
"theme": "charcoal-light",
|
|
7
7
|
"autoTheme": {
|
|
8
8
|
"enabled": false,
|
|
9
9
|
"dayTheme": "charcoal-light",
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
"dayStart": "07:00",
|
|
12
12
|
"nightStart": "19:00"
|
|
13
13
|
},
|
|
14
|
-
"adminTheme": "
|
|
14
|
+
"adminTheme": "silver-dark",
|
|
15
15
|
"layoutOptions": {
|
|
16
16
|
"spacerSize": 40
|
|
17
17
|
},
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "domma-cms",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.14",
|
|
4
4
|
"description": "File-based CMS powered by Domma and Fastify. Run npx domma-cms my-site to create a new project.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "server/server.js",
|
|
@@ -71,7 +71,7 @@
|
|
|
71
71
|
"@fastify/rate-limit": "^10.3.0",
|
|
72
72
|
"@fastify/static": "^8.1.0",
|
|
73
73
|
"bcryptjs": "^3.0.3",
|
|
74
|
-
"domma-js": "^0.21.
|
|
74
|
+
"domma-js": "^0.21.1",
|
|
75
75
|
"dotenv": "^17.2.3",
|
|
76
76
|
"fastify": "5.8.1",
|
|
77
77
|
"gray-matter": "^4.0.3",
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
<div class="view-header">
|
|
2
|
+
<h1><span data-icon="search"></span> Site Search</h1>
|
|
3
|
+
<div>
|
|
4
|
+
<button id="save-settings-btn" class="btn btn-primary">
|
|
5
|
+
<span data-icon="save"></span> Save
|
|
6
|
+
</button>
|
|
7
|
+
</div>
|
|
8
|
+
</div>
|
|
9
|
+
|
|
10
|
+
<div class="card mb-4">
|
|
11
|
+
<div class="card-header"><h2>Settings</h2></div>
|
|
12
|
+
<div class="card-body">
|
|
13
|
+
|
|
14
|
+
<div class="row mb-3">
|
|
15
|
+
<div class="col">
|
|
16
|
+
<label class="form-label">Search placeholder text</label>
|
|
17
|
+
<input id="field-placeholder" type="text" class="form-input" placeholder="Search pages...">
|
|
18
|
+
<span class="form-hint">Displayed inside the search input when empty.</span>
|
|
19
|
+
</div>
|
|
20
|
+
</div>
|
|
21
|
+
|
|
22
|
+
<div class="row mb-3">
|
|
23
|
+
<div class="col">
|
|
24
|
+
<label class="form-check-label">
|
|
25
|
+
<input id="field-keyboard-shortcut" type="checkbox">
|
|
26
|
+
Enable keyboard shortcut (Ctrl+K / ⌘K)
|
|
27
|
+
</label>
|
|
28
|
+
<span class="form-hint">Allows visitors to open the search overlay using a keyboard shortcut.</span>
|
|
29
|
+
</div>
|
|
30
|
+
</div>
|
|
31
|
+
|
|
32
|
+
<div class="row mb-3">
|
|
33
|
+
<div class="col-6">
|
|
34
|
+
<label class="form-label">Max results</label>
|
|
35
|
+
<input id="field-max-results" type="number" class="form-input" min="1" max="50" placeholder="10">
|
|
36
|
+
<span class="form-hint">Maximum number of results to return per search (1–50).</span>
|
|
37
|
+
</div>
|
|
38
|
+
<div class="col-6">
|
|
39
|
+
<label class="form-label">Minimum query length</label>
|
|
40
|
+
<input id="field-min-query-length" type="number" class="form-input" min="1" max="5" placeholder="2">
|
|
41
|
+
<span class="form-hint">Minimum characters required before searching (1–5).</span>
|
|
42
|
+
</div>
|
|
43
|
+
</div>
|
|
44
|
+
|
|
45
|
+
<div class="row">
|
|
46
|
+
<div class="col-6">
|
|
47
|
+
<label class="form-label">Debounce delay (ms)</label>
|
|
48
|
+
<input id="field-debounce-ms" type="number" class="form-input" min="100" max="1000" placeholder="300">
|
|
49
|
+
<span class="form-hint">Delay after typing stops before search fires (100–1000ms).</span>
|
|
50
|
+
</div>
|
|
51
|
+
</div>
|
|
52
|
+
|
|
53
|
+
</div>
|
|
54
|
+
</div>
|
|
55
|
+
|
|
56
|
+
<div class="card mb-4">
|
|
57
|
+
<div class="card-header"><h2>How it works</h2></div>
|
|
58
|
+
<div class="card-body">
|
|
59
|
+
<p class="text-muted mb-2">Site Search adds a search icon to the public navbar. Visitors can click it or use
|
|
60
|
+
the keyboard shortcut to open a full-screen overlay with live results.</p>
|
|
61
|
+
<ul class="text-muted" style="padding-left:1.25rem;line-height:1.8;">
|
|
62
|
+
<li>Results are weighted: title matches score highest, followed by tags, description, and page content.</li>
|
|
63
|
+
<li>Draft pages and private pages are excluded from results.</li>
|
|
64
|
+
<li>Use <kbd>↑</kbd> <kbd>↓</kbd> to navigate results, <kbd>↵</kbd> to open, <kbd>Esc</kbd> to close.</li>
|
|
65
|
+
</ul>
|
|
66
|
+
</div>
|
|
67
|
+
</div>
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Site Search Plugin — Admin Settings View
|
|
3
|
+
*/
|
|
4
|
+
import {apiRequest} from '/admin/js/api.js';
|
|
5
|
+
|
|
6
|
+
export const siteSearchView = {
|
|
7
|
+
templateUrl: '/plugins/site-search/admin/templates/site-search.html',
|
|
8
|
+
|
|
9
|
+
async onMount($container) {
|
|
10
|
+
let settings = {};
|
|
11
|
+
try {
|
|
12
|
+
settings = await apiRequest('/plugins/site-search/settings');
|
|
13
|
+
} catch {
|
|
14
|
+
E.toast('Could not load settings.', {type: 'error'});
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
$container.find('#field-placeholder').val(settings.placeholder || 'Search pages...');
|
|
18
|
+
$container.find('#field-keyboard-shortcut').prop('checked', settings.keyboardShortcut !== false);
|
|
19
|
+
$container.find('#field-max-results').val(settings.maxResults ?? 10);
|
|
20
|
+
$container.find('#field-min-query-length').val(settings.minQueryLength ?? 2);
|
|
21
|
+
$container.find('#field-debounce-ms').val(settings.debounceMs ?? 300);
|
|
22
|
+
|
|
23
|
+
$container.find('#save-settings-btn').off('click').on('click', async () => {
|
|
24
|
+
const data = {
|
|
25
|
+
placeholder: $container.find('#field-placeholder').val() || 'Search pages...',
|
|
26
|
+
keyboardShortcut: $container.find('#field-keyboard-shortcut').prop('checked'),
|
|
27
|
+
maxResults: parseInt($container.find('#field-max-results').val(), 10) || 10,
|
|
28
|
+
minQueryLength: parseInt($container.find('#field-min-query-length').val(), 10) || 2,
|
|
29
|
+
debounceMs: parseInt($container.find('#field-debounce-ms').val(), 10) || 300
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
try {
|
|
33
|
+
await apiRequest('/plugins/site-search/settings', {
|
|
34
|
+
method: 'PUT',
|
|
35
|
+
body: JSON.stringify(data)
|
|
36
|
+
});
|
|
37
|
+
E.toast('Settings saved.', {type: 'success'});
|
|
38
|
+
} catch {
|
|
39
|
+
E.toast('Failed to save settings.', {type: 'error'});
|
|
40
|
+
}
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
Domma.icons.scan();
|
|
44
|
+
}
|
|
45
|
+
};
|
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Site Search Plugin — Server
|
|
3
|
+
*
|
|
4
|
+
* Endpoints (prefix: /api/plugins/site-search):
|
|
5
|
+
* GET /search?q=term — public: full-text search across all published pages
|
|
6
|
+
* GET /settings — public: return plugin settings (used by inject script)
|
|
7
|
+
* PUT /settings — admin-auth: save user overrides
|
|
8
|
+
*/
|
|
9
|
+
import {listPages} from '../../server/services/content.js';
|
|
10
|
+
import {getPluginSettings, savePluginState} from '../../server/services/plugins.js';
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Strip markdown syntax and shortcodes from content for plain-text searching.
|
|
14
|
+
*
|
|
15
|
+
* @param {string} content
|
|
16
|
+
* @returns {string}
|
|
17
|
+
*/
|
|
18
|
+
function stripMarkdown(content) {
|
|
19
|
+
if (!content) return '';
|
|
20
|
+
return content
|
|
21
|
+
// Remove shortcodes (self-closing and wrapping)
|
|
22
|
+
.replace(/\[[a-z][^\]]*\/\]/gi, '')
|
|
23
|
+
.replace(/\[[a-z][^\]]*\][\s\S]*?\[\/[a-z]+\]/gi, '')
|
|
24
|
+
.replace(/\[[a-z][^\]]*\]/gi, '')
|
|
25
|
+
// Remove HTML tags
|
|
26
|
+
.replace(/<[^>]+>/g, '')
|
|
27
|
+
// Remove headings (keep text)
|
|
28
|
+
.replace(/^#{1,6}\s+/gm, '')
|
|
29
|
+
// Remove bold / italic
|
|
30
|
+
.replace(/\*{1,3}([^*]+)\*{1,3}/g, '$1')
|
|
31
|
+
.replace(/_{1,3}([^_]+)_{1,3}/g, '$1')
|
|
32
|
+
// Remove images
|
|
33
|
+
.replace(/!\[[^\]]*\]\([^)]*\)/g, '')
|
|
34
|
+
// Remove links (keep text)
|
|
35
|
+
.replace(/\[([^\]]+)\]\([^)]*\)/g, '$1')
|
|
36
|
+
// Remove code blocks
|
|
37
|
+
.replace(/```[\s\S]*?```/g, '')
|
|
38
|
+
.replace(/`[^`]+`/g, '')
|
|
39
|
+
// Remove blockquotes marker
|
|
40
|
+
.replace(/^>\s+/gm, '')
|
|
41
|
+
// Collapse whitespace
|
|
42
|
+
.replace(/\s+/g, ' ')
|
|
43
|
+
.trim();
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Build a snippet of ~length chars around the first occurrence of term in content.
|
|
48
|
+
*
|
|
49
|
+
* @param {string} rawContent - raw markdown content
|
|
50
|
+
* @param {string} term
|
|
51
|
+
* @param {number} length
|
|
52
|
+
* @returns {string}
|
|
53
|
+
*/
|
|
54
|
+
function buildSnippet(rawContent, term, length = 120) {
|
|
55
|
+
const text = stripMarkdown(rawContent);
|
|
56
|
+
if (!text) return '';
|
|
57
|
+
|
|
58
|
+
const lower = text.toLowerCase();
|
|
59
|
+
const idx = lower.indexOf(term.toLowerCase());
|
|
60
|
+
|
|
61
|
+
if (idx === -1) {
|
|
62
|
+
return text.length > length ? text.slice(0, length) + '…' : text;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
const half = Math.floor(length / 2);
|
|
66
|
+
const start = Math.max(0, idx - half);
|
|
67
|
+
const end = Math.min(text.length, start + length);
|
|
68
|
+
const snippet = text.slice(start, end);
|
|
69
|
+
|
|
70
|
+
return (start > 0 ? '…' : '') + snippet + (end < text.length ? '…' : '');
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Score a page against a search query using weighted field matching.
|
|
75
|
+
*
|
|
76
|
+
* @param {object} page
|
|
77
|
+
* @param {string} query
|
|
78
|
+
* @param {string[]} words - query split into words
|
|
79
|
+
* @returns {number}
|
|
80
|
+
*/
|
|
81
|
+
function scorePage(page, query, words) {
|
|
82
|
+
let score = 0;
|
|
83
|
+
const title = (page.title || '').toLowerCase();
|
|
84
|
+
const description = (page.description || '').toLowerCase();
|
|
85
|
+
const tagsRaw = Array.isArray(page.tags) ? page.tags : [];
|
|
86
|
+
const tags = tagsRaw.map(t => t.toLowerCase());
|
|
87
|
+
const stripped = stripMarkdown(page.content || '').toLowerCase();
|
|
88
|
+
const q = query.toLowerCase();
|
|
89
|
+
|
|
90
|
+
// Title scoring
|
|
91
|
+
if (title === q) {
|
|
92
|
+
score += 100;
|
|
93
|
+
} else if (title.includes(q)) {
|
|
94
|
+
score += 60;
|
|
95
|
+
} else if (words.every(w => title.includes(w))) {
|
|
96
|
+
score += 40;
|
|
97
|
+
} else if (words.some(w => title.includes(w))) {
|
|
98
|
+
score += 20;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
// Tags scoring
|
|
102
|
+
if (tags.includes(q)) {
|
|
103
|
+
score += 30;
|
|
104
|
+
} else if (tags.some(t => t.includes(q))) {
|
|
105
|
+
score += 20;
|
|
106
|
+
} else if (words.every(w => tags.some(t => t.includes(w)))) {
|
|
107
|
+
score += 15;
|
|
108
|
+
} else if (words.some(w => tags.some(t => t.includes(w)))) {
|
|
109
|
+
score += 8;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// Description scoring
|
|
113
|
+
if (description.includes(q)) {
|
|
114
|
+
score += 25;
|
|
115
|
+
} else if (words.some(w => description.includes(w))) {
|
|
116
|
+
score += 10;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
// Content scoring
|
|
120
|
+
if (stripped.includes(q)) {
|
|
121
|
+
score += 10;
|
|
122
|
+
} else if (words.every(w => stripped.includes(w))) {
|
|
123
|
+
score += 5;
|
|
124
|
+
} else if (words.some(w => stripped.includes(w))) {
|
|
125
|
+
score += 2;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
return score;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
export default async function siteSearchPlugin(fastify, options) {
|
|
132
|
+
const {authenticate, requireAdmin} = options.auth;
|
|
133
|
+
|
|
134
|
+
// -------------------------------------------------------------------------
|
|
135
|
+
// Public search endpoint
|
|
136
|
+
// -------------------------------------------------------------------------
|
|
137
|
+
|
|
138
|
+
fastify.get('/search', async (request, reply) => {
|
|
139
|
+
const settings = getPluginSettings('site-search');
|
|
140
|
+
const minLen = settings.minQueryLength ?? 2;
|
|
141
|
+
const maxResults = settings.maxResults ?? 10;
|
|
142
|
+
|
|
143
|
+
const q = (request.query.q || '').trim();
|
|
144
|
+
if (q.length < minLen) {
|
|
145
|
+
return reply.status(400).send({error: `Query must be at least ${minLen} characters`});
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
const pages = await listPages();
|
|
149
|
+
const words = q.toLowerCase().split(/\s+/).filter(Boolean);
|
|
150
|
+
|
|
151
|
+
const results = [];
|
|
152
|
+
for (const page of pages) {
|
|
153
|
+
// Filter out drafts and private pages
|
|
154
|
+
if (page.status === 'draft') continue;
|
|
155
|
+
if (page.visibility === 'private') continue;
|
|
156
|
+
|
|
157
|
+
const score = scorePage(page, q, words);
|
|
158
|
+
if (score === 0) continue;
|
|
159
|
+
|
|
160
|
+
results.push({
|
|
161
|
+
title: page.title || 'Untitled',
|
|
162
|
+
url: page.urlPath,
|
|
163
|
+
description: page.description || '',
|
|
164
|
+
tags: Array.isArray(page.tags) ? page.tags : [],
|
|
165
|
+
snippet: buildSnippet(page.content || '', q),
|
|
166
|
+
score
|
|
167
|
+
});
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
results.sort((a, b) => b.score - a.score);
|
|
171
|
+
|
|
172
|
+
return {results: results.slice(0, maxResults)};
|
|
173
|
+
});
|
|
174
|
+
|
|
175
|
+
// -------------------------------------------------------------------------
|
|
176
|
+
// Settings routes
|
|
177
|
+
// -------------------------------------------------------------------------
|
|
178
|
+
|
|
179
|
+
fastify.get('/settings', async () => {
|
|
180
|
+
return getPluginSettings('site-search');
|
|
181
|
+
});
|
|
182
|
+
|
|
183
|
+
fastify.put('/settings', {preHandler: [authenticate, requireAdmin]}, async (request) => {
|
|
184
|
+
const body = request.body || {};
|
|
185
|
+
savePluginState('site-search', {settings: body});
|
|
186
|
+
return {ok: true};
|
|
187
|
+
});
|
|
188
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "site-search",
|
|
3
|
+
"displayName": "Site Search",
|
|
4
|
+
"version": "1.0.0",
|
|
5
|
+
"description": "Full-text search for the public site. Search icon in navbar, Cmd+K shortcut, weighted results.",
|
|
6
|
+
"author": "Darryl Waterhouse",
|
|
7
|
+
"date": "2026-03-19",
|
|
8
|
+
"icon": "search",
|
|
9
|
+
"admin": {
|
|
10
|
+
"sidebar": [
|
|
11
|
+
{
|
|
12
|
+
"id": "site-search",
|
|
13
|
+
"text": "Site Search",
|
|
14
|
+
"icon": "search",
|
|
15
|
+
"url": "#/plugins/site-search",
|
|
16
|
+
"section": "#/plugins/site-search"
|
|
17
|
+
}
|
|
18
|
+
],
|
|
19
|
+
"routes": [
|
|
20
|
+
{
|
|
21
|
+
"path": "/plugins/site-search",
|
|
22
|
+
"view": "plugin-site-search",
|
|
23
|
+
"title": "Site Search - Domma CMS"
|
|
24
|
+
}
|
|
25
|
+
],
|
|
26
|
+
"views": {
|
|
27
|
+
"plugin-site-search": {
|
|
28
|
+
"entry": "site-search/admin/views/site-search.js",
|
|
29
|
+
"exportName": "siteSearchView"
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
},
|
|
33
|
+
"inject": {
|
|
34
|
+
"headLate": "public/inject-head.html",
|
|
35
|
+
"bodyEnd": "public/inject-body.html"
|
|
36
|
+
}
|
|
37
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
<!-- site-search: load settings then initialise search UI -->
|
|
2
|
+
<script>
|
|
3
|
+
(function () {
|
|
4
|
+
fetch('/api/plugins/site-search/settings')
|
|
5
|
+
.then(function (r) {
|
|
6
|
+
return r.json();
|
|
7
|
+
})
|
|
8
|
+
.then(function (cfg) {
|
|
9
|
+
window.__SITE_SEARCH__ = cfg;
|
|
10
|
+
var s = document.createElement('script');
|
|
11
|
+
s.src = '/plugins/site-search/public/search.js';
|
|
12
|
+
document.body.appendChild(s);
|
|
13
|
+
})
|
|
14
|
+
.catch(function () {
|
|
15
|
+
});
|
|
16
|
+
}());
|
|
17
|
+
</script>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<link rel="stylesheet" href="/plugins/site-search/public/search.css">
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
.site-search-trigger{display:inline-flex;align-items:center;justify-content:center;background:none;border:none;cursor:pointer;padding:6px 8px;border-radius:var(--dm-radius, 6px);color:inherit;opacity:.75;transition:opacity .15s,background .15s;font-size:var(--dm-font-size-sm, 14px)}.site-search-trigger:hover{opacity:1;background:var(--dm-surface-hover, rgba(0, 0, 0, .06))}.site-search-trigger svg,.site-search-trigger span[data-icon]{width:18px;height:18px}.site-search-shortcut-hint{display:inline-block;font-size:11px;line-height:1;padding:2px 5px;border-radius:4px;border:1px solid var(--dm-border, rgba(0, 0, 0, .15));color:var(--dm-text-muted, #888);margin-left:4px;vertical-align:middle;font-family:var(--dm-font-mono, monospace)}.site-search-overlay{position:fixed;inset:0;z-index:10000;background:#00000073;backdrop-filter:blur(3px);-webkit-backdrop-filter:blur(3px);display:flex;align-items:flex-start;justify-content:center;padding-top:10vh;animation:ss-overlay-in .15s ease}@keyframes ss-overlay-in{0%{opacity:0}to{opacity:1}}.site-search-panel{width:100%;max-width:600px;margin:0 16px;border-radius:var(--dm-radius-lg, 10px);box-shadow:0 20px 60px #00000059;background:var(--dm-bg, #fff);overflow:hidden;animation:ss-panel-in .15s ease}@keyframes ss-panel-in{0%{transform:translateY(-12px);opacity:0}to{transform:translateY(0);opacity:1}}.site-search-header{display:flex;align-items:center;padding:12px 16px;border-bottom:1px solid var(--dm-border, rgba(0, 0, 0, .1));gap:8px}.site-search-header span[data-icon],.site-search-header svg{width:18px;height:18px;flex-shrink:0;opacity:.5}.site-search-input{flex:1;border:none;outline:none;background:transparent;font-size:var(--dm-font-size-lg, 16px);color:var(--dm-text, #111);font-family:var(--dm-font-sans, sans-serif);padding:0}.site-search-input::placeholder{color:var(--dm-text-muted, #aaa)}.site-search-close-btn{display:inline-flex;align-items:center;justify-content:center;background:none;border:none;cursor:pointer;color:var(--dm-text-muted, #999);border-radius:var(--dm-radius, 6px);padding:4px 8px;font-size:12px;font-family:var(--dm-font-mono, monospace);border:1px solid var(--dm-border, rgba(0, 0, 0, .15));transition:color .15s;flex-shrink:0}.site-search-close-btn:hover{color:var(--dm-text, #111)}.site-search-results{max-height:60vh;overflow-y:auto;padding:8px 0}.site-search-result{display:block;padding:10px 16px;text-decoration:none;color:var(--dm-text, #111);border-left:3px solid transparent;transition:background .1s,border-color .1s;cursor:pointer}.site-search-result:hover,.site-search-result.active{background:var(--dm-surface-hover, rgba(0, 0, 0, .05));border-left-color:var(--dm-primary, #5b6af0)}.site-search-result-title{font-weight:600;font-size:var(--dm-font-size-sm, 14px);margin-bottom:2px;color:var(--dm-text, #111)}.site-search-result-snippet{font-size:12px;color:var(--dm-text-muted, #888);line-height:1.4;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.site-search-result-snippet mark{background:var(--dm-primary-subtle, rgba(91, 106, 240, .15));color:inherit;border-radius:2px;padding:0 1px}.site-search-loading,.site-search-empty{padding:24px 16px;text-align:center;color:var(--dm-text-muted, #888);font-size:var(--dm-font-size-sm, 14px)}.site-search-loading-dots{display:inline-flex;gap:4px}.site-search-loading-dots span{width:6px;height:6px;border-radius:50%;background:var(--dm-text-muted, #aaa);animation:ss-dot-pulse 1.2s ease-in-out infinite}.site-search-loading-dots span:nth-child(2){animation-delay:.2s}.site-search-loading-dots span:nth-child(3){animation-delay:.4s}@keyframes ss-dot-pulse{0%,80%,to{transform:scale(.6);opacity:.4}40%{transform:scale(1);opacity:1}}.site-search-results:not(:empty){border-top:1px solid var(--dm-border, rgba(0, 0, 0, .07))}.site-search-footer{padding:6px 16px;border-top:1px solid var(--dm-border, rgba(0, 0, 0, .07));display:flex;gap:12px;font-size:11px;color:var(--dm-text-muted, #aaa)}.site-search-footer kbd{display:inline-block;padding:1px 4px;border-radius:3px;border:1px solid var(--dm-border, rgba(0, 0, 0, .2));font-family:var(--dm-font-mono, monospace);font-size:10px}@media(max-width:640px){.site-search-overlay{padding-top:5vh;align-items:flex-start}.site-search-panel{margin:0 8px;border-radius:var(--dm-radius, 6px)}.site-search-results{max-height:70vh}.site-search-shortcut-hint{display:none}}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
(function(){"use strict";var f=window.__SITE_SEARCH__||{},S=f.placeholder||"Search pages...",b=f.keyboardShortcut!==!1,N=f.debounceMs||300,d=null,o=null,c=null,m=null,u=!1;function h(){var e=document.querySelector("#site-navbar, .navbar");if(e){var t=e.querySelector(".navbar-actions");if(!t){var a=e.querySelector(".navbar-container")||e;t=document.createElement("div"),t.className="navbar-actions",a.appendChild(t)}if(!t.querySelector(".site-search-trigger")){var s=/Mac|iPhone|iPad|iPod/.test(navigator.platform||navigator.userAgent),r=s?"\u2318K":"Ctrl+K",n=document.createElement("button");n.className="navbar-action-link site-search-trigger",n.setAttribute("aria-label","Search"),n.setAttribute("type","button");var i=document.createElement("span");if(i.setAttribute("data-icon","search"),n.appendChild(i),b){var l=document.createElement("span");l.className="site-search-shortcut-hint",l.textContent=r,n.appendChild(l)}t.insertBefore(n,t.firstChild),n.addEventListener("click",E),window.Domma&&Domma.icons&&Domma.icons.scan&&Domma.icons.scan(n)}}}function g(){if(document.querySelector("#site-navbar .navbar-actions, .navbar .navbar-actions")){h();return}var e=new MutationObserver(function(){var t=document.querySelector("#site-navbar, .navbar");t&&(e.disconnect(),h())});e.observe(document.body,{childList:!0,subtree:!0}),setTimeout(function(){e.disconnect(),h()},5e3)}function w(){var e=document.createElement("div");e.className="site-search-overlay",e.setAttribute("role","dialog"),e.setAttribute("aria-modal","true"),e.setAttribute("aria-label","Site search");var t=document.createElement("div");t.className="site-search-panel",t.setAttribute("role","search");var a=document.createElement("div");a.className="site-search-header";var s=document.createElement("span");s.setAttribute("data-icon","search"),a.appendChild(s),o=document.createElement("input"),o.className="site-search-input",o.type="search",o.setAttribute("autocomplete","off"),o.setAttribute("autocorrect","off"),o.setAttribute("spellcheck","false"),o.setAttribute("aria-label","Search"),o.placeholder=S,a.appendChild(o);var r=document.createElement("button");r.className="site-search-close-btn",r.setAttribute("type","button"),r.setAttribute("aria-label","Close search"),r.textContent="Esc",a.appendChild(r),t.appendChild(a),c=document.createElement("div"),c.className="site-search-results",c.setAttribute("role","listbox"),c.setAttribute("aria-live","polite"),t.appendChild(c);var n=document.createElement("div");return n.className="site-search-footer",n.innerHTML="<span><kbd>\u2191</kbd><kbd>\u2193</kbd> navigate</span><span><kbd>\u21B5</kbd> open</span><span><kbd>Esc</kbd> close</span>",t.appendChild(n),e.appendChild(t),e.addEventListener("click",function(i){i.target===e&&v()}),r.addEventListener("click",v),o.addEventListener("input",function(){clearTimeout(m);var i=o.value.trim();if(!i){C();return}m=setTimeout(function(){k(i)},N)}),o.addEventListener("keydown",D),window.Domma&&Domma.icons&&Domma.icons.scan&&Domma.icons.scan(a),e}function E(){u||(u=!0,d=w(),document.body.appendChild(d),document.body.style.overflow="hidden",setTimeout(function(){o&&o.focus()},30))}function v(){u&&(u=!1,clearTimeout(m),d&&d.parentNode&&d.parentNode.removeChild(d),d=null,o=null,c=null,document.body.style.overflow="")}function k(e){c&&(L(),fetch("/api/plugins/site-search/search?q="+encodeURIComponent(e)).then(function(t){return t.json()}).then(function(t){T(t.results||[],e)}).catch(function(){C();var t=document.createElement("div");t.className="site-search-empty",t.textContent="Search unavailable. Please try again.",c.appendChild(t)}))}function L(){c&&(c.innerHTML='<div class="site-search-loading"><div class="site-search-loading-dots"><span></span><span></span><span></span></div></div>')}function C(){c&&(c.innerHTML="")}function T(e,t){if(c){if(c.innerHTML="",!e.length){var a=document.createElement("div");a.className="site-search-empty",a.textContent='No results found for "'+t+'"',c.appendChild(a);return}for(var s=document.createDocumentFragment(),r=0;r<e.length;r++){var n=e[r],i=document.createElement("a");i.className="site-search-result",i.href=n.url||"/",i.setAttribute("role","option"),i.setAttribute("tabindex","-1"),i.setAttribute("data-index",String(r));var l=document.createElement("div");if(l.className="site-search-result-title",y(l,n.title||"Untitled",t),i.appendChild(l),n.snippet){var p=document.createElement("div");p.className="site-search-result-snippet",y(p,n.snippet,t),i.appendChild(p)}i.addEventListener("click",v),s.appendChild(i)}c.appendChild(s)}}function y(e,t,a){if(!a){e.textContent=t;return}var s=a.trim().split(/\s+/).filter(Boolean);if(!s.length){e.textContent=t;return}var r;try{r=new RegExp("("+s.map(function(p){return p.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}).join("|")+")","gi")}catch{e.textContent=t;return}for(var n=t.split(r),i=0;i<n.length;i++){if(r.test(n[i])){var l=document.createElement("mark");l.textContent=n[i],e.appendChild(l)}else e.appendChild(document.createTextNode(n[i]));r.lastIndex=0}}function D(e){if(e.key==="Escape"){e.preventDefault(),v();return}if(c){var t=c.querySelectorAll(".site-search-result");if(t.length){for(var a=c.querySelector(".site-search-result.active"),s=-1,r=0;r<t.length;r++)if(t[r]===a){s=r;break}if(e.key==="ArrowDown")e.preventDefault(),A(t,s<t.length-1?s+1:0);else if(e.key==="ArrowUp")e.preventDefault(),A(t,s>0?s-1:t.length-1);else if(e.key==="Enter"&&a){e.preventDefault();var n=a.getAttribute("href");v(),window.location.href=n}}}}function A(e,t){for(var a=0;a<e.length;a++)e[a].classList.toggle("active",a===t);e[t]&&e[t].scrollIntoView({block:"nearest"})}b&&document.addEventListener("keydown",function(e){if((e.metaKey||e.ctrlKey)&&e.key==="k"){var t=document.activeElement&&document.activeElement.tagName;if((t==="INPUT"||t==="TEXTAREA"||t==="SELECT")&&!u)return;e.preventDefault(),u?v():E()}}),document.readyState==="loading"?document.addEventListener("DOMContentLoaded",g):g()})();
|
package/public/css/site.css
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
body,button,input,select,textarea{font-family:Roboto,sans-serif}.site-main{min-height:calc(100vh - 60px);padding-top:2rem;padding-bottom:4rem}.site-main.with-sidebar{display:grid;grid-template-columns:260px 1fr;gap:0}.site-sidebar{min-height:100%;border-right:1px solid var(--border-color, rgba(255,255,255,.08))}.site-content{overflow:hidden}.table-responsive{overflow-x:auto;-webkit-overflow-scrolling:touch}.container{max-width:860px;margin:0 auto;padding:0 1.5rem}.page-title{font-size:2rem;font-weight:700;margin-bottom:1.5rem;line-height:1.2}.page-body{line-height:1.7;font-size:1rem}.page-body h1,.page-body h2,.page-body h3,.page-body h4{margin-top:2rem;margin-bottom:.75rem;font-weight:600}.page-body h2{font-size:1.5rem}.page-body h3{font-size:1.25rem}.page-body p{margin-bottom:1rem}.page-body ul,.page-body ol{margin-bottom:1rem;padding-left:1.5rem}.page-body a{color:var(--primary, #5b8cff)}.page-body a:hover{text-decoration:underline}.page-body code{font-family:Fira Code,Courier New,monospace;font-size:.9em;background:#ffffff0f;padding:.15em .35em;border-radius:3px}.page-body pre{background:#0000004d;border:1px solid rgba(255,255,255,.08);border-radius:6px;padding:1rem;overflow-x:auto;margin-bottom:1rem}.page-body pre code{background:none;padding:0}.page-body img{max-width:100%;border-radius:6px}.page-body blockquote{border-left:3px solid var(--primary, #5b8cff);margin:1.5rem 0;padding:.75rem 1rem;background:#5b8cff0f;border-radius:0 6px 6px 0}h3.accordion-header{margin:0}.accordion-button{all:unset;display:flex;align-items:center;justify-content:space-between;width:100%;cursor:pointer;font:inherit}.page-body .card-header h2{margin:0;font-size:1rem;font-weight:600;line-height:1.4}.card[data-collapsible] .card-header{cursor:pointer;user-select:none;display:flex;align-items:center;justify-content:space-between}.card[data-collapsible] .card-header:after{content:"\25be";font-size:1.1em;line-height:1;display:inline-block;transition:transform .25s ease;flex-shrink:0}.card[data-collapsible].is-collapsed .card-header:after{transform:rotate(-90deg)}.card[data-collapsible] .card-body{overflow:hidden;max-height:4000px;opacity:1;transition:max-height .3s ease,opacity .25s ease}.card[data-collapsible].is-collapsed .card-body{max-height:0;opacity:0}.navbar-link span[data-icon],.navbar-link svg,.navbar-dropdown-toggle span[data-icon],.navbar-dropdown-toggle svg,.navbar-dropdown-item span[data-icon],.navbar-dropdown-item svg{width:13px!important;height:13px!important;margin-right:10px!important}.navbar-dropdown-toggle{font-size:var(--dm-font-size-base)}@media(min-width:993px){.navbar-dropdown-toggle{font-size:var(--dm-font-size-sm)}}@media(min-width:1201px){.navbar-dropdown-toggle{font-size:var(--dm-font-size-xs)}}.dm-reduced-motion *,.dm-reduced-motion *:before,.dm-reduced-motion *:after{animation-duration:.001ms!important;animation-iteration-count:1!important;transition-duration:.001ms!important;scroll-behavior:auto!important}.page-footer{border-top:1px solid var(--border-color, rgba(255,255,255,.08));padding:1.5rem 0}.footer-inner{display:flex;align-items:center;justify-content:space-between;flex-wrap:wrap;gap:1rem}.footer-inner p{margin:0;color:var(--text-muted, #888);font-size:.875rem}.footer-links{display:flex;gap:1.25rem}.footer-links a{color:var(--text-muted, #888);font-size:.875rem;text-decoration:none}.footer-links a:hover{color:var(--text, #eee)}.footer-social{display:flex;gap:.5rem;align-items:center}.footer-social-link{display:inline-flex;align-items:center;justify-content:center;width:1.75rem;height:1.75rem;color:var(--text-muted, #888);transition:color .15s}.footer-social-link:hover{color:var(--text, #eee)}.footer-social-link svg{width:1rem;height:1rem}.footer-motion-switch{font-size:.8rem;color:var(--text-muted, #888);white-space:nowrap}.footer-motion-switch .form-switch-label{color:var(--text-muted, #888)}.footer-motion-switch .form-switch-input{width:2rem;height:1.125rem}.footer-motion-switch .form-switch-input:after{width:.875rem;height:.875rem}.footer-motion-switch .form-switch-input:checked:after{transform:translate(.875rem)}.dm-slideover-header{display:flex;align-items:center;justify-content:space-between;padding:.875rem 1.25rem;border-bottom:1px solid var(--border-color, rgba(255, 255, 255, .08));flex-shrink:0}.dm-slideover-title{margin:0;font-size:1rem;font-weight:600;line-height:1.4}.dm-slideover-body{padding:1.25rem;overflow-y:auto;flex:1}@media(max-width:768px){.site-main.with-sidebar{grid-template-columns:1fr}.site-sidebar{display:none}}.dm-spacer{display:block;width:100%}.hero-breakout{width:calc(100vw - 2rem);margin-left:calc(50% - 50vw + 1rem);margin-right:calc(50% - 50vw + 1rem)}.site-main:has(.page-body>.hero-breakout:first-child){padding-top:0}body[data-layout=landing]>.site-main{padding-top:0}body[data-layout=landing]>.site-main .container{max-width:none;padding:0}body[data-layout=landing] .page-body{padding-left:1.5rem;padding-right:1.5rem}body[data-layout=landing] .page-body>p,body[data-layout=landing] .page-body>h1,body[data-layout=landing] .page-body>h2,body[data-layout=landing] .page-body>h3,body[data-layout=landing] .page-body>ul,body[data-layout=landing] .page-body>ol,body[data-layout=landing] .page-body>blockquote{max-width:860px;margin-left:auto;margin-right:auto}body[data-layout=landing] .page-body .hero-breakout{width:calc(100% + 3rem);margin-left:-1.5rem;margin-right:-1.5rem}body[data-layout=landing] .page-body .grid-breakout{width:calc(100% + 3rem);margin-left:-1.5rem;margin-right:-1.5rem;padding-left:1.5rem;padding-right:1.5rem}.page-body .card{transition:transform .2s ease,box-shadow .2s ease}.page-body .card:hover{transform:translateY(-3px);box-shadow:0 8px 24px #00000059}.page-body .card-header-icon-inline{display:flex;align-items:center;gap:.6rem}.page-body .card-header-icon-inline [data-icon]{flex-shrink:0;line-height:0}.page-body .card-header-icon-inline [data-icon] svg,.page-body .card-header-icon-inline>svg{display:block;width:1.25rem;height:1.25rem}.page-body .card-header-icon-stacked{display:flex;flex-direction:column;align-items:center;text-align:center;gap:.35rem;padding-top:.25rem}.page-body .card-header-icon-stacked [data-icon],.page-body .card-header-icon-stacked svg{width:2rem;height:2rem}.hero.hero-dark{background:linear-gradient(135deg,#1f2937,#111827);color:#e2e8f0}.hero .hero-content{position:relative;z-index:2}.hero.hero-left .hero-content{text-align:left;align-items:flex-start;max-width:62%}@media(max-width:768px){.hero.hero-left .hero-content{max-width:100%}}.hero .hero-cta{display:flex;gap:.85rem;flex-wrap:wrap;margin-top:1.75rem}.hero .hero-cta a{display:inline-flex;align-items:center;gap:.4rem;padding:.55rem 1.35rem;border-radius:6px;font-size:.95rem;font-weight:500;text-decoration:none;transition:background .2s ease,border-color .2s ease,transform .15s ease,box-shadow .2s ease}.hero .hero-cta a:first-child{background:#ffffffeb;color:#111;border:1px solid transparent}.hero .hero-cta a:first-child:hover{background:#fff;box-shadow:0 4px 16px #00000040;transform:translateY(-2px)}.hero .hero-cta a:last-child{background:transparent;color:#fff;border:1px solid rgba(255,255,255,.4)}.hero .hero-cta a:last-child:hover{border-color:#ffffffbf;background:#ffffff14;transform:translateY(-2px)}.hero .hero-label{display:inline-block;margin-bottom:.9rem;padding:.2rem .8rem;border-radius:999px;font-size:.72rem;font-weight:600;letter-spacing:.07em;text-transform:uppercase;color:#ffffffb3;border:1px solid rgba(255,255,255,.22)}.grid-breakout{width:calc(100vw - 2rem);margin-left:calc(50% - 50vw + 1rem);margin-right:calc(50% - 50vw + 1rem)}.dm-breadcrumbs{position:fixed;z-index:200;display:inline-flex;align-items:center;gap:.2rem;padding:.3rem .8rem;border-radius:999px;backdrop-filter:blur(14px);-webkit-backdrop-filter:blur(14px);background:#00000047;border:1px solid rgba(255,255,255,.11);box-shadow:0 2px 10px #00000038;font-size:.72rem;font-weight:500;letter-spacing:.01em;line-height:1.4;max-width:calc(100vw - 2rem);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.dm-breadcrumbs .dm-breadcrumbs-item{color:#ffffffa6}.dm-breadcrumbs .dm-breadcrumbs-link{display:inline-flex;align-items:center;gap:.25rem;color:#ffffff8c;text-decoration:none;transition:color .15s}.dm-breadcrumbs .dm-breadcrumbs-home-icon{flex-shrink:0;vertical-align:middle}.dm-breadcrumbs .dm-breadcrumbs-link:hover{color:#fffffff2}.dm-breadcrumbs .dm-breadcrumbs-current{color:#ffffffeb;font-weight:600}.dm-breadcrumbs .dm-breadcrumbs-separator{color:#ffffff47;font-size:.8em;line-height:1;margin:0 .05rem}[data-mode=light] .dm-breadcrumbs{background:#ffffff8c;border-color:#00000012;box-shadow:0 2px 10px #00000014}[data-mode=light] .dm-breadcrumbs .dm-breadcrumbs-item,[data-mode=light] .dm-breadcrumbs .dm-breadcrumbs-link{color:#0000008c}[data-mode=light] .dm-breadcrumbs .dm-breadcrumbs-link:hover{color:#000000e6}[data-mode=light] .dm-breadcrumbs .dm-breadcrumbs-current{color:#000000d9}[data-mode=light] .dm-breadcrumbs .dm-breadcrumbs-separator{color:#00000040}.dm-collection-display{margin:1.5rem 0}.dm-collection-list{display:flex;flex-direction:column;gap:0}.dm-collection-list-item{padding:1rem 0;border-bottom:1px solid var(--border-color, rgba(255, 255, 255, .08))}.dm-collection-list-item:last-child{border-bottom:none}.dm-collection-list-item strong{display:block;font-size:1rem;margin-bottom:.25rem}.dm-collection-list-item p{margin:0;color:var(--text-muted, #888);font-size:.9rem}.dm-collection-empty p{color:var(--text-muted, #888);font-style:italic}.hero-gradient-purple{background:linear-gradient(135deg,#ede9fe,#ddd6fe);color:#1e1b4b}.hero-gradient-blue{background:linear-gradient(135deg,#dbeafe,#bfdbfe);color:#1e3a5f}.hero-gradient-green{background:linear-gradient(135deg,#d1fae5,#a7f3d0);color:#064e3b}.hero-gradient-sunset{background:linear-gradient(135deg,#fef3c7,#fde68a);color:#78350f}.hero-gradient-ocean{background:linear-gradient(135deg,#e0f2fe,#bae6fd);color:#0c4a6e}.hero-gradient-rose{background:linear-gradient(135deg,#fce7f3,#fbcfe8);color:#831843}.hero-gradient-forest{background:linear-gradient(135deg,#dcfce7,#bbf7d0);color:#14532d}.hero-gradient-night{background:linear-gradient(135deg,#334155,#1e293b);color:#e2e8f0}.hero-gradient-ocean-light{background:linear-gradient(135deg,#e0f2fe,#caf0f8);color:#1e293b}.hero-gradient-ocean-dark{background:linear-gradient(135deg,#0c4a6e,#164e63);color:#e2e8f0}.hero-gradient-forest-light{background:linear-gradient(135deg,#d1fae5,#c6f6dc);color:#1e293b}.hero-gradient-forest-dark{background:linear-gradient(135deg,#1a4731,#166534);color:#e2e8f0}.hero-gradient-sunset-light{background:linear-gradient(135deg,#fde8d8,#fddcc9);color:#1e293b}.hero-gradient-sunset-dark{background:linear-gradient(135deg,#6b3727,#7c4036);color:#f5ede8}.hero-gradient-royal-light{background:linear-gradient(135deg,#e8f0fd,#dce8fc);color:#1e293b}.hero-gradient-royal-dark{background:linear-gradient(135deg,#1e3465,#263d7a);color:#e2e8f0}.hero-gradient-lemon-light{background:linear-gradient(135deg,#fefce8,#fef9c3);color:#1e293b}.hero-gradient-lemon-dark{background:linear-gradient(135deg,#5c4d1a,#6b5920);color:#fefce8}.hero-gradient-silver-light{background:linear-gradient(135deg,#f1f5f9,#e2e8f0);color:#1e293b}.hero-gradient-silver-dark{background:linear-gradient(135deg,#2d3748,#374151);color:#e2e8f0}.hero-gradient-charcoal-light{background:linear-gradient(135deg,#eceff1,#e1e7eb);color:#1e293b}.hero-gradient-charcoal-dark{background:linear-gradient(135deg,#2c3843,#374451);color:#e2e8f0}.hero-gradient-christmas-light{background:linear-gradient(135deg,#fde8ea,#fdd5d8);color:#1e293b}.hero-gradient-christmas-dark{background:linear-gradient(135deg,#5c0f1d,#7a1525);color:#fde8ea}.hero-gradient-unicorn-light{background:linear-gradient(135deg,#f5e8fd,#edd6fb);color:#1e293b}.hero-gradient-unicorn-dark{background:linear-gradient(135deg,#3d1a5a,#4a2068);color:#f5e8fd}.hero-gradient-dreamy-light{background:linear-gradient(135deg,#f5ede8,#eeddd4);color:#1e293b}.hero-gradient-dreamy-dark{background:linear-gradient(135deg,#3d2820,#503328);color:#f5ede8}.hero-gradient-grayve-light{background:linear-gradient(135deg,#e0f7f9,#cbf2f5);color:#1e293b}.hero-gradient-grayve-dark{background:linear-gradient(135deg,#00363d,#00444d);color:#e0f7f9}.hero-gradient-mint-light{background:linear-gradient(135deg,#d8f5ea,#c5efdd);color:#1e293b}.hero-gradient-mint-dark{background:linear-gradient(135deg,#134d33,#195f3f);color:#d8f5ea}.hero-gradient-wedding-light{background:linear-gradient(135deg,#faf3e0,#f5e9c7);color:#1e293b}.hero-gradient-wedding-dark{background:linear-gradient(135deg,#5c4418,#6f5320);color:#faf3e0}.tabs-centered{text-align:center}.tabs-centered .tab-list{display:inline-flex}.tabs-centered .tab-content{text-align:left}
|
|
1
|
+
body,button,input,select,textarea{font-family:Roboto,sans-serif}.site-main{min-height:calc(100vh - 60px);padding-top:2rem;padding-bottom:4rem}.site-main.with-sidebar{display:grid;grid-template-columns:260px 1fr;gap:0}.site-sidebar{min-height:100%;border-right:1px solid var(--border-color, rgba(255,255,255,.08))}.site-content{overflow:hidden}.table-responsive{overflow-x:auto;-webkit-overflow-scrolling:touch}.container{max-width:860px;margin:0 auto;padding:0 1.5rem}.page-title{font-size:clamp(1.5rem,4vw,2rem);font-weight:700;margin-bottom:1.5rem;line-height:1.2}.page-body{line-height:1.7;font-size:1rem}.page-body h1,.page-body h2,.page-body h3,.page-body h4{margin-top:2rem;margin-bottom:.75rem;font-weight:600}.page-body h2{font-size:clamp(1.2rem,3vw,1.5rem)}.page-body h3{font-size:clamp(1.1rem,2.5vw,1.25rem)}.page-body p{margin-bottom:1rem}.page-body ul,.page-body ol{margin-bottom:1rem;padding-left:1.5rem}.page-body a{color:var(--primary, #5b8cff)}.page-body a:hover{text-decoration:underline}.page-body code{font-family:Fira Code,Courier New,monospace;font-size:.9em;background:#ffffff0f;padding:.15em .35em;border-radius:3px}.page-body pre{background:#0000004d;border:1px solid rgba(255,255,255,.08);border-radius:6px;padding:1rem;overflow-x:auto;margin-bottom:1rem}.page-body pre code{background:none;padding:0}.page-body img{max-width:100%;border-radius:6px}.page-body blockquote{border-left:3px solid var(--primary, #5b8cff);margin:1.5rem 0;padding:.75rem 1rem;background:#5b8cff0f;border-radius:0 6px 6px 0}h3.accordion-header{margin:0}.accordion-button{all:unset;display:flex;align-items:center;justify-content:space-between;width:100%;cursor:pointer;font:inherit}.page-body .card-header h2{margin:0;font-size:1rem;font-weight:600;line-height:1.4}.card[data-collapsible] .card-header{cursor:pointer;user-select:none;display:flex;align-items:center;justify-content:space-between}.card[data-collapsible] .card-header:after{content:"\25be";font-size:1.1em;line-height:1;display:inline-block;transition:transform .25s ease;flex-shrink:0}.card[data-collapsible].is-collapsed .card-header:after{transform:rotate(-90deg)}.card[data-collapsible] .card-body{overflow:hidden;max-height:4000px;opacity:1;transition:max-height .3s ease,opacity .25s ease}.card[data-collapsible].is-collapsed .card-body{max-height:0;opacity:0}.navbar-link span[data-icon],.navbar-link svg,.navbar-dropdown-toggle span[data-icon],.navbar-dropdown-toggle svg,.navbar-dropdown-item span[data-icon],.navbar-dropdown-item svg{width:13px!important;height:13px!important;margin-right:10px!important}.navbar-dropdown-toggle{font-size:var(--dm-font-size-base)}@media(min-width:993px){.navbar-dropdown-toggle{font-size:var(--dm-font-size-sm)}}@media(min-width:1201px){.navbar-dropdown-toggle{font-size:var(--dm-font-size-xs)}}.dm-reduced-motion *,.dm-reduced-motion *:before,.dm-reduced-motion *:after{animation-duration:.001ms!important;animation-iteration-count:1!important;transition-duration:.001ms!important;scroll-behavior:auto!important}.page-footer{border-top:1px solid var(--border-color, rgba(255,255,255,.08));padding:1.5rem 0}.footer-inner{display:flex;align-items:center;justify-content:space-between;flex-wrap:wrap;gap:1rem}.footer-inner p{margin:0;color:var(--text-muted, #888);font-size:.875rem}.footer-links{display:flex;gap:1.25rem}.footer-links a{color:var(--text-muted, #888);font-size:.875rem;text-decoration:none}.footer-links a:hover{color:var(--text, #eee)}.footer-social{display:flex;gap:.5rem;align-items:center}.footer-social-link{display:inline-flex;align-items:center;justify-content:center;width:1.75rem;height:1.75rem;color:var(--text-muted, #888);transition:color .15s}.footer-social-link:hover{color:var(--text, #eee)}.footer-social-link svg{width:1rem;height:1rem}.footer-motion-switch{font-size:.8rem;color:var(--text-muted, #888);white-space:nowrap}.footer-motion-switch .form-switch-label{color:var(--text-muted, #888)}.footer-motion-switch .form-switch-input{width:2rem;height:1.125rem}.footer-motion-switch .form-switch-input:after{width:.875rem;height:.875rem}.footer-motion-switch .form-switch-input:checked:after{transform:translate(.875rem)}.dm-slideover-header{display:flex;align-items:center;justify-content:space-between;padding:.875rem 1.25rem;border-bottom:1px solid var(--border-color, rgba(255, 255, 255, .08));flex-shrink:0}.dm-slideover-title{margin:0;font-size:1rem;font-weight:600;line-height:1.4}.dm-slideover-body{padding:1.25rem;overflow-y:auto;flex:1}@media(max-width:768px){.site-main.with-sidebar{grid-template-columns:1fr}.site-sidebar{display:none}}.dm-spacer{display:block;width:100%}.hero-breakout{width:calc(100vw - 2rem);margin-left:calc(50% - 50vw + 1rem);margin-right:calc(50% - 50vw + 1rem)}.site-main:has(.page-body>.hero-breakout:first-child){padding-top:0}body[data-layout=landing]>.site-main{padding-top:0}body[data-layout=landing]>.site-main .container{max-width:none;padding:0}body[data-layout=landing] .page-body{padding-left:1.5rem;padding-right:1.5rem}body[data-layout=landing] .page-body>p,body[data-layout=landing] .page-body>h1,body[data-layout=landing] .page-body>h2,body[data-layout=landing] .page-body>h3,body[data-layout=landing] .page-body>ul,body[data-layout=landing] .page-body>ol,body[data-layout=landing] .page-body>blockquote{max-width:860px;margin-left:auto;margin-right:auto}body[data-layout=landing] .page-body .hero-breakout{width:calc(100% + 3rem);margin-left:-1.5rem;margin-right:-1.5rem}body[data-layout=landing] .page-body .grid-breakout{width:calc(100% + 3rem);margin-left:-1.5rem;margin-right:-1.5rem;padding-left:1.5rem;padding-right:1.5rem}.page-body .card{transition:transform .2s ease,box-shadow .2s ease}.page-body .card:hover{transform:translateY(-3px);box-shadow:0 8px 24px #00000059}.page-body .card-header-icon-inline{display:flex;align-items:center;gap:.6rem}.page-body .card-header-icon-inline [data-icon]{flex-shrink:0;line-height:0}.page-body .card-header-icon-inline [data-icon] svg,.page-body .card-header-icon-inline>svg{display:block;width:1.25rem;height:1.25rem}.page-body .card-header-icon-stacked{display:flex;flex-direction:column;align-items:center;text-align:center;gap:.35rem;padding-top:.25rem}.page-body .card-header-icon-stacked [data-icon],.page-body .card-header-icon-stacked svg{width:2rem;height:2rem}.hero.hero-dark{background:linear-gradient(135deg,#1f2937,#111827);color:#e2e8f0}.hero .hero-content{position:relative;z-index:2}.hero.hero-left .hero-content{text-align:left;align-items:flex-start;max-width:62%}@media(max-width:768px){.hero.hero-left .hero-content{max-width:100%}}.hero .hero-cta{display:flex;gap:.85rem;flex-wrap:wrap;margin-top:1.75rem}.hero .hero-cta a{display:inline-flex;align-items:center;gap:.4rem;padding:.55rem 1.35rem;border-radius:6px;font-size:.95rem;font-weight:500;text-decoration:none;transition:background .2s ease,border-color .2s ease,transform .15s ease,box-shadow .2s ease}.hero .hero-cta a:first-child{background:#ffffffeb;color:#111;border:1px solid transparent}.hero .hero-cta a:first-child:hover{background:#fff;box-shadow:0 4px 16px #00000040;transform:translateY(-2px)}.hero .hero-cta a:last-child{background:transparent;color:#fff;border:1px solid rgba(255,255,255,.4)}.hero .hero-cta a:last-child:hover{border-color:#ffffffbf;background:#ffffff14;transform:translateY(-2px)}.hero .hero-label{display:inline-block;margin-bottom:.9rem;padding:.2rem .8rem;border-radius:999px;font-size:.72rem;font-weight:600;letter-spacing:.07em;text-transform:uppercase;color:#ffffffb3;border:1px solid rgba(255,255,255,.22)}.grid-breakout{width:calc(100vw - 2rem);margin-left:calc(50% - 50vw + 1rem);margin-right:calc(50% - 50vw + 1rem)}.dm-breadcrumbs{position:fixed;z-index:200;display:inline-flex;align-items:center;gap:.2rem;padding:.3rem .8rem;border-radius:999px;backdrop-filter:blur(14px);-webkit-backdrop-filter:blur(14px);background:#00000047;border:1px solid rgba(255,255,255,.11);box-shadow:0 2px 10px #00000038;font-size:.72rem;font-weight:500;letter-spacing:.01em;line-height:1.4;max-width:calc(100vw - 2rem);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.dm-breadcrumbs .dm-breadcrumbs-item{color:#ffffffa6}.dm-breadcrumbs .dm-breadcrumbs-link{display:inline-flex;align-items:center;gap:.25rem;color:#ffffff8c;text-decoration:none;transition:color .15s}.dm-breadcrumbs .dm-breadcrumbs-home-icon{flex-shrink:0;vertical-align:middle}.dm-breadcrumbs .dm-breadcrumbs-link:hover{color:#fffffff2}.dm-breadcrumbs .dm-breadcrumbs-current{color:#ffffffeb;font-weight:600}.dm-breadcrumbs .dm-breadcrumbs-separator{color:#ffffff47;font-size:.8em;line-height:1;margin:0 .05rem}[data-mode=light] .dm-breadcrumbs{background:#ffffff8c;border-color:#00000012;box-shadow:0 2px 10px #00000014}[data-mode=light] .dm-breadcrumbs .dm-breadcrumbs-item,[data-mode=light] .dm-breadcrumbs .dm-breadcrumbs-link{color:#0000008c}[data-mode=light] .dm-breadcrumbs .dm-breadcrumbs-link:hover{color:#000000e6}[data-mode=light] .dm-breadcrumbs .dm-breadcrumbs-current{color:#000000d9}[data-mode=light] .dm-breadcrumbs .dm-breadcrumbs-separator{color:#00000040}.dm-collection-display{margin:1.5rem 0}.dm-collection-list{display:flex;flex-direction:column;gap:0}.dm-collection-list-item{padding:1rem 0;border-bottom:1px solid var(--border-color, rgba(255, 255, 255, .08))}.dm-collection-list-item:last-child{border-bottom:none}.dm-collection-list-item strong{display:block;font-size:1rem;margin-bottom:.25rem}.dm-collection-list-item p{margin:0;color:var(--text-muted, #888);font-size:.9rem}.dm-collection-empty p{color:var(--text-muted, #888);font-style:italic}.hero-gradient-purple{background:linear-gradient(135deg,#ede9fe,#ddd6fe);color:#1e1b4b}.hero-gradient-blue{background:linear-gradient(135deg,#dbeafe,#bfdbfe);color:#1e3a5f}.hero-gradient-green{background:linear-gradient(135deg,#d1fae5,#a7f3d0);color:#064e3b}.hero-gradient-sunset{background:linear-gradient(135deg,#fef3c7,#fde68a);color:#78350f}.hero-gradient-ocean{background:linear-gradient(135deg,#e0f2fe,#bae6fd);color:#0c4a6e}.hero-gradient-rose{background:linear-gradient(135deg,#fce7f3,#fbcfe8);color:#831843}.hero-gradient-forest{background:linear-gradient(135deg,#dcfce7,#bbf7d0);color:#14532d}.hero-gradient-night{background:linear-gradient(135deg,#334155,#1e293b);color:#e2e8f0}.hero-gradient-ocean-light{background:linear-gradient(135deg,#e0f2fe,#caf0f8);color:#1e293b}.hero-gradient-ocean-dark{background:linear-gradient(135deg,#0c4a6e,#164e63);color:#e2e8f0}.hero-gradient-forest-light{background:linear-gradient(135deg,#d1fae5,#c6f6dc);color:#1e293b}.hero-gradient-forest-dark{background:linear-gradient(135deg,#1a4731,#166534);color:#e2e8f0}.hero-gradient-sunset-light{background:linear-gradient(135deg,#fde8d8,#fddcc9);color:#1e293b}.hero-gradient-sunset-dark{background:linear-gradient(135deg,#6b3727,#7c4036);color:#f5ede8}.hero-gradient-royal-light{background:linear-gradient(135deg,#e8f0fd,#dce8fc);color:#1e293b}.hero-gradient-royal-dark{background:linear-gradient(135deg,#1e3465,#263d7a);color:#e2e8f0}.hero-gradient-lemon-light{background:linear-gradient(135deg,#fefce8,#fef9c3);color:#1e293b}.hero-gradient-lemon-dark{background:linear-gradient(135deg,#5c4d1a,#6b5920);color:#fefce8}.hero-gradient-silver-light{background:linear-gradient(135deg,#f1f5f9,#e2e8f0);color:#1e293b}.hero-gradient-silver-dark{background:linear-gradient(135deg,#2d3748,#374151);color:#e2e8f0}.hero-gradient-charcoal-light{background:linear-gradient(135deg,#eceff1,#e1e7eb);color:#1e293b}.hero-gradient-charcoal-dark{background:linear-gradient(135deg,#2c3843,#374451);color:#e2e8f0}.hero-gradient-christmas-light{background:linear-gradient(135deg,#fde8ea,#fdd5d8);color:#1e293b}.hero-gradient-christmas-dark{background:linear-gradient(135deg,#5c0f1d,#7a1525);color:#fde8ea}.hero-gradient-unicorn-light{background:linear-gradient(135deg,#f5e8fd,#edd6fb);color:#1e293b}.hero-gradient-unicorn-dark{background:linear-gradient(135deg,#3d1a5a,#4a2068);color:#f5e8fd}.hero-gradient-dreamy-light{background:linear-gradient(135deg,#f5ede8,#eeddd4);color:#1e293b}.hero-gradient-dreamy-dark{background:linear-gradient(135deg,#3d2820,#503328);color:#f5ede8}.hero-gradient-grayve-light{background:linear-gradient(135deg,#e0f7f9,#cbf2f5);color:#1e293b}.hero-gradient-grayve-dark{background:linear-gradient(135deg,#00363d,#00444d);color:#e0f7f9}.hero-gradient-mint-light{background:linear-gradient(135deg,#d8f5ea,#c5efdd);color:#1e293b}.hero-gradient-mint-dark{background:linear-gradient(135deg,#134d33,#195f3f);color:#d8f5ea}.hero-gradient-wedding-light{background:linear-gradient(135deg,#faf3e0,#f5e9c7);color:#1e293b}.hero-gradient-wedding-dark{background:linear-gradient(135deg,#5c4418,#6f5320);color:#faf3e0}.tabs-centered{text-align:center}.tabs-centered .tab-list{display:inline-flex}.tabs-centered .tab-content{text-align:left}.site-main{overflow-x:hidden}@media(max-width:768px){.hero .hero-cta a,.dm-so-trigger,.dm-cta-trigger{min-height:44px;padding:.6rem 1.25rem}}
|
|
@@ -90,7 +90,7 @@ function renderCollectionBlocks(entries, blockTemplate, emptyMsg, ctaOpts, cols)
|
|
|
90
90
|
|
|
91
91
|
const validCols = ['2', '3', '4', '5', '6'].includes(String(cols)) ? cols : '';
|
|
92
92
|
const wrapperClass = validCols
|
|
93
|
-
? `dm-collection-display dm-collection-blocks grid
|
|
93
|
+
? `dm-collection-display dm-collection-blocks grid ${responsiveGridCols(validCols).join(' ')} gap-4`
|
|
94
94
|
: 'dm-collection-display dm-collection-blocks';
|
|
95
95
|
|
|
96
96
|
return `<div class="${wrapperClass}">\n${items.join('\n')}\n</div>`;
|
|
@@ -145,7 +145,7 @@ function renderCollectionCards(entries, visibleFields, titleField, columns, empt
|
|
|
145
145
|
}
|
|
146
146
|
return `<div class="card">${title ? `<div class="card-header">${title}</div>` : ''}<div class="card-body">${body || ' '}</div>${footer}</div>`;
|
|
147
147
|
}).join('\n');
|
|
148
|
-
return `<div class="dm-collection-display grid
|
|
148
|
+
return `<div class="dm-collection-display grid ${responsiveGridCols(cols).join(' ')} gap-4">\n${cards}\n</div>`;
|
|
149
149
|
}
|
|
150
150
|
|
|
151
151
|
function renderCollectionList(entries, visibleFields, titleField, emptyMsg, ctaOpts) {
|
|
@@ -495,14 +495,36 @@ function processPluginShortcodes(markdown) {
|
|
|
495
495
|
* @param {string} markdown
|
|
496
496
|
* @returns {string}
|
|
497
497
|
*/
|
|
498
|
+
|
|
499
|
+
/**
|
|
500
|
+
* Return the responsive Domma grid-cols class list for a given column count.
|
|
501
|
+
* Outputs mobile-first stacking: single column on small screens, then
|
|
502
|
+
* intermediate and full column counts at md/lg breakpoints.
|
|
503
|
+
*
|
|
504
|
+
* @param {string|number} cols
|
|
505
|
+
* @returns {string[]}
|
|
506
|
+
*/
|
|
507
|
+
function responsiveGridCols(cols) {
|
|
508
|
+
const map = {
|
|
509
|
+
'1': ['grid-cols-1'],
|
|
510
|
+
'2': ['grid-cols-1', 'grid-cols-md-2'],
|
|
511
|
+
'3': ['grid-cols-1', 'grid-cols-md-2', 'grid-cols-lg-3'],
|
|
512
|
+
'4': ['grid-cols-1', 'grid-cols-md-2', 'grid-cols-lg-4'],
|
|
513
|
+
'5': ['grid-cols-1', 'grid-cols-md-2', 'grid-cols-lg-5'],
|
|
514
|
+
'6': ['grid-cols-1', 'grid-cols-md-3', 'grid-cols-lg-6'],
|
|
515
|
+
};
|
|
516
|
+
return map[String(cols)] ?? [`grid-cols-${cols}`];
|
|
517
|
+
}
|
|
518
|
+
|
|
498
519
|
function processGridBlocks(markdown) {
|
|
499
520
|
const {scrubbed, restore} = scrubCodeRegions(markdown);
|
|
500
521
|
// Pass 1: [col span="N"]...[/col] → <div class="col-span-N">...</div>
|
|
522
|
+
// [col]...[/col] → <div class="col">...</div> (enables flex stacking in [row])
|
|
501
523
|
let result = scrubbed.replace(
|
|
502
524
|
/\[col([^\]]*)\]([\s\S]*?)\[\/col\]/gi,
|
|
503
525
|
(_, attrStr, body) => {
|
|
504
526
|
const attrs = parseShortcodeAttrs(attrStr);
|
|
505
|
-
|
|
527
|
+
const cls = attrs.span ? ` class="col-span-${attrs.span}"` : ' class="col"';
|
|
506
528
|
const id = attrs.id ? ` id="${escapeAttr(attrs.id)}"` : '';
|
|
507
529
|
return `<div${cls}${id}>${marked.parse(processCardBlocks(body.trim()))}</div>`;
|
|
508
530
|
}
|
|
@@ -521,13 +543,20 @@ function processGridBlocks(markdown) {
|
|
|
521
543
|
}
|
|
522
544
|
);
|
|
523
545
|
|
|
524
|
-
|
|
546
|
+
// Pass 3: [grid cols="N" gap="N"]...[/grid] → <div class="grid grid-cols-1 grid-cols-md-N ...">
|
|
547
|
+
// responsive="false" disables the mobile-first stacking behaviour
|
|
525
548
|
result = result.replace(
|
|
526
549
|
/\[grid([^\]]*)\]([\s\S]*?)\[\/grid\]/gi,
|
|
527
550
|
(_, attrStr, inner) => {
|
|
528
551
|
const attrs = parseShortcodeAttrs(attrStr);
|
|
529
552
|
const classes = ['grid'];
|
|
530
|
-
|
|
553
|
+
if (attrs.cols) {
|
|
554
|
+
if (attrs.responsive === 'false') {
|
|
555
|
+
classes.push(`grid-cols-${attrs.cols}`);
|
|
556
|
+
} else {
|
|
557
|
+
classes.push(...responsiveGridCols(attrs.cols));
|
|
558
|
+
}
|
|
559
|
+
}
|
|
531
560
|
if (attrs.gap) classes.push(`gap-${attrs.gap}`);
|
|
532
561
|
if (attrs.class) classes.push(attrs.class);
|
|
533
562
|
if (attrs.fullwidth === 'true') classes.push('grid-breakout');
|
|
@@ -1318,7 +1347,7 @@ function processHeroBlocks(markdown) {
|
|
|
1318
1347
|
const blobs = 'blobs' in attrs;
|
|
1319
1348
|
const blobsType = attrs['blobs-type'] || 'float-blobs';
|
|
1320
1349
|
|
|
1321
|
-
|
|
1350
|
+
const classes = ['hero', 'hero-responsive'];
|
|
1322
1351
|
if (size) classes.push(`hero-${size}`);
|
|
1323
1352
|
if (variant) classes.push(`hero-${variant}`);
|
|
1324
1353
|
if (align) classes.push(`hero-${align}`);
|