markdowndocs 0.4.0 → 0.6.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b10065bc9db477eab3c5c118832bf1bf3d0b8c68d879c6b3b5bd324b0deb4ec3
4
- data.tar.gz: 4696b2b0c2e906ae7875ba69b32279d222f717db45abbed0987bb335f2d1e55d
3
+ metadata.gz: 57e0fd3a2811b71d43a7e32029abd3a252af462158017fe7dff81abe94b827eb
4
+ data.tar.gz: bc74b02043fb27fa165d89cbbad04f8c89209fd45ef584ac6e1d017ffd89548b
5
5
  SHA512:
6
- metadata.gz: 81f260911757400e215ebdc586c40229032e381ee5fc445e6606509de5a8fa15e7d60ce5a22f2b33e110c4984f63f093ca9e78393935b1d3e5306002c9dfe9de
7
- data.tar.gz: f41f6d08e1736a2d772a89e0d89a5f6d57d6da25342b1a426c0f9bd339f028280d9e1bb0814209ac43edea4823057392a2e2e18db7d52164d1363d0b8c22462e
6
+ metadata.gz: ce7f0b7b5ad9e21ff9b58d7bfe5a55319b127b68b9f614d33c69c2d825f3cb33bf8e58be7915ab619bcdb54b3830b7d699ed2ea1efa995204b7759f1967a45bc
7
+ data.tar.gz: 2fbb656ed33f668b517f2d8a105fd3c1be00a2b0a3f6d212f7fc80b603118121e5eea04e569ea7d75d0146a82537c299a65cebfc425e9b36dd49a5205aa1e60f
data/CHANGELOG.md CHANGED
@@ -5,6 +5,77 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [0.6.0] - 2026-05-13
9
+
10
+ ### Added
11
+
12
+ - `audience:` frontmatter key on individual docs. Accepts a single string
13
+ or an array of mode names (e.g. `audience: technical`, or
14
+ `audience: [guide, technical]`). When the current mode does not appear
15
+ in a doc's audience, the doc is hidden from the index and unreachable
16
+ via slug (returns 404). Docs WITHOUT an `audience:` key remain visible
17
+ in every mode — fully backward compatible with pre-0.6 docs.
18
+ - `Documentation#audience` returns the resolved audience as `Array<String>`.
19
+ - `Documentation#visible_to?(mode)` predicate. `nil` mode means no filter.
20
+ - `Documentation.find_by_slug(slug, mode: nil)` and
21
+ `Documentation.grouped_by_category(mode: nil)` both accept an optional
22
+ `mode:` kwarg. Default behavior (no kwarg) is unchanged — backward
23
+ compatible signature.
24
+
25
+ ### Changed
26
+
27
+ - `Documentation.grouped_by_category` now drops empty categories when a
28
+ `mode:` filter is applied — categories whose docs are all hidden by the
29
+ current audience no longer render as empty headers.
30
+ - `Markdowndocs::DocsController#index` and `#show` pass the resolved
31
+ `@docs_mode` through to `Documentation` so the index reflects the
32
+ user's mode pick. URL guessing / shared links to wrong-audience docs
33
+ now return 404.
34
+
35
+ ### Migration notes
36
+
37
+ - No action required if you don't use modes. Existing docs continue to
38
+ appear in both `guide` and `technical` modes.
39
+ - To restrict a doc to a specific audience, add `audience: technical`
40
+ (or `audience: guide`) to its frontmatter.
41
+ - To make a doc explicitly multi-audience, use `audience: [guide, technical]`.
42
+
43
+ ## [0.5.0] - 2026-05-05
44
+
45
+ ### Added
46
+
47
+ - Dark mode support across all docs templates. Every `bg-*`, `text-*`, and
48
+ `border-*` class now has a paired `dark:` variant chosen for WCAG 2.2 AAA
49
+ contrast (7:1) on dark surfaces. Host apps with `class="dark"` on `<html>`
50
+ (or `prefers-color-scheme: dark`) will see proper dark theming without
51
+ needing to override gem views.
52
+
53
+ ### Changed
54
+
55
+ - Bumped indigo link colors from `text-indigo-600` to `text-indigo-700` (light)
56
+ and `text-indigo-300` (dark) so links pass AAA contrast on both surfaces.
57
+ - Selected-state mode-switcher cyan text bumped from `text-cyan-700`/`-800` to
58
+ `text-cyan-900` (light) and `text-cyan-100` (dark) for AAA against the
59
+ selected card's `bg-cyan-50`/`bg-cyan-900/40` background.
60
+ - `prose-indigo` content area now also applies `dark:prose-invert` so the
61
+ rendered Markdown body inverts cleanly in dark mode.
62
+
63
+ ## [0.4.0] - 2026-03-20
64
+
65
+ ### Changed
66
+
67
+ - Engine now uses its own layout instead of inheriting the host app's layout, eliminating route helper conflicts caused by `isolate_namespace`. Host apps can override at `app/views/layouts/markdowndocs/application.html.erb` or configure via `config.layout`.
68
+ - Supports `content_for` blocks (`:docs_header`, `:docs_footer`, `:head`, `:title`) for customization.
69
+ - Removed `ensure_host_route_helpers` `before_action` — no longer needed with isolated layout.
70
+
71
+ ## [0.3.1] - 2026-03-20
72
+
73
+ ### Changed
74
+
75
+ - Fenced code block content is now indexed as a low-boost (0.5x) search field, making class names, methods, and config keys in examples discoverable.
76
+ - Visible cards are now reordered by MiniSearch relevance score within each category.
77
+ - Search debounce reduced from 150ms to 50ms for snappier results.
78
+
8
79
  ## [0.3.0] - 2026-03-20
