@janga/norna 0.7.23 → 0.7.24
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 +14 -18
- package/astro.config.mjs +12 -0
- package/bin/norna-cli.mjs +6 -0
- package/package.json +13 -2
- package/schemas/category.schema.json +2 -2
- package/schemas/config.schema.json +45 -15
- package/schemas/content-frontmatter.schema.json +7 -7
- package/schemas/page-theme.schema.json +26 -26
- package/schemas/sitewide-content.schema.json +18 -18
- package/schemas/theme.schema.json +246 -246
- package/scripts/build-site.mjs +1 -0
- package/scripts/check-config.mjs +12 -1
- package/scripts/generate-search-index.mjs +57 -0
- package/scripts/init-site.mjs +1 -0
- package/scripts/lib/code-fence-metadata.mjs +223 -0
- package/scripts/lib/edit-source-link.mjs +49 -0
- package/scripts/lib/editor-language-service.mjs +32 -12
- package/scripts/lib/image-presentation.mjs +4 -0
- package/scripts/lib/navigation-model.mjs +34 -13
- package/scripts/lib/navigation-review.mjs +396 -0
- package/scripts/lib/norna-markdown-blocks.mjs +73 -26
- package/scripts/lib/norna-markdown-render-plugin.mjs +64 -1
- package/scripts/lib/page-aliases.mjs +21 -1
- package/scripts/lib/page-markdown.mjs +32 -1
- package/scripts/lib/page-move-plan.mjs +659 -0
- package/scripts/lib/presentation-palette-metadata.mjs +1 -1
- package/scripts/lib/presentation.mjs +1 -10
- package/scripts/lib/project-config.mjs +111 -5
- package/scripts/lib/public-asset-conventions.mjs +36 -2
- package/scripts/lib/schema-definitions.mjs +22 -5
- package/scripts/lib/schema-editor-metadata.mjs +19 -4
- package/scripts/lib/schema-value-definitions.mjs +1 -1
- package/scripts/lib/semantic-callouts.mjs +128 -0
- package/scripts/lib/site-content.mjs +2 -1
- package/scripts/lib/site-link-graph.mjs +33 -2
- package/scripts/lib/site-navigation-tree.mjs +85 -0
- package/scripts/lib/social-image-assets.mjs +30 -0
- package/scripts/lib/theme-presets.mjs +2 -2
- package/scripts/lib/theme-profiles.mjs +0 -4
- package/scripts/move-site-page.mjs +256 -0
- package/scripts/review-navigation.mjs +32 -0
- package/scripts/sync-content-sections.mjs +67 -4
- package/scripts/sync-site-public.mjs +24 -5
- package/src/components/CodeBlockCopyScript.astro +9 -4
- package/src/components/EditSourceLink.astro +17 -0
- package/src/components/ImageCarousel.astro +5 -6
- package/src/components/NavigationPageTree.astro +66 -55
- package/src/components/NavigationTreeControls.astro +77 -0
- package/src/components/PageAliasRedirect.astro +1 -1
- package/src/components/PageList.astro +33 -0
- package/src/components/PageSequenceNavigation.astro +37 -0
- package/src/components/SearchPage.astro +151 -0
- package/src/components/SiteNavigation.astro +35 -8
- package/src/components/SitePage.astro +79 -26
- package/src/components/SiteSection.astro +11 -3
- package/src/components/SiteTreeNavigation.astro +8 -1
- package/src/components/TreeNavigationScript.astro +207 -26
- package/src/layouts/BaseLayout.astro +57 -2
- package/src/lib/sectionContent.ts +32 -3
- package/src/lib/siteNavigation.ts +31 -52
- package/src/lib/sitePublicAssets.ts +1 -0
- package/src/pages/404.astro +110 -0
- package/src/pages/[...slug].astro +15 -5
- package/src/styles/content.css +242 -18
- package/src/styles/media.css +0 -5
- package/src/styles/navigation.css +31 -0
- package/src/styles/page-layout.css +438 -89
- package/src/styles/responsive.css +77 -8
- package/starters/basic/README.md +6 -19
- package/starters/basic/package.json +1 -0
- package/starters/basic/site/pages/000-home/content.md +13 -50
|
@@ -36,7 +36,16 @@ type ParsedCardListBlock = {
|
|
|
36
36
|
width?: CardListWidth;
|
|
37
37
|
cards: CardListItem[];
|
|
38
38
|
};
|
|
39
|
-
type
|
|
39
|
+
type ParsedPageListBlock = {
|
|
40
|
+
type: 'page-list';
|
|
41
|
+
line: number;
|
|
42
|
+
};
|
|
43
|
+
type ParsedNornaBlock = ParsedImageBlock | ParsedCardListBlock | ParsedPageListBlock;
|
|
44
|
+
type PageListItem = {
|
|
45
|
+
title: string;
|
|
46
|
+
pathname: string;
|
|
47
|
+
description?: string;
|
|
48
|
+
};
|
|
40
49
|
type InlineNote = {
|
|
41
50
|
markdown: string;
|
|
42
51
|
number: number;
|
|
@@ -48,7 +57,8 @@ type SectionContentBlock =
|
|
|
48
57
|
| { type: 'html'; html: string }
|
|
49
58
|
| { type: 'image-stack'; images: ManagedImage[] }
|
|
50
59
|
| { type: 'image-carousel'; images: ManagedImage[] }
|
|
51
|
-
| { type: 'card-list'; layout: CardListLayout; flow: CardListFlow; size: CardListSize; width?: CardListWidth; cards: CardListItem[] }
|
|
60
|
+
| { type: 'card-list'; layout: CardListLayout; flow: CardListFlow; size: CardListSize; width?: CardListWidth; cards: CardListItem[] }
|
|
61
|
+
| { type: 'page-list'; pages: PageListItem[] };
|
|
52
62
|
export type ResolvedSection = {
|
|
53
63
|
id: string | null;
|
|
54
64
|
title: string;
|
|
@@ -222,6 +232,7 @@ const resolveContentBlocks = async (
|
|
|
222
232
|
html: string,
|
|
223
233
|
blocks: ParsedNornaBlock[],
|
|
224
234
|
page: SitePage,
|
|
235
|
+
childPages: SitePage[],
|
|
225
236
|
inlineNotes: InlineNote[] = [],
|
|
226
237
|
) => {
|
|
227
238
|
const renderedNotes = await Promise.all(inlineNotes.map(async (note) => ({
|
|
@@ -252,6 +263,20 @@ const resolveContentBlocks = async (
|
|
|
252
263
|
});
|
|
253
264
|
continue;
|
|
254
265
|
}
|
|
266
|
+
if (block.type === 'page-list') {
|
|
267
|
+
if (childPages.length === 0) {
|
|
268
|
+
throw new Error(`${page.contentLabel} line ${block.line}: page-list has no listed direct child pages to display. Navigation categories are not pages. Add a listed direct child page or remove the block.`);
|
|
269
|
+
}
|
|
270
|
+
resolvedBlocks.push({
|
|
271
|
+
type: 'page-list',
|
|
272
|
+
pages: childPages.map((childPage) => ({
|
|
273
|
+
title: childPage.title,
|
|
274
|
+
pathname: childPage.pathname,
|
|
275
|
+
description: childPage.entry.data.page?.description,
|
|
276
|
+
})),
|
|
277
|
+
});
|
|
278
|
+
continue;
|
|
279
|
+
}
|
|
255
280
|
|
|
256
281
|
resolvedBlocks.push({
|
|
257
282
|
type: block.type,
|
|
@@ -268,6 +293,7 @@ const resolveContentBlocks = async (
|
|
|
268
293
|
export const getSectionsContent = async (
|
|
269
294
|
html: string,
|
|
270
295
|
page: SitePage,
|
|
296
|
+
childPages: SitePage[] = [],
|
|
271
297
|
) => {
|
|
272
298
|
const pageDocument = page.markdownDocument;
|
|
273
299
|
const sourceLabel = page.contentLabel;
|
|
@@ -307,6 +333,9 @@ export const getSectionsContent = async (
|
|
|
307
333
|
if (bodySection.noteErrors.length > 0) {
|
|
308
334
|
throw new Error(bodySection.noteErrors[0].message);
|
|
309
335
|
}
|
|
336
|
+
if (bodySection.calloutErrors.length > 0) {
|
|
337
|
+
throw new Error(bodySection.calloutErrors[0].message);
|
|
338
|
+
}
|
|
310
339
|
|
|
311
340
|
const inlineNotes = bodySection.notes.map((note) => {
|
|
312
341
|
const number = nextNoteNumber;
|
|
@@ -326,7 +355,7 @@ export const getSectionsContent = async (
|
|
|
326
355
|
title,
|
|
327
356
|
titleHtml: await renderHeadingTitleHtml(bodySection.heading.source),
|
|
328
357
|
headingLevel,
|
|
329
|
-
contentBlocks: await resolveContentBlocks(content, bodySection.blocks, page, inlineNotes),
|
|
358
|
+
contentBlocks: await resolveContentBlocks(content, bodySection.blocks, page, childPages, inlineNotes),
|
|
330
359
|
});
|
|
331
360
|
}
|
|
332
361
|
|
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
import type { HeadingNavigation, SectionNavigation } from './sectionContent';
|
|
2
2
|
import type { SiteNode, SitePage } from './sitePages';
|
|
3
|
+
import {
|
|
4
|
+
flattenSiteNavigationTree as flattenSiteNavigationTreeShared,
|
|
5
|
+
getDirectChildPages as getDirectChildPagesShared,
|
|
6
|
+
getFirstPageInNavigationNode as getFirstPageInNavigationNodeShared,
|
|
7
|
+
getListedSiteNavigationTree as getListedSiteNavigationTreeShared,
|
|
8
|
+
getSequentialPageNavigation as getSequentialPageNavigationShared,
|
|
9
|
+
} from '../../scripts/lib/site-navigation-tree.mjs';
|
|
3
10
|
|
|
4
11
|
export type SiteNavigationEntry = {
|
|
5
12
|
node: SiteNode;
|
|
@@ -11,57 +18,29 @@ export type SiteNavigationNode = SiteNavigationEntry & {
|
|
|
11
18
|
children: SiteNavigationNode[];
|
|
12
19
|
};
|
|
13
20
|
|
|
14
|
-
export const
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
throw new Error(`Site node "${entry.node.pagePath}" has no parent node "${entry.node.parentPagePath}".`);
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
parent.children.push(node);
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
return roots;
|
|
40
|
-
};
|
|
41
|
-
|
|
42
|
-
export const getListedSiteNavigationTree = (entries: SiteNavigationEntry[]) => {
|
|
43
|
-
const filterListed = (nodes: SiteNavigationNode[]): SiteNavigationNode[] => nodes.flatMap((node) => {
|
|
44
|
-
if (!node.node.isHome && !node.node.navigation.listed) return [];
|
|
45
|
-
const children = filterListed(node.children);
|
|
46
|
-
if (node.node.kind === 'category' && children.length === 0) return [];
|
|
47
|
-
return [{ ...node, children }];
|
|
48
|
-
});
|
|
49
|
-
|
|
50
|
-
return filterListed(getSiteNavigationTree(entries));
|
|
51
|
-
};
|
|
52
|
-
|
|
53
|
-
export const getFirstPageInNavigationNode = (node: SiteNavigationNode): SitePage | null => {
|
|
54
|
-
if (node.node.kind === 'page') return node.node;
|
|
55
|
-
|
|
56
|
-
for (const child of node.children) {
|
|
57
|
-
const page = getFirstPageInNavigationNode(child);
|
|
58
|
-
if (page) return page;
|
|
21
|
+
export const getListedSiteNavigationTree = (entries: SiteNavigationEntry[]) => (
|
|
22
|
+
getListedSiteNavigationTreeShared(entries) as SiteNavigationNode[]
|
|
23
|
+
);
|
|
24
|
+
|
|
25
|
+
export const getFirstPageInNavigationNode = (node: SiteNavigationNode): SitePage | null => (
|
|
26
|
+
getFirstPageInNavigationNodeShared(node) as SitePage | null
|
|
27
|
+
);
|
|
28
|
+
|
|
29
|
+
export const flattenSiteNavigationTree = (nodes: SiteNavigationNode[]): SiteNavigationNode[] => (
|
|
30
|
+
flattenSiteNavigationTreeShared(nodes) as SiteNavigationNode[]
|
|
31
|
+
);
|
|
32
|
+
|
|
33
|
+
export const getSequentialPageNavigation = (
|
|
34
|
+
nodes: SiteNavigationNode[],
|
|
35
|
+
currentPagePath: string,
|
|
36
|
+
): { previous: SitePage | null; next: SitePage | null } => (
|
|
37
|
+
getSequentialPageNavigationShared(nodes, currentPagePath) as {
|
|
38
|
+
previous: SitePage | null;
|
|
39
|
+
next: SitePage | null;
|
|
59
40
|
}
|
|
41
|
+
);
|
|
60
42
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
node,
|
|
66
|
-
...flattenSiteNavigationTree(node.children),
|
|
67
|
-
]);
|
|
43
|
+
export const getDirectChildPages = (
|
|
44
|
+
nodes: SiteNavigationNode[],
|
|
45
|
+
currentPagePath: string,
|
|
46
|
+
): SitePage[] => getDirectChildPagesShared(nodes, currentPagePath) as SitePage[];
|
|
@@ -4,6 +4,7 @@ import { sitePublicDir } from '../../scripts/lib/site-paths.mjs';
|
|
|
4
4
|
import { browserIconAssetDefinitions } from '../../scripts/lib/public-asset-conventions.mjs';
|
|
5
5
|
import projectConfig from '../../scripts/lib/project-config.mjs';
|
|
6
6
|
export { getLogoAsset } from '../../scripts/lib/logo-assets.mjs';
|
|
7
|
+
export { getSocialImageAsset } from '../../scripts/lib/social-image-assets.mjs';
|
|
7
8
|
import { withBasePath } from './basePath';
|
|
8
9
|
|
|
9
10
|
type IconLink = {
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
---
|
|
2
|
+
import { getCollection } from 'astro:content';
|
|
3
|
+
import { resolveNavigationModel } from '../../scripts/lib/navigation-model.mjs';
|
|
4
|
+
import { getTextWidthCssValue, resolveFrameColors, resolvePagePresentation } from '../../scripts/lib/presentation.mjs';
|
|
5
|
+
import { projectConfig, resolveThemeVisualConfig } from '../../scripts/lib/project-config.mjs';
|
|
6
|
+
import SiteBanners from '../components/SiteBanners.astro';
|
|
7
|
+
import SiteNavigation from '../components/SiteNavigation.astro';
|
|
8
|
+
import SiteSection from '../components/SiteSection.astro';
|
|
9
|
+
import BaseLayout from '../layouts/BaseLayout.astro';
|
|
10
|
+
import type { ResolvedSection } from '../lib/sectionContent';
|
|
11
|
+
import { flattenSiteNavigationTree, getListedSiteNavigationTree } from '../lib/siteNavigation';
|
|
12
|
+
import { getSiteModel, type SitePage } from '../lib/sitePages';
|
|
13
|
+
import { getLogoAsset } from '../lib/sitePublicAssets';
|
|
14
|
+
import { getToday, isVisibleToday } from '../lib/visibility';
|
|
15
|
+
|
|
16
|
+
const siteDirectory = (process.env.NORNA_SITE_DIR ?? 'site').trim();
|
|
17
|
+
const siteModel = await getSiteModel(await getCollection('site'));
|
|
18
|
+
const { nodes: siteNodes, pages: sitePages } = siteModel;
|
|
19
|
+
const homePage = sitePages.find((page) => page.isHome);
|
|
20
|
+
if (!homePage) throw new Error('The required homepage is missing from the site page model.');
|
|
21
|
+
|
|
22
|
+
const [siteTheme] = await getCollection('theme');
|
|
23
|
+
if (!siteTheme) throw new Error('site/theme.yaml is required. Add a root theme before building the site.');
|
|
24
|
+
const [sitewide] = await getCollection('sitewide');
|
|
25
|
+
const sitewideData = sitewide?.data ?? {};
|
|
26
|
+
const siteThemeData = siteTheme.data;
|
|
27
|
+
const themeLabel = `${siteDirectory || 'site'}/${siteTheme.id}`;
|
|
28
|
+
const visualTheme = resolveThemeVisualConfig(siteThemeData, themeLabel);
|
|
29
|
+
const getPageContent = (page: SitePage) => page.markdownDocument.navigationHeadings.map((heading) => ({ ...heading }));
|
|
30
|
+
const siteNavigation = siteNodes.map((node) => {
|
|
31
|
+
const headings = node.kind === 'page' ? getPageContent(node) : [];
|
|
32
|
+
return {
|
|
33
|
+
node,
|
|
34
|
+
headings,
|
|
35
|
+
sections: headings
|
|
36
|
+
.filter((heading) => heading.depth === 2)
|
|
37
|
+
.map(({ id, title }) => ({ id, title })),
|
|
38
|
+
};
|
|
39
|
+
});
|
|
40
|
+
const renderedNavigationEntries = flattenSiteNavigationTree(getListedSiteNavigationTree(siteNavigation));
|
|
41
|
+
const navigationModel = resolveNavigationModel({
|
|
42
|
+
mode: projectConfig.navigation.mode,
|
|
43
|
+
nodes: renderedNavigationEntries.map(({ node, headings }) => ({
|
|
44
|
+
depth: Math.max(1, node.depth),
|
|
45
|
+
headings,
|
|
46
|
+
isHome: node.isHome,
|
|
47
|
+
kind: node.kind,
|
|
48
|
+
listed: node.navigation.listed,
|
|
49
|
+
pagePath: node.pagePath,
|
|
50
|
+
})),
|
|
51
|
+
});
|
|
52
|
+
const pagePresentation = resolvePagePresentation(siteThemeData, themeLabel, {
|
|
53
|
+
navigationMode: navigationModel.mode,
|
|
54
|
+
});
|
|
55
|
+
const pageTextWidth = getTextWidthCssValue(pagePresentation.typography.values.body.width);
|
|
56
|
+
const frameColors = resolveFrameColors({ theme: siteThemeData, sourceLabel: themeLabel });
|
|
57
|
+
const logoAsset = getLogoAsset();
|
|
58
|
+
const logo = logoAsset
|
|
59
|
+
? {
|
|
60
|
+
src: logoAsset.href,
|
|
61
|
+
alt: homePage.title,
|
|
62
|
+
height: sitewideData.logo?.height,
|
|
63
|
+
}
|
|
64
|
+
: undefined;
|
|
65
|
+
const today = getToday();
|
|
66
|
+
const siteBanners = (sitewideData.banners ?? []).filter((banner) => isVisibleToday(banner.visible, today));
|
|
67
|
+
const notFoundSection: ResolvedSection = {
|
|
68
|
+
id: null,
|
|
69
|
+
title: projectConfig.locale.labels.notFound,
|
|
70
|
+
titleHtml: projectConfig.locale.labels.notFound,
|
|
71
|
+
headingLevel: 1,
|
|
72
|
+
contentBlocks: [{
|
|
73
|
+
type: 'html',
|
|
74
|
+
html: `<p>${projectConfig.locale.labels.notFoundText}</p><p><a href="${projectConfig.site.basePath}">${projectConfig.locale.labels.returnHome}</a></p>`,
|
|
75
|
+
}],
|
|
76
|
+
};
|
|
77
|
+
const hasNavigationRailFrame = navigationModel.requestedMode === 'tree'
|
|
78
|
+
|| (
|
|
79
|
+
navigationModel.requestedMode === 'automatic'
|
|
80
|
+
&& (navigationModel.hasNestedPages || navigationModel.hasCategories)
|
|
81
|
+
);
|
|
82
|
+
---
|
|
83
|
+
|
|
84
|
+
<BaseLayout
|
|
85
|
+
title={projectConfig.locale.labels.notFound}
|
|
86
|
+
presentation={pagePresentation}
|
|
87
|
+
visualTheme={visualTheme}
|
|
88
|
+
frameColors={frameColors}
|
|
89
|
+
footer={sitewideData.footer}
|
|
90
|
+
indexable={false}
|
|
91
|
+
>
|
|
92
|
+
<SiteNavigation
|
|
93
|
+
logo={logo}
|
|
94
|
+
navigationEntries={siteNavigation}
|
|
95
|
+
navigationMode={navigationModel.mode}
|
|
96
|
+
showTopNavigationSubmenus={navigationModel.requestedMode !== 'automatic' && navigationModel.mode !== 'tree'}
|
|
97
|
+
hasNavigationRailFrame={hasNavigationRailFrame}
|
|
98
|
+
frameColors={frameColors}
|
|
99
|
+
readerPreferences={pagePresentation.readerPreferences}
|
|
100
|
+
/>
|
|
101
|
+
{siteBanners.length > 0 && <SiteBanners banners={siteBanners} />}
|
|
102
|
+
<main class="site-content" id="main-content" style={`--page-text-width: ${pageTextWidth}`}>
|
|
103
|
+
<SiteSection
|
|
104
|
+
section={notFoundSection}
|
|
105
|
+
pagePresentation={pagePresentation}
|
|
106
|
+
visualTheme={visualTheme}
|
|
107
|
+
sectionIndex={0}
|
|
108
|
+
/>
|
|
109
|
+
</main>
|
|
110
|
+
</BaseLayout>
|
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
---
|
|
2
2
|
import { getCollection } from 'astro:content';
|
|
3
3
|
import { assertPageAliasModel, createPageAliasModel } from '../../scripts/lib/page-aliases.mjs';
|
|
4
|
+
import { getGeneratedSiteRoutes } from '../../scripts/lib/page-aliases.mjs';
|
|
4
5
|
import { getSitePublicFiles } from '../../scripts/lib/site-link-graph.mjs';
|
|
6
|
+
import projectConfig from '../../scripts/lib/project-config.mjs';
|
|
5
7
|
import PageAliasRedirect from '../components/PageAliasRedirect.astro';
|
|
8
|
+
import SearchPage from '../components/SearchPage.astro';
|
|
6
9
|
import SitePage from '../components/SitePage.astro';
|
|
7
10
|
import { getSiteModel, getSitePage, isHomePageEntry } from '../lib/sitePages';
|
|
8
11
|
|
|
@@ -13,6 +16,7 @@ export async function getStaticPaths() {
|
|
|
13
16
|
categories: siteModel.categories,
|
|
14
17
|
pages: siteModel.pages,
|
|
15
18
|
publicFiles: await getSitePublicFiles(),
|
|
19
|
+
generatedRoutes: getGeneratedSiteRoutes({ searchEnabled: projectConfig.search.enabled }),
|
|
16
20
|
}));
|
|
17
21
|
const pagesByPathname = new Map(siteModel.pages.map((page) => [page.pathname, page]));
|
|
18
22
|
|
|
@@ -37,22 +41,28 @@ export async function getStaticPaths() {
|
|
|
37
41
|
};
|
|
38
42
|
});
|
|
39
43
|
|
|
40
|
-
|
|
44
|
+
const searchPath = projectConfig.search.enabled
|
|
45
|
+
? [{ params: { slug: 'search' }, props: { searchPage: true } }]
|
|
46
|
+
: [];
|
|
47
|
+
|
|
48
|
+
return [...pagePaths, ...aliasPaths, ...searchPath];
|
|
41
49
|
}
|
|
42
50
|
|
|
43
|
-
const { alias, entry } = Astro.props;
|
|
51
|
+
const { alias, entry, searchPage } = Astro.props;
|
|
44
52
|
|
|
45
|
-
if (!alias && (!entry || isHomePageEntry(entry))) {
|
|
53
|
+
if (!searchPage && !alias && (!entry || isHomePageEntry(entry))) {
|
|
46
54
|
throw new Error('Page entry is missing.');
|
|
47
55
|
}
|
|
48
56
|
|
|
49
57
|
const currentPage = entry ? await getSitePage(entry) : null;
|
|
50
58
|
|
|
51
|
-
if (!alias && !currentPage?.pathSegment) {
|
|
59
|
+
if (!searchPage && !alias && !currentPage?.pathSegment) {
|
|
52
60
|
throw new Error(`Page "${entry.id}" needs a page id.`);
|
|
53
61
|
}
|
|
54
62
|
---
|
|
55
63
|
|
|
56
|
-
{
|
|
64
|
+
{searchPage
|
|
65
|
+
? <SearchPage />
|
|
66
|
+
: alias
|
|
57
67
|
? <PageAliasRedirect targetPathname={alias.targetPathname} targetTitle={alias.targetTitle} />
|
|
58
68
|
: <SitePage entry={entry} />}
|
package/src/styles/content.css
CHANGED
|
@@ -252,24 +252,6 @@ ul {
|
|
|
252
252
|
min-width: 0;
|
|
253
253
|
}
|
|
254
254
|
|
|
255
|
-
@media (min-width: 1101px) {
|
|
256
|
-
@container (min-width: 55rem) {
|
|
257
|
-
.section-note {
|
|
258
|
-
float: right;
|
|
259
|
-
clear: right;
|
|
260
|
-
width: var(--layout-note-width);
|
|
261
|
-
margin: 0 calc(0px - var(--layout-note-width) - var(--layout-note-gap)) 0.75rem var(--layout-note-gap);
|
|
262
|
-
}
|
|
263
|
-
}
|
|
264
|
-
|
|
265
|
-
.site-page-layout-contents .section-note {
|
|
266
|
-
float: none;
|
|
267
|
-
clear: none;
|
|
268
|
-
width: 100%;
|
|
269
|
-
margin: var(--section-body-paragraph-spacing, 0.85em) 0 0;
|
|
270
|
-
}
|
|
271
|
-
}
|
|
272
|
-
|
|
273
255
|
.section-markdown {
|
|
274
256
|
width: var(--layout-reading-width);
|
|
275
257
|
max-width: none;
|
|
@@ -280,6 +262,95 @@ ul {
|
|
|
280
262
|
text-align: var(--section-body-align-desktop, left);
|
|
281
263
|
}
|
|
282
264
|
|
|
265
|
+
.norna-search {
|
|
266
|
+
--pagefind-ui-scale: 0.88;
|
|
267
|
+
--pagefind-ui-primary: var(--color-link-text);
|
|
268
|
+
--pagefind-ui-text: var(--color-primary-text);
|
|
269
|
+
--pagefind-ui-background: var(--color-page);
|
|
270
|
+
--pagefind-ui-border: var(--color-nav-separator);
|
|
271
|
+
--pagefind-ui-tag: var(--color-surface-soft-background);
|
|
272
|
+
--pagefind-ui-border-width: 1px;
|
|
273
|
+
--pagefind-ui-border-radius: var(--corner-radius-medium);
|
|
274
|
+
--pagefind-ui-image-border-radius: var(--corner-radius-medium);
|
|
275
|
+
--pagefind-ui-font: var(--font-sans);
|
|
276
|
+
width: var(--layout-reading-width);
|
|
277
|
+
margin: var(--space-content-block-gap) var(--layout-inline-end-margin) 0 var(--layout-inline-start-margin);
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
.norna-search > [data-search-status] {
|
|
281
|
+
margin: 0;
|
|
282
|
+
color: var(--color-secondary-text);
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
.child-page-list {
|
|
286
|
+
width: var(--layout-reading-width);
|
|
287
|
+
margin-block: 0;
|
|
288
|
+
margin-inline: var(--layout-inline-start-margin) var(--layout-inline-end-margin);
|
|
289
|
+
font-size: var(--section-body-font-size-desktop, clamp(0.96rem, 0.94rem + 0.08vw, 1rem));
|
|
290
|
+
line-height: var(--section-body-line-height, 1.6);
|
|
291
|
+
text-align: left;
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
.child-page-list ul {
|
|
295
|
+
display: grid;
|
|
296
|
+
gap: 0;
|
|
297
|
+
margin: 0;
|
|
298
|
+
padding: 0;
|
|
299
|
+
list-style: none;
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
.child-page-list li {
|
|
303
|
+
margin: 0;
|
|
304
|
+
border-top: 1px solid var(--color-nav-separator);
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
.child-page-list li:last-child {
|
|
308
|
+
border-bottom: 1px solid var(--color-nav-separator);
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
.child-page-list a {
|
|
312
|
+
display: grid;
|
|
313
|
+
grid-template-columns: minmax(0, 1fr) auto;
|
|
314
|
+
align-items: center;
|
|
315
|
+
gap: 1rem;
|
|
316
|
+
padding: 0.9rem 0.15rem;
|
|
317
|
+
color: inherit;
|
|
318
|
+
text-decoration: none;
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
.child-page-list a:hover,
|
|
322
|
+
.child-page-list a:focus-visible {
|
|
323
|
+
background: var(--color-surface-soft-background);
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
.child-page-list-copy {
|
|
327
|
+
display: grid;
|
|
328
|
+
min-width: 0;
|
|
329
|
+
gap: 0.2rem;
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
.child-page-list-copy strong {
|
|
333
|
+
font-size: 1em;
|
|
334
|
+
font-weight: 650;
|
|
335
|
+
line-height: 1.35;
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
.child-page-list-copy > span {
|
|
339
|
+
color: var(--section-secondary-text-color, var(--color-secondary-text));
|
|
340
|
+
font-size: 0.9em;
|
|
341
|
+
line-height: 1.45;
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
.child-page-list svg {
|
|
345
|
+
width: 1rem;
|
|
346
|
+
height: 1rem;
|
|
347
|
+
stroke-width: 1.75;
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
.section-body > .child-page-list:not(:last-child) {
|
|
351
|
+
margin-bottom: var(--space-content-block-gap);
|
|
352
|
+
}
|
|
353
|
+
|
|
283
354
|
.section-markdown table {
|
|
284
355
|
display: block;
|
|
285
356
|
max-width: 100%;
|
|
@@ -363,6 +434,61 @@ ul {
|
|
|
363
434
|
margin-bottom: 0;
|
|
364
435
|
}
|
|
365
436
|
|
|
437
|
+
.section-markdown .norna-callout {
|
|
438
|
+
--callout-accent: var(--color-accent);
|
|
439
|
+
--callout-background: var(--color-surface-soft-background);
|
|
440
|
+
--callout-text: var(--color-surface-soft-text);
|
|
441
|
+
display: flow-root;
|
|
442
|
+
margin: 0 0 var(--section-body-paragraph-spacing, 1em);
|
|
443
|
+
border: 1px solid color-mix(in srgb, var(--callout-accent) 52%, transparent);
|
|
444
|
+
border-inline-start: 0.3rem solid var(--callout-accent);
|
|
445
|
+
border-radius: var(--corner-radius-medium, 6px);
|
|
446
|
+
padding: 0.85rem 1rem;
|
|
447
|
+
background: var(--callout-background);
|
|
448
|
+
color: var(--callout-text);
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
.section-markdown .norna-callout-important {
|
|
452
|
+
--callout-background: var(--color-surface-emphasis-background);
|
|
453
|
+
--callout-text: var(--color-surface-emphasis-text);
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
.section-markdown .norna-callout-tip {
|
|
457
|
+
--callout-accent: var(--color-success-accent);
|
|
458
|
+
--callout-background: var(--color-success-surface);
|
|
459
|
+
--callout-text: var(--color-success-text);
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
.section-markdown :is(.norna-callout-warning, .norna-callout-caution) {
|
|
463
|
+
--callout-accent: var(--color-warning-accent);
|
|
464
|
+
--callout-background: var(--color-warning-surface);
|
|
465
|
+
--callout-text: var(--color-warning-text);
|
|
466
|
+
}
|
|
467
|
+
|
|
468
|
+
.section-markdown .norna-callout-danger {
|
|
469
|
+
--callout-accent: var(--color-error-accent);
|
|
470
|
+
--callout-background: var(--color-error-surface);
|
|
471
|
+
--callout-text: var(--color-error-text);
|
|
472
|
+
}
|
|
473
|
+
|
|
474
|
+
.section-markdown .norna-callout-label {
|
|
475
|
+
margin: 0 0 0.35rem;
|
|
476
|
+
color: inherit;
|
|
477
|
+
font-family: var(--font-sans);
|
|
478
|
+
font-size: 0.78rem;
|
|
479
|
+
font-weight: 700;
|
|
480
|
+
letter-spacing: 0;
|
|
481
|
+
line-height: 1.35;
|
|
482
|
+
}
|
|
483
|
+
|
|
484
|
+
.section-markdown .norna-callout a {
|
|
485
|
+
color: inherit;
|
|
486
|
+
}
|
|
487
|
+
|
|
488
|
+
.section-markdown .norna-callout > :last-child {
|
|
489
|
+
margin-bottom: 0;
|
|
490
|
+
}
|
|
491
|
+
|
|
366
492
|
.section-markdown pre.astro-code {
|
|
367
493
|
margin: 0 0 var(--section-body-paragraph-spacing, 1em);
|
|
368
494
|
border: 1px solid color-mix(in srgb, currentColor 18%, transparent);
|
|
@@ -380,11 +506,55 @@ ul {
|
|
|
380
506
|
margin: 0 0 var(--section-body-paragraph-spacing, 1em);
|
|
381
507
|
}
|
|
382
508
|
|
|
509
|
+
.section-markdown .norna-code-example {
|
|
510
|
+
margin: 0 0 var(--section-body-paragraph-spacing, 1em);
|
|
511
|
+
border: 1px solid color-mix(in srgb, var(--color-code-text) 18%, transparent);
|
|
512
|
+
border-radius: var(--corner-radius-medium, 6px);
|
|
513
|
+
overflow: hidden;
|
|
514
|
+
background: var(--color-code-background);
|
|
515
|
+
color: var(--color-code-text);
|
|
516
|
+
}
|
|
517
|
+
|
|
518
|
+
.section-markdown .norna-code-title {
|
|
519
|
+
min-height: 3.25rem;
|
|
520
|
+
margin: 0;
|
|
521
|
+
padding: 0.85rem 3.85rem 0.75rem 0.9rem;
|
|
522
|
+
border-bottom: 1px solid color-mix(in srgb, var(--color-code-text) 22%, transparent);
|
|
523
|
+
font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
|
|
524
|
+
font-size: 0.82rem;
|
|
525
|
+
font-weight: 650;
|
|
526
|
+
line-height: 1.35;
|
|
527
|
+
overflow-wrap: anywhere;
|
|
528
|
+
}
|
|
529
|
+
|
|
530
|
+
.section-markdown .norna-code-example > pre.astro-code {
|
|
531
|
+
margin: 0;
|
|
532
|
+
border: 0;
|
|
533
|
+
border-radius: 0;
|
|
534
|
+
}
|
|
535
|
+
|
|
536
|
+
.section-markdown .norna-code-example.code-block > pre.astro-code {
|
|
537
|
+
padding-right: 0.9rem;
|
|
538
|
+
}
|
|
539
|
+
|
|
383
540
|
.section-markdown .code-block > pre.astro-code {
|
|
384
541
|
margin: 0;
|
|
385
542
|
padding-right: 3.85rem;
|
|
386
543
|
}
|
|
387
544
|
|
|
545
|
+
.section-markdown pre.astro-code.norna-code-has-highlighted-lines code {
|
|
546
|
+
display: block;
|
|
547
|
+
}
|
|
548
|
+
|
|
549
|
+
.section-markdown pre.astro-code .norna-code-line-highlighted {
|
|
550
|
+
display: inline-block;
|
|
551
|
+
width: calc(100% + 1.8rem);
|
|
552
|
+
margin-inline: -0.9rem;
|
|
553
|
+
padding-inline: calc(0.9rem - 3px) 0.9rem;
|
|
554
|
+
border-inline-start: 3px solid var(--color-code-text);
|
|
555
|
+
background: color-mix(in srgb, var(--color-code-text) 14%, var(--color-code-background));
|
|
556
|
+
}
|
|
557
|
+
|
|
388
558
|
.code-block-copy {
|
|
389
559
|
position: absolute;
|
|
390
560
|
top: 0.5rem;
|
|
@@ -443,6 +613,10 @@ ul {
|
|
|
443
613
|
margin-bottom: 0;
|
|
444
614
|
}
|
|
445
615
|
|
|
616
|
+
.section-markdown > .norna-code-example:last-child {
|
|
617
|
+
margin-bottom: 0;
|
|
618
|
+
}
|
|
619
|
+
|
|
446
620
|
.section-markdown blockquote > pre.astro-code:last-child {
|
|
447
621
|
margin-bottom: 0;
|
|
448
622
|
}
|
|
@@ -492,3 +666,53 @@ ul {
|
|
|
492
666
|
.section-markdown li + li {
|
|
493
667
|
margin-top: 0.35rem;
|
|
494
668
|
}
|
|
669
|
+
|
|
670
|
+
.section-markdown [data-footnote-ref] {
|
|
671
|
+
color: inherit;
|
|
672
|
+
font-size: 0.72em;
|
|
673
|
+
font-weight: 700;
|
|
674
|
+
text-decoration-thickness: 0.08em;
|
|
675
|
+
text-underline-offset: 0.15em;
|
|
676
|
+
}
|
|
677
|
+
|
|
678
|
+
.section-markdown [data-footnotes] {
|
|
679
|
+
margin-top: calc(var(--section-body-paragraph-spacing, 1em) * 1.75);
|
|
680
|
+
border-top: 1px solid color-mix(in srgb, currentColor 24%, transparent);
|
|
681
|
+
padding-top: var(--section-body-paragraph-spacing, 1em);
|
|
682
|
+
font-size: 0.88em;
|
|
683
|
+
line-height: 1.5;
|
|
684
|
+
}
|
|
685
|
+
|
|
686
|
+
.section-markdown [data-footnotes] > .sr-only {
|
|
687
|
+
position: absolute;
|
|
688
|
+
width: 1px;
|
|
689
|
+
height: 1px;
|
|
690
|
+
margin: -1px;
|
|
691
|
+
padding: 0;
|
|
692
|
+
border: 0;
|
|
693
|
+
overflow: hidden;
|
|
694
|
+
clip: rect(0 0 0 0);
|
|
695
|
+
clip-path: inset(50%);
|
|
696
|
+
white-space: nowrap;
|
|
697
|
+
}
|
|
698
|
+
|
|
699
|
+
.section-markdown [data-footnotes] ol {
|
|
700
|
+
display: block;
|
|
701
|
+
margin: 0;
|
|
702
|
+
padding-inline-start: 1.5rem;
|
|
703
|
+
}
|
|
704
|
+
|
|
705
|
+
.section-markdown [data-footnotes] li {
|
|
706
|
+
padding-inline-start: 0.2rem;
|
|
707
|
+
scroll-margin-top: calc(var(--site-top-anchor-offset) + 1rem);
|
|
708
|
+
}
|
|
709
|
+
|
|
710
|
+
.section-markdown [data-footnotes] li:target {
|
|
711
|
+
background: color-mix(in srgb, currentColor 6%, transparent);
|
|
712
|
+
}
|
|
713
|
+
|
|
714
|
+
.section-markdown [data-footnote-backref] {
|
|
715
|
+
margin-inline-start: 0.15em;
|
|
716
|
+
color: inherit;
|
|
717
|
+
text-decoration: none;
|
|
718
|
+
}
|
package/src/styles/media.css
CHANGED
|
@@ -291,10 +291,6 @@
|
|
|
291
291
|
outline: none;
|
|
292
292
|
}
|
|
293
293
|
|
|
294
|
-
:root[data-image-presentation='prose-aligned'] .image-carousel {
|
|
295
|
-
--layout-carousel-width: min(100%, var(--layout-media-width));
|
|
296
|
-
}
|
|
297
|
-
|
|
298
294
|
.image-carousel:focus-visible {
|
|
299
295
|
outline: var(--focus-indicator-width) solid var(--color-focus-ring);
|
|
300
296
|
outline-offset: 0.5rem;
|
|
@@ -317,7 +313,6 @@
|
|
|
317
313
|
}
|
|
318
314
|
|
|
319
315
|
:root[data-image-presentation='prose-aligned'] .image-carousel-stage {
|
|
320
|
-
max-height: none;
|
|
321
316
|
margin-inline: 0 auto;
|
|
322
317
|
}
|
|
323
318
|
|