@janga/norna 0.7.6 → 0.7.7

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 (137) hide show
  1. package/README.md +5 -5
  2. package/astro.config.mjs +76 -0
  3. package/bin/norna-cli.mjs +2 -2
  4. package/docs/README.md +3 -3
  5. package/docs/commands.md +6 -6
  6. package/docs/configuration.md +3 -2
  7. package/docs/content.md +152 -91
  8. package/docs/design/site-examples-structure.md +1 -1
  9. package/docs/engine-development.md +3 -3
  10. package/docs/getting-started.md +4 -3
  11. package/docs/images-and-metadata.md +112 -20
  12. package/docs/routes.md +9 -12
  13. package/docs/site-structure.md +4 -3
  14. package/docs/theme.md +8 -7
  15. package/docs/typography.md +5 -5
  16. package/examples/dog-gallery/site/content.md +41 -45
  17. package/examples/dog-gallery/site/routes/010-dog-care/route-content.md +1 -3
  18. package/fixtures/basic/site/content.md +2 -4
  19. package/fixtures/content-model-v2/.astro/collections/site.schema.json +776 -0
  20. package/fixtures/content-model-v2/.astro/collections/theme.schema.json +668 -0
  21. package/fixtures/content-model-v2/.astro/content-assets.mjs +4 -0
  22. package/fixtures/content-model-v2/.astro/content-modules.mjs +1 -0
  23. package/fixtures/content-model-v2/.astro/content.d.ts +175 -0
  24. package/fixtures/content-model-v2/.astro/data-store.json +1 -0
  25. package/fixtures/content-model-v2/.astro/dev-local.json +8 -0
  26. package/fixtures/content-model-v2/.astro/dev.json +13 -0
  27. package/fixtures/content-model-v2/.astro/dev.log +231 -0
  28. package/fixtures/content-model-v2/.astro/settings.json +5 -0
  29. package/fixtures/content-model-v2/.astro/types.d.ts +2 -0
  30. package/fixtures/content-model-v2/dist/_astro/GalleryGrid.astro_astro_type_script_index_0_lang.B0kxDyGz.js +1 -0
  31. package/fixtures/content-model-v2/dist/_astro/SitePage.BbfZub4g.css +1 -0
  32. package/fixtures/content-model-v2/dist/guide/index.html +3 -0
  33. package/fixtures/content-model-v2/dist/images/generated/intro/detail-27930b14-480.webp +0 -0
  34. package/fixtures/content-model-v2/dist/images/generated/intro/detail-27930b14-768.webp +0 -0
  35. package/fixtures/content-model-v2/dist/images/generated/intro/detail-27930b14-971.webp +0 -0
  36. package/fixtures/content-model-v2/dist/images/generated/intro/duplicate-49c98f6c-480.webp +0 -0
  37. package/fixtures/content-model-v2/dist/images/generated/intro/duplicate-49c98f6c-768.webp +0 -0
  38. package/fixtures/content-model-v2/dist/images/generated/intro/duplicate-49c98f6c-971.webp +0 -0
  39. package/fixtures/content-model-v2/dist/images/generated/intro/hero-6d588a83-480.webp +0 -0
  40. package/fixtures/content-model-v2/dist/images/generated/intro/hero-6d588a83-768.webp +0 -0
  41. package/fixtures/content-model-v2/dist/images/generated/intro/hero-6d588a83-971.webp +0 -0
  42. package/fixtures/content-model-v2/dist/images/generated/plain/image-3770d763-1080.webp +0 -0
  43. package/fixtures/content-model-v2/dist/images/generated/plain/image-3770d763-1440.webp +0 -0
  44. package/fixtures/content-model-v2/dist/images/generated/plain/image-3770d763-1600.webp +0 -0
  45. package/fixtures/content-model-v2/dist/images/generated/plain/image-3770d763-480.webp +0 -0
  46. package/fixtures/content-model-v2/dist/images/generated/plain/image-3770d763-768.webp +0 -0
  47. package/fixtures/content-model-v2/dist/images/generated/routes/010-guide/images/intro/duplicate-5cf614d2-480.webp +0 -0
  48. package/fixtures/content-model-v2/dist/images/generated/routes/010-guide/images/intro/duplicate-5cf614d2-768.webp +0 -0
  49. package/fixtures/content-model-v2/dist/images/generated/routes/010-guide/images/intro/duplicate-5cf614d2-960.webp +0 -0
  50. package/fixtures/content-model-v2/dist/images/generated/timed/slide-one-3770d763-1080.webp +0 -0
  51. package/fixtures/content-model-v2/dist/images/generated/timed/slide-one-3770d763-1440.webp +0 -0
  52. package/fixtures/content-model-v2/dist/images/generated/timed/slide-one-3770d763-1600.webp +0 -0
  53. package/fixtures/content-model-v2/dist/images/generated/timed/slide-one-3770d763-480.webp +0 -0
  54. package/fixtures/content-model-v2/dist/images/generated/timed/slide-one-3770d763-768.webp +0 -0
  55. package/fixtures/content-model-v2/dist/images/generated/timed/slide-three-5bdec65e-1080.webp +0 -0
  56. package/fixtures/content-model-v2/dist/images/generated/timed/slide-three-5bdec65e-1440.webp +0 -0
  57. package/fixtures/content-model-v2/dist/images/generated/timed/slide-three-5bdec65e-1600.webp +0 -0
  58. package/fixtures/content-model-v2/dist/images/generated/timed/slide-three-5bdec65e-480.webp +0 -0
  59. package/fixtures/content-model-v2/dist/images/generated/timed/slide-three-5bdec65e-768.webp +0 -0
  60. package/fixtures/content-model-v2/dist/images/generated/timed/slide-two-26c08aee-1080.webp +0 -0
  61. package/fixtures/content-model-v2/dist/images/generated/timed/slide-two-26c08aee-1440.webp +0 -0
  62. package/fixtures/content-model-v2/dist/images/generated/timed/slide-two-26c08aee-1600.webp +0 -0
  63. package/fixtures/content-model-v2/dist/images/generated/timed/slide-two-26c08aee-480.webp +0 -0
  64. package/fixtures/content-model-v2/dist/images/generated/timed/slide-two-26c08aee-768.webp +0 -0
  65. package/fixtures/content-model-v2/dist/index.html +8 -0
  66. package/fixtures/content-model-v2/node_modules/.vite/deps/_metadata.json +80 -0
  67. package/fixtures/content-model-v2/node_modules/.vite/deps/astro-D_GIpJIE.js +434 -0
  68. package/fixtures/content-model-v2/node_modules/.vite/deps/astro-D_GIpJIE.js.map +1 -0
  69. package/fixtures/content-model-v2/node_modules/.vite/deps/astro_n_aria-query.js +6390 -0
  70. package/fixtures/content-model-v2/node_modules/.vite/deps/astro_n_aria-query.js.map +1 -0
  71. package/fixtures/content-model-v2/node_modules/.vite/deps/astro_n_axobject-query.js +2702 -0
  72. package/fixtures/content-model-v2/node_modules/.vite/deps/astro_n_axobject-query.js.map +1 -0
  73. package/fixtures/content-model-v2/node_modules/.vite/deps/astro_n_html-escaper.js +65 -0
  74. package/fixtures/content-model-v2/node_modules/.vite/deps/astro_n_html-escaper.js.map +1 -0
  75. package/fixtures/content-model-v2/node_modules/.vite/deps/astro_runtime_client_dev-toolbar_entrypoint__js.js +455 -0
  76. package/fixtures/content-model-v2/node_modules/.vite/deps/astro_runtime_client_dev-toolbar_entrypoint__js.js.map +1 -0
  77. package/fixtures/content-model-v2/node_modules/.vite/deps/audit-DM9Hkl5B.js +1534 -0
  78. package/fixtures/content-model-v2/node_modules/.vite/deps/audit-DM9Hkl5B.js.map +1 -0
  79. package/fixtures/content-model-v2/node_modules/.vite/deps/embla-carousel.js +1389 -0
  80. package/fixtures/content-model-v2/node_modules/.vite/deps/embla-carousel.js.map +1 -0
  81. package/fixtures/content-model-v2/node_modules/.vite/deps/highlight-DnZ1ULOL.js +48 -0
  82. package/fixtures/content-model-v2/node_modules/.vite/deps/highlight-DnZ1ULOL.js.map +1 -0
  83. package/fixtures/content-model-v2/node_modules/.vite/deps/icons-RyebKi45.js +42 -0
  84. package/fixtures/content-model-v2/node_modules/.vite/deps/icons-RyebKi45.js.map +1 -0
  85. package/fixtures/content-model-v2/node_modules/.vite/deps/package.json +3 -0
  86. package/fixtures/content-model-v2/node_modules/.vite/deps/rolldown-runtime-BvCyGRYZ.js +4 -0
  87. package/fixtures/content-model-v2/node_modules/.vite/deps/settings-DaU-gNnK.js +190 -0
  88. package/fixtures/content-model-v2/node_modules/.vite/deps/settings-DaU-gNnK.js.map +1 -0
  89. package/fixtures/content-model-v2/node_modules/.vite/deps/toolbar-63PA619H.js +458 -0
  90. package/fixtures/content-model-v2/node_modules/.vite/deps/toolbar-63PA619H.js.map +1 -0
  91. package/fixtures/content-model-v2/node_modules/.vite/deps/ui-library--bkcNSYz.js +1016 -0
  92. package/fixtures/content-model-v2/node_modules/.vite/deps/ui-library--bkcNSYz.js.map +1 -0
  93. package/fixtures/content-model-v2/node_modules/.vite/deps/window-jPkpKVcy.js +32 -0
  94. package/fixtures/content-model-v2/node_modules/.vite/deps/window-jPkpKVcy.js.map +1 -0
  95. package/fixtures/content-model-v2/node_modules/.vite/deps/xray-BXCHpEJP.js +111 -0
  96. package/fixtures/content-model-v2/node_modules/.vite/deps/xray-BXCHpEJP.js.map +1 -0
  97. package/fixtures/content-model-v2/site/.norna/generated-images.json +210 -0
  98. package/fixtures/content-model-v2/site/config.mjs +11 -0
  99. package/fixtures/content-model-v2/site/content.md +84 -0
  100. package/fixtures/content-model-v2/site/images/card-section/adopt.svg +9 -0
  101. package/fixtures/content-model-v2/site/images/card-section/foster.svg +12 -0
  102. package/fixtures/content-model-v2/site/images/intro/detail.jpg +0 -0
  103. package/fixtures/content-model-v2/site/images/intro/duplicate.jpg +0 -0
  104. package/fixtures/content-model-v2/site/images/intro/hero.jpg +0 -0
  105. package/fixtures/content-model-v2/site/images/plain/image.jpg +0 -0
  106. package/fixtures/content-model-v2/site/images/timed/slide-one.jpg +0 -0
  107. package/fixtures/content-model-v2/site/images/timed/slide-three.jpg +0 -0
  108. package/fixtures/content-model-v2/site/images/timed/slide-two.jpg +0 -0
  109. package/fixtures/content-model-v2/site/routes/010-guide/images/intro/duplicate.jpg +0 -0
  110. package/fixtures/content-model-v2/site/routes/010-guide/route-content.md +17 -0
  111. package/fixtures/content-model-v2/site/theme.md +9 -0
  112. package/package.json +3 -2
  113. package/scripts/deploy-site.mjs +11 -4
  114. package/scripts/dev-local.mjs +6 -0
  115. package/scripts/generate-images.mjs +132 -56
  116. package/scripts/lib/image-dimensions.mjs +26 -0
  117. package/scripts/lib/norna-markdown-blocks.mjs +643 -0
  118. package/scripts/lib/site-content.mjs +31 -29
  119. package/scripts/show-typography.mjs +17 -9
  120. package/scripts/sync-content-sections.mjs +280 -411
  121. package/scripts/test-content-check.mjs +59 -45
  122. package/scripts/test-content-model-v2.mjs +998 -0
  123. package/scripts/test-engine-commands.mjs +1 -1
  124. package/scripts/test-package-check.mjs +36 -8
  125. package/scripts/test-temporary-visibility.mjs +3 -6
  126. package/src/components/CardList.astro +77 -0
  127. package/src/components/GalleryGrid.astro +22 -12
  128. package/src/components/SiteNavigation.astro +5 -4
  129. package/src/components/SitePage.astro +9 -2
  130. package/src/components/SiteSection.astro +35 -13
  131. package/src/content.config.ts +4 -17
  132. package/src/lib/generatedImages.ts +50 -10
  133. package/src/lib/sectionContent.ts +130 -35
  134. package/src/styles/global.css +187 -0
  135. package/starters/basic/site/content.md +10 -6
  136. package/starters/project/site/content.md +0 -9
  137. package/starters/project/site/routes/010-guide/route-content.md +0 -5
