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
@@ -4,25 +4,23 @@ require "json"
4
4
  require "rack"
5
5
  require_relative "../navigation/sidebar_builder"
6
6
  require_relative "../navigation/prev_next_builder"
7
+ require_relative "../navigation/breadcrumb_builder"
7
8
  require_relative "../config/branding_resolver"
8
9
  require_relative "../config/constants"
10
+ require_relative "../rendering/template_resolver"
11
+ require_relative "../routing/fallback_resolver"
12
+ require_relative "pagefind_handler"
9
13
 
10
14
  module Docyard
11
15
  class RackApplication
12
- PAGEFIND_CONTENT_TYPES = {
13
- ".js" => "application/javascript; charset=utf-8",
14
- ".css" => "text/css; charset=utf-8",
15
- ".json" => "application/json; charset=utf-8"
16
- }.freeze
17
-
18
16
  def initialize(docs_path:, file_watcher:, config: nil, pagefind_path: nil)
19
17
  @docs_path = docs_path
20
18
  @file_watcher = file_watcher
21
19
  @config = config
22
- @pagefind_path = pagefind_path
23
20
  @router = Router.new(docs_path: docs_path)
24
- @renderer = Renderer.new(base_url: config&.build&.base_url || "/", config: config)
21
+ @renderer = Renderer.new(base_url: config&.build&.base || "/", config: config)
25
22
  @asset_handler = AssetHandler.new
23
+ @pagefind_handler = PagefindHandler.new(pagefind_path: pagefind_path, config: config)
26
24
  end
27
25
 
28
26
  def call(env)
@@ -31,14 +29,17 @@ module Docyard
31
29
 
32
30
  private
33
31
 
34
- attr_reader :docs_path, :file_watcher, :config, :pagefind_path, :router, :renderer, :asset_handler
32
+ attr_reader :docs_path, :file_watcher, :config, :router, :renderer, :asset_handler, :pagefind_handler
35
33
 
36
34
  def handle_request(env)
37
35
  path = env["PATH_INFO"]
38
36
 
39
37
  return handle_reload_check(env) if path == Constants::RELOAD_ENDPOINT
40
- return asset_handler.serve(path) if path.start_with?(Constants::ASSETS_PREFIX)
41
- return serve_pagefind(path) if path.start_with?(Constants::PAGEFIND_PREFIX)
38
+ return asset_handler.serve_docyard_assets(path) if path.start_with?(Constants::DOCYARD_ASSETS_PREFIX)
39
+ return pagefind_handler.serve(path) if path.start_with?(Constants::PAGEFIND_PREFIX)
40
+
41
+ public_response = asset_handler.serve_public_file(path)
42
+ return public_response if public_response
42
43
 
43
44
  handle_documentation_request(path)
44
45
  rescue StandardError => e
@@ -46,45 +47,90 @@ module Docyard
46
47
  end
47
48
 
48
49
  def handle_documentation_request(path)
50
+ if root_path?(path)
51
+ html_response = serve_custom_landing_page
52
+ return html_response if html_response
53
+ end
54
+
49
55
  result = router.resolve(path)
50
56
 
51
57
  if result.found?
52
58
  render_documentation_page(result.file_path, path)
59
+ else
60
+ try_fallback_redirect(path)
61
+ end
62
+ end
63
+
64
+ def root_path?(path)
65
+ path == "/" || path.empty?
66
+ end
67
+
68
+ def serve_custom_landing_page
69
+ html_path = File.join(docs_path, "index.html")
70
+ return nil unless File.file?(html_path)
71
+
72
+ html = File.read(html_path)
73
+ [Constants::STATUS_OK, { "Content-Type" => Constants::CONTENT_TYPE_HTML }, [html]]
74
+ end
75
+
76
+ def try_fallback_redirect(path)
77
+ sidebar_builder = build_sidebar_instance(path)
78
+ fallback_resolver = Routing::FallbackResolver.new(
79
+ docs_path: docs_path,
80
+ sidebar_builder: sidebar_builder
81
+ )
82
+
83
+ fallback_path = fallback_resolver.resolve_fallback(path)
84
+ if fallback_path
85
+ redirect_to(fallback_path)
53
86
  else
54
87
  render_not_found_page
55
88
  end
56
89
  end
57
90
 
91
+ def redirect_to(path)
92
+ [Constants::STATUS_REDIRECT, { "Location" => path }, []]
93
+ end
94
+
58
95
  def render_documentation_page(file_path, current_path)
