@janga/norna 0.7.1 → 0.7.3
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 +32 -18
- package/astro.config.mjs +2 -0
- package/bin/norna-cli.mjs +175 -0
- package/bin/norna.mjs +149 -150
- package/docs/README.md +41 -22
- package/docs/commands.md +25 -12
- package/docs/configuration.md +38 -135
- package/docs/content.md +108 -265
- package/docs/{command-organization.md → design/command-organization.md} +64 -60
- package/docs/{site-examples-structure-note.md → design/site-examples-structure.md} +19 -24
- package/docs/engine-development.md +35 -7
- package/docs/getting-started.md +55 -26
- package/docs/images-and-metadata.md +1 -1
- package/docs/local-development.md +14 -1
- package/docs/publishing.md +24 -1
- package/docs/routes.md +90 -0
- package/docs/site-structure.md +18 -10
- package/docs/theme.md +292 -0
- package/docs/typography.md +144 -0
- package/examples/dog-gallery/.astro/collections/site.schema.json +802 -0
- package/examples/dog-gallery/.astro/collections/theme.schema.json +714 -0
- package/examples/dog-gallery/.astro/content-assets.mjs +4 -0
- package/examples/dog-gallery/.astro/content-modules.mjs +1 -0
- package/examples/dog-gallery/.astro/content.d.ts +175 -0
- package/examples/dog-gallery/.astro/data-store.json +1 -0
- package/examples/dog-gallery/.astro/dev-local.json +8 -0
- package/examples/dog-gallery/.astro/dev.json +13 -0
- package/examples/dog-gallery/.astro/dev.log +49 -0
- package/examples/dog-gallery/.astro/settings.json +5 -0
- package/examples/dog-gallery/.astro/types.d.ts +2 -0
- package/examples/dog-gallery/dist/_astro/GalleryGrid.astro_astro_type_script_index_0_lang.B0kxDyGz.js +1 -0
- package/examples/dog-gallery/dist/_astro/SitePage.BFHZm5UG.css +1 -0
- package/examples/dog-gallery/dist/dog-care/index.html +15 -0
- package/examples/dog-gallery/dist/favicon.svg +7 -0
- package/examples/dog-gallery/dist/images/generated/black-dogs/black-puppy-meadow-7255e3d9-1080.webp +0 -0
- package/examples/dog-gallery/dist/images/generated/black-dogs/black-puppy-meadow-7255e3d9-1440.webp +0 -0
- package/examples/dog-gallery/dist/images/generated/black-dogs/black-puppy-meadow-7255e3d9-1536.webp +0 -0
- package/examples/dog-gallery/dist/images/generated/black-dogs/black-puppy-meadow-7255e3d9-480.webp +0 -0
- package/examples/dog-gallery/dist/images/generated/black-dogs/black-puppy-meadow-7255e3d9-768.webp +0 -0
- package/examples/dog-gallery/dist/images/generated/black-dogs/photo-of-a-black-dog-5cf614d2-480.webp +0 -0
- package/examples/dog-gallery/dist/images/generated/black-dogs/photo-of-a-black-dog-5cf614d2-768.webp +0 -0
- package/examples/dog-gallery/dist/images/generated/black-dogs/photo-of-a-black-dog-5cf614d2-960.webp +0 -0
- package/examples/dog-gallery/dist/images/generated/brown-dogs/brown-dog-50ef114e-1080.webp +0 -0
- package/examples/dog-gallery/dist/images/generated/brown-dogs/brown-dog-50ef114e-1440.webp +0 -0
- package/examples/dog-gallery/dist/images/generated/brown-dogs/brown-dog-50ef114e-1920.webp +0 -0
- package/examples/dog-gallery/dist/images/generated/brown-dogs/brown-dog-50ef114e-3939.webp +0 -0
- package/examples/dog-gallery/dist/images/generated/brown-dogs/brown-dog-50ef114e-480.webp +0 -0
- package/examples/dog-gallery/dist/images/generated/brown-dogs/brown-dog-50ef114e-768.webp +0 -0
- package/examples/dog-gallery/dist/images/generated/brown-dogs/dog-accompanies-master-7ef804d5-1080.webp +0 -0
- package/examples/dog-gallery/dist/images/generated/brown-dogs/dog-accompanies-master-7ef804d5-1440.webp +0 -0
- package/examples/dog-gallery/dist/images/generated/brown-dogs/dog-accompanies-master-7ef804d5-1920.webp +0 -0
- package/examples/dog-gallery/dist/images/generated/brown-dogs/dog-accompanies-master-7ef804d5-2400.webp +0 -0
- package/examples/dog-gallery/dist/images/generated/brown-dogs/dog-accompanies-master-7ef804d5-480.webp +0 -0
- package/examples/dog-gallery/dist/images/generated/brown-dogs/dog-accompanies-master-7ef804d5-768.webp +0 -0
- package/examples/dog-gallery/dist/images/generated/golden-dogs/golden-retriever-f797fd88-1080.webp +0 -0
- package/examples/dog-gallery/dist/images/generated/golden-dogs/golden-retriever-f797fd88-1440.webp +0 -0
- package/examples/dog-gallery/dist/images/generated/golden-dogs/golden-retriever-f797fd88-1600.webp +0 -0
- package/examples/dog-gallery/dist/images/generated/golden-dogs/golden-retriever-f797fd88-480.webp +0 -0
- package/examples/dog-gallery/dist/images/generated/golden-dogs/golden-retriever-f797fd88-768.webp +0 -0
- package/examples/dog-gallery/dist/images/generated/golden-dogs/toller-puppy-a2a8fbc0-1080.webp +0 -0
- package/examples/dog-gallery/dist/images/generated/golden-dogs/toller-puppy-a2a8fbc0-1440.webp +0 -0
- package/examples/dog-gallery/dist/images/generated/golden-dogs/toller-puppy-a2a8fbc0-1920.webp +0 -0
- package/examples/dog-gallery/dist/images/generated/golden-dogs/toller-puppy-a2a8fbc0-2576.webp +0 -0
- package/examples/dog-gallery/dist/images/generated/golden-dogs/toller-puppy-a2a8fbc0-480.webp +0 -0
- package/examples/dog-gallery/dist/images/generated/golden-dogs/toller-puppy-a2a8fbc0-768.webp +0 -0
- package/examples/dog-gallery/dist/images/generated/white-dogs/white-cute-dog-077a0689-1080.webp +0 -0
- package/examples/dog-gallery/dist/images/generated/white-dogs/white-cute-dog-077a0689-1277.webp +0 -0
- package/examples/dog-gallery/dist/images/generated/white-dogs/white-cute-dog-077a0689-480.webp +0 -0
- package/examples/dog-gallery/dist/images/generated/white-dogs/white-cute-dog-077a0689-768.webp +0 -0
- package/examples/dog-gallery/dist/images/generated/white-dogs/white-puppy-garden-d3ab2ca0-1080.webp +0 -0
- package/examples/dog-gallery/dist/images/generated/white-dogs/white-puppy-garden-d3ab2ca0-1440.webp +0 -0
- package/examples/dog-gallery/dist/images/generated/white-dogs/white-puppy-garden-d3ab2ca0-1536.webp +0 -0
- package/examples/dog-gallery/dist/images/generated/white-dogs/white-puppy-garden-d3ab2ca0-480.webp +0 -0
- package/examples/dog-gallery/dist/images/generated/white-dogs/white-puppy-garden-d3ab2ca0-768.webp +0 -0
- package/examples/dog-gallery/dist/index.html +43 -0
- package/examples/dog-gallery/dist/robots.txt +2 -0
- package/examples/dog-gallery/node_modules/.vite/deps/_metadata.json +74 -0
- package/examples/dog-gallery/node_modules/.vite/deps/astro-D_GIpJIE.js +434 -0
- package/examples/dog-gallery/node_modules/.vite/deps/astro-D_GIpJIE.js.map +1 -0
- package/examples/dog-gallery/node_modules/.vite/deps/astro_n_aria-query.js +6390 -0
- package/examples/dog-gallery/node_modules/.vite/deps/astro_n_aria-query.js.map +1 -0
- package/examples/dog-gallery/node_modules/.vite/deps/astro_n_axobject-query.js +2702 -0
- package/examples/dog-gallery/node_modules/.vite/deps/astro_n_axobject-query.js.map +1 -0
- package/examples/dog-gallery/node_modules/.vite/deps/astro_n_html-escaper.js +65 -0
- package/examples/dog-gallery/node_modules/.vite/deps/astro_n_html-escaper.js.map +1 -0
- package/examples/dog-gallery/node_modules/.vite/deps/astro_runtime_client_dev-toolbar_entrypoint__js.js +455 -0
- package/examples/dog-gallery/node_modules/.vite/deps/astro_runtime_client_dev-toolbar_entrypoint__js.js.map +1 -0
- package/examples/dog-gallery/node_modules/.vite/deps/audit-DM9Hkl5B.js +1534 -0
- package/examples/dog-gallery/node_modules/.vite/deps/audit-DM9Hkl5B.js.map +1 -0
- package/examples/dog-gallery/node_modules/.vite/deps/highlight-DnZ1ULOL.js +48 -0
- package/examples/dog-gallery/node_modules/.vite/deps/highlight-DnZ1ULOL.js.map +1 -0
- package/examples/dog-gallery/node_modules/.vite/deps/icons-RyebKi45.js +42 -0
- package/examples/dog-gallery/node_modules/.vite/deps/icons-RyebKi45.js.map +1 -0
- package/examples/dog-gallery/node_modules/.vite/deps/package.json +3 -0
- package/examples/dog-gallery/node_modules/.vite/deps/rolldown-runtime-BvCyGRYZ.js +4 -0
- package/examples/dog-gallery/node_modules/.vite/deps/settings-DaU-gNnK.js +190 -0
- package/examples/dog-gallery/node_modules/.vite/deps/settings-DaU-gNnK.js.map +1 -0
- package/examples/dog-gallery/node_modules/.vite/deps/toolbar-63PA619H.js +458 -0
- package/examples/dog-gallery/node_modules/.vite/deps/toolbar-63PA619H.js.map +1 -0
- package/examples/dog-gallery/node_modules/.vite/deps/ui-library--bkcNSYz.js +1016 -0
- package/examples/dog-gallery/node_modules/.vite/deps/ui-library--bkcNSYz.js.map +1 -0
- package/examples/dog-gallery/node_modules/.vite/deps/window-jPkpKVcy.js +32 -0
- package/examples/dog-gallery/node_modules/.vite/deps/window-jPkpKVcy.js.map +1 -0
- package/examples/dog-gallery/node_modules/.vite/deps/xray-BXCHpEJP.js +111 -0
- package/examples/dog-gallery/node_modules/.vite/deps/xray-BXCHpEJP.js.map +1 -0
- package/examples/dog-gallery/site/.norna/generated-images.json +226 -0
- package/examples/dog-gallery/site/config.mjs +67 -0
- package/examples/dog-gallery/site/content.md +168 -0
- package/examples/dog-gallery/site/images/black-dogs/black-puppy-meadow.png +0 -0
- package/examples/dog-gallery/site/images/black-dogs/photo-of-a-black-dog.jpg +0 -0
- package/examples/dog-gallery/site/images/brown-dogs/brown-dog.jpg +0 -0
- package/examples/dog-gallery/site/images/brown-dogs/dog-accompanies-master.jpg +0 -0
- package/examples/dog-gallery/site/images/golden-dogs/golden-retriever.jpg +0 -0
- package/examples/dog-gallery/site/images/golden-dogs/toller-puppy.jpg +0 -0
- package/examples/dog-gallery/site/images/white-dogs/white-cute-dog.jpg +0 -0
- package/examples/dog-gallery/site/images/white-dogs/white-puppy-garden.png +0 -0
- package/examples/dog-gallery/site/public/favicon.svg +7 -0
- package/examples/dog-gallery/site/public/robots.txt +2 -0
- package/examples/dog-gallery/site/routes/dog-care/route-content.md +49 -0
- package/examples/dog-gallery/site/theme.md +114 -0
- package/fixtures/basic/site/config.mjs +3 -22
- package/fixtures/basic/site/content.md +1 -1
- package/fixtures/basic/site/theme.md +7 -3
- package/package.json +10 -9
- package/scripts/check-config.mjs +4 -3
- package/scripts/deploy-site.mjs +3 -3
- package/scripts/dev-local.mjs +64 -15
- package/scripts/init-site.mjs +11 -9
- package/scripts/lib/frontmatter-yaml.mjs +85 -0
- package/scripts/lib/presentation.mjs +10 -11
- package/scripts/lib/project-config.mjs +113 -45
- package/scripts/lib/site-content.mjs +21 -2
- package/scripts/lib/site-paths.mjs +18 -3
- package/scripts/lib/theme-config.mjs +34 -0
- package/scripts/lib/typography.mjs +103 -23
- package/scripts/show-typography.mjs +202 -75
- package/scripts/sync-content-sections.mjs +6 -6
- package/scripts/test-cli-discovery.mjs +124 -0
- package/scripts/test-content-check.mjs +3 -4
- package/scripts/test-engine-commands.mjs +20 -6
- package/scripts/test-navigation.mjs +10 -6
- package/scripts/test-package-check.mjs +40 -11
- package/scripts/test-temporary-visibility.mjs +2 -3
- package/src/components/SiteNavigation.astro +7 -5
- package/src/components/SitePage.astro +5 -3
- package/src/components/SiteSection.astro +63 -29
- package/src/content.config.ts +64 -2
- package/src/layouts/BaseLayout.astro +19 -1
- package/src/lib/basePath.ts +21 -0
- package/src/lib/generatedImages.ts +8 -4
- package/src/lib/sectionContent.ts +6 -1
- package/src/lib/sitePublicAssets.ts +8 -1
- package/src/styles/global.css +59 -55
- package/starters/basic/.github/workflows/deploy.yml +3 -3
- package/starters/basic/README.md +30 -14
- package/starters/basic/package.json +3 -3
- package/starters/basic/site/config.mjs +4 -24
- package/starters/basic/site/content.md +44 -9
- package/starters/basic/site/theme.md +113 -16
- package/starters/project/.github/workflows/deploy.yml +65 -0
- package/starters/project/README.md +72 -0
- package/starters/project/package-lock.json +4296 -0
- package/starters/project/package.json +35 -0
- package/starters/project/site/config.mjs +43 -0
- package/starters/project/site/content.md +88 -0
- package/starters/project/site/public/robots.txt +2 -0
- package/starters/project/site/routes/guide/route-content.md +58 -0
- package/starters/project/site/theme.md +15 -0
package/docs/publishing.md
CHANGED
|
@@ -25,6 +25,29 @@ workflow:
|
|
|
25
25
|
Site-specific static files such as `site/public/CNAME`, `robots.txt`, and
|
|
26
26
|
`sitemap.xml` belong in the site repository.
|
|
27
27
|
|
|
28
|
+
In the GitHub repository settings, set Pages to build from GitHub Actions. For
|
|
29
|
+
a project site without a custom domain, configure the site URL and base path in
|
|
30
|
+
`site/config.mjs`:
|
|
31
|
+
|
|
32
|
+
```js
|
|
33
|
+
site: {
|
|
34
|
+
url: 'https://owner.github.io/repository-name/',
|
|
35
|
+
basePath: '/repository-name/',
|
|
36
|
+
}
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
For a custom domain, keep `basePath` as `/`:
|
|
40
|
+
|
|
41
|
+
```js
|
|
42
|
+
site: {
|
|
43
|
+
url: 'https://example.com/',
|
|
44
|
+
basePath: '/',
|
|
45
|
+
}
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
Norna uses `site.basePath` for generated internal page links, favicons,
|
|
49
|
+
generated images, and root-relative links or images written in Markdown.
|
|
50
|
+
|
|
28
51
|
## Deploy An Already Committed Branch
|
|
29
52
|
|
|
30
53
|
Use:
|
|
@@ -56,7 +79,7 @@ npm run norna:deploy:commit -- "Commit message"
|
|
|
56
79
|
|
|
57
80
|
It builds, stages only allowed site changes, commits, pushes, and checks Pages.
|
|
58
81
|
The allowlist is implemented in `scripts/deploy-site.mjs` and includes the
|
|
59
|
-
site content file, selected config/static files, expected
|
|
82
|
+
site content file, selected config/static files, expected generated images,
|
|
60
83
|
generated image manifest, package files, `tsconfig.json`, `astro.config.mjs`,
|
|
61
84
|
and `src/` changes.
|
|
62
85
|
|
package/docs/routes.md
ADDED
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
# Routes
|
|
2
|
+
|
|
3
|
+
`site/content.md` is the homepage and builds to `/`. Optional route pages live
|
|
4
|
+
under `site/routes/<route-folder>/route-content.md` and build to first-level
|
|
5
|
+
URLs.
|
|
6
|
+
|
|
7
|
+
Routes use the same page frontmatter, section frontmatter, image rows, and
|
|
8
|
+
Markdown section model as the homepage. See [Content](content.md) for the page
|
|
9
|
+
and section model.
|
|
10
|
+
|
|
11
|
+
## Route File
|
|
12
|
+
|
|
13
|
+
Add a first-level route by creating:
|
|
14
|
+
|
|
15
|
+
```text
|
|
16
|
+
site/routes/about/route-content.md
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
Minimal route page:
|
|
20
|
+
|
|
21
|
+
```md
|
|
22
|
+
---
|
|
23
|
+
title: About
|
|
24
|
+
description: About this site.
|
|
25
|
+
navigation:
|
|
26
|
+
label: About
|
|
27
|
+
order: 20
|
|
28
|
+
sections:
|
|
29
|
+
- id: intro
|
|
30
|
+
---
|
|
31
|
+
|
|
32
|
+
## Intro {#intro}
|
|
33
|
+
|
|
34
|
+
Text...
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
The example above builds to `/about/`.
|
|
38
|
+
|
|
39
|
+
## Slug
|
|
40
|
+
|
|
41
|
+
If `slug` is omitted, the route folder name is used. If `slug` is set, it must
|
|
42
|
+
use lowercase letters, numbers, and hyphens.
|
|
43
|
+
|
|
44
|
+
```yaml
|
|
45
|
+
slug: about-the-work
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
Keep the route folder and `slug` aligned unless you intentionally need a
|
|
49
|
+
different URL.
|
|
50
|
+
|
|
51
|
+
The homepage ignores `slug`.
|
|
52
|
+
|
|
53
|
+
## Navigation
|
|
54
|
+
|
|
55
|
+
`navigation` may contain:
|
|
56
|
+
|
|
57
|
+
- `include`: optional boolean. Defaults to `true`.
|
|
58
|
+
- `label`: optional string. Defaults to `title`.
|
|
59
|
+
- `order`: optional integer. Defaults to `0` for the homepage and `100` for
|
|
60
|
+
route pages.
|
|
61
|
+
|
|
62
|
+
Current route navigation is intended for small sites. This guidance may change
|
|
63
|
+
as route support matures, but the present model is:
|
|
64
|
+
|
|
65
|
+
- A single-page site should normally use only page navigation between sections.
|
|
66
|
+
- A small multi-page site may use site navigation between routes plus page
|
|
67
|
+
navigation between sections on the current page.
|
|
68
|
+
- If a site needs many routes, deeply nested routes, or several navigation
|
|
69
|
+
levels, it has probably outgrown the current sticky-navigation model and may
|
|
70
|
+
need a different site structure or navigation system.
|
|
71
|
+
|
|
72
|
+
## Route Images
|
|
73
|
+
|
|
74
|
+
Route images live under the route:
|
|
75
|
+
|
|
76
|
+
```text
|
|
77
|
+
site/routes/about/images/intro/image.jpg
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
Image references in route frontmatter still use only the filename:
|
|
81
|
+
|
|
82
|
+
```yaml
|
|
83
|
+
sections:
|
|
84
|
+
- id: intro
|
|
85
|
+
gallery:
|
|
86
|
+
- image: image.jpg
|
|
87
|
+
alt: "Intro image."
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
The image directory segment after `images/` should match the section id.
|
package/docs/site-structure.md
CHANGED
|
@@ -26,22 +26,26 @@ site/
|
|
|
26
26
|
```
|
|
27
27
|
|
|
28
28
|
Use `NORNA_SITE_DIR` or `norna --site-dir <path>` to select another
|
|
29
|
-
site directory.
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
29
|
+
site directory. Without an explicit site directory, commands first accept the
|
|
30
|
+
current directory when it contains both `config.mjs` and `content.md`.
|
|
31
|
+
Otherwise, commands started from a subdirectory walk upward until they find the
|
|
32
|
+
default `site/` directory containing those files.
|
|
33
|
+
`theme.md` is optional; omit it to use the engine's built-in visual defaults.
|
|
33
34
|
|
|
34
35
|
## Versioned Source Files
|
|
35
36
|
|
|
36
37
|
Version these files in a site repository:
|
|
37
38
|
|
|
38
39
|
- `site/config.mjs`: technical site configuration.
|
|
39
|
-
- `site/theme.md`: optional site-wide visual theme,
|
|
40
|
-
defaults
|
|
40
|
+
- `site/theme.md`: optional site-wide visual theme, including layout, spacing,
|
|
41
|
+
image sizing, font, typography defaults, colors, inline styles, and frame
|
|
42
|
+
colors.
|
|
43
|
+
See [Theme](theme.md).
|
|
41
44
|
- `site/content.md`: homepage page file with editable content, section
|
|
42
|
-
definitions,
|
|
45
|
+
definitions, image rows, alt text, and captions. See [Content](content.md).
|
|
43
46
|
- `site/images/<section-id>/`: original source images.
|
|
44
47
|
- `site/routes/<route-folder>/route-content.md`: optional route page files.
|
|
48
|
+
See [Routes](routes.md).
|
|
45
49
|
- `site/routes/<route-folder>/images/<section-id>/`: original source images
|
|
46
50
|
for that route page.
|
|
47
51
|
- `site/public/`: site-specific static public files.
|
|
@@ -66,16 +70,20 @@ Do not edit these by hand:
|
|
|
66
70
|
|
|
67
71
|
Favicons are convention-based. Put files such as `favicon.svg`, `favicon.ico`,
|
|
68
72
|
`favicon.png`, or `apple-touch-icon.png` in `site/public/`. The renderer emits
|
|
69
|
-
icon links only for files that exist.
|
|
73
|
+
icon links only for files that exist and prefixes them with `site.basePath`
|
|
74
|
+
when the site is published below a path such as `/repository-name/`.
|
|
70
75
|
|
|
71
76
|
## Engine Repository Layout
|
|
72
77
|
|
|
73
78
|
In this repository:
|
|
74
79
|
|
|
75
|
-
- `bin/norna.mjs`
|
|
80
|
+
- `bin/norna.mjs` launches the appropriate installed Norna version.
|
|
81
|
+
- `bin/norna-cli.mjs` dispatches public CLI commands.
|
|
76
82
|
- `scripts/` contains validation, image, local preview, deploy, and test tools.
|
|
77
83
|
- `src/` contains the Astro renderer, components, styles, and content schema.
|
|
78
84
|
- `starters/basic/` is copied by `norna init <target-dir>` to create a
|
|
79
85
|
site repository.
|
|
80
86
|
- `fixtures/basic/site/` is used by engine regression tests.
|
|
81
|
-
- `site/` is the local dog
|
|
87
|
+
- `examples/dog-gallery/site/` is the local visual dog example used by demo
|
|
88
|
+
builds and navigation diagnostics.
|
|
89
|
+
- `site/` is reserved for the local documentation site.
|
package/docs/theme.md
ADDED
|
@@ -0,0 +1,292 @@
|
|
|
1
|
+
# Theme
|
|
2
|
+
|
|
3
|
+
`site/theme.md` defines optional site-wide visual defaults for a `norna` site.
|
|
4
|
+
It uses YAML frontmatter and does not need a Markdown body. If the file is
|
|
5
|
+
missing, built-in engine defaults are used.
|
|
6
|
+
|
|
7
|
+
Page-level presentation in `site/content.md` and route page files is always an
|
|
8
|
+
override on top of `site/theme.md`. Section-level presentation is an override
|
|
9
|
+
on top of the resolved page presentation.
|
|
10
|
+
|
|
11
|
+
## Minimal Theme
|
|
12
|
+
|
|
13
|
+
```yaml
|
|
14
|
+
---
|
|
15
|
+
navigation:
|
|
16
|
+
brand: Example Site
|
|
17
|
+
layout:
|
|
18
|
+
pageWidth: 1180px
|
|
19
|
+
gutter:
|
|
20
|
+
desktop: clamp(1.25rem, 4vw, 3rem)
|
|
21
|
+
mobile: 1rem
|
|
22
|
+
spacing:
|
|
23
|
+
firstSectionTop:
|
|
24
|
+
desktop: clamp(1.875rem, 3vw, 2.75rem)
|
|
25
|
+
mobile: 1.375rem
|
|
26
|
+
sectionGap:
|
|
27
|
+
desktop: clamp(2.55rem, 4.2vw, 3.9rem)
|
|
28
|
+
mobile: 2.25rem
|
|
29
|
+
finalSectionBottom:
|
|
30
|
+
desktop: clamp(2.55rem, 4.2vw, 3.9rem)
|
|
31
|
+
mobile: 2.25rem
|
|
32
|
+
sectionHeadingToBody:
|
|
33
|
+
desktop: clamp(0.5625rem, 1.25vw, 0.75rem)
|
|
34
|
+
mobile: 0.4375rem
|
|
35
|
+
bodyToImages:
|
|
36
|
+
desktop: clamp(1.25rem, 2.5vw, 2rem)
|
|
37
|
+
mobile: 1.25rem
|
|
38
|
+
imageGap:
|
|
39
|
+
desktop: clamp(1.5rem, 3.5vw, 2.75rem)
|
|
40
|
+
mobile: 2.75rem
|
|
41
|
+
subheadingTop:
|
|
42
|
+
desktop: 2rem
|
|
43
|
+
mobile: 1.6rem
|
|
44
|
+
subheadingRuleTop:
|
|
45
|
+
desktop: 1rem
|
|
46
|
+
mobile: 0.8rem
|
|
47
|
+
gallery:
|
|
48
|
+
width: 900px
|
|
49
|
+
maxAvailableWidthPercent:
|
|
50
|
+
desktop: 100
|
|
51
|
+
mobile: 100
|
|
52
|
+
maxAvailableHeightPercent:
|
|
53
|
+
desktop: 74
|
|
54
|
+
mobile: 68
|
|
55
|
+
typography:
|
|
56
|
+
fontFamily: "Arial, 'Helvetica Neue', Helvetica, sans-serif"
|
|
57
|
+
preset: quiet-gallery
|
|
58
|
+
presentation:
|
|
59
|
+
backgroundColor: "#000000"
|
|
60
|
+
textColor: "#f7f4ee"
|
|
61
|
+
frame:
|
|
62
|
+
colors: presentation
|
|
63
|
+
---
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
Starter sites include a marked comment block such as
|
|
67
|
+
`norna:start theme-help` / `norna:end theme-help`. The block is only
|
|
68
|
+
explorable help text; YAML comments do not affect rendering. The active
|
|
69
|
+
configuration is the uncommented YAML below it.
|
|
70
|
+
|
|
71
|
+
## Navigation
|
|
72
|
+
|
|
73
|
+
`navigation` is optional. It currently supports:
|
|
74
|
+
|
|
75
|
+
- `brand`: optional site-wide brand or home-link text shown in the site
|
|
76
|
+
navigation.
|
|
77
|
+
|
|
78
|
+
If `navigation.brand` is omitted, Norna uses the homepage `title` from
|
|
79
|
+
`site/content.md`. Use `navigation.brand` when the homepage title is editorial
|
|
80
|
+
or route-specific, but the navigation should keep a stable site name.
|
|
81
|
+
|
|
82
|
+
Example:
|
|
83
|
+
|
|
84
|
+
```yaml
|
|
85
|
+
navigation:
|
|
86
|
+
brand: Norna
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
## Layout
|
|
90
|
+
|
|
91
|
+
`layout` is optional. It controls the outer page geometry:
|
|
92
|
+
|
|
93
|
+
- `pageWidth`: maximum width of the main page content area.
|
|
94
|
+
- `gutter`: side margin removed from the viewport before available content
|
|
95
|
+
width is calculated. Use either one CSS length for all viewports or
|
|
96
|
+
`desktop` / `mobile` values.
|
|
97
|
+
- `spacing`: vertical rhythm for sections, text, image rows, and Markdown
|
|
98
|
+
subheadings. Every spacing value accepts either one CSS length for all
|
|
99
|
+
viewports or `desktop` / `mobile` values.
|
|
100
|
+
|
|
101
|
+
Example:
|
|
102
|
+
|
|
103
|
+
```yaml
|
|
104
|
+
layout:
|
|
105
|
+
pageWidth: 1180px
|
|
106
|
+
gutter:
|
|
107
|
+
desktop: clamp(1.25rem, 4vw, 3rem)
|
|
108
|
+
mobile: 1rem
|
|
109
|
+
spacing:
|
|
110
|
+
firstSectionTop:
|
|
111
|
+
desktop: clamp(1.875rem, 3vw, 2.75rem)
|
|
112
|
+
mobile: 1.375rem
|
|
113
|
+
sectionGap:
|
|
114
|
+
desktop: clamp(2.55rem, 4.2vw, 3.9rem)
|
|
115
|
+
mobile: 2.25rem
|
|
116
|
+
subheadingTop:
|
|
117
|
+
desktop: 2rem
|
|
118
|
+
mobile: 1.6rem
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
If omitted, Norna uses `1180px` for `pageWidth`, desktop
|
|
122
|
+
`clamp(1.25rem, 4vw, 3rem)` for `gutter`, mobile `1rem`, and the spacing
|
|
123
|
+
defaults shown in the minimal theme example.
|
|
124
|
+
|
|
125
|
+
Spacing keys:
|
|
126
|
+
|
|
127
|
+
- `firstSectionTop`: space above the first section heading.
|
|
128
|
+
- `sectionGap`: space above each following section.
|
|
129
|
+
- `finalSectionBottom`: space below the final section.
|
|
130
|
+
- `sectionHeadingToBody`: space from a section heading to its body text.
|
|
131
|
+
- `bodyToImages`: space from section body text to image rows.
|
|
132
|
+
- `imageGap`: space between image rows.
|
|
133
|
+
- `subheadingTop`: space above Markdown `###` subheadings inside body text.
|
|
134
|
+
- `subheadingRuleTop`: space between the rule above a Markdown `###`
|
|
135
|
+
subheading and the subheading text.
|
|
136
|
+
|
|
137
|
+
## Image Sizing
|
|
138
|
+
|
|
139
|
+
`gallery` is optional. It controls image sizing:
|
|
140
|
+
|
|
141
|
+
- `width`: hard maximum rendered image area width for images, captions, and
|
|
142
|
+
aligned text.
|
|
143
|
+
- `maxAvailableWidthPercent`: maximum share of available width after gutters.
|
|
144
|
+
- `maxAvailableHeightPercent`: maximum share of viewport height used by
|
|
145
|
+
images.
|
|
146
|
+
|
|
147
|
+
Example:
|
|
148
|
+
|
|
149
|
+
```yaml
|
|
150
|
+
gallery:
|
|
151
|
+
width: 900px
|
|
152
|
+
maxAvailableWidthPercent:
|
|
153
|
+
desktop: 100
|
|
154
|
+
mobile: 100
|
|
155
|
+
maxAvailableHeightPercent:
|
|
156
|
+
desktop: 74
|
|
157
|
+
mobile: 68
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
If omitted, Norna uses `900px`, full available width, and image height limits of
|
|
161
|
+
desktop `74` / mobile `68`.
|
|
162
|
+
|
|
163
|
+
## Typography
|
|
164
|
+
|
|
165
|
+
Top-level `typography` is the site-wide typographic base. It supports:
|
|
166
|
+
|
|
167
|
+
- `fontFamily`: global CSS font-family stack.
|
|
168
|
+
- `preset`: built-in typography preset.
|
|
169
|
+
- `overrides`: focused changes to preset values.
|
|
170
|
+
|
|
171
|
+
Example:
|
|
172
|
+
|
|
173
|
+
```yaml
|
|
174
|
+
typography:
|
|
175
|
+
fontFamily: "Arial, 'Helvetica Neue', Helvetica, sans-serif"
|
|
176
|
+
preset: quiet-gallery
|
|
177
|
+
overrides:
|
|
178
|
+
headings:
|
|
179
|
+
h2:
|
|
180
|
+
size: medium
|
|
181
|
+
h3:
|
|
182
|
+
size: small
|
|
183
|
+
body:
|
|
184
|
+
lineHeight: 1.55
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
Use `norna typography presets` to inspect built-in preset values and
|
|
188
|
+
`norna typography show` to inspect the resolved typography for the selected
|
|
189
|
+
site. See [Typography](typography.md).
|
|
190
|
+
|
|
191
|
+
## Presentation
|
|
192
|
+
|
|
193
|
+
`presentation` is optional. It can contain:
|
|
194
|
+
|
|
195
|
+
- `backgroundColor`: optional quoted hex color in `#rgb`, `#rrggbb`, or
|
|
196
|
+
`#rrggbbaa` form.
|
|
197
|
+
- `textColor`: optional quoted hex color in `#rgb`, `#rrggbb`, or
|
|
198
|
+
`#rrggbbaa` form.
|
|
199
|
+
- `inlineStyles`: optional named inline text styles.
|
|
200
|
+
|
|
201
|
+
Example:
|
|
202
|
+
|
|
203
|
+
```yaml
|
|
204
|
+
presentation:
|
|
205
|
+
backgroundColor: "#101418"
|
|
206
|
+
textColor: "#f4f1ea"
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
## Page And Section Overrides
|
|
210
|
+
|
|
211
|
+
Site-wide presentation belongs in `site/theme.md`. Page-level presentation in a
|
|
212
|
+
page file is always an override on top of the theme:
|
|
213
|
+
|
|
214
|
+
```yaml
|
|
215
|
+
presentation:
|
|
216
|
+
typography:
|
|
217
|
+
overrides:
|
|
218
|
+
headings:
|
|
219
|
+
h2:
|
|
220
|
+
size: large
|
|
221
|
+
body:
|
|
222
|
+
paragraphSpacing: 1em
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
Section-specific presentation belongs under `sections[].presentation`:
|
|
226
|
+
|
|
227
|
+
```yaml
|
|
228
|
+
sections:
|
|
229
|
+
- id: intro
|
|
230
|
+
presentation:
|
|
231
|
+
backgroundColor: "#161616"
|
|
232
|
+
textColor: "#ffffff"
|
|
233
|
+
typography:
|
|
234
|
+
preset: statement
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
If a page omits `presentation`, it uses the theme presentation unchanged. If a
|
|
238
|
+
section omits `presentation`, it uses the resolved page presentation.
|
|
239
|
+
|
|
240
|
+
Configured section backgrounds render as full-width horizontal bands while the
|
|
241
|
+
section content keeps the normal page and image widths. The top spacing
|
|
242
|
+
before the first heading, the spacing between sections, and the spacing after
|
|
243
|
+
the final section are part of the section background.
|
|
244
|
+
|
|
245
|
+
Configured section text colors apply to section headings, Markdown text,
|
|
246
|
+
Markdown subheadings, and image captions. Links keep the global accent color.
|
|
247
|
+
|
|
248
|
+
## Frame Colors
|
|
249
|
+
|
|
250
|
+
`frame.colors` controls the sticky navigation and footer colors.
|
|
251
|
+
|
|
252
|
+
Allowed values:
|
|
253
|
+
|
|
254
|
+
- `presentation`: use the resolved presentation colors for this level.
|
|
255
|
+
- `theme`: use the site theme frame colors. This is useful in page-level
|
|
256
|
+
frontmatter.
|
|
257
|
+
- explicit colors:
|
|
258
|
+
|
|
259
|
+
```yaml
|
|
260
|
+
frame:
|
|
261
|
+
colors:
|
|
262
|
+
backgroundColor: "#111111"
|
|
263
|
+
textColor: "#eeeeee"
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
The sticky section navigation row and footer use the resolved frame colors, not
|
|
267
|
+
section-specific presentation.
|
|
268
|
+
|
|
269
|
+
## Inline Styles
|
|
270
|
+
|
|
271
|
+
`presentation.inlineStyles` defines named inline text styles that can be used
|
|
272
|
+
from Markdown:
|
|
273
|
+
|
|
274
|
+
```yaml
|
|
275
|
+
presentation:
|
|
276
|
+
inlineStyles:
|
|
277
|
+
highlight:
|
|
278
|
+
color: "#ffd84d"
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
Inline style names must match `^[a-z][a-z0-9-]*$`. Each style currently
|
|
282
|
+
supports a required `color` field using the same quoted hex color format as
|
|
283
|
+
`textColor`.
|
|
284
|
+
|
|
285
|
+
Apply an inline style in Markdown with `[text]{.style-name}`:
|
|
286
|
+
|
|
287
|
+
```md
|
|
288
|
+
This sentence contains [highlighted text]{.highlight}.
|
|
289
|
+
```
|
|
290
|
+
|
|
291
|
+
`content:check` fails if Markdown uses an inline style that is not defined in
|
|
292
|
+
`site/theme.md` `presentation.inlineStyles`.
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
# Typography
|
|
2
|
+
|
|
3
|
+
`norna` typography is configured in `site/theme.md` through a site-wide font,
|
|
4
|
+
presets, and optional overrides.
|
|
5
|
+
|
|
6
|
+
The normal place to choose a site-wide typography preset is the top-level
|
|
7
|
+
`typography` block in `site/theme.md`.
|
|
8
|
+
Page and section files may override the theme when a page or section needs a
|
|
9
|
+
different presentation.
|
|
10
|
+
|
|
11
|
+
## Presets
|
|
12
|
+
|
|
13
|
+
Available presets:
|
|
14
|
+
|
|
15
|
+
- `quiet-gallery`: the default for image-led sites. Text is restrained and
|
|
16
|
+
supports the images without dominating the page.
|
|
17
|
+
- `compact-gallery`: tighter typography for many sections, many images, or
|
|
18
|
+
short information blocks.
|
|
19
|
+
- `text-forward`: more generous body text for pages where longer text carries
|
|
20
|
+
more of the experience.
|
|
21
|
+
- `statement`: stronger type for introductions, first sections, and short
|
|
22
|
+
programmatic statements. Use it sparingly, usually as a section override.
|
|
23
|
+
|
|
24
|
+
If theme typography is omitted, `quiet-gallery` is used.
|
|
25
|
+
|
|
26
|
+
Presets define `headings.h1` through `headings.h4`, `body`, and `caption`.
|
|
27
|
+
They differ primarily through heading scale, alignment, line height, paragraph
|
|
28
|
+
spacing, caption treatment, and intended use. Choose larger or smaller type
|
|
29
|
+
with focused overrides when a specific page or section needs it.
|
|
30
|
+
|
|
31
|
+
Use this command to inspect the exact preset values shipped with the installed
|
|
32
|
+
engine:
|
|
33
|
+
|
|
34
|
+
```sh
|
|
35
|
+
norna typography presets
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
Use this command to inspect the effective values for the selected site after
|
|
39
|
+
presets and overrides have been applied:
|
|
40
|
+
|
|
41
|
+
```sh
|
|
42
|
+
norna typography show
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
The output includes the site theme, every page route, and every section. Each
|
|
46
|
+
resolved value shows its `source`; values inherited by a page or section are
|
|
47
|
+
also marked with `inherited: true`.
|
|
48
|
+
|
|
49
|
+
## Configuration Shape
|
|
50
|
+
|
|
51
|
+
```yaml
|
|
52
|
+
typography:
|
|
53
|
+
fontFamily: "Arial, 'Helvetica Neue', Helvetica, sans-serif"
|
|
54
|
+
preset: quiet-gallery
|
|
55
|
+
overrides:
|
|
56
|
+
headings:
|
|
57
|
+
h2:
|
|
58
|
+
size: medium
|
|
59
|
+
h3:
|
|
60
|
+
size: small
|
|
61
|
+
body:
|
|
62
|
+
paragraphSpacing: 0.8em
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
The typographic roles are:
|
|
66
|
+
|
|
67
|
+
- `headings.h1`: reserved for page-level Markdown `#` headings if the content
|
|
68
|
+
model starts supporting them.
|
|
69
|
+
- `headings.h2`: Markdown `##` section headings.
|
|
70
|
+
- `headings.h3`: Markdown `###` subheadings inside section body text.
|
|
71
|
+
- `headings.h4`: Markdown `####` subheadings inside section body text.
|
|
72
|
+
- `body`: Markdown body text inside sections.
|
|
73
|
+
- `caption`: image captions.
|
|
74
|
+
|
|
75
|
+
Allowed alignment values are `left`, `center`, and `right`. Alignment can be
|
|
76
|
+
responsive:
|
|
77
|
+
|
|
78
|
+
```yaml
|
|
79
|
+
align:
|
|
80
|
+
desktop: left
|
|
81
|
+
mobile: center
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
Allowed size values are `small`, `medium`, `large`, and `xlarge`. `medium` is
|
|
85
|
+
the normal reading size. Use `small` for quieter supporting text, and use
|
|
86
|
+
`large` or `xlarge` only when a page or section needs stronger emphasis.
|
|
87
|
+
Headings use their own scale, but follow the same principle: `medium` is the
|
|
88
|
+
normal section heading size, not a hero size. Norna may render the first
|
|
89
|
+
section heading as an HTML `h1` for document structure, but its visual
|
|
90
|
+
typography still follows the Markdown level the user wrote: `##` uses
|
|
91
|
+
`headings.h2`.
|
|
92
|
+
|
|
93
|
+
`lineHeight` is a unitless number from `1` through `3`. `spacing` and
|
|
94
|
+
`paragraphSpacing` are CSS lengths such as `0`, `0.8em`, `1rem`, or `12px`.
|
|
95
|
+
|
|
96
|
+
Supported override fields:
|
|
97
|
+
|
|
98
|
+
- `headings.h1.align`, `headings.h1.size`, `headings.h1.lineHeight`,
|
|
99
|
+
`headings.h1.spacing`
|
|
100
|
+
- `headings.h2.align`, `headings.h2.size`, `headings.h2.lineHeight`,
|
|
101
|
+
`headings.h2.spacing`
|
|
102
|
+
- `headings.h3.align`, `headings.h3.size`, `headings.h3.lineHeight`,
|
|
103
|
+
`headings.h3.spacing`
|
|
104
|
+
- `headings.h4.align`, `headings.h4.size`, `headings.h4.lineHeight`,
|
|
105
|
+
`headings.h4.spacing`
|
|
106
|
+
- `body.align`, `body.size`, `body.lineHeight`, `body.paragraphSpacing`
|
|
107
|
+
- `caption.align`, `caption.size`, `caption.lineHeight`, `caption.spacing`
|
|
108
|
+
|
|
109
|
+
## Inheritance
|
|
110
|
+
|
|
111
|
+
Theme typography is the site-wide base:
|
|
112
|
+
|
|
113
|
+
```yaml
|
|
114
|
+
# site/theme.md
|
|
115
|
+
typography:
|
|
116
|
+
fontFamily: "Arial, 'Helvetica Neue', Helvetica, sans-serif"
|
|
117
|
+
preset: quiet-gallery
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
A page-level `presentation.typography.preset` changes the typographic base for
|
|
121
|
+
that page. A section-level `sections[].presentation.typography.preset` changes
|
|
122
|
+
the typographic base for that section.
|
|
123
|
+
|
|
124
|
+
If a section sets `typography.preset`, that section starts from that preset. If
|
|
125
|
+
a section only sets `typography.overrides`, it keeps the resolved page preset
|
|
126
|
+
and changes only the specified values.
|
|
127
|
+
|
|
128
|
+
Example section override:
|
|
129
|
+
|
|
130
|
+
```yaml
|
|
131
|
+
sections:
|
|
132
|
+
- id: intro
|
|
133
|
+
presentation:
|
|
134
|
+
typography:
|
|
135
|
+
preset: statement
|
|
136
|
+
overrides:
|
|
137
|
+
body:
|
|
138
|
+
paragraphSpacing: 0.7em
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
Centered text uses narrower text widths. Left- or right-aligned heading and body
|
|
142
|
+
text use the calculated image layout width so text edges line up with images
|
|
143
|
+
after layout gutters and image limits are applied. Captions are normally
|
|
144
|
+
centered.
|