9
80
 
10
81
  ### Added
@@ -96,6 +167,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
96
167
  - i18n support for all UI strings
97
168
  - Install generator (`rails generate markdowndocs:install`)
98
169
 
170
+ [0.5.0]: https://github.com/dschmura/markdowndocs/releases/tag/v0.5.0
171
+ [0.4.0]: https://github.com/dschmura/markdowndocs/releases/tag/v0.4.0
172
+ [0.3.1]: https://github.com/dschmura/markdowndocs/releases/tag/v0.3.1
99
173
  [0.3.0]: https://github.com/dschmura/markdowndocs/releases/tag/v0.3.0
100
174
  [0.2.3]: https://github.com/dschmura/markdowndocs/releases/tag/v0.2.3
101
175
  [0.2.2]: https://github.com/dschmura/markdowndocs/releases/tag/v0.2.2
data/README.md CHANGED
@@ -108,6 +108,9 @@ Add optional YAML front matter to set metadata:
108
108
  ---
109
109
  title: "Quick Start Guide"
110
110
  description: "Get up and running in five minutes"
111
+ audience:
112
+ - guide
113
+ - technical
111
114
  modes:
112
115
  - guide
113
116
  - technical
@@ -121,6 +124,24 @@ Your content here...
121
124
 
122
125
  If front matter is omitted, the title is extracted from the first H1 heading and the description from the first paragraph.
123
126
 
127
+ ### Audience Filtering (whole-document)
128
+
129
+ For content that's split into separate files per audience (a user guide
130
+ and a deep-dive technical reference, for example), use the `audience:`
131
+ key in front matter to declare who a doc is for:
132
+
133
+ ```yaml
134
+ audience: technical # single-audience: shown only when mode=technical
135
+ audience: [guide, technical] # multi-audience: shown in either mode
136
+ # omit `audience:` # backward-compatible: shown in every mode
137
+ ```
138
+
139
+ When the current mode does not appear in a doc's audience, the doc is
140
+ hidden from the index AND unreachable via slug (404). This complements
141
+ the in-page `<!-- mode: -->` blocks below: use mode blocks when one doc
142
+ mixes audience-specific snippets; use `audience:` when whole docs are
143
+ audience-specific.
144
+
124
145
  ### Mode Blocks
125
146
 
126
147
  Use HTML comments to show content only in specific modes:
@@ -9,7 +9,10 @@ module Markdowndocs
9
9
  SAFE_SLUG_PATTERN = /\A[a-zA-Z0-9_-]+\z/
10
10
 
11
11
  def index
12
- @docs_by_category = Documentation.grouped_by_category
12
+ # Pass the resolved mode so docs whose `audience:` frontmatter
13
+ # excludes it are hidden from the index. Categories with no
14
+ # surviving docs are dropped (see Documentation.grouped_by_category).
15
+ @docs_by_category = Documentation.grouped_by_category(mode: @docs_mode)
13
16
  @search_enabled = Markdowndocs.config.search_enabled
14
17
  end
15
18
 
@@ -38,7 +41,12 @@ module Markdowndocs
38
41
  end
39
42
 
40
43
  def show
41
- @doc = Documentation.find_by_slug(params[:slug])
44
+ # Audience filter: a doc with `audience: technical` is unreachable
45
+ # via slug while the user is in guide mode — they get the 404 page,
46
+ # not the doc's content. This matters because the index already
47
+ # hides those docs; making the show route honor the same filter
48
+ # keeps URL guessing / shared-link scenarios consistent.
49
+ @doc = Documentation.find_by_slug(params[:slug], mode: @docs_mode)
42
50
 
43
51
  if @doc.nil?
44
52
  render_not_found
@@ -23,14 +23,21 @@ module Markdowndocs
23
23
  end.sort_by(&:slug)
24
24
  end
25
25
 
26
- def self.find_by_slug(slug)
26
+ # When `mode:` is given (e.g. "guide" / "technical"), returns nil if
27
+ # the resolved doc's `audience:` frontmatter excludes that mode. Docs
28
+ # without an explicit `audience:` key default to "visible in all modes"
29
+ # — backward compatible with pre-0.6 docs.
30
+ def self.find_by_slug(slug, mode: nil)
27
31
  return nil if slug.blank?
28
32
  return nil if slug.include?("..") || slug.include?("/")
29
33
 
30
34
  file_path = Markdowndocs.config.resolved_docs_path.join("#{slug}.md")
31
35
  return nil unless file_path.exist?
32
36
 
33
- new(file_path)
37
+ doc = new(file_path)
38
+ return nil unless doc.visible_to?(mode)
39
+
40
+ doc
34
41
  rescue => e
35
42
  Rails.logger.error("Error finding documentation by slug '#{slug}': #{e.message}")
36
43
  nil
@@ -40,9 +47,13 @@ module Markdowndocs
40
47
  all.select { |doc| doc.category == category }
41
48
  end
42
49
 
43
- def self.grouped_by_category
50
+ # When `mode:` is given, filters out docs whose `audience:` excludes
51
+ # that mode AND drops categories that end up empty (so the index
52
+ # sidebar doesn't render headers with no children).
53
+ def self.grouped_by_category(mode: nil)
44
54
  Markdowndocs.config.categories.each_with_object({}) do |(category, slugs), hash|
45
- hash[category] = slugs.map { |slug| find_by_slug(slug) }.compact
55
+ docs = slugs.map { |slug| find_by_slug(slug, mode: mode) }.compact
56
+ hash[category] = docs unless docs.empty?
46
57
  end
47
58
  end
48
59
 
@@ -83,6 +94,32 @@ module Markdowndocs
83
94
  available_modes.include?(mode.to_s)
84
95
  end
85
96
 
97
+ # The audience(s) this doc is written for, declared via `audience:`
98
+ # frontmatter. Accepts a single string or an array; both are coerced
99
+ # to an Array<String>. When the frontmatter key is missing, defaults
100
+ # to all configured modes — a doc with no audience declaration is
101
+ # visible in every mode (backward compat with pre-0.6 docs).
102
+ def audience
103
+ @audience ||= begin
104
+ parsed = parse_frontmatter
105
+ raw = parsed[:frontmatter]["audience"]
106
+ case raw
107
+ when Array then raw.map(&:to_s)
108
+ when String then [ raw ]
109
+ when nil then Markdowndocs.config.modes.dup
110
+ else Markdowndocs.config.modes.dup
111
+ end
112
+ end
113
+ end
114
+
115
+ # Whether this doc should be surfaced to a viewer in the given mode.
116
+ # `nil` mode is treated as "no filter" — useful for callers that
117
+ # don't care about audience (search indexer, admin tools).
118
+ def visible_to?(mode)
119
+ return true if mode.nil?
120
+ audience.include?(mode.to_s)
121
+ end
122
+
86
123
  # Returns content stripped of frontmatter, markdown syntax, and HTML tags
