@jaamd/jaad 0.11.0 → 1.0.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 (138) hide show
  1. package/README.md +8 -2
  2. package/dist/jaad.css +232 -347
  3. package/docs/00-overview.md +25 -0
  4. package/docs/01-getting-started/01-installation.md +216 -0
  5. package/docs/01-getting-started/02-pages.md +109 -0
  6. package/docs/01-getting-started/03-deployment.md +100 -0
  7. package/docs/02-configurations/01-reference.md +215 -0
  8. package/docs/02-configurations/02-frontmatter.md +105 -0
  9. package/docs/02-configurations/03-i18n.md +210 -0
  10. package/docs/02-configurations/04-search.md +58 -0
  11. package/docs/02-configurations/05-themes.md +104 -0
  12. package/docs/02-configurations/06-styles.md +156 -0
  13. package/docs/02-configurations/07-custom-pages.md +119 -0
  14. package/docs/02-configurations/08-advanced-layout.md +139 -0
  15. package/docs/03-upgrading.md +208 -0
  16. package/index.ts +8 -22
  17. package/package.json +10 -9
  18. package/site.ts +18 -1
  19. package/src/config.ts +25 -176
  20. package/src/{advanced.ts → docs/advanced.ts} +6 -4
  21. package/src/docs/collection.ts +109 -0
  22. package/src/docs/components/Breadcrumbs.astro +29 -0
  23. package/src/docs/components/DocsMobileNav.astro +90 -0
  24. package/src/docs/components/DocsNavTree.astro +57 -0
  25. package/src/docs/components/DocsPage.astro +66 -0
  26. package/src/{components/docs → docs/components}/DocsPageNav.astro +4 -4
  27. package/src/docs/components/DocsSidebarLeft.astro +53 -0
  28. package/src/{components/docs → docs/components}/PageActions.astro +10 -8
  29. package/src/{components/docs → docs/components}/StructuredData.astro +3 -3
  30. package/src/{components/docs → docs/components}/TableOfContents.astro +20 -22
  31. package/src/docs/config.ts +167 -0
  32. package/src/docs/content.ts +36 -0
  33. package/src/docs/endpoints.ts +89 -0
  34. package/src/docs/integration.ts +249 -0
  35. package/src/{layouts → docs/layouts}/DefaultDocsFrame.astro +7 -5
  36. package/src/{layouts → docs/layouts}/Docs.astro +44 -43
  37. package/src/docs/layouts/Page.astro +18 -0
  38. package/src/docs/link-plugins.ts +52 -0
  39. package/src/docs/links.ts +42 -0
  40. package/src/{locale-tree.ts → docs/locale-tree.ts} +1 -1
  41. package/src/docs/model/ids.ts +87 -0
  42. package/src/docs/model/rendered.ts +185 -0
  43. package/src/docs/model/tree.ts +124 -0
  44. package/src/docs/model/validate.ts +75 -0
  45. package/src/docs/navigation.ts +75 -0
  46. package/src/{routes → docs/routes}/404.astro +1 -1
  47. package/src/docs/routes/docs-index.astro +19 -0
  48. package/src/docs/routes/docs-slug.astro +54 -0
  49. package/src/{routes → docs/routes}/docs-slug.md.ts +8 -10
  50. package/src/{routes → docs/routes}/llms-locale.txt.ts +1 -1
  51. package/src/{routes → docs/routes}/llms.txt.ts +1 -1
  52. package/src/{routes → docs/routes}/search-index-locale.json.ts +1 -1
  53. package/src/{routes → docs/routes}/search-index.json.ts +1 -1
  54. package/src/docs/runtime.ts +17 -0
  55. package/src/docs/search-index.ts +39 -0
  56. package/src/docs/styles/components/breadcrumbs.css +26 -0
  57. package/src/docs/styles/components/docs-mobile-nav.css +47 -0
  58. package/src/docs/styles/components/docs-page-nav.css +41 -0
  59. package/src/docs/styles/components/docs-sidebar.css +59 -0
  60. package/src/docs/styles/components/page-actions.css +51 -0
  61. package/src/docs/styles/components/toc.css +38 -0
  62. package/src/docs/styles/components.css +7 -0
  63. package/src/docs/styles/docs.css +81 -0
  64. package/src/{@types/docs.ts → docs/types.ts} +8 -16
  65. package/src/{urls.ts → docs/urls.ts} +2 -16
  66. package/src/env.d.ts +1 -1
  67. package/src/integration.ts +15 -249
  68. package/src/{components → site/components}/Footer.astro +1 -1
  69. package/src/{components → site/components}/Header.astro +14 -11
  70. package/src/{components → site/components}/LocaleSwitcher.astro +2 -2
  71. package/src/{components → site/components}/NavMobile.astro +1 -1
  72. package/src/{components → site/components}/SearchPalette.astro +160 -79
  73. package/src/{components → site/components}/ThemeSwitcher.astro +1 -1
  74. package/src/site/config.ts +149 -0
  75. package/src/{infer.ts → site/infer.ts} +3 -3
  76. package/src/site/integration.ts +59 -0
  77. package/src/{layouts/Page.astro → site/layouts/Shell.astro} +6 -3
  78. package/src/{locales.ts → site/locales.ts} +9 -1
  79. package/src/{docs-config.ts → site/runtime.ts} +1 -12
  80. package/src/site/search.ts +227 -0
  81. package/src/{social.ts → site/social.ts} +2 -2
  82. package/src/site/styles/components/header.css +31 -0
  83. package/src/{styles → site/styles}/components/search.css +21 -1
  84. package/src/{styles → site/styles}/components/shell.css +4 -0
  85. package/src/site/styles/components.css +10 -0
  86. package/src/{styles → site/styles}/global.css +4 -26
  87. package/src/{themes/index.ts → site/themes.ts} +1 -1
  88. package/src/{ui → site/ui}/en.ts +3 -5
  89. package/src/{ui → site/ui}/it.ts +2 -4
  90. package/src/site/urls.ts +14 -0
  91. package/src/{virtual.ts → site/virtual.ts} +12 -18
  92. package/src/styles.css +5 -0
  93. package/src/collection.ts +0 -97
  94. package/src/components/ScrollToTop.astro +0 -43
  95. package/src/components/docs/Breadcrumbs.astro +0 -36
  96. package/src/components/docs/DocsMobileNav.astro +0 -93
  97. package/src/components/docs/DocsPage.astro +0 -68
  98. package/src/components/docs/DocsSidebarLeft.astro +0 -82
  99. package/src/content.ts +0 -42
  100. package/src/navigation.ts +0 -97
  101. package/src/routes/docs-index.astro +0 -19
  102. package/src/routes/docs-slug.astro +0 -58
  103. package/src/styles/components/breadcrumbs.css +0 -13
  104. package/src/styles/components/docs-mobile-nav.css +0 -9
  105. package/src/styles/components/docs-page-nav.css +0 -31
  106. package/src/styles/components/docs-sidebar.css +0 -42
  107. package/src/styles/components/header.css +0 -20
  108. package/src/styles/components/page-actions.css +0 -13
  109. package/src/styles/components/scroll-to-top.css +0 -11
  110. package/src/styles/components/toc.css +0 -21
  111. package/src/styles/docs.css +0 -112
  112. package/src/utils/docs.ts +0 -300
  113. package/src/utils/endpoints.ts +0 -80
  114. package/src/utils/search.ts +0 -83
  115. /package/src/{styles → docs/styles}/components/docs-page.css +0 -0
  116. /package/src/{styles → docs/styles}/jaamd.css +0 -0
  117. /package/src/{components → site/components}/Head.astro +0 -0
  118. /package/src/{components → site/components}/Nav.astro +0 -0
  119. /package/src/{components → site/components}/SocialLinks.astro +0 -0
  120. /package/src/{components → site/components}/locale-switcher.ts +0 -0
  121. /package/src/{fonts → site/fonts}/OFL.txt +0 -0
  122. /package/src/{fonts → site/fonts}/inter.woff2 +0 -0
  123. /package/src/{fonts → site/fonts}/merriweather-italic.woff2 +0 -0
  124. /package/src/{fonts → site/fonts}/merriweather.woff2 +0 -0
  125. /package/src/{fonts.ts → site/fonts.ts} +0 -0
  126. /package/src/{forges.ts → site/forges.ts} +0 -0
  127. /package/src/{utils → site}/helpers.ts +0 -0
  128. /package/src/{styles → site/styles}/components/footer.css +0 -0
  129. /package/src/{styles → site/styles}/components/locale-switcher.css +0 -0
  130. /package/src/{styles → site/styles}/components/nav-mobile.css +0 -0
  131. /package/src/{styles → site/styles}/components/nav.css +0 -0
  132. /package/src/{styles → site/styles}/components/not-found.css +0 -0
  133. /package/src/{styles → site/styles}/components/social-links.css +0 -0
  134. /package/src/{styles → site/styles}/components/theme-switcher.css +0 -0
  135. /package/src/{styles → site/styles}/jaamd-forward.css +0 -0
  136. /package/src/{styles → site/styles}/jaamd-reverse.css +0 -0
  137. /package/src/{styles → site/styles}/tailwind.css +0 -0
  138. /package/src/{ui.ts → site/ui.ts} +0 -0
