rails-profiler 0.1.4

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 (65) hide show
  1. checksums.yaml +7 -0
  2. data/app/assets/builds/profiler-toolbar.js +1191 -0
  3. data/app/assets/builds/profiler.css +2668 -0
  4. data/app/assets/builds/profiler.js +2772 -0
  5. data/app/controllers/profiler/api/ajax_controller.rb +36 -0
  6. data/app/controllers/profiler/api/jobs_controller.rb +39 -0
  7. data/app/controllers/profiler/api/outbound_http_controller.rb +36 -0
  8. data/app/controllers/profiler/api/profiles_controller.rb +60 -0
  9. data/app/controllers/profiler/api/toolbar_controller.rb +44 -0
  10. data/app/controllers/profiler/application_controller.rb +19 -0
  11. data/app/controllers/profiler/assets_controller.rb +29 -0
  12. data/app/controllers/profiler/profiles_controller.rb +107 -0
  13. data/app/views/layouts/profiler/application.html.erb +16 -0
  14. data/app/views/layouts/profiler/embedded.html.erb +34 -0
  15. data/app/views/profiler/profiles/index.html.erb +1 -0
  16. data/app/views/profiler/profiles/show.html.erb +4 -0
  17. data/config/routes.rb +36 -0
  18. data/exe/profiler-mcp +8 -0
  19. data/lib/profiler/collectors/ajax_collector.rb +109 -0
  20. data/lib/profiler/collectors/base_collector.rb +92 -0
  21. data/lib/profiler/collectors/cache_collector.rb +96 -0
  22. data/lib/profiler/collectors/database_collector.rb +113 -0
  23. data/lib/profiler/collectors/dump_collector.rb +98 -0
  24. data/lib/profiler/collectors/flamegraph_collector.rb +182 -0
  25. data/lib/profiler/collectors/http_collector.rb +112 -0
  26. data/lib/profiler/collectors/job_collector.rb +50 -0
  27. data/lib/profiler/collectors/performance_collector.rb +103 -0
  28. data/lib/profiler/collectors/request_collector.rb +80 -0
  29. data/lib/profiler/collectors/view_collector.rb +79 -0
  30. data/lib/profiler/configuration.rb +81 -0
  31. data/lib/profiler/engine.rb +17 -0
  32. data/lib/profiler/instrumentation/active_job_instrumentation.rb +22 -0
  33. data/lib/profiler/instrumentation/net_http_instrumentation.rb +153 -0
  34. data/lib/profiler/instrumentation/sidekiq_middleware.rb +18 -0
  35. data/lib/profiler/job_profiler.rb +118 -0
  36. data/lib/profiler/mcp/resources/n1_patterns.rb +62 -0
  37. data/lib/profiler/mcp/resources/recent_jobs.rb +39 -0
  38. data/lib/profiler/mcp/resources/recent_requests.rb +35 -0
  39. data/lib/profiler/mcp/resources/slow_queries.rb +47 -0
  40. data/lib/profiler/mcp/server.rb +217 -0
  41. data/lib/profiler/mcp/tools/analyze_queries.rb +124 -0
  42. data/lib/profiler/mcp/tools/clear_profiles.rb +22 -0
  43. data/lib/profiler/mcp/tools/get_profile_ajax.rb +66 -0
  44. data/lib/profiler/mcp/tools/get_profile_detail.rb +326 -0
  45. data/lib/profiler/mcp/tools/get_profile_dumps.rb +51 -0
  46. data/lib/profiler/mcp/tools/get_profile_http.rb +104 -0
  47. data/lib/profiler/mcp/tools/query_jobs.rb +60 -0
  48. data/lib/profiler/mcp/tools/query_profiles.rb +66 -0
  49. data/lib/profiler/middleware/cors_middleware.rb +55 -0
  50. data/lib/profiler/middleware/profiler_middleware.rb +151 -0
  51. data/lib/profiler/middleware/toolbar_injector.rb +378 -0
  52. data/lib/profiler/models/profile.rb +182 -0
  53. data/lib/profiler/models/sql_query.rb +48 -0
  54. data/lib/profiler/models/timeline_event.rb +40 -0
  55. data/lib/profiler/railtie.rb +75 -0
  56. data/lib/profiler/storage/base_store.rb +41 -0
  57. data/lib/profiler/storage/blob_store.rb +46 -0
  58. data/lib/profiler/storage/file_store.rb +119 -0
  59. data/lib/profiler/storage/memory_store.rb +94 -0
  60. data/lib/profiler/storage/redis_store.rb +98 -0
  61. data/lib/profiler/storage/sqlite_store.rb +272 -0
  62. data/lib/profiler/tasks/profiler.rake +79 -0
  63. data/lib/profiler/version.rb +5 -0
  64. data/lib/profiler.rb +68 -0
  65. metadata +194 -0