59
- sidebar_builder = build_sidebar_instance(current_path)
96
+ markdown = Markdown.new(File.read(file_path))
97
+ template_resolver = TemplateResolver.new(markdown.frontmatter, @config&.data)
98
+ branding = branding_options
60
99
 
61
- html = renderer.render_file(
62
- file_path,
63
- sidebar_html: sidebar_builder.to_html,
64
- prev_next_html: build_prev_next(sidebar_builder, current_path, file_path),
65
- branding: branding_options
66
- )
100
+ navigation = build_navigation_html(template_resolver, current_path, markdown, branding[:header_ctas])
101
+ html = renderer.render_file(file_path, **navigation, branding: branding,
102
+ template_options: template_resolver.to_options,
103
+ current_path: current_path)
67
104
 
68
105
  [Constants::STATUS_OK, { "Content-Type" => Constants::CONTENT_TYPE_HTML }, [html]]
69
106
  end
70
107
 
108
+ def build_navigation_html(template_resolver, current_path, markdown, header_ctas)
109
+ return { sidebar_html: "", prev_next_html: "", breadcrumbs: nil } unless template_resolver.show_sidebar?
110
+
111
+ sidebar_builder = build_sidebar_instance(current_path, header_ctas)
112
+ {
113
+ sidebar_html: sidebar_builder.to_html,
114
+ prev_next_html: build_prev_next(sidebar_builder, current_path, markdown),
115
+ breadcrumbs: build_breadcrumbs(sidebar_builder.tree, current_path)
116
+ }
117
+ end
118
+
71
119
  def render_not_found_page
72
120
  html = renderer.render_not_found
73
121
  [Constants::STATUS_NOT_FOUND, { "Content-Type" => Constants::CONTENT_TYPE_HTML }, [html]]
74
122
  end
75
123
 
76
- def build_sidebar_instance(current_path)
124
+ def build_sidebar_instance(current_path, header_ctas = [])
77
125
  SidebarBuilder.new(
78
126
  docs_path: docs_path,
79
127
  current_path: current_path,
80
- config: config
128
+ config: config,
129
+ header_ctas: header_ctas
81
130
  )
82
131
  end
83
132
 
84
- def build_prev_next(sidebar_builder, current_path, file_path)
85
- markdown_content = File.read(file_path)
86
- markdown = Markdown.new(markdown_content)
87
-
133
+ def build_prev_next(sidebar_builder, current_path, markdown)
88
134
  PrevNextBuilder.new(
89
135
  sidebar_tree: sidebar_builder.tree,
90
136
  current_path: current_path,
@@ -93,10 +139,18 @@ module Docyard
93
139
  ).to_html
94
140
  end
95
141
 
96
- def navigation_config
97
- return {} unless config
142
+ def build_breadcrumbs(sidebar_tree, current_path)
143
+ return nil unless breadcrumbs_enabled?
144
+
145
+ BreadcrumbBuilder.new(sidebar_tree: sidebar_tree, current_path: current_path)
146
+ end
98
147
 
99
- config.navigation&.footer || {}
148
+ def breadcrumbs_enabled?
149
+ config&.navigation&.breadcrumbs != false
150
+ end
151
+
152
+ def navigation_config
153
+ {}
100
154
  end
101
155
 
102
156
  def branding_options
@@ -134,42 +188,5 @@ module Docyard
134
188
  [Constants::STATUS_INTERNAL_ERROR, { "Content-Type" => Constants::CONTENT_TYPE_HTML },
135
189
  [renderer.render_server_error(error)]]
136
190
  end
137
-
138
- def serve_pagefind(path)
139
- relative_path = path.delete_prefix(Constants::PAGEFIND_PREFIX)
140
- return pagefind_not_found if relative_path.include?("..")
141
-
142
- file_path = resolve_pagefind_file(relative_path)
143
- return pagefind_not_found unless file_path && File.file?(file_path)
144
-
145
- content = File.binread(file_path)
146
- content_type = pagefind_content_type(file_path)
147
-
148
- headers = {
149
- "Content-Type" => content_type,
150
- "Cache-Control" => "no-cache, no-store, must-revalidate",
151
- "Pragma" => "no-cache",
152
- "Expires" => "0"
153
- }
154
-
155
- [Constants::STATUS_OK, headers, [content]]
156
- end
157
-
158
- def resolve_pagefind_file(relative_path)
159
- return File.join(pagefind_path, relative_path) if pagefind_path && Dir.exist?(pagefind_path)
160
-
161
- output_dir = config&.build&.output_dir || "dist"
162
- File.join(output_dir, "pagefind", relative_path)
163
- end
164
-
165
- def pagefind_content_type(file_path)
166
- extension = File.extname(file_path)
167
- PAGEFIND_CONTENT_TYPES.fetch(extension, "application/octet-stream")
168
- end
169
-
170
- def pagefind_not_found
171
- message = "Pagefind not found. Run 'docyard build' first."
172
- [Constants::STATUS_NOT_FOUND, { "Content-Type" => "text/plain" }, [message]]
173
- end
174
191
  end
