@memberjunction/ng-record-changes 5.27.1 → 5.29.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.
@@ -1,5 +1,6 @@
1
- import { Component, EventEmitter, Input, Output, ChangeDetectionStrategy, ViewEncapsulation } from '@angular/core';
2
- import { EntityFieldTSType, Metadata, RunView } from '@memberjunction/core';
1
+ import { Component, EventEmitter, Input, Output, ChangeDetectionStrategy, ViewEncapsulation, } from '@angular/core';
2
+ import { EntityFieldTSType, Metadata, RunView, } from '@memberjunction/core';
3
+ import { UUIDsEqual } from '@memberjunction/global';
3
4
  import { diffChars, diffWords } from 'diff';
4
5
  import * as i0 from "@angular/core";
5
6
  import * as i1 from "@memberjunction/ng-notifications";
@@ -7,12 +8,14 @@ import * as i2 from "@angular/platform-browser";
7
8
  import * as i3 from "@angular/forms";
8
9
  import * as i4 from "@memberjunction/ng-shared-generic";
9
10
  import * as i5 from "@memberjunction/ng-versions";
11
+ import * as i6 from "./restore-preview-panel/restore-preview-panel.component";
12
+ import * as i7 from "@angular/common";
10
13
  const _c0 = a0 => [a0];
11
14
  const _forTrack0 = ($index, $item) => $item.ID;
12
- const _forTrack1 = ($index, $item) => $item.label;
13
- const _forTrack2 = ($index, $item) => $item.name;
14
- const _forTrack3 = ($index, $item) => $item.field;
15
- const _forTrack4 = ($index, $item) => $item.FieldName;
15
+ const _forTrack1 = ($index, $item) => $item.Key;
16
+ const _forTrack2 = ($index, $item) => $item.label;
17
+ const _forTrack3 = ($index, $item) => $item.name;
18
+ const _forTrack4 = ($index, $item) => $item.field;
16
19
  function RecordChangesComponent_Conditional_1_Template(rf, ctx) { if (rf & 1) {
17
20
  i0.ɵɵelement(0, "mj-loading", 1);
18
21
  } }
@@ -86,12 +89,120 @@ function RecordChangesComponent_Conditional_2_Conditional_14_Template(rf, ctx) {
86
89
  i0.ɵɵtext(10, "Record change tracking is managed at the entity level");
87
90
  i0.ɵɵelementEnd()()();
88
91
  } }
89
- function RecordChangesComponent_Conditional_2_Conditional_15_Conditional_28_Template(rf, ctx) { if (rf & 1) {
92
+ function RecordChangesComponent_Conditional_2_Conditional_15_Conditional_19_Conditional_0_For_1_Template(rf, ctx) { if (rf & 1) {
90
93
  const _r5 = i0.ɵɵgetCurrentView();
91
- i0.ɵɵelementStart(0, "div", 45);
94
+ i0.ɵɵelementStart(0, "button", 40);
95
+ i0.ɵɵlistener("click", function RecordChangesComponent_Conditional_2_Conditional_15_Conditional_19_Conditional_0_For_1_Template_button_click_0_listener() { const pill_r6 = i0.ɵɵrestoreView(_r5).$implicit; const ctx_r1 = i0.ɵɵnextContext(5); return i0.ɵɵresetView(ctx_r1.TogglePill(pill_r6.Key)); });
96
+ i0.ɵɵelement(1, "i", 47);
97
+ i0.ɵɵtext(2);
98
+ i0.ɵɵelementStart(3, "span", 48);
99
+ i0.ɵɵtext(4);
100
+ i0.ɵɵelementEnd()();
101
+ } if (rf & 2) {
102
+ const pill_r6 = ctx.$implicit;
103
+ const ctx_r1 = i0.ɵɵnextContext(5);
104
+ i0.ɵɵclassProp("active", ctx_r1.ChipSelections[pill_r6.Key])("rc-filter-pill-restore", pill_r6.Variant === "restore");
105
+ i0.ɵɵadvance();
106
+ i0.ɵɵclassMap(i0.ɵɵinterpolate1("fa-solid ", pill_r6.Icon));
107
+ i0.ɵɵadvance();
108
+ i0.ɵɵtextInterpolate1(" ", pill_r6.Label, " ");
109
+ i0.ɵɵadvance(2);
110
+ i0.ɵɵtextInterpolate(pill_r6.Count);
111
+ } }
112
+ function RecordChangesComponent_Conditional_2_Conditional_15_Conditional_19_Conditional_0_Template(rf, ctx) { if (rf & 1) {
113
+ i0.ɵɵrepeaterCreate(0, RecordChangesComponent_Conditional_2_Conditional_15_Conditional_19_Conditional_0_For_1_Template, 5, 9, "button", 46, _forTrack1);
114
+ } if (rf & 2) {
115
+ const ctx_r1 = i0.ɵɵnextContext(4);
116
+ i0.ɵɵrepeater(ctx_r1.ConditionalPills);
117
+ } }
118
+ function RecordChangesComponent_Conditional_2_Conditional_15_Conditional_19_Conditional_1_Conditional_4_Template(rf, ctx) { if (rf & 1) {
119
+ i0.ɵɵelementStart(0, "span", 48);
92
120
  i0.ɵɵtext(1);
93
- i0.ɵɵelementStart(2, "button", 48);
94
- i0.ɵɵlistener("click", function RecordChangesComponent_Conditional_2_Conditional_15_Conditional_28_Template_button_click_2_listener() { i0.ɵɵrestoreView(_r5); const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.ClearFilters()); });
121
+ i0.ɵɵelementEnd();
122
+ } if (rf & 2) {
123
+ const ctx_r1 = i0.ɵɵnextContext(5);
124
+ i0.ɵɵadvance();
125
+ i0.ɵɵtextInterpolate(ctx_r1.SelectedConditionalCount);
126
+ } }
127
+ function RecordChangesComponent_Conditional_2_Conditional_15_Conditional_19_Conditional_1_Conditional_6_For_5_Template(rf, ctx) { if (rf & 1) {
128
+ const _r9 = i0.ɵɵgetCurrentView();
129
+ i0.ɵɵelementStart(0, "label", 59)(1, "input", 60);
130
+ i0.ɵɵlistener("change", function RecordChangesComponent_Conditional_2_Conditional_15_Conditional_19_Conditional_1_Conditional_6_For_5_Template_input_change_1_listener() { const pill_r10 = i0.ɵɵrestoreView(_r9).$implicit; const ctx_r1 = i0.ɵɵnextContext(6); return i0.ɵɵresetView(ctx_r1.TogglePill(pill_r10.Key)); });
131
+ i0.ɵɵelementEnd();
132
+ i0.ɵɵelement(2, "i", 47);
133
+ i0.ɵɵelementStart(3, "span", 61);
134
+ i0.ɵɵtext(4);
135
+ i0.ɵɵelementEnd();
136
+ i0.ɵɵelementStart(5, "span", 62);
137
+ i0.ɵɵtext(6);
138
+ i0.ɵɵelementEnd()();
139
+ } if (rf & 2) {
140
+ const pill_r10 = ctx.$implicit;
141
+ const ctx_r1 = i0.ɵɵnextContext(6);
142
+ i0.ɵɵclassProp("rc-filter-overflow-row-restore", pill_r10.Variant === "restore");
143
+ i0.ɵɵadvance();
144
+ i0.ɵɵproperty("checked", ctx_r1.ChipSelections[pill_r10.Key]);
145
+ i0.ɵɵadvance();
146
+ i0.ɵɵclassMap(i0.ɵɵinterpolate1("fa-solid ", pill_r10.Icon));
147
+ i0.ɵɵadvance(2);
148
+ i0.ɵɵtextInterpolate(pill_r10.Label);
149
+ i0.ɵɵadvance(2);
150
+ i0.ɵɵtextInterpolate(pill_r10.Count);
151
+ } }
152
+ function RecordChangesComponent_Conditional_2_Conditional_15_Conditional_19_Conditional_1_Conditional_6_Template(rf, ctx) { if (rf & 1) {
153
+ const _r8 = i0.ɵɵgetCurrentView();
154
+ i0.ɵɵelementStart(0, "div", 52);
155
+ i0.ɵɵlistener("click", function RecordChangesComponent_Conditional_2_Conditional_15_Conditional_19_Conditional_1_Conditional_6_Template_div_click_0_listener() { i0.ɵɵrestoreView(_r8); const ctx_r1 = i0.ɵɵnextContext(5); return i0.ɵɵresetView(ctx_r1.CloseFilterOverflow()); });
156
+ i0.ɵɵelementEnd();
157
+ i0.ɵɵelementStart(1, "div", 53)(2, "div", 54);
158
+ i0.ɵɵtext(3, "Filter by");
159
+ i0.ɵɵelementEnd();
160
+ i0.ɵɵrepeaterCreate(4, RecordChangesComponent_Conditional_2_Conditional_15_Conditional_19_Conditional_1_Conditional_6_For_5_Template, 7, 8, "label", 55, _forTrack1);
161
+ i0.ɵɵelementStart(6, "div", 56)(7, "button", 57);
162
+ i0.ɵɵlistener("click", function RecordChangesComponent_Conditional_2_Conditional_15_Conditional_19_Conditional_1_Conditional_6_Template_button_click_7_listener() { i0.ɵɵrestoreView(_r8); const ctx_r1 = i0.ɵɵnextContext(5); ctx_r1.SelectAllPill(); return i0.ɵɵresetView(ctx_r1.CloseFilterOverflow()); });
163
+ i0.ɵɵtext(8, " Clear all ");
164
+ i0.ɵɵelementEnd();
165
+ i0.ɵɵelementStart(9, "button", 58);
166
+ i0.ɵɵlistener("click", function RecordChangesComponent_Conditional_2_Conditional_15_Conditional_19_Conditional_1_Conditional_6_Template_button_click_9_listener() { i0.ɵɵrestoreView(_r8); const ctx_r1 = i0.ɵɵnextContext(5); return i0.ɵɵresetView(ctx_r1.CloseFilterOverflow()); });
167
+ i0.ɵɵtext(10, " Done ");
168
+ i0.ɵɵelementEnd()()();
169
+ } if (rf & 2) {
170
+ const ctx_r1 = i0.ɵɵnextContext(5);
171
+ i0.ɵɵadvance(4);
172
+ i0.ɵɵrepeater(ctx_r1.ConditionalPills);
173
+ } }
174
+ function RecordChangesComponent_Conditional_2_Conditional_15_Conditional_19_Conditional_1_Template(rf, ctx) { if (rf & 1) {
175
+ const _r7 = i0.ɵɵgetCurrentView();
176
+ i0.ɵɵelementStart(0, "div", 45)(1, "button", 49);
177
+ i0.ɵɵlistener("click", function RecordChangesComponent_Conditional_2_Conditional_15_Conditional_19_Conditional_1_Template_button_click_1_listener() { i0.ɵɵrestoreView(_r7); const ctx_r1 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r1.ToggleFilterOverflow()); });
178
+ i0.ɵɵelement(2, "i", 50);
179
+ i0.ɵɵtext(3, " More filters ");
180
+ i0.ɵɵconditionalCreate(4, RecordChangesComponent_Conditional_2_Conditional_15_Conditional_19_Conditional_1_Conditional_4_Template, 2, 1, "span", 48);
181
+ i0.ɵɵelement(5, "i", 51);
182
+ i0.ɵɵelementEnd();
183
+ i0.ɵɵconditionalCreate(6, RecordChangesComponent_Conditional_2_Conditional_15_Conditional_19_Conditional_1_Conditional_6_Template, 11, 0);
184
+ i0.ɵɵelementEnd();
185
+ } if (rf & 2) {
186
+ const ctx_r1 = i0.ɵɵnextContext(4);
187
+ i0.ɵɵadvance();
188
+ i0.ɵɵclassProp("active", ctx_r1.SelectedConditionalCount > 0);
189
+ i0.ɵɵadvance(3);
190
+ i0.ɵɵconditional(ctx_r1.SelectedConditionalCount > 0 ? 4 : -1);
191
+ i0.ɵɵadvance(2);
192
+ i0.ɵɵconditional(ctx_r1.ShowFilterOverflow ? 6 : -1);
193
+ } }
194
+ function RecordChangesComponent_Conditional_2_Conditional_15_Conditional_19_Template(rf, ctx) { if (rf & 1) {
195
+ i0.ɵɵconditionalCreate(0, RecordChangesComponent_Conditional_2_Conditional_15_Conditional_19_Conditional_0_Template, 2, 0)(1, RecordChangesComponent_Conditional_2_Conditional_15_Conditional_19_Conditional_1_Template, 7, 4, "div", 45);
196
+ } if (rf & 2) {
197
+ const ctx_r1 = i0.ɵɵnextContext(3);
198
+ i0.ɵɵconditional(!ctx_r1.UseOverflowPopover ? 0 : 1);
199
+ } }
200
+ function RecordChangesComponent_Conditional_2_Conditional_15_Conditional_20_Template(rf, ctx) { if (rf & 1) {
201
+ const _r11 = i0.ɵɵgetCurrentView();
202
+ i0.ɵɵelementStart(0, "div", 42);
203
+ i0.ɵɵtext(1);
204
+ i0.ɵɵelementStart(2, "button", 63);
205
+ i0.ɵɵlistener("click", function RecordChangesComponent_Conditional_2_Conditional_15_Conditional_20_Template_button_click_2_listener() { i0.ɵɵrestoreView(_r11); const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.ClearFilters()); });
95
206
  i0.ɵɵtext(3, "Clear filters");
96
207
  i0.ɵɵelementEnd()();
97
208
  } if (rf & 2) {
@@ -99,254 +210,314 @@ function RecordChangesComponent_Conditional_2_Conditional_15_Conditional_28_Temp
99
210
  i0.ɵɵadvance();
100
211
  i0.ɵɵtextInterpolate2(" Showing ", ctx_r1.filteredData.length, " of ", ctx_r1.viewData.length, " changes ");
101
212
  } }
102
- function RecordChangesComponent_Conditional_2_Conditional_15_Conditional_30_Template(rf, ctx) { if (rf & 1) {
103
- const _r6 = i0.ɵɵgetCurrentView();
104
- i0.ɵɵelementStart(0, "div", 47);
105
- i0.ɵɵelement(1, "i", 49);
213
+ function RecordChangesComponent_Conditional_2_Conditional_15_Conditional_22_Template(rf, ctx) { if (rf & 1) {
214
+ const _r12 = i0.ɵɵgetCurrentView();
215
+ i0.ɵɵelementStart(0, "div", 44);
216
+ i0.ɵɵelement(1, "i", 64);
106
217
  i0.ɵɵelementStart(2, "p");
107
218
  i0.ɵɵtext(3, "No changes match your current filters.");
108
219
  i0.ɵɵelementEnd();
109
- i0.ɵɵelementStart(4, "button", 50);
110
- i0.ɵɵlistener("click", function RecordChangesComponent_Conditional_2_Conditional_15_Conditional_30_Template_button_click_4_listener() { i0.ɵɵrestoreView(_r6); const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.ClearFilters()); });
111
- i0.ɵɵelement(5, "i", 51);
220
+ i0.ɵɵelementStart(4, "button", 65);
221
+ i0.ɵɵlistener("click", function RecordChangesComponent_Conditional_2_Conditional_15_Conditional_22_Template_button_click_4_listener() { i0.ɵɵrestoreView(_r12); const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.ClearFilters()); });
222
+ i0.ɵɵelement(5, "i", 66);
112
223
  i0.ɵɵtext(6, " Clear Filters ");
113
224
  i0.ɵɵelementEnd()();
114
225
  } }
