rails_nexus 2.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 (114) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.md +430 -0
  4. data/Rakefile +6 -0
  5. data/app/assets/config/rails_nexus_manifest.js +2 -0
  6. data/app/assets/javascripts/rails_nexus/controllers.js +603 -0
  7. data/app/assets/stylesheets/rails_nexus/application.css +1964 -0
  8. data/app/controllers/rails_nexus/analytics_controller.rb +361 -0
  9. data/app/controllers/rails_nexus/application_controller.rb +15 -0
  10. data/app/controllers/rails_nexus/backup_controller.rb +91 -0
  11. data/app/controllers/rails_nexus/cron_jobs_controller.rb +64 -0
  12. data/app/controllers/rails_nexus/database_health_controller.rb +128 -0
  13. data/app/controllers/rails_nexus/logged_exceptions_controller.rb +227 -0
  14. data/app/controllers/rails_nexus/n1_patterns_controller.rb +10 -0
  15. data/app/controllers/rails_nexus/settings_controller.rb +100 -0
  16. data/app/controllers/rails_nexus/source_code_controller.rb +39 -0
  17. data/app/controllers/rails_nexus/stats_controller.rb +494 -0
  18. data/app/controllers/rails_nexus/workflow_controller.rb +96 -0
  19. data/app/helpers/rails_nexus/application_helper.rb +5 -0
  20. data/app/helpers/rails_nexus/logged_exceptions_helper.rb +254 -0
  21. data/app/helpers/rails_nexus/source_code_helper.rb +107 -0
  22. data/app/javascript/controllers/rails_nexus_controller.js +380 -0
  23. data/app/javascript/controllers/rails_nexus_detail_controller.js +165 -0
  24. data/app/javascript/controllers/rails_nexus_sidebar_controller.js +15 -0
  25. data/app/javascript/controllers/rails_nexus_theme_controller.js +31 -0
  26. data/app/javascript/rails_nexus/application.js +17 -0
  27. data/app/jobs/rails_nexus/application_job.rb +4 -0
  28. data/app/mailers/rails_nexus/application_mailer.rb +6 -0
  29. data/app/models/rails_nexus/application_record.rb +5 -0
  30. data/app/models/rails_nexus/backup.rb +107 -0
  31. data/app/models/rails_nexus/base_record.rb +26 -0
  32. data/app/models/rails_nexus/comment.rb +13 -0
  33. data/app/models/rails_nexus/cron_job.rb +72 -0
  34. data/app/models/rails_nexus/database_stat.rb +128 -0
  35. data/app/models/rails_nexus/event.rb +101 -0
  36. data/app/models/rails_nexus/logged_exception.rb +864 -0
  37. data/app/models/rails_nexus/logged_exception_n1.rb +87 -0
  38. data/app/models/rails_nexus/metric.rb +107 -0
  39. data/app/models/rails_nexus/nginx_metric.rb +112 -0
  40. data/app/models/rails_nexus/server_metric.rb +168 -0
  41. data/app/models/rails_nexus/webhook_delivery.rb +64 -0
  42. data/app/services/rails_nexus/backup_service.rb +275 -0
  43. data/app/views/layouts/rails_nexus/application.html.erb +185 -0
  44. data/app/views/rails_nexus/analytics/index.html.erb +363 -0
  45. data/app/views/rails_nexus/backup/files.html.erb +53 -0
  46. data/app/views/rails_nexus/backup/index.html.erb +211 -0
  47. data/app/views/rails_nexus/backup/settings.html.erb +158 -0
  48. data/app/views/rails_nexus/cron_jobs/index.html.erb +141 -0
  49. data/app/views/rails_nexus/database_health/index.html.erb +139 -0
  50. data/app/views/rails_nexus/logged_exceptions/_comments_list.html.erb +50 -0
  51. data/app/views/rails_nexus/logged_exceptions/_exceptions.html.erb +190 -0
  52. data/app/views/rails_nexus/logged_exceptions/_feed.html.erb +3 -0
  53. data/app/views/rails_nexus/logged_exceptions/_filter_group.html.erb +10 -0
  54. data/app/views/rails_nexus/logged_exceptions/_show.html.erb +554 -0
  55. data/app/views/rails_nexus/logged_exceptions/_workflow_panel.html.erb +118 -0
  56. data/app/views/rails_nexus/logged_exceptions/clear.turbo_stream.erb +6 -0
  57. data/app/views/rails_nexus/logged_exceptions/destroy.turbo_stream.erb +2 -0
  58. data/app/views/rails_nexus/logged_exceptions/destroy_all.turbo_stream.erb +6 -0
  59. data/app/views/rails_nexus/logged_exceptions/feed.rss.builder +20 -0
  60. data/app/views/rails_nexus/logged_exceptions/index.html.erb +323 -0
  61. data/app/views/rails_nexus/logged_exceptions/query.html.erb +3 -0
  62. data/app/views/rails_nexus/logged_exceptions/query.turbo_stream.erb +6 -0
  63. data/app/views/rails_nexus/logged_exceptions/show.html.erb +3 -0
  64. data/app/views/rails_nexus/logged_exceptions/show.turbo_stream.erb +5 -0
  65. data/app/views/rails_nexus/n1_patterns/index.html.erb +153 -0
  66. data/app/views/rails_nexus/settings/index.html.erb +140 -0
  67. data/app/views/rails_nexus/stats/index.html.erb +569 -0
  68. data/config/importmap.rb +15 -0
  69. data/config/initializers/date_formats.rb +5 -0
  70. data/config/initializers/rails_nexus.rb +18 -0
  71. data/config/locales/en.yml +47 -0
  72. data/config/routes.rb +58 -0
  73. data/db/migrate/20240330122311_create_rails_nexus_logged_exceptions.rb +22 -0
  74. data/lib/generators/rails_nexus/backup_generator.rb +70 -0
  75. data/lib/generators/rails_nexus/customize_generator.rb +159 -0
  76. data/lib/generators/rails_nexus/install_generator.rb +61 -0
  77. data/lib/generators/rails_nexus/templates/INSTALL.md +9 -0
  78. data/lib/generators/rails_nexus/templates/backup/backup_helper.sh +152 -0
  79. data/lib/generators/rails_nexus/templates/backup/config.rb +27 -0
  80. data/lib/generators/rails_nexus/templates/backup/models/daily_backup.rb +24 -0
  81. data/lib/generators/rails_nexus/templates/backup/models/full_backup.rb +35 -0
  82. data/lib/generators/rails_nexus/templates/backup/models/sync_backup.rb +43 -0
  83. data/lib/generators/rails_nexus/templates/backup/mysql-config/db_config.cnf +15 -0
  84. data/lib/generators/rails_nexus/templates/backup/schedule.rb +28 -0
  85. data/lib/generators/rails_nexus/templates/javascript/controllers/rails_nexus_controller.js +310 -0
  86. data/lib/generators/rails_nexus/templates/javascript/controllers/rails_nexus_detail_controller.js +98 -0
  87. data/lib/generators/rails_nexus/templates/javascript/controllers/rails_nexus_sidebar_controller.js +15 -0
  88. data/lib/generators/rails_nexus/templates/javascript/controllers/rails_nexus_theme_controller.js +30 -0
  89. data/lib/generators/rails_nexus/templates/migration.rb +24 -0
  90. data/lib/generators/rails_nexus/templates/migration_advanced_features.rb +30 -0
  91. data/lib/generators/rails_nexus/templates/migration_cron_jobs.rb +22 -0
  92. data/lib/generators/rails_nexus/templates/migration_new_schema.rb +120 -0
  93. data/lib/generators/rails_nexus/templates/migration_platform_detection.rb +11 -0
  94. data/lib/generators/rails_nexus/templates/migration_webhook_deliveries.rb +21 -0
  95. data/lib/generators/rails_nexus/templates/migration_workflow.rb +29 -0
  96. data/lib/generators/rails_nexus/templates/rails_nexus.rb +96 -0
  97. data/lib/generators/rails_nexus/templates/views/layouts/rails_nexus/application.html.erb +129 -0
  98. data/lib/generators/rails_nexus/templates/views/rails_nexus/logged_exceptions/_exceptions.html.erb +123 -0
  99. data/lib/generators/rails_nexus/templates/views/rails_nexus/logged_exceptions/_show.html.erb +297 -0
  100. data/lib/generators/rails_nexus/templates/views/rails_nexus/logged_exceptions/index.html.erb +113 -0
  101. data/lib/rails_nexus/breadcrumbs.rb +161 -0
  102. data/lib/rails_nexus/cleanup.rb +32 -0
  103. data/lib/rails_nexus/configuration.rb +319 -0
  104. data/lib/rails_nexus/engine.rb +135 -0
  105. data/lib/rails_nexus/logger.rb +188 -0
  106. data/lib/rails_nexus/notifications.rb +105 -0
  107. data/lib/rails_nexus/ransack_config.rb +4 -0
  108. data/lib/rails_nexus/storm_protection.rb +124 -0
  109. data/lib/rails_nexus/version.rb +3 -0
  110. data/lib/rails_nexus.rb +133 -0
  111. data/lib/tasks/rails_nexus.rake +230 -0
  112. data/lib/tasks/rails_nexus_tasks.rake +37 -0
  113. data/rails_nexus.gemspec +36 -0
  114. metadata +252 -0
