jaamd 0.1.14 → 0.2.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/README.md +73 -12
- package/index.ts +21 -3
- package/package.json +18 -4
- package/src/scripts/enhancements.ts +10 -261
- package/src/scripts/modules/code-tabs.ts +26 -0
- package/src/scripts/modules/copy-buttons.ts +42 -0
- package/src/scripts/modules/details.ts +65 -0
- package/src/scripts/modules/heading-links.ts +37 -0
- package/src/scripts/modules/lightbox.ts +50 -0
- package/src/scripts/modules/spoilers.ts +11 -0
- package/src/scripts/modules/tables.ts +13 -0
- package/src/scripts/utils.ts +24 -0
- package/src/styles/markdown.css +7 -7
- package/src/styles/shiki-dual.css +28 -0
- package/src/styles/variables.css +60 -0
- package/src/themes/dracula/dark.css +66 -0
- package/src/themes/dracula/index.css +66 -0
- package/src/themes/nord/dark.css +66 -0
- package/src/themes/nord/index.css +66 -0
- package/src/themes/one-dark/dark.css +66 -0
- package/src/themes/one-dark/index.css +66 -0
package/README.md
CHANGED
|
@@ -13,6 +13,10 @@
|
|
|
13
13
|
- [Integration Options](#integration-options)
|
|
14
14
|
- [MarkdownContent Component](#markdowncontent-component)
|
|
15
15
|
- [Theming](#theming)
|
|
16
|
+
- [Customizing variables](#customizing-variables)
|
|
17
|
+
- [Dark mode](#dark-mode)
|
|
18
|
+
- [Theme presets](#theme-presets)
|
|
19
|
+
- [Dual-theme Shiki](#dual-theme-shiki-optional)
|
|
16
20
|
- [Manual / Advanced Usage](#manual--advanced-usage)
|
|
17
21
|
|
|
18
22
|
---
|
|
@@ -62,7 +66,7 @@ To fix it, import the stylesheet **statically** in your layout's frontmatter alo
|
|
|
62
66
|
```astro
|
|
63
67
|
---
|
|
64
68
|
// In any layout that uses MarkdownContent
|
|
65
|
-
import "jaamd/default.css";
|
|
69
|
+
import "jaamd/default.css";
|
|
66
70
|
import "jaamd/styles.css";
|
|
67
71
|
---
|
|
68
72
|
```
|
|
@@ -73,9 +77,9 @@ The duplicate import from `injectScript` is automatically deduplicated by the br
|
|
|
73
77
|
|
|
74
78
|
```ts
|
|
75
79
|
jaamd({
|
|
76
|
-
selector: ".jaamd-content", // CSS selector for the JS enhancements
|
|
77
|
-
theme: "",
|
|
78
|
-
noDefault: false, //
|
|
80
|
+
selector: ".jaamd-content", // CSS selector for the JS enhancements
|
|
81
|
+
theme: "github-light", // Shiki theme name (or { light, dark } — see below)
|
|
82
|
+
noDefault: false, // skip injecting jaamd/default variable fallbacks
|
|
79
83
|
plugins: {
|
|
80
84
|
codeTabs: true, // :::code-tabs directive blocks
|
|
81
85
|
alerts: true, // > [!NOTE] / [!WARNING] blockquote alerts
|
|
@@ -134,30 +138,87 @@ import { MarkdownContent } from "jaamd/components";
|
|
|
134
138
|
|
|
135
139
|
## Theming
|
|
136
140
|
|
|
137
|
-
All styles are driven by CSS custom properties
|
|
141
|
+
All styles are driven by CSS custom properties prefixed with `--jaamd-*`. The default variable set (`jaamd/default`) is injected automatically so everything works out of the box.
|
|
138
142
|
|
|
139
|
-
|
|
143
|
+
### Customizing variables
|
|
144
|
+
|
|
145
|
+
Override any variable on `:root` in your own stylesheet:
|
|
140
146
|
|
|
141
147
|
```css
|
|
142
148
|
:root {
|
|
143
|
-
/* core colors */
|
|
144
149
|
--jaamd-color-fg: #334155;
|
|
145
150
|
--jaamd-color-fg-bright: #0f172a;
|
|
146
151
|
--jaamd-color-primary: #6366f1;
|
|
147
152
|
--jaamd-color-primary-light: #818cf8;
|
|
148
|
-
|
|
149
|
-
/* typography */
|
|
150
|
-
--jaamd-font-sans: ui-sans-serif, system-ui, sans-serif;
|
|
151
153
|
--jaamd-font-mono: ui-monospace, monospace;
|
|
152
154
|
--jaamd-font-size: 1rem;
|
|
153
155
|
}
|
|
154
156
|
```
|
|
155
157
|
|
|
156
|
-
|
|
158
|
+
See [`src/styles/variables.css`](src/styles/variables.css) for every available variable and its default value.
|
|
159
|
+
|
|
160
|
+
### Dark mode
|
|
161
|
+
|
|
162
|
+
The default variable set includes dark-mode overrides activated by the `dark` class on `<html>`. Toggle the class and all JAAMD elements adapt.
|
|
163
|
+
|
|
164
|
+
### Theme presets
|
|
165
|
+
|
|
166
|
+
Three additional presets restyle all `--jaamd-*` variables to match popular editor colour schemes:
|
|
167
|
+
|
|
168
|
+
| Preset | Import | Recommended Shiki theme |
|
|
169
|
+
|--------|--------|------------------------|
|
|
170
|
+
| Dracula | `jaamd/themes/dracula` | `dracula` |
|
|
171
|
+
| Nord | `jaamd/themes/nord` | `nord` |
|
|
172
|
+
| One Dark | `jaamd/themes/one-dark` | `one-dark-pro` |
|
|
173
|
+
|
|
174
|
+
**Standalone preset** — replaces the default light theme entirely:
|
|
175
|
+
|
|
176
|
+
```ts
|
|
177
|
+
jaamd({ theme: "dracula", noDefault: true })
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
```css
|
|
181
|
+
@import "jaamd/themes/dracula.css";
|
|
182
|
+
@import "jaamd/styles.css";
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
**Dark-mode toggle** — each preset ships a `/dark` variant scoped to `html.dark`:
|
|
186
|
+
|
|
187
|
+
```css
|
|
188
|
+
@import "jaamd/themes/dracula/dark.css";
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
```ts
|
|
192
|
+
import "jaamd/themes/dracula/dark";
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
You can also copy any preset from `src/themes/` and customise the values.
|
|
196
|
+
|
|
197
|
+
### Dual-theme Shiki (optional)
|
|
198
|
+
|
|
199
|
+
Pass an object to `theme` to configure Shiki with two colour schemes and CSS-variable–based switching:
|
|
200
|
+
|
|
201
|
+
```ts
|
|
202
|
+
jaamd({
|
|
203
|
+
theme: { light: "github-light", dark: "github-dark" },
|
|
204
|
+
})
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
JAAMD sets `defaultColor: false` on Shiki and injects a stylesheet that swaps token colours when `html.dark` is present. Add an inline script in `<head>` to prevent a flash of wrong theme:
|
|
208
|
+
|
|
209
|
+
```html
|
|
210
|
+
<script is:inline>
|
|
211
|
+
(function () {
|
|
212
|
+
var t = localStorage.getItem("theme");
|
|
213
|
+
if (t === "dark" || (!t && matchMedia("(prefers-color-scheme: dark)").matches))
|
|
214
|
+
document.documentElement.classList.add("dark");
|
|
215
|
+
})();
|
|
216
|
+
</script>
|
|
217
|
+
```
|
|
157
218
|
|
|
158
219
|
### Skipping the defaults
|
|
159
220
|
|
|
160
|
-
If you supply your own full variable set
|
|
221
|
+
If you supply your own full variable set, set `noDefault: true`:
|
|
161
222
|
|
|
162
223
|
```ts
|
|
163
224
|
jaamd({ noDefault: true })
|
package/index.ts
CHANGED
|
@@ -12,10 +12,16 @@ export interface JaamdOptions {
|
|
|
12
12
|
selector?: string;
|
|
13
13
|
|
|
14
14
|
/**
|
|
15
|
-
* Shiki syntax-highlighting theme
|
|
15
|
+
* Shiki syntax-highlighting theme.
|
|
16
|
+
*
|
|
17
|
+
* - **string** — single theme name (e.g. `"github-light"`).
|
|
18
|
+
* - **{ light, dark }** — enables dual-theme mode. Shiki outputs CSS
|
|
19
|
+
* variables for both themes and JAAMD injects the switching CSS.
|
|
20
|
+
* Use together with a `.dark` class on `<html>` for dark-mode toggling.
|
|
21
|
+
*
|
|
16
22
|
* @default "github-light"
|
|
17
23
|
*/
|
|
18
|
-
theme?: string;
|
|
24
|
+
theme?: string | { light: string; dark: string };
|
|
19
25
|
|
|
20
26
|
/**
|
|
21
27
|
* Skip injecting the default CSS variable fallbacks (`jaamd/default`).
|
|
@@ -73,7 +79,16 @@ export default function jaamd(options: JaamdOptions = {}): AstroIntegration {
|
|
|
73
79
|
|
|
74
80
|
// `wrap` and other keys are only filled in when absent.
|
|
75
81
|
const mergedShikiConfig: any = { ...existingShikiConfig };
|
|
76
|
-
|
|
82
|
+
|
|
83
|
+
// Dual-theme mode: { light, dark } → Shiki "themes" with CSS variables
|
|
84
|
+
if (typeof theme === "object" && theme.light && theme.dark) {
|
|
85
|
+
delete mergedShikiConfig.theme;
|
|
86
|
+
mergedShikiConfig.themes = { light: theme.light, dark: theme.dark };
|
|
87
|
+
mergedShikiConfig.defaultColor = false;
|
|
88
|
+
} else {
|
|
89
|
+
mergedShikiConfig.theme = typeof theme === "string" ? theme : "github-light";
|
|
90
|
+
}
|
|
91
|
+
|
|
77
92
|
if (mergedShikiConfig.wrap === undefined) mergedShikiConfig.wrap = true;
|
|
78
93
|
|
|
79
94
|
updateConfig({
|
|
@@ -92,9 +107,12 @@ export default function jaamd(options: JaamdOptions = {}): AstroIntegration {
|
|
|
92
107
|
});
|
|
93
108
|
|
|
94
109
|
// "page" stage: bundled by Vite, tree-shaken, no duplicate injection
|
|
110
|
+
const isDualTheme = typeof theme === "object" && theme.light && theme.dark;
|
|
95
111
|
injectScript(
|
|
96
112
|
"page",
|
|
97
113
|
(!noDefault ? `import "jaamd/default";
|
|
114
|
+
` : "") +
|
|
115
|
+
(isDualTheme ? `import "jaamd/shiki-dual";
|
|
98
116
|
` : "") +
|
|
99
117
|
`import "jaamd/styles";
|
|
100
118
|
` +
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "jaamd",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "Just Another Astro Markdown",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -24,7 +24,21 @@
|
|
|
24
24
|
"./default": "./src/styles/variables.css",
|
|
25
25
|
"./default.css": "./src/styles/variables.css",
|
|
26
26
|
"./styles": "./src/styles/markdown.css",
|
|
27
|
-
"./styles.css": "./src/styles/markdown.css"
|
|
27
|
+
"./styles.css": "./src/styles/markdown.css",
|
|
28
|
+
"./shiki-dual": "./src/styles/shiki-dual.css",
|
|
29
|
+
"./shiki-dual.css": "./src/styles/shiki-dual.css",
|
|
30
|
+
"./themes/dracula": "./src/themes/dracula/index.css",
|
|
31
|
+
"./themes/dracula.css": "./src/themes/dracula/index.css",
|
|
32
|
+
"./themes/dracula/dark": "./src/themes/dracula/dark.css",
|
|
33
|
+
"./themes/dracula/dark.css": "./src/themes/dracula/dark.css",
|
|
34
|
+
"./themes/nord": "./src/themes/nord/index.css",
|
|
35
|
+
"./themes/nord.css": "./src/themes/nord/index.css",
|
|
36
|
+
"./themes/nord/dark": "./src/themes/nord/dark.css",
|
|
37
|
+
"./themes/nord/dark.css": "./src/themes/nord/dark.css",
|
|
38
|
+
"./themes/one-dark": "./src/themes/one-dark/index.css",
|
|
39
|
+
"./themes/one-dark.css": "./src/themes/one-dark/index.css",
|
|
40
|
+
"./themes/one-dark/dark": "./src/themes/one-dark/dark.css",
|
|
41
|
+
"./themes/one-dark/dark.css": "./src/themes/one-dark/dark.css"
|
|
28
42
|
},
|
|
29
43
|
"files": [
|
|
30
44
|
"index.ts",
|
|
@@ -40,8 +54,8 @@
|
|
|
40
54
|
},
|
|
41
55
|
"devDependencies": {
|
|
42
56
|
"@types/mdast": "^4.0.4",
|
|
43
|
-
"astro": "^
|
|
44
|
-
"typescript": "^
|
|
57
|
+
"astro": "^6.0.0",
|
|
58
|
+
"typescript": "^6.0.0",
|
|
45
59
|
"unified": "^11.0.0"
|
|
46
60
|
}
|
|
47
61
|
}
|
|
@@ -3,32 +3,18 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Plain ES module — bundled by Vite as part of the Astro build.
|
|
5
5
|
* No external runtime dependencies.
|
|
6
|
+
*
|
|
7
|
+
* Each feature lives in its own module; this file is the public entry point
|
|
8
|
+
* that wires them all together via `initMarkdownEnhancements`.
|
|
6
9
|
*/
|
|
7
10
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
.replace(/[\s_]+/g, "-")
|
|
16
|
-
.replace(/^-+|-+$/g, "");
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
function qs<T extends Element = Element>(
|
|
20
|
-
root: ParentNode,
|
|
21
|
-
sel: string,
|
|
22
|
-
): T | null {
|
|
23
|
-
return root.querySelector<T>(sel);
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
function qsa<T extends Element = Element>(
|
|
27
|
-
root: ParentNode,
|
|
28
|
-
sel: string,
|
|
29
|
-
): NodeListOf<T> {
|
|
30
|
-
return root.querySelectorAll<T>(sel);
|
|
31
|
-
}
|
|
11
|
+
import { addHeadingLinks } from "./modules/heading-links.js";
|
|
12
|
+
import { addCopyButtons } from "./modules/copy-buttons.js";
|
|
13
|
+
import { addImageLightbox } from "./modules/lightbox.js";
|
|
14
|
+
import { wrapTables } from "./modules/tables.js";
|
|
15
|
+
import { initCodeTabs } from "./modules/code-tabs.js";
|
|
16
|
+
import { initSpoilers } from "./modules/spoilers.js";
|
|
17
|
+
import { initDetails } from "./modules/details.js";
|
|
32
18
|
|
|
33
19
|
// ─── Public API ───────────────────────────────────────────────────────────────
|
|
34
20
|
|
|
@@ -42,241 +28,4 @@ export function initMarkdownEnhancements(
|
|
|
42
28
|
initCodeTabs();
|
|
43
29
|
initSpoilers(selector);
|
|
44
30
|
initDetails(selector);
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
// ─── Heading anchor links ─────────────────────────────────────────────────────
|
|
48
|
-
|
|
49
|
-
function addHeadingLinks(selector: string): void {
|
|
50
|
-
qsa<HTMLElement>(document, `${selector} h1, ${selector} h2, ${selector} h3`).forEach(
|
|
51
|
-
(header) => {
|
|
52
|
-
if (!header.id) header.id = slugify(header.textContent ?? "");
|
|
53
|
-
if (qs(header, ".jaamd-heading-link")) return;
|
|
54
|
-
|
|
55
|
-
const a = document.createElement("a");
|
|
56
|
-
a.className = "jaamd-heading-link";
|
|
57
|
-
a.setAttribute("aria-label", `Link to section: ${header.textContent}`);
|
|
58
|
-
a.setAttribute("href", `#${header.id}`);
|
|
59
|
-
a.title = "Copy link";
|
|
60
|
-
a.innerHTML =
|
|
61
|
-
`<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" ` +
|
|
62
|
-
`stroke="currentColor" stroke-width="2" stroke-linecap="round" ` +
|
|
63
|
-
`stroke-linejoin="round" width="1em" height="1em" aria-hidden="true">` +
|
|
64
|
-
`<path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"/>` +
|
|
65
|
-
`<path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"/>` +
|
|
66
|
-
`</svg>`;
|
|
67
|
-
|
|
68
|
-
a.addEventListener("click", async (e) => {
|
|
69
|
-
e.preventDefault();
|
|
70
|
-
const url = `${location.origin}${location.pathname}#${header.id}`;
|
|
71
|
-
try {
|
|
72
|
-
await navigator.clipboard.writeText(url);
|
|
73
|
-
} catch {
|
|
74
|
-
// clipboard not available (e.g. non-secure context) — fail silently
|
|
75
|
-
}
|
|
76
|
-
});
|
|
77
|
-
|
|
78
|
-
header.appendChild(a);
|
|
79
|
-
},
|
|
80
|
-
);
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
// ─── Code copy buttons ────────────────────────────────────────────────────────
|
|
84
|
-
|
|
85
|
-
function addCopyButtons(selector: string): void {
|
|
86
|
-
qsa<HTMLElement>(document, `${selector} pre`).forEach((pre) => {
|
|
87
|
-
if (qs(pre, ".jaamd-copy-btn")) return;
|
|
88
|
-
const code = qs<HTMLElement>(pre, "code");
|
|
89
|
-
if (!code) return;
|
|
90
|
-
|
|
91
|
-
const btn = document.createElement("button");
|
|
92
|
-
btn.className = "jaamd-copy-btn";
|
|
93
|
-
btn.title = "Copy code";
|
|
94
|
-
btn.setAttribute("aria-label", "Copy code to clipboard");
|
|
95
|
-
btn.innerHTML = iconCopy();
|
|
96
|
-
|
|
97
|
-
btn.addEventListener("click", async () => {
|
|
98
|
-
try {
|
|
99
|
-
await navigator.clipboard.writeText(code.textContent ?? "");
|
|
100
|
-
const orig = btn.innerHTML;
|
|
101
|
-
btn.innerHTML = iconCheck();
|
|
102
|
-
btn.style.color = "var(--jaamd-color-success, #22c55e)";
|
|
103
|
-
setTimeout(() => {
|
|
104
|
-
btn.innerHTML = orig;
|
|
105
|
-
btn.style.color = "";
|
|
106
|
-
}, 2000);
|
|
107
|
-
} catch {
|
|
108
|
-
// fail silently
|
|
109
|
-
}
|
|
110
|
-
});
|
|
111
|
-
|
|
112
|
-
pre.appendChild(btn);
|
|
113
|
-
});
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
function iconCopy(): string {
|
|
117
|
-
return `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" width="1em" height="1em" aria-hidden="true"><path d="M16 1H4c-1.1 0-2 .9-2 2v14h2V3h12V1zm3 4H8c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h11c1.1 0 2-.9 2-2V7c0-1.1-.9-2-2-2zm0 16H8V7h11v14z"/></svg>`;
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
function iconCheck(): string {
|
|
121
|
-
return `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" width="1em" height="1em" aria-hidden="true"><path d="M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z"/></svg>`;
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
// ─── Image lightbox ───────────────────────────────────────────────────────────
|
|
125
|
-
|
|
126
|
-
function addImageLightbox(selector: string): void {
|
|
127
|
-
qsa<HTMLImageElement>(document, `${selector} img`).forEach((img) => {
|
|
128
|
-
if (img.classList.contains("jaamd-lightbox-enabled")) return;
|
|
129
|
-
img.classList.add("jaamd-lightbox-enabled");
|
|
130
|
-
img.style.cursor = "pointer";
|
|
131
|
-
img.title = img.alt || "Click to enlarge";
|
|
132
|
-
img.addEventListener("click", () => openLightbox(img.src, img.alt));
|
|
133
|
-
});
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
function openLightbox(src: string, alt: string): void {
|
|
137
|
-
let lb = document.getElementById("jaamd-lightbox");
|
|
138
|
-
|
|
139
|
-
if (!lb) {
|
|
140
|
-
lb = document.createElement("div");
|
|
141
|
-
lb.id = "jaamd-lightbox";
|
|
142
|
-
lb.className = "jaamd-lightbox jaamd-lightbox--hidden";
|
|
143
|
-
lb.innerHTML =
|
|
144
|
-
`<div class="jaamd-lightbox__backdrop"></div>` +
|
|
145
|
-
`<div class="jaamd-lightbox__content">` +
|
|
146
|
-
`<button class="jaamd-lightbox__close" aria-label="Close lightbox">` +
|
|
147
|
-
`<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" width="1em" height="1em" aria-hidden="true">` +
|
|
148
|
-
`<path d="M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"/></svg>` +
|
|
149
|
-
`</button>` +
|
|
150
|
-
`<img class="jaamd-lightbox__img" src="" alt="" />` +
|
|
151
|
-
`</div>`;
|
|
152
|
-
document.body.appendChild(lb);
|
|
153
|
-
|
|
154
|
-
const close = (): void => {
|
|
155
|
-
lb!.classList.add("jaamd-lightbox--hidden");
|
|
156
|
-
document.body.style.overflow = "";
|
|
157
|
-
};
|
|
158
|
-
|
|
159
|
-
qs(lb, ".jaamd-lightbox__backdrop")!.addEventListener("click", close);
|
|
160
|
-
qs(lb, ".jaamd-lightbox__close")!.addEventListener("click", close);
|
|
161
|
-
document.addEventListener("keydown", (e) => {
|
|
162
|
-
if (e.key === "Escape" && !lb!.classList.contains("jaamd-lightbox--hidden"))
|
|
163
|
-
close();
|
|
164
|
-
});
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
(qs<HTMLImageElement>(lb, ".jaamd-lightbox__img")!).src = src;
|
|
168
|
-
(qs<HTMLImageElement>(lb, ".jaamd-lightbox__img")!).alt = alt ?? "";
|
|
169
|
-
lb.classList.remove("jaamd-lightbox--hidden");
|
|
170
|
-
document.body.style.overflow = "hidden";
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
// ─── Responsive table wrapper ─────────────────────────────────────────────────
|
|
174
|
-
|
|
175
|
-
function wrapTables(selector: string): void {
|
|
176
|
-
qsa<HTMLTableElement>(document, `${selector} table`).forEach((table) => {
|
|
177
|
-
if (table.parentElement?.classList.contains("jaamd-table-wrapper")) return;
|
|
178
|
-
const wrapper = document.createElement("div");
|
|
179
|
-
wrapper.className = "jaamd-table-wrapper";
|
|
180
|
-
table.parentNode!.insertBefore(wrapper, table);
|
|
181
|
-
wrapper.appendChild(table);
|
|
182
|
-
});
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
// ─── Code tabs ────────────────────────────────────────────────────────────────
|
|
186
|
-
|
|
187
|
-
function initCodeTabs(): void {
|
|
188
|
-
qsa<HTMLElement>(document, ".code-tabs").forEach((group) => {
|
|
189
|
-
if (group.dataset.tabsInit) return;
|
|
190
|
-
group.dataset.tabsInit = "1";
|
|
191
|
-
|
|
192
|
-
qsa<HTMLButtonElement>(group, ".code-tab-btn").forEach((btn) => {
|
|
193
|
-
btn.addEventListener("click", () => {
|
|
194
|
-
const idx = btn.dataset.tabIndex;
|
|
195
|
-
qsa(group, ".code-tab-btn").forEach((b) =>
|
|
196
|
-
b.classList.remove("active"),
|
|
197
|
-
);
|
|
198
|
-
qsa(group, ".code-tab-panel").forEach((p) =>
|
|
199
|
-
p.classList.remove("active"),
|
|
200
|
-
);
|
|
201
|
-
btn.classList.add("active");
|
|
202
|
-
qs(group, `.code-tab-panel[data-tab-index="${idx}"]`)?.classList.add(
|
|
203
|
-
"active",
|
|
204
|
-
);
|
|
205
|
-
});
|
|
206
|
-
});
|
|
207
|
-
});
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
// ─── Spoilers ─────────────────────────────────────────────────────────────────
|
|
211
|
-
|
|
212
|
-
function initSpoilers(selector: string): void {
|
|
213
|
-
qsa<HTMLElement>(document, `${selector} .spoiler`).forEach((el) => {
|
|
214
|
-
if (el.dataset.spoilerInit) return;
|
|
215
|
-
el.dataset.spoilerInit = "1";
|
|
216
|
-
el.addEventListener("click", () => el.classList.toggle("revealed"));
|
|
217
|
-
});
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
// ─── Details / Summary animation ─────────────────────────────────────────────
|
|
221
|
-
|
|
222
|
-
function initDetails(selector: string): void {
|
|
223
|
-
qsa<HTMLDetailsElement>(document, `${selector} details`).forEach(
|
|
224
|
-
(details) => {
|
|
225
|
-
if (details.dataset.detailsInit) return;
|
|
226
|
-
details.dataset.detailsInit = "1";
|
|
227
|
-
|
|
228
|
-
const summary = qs<HTMLElement>(details, "summary");
|
|
229
|
-
if (!summary) return;
|
|
230
|
-
|
|
231
|
-
// Two-level wrap:
|
|
232
|
-
// wrapper — animates height only
|
|
233
|
-
// inner — holds padding so it's baked into scrollHeight (no jump)
|
|
234
|
-
const wrapper = document.createElement("div");
|
|
235
|
-
wrapper.className = "jaamd-details-wrapper";
|
|
236
|
-
const inner = document.createElement("div");
|
|
237
|
-
inner.className = "jaamd-details-inner";
|
|
238
|
-
|
|
239
|
-
Array.from(details.childNodes).forEach((node) => {
|
|
240
|
-
if (node !== summary) inner.appendChild(node);
|
|
241
|
-
});
|
|
242
|
-
wrapper.appendChild(inner);
|
|
243
|
-
details.appendChild(wrapper);
|
|
244
|
-
|
|
245
|
-
if (!details.open) {
|
|
246
|
-
wrapper.style.height = "0px";
|
|
247
|
-
wrapper.style.overflow = "hidden";
|
|
248
|
-
}
|
|
249
|
-
|
|
250
|
-
summary.addEventListener("click", (e) => {
|
|
251
|
-
e.preventDefault();
|
|
252
|
-
|
|
253
|
-
if (details.open) {
|
|
254
|
-
// closing
|
|
255
|
-
const startH = wrapper.scrollHeight;
|
|
256
|
-
wrapper.style.overflow = "hidden";
|
|
257
|
-
const anim = wrapper.animate(
|
|
258
|
-
[{ height: `${startH}px` }, { height: "0px" }],
|
|
259
|
-
{ duration: 280, easing: "ease" },
|
|
260
|
-
);
|
|
261
|
-
anim.onfinish = () => {
|
|
262
|
-
wrapper.style.height = "0px";
|
|
263
|
-
details.removeAttribute("open");
|
|
264
|
-
};
|
|
265
|
-
} else {
|
|
266
|
-
// opening
|
|
267
|
-
details.setAttribute("open", "");
|
|
268
|
-
const endH = wrapper.scrollHeight;
|
|
269
|
-
wrapper.style.overflow = "hidden";
|
|
270
|
-
const anim = wrapper.animate(
|
|
271
|
-
[{ height: "0px" }, { height: `${endH}px` }],
|
|
272
|
-
{ duration: 280, easing: "ease" },
|
|
273
|
-
);
|
|
274
|
-
anim.onfinish = () => {
|
|
275
|
-
wrapper.style.height = "auto";
|
|
276
|
-
wrapper.style.overflow = "";
|
|
277
|
-
};
|
|
278
|
-
}
|
|
279
|
-
});
|
|
280
|
-
},
|
|
281
|
-
);
|
|
282
31
|
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { qs, qsa } from "../utils.js";
|
|
2
|
+
|
|
3
|
+
// ─── Code tabs ────────────────────────────────────────────────────────────────
|
|
4
|
+
|
|
5
|
+
export function initCodeTabs(): void {
|
|
6
|
+
qsa<HTMLElement>(document, ".code-tabs").forEach((group) => {
|
|
7
|
+
if (group.dataset.tabsInit) return;
|
|
8
|
+
group.dataset.tabsInit = "1";
|
|
9
|
+
|
|
10
|
+
qsa<HTMLButtonElement>(group, ".code-tab-btn").forEach((btn) => {
|
|
11
|
+
btn.addEventListener("click", () => {
|
|
12
|
+
const idx = btn.dataset.tabIndex;
|
|
13
|
+
qsa(group, ".code-tab-btn").forEach((b) =>
|
|
14
|
+
b.classList.remove("active"),
|
|
15
|
+
);
|
|
16
|
+
qsa(group, ".code-tab-panel").forEach((p) =>
|
|
17
|
+
p.classList.remove("active"),
|
|
18
|
+
);
|
|
19
|
+
btn.classList.add("active");
|
|
20
|
+
qs(group, `.code-tab-panel[data-tab-index="${idx}"]`)?.classList.add(
|
|
21
|
+
"active",
|
|
22
|
+
);
|
|
23
|
+
});
|
|
24
|
+
});
|
|
25
|
+
});
|
|
26
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { qs, qsa } from "../utils.js";
|
|
2
|
+
|
|
3
|
+
// ─── Code copy buttons ────────────────────────────────────────────────────────
|
|
4
|
+
|
|
5
|
+
export function addCopyButtons(selector: string): void {
|
|
6
|
+
qsa<HTMLElement>(document, `${selector} pre`).forEach((pre) => {
|
|
7
|
+
if (qs(pre, ".jaamd-copy-btn")) return;
|
|
8
|
+
const code = qs<HTMLElement>(pre, "code");
|
|
9
|
+
if (!code) return;
|
|
10
|
+
|
|
11
|
+
const btn = document.createElement("button");
|
|
12
|
+
btn.className = "jaamd-copy-btn";
|
|
13
|
+
btn.title = "Copy code";
|
|
14
|
+
btn.setAttribute("aria-label", "Copy code to clipboard");
|
|
15
|
+
btn.innerHTML = iconCopy();
|
|
16
|
+
|
|
17
|
+
btn.addEventListener("click", async () => {
|
|
18
|
+
try {
|
|
19
|
+
await navigator.clipboard.writeText(code.textContent ?? "");
|
|
20
|
+
const orig = btn.innerHTML;
|
|
21
|
+
btn.innerHTML = iconCheck();
|
|
22
|
+
btn.style.color = "var(--jaamd-color-success, #22c55e)";
|
|
23
|
+
setTimeout(() => {
|
|
24
|
+
btn.innerHTML = orig;
|
|
25
|
+
btn.style.color = "";
|
|
26
|
+
}, 2000);
|
|
27
|
+
} catch {
|
|
28
|
+
// fail silently
|
|
29
|
+
}
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
pre.appendChild(btn);
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function iconCopy(): string {
|
|
37
|
+
return `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" width="1em" height="1em" aria-hidden="true"><path d="M16 1H4c-1.1 0-2 .9-2 2v14h2V3h12V1zm3 4H8c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h11c1.1 0 2-.9 2-2V7c0-1.1-.9-2-2-2zm0 16H8V7h11v14z"/></svg>`;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function iconCheck(): string {
|
|
41
|
+
return `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" width="1em" height="1em" aria-hidden="true"><path d="M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z"/></svg>`;
|
|
42
|
+
}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { qs, qsa } from "../utils.js";
|
|
2
|
+
|
|
3
|
+
// ─── Details / Summary animation ─────────────────────────────────────────────
|
|
4
|
+
|
|
5
|
+
export function initDetails(selector: string): void {
|
|
6
|
+
qsa<HTMLDetailsElement>(document, `${selector} details`).forEach(
|
|
7
|
+
(details) => {
|
|
8
|
+
if (details.dataset.detailsInit) return;
|
|
9
|
+
details.dataset.detailsInit = "1";
|
|
10
|
+
|
|
11
|
+
const summary = qs<HTMLElement>(details, "summary");
|
|
12
|
+
if (!summary) return;
|
|
13
|
+
|
|
14
|
+
// Two-level wrap:
|
|
15
|
+
// wrapper — animates height only
|
|
16
|
+
// inner — holds padding so it's baked into scrollHeight (no jump)
|
|
17
|
+
const wrapper = document.createElement("div");
|
|
18
|
+
wrapper.className = "jaamd-details-wrapper";
|
|
19
|
+
const inner = document.createElement("div");
|
|
20
|
+
inner.className = "jaamd-details-inner";
|
|
21
|
+
|
|
22
|
+
Array.from(details.childNodes).forEach((node) => {
|
|
23
|
+
if (node !== summary) inner.appendChild(node);
|
|
24
|
+
});
|
|
25
|
+
wrapper.appendChild(inner);
|
|
26
|
+
details.appendChild(wrapper);
|
|
27
|
+
|
|
28
|
+
if (!details.open) {
|
|
29
|
+
wrapper.style.height = "0px";
|
|
30
|
+
wrapper.style.overflow = "hidden";
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
summary.addEventListener("click", (e) => {
|
|
34
|
+
e.preventDefault();
|
|
35
|
+
|
|
36
|
+
if (details.open) {
|
|
37
|
+
// closing
|
|
38
|
+
const startH = wrapper.scrollHeight;
|
|
39
|
+
wrapper.style.overflow = "hidden";
|
|
40
|
+
const anim = wrapper.animate(
|
|
41
|
+
[{ height: `${startH}px` }, { height: "0px" }],
|
|
42
|
+
{ duration: 280, easing: "ease" },
|
|
43
|
+
);
|
|
44
|
+
anim.onfinish = () => {
|
|
45
|
+
wrapper.style.height = "0px";
|
|
46
|
+
details.removeAttribute("open");
|
|
47
|
+
};
|
|
48
|
+
} else {
|
|
49
|
+
// opening
|
|
50
|
+
details.setAttribute("open", "");
|
|
51
|
+
const endH = wrapper.scrollHeight;
|
|
52
|
+
wrapper.style.overflow = "hidden";
|
|
53
|
+
const anim = wrapper.animate(
|
|
54
|
+
[{ height: "0px" }, { height: `${endH}px` }],
|
|
55
|
+
{ duration: 280, easing: "ease" },
|
|
56
|
+
);
|
|
57
|
+
anim.onfinish = () => {
|
|
58
|
+
wrapper.style.height = "auto";
|
|
59
|
+
wrapper.style.overflow = "";
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
});
|
|
63
|
+
},
|
|
64
|
+
);
|
|
65
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { qs, qsa, slugify } from "../utils.js";
|
|
2
|
+
|
|
3
|
+
// ─── Heading anchor links ─────────────────────────────────────────────────────
|
|
4
|
+
|
|
5
|
+
export function addHeadingLinks(selector: string): void {
|
|
6
|
+
qsa<HTMLElement>(document, `${selector} h1, ${selector} h2, ${selector} h3`).forEach(
|
|
7
|
+
(header) => {
|
|
8
|
+
if (!header.id) header.id = slugify(header.textContent ?? "");
|
|
9
|
+
if (qs(header, ".jaamd-heading-link")) return;
|
|
10
|
+
|
|
11
|
+
const a = document.createElement("a");
|
|
12
|
+
a.className = "jaamd-heading-link";
|
|
13
|
+
a.setAttribute("aria-label", `Link to section: ${header.textContent}`);
|
|
14
|
+
a.setAttribute("href", `#${header.id}`);
|
|
15
|
+
a.title = "Copy link";
|
|
16
|
+
a.innerHTML =
|
|
17
|
+
`<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" ` +
|
|
18
|
+
`stroke="currentColor" stroke-width="2" stroke-linecap="round" ` +
|
|
19
|
+
`stroke-linejoin="round" width="1em" height="1em" aria-hidden="true">` +
|
|
20
|
+
`<path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"/>` +
|
|
21
|
+
`<path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"/>` +
|
|
22
|
+
`</svg>`;
|
|
23
|
+
|
|
24
|
+
a.addEventListener("click", async (e) => {
|
|
25
|
+
e.preventDefault();
|
|
26
|
+
const url = `${location.origin}${location.pathname}#${header.id}`;
|
|
27
|
+
try {
|
|
28
|
+
await navigator.clipboard.writeText(url);
|
|
29
|
+
} catch {
|
|
30
|
+
// clipboard not available (e.g. non-secure context) — fail silently
|
|
31
|
+
}
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
header.appendChild(a);
|
|
35
|
+
},
|
|
36
|
+
);
|
|
37
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { qs, qsa } from "../utils.js";
|
|
2
|
+
|
|
3
|
+
// ─── Image lightbox ───────────────────────────────────────────────────────────
|
|
4
|
+
|
|
5
|
+
export function addImageLightbox(selector: string): void {
|
|
6
|
+
qsa<HTMLImageElement>(document, `${selector} img`).forEach((img) => {
|
|
7
|
+
if (img.classList.contains("jaamd-lightbox-enabled")) return;
|
|
8
|
+
img.classList.add("jaamd-lightbox-enabled");
|
|
9
|
+
img.style.cursor = "pointer";
|
|
10
|
+
img.title = img.alt || "Click to enlarge";
|
|
11
|
+
img.addEventListener("click", () => openLightbox(img.src, img.alt));
|
|
12
|
+
});
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
function openLightbox(src: string, alt: string): void {
|
|
16
|
+
let lb = document.getElementById("jaamd-lightbox");
|
|
17
|
+
|
|
18
|
+
if (!lb) {
|
|
19
|
+
lb = document.createElement("div");
|
|
20
|
+
lb.id = "jaamd-lightbox";
|
|
21
|
+
lb.className = "jaamd-lightbox jaamd-lightbox--hidden";
|
|
22
|
+
lb.innerHTML =
|
|
23
|
+
`<div class="jaamd-lightbox__backdrop"></div>` +
|
|
24
|
+
`<div class="jaamd-lightbox__content">` +
|
|
25
|
+
`<button class="jaamd-lightbox__close" aria-label="Close lightbox">` +
|
|
26
|
+
`<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" width="1em" height="1em" aria-hidden="true">` +
|
|
27
|
+
`<path d="M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"/></svg>` +
|
|
28
|
+
`</button>` +
|
|
29
|
+
`<img class="jaamd-lightbox__img" src="" alt="" />` +
|
|
30
|
+
`</div>`;
|
|
31
|
+
document.body.appendChild(lb);
|
|
32
|
+
|
|
33
|
+
const close = (): void => {
|
|
34
|
+
lb!.classList.add("jaamd-lightbox--hidden");
|
|
35
|
+
document.body.style.overflow = "";
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
qs(lb, ".jaamd-lightbox__backdrop")!.addEventListener("click", close);
|
|
39
|
+
qs(lb, ".jaamd-lightbox__close")!.addEventListener("click", close);
|
|
40
|
+
document.addEventListener("keydown", (e) => {
|
|
41
|
+
if (e.key === "Escape" && !lb!.classList.contains("jaamd-lightbox--hidden"))
|
|
42
|
+
close();
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
(qs<HTMLImageElement>(lb, ".jaamd-lightbox__img")!).src = src;
|
|
47
|
+
(qs<HTMLImageElement>(lb, ".jaamd-lightbox__img")!).alt = alt ?? "";
|
|
48
|
+
lb.classList.remove("jaamd-lightbox--hidden");
|
|
49
|
+
document.body.style.overflow = "hidden";
|
|
50
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { qsa } from "../utils.js";
|
|
2
|
+
|
|
3
|
+
// ─── Spoilers ─────────────────────────────────────────────────────────────────
|
|
4
|
+
|
|
5
|
+
export function initSpoilers(selector: string): void {
|
|
6
|
+
qsa<HTMLElement>(document, `${selector} .spoiler`).forEach((el) => {
|
|
7
|
+
if (el.dataset.spoilerInit) return;
|
|
8
|
+
el.dataset.spoilerInit = "1";
|
|
9
|
+
el.addEventListener("click", () => el.classList.toggle("revealed"));
|
|
10
|
+
});
|
|
11
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { qsa } from "../utils.js";
|
|
2
|
+
|
|
3
|
+
// ─── Responsive table wrapper ─────────────────────────────────────────────────
|
|
4
|
+
|
|
5
|
+
export function wrapTables(selector: string): void {
|
|
6
|
+
qsa<HTMLTableElement>(document, `${selector} table`).forEach((table) => {
|
|
7
|
+
if (table.parentElement?.classList.contains("jaamd-table-wrapper")) return;
|
|
8
|
+
const wrapper = document.createElement("div");
|
|
9
|
+
wrapper.className = "jaamd-table-wrapper";
|
|
10
|
+
table.parentNode!.insertBefore(wrapper, table);
|
|
11
|
+
wrapper.appendChild(table);
|
|
12
|
+
});
|
|
13
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
// ─── Shared DOM utilities ─────────────────────────────────────────────────────
|
|
2
|
+
|
|
3
|
+
export function slugify(text: string): string {
|
|
4
|
+
return text
|
|
5
|
+
.toLowerCase()
|
|
6
|
+
.trim()
|
|
7
|
+
.replace(/[^\w\s-]/g, "")
|
|
8
|
+
.replace(/[\s_]+/g, "-")
|
|
9
|
+
.replace(/^-+|-+$/g, "");
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export function qs<T extends Element = Element>(
|
|
13
|
+
root: ParentNode,
|
|
14
|
+
sel: string,
|
|
15
|
+
): T | null {
|
|
16
|
+
return root.querySelector<T>(sel);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export function qsa<T extends Element = Element>(
|
|
20
|
+
root: ParentNode,
|
|
21
|
+
sel: string,
|
|
22
|
+
): NodeListOf<T> {
|
|
23
|
+
return root.querySelectorAll<T>(sel);
|
|
24
|
+
}
|
package/src/styles/markdown.css
CHANGED
|
@@ -361,11 +361,11 @@
|
|
|
361
361
|
animation: jaamd-fade-in 0.2s ease-in-out;
|
|
362
362
|
}
|
|
363
363
|
|
|
364
|
-
.jaamd-lightbox
|
|
364
|
+
.jaamd-lightbox--hidden {
|
|
365
365
|
display: none;
|
|
366
366
|
}
|
|
367
367
|
|
|
368
|
-
.jaamd-
|
|
368
|
+
.jaamd-lightbox__backdrop {
|
|
369
369
|
position: absolute;
|
|
370
370
|
inset: 0;
|
|
371
371
|
background-color: rgba(0, 0, 0, 0.75);
|
|
@@ -373,7 +373,7 @@
|
|
|
373
373
|
cursor: pointer;
|
|
374
374
|
}
|
|
375
375
|
|
|
376
|
-
.jaamd-
|
|
376
|
+
.jaamd-lightbox__content {
|
|
377
377
|
position: relative;
|
|
378
378
|
max-width: 95vw;
|
|
379
379
|
max-height: 95vh;
|
|
@@ -383,7 +383,7 @@
|
|
|
383
383
|
z-index: 1;
|
|
384
384
|
}
|
|
385
385
|
|
|
386
|
-
.jaamd-
|
|
386
|
+
.jaamd-lightbox__img {
|
|
387
387
|
max-width: 100%;
|
|
388
388
|
max-height: 95vh;
|
|
389
389
|
width: auto;
|
|
@@ -393,7 +393,7 @@
|
|
|
393
393
|
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.5);
|
|
394
394
|
}
|
|
395
395
|
|
|
396
|
-
.jaamd-
|
|
396
|
+
.jaamd-lightbox__close {
|
|
397
397
|
position: fixed;
|
|
398
398
|
top: 1rem;
|
|
399
399
|
right: 1rem;
|
|
@@ -413,13 +413,13 @@
|
|
|
413
413
|
z-index: 10;
|
|
414
414
|
}
|
|
415
415
|
|
|
416
|
-
.jaamd-
|
|
416
|
+
.jaamd-lightbox__close:hover {
|
|
417
417
|
background: rgba(255, 255, 255, 0.2);
|
|
418
418
|
border-color: rgba(255, 255, 255, 0.3);
|
|
419
419
|
transform: scale(1.1);
|
|
420
420
|
}
|
|
421
421
|
|
|
422
|
-
.jaamd-
|
|
422
|
+
.jaamd-lightbox__close:active {
|
|
423
423
|
transform: scale(0.95);
|
|
424
424
|
}
|
|
425
425
|
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/* ============================================================
|
|
2
|
+
* JAAMD — Shiki Dual-Theme Switching
|
|
3
|
+
* ============================================================
|
|
4
|
+
*
|
|
5
|
+
* Injected automatically when theme is { light, dark }.
|
|
6
|
+
* Applies the correct Shiki CSS-variable set based on html.dark.
|
|
7
|
+
*
|
|
8
|
+
* Importable as: import "jaamd/shiki-dual";
|
|
9
|
+
* @import "jaamd/shiki-dual.css";
|
|
10
|
+
* ============================================================ */
|
|
11
|
+
|
|
12
|
+
/* Light mode (default) — use --shiki-light-* variables */
|
|
13
|
+
.jaamd-content .astro-code span,
|
|
14
|
+
.jaamd-content .shiki span {
|
|
15
|
+
color: var(--shiki-light) !important;
|
|
16
|
+
font-style: var(--shiki-light-font-style) !important;
|
|
17
|
+
font-weight: var(--shiki-light-font-weight) !important;
|
|
18
|
+
text-decoration: var(--shiki-light-text-decoration) !important;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/* Dark mode — switch to --shiki-dark-* variants */
|
|
22
|
+
html.dark .jaamd-content .astro-code span,
|
|
23
|
+
html.dark .jaamd-content .shiki span {
|
|
24
|
+
color: var(--shiki-dark) !important;
|
|
25
|
+
font-style: var(--shiki-dark-font-style) !important;
|
|
26
|
+
font-weight: var(--shiki-dark-font-weight) !important;
|
|
27
|
+
text-decoration: var(--shiki-dark-text-decoration) !important;
|
|
28
|
+
}
|
package/src/styles/variables.css
CHANGED
|
@@ -206,4 +206,64 @@
|
|
|
206
206
|
--jaamd-alert-caution-color: #cf222e;
|
|
207
207
|
--jaamd-alert-caution-bg: #ffebe9;
|
|
208
208
|
}
|
|
209
|
+
|
|
210
|
+
/* ── Dark mode overrides ─────────────────────────────────── */
|
|
211
|
+
|
|
212
|
+
html.dark {
|
|
213
|
+
--jaamd-color-fg: #c9d1d9;
|
|
214
|
+
--jaamd-color-fg-bright: #e6edf3;
|
|
215
|
+
--jaamd-color-primary: #c9d1d9;
|
|
216
|
+
--jaamd-color-primary-light: #8b949e;
|
|
217
|
+
|
|
218
|
+
--jaamd-heading-border-color: rgb(from var(--jaamd-color-primary) r g b / 0.3);
|
|
219
|
+
|
|
220
|
+
--jaamd-code-bg: #161b22;
|
|
221
|
+
--jaamd-code-border: #30363d;
|
|
222
|
+
--jaamd-code-fg: #e6edf3;
|
|
223
|
+
|
|
224
|
+
--jaamd-pre-bg: #161b22;
|
|
225
|
+
--jaamd-pre-border: #30363d;
|
|
226
|
+
--jaamd-pre-fg: #c9d1d9;
|
|
227
|
+
|
|
228
|
+
--jaamd-copy-btn-bg: #21262d;
|
|
229
|
+
--jaamd-copy-btn-border: #30363d;
|
|
230
|
+
--jaamd-copy-btn-fg: #c9d1d9;
|
|
231
|
+
--jaamd-copy-btn-hover-bg: #30363d;
|
|
232
|
+
--jaamd-copy-btn-hover-border: #484f58;
|
|
233
|
+
--jaamd-copy-btn-hover-fg: #e6edf3;
|
|
234
|
+
|
|
235
|
+
--jaamd-blockquote-bg: #161b22;
|
|
236
|
+
--jaamd-blockquote-border: #484f58;
|
|
237
|
+
--jaamd-blockquote-fg: #8b949e;
|
|
238
|
+
|
|
239
|
+
--jaamd-em-fg: #8b949e;
|
|
240
|
+
--jaamd-hr-color: rgb(from var(--jaamd-color-primary) r g b / 0.3);
|
|
241
|
+
|
|
242
|
+
--jaamd-table-border: #30363d;
|
|
243
|
+
--jaamd-table-header-bg: #161b22;
|
|
244
|
+
--jaamd-table-hover-bg: #1c2128;
|
|
245
|
+
|
|
246
|
+
--jaamd-tabs-border: #30363d;
|
|
247
|
+
--jaamd-tabs-header-bg: #1c2128;
|
|
248
|
+
--jaamd-tabs-btn-hover-bg: #21262d;
|
|
249
|
+
--jaamd-tabs-btn-active-bg: #161b22;
|
|
250
|
+
|
|
251
|
+
--jaamd-details-bg: #161b22;
|
|
252
|
+
--jaamd-details-border: #30363d;
|
|
253
|
+
|
|
254
|
+
--jaamd-spoiler-hidden-color: #e6edf3;
|
|
255
|
+
--jaamd-spoiler-revealed-bg: #161b22;
|
|
256
|
+
--jaamd-spoiler-revealed-fg: #c9d1d9;
|
|
257
|
+
|
|
258
|
+
--jaamd-alert-note-color: #58a6ff;
|
|
259
|
+
--jaamd-alert-note-bg: rgba(56, 139, 253, 0.1);
|
|
260
|
+
--jaamd-alert-tip-color: #3fb950;
|
|
261
|
+
--jaamd-alert-tip-bg: rgba(46, 160, 67, 0.1);
|
|
262
|
+
--jaamd-alert-important-color: #a371f7;
|
|
263
|
+
--jaamd-alert-important-bg: rgba(163, 113, 247, 0.1);
|
|
264
|
+
--jaamd-alert-warning-color: #d29922;
|
|
265
|
+
--jaamd-alert-warning-bg: rgba(187, 128, 9, 0.1);
|
|
266
|
+
--jaamd-alert-caution-color: #f85149;
|
|
267
|
+
--jaamd-alert-caution-bg: rgba(248, 81, 73, 0.1);
|
|
268
|
+
}
|
|
209
269
|
}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/* ============================================================
|
|
2
|
+
* JAAMD Theme — Dracula
|
|
3
|
+
* Pairs with Shiki theme: "dracula" or "dracula-soft"
|
|
4
|
+
* ============================================================
|
|
5
|
+
*
|
|
6
|
+
* Import: @import "jaamd/themes/dracula/dark";
|
|
7
|
+
* import "jaamd/themes/dracula/dark";
|
|
8
|
+
* ============================================================ */
|
|
9
|
+
|
|
10
|
+
html.dark {
|
|
11
|
+
--jaamd-color-fg: #f8f8f2;
|
|
12
|
+
--jaamd-color-fg-bright: #ffffff;
|
|
13
|
+
--jaamd-color-primary: #bd93f9;
|
|
14
|
+
--jaamd-color-primary-light: #ff79c6;
|
|
15
|
+
|
|
16
|
+
--jaamd-heading-border-color: rgba(189, 147, 249, 0.3);
|
|
17
|
+
|
|
18
|
+
--jaamd-code-bg: #44475a;
|
|
19
|
+
--jaamd-code-border: #6272a4;
|
|
20
|
+
--jaamd-code-fg: #f8f8f2;
|
|
21
|
+
|
|
22
|
+
--jaamd-pre-bg: #282a36;
|
|
23
|
+
--jaamd-pre-border: #44475a;
|
|
24
|
+
--jaamd-pre-fg: #f8f8f2;
|
|
25
|
+
|
|
26
|
+
--jaamd-copy-btn-bg: #44475a;
|
|
27
|
+
--jaamd-copy-btn-border: #6272a4;
|
|
28
|
+
--jaamd-copy-btn-fg: #f8f8f2;
|
|
29
|
+
--jaamd-copy-btn-hover-bg: #6272a4;
|
|
30
|
+
--jaamd-copy-btn-hover-border: #bd93f9;
|
|
31
|
+
--jaamd-copy-btn-hover-fg: #ffffff;
|
|
32
|
+
|
|
33
|
+
--jaamd-blockquote-bg: #282a36;
|
|
34
|
+
--jaamd-blockquote-border: #6272a4;
|
|
35
|
+
--jaamd-blockquote-fg: #6272a4;
|
|
36
|
+
|
|
37
|
+
--jaamd-em-fg: #8be9fd;
|
|
38
|
+
--jaamd-hr-color: rgba(189, 147, 249, 0.3);
|
|
39
|
+
|
|
40
|
+
--jaamd-table-border: #44475a;
|
|
41
|
+
--jaamd-table-header-bg: #282a36;
|
|
42
|
+
--jaamd-table-hover-bg: #44475a;
|
|
43
|
+
|
|
44
|
+
--jaamd-tabs-border: #44475a;
|
|
45
|
+
--jaamd-tabs-header-bg: #21222c;
|
|
46
|
+
--jaamd-tabs-btn-hover-bg: #44475a;
|
|
47
|
+
--jaamd-tabs-btn-active-bg: #282a36;
|
|
48
|
+
|
|
49
|
+
--jaamd-details-bg: #282a36;
|
|
50
|
+
--jaamd-details-border: #44475a;
|
|
51
|
+
|
|
52
|
+
--jaamd-spoiler-hidden-color: #f8f8f2;
|
|
53
|
+
--jaamd-spoiler-revealed-bg: #44475a;
|
|
54
|
+
--jaamd-spoiler-revealed-fg: #f8f8f2;
|
|
55
|
+
|
|
56
|
+
--jaamd-alert-note-color: #8be9fd;
|
|
57
|
+
--jaamd-alert-note-bg: rgba(139, 233, 253, 0.1);
|
|
58
|
+
--jaamd-alert-tip-color: #50fa7b;
|
|
59
|
+
--jaamd-alert-tip-bg: rgba(80, 250, 123, 0.1);
|
|
60
|
+
--jaamd-alert-important-color: #bd93f9;
|
|
61
|
+
--jaamd-alert-important-bg: rgba(189, 147, 249, 0.1);
|
|
62
|
+
--jaamd-alert-warning-color: #f1fa8c;
|
|
63
|
+
--jaamd-alert-warning-bg: rgba(241, 250, 140, 0.1);
|
|
64
|
+
--jaamd-alert-caution-color: #ff5555;
|
|
65
|
+
--jaamd-alert-caution-bg: rgba(255, 85, 85, 0.1);
|
|
66
|
+
}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/* ============================================================
|
|
2
|
+
* JAAMD Theme — Dracula
|
|
3
|
+
* Pairs with Shiki theme: "dracula" or "dracula-soft"
|
|
4
|
+
* ============================================================
|
|
5
|
+
*
|
|
6
|
+
* Import: @import "jaamd/themes/dracula";
|
|
7
|
+
* import "jaamd/themes/dracula";
|
|
8
|
+
* ============================================================ */
|
|
9
|
+
|
|
10
|
+
:root {
|
|
11
|
+
--jaamd-color-fg: #f8f8f2;
|
|
12
|
+
--jaamd-color-fg-bright: #ffffff;
|
|
13
|
+
--jaamd-color-primary: #bd93f9;
|
|
14
|
+
--jaamd-color-primary-light: #ff79c6;
|
|
15
|
+
|
|
16
|
+
--jaamd-heading-border-color: rgba(189, 147, 249, 0.3);
|
|
17
|
+
|
|
18
|
+
--jaamd-code-bg: #44475a;
|
|
19
|
+
--jaamd-code-border: #6272a4;
|
|
20
|
+
--jaamd-code-fg: #f8f8f2;
|
|
21
|
+
|
|
22
|
+
--jaamd-pre-bg: #282a36;
|
|
23
|
+
--jaamd-pre-border: #44475a;
|
|
24
|
+
--jaamd-pre-fg: #f8f8f2;
|
|
25
|
+
|
|
26
|
+
--jaamd-copy-btn-bg: #44475a;
|
|
27
|
+
--jaamd-copy-btn-border: #6272a4;
|
|
28
|
+
--jaamd-copy-btn-fg: #f8f8f2;
|
|
29
|
+
--jaamd-copy-btn-hover-bg: #6272a4;
|
|
30
|
+
--jaamd-copy-btn-hover-border: #bd93f9;
|
|
31
|
+
--jaamd-copy-btn-hover-fg: #ffffff;
|
|
32
|
+
|
|
33
|
+
--jaamd-blockquote-bg: #282a36;
|
|
34
|
+
--jaamd-blockquote-border: #6272a4;
|
|
35
|
+
--jaamd-blockquote-fg: #6272a4;
|
|
36
|
+
|
|
37
|
+
--jaamd-em-fg: #8be9fd;
|
|
38
|
+
--jaamd-hr-color: rgba(189, 147, 249, 0.3);
|
|
39
|
+
|
|
40
|
+
--jaamd-table-border: #44475a;
|
|
41
|
+
--jaamd-table-header-bg: #282a36;
|
|
42
|
+
--jaamd-table-hover-bg: #44475a;
|
|
43
|
+
|
|
44
|
+
--jaamd-tabs-border: #44475a;
|
|
45
|
+
--jaamd-tabs-header-bg: #21222c;
|
|
46
|
+
--jaamd-tabs-btn-hover-bg: #44475a;
|
|
47
|
+
--jaamd-tabs-btn-active-bg: #282a36;
|
|
48
|
+
|
|
49
|
+
--jaamd-details-bg: #282a36;
|
|
50
|
+
--jaamd-details-border: #44475a;
|
|
51
|
+
|
|
52
|
+
--jaamd-spoiler-hidden-color: #f8f8f2;
|
|
53
|
+
--jaamd-spoiler-revealed-bg: #44475a;
|
|
54
|
+
--jaamd-spoiler-revealed-fg: #f8f8f2;
|
|
55
|
+
|
|
56
|
+
--jaamd-alert-note-color: #8be9fd;
|
|
57
|
+
--jaamd-alert-note-bg: rgba(139, 233, 253, 0.1);
|
|
58
|
+
--jaamd-alert-tip-color: #50fa7b;
|
|
59
|
+
--jaamd-alert-tip-bg: rgba(80, 250, 123, 0.1);
|
|
60
|
+
--jaamd-alert-important-color: #bd93f9;
|
|
61
|
+
--jaamd-alert-important-bg: rgba(189, 147, 249, 0.1);
|
|
62
|
+
--jaamd-alert-warning-color: #f1fa8c;
|
|
63
|
+
--jaamd-alert-warning-bg: rgba(241, 250, 140, 0.1);
|
|
64
|
+
--jaamd-alert-caution-color: #ff5555;
|
|
65
|
+
--jaamd-alert-caution-bg: rgba(255, 85, 85, 0.1);
|
|
66
|
+
}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/* ============================================================
|
|
2
|
+
* JAAMD Theme — Nord
|
|
3
|
+
* Pairs with Shiki theme: "nord"
|
|
4
|
+
* ============================================================
|
|
5
|
+
*
|
|
6
|
+
* Import: @import "jaamd/themes/nord/dark";
|
|
7
|
+
* import "jaamd/themes/nord/dark";
|
|
8
|
+
* ============================================================ */
|
|
9
|
+
|
|
10
|
+
html.dark {
|
|
11
|
+
--jaamd-color-fg: #d8dee9;
|
|
12
|
+
--jaamd-color-fg-bright: #eceff4;
|
|
13
|
+
--jaamd-color-primary: #88c0d0;
|
|
14
|
+
--jaamd-color-primary-light: #81a1c1;
|
|
15
|
+
|
|
16
|
+
--jaamd-heading-border-color: rgba(136, 192, 208, 0.3);
|
|
17
|
+
|
|
18
|
+
--jaamd-code-bg: #3b4252;
|
|
19
|
+
--jaamd-code-border: #4c566a;
|
|
20
|
+
--jaamd-code-fg: #eceff4;
|
|
21
|
+
|
|
22
|
+
--jaamd-pre-bg: #2e3440;
|
|
23
|
+
--jaamd-pre-border: #3b4252;
|
|
24
|
+
--jaamd-pre-fg: #d8dee9;
|
|
25
|
+
|
|
26
|
+
--jaamd-copy-btn-bg: #3b4252;
|
|
27
|
+
--jaamd-copy-btn-border: #4c566a;
|
|
28
|
+
--jaamd-copy-btn-fg: #d8dee9;
|
|
29
|
+
--jaamd-copy-btn-hover-bg: #4c566a;
|
|
30
|
+
--jaamd-copy-btn-hover-border: #88c0d0;
|
|
31
|
+
--jaamd-copy-btn-hover-fg: #eceff4;
|
|
32
|
+
|
|
33
|
+
--jaamd-blockquote-bg: #2e3440;
|
|
34
|
+
--jaamd-blockquote-border: #4c566a;
|
|
35
|
+
--jaamd-blockquote-fg: #81a1c1;
|
|
36
|
+
|
|
37
|
+
--jaamd-em-fg: #88c0d0;
|
|
38
|
+
--jaamd-hr-color: rgba(136, 192, 208, 0.3);
|
|
39
|
+
|
|
40
|
+
--jaamd-table-border: #3b4252;
|
|
41
|
+
--jaamd-table-header-bg: #2e3440;
|
|
42
|
+
--jaamd-table-hover-bg: #3b4252;
|
|
43
|
+
|
|
44
|
+
--jaamd-tabs-border: #3b4252;
|
|
45
|
+
--jaamd-tabs-header-bg: #2e3440;
|
|
46
|
+
--jaamd-tabs-btn-hover-bg: #3b4252;
|
|
47
|
+
--jaamd-tabs-btn-active-bg: #2e3440;
|
|
48
|
+
|
|
49
|
+
--jaamd-details-bg: #2e3440;
|
|
50
|
+
--jaamd-details-border: #3b4252;
|
|
51
|
+
|
|
52
|
+
--jaamd-spoiler-hidden-color: #eceff4;
|
|
53
|
+
--jaamd-spoiler-revealed-bg: #3b4252;
|
|
54
|
+
--jaamd-spoiler-revealed-fg: #d8dee9;
|
|
55
|
+
|
|
56
|
+
--jaamd-alert-note-color: #81a1c1;
|
|
57
|
+
--jaamd-alert-note-bg: rgba(129, 161, 193, 0.1);
|
|
58
|
+
--jaamd-alert-tip-color: #a3be8c;
|
|
59
|
+
--jaamd-alert-tip-bg: rgba(163, 190, 140, 0.1);
|
|
60
|
+
--jaamd-alert-important-color: #b48ead;
|
|
61
|
+
--jaamd-alert-important-bg: rgba(180, 142, 173, 0.1);
|
|
62
|
+
--jaamd-alert-warning-color: #ebcb8b;
|
|
63
|
+
--jaamd-alert-warning-bg: rgba(235, 203, 139, 0.1);
|
|
64
|
+
--jaamd-alert-caution-color: #bf616a;
|
|
65
|
+
--jaamd-alert-caution-bg: rgba(191, 97, 106, 0.1);
|
|
66
|
+
}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/* ============================================================
|
|
2
|
+
* JAAMD Theme — Nord
|
|
3
|
+
* Pairs with Shiki theme: "nord"
|
|
4
|
+
* ============================================================
|
|
5
|
+
*
|
|
6
|
+
* Import: @import "jaamd/themes/nord";
|
|
7
|
+
* import "jaamd/themes/nord";
|
|
8
|
+
* ============================================================ */
|
|
9
|
+
|
|
10
|
+
:root {
|
|
11
|
+
--jaamd-color-fg: #d8dee9;
|
|
12
|
+
--jaamd-color-fg-bright: #eceff4;
|
|
13
|
+
--jaamd-color-primary: #88c0d0;
|
|
14
|
+
--jaamd-color-primary-light: #81a1c1;
|
|
15
|
+
|
|
16
|
+
--jaamd-heading-border-color: rgba(136, 192, 208, 0.3);
|
|
17
|
+
|
|
18
|
+
--jaamd-code-bg: #3b4252;
|
|
19
|
+
--jaamd-code-border: #4c566a;
|
|
20
|
+
--jaamd-code-fg: #eceff4;
|
|
21
|
+
|
|
22
|
+
--jaamd-pre-bg: #2e3440;
|
|
23
|
+
--jaamd-pre-border: #3b4252;
|
|
24
|
+
--jaamd-pre-fg: #d8dee9;
|
|
25
|
+
|
|
26
|
+
--jaamd-copy-btn-bg: #3b4252;
|
|
27
|
+
--jaamd-copy-btn-border: #4c566a;
|
|
28
|
+
--jaamd-copy-btn-fg: #d8dee9;
|
|
29
|
+
--jaamd-copy-btn-hover-bg: #4c566a;
|
|
30
|
+
--jaamd-copy-btn-hover-border: #88c0d0;
|
|
31
|
+
--jaamd-copy-btn-hover-fg: #eceff4;
|
|
32
|
+
|
|
33
|
+
--jaamd-blockquote-bg: #2e3440;
|
|
34
|
+
--jaamd-blockquote-border: #4c566a;
|
|
35
|
+
--jaamd-blockquote-fg: #81a1c1;
|
|
36
|
+
|
|
37
|
+
--jaamd-em-fg: #88c0d0;
|
|
38
|
+
--jaamd-hr-color: rgba(136, 192, 208, 0.3);
|
|
39
|
+
|
|
40
|
+
--jaamd-table-border: #3b4252;
|
|
41
|
+
--jaamd-table-header-bg: #2e3440;
|
|
42
|
+
--jaamd-table-hover-bg: #3b4252;
|
|
43
|
+
|
|
44
|
+
--jaamd-tabs-border: #3b4252;
|
|
45
|
+
--jaamd-tabs-header-bg: #2e3440;
|
|
46
|
+
--jaamd-tabs-btn-hover-bg: #3b4252;
|
|
47
|
+
--jaamd-tabs-btn-active-bg: #2e3440;
|
|
48
|
+
|
|
49
|
+
--jaamd-details-bg: #2e3440;
|
|
50
|
+
--jaamd-details-border: #3b4252;
|
|
51
|
+
|
|
52
|
+
--jaamd-spoiler-hidden-color: #eceff4;
|
|
53
|
+
--jaamd-spoiler-revealed-bg: #3b4252;
|
|
54
|
+
--jaamd-spoiler-revealed-fg: #d8dee9;
|
|
55
|
+
|
|
56
|
+
--jaamd-alert-note-color: #81a1c1;
|
|
57
|
+
--jaamd-alert-note-bg: rgba(129, 161, 193, 0.1);
|
|
58
|
+
--jaamd-alert-tip-color: #a3be8c;
|
|
59
|
+
--jaamd-alert-tip-bg: rgba(163, 190, 140, 0.1);
|
|
60
|
+
--jaamd-alert-important-color: #b48ead;
|
|
61
|
+
--jaamd-alert-important-bg: rgba(180, 142, 173, 0.1);
|
|
62
|
+
--jaamd-alert-warning-color: #ebcb8b;
|
|
63
|
+
--jaamd-alert-warning-bg: rgba(235, 203, 139, 0.1);
|
|
64
|
+
--jaamd-alert-caution-color: #bf616a;
|
|
65
|
+
--jaamd-alert-caution-bg: rgba(191, 97, 106, 0.1);
|
|
66
|
+
}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/* ============================================================
|
|
2
|
+
* JAAMD Theme — One Dark
|
|
3
|
+
* Pairs with Shiki theme: "one-dark-pro"
|
|
4
|
+
* ============================================================
|
|
5
|
+
*
|
|
6
|
+
* Import: @import "jaamd/themes/one-dark/dark";
|
|
7
|
+
* import "jaamd/themes/one-dark/dark";
|
|
8
|
+
* ============================================================ */
|
|
9
|
+
|
|
10
|
+
html.dark {
|
|
11
|
+
--jaamd-color-fg: #abb2bf;
|
|
12
|
+
--jaamd-color-fg-bright: #e6e6e6;
|
|
13
|
+
--jaamd-color-primary: #61afef;
|
|
14
|
+
--jaamd-color-primary-light: #56b6c2;
|
|
15
|
+
|
|
16
|
+
--jaamd-heading-border-color: rgba(97, 175, 239, 0.3);
|
|
17
|
+
|
|
18
|
+
--jaamd-code-bg: #2c313c;
|
|
19
|
+
--jaamd-code-border: #3e4451;
|
|
20
|
+
--jaamd-code-fg: #e6e6e6;
|
|
21
|
+
|
|
22
|
+
--jaamd-pre-bg: #282c34;
|
|
23
|
+
--jaamd-pre-border: #2c313c;
|
|
24
|
+
--jaamd-pre-fg: #abb2bf;
|
|
25
|
+
|
|
26
|
+
--jaamd-copy-btn-bg: #2c313c;
|
|
27
|
+
--jaamd-copy-btn-border: #3e4451;
|
|
28
|
+
--jaamd-copy-btn-fg: #abb2bf;
|
|
29
|
+
--jaamd-copy-btn-hover-bg: #3e4451;
|
|
30
|
+
--jaamd-copy-btn-hover-border: #61afef;
|
|
31
|
+
--jaamd-copy-btn-hover-fg: #e6e6e6;
|
|
32
|
+
|
|
33
|
+
--jaamd-blockquote-bg: #2c313c;
|
|
34
|
+
--jaamd-blockquote-border: #3e4451;
|
|
35
|
+
--jaamd-blockquote-fg: #5c6370;
|
|
36
|
+
|
|
37
|
+
--jaamd-em-fg: #c678dd;
|
|
38
|
+
--jaamd-hr-color: rgba(97, 175, 239, 0.3);
|
|
39
|
+
|
|
40
|
+
--jaamd-table-border: #2c313c;
|
|
41
|
+
--jaamd-table-header-bg: #21252b;
|
|
42
|
+
--jaamd-table-hover-bg: #2c313c;
|
|
43
|
+
|
|
44
|
+
--jaamd-tabs-border: #2c313c;
|
|
45
|
+
--jaamd-tabs-header-bg: #21252b;
|
|
46
|
+
--jaamd-tabs-btn-hover-bg: #2c313c;
|
|
47
|
+
--jaamd-tabs-btn-active-bg: #282c34;
|
|
48
|
+
|
|
49
|
+
--jaamd-details-bg: #2c313c;
|
|
50
|
+
--jaamd-details-border: #3e4451;
|
|
51
|
+
|
|
52
|
+
--jaamd-spoiler-hidden-color: #e6e6e6;
|
|
53
|
+
--jaamd-spoiler-revealed-bg: #2c313c;
|
|
54
|
+
--jaamd-spoiler-revealed-fg: #abb2bf;
|
|
55
|
+
|
|
56
|
+
--jaamd-alert-note-color: #61afef;
|
|
57
|
+
--jaamd-alert-note-bg: rgba(97, 175, 239, 0.1);
|
|
58
|
+
--jaamd-alert-tip-color: #98c379;
|
|
59
|
+
--jaamd-alert-tip-bg: rgba(152, 195, 121, 0.1);
|
|
60
|
+
--jaamd-alert-important-color: #c678dd;
|
|
61
|
+
--jaamd-alert-important-bg: rgba(198, 120, 221, 0.1);
|
|
62
|
+
--jaamd-alert-warning-color: #e5c07b;
|
|
63
|
+
--jaamd-alert-warning-bg: rgba(229, 192, 123, 0.1);
|
|
64
|
+
--jaamd-alert-caution-color: #e06c75;
|
|
65
|
+
--jaamd-alert-caution-bg: rgba(224, 108, 117, 0.1);
|
|
66
|
+
}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/* ============================================================
|
|
2
|
+
* JAAMD Theme — One Dark
|
|
3
|
+
* Pairs with Shiki theme: "one-dark-pro"
|
|
4
|
+
* ============================================================
|
|
5
|
+
*
|
|
6
|
+
* Import: @import "jaamd/themes/one-dark";
|
|
7
|
+
* import "jaamd/themes/one-dark";
|
|
8
|
+
* ============================================================ */
|
|
9
|
+
|
|
10
|
+
:root {
|
|
11
|
+
--jaamd-color-fg: #abb2bf;
|
|
12
|
+
--jaamd-color-fg-bright: #e6e6e6;
|
|
13
|
+
--jaamd-color-primary: #61afef;
|
|
14
|
+
--jaamd-color-primary-light: #56b6c2;
|
|
15
|
+
|
|
16
|
+
--jaamd-heading-border-color: rgba(97, 175, 239, 0.3);
|
|
17
|
+
|
|
18
|
+
--jaamd-code-bg: #2c313c;
|
|
19
|
+
--jaamd-code-border: #3e4451;
|
|
20
|
+
--jaamd-code-fg: #e6e6e6;
|
|
21
|
+
|
|
22
|
+
--jaamd-pre-bg: #282c34;
|
|
23
|
+
--jaamd-pre-border: #2c313c;
|
|
24
|
+
--jaamd-pre-fg: #abb2bf;
|
|
25
|
+
|
|
26
|
+
--jaamd-copy-btn-bg: #2c313c;
|
|
27
|
+
--jaamd-copy-btn-border: #3e4451;
|
|
28
|
+
--jaamd-copy-btn-fg: #abb2bf;
|
|
29
|
+
--jaamd-copy-btn-hover-bg: #3e4451;
|
|
30
|
+
--jaamd-copy-btn-hover-border: #61afef;
|
|
31
|
+
--jaamd-copy-btn-hover-fg: #e6e6e6;
|
|
32
|
+
|
|
33
|
+
--jaamd-blockquote-bg: #2c313c;
|
|
34
|
+
--jaamd-blockquote-border: #3e4451;
|
|
35
|
+
--jaamd-blockquote-fg: #5c6370;
|
|
36
|
+
|
|
37
|
+
--jaamd-em-fg: #c678dd;
|
|
38
|
+
--jaamd-hr-color: rgba(97, 175, 239, 0.3);
|
|
39
|
+
|
|
40
|
+
--jaamd-table-border: #2c313c;
|
|
41
|
+
--jaamd-table-header-bg: #21252b;
|
|
42
|
+
--jaamd-table-hover-bg: #2c313c;
|
|
43
|
+
|
|
44
|
+
--jaamd-tabs-border: #2c313c;
|
|
45
|
+
--jaamd-tabs-header-bg: #21252b;
|
|
46
|
+
--jaamd-tabs-btn-hover-bg: #2c313c;
|
|
47
|
+
--jaamd-tabs-btn-active-bg: #282c34;
|
|
48
|
+
|
|
49
|
+
--jaamd-details-bg: #2c313c;
|
|
50
|
+
--jaamd-details-border: #3e4451;
|
|
51
|
+
|
|
52
|
+
--jaamd-spoiler-hidden-color: #e6e6e6;
|
|
53
|
+
--jaamd-spoiler-revealed-bg: #2c313c;
|
|
54
|
+
--jaamd-spoiler-revealed-fg: #abb2bf;
|
|
55
|
+
|
|
56
|
+
--jaamd-alert-note-color: #61afef;
|
|
57
|
+
--jaamd-alert-note-bg: rgba(97, 175, 239, 0.1);
|
|
58
|
+
--jaamd-alert-tip-color: #98c379;
|
|
59
|
+
--jaamd-alert-tip-bg: rgba(152, 195, 121, 0.1);
|
|
60
|
+
--jaamd-alert-important-color: #c678dd;
|
|
61
|
+
--jaamd-alert-important-bg: rgba(198, 120, 221, 0.1);
|
|
62
|
+
--jaamd-alert-warning-color: #e5c07b;
|
|
63
|
+
--jaamd-alert-warning-bg: rgba(229, 192, 123, 0.1);
|
|
64
|
+
--jaamd-alert-caution-color: #e06c75;
|
|
65
|
+
--jaamd-alert-caution-bg: rgba(224, 108, 117, 0.1);
|
|
66
|
+
}
|