@uptime.link/statuspage 1.1.0 → 1.3.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 (29) hide show
  1. package/dist_bundle/bundle.js +1814 -917
  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.d.ts +3 -0
  9. package/dist_ts_web/elements/upl-statuspage-statsgrid.js +239 -52
  10. package/dist_ts_web/elements/upl-statuspage-statusbar.js +58 -7
  11. package/dist_ts_web/elements/upl-statuspage-statusdetails.js +36 -11
  12. package/dist_ts_web/elements/upl-statuspage-statusmonth.d.ts +2 -0
  13. package/dist_ts_web/elements/upl-statuspage-statusmonth.js +415 -230
  14. package/dist_ts_web/styles/shared.styles.d.ts +22 -0
  15. package/dist_ts_web/styles/shared.styles.js +146 -3
  16. package/dist_watch/bundle.js +1425 -446
  17. package/dist_watch/bundle.js.map +3 -3
  18. package/dist_watch/index.html +1 -0
  19. package/package.json +1 -1
  20. package/ts_web/00_commitinfo_data.ts +1 -1
  21. package/ts_web/elements/upl-statuspage-assetsselector.ts +118 -44
  22. package/ts_web/elements/upl-statuspage-footer.ts +80 -26
  23. package/ts_web/elements/upl-statuspage-header.ts +87 -18
  24. package/ts_web/elements/upl-statuspage-incidents.ts +248 -56
  25. package/ts_web/elements/upl-statuspage-statsgrid.ts +235 -55
  26. package/ts_web/elements/upl-statuspage-statusbar.ts +57 -6
  27. package/ts_web/elements/upl-statuspage-statusdetails.ts +35 -10
  28. package/ts_web/elements/upl-statuspage-statusmonth.ts +436 -252
  29. package/ts_web/styles/shared.styles.ts +166 -2
@@ -76,66 +76,159 @@ export class UplStatuspageStatsgrid extends DeesElement {
76
76
  }
77
77
 
78
78
  .stat-card {
79
- background: ${cssManager.bdTheme('#ffffff', '#0a0a0a')};
80
- border: 1px solid ${cssManager.bdTheme('#e5e7eb', '#27272a')};
81
- border-radius: ${unsafeCSS(sharedStyles.borderRadius.base)};
79
+ background: ${sharedStyles.colors.background.card};
80
+ border: 1px solid ${sharedStyles.colors.border.default};
81
+ border-radius: ${unsafeCSS(sharedStyles.borderRadius.lg)};
82
82
  padding: ${unsafeCSS(sharedStyles.spacing.lg)};
83
- transition: all 0.2s ease;
83
+ transition: all ${unsafeCSS(sharedStyles.durations.normal)} ${unsafeCSS(sharedStyles.easings.default)};
84
+ position: relative;
85
+ overflow: hidden;
86
+ animation: fadeInUp 0.4s ${unsafeCSS(sharedStyles.easings.default)} both;
87
+ }
88
+
89
+ .stat-card:nth-child(1) { animation-delay: 0ms; }
90
+ .stat-card:nth-child(2) { animation-delay: 50ms; }
91
+ .stat-card:nth-child(3) { animation-delay: 100ms; }
92
+ .stat-card:nth-child(4) { animation-delay: 150ms; }
93
+
94
+ @keyframes fadeInUp {
95
+ from {
96
+ opacity: 0;
97
+ transform: translateY(12px);
98
+ }
99
+ to {
100
+ opacity: 1;
101
+ transform: translateY(0);
102
+ }
103
+ }
104
+
105
+ /* Status-colored top accent */
106
+ .stat-card::before {
107
+ content: '';
108
+ position: absolute;
109
+ top: 0;
110
+ left: 0;
111
+ right: 0;
112
+ height: 3px;
113
+ background: ${sharedStyles.colors.border.muted};
114
+ transition: all ${unsafeCSS(sharedStyles.durations.fast)} ${unsafeCSS(sharedStyles.easings.default)};
115
+ }
116
+
117
+ /* Dynamic status-based accent colors for all stat cards */
118
+ .stat-card.operational::before {
119
+ background: ${sharedStyles.colors.status.operational};
120
+ }
121
+
122
+ .stat-card.degraded::before {
123
+ background: ${sharedStyles.colors.status.degraded};
124
+ }
125
+
126
+ .stat-card.partial_outage::before {
127
+ background: ${sharedStyles.colors.status.partial};
128
+ }
129
+
130
+ .stat-card.major_outage::before {
131
+ background: ${sharedStyles.colors.status.major};
132
+ }
133
+
134
+ .stat-card.maintenance::before {
135
+ background: ${sharedStyles.colors.status.maintenance};
84
136
  }
