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
@@ -1,24 +1,41 @@
1
- /* Page Layout */
1
+ html {
2
+ scroll-padding-top: calc(var(--header-height) + var(--spacing-6));
3
+ }
4
+
5
+ html:has(.has-tabs) {
6
+ scroll-padding-top: calc(var(--header-height) + var(--tab-bar-height) + var(--spacing-6));
7
+ }
8
+
9
+ @media (max-width: 1280px) and (min-width: 1025px) {
10
+ html {
11
+ scroll-padding-top: calc(var(--header-height) + var(--tab-bar-height) + var(--spacing-6));
12
+ }
13
+ }
14
+
15
+ @media (max-width: 1024px) {
16
+ html {
17
+ scroll-padding-top: calc(var(--header-height) + var(--tab-bar-height) + var(--spacing-6));
18
+ }
19
+ }
20
+
21
+ .page-wrapper {
22
+ max-width: var(--layout-max-width);
23
+ margin: 0 auto;
24
+ position: relative;
25
+ }
2
26
 
3
- /* Header */
4
27
  .header {
5
28
  position: fixed;
6
29
  top: 0;
7
30
  left: 0;
8
31
  right: 0;
9
32
  height: var(--header-height);
10
- background-color: var(--color-bg);
33
+ background-color: oklch(from var(--background) l c h / 80%);
11
34
  backdrop-filter: blur(12px);
12
- border-bottom: 1px solid var(--color-border);
13
- box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.02);
14
35
  z-index: var(--z-header);
15
36
  transition: transform 0.3s cubic-bezier(0.4, 0, 0.2, 1);
16
37
  }
17
38
 
18
- .dark .header {
19
- box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.3);
20
- }
21
-
22
39
  .header.hide-on-scroll {
23
40
  transform: translateY(-100%);
24
41
  }
@@ -26,33 +43,51 @@
26
43
  .header-content {
27
44
  display: flex;
28
45
  align-items: center;
29
- justify-content: space-between;
30
46
  height: 100%;
31
- padding: var(--space-5) var(--space-6);
47
+ max-width: var(--layout-max-width);
48
+ margin: 0 auto;
49
+ padding: var(--spacing-5) var(--spacing-6);
50
+ border-bottom: 1px solid var(--hr-color);
51
+ }
52
+
53
+ .header-logo {
54
+ flex-shrink: 0;
55
+ }
56
+
57
+ .header-center {
58
+ flex: 1;
59
+ display: flex;
60
+ justify-content: center;
61
+ padding: 0 var(--spacing-6);
62
+ }
63
+
64
+ .header-actions {
65
+ flex-shrink: 0;
66
+ margin-left: auto;
32
67
  }
33
68
 
34
69
  .header-left {
35
70
  display: flex;
36
71
  align-items: center;
37
- gap: var(--space-4);
72
+ gap: var(--spacing-4);
38
73
  }
39
74
 
40
75
  .header-logo {
41
76
  display: flex;
42
77
  align-items: center;
43
78
  text-decoration: none;
44
- gap: var(--space-3);
79
+ gap: var(--spacing-3);
45
80
  }
46
81
 
47
82
  .header-title {
48
83
  font-size: 1.0625rem;
49
- font-weight: var(--font-weight-semibold);
50
- color: var(--color-text);
84
+ font-weight: var(--font-semibold);
85
+ color: var(--foreground);
51
86
  letter-spacing: -0.02em;
52
87
  }
53
88
 
54
89
  .header-logo:hover .header-title {
55
- color: var(--color-primary);
90
+ color: var(--primary);
56
91
  }
57
92
 
58
93
  .header-logo:hover {
@@ -60,17 +95,94 @@
60
95
  }
61
96
 
62
97
  .header-logo:focus-visible {
63
- outline: 2px solid var(--color-primary);
64
- outline-offset: 4px;
65
- border-radius: var(--radius-sm);
98
+ outline: none;
99
+ border-radius: var(--radius-lg);
100
+ box-shadow: 0 0 0 var(--ring-width) oklch(from var(--ring) l c h / 50%);
66
101
  }
67
102
 
