docyard 0.7.0 → 0.9.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 (155) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +5 -1
  3. data/CHANGELOG.md +43 -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 +85 -12
  8. data/lib/docyard/builder.rb +6 -6
  9. data/lib/docyard/components/aliases.rb +12 -0
  10. data/lib/docyard/components/processors/abbreviation_processor.rb +72 -0
  11. data/lib/docyard/components/processors/accordion_processor.rb +81 -0
  12. data/lib/docyard/components/processors/badge_processor.rb +72 -0
  13. data/lib/docyard/components/processors/callout_processor.rb +8 -2
  14. data/lib/docyard/components/processors/cards_processor.rb +100 -0
  15. data/lib/docyard/components/processors/code_block_options_preprocessor.rb +23 -2
  16. data/lib/docyard/components/processors/code_block_processor.rb +6 -0
  17. data/lib/docyard/components/processors/code_group_processor.rb +198 -0
  18. data/lib/docyard/components/processors/code_snippet_import_preprocessor.rb +6 -1
  19. data/lib/docyard/components/processors/custom_anchor_processor.rb +42 -0
  20. data/lib/docyard/components/processors/file_tree_processor.rb +151 -0
  21. data/lib/docyard/components/processors/image_caption_processor.rb +96 -0
  22. data/lib/docyard/components/processors/include_processor.rb +86 -0
  23. data/lib/docyard/components/processors/steps_processor.rb +89 -0
  24. data/lib/docyard/components/processors/tabs_processor.rb +9 -1
  25. data/lib/docyard/components/processors/tooltip_processor.rb +57 -0
  26. data/lib/docyard/components/processors/video_embed_processor.rb +196 -0
  27. data/lib/docyard/components/support/code_group/html_builder.rb +122 -0
  28. data/lib/docyard/components/support/markdown_code_block_helper.rb +56 -0
  29. data/lib/docyard/config/branding_resolver.rb +121 -17
  30. data/lib/docyard/config/constants.rb +6 -4
  31. data/lib/docyard/config/logo_detector.rb +39 -0
  32. data/lib/docyard/config/validator.rb +122 -99
  33. data/lib/docyard/config.rb +40 -42
  34. data/lib/docyard/initializer.rb +15 -76
  35. data/lib/docyard/navigation/breadcrumb_builder.rb +133 -0
  36. data/lib/docyard/navigation/prev_next_builder.rb +4 -1
  37. data/lib/docyard/navigation/sidebar/children_discoverer.rb +51 -0
  38. data/lib/docyard/navigation/sidebar/config_parser.rb +136 -108
  39. data/lib/docyard/navigation/sidebar/file_resolver.rb +90 -0
  40. data/lib/docyard/navigation/sidebar/file_system_scanner.rb +2 -1
  41. data/lib/docyard/navigation/sidebar/item.rb +50 -7
  42. data/lib/docyard/navigation/sidebar/local_config_loader.rb +51 -0
  43. data/lib/docyard/navigation/sidebar/metadata_extractor.rb +71 -0
  44. data/lib/docyard/navigation/sidebar/metadata_reader.rb +51 -0
  45. data/lib/docyard/navigation/sidebar/path_prefixer.rb +34 -0
  46. data/lib/docyard/navigation/sidebar/renderer.rb +60 -38
  47. data/lib/docyard/navigation/sidebar/sorter.rb +21 -0
  48. data/lib/docyard/navigation/sidebar/tree_builder.rb +100 -26
  49. data/lib/docyard/navigation/sidebar/tree_filter.rb +55 -0
  50. data/lib/docyard/navigation/sidebar_builder.rb +105 -36
  51. data/lib/docyard/rendering/icon_helpers.rb +13 -0
  52. data/lib/docyard/rendering/icons/phosphor.rb +26 -1
  53. data/lib/docyard/rendering/markdown.rb +29 -1
  54. data/lib/docyard/rendering/renderer.rb +75 -34
  55. data/lib/docyard/rendering/template_resolver.rb +172 -0
  56. data/lib/docyard/routing/fallback_resolver.rb +92 -0
  57. data/lib/docyard/search/build_indexer.rb +1 -1
  58. data/lib/docyard/search/dev_indexer.rb +51 -6
  59. data/lib/docyard/search/pagefind_support.rb +2 -0
  60. data/lib/docyard/server/asset_handler.rb +25 -19
  61. data/lib/docyard/server/pagefind_handler.rb +63 -0
  62. data/lib/docyard/server/preview_server.rb +1 -1
  63. data/lib/docyard/server/rack_application.rb +81 -64
  64. data/lib/docyard/templates/assets/css/code.css +18 -51
  65. data/lib/docyard/templates/assets/css/components/abbreviation.css +86 -0
  66. data/lib/docyard/templates/assets/css/components/accordion.css +138 -0
  67. data/lib/docyard/templates/assets/css/components/badges.css +47 -0
  68. data/lib/docyard/templates/assets/css/components/banner.css +202 -0
  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/cards.css +100 -0
  72. data/lib/docyard/templates/assets/css/components/code-block.css +190 -282
  73. data/lib/docyard/templates/assets/css/components/code-group.css +281 -0
  74. data/lib/docyard/templates/assets/css/components/figure.css +22 -0
  75. data/lib/docyard/templates/assets/css/components/file-tree.css +124 -0
  76. data/lib/docyard/templates/assets/css/components/heading-anchor.css +36 -15
  77. data/lib/docyard/templates/assets/css/components/icon.css +0 -1
  78. data/lib/docyard/templates/assets/css/components/lightbox.css +65 -0
  79. data/lib/docyard/templates/assets/css/components/logo.css +0 -2
  80. data/lib/docyard/templates/assets/css/components/nav-menu.css +237 -0
  81. data/lib/docyard/templates/assets/css/components/navigation.css +193 -167
  82. data/lib/docyard/templates/assets/css/components/prev-next.css +68 -48
  83. data/lib/docyard/templates/assets/css/components/search.css +186 -174
  84. data/lib/docyard/templates/assets/css/components/steps.css +122 -0
  85. data/lib/docyard/templates/assets/css/components/tab-bar.css +163 -0
  86. data/lib/docyard/templates/assets/css/components/table-of-contents.css +127 -114
  87. data/lib/docyard/templates/assets/css/components/tabs.css +119 -160
  88. data/lib/docyard/templates/assets/css/components/theme-toggle.css +48 -44
  89. data/lib/docyard/templates/assets/css/components/tooltip.css +113 -0
  90. data/lib/docyard/templates/assets/css/components/video.css +41 -0
  91. data/lib/docyard/templates/assets/css/landing.css +815 -0
  92. data/lib/docyard/templates/assets/css/layout.css +489 -87
  93. data/lib/docyard/templates/assets/css/main.css +1 -3
  94. data/lib/docyard/templates/assets/css/markdown.css +113 -93
  95. data/lib/docyard/templates/assets/css/reset.css +0 -3
  96. data/lib/docyard/templates/assets/css/typography.css +43 -41
  97. data/lib/docyard/templates/assets/css/variables.css +268 -208
  98. data/lib/docyard/templates/assets/favicon.svg +7 -8
  99. data/lib/docyard/templates/assets/fonts/Inter-Variable.ttf +0 -0
  100. data/lib/docyard/templates/assets/js/components/abbreviation.js +85 -0
  101. data/lib/docyard/templates/assets/js/components/banner.js +81 -0
  102. data/lib/docyard/templates/assets/js/components/code-block.js +24 -42
  103. data/lib/docyard/templates/assets/js/components/code-group.js +283 -0
  104. data/lib/docyard/templates/assets/js/components/file-tree.js +39 -0
  105. data/lib/docyard/templates/assets/js/components/heading-anchor.js +26 -24
  106. data/lib/docyard/templates/assets/js/components/lightbox.js +72 -0
  107. data/lib/docyard/templates/assets/js/components/navigation.js +181 -70
  108. data/lib/docyard/templates/assets/js/components/search.js +0 -75
  109. data/lib/docyard/templates/assets/js/components/sidebar-toggle.js +29 -0
  110. data/lib/docyard/templates/assets/js/components/tab-navigation.js +145 -0
  111. data/lib/docyard/templates/assets/js/components/table-of-contents.js +153 -66
  112. data/lib/docyard/templates/assets/js/components/tabs.js +31 -69
  113. data/lib/docyard/templates/assets/js/components/tooltip.js +118 -0
  114. data/lib/docyard/templates/assets/js/theme.js +0 -3
  115. data/lib/docyard/templates/assets/logo-dark.svg +8 -2
  116. data/lib/docyard/templates/assets/logo.svg +7 -4
  117. data/lib/docyard/templates/config/docyard.yml.erb +37 -34
  118. data/lib/docyard/templates/errors/404.html.erb +1 -1
  119. data/lib/docyard/templates/errors/500.html.erb +1 -1
  120. data/lib/docyard/templates/layouts/default.html.erb +19 -67
  121. data/lib/docyard/templates/layouts/splash.html.erb +177 -0
  122. data/lib/docyard/templates/partials/_accordion.html.erb +9 -0
  123. data/lib/docyard/templates/partials/_banner.html.erb +27 -0
  124. data/lib/docyard/templates/partials/_breadcrumbs.html.erb +24 -0
  125. data/lib/docyard/templates/partials/_card.html.erb +23 -0
  126. data/lib/docyard/templates/partials/_code_block.html.erb +5 -3
  127. data/lib/docyard/templates/partials/_doc_footer.html.erb +25 -0
  128. data/lib/docyard/templates/partials/_features.html.erb +15 -0
  129. data/lib/docyard/templates/partials/_footer.html.erb +42 -0
  130. data/lib/docyard/templates/partials/_head.html.erb +22 -0
  131. data/lib/docyard/templates/partials/_header.html.erb +49 -0
  132. data/lib/docyard/templates/partials/_heading_anchor.html.erb +3 -1
  133. data/lib/docyard/templates/partials/_hero.html.erb +27 -0
  134. data/lib/docyard/templates/partials/_nav_group.html.erb +31 -11
  135. data/lib/docyard/templates/partials/_nav_leaf.html.erb +4 -1
  136. data/lib/docyard/templates/partials/_nav_menu.html.erb +42 -0
  137. data/lib/docyard/templates/partials/_nav_nested_section.html.erb +11 -0
  138. data/lib/docyard/templates/partials/_nav_section.html.erb +1 -1
  139. data/lib/docyard/templates/partials/_prev_next.html.erb +8 -2
  140. data/lib/docyard/templates/partials/_scripts.html.erb +7 -0
  141. data/lib/docyard/templates/partials/_search_modal.html.erb +2 -6
  142. data/lib/docyard/templates/partials/_search_trigger.html.erb +2 -6
  143. data/lib/docyard/templates/partials/_sidebar.html.erb +21 -4
  144. data/lib/docyard/templates/partials/_step.html.erb +14 -0
  145. data/lib/docyard/templates/partials/_tab_bar.html.erb +25 -0
  146. data/lib/docyard/templates/partials/_table_of_contents.html.erb +12 -12
  147. data/lib/docyard/templates/partials/_table_of_contents_toggle.html.erb +1 -3
  148. data/lib/docyard/templates/partials/_tabs.html.erb +2 -2
  149. data/lib/docyard/templates/partials/_theme_toggle.html.erb +2 -11
  150. data/lib/docyard/version.rb +1 -1
  151. metadata +70 -5
  152. data/lib/docyard/templates/markdown/getting-started/installation.md.erb +0 -77
  153. data/lib/docyard/templates/markdown/guides/configuration.md.erb +0 -202
  154. data/lib/docyard/templates/markdown/guides/markdown-features.md.erb +0 -247
  155. data/lib/docyard/templates/markdown/index.md.erb +0 -82
