sourcey 2.1.0 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (133) hide show
  1. package/README.md +128 -210
  2. package/dist/cli.js +18 -57
  3. package/dist/cli.js.map +1 -1
  4. package/dist/client/scroll-tracker.js +125 -40
  5. package/dist/client/search.js +27 -3
  6. package/dist/client/tabs.js +164 -24
  7. package/dist/components/App.d.ts +3 -2
  8. package/dist/components/App.d.ts.map +1 -1
  9. package/dist/components/App.js +3 -3
  10. package/dist/components/App.js.map +1 -1
  11. package/dist/components/layout/Head.d.ts.map +1 -1
  12. package/dist/components/layout/Head.js +30 -9
  13. package/dist/components/layout/Head.js.map +1 -1
  14. package/dist/components/layout/Header.d.ts +2 -7
  15. package/dist/components/layout/Header.d.ts.map +1 -1
  16. package/dist/components/layout/Header.js +12 -15
  17. package/dist/components/layout/Header.js.map +1 -1
  18. package/dist/components/layout/Page.d.ts.map +1 -1
  19. package/dist/components/layout/Page.js +54 -10
  20. package/dist/components/layout/Page.js.map +1 -1
  21. package/dist/components/layout/Sidebar.js +1 -1
  22. package/dist/components/layout/Sidebar.js.map +1 -1
  23. package/dist/components/layout/TableOfContents.d.ts.map +1 -1
  24. package/dist/components/layout/TableOfContents.js +1 -1
  25. package/dist/components/layout/TableOfContents.js.map +1 -1
  26. package/dist/components/openapi/CodeSamples.d.ts +4 -2
  27. package/dist/components/openapi/CodeSamples.d.ts.map +1 -1
  28. package/dist/components/openapi/CodeSamples.js +9 -5
  29. package/dist/components/openapi/CodeSamples.js.map +1 -1
  30. package/dist/components/openapi/Definition.js +1 -1
  31. package/dist/components/openapi/Definition.js.map +1 -1
  32. package/dist/components/openapi/EndpointBar.d.ts.map +1 -1
  33. package/dist/components/openapi/EndpointBar.js +3 -3
  34. package/dist/components/openapi/EndpointBar.js.map +1 -1
  35. package/dist/components/openapi/Introduction.d.ts.map +1 -1
  36. package/dist/components/openapi/Introduction.js +1 -1
  37. package/dist/components/openapi/Introduction.js.map +1 -1
  38. package/dist/components/openapi/Operation.d.ts.map +1 -1
  39. package/dist/components/openapi/Operation.js +5 -1
  40. package/dist/components/openapi/Operation.js.map +1 -1
  41. package/dist/components/openapi/Responses.d.ts +2 -1
  42. package/dist/components/openapi/Responses.d.ts.map +1 -1
  43. package/dist/components/openapi/Responses.js +17 -6
  44. package/dist/components/openapi/Responses.js.map +1 -1
  45. package/dist/components/openapi/Security.d.ts.map +1 -1
  46. package/dist/components/openapi/Security.js +3 -2
  47. package/dist/components/openapi/Security.js.map +1 -1
  48. package/dist/components/openapi/Tags.d.ts.map +1 -1
  49. package/dist/components/openapi/Tags.js +1 -1
  50. package/dist/components/openapi/Tags.js.map +1 -1
  51. package/dist/components/schema/ExampleView.d.ts +1 -1
  52. package/dist/components/schema/ExampleView.d.ts.map +1 -1
  53. package/dist/components/schema/ExampleView.js +3 -2
  54. package/dist/components/schema/ExampleView.js.map +1 -1
  55. package/dist/components/ui/CopyButton.d.ts +6 -0
  56. package/dist/components/ui/CopyButton.d.ts.map +1 -0
  57. package/dist/components/ui/CopyButton.js +10 -0
  58. package/dist/components/ui/CopyButton.js.map +1 -0
  59. package/dist/components/ui/Markdown.js +1 -1
  60. package/dist/components/ui/Markdown.js.map +1 -1
  61. package/dist/components/ui/SocialIcon.d.ts +5 -0
  62. package/dist/components/ui/SocialIcon.d.ts.map +1 -0
  63. package/dist/components/ui/SocialIcon.js +19 -0
  64. package/dist/components/ui/SocialIcon.js.map +1 -0
  65. package/dist/config.d.ts +133 -37
  66. package/dist/config.d.ts.map +1 -1
  67. package/dist/config.js +227 -73
  68. package/dist/config.js.map +1 -1
  69. package/dist/core/doxygen-loader.d.ts +9 -0
  70. package/dist/core/doxygen-loader.d.ts.map +1 -0
  71. package/dist/core/doxygen-loader.js +68 -0
  72. package/dist/core/doxygen-loader.js.map +1 -0
  73. package/dist/core/markdown-loader.d.ts +2 -5
  74. package/dist/core/markdown-loader.d.ts.map +1 -1
  75. package/dist/core/markdown-loader.js +218 -27
  76. package/dist/core/markdown-loader.js.map +1 -1
  77. package/dist/core/navigation.d.ts +2 -2
  78. package/dist/core/navigation.d.ts.map +1 -1
  79. package/dist/core/navigation.js +9 -10
  80. package/dist/core/navigation.js.map +1 -1
  81. package/dist/core/search-indexer.d.ts +1 -1
  82. package/dist/core/search-indexer.d.ts.map +1 -1
  83. package/dist/core/search-indexer.js +6 -5
  84. package/dist/core/search-indexer.js.map +1 -1
  85. package/dist/dev-server.d.ts +0 -12
  86. package/dist/dev-server.d.ts.map +1 -1
  87. package/dist/dev-server.js +101 -79
  88. package/dist/dev-server.js.map +1 -1
  89. package/dist/index.d.ts +2 -30
  90. package/dist/index.d.ts.map +1 -1
  91. package/dist/index.js +82 -70
  92. package/dist/index.js.map +1 -1
  93. package/dist/renderer/context.d.ts +29 -2
  94. package/dist/renderer/context.d.ts.map +1 -1
  95. package/dist/renderer/context.js +1 -1
  96. package/dist/renderer/context.js.map +1 -1
  97. package/dist/renderer/html-builder.d.ts +3 -16
  98. package/dist/renderer/html-builder.d.ts.map +1 -1
  99. package/dist/renderer/html-builder.js +6 -20
  100. package/dist/renderer/html-builder.js.map +1 -1
  101. package/dist/renderer/static-renderer.d.ts +2 -2
  102. package/dist/renderer/static-renderer.d.ts.map +1 -1
  103. package/dist/renderer/static-renderer.js +2 -2
  104. package/dist/renderer/static-renderer.js.map +1 -1
  105. package/dist/themes/default/main.css +13 -1
  106. package/dist/themes/default/sourcey.css +629 -41
  107. package/dist/utils/code-samples.d.ts +8 -3
  108. package/dist/utils/code-samples.d.ts.map +1 -1
  109. package/dist/utils/code-samples.js +188 -51
  110. package/dist/utils/code-samples.js.map +1 -1
  111. package/dist/utils/copy-svg.d.ts +9 -0
  112. package/dist/utils/copy-svg.d.ts.map +1 -0
  113. package/dist/utils/copy-svg.js +9 -0
  114. package/dist/utils/copy-svg.js.map +1 -0
  115. package/dist/utils/highlighter.d.ts.map +1 -1
  116. package/dist/utils/highlighter.js +18 -7
  117. package/dist/utils/highlighter.js.map +1 -1
  118. package/dist/utils/icons.d.ts +14 -0
  119. package/dist/utils/icons.d.ts.map +1 -0
  120. package/dist/utils/icons.js +59 -0
  121. package/dist/utils/icons.js.map +1 -0
  122. package/dist/utils/lang-icons.d.ts +17 -0
  123. package/dist/utils/lang-icons.d.ts.map +1 -0
  124. package/dist/utils/lang-icons.js +87 -0
  125. package/dist/utils/lang-icons.js.map +1 -0
  126. package/dist/utils/markdown.d.ts +17 -1
  127. package/dist/utils/markdown.d.ts.map +1 -1
  128. package/dist/utils/markdown.js +59 -2
  129. package/dist/utils/markdown.js.map +1 -1
  130. package/dist/vite-plugin.d.ts.map +1 -1
  131. package/dist/vite-plugin.js +4 -7
  132. package/dist/vite-plugin.js.map +1 -1
  133. package/package.json +5 -4