115
- function RecordChangesComponent_Conditional_2_Conditional_15_Conditional_31_For_1_For_4_Conditional_19_Conditional_1_Conditional_0_For_1_Template(rf, ctx) { if (rf & 1) {
116
- i0.ɵɵelementStart(0, "div", 72)(1, "div", 73);
226
+ function RecordChangesComponent_Conditional_2_Conditional_15_Conditional_23_For_1_For_4_Conditional_7_Conditional_0_Conditional_4_Template(rf, ctx) { if (rf & 1) {
227
+ i0.ɵɵtext(0);
228
+ } if (rf & 2) {
229
+ const srcChange_r16 = i0.ɵɵnextContext();
230
+ const ctx_r1 = i0.ɵɵnextContext(7);
231
+ i0.ɵɵtextInterpolate1(" by ", ctx_r1.getUserDisplayName(srcChange_r16.User), " ");
232
+ } }
233
+ function RecordChangesComponent_Conditional_2_Conditional_15_Conditional_23_For_1_For_4_Conditional_7_Conditional_0_Template(rf, ctx) { if (rf & 1) {
234
+ const _r15 = i0.ɵɵgetCurrentView();
235
+ i0.ɵɵelementStart(0, "a", 85);
236
+ i0.ɵɵlistener("click", function RecordChangesComponent_Conditional_2_Conditional_15_Conditional_23_For_1_For_4_Conditional_7_Conditional_0_Template_a_click_0_listener($event) { const srcChange_r16 = i0.ɵɵrestoreView(_r15); const ctx_r1 = i0.ɵɵnextContext(7); return i0.ɵɵresetView(ctx_r1.JumpToSourceChange(srcChange_r16, $event)); });
237
+ i0.ɵɵelement(1, "i", 86);
238
+ i0.ɵɵtext(2);
239
+ i0.ɵɵpipe(3, "date");
240
+ i0.ɵɵconditionalCreate(4, RecordChangesComponent_Conditional_2_Conditional_15_Conditional_23_For_1_For_4_Conditional_7_Conditional_0_Conditional_4_Template, 1, 1);
241
+ i0.ɵɵelementEnd();
242
+ } if (rf & 2) {
243
+ const srcChange_r16 = ctx;
244
+ const ctx_r1 = i0.ɵɵnextContext(7);
245
+ i0.ɵɵproperty("title", "Jump to source version (" + ctx_r1.formatFullDateTime(srcChange_r16.ChangedAt) + ")");
246
+ i0.ɵɵadvance(2);
247
+ i0.ɵɵtextInterpolate2(" Restored from ", ctx_r1.formatTime(srcChange_r16.ChangedAt), " ", srcChange_r16.ChangedAt ? "on " + i0.ɵɵpipeBind2(3, 4, srcChange_r16.ChangedAt, "mediumDate") : "", " ");
248
+ i0.ɵɵadvance(2);
249
+ i0.ɵɵconditional(srcChange_r16.User ? 4 : -1);
250
+ } }
251
+ function RecordChangesComponent_Conditional_2_Conditional_15_Conditional_23_For_1_For_4_Conditional_7_Conditional_1_Template(rf, ctx) { if (rf & 1) {
252
+ i0.ɵɵelementStart(0, "span", 84);
253
+ i0.ɵɵelement(1, "i", 87);
254
+ i0.ɵɵtext(2, " Restored from earlier version ");
255
+ i0.ɵɵelementEnd();
256
+ } }
257
+ function RecordChangesComponent_Conditional_2_Conditional_15_Conditional_23_For_1_For_4_Conditional_7_Template(rf, ctx) { if (rf & 1) {
258
+ i0.ɵɵconditionalCreate(0, RecordChangesComponent_Conditional_2_Conditional_15_Conditional_23_For_1_For_4_Conditional_7_Conditional_0_Template, 5, 7, "a", 83)(1, RecordChangesComponent_Conditional_2_Conditional_15_Conditional_23_For_1_For_4_Conditional_7_Conditional_1_Template, 3, 0, "span", 84);
259
+ } if (rf & 2) {
260
+ let tmp_24_0;
261
+ const change_r14 = i0.ɵɵnextContext().$implicit;
262
+ const ctx_r1 = i0.ɵɵnextContext(5);
263
+ i0.ɵɵconditional((tmp_24_0 = ctx_r1.getRestoredFromSourceChange(change_r14)) ? 0 : 1, tmp_24_0);
264
+ } }
265
+ function RecordChangesComponent_Conditional_2_Conditional_15_Conditional_23_For_1_For_4_Conditional_20_Conditional_1_Template(rf, ctx) { if (rf & 1) {
266
+ i0.ɵɵelementStart(0, "blockquote", 88)(1, "span", 93);
267
+ i0.ɵɵtext(2, "Reason");
268
+ i0.ɵɵelementEnd();
269
+ i0.ɵɵelementStart(3, "span", 94);
270
+ i0.ɵɵtext(4);
271
+ i0.ɵɵelementEnd()();
272
+ } if (rf & 2) {
273
+ i0.ɵɵadvance(4);
274
+ i0.ɵɵtextInterpolate(ctx);
275
+ } }
276
+ function RecordChangesComponent_Conditional_2_Conditional_15_Conditional_23_For_1_For_4_Conditional_20_Conditional_2_Conditional_0_For_1_Template(rf, ctx) { if (rf & 1) {
277
+ i0.ɵɵelementStart(0, "div", 95)(1, "div", 96);
117
278
  i0.ɵɵtext(2);
118
279
  i0.ɵɵelementEnd();
119
- i0.ɵɵelementStart(3, "div", 74)(4, "span", 75);
280
+ i0.ɵɵelementStart(3, "div", 97)(4, "span", 98);
120
281
  i0.ɵɵtext(5);
121
282
  i0.ɵɵelementEnd()()();
122
283
  } if (rf & 2) {
123
- const field_r9 = ctx.$implicit;
284
+ const field_r17 = ctx.$implicit;
124
285
  i0.ɵɵadvance(2);
125
- i0.ɵɵtextInterpolate(field_r9.displayName);
286
+ i0.ɵɵtextInterpolate(field_r17.displayName);
126
287
  i0.ɵɵadvance(3);
127
- i0.ɵɵtextInterpolate(field_r9.value);
288
+ i0.ɵɵtextInterpolate(field_r17.value);
128
289
  } }
129
- function RecordChangesComponent_Conditional_2_Conditional_15_Conditional_31_For_1_For_4_Conditional_19_Conditional_1_Conditional_0_Template(rf, ctx) { if (rf & 1) {
130
- i0.ɵɵrepeaterCreate(0, RecordChangesComponent_Conditional_2_Conditional_15_Conditional_31_For_1_For_4_Conditional_19_Conditional_1_Conditional_0_For_1_Template, 6, 2, "div", 72, _forTrack2);
290
+ function RecordChangesComponent_Conditional_2_Conditional_15_Conditional_23_For_1_For_4_Conditional_20_Conditional_2_Conditional_0_Template(rf, ctx) { if (rf & 1) {
291
+ i0.ɵɵrepeaterCreate(0, RecordChangesComponent_Conditional_2_Conditional_15_Conditional_23_For_1_For_4_Conditional_20_Conditional_2_Conditional_0_For_1_Template, 6, 2, "div", 95, _forTrack3);
131
292
  } if (rf & 2) {
132
- const change_r8 = i0.ɵɵnextContext(3).$implicit;
293
+ const change_r14 = i0.ɵɵnextContext(3).$implicit;
133
294
  const ctx_r1 = i0.ɵɵnextContext(5);
134
- i0.ɵɵrepeater(ctx_r1.getCreatedFields(change_r8));
295
+ i0.ɵɵrepeater(ctx_r1.getCreatedFields(change_r14));
135
296
  } }
136
- function RecordChangesComponent_Conditional_2_Conditional_15_Conditional_31_For_1_For_4_Conditional_19_Conditional_1_Template(rf, ctx) { if (rf & 1) {
137
- i0.ɵɵconditionalCreate(0, RecordChangesComponent_Conditional_2_Conditional_15_Conditional_31_For_1_For_4_Conditional_19_Conditional_1_Conditional_0_Template, 2, 0);
297
+ function RecordChangesComponent_Conditional_2_Conditional_15_Conditional_23_For_1_For_4_Conditional_20_Conditional_2_Template(rf, ctx) { if (rf & 1) {
298
+ i0.ɵɵconditionalCreate(0, RecordChangesComponent_Conditional_2_Conditional_15_Conditional_23_For_1_For_4_Conditional_20_Conditional_2_Conditional_0_Template, 2, 0);
138
299
  } if (rf & 2) {
139
- const change_r8 = i0.ɵɵnextContext(2).$implicit;
140
- i0.ɵɵconditional(change_r8.FullRecordJSON ? 0 : -1);
300
+ const change_r14 = i0.ɵɵnextContext(2).$implicit;
301
+ i0.ɵɵconditional(change_r14.FullRecordJSON ? 0 : -1);
141
302
  } }
142
- function RecordChangesComponent_Conditional_2_Conditional_15_Conditional_31_For_1_For_4_Conditional_19_Conditional_2_Template(rf, ctx) { if (rf & 1) {
143
- i0.ɵɵelementStart(0, "div", 68);
144
- i0.ɵɵelement(1, "i", 44);
303
+ function RecordChangesComponent_Conditional_2_Conditional_15_Conditional_23_For_1_For_4_Conditional_20_Conditional_3_Template(rf, ctx) { if (rf & 1) {
304
+ i0.ɵɵelementStart(0, "div", 89);
305
+ i0.ɵɵelement(1, "i", 99);
145
306
  i0.ɵɵtext(2, " This record was permanently removed from the system. ");
146
307
  i0.ɵɵelementEnd();
147
308
  } }
148
- function RecordChangesComponent_Conditional_2_Conditional_15_Conditional_31_For_1_For_4_Conditional_19_Conditional_3_For_1_Conditional_4_Template(rf, ctx) { if (rf & 1) {
149
- i0.ɵɵelementStart(0, "div", 76);
150
- i0.ɵɵelement(1, "span", 79);
151
- i0.ɵɵelementStart(2, "span", 80);
309
+ function RecordChangesComponent_Conditional_2_Conditional_15_Conditional_23_For_1_For_4_Conditional_20_Conditional_4_For_1_Conditional_4_Template(rf, ctx) { if (rf & 1) {
310
+ i0.ɵɵelementStart(0, "div", 100);
311
+ i0.ɵɵelement(1, "span", 103);
312
+ i0.ɵɵelementStart(2, "span", 104);
152
313
  i0.ɵɵtext(3);
153
314
  i0.ɵɵelementEnd();
154
- i0.ɵɵelement(4, "i", 81)(5, "span", 79);
155
- i0.ɵɵelementStart(6, "span", 82);
315
+ i0.ɵɵelement(4, "i", 105)(5, "span", 103);
316
+ i0.ɵɵelementStart(6, "span", 106);
156
317
  i0.ɵɵtext(7);
157
318
  i0.ɵɵelementEnd()();
158
319
  } if (rf & 2) {
159
- const fc_r10 = i0.ɵɵnextContext().$implicit;
320
+ const fc_r18 = i0.ɵɵnextContext().$implicit;
160
321
  i0.ɵɵadvance();
161
- i0.ɵɵclassProp("on", fc_r10.oldValue === "true" || fc_r10.oldValue === "1")("off", fc_r10.oldValue !== "true" && fc_r10.oldValue !== "1");
322
+ i0.ɵɵclassProp("on", fc_r18.oldValue === "true" || fc_r18.oldValue === "1")("off", fc_r18.oldValue !== "true" && fc_r18.oldValue !== "1");
162
323
  i0.ɵɵadvance(2);
163
- i0.ɵɵtextInterpolate(fc_r10.oldValue === "true" || fc_r10.oldValue === "1" ? "Yes" : "No");
324
+ i0.ɵɵtextInterpolate(fc_r18.oldValue === "true" || fc_r18.oldValue === "1" ? "Yes" : "No");
164
325
  i0.ɵɵadvance(2);
165
- i0.ɵɵclassProp("on", fc_r10.newValue === "true" || fc_r10.newValue === "1")("off", fc_r10.newValue !== "true" && fc_r10.newValue !== "1");
326
+ i0.ɵɵclassProp("on", fc_r18.newValue === "true" || fc_r18.newValue === "1")("off", fc_r18.newValue !== "true" && fc_r18.newValue !== "1");
166
327
  i0.ɵɵadvance();
167
- i0.ɵɵclassProp("active", fc_r10.newValue === "true" || fc_r10.newValue === "1")("inactive", fc_r10.newValue !== "true" && fc_r10.newValue !== "1");
328
+ i0.ɵɵclassProp("active", fc_r18.newValue === "true" || fc_r18.newValue === "1")("inactive", fc_r18.newValue !== "true" && fc_r18.newValue !== "1");
168
329
  i0.ɵɵadvance();
169
- i0.ɵɵtextInterpolate(fc_r10.newValue === "true" || fc_r10.newValue === "1" ? "Yes" : "No");
330
+ i0.ɵɵtextInterpolate(fc_r18.newValue === "true" || fc_r18.newValue === "1" ? "Yes" : "No");
170
331
  } }
171
- function RecordChangesComponent_Conditional_2_Conditional_15_Conditional_31_For_1_For_4_Conditional_19_Conditional_3_For_1_Conditional_5_Template(rf, ctx) { if (rf & 1) {
172
- i0.ɵɵelementStart(0, "div", 77)(1, "span", 83);
332
+ function RecordChangesComponent_Conditional_2_Conditional_15_Conditional_23_For_1_For_4_Conditional_20_Conditional_4_For_1_Conditional_5_Template(rf, ctx) { if (rf & 1) {
333
+ i0.ɵɵelementStart(0, "div", 101)(1, "span", 107);
173
334
  i0.ɵɵtext(2);
174
335
  i0.ɵɵelementEnd();
175
- i0.ɵɵelement(3, "i", 81);
176
- i0.ɵɵelementStart(4, "span", 75);
336
+ i0.ɵɵelement(3, "i", 105);
337
+ i0.ɵɵelementStart(4, "span", 98);
177
338
  i0.ɵɵtext(5);
178
339
  i0.ɵɵelementEnd()();
179
340
  } if (rf & 2) {
180
- const fc_r10 = i0.ɵɵnextContext().$implicit;
341
+ const fc_r18 = i0.ɵɵnextContext().$implicit;
181
342
  i0.ɵɵadvance(2);
182
- i0.ɵɵtextInterpolate(fc_r10.oldValue || "(empty)");
343
+ i0.ɵɵtextInterpolate(fc_r18.oldValue || "(empty)");
183
344
  i0.ɵɵadvance(3);
184
- i0.ɵɵtextInterpolate(fc_r10.newValue || "(empty)");
345
+ i0.ɵɵtextInterpolate(fc_r18.newValue || "(empty)");
185
346
  } }
186
- function RecordChangesComponent_Conditional_2_Conditional_15_Conditional_31_For_1_For_4_Conditional_19_Conditional_3_For_1_Conditional_6_Template(rf, ctx) { if (rf & 1) {
187
- i0.ɵɵelement(0, "div", 78);
347
+ function RecordChangesComponent_Conditional_2_Conditional_15_Conditional_23_For_1_For_4_Conditional_20_Conditional_4_For_1_Conditional_6_Template(rf, ctx) { if (rf & 1) {
348
+ i0.ɵɵelement(0, "div", 102);
188
349
  } if (rf & 2) {
189
- const fc_r10 = i0.ɵɵnextContext().$implicit;
190
- i0.ɵɵproperty("innerHTML", fc_r10.diffHtml, i0.ɵɵsanitizeHtml);
350
+ const fc_r18 = i0.ɵɵnextContext().$implicit;
351
+ i0.ɵɵproperty("innerHTML", fc_r18.diffHtml, i0.ɵɵsanitizeHtml);
191
352
  } }
192
- function RecordChangesComponent_Conditional_2_Conditional_15_Conditional_31_For_1_For_4_Conditional_19_Conditional_3_For_1_Conditional_7_Template(rf, ctx) { if (rf & 1) {
193
- i0.ɵɵelementStart(0, "div", 77)(1, "span", 83);
353
+ function RecordChangesComponent_Conditional_2_Conditional_15_Conditional_23_For_1_For_4_Conditional_20_Conditional_4_For_1_Conditional_7_Template(rf, ctx) { if (rf & 1) {
354
+ i0.ɵɵelementStart(0, "div", 101)(1, "span", 107);
194
355
  i0.ɵɵtext(2);
195
356
  i0.ɵɵelementEnd();
196
- i0.ɵɵelement(3, "i", 81);
197
- i0.ɵɵelementStart(4, "span", 75);
357
+ i0.ɵɵelement(3, "i", 105);
358
+ i0.ɵɵelementStart(4, "span", 98);
198
359
  i0.ɵɵtext(5);
199
360
  i0.ɵɵelementEnd()();
200
361
  } if (rf & 2) {
201
- const fc_r10 = i0.ɵɵnextContext().$implicit;
362
+ const fc_r18 = i0.ɵɵnextContext().$implicit;
202
363
  i0.ɵɵadvance(2);
203
- i0.ɵɵtextInterpolate(fc_r10.oldValue || "(empty)");
364
+ i0.ɵɵtextInterpolate(fc_r18.oldValue || "(empty)");
204
365
  i0.ɵɵadvance(3);
205
- i0.ɵɵtextInterpolate(fc_r10.newValue || "(empty)");
366
+ i0.ɵɵtextInterpolate(fc_r18.newValue || "(empty)");
206
367
  } }
207
- function RecordChangesComponent_Conditional_2_Conditional_15_Conditional_31_For_1_For_4_Conditional_19_Conditional_3_For_1_Template(rf, ctx) { if (rf & 1) {
208
- i0.ɵɵelementStart(0, "div", 72)(1, "div", 73);
368
+ function RecordChangesComponent_Conditional_2_Conditional_15_Conditional_23_For_1_For_4_Conditional_20_Conditional_4_For_1_Template(rf, ctx) { if (rf & 1) {
369
+ i0.ɵɵelementStart(0, "div", 95)(1, "div", 96);
209
370
  i0.ɵɵtext(2);
210
371
  i0.ɵɵelementEnd();
211
- i0.ɵɵelementStart(3, "div", 74);
212
- i0.ɵɵconditionalCreate(4, RecordChangesComponent_Conditional_2_Conditional_15_Conditional_31_For_1_For_4_Conditional_19_Conditional_3_For_1_Conditional_4_Template, 8, 14, "div", 76)(5, RecordChangesComponent_Conditional_2_Conditional_15_Conditional_31_For_1_For_4_Conditional_19_Conditional_3_For_1_Conditional_5_Template, 6, 2, "div", 77)(6, RecordChangesComponent_Conditional_2_Conditional_15_Conditional_31_For_1_For_4_Conditional_19_Conditional_3_For_1_Conditional_6_Template, 1, 1, "div", 78)(7, RecordChangesComponent_Conditional_2_Conditional_15_Conditional_31_For_1_For_4_Conditional_19_Conditional_3_For_1_Conditional_7_Template, 6, 2, "div", 77);
372
+ i0.ɵɵelementStart(3, "div", 97);
373
+ i0.ɵɵconditionalCreate(4, RecordChangesComponent_Conditional_2_Conditional_15_Conditional_23_For_1_For_4_Conditional_20_Conditional_4_For_1_Conditional_4_Template, 8, 14, "div", 100)(5, RecordChangesComponent_Conditional_2_Conditional_15_Conditional_23_For_1_For_4_Conditional_20_Conditional_4_For_1_Conditional_5_Template, 6, 2, "div", 101)(6, RecordChangesComponent_Conditional_2_Conditional_15_Conditional_23_For_1_For_4_Conditional_20_Conditional_4_For_1_Conditional_6_Template, 1, 1, "div", 102)(7, RecordChangesComponent_Conditional_2_Conditional_15_Conditional_23_For_1_For_4_Conditional_20_Conditional_4_For_1_Conditional_7_Template, 6, 2, "div", 101);
213
374
  i0.ɵɵelementEnd()();
214
375
  } if (rf & 2) {
215
- const fc_r10 = ctx.$implicit;
376
+ const fc_r18 = ctx.$implicit;
216
377
  i0.ɵɵadvance(2);
217
- i0.ɵɵtextInterpolate(fc_r10.displayName);
378
+ i0.ɵɵtextInterpolate(fc_r18.displayName);
218
379
  i0.ɵɵadvance(2);
219
- i0.ɵɵconditional(fc_r10.fieldType === "boolean" ? 4 : fc_r10.fieldType === "date" || fc_r10.fieldType === "number" ? 5 : fc_r10.diffHtml ? 6 : 7);
380
+ i0.ɵɵconditional(fc_r18.fieldType === "boolean" ? 4 : fc_r18.fieldType === "date" || fc_r18.fieldType === "number" ? 5 : fc_r18.diffHtml ? 6 : 7);
220
381
  } }
221
- function RecordChangesComponent_Conditional_2_Conditional_15_Conditional_31_For_1_For_4_Conditional_19_Conditional_3_Template(rf, ctx) { if (rf & 1) {
222
- i0.ɵɵrepeaterCreate(0, RecordChangesComponent_Conditional_2_Conditional_15_Conditional_31_For_1_For_4_Conditional_19_Conditional_3_For_1_Template, 8, 2, "div", 72, _forTrack3);
382
+ function RecordChangesComponent_Conditional_2_Conditional_15_Conditional_23_For_1_For_4_Conditional_20_Conditional_4_Template(rf, ctx) { if (rf & 1) {
383
+ i0.ɵɵrepeaterCreate(0, RecordChangesComponent_Conditional_2_Conditional_15_Conditional_23_For_1_For_4_Conditional_20_Conditional_4_For_1_Template, 8, 2, "div", 95, _forTrack4);
223
384
  } if (rf & 2) {
224
- const change_r8 = i0.ɵɵnextContext(2).$implicit;
385
+ const change_r14 = i0.ɵɵnextContext(2).$implicit;
225
386
  const ctx_r1 = i0.ɵɵnextContext(5);
226
- i0.ɵɵrepeater(ctx_r1.getFieldChanges(change_r8));
387
+ i0.ɵɵrepeater(ctx_r1.getFieldChanges(change_r14));
227
388
  } }
228
- function RecordChangesComponent_Conditional_2_Conditional_15_Conditional_31_For_1_For_4_Conditional_19_Conditional_4_Template(rf, ctx) { if (rf & 1) {
229
- i0.ɵɵelementStart(0, "div", 69);
230
- i0.ɵɵelement(1, "i", 84);
389
+ function RecordChangesComponent_Conditional_2_Conditional_15_Conditional_23_For_1_For_4_Conditional_20_Conditional_5_Template(rf, ctx) { if (rf & 1) {
390
+ i0.ɵɵelementStart(0, "div", 90);
391
+ i0.ɵɵelement(1, "i", 108);
231
392
  i0.ɵɵtext(2);
232
393
  i0.ɵɵelementEnd();
233
394
  } if (rf & 2) {
234
- const change_r8 = i0.ɵɵnextContext(2).$implicit;
395
+ const change_r14 = i0.ɵɵnextContext(2).$implicit;
235
396
  i0.ɵɵadvance(2);
236
- i0.ɵɵtextInterpolate1(" ", change_r8.Comments, " ");
397
+ i0.ɵɵtextInterpolate1(" ", change_r14.Comments, " ");
237
398
  } }
238
- function RecordChangesComponent_Conditional_2_Conditional_15_Conditional_31_For_1_For_4_Conditional_19_Conditional_5_Template(rf, ctx) { if (rf & 1) {
239
- i0.ɵɵelementStart(0, "div", 70);
240
- i0.ɵɵelement(1, "i", 85);
241
- i0.ɵɵelementStart(2, "pre", 86);
399
+ function RecordChangesComponent_Conditional_2_Conditional_15_Conditional_23_For_1_For_4_Conditional_20_Conditional_6_Template(rf, ctx) { if (rf & 1) {
400
+ i0.ɵɵelementStart(0, "div", 91);
401
+ i0.ɵɵelement(1, "i", 109);
402
+ i0.ɵɵelementStart(2, "pre", 110);
242
403
  i0.ɵɵtext(3);
243
404
  i0.ɵɵelementEnd()();
244
405
  } if (rf & 2) {
245
- const change_r8 = i0.ɵɵnextContext(2).$implicit;
406
+ const change_r14 = i0.ɵɵnextContext(2).$implicit;
246
407
  i0.ɵɵadvance(3);
247
- i0.ɵɵtextInterpolate(change_r8.ErrorLog);
408
+ i0.ɵɵtextInterpolate(change_r14.ErrorLog);
248
409
  } }
249
- function RecordChangesComponent_Conditional_2_Conditional_15_Conditional_31_For_1_For_4_Conditional_19_Conditional_6_Template(rf, ctx) { if (rf & 1) {
250
- const _r11 = i0.ɵɵgetCurrentView();
251
- i0.ɵɵelementStart(0, "div", 71)(1, "button", 87);
252
- i0.ɵɵlistener("click", function RecordChangesComponent_Conditional_2_Conditional_15_Conditional_31_For_1_For_4_Conditional_19_Conditional_6_Template_button_click_1_listener($event) { i0.ɵɵrestoreView(_r11); const change_r8 = i0.ɵɵnextContext(2).$implicit; const ctx_r1 = i0.ɵɵnextContext(5); return i0.ɵɵresetView(ctx_r1.OnRestoreVersion(change_r8, $event)); });
253
- i0.ɵɵelement(2, "i", 88);
254
- i0.ɵɵtext(3, " Restore Previous Values ");
410
+ function RecordChangesComponent_Conditional_2_Conditional_15_Conditional_23_For_1_For_4_Conditional_20_Conditional_7_Template(rf, ctx) { if (rf & 1) {
411
+ const _r19 = i0.ɵɵgetCurrentView();
412
+ i0.ɵɵelementStart(0, "div", 92)(1, "button", 111);
413
+ i0.ɵɵlistener("click", function RecordChangesComponent_Conditional_2_Conditional_15_Conditional_23_For_1_For_4_Conditional_20_Conditional_7_Template_button_click_1_listener($event) { i0.ɵɵrestoreView(_r19); const change_r14 = i0.ɵɵnextContext(2).$implicit; const ctx_r1 = i0.ɵɵnextContext(5); return i0.ɵɵresetView(ctx_r1.OnRestoreVersion(change_r14, $event)); });
414
+ i0.ɵɵelement(2, "i", 87);
415
+ i0.ɵɵtext(3, " Restore record to this version ");
255
416
  i0.ɵɵelementEnd()();
256
417
  } }
257
- function RecordChangesComponent_Conditional_2_Conditional_15_Conditional_31_For_1_For_4_Conditional_19_Template(rf, ctx) { if (rf & 1) {
258
- i0.ɵɵelementStart(0, "div", 67);
259
- i0.ɵɵconditionalCreate(1, RecordChangesComponent_Conditional_2_Conditional_15_Conditional_31_For_1_For_4_Conditional_19_Conditional_1_Template, 1, 1)(2, RecordChangesComponent_Conditional_2_Conditional_15_Conditional_31_For_1_For_4_Conditional_19_Conditional_2_Template, 3, 0, "div", 68)(3, RecordChangesComponent_Conditional_2_Conditional_15_Conditional_31_For_1_For_4_Conditional_19_Conditional_3_Template, 2, 0);
260
- i0.ɵɵconditionalCreate(4, RecordChangesComponent_Conditional_2_Conditional_15_Conditional_31_For_1_For_4_Conditional_19_Conditional_4_Template, 3, 1, "div", 69);
261
- i0.ɵɵconditionalCreate(5, RecordChangesComponent_Conditional_2_Conditional_15_Conditional_31_For_1_For_4_Conditional_19_Conditional_5_Template, 4, 1, "div", 70);
262
- i0.ɵɵconditionalCreate(6, RecordChangesComponent_Conditional_2_Conditional_15_Conditional_31_For_1_For_4_Conditional_19_Conditional_6_Template, 4, 0, "div", 71);
418
+ function RecordChangesComponent_Conditional_2_Conditional_15_Conditional_23_For_1_For_4_Conditional_20_Template(rf, ctx) { if (rf & 1) {
419
+ i0.ɵɵelementStart(0, "div", 82);
420
+ i0.ɵɵconditionalCreate(1, RecordChangesComponent_Conditional_2_Conditional_15_Conditional_23_For_1_For_4_Conditional_20_Conditional_1_Template, 5, 1, "blockquote", 88);
421
+ i0.ɵɵconditionalCreate(2, RecordChangesComponent_Conditional_2_Conditional_15_Conditional_23_For_1_For_4_Conditional_20_Conditional_2_Template, 1, 1)(3, RecordChangesComponent_Conditional_2_Conditional_15_Conditional_23_For_1_For_4_Conditional_20_Conditional_3_Template, 3, 0, "div", 89)(4, RecordChangesComponent_Conditional_2_Conditional_15_Conditional_23_For_1_For_4_Conditional_20_Conditional_4_Template, 2, 0);
422
+ i0.ɵɵconditionalCreate(5, RecordChangesComponent_Conditional_2_Conditional_15_Conditional_23_For_1_For_4_Conditional_20_Conditional_5_Template, 3, 1, "div", 90);
423
+ i0.ɵɵconditionalCreate(6, RecordChangesComponent_Conditional_2_Conditional_15_Conditional_23_For_1_For_4_Conditional_20_Conditional_6_Template, 4, 1, "div", 91);
424
+ i0.ɵɵconditionalCreate(7, RecordChangesComponent_Conditional_2_Conditional_15_Conditional_23_For_1_For_4_Conditional_20_Conditional_7_Template, 4, 0, "div", 92);
263
425
  i0.ɵɵelementEnd();
264
426
  } if (rf & 2) {
265
- const change_r8 = i0.ɵɵnextContext().$implicit;
427
+ let tmp_24_0;
428
+ const change_r14 = i0.ɵɵnextContext().$implicit;
266
429
  const ctx_r1 = i0.ɵɵnextContext(5);
267
430
  i0.ɵɵadvance();
268
- i0.ɵɵconditional(change_r8.Type === "Create" ? 1 : change_r8.Type === "Delete" ? 2 : 3);
431
+ i0.ɵɵconditional((tmp_24_0 = ctx_r1.getRestoreReason(change_r14)) ? 1 : -1, tmp_24_0);
432
+ i0.ɵɵadvance();
433
+ i0.ɵɵconditional(change_r14.Type === "Create" ? 2 : change_r14.Type === "Delete" ? 3 : 4);
269
434
  i0.ɵɵadvance(3);
270
- i0.ɵɵconditional(change_r8.Comments ? 4 : -1);
435
+ i0.ɵɵconditional(change_r14.Comments ? 5 : -1);
271
436
  i0.ɵɵadvance();
272
- i0.ɵɵconditional(change_r8.ErrorLog ? 5 : -1);
437
+ i0.ɵɵconditional(change_r14.ErrorLog ? 6 : -1);
273
438
  i0.ɵɵadvance();
274
- i0.ɵɵconditional(ctx_r1.AllowRestore && change_r8.Type === "Update" ? 6 : -1);
439
+ i0.ɵɵconditional(ctx_r1.AllowRestore && change_r14.Type !== "Delete" && !ctx_r1.isMostRecentChange(change_r14) ? 7 : -1);
275
440
  } }
276
- function RecordChangesComponent_Conditional_2_Conditional_15_Conditional_31_For_1_For_4_Template(rf, ctx) { if (rf & 1) {
277
- const _r7 = i0.ɵɵgetCurrentView();
278
- i0.ɵɵelementStart(0, "div", 55);
279
- i0.ɵɵlistener("keydown", function RecordChangesComponent_Conditional_2_Conditional_15_Conditional_31_For_1_For_4_Template_div_keydown_0_listener($event) { const change_r8 = i0.ɵɵrestoreView(_r7).$implicit; const ctx_r1 = i0.ɵɵnextContext(5); return i0.ɵɵresetView(ctx_r1.onTimelineItemKeydown($event, change_r8.ID)); });
280
- i0.ɵɵelementStart(1, "div", 56);
281
- i0.ɵɵlistener("click", function RecordChangesComponent_Conditional_2_Conditional_15_Conditional_31_For_1_For_4_Template_div_click_1_listener() { const change_r8 = i0.ɵɵrestoreView(_r7).$implicit; const ctx_r1 = i0.ɵɵnextContext(5); return i0.ɵɵresetView(ctx_r1.toggleExpansion(change_r8.ID)); });
282
- i0.ɵɵelementStart(2, "div", 57)(3, "span", 58);
441
+ function RecordChangesComponent_Conditional_2_Conditional_15_Conditional_23_For_1_For_4_Template(rf, ctx) { if (rf & 1) {
442
+ const _r13 = i0.ɵɵgetCurrentView();
443
+ i0.ɵɵelementStart(0, "div", 70);
444
+ i0.ɵɵlistener("keydown", function RecordChangesComponent_Conditional_2_Conditional_15_Conditional_23_For_1_For_4_Template_div_keydown_0_listener($event) { const change_r14 = i0.ɵɵrestoreView(_r13).$implicit; const ctx_r1 = i0.ɵɵnextContext(5); return i0.ɵɵresetView(ctx_r1.onTimelineItemKeydown($event, change_r14.ID)); });
445
+ i0.ɵɵelementStart(1, "div", 71);
446
+ i0.ɵɵlistener("click", function RecordChangesComponent_Conditional_2_Conditional_15_Conditional_23_For_1_For_4_Template_div_click_1_listener() { const change_r14 = i0.ɵɵrestoreView(_r13).$implicit; const ctx_r1 = i0.ɵɵnextContext(5); return i0.ɵɵresetView(ctx_r1.toggleExpansion(change_r14.ID)); });
447
+ i0.ɵɵelementStart(2, "div", 72)(3, "span", 73);
283
448
  i0.ɵɵtext(4);
284
449
  i0.ɵɵelementEnd();
285
- i0.ɵɵelementStart(5, "span", 59);
450
+ i0.ɵɵelementStart(5, "span", 74);
286
451
  i0.ɵɵtext(6);
287
- i0.ɵɵelementEnd()();
288
- i0.ɵɵelementStart(7, "div", 60)(8, "div", 61)(9, "div", 62);
289
- i0.ɵɵtext(10);
290
452
  i0.ɵɵelementEnd();
453
+ i0.ɵɵconditionalCreate(7, RecordChangesComponent_Conditional_2_Conditional_15_Conditional_23_For_1_For_4_Conditional_7_Template, 2, 1);
454
+ i0.ɵɵelementEnd();
455
+ i0.ɵɵelementStart(8, "div", 75)(9, "div", 76)(10, "div", 77);
291
456
  i0.ɵɵtext(11);
292
457
  i0.ɵɵelementEnd();
293
- i0.ɵɵelementStart(12, "span", 63);
294
- i0.ɵɵtext(13);
458
+ i0.ɵɵtext(12);
459
+ i0.ɵɵelementEnd();
460
+ i0.ɵɵelementStart(13, "span", 78);
461
+ i0.ɵɵtext(14);
295
462
  i0.ɵɵelementEnd();
296
- i0.ɵɵelementStart(14, "span", 64);
297
- i0.ɵɵtext(15);
463
+ i0.ɵɵelementStart(15, "span", 79);
464
+ i0.ɵɵtext(16);
298
465
  i0.ɵɵelementEnd();
299
- i0.ɵɵelementStart(16, "span", 65);
300
- i0.ɵɵtext(17);
466
+ i0.ɵɵelementStart(17, "span", 80);
467
+ i0.ɵɵtext(18);
301
468
  i0.ɵɵelementEnd();
302
- i0.ɵɵelement(18, "i", 66);
469
+ i0.ɵɵelement(19, "i", 81);
303
470
  i0.ɵɵelementEnd()();
304
- i0.ɵɵconditionalCreate(19, RecordChangesComponent_Conditional_2_Conditional_15_Conditional_31_For_1_For_4_Conditional_19_Template, 7, 4, "div", 67);
471
+ i0.ɵɵconditionalCreate(20, RecordChangesComponent_Conditional_2_Conditional_15_Conditional_23_For_1_For_4_Conditional_20_Template, 8, 5, "div", 82);
305
472
  i0.ɵɵelementEnd();
306
473
  } if (rf & 2) {
307
- const change_r8 = ctx.$implicit;
474
+ const change_r14 = ctx.$implicit;
308
475
  const ctx_r1 = i0.ɵɵnextContext(5);
309
- i0.ɵɵclassMap(ctx_r1.getChangeTypeCardClass(change_r8.Type));
310
- i0.ɵɵclassProp("expanded", ctx_r1.expandedItems.has(change_r8.ID));
311
- i0.ɵɵattribute("tabindex", 0)("aria-expanded", ctx_r1.expandedItems.has(change_r8.ID))("aria-label", ctx_r1.getTimelineItemLabel(change_r8));
312
- i0.ɵɵadvance(4);
313
- i0.ɵɵtextInterpolate(ctx_r1.getChangeTypeBadgeText(change_r8.Type));
476
+ i0.ɵɵclassMap(ctx_r1.getChangeTypeCardClass(change_r14.Type));
477
+ i0.ɵɵclassProp("expanded", ctx_r1.expandedItems.has(change_r14.ID))("rc-card-restore", ctx_r1.isRestoreRow(change_r14))("rc-card-highlight", ctx_r1.HighlightedChangeID === change_r14.ID);
478
+ i0.ɵɵattribute("data-change-id", change_r14.ID)("tabindex", 0)("aria-expanded", ctx_r1.expandedItems.has(change_r14.ID))("aria-label", ctx_r1.getTimelineItemLabel(change_r14));
479
+ i0.ɵɵadvance(3);
480
+ i0.ɵɵclassProp("rc-card-type-badge-restore", ctx_r1.isRestoreRow(change_r14));
481
+ i0.ɵɵadvance();
482
+ i0.ɵɵtextInterpolate(ctx_r1.getEffectiveBadgeText(change_r14));
314
483
  i0.ɵɵadvance(2);
315
- i0.ɵɵtextInterpolate(ctx_r1.getChangeSummary(change_r8));
484
+ i0.ɵɵtextInterpolate(ctx_r1.getChangeSummary(change_r14));
485
+ i0.ɵɵadvance();
486
+ i0.ɵɵconditional(ctx_r1.isRestoreRow(change_r14) ? 7 : -1);
316
487
  i0.ɵɵadvance(4);
317
- i0.ɵɵtextInterpolate(ctx_r1.getUserInitials(change_r8.User));
488
+ i0.ɵɵtextInterpolate(ctx_r1.getUserInitials(change_r14.User));
318
489
  i0.ɵɵadvance();
319
- i0.ɵɵtextInterpolate1(" ", ctx_r1.getUserDisplayName(change_r8.User), " ");
490
+ i0.ɵɵtextInterpolate1(" ", ctx_r1.getUserDisplayName(change_r14.User), " ");
320
491
  i0.ɵɵadvance();
321
- i0.ɵɵproperty("title", ctx_r1.formatFullDateTime(change_r8.ChangedAt));
492
+ i0.ɵɵproperty("title", ctx_r1.formatFullDateTime(change_r14.ChangedAt));
322
493
  i0.ɵɵadvance();
323
- i0.ɵɵtextInterpolate(ctx_r1.formatTime(change_r8.ChangedAt));
494
+ i0.ɵɵtextInterpolate(ctx_r1.formatTime(change_r14.ChangedAt));
324
495
  i0.ɵɵadvance();
325
- i0.ɵɵclassMap(ctx_r1.getSourceClass(change_r8.Source));
496
+ i0.ɵɵclassMap(ctx_r1.getSourceClass(change_r14.Source));
326
497
  i0.ɵɵadvance();
327
- i0.ɵɵtextInterpolate(change_r8.Source);
498
+ i0.ɵɵtextInterpolate(change_r14.Source);
328
499
  i0.ɵɵadvance();
329
- i0.ɵɵclassMap(ctx_r1.getStatusClass(change_r8.Status));
500
+ i0.ɵɵclassMap(ctx_r1.getStatusClass(change_r14.Status));
330
501
  i0.ɵɵadvance();
331
- i0.ɵɵtextInterpolate(change_r8.Status);
502
+ i0.ɵɵtextInterpolate(change_r14.Status);
332
503
  i0.ɵɵadvance(2);
333
- i0.ɵɵconditional(ctx_r1.expandedItems.has(change_r8.ID) ? 19 : -1);
504
+ i0.ɵɵconditional(ctx_r1.expandedItems.has(change_r14.ID) ? 20 : -1);
334
505
  } }
335
- function RecordChangesComponent_Conditional_2_Conditional_15_Conditional_31_For_1_Template(rf, ctx) { if (rf & 1) {
336
- i0.ɵɵelementStart(0, "div", 52)(1, "div", 53);
506
+ function RecordChangesComponent_Conditional_2_Conditional_15_Conditional_23_For_1_Template(rf, ctx) { if (rf & 1) {
507
+ i0.ɵɵelementStart(0, "div", 67)(1, "div", 68);
337
508
  i0.ɵɵtext(2);
338
509
  i0.ɵɵelementEnd();
339
- i0.ɵɵrepeaterCreate(3, RecordChangesComponent_Conditional_2_Conditional_15_Conditional_31_For_1_For_4_Template, 20, 20, "div", 54, _forTrack0);
510
+ i0.ɵɵrepeaterCreate(3, RecordChangesComponent_Conditional_2_Conditional_15_Conditional_23_For_1_For_4_Template, 21, 28, "div", 69, _forTrack0);
340
511
  i0.ɵɵelementEnd();
341
512
  } if (rf & 2) {
342
- const group_r12 = ctx.$implicit;
513
+ const group_r20 = ctx.$implicit;
343
514
  i0.ɵɵadvance(2);
344
- i0.ɵɵtextInterpolate(group_r12.label);
515
+ i0.ɵɵtextInterpolate(group_r20.label);
345
516
  i0.ɵɵadvance();
346
- i0.ɵɵrepeater(group_r12.changes);
517
+ i0.ɵɵrepeater(group_r20.changes);
347
518
  } }
348
- function RecordChangesComponent_Conditional_2_Conditional_15_Conditional_31_Template(rf, ctx) { if (rf & 1) {
349
- i0.ɵɵrepeaterCreate(0, RecordChangesComponent_Conditional_2_Conditional_15_Conditional_31_For_1_Template, 5, 1, "div", 52, _forTrack1);
519
+ function RecordChangesComponent_Conditional_2_Conditional_15_Conditional_23_Template(rf, ctx) { if (rf & 1) {
520
+ i0.ɵɵrepeaterCreate(0, RecordChangesComponent_Conditional_2_Conditional_15_Conditional_23_For_1_Template, 5, 1, "div", 67, _forTrack2);
350
521
  } if (rf & 2) {
351
522
  const ctx_r1 = i0.ɵɵnextContext(3);
352
523
  i0.ɵɵrepeater(ctx_r1.dateGroups);
@@ -373,28 +544,15 @@ function RecordChangesComponent_Conditional_2_Conditional_15_Template(rf, ctx) {
373
544
  i0.ɵɵlistener("input", function RecordChangesComponent_Conditional_2_Conditional_15_Template_input_input_15_listener() { i0.ɵɵrestoreView(_r4); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.onSearchChange()); });
374
545
  i0.ɵɵelementEnd()();
375
546
  i0.ɵɵelementStart(16, "button", 40);
376
- i0.ɵɵlistener("click", function RecordChangesComponent_Conditional_2_Conditional_15_Template_button_click_16_listener() { i0.ɵɵrestoreView(_r4); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.SetTypeFilter("")); });
547
+ i0.ɵɵlistener("click", function RecordChangesComponent_Conditional_2_Conditional_15_Template_button_click_16_listener() { i0.ɵɵrestoreView(_r4); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.SelectAllPill()); });
377
548
  i0.ɵɵelement(17, "i", 41);
378
549
  i0.ɵɵtext(18, " All ");
379
550
  i0.ɵɵelementEnd();
380
- i0.ɵɵelementStart(19, "button", 40);
381
- i0.ɵɵlistener("click", function RecordChangesComponent_Conditional_2_Conditional_15_Template_button_click_19_listener() { i0.ɵɵrestoreView(_r4); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.SetTypeFilter("Update")); });
382
- i0.ɵɵelement(20, "i", 42);
383
- i0.ɵɵtext(21, " Updates ");
551
+ i0.ɵɵconditionalCreate(19, RecordChangesComponent_Conditional_2_Conditional_15_Conditional_19_Template, 2, 1);
384
552
  i0.ɵɵelementEnd();
385
- i0.ɵɵelementStart(22, "button", 40);
386
- i0.ɵɵlistener("click", function RecordChangesComponent_Conditional_2_Conditional_15_Template_button_click_22_listener() { i0.ɵɵrestoreView(_r4); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.SetTypeFilter("Create")); });
387
- i0.ɵɵelement(23, "i", 43);
388
- i0.ɵɵtext(24, " Creates ");
389
- i0.ɵɵelementEnd();
390
- i0.ɵɵelementStart(25, "button", 40);
391
- i0.ɵɵlistener("click", function RecordChangesComponent_Conditional_2_Conditional_15_Template_button_click_25_listener() { i0.ɵɵrestoreView(_r4); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.SetTypeFilter("Delete")); });
392
- i0.ɵɵelement(26, "i", 44);
393
- i0.ɵɵtext(27, " Deletes ");
394
- i0.ɵɵelementEnd()();
395
- i0.ɵɵconditionalCreate(28, RecordChangesComponent_Conditional_2_Conditional_15_Conditional_28_Template, 4, 2, "div", 45);
396
- i0.ɵɵelementStart(29, "div", 46);
397
- i0.ɵɵconditionalCreate(30, RecordChangesComponent_Conditional_2_Conditional_15_Conditional_30_Template, 7, 0, "div", 47)(31, RecordChangesComponent_Conditional_2_Conditional_15_Conditional_31_Template, 2, 0);
553
+ i0.ɵɵconditionalCreate(20, RecordChangesComponent_Conditional_2_Conditional_15_Conditional_20_Template, 4, 2, "div", 42);
554
+ i0.ɵɵelementStart(21, "div", 43);
555
+ i0.ɵɵconditionalCreate(22, RecordChangesComponent_Conditional_2_Conditional_15_Conditional_22_Template, 7, 0, "div", 44)(23, RecordChangesComponent_Conditional_2_Conditional_15_Conditional_23_Template, 2, 0);
398
556
  i0.ɵɵelementEnd();
399
557
  } if (rf & 2) {
400
558
  const ctx_r1 = i0.ɵɵnextContext(2);
@@ -407,19 +565,15 @@ function RecordChangesComponent_Conditional_2_Conditional_15_Template(rf, ctx) {
407
565
  i0.ɵɵadvance(4);
408
566
  i0.ɵɵtwoWayProperty("ngModel", ctx_r1.searchTerm);
409
567
  i0.ɵɵadvance();
410
- i0.ɵɵclassProp("active", !ctx_r1.selectedType);
411
- i0.ɵɵadvance(3);
412
- i0.ɵɵclassProp("active", ctx_r1.selectedType === "Update");
413
- i0.ɵɵadvance(3);
414
- i0.ɵɵclassProp("active", ctx_r1.selectedType === "Create");
568
+ i0.ɵɵclassProp("active", ctx_r1.IsAllSelected);
415
569
  i0.ɵɵadvance(3);
416
- i0.ɵɵclassProp("active", ctx_r1.selectedType === "Delete");
417
- i0.ɵɵadvance(3);
418
- i0.ɵɵconditional(ctx_r1.filteredData.length !== ctx_r1.viewData.length ? 28 : -1);
570
+ i0.ɵɵconditional(ctx_r1.HasConditionalPills ? 19 : -1);
571
+ i0.ɵɵadvance();
572
+ i0.ɵɵconditional(ctx_r1.filteredData.length !== ctx_r1.viewData.length ? 20 : -1);
419
573
  i0.ɵɵadvance();
420
574
  i0.ɵɵattribute("aria-label", "Timeline of changes for " + ctx_r1.record.EntityInfo.Name + " record");
421
575
  i0.ɵɵadvance();
422
- i0.ɵɵconditional(ctx_r1.filteredData.length === 0 ? 30 : 31);
576
+ i0.ɵɵconditional(ctx_r1.filteredData.length === 0 ? 22 : 23);
423
577
  } }
424
578
  function RecordChangesComponent_Conditional_2_Template(rf, ctx) { if (rf & 1) {
425
579
  const _r1 = i0.ɵɵgetCurrentView();
@@ -437,7 +591,7 @@ function RecordChangesComponent_Conditional_2_Template(rf, ctx) { if (rf & 1) {
437
591
  i0.ɵɵelementEnd()();
438
592
  i0.ɵɵconditionalCreate(11, RecordChangesComponent_Conditional_2_Conditional_11_Template, 3, 0, "div", 12)(12, RecordChangesComponent_Conditional_2_Conditional_12_Template, 2, 0, "div", 13)(13, RecordChangesComponent_Conditional_2_Conditional_13_Template, 3, 0, "div", 14);
439
593
  i0.ɵɵelementEnd();
440
- i0.ɵɵconditionalCreate(14, RecordChangesComponent_Conditional_2_Conditional_14_Template, 11, 0, "div", 15)(15, RecordChangesComponent_Conditional_2_Conditional_15_Template, 32, 18);
594
+ i0.ɵɵconditionalCreate(14, RecordChangesComponent_Conditional_2_Conditional_14_Template, 11, 0, "div", 15)(15, RecordChangesComponent_Conditional_2_Conditional_15_Template, 24, 13);
441
595
  i0.ɵɵelementEnd();
442
596
  } if (rf & 2) {
443
597
  const ctx_r1 = i0.ɵɵnextContext();
@@ -448,133 +602,34 @@ function RecordChangesComponent_Conditional_2_Template(rf, ctx) { if (rf & 1) {
448
602
  i0.ɵɵadvance(3);
449
603
  i0.ɵɵconditional(ctx_r1.viewData.length === 0 ? 14 : 15);
450
604
  } }
451
- function RecordChangesComponent_Conditional_3_Conditional_17_Template(rf, ctx) { if (rf & 1) {
452
- i0.ɵɵelementStart(0, "div", 96);
453
- i0.ɵɵelement(1, "i", 101);
454
- i0.ɵɵtext(2, " No field changes could be parsed from this version. ");
455
- i0.ɵɵelementEnd();
456
- } }
457
- function RecordChangesComponent_Conditional_3_Conditional_18_For_12_Conditional_8_Template(rf, ctx) { if (rf & 1) {
458
- i0.ɵɵelement(0, "i", 107);
459
- } }
460
- function RecordChangesComponent_Conditional_3_Conditional_18_For_12_Conditional_9_Template(rf, ctx) { if (rf & 1) {
461
- i0.ɵɵelement(0, "i", 108);
462
- } }
463
- function RecordChangesComponent_Conditional_3_Conditional_18_For_12_Template(rf, ctx) { if (rf & 1) {
464
- i0.ɵɵelementStart(0, "tr")(1, "td", 103);
465
- i0.ɵɵtext(2);
466
- i0.ɵɵelementEnd();
467
- i0.ɵɵelementStart(3, "td", 104);
468
- i0.ɵɵtext(4);
469
- i0.ɵɵelementEnd();
470
- i0.ɵɵelementStart(5, "td", 105);
471
- i0.ɵɵtext(6);
472
- i0.ɵɵelementEnd();
473
- i0.ɵɵelementStart(7, "td", 106);
474
- i0.ɵɵconditionalCreate(8, RecordChangesComponent_Conditional_3_Conditional_18_For_12_Conditional_8_Template, 1, 0, "i", 107)(9, RecordChangesComponent_Conditional_3_Conditional_18_For_12_Conditional_9_Template, 1, 0, "i", 108);
475
- i0.ɵɵelementEnd()();
476
- } if (rf & 2) {
477
- const diff_r14 = ctx.$implicit;
478
- i0.ɵɵclassProp("rc-diff-changed", diff_r14.IsChanged)("rc-diff-unchanged", !diff_r14.IsChanged);
479
- i0.ɵɵadvance(2);
480
- i0.ɵɵtextInterpolate(diff_r14.DisplayName);
481
- i0.ɵɵadvance(2);
482
- i0.ɵɵtextInterpolate(diff_r14.CurrentValue || "(empty)");
483
- i0.ɵɵadvance(2);
484
- i0.ɵɵtextInterpolate(diff_r14.VersionValue || "(empty)");
485
- i0.ɵɵadvance(2);
486
- i0.ɵɵconditional(diff_r14.IsChanged ? 8 : 9);
487
- } }
488
- function RecordChangesComponent_Conditional_3_Conditional_18_Template(rf, ctx) { if (rf & 1) {
489
- i0.ɵɵelementStart(0, "table", 97)(1, "thead")(2, "tr")(3, "th");
490
- i0.ɵɵtext(4, "Field");
491
- i0.ɵɵelementEnd();
492
- i0.ɵɵelementStart(5, "th");
493
- i0.ɵɵtext(6, "Current Value");
494
- i0.ɵɵelementEnd();
495
- i0.ɵɵelementStart(7, "th");
496
- i0.ɵɵtext(8, "Restore To");
497
- i0.ɵɵelementEnd();
498
- i0.ɵɵelement(9, "th");
499
- i0.ɵɵelementEnd()();
500
- i0.ɵɵelementStart(10, "tbody");
501
- i0.ɵɵrepeaterCreate(11, RecordChangesComponent_Conditional_3_Conditional_18_For_12_Template, 10, 8, "tr", 102, _forTrack4);
502
- i0.ɵɵelementEnd()();
503
- } if (rf & 2) {
504
- const ctx_r1 = i0.ɵɵnextContext(2);
505
- i0.ɵɵadvance(11);
506
- i0.ɵɵrepeater(ctx_r1.RestorePreviewFields);
507
- } }
508
- function RecordChangesComponent_Conditional_3_Conditional_21_Template(rf, ctx) { if (rf & 1) {
509
- i0.ɵɵelement(0, "i", 109);
510
- i0.ɵɵtext(1, " Restoring... ");
511
- } }
512
- function RecordChangesComponent_Conditional_3_Conditional_22_Template(rf, ctx) { if (rf & 1) {
513
- i0.ɵɵelement(0, "i", 110);
514
- i0.ɵɵtext(1, " Apply Restore ");
515
- } }
516
- function RecordChangesComponent_Conditional_3_Template(rf, ctx) { if (rf & 1) {
517
- const _r13 = i0.ɵɵgetCurrentView();
518
- i0.ɵɵelementStart(0, "div", 89);
519
- i0.ɵɵlistener("click", function RecordChangesComponent_Conditional_3_Template_div_click_0_listener() { i0.ɵɵrestoreView(_r13); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.CancelRestorePreview()); });
520
- i0.ɵɵelementStart(1, "div", 90);
521
- i0.ɵɵlistener("click", function RecordChangesComponent_Conditional_3_Template_div_click_1_listener($event) { i0.ɵɵrestoreView(_r13); return i0.ɵɵresetView($event.stopPropagation()); });
522
- i0.ɵɵelementStart(2, "div", 91)(3, "div", 92);
523
- i0.ɵɵelement(4, "i", 88);
524
- i0.ɵɵtext(5, " Restore Preview ");
525
- i0.ɵɵelementEnd();
526
- i0.ɵɵelementStart(6, "button", 93);
527
- i0.ɵɵlistener("click", function RecordChangesComponent_Conditional_3_Template_button_click_6_listener() { i0.ɵɵrestoreView(_r13); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.CancelRestorePreview()); });
528
- i0.ɵɵelement(7, "i", 94);
529
- i0.ɵɵelementEnd()();
530
- i0.ɵɵelementStart(8, "div", 95)(9, "span")(10, "strong");
531
- i0.ɵɵtext(11, "Version:");
532
- i0.ɵɵelementEnd();
533
- i0.ɵɵtext(12);
534
- i0.ɵɵelementEnd();
535
- i0.ɵɵelementStart(13, "span")(14, "strong");
536
- i0.ɵɵtext(15, "By:");
537
- i0.ɵɵelementEnd();
538
- i0.ɵɵtext(16);
539
- i0.ɵɵelementEnd()();
540
- i0.ɵɵconditionalCreate(17, RecordChangesComponent_Conditional_3_Conditional_17_Template, 3, 0, "div", 96)(18, RecordChangesComponent_Conditional_3_Conditional_18_Template, 13, 0, "table", 97);
541
- i0.ɵɵelementStart(19, "div", 98)(20, "button", 99);
542
- i0.ɵɵlistener("click", function RecordChangesComponent_Conditional_3_Template_button_click_20_listener() { i0.ɵɵrestoreView(_r13); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.ConfirmRestore()); });
543
- i0.ɵɵconditionalCreate(21, RecordChangesComponent_Conditional_3_Conditional_21_Template, 2, 0)(22, RecordChangesComponent_Conditional_3_Conditional_22_Template, 2, 0);
544
- i0.ɵɵelementEnd();
545
- i0.ɵɵelementStart(23, "button", 100);
546
- i0.ɵɵlistener("click", function RecordChangesComponent_Conditional_3_Template_button_click_23_listener() { i0.ɵɵrestoreView(_r13); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.CancelRestorePreview()); });
547
- i0.ɵɵtext(24, " Cancel ");
548
- i0.ɵɵelementEnd()()()();
549
- } if (rf & 2) {
550
- const ctx_r1 = i0.ɵɵnextContext();
551
- i0.ɵɵadvance(12);
552
- i0.ɵɵtextInterpolate1(" ", ctx_r1.formatFullDateTime(ctx_r1.RestorePreview.ChangedAt));
553
- i0.ɵɵadvance(4);
554
- i0.ɵɵtextInterpolate1(" ", ctx_r1.getUserDisplayName(ctx_r1.RestorePreview.User));
555
- i0.ɵɵadvance();
556
- i0.ɵɵconditional(ctx_r1.RestorePreviewFields.length === 0 ? 17 : 18);
557
- i0.ɵɵadvance(3);
558
- i0.ɵɵproperty("disabled", ctx_r1.IsRestoring || ctx_r1.RestorePreviewFields.length === 0);
559
- i0.ɵɵadvance();
560
- i0.ɵɵconditional(ctx_r1.IsRestoring ? 21 : 22);
561
- i0.ɵɵadvance(2);
562
- i0.ɵɵproperty("disabled", ctx_r1.IsRestoring);
563
- } }
564
605
  function RecordChangesComponent_Conditional_4_Template(rf, ctx) { if (rf & 1) {
565
- const _r15 = i0.ɵɵgetCurrentView();
566
- i0.ɵɵelementStart(0, "div", 111);
567
- i0.ɵɵlistener("click", function RecordChangesComponent_Conditional_4_Template_div_click_0_listener() { i0.ɵɵrestoreView(_r15); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.OnLabelCreateCancelled()); });
568
- i0.ɵɵelementStart(1, "div", 112);
569
- i0.ɵɵlistener("click", function RecordChangesComponent_Conditional_4_Template_div_click_1_listener($event) { i0.ɵɵrestoreView(_r15); return i0.ɵɵresetView($event.stopPropagation()); });
570
- i0.ɵɵelementStart(2, "mj-label-create", 113);
571
- i0.ɵɵlistener("Created", function RecordChangesComponent_Conditional_4_Template_mj_label_create_Created_2_listener($event) { i0.ɵɵrestoreView(_r15); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.OnLabelCreated($event)); })("Cancel", function RecordChangesComponent_Conditional_4_Template_mj_label_create_Cancel_2_listener() { i0.ɵɵrestoreView(_r15); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.OnLabelCreateCancelled()); });
606
+ const _r21 = i0.ɵɵgetCurrentView();
607
+ i0.ɵɵelementStart(0, "div", 112);
608
+ i0.ɵɵlistener("click", function RecordChangesComponent_Conditional_4_Template_div_click_0_listener() { i0.ɵɵrestoreView(_r21); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.OnLabelCreateCancelled()); });
609
+ i0.ɵɵelementStart(1, "div", 113);
610
+ i0.ɵɵlistener("click", function RecordChangesComponent_Conditional_4_Template_div_click_1_listener($event) { i0.ɵɵrestoreView(_r21); return i0.ɵɵresetView($event.stopPropagation()); });
611
+ i0.ɵɵelementStart(2, "mj-label-create", 114);
612
+ i0.ɵɵlistener("Created", function RecordChangesComponent_Conditional_4_Template_mj_label_create_Created_2_listener($event) { i0.ɵɵrestoreView(_r21); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.OnLabelCreated($event)); })("Cancel", function RecordChangesComponent_Conditional_4_Template_mj_label_create_Cancel_2_listener() { i0.ɵɵrestoreView(_r21); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.OnLabelCreateCancelled()); });
572
613
  i0.ɵɵelementEnd()()();
573
614
  } if (rf & 2) {
574
615
  const ctx_r1 = i0.ɵɵnextContext();
575
616
  i0.ɵɵadvance(2);
576
617
  i0.ɵɵproperty("PreselectedEntity", ctx_r1.record.EntityInfo)("PreselectedRecordIds", i0.ɵɵpureFunction1(2, _c0, ctx_r1.record.PrimaryKey.KeyValuePairs[0].Value));
577
618
  } }
619
+ /**
620
+ * Slide-out timeline of all changes to a single record. Hosts the reusable
621
+ * {@link RestorePreviewPanelComponent} for the actual restore confirmation
622
+ * flow, and exposes a `RestoreRequested` event the host can act on to
623
+ * persist the restore.
624
+ *
625
+ * @example
626
+ * <mj-record-changes
627
+ * [record]="myEntity"
628
+ * [AllowRestore]="true"
629
+ * (dialogClosed)="showHistory = false"
630
+ * (RestoreRequested)="onRestoreRequested($event)">
631
+ * </mj-record-changes>
632
+ */
578
633
  export class RecordChangesComponent {
579
634
  cdr;
580
635
  ngZone;
@@ -587,19 +642,20 @@ export class RecordChangesComponent {
587
642
  /** Whether to show a "Restore" button on each historical version row. Default false. */
588
643
  AllowRestore = false;
589
644
  /**
590
- * Emitted when the user clicks Restore on a historical version.
591
- * The parent is responsible for loading old values into the record and saving.
645
+ * Emitted when the user confirms a restore in the preview panel.
646
+ * The host is responsible for applying the snapshot to the record and
647
+ * saving with `record.SetRestoreContext()` set first.
592
648
  */
593
649
  RestoreRequested = new EventEmitter();
594
650
  viewData = [];
595
651
  filteredData = [];
596
652
  dateGroups = [];
597
653
  expandedItems = new Set();
598
- /** The change record being previewed for restore, or null if no preview is active */
599
- RestorePreview = null;
600
- /** Parsed field-level diff for the restore preview */
601
- RestorePreviewFields = [];
602
- /** Whether the restore operation is in progress */
654
+ /** The change record currently selected for restore preview, or null. */
655
+ RestorePreviewChange = null;
656
+ /** Visibility of the embedded restore preview slide-in. */
657
+ RestorePreviewVisible = false;
658
+ /** Whether the restore commit is in progress (between confirmation and host response). */
603
659
  IsRestoring = false;
604
660
  // Version label state
605
661
  RecordLabels = [];
@@ -607,8 +663,30 @@ export class RecordChangesComponent {
607
663
  ShowCreateWizard = false;
608
664
  // Filter properties
609
665
  searchTerm = '';
666
+ /** Single selected type filter (legacy, kept for backwards compat). */
610
667
  selectedType = '';
611
668
  selectedSource = '';
669
+ /** Map of Key → selected, used by the conditional chip system. */
670
+ ChipSelections = {};
671
+ /** Whether the overflow popover is open. */
672
+ ShowFilterOverflow = false;
673
+ /** Highlighted change ID for the lineage-jump indicator (transient). */
674
+ HighlightedChangeID = null;
675
+ /**
676
+ * Conditional filter pills derived from loaded data. Always includes 'All'
677
+ * implicitly. Other pills only render when at least one matching change
678
+ * exists. Overflows into a popover when the count exceeds 2.
679
+ */
680
+ ConditionalPills = [];
681
+ /** Threshold above which conditional chips collapse into the overflow popover. */
682
+ OVERFLOW_THRESHOLD = 2;
683
+ /**
684
+ * Subscription to the record's BaseEntity event stream. We listen for
685
+ * 'save' events and auto-refresh the timeline so the user immediately
686
+ * sees the new RecordChange row produced by either a normal save or a
687
+ * restore. Cleaned up in ngOnDestroy.
688
+ */
689
+ _entitySaveSub = null;
612
690
  constructor(cdr, ngZone, mjNotificationService, sanitizer) {
613
691
  this.cdr = cdr;
614
692
  this.ngZone = ngZone;
@@ -622,8 +700,30 @@ export class RecordChangesComponent {
622
700
  this.cdr.markForCheck();
623
701
  this.LoadRecordChanges(this.record.PrimaryKey, '', this.record.EntityInfo.Name);
624
702
  this.LoadRecordLabels();
703
+ this.subscribeToRecordSaves();
625
704
  }
626
705
  }
706
+ ngOnDestroy() {
707
+ this._entitySaveSub?.unsubscribe();
708
+ this._entitySaveSub = null;
709
+ }
710
+ /**
711
+ * Wires up an event handler on the live record so the timeline auto-
712
+ * refreshes immediately after any save lands — including the one
713
+ * produced by the restore flow. Without this the user sees their record
714
+ * update in the form but the panel above still shows the pre-restore
715
+ * change list, which is confusing.
716
+ */
717
+ subscribeToRecordSaves() {
718
+ if (!this.record)
719
+ return;
720
+ this._entitySaveSub?.unsubscribe();
721
+ this._entitySaveSub = this.record.RegisterEventHandler((event) => {
722
+ if (event?.type === 'save') {
723
+ this.ngZone.run(() => this.Refresh());
724
+ }
725
+ });
726
+ }
627
727
  /**
628
728
  * Reloads the record changes list from the database.
629
729
  * Called by the parent container after a save completes while the drawer is open.
@@ -648,8 +748,8 @@ export class RecordChangesComponent {
648
748
  this.ngZone.run(() => {
649
749
  if (changes) {
650
750
  this.viewData = changes.sort((a, b) => new Date(b.ChangedAt).getTime() - new Date(a.ChangedAt).getTime());
651
- this.filteredData = [...this.viewData];
652
- this.dateGroups = this.buildDateGroups(this.filteredData);
751
+ this.rebuildConditionalPills();
752
+ this.applyFilters();
653
753
  this.IsLoading = false;
654
754
  }
655
755
  else {
@@ -667,16 +767,102 @@ export class RecordChangesComponent {
667
767
  onFilterChange() {
668
768
  this.applyFilters();
669
769
  }
670
- SetTypeFilter(type) {
671
- this.selectedType = this.selectedType === type ? '' : type;
770
+ /**
771
+ * Toggles the "All" pill clears every conditional selection.
772
+ */
773
+ SelectAllPill() {
774
+ for (const k of Object.keys(this.ChipSelections))
775
+ this.ChipSelections[k] = false;
776
+ this.applyFilters();
777
+ }
778
+ /**
779
+ * Toggles a conditional pill on/off.
780
+ */
781
+ TogglePill(key) {
782
+ this.ChipSelections[key] = !this.ChipSelections[key];
672
783
  this.applyFilters();
673
784
  }
785
+ /**
786
+ * Returns true when no conditional pills are selected (i.e. "All" mode).
787
+ */
788
+ get IsAllSelected() {
789
+ return !Object.values(this.ChipSelections).some(v => v);
790
+ }
791
+ /**
792
+ * Whether any conditional pills are actually visible at all.
793
+ */
794
+ get HasConditionalPills() {
795
+ return this.ConditionalPills.length > 0;
796
+ }
797
+ /**
798
+ * True when the conditional chips should collapse into an overflow popover
799
+ * because there are more than the threshold.
800
+ */
801
+ get UseOverflowPopover() {
802
+ return this.ConditionalPills.length > this.OVERFLOW_THRESHOLD;
803
+ }
804
+ /** Number of currently selected conditional pills (for the popover trigger label). */
805
+ get SelectedConditionalCount() {
806
+ return Object.values(this.ChipSelections).filter(v => v).length;
807
+ }
808
+ ToggleFilterOverflow() {
809
+ this.ShowFilterOverflow = !this.ShowFilterOverflow;
810
+ this.cdr.markForCheck();
811
+ }
812
+ CloseFilterOverflow() {
813
+ this.ShowFilterOverflow = false;
814
+ this.cdr.markForCheck();
815
+ }
674
816
  ClearFilters() {
675
817
  this.searchTerm = '';
676
- this.selectedType = '';
677
- this.selectedSource = '';
818
+ for (const k of Object.keys(this.ChipSelections))
819
+ this.ChipSelections[k] = false;
678
820
  this.applyFilters();
679
821
  }
822
+ /**
823
+ * Builds the list of conditional pills from currently loaded data —
824
+ * a pill only appears for change types/sources that actually exist.
825
+ */
826
+ rebuildConditionalPills() {
827
+ const counts = {};
828
+ let restoreCount = 0;
829
+ for (const c of this.viewData) {
830
+ const type = c.Type ?? 'Update';
831
+ counts[type] = (counts[type] ?? 0) + 1;
832
+ if (this.isRestoreChange(c))
833
+ restoreCount++;
834
+ }
835
+ const pills = [];
836
+ if ((counts['Update'] ?? 0) > 0) {
837
+ pills.push({ Key: 'Update', Label: 'Updates', Icon: 'fa-pen', Count: counts['Update'], Variant: 'type' });
838
+ }
839
+ if ((counts['Create'] ?? 0) > 0) {
840
+ pills.push({ Key: 'Create', Label: 'Creates', Icon: 'fa-plus', Count: counts['Create'], Variant: 'type' });
841
+ }
842
+ if ((counts['Delete'] ?? 0) > 0) {
843
+ pills.push({ Key: 'Delete', Label: 'Deletes', Icon: 'fa-trash', Count: counts['Delete'], Variant: 'type' });
844
+ }
845
+ if ((counts['Snapshot'] ?? 0) > 0) {
846
+ pills.push({ Key: 'Snapshot', Label: 'Snapshots', Icon: 'fa-camera', Count: counts['Snapshot'], Variant: 'type' });
847
+ }
848
+ if (restoreCount > 0) {
849
+ pills.push({ Key: 'Restore', Label: 'Restored', Icon: 'fa-clock-rotate-left', Count: restoreCount, Variant: 'restore' });
850
+ }
851
+ // Initialize/prune selection state
852
+ const validKeys = new Set(pills.map(p => p.Key));
853
+ for (const k of Object.keys(this.ChipSelections)) {
854
+ if (!validKeys.has(k))
855
+ delete this.ChipSelections[k];
856
+ }
857
+ for (const p of pills) {
858
+ if (this.ChipSelections[p.Key] === undefined)
859
+ this.ChipSelections[p.Key] = false;
860
+ }
861
+ this.ConditionalPills = pills;
862
+ }
863
+ isRestoreChange(c) {
864
+ return c.Source === 'Restore' || c.RestoredFromID != null;
865
+ }
680
866
  applyFilters() {
681
867
  let filtered = [...this.viewData];
682
868
  if (this.searchTerm.trim()) {
@@ -685,11 +871,22 @@ export class RecordChangesComponent {
685
871
  change.User?.toLowerCase().includes(search) ||
686
872
  change.Comments?.toLowerCase().includes(search));
687
873
  }
688
- if (this.selectedType) {
689
- filtered = filtered.filter(change => change.Type === this.selectedType);
690
- }
691
- if (this.selectedSource) {
692
- filtered = filtered.filter(change => change.Source === this.selectedSource);
874
+ // Apply conditional pill filters — if any are selected, only show changes matching ANY of them (OR semantics).
875
+ const selectedKeys = Object.keys(this.ChipSelections).filter(k => this.ChipSelections[k]);
876
+ if (selectedKeys.length > 0) {
877
+ filtered = filtered.filter(change => {
878
+ for (const key of selectedKeys) {
879
+ if (key === 'Restore') {
880
+ if (this.isRestoreChange(change))
881
+ return true;
882
+ }
883
+ else {
884
+ if (change.Type === key)
885
+ return true;
886
+ }
887
+ }
888
+ return false;
889
+ });
693
890
  }
694
891
  this.filteredData = filtered;
695
892
  this.dateGroups = this.buildDateGroups(this.filteredData);
@@ -709,7 +906,7 @@ export class RecordChangesComponent {
709
906
  EntityName: 'MJ: Version Label Items',
710
907
  Fields: ['VersionLabelID'],
711
908
  ExtraFilter: `EntityID='${entityId}' AND RecordID='${recordId}'`,
712
- ResultType: 'simple'
909
+ ResultType: 'simple',
713
910
  });
714
911
  if (!itemsResult.Success || itemsResult.Results.length === 0) {
715
912
  this.ngZone.run(() => {
@@ -726,7 +923,7 @@ export class RecordChangesComponent {
726
923
  Fields: ['ID', 'Name', 'Description', 'Scope', 'Status', 'ItemCount', '__mj_CreatedAt'],
727
924
  ExtraFilter: `ID IN (${labelIdFilter})`,
728
925
  OrderBy: '__mj_CreatedAt DESC',
729
- ResultType: 'simple'
926
+ ResultType: 'simple',
730
927
  });
731
928
  if (labelsResult.Success) {
732
929
  this.RecordLabels = labelsResult.Results.map(l => ({
@@ -736,7 +933,7 @@ export class RecordChangesComponent {
736
933
  Scope: l.Scope,
737
934
  Status: l.Status,
738
935
  CreatedAt: l.__mj_CreatedAt,
739
- ItemCount: l.ItemCount
936
+ ItemCount: l.ItemCount,
740
937
  }));
741
938
  }
742
939
  }
@@ -790,104 +987,101 @@ export class RecordChangesComponent {
790
987
  }
791
988
  }
792
989
  /**
793
- * Opens the inline restore preview panel for a given change record.
794
- * Computes a field-by-field diff between the version's old values and the current record.
990
+ * Opens the embedded restore preview panel for a given change record.
991
+ * The panel computes a full-record diff (current vs the change's
992
+ * FullRecordJSON snapshot) — this is the semantic-correctness fix:
993
+ * we restore TO the state at that point in time, not just undo the
994
+ * one delta the user clicked.
795
995
  */
796
996
  OnRestoreVersion(change, event) {
797
- event.stopPropagation(); // Prevent card toggle
798
- this.RestorePreview = change;
799
- this.RestorePreviewFields = this.buildRestorePreviewFields(change);
800
- this.IsRestoring = false;
801
- this.cdr.markForCheck();
802
- }
803
- /** Closes the restore preview panel without applying changes. */
804
- CancelRestorePreview() {
805
- this.RestorePreview = null;
806
- this.RestorePreviewFields = [];
997
+ event.stopPropagation();
998
+ this.RestorePreviewChange = change;
999
+ this.RestorePreviewVisible = true;
807
1000
  this.cdr.markForCheck();
808
1001
  }
809
1002
  /**
810
- * Confirms the restore: emits a RestoreVersionEvent with the old field values
811
- * so the parent (record-form-container) can apply them and save.
1003
+ * Called when the user confirms the restore in the embedded panel.
1004
+ * Translates the panel's RestoreCommitEvent into the broader-shape
1005
+ * RestoreVersionEvent the host is wired to handle.
812
1006
  */
813
- ConfirmRestore() {
814
- if (!this.RestorePreview)
1007
+ OnRestorePanelConfirmed(commit) {
1008
+ if (!this.RestorePreviewChange)
815
1009
  return;
816
- const change = this.RestorePreview;
817
- const fieldChanges = this.parseFieldChanges(change);
1010
+ const change = this.RestorePreviewChange;
818
1011
  this.IsRestoring = true;
819
1012
  this.cdr.markForCheck();
820
1013
  this.RestoreRequested.emit({
821
- VersionID: change.ID,
1014
+ SourceChangeID: commit.SourceChangeID,
822
1015
  ChangedAt: change.ChangedAt,
823
1016
  ChangedByUser: change.User || '',
824
- FieldChanges: fieldChanges
1017
+ Reason: commit.Reason,
1018
+ FieldValues: commit.FieldValues,
825
1019
  });
826
- // The parent will handle the actual save; we close the preview on completion.
827
- // A brief delay allows the parent to process, then we reset.
1020
+ // Close the panel after a brief delay so the host has a moment to react.
828
1021
  setTimeout(() => {
829
- this.RestorePreview = null;
830
- this.RestorePreviewFields = [];
1022
+ this.RestorePreviewVisible = false;
1023
+ this.RestorePreviewChange = null;
831
1024
  this.IsRestoring = false;
832
1025
  this.cdr.markForCheck();
833
1026
  }, 500);
834
1027
  }
835
1028
  /**
836
- * Builds the diff list comparing version old values vs the current record.
1029
+ * Called when the user dismisses the restore preview without confirming.
837
1030
  */
838
- buildRestorePreviewFields(change) {
839
- const changesJson = this.parseChangesJson(change);
840
- if (!changesJson)
841
- return [];
842
- const diffs = [];
843
- for (const key of Object.keys(changesJson)) {
844
- const entry = changesJson[key];
845
- const fieldName = entry.field || key;
846
- const entityField = this.record.EntityInfo.Fields.find((f) => f.Name.trim().toLowerCase() === fieldName.trim().toLowerCase());
847
- const isDateField = entityField?.TSType === EntityFieldTSType.Date;
848
- const versionValue = this.formatChangeValue(entry.oldValue, isDateField);
849
- const currentValue = this.getCurrentFieldValue(fieldName, isDateField);
850
- diffs.push({
851
- FieldName: fieldName,
852
- DisplayName: entityField?.DisplayNameOrName || fieldName,
853
- VersionValue: versionValue,
854
- CurrentValue: currentValue,
855
- IsChanged: versionValue !== currentValue
856
- });
857
- }
858
- return diffs;
859
- }
860
- /** Gets the current value of a field from the live record, formatted for display. */
861
- getCurrentFieldValue(fieldName, isDateField) {
862
- const field = this.record.Fields.find(f => f.Name.trim().toLowerCase() === fieldName.trim().toLowerCase());
863
- if (!field)
864
- return '';
865
- return this.formatChangeValue(field.Value, isDateField);
1031
+ OnRestorePanelCancelled() {
1032
+ this.RestorePreviewVisible = false;
1033
+ this.RestorePreviewChange = null;
1034
+ this.cdr.markForCheck();
866
1035
  }
867
- /** Parses ChangesJSON into a structured map, returning null on failure. */
868
- parseChangesJson(change) {
869
- try {
870
- return JSON.parse(change.ChangesJSON || '{}');
871
- }
872
- catch {
1036
+ // ─── Lineage chip ───────────────────────────────────────────────
1037
+ /**
1038
+ * Returns the source change for a given restored row, if found in the
1039
+ * currently loaded changes. Returns null when the source isn't loaded
1040
+ * (e.g., it's been pruned from history) or when this row isn't a restore.
1041
+ */
1042
+ getRestoredFromSourceChange(change) {
1043
+ const sourceId = change.RestoredFromID;
1044
+ if (!sourceId)
873
1045
  return null;
874
- }
1046
+ return this.viewData.find(c => UUIDsEqual(c.ID, sourceId)) ?? null;
875
1047
  }
876
- /** Parses field changes into the RestoreVersionEvent format. */
877
- parseFieldChanges(change) {
878
- const fieldChanges = {};
879
- const changesJson = this.parseChangesJson(change);
880
- if (!changesJson)
881
- return fieldChanges;
882
- for (const key of Object.keys(changesJson)) {
883
- const entry = changesJson[key];
884
- const fieldName = entry.field || key;
885
- fieldChanges[fieldName] = {
886
- OldValue: entry.oldValue,
887
- NewValue: entry.newValue
888
- };
889
- }
890
- return fieldChanges;
1048
+ /**
1049
+ * True when the row was produced by a restore operation (either the
1050
+ * `Source` is `'Restore'` OR `RestoredFromID` is populated).
1051
+ */
1052
+ isRestoreRow(change) {
1053
+ return this.isRestoreChange(change);
1054
+ }
1055
+ /**
1056
+ * True when this change is the most recent in the loaded history.
1057
+ * `viewData` is sorted DESC by `ChangedAt`, so the most recent is index 0.
1058
+ * Restoring to the most recent version is a no-op, so the timeline hides
1059
+ * the Restore button on this row.
1060
+ */
1061
+ isMostRecentChange(change) {
1062
+ return this.viewData.length > 0 && this.viewData[0] === change;
1063
+ }
1064
+ /**
1065
+ * Click handler for the lineage chip — scrolls/highlights the source
1066
+ * change row in the timeline. Auto-clears after a few seconds.
1067
+ */
1068
+ JumpToSourceChange(sourceChange, event) {
1069
+ event.stopPropagation();
1070
+ this.HighlightedChangeID = sourceChange.ID;
1071
+ this.expandedItems.add(sourceChange.ID);
1072
+ this.cdr.markForCheck();
1073
+ // Auto-clear the highlight after 3s
1074
+ setTimeout(() => {
1075
+ if (this.HighlightedChangeID && UUIDsEqual(this.HighlightedChangeID, sourceChange.ID)) {
1076
+ this.HighlightedChangeID = null;
1077
+ this.cdr.markForCheck();
1078
+ }
1079
+ }, 3000);
1080
+ // Scroll into view
1081
+ setTimeout(() => {
1082
+ const el = document.querySelector(`[data-change-id="${sourceChange.ID}"]`);
1083
+ el?.scrollIntoView({ behavior: 'smooth', block: 'center' });
1084
+ }, 50);
891
1085
  }
892
1086
  // ─── Date Grouping ─────────────────────────────────────────────
893
1087
  buildDateGroups(changes) {
@@ -919,6 +1113,7 @@ export class RecordChangesComponent {
919
1113
  case 'Create': return 'type-create';
920
1114
  case 'Update': return 'type-update';
921
1115
  case 'Delete': return 'type-delete';
1116
+ case 'Snapshot': return 'type-snapshot';
922
1117
  default: return 'type-update';
923
1118
  }
924
1119
  }
@@ -926,11 +1121,38 @@ export class RecordChangesComponent {
926
1121
  switch (type) {
927
1122
  case 'Create': return 'Created';
928
1123
  case 'Delete': return 'Deleted';
1124
+ case 'Snapshot': return 'Snapshot';
929
1125
  default: return type;
930
1126
  }
931
1127
  }
1128
+ /**
1129
+ * Badge text for the row's primary type tag. For restore rows we override
1130
+ * the underlying `Type='Update'` and show "Restore" instead — matches the
1131
+ * mockup's intent of treating restore as a first-class operation in the
1132
+ * timeline rather than a flavor of update.
1133
+ */
1134
+ getEffectiveBadgeText(change) {
1135
+ if (this.isRestoreRow(change))
1136
+ return 'Restore';
1137
+ return this.getChangeTypeBadgeText(change.Type);
1138
+ }
1139
+ /**
1140
+ * Optional restore reason — pulled from the dynamic `RestoreReason`
1141
+ * column added by the lineage migration. Returns null when not present
1142
+ * or not a restore row.
1143
+ */
1144
+ getRestoreReason(change) {
1145
+ if (!this.isRestoreRow(change))
1146
+ return null;
1147
+ const reason = change.RestoreReason;
1148
+ return reason && reason.trim().length > 0 ? reason : null;
1149
+ }
932
1150
  getSourceClass(source) {
933
- return source === 'Internal' ? 'source-internal' : 'source-external';
1151
+ if (source === 'Restore')
1152
+ return 'source-restore';
1153
+ if (source === 'Internal')
1154
+ return 'source-internal';
1155
+ return 'source-external';
934
1156
  }
935
1157
  getStatusClass(status) {
936
1158
  switch (status) {
@@ -946,12 +1168,10 @@ export class RecordChangesComponent {
946
1168
  getUserInitials(user) {
947
1169
  if (!user)
948
1170
  return '?';
949
- // Handle email addresses: take first char of local part + first char of domain
950
1171
  if (user.includes('@')) {
951
1172
  const local = user.split('@')[0];
952
1173
  return local.substring(0, 2).toUpperCase();
953
1174
  }
954
- // Handle names: first char of each word
955
1175
  const parts = user.trim().split(/\s+/);
956
1176
  if (parts.length >= 2) {
957
1177
  return (parts[0][0] + parts[1][0]).toUpperCase();
@@ -973,7 +1193,7 @@ export class RecordChangesComponent {
973
1193
  return new Intl.DateTimeFormat('en-US', {
974
1194
  hour: 'numeric',
975
1195
  minute: '2-digit',
976
- hour12: true
1196
+ hour12: true,
977
1197
  }).format(new Date(date));
978
1198
  }
979
1199
  formatRelativeTime(date) {
@@ -993,7 +1213,7 @@ export class RecordChangesComponent {
993
1213
  return new Intl.DateTimeFormat('en-US', {
994
1214
  month: 'short',
995
1215
  day: 'numeric',
996
- year: diffDays > 365 ? 'numeric' : undefined
1216
+ year: diffDays > 365 ? 'numeric' : undefined,
997
1217
  }).format(new Date(date));
998
1218
  }
999
1219
  formatFullDateTime(date) {
@@ -1004,15 +1224,27 @@ export class RecordChangesComponent {
1004
1224
  hour: 'numeric',
1005
1225
  minute: 'numeric',
1006
1226
  hour12: true,
1007
- timeZoneName: 'short'
1227
+ timeZoneName: 'short',
1008
1228
  }).format(new Date(date));
1009
1229
  }
1010
1230
  // ─── Change Summary ─────────────────────────────────────────────
1011
1231
  getChangeSummary(change) {
1232
+ // Restore rows get a distinctive summary so the timeline reads like a
1233
+ // sentence — "Restored to 5:56 PM version" rather than yet another
1234
+ // "Name and Description changed". The lineage chip carries the full
1235
+ // source-version detail.
1236
+ if (this.isRestoreRow(change)) {
1237
+ const src = this.getRestoredFromSourceChange(change);
1238
+ if (src)
1239
+ return `Restored to ${this.formatTime(src.ChangedAt)} version`;
1240
+ return 'Restored from earlier version';
1241
+ }
1012
1242
  if (change.Type === 'Create')
1013
1243
  return 'Record created';
1014
1244
  if (change.Type === 'Delete')
1015
1245
  return 'Record deleted';
1246
+ if (change.Type === 'Snapshot')
1247
+ return change.ChangesDescription || 'Snapshot captured';
1016
1248
  try {
1017
1249
  const changesJson = JSON.parse(change.ChangesJSON || '{}');
1018
1250
  const fieldNames = this.extractFieldDisplayNames(changesJson);
@@ -1029,9 +1261,7 @@ export class RecordChangesComponent {
1029
1261
  if (!change.FullRecordJSON)
1030
1262
  return 0;
1031
1263
  const record = JSON.parse(change.FullRecordJSON);
1032
- return this.record.EntityInfo.Fields
1033
- .filter((f) => record[f.Name] != null && record[f.Name] !== '')
1034
- .length;
1264
+ return this.record.EntityInfo.Fields.filter((f) => record[f.Name] != null && record[f.Name] !== '').length;
1035
1265
  }
1036
1266
  catch {
1037
1267
  return 0;
@@ -1082,7 +1312,7 @@ export class RecordChangesComponent {
1082
1312
  oldValue: formattedOld,
1083
1313
  newValue: formattedNew,
1084
1314
  fieldType,
1085
- diffHtml
1315
+ diffHtml,
1086
1316
  };
1087
1317
  }
1088
1318
  classifyFieldType(field) {
@@ -1107,7 +1337,7 @@ export class RecordChangesComponent {
1107
1337
  .map((field) => ({
1108
1338
  name: field.Name,
1109
1339
  displayName: field.DisplayNameOrName,
1110
- value: this.formatChangeValue(record[field.Name], field.TSType === EntityFieldTSType.Date)
1340
+ value: this.formatChangeValue(record[field.Name], field.TSType === EntityFieldTSType.Date),
1111
1341
  }));
1112
1342
  }
1113
1343
  catch {
@@ -1115,10 +1345,6 @@ export class RecordChangesComponent {
1115
1345
  }
1116
1346
  }
1117
1347
  // ─── Value Formatting ───────────────────────────────────────────
1118
- /**
1119
- * Formats a change value for display. Handles corrupted date values (stored as empty objects)
1120
- * and formats ISO date strings into a human-readable format.
1121
- */
1122
1348
  formatChangeValue(value, isDateField) {
1123
1349
  if (value == null)
1124
1350
  return '';
@@ -1137,7 +1363,7 @@ export class RecordChangesComponent {
1137
1363
  year: 'numeric',
1138
1364
  hour: 'numeric',
1139
1365
  minute: '2-digit',
1140
- hour12: true
1366
+ hour12: true,
1141
1367
  }).format(date);
1142
1368
  }
1143
1369
  }
@@ -1156,21 +1382,22 @@ export class RecordChangesComponent {
1156
1382
  }
1157
1383
  const useWordDiff = this.shouldUseWordDiff(oldValue, newValue);
1158
1384
  const diffs = useWordDiff ? diffWords(oldValue, newValue) : diffChars(oldValue, newValue);
1159
- const html = diffs.map((part) => {
1385
+ const html = diffs
1386
+ .map((part) => {
1160
1387
  const escaped = this.escapeHtml(part.value);
1161
1388
  if (part.added)
1162
1389
  return `<span class="rc-diff-added">${escaped}</span>`;
1163
1390
  if (part.removed)
1164
1391
  return `<span class="rc-diff-removed">${escaped}</span>`;
1165
1392
  return `<span class="rc-diff-unchanged">${escaped}</span>`;
1166
- }).join('');
1393
+ })
1394
+ .join('');
1167
1395
  return this.sanitizer.bypassSecurityTrustHtml(html);
1168
1396
  }
1169
1397
  shouldUseWordDiff(oldValue, newValue) {
1170
1398
  const hasMultipleWords = (text) => text.includes(' ') && text.split(' ').length > 3;
1171
1399
  const isLongText = (text) => text.length > 50;
1172
- return (hasMultipleWords(oldValue) || hasMultipleWords(newValue)) &&
1173
- (isLongText(oldValue) || isLongText(newValue));
1400
+ return (hasMultipleWords(oldValue) || hasMultipleWords(newValue)) && (isLongText(oldValue) || isLongText(newValue));
1174
1401
  }
1175
1402
  escapeHtml(text) {
1176
1403
  const div = document.createElement('div');
@@ -1178,12 +1405,14 @@ export class RecordChangesComponent {
1178
1405
  return div.innerHTML;
1179
1406
  }
1180
1407
  static ɵfac = function RecordChangesComponent_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || RecordChangesComponent)(i0.ɵɵdirectiveInject(i0.ChangeDetectorRef), i0.ɵɵdirectiveInject(i0.NgZone), i0.ɵɵdirectiveInject(i1.MJNotificationService), i0.ɵɵdirectiveInject(i2.DomSanitizer)); };
1181
- static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: RecordChangesComponent, selectors: [["mj-record-changes"]], inputs: { record: "record", AllowRestore: "AllowRestore" }, outputs: { dialogClosed: "dialogClosed", RestoreRequested: "RestoreRequested" }, standalone: false, decls: 5, vars: 10, consts: [[3, "Closed", "Mode", "Title", "Visible", "Resizable", "MinWidthPx", "MaxWidthRatio"], ["text", "Loading history...", "size", "medium"], [1, "rc-container"], [1, "rc-restore-preview-backdrop"], [1, "rc-wizard-overlay"], [1, "rc-labels-section"], [1, "rc-labels-header"], [1, "rc-labels-title"], ["aria-hidden", "true", 1, "fa-solid", "fa-tags"], [1, "rc-labels-count"], ["title", "Create a version label for this record", 1, "rc-create-label-btn", 3, "click"], [1, "fa-solid", "fa-plus"], [1, "rc-labels-loading"], [1, "rc-labels-empty"], [1, "rc-labels-list"], [1, "rc-empty-state"], [1, "fa-solid", "fa-spinner", "fa-spin"], [1, "rc-label-chip", 3, "title"], [1, "fa-solid", "fa-tag", "rc-label-chip-icon"], [1, "rc-label-chip-name"], [1, "rc-label-chip-meta"], [1, "rc-label-chip-status"], [1, "rc-label-chip-items"], [1, "rc-empty-state-icon"], [1, "fa-solid", "fa-clock-rotate-left"], [1, "rc-empty-state-title"], [1, "rc-empty-state-description"], [1, "rc-empty-state-hint"], [1, "fa-solid", "fa-shield-halved"], [1, "rc-page-header"], [1, "rc-page-title"], [1, "rc-page-subtitle"], [1, "rc-header-meta"], [1, "rc-entity-badge"], ["aria-hidden", "true", 1, "fa-solid", "fa-database"], [1, "rc-change-count"], [1, "rc-filter-bar"], [1, "rc-search-wrap"], ["aria-hidden", "true", 1, "fa-solid", "fa-search"], ["type", "text", "placeholder", "Search changes...", "aria-label", "Search record changes", 1, "rc-search-box", 3, "ngModelChange", "input", "ngModel"], [1, "rc-filter-pill", 3, "click"], ["aria-hidden", "true", 1, "fa-solid", "fa-layer-group"], ["aria-hidden", "true", 1, "fa-solid", "fa-pen"], ["aria-hidden", "true", 1, "fa-solid", "fa-plus"], ["aria-hidden", "true", 1, "fa-solid", "fa-trash"], [1, "rc-filter-results"], [1, "rc-timeline"], [1, "rc-no-results"], [1, "rc-clear-filters-link", 3, "click"], ["aria-hidden", "true", 1, "fa-solid", "fa-filter"], [1, "rc-clear-filters-btn", 3, "click"], [1, "fa-solid", "fa-xmark"], [1, "rc-date-group"], [1, "rc-date-label"], [1, "rc-card", 3, "class", "expanded"], [1, "rc-card", 3, "keydown"], [1, "rc-card-header", 3, "click"], [1, "rc-card-header-left"], [1, "rc-card-type-badge"], [1, "rc-card-summary"], [1, "rc-card-meta"], [1, "rc-card-user"], [1, "rc-avatar"], [1, "rc-card-time", 3, "title"], [1, "rc-card-source"], [1, "rc-card-status"], ["aria-hidden", "true", 1, "fa-solid", "fa-chevron-down", "rc-card-chevron"], [1, "rc-card-body"], [1, "rc-deletion-note"], [1, "rc-comments"], [1, "rc-errors"], [1, "rc-restore-action"], [1, "rc-field-row"], [1, "rc-field-label"], [1, "rc-field-values"], [1, "rc-val-new"], [1, "rc-bool-change"], [1, "rc-atomic-change"], [1, "rc-text-diff", 3, "innerHTML"], [1, "rc-bool-dot"], [1, "rc-bool-label", "old"], ["aria-hidden", "true", 1, "fa-solid", "fa-arrow-right", "rc-val-arrow"], [1, "rc-bool-label", "new"], [1, "rc-val-old"], ["aria-hidden", "true", 1, "fa-solid", "fa-comment"], ["aria-hidden", "true", 1, "fa-solid", "fa-exclamation-triangle"], [1, "rc-error-log"], ["title", "Restore field values from before this change", 1, "rc-restore-btn", 3, "click"], ["aria-hidden", "true", 1, "fa-solid", "fa-clock-rotate-left"], [1, "rc-restore-preview-backdrop", 3, "click"], [1, "rc-restore-preview-panel", 3, "click"], [1, "rc-restore-preview-header"], [1, "rc-restore-preview-title"], ["title", "Close preview", 1, "rc-restore-preview-close", 3, "click"], [1, "fa-solid", "fa-times"], [1, "rc-restore-preview-meta"], [1, "rc-restore-preview-empty"], [1, "rc-restore-preview-table"], [1, "rc-restore-preview-actions"], [1, "rc-restore-confirm-btn", 3, "click", "disabled"], [1, "rc-restore-cancel-btn", 3, "click", "disabled"], ["aria-hidden", "true", 1, "fa-solid", "fa-circle-info"], [3, "rc-diff-changed", "rc-diff-unchanged"], [1, "rc-restore-field-name"], [1, "rc-restore-current"], [1, "rc-restore-version"], [1, "rc-restore-indicator"], ["title", "Will be changed", 1, "fa-solid", "fa-circle-exclamation"], ["title", "Already matches", 1, "fa-solid", "fa-check"], ["aria-hidden", "true", 1, "fa-solid", "fa-spinner", "fa-spin"], ["aria-hidden", "true", 1, "fa-solid", "fa-rotate-left"], [1, "rc-wizard-overlay", 3, "click"], [1, "rc-wizard-container", 3, "click"], [3, "Created", "Cancel", "PreselectedEntity", "PreselectedRecordIds"]], template: function RecordChangesComponent_Template(rf, ctx) { if (rf & 1) {
1408
+ static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: RecordChangesComponent, selectors: [["mj-record-changes"]], inputs: { record: "record", AllowRestore: "AllowRestore" }, outputs: { dialogClosed: "dialogClosed", RestoreRequested: "RestoreRequested" }, standalone: false, decls: 5, vars: 13, consts: [[3, "Closed", "Mode", "Title", "Visible", "Resizable", "MinWidthPx", "MaxWidthRatio"], ["text", "Loading history...", "size", "medium"], [1, "rc-container"], [3, "RestoreConfirmed", "RestoreCancelled", "Visible", "Mode", "RecordChange", "LiveRecord"], [1, "rc-wizard-overlay"], [1, "rc-labels-section"], [1, "rc-labels-header"], [1, "rc-labels-title"], ["aria-hidden", "true", 1, "fa-solid", "fa-tags"], [1, "rc-labels-count"], ["title", "Create a version label for this record", 1, "rc-create-label-btn", 3, "click"], [1, "fa-solid", "fa-plus"], [1, "rc-labels-loading"], [1, "rc-labels-empty"], [1, "rc-labels-list"], [1, "rc-empty-state"], [1, "fa-solid", "fa-spinner", "fa-spin"], [1, "rc-label-chip", 3, "title"], [1, "fa-solid", "fa-tag", "rc-label-chip-icon"], [1, "rc-label-chip-name"], [1, "rc-label-chip-meta"], [1, "rc-label-chip-status"], [1, "rc-label-chip-items"], [1, "rc-empty-state-icon"], [1, "fa-solid", "fa-clock-rotate-left"], [1, "rc-empty-state-title"], [1, "rc-empty-state-description"], [1, "rc-empty-state-hint"], [1, "fa-solid", "fa-shield-halved"], [1, "rc-page-header"], [1, "rc-page-title"], [1, "rc-page-subtitle"], [1, "rc-header-meta"], [1, "rc-entity-badge"], ["aria-hidden", "true", 1, "fa-solid", "fa-database"], [1, "rc-change-count"], [1, "rc-filter-bar"], [1, "rc-search-wrap"], ["aria-hidden", "true", 1, "fa-solid", "fa-search"], ["type", "text", "placeholder", "Search changes...", "aria-label", "Search record changes", 1, "rc-search-box", 3, "ngModelChange", "input", "ngModel"], ["type", "button", 1, "rc-filter-pill", 3, "click"], ["aria-hidden", "true", 1, "fa-solid", "fa-layer-group"], [1, "rc-filter-results"], [1, "rc-timeline"], [1, "rc-no-results"], [1, "rc-filter-overflow-wrap"], ["type", "button", 1, "rc-filter-pill", 3, "active", "rc-filter-pill-restore"], ["aria-hidden", "true"], [1, "rc-filter-pill-count"], ["type", "button", 1, "rc-filter-pill", "rc-filter-pill-overflow", 3, "click"], ["aria-hidden", "true", 1, "fa-solid", "fa-sliders"], ["aria-hidden", "true", 1, "fa-solid", "fa-chevron-down", "rc-filter-overflow-caret"], [1, "rc-filter-overflow-backdrop", 3, "click"], ["role", "menu", 1, "rc-filter-overflow-popover"], [1, "rc-filter-overflow-header"], [1, "rc-filter-overflow-row", 3, "rc-filter-overflow-row-restore"], [1, "rc-filter-overflow-actions"], ["type", "button", 1, "rc-filter-overflow-clear", 3, "click"], ["type", "button", 1, "rc-filter-overflow-done", 3, "click"], [1, "rc-filter-overflow-row"], ["type", "checkbox", 3, "change", "checked"], [1, "rc-filter-overflow-label"], [1, "rc-filter-overflow-count"], [1, "rc-clear-filters-link", 3, "click"], ["aria-hidden", "true", 1, "fa-solid", "fa-filter"], [1, "rc-clear-filters-btn", 3, "click"], [1, "fa-solid", "fa-xmark"], [1, "rc-date-group"], [1, "rc-date-label"], [1, "rc-card", 3, "class", "expanded", "rc-card-restore", "rc-card-highlight"], [1, "rc-card", 3, "keydown"], [1, "rc-card-header", 3, "click"], [1, "rc-card-header-left"], [1, "rc-card-type-badge"], [1, "rc-card-summary"], [1, "rc-card-meta"], [1, "rc-card-user"], [1, "rc-avatar"], [1, "rc-card-time", 3, "title"], [1, "rc-card-source"], [1, "rc-card-status"], ["aria-hidden", "true", 1, "fa-solid", "fa-chevron-down", "rc-card-chevron"], [1, "rc-card-body"], [1, "rc-restored-chip", 3, "title"], ["title", "Source version was not loaded into this view", 1, "rc-restored-chip", "rc-restored-chip-orphan"], [1, "rc-restored-chip", 3, "click", "title"], ["aria-hidden", "true", 1, "fa-solid", "fa-link"], ["aria-hidden", "true", 1, "fa-solid", "fa-clock-rotate-left"], [1, "rc-restore-reason"], [1, "rc-deletion-note"], [1, "rc-comments"], [1, "rc-errors"], [1, "rc-restore-action"], [1, "rc-restore-reason-label"], [1, "rc-restore-reason-text"], [1, "rc-field-row"], [1, "rc-field-label"], [1, "rc-field-values"], [1, "rc-val-new"], ["aria-hidden", "true", 1, "fa-solid", "fa-trash"], [1, "rc-bool-change"], [1, "rc-atomic-change"], [1, "rc-text-diff", 3, "innerHTML"], [1, "rc-bool-dot"], [1, "rc-bool-label", "old"], ["aria-hidden", "true", 1, "fa-solid", "fa-arrow-right", "rc-val-arrow"], [1, "rc-bool-label", "new"], [1, "rc-val-old"], ["aria-hidden", "true", 1, "fa-solid", "fa-comment"], ["aria-hidden", "true", 1, "fa-solid", "fa-exclamation-triangle"], [1, "rc-error-log"], ["title", "Restore the entire record to its state at this version", 1, "rc-restore-btn", 3, "click"], [1, "rc-wizard-overlay", 3, "click"], [1, "rc-wizard-container", 3, "click"], [3, "Created", "Cancel", "PreselectedEntity", "PreselectedRecordIds"]], template: function RecordChangesComponent_Template(rf, ctx) { if (rf & 1) {
1182
1409
  i0.ɵɵelementStart(0, "mj-slide-panel", 0);
1183
1410
  i0.ɵɵlistener("Closed", function RecordChangesComponent_Template_mj_slide_panel_Closed_0_listener() { return ctx.OnClose(); });
1184
1411
  i0.ɵɵconditionalCreate(1, RecordChangesComponent_Conditional_1_Template, 1, 0, "mj-loading", 1);
1185
1412
  i0.ɵɵconditionalCreate(2, RecordChangesComponent_Conditional_2_Template, 16, 3, "div", 2);
1186
- i0.ɵɵconditionalCreate(3, RecordChangesComponent_Conditional_3_Template, 25, 6, "div", 3);
1413
+ i0.ɵɵelementStart(3, "mj-restore-preview-panel", 3);
1414
+ i0.ɵɵlistener("RestoreConfirmed", function RecordChangesComponent_Template_mj_restore_preview_panel_RestoreConfirmed_3_listener($event) { return ctx.OnRestorePanelConfirmed($event); })("RestoreCancelled", function RecordChangesComponent_Template_mj_restore_preview_panel_RestoreCancelled_3_listener() { return ctx.OnRestorePanelCancelled(); });
1415
+ i0.ɵɵelementEnd();
1187
1416
  i0.ɵɵconditionalCreate(4, RecordChangesComponent_Conditional_4_Template, 3, 4, "div", 4);
1188
1417
  i0.ɵɵelementEnd();
1189
1418
  } if (rf & 2) {
@@ -1193,14 +1422,14 @@ export class RecordChangesComponent {
1193
1422
  i0.ɵɵadvance();
1194
1423
  i0.ɵɵconditional(!ctx.IsLoading ? 2 : -1);
1195
1424
  i0.ɵɵadvance();
1196
- i0.ɵɵconditional(ctx.RestorePreview ? 3 : -1);
1425
+ i0.ɵɵproperty("Visible", ctx.RestorePreviewVisible)("Mode", "live")("RecordChange", ctx.RestorePreviewChange)("LiveRecord", ctx.record);
1197
1426
  i0.ɵɵadvance();
1198
1427
  i0.ɵɵconditional(ctx.ShowCreateWizard ? 4 : -1);
1199
- } }, dependencies: [i3.DefaultValueAccessor, i3.NgControlStatus, i3.NgModel, i4.LoadingComponent, i5.MjSlidePanelComponent, i5.MjLabelCreateComponent], styles: ["/* \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n Record Changes \u2014 Option A \"Clean Timeline\"\n Linear / Notion-inspired minimal timeline design\n \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 */\n\n/* \u2500\u2500\u2500 Container \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.rc-container {\n display: flex;\n flex-direction: column;\n height: 100%;\n padding: 20px 24px;\n background: var(--mj-bg-surface-card);\n}\n\n/* \u2500\u2500\u2500 Version Labels Section \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.rc-labels-section {\n background: var(--mj-bg-surface-card);\n border-radius: 8px;\n padding: 12px 16px;\n margin-bottom: 20px;\n border: 1px solid var(--mj-border-default);\n}\n\n.rc-labels-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: 8px;\n}\n\n.rc-labels-title {\n display: flex;\n align-items: center;\n gap: 8px;\n font-weight: 600;\n font-size: 13px;\n color: var(--mj-text-secondary);\n}\n\n.rc-labels-title i { color: var(--mj-brand-primary); }\n\n.rc-labels-count {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n min-width: 20px;\n height: 20px;\n padding: 0 6px;\n border-radius: 10px;\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n font-size: 10px;\n font-weight: 700;\n}\n\n.rc-create-label-btn {\n display: inline-flex;\n align-items: center;\n gap: 5px;\n padding: 5px 12px;\n border: 1px solid var(--mj-brand-primary);\n border-radius: 6px;\n background: var(--mj-bg-surface);\n color: var(--mj-brand-primary);\n font-size: 12px;\n font-weight: 600;\n cursor: pointer;\n transition: all 0.15s ease;\n}\n\n.rc-create-label-btn:hover {\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n}\n\n.rc-labels-loading {\n font-size: 12px;\n color: var(--mj-text-muted);\n padding: 4px 0;\n}\n\n.rc-labels-loading i { margin-right: 4px; }\n\n.rc-labels-empty {\n font-size: 12px;\n color: var(--mj-text-disabled);\n font-style: italic;\n padding: 4px 0;\n}\n\n.rc-labels-list {\n display: flex;\n flex-wrap: wrap;\n gap: 8px;\n}\n\n.rc-label-chip {\n display: inline-flex;\n align-items: center;\n gap: 5px;\n padding: 4px 10px;\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: 16px;\n font-size: 12px;\n color: var(--mj-text-secondary);\n transition: all 0.15s ease;\n cursor: default;\n}\n\n.rc-label-chip:hover {\n border-color: var(--mj-brand-primary);\n box-shadow: var(--mj-shadow-sm);\n}\n\n.rc-label-chip-icon { color: var(--mj-brand-primary); font-size: 10px; }\n\n.rc-label-chip-name {\n font-weight: 600;\n max-width: 180px;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.rc-label-chip-meta {\n display: flex;\n align-items: center;\n gap: 4px;\n font-size: 10px;\n color: var(--mj-text-muted);\n}\n\n.rc-label-chip-status {\n padding: 1px 5px;\n border-radius: 4px;\n font-weight: 600;\n text-transform: uppercase;\n font-size: 9px;\n letter-spacing: 0.03em;\n}\n\n.label-status-active { background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface)); color: var(--mj-status-success); }\n.label-status-archived { background: var(--mj-bg-surface-sunken); color: var(--mj-text-secondary); }\n.label-status-restored { background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface)); color: var(--mj-brand-primary); }\n\n.rc-label-chip-items { white-space: nowrap; }\n\n/* \u2500\u2500\u2500 Empty State \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.rc-empty-state {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 64px 32px;\n text-align: center;\n min-height: 400px;\n}\n\n.rc-empty-state-icon {\n width: 80px;\n height: 80px;\n border-radius: 50%;\n background: var(--mj-bg-surface-sunken);\n display: flex;\n align-items: center;\n justify-content: center;\n margin-bottom: 24px;\n}\n\n.rc-empty-state-icon i { font-size: 32px; color: var(--mj-text-disabled); }\n\n.rc-empty-state-title {\n font-size: 20px;\n font-weight: 600;\n color: var(--mj-text-secondary);\n margin: 0 0 12px 0;\n}\n\n.rc-empty-state-description {\n font-size: 14px;\n color: var(--mj-text-muted);\n line-height: 1.6;\n max-width: 320px;\n margin: 0 0 24px 0;\n}\n\n.rc-empty-state-hint {\n display: inline-flex;\n align-items: center;\n gap: 8px;\n padding: 8px 16px;\n background: var(--mj-bg-surface-sunken);\n border-radius: 20px;\n font-size: 12px;\n color: var(--mj-text-muted);\n}\n\n.rc-empty-state-hint i { color: var(--mj-text-disabled); }\n\n/* \u2500\u2500\u2500 Page Header \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.rc-page-header {\n display: flex;\n justify-content: space-between;\n align-items: flex-start;\n margin-bottom: 24px;\n padding-bottom: 20px;\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.rc-page-title {\n font-size: 20px;\n font-weight: 700;\n color: var(--mj-text-primary);\n margin: 0;\n}\n\n.rc-page-subtitle {\n font-size: 13px;\n color: var(--mj-text-muted);\n margin-top: 4px;\n}\n\n.rc-header-meta { text-align: right; }\n\n.rc-entity-badge {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 5px 12px;\n border-radius: 6px;\n font-size: 12px;\n font-weight: 500;\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n border: 1px solid color-mix(in srgb, var(--mj-brand-primary) 25%, var(--mj-bg-surface));\n}\n\n.rc-change-count {\n font-size: 12px;\n color: var(--mj-text-disabled);\n margin-top: 6px;\n}\n\n/* \u2500\u2500\u2500 Filter Bar \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.rc-filter-bar {\n display: flex;\n gap: 8px;\n margin-bottom: 20px;\n flex-wrap: wrap;\n align-items: center;\n}\n\n.rc-search-wrap {\n position: relative;\n flex: 1;\n min-width: 180px;\n}\n\n.rc-search-wrap i {\n position: absolute;\n left: 12px;\n top: 50%;\n transform: translateY(-50%);\n color: var(--mj-text-disabled);\n font-size: 13px;\n pointer-events: none;\n}\n\n.rc-search-box {\n width: 100%;\n padding: 8px 12px 8px 36px;\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n font-size: 13px;\n background: var(--mj-bg-surface);\n outline: none;\n color: var(--mj-text-primary);\n transition: border-color 0.15s, box-shadow 0.15s;\n}\n\n.rc-search-box:focus {\n border-color: var(--mj-brand-primary);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n}\n\n.rc-search-box::placeholder { color: var(--mj-text-disabled); }\n\n.rc-filter-pill {\n padding: 7px 14px;\n border-radius: 8px;\n font-size: 12px;\n font-weight: 500;\n border: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface);\n cursor: pointer;\n color: var(--mj-text-secondary);\n transition: all 0.15s;\n display: flex;\n align-items: center;\n gap: 5px;\n}\n\n.rc-filter-pill:hover {\n border-color: var(--mj-brand-primary);\n color: var(--mj-brand-primary);\n}\n\n.rc-filter-pill.active {\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n border-color: var(--mj-brand-primary);\n}\n\n.rc-filter-results {\n font-size: 12px;\n color: var(--mj-text-muted);\n margin-bottom: 16px;\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.rc-clear-filters-link {\n background: none;\n border: none;\n color: var(--mj-brand-primary);\n font-size: 12px;\n font-weight: 500;\n cursor: pointer;\n padding: 0;\n text-decoration: underline;\n}\n\n.rc-clear-filters-link:hover { color: var(--mj-brand-primary-hover); }\n\n/* \u2500\u2500\u2500 No Results \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.rc-no-results {\n text-align: center;\n padding: 48px 16px;\n color: var(--mj-text-muted);\n}\n\n.rc-no-results i {\n display: block;\n font-size: 32px;\n margin-bottom: 16px;\n color: var(--mj-text-disabled);\n}\n\n.rc-no-results p { font-size: 14px; margin: 0 0 16px 0; }\n\n.rc-clear-filters-btn {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 6px 16px;\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n background: var(--mj-bg-surface);\n color: var(--mj-text-secondary);\n font-size: 13px;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.15s ease;\n}\n\n.rc-clear-filters-btn:hover {\n border-color: var(--mj-brand-primary);\n color: var(--mj-brand-primary);\n}\n\n/* \u2500\u2500\u2500 Timeline \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.rc-timeline {\n position: relative;\n flex: 1;\n overflow-y: auto;\n}\n\n/* Vertical line running through the timeline */\n.rc-timeline::before {\n content: '';\n position: absolute;\n left: 15px;\n top: 24px;\n bottom: 0;\n width: 2px;\n background: var(--mj-border-default);\n}\n\n/* \u2500\u2500\u2500 Date Group \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.rc-date-group { margin-bottom: 8px; }\n\n.rc-date-label {\n position: relative;\n font-size: 11px;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.8px;\n color: var(--mj-text-disabled);\n padding: 16px 0 12px 44px;\n}\n\n/* Date dot on the timeline line */\n.rc-date-label::before {\n content: '';\n position: absolute;\n left: 10px;\n top: 50%;\n transform: translateY(-50%);\n width: 12px;\n height: 12px;\n border-radius: 50%;\n background: var(--mj-border-default);\n border: 2px solid var(--mj-bg-surface-card);\n}\n\n/* \u2500\u2500\u2500 Change Card \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.rc-card {\n position: relative;\n margin-left: 44px;\n margin-bottom: 12px;\n background: var(--mj-bg-surface);\n border-radius: 12px;\n border: 1px solid var(--mj-border-default);\n transition: all 0.2s;\n overflow: hidden;\n}\n\n.rc-card:hover {\n border-color: var(--mj-border-strong);\n box-shadow: var(--mj-shadow-sm);\n}\n\n.rc-card:focus {\n outline: 2px solid var(--mj-brand-primary);\n outline-offset: 2px;\n}\n\n/* Colored dot on the timeline line for each card */\n.rc-card::before {\n content: '';\n position: absolute;\n left: -23px;\n top: 20px;\n width: 8px;\n height: 8px;\n border-radius: 50%;\n z-index: 1;\n}\n\n.rc-card.type-update::before {\n background: var(--mj-brand-primary);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n}\n\n.rc-card.type-create::before {\n background: var(--mj-status-success);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-status-success) 15%, transparent);\n}\n\n.rc-card.type-delete::before {\n background: var(--mj-status-error);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-status-error) 15%, transparent);\n}\n\n/* \u2500\u2500\u2500 Card Header \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.rc-card-header {\n padding: 14px 18px;\n display: flex;\n justify-content: space-between;\n align-items: center;\n cursor: pointer;\n user-select: none;\n gap: 12px;\n}\n\n.rc-card-header-left {\n display: flex;\n align-items: center;\n gap: 10px;\n min-width: 0;\n flex: 1;\n}\n\n.rc-card-type-badge {\n padding: 3px 10px;\n border-radius: 5px;\n font-size: 10px;\n font-weight: 600;\n letter-spacing: 0.3px;\n text-transform: uppercase;\n white-space: nowrap;\n flex-shrink: 0;\n}\n\n.type-update .rc-card-type-badge { background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface)); color: var(--mj-brand-primary); }\n.type-create .rc-card-type-badge { background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface)); color: var(--mj-status-success); }\n.type-delete .rc-card-type-badge { background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface)); color: var(--mj-status-error); }\n\n.rc-card-summary {\n font-size: 13px;\n color: var(--mj-text-secondary);\n font-weight: 500;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.rc-card-meta {\n display: flex;\n align-items: center;\n gap: 12px;\n font-size: 12px;\n color: var(--mj-text-disabled);\n flex-shrink: 0;\n}\n\n.rc-card-user {\n display: flex;\n align-items: center;\n gap: 5px;\n white-space: nowrap;\n}\n\n.rc-avatar {\n width: 20px;\n height: 20px;\n border-radius: 50%;\n background: var(--mj-brand-primary);\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 8px;\n font-weight: 700;\n color: var(--mj-text-inverse);\n flex-shrink: 0;\n}\n\n.rc-card-time { white-space: nowrap; }\n\n.rc-card-source {\n font-size: 10px;\n padding: 2px 6px;\n border-radius: 4px;\n font-weight: 500;\n white-space: nowrap;\n}\n\n.source-internal { background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface)); color: var(--mj-brand-primary); }\n.source-external { background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface)); color: var(--mj-status-warning); }\n\n.rc-card-status {\n font-size: 10px;\n padding: 2px 6px;\n border-radius: 4px;\n font-weight: 600;\n text-transform: uppercase;\n white-space: nowrap;\n}\n\n.status-complete { background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface)); color: var(--mj-status-success); }\n.status-pending { background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface)); color: var(--mj-status-warning); }\n.status-error { background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface)); color: var(--mj-status-error); }\n.status-unknown { background: var(--mj-bg-surface-sunken); color: var(--mj-text-muted); }\n\n.rc-card-chevron {\n color: var(--mj-text-disabled);\n transition: transform 0.2s;\n font-size: 12px;\n flex-shrink: 0;\n}\n\n.rc-card.expanded .rc-card-chevron { transform: rotate(180deg); }\n\n/* \u2500\u2500\u2500 Card Body \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.rc-card-body {\n border-top: 1px solid var(--mj-border-default);\n}\n\n/* \u2500\u2500\u2500 Field Row \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.rc-field-row {\n display: flex;\n align-items: stretch;\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.rc-field-row:last-child { border-bottom: none; }\n\n.rc-field-label {\n width: 140px;\n min-width: 140px;\n padding: 12px 16px;\n font-size: 12px;\n font-weight: 600;\n color: var(--mj-text-muted);\n background: var(--mj-bg-surface-card);\n display: flex;\n align-items: center;\n border-right: 1px solid var(--mj-border-default);\n}\n\n.rc-field-values {\n flex: 1;\n padding: 12px 16px;\n display: flex;\n align-items: center;\n min-width: 0;\n}\n\n/* \u2500\u2500\u2500 Atomic Change (numbers, dates) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.rc-atomic-change {\n display: flex;\n align-items: center;\n gap: 10px;\n flex-wrap: wrap;\n}\n\n.rc-val-old {\n font-size: 13px;\n font-family: 'SFMono-Regular', 'Consolas', 'Liberation Mono', 'Menlo', monospace;\n color: var(--mj-text-disabled);\n text-decoration: line-through;\n font-weight: 400;\n}\n\n.rc-val-arrow {\n color: var(--mj-border-strong);\n font-size: 11px;\n flex-shrink: 0;\n}\n\n.rc-val-new {\n font-size: 13px;\n font-family: 'SFMono-Regular', 'Consolas', 'Liberation Mono', 'Menlo', monospace;\n color: var(--mj-text-primary);\n font-weight: 500;\n}\n\n/* \u2500\u2500\u2500 Boolean Change \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.rc-bool-change {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.rc-bool-dot {\n width: 8px;\n height: 8px;\n border-radius: 50%;\n flex-shrink: 0;\n}\n\n.rc-bool-dot.on { background: var(--mj-status-success); }\n.rc-bool-dot.off { background: var(--mj-border-strong); }\n\n.rc-bool-label {\n font-size: 13px;\n font-weight: 500;\n}\n\n.rc-bool-label.old {\n color: var(--mj-text-disabled);\n text-decoration: line-through;\n}\n\n.rc-bool-label.new.active { color: var(--mj-status-success); }\n.rc-bool-label.new.inactive { color: var(--mj-text-disabled); }\n\n/* \u2500\u2500\u2500 Text Diff (strings only) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.rc-text-diff {\n font-size: 13px;\n font-family: 'SFMono-Regular', 'Consolas', 'Liberation Mono', 'Menlo', monospace;\n line-height: 1.6;\n word-wrap: break-word;\n white-space: pre-wrap;\n}\n\n.rc-diff-added {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n color: var(--mj-status-success);\n padding: 1px 3px;\n border-radius: 3px;\n}\n\n.rc-diff-removed {\n background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n color: var(--mj-status-error);\n padding: 1px 3px;\n border-radius: 3px;\n text-decoration: line-through;\n}\n\n.rc-diff-unchanged {\n color: var(--mj-text-secondary);\n}\n\n/* \u2500\u2500\u2500 Deletion Note \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.rc-deletion-note {\n padding: 16px 18px;\n color: var(--mj-text-muted);\n font-size: 13px;\n font-style: italic;\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.rc-deletion-note i {\n color: var(--mj-status-error);\n font-size: 14px;\n}\n\n/* \u2500\u2500\u2500 Comments & Errors \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.rc-comments {\n padding: 12px 18px;\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n font-size: 13px;\n color: var(--mj-brand-primary);\n display: flex;\n align-items: flex-start;\n gap: 8px;\n border-top: 1px solid var(--mj-border-default);\n}\n\n.rc-comments i {\n color: var(--mj-brand-primary);\n margin-top: 2px;\n flex-shrink: 0;\n}\n\n.rc-errors {\n padding: 12px 18px;\n background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n font-size: 13px;\n color: var(--mj-status-error);\n display: flex;\n align-items: flex-start;\n gap: 8px;\n border-top: 1px solid var(--mj-border-default);\n}\n\n.rc-errors i {\n color: var(--mj-status-error);\n margin-top: 2px;\n flex-shrink: 0;\n}\n\n.rc-error-log {\n background: var(--mj-bg-surface);\n padding: 8px;\n border-radius: 4px;\n font-family: 'SFMono-Regular', 'Consolas', 'Liberation Mono', 'Menlo', monospace;\n font-size: 12px;\n color: var(--mj-status-error);\n margin: 0;\n white-space: pre-wrap;\n overflow-x: auto;\n flex: 1;\n}\n\n/* \u2500\u2500\u2500 Create Wizard Overlay \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.rc-wizard-overlay {\n position: fixed;\n inset: 0;\n background: var(--mj-bg-overlay);\n z-index: 10000;\n display: flex;\n align-items: center;\n justify-content: center;\n animation: rc-fadeIn 0.15s ease;\n}\n\n.rc-wizard-container {\n background: var(--mj-bg-surface);\n border-radius: 12px;\n box-shadow: var(--mj-shadow-lg);\n width: 90%;\n max-width: 600px;\n max-height: 80vh;\n overflow-y: auto;\n padding: 24px;\n animation: rc-slideUp 0.2s ease;\n}\n\n@keyframes rc-fadeIn {\n from { opacity: 0; }\n to { opacity: 1; }\n}\n\n@keyframes rc-slideUp {\n from { opacity: 0; transform: translateY(20px); }\n to { opacity: 1; transform: translateY(0); }\n}\n\n/* \u2500\u2500\u2500 Responsive \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n@media (max-width: 768px) {\n .rc-card-header {\n flex-direction: column;\n align-items: flex-start;\n gap: 8px;\n }\n\n .rc-card-meta {\n flex-wrap: wrap;\n gap: 8px;\n }\n\n .rc-field-row {\n flex-direction: column;\n }\n\n .rc-field-label {\n width: 100%;\n min-width: unset;\n border-right: none;\n border-bottom: 1px solid var(--mj-border-default);\n padding: 8px 16px;\n }\n\n .rc-field-values {\n padding: 8px 16px;\n }\n\n .rc-atomic-change {\n flex-wrap: wrap;\n }\n\n .rc-filter-bar {\n flex-direction: column;\n align-items: stretch;\n }\n\n .rc-search-wrap { min-width: unset; }\n\n .rc-filter-pill { justify-content: center; }\n\n .rc-page-header {\n flex-direction: column;\n gap: 12px;\n }\n\n .rc-header-meta { text-align: left; }\n}\n\n@media (max-width: 480px) {\n .rc-container { padding: 12px 16px; }\n\n .rc-card { margin-left: 36px; }\n\n .rc-date-label { padding-left: 36px; }\n\n .rc-card::before { left: -19px; }\n\n .rc-timeline::before { left: 12px; }\n\n .rc-date-label::before { left: 7px; }\n}\n\n/* \u2500\u2500\u2500 Restore Action \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.rc-restore-action {\n display: flex;\n justify-content: flex-end;\n padding-top: 10px;\n margin-top: 10px;\n border-top: 1px solid var(--mj-border-subtle);\n}\n\n.rc-restore-btn {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 6px 14px;\n font-size: 12px;\n font-weight: 500;\n color: var(--mj-brand-primary);\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%, transparent);\n border-radius: 6px;\n cursor: pointer;\n transition: all 150ms ease;\n font-family: inherit;\n line-height: 1;\n}\n\n.rc-restore-btn:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n border-color: var(--mj-brand-primary);\n box-shadow: 0 2px 6px color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n}\n\n.rc-restore-btn:active {\n transform: translateY(1px);\n box-shadow: none;\n}\n\n.rc-restore-btn i {\n font-size: 13px;\n}\n\n/* \u2500\u2500\u2500 Restore Preview Panel \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.rc-restore-preview-backdrop {\n position: fixed;\n inset: 0;\n background: var(--mj-bg-overlay);\n z-index: 10000;\n display: flex;\n align-items: center;\n justify-content: center;\n animation: rc-fadeIn 0.15s ease;\n}\n\n.rc-restore-preview-panel {\n background: var(--mj-bg-surface);\n border-radius: 12px;\n box-shadow: var(--mj-shadow-lg);\n width: 90%;\n max-width: 700px;\n max-height: 80vh;\n overflow-y: auto;\n padding: 0;\n animation: rc-slideUp 0.2s ease;\n}\n\n.rc-restore-preview-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 16px 20px;\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.rc-restore-preview-title {\n display: flex;\n align-items: center;\n gap: 8px;\n font-size: 16px;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.rc-restore-preview-title i {\n color: var(--mj-brand-primary);\n}\n\n.rc-restore-preview-close {\n background: none;\n border: none;\n color: var(--mj-text-muted);\n cursor: pointer;\n padding: 4px 8px;\n border-radius: 4px;\n font-size: 16px;\n transition: color 0.15s, background 0.15s;\n}\n\n.rc-restore-preview-close:hover {\n color: var(--mj-text-primary);\n background: var(--mj-bg-surface-hover);\n}\n\n.rc-restore-preview-meta {\n display: flex;\n gap: 20px;\n padding: 12px 20px;\n font-size: 13px;\n color: var(--mj-text-secondary);\n background: var(--mj-bg-surface-card);\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.rc-restore-preview-empty {\n padding: 24px 20px;\n text-align: center;\n color: var(--mj-text-muted);\n font-size: 13px;\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 8px;\n}\n\n.rc-restore-preview-empty i {\n color: var(--mj-text-disabled);\n}\n\n/* Restore Preview Table */\n.rc-restore-preview-table {\n width: 100%;\n border-collapse: collapse;\n font-size: 13px;\n}\n\n.rc-restore-preview-table th {\n text-align: left;\n padding: 10px 16px;\n font-weight: 600;\n font-size: 11px;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n color: var(--mj-text-muted);\n background: var(--mj-bg-surface-sunken);\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.rc-restore-preview-table td {\n padding: 10px 16px;\n border-bottom: 1px solid var(--mj-border-default);\n vertical-align: top;\n}\n\n.rc-restore-preview-table tr:last-child td {\n border-bottom: none;\n}\n\n.rc-restore-preview-table tr.rc-diff-changed {\n background: color-mix(in srgb, var(--mj-status-warning) 5%, var(--mj-bg-surface));\n}\n\n.rc-restore-preview-table tr.rc-diff-unchanged {\n opacity: 0.6;\n}\n\n.rc-restore-field-name {\n font-weight: 600;\n color: var(--mj-text-primary);\n white-space: nowrap;\n}\n\n.rc-restore-current {\n font-family: 'SFMono-Regular', 'Consolas', 'Liberation Mono', 'Menlo', monospace;\n color: var(--mj-text-secondary);\n max-width: 200px;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.rc-restore-version {\n font-family: 'SFMono-Regular', 'Consolas', 'Liberation Mono', 'Menlo', monospace;\n color: var(--mj-text-primary);\n font-weight: 500;\n max-width: 200px;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.rc-restore-indicator {\n text-align: center;\n width: 30px;\n}\n\n.rc-diff-changed .rc-restore-indicator i {\n color: var(--mj-status-warning);\n}\n\n.rc-diff-unchanged .rc-restore-indicator i {\n color: var(--mj-status-success);\n font-size: 12px;\n}\n\n/* Restore Preview Actions */\n.rc-restore-preview-actions {\n display: flex;\n gap: 10px;\n padding: 16px 20px;\n border-top: 1px solid var(--mj-border-default);\n}\n\n.rc-restore-confirm-btn {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 8px 18px;\n font-size: 13px;\n font-weight: 600;\n color: var(--mj-text-inverse);\n background: var(--mj-brand-primary);\n border: none;\n border-radius: 8px;\n cursor: pointer;\n transition: background 0.15s, box-shadow 0.15s;\n font-family: inherit;\n}\n\n.rc-restore-confirm-btn:hover:not(:disabled) {\n background: var(--mj-brand-primary-hover);\n box-shadow: 0 2px 8px color-mix(in srgb, var(--mj-brand-primary) 25%, transparent);\n}\n\n.rc-restore-confirm-btn:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.rc-restore-cancel-btn {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 8px 18px;\n font-size: 13px;\n font-weight: 500;\n color: var(--mj-text-secondary);\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n cursor: pointer;\n transition: all 0.15s;\n font-family: inherit;\n}\n\n.rc-restore-cancel-btn:hover:not(:disabled) {\n border-color: var(--mj-border-strong);\n color: var(--mj-text-primary);\n}\n\n.rc-restore-cancel-btn:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n"], encapsulation: 2, changeDetection: 0 });
1428
+ } }, dependencies: [i3.DefaultValueAccessor, i3.NgControlStatus, i3.NgModel, i4.LoadingComponent, i5.MjSlidePanelComponent, i5.MjLabelCreateComponent, i6.RestorePreviewPanelComponent, i7.DatePipe], styles: ["/* \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n Record Changes \u2014 Option A \"Clean Timeline\"\n Linear / Notion-inspired minimal timeline design\n \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 */\n\n/* \u2500\u2500\u2500 Container \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.rc-container {\n display: flex;\n flex-direction: column;\n height: 100%;\n padding: 20px 24px;\n background: var(--mj-bg-surface-card);\n}\n\n/* \u2500\u2500\u2500 Version Labels Section \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.rc-labels-section {\n background: var(--mj-bg-surface-card);\n border-radius: 8px;\n padding: 12px 16px;\n margin-bottom: 20px;\n border: 1px solid var(--mj-border-default);\n}\n\n.rc-labels-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: 8px;\n}\n\n.rc-labels-title {\n display: flex;\n align-items: center;\n gap: 8px;\n font-weight: 600;\n font-size: 13px;\n color: var(--mj-text-secondary);\n}\n\n.rc-labels-title i { color: var(--mj-brand-primary); }\n\n.rc-labels-count {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n min-width: 20px;\n height: 20px;\n padding: 0 6px;\n border-radius: 10px;\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n font-size: 10px;\n font-weight: 700;\n}\n\n.rc-create-label-btn {\n display: inline-flex;\n align-items: center;\n gap: 5px;\n padding: 5px 12px;\n border: 1px solid var(--mj-brand-primary);\n border-radius: 6px;\n background: var(--mj-bg-surface);\n color: var(--mj-brand-primary);\n font-size: 12px;\n font-weight: 600;\n cursor: pointer;\n transition: all 0.15s ease;\n}\n\n.rc-create-label-btn:hover {\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n}\n\n.rc-labels-loading {\n font-size: 12px;\n color: var(--mj-text-muted);\n padding: 4px 0;\n}\n\n.rc-labels-loading i { margin-right: 4px; }\n\n.rc-labels-empty {\n font-size: 12px;\n color: var(--mj-text-disabled);\n font-style: italic;\n padding: 4px 0;\n}\n\n.rc-labels-list {\n display: flex;\n flex-wrap: wrap;\n gap: 8px;\n}\n\n.rc-label-chip {\n display: inline-flex;\n align-items: center;\n gap: 5px;\n padding: 4px 10px;\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: 16px;\n font-size: 12px;\n color: var(--mj-text-secondary);\n transition: all 0.15s ease;\n cursor: default;\n}\n\n.rc-label-chip:hover {\n border-color: var(--mj-brand-primary);\n box-shadow: var(--mj-shadow-sm);\n}\n\n.rc-label-chip-icon { color: var(--mj-brand-primary); font-size: 10px; }\n\n.rc-label-chip-name {\n font-weight: 600;\n max-width: 180px;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.rc-label-chip-meta {\n display: flex;\n align-items: center;\n gap: 4px;\n font-size: 10px;\n color: var(--mj-text-muted);\n}\n\n.rc-label-chip-status {\n padding: 1px 5px;\n border-radius: 4px;\n font-weight: 600;\n text-transform: uppercase;\n font-size: 9px;\n letter-spacing: 0.03em;\n}\n\n.label-status-active { background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface)); color: var(--mj-status-success); }\n.label-status-archived { background: var(--mj-bg-surface-sunken); color: var(--mj-text-secondary); }\n.label-status-restored { background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface)); color: var(--mj-brand-primary); }\n\n.rc-label-chip-items { white-space: nowrap; }\n\n/* \u2500\u2500\u2500 Empty State \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.rc-empty-state {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 64px 32px;\n text-align: center;\n min-height: 400px;\n}\n\n.rc-empty-state-icon {\n width: 80px;\n height: 80px;\n border-radius: 50%;\n background: var(--mj-bg-surface-sunken);\n display: flex;\n align-items: center;\n justify-content: center;\n margin-bottom: 24px;\n}\n\n.rc-empty-state-icon i { font-size: 32px; color: var(--mj-text-disabled); }\n\n.rc-empty-state-title {\n font-size: 20px;\n font-weight: 600;\n color: var(--mj-text-secondary);\n margin: 0 0 12px 0;\n}\n\n.rc-empty-state-description {\n font-size: 14px;\n color: var(--mj-text-muted);\n line-height: 1.6;\n max-width: 320px;\n margin: 0 0 24px 0;\n}\n\n.rc-empty-state-hint {\n display: inline-flex;\n align-items: center;\n gap: 8px;\n padding: 8px 16px;\n background: var(--mj-bg-surface-sunken);\n border-radius: 20px;\n font-size: 12px;\n color: var(--mj-text-muted);\n}\n\n.rc-empty-state-hint i { color: var(--mj-text-disabled); }\n\n/* \u2500\u2500\u2500 Page Header \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.rc-page-header {\n display: flex;\n justify-content: space-between;\n align-items: flex-start;\n margin-bottom: 24px;\n padding-bottom: 20px;\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.rc-page-title {\n font-size: 20px;\n font-weight: 700;\n color: var(--mj-text-primary);\n margin: 0;\n}\n\n.rc-page-subtitle {\n font-size: 13px;\n color: var(--mj-text-muted);\n margin-top: 4px;\n}\n\n.rc-header-meta { text-align: right; }\n\n.rc-entity-badge {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 5px 12px;\n border-radius: 6px;\n font-size: 12px;\n font-weight: 500;\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n border: 1px solid color-mix(in srgb, var(--mj-brand-primary) 25%, var(--mj-bg-surface));\n}\n\n.rc-change-count {\n font-size: 12px;\n color: var(--mj-text-disabled);\n margin-top: 6px;\n}\n\n/* \u2500\u2500\u2500 Filter Bar \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.rc-filter-bar {\n display: flex;\n gap: 8px;\n margin-bottom: 20px;\n flex-wrap: wrap;\n align-items: center;\n}\n\n.rc-search-wrap {\n position: relative;\n flex: 1;\n min-width: 180px;\n}\n\n.rc-search-wrap i {\n position: absolute;\n left: 12px;\n top: 50%;\n transform: translateY(-50%);\n color: var(--mj-text-disabled);\n font-size: 13px;\n pointer-events: none;\n}\n\n.rc-search-box {\n width: 100%;\n padding: 8px 12px 8px 36px;\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n font-size: 13px;\n background: var(--mj-bg-surface);\n outline: none;\n color: var(--mj-text-primary);\n transition: border-color 0.15s, box-shadow 0.15s;\n}\n\n.rc-search-box:focus {\n border-color: var(--mj-brand-primary);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n}\n\n.rc-search-box::placeholder { color: var(--mj-text-disabled); }\n\n.rc-filter-pill {\n padding: 7px 14px;\n border-radius: 8px;\n font-size: 12px;\n font-weight: 500;\n border: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface);\n cursor: pointer;\n color: var(--mj-text-secondary);\n transition: all 0.15s;\n display: flex;\n align-items: center;\n gap: 5px;\n}\n\n.rc-filter-pill:hover {\n border-color: var(--mj-brand-primary);\n color: var(--mj-brand-primary);\n}\n\n.rc-filter-pill.active {\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n border-color: var(--mj-brand-primary);\n}\n\n.rc-filter-results {\n font-size: 12px;\n color: var(--mj-text-muted);\n margin-bottom: 16px;\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.rc-clear-filters-link {\n background: none;\n border: none;\n color: var(--mj-brand-primary);\n font-size: 12px;\n font-weight: 500;\n cursor: pointer;\n padding: 0;\n text-decoration: underline;\n}\n\n.rc-clear-filters-link:hover { color: var(--mj-brand-primary-hover); }\n\n/* \u2500\u2500\u2500 No Results \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.rc-no-results {\n text-align: center;\n padding: 48px 16px;\n color: var(--mj-text-muted);\n}\n\n.rc-no-results i {\n display: block;\n font-size: 32px;\n margin-bottom: 16px;\n color: var(--mj-text-disabled);\n}\n\n.rc-no-results p { font-size: 14px; margin: 0 0 16px 0; }\n\n.rc-clear-filters-btn {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 6px 16px;\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n background: var(--mj-bg-surface);\n color: var(--mj-text-secondary);\n font-size: 13px;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.15s ease;\n}\n\n.rc-clear-filters-btn:hover {\n border-color: var(--mj-brand-primary);\n color: var(--mj-brand-primary);\n}\n\n/* \u2500\u2500\u2500 Timeline \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.rc-timeline {\n position: relative;\n flex: 1;\n overflow-y: auto;\n}\n\n/* Vertical line running through the timeline */\n.rc-timeline::before {\n content: '';\n position: absolute;\n left: 15px;\n top: 24px;\n bottom: 0;\n width: 2px;\n background: var(--mj-border-default);\n}\n\n/* \u2500\u2500\u2500 Date Group \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.rc-date-group { margin-bottom: 8px; }\n\n.rc-date-label {\n position: relative;\n font-size: 11px;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.8px;\n color: var(--mj-text-disabled);\n padding: 16px 0 12px 44px;\n}\n\n/* Date dot on the timeline line */\n.rc-date-label::before {\n content: '';\n position: absolute;\n left: 10px;\n top: 50%;\n transform: translateY(-50%);\n width: 12px;\n height: 12px;\n border-radius: 50%;\n background: var(--mj-border-default);\n border: 2px solid var(--mj-bg-surface-card);\n}\n\n/* \u2500\u2500\u2500 Change Card \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.rc-card {\n position: relative;\n margin-left: 44px;\n margin-bottom: 12px;\n background: var(--mj-bg-surface);\n border-radius: 12px;\n border: 1px solid var(--mj-border-default);\n transition: all 0.2s;\n overflow: hidden;\n}\n\n.rc-card:hover {\n border-color: var(--mj-border-strong);\n box-shadow: var(--mj-shadow-sm);\n}\n\n.rc-card:focus {\n outline: 2px solid var(--mj-brand-primary);\n outline-offset: 2px;\n}\n\n/* Colored dot on the timeline line for each card */\n.rc-card::before {\n content: '';\n position: absolute;\n left: -23px;\n top: 20px;\n width: 8px;\n height: 8px;\n border-radius: 50%;\n z-index: 1;\n}\n\n.rc-card.type-update::before {\n background: var(--mj-brand-primary);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n}\n\n.rc-card.type-create::before {\n background: var(--mj-status-success);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-status-success) 15%, transparent);\n}\n\n.rc-card.type-delete::before {\n background: var(--mj-status-error);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-status-error) 15%, transparent);\n}\n\n/* \u2500\u2500\u2500 Card Header \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.rc-card-header {\n padding: 14px 18px;\n display: flex;\n justify-content: space-between;\n align-items: center;\n cursor: pointer;\n user-select: none;\n gap: 12px;\n}\n\n.rc-card-header-left {\n display: flex;\n align-items: center;\n gap: 10px;\n min-width: 0;\n flex: 1;\n /* Allow the lineage chip to wrap to a second line on narrow panel widths\n instead of squeezing the title text into a \"Name and Description c...\"\n truncation. The badge stays on the first line; chip wraps gracefully. */\n flex-wrap: wrap;\n row-gap: 6px;\n}\n\n.rc-card-type-badge {\n padding: 3px 10px;\n border-radius: 5px;\n font-size: 10px;\n font-weight: 600;\n letter-spacing: 0.3px;\n text-transform: uppercase;\n white-space: nowrap;\n flex-shrink: 0;\n}\n\n.type-update .rc-card-type-badge { background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface)); color: var(--mj-brand-primary); }\n.type-create .rc-card-type-badge { background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface)); color: var(--mj-status-success); }\n.type-delete .rc-card-type-badge { background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface)); color: var(--mj-status-error); }\n\n.rc-card-summary {\n font-size: 13px;\n color: var(--mj-text-secondary);\n font-weight: 500;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.rc-card-meta {\n display: flex;\n align-items: center;\n gap: 12px;\n font-size: 12px;\n color: var(--mj-text-disabled);\n flex-shrink: 0;\n}\n\n.rc-card-user {\n display: flex;\n align-items: center;\n gap: 5px;\n white-space: nowrap;\n}\n\n.rc-avatar {\n width: 20px;\n height: 20px;\n border-radius: 50%;\n background: var(--mj-brand-primary);\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 8px;\n font-weight: 700;\n color: var(--mj-text-inverse);\n flex-shrink: 0;\n}\n\n.rc-card-time { white-space: nowrap; }\n\n.rc-card-source {\n font-size: 10px;\n padding: 2px 6px;\n border-radius: 4px;\n font-weight: 500;\n white-space: nowrap;\n}\n\n.source-internal { background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface)); color: var(--mj-brand-primary); }\n.source-external { background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface)); color: var(--mj-status-warning); }\n\n.rc-card-status {\n font-size: 10px;\n padding: 2px 6px;\n border-radius: 4px;\n font-weight: 600;\n text-transform: uppercase;\n white-space: nowrap;\n}\n\n.status-complete { background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface)); color: var(--mj-status-success); }\n.status-pending { background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface)); color: var(--mj-status-warning); }\n.status-error { background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface)); color: var(--mj-status-error); }\n.status-unknown { background: var(--mj-bg-surface-sunken); color: var(--mj-text-muted); }\n\n.rc-card-chevron {\n color: var(--mj-text-disabled);\n transition: transform 0.2s;\n font-size: 12px;\n flex-shrink: 0;\n}\n\n.rc-card.expanded .rc-card-chevron { transform: rotate(180deg); }\n\n/* \u2500\u2500\u2500 Card Body \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.rc-card-body {\n border-top: 1px solid var(--mj-border-default);\n}\n\n/* \u2500\u2500\u2500 Field Row \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.rc-field-row {\n display: flex;\n align-items: stretch;\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.rc-field-row:last-child { border-bottom: none; }\n\n.rc-field-label {\n width: 140px;\n min-width: 140px;\n padding: 12px 16px;\n font-size: 12px;\n font-weight: 600;\n color: var(--mj-text-muted);\n background: var(--mj-bg-surface-card);\n display: flex;\n align-items: center;\n border-right: 1px solid var(--mj-border-default);\n}\n\n.rc-field-values {\n flex: 1;\n padding: 12px 16px;\n display: flex;\n align-items: center;\n min-width: 0;\n}\n\n/* \u2500\u2500\u2500 Atomic Change (numbers, dates) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.rc-atomic-change {\n display: flex;\n align-items: center;\n gap: 10px;\n flex-wrap: wrap;\n}\n\n.rc-val-old {\n font-size: 13px;\n font-family: 'SFMono-Regular', 'Consolas', 'Liberation Mono', 'Menlo', monospace;\n color: var(--mj-text-disabled);\n text-decoration: line-through;\n font-weight: 400;\n}\n\n.rc-val-arrow {\n color: var(--mj-border-strong);\n font-size: 11px;\n flex-shrink: 0;\n}\n\n.rc-val-new {\n font-size: 13px;\n font-family: 'SFMono-Regular', 'Consolas', 'Liberation Mono', 'Menlo', monospace;\n color: var(--mj-text-primary);\n font-weight: 500;\n}\n\n/* \u2500\u2500\u2500 Boolean Change \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.rc-bool-change {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.rc-bool-dot {\n width: 8px;\n height: 8px;\n border-radius: 50%;\n flex-shrink: 0;\n}\n\n.rc-bool-dot.on { background: var(--mj-status-success); }\n.rc-bool-dot.off { background: var(--mj-border-strong); }\n\n.rc-bool-label {\n font-size: 13px;\n font-weight: 500;\n}\n\n.rc-bool-label.old {\n color: var(--mj-text-disabled);\n text-decoration: line-through;\n}\n\n.rc-bool-label.new.active { color: var(--mj-status-success); }\n.rc-bool-label.new.inactive { color: var(--mj-text-disabled); }\n\n/* \u2500\u2500\u2500 Text Diff (strings only) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.rc-text-diff {\n font-size: 13px;\n font-family: 'SFMono-Regular', 'Consolas', 'Liberation Mono', 'Menlo', monospace;\n line-height: 1.6;\n word-wrap: break-word;\n white-space: pre-wrap;\n}\n\n.rc-diff-added {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n color: var(--mj-status-success);\n padding: 1px 3px;\n border-radius: 3px;\n}\n\n.rc-diff-removed {\n background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n color: var(--mj-status-error);\n padding: 1px 3px;\n border-radius: 3px;\n text-decoration: line-through;\n}\n\n.rc-diff-unchanged {\n color: var(--mj-text-secondary);\n}\n\n/* \u2500\u2500\u2500 Deletion Note \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.rc-deletion-note {\n padding: 16px 18px;\n color: var(--mj-text-muted);\n font-size: 13px;\n font-style: italic;\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.rc-deletion-note i {\n color: var(--mj-status-error);\n font-size: 14px;\n}\n\n/* \u2500\u2500\u2500 Comments & Errors \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.rc-comments {\n padding: 12px 18px;\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n font-size: 13px;\n color: var(--mj-brand-primary);\n display: flex;\n align-items: flex-start;\n gap: 8px;\n border-top: 1px solid var(--mj-border-default);\n}\n\n.rc-comments i {\n color: var(--mj-brand-primary);\n margin-top: 2px;\n flex-shrink: 0;\n}\n\n.rc-errors {\n padding: 12px 18px;\n background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n font-size: 13px;\n color: var(--mj-status-error);\n display: flex;\n align-items: flex-start;\n gap: 8px;\n border-top: 1px solid var(--mj-border-default);\n}\n\n.rc-errors i {\n color: var(--mj-status-error);\n margin-top: 2px;\n flex-shrink: 0;\n}\n\n.rc-error-log {\n background: var(--mj-bg-surface);\n padding: 8px;\n border-radius: 4px;\n font-family: 'SFMono-Regular', 'Consolas', 'Liberation Mono', 'Menlo', monospace;\n font-size: 12px;\n color: var(--mj-status-error);\n margin: 0;\n white-space: pre-wrap;\n overflow-x: auto;\n flex: 1;\n}\n\n/* \u2500\u2500\u2500 Create Wizard Overlay \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.rc-wizard-overlay {\n position: fixed;\n inset: 0;\n background: var(--mj-bg-overlay);\n z-index: 10000;\n display: flex;\n align-items: center;\n justify-content: center;\n animation: rc-fadeIn 0.15s ease;\n}\n\n.rc-wizard-container {\n background: var(--mj-bg-surface);\n border-radius: 12px;\n box-shadow: var(--mj-shadow-lg);\n width: 90%;\n max-width: 600px;\n max-height: 80vh;\n overflow-y: auto;\n padding: 24px;\n animation: rc-slideUp 0.2s ease;\n}\n\n@keyframes rc-fadeIn {\n from { opacity: 0; }\n to { opacity: 1; }\n}\n\n@keyframes rc-slideUp {\n from { opacity: 0; transform: translateY(20px); }\n to { opacity: 1; transform: translateY(0); }\n}\n\n/* \u2500\u2500\u2500 Responsive \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n@media (max-width: 768px) {\n .rc-card-header {\n flex-direction: column;\n align-items: flex-start;\n gap: 8px;\n }\n\n .rc-card-meta {\n flex-wrap: wrap;\n gap: 8px;\n }\n\n .rc-field-row {\n flex-direction: column;\n }\n\n .rc-field-label {\n width: 100%;\n min-width: unset;\n border-right: none;\n border-bottom: 1px solid var(--mj-border-default);\n padding: 8px 16px;\n }\n\n .rc-field-values {\n padding: 8px 16px;\n }\n\n .rc-atomic-change {\n flex-wrap: wrap;\n }\n\n .rc-filter-bar {\n flex-direction: column;\n align-items: stretch;\n }\n\n .rc-search-wrap { min-width: unset; }\n\n .rc-filter-pill { justify-content: center; }\n\n .rc-page-header {\n flex-direction: column;\n gap: 12px;\n }\n\n .rc-header-meta { text-align: left; }\n}\n\n@media (max-width: 480px) {\n .rc-container { padding: 12px 16px; }\n\n .rc-card { margin-left: 36px; }\n\n .rc-date-label { padding-left: 36px; }\n\n .rc-card::before { left: -19px; }\n\n .rc-timeline::before { left: 12px; }\n\n .rc-date-label::before { left: 7px; }\n}\n\n/* \u2500\u2500\u2500 Restore Action \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.rc-restore-action {\n display: flex;\n justify-content: flex-end;\n padding-top: 10px;\n margin-top: 10px;\n /* Breathing room from the card's bottom and right edges so the button\n doesn't sit flush against the border. */\n padding-right: 10px;\n padding-bottom: 10px;\n border-top: 1px solid var(--mj-border-subtle);\n}\n\n.rc-restore-btn {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 6px 14px;\n font-size: 12px;\n font-weight: 500;\n color: var(--mj-brand-primary);\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%, transparent);\n border-radius: 6px;\n cursor: pointer;\n transition: all 150ms ease;\n font-family: inherit;\n line-height: 1;\n}\n\n.rc-restore-btn:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n border-color: var(--mj-brand-primary);\n box-shadow: 0 2px 6px color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n}\n\n.rc-restore-btn:active {\n transform: translateY(1px);\n box-shadow: none;\n}\n\n.rc-restore-btn i {\n font-size: 13px;\n}\n\n/* \u2500\u2500\u2500 Restore Preview Panel \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.rc-restore-preview-backdrop {\n position: fixed;\n inset: 0;\n background: var(--mj-bg-overlay);\n z-index: 10000;\n display: flex;\n align-items: center;\n justify-content: center;\n animation: rc-fadeIn 0.15s ease;\n}\n\n.rc-restore-preview-panel {\n background: var(--mj-bg-surface);\n border-radius: 12px;\n box-shadow: var(--mj-shadow-lg);\n width: 90%;\n max-width: 700px;\n max-height: 80vh;\n overflow-y: auto;\n padding: 0;\n animation: rc-slideUp 0.2s ease;\n}\n\n.rc-restore-preview-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 16px 20px;\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.rc-restore-preview-title {\n display: flex;\n align-items: center;\n gap: 8px;\n font-size: 16px;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.rc-restore-preview-title i {\n color: var(--mj-brand-primary);\n}\n\n.rc-restore-preview-close {\n background: none;\n border: none;\n color: var(--mj-text-muted);\n cursor: pointer;\n padding: 4px 8px;\n border-radius: 4px;\n font-size: 16px;\n transition: color 0.15s, background 0.15s;\n}\n\n.rc-restore-preview-close:hover {\n color: var(--mj-text-primary);\n background: var(--mj-bg-surface-hover);\n}\n\n.rc-restore-preview-meta {\n display: flex;\n gap: 20px;\n padding: 12px 20px;\n font-size: 13px;\n color: var(--mj-text-secondary);\n background: var(--mj-bg-surface-card);\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.rc-restore-preview-empty {\n padding: 24px 20px;\n text-align: center;\n color: var(--mj-text-muted);\n font-size: 13px;\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 8px;\n}\n\n.rc-restore-preview-empty i {\n color: var(--mj-text-disabled);\n}\n\n/* Restore Preview Table */\n.rc-restore-preview-table {\n width: 100%;\n border-collapse: collapse;\n font-size: 13px;\n}\n\n.rc-restore-preview-table th {\n text-align: left;\n padding: 10px 16px;\n font-weight: 600;\n font-size: 11px;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n color: var(--mj-text-muted);\n background: var(--mj-bg-surface-sunken);\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.rc-restore-preview-table td {\n padding: 10px 16px;\n border-bottom: 1px solid var(--mj-border-default);\n vertical-align: top;\n}\n\n.rc-restore-preview-table tr:last-child td {\n border-bottom: none;\n}\n\n.rc-restore-preview-table tr.rc-diff-changed {\n background: color-mix(in srgb, var(--mj-status-warning) 5%, var(--mj-bg-surface));\n}\n\n.rc-restore-preview-table tr.rc-diff-unchanged {\n opacity: 0.6;\n}\n\n.rc-restore-field-name {\n font-weight: 600;\n color: var(--mj-text-primary);\n white-space: nowrap;\n}\n\n.rc-restore-current {\n font-family: 'SFMono-Regular', 'Consolas', 'Liberation Mono', 'Menlo', monospace;\n color: var(--mj-text-secondary);\n max-width: 200px;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.rc-restore-version {\n font-family: 'SFMono-Regular', 'Consolas', 'Liberation Mono', 'Menlo', monospace;\n color: var(--mj-text-primary);\n font-weight: 500;\n max-width: 200px;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.rc-restore-indicator {\n text-align: center;\n width: 30px;\n}\n\n.rc-diff-changed .rc-restore-indicator i {\n color: var(--mj-status-warning);\n}\n\n.rc-diff-unchanged .rc-restore-indicator i {\n color: var(--mj-status-success);\n font-size: 12px;\n}\n\n/* Restore Preview Actions */\n.rc-restore-preview-actions {\n display: flex;\n gap: 10px;\n padding: 16px 20px;\n border-top: 1px solid var(--mj-border-default);\n}\n\n.rc-restore-confirm-btn {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 8px 18px;\n font-size: 13px;\n font-weight: 600;\n color: var(--mj-text-inverse);\n background: var(--mj-brand-primary);\n border: none;\n border-radius: 8px;\n cursor: pointer;\n transition: background 0.15s, box-shadow 0.15s;\n font-family: inherit;\n}\n\n.rc-restore-confirm-btn:hover:not(:disabled) {\n background: var(--mj-brand-primary-hover);\n box-shadow: 0 2px 8px color-mix(in srgb, var(--mj-brand-primary) 25%, transparent);\n}\n\n.rc-restore-confirm-btn:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.rc-restore-cancel-btn {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 8px 18px;\n font-size: 13px;\n font-weight: 500;\n color: var(--mj-text-secondary);\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n cursor: pointer;\n transition: all 0.15s;\n font-family: inherit;\n}\n\n.rc-restore-cancel-btn:hover:not(:disabled) {\n border-color: var(--mj-border-strong);\n color: var(--mj-text-primary);\n}\n\n.rc-restore-cancel-btn:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n/* \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n * Restore lineage + conditional filter chips + overflow popover\n * (added with the Restore Prior Version feature)\n * \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n/* \u2500\u2500\u2500 Filter pill enhancements \u2500\u2500\u2500 */\n\n.rc-filter-pill-count {\n margin-left: 4px;\n background: color-mix(in srgb, currentColor 12%, transparent);\n padding: 1px 6px;\n border-radius: 10px;\n font-size: 10px;\n font-weight: 700;\n}\n\n.rc-filter-pill.active .rc-filter-pill-count {\n background: color-mix(in srgb, var(--mj-text-inverse, #fff) 22%, transparent);\n}\n\n/* Restore-variant pill: violet treatment to set it apart from type pills */\n.rc-filter-pill-restore {\n background: color-mix(in srgb, var(--mj-status-info) 8%, var(--mj-bg-surface));\n color: color-mix(in srgb, var(--mj-status-info) 80%, var(--mj-text-secondary));\n border-color: color-mix(in srgb, var(--mj-status-info) 30%, var(--mj-border-default));\n}\n.rc-filter-pill-restore:hover {\n border-color: var(--mj-status-info);\n color: var(--mj-status-info);\n}\n.rc-filter-pill-restore.active {\n background: var(--mj-status-info);\n color: var(--mj-text-inverse, #fff);\n border-color: var(--mj-status-info);\n}\n\n/* \u2500\u2500\u2500 Overflow filter popover \u2500\u2500\u2500 */\n\n.rc-filter-overflow-wrap {\n position: relative;\n display: inline-block;\n}\n\n.rc-filter-pill-overflow {\n /* Overflow trigger inherits the standard filter pill look */\n}\n\n.rc-filter-overflow-caret {\n font-size: 9px;\n margin-left: 2px;\n}\n\n.rc-filter-overflow-backdrop {\n position: fixed;\n inset: 0;\n z-index: 10;\n}\n\n.rc-filter-overflow-popover {\n position: absolute;\n top: calc(100% + 6px);\n left: 0;\n z-index: 11;\n min-width: 240px;\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: 10px;\n box-shadow: 0 14px 40px rgba(15, 23, 42, 0.18);\n padding: 8px;\n}\n\n.rc-filter-overflow-header {\n font-size: 11px;\n text-transform: uppercase;\n letter-spacing: 0.06em;\n color: var(--mj-text-muted);\n font-weight: 600;\n padding: 6px 8px 8px;\n}\n\n.rc-filter-overflow-row {\n display: flex;\n align-items: center;\n gap: 9px;\n padding: 7px 8px;\n border-radius: 6px;\n font-size: 13px;\n color: var(--mj-text-primary);\n cursor: pointer;\n}\n\n.rc-filter-overflow-row:hover {\n background: var(--mj-bg-surface-hover);\n}\n\n.rc-filter-overflow-row input[type=\"checkbox\"] {\n margin: 0;\n accent-color: var(--mj-brand-primary);\n}\n\n.rc-filter-overflow-row i {\n color: var(--mj-text-muted);\n font-size: 12px;\n width: 14px;\n text-align: center;\n}\n\n.rc-filter-overflow-row-restore i {\n color: var(--mj-status-info);\n}\n\n.rc-filter-overflow-label {\n flex: 1;\n}\n\n.rc-filter-overflow-count {\n color: var(--mj-text-muted);\n font-size: 11px;\n font-weight: 500;\n}\n\n.rc-filter-overflow-actions {\n display: flex;\n justify-content: space-between;\n border-top: 1px solid var(--mj-border-subtle);\n padding-top: 8px;\n margin-top: 6px;\n}\n\n.rc-filter-overflow-clear,\n.rc-filter-overflow-done {\n background: none;\n border: none;\n font-size: 12px;\n font-weight: 500;\n cursor: pointer;\n padding: 4px 10px;\n border-radius: 5px;\n}\n\n.rc-filter-overflow-clear {\n color: var(--mj-text-muted);\n}\n.rc-filter-overflow-clear:hover {\n background: var(--mj-bg-surface-hover);\n color: var(--mj-text-primary);\n}\n\n.rc-filter-overflow-done {\n color: var(--mj-brand-primary);\n}\n.rc-filter-overflow-done:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 8%, transparent);\n}\n\n/* \u2500\u2500\u2500 Snapshot type badge + card accent \u2500\u2500\u2500 */\n\n.type-snapshot .rc-card-type-badge {\n background: color-mix(in srgb, var(--mj-text-muted) 15%, var(--mj-bg-surface));\n color: var(--mj-text-secondary);\n}\n\n/* \u2500\u2500\u2500 Restore Source pill (in card meta) \u2500\u2500\u2500 */\n\n.source-restore {\n background: color-mix(in srgb, var(--mj-status-info) 12%, var(--mj-bg-surface));\n color: var(--mj-status-info);\n}\n\n/* \u2500\u2500\u2500 Restore card variant: violet left accent \u2500\u2500\u2500 */\n\n.rc-card.rc-card-restore {\n border-left: 3px solid var(--mj-status-info);\n}\n\n/* \u2500\u2500\u2500 Lineage chip \u2500\u2500\u2500 */\n\n/* Lineage chip \u2014 outline-only \"interactive link\" treatment so it reads as\n distinct from the filled RESTORE badge sitting next to it. The badge says\n \"this row IS a restore\" (filled, static); the chip says \"click here to\n see the source version\" (outline, hoverable). */\n.rc-restored-chip {\n display: inline-flex;\n align-items: center;\n gap: 5px;\n margin-left: 8px;\n padding: 2px 9px;\n border-radius: 11px;\n font-size: 11px;\n font-weight: 500;\n background: transparent;\n color: color-mix(in srgb, var(--mj-status-info) 90%, var(--mj-text-primary));\n border: 1px solid color-mix(in srgb, var(--mj-status-info) 40%, var(--mj-border-default));\n cursor: pointer;\n text-decoration: none;\n white-space: nowrap;\n transition: background-color 0.12s, border-color 0.12s, color 0.12s;\n}\n\n.rc-restored-chip:hover {\n background: color-mix(in srgb, var(--mj-status-info) 12%, transparent);\n border-color: var(--mj-status-info);\n color: var(--mj-status-info);\n}\n\n.rc-restored-chip i {\n font-size: 10px;\n}\n\n.rc-restored-chip-orphan {\n cursor: default;\n background: var(--mj-bg-surface-card);\n color: var(--mj-text-muted);\n border-color: var(--mj-border-default);\n}\n\n.rc-restored-chip-orphan:hover {\n background: var(--mj-bg-surface-card);\n border-color: var(--mj-border-default);\n}\n\n/* \u2500\u2500\u2500 Card highlight (when jumped-to via lineage chip) \u2500\u2500\u2500 */\n\n.rc-card.rc-card-highlight {\n outline: 2px solid var(--mj-brand-primary);\n outline-offset: 2px;\n animation: rc-card-pulse 1.4s ease-in-out;\n}\n\n@keyframes rc-card-pulse {\n 0%, 100% { background: var(--mj-bg-surface); }\n 50% { background: color-mix(in srgb, var(--mj-brand-primary) 8%, var(--mj-bg-surface)); }\n}\n\n/* \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n * Restore-row badge override + Restore Reason block\n * (mockup-aligned treatment for restore rows in the timeline)\n * \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n/* The base type-update badge styling would otherwise paint a restore row's\n badge blue with \"Update\" text. Override to violet + \"Restore\" text so it\n matches the source pill, lineage chip, and card border. */\n.rc-card-type-badge.rc-card-type-badge-restore {\n background: color-mix(in srgb, var(--mj-status-info) 14%, var(--mj-bg-surface));\n color: var(--mj-status-info);\n}\n\n/* Restore reason \u2014 minimal blockquote treatment.\n A thin violet left bar + italic text reads like a margin note rather than\n a heavy callout. Visually connected to the restore family (left bar uses\n the same violet as the badge / source pill / card border) without\n competing with the field-diff rows that follow. */\n.rc-restore-reason {\n /* Indented in from the card body edge so it visually nests one level\n deeper than the field-diff rows that follow, and given generous\n vertical breathing room so it doesn't crowd the lineage chip above\n or the first field row below. */\n margin: 14px 8px 18px 18px;\n padding: 0 0 0 12px;\n border-left: 2px solid color-mix(in srgb, var(--mj-status-info) 55%, var(--mj-border-default));\n display: flex;\n align-items: baseline;\n gap: 8px;\n font-size: 13px;\n line-height: 1.5;\n}\n\n.rc-restore-reason-label {\n flex-shrink: 0;\n font-size: 11px;\n font-weight: 600;\n color: color-mix(in srgb, var(--mj-status-info) 75%, var(--mj-text-muted));\n text-transform: uppercase;\n letter-spacing: 0.04em;\n}\n\n.rc-restore-reason-text {\n color: var(--mj-text-secondary);\n font-style: italic;\n}\n"], encapsulation: 2, changeDetection: 0 });
1200
1429
  }
1201
1430
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(RecordChangesComponent, [{
1202
1431
  type: Component,
1203
- args: [{ standalone: false, selector: 'mj-record-changes', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: "<mj-slide-panel\n [Mode]=\"'slide'\"\n [Title]=\"'Record Changes History'\"\n [Visible]=\"IsVisible\"\n [Resizable]=\"true\"\n [MinWidthPx]=\"400\"\n [MaxWidthRatio]=\"0.6\"\n (Closed)=\"OnClose()\">\n\n @if (IsLoading) {\n <mj-loading text=\"Loading history...\" size=\"medium\"></mj-loading>\n }\n\n @if (!IsLoading) {\n <div class=\"rc-container\">\n <!-- Version Labels Section -->\n <div class=\"rc-labels-section\">\n <div class=\"rc-labels-header\">\n <div class=\"rc-labels-title\">\n <i class=\"fa-solid fa-tags\" aria-hidden=\"true\"></i>\n <span>Version Labels</span>\n @if (RecordLabels.length > 0) {\n <span class=\"rc-labels-count\">{{ RecordLabels.length }}</span>\n }\n </div>\n <button class=\"rc-create-label-btn\" (click)=\"OpenCreateWizard()\" title=\"Create a version label for this record\">\n <i class=\"fa-solid fa-plus\"></i> Create Label\n </button>\n </div>\n @if (IsLoadingLabels) {\n <div class=\"rc-labels-loading\">\n <i class=\"fa-solid fa-spinner fa-spin\"></i> Loading labels...\n </div>\n } @else if (RecordLabels.length === 0) {\n <div class=\"rc-labels-empty\">\n No version labels for this record yet.\n </div>\n } @else {\n <div class=\"rc-labels-list\">\n @for (label of RecordLabels; track label.ID) {\n <div class=\"rc-label-chip\" [title]=\"label.Description || label.Name\">\n <i class=\"fa-solid fa-tag rc-label-chip-icon\"></i>\n <span class=\"rc-label-chip-name\">{{ label.Name }}</span>\n <span class=\"rc-label-chip-meta\">\n <span class=\"rc-label-chip-status\" [class]=\"getLabelStatusClass(label.Status)\">{{ label.Status }}</span>\n <span class=\"rc-label-chip-items\">{{ label.ItemCount }} item{{ label.ItemCount !== 1 ? 's' : '' }}</span>\n </span>\n </div>\n }\n </div>\n }\n </div>\n\n @if (viewData.length === 0) {\n <!-- Empty state -->\n <div class=\"rc-empty-state\">\n <div class=\"rc-empty-state-icon\">\n <i class=\"fa-solid fa-clock-rotate-left\"></i>\n </div>\n <h3 class=\"rc-empty-state-title\">No Change History</h3>\n <p class=\"rc-empty-state-description\">\n This record doesn't have any tracked changes yet.\n Changes will appear here automatically as edits are made.\n </p>\n <div class=\"rc-empty-state-hint\">\n <i class=\"fa-solid fa-shield-halved\"></i>\n <span>Record change tracking is managed at the entity level</span>\n </div>\n </div>\n } @else {\n <!-- Page Header -->\n <div class=\"rc-page-header\">\n <div>\n <h2 class=\"rc-page-title\">Change History</h2>\n <div class=\"rc-page-subtitle\">{{ record.EntityInfo.Name }}</div>\n </div>\n <div class=\"rc-header-meta\">\n <div class=\"rc-entity-badge\">\n <i class=\"fa-solid fa-database\" aria-hidden=\"true\"></i>\n {{ record.EntityInfo.Name }}\n </div>\n <div class=\"rc-change-count\">{{ viewData.length }} change{{ viewData.length !== 1 ? 's' : '' }} &middot; {{ getUniqueContributorCount() }} contributor{{ getUniqueContributorCount() !== 1 ? 's' : '' }}</div>\n </div>\n </div>\n\n <!-- Filter Bar -->\n <div class=\"rc-filter-bar\">\n <div class=\"rc-search-wrap\">\n <i class=\"fa-solid fa-search\" aria-hidden=\"true\"></i>\n <input\n class=\"rc-search-box\"\n type=\"text\"\n placeholder=\"Search changes...\"\n [(ngModel)]=\"searchTerm\"\n (input)=\"onSearchChange()\"\n aria-label=\"Search record changes\"\n />\n </div>\n <button class=\"rc-filter-pill\" [class.active]=\"!selectedType\" (click)=\"SetTypeFilter('')\">\n <i class=\"fa-solid fa-layer-group\" aria-hidden=\"true\"></i> All\n </button>\n <button class=\"rc-filter-pill\" [class.active]=\"selectedType === 'Update'\" (click)=\"SetTypeFilter('Update')\">\n <i class=\"fa-solid fa-pen\" aria-hidden=\"true\"></i> Updates\n </button>\n <button class=\"rc-filter-pill\" [class.active]=\"selectedType === 'Create'\" (click)=\"SetTypeFilter('Create')\">\n <i class=\"fa-solid fa-plus\" aria-hidden=\"true\"></i> Creates\n </button>\n <button class=\"rc-filter-pill\" [class.active]=\"selectedType === 'Delete'\" (click)=\"SetTypeFilter('Delete')\">\n <i class=\"fa-solid fa-trash\" aria-hidden=\"true\"></i> Deletes\n </button>\n </div>\n\n @if (filteredData.length !== viewData.length) {\n <div class=\"rc-filter-results\">\n Showing {{ filteredData.length }} of {{ viewData.length }} changes\n <button class=\"rc-clear-filters-link\" (click)=\"ClearFilters()\">Clear filters</button>\n </div>\n }\n\n <!-- Timeline -->\n <div class=\"rc-timeline\" [attr.aria-label]=\"'Timeline of changes for ' + record.EntityInfo.Name + ' record'\">\n @if (filteredData.length === 0) {\n <div class=\"rc-no-results\">\n <i class=\"fa-solid fa-filter\" aria-hidden=\"true\"></i>\n <p>No changes match your current filters.</p>\n <button class=\"rc-clear-filters-btn\" (click)=\"ClearFilters()\">\n <i class=\"fa-solid fa-xmark\"></i> Clear Filters\n </button>\n </div>\n } @else {\n @for (group of dateGroups; track group.label) {\n <div class=\"rc-date-group\">\n <div class=\"rc-date-label\">{{ group.label }}</div>\n\n @for (change of group.changes; track change.ID) {\n <div\n class=\"rc-card\"\n [class]=\"getChangeTypeCardClass(change.Type)\"\n [class.expanded]=\"expandedItems.has(change.ID)\"\n [attr.tabindex]=\"0\"\n [attr.aria-expanded]=\"expandedItems.has(change.ID)\"\n [attr.aria-label]=\"getTimelineItemLabel(change)\"\n (keydown)=\"onTimelineItemKeydown($event, change.ID)\"\n >\n <!-- Card Header -->\n <div class=\"rc-card-header\" (click)=\"toggleExpansion(change.ID)\">\n <div class=\"rc-card-header-left\">\n <span class=\"rc-card-type-badge\">{{ getChangeTypeBadgeText(change.Type) }}</span>\n <span class=\"rc-card-summary\">{{ getChangeSummary(change) }}</span>\n </div>\n <div class=\"rc-card-meta\">\n <div class=\"rc-card-user\">\n <div class=\"rc-avatar\">{{ getUserInitials(change.User) }}</div>\n {{ getUserDisplayName(change.User) }}\n </div>\n <span class=\"rc-card-time\" [title]=\"formatFullDateTime(change.ChangedAt)\">{{ formatTime(change.ChangedAt) }}</span>\n <span class=\"rc-card-source\" [class]=\"getSourceClass(change.Source)\">{{ change.Source }}</span>\n <span class=\"rc-card-status\" [class]=\"getStatusClass(change.Status)\">{{ change.Status }}</span>\n <i class=\"fa-solid fa-chevron-down rc-card-chevron\" aria-hidden=\"true\"></i>\n </div>\n </div>\n\n <!-- Card Body (expanded) -->\n @if (expandedItems.has(change.ID)) {\n <div class=\"rc-card-body\">\n @if (change.Type === 'Create') {\n <!-- Created record fields -->\n @if (change.FullRecordJSON) {\n @for (field of getCreatedFields(change); track field.name) {\n <div class=\"rc-field-row\">\n <div class=\"rc-field-label\">{{ field.displayName }}</div>\n <div class=\"rc-field-values\">\n <span class=\"rc-val-new\">{{ field.value }}</span>\n </div>\n </div>\n }\n }\n } @else if (change.Type === 'Delete') {\n <div class=\"rc-deletion-note\">\n <i class=\"fa-solid fa-trash\" aria-hidden=\"true\"></i>\n This record was permanently removed from the system.\n </div>\n } @else {\n <!-- Update: type-aware field changes -->\n @for (fc of getFieldChanges(change); track fc.field) {\n <div class=\"rc-field-row\">\n <div class=\"rc-field-label\">{{ fc.displayName }}</div>\n <div class=\"rc-field-values\">\n @if (fc.fieldType === 'boolean') {\n <!-- Boolean: dot indicators -->\n <div class=\"rc-bool-change\">\n <span class=\"rc-bool-dot\" [class.on]=\"fc.oldValue === 'true' || fc.oldValue === '1'\" [class.off]=\"fc.oldValue !== 'true' && fc.oldValue !== '1'\"></span>\n <span class=\"rc-bool-label old\">{{ fc.oldValue === 'true' || fc.oldValue === '1' ? 'Yes' : 'No' }}</span>\n <i class=\"fa-solid fa-arrow-right rc-val-arrow\" aria-hidden=\"true\"></i>\n <span class=\"rc-bool-dot\" [class.on]=\"fc.newValue === 'true' || fc.newValue === '1'\" [class.off]=\"fc.newValue !== 'true' && fc.newValue !== '1'\"></span>\n <span class=\"rc-bool-label new\" [class.active]=\"fc.newValue === 'true' || fc.newValue === '1'\" [class.inactive]=\"fc.newValue !== 'true' && fc.newValue !== '1'\">{{ fc.newValue === 'true' || fc.newValue === '1' ? 'Yes' : 'No' }}</span>\n </div>\n } @else if (fc.fieldType === 'date' || fc.fieldType === 'number') {\n <!-- Atomic: old \u2192 new -->\n <div class=\"rc-atomic-change\">\n <span class=\"rc-val-old\">{{ fc.oldValue || '(empty)' }}</span>\n <i class=\"fa-solid fa-arrow-right rc-val-arrow\" aria-hidden=\"true\"></i>\n <span class=\"rc-val-new\">{{ fc.newValue || '(empty)' }}</span>\n </div>\n } @else if (fc.diffHtml) {\n <!-- Text: word/char diff -->\n <div class=\"rc-text-diff\" [innerHTML]=\"fc.diffHtml\"></div>\n } @else {\n <!-- Fallback: old \u2192 new -->\n <div class=\"rc-atomic-change\">\n <span class=\"rc-val-old\">{{ fc.oldValue || '(empty)' }}</span>\n <i class=\"fa-solid fa-arrow-right rc-val-arrow\" aria-hidden=\"true\"></i>\n <span class=\"rc-val-new\">{{ fc.newValue || '(empty)' }}</span>\n </div>\n }\n </div>\n </div>\n }\n }\n\n @if (change.Comments) {\n <div class=\"rc-comments\">\n <i class=\"fa-solid fa-comment\" aria-hidden=\"true\"></i>\n {{ change.Comments }}\n </div>\n }\n\n @if (change.ErrorLog) {\n <div class=\"rc-errors\">\n <i class=\"fa-solid fa-exclamation-triangle\" aria-hidden=\"true\"></i>\n <pre class=\"rc-error-log\">{{ change.ErrorLog }}</pre>\n </div>\n }\n\n @if (AllowRestore && change.Type === 'Update') {\n <div class=\"rc-restore-action\">\n <button class=\"rc-restore-btn\"\n (click)=\"OnRestoreVersion(change, $event)\"\n title=\"Restore field values from before this change\">\n <i class=\"fa-solid fa-clock-rotate-left\" aria-hidden=\"true\"></i>\n Restore Previous Values\n </button>\n </div>\n }\n </div>\n }\n </div>\n }\n </div>\n }\n }\n </div>\n }\n </div>\n }\n\n <!-- \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n RESTORE PREVIEW PANEL (inline diff before applying)\n \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 -->\n @if (RestorePreview) {\n <div class=\"rc-restore-preview-backdrop\" (click)=\"CancelRestorePreview()\">\n <div class=\"rc-restore-preview-panel\" (click)=\"$event.stopPropagation()\">\n <div class=\"rc-restore-preview-header\">\n <div class=\"rc-restore-preview-title\">\n <i class=\"fa-solid fa-clock-rotate-left\" aria-hidden=\"true\"></i>\n Restore Preview\n </div>\n <button class=\"rc-restore-preview-close\" (click)=\"CancelRestorePreview()\" title=\"Close preview\">\n <i class=\"fa-solid fa-times\"></i>\n </button>\n </div>\n\n <div class=\"rc-restore-preview-meta\">\n <span><strong>Version:</strong> {{ formatFullDateTime(RestorePreview.ChangedAt) }}</span>\n <span><strong>By:</strong> {{ getUserDisplayName(RestorePreview.User) }}</span>\n </div>\n\n @if (RestorePreviewFields.length === 0) {\n <div class=\"rc-restore-preview-empty\">\n <i class=\"fa-solid fa-circle-info\" aria-hidden=\"true\"></i>\n No field changes could be parsed from this version.\n </div>\n } @else {\n <table class=\"rc-restore-preview-table\">\n <thead>\n <tr>\n <th>Field</th>\n <th>Current Value</th>\n <th>Restore To</th>\n <th></th>\n </tr>\n </thead>\n <tbody>\n @for (diff of RestorePreviewFields; track diff.FieldName) {\n <tr [class.rc-diff-changed]=\"diff.IsChanged\" [class.rc-diff-unchanged]=\"!diff.IsChanged\">\n <td class=\"rc-restore-field-name\">{{ diff.DisplayName }}</td>\n <td class=\"rc-restore-current\">{{ diff.CurrentValue || '(empty)' }}</td>\n <td class=\"rc-restore-version\">{{ diff.VersionValue || '(empty)' }}</td>\n <td class=\"rc-restore-indicator\">\n @if (diff.IsChanged) {\n <i class=\"fa-solid fa-circle-exclamation\" title=\"Will be changed\"></i>\n } @else {\n <i class=\"fa-solid fa-check\" title=\"Already matches\"></i>\n }\n </td>\n </tr>\n }\n </tbody>\n </table>\n }\n\n <div class=\"rc-restore-preview-actions\">\n <button class=\"rc-restore-confirm-btn\"\n [disabled]=\"IsRestoring || RestorePreviewFields.length === 0\"\n (click)=\"ConfirmRestore()\">\n @if (IsRestoring) {\n <i class=\"fa-solid fa-spinner fa-spin\" aria-hidden=\"true\"></i>\n Restoring...\n } @else {\n <i class=\"fa-solid fa-rotate-left\" aria-hidden=\"true\"></i>\n Apply Restore\n }\n </button>\n <button class=\"rc-restore-cancel-btn\" (click)=\"CancelRestorePreview()\" [disabled]=\"IsRestoring\">\n Cancel\n </button>\n </div>\n </div>\n </div>\n }\n\n @if (ShowCreateWizard) {\n <div class=\"rc-wizard-overlay\" (click)=\"OnLabelCreateCancelled()\">\n <div class=\"rc-wizard-container\" (click)=\"$event.stopPropagation()\">\n <mj-label-create\n [PreselectedEntity]=\"record.EntityInfo\"\n [PreselectedRecordIds]=\"[record.PrimaryKey.KeyValuePairs[0].Value]\"\n (Created)=\"OnLabelCreated($event)\"\n (Cancel)=\"OnLabelCreateCancelled()\">\n </mj-label-create>\n </div>\n </div>\n }\n</mj-slide-panel>\n", styles: ["/* \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n Record Changes \u2014 Option A \"Clean Timeline\"\n Linear / Notion-inspired minimal timeline design\n \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 */\n\n/* \u2500\u2500\u2500 Container \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.rc-container {\n display: flex;\n flex-direction: column;\n height: 100%;\n padding: 20px 24px;\n background: var(--mj-bg-surface-card);\n}\n\n/* \u2500\u2500\u2500 Version Labels Section \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.rc-labels-section {\n background: var(--mj-bg-surface-card);\n border-radius: 8px;\n padding: 12px 16px;\n margin-bottom: 20px;\n border: 1px solid var(--mj-border-default);\n}\n\n.rc-labels-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: 8px;\n}\n\n.rc-labels-title {\n display: flex;\n align-items: center;\n gap: 8px;\n font-weight: 600;\n font-size: 13px;\n color: var(--mj-text-secondary);\n}\n\n.rc-labels-title i { color: var(--mj-brand-primary); }\n\n.rc-labels-count {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n min-width: 20px;\n height: 20px;\n padding: 0 6px;\n border-radius: 10px;\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n font-size: 10px;\n font-weight: 700;\n}\n\n.rc-create-label-btn {\n display: inline-flex;\n align-items: center;\n gap: 5px;\n padding: 5px 12px;\n border: 1px solid var(--mj-brand-primary);\n border-radius: 6px;\n background: var(--mj-bg-surface);\n color: var(--mj-brand-primary);\n font-size: 12px;\n font-weight: 600;\n cursor: pointer;\n transition: all 0.15s ease;\n}\n\n.rc-create-label-btn:hover {\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n}\n\n.rc-labels-loading {\n font-size: 12px;\n color: var(--mj-text-muted);\n padding: 4px 0;\n}\n\n.rc-labels-loading i { margin-right: 4px; }\n\n.rc-labels-empty {\n font-size: 12px;\n color: var(--mj-text-disabled);\n font-style: italic;\n padding: 4px 0;\n}\n\n.rc-labels-list {\n display: flex;\n flex-wrap: wrap;\n gap: 8px;\n}\n\n.rc-label-chip {\n display: inline-flex;\n align-items: center;\n gap: 5px;\n padding: 4px 10px;\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: 16px;\n font-size: 12px;\n color: var(--mj-text-secondary);\n transition: all 0.15s ease;\n cursor: default;\n}\n\n.rc-label-chip:hover {\n border-color: var(--mj-brand-primary);\n box-shadow: var(--mj-shadow-sm);\n}\n\n.rc-label-chip-icon { color: var(--mj-brand-primary); font-size: 10px; }\n\n.rc-label-chip-name {\n font-weight: 600;\n max-width: 180px;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.rc-label-chip-meta {\n display: flex;\n align-items: center;\n gap: 4px;\n font-size: 10px;\n color: var(--mj-text-muted);\n}\n\n.rc-label-chip-status {\n padding: 1px 5px;\n border-radius: 4px;\n font-weight: 600;\n text-transform: uppercase;\n font-size: 9px;\n letter-spacing: 0.03em;\n}\n\n.label-status-active { background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface)); color: var(--mj-status-success); }\n.label-status-archived { background: var(--mj-bg-surface-sunken); color: var(--mj-text-secondary); }\n.label-status-restored { background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface)); color: var(--mj-brand-primary); }\n\n.rc-label-chip-items { white-space: nowrap; }\n\n/* \u2500\u2500\u2500 Empty State \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.rc-empty-state {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 64px 32px;\n text-align: center;\n min-height: 400px;\n}\n\n.rc-empty-state-icon {\n width: 80px;\n height: 80px;\n border-radius: 50%;\n background: var(--mj-bg-surface-sunken);\n display: flex;\n align-items: center;\n justify-content: center;\n margin-bottom: 24px;\n}\n\n.rc-empty-state-icon i { font-size: 32px; color: var(--mj-text-disabled); }\n\n.rc-empty-state-title {\n font-size: 20px;\n font-weight: 600;\n color: var(--mj-text-secondary);\n margin: 0 0 12px 0;\n}\n\n.rc-empty-state-description {\n font-size: 14px;\n color: var(--mj-text-muted);\n line-height: 1.6;\n max-width: 320px;\n margin: 0 0 24px 0;\n}\n\n.rc-empty-state-hint {\n display: inline-flex;\n align-items: center;\n gap: 8px;\n padding: 8px 16px;\n background: var(--mj-bg-surface-sunken);\n border-radius: 20px;\n font-size: 12px;\n color: var(--mj-text-muted);\n}\n\n.rc-empty-state-hint i { color: var(--mj-text-disabled); }\n\n/* \u2500\u2500\u2500 Page Header \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.rc-page-header {\n display: flex;\n justify-content: space-between;\n align-items: flex-start;\n margin-bottom: 24px;\n padding-bottom: 20px;\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.rc-page-title {\n font-size: 20px;\n font-weight: 700;\n color: var(--mj-text-primary);\n margin: 0;\n}\n\n.rc-page-subtitle {\n font-size: 13px;\n color: var(--mj-text-muted);\n margin-top: 4px;\n}\n\n.rc-header-meta { text-align: right; }\n\n.rc-entity-badge {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 5px 12px;\n border-radius: 6px;\n font-size: 12px;\n font-weight: 500;\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n border: 1px solid color-mix(in srgb, var(--mj-brand-primary) 25%, var(--mj-bg-surface));\n}\n\n.rc-change-count {\n font-size: 12px;\n color: var(--mj-text-disabled);\n margin-top: 6px;\n}\n\n/* \u2500\u2500\u2500 Filter Bar \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.rc-filter-bar {\n display: flex;\n gap: 8px;\n margin-bottom: 20px;\n flex-wrap: wrap;\n align-items: center;\n}\n\n.rc-search-wrap {\n position: relative;\n flex: 1;\n min-width: 180px;\n}\n\n.rc-search-wrap i {\n position: absolute;\n left: 12px;\n top: 50%;\n transform: translateY(-50%);\n color: var(--mj-text-disabled);\n font-size: 13px;\n pointer-events: none;\n}\n\n.rc-search-box {\n width: 100%;\n padding: 8px 12px 8px 36px;\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n font-size: 13px;\n background: var(--mj-bg-surface);\n outline: none;\n color: var(--mj-text-primary);\n transition: border-color 0.15s, box-shadow 0.15s;\n}\n\n.rc-search-box:focus {\n border-color: var(--mj-brand-primary);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n}\n\n.rc-search-box::placeholder { color: var(--mj-text-disabled); }\n\n.rc-filter-pill {\n padding: 7px 14px;\n border-radius: 8px;\n font-size: 12px;\n font-weight: 500;\n border: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface);\n cursor: pointer;\n color: var(--mj-text-secondary);\n transition: all 0.15s;\n display: flex;\n align-items: center;\n gap: 5px;\n}\n\n.rc-filter-pill:hover {\n border-color: var(--mj-brand-primary);\n color: var(--mj-brand-primary);\n}\n\n.rc-filter-pill.active {\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n border-color: var(--mj-brand-primary);\n}\n\n.rc-filter-results {\n font-size: 12px;\n color: var(--mj-text-muted);\n margin-bottom: 16px;\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.rc-clear-filters-link {\n background: none;\n border: none;\n color: var(--mj-brand-primary);\n font-size: 12px;\n font-weight: 500;\n cursor: pointer;\n padding: 0;\n text-decoration: underline;\n}\n\n.rc-clear-filters-link:hover { color: var(--mj-brand-primary-hover); }\n\n/* \u2500\u2500\u2500 No Results \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.rc-no-results {\n text-align: center;\n padding: 48px 16px;\n color: var(--mj-text-muted);\n}\n\n.rc-no-results i {\n display: block;\n font-size: 32px;\n margin-bottom: 16px;\n color: var(--mj-text-disabled);\n}\n\n.rc-no-results p { font-size: 14px; margin: 0 0 16px 0; }\n\n.rc-clear-filters-btn {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 6px 16px;\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n background: var(--mj-bg-surface);\n color: var(--mj-text-secondary);\n font-size: 13px;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.15s ease;\n}\n\n.rc-clear-filters-btn:hover {\n border-color: var(--mj-brand-primary);\n color: var(--mj-brand-primary);\n}\n\n/* \u2500\u2500\u2500 Timeline \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.rc-timeline {\n position: relative;\n flex: 1;\n overflow-y: auto;\n}\n\n/* Vertical line running through the timeline */\n.rc-timeline::before {\n content: '';\n position: absolute;\n left: 15px;\n top: 24px;\n bottom: 0;\n width: 2px;\n background: var(--mj-border-default);\n}\n\n/* \u2500\u2500\u2500 Date Group \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.rc-date-group { margin-bottom: 8px; }\n\n.rc-date-label {\n position: relative;\n font-size: 11px;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.8px;\n color: var(--mj-text-disabled);\n padding: 16px 0 12px 44px;\n}\n\n/* Date dot on the timeline line */\n.rc-date-label::before {\n content: '';\n position: absolute;\n left: 10px;\n top: 50%;\n transform: translateY(-50%);\n width: 12px;\n height: 12px;\n border-radius: 50%;\n background: var(--mj-border-default);\n border: 2px solid var(--mj-bg-surface-card);\n}\n\n/* \u2500\u2500\u2500 Change Card \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.rc-card {\n position: relative;\n margin-left: 44px;\n margin-bottom: 12px;\n background: var(--mj-bg-surface);\n border-radius: 12px;\n border: 1px solid var(--mj-border-default);\n transition: all 0.2s;\n overflow: hidden;\n}\n\n.rc-card:hover {\n border-color: var(--mj-border-strong);\n box-shadow: var(--mj-shadow-sm);\n}\n\n.rc-card:focus {\n outline: 2px solid var(--mj-brand-primary);\n outline-offset: 2px;\n}\n\n/* Colored dot on the timeline line for each card */\n.rc-card::before {\n content: '';\n position: absolute;\n left: -23px;\n top: 20px;\n width: 8px;\n height: 8px;\n border-radius: 50%;\n z-index: 1;\n}\n\n.rc-card.type-update::before {\n background: var(--mj-brand-primary);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n}\n\n.rc-card.type-create::before {\n background: var(--mj-status-success);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-status-success) 15%, transparent);\n}\n\n.rc-card.type-delete::before {\n background: var(--mj-status-error);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-status-error) 15%, transparent);\n}\n\n/* \u2500\u2500\u2500 Card Header \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.rc-card-header {\n padding: 14px 18px;\n display: flex;\n justify-content: space-between;\n align-items: center;\n cursor: pointer;\n user-select: none;\n gap: 12px;\n}\n\n.rc-card-header-left {\n display: flex;\n align-items: center;\n gap: 10px;\n min-width: 0;\n flex: 1;\n}\n\n.rc-card-type-badge {\n padding: 3px 10px;\n border-radius: 5px;\n font-size: 10px;\n font-weight: 600;\n letter-spacing: 0.3px;\n text-transform: uppercase;\n white-space: nowrap;\n flex-shrink: 0;\n}\n\n.type-update .rc-card-type-badge { background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface)); color: var(--mj-brand-primary); }\n.type-create .rc-card-type-badge { background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface)); color: var(--mj-status-success); }\n.type-delete .rc-card-type-badge { background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface)); color: var(--mj-status-error); }\n\n.rc-card-summary {\n font-size: 13px;\n color: var(--mj-text-secondary);\n font-weight: 500;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.rc-card-meta {\n display: flex;\n align-items: center;\n gap: 12px;\n font-size: 12px;\n color: var(--mj-text-disabled);\n flex-shrink: 0;\n}\n\n.rc-card-user {\n display: flex;\n align-items: center;\n gap: 5px;\n white-space: nowrap;\n}\n\n.rc-avatar {\n width: 20px;\n height: 20px;\n border-radius: 50%;\n background: var(--mj-brand-primary);\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 8px;\n font-weight: 700;\n color: var(--mj-text-inverse);\n flex-shrink: 0;\n}\n\n.rc-card-time { white-space: nowrap; }\n\n.rc-card-source {\n font-size: 10px;\n padding: 2px 6px;\n border-radius: 4px;\n font-weight: 500;\n white-space: nowrap;\n}\n\n.source-internal { background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface)); color: var(--mj-brand-primary); }\n.source-external { background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface)); color: var(--mj-status-warning); }\n\n.rc-card-status {\n font-size: 10px;\n padding: 2px 6px;\n border-radius: 4px;\n font-weight: 600;\n text-transform: uppercase;\n white-space: nowrap;\n}\n\n.status-complete { background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface)); color: var(--mj-status-success); }\n.status-pending { background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface)); color: var(--mj-status-warning); }\n.status-error { background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface)); color: var(--mj-status-error); }\n.status-unknown { background: var(--mj-bg-surface-sunken); color: var(--mj-text-muted); }\n\n.rc-card-chevron {\n color: var(--mj-text-disabled);\n transition: transform 0.2s;\n font-size: 12px;\n flex-shrink: 0;\n}\n\n.rc-card.expanded .rc-card-chevron { transform: rotate(180deg); }\n\n/* \u2500\u2500\u2500 Card Body \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.rc-card-body {\n border-top: 1px solid var(--mj-border-default);\n}\n\n/* \u2500\u2500\u2500 Field Row \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.rc-field-row {\n display: flex;\n align-items: stretch;\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.rc-field-row:last-child { border-bottom: none; }\n\n.rc-field-label {\n width: 140px;\n min-width: 140px;\n padding: 12px 16px;\n font-size: 12px;\n font-weight: 600;\n color: var(--mj-text-muted);\n background: var(--mj-bg-surface-card);\n display: flex;\n align-items: center;\n border-right: 1px solid var(--mj-border-default);\n}\n\n.rc-field-values {\n flex: 1;\n padding: 12px 16px;\n display: flex;\n align-items: center;\n min-width: 0;\n}\n\n/* \u2500\u2500\u2500 Atomic Change (numbers, dates) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.rc-atomic-change {\n display: flex;\n align-items: center;\n gap: 10px;\n flex-wrap: wrap;\n}\n\n.rc-val-old {\n font-size: 13px;\n font-family: 'SFMono-Regular', 'Consolas', 'Liberation Mono', 'Menlo', monospace;\n color: var(--mj-text-disabled);\n text-decoration: line-through;\n font-weight: 400;\n}\n\n.rc-val-arrow {\n color: var(--mj-border-strong);\n font-size: 11px;\n flex-shrink: 0;\n}\n\n.rc-val-new {\n font-size: 13px;\n font-family: 'SFMono-Regular', 'Consolas', 'Liberation Mono', 'Menlo', monospace;\n color: var(--mj-text-primary);\n font-weight: 500;\n}\n\n/* \u2500\u2500\u2500 Boolean Change \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.rc-bool-change {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.rc-bool-dot {\n width: 8px;\n height: 8px;\n border-radius: 50%;\n flex-shrink: 0;\n}\n\n.rc-bool-dot.on { background: var(--mj-status-success); }\n.rc-bool-dot.off { background: var(--mj-border-strong); }\n\n.rc-bool-label {\n font-size: 13px;\n font-weight: 500;\n}\n\n.rc-bool-label.old {\n color: var(--mj-text-disabled);\n text-decoration: line-through;\n}\n\n.rc-bool-label.new.active { color: var(--mj-status-success); }\n.rc-bool-label.new.inactive { color: var(--mj-text-disabled); }\n\n/* \u2500\u2500\u2500 Text Diff (strings only) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.rc-text-diff {\n font-size: 13px;\n font-family: 'SFMono-Regular', 'Consolas', 'Liberation Mono', 'Menlo', monospace;\n line-height: 1.6;\n word-wrap: break-word;\n white-space: pre-wrap;\n}\n\n.rc-diff-added {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n color: var(--mj-status-success);\n padding: 1px 3px;\n border-radius: 3px;\n}\n\n.rc-diff-removed {\n background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n color: var(--mj-status-error);\n padding: 1px 3px;\n border-radius: 3px;\n text-decoration: line-through;\n}\n\n.rc-diff-unchanged {\n color: var(--mj-text-secondary);\n}\n\n/* \u2500\u2500\u2500 Deletion Note \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.rc-deletion-note {\n padding: 16px 18px;\n color: var(--mj-text-muted);\n font-size: 13px;\n font-style: italic;\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.rc-deletion-note i {\n color: var(--mj-status-error);\n font-size: 14px;\n}\n\n/* \u2500\u2500\u2500 Comments & Errors \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.rc-comments {\n padding: 12px 18px;\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n font-size: 13px;\n color: var(--mj-brand-primary);\n display: flex;\n align-items: flex-start;\n gap: 8px;\n border-top: 1px solid var(--mj-border-default);\n}\n\n.rc-comments i {\n color: var(--mj-brand-primary);\n margin-top: 2px;\n flex-shrink: 0;\n}\n\n.rc-errors {\n padding: 12px 18px;\n background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n font-size: 13px;\n color: var(--mj-status-error);\n display: flex;\n align-items: flex-start;\n gap: 8px;\n border-top: 1px solid var(--mj-border-default);\n}\n\n.rc-errors i {\n color: var(--mj-status-error);\n margin-top: 2px;\n flex-shrink: 0;\n}\n\n.rc-error-log {\n background: var(--mj-bg-surface);\n padding: 8px;\n border-radius: 4px;\n font-family: 'SFMono-Regular', 'Consolas', 'Liberation Mono', 'Menlo', monospace;\n font-size: 12px;\n color: var(--mj-status-error);\n margin: 0;\n white-space: pre-wrap;\n overflow-x: auto;\n flex: 1;\n}\n\n/* \u2500\u2500\u2500 Create Wizard Overlay \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.rc-wizard-overlay {\n position: fixed;\n inset: 0;\n background: var(--mj-bg-overlay);\n z-index: 10000;\n display: flex;\n align-items: center;\n justify-content: center;\n animation: rc-fadeIn 0.15s ease;\n}\n\n.rc-wizard-container {\n background: var(--mj-bg-surface);\n border-radius: 12px;\n box-shadow: var(--mj-shadow-lg);\n width: 90%;\n max-width: 600px;\n max-height: 80vh;\n overflow-y: auto;\n padding: 24px;\n animation: rc-slideUp 0.2s ease;\n}\n\n@keyframes rc-fadeIn {\n from { opacity: 0; }\n to { opacity: 1; }\n}\n\n@keyframes rc-slideUp {\n from { opacity: 0; transform: translateY(20px); }\n to { opacity: 1; transform: translateY(0); }\n}\n\n/* \u2500\u2500\u2500 Responsive \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n@media (max-width: 768px) {\n .rc-card-header {\n flex-direction: column;\n align-items: flex-start;\n gap: 8px;\n }\n\n .rc-card-meta {\n flex-wrap: wrap;\n gap: 8px;\n }\n\n .rc-field-row {\n flex-direction: column;\n }\n\n .rc-field-label {\n width: 100%;\n min-width: unset;\n border-right: none;\n border-bottom: 1px solid var(--mj-border-default);\n padding: 8px 16px;\n }\n\n .rc-field-values {\n padding: 8px 16px;\n }\n\n .rc-atomic-change {\n flex-wrap: wrap;\n }\n\n .rc-filter-bar {\n flex-direction: column;\n align-items: stretch;\n }\n\n .rc-search-wrap { min-width: unset; }\n\n .rc-filter-pill { justify-content: center; }\n\n .rc-page-header {\n flex-direction: column;\n gap: 12px;\n }\n\n .rc-header-meta { text-align: left; }\n}\n\n@media (max-width: 480px) {\n .rc-container { padding: 12px 16px; }\n\n .rc-card { margin-left: 36px; }\n\n .rc-date-label { padding-left: 36px; }\n\n .rc-card::before { left: -19px; }\n\n .rc-timeline::before { left: 12px; }\n\n .rc-date-label::before { left: 7px; }\n}\n\n/* \u2500\u2500\u2500 Restore Action \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.rc-restore-action {\n display: flex;\n justify-content: flex-end;\n padding-top: 10px;\n margin-top: 10px;\n border-top: 1px solid var(--mj-border-subtle);\n}\n\n.rc-restore-btn {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 6px 14px;\n font-size: 12px;\n font-weight: 500;\n color: var(--mj-brand-primary);\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%, transparent);\n border-radius: 6px;\n cursor: pointer;\n transition: all 150ms ease;\n font-family: inherit;\n line-height: 1;\n}\n\n.rc-restore-btn:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n border-color: var(--mj-brand-primary);\n box-shadow: 0 2px 6px color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n}\n\n.rc-restore-btn:active {\n transform: translateY(1px);\n box-shadow: none;\n}\n\n.rc-restore-btn i {\n font-size: 13px;\n}\n\n/* \u2500\u2500\u2500 Restore Preview Panel \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.rc-restore-preview-backdrop {\n position: fixed;\n inset: 0;\n background: var(--mj-bg-overlay);\n z-index: 10000;\n display: flex;\n align-items: center;\n justify-content: center;\n animation: rc-fadeIn 0.15s ease;\n}\n\n.rc-restore-preview-panel {\n background: var(--mj-bg-surface);\n border-radius: 12px;\n box-shadow: var(--mj-shadow-lg);\n width: 90%;\n max-width: 700px;\n max-height: 80vh;\n overflow-y: auto;\n padding: 0;\n animation: rc-slideUp 0.2s ease;\n}\n\n.rc-restore-preview-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 16px 20px;\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.rc-restore-preview-title {\n display: flex;\n align-items: center;\n gap: 8px;\n font-size: 16px;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.rc-restore-preview-title i {\n color: var(--mj-brand-primary);\n}\n\n.rc-restore-preview-close {\n background: none;\n border: none;\n color: var(--mj-text-muted);\n cursor: pointer;\n padding: 4px 8px;\n border-radius: 4px;\n font-size: 16px;\n transition: color 0.15s, background 0.15s;\n}\n\n.rc-restore-preview-close:hover {\n color: var(--mj-text-primary);\n background: var(--mj-bg-surface-hover);\n}\n\n.rc-restore-preview-meta {\n display: flex;\n gap: 20px;\n padding: 12px 20px;\n font-size: 13px;\n color: var(--mj-text-secondary);\n background: var(--mj-bg-surface-card);\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.rc-restore-preview-empty {\n padding: 24px 20px;\n text-align: center;\n color: var(--mj-text-muted);\n font-size: 13px;\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 8px;\n}\n\n.rc-restore-preview-empty i {\n color: var(--mj-text-disabled);\n}\n\n/* Restore Preview Table */\n.rc-restore-preview-table {\n width: 100%;\n border-collapse: collapse;\n font-size: 13px;\n}\n\n.rc-restore-preview-table th {\n text-align: left;\n padding: 10px 16px;\n font-weight: 600;\n font-size: 11px;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n color: var(--mj-text-muted);\n background: var(--mj-bg-surface-sunken);\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.rc-restore-preview-table td {\n padding: 10px 16px;\n border-bottom: 1px solid var(--mj-border-default);\n vertical-align: top;\n}\n\n.rc-restore-preview-table tr:last-child td {\n border-bottom: none;\n}\n\n.rc-restore-preview-table tr.rc-diff-changed {\n background: color-mix(in srgb, var(--mj-status-warning) 5%, var(--mj-bg-surface));\n}\n\n.rc-restore-preview-table tr.rc-diff-unchanged {\n opacity: 0.6;\n}\n\n.rc-restore-field-name {\n font-weight: 600;\n color: var(--mj-text-primary);\n white-space: nowrap;\n}\n\n.rc-restore-current {\n font-family: 'SFMono-Regular', 'Consolas', 'Liberation Mono', 'Menlo', monospace;\n color: var(--mj-text-secondary);\n max-width: 200px;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.rc-restore-version {\n font-family: 'SFMono-Regular', 'Consolas', 'Liberation Mono', 'Menlo', monospace;\n color: var(--mj-text-primary);\n font-weight: 500;\n max-width: 200px;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.rc-restore-indicator {\n text-align: center;\n width: 30px;\n}\n\n.rc-diff-changed .rc-restore-indicator i {\n color: var(--mj-status-warning);\n}\n\n.rc-diff-unchanged .rc-restore-indicator i {\n color: var(--mj-status-success);\n font-size: 12px;\n}\n\n/* Restore Preview Actions */\n.rc-restore-preview-actions {\n display: flex;\n gap: 10px;\n padding: 16px 20px;\n border-top: 1px solid var(--mj-border-default);\n}\n\n.rc-restore-confirm-btn {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 8px 18px;\n font-size: 13px;\n font-weight: 600;\n color: var(--mj-text-inverse);\n background: var(--mj-brand-primary);\n border: none;\n border-radius: 8px;\n cursor: pointer;\n transition: background 0.15s, box-shadow 0.15s;\n font-family: inherit;\n}\n\n.rc-restore-confirm-btn:hover:not(:disabled) {\n background: var(--mj-brand-primary-hover);\n box-shadow: 0 2px 8px color-mix(in srgb, var(--mj-brand-primary) 25%, transparent);\n}\n\n.rc-restore-confirm-btn:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.rc-restore-cancel-btn {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 8px 18px;\n font-size: 13px;\n font-weight: 500;\n color: var(--mj-text-secondary);\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n cursor: pointer;\n transition: all 0.15s;\n font-family: inherit;\n}\n\n.rc-restore-cancel-btn:hover:not(:disabled) {\n border-color: var(--mj-border-strong);\n color: var(--mj-text-primary);\n}\n\n.rc-restore-cancel-btn:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n"] }]
1432
+ args: [{ standalone: false, selector: 'mj-record-changes', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: "<mj-slide-panel\n [Mode]=\"'slide'\"\n [Title]=\"'Record Changes History'\"\n [Visible]=\"IsVisible\"\n [Resizable]=\"true\"\n [MinWidthPx]=\"400\"\n [MaxWidthRatio]=\"0.6\"\n (Closed)=\"OnClose()\">\n\n @if (IsLoading) {\n <mj-loading text=\"Loading history...\" size=\"medium\"></mj-loading>\n }\n\n @if (!IsLoading) {\n <div class=\"rc-container\">\n <!-- Version Labels Section -->\n <div class=\"rc-labels-section\">\n <div class=\"rc-labels-header\">\n <div class=\"rc-labels-title\">\n <i class=\"fa-solid fa-tags\" aria-hidden=\"true\"></i>\n <span>Version Labels</span>\n @if (RecordLabels.length > 0) {\n <span class=\"rc-labels-count\">{{ RecordLabels.length }}</span>\n }\n </div>\n <button class=\"rc-create-label-btn\" (click)=\"OpenCreateWizard()\" title=\"Create a version label for this record\">\n <i class=\"fa-solid fa-plus\"></i> Create Label\n </button>\n </div>\n @if (IsLoadingLabels) {\n <div class=\"rc-labels-loading\">\n <i class=\"fa-solid fa-spinner fa-spin\"></i> Loading labels...\n </div>\n } @else if (RecordLabels.length === 0) {\n <div class=\"rc-labels-empty\">\n No version labels for this record yet.\n </div>\n } @else {\n <div class=\"rc-labels-list\">\n @for (label of RecordLabels; track label.ID) {\n <div class=\"rc-label-chip\" [title]=\"label.Description || label.Name\">\n <i class=\"fa-solid fa-tag rc-label-chip-icon\"></i>\n <span class=\"rc-label-chip-name\">{{ label.Name }}</span>\n <span class=\"rc-label-chip-meta\">\n <span class=\"rc-label-chip-status\" [class]=\"getLabelStatusClass(label.Status)\">{{ label.Status }}</span>\n <span class=\"rc-label-chip-items\">{{ label.ItemCount }} item{{ label.ItemCount !== 1 ? 's' : '' }}</span>\n </span>\n </div>\n }\n </div>\n }\n </div>\n\n @if (viewData.length === 0) {\n <!-- Empty state -->\n <div class=\"rc-empty-state\">\n <div class=\"rc-empty-state-icon\">\n <i class=\"fa-solid fa-clock-rotate-left\"></i>\n </div>\n <h3 class=\"rc-empty-state-title\">No Change History</h3>\n <p class=\"rc-empty-state-description\">\n This record doesn't have any tracked changes yet.\n Changes will appear here automatically as edits are made.\n </p>\n <div class=\"rc-empty-state-hint\">\n <i class=\"fa-solid fa-shield-halved\"></i>\n <span>Record change tracking is managed at the entity level</span>\n </div>\n </div>\n } @else {\n <!-- Page Header -->\n <div class=\"rc-page-header\">\n <div>\n <h2 class=\"rc-page-title\">Change History</h2>\n <div class=\"rc-page-subtitle\">{{ record.EntityInfo.Name }}</div>\n </div>\n <div class=\"rc-header-meta\">\n <div class=\"rc-entity-badge\">\n <i class=\"fa-solid fa-database\" aria-hidden=\"true\"></i>\n {{ record.EntityInfo.Name }}\n </div>\n <div class=\"rc-change-count\">{{ viewData.length }} change{{ viewData.length !== 1 ? 's' : '' }} &middot; {{ getUniqueContributorCount() }} contributor{{ getUniqueContributorCount() !== 1 ? 's' : '' }}</div>\n </div>\n </div>\n\n <!-- Filter Bar \u2014 chips render only for change types/sources actually present in loaded data.\n When more than 2 conditional chips would render, they collapse into a \"More filters\" popover. -->\n <div class=\"rc-filter-bar\">\n <div class=\"rc-search-wrap\">\n <i class=\"fa-solid fa-search\" aria-hidden=\"true\"></i>\n <input\n class=\"rc-search-box\"\n type=\"text\"\n placeholder=\"Search changes...\"\n [(ngModel)]=\"searchTerm\"\n (input)=\"onSearchChange()\"\n aria-label=\"Search record changes\"\n />\n </div>\n\n <button class=\"rc-filter-pill\" [class.active]=\"IsAllSelected\" (click)=\"SelectAllPill()\" type=\"button\">\n <i class=\"fa-solid fa-layer-group\" aria-hidden=\"true\"></i> All\n </button>\n\n @if (HasConditionalPills) {\n @if (!UseOverflowPopover) {\n <!-- 1-2 conditional pills: render inline -->\n @for (pill of ConditionalPills; track pill.Key) {\n <button class=\"rc-filter-pill\"\n [class.active]=\"ChipSelections[pill.Key]\"\n [class.rc-filter-pill-restore]=\"pill.Variant === 'restore'\"\n (click)=\"TogglePill(pill.Key)\"\n type=\"button\">\n <i class=\"fa-solid {{ pill.Icon }}\" aria-hidden=\"true\"></i>\n {{ pill.Label }}\n <span class=\"rc-filter-pill-count\">{{ pill.Count }}</span>\n </button>\n }\n } @else {\n <!-- 3+ conditional pills: overflow popover -->\n <div class=\"rc-filter-overflow-wrap\">\n <button class=\"rc-filter-pill rc-filter-pill-overflow\"\n [class.active]=\"SelectedConditionalCount > 0\"\n (click)=\"ToggleFilterOverflow()\"\n type=\"button\">\n <i class=\"fa-solid fa-sliders\" aria-hidden=\"true\"></i>\n More filters\n @if (SelectedConditionalCount > 0) {\n <span class=\"rc-filter-pill-count\">{{ SelectedConditionalCount }}</span>\n }\n <i class=\"fa-solid fa-chevron-down rc-filter-overflow-caret\" aria-hidden=\"true\"></i>\n </button>\n\n @if (ShowFilterOverflow) {\n <!-- Backdrop: clicks close the popover -->\n <div class=\"rc-filter-overflow-backdrop\" (click)=\"CloseFilterOverflow()\"></div>\n <div class=\"rc-filter-overflow-popover\" role=\"menu\">\n <div class=\"rc-filter-overflow-header\">Filter by</div>\n @for (pill of ConditionalPills; track pill.Key) {\n <label class=\"rc-filter-overflow-row\" [class.rc-filter-overflow-row-restore]=\"pill.Variant === 'restore'\">\n <input type=\"checkbox\"\n [checked]=\"ChipSelections[pill.Key]\"\n (change)=\"TogglePill(pill.Key)\" />\n <i class=\"fa-solid {{ pill.Icon }}\" aria-hidden=\"true\"></i>\n <span class=\"rc-filter-overflow-label\">{{ pill.Label }}</span>\n <span class=\"rc-filter-overflow-count\">{{ pill.Count }}</span>\n </label>\n }\n <div class=\"rc-filter-overflow-actions\">\n <button class=\"rc-filter-overflow-clear\" (click)=\"SelectAllPill(); CloseFilterOverflow()\" type=\"button\">\n Clear all\n </button>\n <button class=\"rc-filter-overflow-done\" (click)=\"CloseFilterOverflow()\" type=\"button\">\n Done\n </button>\n </div>\n </div>\n }\n </div>\n }\n }\n </div>\n\n @if (filteredData.length !== viewData.length) {\n <div class=\"rc-filter-results\">\n Showing {{ filteredData.length }} of {{ viewData.length }} changes\n <button class=\"rc-clear-filters-link\" (click)=\"ClearFilters()\">Clear filters</button>\n </div>\n }\n\n <!-- Timeline -->\n <div class=\"rc-timeline\" [attr.aria-label]=\"'Timeline of changes for ' + record.EntityInfo.Name + ' record'\">\n @if (filteredData.length === 0) {\n <div class=\"rc-no-results\">\n <i class=\"fa-solid fa-filter\" aria-hidden=\"true\"></i>\n <p>No changes match your current filters.</p>\n <button class=\"rc-clear-filters-btn\" (click)=\"ClearFilters()\">\n <i class=\"fa-solid fa-xmark\"></i> Clear Filters\n </button>\n </div>\n } @else {\n @for (group of dateGroups; track group.label) {\n <div class=\"rc-date-group\">\n <div class=\"rc-date-label\">{{ group.label }}</div>\n\n @for (change of group.changes; track change.ID) {\n <div\n class=\"rc-card\"\n [attr.data-change-id]=\"change.ID\"\n [class]=\"getChangeTypeCardClass(change.Type)\"\n [class.expanded]=\"expandedItems.has(change.ID)\"\n [class.rc-card-restore]=\"isRestoreRow(change)\"\n [class.rc-card-highlight]=\"HighlightedChangeID === change.ID\"\n [attr.tabindex]=\"0\"\n [attr.aria-expanded]=\"expandedItems.has(change.ID)\"\n [attr.aria-label]=\"getTimelineItemLabel(change)\"\n (keydown)=\"onTimelineItemKeydown($event, change.ID)\"\n >\n <!-- Card Header -->\n <div class=\"rc-card-header\" (click)=\"toggleExpansion(change.ID)\">\n <div class=\"rc-card-header-left\">\n <span class=\"rc-card-type-badge\"\n [class.rc-card-type-badge-restore]=\"isRestoreRow(change)\">{{ getEffectiveBadgeText(change) }}</span>\n <span class=\"rc-card-summary\">{{ getChangeSummary(change) }}</span>\n\n <!-- Lineage chip \u2014 visible when this row was produced by a restore -->\n @if (isRestoreRow(change)) {\n @if (getRestoredFromSourceChange(change); as srcChange) {\n <a class=\"rc-restored-chip\"\n (click)=\"JumpToSourceChange(srcChange, $event)\"\n [title]=\"'Jump to source version (' + formatFullDateTime(srcChange.ChangedAt) + ')'\">\n <i class=\"fa-solid fa-link\" aria-hidden=\"true\"></i>\n Restored from {{ formatTime(srcChange.ChangedAt) }} {{ srcChange.ChangedAt ? 'on ' + (srcChange.ChangedAt | date:'mediumDate') : '' }}\n @if (srcChange.User) {\n by {{ getUserDisplayName(srcChange.User) }}\n }\n </a>\n } @else {\n <span class=\"rc-restored-chip rc-restored-chip-orphan\"\n title=\"Source version was not loaded into this view\">\n <i class=\"fa-solid fa-clock-rotate-left\" aria-hidden=\"true\"></i>\n Restored from earlier version\n </span>\n }\n }\n </div>\n <div class=\"rc-card-meta\">\n <div class=\"rc-card-user\">\n <div class=\"rc-avatar\">{{ getUserInitials(change.User) }}</div>\n {{ getUserDisplayName(change.User) }}\n </div>\n <span class=\"rc-card-time\" [title]=\"formatFullDateTime(change.ChangedAt)\">{{ formatTime(change.ChangedAt) }}</span>\n <span class=\"rc-card-source\" [class]=\"getSourceClass(change.Source)\">{{ change.Source }}</span>\n <span class=\"rc-card-status\" [class]=\"getStatusClass(change.Status)\">{{ change.Status }}</span>\n <i class=\"fa-solid fa-chevron-down rc-card-chevron\" aria-hidden=\"true\"></i>\n </div>\n </div>\n\n <!-- Card Body (expanded) -->\n @if (expandedItems.has(change.ID)) {\n <div class=\"rc-card-body\">\n <!-- Restore reason (when present) \u2014 Notion/Linear-style\n blockquote: a thin violet left bar + italic text,\n with a tiny \"Reason\" prefix. No box, no header,\n no large vertical footprint. Reads as a\n justification note rather than a callout. -->\n @if (getRestoreReason(change); as reason) {\n <blockquote class=\"rc-restore-reason\">\n <span class=\"rc-restore-reason-label\">Reason</span>\n <span class=\"rc-restore-reason-text\">{{ reason }}</span>\n </blockquote>\n }\n\n @if (change.Type === 'Create') {\n @if (change.FullRecordJSON) {\n @for (field of getCreatedFields(change); track field.name) {\n <div class=\"rc-field-row\">\n <div class=\"rc-field-label\">{{ field.displayName }}</div>\n <div class=\"rc-field-values\">\n <span class=\"rc-val-new\">{{ field.value }}</span>\n </div>\n </div>\n }\n }\n } @else if (change.Type === 'Delete') {\n <div class=\"rc-deletion-note\">\n <i class=\"fa-solid fa-trash\" aria-hidden=\"true\"></i>\n This record was permanently removed from the system.\n </div>\n } @else {\n <!-- Update / Snapshot / Restore: type-aware field changes -->\n @for (fc of getFieldChanges(change); track fc.field) {\n <div class=\"rc-field-row\">\n <div class=\"rc-field-label\">{{ fc.displayName }}</div>\n <div class=\"rc-field-values\">\n @if (fc.fieldType === 'boolean') {\n <div class=\"rc-bool-change\">\n <span class=\"rc-bool-dot\" [class.on]=\"fc.oldValue === 'true' || fc.oldValue === '1'\" [class.off]=\"fc.oldValue !== 'true' && fc.oldValue !== '1'\"></span>\n <span class=\"rc-bool-label old\">{{ fc.oldValue === 'true' || fc.oldValue === '1' ? 'Yes' : 'No' }}</span>\n <i class=\"fa-solid fa-arrow-right rc-val-arrow\" aria-hidden=\"true\"></i>\n <span class=\"rc-bool-dot\" [class.on]=\"fc.newValue === 'true' || fc.newValue === '1'\" [class.off]=\"fc.newValue !== 'true' && fc.newValue !== '1'\"></span>\n <span class=\"rc-bool-label new\" [class.active]=\"fc.newValue === 'true' || fc.newValue === '1'\" [class.inactive]=\"fc.newValue !== 'true' && fc.newValue !== '1'\">{{ fc.newValue === 'true' || fc.newValue === '1' ? 'Yes' : 'No' }}</span>\n </div>\n } @else if (fc.fieldType === 'date' || fc.fieldType === 'number') {\n <div class=\"rc-atomic-change\">\n <span class=\"rc-val-old\">{{ fc.oldValue || '(empty)' }}</span>\n <i class=\"fa-solid fa-arrow-right rc-val-arrow\" aria-hidden=\"true\"></i>\n <span class=\"rc-val-new\">{{ fc.newValue || '(empty)' }}</span>\n </div>\n } @else if (fc.diffHtml) {\n <div class=\"rc-text-diff\" [innerHTML]=\"fc.diffHtml\"></div>\n } @else {\n <div class=\"rc-atomic-change\">\n <span class=\"rc-val-old\">{{ fc.oldValue || '(empty)' }}</span>\n <i class=\"fa-solid fa-arrow-right rc-val-arrow\" aria-hidden=\"true\"></i>\n <span class=\"rc-val-new\">{{ fc.newValue || '(empty)' }}</span>\n </div>\n }\n </div>\n </div>\n }\n }\n\n @if (change.Comments) {\n <div class=\"rc-comments\">\n <i class=\"fa-solid fa-comment\" aria-hidden=\"true\"></i>\n {{ change.Comments }}\n </div>\n }\n\n @if (change.ErrorLog) {\n <div class=\"rc-errors\">\n <i class=\"fa-solid fa-exclamation-triangle\" aria-hidden=\"true\"></i>\n <pre class=\"rc-error-log\">{{ change.ErrorLog }}</pre>\n </div>\n }\n\n <!-- Restore action: shown for Update, Create, and Snapshot rows.\n Hidden on Delete rows (handled via the Recycle Bin path)\n and on the most recent change (restoring to current state is a no-op). -->\n @if (AllowRestore && change.Type !== 'Delete' && !isMostRecentChange(change)) {\n <div class=\"rc-restore-action\">\n <button class=\"rc-restore-btn\"\n (click)=\"OnRestoreVersion(change, $event)\"\n title=\"Restore the entire record to its state at this version\">\n <i class=\"fa-solid fa-clock-rotate-left\" aria-hidden=\"true\"></i>\n Restore record to this version\n </button>\n </div>\n }\n </div>\n }\n </div>\n }\n </div>\n }\n }\n </div>\n }\n </div>\n }\n\n <!-- Restore preview slide-in (reusable component) -->\n <mj-restore-preview-panel\n [Visible]=\"RestorePreviewVisible\"\n [Mode]=\"'live'\"\n [RecordChange]=\"RestorePreviewChange\"\n [LiveRecord]=\"record\"\n (RestoreConfirmed)=\"OnRestorePanelConfirmed($event)\"\n (RestoreCancelled)=\"OnRestorePanelCancelled()\">\n </mj-restore-preview-panel>\n\n @if (ShowCreateWizard) {\n <div class=\"rc-wizard-overlay\" (click)=\"OnLabelCreateCancelled()\">\n <div class=\"rc-wizard-container\" (click)=\"$event.stopPropagation()\">\n <mj-label-create\n [PreselectedEntity]=\"record.EntityInfo\"\n [PreselectedRecordIds]=\"[record.PrimaryKey.KeyValuePairs[0].Value]\"\n (Created)=\"OnLabelCreated($event)\"\n (Cancel)=\"OnLabelCreateCancelled()\">\n </mj-label-create>\n </div>\n </div>\n }\n</mj-slide-panel>\n", styles: ["/* \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n Record Changes \u2014 Option A \"Clean Timeline\"\n Linear / Notion-inspired minimal timeline design\n \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 */\n\n/* \u2500\u2500\u2500 Container \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.rc-container {\n display: flex;\n flex-direction: column;\n height: 100%;\n padding: 20px 24px;\n background: var(--mj-bg-surface-card);\n}\n\n/* \u2500\u2500\u2500 Version Labels Section \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.rc-labels-section {\n background: var(--mj-bg-surface-card);\n border-radius: 8px;\n padding: 12px 16px;\n margin-bottom: 20px;\n border: 1px solid var(--mj-border-default);\n}\n\n.rc-labels-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: 8px;\n}\n\n.rc-labels-title {\n display: flex;\n align-items: center;\n gap: 8px;\n font-weight: 600;\n font-size: 13px;\n color: var(--mj-text-secondary);\n}\n\n.rc-labels-title i { color: var(--mj-brand-primary); }\n\n.rc-labels-count {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n min-width: 20px;\n height: 20px;\n padding: 0 6px;\n border-radius: 10px;\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n font-size: 10px;\n font-weight: 700;\n}\n\n.rc-create-label-btn {\n display: inline-flex;\n align-items: center;\n gap: 5px;\n padding: 5px 12px;\n border: 1px solid var(--mj-brand-primary);\n border-radius: 6px;\n background: var(--mj-bg-surface);\n color: var(--mj-brand-primary);\n font-size: 12px;\n font-weight: 600;\n cursor: pointer;\n transition: all 0.15s ease;\n}\n\n.rc-create-label-btn:hover {\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n}\n\n.rc-labels-loading {\n font-size: 12px;\n color: var(--mj-text-muted);\n padding: 4px 0;\n}\n\n.rc-labels-loading i { margin-right: 4px; }\n\n.rc-labels-empty {\n font-size: 12px;\n color: var(--mj-text-disabled);\n font-style: italic;\n padding: 4px 0;\n}\n\n.rc-labels-list {\n display: flex;\n flex-wrap: wrap;\n gap: 8px;\n}\n\n.rc-label-chip {\n display: inline-flex;\n align-items: center;\n gap: 5px;\n padding: 4px 10px;\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: 16px;\n font-size: 12px;\n color: var(--mj-text-secondary);\n transition: all 0.15s ease;\n cursor: default;\n}\n\n.rc-label-chip:hover {\n border-color: var(--mj-brand-primary);\n box-shadow: var(--mj-shadow-sm);\n}\n\n.rc-label-chip-icon { color: var(--mj-brand-primary); font-size: 10px; }\n\n.rc-label-chip-name {\n font-weight: 600;\n max-width: 180px;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.rc-label-chip-meta {\n display: flex;\n align-items: center;\n gap: 4px;\n font-size: 10px;\n color: var(--mj-text-muted);\n}\n\n.rc-label-chip-status {\n padding: 1px 5px;\n border-radius: 4px;\n font-weight: 600;\n text-transform: uppercase;\n font-size: 9px;\n letter-spacing: 0.03em;\n}\n\n.label-status-active { background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface)); color: var(--mj-status-success); }\n.label-status-archived { background: var(--mj-bg-surface-sunken); color: var(--mj-text-secondary); }\n.label-status-restored { background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface)); color: var(--mj-brand-primary); }\n\n.rc-label-chip-items { white-space: nowrap; }\n\n/* \u2500\u2500\u2500 Empty State \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.rc-empty-state {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 64px 32px;\n text-align: center;\n min-height: 400px;\n}\n\n.rc-empty-state-icon {\n width: 80px;\n height: 80px;\n border-radius: 50%;\n background: var(--mj-bg-surface-sunken);\n display: flex;\n align-items: center;\n justify-content: center;\n margin-bottom: 24px;\n}\n\n.rc-empty-state-icon i { font-size: 32px; color: var(--mj-text-disabled); }\n\n.rc-empty-state-title {\n font-size: 20px;\n font-weight: 600;\n color: var(--mj-text-secondary);\n margin: 0 0 12px 0;\n}\n\n.rc-empty-state-description {\n font-size: 14px;\n color: var(--mj-text-muted);\n line-height: 1.6;\n max-width: 320px;\n margin: 0 0 24px 0;\n}\n\n.rc-empty-state-hint {\n display: inline-flex;\n align-items: center;\n gap: 8px;\n padding: 8px 16px;\n background: var(--mj-bg-surface-sunken);\n border-radius: 20px;\n font-size: 12px;\n color: var(--mj-text-muted);\n}\n\n.rc-empty-state-hint i { color: var(--mj-text-disabled); }\n\n/* \u2500\u2500\u2500 Page Header \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.rc-page-header {\n display: flex;\n justify-content: space-between;\n align-items: flex-start;\n margin-bottom: 24px;\n padding-bottom: 20px;\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.rc-page-title {\n font-size: 20px;\n font-weight: 700;\n color: var(--mj-text-primary);\n margin: 0;\n}\n\n.rc-page-subtitle {\n font-size: 13px;\n color: var(--mj-text-muted);\n margin-top: 4px;\n}\n\n.rc-header-meta { text-align: right; }\n\n.rc-entity-badge {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 5px 12px;\n border-radius: 6px;\n font-size: 12px;\n font-weight: 500;\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n border: 1px solid color-mix(in srgb, var(--mj-brand-primary) 25%, var(--mj-bg-surface));\n}\n\n.rc-change-count {\n font-size: 12px;\n color: var(--mj-text-disabled);\n margin-top: 6px;\n}\n\n/* \u2500\u2500\u2500 Filter Bar \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.rc-filter-bar {\n display: flex;\n gap: 8px;\n margin-bottom: 20px;\n flex-wrap: wrap;\n align-items: center;\n}\n\n.rc-search-wrap {\n position: relative;\n flex: 1;\n min-width: 180px;\n}\n\n.rc-search-wrap i {\n position: absolute;\n left: 12px;\n top: 50%;\n transform: translateY(-50%);\n color: var(--mj-text-disabled);\n font-size: 13px;\n pointer-events: none;\n}\n\n.rc-search-box {\n width: 100%;\n padding: 8px 12px 8px 36px;\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n font-size: 13px;\n background: var(--mj-bg-surface);\n outline: none;\n color: var(--mj-text-primary);\n transition: border-color 0.15s, box-shadow 0.15s;\n}\n\n.rc-search-box:focus {\n border-color: var(--mj-brand-primary);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n}\n\n.rc-search-box::placeholder { color: var(--mj-text-disabled); }\n\n.rc-filter-pill {\n padding: 7px 14px;\n border-radius: 8px;\n font-size: 12px;\n font-weight: 500;\n border: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface);\n cursor: pointer;\n color: var(--mj-text-secondary);\n transition: all 0.15s;\n display: flex;\n align-items: center;\n gap: 5px;\n}\n\n.rc-filter-pill:hover {\n border-color: var(--mj-brand-primary);\n color: var(--mj-brand-primary);\n}\n\n.rc-filter-pill.active {\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n border-color: var(--mj-brand-primary);\n}\n\n.rc-filter-results {\n font-size: 12px;\n color: var(--mj-text-muted);\n margin-bottom: 16px;\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.rc-clear-filters-link {\n background: none;\n border: none;\n color: var(--mj-brand-primary);\n font-size: 12px;\n font-weight: 500;\n cursor: pointer;\n padding: 0;\n text-decoration: underline;\n}\n\n.rc-clear-filters-link:hover { color: var(--mj-brand-primary-hover); }\n\n/* \u2500\u2500\u2500 No Results \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.rc-no-results {\n text-align: center;\n padding: 48px 16px;\n color: var(--mj-text-muted);\n}\n\n.rc-no-results i {\n display: block;\n font-size: 32px;\n margin-bottom: 16px;\n color: var(--mj-text-disabled);\n}\n\n.rc-no-results p { font-size: 14px; margin: 0 0 16px 0; }\n\n.rc-clear-filters-btn {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 6px 16px;\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n background: var(--mj-bg-surface);\n color: var(--mj-text-secondary);\n font-size: 13px;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.15s ease;\n}\n\n.rc-clear-filters-btn:hover {\n border-color: var(--mj-brand-primary);\n color: var(--mj-brand-primary);\n}\n\n/* \u2500\u2500\u2500 Timeline \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.rc-timeline {\n position: relative;\n flex: 1;\n overflow-y: auto;\n}\n\n/* Vertical line running through the timeline */\n.rc-timeline::before {\n content: '';\n position: absolute;\n left: 15px;\n top: 24px;\n bottom: 0;\n width: 2px;\n background: var(--mj-border-default);\n}\n\n/* \u2500\u2500\u2500 Date Group \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.rc-date-group { margin-bottom: 8px; }\n\n.rc-date-label {\n position: relative;\n font-size: 11px;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.8px;\n color: var(--mj-text-disabled);\n padding: 16px 0 12px 44px;\n}\n\n/* Date dot on the timeline line */\n.rc-date-label::before {\n content: '';\n position: absolute;\n left: 10px;\n top: 50%;\n transform: translateY(-50%);\n width: 12px;\n height: 12px;\n border-radius: 50%;\n background: var(--mj-border-default);\n border: 2px solid var(--mj-bg-surface-card);\n}\n\n/* \u2500\u2500\u2500 Change Card \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.rc-card {\n position: relative;\n margin-left: 44px;\n margin-bottom: 12px;\n background: var(--mj-bg-surface);\n border-radius: 12px;\n border: 1px solid var(--mj-border-default);\n transition: all 0.2s;\n overflow: hidden;\n}\n\n.rc-card:hover {\n border-color: var(--mj-border-strong);\n box-shadow: var(--mj-shadow-sm);\n}\n\n.rc-card:focus {\n outline: 2px solid var(--mj-brand-primary);\n outline-offset: 2px;\n}\n\n/* Colored dot on the timeline line for each card */\n.rc-card::before {\n content: '';\n position: absolute;\n left: -23px;\n top: 20px;\n width: 8px;\n height: 8px;\n border-radius: 50%;\n z-index: 1;\n}\n\n.rc-card.type-update::before {\n background: var(--mj-brand-primary);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n}\n\n.rc-card.type-create::before {\n background: var(--mj-status-success);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-status-success) 15%, transparent);\n}\n\n.rc-card.type-delete::before {\n background: var(--mj-status-error);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-status-error) 15%, transparent);\n}\n\n/* \u2500\u2500\u2500 Card Header \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.rc-card-header {\n padding: 14px 18px;\n display: flex;\n justify-content: space-between;\n align-items: center;\n cursor: pointer;\n user-select: none;\n gap: 12px;\n}\n\n.rc-card-header-left {\n display: flex;\n align-items: center;\n gap: 10px;\n min-width: 0;\n flex: 1;\n /* Allow the lineage chip to wrap to a second line on narrow panel widths\n instead of squeezing the title text into a \"Name and Description c...\"\n truncation. The badge stays on the first line; chip wraps gracefully. */\n flex-wrap: wrap;\n row-gap: 6px;\n}\n\n.rc-card-type-badge {\n padding: 3px 10px;\n border-radius: 5px;\n font-size: 10px;\n font-weight: 600;\n letter-spacing: 0.3px;\n text-transform: uppercase;\n white-space: nowrap;\n flex-shrink: 0;\n}\n\n.type-update .rc-card-type-badge { background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface)); color: var(--mj-brand-primary); }\n.type-create .rc-card-type-badge { background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface)); color: var(--mj-status-success); }\n.type-delete .rc-card-type-badge { background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface)); color: var(--mj-status-error); }\n\n.rc-card-summary {\n font-size: 13px;\n color: var(--mj-text-secondary);\n font-weight: 500;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.rc-card-meta {\n display: flex;\n align-items: center;\n gap: 12px;\n font-size: 12px;\n color: var(--mj-text-disabled);\n flex-shrink: 0;\n}\n\n.rc-card-user {\n display: flex;\n align-items: center;\n gap: 5px;\n white-space: nowrap;\n}\n\n.rc-avatar {\n width: 20px;\n height: 20px;\n border-radius: 50%;\n background: var(--mj-brand-primary);\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 8px;\n font-weight: 700;\n color: var(--mj-text-inverse);\n flex-shrink: 0;\n}\n\n.rc-card-time { white-space: nowrap; }\n\n.rc-card-source {\n font-size: 10px;\n padding: 2px 6px;\n border-radius: 4px;\n font-weight: 500;\n white-space: nowrap;\n}\n\n.source-internal { background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface)); color: var(--mj-brand-primary); }\n.source-external { background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface)); color: var(--mj-status-warning); }\n\n.rc-card-status {\n font-size: 10px;\n padding: 2px 6px;\n border-radius: 4px;\n font-weight: 600;\n text-transform: uppercase;\n white-space: nowrap;\n}\n\n.status-complete { background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface)); color: var(--mj-status-success); }\n.status-pending { background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface)); color: var(--mj-status-warning); }\n.status-error { background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface)); color: var(--mj-status-error); }\n.status-unknown { background: var(--mj-bg-surface-sunken); color: var(--mj-text-muted); }\n\n.rc-card-chevron {\n color: var(--mj-text-disabled);\n transition: transform 0.2s;\n font-size: 12px;\n flex-shrink: 0;\n}\n\n.rc-card.expanded .rc-card-chevron { transform: rotate(180deg); }\n\n/* \u2500\u2500\u2500 Card Body \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.rc-card-body {\n border-top: 1px solid var(--mj-border-default);\n}\n\n/* \u2500\u2500\u2500 Field Row \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.rc-field-row {\n display: flex;\n align-items: stretch;\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.rc-field-row:last-child { border-bottom: none; }\n\n.rc-field-label {\n width: 140px;\n min-width: 140px;\n padding: 12px 16px;\n font-size: 12px;\n font-weight: 600;\n color: var(--mj-text-muted);\n background: var(--mj-bg-surface-card);\n display: flex;\n align-items: center;\n border-right: 1px solid var(--mj-border-default);\n}\n\n.rc-field-values {\n flex: 1;\n padding: 12px 16px;\n display: flex;\n align-items: center;\n min-width: 0;\n}\n\n/* \u2500\u2500\u2500 Atomic Change (numbers, dates) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.rc-atomic-change {\n display: flex;\n align-items: center;\n gap: 10px;\n flex-wrap: wrap;\n}\n\n.rc-val-old {\n font-size: 13px;\n font-family: 'SFMono-Regular', 'Consolas', 'Liberation Mono', 'Menlo', monospace;\n color: var(--mj-text-disabled);\n text-decoration: line-through;\n font-weight: 400;\n}\n\n.rc-val-arrow {\n color: var(--mj-border-strong);\n font-size: 11px;\n flex-shrink: 0;\n}\n\n.rc-val-new {\n font-size: 13px;\n font-family: 'SFMono-Regular', 'Consolas', 'Liberation Mono', 'Menlo', monospace;\n color: var(--mj-text-primary);\n font-weight: 500;\n}\n\n/* \u2500\u2500\u2500 Boolean Change \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.rc-bool-change {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.rc-bool-dot {\n width: 8px;\n height: 8px;\n border-radius: 50%;\n flex-shrink: 0;\n}\n\n.rc-bool-dot.on { background: var(--mj-status-success); }\n.rc-bool-dot.off { background: var(--mj-border-strong); }\n\n.rc-bool-label {\n font-size: 13px;\n font-weight: 500;\n}\n\n.rc-bool-label.old {\n color: var(--mj-text-disabled);\n text-decoration: line-through;\n}\n\n.rc-bool-label.new.active { color: var(--mj-status-success); }\n.rc-bool-label.new.inactive { color: var(--mj-text-disabled); }\n\n/* \u2500\u2500\u2500 Text Diff (strings only) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.rc-text-diff {\n font-size: 13px;\n font-family: 'SFMono-Regular', 'Consolas', 'Liberation Mono', 'Menlo', monospace;\n line-height: 1.6;\n word-wrap: break-word;\n white-space: pre-wrap;\n}\n\n.rc-diff-added {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n color: var(--mj-status-success);\n padding: 1px 3px;\n border-radius: 3px;\n}\n\n.rc-diff-removed {\n background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n color: var(--mj-status-error);\n padding: 1px 3px;\n border-radius: 3px;\n text-decoration: line-through;\n}\n\n.rc-diff-unchanged {\n color: var(--mj-text-secondary);\n}\n\n/* \u2500\u2500\u2500 Deletion Note \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.rc-deletion-note {\n padding: 16px 18px;\n color: var(--mj-text-muted);\n font-size: 13px;\n font-style: italic;\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.rc-deletion-note i {\n color: var(--mj-status-error);\n font-size: 14px;\n}\n\n/* \u2500\u2500\u2500 Comments & Errors \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.rc-comments {\n padding: 12px 18px;\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n font-size: 13px;\n color: var(--mj-brand-primary);\n display: flex;\n align-items: flex-start;\n gap: 8px;\n border-top: 1px solid var(--mj-border-default);\n}\n\n.rc-comments i {\n color: var(--mj-brand-primary);\n margin-top: 2px;\n flex-shrink: 0;\n}\n\n.rc-errors {\n padding: 12px 18px;\n background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n font-size: 13px;\n color: var(--mj-status-error);\n display: flex;\n align-items: flex-start;\n gap: 8px;\n border-top: 1px solid var(--mj-border-default);\n}\n\n.rc-errors i {\n color: var(--mj-status-error);\n margin-top: 2px;\n flex-shrink: 0;\n}\n\n.rc-error-log {\n background: var(--mj-bg-surface);\n padding: 8px;\n border-radius: 4px;\n font-family: 'SFMono-Regular', 'Consolas', 'Liberation Mono', 'Menlo', monospace;\n font-size: 12px;\n color: var(--mj-status-error);\n margin: 0;\n white-space: pre-wrap;\n overflow-x: auto;\n flex: 1;\n}\n\n/* \u2500\u2500\u2500 Create Wizard Overlay \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.rc-wizard-overlay {\n position: fixed;\n inset: 0;\n background: var(--mj-bg-overlay);\n z-index: 10000;\n display: flex;\n align-items: center;\n justify-content: center;\n animation: rc-fadeIn 0.15s ease;\n}\n\n.rc-wizard-container {\n background: var(--mj-bg-surface);\n border-radius: 12px;\n box-shadow: var(--mj-shadow-lg);\n width: 90%;\n max-width: 600px;\n max-height: 80vh;\n overflow-y: auto;\n padding: 24px;\n animation: rc-slideUp 0.2s ease;\n}\n\n@keyframes rc-fadeIn {\n from { opacity: 0; }\n to { opacity: 1; }\n}\n\n@keyframes rc-slideUp {\n from { opacity: 0; transform: translateY(20px); }\n to { opacity: 1; transform: translateY(0); }\n}\n\n/* \u2500\u2500\u2500 Responsive \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n@media (max-width: 768px) {\n .rc-card-header {\n flex-direction: column;\n align-items: flex-start;\n gap: 8px;\n }\n\n .rc-card-meta {\n flex-wrap: wrap;\n gap: 8px;\n }\n\n .rc-field-row {\n flex-direction: column;\n }\n\n .rc-field-label {\n width: 100%;\n min-width: unset;\n border-right: none;\n border-bottom: 1px solid var(--mj-border-default);\n padding: 8px 16px;\n }\n\n .rc-field-values {\n padding: 8px 16px;\n }\n\n .rc-atomic-change {\n flex-wrap: wrap;\n }\n\n .rc-filter-bar {\n flex-direction: column;\n align-items: stretch;\n }\n\n .rc-search-wrap { min-width: unset; }\n\n .rc-filter-pill { justify-content: center; }\n\n .rc-page-header {\n flex-direction: column;\n gap: 12px;\n }\n\n .rc-header-meta { text-align: left; }\n}\n\n@media (max-width: 480px) {\n .rc-container { padding: 12px 16px; }\n\n .rc-card { margin-left: 36px; }\n\n .rc-date-label { padding-left: 36px; }\n\n .rc-card::before { left: -19px; }\n\n .rc-timeline::before { left: 12px; }\n\n .rc-date-label::before { left: 7px; }\n}\n\n/* \u2500\u2500\u2500 Restore Action \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.rc-restore-action {\n display: flex;\n justify-content: flex-end;\n padding-top: 10px;\n margin-top: 10px;\n /* Breathing room from the card's bottom and right edges so the button\n doesn't sit flush against the border. */\n padding-right: 10px;\n padding-bottom: 10px;\n border-top: 1px solid var(--mj-border-subtle);\n}\n\n.rc-restore-btn {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 6px 14px;\n font-size: 12px;\n font-weight: 500;\n color: var(--mj-brand-primary);\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%, transparent);\n border-radius: 6px;\n cursor: pointer;\n transition: all 150ms ease;\n font-family: inherit;\n line-height: 1;\n}\n\n.rc-restore-btn:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n border-color: var(--mj-brand-primary);\n box-shadow: 0 2px 6px color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n}\n\n.rc-restore-btn:active {\n transform: translateY(1px);\n box-shadow: none;\n}\n\n.rc-restore-btn i {\n font-size: 13px;\n}\n\n/* \u2500\u2500\u2500 Restore Preview Panel \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.rc-restore-preview-backdrop {\n position: fixed;\n inset: 0;\n background: var(--mj-bg-overlay);\n z-index: 10000;\n display: flex;\n align-items: center;\n justify-content: center;\n animation: rc-fadeIn 0.15s ease;\n}\n\n.rc-restore-preview-panel {\n background: var(--mj-bg-surface);\n border-radius: 12px;\n box-shadow: var(--mj-shadow-lg);\n width: 90%;\n max-width: 700px;\n max-height: 80vh;\n overflow-y: auto;\n padding: 0;\n animation: rc-slideUp 0.2s ease;\n}\n\n.rc-restore-preview-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 16px 20px;\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.rc-restore-preview-title {\n display: flex;\n align-items: center;\n gap: 8px;\n font-size: 16px;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.rc-restore-preview-title i {\n color: var(--mj-brand-primary);\n}\n\n.rc-restore-preview-close {\n background: none;\n border: none;\n color: var(--mj-text-muted);\n cursor: pointer;\n padding: 4px 8px;\n border-radius: 4px;\n font-size: 16px;\n transition: color 0.15s, background 0.15s;\n}\n\n.rc-restore-preview-close:hover {\n color: var(--mj-text-primary);\n background: var(--mj-bg-surface-hover);\n}\n\n.rc-restore-preview-meta {\n display: flex;\n gap: 20px;\n padding: 12px 20px;\n font-size: 13px;\n color: var(--mj-text-secondary);\n background: var(--mj-bg-surface-card);\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.rc-restore-preview-empty {\n padding: 24px 20px;\n text-align: center;\n color: var(--mj-text-muted);\n font-size: 13px;\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 8px;\n}\n\n.rc-restore-preview-empty i {\n color: var(--mj-text-disabled);\n}\n\n/* Restore Preview Table */\n.rc-restore-preview-table {\n width: 100%;\n border-collapse: collapse;\n font-size: 13px;\n}\n\n.rc-restore-preview-table th {\n text-align: left;\n padding: 10px 16px;\n font-weight: 600;\n font-size: 11px;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n color: var(--mj-text-muted);\n background: var(--mj-bg-surface-sunken);\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.rc-restore-preview-table td {\n padding: 10px 16px;\n border-bottom: 1px solid var(--mj-border-default);\n vertical-align: top;\n}\n\n.rc-restore-preview-table tr:last-child td {\n border-bottom: none;\n}\n\n.rc-restore-preview-table tr.rc-diff-changed {\n background: color-mix(in srgb, var(--mj-status-warning) 5%, var(--mj-bg-surface));\n}\n\n.rc-restore-preview-table tr.rc-diff-unchanged {\n opacity: 0.6;\n}\n\n.rc-restore-field-name {\n font-weight: 600;\n color: var(--mj-text-primary);\n white-space: nowrap;\n}\n\n.rc-restore-current {\n font-family: 'SFMono-Regular', 'Consolas', 'Liberation Mono', 'Menlo', monospace;\n color: var(--mj-text-secondary);\n max-width: 200px;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.rc-restore-version {\n font-family: 'SFMono-Regular', 'Consolas', 'Liberation Mono', 'Menlo', monospace;\n color: var(--mj-text-primary);\n font-weight: 500;\n max-width: 200px;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.rc-restore-indicator {\n text-align: center;\n width: 30px;\n}\n\n.rc-diff-changed .rc-restore-indicator i {\n color: var(--mj-status-warning);\n}\n\n.rc-diff-unchanged .rc-restore-indicator i {\n color: var(--mj-status-success);\n font-size: 12px;\n}\n\n/* Restore Preview Actions */\n.rc-restore-preview-actions {\n display: flex;\n gap: 10px;\n padding: 16px 20px;\n border-top: 1px solid var(--mj-border-default);\n}\n\n.rc-restore-confirm-btn {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 8px 18px;\n font-size: 13px;\n font-weight: 600;\n color: var(--mj-text-inverse);\n background: var(--mj-brand-primary);\n border: none;\n border-radius: 8px;\n cursor: pointer;\n transition: background 0.15s, box-shadow 0.15s;\n font-family: inherit;\n}\n\n.rc-restore-confirm-btn:hover:not(:disabled) {\n background: var(--mj-brand-primary-hover);\n box-shadow: 0 2px 8px color-mix(in srgb, var(--mj-brand-primary) 25%, transparent);\n}\n\n.rc-restore-confirm-btn:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.rc-restore-cancel-btn {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 8px 18px;\n font-size: 13px;\n font-weight: 500;\n color: var(--mj-text-secondary);\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n cursor: pointer;\n transition: all 0.15s;\n font-family: inherit;\n}\n\n.rc-restore-cancel-btn:hover:not(:disabled) {\n border-color: var(--mj-border-strong);\n color: var(--mj-text-primary);\n}\n\n.rc-restore-cancel-btn:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n/* \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n * Restore lineage + conditional filter chips + overflow popover\n * (added with the Restore Prior Version feature)\n * \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n/* \u2500\u2500\u2500 Filter pill enhancements \u2500\u2500\u2500 */\n\n.rc-filter-pill-count {\n margin-left: 4px;\n background: color-mix(in srgb, currentColor 12%, transparent);\n padding: 1px 6px;\n border-radius: 10px;\n font-size: 10px;\n font-weight: 700;\n}\n\n.rc-filter-pill.active .rc-filter-pill-count {\n background: color-mix(in srgb, var(--mj-text-inverse, #fff) 22%, transparent);\n}\n\n/* Restore-variant pill: violet treatment to set it apart from type pills */\n.rc-filter-pill-restore {\n background: color-mix(in srgb, var(--mj-status-info) 8%, var(--mj-bg-surface));\n color: color-mix(in srgb, var(--mj-status-info) 80%, var(--mj-text-secondary));\n border-color: color-mix(in srgb, var(--mj-status-info) 30%, var(--mj-border-default));\n}\n.rc-filter-pill-restore:hover {\n border-color: var(--mj-status-info);\n color: var(--mj-status-info);\n}\n.rc-filter-pill-restore.active {\n background: var(--mj-status-info);\n color: var(--mj-text-inverse, #fff);\n border-color: var(--mj-status-info);\n}\n\n/* \u2500\u2500\u2500 Overflow filter popover \u2500\u2500\u2500 */\n\n.rc-filter-overflow-wrap {\n position: relative;\n display: inline-block;\n}\n\n.rc-filter-pill-overflow {\n /* Overflow trigger inherits the standard filter pill look */\n}\n\n.rc-filter-overflow-caret {\n font-size: 9px;\n margin-left: 2px;\n}\n\n.rc-filter-overflow-backdrop {\n position: fixed;\n inset: 0;\n z-index: 10;\n}\n\n.rc-filter-overflow-popover {\n position: absolute;\n top: calc(100% + 6px);\n left: 0;\n z-index: 11;\n min-width: 240px;\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: 10px;\n box-shadow: 0 14px 40px rgba(15, 23, 42, 0.18);\n padding: 8px;\n}\n\n.rc-filter-overflow-header {\n font-size: 11px;\n text-transform: uppercase;\n letter-spacing: 0.06em;\n color: var(--mj-text-muted);\n font-weight: 600;\n padding: 6px 8px 8px;\n}\n\n.rc-filter-overflow-row {\n display: flex;\n align-items: center;\n gap: 9px;\n padding: 7px 8px;\n border-radius: 6px;\n font-size: 13px;\n color: var(--mj-text-primary);\n cursor: pointer;\n}\n\n.rc-filter-overflow-row:hover {\n background: var(--mj-bg-surface-hover);\n}\n\n.rc-filter-overflow-row input[type=\"checkbox\"] {\n margin: 0;\n accent-color: var(--mj-brand-primary);\n}\n\n.rc-filter-overflow-row i {\n color: var(--mj-text-muted);\n font-size: 12px;\n width: 14px;\n text-align: center;\n}\n\n.rc-filter-overflow-row-restore i {\n color: var(--mj-status-info);\n}\n\n.rc-filter-overflow-label {\n flex: 1;\n}\n\n.rc-filter-overflow-count {\n color: var(--mj-text-muted);\n font-size: 11px;\n font-weight: 500;\n}\n\n.rc-filter-overflow-actions {\n display: flex;\n justify-content: space-between;\n border-top: 1px solid var(--mj-border-subtle);\n padding-top: 8px;\n margin-top: 6px;\n}\n\n.rc-filter-overflow-clear,\n.rc-filter-overflow-done {\n background: none;\n border: none;\n font-size: 12px;\n font-weight: 500;\n cursor: pointer;\n padding: 4px 10px;\n border-radius: 5px;\n}\n\n.rc-filter-overflow-clear {\n color: var(--mj-text-muted);\n}\n.rc-filter-overflow-clear:hover {\n background: var(--mj-bg-surface-hover);\n color: var(--mj-text-primary);\n}\n\n.rc-filter-overflow-done {\n color: var(--mj-brand-primary);\n}\n.rc-filter-overflow-done:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 8%, transparent);\n}\n\n/* \u2500\u2500\u2500 Snapshot type badge + card accent \u2500\u2500\u2500 */\n\n.type-snapshot .rc-card-type-badge {\n background: color-mix(in srgb, var(--mj-text-muted) 15%, var(--mj-bg-surface));\n color: var(--mj-text-secondary);\n}\n\n/* \u2500\u2500\u2500 Restore Source pill (in card meta) \u2500\u2500\u2500 */\n\n.source-restore {\n background: color-mix(in srgb, var(--mj-status-info) 12%, var(--mj-bg-surface));\n color: var(--mj-status-info);\n}\n\n/* \u2500\u2500\u2500 Restore card variant: violet left accent \u2500\u2500\u2500 */\n\n.rc-card.rc-card-restore {\n border-left: 3px solid var(--mj-status-info);\n}\n\n/* \u2500\u2500\u2500 Lineage chip \u2500\u2500\u2500 */\n\n/* Lineage chip \u2014 outline-only \"interactive link\" treatment so it reads as\n distinct from the filled RESTORE badge sitting next to it. The badge says\n \"this row IS a restore\" (filled, static); the chip says \"click here to\n see the source version\" (outline, hoverable). */\n.rc-restored-chip {\n display: inline-flex;\n align-items: center;\n gap: 5px;\n margin-left: 8px;\n padding: 2px 9px;\n border-radius: 11px;\n font-size: 11px;\n font-weight: 500;\n background: transparent;\n color: color-mix(in srgb, var(--mj-status-info) 90%, var(--mj-text-primary));\n border: 1px solid color-mix(in srgb, var(--mj-status-info) 40%, var(--mj-border-default));\n cursor: pointer;\n text-decoration: none;\n white-space: nowrap;\n transition: background-color 0.12s, border-color 0.12s, color 0.12s;\n}\n\n.rc-restored-chip:hover {\n background: color-mix(in srgb, var(--mj-status-info) 12%, transparent);\n border-color: var(--mj-status-info);\n color: var(--mj-status-info);\n}\n\n.rc-restored-chip i {\n font-size: 10px;\n}\n\n.rc-restored-chip-orphan {\n cursor: default;\n background: var(--mj-bg-surface-card);\n color: var(--mj-text-muted);\n border-color: var(--mj-border-default);\n}\n\n.rc-restored-chip-orphan:hover {\n background: var(--mj-bg-surface-card);\n border-color: var(--mj-border-default);\n}\n\n/* \u2500\u2500\u2500 Card highlight (when jumped-to via lineage chip) \u2500\u2500\u2500 */\n\n.rc-card.rc-card-highlight {\n outline: 2px solid var(--mj-brand-primary);\n outline-offset: 2px;\n animation: rc-card-pulse 1.4s ease-in-out;\n}\n\n@keyframes rc-card-pulse {\n 0%, 100% { background: var(--mj-bg-surface); }\n 50% { background: color-mix(in srgb, var(--mj-brand-primary) 8%, var(--mj-bg-surface)); }\n}\n\n/* \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n * Restore-row badge override + Restore Reason block\n * (mockup-aligned treatment for restore rows in the timeline)\n * \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n/* The base type-update badge styling would otherwise paint a restore row's\n badge blue with \"Update\" text. Override to violet + \"Restore\" text so it\n matches the source pill, lineage chip, and card border. */\n.rc-card-type-badge.rc-card-type-badge-restore {\n background: color-mix(in srgb, var(--mj-status-info) 14%, var(--mj-bg-surface));\n color: var(--mj-status-info);\n}\n\n/* Restore reason \u2014 minimal blockquote treatment.\n A thin violet left bar + italic text reads like a margin note rather than\n a heavy callout. Visually connected to the restore family (left bar uses\n the same violet as the badge / source pill / card border) without\n competing with the field-diff rows that follow. */\n.rc-restore-reason {\n /* Indented in from the card body edge so it visually nests one level\n deeper than the field-diff rows that follow, and given generous\n vertical breathing room so it doesn't crowd the lineage chip above\n or the first field row below. */\n margin: 14px 8px 18px 18px;\n padding: 0 0 0 12px;\n border-left: 2px solid color-mix(in srgb, var(--mj-status-info) 55%, var(--mj-border-default));\n display: flex;\n align-items: baseline;\n gap: 8px;\n font-size: 13px;\n line-height: 1.5;\n}\n\n.rc-restore-reason-label {\n flex-shrink: 0;\n font-size: 11px;\n font-weight: 600;\n color: color-mix(in srgb, var(--mj-status-info) 75%, var(--mj-text-muted));\n text-transform: uppercase;\n letter-spacing: 0.04em;\n}\n\n.rc-restore-reason-text {\n color: var(--mj-text-secondary);\n font-style: italic;\n}\n"] }]
1204
1433
  }], () => [{ type: i0.ChangeDetectorRef }, { type: i0.NgZone }, { type: i1.MJNotificationService }, { type: i2.DomSanitizer }], { dialogClosed: [{
1205
1434
  type: Output
1206
1435
  }], record: [{
@@ -1210,5 +1439,5 @@ export class RecordChangesComponent {
1210
1439
  }], RestoreRequested: [{
1211
1440
  type: Output
1212
1441
  }] }); })();
1213
- (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(RecordChangesComponent, { className: "RecordChangesComponent", filePath: "src/lib/ng-record-changes.component.ts", lineNumber: 67 }); })();
1442
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(RecordChangesComponent, { className: "RecordChangesComponent", filePath: "src/lib/ng-record-changes.component.ts", lineNumber: 120 }); })();
1214
1443
  //# sourceMappingURL=ng-record-changes.component.js.map