@@ -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
  }
@@ -27,7 +44,10 @@
27
44
  display: flex;
28
45
  align-items: center;
29
46
  height: 100%;
30
- 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);
31
51
  }
32
52
 
33
53
  .header-logo {
@@ -38,35 +58,36 @@
38
58
  flex: 1;
39
59
  display: flex;
40
60
  justify-content: center;
41
- padding: 0 var(--space-6);
61
+ padding: 0 var(--spacing-6);
42
62
  }
43
63
 
44
64
  .header-actions {
45
65
  flex-shrink: 0;
66
+ margin-left: auto;
46
67
  }
47
68
 
48
69
  .header-left {
49
70
  display: flex;
50
71
  align-items: center;
51
- gap: var(--space-4);
72
+ gap: var(--spacing-4);
52
73
  }
53
74
 
54
75
  .header-logo {
55
76
  display: flex;
56
77
  align-items: center;
57
78
  text-decoration: none;
58
- gap: var(--space-3);
79
+ gap: var(--spacing-3);
59
80
  }
60
81
 
61
82
  .header-title {
62
83
  font-size: 1.0625rem;
63
- font-weight: var(--font-weight-semibold);
64
- color: var(--color-text);
84
+ font-weight: var(--font-semibold);
85
+ color: var(--foreground);
65
86
  letter-spacing: -0.02em;
66
87
  }
