@uptime.link/statuspage 1.1.0 → 1.2.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.
Files changed (28) hide show
  1. package/dist_bundle/bundle.js +1823 -915
  2. package/dist_bundle/bundle.js.map +3 -3
  3. package/dist_ts_web/00_commitinfo_data.js +1 -1
  4. package/dist_ts_web/elements/upl-statuspage-assetsselector.js +119 -45
  5. package/dist_ts_web/elements/upl-statuspage-footer.js +81 -27
  6. package/dist_ts_web/elements/upl-statuspage-header.js +79 -19
  7. package/dist_ts_web/elements/upl-statuspage-incidents.js +242 -55
  8. package/dist_ts_web/elements/upl-statuspage-statsgrid.js +225 -50
  9. package/dist_ts_web/elements/upl-statuspage-statusbar.js +58 -7
  10. package/dist_ts_web/elements/upl-statuspage-statusdetails.js +36 -11
  11. package/dist_ts_web/elements/upl-statuspage-statusmonth.d.ts +2 -0
  12. package/dist_ts_web/elements/upl-statuspage-statusmonth.js +415 -230
  13. package/dist_ts_web/styles/shared.styles.d.ts +22 -0
  14. package/dist_ts_web/styles/shared.styles.js +146 -3
  15. package/dist_watch/bundle.js +1417 -444
  16. package/dist_watch/bundle.js.map +3 -3
  17. package/dist_watch/index.html +1 -0
  18. package/package.json +1 -1
  19. package/ts_web/00_commitinfo_data.ts +1 -1
  20. package/ts_web/elements/upl-statuspage-assetsselector.ts +118 -44
  21. package/ts_web/elements/upl-statuspage-footer.ts +80 -26
  22. package/ts_web/elements/upl-statuspage-header.ts +87 -18
  23. package/ts_web/elements/upl-statuspage-incidents.ts +247 -56
  24. package/ts_web/elements/upl-statuspage-statsgrid.ts +224 -52
  25. package/ts_web/elements/upl-statuspage-statusbar.ts +57 -6
  26. package/ts_web/elements/upl-statuspage-statusdetails.ts +35 -10
  27. package/ts_web/elements/upl-statuspage-statusmonth.ts +436 -252
  28. package/ts_web/styles/shared.styles.ts +166 -2
@@ -108,36 +108,79 @@ export class UplStatuspageIncidents extends DeesElement {
108
108
  background: ${sharedStyles.colors.background.card};
109
109
  padding: ${unsafeCSS(sharedStyles.spacing.xl)};
110
110
  margin-bottom: ${unsafeCSS(sharedStyles.spacing.lg)};
111
- border-radius: ${unsafeCSS(sharedStyles.borderRadius.md)};
111
+ border-radius: ${unsafeCSS(sharedStyles.borderRadius.lg)};
112
112
  border: 1px solid ${sharedStyles.colors.border.default};
113
113
  text-align: center;
114
114
  color: ${sharedStyles.colors.text.secondary};
115
115
  box-shadow: ${unsafeCSS(sharedStyles.shadows.sm)};
116
+ animation: fadeInUp 0.4s ${unsafeCSS(sharedStyles.easings.default)} both;
116
117
  }
117
118
 
119
+ /* Staggered entrance animations */
118
120
  .incident-card {
119
121
  background: ${sharedStyles.colors.background.card};
120
- border-radius: ${unsafeCSS(sharedStyles.borderRadius.md)};
122
+ border-radius: ${unsafeCSS(sharedStyles.borderRadius.lg)};
121
123
  margin-bottom: ${unsafeCSS(sharedStyles.spacing.lg)};
122
124
  overflow: hidden;
123
125
  box-shadow: ${unsafeCSS(sharedStyles.shadows.sm)};
124
126
  border: 1px solid ${sharedStyles.colors.border.default};
125
- transition: all 0.2s ease;
127
+ transition: all ${unsafeCSS(sharedStyles.durations.normal)} ${unsafeCSS(sharedStyles.easings.default)};
128
+ animation: fadeInUp 0.4s ${unsafeCSS(sharedStyles.easings.default)} both;
126
129
  }