@@ -0,0 +1,2668 @@
1
+ @import url("https://fonts.googleapis.com/css2?family=Outfit:wght@400;500;600;700&family=JetBrains+Mono:ital,wght@0,400;0,500;0,600;1,400&display=swap");
2
+ :root,
3
+ [data-theme=dark] {
4
+ --profiler-bg: #080b10;
5
+ --profiler-bg-light: #0d1117;
6
+ --profiler-bg-lighter: #131920;
7
+ --profiler-bg-elevated: #1a2030;
8
+ --profiler-bg-overlay: rgba(8, 11, 16, 0.96);
9
+ --profiler-text: #eef2f7;
10
+ --profiler-text-secondary: #a8b4c2;
11
+ --profiler-text-muted: #5e7080;
12
+ --profiler-text-subtle: #3d4f5f;
13
+ --profiler-text-on-accent: #08090c;
14
+ --profiler-accent: #f59e0b;
15
+ --profiler-accent-hover: #fbbf24;
16
+ --profiler-accent-dim: #92600a;
17
+ --profiler-accent-bg: rgba(245, 158, 11, 0.1);
18
+ --profiler-accent-glow: rgba(245, 158, 11, 0.35);
19
+ --profiler-success: #22c55e;
20
+ --profiler-success-bg: rgba(34, 197, 94, 0.1);
21
+ --profiler-success-glow: rgba(34, 197, 94, 0.3);
22
+ --profiler-warning: #fb923c;
23
+ --profiler-warning-bg: rgba(251, 146, 60, 0.1);
24
+ --profiler-warning-glow: rgba(251, 146, 60, 0.3);
25
+ --profiler-error: #f87171;
26
+ --profiler-error-bg: rgba(248, 113, 113, 0.1);
27
+ --profiler-error-glow: rgba(248, 113, 113, 0.3);
28
+ --profiler-info: #60a5fa;
29
+ --profiler-info-bg: rgba(96, 165, 250, 0.1);
30
+ --profiler-info-glow: rgba(96, 165, 250, 0.3);
31
+ --profiler-border: rgba(255, 255, 255, 0.07);
32
+ --profiler-border-strong: rgba(255, 255, 255, 0.14);
33
+ --profiler-border-accent: rgba(245, 158, 11, 0.3);
34
+ --profiler-shadow-sm: 0 1px 4px rgba(0, 0, 0, 0.4);
35
+ --profiler-shadow-md: 0 4px 16px rgba(0, 0, 0, 0.5);
36
+ --profiler-shadow-lg: 0 8px 32px rgba(0, 0, 0, 0.6);
37
+ --profiler-shadow-xl: 0 16px 48px rgba(0, 0, 0, 0.7);
38
+ --profiler-glass-bg: rgba(13, 17, 23, 0.85);
39
+ --profiler-glass-border: rgba(255, 255, 255, 0.06);
40
+ --profiler-blur: blur(20px) saturate(180%);
41
+ }
42
+
43
+ [data-theme=light] {
44
+ --profiler-bg: #f5f3ef;
45
+ --profiler-bg-light: #edeae3;
46
+ --profiler-bg-lighter: #e3ded5;
47
+ --profiler-bg-elevated: #ffffff;
48
+ --profiler-bg-overlay: rgba(245, 243, 239, 0.96);
49
+ --profiler-text: #1c1410;
50
+ --profiler-text-secondary: #4a3f35;
51
+ --profiler-text-muted: #8a7a6e;
52
+ --profiler-text-subtle: #b5a898;
53
+ --profiler-text-on-accent: #ffffff;
54
+ --profiler-accent: #b45309;
55
+ --profiler-accent-hover: #92400e;
56
+ --profiler-accent-dim: #d97706;
57
+ --profiler-accent-bg: rgba(180, 83, 9, 0.08);
58
+ --profiler-accent-glow: rgba(180, 83, 9, 0.2);
59
+ --profiler-success: #15803d;
60
+ --profiler-success-bg: rgba(21, 128, 61, 0.08);
61
+ --profiler-success-glow: rgba(21, 128, 61, 0.2);
62
+ --profiler-warning: #c2410c;
63
+ --profiler-warning-bg: rgba(194, 65, 12, 0.08);
64
+ --profiler-warning-glow: rgba(194, 65, 12, 0.2);
65
+ --profiler-error: #dc2626;
66
+ --profiler-error-bg: rgba(220, 38, 38, 0.08);
67
+ --profiler-error-glow: rgba(220, 38, 38, 0.2);
68
+ --profiler-info: #1d4ed8;
69
+ --profiler-info-bg: rgba(29, 78, 216, 0.08);
70
+ --profiler-info-glow: rgba(29, 78, 216, 0.2);
71
+ --profiler-border: rgba(28, 20, 16, 0.1);
72
+ --profiler-border-strong: rgba(28, 20, 16, 0.2);
73
+ --profiler-border-accent: rgba(180, 83, 9, 0.3);
74
+ --profiler-shadow-sm: 0 1px 3px rgba(28, 20, 16, 0.08);
75
+ --profiler-shadow-md: 0 4px 12px rgba(28, 20, 16, 0.1);
76
+ --profiler-shadow-lg: 0 8px 24px rgba(28, 20, 16, 0.12);
77
+ --profiler-shadow-xl: 0 16px 40px rgba(28, 20, 16, 0.15);
78
+ --profiler-glass-bg: rgba(245, 243, 239, 0.88);
79
+ --profiler-glass-border: rgba(28, 20, 16, 0.08);
80
+ --profiler-blur: blur(16px) saturate(140%);
81
+ }
82
+
83
+ @media (prefers-color-scheme: light) {
84
+ :root:not([data-theme]) {
85
+ --profiler-bg: #f5f3ef;
86
+ --profiler-bg-light: #edeae3;
87
+ --profiler-bg-lighter: #e3ded5;
88
+ --profiler-bg-elevated: #ffffff;
89
+ --profiler-bg-overlay: rgba(245, 243, 239, 0.96);
90
+ --profiler-text: #1c1410;
91
+ --profiler-text-secondary: #4a3f35;
92
+ --profiler-text-muted: #8a7a6e;
93
+ --profiler-text-subtle: #b5a898;
94
+ --profiler-text-on-accent: #ffffff;
95
+ --profiler-accent: #b45309;
96
+ --profiler-accent-hover: #92400e;
97
+ --profiler-accent-dim: #d97706;
98
+ --profiler-accent-bg: rgba(180, 83, 9, 0.08);
99
+ --profiler-accent-glow: rgba(180, 83, 9, 0.2);
100
+ --profiler-success: #15803d;
101
+ --profiler-success-bg: rgba(21, 128, 61, 0.08);
102
+ --profiler-success-glow: rgba(21, 128, 61, 0.2);
103
+ --profiler-warning: #c2410c;
104
+ --profiler-warning-bg: rgba(194, 65, 12, 0.08);
105
+ --profiler-warning-glow: rgba(194, 65, 12, 0.2);
106
+ --profiler-error: #dc2626;
107
+ --profiler-error-bg: rgba(220, 38, 38, 0.08);
108
+ --profiler-error-glow: rgba(220, 38, 38, 0.2);
109
+ --profiler-info: #1d4ed8;
110
+ --profiler-info-bg: rgba(29, 78, 216, 0.08);
111
+ --profiler-info-glow: rgba(29, 78, 216, 0.2);
112
+ --profiler-border: rgba(28, 20, 16, 0.1);
113
+ --profiler-border-strong: rgba(28, 20, 16, 0.2);
114
+ --profiler-border-accent: rgba(180, 83, 9, 0.3);
115
+ --profiler-shadow-sm: 0 1px 3px rgba(28, 20, 16, 0.08);
116
+ --profiler-shadow-md: 0 4px 12px rgba(28, 20, 16, 0.1);
117
+ --profiler-shadow-lg: 0 8px 24px rgba(28, 20, 16, 0.12);
118
+ --profiler-shadow-xl: 0 16px 40px rgba(28, 20, 16, 0.15);
119
+ --profiler-glass-bg: rgba(245, 243, 239, 0.88);
120
+ --profiler-glass-border: rgba(28, 20, 16, 0.08);
121
+ --profiler-blur: blur(16px) saturate(140%);
122
+ }
123
+ }
124
+ :root {
125
+ --profiler-font-sans: 'Outfit', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
126
+ --profiler-font-mono: 'JetBrains Mono', 'SF Mono', 'Fira Code', 'Cascadia Code', monospace;
127
+ --profiler-text-xs: 10px;
128
+ --profiler-text-sm: 11px;
129
+ --profiler-text-base: 13px;
130
+ --profiler-text-lg: 15px;
131
+ --profiler-text-xl: 18px;
132
+ --profiler-text-2xl: 22px;
133
+ --profiler-text-3xl: 28px;
134
+ --profiler-space-1: 4px;
135
+ --profiler-space-2: 8px;
136
+ --profiler-space-3: 12px;
137
+ --profiler-space-4: 16px;
138
+ --profiler-space-6: 24px;
139
+ --profiler-space-8: 32px;
140
+ --profiler-space-12: 48px;
141
+ --profiler-radius-sm: 4px;
142
+ --profiler-radius-md: 6px;
143
+ --profiler-radius-lg: 10px;
144
+ --profiler-radius-full: 9999px;
145
+ --profiler-transition-fast: 120ms cubic-bezier(0.4, 0, 0.2, 1);
146
+ --profiler-transition-base: 220ms cubic-bezier(0.4, 0, 0.2, 1);
147
+ --profiler-transition-slow: 350ms cubic-bezier(0.4, 0, 0.2, 1);
148
+ --profiler-transition-elastic: 500ms cubic-bezier(0.34, 1.56, 0.64, 1);
149
+ --profiler-z-toolbar: 999999;
150
+ --profiler-z-panel: 1000000;
151
+ --profiler-z-modal: 1000001;
152
+ }
153
+
154
+ .profiler-theme-toggle {
155
+ display: inline-flex;
156
+ align-items: center;
157
+ justify-content: center;
158
+ width: 32px;
159
+ height: 32px;
160
+ background: var(--profiler-bg-lighter);
161
+ border: 1px solid var(--profiler-border);
162
+ border-radius: var(--profiler-radius-sm);
163
+ cursor: pointer;
164
+ transition: all var(--profiler-transition-base);
165
+ color: var(--profiler-text-muted);
166
+ font-size: 14px;
167
+ }
168
+ .profiler-theme-toggle:hover {
169
+ background: var(--profiler-accent-bg);
170
+ border-color: var(--profiler-border-accent);
171
+ color: var(--profiler-accent);
172
+ transform: scale(1.08);
173
+ }
174
+ .profiler-theme-toggle:active {
175
+ transform: scale(0.94);
176
+ }
177
+
178
+ *,
179
+ *::before,
180
+ *::after {
181
+ margin: 0;
182
+ padding: 0;
183
+ box-sizing: border-box;
184
+ }
185
+
186
+ body {
187
+ font-family: var(--profiler-font-sans);
188
+ background: var(--profiler-bg);
189
+ color: var(--profiler-text);
190
+ line-height: 1.6;
191
+ font-size: var(--profiler-text-base);
192
+ -webkit-font-smoothing: antialiased;
193
+ -moz-osx-font-smoothing: grayscale;
194
+ }
195
+
196
+ .container {
197
+ max-width: 1400px;
198
+ margin: 0 auto;
199
+ padding: var(--profiler-space-8) var(--profiler-space-6);
200
+ }
201
+ @media (max-width: 768px) {
202
+ .container {
203
+ padding: var(--profiler-space-6) var(--profiler-space-4);
204
+ }
205
+ }
206
+
207
+ .header {
208
+ margin-bottom: var(--profiler-space-8);
209
+ padding-bottom: var(--profiler-space-6);
210
+ border-bottom: 1px solid var(--profiler-border);
211
+ animation: fadeInDown 400ms cubic-bezier(0.4, 0, 0.2, 1) both;
212
+ }
213
+ .header h1 {
214
+ font-size: var(--profiler-text-3xl);
215
+ font-weight: 700;
216
+ letter-spacing: -0.03em;
217
+ line-height: 1.15;
218
+ margin-bottom: var(--profiler-space-2);
219
+ color: var(--profiler-text);
220
+ background: linear-gradient(125deg, var(--profiler-accent) 0%, var(--profiler-accent-hover) 60%, var(--profiler-warning) 100%);
221
+ -webkit-background-clip: text;
222
+ -webkit-text-fill-color: transparent;
223
+ background-clip: text;
224
+ }
225
+ .header h1 .h1-emoji {
226
+ -webkit-text-fill-color: initial;
227
+ }
228
+ .header h1 a {
229
+ color: inherit;
230
+ text-decoration: none;
231
+ background: inherit;
232
+ -webkit-background-clip: inherit;
233
+ -webkit-text-fill-color: inherit;
234
+ background-clip: inherit;
235
+ }
236
+ .header h1 a:hover {
237
+ opacity: 0.75;
238
+ }
239
+ @media (max-width: 768px) {
240
+ .header h1 {
241
+ font-size: var(--profiler-text-2xl);
242
+ }
243
+ }
244
+ .header p {
245
+ font-size: var(--profiler-text-sm);
246
+ color: var(--profiler-text-muted);
247
+ font-family: var(--profiler-font-mono);
248
+ letter-spacing: 0.03em;
249
+ }
250
+
251
+ a {
252
+ color: var(--profiler-accent);
253
+ text-decoration: none;
254
+ transition: color var(--profiler-transition-fast);
255
+ }
256
+ a:hover {
257
+ color: var(--profiler-accent-hover);
258
+ }
259
+ a:focus-visible {
260
+ outline: 2px solid var(--profiler-border-accent);
261
+ outline-offset: 2px;
262
+ border-radius: var(--profiler-radius-sm);
263
+ }
264
+
265
+ code,
266
+ pre {
267
+ font-family: var(--profiler-font-mono);
268
+ }
269
+
270
+ code {
271
+ background: var(--profiler-accent-bg);
272
+ color: var(--profiler-accent);
273
+ padding: 2px 6px;
274
+ border-radius: var(--profiler-radius-sm);
275
+ border: 1px solid var(--profiler-border-accent);
276
+ font-size: var(--profiler-text-sm);
277
+ }
278
+
279
+ pre {
280
+ background: rgba(0, 0, 0, 0.25);
281
+ padding: var(--profiler-space-4);
282
+ border-radius: var(--profiler-radius-md);
283
+ border: 1px solid var(--profiler-border);
284
+ overflow-x: auto;
285
+ line-height: 1.65;
286
+ color: var(--profiler-text-secondary);
287
+ }
288
+ pre code {
289
+ background: none;
290
+ padding: 0;
291
+ border: none;
292
+ color: inherit;
293
+ font-size: inherit;
294
+ }
295
+
296
+ [data-theme=light] pre {
297
+ background: rgba(0, 0, 0, 0.03);
298
+ }
299
+
300
+ table {
301
+ width: 100%;
302
+ border-collapse: collapse;
303
+ font-size: var(--profiler-text-base);
304
+ }
305
+ table th {
306
+ text-align: left;
307
+ font-weight: 600;
308
+ font-size: var(--profiler-text-xs);
309
+ text-transform: uppercase;
310
+ letter-spacing: 0.08em;
311
+ color: var(--profiler-text-muted);
312
+ padding: var(--profiler-space-2) var(--profiler-space-3);
313
+ border-bottom: 1px solid var(--profiler-border-strong);
314
+ background: var(--profiler-bg-light);
315
+ white-space: nowrap;
316
+ }
317
+ table td {
318
+ padding: var(--profiler-space-3);
319
+ border-bottom: 1px solid var(--profiler-border);
320
+ color: var(--profiler-text);
321
+ vertical-align: middle;
322
+ font-size: var(--profiler-text-base);
323
+ }
324
+ table tr:last-child td {
325
+ border-bottom: none;
326
+ }
327
+ table tr:hover td {
328
+ background: var(--profiler-bg-lighter);
329
+ }
330
+ table a {
331
+ font-family: var(--profiler-font-mono);
332
+ font-size: var(--profiler-text-sm);
333
+ }
334
+
335
+ ::-webkit-scrollbar {
336
+ width: 8px;
337
+ height: 8px;
338
+ }
339
+
340
+ ::-webkit-scrollbar-track {
341
+ background: transparent;
342
+ }
343
+
344
+ ::-webkit-scrollbar-thumb {
345
+ background: var(--profiler-border-strong);
346
+ border-radius: var(--profiler-radius-full);
347
+ }
348
+ ::-webkit-scrollbar-thumb:hover {
349
+ background: var(--profiler-text-subtle);
350
+ }
351
+
352
+ ::selection {
353
+ background: var(--profiler-accent-bg);
354
+ color: var(--profiler-text);
355
+ }
356
+
357
+ :focus-visible {
358
+ outline: 2px solid var(--profiler-accent);
359
+ outline-offset: 2px;
360
+ border-radius: var(--profiler-radius-sm);
361
+ }
362
+
363
+ .card {
364
+ background: var(--profiler-bg-light);
365
+ border: 1px solid var(--profiler-border);
366
+ border-radius: var(--profiler-radius-lg);
367
+ padding: var(--profiler-space-6);
368
+ box-shadow: var(--profiler-shadow-md);
369
+ transition: all var(--profiler-transition-base);
370
+ }
371
+ .card:hover {
372
+ border-color: var(--profiler-border-strong);
373
+ box-shadow: var(--profiler-shadow-lg);
374
+ transform: translateY(-2px);
375
+ }
376
+
377
+ .btn {
378
+ display: inline-flex;
379
+ align-items: center;
380
+ justify-content: center;
381
+ gap: var(--profiler-space-2);
382
+ padding: var(--profiler-space-2) var(--profiler-space-4);
383
+ font-family: var(--profiler-font-sans);
384
+ font-size: var(--profiler-text-base);
385
+ font-weight: 600;
386
+ border-radius: var(--profiler-radius-sm);
387
+ border: 1px solid transparent;
388
+ cursor: pointer;
389
+ transition: all var(--profiler-transition-base);
390
+ text-decoration: none;
391
+ white-space: nowrap;
392
+ letter-spacing: 0.01em;
393
+ }
394
+ .btn:disabled {
395
+ opacity: 0.45;
396
+ cursor: not-allowed;
397
+ }
398
+ .btn.btn-primary {
399
+ background: var(--profiler-accent-bg);
400
+ color: var(--profiler-accent);
401
+ border-color: var(--profiler-border-accent);
402
+ }
403
+ .btn.btn-primary:hover:not(:disabled) {
404
+ background: var(--profiler-accent);
405
+ color: var(--profiler-text-on-accent);
406
+ transform: translateY(-1px);
407
+ box-shadow: 0 4px 16px var(--profiler-accent-glow);
408
+ }
409
+ .btn.btn-secondary {
410
+ background: var(--profiler-bg-lighter);
411
+ color: var(--profiler-text-secondary);
412
+ border-color: var(--profiler-border);
413
+ }
414
+ .btn.btn-secondary:hover:not(:disabled) {
415
+ background: var(--profiler-bg-elevated);
416
+ border-color: var(--profiler-border-strong);
417
+ color: var(--profiler-text);
418
+ }
419
+ .btn.btn-sm {
420
+ padding: var(--profiler-space-1) var(--profiler-space-3);
421
+ font-size: var(--profiler-text-sm);
422
+ }
423
+ .btn.btn-danger {
424
+ background: transparent;
425
+ color: var(--profiler-error);
426
+ border-color: var(--profiler-error);
427
+ }
428
+ .btn.btn-danger:hover:not(:disabled) {
429
+ background: var(--profiler-error);
430
+ color: #fff;
431
+ }
432
+
433
+ .token-copy {
434
+ background: none;
435
+ border: none;
436
+ cursor: pointer;
437
+ font-family: var(--profiler-font-mono);
438
+ font-size: var(--profiler-text-xs);
439
+ color: var(--profiler-text-muted);
440
+ padding: 2px 4px;
441
+ border-radius: var(--profiler-radius-sm);
442
+ transition: color var(--profiler-transition-base), background var(--profiler-transition-base);
443
+ }
444
+ .token-copy:hover {
445
+ color: var(--profiler-accent);
446
+ background: var(--profiler-accent-bg);
447
+ }
448
+
449
+ .btn-row-delete {
450
+ background: none;
451
+ border: none;
452
+ cursor: pointer;
453
+ color: var(--profiler-text-muted);
454
+ font-size: var(--profiler-text-base);
455
+ line-height: 1;
456
+ padding: 2px 6px;
457
+ border-radius: var(--profiler-radius-sm);
458
+ transition: color var(--profiler-transition-base), background var(--profiler-transition-base);
459
+ opacity: 0;
460
+ }
461
+ tr:hover .btn-row-delete {
462
+ opacity: 1;
463
+ }
464
+ .btn-row-delete:hover {
465
+ color: var(--profiler-error);
466
+ background: var(--profiler-error-bg);
467
+ }
468
+
469
+ .badge,
470
+ [class*=badge-] {
471
+ display: inline-flex;
472
+ align-items: center;
473
+ padding: 2px 7px;
474
+ border-radius: var(--profiler-radius-sm);
475
+ font-family: var(--profiler-font-mono);
476
+ font-size: var(--profiler-text-xs);
477
+ font-weight: 600;
478
+ letter-spacing: 0.04em;
479
+ white-space: nowrap;
480
+ }
481
+
482
+ .badge {
483
+ background: var(--profiler-bg-lighter);
484
+ color: var(--profiler-text-secondary);
485
+ border: 1px solid var(--profiler-border);
486
+ }
487
+
488
+ .badge-success {
489
+ background: var(--profiler-success-bg);
490
+ color: var(--profiler-success);
491
+ border: 1px solid rgba(34, 197, 94, 0.2);
492
+ }
493
+
494
+ .badge-warning {
495
+ background: var(--profiler-warning-bg);
496
+ color: var(--profiler-warning);
497
+ border: 1px solid rgba(251, 146, 60, 0.2);
498
+ }
499
+
500
+ .badge-error {
501
+ background: var(--profiler-error-bg);
502
+ color: var(--profiler-error);
503
+ border: 1px solid rgba(248, 113, 113, 0.2);
504
+ }
505
+
506
+ .badge-info {
507
+ background: var(--profiler-info-bg);
508
+ color: var(--profiler-info);
509
+ border: 1px solid rgba(96, 165, 250, 0.2);
510
+ }
511
+
512
+ .badge-default {
513
+ background: var(--profiler-bg-lighter);
514
+ color: var(--profiler-text-muted);
515
+ border: 1px solid var(--profiler-border);
516
+ }
517
+
518
+ @keyframes fadeInDown {
519
+ from {
520
+ opacity: 0;
521
+ transform: translateY(-12px);
522
+ }
523
+ to {
524
+ opacity: 1;
525
+ transform: translateY(0);
526
+ }
527
+ }
528
+ @keyframes fadeIn {
529
+ from {
530
+ opacity: 0;
531
+ }
532
+ to {
533
+ opacity: 1;
534
+ }
535
+ }
536
+ @keyframes fadeInUp {
537
+ from {
538
+ opacity: 0;
539
+ transform: translateY(12px);
540
+ }
541
+ to {
542
+ opacity: 1;
543
+ transform: translateY(0);
544
+ }
545
+ }
546
+ @keyframes spin {
547
+ to {
548
+ transform: rotate(360deg);
549
+ }
550
+ }
551
+ @keyframes pulse {
552
+ 0%, 100% {
553
+ opacity: 1;
554
+ }
555
+ 50% {
556
+ opacity: 0.45;
557
+ }
558
+ }
559
+ .animate-fade-in {
560
+ animation: fadeIn 300ms ease both;
561
+ }
562
+
563
+ .animate-fade-in-up {
564
+ animation: fadeInUp 400ms ease both;
565
+ }
566
+
567
+ .loading-spinner {
568
+ display: inline-block;
569
+ width: 18px;
570
+ height: 18px;
571
+ border: 2px solid var(--profiler-border-strong);
572
+ border-top-color: var(--profiler-accent);
573
+ border-radius: 50%;
574
+ animation: spin 700ms linear infinite;
575
+ }
576
+
577
+ @media (max-width: 768px) {
578
+ .hidden-mobile {
579
+ display: none !important;
580
+ }
581
+ }
582
+ @media (min-width: 769px) {
583
+ .hidden-desktop {
584
+ display: none !important;
585
+ }
586
+ }
587
+ .profiler-flex {
588
+ display: flex;
589
+ align-items: center;
590
+ }
591
+ .profiler-flex--center {
592
+ justify-content: center;
593
+ }
594
+ .profiler-flex--between {
595
+ justify-content: space-between;
596
+ }
597
+ .profiler-flex--column {
598
+ flex-direction: column;
599
+ align-items: flex-start;
600
+ }
601
+ .profiler-flex--gap-1 {
602
+ gap: var(--profiler-space-1);
603
+ }
604
+ .profiler-flex--gap-2 {
605
+ gap: var(--profiler-space-2);
606
+ }
607
+ .profiler-flex--gap-3 {
608
+ gap: var(--profiler-space-3);
609
+ }
610
+ .profiler-flex--gap-4 {
611
+ gap: var(--profiler-space-4);
612
+ }
613
+ .profiler-flex--gap-6 {
614
+ gap: var(--profiler-space-6);
615
+ }
616
+
617
+ .profiler-grid {
618
+ display: grid;
619
+ gap: var(--profiler-space-4);
620
+ }
621
+ .profiler-grid--2 {
622
+ grid-template-columns: repeat(2, 1fr);
623
+ }
624
+ .profiler-grid--3 {
625
+ grid-template-columns: repeat(3, 1fr);
626
+ }
627
+ .profiler-grid--auto {
628
+ grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
629
+ }
630
+
631
+ .profiler-mt-1 {
632
+ margin-top: var(--profiler-space-1);
633
+ }
634
+
635
+ .profiler-mt-2 {
636
+ margin-top: var(--profiler-space-2);
637
+ }
638
+
639
+ .profiler-mt-3 {
640
+ margin-top: var(--profiler-space-3);
641
+ }
642
+
643
+ .profiler-mt-4 {
644
+ margin-top: var(--profiler-space-4);
645
+ }
646
+
647
+ .profiler-mt-6 {
648
+ margin-top: var(--profiler-space-6);
649
+ }
650
+
651
+ .profiler-mt-8 {
652
+ margin-top: var(--profiler-space-8);
653
+ }
654
+
655
+ .profiler-mb-1 {
656
+ margin-bottom: var(--profiler-space-1);
657
+ }
658
+
659
+ .profiler-mb-2 {
660
+ margin-bottom: var(--profiler-space-2);
661
+ }
662
+
663
+ .profiler-mb-3 {
664
+ margin-bottom: var(--profiler-space-3);
665
+ }
666
+
667
+ .profiler-mb-4 {
668
+ margin-bottom: var(--profiler-space-4);
669
+ }
670
+
671
+ .profiler-mb-6 {
672
+ margin-bottom: var(--profiler-space-6);
673
+ }
674
+
675
+ .profiler-p-2 {
676
+ padding: var(--profiler-space-2);
677
+ }
678
+
679
+ .profiler-p-3 {
680
+ padding: var(--profiler-space-3);
681
+ }
682
+
683
+ .profiler-p-4 {
684
+ padding: var(--profiler-space-4);
685
+ }
686
+
687
+ .profiler-p-6 {
688
+ padding: var(--profiler-space-6);
689
+ }
690
+
691
+ .profiler-text--xs {
692
+ font-size: var(--profiler-text-xs);
693
+ }
694
+ .profiler-text--sm {
695
+ font-size: var(--profiler-text-sm);
696
+ }
697
+ .profiler-text--base {
698
+ font-size: var(--profiler-text-base);
699
+ }
700
+ .profiler-text--lg {
701
+ font-size: var(--profiler-text-lg);
702
+ }
703
+ .profiler-text--xl {
704
+ font-size: var(--profiler-text-xl);
705
+ }
706
+ .profiler-text--2xl {
707
+ font-size: var(--profiler-text-2xl);
708
+ }
709
+ .profiler-text--muted {
710
+ color: var(--profiler-text-muted);
711
+ }
712
+ .profiler-text--subtle {
713
+ color: var(--profiler-text-subtle);
714
+ }
715
+ .profiler-text--secondary {
716
+ color: var(--profiler-text-secondary);
717
+ }
718
+ .profiler-text--success {
719
+ color: var(--profiler-success);
720
+ }
721
+ .profiler-text--warning {
722
+ color: var(--profiler-warning);
723
+ }
724
+ .profiler-text--error {
725
+ color: var(--profiler-error);
726
+ }
727
+ .profiler-text--accent {
728
+ color: var(--profiler-accent);
729
+ }
730
+ .profiler-text--uppercase {
731
+ text-transform: uppercase;
732
+ letter-spacing: 0.08em;
733
+ }
734
+ .profiler-text--mono {
735
+ font-family: var(--profiler-font-mono);
736
+ }
737
+ .profiler-text--truncate {
738
+ overflow: hidden;
739
+ text-overflow: ellipsis;
740
+ white-space: nowrap;
741
+ }
742
+ .profiler-text--break {
743
+ word-break: break-all;
744
+ }
745
+
746
+ .profiler-panel {
747
+ background: var(--profiler-bg-elevated);
748
+ border: 1px solid var(--profiler-border);
749
+ border-radius: var(--profiler-radius-md);
750
+ padding: var(--profiler-space-4);
751
+ }
752
+ .profiler-panel--sm {
753
+ padding: var(--profiler-space-3);
754
+ }
755
+ .profiler-panel--lg {
756
+ padding: var(--profiler-space-6);
757
+ }
758
+
759
+ .profiler-stat-card {
760
+ background: var(--profiler-bg-light);
761
+ border: 1px solid var(--profiler-border);
762
+ border-radius: var(--profiler-radius-md);
763
+ padding: var(--profiler-space-4);
764
+ transition: all var(--profiler-transition-base);
765
+ }
766
+ .profiler-stat-card:hover {
767
+ border-color: var(--profiler-border-accent);
768
+ box-shadow: var(--profiler-shadow-sm);
769
+ transform: translateY(-2px);
770
+ }
771
+ .profiler-stat-card__label {
772
+ font-size: var(--profiler-text-xs);
773
+ text-transform: uppercase;
774
+ letter-spacing: 0.1em;
775
+ color: var(--profiler-text-muted);
776
+ margin-bottom: var(--profiler-space-2);
777
+ font-family: var(--profiler-font-mono);
778
+ }
779
+ .profiler-stat-card__value {
780
+ font-size: var(--profiler-text-2xl);
781
+ font-weight: 700;
782
+ font-family: var(--profiler-font-mono);
783
+ color: var(--profiler-accent);
784
+ line-height: 1.1;
785
+ }
786
+ .profiler-stat-card__value small {
787
+ font-size: var(--profiler-text-sm);
788
+ color: var(--profiler-text-muted);
789
+ font-weight: 500;
790
+ margin-left: var(--profiler-space-1);
791
+ }
792
+
793
+ .profiler-kv-row {
794
+ display: flex;
795
+ justify-content: space-between;
796
+ align-items: center;
797
+ padding: var(--profiler-space-2) 0;
798
+ border-bottom: 1px solid var(--profiler-border);
799
+ gap: var(--profiler-space-4);
800
+ }
801
+ .profiler-kv-row:last-child {
802
+ border-bottom: none;
803
+ }
804
+ .profiler-kv-row > span:first-child {
805
+ color: var(--profiler-text-muted);
806
+ font-size: var(--profiler-text-sm);
807
+ flex-shrink: 0;
808
+ }
809
+ .profiler-kv-row > *:last-child {
810
+ color: var(--profiler-text);
811
+ font-weight: 600;
812
+ font-family: var(--profiler-font-mono);
813
+ font-size: var(--profiler-text-sm);
814
+ text-align: right;
815
+ }
816
+
817
+ .profiler-query-card {
818
+ background: var(--profiler-bg-light);
819
+ border: 1px solid var(--profiler-border);
820
+ border-radius: var(--profiler-radius-md);
821
+ padding: var(--profiler-space-3);
822
+ margin-bottom: var(--profiler-space-3);
823
+ transition: all var(--profiler-transition-base);
824
+ }
825
+ .profiler-query-card:hover {
826
+ border-color: var(--profiler-border-strong);
827
+ transform: translateX(3px);
828
+ box-shadow: var(--profiler-shadow-sm);
829
+ }
830
+ .profiler-query-card--slow {
831
+ border-left: 3px solid var(--profiler-error);
832
+ background: var(--profiler-error-bg);
833
+ }
834
+ .profiler-query-card--slow:hover {
835
+ box-shadow: 0 0 16px var(--profiler-error-glow);
836
+ }
837
+ .profiler-query-card--success {
838
+ border-left: 3px solid var(--profiler-success);
839
+ }
840
+ .profiler-query-card__header {
841
+ display: flex;
842
+ justify-content: space-between;
843
+ align-items: center;
844
+ margin-bottom: var(--profiler-space-2);
845
+ gap: var(--profiler-space-3);
846
+ }
847
+ .profiler-query-card__duration {
848
+ font-weight: 700;
849
+ font-family: var(--profiler-font-mono);
850
+ font-size: var(--profiler-text-sm);
851
+ color: var(--profiler-accent);
852
+ }
853
+ .profiler-query-card__duration--slow {
854
+ color: var(--profiler-error);
855
+ }
856
+ .profiler-query-card__duration--fast {
857
+ color: var(--profiler-success);
858
+ }
859
+ .profiler-query-card__code {
860
+ font-size: var(--profiler-text-sm);
861
+ color: var(--profiler-info);
862
+ font-family: var(--profiler-font-mono);
863
+ overflow: hidden;
864
+ text-overflow: ellipsis;
865
+ white-space: nowrap;
866
+ display: block;
867
+ line-height: 1.5;
868
+ }
869
+
870
+ .profiler-dump-card {
871
+ background: var(--profiler-bg-light);
872
+ border: 1px solid var(--profiler-border);
873
+ border-left: 3px solid var(--profiler-warning);
874
+ border-radius: var(--profiler-radius-md);
875
+ padding: var(--profiler-space-4);
876
+ margin-bottom: var(--profiler-space-4);
877
+ }
878
+ .profiler-dump-card__header {
879
+ display: flex;
880
+ justify-content: space-between;
881
+ align-items: flex-start;
882
+ margin-bottom: var(--profiler-space-3);
883
+ }
884
+ .profiler-dump-card__label {
885
+ display: inline-block;
886
+ background: var(--profiler-warning-bg);
887
+ color: var(--profiler-warning);
888
+ border: 1px solid rgba(251, 146, 60, 0.3);
889
+ padding: 2px 8px;
890
+ border-radius: var(--profiler-radius-sm);
891
+ font-size: var(--profiler-text-xs);
892
+ font-weight: 600;
893
+ font-family: var(--profiler-font-mono);
894
+ margin-left: var(--profiler-space-2);
895
+ }
896
+ .profiler-dump-card__location {
897
+ font-size: var(--profiler-text-xs);
898
+ color: var(--profiler-info);
899
+ font-family: var(--profiler-font-mono);
900
+ text-align: right;
901
+ }
902
+ .profiler-dump-card__content {
903
+ background: var(--profiler-bg-lighter);
904
+ border: 1px solid var(--profiler-border);
905
+ border-radius: var(--profiler-radius-sm);
906
+ padding: var(--profiler-space-3);
907
+ overflow-x: auto;
908
+ }
909
+ .profiler-dump-card__content pre {
910
+ color: var(--profiler-warning);
911
+ margin: 0;
912
+ font-size: var(--profiler-text-sm);
913
+ line-height: 1.6;
914
+ background: none;
915
+ border: none;
916
+ padding: 0;
917
+ }
918
+
919
+ .profiler-ajax-card {
920
+ background: var(--profiler-bg-light);
921
+ border: 1px solid var(--profiler-border);
922
+ border-left: 3px solid;
923
+ border-radius: var(--profiler-radius-md);
924
+ padding: var(--profiler-space-3);
925
+ margin-bottom: var(--profiler-space-2);
926
+ transition: all var(--profiler-transition-base);
927
+ }
928
+ .profiler-ajax-card--success {
929
+ border-left-color: var(--profiler-success);
930
+ }
931
+ .profiler-ajax-card--error {
932
+ border-left-color: var(--profiler-error);
933
+ }
934
+ .profiler-ajax-card:hover {
935
+ background: var(--profiler-bg-elevated);
936
+ transform: translateX(3px);
937
+ box-shadow: var(--profiler-shadow-sm);
938
+ }
939
+ .profiler-ajax-card__row {
940
+ display: flex;
941
+ justify-content: space-between;
942
+ align-items: center;
943
+ gap: var(--profiler-space-3);
944
+ }
945
+ .profiler-ajax-card__row + .profiler-ajax-card__row {
946
+ margin-top: var(--profiler-space-2);
947
+ }
948
+ .profiler-ajax-card__path {
949
+ color: var(--profiler-text-secondary);
950
+ font-size: var(--profiler-text-sm);
951
+ font-family: var(--profiler-font-mono);
952
+ overflow: hidden;
953
+ text-overflow: ellipsis;
954
+ white-space: nowrap;
955
+ flex: 1;
956
+ }
957
+ .profiler-ajax-card__time {
958
+ font-size: var(--profiler-text-xs);
959
+ color: var(--profiler-text-muted);
960
+ font-family: var(--profiler-font-mono);
961
+ }
962
+
963
+ .profiler-empty {
964
+ display: flex;
965
+ flex-direction: column;
966
+ align-items: center;
967
+ padding: var(--profiler-space-12) var(--profiler-space-6);
968
+ text-align: center;
969
+ color: var(--profiler-text-muted);
970
+ }
971
+ .profiler-empty__icon {
972
+ font-size: 52px;
973
+ margin-bottom: var(--profiler-space-4);
974
+ opacity: 0.4;
975
+ filter: grayscale(1);
976
+ }
977
+ .profiler-empty__title {
978
+ font-size: var(--profiler-text-lg);
979
+ font-weight: 600;
980
+ color: var(--profiler-text);
981
+ margin-bottom: var(--profiler-space-3);
982
+ }
983
+ .profiler-empty__description {
984
+ font-size: var(--profiler-text-base);
985
+ line-height: 1.7;
986
+ max-width: 420px;
987
+ color: var(--profiler-text-muted);
988
+ }
989
+ .profiler-empty__description code {
990
+ background: var(--profiler-accent-bg);
991
+ color: var(--profiler-accent);
992
+ border: 1px solid var(--profiler-border-accent);
993
+ }
994
+
995
+ .profiler-divider {
996
+ border: none;
997
+ border-top: 1px solid var(--profiler-border);
998
+ margin: var(--profiler-space-4) 0;
999
+ }
1000
+ .profiler-divider--strong {
1001
+ border-top-color: var(--profiler-border-strong);
1002
+ }
1003
+ .profiler-divider--sm {
1004
+ margin: var(--profiler-space-2) 0;
1005
+ }
1006
+ .profiler-divider--lg {
1007
+ margin: var(--profiler-space-6) 0;
1008
+ }
1009
+
1010
+ .profiler-more {
1011
+ text-align: center;
1012
+ padding: var(--profiler-space-3) var(--profiler-space-4);
1013
+ color: var(--profiler-text-muted);
1014
+ font-size: var(--profiler-text-xs);
1015
+ font-family: var(--profiler-font-mono);
1016
+ letter-spacing: 0.05em;
1017
+ border-top: 1px dashed var(--profiler-border);
1018
+ margin-top: var(--profiler-space-2);
1019
+ }
1020
+
1021
+ .profiler-float-right {
1022
+ float: right;
1023
+ }
1024
+
1025
+ .profiler-float-left {
1026
+ float: left;
1027
+ }
1028
+
1029
+ .profiler-clearfix::after {
1030
+ content: "";
1031
+ display: table;
1032
+ clear: both;
1033
+ }
1034
+
1035
+ .profiler-code {
1036
+ background: var(--profiler-bg-light);
1037
+ border: 1px solid var(--profiler-border);
1038
+ border-radius: var(--profiler-radius-md);
1039
+ font-family: var(--profiler-font-mono);
1040
+ font-size: var(--profiler-text-xs);
1041
+ color: var(--profiler-text);
1042
+ padding: var(--profiler-space-3);
1043
+ margin: 0;
1044
+ white-space: pre-wrap;
1045
+ word-break: break-all;
1046
+ overflow-x: auto;
1047
+ line-height: 1.6;
1048
+ }
1049
+
1050
+ .profiler-body-csv {
1051
+ width: 100%;
1052
+ border-collapse: collapse;
1053
+ font-size: var(--profiler-text-xs);
1054
+ font-family: var(--profiler-font-mono);
1055
+ }
1056
+ .profiler-body-csv th {
1057
+ background: var(--profiler-bg-elevated);
1058
+ color: var(--profiler-text-muted);
1059
+ font-weight: 600;
1060
+ text-align: left;
1061
+ padding: 4px 8px;
1062
+ border: 1px solid var(--profiler-border);
1063
+ white-space: nowrap;
1064
+ }
1065
+ .profiler-body-csv td {
1066
+ padding: 3px 8px;
1067
+ border: 1px solid var(--profiler-border);
1068
+ color: var(--profiler-text);
1069
+ word-break: break-all;
1070
+ }
1071
+ .profiler-body-csv tbody tr:nth-child(even) {
1072
+ background: var(--profiler-bg-elevated);
1073
+ }
1074
+
1075
+ .profiler-body-binary {
1076
+ display: flex;
1077
+ flex-direction: column;
1078
+ gap: var(--profiler-space-2);
1079
+ padding: var(--profiler-space-3);
1080
+ background: var(--profiler-bg-elevated);
1081
+ border: 1px solid var(--profiler-border);
1082
+ border-radius: var(--profiler-radius-md);
1083
+ }
1084
+
1085
+ .profiler-body-preview-frame {
1086
+ width: 100%;
1087
+ height: 400px;
1088
+ border: 1px solid var(--profiler-border);
1089
+ border-radius: var(--profiler-radius-sm);
1090
+ }
1091
+
1092
+ .profiler-body-download-btn {
1093
+ display: inline-flex;
1094
+ align-items: center;
1095
+ gap: var(--profiler-space-1);
1096
+ padding: 4px 10px;
1097
+ background: var(--profiler-accent-bg);
1098
+ color: var(--profiler-accent);
1099
+ border: 1px solid var(--profiler-border-accent);
1100
+ border-radius: var(--profiler-radius-sm);
1101
+ text-decoration: none;
1102
+ font-family: var(--profiler-font-mono);
1103
+ transition: all var(--profiler-transition-base);
1104
+ }
1105
+ .profiler-body-download-btn:hover {
1106
+ background: var(--profiler-accent);
1107
+ color: #fff;
1108
+ }
1109
+
1110
+ #profiler-toolbar {
1111
+ position: fixed;
1112
+ bottom: 0;
1113
+ left: 0;
1114
+ right: 0;
1115
+ height: 44px;
1116
+ background: var(--profiler-glass-bg);
1117
+ backdrop-filter: var(--profiler-blur);
1118
+ -webkit-backdrop-filter: var(--profiler-blur);
1119
+ border-top: 1px solid var(--profiler-border-strong);
1120
+ z-index: var(--profiler-z-toolbar);
1121
+ font-family: var(--profiler-font-mono);
1122
+ font-size: 11px;
1123
+ animation: toolbarIn 300ms cubic-bezier(0.4, 0, 0.2, 1) both;
1124
+ }
1125
+ #profiler-toolbar::before {
1126
+ content: "";
1127
+ position: absolute;
1128
+ top: -1px;
1129
+ left: 0;
1130
+ right: 0;
1131
+ height: 1px;
1132
+ background: linear-gradient(90deg, transparent 0%, var(--profiler-accent) 15%, var(--profiler-accent-hover) 50%, var(--profiler-accent) 85%, transparent 100%);
1133
+ opacity: 0.65;
1134
+ }
1135
+ @keyframes toolbarIn {
1136
+ from {
1137
+ transform: translateY(100%);
1138
+ opacity: 0;
1139
+ }
1140
+ to {
1141
+ transform: translateY(0);
1142
+ opacity: 1;
1143
+ }
1144
+ }
1145
+
1146
+ .profiler-toolbar-container {
1147
+ display: flex;
1148
+ align-items: stretch;
1149
+ height: 100%;
1150
+ }
1151
+
1152
+ .profiler-toolbar-item {
1153
+ position: relative;
1154
+ display: inline-flex;
1155
+ align-items: center;
1156
+ gap: 5px;
1157
+ padding: 0 16px;
1158
+ color: var(--profiler-text-muted);
1159
+ text-decoration: none;
1160
+ white-space: nowrap;
1161
+ font-weight: 500;
1162
+ letter-spacing: 0.01em;
1163
+ cursor: default;
1164
+ background: transparent;
1165
+ border: none;
1166
+ border-right: 1px solid var(--profiler-border);
1167
+ transition: color var(--profiler-transition-fast), background var(--profiler-transition-fast);
1168
+ }
1169
+ .profiler-toolbar-item::after {
1170
+ content: "";
1171
+ position: absolute;
1172
+ bottom: 0;
1173
+ left: 0;
1174
+ right: 0;
1175
+ height: 2px;
1176
+ background: var(--profiler-accent);
1177
+ transform: scaleX(0);
1178
+ transform-origin: left;
1179
+ transition: transform var(--profiler-transition-base);
1180
+ }
1181
+ .profiler-toolbar-item:last-child {
1182
+ border-right: none;
1183
+ margin-left: auto;
1184
+ padding-left: 20px;
1185
+ }
1186
+ .profiler-toolbar-item:hover {
1187
+ color: var(--profiler-text);
1188
+ background: var(--profiler-accent-bg);
1189
+ }
1190
+ .profiler-toolbar-item:hover::after {
1191
+ transform: scaleX(1);
1192
+ }
1193
+
1194
+ a.profiler-toolbar-item {
1195
+ cursor: pointer;
1196
+ font-family: var(--profiler-font-mono);
1197
+ font-size: 11px;
1198
+ }
1199
+
1200
+ .profiler-text--success {
1201
+ color: var(--profiler-success) !important;
1202
+ }
1203
+
1204
+ .profiler-text--warning {
1205
+ color: var(--profiler-warning) !important;
1206
+ }
1207
+
1208
+ .profiler-text--error {
1209
+ color: var(--profiler-error) !important;
1210
+ }
1211
+
1212
+ .profiler-text--muted {
1213
+ color: var(--profiler-text-muted) !important;
1214
+ }
1215
+
1216
+ .profiler-text--accent {
1217
+ color: var(--profiler-accent) !important;
1218
+ }
1219
+
1220
+ a.profiler-toolbar-item.profiler-text--error::after {
1221
+ background: var(--profiler-error);
1222
+ }
1223
+
1224
+ a.profiler-toolbar-item.profiler-text--warning::after {
1225
+ background: var(--profiler-warning);
1226
+ }
1227
+
1228
+ .profiler-toolbar-hoverable {
1229
+ position: relative;
1230
+ }
1231
+ .profiler-toolbar-hoverable .profiler-toolbar-panel {
1232
+ display: none;
1233
+ position: absolute;
1234
+ bottom: calc(100% + 12px);
1235
+ left: 50%;
1236
+ transform: translateX(-50%);
1237
+ min-width: 320px;
1238
+ max-width: 440px;
1239
+ background: var(--profiler-bg-elevated);
1240
+ border: 1px solid var(--profiler-border-strong);
1241
+ border-radius: var(--profiler-radius-lg);
1242
+ box-shadow: var(--profiler-shadow-xl), 0 0 0 1px var(--profiler-border-accent);
1243
+ z-index: var(--profiler-z-panel);
1244
+ overflow: hidden;
1245
+ }
1246
+ .profiler-toolbar-hoverable .profiler-toolbar-panel::before {
1247
+ content: "";
1248
+ position: absolute;
1249
+ top: 0;
1250
+ left: 0;
1251
+ right: 0;
1252
+ height: 2px;
1253
+ background: linear-gradient(90deg, var(--profiler-accent) 0%, var(--profiler-accent-hover) 100%);
1254
+ }
1255
+ .profiler-toolbar-hoverable .profiler-toolbar-panel::after {
1256
+ content: "";
1257
+ position: absolute;
1258
+ top: 100%;
1259
+ left: 50%;
1260
+ transform: translateX(-50%);
1261
+ border: 6px solid transparent;
1262
+ border-top-color: var(--profiler-border-strong);
1263
+ }
1264
+ .profiler-toolbar-hoverable .profiler-toolbar-panel.profiler-toolbar-panel-large {
1265
+ min-width: 440px;
1266
+ max-width: 580px;
1267
+ }
1268
+
1269
+ .profiler-toolbar-panel-header {
1270
+ display: flex;
1271
+ align-items: center;
1272
+ justify-content: space-between;
1273
+ padding: 11px 16px 9px;
1274
+ font-size: 10px;
1275
+ font-weight: 700;
1276
+ letter-spacing: 0.12em;
1277
+ text-transform: uppercase;
1278
+ color: var(--profiler-accent);
1279
+ background: var(--profiler-accent-bg);
1280
+ border-bottom: 1px solid var(--profiler-border);
1281
+ font-family: var(--profiler-font-mono);
1282
+ }
1283
+
1284
+ .profiler-float-right {
1285
+ color: var(--profiler-text-muted);
1286
+ font-weight: 400;
1287
+ text-transform: none;
1288
+ letter-spacing: 0;
1289
+ font-size: 10px;
1290
+ font-family: var(--profiler-font-mono);
1291
+ }
1292
+
1293
+ .profiler-toolbar-panel-content {
1294
+ padding: 10px 16px 14px;
1295
+ max-height: 420px;
1296
+ overflow-y: auto;
1297
+ font-size: 11px;
1298
+ font-family: var(--profiler-font-mono);
1299
+ scrollbar-width: thin;
1300
+ scrollbar-color: var(--profiler-border-strong) transparent;
1301
+ }
1302
+ .profiler-toolbar-panel-content::-webkit-scrollbar {
1303
+ width: 4px;
1304
+ }
1305
+ .profiler-toolbar-panel-content::-webkit-scrollbar-thumb {
1306
+ background: var(--profiler-border-strong);
1307
+ border-radius: var(--profiler-radius-full);
1308
+ }
1309
+
1310
+ .profiler-toolbar-panel-row {
1311
+ display: flex;
1312
+ justify-content: space-between;
1313
+ align-items: baseline;
1314
+ padding: 6px 0;
1315
+ border-bottom: 1px solid var(--profiler-border);
1316
+ gap: 12px;
1317
+ }
1318
+ .profiler-toolbar-panel-row:last-child {
1319
+ border-bottom: none;
1320
+ }
1321
+ .profiler-toolbar-panel-row span {
1322
+ color: var(--profiler-text-muted);
1323
+ font-size: 10px;
1324
+ flex-shrink: 0;
1325
+ }
1326
+ .profiler-toolbar-panel-row strong {
1327
+ color: var(--profiler-text);
1328
+ font-weight: 600;
1329
+ text-align: right;
1330
+ font-variant-numeric: tabular-nums;
1331
+ word-break: break-all;
1332
+ }
1333
+
1334
+ .profiler-section__header {
1335
+ font-size: 10px;
1336
+ font-weight: 700;
1337
+ letter-spacing: 0.1em;
1338
+ text-transform: uppercase;
1339
+ color: var(--profiler-accent);
1340
+ padding: 10px 0 4px;
1341
+ border-bottom: 1px solid var(--profiler-border-accent);
1342
+ margin-bottom: 6px;
1343
+ font-family: var(--profiler-font-mono);
1344
+ }
1345
+ .profiler-section__header:first-child {
1346
+ padding-top: 4px;
1347
+ }
1348
+
1349
+ .profiler-toolbar-panel-query {
1350
+ padding: 9px 10px;
1351
+ background: var(--profiler-bg-lighter);
1352
+ border: 1px solid var(--profiler-border);
1353
+ border-radius: var(--profiler-radius-sm);
1354
+ margin-bottom: 6px;
1355
+ transition: all var(--profiler-transition-fast);
1356
+ }
1357
+ .profiler-toolbar-panel-query:last-child {
1358
+ margin-bottom: 0;
1359
+ }
1360
+ .profiler-toolbar-panel-query:hover {
1361
+ border-color: var(--profiler-border-strong);
1362
+ transform: translateX(2px);
1363
+ }
1364
+ .profiler-toolbar-panel-query.profiler-toolbar-panel-query-slow {
1365
+ border-left: 2px solid var(--profiler-error);
1366
+ background: var(--profiler-error-bg);
1367
+ }
1368
+ .profiler-toolbar-panel-query code {
1369
+ display: block;
1370
+ overflow: hidden;
1371
+ text-overflow: ellipsis;
1372
+ white-space: nowrap;
1373
+ color: var(--profiler-info);
1374
+ font-size: 10px;
1375
+ line-height: 1.5;
1376
+ margin-top: 4px;
1377
+ }
1378
+
1379
+ .profiler-more {
1380
+ text-align: center;
1381
+ padding: 8px;
1382
+ color: var(--profiler-text-muted);
1383
+ font-size: 10px;
1384
+ letter-spacing: 0.05em;
1385
+ border-top: 1px dashed var(--profiler-border);
1386
+ margin-top: 6px;
1387
+ }
1388
+
1389
+ .container > table {
1390
+ width: 100%;
1391
+ border-collapse: collapse;
1392
+ background: var(--profiler-bg-light);
1393
+ border: 1px solid var(--profiler-border);
1394
+ border-radius: var(--profiler-radius-lg);
1395
+ overflow: hidden;
1396
+ box-shadow: var(--profiler-shadow-md);
1397
+ }
1398
+ .container > table thead {
1399
+ background: var(--profiler-accent-bg);
1400
+ border-bottom: 1px solid var(--profiler-border-accent);
1401
+ }
1402
+ .container > table thead th {
1403
+ font-weight: 600;
1404
+ font-size: var(--profiler-text-xs);
1405
+ letter-spacing: 0.1em;
1406
+ text-transform: uppercase;
1407
+ color: var(--profiler-accent);
1408
+ padding: 14px 20px;
1409
+ border-bottom: none;
1410
+ background: transparent;
1411
+ }
1412
+ .container > table tbody td {
1413
+ padding: 14px 20px;
1414
+ font-size: var(--profiler-text-base);
1415
+ color: var(--profiler-text-secondary);
1416
+ border-bottom: 1px solid var(--profiler-border);
1417
+ vertical-align: middle;
1418
+ }
1419
+ .container > table tbody tr:last-child td {
1420
+ border-bottom: none;
1421
+ }
1422
+ .container > table tbody tr:hover td {
1423
+ background: var(--profiler-accent-bg);
1424
+ color: var(--profiler-text);
1425
+ }
1426
+ .container > table tbody tr:hover td:first-child {
1427
+ border-left: 2px solid var(--profiler-accent);
1428
+ padding-left: 18px;
1429
+ }
1430
+ .container > table a {
1431
+ font-family: var(--profiler-font-mono);
1432
+ font-size: var(--profiler-text-sm);
1433
+ color: var(--profiler-accent);
1434
+ }
1435
+ .container > table a:hover {
1436
+ color: var(--profiler-accent-hover);
1437
+ }
1438
+
1439
+ .tabs {
1440
+ display: flex;
1441
+ align-items: center;
1442
+ border-bottom: 1px solid var(--profiler-border);
1443
+ margin-bottom: var(--profiler-space-6);
1444
+ gap: 2px;
1445
+ overflow-x: auto;
1446
+ scrollbar-width: none;
1447
+ }
1448
+ .tabs::-webkit-scrollbar {
1449
+ display: none;
1450
+ }
1451
+
1452
+ .btn-refresh {
1453
+ flex-shrink: 0;
1454
+ background: none;
1455
+ border: none;
1456
+ cursor: pointer;
1457
+ color: var(--profiler-text-muted);
1458
+ font-size: 1.1rem;
1459
+ line-height: 1;
1460
+ padding: 4px 8px;
1461
+ border-radius: var(--profiler-radius-sm);
1462
+ transition: color var(--profiler-transition-base), background var(--profiler-transition-base);
1463
+ margin-bottom: -1px;
1464
+ }
1465
+ .btn-refresh:hover:not(:disabled) {
1466
+ color: var(--profiler-accent);
1467
+ background: var(--profiler-accent-bg);
1468
+ }
1469
+ .btn-refresh:disabled {
1470
+ cursor: not-allowed;
1471
+ }
1472
+ .btn-refresh--spinning {
1473
+ animation: profiler-spin 0.7s linear infinite;
1474
+ }
1475
+
1476
+ @keyframes profiler-spin {
1477
+ to {
1478
+ transform: rotate(360deg);
1479
+ }
1480
+ }
1481
+ .tab {
1482
+ position: relative;
1483
+ display: flex;
1484
+ align-items: center;
1485
+ gap: 6px;
1486
+ padding: 12px 18px;
1487
+ color: var(--profiler-text-muted);
1488
+ text-decoration: none;
1489
+ font-size: var(--profiler-text-base);
1490
+ font-weight: 500;
1491
+ white-space: nowrap;
1492
+ border-bottom: 2px solid transparent;
1493
+ transition: color var(--profiler-transition-fast), border-color var(--profiler-transition-fast);
1494
+ font-family: var(--profiler-font-sans);
1495
+ cursor: pointer;
1496
+ background: none;
1497
+ border-top: none;
1498
+ border-left: none;
1499
+ border-right: none;
1500
+ }
1501
+ .tab:hover {
1502
+ color: var(--profiler-text);
1503
+ background: var(--profiler-accent-bg);
1504
+ }
1505
+ .tab.active {
1506
+ color: var(--profiler-accent);
1507
+ border-bottom-color: var(--profiler-accent);
1508
+ font-weight: 600;
1509
+ }
1510
+ .tab .tab-icon {
1511
+ font-size: 14px;
1512
+ line-height: 1;
1513
+ }
1514
+
1515
+ .tab-content {
1516
+ display: none;
1517
+ }
1518
+ .tab-content.active {
1519
+ display: block;
1520
+ }
1521
+ .tab-content h2 {
1522
+ font-size: var(--profiler-text-xl);
1523
+ font-weight: 700;
1524
+ color: var(--profiler-text);
1525
+ margin-bottom: var(--profiler-space-4);
1526
+ letter-spacing: -0.02em;
1527
+ }
1528
+ .tab-content h3 {
1529
+ font-size: var(--profiler-text-lg);
1530
+ font-weight: 600;
1531
+ color: var(--profiler-text);
1532
+ margin-bottom: var(--profiler-space-3);
1533
+ }
1534
+ .tab-content table {
1535
+ width: 100%;
1536
+ border-collapse: collapse;
1537
+ background: var(--profiler-bg-light);
1538
+ border: 1px solid var(--profiler-border);
1539
+ border-radius: var(--profiler-radius-md);
1540
+ overflow: hidden;
1541
+ }
1542
+ .tab-content table th {
1543
+ width: 180px;
1544
+ text-align: left;
1545
+ padding: 12px 16px;
1546
+ font-size: var(--profiler-text-xs);
1547
+ font-weight: 600;
1548
+ letter-spacing: 0.08em;
1549
+ text-transform: uppercase;
1550
+ color: var(--profiler-accent);
1551
+ background: var(--profiler-accent-bg);
1552
+ border-bottom: 1px solid var(--profiler-border);
1553
+ border-right: 1px solid var(--profiler-border);
1554
+ vertical-align: top;
1555
+ }
1556
+ .tab-content table td {
1557
+ padding: 12px 16px;
1558
+ font-size: var(--profiler-text-base);
1559
+ color: var(--profiler-text);
1560
+ border-bottom: 1px solid var(--profiler-border);
1561
+ vertical-align: top;
1562
+ }
1563
+ .tab-content table tr:last-child th,
1564
+ .tab-content table tr:last-child td {
1565
+ border-bottom: none;
1566
+ }
1567
+ .tab-content table pre {
1568
+ margin: 0;
1569
+ font-size: var(--profiler-text-sm);
1570
+ }
1571
+
1572
+ .profiler-panel {
1573
+ background: var(--profiler-bg-elevated);
1574
+ border: 1px solid var(--profiler-border);
1575
+ border-radius: var(--profiler-radius-lg);
1576
+ overflow: hidden;
1577
+ box-shadow: var(--profiler-shadow-md);
1578
+ }
1579
+ .profiler-panel--sm {
1580
+ padding: var(--profiler-space-3);
1581
+ border-radius: var(--profiler-radius-md);
1582
+ }
1583
+
1584
+ .profiler-section__header {
1585
+ font-size: var(--profiler-text-xs);
1586
+ font-weight: 600;
1587
+ letter-spacing: 0.1em;
1588
+ text-transform: uppercase;
1589
+ color: var(--profiler-accent);
1590
+ padding-bottom: var(--profiler-space-2);
1591
+ margin-bottom: var(--profiler-space-4);
1592
+ border-bottom: 1px solid var(--profiler-border-accent);
1593
+ font-family: var(--profiler-font-mono);
1594
+ }
1595
+
1596
+ .profiler-action-bar {
1597
+ display: flex;
1598
+ align-items: center;
1599
+ justify-content: space-between;
1600
+ gap: var(--profiler-space-2);
1601
+ flex-wrap: wrap;
1602
+ }
1603
+
1604
+ .profiler-filter-group {
1605
+ display: flex;
1606
+ align-items: center;
1607
+ gap: var(--profiler-space-2);
1608
+ flex-wrap: wrap;
1609
+ }
1610
+
1611
+ .profiler-filter-count {
1612
+ font-size: var(--profiler-text-xs);
1613
+ color: var(--profiler-text-muted);
1614
+ font-family: var(--profiler-font-mono);
1615
+ white-space: nowrap;
1616
+ opacity: 0.7;
1617
+ }
1618
+
1619
+ .profiler-filter-input,
1620
+ .profiler-filter-select {
1621
+ height: 28px;
1622
+ padding: 0 var(--profiler-space-2);
1623
+ background: var(--profiler-bg-lighter);
1624
+ border: 1px solid var(--profiler-border);
1625
+ border-radius: var(--profiler-radius-sm);
1626
+ color: var(--profiler-text);
1627
+ font-family: var(--profiler-font-mono);
1628
+ font-size: var(--profiler-text-xs);
1629
+ transition: border-color var(--profiler-transition-base);
1630
+ }
1631
+ .profiler-filter-input:focus,
1632
+ .profiler-filter-select:focus {
1633
+ outline: none;
1634
+ border-color: var(--profiler-accent);
1635
+ }
1636
+
1637
+ .profiler-filter-input {
1638
+ width: 160px;
1639
+ }
1640
+
1641
+ .profiler-filter-select {
1642
+ cursor: pointer;
1643
+ }
1644
+
1645
+ .profiler-timeline {
1646
+ margin: 24px 0;
1647
+ padding: 24px;
1648
+ background: linear-gradient(135deg, rgba(21, 25, 31, 0.4) 0%, rgba(31, 35, 41, 0.4) 100%);
1649
+ backdrop-filter: blur(12px);
1650
+ border: 1px solid var(--profiler-border);
1651
+ border-radius: 12px;
1652
+ box-shadow: var(--profiler-shadow-md);
1653
+ animation: fadeIn 500ms cubic-bezier(0.4, 0, 0.2, 1);
1654
+ }
1655
+ .profiler-timeline svg {
1656
+ display: block;
1657
+ width: 100%;
1658
+ height: auto;
1659
+ filter: drop-shadow(0 2px 8px rgba(0, 0, 0, 0.2));
1660
+ }
1661
+ .profiler-timeline .timeline-event {
1662
+ cursor: pointer;
1663
+ transition: all var(--profiler-transition-base);
1664
+ transform-origin: center;
1665
+ }
1666
+ .profiler-timeline .timeline-event:hover {
1667
+ opacity: 0.85;
1668
+ transform: scale(1.02);
1669
+ filter: drop-shadow(0 4px 12px rgba(0, 217, 255, 0.3));
1670
+ }
1671
+ .profiler-timeline .timeline-event:active {
1672
+ transform: scale(0.98);
1673
+ }
1674
+ .profiler-timeline .timeline-label {
1675
+ font-size: 11px;
1676
+ font-family: var(--profiler-font-mono);
1677
+ font-weight: 500;
1678
+ fill: var(--profiler-text-secondary);
1679
+ transition: fill var(--profiler-transition-base);
1680
+ }
1681
+ .profiler-timeline .timeline-label:hover {
1682
+ fill: var(--profiler-text);
1683
+ }
1684
+ .profiler-timeline .timeline-bar {
1685
+ rx: 4;
1686
+ transition: all var(--profiler-transition-base);
1687
+ stroke-width: 1;
1688
+ stroke: rgba(0, 0, 0, 0.3);
1689
+ }
1690
+ .profiler-timeline .timeline-bar.controller {
1691
+ fill: #60a5fa;
1692
+ stroke: rgba(96, 165, 250, 0.5);
1693
+ }
1694
+ .profiler-timeline .timeline-bar.controller:hover {
1695
+ fill: #93c5fd;
1696
+ filter: drop-shadow(0 0 8px rgba(96, 165, 250, 0.6));
1697
+ }
1698
+ .profiler-timeline .timeline-bar.view {
1699
+ fill: #34d399;
1700
+ stroke: rgba(52, 211, 153, 0.5);
1701
+ }
1702
+ .profiler-timeline .timeline-bar.view:hover {
1703
+ fill: #6ee7b7;
1704
+ filter: drop-shadow(0 0 8px rgba(52, 211, 153, 0.6));
1705
+ }
1706
+ .profiler-timeline .timeline-bar.partial {
1707
+ fill: #f59e0b;
1708
+ stroke: rgba(245, 158, 11, 0.5);
1709
+ }
1710
+ .profiler-timeline .timeline-bar.partial:hover {
1711
+ fill: #fbbf24;
1712
+ filter: drop-shadow(0 0 8px rgba(245, 158, 11, 0.6));
1713
+ }
1714
+ .profiler-timeline .timeline-bar.database {
1715
+ fill: #fb923c;
1716
+ stroke: rgba(251, 146, 60, 0.5);
1717
+ }
1718
+ .profiler-timeline .timeline-bar.database:hover {
1719
+ fill: #fdba74;
1720
+ filter: drop-shadow(0 0 8px rgba(251, 146, 60, 0.6));
1721
+ }
1722
+ .profiler-timeline .timeline-bar.default {
1723
+ fill: #a78bfa;
1724
+ stroke: rgba(167, 139, 250, 0.5);
1725
+ }
1726
+ .profiler-timeline .timeline-bar.default:hover {
1727
+ fill: #c4b5fd;
1728
+ filter: drop-shadow(0 0 8px rgba(167, 139, 250, 0.6));
1729
+ }
1730
+ .profiler-timeline .timeline-axis {
1731
+ stroke: var(--profiler-border-strong);
1732
+ stroke-width: 2;
1733
+ stroke-linecap: round;
1734
+ }
1735
+ .profiler-timeline .timeline-grid {
1736
+ stroke: var(--profiler-border);
1737
+ stroke-width: 1;
1738
+ stroke-dasharray: 4 4;
1739
+ opacity: 0.2;
1740
+ transition: opacity var(--profiler-transition-base);
1741
+ }
1742
+ .profiler-timeline .timeline-grid:hover {
1743
+ opacity: 0.4;
1744
+ }
1745
+ .profiler-timeline .timeline-legend {
1746
+ display: flex;
1747
+ gap: 20px;
1748
+ margin-top: 20px;
1749
+ padding-top: 20px;
1750
+ border-top: 1px solid var(--profiler-border);
1751
+ flex-wrap: wrap;
1752
+ justify-content: center;
1753
+ }
1754
+ .profiler-timeline .timeline-legend .legend-item {
1755
+ display: flex;
1756
+ align-items: center;
1757
+ gap: 8px;
1758
+ font-size: 12px;
1759
+ font-family: var(--profiler-font-sans);
1760
+ color: var(--profiler-text-muted);
1761
+ padding: 6px 12px;
1762
+ background: rgba(255, 255, 255, 0.02);
1763
+ border-radius: 8px;
1764
+ border: 1px solid var(--profiler-border);
1765
+ transition: all var(--profiler-transition-base);
1766
+ }
1767
+ .profiler-timeline .timeline-legend .legend-item:hover {
1768
+ background: rgba(255, 255, 255, 0.05);
1769
+ color: var(--profiler-text);
1770
+ transform: translateY(-2px);
1771
+ }
1772
+ .profiler-timeline .timeline-legend .legend-item .legend-color {
1773
+ width: 16px;
1774
+ height: 16px;
1775
+ border-radius: 4px;
1776
+ border: 1px solid rgba(0, 0, 0, 0.3);
1777
+ box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.2);
1778
+ }
1779
+ .profiler-timeline .timeline-legend .legend-item .legend-color.controller {
1780
+ background: var(--profiler-accent);
1781
+ box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.2), 0 0 8px rgba(0, 217, 255, 0.3);
1782
+ }
1783
+ .profiler-timeline .timeline-legend .legend-item .legend-color.view {
1784
+ background: var(--profiler-success);
1785
+ box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.2), 0 0 8px rgba(0, 255, 159, 0.3);
1786
+ }
1787
+ .profiler-timeline .timeline-legend .legend-item .legend-color.partial {
1788
+ background: var(--profiler-warning);
1789
+ box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.2), 0 0 8px rgba(255, 107, 53, 0.3);
1790
+ }
1791
+ .profiler-timeline .timeline-legend .legend-item .legend-color.database {
1792
+ background: var(--profiler-warning);
1793
+ box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.2), 0 0 8px rgba(255, 184, 108, 0.3);
1794
+ }
1795
+ .profiler-timeline .timeline-legend .legend-item .legend-color.default {
1796
+ background: var(--profiler-info);
1797
+ box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.2), 0 0 8px rgba(189, 147, 249, 0.3);
1798
+ }
1799
+ .profiler-timeline .timeline-metrics {
1800
+ display: grid;
1801
+ grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
1802
+ gap: 16px;
1803
+ margin-bottom: 24px;
1804
+ }
1805
+ .profiler-timeline .timeline-metrics .metric-card {
1806
+ background: rgba(0, 0, 0, 0.2);
1807
+ border: 1px solid var(--profiler-border);
1808
+ border-radius: 8px;
1809
+ padding: 16px;
1810
+ transition: all var(--profiler-transition-base);
1811
+ }
1812
+ .profiler-timeline .timeline-metrics .metric-card:hover {
1813
+ background: rgba(0, 0, 0, 0.3);
1814
+ border-color: var(--profiler-border-strong);
1815
+ transform: translateY(-2px);
1816
+ box-shadow: var(--profiler-shadow-sm);
1817
+ }
1818
+ .profiler-timeline .timeline-metrics .metric-card .metric-label {
1819
+ font-size: 11px;
1820
+ text-transform: uppercase;
1821
+ letter-spacing: 0.08em;
1822
+ color: var(--profiler-text-muted);
1823
+ margin-bottom: 8px;
1824
+ font-family: var(--profiler-font-sans);
1825
+ }
1826
+ .profiler-timeline .timeline-metrics .metric-card .metric-value {
1827
+ font-size: 24px;
1828
+ font-weight: 700;
1829
+ font-family: var(--profiler-font-mono);
1830
+ color: var(--profiler-accent);
1831
+ line-height: 1;
1832
+ }
1833
+ .profiler-timeline .timeline-metrics .metric-card .metric-value small {
1834
+ font-size: 14px;
1835
+ color: var(--profiler-text-muted);
1836
+ font-weight: 500;
1837
+ margin-left: 4px;
1838
+ }
1839
+ .profiler-timeline .timeline-metrics .metric-card .metric-change {
1840
+ font-size: 11px;
1841
+ margin-top: 6px;
1842
+ font-family: var(--profiler-font-mono);
1843
+ }
1844
+ .profiler-timeline .timeline-metrics .metric-card .metric-change.positive {
1845
+ color: var(--profiler-success);
1846
+ }
1847
+ .profiler-timeline .timeline-metrics .metric-card .metric-change.negative {
1848
+ color: var(--profiler-error);
1849
+ }
1850
+ .profiler-timeline .timeline-metrics .metric-card .metric-change.neutral {
1851
+ color: var(--profiler-text-muted);
1852
+ }
1853
+ .profiler-timeline .timeline-tooltip {
1854
+ position: absolute;
1855
+ background: linear-gradient(135deg, rgba(21, 25, 31, 0.98) 0%, rgba(31, 35, 41, 0.98) 100%);
1856
+ backdrop-filter: blur(16px);
1857
+ border: 1px solid var(--profiler-border-strong);
1858
+ border-radius: 8px;
1859
+ padding: 12px 16px;
1860
+ font-family: var(--profiler-font-mono);
1861
+ font-size: 12px;
1862
+ color: var(--profiler-text);
1863
+ pointer-events: none;
1864
+ z-index: 1000;
1865
+ box-shadow: 0 8px 32px rgba(0, 0, 0, 0.5), 0 0 0 1px rgba(255, 255, 255, 0.03);
1866
+ opacity: 0;
1867
+ transform: translateY(8px);
1868
+ transition: all var(--profiler-transition-base);
1869
+ }
1870
+ .profiler-timeline .timeline-tooltip.visible {
1871
+ opacity: 1;
1872
+ transform: translateY(0);
1873
+ }
1874
+ .profiler-timeline .timeline-tooltip .tooltip-header {
1875
+ font-weight: 600;
1876
+ color: var(--profiler-accent);
1877
+ margin-bottom: 6px;
1878
+ padding-bottom: 6px;
1879
+ border-bottom: 1px solid var(--profiler-border);
1880
+ }
1881
+ .profiler-timeline .timeline-tooltip .tooltip-row {
1882
+ display: flex;
1883
+ justify-content: space-between;
1884
+ gap: 16px;
1885
+ margin: 4px 0;
1886
+ }
1887
+ .profiler-timeline .timeline-tooltip .tooltip-row .label {
1888
+ color: var(--profiler-text-muted);
1889
+ }
1890
+ .profiler-timeline .timeline-tooltip .tooltip-row .value {
1891
+ color: var(--profiler-text);
1892
+ font-weight: 600;
1893
+ }
1894
+
1895
+ @keyframes barSlideIn {
1896
+ from {
1897
+ transform: scaleX(0);
1898
+ opacity: 0;
1899
+ }
1900
+ to {
1901
+ transform: scaleX(1);
1902
+ opacity: 1;
1903
+ }
1904
+ }
1905
+ .profiler-timeline .timeline-bar {
1906
+ animation: barSlideIn 600ms cubic-bezier(0.4, 0, 0.2, 1) backwards;
1907
+ }
1908
+ .profiler-timeline .timeline-bar:nth-child(1) {
1909
+ animation-delay: 30ms;
1910
+ }
1911
+ .profiler-timeline .timeline-bar:nth-child(2) {
1912
+ animation-delay: 60ms;
1913
+ }
1914
+ .profiler-timeline .timeline-bar:nth-child(3) {
1915
+ animation-delay: 90ms;
1916
+ }
1917
+ .profiler-timeline .timeline-bar:nth-child(4) {
1918
+ animation-delay: 120ms;
1919
+ }
1920
+ .profiler-timeline .timeline-bar:nth-child(5) {
1921
+ animation-delay: 150ms;
1922
+ }
1923
+ .profiler-timeline .timeline-bar:nth-child(6) {
1924
+ animation-delay: 180ms;
1925
+ }
1926
+ .profiler-timeline .timeline-bar:nth-child(7) {
1927
+ animation-delay: 210ms;
1928
+ }
1929
+ .profiler-timeline .timeline-bar:nth-child(8) {
1930
+ animation-delay: 240ms;
1931
+ }
1932
+ .profiler-timeline .timeline-bar:nth-child(9) {
1933
+ animation-delay: 270ms;
1934
+ }
1935
+ .profiler-timeline .timeline-bar:nth-child(10) {
1936
+ animation-delay: 300ms;
1937
+ }
1938
+ .profiler-timeline .timeline-bar:nth-child(11) {
1939
+ animation-delay: 330ms;
1940
+ }
1941
+ .profiler-timeline .timeline-bar:nth-child(12) {
1942
+ animation-delay: 360ms;
1943
+ }
1944
+ .profiler-timeline .timeline-bar:nth-child(13) {
1945
+ animation-delay: 390ms;
1946
+ }
1947
+ .profiler-timeline .timeline-bar:nth-child(14) {
1948
+ animation-delay: 420ms;
1949
+ }
1950
+ .profiler-timeline .timeline-bar:nth-child(15) {
1951
+ animation-delay: 450ms;
1952
+ }
1953
+ .profiler-timeline .timeline-bar:nth-child(16) {
1954
+ animation-delay: 480ms;
1955
+ }
1956
+ .profiler-timeline .timeline-bar:nth-child(17) {
1957
+ animation-delay: 510ms;
1958
+ }
1959
+ .profiler-timeline .timeline-bar:nth-child(18) {
1960
+ animation-delay: 540ms;
1961
+ }
1962
+ .profiler-timeline .timeline-bar:nth-child(19) {
1963
+ animation-delay: 570ms;
1964
+ }
1965
+ .profiler-timeline .timeline-bar:nth-child(20) {
1966
+ animation-delay: 600ms;
1967
+ }
1968
+
1969
+ .profiler-flamegraph {
1970
+ animation: fadeIn 500ms cubic-bezier(0.4, 0, 0.2, 1);
1971
+ }
1972
+ .profiler-flamegraph__stats {
1973
+ display: flex;
1974
+ flex-wrap: wrap;
1975
+ gap: 12px;
1976
+ margin-bottom: 16px;
1977
+ }
1978
+ .profiler-flamegraph__stats .stat-item {
1979
+ display: flex;
1980
+ flex-direction: column;
1981
+ gap: 2px;
1982
+ padding: 10px 14px;
1983
+ background: var(--profiler-bg-lighter);
1984
+ border: 1px solid var(--profiler-border);
1985
+ border-radius: var(--profiler-radius-md);
1986
+ min-width: 80px;
1987
+ transition: all var(--profiler-transition-base);
1988
+ }
1989
+ .profiler-flamegraph__stats .stat-item:hover {
1990
+ border-color: var(--profiler-border-strong);
1991
+ transform: translateY(-1px);
1992
+ box-shadow: var(--profiler-shadow-sm);
1993
+ }
1994
+ .profiler-flamegraph__stats .stat-label {
1995
+ font-size: var(--profiler-text-xs);
1996
+ text-transform: uppercase;
1997
+ letter-spacing: 0.06em;
1998
+ color: var(--profiler-text-muted);
1999
+ font-family: var(--profiler-font-sans);
2000
+ display: flex;
2001
+ align-items: center;
2002
+ gap: 6px;
2003
+ }
2004
+ .profiler-flamegraph__stats .stat-value {
2005
+ font-size: var(--profiler-text-lg);
2006
+ font-weight: 700;
2007
+ font-family: var(--profiler-font-mono);
2008
+ color: var(--profiler-accent);
2009
+ line-height: 1.2;
2010
+ }
2011
+ .profiler-flamegraph__stats .stat-value small {
2012
+ font-size: var(--profiler-text-sm);
2013
+ color: var(--profiler-text-muted);
2014
+ font-weight: 500;
2015
+ }
2016
+ .profiler-flamegraph__stats .stat-dot {
2017
+ display: inline-block;
2018
+ width: 8px;
2019
+ height: 8px;
2020
+ border-radius: 50%;
2021
+ flex-shrink: 0;
2022
+ }
2023
+ .profiler-flamegraph__legend {
2024
+ display: flex;
2025
+ gap: 16px;
2026
+ margin-bottom: 12px;
2027
+ flex-wrap: wrap;
2028
+ }
2029
+ .profiler-flamegraph__legend .legend-item {
2030
+ display: flex;
2031
+ align-items: center;
2032
+ gap: 6px;
2033
+ font-size: var(--profiler-text-sm);
2034
+ font-family: var(--profiler-font-sans);
2035
+ color: var(--profiler-text-muted);
2036
+ }
2037
+ .profiler-flamegraph__legend .legend-item .legend-color {
2038
+ width: 12px;
2039
+ height: 12px;
2040
+ border-radius: 3px;
2041
+ flex-shrink: 0;
2042
+ }
2043
+ .profiler-flamegraph__controls {
2044
+ display: flex;
2045
+ align-items: center;
2046
+ gap: 12px;
2047
+ margin-bottom: 8px;
2048
+ }
2049
+ .profiler-flamegraph__reset {
2050
+ padding: 4px 12px;
2051
+ font-size: var(--profiler-text-sm);
2052
+ font-family: var(--profiler-font-sans);
2053
+ font-weight: 500;
2054
+ background: var(--profiler-accent-bg);
2055
+ color: var(--profiler-accent);
2056
+ border: 1px solid var(--profiler-border-accent);
2057
+ border-radius: var(--profiler-radius-sm);
2058
+ cursor: pointer;
2059
+ transition: all var(--profiler-transition-base);
2060
+ }
2061
+ .profiler-flamegraph__reset:hover {
2062
+ background: var(--profiler-accent);
2063
+ color: var(--profiler-text-on-accent);
2064
+ }
2065
+ .profiler-flamegraph__hint {
2066
+ font-size: var(--profiler-text-xs);
2067
+ color: var(--profiler-text-subtle);
2068
+ font-family: var(--profiler-font-sans);
2069
+ }
2070
+ .profiler-flamegraph__canvas-container {
2071
+ position: relative;
2072
+ border: 1px solid var(--profiler-border);
2073
+ border-radius: var(--profiler-radius-lg);
2074
+ overflow: visible;
2075
+ background: var(--profiler-bg-light);
2076
+ }
2077
+ .profiler-flamegraph__canvas {
2078
+ display: block;
2079
+ width: 100%;
2080
+ cursor: default;
2081
+ }
2082
+ .profiler-flamegraph__breadcrumbs {
2083
+ display: none;
2084
+ align-items: center;
2085
+ gap: 4px;
2086
+ padding: 8px 12px;
2087
+ background: var(--profiler-bg-lighter);
2088
+ border-bottom: 1px solid var(--profiler-border);
2089
+ font-size: var(--profiler-text-sm);
2090
+ font-family: var(--profiler-font-mono);
2091
+ flex-wrap: wrap;
2092
+ overflow: hidden;
2093
+ }
2094
+ .profiler-flamegraph__breadcrumbs .breadcrumb-item {
2095
+ background: none;
2096
+ border: none;
2097
+ padding: 2px 6px;
2098
+ font-size: var(--profiler-text-sm);
2099
+ font-family: var(--profiler-font-mono);
2100
+ color: var(--profiler-text-secondary);
2101
+ cursor: pointer;
2102
+ border-radius: var(--profiler-radius-sm);
2103
+ transition: all var(--profiler-transition-fast);
2104
+ white-space: nowrap;
2105
+ }
2106
+ .profiler-flamegraph__breadcrumbs .breadcrumb-item:hover {
2107
+ background: var(--profiler-accent-bg);
2108
+ color: var(--profiler-accent);
2109
+ }
2110
+ .profiler-flamegraph__breadcrumbs .breadcrumb-item:last-child {
2111
+ color: var(--profiler-accent);
2112
+ font-weight: 600;
2113
+ }
2114
+ .profiler-flamegraph__breadcrumbs .breadcrumb-separator {
2115
+ color: var(--profiler-text-subtle);
2116
+ font-size: var(--profiler-text-base);
2117
+ user-select: none;
2118
+ }
2119
+ .profiler-flamegraph__tooltip {
2120
+ position: fixed;
2121
+ background: var(--profiler-bg-overlay);
2122
+ backdrop-filter: blur(16px);
2123
+ border: 1px solid var(--profiler-border-strong);
2124
+ border-radius: var(--profiler-radius-md);
2125
+ padding: 10px 14px;
2126
+ font-family: var(--profiler-font-mono);
2127
+ font-size: var(--profiler-text-sm);
2128
+ color: var(--profiler-text);
2129
+ pointer-events: none;
2130
+ z-index: 1000;
2131
+ box-shadow: var(--profiler-shadow-lg);
2132
+ opacity: 0;
2133
+ transform: translateY(6px);
2134
+ transition: opacity var(--profiler-transition-fast), transform var(--profiler-transition-fast);
2135
+ max-width: 400px;
2136
+ word-break: break-all;
2137
+ }
2138
+ .profiler-flamegraph__tooltip.visible {
2139
+ opacity: 1;
2140
+ transform: translateY(0);
2141
+ }
2142
+ .profiler-flamegraph__tooltip .tooltip-header {
2143
+ font-weight: 600;
2144
+ color: var(--profiler-accent);
2145
+ margin-bottom: 6px;
2146
+ padding-bottom: 6px;
2147
+ border-bottom: 1px solid var(--profiler-border);
2148
+ white-space: nowrap;
2149
+ overflow: hidden;
2150
+ text-overflow: ellipsis;
2151
+ max-width: 350px;
2152
+ }
2153
+ .profiler-flamegraph__tooltip .tooltip-row {
2154
+ display: flex;
2155
+ justify-content: space-between;
2156
+ gap: 16px;
2157
+ margin: 3px 0;
2158
+ }
2159
+ .profiler-flamegraph__tooltip .tooltip-row .label {
2160
+ color: var(--profiler-text-muted);
2161
+ }
2162
+ .profiler-flamegraph__tooltip .tooltip-row .value {
2163
+ color: var(--profiler-text);
2164
+ font-weight: 600;
2165
+ }
2166
+ .profiler-flamegraph__tooltip .tooltip-badge {
2167
+ display: inline-block;
2168
+ padding: 1px 8px;
2169
+ border-radius: var(--profiler-radius-full);
2170
+ font-size: var(--profiler-text-xs);
2171
+ font-weight: 600;
2172
+ color: #fff;
2173
+ }
2174
+ .profiler-flamegraph__tooltip .tooltip-payload {
2175
+ margin-top: 6px;
2176
+ padding-top: 6px;
2177
+ border-top: 1px solid var(--profiler-border);
2178
+ font-size: var(--profiler-text-xs);
2179
+ color: var(--profiler-text-secondary);
2180
+ white-space: pre-wrap;
2181
+ max-height: 80px;
2182
+ overflow: hidden;
2183
+ }
2184
+
2185
+ pre[data-language=sql],
2186
+ .sql-code {
2187
+ background: var(--profiler-bg);
2188
+ padding: 15px;
2189
+ border-radius: 4px;
2190
+ overflow-x: auto;
2191
+ font-family: "Monaco", "Menlo", "Ubuntu Mono", monospace;
2192
+ font-size: 13px;
2193
+ line-height: 1.5;
2194
+ }
2195
+ pre[data-language=sql] .sql-keyword,
2196
+ .sql-code .sql-keyword {
2197
+ color: #c586c0;
2198
+ font-weight: 600;
2199
+ }
2200
+ pre[data-language=sql] .sql-string,
2201
+ .sql-code .sql-string {
2202
+ color: #ce9178;
2203
+ }
2204
+ pre[data-language=sql] .sql-number,
2205
+ .sql-code .sql-number {
2206
+ color: #b5cea8;
2207
+ }
2208
+ pre[data-language=sql] .sql-comment,
2209
+ .sql-code .sql-comment {
2210
+ color: var(--profiler-text-muted);
2211
+ font-style: italic;
2212
+ }
2213
+ pre[data-language=sql] .sql-function,
2214
+ .sql-code .sql-function {
2215
+ color: #dcdcaa;
2216
+ }
2217
+ pre[data-language=sql] .sql-operator,
2218
+ .sql-code .sql-operator {
2219
+ color: var(--profiler-info);
2220
+ }
2221
+
2222
+ .backtrace {
2223
+ font-family: "Monaco", "Menlo", "Ubuntu Mono", monospace;
2224
+ font-size: 11px;
2225
+ color: var(--profiler-text-muted);
2226
+ line-height: 1.6;
2227
+ }
2228
+ .backtrace .file-path {
2229
+ color: var(--profiler-info);
2230
+ }
2231
+ .backtrace .file-path:hover {
2232
+ text-decoration: underline;
2233
+ }
2234
+ .backtrace .line-number {
2235
+ color: var(--profiler-warning);
2236
+ }
2237
+ .backtrace .method-name {
2238
+ color: #dcdcaa;
2239
+ }
2240
+
2241
+ .profile-header {
2242
+ margin-bottom: var(--profiler-space-6);
2243
+ padding-bottom: var(--profiler-space-4);
2244
+ border-bottom: 1px solid var(--profiler-border);
2245
+ }
2246
+ .profile-header h2 {
2247
+ font-size: var(--profiler-text-xl);
2248
+ margin-bottom: var(--profiler-space-3);
2249
+ color: var(--profiler-text);
2250
+ font-weight: 600;
2251
+ }
2252
+
2253
+ .stats-grid {
2254
+ display: grid;
2255
+ grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
2256
+ gap: var(--profiler-space-4);
2257
+ margin-bottom: var(--profiler-space-6);
2258
+ }
2259
+
2260
+ .stat {
2261
+ background: var(--profiler-bg-lighter);
2262
+ padding: var(--profiler-space-3);
2263
+ border-radius: var(--profiler-radius-md);
2264
+ border: 1px solid var(--profiler-border);
2265
+ transition: all var(--profiler-transition-base);
2266
+ }
2267
+ .stat:hover {
2268
+ background: var(--profiler-bg-elevated);
2269
+ border-color: var(--profiler-border-strong);
2270
+ transform: translateY(-2px);
2271
+ box-shadow: var(--profiler-shadow-sm);
2272
+ }
2273
+
2274
+ .stat-label {
2275
+ font-size: var(--profiler-text-xs);
2276
+ color: var(--profiler-text-muted);
2277
+ margin-bottom: var(--profiler-space-1);
2278
+ text-transform: uppercase;
2279
+ letter-spacing: 0.08em;
2280
+ }
2281
+
2282
+ .stat-value {
2283
+ font-size: var(--profiler-text-xl);
2284
+ font-weight: 600;
2285
+ color: var(--profiler-accent);
2286
+ font-family: var(--profiler-font-mono);
2287
+ }
2288
+
2289
+ .tabs {
2290
+ display: flex;
2291
+ gap: var(--profiler-space-1);
2292
+ border-bottom: 1px solid var(--profiler-border);
2293
+ margin-bottom: var(--profiler-space-6);
2294
+ }
2295
+
2296
+ .tab {
2297
+ padding: var(--profiler-space-3) var(--profiler-space-4);
2298
+ background: transparent;
2299
+ border: none;
2300
+ color: var(--profiler-text-muted);
2301
+ cursor: pointer;
2302
+ font-size: var(--profiler-text-base);
2303
+ border-bottom: 2px solid transparent;
2304
+ display: flex;
2305
+ align-items: center;
2306
+ gap: var(--profiler-space-2);
2307
+ transition: all var(--profiler-transition-fast);
2308
+ }
2309
+ .tab .tab-icon {
2310
+ font-size: var(--profiler-text-lg);
2311
+ line-height: 1;
2312
+ }
2313
+ .tab:hover {
2314
+ color: var(--profiler-text);
2315
+ background: rgba(0, 0, 0, 0.1);
2316
+ }
2317
+ .tab.active {
2318
+ color: var(--profiler-accent);
2319
+ border-bottom-color: var(--profiler-accent);
2320
+ }
2321
+
2322
+ .tab-content {
2323
+ display: none;
2324
+ }
2325
+ .tab-content.active {
2326
+ display: block;
2327
+ }
2328
+
2329
+ .query-item {
2330
+ background: var(--profiler-bg-lighter);
2331
+ padding: var(--profiler-space-3);
2332
+ margin-bottom: var(--profiler-space-3);
2333
+ border-radius: var(--profiler-radius-md);
2334
+ border-left: 3px solid var(--profiler-info);
2335
+ transition: all var(--profiler-transition-base);
2336
+ }
2337
+ .query-item:hover {
2338
+ background: var(--profiler-bg-elevated);
2339
+ transform: translateX(4px);
2340
+ box-shadow: var(--profiler-shadow-sm);
2341
+ }
2342
+ .query-item.slow {
2343
+ border-left-color: var(--profiler-error);
2344
+ background: var(--profiler-error-bg);
2345
+ }
2346
+ .query-item.slow:hover {
2347
+ box-shadow: 0 0 16px var(--profiler-error-glow);
2348
+ }
2349
+
2350
+ .query-sql {
2351
+ font-family: var(--profiler-font-mono);
2352
+ font-size: var(--profiler-text-sm);
2353
+ color: var(--profiler-info);
2354
+ margin-bottom: var(--profiler-space-2);
2355
+ white-space: pre-wrap;
2356
+ word-break: break-all;
2357
+ line-height: 1.6;
2358
+ }
2359
+
2360
+ .query-meta {
2361
+ display: flex;
2362
+ gap: var(--profiler-space-3);
2363
+ font-size: var(--profiler-text-xs);
2364
+ color: var(--profiler-text-muted);
2365
+ }
2366
+
2367
+ .badge {
2368
+ display: inline-flex;
2369
+ padding: var(--profiler-space-1) var(--profiler-space-2);
2370
+ border-radius: var(--profiler-radius-sm);
2371
+ font-size: var(--profiler-text-xs);
2372
+ font-weight: 600;
2373
+ background: var(--profiler-info);
2374
+ color: var(--profiler-text-on-accent);
2375
+ font-family: var(--profiler-font-mono);
2376
+ }
2377
+
2378
+ .badge-slow {
2379
+ background: var(--profiler-error);
2380
+ }
2381
+
2382
+ .badge-cached {
2383
+ background: var(--profiler-success);
2384
+ }
2385
+
2386
+ .dump-item {
2387
+ background: var(--profiler-bg-lighter);
2388
+ padding: var(--profiler-space-4);
2389
+ margin-bottom: var(--profiler-space-4);
2390
+ border-radius: var(--profiler-radius-md);
2391
+ border-left: 3px solid var(--profiler-warning);
2392
+ }
2393
+
2394
+ .dump-header {
2395
+ display: flex;
2396
+ justify-content: space-between;
2397
+ align-items: center;
2398
+ margin-bottom: var(--profiler-space-3);
2399
+ font-size: var(--profiler-text-sm);
2400
+ }
2401
+
2402
+ .dump-label {
2403
+ color: var(--profiler-accent);
2404
+ font-weight: 600;
2405
+ }
2406
+
2407
+ .dump-location {
2408
+ color: var(--profiler-info);
2409
+ font-size: var(--profiler-text-xs);
2410
+ font-family: var(--profiler-font-mono);
2411
+ }
2412
+
2413
+ .dump-value {
2414
+ font-family: var(--profiler-font-mono);
2415
+ font-size: var(--profiler-text-sm);
2416
+ color: var(--profiler-warning);
2417
+ white-space: pre-wrap;
2418
+ background: rgba(0, 0, 0, 0.3);
2419
+ padding: var(--profiler-space-3);
2420
+ border-radius: var(--profiler-radius-sm);
2421
+ max-height: 400px;
2422
+ overflow-y: auto;
2423
+ line-height: 1.5;
2424
+ }
2425
+
2426
+ .cache-stats {
2427
+ display: grid;
2428
+ grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
2429
+ gap: var(--profiler-space-3);
2430
+ margin-bottom: var(--profiler-space-6);
2431
+ }
2432
+
2433
+ .cache-stat {
2434
+ background: var(--profiler-bg-lighter);
2435
+ padding: var(--profiler-space-3);
2436
+ border-radius: var(--profiler-radius-md);
2437
+ text-align: center;
2438
+ border: 1px solid var(--profiler-border);
2439
+ transition: all var(--profiler-transition-base);
2440
+ }
2441
+ .cache-stat:hover {
2442
+ background: var(--profiler-bg-elevated);
2443
+ border-color: var(--profiler-border-strong);
2444
+ transform: translateY(-2px);
2445
+ box-shadow: var(--profiler-shadow-sm);
2446
+ }
2447
+
2448
+ .cache-stat-label {
2449
+ font-size: var(--profiler-text-xs);
2450
+ color: var(--profiler-text-muted);
2451
+ margin-bottom: var(--profiler-space-1);
2452
+ text-transform: uppercase;
2453
+ letter-spacing: 0.08em;
2454
+ }
2455
+
2456
+ .cache-stat-value {
2457
+ font-size: var(--profiler-text-xl);
2458
+ font-weight: 600;
2459
+ color: var(--profiler-accent);
2460
+ font-family: var(--profiler-font-mono);
2461
+ }
2462
+
2463
+ .empty-state {
2464
+ display: flex;
2465
+ align-items: center;
2466
+ justify-content: center;
2467
+ min-height: 200px;
2468
+ flex-direction: column;
2469
+ gap: var(--profiler-space-2);
2470
+ color: var(--profiler-text-muted);
2471
+ padding: var(--profiler-space-12) var(--profiler-space-6);
2472
+ text-align: center;
2473
+ }
2474
+
2475
+ .loading {
2476
+ text-align: center;
2477
+ padding: var(--profiler-space-12) var(--profiler-space-6);
2478
+ color: var(--profiler-text-muted);
2479
+ font-size: var(--profiler-text-base);
2480
+ }
2481
+
2482
+ .error {
2483
+ background: var(--profiler-error-bg);
2484
+ color: var(--profiler-error);
2485
+ padding: var(--profiler-space-3);
2486
+ border-radius: var(--profiler-radius-md);
2487
+ margin-bottom: var(--profiler-space-3);
2488
+ border-left: 3px solid var(--profiler-error);
2489
+ font-size: var(--profiler-text-sm);
2490
+ }
2491
+
2492
+ .generic-tab pre {
2493
+ color: var(--profiler-info);
2494
+ font-family: var(--profiler-font-mono);
2495
+ font-size: var(--profiler-text-sm);
2496
+ line-height: 1.6;
2497
+ }
2498
+
2499
+ .ajax-breakdown {
2500
+ margin: var(--profiler-space-6) 0;
2501
+ padding: var(--profiler-space-4);
2502
+ background: var(--profiler-bg-light);
2503
+ border: 1px solid var(--profiler-border);
2504
+ border-radius: var(--profiler-radius-md);
2505
+ }
2506
+ .ajax-breakdown h3 {
2507
+ margin: 0 0 var(--profiler-space-3) 0;
2508
+ font-size: var(--profiler-text-base);
2509
+ color: var(--profiler-text);
2510
+ font-weight: 600;
2511
+ }
2512
+
2513
+ .ajax-breakdown-items {
2514
+ display: flex;
2515
+ flex-wrap: wrap;
2516
+ gap: var(--profiler-space-3);
2517
+ }
2518
+
2519
+ .ajax-breakdown-item {
2520
+ display: flex;
2521
+ align-items: center;
2522
+ gap: var(--profiler-space-2);
2523
+ padding: var(--profiler-space-1) var(--profiler-space-3);
2524
+ background: var(--profiler-bg-elevated);
2525
+ border: 1px solid var(--profiler-border);
2526
+ border-radius: var(--profiler-radius-md);
2527
+ font-size: var(--profiler-text-base);
2528
+ color: var(--profiler-text);
2529
+ font-family: var(--profiler-font-mono);
2530
+ }
2531
+
2532
+ .ajax-requests-list {
2533
+ margin-top: var(--profiler-space-6);
2534
+ }
2535
+
2536
+ .ajax-request-item {
2537
+ background: var(--profiler-bg-light);
2538
+ border: 1px solid var(--profiler-border);
2539
+ border-radius: var(--profiler-radius-md);
2540
+ padding: var(--profiler-space-3) var(--profiler-space-4);
2541
+ margin-bottom: var(--profiler-space-3);
2542
+ transition: all var(--profiler-transition-base);
2543
+ }
2544
+ .ajax-request-item:hover {
2545
+ background: var(--profiler-accent-bg);
2546
+ border-color: var(--profiler-border-accent);
2547
+ transform: translateX(3px);
2548
+ box-shadow: var(--profiler-shadow-sm);
2549
+ }
2550
+
2551
+ .ajax-request-header {
2552
+ display: flex;
2553
+ justify-content: space-between;
2554
+ align-items: center;
2555
+ margin-bottom: var(--profiler-space-2);
2556
+ }
2557
+
2558
+ .ajax-request-method {
2559
+ display: flex;
2560
+ align-items: center;
2561
+ gap: var(--profiler-space-3);
2562
+ flex: 1;
2563
+ min-width: 0;
2564
+ }
2565
+
2566
+ .ajax-request-path {
2567
+ color: var(--profiler-text);
2568
+ font-size: var(--profiler-text-sm);
2569
+ font-family: var(--profiler-font-mono);
2570
+ overflow: hidden;
2571
+ text-overflow: ellipsis;
2572
+ white-space: nowrap;
2573
+ }
2574
+
2575
+ .ajax-request-stats {
2576
+ display: flex;
2577
+ align-items: center;
2578
+ gap: var(--profiler-space-3);
2579
+ }
2580
+
2581
+ .ajax-request-duration {
2582
+ color: var(--profiler-accent);
2583
+ font-weight: 700;
2584
+ font-size: var(--profiler-text-sm);
2585
+ font-family: var(--profiler-font-mono);
2586
+ }
2587
+
2588
+ .ajax-request-meta {
2589
+ display: flex;
2590
+ justify-content: space-between;
2591
+ align-items: center;
2592
+ color: var(--profiler-text-muted);
2593
+ font-size: var(--profiler-text-sm);
2594
+ }
2595
+
2596
+ .ajax-request-time {
2597
+ font-family: var(--profiler-font-mono);
2598
+ font-size: var(--profiler-text-xs);
2599
+ }
2600
+
2601
+ .ajax-request-link {
2602
+ color: var(--profiler-accent);
2603
+ text-decoration: none;
2604
+ font-weight: 500;
2605
+ font-size: var(--profiler-text-sm);
2606
+ font-family: var(--profiler-font-mono);
2607
+ transition: color var(--profiler-transition-fast);
2608
+ }
2609
+ .ajax-request-link:hover {
2610
+ color: var(--profiler-accent-hover);
2611
+ }
2612
+
2613
+ .method-badge {
2614
+ display: inline-flex;
2615
+ align-items: center;
2616
+ padding: 2px 7px;
2617
+ border-radius: var(--profiler-radius-sm);
2618
+ font-size: var(--profiler-text-xs);
2619
+ font-weight: 700;
2620
+ text-transform: uppercase;
2621
+ font-family: var(--profiler-font-mono);
2622
+ letter-spacing: 0.05em;
2623
+ color: #fff;
2624
+ }
2625
+ .method-badge.method-get {
2626
+ background: var(--profiler-info);
2627
+ }
2628
+ .method-badge.method-post {
2629
+ background: var(--profiler-success);
2630
+ }
2631
+ .method-badge.method-put {
2632
+ background: var(--profiler-warning);
2633
+ }
2634
+ .method-badge.method-patch {
2635
+ background: var(--profiler-warning);
2636
+ }
2637
+ .method-badge.method-delete {
2638
+ background: var(--profiler-error);
2639
+ }
2640
+ .method-badge.method-head, .method-badge.method-options {
2641
+ background: var(--profiler-text-muted);
2642
+ }
2643
+
2644
+ .status-badge {
2645
+ display: inline-flex;
2646
+ align-items: center;
2647
+ padding: 2px 7px;
2648
+ border-radius: var(--profiler-radius-sm);
2649
+ font-size: var(--profiler-text-xs);
2650
+ font-weight: 700;
2651
+ font-family: var(--profiler-font-mono);
2652
+ color: #fff;
2653
+ }
2654
+ .status-badge.status-2xx {
2655
+ background: var(--profiler-success);
2656
+ }
2657
+ .status-badge.status-3xx {
2658
+ background: var(--profiler-info);
2659
+ }
2660
+ .status-badge.status-4xx {
2661
+ background: var(--profiler-warning);
2662
+ }
2663
+ .status-badge.status-5xx {
2664
+ background: var(--profiler-error);
2665
+ }
2666
+ .status-badge.status-other {
2667
+ background: var(--profiler-text-muted);
2668
+ }