67
88
 
68
89
  .header-logo:hover .header-title {
69
- color: var(--color-primary);
90
+ color: var(--primary);
70
91
  }
71
92
 
72
93
  .header-logo:hover {
@@ -74,17 +95,94 @@
74
95
  }
75
96
 
76
97
  .header-logo:focus-visible {
77
- outline: 2px solid var(--color-primary);
78
- outline-offset: 4px;
79
- 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%);
101
+ }
102
+
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;
80
126
  }
81
127
 
82
- /* Secondary Header (Tablet & Mobile Navigation Bar) */
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
+
83
182
  .secondary-header {
84
183
  display: none;
85
184
  }
86
185
 
87
- /* Tablet: Show secondary header with TOC toggle only */
88
186
  @media (max-width: 1280px) and (min-width: 1025px) {
89
187
  .secondary-header {
90
188
  display: flex;
@@ -92,13 +190,13 @@
92
190
  justify-content: flex-end;
93
191
  position: fixed;
94
192
  top: var(--header-height);
95
- left: var(--sidebar-width);
96
- 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));
97
195
  height: 3rem;
98
196
  min-height: 3rem;
99
- background: var(--color-bg);
100
- border-bottom: 1px solid var(--color-border);
101
- padding: 0 var(--space-6);
197
+ background: var(--background);
198
+ border-bottom: 1px solid var(--border);
199
+ padding: 0 var(--spacing-6);
102
200
  z-index: var(--z-secondary-header);
