@janga/norna 0.7.15 → 0.7.17
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 +6 -6
- package/astro.config.mjs +35 -3
- package/docs/README.md +10 -10
- package/docs/commands.md +2 -2
- package/docs/content.md +82 -102
- package/docs/design/navigation-and-theme-plan.md +115 -0
- package/docs/design/norna-diagram-design.md +9 -9
- package/docs/design/site-examples-structure.md +9 -9
- package/docs/engine-development.md +9 -9
- package/docs/getting-started.md +20 -15
- package/docs/images-and-metadata.md +10 -9
- package/docs/pages.md +134 -0
- package/docs/public-files.md +49 -36
- package/docs/publishing.md +19 -3
- package/docs/site-files.md +29 -28
- package/docs/sitewide-content.md +20 -36
- package/docs/theme.md +20 -20
- package/docs/typography.md +10 -10
- package/examples/README.md +2 -2
- package/examples/complete-sites/dog-shelter-multi-page/.astro/collections/site.schema.json +17 -41
- package/examples/complete-sites/dog-shelter-multi-page/.astro/collections/sitewide.schema.json +26 -67
- package/examples/complete-sites/dog-shelter-multi-page/.astro/collections/theme.schema.json +185 -88
- package/examples/complete-sites/dog-shelter-multi-page/.astro/data-store.json +1 -1
- package/examples/complete-sites/dog-shelter-multi-page/.astro/dev-local.json +4 -4
- package/examples/complete-sites/dog-shelter-multi-page/.astro/dev.json +5 -5
- package/examples/complete-sites/dog-shelter-multi-page/.astro/dev.log +33 -23
- package/examples/complete-sites/dog-shelter-multi-page/README.md +1 -1
- package/examples/complete-sites/dog-shelter-multi-page/node_modules/.vite/deps/_metadata.json +8 -8
- package/examples/complete-sites/dog-shelter-multi-page/site/.norna/generated-images.json +20 -20
- package/examples/complete-sites/dog-shelter-multi-page/site/content.md +3 -4
- package/examples/complete-sites/dog-shelter-multi-page/site/{routes → pages}/010-dogs/content.md +3 -4
- package/examples/complete-sites/dog-shelter-multi-page/site/{routes → pages}/020-adopt/content.md +3 -4
- package/examples/complete-sites/dog-shelter-multi-page/site/sitewide-content.yaml +2 -4
- package/examples/complete-sites/dog-shelter-single-page/.astro/collections/site.schema.json +17 -41
- package/examples/complete-sites/dog-shelter-single-page/.astro/collections/sitewide.schema.json +26 -67
- package/examples/complete-sites/dog-shelter-single-page/.astro/collections/theme.schema.json +185 -88
- package/examples/complete-sites/dog-shelter-single-page/.astro/data-store.json +1 -1
- package/examples/complete-sites/dog-shelter-single-page/.astro/dev-local.json +8 -0
- package/examples/complete-sites/dog-shelter-single-page/.astro/dev.json +5 -5
- package/examples/complete-sites/dog-shelter-single-page/.astro/dev.log +16 -12
- package/examples/complete-sites/dog-shelter-single-page/README.md +1 -1
- package/examples/complete-sites/dog-shelter-single-page/node_modules/.vite/deps/_metadata.json +8 -8
- package/examples/complete-sites/dog-shelter-single-page/site/.norna/generated-images.json +12 -12
- package/examples/complete-sites/dog-shelter-single-page/site/content.md +5 -2
- package/examples/complete-sites/dog-shelter-single-page/site/sitewide-content.yaml +2 -4
- package/examples/feature-demos/media-and-surfaces/.astro/collections/site.schema.json +17 -41
- package/examples/feature-demos/media-and-surfaces/.astro/collections/sitewide.schema.json +26 -67
- package/examples/feature-demos/media-and-surfaces/.astro/collections/theme.schema.json +185 -88
- package/examples/feature-demos/media-and-surfaces/.astro/data-store.json +1 -1
- package/examples/feature-demos/media-and-surfaces/.astro/dev.log +4 -14
- package/examples/feature-demos/media-and-surfaces/README.md +2 -2
- package/examples/feature-demos/media-and-surfaces/node_modules/.vite/deps/_metadata.json +9 -9
- package/examples/feature-demos/media-and-surfaces/site/.norna/generated-images.json +16 -16
- package/examples/feature-demos/media-and-surfaces/site/content.md +4 -7
- package/examples/feature-demos/media-and-surfaces/site/{routes → pages}/010-media/content.md +6 -5
- package/examples/feature-demos/media-and-surfaces/site/{routes → pages}/020-surfaces/content.md +7 -6
- package/examples/feature-demos/media-and-surfaces/site/sitewide-content.yaml +0 -2
- package/examples/feature-demos/sitewide-content/README.md +3 -3
- package/examples/feature-demos/sitewide-content/site/content.md +8 -7
- package/examples/feature-demos/sitewide-content/site/pages/010-logo-and-navigation/content.md +17 -0
- package/examples/feature-demos/sitewide-content/site/{routes → pages}/020-notices/content.md +7 -6
- package/examples/feature-demos/sitewide-content/site/{routes → pages}/030-footer/content.md +6 -5
- package/examples/feature-demos/sitewide-content/site/sitewide-content.yaml +4 -13
- package/examples/feature-demos/theme-presets/README.md +1 -1
- package/examples/feature-demos/theme-presets/site/.norna/generated-images.json +60 -60
- package/examples/feature-demos/theme-presets/site/content.md +4 -7
- package/examples/feature-demos/theme-presets/site/{routes → pages}/010-portfolio/content.md +4 -7
- package/examples/feature-demos/theme-presets/site/{routes → pages}/020-documentation/content.md +4 -7
- package/examples/feature-demos/theme-presets/site/{routes → pages}/030-project/content.md +4 -7
- package/examples/feature-demos/theme-presets/site/{routes → pages}/040-statement/content.md +4 -7
- package/examples/feature-demos/theme-presets/site/sitewide-content.yaml +1 -10
- package/fixtures/basic/site/content.md +5 -6
- package/fixtures/basic/site/sitewide-content.yaml +1 -8
- package/fixtures/content-model-v2/site/content.md +11 -13
- package/fixtures/content-model-v2/site/pages/010-guide/content.md +18 -0
- package/fixtures/nested-pages/site/.norna/generated-images.json +10 -0
- package/fixtures/nested-pages/site/config.yaml +1 -0
- package/fixtures/nested-pages/site/content.md +15 -0
- package/fixtures/nested-pages/site/pages/010-guides/content.md +15 -0
- package/fixtures/nested-pages/site/pages/010-guides/pages/010-installation/content.md +21 -0
- package/fixtures/nested-pages/site/pages/010-guides/pages/010-installation/images/diagram.svg +21 -0
- package/fixtures/nested-pages/site/pages/010-guides/pages/010-installation/pages/010-macos/content.md +14 -0
- package/fixtures/nested-pages/site/pages/010-guides/pages/020-workflows/content.md +11 -0
- package/fixtures/nested-pages/site/pages/010-guides/theme.yaml +3 -0
- package/fixtures/nested-pages/site/pages/020-reference/content.md +10 -0
- package/fixtures/nested-pages/site/pages/020-reference/pages/010-installation/content.md +11 -0
- package/fixtures/nested-pages/site/theme.yaml +3 -0
- package/package.json +7 -4
- package/schemas/config.schema.json +5 -5
- package/schemas/content-frontmatter.schema.json +28 -63
- package/schemas/manifest.json +1 -0
- package/schemas/sitewide-content.schema.json +58 -132
- package/schemas/theme.schema.json +396 -86
- package/scripts/check-config.mjs +6 -5
- package/scripts/deploy-site.mjs +6 -8
- package/scripts/doctor.mjs +2 -2
- package/scripts/generate-images.mjs +11 -18
- package/scripts/generate-schemas.mjs +3 -217
- package/scripts/lib/base-path-redirect.mjs +9 -0
- package/scripts/lib/editor-language-service.mjs +126 -66
- package/scripts/lib/heading-ids.mjs +161 -0
- package/scripts/lib/navigation-model.mjs +51 -0
- package/scripts/lib/norna-markdown-blocks.mjs +3 -4
- package/scripts/lib/page-model.mjs +83 -0
- package/scripts/lib/project-config.mjs +28 -0
- package/scripts/lib/schema-definitions.mjs +41 -46
- package/scripts/lib/schema-editor-metadata.mjs +475 -0
- package/scripts/lib/schema-value-definitions.mjs +6 -6
- package/scripts/lib/site-content.mjs +124 -87
- package/scripts/lib/site-paths.mjs +2 -2
- package/scripts/lib/theme-config.mjs +9 -16
- package/scripts/lib/theme-presets.mjs +9 -1
- package/scripts/release.mjs +1 -1
- package/scripts/show-typography.mjs +26 -20
- package/scripts/sync-content-sections.mjs +106 -65
- package/scripts/{test-temporary-visibility.mjs → test-banner-visibility.mjs} +7 -24
- package/scripts/test-client-javascript.mjs +39 -42
- package/scripts/test-content-check.mjs +138 -54
- package/scripts/test-content-model-v2.mjs +445 -228
- package/scripts/test-documentation.mjs +6 -1
- package/scripts/test-editor-language-service.mjs +168 -24
- package/scripts/test-engine-commands.mjs +2 -1
- package/scripts/test-heading-ids.mjs +68 -0
- package/scripts/test-navigation-model.mjs +63 -0
- package/scripts/test-nested-pages.mjs +110 -0
- package/scripts/test-package-check.mjs +31 -40
- package/scripts/test-page-model.mjs +80 -0
- package/scripts/test-project-config.mjs +25 -1
- package/scripts/test-schemas.mjs +66 -14
- package/scripts/test-theme-presets.mjs +33 -24
- package/src/components/NavigationPageTree.astro +68 -0
- package/src/components/SectionNavigationScript.astro +110 -5
- package/src/components/SiteBreadcrumbs.astro +29 -0
- package/src/components/SiteNavigation.astro +65 -69
- package/src/components/SitePage.astro +70 -46
- package/src/components/SiteSection.astro +27 -20
- package/src/content.config.ts +9 -5
- package/src/layouts/BaseLayout.astro +11 -20
- package/src/lib/pageThemes.ts +42 -0
- package/src/lib/sectionContent.ts +109 -106
- package/src/lib/siteNavigation.ts +48 -0
- package/src/lib/sitePages.ts +85 -38
- package/src/pages/{[slug].astro → [...slug].astro} +2 -2
- package/src/styles/global.css +373 -55
- package/starters/basic/README.md +5 -7
- package/starters/basic/site/content.md +7 -4
- package/starters/basic/site/sitewide-content.yaml +1 -10
- package/starters/project/README.md +8 -8
- package/starters/project/site/content.md +5 -4
- package/starters/project/site/{routes → pages}/010-guide/content.md +5 -4
- package/starters/project/site/sitewide-content.yaml +1 -10
- package/docs/routes.md +0 -121
- package/examples/feature-demos/sitewide-content/site/routes/010-identity/content.md +0 -20
- package/fixtures/content-model-v2/site/routes/010-guide/content.md +0 -17
- package/scripts/lib/route-model.mjs +0 -17
- package/scripts/test-route-model.mjs +0 -32
- package/src/lib/routeThemes.ts +0 -41
- /package/examples/complete-sites/dog-shelter-multi-page/site/images/{intro/shelter-dog.jpg → shelter-dog.jpg} +0 -0
- /package/examples/complete-sites/dog-shelter-multi-page/site/{routes/010-dogs/images/dogs → pages/010-dogs/images}/rex.jpg +0 -0
- /package/examples/complete-sites/dog-shelter-multi-page/site/{routes/010-dogs/images/dogs → pages/010-dogs/images}/rover.jpg +0 -0
- /package/examples/complete-sites/dog-shelter-multi-page/site/{routes/020-adopt/images/adopt → pages/020-adopt/images}/adoption-dog.jpg +0 -0
- /package/examples/complete-sites/dog-shelter-single-page/site/images/{you-can-help/foster-dog.jpg → foster-dog.jpg} +0 -0
- /package/examples/complete-sites/dog-shelter-single-page/site/images/{what-we-do/rescue-dog.jpg → rescue-dog.jpg} +0 -0
- /package/examples/feature-demos/media-and-surfaces/site/{routes/010-media/images/cards → pages/010-media/images}/card-carousel.svg +0 -0
- /package/examples/feature-demos/media-and-surfaces/site/{routes/010-media/images/cards → pages/010-media/images}/card-stack.svg +0 -0
- /package/examples/feature-demos/media-and-surfaces/site/{routes/010-media/images/cards → pages/010-media/images}/card-surfaces.svg +0 -0
- /package/examples/feature-demos/media-and-surfaces/site/{routes/010-media/images/carousel → pages/010-media/images}/carousel-one.svg +0 -0
- /package/examples/feature-demos/media-and-surfaces/site/{routes/010-media/images/carousel → pages/010-media/images}/carousel-three.svg +0 -0
- /package/examples/feature-demos/media-and-surfaces/site/{routes/010-media/images/carousel → pages/010-media/images}/carousel-two.svg +0 -0
- /package/examples/feature-demos/media-and-surfaces/site/{routes/010-media/images/stack → pages/010-media/images}/stack-one.svg +0 -0
- /package/examples/feature-demos/media-and-surfaces/site/{routes/010-media/images/stack → pages/010-media/images}/stack-two.svg +0 -0
- /package/examples/feature-demos/media-and-surfaces/site/{routes → pages}/020-surfaces/theme.yaml +0 -0
- /package/examples/feature-demos/theme-presets/site/{routes/010-portfolio/images/portfolio → pages/010-portfolio/images}/puppy-portrait.jpg +0 -0
- /package/examples/feature-demos/theme-presets/site/{routes/010-portfolio/images/portfolio → pages/010-portfolio/images}/shepherd-portrait.jpg +0 -0
- /package/examples/feature-demos/theme-presets/site/{routes/010-portfolio/images/portfolio → pages/010-portfolio/images}/white-puppy.jpg +0 -0
- /package/examples/feature-demos/theme-presets/site/{routes → pages}/010-portfolio/theme.yaml +0 -0
- /package/examples/feature-demos/theme-presets/site/{routes/020-documentation/images/documentation → pages/020-documentation/images}/black-schnauzer.jpg +0 -0
- /package/examples/feature-demos/theme-presets/site/{routes/020-documentation/images/documentation → pages/020-documentation/images}/retriever-portrait.jpg +0 -0
- /package/examples/feature-demos/theme-presets/site/{routes/020-documentation/images/documentation → pages/020-documentation/images}/schnauzer-portrait.jpg +0 -0
- /package/examples/feature-demos/theme-presets/site/{routes → pages}/020-documentation/theme.yaml +0 -0
- /package/examples/feature-demos/theme-presets/site/{routes/030-project/images/project → pages/030-project/images}/boxer-portrait.jpg +0 -0
- /package/examples/feature-demos/theme-presets/site/{routes/030-project/images/project → pages/030-project/images}/grass-puppy.jpg +0 -0
- /package/examples/feature-demos/theme-presets/site/{routes/030-project/images/project → pages/030-project/images}/grey-street-dog.jpg +0 -0
- /package/examples/feature-demos/theme-presets/site/{routes → pages}/030-project/theme.yaml +0 -0
- /package/examples/feature-demos/theme-presets/site/{routes/040-statement/images/statement → pages/040-statement/images}/black-pedigree.jpg +0 -0
- /package/examples/feature-demos/theme-presets/site/{routes/040-statement/images/statement → pages/040-statement/images}/sheepdog-grass.jpg +0 -0
- /package/examples/feature-demos/theme-presets/site/{routes/040-statement/images/statement → pages/040-statement/images}/sheepdog-wide.jpg +0 -0
- /package/examples/feature-demos/theme-presets/site/{routes → pages}/040-statement/theme.yaml +0 -0
- /package/fixtures/basic/site/images/{work/.gitkeep → .gitkeep} +0 -0
- /package/fixtures/content-model-v2/site/images/{card-section/adopt.svg → adopt.svg} +0 -0
- /package/fixtures/content-model-v2/site/images/{intro/detail.jpg → detail.jpg} +0 -0
- /package/fixtures/content-model-v2/site/images/{intro/duplicate.jpg → duplicate.jpg} +0 -0
- /package/fixtures/content-model-v2/site/images/{card-section/foster.svg → foster.svg} +0 -0
- /package/fixtures/content-model-v2/site/images/{intro/hero.jpg → hero.jpg} +0 -0
- /package/fixtures/content-model-v2/site/images/{plain/image.jpg → image.jpg} +0 -0
- /package/fixtures/content-model-v2/site/images/{timed/slide-one.jpg → slide-one.jpg} +0 -0
- /package/fixtures/content-model-v2/site/images/{timed/slide-three.jpg → slide-three.jpg} +0 -0
- /package/fixtures/content-model-v2/site/images/{timed/slide-two.jpg → slide-two.jpg} +0 -0
- /package/fixtures/content-model-v2/site/{routes/010-guide/images/intro → pages/010-guide/images}/duplicate.jpg +0 -0
- /package/starters/basic/site/images/{work/.gitkeep → .gitkeep} +0 -0
package/README.md
CHANGED
|
@@ -17,7 +17,7 @@ implementing a new presentation layer for every project.
|
|
|
17
17
|
[Live examples](https://janga.github.io/norna/examples/) |
|
|
18
18
|
[npm package](https://www.npmjs.com/package/@janga/norna)
|
|
19
19
|
|
|
20
|
-
[](https://janga.github.io/norna/examples/complete-sites/dog-shelter-multi-page/)
|
|
21
21
|
|
|
22
22
|
The screenshot shows the built
|
|
23
23
|
[multi-page example source](examples/complete-sites/dog-shelter-multi-page/).
|
|
@@ -54,15 +54,15 @@ site/
|
|
|
54
54
|
|-- sitewide-content.yaml
|
|
55
55
|
|-- content.md
|
|
56
56
|
|-- images/
|
|
57
|
-
|--
|
|
57
|
+
|-- pages/
|
|
58
58
|
`-- public/
|
|
59
59
|
```
|
|
60
60
|
|
|
61
|
-
- `content.md` holds the homepage and
|
|
62
|
-
- `images/` holds managed source images
|
|
63
|
-
- `
|
|
61
|
+
- `content.md` holds the homepage title, introduction, and sections.
|
|
62
|
+
- `images/` holds the homepage's managed source images.
|
|
63
|
+
- `pages/` adds pages, each with content and optional local images and theme.
|
|
64
64
|
- `theme.yaml` normally selects one complete visual preset.
|
|
65
|
-
- `sitewide-content.yaml` holds shared
|
|
65
|
+
- `sitewide-content.yaml` holds shared logo display settings, banners, and footer content.
|
|
66
66
|
- `config.yaml` holds the public URL and optional language and scroll behavior.
|
|
67
67
|
- `public/` holds static files copied without processing.
|
|
68
68
|
|
package/astro.config.mjs
CHANGED
|
@@ -3,6 +3,7 @@ import { execFile } from 'node:child_process';
|
|
|
3
3
|
import path from 'node:path';
|
|
4
4
|
import { promisify } from 'node:util';
|
|
5
5
|
import { defineConfig } from 'astro/config';
|
|
6
|
+
import { getBasePathRedirectLocation } from './scripts/lib/base-path-redirect.mjs';
|
|
6
7
|
import {
|
|
7
8
|
astroCacheDir,
|
|
8
9
|
astroDistDir,
|
|
@@ -12,7 +13,7 @@ import {
|
|
|
12
13
|
siteContentPath,
|
|
13
14
|
siteImagesDir,
|
|
14
15
|
siteProjectRoot,
|
|
15
|
-
|
|
16
|
+
sitePagesDir,
|
|
16
17
|
} from './scripts/lib/site-paths.mjs';
|
|
17
18
|
import projectConfig from './scripts/lib/project-config.mjs';
|
|
18
19
|
|
|
@@ -28,6 +29,37 @@ const runGenerateImages = () => execFileAsync(process.execPath, [path.join(engin
|
|
|
28
29
|
maxBuffer: 1024 * 1024 * 10,
|
|
29
30
|
});
|
|
30
31
|
|
|
32
|
+
const nornaBasePathRedirect = () => {
|
|
33
|
+
const middleware = (request, response, next) => {
|
|
34
|
+
if (!request.url) {
|
|
35
|
+
next();
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const redirectLocation = getBasePathRedirectLocation(projectConfig.site.basePath, request.url);
|
|
40
|
+
if (!redirectLocation) {
|
|
41
|
+
next();
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
response.statusCode = 308;
|
|
46
|
+
response.setHeader('Location', redirectLocation);
|
|
47
|
+
response.end();
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
return {
|
|
51
|
+
name: 'norna-base-path-redirect',
|
|
52
|
+
configureServer(server) {
|
|
53
|
+
return () => {
|
|
54
|
+
server.middlewares.stack.unshift({ route: '', handle: middleware });
|
|
55
|
+
};
|
|
56
|
+
},
|
|
57
|
+
configurePreviewServer(server) {
|
|
58
|
+
server.middlewares.use(middleware);
|
|
59
|
+
},
|
|
60
|
+
};
|
|
61
|
+
};
|
|
62
|
+
|
|
31
63
|
const nornaGeneratedImagesWatcher = () => ({
|
|
32
64
|
name: 'norna-generated-images-watcher',
|
|
33
65
|
configureServer(server) {
|
|
@@ -35,7 +67,7 @@ const nornaGeneratedImagesWatcher = () => ({
|
|
|
35
67
|
const watchedSourcePaths = [
|
|
36
68
|
siteContentPath,
|
|
37
69
|
siteImagesDir,
|
|
38
|
-
|
|
70
|
+
sitePagesDir,
|
|
39
71
|
].map((watchedPath) => path.resolve(watchedPath));
|
|
40
72
|
let refreshTimer;
|
|
41
73
|
let refreshPromise = Promise.resolve();
|
|
@@ -90,6 +122,6 @@ export default defineConfig({
|
|
|
90
122
|
publicDir: astroPublicDir,
|
|
91
123
|
srcDir: path.join(engineRoot, 'src'),
|
|
92
124
|
vite: {
|
|
93
|
-
plugins: [nornaGeneratedImagesWatcher()],
|
|
125
|
+
plugins: [nornaBasePathRedirect(), nornaGeneratedImagesWatcher()],
|
|
94
126
|
},
|
|
95
127
|
});
|
package/docs/README.md
CHANGED
|
@@ -29,7 +29,7 @@ site/
|
|
|
29
29
|
|-- sitewide-content.yaml
|
|
30
30
|
|-- content.md
|
|
31
31
|
|-- images/
|
|
32
|
-
|--
|
|
32
|
+
|-- pages/
|
|
33
33
|
`-- public/
|
|
34
34
|
```
|
|
35
35
|
|
|
@@ -37,14 +37,14 @@ site/
|
|
|
37
37
|
scroll behavior.
|
|
38
38
|
- [`theme.yaml`](theme.md): complete visual presets and focused presentation
|
|
39
39
|
overrides.
|
|
40
|
-
- [`sitewide-content.yaml`](sitewide-content.md): shared
|
|
40
|
+
- [`sitewide-content.yaml`](sitewide-content.md): shared logo display settings,
|
|
41
41
|
banners, and footer.
|
|
42
|
-
- [`content.md`](content.md): page
|
|
43
|
-
blocks.
|
|
42
|
+
- [`content.md`](content.md): Markdown page title, optional metadata, sections,
|
|
43
|
+
prose, notes, and Norna blocks.
|
|
44
44
|
- [`images/`](images-and-metadata.md): managed source formats, variants, sync,
|
|
45
45
|
and generated image state.
|
|
46
|
-
- [`
|
|
47
|
-
|
|
46
|
+
- [`pages/`](pages.md): additional pages, ordering, URLs, page themes, and
|
|
47
|
+
page-local images.
|
|
48
48
|
- [`public/`](public-files.md): navigation logos, favicons, and other static
|
|
49
49
|
files copied without managed-image processing.
|
|
50
50
|
- [Generated files](site-files.md#generated-files): `site/.norna/public/`,
|
|
@@ -67,7 +67,7 @@ required, optional, convention-discovered, versioned, or generated.
|
|
|
67
67
|
- [Write page sections](content.md#sections)
|
|
68
68
|
- [Use image stacks, carousels, and cards](content.md#norna-blocks)
|
|
69
69
|
- [Add notes to prose](content.md#markdown-text)
|
|
70
|
-
- [Add another page](
|
|
70
|
+
- [Add another page](pages.md)
|
|
71
71
|
- [Add shared banners or footer content](sitewide-content.md)
|
|
72
72
|
|
|
73
73
|
### Work With Images And Public Assets
|
|
@@ -75,14 +75,14 @@ required, optional, convention-discovered, versioned, or generated.
|
|
|
75
75
|
- [Add managed source images](images-and-metadata.md#managed-source-images)
|
|
76
76
|
- [Check and sync moved image references](content.md#validation-and-sync)
|
|
77
77
|
- [Add a navigation logo](public-files.md#navigation-logo)
|
|
78
|
-
- [Add
|
|
78
|
+
- [Add browser icons](public-files.md#browser-icons)
|
|
79
79
|
- [Add other static files](public-files.md#other-static-files)
|
|
80
80
|
|
|
81
81
|
### Change Presentation
|
|
82
82
|
|
|
83
83
|
- [Choose a complete theme preset](theme.md#theme-presets)
|
|
84
84
|
- [Inspect and override a preset](theme.md#overrides)
|
|
85
|
-
- [Give a
|
|
85
|
+
- [Give a page a different theme](theme.md#page-themes)
|
|
86
86
|
- [Adjust typography](typography.md)
|
|
87
87
|
|
|
88
88
|
### Check, Build, And Publish
|
|
@@ -95,7 +95,7 @@ required, optional, convention-discovered, versioned, or generated.
|
|
|
95
95
|
## Concepts And Explanation
|
|
96
96
|
|
|
97
97
|
- [Norna's site model](https://janga.github.io/norna/concepts/) explains how
|
|
98
|
-
files, sections, images, and
|
|
98
|
+
files, sections, images, and pages become a website.
|
|
99
99
|
- [Images and Metadata](images-and-metadata.md) explains managed variants and
|
|
100
100
|
published URLs.
|
|
101
101
|
- [Command Organization](design/command-organization.md) explains standalone,
|
package/docs/commands.md
CHANGED
|
@@ -119,7 +119,7 @@ should normally mean the repository's complete publishable artifact, while
|
|
|
119
119
|
inline styles, and common content mistakes.
|
|
120
120
|
- `content:sync` / `norna:sync`: moves misplaced referenced image files after
|
|
121
121
|
confirmation when the intended move is unambiguous. Moving files between the
|
|
122
|
-
homepage and
|
|
122
|
+
homepage and an additional page, or between additional pages, requires a clean Git working tree.
|
|
123
123
|
- `theme:presets`: lists the available complete theme presets and explains the
|
|
124
124
|
intended use of each one.
|
|
125
125
|
- `theme:export <preset>`: writes a protected, commented
|
|
@@ -129,7 +129,7 @@ should normally mean the repository's complete publishable artifact, while
|
|
|
129
129
|
- `typography profiles`: prints the exact built-in values for typography
|
|
130
130
|
profiles and rhythms.
|
|
131
131
|
- `typography show`: prints the selected site's resolved typography for the
|
|
132
|
-
theme, every page
|
|
132
|
+
theme, every page, and every section. Each value includes its source,
|
|
133
133
|
and inherited page or section values are marked with `inherited: true`.
|
|
134
134
|
- `site:public`: copies `site/public/` into `site/.norna/public/` and
|
|
135
135
|
removes stale copied static files.
|
package/docs/content.md
CHANGED
|
@@ -1,36 +1,64 @@
|
|
|
1
1
|
# Content
|
|
2
2
|
|
|
3
|
-
`site/content.md` is the homepage
|
|
4
|
-
|
|
3
|
+
`site/content.md` is the homepage file for a Norna site. Its Markdown H1 is
|
|
4
|
+
the page title. Optional page metadata can be added in YAML frontmatter.
|
|
5
5
|
|
|
6
|
-
|
|
7
|
-
`site/
|
|
8
|
-
|
|
6
|
+
Additional pages use the same page model in
|
|
7
|
+
`site/pages/<NNN-page-id>/content.md`. See [Pages](pages.md) for the
|
|
8
|
+
page-specific rules.
|
|
9
9
|
|
|
10
10
|
Site-wide visual defaults belong in [Theme](theme.md). Typography profiles and
|
|
11
11
|
overrides are described in [Typography](typography.md). Technical site settings
|
|
12
12
|
belong in [Configuration](configuration.md).
|
|
13
13
|
|
|
14
|
-
## Page Frontmatter
|
|
14
|
+
## Page Title And Frontmatter
|
|
15
15
|
|
|
16
|
-
|
|
16
|
+
Every page must contain exactly one Markdown H1. It must be the first heading,
|
|
17
|
+
must not have a section id, and supplies the visible page title, HTML document
|
|
18
|
+
title, and page label in site navigation:
|
|
17
19
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
20
|
+
```md
|
|
21
|
+
# My Site
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
Content between the H1 and the first H2 is the page introduction. It may
|
|
25
|
+
contain prose and Norna blocks.
|
|
26
|
+
|
|
27
|
+
Frontmatter is optional. When present, the content schema validates these
|
|
28
|
+
top-level fields:
|
|
29
|
+
|
|
30
|
+
- `page`: optional page metadata.
|
|
31
|
+
- `navigation`: optional page-listing metadata. See [Pages](pages.md).
|
|
32
|
+
|
|
33
|
+
`page` contains:
|
|
34
|
+
|
|
35
|
+
- `description`: optional string. Used only as the page's HTML meta description
|
|
36
|
+
for search engines, link previews, and other metadata consumers. It is not
|
|
37
|
+
rendered as visible page content.
|
|
38
|
+
|
|
39
|
+
Minimal homepage without metadata:
|
|
40
|
+
|
|
41
|
+
```md
|
|
42
|
+
# My Site
|
|
43
|
+
|
|
44
|
+
Introductory text.
|
|
22
45
|
|
|
23
|
-
|
|
46
|
+
## Work {#work}
|
|
47
|
+
|
|
48
|
+
Text...
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
Homepage with a meta description:
|
|
24
52
|
|
|
25
53
|
```md
|
|
26
54
|
---
|
|
27
|
-
|
|
28
|
-
description: A small Norna site.
|
|
55
|
+
page:
|
|
56
|
+
description: A small Norna site.
|
|
29
57
|
---
|
|
30
58
|
|
|
31
|
-
|
|
59
|
+
# My Site
|
|
32
60
|
|
|
33
|
-
|
|
61
|
+
Introductory text.
|
|
34
62
|
```
|
|
35
63
|
|
|
36
64
|
## Sections
|
|
@@ -57,39 +85,14 @@ Every section heading must have an explicit id:
|
|
|
57
85
|
## Work {#work}
|
|
58
86
|
```
|
|
59
87
|
|
|
60
|
-
The id must match `^[a-z0-9-]+$`. It is used for anchors
|
|
61
|
-
|
|
62
|
-
|
|
88
|
+
The id must match `^[a-z0-9-]+$`. It is used for anchors and section
|
|
89
|
+
navigation. The visible section navigation label comes from the Markdown
|
|
90
|
+
heading text.
|
|
63
91
|
|
|
64
92
|
Markdown section content starts at the level 2 heading and continues until the
|
|
65
93
|
next level 2 heading. `###` and `####` headings are body subheadings within the
|
|
66
94
|
current section, not new sections.
|
|
67
95
|
|
|
68
|
-
## Section Metadata
|
|
69
|
-
|
|
70
|
-
Use `sections` only when a section needs structured metadata that is not
|
|
71
|
-
naturally expressed by Markdown. Currently this is date-based visibility.
|
|
72
|
-
|
|
73
|
-
```yaml
|
|
74
|
-
sections:
|
|
75
|
-
work:
|
|
76
|
-
visible:
|
|
77
|
-
from: "2026-08-01"
|
|
78
|
-
until: "2026-09-16"
|
|
79
|
-
```
|
|
80
|
-
|
|
81
|
-
See [Temporary Sections](#temporary-sections) for visibility semantics.
|
|
82
|
-
|
|
83
|
-
Each `sections.<section-id>` key must match a Markdown heading id in the same
|
|
84
|
-
page file:
|
|
85
|
-
|
|
86
|
-
```md
|
|
87
|
-
## Work {#work}
|
|
88
|
-
```
|
|
89
|
-
|
|
90
|
-
Do not list sections in frontmatter just to define order. Section order comes
|
|
91
|
-
from the Markdown heading order.
|
|
92
|
-
|
|
93
96
|
## Norna Blocks
|
|
94
97
|
|
|
95
98
|
Norna-managed local images and cards are written in Markdown fenced blocks at
|
|
@@ -97,6 +100,8 @@ the point where they should appear in the section. Markdown determines
|
|
|
97
100
|
placement: move the fenced block in the page file to move the rendered image,
|
|
98
101
|
carousel, or card list.
|
|
99
102
|
|
|
103
|
+
### Image Stack
|
|
104
|
+
|
|
100
105
|
Use `norna-image-stack` for one or more stacked images:
|
|
101
106
|
|
|
102
107
|
````md
|
|
@@ -107,6 +112,8 @@ Use `norna-image-stack` for one or more stacked images:
|
|
|
107
112
|
```
|
|
108
113
|
````
|
|
109
114
|
|
|
115
|
+
### Image Carousel
|
|
116
|
+
|
|
110
117
|
Use `norna-image-carousel` for a carousel:
|
|
111
118
|
|
|
112
119
|
````md
|
|
@@ -120,6 +127,8 @@ Use `norna-image-carousel` for a carousel:
|
|
|
120
127
|
```
|
|
121
128
|
````
|
|
122
129
|
|
|
130
|
+
### Card List
|
|
131
|
+
|
|
123
132
|
Use `norna-card-list` for a list of compact cards. Cards can include text,
|
|
124
133
|
managed images, links, and optional badge text:
|
|
125
134
|
|
|
@@ -198,13 +207,13 @@ sizing is less predictable.
|
|
|
198
207
|
Homepage images live under:
|
|
199
208
|
|
|
200
209
|
```text
|
|
201
|
-
site/images
|
|
210
|
+
site/images/
|
|
202
211
|
```
|
|
203
212
|
|
|
204
|
-
|
|
213
|
+
Page images live under:
|
|
205
214
|
|
|
206
215
|
```text
|
|
207
|
-
site/
|
|
216
|
+
site/pages/<NNN-page-id>/images/
|
|
208
217
|
```
|
|
209
218
|
|
|
210
219
|
Image references in Norna managed image blocks use only the filename:
|
|
@@ -215,13 +224,15 @@ Image references in Norna managed image blocks use only the filename:
|
|
|
215
224
|
```
|
|
216
225
|
````
|
|
217
226
|
|
|
218
|
-
If `portrait.jpg` is referenced
|
|
219
|
-
location is `site/images/
|
|
227
|
+
If `portrait.jpg` is referenced anywhere on the homepage, its expected
|
|
228
|
+
location is `site/images/portrait.jpg`. The same file may be referenced from
|
|
229
|
+
more than one section on that page.
|
|
220
230
|
|
|
221
|
-
Filenames
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
exists, Norna reports the
|
|
231
|
+
Filenames must be unique within one page's image directory, but do not have to
|
|
232
|
+
be globally unique across the site. Automatic sync only moves files between
|
|
233
|
+
page image roots when the filename identifies exactly one source candidate
|
|
234
|
+
across the site. If more than one candidate exists, Norna reports the
|
|
235
|
+
ambiguity instead of guessing.
|
|
225
236
|
|
|
226
237
|
## Markdown Images
|
|
227
238
|
|
|
@@ -237,36 +248,6 @@ managed by Norna. Use `norna-image-stack`, `norna-image-carousel`, or
|
|
|
237
248
|
`norna-card-list` for local site images that should be validated, processed and
|
|
238
249
|
synced.
|
|
239
250
|
|
|
240
|
-
## Temporary Sections
|
|
241
|
-
|
|
242
|
-
Use `sections.<section-id>.visible` for sections that should be rendered only
|
|
243
|
-
during a date window:
|
|
244
|
-
|
|
245
|
-
```yaml
|
|
246
|
-
sections:
|
|
247
|
-
exhibition:
|
|
248
|
-
visible:
|
|
249
|
-
from: "2026-08-01"
|
|
250
|
-
until: "2026-09-16"
|
|
251
|
-
```
|
|
252
|
-
|
|
253
|
-
`from` is inclusive. `until` is exclusive. With the example above, the section
|
|
254
|
-
is visible from 2026-08-01 through 2026-09-15 and hidden again on 2026-09-16.
|
|
255
|
-
|
|
256
|
-
Both `from` and `until` use `YYYY-MM-DD`. Either value may be omitted, but a
|
|
257
|
-
`visible` object must contain at least one of them.
|
|
258
|
-
|
|
259
|
-
Hidden sections are omitted from the rendered HTML and sticky navigation. They
|
|
260
|
-
remain in the page file, and `content:check` still validates their matching
|
|
261
|
-
Markdown headings and image references.
|
|
262
|
-
|
|
263
|
-
The current date is evaluated at dev/build time. Set `NORNA_TODAY` to preview
|
|
264
|
-
or test a specific date:
|
|
265
|
-
|
|
266
|
-
```sh
|
|
267
|
-
NORNA_TODAY=2026-08-15 npm run norna:build
|
|
268
|
-
```
|
|
269
|
-
|
|
270
251
|
## Markdown Text
|
|
271
252
|
|
|
272
253
|
Use ordinary Markdown for emphasis and structure:
|
|
@@ -277,7 +258,7 @@ This sentence contains **important text** and *emphasised text*.
|
|
|
277
258
|
|
|
278
259
|
Norna intentionally does not support arbitrary inline color or style classes.
|
|
279
260
|
Deprecated syntax such as `[highlighted text]{.yellow}` is rejected by
|
|
280
|
-
`content:check`. Keep the
|
|
261
|
+
`content:check`. Keep the page visually coherent through its `theme.yaml`
|
|
281
262
|
instead of styling individual phrases.
|
|
282
263
|
|
|
283
264
|
### Side Notes
|
|
@@ -315,7 +296,7 @@ Run:
|
|
|
315
296
|
npm run norna:content:check
|
|
316
297
|
```
|
|
317
298
|
|
|
318
|
-
This checks section heading ids,
|
|
299
|
+
This checks section heading ids, duplicate image names,
|
|
319
300
|
missing image files, misplaced referenced images, duplicate image references,
|
|
320
301
|
invalid Norna blocks, unreferenced images, removed inline style syntax,
|
|
321
302
|
Markdown image references to unmanaged local files, and common frontmatter
|
|
@@ -327,15 +308,12 @@ invalid, when a key is indented under a line that already has a value, or when a
|
|
|
327
308
|
known nested key appears at the top level:
|
|
328
309
|
|
|
329
310
|
```yaml
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
visible:
|
|
333
|
-
from: "2026-08-01"
|
|
311
|
+
navigation:
|
|
312
|
+
listed: false
|
|
334
313
|
```
|
|
335
314
|
|
|
336
|
-
Top-level page frontmatter may contain only `
|
|
337
|
-
|
|
338
|
-
`theme.yaml`.
|
|
315
|
+
Top-level page frontmatter may contain only `page` and `navigation`. Visual
|
|
316
|
+
settings belong in the root or page-local `theme.yaml`.
|
|
339
317
|
|
|
340
318
|
Run:
|
|
341
319
|
|
|
@@ -343,20 +321,22 @@ Run:
|
|
|
343
321
|
npm run norna:sync
|
|
344
322
|
```
|
|
345
323
|
|
|
346
|
-
This moves referenced image files into the
|
|
347
|
-
|
|
324
|
+
This moves referenced image files into the image directory for the page that
|
|
325
|
+
references them. Moving a block between sections on the same page does not
|
|
326
|
+
move the file because all sections share the page image directory. The command
|
|
327
|
+
prompts before writing unless `--yes` is passed.
|
|
348
328
|
|
|
349
329
|
`content:sync` is intentionally conservative. It only moves a file when the
|
|
350
|
-
filename identifies exactly one matching source candidate across
|
|
351
|
-
|
|
330
|
+
filename identifies exactly one matching source candidate across all page
|
|
331
|
+
image roots, and when the move will not break another reference.
|
|
352
332
|
If the intended move is ambiguous, rename or move the file manually and run
|
|
353
333
|
`content:check` again.
|
|
354
334
|
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
335
|
+
The same filename may exist in different page image directories. Automatic
|
|
336
|
+
relocation only requires site-wide filename uniqueness for the file being
|
|
337
|
+
moved.
|
|
358
338
|
|
|
359
|
-
When `content:sync` needs to move an image between the homepage and a
|
|
360
|
-
between two
|
|
361
|
-
keeps cross-
|
|
339
|
+
When `content:sync` needs to move an image between the homepage and a page, or
|
|
340
|
+
between two pages, the Git working tree must be clean before the write. This
|
|
341
|
+
keeps cross-page sync easy to roll back. `content:check` only reports issues
|
|
362
342
|
and does not require a clean working tree.
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
# Navigation And Theme Plan
|
|
2
|
+
|
|
3
|
+
This document records the intended order of work for page hierarchy,
|
|
4
|
+
navigation, and theme presets. It is an implementation plan, not a description
|
|
5
|
+
of released behavior.
|
|
6
|
+
|
|
7
|
+
## Goal
|
|
8
|
+
|
|
9
|
+
Norna should support sites with limited global navigation and a larger local
|
|
10
|
+
page hierarchy without making mobile navigation harder to understand. Theme
|
|
11
|
+
presets should provide a coherent visual system without changing the site's
|
|
12
|
+
information architecture.
|
|
13
|
+
|
|
14
|
+
## Working Principles
|
|
15
|
+
|
|
16
|
+
- The file structure defines the page hierarchy and presentation order.
|
|
17
|
+
- Navigation behavior and navigation styling are separate concerns.
|
|
18
|
+
- Global site navigation, local page navigation, and headings on the current
|
|
19
|
+
page have distinct roles.
|
|
20
|
+
- Changing a theme preset must not change which pages are available or how the
|
|
21
|
+
page hierarchy is interpreted.
|
|
22
|
+
- Site-wide visual identity should remain coherent while individual pages may
|
|
23
|
+
vary where that does not disrupt navigation or orientation.
|
|
24
|
+
- Documentation and broad example migration should follow implementation and
|
|
25
|
+
manual evaluation, not precede them.
|
|
26
|
+
|
|
27
|
+
## Order Of Work
|
|
28
|
+
|
|
29
|
+
### 1. Stabilize The Page Tree
|
|
30
|
+
|
|
31
|
+
Finish and test nested page discovery independently of final navigation
|
|
32
|
+
presentation. Establish deterministic rules for:
|
|
33
|
+
|
|
34
|
+
- directory parsing, page ids, URL paths, and presentation order;
|
|
35
|
+
- parent and ancestor relationships;
|
|
36
|
+
- collisions and invalid nesting;
|
|
37
|
+
- page-local content, images, and themes;
|
|
38
|
+
- breadcrumbs and current-branch discovery.
|
|
39
|
+
|
|
40
|
+
Commit this foundation separately before broad theme or preset changes.
|
|
41
|
+
|
|
42
|
+
### 2. Define The Navigation Contract
|
|
43
|
+
|
|
44
|
+
The intended information architecture is:
|
|
45
|
+
|
|
46
|
+
- a small global navigation for the site's top-level areas;
|
|
47
|
+
- a larger local page tree for the selected area;
|
|
48
|
+
- a separate `On this page` list for headings on the current page;
|
|
49
|
+
- breadcrumbs for location and ancestry;
|
|
50
|
+
- one unified mobile navigation containing the whole page hierarchy, with the
|
|
51
|
+
current branch expanded and current page marked.
|
|
52
|
+
|
|
53
|
+
The exact contract is potentially difficult to evaluate at an abstract level.
|
|
54
|
+
The maintainer therefore expects this phase to use executable test sites,
|
|
55
|
+
focused automated tests, or clear illustrative examples. These artifacts
|
|
56
|
+
should demonstrate short single-page sites, ordinary two-level sites, and
|
|
57
|
+
deeper documentation-style hierarchies on both desktop and mobile before the
|
|
58
|
+
contract is considered stable.
|
|
59
|
+
|
|
60
|
+
The contract should also define the fallback and override behavior for the
|
|
61
|
+
supported navigation modes. Structural behavior belongs to site-level engine
|
|
62
|
+
configuration or deterministic automatic selection, not to presentation
|
|
63
|
+
presets.
|
|
64
|
+
|
|
65
|
+
### 3. Implement Navigation In Layers
|
|
66
|
+
|
|
67
|
+
Implement and verify the navigation model in this order:
|
|
68
|
+
|
|
69
|
+
1. page-tree data and validation;
|
|
70
|
+
2. desktop global navigation, local tree, breadcrumbs, and `On this page`;
|
|
71
|
+
3. unified mobile navigation;
|
|
72
|
+
4. keyboard, focus, current-page, and progressive-enhancement behavior;
|
|
73
|
+
5. visual evaluation at representative viewport sizes.
|
|
74
|
+
|
|
75
|
+
Keep real links as the foundation. Client-side JavaScript should only enhance
|
|
76
|
+
interaction that cannot be expressed adequately with HTML and CSS.
|
|
77
|
+
|
|
78
|
+
### 4. Refine Theme And Preset Responsibilities
|
|
79
|
+
|
|
80
|
+
Presets should control visual presentation, including:
|
|
81
|
+
|
|
82
|
+
- color system;
|
|
83
|
+
- typography;
|
|
84
|
+
- spacing and density;
|
|
85
|
+
- page and content widths;
|
|
86
|
+
- the visual treatment of global navigation, local navigation, breadcrumbs,
|
|
87
|
+
and `On this page`.
|
|
88
|
+
|
|
89
|
+
Presets must not determine page hierarchy, link membership, or semantic
|
|
90
|
+
navigation structure. Those must remain stable when a preset changes.
|
|
91
|
+
|
|
92
|
+
Site-wide color, typography, and navigation treatment should normally remain
|
|
93
|
+
consistent. Page-local theme variation should be limited to properties such as
|
|
94
|
+
content width, density, and media presentation when variation does not weaken
|
|
95
|
+
site identity or navigation clarity.
|
|
96
|
+
|
|
97
|
+
### 5. Migrate After Evaluation
|
|
98
|
+
|
|
99
|
+
After the page tree, navigation contract, and preset boundaries have been
|
|
100
|
+
manually evaluated:
|
|
101
|
+
|
|
102
|
+
- migrate fixtures and examples;
|
|
103
|
+
- update schemas and editor assistance;
|
|
104
|
+
- update Markdown reference documentation;
|
|
105
|
+
- update the rendered documentation site;
|
|
106
|
+
- remove obsolete navigation and preset behavior rather than retaining
|
|
107
|
+
compatibility layers.
|
|
108
|
+
|
|
109
|
+
Keep foundation, navigation, preset, migration, and documentation changes in
|
|
110
|
+
separate commits where practical.
|
|
111
|
+
|
|
112
|
+
## Immediate Checkpoint
|
|
113
|
+
|
|
114
|
+
The current nested-page implementation should be reviewed, tested, and secured
|
|
115
|
+
before work continues on the final navigation contract or preset model.
|
|
@@ -54,9 +54,9 @@ the image, or in `docs/design/` when it is useful for future maintenance.
|
|
|
54
54
|
- Keep arrows few and directional.
|
|
55
55
|
- Avoid diagrams where every object connects to every other object.
|
|
56
56
|
- Prefer multiple simple diagrams over one dense diagram.
|
|
57
|
-
- Make
|
|
57
|
+
- Make page order, URL slugs, section ids, image folders, source files, and
|
|
58
58
|
generated output visually distinct when those ideas matter.
|
|
59
|
-
- Do not show templates, components, custom rendering logic,
|
|
59
|
+
- Do not show templates, components, custom rendering logic, page-level
|
|
60
60
|
technical configuration, or hosting integrations that Norna does not support.
|
|
61
61
|
- Do not show page layouts that Norna cannot actually render unless the diagram
|
|
62
62
|
is clearly abstract and not a product capability example.
|
|
@@ -67,12 +67,12 @@ Diagrams must match the current Norna model:
|
|
|
67
67
|
|
|
68
68
|
- A Norna site is described with site files, not arbitrary project structure.
|
|
69
69
|
- `content.md` is the homepage content file.
|
|
70
|
-
- `sitewide-content.yaml` contains shared
|
|
70
|
+
- `sitewide-content.yaml` contains shared logo settings, banners, and footer
|
|
71
71
|
content.
|
|
72
|
-
- Additional pages are
|
|
73
|
-
-
|
|
74
|
-
-
|
|
75
|
-
- Images belong under the image root for
|
|
72
|
+
- Additional pages are page directories with `content.md`.
|
|
73
|
+
- Page folder prefixes control navigation order.
|
|
74
|
+
- Page ids become URL segments.
|
|
75
|
+
- Images belong under the image root for their page, usually grouped by
|
|
76
76
|
section id.
|
|
77
77
|
- Markdown remains the primary writing format.
|
|
78
78
|
- Norna blocks cover fixed site patterns such as image stacks,
|
|
@@ -108,7 +108,7 @@ over relying on horizontal scrolling.
|
|
|
108
108
|
Store diagram SVG files as normal Norna managed image assets:
|
|
109
109
|
|
|
110
110
|
```text
|
|
111
|
-
site/
|
|
111
|
+
site/pages/<NNN-page-id>/images/<diagram-name>.svg
|
|
112
112
|
```
|
|
113
113
|
|
|
114
114
|
Reference them with a Norna image block:
|
|
@@ -132,7 +132,7 @@ Before accepting a diagram:
|
|
|
132
132
|
|
|
133
133
|
- The main message is obvious without reading the surrounding section.
|
|
134
134
|
- The diagram does not imply unsupported Norna functionality.
|
|
135
|
-
- URL,
|
|
135
|
+
- URL, page, section, image, theme, config, and output terminology is
|
|
136
136
|
consistent with documentation.
|
|
137
137
|
- Text fits inside boxes at desktop and mobile widths.
|
|
138
138
|
- Arrows clarify the relationship instead of adding noise.
|