@@ -1,12 +1,19 @@
1
1
  /**
2
- * Sourcey — Minimal component styles.
2
+ * Sourcey — Component styles.
3
3
  *
4
- * Layout and OpenAPI components use Tailwind classes directly.
5
- * This file only contains what can't be expressed as utilities:
6
- * focus rings, search dialog, Shiki theming, code tab state,
7
- * parameter/schema display, selection.
4
+ * Layout and OpenAPI components use Tailwind classes in .tsx files.
5
+ * Markdown-generated components (code blocks, cards, steps, accordions,
6
+ * callouts, tabs) use semantic class names styled here — no Tailwind
7
+ * utilities in generated HTML.
8
8
  */
9
9
 
10
+ /* ── Scroll Offset (clears fixed navbar on anchor clicks) ──────────── */
11
+
12
+ [data-traverse-target],
13
+ h1[id], h2[id], h3[id], h4[id], h5[id], h6[id] {
14
+ scroll-margin-top: var(--header-height, 7rem);
15
+ }
16
+
10
17
  /* ── Focus ─────────────────────────────────────────────────────────── */
11
18
 
12
19
  #sourcey button:focus-visible {
@@ -14,12 +21,19 @@
14
21
  outline-offset: 2px;
15
22
  }
16
23
 
17
- /* ── Shiki Dual-Theme ─────────────────────────────────────────────── */
24
+ /* ── Shiki Dual-Theme (defaultColor: false) ───────────────────────── */
25
+ /* Shiki outputs --shiki-light and --shiki-dark CSS vars on each span. */
26
+ /* Light mode: use --shiki-light. Dark mode: use --shiki-dark. */
27
+
28
+ .shiki,
29
+ .shiki span {
30
+ color: var(--shiki-light);
31
+ background-color: transparent !important;
32
+ }
18
33
 
