solidstats 2.0.0 → 3.0.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 (135) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +12 -63
  3. data/README.md +27 -0
  4. data/Rakefile +3 -3
  5. data/app/assets/javascripts/solidstats/dashboard.js +0 -46
  6. data/app/assets/stylesheets/solidstats/dashboard.css +48 -0
  7. data/app/controllers/solidstats/dashboard_controller.rb +73 -61
  8. data/app/controllers/solidstats/logs_controller.rb +72 -0
  9. data/app/controllers/solidstats/performance_controller.rb +25 -0
  10. data/app/controllers/solidstats/productivity_controller.rb +39 -0
  11. data/app/controllers/solidstats/quality_controller.rb +152 -0
  12. data/app/controllers/solidstats/securities_controller.rb +30 -0
  13. data/app/helpers/solidstats/application_helper.rb +124 -11
  14. data/app/helpers/solidstats/performance_helper.rb +87 -0
  15. data/app/helpers/solidstats/productivity_helper.rb +38 -0
  16. data/app/services/solidstats/bundler_audit_service.rb +206 -0
  17. data/app/services/solidstats/coverage_compass_service.rb +335 -0
  18. data/app/services/solidstats/load_lens_service.rb +474 -0
  19. data/app/services/solidstats/log_size_monitor_service.rb +197 -66
  20. data/app/services/solidstats/my_todo_service.rb +242 -0
  21. data/app/services/solidstats/style_patrol_service.rb +319 -0
  22. data/app/views/layouts/solidstats/application.html.erb +8 -2
  23. data/app/views/layouts/solidstats/dashboard.html.erb +84 -0
  24. data/app/views/solidstats/dashboard/dashboard.html.erb +39 -0
  25. data/app/views/solidstats/logs/logs_size.html.erb +409 -0
  26. data/app/views/solidstats/performance/load_lens.html.erb +158 -0
  27. data/app/views/solidstats/productivity/_todo_list.html.erb +49 -0
  28. data/app/views/solidstats/productivity/my_todos.html.erb +84 -0
  29. data/app/views/solidstats/quality/coverage_compass.html.erb +420 -0
  30. data/app/views/solidstats/quality/style_patrol.html.erb +463 -0
  31. data/app/views/solidstats/securities/bundler_audit.html.erb +345 -0
  32. data/app/views/solidstats/shared/_dashboard_card.html.erb +160 -0
  33. data/app/views/solidstats/shared/_quick_actions.html.erb +26 -0
  34. data/config/routes.rb +31 -6
  35. data/lib/generators/solidstats/clean/clean_generator.rb +24 -0
  36. data/lib/generators/solidstats/clean/templates/README +8 -0
  37. data/lib/generators/solidstats/install/install_generator.rb +51 -10
  38. data/lib/generators/solidstats/install/templates/README +7 -0
  39. data/lib/solidstats/engine.rb +6 -71
  40. data/lib/solidstats/version.rb +1 -1
  41. data/lib/solidstats.rb +19 -303
  42. data/lib/tasks/solidstats.rake +67 -0
  43. data/lib/tasks/solidstats_performance.rake +61 -0
  44. data/lib/tasks/solidstats_tasks.rake +16 -4
  45. metadata +33 -95
  46. data/app/assets/javascripts/solidstats/gem_metadata.js +0 -554
  47. data/app/assets/stylesheets/solidstats/components/action_button.css +0 -99
  48. data/app/assets/stylesheets/solidstats/components/dashboard.css +0 -151
  49. data/app/assets/stylesheets/solidstats/components/dashboard_header.css +0 -93
  50. data/app/assets/stylesheets/solidstats/components/dashboard_layout.css +0 -97
  51. data/app/assets/stylesheets/solidstats/components/gem_metadata.css +0 -1403
  52. data/app/assets/stylesheets/solidstats/components/navigation.css +0 -80
  53. data/app/assets/stylesheets/solidstats/components/quick_navigation.css +0 -54
  54. data/app/assets/stylesheets/solidstats/components/security.css +0 -332
  55. data/app/assets/stylesheets/solidstats/components/status_badge.css +0 -58
  56. data/app/assets/stylesheets/solidstats/components/summary_card.css +0 -66
  57. data/app/assets/stylesheets/solidstats/components/tab_navigation.css +0 -95
  58. data/app/components/solidstats/base_component.rb +0 -88
  59. data/app/components/solidstats/code_quality/code_quality_section_component.html.erb +0 -0
  60. data/app/components/solidstats/code_quality/code_quality_section_component.rb +0 -0
  61. data/app/components/solidstats/code_quality/section_component.html.erb +0 -45
  62. data/app/components/solidstats/code_quality/section_component.rb +0 -34
  63. data/app/components/solidstats/dashboard_header_component.html.erb +0 -39
  64. data/app/components/solidstats/dashboard_header_component.rb +0 -33
  65. data/app/components/solidstats/previews/action_button_component_preview/button_vs_link.html.erb +0 -6
  66. data/app/components/solidstats/previews/action_button_component_preview/sizes.html.erb +0 -6
  67. data/app/components/solidstats/previews/action_button_component_preview/variants.html.erb +0 -6
  68. data/app/components/solidstats/previews/action_button_component_preview/with_icons.html.erb +0 -6
  69. data/app/components/solidstats/previews/action_button_component_preview.rb +0 -64
  70. data/app/components/solidstats/previews/navigation_component_preview.rb +0 -74
  71. data/app/components/solidstats/previews/stats_overview_component_preview.rb +0 -100
  72. data/app/components/solidstats/previews/status_badge_component_preview/sizes.html.erb +0 -6
  73. data/app/components/solidstats/previews/status_badge_component_preview/statuses.html.erb +0 -6
  74. data/app/components/solidstats/previews/status_badge_component_preview/with_icons.html.erb +0 -6
  75. data/app/components/solidstats/previews/status_badge_component_preview.rb +0 -49
  76. data/app/components/solidstats/previews/summary_card_component_preview/clickable.html.erb +0 -9
  77. data/app/components/solidstats/previews/summary_card_component_preview/dashboard_layout.html.erb +0 -9
  78. data/app/components/solidstats/previews/summary_card_component_preview/statuses.html.erb +0 -6
  79. data/app/components/solidstats/previews/summary_card_component_preview/value_formats.html.erb +0 -6
  80. data/app/components/solidstats/previews/summary_card_component_preview.rb +0 -67
  81. data/app/components/solidstats/quick_navigation_component.html.erb +0 -8
  82. data/app/components/solidstats/quick_navigation_component.rb +0 -21
  83. data/app/components/solidstats/security/gem_impact_analysis_component.html.erb +0 -44
  84. data/app/components/solidstats/security/gem_impact_analysis_component.rb +0 -45
  85. data/app/components/solidstats/security/overview_component.html.erb +0 -21
  86. data/app/components/solidstats/security/overview_component.rb +0 -104
  87. data/app/components/solidstats/security/section_component.html.erb +0 -26
  88. data/app/components/solidstats/security/section_component.rb +0 -52
  89. data/app/components/solidstats/security/timeline_component.html.erb +0 -39
  90. data/app/components/solidstats/security/timeline_component.rb +0 -43
  91. data/app/components/solidstats/tasks_section_component.html.erb +0 -17
  92. data/app/components/solidstats/tasks_section_component.rb +0 -22
  93. data/app/components/solidstats/ui/action_button_component.html.erb +0 -6
  94. data/app/components/solidstats/ui/action_button_component.rb +0 -71
  95. data/app/components/solidstats/ui/dashboard_layout_component.html.erb +0 -19
  96. data/app/components/solidstats/ui/dashboard_layout_component.rb +0 -85
  97. data/app/components/solidstats/ui/navigation_component.html.erb +0 -34
  98. data/app/components/solidstats/ui/navigation_component.rb +0 -72
  99. data/app/components/solidstats/ui/stats_overview_component.html.erb +0 -14
  100. data/app/components/solidstats/ui/stats_overview_component.rb +0 -78
  101. data/app/components/solidstats/ui/status_badge_component.html.erb +0 -6
  102. data/app/components/solidstats/ui/status_badge_component.rb +0 -42
  103. data/app/components/solidstats/ui/summary_card_component.html.erb +0 -12
  104. data/app/components/solidstats/ui/summary_card_component.rb +0 -63
  105. data/app/components/solidstats/ui/tab_navigation_component.html.erb +0 -22
  106. data/app/components/solidstats/ui/tab_navigation_component.rb +0 -79
  107. data/app/services/solidstats/audit_service.rb +0 -56
  108. data/app/services/solidstats/data_collector_service.rb +0 -83
  109. data/app/services/solidstats/gem_metadata/fetcher_service.rb +0 -136
  110. data/app/services/solidstats/todo_service.rb +0 -114
  111. data/app/views/solidstats/dashboard/_log_monitor.html.erb +0 -759
  112. data/app/views/solidstats/dashboard/_todos.html.erb +0 -151
  113. data/app/views/solidstats/dashboard/audit/_additional_styles.css +0 -22
  114. data/app/views/solidstats/dashboard/audit/_audit_badge.html.erb +0 -5
  115. data/app/views/solidstats/dashboard/audit/_audit_details.html.erb +0 -495
  116. data/app/views/solidstats/dashboard/audit/_audit_summary.html.erb +0 -26
  117. data/app/views/solidstats/dashboard/audit/_no_vulnerabilities.html.erb +0 -3
  118. data/app/views/solidstats/dashboard/audit/_security_audit.html.erb +0 -14
  119. data/app/views/solidstats/dashboard/audit/_vulnerabilities_table.html.erb +0 -1120
  120. data/app/views/solidstats/dashboard/audit/_vulnerability_details.html.erb +0 -63
  121. data/app/views/solidstats/dashboard/index.html.erb +0 -81
  122. data/app/views/solidstats/gem_metadata/_panel.html.erb +0 -419
  123. data/lib/generators/solidstats/feature/feature_generator.rb +0 -170
  124. data/lib/generators/solidstats/feature/templates/component.html.erb +0 -84
  125. data/lib/generators/solidstats/feature/templates/component.rb.erb +0 -103
  126. data/lib/generators/solidstats/feature/templates/component.scss +0 -243
  127. data/lib/generators/solidstats/feature/templates/component_test.rb.erb +0 -183
  128. data/lib/generators/solidstats/feature/templates/controller.rb.erb +0 -44
  129. data/lib/generators/solidstats/feature/templates/controller_test.rb.erb +0 -111
  130. data/lib/generators/solidstats/feature/templates/detail_view.html.erb +0 -755
  131. data/lib/generators/solidstats/feature/templates/preview.rb.erb +0 -107
  132. data/lib/generators/solidstats/feature/templates/service.rb.erb +0 -132
  133. data/lib/generators/solidstats/feature/templates/service_test.rb.erb +0 -109
  134. data/lib/generators/solidstats/install_generator.rb +0 -109
  135. data/lib/tasks/solidstats_install.rake +0 -133
