@janga/norna 0.7.13 → 0.7.15

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.
Files changed (146) hide show
  1. package/README.md +15 -9
  2. package/bin/norna-cli.mjs +11 -4
  3. package/docs/README.md +71 -43
  4. package/docs/commands.md +34 -20
  5. package/docs/configuration.md +43 -62
  6. package/docs/content.md +34 -7
  7. package/docs/design/command-organization.md +15 -8
  8. package/docs/design/norna-diagram-design.md +6 -6
  9. package/docs/design/site-examples-structure.md +1 -1
  10. package/docs/engine-development.md +22 -9
  11. package/docs/getting-started.md +29 -16
  12. package/docs/how-to/embedded-site.md +1 -1
  13. package/docs/images-and-metadata.md +3 -3
  14. package/docs/local-development.md +11 -3
  15. package/docs/public-files.md +105 -0
  16. package/docs/publishing.md +4 -8
  17. package/docs/routes.md +6 -7
  18. package/docs/site-files.md +144 -0
  19. package/docs/sitewide-content.md +47 -33
  20. package/docs/theme.md +37 -49
  21. package/docs/typography.md +25 -31
  22. package/examples/complete-sites/dog-shelter-multi-page/README.md +8 -0
  23. package/examples/complete-sites/{dog-shelter-single-page/site/config.md → dog-shelter-multi-page/site/config.yaml} +0 -2
  24. package/examples/complete-sites/dog-shelter-multi-page/site/sitewide-content.yaml +6 -0
  25. package/examples/complete-sites/dog-shelter-multi-page/site/{theme.md → theme.yaml} +0 -2
  26. package/examples/complete-sites/dog-shelter-single-page/README.md +8 -0
  27. package/examples/complete-sites/{dog-shelter-multi-page/site/config.md → dog-shelter-single-page/site/config.yaml} +0 -2
  28. package/examples/complete-sites/dog-shelter-single-page/site/sitewide-content.yaml +6 -0
  29. package/examples/complete-sites/dog-shelter-single-page/site/{theme.md → theme.yaml} +0 -2
  30. package/examples/feature-demos/media-and-surfaces/.astro/data-store.json +1 -1
  31. package/examples/feature-demos/media-and-surfaces/README.md +1 -1
  32. package/examples/feature-demos/media-and-surfaces/site/{config.md → config.yaml} +0 -2
  33. package/examples/feature-demos/media-and-surfaces/site/content.md +2 -2
  34. package/examples/feature-demos/media-and-surfaces/site/routes/020-surfaces/{route-content.md → content.md} +3 -7
  35. package/examples/feature-demos/media-and-surfaces/site/routes/020-surfaces/theme.yaml +3 -0
  36. package/examples/feature-demos/media-and-surfaces/site/{sitewide-content.md → sitewide-content.yaml} +1 -3
  37. package/examples/feature-demos/media-and-surfaces/site/{theme.md → theme.yaml} +0 -2
  38. package/examples/feature-demos/sitewide-content/README.md +8 -0
  39. package/examples/feature-demos/sitewide-content/site/{config.md → config.yaml} +0 -2
  40. package/examples/feature-demos/sitewide-content/site/routes/010-identity/{route-content.md → content.md} +3 -3
  41. package/examples/feature-demos/sitewide-content/site/routes/020-notices/{route-content.md → content.md} +1 -1
  42. package/examples/feature-demos/sitewide-content/site/routes/030-footer/{route-content.md → content.md} +1 -1
  43. package/examples/feature-demos/sitewide-content/site/{sitewide-content.md → sitewide-content.yaml} +1 -11
  44. package/examples/feature-demos/sitewide-content/site/{theme.md → theme.yaml} +0 -2
  45. package/examples/feature-demos/theme-presets/site/config.yaml +1 -0
  46. package/examples/feature-demos/theme-presets/site/routes/010-portfolio/{theme.md → theme.yaml} +0 -2
  47. package/examples/feature-demos/theme-presets/site/routes/020-documentation/{theme.md → theme.yaml} +0 -2
  48. package/examples/feature-demos/theme-presets/site/routes/030-project/theme.yaml +1 -0
  49. package/examples/feature-demos/theme-presets/site/routes/040-statement/{route-content.md → content.md} +1 -1
  50. package/examples/feature-demos/theme-presets/site/routes/040-statement/{theme.md → theme.yaml} +0 -2
  51. package/examples/feature-demos/theme-presets/site/{sitewide-content.md → sitewide-content.yaml} +1 -3
  52. package/examples/feature-demos/theme-presets/site/theme.yaml +1 -0
  53. package/fixtures/basic/site/{config.md → config.yaml} +0 -2
  54. package/fixtures/basic/site/content.md +3 -3
  55. package/fixtures/basic/site/{sitewide-content.md → sitewide-content.yaml} +0 -2
  56. package/fixtures/basic/site/{theme.md → theme.yaml} +3 -6
  57. package/fixtures/content-model-v2/site/{config.md → config.yaml} +0 -2
  58. package/fixtures/content-model-v2/site/theme.yaml +4 -0
  59. package/package.json +10 -3
  60. package/schemas/config.schema.json +77 -0
  61. package/schemas/content-frontmatter.schema.json +81 -0
  62. package/schemas/manifest.json +9 -0
  63. package/schemas/sitewide-content.schema.json +215 -0
  64. package/schemas/theme.schema.json +1208 -0
  65. package/scripts/check-config.mjs +18 -11
  66. package/scripts/export-theme-preset.mjs +1 -1
  67. package/scripts/generate-schemas.mjs +283 -0
  68. package/scripts/init-site.mjs +22 -27
  69. package/scripts/lib/documentation-links.mjs +8 -0
  70. package/scripts/lib/editor-language-service.mjs +609 -0
  71. package/scripts/lib/example-sites.mjs +2 -2
  72. package/scripts/lib/git-status.mjs +7 -0
  73. package/scripts/lib/logo-assets.mjs +15 -10
  74. package/scripts/lib/norna-markdown-blocks.mjs +90 -11
  75. package/scripts/lib/presentation.mjs +23 -12
  76. package/scripts/lib/project-config.mjs +17 -41
  77. package/scripts/lib/public-asset-conventions.mjs +112 -0
  78. package/scripts/lib/schema-definitions.mjs +213 -0
  79. package/scripts/lib/schema-value-definitions.mjs +86 -0
  80. package/scripts/lib/site-content.mjs +24 -18
  81. package/scripts/lib/site-paths.mjs +4 -8
  82. package/scripts/lib/sitewide-content.mjs +24 -0
  83. package/scripts/lib/theme-config.mjs +15 -35
  84. package/scripts/lib/theme-presets.mjs +76 -66
  85. package/scripts/lib/typography.mjs +15 -15
  86. package/scripts/lib/yaml-config.mjs +50 -0
  87. package/scripts/list-theme-presets.mjs +15 -0
  88. package/scripts/release.mjs +84 -8
  89. package/scripts/show-typography.mjs +22 -46
  90. package/scripts/sync-content-sections.mjs +2 -2
  91. package/scripts/test-client-javascript.mjs +28 -28
  92. package/scripts/test-content-check.mjs +21 -26
  93. package/scripts/test-content-model-v2.mjs +72 -40
  94. package/scripts/test-documentation.mjs +70 -4
  95. package/scripts/test-editor-language-service.mjs +158 -0
  96. package/scripts/test-engine-commands.mjs +65 -34
  97. package/scripts/test-package-check.mjs +37 -30
  98. package/scripts/test-project-config.mjs +15 -20
  99. package/scripts/test-schemas.mjs +102 -0
  100. package/scripts/test-temporary-visibility.mjs +5 -13
  101. package/scripts/test-theme-presets.mjs +64 -37
  102. package/src/components/CardList.astro +2 -5
  103. package/src/components/ImageCarousel.astro +21 -21
  104. package/src/components/{GalleryGrid.astro → ImageStack.astro} +12 -12
  105. package/src/components/SectionNavigationScript.astro +28 -0
  106. package/src/components/SiteNavigation.astro +6 -5
  107. package/src/components/SitePage.astro +8 -8
  108. package/src/components/SiteSection.astro +18 -21
  109. package/src/content.config.ts +17 -209
  110. package/src/layouts/BaseLayout.astro +9 -9
  111. package/src/lib/{galleryImages.ts → imagePresentation.ts} +7 -7
  112. package/src/lib/routeThemes.ts +9 -29
  113. package/src/lib/sectionContent.ts +3 -3
  114. package/src/lib/sitePublicAssets.ts +5 -21
  115. package/src/styles/global.css +73 -73
  116. package/starters/basic/.github/workflows/deploy.yml +1 -1
  117. package/starters/basic/README.md +16 -13
  118. package/starters/basic/package.json +3 -2
  119. package/starters/basic/site/{config.md → config.yaml} +0 -2
  120. package/starters/basic/site/content.md +1 -1
  121. package/starters/basic/site/{sitewide-content.md → sitewide-content.yaml} +1 -3
  122. package/starters/basic/site/{theme.md → theme.yaml} +8 -15
  123. package/starters/project/.github/workflows/deploy.yml +1 -1
  124. package/starters/project/README.md +22 -15
  125. package/starters/project/package.json +3 -2
  126. package/starters/project/site/{config.md → config.yaml} +0 -2
  127. package/starters/project/site/{sitewide-content.md → sitewide-content.yaml} +1 -3
  128. package/starters/project/site/{theme.md → theme.yaml} +4 -8
  129. package/docs/site-structure.md +0 -98
  130. package/examples/complete-sites/dog-shelter-multi-page/site/sitewide-content.md +0 -16
  131. package/examples/complete-sites/dog-shelter-single-page/site/sitewide-content.md +0 -16
  132. package/examples/feature-demos/media-and-surfaces/site/routes/020-surfaces/theme.md +0 -8
  133. package/examples/feature-demos/theme-presets/site/config.md +0 -3
  134. package/examples/feature-demos/theme-presets/site/routes/030-project/theme.md +0 -3
  135. package/examples/feature-demos/theme-presets/site/theme.md +0 -3
  136. package/fixtures/content-model-v2/site/theme.md +0 -7
  137. package/scripts/lib/sitewide-config.mjs +0 -34
  138. package/src/components/MobileSectionNavigationScript.astro +0 -14
  139. /package/examples/complete-sites/dog-shelter-multi-page/site/routes/010-dogs/{route-content.md → content.md} +0 -0
  140. /package/examples/complete-sites/dog-shelter-multi-page/site/routes/020-adopt/{route-content.md → content.md} +0 -0
  141. /package/examples/feature-demos/media-and-surfaces/site/routes/010-media/{route-content.md → content.md} +0 -0
  142. /package/examples/feature-demos/theme-presets/site/routes/010-portfolio/{route-content.md → content.md} +0 -0
  143. /package/examples/feature-demos/theme-presets/site/routes/020-documentation/{route-content.md → content.md} +0 -0
  144. /package/examples/feature-demos/theme-presets/site/routes/030-project/{route-content.md → content.md} +0 -0
  145. /package/fixtures/content-model-v2/site/routes/010-guide/{route-content.md → content.md} +0 -0
  146. /package/starters/project/site/routes/010-guide/{route-content.md → content.md} +0 -0