19
34
  .dark .shiki,
20
35
  .dark .shiki span {
21
- color: var(--shiki-dark) !important;
22
- background-color: transparent !important;
36
+ color: var(--shiki-dark);
23
37
  }
24
38
 
25
39
  .shiki pre {
@@ -34,75 +48,169 @@
34
48
  padding: 0;
35
49
  }
36
50
 
51
+ /* ── Prose Code Block (fenced code in markdown pages) ─────────────── */
52
+
53
+ #sourcey .prose-code-block {
54
+ position: relative;
55
+ border-radius: var(--radius);
56
+ border: 1px solid rgb(var(--color-gray-950) / 0.1);
57
+ margin: 1.25rem 0 2rem;
58
+ overflow: hidden;
59
+ color: rgb(var(--color-gray-950));
60
+ }
61
+ .dark #sourcey .prose-code-block {
62
+ border-color: rgb(255 255 255 / 0.1);
63
+ color: rgb(var(--color-gray-50));
64
+ }
65
+
66
+ #sourcey .prose-code-copy {
67
+ position: absolute;
68
+ top: 0.75rem;
69
+ right: 1rem;
70
+ z-index: 10;
71
+ }
72
+
73
+ #sourcey .prose-code-copy .copy-btn {
74
+ display: flex;
75
+ align-items: center;
76
+ justify-content: center;
77
+ width: 26px;
78
+ height: 26px;
79
+ border-radius: 0.375rem;
80
+ border: none;
81
+ background: transparent;
82
+ cursor: pointer;
83
+ color: rgb(var(--color-gray-400));
84
+ transition: color 0.15s;
85
+ }
86
+ #sourcey .prose-code-copy .copy-btn:hover {
87
+ color: rgb(var(--color-gray-500));
88
+ }
89
+ .dark #sourcey .prose-code-copy .copy-btn {
90
+ color: rgb(255 255 255 / 0.4);
91
+ }
92
+ .dark #sourcey .prose-code-copy .copy-btn:hover {
93
+ color: rgb(255 255 255 / 0.6);
94
+ }
95
+
96
+ #sourcey .prose-code-copy .copy-btn svg {
97
+ width: 1rem;
98
+ height: 1rem;
99
+ }
100
+
101
+ #sourcey .prose-code-content {
102
+ padding: 0.875rem 1rem;
103
+ border-radius: var(--radius);
104
+ background: #fff;
105
+ overflow-x: auto;
106
+ font-variant-ligatures: none;
107
+ }
108
+ .dark #sourcey .prose-code-content {
109
+ background: rgb(var(--color-code-block-dark));
110
+ }
111
+
112
+ #sourcey .prose-code-content pre {
113
+ margin: 0;
114
+ font-family: var(--font-mono);
115
+ font-size: 0.875rem;
116
+ line-height: 1.5rem;
117
+ white-space: pre;
118
+ }
119
+
37
120
  /* ── Sidebar Nav Links (state managed by scroll-tracker + SSR) ────── */
38
121
 
39
122
  #sourcey #nav .nav-link {
40
123
  display: flex;
41
124
  align-items: flex-start;
42
- padding: 0.375rem 0.75rem 0.375rem 1rem;
125
+ padding: 0.25rem 0.75rem 0.25rem 1rem;
43
126
  gap: 0.75rem;
44
127
  cursor: pointer;
45
128
  text-align: left;
46
129
  overflow-wrap: break-word;
47
130
  hyphens: auto;
48
- border-radius: 0.75rem;
131
+ border-radius: 0;
132
+ border-left: 2px solid transparent;
49
133
  width: 100%;
50
134
  color: rgb(var(--color-gray-700));
51
- transition: color 0.15s, background-color 0.15s;
135
+ transition: color 0.15s, border-color 0.15s;
52
136
  }
53
137
  .dark #sourcey #nav .nav-link {
54
138
  color: rgb(var(--color-gray-400));
55
139
  }
56
140
 
57
141
  #sourcey #nav .nav-link:hover {
58
- background: rgb(var(--color-gray-600) / 0.05);
59
142
  color: rgb(var(--color-gray-900));
143
+ border-left-color: rgb(var(--color-gray-300));
60
144
  }
61
145
  .dark #sourcey #nav .nav-link:hover {
