docyard 0.6.0 → 0.8.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 (177) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +5 -1
  3. data/CHANGELOG.md +34 -1
  4. data/lib/docyard/build/asset_bundler.rb +22 -7
  5. data/lib/docyard/build/file_copier.rb +49 -27
  6. data/lib/docyard/build/sitemap_generator.rb +6 -6
  7. data/lib/docyard/build/static_generator.rb +82 -50
  8. data/lib/docyard/builder.rb +20 -10
  9. data/lib/docyard/cli.rb +6 -3
  10. data/lib/docyard/components/aliases.rb +29 -0
  11. data/lib/docyard/components/processors/callout_processor.rb +124 -0
  12. data/lib/docyard/components/processors/code_block_diff_preprocessor.rb +106 -0
  13. data/lib/docyard/components/processors/code_block_focus_preprocessor.rb +79 -0
  14. data/lib/docyard/components/processors/code_block_options_preprocessor.rb +78 -0
  15. data/lib/docyard/components/processors/code_block_processor.rb +175 -0
  16. data/lib/docyard/components/processors/code_snippet_import_preprocessor.rb +127 -0
  17. data/lib/docyard/components/processors/heading_anchor_processor.rb +39 -0
  18. data/lib/docyard/components/processors/icon_processor.rb +53 -0
  19. data/lib/docyard/components/processors/table_of_contents_processor.rb +68 -0
  20. data/lib/docyard/components/processors/table_wrapper_processor.rb +22 -0
  21. data/lib/docyard/components/processors/tabs_processor.rb +48 -0
  22. data/lib/docyard/components/support/code_block/feature_extractor.rb +117 -0
  23. data/lib/docyard/components/support/code_block/icon_detector.rb +44 -0
  24. data/lib/docyard/components/support/code_block/line_parser.rb +84 -0
  25. data/lib/docyard/components/support/code_block/line_wrapper.rb +50 -0
  26. data/lib/docyard/components/support/code_block/patterns.rb +55 -0
  27. data/lib/docyard/components/support/code_detector.rb +61 -0
  28. data/lib/docyard/components/support/tabs/icon_detector.rb +62 -0
  29. data/lib/docyard/components/support/tabs/parser.rb +195 -0
  30. data/lib/docyard/components/support/tabs/range_finder.rb +46 -0
  31. data/lib/docyard/config/branding_resolver.rb +183 -0
  32. data/lib/docyard/{constants.rb → config/constants.rb} +7 -4
  33. data/lib/docyard/config/validator.rb +122 -99
  34. data/lib/docyard/config.rb +38 -36
  35. data/lib/docyard/initializer.rb +15 -76
  36. data/lib/docyard/navigation/breadcrumb_builder.rb +133 -0
  37. data/lib/docyard/{prev_next_builder.rb → navigation/prev_next_builder.rb} +6 -3
  38. data/lib/docyard/navigation/sidebar/children_discoverer.rb +51 -0
  39. data/lib/docyard/navigation/sidebar/config_parser.rb +208 -0
  40. data/lib/docyard/navigation/sidebar/file_resolver.rb +78 -0
  41. data/lib/docyard/{sidebar → navigation/sidebar}/file_system_scanner.rb +2 -1
  42. data/lib/docyard/navigation/sidebar/item.rb +96 -0
  43. data/lib/docyard/navigation/sidebar/local_config_loader.rb +51 -0
  44. data/lib/docyard/navigation/sidebar/metadata_extractor.rb +69 -0
  45. data/lib/docyard/navigation/sidebar/metadata_reader.rb +47 -0
  46. data/lib/docyard/navigation/sidebar/path_prefixer.rb +34 -0
  47. data/lib/docyard/navigation/sidebar/renderer.rb +144 -0
  48. data/lib/docyard/navigation/sidebar/sorter.rb +21 -0
  49. data/lib/docyard/navigation/sidebar/tree_builder.rb +139 -0
  50. data/lib/docyard/navigation/sidebar/tree_filter.rb +55 -0
  51. data/lib/docyard/navigation/sidebar_builder.rb +159 -0
  52. data/lib/docyard/rendering/icon_helpers.rb +13 -0
  53. data/lib/docyard/{icons → rendering/icons}/phosphor.rb +26 -1
  54. data/lib/docyard/{markdown.rb → rendering/markdown.rb} +19 -13
  55. data/lib/docyard/rendering/renderer.rb +163 -0
  56. data/lib/docyard/rendering/template_resolver.rb +172 -0
  57. data/lib/docyard/routing/fallback_resolver.rb +92 -0
  58. data/lib/docyard/search/build_indexer.rb +74 -0
  59. data/lib/docyard/search/dev_indexer.rb +155 -0
  60. data/lib/docyard/search/pagefind_support.rb +33 -0
  61. data/lib/docyard/{asset_handler.rb → server/asset_handler.rb} +24 -19
  62. data/lib/docyard/{server.rb → server/dev_server.rb} +32 -9
  63. data/lib/docyard/server/pagefind_handler.rb +63 -0
  64. data/lib/docyard/{preview_server.rb → server/preview_server.rb} +2 -2
  65. data/lib/docyard/server/rack_application.rb +192 -0
  66. data/lib/docyard/server/resolution_result.rb +29 -0
  67. data/lib/docyard/{router.rb → server/router.rb} +4 -4
  68. data/lib/docyard/templates/assets/css/code.css +18 -51
  69. data/lib/docyard/templates/assets/css/components/breadcrumbs.css +143 -0
  70. data/lib/docyard/templates/assets/css/components/callout.css +67 -67
  71. data/lib/docyard/templates/assets/css/components/code-block.css +180 -282
  72. data/lib/docyard/templates/assets/css/components/heading-anchor.css +28 -15
  73. data/lib/docyard/templates/assets/css/components/icon.css +0 -1
  74. data/lib/docyard/templates/assets/css/components/logo.css +0 -2
  75. data/lib/docyard/templates/assets/css/components/nav-menu.css +237 -0
  76. data/lib/docyard/templates/assets/css/components/navigation.css +186 -167
  77. data/lib/docyard/templates/assets/css/components/prev-next.css +76 -47
  78. data/lib/docyard/templates/assets/css/components/search.css +561 -0
  79. data/lib/docyard/templates/assets/css/components/tab-bar.css +163 -0
  80. data/lib/docyard/templates/assets/css/components/table-of-contents.css +127 -114
  81. data/lib/docyard/templates/assets/css/components/tabs.css +119 -160
  82. data/lib/docyard/templates/assets/css/components/theme-toggle.css +48 -44
  83. data/lib/docyard/templates/assets/css/landing.css +815 -0
  84. data/lib/docyard/templates/assets/css/layout.css +503 -87
  85. data/lib/docyard/templates/assets/css/main.css +1 -3
  86. data/lib/docyard/templates/assets/css/markdown.css +111 -93
  87. data/lib/docyard/templates/assets/css/reset.css +0 -3
  88. data/lib/docyard/templates/assets/css/typography.css +43 -41
  89. data/lib/docyard/templates/assets/css/variables.css +268 -208
  90. data/lib/docyard/templates/assets/favicon.svg +7 -8
  91. data/lib/docyard/templates/assets/fonts/Inter-Variable.ttf +0 -0
  92. data/lib/docyard/templates/assets/js/components/code-block.js +24 -42
  93. data/lib/docyard/templates/assets/js/components/heading-anchor.js +26 -24
  94. data/lib/docyard/templates/assets/js/components/navigation.js +181 -70
  95. data/lib/docyard/templates/assets/js/components/search.js +610 -0
  96. data/lib/docyard/templates/assets/js/components/sidebar-toggle.js +29 -0
  97. data/lib/docyard/templates/assets/js/components/tab-navigation.js +145 -0
  98. data/lib/docyard/templates/assets/js/components/table-of-contents.js +153 -66
  99. data/lib/docyard/templates/assets/js/components/tabs.js +31 -69
  100. data/lib/docyard/templates/assets/js/theme.js +0 -3
  101. data/lib/docyard/templates/assets/logo-dark.svg +8 -2
  102. data/lib/docyard/templates/assets/logo.svg +7 -4
  103. data/lib/docyard/templates/config/docyard.yml.erb +37 -34
  104. data/lib/docyard/templates/errors/404.html.erb +1 -1
  105. data/lib/docyard/templates/errors/500.html.erb +1 -1
  106. data/lib/docyard/templates/layouts/default.html.erb +19 -56
  107. data/lib/docyard/templates/layouts/splash.html.erb +176 -0
  108. data/lib/docyard/templates/partials/_breadcrumbs.html.erb +24 -0
  109. data/lib/docyard/templates/partials/_code_block.html.erb +6 -4
  110. data/lib/docyard/templates/partials/_doc_footer.html.erb +25 -0
  111. data/lib/docyard/templates/partials/_features.html.erb +15 -0
  112. data/lib/docyard/templates/partials/_footer.html.erb +42 -0
  113. data/lib/docyard/templates/partials/_head.html.erb +22 -0
  114. data/lib/docyard/templates/partials/_header.html.erb +49 -0
  115. data/lib/docyard/templates/partials/_heading_anchor.html.erb +3 -1
  116. data/lib/docyard/templates/partials/_hero.html.erb +27 -0
  117. data/lib/docyard/templates/partials/_nav_group.html.erb +25 -11
  118. data/lib/docyard/templates/partials/_nav_leaf.html.erb +1 -1
  119. data/lib/docyard/templates/partials/_nav_menu.html.erb +42 -0
  120. data/lib/docyard/templates/partials/_nav_nested_section.html.erb +11 -0
  121. data/lib/docyard/templates/partials/_nav_section.html.erb +1 -1
  122. data/lib/docyard/templates/partials/_prev_next.html.erb +9 -3
  123. data/lib/docyard/templates/partials/_scripts.html.erb +7 -0
  124. data/lib/docyard/templates/partials/_search_modal.html.erb +41 -0
  125. data/lib/docyard/templates/partials/_search_trigger.html.erb +18 -0
  126. data/lib/docyard/templates/partials/_sidebar.html.erb +21 -4
  127. data/lib/docyard/templates/partials/_tab_bar.html.erb +25 -0
  128. data/lib/docyard/templates/partials/_table_of_contents.html.erb +12 -12
  129. data/lib/docyard/templates/partials/_table_of_contents_toggle.html.erb +1 -3
  130. data/lib/docyard/templates/partials/_tabs.html.erb +2 -2
  131. data/lib/docyard/templates/partials/_theme_toggle.html.erb +2 -11
  132. data/lib/docyard/utils/html_helpers.rb +14 -0
  133. data/lib/docyard/utils/path_resolver.rb +2 -1
  134. data/lib/docyard/utils/url_helpers.rb +20 -0
  135. data/lib/docyard/version.rb +1 -1
  136. data/lib/docyard.rb +22 -15
  137. metadata +89 -50
  138. data/lib/docyard/components/callout_processor.rb +0 -121
  139. data/lib/docyard/components/code_block_diff_preprocessor.rb +0 -104
  140. data/lib/docyard/components/code_block_feature_extractor.rb +0 -113
  141. data/lib/docyard/components/code_block_focus_preprocessor.rb +0 -77
  142. data/lib/docyard/components/code_block_icon_detector.rb +0 -40
  143. data/lib/docyard/components/code_block_line_wrapper.rb +0 -46
  144. data/lib/docyard/components/code_block_options_preprocessor.rb +0 -76
  145. data/lib/docyard/components/code_block_patterns.rb +0 -51
  146. data/lib/docyard/components/code_block_processor.rb +0 -176
  147. data/lib/docyard/components/code_detector.rb +0 -59
  148. data/lib/docyard/components/code_line_parser.rb +0 -80
  149. data/lib/docyard/components/code_snippet_import_preprocessor.rb +0 -125
  150. data/lib/docyard/components/heading_anchor_processor.rb +0 -34
  151. data/lib/docyard/components/icon_detector.rb +0 -57
  152. data/lib/docyard/components/icon_processor.rb +0 -51
  153. data/lib/docyard/components/table_of_contents_processor.rb +0 -64
  154. data/lib/docyard/components/table_wrapper_processor.rb +0 -18
  155. data/lib/docyard/components/tabs_parser.rb +0 -191
  156. data/lib/docyard/components/tabs_processor.rb +0 -44
  157. data/lib/docyard/components/tabs_range_finder.rb +0 -42
  158. data/lib/docyard/rack_application.rb +0 -172
  159. data/lib/docyard/renderer.rb +0 -120
  160. data/lib/docyard/routing/resolution_result.rb +0 -31
  161. data/lib/docyard/sidebar/config_parser.rb +0 -180
  162. data/lib/docyard/sidebar/item.rb +0 -58
  163. data/lib/docyard/sidebar/renderer.rb +0 -137
  164. data/lib/docyard/sidebar/tree_builder.rb +0 -59
  165. data/lib/docyard/sidebar_builder.rb +0 -102
  166. data/lib/docyard/templates/markdown/getting-started/installation.md.erb +0 -77
  167. data/lib/docyard/templates/markdown/guides/configuration.md.erb +0 -202
  168. data/lib/docyard/templates/markdown/guides/markdown-features.md.erb +0 -247
  169. data/lib/docyard/templates/markdown/index.md.erb +0 -82
  170. /data/lib/docyard/{sidebar → navigation/sidebar}/title_extractor.rb +0 -0
  171. /data/lib/docyard/{icons → rendering/icons}/LICENSE.phosphor +0 -0
  172. /data/lib/docyard/{icons → rendering/icons}/file_types.rb +0 -0
  173. /data/lib/docyard/{icons.rb → rendering/icons.rb} +0 -0
  174. /data/lib/docyard/{language_mapping.rb → rendering/language_mapping.rb} +0 -0
  175. /data/lib/docyard/{file_watcher.rb → server/file_watcher.rb} +0 -0
  176. /data/lib/docyard/{errors.rb → utils/errors.rb} +0 -0
  177. /data/lib/docyard/{logging.rb → utils/logging.rb} +0 -0