68
- /* Secondary Header (Tablet & Mobile Navigation Bar) */
103
+ .header-ctas {
104
+ display: flex;
105
+ align-items: center;
106
+ gap: var(--spacing-3);
107
+ }
108
+
109
+ .header-cta {
110
+ display: inline-flex;
111
+ align-items: center;
112
+ gap: var(--spacing-1-5);
113
+ padding: 6px 12px;
114
+ font-size: var(--text-sm);
115
+ font-weight: var(--font-medium);
116
+ text-decoration: none;
117
+ border-radius: var(--radius-md);
118
+ cursor: pointer;
119
+ transition: background-color 0.2s ease, border-color 0.2s ease;
120
+ white-space: nowrap;
121
+ border: 1px solid transparent;
122
+ }
123
+
124
+ .header-cta:hover {
125
+ text-decoration: none;
126
+ }
127
+
128
+ .header-cta--primary {
129
+ background-color: var(--primary);
130
+ color: var(--primary-foreground);
131
+ border-color: var(--primary);
132
+ }
133
+
134
+ .header-cta--primary:hover {
135
+ background-color: oklch(from var(--primary) calc(l - 0.05) c h);
136
+ border-color: oklch(from var(--primary) calc(l - 0.05) c h);
137
+ color: var(--primary-foreground);
138
+ }
139
+
140
+ .header-cta--primary:active {
141
+ background-color: oklch(from var(--primary) calc(l - 0.08) c h);
142
+ border-color: oklch(from var(--primary) calc(l - 0.08) c h);
143
+ }
144
+
145
+ .header-cta--secondary {
146
+ background: transparent;
147
+ color: var(--foreground);
148
+ border-color: var(--border);
149
+ }
150
+
151
+ .header-cta--secondary:hover {
152
+ background: var(--muted);
153
+ color: var(--foreground);
154
+ }
155
+
156
+ .header-cta--secondary:active {
157
+ opacity: 0.8;
158
+ }
159
+
160
+ .header-cta-arrow {
161
+ width: 16px;
162
+ height: 16px;
163
+ stroke-width: 2;
164
+ transition: transform 0.3s cubic-bezier(0.34, 1.56, 0.64, 1);
165
+ }
166
+
167
+ .header-cta--primary:hover .header-cta-arrow {
168
+ transform: translateX(3px);
169
+ }
170
+
171
+ @media (max-width: 1024px) {
172
+ .header-ctas {
173
+ display: none;
174
+ }
175
+ }
176
+
177
+ .sidebar-ctas {
178
+ display: none;
179
+ }
180
+
181
+
69
182
  .secondary-header {
70
183
  display: none;
71
184
  }
72
185
 
73
- /* Tablet: Show secondary header with TOC toggle only */
74
186
  @media (max-width: 1280px) and (min-width: 1025px) {
75
187
  .secondary-header {
76
188
  display: flex;
@@ -78,13 +190,13 @@
78
190
  justify-content: flex-end;
79
191
  position: fixed;
80
192
  top: var(--header-height);
81
- left: var(--sidebar-width);
82
- right: 0;
193
+ left: calc(max(0px, (100vw - var(--layout-max-width)) / 2) + var(--sidebar-width));
194
+ right: max(0px, calc((100vw - var(--layout-max-width)) / 2));
83
195
  height: 3rem;
84
196
  min-height: 3rem;
85
- background: var(--color-bg);
86
- border-bottom: 1px solid var(--color-border);
87
- padding: 0 var(--space-6);
197
+ background: var(--background);
198
+ border-bottom: 1px solid var(--border);
199
+ padding: 0 var(--spacing-6);
88
200
  z-index: var(--z-secondary-header);
89
201
  transition: top 0.3s cubic-bezier(0.4, 0, 0.2, 1), left 0.3s cubic-bezier(0.4, 0, 0.2, 1);
90
202
  box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.02);
@@ -103,7 +215,6 @@
103
215
  }
104
216
  }
105
217
 