62
- background: rgb(var(--color-gray-200) / 0.05);
63
146
  color: rgb(var(--color-gray-300));
147
+ border-left-color: rgb(var(--color-gray-600));
64
148
  }
65
149
 
66
150
  #sourcey #nav .nav-link.active {
67
- background: rgb(var(--color-primary) / 0.1);
68
151
  color: rgb(var(--color-primary));
152
+ border-left-color: rgb(var(--color-primary));
153
+ font-weight: 500;
69
154
  }
70
155
  .dark #sourcey #nav .nav-link.active {
71
- background: rgb(var(--color-primary-light) / 0.1);
72
156
  color: rgb(var(--color-primary-light));
157
+ border-left-color: rgb(var(--color-primary-light));
73
158
  }
74
159
 
75
- /* ── Code Sample Tabs (state managed by client JS) ────────────────── */
160
+ /* ── TOC Active State ─────────────────────────────────────────────── */
76
161
 
77
- #sourcey .code-samples-panel { display: none; }
78
- #sourcey .code-samples-panel.active { display: block; }
162
+ #sourcey #toc .toc-item.active {
163
+ color: rgb(var(--color-primary));
164
+ }
165
+ .dark #sourcey #toc .toc-item.active {
166
+ color: rgb(var(--color-primary-light));
167
+ }
79
168
 
80
- #sourcey .code-samples-tab {
81
- position: relative;
82
- display: flex;
83
- align-items: center;
84
- gap: 0.375rem;
85
- white-space: nowrap;
86
- font-weight: 500;
87
- outline: 0;
88
- margin-top: 0.25rem;
89
- margin-bottom: 0.375rem;
90
- color: rgb(var(--color-gray-500));
169
+ /* ── Code Block Panels (language dropdown + response tabs) ─────────── */
170
+
171
+ #sourcey .code-lang-panel { display: none; }
172
+ #sourcey .code-lang-panel.active { display: block; }
173
+
174
+ #sourcey .lang-icon {
175
+ width: 0.875rem;
176
+ height: 0.875rem;
177
+ flex-shrink: 0;
178
+ vertical-align: -0.125rem;
179
+ }
180
+
181
+ #sourcey .lang-icon[data-lang] {
182
+ display: inline-block;
183
+ background: currentColor;
184
+ -webkit-mask-size: contain;
185
+ mask-size: contain;
186
+ -webkit-mask-repeat: no-repeat;
187
+ mask-repeat: no-repeat;
188
+ -webkit-mask-position: center;
189
+ mask-position: center;
190
+ }
191
+
192
+ #sourcey .response-panel { display: none; }
193
+ #sourcey .response-panel.active { display: block; }
194
+
195
+ /* ── Response Tabs (status code tabs on code block) ───────────────── */
196
+
197
+ #sourcey .response-tab {
198
+ color: rgb(var(--color-stone-500));
91
199
  transition: color 0.15s;
92
200
  }
93
- .dark #sourcey .code-samples-tab {
94
- color: rgb(var(--color-gray-400));
201
+ .dark #sourcey .response-tab {
202
+ color: rgb(var(--color-stone-400));
95
203
  }
96
204
 
97
- #sourcey .code-samples-tab.active {
205
+ #sourcey .response-tab.active {
98
206
  color: rgb(var(--color-primary));
99
207
  }
100
- .dark #sourcey .code-samples-tab.active {
208
+ .dark #sourcey .response-tab.active {
101
209
  color: rgb(var(--color-primary-light));
102
210
  }
103
211
 
104
- /* Active tab underline indicator */
105
- #sourcey .code-samples-tab.active::after {
212
+ /* Active response tab underline */
213
+ #sourcey .response-tab.active::after {
106
214
  content: '';
107
215
  position: absolute;
108
216
  right: 0;
@@ -112,7 +220,7 @@
112
220
  border-radius: 9999px;
113
221
  background: rgb(var(--color-primary));
114
222
  }
115
- .dark #sourcey .code-samples-tab.active::after {
223
+ .dark #sourcey .response-tab.active::after {
116
224
  background: rgb(var(--color-primary-light));
117
225
  }
118
226
 
@@ -278,6 +386,422 @@
278
386
  margin-bottom: 0.25rem;
279
387
  }
280
388
 
