honkit-plugin-theme-learnj 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.
- package/LICENSE +21 -0
- package/README.md +78 -0
- package/_assets/website/learnj.css +1 -0
- package/_assets/website/learnj.js +111 -0
- package/_i18n/en.json +22 -0
- package/_layouts/layout.html +41 -0
- package/_layouts/website/header.html +25 -0
- package/_layouts/website/layout.html +18 -0
- package/_layouts/website/page.html +101 -0
- package/_layouts/website/summary.html +71 -0
- package/index.js +9 -0
- package/package.json +74 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 LearnJ
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
# honkit-plugin-theme-learnj
|
|
2
|
+
|
|
3
|
+
LearnJ HonKit theme built with **Tailwind CSS** and **shadcn/ui** design tokens.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install honkit-plugin-theme-learnj --save-dev
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Usage
|
|
12
|
+
|
|
13
|
+
In your book's `book.json`:
|
|
14
|
+
|
|
15
|
+
```json
|
|
16
|
+
{
|
|
17
|
+
"plugins": [
|
|
18
|
+
"-theme-default",
|
|
19
|
+
"theme-learnj"
|
|
20
|
+
],
|
|
21
|
+
"pluginsConfig": {
|
|
22
|
+
"theme-learnj": {
|
|
23
|
+
"logoText": "LearnJ Workshop",
|
|
24
|
+
"githubUrl": "https://github.com/learnj-ai/workshops",
|
|
25
|
+
"showLevel": false
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
Load `theme-learnj` **last** in the plugins array. Disable the default theme with `-theme-default`.
|
|
32
|
+
|
|
33
|
+
## Configuration
|
|
34
|
+
|
|
35
|
+
| Option | Type | Description |
|
|
36
|
+
|--------|------|-------------|
|
|
37
|
+
| `logo` | string | Logo image URL for sidebar |
|
|
38
|
+
| `logoText` | string | Sidebar title (default: book title) |
|
|
39
|
+
| `githubUrl` | string | GitHub link in sidebar footer |
|
|
40
|
+
| `showLevel` | boolean | Show chapter level numbers in TOC |
|
|
41
|
+
|
|
42
|
+
## Development
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
git clone https://github.com/learnj-ai/honkit-plugin-theme-learnj.git
|
|
46
|
+
cd honkit-plugin-theme-learnj
|
|
47
|
+
npm install
|
|
48
|
+
npm run build:css
|
|
49
|
+
npm run watch # optional: rebuild CSS on change
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
To test locally in a HonKit book:
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
npm link
|
|
56
|
+
cd /path/to/your/book
|
|
57
|
+
npm link honkit-plugin-theme-learnj
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
## shadcn / Tailwind
|
|
61
|
+
|
|
62
|
+
HonKit renders static HTML, so this theme uses shadcn's **design tokens and utility patterns** (`learnj-btn`, `learnj-nav-link`, etc.) rather than React components.
|
|
63
|
+
|
|
64
|
+
Customize colors in `src/learnj.css` (`:root` / `.dark` variables), then run `npm run build:css`.
|
|
65
|
+
|
|
66
|
+
## Publishing
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
npm login
|
|
70
|
+
npm run build
|
|
71
|
+
npm publish
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
The `prepublishOnly` hook rebuilds CSS before each publish.
|
|
75
|
+
|
|
76
|
+
## License
|
|
77
|
+
|
|
78
|
+
MIT
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
*,:after,:before{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgba(59,130,246,.5);--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }::backdrop{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgba(59,130,246,.5);--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }/*! tailwindcss v3.4.19 | MIT License | https://tailwindcss.com*/*,:after,:before{box-sizing:border-box;border:0 solid #e5e7eb}:after,:before{--tw-content:""}:host,html{line-height:1.5;-webkit-text-size-adjust:100%;-moz-tab-size:4;-o-tab-size:4;tab-size:4;font-family:Inter,ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,sans-serif;font-feature-settings:normal;font-variation-settings:normal;-webkit-tap-highlight-color:transparent}body{margin:0;line-height:inherit}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,pre,samp{font-family:JetBrains Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-feature-settings:normal;font-variation-settings:normal;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}button,input,optgroup,select,textarea{font-family:inherit;font-feature-settings:inherit;font-variation-settings:inherit;font-size:100%;font-weight:inherit;line-height:inherit;letter-spacing:inherit;color:inherit;margin:0;padding:0}button,select{text-transform:none}button,input:where([type=button]),input:where([type=reset]),input:where([type=submit]){-webkit-appearance:button;background-color:transparent;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:baseline}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dd,dl,figure,h1,h2,h3,h4,h5,h6,hr,p,pre{margin:0}fieldset{margin:0}fieldset,legend{padding:0}menu,ol,ul{list-style:none;margin:0;padding:0}dialog{padding:0}textarea{resize:vertical}input::-moz-placeholder,textarea::-moz-placeholder{opacity:1;color:#9ca3af}input::placeholder,textarea::placeholder{opacity:1;color:#9ca3af}[role=button],button{cursor:pointer}:disabled{cursor:default}audio,canvas,embed,iframe,img,object,svg,video{display:block;vertical-align:middle}img,video{max-width:100%;height:auto}[hidden]:where(:not([hidden=until-found])){display:none}:root{--background:0 0% 100%;--foreground:240 10% 3.9%;--card:0 0% 100%;--card-foreground:240 10% 3.9%;--popover:0 0% 100%;--popover-foreground:240 10% 3.9%;--primary:240 5.9% 10%;--primary-foreground:0 0% 98%;--secondary:240 4.8% 95.9%;--secondary-foreground:240 5.9% 10%;--muted:240 4.8% 95.9%;--muted-foreground:240 3.8% 46.1%;--accent:240 4.8% 95.9%;--accent-foreground:240 5.9% 10%;--destructive:0 84.2% 60.2%;--destructive-foreground:0 0% 98%;--border:240 5.9% 90%;--input:240 5.9% 90%;--ring:240 5.9% 10%;--radius:0.5rem;--sidebar-background:0 0% 98%;--sidebar-foreground:240 5.3% 26.1%;--sidebar-primary:240 5.9% 10%;--sidebar-primary-foreground:0 0% 98%;--sidebar-accent:240 4.8% 95.9%;--sidebar-accent-foreground:240 5.9% 10%;--sidebar-border:220 13% 91%;--sidebar-ring:217.2 91.2% 59.8%}.dark{--background:240 10% 3.9%;--foreground:0 0% 98%;--card:240 10% 3.9%;--card-foreground:0 0% 98%;--popover:240 10% 3.9%;--popover-foreground:0 0% 98%;--primary:0 0% 98%;--primary-foreground:240 5.9% 10%;--secondary:240 3.7% 15.9%;--secondary-foreground:0 0% 98%;--muted:240 3.7% 15.9%;--muted-foreground:240 5% 64.9%;--accent:240 3.7% 15.9%;--accent-foreground:0 0% 98%;--destructive:0 62.8% 30.6%;--destructive-foreground:0 0% 98%;--border:240 3.7% 15.9%;--input:240 3.7% 15.9%;--ring:240 4.9% 83.9%;--sidebar-background:240 5.9% 10%;--sidebar-foreground:240 4.8% 95.9%;--sidebar-primary:224.3 76.3% 48%;--sidebar-primary-foreground:0 0% 100%;--sidebar-accent:240 3.7% 15.9%;--sidebar-accent-foreground:240 4.8% 95.9%;--sidebar-border:240 3.7% 15.9%;--sidebar-ring:217.2 91.2% 59.8%}*{border-color:hsl(var(--border))}body{background-color:hsl(var(--background));color:hsl(var(--foreground));-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.prose{color:var(--tw-prose-body);max-width:none}.prose :where(p):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:1.25em;margin-bottom:1.25em}.prose :where([class~=lead]):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-lead);font-size:1.25em;line-height:1.6;margin-top:1.2em;margin-bottom:1.2em}.prose :where(a):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-links);text-decoration:underline;font-weight:500}.prose :where(strong):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-bold);font-weight:600}.prose :where(a strong):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit}.prose :where(blockquote strong):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit}.prose :where(thead th strong):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit}.prose :where(ol):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:decimal;margin-top:1.25em;margin-bottom:1.25em;padding-inline-start:1.625em}.prose :where(ol[type=A]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:upper-alpha}.prose :where(ol[type=a]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:lower-alpha}.prose :where(ol[type=A s]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:upper-alpha}.prose :where(ol[type=a s]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:lower-alpha}.prose :where(ol[type=I]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:upper-roman}.prose :where(ol[type=i]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:lower-roman}.prose :where(ol[type=I s]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:upper-roman}.prose :where(ol[type=i s]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:lower-roman}.prose :where(ol[type="1"]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:decimal}.prose :where(ul):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:disc;margin-top:1.25em;margin-bottom:1.25em;padding-inline-start:1.625em}.prose :where(ol>li):not(:where([class~=not-prose],[class~=not-prose] *))::marker{font-weight:400;color:var(--tw-prose-counters)}.prose :where(ul>li):not(:where([class~=not-prose],[class~=not-prose] *))::marker{color:var(--tw-prose-bullets)}.prose :where(dt):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-headings);font-weight:600;margin-top:1.25em}.prose :where(hr):not(:where([class~=not-prose],[class~=not-prose] *)){border-color:var(--tw-prose-hr);border-top-width:1px;margin-top:3em;margin-bottom:3em}.prose :where(blockquote):not(:where([class~=not-prose],[class~=not-prose] *)){font-weight:500;font-style:italic;color:var(--tw-prose-quotes);border-inline-start-width:.25rem;border-inline-start-color:var(--tw-prose-quote-borders);quotes:"\201C""\201D""\2018""\2019";margin-top:1.6em;margin-bottom:1.6em;padding-inline-start:1em;border-left-color:hsl(var(--primary));background-color:hsl(var(--muted));border-radius:calc(var(--radius) - 2px);padding:.5em 1em}.prose :where(blockquote p:first-of-type):not(:where([class~=not-prose],[class~=not-prose] *)):before{content:open-quote}.prose :where(blockquote p:last-of-type):not(:where([class~=not-prose],[class~=not-prose] *)):after{content:close-quote}.prose :where(h1):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-headings);font-weight:800;font-size:2.25em;margin-top:0;margin-bottom:.8888889em;line-height:1.1111111}.prose :where(h1 strong):not(:where([class~=not-prose],[class~=not-prose] *)){font-weight:900;color:inherit}.prose :where(h2):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-headings);font-weight:700;font-size:1.5em;margin-top:2em;margin-bottom:1em;line-height:1.3333333}.prose :where(h2 strong):not(:where([class~=not-prose],[class~=not-prose] *)){font-weight:800;color:inherit}.prose :where(h3):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-headings);font-weight:600;font-size:1.25em;margin-top:1.6em;margin-bottom:.6em;line-height:1.6}.prose :where(h3 strong):not(:where([class~=not-prose],[class~=not-prose] *)){font-weight:700;color:inherit}.prose :where(h4):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-headings);font-weight:600;margin-top:1.5em;margin-bottom:.5em;line-height:1.5}.prose :where(h4 strong):not(:where([class~=not-prose],[class~=not-prose] *)){font-weight:700;color:inherit}.prose :where(img):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:2em;margin-bottom:2em}.prose :where(picture):not(:where([class~=not-prose],[class~=not-prose] *)){display:block;margin-top:2em;margin-bottom:2em}.prose :where(video):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:2em;margin-bottom:2em}.prose :where(kbd):not(:where([class~=not-prose],[class~=not-prose] *)){font-weight:500;font-family:inherit;color:var(--tw-prose-kbd);box-shadow:0 0 0 1px var(--tw-prose-kbd-shadows),0 3px 0 var(--tw-prose-kbd-shadows);font-size:.875em;border-radius:.3125rem;padding-top:.1875em;padding-inline-end:.375em;padding-bottom:.1875em;padding-inline-start:.375em}.prose :where(code):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-code);font-weight:500;font-size:.875em;background-color:hsl(var(--muted));padding:.2em .4em;border-radius:calc(var(--radius) - 4px)}.prose :where(code):not(:where([class~=not-prose],[class~=not-prose] *)):before{content:""}.prose :where(code):not(:where([class~=not-prose],[class~=not-prose] *)):after{content:""}.prose :where(a code):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit}.prose :where(h1 code):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit}.prose :where(h2 code):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit;font-size:.875em}.prose :where(h3 code):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit;font-size:.9em}.prose :where(h4 code):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit}.prose :where(blockquote code):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit}.prose :where(thead th code):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit}.prose :where(pre):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-pre-code);background-color:hsl(var(--muted));overflow-x:auto;font-weight:400;font-size:.875em;line-height:1.7142857;margin-top:1.7142857em;margin-bottom:1.7142857em;border-radius:var(--radius);padding-top:.8571429em;padding-inline-end:1.1428571em;padding-bottom:.8571429em;padding-inline-start:1.1428571em;border:1px solid hsl(var(--border))}.prose :where(pre code):not(:where([class~=not-prose],[class~=not-prose] *)){background-color:transparent;border-width:0;border-radius:0;padding:0;font-weight:inherit;color:inherit;font-size:inherit;font-family:inherit;line-height:inherit}.prose :where(pre code):not(:where([class~=not-prose],[class~=not-prose] *)):before{content:none}.prose :where(pre code):not(:where([class~=not-prose],[class~=not-prose] *)):after{content:none}.prose :where(table):not(:where([class~=not-prose],[class~=not-prose] *)){width:100%;table-layout:auto;margin-top:2em;margin-bottom:2em;font-size:.875em;line-height:1.7142857}.prose :where(thead):not(:where([class~=not-prose],[class~=not-prose] *)){border-bottom-width:1px;border-bottom-color:var(--tw-prose-th-borders)}.prose :where(thead th):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-headings);font-weight:600;vertical-align:bottom;padding-inline-end:.5714286em;padding-bottom:.5714286em;padding-inline-start:.5714286em;background-color:hsl(var(--muted))}.prose :where(tbody tr):not(:where([class~=not-prose],[class~=not-prose] *)){border-bottom-width:1px;border-bottom-color:var(--tw-prose-td-borders)}.prose :where(tbody tr:last-child):not(:where([class~=not-prose],[class~=not-prose] *)){border-bottom-width:0}.prose :where(tbody td):not(:where([class~=not-prose],[class~=not-prose] *)){vertical-align:baseline}.prose :where(tfoot):not(:where([class~=not-prose],[class~=not-prose] *)){border-top-width:1px;border-top-color:var(--tw-prose-th-borders)}.prose :where(tfoot td):not(:where([class~=not-prose],[class~=not-prose] *)){vertical-align:top}.prose :where(th,td):not(:where([class~=not-prose],[class~=not-prose] *)){text-align:start}.prose :where(figure>*):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:0;margin-bottom:0}.prose :where(figcaption):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-captions);font-size:.875em;line-height:1.4285714;margin-top:.8571429em}.prose{--tw-prose-body:hsl(var(--foreground));--tw-prose-headings:hsl(var(--foreground));--tw-prose-lead:#4b5563;--tw-prose-links:hsl(var(--primary));--tw-prose-bold:#111827;--tw-prose-counters:#6b7280;--tw-prose-bullets:#d1d5db;--tw-prose-hr:#e5e7eb;--tw-prose-quotes:#111827;--tw-prose-quote-borders:#e5e7eb;--tw-prose-captions:#6b7280;--tw-prose-kbd:#111827;--tw-prose-kbd-shadows:rgba(17,24,39,.1);--tw-prose-code:hsl(var(--foreground));--tw-prose-pre-code:#e5e7eb;--tw-prose-pre-bg:#1f2937;--tw-prose-th-borders:#d1d5db;--tw-prose-td-borders:#e5e7eb;--tw-prose-invert-body:#d1d5db;--tw-prose-invert-headings:#fff;--tw-prose-invert-lead:#9ca3af;--tw-prose-invert-links:#fff;--tw-prose-invert-bold:#fff;--tw-prose-invert-counters:#9ca3af;--tw-prose-invert-bullets:#4b5563;--tw-prose-invert-hr:#374151;--tw-prose-invert-quotes:#f3f4f6;--tw-prose-invert-quote-borders:#374151;--tw-prose-invert-captions:#9ca3af;--tw-prose-invert-kbd:#fff;--tw-prose-invert-kbd-shadows:hsla(0,0%,100%,.1);--tw-prose-invert-code:#fff;--tw-prose-invert-pre-code:#d1d5db;--tw-prose-invert-pre-bg:rgba(0,0,0,.5);--tw-prose-invert-th-borders:#4b5563;--tw-prose-invert-td-borders:#374151;font-size:1rem;line-height:1.75}.prose :where(picture>img):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:0;margin-bottom:0}.prose :where(li):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:.5em;margin-bottom:.5em}.prose :where(ol>li):not(:where([class~=not-prose],[class~=not-prose] *)){padding-inline-start:.375em}.prose :where(ul>li):not(:where([class~=not-prose],[class~=not-prose] *)){padding-inline-start:.375em}.prose :where(.prose>ul>li p):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:.75em;margin-bottom:.75em}.prose :where(.prose>ul>li>p:first-child):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:1.25em}.prose :where(.prose>ul>li>p:last-child):not(:where([class~=not-prose],[class~=not-prose] *)){margin-bottom:1.25em}.prose :where(.prose>ol>li>p:first-child):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:1.25em}.prose :where(.prose>ol>li>p:last-child):not(:where([class~=not-prose],[class~=not-prose] *)){margin-bottom:1.25em}.prose :where(ul ul,ul ol,ol ul,ol ol):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:.75em;margin-bottom:.75em}.prose :where(dl):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:1.25em;margin-bottom:1.25em}.prose :where(dd):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:.5em;padding-inline-start:1.625em}.prose :where(hr+*):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:0}.prose :where(h2+*):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:0}.prose :where(h3+*):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:0}.prose :where(h4+*):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:0}.prose :where(thead th:first-child):not(:where([class~=not-prose],[class~=not-prose] *)){padding-inline-start:0}.prose :where(thead th:last-child):not(:where([class~=not-prose],[class~=not-prose] *)){padding-inline-end:0}.prose :where(tbody td,tfoot td):not(:where([class~=not-prose],[class~=not-prose] *)){padding-top:.5714286em;padding-inline-end:.5714286em;padding-bottom:.5714286em;padding-inline-start:.5714286em}.prose :where(tbody td:first-child,tfoot td:first-child):not(:where([class~=not-prose],[class~=not-prose] *)){padding-inline-start:0}.prose :where(tbody td:last-child,tfoot td:last-child):not(:where([class~=not-prose],[class~=not-prose] *)){padding-inline-end:0}.prose :where(figure):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:2em;margin-bottom:2em}.prose :where(.prose>:first-child):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:0}.prose :where(.prose>:last-child):not(:where([class~=not-prose],[class~=not-prose] *)){margin-bottom:0}.prose-slate{--tw-prose-body:#334155;--tw-prose-headings:#0f172a;--tw-prose-lead:#475569;--tw-prose-links:#0f172a;--tw-prose-bold:#0f172a;--tw-prose-counters:#64748b;--tw-prose-bullets:#cbd5e1;--tw-prose-hr:#e2e8f0;--tw-prose-quotes:#0f172a;--tw-prose-quote-borders:#e2e8f0;--tw-prose-captions:#64748b;--tw-prose-kbd:#0f172a;--tw-prose-kbd-shadows:rgba(15,23,42,.1);--tw-prose-code:#0f172a;--tw-prose-pre-code:#e2e8f0;--tw-prose-pre-bg:#1e293b;--tw-prose-th-borders:#cbd5e1;--tw-prose-td-borders:#e2e8f0;--tw-prose-invert-body:#cbd5e1;--tw-prose-invert-headings:#fff;--tw-prose-invert-lead:#94a3b8;--tw-prose-invert-links:#fff;--tw-prose-invert-bold:#fff;--tw-prose-invert-counters:#94a3b8;--tw-prose-invert-bullets:#475569;--tw-prose-invert-hr:#334155;--tw-prose-invert-quotes:#f1f5f9;--tw-prose-invert-quote-borders:#334155;--tw-prose-invert-captions:#94a3b8;--tw-prose-invert-kbd:#fff;--tw-prose-invert-kbd-shadows:hsla(0,0%,100%,.1);--tw-prose-invert-code:#fff;--tw-prose-invert-pre-code:#cbd5e1;--tw-prose-invert-pre-bg:rgba(0,0,0,.5);--tw-prose-invert-th-borders:#475569;--tw-prose-invert-td-borders:#334155}.learnj-nav-link{display:flex;width:100%;align-items:center;gap:.5rem;border-radius:calc(var(--radius) - 2px);padding:.5rem .75rem;font-size:.875rem;line-height:1.25rem;font-weight:500;color:hsl(var(--sidebar-foreground));transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.learnj-nav-link.active,.learnj-nav-link:hover{background-color:hsl(var(--sidebar-accent));color:hsl(var(--sidebar-accent-foreground))}.learnj-nav-link.active{font-weight:600}.learnj-nav-section{padding:.5rem .75rem;font-size:.75rem;line-height:1rem;font-weight:600;text-transform:uppercase;letter-spacing:.05em;color:hsl(var(--muted-foreground))}.learnj-btn-ghost{display:inline-flex;align-items:center;justify-content:center;gap:.5rem;white-space:nowrap;border-radius:calc(var(--radius) - 2px);font-size:.875rem;line-height:1.25rem;font-weight:500;--tw-ring-offset-color:hsl(var(--background));transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.learnj-btn-ghost:focus-visible{outline:2px solid transparent;outline-offset:2px;--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000);--tw-ring-color:hsl(var(--ring));--tw-ring-offset-width:2px}.learnj-btn-ghost:disabled{pointer-events:none;opacity:.5}.learnj-btn-ghost{height:2.25rem;width:2.25rem}.learnj-btn-ghost:hover{background-color:hsl(var(--accent));color:hsl(var(--accent-foreground))}.learnj-btn-outline{display:inline-flex;align-items:center;justify-content:center;gap:.5rem;white-space:nowrap;border-radius:calc(var(--radius) - 2px);font-size:.875rem;line-height:1.25rem;font-weight:500;--tw-ring-offset-color:hsl(var(--background));transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.learnj-btn-outline:focus-visible{outline:2px solid transparent;outline-offset:2px;--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000);--tw-ring-color:hsl(var(--ring));--tw-ring-offset-width:2px}.learnj-btn-outline:disabled{pointer-events:none;opacity:.5}.learnj-btn-outline{height:2.25rem;border-width:1px;border-color:hsl(var(--input));background-color:hsl(var(--background));padding:.5rem 1rem}.learnj-btn-outline:hover{background-color:hsl(var(--accent));color:hsl(var(--accent-foreground))}.learnj-badge-secondary{display:inline-flex;align-items:center;border-radius:.25rem;border-width:1px;padding:.125rem .625rem;font-size:.75rem;line-height:1rem;font-weight:600;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s;border-color:transparent;background-color:hsl(var(--secondary));color:hsl(var(--secondary-foreground))}.fixed{position:fixed}.sticky{position:sticky}.inset-y-0{top:0;bottom:0}.left-0{left:0}.top-0{top:0}.z-30{z-index:30}.z-50{z-index:50}.mx-auto{margin-left:auto;margin-right:auto}.my-2{margin-top:.5rem;margin-bottom:.5rem}.ml-3{margin-left:.75rem}.mr-1{margin-right:.25rem}.mt-auto{margin-top:auto}.block{display:block}.flex{display:flex}.contents{display:contents}.hidden{display:none}.h-14{height:3.5rem}.h-8{height:2rem}.h-full{height:100%}.min-h-full{min-height:100%}.min-h-screen{min-height:100vh}.w-8{width:2rem}.w-\[280px\]{width:280px}.min-w-0{min-width:0}.max-w-4xl{max-width:56rem}.max-w-\[85vw\]{max-width:85vw}.max-w-none{max-width:none}.flex-1{flex:1 1 0%}.shrink-0{flex-shrink:0}.-translate-x-full{--tw-translate-x:-100%}.-translate-x-full,.translate-x-0{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.translate-x-0{--tw-translate-x:0px}.cursor-default{cursor:default}.resize{resize:both}.flex-col{flex-direction:column}.items-center{align-items:center}.justify-center{justify-content:center}.gap-1{gap:.25rem}.gap-2{gap:.5rem}.gap-3{gap:.75rem}.space-y-0\.5>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-top:calc(.125rem*(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.125rem*var(--tw-space-y-reverse))}.space-y-1>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-top:calc(.25rem*(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.25rem*var(--tw-space-y-reverse))}.overflow-y-auto{overflow-y:auto}.truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.rounded-md{border-radius:calc(var(--radius) - 2px)}.border-b{border-bottom-width:1px}.border-l{border-left-width:1px}.border-r{border-right-width:1px}.border-t{border-top-width:1px}.border-sidebar-border{border-color:hsl(var(--sidebar-border))}.bg-background\/95{background-color:hsl(var(--background)/.95)}.bg-primary{background-color:hsl(var(--primary))}.bg-sidebar{background-color:hsl(var(--sidebar-background))}.object-contain{-o-object-fit:contain;object-fit:contain}.px-2{padding-left:.5rem;padding-right:.5rem}.px-4{padding-left:1rem;padding-right:1rem}.py-3{padding-top:.75rem;padding-bottom:.75rem}.py-6{padding-top:1.5rem;padding-bottom:1.5rem}.pl-2{padding-left:.5rem}.pt-4{padding-top:1rem}.font-sans{font-family:Inter,ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,sans-serif}.text-sm{font-size:.875rem;line-height:1.25rem}.font-bold{font-weight:700}.font-semibold{font-weight:600}.tracking-tight{letter-spacing:-.025em}.text-muted-foreground{color:hsl(var(--muted-foreground))}.text-primary-foreground{color:hsl(var(--primary-foreground))}.text-sidebar-foreground{color:hsl(var(--sidebar-foreground))}.opacity-80{opacity:.8}.backdrop-blur{--tw-backdrop-blur:blur(8px)}.backdrop-blur,.backdrop-filter{backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia)}.transition-colors{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-opacity{transition-property:opacity;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-transform{transition-property:transform;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.duration-200{transition-duration:.2s}@keyframes enter{0%{opacity:var(--tw-enter-opacity,1);transform:translate3d(var(--tw-enter-translate-x,0),var(--tw-enter-translate-y,0),0) scale3d(var(--tw-enter-scale,1),var(--tw-enter-scale,1),var(--tw-enter-scale,1)) rotate(var(--tw-enter-rotate,0))}}@keyframes exit{to{opacity:var(--tw-exit-opacity,1);transform:translate3d(var(--tw-exit-translate-x,0),var(--tw-exit-translate-y,0),0) scale3d(var(--tw-exit-scale,1),var(--tw-exit-scale,1),var(--tw-exit-scale,1)) rotate(var(--tw-exit-rotate,0))}}.duration-200{animation-duration:.2s}.learnj-cloak{visibility:hidden}.learnj-cloak.learnj-ready{visibility:visible}#book-search-input{margin-left:.5rem;margin-right:.5rem;margin-bottom:.75rem}#book-search-input input{display:flex;height:2.25rem;width:100%;border-radius:calc(var(--radius) - 2px);border-width:1px;border-color:hsl(var(--input));background-color:hsl(var(--background));padding:.25rem .75rem;font-size:.875rem;line-height:1.25rem;--tw-shadow:0 1px 2px 0 rgba(0,0,0,.05);--tw-shadow-colored:0 1px 2px 0 var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow);transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}#book-search-input input::-moz-placeholder{color:hsl(var(--muted-foreground))}#book-search-input input::placeholder{color:hsl(var(--muted-foreground))}#book-search-input input:focus-visible{outline:2px solid transparent;outline-offset:2px;--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000);--tw-ring-color:hsl(var(--ring))}.book-search-results{position:absolute;z-index:50;margin-top:.25rem;max-height:20rem;width:100%;overflow:auto;border-radius:calc(var(--radius) - 2px);border-width:1px;background-color:hsl(var(--popover));padding:.25rem;color:hsl(var(--popover-foreground));--tw-shadow:0 4px 6px -1px rgba(0,0,0,.1),0 2px 4px -2px rgba(0,0,0,.1);--tw-shadow-colored:0 4px 6px -1px var(--tw-shadow-color),0 2px 4px -2px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.mermaid{margin-top:1.5rem;margin-bottom:1.5rem;border-radius:var(--radius);border-width:1px;background-color:hsl(var(--muted)/.5);padding:1rem;text-align:center}.mermaid svg{margin-left:auto;margin-right:auto;max-width:100%}.markdown-section style[data-mermaid],.markdown-section>style{display:none!important}.markdown-section pre{overflow-x:auto}.markdown-section .hljs{background-color:transparent}.font-settings{border-radius:calc(var(--radius) - 2px);border-width:1px;background-color:hsl(var(--popover));padding:.5rem;--tw-shadow:0 4px 6px -1px rgba(0,0,0,.1),0 2px 4px -2px rgba(0,0,0,.1);--tw-shadow-colored:0 4px 6px -1px var(--tw-shadow-color),0 2px 4px -2px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.learnj-sidebar-backdrop{position:fixed;inset:0;z-index:40;background-color:hsl(var(--background)/.8);--tw-backdrop-blur:blur(4px);backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia)}@media (min-width:1024px){.learnj-sidebar-backdrop{display:none}}.learnj-sidebar-backdrop.hidden{display:none}.learnj-page-nav{position:fixed;bottom:1.5rem;z-index:30;display:flex;height:2.5rem;width:2.5rem;align-items:center;justify-content:center;border-radius:9999px;border-width:1px;background-color:hsl(var(--background));--tw-shadow:0 4px 6px -1px rgba(0,0,0,.1),0 2px 4px -2px rgba(0,0,0,.1);--tw-shadow-colored:0 4px 6px -1px var(--tw-shadow-color),0 2px 4px -2px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow);transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.learnj-page-nav:hover{background-color:hsl(var(--accent))}.learnj-page-nav-prev{left:1.5rem;position:fixed;bottom:1.5rem;z-index:30;display:flex;height:2.5rem;width:2.5rem;align-items:center;justify-content:center;border-radius:9999px;border-width:1px;background-color:hsl(var(--background));--tw-shadow:0 4px 6px -1px rgba(0,0,0,.1),0 2px 4px -2px rgba(0,0,0,.1);--tw-shadow-colored:0 4px 6px -1px var(--tw-shadow-color),0 2px 4px -2px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow);transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.learnj-page-nav-prev:hover{background-color:hsl(var(--accent))}@media print{.learnj-page-nav-prev{display:none}}.learnj-page-nav-next{right:1.5rem;position:fixed;bottom:1.5rem;z-index:30;display:flex;height:2.5rem;width:2.5rem;align-items:center;justify-content:center;border-radius:9999px;border-width:1px;background-color:hsl(var(--background));--tw-shadow:0 4px 6px -1px rgba(0,0,0,.1),0 2px 4px -2px rgba(0,0,0,.1);--tw-shadow-colored:0 4px 6px -1px var(--tw-shadow-color),0 2px 4px -2px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow);transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.learnj-page-nav-next:hover{background-color:hsl(var(--accent))}@media print{.learnj-page-nav-next{display:none}#book-search-input,.learnj-header,.learnj-page-nav,.learnj-sidebar{display:none!important}.learnj-main{margin-left:0!important}}.dark\:prose-invert:is(.dark *){--tw-prose-body:var(--tw-prose-invert-body);--tw-prose-headings:var(--tw-prose-invert-headings);--tw-prose-lead:var(--tw-prose-invert-lead);--tw-prose-links:var(--tw-prose-invert-links);--tw-prose-bold:var(--tw-prose-invert-bold);--tw-prose-counters:var(--tw-prose-invert-counters);--tw-prose-bullets:var(--tw-prose-invert-bullets);--tw-prose-hr:var(--tw-prose-invert-hr);--tw-prose-quotes:var(--tw-prose-invert-quotes);--tw-prose-quote-borders:var(--tw-prose-invert-quote-borders);--tw-prose-captions:var(--tw-prose-invert-captions);--tw-prose-kbd:var(--tw-prose-invert-kbd);--tw-prose-kbd-shadows:var(--tw-prose-invert-kbd-shadows);--tw-prose-code:var(--tw-prose-invert-code);--tw-prose-pre-code:var(--tw-prose-invert-pre-code);--tw-prose-pre-bg:var(--tw-prose-invert-pre-bg);--tw-prose-th-borders:var(--tw-prose-invert-th-borders);--tw-prose-td-borders:var(--tw-prose-invert-td-borders)}.hover\:text-primary:hover{color:hsl(var(--primary))}.hover\:opacity-80:hover{opacity:.8}@supports (backdrop-filter:var(--tw )){.supports-\[backdrop-filter\]\:bg-background\/60{background-color:hsl(var(--background)/.6)}}.dark\:block:is(.dark *){display:block}.dark\:hidden:is(.dark *){display:none}@media (min-width:640px){.sm\:inline-flex{display:inline-flex}.sm\:text-base{font-size:1rem;line-height:1.5rem}}@media (min-width:1024px){.lg\:static{position:static}.lg\:hidden{display:none}.lg\:translate-x-0{--tw-translate-x:0px;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.lg\:px-6{padding-left:1.5rem;padding-right:1.5rem}.lg\:px-8{padding-left:2rem;padding-right:2rem}}
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
(function () {
|
|
2
|
+
"use strict";
|
|
3
|
+
|
|
4
|
+
var STORAGE_SIDEBAR = "learnj-sidebar-open";
|
|
5
|
+
var STORAGE_THEME = "learnj-theme";
|
|
6
|
+
|
|
7
|
+
function ready(fn) {
|
|
8
|
+
if (document.readyState !== "loading") {
|
|
9
|
+
fn();
|
|
10
|
+
} else {
|
|
11
|
+
document.addEventListener("DOMContentLoaded", fn);
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
function getSidebarOpen() {
|
|
16
|
+
try {
|
|
17
|
+
var stored = localStorage.getItem(STORAGE_SIDEBAR);
|
|
18
|
+
if (stored !== null) return stored === "true";
|
|
19
|
+
} catch (e) {}
|
|
20
|
+
return window.matchMedia("(min-width: 1024px)").matches;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function setSidebarOpen(open) {
|
|
24
|
+
var sidebar = document.getElementById("learnj-sidebar");
|
|
25
|
+
var backdrop = document.getElementById("learnj-sidebar-backdrop");
|
|
26
|
+
if (!sidebar) return;
|
|
27
|
+
|
|
28
|
+
if (open) {
|
|
29
|
+
sidebar.classList.remove("-translate-x-full");
|
|
30
|
+
sidebar.classList.add("translate-x-0");
|
|
31
|
+
if (backdrop) {
|
|
32
|
+
backdrop.classList.remove("hidden");
|
|
33
|
+
backdrop.setAttribute("aria-hidden", "false");
|
|
34
|
+
}
|
|
35
|
+
} else {
|
|
36
|
+
sidebar.classList.add("-translate-x-full");
|
|
37
|
+
sidebar.classList.remove("translate-x-0");
|
|
38
|
+
if (backdrop) {
|
|
39
|
+
backdrop.classList.add("hidden");
|
|
40
|
+
backdrop.setAttribute("aria-hidden", "true");
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
try {
|
|
45
|
+
localStorage.setItem(STORAGE_SIDEBAR, String(open));
|
|
46
|
+
} catch (e) {}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function toggleSidebar() {
|
|
50
|
+
var sidebar = document.getElementById("learnj-sidebar");
|
|
51
|
+
if (!sidebar) return;
|
|
52
|
+
var isOpen = !sidebar.classList.contains("-translate-x-full");
|
|
53
|
+
setSidebarOpen(!isOpen);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
function setTheme(dark) {
|
|
57
|
+
document.documentElement.classList.toggle("dark", dark);
|
|
58
|
+
try {
|
|
59
|
+
localStorage.setItem(STORAGE_THEME, dark ? "dark" : "light");
|
|
60
|
+
} catch (e) {}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
function toggleTheme() {
|
|
64
|
+
setTheme(!document.documentElement.classList.contains("dark"));
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
ready(function () {
|
|
68
|
+
var app = document.getElementById("learnj-app");
|
|
69
|
+
if (app) {
|
|
70
|
+
app.classList.add("learnj-ready");
|
|
71
|
+
app.classList.remove("learnj-cloak");
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
var isDesktop = window.matchMedia("(min-width: 1024px)").matches;
|
|
75
|
+
if (isDesktop) {
|
|
76
|
+
setSidebarOpen(true);
|
|
77
|
+
} else {
|
|
78
|
+
setSidebarOpen(getSidebarOpen() && !window.matchMedia("(max-width: 1023px)").matches);
|
|
79
|
+
setSidebarOpen(false);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
var toggleBtn = document.getElementById("learnj-sidebar-toggle");
|
|
83
|
+
if (toggleBtn) {
|
|
84
|
+
toggleBtn.addEventListener("click", toggleSidebar);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
var backdrop = document.getElementById("learnj-sidebar-backdrop");
|
|
88
|
+
if (backdrop) {
|
|
89
|
+
backdrop.addEventListener("click", function () {
|
|
90
|
+
setSidebarOpen(false);
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
var themeBtn = document.getElementById("learnj-theme-toggle");
|
|
95
|
+
if (themeBtn) {
|
|
96
|
+
themeBtn.addEventListener("click", toggleTheme);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
window.addEventListener("resize", function () {
|
|
100
|
+
if (window.matchMedia("(min-width: 1024px)").matches) {
|
|
101
|
+
setSidebarOpen(true);
|
|
102
|
+
}
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
document.addEventListener("keydown", function (e) {
|
|
106
|
+
if (e.key === "Escape") {
|
|
107
|
+
setSidebarOpen(false);
|
|
108
|
+
}
|
|
109
|
+
});
|
|
110
|
+
});
|
|
111
|
+
})();
|
package/_i18n/en.json
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
{
|
|
2
|
+
"LANGS_CHOOSE": "Choose a language",
|
|
3
|
+
"GLOSSARY": "Glossary",
|
|
4
|
+
"GLOSSARY_INDEX": "Index",
|
|
5
|
+
"GLOSSARY_OPEN": "Glossary",
|
|
6
|
+
"GITBOOK_LINK": "Published with HonKit",
|
|
7
|
+
"SUMMARY": "Table of Contents",
|
|
8
|
+
"SUMMARY_INTRODUCTION": "Introduction",
|
|
9
|
+
"SUMMARY_TOGGLE": "Table of Contents",
|
|
10
|
+
"SEARCH_TOGGLE": "Search",
|
|
11
|
+
"SEARCH_PLACEHOLDER": "Search documentation…",
|
|
12
|
+
"SEARCH_RESULTS_TITLE": "<span class='search-results-count'></span> results matching \"<span class='search-query'></span>\"",
|
|
13
|
+
"SEARCH_NO_RESULTS_TITLE": "No results matching \"<span class='search-query'></span>\"",
|
|
14
|
+
"FONTSETTINGS_TOGGLE": "Font Settings",
|
|
15
|
+
"SHARE_TOGGLE": "Share",
|
|
16
|
+
"SHARE_ON": "Share on {{platform}}",
|
|
17
|
+
"FONTSETTINGS_WHITE": "White",
|
|
18
|
+
"FONTSETTINGS_SEPIA": "Sepia",
|
|
19
|
+
"FONTSETTINGS_NIGHT": "Night",
|
|
20
|
+
"FONTSETTINGS_SANS": "Sans",
|
|
21
|
+
"FONTSETTINGS_SERIF": "Serif"
|
|
22
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
<!DOCTYPE HTML>
|
|
2
|
+
<html lang="{{ config.language }}" class="h-full" {% if page.dir == "rtl" %}dir="rtl"{% endif %}>
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8">
|
|
5
|
+
<title>{% block title %}{{ config.title|d("HonKit", true) }}{% endblock %}</title>
|
|
6
|
+
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
|
7
|
+
<meta name="description" content="{% block description %}{% endblock %}">
|
|
8
|
+
<meta name="generator" content="HonKit {{ gitbook.version }}">
|
|
9
|
+
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">
|
|
10
|
+
{% if config.author %}<meta name="author" content="{{ config.author }}">{% endif %}
|
|
11
|
+
{% if config.isbn %}<meta name="identifier" content="{{ config.isbn }}" scheme="ISBN">{% endif %}
|
|
12
|
+
<link rel="preconnect" href="https://fonts.googleapis.com">
|
|
13
|
+
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
|
14
|
+
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500&display=swap" rel="stylesheet">
|
|
15
|
+
{% block style %}
|
|
16
|
+
{% for resource in plugins.resources.css %}
|
|
17
|
+
{% if resource.url %}
|
|
18
|
+
<link rel="stylesheet" href="{{ resource.url }}">
|
|
19
|
+
{% else %}
|
|
20
|
+
<link rel="stylesheet" href="{{ resource.path|resolveAsset }}">
|
|
21
|
+
{% endif %}
|
|
22
|
+
{% endfor %}
|
|
23
|
+
{% endblock %}
|
|
24
|
+
{% block head %}{% endblock %}
|
|
25
|
+
<script>
|
|
26
|
+
(function () {
|
|
27
|
+
try {
|
|
28
|
+
var stored = localStorage.getItem("learnj-theme");
|
|
29
|
+
var prefersDark = window.matchMedia("(prefers-color-scheme: dark)").matches;
|
|
30
|
+
if (stored === "dark" || (!stored && prefersDark)) {
|
|
31
|
+
document.documentElement.classList.add("dark");
|
|
32
|
+
}
|
|
33
|
+
} catch (e) {}
|
|
34
|
+
})();
|
|
35
|
+
</script>
|
|
36
|
+
</head>
|
|
37
|
+
<body class="min-h-full font-sans">
|
|
38
|
+
{% block body %}{% endblock %}
|
|
39
|
+
{% block javascript %}{% endblock %}
|
|
40
|
+
</body>
|
|
41
|
+
</html>
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
{% set themeConfig = config.pluginsConfig['theme-learnj'] or {} %}
|
|
2
|
+
|
|
3
|
+
{% block book_header %}
|
|
4
|
+
<header class="learnj-header sticky top-0 z-30 flex h-14 shrink-0 items-center gap-3 border-b bg-background/95 px-4 backdrop-blur supports-[backdrop-filter]:bg-background/60 lg:px-6" role="banner">
|
|
5
|
+
<button type="button" id="learnj-sidebar-toggle" class="learnj-btn-ghost lg:hidden" aria-label="Toggle sidebar">
|
|
6
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="4" x2="20" y1="12" y2="12"/><line x1="4" x2="20" y1="6" y2="6"/><line x1="4" x2="20" y1="18" y2="18"/></svg>
|
|
7
|
+
</button>
|
|
8
|
+
|
|
9
|
+
<div class="flex min-w-0 flex-1 items-center gap-2">
|
|
10
|
+
{% if glossary.path %}
|
|
11
|
+
<a href="{{ ('/' + glossary.path)|resolveFile }}" class="learnj-btn-outline hidden sm:inline-flex" aria-label="{{ "GLOSSARY_OPEN"|t }}">
|
|
12
|
+
Glossary
|
|
13
|
+
</a>
|
|
14
|
+
{% endif %}
|
|
15
|
+
<h1 class="truncate text-sm font-semibold sm:text-base">
|
|
16
|
+
<a href="{{ "/"|resolveFile }}" class="hover:text-primary transition-colors">{{ page.title }}</a>
|
|
17
|
+
</h1>
|
|
18
|
+
</div>
|
|
19
|
+
|
|
20
|
+
<button type="button" id="learnj-theme-toggle" class="learnj-btn-ghost" aria-label="Toggle dark mode">
|
|
21
|
+
<svg class="hidden dark:block" xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="4"/><path d="M12 2v2"/><path d="M12 20v2"/><path d="m4.93 4.93 1.41 1.41"/><path d="m17.66 17.66 1.41 1.41"/><path d="M2 12h2"/><path d="M20 12h2"/><path d="m6.34 17.66-1.41 1.41"/><path d="m19.07 4.93-1.41 1.41"/></svg>
|
|
22
|
+
<svg class="block dark:hidden" xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 3a6 6 0 0 0 9 9 9 9 0 1 1-9-9Z"/></svg>
|
|
23
|
+
</button>
|
|
24
|
+
</header>
|
|
25
|
+
{% endblock %}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{% extends "layout.html" %}
|
|
2
|
+
|
|
3
|
+
{% block head %}
|
|
4
|
+
{{ super() }}
|
|
5
|
+
<link rel="shortcut icon" href="data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'><text y='.9em' font-size='90'>📘</text></svg>" type="image/svg+xml">
|
|
6
|
+
{% endblock %}
|
|
7
|
+
|
|
8
|
+
{% block style %}
|
|
9
|
+
<link rel="stylesheet" href="{{ "learnj.css"|resolveAsset }}">
|
|
10
|
+
{{ super() }}
|
|
11
|
+
{% for type, style in config.styles %}
|
|
12
|
+
{% if fileExists(style) and type == "website" %}
|
|
13
|
+
<link rel="stylesheet" href="{{ style|resolveFile }}">
|
|
14
|
+
{% endif %}
|
|
15
|
+
{% endfor %}
|
|
16
|
+
{% endblock %}
|
|
17
|
+
|
|
18
|
+
{% block body %}{% endblock %}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
{% extends "./layout.html" %}
|
|
2
|
+
|
|
3
|
+
{% block title %}{{ page.title }} · {{ super() }}{% endblock %}
|
|
4
|
+
|
|
5
|
+
{% block description %}{{ page.description }}{% endblock %}
|
|
6
|
+
|
|
7
|
+
{% block head %}
|
|
8
|
+
{{ super() }}
|
|
9
|
+
{% if page.next and page.next.path %}
|
|
10
|
+
<link rel="next" href="{{ page.next.path|resolveFile }}" />
|
|
11
|
+
{% endif %}
|
|
12
|
+
{% if page.previous and page.previous.path %}
|
|
13
|
+
<link rel="prev" href="{{ page.previous.path|resolveFile }}" />
|
|
14
|
+
{% endif %}
|
|
15
|
+
{% endblock %}
|
|
16
|
+
|
|
17
|
+
{% block javascript %}
|
|
18
|
+
<script src="{{ "learnj.js"|resolveAsset }}"></script>
|
|
19
|
+
{% for resource in plugins.resources.js %}
|
|
20
|
+
{% if resource.url %}
|
|
21
|
+
<script src="{{ resource.url }}"></script>
|
|
22
|
+
{% else %}
|
|
23
|
+
<script src="{{ resource.path|resolveAsset }}"></script>
|
|
24
|
+
{% endif %}
|
|
25
|
+
{% endfor %}
|
|
26
|
+
{% endblock %}
|
|
27
|
+
|
|
28
|
+
{% block body %}
|
|
29
|
+
{% set themeConfig = config.pluginsConfig['theme-learnj'] or {} %}
|
|
30
|
+
<div id="learnj-app" class="learnj-cloak flex min-h-screen">
|
|
31
|
+
<div id="learnj-sidebar-backdrop" class="learnj-sidebar-backdrop hidden" aria-hidden="true"></div>
|
|
32
|
+
|
|
33
|
+
<aside id="learnj-sidebar" class="learnj-sidebar fixed inset-y-0 left-0 z-50 flex w-[280px] max-w-[85vw] flex-col border-r border-sidebar-border bg-sidebar text-sidebar-foreground transition-transform duration-200 -translate-x-full lg:static lg:translate-x-0">
|
|
34
|
+
<div class="flex h-14 shrink-0 items-center gap-2 border-b border-sidebar-border">
|
|
35
|
+
<a href="{{ "/"|resolveFile }}" class="flex items-center gap-2 px-4 font-semibold tracking-tight transition-opacity hover:opacity-80">
|
|
36
|
+
{% if themeConfig.logo %}
|
|
37
|
+
<img src="{{ themeConfig.logo }}" alt="" class="h-8 w-8 rounded-md object-contain" />
|
|
38
|
+
{% else %}
|
|
39
|
+
<span class="flex h-8 w-8 items-center justify-center rounded-md bg-primary text-sm font-bold text-primary-foreground">LJ</span>
|
|
40
|
+
{% endif %}
|
|
41
|
+
<span class="truncate text-sm">{{ themeConfig.logoText or config.title }}</span>
|
|
42
|
+
</a>
|
|
43
|
+
</div>
|
|
44
|
+
|
|
45
|
+
<div class="flex-1 overflow-y-auto py-3">
|
|
46
|
+
{% block book_sidebar %}
|
|
47
|
+
{% block search_input %}{% endblock %}
|
|
48
|
+
{% block book_summary %}
|
|
49
|
+
{% include "website/summary.html" %}
|
|
50
|
+
{% endblock %}
|
|
51
|
+
{% endblock %}
|
|
52
|
+
</div>
|
|
53
|
+
</aside>
|
|
54
|
+
|
|
55
|
+
<main class="learnj-main flex min-h-screen min-w-0 flex-1 flex-col">
|
|
56
|
+
{% block book_body %}
|
|
57
|
+
{% block book_inner %}
|
|
58
|
+
{% include "website/header.html" %}
|
|
59
|
+
|
|
60
|
+
<div class="flex-1 px-4 py-6 lg:px-8" tabindex="-1" role="main">
|
|
61
|
+
<div class="mx-auto max-w-4xl">
|
|
62
|
+
{% block search_results %}
|
|
63
|
+
<article class="markdown-section prose prose-slate dark:prose-invert max-w-none">
|
|
64
|
+
{% block page %}
|
|
65
|
+
{{ page.content|safe }}
|
|
66
|
+
{% endblock %}
|
|
67
|
+
</article>
|
|
68
|
+
{% endblock %}
|
|
69
|
+
</div>
|
|
70
|
+
</div>
|
|
71
|
+
{% endblock %}
|
|
72
|
+
|
|
73
|
+
{% block book_navigation %}
|
|
74
|
+
{% if page.previous and page.previous.path %}
|
|
75
|
+
<a href="{{ page.previous.path|resolveFile }}{{ page.previous.anchor }}"
|
|
76
|
+
class="learnj-page-nav-prev"
|
|
77
|
+
aria-label="Previous page: {{ page.previous.title }}"
|
|
78
|
+
title="{{ page.previous.title }}">
|
|
79
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="m15 18-6-6 6-6"/></svg>
|
|
80
|
+
</a>
|
|
81
|
+
{% endif %}
|
|
82
|
+
{% if page.next and page.next.path %}
|
|
83
|
+
<a href="{{ page.next.path|resolveFile }}{{ page.next.anchor }}"
|
|
84
|
+
class="learnj-page-nav-next"
|
|
85
|
+
aria-label="Next page: {{ page.next.title }}"
|
|
86
|
+
title="{{ page.next.title }}">
|
|
87
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="m9 18 6-6-6-6"/></svg>
|
|
88
|
+
</a>
|
|
89
|
+
{% endif %}
|
|
90
|
+
{% endblock %}
|
|
91
|
+
{% endblock %}
|
|
92
|
+
</main>
|
|
93
|
+
|
|
94
|
+
<script>
|
|
95
|
+
var gitbook = gitbook || [];
|
|
96
|
+
gitbook.push(function() {
|
|
97
|
+
gitbook.page.hasChanged({{ template.getJSContext()|dump|safe }});
|
|
98
|
+
});
|
|
99
|
+
</script>
|
|
100
|
+
</div>
|
|
101
|
+
{% endblock %}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
{% set themeConfig = config.pluginsConfig['theme-learnj'] or {} %}
|
|
2
|
+
{% set showLevel = themeConfig.showLevel %}
|
|
3
|
+
|
|
4
|
+
{% macro articles(_articles) %}
|
|
5
|
+
{% for article in _articles %}
|
|
6
|
+
{% set isActive = article.path == file.path and not article.anchor %}
|
|
7
|
+
<li class="{% if article.articles.length > 0 %}space-y-1{% endif %}">
|
|
8
|
+
{% if article.path and getPageByPath(article.path) %}
|
|
9
|
+
<a href="{{ article.path|resolveFile }}{{ article.anchor }}"
|
|
10
|
+
class="learnj-nav-link {% if isActive %}active{% endif %}"
|
|
11
|
+
{% if isActive %}aria-current="page"{% endif %}>
|
|
12
|
+
{% elif article.url %}
|
|
13
|
+
<a href="{{ article.url }}" target="_blank" rel="noopener noreferrer"
|
|
14
|
+
class="learnj-nav-link">
|
|
15
|
+
{% else %}
|
|
16
|
+
<span class="learnj-nav-link cursor-default opacity-80">
|
|
17
|
+
{% endif %}
|
|
18
|
+
{% if article.level != "0" and showLevel %}
|
|
19
|
+
<span class="learnj-badge-secondary mr-1">{{ article.level }}</span>
|
|
20
|
+
{% endif %}
|
|
21
|
+
<span class="truncate">{{ article.title }}</span>
|
|
22
|
+
{% if article.path or article.url %}
|
|
23
|
+
</a>
|
|
24
|
+
{% else %}
|
|
25
|
+
</span>
|
|
26
|
+
{% endif %}
|
|
27
|
+
|
|
28
|
+
{% if article.articles.length > 0 %}
|
|
29
|
+
<ul class="ml-3 space-y-0.5 border-l border-sidebar-border pl-2">
|
|
30
|
+
{{ articles(article.articles) }}
|
|
31
|
+
</ul>
|
|
32
|
+
{% endif %}
|
|
33
|
+
</li>
|
|
34
|
+
{% endfor %}
|
|
35
|
+
{% endmacro %}
|
|
36
|
+
|
|
37
|
+
<nav class="flex flex-col gap-1 px-2" aria-label="Table of contents">
|
|
38
|
+
{% if config.links.sidebar %}
|
|
39
|
+
<ul class="space-y-0.5">
|
|
40
|
+
{% for linkTitle, link in config.links.sidebar %}
|
|
41
|
+
<li>
|
|
42
|
+
<a href="{{ link }}" target="_blank" rel="noopener noreferrer" class="learnj-nav-link">
|
|
43
|
+
{{ linkTitle }}
|
|
44
|
+
</a>
|
|
45
|
+
</li>
|
|
46
|
+
{% endfor %}
|
|
47
|
+
</ul>
|
|
48
|
+
<div class="my-2 border-t border-sidebar-border"></div>
|
|
49
|
+
{% endif %}
|
|
50
|
+
|
|
51
|
+
<ul class="space-y-0.5">
|
|
52
|
+
{% for part in summary.parts %}
|
|
53
|
+
{% if part.title %}
|
|
54
|
+
<li class="learnj-nav-section">{{ part.title }}</li>
|
|
55
|
+
{% elif not loop.first %}
|
|
56
|
+
<li class="my-2 border-t border-sidebar-border" role="separator"></li>
|
|
57
|
+
{% endif %}
|
|
58
|
+
{{ articles(part.articles) }}
|
|
59
|
+
{% endfor %}
|
|
60
|
+
</ul>
|
|
61
|
+
|
|
62
|
+
{% if themeConfig.githubUrl %}
|
|
63
|
+
<div class="mt-auto border-t border-sidebar-border pt-4">
|
|
64
|
+
<a href="{{ themeConfig.githubUrl }}" target="_blank" rel="noopener noreferrer"
|
|
65
|
+
class="learnj-nav-link text-muted-foreground">
|
|
66
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="shrink-0"><path d="M15 22v-4a4.8 4.8 0 0 0-1-3.5c3 0 6-2 6-5.5.08-1.25-.27-2.48-1-3.5.28-1.15.28-2.35 0-3.5 0 0-1 0-3 1.5-2.64-.5-5.36-.5-8 0C6 2 5 2 5 2c-.3 1.15-.3 2.35 0 3.5A5.403 5.403 0 0 0 4 9c0 3.5 3 5.5 6 5.5-.39.49-.68 1.05-.85 1.65-.17.6-.22 1.23-.15 1.85v4"/><path d="M9 18c-4.51 2-5-2-7-2"/></svg>
|
|
67
|
+
View on GitHub
|
|
68
|
+
</a>
|
|
69
|
+
</div>
|
|
70
|
+
{% endif %}
|
|
71
|
+
</nav>
|
package/index.js
ADDED
package/package.json
ADDED
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "honkit-plugin-theme-learnj",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "LearnJ HonKit theme — Tailwind CSS + shadcn/ui design system",
|
|
5
|
+
"main": "./index.js",
|
|
6
|
+
"files": [
|
|
7
|
+
"index.js",
|
|
8
|
+
"_assets",
|
|
9
|
+
"_i18n",
|
|
10
|
+
"_layouts"
|
|
11
|
+
],
|
|
12
|
+
"scripts": {
|
|
13
|
+
"build:css": "tailwindcss -i ./src/learnj.css -o ./_assets/website/learnj.css --minify",
|
|
14
|
+
"build": "npm run build:css",
|
|
15
|
+
"watch": "tailwindcss -i ./src/learnj.css -o ./_assets/website/learnj.css --watch",
|
|
16
|
+
"prepublishOnly": "npm run build",
|
|
17
|
+
"prepack": "npm run build"
|
|
18
|
+
},
|
|
19
|
+
"keywords": [
|
|
20
|
+
"honkit",
|
|
21
|
+
"gitbook",
|
|
22
|
+
"theme",
|
|
23
|
+
"learnj",
|
|
24
|
+
"tailwind",
|
|
25
|
+
"shadcn",
|
|
26
|
+
"documentation"
|
|
27
|
+
],
|
|
28
|
+
"author": "LearnJ",
|
|
29
|
+
"license": "MIT",
|
|
30
|
+
"repository": {
|
|
31
|
+
"type": "git",
|
|
32
|
+
"url": "git+https://github.com/learnj-ai/honkit-plugin-theme-learnj.git"
|
|
33
|
+
},
|
|
34
|
+
"bugs": {
|
|
35
|
+
"url": "https://github.com/learnj-ai/honkit-plugin-theme-learnj/issues"
|
|
36
|
+
},
|
|
37
|
+
"homepage": "https://github.com/learnj-ai/honkit-plugin-theme-learnj#readme",
|
|
38
|
+
"engines": {
|
|
39
|
+
"honkit": ">=5.0.0",
|
|
40
|
+
"node": ">=18"
|
|
41
|
+
},
|
|
42
|
+
"publishConfig": {
|
|
43
|
+
"access": "public"
|
|
44
|
+
},
|
|
45
|
+
"devDependencies": {
|
|
46
|
+
"@tailwindcss/typography": "^0.5.16",
|
|
47
|
+
"autoprefixer": "^10.4.21",
|
|
48
|
+
"postcss": "^8.5.3",
|
|
49
|
+
"tailwindcss": "^3.4.17",
|
|
50
|
+
"tailwindcss-animate": "^1.0.7"
|
|
51
|
+
},
|
|
52
|
+
"honkit": {
|
|
53
|
+
"properties": {
|
|
54
|
+
"showLevel": {
|
|
55
|
+
"type": "boolean",
|
|
56
|
+
"title": "Show level indicator in TOC",
|
|
57
|
+
"default": false
|
|
58
|
+
},
|
|
59
|
+
"logo": {
|
|
60
|
+
"type": "string",
|
|
61
|
+
"title": "Logo URL for sidebar header"
|
|
62
|
+
},
|
|
63
|
+
"logoText": {
|
|
64
|
+
"type": "string",
|
|
65
|
+
"title": "Text shown next to logo",
|
|
66
|
+
"default": "LearnJ"
|
|
67
|
+
},
|
|
68
|
+
"githubUrl": {
|
|
69
|
+
"type": "string",
|
|
70
|
+
"title": "GitHub repository URL"
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|