106
- /* Mobile: Show menu button + TOC toggle */
107
218
  @media (max-width: 1024px) {
108
219
  .secondary-header {
109
220
  display: flex;
@@ -115,9 +226,9 @@
115
226
  right: 0;
116
227
  height: 3rem;
117
228
  min-height: 3rem;
118
- background: var(--color-bg);
119
- border-bottom: 1px solid var(--color-border);
120
- padding: 0 var(--space-6);
229
+ background: var(--background);
230
+ border-bottom: 1px solid var(--border);
231
+ padding: 0 var(--spacing-6);
121
232
  z-index: var(--z-secondary-header);
122
233
  transition: top 0.3s cubic-bezier(0.4, 0, 0.2, 1);
123
234
  box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.02);
@@ -130,33 +241,33 @@
130
241
  .secondary-header-menu {
131
242
  display: flex;
132
243
  align-items: center;
133
- gap: var(--space-2);
244
+ gap: var(--spacing-2);
134
245
  background: none;
135
246
  border: none;
136
- padding: var(--space-2);
137
- font-size: var(--font-size-sm);
138
- font-weight: var(--font-weight-medium);
139
- color: var(--color-text);
247
+ padding: var(--spacing-2);
248
+ font-size: var(--text-sm);
249
+ font-weight: var(--font-medium);
250
+ color: var(--foreground);
140
251
  cursor: pointer;
141
252
  border-radius: var(--radius-md);
142
253
  transition: background-color 0.2s ease;
143
254
  font-family: var(--font-sans);
144
- margin-left: calc(-1 * var(--space-2));
255
+ margin-left: calc(-1 * var(--spacing-2));
145
256
  outline: none;
146
257
  }
147
258
 
148
259
  .secondary-header-menu:hover {
149
- background-color: var(--color-bg-tertiary);
260
+ background-color: var(--muted);
150
261
  }
151
262
 
152
263
  .secondary-header-menu:active {
153
- background-color: var(--color-border);
264
+ background-color: var(--muted);
154
265
  }
155
266
 
156
267
  .secondary-header-menu:focus-visible {
157
- outline: 2px solid var(--color-primary);
158
- outline-offset: 2px;
159
- border-radius: var(--radius-sm);
268
+ outline: none;
269
+ border-radius: var(--radius-lg);
270
+ box-shadow: 0 0 0 var(--ring-width) oklch(from var(--ring) l c h / 50%);
160
271
  }
161
272
 
162
273
  .secondary-header-menu .icon {
@@ -164,57 +275,77 @@
164
275
  }
165
276
  }
166
277
 
167
- /* Main layout container */
168
278
  .layout {
169
279
  display: flex;
170
280
  min-height: calc(100vh - var(--header-height));
171
281
  padding-top: var(--header-height);
172
282
  width: 100%;
173
- max-width: 100vw;
174
- overflow-x: hidden;
283
+ max-width: var(--layout-max-width);
284
+ margin: 0 auto;
285
+ position: relative;
175
286
  }
176
287
 
177
- /* Sidebar */
178
288
  .sidebar {
179
289
  width: var(--sidebar-width);
180
290
  height: calc(100vh - var(--header-height));
181
291
  position: fixed;
182
292
  top: var(--header-height);
183
- left: 0;
184
- background-color: var(--color-sidebar-bg);
185
- border-right: 1px solid var(--color-border);
186
- overflow-y: auto;
187
- overflow-x: hidden;
188
- overflow-anchor: none;
293
+ left: max(0px, calc((100vw - var(--layout-max-width)) / 2));
294
+ background-color: var(--sidebar);
189
295
  z-index: var(--z-sidebar);
190
296
  display: flex;
191
297
  flex-direction: column;
192
298
  }
193
299
 