389
+ /* ── Steps (numbered step list with vertical connector) ────────────── */
390
+
391
+ #sourcey .steps {
392
+ margin-left: 0.875rem;
393
+ margin-top: 2.5rem;
394
+ margin-bottom: 1.5rem;
395
+ }
396
+
397
+ #sourcey .steps .step-item {
398
+ position: relative;
399
+ display: flex;
400
+ align-items: flex-start;
401
+ padding-bottom: 1.25rem;
402
+ }
403
+
404
+ #sourcey .steps .step-item::before {
405
+ content: '';
406
+ position: absolute;
407
+ left: 13px;
408
+ top: 2.75rem;
409
+ bottom: 0;
410
+ width: 1px;
411
+ background: rgb(var(--color-gray-200) / 0.7);
412
+ }
413
+ .dark #sourcey .steps .step-item::before {
414
+ background: rgb(255 255 255 / 0.1);
415
+ }
416
+
417
+ #sourcey .steps .step-item:last-child::before {
418
+ background: linear-gradient(to bottom, rgb(var(--color-gray-200) / 0.7), transparent);
419
+ }
420
+ .dark #sourcey .steps .step-item:last-child::before {
421
+ background: linear-gradient(to bottom, rgb(255 255 255 / 0.1), transparent);
422
+ }
423
+
424
+ #sourcey .steps .step-number {
425
+ position: relative;
426
+ display: flex;
427
+ align-items: center;
428
+ justify-content: center;
429
+ width: 1.75rem;
430
+ height: 1.75rem;
431
+ flex-shrink: 0;
432
+ border-radius: 9999px;
433
+ background: rgb(var(--color-gray-50));
434
+ font-size: 0.75rem;
435
+ font-weight: 600;
436
+ color: rgb(var(--color-gray-900));
437
+ margin-top: 0.5rem;
438
+ }
439
+ .dark #sourcey .steps .step-number {
440
+ background: rgb(255 255 255 / 0.1);
441
+ color: rgb(var(--color-gray-50));
442
+ }
443
+
444
+ #sourcey .steps .step-body {
445
+ padding-left: 1rem;
446
+ flex: 1;
447
+ overflow: hidden;
448
+ }
449
+
450
+ #sourcey .steps .step-title {
451
+ margin-top: 0.5rem;
452
+ font-weight: 600;
453
+ color: rgb(var(--color-gray-900));
454
+ }
455
+ .dark #sourcey .steps .step-title {
456
+ color: rgb(var(--color-gray-200));
457
+ }
458
+
459
+ #sourcey .steps .step-content {
460
+ margin-top: 0.25rem;
461
+ }
462
+
463
+ #sourcey .steps .step-content p {
464
+ margin: 0.25rem 0;
465
+ }
466
+
467
+ /* ── Card Group (icon cards in a grid) ─────────────────────────────── */
468
+
469
+ #sourcey .card-group {
470
+ display: grid;
471
+ gap: 1rem;
472
+ margin-top: 1.25rem;
473
+ margin-bottom: 2rem;
474
+ }
475
+ @media (min-width: 640px) {
476
+ #sourcey .card-group[data-cols="2"] { grid-template-columns: repeat(2, 1fr); }
477
+ #sourcey .card-group[data-cols="3"] { grid-template-columns: repeat(3, 1fr); }
478
+ #sourcey .card-group[data-cols="4"] { grid-template-columns: repeat(4, 1fr); }
479
+ }
480
+
481
+ #sourcey .card-item {
482
+ display: block;
483
+ position: relative;
484
+ border: 1px solid rgb(var(--color-gray-950) / 0.1);
485
+ border-radius: var(--radius);
486
+ padding: 1.25rem 1.5rem;
487
+ background: rgb(var(--color-background-light));
488
+ text-decoration: none;
489
+ color: inherit;
490
+ cursor: pointer;
491
+ overflow: hidden;
492
+ transition: border-color 0.15s;
493
+ }
494
+ .dark #sourcey .card-item {
495
+ border-color: rgb(255 255 255 / 0.1);
496
+ background: rgb(var(--color-background-dark));
497
+ }
498
+
499
+ #sourcey .card-item:hover {
500
+ border-color: rgb(var(--color-primary));
501
+ }
502
+ .dark #sourcey .card-item:hover {
503
+ border-color: rgb(var(--color-primary-light));
504
+ }
505
+
506
+ #sourcey .card-icon {
507
+ width: 1.5rem;
508
+ height: 1.5rem;
509
+ flex-shrink: 0;
510
+ color: rgb(var(--color-primary));
511
+ margin-bottom: 0.75rem;
512
+ }
513
+ .dark #sourcey .card-icon {
514
+ color: rgb(var(--color-primary-light));
515
+ }
516
+
517
+ #sourcey .card-item-title {
518
+ font-size: 1rem;
519
+ font-weight: 600;
520
+ color: rgb(var(--color-gray-800));
521
+ margin: 0 0 0.25rem;
522
+ }
523
+ .dark #sourcey .card-item-title {
524
+ color: #fff;
525
+ }
526
+
527
+ #sourcey .card-item-content {
528
+ margin-top: 0.25rem;
529
+ font-size: 1rem;
530
+ line-height: 1.5;
531
+ color: rgb(var(--color-gray-600));
532
+ }
533
+ .dark #sourcey .card-item-content {
534
+ color: rgb(var(--color-gray-400));
535
+ }
536
+
537
+ #sourcey .card-item-content p {
538
+ margin: 0;
539
+ }
540
+
541
+ /* ── Accordion (expandable details) ────────────────────────────────── */
542
+
543
+ #sourcey .accordion-group {
544
+ margin-top: 0;
545
+ margin-bottom: 0.75rem;
546
+ border-radius: var(--radius);
547
+ border: 1px solid rgb(var(--color-gray-200) / 0.7);
548
+ overflow: hidden;
549
+ }
550
+ .dark #sourcey .accordion-group {
551
+ border-color: rgb(var(--color-gray-800) / 0.5);
552
+ }
553
+
554
+ #sourcey .accordion-item {
555
+ border-bottom: 1px solid rgb(var(--color-gray-200) / 0.7);
556
+ background: rgb(var(--color-background-light));
557
+ }
558
+ .dark #sourcey .accordion-item {
559
+ border-bottom-color: rgb(var(--color-gray-800) / 0.5);
560
+ background: rgb(var(--color-code-block-dark));
561
+ }
562
+
563
+ #sourcey .accordion-item:last-child {
564
+ border-bottom: none;
565
+ }
566
+
567
+ #sourcey .accordion-trigger {
568
+ display: flex;
569
+ align-items: center;
570
+ gap: 0.5rem;
571
+ width: 100%;
572
+ padding: 1rem 1.25rem;
573
+ cursor: pointer;
574
+ font-weight: 500;
575
+ color: rgb(var(--color-gray-900));
576
+ list-style: none;
577
+ }
578
+ #sourcey .accordion-trigger::-webkit-details-marker { display: none; }
579
+ .dark #sourcey .accordion-trigger {
580
+ color: rgb(var(--color-gray-200));
581
+ }
582
+
583
+ #sourcey .accordion-trigger:hover {
584
+ background: rgb(var(--color-gray-100));
585
+ }
586
+ .dark #sourcey .accordion-trigger:hover {
587
+ background: rgb(var(--color-gray-800));
588
+ }
589
+
590
+ #sourcey .accordion-trigger::before {
591
+ content: '';
592
+ display: inline-block;
593
+ width: 0.75rem;
594
+ height: 0.75rem;
595
+ flex-shrink: 0;
596
+ background: rgb(var(--color-gray-700));
597
+ mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 256 512'%3E%3Cpath d='M246.6 278.6c12.5-12.5 12.5-32.8 0-45.3l-128-128c-9.2-9.2-22.9-11.9-34.9-6.9s-19.8 16.6-19.8 29.6l0 256c0 12.9 7.8 24.6 19.8 29.6s25.7 2.2 34.9-6.9l128-128z'/%3E%3C/svg%3E");
598
+ mask-repeat: no-repeat;
599
+ mask-position: center;
600
+ mask-size: contain;
601
+ transition: transform 0.15s;
602
+ }
603
+ .dark #sourcey .accordion-trigger::before {
604
+ background: rgb(var(--color-gray-400));
605
+ }
606
+
607
+ #sourcey .accordion-item[open] > .accordion-trigger::before {
608
+ transform: rotate(90deg);
609
+ }
610
+
611
+ #sourcey .accordion-content {
612
+ padding: 0 1.25rem 1rem 2.5rem;
613
+ color: rgb(var(--color-gray-700));
614
+ }
615
+ .dark #sourcey .accordion-content {
616
+ color: rgb(var(--color-gray-400));
617
+ }
618
+
619
+ #sourcey .accordion-content p {
620
+ margin: 0.25rem 0;
621
+ }
622
+
623
+ /* ── Callouts (:::note, :::warning, :::tip, :::info) ───────────────── */
624
+
625
+ #sourcey .callout {
626
+ margin: 1.25rem 0;
627
+ border-radius: var(--radius);
628
+ border: 1px solid rgb(var(--color-gray-200) / 0.7);
629
+ border-left-width: 3px;
630
+ padding: 0.875rem 1rem;
631
+ font-size: 0.875rem;
632
+ line-height: 1.6;
633
+ color: rgb(var(--color-gray-700));
634
+ }
635
+ .dark #sourcey .callout {
636
+ border-color: rgb(var(--color-gray-800) / 0.5);
637
+ color: rgb(var(--color-gray-400));
638
+ }
639
+
640
+ #sourcey .callout-title {
641
+ font-weight: 600;
642
+ font-size: 0.8125rem;
643
+ text-transform: uppercase;
644
+ letter-spacing: 0.04em;
645
+ }
646
+
647
+ /* Remove bottom margin when no content follows */
648
+ #sourcey .callout-title:last-child {
649
+ margin-bottom: 0;
650
+ }
651
+
652
+ #sourcey .callout-content {
653
+ margin-top: 0.375rem;
654
+ }
655
+
656
+ #sourcey .callout-content p {
657
+ margin: 0.25rem 0;
658
+ }
659
+
660
+ #sourcey .callout-content p:last-child {
661
+ margin-bottom: 0;
662
+ }
663
+
664
+ /* Note — blue */
665
+ #sourcey .callout-note {
666
+ border-left-color: #3b82f6;
667
+ background: rgb(59 130 246 / 0.04);
668
+ }
669
+ .dark #sourcey .callout-note {
670
+ border-left-color: #60a5fa;
671
+ background: rgb(59 130 246 / 0.06);
672
+ }
673
+ #sourcey .callout-note .callout-title { color: #3b82f6; }
674
+ .dark #sourcey .callout-note .callout-title { color: #60a5fa; }
675
+
676
+ /* Warning — amber */
677
+ #sourcey .callout-warning {
678
+ border-left-color: #f59e0b;
679
+ background: rgb(245 158 11 / 0.04);
680
+ }
681
+ .dark #sourcey .callout-warning {
682
+ border-left-color: #fbbf24;
683
+ background: rgb(245 158 11 / 0.06);
684
+ }
685
+ #sourcey .callout-warning .callout-title { color: #f59e0b; }
686
+ .dark #sourcey .callout-warning .callout-title { color: #fbbf24; }
687
+
688
+ /* Tip — green */
689
+ #sourcey .callout-tip {
690
+ border-left-color: #22c55e;
691
+ background: rgb(34 197 94 / 0.04);
692
+ }
693
+ .dark #sourcey .callout-tip {
694
+ border-left-color: #4ade80;
695
+ background: rgb(34 197 94 / 0.06);
696
+ }
697
+ #sourcey .callout-tip .callout-title { color: #22c55e; }
698
+ .dark #sourcey .callout-tip .callout-title { color: #4ade80; }
699
+
700
+ /* Info — violet */
701
+ #sourcey .callout-info {
702
+ border-left-color: #8b5cf6;
703
+ background: rgb(139 92 246 / 0.04);
704
+ }
705
+ .dark #sourcey .callout-info {
706
+ border-left-color: #a78bfa;
707
+ background: rgb(139 92 246 / 0.06);
708
+ }
709
+ #sourcey .callout-info .callout-title { color: #8b5cf6; }
710
+ .dark #sourcey .callout-info .callout-title { color: #a78bfa; }
711
+
712
+ /* ── Directive Tabs (:::tabs, :::code-group) ───────────────────────── */
713
+
714
+ #sourcey .directive-tabs {
715
+ margin: 1.25rem 0;
716
+ border: 1px solid rgb(var(--color-gray-200) / 0.7);
717
+ border-radius: var(--radius);
718
+ overflow: hidden;
719
+ }
720
+ .dark #sourcey .directive-tabs {
721
+ border-color: rgb(var(--color-gray-800) / 0.5);
722
+ }
723
+
724
+ #sourcey .directive-tab-bar {
725
+ display: flex;
726
+ gap: 0;
727
+ border-bottom: 1px solid rgb(var(--color-gray-200) / 0.7);
728
+ background: rgb(var(--color-gray-50));
729
+ padding: 0 0.25rem;
730
+ }
731
+ .dark #sourcey .directive-tab-bar {
732
+ border-bottom-color: rgb(var(--color-gray-800) / 0.5);
733
+ background: rgb(var(--color-code-block-dark));
734
+ }
735
+
736
+ #sourcey .directive-tab {
737
+ position: relative;
738
+ padding: 0.625rem 1rem;
739
+ font-size: 0.8125rem;
740
+ font-weight: 500;
741
+ color: rgb(var(--color-gray-500));
742
+ background: transparent;
743
+ border: none;
744
+ cursor: pointer;
745
+ transition: color 0.15s;
746
+ }
747
+ #sourcey .directive-tab:hover {
748
+ color: rgb(var(--color-gray-900));
749
+ }
750
+ .dark #sourcey .directive-tab:hover {
751
+ color: rgb(var(--color-gray-300));
752
+ }
753
+
754
+ #sourcey .directive-tab.active {
755
+ color: rgb(var(--color-primary));
756
+ }
757
+ .dark #sourcey .directive-tab.active {
758
+ color: rgb(var(--color-primary-light));
759
+ }
760
+
761
+ #sourcey .directive-tab.active::after {
762
+ content: '';
763
+ position: absolute;
764
+ right: 0.5rem;
765
+ bottom: -1px;
766
+ left: 0.5rem;
767
+ height: 2px;
768
+ border-radius: 9999px;
769
+ background: rgb(var(--color-primary));
770
+ }
771
+ .dark #sourcey .directive-tab.active::after {
772
+ background: rgb(var(--color-primary-light));
773
+ }
774
+
775
+ #sourcey .directive-tab-panel {
776
+ display: none;
777
+ padding: 1rem 1.25rem;
778
+ }
779
+
780
+ #sourcey .directive-tab-panel.active {
781
+ display: block;
782
+ }
783
+
784
+ /* Code group: tighter padding, code blocks fill the panel */
785
+ #sourcey .directive-code-group .directive-tab-panel {
786
+ padding: 0;
787
+ }
788
+
789
+ #sourcey .directive-code-group .directive-tab-panel pre {
790
+ margin: 0;
791
+ border-radius: 0;
792
+ }
793
+
794
+ /* Strip nested code block chrome inside tab panels */
795
+ #sourcey .directive-tabs .prose-code-block {
796
+ border: none;
797
+ border-radius: 0;
798
+ margin: 0;
799
+ }
800
+
801
+ #sourcey .directive-tabs .prose-code-block .prose-code-copy {
802
+ display: none;
803
+ }
804
+
281
805
  /* ── Selection ─────────────────────────────────────────────────────── */