103
201
  transition: top 0.3s cubic-bezier(0.4, 0, 0.2, 1), left 0.3s cubic-bezier(0.4, 0, 0.2, 1);
104
202
  box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.02);
@@ -117,7 +215,6 @@
117
215
  }
118
216
  }
119
217
 
120
- /* Mobile: Show menu button + TOC toggle */
121
218
  @media (max-width: 1024px) {
122
219
  .secondary-header {
123
220
  display: flex;
@@ -129,9 +226,9 @@
129
226
  right: 0;
130
227
  height: 3rem;
131
228
  min-height: 3rem;
132
- background: var(--color-bg);
133
- border-bottom: 1px solid var(--color-border);
134
- padding: 0 var(--space-6);
229
+ background: var(--background);
230
+ border-bottom: 1px solid var(--border);
231
+ padding: 0 var(--spacing-6);
135
232
  z-index: var(--z-secondary-header);
136
233
  transition: top 0.3s cubic-bezier(0.4, 0, 0.2, 1);
137
234
  box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.02);
@@ -144,33 +241,33 @@
144
241
  .secondary-header-menu {
145
242
  display: flex;
146
243
  align-items: center;
147
- gap: var(--space-2);
244
+ gap: var(--spacing-2);
148
245
  background: none;
149
246
  border: none;
150
- padding: var(--space-2);
151
- font-size: var(--font-size-sm);
152
- font-weight: var(--font-weight-medium);
153
- 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);
154
251
  cursor: pointer;
155
252
  border-radius: var(--radius-md);
156
253
  transition: background-color 0.2s ease;
157
254
  font-family: var(--font-sans);
158
- margin-left: calc(-1 * var(--space-2));
255
+ margin-left: calc(-1 * var(--spacing-2));
159
256
  outline: none;
160
257
  }
