code_sunset 0.1.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 (71) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.md +242 -0
  4. data/Rakefile +6 -0
  5. data/app/assets/images/code_sunset/.keep +0 -0
  6. data/app/assets/images/code_sunset/logo-dark.png +0 -0
  7. data/app/assets/images/code_sunset/logo-light.png +0 -0
  8. data/app/assets/images/code_sunset/topography.svg +1 -0
  9. data/app/assets/javascripts/code_sunset/application.js +179 -0
  10. data/app/assets/javascripts/code_sunset/vendor/chart.umd.min.js +14 -0
  11. data/app/assets/stylesheets/code_sunset/application.css +1075 -0
  12. data/app/controllers/code_sunset/application_controller.rb +50 -0
  13. data/app/controllers/code_sunset/dashboard_controller.rb +12 -0
  14. data/app/controllers/code_sunset/features_controller.rb +62 -0
  15. data/app/controllers/code_sunset/removal_candidates_controller.rb +9 -0
  16. data/app/controllers/concerns/.keep +0 -0
  17. data/app/helpers/code_sunset/application_helper.rb +244 -0
  18. data/app/jobs/code_sunset/aggregate_daily_rollups_job.rb +48 -0
  19. data/app/jobs/code_sunset/application_job.rb +4 -0
  20. data/app/jobs/code_sunset/cleanup_events_job.rb +10 -0
  21. data/app/jobs/code_sunset/evaluate_alerts_job.rb +15 -0
  22. data/app/jobs/code_sunset/flush_buffered_events_job.rb +9 -0
  23. data/app/jobs/code_sunset/persist_event_job.rb +9 -0
  24. data/app/mailers/code_sunset/application_mailer.rb +6 -0
  25. data/app/models/code_sunset/alert_delivery.rb +14 -0
  26. data/app/models/code_sunset/application_record.rb +5 -0
  27. data/app/models/code_sunset/daily_rollup.rb +31 -0
  28. data/app/models/code_sunset/event.rb +190 -0
  29. data/app/models/code_sunset/feature.rb +33 -0
  30. data/app/models/concerns/.keep +0 -0
  31. data/app/views/code_sunset/dashboard/index.html.erb +123 -0
  32. data/app/views/code_sunset/features/index.html.erb +88 -0
  33. data/app/views/code_sunset/features/show.html.erb +266 -0
  34. data/app/views/code_sunset/removal_candidates/index.html.erb +118 -0
  35. data/app/views/code_sunset/shared/_filter_bar.html.erb +81 -0
  36. data/app/views/layouts/code_sunset/application.html.erb +57 -0
  37. data/bin/rails +26 -0
  38. data/code_sunset.gemspec +35 -0
  39. data/config/routes.rb +5 -0
  40. data/db/migrate/20260330000000_create_code_sunset_tables.rb +62 -0
  41. data/db/migrate/20260331000000_harden_code_sunset_reliability.rb +39 -0
  42. data/lib/code_sunset/alert_dispatcher.rb +103 -0
  43. data/lib/code_sunset/analytics_filters.rb +59 -0
  44. data/lib/code_sunset/configuration.rb +104 -0
  45. data/lib/code_sunset/context.rb +49 -0
  46. data/lib/code_sunset/controller_context.rb +23 -0
  47. data/lib/code_sunset/engine.rb +24 -0
  48. data/lib/code_sunset/event_buffer.rb +28 -0
  49. data/lib/code_sunset/event_ingestor.rb +57 -0
  50. data/lib/code_sunset/event_payload.rb +79 -0
  51. data/lib/code_sunset/feature_query.rb +69 -0
  52. data/lib/code_sunset/feature_snapshot.rb +14 -0
  53. data/lib/code_sunset/feature_usage_series.rb +59 -0
  54. data/lib/code_sunset/identity_hash.rb +9 -0
  55. data/lib/code_sunset/instrumentation.rb +17 -0
  56. data/lib/code_sunset/job_context.rb +17 -0
  57. data/lib/code_sunset/removal_candidate_query.rb +17 -0
  58. data/lib/code_sunset/removal_prompt_builder.rb +331 -0
  59. data/lib/code_sunset/score_calculator.rb +83 -0
  60. data/lib/code_sunset/status_engine.rb +38 -0
  61. data/lib/code_sunset/subscriber.rb +24 -0
  62. data/lib/code_sunset/version.rb +3 -0
  63. data/lib/code_sunset.rb +109 -0
  64. data/lib/generators/code_sunset/eject_ui/eject_ui_generator.rb +33 -0
  65. data/lib/generators/code_sunset/initializer/initializer_generator.rb +13 -0
  66. data/lib/generators/code_sunset/initializer/templates/code_sunset.rb +34 -0
  67. data/lib/generators/code_sunset/install/install_generator.rb +23 -0
  68. data/lib/generators/code_sunset/migration/migration_generator.rb +21 -0
  69. data/lib/generators/code_sunset/migration/templates/create_code_sunset_tables.rb +75 -0
  70. data/lib/tasks/code_sunset_tasks.rake +21 -0
  71. metadata +185 -0