282
806
 
283
807
  #sourcey ::selection { background: rgb(var(--color-primary) / 0.12); }
@@ -305,7 +829,7 @@
305
829
  width: 100%;
306
830
  max-width: 540px;
307
831
  background: rgb(var(--color-background-light));
308
- border-radius: 0.75rem;
832
+ border-radius: var(--radius);
309
833
  box-shadow: 0 16px 48px rgb(var(--color-overlay) / 0.2);
310
834
  overflow: hidden;
311
835
  margin: 0 1rem;
@@ -315,20 +839,35 @@
315
839
  box-shadow: 0 16px 48px rgb(var(--color-overlay) / 0.5);
316
840
  }
317
841
 
842
+ #sourcey .search-input-row {
843
+ display: flex;
844
+ align-items: center;
845
+ gap: 0.625rem;
846
+ padding: 0.75rem 1rem;
847
+ border-bottom: 1px solid rgb(var(--color-gray-200));
848
+ }
849
+ .dark #sourcey .search-input-row {
850
+ border-bottom-color: rgb(var(--color-gray-800));
851
+ }
852
+
853
+ #sourcey .search-input-icon {
854
+ width: 1.125rem;
855
+ height: 1.125rem;
856
+ flex-shrink: 0;
857
+ color: rgb(var(--color-gray-400));
858
+ }
859
+
318
860
  #sourcey #search-input {