@@ -0,0 +1,561 @@
1
+ .search-trigger {
2
+ display: flex;
3
+ align-items: center;
4
+ gap: var(--spacing-2);
5
+ padding: var(--spacing-2) var(--spacing-3);
6
+ background-color: var(--search-trigger-bg);
7
+ border: 1px solid var(--search-trigger-border);
8
+ border-radius: var(--radius-4xl);
9
+ cursor: pointer;
10
+ color: var(--muted-foreground);
11
+ font-size: var(--text-sm);
12
+ transition: all var(--transition-fast);
13
+ min-width: 400px;
14
+ height: 2.25rem;
15
+ }
16
+
17
+ .search-trigger:hover {
18
+ background-color: var(--search-trigger-bg-hover);
19
+ border-color: var(--search-trigger-border-hover);
20
+ color: var(--foreground);
21
+ }
22
+
23
+ .search-trigger:focus-visible {
24
+ outline: none;
25
+ border-color: var(--ring);
26
+ box-shadow: 0 0 0 var(--ring-width) oklch(from var(--ring) l c h / 50%);
27
+ }
28
+
29
+ .search-trigger-icon {
30
+ display: flex;
31
+ flex-shrink: 0;
32
+ color: var(--muted-foreground);
33
+ }
34
+
35
+ .search-trigger-icon svg {
36
+ width: 1rem;
37
+ height: 1rem;
38
+ }
39
+
40
+ .search-trigger-text {
41
+ flex: 1;
42
+ text-align: left;
43
+ color: var(--muted-foreground);
44
+ font-size: var(--text-sm);
45
+ }
46
+
47
+ .search-trigger-shortcut {
48
+ display: flex;
49
+ align-items: center;
50
+ gap: 2px;
51
+ font-family: var(--font-mono);
52
+ font-size: 0.6875rem;
53
+ color: var(--muted-foreground);
54
+ background: none;
55
+ border: none;
56
+ padding: 0;
57
+ }
58
+
59
+ .search-trigger-shortcut-icon {
60
+ display: flex;
61
+ }
62
+
63
+ .search-trigger-shortcut-icon svg {
64
+ width: 0.875rem;
65
+ height: 0.875rem;
66
+ }
67
+
68
+ .search-trigger-shortcut-text {
69
+ opacity: 0.8;
70
+ }
71
+
72
+ .search-trigger-shortcut[data-os="windows"] .search-trigger-shortcut-icon {
73
+ display: none;
74
+ }
75
+
76
+ .search-trigger-shortcut[data-os="windows"] .search-trigger-shortcut-text::before {
77
+ content: "Ctrl ";
78
+ }
79
+
80
+ .header-actions {
81
+ display: flex;
82
+ align-items: center;
83
+ gap: var(--spacing-3);
84
+ }
85
+
86
+ .search-modal {
87
+ position: fixed;
88
+ inset: 0;
89
+ z-index: var(--z-modal);
90
+ display: flex;
91
+ align-items: flex-start;
92
+ justify-content: center;
93
+ padding-top: 10vh;
94
+ opacity: 0;
95
+ visibility: hidden;
96
+ transition: opacity var(--transition-fast), visibility var(--transition-fast);
97
+ }
98
+
99
+ .search-modal.is-open {
100
+ opacity: 1;
101
+ visibility: visible;
102
+ }
103
+
104
+ .search-modal[hidden] {
105
+ display: none;
106
+ }
107
+
108
+ .search-modal-backdrop {
109
+ position: fixed;
110
+ inset: 0;
111
+ background-color: var(--overlay-bg);
112
+ backdrop-filter: blur(var(--overlay-blur));
113
+ opacity: 0;
114
+ transition: opacity var(--transition-fast);
115
+ }
116
+
117
+ .search-modal.is-open .search-modal-backdrop {
118
+ opacity: 1;
119
+ }
120
+
121
+ .search-modal-container {
122
+ position: relative;
123
+ width: 100%;
124
+ max-width: 600px;
125
+ max-height: 80vh;
126
+ margin: 0 var(--spacing-4);
127
+ background-color: var(--background);
128
+ border: 1px solid var(--border);
129
+ border-radius: var(--radius-2xl);
130
+ box-shadow: var(--shadow-2xl);
131
+ display: flex;
132
+ flex-direction: column;
133
+ overflow: hidden;
134
+ transform: scale(0.95) translateY(-10px);
135
+ opacity: 0;
136
+ transition: transform var(--transition-base), opacity var(--transition-fast);
137
+ }
138
+
139
+ .search-modal.is-open .search-modal-container {
140
+ transform: scale(1) translateY(0);
141
+ opacity: 1;
142
+ }
143
+
144
+ .search-modal-header {
145
+ display: flex;
146
+ align-items: center;
147
+ gap: var(--spacing-3);
148
+ padding: var(--spacing-4) var(--spacing-5);
149
+ border-bottom: 1px solid var(--border);
150
+ }
151
+
152
+ .search-modal-icon {
153
+ display: flex;
154
+ align-items: center;
155
+ justify-content: center;
156
+ flex-shrink: 0;
157
+ width: 1.25rem;
158
+ height: 1.25rem;
159
+ color: var(--muted-foreground);
160
+ }
161
+
162
+ .search-modal-input {
163
+ flex: 1;
164
+ border: none;
165
+ background: transparent;
166
+ font-size: var(--text-base);
167
+ font-family: var(--font-sans);
168
+ color: var(--foreground);
169
+ outline: none;
170
+ }
171
+
172
+ .search-modal-input::placeholder {
173
+ color: var(--muted-foreground);
174
+ }
175
+
176
+ .search-modal-close {
177
+ display: flex;
178
+ align-items: center;
179
+ padding: 0;
180
+ background: none;
181
+ border: none;
182
+ cursor: pointer;
183
+ transition: opacity var(--transition-fast);
184
+ }
185
+
186
+ .search-modal-close:hover {
187
+ opacity: 0.7;
188
+ }
189
+
190
+ .search-modal-close-text {
191
+ font-family: var(--font-mono);
192
+ font-size: 0.625rem;
193
+ text-transform: uppercase;
194
+ letter-spacing: 0.05em;
195
+ color: var(--muted-foreground);
196
+ background-color: var(--muted);
197
+ border: 1px solid var(--border);
198
+ border-radius: var(--radius-sm);
199
+ padding: var(--spacing-1) var(--spacing-1-5);
200
+ }
201
+
202
+ .search-modal-body {
203
+ flex: 1;
204
+ max-height: 400px;
205
+ overflow-y: auto;
206
+ overscroll-behavior: contain;
207
+ padding: var(--spacing-2);
208
+ }
209
+
210
+ .search-modal-body[hidden] {
211
+ display: none;
212
+ }
213
+
214
+ .search-modal-loading {
215
+ display: flex;
216
+ align-items: center;
217
+ justify-content: center;
218
+ padding: var(--spacing-8) var(--spacing-4);
219
+ color: var(--muted-foreground);
220
+ font-size: var(--text-sm);
221
+ }
222
+
223
+ .search-modal-loading[hidden] {
224
+ display: none;
225
+ }
226
+
227
+ .search-modal-empty {
228
+ display: flex;
229
+ flex-direction: column;
230
+ align-items: center;
231
+ justify-content: center;
232
+ padding: var(--spacing-10) var(--spacing-4);
233
+ text-align: center;
234
+ gap: var(--spacing-2);
235
+ }
236
+
237
+ .search-modal-empty[hidden] {
238
+ display: none;
239
+ }
240
+
241
+ .search-empty-icon {
242
+ display: flex;
243
+ align-items: center;
244
+ justify-content: center;
245
+ color: var(--muted-foreground);
246
+ margin-bottom: var(--spacing-4);
247
+ opacity: 0.4;
248
+ }
249
+
250
+ .search-empty-icon .docyard-icon {
251
+ width: 4rem;
252
+ height: 4rem;
253
+ }
254
+
255
+ .search-empty-icon .docyard-icon svg {
256
+ width: 100%;
257
+ height: 100%;
258
+ }
259
+
260
+ .search-empty-title {
261
+ font-size: var(--text-sm);
262
+ font-weight: var(--font-medium);
263
+ color: var(--foreground);
264
+ }
265
+
266
+ .search-empty-hint {
267
+ font-size: var(--text-sm);
268
+ color: var(--muted-foreground);
269
+ }
270
+
271
+ .search-modal-spinner {
272
+ width: 1.25rem;
273
+ height: 1.25rem;
274
+ border: 2px solid var(--border);
275
+ border-top-color: var(--primary);
276
+ border-radius: 50%;
277
+ animation: search-spin 0.6s linear infinite;
278
+ }
279
+
280
+ @keyframes search-spin {
281
+ to {
282
+ transform: rotate(360deg);
283
+ }
284
+ }
285
+
286
+ .search-modal-results {
287
+ list-style: none;
288
+ padding: 0;
289
+ margin: 0;
290
+ }
291
+
292
+ .search-modal-results[hidden] {
293
+ display: none;
294
+ }
295
+
296
+ .search-result-group {
297
+ list-style: none;
298
+ }
299
+
300
+ .search-result-group+.search-result-group {
301
+ margin-top: var(--spacing-1);
302
+ }
303
+
304
+ .search-result {
305
+ display: flex;
306
+ align-items: flex-start;
307
+ gap: var(--spacing-3);
308
+ padding: var(--spacing-2) var(--spacing-3);
309
+ border-radius: var(--radius-lg);
310
+ cursor: pointer;
311
+ text-decoration: none;
312
+ color: var(--foreground);
313
+ transition: background-color var(--transition-fast);
314
+ }
315
+
316
+ .search-result:hover,
317
+ .search-result[aria-selected="true"] {
318
+ background-color: var(--accent);
319
+ text-decoration: none;
320
+ }
321
+
322
+ .search-result:hover .search-result-title,
323
+ .search-result[aria-selected="true"] .search-result-title {
324
+ color: var(--primary);
325
+ text-decoration: none;
326
+ }
327
+
328
+ .search-result-icon {
329
+ flex-shrink: 0;
330
+ width: 1rem;
331
+ height: 1rem;
332
+ margin-top: 2px;
333
+ color: var(--muted-foreground);
334
+ }
335
+
336
+ .search-result-content {
337
+ display: flex;
338
+ flex-direction: column;
339
+ gap: 2px;
340
+ min-width: 0;
341
+ flex: 1;
342
+ }
343
+
344
+ .search-result-title {
345
+ font-size: var(--text-sm);
346
+ font-weight: var(--font-medium);
347
+ color: var(--foreground);
348
+ white-space: nowrap;
349
+ overflow: hidden;
350
+ text-overflow: ellipsis;
351
+ text-decoration: none;
352
+ transition: color var(--transition-fast);
353
+ }
354
+
355
+ .search-result-excerpt {
356
+ font-size: var(--text-xs);
357
+ color: var(--muted-foreground);
358
+ white-space: nowrap;
359
+ overflow: hidden;
360
+ text-overflow: ellipsis;
361
+ line-height: 1.4;
362
+ }
363
+
364
+ .search-result-excerpt mark {
365
+ background-color: oklch(from var(--primary) l c h / 15%);
366
+ color: inherit;
367
+ font-weight: inherit;
368
+ border-radius: 2px;
369
+ padding: 0 1px;
370
+ }
371
+
372
+ .search-title-highlight {
373
+ background-color: oklch(from var(--primary) l c h / 15%);
374
+ color: inherit;
375
+ font-weight: inherit;
376
+ border-radius: 2px;
377
+ padding: 0 1px;
378
+ }
379
+
380
+ .search-result-page {
381
+ font-weight: var(--font-medium);
382
+ }
383
+
384
+ .search-result-sections {
385
+ list-style: none;
386
+ padding: 0;
387
+ margin: 0;
388
+ padding-left: var(--spacing-3);
389
+ }
390
+
391
+ .search-result-section-item {
392
+ position: relative;
393
+ }
394
+
395
+ .search-result-section {
396
+ padding-left: var(--spacing-5);
397
+ }
398
+
399
+ .search-result-section .search-result-title {
400
+ font-weight: var(--font-normal);
401
+ color: var(--muted-foreground);
402
+ }
403
+
404
+ .search-result-section:hover .search-result-title,
405
+ .search-result-section[aria-selected="true"] .search-result-title {
406
+ color: var(--primary);
407
+ }
408
+
409
+ .search-result-tree-line {
410
+ position: absolute;
411
+ left: var(--spacing-3);
412
+ top: 0;
413
+ bottom: 50%;
414
+ width: var(--spacing-3);
415
+ border-left: 1px solid var(--border);
416
+ border-bottom: 1px solid var(--border);
417
+ border-radius: 0 0 0 var(--radius-sm);
418
+ }
419
+
420
+ .search-result-section-item:last-child .search-result-tree-line {
421
+ bottom: 50%;
422
+ }
423
+
424
+ .search-result-section-item:not(:last-child)::before {
425
+ content: '';
426
+ position: absolute;
427
+ left: var(--spacing-3);
428
+ top: 50%;
429
+ bottom: -50%;
430
+ width: 1px;
431
+ background-color: var(--border);
432
+ }
433
+
434
+ .search-load-more {
435
+ list-style: none;
436
+ padding: var(--spacing-3);
437
+ }
438
+
439
+ .search-load-more-btn {
440
+ font-size: var(--text-sm);
441
+ font-weight: var(--font-medium);
442
+ color: var(--primary);
443
+ background: none;
444
+ border: none;
445
+ padding: 0;
446
+ cursor: pointer;
447
+ transition: opacity var(--transition-fast);
448
+ }
449
+
450
+ .search-load-more-btn:hover {
451
+ opacity: 0.8;
452
+ }
453
+
454
+ .search-load-more-btn:focus-visible {
455
+ outline: none;
456
+ box-shadow: 0 0 0 var(--ring-width) var(--ring);
457
+ border-radius: var(--radius-sm);
458
+ }
459
+
460
+ .search-modal-footer {
461
+ display: flex;
462
+ align-items: center;
463
+ gap: var(--spacing-4);
464
+ padding: var(--spacing-3) var(--spacing-5);
465
+ border-top: 1px solid var(--border);
466
+ background-color: var(--muted);
467
+ font-size: 0.6875rem;
468
+ color: var(--muted-foreground);
469
+ }
470
+
471
+ .search-modal-hint {
472
+ display: flex;
473
+ align-items: center;
474
+ gap: var(--spacing-1);
475
+ }
476
+
477
+ .search-modal-hint kbd {
478
+ display: inline-flex;
479
+ align-items: center;
480
+ justify-content: center;
481
+ min-width: 1.125rem;
482
+ height: 1.125rem;
483
+ padding: 0 var(--spacing-1);
484
+ font-family: var(--font-mono);
485
+ font-size: 0.625rem;
486
+ background-color: var(--background);
487
+ border: 1px solid var(--border);
488
+ border-radius: var(--radius-sm);
489
+ }
490
+
491
+ @media (max-width: 1024px) {
492
+
493
+
494
+ .search-trigger {
495
+ min-width: auto;
496
+ width: 2.25rem;
497
+ height: 2.25rem;
498
+ padding: 0;
499
+ background: transparent;
500
+ border-color: transparent;
501
+ justify-content: center;
502
+ }
503
+
504
+ .search-trigger:hover {
505
+ background-color: var(--muted);
506
+ border-color: transparent;
507
+ }
508
+
509
+ .dark .search-trigger:hover {
510
+ background-color: oklch(from var(--muted) l c h / 50%);
511
+ }
512
+
513
+ .search-trigger-text,
514
+ .search-trigger-shortcut {
515
+ display: none;
516
+ }
517
+
518
+ .search-trigger-icon .docyard-icon {
519
+ width: 1.25rem;
520
+ height: 1.25rem;
521
+ }
522
+
523
+ .header-center {
524
+ flex: 0;
525
+ padding: 0;
526
+ margin-left: auto;
527
+ }
528
+
529
+ .search-modal-header {
530
+ padding: var(--spacing-3) var(--spacing-4);
531
+ }
532
+
533
+ .search-modal-input {
534
+ font-size: var(--text-sm);
535
+ }
536
+
537
+ .search-modal-close {
538
+ display: none;
539
+ }
540
+
541
+ .search-modal-footer {
542
+ display: none;
543
+ }
544
+ }
545
+
546
+ @media (prefers-reduced-motion: reduce) {
547
+ .search-modal-spinner {
548
+ animation: none;
549
+ }
550
+
551
+ .search-modal,
552
+ .search-modal-backdrop,
553
+ .search-modal-container,
554
+ .search-trigger,
555
+ .search-result,
556
+ .search-modal-close,
557
+ .search-result-title,
558
+ .search-load-more-btn {
559
+ transition: none;
560
+ }
561
+ }
@@ -0,0 +1,163 @@
1
+ /* Tab Bar - Desktop navigation below header */
2
+
3
+ .tab-bar {
4
+ position: fixed;
5
+ top: var(--header-height);
6
+ left: 0;
7
+ right: 0;
8
+ height: var(--tab-bar-height);
9
+ background: var(--background);
10
+ z-index: var(--z-header);
11
+ display: none;
12
+ }
13
+
14
+ .has-tabs .tab-bar {
15
+ display: block;
16
+ }
17
+
18
+ /* Hide tab bar on landing/splash pages */
19
+ .splash-page .tab-bar {
20
+ display: none;
21
+ }
22
+
23
+ .tab-bar-content {
24
+ position: relative;
25
+ display: flex;
26
+ align-items: center;
27
+ height: 100%;
28
+ max-width: var(--layout-max-width);
29
+ margin: 0 auto;
30
+ padding: 0 var(--spacing-6);
31
+ gap: var(--spacing-2);
32
+ border-bottom: 1px solid var(--hr-color);
33
+ }
34
+
35
+ .tab-item {
36
+ position: relative;
37
+ display: flex;
38
+ align-items: center;
39
+ gap: 6px;
40
+ height: 100%;
41
+ padding: 0 var(--spacing-4);
42
+ font-size: var(--text-sm);
43
+ font-weight: var(--font-medium);
44
+ color: var(--muted-foreground);
45
+ text-decoration: none;
46
+ transition: color var(--transition-fast);
47
+ }
48
+
49
+ .tab-item:hover {
50
+ color: var(--foreground);
51
+ text-decoration: none;
52
+ }
53
+
54
+ .tab-item.is-active {
55
+ color: var(--foreground);
56
+ }
57
+
58
+ .tab-icon {
59
+ display: flex;
60
+ align-items: center;
61
+ flex-shrink: 0;
62
+ opacity: 0.7;
63
+ }
64
+
65
+ .tab-icon .docyard-icon {
66
+ width: 16px;
67
+ height: 16px;
68
+ }
69
+
70
+ .tab-item.is-active .tab-icon {
71
+ opacity: 1;
72
+ }
73
+
74
+ .tab-external-icon {
75
+ width: 14px;
76
+ height: 14px;
77
+ opacity: 0.5;
78
+ flex-shrink: 0;
79
+ }
80
+
81
+ /* Sliding indicator */
82
+ .tab-indicator {
83
+ position: absolute;
84
+ bottom: 0;
85
+ left: 0;
86
+ width: 0;
87
+ height: 2px;
88
+ background: var(--primary);
89
+ border-radius: 2px 2px 0 0;
90
+ pointer-events: none;
91
+ view-transition-name: tab-indicator;
92
+ }
93
+
94
+ .tab-indicator.is-ready {
95
+ transition: left 0.25s cubic-bezier(0.4, 0, 0.2, 1), width 0.25s cubic-bezier(0.4, 0, 0.2, 1);
96
+ }
97
+
98
+ /* View Transitions API - animate indicator between pages */
99
+ ::view-transition-group(tab-indicator) {
100
+ animation-duration: 0.25s;
101
+ animation-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
102
+ }
103
+
104
+ ::view-transition-old(tab-indicator),
105
+ ::view-transition-new(tab-indicator) {
106
+ animation: none;
107
+ mix-blend-mode: normal;
108
+ }
109
+
110
+ /* Faster page transition */
111
+ ::view-transition-old(root),
112
+ ::view-transition-new(root) {
113
+ animation-duration: 0.15s;
114
+ }
115
+
116
+ /* Layout adjustments when tabs are present */
117
+ .has-tabs .layout {
118
+ padding-top: calc(var(--header-height) + var(--tab-bar-height));
119
+ }
120
+
121
+ @media (max-width: 1280px) and (min-width: 1025px) {
122
+ .has-tabs .layout {
123
+ padding-top: calc(var(--header-height) + var(--tab-bar-height) + 3rem);
124
+ }
125
+ }
126
+
127
+ .has-tabs .sidebar {
128
+ top: calc(var(--header-height) + var(--tab-bar-height));
129
+ height: calc(100vh - var(--header-height) - var(--tab-bar-height));
130
+ }
131
+
132
+ .has-tabs .secondary-header {
133
+ top: calc(var(--header-height) + var(--tab-bar-height));
134
+ }
135
+
136
+ /* Hide tab bar on mobile */
137
+ @media (max-width: 1024px) {
138
+ .tab-bar {
139
+ display: none;
140
+ }
141
+
142
+ .has-tabs .layout {
143
+ padding-top: calc(var(--header-height) + 3rem);
144
+ }
145
+
146
+ .has-tabs .sidebar {
147
+ top: 0;
148
+ height: 100vh;
149
+ height: 100dvh;
150
+ }
151
+
152
+ .has-tabs .secondary-header {
153
+ top: var(--header-height);
154
+ }
155
+ }
156
+
157
+ /* Reduced motion preference */
158
+ @media (prefers-reduced-motion: reduce) {
159
+ .tab-item,
160
+ .tab-indicator {
161
+ transition: none;
162
+ }
163
+ }