serialbench 0.1.1 → 0.1.3

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 (100) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/benchmark.yml +273 -220
  3. data/.github/workflows/rake.yml +26 -0
  4. data/.github/workflows/windows-debug.yml +171 -0
  5. data/.gitignore +32 -0
  6. data/.rubocop.yml +1 -0
  7. data/.rubocop_todo.yml +274 -0
  8. data/Gemfile +14 -1
  9. data/README.adoc +292 -1118
  10. data/Rakefile +0 -55
  11. data/config/benchmarks/full.yml +29 -0
  12. data/config/benchmarks/short.yml +26 -0
  13. data/config/environments/asdf-ruby-3.2.yml +8 -0
  14. data/config/environments/asdf-ruby-3.3.yml +8 -0
  15. data/config/environments/docker-ruby-3.0.yml +9 -0
  16. data/config/environments/docker-ruby-3.1.yml +9 -0
  17. data/config/environments/docker-ruby-3.2.yml +9 -0
  18. data/config/environments/docker-ruby-3.3.yml +9 -0
  19. data/config/environments/docker-ruby-3.4.yml +9 -0
  20. data/data/schemas/result.yml +29 -0
  21. data/docker/Dockerfile.alpine +33 -0
  22. data/docker/{Dockerfile.benchmark → Dockerfile.ubuntu} +4 -3
  23. data/docker/README.md +2 -2
  24. data/docs/PLATFORM_VALIDATION_FIX.md +79 -0
  25. data/docs/SYCK_YAML_FIX.md +91 -0
  26. data/docs/WEBSITE_COMPLETION_PLAN.md +440 -0
  27. data/docs/WINDOWS_LIBXML_FIX.md +136 -0
  28. data/docs/WINDOWS_SETUP.md +122 -0
  29. data/exe/serialbench +1 -1
  30. data/lib/serialbench/benchmark_runner.rb +261 -423
  31. data/lib/serialbench/cli/base_cli.rb +51 -0
  32. data/lib/serialbench/cli/benchmark_cli.rb +453 -0
  33. data/lib/serialbench/cli/environment_cli.rb +181 -0
  34. data/lib/serialbench/cli/resultset_cli.rb +261 -0
  35. data/lib/serialbench/cli/ruby_build_cli.rb +225 -0
  36. data/lib/serialbench/cli/validate_cli.rb +88 -0
  37. data/lib/serialbench/cli.rb +61 -600
  38. data/lib/serialbench/config_manager.rb +129 -0
  39. data/lib/serialbench/models/benchmark_config.rb +75 -0
  40. data/lib/serialbench/models/benchmark_result.rb +81 -0
  41. data/lib/serialbench/models/environment_config.rb +72 -0
  42. data/lib/serialbench/models/platform.rb +111 -0
  43. data/lib/serialbench/models/result.rb +80 -0
  44. data/lib/serialbench/models/result_set.rb +79 -0
  45. data/lib/serialbench/models/result_store.rb +108 -0
  46. data/lib/serialbench/models.rb +54 -0
  47. data/lib/serialbench/ruby_build_manager.rb +149 -0
  48. data/lib/serialbench/runners/asdf_runner.rb +296 -0
  49. data/lib/serialbench/runners/base.rb +32 -0
  50. data/lib/serialbench/runners/docker_runner.rb +140 -0
  51. data/lib/serialbench/runners/local_runner.rb +71 -0
  52. data/lib/serialbench/serializers/base_serializer.rb +9 -17
  53. data/lib/serialbench/serializers/json/base_json_serializer.rb +4 -4
  54. data/lib/serialbench/serializers/json/json_serializer.rb +0 -2
  55. data/lib/serialbench/serializers/json/oj_serializer.rb +0 -2
  56. data/lib/serialbench/serializers/json/rapidjson_serializer.rb +1 -1
  57. data/lib/serialbench/serializers/json/yajl_serializer.rb +0 -2
  58. data/lib/serialbench/serializers/toml/base_toml_serializer.rb +5 -5
  59. data/lib/serialbench/serializers/toml/toml_rb_serializer.rb +1 -3
  60. data/lib/serialbench/serializers/toml/tomlib_serializer.rb +1 -3
  61. data/lib/serialbench/serializers/toml/tomlrb_serializer.rb +56 -0
  62. data/lib/serialbench/serializers/xml/base_xml_serializer.rb +4 -9
  63. data/lib/serialbench/serializers/xml/libxml_serializer.rb +4 -10
  64. data/lib/serialbench/serializers/xml/nokogiri_serializer.rb +2 -4
  65. data/lib/serialbench/serializers/xml/oga_serializer.rb +4 -10
  66. data/lib/serialbench/serializers/xml/ox_serializer.rb +2 -4
  67. data/lib/serialbench/serializers/xml/rexml_serializer.rb +3 -5
  68. data/lib/serialbench/serializers/yaml/base_yaml_serializer.rb +5 -1
  69. data/lib/serialbench/serializers/yaml/psych_serializer.rb +1 -1
  70. data/lib/serialbench/serializers/yaml/syck_serializer.rb +60 -23
  71. data/lib/serialbench/serializers.rb +23 -6
  72. data/lib/serialbench/site_generator.rb +283 -0
  73. data/lib/serialbench/templates/assets/css/benchmark_report.css +535 -0
  74. data/lib/serialbench/templates/assets/css/format_based.css +474 -0
  75. data/lib/serialbench/templates/assets/css/themes.css +589 -0
  76. data/lib/serialbench/templates/assets/js/chart_helpers.js +411 -0
  77. data/lib/serialbench/templates/assets/js/dashboard.js +795 -0
  78. data/lib/serialbench/templates/assets/js/navigation.js +142 -0
  79. data/lib/serialbench/templates/base.liquid +49 -0
  80. data/lib/serialbench/templates/format_based.liquid +507 -0
  81. data/lib/serialbench/templates/partials/chart_section.liquid +4 -0
  82. data/lib/serialbench/version.rb +1 -1
  83. data/lib/serialbench/yaml_validator.rb +36 -0
  84. data/lib/serialbench.rb +2 -31
  85. data/serialbench.gemspec +15 -3
  86. metadata +106 -25
  87. data/.github/workflows/ci.yml +0 -74
  88. data/.github/workflows/docker.yml +0 -246
  89. data/config/ci.yml +0 -22
  90. data/config/full.yml +0 -30
  91. data/docker/run-benchmarks.sh +0 -356
  92. data/lib/serialbench/chart_generator.rb +0 -821
  93. data/lib/serialbench/result_formatter.rb +0 -182
  94. data/lib/serialbench/result_merger.rb +0 -1201
  95. data/lib/serialbench/serializers/xml/base_parser.rb +0 -69
  96. data/lib/serialbench/serializers/xml/libxml_parser.rb +0 -98
  97. data/lib/serialbench/serializers/xml/nokogiri_parser.rb +0 -111
  98. data/lib/serialbench/serializers/xml/oga_parser.rb +0 -85
  99. data/lib/serialbench/serializers/xml/ox_parser.rb +0 -64
  100. data/lib/serialbench/serializers/xml/rexml_parser.rb +0 -129