175
192
  end
@@ -1,32 +1,27 @@
1
- /* Code Block Styles */
2
-
3
- /* Code blocks */
4
1
  .content pre {
5
- margin: var(--space-6) 0;
6
- border-radius: var(--radius-lg);
2
+ margin: var(--spacing-6) 0;
3
+ border-radius: var(--radius-2xl);
7
4
  overflow-x: auto;
8
- border: 1px solid var(--color-border);
9
- box-shadow: 0 1px 2px 0 rgb(0 0 0 / 0.03);
5
+ overscroll-behavior-x: contain;
10
6
  }
11
7
 
12
8
  .content pre code {
13
9
  display: block;
14
- padding: var(--space-4);
10
+ padding: var(--spacing-4);
15
11
  font-family: var(--font-mono);
16
- font-size: var(--font-size-sm);
17
- line-height: var(--line-height-relaxed);
18
- background-color: var(--color-code-bg);
19
- color: var(--color-code-text);
12
+ font-size: var(--text-sm);
13
+ line-height: var(--leading-relaxed);
14
+ background-color: oklch(from var(--input) l c h / 30%);
15
+ color: var(--code-foreground);
20
16
  overflow-x: auto;
17
+ overscroll-behavior-x: contain;
21
18
  }
22
19
 
23
- /* Syntax highlighting - GitHub style */
24
20
  .highlight {
25
- margin: var(--space-6) 0;
26
- background-color: var(--color-code-bg);
27
- border-radius: var(--radius-lg);
28
- border: 1px solid var(--color-border);
29
- box-shadow: 0 1px 2px 0 rgb(0 0 0 / 0.03);
21
+ margin: var(--spacing-6) 0;
22
+ background-color: oklch(from var(--input) l c h / 30%);
23
+ border-radius: var(--radius-2xl);
24
+ border: 1px solid var(--input);
30
25
  }
31
26
 
32
27
  .highlight pre {
@@ -44,7 +39,7 @@
44
39
 
45
40
  .highlight {
46
41
  color: #24292f;
47
- background-color: #f6f8fa;
42
+ background-color: oklch(from var(--input) l c h / 30%);
48
43
  }
49
44
 
50
45
  .highlight .w {
@@ -52,7 +47,6 @@
52
47
  background-color: transparent;
53
48
  }
54
49
 
55
- /* Keywords */
56
50
  .highlight .k,
57
51
  .highlight .kd,
58
52
  .highlight .kn,
@@ -72,7 +66,6 @@
72
66
  background-color: #ffebe9;
73
67
  }
74
68
 
75
- /* Built-in names */
76
69
  .highlight .nb,
77
70
  .highlight .nc,
78
71
  .highlight .no,
@@ -80,7 +73,6 @@
80
73
  color: #953800;
81
74
  }
82
75
 
83
- /* Strings and regex */
84
76
  .highlight .sr,
85
77
  .highlight .na,
86
78
  .highlight .nt {
@@ -97,7 +89,6 @@
97
89
  font-style: italic;
98
90
  }
99
91
 
100
- /* Constants and literals */
101
92
  .highlight .kc,
102
93
  .highlight .l,
103
94
  .highlight .ld,
@@ -117,7 +108,6 @@
117
108
  color: #0550ae;
118
109
  }
119
110
 
120
- /* Variables */
121
111
  .highlight .nv,
122
112
  .highlight .vc,
123
113
  .highlight .vg,
@@ -126,20 +116,17 @@
126
116
  color: #0550ae;
127
117
  }
128
118
 
129
- /* Operators */
130
119
  .highlight .o,
131
120
  .highlight .ow {
132
121
  color: #0550ae;
133
122
  }
134
123
 
135
- /* Headers and subheaders in diffs */
136
124
  .highlight .gh,
