docyard 0.7.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 (112) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +5 -1
  3. data/CHANGELOG.md +20 -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/config/branding_resolver.rb +126 -17
  10. data/lib/docyard/config/constants.rb +6 -4
  11. data/lib/docyard/config/validator.rb +122 -99
  12. data/lib/docyard/config.rb +36 -43
  13. data/lib/docyard/initializer.rb +15 -76
  14. data/lib/docyard/navigation/breadcrumb_builder.rb +133 -0
  15. data/lib/docyard/navigation/prev_next_builder.rb +4 -1
  16. data/lib/docyard/navigation/sidebar/children_discoverer.rb +51 -0
  17. data/lib/docyard/navigation/sidebar/config_parser.rb +136 -108
  18. data/lib/docyard/navigation/sidebar/file_resolver.rb +78 -0
  19. data/lib/docyard/navigation/sidebar/file_system_scanner.rb +2 -1
  20. data/lib/docyard/navigation/sidebar/item.rb +45 -7
  21. data/lib/docyard/navigation/sidebar/local_config_loader.rb +51 -0
  22. data/lib/docyard/navigation/sidebar/metadata_extractor.rb +69 -0
  23. data/lib/docyard/navigation/sidebar/metadata_reader.rb +47 -0
  24. data/lib/docyard/navigation/sidebar/path_prefixer.rb +34 -0
  25. data/lib/docyard/navigation/sidebar/renderer.rb +55 -37
  26. data/lib/docyard/navigation/sidebar/sorter.rb +21 -0
  27. data/lib/docyard/navigation/sidebar/tree_builder.rb +99 -26
  28. data/lib/docyard/navigation/sidebar/tree_filter.rb +55 -0
  29. data/lib/docyard/navigation/sidebar_builder.rb +105 -36
  30. data/lib/docyard/rendering/icon_helpers.rb +13 -0
  31. data/lib/docyard/rendering/icons/phosphor.rb +23 -1
  32. data/lib/docyard/rendering/markdown.rb +5 -0
  33. data/lib/docyard/rendering/renderer.rb +74 -34
  34. data/lib/docyard/rendering/template_resolver.rb +172 -0
  35. data/lib/docyard/routing/fallback_resolver.rb +92 -0
  36. data/lib/docyard/search/build_indexer.rb +1 -1
  37. data/lib/docyard/search/dev_indexer.rb +51 -6
  38. data/lib/docyard/search/pagefind_support.rb +2 -0
  39. data/lib/docyard/server/asset_handler.rb +24 -19
  40. data/lib/docyard/server/pagefind_handler.rb +63 -0
  41. data/lib/docyard/server/preview_server.rb +1 -1
  42. data/lib/docyard/server/rack_application.rb +81 -64
  43. data/lib/docyard/templates/assets/css/code.css +18 -51
  44. data/lib/docyard/templates/assets/css/components/breadcrumbs.css +143 -0
  45. data/lib/docyard/templates/assets/css/components/callout.css +67 -67
  46. data/lib/docyard/templates/assets/css/components/code-block.css +180 -282
  47. data/lib/docyard/templates/assets/css/components/heading-anchor.css +28 -15
  48. data/lib/docyard/templates/assets/css/components/icon.css +0 -1
  49. data/lib/docyard/templates/assets/css/components/logo.css +0 -2
  50. data/lib/docyard/templates/assets/css/components/nav-menu.css +237 -0
  51. data/lib/docyard/templates/assets/css/components/navigation.css +186 -167
  52. data/lib/docyard/templates/assets/css/components/prev-next.css +76 -47
  53. data/lib/docyard/templates/assets/css/components/search.css +186 -174
  54. data/lib/docyard/templates/assets/css/components/tab-bar.css +163 -0
  55. data/lib/docyard/templates/assets/css/components/table-of-contents.css +127 -114
  56. data/lib/docyard/templates/assets/css/components/tabs.css +119 -160
  57. data/lib/docyard/templates/assets/css/components/theme-toggle.css +48 -44
  58. data/lib/docyard/templates/assets/css/landing.css +815 -0
  59. data/lib/docyard/templates/assets/css/layout.css +489 -87
  60. data/lib/docyard/templates/assets/css/main.css +1 -3
  61. data/lib/docyard/templates/assets/css/markdown.css +111 -93
  62. data/lib/docyard/templates/assets/css/reset.css +0 -3
  63. data/lib/docyard/templates/assets/css/typography.css +43 -41
  64. data/lib/docyard/templates/assets/css/variables.css +268 -208
  65. data/lib/docyard/templates/assets/favicon.svg +7 -8
  66. data/lib/docyard/templates/assets/fonts/Inter-Variable.ttf +0 -0
  67. data/lib/docyard/templates/assets/js/components/code-block.js +24 -42
  68. data/lib/docyard/templates/assets/js/components/heading-anchor.js +26 -24
  69. data/lib/docyard/templates/assets/js/components/navigation.js +181 -70
  70. data/lib/docyard/templates/assets/js/components/search.js +0 -75
  71. data/lib/docyard/templates/assets/js/components/sidebar-toggle.js +29 -0
  72. data/lib/docyard/templates/assets/js/components/tab-navigation.js +145 -0
  73. data/lib/docyard/templates/assets/js/components/table-of-contents.js +153 -66
  74. data/lib/docyard/templates/assets/js/components/tabs.js +31 -69
  75. data/lib/docyard/templates/assets/js/theme.js +0 -3
  76. data/lib/docyard/templates/assets/logo-dark.svg +8 -2
  77. data/lib/docyard/templates/assets/logo.svg +7 -4
  78. data/lib/docyard/templates/config/docyard.yml.erb +37 -34
  79. data/lib/docyard/templates/errors/404.html.erb +1 -1
  80. data/lib/docyard/templates/errors/500.html.erb +1 -1
  81. data/lib/docyard/templates/layouts/default.html.erb +18 -67
  82. data/lib/docyard/templates/layouts/splash.html.erb +176 -0
  83. data/lib/docyard/templates/partials/_breadcrumbs.html.erb +24 -0
  84. data/lib/docyard/templates/partials/_code_block.html.erb +5 -3
  85. data/lib/docyard/templates/partials/_doc_footer.html.erb +25 -0
  86. data/lib/docyard/templates/partials/_features.html.erb +15 -0
  87. data/lib/docyard/templates/partials/_footer.html.erb +42 -0
  88. data/lib/docyard/templates/partials/_head.html.erb +22 -0
  89. data/lib/docyard/templates/partials/_header.html.erb +49 -0
  90. data/lib/docyard/templates/partials/_heading_anchor.html.erb +3 -1
  91. data/lib/docyard/templates/partials/_hero.html.erb +27 -0
  92. data/lib/docyard/templates/partials/_nav_group.html.erb +25 -11
  93. data/lib/docyard/templates/partials/_nav_leaf.html.erb +1 -1
  94. data/lib/docyard/templates/partials/_nav_menu.html.erb +42 -0
  95. data/lib/docyard/templates/partials/_nav_nested_section.html.erb +11 -0
  96. data/lib/docyard/templates/partials/_nav_section.html.erb +1 -1
  97. data/lib/docyard/templates/partials/_prev_next.html.erb +8 -2
  98. data/lib/docyard/templates/partials/_scripts.html.erb +7 -0
  99. data/lib/docyard/templates/partials/_search_modal.html.erb +2 -6
  100. data/lib/docyard/templates/partials/_search_trigger.html.erb +2 -6
  101. data/lib/docyard/templates/partials/_sidebar.html.erb +21 -4
  102. data/lib/docyard/templates/partials/_tab_bar.html.erb +25 -0
  103. data/lib/docyard/templates/partials/_table_of_contents.html.erb +12 -12
  104. data/lib/docyard/templates/partials/_table_of_contents_toggle.html.erb +1 -3
  105. data/lib/docyard/templates/partials/_tabs.html.erb +2 -2
  106. data/lib/docyard/templates/partials/_theme_toggle.html.erb +2 -11
  107. data/lib/docyard/version.rb +1 -1
  108. metadata +33 -5
  109. data/lib/docyard/templates/markdown/getting-started/installation.md.erb +0 -77
  110. data/lib/docyard/templates/markdown/guides/configuration.md.erb +0 -202
  111. data/lib/docyard/templates/markdown/guides/markdown-features.md.erb +0 -247
  112. 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
  }