@@ -10,12 +10,13 @@
10
10
  "norna:dev:status": "norna dev:status",
11
11
  "norna:dev:logs": "norna dev:logs",
12
12
  "norna:dev:stop": "norna dev:stop",
13
- "norna:check": "npm run norna:config:check && npm run norna:content:check",
13
+ "norna:check": "norna check",
14
14
  "norna:config:check": "norna config:check",
15
15
  "norna:content:check": "norna content:check",
16
16
  "norna:sync": "norna content:sync",
17
+ "norna:theme:presets": "norna theme:presets",
17
18
  "norna:theme:export": "norna theme:export",
18
- "norna:typography:presets": "norna typography presets",
19
+ "norna:typography:profiles": "norna typography profiles",
19
20
  "norna:typography:show": "norna typography show",
20
21
  "norna:public": "norna site:public",
21
22
  "norna:images": "norna images",
@@ -1,3 +1 @@
1
- ---
2
1
  url: https://example.com/
3
- ---
@@ -1,6 +1,5 @@
1
- ---
2
1
  navigation:
3
- brand: Project Name
2
+ label: Project Name
4
3
  footer:
5
4
  copyrightMessage: (c) Project contributors.
6
5
  buildInfo:
@@ -11,4 +10,3 @@ footer:
11
10
  timeZone: UTC