@@ -0,0 +1,175 @@
1
+ declare module 'astro:content' {
2
+ export interface RenderResult {
3
+ Content: import('astro/runtime/server/index.js').AstroComponentFactory;
4
+ headings: import('astro').MarkdownHeading[];
5
+ remarkPluginFrontmatter: Record<string, any>;
6
+ }
7
+ interface Render {
8
+ '.md': Promise<RenderResult>;
9
+ }
10
+
11
+ export interface RenderedContent {
12
+ html: string;
13
+ metadata?: {
14
+ imagePaths: Array<string>;
15
+ [key: string]: unknown;
16
+ };
17
+ }
18
+
19
+ type Flatten<T> = T extends { [K: string]: infer U } ? U : never;
20
+
21
+ export type CollectionKey = keyof DataEntryMap;
22
+ export type CollectionEntry<C extends CollectionKey> = Flatten<DataEntryMap[C]>;
23
+
24
+ type AllValuesOf<T> = T extends any ? T[keyof T] : never;
25
+
26
+ export type ReferenceDataEntry<
27
+ C extends CollectionKey,
28
+ E extends keyof DataEntryMap[C] = string,
29
+ > = {
30
+ collection: C;
31
+ id: E;
32
+ };
33
+
34
+ export type ReferenceLiveEntry<C extends keyof LiveContentConfig['collections']> = {
35
+ collection: C;
36
+ id: string;
37
+ };
38
+
39
+ export function getCollection<C extends keyof DataEntryMap, E extends CollectionEntry<C>>(
40
+ collection: C,
41
+ filter?: (entry: CollectionEntry<C>) => entry is E,
42
+ ): Promise<E[]>;
43
+ export function getCollection<C extends keyof DataEntryMap>(
44
+ collection: C,
45
+ filter?: (entry: CollectionEntry<C>) => unknown,
46
+ ): Promise<CollectionEntry<C>[]>;
47
+
48
+ export function getLiveCollection<C extends keyof LiveContentConfig['collections']>(
49
+ collection: C,
50
+ filter?: LiveLoaderCollectionFilterType<C>,
51
+ ): Promise<
52
+ import('astro').LiveDataCollectionResult<LiveLoaderDataType<C>, LiveLoaderErrorType<C>>
53
+ >;
54
+
55
+ export function getEntry<
56
+ C extends keyof DataEntryMap,
57
+ E extends keyof DataEntryMap[C] | (string & {}),
58
+ >(
59
+ entry: ReferenceDataEntry<C, E>,
60
+ ): E extends keyof DataEntryMap[C]
61
+ ? Promise<DataEntryMap[C][E]>
62
+ : Promise<CollectionEntry<C> | undefined>;
63
+ export function getEntry<
64
+ C extends keyof DataEntryMap,
65
+ E extends keyof DataEntryMap[C] | (string & {}),
66
+ >(
67
+ collection: C,
68
+ id: E,
69
+ ): E extends keyof DataEntryMap[C]
70
+ ? string extends keyof DataEntryMap[C]
71
+ ? Promise<DataEntryMap[C][E]> | undefined
72
+ : Promise<DataEntryMap[C][E]>
73
+ : Promise<CollectionEntry<C> | undefined>;
74
+ export function getLiveEntry<C extends keyof LiveContentConfig['collections']>(
75
+ collection: C,
76
+ filter: string | LiveLoaderEntryFilterType<C>,
77
+ ): Promise<import('astro').LiveDataEntryResult<LiveLoaderDataType<C>, LiveLoaderErrorType<C>>>;
78
+
79
+ /** Resolve an array of entry references from the same collection */
80
+ export function getEntries<C extends keyof DataEntryMap>(
81
+ entries: ReferenceDataEntry<C, keyof DataEntryMap[C]>[],
82
+ ): Promise<CollectionEntry<C>[]>;
83
+
84
+ export function render<C extends keyof DataEntryMap>(
85
+ entry: DataEntryMap[C][string],
86
+ ): Promise<RenderResult>;
87
+
88
+ export function render<C extends keyof LiveContentConfig['collections']>(
89
+ entry: import('astro').LiveDataEntry<LiveLoaderDataType<C>>,
90
+ ): Promise<RenderResult>;
91
+
92
+ export function reference<
93
+ C extends
94
+ | keyof DataEntryMap
95
+ // Allow generic `string` to avoid excessive type errors in the config
96
+ // if `dev` is not running to update as you edit.
97
+ // Invalid collection names will be caught at build time.
98
+ | (string & {}),
99
+ >(
100
+ collection: C,
101
+ ): import('astro/zod').ZodPipe<
102
+ import('astro/zod').ZodString,
103
+ import('astro/zod').ZodTransform<
104
+ C extends keyof DataEntryMap
105
+ ? {
106
+ collection: C;
107
+ id: string;
108
+ }
109
+ : never,
110
+ string
111
+ >
112
+ >;
113
+
114
+ type ReturnTypeOrOriginal<T> = T extends (...args: any[]) => infer R ? R : T;
115
+ type InferEntrySchema<C extends keyof DataEntryMap> = import('astro/zod').infer<
116
+ ReturnTypeOrOriginal<Required<ContentConfig['collections'][C]>['schema']>
117
+ >;
118
+ type ExtractLoaderConfig<T> = T extends { loader: infer L } ? L : never;
119
+ type InferLoaderSchema<
120
+ C extends keyof DataEntryMap,
121
+ L = ExtractLoaderConfig<ContentConfig['collections'][C]>,
122
+ > = L extends { schema: import('astro/zod').ZodSchema }
123
+ ? import('astro/zod').infer<L['schema']>
124
+ : any;
125
+
126
+ type DataEntryMap = {
127
+ "site": Record<string, {
128
+ id: string;
129
+ body?: string;
130
+ collection: "site";
131
+ data: InferEntrySchema<"site">;
132
+ rendered?: RenderedContent;
133
+ filePath?: string;
134
+ }>;
135
+ "theme": Record<string, {
136
+ id: string;
137
+ body?: string;
138
+ collection: "theme";
139
+ data: InferEntrySchema<"theme">;
140
+ rendered?: RenderedContent;
141
+ filePath?: string;
142
+ }>;
143
+
144
+ };
145
+
146
+ type ExtractLoaderTypes<T> = T extends import('astro/loaders').LiveLoader<
147
+ infer TData,
148
+ infer TEntryFilter,
149
+ infer TCollectionFilter,
150
+ infer TError
151
+ >
152
+ ? { data: TData; entryFilter: TEntryFilter; collectionFilter: TCollectionFilter; error: TError }
153
+ : { data: never; entryFilter: never; collectionFilter: never; error: never };
154
+ type ExtractEntryFilterType<T> = ExtractLoaderTypes<T>['entryFilter'];
155
+ type ExtractCollectionFilterType<T> = ExtractLoaderTypes<T>['collectionFilter'];
156
+ type ExtractErrorType<T> = ExtractLoaderTypes<T>['error'];
157
+ type ExtractDataType<T> = ExtractLoaderTypes<T>['data'];
158
+
159
+ type LiveLoaderDataType<C extends keyof LiveContentConfig['collections']> =
160
+ LiveContentConfig['collections'][C]['schema'] extends undefined
161
+ ? ExtractDataType<LiveContentConfig['collections'][C]['loader']>
162
+ : import('astro/zod').infer<
163
+ Exclude<LiveContentConfig['collections'][C]['schema'], undefined>
164
+ >;
165
+ type LiveLoaderEntryFilterType<C extends keyof LiveContentConfig['collections']> =
166
+ ExtractEntryFilterType<LiveContentConfig['collections'][C]['loader']>;
167
+ type LiveLoaderCollectionFilterType<C extends keyof LiveContentConfig['collections']> =
168
+ ExtractCollectionFilterType<LiveContentConfig['collections'][C]['loader']>;
169
+ type LiveLoaderErrorType<C extends keyof LiveContentConfig['collections']> = ExtractErrorType<
170
+ LiveContentConfig['collections'][C]['loader']
171
+ >;
172
+
173
+ export type ContentConfig = typeof import("../../../src/content.config.js");
174
+ export type LiveContentConfig = never;
175
+ }
@@ -0,0 +1 @@
1
+ [["Map",1,2,9,10,79,80],"meta::meta",["Map",3,4,5,6,7,8],"astro-config-digest","{\"root\":{},\"srcDir\":{},\"publicDir\":{},\"outDir\":{},\"cacheDir\":{},\"compressHTML\":\"jsx\",\"base\":\"/\",\"trailingSlash\":\"ignore\",\"output\":\"static\",\"scopedStyleStrategy\":\"attribute\",\"build\":{\"format\":\"directory\",\"client\":{},\"server\":{},\"assets\":\"_astro\",\"serverEntry\":\"entry.mjs\",\"redirects\":true,\"inlineStylesheets\":\"auto\",\"concurrency\":1},\"server\":{\"open\":false,\"host\":\"127.0.0.1\",\"port\":4321,\"allowedHosts\":[\"127.0.0.1\",\"127.0.0.1\",\"127.0.0.1\",\"127.0.0.1\"]},\"redirects\":{},\"image\":{\"endpoint\":{\"route\":\"/_image\"},\"service\":{\"entrypoint\":\"astro/assets/services/sharp\",\"config\":{}},\"dangerouslyProcessSVG\":false,\"domains\":[],\"remotePatterns\":[],\"responsiveStyles\":false},\"devToolbar\":{\"enabled\":true},\"markdown\":{\"syntaxHighlight\":{\"type\":\"shiki\",\"excludeLangs\":[\"math\"]},\"shikiConfig\":{\"langs\":[],\"langAlias\":{},\"theme\":\"github-dark\",\"themes\":{},\"wrap\":false,\"transformers\":[]},\"remarkPlugins\":[],\"rehypePlugins\":[],\"remarkRehype\":{},\"processor\":{\"name\":\"satteri\",\"options\":{\"mdastPlugins\":[],\"hastPlugins\":[],\"features\":{}}}},\"security\":{\"checkOrigin\":true,\"allowedDomains\":[],\"csp\":false,\"actionBodySizeLimit\":1048576,\"serverIslandBodySizeLimit\":1048576},\"env\":{\"schema\":{},\"validateSecrets\":false},\"prerenderConflictBehavior\":\"warn\",\"fetchFile\":\"fetch\",\"experimental\":{\"clientPrerender\":false,\"contentIntellisense\":false,\"chromeDevtoolsWorkspace\":false,\"collectionStorage\":\"single-file\"},\"legacy\":{\"collectionsBackwardsCompat\":false}}","astro-version","7.1.3","content-config-digest","ccc39d7fb56a7431","site",["Map",11,12,59,60],"site-content",{"id":11,"data":13,"body":25,"filePath":26,"digest":27,"rendered":28},{"title":14,"description":15,"sections":16},"Content Model v2 Fixture","Internal fixture for Markdown-authoritative Norna content.",{"intro":17,"timed":21},{"presentation":18},{"typography":19},{"preset":20},"statement",{"visible":22},{"from":23,"until":24},"2026-01-01","2027-01-01","## Intro {#intro}\n\nThis fixture validates that Markdown defines sections and that section metadata\nis optional. It also checks [inline styles]{.highlight}.\n\n```norna-image-stack\n- image: hero.jpg\n alt: A black Labrador-type dog sitting on grass.\n caption: Dog portrait one: a black Labrador-type dog.\n```\n\n### Subhead, but not a new section\n\nText can continue after a Norna-managed image.\n\n```norna-image-stack\n- image: detail.jpg\n alt: A small tan terrier-type dog standing in grass.\n caption: Dog portrait two: a small tan terrier-type dog.\n- image: duplicate.jpg\n alt: A white and brown border collie-type dog sitting outdoors.\n caption: Dog portrait three: a white and brown border collie-type dog.\n```\n\n## Timed section {#timed}\n\nThis section uses frontmatter metadata without duplicating section order.\n\n```norna-image-carousel\n- image: slide-one.jpg\n alt: A russet-brown dog beginning a gallop in a grassy field.\n caption: Gallop phase one: push-off.\n- image: slide-two.jpg\n alt: The same russet-brown dog fully extended in mid-gallop.\n caption: Gallop phase two: suspension.\n- image: slide-three.jpg\n alt: The same russet-brown dog landing during a gallop.\n caption: Gallop phase three: landing.\n```\n\n## Plain section {#plain}\n\nThis section has no frontmatter metadata.\n\n```norna-image-stack\n- image: image.jpg\n caption: a dog\n```\n\n## Card section {#card-section}\n\nCards are very limited but may be developed in the future.\n\n```norna-card-list\nlayout: image-right\nflow: stack\nsize: s\nwidth: narrow\n\n- title: Adopt\n text: A card can combine a short label, supporting text, a managed SVG image and an optional link.\n image: adopt.svg\n link: /guide/\n badge-text: Recommended\n- title: Foster\n text: Cards without links use the same visual structure.\n image: foster.svg\n- title: Donate\n text: Cards may also be text-only when no image is needed.\n```","site/content.md","43b471faae9ddc04",{"html":29,"metadata":30},"\u003Ch2 id=\"intro-intro\">Intro {#intro}\u003C/h2>\n\u003Cp>This fixture validates that Markdown defines sections and that section metadata\nis optional. It also checks [inline styles]{.highlight}.\u003C/p>\n\u003Cpre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"plaintext\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan>- image: hero.jpg\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan> alt: A black Labrador-type dog sitting on grass.\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan> caption: Dog portrait one: a black Labrador-type dog.\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Ch3 id=\"subhead-but-not-a-new-section\">Subhead, but not a new section\u003C/h3>\n\u003Cp>Text can continue after a Norna-managed image.\u003C/p>\n\u003Cpre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"plaintext\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan>- image: detail.jpg\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan> alt: A small tan terrier-type dog standing in grass.\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan> caption: Dog portrait two: a small tan terrier-type dog.\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan>- image: duplicate.jpg\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan> alt: A white and brown border collie-type dog sitting outdoors.\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan> caption: Dog portrait three: a white and brown border collie-type dog.\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Ch2 id=\"timed-section-timed\">Timed section {#timed}\u003C/h2>\n\u003Cp>This section uses frontmatter metadata without duplicating section order.\u003C/p>\n\u003Cpre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"plaintext\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan>- image: slide-one.jpg\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan> alt: A russet-brown dog beginning a gallop in a grassy field.\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan> caption: Gallop phase one: push-off.\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan>- image: slide-two.jpg\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan> alt: The same russet-brown dog fully extended in mid-gallop.\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan> caption: Gallop phase two: suspension.\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan>- image: slide-three.jpg\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan> alt: The same russet-brown dog landing during a gallop.\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan> caption: Gallop phase three: landing.\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Ch2 id=\"plain-section-plain\">Plain section {#plain}\u003C/h2>\n\u003Cp>This section has no frontmatter metadata.\u003C/p>\n\u003Cpre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"plaintext\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan>- image: image.jpg\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan> caption: a dog\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n\u003Ch2 id=\"card-section-card-section\">Card section {#card-section}\u003C/h2>\n\u003Cp>Cards are very limited but may be developed in the future.\u003C/p>\n\u003Cpre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"plaintext\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan>layout: image-right\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan>flow: stack\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan>size: s\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan>width: narrow\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan>\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan>- title: Adopt\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan> text: A card can combine a short label, supporting text, a managed SVG image and an optional link.\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan> image: adopt.svg\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan> link: /guide/\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan> badge-text: Recommended\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan>- title: Foster\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan> text: Cards without links use the same visual structure.\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan> image: foster.svg\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan>- title: Donate\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan> text: Cards may also be text-only when no image is needed.\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n",{"headings":31,"localImagePaths":49,"remoteImagePaths":50,"frontmatter":51,"imagePaths":58},[32,36,40,43,46],{"depth":33,"slug":34,"text":35},2,"intro-intro","Intro {#intro}",{"depth":37,"slug":38,"text":39},3,"subhead-but-not-a-new-section","Subhead, but not a new section",{"depth":33,"slug":41,"text":42},"timed-section-timed","Timed section {#timed}",{"depth":33,"slug":44,"text":45},"plain-section-plain","Plain section {#plain}",{"depth":33,"slug":47,"text":48},"card-section-card-section","Card section {#card-section}",[],[],{"title":14,"description":15,"sections":52},{"intro":53,"timed":56},{"presentation":54},{"typography":55},{"preset":20},{"visible":57},{"from":23,"until":24},[],"site-route-010-guide",{"id":59,"data":61,"body":66,"filePath":67,"digest":68,"rendered":69},{"title":62,"description":63,"navigation":64,"sections":65},"Guide","Internal route fixture for content model v2.",{"label":62},{},"## Intro {#intro}\n\nRoutes may use the same section id and image filename as other pages without\nmaking the site invalid.\n\n```norna-image-stack\n- image: duplicate.jpg\n alt: A route-local duplicated filename.\n caption: This file is resolved in the route image root.\n```","site/routes/010-guide/route-content.md","1b981a1b59c8d88c",{"html":70,"metadata":71},"\u003Ch2 id=\"intro-intro\">Intro {#intro}\u003C/h2>\n\u003Cp>Routes may use the same section id and image filename as other pages without\nmaking the site invalid.\u003C/p>\n\u003Cpre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"plaintext\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan>- image: duplicate.jpg\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan> alt: A route-local duplicated filename.\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan> caption: This file is resolved in the route image root.\u003C/span>\u003C/span>\u003C/code>\u003C/pre>\n",{"headings":72,"localImagePaths":74,"remoteImagePaths":75,"frontmatter":76,"imagePaths":78},[73],{"depth":33,"slug":34,"text":35},[],[],{"title":62,"description":63,"navigation":77},{"label":62},[],"theme",["Map",81,82],"site-theme",{"id":81,"data":83,"filePath":91,"digest":92,"rendered":93},{"typography":84,"presentation":87},{"preset":85,"rhythm":86},"text-forward","normal",{"inlineStyles":88},{"highlight":89},{"color":90},"#b3261e","site/theme.md","fd242f12efaaba1f",{"html":94,"metadata":95},"",{"headings":96,"localImagePaths":97,"remoteImagePaths":98,"frontmatter":99,"imagePaths":104},[],[],[],{"typography":100,"presentation":101},{"preset":85,"rhythm":86},{"inlineStyles":102},{"highlight":103},{"color":90},[]]
@@ -0,0 +1,8 @@
1
+ {
2
+ "pid": 96271,
3
+ "port": 4321,
4
+ "host": "127.0.0.1",
5
+ "mode": "local",
6
+ "url": "http://127.0.0.1:4321/",
7
+ "startedAt": "2026-08-12T07:28:27.466Z"
8
+ }
@@ -0,0 +1,13 @@
1
+ {
2
+ "pid": 96271,
3
+ "port": 4321,
4
+ "url": "http://127.0.0.1:4321",
5
+ "urls": {
6
+ "local": [
7
+ "http://127.0.0.1:4321/"
8
+ ],
9
+ "network": []
10
+ },
11
+ "background": true,
12
+ "startedAt": "2026-08-12T07:28:27.184Z"
13
+ }
@@ -0,0 +1,231 @@
1
+ 09:28:26 [vite] connected.
2
+ 09:28:26 [types] Generated 0ms
3
+ 09:28:26 [vite] connected.
4
+ 09:28:27 [content] Syncing content
5
+ 09:28:27 [content] Astro config changed
6
+ 09:28:27 [content] Clearing content store
7
+ [Shiki] The language "norna-image-stack" doesn't exist, falling back to "plaintext".
8
+ [Shiki] The language "norna-image-stack" doesn't exist, falling back to "plaintext".
9
+ [Shiki] The language "norna-image-stack" doesn't exist, falling back to "plaintext".
10
+ [Shiki] The language "norna-image-carousel" doesn't exist, falling back to "plaintext".
11
+ [Shiki] The language "norna-image-stack" doesn't exist, falling back to "plaintext".
12
+ [Shiki] The language "norna-card-list" doesn't exist, falling back to "plaintext".
13
+ 09:28:27 [content] Synced content
14
+ astro v7.1.3 ready in 1141 ms
15
+ ┃ Local http://127.0.0.1:4321/
16
+ 09:28:27 watching for file changes...
17
+ 09:28:27 [200] / 51ms
18
+ 09:28:27 [200] / 5ms
19
+ 09:28:27 [200] / 7ms
20
+ 09:28:39 [glob-loader] Reloaded data from content.md
21
+ 09:28:40 [200] / 14ms
22
+ [Shiki] The language "norna-image-stack" doesn't exist, falling back to "plaintext".
23
+ [Shiki] The language "norna-image-stack" doesn't exist, falling back to "plaintext".
24
+ [Shiki] The language "norna-image-carousel" doesn't exist, falling back to "plaintext".
25
+ [Shiki] The language "norna-image-stack" doesn't exist, falling back to "plaintext".
26
+ [Shiki] The language "norna-card-list" doesn't exist, falling back to "plaintext".
27
+ 09:29:08 [glob-loader] Reloaded data from content.md
28
+ 09:29:09 [200] / 14ms
29
+ [Shiki] The language "norna-image-stack" doesn't exist, falling back to "plaintext".
30
+ [Shiki] The language "norna-image-stack" doesn't exist, falling back to "plaintext".
31
+ [Shiki] The language "norna-image-carousel" doesn't exist, falling back to "plaintext".
32
+ [Shiki] The language "norna-image-stack" doesn't exist, falling back to "plaintext".
33
+ [Shiki] The language "norna-card-list" doesn't exist, falling back to "plaintext".
34
+ 09:29:26 [glob-loader] Reloaded data from content.md
35
+ 09:29:27 [200] / 6ms
36
+ 09:29:27 [200] / 13ms
37
+ [Shiki] The language "norna-image-stack" doesn't exist, falling back to "plaintext".
38
+ [Shiki] The language "norna-image-stack" doesn't exist, falling back to "plaintext".
39
+ [Shiki] The language "norna-image-carousel" doesn't exist, falling back to "plaintext".
40
+ [Shiki] The language "norna-image-stack" doesn't exist, falling back to "plaintext".
41
+ [Shiki] The language "norna-card-list" doesn't exist, falling back to "plaintext".
42
+ 09:29:48 [glob-loader] Reloaded data from content.md
43
+ 09:29:49 [200] / 4ms
44
+ 09:29:49 [200] / 7ms
45
+ 09:30:08 [404] /norna/concepts/ 4ms
46
+ [Shiki] The language "norna-image-stack" doesn't exist, falling back to "plaintext".
47
+ [Shiki] The language "norna-image-stack" doesn't exist, falling back to "plaintext".
48
+ [Shiki] The language "norna-image-carousel" doesn't exist, falling back to "plaintext".
49
+ [Shiki] The language "norna-image-stack" doesn't exist, falling back to "plaintext".
50
+ [Shiki] The language "norna-card-list" doesn't exist, falling back to "plaintext".
51
+ 09:38:28 [glob-loader] Reloaded data from content.md
52
+ 09:38:28 [200] / 21ms
53
+ [Shiki] The language "norna-image-stack" doesn't exist, falling back to "plaintext".
54
+ [Shiki] The language "norna-image-stack" doesn't exist, falling back to "plaintext".
55
+ [Shiki] The language "norna-image-carousel" doesn't exist, falling back to "plaintext".
56
+ [Shiki] The language "norna-image-stack" doesn't exist, falling back to "plaintext".
57
+ [Shiki] The language "norna-card-list" doesn't exist, falling back to "plaintext".
58
+ 09:39:05 [glob-loader] Reloaded data from content.md
59
+ 09:39:05 [200] / 4ms
60
+ 09:39:05 [200] / 9ms
61
+ [Shiki] The language "norna-image-stack" doesn't exist, falling back to "plaintext".
62
+ [Shiki] The language "norna-image-stack" doesn't exist, falling back to "plaintext".
63
+ [Shiki] The language "norna-image-carousel" doesn't exist, falling back to "plaintext".
64
+ [Shiki] The language "norna-image-stack" doesn't exist, falling back to "plaintext".
65
+ [Shiki] The language "norna-card-list" doesn't exist, falling back to "plaintext".
66
+ 09:39:14 [glob-loader] Reloaded data from content.md
67
+ 09:39:14 [ERROR] [vite] Norna image refresh failed:
68
+ Command failed: /opt/homebrew/Cellar/node/26.7.0/bin/node /Users/jangarefelt/Projects/webbhack/norna/scripts/generate-images.mjs
69
+ file:///Users/jangarefelt/Projects/webbhack/norna/scripts/lib/norna-markdown-blocks.mjs:43
70
+ throw new Error(location ? `${location}: ${message}` : message);
71
+ ^
72
+
73
+ Error: site/content.md line 6: Invalid norna-card-list layout "image-bottom". Use one of: image-top, image-left, image-right.
74
+ at fail (file:///Users/jangarefelt/Projects/webbhack/norna/scripts/lib/norna-markdown-blocks.mjs:43:8)
75
+ at parseCardListBlock (file:///Users/jangarefelt/Projects/webbhack/norna/scripts/lib/norna-markdown-blocks.mjs:323:6)
76
+ at parseNornaMarkdownBlock (file:///Users/jangarefelt/Projects/webbhack/norna/scripts/lib/norna-markdown-blocks.mjs:393:5)
77
+ at extractNornaMarkdownBlocks (file:///Users/jangarefelt/Projects/webbhack/norna/scripts/lib/norna-markdown-blocks.mjs:409:7)
78
+ at getReferencedImages (file:///Users/jangarefelt/Projects/webbhack/norna/scripts/generate-images.mjs:123:18)
79
+ at async getReferencedSources (file:///Users/jangarefelt/Projects/webbhack/norna/scripts/generate-images.mjs:158:22)
80
+ at async file:///Users/jangarefelt/Projects/webbhack/norna/scripts/generate-images.mjs:372:17
81
+
82
+ Node.js v26.7.0
83
+
84
+ 09:39:15 [ERROR] Error: line 6: Invalid norna-card-list layout "image-bottom". Use one of: image-top, image-left, image-right.
85
+ at fail (/Users/jangarefelt/Projects/webbhack/norna/scripts/lib/norna-markdown-blocks.mjs:43:8)
86
+ at parseCardListBlock (/Users/jangarefelt/Projects/webbhack/norna/scripts/lib/norna-markdown-blocks.mjs:323:6)
87
+ at parseNornaMarkdownBlock (/Users/jangarefelt/Projects/webbhack/norna/scripts/lib/norna-markdown-blocks.mjs:393:5)
88
+ at extractNornaMarkdownBlocks (/Users/jangarefelt/Projects/webbhack/norna/scripts/lib/norna-markdown-blocks.mjs:409:7)
89
+ at resolveContentBlocks (/Users/jangarefelt/Projects/webbhack/norna/src/lib/sectionContent.ts:137:20)
90
+ at getSectionsContent (/Users/jangarefelt/Projects/webbhack/norna/src/lib/sectionContent.ts:210:19)
91
+ at eval (/Users/jangarefelt/Projects/webbhack/norna/src/components/SitePage.astro:44:1)
92
+ 09:39:15 [ERROR] line 6: Invalid norna-card-list layout "image-bottom". Use one of: image-top, image-left, image-right.
93
+ Stack trace:
94
+ at /Users/jangarefelt/Projects/webbhack/norna/fixtures/content-model-v2/Users/jangarefelt/Projects/webbhack/norna/src/lib/sectionContent.ts:137:20
95
+ [...] See full stack trace in the browser, or rerun with --verbose.
96
+ [Shiki] The language "norna-image-stack" doesn't exist, falling back to "plaintext".
97
+ [Shiki] The language "norna-image-stack" doesn't exist, falling back to "plaintext".
98
+ [Shiki] The language "norna-image-carousel" doesn't exist, falling back to "plaintext".
99
+ [Shiki] The language "norna-image-stack" doesn't exist, falling back to "plaintext".
100
+ [Shiki] The language "norna-card-list" doesn't exist, falling back to "plaintext".
101
+ 09:39:22 [glob-loader] Reloaded data from content.md
102
+ 09:39:23 [ERROR] [vite] Norna image refresh failed:
103
+ Command failed: /opt/homebrew/Cellar/node/26.7.0/bin/node /Users/jangarefelt/Projects/webbhack/norna/scripts/generate-images.mjs
104
+ file:///Users/jangarefelt/Projects/webbhack/norna/scripts/lib/norna-markdown-blocks.mjs:43
105
+ throw new Error(location ? `${location}: ${message}` : message);
106
+ ^
107
+
108
+ Error: site/content.md line 6: Invalid norna-card-list layout "image-down". Use one of: image-top, image-left, image-right.
109
+ at fail (file:///Users/jangarefelt/Projects/webbhack/norna/scripts/lib/norna-markdown-blocks.mjs:43:8)
110
+ at parseCardListBlock (file:///Users/jangarefelt/Projects/webbhack/norna/scripts/lib/norna-markdown-blocks.mjs:323:6)
111
+ at parseNornaMarkdownBlock (file:///Users/jangarefelt/Projects/webbhack/norna/scripts/lib/norna-markdown-blocks.mjs:393:5)
112
+ at extractNornaMarkdownBlocks (file:///Users/jangarefelt/Projects/webbhack/norna/scripts/lib/norna-markdown-blocks.mjs:409:7)
113
+ at getReferencedImages (file:///Users/jangarefelt/Projects/webbhack/norna/scripts/generate-images.mjs:123:18)
114
+ at async getReferencedSources (file:///Users/jangarefelt/Projects/webbhack/norna/scripts/generate-images.mjs:158:22)
115
+ at async file:///Users/jangarefelt/Projects/webbhack/norna/scripts/generate-images.mjs:372:17
116
+
117
+ Node.js v26.7.0
118
+
119
+ 09:39:23 [ERROR] Error: line 6: Invalid norna-card-list layout "image-down". Use one of: image-top, image-left, image-right.
120
+ at fail (/Users/jangarefelt/Projects/webbhack/norna/scripts/lib/norna-markdown-blocks.mjs:43:8)
121
+ at parseCardListBlock (/Users/jangarefelt/Projects/webbhack/norna/scripts/lib/norna-markdown-blocks.mjs:323:6)
122
+ at parseNornaMarkdownBlock (/Users/jangarefelt/Projects/webbhack/norna/scripts/lib/norna-markdown-blocks.mjs:393:5)
123
+ at extractNornaMarkdownBlocks (/Users/jangarefelt/Projects/webbhack/norna/scripts/lib/norna-markdown-blocks.mjs:409:7)
124
+ at resolveContentBlocks (/Users/jangarefelt/Projects/webbhack/norna/src/lib/sectionContent.ts:137:20)
125
+ at getSectionsContent (/Users/jangarefelt/Projects/webbhack/norna/src/lib/sectionContent.ts:210:19)
126
+ at eval (/Users/jangarefelt/Projects/webbhack/norna/src/components/SitePage.astro:44:1)
127
+ 09:39:23 [ERROR] line 6: Invalid norna-card-list layout "image-down". Use one of: image-top, image-left, image-right.
128
+ Stack trace:
129
+ at /Users/jangarefelt/Projects/webbhack/norna/fixtures/content-model-v2/Users/jangarefelt/Projects/webbhack/norna/src/lib/sectionContent.ts:137:20
130
+ [...] See full stack trace in the browser, or rerun with --verbose.
131
+ 09:39:23 [ERROR] Error: line 6: Invalid norna-card-list layout "image-down". Use one of: image-top, image-left, image-right.
132
+ at fail (/Users/jangarefelt/Projects/webbhack/norna/scripts/lib/norna-markdown-blocks.mjs:43:8)
133
+ at parseCardListBlock (/Users/jangarefelt/Projects/webbhack/norna/scripts/lib/norna-markdown-blocks.mjs:323:6)
134
+ at parseNornaMarkdownBlock (/Users/jangarefelt/Projects/webbhack/norna/scripts/lib/norna-markdown-blocks.mjs:393:5)
135
+ at extractNornaMarkdownBlocks (/Users/jangarefelt/Projects/webbhack/norna/scripts/lib/norna-markdown-blocks.mjs:409:7)
136
+ at resolveContentBlocks (/Users/jangarefelt/Projects/webbhack/norna/src/lib/sectionContent.ts:137:20)
137
+ at getSectionsContent (/Users/jangarefelt/Projects/webbhack/norna/src/lib/sectionContent.ts:210:19)
138
+ at eval (/Users/jangarefelt/Projects/webbhack/norna/src/components/SitePage.astro:44:1)
139
+ 09:39:23 [ERROR] line 6: Invalid norna-card-list layout "image-down". Use one of: image-top, image-left, image-right.
140
+ Stack trace:
141
+ at /Users/jangarefelt/Projects/webbhack/norna/fixtures/content-model-v2/Users/jangarefelt/Projects/webbhack/norna/src/lib/sectionContent.ts:137:20
142
+ [...] See full stack trace in the browser, or rerun with --verbose.
143
+ [Shiki] The language "norna-image-stack" doesn't exist, falling back to "plaintext".
144
+ [Shiki] The language "norna-image-stack" doesn't exist, falling back to "plaintext".
145
+ [Shiki] The language "norna-image-carousel" doesn't exist, falling back to "plaintext".
146
+ [Shiki] The language "norna-image-stack" doesn't exist, falling back to "plaintext".
147
+ [Shiki] The language "norna-card-list" doesn't exist, falling back to "plaintext".
148
+ 09:41:02 [glob-loader] Reloaded data from content.md
149
+ 09:41:03 [200] / 13ms
150
+ 09:41:05 [200] / 4ms
151
+ 09:41:06 [200] / 4ms
152
+ 09:41:07 [200] / 3ms
153
+ 09:41:34 [watch] /@fs/Users/jangarefelt/Projects/webbhack/norna/src/styles/global.css
154
+ 09:42:03 [200] / 13ms
155
+ 09:42:04 [200] / 3ms
156
+ 09:42:04 [200] / 3ms
157
+ 09:43:34 [404] /norna/concepts/ 2ms
158
+ 09:43:38 [WARN] [router] A `getStaticPaths()` route pattern was matched, but no matching static path was found for requested path `/norna/`.
159
+
160
+ Possible dynamic routes being matched: ../../src/pages/[slug].astro.
161
+ 09:43:38 [404] /norna/ 1ms
162
+ 09:43:38 [200] / 7ms
163
+ [Shiki] The language "norna-image-stack" doesn't exist, falling back to "plaintext".
164
+ [Shiki] The language "norna-image-stack" doesn't exist, falling back to "plaintext".
165
+ [Shiki] The language "norna-image-carousel" doesn't exist, falling back to "plaintext".
166
+ [Shiki] The language "norna-image-stack" doesn't exist, falling back to "plaintext".
167
+ [Shiki] The language "norna-card-list" doesn't exist, falling back to "plaintext".
168
+ 09:44:36 [glob-loader] Reloaded data from content.md
169
+ 09:44:36 [200] / 4ms
170
+ 09:44:36 [200] / 7ms
171
+ 09:44:36 [200] / 7ms
172
+ [Shiki] The language "norna-image-stack" doesn't exist, falling back to "plaintext".
173
+ [Shiki] The language "norna-image-stack" doesn't exist, falling back to "plaintext".
174
+ [Shiki] The language "norna-image-carousel" doesn't exist, falling back to "plaintext".
175
+ [Shiki] The language "norna-image-stack" doesn't exist, falling back to "plaintext".
176
+ [Shiki] The language "norna-card-list" doesn't exist, falling back to "plaintext".
177
+ 09:44:58 [glob-loader] Reloaded data from content.md
178
+ 09:44:59 [200] / 14ms
179
+ 09:44:59 [200] / 5ms
180
+ [Shiki] The language "norna-image-stack" doesn't exist, falling back to "plaintext".
181
+ [Shiki] The language "norna-image-stack" doesn't exist, falling back to "plaintext".
182
+ [Shiki] The language "norna-image-carousel" doesn't exist, falling back to "plaintext".
183
+ [Shiki] The language "norna-image-stack" doesn't exist, falling back to "plaintext".
184
+ [Shiki] The language "norna-card-list" doesn't exist, falling back to "plaintext".
185
+ 09:45:25 [glob-loader] Reloaded data from content.md
186
+ 09:45:25 [200] / 13ms
187
+ 09:45:25 [200] / 7ms
188
+ 09:51:14 [200] / 17ms
189
+ 09:51:14 [200] / 5ms
190
+ 09:51:24 [200] / 16ms
191
+ 09:51:24 [200] / 7ms
192
+ 09:51:30 [200] / 16ms
193
+ 09:51:30 [200] / 7ms
194
+ 09:51:39 [200] / 11ms
195
+ 09:51:39 [200] / 5ms
196
+ 09:51:50 [watch] /@fs/Users/jangarefelt/Projects/webbhack/norna/src/styles/global.css
197
+ [Shiki] The language "norna-image-stack" doesn't exist, falling back to "plaintext".
198
+ [Shiki] The language "norna-image-stack" doesn't exist, falling back to "plaintext".
199
+ [Shiki] The language "norna-image-carousel" doesn't exist, falling back to "plaintext".
200
+ [Shiki] The language "norna-image-stack" doesn't exist, falling back to "plaintext".
201
+ [Shiki] The language "norna-card-list" doesn't exist, falling back to "plaintext".
202
+ 09:52:16 [glob-loader] Reloaded data from content.md
203
+ 09:52:17 [200] / 29ms
204
+ 09:52:17 [200] / 6ms
205
+ 09:52:47 [200] / 4ms
206
+ [Shiki] The language "norna-image-stack" doesn't exist, falling back to "plaintext".
207
+ [Shiki] The language "norna-image-stack" doesn't exist, falling back to "plaintext".
208
+ [Shiki] The language "norna-image-carousel" doesn't exist, falling back to "plaintext".
209
+ [Shiki] The language "norna-image-stack" doesn't exist, falling back to "plaintext".
210
+ [Shiki] The language "norna-card-list" doesn't exist, falling back to "plaintext".
211
+ 09:53:39 [glob-loader] Reloaded data from content.md
212
+ 09:53:39 [200] / 13ms
213
+ 09:53:39 [200] / 7ms
214
+ [Shiki] The language "norna-image-stack" doesn't exist, falling back to "plaintext".
215
+ [Shiki] The language "norna-image-stack" doesn't exist, falling back to "plaintext".
216
+ [Shiki] The language "norna-image-carousel" doesn't exist, falling back to "plaintext".
217
+ [Shiki] The language "norna-image-stack" doesn't exist, falling back to "plaintext".
218
+ [Shiki] The language "norna-card-list" doesn't exist, falling back to "plaintext".
219
+ 09:53:56 [glob-loader] Reloaded data from content.md
220
+ 09:53:57 [200] / 17ms
221
+ 09:53:57 [200] / 7ms
222
+ [Shiki] The language "norna-image-stack" doesn't exist, falling back to "plaintext".
223
+ [Shiki] The language "norna-image-stack" doesn't exist, falling back to "plaintext".
224
+ [Shiki] The language "norna-image-carousel" doesn't exist, falling back to "plaintext".
225
+ [Shiki] The language "norna-image-stack" doesn't exist, falling back to "plaintext".
226
+ [Shiki] The language "norna-card-list" doesn't exist, falling back to "plaintext".
227
+ 09:54:16 [glob-loader] Reloaded data from content.md
228
+ 09:54:16 [200] / 5ms
229
+ 09:54:16 [200] / 6ms
230
+ 09:54:16 [200] / 8ms
231
+ 09:55:44 [200] /guide/ 24ms
@@ -0,0 +1,5 @@
1
+ {
2
+ "_variables": {
3
+ "lastUpdateCheck": 1786394670921
4
+ }
5
+ }
@@ -0,0 +1,2 @@
1
+ /// <reference types="astro/client" />
2
+ /// <reference path="content.d.ts" />
@@ -0,0 +1 @@
1
+ function e(e){return typeof e==`number`}function t(e){return typeof e==`string`}function n(e){return typeof e==`boolean`}function r(e){return Object.prototype.toString.call(e)===`[object Object]`}function i(e){return Math.abs(e)}function a(e){return Math.sign(e)}function o(e,t){return i(e-t)}function s(e,t){return e===0||t===0||i(e)<=i(t)?0:i(o(i(e),i(t))/e)}function c(e){return Math.round(e*100)/100}function l(e){return m(e).map(Number)}function u(e){return e[d(e)]}function d(e){return Math.max(0,e.length-1)}function f(e,t){return t===d(e)}function p(e,t=0){return Array.from(Array(e),(e,n)=>t+n)}function m(e){return Object.keys(e)}function h(e,t){return[e,t].reduce((e,t)=>(m(t).forEach(n=>{let i=e[n],a=t[n];e[n]=r(i)&&r(a)?h(i,a):a}),e),{})}function g(e,t){return t.MouseEvent!==void 0&&e instanceof t.MouseEvent}function _(e,n){let r={start:i,center:a,end:o};function i(){return 0}function a(e){return o(e)/2}function o(e){return n-e}function s(i,a){return t(e)?r[e](i):e(n,i,a)}return{measure:s}}function v(){let e=[];function t(t,n,i,a={passive:!0}){let o;if(`addEventListener`in t)t.addEventListener(n,i,a),o=()=>t.removeEventListener(n,i,a);else{let e=t;e.addListener(i),o=()=>e.removeListener(i)}return e.push(o),r}function n(){e=e.filter(e=>e())}let r={add:t,clear:n};return r}function y(e,t,n,r){let i=v(),a=1e3/60,o=null,s=0,c=0;function l(){i.add(e,`visibilitychange`,()=>{e.hidden&&m()})}function u(){p(),i.clear()}function d(e){if(!c)return;o||(o=e,n(),n());let i=e-o;for(o=e,s+=i;s>=a;)n(),s-=a;r(s/a),c&&=t.requestAnimationFrame(d)}function f(){c||=t.requestAnimationFrame(d)}function p(){t.cancelAnimationFrame(c),o=null,s=0,c=0}function m(){o=null,s=0}return{init:l,destroy:u,start:f,stop:p,update:n,render:r}}function b(e,t){let n=t===`rtl`,r=e===`y`,i=r?`y`:`x`,a=r?`x`:`y`,o=!r&&n?-1:1,s=u(),c=d();function l(e){let{height:t,width:n}=e;return r?t:n}function u(){return r?`top`:n?`right`:`left`}function d(){return r?`bottom`:n?`left`:`right`}function f(e){return e*o}return{scroll:i,cross:a,startEdge:s,endEdge:c,measureSize:l,direction:f}}function x(e=0,t=0){let n=i(e-t);function r(t){return t<e}function a(e){return e>t}function o(e){return r(e)||a(e)}function s(n){return o(n)?r(n)?e:t:n}function c(e){return n?e-n*Math.ceil((e-t)/n):e}return{length:n,max:t,min:e,constrain:s,reachedAny:o,reachedMax:a,reachedMin:r,removeOffset:c}}function S(e,t,n){let{constrain:r}=x(0,e),a=e+1,o=s(t);function s(e){return n?i((a+e)%a):r(e)}function c(){return o}function l(e){return o=s(e),f}function u(e){return d().set(c()+e)}function d(){return S(e,c(),n)}let f={get:c,set:l,add:u,clone:d};return f}function C(e,t,r,c,l,u,d,f,p,m,h,_,y,b,S,C,w,T,E){let{cross:D,direction:O}=e,k=[`INPUT`,`SELECT`,`TEXTAREA`],A={passive:!1},j=v(),M=v(),ee=x(50,225).constrain(b.measure(20)),te={mouse:300,touch:400},ne={mouse:500,touch:600},re=S?43:25,ie=!1,N=0,P=0,F=!1,I=!1,L=!1,R=!1;function ae(e){if(!E)return;function r(t){(n(E)||E(e,t))&&ue(t)}let i=t;j.add(i,`dragstart`,e=>e.preventDefault(),A).add(i,`touchmove`,()=>void 0,A).add(i,`touchend`,()=>void 0).add(i,`touchstart`,r).add(i,`mousedown`,r).add(i,`touchcancel`,V).add(i,`contextmenu`,V).add(i,`click`,de,!0)}function oe(){j.clear(),M.clear()}function se(){let e=R?r:t;M.add(e,`touchmove`,B,A).add(e,`touchend`,V).add(e,`mousemove`,B,A).add(e,`mouseup`,V)}function ce(e){let t=e.nodeName||``;return k.includes(t)}function le(){return(S?ne:te)[R?`mouse`:`touch`]}function z(e,t){let n=_.add(a(e)*-1),r=h.byDistance(e,!S).distance;return S||i(e)<ee?r:w&&t?r*.5:h.byIndex(n.get(),0).distance}function ue(e){let t=g(e,c);R=t,L=S&&t&&!e.buttons&&ie,ie=o(l.get(),d.get())>=2,!(t&&e.button!==0)&&(ce(e.target)||(F=!0,u.pointerDown(e),m.useFriction(0).useDuration(0),l.set(d),se(),N=u.readPoint(e),P=u.readPoint(e,D),y.emit(`pointerDown`)))}function B(e){if(!g(e,c)&&e.touches.length>=2)return V(e);let t=u.readPoint(e),n=u.readPoint(e,D),r=o(t,N),i=o(n,P);if(!I&&!R&&(!e.cancelable||(I=r>i,!I)))return V(e);let a=u.pointerMove(e);r>C&&(L=!0),m.useFriction(.3).useDuration(.75),f.start(),l.add(O(a)),e.preventDefault()}function V(e){let t=h.byDistance(0,!1).index!==_.get(),n=u.pointerUp(e)*le(),r=z(O(n),t),i=s(n,r),a=re-10*i,o=T+i/50;I=!1,F=!1,M.clear(),m.useDuration(a).useFriction(o),p.distance(r,!S),R=!1,y.emit(`pointerUp`)}function de(e){L&&=(e.stopPropagation(),e.preventDefault(),!1)}function H(){return F}return{init:ae,destroy:oe,pointerDown:H}}function w(e,t){let n,r;function a(e){return e.timeStamp}function o(n,r){let i=`client${(r||e.scroll)===`x`?`X`:`Y`}`;return(g(n,t)?n:n.touches[0])[i]}function s(e){return n=e,r=e,o(e)}function c(e){let t=o(e)-o(r),i=a(e)-a(n)>170;return r=e,i&&(n=e),t}function l(e){if(!n||!r)return 0;let t=o(r)-o(n),s=a(e)-a(n),c=a(e)-a(r)>170,l=t/s;return s&&!c&&i(l)>.1?l:0}return{pointerDown:s,pointerMove:c,pointerUp:l,readPoint:o}}function T(){function e(e){let{offsetTop:t,offsetLeft:n,offsetWidth:r,offsetHeight:i}=e;return{top:t,right:n+r,bottom:t+i,left:n,width:r,height:i}}return{measure:e}}function E(e){function t(t){return t/100*e}return{measure:t}}function D(e,t,r,a,o,s,c){let l=[e].concat(a),u,d,f=[],p=!1;function m(e){return o.measureSize(c.measure(e))}function h(o){if(!s)return;d=m(e),f=a.map(m);function c(n){for(let r of n){if(p)return;let n=r.target===e,s=a.indexOf(r.target),c=n?d:f[s];if(i(m(n?e:a[s])-c)>=.5){o.reInit(),t.emit(`resize`);break}}}u=new ResizeObserver(e=>{(n(s)||s(o,e))&&c(e)}),r.requestAnimationFrame(()=>{l.forEach(e=>u.observe(e))})}function g(){p=!0,u&&u.disconnect()}return{init:h,destroy:g}}function O(e,t,n,r,o,s){let c=0,l=0,u=o,d=s,f=e.get(),p=0;function m(){let t=r.get()-e.get(),i=!u,o=0;return i?(c=0,n.set(r),e.set(r),o=t):(n.set(e),c+=t/u,c*=d,f+=c,e.add(c),o=f-p),l=a(o),p=f,C}function h(){return i(r.get()-t.get())<.001}function g(){return u}function _(){return l}function v(){return c}function y(){return x(o)}function b(){return S(s)}function x(e){return u=e,C}function S(e){return d=e,C}let C={direction:_,duration:g,velocity:v,seek:m,settled:h,useBaseFriction:b,useBaseDuration:y,useFriction:S,useDuration:x};return C}function k(e,t,n,r,a){let o=a.measure(10),s=a.measure(50),c=x(.1,.99),l=!1;function u(){return!(l||!e.reachedAny(n.get())||!e.reachedAny(t.get()))}function d(a){if(!u())return;let l=i(e[e.reachedMin(t.get())?`min`:`max`]-t.get()),d=n.get()-t.get(),f=c.constrain(l/s);n.subtract(d*f),!a&&i(d)<o&&(n.set(e.constrain(n.get())),r.useDuration(25).useBaseFriction())}function f(e){l=!e}return{shouldConstrain:u,constrain:d,toggleActive:f}}function A(e,t,n,r,i){let a=x(-t+e,0),s=m(),c=p(),l=h();function d(e,t){return o(e,t)<=1}function p(){let e=s[0],t=u(s);return x(s.lastIndexOf(e),s.indexOf(t)+1)}function m(){return n.map((e,t)=>{let{min:r,max:i}=a,o=a.constrain(e),s=!t,c=f(n,t);return s?i:c||d(r,o)?r:d(i,o)?i:o}).map(e=>parseFloat(e.toFixed(3)))}function h(){if(t<=e+i)return[a.max];if(r===`keepSnaps`)return s;let{min:n,max:o}=c;return s.slice(n,o)}return{snapsContained:l,scrollContainLimit:c}}function j(e,t,n){let r=t[0];return{limit:x(n?r-e:u(t),r)}}function M(e,t,n,r){let i=.1,{reachedMin:a,reachedMax:o}=x(t.min+i,t.max+i);function s(e){return e===1?o(n.get()):e===-1?a(n.get()):!1}function c(t){if(!s(t))return;let n=t*-1*e;r.forEach(e=>e.add(n))}return{loop:c}}function ee(e){let{max:t,length:n}=e;function r(e){let r=e-t;return n?r/-n:0}return{get:r}}function te(e,t,n,r,a){let{startEdge:o,endEdge:s}=e,{groupSlides:c}=a,l=p().map(t.measure),d=m(),f=h();function p(){return c(r).map(e=>u(e)[s]-e[0][o]).map(i)}function m(){return r.map(e=>n[o]-e[o]).map(e=>-i(e))}function h(){return c(d).map(e=>e[0]).map((e,t)=>e+l[t])}return{snaps:d,snapsAligned:f}}function ne(e,t,n,r,i,a){let{groupSlides:o}=i,{min:s,max:c}=r,l=m();function m(){let r=o(a),i=!e||t===`keepSnaps`;return n.length===1?[a]:i?r:r.slice(s,c).map((e,t,n)=>{let r=!t,i=f(n,t);return r?p(u(n[0])+1):i?p(d(a)-u(n)[0]+1,u(n)[0]):e})}return{slideRegistry:l}}function re(e,t,n,r,o){let{reachedAny:s,removeOffset:c,constrain:l}=r;function d(e){return e.concat().sort((e,t)=>i(e)-i(t))[0]}function f(n){let r=e?c(n):l(n),{index:a}=t.map((e,t)=>({diff:p(e-r,0),index:t})).sort((e,t)=>i(e.diff)-i(t.diff))[0];return{index:a,distance:r}}function p(t,r){let i=[t,t+n,t-n];if(!e)return t;if(!r)return d(i);let o=i.filter(e=>a(e)===r);return o.length?d(o):u(i)-n}function m(e,n){return{index:e,distance:p(t[e]-o.get(),n)}}function h(n,r){let i=o.get()+n,{index:a,distance:c}=f(i),l=!e&&s(i);return!r||l?{index:a,distance:n}:{index:a,distance:n+p(t[a]-c,0)}}return{byDistance:h,byIndex:m,shortcut:p}}function ie(e,t,n,r,i,a,o){function s(i){let s=i.distance,c=i.index!==t.get();a.add(s),s&&(r.duration()?e.start():(e.update(),e.render(1),e.update())),c&&(n.set(t.get()),t.set(i.index),o.emit(`select`))}function c(e,t){s(i.byDistance(e,t))}function l(e,n){let r=t.clone().set(e);s(i.byIndex(r.get(),n))}return{distance:c,index:l}}function N(t,r,i,a,o,s,c,l){let u={passive:!0,capture:!0},d=0;function f(f){if(!l)return;function m(n){if(new Date().getTime()-d>10)return;c.emit(`slideFocusStart`),t.scrollLeft=0;let r=i.findIndex(e=>e.includes(n));e(r)&&(o.useDuration(0),a.index(r,0),c.emit(`slideFocus`))}s.add(document,`keydown`,p,!1),r.forEach((e,t)=>{s.add(e,`focus`,e=>{(n(l)||l(f,e))&&m(t)},u)})}function p(e){e.code===`Tab`&&(d=new Date().getTime())}return{init:f}}function P(t){let n=t;function r(){return n}function i(e){n=s(e)}function a(e){n+=s(e)}function o(e){n-=s(e)}function s(t){return e(t)?t:t.get()}return{get:r,set:i,add:a,subtract:o}}function F(e,t){let n=e.scroll===`x`?o:s,r=t.style,i=null,a=!1;function o(e){return`translate3d(${e}px,0px,0px)`}function s(e){return`translate3d(0px,${e}px,0px)`}function l(t){if(a)return;let o=c(e.direction(t));o!==i&&(r.transform=n(o),i=o)}function u(e){a=!e}function d(){a||(r.transform=``,t.getAttribute(`style`)||t.removeAttribute(`style`))}return{clear:d,to:l,toggleActive:u}}function I(e,t,n,r,i,a,o,s,c){let u=.5,d=l(i),f=l(i).reverse(),p=v().concat(y());function m(e,t){return e.reduce((e,t)=>e-i[t],t)}function h(e,t){return e.reduce((e,n)=>m(e,t)>0?e.concat([n]):e,[])}function g(e){return a.map((n,i)=>({start:n-r[i]+u+e,end:n+t-u+e}))}function _(t,r,i){let a=g(r);return t.map(t=>{let r=i?0:-n,o=i?n:0,l=i?`end`:`start`,u=a[t][l];return{index:t,loopPoint:u,slideLocation:P(-1),translate:F(e,c[t]),target:()=>s.get()>u?r:o}})}function v(){let e=o[0];return _(h(f,e),n,!1)}function y(){return _(h(d,t-o[0]-1),-n,!0)}function b(){return p.every(({index:e})=>m(d.filter(t=>t!==e),t)<=.1)}function x(){p.forEach(e=>{let{target:t,translate:n,slideLocation:r}=e,i=t();i!==r.get()&&(n.to(i),r.set(i))})}function S(){p.forEach(e=>e.translate.clear())}return{canLoop:b,clear:S,loop:x,loopPoints:p}}function L(e,t,r){let i,a=!1;function o(o){if(!r)return;function s(e){for(let n of e)if(n.type===`childList`){o.reInit(),t.emit(`slidesChanged`);break}}i=new MutationObserver(e=>{a||(n(r)||r(o,e))&&s(e)}),i.observe(e,{childList:!0})}function s(){i&&i.disconnect(),a=!0}return{init:o,destroy:s}}function R(e,t,n,r){let i={},a=null,o=null,s,c=!1;function l(){s=new IntersectionObserver(e=>{c||(e.forEach(e=>{let n=t.indexOf(e.target);i[n]=e}),a=null,o=null,n.emit(`slidesInView`))},{root:e.parentElement,threshold:r}),t.forEach(e=>s.observe(e))}function u(){s&&s.disconnect(),c=!0}function d(e){return m(i).reduce((t,n)=>{let r=parseInt(n),{isIntersecting:a}=i[r];return(e&&a||!e&&!a)&&t.push(r),t},[])}function f(e=!0){if(e&&a)return a;if(!e&&o)return o;let t=d(e);return e&&(a=t),e||(o=t),t}return{init:l,destroy:u,get:f}}function ae(e,t,n,r,a,o){let{measureSize:s,startEdge:c,endEdge:l}=e,d=n[0]&&a,p=_(),m=v(),h=n.map(s),g=y();function _(){if(!d)return 0;let e=n[0];return i(t[c]-e[c])}function v(){if(!d)return 0;let e=o.getComputedStyle(u(r));return parseFloat(e.getPropertyValue(`margin-${l}`))}function y(){return n.map((e,t,n)=>{let r=!t,i=f(n,t);return r?h[t]+p:i?h[t]+m:n[t+1][c]-e[c]}).map(i)}return{slideSizes:h,slideSizesWithGaps:g,startGap:p,endGap:m}}function oe(t,n,r,a,o,s,c,f,p){let{startEdge:m,endEdge:h,direction:g}=t,_=e(r);function v(e,t){return l(e).filter(e=>e%t===0).map(n=>e.slice(n,n+t))}function y(e){return e.length?l(e).reduce((t,r,l)=>{let _=u(t)||0,v=_===0,y=r===d(e),b=o[m]-s[_][m],x=o[m]-s[r][h],S=!a&&v?g(c):0,C=i(x-(!a&&y?g(f):0)-(b+S));return l&&C>n+p&&t.push(r),y&&t.push(e.length),t},[]).map((t,n,r)=>{let i=Math.max(r[n-1]||0);return e.slice(i,t)}):[]}function b(e){return _?v(e,r):y(e)}return{groupSlides:b}}function se(e,t,n,r,i,a,o){let{align:s,axis:c,direction:f,startIndex:p,loop:m,duration:h,dragFree:g,dragThreshold:x,inViewThreshold:se,slidesToScroll:ce,skipSnaps:le,containScroll:z,watchResize:ue,watchSlides:B,watchDrag:V,watchFocus:de}=a,H=T(),U=H.measure(t),fe=n.map(H.measure),W=b(c,f),G=W.measureSize(U),pe=E(G),me=_(s,G),he=!m&&!!z,{slideSizes:ge,slideSizesWithGaps:_e,startGap:ve,endGap:ye}=ae(W,U,fe,n,m||!!z,i),be=oe(W,G,ce,m,U,fe,ve,ye,2),{snaps:xe,snapsAligned:Se}=te(W,me,U,fe,be),K=-u(xe)+u(_e),{snapsContained:Ce,scrollContainLimit:we}=A(G,K,Se,z,2),q=he?Ce:Se,{limit:J}=j(K,q,m),Y=S(d(q),p,m),Te=Y.clone(),Ee=l(n),De=({dragHandler:e,scrollBody:t,scrollBounds:n,options:{loop:r}})=>{r||n.constrain(e.pointerDown()),t.seek()},Oe=({scrollBody:e,translate:t,location:n,offsetLocation:r,previousLocation:i,scrollLooper:a,slideLooper:o,dragHandler:s,animation:c,eventHandler:l,scrollBounds:u,options:{loop:d}},f)=>{let p=e.settled(),m=!u.shouldConstrain(),h=d?p:p&&m,g=h&&!s.pointerDown();g&&c.stop();let _=n.get()*f+i.get()*(1-f);r.set(_),d&&(a.loop(e.direction()),o.loop()),t.to(r.get()),g&&l.emit(`settle`),h||l.emit(`scroll`)},ke=y(r,i,()=>De(Be),e=>Oe(Be,e)),Ae=.68,X=q[Y.get()],je=P(X),Me=P(X),Z=P(X),Q=P(X),$=O(je,Z,Me,Q,h,Ae),Ne=re(m,q,K,J,Q),Pe=ie(ke,Y,Te,$,Ne,Q,o),Fe=ee(J),Ie=v(),Le=R(t,n,o,se),{slideRegistry:Re}=ne(he,z,q,we,be,Ee),ze=N(e,n,Re,Pe,$,Ie,o,de),Be={ownerDocument:r,ownerWindow:i,eventHandler:o,containerRect:U,slideRects:fe,animation:ke,axis:W,dragHandler:C(W,e,r,i,Q,w(W,i),je,ke,Pe,$,Ne,Y,o,pe,g,x,le,Ae,V),eventStore:Ie,percentOfView:pe,index:Y,indexPrevious:Te,limit:J,location:je,offsetLocation:Z,previousLocation:Me,options:a,resizeHandler:D(t,o,i,n,W,ue,H),scrollBody:$,scrollBounds:k(J,Z,Q,$,pe),scrollLooper:M(K,J,Z,[je,Z,Me,Q]),scrollProgress:Fe,scrollSnapList:q.map(Fe.get),scrollSnaps:q,scrollTarget:Ne,scrollTo:Pe,slideLooper:I(W,G,K,ge,_e,xe,q,Z,n),slideFocus:ze,slidesHandler:L(t,o,B),slidesInView:Le,slideIndexes:Ee,slideRegistry:Re,slidesToScroll:be,target:Q,translate:F(W,t)};return Be}function ce(){let e={},t;function n(e){t=e}function r(t){return e[t]||[]}function i(e){return r(e).forEach(n=>n(t,e)),c}function a(t,n){return e[t]=r(t).concat([n]),c}function o(t,n){return e[t]=r(t).filter(e=>e!==n),c}function s(){e={}}let c={init:n,emit:i,off:o,on:a,clear:s};return c}var le={align:`center`,axis:`x`,container:null,slides:null,containScroll:`trimSnaps`,direction:`ltr`,slidesToScroll:1,inViewThreshold:0,breakpoints:{},dragFree:!1,dragThreshold:10,loop:!1,skipSnaps:!1,duration:25,startIndex:0,active:!0,watchDrag:!0,watchResize:!0,watchSlides:!0,watchFocus:!0};function z(e){function t(e,t){return h(e,t||{})}function n(n){let r=n.breakpoints||{};return t(n,m(r).filter(t=>e.matchMedia(t).matches).map(e=>r[e]).reduce((e,n)=>t(e,n),{}))}function r(t){return t.map(e=>m(e.breakpoints||{})).reduce((e,t)=>e.concat(t),[]).map(e.matchMedia)}return{mergeOptions:t,optionsAtMedia:n,optionsMediaQueries:r}}function ue(e){let t=[];function n(n,r){return t=r.filter(({options:t})=>e.optionsAtMedia(t).active!==!1),t.forEach(t=>t.init(n,e)),r.reduce((e,t)=>Object.assign(e,{[t.name]:t}),{})}function r(){t=t.filter(e=>e.destroy())}return{init:n,destroy:r}}function B(e,n,r){let i=e.ownerDocument,a=i.defaultView,o=z(a),s=ue(o),c=v(),l=ce(),{mergeOptions:u,optionsAtMedia:d,optionsMediaQueries:f}=o,{on:p,off:m,emit:h}=l,g=k,_=!1,y,b=u(le,B.globalOptions),x=u(b),S=[],C,w,T;function E(){let{container:n,slides:r}=x;w=(t(n)?e.querySelector(n):n)||e.children[0];let i=t(r)?w.querySelectorAll(r):r;T=[].slice.call(i||w.children)}function D(t){let n=se(e,w,T,i,a,t,l);return t.loop&&!n.slideLooper.canLoop()?D(Object.assign({},t,{loop:!1})):n}function O(e,t){_||(b=u(b,e),x=d(b),S=t||S,E(),y=D(x),f([b,...S.map(({options:e})=>e)]).forEach(e=>c.add(e,`change`,k)),x.active&&(y.translate.to(y.location.get()),y.animation.init(),y.slidesInView.init(),y.slideFocus.init(H),y.eventHandler.init(H),y.resizeHandler.init(H),y.slidesHandler.init(H),y.options.loop&&y.slideLooper.loop(),w.offsetParent&&T.length&&y.dragHandler.init(H),C=s.init(H,S)))}function k(e,t){let n=P();A(),O(u({startIndex:n},e),t),l.emit(`reInit`)}function A(){y.dragHandler.destroy(),y.eventStore.clear(),y.translate.clear(),y.slideLooper.clear(),y.resizeHandler.destroy(),y.slidesHandler.destroy(),y.slidesInView.destroy(),y.animation.destroy(),s.destroy(),c.clear()}function j(){_||(_=!0,c.clear(),A(),l.emit(`destroy`),l.clear())}function M(e,t,n){!x.active||_||(y.scrollBody.useBaseFriction().useDuration(t===!0?0:x.duration),y.scrollTo.index(e,n||0))}function ee(e){M(y.index.add(1).get(),e,-1)}function te(e){M(y.index.add(-1).get(),e,1)}function ne(){return y.index.add(1).get()!==P()}function re(){return y.index.add(-1).get()!==P()}function ie(){return y.scrollSnapList}function N(){return y.scrollProgress.get(y.offsetLocation.get())}function P(){return y.index.get()}function F(){return y.indexPrevious.get()}function I(){return y.slidesInView.get()}function L(){return y.slidesInView.get(!1)}function R(){return C}function ae(){return y}function oe(){return e}function V(){return w}function de(){return T}let H={canScrollNext:ne,canScrollPrev:re,containerNode:V,internalEngine:ae,destroy:j,off:m,on:p,emit:h,plugins:R,previousScrollSnap:F,reInit:g,rootNode:oe,scrollNext:ee,scrollPrev:te,scrollProgress:N,scrollSnapList:ie,scrollTo:M,selectedScrollSnap:P,slideNodes:de,slidesInView:I,slidesNotInView:L};return O(n,r),setTimeout(()=>l.emit(`init`),0),H}B.globalOptions=void 0,document.querySelectorAll(`[data-carousel]`).forEach(e=>{let t=e.querySelector(`[data-carousel-viewport]`),n=e.querySelector(`[data-carousel-previous]`),r=e.querySelector(`[data-carousel-next]`),i=e.querySelector(`[data-carousel-position]`),a=Array.from(e.querySelectorAll(`[data-carousel-caption]`)),o=Array.from(e.querySelectorAll(`[data-carousel-slide]`));if(!t||!n||!r||!i||o.length<2)return;let s,c=()=>{e.classList.add(`is-interacting`),window.clearTimeout(s),s=window.setTimeout(()=>{e.classList.remove(`is-interacting`)},1600)};e.dataset.carouselReady=`true`;let l=B(t,{align:`start`,containScroll:!1,loop:!0}),u=()=>{let e=l.selectedScrollSnap();o.forEach((t,n)=>{let r=n===e;t.classList.toggle(`is-active`,r),t.setAttribute(`aria-hidden`,String(!r))}),a.forEach(t=>{let n=Number(t.dataset.carouselCaptionIndex)===e;t.classList.toggle(`is-active`,n),t.setAttribute(`aria-hidden`,String(!n))}),n.disabled=!1,r.disabled=!1,i.textContent=`${e+1} / ${o.length}`};n.addEventListener(`click`,()=>{c(),l.scrollPrev()}),r.addEventListener(`click`,()=>{c(),l.scrollNext()}),e.addEventListener(`focusin`,c),e.addEventListener(`pointerdown`,c),e.addEventListener(`keydown`,e=>{e.key===`ArrowLeft`&&(e.preventDefault(),c(),l.scrollPrev()),e.key===`ArrowRight`&&(e.preventDefault(),c(),l.scrollNext())}),l.on(`select`,()=>{c(),u()}),l.on(`reInit`,u),u()});
@@ -0,0 +1 @@
1
+ *,:before,:after{box-sizing:border-box}:root{--color-page:#000;--color-surface:#101010;--color-text:#f7f4ee;--color-muted:#aaa49a;--color-soft:#302f2c;--color-accent:#d8d2c8;--color-border:#ffffff24;--color-nav-background:#000000e6;--color-nav-separator:#ffffff47;--font-sans:Arial, "Helvetica Neue", Helvetica, sans-serif;--font-serif:Georgia, "Times New Roman", serif;--page-width:1180px;--text-width:680px;--gallery-width:900px;--gallery-max-available-width-desktop:100%;--gallery-max-available-width-mobile:100%;--gallery-max-available-width:var(--gallery-max-available-width-desktop);--gallery-layout-width:min(var(--gallery-width), var(--gallery-max-available-width));--gallery-max-image-height-desktop:74svh;--gallery-max-image-height-mobile:68svh;--gallery-max-image-height:var(--gallery-max-image-height-desktop);--nav-top-safety-inset:0px;--space-nav-to-first-section-desktop:clamp(1.875rem, 3vw, 2.75rem);--space-nav-to-first-section-mobile:1.375rem;--space-nav-to-first-section:var(--space-nav-to-first-section-desktop);--space-section-body-to-gallery-desktop:clamp(1.25rem, 2.5vw, 2rem);--space-section-body-to-gallery-mobile:1.25rem;--space-section-body-to-gallery:var(--space-section-body-to-gallery-desktop);--space-gallery-item-desktop:clamp(1.5rem, 3.5vw, 2.75rem);--space-gallery-item-mobile:2.75rem;--space-gallery-item:var(--space-gallery-item-desktop);--space-section-to-section-desktop:clamp(2.55rem, 4.2vw, 3.9rem);--space-section-to-section-mobile:2.25rem;--space-section-to-section:var(--space-section-to-section-desktop);--space-final-section-bottom-desktop:var(--space-section-to-section-desktop);--space-final-section-bottom-mobile:var(--space-section-to-section-mobile);--space-final-section-bottom:var(--space-final-section-bottom-desktop);--content-gutter-desktop:clamp(1.25rem, 4vw, 3rem);--content-gutter-mobile:1rem;--content-gutter:var(--content-gutter-desktop);--site-top-anchor-offset:4.5rem;color-scheme:dark;scroll-behavior:smooth;scroll-padding-top:var(--site-top-anchor-offset)}html{background:var(--color-page);min-height:100%}body{isolation:isolate;background:var(--color-page);min-height:100svh;color:var(--color-text);font-family:var(--font-sans);-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;margin:0}img{max-width:100%;height:auto;display:block}a{color:var(--color-accent);transition:color .18s,opacity .18s}::selection{background:var(--color-text);color:var(--color-page)}.skip-link{z-index:100;background:var(--color-text);color:var(--color-surface);padding:.75rem 1rem;font-weight:700;text-decoration:none;position:fixed;top:.75rem;left:.75rem;transform:translateY(-200%)}.skip-link:focus{transform:translateY(0)}.site-top{z-index:10;padding-top:var(--nav-top-safety-inset);padding-top:max(env(safe-area-inset-top,0px), var(--nav-top-safety-inset));border-bottom:1px solid var(--color-border);background-color:var(--site-top-background-color,var(--color-nav-background));color:var(--site-top-text-color,var(--color-text));backdrop-filter:blur(16px);transition:background-color .18s,color .18s;position:sticky;top:0}.site-nav-row{width:min(calc(100% - (var(--content-gutter) * 2)), var(--page-width));justify-content:space-between;align-items:center;gap:1rem;margin:0 auto;padding:.8rem 0 .7rem;display:flex}.site-brand,.site-nav a,.mobile-nav-menu summary,.mobile-nav-panel a,.page-nav a{color:currentColor;text-decoration:none}.site-brand{letter-spacing:.08em;text-transform:uppercase;flex:none;font-size:.82rem;font-weight:700;line-height:1.1}.site-nav ul,.mobile-nav-panel ul,.page-nav ul{margin:0;padding:0;list-style:none}.site-nav ul{flex-wrap:wrap;justify-content:flex-end;gap:.35rem clamp(.9rem,2.6vw,2rem);display:flex}.site-nav a,.mobile-nav-panel a{letter-spacing:.08em;opacity:.72;text-transform:uppercase;font-size:.78rem;font-weight:500;line-height:1.2;display:block}.site-nav a:hover,.site-nav a[aria-current=page],.mobile-nav-panel a:hover,.mobile-nav-panel a[aria-current=page]{opacity:1}.site-nav a[aria-current=page]{text-underline-offset:.35em;text-decoration:underline 1px}.mobile-nav-menu{display:none}.page-nav{border-top:1px solid color-mix(in srgb, currentColor 14%, transparent)}.page-nav ul{flex-wrap:wrap;justify-content:center;gap:0 clamp(1.4rem,4vw,3.25rem);display:flex}.page-nav li{position:relative}.page-nav li+li:before{color:currentColor;content:"/";opacity:.28;font-size:.75rem;position:absolute;top:50%;left:calc(clamp(1.4rem,4vw,3.25rem)/-2 - .1rem);transform:translateY(-50%)}.page-nav a{letter-spacing:.12em;opacity:.76;text-transform:uppercase;padding:1.05rem 0 .95rem;font-size:.76rem;font-weight:500;line-height:1;text-decoration:none;display:block;position:relative}.page-nav a:after{content:"";opacity:0;background:currentColor;height:1px;transition:opacity .18s,transform .18s;position:absolute;bottom:.62rem;left:0;right:0;transform:scaleX(0)}.page-nav a:hover,.page-nav a[aria-current=true],.mobile-page-nav a[aria-current=true]{opacity:1}.page-nav a[aria-current=true]:after{opacity:.75;transform:scaleX(1)}@media (hover:hover) and (pointer:fine){:root{--nav-top-safety-inset:.625rem}}.site-content{z-index:2;width:min(calc(100% - (var(--content-gutter) * 2)), var(--page-width));margin:0 auto;padding:0;position:relative}.site-footer{isolation:isolate;z-index:2;width:min(calc(100% - (var(--content-gutter) * 2)), var(--page-width));background-color:var(--site-footer-background-color,var(--color-page));color:var(--site-footer-text-color,var(--color-muted));text-align:center;margin:0 auto;padding:0 0 2.5rem;font-size:.75rem;line-height:1.5;position:relative}.site-footer:before{z-index:-1;background-color:var(--site-footer-background-color,var(--color-page));content:"";pointer-events:none;position:absolute;inset:0 calc(50% - 50vw)}.site-footer p{margin:0}.site-footer span{display:block}.site-section{isolation:isolate;background-color:var(--section-background-color,transparent);padding:var(--space-nav-to-first-section) 0 0;position:relative}.site-section:before{z-index:-1;background-color:var(--section-background-color,transparent);content:"";pointer-events:none;position:absolute;inset:0 calc(50% - 50vw)}.site-section+.site-section{padding-top:var(--space-section-to-section);margin-top:0}.site-section:last-child{padding-bottom:var(--space-final-section-bottom)}.section-card{color:var(--section-text-color,var(--color-text));background:0 0}.section-header{width:min(100%, var(--section-heading-width-desktop,760px));padding:0 0 var(--section-heading-spacing-after,.55em);text-align:var(--section-heading-align-desktop,center);margin:0 auto}.section-header h1,.section-header h2,p,ul{margin-top:0}.section-header h1,.section-header h2{color:inherit;font-size:var(--section-heading-font-size-desktop,clamp(1.35rem, 1.1rem + .9vw, 2rem));letter-spacing:0;font-weight:400;line-height:var(--section-heading-line-height,1.04);text-transform:uppercase;overflow-wrap:anywhere;margin-bottom:0}.section-body{width:100%;color:inherit;font-family:var(--font-sans);margin:0 auto;font-size:clamp(.96rem,.94rem + .08vw,1rem)}.section-markdown{width:min(100%, var(--section-body-width-desktop,var(--text-width)));margin:0 auto var(--space-section-body-to-gallery);font-size:var(--section-body-font-size-desktop,clamp(.96rem, .94rem + .08vw, 1rem));line-height:var(--section-body-line-height,1.78);text-align:var(--section-body-align-desktop,center)}.section-markdown p{margin:0 0 var(--section-body-paragraph-spacing,1em)}.section-markdown blockquote{margin:0 0 var(--section-body-paragraph-spacing,1em);border-left:1px solid color-mix(in srgb, currentColor 34%, transparent);padding-left:1rem}.section-markdown blockquote>:last-child{margin-bottom:0}.section-markdown pre.astro-code{margin:0 0 var(--section-body-paragraph-spacing,1em);border:1px solid color-mix(in srgb, currentColor 18%, transparent);text-align:left;border-radius:6px;padding:.78rem .9rem;font-size:.92em;line-height:1.45;background:#0d1117!important}.section-markdown pre.astro-code code{font:inherit}.section-markdown .inline-style{color:var(--inline-style-color)}.section-body-text-only .section-markdown,.section-markdown>:last-child,.gallery-meta :last-child,.section-markdown>pre.astro-code:last-child,.section-markdown blockquote>pre.astro-code:last-child{margin-bottom:0}.section-markdown h3{margin:var(--section-markdown-h3-spacing-before,1.5em) 0 var(--section-markdown-h3-spacing-after,.5em);border-top:1px solid var(--color-soft);font-family:var(--font-sans);font-size:var(--section-markdown-h3-font-size-desktop,.82rem);letter-spacing:0;line-height:var(--section-markdown-h3-line-height,1.35);text-align:var(--section-markdown-h3-align-desktop,left);text-transform:uppercase;padding-top:.55em}.section-markdown h4{margin:var(--section-markdown-h4-spacing-before,1.1em) 0 var(--section-markdown-h4-spacing-after,.4em);color:inherit;font-size:var(--section-markdown-h4-font-size-desktop,clamp(.96rem, .94rem + .08vw, 1rem));letter-spacing:0;font-weight:400;line-height:var(--section-markdown-h4-line-height,1.5);text-align:var(--section-markdown-h4-align-desktop,left)}.section-markdown ul,.section-markdown ol{text-align:left;margin-left:auto;margin-right:auto;padding-left:1.2rem;display:inline-block}.section-markdown li+li{margin-top:.35rem}.gallery{gap:var(--space-gallery-item);margin-top:0;display:grid}.gallery-item{align-content:start;gap:.7rem;margin:0;display:grid}.gallery-image-frame{width:min(100%, var(--gallery-layout-width));background:0 0;place-items:center;margin:0 auto;display:grid}.gallery-image{width:auto;max-width:100%;height:auto;max-height:var(--gallery-max-image-height);object-fit:contain;background:0 0;margin:0 auto;display:block}.gallery-image.gallery-image-landscape{width:100%;max-height:none}.gallery-carousel{outline:none;position:relative}.gallery-carousel:focus-visible{outline-offset:.5rem;outline:2px solid}.gallery-carousel-slide{flex:0 0 100%;min-width:0;margin:0}.gallery-carousel-stage{width:min(100%, var(--gallery-layout-width));max-height:var(--gallery-max-image-height);aspect-ratio:var(--gallery-carousel-aspect-ratio,auto);margin:0 auto;display:grid;position:relative}.gallery-carousel-viewport{height:100%}.gallery-carousel-image-frame{place-items:center;width:100%;height:100%;display:grid}.gallery-carousel[data-carousel-ready=true] .gallery-carousel-viewport{overflow:hidden}.gallery-carousel[data-carousel-ready=true] .gallery-carousel-slides{touch-action:pan-y pinch-zoom;height:100%;display:flex}.gallery-carousel[data-carousel-ready=true] .gallery-carousel-slide{align-content:start;height:100%;display:grid}.gallery-carousel-image-frame .gallery-image.gallery-image-landscape{width:100%;max-width:100%;height:auto;max-height:100%}.gallery-carousel-image-frame .gallery-image:not(.gallery-image-landscape){width:auto;max-width:100%;height:100%;max-height:100%}.gallery-carousel-button,.gallery-carousel-position{display:none}.gallery-carousel[data-carousel-ready=true] .gallery-carousel-button,.gallery-carousel[data-carousel-ready=true] .gallery-carousel-position{display:grid}.gallery-carousel-button{z-index:2;background:var(--section-background-color,var(--color-page));width:2.625rem;height:2.625rem;color:inherit;cursor:pointer;font:inherit;opacity:.88;border:1px solid;border-radius:999px;place-items:center;padding:0;font-size:2rem;line-height:1;position:absolute;top:50%;transform:translateY(-50%);box-shadow:0 .25rem 1rem #0000001f}.gallery-carousel-button:hover:not(:disabled),.gallery-carousel-button:focus-visible:not(:disabled){color:var(--section-background-color,var(--color-page));opacity:1;background:currentColor}.gallery-carousel-button:disabled{cursor:default;opacity:0;pointer-events:none}.gallery-carousel-button-previous{left:.75rem}.gallery-carousel-button-next{right:.75rem}.gallery-carousel-position{z-index:2;background:var(--section-background-color,var(--color-page));text-align:center;border:1px solid;place-items:center;min-width:3.25rem;min-height:1.75rem;font-size:.85rem;line-height:1;position:absolute;bottom:.75rem;right:.75rem;box-shadow:0 .25rem 1rem #0000001f}.gallery-carousel-captions{width:min(100%, var(--gallery-layout-width));margin:0 auto}.gallery-carousel-caption{margin-bottom:0}.gallery-carousel[data-carousel-ready=true] .gallery-carousel-captions{display:grid}.gallery-carousel[data-carousel-ready=true] .gallery-carousel-caption{visibility:hidden;pointer-events:none;grid-area:1/1}.gallery-carousel[data-carousel-ready=true] .gallery-carousel-caption.is-active{visibility:visible;pointer-events:auto}.gallery-meta{width:min(100%, var(--gallery-layout-width));margin:var(--section-caption-spacing-before,.5em) auto 0;font-size:var(--section-caption-font-size-desktop,.95rem);text-align:var(--section-caption-align-desktop,center)}.gallery-details{align-items:baseline;justify-content:var(--section-caption-justify-desktop,center);color:inherit;font-size:inherit;font-family:var(--font-sans);letter-spacing:0;line-height:var(--section-caption-line-height,1.5);flex-wrap:wrap;gap:.5rem;margin-bottom:0;display:flex}@media (width<=700px){:root{--space-nav-to-first-section:var(--space-nav-to-first-section-mobile);--space-section-body-to-gallery:var(--space-section-body-to-gallery-mobile);--space-gallery-item:var(--space-gallery-item-mobile);--space-section-to-section:var(--space-section-to-section-mobile);--space-final-section-bottom:var(--space-final-section-bottom-mobile);--content-gutter:var(--content-gutter-mobile);--gallery-max-available-width:var(--gallery-max-available-width-mobile);--gallery-max-image-height:var(--gallery-max-image-height-mobile);--site-top-anchor-offset:6.25rem}.site-nav-row{width:min(calc(100% - (var(--content-gutter) * 2)), var(--page-width));padding:.75rem 0}.site-brand{overflow-wrap:anywhere;max-width:min(70vw,26rem);font-size:.76rem}.site-nav,.site-top-has-site-nav .page-nav{display:none}.page-nav ul{text-align:center;justify-content:center;gap:0 1.55rem;padding:0 1rem}.page-nav li+li:before{left:-.95rem}.page-nav a{white-space:nowrap;padding:.95rem 0 .85rem;font-size:.72rem}.mobile-nav-menu{flex:none;display:block;position:relative}.mobile-nav-menu summary{letter-spacing:.1em;opacity:.9;text-transform:uppercase;border:1px solid;align-items:center;gap:.42rem;padding:.5rem .7rem .44rem;font-size:.72rem;font-weight:700;line-height:1;list-style:none;display:flex}.mobile-nav-menu summary:after{content:"▾";opacity:.78;font-size:.82em;line-height:1}.mobile-nav-menu[open] summary:after{transform:rotate(180deg)}.mobile-nav-menu summary::-webkit-details-marker{display:none}.mobile-nav-panel{border:1px solid color-mix(in srgb, currentColor 30%, transparent);background:var(--site-top-background-color,var(--color-nav-background));width:min(82vw,22rem);color:var(--site-top-text-color,var(--color-text));gap:1.75rem;padding:1rem;display:grid;position:absolute;top:calc(100% + .75rem);right:0;box-shadow:0 1rem 2.5rem #00000047}.mobile-nav-panel h2{letter-spacing:.14em;text-transform:uppercase;margin:0 0 .75rem;font-size:.68rem;font-weight:700;line-height:1}.mobile-page-nav{border-top:1px solid color-mix(in srgb, currentColor 18%, transparent);padding-top:1.05rem}.mobile-nav-panel ul{gap:.65rem;display:grid}.mobile-nav-panel a{letter-spacing:.06em;font-size:.82rem}.mobile-page-nav a[aria-current=true]{text-underline-offset:.35em;text-decoration:underline 1px}.site-content{width:min(calc(100% - (var(--content-gutter) * 2)), var(--page-width))}.site-footer{width:min(100% - 2rem,34rem)}.site-section+.site-section{margin-top:0}.section-body{width:100%;line-height:1.72}.section-header h1,.section-header h2{font-size:var(--section-heading-font-size-mobile,var(--section-heading-font-size-desktop,clamp(1.3rem, 1.05rem + 1.35vw, 1.75rem)))}.section-header{width:min(100%, var(--section-heading-width-mobile,var(--section-heading-width-desktop,760px)));text-align:var(--section-heading-align-mobile,var(--section-heading-align-desktop,center))}.section-markdown{width:min(100%, var(--section-body-width-mobile,var(--section-body-width-desktop,var(--text-width))));font-size:var(--section-body-font-size-mobile,var(--section-body-font-size-desktop,clamp(.96rem, .94rem + .08vw, 1rem)));text-align:var(--section-body-align-mobile,var(--section-body-align-desktop,left))}.gallery-meta{font-size:var(--section-caption-font-size-mobile,var(--section-caption-font-size-desktop,.95rem));text-align:var(--section-caption-align-mobile,var(--section-caption-align-desktop,center))}.gallery-details{justify-content:var(--section-caption-justify-mobile,var(--section-caption-justify-desktop,center))}.section-markdown h3{font-size:var(--section-markdown-h3-font-size-mobile,var(--section-markdown-h3-font-size-desktop,.82rem));text-align:var(--section-markdown-h3-align-mobile,var(--section-markdown-h3-align-desktop,left))}.section-markdown h4{font-size:var(--section-markdown-h4-font-size-mobile,var(--section-markdown-h4-font-size-desktop,clamp(.96rem, .94rem + .08vw, 1rem)));text-align:var(--section-markdown-h4-align-mobile,var(--section-markdown-h4-align-desktop,left))}.section-markdown ul,.section-markdown ol{display:block}.gallery-item img{max-height:var(--gallery-max-image-height)}.gallery-carousel-stage{aspect-ratio:auto}.gallery-carousel-viewport{width:100%;height:auto;aspect-ratio:var(--gallery-carousel-aspect-ratio,auto)}.gallery-carousel[data-carousel-ready=true] .gallery-carousel-button{display:none}.gallery-carousel-position{opacity:.88;min-width:3rem;min-height:1.5rem;font-size:.78rem;position:absolute;bottom:.5rem;right:.5rem;box-shadow:0 .2rem .75rem #0000001a}.gallery{gap:var(--space-gallery-item)}.gallery-details{padding:0 .25rem;font-size:1rem}}
@@ -0,0 +1,3 @@
1
+ <!DOCTYPE html><html lang="en" style="scroll-behavior: smooth; --font-sans: Arial, 'Helvetica Neue', Helvetica, sans-serif; --page-width: 1180px; --content-gutter-desktop: clamp(1.25rem, 4vw, 3rem); --content-gutter-mobile: 1rem; --space-nav-to-first-section-desktop: clamp(1.25rem, 3vw, 2.5rem); --space-nav-to-first-section-mobile: 1.25rem; --space-section-body-to-gallery-desktop: 1.25rem; --space-section-body-to-gallery-mobile: 1rem; --space-gallery-item-desktop: clamp(1.25rem, 2.8vw, 2rem); --space-gallery-item-mobile: 1.5rem; --space-section-to-section-desktop: clamp(1.4rem, 3vw, 2.75rem); --space-section-to-section-mobile: 1.5rem; --space-final-section-bottom-desktop: clamp(1.4rem, 3vw, 2.75rem); --space-final-section-bottom-mobile: 1.5rem; --gallery-width: 900px; --gallery-max-available-width-desktop: 100%; --gallery-max-available-width-mobile: 100%; --gallery-max-image-height-desktop: 74svh; --gallery-max-image-height-mobile: 68svh"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1"><meta name="format-detection" content="telephone=no"><meta name="description" content="Internal route fixture for content model v2."><meta name="theme-color" content="#000000"><link rel="canonical" href="https://example.com/guide/"><meta name="generator" content="Astro v7.1.3"><title>Guide</title><link rel="stylesheet" href="/_astro/SitePage.BbfZub4g.css"></head><body><a class="skip-link" href="#main-content">Skip to content</a><header class="site-top site-top-has-site-nav" data-smooth-scroll="{&quot;durationPerPixelMs&quot;:0.22,&quot;enabled&quot;:true,&quot;maximumDurationMs&quot;:4000,&quot;minimumDurationMs&quot;:2000}" style="--site-top-background-color: var(--color-page); --site-top-text-color: var(--color-text)"><div class="site-nav-row"><a class="site-brand" href="/">Content Model v2 Fixture</a><nav class="site-nav" aria-label="Pages"><ul><li><a href="/">Content Model v2 Fixture</a></li><li><a href="/guide/" aria-current="page">Guide</a></li></ul></nav><details class="mobile-nav-menu"><summary><span>Guide</span></summary><div class="mobile-nav-panel"><nav class="mobile-site-nav" aria-label="Pages"><h2>Pages</h2><ul><li><a href="/">Content Model v2 Fixture</a></li><li><a href="/guide/" aria-current="page">Guide</a></li></ul></nav></div></details></div></header><script type="module">var e=document.querySelector(`.site-top`),t=Array.from(document.querySelectorAll(`.site-section`)),n=Array.from(document.querySelectorAll(`.page-nav a, .mobile-page-nav a`)),r=document.querySelector(`.mobile-nav-menu`),i=JSON.parse(e?.getAttribute(`data-smooth-scroll`)??`{}`),a=0,o=[120,320,700,1e3,2e3],s=window.matchMedia(`(prefers-reduced-motion: reduce)`),c=i.minimumDurationMs,l=i.maximumDurationMs,u=i.durationPerPixelMs,d=[`wheel`,`touchstart`],f=new Set([`ArrowDown`,`ArrowUp`,`End`,`Home`,`PageDown`,`PageUp`,` `]),p=null,m=null,h=0;`scrollRestoration`in history&&(history.scrollRestoration=`manual`);var g=()=>{if(!(e instanceof HTMLElement))return;let t=Math.ceil(e.getBoundingClientRect().height+a);return document.documentElement.style.setProperty(`--site-top-anchor-offset`,`${t}px`),t},_=e=>{let n=e.replace(/^#/,``);return t.find(e=>e.id===n)},v=e=>e?.querySelector(`h1, h2`),y=()=>{p&&=(p.cancel(),null)},b=e=>{e&&m!==e.id&&(m=e.id,n.forEach(t=>{t.getAttribute(`href`)===`#${e.id}`?t.setAttribute(`aria-current`,`true`):t.removeAttribute(`aria-current`)}))},x=()=>_(window.location.hash),S=e=>{window.location.hash!==e&&history.pushState(null,``,e)},C=()=>{r instanceof HTMLDetailsElement&&(r.open=!1)},w=e=>{if(!(e instanceof HTMLElement))return;let t=v(e);if(!(t instanceof HTMLElement))return;let n=g();if(n)return Math.max(0,t.getBoundingClientRect().top+window.scrollY-n)},T=e=>{y();let t=document.documentElement,n=t.style.scrollBehavior;t.style.scrollBehavior=`auto`,window.scrollTo(0,e),t.style.scrollBehavior=n},E=e=>{let t=Math.abs(e);return!i.enabled||s.matches||t<=a?0:Math.min(l,Math.max(c,t*u))},D=e=>e<.5?4*e*e*e:1-(-2*e+2)**3/2,O=(e,{duration:t,onComplete:n}={})=>{y();let r=typeof e==`function`?e:()=>e,i=r();if(i===void 0)return 0;let a=window.scrollY,o=i-a,s=t??E(o);if(s<=0){let e=r();return e===void 0?0:(T(e),n?.(),0)}let c=document.documentElement,l=c.style.scrollBehavior,u=performance.now(),m=0,h={cancel:()=>{}},g=()=>{d.forEach(e=>{window.removeEventListener(e,v)}),window.removeEventListener(`keydown`,b),c.style.scrollBehavior=l,p===h&&(p=null)},_=()=>{m&&cancelAnimationFrame(m),g()},v=()=>_(),b=e=>{f.has(e.key)&&v()},x=e=>{let t=e-u,o=Math.min(1,t/s),c=r();c!==void 0&&(i=c);let l=a+(i-a)*D(o);if(window.scrollTo(0,l),o>=1){window.scrollTo(0,i),g(),n?.();return}m=requestAnimationFrame(x)};return h.cancel=_,p=h,c.style.scrollBehavior=`auto`,d.forEach(e=>{window.addEventListener(e,v,{passive:!0})}),window.addEventListener(`keydown`,b),m=requestAnimationFrame(x),s},k=(e,{behavior:t=`smooth`,duration:n,onComplete:r}={})=>{let i=w(e);if(i===void 0)return 0;let a=t===`smooth`?O(()=>w(e),{duration:n,onComplete:r}):(T(i),r?.(),0);return b(e),a},A=()=>{g()},j=()=>{if(p)return;let e=x();e instanceof HTMLElement&&k(e,{behavior:`auto`})},M=()=>{if(!window.location.hash)return;h+=1;let e=h;o.forEach(t=>{window.setTimeout(()=>{e===h&&requestAnimationFrame(j)},t)})},N=({behavior:e=`auto`,scrollHashlessTop:n=!1}={})=>{let r=x();if(r instanceof HTMLElement){k(r,{behavior:e}),M();return}n&&T(0),b(t[0])};n.forEach(e=>{e.addEventListener(`click`,t=>{let n=_(e.hash);if(!(n instanceof HTMLElement))return;let r=w(n);if(r===void 0)return;t.preventDefault();let i=`#${n.id}`,a=E(r-window.scrollY);S(i),b(n),C(),k(n,{behavior:`smooth`,duration:a,onComplete:M})})}),A(),requestAnimationFrame(()=>N({behavior:`auto`})),e instanceof HTMLElement&&`ResizeObserver`in window&&new ResizeObserver(A).observe(e),window.addEventListener(`resize`,A),window.addEventListener(`load`,M),window.addEventListener(`hashchange`,()=>N({behavior:`auto`,scrollHashlessTop:!0})),window.addEventListener(`popstate`,()=>N({behavior:`auto`,scrollHashlessTop:!0})),window.visualViewport&&window.visualViewport.addEventListener(`resize`,A);</script><main id="main-content" class="site-content"><section id="intro" class="site-section" data-section-title="Intro" style="--section-background-color: transparent; --section-text-color: var(--color-text); --section-heading-align-desktop: left; --section-heading-align-mobile: left; --section-heading-font-size-desktop: clamp(1.35rem, 1.1rem + 0.9vw, 2rem); --section-heading-font-size-mobile: clamp(1.3rem, 1.05rem + 1.35vw, 1.75rem); --section-heading-line-height: 1.12; --section-heading-spacing-after: 0.55em; --section-heading-width-desktop: var(--gallery-layout-width); --section-heading-width-mobile: var(--gallery-layout-width); --section-markdown-h3-align-desktop: left; --section-markdown-h3-align-mobile: left; --section-markdown-h3-font-size-desktop: clamp(1.05rem, 0.98rem + 0.28vw, 1.22rem); --section-markdown-h3-font-size-mobile: clamp(1.04rem, 0.98rem + 0.45vw, 1.18rem); --section-markdown-h3-line-height: 1.35; --section-markdown-h3-spacing-before: 1.5em; --section-markdown-h3-spacing-after: 0.5em; --section-markdown-h4-align-desktop: left; --section-markdown-h4-align-mobile: left; --section-markdown-h4-font-size-desktop: clamp(0.96rem, 0.94rem + 0.08vw, 1rem); --section-markdown-h4-font-size-mobile: clamp(0.96rem, 0.94rem + 0.08vw, 1rem); --section-markdown-h4-line-height: 1.55; --section-markdown-h4-spacing-before: 1.1em; --section-markdown-h4-spacing-after: 0.4em; --section-body-align-desktop: left; --section-body-align-mobile: left; --section-body-font-size-desktop: clamp(0.96rem, 0.94rem + 0.08vw, 1rem); --section-body-font-size-mobile: clamp(0.96rem, 0.94rem + 0.08vw, 1rem); --section-body-line-height: 1.62; --section-body-paragraph-spacing: 0.85em; --section-body-width-desktop: var(--gallery-layout-width); --section-body-width-mobile: var(--gallery-layout-width); --section-caption-align-desktop: left; --section-caption-align-mobile: left; --section-caption-font-size-desktop: clamp(0.86rem, 0.84rem + 0.08vw, 0.92rem); --section-caption-font-size-mobile: clamp(0.86rem, 0.84rem + 0.08vw, 0.92rem); --section-caption-line-height: 1.4; --section-caption-spacing-before: 0.5em; --section-caption-justify-desktop: flex-start; --section-caption-justify-mobile: flex-start"><div class="section-card"><header class="section-header"><h1>Intro</h1></header><div class="section-body section-body-has-gallery"><div class="section-markdown"><p>Routes may use the same section id and image filename as other pages without
2
+ making the site invalid.</p>
3
+ </div><div class="gallery" aria-label="Images: Intro"><figure class="gallery-item"><div class="gallery-image-frame"><img src="/images/generated/routes/010-guide/images/intro/duplicate-5cf614d2-960.webp" srcset="/images/generated/routes/010-guide/images/intro/duplicate-5cf614d2-480.webp 480w, /images/generated/routes/010-guide/images/intro/duplicate-5cf614d2-768.webp 768w, /images/generated/routes/010-guide/images/intro/duplicate-5cf614d2-960.webp 960w" sizes="(max-width: 700px) 100vw, 100vw" style="aspect-ratio: 960 / 1600;" width="960" height="1600" class="gallery-image" alt="A route-local duplicated filename." decoding="async" fetchpriority="low" loading="lazy"></div><figcaption class="gallery-meta"><div class="gallery-details"><span>This file is resolved in the route image root.</span></div></figcaption></figure></div><script type="module" src="/_astro/GalleryGrid.astro_astro_type_script_index_0_lang.B0kxDyGz.js"></script></div></div></section></main></body></html>