127
130
 
128
- .incident-card.expanded {
131
+ .incident-card:nth-child(1) { animation-delay: 0ms; }
132
+ .incident-card:nth-child(2) { animation-delay: 50ms; }
133
+ .incident-card:nth-child(3) { animation-delay: 100ms; }
134
+ .incident-card:nth-child(4) { animation-delay: 150ms; }
135
+ .incident-card:nth-child(5) { animation-delay: 200ms; }
136
+
137
+ .incident-card:hover {
138
+ transform: translateY(-2px);
129
139
  box-shadow: ${unsafeCSS(sharedStyles.shadows.md)};
140
+ border-color: ${sharedStyles.colors.border.muted};
141
+ }
142
+
143
+ .incident-card.expanded {
144
+ box-shadow: ${unsafeCSS(sharedStyles.shadows.lg)};
145
+ }
146
+
147
+ /* Active incident pulse effect */
148
+ .incident-card.active-incident {
149
+ animation: fadeInUp 0.4s ${unsafeCSS(sharedStyles.easings.default)} both,
150
+ incident-pulse 3s ease-in-out infinite;
151
+ }
152
+
153
+ @keyframes fadeInUp {
154
+ from {
155
+ opacity: 0;
156
+ transform: translateY(16px);
157
+ }
158
+ to {
159
+ opacity: 1;
160
+ transform: translateY(0);
161
+ }
162
+ }
163
+
164
+ @keyframes incident-pulse {
165
+ 0%, 100% {
166
+ box-shadow: ${unsafeCSS(sharedStyles.shadows.sm)};
167
+ }
168
+ 50% {
169
+ box-shadow: ${unsafeCSS(sharedStyles.shadows.md)},
170
+ 0 0 0 2px ${cssManager.bdTheme('rgba(239, 68, 68, 0.15)', 'rgba(248, 113, 113, 0.2)')};
171
+ }
130
172
  }
131
173
 
132
174
  .incident-header {
133
- padding: ${unsafeCSS(sharedStyles.spacing.lg)} ${unsafeCSS(sharedStyles.spacing.lg)};
175
+ padding: ${unsafeCSS(sharedStyles.spacing.lg)} ${unsafeCSS(sharedStyles.spacing.xl)};
134
176
  border-left: 4px solid;
135
177
  display: flex;
136
178
  align-items: start;
137
179
  justify-content: space-between;
138
180
  gap: ${unsafeCSS(sharedStyles.spacing.md)};
139
181
  cursor: pointer;
140
- transition: background-color 0.2s ease;
182
+ transition: background-color ${unsafeCSS(sharedStyles.durations.fast)} ${unsafeCSS(sharedStyles.easings.default)};
183
+ position: relative;
141
184
  }
142
185
 
143
186
  .incident-header:hover {
@@ -161,10 +204,11 @@ export class UplStatuspageIncidents extends DeesElement {
161
204
  }
162
205
 
163
206
  .incident-title {
164
- font-size: 18px;
207
+ font-size: 17px;
165
208
  font-weight: 600;
166
209
  margin: 0;
167
- line-height: 1.3;
210
+ line-height: 1.4;
211
+ letter-spacing: -0.01em;
168
212
  }
169
213
 
170
214
  .incident-meta {
@@ -176,17 +220,24 @@ export class UplStatuspageIncidents extends DeesElement {
176
220
  flex-wrap: wrap;
177
221
  }
178
222
 
223
+ .incident-meta span {
224
+ display: flex;
225
+ align-items: center;
226
+ gap: 4px;
227
+ }
228
+
179
229
  .incident-status {
180
230
  display: inline-flex;
181
231
  align-items: center;
182
- gap: ${unsafeCSS(sharedStyles.spacing.xs)};
183
- padding: ${unsafeCSS(sharedStyles.spacing.xs)} ${unsafeCSS(sharedStyles.spacing.md)};
232
+ gap: 6px;
233
+ padding: 6px 12px;
184
234
  border-radius: ${unsafeCSS(sharedStyles.borderRadius.full)};
185
- font-size: 12px;
235
+ font-size: 11px;
186
236
  font-weight: 600;
187
237
  text-transform: uppercase;
188
- letter-spacing: 0.02em;
238
+ letter-spacing: 0.04em;
189
239
  flex-shrink: 0;
240
+ transition: all ${unsafeCSS(sharedStyles.durations.fast)} ${unsafeCSS(sharedStyles.easings.default)};
190
241
  }
191
242
 
192
243
  .incident-status.investigating {
@@ -214,68 +265,164 @@ export class UplStatuspageIncidents extends DeesElement {
214
265
  color: ${cssManager.bdTheme('#4b5563', '#d1d5db')};
215
266
  }
216
267
 
268
+ /* Pulse for investigating status */
269
+ .incident-status.investigating .status-dot {
270
+ animation: status-pulse 1.5s ease-in-out infinite;
271
+ }
272
+
273
+ @keyframes status-pulse {
274
+ 0%, 100% { opacity: 1; transform: scale(1); }
275
+ 50% { opacity: 0.6; transform: scale(1.2); }
276
+ }
277
+
217
278
  .incident-body {
218
- padding: 0 ${unsafeCSS(sharedStyles.spacing.lg)} ${unsafeCSS(sharedStyles.spacing.lg)} ${unsafeCSS(sharedStyles.spacing.lg)};
279
+ padding: 0 ${unsafeCSS(sharedStyles.spacing.xl)} ${unsafeCSS(sharedStyles.spacing.xl)} ${unsafeCSS(sharedStyles.spacing.xl)};
280
+ animation: slideDown 0.3s ${unsafeCSS(sharedStyles.easings.default)};
281
+ }
282
+
283
+ @keyframes slideDown {
284
+ from {
285
+ opacity: 0;
286
+ transform: translateY(-8px);
287
+ }
288
+ to {
289
+ opacity: 1;
290
+ transform: translateY(0);
291
+ }
219
292
  }
220
293
 
221
294
  .incident-impact {
222
295
  margin: ${unsafeCSS(sharedStyles.spacing.md)} 0;
223
- padding: ${unsafeCSS(sharedStyles.spacing.md)};
296
+ padding: ${unsafeCSS(sharedStyles.spacing.md)} ${unsafeCSS(sharedStyles.spacing.lg)};
224
297
  background: ${sharedStyles.colors.background.secondary};
225
298
  border-radius: ${unsafeCSS(sharedStyles.borderRadius.base)};
226
299
  font-size: 14px;
227
300
  line-height: 1.6;
301
+ border-left: 3px solid ${sharedStyles.colors.border.muted};
228
302
  }
229
303
 
230
304
  .affected-services {
231
- margin-top: ${unsafeCSS(sharedStyles.spacing.md)};
305
+ margin-top: ${unsafeCSS(sharedStyles.spacing.lg)};
232
306
  }
233
307
 
234
308
  .affected-services-title {
235
- font-size: 13px;
309
+ font-size: 12px;
236
310
  font-weight: 600;
237
311
  margin-bottom: ${unsafeCSS(sharedStyles.spacing.sm)};
238
- color: ${sharedStyles.colors.text.primary};
312
+ color: ${sharedStyles.colors.text.secondary};
313
+ text-transform: uppercase;
314
+ letter-spacing: 0.04em;
239
315
  }
240
316
 
241
317
  .service-tag {
242
318
  display: inline-block;
243
- padding: ${unsafeCSS(sharedStyles.spacing.xs)} ${unsafeCSS(sharedStyles.spacing.sm)};
319
+ padding: 4px 10px;
244
320
  margin: 2px;
245
321
  background: ${sharedStyles.colors.background.muted};
246
322
  border-radius: ${unsafeCSS(sharedStyles.borderRadius.sm)};
247
323
  font-size: 12px;
248
324
  color: ${sharedStyles.colors.text.secondary};
325
+ transition: all ${unsafeCSS(sharedStyles.durations.fast)} ${unsafeCSS(sharedStyles.easings.default)};
249
326
  }
250
327
 
328
+ .service-tag:hover {
329
+ background: ${sharedStyles.colors.background.secondary};
330
+ color: ${sharedStyles.colors.text.primary};
331
+ }
332
+
333
+ /* Timeline visualization for updates */
251
334
  .incident-updates {
252
- margin-top: ${unsafeCSS(sharedStyles.spacing.lg)};
335
+ margin-top: ${unsafeCSS(sharedStyles.spacing.xl)};
253
336
  border-top: 1px solid ${sharedStyles.colors.border.default};
254
337
  padding-top: ${unsafeCSS(sharedStyles.spacing.lg)};
255
338
  }
256
339
 
340
+ .updates-title {
341
+ font-size: 12px;
342
+ font-weight: 600;
343
+ text-transform: uppercase;
344
+ letter-spacing: 0.04em;
345
+ margin: 0 0 ${unsafeCSS(sharedStyles.spacing.lg)} 0;
346
+ color: ${sharedStyles.colors.text.secondary};
347
+ }
348
+
349
+ .timeline {
350
+ position: relative;
351
+ padding-left: 24px;
352
+ }
353
+
354
+ /* Vertical connector line */
355
+ .timeline::before {
356
+ content: '';
357
+ position: absolute;
358
+ left: 5px;
359
+ top: 8px;
360
+ bottom: 8px;
361
+ width: 2px;
362
+ background: ${cssManager.bdTheme(
363
+ 'linear-gradient(to bottom, #e5e7eb 0%, #d1d5db 50%, #e5e7eb 100%)',
364
+ 'linear-gradient(to bottom, #27272a 0%, #3f3f46 50%, #27272a 100%)'
365
+ )};
366
+ border-radius: 1px;
367
+ }
368
+
257
369
  .update-item {
258
370
  position: relative;
259
371
  padding-left: ${unsafeCSS(sharedStyles.spacing.lg)};
260
- margin-bottom: ${unsafeCSS(sharedStyles.spacing.md)};
372
+ padding-bottom: ${unsafeCSS(sharedStyles.spacing.lg)};
373
+ animation: fadeInUp 0.3s ${unsafeCSS(sharedStyles.easings.default)} both;
374
+ }
375
+
376
+ .update-item:last-child {
377
+ padding-bottom: 0;
261
378
  }
262
379
 
380
+ /* Timeline dot */
263
381
  .update-item::before {
264
382
  content: '';
265
383
  position: absolute;
266
- left: 0;
267
- top: 6px;
268
- width: 8px;
269
- height: 8px;
270
- border-radius: ${unsafeCSS(sharedStyles.borderRadius.full)};
271
- background: ${sharedStyles.colors.border.muted};
384
+ left: -22px;
385
+ top: 4px;
386
+ width: 12px;
387
+ height: 12px;
388
+ border-radius: 50%;
389
+ background: ${sharedStyles.colors.background.card};
390
+ border: 2px solid ${sharedStyles.colors.border.muted};
391
+ z-index: 1;
392
+ transition: all ${unsafeCSS(sharedStyles.durations.fast)} ${unsafeCSS(sharedStyles.easings.default)};
393
+ }
394
+
395
+ .update-item:first-child::before {
396
+ border-color: ${sharedStyles.colors.status.operational};
397
+ background: ${sharedStyles.colors.status.operational};
398
+ box-shadow: 0 0 0 3px ${cssManager.bdTheme('rgba(22, 163, 74, 0.15)', 'rgba(34, 197, 94, 0.2)')};
399
+ }
400
+
401
+ .update-item:hover::before {
402
+ transform: scale(1.2);
403
+ border-color: ${sharedStyles.colors.text.secondary};
272
404
  }
273
405
 
274
406
  .update-time {
275
- font-size: 12px;
276
- color: ${sharedStyles.colors.text.secondary};
277
- margin-bottom: ${unsafeCSS(sharedStyles.spacing.xs)};
407
+ font-size: 11px;
408
+ color: ${sharedStyles.colors.text.muted};
409
+ margin-bottom: 4px;
278
410
  font-family: ${unsafeCSS(sharedStyles.fonts.mono)};
411
+ display: flex;
412
+ align-items: center;
413
+ gap: 8px;
414
+ }
415
+
416
+ .update-status-badge {
417
+ display: inline-flex;
418
+ padding: 2px 6px;
419
+ border-radius: 4px;
420
+ font-size: 10px;
421
+ font-weight: 600;
422
+ text-transform: uppercase;
423
+ letter-spacing: 0.02em;
424
+ background: ${sharedStyles.colors.background.muted};
425
+ color: ${sharedStyles.colors.text.secondary};
279
426
  }
280
427
 
281
428
  .update-message {
@@ -286,9 +433,11 @@ export class UplStatuspageIncidents extends DeesElement {
286
433
 
287
434
  .update-author {
288
435
  font-size: 12px;
289
- color: ${sharedStyles.colors.text.secondary};
290
- margin-top: ${unsafeCSS(sharedStyles.spacing.xs)};
291
- font-style: italic;
436
+ color: ${sharedStyles.colors.text.muted};
437
+ margin-top: 4px;
438
+ display: flex;
439
+ align-items: center;
440
+ gap: 4px;
292
441
  }
293
442
 
294
443
  .loading-skeleton {
@@ -298,33 +447,34 @@ export class UplStatuspageIncidents extends DeesElement {
298
447
  'linear-gradient(90deg, #1f1f1f 25%, #262626 50%, #1f1f1f 75%)'
299
448
  )};
300
449
  background-size: 200% 100%;
301
- animation: loading 1.5s infinite;
302
- border-radius: ${unsafeCSS(sharedStyles.borderRadius.md)};
450
+ animation: shimmer 1.5s infinite;
451
+ border-radius: ${unsafeCSS(sharedStyles.borderRadius.lg)};
303
452
  margin-bottom: ${unsafeCSS(sharedStyles.spacing.lg)};
304
453
  }
305
454
 
306
- @keyframes loading {
455
+ @keyframes shimmer {
307
456
  0% { background-position: 200% 0; }
308
457
  100% { background-position: -200% 0; }
309
458
  }
310
459
 
311
460
  .show-more {
312
461
  text-align: center;
313
- margin-top: ${unsafeCSS(sharedStyles.spacing.lg)};
462
+ margin-top: ${unsafeCSS(sharedStyles.spacing.xl)};
314
463
  }
315
464
 
316
465
  .show-more-button {
317
466
  display: inline-flex;
318
467
  align-items: center;
319
468
  justify-content: center;
320
- padding: ${unsafeCSS(sharedStyles.spacing.sm)} ${unsafeCSS(sharedStyles.spacing.lg)};
469
+ gap: 8px;
470
+ padding: 10px 20px;
321
471
  background: transparent;
322
472
  border: 1px solid ${sharedStyles.colors.border.default};
323
473
  border-radius: ${unsafeCSS(sharedStyles.borderRadius.base)};
324
474
  cursor: pointer;
325
475
  font-size: 14px;
326
476
  font-weight: 500;
327
- transition: all 0.2s ease;
477
+ transition: all ${unsafeCSS(sharedStyles.durations.fast)} ${unsafeCSS(sharedStyles.easings.default)};
328
478
  color: ${sharedStyles.colors.text.primary};
329
479
  font-family: ${unsafeCSS(sharedStyles.fonts.base)};
330
480
  }
@@ -332,7 +482,8 @@ export class UplStatuspageIncidents extends DeesElement {
332
482
  .show-more-button:hover {
333
483
  background: ${sharedStyles.colors.background.secondary};
334
484
  border-color: ${sharedStyles.colors.border.muted};
335
- transform: translateY(-1px);
485
+ transform: translateY(-2px);
486
+ box-shadow: ${unsafeCSS(sharedStyles.shadows.sm)};
336
487
  }
337
488
 
338
489
  .show-more-button:active {
@@ -351,15 +502,15 @@ export class UplStatuspageIncidents extends DeesElement {
351
502
  .subscribe-button {
352
503
  display: inline-flex;
353
504
  align-items: center;
354
- gap: ${unsafeCSS(sharedStyles.spacing.xs)};
355
- padding: ${unsafeCSS(sharedStyles.spacing.xs)} ${unsafeCSS(sharedStyles.spacing.md)};
505
+ gap: 6px;
506
+ padding: 8px 14px;
356
507
  background: transparent;
357
508
  border: 1px solid ${sharedStyles.colors.border.default};
358
509
  border-radius: ${unsafeCSS(sharedStyles.borderRadius.base)};
359
510
  cursor: pointer;
360
511
  font-size: 13px;
361
- font-weight: 400;
362
- transition: all 0.2s ease;
512
+ font-weight: 500;
513
+ transition: all ${unsafeCSS(sharedStyles.durations.fast)} ${unsafeCSS(sharedStyles.easings.default)};
363
514
  color: ${sharedStyles.colors.text.primary};
364
515
  font-family: ${unsafeCSS(sharedStyles.fonts.base)};
365
516
  }
@@ -367,14 +518,15 @@ export class UplStatuspageIncidents extends DeesElement {
367
518
  .subscribe-button:hover {
368
519
  background: ${sharedStyles.colors.background.secondary};
369
520
  border-color: ${sharedStyles.colors.border.muted};
521
+ transform: translateY(-1px);
370
522
  }
371
-
523
+
372
524
  .subscribe-button.subscribed {
373
525
  background: ${cssManager.bdTheme('#f0fdf4', '#064e3b')};
374
526
  border-color: ${cssManager.bdTheme('#86efac', '#047857')};
375
527
  color: ${cssManager.bdTheme('#047857', '#86efac')};
376
528
  }
377
-
529
+
378
530
  .subscribe-button.subscribed:hover {
379
531
  background: ${cssManager.bdTheme('#dcfce7', '#065f46')};
380
532
  }
@@ -387,6 +539,15 @@ export class UplStatuspageIncidents extends DeesElement {
387
539
  opacity: 0.8;
388
540
  }
389
541
 
542
+ /* Expand icon animation */
543
+ .expand-icon {
544
+ transition: transform ${unsafeCSS(sharedStyles.durations.normal)} ${unsafeCSS(sharedStyles.easings.default)};
545
+ }
546
+
547
+ .expand-icon.rotated {
548
+ transform: rotate(180deg);
549
+ }
550
+
390
551
  @media (max-width: 640px) {
391
552
  .container {
392
553
  padding: 0 ${unsafeCSS(sharedStyles.spacing.md)} ${unsafeCSS(sharedStyles.spacing.md)} ${unsafeCSS(sharedStyles.spacing.md)};
@@ -396,10 +557,28 @@ export class UplStatuspageIncidents extends DeesElement {
396
557
  padding: ${unsafeCSS(sharedStyles.spacing.md)};
397
558
  }
398
559
 
560
+ .incident-body {
561
+ padding: 0 ${unsafeCSS(sharedStyles.spacing.md)} ${unsafeCSS(sharedStyles.spacing.md)} ${unsafeCSS(sharedStyles.spacing.md)};
562
+ }
563
+
399
564
  .incident-meta {
400
565
  flex-direction: column;
401
566
  gap: ${unsafeCSS(sharedStyles.spacing.xs)};
402
567
  }
568
+
569
+ .timeline {
570
+ padding-left: 20px;
571
+ }
572
+
573
+ .timeline::before {
574
+ left: 4px;
575
+ }
576
+
577
+ .update-item::before {
578
+ left: -18px;
579
+ width: 10px;
580
+ height: 10px;
581
+ }
403
582
  }
404
583
  `,
405
584
  ];
@@ -438,12 +617,14 @@ export class UplStatuspageIncidents extends DeesElement {
438
617
 
439
618
  private renderIncident(incident: IIncidentDetails, isCurrent: boolean): TemplateResult {
440
619
  const latestUpdate = incident.updates[incident.updates.length - 1];
441
- const duration = incident.endTime ?
620
+ const duration = incident.endTime ?
442
621
  this.formatDuration(incident.endTime - incident.startTime) :
443
622
  this.formatDuration(Date.now() - incident.startTime);
444
-
623
+
624
+ const isActive = isCurrent && latestUpdate?.status !== 'resolved';
625
+
445
626
  return html`
446
- <div class="incident-card ${this.expandedIncidents.has(incident.id) ? 'expanded' : ''}">
627
+ <div class="incident-card ${this.expandedIncidents.has(incident.id) ? 'expanded' : ''} ${isActive ? 'active-incident' : ''}">
447
628
  <div class="incident-header ${incident.severity}" @click=${() => this.toggleIncident(incident.id)}>
448
629
  <div>
449
630
  <h3 class="incident-title">${incident.title}</h3>
@@ -520,8 +701,10 @@ export class UplStatuspageIncidents extends DeesElement {
520
701
 
521
702
  ${incident.updates.length > 0 ? html`
522
703
  <div class="incident-updates">
523
- <h4 style="font-size: 14px; margin: 0 0 12px 0;">Updates</h4>
524
- ${incident.updates.slice(-3).reverse().map(update => this.renderUpdate(update))}
704
+ <h4 class="updates-title">Updates</h4>
705
+ <div class="timeline">
706
+ ${incident.updates.slice(-3).reverse().map((update, index) => this.renderUpdate(update, index))}
707
+ </div>
525
708
  </div>
526
709
  ` : ''}
527
710
 
@@ -571,25 +754,33 @@ export class UplStatuspageIncidents extends DeesElement {
571
754
  `;
572
755
  }
573
756
 
574
- private renderUpdate(update: any): TemplateResult {
757
+ private renderUpdate(update: any, index: number = 0): TemplateResult {
575
758
  return html`
576
- <div class="update-item">
577
- <div class="update-time">${this.formatDate(update.timestamp)}</div>
759
+ <div class="update-item" style="animation-delay: ${index * 50}ms">
760
+ <div class="update-time">
761
+ ${this.formatDate(update.timestamp)}
762
+ ${update.status ? html`<span class="update-status-badge">${update.status}</span>` : ''}
763
+ </div>
578
764
  <div class="update-message">${update.message}</div>
579
765
  ${update.author ? html`
580
- <div class="update-author">— ${update.author}</div>
766
+ <div class="update-author">
767
+ <svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
768
+ <path d="M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2"></path>
769
+ <circle cx="12" cy="7" r="4"></circle>
770
+ </svg>
771
+ ${update.author}
772
+ </div>
581
773
  ` : ''}
582
774
  </div>
583
775
  `;
584
776
  }
585
777
 
586
778
  private getStatusIcon(status: string): TemplateResult {
587
- return html`<span style="
779
+ return html`<span class="status-dot" style="
588
780
  display: inline-block;
589
781
  width: 6px;
590
782
  height: 6px;
591
783
  border-radius: 50%;
592
- margin-right: 4px;
593
784
  background: ${status === 'resolved' ? sharedStyles.colors.status.operational :
594
785
  status === 'monitoring' ? sharedStyles.colors.status.maintenance :
595
786
  status === 'identified' ? sharedStyles.colors.status.degraded :