85
137
 
86
138
  .stat-card:hover {
87
- border-color: ${cssManager.bdTheme('#d1d5db', '#3f3f46')};
88
- box-shadow: ${cssManager.bdTheme(
89
- '0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06)',
90
- '0 0 0 1px rgba(255, 255, 255, 0.1)'
91
- )};
139
+ border-color: ${sharedStyles.colors.border.muted};
140
+ box-shadow: ${unsafeCSS(sharedStyles.shadows.md)};
141
+ transform: translateY(-3px);
142
+ }
143
+
144
+ .stat-card:hover::before {
145
+ height: 4px;
92
146
  }
93
147
 
94
148
  .stat-label {
95
- font-size: 12px;
96
- color: ${cssManager.bdTheme('#6b7280', '#a1a1aa')};
149
+ font-size: 11px;
150
+ color: ${sharedStyles.colors.text.muted};
97
151
  text-transform: uppercase;
98
- letter-spacing: 0.05em;
99
- font-weight: 500;
152
+ letter-spacing: 0.06em;
153
+ font-weight: 600;
100
154
  margin-bottom: ${unsafeCSS(sharedStyles.spacing.sm)};
101
155
  display: flex;
102
156
  align-items: center;
103
- gap: ${unsafeCSS(sharedStyles.spacing.xs)};
157
+ gap: 6px;
158
+ }
159
+
160
+ .stat-label svg {
161
+ width: 14px;
162
+ height: 14px;
163
+ opacity: 0.7;
104
164
  }
105
165
 
106
166
  .stat-value {
107
- font-size: 24px;
108
- font-weight: 600;
109
- color: ${cssManager.bdTheme('#0a0a0a', '#fafafa')};
167
+ font-size: 28px;
168
+ font-weight: 700;
169
+ color: ${sharedStyles.colors.text.primary};
110
170
  font-variant-numeric: tabular-nums;
111
171
  line-height: 1.2;
172
+ letter-spacing: -0.02em;
173
+ transition: transform ${unsafeCSS(sharedStyles.durations.fast)} ${unsafeCSS(sharedStyles.easings.default)};
174
+ }
175
+
176
+ .stat-card:hover .stat-value {
177
+ transform: scale(1.02);
112
178
  }
113
179
 
114
180
  .stat-unit {
115
- font-size: 14px;
116
- font-weight: 400;
117
- color: ${cssManager.bdTheme('#6b7280', '#a1a1aa')};
118
- margin-left: 4px;
181
+ font-size: 16px;
182
+ font-weight: 500;
183
+ color: ${sharedStyles.colors.text.secondary};
184
+ margin-left: 2px;
119
185
  }
120
186
 
121
187
  .stat-change {
122
188
  font-size: 12px;
123
- margin-top: ${unsafeCSS(sharedStyles.spacing.xs)};
189
+ margin-top: ${unsafeCSS(sharedStyles.spacing.sm)};
124
190
  display: flex;
125
191
  align-items: center;
126
192
  gap: 4px;
193
+ padding: 4px 8px;
194
+ border-radius: ${unsafeCSS(sharedStyles.borderRadius.sm)};
195
+ width: fit-content;
127
196
  }
128
197
 
129
198
  .stat-change.positive {
130
- color: ${cssManager.bdTheme('#10b981', '#10b981')};
199
+ color: ${sharedStyles.colors.status.operational};
200
+ background: ${cssManager.bdTheme('rgba(22, 163, 74, 0.08)', 'rgba(34, 197, 94, 0.12)')};
131
201
  }
132
202
 
133
203
  .stat-change.negative {
134
- color: ${cssManager.bdTheme('#ef4444', '#ef4444')};
204
+ color: ${sharedStyles.colors.status.partial};
205
+ background: ${cssManager.bdTheme('rgba(239, 68, 68, 0.08)', 'rgba(248, 113, 113, 0.12)')};
135
206
  }