@@ -0,0 +1,105 @@
1
+ ---
2
+ description: Every frontmatter field JAAD reads, and what each one changes.
3
+ keywords: [frontmatter, metadata, seo]
4
+ ---
5
+
6
+ # Frontmatter
7
+
8
+ Frontmatter is optional. Markdown without it works as-is: the filename sets the
9
+ order and the URL, and the first `# Heading` sets the title. Each field below
10
+ overrides something the file tree or the body already supplies.
11
+
12
+ ```markdown
13
+ ---
14
+ title: Images & Videos
15
+ label: Media
16
+ translationKey: media
17
+ description: Add accessible images and embedded videos.
18
+ keywords: [markdown, media]
19
+ order: 5
20
+ draft: false
21
+ author: Ada Lovelace
22
+ ogImage: /og/media.png
23
+ lastUpdated: 2026-09-12
24
+ ---
25
+
26
+ # Images and videos
27
+ ```
28
+
29
+ | Field | Type | Effect |
30
+ | ---------------- | ----------------- | -------------------------------------------- |
31
+ | `title` | `string` | Page title, everywhere the page is named |
32
+ | `label` | `string` | Shorter name, in navigation only |
33
+ | `translationKey` | `string` | Pairs this page with its translations |
34
+ | `description` | `string` | Description metadata and `llms.txt` |
35
+ | `order` | `number` | Replaces the number from the filename prefix |
36
+ | `draft` | `boolean` | Kept in development, left out of the build |
37
+ | `keywords` | `string[]` | Keyword metadata, and weight in search |
38
+ | `author` | `string` | Author metadata |
39
+ | `ogImage` | `string \| false` | Social image for this page |
40
+ | `lastUpdated` | `date` | Modification date in metadata |
41
+
42
+ Fields JAAD does not know are ignored, so frontmatter your own tooling
43
+ reads can sit alongside these. A wrong type is a build error.
44
+
45
+ ## Naming
46
+
47
+ `title` names the page in metadata, breadcrumbs, search and the table of
48
+ contents. The filename still determines the URL, whatever the title says.
49
+
50
+ `label` is for pages whose title is too long for a sidebar entry. It changes
51
+ the sidebar, the mobile selectors and the previous/next links, and nothing
52
+ else:
53
+
54
+ ```markdown
55
+ ---
56
+ title: Frequently Asked Questions
57
+ label: FAQ
58
+ ---
59
+ ```
60
+
61
+ Without `title`, JAAD uses the first `# Heading`, then the filename.
62
+
63
+ `translationKey` pairs a page with its translations when their slugs differ.
64
+ See [Languages](03-i18n.md).
65
+
66
+ ## Ordering and drafts
67
+
68
+ `order` replaces the number a filename prefix supplies, so a page can move
69
+ without being renamed. Inside a chapter it moves the page within that chapter;
70
+ the chapter keeps the order of its own directory prefix.
71
+
72
+ ```markdown
73
+ ---
74
+ order: 0
75
+ ---
76
+ ```
77
+
78
+ A page ordered ahead of every other becomes the opening page at `routeBase`.
79
+
80
+ `draft` pages are served in development and left out of production builds:
81
+ they disappear from routes, navigation, search, the sitemap and `llms.txt`.
82
+ The file tree is still validated as a whole, so a draft that would collide
83
+ with another page is reported while it is being written.
84
+
85
+ ## Metadata
86
+
87
+ `description` is used for the description metadata, Open Graph, structured
88
+ data and `llms.txt`. Without it, JAAD uses the first paragraph of the page, followed
89
+ by the site description.
90
+
91
+ `keywords` become `<meta name="keywords">` and the `keywords` of the page's
92
+ structured data, and they rank a page in search below its chapter and above
93
+ its body. They are metadata, not a visible list: JAAD renders nothing for
94
+ them, though a frame of your own can, through
95
+ [`page.data`](08-advanced-layout.md).
96
+
97
+ `author` becomes `<meta name="author">` and the structured-data author.
98
+
99
+ `ogImage` overrides the site's social image for one page. It takes a public
100
+ path or an absolute URL, and `false` removes the image from that page. Local
101
+ paths need `site` to resolve, as elsewhere.
102
+
103
+ `lastUpdated` takes a date. It becomes `article:modified_time` and
104
+ `dateModified` in structured data, and is shown under the page, formatted for
105
+ its language.
@@ -0,0 +1,210 @@
1
+ ---
2
+ description: One documentation site per language, from locale directories under docs/.
3
+ keywords: [i18n, locales, translation, hreflang]
4
+ ---
5
+
6
+ # Languages
7
+
8
+ Name the directories directly under `docs/` after language codes and JAAD
9
+ builds one documentation site per language, with a switcher in the header.
10
+
11
+ ```
12
+ docs/
13
+ en/
14
+ 01-introduction.md → /
15
+ 02-guides/
16
+ 01-setup.md → /guides/setup
17
+ it/
18
+ 01-introduzione.md → /it
19
+ 02-guide/
20
+ 01-installazione.md → /it/guide/installazione
21
+ ```
22
+
23
+ Nothing needs configuring. With one language, or with no locale directory at
24
+ all, everything behaves exactly as it did before.
25
+
26
+ ## Detection
27
+
28
+ A directory is a locale when its name is an ISO 639-1 language, optionally with
29
+ a script and a region: `it`, `pt-BR`, `zh-Hans`. A three-letter directory such
30
+ as `api` is never a locale.
31
+
32
+ **Two directories make the tree localised.** A single one counts only when
33
+ `lang` names it — so `docs/en/` with `lang: "en"` is a first language you are
34
+ about to translate, while a lone `docs/it/` on an English site stays the
35
+ chapter an "IT" section depends on.
36
+
37
+ A locale directory with no markdown in it is not a language: it would be
38
+ offered in the switcher and then answer 404. It is dropped, and if that leaves
39
+ one language the documentation stays localised — the remaining directory is
40
+ still stripped from the URLs, so nothing moves.
41
+
42
+ Once the tree is localised, every entry under `docs/` has to be a locale
43
+ directory. A stray one stops the build and is named:
44
+
45
+ ```
46
+ jaad: mixed documentation tree
47
+ docs/guides is not a locale, but en, it are
48
+ Move every page under a locale directory, or set locales: false.
49
+ ```
50
+
51
+ The nesting limit applies inside each language, not to the tree as a whole:
52
+ `it/guides/setup.md` is a chapter inside Italian, and still only one level.
53
+
54
+ ## The default language
55
+
56
+ `lang` names the language that keeps the unprefixed URLs:
57
+
58
+ ```ts
59
+ defineJaadConfig({ title: 'My Project', lang: 'en' })
60
+ ```
61
+
62
+ `/guide` is English and `/it/guide` is Italian. Adding a second language to an
63
+ existing site therefore changes none of its URLs. `lang` must match one of the
64
+ directories, or the build stops and lists what it found.
65
+
66
+ ## Overriding detection
67
+
68
+ `locales` is only for when detection guesses wrong:
69
+
70
+ ```ts
71
+ defineJaadConfig({ title: 'My Project', locales: ['en', 'it'] })
72
+ defineJaadConfig({ title: 'My Project', locales: false })
73
+ ```
74
+
75
+ A list pins the set. `false` switches detection off, so every directory is a
76
+ chapter again.
77
+
78
+ ## Pairing translations
79
+
80
+ Two pages are translations of each other when their slugs match:
81
+ `en/guides/setup.md` and `it/guides/setup.md` both resolve to `guides/setup`.
82
+ That is the whole rule, and it is why nothing pairs when a language translates
83
+ its own file and directory names.
84
+
85
+ To translate the URLs too, give both files the same `translationKey`:
86
+
87
+ ```markdown
88
+ ---
89
+ translationKey: setup
90
+ ---
91
+ ```
92
+
93
+ ```
94
+ docs/en/02-handbook/01-setup.md → /handbook/setup
95
+ docs/it/02-guida/01-installazione.md → /it/guida/installazione
96
+ ```
97
+
98
+ With the key the two link to each other in the switcher and in `hreflang`;
99
+ without it neither would know the other existed. Two pages of one language
100
+ claiming the same key stop the build.
101
+
102
+ ## Untranslated pages
103
+
104
+ Each language has exactly the pages in its own directory. There is no fallback:
105
+ a page that exists only in English is not built under `/it`, does not appear in
106
+ the Italian sidebar, and is not in the Italian search index or `llms.txt`.
107
+
108
+ A language whose every page is a [draft](02-frontmatter.md)
109
+ empties out in the production build, and drops out of the switcher there too.
110
+
111
+ The switcher accounts for this. On a page with no counterpart in a language, it
112
+ links to that language's opening page rather than to a URL that would 404.
113
+
114
+ ## The switcher
115
+
116
+ It sits next to the theme switcher and shows the current language's flag and
117
+ code, with the languages' own names in the menu. It renders only when there is
118
+ more than one language.
119
+
120
+ Flags come from the region: explicit in `pt-BR`, and otherwise from the
121
+ language's usual one. A language with no usual region shows its code alone —
122
+ better than a wrong flag.
123
+
124
+ ## Metadata
125
+
126
+ Per-language metadata is handled for you:
127
+
128
+ | Tag | Value |
129
+ | ------------------------ | --------------------------------------- |
130
+ | `<html lang>` | The page's language |
131
+ | `og:locale` | The page's language |
132
+ | `og:locale:alternate` | Every language that has this page |
133
+ | `<link rel="alternate">` | `hreflang` per translation, `x-default` |
134
+
135
+ `hreflang` links need absolute URLs, so they are emitted only when `site` is
136
+ set, like `canonical`.
137
+
138
+ Everything in [frontmatter](02-frontmatter.md) is per file, so
139
+ `description`, `keywords` and the rest are already per language: write them in
140
+ the language of the file they sit in.
141
+
142
+ Each language also gets its own search index and `llms.txt`, at
143
+ `/it/llms.txt` and so on. Search only ever returns pages in the language the
144
+ reader is in.
145
+
146
+ ## The interface
147
+
148
+ JAAD ships its own interface in English and Italian. It picks the catalogue
149
+ from each page's locale automatically, so Italian documentation needs no UI
150
+ configuration. Regional locales inherit their base language: `it-IT` and
151
+ `it-CH` both use Italian.
152
+
153
+ Use `ui` only for wording you want to replace:
154
+
155
+ ```ts
156
+ defineJaadConfig({
157
+ title: 'My Project',
158
+ ui: {
159
+ it: {
160
+ 'search.trigger': 'Cerca…',
161
+ 'page.copy': 'Copia la pagina',
162
+ },
163
+ },
164
+ })
165
+ ```
166
+
167
+ Overrides are matched case-insensitively. An exact override comes first, then
168
+ one for the base language, then the bundled catalogue. A locale without a
169
+ bundled catalogue falls back to English. For example, `ui["it-IT"]` wins over
170
+ `ui.it`, while the latter also applies to `it-CH`.
171
+
172
+ An override can therefore stay partial without blanking or changing any other
173
+ label. These are all the keys and their English fallback values:
174
+
175
+ ```ts
176
+ ui: {
177
+ en: {
178
+ "breadcrumb.label": "Breadcrumb",
179
+ home: "Home",
180
+ "locale.change": "Change language",
181
+ "nav.documentation": "Documentation navigation",
182
+ "nav.mobile": "Toggle mobile menu",
183
+ "nav.page": "Page navigation",
184
+ "page.copied": "Copied!",
185
+ "page.copy": "Copy page",
186
+ "page.edit": "Edit this page",
187
+ "page.lastUpdated": "Last updated on",
188
+ "search.all": "All",
189
+ "search.close": "close",
190
+ "search.empty": "No results for",
191
+ "search.label": "Search documentation",
192
+ "search.loading": "Loading...",
193
+ "search.navigate": "navigate",
194
+ "search.open": "open",
195
+ "search.placeholder": "Search documentation...",
196
+ "search.results": "Search results",
197
+ "search.sections": "Search in",
198
+ "search.trigger": "Search docs...",
199
+ "theme.toggle": "Toggle color theme",
200
+ "toc.label": "Table of contents",
201
+ "toc.title": "On this page",
202
+ },
203
+ },
204
+ ```
205
+
206
+ To add another bundled language, see the
207
+ [translation contribution guide](https://github.com/jaamd/jaamd/blob/main/CONTRIBUTING.md#translating-the-interface).
208
+
209
+ Your documentation, its navigation, its chapter names and its metadata come
210
+ from your files and are already in whatever language you wrote them.
@@ -0,0 +1,58 @@
1
+ ---
2
+ description: What JAAD's search indexes, how it ranks results, and the keyboard shortcuts.
3
+ ---
4
+
5
+ # Search
6
+
7
+ Every JAAD site has full-text search, with no configuration and no external
8
+ service. Readers open it from the header or with <kbd>Ctrl</kbd>+<kbd>K</kbd>
9
+ (<kbd>⌘</kbd>+<kbd>K</kbd> on macOS).
10
+
11
+ ## What is indexed
12
+
13
+ The build cuts every page at its `##` and `###` headings and indexes each part
14
+ with:
15
+
16
+ - the page title, its chapter and its `keywords`;
17
+ - the heading;
18
+ - the text below it, excluding code blocks, images and directives.
19
+
20
+ Drafts are left out of production builds. The index is emitted at
21
+ `<routeBase>/search-index.json`, one per language, loaded on first use and
22
+ cached for the session. It holds the text of every page, so its size grows with
23
+ the documentation.
24
+
25
+ ## How results are found
26
+
27
+ - Every word of the query must appear in a part of a page or in the page's
28
+ title, chapter or keywords.
29
+ - A word also matches the words it starts: `config` finds `configuration`.
30
+ - Case and accents are ignored: `citta` finds `città`.
31
+ - A match in the title ranks first, then the heading, the keywords, the
32
+ chapter and the text.
33
+
34
+ Results are grouped by page. Under each page are the headings that matched,
35
+ and choosing one opens the page at that heading.
36
+
37
+ With an empty query, search lists the first pages of the documentation. When
38
+ the docs have [sections](../01-getting-started/02-pages.md#sections), it lists
39
+ the first pages of each, and buttons above the results limit the search to one
40
+ section.
41
+
42
+ ## Keyboard shortcuts
43
+
44
+ | Where | Keys | Action |
45
+ | ------ | --------------------------------------------------------- | ----------------------- |
46
+ | Search | <kbd>Ctrl</kbd>+<kbd>K</kbd> or <kbd>⌘</kbd>+<kbd>K</kbd> | Open the search palette |
47
+ | Search | <kbd>↑</kbd> <kbd>↓</kbd> | Select a result |
48
+ | Search | <kbd>Enter</kbd> | Open the result |
49
+ | Search | <kbd>Esc</kbd> | Close the palette |
50
+ | Page | <kbd>←</kbd> | Open the previous page |
51
+ | Page | <kbd>→</kbd> | Open the next page |
52
+
53
+ The page shortcuts are off while:
54
+
55
+ - an input, textarea, select or editable element has focus;
56
+ - the focus is inside a sideways-scrollable area, such as a wide table or code
57
+ block;
58
+ - a modifier key is held.
@@ -0,0 +1,104 @@
1
+ ---
2
+ description: Named themes, a fixed appearance, code themes and custom palettes.
3
+ ---
4
+
5
+ # Themes
6
+
7
+ Dark mode works without configuration. The default `appearance: "auto"`
8
+ follows the reader's system preference and shows a switcher.
9
+
10
+ ## Named themes
11
+
12
+ ```ts
13
+ defineJaadConfig({ title: 'My Project', theme: 'dracula' })
14
+ ```
15
+
16
+ | Name | Light | Dark |
17
+ | ---------------- | ------------- | ------------ |
18
+ | `default` | Paper | GitHub Dark |
19
+ | `catppuccin` | Latte | Mocha |
20
+ | `gruvbox` | Gruvbox Light | Gruvbox Dark |
21
+ | `rose-pine` | Dawn | Rosé Pine |
22
+ | `rose-pine-moon` | Dawn | Moon |
23
+ | `dracula` | Dracula | Dracula |
24
+ | `nord` | Nord | Nord |
25
+ | `one-dark` | One Dark | One Dark |
26
+ | `tokyo-night` | Tokyo Night | Tokyo Night |
27
+
28
+ Unknown names stop the build. Themes without a light palette stay dark in both
29
+ modes; use `appearance: "dark"` for a consistently dark site.
30
+
31
+ ## Fixed appearance
32
+
33
+ ```ts
34
+ defineJaadConfig({
35
+ title: 'My Project',
36
+ theme: 'tokyo-night',
37
+ appearance: 'dark',
38
+ })
39
+ ```
40
+
41
+ `"light"` and `"dark"` remove the switcher and the client-side preference
42
+ script. The default is `"auto"`.
43
+
44
+ ## Code theme only
45
+
46
+ Pass a [Shiki](https://shiki.style/themes) pair to change syntax highlighting
47
+ without changing the interface colours:
48
+
49
+ ```ts
50
+ defineJaadConfig({
51
+ title: 'My Project',
52
+ theme: { light: 'github-light', dark: 'github-dark' },
53
+ })
54
+ ```
55
+
56
+ ## Custom themes
57
+
58
+ Set theme seeds in `src/jaad.css`:
59
+
60
+ ```css
61
+ :root,
62
+ html.dark {
63
+ --color-background: #1e1e2e;
64
+ --color-surface: #313244;
65
+ --color-foreground: #cdd6f4;
66
+ --color-foreground-bright: #f5f5f5;
67
+ --color-primary: #89b4fa;
68
+ --color-error: #f38ba8;
69
+ --color-warning: #f9e2af;
70
+ --color-info: #89dceb;
71
+ --color-success: #a6e3a1;
72
+ }
73
+ ```
74
+
75
+ Use `:root` for light mode and `html.dark` for dark mode. Override individual
76
+ `--jaamd-` tokens only when a palette needs values that cannot derive from the
77
+ seeds.
78
+
79
+ ## Sharing the theme with your own pages
80
+
81
+ [Pages of your own](07-custom-pages.md) use your layout, not
82
+ JAAD's. Two values keep both halves of a site in step:
83
+
84
+ | What | Value |
85
+ | ------------------------- | ----------------------------- |
86
+ | Class on `<html>` in dark | `dark` |
87
+ | Stored preference | `localStorage["theme"]` |
88
+ | Stored values | `"dark"` / `"light"` |
89
+ | No stored value | follow `prefers-color-scheme` |
90
+
91
+ Apply the class in the `<head>`, before anything paints:
92
+
93
+ ```astro
94
+ <script is:inline>
95
+ ;(function () {
96
+ var t = localStorage.getItem('theme')
97
+ var dark = t === 'dark' || (!t && matchMedia('(prefers-color-scheme: dark)').matches)
98
+ document.documentElement.classList.toggle('dark', dark)
99
+ })()
100
+ </script>
101
+ ```
102
+
103
+ Write `"dark"` or `"light"` to that key from your own switcher. JAAD reads it
104
+ again on the next documentation page.
@@ -0,0 +1,156 @@
1
+ ---
2
+ description: Colours, fonts and widths as CSS custom properties in src/jaad.css, and Tailwind.
3
+ ---
4
+
5
+ # Styles
6
+
7
+ JAAD's look is a set of CSS custom properties. Override them in
8
+ `src/jaad.css`, which loads after the bundled stylesheet on documentation pages
9
+ and on pages using `Page`:
10
+
11
+ ```css
12
+ :root {
13
+ --color-primary: #3b5bdb;
14
+ --color-background: #ffffff;
15
+ }
16
+
17
+ html.dark {
18
+ --color-primary: #748ffc;
19
+ --color-background: #0d1117;
20
+ }
21
+ ```
22
+
23
+ JAAD ships its stylesheet compiled and adds nothing to your project. Use any
24
+ CSS for pages of your own.
25
+
26
+ ## Colour tokens
27
+
28
+ | Token | Purpose |
29
+ | -------------------- | -------------------------------- |
30
+ | `--color-background` | Page background |
31
+ | `--color-foreground` | Body text |
32
+ | `--color-primary` | Links, accents and active states |
33
+ | `--color-surface` | Raised surfaces |
34
+ | `--color-border` | Separators and outlines |
35
+
36
+ The complete groups are:
37
+
38
+ - Backgrounds: `--color-background`, `--color-background-secondary`,
39
+ `--color-background-tertiary`, `--color-surface`, `--color-surface-hover`.
40
+ - Text: `--color-foreground`, `--color-foreground-secondary`,
41
+ `--color-foreground-muted`, `--color-foreground-bright`.
42
+ - Accent: `--color-primary`, `--color-primary-dark`, `--color-primary-light`.
43
+ - Borders: `--color-border`, `--color-border-light`, `--color-border-dark`.
44
+ - Status: `--color-error`, `--color-warning`, `--color-info`, `--color-success`.
45
+
46
+ The rendered Markdown follows these colours. To change it alone, set JAAMD's
47
+ `--jaamd-*` [variables](../../../astro/docs/04-styling/01-variables.md). For a
48
+ whole palette, see [Themes](05-themes.md).
49
+
50
+ ## Fonts
51
+
52
+ JAAD uses self-hosted Inter for the interface and Merriweather for headings.
53
+ Three tokens choose the families:
54
+
55
+ ```css
56
+ :root {
57
+ --font-sans: 'IBM Plex Sans', system-ui, sans-serif;
58
+ --font-serif: 'IBM Plex Serif', Georgia, serif;
59
+ --font-mono: 'IBM Plex Mono', monospace;
60
+ }
61
+ ```
62
+
63
+ A token does not load the font. Add the family with Astro's font
64
+ configuration, then point the token at its CSS variable:
65
+
66
+ ```ts
67
+ // jaad.config.ts
68
+ import { defineJaadConfig } from '@jaamd/jaad'
69
+ import { fontProviders } from 'astro/config'
70
+
71
+ export default defineJaadConfig({
72
+ title: 'My Project',
73
+ astro: {
74
+ fonts: [
75
+ {
76
+ provider: fontProviders.google(),
77
+ name: 'IBM Plex Sans',
78
+ cssVariable: '--font-plex',
79
+ weights: [400, 600],
80
+ },
81
+ ],
82
+ },
83
+ })
84
+ ```
85
+
86
+ ```css
87
+ :root {
88
+ --font-sans: var(--font-plex), system-ui, sans-serif;
89
+ }
90
+ ```
91
+
92
+ For system fonts only, point the tokens at a system stack. JAAD's bundled
93
+ fonts are still downloaded during the build even when unused.
94
+
95
+ ## Layout tokens
96
+
97
+ | Token | Default |
98
+ | ---------------------- | ------------------------------------------------- |
99
+ | `--jaad-chrome-width` | content, both sidebars and their gaps |
100
+ | `--jaad-content-width` | `56rem`, the most the page column takes |
101
+ | `--jaad-sidebar-width` | `16rem`, the navigation and the table of contents |
102
+ | `--jaad-page-padding` | `2rem`, on each side of the page |
103
+ | `--jaad-header-height` | `4.25rem`, the fixed header |
104
+
105
+ `--jaad-chrome-width` is the column the header, the sidebars and the page share.
106
+ The header and the two sidebars are fixed to the window, and only the page
107
+ scrolls; raise `--jaad-header-height` along with a logo taller than the header.
108
+ Set it to fit the documentation to the width of the rest of a site; the page
109
+ column takes what the sidebars leave, up to `--jaad-content-width`:
110
+
111
+ ```css
112
+ :root {
113
+ --jaad-chrome-width: 80rem;
114
+ --jaad-sidebar-width: 14rem;
115
+ }
116
+ ```
117
+
118
+ Use [Advanced layout](08-advanced-layout.md) when token changes are not
119
+ enough.
120
+
121
+ ## Tailwind
122
+
123
+ :::code-tabs
124
+
125
+ ```bash npm
126
+ npm i -D tailwindcss @tailwindcss/vite
127
+ ```
128
+
129
+ ```bash pnpm
130
+ pnpm add -D tailwindcss @tailwindcss/vite
131
+ ```
132
+
133
+ ```bash yarn
134
+ yarn add -D tailwindcss @tailwindcss/vite
135
+ ```
136
+
137
+ ```bash bun
138
+ bun add -d tailwindcss @tailwindcss/vite
139
+ ```
140
+
141
+ :::
142
+
143
+ ```ts
144
+ // jaad.config.ts
145
+ defineJaadConfig({ title: 'My Project', tailwind: true })
146
+ ```
147
+
148
+ JAAD registers the plugin, unless `astro.vite.plugins` already has it.
149
+
150
+ - Applies to documentation pages, pages using `Page` and a custom `DocsFrame`.
151
+ - Colours and fonts follow JAAD's tokens: `bg-surface`, `border-border-light`,
152
+ `font-mono`.
153
+ - `dark:` follows JAAD's theme switch.
154
+ - Layout tokens via arbitrary values: `max-w-(--jaad-chrome-width)`.
155
+ - Pages on a local layout get plain Tailwind (no JAAD tokens) by adding
156
+ `@import "tailwindcss";` to their CSS.