@@ -0,0 +1,589 @@
1
+ /* Modern Dark Marine/Orange Theme with Light/Dark Mode Support */
2
+
3
+ /* CSS Custom Properties for Theme System */
4
+ :root {
5
+ /* Dark Marine Theme (Default) */
6
+ --bg-primary: #0F172A;
7
+ --bg-secondary: #1E293B;
8
+ --bg-tertiary: #334155;
9
+ --bg-card: #1E293B;
10
+ --bg-hover: #334155;
11
+
12
+ /* Orange Accent Colors */
13
+ --accent-primary: #F97316;
14
+ --accent-secondary: #EA580C;
15
+ --accent-tertiary: #FB923C;
16
+ --accent-light: #FED7AA;
17
+
18
+ /* Text Colors */
19
+ --text-primary: #F8FAFC;
20
+ --text-secondary: #CBD5E1;
21
+ --text-muted: #64748B;
22
+ --text-inverse: #0F172A;
23
+
24
+ /* Border Colors */
25
+ --border-primary: #475569;
26
+ --border-secondary: #334155;
27
+ --border-accent: #F97316;
28
+
29
+ /* Status Colors */
30
+ --success: #10B981;
31
+ --warning: #F59E0B;
32
+ --error: #EF4444;
33
+ --info: #3B82F6;
34
+
35
+ /* Shadows */
36
+ --shadow-sm: 0 1px 2px 0 rgba(0, 0, 0, 0.3);
37
+ --shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.4);
38
+ --shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.5);
39
+ --shadow-xl: 0 20px 25px -5px rgba(0, 0, 0, 0.6);
40
+
41
+ /* Gradients */
42
+ --gradient-primary: linear-gradient(135deg, var(--accent-primary), var(--accent-secondary));
43
+ --gradient-secondary: linear-gradient(135deg, var(--bg-secondary), var(--bg-tertiary));
44
+ --gradient-accent: linear-gradient(135deg, var(--accent-tertiary), var(--accent-primary));
45
+
46
+ /* Spacing */
47
+ --space-xs: 0.25rem;
48
+ --space-sm: 0.5rem;
49
+ --space-md: 1rem;
50
+ --space-lg: 1.5rem;
51
+ --space-xl: 2rem;
52
+ --space-2xl: 3rem;
53
+
54
+ /* Border Radius */
55
+ --radius-sm: 0.375rem;
56
+ --radius-md: 0.5rem;
57
+ --radius-lg: 0.75rem;
58
+ --radius-xl: 1rem;
59
+ --radius-full: 9999px;
60
+
61
+ /* Typography */
62
+ --font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
63
+ --font-mono: 'JetBrains Mono', 'Fira Code', Consolas, monospace;
64
+
65
+ /* Transitions */
66
+ --transition-fast: 0.15s ease-in-out;
67
+ --transition-normal: 0.3s ease-in-out;
68
+ --transition-slow: 0.5s ease-in-out;
69
+ }
70
+
71
+ /* Light Theme Override */
72
+ [data-theme="light"] {
73
+ --bg-primary: #FFFFFF;
74
+ --bg-secondary: #F8FAFC;
75
+ --bg-tertiary: #E2E8F0;
76
+ --bg-card: #FFFFFF;
77
+ --bg-hover: #F1F5F9;
78
+
79
+ --text-primary: #0F172A;
80
+ --text-secondary: #334155;
81
+ --text-muted: #64748B;
82
+ --text-inverse: #FFFFFF;
83
+
84
+ --border-primary: #E2E8F0;
85
+ --border-secondary: #CBD5E1;
86
+
87
+ --shadow-sm: 0 1px 2px 0 rgba(0, 0, 0, 0.05);
88
+ --shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.1);
89
+ --shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.1);
90
+ --shadow-xl: 0 20px 25px -5px rgba(0, 0, 0, 0.1);
91
+ }
92
+
93
+ /* Base Styles */
94
+ * {
95
+ box-sizing: border-box;
96
+ }
97
+
98
+ html {
99
+ font-family: var(--font-family);
100
+ line-height: 1.6;
101
+ -webkit-font-smoothing: antialiased;
102
+ -moz-osx-font-smoothing: grayscale;
103
+ }
104
+
105
+ body {
106
+ margin: 0;
107
+ padding: 0;
108
+ background: var(--bg-primary);
109
+ color: var(--text-primary);
110
+ transition: background-color var(--transition-normal), color var(--transition-normal);
111
+ min-height: 100vh;
112
+ }
113
+
114
+ /* Navigation Bar */
115
+ .navbar {
116
+ background: var(--bg-secondary);
117
+ border-bottom: 1px solid var(--border-primary);
118
+ box-shadow: var(--shadow-md);
119
+ position: sticky;
120
+ top: 0;
121
+ z-index: 1000;
122
+ backdrop-filter: blur(10px);
123
+ }
124
+
125
+ .navbar-container {
126
+ max-width: 1400px;
127
+ margin: 0 auto;
128
+ padding: 0 var(--space-lg);
129
+ }
130
+
131
+ .navbar-header {
132
+ display: flex;
133
+ justify-content: space-between;
134
+ align-items: center;
135
+ padding: var(--space-md) 0;
136
+ }
137
+
138
+ .navbar-brand {
139
+ display: flex;
140
+ align-items: center;
141
+ gap: var(--space-sm);
142
+ font-size: 1.5rem;
143
+ font-weight: 700;
144
+ color: var(--text-primary);
145
+ text-decoration: none;
146
+ }
147
+
148
+ .navbar-brand-icon {
149
+ width: 32px;
150
+ height: 32px;
151
+ background: var(--gradient-primary);
152
+ border-radius: var(--radius-md);
153
+ display: flex;
154
+ align-items: center;
155
+ justify-content: center;
156
+ color: white;
157
+ }
158
+
159
+ .navbar-controls {
160
+ display: flex;
161
+ align-items: center;
162
+ gap: var(--space-md);
163
+ }
164
+
165
+ /* Theme Toggle */
166
+ .theme-toggle {
167
+ background: var(--bg-tertiary);
168
+ border: 1px solid var(--border-primary);
169
+ border-radius: var(--radius-full);
170
+ padding: var(--space-sm);
171
+ cursor: pointer;
172
+ transition: all var(--transition-fast);
173
+ display: flex;
174
+ align-items: center;
175
+ justify-content: center;
176
+ width: 40px;
177
+ height: 40px;
178
+ }
179
+
180
+ .theme-toggle:hover {
181
+ background: var(--bg-hover);
182
+ transform: scale(1.05);
183
+ }
184
+
185
+ .theme-toggle svg {
186
+ width: 20px;
187
+ height: 20px;
188
+ color: var(--text-secondary);
189
+ transition: color var(--transition-fast);
190
+ }
191
+
192
+ /* Filter Bar */
193
+ .filter-bar {
194
+ /* background: var(--bg-tertiary); */
195
+ border-bottom: 1px solid var(--border-primary);
196
+ padding: var(--space-md) 0;
197
+ }
198
+
199
+ .filter-container {
200
+ display: flex;
201
+ align-items: center;
202
+ gap: var(--space-lg);
203
+ flex-wrap: wrap;
204
+ }
205
+
206
+ .filter-group {
207
+ display: flex;
208
+ align-items: center;
209
+ gap: var(--space-sm);
210
+ }
211
+
212
+ .filter-label {
213
+ font-size: 0.875rem;
214
+ font-weight: 600;
215
+ color: var(--text-secondary);
216
+ white-space: nowrap;
217
+ }
218
+
219
+ /* Custom Select Styling */
220
+ .custom-select {
221
+ position: relative;
222
+ min-width: 150px;
223
+ }
224
+
225
+ .custom-select select {
226
+ width: 100%;
227
+ padding: var(--space-sm) var(--space-md);
228
+ background: var(--bg-card);
229
+ border: 1px solid var(--border-primary);
230
+ border-radius: var(--radius-md);
231
+ color: var(--text-primary);
232
+ font-size: 0.875rem;
233
+ cursor: pointer;
234
+ transition: all var(--transition-fast);
235
+ appearance: none;
236
+ 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 8 4 4 4-4'/%3e%3c/svg%3e");
237
+ background-position: right var(--space-sm) center;
238
+ background-repeat: no-repeat;
239
+ background-size: 16px;
240
+ padding-right: 2.5rem;
241
+ }
242
+
243
+ .custom-select select:focus {
244
+ outline: none;
245
+ border-color: var(--accent-primary);
246
+ box-shadow: 0 0 0 3px rgba(249, 115, 22, 0.1);
247
+ }
248
+
249
+ .custom-select select:hover {
250
+ border-color: var(--border-accent);
251
+ }
252
+
253
+ /* Format Tabs */
254
+ .format-tabs {
255
+ display: flex;
256
+ gap: var(--space-xs);
257
+ margin-left: auto;
258
+ }
259
+
260
+ .format-tab {
261
+ padding: var(--space-sm) var(--space-lg);
262
+ background: var(--bg-card);
263
+ border: 1px solid var(--border-primary);
264
+ border-radius: var(--radius-md);
265
+ color: var(--text-secondary);
266
+ font-size: 0.875rem;
267
+ font-weight: 600;
268
+ cursor: pointer;
269
+ transition: all var(--transition-fast);
270
+ text-transform: uppercase;
271
+ letter-spacing: 0.05em;
272
+ }
273
+
274
+ .format-tab:hover:not(.active) {
275
+ background: var(--bg-tertiary);
276
+ color: var(--text-primary);
277
+ border-color: var(--border-secondary);
278
+ transform: translateY(-1px);
279
+ }
280
+
281
+ .format-tab.active {
282
+ background: var(--accent-primary);
283
+ border-color: var(--accent-primary);
284
+ color: white;
285
+ box-shadow: var(--shadow-md);
286
+ }
287
+
288
+ /* Main Content */
289
+ .main-content {
290
+ max-width: 1400px;
291
+ margin: 0 auto;
292
+ padding: var(--space-xl) var(--space-lg);
293
+ }
294
+
295
+ /* Dashboard Grid */
296
+ .dashboard-grid {
297
+ display: grid;
298
+ grid-template-columns: repeat(2, 1fr);
299
+ gap: var(--space-xl);
300
+ margin-bottom: var(--space-2xl);
301
+ }
302
+
303
+ /* Chart Cards */
304
+ .chart-card {
305
+ background: var(--bg-card);
306
+ border: 1px solid var(--border-primary);
307
+ border-radius: var(--radius-lg);
308
+ padding: var(--space-xl);
309
+ box-shadow: var(--shadow-md);
310
+ transition: all var(--transition-normal);
311
+ position: relative;
312
+ overflow: hidden;
313
+ }
314
+
315
+ .chart-card::before {
316
+ content: '';
317
+ position: absolute;
318
+ top: 0;
319
+ left: 0;
320
+ right: 0;
321
+ height: 3px;
322
+ background: var(--gradient-primary);
323
+ }
324
+
325
+ .chart-card:hover {
326
+ transform: translateY(-2px);
327
+ box-shadow: var(--shadow-lg);
328
+ }
329
+
330
+ .chart-header {
331
+ display: flex;
332
+ justify-content: between;
333
+ align-items: center;
334
+ margin-bottom: var(--space-lg);
335
+ }
336
+
337
+ .chart-title {
338
+ font-size: 1.25rem;
339
+ font-weight: 700;
340
+ color: var(--text-primary);
341
+ margin: 0;
342
+ }
343
+
344
+ .chart-subtitle {
345
+ font-size: 0.875rem;
346
+ color: var(--text-muted);
347
+ margin: var(--space-xs) 0 0 0;
348
+ }
349
+
350
+ .chart-container {
351
+ position: relative;
352
+ height: 300px;
353
+ margin-bottom: var(--space-md);
354
+ }
355
+
356
+ .chart-container canvas {
357
+ max-width: 100%;
358
+ height: auto;
359
+ }
360
+
361
+ /* Loading and Error States */
362
+ .chart-loading,
363
+ .chart-error {
364
+ display: flex;
365
+ align-items: center;
366
+ justify-content: center;
367
+ height: 300px;
368
+ color: var(--text-muted);
369
+ font-style: italic;
370
+ }
371
+
372
+ .chart-error {
373
+ color: var(--error);
374
+ }
375
+
376
+ /* Summary Section */
377
+ .summary-section {
378
+ background: var(--bg-card);
379
+ border: 1px solid var(--border-primary);
380
+ border-radius: var(--radius-lg);
381
+ padding: var(--space-xl);
382
+ margin-bottom: var(--space-2xl);
383
+ box-shadow: var(--shadow-md);
384
+ }
385
+
386
+ .summary-title {
387
+ font-size: 1.5rem;
388
+ font-weight: 700;
389
+ color: var(--text-primary);
390
+ margin-bottom: var(--space-lg);
391
+ }
392
+
393
+ .summary-grid {
394
+ display: grid;
395
+ grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
396
+ gap: var(--space-lg);
397
+ }
398
+
399
+ .summary-card {
400
+ background: var(--bg-secondary);
401
+ border: 1px solid var(--border-secondary);
402
+ border-radius: var(--radius-md);
403
+ padding: var(--space-lg);
404
+ transition: all var(--transition-fast);
405
+ }
406
+
407
+ .summary-card:hover {
408
+ transform: translateY(-1px);
409
+ box-shadow: var(--shadow-md);
410
+ }
411
+
412
+ .summary-card-title {
413
+ font-size: 1.125rem;
414
+ font-weight: 600;
415
+ color: var(--accent-primary);
416
+ margin-bottom: var(--space-md);
417
+ }
418
+
419
+ /* Environment Section */
420
+ .environment-section {
421
+ background: var(--bg-card);
422
+ border: 1px solid var(--border-primary);
423
+ border-radius: var(--radius-lg);
424
+ padding: var(--space-xl);
425
+ box-shadow: var(--shadow-md);
426
+ }
427
+
428
+ .environment-grid {
429
+ display: grid;
430
+ grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
431
+ gap: var(--space-lg);
432
+ }
433
+
434
+ .environment-card {
435
+ background: var(--bg-secondary);
436
+ border: 1px solid var(--border-secondary);
437
+ border-radius: var(--radius-md);
438
+ padding: var(--space-lg);
439
+ transition: all var(--transition-fast);
440
+ }
441
+
442
+ .environment-card:hover {
443
+ transform: translateY(-1px);
444
+ box-shadow: var(--shadow-md);
445
+ }
446
+
447
+ .environment-card-title {
448
+ font-size: 1.125rem;
449
+ font-weight: 600;
450
+ color: var(--text-primary);
451
+ margin-bottom: var(--space-md);
452
+ }
453
+
454
+ /* Responsive Design */
455
+ @media (max-width: 1024px) {
456
+ .dashboard-grid {
457
+ grid-template-columns: 1fr;
458
+ }
459
+
460
+ .filter-container {
461
+ flex-direction: column;
462
+ align-items: stretch;
463
+ gap: var(--space-md);
464
+ }
465
+
466
+ .format-tabs {
467
+ margin-left: 0;
468
+ justify-content: center;
469
+ }
470
+ }
471
+
472
+ @media (max-width: 768px) {
473
+ .navbar-header {
474
+ flex-direction: column;
475
+ gap: var(--space-md);
476
+ }
477
+
478
+ .navbar-controls {
479
+ order: -1;
480
+ align-self: flex-end;
481
+ }
482
+
483
+ .main-content {
484
+ padding: var(--space-lg) var(--space-md);
485
+ }
486
+
487
+ .chart-card {
488
+ padding: var(--space-lg);
489
+ }
490
+
491
+ .chart-container {
492
+ height: 250px;
493
+ }
494
+ }
495
+
496
+ @media (max-width: 480px) {
497
+ .format-tabs {
498
+ flex-direction: column;
499
+ width: 100%;
500
+ }
501
+
502
+ .format-tab {
503
+ width: 100%;
504
+ text-align: center;
505
+ }
506
+
507
+ .summary-grid,
508
+ .environment-grid {
509
+ grid-template-columns: 1fr;
510
+ }
511
+ }
512
+
513
+ /* Animations */
514
+ @keyframes fadeInUp {
515
+ from {
516
+ opacity: 0;
517
+ transform: translateY(20px);
518
+ }
519
+ to {
520
+ opacity: 1;
521
+ transform: translateY(0);
522
+ }
523
+ }
524
+
525
+ @keyframes slideInRight {
526
+ from {
527
+ opacity: 0;
528
+ transform: translateX(20px);
529
+ }
530
+ to {
531
+ opacity: 1;
532
+ transform: translateX(0);
533
+ }
534
+ }
535
+
536
+ .fade-in-up {
537
+ animation: fadeInUp 0.6s ease-out;
538
+ }
539
+
540
+ .slide-in-right {
541
+ animation: slideInRight 0.4s ease-out;
542
+ }
543
+
544
+ /* Utility Classes */
545
+ .hidden {
546
+ display: none !important;
547
+ }
548
+
549
+ .sr-only {
550
+ position: absolute;
551
+ width: 1px;
552
+ height: 1px;
553
+ padding: 0;
554
+ margin: -1px;
555
+ overflow: hidden;
556
+ clip: rect(0, 0, 0, 0);
557
+ white-space: nowrap;
558
+ border: 0;
559
+ }
560
+
561
+ /* Focus Styles for Accessibility */
562
+ *:focus {
563
+ outline: 2px solid var(--accent-primary);
564
+ outline-offset: 2px;
565
+ }
566
+
567
+ button:focus,
568
+ select:focus {
569
+ outline-offset: 0;
570
+ }
571
+
572
+ /* High Contrast Mode Support */
573
+ @media (prefers-contrast: high) {
574
+ :root {
575
+ --border-primary: var(--text-primary);
576
+ --border-secondary: var(--text-secondary);
577
+ }
578
+ }
579
+
580
+ /* Reduced Motion Support */
581
+ @media (prefers-reduced-motion: reduce) {
582
+ *,
583
+ *::before,
584
+ *::after {
585
+ animation-duration: 0.01ms !important;
586
+ animation-iteration-count: 1 !important;
587
+ transition-duration: 0.01ms !important;
588
+ }
589
+ }