137
125
  .highlight .gu {
138
126
  color: #0550ae;
139
127
  font-weight: bold;
140
128
  }
141
129
 
142
- /* Strings */
143
130
  .highlight .s,
144
131
  .highlight .sa,
145
132
  .highlight .sc,
@@ -154,20 +141,17 @@
154
141
  color: #0a3069;
155
142
  }
156
143
 
157
- /* Decorators and functions */
158
144
  .highlight .nd,
159
145
  .highlight .nf,
160
146
  .highlight .fm {
161
147
  color: #8250df;
162
148
  }
163
149
 
164
- /* Errors */
165
150
  .highlight .err {
166
151
  color: #f6f8fa;
167
152
  background-color: #82071e;
168
153
  }
169
154
 
170
- /* Comments */
171
155
  .highlight .c,
172
156
  .highlight .ch,
173
157
  .highlight .cd,
@@ -181,13 +165,11 @@
181
165
  color: #6e7781;
182
166
  }
183
167
 
184
- /* Name indicators */
185
168
  .highlight .ni,
186
169
  .highlight .si {
187
170
  color: #24292f;
188
171
  }
189
172
 
190
- /* Generic emphasis */
191
173
  .highlight .ge {
192
174
  color: #24292f;
193
175
  font-style: italic;
@@ -198,29 +180,27 @@
198
180
  font-weight: bold;
199
181
  }
200
182
 
201
- /* Code block scrollbar */
202
183
  .content pre::-webkit-scrollbar {
203
184
  height: 0.5rem;
204
185
  }
205
186
 
206
187
  .content pre::-webkit-scrollbar-track {
207
- background: var(--color-bg-secondary);
188
+ background: var(--secondary);
208
189
  border-radius: var(--radius-md);
209
190
  }
210
191
 
211
192
  .content pre::-webkit-scrollbar-thumb {
212
- background: var(--color-border);
193
+ background: var(--border);
213
194
  border-radius: var(--radius-md);
214
195
  }
215
196
 
216
197
  .content pre::-webkit-scrollbar-thumb:hover {
217
- background: var(--color-text-tertiary);
198
+ background: var(--muted-foreground);
218
199
  }
219
200
 
220
- /* Dark Mode Syntax Highlighting - GitHub Dark */
221
201
  .dark .highlight {
222
202
  color: #e6edf3;
223
- background-color: #161b22;
203
+ background-color: oklch(from var(--input) l c h / 30%);
224
204
  }
225
205
 
226
206
  .dark .highlight .w {
@@ -228,7 +208,6 @@
228
208
  background-color: transparent;
229
209
  }
230
210
 
231
- /* Keywords */
232
211
  .dark .highlight .k,
233
212
  .dark .highlight .kd,
234
213
  .dark .highlight .kn,
@@ -248,7 +227,6 @@
248
227
  background-color: #490202;
249
228
  }
250
229
 
251
- /* Built-in names */
252
230
  .dark .highlight .nb,
253
231
  .dark .highlight .nc,
254
232
  .dark .highlight .no,
@@ -256,7 +234,6 @@
256
234
  color: #ffa657;
257
235
  }
258
236
 
259
- /* Strings and regex */
260
237
  .dark .highlight .sr,
261
238
  .dark .highlight .na,
262
239
  .dark .highlight .nt {
@@ -268,7 +245,6 @@
268
245
  background-color: #0f3b17;
269
246
  }
270
247
 
271
- /* Constants and literals */
272
248
  .dark .highlight .kc,
273
249
  .dark .highlight .l,
274
250
  .dark .highlight .ld,
@@ -288,7 +264,6 @@
288
264
  color: #79c0ff;
289
265
  }
290
266
 
291
- /* Variables */
292
267
  .dark .highlight .nv,
293
268
  .dark .highlight .vc,
294
269
  .dark .highlight .vg,
@@ -297,20 +272,17 @@
297
272
  color: #79c0ff;
298
273
  }
299
274
 
300
- /* Operators */
301
275
  .dark .highlight .o,
302
276
  .dark .highlight .ow {
303
277
  color: #79c0ff;
304
278
  }
305
279
 
306
- /* Headers and subheaders in diffs */
307
280
  .dark .highlight .gh,
308
281
  .dark .highlight .gu {
309
282
  color: #79c0ff;
310
283
  font-weight: bold;
311
284
  }
312
285
 
313
- /* Strings */
314
286
  .dark .highlight .s,