161
258
 
162
259
  .secondary-header-menu:hover {
163
- background-color: var(--color-bg-tertiary);
260
+ background-color: var(--muted);
164
261
  }
165
262
 
166
263
  .secondary-header-menu:active {
167
- background-color: var(--color-border);
264
+ background-color: var(--muted);
168
265
  }
169
266
 
170
267
  .secondary-header-menu:focus-visible {
171
- outline: 2px solid var(--color-primary);
172
- outline-offset: 2px;
173
- 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%);
174
271
  }
175
272
 
176
273
  .secondary-header-menu .icon {
@@ -178,57 +275,77 @@
178
275
  }
179
276
  }
180
277
 
181
- /* Main layout container */
182
278
  .layout {
183
279
  display: flex;
184
280
  min-height: calc(100vh - var(--header-height));
185
281
  padding-top: var(--header-height);
186
282
  width: 100%;
187
- max-width: 100vw;
188
- overflow-x: hidden;
283
+ max-width: var(--layout-max-width);
284
+ margin: 0 auto;
285
+ position: relative;
189
286
  }
190
287
 
191
- /* Sidebar */
192
288
  .sidebar {
193
289
  width: var(--sidebar-width);
194
290
  height: calc(100vh - var(--header-height));
195
291
  position: fixed;
196
292
  top: var(--header-height);
197
- left: 0;
198
- background-color: var(--color-sidebar-bg);
199
- border-right: 1px solid var(--color-border);
200
- overflow-y: auto;
201
- overflow-x: hidden;
202
- overflow-anchor: none;
293
+ left: max(0px, calc((100vw - var(--layout-max-width)) / 2));
294
+ background-color: var(--sidebar);
203
295
  z-index: var(--z-sidebar);
204
296
  display: flex;
205
297
  flex-direction: column;
206
298
  }
207
299
 
208
- .sidebar > nav {
209
- 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;
210
305
  overscroll-behavior: contain;
306
+ position: relative;
211
307
  }
212
308
 