12
11
  dateStyle: short
13
12
  timeStyle: short
14
- ---
@@ -1,4 +1,3 @@
1
- ---
2
1
  # Site-wide visual defaults. Remove a value to use the engine default.
3
2
  layout:
4
3
  density: compact
@@ -16,7 +15,7 @@ layout:
16
15
  finalSectionBottom:
17
16
  desktop: clamp(1rem, 2vw, 1.75rem)
18
17
  mobile: 1rem
19
- gallery:
18
+ images:
20
19
  width: 840px
21
20
  maxAvailableWidthPercent:
22
21
  desktop: 100
@@ -26,10 +25,7 @@ gallery:
26
25
  mobile: 62
27
26
  typography:
28
27
  fontFamily: "Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif"
29
- preset: text-forward
28
+ profile: reading
30
29
  rhythm: compact
31
- presentation:
32
- palette: dark # Alternatives: light, paper
33
- sectionSurfaces:
34
- mode: cycle
35
- ---
30
+ palette: dark # Alternatives: light, paper
31
+ sectionSurfaces: [base, soft]
@@ -1,98 +0,0 @@
1
- # Site Structure
2
-
3
- A `norna` site repository owns the content and configuration for one
4
- published site. The engine repository owns the reusable CLI and renderer.
5
-
6
- ## Default Layout
7
-
8
- The selected site directory defaults to `site/`:
9
-
10
- ```text
11
- site/
12
- |-- config.md
13
- |-- theme.md
14
- |-- sitewide-content.md
15
- |-- content.md
16
- |-- images/
17
- | `-- <section-id>/
18
- |-- routes/
19
- | `-- <NNN-route-id>/
20
- | |-- route-content.md
21
- | `-- images/
22
- | `-- <section-id>/
23
- |-- public/
24
- `-- .norna/
25
- |-- generated-images.json
26
- `-- public/
27
- ```
28
-
29
- Use `NORNA_SITE_DIR` or `norna --site-dir <path>` to select another
30
- site directory. Without an explicit site directory, commands first accept the
31
- current directory when it contains both `config.md` and `content.md`.
32
- Otherwise, commands started from a subdirectory walk upward until they find the
33
- default `site/` directory containing those files.
34
- `theme.md` is required. It can contain only a complete preset selection.
35
-
36
- ## Versioned Source Files
37
-
38
- Version these files in a site repository:
39
-
40
- - `site/config.md`: public URL and optional language and smooth scrolling.
41
- - `site/theme.md`: required site-wide visual theme. It normally selects a
42
- complete preset and may add focused layout, image, typography, palette, or
43
- section-surface overrides.
44
- See [Theme](theme.md).
45
- - `site/sitewide-content.md`: shared site identity, banners and footer content.
46
- See [Sitewide Content](sitewide-content.md).
47
- - `site/content.md`: homepage page file with editable content, Markdown
48
- sections, optional section metadata, managed media blocks, alt text, and
49
- captions.
50
- See [Content](content.md).
51
- - `site/images/<section-id>/`: original source images.
52
- - `site/routes/<NNN-route-id>/route-content.md`: optional route page files.
53
- See [Routes](routes.md).
54
- - `site/routes/<NNN-route-id>/images/<section-id>/`: original source images
55
- for that route page.
56
- - `site/public/`: site-specific static public files.
57
- - `site/.norna/generated-images.json`: generated image manifest used to
58
- decide whether WebP variants and copied managed SVG files can be reused.
59
- - `.github/workflows/deploy.yml`: site-owned GitHub Pages workflow.
60
- - `package.json` and `package-lock.json`: scripts and pinned engine dependency.
61
-
62
- ## Generated Files
63
-
64
- Do not edit these by hand:
65
-
66
- - `site/.norna/public/`: build-preparation output copied from
67
- `site/public/`, plus generated images.
68
- - `dist/`: final static build output.
69
- - `.astro/`: Astro cache, generated types, and dev-server state.
70
- - `public/`: legacy generated public output from older engine versions.
71
-
72
- `site:public` removes stale copied static files under
73
- `site/.norna/public/` while preserving generated image output under
74
- `site/.norna/public/images/`.
75
-
76
- Favicons are convention-based. Put files such as `favicon.svg`, `favicon.ico`,
77
- `favicon.png`, or `apple-touch-icon.png` in `site/public/`. The renderer emits
78
- icon links only for files that exist and prefixes them with the base path
79
- when the site is published below a path such as `/repository-name/`.
80
-
81
- ## Engine Repository Layout
82
-
83
- In this repository:
84
-
85
- - `bin/norna.mjs` launches the appropriate installed Norna version.
86
- - `bin/norna-cli.mjs` dispatches public CLI commands.
87
- - `scripts/` contains validation, image, local preview, deploy, and test tools.
88
- - `src/` contains the Astro renderer, components, styles, and content schema.
89
- - `starters/basic/` is the default compact starter copied by
90
- `norna init <target-dir>`.
91
- - `starters/project/` is a project-site starter used as a maintained example
92
- for small project and developer-tool sites.
93
- - `fixtures/basic/site/` is used by engine regression tests.
94
- - `examples/feature-demos/media-and-surfaces/site/` is the broad visual example
95
- used by demo builds and navigation diagnostics.
96
- - `examples/complete-sites/` contains coherent sites, while
97
- `examples/feature-demos/` contains focused visual test benches.
98
- - `site/` is reserved for the local documentation site.
@@ -1,16 +0,0 @@
1
- ---
2
- navigation:
3
- logo:
4
- alt: Dog Shelter
5
- height: 3rem
6
- footer:
7
- copyrightMessage: Dog Shelter example site. Dog photos by Bicanski, CC0, via Pixnio.
8
- ---
9
-
10
- <!-- norna-image-provenance:
11
- image: logo.svg
12
- source: AI-assisted, hand-authored SVG
13
- prompt: Create a compact horizontal dog shelter logo with a simple dog face in
14
- a house-shaped mark and the words Dog Shelter. Use flat vector shapes, a warm
15
- red accent, dark text, transparent background and no external assets.
16
- -->
@@ -1,16 +0,0 @@
1
- ---
2
- navigation:
3
- logo:
4
- alt: Dog Shelter
5
- height: 3rem
6
- footer:
7
- copyrightMessage: Dog Shelter example site. Dog photos by Bicanski, CC0, via Pixnio.
8
- ---
9
-
10
- <!-- norna-image-provenance:
11
- image: logo.svg
12
- source: AI-assisted, hand-authored SVG
13
- prompt: Create a compact horizontal dog shelter logo with a simple dog face in
14
- a house-shaped mark and the words Dog Shelter. Use flat vector shapes, a warm
15
- red accent, dark text, transparent background and no external assets.
16
- -->
@@ -1,8 +0,0 @@
1
- ---
2
- preset: project
3
- presentation:
4
- palette: light
5
- sectionSurfaces:
6
- mode: cycle
7
- sequence: [base, soft, emphasis]
8
- ---
@@ -1,3 +0,0 @@
1
- ---
2
- url: http://localhost:4321/
3
- ---
@@ -1,3 +0,0 @@
1
- ---
2
- preset: project
3
- ---
@@ -1,3 +0,0 @@
1
- ---
2
- preset: project
3
- ---
@@ -1,7 +0,0 @@
1
- ---
2
- typography:
3
- preset: text-forward
4
- rhythm: normal
5
- presentation:
6
- palette: dark
7
- ---
@@ -1,34 +0,0 @@
1
- import { readFile } from 'node:fs/promises';
2
- import { parseYamlMapping } from './frontmatter-yaml.mjs';
3
- import {
4
- sitewideContentLabel,
5
- sitewideContentPath,
6
- } from './site-paths.mjs';
7
- import {
8
- splitSiteFile,
9
- validateFrontmatterIndentation,
10
- validateSitewideFrontmatterStructure,
11
- } from './site-content.mjs';
12
-
13
- export const readSitewideConfig = async () => {
14
- const source = await readFile(sitewideContentPath, 'utf8').catch((error) => {
15
- if (error?.code === 'ENOENT') return null;
16
- throw error;
17
- });
18
-
19
- if (!source) return {};
20
-
21
- const { frontmatter, frontmatterBody } = splitSiteFile(source, sitewideContentLabel);
22
- const issues = [];
23
- validateFrontmatterIndentation(frontmatter, (issue) => issues.push(issue));
24
- validateSitewideFrontmatterStructure(frontmatter, (issue) => issues.push(issue));
25
-
26
- if (issues.length > 0) {
27
- throw new Error([
28
- `${sitewideContentLabel} has invalid frontmatter.`,
29
- ...issues.map((issue) => `- ${issue.message}`),
30
- ].join('\n'));
31
- }
32
-
33
- return parseYamlMapping(frontmatterBody);
34
- };
@@ -1,14 +0,0 @@
1
- <script>
2
- const mobileMenu = document.querySelector<HTMLDetailsElement>('.mobile-nav-menu');
3
- const sectionLinks = Array.from(document.querySelectorAll<HTMLAnchorElement>('.mobile-page-nav a'));
4
-
5
- sectionLinks.forEach((link) => {
6
- link.addEventListener('click', (event) => {
7
- const linkUrl = new URL(link.href, window.location.href);
8
- if (linkUrl.pathname !== window.location.pathname) return;
9
-
10
- if (mobileMenu) mobileMenu.open = false;
11
- if (event.detail > 0) link.blur();
12
- });
13
- });
14
- </script>