87
124
  # for use in search indexing.
88
125
  def plain_text_content
@@ -7,21 +7,21 @@
7
7
  ]
8
8
  %>
9
9
  <nav aria-label="Breadcrumb" class="mb-6">
10
- <ol class="flex items-center space-x-2 text-sm text-gray-600">
10
+ <ol class="flex items-center space-x-2 text-sm text-gray-700 dark:text-slate-300">
11
11
  <% breadcrumb_items.each_with_index do |item, index| %>
12
12
  <li class="flex items-center">
13
13
  <% if index > 0 %>
14
- <svg class="w-4 h-4 mx-2 text-gray-700" fill="currentColor" viewBox="0 0 20 20" aria-hidden="true">
14
+ <svg class="w-4 h-4 mx-2 text-gray-700 dark:text-slate-300" fill="currentColor" viewBox="0 0 20 20" aria-hidden="true">
15
15
  <path fill-rule="evenodd" d="M7.293 14.707a1 1 0 010-1.414L10.586 10 7.293 6.707a1 1 0 011.414-1.414l4 4a1 1 0 010 1.414l-4 4a1 1 0 01-1.414 0z" clip-rule="evenodd" />
16
16
  </svg>
17
17
  <% end %>
18
18
 
19
19
  <% if item[:current] %>
20
- <span class="font-medium text-gray-900" aria-current="page"><%= item[:name] %></span>
20
+ <span class="font-medium text-gray-900 dark:text-slate-100" aria-current="page"><%= item[:name] %></span>
21
21
  <% elsif item[:path] %>
22
- <%= link_to item[:name], item[:path], class: "hover:text-indigo-600 transition-colors" %>
22
+ <%= link_to item[:name], item[:path], class: "hover:text-indigo-700 dark:hover:text-indigo-300 transition-colors" %>
23
23
  <% else %>
24
- <span class="text-gray-700"><%= item[:name] %></span>
24
+ <span class="text-gray-700 dark:text-slate-300"><%= item[:name] %></span>
25
25
  <% end %>
26
26
  </li>
27
27
  <% end %>
@@ -1,7 +1,7 @@
1
1
  <%# locals: (doc:) %>
2
- <div class="bg-white rounded-lg shadow-sm hover:shadow-md transition-shadow duration-200 p-6 h-full flex flex-col">
3
- <h3 class="text-lg font-semibold text-gray-900 mb-2 hover:text-indigo-600 transition-colors">
2
+ <div class="bg-white dark:bg-slate-800 rounded-lg shadow-sm hover:shadow-md transition-shadow duration-200 p-6 h-full flex flex-col">
3
+ <h3 class="text-lg font-semibold text-gray-900 dark:text-slate-100 mb-2 hover:text-indigo-700 dark:hover:text-indigo-300 transition-colors">
4
4
  <%= link_to doc.title, markdowndocs.doc_path(doc.slug) %>
5
5
  </h3>
6
- <p class="text-gray-600 text-sm line-clamp-3"><%= doc.description %></p>
6
+ <p class="text-gray-700 dark:text-slate-300 text-sm line-clamp-3"><%= doc.description %></p>
7
7
  </div>
@@ -3,9 +3,11 @@
3
3
  id="docs-mode-switcher"
4
4
  class="
5
5
  bg-white
6
+ dark:bg-slate-800
6
7
  rounded-lg
7
8
  border
8
9
  border-slate-200
10
+ dark:border-slate-700
9
11
  p-4
10
12
  "
11
13
  data-controller="docs-mode"
@@ -15,6 +17,7 @@
15
17
  text-sm