319
861
  width: 100%;
320
- padding: 0.75rem 1rem;
321
862
  border: none;
322
- border-bottom: 1px solid rgb(var(--color-gray-200));
323
863
  font-family: var(--font-sans);
324
- font-size: 1rem;
864
+ font-size: 0.9375rem;
325
865
  color: rgb(var(--color-gray-900));
326
866
  background: transparent;
327
867
  outline: none;
328
868
  }
329
869
  .dark #sourcey #search-input {
330
870
  color: rgb(var(--color-gray-100));
331
- border-bottom-color: rgb(var(--color-gray-800));
332
871
  }
333
872
 
334
873
  #sourcey #search-input::placeholder { color: rgb(var(--color-gray-400)); }
@@ -339,6 +878,55 @@
339
878
  padding: 0.25rem;
340
879
  }
341
880
 
881
+ #sourcey .search-category {
882
+ padding: 0.5rem 0.75rem 0.25rem;
883
+ font-size: 0.6875rem;
884
+ font-weight: 600;
885
+ text-transform: uppercase;
886
+ letter-spacing: 0.05em;
887
+ color: rgb(var(--color-gray-400));
888
+ }
889
+
890
+ #sourcey .search-footer {
891
+ display: flex;
892
+ align-items: center;
893
+ gap: 1rem;
894
+ padding: 0.5rem 0.75rem;
895
+ border-top: 1px solid rgb(var(--color-gray-200));
896
+ font-size: 0.6875rem;
897
+ color: rgb(var(--color-gray-400));
898
+ }
899
+ .dark #sourcey .search-footer {
900
+ border-top-color: rgb(var(--color-gray-800));
901
+ }
902
+
903
+ #sourcey .search-footer-hint {
904
+ display: flex;
905
+ align-items: center;
906
+ gap: 0.25rem;
907
+ }
908
+
909
+ #sourcey .search-footer kbd {
910
+ display: inline-flex;
911
+ align-items: center;
912
+ justify-content: center;
913
+ min-width: 1.25rem;
914
+ height: 1.125rem;
915
+ padding: 0 0.25rem;
916
+ font-family: var(--font-sans);
917
+ font-size: 0.625rem;
918
+ font-weight: 500;
919
+ border-radius: 0.25rem;
920
+ border: 1px solid rgb(var(--color-gray-200));
921
+ background: rgb(var(--color-gray-50));
922
+ color: rgb(var(--color-gray-500));
923
+ }
924
+ .dark #sourcey .search-footer kbd {
925
+ border-color: rgb(var(--color-gray-700));
926
+ background: rgb(var(--color-gray-800));
927
+ color: rgb(var(--color-gray-400));
928
+ }
929
+
342
930
  #sourcey .search-result {
343
931
  display: flex;
344
932
  align-items: baseline;