213
- /* Sidebar scrollbar styling */
214
- .sidebar::-webkit-scrollbar {
215
- width: 0.5rem;
309
+ .sidebar-scroll>nav {
310
+ padding: var(--spacing-4) var(--spacing-4);
216
311
  }
217
312
 
218
- .sidebar::-webkit-scrollbar-track {
219
- 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;
324
+ }
325
+
326
+ .sidebar::before {
327
+ top: 0;
328
+ background: linear-gradient(to bottom, var(--sidebar) 0%, transparent 100%);
329
+ }
330
+
331
+ .sidebar::after {
332
+ bottom: 0;
333
+ background: linear-gradient(to top, var(--sidebar) 0%, transparent 100%);
220
334
  }
221
335
 
222
- .sidebar::-webkit-scrollbar-thumb {
223
- background: rgba(208, 215, 222, 0.5);
224
- border-radius: 0.25rem;
336
+ .sidebar.can-scroll-top::before {
337
+ opacity: 1;
225
338
  }
226
339
 
227
- .sidebar::-webkit-scrollbar-thumb:hover {
228
- background: rgba(208, 215, 222, 0.7);
340
+ .sidebar.can-scroll-bottom::after {
341
+ opacity: 1;
342
+ }
343
+
344
+ .sidebar-scroll {
345
+ scrollbar-width: thin;
346
+ scrollbar-color: var(--border) transparent;
229
347
  }
230
348
 
231
- /* Main content area */
232
349
  .layout-main {
233
350
  flex: 1;
234
351
  margin-left: var(--sidebar-width);
@@ -236,30 +353,71 @@
236
353
  display: flex;
237
354
  flex-direction: column;
238
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
+ }
239
387
  }
240
388
 
241
- /* Tablet Layout (1024px - 1280px) */
242
389
  @media (max-width: 1280px) and (min-width: 1025px) {
243
390
  .layout-main {
244
391
  margin-right: 0;
245
392
  }
246
393
  }
247
394
 
248
- /* Content wrapper */
249
395
  main.content {
250
396
  flex: 1;
251
397
  max-width: var(--content-max-width);
252
398
  width: 100%;
253
- padding: var(--space-16) var(--space-10);
399
+ padding: var(--spacing-8) var(--spacing-10) var(--spacing-16);
254
400
  margin: 0 auto;
255
401
  min-width: 0;
256
402
  box-sizing: border-box;
257
403
  }
258
404
 
259
- /* Mobile Layout */
260
405
  @media (max-width: 1024px) {
261
406
  .header-content {
262
- 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;
263
421
  }
264
422
 
265
423
  .layout {
@@ -271,16 +429,17 @@ main.content {
271
429
  position: fixed;
272
430
  top: 0;
273
431
  left: 0;
274
- bottom: 0;
275
- right: auto;
276
432
  width: 20rem;
277
433
  max-width: 85vw;
278
434
  height: 100vh;
435
+ height: 100dvh;
279
436
  transform: translateX(-100%);
280
437
  transition: transform 0.25s cubic-bezier(0.4, 0, 0.2, 1);
281
438
  z-index: var(--z-sidebar);
282
- background-color: var(--color-sidebar-bg);
439
+ background-color: var(--sidebar);
283
440
  box-shadow: none;
441
+ padding-top: env(safe-area-inset-top, 0);
442
+ padding-bottom: env(safe-area-inset-bottom, 0);
284
443
  }
285
444
 
286
445
  .sidebar.is-open {
@@ -299,11 +458,10 @@ main.content {
299
458
  }
300
459
 
301
460
  main.content {
302
- padding: var(--space-6);
461
+ padding: var(--spacing-6);
303
462
  }
304
463
  }
305
464
 
306
- /* Mobile menu overlay */
307
465
  @media (max-width: 1024px) {
308
466
  .mobile-overlay {
309
467
  position: fixed;
@@ -311,7 +469,8 @@ main.content {
311
469
  left: 0;
312
470
  right: 0;
313
471
  bottom: 0;
314
- background-color: rgba(0, 0, 0, 0.5);
472
+ background-color: var(--overlay-bg);
473
+ backdrop-filter: blur(var(--overlay-blur));
315
474
  z-index: var(--z-overlay);
316
475
  opacity: 0;
317
476
  pointer-events: none;
@@ -324,31 +483,274 @@ main.content {
324
483
  }
325
484
  }
326
485
 
327
- /* Skip to main content link (accessibility) */
328
486
  .skip-link {
329
- position: absolute;
330
- top: -40px;
331
- left: 0;
332
- background: var(--color-primary);
333
- color: white;
334
- 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);
335
495
  text-decoration: none;
336
- 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);
337
501
  }
338
502
 
339
503
  .skip-link:focus {
340
- top: 0;
504
+ transform: translate(-50%, 0);
505
+ outline: none;
341
506
  }
342
507
 
343
- /* Container utilities */
344
508
  .container {
345
509
  max-width: var(--layout-max-width);
346
510
  margin: 0 auto;
347
- padding: 0 var(--space-6);
511
+ padding: 0 var(--spacing-6);
348
512
  }
349
513
 
350
514
  .container-narrow {
351
515
  max-width: var(--content-max-width);
352
516
  margin: 0 auto;
353
- 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
+ }
354
756
  }