16
18
  font-medium
17
19
  text-slate-700
20
+ dark:text-slate-300
18
21
  mb-3
19
22
  ">
20
23
  <%= t("markdowndocs.viewing_mode") %>
@@ -46,13 +49,13 @@
46
49
  border-2
47
50
  transition-all
48
51
  duration-150
49
- <%= (current_mode == mode) ? 'border-cyan-500 bg-cyan-50' : 'border-slate-200 hover:border-slate-300 hover:bg-slate-50' %>
52
+ <%= (current_mode == mode) ? 'border-cyan-500 bg-cyan-50 dark:bg-cyan-900/40 dark:border-cyan-400' : 'border-slate-200 hover:border-slate-300 hover:bg-slate-50 dark:border-slate-700 dark:hover:border-slate-500 dark:hover:bg-slate-700' %>
50
53
  "
51
54
  >
52
55
  <span class="
53
56
  block
54
57
  font-medium
55
- <%= (current_mode == mode) ? 'text-cyan-700' : 'text-slate-900' %>
58
+ <%= (current_mode == mode) ? 'text-cyan-900 dark:text-cyan-100' : 'text-slate-900 dark:text-slate-100' %>
56
59
  ">
57
60
  <%= t("markdowndocs.modes.#{mode}", default: mode.titleize) %>
58
61
  </span>
@@ -61,7 +64,7 @@
61
64
  <p class="
62
65
  text-xs
63
66
  mt-1
64
- <%= (current_mode == mode) ? 'text-cyan-800' : 'text-slate-600' %>
67
+ <%= (current_mode == mode) ? 'text-cyan-900 dark:text-cyan-100' : 'text-slate-700 dark:text-slate-300' %>
65
68
  ">
66
69
  <%= description %>
67
70
  </p>
@@ -7,13 +7,13 @@
7
7
  <% end %>
8
8
 
9
9
  <% if toc_items.length >= 3 %>
10
- <div class="bg-white rounded-lg shadow-sm p-6">
10
+ <div class="bg-white dark:bg-slate-800 rounded-lg shadow-sm p-6">
11
11
  <nav aria-label="Table of Contents">
12
- <h2 class="text-lg font-semibold text-gray-900 mb-4">On this page</h2>
12
+ <h2 class="text-lg font-semibold text-gray-900 dark:text-slate-100 mb-4">On this page</h2>
13
13
  <ul class="space-y-2">
14
14
  <% toc_items.each do |item| %>
15
15
  <li class="<%= 'ml-4' if item[:level] == 3 %>">
16
- <a href="#<%= item[:slug] %>" class="text-sm text-gray-600 hover:text-indigo-600 transition-colors block py-1">
16
+ <a href="#<%= item[:slug] %>" class="text-sm text-gray-700 dark:text-slate-300 hover:text-indigo-700 dark:hover:text-indigo-300 transition-colors block py-1">
17
17
  <%= item[:text] %>
18
18
  </a>
19
19
  </li>
@@ -24,13 +24,13 @@
24
24
  <% end %>
25
25
 
26
26
  <% if related_docs.any? %>
27
- <div class="bg-white rounded-lg shadow-sm p-6 related-docs">
28
- <h2 class="text-lg font-semibold text-gray-900 mb-4">Related Documentation</h2>
27
+ <div class="bg-white dark:bg-slate-800 rounded-lg shadow-sm p-6 related-docs">
28
+ <h2 class="text-lg font-semibold text-gray-900 dark:text-slate-100 mb-4">Related Documentation</h2>
29
29
  <ul class="space-y-3">
30
30
  <% related_docs.each do |related_doc| %>
31
31
  <li>
32
- <%= link_to related_doc.title, markdowndocs.doc_path(related_doc.slug), class: "text-sm text-indigo-600 hover:text-indigo-700 font-medium transition-colors" %>
33
- <p class="text-xs text-gray-600 mt-1"><%= related_doc.description %></p>
32
+ <%= link_to related_doc.title, markdowndocs.doc_path(related_doc.slug), class: "text-sm text-indigo-700 dark:text-indigo-300 hover:text-indigo-800 dark:hover:text-indigo-200 font-medium transition-colors" %>
33
+ <p class="text-xs text-gray-700 dark:text-slate-300 mt-1"><%= related_doc.description %></p>
34
34
  </li>
