@janga/norna 0.7.27 → 0.7.29

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 (136) hide show
  1. package/README.md +41 -29
  2. package/astro.config.mjs +33 -3
  3. package/bin/norna-cli.mjs +5 -3
  4. package/package.json +18 -12
  5. package/schemas/card-list.schema.json +1 -1
  6. package/schemas/config.schema.json +81 -66
  7. package/schemas/content-frontmatter.schema.json +23 -7
  8. package/schemas/manifest.json +49 -3
  9. package/schemas/page-theme.schema.json +1585 -41
  10. package/schemas/root-theme.schema.json +1767 -0
  11. package/schemas/sitewide-content.schema.json +18 -18
  12. package/schemas/theme.schema.json +243 -243
  13. package/scripts/add-site-node.mjs +31 -250
  14. package/scripts/build-site.mjs +11 -6
  15. package/scripts/check-config.mjs +7 -23
  16. package/scripts/dev-local.mjs +51 -17
  17. package/scripts/export-theme-preset.mjs +2 -2
  18. package/scripts/generate-images.mjs +89 -70
  19. package/scripts/generate-schemas.mjs +9 -6
  20. package/scripts/generate-search-index.mjs +3 -2
  21. package/scripts/lib/attachment-render.mjs +23 -0
  22. package/scripts/lib/category-destinations.mjs +13 -12
  23. package/scripts/lib/dev-server-identity.mjs +30 -0
  24. package/scripts/lib/documentation-links.mjs +1 -1
  25. package/scripts/lib/documentation-routes.json +70 -62
  26. package/scripts/lib/docusaurus-migration-audit.mjs +15 -12
  27. package/scripts/lib/editor-attachments.mjs +69 -0
  28. package/scripts/lib/editor-file-policy.mjs +20 -0
  29. package/scripts/lib/editor-language-service.mjs +74 -73
  30. package/scripts/lib/editor-page-addresses.mjs +57 -0
  31. package/scripts/lib/editor-page-placement.mjs +102 -0
  32. package/scripts/lib/editor-resource-actions.mjs +216 -0
  33. package/scripts/lib/editor-site-editing-tree.mjs +181 -0
  34. package/scripts/lib/editor-site-files.mjs +154 -0
  35. package/scripts/lib/editor-site-links.mjs +81 -0
  36. package/scripts/lib/editor-site-preview.mjs +149 -0
  37. package/scripts/lib/editor-site-tree.mjs +158 -0
  38. package/scripts/lib/editor-source-files.mjs +87 -0
  39. package/scripts/lib/editor-theme-help.mjs +43 -0
  40. package/scripts/lib/locale-registry.mjs +1 -1
  41. package/scripts/lib/locales/en.mjs +1 -1
  42. package/scripts/lib/logo-assets.mjs +2 -1
  43. package/scripts/lib/markdown-images.mjs +59 -0
  44. package/scripts/lib/markdown-links.mjs +29 -9
  45. package/scripts/lib/navigation-model.mjs +2 -44
  46. package/scripts/lib/navigation-review.mjs +14 -50
  47. package/scripts/lib/norna-markdown-blocks.mjs +1 -58
  48. package/scripts/lib/norna-markdown-render-plugin.mjs +29 -0
  49. package/scripts/lib/page-aliases.mjs +8 -1
  50. package/scripts/lib/page-attachments.mjs +59 -0
  51. package/scripts/lib/page-markdown.mjs +11 -7
  52. package/scripts/lib/page-model.mjs +19 -36
  53. package/scripts/lib/page-move-apply.mjs +119 -0
  54. package/scripts/lib/page-move-plan.mjs +64 -78
  55. package/scripts/lib/page-order-source.mjs +22 -0
  56. package/scripts/lib/page-order.mjs +45 -0
  57. package/scripts/lib/page-placement-cli.mjs +50 -0
  58. package/scripts/lib/presentation.mjs +3 -3
  59. package/scripts/lib/project-config.mjs +10 -8
  60. package/scripts/lib/publication-paths.mjs +72 -0
  61. package/scripts/lib/schema-definitions.mjs +15 -38
  62. package/scripts/lib/schema-editor-metadata.mjs +16 -60
  63. package/scripts/lib/schema-value-definitions.mjs +1 -1
  64. package/scripts/lib/site-content.mjs +8 -25
  65. package/scripts/lib/site-conventions.mjs +19 -1
  66. package/scripts/lib/site-link-graph.mjs +88 -18
  67. package/scripts/lib/site-navigation-tree.mjs +2 -7
  68. package/scripts/lib/site-node-create.mjs +182 -0
  69. package/scripts/lib/site-paths.mjs +24 -12
  70. package/scripts/lib/site-source-format.mjs +12 -0
  71. package/scripts/lib/site-structure.mjs +86 -95
  72. package/scripts/lib/site-upgrade.mjs +32 -0
  73. package/scripts/lib/social-image-assets.mjs +2 -1
  74. package/scripts/lib/source-files.mjs +34 -0
  75. package/scripts/lib/structured-blocks.mjs +3 -1
  76. package/scripts/lib/theme-config.mjs +26 -68
  77. package/scripts/lib/theme-packages.mjs +47 -0
  78. package/scripts/lib/theme-presets.mjs +20 -53
  79. package/scripts/lib/typography.mjs +2 -2
  80. package/scripts/lib/yaml-config.mjs +1 -1
  81. package/scripts/lib/yaml-source-edit.mjs +94 -0
  82. package/scripts/move-site-page.mjs +46 -254
  83. package/scripts/show-typography.mjs +32 -17
  84. package/scripts/sync-content-sections.mjs +17 -17
  85. package/scripts/sync-site-public.mjs +44 -66
  86. package/scripts/upgrade-site.mjs +17 -0
  87. package/src/components/AreaNavigationMenu.astro +24 -0
  88. package/src/components/AreaNavigationPanel.astro +55 -0
  89. package/src/components/AreaNavigationSwitcher.astro +30 -0
  90. package/src/components/ContentBlocks.astro +2 -1
  91. package/src/components/ImageStack.astro +7 -5
  92. package/src/components/ImageStackEnhancement.astro +0 -7
  93. package/src/components/NavigationContinuity.astro +26 -0
  94. package/src/components/NavigationPageTree.astro +13 -4
  95. package/src/components/NavigationState.astro +11 -0
  96. package/src/components/NavigationTreeControls.astro +3 -2
  97. package/src/components/SearchPage.astro +11 -2
  98. package/src/components/SectionNavigationScript.astro +106 -26
  99. package/src/components/SiteNavigation.astro +45 -20
  100. package/src/components/SitePage.astro +38 -61
  101. package/src/components/SiteSection.astro +1 -0
  102. package/src/components/SiteTreeNavigation.astro +38 -18
  103. package/src/components/TopPageMenu.astro +4 -3
  104. package/src/components/TreeNavigationScript.astro +50 -57
  105. package/src/content.config.ts +11 -12
  106. package/src/layouts/BaseLayout.astro +15 -39
  107. package/src/lib/areaNavigation.ts +42 -0
  108. package/src/lib/imagePresentation.ts +3 -0
  109. package/src/lib/markdownImages.ts +101 -0
  110. package/src/lib/navigationContinuity.ts +212 -0
  111. package/src/lib/navigationFollowing.ts +28 -18
  112. package/src/lib/navigationState.mjs +88 -0
  113. package/src/lib/navigationStateScript.mjs +76 -0
  114. package/src/lib/navigationVisibility.ts +9 -0
  115. package/src/lib/pageThemes.ts +5 -42
  116. package/src/lib/sectionContent.ts +67 -21
  117. package/src/lib/siteNavigation.ts +6 -0
  118. package/src/lib/sitePages.ts +13 -36
  119. package/src/lib/sitePublicAssets.ts +2 -1
  120. package/src/pages/404.astro +1 -1
  121. package/src/pages/[...slug].astro +7 -16
  122. package/src/pages/index.astro +1 -3
  123. package/src/styles/area-navigation.css +408 -0
  124. package/src/styles/content.css +8 -29
  125. package/src/styles/media.css +24 -0
  126. package/src/styles/navigation-continuity.css +163 -0
  127. package/src/styles/page-layout.css +57 -68
  128. package/src/styles/responsive.css +0 -4
  129. package/starters/basic/README.md +9 -8
  130. package/starters/basic/site/{pages/000-home → root}/content.md +2 -2
  131. package/starters/basic/site/{config.yaml → site-config/settings.yaml} +1 -0
  132. package/schemas/category.schema.json +0 -20
  133. package/src/components/PageContentsNavigation.astro +0 -20
  134. /package/starters/basic/site/{pages/000-home → root}/images/.gitkeep +0 -0
  135. /package/starters/basic/site/{theme.yaml → root/tree-theme.yaml} +0 -0
  136. /package/starters/basic/site/{sitewide-content.yaml → site-config/shared-content.yaml} +0 -0
