@memberjunction/ng-entity-viewer 5.11.0 → 5.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/lib/aggregate-panel/aggregate-panel.component.js +2 -2
- package/dist/lib/aggregate-setup-dialog/aggregate-setup-dialog.component.js +2 -2
- package/dist/lib/confirm-dialog/confirm-dialog.component.js +2 -2
- package/dist/lib/duplicate-view-dialog/duplicate-view-dialog.component.js +2 -2
- package/dist/lib/entity-cards/entity-cards.component.js +4 -4
- package/dist/lib/entity-cards/entity-cards.component.js.map +1 -1
- package/dist/lib/entity-data-grid/entity-data-grid.component.d.ts +26 -3
- package/dist/lib/entity-data-grid/entity-data-grid.component.d.ts.map +1 -1
- package/dist/lib/entity-data-grid/entity-data-grid.component.js +196 -137
- package/dist/lib/entity-data-grid/entity-data-grid.component.js.map +1 -1
- package/dist/lib/entity-data-grid/models/grid-types.js +4 -4
- package/dist/lib/entity-data-grid/models/grid-types.js.map +1 -1
- package/dist/lib/entity-record-detail-panel/entity-record-detail-panel.component.js +2 -2
- package/dist/lib/entity-viewer/entity-viewer.component.d.ts +5 -4
- package/dist/lib/entity-viewer/entity-viewer.component.d.ts.map +1 -1
- package/dist/lib/entity-viewer/entity-viewer.component.js +46 -69
- package/dist/lib/entity-viewer/entity-viewer.component.js.map +1 -1
- package/dist/lib/pill/pill.component.js +2 -2
- package/dist/lib/pill/pill.component.js.map +1 -1
- package/dist/lib/quick-save-dialog/quick-save-dialog.component.js +2 -2
- package/dist/lib/shared-view-warning-dialog/shared-view-warning-dialog.component.js +2 -2
- package/dist/lib/view-config-panel/view-config-panel.component.js +2 -2
- package/dist/lib/view-header/view-header.component.js +2 -2
- package/dist/module.d.ts +15 -16
- package/dist/module.d.ts.map +1 -1
- package/dist/module.js +4 -6
- package/dist/module.js.map +1 -1
- package/dist/public-api.d.ts +0 -1
- package/dist/public-api.d.ts.map +1 -1
- package/dist/public-api.js +0 -1
- package/dist/public-api.js.map +1 -1
- package/package.json +10 -9
- package/dist/lib/pagination/pagination.component.d.ts +0 -60
- package/dist/lib/pagination/pagination.component.d.ts.map +0 -1
- package/dist/lib/pagination/pagination.component.js +0 -201
- package/dist/lib/pagination/pagination.component.js.map +0 -1
|
@@ -2850,11 +2850,11 @@ export class ViewConfigPanelComponent {
|
|
|
2850
2850
|
i0.ɵɵproperty("IsOpen", ctx.showDeleteConfirm)("Message", "Are you sure you want to delete '" + ctx.viewName + "'?");
|
|
2851
2851
|
i0.ɵɵadvance();
|
|
2852
2852
|
i0.ɵɵproperty("IsOpen", ctx.showFilterModeSwitchConfirm)("Message", ctx.filterMode === "smart" ? "Switching to Traditional mode will clear your smart filter prompt." : "Switching to Smart mode will clear your traditional filter rules.");
|
|
2853
|
-
} }, dependencies: [i1.NgSelectOption, i1.ɵNgSelectMultipleOption, i1.DefaultValueAccessor, i1.NumberValueAccessor, i1.CheckboxControlValueAccessor, i1.SelectControlValueAccessor, i1.NgControlStatus, i1.MinValidator, i1.MaxValidator, i1.NgModel, i2.AggregateSetupDialogComponent, i3.ConfirmDialogComponent], styles: ["\n\n.panel-backdrop[_ngcontent-%COMP%] {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: rgba(0, 0, 0, 0.3);\n z-index: 1000;\n animation: _ngcontent-%COMP%_fadeIn 0.2s ease;\n}\n\n@keyframes _ngcontent-%COMP%_fadeIn {\n from { opacity: 0; }\n to { opacity: 1; }\n}\n\n\n\n.config-panel[_ngcontent-%COMP%] {\n position: fixed;\n top: 0;\n right: 0;\n width: 450px;\n min-width: 360px;\n max-width: min(800px, 100vw);\n height: 100%;\n background: white;\n box-shadow: -4px 0 24px rgba(0, 0, 0, 0.15);\n z-index: 1001;\n display: flex;\n flex-direction: column;\n transform: translateX(100%);\n transition: transform 0.25s ease, width 0s;\n}\n\n.config-panel.open[_ngcontent-%COMP%] {\n transform: translateX(0);\n}\n\n.config-panel.resizing[_ngcontent-%COMP%] {\n transition: none;\n user-select: none;\n}\n\n\n\n.resize-handle[_ngcontent-%COMP%] {\n position: absolute;\n left: 0;\n top: 0;\n bottom: 0;\n width: 6px;\n cursor: ew-resize;\n z-index: 10;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.resize-handle[_ngcontent-%COMP%]:hover, \n.config-panel.resizing[_ngcontent-%COMP%] .resize-handle[_ngcontent-%COMP%] {\n background: linear-gradient(90deg, rgba(25, 118, 210, 0.1) 0%, transparent 100%);\n}\n\n.resize-grip[_ngcontent-%COMP%] {\n width: 3px;\n height: 40px;\n background: #cbd5e1;\n border-radius: 3px;\n opacity: 0;\n transition: opacity 0.2s ease;\n}\n\n.resize-handle[_ngcontent-%COMP%]:hover .resize-grip[_ngcontent-%COMP%], \n.config-panel.resizing[_ngcontent-%COMP%] .resize-grip[_ngcontent-%COMP%] {\n opacity: 1;\n background: #1976d2;\n}\n\n\n\n.panel-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 16px 20px;\n border-bottom: 1px solid #e0e0e0;\n background: #fafafa;\n flex-shrink: 0;\n}\n\n.header-title[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 10px;\n font-size: 16px;\n font-weight: 600;\n color: #333;\n}\n\n.header-title[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: #1976d2;\n}\n\n.close-btn[_ngcontent-%COMP%] {\n width: 32px;\n height: 32px;\n border: none;\n background: transparent;\n border-radius: 6px;\n cursor: pointer;\n color: #666;\n transition: all 0.15s ease;\n}\n\n.close-btn[_ngcontent-%COMP%]:hover {\n background: #e0e0e0;\n color: #333;\n}\n\n\n\n.tab-nav[_ngcontent-%COMP%] {\n display: flex;\n border-bottom: 1px solid #e0e0e0;\n flex-shrink: 0;\n}\n\n.tab-btn[_ngcontent-%COMP%] {\n flex: 1;\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 8px;\n padding: 12px 16px;\n border: none;\n background: transparent;\n color: #666;\n font-size: 13px;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.15s ease;\n border-bottom: 2px solid transparent;\n}\n\n.tab-btn[_ngcontent-%COMP%]:hover {\n background: #f5f5f5;\n color: #333;\n}\n\n.tab-btn.active[_ngcontent-%COMP%] {\n color: #1976d2;\n border-bottom-color: #1976d2;\n background: transparent;\n}\n\n.tab-btn[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 12px;\n}\n\n.tab-badge[_ngcontent-%COMP%] {\n background: #1976d2;\n color: white;\n font-size: 10px;\n font-weight: 600;\n padding: 2px 6px;\n border-radius: 8px;\n margin-left: 4px;\n}\n\n\n\n.tab-nav.icon-only[_ngcontent-%COMP%] .tab-btn[_ngcontent-%COMP%] {\n padding: 12px 8px;\n gap: 4px;\n}\n\n.tab-nav.icon-only[_ngcontent-%COMP%] .tab-btn[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 14px;\n}\n\n.tab-nav.icon-only[_ngcontent-%COMP%] .tab-badge[_ngcontent-%COMP%] {\n margin-left: 0;\n padding: 2px 4px;\n font-size: 9px;\n}\n\n\n\n.panel-content[_ngcontent-%COMP%] {\n flex: 1;\n overflow: hidden;\n padding: 16px 0;\n display: flex;\n flex-direction: column;\n min-height: 0;\n}\n\n.tab-content[_ngcontent-%COMP%] {\n padding: 0 20px;\n flex: 1;\n display: flex;\n flex-direction: column;\n min-height: 0;\n overflow-y: auto;\n}\n\n\n\n.config-section[_ngcontent-%COMP%] {\n margin-bottom: 24px;\n}\n\n.section-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n margin-bottom: 12px;\n font-size: 13px;\n font-weight: 600;\n color: #333;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.section-header[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: #1976d2;\n font-size: 12px;\n}\n\n.column-count[_ngcontent-%COMP%] {\n margin-left: auto;\n background: #e3f2fd;\n color: #1976d2;\n padding: 2px 8px;\n border-radius: 10px;\n font-size: 11px;\n}\n\n\n\n.sort-config[_ngcontent-%COMP%] {\n display: flex;\n gap: 8px;\n}\n\n.sort-field-select[_ngcontent-%COMP%] {\n flex: 1;\n padding: 10px 12px;\n border: 1px solid #e0e0e0;\n border-radius: 6px;\n font-size: 14px;\n background: white;\n cursor: pointer;\n}\n\n.sort-field-select[_ngcontent-%COMP%]:focus {\n outline: none;\n border-color: #1976d2;\n}\n\n.sort-direction-toggle[_ngcontent-%COMP%] {\n display: flex;\n background: #f0f0f0;\n border-radius: 6px;\n padding: 2px;\n}\n\n.direction-btn[_ngcontent-%COMP%] {\n width: 36px;\n height: 36px;\n border: none;\n background: transparent;\n border-radius: 4px;\n cursor: pointer;\n color: #666;\n transition: all 0.15s ease;\n}\n\n.direction-btn[_ngcontent-%COMP%]:hover {\n color: #333;\n}\n\n.direction-btn.active[_ngcontent-%COMP%] {\n background: white;\n color: #1976d2;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);\n}\n\n\n\n\n\n\n.add-sort-btn[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 10px 14px;\n border: 1px dashed #ccc;\n border-radius: 8px;\n background: transparent;\n color: #666;\n font-size: 13px;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.15s ease;\n width: 100%;\n justify-content: center;\n margin-bottom: 12px;\n}\n\n.add-sort-btn[_ngcontent-%COMP%]:hover:not(:disabled) {\n border-color: #1976d2;\n background: #e3f2fd;\n color: #1976d2;\n}\n\n.add-sort-btn[_ngcontent-%COMP%]:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.add-sort-btn[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 12px;\n}\n\n\n\n.sort-items-list[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 8px;\n margin-bottom: 12px;\n}\n\n\n\n.sort-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 10px 12px;\n background: white;\n border: 1px solid #e0e0e0;\n border-radius: 8px;\n transition: all 0.15s ease;\n}\n\n.sort-item[_ngcontent-%COMP%]:hover {\n border-color: #bdbdbd;\n background: #fafafa;\n}\n\n.sort-item.dragging[_ngcontent-%COMP%] {\n opacity: 0.5;\n background: #e3f2fd;\n border-color: #1976d2;\n}\n\n.sort-item.drop-target[_ngcontent-%COMP%] {\n border-color: #1976d2;\n}\n\n\n\n.sort-priority-badge[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n min-width: 24px;\n height: 24px;\n padding: 0 6px;\n font-size: 12px;\n font-weight: 700;\n color: white;\n background: linear-gradient(135deg, #1976d2 0%, #42a5f5 100%);\n border-radius: 12px;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2);\n flex-shrink: 0;\n}\n\n\n\n.sort-drag-handle[_ngcontent-%COMP%] {\n color: #bdbdbd;\n cursor: grab;\n padding: 4px;\n transition: color 0.15s ease;\n flex-shrink: 0;\n}\n\n.sort-drag-handle[_ngcontent-%COMP%]:hover {\n color: #757575;\n}\n\n.sort-item.dragging[_ngcontent-%COMP%] .sort-drag-handle[_ngcontent-%COMP%] {\n cursor: grabbing;\n color: #1976d2;\n}\n\n\n\n.sort-field-dropdown[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 120px;\n padding: 8px 10px;\n border: 1px solid #e0e0e0;\n border-radius: 6px;\n font-size: 13px;\n background: white;\n cursor: pointer;\n}\n\n.sort-field-dropdown[_ngcontent-%COMP%]:focus {\n outline: none;\n border-color: #1976d2;\n}\n\n.sort-field-dropdown[_ngcontent-%COMP%]:disabled {\n background: #f5f5f5;\n color: #999;\n cursor: not-allowed;\n}\n\n\n\n.sort-remove-btn[_ngcontent-%COMP%] {\n width: 28px;\n height: 28px;\n border: none;\n background: transparent;\n border-radius: 4px;\n cursor: pointer;\n color: #bdbdbd;\n transition: all 0.15s ease;\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n}\n\n.sort-remove-btn[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: #ffebee;\n color: #c62828;\n}\n\n.sort-remove-btn[_ngcontent-%COMP%]:disabled {\n opacity: 0.3;\n cursor: not-allowed;\n}\n\n\n\n.sort-drop-indicator[_ngcontent-%COMP%] {\n height: 3px;\n background: linear-gradient(90deg, #1976d2 0%, #42a5f5 50%, #1976d2 100%);\n border-radius: 2px;\n margin: 0 12px;\n box-shadow: 0 0 8px rgba(25, 118, 210, 0.5);\n animation: _ngcontent-%COMP%_sortDropIndicatorPulse 0.8s ease-in-out infinite;\n}\n\n@keyframes _ngcontent-%COMP%_sortDropIndicatorPulse {\n 0%, 100% { opacity: 1; transform: scaleX(1); }\n 50% { opacity: 0.7; transform: scaleX(0.98); }\n}\n\n\n\n.sort-hint[_ngcontent-%COMP%] {\n display: flex;\n align-items: flex-start;\n gap: 8px;\n padding: 10px 12px;\n background: #f5f7fa;\n border-radius: 6px;\n font-size: 12px;\n color: #666;\n}\n\n.sort-hint[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: #1976d2;\n margin-top: 1px;\n flex-shrink: 0;\n}\n\n\n\n.sorting-section[_ngcontent-%COMP%] {\n padding-top: 0;\n}\n\n.sorting-header[_ngcontent-%COMP%] {\n margin-bottom: 16px;\n}\n\n.sorting-description[_ngcontent-%COMP%] {\n font-size: 13px;\n color: #666;\n line-height: 1.5;\n margin: 0;\n}\n\n\n\n.sort-empty-state[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n gap: 8px;\n padding: 40px 20px;\n color: #999;\n font-size: 14px;\n text-align: center;\n}\n\n.sort-empty-state[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 48px;\n opacity: 0.4;\n margin-bottom: 8px;\n}\n\n.sort-empty-hint[_ngcontent-%COMP%] {\n font-size: 12px;\n color: #bbb;\n margin: 0;\n}\n\n\n\n.column-list[_ngcontent-%COMP%] {\n border: 1px solid #e0e0e0;\n border-radius: 8px;\n overflow: hidden;\n background: #fafafa;\n}\n\n.column-list.visible-columns[_ngcontent-%COMP%] {\n max-height: 300px;\n overflow-y: auto;\n}\n\n.column-list.hidden-columns[_ngcontent-%COMP%] {\n flex: 1;\n min-height: 100px;\n overflow-y: auto;\n}\n\n\n\n.config-section[_ngcontent-%COMP%]:last-child {\n flex: 1;\n display: flex;\n flex-direction: column;\n min-height: 0;\n margin-bottom: 0;\n}\n\n.column-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 10px 12px;\n background: white;\n border-bottom: 1px solid #f0f0f0;\n transition: background 0.1s ease;\n position: relative;\n}\n\n.column-item[_ngcontent-%COMP%]:last-child {\n border-bottom: none;\n}\n\n.column-item[_ngcontent-%COMP%]:hover {\n background: #f5f7fa;\n}\n\n.column-item.hidden[_ngcontent-%COMP%] {\n background: #fafafa;\n}\n\n.column-item.hidden[_ngcontent-%COMP%]:hover {\n background: #f0f0f0;\n}\n\n\n\n\n\n\n\n\n.drop-indicator[_ngcontent-%COMP%] {\n height: 3px;\n background: linear-gradient(90deg, #1976d2 0%, #42a5f5 50%, #1976d2 100%);\n border-radius: 2px;\n margin: 0 12px;\n box-shadow: 0 0 8px rgba(25, 118, 210, 0.5);\n animation: _ngcontent-%COMP%_dropIndicatorPulse 0.8s ease-in-out infinite;\n}\n\n@keyframes _ngcontent-%COMP%_dropIndicatorPulse {\n 0%, 100% { opacity: 1; transform: scaleX(1); }\n 50% { opacity: 0.7; transform: scaleX(0.98); }\n}\n\n\n\n.column-item.dragging[_ngcontent-%COMP%] {\n opacity: 0.5;\n background: #e3f2fd;\n}\n\n\n\n.column-item.drag-over[_ngcontent-%COMP%] {\n background: #f5f7fa;\n}\n\n.drag-handle[_ngcontent-%COMP%] {\n cursor: grab;\n color: #999;\n padding: 4px;\n transition: color 0.15s ease;\n}\n\n.drag-handle[_ngcontent-%COMP%]:hover {\n color: #666;\n}\n\n.drag-handle[_ngcontent-%COMP%]:active {\n cursor: grabbing;\n color: #1976d2;\n}\n\n.column-name[_ngcontent-%COMP%] {\n flex: 1;\n font-size: 14px;\n color: #333;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n display: flex;\n align-items: center;\n gap: 6px;\n}\n\n.column-name[_ngcontent-%COMP%] .format-indicator[_ngcontent-%COMP%] {\n font-size: 10px;\n color: #1976d2;\n opacity: 0.7;\n}\n\n.column-name[_ngcontent-%COMP%] .alias-indicator[_ngcontent-%COMP%] {\n font-size: 10px;\n color: #7b1fa2;\n opacity: 0.8;\n}\n\n.column-actions[_ngcontent-%COMP%] {\n display: flex;\n gap: 4px;\n}\n\n.action-btn[_ngcontent-%COMP%] {\n width: 28px;\n height: 28px;\n border: none;\n background: transparent;\n border-radius: 4px;\n cursor: pointer;\n color: #999;\n transition: all 0.15s ease;\n}\n\n.action-btn[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: #e0e0e0;\n color: #333;\n}\n\n.action-btn[_ngcontent-%COMP%]:disabled {\n opacity: 0.3;\n cursor: not-allowed;\n}\n\n.action-btn.hide-btn[_ngcontent-%COMP%]:hover {\n background: #ffebee;\n color: #c62828;\n}\n\n.action-btn.show-btn[_ngcontent-%COMP%]:hover {\n background: #e8f5e9;\n color: #2e7d32;\n}\n\n.action-btn.format-btn[_ngcontent-%COMP%]:hover {\n background: #e3f2fd;\n color: #1976d2;\n}\n\n.action-btn.format-btn.has-format[_ngcontent-%COMP%] {\n color: #1976d2;\n background: #e3f2fd;\n}\n\n.empty-list[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 8px;\n padding: 20px;\n color: #999;\n font-size: 13px;\n}\n\n\n\n.column-search[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px 12px;\n background: white;\n border: 1px solid #e0e0e0;\n border-radius: 6px;\n margin-bottom: 8px;\n}\n\n.column-search[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: #999;\n font-size: 12px;\n}\n\n.column-search[_ngcontent-%COMP%] input[_ngcontent-%COMP%] {\n flex: 1;\n border: none;\n outline: none;\n font-size: 14px;\n}\n\n\n\n\n\n\n.format-editor-panel[_ngcontent-%COMP%] {\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: white;\n z-index: 100;\n display: flex;\n flex-direction: column;\n animation: _ngcontent-%COMP%_slideInFromRight 0.2s ease;\n}\n\n@keyframes _ngcontent-%COMP%_slideInFromRight {\n from {\n transform: translateX(100%);\n opacity: 0;\n }\n to {\n transform: translateX(0);\n opacity: 1;\n }\n}\n\n.format-editor-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 16px 20px;\n border-bottom: 1px solid #e0e0e0;\n background: #fafafa;\n flex-shrink: 0;\n}\n\n.format-back-btn[_ngcontent-%COMP%] {\n width: 32px;\n height: 32px;\n border: none;\n background: transparent;\n border-radius: 6px;\n cursor: pointer;\n color: #666;\n transition: all 0.15s ease;\n}\n\n.format-back-btn[_ngcontent-%COMP%]:hover {\n background: #e0e0e0;\n color: #333;\n}\n\n.format-header-title[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 2px;\n}\n\n.format-header-title[_ngcontent-%COMP%] span[_ngcontent-%COMP%]:first-child {\n font-size: 14px;\n font-weight: 600;\n color: #333;\n}\n\n.format-header-title[_ngcontent-%COMP%] span[_ngcontent-%COMP%]:last-child {\n font-size: 12px;\n color: #666;\n}\n\n.format-editor-content[_ngcontent-%COMP%] {\n flex: 1;\n overflow-y: auto;\n padding: 20px;\n}\n\n\n\n.format-preview-section[_ngcontent-%COMP%] {\n margin-bottom: 24px;\n padding: 16px;\n background: linear-gradient(135deg, #f8fafc 0%, #f1f5f9 100%);\n border: 1px solid #e2e8f0;\n border-radius: 12px;\n}\n\n.preview-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n margin-bottom: 12px;\n font-size: 12px;\n font-weight: 600;\n color: #64748b;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.preview-header[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: #3b82f6;\n}\n\n.preview-samples[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n\n.preview-sample[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 10px 14px;\n background: white;\n border-radius: 8px;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.08);\n}\n\n.preview-label[_ngcontent-%COMP%] {\n font-size: 12px;\n color: #94a3b8;\n min-width: 60px;\n}\n\n.preview-value[_ngcontent-%COMP%] {\n flex: 1;\n font-size: 14px;\n font-family: 'SF Mono', 'Monaco', monospace;\n color: #1e293b;\n}\n\n\n\n.format-type-section[_ngcontent-%COMP%] {\n margin-bottom: 24px;\n}\n\n.format-type-section[_ngcontent-%COMP%] .section-label[_ngcontent-%COMP%] {\n display: block;\n margin-bottom: 10px;\n font-size: 13px;\n font-weight: 600;\n color: #333;\n}\n\n.format-type-grid[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: repeat(4, 1fr);\n gap: 8px;\n}\n\n.format-type-btn[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 6px;\n padding: 12px 8px;\n border: 2px solid #e5e7eb;\n border-radius: 10px;\n background: white;\n cursor: pointer;\n transition: all 0.15s ease;\n}\n\n.format-type-btn[_ngcontent-%COMP%]:hover {\n border-color: #cbd5e1;\n background: #f8fafc;\n}\n\n.format-type-btn.active[_ngcontent-%COMP%] {\n border-color: #3b82f6;\n background: #eff6ff;\n}\n\n.format-type-btn[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 18px;\n color: #64748b;\n}\n\n.format-type-btn.active[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: #3b82f6;\n}\n\n.format-type-btn[_ngcontent-%COMP%] span[_ngcontent-%COMP%] {\n font-size: 11px;\n font-weight: 500;\n color: #64748b;\n}\n\n.format-type-btn.active[_ngcontent-%COMP%] span[_ngcontent-%COMP%] {\n color: #1d4ed8;\n}\n\n\n\n.format-options-section[_ngcontent-%COMP%] {\n margin-bottom: 24px;\n}\n\n.format-options-section[_ngcontent-%COMP%] .section-label[_ngcontent-%COMP%] {\n display: block;\n margin-bottom: 12px;\n font-size: 13px;\n font-weight: 600;\n color: #333;\n}\n\n.format-option-group[_ngcontent-%COMP%] {\n margin-bottom: 16px;\n}\n\n.format-option-group[_ngcontent-%COMP%] label[_ngcontent-%COMP%] {\n display: block;\n margin-bottom: 6px;\n font-size: 13px;\n font-weight: 500;\n color: #333;\n}\n\n.format-option-group[_ngcontent-%COMP%] input[_ngcontent-%COMP%], \n.format-option-group[_ngcontent-%COMP%] select[_ngcontent-%COMP%] {\n width: 100%;\n padding: 10px 12px;\n border: 1px solid #e0e0e0;\n border-radius: 6px;\n font-size: 14px;\n transition: border-color 0.15s ease;\n}\n\n.format-option-group[_ngcontent-%COMP%] input[_ngcontent-%COMP%]:focus, \n.format-option-group[_ngcontent-%COMP%] select[_ngcontent-%COMP%]:focus {\n outline: none;\n border-color: #1976d2;\n}\n\n.format-option-row[_ngcontent-%COMP%] {\n display: flex;\n gap: 12px;\n}\n\n.format-option-row[_ngcontent-%COMP%] .format-option-group[_ngcontent-%COMP%] {\n flex: 1;\n}\n\n.format-checkbox[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 10px;\n cursor: pointer;\n}\n\n.format-checkbox[_ngcontent-%COMP%] input[type=\"checkbox\"][_ngcontent-%COMP%] {\n width: 18px;\n height: 18px;\n cursor: pointer;\n}\n\n.format-checkbox[_ngcontent-%COMP%] span[_ngcontent-%COMP%] {\n font-size: 14px;\n color: #333;\n}\n\n\n\n.alignment-options[_ngcontent-%COMP%] {\n display: flex;\n gap: 8px;\n}\n\n.align-btn[_ngcontent-%COMP%] {\n flex: 1;\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 10px;\n border: 2px solid #e5e7eb;\n border-radius: 8px;\n background: white;\n cursor: pointer;\n transition: all 0.15s ease;\n}\n\n.align-btn[_ngcontent-%COMP%]:hover {\n border-color: #cbd5e1;\n background: #f8fafc;\n}\n\n.align-btn.active[_ngcontent-%COMP%] {\n border-color: #3b82f6;\n background: #eff6ff;\n color: #3b82f6;\n}\n\n.align-btn[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 16px;\n color: #64748b;\n}\n\n.align-btn.active[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: #3b82f6;\n}\n\n\n\n.style-section[_ngcontent-%COMP%] {\n margin-bottom: 24px;\n}\n\n.style-section[_ngcontent-%COMP%] .section-label[_ngcontent-%COMP%] {\n display: block;\n margin-bottom: 12px;\n font-size: 13px;\n font-weight: 600;\n color: #333;\n}\n\n.style-toggle-group[_ngcontent-%COMP%] {\n display: flex;\n gap: 8px;\n margin-bottom: 12px;\n}\n\n.style-toggle-btn[_ngcontent-%COMP%] {\n width: 40px;\n height: 40px;\n border: 2px solid #e5e7eb;\n border-radius: 8px;\n background: white;\n cursor: pointer;\n transition: all 0.15s ease;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.style-toggle-btn[_ngcontent-%COMP%]:hover {\n border-color: #cbd5e1;\n background: #f8fafc;\n}\n\n.style-toggle-btn.active[_ngcontent-%COMP%] {\n border-color: #3b82f6;\n background: #eff6ff;\n}\n\n.style-toggle-btn[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 16px;\n color: #64748b;\n}\n\n.style-toggle-btn.active[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: #3b82f6;\n}\n\n.color-picker-row[_ngcontent-%COMP%] {\n display: flex;\n gap: 12px;\n align-items: center;\n}\n\n.color-picker-group[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.color-picker-group[_ngcontent-%COMP%] label[_ngcontent-%COMP%] {\n font-size: 13px;\n color: #64748b;\n min-width: 80px;\n}\n\n.color-picker-group[_ngcontent-%COMP%] input[type=\"color\"][_ngcontent-%COMP%] {\n width: 40px;\n height: 32px;\n padding: 2px;\n border: 1px solid #e0e0e0;\n border-radius: 6px;\n cursor: pointer;\n}\n\n.color-clear-btn[_ngcontent-%COMP%] {\n width: 32px;\n height: 32px;\n border: 1px solid #e0e0e0;\n border-radius: 6px;\n background: white;\n cursor: pointer;\n color: #999;\n transition: all 0.15s ease;\n}\n\n.color-clear-btn[_ngcontent-%COMP%]:hover {\n background: #f5f5f5;\n color: #666;\n}\n\n\n\n.format-editor-footer[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 16px 20px;\n border-top: 1px solid #e0e0e0;\n background: #fafafa;\n flex-shrink: 0;\n}\n\n.format-footer-left[_ngcontent-%COMP%] {\n display: flex;\n gap: 8px;\n}\n\n.format-footer-right[_ngcontent-%COMP%] {\n display: flex;\n gap: 8px;\n}\n\n.format-footer-btn[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 8px;\n padding: 10px 16px;\n border: 1px solid #e0e0e0;\n background: white;\n border-radius: 6px;\n font-size: 14px;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.15s ease;\n}\n\n.format-footer-btn[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: #f0f0f0;\n border-color: #ccc;\n}\n\n.format-footer-btn.primary[_ngcontent-%COMP%] {\n background: #1976d2;\n border-color: #1976d2;\n color: white;\n}\n\n.format-footer-btn.primary[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: #1565c0;\n border-color: #1565c0;\n}\n\n.format-footer-btn.danger[_ngcontent-%COMP%] {\n color: #c62828;\n border-color: #c62828;\n}\n\n.format-footer-btn.danger[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: #c62828;\n color: white;\n}\n\n\n\n.filter-summary-container[_ngcontent-%COMP%] {\n padding: 4px 0;\n}\n\n.filter-summary[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 12px 16px;\n background: #f5f7fa;\n border-radius: 8px;\n border: 1px solid #e8e8e8;\n}\n\n.summary-info[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.filter-badge[_ngcontent-%COMP%] {\n background: #1976d2;\n color: white;\n font-size: 12px;\n font-weight: 600;\n padding: 2px 8px;\n border-radius: 10px;\n min-width: 20px;\n text-align: center;\n}\n\n.summary-text[_ngcontent-%COMP%] {\n font-size: 14px;\n color: #333;\n}\n\n.summary-text.no-filters[_ngcontent-%COMP%] {\n color: #999;\n}\n\n.summary-actions[_ngcontent-%COMP%] {\n display: flex;\n gap: 8px;\n}\n\n.summary-btn[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 4px;\n padding: 6px 12px;\n border: none;\n border-radius: 6px;\n font-size: 13px;\n cursor: pointer;\n transition: all 0.15s ease;\n}\n\n.summary-btn[_ngcontent-%COMP%]:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.summary-btn[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 11px;\n}\n\n.summary-btn.clear-btn[_ngcontent-%COMP%] {\n background: transparent;\n color: #c62828;\n border: 1px solid #e0e0e0;\n}\n\n.summary-btn.clear-btn[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: #ffebee;\n border-color: #c62828;\n}\n\n.summary-btn.edit-btn[_ngcontent-%COMP%] {\n background: #1976d2;\n color: white;\n}\n\n.summary-btn.edit-btn[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: #1565c0;\n}\n\n\n\n\n\n\n.filter-mode-selector[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 8px;\n margin-bottom: 16px;\n}\n\n.filter-mode-btn[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 14px;\n padding: 14px 16px;\n border: 2px solid #e5e7eb;\n border-radius: 12px;\n background: white;\n cursor: pointer;\n transition: all 0.2s ease;\n text-align: left;\n}\n\n.filter-mode-btn[_ngcontent-%COMP%]:hover:not(:disabled) {\n border-color: #d1d5db;\n background: #f9fafb;\n}\n\n.filter-mode-btn[_ngcontent-%COMP%]:disabled {\n opacity: 0.6;\n cursor: not-allowed;\n}\n\n.filter-mode-btn.active[_ngcontent-%COMP%] {\n border-color: #3b82f6;\n background: linear-gradient(135deg, #eff6ff 0%, #dbeafe 100%);\n}\n\n.filter-mode-btn[_ngcontent-%COMP%] .mode-icon[_ngcontent-%COMP%] {\n width: 40px;\n height: 40px;\n display: flex;\n align-items: center;\n justify-content: center;\n border-radius: 10px;\n background: #f3f4f6;\n color: #6b7280;\n font-size: 16px;\n flex-shrink: 0;\n transition: all 0.2s ease;\n}\n\n.filter-mode-btn.active[_ngcontent-%COMP%] .mode-icon[_ngcontent-%COMP%] {\n background: #3b82f6;\n color: white;\n}\n\n.filter-mode-btn[_ngcontent-%COMP%] .mode-content[_ngcontent-%COMP%] {\n flex: 1;\n display: flex;\n flex-direction: column;\n gap: 2px;\n}\n\n.filter-mode-btn[_ngcontent-%COMP%] .mode-title[_ngcontent-%COMP%] {\n font-size: 14px;\n font-weight: 600;\n color: #1f2937;\n}\n\n.filter-mode-btn[_ngcontent-%COMP%] .mode-subtitle[_ngcontent-%COMP%] {\n font-size: 12px;\n color: #6b7280;\n}\n\n.filter-mode-btn.active[_ngcontent-%COMP%] .mode-title[_ngcontent-%COMP%] {\n color: #1d4ed8;\n}\n\n.filter-mode-btn[_ngcontent-%COMP%] .mode-check[_ngcontent-%COMP%] {\n color: #3b82f6;\n font-size: 16px;\n flex-shrink: 0;\n}\n\n\n\n\n\n\n.smart-filter-section[_ngcontent-%COMP%] {\n padding: 0;\n border: none;\n background: transparent;\n}\n\n.smart-filter-input-container[_ngcontent-%COMP%] {\n display: flex;\n gap: 12px;\n padding: 16px;\n background: linear-gradient(135deg, #f0f9ff 0%, #e0f2fe 100%);\n border: 1px solid #bae6fd;\n border-radius: 12px;\n margin-bottom: 16px;\n}\n\n.smart-filter-icon[_ngcontent-%COMP%] {\n width: 36px;\n height: 36px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: linear-gradient(135deg, #3b82f6 0%, #6366f1 100%);\n border-radius: 10px;\n color: white;\n font-size: 14px;\n flex-shrink: 0;\n}\n\n.smart-filter-input-container[_ngcontent-%COMP%] .smart-filter-textarea[_ngcontent-%COMP%] {\n flex: 1;\n border: none;\n background: white;\n border-radius: 8px;\n padding: 12px;\n font-size: 14px;\n line-height: 1.5;\n resize: none;\n min-height: 60px;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.08);\n}\n\n.smart-filter-input-container[_ngcontent-%COMP%] .smart-filter-textarea[_ngcontent-%COMP%]:focus {\n outline: none;\n box-shadow: 0 0 0 2px rgba(59, 130, 246, 0.3), 0 1px 3px rgba(0, 0, 0, 0.08);\n}\n\n.smart-filter-input-container[_ngcontent-%COMP%] .smart-filter-textarea[_ngcontent-%COMP%]::placeholder {\n color: #9ca3af;\n}\n\n.smart-filter-explanation[_ngcontent-%COMP%] {\n display: flex;\n align-items: flex-start;\n gap: 8px;\n padding: 12px;\n background: #e3f2fd;\n border-radius: 6px;\n margin-bottom: 12px;\n font-size: 13px;\n color: #1565c0;\n}\n\n.smart-filter-explanation[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: #1976d2;\n font-size: 14px;\n margin-top: 2px;\n flex-shrink: 0;\n}\n\n\n\n.smart-filter-examples[_ngcontent-%COMP%] {\n margin-bottom: 16px;\n}\n\n.examples-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n margin-bottom: 10px;\n font-size: 13px;\n font-weight: 500;\n color: #6b7280;\n}\n\n.examples-header[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: #f59e0b;\n}\n\n.example-chips[_ngcontent-%COMP%] {\n display: flex;\n flex-wrap: wrap;\n gap: 8px;\n}\n\n.example-chip[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 8px 12px;\n border: 1px solid #e5e7eb;\n border-radius: 20px;\n background: white;\n font-size: 12px;\n font-weight: 500;\n color: #4b5563;\n cursor: pointer;\n transition: all 0.15s ease;\n}\n\n.example-chip[_ngcontent-%COMP%]:hover:not(:disabled) {\n border-color: #3b82f6;\n background: #eff6ff;\n color: #1d4ed8;\n}\n\n.example-chip[_ngcontent-%COMP%]:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.example-chip[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 11px;\n color: #9ca3af;\n}\n\n.example-chip[_ngcontent-%COMP%]:hover:not(:disabled) i[_ngcontent-%COMP%] {\n color: #3b82f6;\n}\n\n\n\n.smart-filter-tip[_ngcontent-%COMP%] {\n display: flex;\n align-items: flex-start;\n gap: 10px;\n padding: 12px 14px;\n background: #f8fafc;\n border: 1px solid #e2e8f0;\n border-radius: 8px;\n font-size: 12px;\n color: #64748b;\n line-height: 1.5;\n}\n\n.smart-filter-tip[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: #94a3b8;\n margin-top: 1px;\n flex-shrink: 0;\n}\n\n\n\n\n\n\n.traditional-filter-section[_ngcontent-%COMP%] {\n padding: 0;\n border: none;\n background: transparent;\n}\n\n.traditional-filter-tip[_ngcontent-%COMP%] {\n display: flex;\n align-items: flex-start;\n gap: 10px;\n padding: 12px 14px;\n background: #f8fafc;\n border: 1px solid #e2e8f0;\n border-radius: 8px;\n font-size: 12px;\n color: #64748b;\n line-height: 1.5;\n margin-top: 12px;\n}\n\n.traditional-filter-tip[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: #94a3b8;\n margin-top: 1px;\n flex-shrink: 0;\n}\n\n.summary-btn.edit-btn.primary[_ngcontent-%COMP%] {\n background: #3b82f6;\n color: white;\n border-color: #3b82f6;\n}\n\n.summary-btn.edit-btn.primary[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: #2563eb;\n border-color: #2563eb;\n}\n\n\n\n.form-group[_ngcontent-%COMP%] {\n margin-bottom: 16px;\n}\n\n.form-group[_ngcontent-%COMP%] label[_ngcontent-%COMP%] {\n display: block;\n margin-bottom: 6px;\n font-size: 13px;\n font-weight: 500;\n color: #333;\n}\n\n.form-input[_ngcontent-%COMP%] {\n width: 100%;\n padding: 10px 12px;\n border: 1px solid #e0e0e0;\n border-radius: 6px;\n font-size: 14px;\n transition: border-color 0.15s ease;\n}\n\n.form-input[_ngcontent-%COMP%]:focus {\n outline: none;\n border-color: #1976d2;\n}\n\n.form-input[_ngcontent-%COMP%]:disabled {\n background: #f5f5f5;\n color: #999;\n}\n\n.form-textarea[_ngcontent-%COMP%] {\n resize: vertical;\n min-height: 80px;\n}\n\n\n\n.checkbox-label[_ngcontent-%COMP%] {\n display: flex;\n align-items: flex-start;\n gap: 12px;\n cursor: pointer;\n}\n\n.checkbox-label[_ngcontent-%COMP%] input[type=\"checkbox\"][_ngcontent-%COMP%] {\n width: 18px;\n height: 18px;\n margin-top: 2px;\n cursor: pointer;\n}\n\n.checkbox-text[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 2px;\n}\n\n.checkbox-text[_ngcontent-%COMP%] strong[_ngcontent-%COMP%] {\n font-size: 14px;\n color: #333;\n}\n\n.checkbox-text[_ngcontent-%COMP%] small[_ngcontent-%COMP%] {\n font-size: 12px;\n color: #666;\n}\n\n\n\n.danger-zone[_ngcontent-%COMP%] {\n padding-top: 16px;\n border-top: 1px solid #ffcdd2;\n}\n\n.danger-zone[_ngcontent-%COMP%] .section-header[_ngcontent-%COMP%] {\n color: #c62828;\n}\n\n.danger-zone[_ngcontent-%COMP%] .section-header[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: #c62828;\n}\n\n.delete-btn[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 8px;\n width: 100%;\n padding: 10px 16px;\n border: 1px solid #c62828;\n background: transparent;\n border-radius: 6px;\n color: #c62828;\n font-size: 14px;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.15s ease;\n}\n\n.delete-btn[_ngcontent-%COMP%]:hover {\n background: #c62828;\n color: white;\n}\n\n\n\n.panel-footer[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 16px 20px;\n border-top: 1px solid #e0e0e0;\n background: #fafafa;\n flex-shrink: 0;\n}\n\n.footer-left[_ngcontent-%COMP%] {\n display: flex;\n gap: 8px;\n}\n\n.footer-right[_ngcontent-%COMP%] {\n display: flex;\n gap: 8px;\n}\n\n.footer-btn[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 8px;\n padding: 10px 16px;\n border: 1px solid #e0e0e0;\n background: white;\n border-radius: 6px;\n font-size: 14px;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.15s ease;\n}\n\n.footer-btn[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: #f0f0f0;\n border-color: #ccc;\n}\n\n.footer-btn[_ngcontent-%COMP%]:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.footer-btn.primary[_ngcontent-%COMP%] {\n background: #1976d2;\n border-color: #1976d2;\n color: white;\n}\n\n.footer-btn.primary[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: #1565c0;\n border-color: #1565c0;\n}\n\n.footer-btn[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 12px;\n}\n\n\n\n\n\n\n.format-editor[_ngcontent-%COMP%] {\n padding: 0 20px;\n flex: 1;\n display: flex;\n flex-direction: column;\n min-height: 0;\n overflow-y: auto;\n}\n\n.format-editor[_ngcontent-%COMP%] .format-editor-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 12px 0 16px 0;\n border-bottom: 1px solid #e0e0e0;\n margin-bottom: 16px;\n}\n\n.format-editor[_ngcontent-%COMP%] .back-btn[_ngcontent-%COMP%] {\n width: 32px;\n height: 32px;\n border: none;\n background: transparent;\n border-radius: 6px;\n cursor: pointer;\n color: #666;\n transition: all 0.15s ease;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.format-editor[_ngcontent-%COMP%] .back-btn[_ngcontent-%COMP%]:hover {\n background: #e0e0e0;\n color: #333;\n}\n\n.format-editor[_ngcontent-%COMP%] .format-editor-title[_ngcontent-%COMP%] {\n font-size: 16px;\n font-weight: 600;\n color: #333;\n}\n\n\n\n.format-editor[_ngcontent-%COMP%] .preview-table[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 4px;\n margin-top: 12px;\n}\n\n.format-editor[_ngcontent-%COMP%] .preview-header-cell[_ngcontent-%COMP%] {\n padding: 10px 14px;\n background: #f1f5f9;\n border-radius: 6px;\n font-weight: 600;\n font-size: 13px;\n color: #333;\n}\n\n.format-editor[_ngcontent-%COMP%] .preview-cell[_ngcontent-%COMP%] {\n padding: 8px 14px;\n background: white;\n border: 1px solid #e2e8f0;\n border-radius: 4px;\n font-size: 14px;\n color: #333;\n}\n\n\n\n.format-section[_ngcontent-%COMP%] {\n margin-bottom: 20px;\n padding-bottom: 16px;\n border-bottom: 1px solid #f0f0f0;\n}\n\n.format-section[_ngcontent-%COMP%]:last-child {\n border-bottom: none;\n}\n\n.format-section-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n margin-bottom: 12px;\n font-size: 13px;\n font-weight: 600;\n color: #333;\n}\n\n.format-section-header[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: #1976d2;\n font-size: 12px;\n}\n\n\n\n.format-row[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 12px;\n margin-bottom: 10px;\n}\n\n.format-row[_ngcontent-%COMP%]:last-child {\n margin-bottom: 0;\n}\n\n.format-row[_ngcontent-%COMP%] label[_ngcontent-%COMP%] {\n font-size: 13px;\n color: #555;\n flex-shrink: 0;\n}\n\n\n\n.format-select[_ngcontent-%COMP%] {\n flex: 1;\n padding: 8px 12px;\n border: 1px solid #e0e0e0;\n border-radius: 6px;\n font-size: 14px;\n background: white;\n cursor: pointer;\n min-width: 120px;\n}\n\n.format-select[_ngcontent-%COMP%]:focus {\n outline: none;\n border-color: #1976d2;\n}\n\n.format-input[_ngcontent-%COMP%] {\n padding: 8px 12px;\n border: 1px solid #e0e0e0;\n border-radius: 6px;\n font-size: 14px;\n background: white;\n}\n\n.format-input[_ngcontent-%COMP%]:focus {\n outline: none;\n border-color: #1976d2;\n}\n\n.format-input.small[_ngcontent-%COMP%] {\n width: 80px;\n}\n\n\n\n.format-row.alias-info[_ngcontent-%COMP%] {\n justify-content: flex-start;\n gap: 8px;\n}\n\n.format-row.alias-info[_ngcontent-%COMP%] .muted-text[_ngcontent-%COMP%] {\n color: #888;\n font-size: 12px;\n}\n\n.clear-alias-btn[_ngcontent-%COMP%] {\n width: 20px;\n height: 20px;\n border: none;\n background: #f0f0f0;\n border-radius: 50%;\n color: #888;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 10px;\n transition: all 0.15s ease;\n}\n\n.clear-alias-btn[_ngcontent-%COMP%]:hover {\n background: #e0e0e0;\n color: #c62828;\n}\n\n\n\n.color-input[_ngcontent-%COMP%] {\n width: 50px;\n height: 32px;\n padding: 2px;\n border: 1px solid #e0e0e0;\n border-radius: 6px;\n cursor: pointer;\n background: white;\n}\n\n.color-input[_ngcontent-%COMP%]:focus {\n outline: none;\n border-color: #1976d2;\n}\n\n\n\n.alignment-toggle[_ngcontent-%COMP%] {\n display: flex;\n gap: 8px;\n}\n\n.align-btn[_ngcontent-%COMP%] {\n width: 40px;\n height: 36px;\n border: 2px solid #e5e7eb;\n border-radius: 6px;\n background: white;\n cursor: pointer;\n transition: all 0.15s ease;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.align-btn[_ngcontent-%COMP%]:hover {\n border-color: #cbd5e1;\n background: #f8fafc;\n}\n\n.align-btn.active[_ngcontent-%COMP%] {\n border-color: #1976d2;\n background: #e3f2fd;\n}\n\n.align-btn[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 14px;\n color: #64748b;\n}\n\n.align-btn.active[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: #1976d2;\n}\n\n\n\n.style-buttons[_ngcontent-%COMP%] {\n display: flex;\n gap: 8px;\n margin-bottom: 12px;\n}\n\n.style-btn[_ngcontent-%COMP%] {\n width: 36px;\n height: 36px;\n border: 2px solid #e5e7eb;\n border-radius: 6px;\n background: white;\n cursor: pointer;\n transition: all 0.15s ease;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.style-btn[_ngcontent-%COMP%]:hover {\n border-color: #cbd5e1;\n background: #f8fafc;\n}\n\n.style-btn.active[_ngcontent-%COMP%] {\n border-color: #1976d2;\n background: #e3f2fd;\n}\n\n.style-btn[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 14px;\n color: #64748b;\n}\n\n.style-btn.active[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: #1976d2;\n}\n\n\n\n.format-section-collapsible[_ngcontent-%COMP%] {\n margin-bottom: 12px;\n border: 1px solid #e0e0e0;\n border-radius: 8px;\n overflow: hidden;\n}\n\n.format-section-collapsible[_ngcontent-%COMP%] summary[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 12px 14px;\n background: #f8fafc;\n cursor: pointer;\n font-size: 13px;\n font-weight: 500;\n color: #333;\n list-style: none;\n}\n\n.format-section-collapsible[_ngcontent-%COMP%] summary[_ngcontent-%COMP%]::-webkit-details-marker {\n display: none;\n}\n\n.format-section-collapsible[_ngcontent-%COMP%] summary[_ngcontent-%COMP%]::before {\n content: '\\f054';\n font-family: 'Font Awesome 6 Free';\n font-weight: 900;\n font-size: 10px;\n color: #999;\n transition: transform 0.2s ease;\n}\n\n.format-section-collapsible[open][_ngcontent-%COMP%] summary[_ngcontent-%COMP%]::before {\n transform: rotate(90deg);\n}\n\n.format-section-collapsible[_ngcontent-%COMP%] summary[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: #1976d2;\n font-size: 12px;\n}\n\n.format-section-collapsible[_ngcontent-%COMP%] summary[_ngcontent-%COMP%] span[_ngcontent-%COMP%] {\n flex: 1;\n}\n\n.format-section-content[_ngcontent-%COMP%] {\n padding: 14px;\n background: white;\n border-top: 1px solid #e0e0e0;\n}\n\n\n\n.format-actions[_ngcontent-%COMP%] {\n margin-top: 20px;\n padding-top: 16px;\n border-top: 1px solid #e0e0e0;\n}\n\n.clear-format-btn[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 8px;\n width: 100%;\n padding: 10px 16px;\n border: 1px solid #e0e0e0;\n background: white;\n border-radius: 6px;\n color: #666;\n font-size: 14px;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.15s ease;\n}\n\n.clear-format-btn[_ngcontent-%COMP%]:hover {\n background: #fff5f5;\n border-color: #f87171;\n color: #dc2626;\n}\n\n.clear-format-btn[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 12px;\n}\n\n\n\n\n\n\n.aggregates-section[_ngcontent-%COMP%] {\n padding-top: 0;\n}\n\n.aggregates-header[_ngcontent-%COMP%] {\n margin-bottom: 16px;\n}\n\n.aggregates-description[_ngcontent-%COMP%] {\n font-size: 13px;\n color: #666;\n line-height: 1.5;\n margin: 0;\n}\n\n\n\n.add-aggregate-btn[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 12px 16px;\n border: 1px dashed #ccc;\n border-radius: 8px;\n background: transparent;\n color: #666;\n font-size: 14px;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.15s ease;\n width: 100%;\n justify-content: center;\n margin-bottom: 16px;\n}\n\n.add-aggregate-btn[_ngcontent-%COMP%]:hover:not(:disabled) {\n border-color: #1976d2;\n background: #e3f2fd;\n color: #1976d2;\n}\n\n.add-aggregate-btn[_ngcontent-%COMP%]:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.add-aggregate-btn[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 12px;\n}\n\n\n\n.aggregates-list[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 8px;\n margin-bottom: 16px;\n}\n\n\n\n.aggregate-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 12px 14px;\n background: white;\n border: 1px solid #e0e0e0;\n border-radius: 8px;\n transition: all 0.15s ease;\n}\n\n.aggregate-item[_ngcontent-%COMP%]:hover {\n border-color: #bdbdbd;\n background: #fafafa;\n}\n\n.aggregate-item.disabled[_ngcontent-%COMP%] {\n opacity: 0.6;\n background: #f5f5f5;\n}\n\n\n\n.agg-icon[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 36px;\n height: 36px;\n background: linear-gradient(135deg, #e3f2fd 0%, #bbdefb 100%);\n border-radius: 8px;\n color: #1976d2;\n font-size: 14px;\n flex-shrink: 0;\n}\n\n.aggregate-item.disabled[_ngcontent-%COMP%] .agg-icon[_ngcontent-%COMP%] {\n background: #f0f0f0;\n color: #999;\n}\n\n\n\n.agg-content[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n}\n\n.agg-label[_ngcontent-%COMP%] {\n font-size: 14px;\n font-weight: 500;\n color: #333;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n margin-bottom: 2px;\n}\n\n.aggregate-item.disabled[_ngcontent-%COMP%] .agg-label[_ngcontent-%COMP%] {\n color: #888;\n}\n\n.agg-details[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n font-size: 12px;\n color: #888;\n}\n\n.agg-type[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 4px;\n}\n\n.agg-type[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 10px;\n}\n\n.agg-smart-badge[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n padding: 2px 6px;\n background: linear-gradient(135deg, #eff6ff 0%, #dbeafe 100%);\n border-radius: 4px;\n color: #3b82f6;\n font-size: 10px;\n}\n\n\n\n.agg-actions[_ngcontent-%COMP%] {\n display: flex;\n gap: 4px;\n flex-shrink: 0;\n}\n\n.agg-action-btn[_ngcontent-%COMP%] {\n width: 28px;\n height: 28px;\n border: none;\n background: transparent;\n border-radius: 4px;\n cursor: pointer;\n color: #999;\n transition: all 0.15s ease;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.agg-action-btn[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: #e0e0e0;\n color: #333;\n}\n\n.agg-action-btn[_ngcontent-%COMP%]:disabled {\n opacity: 0.3;\n cursor: not-allowed;\n}\n\n.agg-action-btn.toggle-btn.enabled[_ngcontent-%COMP%] {\n color: #2e7d32;\n}\n\n.agg-action-btn.toggle-btn[_ngcontent-%COMP%]:not(.enabled) {\n color: #bdbdbd;\n}\n\n.agg-action-btn.edit-btn[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: #e3f2fd;\n color: #1976d2;\n}\n\n.agg-action-btn.remove-btn[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: #ffebee;\n color: #c62828;\n}\n\n\n\n.aggregates-summary[_ngcontent-%COMP%] {\n display: flex;\n gap: 16px;\n padding: 12px 14px;\n background: #f5f7fa;\n border-radius: 6px;\n margin-bottom: 16px;\n}\n\n.summary-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n font-size: 12px;\n color: #666;\n}\n\n.summary-item[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: #1976d2;\n font-size: 11px;\n}\n\n\n\n.aggregates-empty-state[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n gap: 8px;\n padding: 40px 20px;\n color: #999;\n font-size: 14px;\n text-align: center;\n}\n\n.aggregates-empty-state[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 48px;\n opacity: 0.4;\n margin-bottom: 8px;\n}\n\n.empty-hint[_ngcontent-%COMP%] {\n font-size: 12px;\n color: #bbb;\n margin: 0;\n}\n\n\n\n.aggregates-tip[_ngcontent-%COMP%] {\n display: flex;\n align-items: flex-start;\n gap: 10px;\n padding: 12px 14px;\n background: #f8fafc;\n border: 1px solid #e2e8f0;\n border-radius: 8px;\n font-size: 12px;\n color: #64748b;\n line-height: 1.5;\n}\n\n.aggregates-tip[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: #94a3b8;\n margin-top: 1px;\n flex-shrink: 0;\n}\n\n\n\n@media (max-width: 768px) {\n .config-panel[_ngcontent-%COMP%] {\n width: 100% !important;\n max-width: 100vw !important;\n }\n\n \n\n .resize-handle[_ngcontent-%COMP%] {\n display: none;\n }\n\n .tab-btn[_ngcontent-%COMP%] span[_ngcontent-%COMP%] {\n display: none;\n }\n\n .tab-btn[_ngcontent-%COMP%] {\n padding: 14px;\n }\n\n .tab-btn[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 16px;\n }\n\n .format-type-grid[_ngcontent-%COMP%] {\n grid-template-columns: repeat(3, 1fr);\n }\n}\n\n\n\n@media (min-width: 769px) and (max-width: 1200px) {\n .config-panel[_ngcontent-%COMP%] {\n max-width: min(600px, 80vw);\n }\n}\n\n\n\n.form-input.invalid[_ngcontent-%COMP%] {\n border-color: #ef4444;\n}\n\n.validation-error[_ngcontent-%COMP%] {\n display: block;\n font-size: 12px;\n color: #ef4444;\n margin-top: 4px;\n}\n\n.validation-banner[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 10px 16px;\n background: #fef2f2;\n border-top: 1px solid #fecaca;\n color: #dc2626;\n font-size: 13px;\n}\n\n.validation-banner[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n flex-shrink: 0;\n}\n\n\n\n.footer-btn.duplicate-btn[_ngcontent-%COMP%] {\n background: #f3f4f6;\n color: #374151;\n border: 1px solid #d1d5db;\n}\n\n.footer-btn.duplicate-btn[_ngcontent-%COMP%]:hover {\n background: #e5e7eb;\n border-color: #9ca3af;\n}"] });
|
|
2853
|
+
} }, dependencies: [i1.NgSelectOption, i1.ɵNgSelectMultipleOption, i1.DefaultValueAccessor, i1.NumberValueAccessor, i1.CheckboxControlValueAccessor, i1.SelectControlValueAccessor, i1.NgControlStatus, i1.MinValidator, i1.MaxValidator, i1.NgModel, i2.AggregateSetupDialogComponent, i3.ConfirmDialogComponent], styles: ["\n\n.panel-backdrop[_ngcontent-%COMP%] {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: rgba(0, 0, 0, 0.3);\n z-index: 1000;\n animation: _ngcontent-%COMP%_fadeIn 0.2s ease;\n}\n\n@keyframes _ngcontent-%COMP%_fadeIn {\n from { opacity: 0; }\n to { opacity: 1; }\n}\n\n\n\n.config-panel[_ngcontent-%COMP%] {\n position: fixed;\n top: 0;\n right: 0;\n width: 450px;\n min-width: 360px;\n max-width: min(800px, 100vw);\n height: 100%;\n background: var(--mj-bg-surface);\n box-shadow: -4px 0 24px rgba(0, 0, 0, 0.15);\n z-index: 1001;\n display: flex;\n flex-direction: column;\n transform: translateX(100%);\n transition: transform 0.25s ease, width 0s;\n}\n\n.config-panel.open[_ngcontent-%COMP%] {\n transform: translateX(0);\n}\n\n.config-panel.resizing[_ngcontent-%COMP%] {\n transition: none;\n user-select: none;\n}\n\n\n\n.resize-handle[_ngcontent-%COMP%] {\n position: absolute;\n left: 0;\n top: 0;\n bottom: 0;\n width: 6px;\n cursor: ew-resize;\n z-index: 10;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.resize-handle[_ngcontent-%COMP%]:hover, \n.config-panel.resizing[_ngcontent-%COMP%] .resize-handle[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, transparent);\n}\n\n.resize-grip[_ngcontent-%COMP%] {\n width: 3px;\n height: 40px;\n background: var(--mj-border-strong);\n border-radius: 3px;\n opacity: 0;\n transition: opacity 0.2s ease;\n}\n\n.resize-handle[_ngcontent-%COMP%]:hover .resize-grip[_ngcontent-%COMP%], \n.config-panel.resizing[_ngcontent-%COMP%] .resize-grip[_ngcontent-%COMP%] {\n opacity: 1;\n background: var(--mj-brand-primary);\n}\n\n\n\n.panel-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 16px 20px;\n border-bottom: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface-card);\n flex-shrink: 0;\n}\n\n.header-title[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 10px;\n font-size: 16px;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.header-title[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n}\n\n.close-btn[_ngcontent-%COMP%] {\n width: 32px;\n height: 32px;\n border: none;\n background: transparent;\n border-radius: 8px;\n cursor: pointer;\n color: var(--mj-text-muted);\n transition: all 0.15s ease;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.close-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-hover);\n color: var(--mj-text-primary);\n}\n\n\n\n.tab-nav[_ngcontent-%COMP%] {\n display: flex;\n border-bottom: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface-card);\n flex-shrink: 0;\n overflow-x: auto;\n -webkit-overflow-scrolling: touch;\n}\n\n.tab-btn[_ngcontent-%COMP%] {\n flex: 1;\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 8px;\n padding: 12px 16px;\n border: none;\n background: transparent;\n cursor: pointer;\n color: var(--mj-text-muted);\n font-size: 13px;\n font-weight: 500;\n transition: all 0.15s ease;\n position: relative;\n white-space: nowrap;\n}\n\n.tab-btn[_ngcontent-%COMP%]:hover {\n color: var(--mj-text-secondary);\n background: var(--mj-bg-surface-hover);\n}\n\n.tab-btn.active[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n font-weight: 600;\n}\n\n.tab-btn.active[_ngcontent-%COMP%]::after {\n content: '';\n position: absolute;\n bottom: 0;\n left: 8px;\n right: 8px;\n height: 2px;\n background: var(--mj-brand-primary);\n border-radius: 2px 2px 0 0;\n}\n\n.tab-btn[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 14px;\n}\n\n.tab-badge[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n min-width: 18px;\n height: 18px;\n padding: 0 5px;\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n border-radius: 9px;\n font-size: 11px;\n font-weight: 600;\n}\n\n\n\n.tab-nav.icon-only[_ngcontent-%COMP%] .tab-btn[_ngcontent-%COMP%] {\n padding: 12px 8px;\n}\n\n\n\n.panel-content[_ngcontent-%COMP%] {\n flex: 1;\n overflow-y: auto;\n overflow-x: hidden;\n}\n\n.tab-content[_ngcontent-%COMP%] {\n padding: 16px;\n}\n\n\n\n.config-section[_ngcontent-%COMP%] {\n margin-bottom: 20px;\n}\n\n.section-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 10px 0;\n margin-bottom: 8px;\n font-size: 13px;\n font-weight: 600;\n color: var(--mj-text-secondary);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.section-header[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-text-muted);\n font-size: 14px;\n}\n\n.column-count[_ngcontent-%COMP%] {\n margin-left: auto;\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-muted);\n padding: 2px 8px;\n border-radius: 10px;\n font-size: 12px;\n font-weight: 500;\n}\n\n\n\n.column-search[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px 12px;\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n margin-bottom: 8px;\n}\n\n.column-search[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-text-disabled);\n font-size: 12px;\n}\n\n.column-search[_ngcontent-%COMP%] input[_ngcontent-%COMP%] {\n flex: 1;\n border: none;\n outline: none;\n font-size: 13px;\n background: transparent;\n color: var(--mj-text-primary);\n}\n\n.column-search[_ngcontent-%COMP%] input[_ngcontent-%COMP%]::placeholder {\n color: var(--mj-text-disabled);\n}\n\n\n\n.column-list[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 2px;\n}\n\n\n\n.column-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px 10px;\n border-radius: 8px;\n transition: background 0.15s ease;\n cursor: default;\n}\n\n.column-item[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-card);\n}\n\n.column-item.hidden[_ngcontent-%COMP%] {\n opacity: 0.7;\n}\n\n.column-item.hidden[_ngcontent-%COMP%]:hover {\n opacity: 1;\n}\n\n.column-item.dragging[_ngcontent-%COMP%] {\n opacity: 0.4;\n}\n\n.column-item.drop-target[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 8%, var(--mj-bg-surface));\n}\n\n\n\n.drop-indicator[_ngcontent-%COMP%] {\n height: 2px;\n background: var(--mj-brand-primary);\n border-radius: 1px;\n margin: 0 10px;\n}\n\n\n\n.drag-handle[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n cursor: grab;\n color: var(--mj-text-disabled);\n font-size: 12px;\n padding: 4px 2px;\n}\n\n.drag-handle[_ngcontent-%COMP%]:active {\n cursor: grabbing;\n}\n\n.column-item[_ngcontent-%COMP%]:hover .drag-handle[_ngcontent-%COMP%] {\n color: var(--mj-text-muted);\n}\n\n\n\n.column-name[_ngcontent-%COMP%] {\n flex: 1;\n font-size: 13px;\n color: var(--mj-text-primary);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.alias-indicator[_ngcontent-%COMP%] {\n font-size: 10px;\n color: var(--mj-brand-primary);\n margin-left: 4px;\n}\n\n.format-indicator[_ngcontent-%COMP%] {\n font-size: 10px;\n color: var(--mj-status-warning);\n margin-left: 4px;\n}\n\n\n\n.column-actions[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 2px;\n opacity: 0;\n transition: opacity 0.15s ease;\n}\n\n.column-item[_ngcontent-%COMP%]:hover .column-actions[_ngcontent-%COMP%] {\n opacity: 1;\n}\n\n.action-btn[_ngcontent-%COMP%] {\n width: 26px;\n height: 26px;\n border: none;\n background: transparent;\n border-radius: 6px;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n color: var(--mj-text-muted);\n transition: all 0.15s ease;\n}\n\n.action-btn[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-secondary);\n}\n\n.action-btn[_ngcontent-%COMP%]:disabled {\n opacity: 0.3;\n cursor: not-allowed;\n}\n\n.action-btn.hide-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-status-error-bg);\n color: var(--mj-status-error);\n}\n\n.action-btn.show-btn[_ngcontent-%COMP%] {\n opacity: 0;\n}\n\n.column-item[_ngcontent-%COMP%]:hover .action-btn.show-btn[_ngcontent-%COMP%] {\n opacity: 1;\n}\n\n.action-btn.show-btn[_ngcontent-%COMP%]:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n}\n\n.action-btn.format-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-status-warning-bg);\n color: var(--mj-status-warning);\n}\n\n.action-btn[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 12px;\n}\n\n\n\n.empty-list[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 16px;\n color: var(--mj-text-muted);\n font-size: 13px;\n}\n\n.empty-list[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-text-disabled);\n}\n\n\n\n.format-editor[_ngcontent-%COMP%] {\n padding: 0;\n}\n\n.format-editor-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 16px;\n border-bottom: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface-card);\n}\n\n.back-btn[_ngcontent-%COMP%] {\n width: 32px;\n height: 32px;\n border: none;\n background: var(--mj-bg-surface-sunken);\n border-radius: 8px;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n color: var(--mj-text-secondary);\n transition: all 0.15s ease;\n}\n\n.back-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-active);\n color: var(--mj-text-primary);\n}\n\n.format-editor-title[_ngcontent-%COMP%] {\n font-size: 14px;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n\n\n.format-section[_ngcontent-%COMP%] {\n padding: 16px;\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.format-section-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n margin-bottom: 12px;\n font-size: 13px;\n font-weight: 600;\n color: var(--mj-text-secondary);\n}\n\n.format-section-header[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-text-muted);\n}\n\n\n\n.format-row[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 8px 0;\n}\n\n.format-row[_ngcontent-%COMP%] label[_ngcontent-%COMP%] {\n font-size: 13px;\n color: var(--mj-text-secondary);\n}\n\n.format-row.alias-info[_ngcontent-%COMP%] {\n padding: 4px 0;\n}\n\n.muted-text[_ngcontent-%COMP%] {\n font-size: 12px;\n color: var(--mj-text-muted);\n}\n\n.clear-alias-btn[_ngcontent-%COMP%] {\n width: 24px;\n height: 24px;\n border: none;\n background: transparent;\n border-radius: 4px;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n color: var(--mj-text-disabled);\n transition: all 0.15s ease;\n}\n\n.clear-alias-btn[_ngcontent-%COMP%]:hover {\n color: var(--mj-status-error);\n}\n\n\n\n.format-input[_ngcontent-%COMP%] {\n padding: 6px 10px;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n font-size: 13px;\n color: var(--mj-text-primary);\n background: var(--mj-bg-surface);\n transition: border-color 0.15s ease;\n}\n\n.format-input[_ngcontent-%COMP%]:focus {\n outline: none;\n border-color: var(--mj-brand-primary);\n}\n\n.format-input.small[_ngcontent-%COMP%] {\n width: 60px;\n text-align: center;\n}\n\n.format-select[_ngcontent-%COMP%] {\n padding: 6px 10px;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n font-size: 13px;\n color: var(--mj-text-primary);\n background: var(--mj-bg-surface);\n cursor: pointer;\n}\n\n.format-select[_ngcontent-%COMP%]:focus {\n outline: none;\n border-color: var(--mj-brand-primary);\n}\n\n\n\n.color-input[_ngcontent-%COMP%] {\n width: 36px;\n height: 28px;\n padding: 2px;\n border: 1px solid var(--mj-border-default);\n border-radius: 4px;\n cursor: pointer;\n background: var(--mj-bg-surface);\n}\n\n\n\n.alignment-toggle[_ngcontent-%COMP%] {\n display: flex;\n gap: 4px;\n background: var(--mj-bg-surface-card);\n border-radius: 8px;\n padding: 3px;\n border: 1px solid var(--mj-border-default);\n}\n\n.align-btn[_ngcontent-%COMP%] {\n flex: 1;\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 6px;\n border: none;\n background: transparent;\n border-radius: 6px;\n cursor: pointer;\n color: var(--mj-text-muted);\n transition: all 0.15s ease;\n}\n\n.align-btn[_ngcontent-%COMP%]:hover {\n color: var(--mj-text-secondary);\n}\n\n.align-btn.active[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface);\n color: var(--mj-brand-primary);\n box-shadow: 0 1px 2px rgba(0, 0, 0, 0.08);\n}\n\n\n\n.style-buttons[_ngcontent-%COMP%] {\n display: flex;\n gap: 4px;\n margin-bottom: 12px;\n}\n\n.style-btn[_ngcontent-%COMP%] {\n width: 32px;\n height: 32px;\n border: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface);\n border-radius: 6px;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n color: var(--mj-text-muted);\n transition: all 0.15s ease;\n}\n\n.style-btn[_ngcontent-%COMP%]:hover {\n border-color: var(--mj-border-strong);\n color: var(--mj-text-secondary);\n}\n\n.style-btn.active[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n border-color: var(--mj-brand-primary);\n color: var(--mj-brand-primary);\n}\n\n\n\n.format-preview-section[_ngcontent-%COMP%] {\n padding: 16px;\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.preview-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n margin-bottom: 12px;\n font-size: 13px;\n font-weight: 600;\n color: var(--mj-text-secondary);\n}\n\n.preview-header[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-text-muted);\n}\n\n.preview-table[_ngcontent-%COMP%] {\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n overflow: hidden;\n}\n\n.preview-header-cell[_ngcontent-%COMP%] {\n padding: 8px 12px;\n font-size: 12px;\n font-weight: 600;\n color: var(--mj-text-secondary);\n background: var(--mj-bg-surface-card);\n border-bottom: 1px solid var(--mj-border-default);\n text-transform: uppercase;\n letter-spacing: 0.3px;\n}\n\n.preview-cell[_ngcontent-%COMP%] {\n padding: 8px 12px;\n font-size: 13px;\n color: var(--mj-text-primary);\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.preview-cell[_ngcontent-%COMP%]:last-child {\n border-bottom: none;\n}\n\n\n\n.format-actions[_ngcontent-%COMP%] {\n padding: 16px;\n}\n\n.clear-format-btn[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px 16px;\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n background: var(--mj-bg-surface);\n cursor: pointer;\n font-size: 13px;\n color: var(--mj-text-secondary);\n transition: all 0.15s ease;\n}\n\n.clear-format-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-status-error-bg);\n border-color: var(--mj-status-error);\n color: var(--mj-status-error);\n}\n\n\n\n.sorting-section[_ngcontent-%COMP%] {\n padding: 0;\n}\n\n.sorting-header[_ngcontent-%COMP%] {\n margin-bottom: 12px;\n}\n\n.sorting-description[_ngcontent-%COMP%], \n.aggregates-description[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 13px;\n color: var(--mj-text-muted);\n line-height: 1.5;\n}\n\n\n\n.add-sort-btn[_ngcontent-%COMP%], \n.add-aggregate-btn[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 10px 16px;\n width: 100%;\n border: 2px dashed var(--mj-border-default);\n border-radius: 10px;\n background: transparent;\n cursor: pointer;\n font-size: 13px;\n font-weight: 500;\n color: var(--mj-text-muted);\n transition: all 0.15s ease;\n margin-bottom: 12px;\n}\n\n.add-sort-btn[_ngcontent-%COMP%]:hover:not(:disabled), \n.add-aggregate-btn[_ngcontent-%COMP%]:hover:not(:disabled) {\n border-color: var(--mj-brand-primary);\n color: var(--mj-brand-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 5%, var(--mj-bg-surface));\n}\n\n.add-sort-btn[_ngcontent-%COMP%]:disabled, \n.add-aggregate-btn[_ngcontent-%COMP%]:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n\n\n.sort-items-list[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 6px;\n margin-bottom: 12px;\n}\n\n.sort-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px 10px;\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: 10px;\n transition: all 0.15s ease;\n}\n\n.sort-item[_ngcontent-%COMP%]:hover {\n border-color: var(--mj-border-strong);\n}\n\n.sort-item.dragging[_ngcontent-%COMP%] {\n opacity: 0.4;\n}\n\n.sort-item.drop-target[_ngcontent-%COMP%] {\n border-color: var(--mj-brand-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 5%, var(--mj-bg-surface));\n}\n\n\n\n.sort-drop-indicator[_ngcontent-%COMP%] {\n height: 2px;\n background: var(--mj-brand-primary);\n border-radius: 1px;\n margin: 0 10px;\n}\n\n\n\n.sort-priority-badge[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 22px;\n height: 22px;\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n border-radius: 6px;\n font-size: 11px;\n font-weight: 700;\n flex-shrink: 0;\n}\n\n\n\n.sort-drag-handle[_ngcontent-%COMP%] {\n cursor: grab;\n color: var(--mj-text-disabled);\n padding: 2px;\n font-size: 12px;\n}\n\n.sort-drag-handle[_ngcontent-%COMP%]:active {\n cursor: grabbing;\n}\n\n.sort-item[_ngcontent-%COMP%]:hover .sort-drag-handle[_ngcontent-%COMP%] {\n color: var(--mj-text-muted);\n}\n\n\n\n.sort-field-dropdown[_ngcontent-%COMP%] {\n flex: 1;\n padding: 6px 10px;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n font-size: 13px;\n color: var(--mj-text-primary);\n background: var(--mj-bg-surface);\n cursor: pointer;\n min-width: 0;\n}\n\n.sort-field-dropdown[_ngcontent-%COMP%]:focus {\n outline: none;\n border-color: var(--mj-brand-primary);\n}\n\n\n\n.sort-direction-toggle[_ngcontent-%COMP%] {\n display: flex;\n background: var(--mj-bg-surface-sunken);\n border-radius: 6px;\n padding: 2px;\n gap: 2px;\n}\n\n.direction-btn[_ngcontent-%COMP%] {\n width: 28px;\n height: 28px;\n border: none;\n background: transparent;\n border-radius: 5px;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n color: var(--mj-text-muted);\n font-size: 12px;\n transition: all 0.15s ease;\n}\n\n.direction-btn[_ngcontent-%COMP%]:hover:not(:disabled) {\n color: var(--mj-text-secondary);\n}\n\n.direction-btn.active[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface);\n color: var(--mj-brand-primary);\n box-shadow: 0 1px 2px rgba(0, 0, 0, 0.08);\n}\n\n.direction-btn[_ngcontent-%COMP%]:disabled {\n opacity: 0.3;\n cursor: not-allowed;\n}\n\n\n\n.sort-remove-btn[_ngcontent-%COMP%] {\n width: 28px;\n height: 28px;\n border: none;\n background: transparent;\n border-radius: 6px;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n color: var(--mj-text-disabled);\n font-size: 12px;\n transition: all 0.15s ease;\n}\n\n.sort-remove-btn[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: var(--mj-status-error-bg);\n color: var(--mj-status-error);\n}\n\n.sort-remove-btn[_ngcontent-%COMP%]:disabled {\n opacity: 0.3;\n cursor: not-allowed;\n}\n\n\n\n.sort-hint[_ngcontent-%COMP%] {\n display: flex;\n align-items: flex-start;\n gap: 8px;\n padding: 10px 12px;\n background: var(--mj-bg-surface-card);\n border-radius: 8px;\n font-size: 12px;\n color: var(--mj-text-muted);\n}\n\n.sort-hint[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-text-disabled);\n margin-top: 1px;\n}\n\n\n\n.sort-empty-state[_ngcontent-%COMP%], \n.aggregates-empty-state[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 8px;\n padding: 32px 16px;\n color: var(--mj-text-muted);\n text-align: center;\n}\n\n.sort-empty-state[_ngcontent-%COMP%] i[_ngcontent-%COMP%], \n.aggregates-empty-state[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 32px;\n opacity: 0.4;\n}\n\n.sort-empty-state[_ngcontent-%COMP%] span[_ngcontent-%COMP%], \n.aggregates-empty-state[_ngcontent-%COMP%] span[_ngcontent-%COMP%] {\n font-size: 14px;\n font-weight: 500;\n}\n\n.sort-empty-hint[_ngcontent-%COMP%], \n.empty-hint[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 13px;\n color: var(--mj-text-disabled);\n}\n\n\n\n.filter-mode-selector[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 8px;\n margin-bottom: 16px;\n}\n\n.filter-mode-btn[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 12px 14px;\n border: 2px solid var(--mj-border-default);\n border-radius: 10px;\n background: var(--mj-bg-surface);\n cursor: pointer;\n transition: all 0.15s ease;\n text-align: left;\n}\n\n.filter-mode-btn[_ngcontent-%COMP%]:hover:not(:disabled) {\n border-color: var(--mj-border-strong);\n}\n\n.filter-mode-btn.active[_ngcontent-%COMP%] {\n border-color: var(--mj-brand-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 5%, var(--mj-bg-surface));\n}\n\n.filter-mode-btn[_ngcontent-%COMP%]:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.mode-icon[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 36px;\n height: 36px;\n background: var(--mj-bg-surface-sunken);\n border-radius: 8px;\n font-size: 16px;\n color: var(--mj-text-muted);\n flex-shrink: 0;\n}\n\n.filter-mode-btn.active[_ngcontent-%COMP%] .mode-icon[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n}\n\n.mode-content[_ngcontent-%COMP%] {\n flex: 1;\n display: flex;\n flex-direction: column;\n gap: 2px;\n}\n\n.mode-title[_ngcontent-%COMP%] {\n font-size: 14px;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.mode-subtitle[_ngcontent-%COMP%] {\n font-size: 12px;\n color: var(--mj-text-muted);\n}\n\n.mode-check[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n font-size: 14px;\n}\n\n\n\n.smart-filter-section[_ngcontent-%COMP%] {\n padding: 0;\n}\n\n.smart-filter-input-container[_ngcontent-%COMP%] {\n display: flex;\n gap: 12px;\n padding: 12px;\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: 10px;\n margin-bottom: 12px;\n}\n\n.smart-filter-icon[_ngcontent-%COMP%] {\n display: flex;\n align-items: flex-start;\n padding-top: 4px;\n color: var(--mj-brand-primary);\n font-size: 16px;\n}\n\n.smart-filter-textarea[_ngcontent-%COMP%] {\n flex: 1;\n border: none;\n outline: none;\n resize: vertical;\n font-size: 14px;\n font-family: inherit;\n color: var(--mj-text-primary);\n background: transparent;\n min-height: 60px;\n}\n\n.smart-filter-textarea[_ngcontent-%COMP%]::placeholder {\n color: var(--mj-text-disabled);\n}\n\n.smart-filter-textarea[_ngcontent-%COMP%]:disabled {\n color: var(--mj-text-muted);\n}\n\n\n\n.smart-filter-explanation[_ngcontent-%COMP%] {\n display: flex;\n align-items: flex-start;\n gap: 8px;\n padding: 10px 12px;\n background: color-mix(in srgb, var(--mj-brand-primary) 8%, var(--mj-bg-surface));\n border: 1px solid color-mix(in srgb, var(--mj-brand-primary) 25%, var(--mj-bg-surface));\n border-radius: 8px;\n margin-bottom: 12px;\n font-size: 13px;\n color: var(--mj-brand-primary);\n}\n\n.smart-filter-explanation[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n margin-top: 2px;\n}\n\n\n\n.smart-filter-examples[_ngcontent-%COMP%] {\n margin-bottom: 12px;\n}\n\n.examples-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n margin-bottom: 8px;\n font-size: 12px;\n font-weight: 500;\n color: var(--mj-text-muted);\n}\n\n.examples-header[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-status-warning);\n}\n\n.example-chips[_ngcontent-%COMP%] {\n display: flex;\n flex-wrap: wrap;\n gap: 6px;\n}\n\n.example-chip[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 6px 12px;\n border: 1px solid var(--mj-border-default);\n border-radius: 20px;\n background: var(--mj-bg-surface);\n cursor: pointer;\n font-size: 12px;\n color: var(--mj-text-secondary);\n transition: all 0.15s ease;\n}\n\n.example-chip[_ngcontent-%COMP%]:hover:not(:disabled) {\n border-color: var(--mj-brand-primary);\n color: var(--mj-brand-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 5%, var(--mj-bg-surface));\n}\n\n.example-chip[_ngcontent-%COMP%]:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.example-chip[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 11px;\n}\n\n\n\n.smart-filter-tip[_ngcontent-%COMP%], \n.traditional-filter-tip[_ngcontent-%COMP%], \n.aggregates-tip[_ngcontent-%COMP%] {\n display: flex;\n align-items: flex-start;\n gap: 8px;\n padding: 10px 12px;\n background: var(--mj-bg-surface-card);\n border-radius: 8px;\n font-size: 12px;\n color: var(--mj-text-muted);\n margin-top: 12px;\n}\n\n.smart-filter-tip[_ngcontent-%COMP%] i[_ngcontent-%COMP%], \n.traditional-filter-tip[_ngcontent-%COMP%] i[_ngcontent-%COMP%], \n.aggregates-tip[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-text-disabled);\n margin-top: 1px;\n}\n\n\n\n.traditional-filter-section[_ngcontent-%COMP%] {\n padding: 0;\n}\n\n.filter-summary-container[_ngcontent-%COMP%] {\n margin-bottom: 12px;\n}\n\n.filter-summary[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 12px 14px;\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: 10px;\n}\n\n.summary-info[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.filter-badge[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n min-width: 22px;\n height: 22px;\n padding: 0 6px;\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n border-radius: 11px;\n font-size: 12px;\n font-weight: 600;\n}\n\n.summary-text[_ngcontent-%COMP%] {\n font-size: 13px;\n color: var(--mj-text-primary);\n font-weight: 500;\n}\n\n.summary-text.no-filters[_ngcontent-%COMP%] {\n color: var(--mj-text-muted);\n font-weight: 400;\n}\n\n.summary-actions[_ngcontent-%COMP%] {\n display: flex;\n gap: 8px;\n}\n\n.summary-btn[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 6px 12px;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n background: var(--mj-bg-surface);\n cursor: pointer;\n font-size: 12px;\n font-weight: 500;\n color: var(--mj-text-secondary);\n transition: all 0.15s ease;\n}\n\n.summary-btn[_ngcontent-%COMP%]:hover:not(:disabled) {\n border-color: var(--mj-border-strong);\n}\n\n.summary-btn[_ngcontent-%COMP%]:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.summary-btn.clear-btn[_ngcontent-%COMP%]:hover {\n border-color: var(--mj-status-error);\n color: var(--mj-status-error);\n}\n\n.summary-btn.primary[_ngcontent-%COMP%] {\n background: var(--mj-brand-primary);\n border-color: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n}\n\n.summary-btn.primary[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: var(--mj-brand-primary-hover);\n border-color: var(--mj-brand-primary-hover);\n}\n\n\n\n.aggregates-section[_ngcontent-%COMP%] {\n padding: 0;\n}\n\n.aggregates-header[_ngcontent-%COMP%] {\n margin-bottom: 12px;\n}\n\n\n\n.aggregates-list[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 6px;\n margin-bottom: 12px;\n}\n\n.aggregate-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 10px 12px;\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: 10px;\n transition: all 0.15s ease;\n}\n\n.aggregate-item[_ngcontent-%COMP%]:hover {\n border-color: var(--mj-border-strong);\n}\n\n.aggregate-item.disabled[_ngcontent-%COMP%] {\n opacity: 0.5;\n}\n\n\n\n.agg-icon[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 32px;\n height: 32px;\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n border-radius: 8px;\n color: var(--mj-brand-primary);\n font-size: 14px;\n flex-shrink: 0;\n}\n\n\n\n.agg-content[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n}\n\n.agg-label[_ngcontent-%COMP%] {\n font-size: 13px;\n font-weight: 500;\n color: var(--mj-text-primary);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.agg-details[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n margin-top: 2px;\n}\n\n.agg-type[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 4px;\n font-size: 11px;\n color: var(--mj-text-muted);\n}\n\n.agg-smart-badge[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n font-size: 11px;\n}\n\n\n\n.agg-actions[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 2px;\n opacity: 0;\n transition: opacity 0.15s ease;\n}\n\n.aggregate-item[_ngcontent-%COMP%]:hover .agg-actions[_ngcontent-%COMP%] {\n opacity: 1;\n}\n\n.agg-action-btn[_ngcontent-%COMP%] {\n width: 26px;\n height: 26px;\n border: none;\n background: transparent;\n border-radius: 6px;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n color: var(--mj-text-muted);\n font-size: 12px;\n transition: all 0.15s ease;\n}\n\n.agg-action-btn[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-secondary);\n}\n\n.agg-action-btn[_ngcontent-%COMP%]:disabled {\n opacity: 0.3;\n cursor: not-allowed;\n}\n\n.agg-action-btn.toggle-btn.enabled[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n}\n\n.agg-action-btn.remove-btn[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: var(--mj-status-error-bg);\n color: var(--mj-status-error);\n}\n\n.agg-action-btn.edit-btn[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n}\n\n\n\n.aggregates-summary[_ngcontent-%COMP%] {\n display: flex;\n gap: 16px;\n padding: 10px 12px;\n background: var(--mj-bg-surface-card);\n border-radius: 8px;\n margin-bottom: 12px;\n}\n\n.aggregates-summary[_ngcontent-%COMP%] .summary-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n font-size: 12px;\n color: var(--mj-text-muted);\n}\n\n.aggregates-summary[_ngcontent-%COMP%] .summary-item[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-text-disabled);\n}\n\n\n\n.form-group[_ngcontent-%COMP%] {\n margin-bottom: 16px;\n}\n\n.form-group[_ngcontent-%COMP%] label[_ngcontent-%COMP%] {\n display: block;\n margin-bottom: 6px;\n font-size: 13px;\n font-weight: 500;\n color: var(--mj-text-secondary);\n}\n\n.form-input[_ngcontent-%COMP%] {\n width: 100%;\n padding: 8px 12px;\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n font-size: 14px;\n color: var(--mj-text-primary);\n background: var(--mj-bg-surface);\n transition: border-color 0.15s ease;\n box-sizing: border-box;\n}\n\n.form-input[_ngcontent-%COMP%]:focus {\n outline: none;\n border-color: var(--mj-brand-primary);\n}\n\n.form-input.invalid[_ngcontent-%COMP%] {\n border-color: var(--mj-status-error);\n}\n\n.form-textarea[_ngcontent-%COMP%] {\n resize: vertical;\n min-height: 60px;\n font-family: inherit;\n}\n\n.validation-error[_ngcontent-%COMP%] {\n font-size: 12px;\n color: var(--mj-status-error);\n margin-top: 4px;\n}\n\n\n\n.checkbox-label[_ngcontent-%COMP%] {\n display: flex;\n align-items: flex-start;\n gap: 10px;\n cursor: pointer;\n}\n\n.checkbox-label[_ngcontent-%COMP%] input[type=\"checkbox\"][_ngcontent-%COMP%] {\n margin-top: 3px;\n flex-shrink: 0;\n}\n\n.checkbox-text[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 2px;\n}\n\n.checkbox-text[_ngcontent-%COMP%] strong[_ngcontent-%COMP%] {\n font-size: 13px;\n color: var(--mj-text-primary);\n}\n\n.checkbox-text[_ngcontent-%COMP%] small[_ngcontent-%COMP%] {\n font-size: 12px;\n color: var(--mj-text-muted);\n}\n\n\n\n.danger-zone[_ngcontent-%COMP%] .section-header[_ngcontent-%COMP%] {\n color: var(--mj-status-error);\n}\n\n.danger-zone[_ngcontent-%COMP%] .section-header[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-status-error);\n}\n\n.delete-btn[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 10px 16px;\n border: 1px solid var(--mj-status-error);\n border-radius: 8px;\n background: var(--mj-status-error-bg);\n cursor: pointer;\n font-size: 13px;\n font-weight: 500;\n color: var(--mj-status-error);\n transition: all 0.15s ease;\n}\n\n.delete-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-status-error);\n color: var(--mj-text-inverse);\n}\n\n\n\n.validation-banner[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 10px 16px;\n background: var(--mj-status-error-bg);\n border-top: 1px solid var(--mj-status-error);\n font-size: 13px;\n color: var(--mj-status-error);\n flex-shrink: 0;\n}\n\n\n\n.panel-footer[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 14px 20px;\n border-top: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface-card);\n flex-shrink: 0;\n}\n\n.footer-left[_ngcontent-%COMP%] {\n display: flex;\n gap: 8px;\n}\n\n.footer-btn[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 9px 18px;\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n background: var(--mj-bg-surface);\n cursor: pointer;\n font-size: 14px;\n font-weight: 500;\n color: var(--mj-text-secondary);\n transition: all 0.15s ease;\n}\n\n.footer-btn[_ngcontent-%COMP%]:hover:not(:disabled) {\n border-color: var(--mj-border-strong);\n}\n\n.footer-btn[_ngcontent-%COMP%]:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.footer-btn.primary[_ngcontent-%COMP%] {\n background: var(--mj-brand-primary);\n border-color: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n}\n\n.footer-btn.primary[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: var(--mj-brand-primary-hover);\n border-color: var(--mj-brand-primary-hover);\n}\n\n.footer-btn.cancel-btn[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface-card);\n}\n\n.footer-btn.cancel-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-active);\n}\n\n\n\n@media (max-width: 480px) {\n .config-panel[_ngcontent-%COMP%] {\n width: 100vw;\n min-width: auto;\n }\n\n .resize-handle[_ngcontent-%COMP%] {\n display: none;\n }\n}"] });
|
|
2854
2854
|
}
|
|
2855
2855
|
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(ViewConfigPanelComponent, [{
|
|
2856
2856
|
type: Component,
|
|
2857
|
-
args: [{ standalone: false, selector: 'mj-view-config-panel', template: "<!-- Backdrop -->\n@if (isOpen) {\n <div class=\"panel-backdrop\" (click)=\"onClose()\"></div>\n}\n\n<!-- Sliding Panel -->\n<div class=\"config-panel\"\n [class.open]=\"isOpen\"\n [class.resizing]=\"isResizing\"\n [style.width.px]=\"panelWidth\">\n <!-- Resize Handle -->\n <div class=\"resize-handle\"\n (mousedown)=\"onResizeStart($event)\"\n title=\"Drag to resize\">\n <div class=\"resize-grip\"></div>\n </div>\n\n <!-- Panel Header -->\n <div class=\"panel-header\">\n <div class=\"header-title\">\n <i class=\"fa-solid fa-sliders-h\"></i>\n <span>{{ viewEntity ? 'Edit View' : 'Configure View' }}</span>\n </div>\n <button class=\"close-btn\" (click)=\"onClose()\" title=\"Close\">\n <i class=\"fa-solid fa-times\"></i>\n </button>\n </div>\n\n <!-- Tab Navigation -->\n <div class=\"tab-nav\" [class.icon-only]=\"isIconOnlyMode\">\n <button\n class=\"tab-btn\"\n [class.active]=\"activeTab === 'columns'\"\n (click)=\"setActiveTab('columns')\"\n [title]=\"isIconOnlyMode ? 'Columns' : ''\">\n <i class=\"fa-solid fa-columns\"></i>\n @if (!isIconOnlyMode) {\n <span>Columns</span>\n }\n </button>\n <button\n class=\"tab-btn\"\n [class.active]=\"activeTab === 'sorting'\"\n (click)=\"setActiveTab('sorting')\"\n [title]=\"isIconOnlyMode ? 'Sorting' + (sortItems.length > 0 ? ' (' + sortItems.length + ')' : '') : ''\">\n <i class=\"fa-solid fa-arrow-up-wide-short\"></i>\n @if (!isIconOnlyMode) {\n <span>Sorting</span>\n }\n @if (sortItems.length > 0) {\n <span class=\"tab-badge\">{{ sortItems.length }}</span>\n }\n </button>\n <button\n class=\"tab-btn\"\n [class.active]=\"activeTab === 'filters'\"\n (click)=\"setActiveTab('filters')\"\n [title]=\"isIconOnlyMode ? 'Filters' : ''\">\n <i class=\"fa-solid fa-filter\"></i>\n @if (!isIconOnlyMode) {\n <span>Filters</span>\n }\n </button>\n <button\n class=\"tab-btn\"\n [class.active]=\"activeTab === 'aggregates'\"\n (click)=\"setActiveTab('aggregates')\"\n [title]=\"isIconOnlyMode ? 'Aggregates' + (enabledAggregatesCount > 0 ? ' (' + enabledAggregatesCount + ')' : '') : ''\">\n <i class=\"fa-solid fa-chart-simple\"></i>\n @if (!isIconOnlyMode) {\n <span>Aggregates</span>\n }\n @if (enabledAggregatesCount > 0) {\n <span class=\"tab-badge\">{{ enabledAggregatesCount }}</span>\n }\n </button>\n @if (viewEntity || DefaultSaveAsNew) {\n <button\n class=\"tab-btn\"\n [class.active]=\"activeTab === 'settings'\"\n (click)=\"setActiveTab('settings')\"\n [title]=\"isIconOnlyMode ? 'Settings' : ''\">\n <i class=\"fa-solid fa-cog\"></i>\n @if (!isIconOnlyMode) {\n <span>Settings</span>\n }\n </button>\n }\n </div>\n\n <!-- Panel Content -->\n <div class=\"panel-content\">\n <!-- Columns Tab -->\n @if (activeTab === 'columns' && !formatEditingColumn) {\n <div class=\"tab-content\">\n <!-- Visible Columns -->\n <div class=\"config-section\">\n <div class=\"section-header\">\n <i class=\"fa-solid fa-eye\"></i>\n <span>Visible Columns</span>\n <span class=\"column-count\">{{ visibleColumns.length }}</span>\n </div>\n <div class=\"column-list visible-columns\">\n @for (column of visibleColumns; track column.fieldId; let i = $index) {\n <!-- Drop indicator before -->\n @if (isDropBefore(column)) {\n <div class=\"drop-indicator\"></div>\n }\n <div\n class=\"column-item\"\n [class.dragging]=\"draggedColumn === column\"\n [class.drop-target]=\"dropTargetColumn === column\"\n draggable=\"true\"\n (dragstart)=\"onDragStart($event, column)\"\n (dragover)=\"onDragOver($event, column)\"\n (dragleave)=\"onDragLeave($event)\"\n (drop)=\"onDrop($event, column)\"\n (dragend)=\"onDragEnd($event)\">\n <div class=\"drag-handle\">\n <i class=\"fa-solid fa-grip-vertical\"></i>\n </div>\n <span class=\"column-name\">\n {{ column.userDisplayName || column.displayName }}\n @if (column.userDisplayName) {\n <i class=\"fa-solid fa-pen-nib alias-indicator\" title=\"Custom name: {{ column.userDisplayName }}\"></i>\n }\n @if (hasCustomFormat(column)) {\n <i class=\"fa-solid fa-paintbrush format-indicator\" title=\"Custom formatting applied\"></i>\n }\n </span>\n <div class=\"column-actions\">\n <button\n class=\"action-btn format-btn\"\n (click)=\"openFormatEditor(column)\"\n title=\"Format column\">\n <i class=\"fa-solid fa-paintbrush\"></i>\n </button>\n <button\n class=\"action-btn\"\n [disabled]=\"i === 0\"\n (click)=\"moveColumnUp(column)\"\n title=\"Move up\">\n <i class=\"fa-solid fa-chevron-up\"></i>\n </button>\n <button\n class=\"action-btn\"\n [disabled]=\"i === visibleColumns.length - 1\"\n (click)=\"moveColumnDown(column)\"\n title=\"Move down\">\n <i class=\"fa-solid fa-chevron-down\"></i>\n </button>\n <button\n class=\"action-btn hide-btn\"\n (click)=\"toggleColumnVisibility(column)\"\n title=\"Hide column\">\n <i class=\"fa-solid fa-eye-slash\"></i>\n </button>\n </div>\n </div>\n <!-- Drop indicator after (only for last item) -->\n @if (isDropAfter(column) && i === visibleColumns.length - 1) {\n <div class=\"drop-indicator\"></div>\n }\n }\n @if (visibleColumns.length === 0) {\n <div class=\"empty-list\">\n <i class=\"fa-solid fa-info-circle\"></i>\n <span>No columns visible. Add columns from below.</span>\n </div>\n }\n </div>\n </div>\n\n <!-- Hidden Columns -->\n <div class=\"config-section\">\n <div class=\"section-header\">\n <i class=\"fa-solid fa-eye-slash\"></i>\n <span>Hidden Columns</span>\n <span class=\"column-count\">{{ hiddenColumns.length }}</span>\n </div>\n @if (hiddenColumns.length > 5) {\n <div class=\"column-search\">\n <i class=\"fa-solid fa-search\"></i>\n <input\n type=\"text\"\n placeholder=\"Search columns...\"\n [(ngModel)]=\"columnSearchText\"\n />\n </div>\n }\n <div class=\"column-list hidden-columns\">\n @for (column of filteredHiddenColumns; track column.fieldId) {\n <div class=\"column-item hidden\">\n <span class=\"column-name\">{{ column.displayName }}</span>\n <button\n class=\"action-btn show-btn\"\n (click)=\"toggleColumnVisibility(column)\"\n title=\"Show column\">\n <i class=\"fa-solid fa-plus\"></i>\n </button>\n </div>\n }\n @if (hiddenColumns.length === 0) {\n <div class=\"empty-list\">\n <i class=\"fa-solid fa-check-circle\"></i>\n <span>All columns are visible</span>\n </div>\n }\n </div>\n </div>\n </div>\n }\n\n <!-- Column Format Editor Sub-Panel -->\n @if (activeTab === 'columns' && formatEditingColumn) {\n <div class=\"format-editor\">\n <!-- Format Editor Header -->\n <div class=\"format-editor-header\">\n <button class=\"back-btn\" (click)=\"closeFormatEditor()\">\n <i class=\"fa-solid fa-arrow-left\"></i>\n </button>\n <div class=\"format-editor-title\">\n <span>Format: {{ formatEditingColumn.userDisplayName || formatEditingColumn.displayName }}</span>\n </div>\n </div>\n\n <!-- Column Alias Section -->\n <div class=\"format-section\">\n <div class=\"format-section-header\">\n <i class=\"fa-solid fa-pen-nib\"></i>\n <span>Column Name</span>\n </div>\n <div class=\"format-row\">\n <label>Display As</label>\n <input type=\"text\" class=\"format-input\"\n [value]=\"formatEditingColumn.userDisplayName || ''\"\n (input)=\"updateUserDisplayName($any($event.target).value)\"\n [placeholder]=\"formatEditingColumn.displayName\" />\n </div>\n @if (formatEditingColumn.userDisplayName) {\n <div class=\"format-row alias-info\">\n <small class=\"muted-text\">Original: {{ formatEditingColumn.displayName }}</small>\n <button class=\"clear-alias-btn\" (click)=\"formatEditingColumn.userDisplayName = undefined\" title=\"Clear alias\">\n <i class=\"fa-solid fa-times\"></i>\n </button>\n </div>\n }\n </div>\n\n <!-- Preview Section -->\n <div class=\"format-preview-section\">\n <div class=\"preview-header\">\n <i class=\"fa-solid fa-eye\"></i>\n <span>Preview</span>\n </div>\n <div class=\"preview-table\">\n <div class=\"preview-header-cell\"\n [style.font-weight]=\"formatEditingColumn.format?.headerStyle?.bold ? 'bold' : 'normal'\"\n [style.font-style]=\"formatEditingColumn.format?.headerStyle?.italic ? 'italic' : 'normal'\"\n [style.text-decoration]=\"formatEditingColumn.format?.headerStyle?.underline ? 'underline' : 'none'\"\n [style.color]=\"formatEditingColumn.format?.headerStyle?.color\"\n [style.background-color]=\"formatEditingColumn.format?.headerStyle?.backgroundColor\">\n {{ formatEditingColumn.userDisplayName || formatEditingColumn.displayName }}\n </div>\n @for (value of getSampleValues(formatEditingColumn); track $index) {\n <div class=\"preview-cell\"\n [style.text-align]=\"formatEditingColumn.format?.align || 'left'\"\n [style.font-weight]=\"formatEditingColumn.format?.cellStyle?.bold ? 'bold' : 'normal'\"\n [style.font-style]=\"formatEditingColumn.format?.cellStyle?.italic ? 'italic' : 'normal'\"\n [style.text-decoration]=\"formatEditingColumn.format?.cellStyle?.underline ? 'underline' : 'none'\"\n [style.color]=\"formatEditingColumn.format?.cellStyle?.color\"\n [style.background-color]=\"formatEditingColumn.format?.cellStyle?.backgroundColor\">\n {{ formatPreviewValue(value, formatEditingColumn.format) }}\n </div>\n }\n </div>\n </div>\n\n <!-- Format Type -->\n <div class=\"format-section\">\n <div class=\"format-section-header\">\n <i class=\"fa-solid fa-hashtag\"></i>\n <span>Format Type</span>\n </div>\n <select class=\"format-select\" [(ngModel)]=\"formatEditingColumn.format!.type\">\n <option value=\"auto\">Auto (Smart Default)</option>\n <option value=\"text\">Text</option>\n <option value=\"number\">Number</option>\n <option value=\"currency\">Currency</option>\n <option value=\"percent\">Percent</option>\n <option value=\"date\">Date</option>\n <option value=\"datetime\">Date & Time</option>\n <option value=\"boolean\">Boolean</option>\n </select>\n </div>\n\n <!-- Type-Specific Options -->\n @if (formatEditingColumn.format?.type === 'number' || formatEditingColumn.format?.type === 'currency' || formatEditingColumn.format?.type === 'percent') {\n <div class=\"format-section\">\n <div class=\"format-section-header\">\n <i class=\"fa-solid fa-sliders\"></i>\n <span>Number Options</span>\n </div>\n <div class=\"format-row\">\n <label>Decimal Places</label>\n <input type=\"number\" class=\"format-input small\" min=\"0\" max=\"10\"\n [(ngModel)]=\"formatEditingColumn.format!.decimals\" />\n </div>\n @if (formatEditingColumn.format?.type === 'currency') {\n <div class=\"format-row\">\n <label>Currency</label>\n <select class=\"format-select\" [(ngModel)]=\"formatEditingColumn.format!.currencyCode\">\n <option value=\"USD\">USD ($)</option>\n <option value=\"EUR\">EUR (\u20AC)</option>\n <option value=\"GBP\">GBP (\u00A3)</option>\n <option value=\"JPY\">JPY (\u00A5)</option>\n <option value=\"CAD\">CAD ($)</option>\n <option value=\"AUD\">AUD ($)</option>\n </select>\n </div>\n }\n <div class=\"format-row\">\n <label>Thousands Separator</label>\n <input type=\"checkbox\" [(ngModel)]=\"formatEditingColumn.format!.thousandsSeparator\" />\n </div>\n </div>\n }\n\n @if (formatEditingColumn.format?.type === 'date' || formatEditingColumn.format?.type === 'datetime') {\n <div class=\"format-section\">\n <div class=\"format-section-header\">\n <i class=\"fa-solid fa-calendar\"></i>\n <span>Date Options</span>\n </div>\n <div class=\"format-row\">\n <label>Format</label>\n <select class=\"format-select\" [(ngModel)]=\"formatEditingColumn.format!.dateFormat\">\n <option value=\"short\">Short (1/15/25)</option>\n <option value=\"short-weekday\">Short + Day (Wed, 1/15/25)</option>\n <option value=\"medium\">Medium (Jan 15, 2025)</option>\n <option value=\"medium-weekday\">Medium + Day (Wed, Jan 15, 2025)</option>\n <option value=\"long\">Long (January 15, 2025)</option>\n <option value=\"long-weekday\">Long + Day (Wednesday, January 15, 2025)</option>\n </select>\n </div>\n </div>\n }\n\n @if (formatEditingColumn.format?.type === 'boolean') {\n <div class=\"format-section\">\n <div class=\"format-section-header\">\n <i class=\"fa-solid fa-toggle-on\"></i>\n <span>Boolean Options</span>\n </div>\n <div class=\"format-row\">\n <label>True Label</label>\n <input type=\"text\" class=\"format-input\" [(ngModel)]=\"formatEditingColumn.format!.trueLabel\" placeholder=\"Yes\" />\n </div>\n <div class=\"format-row\">\n <label>False Label</label>\n <input type=\"text\" class=\"format-input\" [(ngModel)]=\"formatEditingColumn.format!.falseLabel\" placeholder=\"No\" />\n </div>\n <div class=\"format-row\">\n <label>Display As</label>\n <select class=\"format-select\" [(ngModel)]=\"formatEditingColumn.format!.booleanDisplay\">\n <option value=\"text\">Text</option>\n <option value=\"checkbox\">Checkbox</option>\n <option value=\"icon\">Icon</option>\n </select>\n </div>\n </div>\n }\n\n <!-- Alignment -->\n <div class=\"format-section\">\n <div class=\"format-section-header\">\n <i class=\"fa-solid fa-align-left\"></i>\n <span>Alignment</span>\n </div>\n <div class=\"alignment-toggle\">\n <button class=\"align-btn\" [class.active]=\"formatEditingColumn.format?.align === 'left' || !formatEditingColumn.format?.align\"\n (click)=\"formatEditingColumn.format!.align = 'left'\" title=\"Left\">\n <i class=\"fa-solid fa-align-left\"></i>\n </button>\n <button class=\"align-btn\" [class.active]=\"formatEditingColumn.format?.align === 'center'\"\n (click)=\"formatEditingColumn.format!.align = 'center'\" title=\"Center\">\n <i class=\"fa-solid fa-align-center\"></i>\n </button>\n <button class=\"align-btn\" [class.active]=\"formatEditingColumn.format?.align === 'right'\"\n (click)=\"formatEditingColumn.format!.align = 'right'\" title=\"Right\">\n <i class=\"fa-solid fa-align-right\"></i>\n </button>\n </div>\n </div>\n\n <!-- Header Style -->\n <div class=\"format-section\">\n <div class=\"format-section-header\">\n <i class=\"fa-solid fa-heading\"></i>\n <span>Header Style</span>\n </div>\n <div class=\"style-buttons\">\n <button class=\"style-btn\" [class.active]=\"formatEditingColumn.format?.headerStyle?.bold\"\n (click)=\"toggleHeaderStyle('bold')\"\n title=\"Bold\">\n <i class=\"fa-solid fa-bold\"></i>\n </button>\n <button class=\"style-btn\" [class.active]=\"formatEditingColumn.format?.headerStyle?.italic\"\n (click)=\"toggleHeaderStyle('italic')\"\n title=\"Italic\">\n <i class=\"fa-solid fa-italic\"></i>\n </button>\n <button class=\"style-btn\" [class.active]=\"formatEditingColumn.format?.headerStyle?.underline\"\n (click)=\"toggleHeaderStyle('underline')\"\n title=\"Underline\">\n <i class=\"fa-solid fa-underline\"></i>\n </button>\n </div>\n <div class=\"format-row\">\n <label>Text Color</label>\n <input type=\"color\" class=\"color-input\"\n [value]=\"formatEditingColumn.format?.headerStyle?.color || '#000000'\"\n (input)=\"updateHeaderColor('color', $any($event.target).value)\" />\n </div>\n <div class=\"format-row\">\n <label>Background</label>\n <input type=\"color\" class=\"color-input\"\n [value]=\"formatEditingColumn.format?.headerStyle?.backgroundColor || '#ffffff'\"\n (input)=\"updateHeaderColor('backgroundColor', $any($event.target).value)\" />\n </div>\n </div>\n\n <!-- Cell Style -->\n <div class=\"format-section\">\n <div class=\"format-section-header\">\n <i class=\"fa-solid fa-table-cells\"></i>\n <span>Cell Style</span>\n </div>\n <div class=\"style-buttons\">\n <button class=\"style-btn\" [class.active]=\"formatEditingColumn.format?.cellStyle?.bold\"\n (click)=\"toggleCellStyle('bold')\"\n title=\"Bold\">\n <i class=\"fa-solid fa-bold\"></i>\n </button>\n <button class=\"style-btn\" [class.active]=\"formatEditingColumn.format?.cellStyle?.italic\"\n (click)=\"toggleCellStyle('italic')\"\n title=\"Italic\">\n <i class=\"fa-solid fa-italic\"></i>\n </button>\n <button class=\"style-btn\" [class.active]=\"formatEditingColumn.format?.cellStyle?.underline\"\n (click)=\"toggleCellStyle('underline')\"\n title=\"Underline\">\n <i class=\"fa-solid fa-underline\"></i>\n </button>\n </div>\n <div class=\"format-row\">\n <label>Text Color</label>\n <input type=\"color\" class=\"color-input\"\n [value]=\"formatEditingColumn.format?.cellStyle?.color || '#000000'\"\n (input)=\"updateCellColor('color', $any($event.target).value)\" />\n </div>\n <div class=\"format-row\">\n <label>Background</label>\n <input type=\"color\" class=\"color-input\"\n [value]=\"formatEditingColumn.format?.cellStyle?.backgroundColor || '#ffffff'\"\n (input)=\"updateCellColor('backgroundColor', $any($event.target).value)\" />\n </div>\n </div>\n\n <!-- Clear Format Button -->\n <div class=\"format-actions\">\n <button class=\"clear-format-btn\" (click)=\"clearColumnFormat(formatEditingColumn); closeFormatEditor()\">\n <i class=\"fa-solid fa-eraser\"></i>\n Clear Formatting\n </button>\n </div>\n </div>\n }\n\n <!-- Sorting Tab -->\n @if (activeTab === 'sorting') {\n <div class=\"tab-content\">\n <div class=\"config-section sorting-section\">\n <div class=\"sorting-header\">\n <p class=\"sorting-description\">\n Define how records should be ordered. Add multiple levels to sort by secondary fields when values are equal.\n </p>\n </div>\n\n <!-- Add Sort Button -->\n <button\n class=\"add-sort-btn\"\n (click)=\"addSortLevel()\"\n [disabled]=\"!canEdit || sortItems.length >= sortableFields.length\"\n title=\"Add another sort level\">\n <i class=\"fa-solid fa-plus\"></i>\n <span>Add Sort Level</span>\n </button>\n\n <!-- Sort Items List -->\n @if (sortItems.length > 0) {\n <div class=\"sort-items-list\">\n @for (sortItem of sortItems; track $index; let i = $index) {\n <!-- Drop indicator before -->\n @if (isSortDropBefore(sortItem)) {\n <div class=\"sort-drop-indicator\"></div>\n }\n <div\n class=\"sort-item\"\n [class.dragging]=\"draggedSortItem === sortItem\"\n [class.drop-target]=\"dropTargetSortItem === sortItem\"\n draggable=\"true\"\n (dragstart)=\"onSortDragStart($event, sortItem)\"\n (dragover)=\"onSortDragOver($event, sortItem)\"\n (dragleave)=\"onSortDragLeave($event)\"\n (drop)=\"onSortDrop($event, sortItem)\"\n (dragend)=\"onSortDragEnd($event)\">\n <!-- Priority Badge -->\n <div class=\"sort-priority-badge\">{{ i + 1 }}</div>\n <!-- Drag Handle -->\n <div class=\"sort-drag-handle\" title=\"Drag to reorder\">\n <i class=\"fa-solid fa-grip-vertical\"></i>\n </div>\n <!-- Field Dropdown -->\n <select\n class=\"sort-field-dropdown\"\n [(ngModel)]=\"sortItem.field\"\n (ngModelChange)=\"onSortFieldChange(sortItem, $event)\"\n [disabled]=\"!canEdit\">\n @for (field of sortableFields; track field.ID) {\n <option [value]=\"field.Name\">{{ field.DisplayNameOrName }}</option>\n }\n </select>\n <!-- Direction Toggle -->\n <div class=\"sort-direction-toggle\">\n <button\n class=\"direction-btn\"\n [class.active]=\"sortItem.direction === 'asc'\"\n (click)=\"onSortDirectionChange(sortItem, 'asc')\"\n [disabled]=\"!canEdit\"\n title=\"Ascending (A-Z, 1-9)\">\n <i class=\"fa-solid fa-arrow-up\"></i>\n </button>\n <button\n class=\"direction-btn\"\n [class.active]=\"sortItem.direction === 'desc'\"\n (click)=\"onSortDirectionChange(sortItem, 'desc')\"\n [disabled]=\"!canEdit\"\n title=\"Descending (Z-A, 9-1)\">\n <i class=\"fa-solid fa-arrow-down\"></i>\n </button>\n </div>\n <!-- Remove Button -->\n <button\n class=\"sort-remove-btn\"\n (click)=\"removeSortLevel(sortItem)\"\n [disabled]=\"!canEdit\"\n title=\"Remove sort level\">\n <i class=\"fa-solid fa-times\"></i>\n </button>\n </div>\n <!-- Drop indicator after (only for last item) -->\n @if (isSortDropAfter(sortItem) && i === sortItems.length - 1) {\n <div class=\"sort-drop-indicator\"></div>\n }\n }\n </div>\n <!-- Multi-sort hint -->\n @if (sortItems.length > 1) {\n <div class=\"sort-hint\">\n <i class=\"fa-solid fa-info-circle\"></i>\n <span>Drag items to change priority. Records sort by first level, then second, etc.</span>\n </div>\n }\n } @else {\n <div class=\"sort-empty-state\">\n <i class=\"fa-solid fa-arrow-up-wide-short\"></i>\n <span>No sorting configured</span>\n <p class=\"sort-empty-hint\">Click \"Add Sort Level\" to define how records should be ordered</p>\n </div>\n }\n </div>\n </div>\n }\n\n <!-- Filters Tab -->\n @if (activeTab === 'filters') {\n <div class=\"tab-content\">\n <!-- Filter Mode Selection -->\n <div class=\"filter-mode-selector\">\n <button\n class=\"filter-mode-btn\"\n [class.active]=\"filterMode === 'smart'\"\n (click)=\"setFilterMode('smart')\"\n [disabled]=\"!canEdit\">\n <div class=\"mode-icon\">\n <i class=\"fa-solid fa-wand-magic-sparkles\"></i>\n </div>\n <div class=\"mode-content\">\n <span class=\"mode-title\">Smart Filter</span>\n <span class=\"mode-subtitle\">Use AI to filter with natural language</span>\n </div>\n @if (filterMode === 'smart') {\n <i class=\"fa-solid fa-check mode-check\"></i>\n }\n </button>\n <button\n class=\"filter-mode-btn\"\n [class.active]=\"filterMode === 'traditional'\"\n (click)=\"setFilterMode('traditional')\"\n [disabled]=\"!canEdit\">\n <div class=\"mode-icon\">\n <i class=\"fa-solid fa-sliders\"></i>\n </div>\n <div class=\"mode-content\">\n <span class=\"mode-title\">Traditional Filter</span>\n <span class=\"mode-subtitle\">Build filters with field/operator/value</span>\n </div>\n @if (filterMode === 'traditional') {\n <i class=\"fa-solid fa-check mode-check\"></i>\n }\n </button>\n </div>\n\n <!-- Smart Filter Section -->\n @if (filterMode === 'smart') {\n <div class=\"config-section smart-filter-section\">\n <div class=\"smart-filter-input-container\">\n <div class=\"smart-filter-icon\">\n <i class=\"fa-solid fa-wand-magic-sparkles\"></i>\n </div>\n <textarea\n id=\"smartFilterPrompt\"\n class=\"smart-filter-textarea\"\n placeholder=\"Describe what you're looking for...\"\n [(ngModel)]=\"smartFilterPrompt\"\n [disabled]=\"!canEdit\"\n rows=\"3\"\n ></textarea>\n </div>\n\n @if (smartFilterExplanation) {\n <div class=\"smart-filter-explanation\">\n <i class=\"fa-solid fa-robot\"></i>\n <span>{{ smartFilterExplanation }}</span>\n </div>\n }\n\n <!-- Example Prompts -->\n <div class=\"smart-filter-examples\">\n <div class=\"examples-header\">\n <i class=\"fa-solid fa-lightbulb\"></i>\n <span>Try these examples:</span>\n </div>\n <div class=\"example-chips\">\n <button\n class=\"example-chip\"\n (click)=\"applySmartFilterExample('Show records created in the last 30 days')\"\n [disabled]=\"!canEdit\">\n <i class=\"fa-regular fa-calendar\"></i>\n Last 30 days\n </button>\n <button\n class=\"example-chip\"\n (click)=\"applySmartFilterExample('Active records only')\"\n [disabled]=\"!canEdit\">\n <i class=\"fa-solid fa-circle-check\"></i>\n Active only\n </button>\n <button\n class=\"example-chip\"\n (click)=\"applySmartFilterExample('Records with high priority')\"\n [disabled]=\"!canEdit\">\n <i class=\"fa-solid fa-star\"></i>\n High priority\n </button>\n <button\n class=\"example-chip\"\n (click)=\"applySmartFilterExample('Records modified this week')\"\n [disabled]=\"!canEdit\">\n <i class=\"fa-solid fa-clock-rotate-left\"></i>\n Modified this week\n </button>\n </div>\n </div>\n\n <div class=\"smart-filter-tip\">\n <i class=\"fa-solid fa-info-circle\"></i>\n <span>The AI will interpret your description and create the appropriate filter when you save the view.</span>\n </div>\n </div>\n }\n\n <!-- Traditional Filter Section -->\n @if (filterMode === 'traditional') {\n <div class=\"config-section traditional-filter-section\">\n <div class=\"filter-summary-container\">\n <div class=\"filter-summary\">\n <div class=\"summary-info\">\n @if (getFilterCount() > 0) {\n <span class=\"filter-badge\">{{ getFilterCount() }}</span>\n <span class=\"summary-text\">{{ getFilterSummary() }}</span>\n } @else {\n <span class=\"summary-text no-filters\">No filters configured</span>\n }\n </div>\n <div class=\"summary-actions\">\n @if (getFilterCount() > 0 && canEdit) {\n <button\n class=\"summary-btn clear-btn\"\n (click)=\"clearFilters()\"\n title=\"Clear all filters\">\n <i class=\"fa-solid fa-times\"></i>\n Clear\n </button>\n }\n <button\n class=\"summary-btn edit-btn primary\"\n (click)=\"openFilterDialog()\"\n [disabled]=\"!canEdit && getFilterCount() === 0\"\n title=\"Edit filters\">\n <i class=\"fa-solid fa-pen\"></i>\n {{ getFilterCount() > 0 ? 'Edit Filters' : 'Add Filters' }}\n </button>\n </div>\n </div>\n </div>\n\n <div class=\"traditional-filter-tip\">\n <i class=\"fa-solid fa-info-circle\"></i>\n <span>Build precise filters by selecting fields, operators, and values. Use groups for complex AND/OR logic.</span>\n </div>\n </div>\n }\n </div>\n }\n\n <!-- Aggregates Tab -->\n @if (activeTab === 'aggregates') {\n <div class=\"tab-content\">\n <div class=\"config-section aggregates-section\">\n <div class=\"aggregates-header\">\n <p class=\"aggregates-description\">\n Add summary calculations like totals, averages, and counts. Display them in cards or as column footers.\n </p>\n </div>\n\n <!-- Add Aggregate Button -->\n <button\n class=\"add-aggregate-btn\"\n (click)=\"openAddAggregateDialog()\"\n [disabled]=\"!canEdit\"\n title=\"Add a new aggregate\">\n <i class=\"fa-solid fa-plus\"></i>\n <span>Add Aggregate</span>\n </button>\n\n <!-- Aggregates List -->\n @if (aggregates.length > 0) {\n <div class=\"aggregates-list\">\n @for (agg of aggregates; track agg.id; let i = $index) {\n <div class=\"aggregate-item\" [class.disabled]=\"agg.enabled === false\">\n <!-- Icon -->\n <div class=\"agg-icon\">\n <i [class]=\"agg.icon || 'fa-solid fa-chart-simple'\"></i>\n </div>\n\n <!-- Content -->\n <div class=\"agg-content\">\n <div class=\"agg-label\">{{ agg.label }}</div>\n <div class=\"agg-details\">\n <span class=\"agg-type\">\n <i [class]=\"agg.displayType === 'card' ? 'fa-solid fa-id-card' : 'fa-solid fa-table-columns'\"></i>\n {{ agg.displayType === 'card' ? 'Card' : 'Column Footer' }}\n </span>\n @if (agg.smartPrompt) {\n <span class=\"agg-smart-badge\" title=\"AI-generated\">\n <i class=\"fa-solid fa-wand-magic-sparkles\"></i>\n </span>\n }\n </div>\n </div>\n\n <!-- Actions -->\n <div class=\"agg-actions\">\n <button\n class=\"agg-action-btn\"\n [disabled]=\"i === 0 || !canEdit\"\n (click)=\"moveAggregateUp(agg)\"\n title=\"Move up\">\n <i class=\"fa-solid fa-chevron-up\"></i>\n </button>\n <button\n class=\"agg-action-btn\"\n [disabled]=\"i === aggregates.length - 1 || !canEdit\"\n (click)=\"moveAggregateDown(agg)\"\n title=\"Move down\">\n <i class=\"fa-solid fa-chevron-down\"></i>\n </button>\n <button\n class=\"agg-action-btn toggle-btn\"\n [class.enabled]=\"agg.enabled !== false\"\n (click)=\"toggleAggregateEnabled(agg, $event)\"\n [disabled]=\"!canEdit\"\n [title]=\"agg.enabled !== false ? 'Disable' : 'Enable'\">\n <i [class]=\"agg.enabled !== false ? 'fa-solid fa-eye' : 'fa-solid fa-eye-slash'\"></i>\n </button>\n <button\n class=\"agg-action-btn edit-btn\"\n (click)=\"editAggregate(agg)\"\n [disabled]=\"!canEdit\"\n title=\"Edit\">\n <i class=\"fa-solid fa-pen\"></i>\n </button>\n <button\n class=\"agg-action-btn remove-btn\"\n (click)=\"removeAggregate(agg)\"\n [disabled]=\"!canEdit\"\n title=\"Remove\">\n <i class=\"fa-solid fa-trash\"></i>\n </button>\n </div>\n </div>\n }\n </div>\n\n <!-- Summary -->\n <div class=\"aggregates-summary\">\n <div class=\"summary-item\">\n <i class=\"fa-solid fa-id-card\"></i>\n <span>{{ cardAggregates.length }} card{{ cardAggregates.length !== 1 ? 's' : '' }}</span>\n </div>\n <div class=\"summary-item\">\n <i class=\"fa-solid fa-table-columns\"></i>\n <span>{{ columnAggregates.length }} column footer{{ columnAggregates.length !== 1 ? 's' : '' }}</span>\n </div>\n </div>\n } @else {\n <div class=\"aggregates-empty-state\">\n <i class=\"fa-solid fa-chart-simple\"></i>\n <span>No aggregates configured</span>\n <p class=\"empty-hint\">Click \"Add Aggregate\" to create summary calculations</p>\n </div>\n }\n\n <!-- Info Tip -->\n <div class=\"aggregates-tip\">\n <i class=\"fa-solid fa-info-circle\"></i>\n <span>Aggregates are calculated server-side for accuracy with filtered/paginated data.</span>\n </div>\n </div>\n </div>\n }\n\n <!-- Settings Tab -->\n @if (activeTab === 'settings') {\n <div class=\"tab-content\">\n <!-- View Name & Description -->\n <div class=\"config-section\">\n <div class=\"section-header\">\n <i class=\"fa-solid fa-info-circle\"></i>\n <span>View Details</span>\n </div>\n <div class=\"form-group\">\n <label for=\"viewName\">Name</label>\n <input\n id=\"viewName\"\n type=\"text\"\n class=\"form-input\"\n [class.invalid]=\"!viewName || !viewName.trim()\"\n placeholder=\"Enter view name...\"\n [(ngModel)]=\"viewName\"\n [disabled]=\"!canEdit\"\n />\n @if (!viewName || !viewName.trim()) {\n <span class=\"validation-error\">View name is required</span>\n }\n </div>\n <div class=\"form-group\">\n <label for=\"viewDescription\">Description</label>\n <textarea\n id=\"viewDescription\"\n class=\"form-input form-textarea\"\n placeholder=\"Describe this view...\"\n [(ngModel)]=\"viewDescription\"\n [disabled]=\"!canEdit\"\n rows=\"3\"\n ></textarea>\n </div>\n </div>\n\n <!-- Sharing -->\n <div class=\"config-section\">\n <div class=\"section-header\">\n <i class=\"fa-solid fa-share-alt\"></i>\n <span>Sharing</span>\n </div>\n <label class=\"checkbox-label\">\n <input\n type=\"checkbox\"\n [(ngModel)]=\"isShared\"\n [disabled]=\"!canEdit\"\n />\n <span class=\"checkbox-text\">\n <strong>Share with others</strong>\n <small>Allow other users to use this view</small>\n </span>\n </label>\n </div>\n\n <!-- Danger Zone -->\n @if (viewEntity && canDelete) {\n <div class=\"config-section danger-zone\">\n <div class=\"section-header\">\n <i class=\"fa-solid fa-exclamation-triangle\"></i>\n <span>Danger Zone</span>\n </div>\n <button class=\"delete-btn\" (click)=\"onDelete()\">\n <i class=\"fa-solid fa-trash\"></i>\n <span>Delete View</span>\n </button>\n </div>\n }\n </div>\n }\n </div>\n\n <!-- Validation Errors Banner -->\n @if (ValidationErrors.length > 0 && visibleColumns.length === 0) {\n <div class=\"validation-banner\">\n <i class=\"fa-solid fa-exclamation-triangle\"></i>\n <span>At least one column must be visible</span>\n </div>\n }\n\n <!-- Panel Footer -->\n <div class=\"panel-footer\">\n <!-- Action buttons on LEFT -->\n <div class=\"footer-left\">\n @if (viewEntity && canEdit) {\n <!-- Editing an existing saved view -->\n <button\n class=\"footer-btn save-btn primary\"\n (click)=\"onSave()\"\n [disabled]=\"isSaving || !IsValid\">\n @if (isSaving) {\n <i class=\"fa-solid fa-spinner fa-spin\"></i>\n } @else {\n <i class=\"fa-solid fa-save\"></i>\n }\n {{ isSaving ? 'Saving...' : 'Save' }}\n </button>\n }\n @if (!viewEntity && DefaultSaveAsNew) {\n <!-- Creating a new view (from quick save dialog) -->\n <button\n class=\"footer-btn save-btn primary\"\n (click)=\"onSaveAsNew()\"\n [disabled]=\"isSaving || !IsValidForSaveAsNew\">\n @if (isSaving) {\n <i class=\"fa-solid fa-spinner fa-spin\"></i>\n } @else {\n <i class=\"fa-solid fa-plus\"></i>\n }\n {{ isSaving ? 'Saving...' : 'Create View' }}\n </button>\n }\n @if (!viewEntity && !DefaultSaveAsNew) {\n <!-- Default/Dynamic view - Save to user settings -->\n <button\n class=\"footer-btn save-btn primary\"\n (click)=\"onSaveDefaults()\"\n [disabled]=\"isSaving\">\n @if (isSaving) {\n <i class=\"fa-solid fa-spinner fa-spin\"></i>\n } @else {\n <i class=\"fa-solid fa-save\"></i>\n }\n {{ isSaving ? 'Saving...' : 'Save' }}\n </button>\n }\n </div>\n <!-- Cancel button on RIGHT -->\n <button class=\"footer-btn cancel-btn\" (click)=\"onClose()\">\n Cancel\n </button>\n </div>\n</div>\n\n<!-- Aggregate Setup Dialog -->\n<mj-aggregate-setup-dialog\n [Entity]=\"entity\"\n [Aggregate]=\"editingAggregate\"\n [IsOpen]=\"showAggregateDialog\"\n (Close)=\"closeAggregateDialog()\"\n (Save)=\"onAggregateSave($event)\">\n</mj-aggregate-setup-dialog>\n\n<!-- Delete Confirmation Dialog -->\n<mj-ev-confirm-dialog\n [IsOpen]=\"showDeleteConfirm\"\n Title=\"Delete View\"\n [Message]=\"'Are you sure you want to delete \\'' + viewName + '\\'?'\"\n DetailMessage=\"This action cannot be undone. All users who have access to this view will lose it.\"\n ConfirmText=\"Delete\"\n ConfirmStyle=\"danger\"\n Icon=\"fa-solid fa-trash\"\n (Confirmed)=\"OnDeleteConfirmed()\"\n (Cancelled)=\"OnDeleteCancelled()\">\n</mj-ev-confirm-dialog>\n\n<!-- Filter Mode Switch Confirmation Dialog (BUG-006) -->\n<mj-ev-confirm-dialog\n [IsOpen]=\"showFilterModeSwitchConfirm\"\n Title=\"Switch Filter Mode\"\n [Message]=\"filterMode === 'smart' ? 'Switching to Traditional mode will clear your smart filter prompt.' : 'Switching to Smart mode will clear your traditional filter rules.'\"\n DetailMessage=\"You can switch back later, but the current filter data will be lost.\"\n ConfirmText=\"Switch\"\n ConfirmStyle=\"primary\"\n Icon=\"fa-solid fa-exchange-alt\"\n (Confirmed)=\"OnFilterModeSwitchConfirmed()\"\n (Cancelled)=\"OnFilterModeSwitchCancelled()\">\n</mj-ev-confirm-dialog>\n", styles: ["/* Backdrop */\n.panel-backdrop {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: rgba(0, 0, 0, 0.3);\n z-index: 1000;\n animation: fadeIn 0.2s ease;\n}\n\n@keyframes fadeIn {\n from { opacity: 0; }\n to { opacity: 1; }\n}\n\n/* Sliding Panel */\n.config-panel {\n position: fixed;\n top: 0;\n right: 0;\n width: 450px;\n min-width: 360px;\n max-width: min(800px, 100vw);\n height: 100%;\n background: white;\n box-shadow: -4px 0 24px rgba(0, 0, 0, 0.15);\n z-index: 1001;\n display: flex;\n flex-direction: column;\n transform: translateX(100%);\n transition: transform 0.25s ease, width 0s;\n}\n\n.config-panel.open {\n transform: translateX(0);\n}\n\n.config-panel.resizing {\n transition: none;\n user-select: none;\n}\n\n/* Resize Handle */\n.resize-handle {\n position: absolute;\n left: 0;\n top: 0;\n bottom: 0;\n width: 6px;\n cursor: ew-resize;\n z-index: 10;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.resize-handle:hover,\n.config-panel.resizing .resize-handle {\n background: linear-gradient(90deg, rgba(25, 118, 210, 0.1) 0%, transparent 100%);\n}\n\n.resize-grip {\n width: 3px;\n height: 40px;\n background: #cbd5e1;\n border-radius: 3px;\n opacity: 0;\n transition: opacity 0.2s ease;\n}\n\n.resize-handle:hover .resize-grip,\n.config-panel.resizing .resize-grip {\n opacity: 1;\n background: #1976d2;\n}\n\n/* Panel Header */\n.panel-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 16px 20px;\n border-bottom: 1px solid #e0e0e0;\n background: #fafafa;\n flex-shrink: 0;\n}\n\n.header-title {\n display: flex;\n align-items: center;\n gap: 10px;\n font-size: 16px;\n font-weight: 600;\n color: #333;\n}\n\n.header-title i {\n color: #1976d2;\n}\n\n.close-btn {\n width: 32px;\n height: 32px;\n border: none;\n background: transparent;\n border-radius: 6px;\n cursor: pointer;\n color: #666;\n transition: all 0.15s ease;\n}\n\n.close-btn:hover {\n background: #e0e0e0;\n color: #333;\n}\n\n/* Tab Navigation */\n.tab-nav {\n display: flex;\n border-bottom: 1px solid #e0e0e0;\n flex-shrink: 0;\n}\n\n.tab-btn {\n flex: 1;\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 8px;\n padding: 12px 16px;\n border: none;\n background: transparent;\n color: #666;\n font-size: 13px;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.15s ease;\n border-bottom: 2px solid transparent;\n}\n\n.tab-btn:hover {\n background: #f5f5f5;\n color: #333;\n}\n\n.tab-btn.active {\n color: #1976d2;\n border-bottom-color: #1976d2;\n background: transparent;\n}\n\n.tab-btn i {\n font-size: 12px;\n}\n\n.tab-badge {\n background: #1976d2;\n color: white;\n font-size: 10px;\n font-weight: 600;\n padding: 2px 6px;\n border-radius: 8px;\n margin-left: 4px;\n}\n\n/* Icon-only mode for narrow panels */\n.tab-nav.icon-only .tab-btn {\n padding: 12px 8px;\n gap: 4px;\n}\n\n.tab-nav.icon-only .tab-btn i {\n font-size: 14px;\n}\n\n.tab-nav.icon-only .tab-badge {\n margin-left: 0;\n padding: 2px 4px;\n font-size: 9px;\n}\n\n/* Panel Content */\n.panel-content {\n flex: 1;\n overflow: hidden;\n padding: 16px 0;\n display: flex;\n flex-direction: column;\n min-height: 0;\n}\n\n.tab-content {\n padding: 0 20px;\n flex: 1;\n display: flex;\n flex-direction: column;\n min-height: 0;\n overflow-y: auto;\n}\n\n/* Config Sections */\n.config-section {\n margin-bottom: 24px;\n}\n\n.section-header {\n display: flex;\n align-items: center;\n gap: 8px;\n margin-bottom: 12px;\n font-size: 13px;\n font-weight: 600;\n color: #333;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.section-header i {\n color: #1976d2;\n font-size: 12px;\n}\n\n.column-count {\n margin-left: auto;\n background: #e3f2fd;\n color: #1976d2;\n padding: 2px 8px;\n border-radius: 10px;\n font-size: 11px;\n}\n\n/* Sort Configuration */\n.sort-config {\n display: flex;\n gap: 8px;\n}\n\n.sort-field-select {\n flex: 1;\n padding: 10px 12px;\n border: 1px solid #e0e0e0;\n border-radius: 6px;\n font-size: 14px;\n background: white;\n cursor: pointer;\n}\n\n.sort-field-select:focus {\n outline: none;\n border-color: #1976d2;\n}\n\n.sort-direction-toggle {\n display: flex;\n background: #f0f0f0;\n border-radius: 6px;\n padding: 2px;\n}\n\n.direction-btn {\n width: 36px;\n height: 36px;\n border: none;\n background: transparent;\n border-radius: 4px;\n cursor: pointer;\n color: #666;\n transition: all 0.15s ease;\n}\n\n.direction-btn:hover {\n color: #333;\n}\n\n.direction-btn.active {\n background: white;\n color: #1976d2;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);\n}\n\n/* ========================================\n MULTI-SORT CONFIGURATION\n ======================================== */\n\n.add-sort-btn {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 10px 14px;\n border: 1px dashed #ccc;\n border-radius: 8px;\n background: transparent;\n color: #666;\n font-size: 13px;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.15s ease;\n width: 100%;\n justify-content: center;\n margin-bottom: 12px;\n}\n\n.add-sort-btn:hover:not(:disabled) {\n border-color: #1976d2;\n background: #e3f2fd;\n color: #1976d2;\n}\n\n.add-sort-btn:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.add-sort-btn i {\n font-size: 12px;\n}\n\n/* Sort Items List */\n.sort-items-list {\n display: flex;\n flex-direction: column;\n gap: 8px;\n margin-bottom: 12px;\n}\n\n/* Sort Item */\n.sort-item {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 10px 12px;\n background: white;\n border: 1px solid #e0e0e0;\n border-radius: 8px;\n transition: all 0.15s ease;\n}\n\n.sort-item:hover {\n border-color: #bdbdbd;\n background: #fafafa;\n}\n\n.sort-item.dragging {\n opacity: 0.5;\n background: #e3f2fd;\n border-color: #1976d2;\n}\n\n.sort-item.drop-target {\n border-color: #1976d2;\n}\n\n/* Priority Badge */\n.sort-priority-badge {\n display: flex;\n align-items: center;\n justify-content: center;\n min-width: 24px;\n height: 24px;\n padding: 0 6px;\n font-size: 12px;\n font-weight: 700;\n color: white;\n background: linear-gradient(135deg, #1976d2 0%, #42a5f5 100%);\n border-radius: 12px;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2);\n flex-shrink: 0;\n}\n\n/* Drag Handle */\n.sort-drag-handle {\n color: #bdbdbd;\n cursor: grab;\n padding: 4px;\n transition: color 0.15s ease;\n flex-shrink: 0;\n}\n\n.sort-drag-handle:hover {\n color: #757575;\n}\n\n.sort-item.dragging .sort-drag-handle {\n cursor: grabbing;\n color: #1976d2;\n}\n\n/* Sort Field Dropdown */\n.sort-field-dropdown {\n flex: 1;\n min-width: 120px;\n padding: 8px 10px;\n border: 1px solid #e0e0e0;\n border-radius: 6px;\n font-size: 13px;\n background: white;\n cursor: pointer;\n}\n\n.sort-field-dropdown:focus {\n outline: none;\n border-color: #1976d2;\n}\n\n.sort-field-dropdown:disabled {\n background: #f5f5f5;\n color: #999;\n cursor: not-allowed;\n}\n\n/* Sort Remove Button */\n.sort-remove-btn {\n width: 28px;\n height: 28px;\n border: none;\n background: transparent;\n border-radius: 4px;\n cursor: pointer;\n color: #bdbdbd;\n transition: all 0.15s ease;\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n}\n\n.sort-remove-btn:hover:not(:disabled) {\n background: #ffebee;\n color: #c62828;\n}\n\n.sort-remove-btn:disabled {\n opacity: 0.3;\n cursor: not-allowed;\n}\n\n/* Sort Drop Indicator */\n.sort-drop-indicator {\n height: 3px;\n background: linear-gradient(90deg, #1976d2 0%, #42a5f5 50%, #1976d2 100%);\n border-radius: 2px;\n margin: 0 12px;\n box-shadow: 0 0 8px rgba(25, 118, 210, 0.5);\n animation: sortDropIndicatorPulse 0.8s ease-in-out infinite;\n}\n\n@keyframes sortDropIndicatorPulse {\n 0%, 100% { opacity: 1; transform: scaleX(1); }\n 50% { opacity: 0.7; transform: scaleX(0.98); }\n}\n\n/* Sort Hint */\n.sort-hint {\n display: flex;\n align-items: flex-start;\n gap: 8px;\n padding: 10px 12px;\n background: #f5f7fa;\n border-radius: 6px;\n font-size: 12px;\n color: #666;\n}\n\n.sort-hint i {\n color: #1976d2;\n margin-top: 1px;\n flex-shrink: 0;\n}\n\n/* Sorting Section Styles */\n.sorting-section {\n padding-top: 0;\n}\n\n.sorting-header {\n margin-bottom: 16px;\n}\n\n.sorting-description {\n font-size: 13px;\n color: #666;\n line-height: 1.5;\n margin: 0;\n}\n\n/* Sort Empty State */\n.sort-empty-state {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n gap: 8px;\n padding: 40px 20px;\n color: #999;\n font-size: 14px;\n text-align: center;\n}\n\n.sort-empty-state i {\n font-size: 48px;\n opacity: 0.4;\n margin-bottom: 8px;\n}\n\n.sort-empty-hint {\n font-size: 12px;\n color: #bbb;\n margin: 0;\n}\n\n/* Column Lists */\n.column-list {\n border: 1px solid #e0e0e0;\n border-radius: 8px;\n overflow: hidden;\n background: #fafafa;\n}\n\n.column-list.visible-columns {\n max-height: 300px;\n overflow-y: auto;\n}\n\n.column-list.hidden-columns {\n flex: 1;\n min-height: 100px;\n overflow-y: auto;\n}\n\n/* Hidden columns section should expand to fill available space */\n.config-section:last-child {\n flex: 1;\n display: flex;\n flex-direction: column;\n min-height: 0;\n margin-bottom: 0;\n}\n\n.column-item {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 10px 12px;\n background: white;\n border-bottom: 1px solid #f0f0f0;\n transition: background 0.1s ease;\n position: relative;\n}\n\n.column-item:last-child {\n border-bottom: none;\n}\n\n.column-item:hover {\n background: #f5f7fa;\n}\n\n.column-item.hidden {\n background: #fafafa;\n}\n\n.column-item.hidden:hover {\n background: #f0f0f0;\n}\n\n/* ========================================\n DRAG & DROP INDICATOR STYLES\n ======================================== */\n\n/* Drop indicator line element - shows where the column will be placed */\n.drop-indicator {\n height: 3px;\n background: linear-gradient(90deg, #1976d2 0%, #42a5f5 50%, #1976d2 100%);\n border-radius: 2px;\n margin: 0 12px;\n box-shadow: 0 0 8px rgba(25, 118, 210, 0.5);\n animation: dropIndicatorPulse 0.8s ease-in-out infinite;\n}\n\n@keyframes dropIndicatorPulse {\n 0%, 100% { opacity: 1; transform: scaleX(1); }\n 50% { opacity: 0.7; transform: scaleX(0.98); }\n}\n\n/* Highlight the column being dragged */\n.column-item.dragging {\n opacity: 0.5;\n background: #e3f2fd;\n}\n\n/* Visual feedback during drag over */\n.column-item.drag-over {\n background: #f5f7fa;\n}\n\n.drag-handle {\n cursor: grab;\n color: #999;\n padding: 4px;\n transition: color 0.15s ease;\n}\n\n.drag-handle:hover {\n color: #666;\n}\n\n.drag-handle:active {\n cursor: grabbing;\n color: #1976d2;\n}\n\n.column-name {\n flex: 1;\n font-size: 14px;\n color: #333;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n display: flex;\n align-items: center;\n gap: 6px;\n}\n\n.column-name .format-indicator {\n font-size: 10px;\n color: #1976d2;\n opacity: 0.7;\n}\n\n.column-name .alias-indicator {\n font-size: 10px;\n color: #7b1fa2;\n opacity: 0.8;\n}\n\n.column-actions {\n display: flex;\n gap: 4px;\n}\n\n.action-btn {\n width: 28px;\n height: 28px;\n border: none;\n background: transparent;\n border-radius: 4px;\n cursor: pointer;\n color: #999;\n transition: all 0.15s ease;\n}\n\n.action-btn:hover:not(:disabled) {\n background: #e0e0e0;\n color: #333;\n}\n\n.action-btn:disabled {\n opacity: 0.3;\n cursor: not-allowed;\n}\n\n.action-btn.hide-btn:hover {\n background: #ffebee;\n color: #c62828;\n}\n\n.action-btn.show-btn:hover {\n background: #e8f5e9;\n color: #2e7d32;\n}\n\n.action-btn.format-btn:hover {\n background: #e3f2fd;\n color: #1976d2;\n}\n\n.action-btn.format-btn.has-format {\n color: #1976d2;\n background: #e3f2fd;\n}\n\n.empty-list {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 8px;\n padding: 20px;\n color: #999;\n font-size: 13px;\n}\n\n/* Column Search */\n.column-search {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px 12px;\n background: white;\n border: 1px solid #e0e0e0;\n border-radius: 6px;\n margin-bottom: 8px;\n}\n\n.column-search i {\n color: #999;\n font-size: 12px;\n}\n\n.column-search input {\n flex: 1;\n border: none;\n outline: none;\n font-size: 14px;\n}\n\n/* ========================================\n COLUMN FORMAT EDITOR SUB-PANEL\n ======================================== */\n\n.format-editor-panel {\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: white;\n z-index: 100;\n display: flex;\n flex-direction: column;\n animation: slideInFromRight 0.2s ease;\n}\n\n@keyframes slideInFromRight {\n from {\n transform: translateX(100%);\n opacity: 0;\n }\n to {\n transform: translateX(0);\n opacity: 1;\n }\n}\n\n.format-editor-header {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 16px 20px;\n border-bottom: 1px solid #e0e0e0;\n background: #fafafa;\n flex-shrink: 0;\n}\n\n.format-back-btn {\n width: 32px;\n height: 32px;\n border: none;\n background: transparent;\n border-radius: 6px;\n cursor: pointer;\n color: #666;\n transition: all 0.15s ease;\n}\n\n.format-back-btn:hover {\n background: #e0e0e0;\n color: #333;\n}\n\n.format-header-title {\n display: flex;\n flex-direction: column;\n gap: 2px;\n}\n\n.format-header-title span:first-child {\n font-size: 14px;\n font-weight: 600;\n color: #333;\n}\n\n.format-header-title span:last-child {\n font-size: 12px;\n color: #666;\n}\n\n.format-editor-content {\n flex: 1;\n overflow-y: auto;\n padding: 20px;\n}\n\n/* Format Preview Section */\n.format-preview-section {\n margin-bottom: 24px;\n padding: 16px;\n background: linear-gradient(135deg, #f8fafc 0%, #f1f5f9 100%);\n border: 1px solid #e2e8f0;\n border-radius: 12px;\n}\n\n.preview-header {\n display: flex;\n align-items: center;\n gap: 8px;\n margin-bottom: 12px;\n font-size: 12px;\n font-weight: 600;\n color: #64748b;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.preview-header i {\n color: #3b82f6;\n}\n\n.preview-samples {\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n\n.preview-sample {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 10px 14px;\n background: white;\n border-radius: 8px;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.08);\n}\n\n.preview-label {\n font-size: 12px;\n color: #94a3b8;\n min-width: 60px;\n}\n\n.preview-value {\n flex: 1;\n font-size: 14px;\n font-family: 'SF Mono', 'Monaco', monospace;\n color: #1e293b;\n}\n\n/* Format Type Selection */\n.format-type-section {\n margin-bottom: 24px;\n}\n\n.format-type-section .section-label {\n display: block;\n margin-bottom: 10px;\n font-size: 13px;\n font-weight: 600;\n color: #333;\n}\n\n.format-type-grid {\n display: grid;\n grid-template-columns: repeat(4, 1fr);\n gap: 8px;\n}\n\n.format-type-btn {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 6px;\n padding: 12px 8px;\n border: 2px solid #e5e7eb;\n border-radius: 10px;\n background: white;\n cursor: pointer;\n transition: all 0.15s ease;\n}\n\n.format-type-btn:hover {\n border-color: #cbd5e1;\n background: #f8fafc;\n}\n\n.format-type-btn.active {\n border-color: #3b82f6;\n background: #eff6ff;\n}\n\n.format-type-btn i {\n font-size: 18px;\n color: #64748b;\n}\n\n.format-type-btn.active i {\n color: #3b82f6;\n}\n\n.format-type-btn span {\n font-size: 11px;\n font-weight: 500;\n color: #64748b;\n}\n\n.format-type-btn.active span {\n color: #1d4ed8;\n}\n\n/* Format Options Section */\n.format-options-section {\n margin-bottom: 24px;\n}\n\n.format-options-section .section-label {\n display: block;\n margin-bottom: 12px;\n font-size: 13px;\n font-weight: 600;\n color: #333;\n}\n\n.format-option-group {\n margin-bottom: 16px;\n}\n\n.format-option-group label {\n display: block;\n margin-bottom: 6px;\n font-size: 13px;\n font-weight: 500;\n color: #333;\n}\n\n.format-option-group input,\n.format-option-group select {\n width: 100%;\n padding: 10px 12px;\n border: 1px solid #e0e0e0;\n border-radius: 6px;\n font-size: 14px;\n transition: border-color 0.15s ease;\n}\n\n.format-option-group input:focus,\n.format-option-group select:focus {\n outline: none;\n border-color: #1976d2;\n}\n\n.format-option-row {\n display: flex;\n gap: 12px;\n}\n\n.format-option-row .format-option-group {\n flex: 1;\n}\n\n.format-checkbox {\n display: flex;\n align-items: center;\n gap: 10px;\n cursor: pointer;\n}\n\n.format-checkbox input[type=\"checkbox\"] {\n width: 18px;\n height: 18px;\n cursor: pointer;\n}\n\n.format-checkbox span {\n font-size: 14px;\n color: #333;\n}\n\n/* Alignment Options */\n.alignment-options {\n display: flex;\n gap: 8px;\n}\n\n.align-btn {\n flex: 1;\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 10px;\n border: 2px solid #e5e7eb;\n border-radius: 8px;\n background: white;\n cursor: pointer;\n transition: all 0.15s ease;\n}\n\n.align-btn:hover {\n border-color: #cbd5e1;\n background: #f8fafc;\n}\n\n.align-btn.active {\n border-color: #3b82f6;\n background: #eff6ff;\n color: #3b82f6;\n}\n\n.align-btn i {\n font-size: 16px;\n color: #64748b;\n}\n\n.align-btn.active i {\n color: #3b82f6;\n}\n\n/* Style Section */\n.style-section {\n margin-bottom: 24px;\n}\n\n.style-section .section-label {\n display: block;\n margin-bottom: 12px;\n font-size: 13px;\n font-weight: 600;\n color: #333;\n}\n\n.style-toggle-group {\n display: flex;\n gap: 8px;\n margin-bottom: 12px;\n}\n\n.style-toggle-btn {\n width: 40px;\n height: 40px;\n border: 2px solid #e5e7eb;\n border-radius: 8px;\n background: white;\n cursor: pointer;\n transition: all 0.15s ease;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.style-toggle-btn:hover {\n border-color: #cbd5e1;\n background: #f8fafc;\n}\n\n.style-toggle-btn.active {\n border-color: #3b82f6;\n background: #eff6ff;\n}\n\n.style-toggle-btn i {\n font-size: 16px;\n color: #64748b;\n}\n\n.style-toggle-btn.active i {\n color: #3b82f6;\n}\n\n.color-picker-row {\n display: flex;\n gap: 12px;\n align-items: center;\n}\n\n.color-picker-group {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.color-picker-group label {\n font-size: 13px;\n color: #64748b;\n min-width: 80px;\n}\n\n.color-picker-group input[type=\"color\"] {\n width: 40px;\n height: 32px;\n padding: 2px;\n border: 1px solid #e0e0e0;\n border-radius: 6px;\n cursor: pointer;\n}\n\n.color-clear-btn {\n width: 32px;\n height: 32px;\n border: 1px solid #e0e0e0;\n border-radius: 6px;\n background: white;\n cursor: pointer;\n color: #999;\n transition: all 0.15s ease;\n}\n\n.color-clear-btn:hover {\n background: #f5f5f5;\n color: #666;\n}\n\n/* Format Editor Footer */\n.format-editor-footer {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 16px 20px;\n border-top: 1px solid #e0e0e0;\n background: #fafafa;\n flex-shrink: 0;\n}\n\n.format-footer-left {\n display: flex;\n gap: 8px;\n}\n\n.format-footer-right {\n display: flex;\n gap: 8px;\n}\n\n.format-footer-btn {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 8px;\n padding: 10px 16px;\n border: 1px solid #e0e0e0;\n background: white;\n border-radius: 6px;\n font-size: 14px;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.15s ease;\n}\n\n.format-footer-btn:hover:not(:disabled) {\n background: #f0f0f0;\n border-color: #ccc;\n}\n\n.format-footer-btn.primary {\n background: #1976d2;\n border-color: #1976d2;\n color: white;\n}\n\n.format-footer-btn.primary:hover:not(:disabled) {\n background: #1565c0;\n border-color: #1565c0;\n}\n\n.format-footer-btn.danger {\n color: #c62828;\n border-color: #c62828;\n}\n\n.format-footer-btn.danger:hover:not(:disabled) {\n background: #c62828;\n color: white;\n}\n\n/* Filter Summary Container */\n.filter-summary-container {\n padding: 4px 0;\n}\n\n.filter-summary {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 12px 16px;\n background: #f5f7fa;\n border-radius: 8px;\n border: 1px solid #e8e8e8;\n}\n\n.summary-info {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.filter-badge {\n background: #1976d2;\n color: white;\n font-size: 12px;\n font-weight: 600;\n padding: 2px 8px;\n border-radius: 10px;\n min-width: 20px;\n text-align: center;\n}\n\n.summary-text {\n font-size: 14px;\n color: #333;\n}\n\n.summary-text.no-filters {\n color: #999;\n}\n\n.summary-actions {\n display: flex;\n gap: 8px;\n}\n\n.summary-btn {\n display: flex;\n align-items: center;\n gap: 4px;\n padding: 6px 12px;\n border: none;\n border-radius: 6px;\n font-size: 13px;\n cursor: pointer;\n transition: all 0.15s ease;\n}\n\n.summary-btn:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.summary-btn i {\n font-size: 11px;\n}\n\n.summary-btn.clear-btn {\n background: transparent;\n color: #c62828;\n border: 1px solid #e0e0e0;\n}\n\n.summary-btn.clear-btn:hover:not(:disabled) {\n background: #ffebee;\n border-color: #c62828;\n}\n\n.summary-btn.edit-btn {\n background: #1976d2;\n color: white;\n}\n\n.summary-btn.edit-btn:hover:not(:disabled) {\n background: #1565c0;\n}\n\n/* ========================================\n FILTER MODE SELECTOR\n ======================================== */\n\n.filter-mode-selector {\n display: flex;\n flex-direction: column;\n gap: 8px;\n margin-bottom: 16px;\n}\n\n.filter-mode-btn {\n display: flex;\n align-items: center;\n gap: 14px;\n padding: 14px 16px;\n border: 2px solid #e5e7eb;\n border-radius: 12px;\n background: white;\n cursor: pointer;\n transition: all 0.2s ease;\n text-align: left;\n}\n\n.filter-mode-btn:hover:not(:disabled) {\n border-color: #d1d5db;\n background: #f9fafb;\n}\n\n.filter-mode-btn:disabled {\n opacity: 0.6;\n cursor: not-allowed;\n}\n\n.filter-mode-btn.active {\n border-color: #3b82f6;\n background: linear-gradient(135deg, #eff6ff 0%, #dbeafe 100%);\n}\n\n.filter-mode-btn .mode-icon {\n width: 40px;\n height: 40px;\n display: flex;\n align-items: center;\n justify-content: center;\n border-radius: 10px;\n background: #f3f4f6;\n color: #6b7280;\n font-size: 16px;\n flex-shrink: 0;\n transition: all 0.2s ease;\n}\n\n.filter-mode-btn.active .mode-icon {\n background: #3b82f6;\n color: white;\n}\n\n.filter-mode-btn .mode-content {\n flex: 1;\n display: flex;\n flex-direction: column;\n gap: 2px;\n}\n\n.filter-mode-btn .mode-title {\n font-size: 14px;\n font-weight: 600;\n color: #1f2937;\n}\n\n.filter-mode-btn .mode-subtitle {\n font-size: 12px;\n color: #6b7280;\n}\n\n.filter-mode-btn.active .mode-title {\n color: #1d4ed8;\n}\n\n.filter-mode-btn .mode-check {\n color: #3b82f6;\n font-size: 16px;\n flex-shrink: 0;\n}\n\n/* ========================================\n SMART FILTER SECTION\n ======================================== */\n\n.smart-filter-section {\n padding: 0;\n border: none;\n background: transparent;\n}\n\n.smart-filter-input-container {\n display: flex;\n gap: 12px;\n padding: 16px;\n background: linear-gradient(135deg, #f0f9ff 0%, #e0f2fe 100%);\n border: 1px solid #bae6fd;\n border-radius: 12px;\n margin-bottom: 16px;\n}\n\n.smart-filter-icon {\n width: 36px;\n height: 36px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: linear-gradient(135deg, #3b82f6 0%, #6366f1 100%);\n border-radius: 10px;\n color: white;\n font-size: 14px;\n flex-shrink: 0;\n}\n\n.smart-filter-input-container .smart-filter-textarea {\n flex: 1;\n border: none;\n background: white;\n border-radius: 8px;\n padding: 12px;\n font-size: 14px;\n line-height: 1.5;\n resize: none;\n min-height: 60px;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.08);\n}\n\n.smart-filter-input-container .smart-filter-textarea:focus {\n outline: none;\n box-shadow: 0 0 0 2px rgba(59, 130, 246, 0.3), 0 1px 3px rgba(0, 0, 0, 0.08);\n}\n\n.smart-filter-input-container .smart-filter-textarea::placeholder {\n color: #9ca3af;\n}\n\n.smart-filter-explanation {\n display: flex;\n align-items: flex-start;\n gap: 8px;\n padding: 12px;\n background: #e3f2fd;\n border-radius: 6px;\n margin-bottom: 12px;\n font-size: 13px;\n color: #1565c0;\n}\n\n.smart-filter-explanation i {\n color: #1976d2;\n font-size: 14px;\n margin-top: 2px;\n flex-shrink: 0;\n}\n\n/* Smart Filter Examples */\n.smart-filter-examples {\n margin-bottom: 16px;\n}\n\n.examples-header {\n display: flex;\n align-items: center;\n gap: 8px;\n margin-bottom: 10px;\n font-size: 13px;\n font-weight: 500;\n color: #6b7280;\n}\n\n.examples-header i {\n color: #f59e0b;\n}\n\n.example-chips {\n display: flex;\n flex-wrap: wrap;\n gap: 8px;\n}\n\n.example-chip {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 8px 12px;\n border: 1px solid #e5e7eb;\n border-radius: 20px;\n background: white;\n font-size: 12px;\n font-weight: 500;\n color: #4b5563;\n cursor: pointer;\n transition: all 0.15s ease;\n}\n\n.example-chip:hover:not(:disabled) {\n border-color: #3b82f6;\n background: #eff6ff;\n color: #1d4ed8;\n}\n\n.example-chip:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.example-chip i {\n font-size: 11px;\n color: #9ca3af;\n}\n\n.example-chip:hover:not(:disabled) i {\n color: #3b82f6;\n}\n\n/* Smart Filter Tip */\n.smart-filter-tip {\n display: flex;\n align-items: flex-start;\n gap: 10px;\n padding: 12px 14px;\n background: #f8fafc;\n border: 1px solid #e2e8f0;\n border-radius: 8px;\n font-size: 12px;\n color: #64748b;\n line-height: 1.5;\n}\n\n.smart-filter-tip i {\n color: #94a3b8;\n margin-top: 1px;\n flex-shrink: 0;\n}\n\n/* ========================================\n TRADITIONAL FILTER SECTION\n ======================================== */\n\n.traditional-filter-section {\n padding: 0;\n border: none;\n background: transparent;\n}\n\n.traditional-filter-tip {\n display: flex;\n align-items: flex-start;\n gap: 10px;\n padding: 12px 14px;\n background: #f8fafc;\n border: 1px solid #e2e8f0;\n border-radius: 8px;\n font-size: 12px;\n color: #64748b;\n line-height: 1.5;\n margin-top: 12px;\n}\n\n.traditional-filter-tip i {\n color: #94a3b8;\n margin-top: 1px;\n flex-shrink: 0;\n}\n\n.summary-btn.edit-btn.primary {\n background: #3b82f6;\n color: white;\n border-color: #3b82f6;\n}\n\n.summary-btn.edit-btn.primary:hover:not(:disabled) {\n background: #2563eb;\n border-color: #2563eb;\n}\n\n/* Form Elements */\n.form-group {\n margin-bottom: 16px;\n}\n\n.form-group label {\n display: block;\n margin-bottom: 6px;\n font-size: 13px;\n font-weight: 500;\n color: #333;\n}\n\n.form-input {\n width: 100%;\n padding: 10px 12px;\n border: 1px solid #e0e0e0;\n border-radius: 6px;\n font-size: 14px;\n transition: border-color 0.15s ease;\n}\n\n.form-input:focus {\n outline: none;\n border-color: #1976d2;\n}\n\n.form-input:disabled {\n background: #f5f5f5;\n color: #999;\n}\n\n.form-textarea {\n resize: vertical;\n min-height: 80px;\n}\n\n/* Checkbox */\n.checkbox-label {\n display: flex;\n align-items: flex-start;\n gap: 12px;\n cursor: pointer;\n}\n\n.checkbox-label input[type=\"checkbox\"] {\n width: 18px;\n height: 18px;\n margin-top: 2px;\n cursor: pointer;\n}\n\n.checkbox-text {\n display: flex;\n flex-direction: column;\n gap: 2px;\n}\n\n.checkbox-text strong {\n font-size: 14px;\n color: #333;\n}\n\n.checkbox-text small {\n font-size: 12px;\n color: #666;\n}\n\n/* Danger Zone */\n.danger-zone {\n padding-top: 16px;\n border-top: 1px solid #ffcdd2;\n}\n\n.danger-zone .section-header {\n color: #c62828;\n}\n\n.danger-zone .section-header i {\n color: #c62828;\n}\n\n.delete-btn {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 8px;\n width: 100%;\n padding: 10px 16px;\n border: 1px solid #c62828;\n background: transparent;\n border-radius: 6px;\n color: #c62828;\n font-size: 14px;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.15s ease;\n}\n\n.delete-btn:hover {\n background: #c62828;\n color: white;\n}\n\n/* Panel Footer */\n.panel-footer {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 16px 20px;\n border-top: 1px solid #e0e0e0;\n background: #fafafa;\n flex-shrink: 0;\n}\n\n.footer-left {\n display: flex;\n gap: 8px;\n}\n\n.footer-right {\n display: flex;\n gap: 8px;\n}\n\n.footer-btn {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 8px;\n padding: 10px 16px;\n border: 1px solid #e0e0e0;\n background: white;\n border-radius: 6px;\n font-size: 14px;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.15s ease;\n}\n\n.footer-btn:hover:not(:disabled) {\n background: #f0f0f0;\n border-color: #ccc;\n}\n\n.footer-btn:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.footer-btn.primary {\n background: #1976d2;\n border-color: #1976d2;\n color: white;\n}\n\n.footer-btn.primary:hover:not(:disabled) {\n background: #1565c0;\n border-color: #1565c0;\n}\n\n.footer-btn i {\n font-size: 12px;\n}\n\n/* ========================================\n FORMAT EDITOR INLINE STYLES\n ======================================== */\n\n.format-editor {\n padding: 0 20px;\n flex: 1;\n display: flex;\n flex-direction: column;\n min-height: 0;\n overflow-y: auto;\n}\n\n.format-editor .format-editor-header {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 12px 0 16px 0;\n border-bottom: 1px solid #e0e0e0;\n margin-bottom: 16px;\n}\n\n.format-editor .back-btn {\n width: 32px;\n height: 32px;\n border: none;\n background: transparent;\n border-radius: 6px;\n cursor: pointer;\n color: #666;\n transition: all 0.15s ease;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.format-editor .back-btn:hover {\n background: #e0e0e0;\n color: #333;\n}\n\n.format-editor .format-editor-title {\n font-size: 16px;\n font-weight: 600;\n color: #333;\n}\n\n/* Preview Table */\n.format-editor .preview-table {\n display: flex;\n flex-direction: column;\n gap: 4px;\n margin-top: 12px;\n}\n\n.format-editor .preview-header-cell {\n padding: 10px 14px;\n background: #f1f5f9;\n border-radius: 6px;\n font-weight: 600;\n font-size: 13px;\n color: #333;\n}\n\n.format-editor .preview-cell {\n padding: 8px 14px;\n background: white;\n border: 1px solid #e2e8f0;\n border-radius: 4px;\n font-size: 14px;\n color: #333;\n}\n\n/* Format Section */\n.format-section {\n margin-bottom: 20px;\n padding-bottom: 16px;\n border-bottom: 1px solid #f0f0f0;\n}\n\n.format-section:last-child {\n border-bottom: none;\n}\n\n.format-section-header {\n display: flex;\n align-items: center;\n gap: 8px;\n margin-bottom: 12px;\n font-size: 13px;\n font-weight: 600;\n color: #333;\n}\n\n.format-section-header i {\n color: #1976d2;\n font-size: 12px;\n}\n\n/* Format Row */\n.format-row {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 12px;\n margin-bottom: 10px;\n}\n\n.format-row:last-child {\n margin-bottom: 0;\n}\n\n.format-row label {\n font-size: 13px;\n color: #555;\n flex-shrink: 0;\n}\n\n/* Format Inputs */\n.format-select {\n flex: 1;\n padding: 8px 12px;\n border: 1px solid #e0e0e0;\n border-radius: 6px;\n font-size: 14px;\n background: white;\n cursor: pointer;\n min-width: 120px;\n}\n\n.format-select:focus {\n outline: none;\n border-color: #1976d2;\n}\n\n.format-input {\n padding: 8px 12px;\n border: 1px solid #e0e0e0;\n border-radius: 6px;\n font-size: 14px;\n background: white;\n}\n\n.format-input:focus {\n outline: none;\n border-color: #1976d2;\n}\n\n.format-input.small {\n width: 80px;\n}\n\n/* Alias Info Row */\n.format-row.alias-info {\n justify-content: flex-start;\n gap: 8px;\n}\n\n.format-row.alias-info .muted-text {\n color: #888;\n font-size: 12px;\n}\n\n.clear-alias-btn {\n width: 20px;\n height: 20px;\n border: none;\n background: #f0f0f0;\n border-radius: 50%;\n color: #888;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 10px;\n transition: all 0.15s ease;\n}\n\n.clear-alias-btn:hover {\n background: #e0e0e0;\n color: #c62828;\n}\n\n/* Color Input */\n.color-input {\n width: 50px;\n height: 32px;\n padding: 2px;\n border: 1px solid #e0e0e0;\n border-radius: 6px;\n cursor: pointer;\n background: white;\n}\n\n.color-input:focus {\n outline: none;\n border-color: #1976d2;\n}\n\n/* Alignment Toggle */\n.alignment-toggle {\n display: flex;\n gap: 8px;\n}\n\n.align-btn {\n width: 40px;\n height: 36px;\n border: 2px solid #e5e7eb;\n border-radius: 6px;\n background: white;\n cursor: pointer;\n transition: all 0.15s ease;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.align-btn:hover {\n border-color: #cbd5e1;\n background: #f8fafc;\n}\n\n.align-btn.active {\n border-color: #1976d2;\n background: #e3f2fd;\n}\n\n.align-btn i {\n font-size: 14px;\n color: #64748b;\n}\n\n.align-btn.active i {\n color: #1976d2;\n}\n\n/* Style Buttons */\n.style-buttons {\n display: flex;\n gap: 8px;\n margin-bottom: 12px;\n}\n\n.style-btn {\n width: 36px;\n height: 36px;\n border: 2px solid #e5e7eb;\n border-radius: 6px;\n background: white;\n cursor: pointer;\n transition: all 0.15s ease;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.style-btn:hover {\n border-color: #cbd5e1;\n background: #f8fafc;\n}\n\n.style-btn.active {\n border-color: #1976d2;\n background: #e3f2fd;\n}\n\n.style-btn i {\n font-size: 14px;\n color: #64748b;\n}\n\n.style-btn.active i {\n color: #1976d2;\n}\n\n/* Collapsible Format Sections */\n.format-section-collapsible {\n margin-bottom: 12px;\n border: 1px solid #e0e0e0;\n border-radius: 8px;\n overflow: hidden;\n}\n\n.format-section-collapsible summary {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 12px 14px;\n background: #f8fafc;\n cursor: pointer;\n font-size: 13px;\n font-weight: 500;\n color: #333;\n list-style: none;\n}\n\n.format-section-collapsible summary::-webkit-details-marker {\n display: none;\n}\n\n.format-section-collapsible summary::before {\n content: '\\f054';\n font-family: 'Font Awesome 6 Free';\n font-weight: 900;\n font-size: 10px;\n color: #999;\n transition: transform 0.2s ease;\n}\n\n.format-section-collapsible[open] summary::before {\n transform: rotate(90deg);\n}\n\n.format-section-collapsible summary i {\n color: #1976d2;\n font-size: 12px;\n}\n\n.format-section-collapsible summary span {\n flex: 1;\n}\n\n.format-section-content {\n padding: 14px;\n background: white;\n border-top: 1px solid #e0e0e0;\n}\n\n/* Format Actions */\n.format-actions {\n margin-top: 20px;\n padding-top: 16px;\n border-top: 1px solid #e0e0e0;\n}\n\n.clear-format-btn {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 8px;\n width: 100%;\n padding: 10px 16px;\n border: 1px solid #e0e0e0;\n background: white;\n border-radius: 6px;\n color: #666;\n font-size: 14px;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.15s ease;\n}\n\n.clear-format-btn:hover {\n background: #fff5f5;\n border-color: #f87171;\n color: #dc2626;\n}\n\n.clear-format-btn i {\n font-size: 12px;\n}\n\n/* ========================================\n AGGREGATES TAB STYLES\n ======================================== */\n\n.aggregates-section {\n padding-top: 0;\n}\n\n.aggregates-header {\n margin-bottom: 16px;\n}\n\n.aggregates-description {\n font-size: 13px;\n color: #666;\n line-height: 1.5;\n margin: 0;\n}\n\n/* Add Aggregate Button */\n.add-aggregate-btn {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 12px 16px;\n border: 1px dashed #ccc;\n border-radius: 8px;\n background: transparent;\n color: #666;\n font-size: 14px;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.15s ease;\n width: 100%;\n justify-content: center;\n margin-bottom: 16px;\n}\n\n.add-aggregate-btn:hover:not(:disabled) {\n border-color: #1976d2;\n background: #e3f2fd;\n color: #1976d2;\n}\n\n.add-aggregate-btn:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.add-aggregate-btn i {\n font-size: 12px;\n}\n\n/* Aggregates List */\n.aggregates-list {\n display: flex;\n flex-direction: column;\n gap: 8px;\n margin-bottom: 16px;\n}\n\n/* Aggregate Item */\n.aggregate-item {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 12px 14px;\n background: white;\n border: 1px solid #e0e0e0;\n border-radius: 8px;\n transition: all 0.15s ease;\n}\n\n.aggregate-item:hover {\n border-color: #bdbdbd;\n background: #fafafa;\n}\n\n.aggregate-item.disabled {\n opacity: 0.6;\n background: #f5f5f5;\n}\n\n/* Aggregate Icon */\n.agg-icon {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 36px;\n height: 36px;\n background: linear-gradient(135deg, #e3f2fd 0%, #bbdefb 100%);\n border-radius: 8px;\n color: #1976d2;\n font-size: 14px;\n flex-shrink: 0;\n}\n\n.aggregate-item.disabled .agg-icon {\n background: #f0f0f0;\n color: #999;\n}\n\n/* Aggregate Content */\n.agg-content {\n flex: 1;\n min-width: 0;\n}\n\n.agg-label {\n font-size: 14px;\n font-weight: 500;\n color: #333;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n margin-bottom: 2px;\n}\n\n.aggregate-item.disabled .agg-label {\n color: #888;\n}\n\n.agg-details {\n display: flex;\n align-items: center;\n gap: 8px;\n font-size: 12px;\n color: #888;\n}\n\n.agg-type {\n display: flex;\n align-items: center;\n gap: 4px;\n}\n\n.agg-type i {\n font-size: 10px;\n}\n\n.agg-smart-badge {\n display: flex;\n align-items: center;\n padding: 2px 6px;\n background: linear-gradient(135deg, #eff6ff 0%, #dbeafe 100%);\n border-radius: 4px;\n color: #3b82f6;\n font-size: 10px;\n}\n\n/* Aggregate Actions */\n.agg-actions {\n display: flex;\n gap: 4px;\n flex-shrink: 0;\n}\n\n.agg-action-btn {\n width: 28px;\n height: 28px;\n border: none;\n background: transparent;\n border-radius: 4px;\n cursor: pointer;\n color: #999;\n transition: all 0.15s ease;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.agg-action-btn:hover:not(:disabled) {\n background: #e0e0e0;\n color: #333;\n}\n\n.agg-action-btn:disabled {\n opacity: 0.3;\n cursor: not-allowed;\n}\n\n.agg-action-btn.toggle-btn.enabled {\n color: #2e7d32;\n}\n\n.agg-action-btn.toggle-btn:not(.enabled) {\n color: #bdbdbd;\n}\n\n.agg-action-btn.edit-btn:hover:not(:disabled) {\n background: #e3f2fd;\n color: #1976d2;\n}\n\n.agg-action-btn.remove-btn:hover:not(:disabled) {\n background: #ffebee;\n color: #c62828;\n}\n\n/* Aggregates Summary */\n.aggregates-summary {\n display: flex;\n gap: 16px;\n padding: 12px 14px;\n background: #f5f7fa;\n border-radius: 6px;\n margin-bottom: 16px;\n}\n\n.summary-item {\n display: flex;\n align-items: center;\n gap: 6px;\n font-size: 12px;\n color: #666;\n}\n\n.summary-item i {\n color: #1976d2;\n font-size: 11px;\n}\n\n/* Aggregates Empty State */\n.aggregates-empty-state {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n gap: 8px;\n padding: 40px 20px;\n color: #999;\n font-size: 14px;\n text-align: center;\n}\n\n.aggregates-empty-state i {\n font-size: 48px;\n opacity: 0.4;\n margin-bottom: 8px;\n}\n\n.empty-hint {\n font-size: 12px;\n color: #bbb;\n margin: 0;\n}\n\n/* Aggregates Tip */\n.aggregates-tip {\n display: flex;\n align-items: flex-start;\n gap: 10px;\n padding: 12px 14px;\n background: #f8fafc;\n border: 1px solid #e2e8f0;\n border-radius: 8px;\n font-size: 12px;\n color: #64748b;\n line-height: 1.5;\n}\n\n.aggregates-tip i {\n color: #94a3b8;\n margin-top: 1px;\n flex-shrink: 0;\n}\n\n/* Responsive */\n@media (max-width: 768px) {\n .config-panel {\n width: 100% !important;\n max-width: 100vw !important;\n }\n\n /* Hide resize handle on mobile - panel is full width */\n .resize-handle {\n display: none;\n }\n\n .tab-btn span {\n display: none;\n }\n\n .tab-btn {\n padding: 14px;\n }\n\n .tab-btn i {\n font-size: 16px;\n }\n\n .format-type-grid {\n grid-template-columns: repeat(3, 1fr);\n }\n}\n\n/* Medium screens - limit max resize width */\n@media (min-width: 769px) and (max-width: 1200px) {\n .config-panel {\n max-width: min(600px, 80vw);\n }\n}\n\n/* Validation Styles (BUG-004) */\n.form-input.invalid {\n border-color: #ef4444;\n}\n\n.validation-error {\n display: block;\n font-size: 12px;\n color: #ef4444;\n margin-top: 4px;\n}\n\n.validation-banner {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 10px 16px;\n background: #fef2f2;\n border-top: 1px solid #fecaca;\n color: #dc2626;\n font-size: 13px;\n}\n\n.validation-banner i {\n flex-shrink: 0;\n}\n\n/* Duplicate Button (F-005) */\n.footer-btn.duplicate-btn {\n background: #f3f4f6;\n color: #374151;\n border: 1px solid #d1d5db;\n}\n\n.footer-btn.duplicate-btn:hover {\n background: #e5e7eb;\n border-color: #9ca3af;\n}\n"] }]
|
|
2857
|
+
args: [{ standalone: false, selector: 'mj-view-config-panel', template: "<!-- Backdrop -->\n@if (isOpen) {\n <div class=\"panel-backdrop\" (click)=\"onClose()\"></div>\n}\n\n<!-- Sliding Panel -->\n<div class=\"config-panel\"\n [class.open]=\"isOpen\"\n [class.resizing]=\"isResizing\"\n [style.width.px]=\"panelWidth\">\n <!-- Resize Handle -->\n <div class=\"resize-handle\"\n (mousedown)=\"onResizeStart($event)\"\n title=\"Drag to resize\">\n <div class=\"resize-grip\"></div>\n </div>\n\n <!-- Panel Header -->\n <div class=\"panel-header\">\n <div class=\"header-title\">\n <i class=\"fa-solid fa-sliders-h\"></i>\n <span>{{ viewEntity ? 'Edit View' : 'Configure View' }}</span>\n </div>\n <button class=\"close-btn\" (click)=\"onClose()\" title=\"Close\">\n <i class=\"fa-solid fa-times\"></i>\n </button>\n </div>\n\n <!-- Tab Navigation -->\n <div class=\"tab-nav\" [class.icon-only]=\"isIconOnlyMode\">\n <button\n class=\"tab-btn\"\n [class.active]=\"activeTab === 'columns'\"\n (click)=\"setActiveTab('columns')\"\n [title]=\"isIconOnlyMode ? 'Columns' : ''\">\n <i class=\"fa-solid fa-columns\"></i>\n @if (!isIconOnlyMode) {\n <span>Columns</span>\n }\n </button>\n <button\n class=\"tab-btn\"\n [class.active]=\"activeTab === 'sorting'\"\n (click)=\"setActiveTab('sorting')\"\n [title]=\"isIconOnlyMode ? 'Sorting' + (sortItems.length > 0 ? ' (' + sortItems.length + ')' : '') : ''\">\n <i class=\"fa-solid fa-arrow-up-wide-short\"></i>\n @if (!isIconOnlyMode) {\n <span>Sorting</span>\n }\n @if (sortItems.length > 0) {\n <span class=\"tab-badge\">{{ sortItems.length }}</span>\n }\n </button>\n <button\n class=\"tab-btn\"\n [class.active]=\"activeTab === 'filters'\"\n (click)=\"setActiveTab('filters')\"\n [title]=\"isIconOnlyMode ? 'Filters' : ''\">\n <i class=\"fa-solid fa-filter\"></i>\n @if (!isIconOnlyMode) {\n <span>Filters</span>\n }\n </button>\n <button\n class=\"tab-btn\"\n [class.active]=\"activeTab === 'aggregates'\"\n (click)=\"setActiveTab('aggregates')\"\n [title]=\"isIconOnlyMode ? 'Aggregates' + (enabledAggregatesCount > 0 ? ' (' + enabledAggregatesCount + ')' : '') : ''\">\n <i class=\"fa-solid fa-chart-simple\"></i>\n @if (!isIconOnlyMode) {\n <span>Aggregates</span>\n }\n @if (enabledAggregatesCount > 0) {\n <span class=\"tab-badge\">{{ enabledAggregatesCount }}</span>\n }\n </button>\n @if (viewEntity || DefaultSaveAsNew) {\n <button\n class=\"tab-btn\"\n [class.active]=\"activeTab === 'settings'\"\n (click)=\"setActiveTab('settings')\"\n [title]=\"isIconOnlyMode ? 'Settings' : ''\">\n <i class=\"fa-solid fa-cog\"></i>\n @if (!isIconOnlyMode) {\n <span>Settings</span>\n }\n </button>\n }\n </div>\n\n <!-- Panel Content -->\n <div class=\"panel-content\">\n <!-- Columns Tab -->\n @if (activeTab === 'columns' && !formatEditingColumn) {\n <div class=\"tab-content\">\n <!-- Visible Columns -->\n <div class=\"config-section\">\n <div class=\"section-header\">\n <i class=\"fa-solid fa-eye\"></i>\n <span>Visible Columns</span>\n <span class=\"column-count\">{{ visibleColumns.length }}</span>\n </div>\n <div class=\"column-list visible-columns\">\n @for (column of visibleColumns; track column.fieldId; let i = $index) {\n <!-- Drop indicator before -->\n @if (isDropBefore(column)) {\n <div class=\"drop-indicator\"></div>\n }\n <div\n class=\"column-item\"\n [class.dragging]=\"draggedColumn === column\"\n [class.drop-target]=\"dropTargetColumn === column\"\n draggable=\"true\"\n (dragstart)=\"onDragStart($event, column)\"\n (dragover)=\"onDragOver($event, column)\"\n (dragleave)=\"onDragLeave($event)\"\n (drop)=\"onDrop($event, column)\"\n (dragend)=\"onDragEnd($event)\">\n <div class=\"drag-handle\">\n <i class=\"fa-solid fa-grip-vertical\"></i>\n </div>\n <span class=\"column-name\">\n {{ column.userDisplayName || column.displayName }}\n @if (column.userDisplayName) {\n <i class=\"fa-solid fa-pen-nib alias-indicator\" title=\"Custom name: {{ column.userDisplayName }}\"></i>\n }\n @if (hasCustomFormat(column)) {\n <i class=\"fa-solid fa-paintbrush format-indicator\" title=\"Custom formatting applied\"></i>\n }\n </span>\n <div class=\"column-actions\">\n <button\n class=\"action-btn format-btn\"\n (click)=\"openFormatEditor(column)\"\n title=\"Format column\">\n <i class=\"fa-solid fa-paintbrush\"></i>\n </button>\n <button\n class=\"action-btn\"\n [disabled]=\"i === 0\"\n (click)=\"moveColumnUp(column)\"\n title=\"Move up\">\n <i class=\"fa-solid fa-chevron-up\"></i>\n </button>\n <button\n class=\"action-btn\"\n [disabled]=\"i === visibleColumns.length - 1\"\n (click)=\"moveColumnDown(column)\"\n title=\"Move down\">\n <i class=\"fa-solid fa-chevron-down\"></i>\n </button>\n <button\n class=\"action-btn hide-btn\"\n (click)=\"toggleColumnVisibility(column)\"\n title=\"Hide column\">\n <i class=\"fa-solid fa-eye-slash\"></i>\n </button>\n </div>\n </div>\n <!-- Drop indicator after (only for last item) -->\n @if (isDropAfter(column) && i === visibleColumns.length - 1) {\n <div class=\"drop-indicator\"></div>\n }\n }\n @if (visibleColumns.length === 0) {\n <div class=\"empty-list\">\n <i class=\"fa-solid fa-info-circle\"></i>\n <span>No columns visible. Add columns from below.</span>\n </div>\n }\n </div>\n </div>\n\n <!-- Hidden Columns -->\n <div class=\"config-section\">\n <div class=\"section-header\">\n <i class=\"fa-solid fa-eye-slash\"></i>\n <span>Hidden Columns</span>\n <span class=\"column-count\">{{ hiddenColumns.length }}</span>\n </div>\n @if (hiddenColumns.length > 5) {\n <div class=\"column-search\">\n <i class=\"fa-solid fa-search\"></i>\n <input\n type=\"text\"\n placeholder=\"Search columns...\"\n [(ngModel)]=\"columnSearchText\"\n />\n </div>\n }\n <div class=\"column-list hidden-columns\">\n @for (column of filteredHiddenColumns; track column.fieldId) {\n <div class=\"column-item hidden\">\n <span class=\"column-name\">{{ column.displayName }}</span>\n <button\n class=\"action-btn show-btn\"\n (click)=\"toggleColumnVisibility(column)\"\n title=\"Show column\">\n <i class=\"fa-solid fa-plus\"></i>\n </button>\n </div>\n }\n @if (hiddenColumns.length === 0) {\n <div class=\"empty-list\">\n <i class=\"fa-solid fa-check-circle\"></i>\n <span>All columns are visible</span>\n </div>\n }\n </div>\n </div>\n </div>\n }\n\n <!-- Column Format Editor Sub-Panel -->\n @if (activeTab === 'columns' && formatEditingColumn) {\n <div class=\"format-editor\">\n <!-- Format Editor Header -->\n <div class=\"format-editor-header\">\n <button class=\"back-btn\" (click)=\"closeFormatEditor()\">\n <i class=\"fa-solid fa-arrow-left\"></i>\n </button>\n <div class=\"format-editor-title\">\n <span>Format: {{ formatEditingColumn.userDisplayName || formatEditingColumn.displayName }}</span>\n </div>\n </div>\n\n <!-- Column Alias Section -->\n <div class=\"format-section\">\n <div class=\"format-section-header\">\n <i class=\"fa-solid fa-pen-nib\"></i>\n <span>Column Name</span>\n </div>\n <div class=\"format-row\">\n <label>Display As</label>\n <input type=\"text\" class=\"format-input\"\n [value]=\"formatEditingColumn.userDisplayName || ''\"\n (input)=\"updateUserDisplayName($any($event.target).value)\"\n [placeholder]=\"formatEditingColumn.displayName\" />\n </div>\n @if (formatEditingColumn.userDisplayName) {\n <div class=\"format-row alias-info\">\n <small class=\"muted-text\">Original: {{ formatEditingColumn.displayName }}</small>\n <button class=\"clear-alias-btn\" (click)=\"formatEditingColumn.userDisplayName = undefined\" title=\"Clear alias\">\n <i class=\"fa-solid fa-times\"></i>\n </button>\n </div>\n }\n </div>\n\n <!-- Preview Section -->\n <div class=\"format-preview-section\">\n <div class=\"preview-header\">\n <i class=\"fa-solid fa-eye\"></i>\n <span>Preview</span>\n </div>\n <div class=\"preview-table\">\n <div class=\"preview-header-cell\"\n [style.font-weight]=\"formatEditingColumn.format?.headerStyle?.bold ? 'bold' : 'normal'\"\n [style.font-style]=\"formatEditingColumn.format?.headerStyle?.italic ? 'italic' : 'normal'\"\n [style.text-decoration]=\"formatEditingColumn.format?.headerStyle?.underline ? 'underline' : 'none'\"\n [style.color]=\"formatEditingColumn.format?.headerStyle?.color\"\n [style.background-color]=\"formatEditingColumn.format?.headerStyle?.backgroundColor\">\n {{ formatEditingColumn.userDisplayName || formatEditingColumn.displayName }}\n </div>\n @for (value of getSampleValues(formatEditingColumn); track $index) {\n <div class=\"preview-cell\"\n [style.text-align]=\"formatEditingColumn.format?.align || 'left'\"\n [style.font-weight]=\"formatEditingColumn.format?.cellStyle?.bold ? 'bold' : 'normal'\"\n [style.font-style]=\"formatEditingColumn.format?.cellStyle?.italic ? 'italic' : 'normal'\"\n [style.text-decoration]=\"formatEditingColumn.format?.cellStyle?.underline ? 'underline' : 'none'\"\n [style.color]=\"formatEditingColumn.format?.cellStyle?.color\"\n [style.background-color]=\"formatEditingColumn.format?.cellStyle?.backgroundColor\">\n {{ formatPreviewValue(value, formatEditingColumn.format) }}\n </div>\n }\n </div>\n </div>\n\n <!-- Format Type -->\n <div class=\"format-section\">\n <div class=\"format-section-header\">\n <i class=\"fa-solid fa-hashtag\"></i>\n <span>Format Type</span>\n </div>\n <select class=\"format-select\" [(ngModel)]=\"formatEditingColumn.format!.type\">\n <option value=\"auto\">Auto (Smart Default)</option>\n <option value=\"text\">Text</option>\n <option value=\"number\">Number</option>\n <option value=\"currency\">Currency</option>\n <option value=\"percent\">Percent</option>\n <option value=\"date\">Date</option>\n <option value=\"datetime\">Date & Time</option>\n <option value=\"boolean\">Boolean</option>\n </select>\n </div>\n\n <!-- Type-Specific Options -->\n @if (formatEditingColumn.format?.type === 'number' || formatEditingColumn.format?.type === 'currency' || formatEditingColumn.format?.type === 'percent') {\n <div class=\"format-section\">\n <div class=\"format-section-header\">\n <i class=\"fa-solid fa-sliders\"></i>\n <span>Number Options</span>\n </div>\n <div class=\"format-row\">\n <label>Decimal Places</label>\n <input type=\"number\" class=\"format-input small\" min=\"0\" max=\"10\"\n [(ngModel)]=\"formatEditingColumn.format!.decimals\" />\n </div>\n @if (formatEditingColumn.format?.type === 'currency') {\n <div class=\"format-row\">\n <label>Currency</label>\n <select class=\"format-select\" [(ngModel)]=\"formatEditingColumn.format!.currencyCode\">\n <option value=\"USD\">USD ($)</option>\n <option value=\"EUR\">EUR (\u20AC)</option>\n <option value=\"GBP\">GBP (\u00A3)</option>\n <option value=\"JPY\">JPY (\u00A5)</option>\n <option value=\"CAD\">CAD ($)</option>\n <option value=\"AUD\">AUD ($)</option>\n </select>\n </div>\n }\n <div class=\"format-row\">\n <label>Thousands Separator</label>\n <input type=\"checkbox\" [(ngModel)]=\"formatEditingColumn.format!.thousandsSeparator\" />\n </div>\n </div>\n }\n\n @if (formatEditingColumn.format?.type === 'date' || formatEditingColumn.format?.type === 'datetime') {\n <div class=\"format-section\">\n <div class=\"format-section-header\">\n <i class=\"fa-solid fa-calendar\"></i>\n <span>Date Options</span>\n </div>\n <div class=\"format-row\">\n <label>Format</label>\n <select class=\"format-select\" [(ngModel)]=\"formatEditingColumn.format!.dateFormat\">\n <option value=\"short\">Short (1/15/25)</option>\n <option value=\"short-weekday\">Short + Day (Wed, 1/15/25)</option>\n <option value=\"medium\">Medium (Jan 15, 2025)</option>\n <option value=\"medium-weekday\">Medium + Day (Wed, Jan 15, 2025)</option>\n <option value=\"long\">Long (January 15, 2025)</option>\n <option value=\"long-weekday\">Long + Day (Wednesday, January 15, 2025)</option>\n </select>\n </div>\n </div>\n }\n\n @if (formatEditingColumn.format?.type === 'boolean') {\n <div class=\"format-section\">\n <div class=\"format-section-header\">\n <i class=\"fa-solid fa-toggle-on\"></i>\n <span>Boolean Options</span>\n </div>\n <div class=\"format-row\">\n <label>True Label</label>\n <input type=\"text\" class=\"format-input\" [(ngModel)]=\"formatEditingColumn.format!.trueLabel\" placeholder=\"Yes\" />\n </div>\n <div class=\"format-row\">\n <label>False Label</label>\n <input type=\"text\" class=\"format-input\" [(ngModel)]=\"formatEditingColumn.format!.falseLabel\" placeholder=\"No\" />\n </div>\n <div class=\"format-row\">\n <label>Display As</label>\n <select class=\"format-select\" [(ngModel)]=\"formatEditingColumn.format!.booleanDisplay\">\n <option value=\"text\">Text</option>\n <option value=\"checkbox\">Checkbox</option>\n <option value=\"icon\">Icon</option>\n </select>\n </div>\n </div>\n }\n\n <!-- Alignment -->\n <div class=\"format-section\">\n <div class=\"format-section-header\">\n <i class=\"fa-solid fa-align-left\"></i>\n <span>Alignment</span>\n </div>\n <div class=\"alignment-toggle\">\n <button class=\"align-btn\" [class.active]=\"formatEditingColumn.format?.align === 'left' || !formatEditingColumn.format?.align\"\n (click)=\"formatEditingColumn.format!.align = 'left'\" title=\"Left\">\n <i class=\"fa-solid fa-align-left\"></i>\n </button>\n <button class=\"align-btn\" [class.active]=\"formatEditingColumn.format?.align === 'center'\"\n (click)=\"formatEditingColumn.format!.align = 'center'\" title=\"Center\">\n <i class=\"fa-solid fa-align-center\"></i>\n </button>\n <button class=\"align-btn\" [class.active]=\"formatEditingColumn.format?.align === 'right'\"\n (click)=\"formatEditingColumn.format!.align = 'right'\" title=\"Right\">\n <i class=\"fa-solid fa-align-right\"></i>\n </button>\n </div>\n </div>\n\n <!-- Header Style -->\n <div class=\"format-section\">\n <div class=\"format-section-header\">\n <i class=\"fa-solid fa-heading\"></i>\n <span>Header Style</span>\n </div>\n <div class=\"style-buttons\">\n <button class=\"style-btn\" [class.active]=\"formatEditingColumn.format?.headerStyle?.bold\"\n (click)=\"toggleHeaderStyle('bold')\"\n title=\"Bold\">\n <i class=\"fa-solid fa-bold\"></i>\n </button>\n <button class=\"style-btn\" [class.active]=\"formatEditingColumn.format?.headerStyle?.italic\"\n (click)=\"toggleHeaderStyle('italic')\"\n title=\"Italic\">\n <i class=\"fa-solid fa-italic\"></i>\n </button>\n <button class=\"style-btn\" [class.active]=\"formatEditingColumn.format?.headerStyle?.underline\"\n (click)=\"toggleHeaderStyle('underline')\"\n title=\"Underline\">\n <i class=\"fa-solid fa-underline\"></i>\n </button>\n </div>\n <div class=\"format-row\">\n <label>Text Color</label>\n <input type=\"color\" class=\"color-input\"\n [value]=\"formatEditingColumn.format?.headerStyle?.color || '#000000'\"\n (input)=\"updateHeaderColor('color', $any($event.target).value)\" />\n </div>\n <div class=\"format-row\">\n <label>Background</label>\n <input type=\"color\" class=\"color-input\"\n [value]=\"formatEditingColumn.format?.headerStyle?.backgroundColor || '#ffffff'\"\n (input)=\"updateHeaderColor('backgroundColor', $any($event.target).value)\" />\n </div>\n </div>\n\n <!-- Cell Style -->\n <div class=\"format-section\">\n <div class=\"format-section-header\">\n <i class=\"fa-solid fa-table-cells\"></i>\n <span>Cell Style</span>\n </div>\n <div class=\"style-buttons\">\n <button class=\"style-btn\" [class.active]=\"formatEditingColumn.format?.cellStyle?.bold\"\n (click)=\"toggleCellStyle('bold')\"\n title=\"Bold\">\n <i class=\"fa-solid fa-bold\"></i>\n </button>\n <button class=\"style-btn\" [class.active]=\"formatEditingColumn.format?.cellStyle?.italic\"\n (click)=\"toggleCellStyle('italic')\"\n title=\"Italic\">\n <i class=\"fa-solid fa-italic\"></i>\n </button>\n <button class=\"style-btn\" [class.active]=\"formatEditingColumn.format?.cellStyle?.underline\"\n (click)=\"toggleCellStyle('underline')\"\n title=\"Underline\">\n <i class=\"fa-solid fa-underline\"></i>\n </button>\n </div>\n <div class=\"format-row\">\n <label>Text Color</label>\n <input type=\"color\" class=\"color-input\"\n [value]=\"formatEditingColumn.format?.cellStyle?.color || '#000000'\"\n (input)=\"updateCellColor('color', $any($event.target).value)\" />\n </div>\n <div class=\"format-row\">\n <label>Background</label>\n <input type=\"color\" class=\"color-input\"\n [value]=\"formatEditingColumn.format?.cellStyle?.backgroundColor || '#ffffff'\"\n (input)=\"updateCellColor('backgroundColor', $any($event.target).value)\" />\n </div>\n </div>\n\n <!-- Clear Format Button -->\n <div class=\"format-actions\">\n <button class=\"clear-format-btn\" (click)=\"clearColumnFormat(formatEditingColumn); closeFormatEditor()\">\n <i class=\"fa-solid fa-eraser\"></i>\n Clear Formatting\n </button>\n </div>\n </div>\n }\n\n <!-- Sorting Tab -->\n @if (activeTab === 'sorting') {\n <div class=\"tab-content\">\n <div class=\"config-section sorting-section\">\n <div class=\"sorting-header\">\n <p class=\"sorting-description\">\n Define how records should be ordered. Add multiple levels to sort by secondary fields when values are equal.\n </p>\n </div>\n\n <!-- Add Sort Button -->\n <button\n class=\"add-sort-btn\"\n (click)=\"addSortLevel()\"\n [disabled]=\"!canEdit || sortItems.length >= sortableFields.length\"\n title=\"Add another sort level\">\n <i class=\"fa-solid fa-plus\"></i>\n <span>Add Sort Level</span>\n </button>\n\n <!-- Sort Items List -->\n @if (sortItems.length > 0) {\n <div class=\"sort-items-list\">\n @for (sortItem of sortItems; track $index; let i = $index) {\n <!-- Drop indicator before -->\n @if (isSortDropBefore(sortItem)) {\n <div class=\"sort-drop-indicator\"></div>\n }\n <div\n class=\"sort-item\"\n [class.dragging]=\"draggedSortItem === sortItem\"\n [class.drop-target]=\"dropTargetSortItem === sortItem\"\n draggable=\"true\"\n (dragstart)=\"onSortDragStart($event, sortItem)\"\n (dragover)=\"onSortDragOver($event, sortItem)\"\n (dragleave)=\"onSortDragLeave($event)\"\n (drop)=\"onSortDrop($event, sortItem)\"\n (dragend)=\"onSortDragEnd($event)\">\n <!-- Priority Badge -->\n <div class=\"sort-priority-badge\">{{ i + 1 }}</div>\n <!-- Drag Handle -->\n <div class=\"sort-drag-handle\" title=\"Drag to reorder\">\n <i class=\"fa-solid fa-grip-vertical\"></i>\n </div>\n <!-- Field Dropdown -->\n <select\n class=\"sort-field-dropdown\"\n [(ngModel)]=\"sortItem.field\"\n (ngModelChange)=\"onSortFieldChange(sortItem, $event)\"\n [disabled]=\"!canEdit\">\n @for (field of sortableFields; track field.ID) {\n <option [value]=\"field.Name\">{{ field.DisplayNameOrName }}</option>\n }\n </select>\n <!-- Direction Toggle -->\n <div class=\"sort-direction-toggle\">\n <button\n class=\"direction-btn\"\n [class.active]=\"sortItem.direction === 'asc'\"\n (click)=\"onSortDirectionChange(sortItem, 'asc')\"\n [disabled]=\"!canEdit\"\n title=\"Ascending (A-Z, 1-9)\">\n <i class=\"fa-solid fa-arrow-up\"></i>\n </button>\n <button\n class=\"direction-btn\"\n [class.active]=\"sortItem.direction === 'desc'\"\n (click)=\"onSortDirectionChange(sortItem, 'desc')\"\n [disabled]=\"!canEdit\"\n title=\"Descending (Z-A, 9-1)\">\n <i class=\"fa-solid fa-arrow-down\"></i>\n </button>\n </div>\n <!-- Remove Button -->\n <button\n class=\"sort-remove-btn\"\n (click)=\"removeSortLevel(sortItem)\"\n [disabled]=\"!canEdit\"\n title=\"Remove sort level\">\n <i class=\"fa-solid fa-times\"></i>\n </button>\n </div>\n <!-- Drop indicator after (only for last item) -->\n @if (isSortDropAfter(sortItem) && i === sortItems.length - 1) {\n <div class=\"sort-drop-indicator\"></div>\n }\n }\n </div>\n <!-- Multi-sort hint -->\n @if (sortItems.length > 1) {\n <div class=\"sort-hint\">\n <i class=\"fa-solid fa-info-circle\"></i>\n <span>Drag items to change priority. Records sort by first level, then second, etc.</span>\n </div>\n }\n } @else {\n <div class=\"sort-empty-state\">\n <i class=\"fa-solid fa-arrow-up-wide-short\"></i>\n <span>No sorting configured</span>\n <p class=\"sort-empty-hint\">Click \"Add Sort Level\" to define how records should be ordered</p>\n </div>\n }\n </div>\n </div>\n }\n\n <!-- Filters Tab -->\n @if (activeTab === 'filters') {\n <div class=\"tab-content\">\n <!-- Filter Mode Selection -->\n <div class=\"filter-mode-selector\">\n <button\n class=\"filter-mode-btn\"\n [class.active]=\"filterMode === 'smart'\"\n (click)=\"setFilterMode('smart')\"\n [disabled]=\"!canEdit\">\n <div class=\"mode-icon\">\n <i class=\"fa-solid fa-wand-magic-sparkles\"></i>\n </div>\n <div class=\"mode-content\">\n <span class=\"mode-title\">Smart Filter</span>\n <span class=\"mode-subtitle\">Use AI to filter with natural language</span>\n </div>\n @if (filterMode === 'smart') {\n <i class=\"fa-solid fa-check mode-check\"></i>\n }\n </button>\n <button\n class=\"filter-mode-btn\"\n [class.active]=\"filterMode === 'traditional'\"\n (click)=\"setFilterMode('traditional')\"\n [disabled]=\"!canEdit\">\n <div class=\"mode-icon\">\n <i class=\"fa-solid fa-sliders\"></i>\n </div>\n <div class=\"mode-content\">\n <span class=\"mode-title\">Traditional Filter</span>\n <span class=\"mode-subtitle\">Build filters with field/operator/value</span>\n </div>\n @if (filterMode === 'traditional') {\n <i class=\"fa-solid fa-check mode-check\"></i>\n }\n </button>\n </div>\n\n <!-- Smart Filter Section -->\n @if (filterMode === 'smart') {\n <div class=\"config-section smart-filter-section\">\n <div class=\"smart-filter-input-container\">\n <div class=\"smart-filter-icon\">\n <i class=\"fa-solid fa-wand-magic-sparkles\"></i>\n </div>\n <textarea\n id=\"smartFilterPrompt\"\n class=\"smart-filter-textarea\"\n placeholder=\"Describe what you're looking for...\"\n [(ngModel)]=\"smartFilterPrompt\"\n [disabled]=\"!canEdit\"\n rows=\"3\"\n ></textarea>\n </div>\n\n @if (smartFilterExplanation) {\n <div class=\"smart-filter-explanation\">\n <i class=\"fa-solid fa-robot\"></i>\n <span>{{ smartFilterExplanation }}</span>\n </div>\n }\n\n <!-- Example Prompts -->\n <div class=\"smart-filter-examples\">\n <div class=\"examples-header\">\n <i class=\"fa-solid fa-lightbulb\"></i>\n <span>Try these examples:</span>\n </div>\n <div class=\"example-chips\">\n <button\n class=\"example-chip\"\n (click)=\"applySmartFilterExample('Show records created in the last 30 days')\"\n [disabled]=\"!canEdit\">\n <i class=\"fa-regular fa-calendar\"></i>\n Last 30 days\n </button>\n <button\n class=\"example-chip\"\n (click)=\"applySmartFilterExample('Active records only')\"\n [disabled]=\"!canEdit\">\n <i class=\"fa-solid fa-circle-check\"></i>\n Active only\n </button>\n <button\n class=\"example-chip\"\n (click)=\"applySmartFilterExample('Records with high priority')\"\n [disabled]=\"!canEdit\">\n <i class=\"fa-solid fa-star\"></i>\n High priority\n </button>\n <button\n class=\"example-chip\"\n (click)=\"applySmartFilterExample('Records modified this week')\"\n [disabled]=\"!canEdit\">\n <i class=\"fa-solid fa-clock-rotate-left\"></i>\n Modified this week\n </button>\n </div>\n </div>\n\n <div class=\"smart-filter-tip\">\n <i class=\"fa-solid fa-info-circle\"></i>\n <span>The AI will interpret your description and create the appropriate filter when you save the view.</span>\n </div>\n </div>\n }\n\n <!-- Traditional Filter Section -->\n @if (filterMode === 'traditional') {\n <div class=\"config-section traditional-filter-section\">\n <div class=\"filter-summary-container\">\n <div class=\"filter-summary\">\n <div class=\"summary-info\">\n @if (getFilterCount() > 0) {\n <span class=\"filter-badge\">{{ getFilterCount() }}</span>\n <span class=\"summary-text\">{{ getFilterSummary() }}</span>\n } @else {\n <span class=\"summary-text no-filters\">No filters configured</span>\n }\n </div>\n <div class=\"summary-actions\">\n @if (getFilterCount() > 0 && canEdit) {\n <button\n class=\"summary-btn clear-btn\"\n (click)=\"clearFilters()\"\n title=\"Clear all filters\">\n <i class=\"fa-solid fa-times\"></i>\n Clear\n </button>\n }\n <button\n class=\"summary-btn edit-btn primary\"\n (click)=\"openFilterDialog()\"\n [disabled]=\"!canEdit && getFilterCount() === 0\"\n title=\"Edit filters\">\n <i class=\"fa-solid fa-pen\"></i>\n {{ getFilterCount() > 0 ? 'Edit Filters' : 'Add Filters' }}\n </button>\n </div>\n </div>\n </div>\n\n <div class=\"traditional-filter-tip\">\n <i class=\"fa-solid fa-info-circle\"></i>\n <span>Build precise filters by selecting fields, operators, and values. Use groups for complex AND/OR logic.</span>\n </div>\n </div>\n }\n </div>\n }\n\n <!-- Aggregates Tab -->\n @if (activeTab === 'aggregates') {\n <div class=\"tab-content\">\n <div class=\"config-section aggregates-section\">\n <div class=\"aggregates-header\">\n <p class=\"aggregates-description\">\n Add summary calculations like totals, averages, and counts. Display them in cards or as column footers.\n </p>\n </div>\n\n <!-- Add Aggregate Button -->\n <button\n class=\"add-aggregate-btn\"\n (click)=\"openAddAggregateDialog()\"\n [disabled]=\"!canEdit\"\n title=\"Add a new aggregate\">\n <i class=\"fa-solid fa-plus\"></i>\n <span>Add Aggregate</span>\n </button>\n\n <!-- Aggregates List -->\n @if (aggregates.length > 0) {\n <div class=\"aggregates-list\">\n @for (agg of aggregates; track agg.id; let i = $index) {\n <div class=\"aggregate-item\" [class.disabled]=\"agg.enabled === false\">\n <!-- Icon -->\n <div class=\"agg-icon\">\n <i [class]=\"agg.icon || 'fa-solid fa-chart-simple'\"></i>\n </div>\n\n <!-- Content -->\n <div class=\"agg-content\">\n <div class=\"agg-label\">{{ agg.label }}</div>\n <div class=\"agg-details\">\n <span class=\"agg-type\">\n <i [class]=\"agg.displayType === 'card' ? 'fa-solid fa-id-card' : 'fa-solid fa-table-columns'\"></i>\n {{ agg.displayType === 'card' ? 'Card' : 'Column Footer' }}\n </span>\n @if (agg.smartPrompt) {\n <span class=\"agg-smart-badge\" title=\"AI-generated\">\n <i class=\"fa-solid fa-wand-magic-sparkles\"></i>\n </span>\n }\n </div>\n </div>\n\n <!-- Actions -->\n <div class=\"agg-actions\">\n <button\n class=\"agg-action-btn\"\n [disabled]=\"i === 0 || !canEdit\"\n (click)=\"moveAggregateUp(agg)\"\n title=\"Move up\">\n <i class=\"fa-solid fa-chevron-up\"></i>\n </button>\n <button\n class=\"agg-action-btn\"\n [disabled]=\"i === aggregates.length - 1 || !canEdit\"\n (click)=\"moveAggregateDown(agg)\"\n title=\"Move down\">\n <i class=\"fa-solid fa-chevron-down\"></i>\n </button>\n <button\n class=\"agg-action-btn toggle-btn\"\n [class.enabled]=\"agg.enabled !== false\"\n (click)=\"toggleAggregateEnabled(agg, $event)\"\n [disabled]=\"!canEdit\"\n [title]=\"agg.enabled !== false ? 'Disable' : 'Enable'\">\n <i [class]=\"agg.enabled !== false ? 'fa-solid fa-eye' : 'fa-solid fa-eye-slash'\"></i>\n </button>\n <button\n class=\"agg-action-btn edit-btn\"\n (click)=\"editAggregate(agg)\"\n [disabled]=\"!canEdit\"\n title=\"Edit\">\n <i class=\"fa-solid fa-pen\"></i>\n </button>\n <button\n class=\"agg-action-btn remove-btn\"\n (click)=\"removeAggregate(agg)\"\n [disabled]=\"!canEdit\"\n title=\"Remove\">\n <i class=\"fa-solid fa-trash\"></i>\n </button>\n </div>\n </div>\n }\n </div>\n\n <!-- Summary -->\n <div class=\"aggregates-summary\">\n <div class=\"summary-item\">\n <i class=\"fa-solid fa-id-card\"></i>\n <span>{{ cardAggregates.length }} card{{ cardAggregates.length !== 1 ? 's' : '' }}</span>\n </div>\n <div class=\"summary-item\">\n <i class=\"fa-solid fa-table-columns\"></i>\n <span>{{ columnAggregates.length }} column footer{{ columnAggregates.length !== 1 ? 's' : '' }}</span>\n </div>\n </div>\n } @else {\n <div class=\"aggregates-empty-state\">\n <i class=\"fa-solid fa-chart-simple\"></i>\n <span>No aggregates configured</span>\n <p class=\"empty-hint\">Click \"Add Aggregate\" to create summary calculations</p>\n </div>\n }\n\n <!-- Info Tip -->\n <div class=\"aggregates-tip\">\n <i class=\"fa-solid fa-info-circle\"></i>\n <span>Aggregates are calculated server-side for accuracy with filtered/paginated data.</span>\n </div>\n </div>\n </div>\n }\n\n <!-- Settings Tab -->\n @if (activeTab === 'settings') {\n <div class=\"tab-content\">\n <!-- View Name & Description -->\n <div class=\"config-section\">\n <div class=\"section-header\">\n <i class=\"fa-solid fa-info-circle\"></i>\n <span>View Details</span>\n </div>\n <div class=\"form-group\">\n <label for=\"viewName\">Name</label>\n <input\n id=\"viewName\"\n type=\"text\"\n class=\"form-input\"\n [class.invalid]=\"!viewName || !viewName.trim()\"\n placeholder=\"Enter view name...\"\n [(ngModel)]=\"viewName\"\n [disabled]=\"!canEdit\"\n />\n @if (!viewName || !viewName.trim()) {\n <span class=\"validation-error\">View name is required</span>\n }\n </div>\n <div class=\"form-group\">\n <label for=\"viewDescription\">Description</label>\n <textarea\n id=\"viewDescription\"\n class=\"form-input form-textarea\"\n placeholder=\"Describe this view...\"\n [(ngModel)]=\"viewDescription\"\n [disabled]=\"!canEdit\"\n rows=\"3\"\n ></textarea>\n </div>\n </div>\n\n <!-- Sharing -->\n <div class=\"config-section\">\n <div class=\"section-header\">\n <i class=\"fa-solid fa-share-alt\"></i>\n <span>Sharing</span>\n </div>\n <label class=\"checkbox-label\">\n <input\n type=\"checkbox\"\n [(ngModel)]=\"isShared\"\n [disabled]=\"!canEdit\"\n />\n <span class=\"checkbox-text\">\n <strong>Share with others</strong>\n <small>Allow other users to use this view</small>\n </span>\n </label>\n </div>\n\n <!-- Danger Zone -->\n @if (viewEntity && canDelete) {\n <div class=\"config-section danger-zone\">\n <div class=\"section-header\">\n <i class=\"fa-solid fa-exclamation-triangle\"></i>\n <span>Danger Zone</span>\n </div>\n <button class=\"delete-btn\" (click)=\"onDelete()\">\n <i class=\"fa-solid fa-trash\"></i>\n <span>Delete View</span>\n </button>\n </div>\n }\n </div>\n }\n </div>\n\n <!-- Validation Errors Banner -->\n @if (ValidationErrors.length > 0 && visibleColumns.length === 0) {\n <div class=\"validation-banner\">\n <i class=\"fa-solid fa-exclamation-triangle\"></i>\n <span>At least one column must be visible</span>\n </div>\n }\n\n <!-- Panel Footer -->\n <div class=\"panel-footer\">\n <!-- Action buttons on LEFT -->\n <div class=\"footer-left\">\n @if (viewEntity && canEdit) {\n <!-- Editing an existing saved view -->\n <button\n class=\"footer-btn save-btn primary\"\n (click)=\"onSave()\"\n [disabled]=\"isSaving || !IsValid\">\n @if (isSaving) {\n <i class=\"fa-solid fa-spinner fa-spin\"></i>\n } @else {\n <i class=\"fa-solid fa-save\"></i>\n }\n {{ isSaving ? 'Saving...' : 'Save' }}\n </button>\n }\n @if (!viewEntity && DefaultSaveAsNew) {\n <!-- Creating a new view (from quick save dialog) -->\n <button\n class=\"footer-btn save-btn primary\"\n (click)=\"onSaveAsNew()\"\n [disabled]=\"isSaving || !IsValidForSaveAsNew\">\n @if (isSaving) {\n <i class=\"fa-solid fa-spinner fa-spin\"></i>\n } @else {\n <i class=\"fa-solid fa-plus\"></i>\n }\n {{ isSaving ? 'Saving...' : 'Create View' }}\n </button>\n }\n @if (!viewEntity && !DefaultSaveAsNew) {\n <!-- Default/Dynamic view - Save to user settings -->\n <button\n class=\"footer-btn save-btn primary\"\n (click)=\"onSaveDefaults()\"\n [disabled]=\"isSaving\">\n @if (isSaving) {\n <i class=\"fa-solid fa-spinner fa-spin\"></i>\n } @else {\n <i class=\"fa-solid fa-save\"></i>\n }\n {{ isSaving ? 'Saving...' : 'Save' }}\n </button>\n }\n </div>\n <!-- Cancel button on RIGHT -->\n <button class=\"footer-btn cancel-btn\" (click)=\"onClose()\">\n Cancel\n </button>\n </div>\n</div>\n\n<!-- Aggregate Setup Dialog -->\n<mj-aggregate-setup-dialog\n [Entity]=\"entity\"\n [Aggregate]=\"editingAggregate\"\n [IsOpen]=\"showAggregateDialog\"\n (Close)=\"closeAggregateDialog()\"\n (Save)=\"onAggregateSave($event)\">\n</mj-aggregate-setup-dialog>\n\n<!-- Delete Confirmation Dialog -->\n<mj-ev-confirm-dialog\n [IsOpen]=\"showDeleteConfirm\"\n Title=\"Delete View\"\n [Message]=\"'Are you sure you want to delete \\'' + viewName + '\\'?'\"\n DetailMessage=\"This action cannot be undone. All users who have access to this view will lose it.\"\n ConfirmText=\"Delete\"\n ConfirmStyle=\"danger\"\n Icon=\"fa-solid fa-trash\"\n (Confirmed)=\"OnDeleteConfirmed()\"\n (Cancelled)=\"OnDeleteCancelled()\">\n</mj-ev-confirm-dialog>\n\n<!-- Filter Mode Switch Confirmation Dialog (BUG-006) -->\n<mj-ev-confirm-dialog\n [IsOpen]=\"showFilterModeSwitchConfirm\"\n Title=\"Switch Filter Mode\"\n [Message]=\"filterMode === 'smart' ? 'Switching to Traditional mode will clear your smart filter prompt.' : 'Switching to Smart mode will clear your traditional filter rules.'\"\n DetailMessage=\"You can switch back later, but the current filter data will be lost.\"\n ConfirmText=\"Switch\"\n ConfirmStyle=\"primary\"\n Icon=\"fa-solid fa-exchange-alt\"\n (Confirmed)=\"OnFilterModeSwitchConfirmed()\"\n (Cancelled)=\"OnFilterModeSwitchCancelled()\">\n</mj-ev-confirm-dialog>\n", styles: ["/* Backdrop */\n.panel-backdrop {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: rgba(0, 0, 0, 0.3);\n z-index: 1000;\n animation: fadeIn 0.2s ease;\n}\n\n@keyframes fadeIn {\n from { opacity: 0; }\n to { opacity: 1; }\n}\n\n/* Sliding Panel */\n.config-panel {\n position: fixed;\n top: 0;\n right: 0;\n width: 450px;\n min-width: 360px;\n max-width: min(800px, 100vw);\n height: 100%;\n background: var(--mj-bg-surface);\n box-shadow: -4px 0 24px rgba(0, 0, 0, 0.15);\n z-index: 1001;\n display: flex;\n flex-direction: column;\n transform: translateX(100%);\n transition: transform 0.25s ease, width 0s;\n}\n\n.config-panel.open {\n transform: translateX(0);\n}\n\n.config-panel.resizing {\n transition: none;\n user-select: none;\n}\n\n/* Resize Handle */\n.resize-handle {\n position: absolute;\n left: 0;\n top: 0;\n bottom: 0;\n width: 6px;\n cursor: ew-resize;\n z-index: 10;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.resize-handle:hover,\n.config-panel.resizing .resize-handle {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, transparent);\n}\n\n.resize-grip {\n width: 3px;\n height: 40px;\n background: var(--mj-border-strong);\n border-radius: 3px;\n opacity: 0;\n transition: opacity 0.2s ease;\n}\n\n.resize-handle:hover .resize-grip,\n.config-panel.resizing .resize-grip {\n opacity: 1;\n background: var(--mj-brand-primary);\n}\n\n/* Panel Header */\n.panel-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 16px 20px;\n border-bottom: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface-card);\n flex-shrink: 0;\n}\n\n.header-title {\n display: flex;\n align-items: center;\n gap: 10px;\n font-size: 16px;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.header-title i {\n color: var(--mj-brand-primary);\n}\n\n.close-btn {\n width: 32px;\n height: 32px;\n border: none;\n background: transparent;\n border-radius: 8px;\n cursor: pointer;\n color: var(--mj-text-muted);\n transition: all 0.15s ease;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.close-btn:hover {\n background: var(--mj-bg-surface-hover);\n color: var(--mj-text-primary);\n}\n\n/* Tab Navigation */\n.tab-nav {\n display: flex;\n border-bottom: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface-card);\n flex-shrink: 0;\n overflow-x: auto;\n -webkit-overflow-scrolling: touch;\n}\n\n.tab-btn {\n flex: 1;\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 8px;\n padding: 12px 16px;\n border: none;\n background: transparent;\n cursor: pointer;\n color: var(--mj-text-muted);\n font-size: 13px;\n font-weight: 500;\n transition: all 0.15s ease;\n position: relative;\n white-space: nowrap;\n}\n\n.tab-btn:hover {\n color: var(--mj-text-secondary);\n background: var(--mj-bg-surface-hover);\n}\n\n.tab-btn.active {\n color: var(--mj-brand-primary);\n font-weight: 600;\n}\n\n.tab-btn.active::after {\n content: '';\n position: absolute;\n bottom: 0;\n left: 8px;\n right: 8px;\n height: 2px;\n background: var(--mj-brand-primary);\n border-radius: 2px 2px 0 0;\n}\n\n.tab-btn i {\n font-size: 14px;\n}\n\n.tab-badge {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n min-width: 18px;\n height: 18px;\n padding: 0 5px;\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n border-radius: 9px;\n font-size: 11px;\n font-weight: 600;\n}\n\n/* Icon-only mode for narrow panel */\n.tab-nav.icon-only .tab-btn {\n padding: 12px 8px;\n}\n\n/* Panel Content */\n.panel-content {\n flex: 1;\n overflow-y: auto;\n overflow-x: hidden;\n}\n\n.tab-content {\n padding: 16px;\n}\n\n/* Config Sections */\n.config-section {\n margin-bottom: 20px;\n}\n\n.section-header {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 10px 0;\n margin-bottom: 8px;\n font-size: 13px;\n font-weight: 600;\n color: var(--mj-text-secondary);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.section-header i {\n color: var(--mj-text-muted);\n font-size: 14px;\n}\n\n.column-count {\n margin-left: auto;\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-muted);\n padding: 2px 8px;\n border-radius: 10px;\n font-size: 12px;\n font-weight: 500;\n}\n\n/* Column Search */\n.column-search {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px 12px;\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n margin-bottom: 8px;\n}\n\n.column-search i {\n color: var(--mj-text-disabled);\n font-size: 12px;\n}\n\n.column-search input {\n flex: 1;\n border: none;\n outline: none;\n font-size: 13px;\n background: transparent;\n color: var(--mj-text-primary);\n}\n\n.column-search input::placeholder {\n color: var(--mj-text-disabled);\n}\n\n/* Column List */\n.column-list {\n display: flex;\n flex-direction: column;\n gap: 2px;\n}\n\n/* Column Item */\n.column-item {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px 10px;\n border-radius: 8px;\n transition: background 0.15s ease;\n cursor: default;\n}\n\n.column-item:hover {\n background: var(--mj-bg-surface-card);\n}\n\n.column-item.hidden {\n opacity: 0.7;\n}\n\n.column-item.hidden:hover {\n opacity: 1;\n}\n\n.column-item.dragging {\n opacity: 0.4;\n}\n\n.column-item.drop-target {\n background: color-mix(in srgb, var(--mj-brand-primary) 8%, var(--mj-bg-surface));\n}\n\n/* Drop Indicator */\n.drop-indicator {\n height: 2px;\n background: var(--mj-brand-primary);\n border-radius: 1px;\n margin: 0 10px;\n}\n\n/* Drag Handle */\n.drag-handle {\n display: flex;\n align-items: center;\n cursor: grab;\n color: var(--mj-text-disabled);\n font-size: 12px;\n padding: 4px 2px;\n}\n\n.drag-handle:active {\n cursor: grabbing;\n}\n\n.column-item:hover .drag-handle {\n color: var(--mj-text-muted);\n}\n\n/* Column Name */\n.column-name {\n flex: 1;\n font-size: 13px;\n color: var(--mj-text-primary);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.alias-indicator {\n font-size: 10px;\n color: var(--mj-brand-primary);\n margin-left: 4px;\n}\n\n.format-indicator {\n font-size: 10px;\n color: var(--mj-status-warning);\n margin-left: 4px;\n}\n\n/* Column Actions */\n.column-actions {\n display: flex;\n align-items: center;\n gap: 2px;\n opacity: 0;\n transition: opacity 0.15s ease;\n}\n\n.column-item:hover .column-actions {\n opacity: 1;\n}\n\n.action-btn {\n width: 26px;\n height: 26px;\n border: none;\n background: transparent;\n border-radius: 6px;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n color: var(--mj-text-muted);\n transition: all 0.15s ease;\n}\n\n.action-btn:hover:not(:disabled) {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-secondary);\n}\n\n.action-btn:disabled {\n opacity: 0.3;\n cursor: not-allowed;\n}\n\n.action-btn.hide-btn:hover {\n background: var(--mj-status-error-bg);\n color: var(--mj-status-error);\n}\n\n.action-btn.show-btn {\n opacity: 0;\n}\n\n.column-item:hover .action-btn.show-btn {\n opacity: 1;\n}\n\n.action-btn.show-btn:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n}\n\n.action-btn.format-btn:hover {\n background: var(--mj-status-warning-bg);\n color: var(--mj-status-warning);\n}\n\n.action-btn i {\n font-size: 12px;\n}\n\n/* Empty List */\n.empty-list {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 16px;\n color: var(--mj-text-muted);\n font-size: 13px;\n}\n\n.empty-list i {\n color: var(--mj-text-disabled);\n}\n\n/* Format Editor */\n.format-editor {\n padding: 0;\n}\n\n.format-editor-header {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 16px;\n border-bottom: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface-card);\n}\n\n.back-btn {\n width: 32px;\n height: 32px;\n border: none;\n background: var(--mj-bg-surface-sunken);\n border-radius: 8px;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n color: var(--mj-text-secondary);\n transition: all 0.15s ease;\n}\n\n.back-btn:hover {\n background: var(--mj-bg-surface-active);\n color: var(--mj-text-primary);\n}\n\n.format-editor-title {\n font-size: 14px;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n/* Format Sections */\n.format-section {\n padding: 16px;\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.format-section-header {\n display: flex;\n align-items: center;\n gap: 8px;\n margin-bottom: 12px;\n font-size: 13px;\n font-weight: 600;\n color: var(--mj-text-secondary);\n}\n\n.format-section-header i {\n color: var(--mj-text-muted);\n}\n\n/* Format Rows */\n.format-row {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 8px 0;\n}\n\n.format-row label {\n font-size: 13px;\n color: var(--mj-text-secondary);\n}\n\n.format-row.alias-info {\n padding: 4px 0;\n}\n\n.muted-text {\n font-size: 12px;\n color: var(--mj-text-muted);\n}\n\n.clear-alias-btn {\n width: 24px;\n height: 24px;\n border: none;\n background: transparent;\n border-radius: 4px;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n color: var(--mj-text-disabled);\n transition: all 0.15s ease;\n}\n\n.clear-alias-btn:hover {\n color: var(--mj-status-error);\n}\n\n/* Format Input */\n.format-input {\n padding: 6px 10px;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n font-size: 13px;\n color: var(--mj-text-primary);\n background: var(--mj-bg-surface);\n transition: border-color 0.15s ease;\n}\n\n.format-input:focus {\n outline: none;\n border-color: var(--mj-brand-primary);\n}\n\n.format-input.small {\n width: 60px;\n text-align: center;\n}\n\n.format-select {\n padding: 6px 10px;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n font-size: 13px;\n color: var(--mj-text-primary);\n background: var(--mj-bg-surface);\n cursor: pointer;\n}\n\n.format-select:focus {\n outline: none;\n border-color: var(--mj-brand-primary);\n}\n\n/* Color Input */\n.color-input {\n width: 36px;\n height: 28px;\n padding: 2px;\n border: 1px solid var(--mj-border-default);\n border-radius: 4px;\n cursor: pointer;\n background: var(--mj-bg-surface);\n}\n\n/* Alignment Toggle */\n.alignment-toggle {\n display: flex;\n gap: 4px;\n background: var(--mj-bg-surface-card);\n border-radius: 8px;\n padding: 3px;\n border: 1px solid var(--mj-border-default);\n}\n\n.align-btn {\n flex: 1;\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 6px;\n border: none;\n background: transparent;\n border-radius: 6px;\n cursor: pointer;\n color: var(--mj-text-muted);\n transition: all 0.15s ease;\n}\n\n.align-btn:hover {\n color: var(--mj-text-secondary);\n}\n\n.align-btn.active {\n background: var(--mj-bg-surface);\n color: var(--mj-brand-primary);\n box-shadow: 0 1px 2px rgba(0, 0, 0, 0.08);\n}\n\n/* Style Buttons */\n.style-buttons {\n display: flex;\n gap: 4px;\n margin-bottom: 12px;\n}\n\n.style-btn {\n width: 32px;\n height: 32px;\n border: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface);\n border-radius: 6px;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n color: var(--mj-text-muted);\n transition: all 0.15s ease;\n}\n\n.style-btn:hover {\n border-color: var(--mj-border-strong);\n color: var(--mj-text-secondary);\n}\n\n.style-btn.active {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n border-color: var(--mj-brand-primary);\n color: var(--mj-brand-primary);\n}\n\n/* Format Preview */\n.format-preview-section {\n padding: 16px;\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.preview-header {\n display: flex;\n align-items: center;\n gap: 8px;\n margin-bottom: 12px;\n font-size: 13px;\n font-weight: 600;\n color: var(--mj-text-secondary);\n}\n\n.preview-header i {\n color: var(--mj-text-muted);\n}\n\n.preview-table {\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n overflow: hidden;\n}\n\n.preview-header-cell {\n padding: 8px 12px;\n font-size: 12px;\n font-weight: 600;\n color: var(--mj-text-secondary);\n background: var(--mj-bg-surface-card);\n border-bottom: 1px solid var(--mj-border-default);\n text-transform: uppercase;\n letter-spacing: 0.3px;\n}\n\n.preview-cell {\n padding: 8px 12px;\n font-size: 13px;\n color: var(--mj-text-primary);\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.preview-cell:last-child {\n border-bottom: none;\n}\n\n/* Format Actions */\n.format-actions {\n padding: 16px;\n}\n\n.clear-format-btn {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px 16px;\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n background: var(--mj-bg-surface);\n cursor: pointer;\n font-size: 13px;\n color: var(--mj-text-secondary);\n transition: all 0.15s ease;\n}\n\n.clear-format-btn:hover {\n background: var(--mj-status-error-bg);\n border-color: var(--mj-status-error);\n color: var(--mj-status-error);\n}\n\n/* Sorting Section */\n.sorting-section {\n padding: 0;\n}\n\n.sorting-header {\n margin-bottom: 12px;\n}\n\n.sorting-description,\n.aggregates-description {\n margin: 0;\n font-size: 13px;\n color: var(--mj-text-muted);\n line-height: 1.5;\n}\n\n/* Add Sort Button */\n.add-sort-btn,\n.add-aggregate-btn {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 10px 16px;\n width: 100%;\n border: 2px dashed var(--mj-border-default);\n border-radius: 10px;\n background: transparent;\n cursor: pointer;\n font-size: 13px;\n font-weight: 500;\n color: var(--mj-text-muted);\n transition: all 0.15s ease;\n margin-bottom: 12px;\n}\n\n.add-sort-btn:hover:not(:disabled),\n.add-aggregate-btn:hover:not(:disabled) {\n border-color: var(--mj-brand-primary);\n color: var(--mj-brand-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 5%, var(--mj-bg-surface));\n}\n\n.add-sort-btn:disabled,\n.add-aggregate-btn:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n/* Sort Items List */\n.sort-items-list {\n display: flex;\n flex-direction: column;\n gap: 6px;\n margin-bottom: 12px;\n}\n\n.sort-item {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px 10px;\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: 10px;\n transition: all 0.15s ease;\n}\n\n.sort-item:hover {\n border-color: var(--mj-border-strong);\n}\n\n.sort-item.dragging {\n opacity: 0.4;\n}\n\n.sort-item.drop-target {\n border-color: var(--mj-brand-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 5%, var(--mj-bg-surface));\n}\n\n/* Sort Drop Indicator */\n.sort-drop-indicator {\n height: 2px;\n background: var(--mj-brand-primary);\n border-radius: 1px;\n margin: 0 10px;\n}\n\n/* Sort Priority Badge */\n.sort-priority-badge {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 22px;\n height: 22px;\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n border-radius: 6px;\n font-size: 11px;\n font-weight: 700;\n flex-shrink: 0;\n}\n\n/* Sort Drag Handle */\n.sort-drag-handle {\n cursor: grab;\n color: var(--mj-text-disabled);\n padding: 2px;\n font-size: 12px;\n}\n\n.sort-drag-handle:active {\n cursor: grabbing;\n}\n\n.sort-item:hover .sort-drag-handle {\n color: var(--mj-text-muted);\n}\n\n/* Sort Field Dropdown */\n.sort-field-dropdown {\n flex: 1;\n padding: 6px 10px;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n font-size: 13px;\n color: var(--mj-text-primary);\n background: var(--mj-bg-surface);\n cursor: pointer;\n min-width: 0;\n}\n\n.sort-field-dropdown:focus {\n outline: none;\n border-color: var(--mj-brand-primary);\n}\n\n/* Sort Direction Toggle */\n.sort-direction-toggle {\n display: flex;\n background: var(--mj-bg-surface-sunken);\n border-radius: 6px;\n padding: 2px;\n gap: 2px;\n}\n\n.direction-btn {\n width: 28px;\n height: 28px;\n border: none;\n background: transparent;\n border-radius: 5px;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n color: var(--mj-text-muted);\n font-size: 12px;\n transition: all 0.15s ease;\n}\n\n.direction-btn:hover:not(:disabled) {\n color: var(--mj-text-secondary);\n}\n\n.direction-btn.active {\n background: var(--mj-bg-surface);\n color: var(--mj-brand-primary);\n box-shadow: 0 1px 2px rgba(0, 0, 0, 0.08);\n}\n\n.direction-btn:disabled {\n opacity: 0.3;\n cursor: not-allowed;\n}\n\n/* Sort Remove Button */\n.sort-remove-btn {\n width: 28px;\n height: 28px;\n border: none;\n background: transparent;\n border-radius: 6px;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n color: var(--mj-text-disabled);\n font-size: 12px;\n transition: all 0.15s ease;\n}\n\n.sort-remove-btn:hover:not(:disabled) {\n background: var(--mj-status-error-bg);\n color: var(--mj-status-error);\n}\n\n.sort-remove-btn:disabled {\n opacity: 0.3;\n cursor: not-allowed;\n}\n\n/* Sort Hint */\n.sort-hint {\n display: flex;\n align-items: flex-start;\n gap: 8px;\n padding: 10px 12px;\n background: var(--mj-bg-surface-card);\n border-radius: 8px;\n font-size: 12px;\n color: var(--mj-text-muted);\n}\n\n.sort-hint i {\n color: var(--mj-text-disabled);\n margin-top: 1px;\n}\n\n/* Sort Empty State */\n.sort-empty-state,\n.aggregates-empty-state {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 8px;\n padding: 32px 16px;\n color: var(--mj-text-muted);\n text-align: center;\n}\n\n.sort-empty-state i,\n.aggregates-empty-state i {\n font-size: 32px;\n opacity: 0.4;\n}\n\n.sort-empty-state span,\n.aggregates-empty-state span {\n font-size: 14px;\n font-weight: 500;\n}\n\n.sort-empty-hint,\n.empty-hint {\n margin: 0;\n font-size: 13px;\n color: var(--mj-text-disabled);\n}\n\n/* Filter Mode Selector */\n.filter-mode-selector {\n display: flex;\n flex-direction: column;\n gap: 8px;\n margin-bottom: 16px;\n}\n\n.filter-mode-btn {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 12px 14px;\n border: 2px solid var(--mj-border-default);\n border-radius: 10px;\n background: var(--mj-bg-surface);\n cursor: pointer;\n transition: all 0.15s ease;\n text-align: left;\n}\n\n.filter-mode-btn:hover:not(:disabled) {\n border-color: var(--mj-border-strong);\n}\n\n.filter-mode-btn.active {\n border-color: var(--mj-brand-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 5%, var(--mj-bg-surface));\n}\n\n.filter-mode-btn:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.mode-icon {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 36px;\n height: 36px;\n background: var(--mj-bg-surface-sunken);\n border-radius: 8px;\n font-size: 16px;\n color: var(--mj-text-muted);\n flex-shrink: 0;\n}\n\n.filter-mode-btn.active .mode-icon {\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n}\n\n.mode-content {\n flex: 1;\n display: flex;\n flex-direction: column;\n gap: 2px;\n}\n\n.mode-title {\n font-size: 14px;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.mode-subtitle {\n font-size: 12px;\n color: var(--mj-text-muted);\n}\n\n.mode-check {\n color: var(--mj-brand-primary);\n font-size: 14px;\n}\n\n/* Smart Filter Section */\n.smart-filter-section {\n padding: 0;\n}\n\n.smart-filter-input-container {\n display: flex;\n gap: 12px;\n padding: 12px;\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: 10px;\n margin-bottom: 12px;\n}\n\n.smart-filter-icon {\n display: flex;\n align-items: flex-start;\n padding-top: 4px;\n color: var(--mj-brand-primary);\n font-size: 16px;\n}\n\n.smart-filter-textarea {\n flex: 1;\n border: none;\n outline: none;\n resize: vertical;\n font-size: 14px;\n font-family: inherit;\n color: var(--mj-text-primary);\n background: transparent;\n min-height: 60px;\n}\n\n.smart-filter-textarea::placeholder {\n color: var(--mj-text-disabled);\n}\n\n.smart-filter-textarea:disabled {\n color: var(--mj-text-muted);\n}\n\n/* Smart Filter Explanation */\n.smart-filter-explanation {\n display: flex;\n align-items: flex-start;\n gap: 8px;\n padding: 10px 12px;\n background: color-mix(in srgb, var(--mj-brand-primary) 8%, var(--mj-bg-surface));\n border: 1px solid color-mix(in srgb, var(--mj-brand-primary) 25%, var(--mj-bg-surface));\n border-radius: 8px;\n margin-bottom: 12px;\n font-size: 13px;\n color: var(--mj-brand-primary);\n}\n\n.smart-filter-explanation i {\n margin-top: 2px;\n}\n\n/* Smart Filter Examples */\n.smart-filter-examples {\n margin-bottom: 12px;\n}\n\n.examples-header {\n display: flex;\n align-items: center;\n gap: 8px;\n margin-bottom: 8px;\n font-size: 12px;\n font-weight: 500;\n color: var(--mj-text-muted);\n}\n\n.examples-header i {\n color: var(--mj-status-warning);\n}\n\n.example-chips {\n display: flex;\n flex-wrap: wrap;\n gap: 6px;\n}\n\n.example-chip {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 6px 12px;\n border: 1px solid var(--mj-border-default);\n border-radius: 20px;\n background: var(--mj-bg-surface);\n cursor: pointer;\n font-size: 12px;\n color: var(--mj-text-secondary);\n transition: all 0.15s ease;\n}\n\n.example-chip:hover:not(:disabled) {\n border-color: var(--mj-brand-primary);\n color: var(--mj-brand-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 5%, var(--mj-bg-surface));\n}\n\n.example-chip:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.example-chip i {\n font-size: 11px;\n}\n\n/* Smart Filter Tip */\n.smart-filter-tip,\n.traditional-filter-tip,\n.aggregates-tip {\n display: flex;\n align-items: flex-start;\n gap: 8px;\n padding: 10px 12px;\n background: var(--mj-bg-surface-card);\n border-radius: 8px;\n font-size: 12px;\n color: var(--mj-text-muted);\n margin-top: 12px;\n}\n\n.smart-filter-tip i,\n.traditional-filter-tip i,\n.aggregates-tip i {\n color: var(--mj-text-disabled);\n margin-top: 1px;\n}\n\n/* Traditional Filter Section */\n.traditional-filter-section {\n padding: 0;\n}\n\n.filter-summary-container {\n margin-bottom: 12px;\n}\n\n.filter-summary {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 12px 14px;\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: 10px;\n}\n\n.summary-info {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.filter-badge {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n min-width: 22px;\n height: 22px;\n padding: 0 6px;\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n border-radius: 11px;\n font-size: 12px;\n font-weight: 600;\n}\n\n.summary-text {\n font-size: 13px;\n color: var(--mj-text-primary);\n font-weight: 500;\n}\n\n.summary-text.no-filters {\n color: var(--mj-text-muted);\n font-weight: 400;\n}\n\n.summary-actions {\n display: flex;\n gap: 8px;\n}\n\n.summary-btn {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 6px 12px;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n background: var(--mj-bg-surface);\n cursor: pointer;\n font-size: 12px;\n font-weight: 500;\n color: var(--mj-text-secondary);\n transition: all 0.15s ease;\n}\n\n.summary-btn:hover:not(:disabled) {\n border-color: var(--mj-border-strong);\n}\n\n.summary-btn:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.summary-btn.clear-btn:hover {\n border-color: var(--mj-status-error);\n color: var(--mj-status-error);\n}\n\n.summary-btn.primary {\n background: var(--mj-brand-primary);\n border-color: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n}\n\n.summary-btn.primary:hover:not(:disabled) {\n background: var(--mj-brand-primary-hover);\n border-color: var(--mj-brand-primary-hover);\n}\n\n/* Aggregates Section */\n.aggregates-section {\n padding: 0;\n}\n\n.aggregates-header {\n margin-bottom: 12px;\n}\n\n/* Aggregates List */\n.aggregates-list {\n display: flex;\n flex-direction: column;\n gap: 6px;\n margin-bottom: 12px;\n}\n\n.aggregate-item {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 10px 12px;\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: 10px;\n transition: all 0.15s ease;\n}\n\n.aggregate-item:hover {\n border-color: var(--mj-border-strong);\n}\n\n.aggregate-item.disabled {\n opacity: 0.5;\n}\n\n/* Aggregate Icon */\n.agg-icon {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 32px;\n height: 32px;\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n border-radius: 8px;\n color: var(--mj-brand-primary);\n font-size: 14px;\n flex-shrink: 0;\n}\n\n/* Aggregate Content */\n.agg-content {\n flex: 1;\n min-width: 0;\n}\n\n.agg-label {\n font-size: 13px;\n font-weight: 500;\n color: var(--mj-text-primary);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.agg-details {\n display: flex;\n align-items: center;\n gap: 8px;\n margin-top: 2px;\n}\n\n.agg-type {\n display: flex;\n align-items: center;\n gap: 4px;\n font-size: 11px;\n color: var(--mj-text-muted);\n}\n\n.agg-smart-badge {\n color: var(--mj-brand-primary);\n font-size: 11px;\n}\n\n/* Aggregate Actions */\n.agg-actions {\n display: flex;\n align-items: center;\n gap: 2px;\n opacity: 0;\n transition: opacity 0.15s ease;\n}\n\n.aggregate-item:hover .agg-actions {\n opacity: 1;\n}\n\n.agg-action-btn {\n width: 26px;\n height: 26px;\n border: none;\n background: transparent;\n border-radius: 6px;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n color: var(--mj-text-muted);\n font-size: 12px;\n transition: all 0.15s ease;\n}\n\n.agg-action-btn:hover:not(:disabled) {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-secondary);\n}\n\n.agg-action-btn:disabled {\n opacity: 0.3;\n cursor: not-allowed;\n}\n\n.agg-action-btn.toggle-btn.enabled {\n color: var(--mj-brand-primary);\n}\n\n.agg-action-btn.remove-btn:hover:not(:disabled) {\n background: var(--mj-status-error-bg);\n color: var(--mj-status-error);\n}\n\n.agg-action-btn.edit-btn:hover:not(:disabled) {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n}\n\n/* Aggregates Summary */\n.aggregates-summary {\n display: flex;\n gap: 16px;\n padding: 10px 12px;\n background: var(--mj-bg-surface-card);\n border-radius: 8px;\n margin-bottom: 12px;\n}\n\n.aggregates-summary .summary-item {\n display: flex;\n align-items: center;\n gap: 6px;\n font-size: 12px;\n color: var(--mj-text-muted);\n}\n\n.aggregates-summary .summary-item i {\n color: var(--mj-text-disabled);\n}\n\n/* Settings Tab */\n.form-group {\n margin-bottom: 16px;\n}\n\n.form-group label {\n display: block;\n margin-bottom: 6px;\n font-size: 13px;\n font-weight: 500;\n color: var(--mj-text-secondary);\n}\n\n.form-input {\n width: 100%;\n padding: 8px 12px;\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n font-size: 14px;\n color: var(--mj-text-primary);\n background: var(--mj-bg-surface);\n transition: border-color 0.15s ease;\n box-sizing: border-box;\n}\n\n.form-input:focus {\n outline: none;\n border-color: var(--mj-brand-primary);\n}\n\n.form-input.invalid {\n border-color: var(--mj-status-error);\n}\n\n.form-textarea {\n resize: vertical;\n min-height: 60px;\n font-family: inherit;\n}\n\n.validation-error {\n font-size: 12px;\n color: var(--mj-status-error);\n margin-top: 4px;\n}\n\n/* Checkbox */\n.checkbox-label {\n display: flex;\n align-items: flex-start;\n gap: 10px;\n cursor: pointer;\n}\n\n.checkbox-label input[type=\"checkbox\"] {\n margin-top: 3px;\n flex-shrink: 0;\n}\n\n.checkbox-text {\n display: flex;\n flex-direction: column;\n gap: 2px;\n}\n\n.checkbox-text strong {\n font-size: 13px;\n color: var(--mj-text-primary);\n}\n\n.checkbox-text small {\n font-size: 12px;\n color: var(--mj-text-muted);\n}\n\n/* Danger Zone */\n.danger-zone .section-header {\n color: var(--mj-status-error);\n}\n\n.danger-zone .section-header i {\n color: var(--mj-status-error);\n}\n\n.delete-btn {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 10px 16px;\n border: 1px solid var(--mj-status-error);\n border-radius: 8px;\n background: var(--mj-status-error-bg);\n cursor: pointer;\n font-size: 13px;\n font-weight: 500;\n color: var(--mj-status-error);\n transition: all 0.15s ease;\n}\n\n.delete-btn:hover {\n background: var(--mj-status-error);\n color: var(--mj-text-inverse);\n}\n\n/* Validation Banner */\n.validation-banner {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 10px 16px;\n background: var(--mj-status-error-bg);\n border-top: 1px solid var(--mj-status-error);\n font-size: 13px;\n color: var(--mj-status-error);\n flex-shrink: 0;\n}\n\n/* Panel Footer */\n.panel-footer {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 14px 20px;\n border-top: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface-card);\n flex-shrink: 0;\n}\n\n.footer-left {\n display: flex;\n gap: 8px;\n}\n\n.footer-btn {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 9px 18px;\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n background: var(--mj-bg-surface);\n cursor: pointer;\n font-size: 14px;\n font-weight: 500;\n color: var(--mj-text-secondary);\n transition: all 0.15s ease;\n}\n\n.footer-btn:hover:not(:disabled) {\n border-color: var(--mj-border-strong);\n}\n\n.footer-btn:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.footer-btn.primary {\n background: var(--mj-brand-primary);\n border-color: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n}\n\n.footer-btn.primary:hover:not(:disabled) {\n background: var(--mj-brand-primary-hover);\n border-color: var(--mj-brand-primary-hover);\n}\n\n.footer-btn.cancel-btn {\n background: var(--mj-bg-surface-card);\n}\n\n.footer-btn.cancel-btn:hover {\n background: var(--mj-bg-surface-active);\n}\n\n/* Responsive */\n@media (max-width: 480px) {\n .config-panel {\n width: 100vw;\n min-width: auto;\n }\n\n .resize-handle {\n display: none;\n }\n}\n"] }]
|
|
2858
2858
|
}], () => [{ type: i0.ChangeDetectorRef }], { entity: [{
|
|
2859
2859
|
type: Input
|
|
2860
2860
|
}], viewEntity: [{
|