35
35
  <% end %>
36
36
  </ul>
@@ -1,4 +1,4 @@
1
- <div class="min-h-screen bg-gray-50">
1
+ <div class="min-h-screen bg-gray-50 dark:bg-slate-900">
2
2
  <div class="max-w-7xl mx-auto px-4 py-12
3
3
  sm:px-6
4
4
  lg:px-8"
@@ -8,14 +8,14 @@
8
8
  <% end %>>
9
9
  <!-- Hero Section -->
10
10
  <div class="text-center mb-12">
11
- <h1 class="text-4xl font-bold text-gray-900 mb-4">Documentation</h1>
12
- <p class="text-xl text-gray-600">Browse our comprehensive documentation and guides</p>
11
+ <h1 class="text-4xl font-bold text-gray-900 dark:text-slate-100 mb-4">Documentation</h1>
12
+ <p class="text-xl text-gray-700 dark:text-slate-300">Browse our comprehensive documentation and guides</p>
13
13
 
14
14
  <% if @search_enabled %>
15
15
  <!-- Search input -->
16
16
  <div class="mt-6 max-w-lg mx-auto">
17
17
  <div class="relative">
18
- <svg class="absolute left-3 top-1/2 -translate-y-1/2 w-5 h-5 text-gray-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
18
+ <svg class="absolute left-3 top-1/2 -translate-y-1/2 w-5 h-5 text-gray-700 dark:text-slate-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
19
19
  <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z" />
20
20
  </svg>
21
21
  <input
@@ -23,7 +23,7 @@
23
23
  data-docs-search-target="input"
24
24
  data-action="input->docs-search#search"
25
25
  placeholder="<%= t("markdowndocs.search_placeholder", default: "Search documentation...") %>"
26
- class="w-full pl-10 pr-4 py-3 rounded-lg border border-gray-300 shadow-sm text-gray-900 placeholder-gray-400 transition-colors
26
+ class="w-full pl-10 pr-4 py-3 rounded-lg border border-gray-300 dark:border-slate-700 shadow-sm bg-white dark:bg-slate-800 text-gray-900 dark:text-slate-100 placeholder-gray-700 dark:placeholder-slate-400 transition-colors
27
27
  focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:border-indigo-500"
28
28
  autocomplete="off" />
29
29
  </div>
@@ -35,11 +35,11 @@
35
35
  <!-- No results message -->
36
36
  <% if @search_enabled %>
37
37
  <div data-docs-search-target="noResults" class="hidden text-center py-12">
38
- <svg class="mx-auto h-12 w-12 text-gray-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
38
+ <svg class="mx-auto h-12 w-12 text-gray-700 dark:text-slate-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
39
39
  <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z" />
40
40
  </svg>
41
- <h3 class="mt-2 text-sm font-medium text-gray-900"><%= t("markdowndocs.no_search_results", default: "No matching documents") %></h3>
42
- <p class="mt-1 text-sm text-gray-600"><%= t("markdowndocs.try_different_search", default: "Try a different search term") %></p>
41
+ <h3 class="mt-2 text-sm font-medium text-gray-900 dark:text-slate-100"><%= t("markdowndocs.no_search_results", default: "No matching documents") %></h3>
42
+ <p class="mt-1 text-sm text-gray-700 dark:text-slate-300"><%= t("markdowndocs.try_different_search", default: "Try a different search term") %></p>
43
43
  </div>
44
44
  <% end %>
45
45
 
@@ -48,7 +48,7 @@
48
48
  <% if docs.any? %>
49
49
  <div id="<%= category.parameterize %>" class="mb-12 scroll-mt-6"
50
50
  <% if @search_enabled %>data-docs-search-target="category"<% end %>>