package/README.md CHANGED
@@ -20,7 +20,7 @@ implementing a new presentation layer for every project.
20
20
  [![A multi-page dog shelter site with a logo, navigation between pages, text, a card, and a managed image.](docs/assets/norna-dog-shelter.jpg)](https://janga.github.io/norna/examples/complete-sites/dog-shelter-multi-page/)
21
21
 
22
22
  The screenshot shows the built
23
- [multi-page example source](examples/complete-sites/dog-shelter-multi-page/).
23
+ [multi-page example source](examples/complete-sites/dog-shelter-multi-page).
24
24
 
25
25
  ## Quick Start
26
26
 
@@ -50,39 +50,51 @@ locally installed and pinned Norna version.
50
50
 
51
51
  ```text
52
52
  site/
53
- |-- config.yaml
54
- |-- theme.yaml
55
- |-- sitewide-content.yaml
56
- |-- pages/
57
- | |-- 000-home/
58
- | | |-- content.md
59
- | | `-- images/
60
- | `-- 010-guides/
61
- | |-- category.yaml
62
- | `-- pages/
63
- | `-- 010-installation/
64
- | |-- content.md
65
- | `-- images/
66
- `-- public/
53
+ |-- site-config/
54
+ | |-- settings.yaml
55
+ | `-- shared-content.yaml
56
+ |-- public/
57
+ `-- root/
58
+ |-- content.md # Required homepage
59
+ |-- tree-theme.yaml # Required preset and inherited overrides
60
+ |-- page-theme.yaml # Optional homepage-only overrides
61
+ |-- images/
62
+ `-- pages/
63
+ `-- guide/
64
+ |-- content.md
65
+ |-- tree-theme.yaml # Optional inherited branch overrides
66
+ |-- images/
67
+ `-- pages/
68
+ `-- install/content.md
67
69
  ```
68
70
 
69
- - `pages/000-home/content.md` is the required homepage at `/`.
70
- - Every other ordered directory under `pages/` contains either `content.md` for
71
- a routable page or `category.yaml` for a navigation-only group.
72
- - A page may contain local images. A page or category may contain limited
73
- presentation settings and nested entries under its own `pages/` directory.
74
- - Category ids remain in child URLs. Opening a category URL leads to its first
75
- listed direct page or a generated child list; see
76
- [Category destinations](https://janga.github.io/norna/reference/site/pages/#opening-a-category-url).
77
- - `theme.yaml` normally selects one complete visual preset.
78
- - `sitewide-content.yaml` holds shared logo display settings, banners, and
71
+ - `root/content.md` is the required homepage at `/`; `root/pages/` contains its
72
+ children. The site container holds shared configuration and public files
73
+ beside this root page. `root/` never becomes a URL segment.
74
+ - Every page directory under `pages/` contains `content.md` for a routable
75
+ page. A parent can append a generated list of its direct child pages with
76
+ `page.listChildren: true`; see
77
+ [Child-page lists](https://janga.github.io/norna/reference/site/pages/#list-child-pages).
78
+ - Page directories use their URL slug. Set optional `navigation.order` in each
79
+ page’s frontmatter to order siblings; reordering keeps their paths unchanged.
80
+ New sites declare `sourceFormat: 2` in `site-config/settings.yaml`.
81
+ - A page may contain local images, visual settings and nested
82
+ entries under its own `pages/` directory.
83
+ - `root/tree-theme.yaml` selects shared visual defaults. Optional `page-theme.yaml`
84
+ overrides its page alone; a child's `tree-theme.yaml` is inherited further.
85
+ The root requires `preset`; elsewhere it is optional and explicitly replaces
86
+ the inherited base. Without it, only supplied fields change.
87
+ - `site-config/shared-content.yaml` holds shared logo display settings, banners, and
79
88
  footer content.
80
- - `config.yaml` holds the public URL and optional language, local and remote
89
+ - `site-config/settings.yaml` holds the public URL and optional language, local and remote
81
90
  source links, navigation model, static search, and scroll behavior.
82
- - `public/` holds static files copied without processing.
91
+ - `public/` holds supported technical files and named site artwork (logo, icons and sharing image). Content images and documents belong in each page's `images/` and `downloads/`.
83
92
 
84
93
  Norna validates this structure, processes managed images when needed, and
85
- builds the generated website into `dist/`.
94
+ builds the generated website into `dist/`. Sites using an earlier layout need
95
+ manual [source conversion](https://janga.github.io/norna/reference/site/files/#convert-the-former-homepage-folder).
96
+ `norna site:upgrade` checks the layout and reports former locations without
97
+ moving or overwriting source files.
86
98
 
87
99
  ## Why Norna?
88
100
 
@@ -152,7 +164,7 @@ Engine contributors should start with
152
164
  [Engine Development](docs/engine-development.md). Planning and future work are
153
165
  tracked in [BACKLOG.md](BACKLOG.md).
154
166
 
155
- The user reference is authored once under `site/pages/032-reference/` and
167
+ The user reference is authored once under `site/root/pages/reference/` and
156
168
  rendered on the documentation site. It describes current development; use the
157
169
  installed release's Git tag when checking older behavior. Tags through 0.7.26
158
170
  keep their reference under `docs/`; later tags use the documentation page tree.
package/astro.config.mjs CHANGED
@@ -1,3 +1,6 @@
1
+ import { compiledOutputDirectory } from './scripts/lib/publication-paths.mjs';
2
+ import { devServerIdentityPlugin } from './scripts/lib/dev-server-identity.mjs';
3
+ import { rewriteAttachmentLinks } from './scripts/lib/attachment-render.mjs';
1
4
  // @ts-check
2
5
  import { execFile } from 'node:child_process';
3
6
  import path from 'node:path';
@@ -16,7 +19,11 @@ import {
16
19
  astroPublicDir,
17
20
  engineRoot,
18
21
  generatedImagesManifestPath,
22
+ siteDir,
23
+ sitePublicDir,
24
+ siteConfigPath,
19
25
  siteContentPath,
26
+ siteHomePageDir,
20
27
  siteImagesDir,
21
28
  siteProjectRoot,
22
29
  sitePagesDir,
@@ -72,7 +79,12 @@ const nornaGeneratedImagesWatcher = () => ({
72
79
  const manifestPath = path.resolve(generatedImagesManifestPath);
73
80
  const watchedSourcePaths = [
74
81
  siteContentPath,
82
+ sitePublicDir,
83
+ siteConfigPath,
84
+ path.join(siteHomePageDir, 'tree-theme.yaml'),
85
+ path.join(siteHomePageDir, 'page-theme.yaml'),
75
86
  siteImagesDir,
87
+ path.join(siteHomePageDir, 'downloads'),
76
88
  sitePagesDir,
77
89
  ].map((watchedPath) => path.resolve(watchedPath));
78
90
  let refreshTimer;
@@ -92,6 +104,7 @@ const nornaGeneratedImagesWatcher = () => ({
92
104
  .then(async () => {
93
105
  try {
94
106
  await runGenerateImages();
107
+ await execFileAsync(process.execPath, [path.join(engineRoot, 'scripts', 'sync-site-public.mjs')], { cwd: siteProjectRoot });
95
108
  } catch (error) {
96
109
  const message = error instanceof Error ? error.message : String(error);
97
110
  server.config.logger.error(`Norna image refresh failed:\n${message}`);
@@ -109,7 +122,7 @@ const nornaGeneratedImagesWatcher = () => ({
109
122
  const scheduleStructureReload = (changedPath) => {
110
123
  if (!isRelevantSourcePath(changedPath)) return;
111
124
  const filename = path.basename(changedPath);
112
- if (filename !== 'category.yaml' && filename !== 'theme.yaml') return;
125
+ if (!['tree-theme.yaml', 'page-theme.yaml'].includes(filename)) return;
113
126
 
114
127
  clearTimeout(structureReloadTimer);
115
128
  structureReloadTimer = setTimeout(() => {
@@ -150,7 +163,8 @@ markdownProcessor.createRenderer = async (shared) => {
150
163
  const renderer = await createMarkdownRenderer(shared);
151
164
  return {
152
165
  ...renderer,
153
- render(source, options) {
166
+ async render(source, options) {
167
+ source = await rewriteAttachmentLinks(source, options?.fileURL, siteDir);
154
168
  return renderer.render(prepareContentTabs(source, {
155
169
  label: options?.fileURL?.pathname ?? 'Markdown',
156
170
  }), options);
@@ -161,7 +175,23 @@ markdownProcessor.createRenderer = async (shared) => {
161
175
  // https://astro.build/config
162
176
  export default defineConfig({
163
177
  base: projectConfig.site.basePath,
178
+ build: { assets: compiledOutputDirectory },
164
179
  cacheDir: astroCacheDir,
180
+ prefetch: { prefetchAll: false, defaultStrategy: 'hover' },
181
+ integrations: [{
182
+ name: 'norna-navigation-continuity',
183
+ hooks: {
184
+ 'astro:config:setup': ({ injectScript }) => {
185
+ injectScript('page', `
186
+ import { prefetch } from 'astro:prefetch';
187
+ import { setupNavigationContinuity } from ${JSON.stringify(path.join(engineRoot, 'src/lib/navigationContinuity.ts'))};
188
+ if (document.documentElement.hasAttribute('data-navigation-continuity')) {
189
+ setupNavigationContinuity(prefetch);
190
+ }
191
+ `);
192
+ },
193
+ },
194
+ }],
165
195
  markdown: {
166
196
  shikiConfig: {
167
197
  transformers: [nornaCodeFenceTransformer],
@@ -175,6 +205,6 @@ export default defineConfig({
175
205
  server: {
176
206
  strictPort: true,
177
207
  },
178
- plugins: [nornaBasePathRedirect(), nornaGeneratedImagesWatcher()],
208
+ plugins: [nornaBasePathRedirect(), devServerIdentityPlugin(siteDir), nornaGeneratedImagesWatcher()],
179
209
  },
180
210
  });
package/bin/norna-cli.mjs CHANGED
@@ -15,7 +15,7 @@ Commands:
15
15
  dev:logs Show local dev server logs
16
16
  dev:stop Stop local dev server
17
17
  check Validate configuration and content
18
- config:check Validate site/config.yaml
18
+ config:check Validate site/site-config/settings.yaml
19
19
  content:check Validate page content and managed image references
20
20
  content:sync Move misplaced Norna-managed images and refresh generated images
21
21
  navigation:review Review the derived navigation structure without changing files
@@ -24,13 +24,13 @@ Commands:
24
24
  typography profiles Show built-in typography profile values
25
25
  typography show Show resolved typography for the selected site
26
26
  site:public Sync static files to the selected site's .norna/public/
27
+ site:upgrade Convert former configuration and homepage locations
27
28
  images Generate optimized image variants
28
29
  engine:update Update @janga/norna in a site repository
29
30
  engine:version Show installed engine and Astro versions
30
31
  init Create a new site project from the starter
31
32
  page:add Add a page to the site page tree
32
33
  page:move Move a page subtree and update internal links
33
- category:add Add a navigation group without an authored page body
34
34
  migrate:check Audit a Docusaurus project without modifying it
35
35
  build Build the selected site
36
36
  build:local Build and restart local dev server
@@ -169,6 +169,8 @@ try {
169
169
  throw new Error(`Unknown typography command: ${subcommand ?? ''}\n${usage}`);
170
170
  } else if (command === 'site:public') {
171
171
  await runScript('scripts/sync-site-public.mjs', rest);
172
+ } else if (command === 'site:upgrade') {
173
+ await runScript('scripts/upgrade-site.mjs', rest);
172
174
  } else if (command === 'images') {
173
175
  await runScript('scripts/generate-images.mjs', rest);
174
176
  } else if (command === 'engine:update') {
@@ -182,7 +184,7 @@ try {
182
184
  } else if (command === 'page:move') {
183
185
  await runScript('scripts/move-site-page.mjs', rest);
184
186
  } else if (command === 'category:add') {
185
- await runScript('scripts/add-site-node.mjs', ['category', ...rest]);
187
+ throw new Error('category:add is no longer supported. Use page:add, then set page.listChildren: true in its content.md to list direct children.');
186
188
  } else if (command === 'build') {
187
189
  await runBuild();
188
190
  } else if (command === 'build:local') {
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@janga/norna",
3
3
  "description": "An opinionated CLI for building responsive websites from Markdown, images, and theme presets.",
4
4
  "type": "module",
5
- "version": "0.7.27",
5
+ "version": "0.7.29",
6
6
  "license": "GPL-3.0-only",
7
7
  "repository": {
8
8
  "type": "git",
@@ -56,6 +56,7 @@
56
56
  "scripts/sync-content-sections.mjs",
57
57
  "scripts/sync-site-public.mjs",
58
58
  "scripts/update-engine.mjs",
59
+ "scripts/upgrade-site.mjs",
59
60
  "scripts/watch-pages-deploy.mjs",
60
61
  "README.md"
61
62
  ],
@@ -100,19 +101,20 @@
100
101
  "deploy:watch": "node bin/norna.mjs deploy:watch",
101
102
  "doctor": "node bin/norna.mjs doctor",
102
103
  "demo:build": "node scripts/build-demo.mjs",
103
- "test": "npm run schemas:check && npm run test:dead-code && npm run test:schemas && npm run test:page-model && npm run test:page-markdown && npm run test:migration-check && npm run test:site-links && npm run test:page-aliases && npm run test:sitemap && npm run test:not-found-page && npm run test:site-node-commands && npm run test:page-move && npm run test:navigation-review && npm run test:nested-pages && npm run test:heading-ids && npm run test:navigation-model && npm run test:project-config && npm run test:locales && npm run test:edit-source-link && npm run test:static-search && npm run test:editor-language && npm run test:content-check && npm run test:content-sync-plan && npm run test:content-model && npm run test:theme-presets && npm run test:presentation-contract && npm run test:presentation-review && npm run test:preset-baselines && npm run test:documentation-preset-review && npm run test:site-public && npm run test:cli-discovery && npm run test:dev-local && npm run test:review-environments && npm run test:engine-commands && npm run test:documentation && npm run test:ci-lockfile && npm run test:banner-visibility && npm run test:client-javascript && npm run test:table-sorting && npm run test:fixture:build && npm run test:examples && npm run package:check",
104
+ "test": "npm run schemas:check && npm run test:dead-code && npm run test:schemas && npm run test:page-model && npm run test:site-upgrade && npm run test:page-markdown && npm run test:migration-check && npm run test:site-links && npm run test:page-aliases && npm run test:sitemap && npm run test:not-found-page && npm run test:site-node-commands && npm run test:page-move && npm run test:navigation-review && npm run test:nested-pages && npm run test:heading-ids && npm run test:navigation-model && npm run test:project-config && npm run test:locales && npm run test:edit-source-link && npm run test:static-search && npm run test:editor-language && npm run test:content-check && npm run test:content-sync-plan && npm run test:content-model && npm run test:theme-inheritance && npm run test:theme-presets && npm run test:presentation-contract && npm run test:presentation-review && npm run test:preset-baselines && npm run test:documentation-preset-review && npm run test:site-public && npm run test:cli-discovery && npm run test:dev-local && npm run test:review-environments && npm run test:engine-commands && npm run test:documentation && npm run test:ci-lockfile && npm run test:banner-visibility && npm run test:client-javascript && npm run test:browser-test-server && npm run test:table-sorting && npm run test:fixture:build && npm run test:examples && npm run package:check",
104
105
  "test:fixture:build": "node scripts/test-basic-fixture-build.mjs",
105
106
  "test:examples": "node scripts/test-examples.mjs",
106
107
  "test:examples:browser": "node scripts/test-navigation.mjs --site-dir site tests/examples-gallery.spec.ts",
107
- "test:page-model": "node scripts/test-page-model.mjs",
108
+ "test:page-model": "node scripts/test-page-model.mjs && node --test scripts/test-page-order.mjs scripts/test-page-order-integration.mjs",
109
+ "test:site-upgrade": "node scripts/test-site-upgrade.mjs",
108
110
  "test:page-markdown": "node scripts/test-page-markdown.mjs && node scripts/test-structured-blocks.mjs && node scripts/test-named-notes.mjs && node scripts/test-content-tabs.mjs",
109
111
  "test:tabs:browser": "node scripts/test-navigation.mjs --site-dir fixtures/content-tabs/site tests/content-tabs.spec.ts",
110
- "test:site-links": "node scripts/test-site-link-graph.mjs",
112
+ "test:site-links": "node scripts/test-site-link-graph.mjs && node --test scripts/test-page-attachments.mjs",
111
113
  "test:page-aliases": "node scripts/test-page-aliases.mjs",
112
114
  "test:sitemap": "node scripts/test-sitemap.mjs",
113
115
  "test:not-found-page": "node scripts/test-not-found-page.mjs",
114
116
  "test:site-node-commands": "node scripts/test-site-node-commands.mjs",
115
- "test:page-move": "node scripts/test-page-move.mjs",
117
+ "test:page-move": "node scripts/test-page-move.mjs && node --test scripts/test-editor-page-placement.mjs",
116
118
  "test:navigation-review": "node scripts/test-navigation-review.mjs",
117
119
  "test:nested-pages": "node scripts/test-nested-pages.mjs && node scripts/test-top-navigation-contract.mjs",
118
120
  "test:heading-ids": "node scripts/test-heading-ids.mjs",
@@ -127,14 +129,16 @@
127
129
  "test:content-sync-plan": "node scripts/test-content-sync-plan.mjs",
128
130
  "test:content-model": "npm run test:page-content && npm run test:managed-media && npm run test:content-sync && npm run test:markdown-constructs",
129
131
  "test:page-content": "node scripts/test-page-content.mjs",
130
- "test:managed-media": "node scripts/test-managed-media.mjs",
132
+ "test:managed-media": "node scripts/test-managed-media.mjs && node scripts/test-markdown-images.mjs",
133
+ "test:markdown-images:browser": "node scripts/test-navigation.mjs --site-dir fixtures/markdown-images/site tests/markdown-images.spec.ts",
131
134
  "test:content-sync": "node scripts/test-content-sync.mjs",
132
- "test:markdown-constructs": "node scripts/test-markdown-constructs.mjs",
135
+ "test:markdown-constructs": "node scripts/test-markdown-constructs.mjs && node scripts/test-standard-markdown-compatibility.mjs",
133
136
  "test:theme-presets": "node scripts/test-theme-presets.mjs",
134
137
  "test:presentation-contract": "node scripts/test-presentation-contract.mjs",
135
138
  "test:presentation-review": "node scripts/test-presentation-review-fixture.mjs",
136
139
  "test:presentation:browser": "node scripts/test-navigation.mjs --site-dir fixtures/preset-baseline/site tests/presentation-contract.spec.ts",
137
140
  "test:table-layout:top": "node scripts/test-navigation.mjs --site-dir fixtures/top-navigation/site tests/table-width-top.spec.ts",
141
+ "test:browser-test-server": "node scripts/test-browser-test-server.mjs",
138
142
  "test:table-sorting": "node scripts/test-navigation.mjs --site-dir fixtures/table-sorting/site tests/table-sorting.spec.ts",
139
143
  "test:table-context:browser": "node scripts/test-navigation.mjs --site-dir fixtures/presentation-review/site tests/table-responsive-context.spec.ts",
140
144
  "test:navigation-surfaces:browser": "npm run test:navigation-surfaces:top && npm run test:navigation-surfaces:tree",
@@ -147,13 +151,14 @@
147
151
  "preset:documentation:review:build": "node scripts/review-documentation-preset.mjs --build-only",
148
152
  "palette:review": "node scripts/review-documentation-preset.mjs --palettes",
149
153
  "palette:review:build": "node scripts/review-documentation-preset.mjs --palettes --build-only",
150
- "test:site-public": "node scripts/test-site-public.mjs",
154
+ "test:site-public": "node scripts/test-site-public.mjs && node --test scripts/test-publication-paths.mjs",
151
155
  "test:cli-discovery": "node scripts/test-cli-discovery.mjs",
152
- "test:dev-local": "node scripts/test-dev-local.mjs",
156
+ "test:dev-local": "node scripts/test-dev-local.mjs && npm run test:editor-preview",
157
+ "test:editor-preview": "node --test scripts/test-editor-site-preview.mjs && node --test editors/vscode/test/site-preview-actions-contract.mjs",
153
158
  "test:review-environments": "node scripts/test-review-environments.mjs",
154
159
  "test:review-environments:browser": "node scripts/test-review-environments-browser.mjs",
155
160
  "test:engine-commands": "node scripts/test-engine-commands.mjs",
156
- "test:editor-language": "node scripts/test-editor-language-service.mjs && npm --prefix editors/vscode run check",
161
+ "test:editor-language": "node scripts/test-editor-language-service.mjs && node --test scripts/test-editor-resource-actions.mjs && npm --prefix editors/vscode run check",
157
162
  "test:editor-integration": "npm --prefix editors/vscode run test:integration",
158
163
  "test:editor-integration:minimum": "npm --prefix editors/vscode run test:integration:minimum",
159
164
  "test:documentation": "node scripts/test-documentation.mjs",
@@ -173,7 +178,8 @@
173
178
  "release:minor": "node scripts/release.mjs minor",
174
179
  "release:major": "node scripts/release.mjs major",
175
180
  "preview": "node bin/norna.mjs preview",
176
- "astro": "node bin/norna.mjs astro"
181
+ "astro": "node bin/norna.mjs astro",
182
+ "test:theme-inheritance": "node scripts/test-theme-inheritance.mjs"
177
183
  },
178
184
  "dependencies": {
179
185
  "@astrojs/markdown-satteri": "0.3.4",
@@ -187,7 +193,7 @@
187
193
  "yaml": "2.9.0"
188
194
  },
189
195
  "devDependencies": {
190
- "@playwright/test": "^1.61.1",
196
+ "@playwright/test": "^1.63.0",
191
197
  "knip": "6.33.0"
192
198
  }
193
199
  }
@@ -45,7 +45,7 @@
45
45
  },
46
46
  "width": {
47
47
  "type": "string",
48
- "description": "Override the root theme's maximum width for this card list.",
48
+ "description": "Override the shared theme's maximum width for this card list.",
49
49
  "enum": [
50
50
  "text",
51
51
  "narrow",