@@ -1,1403 +0,0 @@
1
-
2
- /* ========================================
3
- SECURITY.CSS CONFLICT OVERRIDE
4
- Override any conflicting styles from security.css
5
- ======================================== */
6
-
7
- /* Ensure the gem metadata page grid is not affected by security.css .gems-container */
8
- .gem-metadata-index .gems-container {
9
- /* Reset any inherited grid properties from security.css */
10
- display: block;
11
- grid-template-columns: unset;
12
- gap: unset;
13
- margin-top: unset;
14
- }
15
-
16
- /* Modern Gem Metadata Index Styles */
17
- .gem-metadata-index {
18
- min-height: 100vh;
19
- background: linear-gradient(135deg, #f8fafc 0%, #e2e8f0 100%);
20
- padding: 2rem;
21
- width: 100%;
22
- max-width: 100%;
23
- box-sizing: border-box;
24
- }
25
-
26
- /* Page Header */
27
- .page-header {
28
- background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
29
- border-radius: 16px;
30
- padding: 2rem;
31
- margin-bottom: 2rem;
32
- color: white;
33
- box-shadow: 0 10px 25px -5px rgba(0, 0, 0, 0.1);
34
- }
35
-
36
- .header-content {
37
- display: flex;
38
- justify-content: space-between;
39
- align-items: center;
40
- }
41
-
42
- .header-title-section {
43
- flex: 1;
44
- }
45
-
46
- .page-title {
47
- font-size: 2rem;
48
- font-weight: 700;
49
- margin: 0 0 0.5rem 0;
50
- display: flex;
51
- align-items: center;
52
- gap: 0.75rem;
53
- }
54
-
55
- .page-icon {
56
- font-size: 2.25rem;
57
- }
58
-
59
- .page-subtitle {
60
- font-size: 1rem;
61
- opacity: 0.9;
62
- font-weight: 400;
63
- }
64
-
65
- .header-actions {
66
- display: flex;
67
- gap: 1rem;
68
- }
69
-
70
- .action-btn {
71
- display: flex;
72
- align-items: center;
73
- gap: 0.5rem;
74
- padding: 0.75rem 1.5rem;
75
- border-radius: 8px;
76
- text-decoration: none;
77
- font-weight: 600;
78
- font-size: 0.875rem;
79
- transition: all 0.2s ease;
80
- border: 1px solid transparent;
81
- }
82
-
83
- .refresh-btn {
84
- background: rgba(255, 255, 255, 0.2);
85
- color: white;
86
- backdrop-filter: blur(10px);
87
- }
88
-
89
- .refresh-btn:hover {
90
- background: rgba(255, 255, 255, 0.3);
91
- color: white;
92
- transform: translateY(-1px);
93
- }
94
-
95
- .refresh-btn.primary {
96
- background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
97
- color: white;
98
- }
99
-
100
- /* Stats Overview */
101
- .stats-overview {
102
- display: grid;
103
- grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
104
- gap: 1.5rem;
105
- margin-bottom: 2rem;
106
- }
107
-
108
- .stat-card {
109
- background: white;
110
- border-radius: 12px;
111
- padding: 1.5rem;
112
- display: flex;
113
- align-items: center;
114
- gap: 1rem;
115
- box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1);
116
- border: 1px solid rgba(0, 0, 0, 0.05);
117
- transition: transform 0.2s ease;
118
- }
119
-
120
- .stat-card:hover {
121
- transform: translateY(-2px);
122
- }
123
-
124
- .stat-icon {
125
- font-size: 2rem;
126
- width: 60px;
127
- height: 60px;
128
- display: flex;
129
- align-items: center;
130
- justify-content: center;
131
- border-radius: 12px;
132
- background: #f8fafc;
133
- }
134
-
135
- .stat-card.total .stat-icon {
136
- background: linear-gradient(135deg, #e0f2fe 0%, #b3e5fc 100%);
137
- }
138
-
139
- .stat-card.outdated .stat-icon {
140
- background: linear-gradient(135deg, #fff3e0 0%, #ffcc02 50%);
141
- }
142
-
143
- .stat-card.up-to-date .stat-icon {
144
- background: linear-gradient(135deg, #e8f5e8 0%, #c8e6c9 100%);
145
- }
146
-
147
- .stat-card.unavailable .stat-icon {
148
- background: linear-gradient(135deg, #fafafa 0%, #eeeeee 100%);
149
- }
150
-
151
- .stat-content {
152
- flex: 1;
153
- }
154
-
155
- .stat-number {
156
- font-size: 2rem;
157
- font-weight: 700;
158
- color: #1f2937;
159
- margin-bottom: 0.25rem;
160
- }
161
-
162
- .stat-label {
163
- font-size: 0.875rem;
164
- color: #6b7280;
165
- font-weight: 500;
166
- }
167
-
168
- /* Search and Filters */
169
- .search-filters {
170
- background: white;
171
- border-radius: 12px;
172
- padding: 1.5rem;
173
- margin-bottom: 2rem;
174
- box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1);
175
- border: 1px solid rgba(0, 0, 0, 0.05);
176
- }
177
-
178
- .search-section {
179
- margin-bottom: 1.5rem;
180
- }
181
-
182
- .search-input-wrapper {
183
- position: relative;
184
- max-width: 400px;
185
- }
186
-
187
- .search-icon {
188
- position: absolute;
189
- left: 1rem;
190
- top: 50%;
191
- transform: translateY(-50%);
192
- color: #9ca3af;
193
- font-size: 0.875rem;
194
- }
195
-
196
- .search-input {
197
- width: 100%;
198
- padding: 0.75rem 1rem 0.75rem 2.5rem;
199
- border: 2px solid #e5e7eb;
200
- border-radius: 8px;
201
- font-size: 0.875rem;
202
- transition: all 0.2s ease;
203
- background: #f9fafb;
204
- }
205
-
206
- .search-input:focus {
207
- outline: none;
208
- border-color: #667eea;
209
- background: white;
210
- box-shadow: 0 0 0 3px rgba(102, 126, 234, 0.1);
211
- }
212
-
213
- .clear-search {
214
- position: absolute;
215
- right: 0.75rem;
216
- top: 50%;
217
- transform: translateY(-50%);
218
- background: none;
219
- border: none;
220
- color: #9ca3af;
221
- cursor: pointer;
222
- padding: 0.25rem;
223
- border-radius: 4px;
224
- transition: color 0.2s ease;
225
- }
226
-
227
- .clear-search:hover {
228
- color: #6b7280;
229
- }
230
-
231
- .filters-section {
232
- display: flex;
233
- flex-wrap: wrap;
234
- gap: 1rem;
235
- align-items: center;
236
- }
237
-
238
- .filter-group {
239
- display: flex;
240
- align-items: center;
241
- gap: 0.5rem;
242
- }
243
-
244
- .filter-label {
245
- font-size: 0.875rem;
246
- font-weight: 600;
247
- color: #374151;
248
- margin: 0;
249
- }
250
-
251
- .filter-select {
252
- padding: 0.5rem 0.75rem;
253
- border: 1px solid #d1d5db;
254
- border-radius: 6px;
255
- font-size: 0.875rem;
256
- background: white;
257
- color: #374151;
258
- cursor: pointer;
259
- transition: border-color 0.2s ease;
260
- }
261
-
262
- .filter-select:focus {
263
- outline: none;
264
- border-color: #667eea;
265
- box-shadow: 0 0 0 3px rgba(102, 126, 234, 0.1);
266
- }
267
-
268
- .reset-filters {
269
- padding: 0.5rem 1rem;
270
- background: #f3f4f6;
271
- border: 1px solid #d1d5db;
272
- border-radius: 6px;
273
- font-size: 0.875rem;
274
- color: #374151;
275
- cursor: pointer;
276
- display: flex;
277
- align-items: center;
278
- gap: 0.5rem;
279
- transition: all 0.2s ease;
280
- }
281
-
282
- .reset-filters:hover {
283
- background: #e5e7eb;
284
- }
285
-
286
- /* View Toggle */
287
- .view-toggle-group {
288
- display: flex;
289
- align-items: center;
290
- gap: 0.75rem;
291
- }
292
-
293
- .view-toggle {
294
- display: flex;
295
- background: #f3f4f6;
296
- border-radius: 8px;
297
- padding: 0.25rem;
298
- border: 1px solid #d1d5db;
299
- }
300
-
301
- .view-toggle-btn {
302
- padding: 0.5rem 0.75rem;
303
- background: transparent;
304
- border: none;
305
- border-radius: 6px;
306
- font-size: 0.875rem;
307
- color: #6b7280;
308
- cursor: pointer;
309
- transition: all 0.2s ease;
310
- display: flex;
311
- align-items: center;
312
- justify-content: center;
313
- min-width: 2.5rem;
314
- }
315
-
316
- .view-toggle-btn:hover {
317
- color: #374151;
318
- background: rgba(255, 255, 255, 0.5);
319
- }
320
-
321
- .view-toggle-btn.active {
322
- background: #667eea;
323
- color: white;
324
- box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
325
- }
326
-
327
- .view-toggle-btn i {
328
- font-size: 0.875rem;
329
- }
330
-
331
- /* Export Button */
332
- .export-group {
333
- display: flex;
334
- align-items: center;
335
- gap: 0.5rem;
336
- }
337
-
338
- .export-btn {
339
- padding: 0.5rem 1rem;
340
- background: linear-gradient(135deg, #10b981 0%, #059669 100%);
341
- color: white;
342
- border: none;
343
- border-radius: 6px;
344
- font-size: 0.875rem;
345
- font-weight: 500;
346
- cursor: pointer;
347
- display: flex;
348
- align-items: center;
349
- gap: 0.5rem;
350
- transition: all 0.2s ease;
351
- }
352
-
353
- .export-btn:hover {
354
- background: linear-gradient(135deg, #059669 0%, #047857 100%);
355
- transform: translateY(-1px);
356
- box-shadow: 0 4px 8px -2px rgba(16, 185, 129, 0.3);
357
- }
358
-
359
- /* ========================================
360
- GEMS DISPLAY LAYOUT - GRID AND TABLE VIEWS
361
- ======================================== */
362
-
363
- /* Main Container for both views */
364
- .gem-metadata-index .gems-container {
365
- width: 100%;
366
- max-width: none;
367
- margin: 0;
368
- padding: 0;
369
- }
370
-
371
- /* ========================================
372
- GRID VIEW - CLEAN REWRITE
373
- Highly specific selectors to avoid conflicts with security.css
374
- ======================================== */
375
-
376
- /* Main grid container for gem metadata */
377
- .gem-metadata-index .gems-container .gems-grid {
378
- display: grid;
379
- grid-template-columns: repeat(auto-fit, minmax(380px, 1fr));
380
- gap: 2rem;
381
- width: 100%;
382
- max-width: 100%;
383
- margin: 0;
384
- padding: 0;
385
- box-sizing: border-box;
386
- grid-auto-rows: auto;
387
-
388
- /* Ensure proper grid flow */
389
- grid-auto-flow: row;
390
- align-items: start;
391
- }
392
-
393
- /* Fallback for when gems-container class is not present */
394
- .gem-metadata-index .gems-grid {
395
- display: grid;
396
- grid-template-columns: repeat(auto-fit, minmax(380px, 1fr));
397
- gap: 2rem;
398
- width: 100%;
399
- max-width: 100%;
400
- margin: 0;
401
- padding: 0;
402
- box-sizing: border-box;
403
- }
404
-
405
- /* Ensure grid is visible when active */
406
- .gem-metadata-index .gems-container .gems-grid:not([style*="display: none"]),
407
- .gem-metadata-index .gems-grid:not([style*="display: none"]) {
408
- display: grid;
409
- }
410
-
411
- /* Gem Card Hover and State Effects */
412
- .gem-card-full:hover {
413
- transform: translateY(-4px);
414
- box-shadow: 0 12px 30px -5px rgba(0, 0, 0, 0.15);
415
- border-color: #d1d5db;
416
- background: white;
417
- }
418
-
419
- .gem-card-full.unavailable {
420
- opacity: 0.7;
421
- background: #f9fafb;
422
- border-color: #e5e7eb;
423
- }
424
-
425
- .gem-card-header {
426
- margin-bottom: 1.25rem;
427
- }
428
-
429
- .gem-title-section {
430
- display: flex;
431
- justify-content: space-between;
432
- align-items: flex-start;
433
- gap: 1rem;
434
- }
435
-
436
- .gem-name {
437
- font-size: 1.25rem;
438
- font-weight: 700;
439
- color: #1f2937;
440
- margin: 0;
441
- flex: 1;
442
- }
443
-
444
- .gem-status-badges {
445
- display: flex;
446
- gap: 0.5rem;
447
- }
448
-
449
- .status-badge {
450
- font-size: 0.75rem;
451
- padding: 0.375rem 0.75rem;
452
- border-radius: 8px;
453
- font-weight: 600;
454
- display: flex;
455
- align-items: center;
456
- gap: 0.375rem;
457
- text-transform: uppercase;
458
- letter-spacing: 0.025em;
459
- }
460
-
461
- .status-badge.upgrade-available {
462
- background: linear-gradient(135deg, #fef3c7 0%, #fcd34d 100%);
463
- color: #d97706;
464
- border: 1px solid #f59e0b;
465
- }
466
-
467
- .status-badge.up-to-date {
468
- background: linear-gradient(135deg, #d1fae5 0%, #a7f3d0 100%);
469
- color: #059669;
470
- border: 1px solid #10b981;
471
- }
472
-
473
- .status-badge.unavailable {
474
- background: linear-gradient(135deg, #f3f4f6 0%, #e5e7eb 100%);
475
- color: #6b7280;
476
- border: 1px solid #d1d5db;
477
- }
478
-
479
- .gem-card-body {
480
- display: flex;
481
- flex-direction: column;
482
- gap: 1.25rem;
483
- }
484
-
485
- .versions-section {
486
- background: white;
487
- border-radius: 8px;
488
- padding: 1rem;
489
- border: 1px solid #f3f4f6;
490
- }
491
-
492
- .version-group {
493
- display: grid;
494
- grid-template-columns: 1fr 1fr;
495
- gap: 1rem;
496
- }
497
-
498
- .version-item {
499
- display: flex;
500
- flex-direction: column;
501
- gap: 0.375rem;
502
- }
503
-
504
- .version-label {
505
- font-size: 0.75rem;
506
- color: #6b7280;
507
- font-weight: 600;
508
- text-transform: uppercase;
509
- letter-spacing: 0.05em;
510
- }
511
-
512
- .version-badge {
513
- font-family: 'SF Mono', Monaco, 'Cascadia Code', 'Roboto Mono', Consolas, 'Courier New', monospace;
514
- font-size: 0.875rem;
515
- padding: 0.5rem 0.75rem;
516
- border-radius: 6px;
517
- font-weight: 600;
518
- text-align: center;
519
- border: 1px solid transparent;
520
- }
521
-
522
- .version-badge.current {
523
- background: linear-gradient(135deg, #dbeafe 0%, #bfdbfe 100%);
524
- color: #1d4ed8;
525
- border-color: #3b82f6;
526
- }
527
-
528
- .version-badge.latest {
529
- background: linear-gradient(135deg, #dcfce7 0%, #bbf7d0 100%);
530
- color: #166534;
531
- border-color: #22c55e;
532
- }
533
-
534
- .version-badge.unknown {
535
- background: #f9fafb;
536
- color: #6b7280;
537
- border-color: #e5e7eb;
538
- }
539
-
540
- .gem-info-section {
541
- display: flex;
542
- flex-direction: column;
543
- gap: 0.75rem;
544
- }
545
-
546
- .release-info, .gem-description {
547
- display: flex;
548
- align-items: flex-start;
549
- gap: 0.5rem;
550
- font-size: 0.875rem;
551
- color: #6b7280;
552
- }
553
-
554
- .gem-description {
555
- line-height: 1.5;
556
- }
557
-
558
- .dependencies-section {
559
- border-top: 1px solid #f3f4f6;
560
- padding-top: 1rem;
561
- }
562
-
563
- .deps-header {
564
- display: flex;
565
- align-items: center;
566
- gap: 0.5rem;
567
- font-size: 0.875rem;
568
- color: #6b7280;
569
- font-weight: 600;
570
- margin-bottom: 0.75rem;
571
- }
572
-
573
- .deps-grid {
574
- display: flex;
575
- flex-wrap: wrap;
576
- gap: 0.5rem;
577
- }
578
-
579
- .dep-badge {
580
- font-size: 0.75rem;
581
- padding: 0.375rem 0.75rem;
582
- border-radius: 8px;
583
- background: #f8fafc;
584
- color: #374151;
585
- font-weight: 500;
586
- border: 1px solid #e5e7eb;
587
- display: flex;
588
- flex-direction: column;
589
- align-items: center;
590
- gap: 0.125rem;
591
- min-width: 60px;
592
- }
593
-
594
- .dep-badge.rails-dep {
595
- background: linear-gradient(135deg, #fef3c7 0%, #fcd34d 100%);
596
- color: #d97706;
597
- border-color: #f59e0b;
598
- font-weight: 700;
599
- }
600
-
601
- .dep-version {
602
- font-size: 0.625rem;
603
- opacity: 0.8;
604
- font-family: 'SF Mono', Monaco, 'Cascadia Code', 'Roboto Mono', Consolas, 'Courier New', monospace;
605
- }
606
-
607
- .dep-more {
608
- font-size: 0.75rem;
609
- color: #6b7280;
610
- font-weight: 600;
611
- cursor: help;
612
- padding: 0.375rem 0.75rem;
613
- border-radius: 8px;
614
- background: #f3f4f6;
615
- border: 1px solid #d1d5db;
616
- }
617
-
618
- .results-info {
619
- text-align: center;
620
- padding: 1rem;
621
- font-size: 0.875rem;
622
- color: #6b7280;
623
- font-weight: 500;
624
- }
625
-
626
- /* Table View */
627
- .table-wrapper {
628
- width: 100%;
629
- }
630
-
631
- .gems-table {
632
- width: 100%;
633
- border-collapse: collapse;
634
- font-size: 0.875rem;
635
- min-width: 100%;
636
- table-layout: auto;
637
- }
638
-
639
- .gems-table thead {
640
- background: linear-gradient(135deg, #f8fafc 0%, #e2e8f0 100%);
641
- }
642
-
643
- .gems-table th {
644
- padding: 1rem 0.75rem;
645
- text-align: left;
646
- font-weight: 600;
647
- color: #374151;
648
- border-bottom: 2px solid #e5e7eb;
649
- position: relative;
650
- }
651
-
652
- .gems-table th.sortable {
653
- cursor: pointer;
654
- user-select: none;
655
- transition: background-color 0.2s ease;
656
- }
657
-
658
- .gems-table th.sortable:hover {
659
- background: rgba(102, 126, 234, 0.1);
660
- }
661
-
662
- .gems-table th.sortable .sort-icon {
663
- margin-left: 0.5rem;
664
- opacity: 0.3;
665
- transition: opacity 0.2s ease;
666
- }
667
-
668
- .gems-table th.sortable:hover .sort-icon {
669
- opacity: 0.7;
670
- }
671
-
672
- .gems-table th.sorted .sort-icon {
673
- opacity: 1;
674
- color: #667eea;
675
- }
676
-
677
- /* Flexible column widths */
678
- .gems-table th:first-child,
679
- .gems-table td:first-child {
680
- width: 20%; /* Gem name */
681
- }
682
-
683
- .gems-table th:nth-child(2),
684
- .gems-table td:nth-child(2) {
685
- width: 15%; /* Status */
686
- }
687
-
688
- .gems-table th:nth-child(3),
689
- .gems-table td:nth-child(3) {
690
- width: 15%; /* Current version */
691
- }
692
-
693
- .gems-table th:nth-child(4),
694
- .gems-table td:nth-child(4) {
695
- width: 15%; /* Latest version */
696
- }
697
-
698
- .gems-table tbody tr {
699
- transition: background-color 0.2s ease;
700
- }
701
-
702
- .gems-table tbody tr:hover {
703
- background: #f8fafc;
704
- }
705
-
706
- .gems-table tbody tr.unavailable {
707
- opacity: 0.6;
708
- background: #f9fafb;
709
- }
710
-
711
- .gems-table td {
712
- padding: 1rem 0.75rem;
713
- border-bottom: 1px solid #f3f4f6;
714
- vertical-align: top;
715
- }
716
-
717
- .gem-name-table {
718
- color: #1f2937;
719
- font-weight: 600;
720
- }
721
-
722
- .status-badge-table {
723
- font-size: 0.75rem;
724
- padding: 0.25rem 0.5rem;
725
- border-radius: 6px;
726
- font-weight: 500;
727
- display: inline-flex;
728
- align-items: center;
729
- gap: 0.25rem;
730
- white-space: nowrap;
731
- }
732
-
733
- .status-badge-table.upgrade-available {
734
- background: #fef3c7;
735
- color: #d97706;
736
- }
737
-
738
- .status-badge-table.up-to-date {
739
- background: #d1fae5;
740
- color: #059669;
741
- }
742
-
743
- .status-badge-table.unavailable {
744
- background: #f3f4f6;
745
- color: #6b7280;
746
- }
747
-
748
- .status-badge-table.unknown {
749
- background: #f3f4f6;
750
- color: #9ca3af;
751
- }
752
-
753
- .version-badge-table {
754
- font-family: 'SF Mono', Monaco, 'Cascadia Code', 'Roboto Mono', Consolas, 'Courier New', monospace;
755
- font-size: 0.8rem;
756
- padding: 0.25rem 0.5rem;
757
- border-radius: 6px;
758
- font-weight: 500;
759
- white-space: nowrap;
760
- }
761
-
762
- .version-badge-table.current {
763
- background: #dbeafe;
764
- color: #1d4ed8;
765
- }
766
-
767
- .version-badge-table.latest {
768
- background: #dcfce7;
769
- color: #166534;
770
- }
771
-
772
- .version-badge-table.unknown {
773
- background: #f3f4f6;
774
- color: #6b7280;
775
- }
776
-
777
- .description-cell {
778
- width: 30%;
779
- word-wrap: break-word;
780
- }
781
-
782
- .dependencies-cell {
783
- width: 25%;
784
- word-wrap: break-word;
785
- }
786
-
787
- .table-deps {
788
- display: flex;
789
- flex-wrap: wrap;
790
- gap: 0.25rem;
791
- }
792
-
793
- .dep-badge-table {
794
- font-size: 0.7rem;
795
- padding: 0.125rem 0.375rem;
796
- border-radius: 4px;
797
- background: #f3f4f6;
798
- color: #374151;
799
- font-weight: 500;
800
- white-space: nowrap;
801
- }
802
-
803
- .dep-badge-table.rails-dep {
804
- background: #fef3c7;
805
- color: #d97706;
806
- font-weight: 600;
807
- }
808
-
809
- .dep-more-table {
810
- font-size: 0.7rem;
811
- color: #6b7280;
812
- font-weight: 500;
813
- cursor: help;
814
- }
815
-
816
- .text-muted {
817
- color: #9ca3af;
818
- }
819
-
820
- /* Empty State */
821
- .empty-state {
822
- text-align: center;
823
- padding: 4rem 2rem;
824
- color: #6b7280;
825
- }
826
-
827
- .empty-icon {
828
- font-size: 4rem;
829
- margin-bottom: 1.5rem;
830
- opacity: 0.5;
831
- }
832
-
833
- .empty-title {
834
- font-size: 1.5rem;
835
- font-weight: 700;
836
- color: #374151;
837
- margin-bottom: 0.75rem;
838
- }
839
-
840
- .empty-description {
841
- margin-bottom: 2rem;
842
- max-width: 500px;
843
- margin-left: auto;
844
- margin-right: auto;
845
- line-height: 1.6;
846
- }
847
-
848
- .empty-actions {
849
- display: flex;
850
- justify-content: center;
851
- gap: 1rem;
852
- }
853
-
854
- /* Filter Empty State - Enhanced centering for table view */
855
- .filter-empty-state {
856
- text-align: center;
857
- padding: 2rem;
858
- color: #6b7280;
859
- display: flex;
860
- flex-direction: column;
861
- justify-content: center;
862
- align-items: center;
863
- width: 100%;
864
- max-width: 500px;
865
- margin: 0 auto;
866
- }
867
-
868
- .filter-empty-state .empty-icon {
869
- font-size: 3rem;
870
- margin-bottom: 1.5rem;
871
- opacity: 0.5;
872
- }
873
-
874
- .filter-empty-state .empty-title {
875
- font-size: 1.25rem;
876
- font-weight: 700;
877
- color: #374151;
878
- margin-bottom: 0.75rem;
879
- }
880
-
881
- .filter-empty-state .empty-description {
882
- margin-bottom: 2rem;
883
- max-width: 400px;
884
- line-height: 1.5;
885
- font-size: 0.9rem;
886
- }
887
-
888
- .filter-empty-state .action-btn {
889
- margin: 0 auto;
890
- }
891
-
892
- /* Empty state responsive adjustments */
893
- @media (max-width: 768px) {
894
- .filter-empty-state {
895
- padding: 1.5rem;
896
- max-width: 90%;
897
- }
898
-
899
- .filter-empty-state .empty-icon {
900
- font-size: 2.5rem;
901
- margin-bottom: 1rem;
902
- }
903
-
904
- .filter-empty-state .empty-title {
905
- font-size: 1.1rem;
906
- }
907
-
908
- .filter-empty-state .empty-description {
909
- font-size: 0.85rem;
910
- max-width: 300px;
911
- }
912
-
913
- .filter-empty-state-row td {
914
- height: 300px;
915
- }
916
-
917
- .empty-state-cell {
918
- height: 300px;
919
- }
920
-
921
- .gems-table-container.has-empty-state {
922
- min-height: 300px;
923
- }
924
- }
925
-
926
- /* Table empty state row */
927
- .filter-empty-state-row {
928
- background: transparent !important;
929
- height: 400px;
930
- }
931
-
932
- .filter-empty-state-row:hover {
933
- background: transparent !important;
934
- }
935
-
936
- .filter-empty-state-row td {
937
- padding: 0 !important;
938
- border: none !important;
939
- text-align: center;
940
- height: 400px;
941
- }
942
-
943
- /* Empty state cell styling */
944
- .empty-state-cell {
945
- position: relative;
946
- height: 400px;
947
- vertical-align: middle;
948
- text-align: center;
949
- }
950
-
951
- /* Additional centering improvements for empty state */
952
- .filter-empty-state-row td.empty-state-cell {
953
- position: relative;
954
- display: table-cell;
955
- vertical-align: middle;
956
- text-align: center;
957
- }
958
-
959
- .empty-state-cell .filter-empty-state {
960
- position: static;
961
- margin: 0 auto;
962
- }
963
-
964
- /* Table container styling with empty state */
965
- .gems-table-container.has-empty-state {
966
- min-height: 400px;
967
- }
968
-
969
- /* Table body styling */
970
- .gems-table {
971
- width: 100%;
972
- border-collapse: collapse;
973
- font-size: 0.875rem;
974
- min-width: 100%;
975
- table-layout: auto;
976
- }
977
-
978
- /* Table container with empty state */
979
- .gems-table-container.has-empty-state {
980
- min-height: 400px;
981
- }
982
-
983
- .gems-table-container.has-empty-state .table-wrapper {
984
- width: 100%;
985
- }
986
-
987
- .gems-table-container.has-empty-state .gems-table {
988
- height: 100%;
989
- width: 100%;
990
- }
991
-
992
- /* Fallback for browsers without :has() support */
993
- .gems-table-container.has-empty-state {
994
- min-height: 400px;
995
- display: flex;
996
- flex-direction: column;
997
- }
998
-
999
- .gems-table-container.has-empty-state .table-wrapper {
1000
- flex: 1;
1001
- display: flex;
1002
- flex-direction: column;
1003
- }
1004
-
1005
- .gems-table-container.has-empty-state .gems-table {
1006
- height: 100%;
1007
- }
1008
-
1009
- /* Page Footer */
1010
- .page-footer {
1011
- background: white;
1012
- border-radius: 12px;
1013
- padding: 1.5rem;
1014
- box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1);
1015
- border: 1px solid rgba(0, 0, 0, 0.05);
1016
- }
1017
-
1018
- .footer-content {
1019
- display: flex;
1020
- justify-content: space-between;
1021
- align-items: center;
1022
- }
1023
-
1024
- .footer-link {
1025
- font-size: 0.875rem;
1026
- color: #6366f1;
1027
- text-decoration: none;
1028
- font-weight: 500;
1029
- display: flex;
1030
- align-items: center;
1031
- gap: 0.5rem;
1032
- transition: color 0.2s ease;
1033
- }
1034
-
1035
- .footer-link:hover {
1036
- color: #4f46e5;
1037
- text-decoration: underline;
1038
- }
1039
-
1040
- .footer-link.external {
1041
- color: #059669;
1042
- }
1043
-
1044
- .footer-link.external:hover {
1045
- color: #047857;
1046
- }
1047
-
1048
- .footer-stats {
1049
- font-size: 0.875rem;
1050
- color: #6b7280;
1051
- }
1052
-
1053
- /* Loading States */
1054
- .refresh-btn.loading {
1055
- opacity: 0.6;
1056
- pointer-events: none;
1057
- }
1058
-
1059
- .refresh-btn.loading i {
1060
- animation: spin 1s linear infinite;
1061
- }
1062
-
1063
- .loading-overlay {
1064
- position: fixed;
1065
- top: 0;
1066
- left: 0;
1067
- right: 0;
1068
- bottom: 0;
1069
- background: rgba(255, 255, 255, 0.9);
1070
- backdrop-filter: blur(4px);
1071
- display: flex;
1072
- align-items: center;
1073
- justify-content: center;
1074
- z-index: 1000;
1075
- }
1076
-
1077
- .loading-content {
1078
- text-align: center;
1079
- padding: 2rem;
1080
- background: white;
1081
- border-radius: 12px;
1082
- box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1);
1083
- border: 1px solid rgba(0, 0, 0, 0.05);
1084
- }
1085
-
1086
- .loading-spinner {
1087
- width: 40px;
1088
- height: 40px;
1089
- border: 3px solid #f3f4f6;
1090
- border-top: 3px solid #667eea;
1091
- border-radius: 50%;
1092
- animation: spin 1s linear infinite;
1093
- margin: 0 auto 1rem auto;
1094
- }
1095
-
1096
- @keyframes spin {
1097
- 0% { transform: rotate(0deg); }
1098
- 100% { transform: rotate(360deg); }
1099
- }
1100
-
1101
- .loading-text {
1102
- color: #6b7280;
1103
- font-weight: 500;
1104
- }
1105
-
1106
- /* Toast Notifications */
1107
- .toast-notification {
1108
- position: fixed;
1109
- top: 20px;
1110
- right: 20px;
1111
- padding: 1rem 1.5rem;
1112
- border-radius: 8px;
1113
- font-weight: 500;
1114
- font-size: 0.875rem;
1115
- box-shadow: 0 10px 25px -5px rgba(0, 0, 0, 0.1);
1116
- transform: translateX(100%);
1117
- transition: transform 0.3s ease;
1118
- z-index: 1001;
1119
- }
1120
-
1121
- .toast-notification.visible {
1122
- transform: translateX(0);
1123
- }
1124
-
1125
- .toast-notification.success {
1126
- background: #10b981;
1127
- color: white;
1128
- }
1129
-
1130
- .toast-notification.error {
1131
- background: #ef4444;
1132
- color: white;
1133
- }
1134
-
1135
- .toast-notification.info {
1136
- background: #3b82f6;
1137
- color: white;
1138
- }
1139
-
1140
- /* ========================================
1141
- RESPONSIVE GRID BREAKPOINTS - CLEAN REWRITE
1142
- ======================================== */
1143
-
1144
- /* Extra large screens: 3+ cards per row (1400px+) */
1145
- @media (min-width: 1400px) {
1146
- .gem-metadata-index .gems-container .gems-grid,
1147
- .gem-metadata-index .gems-grid {
1148
- grid-template-columns: repeat(auto-fit, minmax(400px, 1fr));
1149
- gap: 2.5rem;
1150
- }
1151
- }
1152
-
1153
- /* Large screens: 3 cards per row (1200px - 1399px) */
1154
- @media (min-width: 1200px) and (max-width: 1399px) {
1155
- .gem-metadata-index .gems-container .gems-grid,
1156
- .gem-metadata-index .gems-grid {
1157
- grid-template-columns: repeat(auto-fit, minmax(380px, 1fr));
1158
- gap: 2rem;
1159
- }
1160
- }
1161
-
1162
- /* Medium-large screens: 2-3 cards per row (900px - 1199px) */
1163
- @media (min-width: 900px) and (max-width: 1199px) {
1164
- .gem-metadata-index .gems-container .gems-grid,
1165
- .gem-metadata-index .gems-grid {
1166
- grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
1167
- gap: 1.5rem;
1168
- }
1169
- }
1170
-
1171
- /* Medium screens: 2 cards per row (600px - 899px) */
1172
- @media (min-width: 600px) and (max-width: 899px) {
1173
- .gem-metadata-index .gems-container .gems-grid,
1174
- .gem-metadata-index .gems-grid {
1175
- grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
1176
- gap: 1.5rem;
1177
- }
1178
- }
1179
-
1180
- /* Small screens: 1 card per row (under 600px) */
1181
- @media (max-width: 599px) {
1182
- .gem-metadata-index .gems-container .gems-grid,
1183
- .gem-metadata-index .gems-grid {
1184
- grid-template-columns: 1fr;
1185
- gap: 1rem;
1186
- }
1187
- }
1188
-
1189
- /* Responsive Design */
1190
- @media (max-width: 1024px) {
1191
- .gem-metadata-index {
1192
- padding: 1rem;
1193
- }
1194
- }
1195
-
1196
- @media (max-width: 768px) {
1197
- .header-content {
1198
- flex-direction: column;
1199
- gap: 1.5rem;
1200
- text-align: center;
1201
- }
1202
-
1203
- .page-title {
1204
- font-size: 1.75rem;
1205
- }
1206
-
1207
- .stats-overview {
1208
- grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
1209
- gap: 1rem;
1210
- }
1211
-
1212
- .filters-section {
1213
- flex-direction: column;
1214
- align-items: stretch;
1215
- gap: 1rem;
1216
- }
1217
-
1218
- .filter-group {
1219
- justify-content: space-between;
1220
- }
1221
-
1222
- .gem-title-section {
1223
- flex-direction: column;
1224
- align-items: flex-start;
1225
- gap: 0.75rem;
1226
- }
1227
-
1228
- .version-group {
1229
- grid-template-columns: 1fr;
1230
- }
1231
-
1232
- .footer-content {
1233
- flex-direction: column;
1234
- gap: 1rem;
1235
- text-align: center;
1236
- }
1237
-
1238
- /* Table responsive adjustments */
1239
- .gems-table th,
1240
- .gems-table td {
1241
- padding: 0.75rem 0.5rem;
1242
- font-size: 0.8rem;
1243
- }
1244
-
1245
- .gems-table .description-cell {
1246
- max-width: 150px;
1247
- font-size: 0.75rem;
1248
- }
1249
-
1250
- .gems-table .dependencies-cell {
1251
- max-width: 120px;
1252
- font-size: 0.75rem;
1253
- }
1254
-
1255
- .view-toggle-group {
1256
- flex-direction: column;
1257
- align-items: flex-start;
1258
- gap: 0.5rem;
1259
- }
1260
- }
1261
-
1262
- @media (max-width: 480px) {
1263
- .gem-metadata-index {
1264
- padding: 0.5rem;
1265
- }
1266
-
1267
- .page-header {
1268
- padding: 1.5rem;
1269
- }
1270
-
1271
- .stats-overview {
1272
- grid-template-columns: repeat(2, 1fr);
1273
- }
1274
-
1275
- .stat-card {
1276
- padding: 1rem;
1277
- }
1278
-
1279
- .stat-icon {
1280
- width: 50px;
1281
- height: 50px;
1282
- font-size: 1.5rem;
1283
- }
1284
-
1285
- .stat-number {
1286
- font-size: 1.5rem;
1287
- }
1288
- }
1289
-
1290
- /* Very narrow mobile - hide some columns only when necessary */
1291
- @media (max-width: 400px) {
1292
- .gems-table .description-cell,
1293
- .gems-table .dependencies-cell {
1294
- display: none;
1295
- }
1296
- }
1297
-
1298
- /* Accessibility Improvements */
1299
- @media (prefers-reduced-motion: reduce) {
1300
- .gem-card-full,
1301
- .action-btn,
1302
- .stat-card {
1303
- animation: none;
1304
- transition: none;
1305
- }
1306
- }
1307
-
1308
- /* Focus States */
1309
- .action-btn:focus,
1310
- .search-input:focus,
1311
- .filter-select:focus,
1312
- .reset-filters:focus,
1313
- .footer-link:focus {
1314
- outline: 2px solid #667eea;
1315
- outline-offset: 2px;
1316
- }
1317
-
1318
- /* Print Styles */
1319
- @media print {
1320
- .page-header,
1321
- .search-filters,
1322
- .page-footer {
1323
- display: none;
1324
- }
1325
-
1326
- .gem-metadata-index {
1327
- background: white;
1328
- padding: 0;
1329
- }
1330
-
1331
- .gem-metadata-index .gems-grid {
1332
- grid-template-columns: 1fr;
1333
- }
1334
-
1335
- .gem-card-full {
1336
- box-shadow: none;
1337
- border: 1px solid #ccc;
1338
- break-inside: avoid;
1339
- }
1340
- }
1341
-
1342
- /* ========================================
1343
- GEM CARD STYLING FOR GRID VIEW - CLEAN REWRITE
1344
- ======================================== */
1345
-
1346
- /* Primary gem card styling with specific selectors */
1347
- .gem-metadata-index .gems-container .gems-grid .gem-card-full,
1348
- .gem-metadata-index .gems-grid .gem-card-full {
1349
- /* Layout and sizing */
1350
- width: 100%;
1351
- max-width: 100%;
1352
- min-width: 0;
1353
- box-sizing: border-box;
1354
-
1355
- /* Card appearance */
1356
- background: white;
1357
- border: 1px solid #e5e7eb;
1358
- border-radius: 12px;
1359
- padding: 1.5rem;
1360
-
1361
- /* Display properties */
1362
- display: flex;
1363
- flex-direction: column;
1364
- justify-content: flex-start;
1365
- align-items: stretch;
1366
-
1367
- /* Effects and animations */
1368
- transition: all 0.3s ease;
1369
- box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1);
1370
- animation: fadeInUp 0.6s ease-out both;
1371
- }
1372
-
1373
- /* Hover effects for gem cards */
1374
- .gem-metadata-index .gems-container .gems-grid .gem-card-full:hover,
1375
- .gem-metadata-index .gems-grid .gem-card-full:hover {
1376
- transform: translateY(-4px);
1377
- box-shadow: 0 12px 30px -5px rgba(0, 0, 0, 0.15);
1378
- border-color: #d1d5db;
1379
- background: white;
1380
- }
1381
-
1382
- /* Unavailable gem cards */
1383
- .gem-metadata-index .gems-container .gems-grid .gem-card-full.unavailable,
1384
- .gem-metadata-index .gems-grid .gem-card-full.unavailable {
1385
- opacity: 0.7;
1386
- background: #f9fafb;
1387
- border-color: #e5e7eb;
1388
- }
1389
-
1390
- /* ========================================
1391
- ANIMATIONS
1392
- ======================================== */
1393
-
1394
- @keyframes fadeInUp {
1395
- from {
1396
- opacity: 0;
1397
- transform: translateY(20px);
1398
- }
1399
- to {
1400
- opacity: 1;
1401
- transform: translateY(0);
1402
- }
1403
- }