136
207
 
137
208
  .stat-change.neutral {
138
- color: ${cssManager.bdTheme('#6b7280', '#a1a1aa')};
209
+ color: ${sharedStyles.colors.text.muted};
210
+ background: ${sharedStyles.colors.background.muted};
211
+ }
212
+
213
+ /* Status text color variations */
214
+ .stat-value.operational {
215
+ color: ${sharedStyles.colors.status.operational};
216
+ }
217
+
218
+ .stat-value.degraded {
219
+ color: ${sharedStyles.colors.status.degraded};
220
+ }
221
+
222
+ .stat-value.partial_outage {
223
+ color: ${sharedStyles.colors.status.partial};
224
+ }
225
+
226
+ .stat-value.major_outage {
227
+ color: ${sharedStyles.colors.status.major};
228
+ }
229
+
230
+ .stat-value.maintenance {
231
+ color: ${sharedStyles.colors.status.maintenance};
139
232
  }
140
233
 
141
234
  .loading-skeleton {
@@ -145,61 +238,102 @@ export class UplStatuspageStatsgrid extends DeesElement {
145
238
  }
146
239
 
147
240
  .skeleton-card {
148
- background: ${cssManager.bdTheme('#ffffff', '#0a0a0a')};
149
- border: 1px solid ${cssManager.bdTheme('#e5e7eb', '#27272a')};
150
- border-radius: ${unsafeCSS(sharedStyles.borderRadius.base)};
241
+ background: ${sharedStyles.colors.background.card};
242
+ border: 1px solid ${sharedStyles.colors.border.default};
243
+ border-radius: ${unsafeCSS(sharedStyles.borderRadius.lg)};
151
244
  padding: ${unsafeCSS(sharedStyles.spacing.lg)};
152
- height: 100px;
245
+ height: 110px;
246
+ position: relative;
247
+ overflow: hidden;
248
+ }
249
+
250
+ .skeleton-card::before {
251
+ content: '';
252
+ position: absolute;
253
+ top: 0;
254
+ left: 0;
255
+ right: 0;
256
+ height: 3px;
257
+ background: ${sharedStyles.colors.background.muted};
153
258
  }
154
259
 
155
260
  .skeleton-label {
156
- height: 14px;
261
+ height: 12px;
157
262
  width: 80px;
158
- background: ${cssManager.bdTheme('#f3f4f6', '#27272a')};
263
+ background: ${sharedStyles.colors.background.muted};
159
264
  border-radius: 4px;
160
265
  margin-bottom: ${unsafeCSS(sharedStyles.spacing.sm)};
161
- animation: pulse 2s infinite;
266
+ animation: shimmer 1.5s infinite;
162
267
  }
163
268
 
164
269
  .skeleton-value {
165
- height: 28px;
166
- width: 120px;
167
- background: ${cssManager.bdTheme('#f3f4f6', '#27272a')};
168
- border-radius: 4px;
169
- animation: pulse 2s infinite;
270
+ height: 32px;
271
+ width: 100px;
272
+ background: ${sharedStyles.colors.background.muted};
273
+ border-radius: 6px;
274
+ animation: shimmer 1.5s infinite;
170
275
  animation-delay: 0.1s;
171
276
  }
172
277
 
173
- @keyframes pulse {
174
- 0%, 100% { opacity: 1; }
175
- 50% { opacity: 0.5; }
278
+ .skeleton-change {
279
+ height: 20px;
280
+ width: 70px;
281
+ background: ${sharedStyles.colors.background.muted};
282
+ border-radius: 4px;
283
+ margin-top: ${unsafeCSS(sharedStyles.spacing.sm)};
284
+ animation: shimmer 1.5s infinite;
285
+ animation-delay: 0.2s;
286
+ }
287
+
288
+ @keyframes shimmer {
289
+ 0% { opacity: 0.5; }
290
+ 50% { opacity: 1; }
291
+ 100% { opacity: 0.5; }
176
292
  }
177
293
 
178
294
  .status-indicator {
179
295
  display: inline-block;
180
- width: 6px;
181
- height: 6px;
296
+ width: 8px;
297
+ height: 8px;
182
298
  border-radius: 50%;
299
+ flex-shrink: 0;
183
300
  }
184
301
 
185
302
  .status-indicator.operational {
186
303
  background: ${sharedStyles.colors.status.operational};
304
+ box-shadow: 0 0 0 2px ${cssManager.bdTheme('rgba(22, 163, 74, 0.2)', 'rgba(34, 197, 94, 0.25)')};
305
+ animation: statusPulse 2s ease-in-out infinite;
306
+ }
307
+
308
+ @keyframes statusPulse {
309
+ 0%, 100% { box-shadow: 0 0 0 2px ${cssManager.bdTheme('rgba(22, 163, 74, 0.2)', 'rgba(34, 197, 94, 0.25)')}; }
310
+ 50% { box-shadow: 0 0 0 4px ${cssManager.bdTheme('rgba(22, 163, 74, 0.1)', 'rgba(34, 197, 94, 0.15)')}; }
187
311
  }
188
312
 
189
313
  .status-indicator.degraded {
190
314
  background: ${sharedStyles.colors.status.degraded};
315
+ box-shadow: 0 0 0 2px ${cssManager.bdTheme('rgba(217, 119, 6, 0.2)', 'rgba(251, 191, 36, 0.25)')};
191
316
  }
192
317
 
193
318
  .status-indicator.partial_outage {
194
319
  background: ${sharedStyles.colors.status.partial};
320
+ box-shadow: 0 0 0 2px ${cssManager.bdTheme('rgba(239, 68, 68, 0.2)', 'rgba(248, 113, 113, 0.25)')};
195
321
  }
196
322
 
197
323
  .status-indicator.major_outage {
198
324
  background: ${sharedStyles.colors.status.major};
325
+ box-shadow: 0 0 0 2px ${cssManager.bdTheme('rgba(185, 28, 28, 0.2)', 'rgba(239, 68, 68, 0.25)')};
326
+ animation: majorPulse 1s ease-in-out infinite;
327
+ }
328
+
329
+ @keyframes majorPulse {
330
+ 0%, 100% { opacity: 1; }
331
+ 50% { opacity: 0.6; }
199
332
  }
200
333
 
201
334
  .status-indicator.maintenance {
202
335
  background: ${sharedStyles.colors.status.maintenance};
336
+ box-shadow: 0 0 0 2px ${cssManager.bdTheme('rgba(37, 99, 235, 0.2)', 'rgba(96, 165, 250, 0.25)')};
203
337
  }
204
338
 
205
339
  @media (max-width: 640px) {
@@ -208,7 +342,7 @@ export class UplStatuspageStatsgrid extends DeesElement {
208
342
  }
209
343
 
210
344
  .stats-grid {
211
- grid-template-columns: 1fr;
345
+ grid-template-columns: repeat(2, 1fr);
212
346
  gap: ${unsafeCSS(sharedStyles.spacing.sm)};
213
347
  }
214
348
 
@@ -217,7 +351,16 @@ export class UplStatuspageStatsgrid extends DeesElement {
217
351
  }
218
352
 
219
353
  .stat-value {
220
- font-size: 20px;
354
+ font-size: 22px;
355
+ }
356
+
357
+ .stat-label {
358
+ font-size: 10px;
359
+ }
360
+
361
+ .stat-label svg {
362
+ width: 12px;
363
+ height: 12px;
221
364
  }
222
365
  }
223
366
  `,
@@ -237,18 +380,23 @@ export class UplStatuspageStatsgrid extends DeesElement {
237
380
  </div>
238
381
  ` : html`
239
382
  <div class="stats-grid">
240
- <div class="stat-card">
383
+ <div class="stat-card ${this.currentStatus}">
241
384
  <div class="stat-label">
242
385
  <span class="status-indicator ${this.currentStatus}"></span>
243
386
  Current Status
244
387
  </div>
245
- <div class="stat-value">
388
+ <div class="stat-value ${this.currentStatus}">
246
389
  ${this.formatStatus(this.currentStatus)}
247
390
  </div>
248
391
  </div>
249
392
 
250
- <div class="stat-card">
251
- <div class="stat-label">Uptime</div>
393
+ <div class="stat-card ${this.getUptimeCardStatus()}">
394
+ <div class="stat-label">
395
+ <svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
396
+ <polyline points="22 12 18 12 15 21 9 3 6 12 2 12"></polyline>
397
+ </svg>
398
+ Uptime
399
+ </div>
252
400
  <div class="stat-value">
253
401
  ${this.uptime.toFixed(2)}<span class="stat-unit">%</span>
254
402
  </div>
@@ -257,21 +405,34 @@ export class UplStatuspageStatsgrid extends DeesElement {
257
405
  </div>
258
406
  </div>
259
407
 
260
- <div class="stat-card">
261
- <div class="stat-label">Avg Response Time</div>
408
+ <div class="stat-card ${this.getResponseCardStatus()}">
409
+ <div class="stat-label">
410
+ <svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
411
+ <circle cx="12" cy="12" r="10"></circle>
412
+ <polyline points="12 6 12 12 16 14"></polyline>
413
+ </svg>
414
+ Avg Response
415
+ </div>
262
416
  <div class="stat-value">
263
417
  ${this.avgResponseTime}<span class="stat-unit">ms</span>
264
418
  </div>
265
419
  ${this.renderResponseChange()}
266
420
  </div>
267
421
 
268
- <div class="stat-card">
269
- <div class="stat-label">Incidents</div>
422
+ <div class="stat-card ${this.getIncidentCardStatus()}">
423
+ <div class="stat-label">
424
+ <svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
425
+ <path d="M10.29 3.86L1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z"></path>
426
+ <line x1="12" y1="9" x2="12" y2="13"></line>
427
+ <line x1="12" y1="17" x2="12.01" y2="17"></line>
428
+ </svg>
429
+ Incidents
430
+ </div>
270
431
  <div class="stat-value">
271
432
  ${this.totalIncidents}
272
433
  </div>
273
- <div class="stat-change neutral">
274
- ${this.affectedServices} of ${this.totalServices} services
434
+ <div class="stat-change ${this.affectedServices === 0 ? 'positive' : 'negative'}">
435
+ ${this.affectedServices === 0 ? 'All services ok.' : `${this.affectedServices} of ${this.totalServices} services affected`}
275
436
  </div>
276
437
  </div>
277
438
  </div>
@@ -295,7 +456,7 @@ export class UplStatuspageStatsgrid extends DeesElement {
295
456
  // This could be enhanced with actual trend data
296
457
  const trend = this.avgResponseTime < 200 ? 'positive' : this.avgResponseTime > 500 ? 'negative' : 'neutral';
297
458
  const icon = trend === 'positive' ? '↓' : trend === 'negative' ? '↑' : '→';
298
-
459
+
299
460
  return html`
300
461
  <div class="stat-change ${trend}">
301
462
  <span>${icon}</span>
@@ -303,4 +464,23 @@ export class UplStatuspageStatsgrid extends DeesElement {
303
464
  </div>
304
465
  `;
305
466
  }
467
+
468
+ private getUptimeCardStatus(): string {
469
+ if (this.uptime >= 99.9) return 'operational';
470
+ if (this.uptime >= 99.0) return 'degraded';
471
+ return 'partial_outage';
472
+ }
473
+
474
+ private getResponseCardStatus(): string {
475
+ if (this.avgResponseTime < 200) return 'operational';
476
+ if (this.avgResponseTime < 500) return 'degraded';
477
+ return 'partial_outage';
478
+ }
479
+
480
+ private getIncidentCardStatus(): string {
481
+ if (this.affectedServices === 0) return 'operational';
482
+ if (this.currentStatus === 'major_outage') return 'major_outage';
483
+ if (this.currentStatus === 'partial_outage') return 'partial_outage';
484
+ return 'degraded';
485
+ }
306
486
  }
@@ -54,22 +54,32 @@ export class UplStatuspageStatusbar extends DeesElement {
54
54
  display: flex;
55
55
  align-items: center;
56
56
  justify-content: space-between;
57
- min-height: 64px;
58
- padding: ${unsafeCSS(sharedStyles.spacing.md)} ${unsafeCSS(sharedStyles.spacing.lg)};
59
- border-radius: ${unsafeCSS(sharedStyles.borderRadius.lg)};
57
+ min-height: 72px;
58
+ padding: ${unsafeCSS(sharedStyles.spacing.lg)} ${unsafeCSS(sharedStyles.spacing.xl)};
59
+ border-radius: ${unsafeCSS(sharedStyles.borderRadius.xl)};
60
60
  cursor: default;
61
- transition: all ${unsafeCSS(sharedStyles.durations.normal)} ${unsafeCSS(sharedStyles.easings.default)};
61
+ transition: all ${unsafeCSS(sharedStyles.durations.slow)} ${unsafeCSS(sharedStyles.easings.default)};
62
62
  position: relative;
63
63
  overflow: hidden;
64
64
  font-weight: 500;
65
65
  font-size: 15px;
66
66
  letter-spacing: -0.01em;
67
- background: ${sharedStyles.colors.background.card};
68
67
  border: 1px solid ${sharedStyles.colors.border.default};
69
68
  box-shadow: ${unsafeCSS(sharedStyles.shadows.sm)};
70
69
  }
71
70
 
71
+ /* Gradient background overlay */
72
72
  .statusbar-inner::before {
73
+ content: '';
74
+ position: absolute;
75
+ inset: 0;
76
+ opacity: 1;
77
+ transition: opacity ${unsafeCSS(sharedStyles.durations.slow)} ${unsafeCSS(sharedStyles.easings.default)};
78
+ z-index: 0;
79
+ }
80
+
81
+ /* Left accent border */
82
+ .statusbar-inner::after {
73
83
  content: '';
74
84
  position: absolute;
75
85
  left: 0;
@@ -77,31 +87,72 @@ export class UplStatuspageStatusbar extends DeesElement {
77
87
  bottom: 0;
78
88
  width: 4px;
79
89
  transition: background ${unsafeCSS(sharedStyles.durations.normal)} ${unsafeCSS(sharedStyles.easings.default)};
90
+ z-index: 1;
80
91
  }
81
92
 
93
+ /* Operational - green gradient */
94
+ .statusbar-inner.operational {
95
+ background: ${sharedStyles.colors.background.card};
96
+ }
82
97
  .statusbar-inner.operational::before {
98
+ background: ${sharedStyles.statusGradients.operational};
99
+ }
100
+ .statusbar-inner.operational::after {
83
101
  background: ${sharedStyles.colors.status.operational};
84
102
  }
85
103
 
104
+ /* Degraded - yellow/amber gradient */
105
+ .statusbar-inner.degraded {
106
+ background: ${sharedStyles.colors.background.card};
107
+ }
86
108
  .statusbar-inner.degraded::before {
109
+ background: ${sharedStyles.statusGradients.degraded};
110
+ }
111
+ .statusbar-inner.degraded::after {
87
112
  background: ${sharedStyles.colors.status.degraded};
88
113
  }
89
114
 
115
+ /* Partial outage - orange/red gradient */
116
+ .statusbar-inner.partial_outage {
117
+ background: ${sharedStyles.colors.background.card};
118
+ }
90
119
  .statusbar-inner.partial_outage::before {
120
+ background: ${sharedStyles.statusGradients.partial};
121
+ }
122
+ .statusbar-inner.partial_outage::after {
91
123
  background: ${sharedStyles.colors.status.partial};
92
124
  }
93
125
 
126
+ /* Major outage - red gradient */
127
+ .statusbar-inner.major_outage {
128
+ background: ${sharedStyles.colors.background.card};
129
+ }
94
130
  .statusbar-inner.major_outage::before {
131
+ background: ${sharedStyles.statusGradients.major};
132
+ }
133
+ .statusbar-inner.major_outage::after {
95
134
  background: ${sharedStyles.colors.status.major};
96
135
  }
97
136
 
137
+ /* Maintenance - blue gradient */
138
+ .statusbar-inner.maintenance {
139
+ background: ${sharedStyles.colors.background.card};
140
+ }
98
141
  .statusbar-inner.maintenance::before {
142
+ background: ${sharedStyles.statusGradients.maintenance};
143
+ }
144
+ .statusbar-inner.maintenance::after {
99
145
  background: ${sharedStyles.colors.status.maintenance};
100
146
  }
101
147
 
102
148
  .statusbar-inner:hover {
103
149
  border-color: ${sharedStyles.colors.border.muted};
104
- box-shadow: ${unsafeCSS(sharedStyles.shadows.base)};
150
+ box-shadow: ${unsafeCSS(sharedStyles.shadows.md)};
151
+ transform: translateY(-1px);
152
+ }
153
+
154
+ .statusbar-inner:hover::before {
155
+ opacity: 1.2;
105
156
  }
106
157
 
107
158
  .status-indicator {
@@ -73,6 +73,12 @@ export class UplStatuspageStatusdetails extends DeesElement {
73
73
 
74
74
  .graph-container {
75
75
  position: relative;
76
+ animation: fadeIn 0.3s ${unsafeCSS(sharedStyles.easings.default)};
77
+ }
78
+
79
+ @keyframes fadeIn {
80
+ from { opacity: 0; }
81
+ to { opacity: 1; }
76
82
  }
77
83
 
78
84
  .mainbox {
@@ -98,14 +104,29 @@ export class UplStatuspageStatusdetails extends DeesElement {
98
104
  flex: 1;
99
105
  height: 100%;
100
106
  cursor: pointer;
101
- transition: all 0.15s ease;
107
+ transition: all ${unsafeCSS(sharedStyles.durations.fast)} ${unsafeCSS(sharedStyles.easings.default)};
102
108
  position: relative;
103
- border-radius: 2px;
109
+ border-radius: 3px;
110
+ animation: barGrow 0.4s ${unsafeCSS(sharedStyles.easings.default)} both;
111
+ animation-delay: calc(var(--bar-index, 0) * 8ms);
112
+ transform-origin: bottom;
113
+ }
114
+
115
+ @keyframes barGrow {
116
+ from {
117
+ transform: scaleY(0);
118
+ opacity: 0;
119
+ }
120
+ to {
121
+ transform: scaleY(1);
122
+ opacity: 1;
123
+ }
104
124
  }
105
125
 
106
126
  .mainbox .barContainer .bar:hover {
107
- transform: scaleY(1.1);
108
- box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
127
+ transform: scaleY(1.15);
128
+ box-shadow: 0 2px 6px rgba(0, 0, 0, 0.15);
129
+ z-index: 1;
109
130
  }
110
131
 
111
132
  .mainbox .barContainer .bar.operational {
@@ -149,20 +170,23 @@ export class UplStatuspageStatusdetails extends DeesElement {
149
170
  position: absolute;
150
171
  background: ${cssManager.bdTheme('#0a0a0a', '#fafafa')};
151
172
  color: ${cssManager.bdTheme('#fafafa', '#0a0a0a')};
152
- padding: 6px 10px;
153
- border-radius: 4px;
173
+ padding: 8px 12px;
174
+ border-radius: ${unsafeCSS(sharedStyles.borderRadius.base)};
154
175
  font-size: 11px;
155
176
  pointer-events: none;
156
177
  opacity: 0;
157
- transition: opacity 0.15s;
178
+ transition: opacity ${unsafeCSS(sharedStyles.durations.fast)} ${unsafeCSS(sharedStyles.easings.default)},
179
+ transform ${unsafeCSS(sharedStyles.durations.fast)} ${unsafeCSS(sharedStyles.easings.default)};
158
180
  z-index: 50;
159
181
  white-space: nowrap;
160
- box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
161
- line-height: 1.4;
182
+ box-shadow: ${unsafeCSS(sharedStyles.shadows.lg)};
183
+ line-height: 1.5;
184
+ transform: translateY(4px);
162
185
  }
163
186
 
164
187
  .tooltip.visible {
165
188
  opacity: 1;
189
+ transform: translateY(0);
166
190
  }
167
191
 
168
192
  .tooltip-time {
@@ -274,8 +298,9 @@ export class UplStatuspageStatusdetails extends DeesElement {
274
298
  const responseTime = dataPoint?.responseTime || 0;
275
299
 
276
300
  bars.push(html`
277
- <div
301
+ <div
278
302
  class="bar ${status}"
303
+ style="--bar-index: ${i}"
279
304
  @mouseenter=${(e: MouseEvent) => this.showTooltip(e, timestamp, status, responseTime)}
280
305
  @click=${() => this.handleBarClick(timestamp, status, responseTime)}
281
306
  ></div>