@@ -0,0 +1,1075 @@
1
+ :root {
2
+ --cs-bg: #f5f5f7;
3
+ --cs-sidebar: #fafafc;
4
+ --cs-sidebar-muted: #6e6e73;
5
+ --cs-panel: #ffffff;
6
+ --cs-panel-alt: #f9f9fb;
7
+ --cs-ink: #1d1d1f;
8
+ --cs-muted: #6e6e73;
9
+ --cs-border: rgba(29, 29, 31, 0.055);
10
+ --cs-accent: #0a84ff;
11
+ --cs-accent-dark: #0066cc;
12
+ --cs-good: #1f8f55;
13
+ --cs-warn: #b45309;
14
+ --cs-danger: #b91c1c;
15
+ --cs-shadow: 0 8px 28px rgba(29, 29, 31, 0.035);
16
+ }
17
+
18
+ * {
19
+ box-sizing: border-box;
20
+ }
21
+
22
+ body {
23
+ position: relative;
24
+ margin: 0;
25
+ min-height: 100vh;
26
+ color: var(--cs-ink);
27
+ background: var(--cs-bg);
28
+ font-family: "SF Pro Display", "SF Pro Text", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
29
+ -webkit-font-smoothing: antialiased;
30
+ text-rendering: optimizeLegibility;
31
+ }
32
+
33
+ .cs-background {
34
+ position: fixed;
35
+ inset: 0;
36
+ background-position: center top;
37
+ background-repeat: repeat;
38
+ background-size: 440px 440px;
39
+ opacity: 0.028;
40
+ pointer-events: none;
41
+ z-index: 0;
42
+ }
43
+
44
+ a {
45
+ color: var(--cs-accent-dark);
46
+ text-decoration: none;
47
+ }
48
+
49
+ a:hover {
50
+ text-decoration: underline;
51
+ }
52
+
53
+ table {
54
+ width: 100%;
55
+ border-collapse: collapse;
56
+ }
57
+
58
+ th,
59
+ td {
60
+ padding: 0.85rem 0.9rem;
61
+ border-bottom: 1px solid var(--cs-border);
62
+ text-align: left;
63
+ vertical-align: top;
64
+ }
65
+
66
+ th {
67
+ color: var(--cs-muted);
68
+ font-size: 0.74rem;
69
+ text-transform: uppercase;
70
+ letter-spacing: 0.06em;
71
+ font-weight: 650;
72
+ }
73
+
74
+ .cs-app {
75
+ position: relative;
76
+ z-index: 1;
77
+ min-height: 100vh;
78
+ display: grid;
79
+ grid-template-columns: 240px minmax(0, 1fr);
80
+ gap: 0;
81
+ max-width: 1320px;
82
+ margin: 0 auto;
83
+ padding: 1.5rem;
84
+ }
85
+
86
+ .cs-sidebar {
87
+ display: flex;
88
+ flex-direction: column;
89
+ gap: 1.1rem;
90
+ padding: 0.45rem 1.4rem 0.45rem 0.1rem;
91
+ background: transparent;
92
+ color: var(--cs-ink);
93
+ border-right: 1px solid rgba(29, 29, 31, 0.05);
94
+ position: sticky;
95
+ top: 1.5rem;
96
+ height: calc(100vh - 3rem);
97
+ }
98
+
99
+ .cs-shell {
100
+ min-width: 0;
101
+ padding: 0.1rem 0 0.5rem 2rem;
102
+ }
103
+
104
+ .cs-brand-lockup {
105
+ display: inline-flex;
106
+ align-items: center;
107
+ justify-content: center;
108
+ text-decoration: none;
109
+ width: 100%;
110
+ }
111
+
112
+ .cs-brand-lockup:hover {
113
+ text-decoration: none;
114
+ }
115
+
116
+ .cs-brand-mark {
117
+ display: block;
118
+ width: 7rem;
119
+ height: 7rem;
120
+ object-fit: contain;
121
+ }
122
+
123
+ .cs-tagline {
124
+ margin: 0.7rem 0 0;
125
+ color: var(--cs-sidebar-muted);
126
+ font-size: 0.84rem;
127
+ line-height: 1.45;
128
+ max-width: 12.5rem;
129
+ text-align: center;
130
+ }
131
+
132
+ .cs-sidebar__brand {
133
+ display: grid;
134
+ justify-items: center;
135
+ padding: 0 0 0.8rem;
136
+ }
137
+
138
+ .cs-sidebar__section {
139
+ display: grid;
140
+ gap: 0.42rem;
141
+ }
142
+
143
+ .cs-sidebar__label {
144
+ margin: 0;
145
+ color: var(--cs-muted);
146
+ font-size: 0.68rem;
147
+ font-weight: 700;
148
+ letter-spacing: 0.12em;
149
+ text-transform: uppercase;
150
+ opacity: 0.78;
151
+ }
152
+
153
+ .cs-nav {
154
+ display: grid;
155
+ gap: 0.14rem;
156
+ }
157
+
158
+ .cs-nav__link {
159
+ display: flex;
160
+ align-items: center;
161
+ gap: 0.7rem;
162
+ padding: 0.62rem 0.78rem;
163
+ border-radius: 12px;
164
+ color: #3f3f43;
165
+ font-weight: 510;
166
+ border: 1px solid transparent;
167
+ }
168
+
169
+ .cs-nav__icon {
170
+ display: inline-flex;
171
+ align-items: center;
172
+ justify-content: center;
173
+ width: 1.1rem;
174
+ height: 1.1rem;
175
+ color: #9a9aa1;
176
+ flex: 0 0 auto;
177
+ }
178
+
179
+ .cs-nav__icon svg {
180
+ width: 1rem;
181
+ height: 1rem;
182
+ }
183
+
184
+ .cs-nav__text {
185
+ min-width: 0;
186
+ }
187
+
188
+ .cs-nav__link:hover {
189
+ background: rgba(255, 255, 255, 0.58);
190
+ border-color: rgba(15, 23, 42, 0.045);
191
+ text-decoration: none;
192
+ }
193
+
194
+ .cs-nav__link.is-active {
195
+ background: rgba(255, 255, 255, 0.92);
196
+ color: #1d1d1f;
197
+ border-color: rgba(15, 23, 42, 0.035);
198
+ box-shadow: 0 1px 2px rgba(29, 29, 31, 0.03);
199
+ }
200
+
201
+ .cs-nav__link.is-active .cs-nav__icon {
202
+ color: #6a6a71;
203
+ }
204
+
205
+ .cs-main {
206
+ display: grid;
207
+ gap: 1.7rem;
208
+ }
209
+
210
+ .cs-footer {
211
+ margin-top: auto;
212
+ padding: 0.95rem 0.75rem 0 0;
213
+ border-top: 1px solid rgba(15, 23, 42, 0.05);
214
+ color: var(--cs-sidebar-muted);
215
+ font-size: 0.79rem;
216
+ line-height: 1.5;
217
+ opacity: 0.92;
218
+ }
219
+
220
+ .cs-footer__meta {
221
+ margin: 0 0 0.2rem;
222
+ }
223
+
224
+ .cs-footer a {
225
+ color: var(--cs-accent-dark);
226
+ font-weight: 600;
227
+ }
228
+
229
+ .cs-panel {
230
+ background: var(--cs-panel);
231
+ border: 1px solid var(--cs-border);
232
+ border-radius: 26px;
233
+ box-shadow: var(--cs-shadow);
234
+ padding: 1.3rem;
235
+ }
236
+
237
+ .cs-panel--notice {
238
+ background: linear-gradient(180deg, rgba(255, 247, 237, 0.96), rgba(255, 255, 255, 0.94));
239
+ border-color: rgba(251, 191, 36, 0.24);
240
+ }
241
+
242
+ .cs-panel__heading {
243
+ display: flex;
244
+ align-items: flex-start;
245
+ justify-content: space-between;
246
+ gap: 1rem;
247
+ margin-bottom: 0.9rem;
248
+ }
249
+
250
+ .cs-panel__heading--prompt {
251
+ margin-bottom: 0.55rem;
252
+ }
253
+
254
+ .cs-panel__heading h2 {
255
+ margin: 0;
256
+ font-size: 0.96rem;
257
+ letter-spacing: -0.015em;
258
+ font-weight: 610;
259
+ }
260
+
261
+ .cs-panel__copy {
262
+ margin: -0.25rem 0 1rem;
263
+ color: var(--cs-muted);
264
+ line-height: 1.5;
265
+ }
266
+
267
+ .cs-panel__count {
268
+ color: var(--cs-muted);
269
+ font-size: 0.78rem;
270
+ font-weight: 500;
271
+ font-variant-numeric: tabular-nums;
272
+ }
273
+
274
+ .cs-eyebrow {
275
+ margin: 0 0 0.3rem;
276
+ color: var(--cs-muted);
277
+ font-size: 0.68rem;
278
+ letter-spacing: 0.1em;
279
+ text-transform: uppercase;
280
+ font-weight: 700;
281
+ }
282
+
283
+ .cs-page-header {
284
+ display: flex;
285
+ align-items: flex-start;
286
+ justify-content: space-between;
287
+ gap: 1.5rem;
288
+ padding: 0.1rem 0 0;
289
+ }
290
+
291
+ .cs-page-title {
292
+ margin: 0;
293
+ font-size: 2.06rem;
294
+ line-height: 1.15;
295
+ letter-spacing: -0.045em;
296
+ font-weight: 650;
297
+ }
298
+
299
+ .cs-page-copy {
300
+ max-width: 38rem;
301
+ margin: 0.35rem 0 0;
302
+ color: var(--cs-muted);
303
+ font-size: 0.94rem;
304
+ line-height: 1.5;
305
+ }
306
+
307
+ .cs-page-actions {
308
+ display: flex;
309
+ gap: 1rem;
310
+ flex-wrap: wrap;
311
+ align-items: center;
312
+ }
313
+
314
+ .cs-page-header--feature {
315
+ align-items: flex-start;
316
+ }
317
+
318
+ .cs-page-actions--feature {
319
+ justify-content: flex-end;
320
+ gap: 0.65rem;
321
+ max-width: 21rem;
322
+ }
323
+
324
+ .cs-page-actions--compact {
325
+ padding-top: 0.1rem;
326
+ gap: 0.65rem;
327
+ }
328
+
329
+ .cs-overview-layout {
330
+ display: grid;
331
+ grid-template-columns: minmax(0, 1.58fr) minmax(300px, 0.82fr);
332
+ gap: 1rem;
333
+ align-items: start;
334
+ }
335
+
336
+ .cs-grid {
337
+ display: grid;
338
+ grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
339
+ gap: 0.78rem;
340
+ }
341
+
342
+ .cs-grid--feature-summary {
343
+ grid-template-columns: repeat(4, minmax(0, 1fr));
344
+ }
345
+
346
+ .cs-stack {
347
+ display: grid;
348
+ gap: 1rem;
349
+ align-content: start;
350
+ }
351
+
352
+ .cs-stat {
353
+ background: linear-gradient(180deg, rgba(255, 255, 255, 0.96), rgba(250, 250, 252, 0.96));
354
+ border-radius: 22px;
355
+ padding: 1.1rem 1.15rem 1rem;
356
+ border: 1px solid rgba(29, 29, 31, 0.045);
357
+ box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.96);
358
+ }
359
+
360
+ .cs-stat__label {
361
+ margin: 0 0 0.32rem;
362
+ color: #7d7d84;
363
+ font-size: 0.76rem;
364
+ text-transform: none;
365
+ letter-spacing: 0;
366
+ font-weight: 500;
367
+ }
368
+
369
+ .cs-stat__value {
370
+ margin: 0 0 0.24rem;
371
+ font-size: 2rem;
372
+ line-height: 1.02;
373
+ letter-spacing: -0.045em;
374
+ font-weight: 620;
375
+ font-variant-numeric: tabular-nums;
376
+ }
377
+
378
+ .cs-stat__hint {
379
+ margin: 0;
380
+ color: var(--cs-muted);
381
+ line-height: 1.4;
382
+ font-size: 0.78rem;
383
+ }
384
+
385
+ .cs-subtle {
386
+ color: var(--cs-muted);
387
+ }
388
+
389
+ .cs-table-wrap {
390
+ overflow-x: auto;
391
+ border: 1px solid rgba(29, 29, 31, 0.045);
392
+ border-radius: 18px;
393
+ background: linear-gradient(180deg, #ffffff, #fcfcfd);
394
+ box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.96);
395
+ }
396
+
397
+ .cs-table th {
398
+ background: rgba(250, 250, 252, 0.92);
399
+ }
400
+
401
+ .cs-table td,
402
+ .cs-table th {
403
+ border-bottom-color: rgba(29, 29, 31, 0.045);
404
+ }
405
+
406
+ .cs-table td:first-child,
407
+ .cs-table th:first-child {
408
+ padding-left: 1.25rem;
409
+ }
410
+
411
+ .cs-table td:last-child,
412
+ .cs-table th:last-child {
413
+ padding-right: 1.25rem;
414
+ }
415
+
416
+ .cs-table th {
417
+ color: #8e8e93;
418
+ font-size: 0.66rem;
419
+ letter-spacing: 0.11em;
420
+ font-weight: 700;
421
+ }
422
+
423
+ .cs-table td {
424
+ padding-top: 0.74rem;
425
+ padding-bottom: 0.74rem;
426
+ font-size: 0.9rem;
427
+ line-height: 1.38;
428
+ color: #2f2f33;
429
+ font-variant-numeric: tabular-nums;
430
+ }
431
+
432
+ .cs-table--features td {
433
+ vertical-align: middle;
434
+ }
435
+
436
+ .cs-table--features td:nth-child(6) {
437
+ white-space: nowrap;
438
+ }
439
+
440
+ .cs-table--compact td,
441
+ .cs-table--compact th {
442
+ padding-left: 0.95rem;
443
+ padding-right: 0.95rem;
444
+ }
445
+
446
+ .cs-table--compact td:first-child,
447
+ .cs-table--compact th:first-child {
448
+ padding-left: 1rem;
449
+ }
450
+
451
+ .cs-table--compact td:last-child,
452
+ .cs-table--compact th:last-child {
453
+ padding-right: 1rem;
454
+ }
455
+
456
+ .cs-table tbody tr:hover {
457
+ background: rgba(250, 250, 252, 0.9);
458
+ }
459
+
460
+ .cs-table td .cs-code,
461
+ .cs-table th .cs-code {
462
+ font-size: 0.84rem;
463
+ }
464
+
465
+ .cs-table tbody tr:last-child td {
466
+ border-bottom: 0;
467
+ }
468
+
469
+ .cs-filters {
470
+ display: grid;
471
+ grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
472
+ gap: 0.75rem;
473
+ align-items: end;
474
+ }
475
+
476
+ .cs-filter-shell {
477
+ display: grid;
478
+ gap: 0.8rem;
479
+ }
480
+
481
+ .cs-filters--primary {
482
+ grid-template-columns: repeat(3, minmax(160px, 1fr)) auto;
483
+ }
484
+
485
+ .cs-filters--secondary {
486
+ padding-top: 0.1rem;
487
+ }
488
+
489
+ .cs-filter-actions {
490
+ display: flex;
491
+ align-items: end;
492
+ gap: 0.65rem;
493
+ padding-bottom: 0.05rem;
494
+ }
495
+
496
+ .cs-field label {
497
+ display: block;
498
+ margin-bottom: 0.28rem;
499
+ color: var(--cs-muted);
500
+ font-size: 0.79rem;
501
+ }
502
+
503
+ .cs-field input,
504
+ .cs-field select {
505
+ width: 100%;
506
+ border: 1px solid var(--cs-border);
507
+ border-radius: 12px;
508
+ padding: 0.62rem 0.78rem;
509
+ background: white;
510
+ color: var(--cs-ink);
511
+ box-shadow: inset 0 1px 1px rgba(15, 23, 42, 0.025);
512
+ font-size: 0.88rem;
513
+ }
514
+
515
+ .cs-button {
516
+ display: inline-block;
517
+ display: inline-flex;
518
+ align-items: center;
519
+ justify-content: center;
520
+ gap: 0.5rem;
521
+ border: 0;
522
+ border-radius: 999px;
523
+ background: #1d1d1f;
524
+ color: white;
525
+ padding: 0.68rem 1rem;
526
+ cursor: pointer;
527
+ font-weight: 700;
528
+ box-shadow: none;
529
+ white-space: nowrap;
530
+ }
531
+
532
+ .cs-button:hover {
533
+ background: #000000;
534
+ text-decoration: none;
535
+ }
536
+
537
+ .cs-button--secondary {
538
+ background: #ffffff;
539
+ color: var(--cs-ink);
540
+ border: 1px solid var(--cs-border);
541
+ box-shadow: none;
542
+ }
543
+
544
+ .cs-button--secondary:hover {
545
+ background: rgba(255, 255, 255, 1);
546
+ }
547
+
548
+ .cs-button--ai {
549
+ background: linear-gradient(180deg, rgba(255, 255, 255, 0.98), rgba(247, 248, 252, 0.98));
550
+ color: #30303a;
551
+ border: 1px solid rgba(99, 91, 255, 0.14);
552
+ box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.96), 0 1px 2px rgba(29, 29, 31, 0.04);
553
+ }
554
+
555
+ .cs-button--ai:hover {
556
+ background: linear-gradient(180deg, rgba(255, 255, 255, 1), rgba(244, 246, 252, 1));
557
+ border-color: rgba(99, 91, 255, 0.2);
558
+ }
559
+
560
+ .cs-button__icon {
561
+ display: inline-flex;
562
+ align-items: center;
563
+ justify-content: center;
564
+ width: 0.95rem;
565
+ height: 0.95rem;
566
+ color: #635bff;
567
+ flex: 0 0 auto;
568
+ }
569
+
570
+ .cs-button__icon svg {
571
+ width: 0.95rem;
572
+ height: 0.95rem;
573
+ }
574
+
575
+ .cs-inline-link {
576
+ color: var(--cs-accent-dark);
577
+ font-weight: 590;
578
+ font-size: 0.88rem;
579
+ }
580
+
581
+ .cs-inline-link:hover {
582
+ text-decoration: underline;
583
+ }
584
+
585
+ .cs-removal-prompt {
586
+ display: grid;
587
+ gap: 0.9rem;
588
+ }
589
+
590
+ .cs-removal-prompt__section {
591
+ display: grid;
592
+ gap: 0.55rem;
593
+ }
594
+
595
+ .cs-removal-prompt__warnings {
596
+ display: grid;
597
+ gap: 0.35rem;
598
+ margin: 0 0 0.8rem;
599
+ padding: 0.85rem 0.95rem;
600
+ border-radius: 16px;
601
+ background: rgba(255, 247, 237, 0.72);
602
+ border: 1px solid rgba(251, 191, 36, 0.16);
603
+ }
604
+
605
+ .cs-removal-prompt__warning {
606
+ margin: 0;
607
+ color: #6b4f1d;
608
+ font-size: 0.86rem;
609
+ line-height: 1.45;
610
+ }
611
+
612
+ .cs-markdown-block {
613
+ margin: 0;
614
+ padding: 0.92rem 1rem;
615
+ border: 1px solid rgba(29, 29, 31, 0.055);
616
+ border-radius: 18px;
617
+ background: linear-gradient(180deg, rgba(250, 250, 252, 0.98), rgba(255, 255, 255, 0.98));
618
+ color: #2f2f33;
619
+ overflow-x: auto;
620
+ white-space: pre-wrap;
621
+ word-break: break-word;
622
+ font-family: "SF Mono", "SFMono-Regular", ui-monospace, Menlo, Consolas, monospace;
623
+ font-size: 0.79rem;
624
+ line-height: 1.52;
625
+ }
626
+
627
+ .cs-panel--removal-prompt {
628
+ padding-top: 1.15rem;
629
+ }
630
+
631
+ .cs-disclosure {
632
+ border-top: 1px solid rgba(29, 29, 31, 0.05);
633
+ padding-top: 0.9rem;
634
+ }
635
+
636
+ .cs-disclosure__summary {
637
+ list-style: none;
638
+ cursor: pointer;
639
+ color: var(--cs-ink);
640
+ font-size: 0.88rem;
641
+ font-weight: 590;
642
+ }
643
+
644
+ .cs-disclosure__summary::-webkit-details-marker {
645
+ display: none;
646
+ }
647
+
648
+ .cs-disclosure__summary::before {
649
+ content: "+";
650
+ display: inline-block;
651
+ width: 1rem;
652
+ margin-right: 0.35rem;
653
+ color: var(--cs-muted);
654
+ }
655
+
656
+ .cs-disclosure[open] .cs-disclosure__summary::before {
657
+ content: "−";
658
+ }
659
+
660
+ .cs-disclosure[open] .cs-disclosure__summary {
661
+ margin-bottom: 0.9rem;
662
+ }
663
+
664
+ .cs-chip-row {
665
+ display: flex;
666
+ flex-wrap: wrap;
667
+ gap: 0.55rem;
668
+ }
669
+
670
+ .cs-chip {
671
+ display: inline-flex;
672
+ align-items: center;
673
+ gap: 0.38rem;
674
+ padding: 0.42rem 0.62rem;
675
+ border-radius: 999px;
676
+ background: #f6f6f8;
677
+ border: 1px solid rgba(29, 29, 31, 0.05);
678
+ font-size: 0.82rem;
679
+ color: #3c3c43;
680
+ }
681
+
682
+ .cs-chip__label {
683
+ color: var(--cs-muted);
684
+ }
685
+
686
+ .cs-chip__value {
687
+ font-weight: 590;
688
+ }
689
+
690
+ .cs-chip__remove {
691
+ color: var(--cs-accent-dark);
692
+ font-size: 0.76rem;
693
+ font-weight: 600;
694
+ }
695
+
696
+ .cs-pagination {
697
+ display: flex;
698
+ align-items: center;
699
+ justify-content: space-between;
700
+ gap: 0.9rem;
701
+ margin-top: 0.95rem;
702
+ }
703
+
704
+ .cs-pagination__summary {
705
+ color: var(--cs-muted);
706
+ font-size: 0.84rem;
707
+ font-variant-numeric: tabular-nums;
708
+ }
709
+
710
+ .cs-pagination__link {
711
+ display: inline-flex;
712
+ align-items: center;
713
+ justify-content: center;
714
+ min-width: 5.75rem;
715
+ padding: 0.58rem 0.85rem;
716
+ border-radius: 999px;
717
+ border: 1px solid rgba(29, 29, 31, 0.06);
718
+ background: rgba(255, 255, 255, 0.92);
719
+ color: var(--cs-ink);
720
+ font-size: 0.84rem;
721
+ font-weight: 560;
722
+ text-decoration: none;
723
+ }
724
+
725
+ .cs-pagination__link:hover {
726
+ background: white;
727
+ border-color: rgba(29, 29, 31, 0.09);
728
+ text-decoration: none;
729
+ }
730
+
731
+ .cs-pagination__link.is-disabled {
732
+ color: #a1a1a8;
733
+ background: rgba(245, 245, 247, 0.92);
734
+ border-color: rgba(29, 29, 31, 0.04);
735
+ pointer-events: none;
736
+ }
737
+
738
+ .cs-badge {
739
+ display: inline-flex;
740
+ align-items: center;
741
+ border-radius: 999px;
742
+ padding: 0.33rem 0.68rem;
743
+ font-size: 0.72rem;
744
+ text-transform: uppercase;
745
+ letter-spacing: 0.07em;
746
+ font-weight: 680;
747
+ }
748
+
749
+ .cs-badge--active {
750
+ background: rgba(15, 157, 88, 0.12);
751
+ color: var(--cs-good);
752
+ }
753
+
754
+ .cs-badge--cooling_down,
755
+ .cs-badge--candidate_for_removal {
756
+ background: rgba(180, 83, 9, 0.1);
757
+ color: var(--cs-warn);
758
+ }
759
+
760
+ .cs-badge--safe_to_remove {
761
+ background: rgba(185, 28, 28, 0.1);
762
+ color: var(--cs-danger);
763
+ }
764
+
765
+ .cs-split {
766
+ display: grid;
767
+ grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
768
+ gap: 1.1rem;
769
+ }
770
+
771
+ .cs-detail-layout {
772
+ display: grid;
773
+ grid-template-columns: minmax(0, 1.45fr) minmax(300px, 0.85fr);
774
+ gap: 1rem;
775
+ align-items: start;
776
+ }
777
+
778
+ .cs-candidate-grid {
779
+ display: grid;
780
+ grid-template-columns: repeat(2, minmax(0, 1fr));
781
+ gap: 1rem;
782
+ align-items: start;
783
+ }
784
+
785
+ .cs-feature-list {
786
+ list-style: none;
787
+ margin: 0;
788
+ padding: 0;
789
+ display: grid;
790
+ gap: 0.8rem;
791
+ }
792
+
793
+ .cs-feature-list__item {
794
+ display: flex;
795
+ align-items: flex-start;
796
+ justify-content: space-between;
797
+ gap: 1rem;
798
+ padding: 0.9rem 0.95rem;
799
+ border: 1px solid rgba(29, 29, 31, 0.045);
800
+ border-radius: 18px;
801
+ background: #fafafd;
802
+ transition: background 120ms ease, border-color 120ms ease;
803
+ }
804
+
805
+ .cs-feature-list__item:hover {
806
+ background: #ffffff;
807
+ border-color: rgba(15, 23, 42, 0.07);
808
+ }
809
+
810
+ .cs-feature-list__title {
811
+ font-size: 0.94rem;
812
+ font-weight: 620;
813
+ }
814
+
815
+ .cs-feature-list__meta {
816
+ display: flex;
817
+ align-items: center;
818
+ gap: 0.55rem;
819
+ flex-wrap: wrap;
820
+ justify-content: flex-end;
821
+ }
822
+
823
+ .cs-queue-list {
824
+ list-style: none;
825
+ margin: 0;
826
+ padding: 0;
827
+ display: grid;
828
+ gap: 0.2rem;
829
+ }
830
+
831
+ .cs-queue-list__item {
832
+ display: grid;
833
+ grid-template-columns: minmax(0, 1fr) auto;
834
+ gap: 0.9rem;
835
+ align-items: center;
836
+ padding: 0.78rem 0;
837
+ border-bottom: 1px solid rgba(29, 29, 31, 0.05);
838
+ }
839
+
840
+ .cs-queue-list__item:first-child {
841
+ padding-top: 0.1rem;
842
+ }
843
+
844
+ .cs-queue-list__item:last-child {
845
+ padding-bottom: 0;
846
+ border-bottom: 0;
847
+ }
848
+
849
+ .cs-queue-list__body {
850
+ min-width: 0;
851
+ }
852
+
853
+ .cs-queue-list__title {
854
+ display: inline-block;
855
+ font-size: 0.87rem;
856
+ font-weight: 620;
857
+ line-height: 1.35;
858
+ }
859
+
860
+ .cs-queue-list__meta {
861
+ margin: 0.22rem 0 0;
862
+ color: var(--cs-muted);
863
+ font-size: 0.8rem;
864
+ line-height: 1.4;
865
+ }
866
+
867
+ .cs-queue-list__aside {
868
+ display: inline-flex;
869
+ align-items: center;
870
+ }
871
+
872
+ .cs-list {
873
+ margin: 0;
874
+ padding-left: 1.2rem;
875
+ }
876
+
877
+ .cs-breakdown-group {
878
+ display: grid;
879
+ gap: 1rem;
880
+ }
881
+
882
+ .cs-breakdown-block {
883
+ display: grid;
884
+ gap: 0.55rem;
885
+ padding-bottom: 0.95rem;
886
+ border-bottom: 1px solid rgba(29, 29, 31, 0.05);
887
+ }
888
+
889
+ .cs-breakdown-block:last-child {
890
+ padding-bottom: 0;
891
+ border-bottom: 0;
892
+ }
893
+
894
+ .cs-breakdown-block__title {
895
+ margin: 0;
896
+ font-size: 0.9rem;
897
+ letter-spacing: -0.01em;
898
+ font-weight: 610;
899
+ }
900
+
901
+ .cs-meta-grid {
902
+ display: grid;
903
+ gap: 0.8rem;
904
+ }
905
+
906
+ .cs-meta-row {
907
+ display: grid;
908
+ gap: 0.2rem;
909
+ padding-bottom: 0.8rem;
910
+ border-bottom: 1px solid var(--cs-border);
911
+ }
912
+
913
+ .cs-meta-row:last-child {
914
+ padding-bottom: 0;
915
+ border-bottom: 0;
916
+ }
917
+
918
+ .cs-meta-row__label {
919
+ color: var(--cs-muted);
920
+ font-size: 0.76rem;
921
+ text-transform: uppercase;
922
+ letter-spacing: 0.09em;
923
+ font-weight: 700;
924
+ }
925
+
926
+ .cs-code {
927
+ font-family: "SFMono-Regular", Consolas, "Liberation Mono", Menlo, monospace;
928
+ font-size: 0.84rem;
929
+ letter-spacing: -0.01em;
930
+ }
931
+
932
+ .cs-time {
933
+ border-bottom: 1px dotted #cbd5e1;
934
+ cursor: help;
935
+ }
936
+
937
+ .cs-chart-shell {
938
+ position: relative;
939
+ min-height: 240px;
940
+ }
941
+
942
+ .cs-chart {
943
+ width: 100%;
944
+ height: 240px;
945
+ }
946
+
947
+ .cs-score {
948
+ display: inline-flex;
949
+ align-items: center;
950
+ padding: 0.33rem 0.56rem;
951
+ border-radius: 999px;
952
+ background: #f3f3f6;
953
+ color: var(--cs-ink);
954
+ font-size: 0.78rem;
955
+ font-weight: 700;
956
+ }
957
+
958
+ .cs-score--help {
959
+ cursor: help;
960
+ }
961
+
962
+ .cs-metric-pair {
963
+ display: inline-flex;
964
+ align-items: center;
965
+ gap: 0.65rem;
966
+ flex-wrap: wrap;
967
+ }
968
+
969
+ .cs-metric-pair__item {
970
+ display: inline-flex;
971
+ align-items: baseline;
972
+ gap: 0.22rem;
973
+ color: #4b4b52;
974
+ font-size: 0.82rem;
975
+ white-space: nowrap;
976
+ }
977
+
978
+ .cs-metric-pair__item strong {
979
+ font-size: 0.9rem;
980
+ font-weight: 650;
981
+ color: var(--cs-ink);
982
+ }
983
+
984
+ .cs-metric-pair__item span {
985
+ color: var(--cs-muted);
986
+ font-size: 0.72rem;
987
+ letter-spacing: 0.02em;
988
+ }
989
+
990
+ .cs-stacked-meta {
991
+ display: grid;
992
+ gap: 0.12rem;
993
+ min-width: 0;
994
+ }
995
+
996
+ .cs-stacked-meta__primary {
997
+ color: var(--cs-ink);
998
+ font-size: 0.84rem;
999
+ line-height: 1.35;
1000
+ }
1001
+
1002
+ .cs-stacked-meta__secondary {
1003
+ color: var(--cs-muted);
1004
+ font-size: 0.75rem;
1005
+ line-height: 1.35;
1006
+ }
1007
+
1008
+ .cs-code--wrap {
1009
+ white-space: normal;
1010
+ overflow-wrap: anywhere;
1011
+ word-break: break-word;
1012
+ line-height: 1.4;
1013
+ }
1014
+
1015
+ @media (max-width: 1120px) {
1016
+ .cs-grid--feature-summary {
1017
+ grid-template-columns: repeat(2, minmax(0, 1fr));
1018
+ }
1019
+ }
1020
+
1021
+ @media (max-width: 768px) {
1022
+ .cs-app {
1023
+ grid-template-columns: 1fr;
1024
+ gap: 1.25rem;
1025
+ padding: 1rem;
1026
+ }
1027
+
1028
+ .cs-sidebar {
1029
+ gap: 1rem;
1030
+ padding: 0;
1031
+ border-right: 0;
1032
+ border-bottom: 1px solid rgba(15, 23, 42, 0.06);
1033
+ position: static;
1034
+ height: auto;
1035
+ }
1036
+
1037
+ .cs-shell {
1038
+ padding: 0;
1039
+ }
1040
+
1041
+ .cs-topbar,
1042
+ .cs-page-header,
1043
+ .cs-overview-layout,
1044
+ .cs-detail-layout,
1045
+ .cs-candidate-grid,
1046
+ .cs-panel__heading,
1047
+ .cs-feature-list__item {
1048
+ grid-template-columns: 1fr;
1049
+ }
1050
+
1051
+ .cs-page-header,
1052
+ .cs-panel__heading,
1053
+ .cs-feature-list__item {
1054
+ flex-direction: column;
1055
+ }
1056
+
1057
+ .cs-queue-list__item {
1058
+ grid-template-columns: 1fr;
1059
+ }
1060
+
1061
+ .cs-filters--primary {
1062
+ grid-template-columns: 1fr;
1063
+ }
1064
+
1065
+ .cs-filter-actions {
1066
+ align-items: center;
1067
+ padding-bottom: 0;
1068
+ }
1069
+
1070
+ th,
1071
+ td {
1072
+ padding: 0.62rem;
1073
+ font-size: 0.88rem;
1074
+ }
1075
+ }