@@ -0,0 +1,1964 @@
1
+ /* RailsNexus Dashboard - Tailwind CSS with fallbacks */
2
+ /* If Tailwind is loaded, these utilities take precedence. */
3
+ /* If Tailwind is NOT loaded, these fallback styles provide the UI. */
4
+
5
+ /* ═══════════════════════════════════════════════════════════════════
6
+ FALLBACK STYLES (used when Tailwind CSS is NOT available)
7
+ ═══════════════════════════════════════════════════════════════════ */
8
+
9
+ :root {
10
+ --rn-primary: #4f46e5;
11
+ --rn-primary-hover: #4338ca;
12
+ --rn-bg: #f8fafc;
13
+ --rn-surface: #ffffff;
14
+ --rn-border: #e2e8f0;
15
+ --rn-text: #0f172a;
16
+ --rn-text-secondary: #64748b;
17
+ --rn-text-muted: #94a3b8;
18
+ --rn-danger: #dc2626;
19
+ --rn-danger-hover: #b91c1c;
20
+ --rn-danger-bg: #fef2f2;
21
+ --rn-radius: 0.75rem;
22
+ --rn-radius-sm: 0.5rem;
23
+ }
24
+
25
+ /* Base reset */
26
+ *, *::before, *::after { box-sizing: border-box; }
27
+ body { margin: 0; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif; line-height: 1.5; color: var(--rn-text); background: var(--rn-bg); }
28
+ a { color: var(--rn-primary); text-decoration: none; }
29
+ a:hover { text-decoration: underline; }
30
+ h1, h2, h3, h4, p { margin: 0; }
31
+ table { border-collapse: collapse; width: 100%; }
32
+
33
+ /* ─── Tailwind-like Utility Classes ─────────────────────────── */
34
+
35
+ /* Display */
36
+ .hidden { display: none !important; }
37
+ .block { display: block; }
38
+ .inline-block { display: inline-block; }
39
+ .flex { display: flex; }
40
+ .inline-flex { display: inline-flex; }
41
+ .grid { display: grid; }
42
+ .table { display: table; }
43
+ .list-item { display: list-item; }
44
+
45
+ /* Flexbox */
46
+ .flex-1 { flex: 1 1 0%; }
47
+ .flex-col { flex-direction: column; }
48
+ .flex-wrap { flex-wrap: wrap; }
49
+ .items-start { align-items: flex-start; }
50
+ .items-center { align-items: center; }
51
+ .items-end { align-items: flex-end; }
52
+ .items-stretch { align-items: stretch; }
53
+ .justify-start { justify-content: flex-start; }
54
+ .justify-center { justify-content: center; }
55
+ .justify-end { justify-content: flex-end; }
56
+ .justify-between { justify-content: space-between; }
57
+ .flex-shrink-0 { flex-shrink: 0; }
58
+ .shrink-0 { flex-shrink: 0; }
59
+ .grow { flex-grow: 1; }
60
+
61
+ /* Gap */
62
+ .gap-0\.5 { gap: 0.125rem; }
63
+ .gap-1 { gap: 0.25rem; }
64
+ .gap-1\.5 { gap: 0.375rem; }
65
+ .gap-2 { gap: 0.5rem; }
66
+ .gap-2\.5 { gap: 0.625rem; }
67
+ .gap-3 { gap: 0.75rem; }
68
+ .gap-4 { gap: 1rem; }
69
+ .gap-5 { gap: 1.25rem; }
70
+ .gap-6 { gap: 1.5rem; }
71
+ .gap-8 { gap: 2rem; }
72
+
73
+ /* Width */
74
+ .w-3 { width: 0.75rem; }
75
+ .w-3\.5 { width: 0.875rem; }
76
+ .w-4 { width: 1rem; }
77
+ .w-5 { width: 1.25rem; }
78
+ .w-6 { width: 1.5rem; }
79
+ .w-8 { width: 2rem; }
80
+ .w-10 { width: 2.5rem; }
81
+ .w-12 { width: 3rem; }
82
+ .w-16 { width: 4rem; }
83
+ .w-20 { width: 5rem; }
84
+ .w-24 { width: 6rem; }
85
+ .w-32 { width: 8rem; }
86
+ .w-40 { width: 10rem; }
87
+ .w-48 { width: 12rem; }
88
+ .w-56 { width: 14rem; }
89
+ .w-64 { width: 16rem; }
90
+ .w-auto { width: auto; }
91
+ .w-full { width: 100%; }
92
+ .w-screen { width: 100vw; }
93
+ .min-w-0 { min-width: 0; }
94
+ .max-w-xs { max-width: 20rem; }
95
+ .max-w-sm { max-width: 24rem; }
96
+ .max-w-md { max-width: 28rem; }
97
+ .max-w-lg { max-width: 32rem; }
98
+ .max-w-xl { max-width: 36rem; }
99
+ .max-w-2xl { max-width: 42rem; }
100
+ .max-w-4xl { max-width: 56rem; }
101
+ .max-w-full { max-width: 100%; }
102
+
103
+ /* Height */
104
+ .h-3 { height: 0.75rem; }
105
+ .h-3\.5 { height: 0.875rem; }
106
+ .h-4 { height: 1rem; }
107
+ .h-5 { height: 1.25rem; }
108
+ .h-6 { height: 1.5rem; }
109
+ .h-8 { height: 2rem; }
110
+ .h-10 { height: 2.5rem; }
111
+ .h-12 { height: 3rem; }
112
+ .h-16 { height: 4rem; }
113
+ .h-20 { height: 5rem; }
114
+ .h-24 { height: 6rem; }
115
+ .h-32 { height: 8rem; }
116
+ .h-40 { height: 10rem; }
117
+ .h-48 { height: 12rem; }
118
+ .h-56 { height: 14rem; }
119
+ .h-64 { height: 16rem; }
120
+ .h-auto { height: auto; }
121
+ .h-full { height: 100%; }
122
+ .h-screen { height: 100vh; }
123
+ .min-h-full { min-height: 100%; }
124
+ .max-h-48 { max-height: 12rem; }
125
+ .max-h-64 { max-height: 16rem; }
126
+ .max-h-96 { max-height: 24rem; }
127
+ .max-h-full { max-height: 100%; }
128
+
129
+ /* Padding */
130
+ .p-0 { padding: 0; }
131
+ .p-1 { padding: 0.25rem; }
132
+ .p-1\.5 { padding: 0.375rem; }
133
+ .p-2 { padding: 0.5rem; }
134
+ .p-2\.5 { padding: 0.625rem; }
135
+ .p-3 { padding: 0.75rem; }
136
+ .p-4 { padding: 1rem; }
137
+ .p-5 { padding: 1.25rem; }
138
+ .p-6 { padding: 1.5rem; }
139
+ .p-8 { padding: 2rem; }
140
+ .px-1 { padding-left: 0.25rem; padding-right: 0.25rem; }
141
+ .px-1\.5 { padding-left: 0.375rem; padding-right: 0.375rem; }
142
+ .px-2 { padding-left: 0.5rem; padding-right: 0.5rem; }
143
+ .px-3 { padding-left: 0.75rem; padding-right: 0.75rem; }
144
+ .px-4 { padding-left: 1rem; padding-right: 1rem; }
145
+ .px-5 { padding-left: 1.25rem; padding-right: 1.25rem; }
146
+ .px-6 { padding-left: 1.5rem; padding-right: 1.5rem; }
147
+ .px-8 { padding-left: 2rem; padding-right: 2rem; }
148
+ .py-0 { padding-top: 0; padding-bottom: 0; }
149
+ .py-1 { padding-top: 0.25rem; padding-bottom: 0.25rem; }
150
+ .py-1\.5 { padding-top: 0.375rem; padding-bottom: 0.375rem; }
151
+ .py-2 { padding-top: 0.5rem; padding-bottom: 0.5rem; }
152
+ .py-2\.5 { padding-top: 0.625rem; padding-bottom: 0.625rem; }
153
+ .py-3 { padding-top: 0.75rem; padding-bottom: 0.75rem; }
154
+ .py-4 { padding-top: 1rem; padding-bottom: 1rem; }
155
+ .py-6 { padding-top: 1.5rem; padding-bottom: 1.5rem; }
156
+ .py-8 { padding-top: 2rem; padding-bottom: 2rem; }
157
+ .py-12 { padding-top: 3rem; padding-bottom: 3rem; }
158
+ .py-16 { padding-top: 4rem; padding-bottom: 4rem; }
159
+ .pt-0 { padding-top: 0; }
160
+ .pt-1 { padding-top: 0.25rem; }
161
+ .pt-2 { padding-top: 0.5rem; }
162
+ .pt-3 { padding-top: 0.75rem; }
163
+ .pt-4 { padding-top: 1rem; }
164
+ .pt-6 { padding-top: 1.5rem; }
165
+ .pb-0 { padding-bottom: 0; }
166
+ .pb-1 { padding-bottom: 0.25rem; }
167
+ .pb-2 { padding-bottom: 0.5rem; }
168
+ .pb-3 { padding-bottom: 0.75rem; }
169
+ .pb-4 { padding-bottom: 1rem; }
170
+ .pl-1 { padding-left: 0.25rem; }
171
+ .pl-2 { padding-left: 0.5rem; }
172
+ .pl-3 { padding-left: 0.75rem; }
173
+ .pl-4 { padding-left: 1rem; }
174
+ .pr-1 { padding-right: 0.25rem; }
175
+ .pr-2 { padding-right: 0.5rem; }
176
+ .pr-3 { padding-right: 0.75rem; }
177
+ .pr-4 { padding-right: 1rem; }
178
+
179
+ /* Margin */
180
+ .m-0 { margin: 0; }
181
+ .m-1 { margin: 0.25rem; }
182
+ .m-2 { margin: 0.5rem; }
183
+ .m-4 { margin: 1rem; }
184
+ .mx-0 { margin-left: 0; margin-right: 0; }
185
+ .mx-1 { margin-left: 0.25rem; margin-right: 0.25rem; }
186
+ .mx-2 { margin-left: 0.5rem; margin-right: 0.5rem; }
187
+ .mx-3 { margin-left: 0.75rem; margin-right: 0.75rem; }
188
+ .mx-4 { margin-left: 1rem; margin-right: 1rem; }
189
+ .mx-6 { margin-left: 1.5rem; margin-right: 1.5rem; }
190
+ .mx-auto { margin-left: auto; margin-right: auto; }
191
+ .my-0 { margin-top: 0; margin-bottom: 0; }
192
+ .my-1 { margin-top: 0.25rem; margin-bottom: 0.25rem; }
193
+ .my-2 { margin-top: 0.5rem; margin-bottom: 0.5rem; }
194
+ .my-4 { margin-top: 1rem; margin-bottom: 1rem; }
195
+ .mt-0 { margin-top: 0; }
196
+ .mt-0\.5 { margin-top: 0.125rem; }
197
+ .mt-1 { margin-top: 0.25rem; }
198
+ .mt-1\.5 { margin-top: 0.375rem; }
199
+ .mt-2 { margin-top: 0.5rem; }
200
+ .mt-3 { margin-top: 0.75rem; }
201
+ .mt-4 { margin-top: 1rem; }
202
+ .mt-6 { margin-top: 1.5rem; }
203
+ .mt-8 { margin-top: 2rem; }
204
+ .mt-10 { margin-top: 2.5rem; }
205
+ .mt-12 { margin-top: 3rem; }
206
+ .mt-16 { margin-top: 4rem; }
207
+ .mb-0 { margin-bottom: 0; }
208
+ .mb-1 { margin-bottom: 0.25rem; }
209
+ .mb-2 { margin-bottom: 0.5rem; }
210
+ .mb-3 { margin-bottom: 0.75rem; }
211
+ .mb-4 { margin-bottom: 1rem; }
212
+ .mb-6 { margin-bottom: 1.5rem; }
213
+ .mb-8 { margin-bottom: 2rem; }
214
+ .ml-0 { margin-left: 0; }
215
+ .ml-1 { margin-left: 0.25rem; }
216
+ .ml-2 { margin-left: 0.5rem; }
217
+ .ml-3 { margin-left: 0.75rem; }
218
+ .ml-4 { margin-left: 1rem; }
219
+ .ml-auto { margin-left: auto; }
220
+ .mr-0 { margin-right: 0; }
221
+ .mr-1 { margin-right: 0.25rem; }
222
+ .mr-2 { margin-right: 0.5rem; }
223
+ .mr-3 { margin-right: 0.75rem; }
224
+ .mr-4 { margin-right: 1rem; }
225
+ .-ml-1 { margin-left: -0.25rem; }
226
+ .-ml-2 { margin-left: -0.5rem; }
227
+ .-mt-1 { margin-top: -0.25rem; }
228
+ .-mt-2 { margin-top: -0.5rem; }
229
+ .-mr-1 { margin-right: -0.25rem; }
230
+ .-mb-1 { margin-bottom: -0.25rem; }
231
+
232
+ /* Border Radius */
233
+ .rounded { border-radius: 0.25rem; }
234
+ .rounded-sm { border-radius: 0.125rem; }
235
+ .rounded-md { border-radius: 0.375rem; }
236
+ .rounded-lg { border-radius: 0.5rem; }
237
+ .rounded-xl { border-radius: 0.75rem; }
238
+ .rounded-2xl { border-radius: 1rem; }
239
+ .rounded-3xl { border-radius: 1.5rem; }
240
+ .rounded-full { border-radius: 9999px; }
241
+ .rounded-t-lg { border-top-left-radius: 0.5rem; border-top-right-radius: 0.5rem; }
242
+ .rounded-b-lg { border-bottom-left-radius: 0.5rem; border-bottom-right-radius: 0.5rem; }
243
+
244
+ /* Border */
245
+ .border { border: 1px solid var(--rn-border); }
246
+ .border-0 { border-width: 0; }
247
+ .border-2 { border-width: 2px; }
248
+ .border-t { border-top: 1px solid var(--rn-border); }
249
+ .border-b { border-bottom: 1px solid var(--rn-border); }
250
+ .border-l { border-left: 1px solid var(--rn-border); }
251
+ .border-r { border-right: 1px solid var(--rn-border); }
252
+ .border-t-2 { border-top-width: 2px; }
253
+ .border-b-2 { border-bottom-width: 2px; }
254
+
255
+ /* Text */
256
+ .text-xs { font-size: 0.75rem; line-height: 1rem; }
257
+ .text-sm { font-size: 0.875rem; line-height: 1.25rem; }
258
+ .text-base { font-size: 1rem; line-height: 1.5rem; }
259
+ .text-lg { font-size: 1.125rem; line-height: 1.75rem; }
260
+ .text-xl { font-size: 1.25rem; line-height: 1.75rem; }
261
+ .text-2xl { font-size: 1.5rem; line-height: 2rem; }
262
+ .text-3xl { font-size: 1.875rem; line-height: 2.25rem; }
263
+ .text-4xl { font-size: 2.25rem; line-height: 2.5rem; }
264
+ .text-5xl { font-size: 3rem; line-height: 1; }
265
+ .text-6xl { font-size: 3.75rem; line-height: 1; }
266
+ .text-7xl { font-size: 4.5rem; line-height: 1; }
267
+ .text-8xl { font-size: 6rem; line-height: 1; }
268
+ .text-9xl { font-size: 8rem; line-height: 1; }
269
+ .font-thin { font-weight: 100; }
270
+ .font-extralight { font-weight: 200; }
271
+ .font-light { font-weight: 300; }
272
+ .font-normal { font-weight: 400; }
273
+ .font-medium { font-weight: 500; }
274
+ .font-semibold { font-weight: 600; }
275
+ .font-bold { font-weight: 700; }
276
+ .font-extrabold { font-weight: 800; }
277
+ .font-black { font-weight: 900; }
278
+ .tracking-tight { letter-spacing: -0.025em; }
279
+ .tracking-normal { letter-spacing: 0; }
280
+ .tracking-wide { letter-spacing: 0.025em; }
281
+ .tracking-wider { letter-spacing: 0.05em; }
282
+ .tracking-widest { letter-spacing: 0.1em; }
283
+ .uppercase { text-transform: uppercase; }
284
+ .lowercase { text-transform: lowercase; }
285
+ .capitalize { text-transform: capitalize; }
286
+ .normal-case { text-transform: none; }
287
+ .leading-none { line-height: 1; }
288
+ .leading-tight { line-height: 1.25; }
289
+ .leading-snug { line-height: 1.375; }
290
+ .leading-normal { line-height: 1.5; }
291
+ .leading-relaxed { line-height: 1.625; }
292
+ .leading-loose { line-height: 2; }
293
+ .truncate { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
294
+ .text-left { text-align: left; }
295
+ .text-center { text-align: center; }
296
+ .text-right { text-align: right; }
297
+ .text-justify { text-align: justify; }
298
+ .no-underline { text-decoration: none; }
299
+ .underline { text-decoration: underline; }
300
+ .line-through { text-decoration: line-through; }
301
+
302
+ /* Overflow */
303
+ .overflow-hidden { overflow: hidden; }
304
+ .overflow-auto { overflow: auto; }
305
+ .overflow-scroll { overflow: scroll; }
306
+ .overflow-x-auto { overflow-x: auto; }
307
+ .overflow-x-hidden { overflow-x: hidden; }
308
+ .overflow-x-scroll { overflow-x: scroll; }
309
+ .overflow-y-auto { overflow-y: auto; }
310
+ .overflow-y-hidden { overflow-y: hidden; }
311
+ .overflow-y-scroll { overflow-y: scroll; }
312
+ .overflow-visible { overflow: visible; }
313
+
314
+ /* Position */
315
+ .static { position: static; }
316
+ .fixed { position: fixed; }
317
+ .absolute { position: absolute; }
318
+ .relative { position: relative; }
319
+ .sticky { position: sticky; }
320
+ .inset-0 { top: 0; right: 0; bottom: 0; left: 0; }
321
+ .inset-y-0 { top: 0; bottom: 0; }
322
+ .top-0 { top: 0; }
323
+ .right-0 { right: 0; }
324
+ .bottom-0 { bottom: 0; }
325
+ .left-0 { left: 0; }
326
+ .inset-x-0 { left: 0; right: 0; }
327
+
328
+ /* Z-Index */
329
+ .z-0 { z-index: 0; }
330
+ .z-10 { z-index: 10; }
331
+ .z-20 { z-index: 20; }
332
+ .z-30 { z-index: 30; }
333
+ .z-40 { z-index: 40; }
334
+ .z-50 { z-index: 50; }
335
+ .z-auto { z-index: auto; }
336
+
337
+ /* Shadow */
338
+ .shadow-none { box-shadow: none; }
339
+ .shadow-sm { box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.05); }
340
+ .shadow { box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px -1px rgba(0, 0, 0, 0.1); }
341
+ .shadow-md { box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -2px rgba(0, 0, 0, 0.1); }
342
+ .shadow-lg { box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -4px rgba(0, 0, 0, 0.1); }
343
+ .shadow-xl { box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 8px 10px -6px rgba(0, 0, 0, 0.1); }
344
+ .shadow-2xl { box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.25); }
345
+ .shadow-inner { box-shadow: inset 0 2px 4px 0 rgba(0, 0, 0, 0.05); }
346
+ .shadow-none { box-shadow: 0 0 #0000; }
347
+
348
+ /* Opacity */
349
+ .opacity-0 { opacity: 0; }
350
+ .opacity-5 { opacity: 0.05; }
351
+ .opacity-10 { opacity: 0.1; }
352
+ .opacity-15 { opacity: 0.15; }
353
+ .opacity-20 { opacity: 0.2; }
354
+ .opacity-25 { opacity: 0.25; }
355
+ .opacity-30 { opacity: 0.3; }
356
+ .opacity-40 { opacity: 0.4; }
357
+ .opacity-50 { opacity: 0.5; }
358
+ .opacity-60 { opacity: 0.6; }
359
+ .opacity-70 { opacity: 0.7; }
360
+ .opacity-75 { opacity: 0.75; }
361
+ .opacity-80 { opacity: 0.8; }
362
+ .opacity-90 { opacity: 0.9; }
363
+ .opacity-95 { opacity: 0.95; }
364
+ .opacity-100 { opacity: 1; }
365
+
366
+ /* Transition */
367
+ .transition-none { transition-property: none; }
368
+ .transition-all { transition-property: all; transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); transition-duration: 150ms; }
369
+ .transition { transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter; transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); transition-duration: 150ms; }
370
+ .transition-colors { transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter; transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); transition-duration: 150ms; }
371
+ .transition-opacity { transition-property: opacity; transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); transition-duration: 150ms; }
372
+ .transition-transform { transition-property: transform; transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); transition-duration: 150ms; }
373
+ .transition-shadow { transition-property: box-shadow; transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); transition-duration: 150ms; }
374
+ .duration-75 { transition-duration: 75ms; }
375
+ .duration-100 { transition-duration: 100ms; }
376
+ .duration-150 { transition-duration: 150ms; }
377
+ .duration-200 { transition-duration: 200ms; }
378
+ .duration-300 { transition-duration: 300ms; }
379
+ .duration-500 { transition-duration: 500ms; }
380
+ .duration-700 { transition-duration: 700ms; }
381
+ .duration-1000 { transition-duration: 1000ms; }
382
+ .ease-linear { transition-timing-function: linear; }
383
+ .ease-in { transition-timing-function: cubic-bezier(0.4, 0, 1, 1); }
384
+ .ease-out { transition-timing-function: cubic-bezier(0, 0, 0.2, 1); }
385
+ .ease-in-out { transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); }
386
+
387
+ /* Cursor */
388
+ .cursor-auto { cursor: auto; }
389
+ .cursor-default { cursor: default; }
390
+ .cursor-pointer { cursor: pointer; }
391
+ .cursor-wait { cursor: wait; }
392
+ .cursor-text { cursor: text; }
393
+ .cursor-move { cursor: move; }
394
+ .cursor-not-allowed { cursor: not-allowed; }
395
+
396
+ /* Pointer Events */
397
+ .pointer-events-none { pointer-events: none; }
398
+ .pointer-events-auto { pointer-events: auto; }
399
+
400
+ /* Visibility */
401
+ .visible { visibility: visible; }
402
+ .invisible { visibility: hidden; }
403
+ .collapse { visibility: collapse; }
404
+
405
+ /* White Space */
406
+ .whitespace-normal { white-space: normal; }
407
+ .whitespace-nowrap { white-space: nowrap; }
408
+ .whitespace-pre { white-space: pre; }
409
+ .whitespace-pre-line { white-space: pre-line; }
410
+ .whitespace-pre-wrap { white-space: pre-wrap; }
411
+
412
+ /* Word Break */
413
+ .break-normal { overflow-wrap: normal; word-break: normal; }
414
+ .break-words { overflow-wrap: break-word; }
415
+ .break-all { word-break: break-all; }
416
+ .break-keep { word-break: keep-all; }
417
+
418
+ /* List */
419
+ .list-none { list-style-type: none; }
420
+ .list-disc { list-style-type: disc; }
421
+ .list-decimal { list-style-type: decimal; }
422
+ .list-inside { list-style-position: inside; }
423
+ .list-outside { list-style-position: outside; }
424
+
425
+ /* User Select */
426
+ .select-none { user-select: none; }
427
+ .select-text { user-select: text; }
428
+ .select-all { user-select: all; }
429
+ .select-auto { user-select: auto; }
430
+
431
+ /* Appearance */
432
+ .appearance-none { appearance: none; }
433
+
434
+ /* Background */
435
+ .bg-transparent { background-color: transparent; }
436
+ .bg-current { background-color: currentColor; }
437
+ .bg-white { background-color: #ffffff; }
438
+ .bg-black { background-color: #000000; }
439
+ .bg-gray-50 { background-color: #f9fafb; }
440
+ .bg-gray-100 { background-color: #f3f4f6; }
441
+ .bg-gray-200 { background-color: #e5e7eb; }
442
+ .bg-gray-300 { background-color: #d1d5db; }
443
+ .bg-gray-400 { background-color: #9ca3af; }
444
+ .bg-gray-500 { background-color: #6b7280; }
445
+ .bg-gray-600 { background-color: #4b5563; }
446
+ .bg-gray-700 { background-color: #374151; }
447
+ .bg-gray-800 { background-color: #1f2937; }
448
+ .bg-gray-900 { background-color: #111827; }
449
+
450
+ /* Text Color */
451
+ .text-current { color: currentColor; }
452
+ .text-transparent { color: transparent; }
453
+ .text-white { color: #ffffff; }
454
+ .text-black { color: #000000; }
455
+ .text-gray-50 { color: #f9fafb; }
456
+ .text-gray-100 { color: #f3f4f6; }
457
+ .text-gray-200 { color: #e5e7eb; }
458
+ .text-gray-300 { color: #d1d5db; }
459
+ .text-gray-400 { color: #9ca3af; }
460
+ .text-gray-500 { color: #6b7280; }
461
+ .text-gray-600 { color: #4b5563; }
462
+ .text-gray-700 { color: #374151; }
463
+ .text-gray-800 { color: #1f2937; }
464
+ .text-gray-900 { color: #111827; }
465
+
466
+ /* Dark Mode */
467
+ .dark .hidden { display: none !important; }
468
+ .dark .block { display: block; }
469
+
470
+ /* Animation */
471
+ .animate-spin {
472
+ animation: spin 1s linear infinite;
473
+ }
474
+ @keyframes spin {
475
+ from { transform: rotate(0deg); }
476
+ to { transform: rotate(360deg); }
477
+ }
478
+
479
+ .animate-pulse {
480
+ animation: pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;
481
+ }
482
+ @keyframes pulse {
483
+ 0%, 100% { opacity: 1; }
484
+ 50% { opacity: 0.5; }
485
+ }
486
+
487
+ .animate-bounce {
488
+ animation: bounce 1s infinite;
489
+ }
490
+ @keyframes bounce {
491
+ 0%, 100% { transform: translateY(-25%); animation-timing-function: cubic-bezier(0.8, 0, 1, 1); }
492
+ 50% { transform: translateY(0); animation-timing-function: cubic-bezier(0, 0, 0.2, 1); }
493
+ }
494
+
495
+ /* Screen Reader Only */
496
+ .sr-only {
497
+ position: absolute;
498
+ width: 1px;
499
+ height: 1px;
500
+ padding: 0;
501
+ margin: -1px;
502
+ overflow: hidden;
503
+ clip: rect(0, 0, 0, 0);
504
+ white-space: nowrap;
505
+ border-width: 0;
506
+ }
507
+
508
+ /* Space Between */
509
+ .space-y-0 > :not([hidden]) ~ :not([hidden]) { margin-top: 0; }
510
+ .space-y-1 > :not([hidden]) ~ :not([hidden]) { margin-top: 0.25rem; }
511
+ .space-y-2 > :not([hidden]) ~ :not([hidden]) { margin-top: 0.5rem; }
512
+ .space-y-3 > :not([hidden]) ~ :not([hidden]) { margin-top: 0.75rem; }
513
+ .space-y-4 > :not([hidden]) ~ :not([hidden]) { margin-top: 1rem; }
514
+ .space-y-6 > :not([hidden]) ~ :not([hidden]) { margin-top: 1.5rem; }
515
+ .space-y-8 > :not([hidden]) ~ :not([hidden]) { margin-top: 2rem; }
516
+ .space-x-0 > :not([hidden]) ~ :not([hidden]) { margin-left: 0; }
517
+ .space-x-1 > :not([hidden]) ~ :not([hidden]) { margin-left: 0.25rem; }
518
+ .space-x-2 > :not([hidden]) ~ :not([hidden]) { margin-left: 0.5rem; }
519
+ .space-x-3 > :not([hidden]) ~ :not([hidden]) { margin-left: 0.75rem; }
520
+ .space-x-4 > :not([hidden]) ~ :not([hidden]) { margin-left: 1rem; }
521
+
522
+ /* Group Hover */
523
+ .group:hover .group-hover\:opacity-100 { opacity: 1; }
524
+ .group:hover .group-hover\:text-primary { color: var(--rn-primary); }
525
+ .group:hover .group-hover\:text-danger { color: var(--rn-danger); }
526
+
527
+ /* Responsive: Small (sm:) - 640px */
528
+ @media (min-width: 640px) {
529
+ .sm\:block { display: block; }
530
+ .sm\:flex { display: flex; }
531
+ .sm\:hidden { display: none !important; }
532
+ .sm\:inline-flex { display: inline-flex; }
533
+ .sm\:grid { display: grid; }
534
+ .sm\:p-4 { padding: 1rem; }
535
+ .sm\:p-6 { padding: 1.5rem; }
536
+ .sm\:p-8 { padding: 2rem; }
537
+ .sm\:px-4 { padding-left: 1rem; padding-right: 1rem; }
538
+ .sm\:px-6 { padding-left: 1.5rem; padding-right: 1.5rem; }
539
+ .sm\:px-8 { padding-left: 2rem; padding-right: 2rem; }
540
+ .sm\:py-4 { padding-top: 1rem; padding-bottom: 1rem; }
541
+ .sm\:py-6 { padding-top: 1.5rem; padding-bottom: 1.5rem; }
542
+ .sm\:py-8 { padding-top: 2rem; padding-bottom: 2rem; }
543
+ .sm\:mx-2 { margin-left: 0.5rem; margin-right: 0.5rem; }
544
+ .sm\:mx-3 { margin-left: 0.75rem; margin-right: 0.75rem; }
545
+ .sm\:mx-4 { margin-left: 1rem; margin-right: 1rem; }
546
+ .sm\:mx-6 { margin-left: 1.5rem; margin-right: 1.5rem; }
547
+ .sm\:mx-auto { margin-left: auto; margin-right: auto; }
548
+ .sm\:mt-0 { margin-top: 0; }
549
+ .sm\:mt-2 { margin-top: 0.5rem; }
550
+ .sm\:mt-4 { margin-top: 1rem; }
551
+ .sm\:mb-0 { margin-bottom: 0; }
552
+ .sm\:mb-2 { margin-bottom: 0.5rem; }
553
+ .sm\:mb-4 { margin-bottom: 1rem; }
554
+ .sm\:ml-0 { margin-left: 0; }
555
+ .sm\:ml-2 { margin-left: 0.5rem; }
556
+ .sm\:ml-4 { margin-left: 1rem; }
557
+ .sm\:mr-0 { margin-right: 0; }
558
+ .sm\:mr-2 { margin-right: 0.5rem; }
559
+ .sm\:mr-4 { margin-right: 1rem; }
560
+ .sm\:text-xs { font-size: 0.75rem; line-height: 1rem; }
561
+ .sm\:text-sm { font-size: 0.875rem; line-height: 1.25rem; }
562
+ .sm\:text-base { font-size: 1rem; line-height: 1.5rem; }
563
+ .sm\:text-lg { font-size: 1.125rem; line-height: 1.75rem; }
564
+ .sm\:text-xl { font-size: 1.25rem; line-height: 1.75rem; }
565
+ .sm\:text-2xl { font-size: 1.5rem; line-height: 2rem; }
566
+ .sm\:text-3xl { font-size: 1.875rem; line-height: 2.25rem; }
567
+ .sm\:text-4xl { font-size: 2.25rem; line-height: 2.5rem; }
568
+ .sm\:text-center { text-align: center; }
569
+ .sm\:text-left { text-align: left; }
570
+ .sm\:text-right { text-align: right; }
571
+ }
572
+
573
+ /* Responsive: Medium (md:) - 768px */
574
+ @media (min-width: 768px) {
575
+ .md\:block { display: block; }
576
+ .md\:flex { display: flex; }
577
+ .md\:hidden { display: none !important; }
578
+ .md\:inline-flex { display: inline-flex; }
579
+ .md\:grid { display: grid; }
580
+ .md\:grid-cols-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
581
+ .md\:grid-cols-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
582
+ .md\:grid-cols-4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
583
+ .md\:p-4 { padding: 1rem; }
584
+ .md\:p-6 { padding: 1.5rem; }
585
+ .md\:p-8 { padding: 2rem; }
586
+ .md\:px-4 { padding-left: 1rem; padding-right: 1rem; }
587
+ .md\:px-6 { padding-left: 1.5rem; padding-right: 1.5rem; }
588
+ .md\:px-8 { padding-left: 2rem; padding-right: 2rem; }
589
+ .md\:py-4 { padding-top: 1rem; padding-bottom: 1rem; }
590
+ .md\:py-6 { padding-top: 1.5rem; padding-bottom: 1.5rem; }
591
+ .md\:py-8 { padding-top: 2rem; padding-bottom: 2rem; }
592
+ .md\:mx-2 { margin-left: 0.5rem; margin-right: 0.5rem; }
593
+ .md\:mx-3 { margin-left: 0.75rem; margin-right: 0.75rem; }
594
+ .md\:mx-4 { margin-left: 1rem; margin-right: 1rem; }
595
+ .md\:mx-6 { margin-left: 1.5rem; margin-right: 1.5rem; }
596
+ .md\:mx-auto { margin-left: auto; margin-right: auto; }
597
+ .md\:mt-0 { margin-top: 0; }
598
+ .md\:mt-2 { margin-top: 0.5rem; }
599
+ .md\:mt-4 { margin-top: 1rem; }
600
+ .md\:mb-0 { margin-bottom: 0; }
601
+ .md\:mb-2 { margin-bottom: 0.5rem; }
602
+ .md\:mb-4 { margin-bottom: 1rem; }
603
+ .md\:ml-0 { margin-left: 0; }
604
+ .md\:ml-2 { margin-left: 0.5rem; }
605
+ .md\:ml-4 { margin-left: 1rem; }
606
+ .md\:mr-0 { margin-right: 0; }
607
+ .md\:mr-2 { margin-right: 0.5rem; }
608
+ .md\:mr-4 { margin-right: 1rem; }
609
+ .md\:text-xs { font-size: 0.75rem; line-height: 1rem; }
610
+ .md\:text-sm { font-size: 0.875rem; line-height: 1.25rem; }
611
+ .md\:text-base { font-size: 1rem; line-height: 1.5rem; }
612
+ .md\:text-lg { font-size: 1.125rem; line-height: 1.75rem; }
613
+ .md\:text-xl { font-size: 1.25rem; line-height: 1.75rem; }
614
+ .md\:text-2xl { font-size: 1.5rem; line-height: 2rem; }
615
+ .md\:text-3xl { font-size: 1.875rem; line-height: 2.25rem; }
616
+ .md\:text-4xl { font-size: 2.25rem; line-height: 2.5rem; }
617
+ .md\:text-center { text-align: center; }
618
+ .md\:text-left { text-align: left; }
619
+ .md\:text-right { text-align: right; }
620
+ }
621
+
622
+ /* Responsive: Large (lg:) - 1024px */
623
+ @media (min-width: 1024px) {
624
+ .lg\:block { display: block; }
625
+ .lg\:flex { display: flex; }
626
+ .lg\:hidden { display: none !important; }
627
+ .lg\:inline-flex { display: inline-flex; }
628
+ .lg\:grid { display: grid; }
629
+ .lg\:grid-cols-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
630
+ .lg\:grid-cols-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
631
+ .lg\:grid-cols-4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
632
+ .lg\:p-4 { padding: 1rem; }
633
+ .lg\:p-6 { padding: 1.5rem; }
634
+ .lg\:p-8 { padding: 2rem; }
635
+ .lg\:px-4 { padding-left: 1rem; padding-right: 1rem; }
636
+ .lg\:px-6 { padding-left: 1.5rem; padding-right: 1.5rem; }
637
+ .lg\:px-8 { padding-left: 2rem; padding-right: 2rem; }
638
+ .lg\:py-4 { padding-top: 1rem; padding-bottom: 1rem; }
639
+ .lg\:py-6 { padding-top: 1.5rem; padding-bottom: 1.5rem; }
640
+ .lg\:py-8 { padding-top: 2rem; padding-bottom: 2rem; }
641
+ .lg\:mx-2 { margin-left: 0.5rem; margin-right: 0.5rem; }
642
+ .lg\:mx-3 { margin-left: 0.75rem; margin-right: 0.75rem; }
643
+ .lg\:mx-4 { margin-left: 1rem; margin-right: 1rem; }
644
+ .lg\:mx-6 { margin-left: 1.5rem; margin-right: 1.5rem; }
645
+ .lg\:mx-auto { margin-left: auto; margin-right: auto; }
646
+ .lg\:mt-0 { margin-top: 0; }
647
+ .lg\:mt-2 { margin-top: 0.5rem; }
648
+ .lg\:mt-4 { margin-top: 1rem; }
649
+ .lg\:mb-0 { margin-bottom: 0; }
650
+ .lg\:mb-2 { margin-bottom: 0.5rem; }
651
+ .lg\:mb-4 { margin-bottom: 1rem; }
652
+ .lg\:ml-0 { margin-left: 0; }
653
+ .lg\:ml-2 { margin-left: 0.5rem; }
654
+ .lg\:ml-4 { margin-left: 1rem; }
655
+ .lg\:mr-0 { margin-right: 0; }
656
+ .lg\:mr-2 { margin-right: 0.5rem; }
657
+ .lg\:mr-4 { margin-right: 1rem; }
658
+ .lg\:text-xs { font-size: 0.75rem; line-height: 1rem; }
659
+ .lg\:text-sm { font-size: 0.875rem; line-height: 1.25rem; }
660
+ .lg\:text-base { font-size: 1rem; line-height: 1.5rem; }
661
+ .lg\:text-lg { font-size: 1.125rem; line-height: 1.75rem; }
662
+ .lg\:text-xl { font-size: 1.25rem; line-height: 1.75rem; }
663
+ .lg\:text-2xl { font-size: 1.5rem; line-height: 2rem; }
664
+ .lg\:text-3xl { font-size: 1.875rem; line-height: 2.25rem; }
665
+ .lg\:text-4xl { font-size: 2.25rem; line-height: 2.5rem; }
666
+ .lg\:text-center { text-align: center; }
667
+ .lg\:text-left { text-align: left; }
668
+ .lg\:text-right { text-align: right; }
669
+ }
670
+
671
+ /* Responsive: Extra Large (xl:) - 1280px */
672
+ @media (min-width: 1280px) {
673
+ .xl\:block { display: block; }
674
+ .xl\:flex { display: flex; }
675
+ .xl\:hidden { display: none !important; }
676
+ .xl\:inline-flex { display: inline-flex; }
677
+ .xl\:grid { display: grid; }
678
+ .xl\:grid-cols-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
679
+ .xl\:grid-cols-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
680
+ .xl\:grid-cols-4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
681
+ .xl\:p-4 { padding: 1rem; }
682
+ .xl\:p-6 { padding: 1.5rem; }
683
+ .xl\:p-8 { padding: 2rem; }
684
+ .xl\:px-4 { padding-left: 1rem; padding-right: 1rem; }
685
+ .xl\:px-6 { padding-left: 1.5rem; padding-right: 1.5rem; }
686
+ .xl\:px-8 { padding-left: 2rem; padding-right: 2rem; }
687
+ .xl\:py-4 { padding-top: 1rem; padding-bottom: 1rem; }
688
+ .xl\:py-6 { padding-top: 1.5rem; padding-bottom: 1.5rem; }
689
+ .xl\:py-8 { padding-top: 2rem; padding-bottom: 2rem; }
690
+ .xl\:mx-2 { margin-left: 0.5rem; margin-right: 0.5rem; }
691
+ .xl\:mx-3 { margin-left: 0.75rem; margin-right: 0.75rem; }
692
+ .xl\:mx-4 { margin-left: 1rem; margin-right: 1rem; }
693
+ .xl\:mx-6 { margin-left: 1.5rem; margin-right: 1.5rem; }
694
+ .xl\:mx-auto { margin-left: auto; margin-right: auto; }
695
+ .xl\:mt-0 { margin-top: 0; }
696
+ .xl\:mt-2 { margin-top: 0.5rem; }
697
+ .xl\:mt-4 { margin-top: 1rem; }
698
+ .xl\:mb-0 { margin-bottom: 0; }
699
+ .xl\:mb-2 { margin-bottom: 0.5rem; }
700
+ .xl\:mb-4 { margin-bottom: 1rem; }
701
+ .xl\:ml-0 { margin-left: 0; }
702
+ .xl\:ml-2 { margin-left: 0.5rem; }
703
+ .xl\:ml-4 { margin-left: 1rem; }
704
+ .xl\:mr-0 { margin-right: 0; }
705
+ .xl\:mr-2 { margin-right: 0.5rem; }
706
+ .xl\:mr-4 { margin-right: 1rem; }
707
+ .xl\:text-xs { font-size: 0.75rem; line-height: 1rem; }
708
+ .xl\:text-sm { font-size: 0.875rem; line-height: 1.25rem; }
709
+ .xl\:text-base { font-size: 1rem; line-height: 1.5rem; }
710
+ .xl\:text-lg { font-size: 1.125rem; line-height: 1.75rem; }
711
+ .xl\:text-xl { font-size: 1.25rem; line-height: 1.75rem; }
712
+ .xl\:text-2xl { font-size: 1.5rem; line-height: 2rem; }
713
+ .xl\:text-3xl { font-size: 1.875rem; line-height: 2.25rem; }
714
+ .xl\:text-4xl { font-size: 2.25rem; line-height: 2.5rem; }
715
+ .xl\:text-center { text-align: center; }
716
+ .xl\:text-left { text-align: left; }
717
+ .xl\:text-right { text-align: right; }
718
+ }
719
+
720
+ /* ═══════════════════════════════════════════════════════════════════
721
+ LEGACY FALLBACK STYLES (kept for backward compatibility)
722
+ ═══════════════════════════════════════════════════════════════════ */
723
+
724
+ /* Layout */
725
+ .rn-container { max-width: 80rem; margin: 0 auto; padding: 2rem 1rem; }
726
+ .rn-grid { display: grid; gap: 1.5rem; grid-template-columns: 16rem minmax(0, 1fr); }
727
+ @media (max-width: 1024px) { .rn-grid { grid-template-columns: 1fr; } }
728
+
729
+ /* Card */
730
+ .rn-card { background: var(--rn-surface); border: 1px solid var(--rn-border); border-radius: var(--rn-radius); box-shadow: 0 1px 3px rgba(0,0,0,0.06); padding: 1.25rem; }
731
+
732
+ /* Header */
733
+ .rn-header { display: flex; flex-wrap: wrap; align-items: flex-end; justify-content: space-between; gap: 1rem; margin-bottom: 2rem; }
734
+ .rn-header h1 { font-size: 1.875rem; font-weight: 700; letter-spacing: -0.025em; margin-top: 0.5rem; }
735
+ .rn-brand { font-size: 0.875rem; font-weight: 600; text-transform: uppercase; letter-spacing: 0.1em; color: var(--rn-primary); }
736
+ .rn-subtitle { color: var(--rn-text-secondary); margin-top: 0.5rem; }
737
+
738
+ /* Sidebar */
739
+ .rn-sidebar { padding: 1.25rem; }
740
+ .rn-sidebar h2 { font-size: 0.875rem; font-weight: 600; text-transform: uppercase; letter-spacing: 0.05em; color: var(--rn-text-secondary); }
741
+ .rn-sidebar h3 { font-size: 0.75rem; font-weight: 600; text-transform: uppercase; letter-spacing: 0.05em; color: var(--rn-text-secondary); margin-top: 1.5rem; }
742
+ .rn-nav { list-style: none; padding: 0; margin: 0.5rem 0 0; }
743
+ .rn-nav li { margin: 0.25rem 0; }
744
+ .rn-nav a { display: block; padding: 0.5rem 0.75rem; border-radius: var(--rn-radius-sm); font-size: 0.875rem; color: var(--rn-text-secondary); }
745
+ .rn-nav a:hover { background: #f1f5f9; color: var(--rn-text); text-decoration: none; }
746
+ .rn-nav-scroll { max-height: 10rem; overflow-y: auto; }
747
+
748
+ /* Search */
749
+ .rn-search { display: flex; gap: 0.5rem; margin-top: 0.5rem; }
750
+ .rn-search input[type="search"] { flex: 1; min-width: 0; padding: 0.5rem 0.75rem; border: 1px solid #cbd5e1; border-radius: var(--rn-radius-sm); font-size: 0.875rem; }
751
+ .rn-search input[type="search"]:focus { outline: none; border-color: var(--rn-primary); box-shadow: 0 0 0 2px rgba(79,70,229,0.2); }
752
+
753
+ /* Buttons */
754
+ .rn-btn { display: inline-flex; align-items: center; justify-content: center; padding: 0.5rem 1rem; border: none; border-radius: var(--rn-radius-sm); font-size: 0.875rem; font-weight: 600; cursor: pointer; text-decoration: none; }
755
+ .rn-btn-primary { background: var(--rn-primary); color: white; }
756
+ .rn-btn-primary:hover { background: var(--rn-primary-hover); text-decoration: none; }
757
+ .rn-btn-danger { background: var(--rn-danger); color: white; }
758
+ .rn-btn-danger:hover { background: var(--rn-danger-hover); text-decoration: none; }
759
+ .rn-btn-outline { background: transparent; border: 1px solid #e2e8f0; color: #b91c1c; }
760
+ .rn-btn-outline:hover { background: var(--rn-danger-bg); text-decoration: none; }
761
+ .rn-btn-sm { padding: 0.375rem 0.75rem; font-size: 0.8125rem; }
762
+ .rn-btn-ghost { background: transparent; color: var(--rn-text-secondary); }
763
+ .rn-btn-ghost:hover { background: #f1f5f9; text-decoration: none; }
764
+
765
+ /* Table */
766
+ .rn-table-wrap { overflow-x: auto; }
767
+ .rn-table { min-width: 100%; }
768
+ .rn-table thead { background: #f8fafc; }
769
+ .rn-table th { padding: 0.75rem 1.25rem; text-align: left; font-size: 0.75rem; font-weight: 600; text-transform: uppercase; letter-spacing: 0.05em; color: var(--rn-text-secondary); }
770
+ .rn-table td { padding: 1rem 1.25rem; vertical-align: top; border-top: 1px solid #f1f5f9; }
771
+ .rn-table tr:hover { background: #f8fafc; }
772
+ .rn-table .rn-name { font-weight: 500; color: var(--rn-primary); }
773
+ .rn-table .rn-name:hover { text-decoration: underline; }
774
+ .rn-table .rn-msg { margin-top: 0.25rem; font-size: 0.875rem; color: var(--rn-text-secondary); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 40rem; }
775
+ .rn-table .rn-date { font-size: 0.875rem; color: var(--rn-text-secondary); white-space: nowrap; }
776
+
777
+ /* Actions */
778
+ .rn-actions { text-align: right; white-space: nowrap; }
779
+ .rn-delete-link { font-size: 0.875rem; font-weight: 500; color: var(--rn-danger); }
780
+ .rn-delete-link:hover { color: var(--rn-danger-hover); text-decoration: underline; }
781
+
782
+ /* Detail panel */
783
+ .rn-detail-header { display: flex; align-items: flex-start; justify-content: space-between; gap: 1rem; padding-bottom: 1rem; border-bottom: 1px solid var(--rn-border); }
784
+ .rn-detail-header h2 { font-size: 1.25rem; font-weight: 600; word-break: break-word; margin-top: 0.25rem; }
785
+ .rn-detail-time { font-size: 0.875rem; color: var(--rn-text-secondary); }
786
+ .rn-detail-body { margin-top: 1.25rem; }
787
+ .rn-detail-section { margin-bottom: 1.25rem; }
788
+ .rn-detail-section h3 { font-size: 0.75rem; font-weight: 600; text-transform: uppercase; letter-spacing: 0.05em; color: var(--rn-text-secondary); margin-bottom: 0.5rem; }
789
+ .rn-detail-code { background: #f8fafc; padding: 1rem; border-radius: var(--rn-radius-sm); overflow-x: auto; white-space: pre-wrap; word-break: break-all; font-size: 0.875rem; }
790
+ .rn-detail-pre { background: #0f172a; color: #e2e8f0; padding: 1rem; border-radius: var(--rn-radius-sm); overflow: auto; max-height: 24rem; font-size: 0.75rem; line-height: 1.625; }
791
+ .rn-detail-footer { margin-top: 1.5rem; padding-top: 1rem; border-top: 1px solid var(--rn-border); }
792
+
793
+ /* Empty state */
794
+ .rn-empty { padding: 4rem 1.25rem; text-align: center; color: var(--rn-text-secondary); font-size: 0.875rem; }
795
+
796
+ /* Status bar */
797
+ .rn-status { background: #eef2ff; color: #4338ca; padding: 0.75rem 1rem; border-radius: var(--rn-radius-sm); font-size: 0.875rem; margin-bottom: 1rem; }
798
+ .rn-status[hidden] { display: none; }
799
+
800
+ /* Pagination */
801
+ .rn-pagination { border-top: 1px solid var(--rn-border); padding: 1rem 1.25rem; font-size: 0.875rem; }
802
+ .rn-pagination .pagination { display: flex; flex-wrap: wrap; gap: 0.5rem; align-items: center; list-style: none; margin: 0; padding: 0; }
803
+ .rn-pagination .pagination a,
804
+ .rn-pagination .pagination span { padding: 0.375rem 0.75rem; border-radius: var(--rn-radius-sm); }
805
+ .rn-pagination .pagination a { color: var(--rn-primary); }
806
+ .rn-pagination .pagination a:hover { background: #eef2ff; text-decoration: none; }
807
+ .rn-pagination .pagination .current { background: var(--rn-primary); color: white; font-weight: 600; }
808
+
809
+ /* Feed link */
810
+ .rn-feed { margin-top: 1rem; }
811
+ .rn-feed a { font-size: 0.8125rem; color: var(--rn-text-muted); }
812
+ .rn-feed a:hover { color: var(--rn-primary); }
813
+
814
+ /* Utility */
815
+ .sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0,0,0,0); border: 0; }
816
+ .sr-only-focusable:focus { position: static; width: auto; height: auto; padding: 0; margin: 0; overflow: visible; clip: auto; border: 0; }
817
+
818
+ /* Source Code Integration */
819
+ .rn-source-toggle {
820
+ display: inline-flex;
821
+ align-items: center;
822
+ justify-content: center;
823
+ width: 1.5rem;
824
+ height: 1.5rem;
825
+ border-radius: 0.25rem;
826
+ border: none;
827
+ background: transparent;
828
+ color: var(--rn-text-muted);
829
+ cursor: pointer;
830
+ transition: all 0.15s ease;
831
+ }
832
+ .rn-source-toggle:hover {
833
+ background: var(--rn-bg-secondary);
834
+ color: var(--rn-primary);
835
+ }
836
+
837
+ .rn-source-panel {
838
+ border-radius: 0.5rem;
839
+ border: 1px solid var(--rn-border-light);
840
+ overflow: hidden;
841
+ animation: slideDown 0.15s ease-out;
842
+ }
843
+
844
+ .rn-source-code {
845
+ font-size: 0.75rem;
846
+ line-height: 1.5;
847
+ overflow-x: auto;
848
+ }
849
+ .rn-source-code .source-line {
850
+ display: flex;
851
+ padding: 0 0.75rem;
852
+ }
853
+ .rn-source-code .source-line:hover {
854
+ background: var(--rn-bg-secondary);
855
+ }
856
+ .rn-source-code .source-line.is-error {
857
+ background: var(--rn-bg-warning-subtle);
858
+ border-left: 2px solid var(--rn-warning);
859
+ }
860
+ .rn-source-code .line-number {
861
+ min-width: 2.5rem;
862
+ text-align: right;
863
+ color: var(--rn-text-muted);
864
+ user-select: none;
865
+ padding-right: 1rem;
866
+ }
867
+ .rn-source-code .line-content {
868
+ white-space: pre;
869
+ color: var(--rn-text);
870
+ }
871
+
872
+ /* Git Blame Header */
873
+ .rn-blame-header {
874
+ display: flex;
875
+ align-items: center;
876
+ gap: 0.5rem;
877
+ padding: 0.375rem 0.75rem;
878
+ background: var(--rn-bg-secondary);
879
+ border-bottom: 1px solid var(--rn-border-light);
880
+ font-size: 0.625rem;
881
+ color: var(--rn-text-muted);
882
+ }
883
+ .rn-blame-header .blame-author {
884
+ color: var(--rn-primary);
885
+ font-weight: 500;
886
+ }
887
+ .rn-blame-header .blame-sha {
888
+ margin-left: auto;
889
+ font-family: monospace;
890
+ color: var(--rn-text-muted);
891
+ }
892
+
893
+ /* Backtrace Frames */
894
+ .rn-bt-app {
895
+ border-left: 2px solid var(--rn-primary);
896
+ }
897
+ .rn-bt-highlight {
898
+ background: var(--rn-bg-warning-subtle);
899
+ }
900
+ .rn-bt-hidden {
901
+ opacity: 0.5;
902
+ }
903
+
904
+ @keyframes slideDown {
905
+ from { opacity: 0; transform: translateY(-4px); }
906
+ to { opacity: 1; transform: translateY(0); }
907
+ }
908
+
909
+ /* ═══════════════════════════════════════════════════════════════════
910
+ Dashboard Component Styles
911
+ ═══════════════════════════════════════════════════════════════════ */
912
+ /* ═══════════════════════════════════════════════════════════════════
913
+ RailsNexus Dashboard — Advanced Error Logger
914
+ Inspired by Sentry, Datadog, Honeybadger
915
+ ═══════════════════════════════════════════════════════════════════ */
916
+
917
+ /* ─── Light Theme (default) ─────────────────────────────────── */
918
+ :root, .light {
919
+ --rn-bg: #f8fafc;
920
+ --rn-bg-secondary: #f1f5f9;
921
+ --rn-surface: #ffffff;
922
+ --rn-surface-hover: #f8fafc;
923
+ --rn-surface-active: #f1f5f9;
924
+ --rn-border: #e2e8f0;
925
+ --rn-border-light: #f1f5f9;
926
+ --rn-text: #0f172a;
927
+ --rn-text-secondary: #475569;
928
+ --rn-text-muted: #94a3b8;
929
+ --rn-primary: #4f46e5;
930
+ --rn-primary-hover: #4338ca;
931
+ --rn-primary-light: #eef2ff;
932
+ --rn-primary-ring: rgba(79,70,229,0.15);
933
+ --rn-danger: #dc2626;
934
+ --rn-danger-hover: #b91c1c;
935
+ --rn-danger-light: #fef2f2;
936
+ --rn-danger-ring: rgba(220,38,38,0.15);
937
+ --rn-success: #059669;
938
+ --rn-success-light: #f0fdf4;
939
+ --rn-warning: #d97706;
940
+ --rn-warning-light: #fffbeb;
941
+ --rn-info: #2563eb;
942
+ --rn-info-light: #eff6ff;
943
+ --rn-badge-bg: #f1f5f9;
944
+ --rn-badge-text: #475569;
945
+ --rn-badge-danger-bg: #fef2f2;
946
+ --rn-badge-danger-text: #991b1b;
947
+ --rn-badge-danger-border: #fecaca;
948
+ --rn-badge-warning-bg: #fffbeb;
949
+ --rn-badge-warning-text: #92400e;
950
+ --rn-badge-info-bg: #eff6ff;
951
+ --rn-badge-info-text: #1e40af;
952
+ --rn-code-bg: #f8fafc;
953
+ --rn-code-text: #334155;
954
+ --rn-pre-bg: #0f172a;
955
+ --rn-pre-text: #e2e8f0;
956
+ --rn-sidebar-bg: #0f172a;
957
+ --rn-sidebar-text: #94a3b8;
958
+ --rn-sidebar-text-hover: #f8fafc;
959
+ --rn-sidebar-active-bg: #1e293b;
960
+ --rn-sidebar-border: #1e293b;
961
+ --rn-shadow-sm: 0 1px 2px rgba(0,0,0,0.04);
962
+ --rn-shadow: 0 1px 3px rgba(0,0,0,0.06), 0 1px 2px rgba(0,0,0,0.04);
963
+ --rn-shadow-md: 0 4px 6px -1px rgba(0,0,0,0.07), 0 2px 4px -2px rgba(0,0,0,0.05);
964
+ --rn-shadow-lg: 0 10px 15px -3px rgba(0,0,0,0.08), 0 4px 6px -4px rgba(0,0,0,0.04);
965
+ --rn-radius: 0.75rem;
966
+ --rn-radius-sm: 0.5rem;
967
+ --rn-radius-lg: 1rem;
968
+ --rn-radius-xl: 1.25rem;
969
+ --rn-transition: 150ms cubic-bezier(0.4, 0, 0.2, 1);
970
+ --rn-transition-slow: 300ms cubic-bezier(0.4, 0, 0.2, 1);
971
+ }
972
+
973
+ /* ─── Dark Theme ────────────────────────────────────────────── */
974
+ .dark {
975
+ --rn-bg: #0f172a;
976
+ --rn-bg-secondary: #1e293b;
977
+ --rn-surface: #1e293b;
978
+ --rn-surface-hover: #334155;
979
+ --rn-surface-active: #334155;
980
+ --rn-border: #334155;
981
+ --rn-border-light: #1e293b;
982
+ --rn-text: #f1f5f9;
983
+ --rn-text-secondary: #94a3b8;
984
+ --rn-text-muted: #64748b;
985
+ --rn-primary: #818cf8;
986
+ --rn-primary-hover: #6366f1;
987
+ --rn-primary-light: rgba(99,102,241,0.1);
988
+ --rn-primary-ring: rgba(129,140,248,0.2);
989
+ --rn-danger: #f87171;
990
+ --rn-danger-hover: #ef4444;
991
+ --rn-danger-light: rgba(248,113,113,0.1);
992
+ --rn-danger-ring: rgba(248,113,113,0.2);
993
+ --rn-success: #34d399;
994
+ --rn-success-light: rgba(52,211,153,0.1);
995
+ --rn-warning: #fbbf24;
996
+ --rn-warning-light: rgba(251,191,36,0.1);
997
+ --rn-info: #60a5fa;
998
+ --rn-info-light: rgba(96,165,250,0.1);
999
+ --rn-badge-bg: #334155;
1000
+ --rn-badge-text: #94a3b8;
1001
+ --rn-badge-danger-bg: rgba(248,113,113,0.1);
1002
+ --rn-badge-danger-text: #fca5a5;
1003
+ --rn-badge-danger-border: rgba(248,113,113,0.2);
1004
+ --rn-badge-warning-bg: rgba(251,191,36,0.1);
1005
+ --rn-badge-warning-text: #fcd34d;
1006
+ --rn-badge-info-bg: rgba(96,165,250,0.1);
1007
+ --rn-badge-info-text: #93c5fd;
1008
+ --rn-code-bg: #0f172a;
1009
+ --rn-code-text: #94a3b8;
1010
+ --rn-sidebar-bg: #020617;
1011
+ --rn-shadow-sm: 0 1px 2px rgba(0,0,0,0.2);
1012
+ --rn-shadow: 0 1px 3px rgba(0,0,0,0.3), 0 1px 2px rgba(0,0,0,0.2);
1013
+ --rn-shadow-md: 0 4px 6px -1px rgba(0,0,0,0.4), 0 2px 4px -2px rgba(0,0,0,0.3);
1014
+ --rn-shadow-lg: 0 10px 15px -3px rgba(0,0,0,0.5), 0 4px 6px -4px rgba(0,0,0,0.4);
1015
+ }
1016
+
1017
+ /* ─── Base Reset ────────────────────────────────────────────── */
1018
+ *, *::before, *::after { box-sizing: border-box; }
1019
+ body { margin: 0; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif; line-height: 1.5; color: var(--rn-text); background: var(--rn-bg); transition: background var(--rn-transition), color var(--rn-transition); }
1020
+ a { color: var(--rn-primary); text-decoration: none; transition: color var(--rn-transition); }
1021
+ a:hover { color: var(--rn-primary-hover); }
1022
+ h1, h2, h3, h4, p { margin: 0; }
1023
+ table { border-collapse: collapse; width: 100%; }
1024
+ code, pre { font-family: "SF Mono", "Fira Code", "Fira Mono", "Roboto Mono", monospace; }
1025
+
1026
+ /* ─── Sidebar ───────────────────────────────────────────────── */
1027
+ .rn-sidebar {
1028
+ width: 16rem;
1029
+ background: var(--rn-sidebar-bg);
1030
+ color: var(--rn-sidebar-text);
1031
+ display: flex;
1032
+ flex-direction: column;
1033
+ flex-shrink: 0;
1034
+ border-right: 1px solid var(--rn-sidebar-border);
1035
+ position: sticky;
1036
+ top: 0;
1037
+ height: 100vh;
1038
+ z-index: 30;
1039
+ }
1040
+ @media (max-width: 1023px) { .rn-sidebar { display: none; } }
1041
+
1042
+ .rn-sidebar-logo {
1043
+ padding: 1rem;
1044
+ border-bottom: 1px solid var(--rn-sidebar-border);
1045
+ display: flex;
1046
+ align-items: center;
1047
+ justify-content: space-between;
1048
+ min-height: 3.5rem;
1049
+ }
1050
+ .rn-logo-icon {
1051
+ width: 2rem;
1052
+ height: 2rem;
1053
+ border-radius: 0.5rem;
1054
+ background: var(--rn-primary);
1055
+ color: white;
1056
+ display: flex;
1057
+ align-items: center;
1058
+ justify-content: center;
1059
+ font-weight: 700;
1060
+ font-size: 0.875rem;
1061
+ flex-shrink: 0;
1062
+ }
1063
+ .rn-logo-text {
1064
+ font-size: 0.9375rem;
1065
+ font-weight: 700;
1066
+ letter-spacing: -0.01em;
1067
+ color: #f8fafc;
1068
+ }
1069
+
1070
+ .rn-sidebar-nav {
1071
+ flex: 1;
1072
+ padding: 0.75rem;
1073
+ display: flex;
1074
+ flex-direction: column;
1075
+ gap: 0.125rem;
1076
+ overflow-y: auto;
1077
+ }
1078
+
1079
+ .rn-nav-item {
1080
+ display: flex;
1081
+ align-items: center;
1082
+ gap: 0.625rem;
1083
+ padding: 0.5rem 0.75rem;
1084
+ border-radius: 0.5rem;
1085
+ font-size: 0.875rem;
1086
+ font-weight: 500;
1087
+ color: var(--rn-sidebar-text);
1088
+ transition: all var(--rn-transition);
1089
+ text-decoration: none;
1090
+ }
1091
+ .rn-nav-item:hover {
1092
+ color: var(--rn-sidebar-text-hover);
1093
+ background: var(--rn-sidebar-active-bg);
1094
+ text-decoration: none;
1095
+ }
1096
+ .rn-nav-item.active {
1097
+ color: #f8fafc;
1098
+ background: var(--rn-sidebar-active-bg);
1099
+ }
1100
+ .rn-nav-item--muted {
1101
+ font-size: 0.8125rem;
1102
+ opacity: 0.8;
1103
+ }
1104
+ .rn-nav-item--muted:hover {
1105
+ opacity: 1;
1106
+ }
1107
+ .rn-nav-badge {
1108
+ margin-left: auto;
1109
+ padding: 0.0625rem 0.375rem;
1110
+ border-radius: 0.625rem;
1111
+ font-size: 0.625rem;
1112
+ font-weight: 600;
1113
+ background: var(--rn-sidebar-active-bg);
1114
+ color: var(--rn-sidebar-text);
1115
+ line-height: 1.25;
1116
+ }
1117
+ .rn-sidebar-section-divider {
1118
+ height: 1px;
1119
+ background: var(--rn-sidebar-border);
1120
+ margin: 0.5rem 0;
1121
+ opacity: 0.5;
1122
+ }
1123
+
1124
+ .rn-sidebar-footer {
1125
+ padding: 0.75rem 1rem;
1126
+ border-top: 1px solid var(--rn-sidebar-border);
1127
+ font-size: 0.6875rem;
1128
+ color: #475569;
1129
+ }
1130
+
1131
+ /* ─── Mobile Sidebar ────────────────────────────────────────── */
1132
+ .rn-mobile-sidebar {
1133
+ position: fixed;
1134
+ inset-y: 0;
1135
+ left: 0;
1136
+ width: 16rem;
1137
+ background: var(--rn-sidebar-bg);
1138
+ z-index: 50;
1139
+ transform: translateX(-100%);
1140
+ transition: transform 200ms ease-out;
1141
+ }
1142
+ .rn-mobile-sidebar.open { transform: translateX(0); }
1143
+
1144
+ .rn-overlay {
1145
+ position: fixed;
1146
+ inset: 0;
1147
+ background: rgba(0,0,0,0.5);
1148
+ z-index: 40;
1149
+ display: none;
1150
+ backdrop-filter: blur(4px);
1151
+ }
1152
+ .rn-overlay.open { display: block; }
1153
+
1154
+ /* ─── Top Bar ───────────────────────────────────────────────── */
1155
+ .rn-topbar {
1156
+ background: var(--rn-surface);
1157
+ border-bottom: 1px solid var(--rn-border);
1158
+ padding: 0 1.5rem;
1159
+ height: 3.5rem;
1160
+ display: flex;
1161
+ align-items: center;
1162
+ justify-content: space-between;
1163
+ flex-shrink: 0;
1164
+ position: sticky;
1165
+ top: 0;
1166
+ z-index: 20;
1167
+ transition: background var(--rn-transition), border-color var(--rn-transition);
1168
+ backdrop-filter: blur(8px);
1169
+ background: color-mix(in srgb, var(--rn-surface) 85%, transparent);
1170
+ }
1171
+
1172
+ .rn-icon-btn {
1173
+ display: inline-flex;
1174
+ align-items: center;
1175
+ justify-content: center;
1176
+ width: 2rem;
1177
+ height: 2rem;
1178
+ border-radius: 0.5rem;
1179
+ border: none;
1180
+ background: transparent;
1181
+ color: var(--rn-text-secondary);
1182
+ cursor: pointer;
1183
+ transition: all var(--rn-transition);
1184
+ }
1185
+ .rn-icon-btn:hover {
1186
+ background: var(--rn-bg-secondary);
1187
+ color: var(--rn-text);
1188
+ }
1189
+
1190
+ /* ─── Alerts ────────────────────────────────────────────────── */
1191
+ .rn-alert {
1192
+ display: flex;
1193
+ align-items: center;
1194
+ gap: 0.75rem;
1195
+ padding: 0.75rem 1rem;
1196
+ border-radius: 0.5rem;
1197
+ }
1198
+ .rn-alert-success {
1199
+ background: var(--rn-success-light);
1200
+ color: var(--rn-success);
1201
+ border: 1px solid color-mix(in srgb, var(--rn-success) 20%, transparent);
1202
+ }
1203
+ .rn-alert-error {
1204
+ background: var(--rn-danger-light);
1205
+ color: var(--rn-danger);
1206
+ border: 1px solid color-mix(in srgb, var(--rn-danger) 20%, transparent);
1207
+ }
1208
+
1209
+ /* ─── Cards ─────────────────────────────────────────────────── */
1210
+ .rn-card {
1211
+ background: var(--rn-surface);
1212
+ border: 1px solid var(--rn-border);
1213
+ border-radius: var(--rn-radius-lg);
1214
+ box-shadow: var(--rn-shadow);
1215
+ transition: background var(--rn-transition), border-color var(--rn-transition), box-shadow var(--rn-transition);
1216
+ }
1217
+
1218
+ /* ─── Stats Cards (Sentry-style overview) ───────────────────── */
1219
+ .rn-stats {
1220
+ display: grid;
1221
+ grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
1222
+ gap: 1rem;
1223
+ }
1224
+ .rn-stat {
1225
+ background: var(--rn-surface);
1226
+ border: 1px solid var(--rn-border);
1227
+ border-radius: var(--rn-radius);
1228
+ padding: 1.25rem;
1229
+ display: flex;
1230
+ flex-direction: column;
1231
+ gap: 0.25rem;
1232
+ transition: all var(--rn-transition);
1233
+ }
1234
+ .rn-stat:hover {
1235
+ border-color: var(--rn-primary);
1236
+ box-shadow: 0 0 0 3px var(--rn-primary-ring);
1237
+ transform: translateY(-1px);
1238
+ }
1239
+ .rn-stat-label {
1240
+ font-size: 0.6875rem;
1241
+ font-weight: 600;
1242
+ text-transform: uppercase;
1243
+ letter-spacing: 0.05em;
1244
+ color: var(--rn-text-muted);
1245
+ }
1246
+ .rn-stat-value {
1247
+ font-size: 1.75rem;
1248
+ font-weight: 700;
1249
+ color: var(--rn-text);
1250
+ line-height: 1.2;
1251
+ }
1252
+ .rn-stat-value.danger { color: var(--rn-danger); }
1253
+ .rn-stat-value.success { color: var(--rn-success); }
1254
+ .rn-stat-value.warning { color: var(--rn-warning); }
1255
+ .rn-stat-change {
1256
+ font-size: 0.75rem;
1257
+ color: var(--rn-text-muted);
1258
+ display: flex;
1259
+ align-items: center;
1260
+ gap: 0.25rem;
1261
+ }
1262
+ .rn-stat-change.up { color: var(--rn-danger); }
1263
+ .rn-stat-change.down { color: var(--rn-success); }
1264
+
1265
+ /* ─── Tabs (Sentry-style) ──────────────────────────────────── */
1266
+ .rn-tabs {
1267
+ display: flex;
1268
+ border-bottom: 1px solid var(--rn-border);
1269
+ padding: 0 1rem;
1270
+ gap: 0;
1271
+ overflow-x: auto;
1272
+ }
1273
+ .rn-tab {
1274
+ padding: 0.75rem 1rem;
1275
+ font-size: 0.875rem;
1276
+ font-weight: 500;
1277
+ color: var(--rn-text-muted);
1278
+ border-bottom: 2px solid transparent;
1279
+ cursor: pointer;
1280
+ transition: all var(--rn-transition);
1281
+ white-space: nowrap;
1282
+ text-decoration: none;
1283
+ background: none;
1284
+ border-top: none;
1285
+ border-left: none;
1286
+ border-right: none;
1287
+ }
1288
+ .rn-tab:hover {
1289
+ color: var(--rn-text);
1290
+ text-decoration: none;
1291
+ }
1292
+ .rn-tab.active {
1293
+ color: var(--rn-primary);
1294
+ border-bottom-color: var(--rn-primary);
1295
+ }
1296
+ .rn-tab-badge {
1297
+ display: inline-flex;
1298
+ align-items: center;
1299
+ justify-content: center;
1300
+ min-width: 1.25rem;
1301
+ height: 1.25rem;
1302
+ padding: 0 0.375rem;
1303
+ border-radius: 0.625rem;
1304
+ font-size: 0.6875rem;
1305
+ font-weight: 600;
1306
+ margin-left: 0.375rem;
1307
+ background: var(--rn-badge-bg);
1308
+ color: var(--rn-badge-text);
1309
+ }
1310
+ .rn-tab.active .rn-tab-badge {
1311
+ background: var(--rn-primary-light);
1312
+ color: var(--rn-primary);
1313
+ }
1314
+
1315
+ /* ─── Breadcrumbs ───────────────────────────────────────────── */
1316
+ .rn-breadcrumbs {
1317
+ display: flex;
1318
+ align-items: center;
1319
+ gap: 0.375rem;
1320
+ font-size: 0.8125rem;
1321
+ padding: 0.75rem 0;
1322
+ }
1323
+ .rn-breadcrumb {
1324
+ color: var(--rn-text-muted);
1325
+ text-decoration: none;
1326
+ transition: color var(--rn-transition);
1327
+ }
1328
+ .rn-breadcrumb:hover { color: var(--rn-primary); text-decoration: none; }
1329
+ .rn-breadcrumb-current { color: var(--rn-text); font-weight: 500; }
1330
+ .rn-breadcrumb-sep {
1331
+ color: var(--rn-text-muted);
1332
+ opacity: 0.5;
1333
+ user-select: none;
1334
+ }
1335
+
1336
+ /* ─── Filters Bar ───────────────────────────────────────────── */
1337
+ .rn-filters {
1338
+ display: flex;
1339
+ flex-wrap: wrap;
1340
+ align-items: flex-end;
1341
+ gap: 0.75rem;
1342
+ padding: 1rem;
1343
+ border-bottom: 1px solid var(--rn-border-light);
1344
+ }
1345
+ .rn-filters:last-child { border-bottom: none; }
1346
+ .rn-filter-group {
1347
+ flex: 1;
1348
+ min-width: 140px;
1349
+ }
1350
+ .rn-filter-group label {
1351
+ display: block;
1352
+ font-size: 0.6875rem;
1353
+ font-weight: 600;
1354
+ text-transform: uppercase;
1355
+ letter-spacing: 0.05em;
1356
+ color: var(--rn-text-muted);
1357
+ margin-bottom: 0.25rem;
1358
+ }
1359
+
1360
+ /* ─── Active Filter Pills ───────────────────────────────────── */
1361
+ .rn-filter-pills {
1362
+ display: flex;
1363
+ flex-wrap: wrap;
1364
+ gap: 0.375rem;
1365
+ padding: 0.75rem 1rem;
1366
+ }
1367
+ .rn-filter-pill {
1368
+ display: inline-flex;
1369
+ align-items: center;
1370
+ gap: 0.375rem;
1371
+ padding: 0.25rem 0.625rem;
1372
+ background: var(--rn-primary-light);
1373
+ color: var(--rn-primary);
1374
+ border-radius: 1rem;
1375
+ font-size: 0.75rem;
1376
+ font-weight: 500;
1377
+ text-decoration: none;
1378
+ transition: all var(--rn-transition);
1379
+ }
1380
+ .rn-filter-pill:hover { opacity: 0.8; text-decoration: none; }
1381
+ .rn-filter-pill-x {
1382
+ display: inline-flex;
1383
+ width: 1rem;
1384
+ height: 1rem;
1385
+ align-items: center;
1386
+ justify-content: center;
1387
+ border-radius: 50%;
1388
+ font-size: 0.75rem;
1389
+ line-height: 1;
1390
+ }
1391
+
1392
+ /* ─── Form Elements ─────────────────────────────────────────── */
1393
+ .rn-input,
1394
+ .rn-select {
1395
+ display: block;
1396
+ width: 100%;
1397
+ padding: 0.5rem 0.75rem;
1398
+ border: 1px solid var(--rn-border);
1399
+ border-radius: var(--rn-radius-sm);
1400
+ font-size: 0.875rem;
1401
+ color: var(--rn-text);
1402
+ background: var(--rn-surface);
1403
+ transition: all var(--rn-transition);
1404
+ outline: none;
1405
+ appearance: none;
1406
+ }
1407
+ .rn-input:focus,
1408
+ .rn-select:focus {
1409
+ border-color: var(--rn-primary);
1410
+ box-shadow: 0 0 0 3px var(--rn-primary-ring);
1411
+ }
1412
+ .rn-input::placeholder { color: var(--rn-text-muted); }
1413
+ .rn-select {
1414
+ background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 20 20'%3E%3Cpath stroke='%236b7280' stroke-linecap='round' stroke-linejoin='round' stroke-width='1.5' d='M6 8l4 4 4-4'/%3E%3C/svg%3E");
1415
+ background-position: right 0.5rem center;
1416
+ background-repeat: no-repeat;
1417
+ background-size: 1.25rem;
1418
+ padding-right: 2.5rem;
1419
+ }
1420
+
1421
+ /* ─── Search Input (with icon) ──────────────────────────────── */
1422
+ .rn-search {
1423
+ position: relative;
1424
+ }
1425
+ .rn-search-icon {
1426
+ position: absolute;
1427
+ left: 0.75rem;
1428
+ top: 50%;
1429
+ transform: translateY(-50%);
1430
+ color: var(--rn-text-muted);
1431
+ pointer-events: none;
1432
+ }
1433
+ .rn-search .rn-input {
1434
+ padding-left: 2.25rem;
1435
+ }
1436
+ .rn-search-kbd {
1437
+ position: absolute;
1438
+ right: 0.5rem;
1439
+ top: 50%;
1440
+ transform: translateY(-50%);
1441
+ padding: 0.125rem 0.375rem;
1442
+ border: 1px solid var(--rn-border);
1443
+ border-radius: 0.25rem;
1444
+ font-size: 0.625rem;
1445
+ color: var(--rn-text-muted);
1446
+ background: var(--rn-bg-secondary);
1447
+ pointer-events: none;
1448
+ }
1449
+
1450
+ /* ─── Buttons ───────────────────────────────────────────────── */
1451
+ .rn-btn {
1452
+ display: inline-flex;
1453
+ align-items: center;
1454
+ justify-content: center;
1455
+ gap: 0.375rem;
1456
+ padding: 0.5rem 1rem;
1457
+ border: none;
1458
+ border-radius: var(--rn-radius-sm);
1459
+ font-size: 0.875rem;
1460
+ font-weight: 600;
1461
+ cursor: pointer;
1462
+ text-decoration: none;
1463
+ transition: all var(--rn-transition);
1464
+ white-space: nowrap;
1465
+ }
1466
+ .rn-btn-primary {
1467
+ background: var(--rn-primary);
1468
+ color: white;
1469
+ }
1470
+ .rn-btn-primary:hover {
1471
+ background: var(--rn-primary-hover);
1472
+ text-decoration: none;
1473
+ box-shadow: var(--rn-shadow-md);
1474
+ }
1475
+ .rn-btn-danger {
1476
+ background: var(--rn-danger);
1477
+ color: white;
1478
+ }
1479
+ .rn-btn-danger:hover {
1480
+ background: var(--rn-danger-hover);
1481
+ text-decoration: none;
1482
+ }
1483
+ .rn-btn-ghost {
1484
+ background: transparent;
1485
+ color: var(--rn-text-secondary);
1486
+ border: 1px solid var(--rn-border);
1487
+ }
1488
+ .rn-btn-ghost:hover {
1489
+ background: var(--rn-bg-secondary);
1490
+ text-decoration: none;
1491
+ }
1492
+ .rn-btn-sm {
1493
+ padding: 0.25rem 0.625rem;
1494
+ font-size: 0.75rem;
1495
+ }
1496
+ .rn-btn-xs {
1497
+ padding: 0.125rem 0.375rem;
1498
+ font-size: 0.6875rem;
1499
+ }
1500
+
1501
+ /* ─── Badges ────────────────────────────────────────────────── */
1502
+ .rn-badge {
1503
+ display: inline-flex;
1504
+ align-items: center;
1505
+ padding: 0.125rem 0.5rem;
1506
+ border-radius: 0.375rem;
1507
+ font-size: 0.75rem;
1508
+ font-weight: 600;
1509
+ white-space: nowrap;
1510
+ }
1511
+ .rn-badge-danger {
1512
+ background: var(--rn-badge-danger-bg);
1513
+ color: var(--rn-badge-danger-text);
1514
+ border: 1px solid var(--rn-badge-danger-border);
1515
+ }
1516
+ .rn-badge-success {
1517
+ background: var(--rn-success-light);
1518
+ color: var(--rn-success);
1519
+ }
1520
+ .rn-badge-warning {
1521
+ background: var(--rn-badge-warning-bg);
1522
+ color: var(--rn-badge-warning-text);
1523
+ }
1524
+ .rn-badge-info {
1525
+ background: var(--rn-badge-info-bg);
1526
+ color: var(--rn-badge-info-text);
1527
+ }
1528
+ .rn-badge-muted {
1529
+ background: var(--rn-badge-bg);
1530
+ color: var(--rn-badge-text);
1531
+ }
1532
+
1533
+ /* ─── Table ─────────────────────────────────────────────────── */
1534
+ .rn-table-wrap { overflow-x: auto; }
1535
+ .rn-table { min-width: 100%; }
1536
+ .rn-table thead { background: var(--rn-bg-secondary); }
1537
+ .rn-table th {
1538
+ padding: 0.625rem 1rem;
1539
+ text-align: left;
1540
+ font-size: 0.6875rem;
1541
+ font-weight: 600;
1542
+ text-transform: uppercase;
1543
+ letter-spacing: 0.05em;
1544
+ color: var(--rn-text-muted);
1545
+ border-bottom: 1px solid var(--rn-border);
1546
+ white-space: nowrap;
1547
+ user-select: none;
1548
+ }
1549
+ .rn-table th.sortable {
1550
+ cursor: pointer;
1551
+ transition: color var(--rn-transition);
1552
+ }
1553
+ .rn-table th.sortable:hover { color: var(--rn-text); }
1554
+ .rn-table th.sortable a { color: inherit; text-decoration: none; }
1555
+ .rn-table th.sorted-asc::after { content: " ▲"; font-size: 0.5rem; }
1556
+ .rn-table th.sorted-desc::after { content: " ▼"; font-size: 0.5rem; }
1557
+ .rn-table td {
1558
+ padding: 0.75rem 1rem;
1559
+ vertical-align: top;
1560
+ border-bottom: 1px solid var(--rn-border-light);
1561
+ }
1562
+ .rn-table tbody tr {
1563
+ transition: background var(--rn-transition);
1564
+ cursor: pointer;
1565
+ }
1566
+ .rn-table tbody tr:hover {
1567
+ background: var(--rn-surface-hover);
1568
+ }
1569
+ .rn-table tbody tr.selected {
1570
+ background: var(--rn-primary-light);
1571
+ }
1572
+ .rn-table tbody tr.selected td:first-child::before {
1573
+ content: "";
1574
+ position: absolute;
1575
+ left: 0;
1576
+ top: 0;
1577
+ bottom: 0;
1578
+ width: 3px;
1579
+ background: var(--rn-primary);
1580
+ }
1581
+ .rn-table .rn-name { font-weight: 500; color: var(--rn-primary); }
1582
+ .rn-table .rn-name:hover { text-decoration: underline; }
1583
+ .rn-table .rn-msg {
1584
+ font-size: 0.8125rem;
1585
+ color: var(--rn-text-secondary);
1586
+ overflow: hidden;
1587
+ text-overflow: ellipsis;
1588
+ white-space: nowrap;
1589
+ max-width: 16rem;
1590
+ }
1591
+ .rn-table .rn-date {
1592
+ font-size: 0.75rem;
1593
+ color: var(--rn-text-muted);
1594
+ white-space: nowrap;
1595
+ }
1596
+
1597
+ .rn-exceptions-table {
1598
+ table-layout: fixed;
1599
+ min-width: 74rem;
1600
+ }
1601
+ .rn-exceptions-table .rn-col-severity { width: 2rem; padding-right: 0; }
1602
+ .rn-exceptions-table .rn-col-exception { width: 11.5rem; }
1603
+ .rn-exceptions-table .rn-col-platform { width: 6.5rem; }
1604
+ .rn-exceptions-table .rn-col-source { width: 12rem; }
1605
+ .rn-exceptions-table .rn-col-message { width: 16rem; }
1606
+ .rn-exceptions-table .rn-col-count { width: 5rem; text-align: center; }
1607
+ .rn-exceptions-table .rn-col-workflow { width: 12rem; }
1608
+ .rn-exceptions-table .rn-col-time { width: 7rem; }
1609
+ .rn-exceptions-table .rn-col-actions { width: 5rem; }
1610
+ .rn-exceptions-table .rn-exception-name {
1611
+ display: block;
1612
+ overflow: hidden;
1613
+ text-overflow: ellipsis;
1614
+ white-space: nowrap;
1615
+ font-weight: 600;
1616
+ font-size: 0.8125rem;
1617
+ }
1618
+ .rn-exceptions-table .rn-source {
1619
+ display: flex;
1620
+ min-width: 0;
1621
+ overflow: hidden;
1622
+ white-space: nowrap;
1623
+ }
1624
+ .rn-exceptions-table .rn-source > span {
1625
+ overflow: hidden;
1626
+ text-overflow: ellipsis;
1627
+ }
1628
+ .rn-exceptions-table .rn-row-meta {
1629
+ display: block;
1630
+ margin-top: 0.25rem;
1631
+ overflow: hidden;
1632
+ color: var(--rn-text-muted);
1633
+ font-size: 0.6875rem;
1634
+ line-height: 1;
1635
+ text-overflow: ellipsis;
1636
+ white-space: nowrap;
1637
+ }
1638
+ .rn-exceptions-table .rn-workflow-state {
1639
+ display: flex;
1640
+ align-items: flex-start;
1641
+ flex-wrap: wrap;
1642
+ gap: 0.25rem;
1643
+ }
1644
+ .rn-exceptions-table .rn-workflow-state .rn-row-meta { flex-basis: 100%; }
1645
+ .rn-exceptions-table tbody tr {
1646
+ position: relative;
1647
+ border-left: 3px solid transparent;
1648
+ }
1649
+ .rn-exceptions-table tbody tr:hover {
1650
+ border-left-color: var(--rn-primary);
1651
+ }
1652
+ .rn-exceptions-table tbody tr.selected {
1653
+ border-left-color: var(--rn-primary);
1654
+ background: var(--rn-primary-light);
1655
+ }
1656
+
1657
+ /* ─── Row count indicator ───────────────────────────────────── */
1658
+ .rn-count-indicator {
1659
+ width: 1.5rem;
1660
+ height: 1.5rem;
1661
+ border-radius: 50%;
1662
+ display: inline-flex;
1663
+ align-items: center;
1664
+ justify-content: center;
1665
+ font-size: 0.625rem;
1666
+ font-weight: 700;
1667
+ }
1668
+
1669
+ /* ─── Detail Panel (split view) ─────────────────────────────── */
1670
+ .rn-detail-panel {
1671
+ border-left: 1px solid var(--rn-border);
1672
+ background: var(--rn-surface);
1673
+ overflow-y: auto;
1674
+ transition: background var(--rn-transition);
1675
+ }
1676
+ .rn-detail-header {
1677
+ padding: 1rem 1.5rem;
1678
+ border-bottom: 1px solid var(--rn-border-light);
1679
+ display: flex;
1680
+ align-items: flex-start;
1681
+ justify-content: space-between;
1682
+ gap: 1rem;
1683
+ position: sticky;
1684
+ top: 0;
1685
+ background: var(--rn-surface);
1686
+ z-index: 5;
1687
+ }
1688
+ .rn-detail-body { padding: 1.5rem; }
1689
+
1690
+ /* ─── Detail Sections ───────────────────────────────────────── */
1691
+ .rn-detail-section {
1692
+ margin-bottom: 1.5rem;
1693
+ }
1694
+ .rn-detail-section-header {
1695
+ display: flex;
1696
+ align-items: center;
1697
+ justify-content: space-between;
1698
+ margin-bottom: 0.75rem;
1699
+ }
1700
+ .rn-detail-section h3 {
1701
+ font-size: 0.6875rem;
1702
+ font-weight: 600;
1703
+ text-transform: uppercase;
1704
+ letter-spacing: 0.05em;
1705
+ color: var(--rn-text-muted);
1706
+ }
1707
+ .rn-detail-code {
1708
+ background: var(--rn-code-bg);
1709
+ color: var(--rn-code-text);
1710
+ padding: 0.75rem;
1711
+ border-radius: var(--rn-radius-sm);
1712
+ overflow-x: auto;
1713
+ white-space: pre-wrap;
1714
+ word-break: break-all;
1715
+ font-size: 0.8125rem;
1716
+ border: 1px solid var(--rn-border-light);
1717
+ }
1718
+ .rn-detail-pre {
1719
+ background: var(--rn-pre-bg);
1720
+ color: var(--rn-pre-text);
1721
+ padding: 0.75rem;
1722
+ border-radius: var(--rn-radius-sm);
1723
+ overflow: auto;
1724
+ max-height: 24rem;
1725
+ font-size: 0.75rem;
1726
+ line-height: 1.625;
1727
+ }
1728
+
1729
+ /* ─── Metadata Grid ─────────────────────────────────────────── */
1730
+ .rn-meta {
1731
+ display: grid;
1732
+ grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
1733
+ gap: 0.75rem;
1734
+ }
1735
+ .rn-meta-item {
1736
+ padding: 0.75rem;
1737
+ background: var(--rn-bg-secondary);
1738
+ border-radius: var(--rn-radius-sm);
1739
+ }
1740
+ .rn-meta-label {
1741
+ font-size: 0.6875rem;
1742
+ font-weight: 600;
1743
+ text-transform: uppercase;
1744
+ letter-spacing: 0.05em;
1745
+ color: var(--rn-text-muted);
1746
+ margin-bottom: 0.25rem;
1747
+ }
1748
+ .rn-meta-value {
1749
+ font-size: 0.875rem;
1750
+ color: var(--rn-text);
1751
+ font-weight: 500;
1752
+ word-break: break-all;
1753
+ }
1754
+ .rn-meta-value.mono {
1755
+ font-family: "SF Mono", "Fira Code", monospace;
1756
+ font-size: 0.8125rem;
1757
+ }
1758
+
1759
+ /* ─── Navigation (prev/next) ────────────────────────────────── */
1760
+ .rn-nav-row {
1761
+ display: flex;
1762
+ align-items: center;
1763
+ justify-content: space-between;
1764
+ padding: 1rem 1.5rem;
1765
+ border-top: 1px solid var(--rn-border-light);
1766
+ background: var(--rn-bg-secondary);
1767
+ }
1768
+ .rn-nav-link {
1769
+ display: flex;
1770
+ align-items: center;
1771
+ gap: 0.5rem;
1772
+ padding: 0.5rem 1rem;
1773
+ background: var(--rn-surface);
1774
+ border: 1px solid var(--rn-border);
1775
+ border-radius: var(--rn-radius-sm);
1776
+ font-size: 0.8125rem;
1777
+ color: var(--rn-text-secondary);
1778
+ text-decoration: none;
1779
+ transition: all var(--rn-transition);
1780
+ max-width: 240px;
1781
+ overflow: hidden;
1782
+ }
1783
+ .rn-nav-link:hover {
1784
+ border-color: var(--rn-primary);
1785
+ color: var(--rn-primary);
1786
+ text-decoration: none;
1787
+ }
1788
+ .rn-nav-link-label {
1789
+ font-size: 0.6875rem;
1790
+ color: var(--rn-text-muted);
1791
+ font-weight: 600;
1792
+ text-transform: uppercase;
1793
+ letter-spacing: 0.05em;
1794
+ }
1795
+ .rn-nav-link-title {
1796
+ overflow: hidden;
1797
+ text-overflow: ellipsis;
1798
+ white-space: nowrap;
1799
+ }
1800
+
1801
+ /* ─── Copy button ───────────────────────────────────────────── */
1802
+ .rn-copy-btn {
1803
+ display: inline-flex;
1804
+ align-items: center;
1805
+ gap: 0.25rem;
1806
+ padding: 0.25rem 0.5rem;
1807
+ background: transparent;
1808
+ border: 1px solid var(--rn-border);
1809
+ border-radius: 0.375rem;
1810
+ font-size: 0.6875rem;
1811
+ color: var(--rn-text-muted);
1812
+ cursor: pointer;
1813
+ transition: all var(--rn-transition);
1814
+ }
1815
+ .rn-copy-btn:hover {
1816
+ color: var(--rn-text);
1817
+ border-color: var(--rn-text-muted);
1818
+ }
1819
+ .rn-copy-btn.copied {
1820
+ color: var(--rn-success);
1821
+ border-color: var(--rn-success);
1822
+ }
1823
+
1824
+ /* ─── Keyboard shortcut hints ───────────────────────────────── */
1825
+ .rn-kbd {
1826
+ display: inline-flex;
1827
+ align-items: center;
1828
+ justify-content: center;
1829
+ min-width: 1.25rem;
1830
+ height: 1.25rem;
1831
+ padding: 0 0.25rem;
1832
+ border: 1px solid var(--rn-border);
1833
+ border-radius: 0.25rem;
1834
+ font-size: 0.625rem;
1835
+ font-family: inherit;
1836
+ color: var(--rn-text-muted);
1837
+ background: var(--rn-bg-secondary);
1838
+ }
1839
+
1840
+ /* ─── Keyboard shortcuts dialog ─────────────────────────────── */
1841
+ .rn-shortcuts-overlay {
1842
+ position: fixed;
1843
+ inset: 0;
1844
+ background: rgba(0,0,0,0.5);
1845
+ z-index: 100;
1846
+ display: none;
1847
+ align-items: center;
1848
+ justify-content: center;
1849
+ backdrop-filter: blur(4px);
1850
+ }
1851
+ .rn-shortcuts-overlay.open { display: flex; }
1852
+ .rn-shortcuts {
1853
+ background: var(--rn-surface);
1854
+ border: 1px solid var(--rn-border);
1855
+ border-radius: var(--rn-radius-xl);
1856
+ box-shadow: var(--rn-shadow-lg);
1857
+ padding: 1.5rem;
1858
+ width: 100%;
1859
+ max-width: 28rem;
1860
+ max-height: 80vh;
1861
+ overflow-y: auto;
1862
+ }
1863
+ .rn-shortcuts h3 {
1864
+ font-size: 1rem;
1865
+ font-weight: 700;
1866
+ margin-bottom: 1rem;
1867
+ }
1868
+ .rn-shortcut-row {
1869
+ display: flex;
1870
+ align-items: center;
1871
+ justify-content: space-between;
1872
+ padding: 0.5rem 0;
1873
+ border-bottom: 1px solid var(--rn-border-light);
1874
+ }
1875
+ .rn-shortcut-row:last-child { border-bottom: none; }
1876
+ .rn-shortcut-label {
1877
+ font-size: 0.875rem;
1878
+ color: var(--rn-text-secondary);
1879
+ }
1880
+ .rn-shortcut-keys {
1881
+ display: flex;
1882
+ align-items: center;
1883
+ gap: 0.25rem;
1884
+ }
1885
+
1886
+ /* ─── Empty State ───────────────────────────────────────────── */
1887
+ .rn-empty {
1888
+ padding: 3rem 1rem;
1889
+ text-align: center;
1890
+ color: var(--rn-text-muted);
1891
+ font-size: 0.875rem;
1892
+ }
1893
+
1894
+ /* ─── Status Indicator ──────────────────────────────────────── */
1895
+ .rn-pulse {
1896
+ display: inline-block;
1897
+ width: 0.375rem;
1898
+ height: 0.375rem;
1899
+ border-radius: 50%;
1900
+ background: var(--rn-danger);
1901
+ animation: rn-pulse 2s ease-in-out infinite;
1902
+ }
1903
+ @keyframes rn-pulse {
1904
+ 0%, 100% { opacity: 1; }
1905
+ 50% { opacity: 0.4; }
1906
+ }
1907
+
1908
+ /* ─── Pagination ────────────────────────────────────────────── */
1909
+ .rn-pagination {
1910
+ border-top: 1px solid var(--rn-border-light);
1911
+ padding: 0.75rem 1rem;
1912
+ font-size: 0.875rem;
1913
+ display: flex;
1914
+ align-items: center;
1915
+ justify-content: space-between;
1916
+ }
1917
+ .rn-pagination .pagination {
1918
+ display: flex;
1919
+ flex-wrap: wrap;
1920
+ gap: 0.25rem;
1921
+ align-items: center;
1922
+ list-style: none;
1923
+ margin: 0;
1924
+ padding: 0;
1925
+ }
1926
+ .rn-pagination .pagination a,
1927
+ .rn-pagination .pagination span { padding: 0.25rem 0.5rem; border-radius: var(--rn-radius-sm); }
1928
+ .rn-pagination .pagination a { color: var(--rn-primary); }
1929
+ .rn-pagination .pagination a:hover { background: var(--rn-primary-light); text-decoration: none; }
1930
+ .rn-pagination .pagination .current {
1931
+ background: var(--rn-primary);
1932
+ color: white;
1933
+ font-weight: 600;
1934
+ }
1935
+
1936
+ /* ─── Utilities ─────────────────────────────────────────────── */
1937
+ .sr-only {
1938
+ position: absolute;
1939
+ width: 1px;
1940
+ height: 1px;
1941
+ padding: 0;
1942
+ margin: -1px;
1943
+ overflow: hidden;
1944
+ clip: rect(0,0,0,0);
1945
+ border: 0;
1946
+ }
1947
+ .rn-truncate {
1948
+ overflow: hidden;
1949
+ text-overflow: ellipsis;
1950
+ white-space: nowrap;
1951
+ }
1952
+ .rn-mono { font-family: "SF Mono", "Fira Code", monospace; }
1953
+ .rn-text-xs { font-size: 0.75rem; }
1954
+ .rn-text-sm { font-size: 0.875rem; }
1955
+ .rn-text-muted { color: var(--rn-text-muted); }
1956
+ .rn-font-semibold { font-weight: 600; }
1957
+
1958
+ /* ─── Layout (override host app resets) ─────────────────── */
1959
+ html { height: 100%; }
1960
+ body { height: 100vh; overflow: hidden; margin: 0; }
1961
+ body > div.min-h-full { height: 100vh; min-height: 100vh; }
1962
+ body > div.min-h-full > .rn-sidebar { height: 100vh; min-height: 100vh; }
1963
+ body > div.min-h-full > div:last-child { display: flex; flex-direction: column; overflow: hidden; }
1964
+ body > div.min-h-full > div:last-child > main { flex: 1; overflow-y: auto; }