51
- <h2 class="text-2xl font-semibold text-gray-900 mb-6"><%= category %></h2>
51
+ <h2 class="text-2xl font-semibold text-gray-900 dark:text-slate-100 mb-6"><%= category %></h2>
52
52
  <div class="grid grid-cols-1 gap-6
53
53
  md:grid-cols-2
54
54
  lg:grid-cols-3">
@@ -63,15 +63,15 @@
63
63
  <% end %>
64
64
  <% else %>
65
65
  <!-- Empty State -->
66
- <div class="bg-white rounded-lg shadow-sm">
66
+ <div class="bg-white dark:bg-slate-800 rounded-lg shadow-sm">
67
67
  <div class="px-4 py-5
68
68
  sm:p-6">
69
69
  <div class="text-center py-12">
70
- <svg class="mx-auto h-12 w-12 text-gray-700" fill="none" stroke="currentColor" viewBox="0 0 24 24" aria-hidden="true">
70
+ <svg class="mx-auto h-12 w-12 text-gray-700 dark:text-slate-300" fill="none" stroke="currentColor" viewBox="0 0 24 24" aria-hidden="true">
71
71
  <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z" />
72
72
  </svg>
73
- <h3 class="mt-2 text-sm font-medium text-gray-900">No documentation available</h3>
74
- <p class="mt-1 text-sm text-gray-700">Documentation will appear here once markdown files are added.</p>
73
+ <h3 class="mt-2 text-sm font-medium text-gray-900 dark:text-slate-100">No documentation available</h3>
74
+ <p class="mt-1 text-sm text-gray-700 dark:text-slate-300">Documentation will appear here once markdown files are added.</p>
75
75
  </div>
76
76
  </div>
77
77
  </div>
@@ -1,11 +1,11 @@
1
- <div class="min-h-screen bg-gray-50">
1
+ <div class="min-h-screen bg-gray-50 dark:bg-slate-900">
2
2
  <div class="max-w-7xl mx-auto px-4 py-12
3
3
  sm:px-6
4
4
  lg:px-8">
5
5
  <!-- Back link -->
6
6
  <div class="mb-6">
7
- <%= link_to markdowndocs.root_path, class: "inline-flex items-center text-indigo-600 transition-colors
8
- hover:text-indigo-700" do %>
7
+ <%= link_to markdowndocs.root_path, class: "inline-flex items-center text-indigo-700 transition-colors
8
+ hover:text-indigo-800 dark:text-indigo-300 dark:hover:text-indigo-200" do %>
9
9
  <svg class="w-4 h-4 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
10
10
  <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 19l-7-7m0 0l7-7m-7 7h18" />
11
11
  </svg>
@@ -21,8 +21,8 @@
21
21
  <button
22
22
  id="sidebar-toggle"
23
23
  type="button"
24
- class="w-full px-4 py-2 bg-white rounded-lg shadow-sm text-gray-700 transition-colors flex items-center justify-between
25
- hover:bg-gray-50"
24
+ class="w-full px-4 py-2 bg-white dark:bg-slate-800 rounded-lg shadow-sm text-gray-700 dark:text-slate-300 transition-colors flex items-center justify-between
25
+ hover:bg-gray-50 dark:hover:bg-slate-700"
26
26
  aria-label="<%= t("markdowndocs.navigation_sidebar") %>"
27
27
  aria-expanded="false"
28
28
  aria-controls="mobile-sidebar"
@@ -66,8 +66,8 @@
66
66
  lg:grid-cols-12">
67
67
  <!-- Main content -->
68
68
  <main class="lg:col-span-8">
69
- <article class="bg-white rounded-lg shadow-sm p-8">
70
- <div class="prose prose-indigo max-w-none">
69
+ <article class="bg-white dark:bg-slate-800 rounded-lg shadow-sm p-8">
70
+ <div class="prose prose-indigo dark:prose-invert max-w-none">
71
71
  <%= raw @rendered_content %>
72
72
  </div>
73
73
  </article>
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Markdowndocs
4
- VERSION = "0.4.0"
4
+ VERSION = "0.6.0"
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: markdowndocs
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.0
4
+ version: 0.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dave Chmura