194
- .sidebar > nav {
195
- padding: var(--space-5) var(--space-5);
300
+ .sidebar-scroll {
301
+ flex: 1;
302
+ overflow-y: auto;
303
+ overflow-x: hidden;
304
+ overflow-anchor: none;
196
305
  overscroll-behavior: contain;
306
+ position: relative;
197
307
  }
198
308
 
199
- /* Sidebar scrollbar styling */
200
- .sidebar::-webkit-scrollbar {
201
- width: 0.5rem;
309
+ .sidebar-scroll>nav {
310
+ padding: var(--spacing-4) var(--spacing-4);
202
311
  }
203
312
 
204
- .sidebar::-webkit-scrollbar-track {
205
- background: transparent;
313
+ .sidebar::before,
314
+ .sidebar::after {
315
+ content: '';
316
+ position: absolute;
317
+ left: 0;
318
+ right: 0;
319
+ height: 2rem;
320
+ pointer-events: none;
321
+ z-index: 1;
322
+ opacity: 0;
323
+ transition: opacity 0.2s ease;
206
324
  }
207
325
 
208
- .sidebar::-webkit-scrollbar-thumb {
209
- background: rgba(208, 215, 222, 0.5);
210
- border-radius: 0.25rem;
326
+ .sidebar::before {
327
+ top: 0;
328
+ background: linear-gradient(to bottom, var(--sidebar) 0%, transparent 100%);
211
329
  }
212
330
 
213
- .sidebar::-webkit-scrollbar-thumb:hover {
214
- background: rgba(208, 215, 222, 0.7);
331
+ .sidebar::after {
332
+ bottom: 0;
333
+ background: linear-gradient(to top, var(--sidebar) 0%, transparent 100%);
334
+ }
335
+
336
+ .sidebar.can-scroll-top::before {
337
+ opacity: 1;
338
+ }
339
+
340
+ .sidebar.can-scroll-bottom::after {
341
+ opacity: 1;
342
+ }
343
+
344
+ .sidebar-scroll {
345
+ scrollbar-width: thin;
346
+ scrollbar-color: var(--border) transparent;
215
347
  }
216
348
 
217
- /* Main content area */
218
349
  .layout-main {
219
350
  flex: 1;
220
351
  margin-left: var(--sidebar-width);
@@ -222,30 +353,71 @@
222
353
  display: flex;
223
354
  flex-direction: column;
224
355
  min-width: 0;
356
+ transition: margin-left 0.3s cubic-bezier(0.4, 0, 0.2, 1);
357
+ }
358
+
359
+ @media (min-width: 1025px) {
360
+ .sidebar-collapsed .sidebar {
361
+ transform: translateX(-100%);
362
+ opacity: 0;
363
+ pointer-events: none;
364
+ }
365
+
366
+ .sidebar-collapsed .layout-main {
367
+ margin-left: 0;
368
+ }
369
+
370
+ .sidebar-collapsed main.content {
371
+ max-width: 100%;
372
+ }
373
+
374
+ .sidebar-collapsed .secondary-header {
375
+ left: max(0px, calc((100vw - var(--layout-max-width)) / 2));
376
+ }
377
+
378
+ .sidebar {
379
+ transition:
380
+ transform 0.3s cubic-bezier(0.4, 0, 0.2, 1),
381
+ opacity 0.3s cubic-bezier(0.4, 0, 0.2, 1);
382
+ }
383
+
384
+ main.content {
385
+ transition: margin 0.3s cubic-bezier(0.4, 0, 0.2, 1);
386
+ }
225
387
  }
226
388
 
227
- /* Tablet Layout (1024px - 1280px) */
228
389
  @media (max-width: 1280px) and (min-width: 1025px) {
229
390
  .layout-main {
230
391
  margin-right: 0;
231
392
  }
232
393
  }
233
394
 
234
- /* Content wrapper */
235
395
  main.content {
236
396
  flex: 1;
237
397
  max-width: var(--content-max-width);
238
398
  width: 100%;
239
- padding: var(--space-16) var(--space-10);
399
+ padding: var(--spacing-8) var(--spacing-10) var(--spacing-16);
240
400
  margin: 0 auto;
241
401
  min-width: 0;
242
402
  box-sizing: border-box;
243
403
  }
244
404
 
245
- /* Mobile Layout */
246
405
  @media (max-width: 1024px) {
247
406
  .header-content {
248
- padding: var(--space-4) var(--space-6);
407
+ padding: var(--spacing-4) var(--spacing-6);
408
+ }
409
+
410
+ .header-center {
411
+ flex: 0;
412
+ padding: 0;
413
+ margin-left: auto;
414
+ }
415
+
416
+ .header-actions {
417
+ display: flex;
418
+ align-items: center;
419
+ gap: var(--spacing-1);
420
+ margin-left: 0;
249
421
  }
250
422
 
251
423
  .layout {
@@ -257,16 +429,17 @@ main.content {
257
429
  position: fixed;
258
430
  top: 0;
259
431
  left: 0;
260
- bottom: 0;
261
- right: auto;
262
432
  width: 20rem;
263
433
  max-width: 85vw;
264
434
  height: 100vh;
435
+ height: 100dvh;
265
436
  transform: translateX(-100%);
266
437
  transition: transform 0.25s cubic-bezier(0.4, 0, 0.2, 1);
267
438
  z-index: var(--z-sidebar);
268
- background-color: var(--color-sidebar-bg);
439
+ background-color: var(--sidebar);
269
440
  box-shadow: none;
441
+ padding-top: env(safe-area-inset-top, 0);
442
+ padding-bottom: env(safe-area-inset-bottom, 0);
270
443
  }
271
444
 
272
445
  .sidebar.is-open {
@@ -285,11 +458,10 @@ main.content {
285
458
  }
286
459
 
287
460
  main.content {
288
- padding: var(--space-6);
461
+ padding: var(--spacing-6);
289
462
  }
290
463
  }
291
464
 
292
- /* Mobile menu overlay */
293
465
  @media (max-width: 1024px) {
294
466
  .mobile-overlay {
295
467
  position: fixed;
@@ -297,7 +469,8 @@ main.content {
297
469
  left: 0;
298
470
  right: 0;
299
471
  bottom: 0;
300
- background-color: rgba(0, 0, 0, 0.5);
472
+ background-color: var(--overlay-bg);
473
+ backdrop-filter: blur(var(--overlay-blur));
301
474
  z-index: var(--z-overlay);
302
475
  opacity: 0;
303
476
  pointer-events: none;
@@ -310,31 +483,274 @@ main.content {
310
483
  }
311
484
  }
312
485
 
313
- /* Skip to main content link (accessibility) */
314
486
  .skip-link {
315
- position: absolute;
316
- top: -40px;
317
- left: 0;
318
- background: var(--color-primary);
319
- color: white;
320
- padding: var(--space-2) var(--space-4);
487
+ position: fixed;
488
+ left: 50%;
489
+ top: var(--spacing-3);
490
+ background: var(--foreground);
491
+ color: var(--background);
492
+ font-size: var(--text-sm);
493
+ font-weight: var(--font-medium);
494
+ padding: var(--spacing-2) var(--spacing-4);
321
495
  text-decoration: none;
322
- z-index: 100;
496
+ z-index: 9999;
497
+ border-radius: var(--radius-4xl);
498
+ box-shadow: var(--shadow-xl);
499
+ transform: translate(-50%, -200%);
500
+ transition: transform var(--transition-base);
323
501
  }
324
502
 
325
503
  .skip-link:focus {
326
- top: 0;
504
+ transform: translate(-50%, 0);
505
+ outline: none;
327
506
  }
328
507
 
329
- /* Container utilities */
330
508
  .container {
331
509
  max-width: var(--layout-max-width);
332
510
  margin: 0 auto;
333
- padding: 0 var(--space-6);
511
+ padding: 0 var(--spacing-6);
334
512
  }
335
513
 
336
514
  .container-narrow {
337
515
  max-width: var(--content-max-width);
338
516
  margin: 0 auto;
339
- padding: 0 var(--space-6);
517
+ padding: 0 var(--spacing-6);
518
+ }
519
+
520
+ .footer-content {
521
+ max-width: var(--layout-max-width);
522
+ margin: 0 auto;
523
+ padding: var(--spacing-5) var(--spacing-6);
524
+ display: flex;
525
+ align-items: center;
526
+ justify-content: space-between;
527
+ gap: 1.5rem;
528
+ font-size: var(--text-sm);
529
+ }
530
+
531
+ .footer-content--centered {
532
+ justify-content: center;
533
+ }
534
+
535
+ .footer-content--no-attribution .footer-links {
536
+ margin-right: auto;
537
+ }
538
+
539
+ .footer-attribution {
540
+ color: var(--muted-foreground);
541
+ transition: color 0.15s ease;
542
+ }
543
+
544
+ .footer-attribution:hover {
545
+ color: var(--foreground);
546
+ }
547
+
548
+ .footer-links {
549
+ display: flex;
550
+ align-items: center;
551
+ gap: 1.5rem;
552
+ }
553
+
554
+ .footer-links a {
555
+ color: var(--muted-foreground);
556
+ transition: color 0.15s ease;
557
+ }
558
+
559
+ .footer-links a:hover {
560
+ color: var(--foreground);
561
+ }
562
+
563
+ .footer-socials {
564
+ display: flex;
565
+ align-items: center;
566
+ gap: 0;
567
+ }
568
+
569
+ .footer-socials a {
570
+ color: var(--muted-foreground);
571
+ display: flex;
572
+ align-items: center;
573
+ justify-content: center;
574
+ width: 2.25rem;
575
+ height: 2.25rem;
576
+ border-radius: var(--radius-4xl);
577
+ background: transparent;
578
+ transition: background-color var(--transition-fast), color var(--transition-fast);
579
+ }
580
+
581
+ .footer-socials a:hover {
582
+ color: var(--foreground);
583
+ background-color: var(--muted);
584
+ }
585
+
586
+ .dark .footer-socials a:hover {
587
+ background-color: oklch(from var(--muted) l c h / 50%);
588
+ }
589
+
590
+ .footer-socials svg {
591
+ width: 18px;
592
+ height: 18px;
593
+ }
594
+
595
+ @media (max-width: 1024px) {
596
+ .footer-content {
597
+ flex-direction: column;
598
+ gap: 1rem;
599
+ padding: 1.5rem var(--spacing-6);
600
+ }
601
+
602
+ .footer-links {
603
+ order: 1;
604
+ flex-wrap: wrap;
605
+ justify-content: center;
606
+ gap: 1rem;
607
+ }
608
+
609
+ .footer-socials {
610
+ order: 2;
611
+ }
612
+
613
+ .footer-attribution {
614
+ order: 3;
615
+ }
616
+
617
+ .footer-content--no-attribution .footer-links {
618
+ margin-right: 0;
619
+ }
620
+ }
621
+
622
+ .doc-aside {
623
+ width: var(--toc-width);
624
+ position: fixed;
625
+ top: var(--header-height);
626
+ right: max(0px, calc((100vw - var(--layout-max-width)) / 2));
627
+ height: calc(100vh - var(--header-height));
628
+ display: flex;
629
+ flex-direction: column;
630
+ background-color: var(--background);
631
+ }
632
+
633
+ .doc-footer-desktop {
634
+ flex-shrink: 0;
635
+ padding: 0 var(--spacing-4) var(--spacing-6);
636
+ }
637
+
638
+ .doc-aside.has-overflow .doc-footer-desktop {
639
+ margin-top: auto;
640
+ }
641
+
642
+ .doc-footer-desktop .site-footer {
643
+ margin-top: var(--spacing-6);
644
+ padding-top: var(--spacing-4);
645
+ border-top: 1px solid var(--border);
646
+ }
647
+
648
+ .doc-footer-mobile {
649
+ display: none;
650
+ }
651
+
652
+ .site-footer__socials {
653
+ display: flex;
654
+ align-items: center;
655
+ gap: 0;
656
+ margin-bottom: var(--spacing-3);
657
+ }
658
+
659
+ .site-footer__socials a {
660
+ display: flex;
661
+ align-items: center;
662
+ justify-content: center;
663
+ width: 2.25rem;
664
+ height: 2.25rem;
665
+ color: var(--muted-foreground);
666
+ border-radius: var(--radius-4xl);
667
+ background: transparent;
668
+ transition: background-color var(--transition-fast), color var(--transition-fast);
669
+ }
670
+
671
+ .site-footer__socials a:hover {
672
+ color: var(--foreground);
673
+ background-color: var(--muted);
674
+ }
675
+
676
+ .dark .site-footer__socials a:hover {
677
+ background-color: oklch(from var(--muted) l c h / 50%);
678
+ }
679
+
680
+ .site-footer__socials svg {
681
+ width: 18px;
682
+ height: 18px;
683
+ }
684
+
685
+ .site-footer__credits {
686
+ font-size: var(--text-xs);
687
+ color: var(--muted-foreground);
688
+ line-height: 1.5;
689
+ }
690
+
691
+ .site-footer__attribution {
692
+ display: block;
693
+ color: var(--muted-foreground);
694
+ text-decoration: none;
695
+ transition: color var(--transition-fast);
696
+ }
697
+
698
+ .site-footer__attribution:hover {
699
+ color: var(--foreground);
700
+ }
701
+
702
+ .site-footer__copyright {
703
+ display: flex;
704
+ align-items: center;
705
+ gap: var(--spacing-1);
706
+ margin-top: var(--spacing-1);
707
+ color: oklch(from var(--muted-foreground) l c h / 70%);
708
+ }
709
+
710
+ .site-footer__copyright svg {
711
+ width: 14px;
712
+ height: 14px;
713
+ flex-shrink: 0;
714
+ }
715
+
716
+ @media (max-width: 1280px) and (min-width: 1025px) {
717
+ .doc-aside {
718
+ display: none;
719
+ }
720
+
721
+ .doc-footer-mobile {
722
+ display: block;
723
+ margin-top: var(--spacing-12);
724
+ text-align: center;
725
+ }
726
+
727
+ .doc-footer-mobile .site-footer__socials {
728
+ justify-content: center;
729
+ margin-bottom: var(--spacing-4);
730
+ }
731
+
732
+ .doc-footer-mobile .site-footer__copyright {
733
+ justify-content: center;
734
+ }
735
+ }
736
+
737
+ @media (max-width: 1024px) {
738
+ .doc-aside {
739
+ display: none;
740
+ }
741
+
742
+ .doc-footer-mobile {
743
+ display: block;
744
+ margin-top: var(--spacing-12);
745
+ text-align: center;
746
+ }
747
+
748
+ .doc-footer-mobile .site-footer__socials {
749
+ justify-content: center;
750
+ margin-bottom: var(--spacing-4);
751
+ }
752
+
753
+ .doc-footer-mobile .site-footer__copyright {
754
+ justify-content: center;
755
+ }
340
756
  }