@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.
- package/README.md +15 -9
- package/bin/norna-cli.mjs +11 -4
- package/docs/README.md +71 -43
- package/docs/commands.md +34 -20
- package/docs/configuration.md +43 -62
- package/docs/content.md +34 -7
- package/docs/design/command-organization.md +15 -8
- package/docs/design/norna-diagram-design.md +6 -6
- package/docs/design/site-examples-structure.md +1 -1
- package/docs/engine-development.md +22 -9
- package/docs/getting-started.md +29 -16
- package/docs/how-to/embedded-site.md +1 -1
- package/docs/images-and-metadata.md +3 -3
- package/docs/local-development.md +11 -3
- package/docs/public-files.md +105 -0
- package/docs/publishing.md +4 -8
- package/docs/routes.md +6 -7
- package/docs/site-files.md +144 -0
- package/docs/sitewide-content.md +47 -33
- package/docs/theme.md +37 -49
- package/docs/typography.md +25 -31
- package/examples/complete-sites/dog-shelter-multi-page/README.md +8 -0
- package/examples/complete-sites/{dog-shelter-single-page/site/config.md → dog-shelter-multi-page/site/config.yaml} +0 -2
- package/examples/complete-sites/dog-shelter-multi-page/site/sitewide-content.yaml +6 -0
- package/examples/complete-sites/dog-shelter-multi-page/site/{theme.md → theme.yaml} +0 -2
- package/examples/complete-sites/dog-shelter-single-page/README.md +8 -0
- package/examples/complete-sites/{dog-shelter-multi-page/site/config.md → dog-shelter-single-page/site/config.yaml} +0 -2
- package/examples/complete-sites/dog-shelter-single-page/site/sitewide-content.yaml +6 -0
- package/examples/complete-sites/dog-shelter-single-page/site/{theme.md → theme.yaml} +0 -2
- package/examples/feature-demos/media-and-surfaces/.astro/data-store.json +1 -1
- package/examples/feature-demos/media-and-surfaces/README.md +1 -1
- package/examples/feature-demos/media-and-surfaces/site/{config.md → config.yaml} +0 -2
- package/examples/feature-demos/media-and-surfaces/site/content.md +2 -2
- package/examples/feature-demos/media-and-surfaces/site/routes/020-surfaces/{route-content.md → content.md} +3 -7
- package/examples/feature-demos/media-and-surfaces/site/routes/020-surfaces/theme.yaml +3 -0
- package/examples/feature-demos/media-and-surfaces/site/{sitewide-content.md → sitewide-content.yaml} +1 -3
- package/examples/feature-demos/media-and-surfaces/site/{theme.md → theme.yaml} +0 -2
- package/examples/feature-demos/sitewide-content/README.md +8 -0
- package/examples/feature-demos/sitewide-content/site/{config.md → config.yaml} +0 -2
- package/examples/feature-demos/sitewide-content/site/routes/010-identity/{route-content.md → content.md} +3 -3
- package/examples/feature-demos/sitewide-content/site/routes/020-notices/{route-content.md → content.md} +1 -1
- package/examples/feature-demos/sitewide-content/site/routes/030-footer/{route-content.md → content.md} +1 -1
- package/examples/feature-demos/sitewide-content/site/{sitewide-content.md → sitewide-content.yaml} +1 -11
- package/examples/feature-demos/sitewide-content/site/{theme.md → theme.yaml} +0 -2
- package/examples/feature-demos/theme-presets/site/config.yaml +1 -0
- package/examples/feature-demos/theme-presets/site/routes/010-portfolio/{theme.md → theme.yaml} +0 -2
- package/examples/feature-demos/theme-presets/site/routes/020-documentation/{theme.md → theme.yaml} +0 -2
- package/examples/feature-demos/theme-presets/site/routes/030-project/theme.yaml +1 -0
- package/examples/feature-demos/theme-presets/site/routes/040-statement/{route-content.md → content.md} +1 -1
- package/examples/feature-demos/theme-presets/site/routes/040-statement/{theme.md → theme.yaml} +0 -2
- package/examples/feature-demos/theme-presets/site/{sitewide-content.md → sitewide-content.yaml} +1 -3
- package/examples/feature-demos/theme-presets/site/theme.yaml +1 -0
- package/fixtures/basic/site/{config.md → config.yaml} +0 -2
- package/fixtures/basic/site/content.md +3 -3
- package/fixtures/basic/site/{sitewide-content.md → sitewide-content.yaml} +0 -2
- package/fixtures/basic/site/{theme.md → theme.yaml} +3 -6
- package/fixtures/content-model-v2/site/{config.md → config.yaml} +0 -2
- package/fixtures/content-model-v2/site/theme.yaml +4 -0
- package/package.json +10 -3
- package/schemas/config.schema.json +77 -0
- package/schemas/content-frontmatter.schema.json +81 -0
- package/schemas/manifest.json +9 -0
- package/schemas/sitewide-content.schema.json +215 -0
- package/schemas/theme.schema.json +1208 -0
- package/scripts/check-config.mjs +18 -11
- package/scripts/export-theme-preset.mjs +1 -1
- package/scripts/generate-schemas.mjs +283 -0
- package/scripts/init-site.mjs +22 -27
- package/scripts/lib/documentation-links.mjs +8 -0
- package/scripts/lib/editor-language-service.mjs +609 -0
- package/scripts/lib/example-sites.mjs +2 -2
- package/scripts/lib/git-status.mjs +7 -0
- package/scripts/lib/logo-assets.mjs +15 -10
- package/scripts/lib/norna-markdown-blocks.mjs +90 -11
- package/scripts/lib/presentation.mjs +23 -12
- package/scripts/lib/project-config.mjs +17 -41
- package/scripts/lib/public-asset-conventions.mjs +112 -0
- package/scripts/lib/schema-definitions.mjs +213 -0
- package/scripts/lib/schema-value-definitions.mjs +86 -0
- package/scripts/lib/site-content.mjs +24 -18
- package/scripts/lib/site-paths.mjs +4 -8
- package/scripts/lib/sitewide-content.mjs +24 -0
- package/scripts/lib/theme-config.mjs +15 -35
- package/scripts/lib/theme-presets.mjs +76 -66
- package/scripts/lib/typography.mjs +15 -15
- package/scripts/lib/yaml-config.mjs +50 -0
- package/scripts/list-theme-presets.mjs +15 -0
- package/scripts/release.mjs +84 -8
- package/scripts/show-typography.mjs +22 -46
- package/scripts/sync-content-sections.mjs +2 -2
- package/scripts/test-client-javascript.mjs +28 -28
- package/scripts/test-content-check.mjs +21 -26
- package/scripts/test-content-model-v2.mjs +72 -40
- package/scripts/test-documentation.mjs +70 -4
- package/scripts/test-editor-language-service.mjs +158 -0
- package/scripts/test-engine-commands.mjs +65 -34
- package/scripts/test-package-check.mjs +37 -30
- package/scripts/test-project-config.mjs +15 -20
- package/scripts/test-schemas.mjs +102 -0
- package/scripts/test-temporary-visibility.mjs +5 -13
- package/scripts/test-theme-presets.mjs +64 -37
- package/src/components/CardList.astro +2 -5
- package/src/components/ImageCarousel.astro +21 -21
- package/src/components/{GalleryGrid.astro → ImageStack.astro} +12 -12
- package/src/components/SectionNavigationScript.astro +28 -0
- package/src/components/SiteNavigation.astro +6 -5
- package/src/components/SitePage.astro +8 -8
- package/src/components/SiteSection.astro +18 -21
- package/src/content.config.ts +17 -209
- package/src/layouts/BaseLayout.astro +9 -9
- package/src/lib/{galleryImages.ts → imagePresentation.ts} +7 -7
- package/src/lib/routeThemes.ts +9 -29
- package/src/lib/sectionContent.ts +3 -3
- package/src/lib/sitePublicAssets.ts +5 -21
- package/src/styles/global.css +73 -73
- package/starters/basic/.github/workflows/deploy.yml +1 -1
- package/starters/basic/README.md +16 -13
- package/starters/basic/package.json +3 -2
- package/starters/basic/site/{config.md → config.yaml} +0 -2
- package/starters/basic/site/content.md +1 -1
- package/starters/basic/site/{sitewide-content.md → sitewide-content.yaml} +1 -3
- package/starters/basic/site/{theme.md → theme.yaml} +8 -15
- package/starters/project/.github/workflows/deploy.yml +1 -1
- package/starters/project/README.md +22 -15
- package/starters/project/package.json +3 -2
- package/starters/project/site/{config.md → config.yaml} +0 -2
- package/starters/project/site/{sitewide-content.md → sitewide-content.yaml} +1 -3
- package/starters/project/site/{theme.md → theme.yaml} +4 -8
- package/docs/site-structure.md +0 -98
- package/examples/complete-sites/dog-shelter-multi-page/site/sitewide-content.md +0 -16
- package/examples/complete-sites/dog-shelter-single-page/site/sitewide-content.md +0 -16
- package/examples/feature-demos/media-and-surfaces/site/routes/020-surfaces/theme.md +0 -8
- package/examples/feature-demos/theme-presets/site/config.md +0 -3
- package/examples/feature-demos/theme-presets/site/routes/030-project/theme.md +0 -3
- package/examples/feature-demos/theme-presets/site/theme.md +0 -3
- package/fixtures/content-model-v2/site/theme.md +0 -7
- package/scripts/lib/sitewide-config.mjs +0 -34
- package/src/components/MobileSectionNavigationScript.astro +0 -14
- /package/examples/complete-sites/dog-shelter-multi-page/site/routes/010-dogs/{route-content.md → content.md} +0 -0
- /package/examples/complete-sites/dog-shelter-multi-page/site/routes/020-adopt/{route-content.md → content.md} +0 -0
- /package/examples/feature-demos/media-and-surfaces/site/routes/010-media/{route-content.md → content.md} +0 -0
- /package/examples/feature-demos/theme-presets/site/routes/010-portfolio/{route-content.md → content.md} +0 -0
- /package/examples/feature-demos/theme-presets/site/routes/020-documentation/{route-content.md → content.md} +0 -0
- /package/examples/feature-demos/theme-presets/site/routes/030-project/{route-content.md → content.md} +0 -0
- /package/fixtures/content-model-v2/site/routes/010-guide/{route-content.md → content.md} +0 -0
- /package/starters/project/site/routes/010-guide/{route-content.md → content.md} +0 -0
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
# Site Files
|
|
2
|
+
|
|
3
|
+
Norna expects a defined set of files and directories. Their names and locations
|
|
4
|
+
are part of the site model: following the structure lets Norna find content,
|
|
5
|
+
presentation, configuration, routes, and assets without path configuration.
|
|
6
|
+
|
|
7
|
+
The selected site directory is `site/` by default:
|
|
8
|
+
|
|
9
|
+
```text
|
|
10
|
+
site/
|
|
11
|
+
|-- config.yaml
|
|
12
|
+
|-- theme.yaml
|
|
13
|
+
|-- sitewide-content.yaml
|
|
14
|
+
|-- content.md
|
|
15
|
+
|-- images/
|
|
16
|
+
| `-- <section-id>/
|
|
17
|
+
|-- routes/
|
|
18
|
+
| `-- <NNN-route-id>/
|
|
19
|
+
| |-- content.md
|
|
20
|
+
| |-- theme.yaml
|
|
21
|
+
| `-- images/
|
|
22
|
+
| `-- <section-id>/
|
|
23
|
+
|-- public/
|
|
24
|
+
`-- .norna/
|
|
25
|
+
|-- generated-images.json
|
|
26
|
+
`-- public/
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
File and directory names shown literally above must use that exact lowercase
|
|
30
|
+
spelling. This keeps sites portable between case-sensitive and
|
|
31
|
+
case-insensitive file systems.
|
|
32
|
+
|
|
33
|
+
## Root Files
|
|
34
|
+
|
|
35
|
+
| Path | Required | Responsibility |
|
|
36
|
+
| --- | --- | --- |
|
|
37
|
+
| `config.yaml` | Yes | Public URL, language, and browser scroll behavior. |
|
|
38
|
+
| `theme.yaml` | Yes | Complete visual preset and optional focused overrides. |
|
|
39
|
+
| `sitewide-content.yaml` | No | Shared navigation identity, banners, and footer. |
|
|
40
|
+
| `content.md` | Yes | Homepage metadata, sections, prose, and Norna blocks. |
|
|
41
|
+
|
|
42
|
+
These responsibilities are deliberately separate:
|
|
43
|
+
|
|
44
|
+
- [`config.yaml`](configuration.md) contains the few technical settings that
|
|
45
|
+
apply to the whole site.
|
|
46
|
+
- [`theme.yaml`](theme.md) controls presentation. A normal file can contain
|
|
47
|
+
only a preset selection.
|
|
48
|
+
- [`sitewide-content.yaml`](sitewide-content.md) contains editorial material
|
|
49
|
+
shared by every page.
|
|
50
|
+
- [`content.md`](content.md) is the homepage page file and remains ordinary
|
|
51
|
+
Markdown with YAML frontmatter.
|
|
52
|
+
|
|
53
|
+
Routes cannot provide `config.yaml` or `sitewide-content.yaml`. Technical
|
|
54
|
+
configuration and shared identity have one site-wide source.
|
|
55
|
+
|
|
56
|
+
## Images
|
|
57
|
+
|
|
58
|
+
Managed homepage images belong in:
|
|
59
|
+
|
|
60
|
+
```text
|
|
61
|
+
site/images/<section-id>/
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
The directory name must match an explicit level 2 Markdown section id in
|
|
65
|
+
`content.md`. Markdown blocks refer to managed images by filename, not by path.
|
|
66
|
+
See [Images and Metadata](images-and-metadata.md) for supported formats,
|
|
67
|
+
generated variants, and syncing.
|
|
68
|
+
|
|
69
|
+
## Routes
|
|
70
|
+
|
|
71
|
+
Each first-level route is one directory under `routes/`:
|
|
72
|
+
|
|
73
|
+
```text
|
|
74
|
+
site/routes/010-guide/
|
|
75
|
+
|-- content.md
|
|
76
|
+
|-- theme.yaml
|
|
77
|
+
`-- images/
|
|
78
|
+
`-- intro/
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
`content.md` is required for a route. The optional route `theme.yaml` replaces
|
|
82
|
+
the root visual theme for that route. Route images follow the same
|
|
83
|
+
`images/<section-id>/` convention as homepage images.
|
|
84
|
+
|
|
85
|
+
The three-digit route prefix controls navigation order and is not part of the
|
|
86
|
+
URL. See [Routes](routes.md) for exact directory-name and route-id rules.
|
|
87
|
+
|
|
88
|
+
## Public Files
|
|
89
|
+
|
|
90
|
+
`site/public/` contains static files copied without image processing. Most
|
|
91
|
+
names are site-owned, but Norna recognizes a small set of exact conventional
|
|
92
|
+
filenames for the navigation logo and browser icons.
|
|
93
|
+
|
|
94
|
+
See [Public Files](public-files.md) for logo and favicon filenames, arbitrary
|
|
95
|
+
static files, root-relative links, and publishing paths.
|
|
96
|
+
|
|
97
|
+
## Selecting The Site Directory
|
|
98
|
+
|
|
99
|
+
Use `NORNA_SITE_DIR` or `norna --site-dir <path>` to select a site directory
|
|
100
|
+
explicitly.
|
|
101
|
+
|
|
102
|
+
Without an explicit selection, Norna first accepts the current directory when
|
|
103
|
+
it contains both `config.yaml` and `content.md`. Otherwise it walks upward until
|
|
104
|
+
it finds a default `site/` directory containing those two files.
|
|
105
|
+
|
|
106
|
+
## Versioned Files
|
|
107
|
+
|
|
108
|
+
Version the source files above together with:
|
|
109
|
+
|
|
110
|
+
- `site/.norna/generated-images.json`, which records reusable managed-image
|
|
111
|
+
output;
|
|
112
|
+
- `.github/workflows/deploy.yml`, when using the included GitHub Pages
|
|
113
|
+
publishing integration;
|
|
114
|
+
- `package.json` and `package-lock.json`, which pin the local Norna engine and
|
|
115
|
+
project scripts.
|
|
116
|
+
|
|
117
|
+
Source images and files under `site/public/` are also versioned site input.
|
|
118
|
+
|
|
119
|
+
## Generated Files
|
|
120
|
+
|
|
121
|
+
Do not edit these by hand:
|
|
122
|
+
|
|
123
|
+
- `site/.norna/public/`: build-preparation output copied from `site/public/`,
|
|
124
|
+
plus generated or copied managed images;
|
|
125
|
+
- `dist/`: final static website output;
|
|
126
|
+
- `.astro/`: Astro cache, generated types, and local dev-server state.
|
|
127
|
+
|
|
128
|
+
`norna site:public` removes stale copied static files from
|
|
129
|
+
`site/.norna/public/` while preserving managed image output under its `images/`
|
|
130
|
+
directory.
|
|
131
|
+
|
|
132
|
+
## Engine Repository Layout
|
|
133
|
+
|
|
134
|
+
These directories belong to the Norna engine repository, not to an ordinary
|
|
135
|
+
site:
|
|
136
|
+
|
|
137
|
+
- `bin/`: the launcher and public CLI dispatcher;
|
|
138
|
+
- `scripts/`: validation, image, preview, publishing, and test tools;
|
|
139
|
+
- `src/`: the Astro renderer, components, styles, and content schema;
|
|
140
|
+
- `starters/`: source copied by `norna init`;
|
|
141
|
+
- `examples/`: complete sites and focused feature demonstrations;
|
|
142
|
+
- `fixtures/`: engine regression input;
|
|
143
|
+
- root `site/`: the Norna introduction and documentation site.
|
|
144
|
+
|
package/docs/sitewide-content.md
CHANGED
|
@@ -1,38 +1,49 @@
|
|
|
1
|
-
#
|
|
1
|
+
# `sitewide-content.yaml`
|
|
2
2
|
|
|
3
|
-
`site/sitewide-content.
|
|
4
|
-
|
|
5
|
-
`config.md`, which defines the public URL and optional language and scroll
|
|
6
|
-
behaviour.
|
|
3
|
+
`site/sitewide-content.yaml` is optional. It contains editorial content and
|
|
4
|
+
identity shared by every page: the navigation label, banners, and footer.
|
|
7
5
|
|
|
8
|
-
|
|
6
|
+
The file contains plain YAML without Markdown frontmatter delimiters. Page
|
|
7
|
+
sections do not belong here; they remain in each page's `content.md`.
|
|
9
8
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
9
|
+
## Navigation Identity
|
|
10
|
+
|
|
11
|
+
Use the optional `navigation` object for identity shared by the homepage and
|
|
12
|
+
all routes:
|
|
14
13
|
|
|
15
14
|
```yaml
|
|
16
15
|
navigation:
|
|
17
|
-
|
|
16
|
+
label: Example Site
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
Without a navigation logo, `label` is shown in the home link. With a logo,
|
|
20
|
+
`label` becomes the image alternative text. If omitted, Norna uses the homepage
|
|
21
|
+
title from `site/content.md`.
|
|
22
|
+
|
|
23
|
+
A logo file is discovered from `site/public/`; no path is configured here. Add
|
|
24
|
+
`logo` only to override its displayed height:
|
|
25
|
+
|
|
26
|
+
```yaml
|
|
27
|
+
navigation:
|
|
28
|
+
label: Example Site
|
|
18
29
|
logo:
|
|
19
|
-
alt: Example Site
|
|
20
30
|
height: 2.6rem
|
|
21
31
|
```
|
|
22
32
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
33
|
+
The logo width follows the file's intrinsic aspect ratio. See
|
|
34
|
+
[Public Files: Navigation Logo](public-files.md#navigation-logo) for exact
|
|
35
|
+
filenames, placement, portability, and validation rules.
|
|
36
|
+
|
|
37
|
+
Routes inherit this identity and cannot replace it in route content or a route
|
|
38
|
+
theme.
|
|
27
39
|
|
|
28
40
|
## Banners
|
|
29
41
|
|
|
30
|
-
Use `banners` for short notices shown above
|
|
31
|
-
|
|
32
|
-
|
|
42
|
+
Use `banners` for short notices shown above page content on every route. List
|
|
43
|
+
order controls presentation order. Each banner needs a unique lowercase `id`,
|
|
44
|
+
a title, and text:
|
|
33
45
|
|
|
34
46
|
```yaml
|
|
35
|
-
---
|
|
36
47
|
banners:
|
|
37
48
|
- id: project-status
|
|
38
49
|
tone: warning
|
|
@@ -41,26 +52,25 @@ banners:
|
|
|
41
52
|
until: "2026-09-01"
|
|
42
53
|
title: Experimental code
|
|
43
54
|
text: Not for production use.
|
|
44
|
-
---
|
|
45
55
|
```
|
|
46
56
|
|
|
47
|
-
`
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
again.
|
|
57
|
+
`tone` currently supports `warning`. `visible` is optional and uses the same
|
|
58
|
+
date-window rules as temporary sections: `from` is inclusive and `until` is
|
|
59
|
+
exclusive.
|
|
51
60
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
61
|
+
Visitors can dismiss each active banner. Dismissal state is stored locally in
|
|
62
|
+
the browser and tied to the banner content, so an edited banner can appear
|
|
63
|
+
again. Keep banners concise; they are rendered as compact one-line notices and
|
|
64
|
+
may use an ellipsis when space is limited.
|
|
55
65
|
|
|
56
66
|
## Footer
|
|
57
67
|
|
|
58
|
-
The footer
|
|
59
|
-
|
|
68
|
+
The footer can contain copyright or ownership text and optional generated build
|
|
69
|
+
information:
|
|
60
70
|
|
|
61
71
|
```yaml
|
|
62
72
|
footer:
|
|
63
|
-
copyrightMessage: (c) Example
|
|
73
|
+
copyrightMessage: (c) Example Owner.
|
|
64
74
|
buildInfo:
|
|
65
75
|
enabled: true
|
|
66
76
|
text: Built
|
|
@@ -71,5 +81,9 @@ footer:
|
|
|
71
81
|
timeStyle: short
|
|
72
82
|
```
|
|
73
83
|
|
|
74
|
-
|
|
75
|
-
|
|
84
|
+
`dateTimeFormat` uses `Intl.DateTimeFormat` values. `timeZone` must be a valid
|
|
85
|
+
IANA time-zone name. If both copyright text and enabled build information are
|
|
86
|
+
absent, no footer is rendered.
|
|
87
|
+
|
|
88
|
+
See [Site Files](site-files.md) for where this optional file belongs in the
|
|
89
|
+
complete site model.
|
package/docs/theme.md
CHANGED
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
# Theme
|
|
2
2
|
|
|
3
|
-
`site/theme.
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
focused overrides when needed.
|
|
3
|
+
`site/theme.yaml` defines the site-wide visual theme for a Norna site. It is a
|
|
4
|
+
required plain YAML file. The normal setup selects one complete theme preset
|
|
5
|
+
and adds only focused overrides when needed.
|
|
7
6
|
|
|
8
|
-
An optional `theme.
|
|
9
|
-
for that route. Shared identity such as
|
|
10
|
-
belongs in `sitewide-content.
|
|
7
|
+
An optional `theme.yaml` inside a route directory replaces the root visual
|
|
8
|
+
theme for that route. Shared identity such as the navigation label and logo
|
|
9
|
+
remains site-wide and belongs in `sitewide-content.yaml`.
|
|
11
10
|
|
|
12
11
|
## Theme Presets
|
|
13
12
|
|
|
@@ -22,22 +21,20 @@ Available complete theme presets are:
|
|
|
22
21
|
- `statement`: airy spacing and stronger typography for short editorial
|
|
23
22
|
content.
|
|
24
23
|
|
|
25
|
-
A normal `theme.
|
|
24
|
+
A normal `theme.yaml` can be only:
|
|
26
25
|
|
|
27
26
|
```yaml
|
|
28
|
-
---
|
|
29
27
|
preset: documentation
|
|
30
|
-
---
|
|
31
28
|
```
|
|
32
29
|
|
|
33
30
|
Each preset supplies coordinated values for:
|
|
34
31
|
|
|
35
32
|
- layout density, page width, and gutters
|
|
36
33
|
- managed image sizing
|
|
37
|
-
- font family, typography
|
|
34
|
+
- font family, typography profile, and typography rhythm
|
|
38
35
|
- palette and section-surface behaviour
|
|
39
36
|
|
|
40
|
-
The nested `typography.
|
|
37
|
+
The nested `typography.profile` setting documented below is a lower-level
|
|
41
38
|
typography choice. A top-level theme `preset` selects the complete visual
|
|
42
39
|
system, including that typography choice.
|
|
43
40
|
|
|
@@ -47,18 +44,14 @@ Values written beside the top-level preset override only that part of the
|
|
|
47
44
|
preset. Other preset values remain active:
|
|
48
45
|
|
|
49
46
|
```yaml
|
|
50
|
-
---
|
|
51
47
|
preset: documentation
|
|
52
48
|
layout:
|
|
53
49
|
pageWidth: 1320px
|
|
54
|
-
|
|
55
|
-
palette: dark
|
|
56
|
-
---
|
|
50
|
+
palette: dark
|
|
57
51
|
```
|
|
58
52
|
|
|
59
|
-
Nested objects are merged by key.
|
|
60
|
-
|
|
61
|
-
specified.
|
|
53
|
+
Nested objects are merged by key. `sectionSurfaces` replaces the preset array
|
|
54
|
+
when it is specified.
|
|
62
55
|
|
|
63
56
|
It is still valid to omit the top-level preset and define the visual settings
|
|
64
57
|
explicitly. Omitted explicit settings then use engine defaults. This is useful
|
|
@@ -79,16 +72,17 @@ In a generated site, the equivalent npm command is:
|
|
|
79
72
|
npm run norna:theme:export -- documentation
|
|
80
73
|
```
|
|
81
74
|
|
|
82
|
-
The command creates `site/orig-documentation-theme.
|
|
75
|
+
The command creates `site/orig-documentation-theme.yaml`, or the corresponding
|
|
83
76
|
path under the selected site directory. The file contains the preset values,
|
|
84
77
|
comments describing accepted alternatives, and an example of a fine-grained
|
|
85
78
|
typography override.
|
|
86
79
|
|
|
87
|
-
Norna never loads `orig-*-theme.
|
|
80
|
+
Norna never loads `orig-*-theme.yaml`; only `theme.yaml` is active. The export
|
|
88
81
|
command refuses to overwrite an existing reference file.
|
|
89
82
|
|
|
90
83
|
Site identity is not part of the visual theme. Define the optional navigation
|
|
91
|
-
|
|
84
|
+
label and logo display settings in `site/sitewide-content.yaml`; see
|
|
85
|
+
[Sitewide Content](sitewide-content.md).
|
|
92
86
|
|
|
93
87
|
## Layout
|
|
94
88
|
|
|
@@ -155,7 +149,7 @@ before Markdown subheadings, paragraph spacing, and caption spacing, belongs to
|
|
|
155
149
|
|
|
156
150
|
## Image Sizing
|
|
157
151
|
|
|
158
|
-
`
|
|
152
|
+
`images` is optional. It controls managed image sizing:
|
|
159
153
|
|
|
160
154
|
- `width`: hard maximum rendered image area width for images, captions, and
|
|
161
155
|
aligned text.
|
|
@@ -166,7 +160,7 @@ before Markdown subheadings, paragraph spacing, and caption spacing, belongs to
|
|
|
166
160
|
Example:
|
|
167
161
|
|
|
168
162
|
```yaml
|
|
169
|
-
|
|
163
|
+
images:
|
|
170
164
|
width: 900px
|
|
171
165
|
maxAvailableWidthPercent:
|
|
172
166
|
desktop: 100
|
|
@@ -184,7 +178,7 @@ desktop `74` / mobile `68`.
|
|
|
184
178
|
Top-level `typography` is the site-wide typographic base. It supports:
|
|
185
179
|
|
|
186
180
|
- `fontFamily`: global CSS font-family stack.
|
|
187
|
-
- `
|
|
181
|
+
- `profile`: built-in typography profile.
|
|
188
182
|
- `rhythm`: text-near spacing profile. Allowed values are `compact`,
|
|
189
183
|
`normal`, and `airy`.
|
|
190
184
|
- `overrides`: focused changes to preset values.
|
|
@@ -194,7 +188,7 @@ Example:
|
|
|
194
188
|
```yaml
|
|
195
189
|
typography:
|
|
196
190
|
fontFamily: "Arial, 'Helvetica Neue', Helvetica, sans-serif"
|
|
197
|
-
|
|
191
|
+
profile: reading
|
|
198
192
|
rhythm: normal
|
|
199
193
|
overrides:
|
|
200
194
|
headings:
|
|
@@ -211,38 +205,34 @@ typography:
|
|
|
211
205
|
lineHeight: 1.55
|
|
212
206
|
```
|
|
213
207
|
|
|
214
|
-
Use `norna typography
|
|
208
|
+
Use `norna typography profiles` to inspect built-in profile and rhythm values,
|
|
215
209
|
and `norna typography show` to inspect the resolved typography for the
|
|
216
210
|
selected site. See [Typography](typography.md).
|
|
217
211
|
|
|
218
|
-
##
|
|
212
|
+
## Palette And Section Surfaces
|
|
219
213
|
|
|
220
|
-
`
|
|
221
|
-
page frame and defines how section surfaces are assigned:
|
|
214
|
+
`palette` and `sectionSurfaces` are optional top-level theme settings:
|
|
222
215
|
|
|
223
|
-
- `palette`: `dark`, `light`, or `paper`.
|
|
224
|
-
|
|
225
|
-
- `sectionSurfaces
|
|
226
|
-
|
|
227
|
-
|
|
216
|
+
- `palette`: `dark`, `light`, or `paper`. It coordinates page, navigation,
|
|
217
|
+
footer, and section colors.
|
|
218
|
+
- `sectionSurfaces`: one to three unique values chosen from `base`, `soft`, and
|
|
219
|
+
`emphasis`. One value gives every section the same surface. Multiple values
|
|
220
|
+
cycle in the listed order.
|
|
228
221
|
|
|
229
222
|
Example:
|
|
230
223
|
|
|
231
224
|
```yaml
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
sectionSurfaces:
|
|
235
|
-
mode: cycle
|
|
236
|
-
sequence: [base, soft, emphasis]
|
|
225
|
+
palette: paper # Alternatives: dark, light
|
|
226
|
+
sectionSurfaces: [base, soft, emphasis]
|
|
237
227
|
```
|
|
238
228
|
|
|
239
229
|
## Route Themes
|
|
240
230
|
|
|
241
|
-
Add `theme.
|
|
231
|
+
Add `theme.yaml` to a route directory when that route should have a different
|
|
242
232
|
visual expression:
|
|
243
233
|
|
|
244
234
|
```text
|
|
245
|
-
site/routes/010-guide/theme.
|
|
235
|
+
site/routes/010-guide/theme.yaml
|
|
246
236
|
```
|
|
247
237
|
|
|
248
238
|
The route theme uses the same visual schema and complete presets as the root
|
|
@@ -250,14 +240,12 @@ theme. A route can therefore select a different expression without repeating a
|
|
|
250
240
|
large configuration:
|
|
251
241
|
|
|
252
242
|
```yaml
|
|
253
|
-
---
|
|
254
243
|
preset: statement
|
|
255
|
-
---
|
|
256
244
|
```
|
|
257
245
|
|
|
258
246
|
It completely replaces the root visual theme for that route. If the route
|
|
259
247
|
theme selects no top-level preset, omitted values use engine defaults rather
|
|
260
|
-
than values from the root theme. It cannot define navigation
|
|
248
|
+
than values from the root theme. It cannot define navigation identity or
|
|
261
249
|
technical configuration.
|
|
262
250
|
|
|
263
251
|
Section surfaces render as full-width horizontal bands while the section
|
|
@@ -268,7 +256,7 @@ accent color.
|
|
|
268
256
|
|
|
269
257
|
### Should every route select its own preset?
|
|
270
258
|
|
|
271
|
-
No. A route without its own `theme.
|
|
259
|
+
No. A route without its own `theme.yaml` inherits the root theme, which is the
|
|
272
260
|
normal choice when the site should keep one visual expression.
|
|
273
261
|
|
|
274
262
|
Add a route theme only when the route should intentionally look different. If
|
|
@@ -278,6 +266,6 @@ necessary because a route theme replaces the root visual theme rather than
|
|
|
278
266
|
merging with it.
|
|
279
267
|
|
|
280
268
|
For example, a route demonstrating section surfaces may keep `preset: project`
|
|
281
|
-
and change only `
|
|
282
|
-
|
|
283
|
-
|
|
269
|
+
and change only `sectionSurfaces`. A route demonstrating image or content
|
|
270
|
+
blocks should normally inherit the root preset so that the blocks remain the
|
|
271
|
+
only variable being compared.
|
package/docs/typography.md
CHANGED
|
@@ -1,50 +1,48 @@
|
|
|
1
1
|
# Typography
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
Norna typography is configured in `site/theme.yaml` through a site-wide font,
|
|
4
|
+
profile, text rhythm, and optional overrides.
|
|
5
5
|
|
|
6
6
|
The normal workflow is to select a complete top-level theme preset. It already
|
|
7
|
-
chooses a coordinated font, typography
|
|
7
|
+
chooses a coordinated font, typography profile, and rhythm:
|
|
8
8
|
|
|
9
9
|
```yaml
|
|
10
|
-
---
|
|
11
10
|
preset: documentation
|
|
12
|
-
---
|
|
13
11
|
```
|
|
14
12
|
|
|
15
13
|
Use the nested `typography` block only when those typographic choices need to
|
|
16
14
|
differ from the selected theme preset. Typography is configured at root-theme
|
|
17
15
|
or route-theme level, not in page or section content.
|
|
18
16
|
|
|
19
|
-
## Typography
|
|
17
|
+
## Typography Profiles
|
|
20
18
|
|
|
21
|
-
Available
|
|
19
|
+
Available profiles:
|
|
22
20
|
|
|
23
|
-
- `
|
|
21
|
+
- `restrained`: the default for image-led sites. Text is restrained and
|
|
24
22
|
supports the images without dominating the page.
|
|
25
|
-
- `
|
|
23
|
+
- `dense`: tighter typography for many sections, many images, or
|
|
26
24
|
short information blocks.
|
|
27
|
-
- `
|
|
25
|
+
- `reading`: more generous body text for pages where longer text carries
|
|
28
26
|
more of the experience.
|
|
29
27
|
- `statement`: tighter, more declarative line-height for short programmatic
|
|
30
|
-
statements. Use it sparingly, usually as a
|
|
28
|
+
statements. Use it sparingly, usually as a route-level exception.
|
|
31
29
|
|
|
32
30
|
If a complete top-level theme preset is selected, that preset supplies the
|
|
33
31
|
typography choice. If both the top-level preset and nested typography are
|
|
34
|
-
omitted, the engine default is `
|
|
32
|
+
omitted, the engine default is `restrained`.
|
|
35
33
|
|
|
36
|
-
|
|
34
|
+
Profiles define alignment, size, weight, and line height for `headings.h1`
|
|
37
35
|
through `headings.h4`, `body`, and `caption`. They also choose a readable body
|
|
38
36
|
text width. Built-in presets use `medium` as the default size for every text
|
|
39
37
|
role. Visual heading hierarchy comes from the Markdown heading level, so `h1`
|
|
40
38
|
is larger than `h2`, `h2` is larger than `h3`, and so on.
|
|
41
39
|
|
|
42
|
-
The
|
|
40
|
+
The profiles use these controls deliberately:
|
|
43
41
|
|
|
44
|
-
- `
|
|
45
|
-
- `
|
|
42
|
+
- `restrained` uses restrained heading weights and a normal reading width.
|
|
43
|
+
- `dense` uses stronger headings and a wider text column for short,
|
|
46
44
|
scannable content.
|
|
47
|
-
- `
|
|
45
|
+
- `reading` uses a narrower reading width and more generous body line
|
|
48
46
|
height.
|
|
49
47
|
- `statement` uses the strongest heading weights and a narrow text column for
|
|
50
48
|
short, declarative content.
|
|
@@ -53,15 +51,15 @@ The presets use these controls deliberately:
|
|
|
53
51
|
Available rhythms are `compact`, `normal`, and `airy`. Built-in rhythm values
|
|
54
52
|
use `em` so spacing follows the rendered text size.
|
|
55
53
|
|
|
56
|
-
Use this command to inspect the exact
|
|
54
|
+
Use this command to inspect the exact profile and rhythm values shipped with
|
|
57
55
|
the installed engine:
|
|
58
56
|
|
|
59
57
|
```sh
|
|
60
|
-
norna typography
|
|
58
|
+
norna typography profiles
|
|
61
59
|
```
|
|
62
60
|
|
|
63
61
|
Use this command to inspect the effective values for the selected site after
|
|
64
|
-
|
|
62
|
+
profiles, rhythms, and overrides have been applied:
|
|
65
63
|
|
|
66
64
|
```sh
|
|
67
65
|
norna typography show
|
|
@@ -76,7 +74,7 @@ also marked with `inherited: true`.
|
|
|
76
74
|
```yaml
|
|
77
75
|
typography:
|
|
78
76
|
fontFamily: "Arial, 'Helvetica Neue', Helvetica, sans-serif"
|
|
79
|
-
|
|
77
|
+
profile: restrained
|
|
80
78
|
rhythm: normal
|
|
81
79
|
overrides:
|
|
82
80
|
headings:
|
|
@@ -117,7 +115,7 @@ align:
|
|
|
117
115
|
Allowed size values are `small`, `medium`, `large`, and `xlarge`. `medium` is
|
|
118
116
|
the normal reading size. Use `small` for quieter supporting text, and use
|
|
119
117
|
`large` or `xlarge` only when a page or section needs stronger emphasis.
|
|
120
|
-
Each heading level uses its own scale
|
|
118
|
+
Each heading level uses its own scale but follows the same principle:
|
|
121
119
|
`medium` is the normal size for that level. Norna may render the first section
|
|
122
120
|
heading as an HTML `h1` for document structure, but its visual typography still
|
|
123
121
|
follows the Markdown level the user wrote: `##` uses `headings.h2`.
|
|
@@ -156,13 +154,11 @@ The simplest route-specific typography change is to select a complete theme
|
|
|
156
154
|
preset:
|
|
157
155
|
|
|
158
156
|
```yaml
|
|
159
|
-
# site/routes/010-introduction/theme.
|
|
160
|
-
---
|
|
157
|
+
# site/routes/010-introduction/theme.yaml
|
|
161
158
|
preset: statement
|
|
162
|
-
---
|
|
163
159
|
```
|
|
164
160
|
|
|
165
|
-
A route-local `theme.
|
|
161
|
+
A route-local `theme.yaml` replaces the root visual theme rather than inheriting
|
|
166
162
|
from it. The complete preset supplies a coherent route theme without repeating
|
|
167
163
|
the root values.
|
|
168
164
|
|
|
@@ -170,17 +166,15 @@ Use a nested typography choice when only the typographic character needs to be
|
|
|
170
166
|
specified explicitly:
|
|
171
167
|
|
|
172
168
|
```yaml
|
|
173
|
-
# site/routes/010-introduction/theme.
|
|
174
|
-
---
|
|
169
|
+
# site/routes/010-introduction/theme.yaml
|
|
175
170
|
typography:
|
|
176
|
-
|
|
171
|
+
profile: statement
|
|
177
172
|
rhythm: normal
|
|
178
|
-
---
|
|
179
173
|
```
|
|
180
174
|
|
|
181
175
|
Without a top-level theme preset, other omitted route-theme values use engine
|
|
182
176
|
defaults rather than values from the root theme.
|
|
183
177
|
|
|
184
178
|
The `body.width` value controls the prose column independently of the page and
|
|
185
|
-
image widths. Captions are normally centered, but `
|
|
179
|
+
image widths. Captions are normally centered, but `reading` uses
|
|
186
180
|
left-aligned captions to support longer explanatory text.
|
|
@@ -9,6 +9,14 @@ A small Norna site with a homepage and ordered routes for dogs and adoption.
|
|
|
9
9
|
The dog photos are CC0 images by Bicanski, sourced from Pixnio. Attribution is
|
|
10
10
|
included in the site footer even though the licence does not require it.
|
|
11
11
|
|
|
12
|
+
<!-- norna-image-provenance:
|
|
13
|
+
image: site/public/logo.svg
|
|
14
|
+
source: AI-assisted, hand-authored SVG
|
|
15
|
+
prompt: Create a compact horizontal dog shelter logo with a simple dog face in
|
|
16
|
+
a house-shaped mark and the words Dog Shelter. Use flat vector shapes, a warm
|
|
17
|
+
red accent, dark text, transparent background and no external assets.
|
|
18
|
+
-->
|
|
19
|
+
|
|
12
20
|
Run it from the Norna repository root:
|
|
13
21
|
|
|
14
22
|
```sh
|
|
@@ -9,6 +9,14 @@ A small Norna site with two homepage sections and no routes.
|
|
|
9
9
|
The dog photos are CC0 images by Bicanski, sourced from Pixnio. Attribution is
|
|
10
10
|
included in the site footer even though the licence does not require it.
|
|
11
11
|
|
|
12
|
+
<!-- norna-image-provenance:
|
|
13
|
+
image: site/public/logo.svg
|
|
14
|
+
source: AI-assisted, hand-authored SVG
|
|
15
|
+
prompt: Create a compact horizontal dog shelter logo with a simple dog face in
|
|
16
|
+
a house-shaped mark and the words Dog Shelter. Use flat vector shapes, a warm
|
|
17
|
+
red accent, dark text, transparent background and no external assets.
|
|
18
|
+
-->
|
|
19
|
+
|
|
12
20
|
Run it from the Norna repository root:
|
|
13
21
|
|
|
14
22
|
```sh
|