@jaamd/jaad 0.0.0-stage → 1.0.0-rc.1
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 +58 -2
- package/dist/jaad.css +1331 -0
- package/docs/00-overview.md +25 -0
- package/docs/01-getting-started/01-installation.md +216 -0
- package/docs/01-getting-started/02-pages.md +109 -0
- package/docs/01-getting-started/03-deployment.md +100 -0
- package/docs/02-configurations/01-reference.md +215 -0
- package/docs/02-configurations/02-frontmatter.md +105 -0
- package/docs/02-configurations/03-i18n.md +210 -0
- package/docs/02-configurations/04-search.md +58 -0
- package/docs/02-configurations/05-themes.md +104 -0
- package/docs/02-configurations/06-styles.md +156 -0
- package/docs/02-configurations/07-custom-pages.md +119 -0
- package/docs/02-configurations/08-advanced-layout.md +139 -0
- package/docs/03-upgrading.md +208 -0
- package/index.ts +31 -0
- package/package.json +71 -3
- package/site.ts +36 -0
- package/src/config.ts +85 -0
- package/src/docs/advanced.ts +23 -0
- package/src/docs/collection.ts +109 -0
- package/src/docs/components/Breadcrumbs.astro +29 -0
- package/src/docs/components/DocsMobileNav.astro +90 -0
- package/src/docs/components/DocsNavTree.astro +57 -0
- package/src/docs/components/DocsPage.astro +66 -0
- package/src/docs/components/DocsPageNav.astro +53 -0
- package/src/docs/components/DocsSidebarLeft.astro +53 -0
- package/src/docs/components/PageActions.astro +83 -0
- package/src/docs/components/StructuredData.astro +55 -0
- package/src/docs/components/TableOfContents.astro +71 -0
- package/src/docs/config.ts +167 -0
- package/src/docs/content.ts +36 -0
- package/src/docs/endpoints.ts +89 -0
- package/src/docs/integration.ts +249 -0
- package/src/docs/layouts/DefaultDocsFrame.astro +33 -0
- package/src/docs/layouts/Docs.astro +169 -0
- package/src/docs/layouts/Page.astro +18 -0
- package/src/docs/link-plugins.ts +52 -0
- package/src/docs/links.ts +42 -0
- package/src/docs/locale-tree.ts +51 -0
- package/src/docs/model/ids.ts +87 -0
- package/src/docs/model/rendered.ts +185 -0
- package/src/docs/model/tree.ts +124 -0
- package/src/docs/model/validate.ts +75 -0
- package/src/docs/navigation.ts +75 -0
- package/src/docs/routes/404.astro +16 -0
- package/src/docs/routes/docs-index.astro +19 -0
- package/src/docs/routes/docs-slug.astro +54 -0
- package/src/docs/routes/docs-slug.md.ts +35 -0
- package/src/docs/routes/llms-locale.txt.ts +8 -0
- package/src/docs/routes/llms.txt.ts +4 -0
- package/src/docs/routes/search-index-locale.json.ts +8 -0
- package/src/docs/routes/search-index.json.ts +4 -0
- package/src/docs/runtime.ts +17 -0
- package/src/docs/search-index.ts +39 -0
- package/src/docs/styles/components/breadcrumbs.css +26 -0
- package/src/docs/styles/components/docs-mobile-nav.css +47 -0
- package/src/docs/styles/components/docs-page-nav.css +41 -0
- package/src/docs/styles/components/docs-page.css +9 -0
- package/src/docs/styles/components/docs-sidebar.css +59 -0
- package/src/docs/styles/components/page-actions.css +51 -0
- package/src/docs/styles/components/toc.css +38 -0
- package/src/docs/styles/components.css +7 -0
- package/src/docs/styles/docs.css +81 -0
- package/src/docs/styles/jaamd.css +11 -0
- package/src/docs/types.ts +39 -0
- package/src/docs/urls.ts +35 -0
- package/src/env.d.ts +13 -0
- package/src/integration.ts +36 -0
- package/src/site/components/Footer.astro +18 -0
- package/src/site/components/Head.astro +119 -0
- package/src/site/components/Header.astro +50 -0
- package/src/site/components/LocaleSwitcher.astro +111 -0
- package/src/site/components/Nav.astro +22 -0
- package/src/site/components/NavMobile.astro +105 -0
- package/src/site/components/SearchPalette.astro +409 -0
- package/src/site/components/SocialLinks.astro +27 -0
- package/src/site/components/ThemeSwitcher.astro +55 -0
- package/src/site/components/locale-switcher.ts +6 -0
- package/src/site/config.ts +149 -0
- package/src/site/fonts/OFL.txt +94 -0
- package/src/site/fonts/inter.woff2 +0 -0
- package/src/site/fonts/merriweather-italic.woff2 +0 -0
- package/src/site/fonts/merriweather.woff2 +0 -0
- package/src/site/fonts.ts +29 -0
- package/src/site/forges.ts +60 -0
- package/src/site/helpers.ts +4 -0
- package/src/site/infer.ts +75 -0
- package/src/site/integration.ts +59 -0
- package/src/site/layouts/Shell.astro +41 -0
- package/src/site/locales.ts +199 -0
- package/src/site/runtime.ts +19 -0
- package/src/site/search.ts +227 -0
- package/src/site/social.ts +44 -0
- package/src/site/styles/components/footer.css +8 -0
- package/src/site/styles/components/header.css +31 -0
- package/src/site/styles/components/locale-switcher.css +20 -0
- package/src/site/styles/components/nav-mobile.css +15 -0
- package/src/site/styles/components/nav.css +11 -0
- package/src/site/styles/components/not-found.css +11 -0
- package/src/site/styles/components/search.css +118 -0
- package/src/site/styles/components/shell.css +77 -0
- package/src/site/styles/components/social-links.css +8 -0
- package/src/site/styles/components/theme-switcher.css +14 -0
- package/src/site/styles/components.css +10 -0
- package/src/site/styles/global.css +140 -0
- package/src/site/styles/jaamd-forward.css +16 -0
- package/src/site/styles/jaamd-reverse.css +18 -0
- package/src/site/styles/tailwind.css +30 -0
- package/src/site/themes.ts +26 -0
- package/src/site/ui/en.ts +27 -0
- package/src/site/ui/it.ts +28 -0
- package/src/site/ui.ts +49 -0
- package/src/site/urls.ts +14 -0
- package/src/site/virtual.ts +42 -0
- package/src/styles.css +5 -0
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
@layer components {
|
|
2
|
+
.jaad-search-trigger {
|
|
3
|
+
@apply border-border bg-surface hover:bg-surface-hover text-foreground-muted hidden cursor-pointer items-center gap-2 rounded-lg border px-3 py-1.5 text-sm transition-colors md:flex;
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
.jaad-search-trigger-icon {
|
|
7
|
+
@apply h-4 w-4 shrink-0;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
.jaad-search-trigger-label {
|
|
11
|
+
@apply hidden lg:inline;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
.jaad-search-shortcut {
|
|
15
|
+
@apply bg-background-secondary text-foreground-muted rounded px-1.5 py-0.5 text-xs font-medium;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/* Icon trigger on a docs page, where the desktop field is shown from md. */
|
|
19
|
+
.jaad-search-trigger-compact {
|
|
20
|
+
@apply md:hidden;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
.jaad-search-overlay {
|
|
24
|
+
@apply fixed inset-0 z-50 flex items-start justify-center px-4 pt-[15vh];
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
.jaad-search-backdrop {
|
|
28
|
+
@apply absolute inset-0 bg-black/60 backdrop-blur-sm;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
.jaad-search-panel {
|
|
32
|
+
@apply bg-surface border-border relative z-10 w-full max-w-lg overflow-hidden rounded-xl border shadow-2xl;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
.jaad-search-bar {
|
|
36
|
+
@apply border-border flex items-center gap-3 border-b px-4 py-3;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
.jaad-search-bar-icon {
|
|
40
|
+
@apply text-foreground-muted h-5 w-5 shrink-0;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
.jaad-search-input {
|
|
44
|
+
@apply text-foreground placeholder:text-foreground-muted min-w-0 flex-1 bg-transparent text-sm outline-none;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
.jaad-search-close {
|
|
48
|
+
@apply bg-background-secondary text-foreground-muted shrink-0 cursor-pointer rounded px-1.5 py-0.5 text-xs;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
.jaad-search-filters {
|
|
52
|
+
@apply border-border flex flex-wrap gap-1.5 border-b px-4 py-2;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
.jaad-search-filter {
|
|
56
|
+
@apply border-border text-foreground-muted hover:text-foreground cursor-pointer rounded-full border px-2.5 py-0.5 text-xs transition-colors;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
.jaad-search-filter[aria-pressed='true'] {
|
|
60
|
+
@apply border-primary/40 bg-primary/10 text-foreground-bright;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
.jaad-search-results {
|
|
64
|
+
@apply max-h-96 overflow-y-auto p-2;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
.jaad-search-group {
|
|
68
|
+
@apply text-foreground-muted px-3 pt-3 pb-1 text-xs font-semibold tracking-wide uppercase;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
.jaad-search-footer {
|
|
72
|
+
@apply border-border text-foreground-muted flex items-center gap-4 border-t px-4 py-2 text-xs;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
.jaad-search-key {
|
|
76
|
+
@apply bg-background-secondary rounded px-1 py-0.5;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
.jaad-search-result {
|
|
80
|
+
@apply text-foreground cursor-pointer rounded-lg px-3 py-2.5 text-left transition-colors;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
.jaad-search-result:not([aria-selected='true']) {
|
|
84
|
+
@apply hover:bg-primary/5;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
.jaad-search-result[aria-selected='true'] {
|
|
88
|
+
@apply bg-primary/10 text-foreground-bright;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
.jaad-search-result-heading {
|
|
92
|
+
@apply border-border ml-3 rounded-l-none border-l py-2;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
.jaad-search-result-head {
|
|
96
|
+
@apply flex items-center gap-2;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
.jaad-search-result-title {
|
|
100
|
+
@apply text-sm font-medium;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
.jaad-search-result-badge {
|
|
104
|
+
@apply text-foreground-muted bg-background-secondary rounded px-1.5 py-0.5 text-[0.65rem];
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
.jaad-search-result-snippet {
|
|
108
|
+
@apply text-foreground-secondary mt-1 line-clamp-1 text-xs;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
.jaad-search-mark {
|
|
112
|
+
@apply bg-primary/20 text-foreground-bright rounded-sm px-0.5 font-semibold not-italic;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
.jaad-search-message {
|
|
116
|
+
@apply text-foreground-muted px-3 py-6 text-center text-sm;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/* Shared shell classes; first in the layer so component files override them. */
|
|
2
|
+
@layer components {
|
|
3
|
+
/* Header, footer and docs content share one measure. */
|
|
4
|
+
.jaad-chrome {
|
|
5
|
+
width: 100%;
|
|
6
|
+
max-width: var(--jaad-chrome-width);
|
|
7
|
+
margin-inline: auto;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
.jaad-main {
|
|
11
|
+
flex: 1;
|
|
12
|
+
margin-block: 4rem;
|
|
13
|
+
padding-inline: var(--jaad-page-padding);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
@media (min-width: 64rem) {
|
|
17
|
+
.jaad-main {
|
|
18
|
+
padding-inline: calc(var(--jaad-page-padding) * 2);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/* `bare` keeps the landmark without the spacing. */
|
|
23
|
+
.jaad-main-bare {
|
|
24
|
+
flex: 1;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
.jaad-body {
|
|
28
|
+
@apply bg-background text-foreground flex min-h-screen flex-col text-[14px] leading-[1.6];
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
.jaad-body {
|
|
32
|
+
padding-top: var(--jaad-header-height);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
.jaad-icon {
|
|
36
|
+
@apply h-5 w-5;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
.jaad-sr-only {
|
|
40
|
+
@apply sr-only;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
.jaad-sidebar {
|
|
44
|
+
width: var(--jaad-sidebar-width);
|
|
45
|
+
overflow-y: auto;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
.jaad-sidebar::-webkit-scrollbar {
|
|
49
|
+
width: 6px;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
.jaad-sidebar::-webkit-scrollbar-track {
|
|
53
|
+
background: transparent;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
.jaad-sidebar::-webkit-scrollbar-thumb {
|
|
57
|
+
background: rgb(from var(--color-primary) r g b / 0.2);
|
|
58
|
+
border-radius: 3px;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
.jaad-sidebar::-webkit-scrollbar-thumb:hover {
|
|
62
|
+
background: rgb(from var(--color-primary) r g b / 0.4);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/* The header controls sit in one row and have to stay identical. */
|
|
66
|
+
.jaad-icon-button {
|
|
67
|
+
@apply text-foreground-secondary hover:text-foreground-bright flex h-9 w-9 cursor-pointer items-center justify-center rounded-lg no-underline transition-colors;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
.jaad-menu {
|
|
71
|
+
@apply bg-surface border-border absolute top-full right-0 z-40 mt-2 w-44 overflow-hidden rounded-xl border shadow-lg;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
.jaad-menu-item {
|
|
75
|
+
@apply text-foreground-secondary hover:text-foreground-bright hover:bg-primary/5 block rounded-lg px-3 py-2 text-sm no-underline transition-colors;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
@layer components {
|
|
2
|
+
/* Both icons ship; CSS picks one, so the server-rendered control is correct. */
|
|
3
|
+
.jaad-theme-icon-to-light {
|
|
4
|
+
display: none;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
html.dark .jaad-theme-icon-to-dark {
|
|
8
|
+
display: none;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
html.dark .jaad-theme-icon-to-light {
|
|
12
|
+
display: block;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
@import './components/shell.css';
|
|
2
|
+
@import './components/header.css';
|
|
3
|
+
@import './components/footer.css';
|
|
4
|
+
@import './components/nav.css';
|
|
5
|
+
@import './components/nav-mobile.css';
|
|
6
|
+
@import './components/social-links.css';
|
|
7
|
+
@import './components/theme-switcher.css';
|
|
8
|
+
@import './components/locale-switcher.css';
|
|
9
|
+
@import './components/not-found.css';
|
|
10
|
+
@import './components/search.css';
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
@theme static {
|
|
2
|
+
/* Seeds */
|
|
3
|
+
|
|
4
|
+
--color-background: #faf8f5;
|
|
5
|
+
--color-surface: #ffffff;
|
|
6
|
+
--color-foreground: #3a3a3a;
|
|
7
|
+
--color-foreground-bright: #1a1a1a;
|
|
8
|
+
--color-primary: #2d2d2d;
|
|
9
|
+
|
|
10
|
+
--color-error: #c45959;
|
|
11
|
+
--color-warning: #d4a259;
|
|
12
|
+
--color-info: #5988c4;
|
|
13
|
+
--color-success: #5a9c7e;
|
|
14
|
+
|
|
15
|
+
/* Derived */
|
|
16
|
+
|
|
17
|
+
--color-background-secondary: color-mix(in oklab, var(--color-foreground) 2%, var(--color-background));
|
|
18
|
+
--color-background-tertiary: color-mix(in oklab, var(--color-foreground) 6%, var(--color-background));
|
|
19
|
+
--color-surface-hover: color-mix(in oklab, var(--color-foreground) 5%, var(--color-background));
|
|
20
|
+
|
|
21
|
+
--color-border-light: color-mix(in oklab, var(--color-foreground) 11%, var(--color-background));
|
|
22
|
+
--color-border: color-mix(in oklab, var(--color-foreground) 17%, var(--color-background));
|
|
23
|
+
--color-border-dark: color-mix(in oklab, var(--color-foreground) 25%, var(--color-background));
|
|
24
|
+
|
|
25
|
+
--color-foreground-muted: color-mix(in oklab, var(--color-foreground) 55%, var(--color-background));
|
|
26
|
+
--color-foreground-secondary: color-mix(in oklab, var(--color-foreground) 72%, var(--color-background));
|
|
27
|
+
|
|
28
|
+
--color-primary-dark: var(--color-foreground-bright);
|
|
29
|
+
--color-primary-light: color-mix(in oklab, var(--color-primary) 83%, var(--color-background));
|
|
30
|
+
|
|
31
|
+
/* Fonts */
|
|
32
|
+
--font-sans: var(--font-inter), -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
|
|
33
|
+
--font-serif: var(--font-merriweather), Georgia, serif;
|
|
34
|
+
--font-mono: 'SF Mono', SF Mono, Consolas, 'Liberation Mono', Menlo, Courier, monospace;
|
|
35
|
+
|
|
36
|
+
/* Layout */
|
|
37
|
+
--jaad-content-width: 56rem;
|
|
38
|
+
/* Sidebar, page and table of contents, with their gaps and the gutters. */
|
|
39
|
+
--jaad-chrome-width: calc(var(--jaad-content-width) + 2 * var(--jaad-sidebar-width) + 6rem);
|
|
40
|
+
--jaad-sidebar-width: 16rem;
|
|
41
|
+
--jaad-header-height: 4.25rem;
|
|
42
|
+
--jaad-page-padding: 2rem;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
@layer base {
|
|
46
|
+
html {
|
|
47
|
+
scroll-padding-top: calc(var(--jaad-header-height) + 1.5rem);
|
|
48
|
+
background-color: var(--color-background);
|
|
49
|
+
color: var(--color-foreground);
|
|
50
|
+
font-family: var(--font-sans);
|
|
51
|
+
font-size: 16px;
|
|
52
|
+
scroll-behavior: smooth;
|
|
53
|
+
scrollbar-gutter: stable;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
h1,
|
|
57
|
+
h2,
|
|
58
|
+
h3 {
|
|
59
|
+
color: var(--color-foreground-bright);
|
|
60
|
+
font-family: var(--font-serif);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
h2 {
|
|
64
|
+
margin-bottom: 1.5rem;
|
|
65
|
+
font-size: 1.5rem;
|
|
66
|
+
font-weight: 600;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
h3 {
|
|
70
|
+
margin-bottom: 1rem;
|
|
71
|
+
font-size: 1.2rem;
|
|
72
|
+
font-weight: normal;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
a {
|
|
76
|
+
@apply text-primary hover:text-primary-dark underline decoration-1 underline-offset-2 transition duration-200 ease-in-out;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
i {
|
|
80
|
+
@apply text-primary italic;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/* Utilities layer: wins over .jaad-brand's line-height. */
|
|
85
|
+
@layer utilities {
|
|
86
|
+
.font-brand {
|
|
87
|
+
font-family: var(--font-serif);
|
|
88
|
+
font-weight: 300;
|
|
89
|
+
font-style: italic;
|
|
90
|
+
letter-spacing: -0.01em;
|
|
91
|
+
line-height: 1;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/* Dark mode */
|
|
96
|
+
|
|
97
|
+
html.dark {
|
|
98
|
+
color-scheme: dark;
|
|
99
|
+
|
|
100
|
+
--color-background: #0d1117;
|
|
101
|
+
--color-surface: #21262d;
|
|
102
|
+
--color-foreground: #c9d1d9;
|
|
103
|
+
--color-foreground-bright: #e6edf3;
|
|
104
|
+
--color-primary: #c9d1d9;
|
|
105
|
+
|
|
106
|
+
--color-error: #f85149;
|
|
107
|
+
--color-warning: #d29922;
|
|
108
|
+
--color-info: #58a6ff;
|
|
109
|
+
--color-success: #3fb950;
|
|
110
|
+
|
|
111
|
+
--color-background-secondary: color-mix(in oklab, var(--color-foreground) 7%, var(--color-background));
|
|
112
|
+
--color-background-tertiary: color-mix(in oklab, var(--color-foreground) 10%, var(--color-background));
|
|
113
|
+
--color-surface-hover: color-mix(in oklab, var(--color-foreground) 22%, var(--color-background));
|
|
114
|
+
|
|
115
|
+
--color-border-light: color-mix(in oklab, var(--color-foreground) 13%, var(--color-background));
|
|
116
|
+
--color-border: color-mix(in oklab, var(--color-foreground) 22%, var(--color-background));
|
|
117
|
+
--color-border-dark: color-mix(in oklab, var(--color-foreground) 36%, var(--color-background));
|
|
118
|
+
|
|
119
|
+
--color-foreground-muted: color-mix(in oklab, var(--color-foreground) 57%, var(--color-background));
|
|
120
|
+
--color-foreground-secondary: color-mix(in oklab, var(--color-foreground) 71%, var(--color-background));
|
|
121
|
+
|
|
122
|
+
--color-primary-light: color-mix(in oklab, var(--color-primary) 71%, var(--color-background));
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/* Reduced motion */
|
|
126
|
+
|
|
127
|
+
@media (prefers-reduced-motion: reduce) {
|
|
128
|
+
html {
|
|
129
|
+
scroll-behavior: auto;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
*,
|
|
133
|
+
*::before,
|
|
134
|
+
*::after {
|
|
135
|
+
animation-duration: 0.01ms !important;
|
|
136
|
+
animation-iteration-count: 1 !important;
|
|
137
|
+
transition-duration: 0.01ms !important;
|
|
138
|
+
scroll-behavior: auto !important;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/* JAAD's palette drives JAAMD's. Used when the colours come from JAAD — its own
|
|
2
|
+
identity, or a custom theme written in src/jaad.css. */
|
|
3
|
+
|
|
4
|
+
:root {
|
|
5
|
+
--jaamd-bg: var(--color-background);
|
|
6
|
+
--jaamd-color-fg: var(--color-foreground);
|
|
7
|
+
--jaamd-color-fg-bright: var(--color-foreground-bright);
|
|
8
|
+
--jaamd-color-primary: var(--color-primary);
|
|
9
|
+
--jaamd-color-success: var(--color-success);
|
|
10
|
+
|
|
11
|
+
--jaamd-alert-note-color: var(--color-info);
|
|
12
|
+
--jaamd-alert-tip-color: var(--color-success);
|
|
13
|
+
--jaamd-alert-important-color: var(--color-primary);
|
|
14
|
+
--jaamd-alert-warning-color: var(--color-warning);
|
|
15
|
+
--jaamd-alert-caution-color: var(--color-error);
|
|
16
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/* JAAMD's palette drives JAAD's, the opposite direction to jaamd-forward.css.
|
|
2
|
+
Never both at once: together they are a cycle, and CSS drops both sides.
|
|
3
|
+
|
|
4
|
+
Only the seeds; global.css derives the rest with color-mix(). */
|
|
5
|
+
|
|
6
|
+
:root,
|
|
7
|
+
html.dark {
|
|
8
|
+
--color-background: var(--jaamd-bg);
|
|
9
|
+
--color-surface: var(--jaamd-surface-1);
|
|
10
|
+
--color-foreground: var(--jaamd-color-fg);
|
|
11
|
+
--color-foreground-bright: var(--jaamd-color-fg-bright);
|
|
12
|
+
--color-primary: var(--jaamd-color-primary);
|
|
13
|
+
|
|
14
|
+
--color-info: var(--jaamd-alert-note-color);
|
|
15
|
+
--color-success: var(--jaamd-alert-tip-color);
|
|
16
|
+
--color-warning: var(--jaamd-alert-warning-color);
|
|
17
|
+
--color-error: var(--jaamd-alert-caution-color);
|
|
18
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/* Opt-in (`tailwind: true`): site utilities read JAAD's tokens. No values, no preflight. */
|
|
2
|
+
@import 'tailwindcss/theme.css' layer(theme) theme(reference);
|
|
3
|
+
@import 'tailwindcss/utilities.css' layer(utilities);
|
|
4
|
+
|
|
5
|
+
@custom-variant dark (&:where(.dark, .dark *));
|
|
6
|
+
|
|
7
|
+
@theme reference {
|
|
8
|
+
--color-background: transparent;
|
|
9
|
+
--color-surface: transparent;
|
|
10
|
+
--color-foreground: transparent;
|
|
11
|
+
--color-foreground-bright: transparent;
|
|
12
|
+
--color-primary: transparent;
|
|
13
|
+
--color-error: transparent;
|
|
14
|
+
--color-warning: transparent;
|
|
15
|
+
--color-info: transparent;
|
|
16
|
+
--color-success: transparent;
|
|
17
|
+
--color-background-secondary: transparent;
|
|
18
|
+
--color-background-tertiary: transparent;
|
|
19
|
+
--color-surface-hover: transparent;
|
|
20
|
+
--color-border-light: transparent;
|
|
21
|
+
--color-border: transparent;
|
|
22
|
+
--color-border-dark: transparent;
|
|
23
|
+
--color-foreground-muted: transparent;
|
|
24
|
+
--color-foreground-secondary: transparent;
|
|
25
|
+
--color-primary-dark: transparent;
|
|
26
|
+
--color-primary-light: transparent;
|
|
27
|
+
--font-sans: transparent;
|
|
28
|
+
--font-serif: transparent;
|
|
29
|
+
--font-mono: transparent;
|
|
30
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { themes } from '@jaamd/astro/themes'
|
|
2
|
+
|
|
3
|
+
export interface Preset {
|
|
4
|
+
/** Shiki theme, or a light/dark pair, for code blocks. */
|
|
5
|
+
shiki: string | { light: string; dark: string }
|
|
6
|
+
/** JAAMD theme slug, or null when JAAD's own identity already applies. */
|
|
7
|
+
theme: string | null
|
|
8
|
+
/** `dual` carries a light and a dark palette; the others apply in both modes. */
|
|
9
|
+
mode: 'light' | 'dark' | 'dual'
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
/** JAAMD's palettes, plus `default`: JAAD's own, which needs no stylesheet. */
|
|
13
|
+
export const PRESETS: Record<string, Preset> = {
|
|
14
|
+
default: {
|
|
15
|
+
shiki: { light: 'github-light', dark: 'github-dark' },
|
|
16
|
+
theme: null,
|
|
17
|
+
mode: 'dual',
|
|
18
|
+
},
|
|
19
|
+
...Object.fromEntries(
|
|
20
|
+
themes.map((theme) => [theme.slug, { shiki: theme.shiki, theme: theme.slug, mode: theme.mode }]),
|
|
21
|
+
),
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export const PRESET_NAMES = Object.keys(PRESETS)
|
|
25
|
+
|
|
26
|
+
export const isPreset = (value: string): boolean => value in PRESETS
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/** The canonical UI catalogue: its keys define every catalogue JAAD accepts. */
|
|
2
|
+
export const ENGLISH_UI = {
|
|
3
|
+
'breadcrumb.label': 'Breadcrumb',
|
|
4
|
+
home: 'Home',
|
|
5
|
+
'locale.change': 'Change language',
|
|
6
|
+
'nav.documentation': 'Documentation navigation',
|
|
7
|
+
'nav.mobile': 'Toggle mobile menu',
|
|
8
|
+
'nav.page': 'Page navigation',
|
|
9
|
+
'page.copied': 'Copied!',
|
|
10
|
+
'page.copy': 'Copy page',
|
|
11
|
+
'page.edit': 'Edit this page',
|
|
12
|
+
'page.lastUpdated': 'Last updated on',
|
|
13
|
+
'search.all': 'All',
|
|
14
|
+
'search.close': 'close',
|
|
15
|
+
'search.empty': 'No results for',
|
|
16
|
+
'search.label': 'Search documentation',
|
|
17
|
+
'search.loading': 'Loading...',
|
|
18
|
+
'search.navigate': 'navigate',
|
|
19
|
+
'search.open': 'open',
|
|
20
|
+
'search.placeholder': 'Search documentation...',
|
|
21
|
+
'search.results': 'Search results',
|
|
22
|
+
'search.sections': 'Search in',
|
|
23
|
+
'search.trigger': 'Search docs...',
|
|
24
|
+
'theme.toggle': 'Toggle color theme',
|
|
25
|
+
'toc.label': 'Table of contents',
|
|
26
|
+
'toc.title': 'On this page',
|
|
27
|
+
} as const
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { UiCatalog } from '../ui.ts'
|
|
2
|
+
|
|
3
|
+
export const ITALIAN_UI = {
|
|
4
|
+
'breadcrumb.label': 'Percorso di navigazione',
|
|
5
|
+
home: 'Pagina iniziale',
|
|
6
|
+
'locale.change': 'Cambia lingua',
|
|
7
|
+
'nav.documentation': 'Navigazione della documentazione',
|
|
8
|
+
'nav.mobile': 'Apri o chiudi il menu',
|
|
9
|
+
'nav.page': 'Navigazione tra le pagine',
|
|
10
|
+
'page.copied': 'Copiata!',
|
|
11
|
+
'page.copy': 'Copia',
|
|
12
|
+
'page.edit': 'Modifica',
|
|
13
|
+
'page.lastUpdated': 'Ultimo aggiornamento il',
|
|
14
|
+
'search.all': 'Tutte',
|
|
15
|
+
'search.close': 'chiudi',
|
|
16
|
+
'search.empty': 'Nessun risultato per',
|
|
17
|
+
'search.label': 'Cerca nella documentazione',
|
|
18
|
+
'search.loading': 'Caricamento…',
|
|
19
|
+
'search.navigate': 'naviga',
|
|
20
|
+
'search.open': 'apri',
|
|
21
|
+
'search.placeholder': 'Cerca nella documentazione…',
|
|
22
|
+
'search.results': 'Risultati della ricerca',
|
|
23
|
+
'search.sections': 'Cerca in',
|
|
24
|
+
'search.trigger': 'Cerca…',
|
|
25
|
+
'theme.toggle': 'Cambia modalità',
|
|
26
|
+
'toc.label': 'Indice dei contenuti',
|
|
27
|
+
'toc.title': 'In questa pagina',
|
|
28
|
+
} satisfies UiCatalog
|
package/src/site/ui.ts
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { ENGLISH_UI } from './ui/en.ts'
|
|
2
|
+
import { ITALIAN_UI } from './ui/it.ts'
|
|
3
|
+
|
|
4
|
+
/** Every string JAAD puts on a page itself. */
|
|
5
|
+
export const UI_DEFAULTS = ENGLISH_UI
|
|
6
|
+
|
|
7
|
+
export type UiKey = keyof typeof UI_DEFAULTS
|
|
8
|
+
export type UiCatalog = Record<UiKey, string>
|
|
9
|
+
|
|
10
|
+
export type UiOverrides = Record<string, Partial<Record<string, string>>>
|
|
11
|
+
|
|
12
|
+
const UI_CATALOGS = {
|
|
13
|
+
en: ENGLISH_UI,
|
|
14
|
+
it: ITALIAN_UI,
|
|
15
|
+
} satisfies Record<string, UiCatalog>
|
|
16
|
+
|
|
17
|
+
function localeCandidates(locale: string): string[] {
|
|
18
|
+
const exact = locale.toLowerCase()
|
|
19
|
+
const base = exact.split('-', 1)[0]
|
|
20
|
+
return exact === base ? [exact] : [exact, base]
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/** Locale keys in config are BCP-47 and therefore case-insensitive. */
|
|
24
|
+
function localeEntry<T>(entries: Record<string, T>, locale: string) {
|
|
25
|
+
return Object.entries(entries).find(([candidate]) => candidate.toLowerCase() === locale)?.[1]
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/** User overrides win, from the exact locale to its base language. Bundled
|
|
29
|
+
* catalogues follow the same order; English remains the final fallback. */
|
|
30
|
+
export function uiString(overrides: UiOverrides, locale: string, key: UiKey): string {
|
|
31
|
+
const candidates = localeCandidates(locale)
|
|
32
|
+
|
|
33
|
+
for (const candidate of candidates) {
|
|
34
|
+
const value = localeEntry(overrides, candidate)?.[key]
|
|
35
|
+
if (value !== undefined) return value
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
for (const candidate of candidates) {
|
|
39
|
+
const catalogue = localeEntry<UiCatalog>(UI_CATALOGS, candidate)
|
|
40
|
+
if (catalogue) return catalogue[key]
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
return UI_DEFAULTS[key]
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export const UI_KEYS = Object.keys(UI_DEFAULTS) as UiKey[]
|
|
47
|
+
|
|
48
|
+
/** Kept internal: consumers customise strings through `ui`. */
|
|
49
|
+
export const UI_SUPPORTED_LOCALES = Object.keys(UI_CATALOGS)
|
package/src/site/urls.ts
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/** Empty at the site root, otherwise one leading slash and no trailing slash. */
|
|
2
|
+
export function normaliseBasePath(value: string): string {
|
|
3
|
+
const trimmed = value.replace(/^\/+/, '').replace(/\/+$/, '')
|
|
4
|
+
return trimmed ? `/${trimmed}` : ''
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
/** Apply Astro's deployment base to an application-local, root-relative href. */
|
|
8
|
+
export function withDeploymentBase(href: string, deploymentBase: string): string {
|
|
9
|
+
if (!href.startsWith('/') || href.startsWith('//')) return href
|
|
10
|
+
|
|
11
|
+
const prefix = normaliseBasePath(deploymentBase)
|
|
12
|
+
if (!prefix) return href
|
|
13
|
+
return href === '/' ? `${prefix}/` : `${prefix}${href}`
|
|
14
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
const MODULE_ID = 'virtual:jaad/config'
|
|
2
|
+
const RESOLVED_ID = '\0' + MODULE_ID
|
|
3
|
+
|
|
4
|
+
const USER_CSS_ID = 'virtual:jaad/user.css'
|
|
5
|
+
const RESOLVED_USER_CSS = '\0' + USER_CSS_ID
|
|
6
|
+
|
|
7
|
+
const THEME_CSS_ID = 'virtual:jaad/theme.css'
|
|
8
|
+
const RESOLVED_THEME_CSS = '\0' + THEME_CSS_ID
|
|
9
|
+
|
|
10
|
+
// Which way the palette travels between JAAD and JAAMD; always one of the two.
|
|
11
|
+
const BRIDGE_CSS_ID = 'virtual:jaad/bridge.css'
|
|
12
|
+
|
|
13
|
+
const TAILWIND_CSS_ID = 'virtual:jaad/tailwind.css'
|
|
14
|
+
const RESOLVED_TAILWIND_CSS = '\0' + TAILWIND_CSS_ID
|
|
15
|
+
|
|
16
|
+
export interface SiteStylesheets {
|
|
17
|
+
user: string | null
|
|
18
|
+
theme: string | null
|
|
19
|
+
bridge: string
|
|
20
|
+
tailwind: string | null
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/** The resolved config, serialised, and the stylesheets the site may or may not have. */
|
|
24
|
+
export function siteVirtualPlugin(config: object, stylesheets: SiteStylesheets) {
|
|
25
|
+
return {
|
|
26
|
+
name: 'jaad:virtual',
|
|
27
|
+
resolveId(source: string) {
|
|
28
|
+
if (source === MODULE_ID) return RESOLVED_ID
|
|
29
|
+
// Redirecting to the real path lets Vite process it as ordinary CSS.
|
|
30
|
+
if (source === USER_CSS_ID) return stylesheets.user ?? RESOLVED_USER_CSS
|
|
31
|
+
if (source === THEME_CSS_ID) return stylesheets.theme ?? RESOLVED_THEME_CSS
|
|
32
|
+
if (source === BRIDGE_CSS_ID) return stylesheets.bridge
|
|
33
|
+
if (source === TAILWIND_CSS_ID) return stylesheets.tailwind ?? RESOLVED_TAILWIND_CSS
|
|
34
|
+
return null
|
|
35
|
+
},
|
|
36
|
+
load(id: string) {
|
|
37
|
+
if (id === RESOLVED_ID) return `export default ${JSON.stringify(config)};`
|
|
38
|
+
if (id === RESOLVED_USER_CSS || id === RESOLVED_THEME_CSS || id === RESOLVED_TAILWIND_CSS) return ''
|
|
39
|
+
return null
|
|
40
|
+
},
|
|
41
|
+
}
|
|
42
|
+
}
|
package/src/styles.css
ADDED