315
287
  .dark .highlight .sa,
316
288
  .dark .highlight .sc,
@@ -325,20 +297,17 @@
325
297
  color: #a5d6ff;
326
298
  }
327
299
 
328
- /* Decorators and functions */
329
300
  .dark .highlight .nd,
330
301
  .dark .highlight .nf,
331
302
  .dark .highlight .fm {
332
303
  color: #d2a8ff;
333
304
  }
334
305
 
335
- /* Errors */
336
306
  .dark .highlight .err {
337
307
  color: #161b22;
338
308
  background-color: #ffa198;
339
309
  }
340
310
 
341
- /* Comments */
342
311
  .dark .highlight .c,
343
312
  .dark .highlight .ch,
344
313
  .dark .highlight .cd,
@@ -352,13 +321,11 @@
352
321
  color: #8b949e;
353
322
  }
354
323
 
355
- /* Name indicators */
356
324
  .dark .highlight .ni,
357
325
  .dark .highlight .si {
358
326
  color: #e6edf3;
359
327
  }
360
328
 
361
- /* Generic emphasis */
362
329
  .dark .highlight .ge {
363
330
  color: #e6edf3;
364
331
  font-style: italic;
@@ -0,0 +1,86 @@
1
+ .docyard-abbr {
2
+ text-decoration: underline;
3
+ text-decoration-style: dotted;
4
+ text-decoration-color: var(--muted-foreground);
5
+ text-underline-offset: 3px;
6
+ cursor: help;
7
+ position: relative;
8
+ }
9
+
10
+ .docyard-abbr:hover {
11
+ text-decoration-color: var(--primary);
12
+ }
13
+
14
+ .docyard-abbr-popover {
15
+ position: absolute;
16
+ z-index: 1000;
17
+ width: max-content;
18
+ max-width: 280px;
19
+ padding: var(--spacing-3) var(--spacing-4);
20
+ background: var(--background);
21
+ border: 1px solid var(--border);
22
+ border-radius: var(--radius-lg);
23
+ box-shadow:
24
+ 0 4px 6px -1px oklch(from var(--foreground) l c h / 8%),
25
+ 0 2px 4px -2px oklch(from var(--foreground) l c h / 6%);
26
+ pointer-events: none;
27
+ opacity: 0;
28
+ transform: translateY(-4px) scale(0.96);
29
+ transition:
30
+ opacity 0.15s ease,
31
+ transform 0.2s cubic-bezier(0.34, 1.56, 0.64, 1);
32
+ }
33
+
34
+ .docyard-abbr-popover.is-visible {
35
+ opacity: 1;
36
+ transform: translateY(0) scale(1);
37
+ }
38
+
39
+ .docyard-abbr-popover::after {
40
+ content: "";
41
+ position: absolute;
42
+ bottom: -6px;
43
+ left: var(--arrow-left, 16px);
44
+ width: 10px;
45
+ height: 10px;
46
+ background: var(--background);
47
+ border-bottom: 1px solid var(--border);
48
+ border-right: 1px solid var(--border);
49
+ transform: rotate(45deg);
50
+ }
51
+
52
+ .docyard-abbr-popover.is-below::after {
53
+ top: -6px;
54
+ bottom: auto;
55
+ border-bottom: none;
56
+ border-right: none;
57
+ border-top: 1px solid var(--border);
58
+ border-left: 1px solid var(--border);
59
+ }
60
+
61
+ .docyard-abbr-popover__term {
62
+ display: block;
63
+ font-weight: var(--font-semibold);
64
+ font-size: var(--text-sm);
65
+ color: var(--foreground);
66
+ margin-bottom: var(--spacing-1);
67
+ }
68
+
69
+ .docyard-abbr-popover__definition {
70
+ display: block;
71
+ font-size: var(--text-sm);
72
+ color: var(--muted-foreground);
73
+ line-height: var(--leading-relaxed);
74
+ }
75
+
76
+ @media (max-width: 640px) {
77
+ .docyard-abbr-popover {
78
+ max-width: 240px;
79
+ padding: var(--spacing-2) var(--spacing-3);
80
+ }
81
+
82
+ .docyard-abbr-popover__term,
83
+ .docyard-abbr-popover__definition {
84
+ font-size: var(--text-xs);
85
+ }
86
+ }
@@ -0,0 +1,138 @@
1
+ .docyard-accordion {
2
+ margin: var(--spacing-4) 0;
3
+ border: 1px solid var(--border);
4
+ border-radius: var(--radius-xl);
5
+ background-color: var(--card);
6
+ }
7
+
8
+ .docyard-accordion__summary {
9
+ display: flex;
10
+ align-items: center;
11
+ gap: var(--spacing-3);
12
+ padding: var(--spacing-3) var(--spacing-4);
13
+ cursor: pointer;
14
+ user-select: none;
15
+ font-weight: var(--font-medium);
16
+ font-size: var(--text-sm);
17
+ color: var(--foreground);
18
+ list-style: none;
19
+ transition: background-color var(--transition-fast);
20
+ border-radius: var(--radius-xl);
21
+ }
22
+
23
+ .docyard-accordion__summary::-webkit-details-marker {
24
+ display: none;
25
+ }
26
+
27
+ .docyard-accordion__summary::marker {
28
+ display: none;
29
+ content: "";
30
+ }
31
+
32
+ .docyard-accordion__summary:hover {
33
+ background-color: var(--accent);
34
+ }
35
+
36
+ .docyard-accordion__summary:focus-visible {
37
+ outline: 2px solid var(--ring);
38
+ outline-offset: -2px;
39
+ }
40
+
41
+ .docyard-accordion[open] .docyard-accordion__summary {
42
+ border-bottom-left-radius: 0;
43
+ border-bottom-right-radius: 0;
44
+ }
45
+
46
+ .docyard-accordion__icon {
47
+ flex-shrink: 0;
48
+ width: 1rem;
49
+ height: 1rem;
50
+ display: flex;
51
+ align-items: center;
52
+ justify-content: center;
53
+ color: var(--muted-foreground);
54
+ transition: transform var(--transition-fast);
55
+ }
56
+
57
+ .docyard-accordion__icon svg {
58
+ width: 100%;
59
+ height: 100%;
60
+ }
61
+
62
+ .docyard-accordion[open] .docyard-accordion__icon {
63
+ transform: rotate(90deg);
64
+ }
65
+
66
+ .docyard-accordion__title {
67
+ flex: 1;
68
+ }
69
+
70
+ .docyard-accordion__content {
71
+ padding: var(--spacing-4);
72
+ font-size: var(--text-sm);
73
+ color: var(--foreground);
74
+ line-height: var(--leading-relaxed);
75
+ border-top: 1px solid var(--border);
76
+ }
77
+
78
+ .docyard-accordion__content > *:first-child {
79
+ margin-top: 0;
80
+ }
81
+
82
+ .docyard-accordion__content > *:last-child {
83
+ margin-bottom: 0;
84
+ }
85
+
86
+ .docyard-accordion__content a {
87
+ color: var(--primary);
88
+ text-decoration: underline;
89
+ text-underline-offset: 3px;
90
+ }
91
+
92
+ .docyard-accordion__content a:hover {
93
+ color: var(--foreground);
94
+ }
95
+
96
+ .docyard-accordion__content pre {
97
+ margin: var(--spacing-4) 0;
98
+ border-radius: var(--radius-lg);
99
+ }
100
+
101
+ .docyard-accordion__content :not(pre) > code {
102
+ background-color: var(--muted);
103
+ padding: 0.125rem 0.375rem;
104
+ border-radius: var(--radius-sm);
105
+ font-size: 0.875em;
106
+ }
107
+
108
+ .docyard-accordion + .docyard-accordion {
109
+ margin-top: -1px;
110
+ border-top-left-radius: 0;
111
+ border-top-right-radius: 0;
112
+ }
113
+
114
+ .docyard-accordion + .docyard-accordion .docyard-accordion__summary {
115
+ border-top-left-radius: 0;
116
+ border-top-right-radius: 0;
117
+ }
118
+
119
+ .docyard-accordion:has(+ .docyard-accordion) {
120
+ border-bottom-left-radius: 0;
121
+ border-bottom-right-radius: 0;
122
+ margin-bottom: 0;
123
+ }
124
+
125
+ .docyard-accordion:has(+ .docyard-accordion) .docyard-accordion__summary {
126
+ border-bottom-left-radius: 0;
127
+ border-bottom-right-radius: 0;
128
+ }
129
+
130
+ @media (prefers-reduced-motion: reduce) {
131
+ .docyard-accordion__icon {
132
+ transition: none;
133
+ }
134
+
135
+ .docyard-accordion__summary {
136
+ transition: none;
137
+ }
138
+ }