@omniharmonic/openspace-renderer 0.0.0-stage → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +26 -0
- package/README.md +10 -2
- package/dist/base-css-BgaJFrjD.d.ts +19 -0
- package/dist/base-css-CCRQ8Nzw.d.ts +19 -0
- package/dist/behaviors/accordion.js +1 -0
- package/dist/behaviors/announcement.js +1 -0
- package/dist/behaviors/beacon.js +1 -0
- package/dist/behaviors/before-after.js +1 -0
- package/dist/behaviors/carousel.js +1 -0
- package/dist/behaviors/cart.js +1 -0
- package/dist/behaviors/countdown.js +1 -0
- package/dist/behaviors/form.js +1 -0
- package/dist/behaviors/lightbox.js +1 -0
- package/dist/behaviors/marquee.js +1 -0
- package/dist/behaviors/menu.js +1 -0
- package/dist/behaviors/newsletter.js +1 -0
- package/dist/behaviors/os-behaviors.js +1 -0
- package/dist/behaviors/popup.js +1 -0
- package/dist/behaviors/reveal.js +1 -0
- package/dist/behaviors/search.js +1 -0
- package/dist/behaviors/tabs.js +1 -0
- package/dist/behaviors/video-lite.js +1 -0
- package/dist/chunk-RO5BKIKN.js +510 -0
- package/dist/chunk-RO5BKIKN.js.map +1 -0
- package/dist/chunk-VMFXBMCF.js +483 -0
- package/dist/chunk-VMFXBMCF.js.map +1 -0
- package/dist/index.d.ts +798 -0
- package/dist/index.js +2023 -0
- package/dist/index.js.map +1 -0
- package/dist/node.d.ts +42 -0
- package/dist/node.js +82 -0
- package/dist/node.js.map +1 -0
- package/dist/os.css +446 -0
- package/package.json +67 -3
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/block.tsx","../src/context.tsx","../src/cx.ts","../src/layout-vars.ts","../src/registry.ts","../src/chrome.tsx","../src/image.tsx","../src/link.tsx","../src/primitives.tsx","../src/section.tsx","../src/image-map.ts","../src/collections.tsx","../src/recurrence.ts","../src/header.tsx","../src/html.ts","../src/html-meta.ts","../src/page.tsx","../src/richtext.tsx","../src/index.ts"],"sourcesContent":["import {\n type Align,\n type Block,\n type BlockStyle,\n migrateBlock,\n type Responsive,\n resolve,\n type Section,\n} from \"@omniharmonic/openspace-schema\";\nimport { imageTreatmentClass, TOKEN_VARS, themeClass } from \"@omniharmonic/openspace-theme\";\nimport { Component, type ReactNode, useContext } from \"react\";\nimport {\n BlockFieldsContext,\n BlockRegistryContext,\n type RenderMode,\n useEditor,\n useRenderContext,\n} from \"./context\";\nimport { type CssVars, cx } from \"./cx\";\nimport { responsiveVars } from \"./layout-vars\";\nimport { globalRegistry, type RendererBlockDefinition } from \"./registry\";\n\n/** `acme/map` → `acme-map`. */\nexport const blockTypeClass = (type: string) => `os-block--${type.replace(/\\//g, \"-\")}`;\n\nconst spaceVar = (t: string) =>\n `var(${TOKEN_VARS.space[t as keyof typeof TOKEN_VARS.space] ?? TOKEN_VARS.space.md})`;\n\n/** `os-align-center os-talign-center os-malign-start` (inheritance applied). */\nexport function alignClasses(align: Responsive<Align>): string {\n return `os-align-${resolve(align, \"d\")} os-talign-${resolve(align, \"t\")} os-malign-${resolve(align, \"m\")}`;\n}\n\n/** Wrapper classes + vars for a block's token style overrides. */\nexport function blockStyleProps(\n style: BlockStyle | undefined,\n mode: RenderMode,\n): { className: string; vars: CssVars; attrs: Record<string, string> } {\n const vars: CssVars = {};\n const attrs: Record<string, string> = {};\n if (!style) return { className: \"\", vars, attrs };\n Object.assign(vars, responsiveVars(\"bpad\", style.padding, spaceVar));\n if (style.radius) vars[\"--radius\"] = `var(${TOKEN_VARS.radius[style.radius]})`;\n if (style.shadow) vars[\"--shadow\"] = `var(${TOKEN_VARS.shadow[style.shadow]})`;\n const entrance = style.animation?.entrance;\n if (entrance && entrance !== \"none\" && mode !== \"editor\") {\n attrs[\"data-os-behavior\"] = \"reveal\";\n attrs[\"data-os-reveal\"] = entrance;\n }\n const className = cx(\n style.colorTheme && `${themeClass(style.colorTheme)} os-themed`,\n style.imageTreatment && imageTreatmentClass(style.imageTreatment),\n style.padding && \"has-pad\",\n style.align && alignClasses(style.align),\n style.radius && \"has-radius\",\n style.shadow && style.shadow !== \"none\" && \"has-shadow\",\n style.border && style.border !== \"none\" && `os-border-${style.border}`,\n );\n return { className, vars, attrs };\n}\n\nexport function MissingBlock({ block, reason }: { block: Block; reason: string }) {\n const editor = useEditor();\n const { mode } = useRenderContext();\n if (mode === \"production\") return null;\n if (editor?.renderMissingBlock) return <>{editor.renderMissingBlock({ block, reason })}</>;\n return (\n <div className=\"os-block-missing\" role=\"note\">\n {reason}\n </div>\n );\n}\n\ntype Prepared =\n | { ok: true; def: RendererBlockDefinition; block: Block; fields: Record<string, unknown> }\n | { ok: false; reason: string };\n\nfunction prepare(def: RendererBlockDefinition | undefined, raw: Block, mode: RenderMode): Prepared {\n if (!def) return { ok: false, reason: `Unknown block type “${raw.type}”` };\n let block = raw;\n try {\n if (raw.v < def.version) block = migrateBlock(def, raw);\n } catch (err) {\n return { ok: false, reason: `Could not upgrade this ${def.label} block: ${String(err)}` };\n }\n const parsed = def.fieldsSchema.safeParse(block.fields);\n if (parsed.success)\n return { ok: true, def, block, fields: parsed.data as Record<string, unknown> };\n if (mode !== \"production\")\n return {\n ok: false,\n reason: `This ${def.label} block has invalid content: ${parsed.error.issues[0]?.message ?? \"unknown error\"}`,\n };\n // Production: replace only the failing fields with their defaults (or drop them), then\n // re-validate. Raw invalid values never reach a render function (e.g. unsafe link URLs).\n const repaired = repairFields(def, block.fields, parsed.error.issues);\n const again = def.fieldsSchema.safeParse(repaired);\n if (again.success) return { ok: true, def, block, fields: again.data as Record<string, unknown> };\n return { ok: false, reason: `This ${def.label} block has invalid content` };\n}\n\n/** Swap each top-level field with a validation issue for its default, or remove it. */\nexport function repairFields(\n def: Pick<RendererBlockDefinition, \"meta\">,\n fields: Record<string, unknown>,\n issues: readonly { path: readonly PropertyKey[] }[],\n): Record<string, unknown> {\n const out: Record<string, unknown> = { ...fields };\n const defaults = def.meta.defaults.fields as Record<string, unknown>;\n for (const issue of issues) {\n const key = issue.path[0];\n if (typeof key !== \"string\") continue;\n if (defaults[key] !== undefined) out[key] = structuredClone(defaults[key]);\n else delete out[key];\n }\n return out;\n}\n\n/**\n * Calls the definition's render function as its own component so hooks inside it keep a\n * stable order. The try/catch only covers the render function's own synchronous execution:\n * an error thrown by a nested component (rendered later by React) is not caught here. On the\n * client (Studio canvas) {@link BlockErrorBoundary} catches those; during static rendering\n * (`renderToStaticMarkup` has no error boundaries) such an error fails the page render, which\n * site-kit reports as a build error rather than shipping a silently broken page.\n */\nfunction RenderBlock(props: {\n def: RendererBlockDefinition;\n block: Block;\n fields: Record<string, unknown>;\n}) {\n const { def, block, fields } = props;\n try {\n return (\n <BlockFieldsContext.Provider value={{ block, fields }}>\n {\n def.render({\n id: block.id as never,\n fields,\n variant: block.variant ?? def.defaults.variant,\n style: block.style,\n block,\n }) as ReactNode\n }\n </BlockFieldsContext.Provider>\n );\n } catch (err) {\n return <MissingBlock block={block} reason={`This block failed to render: ${String(err)}`} />;\n }\n}\n\n/** Client-side error boundary around each block (no effect during static rendering). */\nexport class BlockErrorBoundary extends Component<\n { block: Block; children: ReactNode },\n { error: string | null }\n> {\n override state = { error: null as string | null };\n static getDerivedStateFromError(err: unknown) {\n return { error: String(err) };\n }\n override render() {\n if (this.state.error)\n return (\n <MissingBlock\n block={this.props.block}\n reason={`This block failed to render: ${this.state.error}`}\n />\n );\n return this.props.children;\n }\n}\n\nexport interface BlockViewProps {\n block: Block;\n /** The containing section (absent for standalone renders such as email/OG). */\n section?: Section;\n}\n\n/**\n * Render one block through the registry: migrate if stale, validate fields, wrap in a\n * `.os-block` container (container-query context, token style overrides, `data-os-id`).\n */\nexport function BlockView({ block, section }: BlockViewProps) {\n const registry = useContext(BlockRegistryContext) ?? globalRegistry;\n const ctx = useRenderContext();\n const editor = useEditor();\n const def = registry.get(block.type) as RendererBlockDefinition | undefined;\n // Hidden blocks are skipped everywhere but Studio, which shows them ghosted.\n if (block.hidden && ctx.mode !== \"editor\") return null;\n const prepared = prepare(def, block, ctx.mode);\n\n const content: ReactNode = prepared.ok ? (\n <BlockErrorBoundary block={block}>\n <RenderBlock def={prepared.def} block={prepared.block} fields={prepared.fields} />\n </BlockErrorBoundary>\n ) : (\n <MissingBlock block={block} reason={prepared.reason} />\n );\n if (!prepared.ok && ctx.mode === \"production\" && !editor) return null;\n\n const variant = prepared.ok\n ? (prepared.block.variant ?? prepared.def.defaults.variant)\n : undefined;\n const s = blockStyleProps(block.style, ctx.mode);\n const el = (\n <div\n className={cx(\n \"os-block\",\n blockTypeClass(block.type),\n variant && `is-${variant}`,\n s.className,\n )}\n data-os-id={block.id}\n data-os-block={block.type}\n data-os-hidden={block.hidden ? \"\" : undefined}\n style={Object.keys(s.vars).length ? s.vars : undefined}\n {...s.attrs}\n >\n {content}\n </div>\n );\n return editor?.wrapBlock ? editor.wrapBlock({ block, section, children: el }) : el;\n}\n","import type {\n Block,\n Page,\n RichTextDoc,\n Section,\n SiteDocument,\n} from \"@omniharmonic/openspace-schema\";\nimport { createContext, type ReactNode, useContext } from \"react\";\nimport type { ImageMap } from \"./image-map\";\nimport type { RendererBlockRegistry } from \"./registry\";\n\n/**\n * Render modes.\n * - `production`: the published site (site-kit build). Broken references render nothing.\n * - `preview`: Hub dev preview / share links. Like production, plus visible notices for broken\n * blocks and links, and always `noindex`.\n * - `editor`: Studio canvas. Like preview, plus no entrance animations and editor hooks.\n */\nexport type RenderMode = \"production\" | \"preview\" | \"editor\";\n\nexport interface RenderContextValue {\n /** The whole site; optional so primitives (`<Img>`, `<Link>`) can render standalone. */\n doc: SiteDocument | undefined;\n /** The page being rendered, if any (used for same-page anchors). */\n page: Page | undefined;\n mode: RenderMode;\n /** Site base path without a trailing slash: `\"\"` or `/maya-yoga`. */\n basePath: string;\n /** Hub origin used by forms, newsletter, cart and analytics. */\n hubUrl: string | undefined;\n}\n\nconst DEFAULT_CONTEXT: RenderContextValue = {\n doc: undefined,\n page: undefined,\n mode: \"production\",\n basePath: \"\",\n hubUrl: undefined,\n};\n\nexport const RenderContext = createContext<RenderContextValue>(DEFAULT_CONTEXT);\n\nexport function useRenderContext(): RenderContextValue {\n return useContext(RenderContext);\n}\n\n/** Resolved image map (see {@link ImageMap}); `<Img>` reads it. */\nexport const ImageResolverContext = createContext<ImageMap>({});\n\nexport function useImageMap(): ImageMap {\n return useContext(ImageResolverContext);\n}\n\n/** Optional block registry override (defaults to the module-level registry). */\nexport const BlockRegistryContext = createContext<RendererBlockRegistry | undefined>(undefined);\n\n/**\n * Hook point for Studio. The renderer always emits `data-os-id` on sections and blocks; in the\n * canvas, Studio can additionally wrap each rendered section/block (selection outlines,\n * drag handles) without the renderer knowing anything about the editor.\n */\nexport interface EditorHooks {\n wrapSection?: (args: { section: Section; children: ReactNode }) => ReactNode;\n wrapBlock?: (args: {\n block: Block;\n section: Section | undefined;\n children: ReactNode;\n }) => ReactNode;\n /** Rendered in place of unknown/invalid blocks (defaults to a small notice). */\n renderMissingBlock?: (args: { block: Block; reason: string }) => ReactNode;\n /**\n * Called by `<RichText>` for a rich-text value that is one of the current block's fields, so\n * Studio can swap in an inline editor. `children` is what `<RichText>` would have rendered\n * (null for an empty document); return it unchanged to keep the normal output.\n */\n renderRichText?: (args: RichTextHookArgs) => ReactNode;\n}\n\nexport interface RichTextHookArgs {\n block: Block;\n /** Dot path of the field inside `block.fields`, e.g. `content` or `items.2.body`. */\n fieldPath: string;\n doc: RichTextDoc | null | undefined;\n /** Classes `<RichText>` puts on its root next to `os-rich`. */\n className: string | undefined;\n /** Root element `<RichText>` renders. */\n as: \"div\" | \"section\" | \"article\";\n children: ReactNode;\n}\n\nexport const EditorContext = createContext<EditorHooks | undefined>(undefined);\n\nexport function useEditor(): EditorHooks | undefined {\n return useContext(EditorContext);\n}\n\n/** The block being rendered and its validated fields (lets `<RichText>` find its field path). */\nexport const BlockFieldsContext = createContext<\n { block: Block; fields: Record<string, unknown> } | undefined\n>(undefined);\n\n/**\n * Where `value` sits inside `fields`, by identity (`items.1.body`). Render functions pass field\n * values straight through, so the object `<RichText>` receives is the one in `fields`.\n */\nexport function fieldPathOf(\n fields: Record<string, unknown>,\n value: unknown,\n depth = 4,\n): string | undefined {\n if (!value || typeof value !== \"object\") return undefined;\n const visit = (node: unknown, path: string[], d: number): string | undefined => {\n if (node === value) return path.join(\".\");\n if (d === 0 || !node || typeof node !== \"object\") return undefined;\n // Don't descend into rich text documents themselves.\n if ((node as { type?: unknown }).type === \"doc\") return undefined;\n for (const [k, v] of Object.entries(node as Record<string, unknown>)) {\n if (v && typeof v === \"object\") {\n const found = visit(v, [...path, k], d - 1);\n if (found) return found;\n }\n }\n return undefined;\n };\n for (const [k, v] of Object.entries(fields)) {\n const found = visit(v, [k], depth);\n if (found) return found;\n }\n return undefined;\n}\n\n/** The section currently being rendered (blocks use it for context, e.g. color theme). */\nexport const SectionContext = createContext<Section | undefined>(undefined);\n","/** Join class names, skipping falsy values. */\nexport function cx(...parts: (string | false | null | undefined | 0)[]): string {\n return parts.filter(Boolean).join(\" \");\n}\n\n/** A CSSProperties-compatible object of custom properties (`{\"--x\": 1}`). */\nexport type CssVars = Record<`--${string}`, string | number>;\n\ndeclare module \"react\" {\n interface CSSProperties {\n [key: `--${string}`]: string | number | undefined;\n }\n}\n","import {\n type Block,\n type Breakpoint,\n GRID_COLUMNS,\n type GridLayout,\n type GridRect,\n type Responsive,\n resolve,\n type SectionStyle,\n type StackLayout,\n} from \"@omniharmonic/openspace-schema\";\nimport { colorVar, TOKEN_VARS } from \"@omniharmonic/openspace-theme\";\nimport type { CssVars } from \"./cx\";\n\n/**\n * Layout → inline custom properties. The base stylesheet is shared and cacheable; every\n * per-instance value travels as an inline custom property (arch §3.3). Responsive values are\n * resolved with `m ← t ← d` inheritance here, so the CSS never has to guess.\n *\n * Prefix convention (desktop / tablet / mobile): `--x` / `--tx` / `--mx`.\n */\nconst PREFIX: Record<Breakpoint, string> = { d: \"\", t: \"t\", m: \"m\" };\nconst BPS: readonly Breakpoint[] = [\"d\", \"t\", \"m\"];\n\n/** Emit `--{p}{name}` for each breakpoint from a responsive value (inheritance applied). */\nexport function responsiveVars<T>(\n name: string,\n value: Responsive<T> | undefined,\n map: (v: T) => string | number,\n): CssVars {\n const out: CssVars = {};\n if (!value) return out;\n for (const bp of BPS) out[`--${PREFIX[bp]}${name}`] = map(resolve(value, bp));\n return out;\n}\n\nconst spaceVar = (token: string) =>\n `var(${TOKEN_VARS.space[token as keyof typeof TOKEN_VARS.space] ?? TOKEN_VARS.space.md})`;\n\n/** Section-level vars: padding, min height. */\nexport function sectionStyleVars(style: SectionStyle): CssVars {\n return {\n ...responsiveVars(\"pad\", style.padding, spaceVar),\n ...responsiveVars(\"minh\", style.minHeight, (v) => v),\n };\n}\n\nconst fr = (cols: readonly number[]) => cols.map((c) => `minmax(0, ${c}fr)`).join(\" \");\n\n/** Stack-mode container vars: column templates per breakpoint. */\nexport function stackVars(layout: StackLayout): CssVars {\n return {\n ...responsiveVars(\"cols\", layout.columns, fr),\n ...(layout.gap ? { \"--gap\": spaceVar(layout.gap) } : {}),\n };\n}\n\n/**\n * Per-column stacking order at tablet/mobile (`layout.order`, FR-13). Mobile inherits the\n * tablet order. Returns `{ \"--to\": n, \"--mo\": n }` for desktop column `index`.\n */\nexport function stackColumnVars(layout: StackLayout, index: number): CssVars {\n const out: CssVars = {};\n const t = layout.order?.t;\n const m = layout.order?.m ?? t;\n if (t) out[\"--to\"] = t.includes(index) ? t.indexOf(index) : t.length + index;\n if (m) out[\"--mo\"] = m.includes(index) ? m.indexOf(index) : m.length + index;\n return out;\n}\n\n/** Group a stack section's blocks by desktop column (out-of-range columns land in the last). */\nexport function blocksByColumn(layout: StackLayout, blocks: readonly Block[]): Block[][] {\n const count = layout.columns.d.length;\n const cols: Block[][] = Array.from({ length: count }, () => []);\n for (const b of blocks) {\n const i = Math.min(Math.max(b.column ?? 0, 0), count - 1);\n cols[i]?.push(b);\n }\n return cols;\n}\n\n/** Grid container vars: row counts per breakpoint. */\nexport function gridVars(layout: GridLayout): CssVars {\n return responsiveVars(\"rows\", layout.rows, (v) => v);\n}\n\nfunction rectVars(rect: GridRect, bp: Breakpoint): CssVars {\n const p = PREFIX[bp];\n const out: CssVars = {\n [`--${p}x`]: rect.x,\n [`--${p}y`]: rect.y,\n [`--${p}w`]: rect.w,\n [`--${p}h`]: rect.h,\n };\n if (rect.z !== undefined) out[`--${p}z`] = rect.z;\n if (rect.bleed === \"left\" || rect.bleed === \"both\") out[`--${p}cs`] = \"full-start\";\n if (rect.bleed === \"right\" || rect.bleed === \"both\") out[`--${p}ce`] = \"full-end\";\n // Pinned rows are drawn from their edge: the first line, or counted back from the last line\n // (negative grid lines), so a bottom-pinned item stays on the last row however many rows\n // there are.\n if (rect.pin === \"top\") out[`--${p}rs`] = 1;\n if (rect.pin === \"bottom\") {\n out[`--${p}rs`] = `span ${rect.h}`;\n out[`--${p}re`] = -1;\n }\n return out;\n}\n\n/** Moved to `@omniharmonic/openspace-schema` (pure, shared with `@omniharmonic/openspace-lint`); re-exported here. */\nexport { fallbackMobileRects } from \"@omniharmonic/openspace-schema\";\n\n/**\n * Inline vars for one grid item: `--x/--y/--w/--h/--z`, `--tx…`, `--mx…`, bleed lines\n * (`--cs/--ce`) and pinned row lines (`--rs/--re`).\n */\nexport function gridItemVars(\n layout: GridLayout,\n id: string,\n mobileFallback?: Record<string, GridRect>,\n): CssVars {\n const item = layout.items[id as keyof GridLayout[\"items\"]];\n if (!item) return {};\n const m = item.m ?? mobileFallback?.[id] ?? { ...item.d, x: 1, w: GRID_COLUMNS.m };\n return {\n ...rectVars(item.d, \"d\"),\n ...rectVars(item.t ?? item.d, \"t\"),\n ...rectVars(clampRect(m, GRID_COLUMNS.m), \"m\"),\n };\n}\n\n/** Keep a rect inside the column count (a `t` rect reused on mobile can be wider than 8). */\nfunction clampRect(rect: GridRect, cols: number): GridRect {\n if (rect.x + rect.w - 1 <= cols) return rect;\n const x = Math.min(rect.x, cols);\n return { ...rect, x, w: Math.max(1, cols - x + 1) };\n}\n\n/** Total rows actually needed for mobile when fallback rects extend past the stored count. */\nexport function mobileRows(layout: GridLayout, fallback: Record<string, GridRect>): number {\n let rows = resolve(layout.rows, \"m\");\n for (const r of Object.values(fallback)) rows = Math.max(rows, r.y + r.h - 1);\n return rows;\n}\n\n/** CSS value for a color value: token → `var(--os-color-…)`, exact colors pass through. */\nexport function colorValue(value: string): string {\n return /^[a-z]/.test(value) && !/^(?:oklch|oklab|rgb|rgba|hsl|hsla|lab|lch)\\(/.test(value)\n ? `var(${colorVar(value)})`\n : value;\n}\n","import type {\n AnyBlockDefinition,\n BlockDefinition,\n FieldsShape,\n} from \"@omniharmonic/openspace-schema\";\nimport type { ReactNode } from \"react\";\n\n/**\n * A block definition whose `render` returns React nodes. Schema keeps `render` generic\n * (`(props) => unknown`) so it has no React dependency; the renderer narrows it here.\n */\n// biome-ignore lint/suspicious/noExplicitAny: erased field shape for registries\nexport type RendererBlockDefinition = BlockDefinition<any, any, ReactNode>;\n\n/** The minimal registry surface the renderer needs (schema's `BlockRegistry` satisfies it). */\nexport interface RendererBlockRegistry {\n get(type: string): AnyBlockDefinition | undefined;\n}\n\nconst blocks = new Map<string, AnyBlockDefinition>();\n\n/**\n * Register block definitions with the renderer. Re-registering a type replaces it (hot reload,\n * custom blocks overriding library blocks).\n */\nexport function registerBlocks(\n defs: readonly (AnyBlockDefinition | BlockDefinition<FieldsShape, string, ReactNode>)[],\n): void {\n for (const def of defs) blocks.set(def.type, def as AnyBlockDefinition);\n}\n\n/** Look up a registered block definition. */\nexport function getBlock(type: string): RendererBlockDefinition | undefined {\n return blocks.get(type) as RendererBlockDefinition | undefined;\n}\n\n/** All registered definitions. */\nexport function listBlocks(): RendererBlockDefinition[] {\n return [...blocks.values()] as RendererBlockDefinition[];\n}\n\n/** Remove one type, or every registration when called without arguments (tests). */\nexport function unregisterBlocks(...types: string[]): void {\n if (types.length === 0) blocks.clear();\n for (const t of types) blocks.delete(t);\n}\n\n/** The module-level registry as a {@link RendererBlockRegistry}. */\nexport const globalRegistry: RendererBlockRegistry = { get: (type) => blocks.get(type) };\n","import type {\n Announcement,\n Block,\n ColorTheme,\n Popup as PopupSettings,\n Site,\n} from \"@omniharmonic/openspace-schema\";\nimport { themeClass } from \"@omniharmonic/openspace-theme\";\nimport { type ReactNode, useContext } from \"react\";\nimport { BlockView } from \"./block\";\nimport { BlockRegistryContext } from \"./context\";\nimport { cx } from \"./cx\";\nimport { Img } from \"./image\";\nimport { Link } from \"./link\";\nimport { Button } from \"./primitives\";\nimport { globalRegistry } from \"./registry\";\nimport { SectionView } from \"./section\";\n\n/** Small stable hash (FNV-1a, base36) used for dismissal / frequency keys. */\nexport function shortHash(text: string): string {\n let h = 0x811c9dc5;\n for (let i = 0; i < text.length; i++) {\n h ^= text.charCodeAt(i);\n h = Math.imul(h, 0x01000193);\n }\n return (h >>> 0).toString(36);\n}\n\nfunction CloseIcon() {\n return (\n <svg viewBox=\"0 0 24 24\" width=\"20\" height=\"20\" aria-hidden=\"true\" focusable=\"false\">\n <path\n d=\"M6 6l12 12M18 6L6 18\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"1.6\"\n strokeLinecap=\"round\"\n />\n </svg>\n );\n}\n\n/** Site-wide announcement bar; dismissal (per message) is remembered by the `announcement` behavior. */\nexport function AnnouncementBar({\n announcement,\n}: {\n announcement: Announcement | null | undefined;\n}) {\n if (!announcement?.enabled) return null;\n const dismissible = announcement.dismissible ?? true;\n return (\n <aside\n className={cx(\"os-announcement\", themeClass(announcement.colorTheme ?? \"dark-accent\"))}\n aria-label=\"Announcement\"\n data-os-behavior={dismissible ? \"announcement\" : undefined}\n data-os-key={shortHash(announcement.message)}\n >\n <p className=\"os-announcement__text\">\n {announcement.link ? (\n <Link to={announcement.link} className=\"os-announcement__link\">\n {announcement.message}\n </Link>\n ) : (\n announcement.message\n )}\n </p>\n {dismissible && (\n <button type=\"button\" className=\"os-announcement__close\" data-os-dismiss=\"\">\n <CloseIcon />\n <span className=\"os-visually-hidden\">Dismiss announcement</span>\n </button>\n )}\n </aside>\n );\n}\n\n/** Site footer: the site's footer section inside a `<footer>` landmark, plus optional extras. */\nexport function Footer({ site, children }: { site: Site; children?: ReactNode }) {\n return (\n <footer className=\"os-footer\">\n <SectionView section={site.footer} as=\"div\" className=\"os-footer__section\" />\n {children}\n </footer>\n );\n}\n\nexport type PopupTrigger =\n | { type: \"time\"; seconds: number }\n | { type: \"scroll\"; percent: number }\n | { type: \"exit\" };\n\nexport interface PopupProps {\n /** Stable id; also the frequency-cap storage key. */\n id: string;\n trigger: PopupTrigger;\n /** Show at most once every N days per visitor (default 7; 0 = every visit). */\n frequencyDays?: number;\n /** Accessible title (rendered as the dialog heading). */\n title: string;\n colorTheme?: ColorTheme;\n children?: ReactNode;\n}\n\n/**\n * Promotional popup as a native `<dialog>` opened by the `popup` behavior on a time, scroll or\n * exit-intent trigger, capped per visitor via localStorage. Esc and the close button dismiss it.\n */\nexport function Popup({\n id,\n trigger,\n frequencyDays = 7,\n title,\n colorTheme = \"light\",\n children,\n}: PopupProps) {\n const triggerAttrs: Record<string, string> = { \"data-os-trigger\": trigger.type };\n if (trigger.type === \"time\") triggerAttrs[\"data-os-delay\"] = String(trigger.seconds);\n if (trigger.type === \"scroll\") triggerAttrs[\"data-os-scroll\"] = String(trigger.percent);\n const titleId = `${id}-title`;\n return (\n <dialog\n id={id}\n className={cx(\"os-popup\", themeClass(colorTheme))}\n aria-labelledby={titleId}\n data-os-behavior=\"popup\"\n data-os-frequency={String(frequencyDays)}\n {...triggerAttrs}\n >\n <div className=\"os-popup__body\">\n <h2 id={titleId} className=\"os-popup__title os-type-h3\">\n {title}\n </h2>\n {children}\n </div>\n <button type=\"button\" className=\"os-popup__close\" data-os-close=\"\">\n <CloseIcon />\n <span className=\"os-visually-hidden\">Close</span>\n </button>\n </dialog>\n );\n}\n\n/** Trigger props for the `<Popup>` from the site's pop-up settings. */\nexport function popupTrigger(popup: PopupSettings): PopupTrigger {\n if (popup.trigger === \"scroll\") return { type: \"scroll\", percent: popup.scrollPercent ?? 50 };\n if (popup.trigger === \"exit-intent\") return { type: \"exit\" };\n return { type: \"time\", seconds: popup.delaySeconds ?? 8 };\n}\n\n/** Block id for the pop-up's newsletter form (stable per site; never stored in content). */\nconst POPUP_NEWSLETTER_ID = \"blk_popupnews0\";\n\n/**\n * The site-wide pop-up from `site.popup` (heading, words, image, button, newsletter signup),\n * rendered with `<Popup>`. The newsletter form is the registered `newsletter` block, so it posts\n * to the Hub exactly like one placed on a page. Content changes reset the visitor frequency cap\n * (the dialog id hashes the heading).\n */\nexport function SitePopup({ popup }: { popup: PopupSettings | null | undefined }) {\n const registry = useContext(BlockRegistryContext) ?? globalRegistry;\n if (!popup?.enabled) return null;\n const newsletter: Block | null =\n popup.newsletter && registry.get(\"newsletter\")\n ? ({\n id: POPUP_NEWSLETTER_ID,\n type: \"newsletter\",\n v: 1,\n variant: \"stacked\",\n fields: {\n askName: false,\n placeholder: \"you@example.com\",\n buttonLabel: \"Subscribe\",\n successMessage: \"Almost there — check your inbox to confirm your subscription.\",\n },\n } as unknown as Block)\n : null;\n return (\n <Popup\n id={`os-popup-${shortHash(popup.heading)}`}\n trigger={popupTrigger(popup)}\n frequencyDays={popup.frequencyDays}\n title={popup.heading}\n colorTheme={popup.colorTheme ?? \"light\"}\n >\n {popup.image ? (\n <Img src={popup.image} className=\"os-popup__image\" sizes=\"34rem\" aspect=\"16:9\" />\n ) : null}\n {popup.body ? <p className=\"os-popup__text\">{popup.body}</p> : null}\n {popup.cta ? (\n <div className=\"os-popup__actions\">\n <Button to={popup.cta.link}>{popup.cta.label}</Button>\n </div>\n ) : null}\n {newsletter ? <BlockView block={newsletter} /> : null}\n </Popup>\n );\n}\n","import type {\n AspectRatio,\n FocalPoint,\n ImageTreatment,\n ImageValue,\n SiteDocument,\n} from \"@omniharmonic/openspace-schema\";\nimport { imageTreatmentClass } from \"@omniharmonic/openspace-theme\";\nimport { createContext, useContext } from \"react\";\nimport { useImageMap, useRenderContext } from \"./context\";\nimport { type CssVars, cx } from \"./cx\";\nimport type { ImageMap, ResolvedImage } from \"./image-map\";\nimport { mediaUrl } from \"./link\";\n\n/** Widths offered for remote images that support on-the-fly resizing (Unsplash, imgix). */\nexport const REMOTE_WIDTHS = [480, 640, 768, 960, 1080, 1440, 1920, 2400] as const;\n\nexport interface ImgProps {\n /** A media path / URL, or a full image value (src + alt + focal + dimensions). */\n src: string | ImageValue;\n /** Required unless `src` is an image value carrying `alt`. `\"\"` marks a decorative image. */\n alt?: string;\n /** `sizes` attribute; describe the rendered width so the browser picks the right file. */\n sizes?: string;\n width?: number;\n height?: number;\n /** Focal point `[x, y]` (0..1); drives `object-position` when the image is cropped. */\n focal?: FocalPoint;\n /** Crop to an aspect ratio (`4:5`, `16:9`); `original` keeps the intrinsic ratio. */\n aspect?: AspectRatio;\n /**\n * Image treatment. Omitted: the site's default treatment (from Site Styles). `\"none\"` opts out.\n */\n treatment?: ImageTreatment;\n fit?: \"cover\" | \"contain\";\n /**\n * Fill the parent's height, cropping at the focal point (grid-mode cells: the cell's rows set\n * the height, the image never stretches the row).\n */\n fill?: boolean;\n /** Above-the-fold image: eager load + high fetch priority. */\n priority?: boolean;\n className?: string;\n}\n\ninterface Resolved {\n src: string;\n srcset?: string | undefined;\n sources: { type: string; srcset: string }[];\n width?: number | undefined;\n height?: number | undefined;\n placeholder?: string | undefined;\n}\n\n/** Build a srcset for Unsplash/imgix-style URLs by rewriting the `w` query parameter. */\nexport function remoteSrcset(src: string, intrinsicWidth?: number): string | undefined {\n let url: URL;\n try {\n url = new URL(src);\n } catch {\n return undefined;\n }\n if (url.hostname !== \"images.unsplash.com\" && !url.hostname.endsWith(\".imgix.net\"))\n return undefined;\n const widths = REMOTE_WIDTHS.filter((w) => !intrinsicWidth || w <= intrinsicWidth);\n if (widths.length === 0) return undefined;\n return widths\n .map((w) => {\n const u = new URL(url.toString());\n u.searchParams.set(\"w\", String(w));\n if (!u.searchParams.has(\"auto\")) u.searchParams.set(\"auto\", \"format\");\n if (!u.searchParams.has(\"fit\")) u.searchParams.set(\"fit\", \"max\");\n return `${u.toString()} ${w}w`;\n })\n .join(\", \");\n}\n\n/** Resolve an image source through the image map, the media library, then raw fallbacks. */\nexport function resolveImage(\n src: string,\n opts: {\n imageMap?: ImageMap | undefined;\n doc?: SiteDocument | undefined;\n basePath?: string;\n width?: number | undefined;\n height?: number | undefined;\n } = {},\n): Resolved {\n const hit: ResolvedImage | undefined = opts.imageMap?.[src];\n if (hit) {\n return {\n src: hit.src,\n srcset: hit.srcset,\n sources: hit.sources ?? [],\n width: hit.width,\n height: hit.height,\n placeholder: hit.placeholder,\n };\n }\n const meta = opts.doc?.media[src];\n const width = opts.width ?? meta?.width;\n const height = opts.height ?? meta?.height;\n return {\n src: mediaUrl(src, opts.basePath),\n srcset: remoteSrcset(src, width),\n sources: [],\n width,\n height,\n placeholder: meta?.placeholder,\n };\n}\n\nfunction ratio(aspect: AspectRatio | undefined): string | undefined {\n if (!aspect || aspect === \"original\") return undefined;\n const [w, h] = aspect.split(\":\");\n return `${w} / ${h}`;\n}\n\nconst pct = (n: number) => `${Math.round(n * 1000) / 10}%`;\n\n/**\n * Above-the-fold images: the sources `SectionView` picked for the page's first section (the\n * first two in reading order, background first — the likely LCP element). Those load eagerly\n * with `fetchpriority=\"high\"`; every other image loads lazily unless `priority` is set. A plain\n * value computed from the section, so rendering stays pure.\n */\nexport type AboveFold = ReadonlySet<string>;\nexport const AboveFoldContext = createContext<AboveFold | null>(null);\n\n/**\n * Responsive image. Reads the `ImageResolverContext` map (AVIF/WebP sources, srcset, intrinsic\n * size, blurred placeholder), always emits width/height when known, crops with\n * `object-position` at the focal point, and applies image-treatment classes.\n */\nexport function Img(props: ImgProps) {\n const ctx = useRenderContext();\n const imageMap = useImageMap();\n const value: ImageValue | undefined = typeof props.src === \"string\" ? undefined : props.src;\n const src = typeof props.src === \"string\" ? props.src : props.src.src;\n const alt = props.alt ?? value?.alt ?? \"\";\n const focal = props.focal ?? value?.focal ?? ctx.doc?.media[src]?.focal;\n const r = resolveImage(src, {\n imageMap,\n doc: ctx.doc,\n basePath: ctx.basePath,\n width: props.width ?? value?.width,\n height: props.height ?? value?.height,\n });\n const sizes = props.sizes ?? \"100vw\";\n const aspect = props.fill ? undefined : ratio(props.aspect);\n const style: CssVars = {};\n if (aspect) style[\"--aspect\"] = aspect;\n if (focal) style[\"--focal\"] = `${pct(focal[0])} ${pct(focal[1])}`;\n const imgStyle = r.placeholder ? { backgroundImage: `url(\"${r.placeholder}\")` } : undefined;\n const fold = useContext(AboveFoldContext);\n // Later images in the first section stay lazy: on phones they're below the fold, and on\n // larger screens the browser still fetches lazy images that are in view right away.\n const high = props.priority ?? fold?.has(src) ?? false;\n const eager = high;\n return (\n <span\n className={cx(\n \"os-img\",\n props.treatment && imageTreatmentClass(props.treatment),\n aspect && \"has-aspect\",\n props.fit === \"contain\" && \"is-contain\",\n props.fill && \"is-fill\",\n !props.fill && !aspect && (r.width === undefined || r.height === undefined) && \"is-unsized\",\n props.className,\n )}\n style={Object.keys(style).length ? style : undefined}\n >\n <picture>\n {r.sources.map((s) => (\n <source key={s.type} type={s.type} srcSet={s.srcset} sizes={sizes} />\n ))}\n <img\n className={cx(\"os-img__img\", r.placeholder && \"has-placeholder\")}\n src={r.src}\n srcSet={r.srcset}\n sizes={r.srcset || r.sources.length ? sizes : undefined}\n width={r.width}\n height={r.height}\n alt={alt}\n loading={eager ? \"eager\" : \"lazy\"}\n decoding={high ? \"sync\" : \"async\"}\n fetchPriority={high ? \"high\" : undefined}\n style={imgStyle}\n />\n </picture>\n </span>\n );\n}\n","import type { Link as LinkValue, Page, SiteDocument } from \"@omniharmonic/openspace-schema\";\nimport type { AnchorHTMLAttributes, ReactNode } from \"react\";\nimport { useRenderContext } from \"./context\";\n\n/** Normalise a base path: `\"\"`, `\"/\"` → `\"\"`; `\"repo/\"` → `\"/repo\"`. */\nexport function normalizeBasePath(basePath: string | undefined): string {\n if (!basePath) return \"\";\n const trimmed = basePath.replace(/^\\/+|\\/+$/g, \"\");\n return trimmed ? `/${trimmed}` : \"\";\n}\n\n/** URL path of a page: home is `/`, others end with a slash (`/about/`). */\nexport function pagePath(page: Pick<Page, \"slug\">, basePath = \"\"): string {\n const base = normalizeBasePath(basePath);\n return page.slug ? `${base}/${page.slug}/` : `${base}/`;\n}\n\n/** URL path of a collection item: `/journal/opening-day/`. */\nexport function itemPath(collection: string, slug: string, basePath = \"\"): string {\n return `${normalizeBasePath(basePath)}/${collection}/${slug}/`;\n}\n\n/** Public URL of a media source: repo paths get the base path, remote URLs pass through. */\nexport function mediaUrl(src: string, basePath = \"\"): string {\n if (/^https?:\\/\\//.test(src) || src.startsWith(\"data:\")) return src;\n return `${normalizeBasePath(basePath)}/${src.replace(/^\\/+/, \"\")}`;\n}\n\n/** Prefix a site-relative path (`/schedule`) with the base path; leave everything else. */\nexport function withBase(href: string, basePath = \"\"): string {\n const base = normalizeBasePath(basePath);\n if (!base || !href.startsWith(\"/\") || href.startsWith(\"//\")) return href;\n if (href === base || href.startsWith(`${base}/`)) return href;\n return `${base}${href}`;\n}\n\nexport interface ResolvedLink {\n href: string;\n /** Open in a new tab (adds `target=\"_blank\" rel=\"noopener\"`). */\n newTab: boolean;\n /** The target no longer exists (deleted page/section). */\n broken: boolean;\n external: boolean;\n}\n\nexport interface LinkResolveOptions {\n doc?: SiteDocument | undefined;\n basePath?: string;\n /** The page being rendered: anchors to its own sections become `#fragment`. */\n currentPageId?: string | undefined;\n}\n\n/** In-page fragment for a section: its `anchor` if set, else its id. */\nexport function sectionFragment(section: { id: string; anchor?: string | undefined }): string {\n return section.anchor ?? section.id;\n}\n\n/** Resolve a link target (page, collection item, URL, email, phone, file, anchor) to an href. */\nexport function resolveLink(link: LinkValue, opts: LinkResolveOptions = {}): ResolvedLink {\n const base = opts.basePath ?? \"\";\n const ok = (href: string, newTab = false, external = false): ResolvedLink => ({\n href,\n newTab,\n broken: false,\n external,\n });\n switch (link.type) {\n case \"page\": {\n const page = opts.doc?.pages[link.page];\n if (opts.doc && !page) return { href: \"#\", newTab: false, broken: true, external: false };\n const path = page ? pagePath(page, base) : `${normalizeBasePath(base)}/`;\n const hash = link.anchor ? `#${link.anchor}` : \"\";\n if (hash && link.page === opts.currentPageId) return ok(hash);\n return ok(path + hash);\n }\n case \"item\": {\n const exists = opts.doc ? Boolean(opts.doc.collections[link.collection]?.[link.slug]) : true;\n return {\n href: itemPath(link.collection, link.slug, base),\n newTab: false,\n broken: !exists,\n external: false,\n };\n }\n case \"url\": {\n const external = /^https?:\\/\\//.test(link.url);\n return ok(external ? link.url : withBase(link.url, base), link.newTab ?? false, external);\n }\n case \"email\": {\n const subject = link.subject ? `?subject=${encodeURIComponent(link.subject)}` : \"\";\n return ok(`mailto:${link.email}${subject}`);\n }\n case \"phone\":\n return ok(`tel:${link.phone.replace(/[^+0-9]/g, \"\")}`);\n case \"file\":\n return ok(mediaUrl(link.src, base), link.newTab ?? false, /^https?:\\/\\//.test(link.src));\n case \"anchor\": {\n if (!opts.doc) return ok(`#${link.section}`);\n for (const page of Object.values(opts.doc.pages)) {\n const section = page.sections.find((s) => s.id === link.section);\n if (!section) continue;\n const hash = `#${sectionFragment(section)}`;\n return ok(page.id === opts.currentPageId ? hash : pagePath(page, base) + hash);\n }\n return { href: \"#\", newTab: false, broken: true, external: false };\n }\n }\n}\n\nexport interface LinkProps extends Omit<AnchorHTMLAttributes<HTMLAnchorElement>, \"href\"> {\n to: LinkValue;\n children?: ReactNode;\n}\n\n/** An `<a>` for a structured link, resolved against the current site and base path. */\nexport function Link({ to, children, ...rest }: LinkProps) {\n const ctx = useRenderContext();\n const r = resolveLink(to, { doc: ctx.doc, basePath: ctx.basePath, currentPageId: ctx.page?.id });\n const extra: Record<string, string> = {};\n if (r.newTab) {\n extra.target = \"_blank\";\n extra.rel = \"noopener\";\n }\n if (r.broken && ctx.mode !== \"production\") extra[\"data-os-broken-link\"] = \"\";\n return (\n <a href={r.href} {...extra} {...rest}>\n {children}\n </a>\n );\n}\n","import type { Link as LinkValue, SocialProfile } from \"@omniharmonic/openspace-schema\";\nimport type { ReactNode } from \"react\";\nimport { cx } from \"./cx\";\nimport { Link } from \"./link\";\n\nexport type ButtonRole = \"primary\" | \"secondary\" | \"tertiary\";\n\nexport interface ButtonProps {\n /** Link target; omit for a `<button>` (e.g. a form submit). */\n to?: LinkValue;\n role?: ButtonRole;\n type?: \"button\" | \"submit\";\n className?: string;\n children: ReactNode;\n /** Extra attributes (data-os-*, aria-*). */\n attrs?: Record<string, string | undefined>;\n}\n\n/**\n * A button styled by the Site Styles button system (`--os-button-<role>-*`). Renders an `<a>`\n * for links, a `<button>` otherwise.\n */\nexport function Button({\n to,\n role = \"primary\",\n type = \"button\",\n className,\n children,\n attrs,\n}: ButtonProps) {\n const cls = cx(\"os-button\", `os-button--${role}`, className);\n const label = <span className=\"os-button__label\">{children}</span>;\n if (to)\n return (\n <Link to={to} className={cls} {...attrs}>\n {label}\n </Link>\n );\n return (\n <button type={type} className={cls} {...attrs}>\n {label}\n </button>\n );\n}\n\nconst ICONS: Record<string, ReactNode> = {\n instagram: (\n <>\n <rect x=\"3\" y=\"3\" width=\"18\" height=\"18\" rx=\"5\" />\n <circle cx=\"12\" cy=\"12\" r=\"4\" />\n <circle cx=\"17.5\" cy=\"6.5\" r=\"0.6\" fill=\"currentColor\" />\n </>\n ),\n facebook: <path d=\"M14 8h3V4h-3a4 4 0 0 0-4 4v3H7v4h3v7h4v-7h3l1-4h-4V8z\" />,\n x: <path d=\"M4 4l16 16M20 4L4 20\" />,\n threads: <path d=\"M16 11c-1-4-8-4-8 1s7 5 7 1-5-3-5-1M12 21a9 9 0 1 1 8-12\" />,\n bluesky: (\n <path d=\"M12 11C10 7 6 4 4 5s0 7 4 8c-3 1-3 4 0 5s4-3 4-5c0 2 1 6 4 5s3-4 0-5c4-1 6-7 4-8s-6 2-8 6z\" />\n ),\n linkedin: (\n <>\n <rect x=\"3\" y=\"3\" width=\"18\" height=\"18\" rx=\"3\" />\n <path d=\"M8 10v7M8 7v.01M12 17v-4a2 2 0 0 1 4 0v4M12 10v7\" />\n </>\n ),\n youtube: (\n <>\n <rect x=\"2\" y=\"5\" width=\"20\" height=\"14\" rx=\"4\" />\n <path d=\"M10 9l5 3-5 3z\" fill=\"currentColor\" />\n </>\n ),\n tiktok: <path d=\"M14 3v11a4 4 0 1 1-4-4M14 3c0 3 2 5 5 5\" />,\n email: (\n <>\n <rect x=\"3\" y=\"5\" width=\"18\" height=\"14\" rx=\"2\" />\n <path d=\"M3 7l9 6 9-6\" />\n </>\n ),\n github: (\n <path d=\"M9 19c-4 1.5-4-2-6-2m12 4v-3.5c0-1 .1-1.4-.5-2 2.8-.3 5.5-1.4 5.5-6a4.6 4.6 0 0 0-1.3-3.2 4.2 4.2 0 0 0-.1-3.2s-1.1-.3-3.5 1.3a12 12 0 0 0-6.2 0C6.5 2.8 5.4 3.1 5.4 3.1a4.2 4.2 0 0 0-.1 3.2A4.6 4.6 0 0 0 4 9.5c0 4.6 2.7 5.7 5.5 6-.6.6-.6 1.2-.5 2V21\" />\n ),\n};\n\nconst GENERIC_ICON = (\n <>\n <circle cx=\"12\" cy=\"12\" r=\"9\" />\n <path d=\"M3 12h18M12 3a14 14 0 0 1 0 18M12 3a14 14 0 0 0 0 18\" />\n </>\n);\n\nconst NETWORK_LABEL: Partial<Record<string, string>> = {\n x: \"X\",\n linkedin: \"LinkedIn\",\n youtube: \"YouTube\",\n tiktok: \"TikTok\",\n github: \"GitHub\",\n soundcloud: \"SoundCloud\",\n tripadvisor: \"Tripadvisor\",\n};\n\nexport function networkLabel(network: string): string {\n return NETWORK_LABEL[network] ?? network.charAt(0).toUpperCase() + network.slice(1);\n}\n\n/** Small outline icon for a social network (inherits `currentColor`). */\nexport function SocialIcon({ network }: { network: string }) {\n return (\n <svg\n className=\"os-icon\"\n viewBox=\"0 0 24 24\"\n width=\"20\"\n height=\"20\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"1.6\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden=\"true\"\n focusable=\"false\"\n >\n {ICONS[network] ?? GENERIC_ICON}\n </svg>\n );\n}\n\n/** A row of social profile links with accessible names. */\nexport function SocialLinks({\n profiles,\n className,\n}: {\n profiles: readonly SocialProfile[];\n className?: string;\n}) {\n if (profiles.length === 0) return null;\n return (\n <ul className={cx(\"os-social\", className)}>\n {profiles.map((p) => (\n <li key={p.url}>\n <a\n href={p.url}\n className=\"os-social__link\"\n rel=\"me noopener\"\n target={p.network === \"email\" ? undefined : \"_blank\"}\n >\n <SocialIcon network={p.network} />\n <span className=\"os-visually-hidden\">{networkLabel(p.network)}</span>\n </a>\n </li>\n ))}\n </ul>\n );\n}\n","import type { Section, SectionBackground } from \"@omniharmonic/openspace-schema\";\nimport { themeClass } from \"@omniharmonic/openspace-theme\";\nimport { createContext, type ReactNode, useContext } from \"react\";\nimport { BlockView, MissingBlock } from \"./block\";\nimport { SectionContext, useEditor, useRenderContext } from \"./context\";\nimport { type CssVars, cx } from \"./cx\";\nimport { AboveFoldContext, Img } from \"./image\";\nimport { collectImageSrcs } from \"./image-map\";\nimport {\n blocksByColumn,\n colorValue,\n fallbackMobileRects,\n gridItemVars,\n gridVars,\n mobileRows,\n sectionStyleVars,\n stackColumnVars,\n stackVars,\n} from \"./layout-vars\";\nimport { mediaUrl, sectionFragment } from \"./link\";\n\n/** True for the first section of a page (its background image loads eagerly). */\nexport const FirstSectionContext = createContext(false);\n\nfunction overlayVars(overlay: { color: string; opacity: number } | undefined): CssVars | undefined {\n if (!overlay) return undefined;\n return { \"--overlay\": colorValue(overlay.color), \"--overlay-opacity\": overlay.opacity };\n}\n\n/** Color/gradient backgrounds become a `--bg` var; image/video become a layer element. */\nexport function backgroundVars(bg: SectionBackground | undefined): CssVars {\n if (!bg) return {};\n if (bg.type === \"color\") return { \"--bg\": colorValue(bg.color) };\n if (bg.type === \"gradient\") {\n const stops = [bg.from, bg.via, bg.to].filter(Boolean).map((c) => colorValue(c as string));\n return { \"--bg\": `linear-gradient(${bg.angle ?? 180}deg, ${stops.join(\", \")})` };\n }\n return {};\n}\n\nexport function SectionBackgroundLayer({\n background,\n}: {\n background: SectionBackground | undefined;\n}) {\n const { basePath } = useRenderContext();\n const first = useContext(FirstSectionContext);\n if (!background) return null;\n if (background.type === \"image\") {\n return (\n <div\n className={cx(\"os-section__bg\", background.parallax && \"is-parallax\")}\n aria-hidden=\"true\"\n >\n <Img\n src={background.src}\n alt=\"\"\n sizes=\"100vw\"\n treatment=\"none\"\n fill\n {...(background.focal ? { focal: background.focal } : {})}\n priority={first}\n className=\"os-section__media\"\n />\n {background.overlay && (\n <div className=\"os-section__overlay\" style={overlayVars(background.overlay)} />\n )}\n </div>\n );\n }\n if (background.type === \"video\") {\n const focal = background.focal;\n return (\n <div className=\"os-section__bg\" aria-hidden=\"true\">\n <video\n className=\"os-section__media os-section__video\"\n data-os-behavior=\"video-lite\"\n data-os-autoplay=\"\"\n muted\n loop\n playsInline\n preload=\"none\"\n poster={background.poster ? mediaUrl(background.poster, basePath) : undefined}\n style={focal ? { objectPosition: `${focal[0] * 100}% ${focal[1] * 100}%` } : undefined}\n >\n <source src={mediaUrl(background.src, basePath)} />\n </video>\n {background.overlay && (\n <div className=\"os-section__overlay\" style={overlayVars(background.overlay)} />\n )}\n </div>\n );\n }\n return null;\n}\n\nfunction StackBody({ section }: { section: Section & { layout: { mode: \"stack\" } } }) {\n const { layout } = section;\n const { mode } = useRenderContext();\n const cols = blocksByColumn(\n layout,\n section.blocks.filter((b) => !b.hidden || mode === \"editor\"),\n );\n return (\n <div\n className={cx(\n \"os-section__inner os-stack\",\n `os-w-${layout.width ?? \"content\"}`,\n layout.align && `is-align-${layout.align}`,\n cols.length > 1 && \"is-multi\",\n )}\n style={stackVars(layout)}\n >\n {cols.map((blocks, i) => {\n const vars = stackColumnVars(layout, i);\n return (\n <div\n // biome-ignore lint/suspicious/noArrayIndexKey: columns are positional\n key={i}\n className=\"os-col\"\n data-os-col={i}\n style={Object.keys(vars).length ? vars : undefined}\n >\n {blocks.map((b) => (\n <BlockView key={b.id} block={b} section={section} />\n ))}\n </div>\n );\n })}\n </div>\n );\n}\n\nfunction GridBody({ section }: { section: Section & { layout: { mode: \"grid\" } } }) {\n const { layout } = section;\n const { mode } = useRenderContext();\n const fallback = fallbackMobileRects(layout);\n const vars = { ...gridVars(layout), \"--mrows\": mobileRows(layout, fallback) };\n // DOM order follows desktop reading order (top-to-bottom, left-to-right) for assistive tech.\n const ordered = section.blocks\n .filter((b) => !b.hidden || mode === \"editor\")\n .sort((a, b) => {\n const ra = layout.items[a.id]?.d;\n const rb = layout.items[b.id as keyof typeof layout.items]?.d;\n if (!ra || !rb) return 0;\n return ra.y - rb.y || ra.x - rb.x;\n });\n return (\n <div\n className={cx(\"os-section__inner os-grid\", `os-w-${layout.width ?? \"content\"}`)}\n style={vars}\n >\n {ordered.map((b) =>\n layout.items[b.id as keyof typeof layout.items] ? (\n <div\n key={b.id}\n className=\"os-grid__item\"\n data-os-item={b.id}\n style={gridItemVars(layout, b.id, fallback)}\n >\n <BlockView block={b} section={section} />\n </div>\n ) : mode !== \"production\" ? (\n <div key={b.id} className=\"os-grid__item os-grid__item--unplaced\" data-os-unplaced={b.id}>\n <MissingBlock block={b} reason=\"This block has no position in the grid\" />\n </div>\n ) : null,\n )}\n </div>\n );\n}\n\nexport interface SectionViewProps {\n section: Section;\n /** Element to render (`div` for the footer's inner section). */\n as?: \"section\" | \"div\";\n /** Extra classes on the section element. */\n className?: string;\n children?: ReactNode;\n}\n\n/**\n * The section's lead image sources (background first): the first image in reading order on\n * desktop and the first on phones (grid sections place blocks separately per breakpoint, and\n * phones are where LCP is hardest), then more in desktop order, `count` in all.\n */\nexport function leadImages(section: Section, count = 2): ReadonlySet<string> {\n const layout = section.layout;\n const order = (bp: \"d\" | \"m\") =>\n layout.mode === \"stack\"\n ? [...section.blocks].sort((a, b) => (a.column ?? 0) - (b.column ?? 0))\n : section.blocks\n // Placed blocks by row then column; any without a layout item keep their order after.\n .map((b, i) => {\n const item = layout.items[b.id];\n return { b, i, r: bp === \"m\" ? (item?.m ?? item?.d) : item?.d };\n })\n .sort((p, q) =>\n p.r && q.r\n ? p.r.y - q.r.y || p.r.x - q.r.x || p.i - q.i\n : p.r\n ? -1\n : q.r\n ? 1\n : p.i - q.i,\n )\n .map((p) => p.b);\n const images = (blocks: Section[\"blocks\"]) => {\n const srcs = new Set<string>();\n for (const b of blocks) collectImageSrcs(b.fields, srcs);\n return [...srcs];\n };\n const desktop = images(order(\"d\"));\n const phone = layout.mode === \"grid\" ? images(order(\"m\")) : desktop;\n const out: string[] = [];\n const bg = section.style.background;\n if (bg?.type === \"image\" && bg.src) out.push(bg.src);\n for (const src of [phone[0], desktop[0], ...desktop])\n if (src && !out.includes(src) && out.length < count) out.push(src);\n return new Set(out);\n}\n\n/**\n * A page section: color-theme wrapper, background layer, then the stack or grid body. Every\n * per-instance value is an inline custom property; classes come from the shared stylesheet.\n */\nexport function SectionView({ section, as: Tag = \"section\", className }: SectionViewProps) {\n const { mode } = useRenderContext();\n const editor = useEditor();\n const first = useContext(FirstSectionContext);\n if (section.hidden && mode !== \"editor\") return null;\n const { style, layout } = section;\n const vars = { ...sectionStyleVars(style), ...backgroundVars(style.background) };\n const bgType = style.background?.type ?? \"none\";\n const entrance = style.animation?.entrance;\n const reveal =\n entrance && entrance !== \"none\" && mode !== \"editor\"\n ? {\n \"data-os-behavior\": \"reveal\",\n \"data-os-reveal\": entrance,\n ...(style.animation?.stagger ? { \"data-os-stagger\": \"\" } : {}),\n }\n : {};\n const el = (\n <Tag\n id={sectionFragment(section)}\n className={cx(\n \"os-section\",\n themeClass(style.colorTheme ?? \"light\"),\n `os-section--${layout.mode}`,\n bgType !== \"none\" && `has-bg-${bgType}`,\n style.minHeight && \"has-minh\",\n style.padding && \"has-pad\",\n first && \"os-section--first\",\n className,\n )}\n data-os-id={section.id}\n data-os-section=\"\"\n data-os-hidden={section.hidden ? \"\" : undefined}\n style={Object.keys(vars).length ? vars : undefined}\n {...reveal}\n >\n <SectionContext.Provider value={section}>\n <AboveFoldContext.Provider value={first ? leadImages(section) : null}>\n <SectionBackgroundLayer background={style.background} />\n {layout.mode === \"stack\" ? (\n <StackBody section={section as Section & { layout: { mode: \"stack\" } }} />\n ) : (\n <GridBody section={section as Section & { layout: { mode: \"grid\" } }} />\n )}\n </AboveFoldContext.Provider>\n </SectionContext.Provider>\n </Tag>\n );\n return editor?.wrapSection ? editor.wrapSection({ section, children: el }) : el;\n}\n","/**\n * The image resolution contract (arch §4.3). site-kit walks a page, resolves every image through\n * Astro's `getImage()` and passes the result in; `<Img>` reads it. Keys are the `src` exactly as\n * stored in content (`media/2026/10/hero.jpg` or an https URL).\n */\nexport interface ResolvedImageSource {\n /** MIME type, e.g. `image/avif`, `image/webp`. */\n type: string;\n srcset: string;\n}\n\nexport interface ResolvedImage {\n /** Fallback URL (JPEG/PNG) for `<img src>`. */\n src: string;\n /** Fallback-format srcset for `<img srcset>`. */\n srcset?: string;\n /** Modern formats, best first, rendered as `<source>`s. */\n sources?: ResolvedImageSource[];\n /** Intrinsic dimensions (always emitted: no layout shift). */\n width: number;\n height: number;\n /** Tiny blurred placeholder data URI (< 300 bytes). */\n placeholder?: string;\n}\n\nexport type ImageMap = Readonly<Record<string, ResolvedImage>>;\n\n/** Every image `src` referenced by a JSON value (pages, site, blocks). */\nexport function collectImageSrcs(value: unknown, out: Set<string> = new Set()): Set<string> {\n if (typeof value === \"string\") {\n if (/^media\\/.+\\.(?:jpe?g|png|webp|avif|gif|svg)$/i.test(value) || isRemoteImage(value))\n out.add(value);\n } else if (Array.isArray(value)) {\n for (const v of value) collectImageSrcs(v, out);\n } else if (value && typeof value === \"object\") {\n for (const v of Object.values(value)) collectImageSrcs(v, out);\n }\n return out;\n}\n\nfunction isRemoteImage(value: string): boolean {\n return (\n /^https:\\/\\/images\\.unsplash\\.com\\//.test(value) ||\n /^https:\\/\\/\\S+\\.(?:jpe?g|png|webp|avif|gif)(?:\\?\\S*)?$/i.test(value)\n );\n}\n","import type {\n CollectionConfig,\n CollectionItem,\n ImageValue,\n ReferenceValue,\n} from \"@omniharmonic/openspace-schema\";\nimport { createContext, useContext } from \"react\";\nimport { useRenderContext } from \"./context\";\nimport { eventLengthDays, eventOn, expandOccurrences, occurrenceDates } from \"./recurrence\";\n\n/**\n * Collection data for blocks that list items (summary, events, product, social feed).\n *\n * By default blocks read `doc.collections` from the {@link RenderContext}. Hosts that hold\n * collection data elsewhere provide it through `CollectionsContext`: site-kit passes the parsed\n * content collections, the build time (`now`) and build-time social feeds; Studio passes the\n * items it has loaded. Values given here take precedence over the document.\n */\nexport interface CollectionsValue {\n /** Items by collection name, then slug. Defaults to `doc.collections`. */\n collections?: Record<string, Record<string, CollectionItem>>;\n /** `_collection.json` per collection. Defaults to `doc.collectionConfigs`. */\n configs?: Record<string, CollectionConfig>;\n /**\n * Reference time for \"upcoming\" filters and scheduled items. Static builds pass the build\n * time so output is deterministic. Defaults to the current time.\n */\n now?: Date | string;\n /**\n * Include drafts and not-yet-due scheduled items. Defaults to `true` in the Studio editor and\n * previews and `false` in production.\n */\n includeDrafts?: boolean;\n /** Build-time social feed posts, keyed by {@link feedKey} (`instagram:juniperyoga`). */\n feeds?: Record<string, SocialFeedPost[]>;\n}\n\n/** One post of a build-time social feed (fetched by site-kit with the owner's authorization). */\nexport interface SocialFeedPost {\n /** Link to the post on the network (https). */\n url: string;\n image: ImageValue;\n caption?: string;\n /** ISO date or date-time. */\n date?: string;\n}\n\nexport const CollectionsContext = createContext<CollectionsValue | undefined>(undefined);\n\n/** Key for {@link CollectionsValue.feeds}: `network:handle`, lowercased, without a leading `@`. */\nexport function feedKey(network: string, handle: string): string {\n return `${network}:${handle.replace(/^@/, \"\")}`.toLowerCase();\n}\n\nexport interface ResolvedCollections {\n collections: Record<string, Record<string, CollectionItem>>;\n configs: Record<string, CollectionConfig>;\n now: Date;\n includeDrafts: boolean;\n feeds: Record<string, SocialFeedPost[]>;\n}\n\n/** Collection data for the current render (context value merged over the site document). */\nexport function useCollections(): ResolvedCollections {\n const ctx = useRenderContext();\n const value = useContext(CollectionsContext);\n return {\n collections: value?.collections ?? ctx.doc?.collections ?? {},\n configs: value?.configs ?? ctx.doc?.collectionConfigs ?? {},\n now: value?.now === undefined ? new Date() : new Date(value.now),\n includeDrafts: value?.includeDrafts ?? ctx.mode !== \"production\",\n feeds: value?.feeds ?? {},\n };\n}\n\n/** The item's primary date: post/episode/project date or event start. */\nexport function itemDate(item: CollectionItem): string | undefined {\n const fm = item.frontmatter as { date?: string; start?: string };\n return item.kind === \"events\" ? fm.start : fm.date;\n}\n\n/** Published (or scheduled and due) at `now`. */\nexport function isLive(item: CollectionItem, now: Date): boolean {\n const fm = item.frontmatter;\n if (fm.status === \"published\") return true;\n if (fm.status === \"scheduled\" && fm.publishAt) return Date.parse(fm.publishAt) <= now.getTime();\n return false;\n}\n\n/** Today's date (`YYYY-MM-DD`) in a time zone; UTC when the zone is missing or unknown. */\nfunction todayIn(now: Date, timeZone: string | undefined): string {\n for (const tz of [timeZone, \"UTC\"]) {\n try {\n // en-CA formats as YYYY-MM-DD.\n return new Intl.DateTimeFormat(\"en-CA\", {\n timeZone: tz ?? \"UTC\",\n year: \"numeric\",\n month: \"2-digit\",\n day: \"2-digit\",\n }).format(now);\n } catch {\n /* unknown zone: fall back to UTC */\n }\n }\n return now.toISOString().slice(0, 10);\n}\n\n/**\n * An event is upcoming until it ends. Date-only events (`2026-11-14`) count as upcoming for\n * that whole day in the event's own time zone (`timezone`, else UTC).\n */\nexport function isUpcoming(item: CollectionItem, now: Date): boolean {\n if (item.kind !== \"events\") return true;\n const fm = item.frontmatter;\n const last = fm.end ?? fm.start;\n if (/^\\d{4}-\\d{2}-\\d{2}$/.test(last)) return last >= todayIn(now, fm.timezone);\n return Date.parse(last) >= now.getTime();\n}\n\nconst time = (item: CollectionItem) => {\n const d = itemDate(item);\n return d ? Date.parse(d) : 0;\n};\n\nconst isoDay = (d: Date) => d.toISOString().slice(0, 10);\nconst plusDays = (d: Date, n: number) => isoDay(new Date(d.getTime() + n * 86_400_000));\n\n/** How far ahead (and back, for past events) repeating events are listed. */\nexport const RECURRENCE_HORIZON_DAYS = 366;\n\n/** A repeating event shown at its next date (or its last one, once the series is over). */\nexport function nextOccurrence(item: CollectionItem, now: Date): CollectionItem {\n if (item.kind !== \"events\" || !item.frontmatter.recurrence) return item;\n const rule = item.frontmatter.recurrence;\n const start = item.frontmatter.start;\n // From as far back as the event lasts (an occurrence may still be running), the next few dates.\n const soon = occurrenceDates(rule, start, {\n from: plusDays(now, -(eventLengthDays(item) + 1)),\n through: plusDays(now, RECURRENCE_HORIZON_DAYS),\n max: 4,\n });\n const upcoming = soon.map((d) => eventOn(item, d)).find((e) => isUpcoming(e, now));\n if (upcoming) return upcoming;\n // The series is over: show its last date (searching back from today, a year at a time).\n for (let back = 1; back <= 50; back++) {\n const past = occurrenceDates(rule, start, {\n from: plusDays(now, -RECURRENCE_HORIZON_DAYS * back),\n through: isoDay(now),\n });\n if (past.length) return eventOn(item, past[past.length - 1] as string);\n if (plusDays(now, -RECURRENCE_HORIZON_DAYS * back) < start.slice(0, 10)) break;\n }\n return item;\n}\n\nexport interface QueryOptions {\n now?: Date;\n includeDrafts?: boolean;\n}\n\n/**\n * Items a `reference` field selects: explicit picks (in their order) or the filter, then sort\n * and limit. Drafts and not-yet-due scheduled items are excluded unless `includeDrafts`.\n * `filter.upcoming: true` keeps events that haven't ended; `false` keeps past events.\n */\nexport function queryCollection(\n ref: ReferenceValue,\n collections: Record<string, Record<string, CollectionItem>>,\n opts: QueryOptions = {},\n): CollectionItem[] {\n const now = opts.now ?? new Date();\n const all = collections[ref.collection] ?? {};\n const visible = (item: CollectionItem | undefined): item is CollectionItem =>\n !!item && (opts.includeDrafts === true || isLive(item, now));\n\n let items: CollectionItem[];\n if (ref.items) {\n items = ref.items\n .map((slug) => all[slug])\n .filter(visible)\n .map((item) => nextOccurrence(item, now));\n } else {\n const f = ref.filter;\n const live = Object.values(all).filter(visible);\n // Repeating events list once per date: upcoming ones for the next year, past ones for the last\n // year; without a date filter each series shows at its next date.\n const expanded =\n f?.upcoming === true\n ? expandOccurrences(live, {\n from: isoDay(now),\n through: plusDays(now, RECURRENCE_HORIZON_DAYS),\n })\n : f?.upcoming === false\n ? expandOccurrences(live, {\n from: plusDays(now, -RECURRENCE_HORIZON_DAYS),\n through: isoDay(now),\n newest: true,\n })\n : live.map((item) => nextOccurrence(item, now));\n items = expanded.filter((item) => {\n const fm = item.frontmatter;\n if (f?.categories?.length && !f.categories.some((c) => fm.categories?.includes(c)))\n return false;\n if (f?.tags?.length) {\n const tags = (fm.tags ?? []).map((t) => t.toLowerCase());\n if (!f.tags.some((t) => tags.includes(t.toLowerCase()))) return false;\n }\n if (f?.featured !== undefined && (fm.featured === true) !== f.featured) return false;\n if (f?.upcoming !== undefined && isUpcoming(item, now) !== f.upcoming) return false;\n return true;\n });\n }\n\n const sort = ref.sort ?? (ref.items ? \"manual\" : ref.filter?.upcoming ? \"date-asc\" : \"date-desc\");\n if (sort === \"date-desc\") items.sort((a, b) => time(b) - time(a));\n else if (sort === \"date-asc\") items.sort((a, b) => time(a) - time(b));\n else if (sort === \"title\")\n items.sort((a, b) => a.frontmatter.title.localeCompare(b.frontmatter.title));\n return ref.limit ? items.slice(0, ref.limit) : items;\n}\n\n/** `queryCollection` bound to the current render's collections, time and draft policy. */\nexport function useCollectionQuery(ref: ReferenceValue): CollectionItem[] {\n const { collections, now, includeDrafts } = useCollections();\n return queryCollection(ref, collections, { now, includeDrafts });\n}\n","import type { CollectionItem } from \"@omniharmonic/openspace-schema\";\n\n/**\n * Repeating events (RFC 5545 RRULE bodies such as `FREQ=WEEKLY;BYDAY=TU,TH;COUNT=10`), the\n * subset Studio writes: DAILY / WEEKLY / MONTHLY / YEARLY, INTERVAL, BYDAY (weekly days or\n * monthly \"2TU\"), BYMONTHDAY, COUNT and UNTIL. Dates are calendar dates as written (the\n * event's own time zone); the first date always counts as an occurrence.\n */\n\nconst DAYS = [\"SU\", \"MO\", \"TU\", \"WE\", \"TH\", \"FR\", \"SA\"] as const;\nconst WEEK = [\"MO\", \"TU\", \"WE\", \"TH\", \"FR\", \"SA\", \"SU\"] as const;\nconst DAY_MS = 86_400_000;\n\nexport interface RecurrenceRule {\n freq: \"DAILY\" | \"WEEKLY\" | \"MONTHLY\" | \"YEARLY\";\n interval: number;\n /** Weekly days, e.g. [\"TU\", \"TH\"]. */\n byDay: string[];\n /** Monthly \"nth weekday\" (1–5 or -1), from BYDAY=2TU. */\n nth?: { n: number; day: string };\n byMonthDay?: number;\n count?: number;\n /** Last allowed date, YYYY-MM-DD. */\n until?: string;\n}\n\nexport function parseRecurrence(rule: string): RecurrenceRule | null {\n const map = new Map<string, string>();\n for (const part of rule.replace(/^RRULE:/i, \"\").split(\";\")) {\n const [k, v] = part.split(\"=\");\n if (k && v) map.set(k.toUpperCase(), v.toUpperCase());\n }\n const freq = map.get(\"FREQ\");\n if (freq !== \"DAILY\" && freq !== \"WEEKLY\" && freq !== \"MONTHLY\" && freq !== \"YEARLY\") return null;\n const interval = Math.max(1, Number(map.get(\"INTERVAL\") ?? 1) || 1);\n const out: RecurrenceRule = { freq, interval, byDay: [] };\n for (const d of (map.get(\"BYDAY\") ?? \"\").split(\",\").filter(Boolean)) {\n const m = /^([+-]?\\d)?(MO|TU|WE|TH|FR|SA|SU)$/.exec(d);\n if (!m) continue;\n if (m[1] && freq === \"MONTHLY\") out.nth = { n: Number(m[1]), day: m[2] as string };\n else out.byDay.push(m[2] as string);\n }\n const bmd = Number(map.get(\"BYMONTHDAY\"));\n if (Number.isInteger(bmd) && bmd > 0) out.byMonthDay = bmd;\n const count = Number(map.get(\"COUNT\"));\n if (Number.isInteger(count) && count > 0) out.count = count;\n const until = map.get(\"UNTIL\");\n if (until && /^\\d{8}/.test(until))\n out.until = `${until.slice(0, 4)}-${until.slice(4, 6)}-${until.slice(6, 8)}`;\n return out;\n}\n\nconst utc = (y: number, m: number, d: number) => new Date(Date.UTC(y, m - 1, d));\nconst iso = (d: Date) => d.toISOString().slice(0, 10);\n\n/**\n * Occurrence dates (YYYY-MM-DD) of a rule starting on `start`, in order.\n * - `from` / `through` bound the dates returned (inclusive);\n * - `max` caps how many are returned (counted from `from`, never from the first date);\n * - COUNT is counted from the first date, as RFC 5545 says (DTSTART is the first occurrence).\n * Without COUNT, the walk jumps straight to `from`, so a series that started years ago costs the\n * same as a new one.\n */\nexport function occurrenceDates(\n rule: string | RecurrenceRule,\n start: string,\n options: { from?: string; through?: string; max?: number } = {},\n): string[] {\n const r = typeof rule === \"string\" ? parseRecurrence(rule) : rule;\n const m = /^(\\d{4})-(\\d{2})-(\\d{2})/.exec(start);\n if (!m) return [];\n const y = Number(m[1]);\n const mo = Number(m[2]);\n const d = Number(m[3]);\n const first = utc(y, mo, d);\n const from = options.from ?? iso(first);\n const max = options.max ?? 500;\n if (!r) return iso(first) >= from && max > 0 ? [iso(first)] : [];\n const last = [r.until, options.through].filter(Boolean).sort()[0];\n const over = (date: Date) => (last ? iso(date) > last : false);\n const out: string[] = [];\n const seen = new Set<string>();\n let total = 0;\n const take = (date: Date) => {\n const s = iso(date);\n if (date < first || seen.has(s)) return;\n seen.add(s);\n total += 1;\n if (s >= from) out.push(s);\n };\n const done = () => out.length >= max || (r.count !== undefined && total >= r.count);\n\n // Jump close to `from` when COUNT doesn't need every earlier date (whole periods only).\n let i0 = 0;\n if (r.count === undefined && from > iso(first)) {\n const f = new Date(`${from}T00:00:00Z`);\n const days = Math.floor((f.getTime() - first.getTime()) / DAY_MS);\n const months = (f.getUTCFullYear() - y) * 12 + (f.getUTCMonth() + 1 - mo);\n const periods =\n r.freq === \"DAILY\"\n ? days / r.interval\n : r.freq === \"WEEKLY\"\n ? days / (7 * r.interval)\n : r.freq === \"MONTHLY\"\n ? months / r.interval\n : (f.getUTCFullYear() - y) / r.interval;\n i0 = Math.max(0, Math.floor(periods) - 1);\n }\n if (i0 === 0) take(first); // DTSTART is always the first occurrence.\n\n for (let i = i0; !done() && i < i0 + 20_000; i++) {\n const batch: Date[] = [];\n if (r.freq === \"DAILY\") batch.push(utc(y, mo, d + i * r.interval));\n else if (r.freq === \"WEEKLY\") {\n const monday = utc(y, mo, d - ((first.getUTCDay() + 6) % 7) + i * 7 * r.interval);\n const days = r.byDay.length ? r.byDay : [DAYS[first.getUTCDay()] as string];\n for (const day of WEEK)\n if (days.includes(day))\n batch.push(\n utc(\n monday.getUTCFullYear(),\n monday.getUTCMonth() + 1,\n monday.getUTCDate() + WEEK.indexOf(day),\n ),\n );\n } else if (r.freq === \"MONTHLY\") {\n const month = utc(y, mo + i * r.interval, 1);\n if (r.nth) {\n const want = DAYS.indexOf(r.nth.day as (typeof DAYS)[number]);\n if (r.nth.n > 0) {\n const offset = (want - month.getUTCDay() + 7) % 7;\n const date = utc(\n month.getUTCFullYear(),\n month.getUTCMonth() + 1,\n 1 + offset + (r.nth.n - 1) * 7,\n );\n if (date.getUTCMonth() === month.getUTCMonth()) batch.push(date);\n } else {\n const end = utc(month.getUTCFullYear(), month.getUTCMonth() + 2, 0);\n const back = (end.getUTCDay() - want + 7) % 7;\n batch.push(utc(end.getUTCFullYear(), end.getUTCMonth() + 1, end.getUTCDate() - back));\n }\n } else {\n const day = r.byMonthDay ?? d;\n const date = utc(month.getUTCFullYear(), month.getUTCMonth() + 1, day);\n if (date.getUTCDate() === day) batch.push(date); // months without that date are skipped\n }\n } else {\n const date = utc(y + i * r.interval, mo, d);\n if (date.getUTCDate() === d) batch.push(date);\n }\n let stop = false;\n for (const date of batch) {\n if (done()) break;\n if (over(date)) {\n stop = true;\n break;\n }\n take(date);\n }\n if (stop) break;\n }\n return out;\n}\n\n/** UTC offset (minutes) of an IANA zone at an instant; null when the zone is unknown. */\nexport function zoneOffsetMinutes(timeZone: string, at: number): number | null {\n try {\n const parts = new Intl.DateTimeFormat(\"en-US\", {\n timeZone,\n hourCycle: \"h23\",\n year: \"numeric\",\n month: \"2-digit\",\n day: \"2-digit\",\n hour: \"2-digit\",\n minute: \"2-digit\",\n second: \"2-digit\",\n }).formatToParts(new Date(at));\n const n = (t: string) => Number(parts.find((p) => p.type === t)?.value);\n const wall = Date.UTC(n(\"year\"), n(\"month\") - 1, n(\"day\"), n(\"hour\"), n(\"minute\"), n(\"second\"));\n return Math.round((wall - at) / 60_000);\n } catch {\n return null;\n }\n}\n\nconst fmtOffset = (min: number) => {\n const sign = min < 0 ? \"-\" : \"+\";\n const a = Math.abs(min);\n return `${sign}${String(Math.floor(a / 60)).padStart(2, \"0\")}:${String(a % 60).padStart(2, \"0\")}`;\n};\n\n/**\n * A date-time on another day at the same local wall time. With an IANA `timeZone` the offset is\n * the zone's offset on that day (so 7pm stays 7pm across daylight-saving changes); otherwise the\n * written offset is kept.\n */\nexport function shiftDateTime(value: string, days: number, timeZone?: string): string {\n const day = new Date(Date.parse(`${value.slice(0, 10)}T00:00:00Z`) + days * DAY_MS)\n .toISOString()\n .slice(0, 10);\n const m = /^\\d{4}-\\d{2}-\\d{2}T(\\d{2}:\\d{2}(?::\\d{2}(?:\\.\\d+)?)?)(Z|[+-]\\d{2}:\\d{2})?$/.exec(\n value,\n );\n if (!m) return `${day}${value.slice(10)}`;\n const time = m[1] as string;\n if (!timeZone) return `${day}T${time}${m[2] ?? \"\"}`;\n const wall = Date.parse(`${day}T${time.length === 5 ? `${time}:00` : time}Z`);\n // The instant whose local time in the zone is `wall` (two passes settle DST edges).\n let off = zoneOffsetMinutes(timeZone, wall);\n if (off === null) return `${day}T${time}${m[2] ?? \"\"}`;\n off = zoneOffsetMinutes(timeZone, wall - off * 60_000) ?? off;\n return `${day}T${time}${fmtOffset(off)}`;\n}\n\n/** The same event moved to another date (local time of day and length kept). */\nexport function eventOn(item: Extract<CollectionItem, { kind: \"events\" }>, date: string) {\n const fm = item.frontmatter;\n const days = Math.round(\n (Date.parse(`${date}T00:00:00Z`) - Date.parse(`${fm.start.slice(0, 10)}T00:00:00Z`)) / DAY_MS,\n );\n const move = (v: string) => shiftDateTime(v, days, fm.timezone);\n return {\n ...item,\n frontmatter: { ...fm, start: move(fm.start), ...(fm.end ? { end: move(fm.end) } : {}) },\n } as typeof item;\n}\n\n/** Whole days an event spans (0 for a single-day event). */\nexport function eventLengthDays(item: CollectionItem): number {\n if (item.kind !== \"events\" || !item.frontmatter.end) return 0;\n const fm = item.frontmatter;\n return Math.max(\n 0,\n Math.round(\n (Date.parse(`${(fm.end as string).slice(0, 10)}T00:00:00Z`) -\n Date.parse(`${fm.start.slice(0, 10)}T00:00:00Z`)) /\n DAY_MS,\n ),\n );\n}\n\n/**\n * Repeating events as one item per occurrence between `from` and `through` (YYYY-MM-DD),\n * at most `perEvent` each: the earliest ones, or with `newest` the most recent ones (for past\n * lists). Other items pass through unchanged.\n */\nexport function expandOccurrences(\n items: CollectionItem[],\n window: { from: string; through: string; perEvent?: number; newest?: boolean },\n): CollectionItem[] {\n const out: CollectionItem[] = [];\n for (const item of items) {\n if (item.kind !== \"events\" || !item.frontmatter.recurrence) {\n out.push(item);\n continue;\n }\n const fm = item.frontmatter;\n const lengthDays = eventLengthDays(item);\n // Keep occurrences that haven't ended before the window starts.\n const fromStart = iso(new Date(Date.parse(`${window.from}T00:00:00Z`) - lengthDays * DAY_MS));\n const per = window.perEvent ?? 12;\n // A window is at most about a year, so every date in it is cheap to list; past lists keep the\n // latest ones (counted back from the end of the window).\n const all = occurrenceDates(fm.recurrence as string, fm.start, {\n from: fromStart,\n through: window.through,\n max: window.newest ? 2000 : per,\n });\n const dates = window.newest ? all.slice(-per) : all;\n for (const date of dates) out.push(eventOn(item, date));\n }\n return out;\n}\n\n/** React key for a listed item (repeating events share a slug). */\nexport function itemKey(item: CollectionItem): string {\n return item.kind === \"events\" && item.frontmatter.recurrence\n ? `${item.slug}@${item.frontmatter.start}`\n : item.slug;\n}\n","import type {\n ColorTheme,\n Header as HeaderConfig,\n HeaderVariant,\n NavItem,\n NavLeaf,\n Page,\n Site,\n SiteDocument,\n} from \"@omniharmonic/openspace-schema\";\nimport { themeClass } from \"@omniharmonic/openspace-theme\";\nimport type { ReactNode } from \"react\";\nimport { useRenderContext } from \"./context\";\nimport { cx } from \"./cx\";\nimport { Img } from \"./image\";\nimport { normalizeBasePath, pagePath } from \"./link\";\nimport { Button, SocialLinks } from \"./primitives\";\n\n/** Header variants whose navigation is always behind the menu button. */\nexport const DRAWER_VARIANTS: readonly HeaderVariant[] = [\"minimal-burger\", \"sidebar-drawer\"];\n\nexport interface EffectiveHeader extends HeaderConfig {\n hidden: boolean;\n /** The header overlays the first section (variant `transparent-overlay` or transparent-on-hero). */\n overlay: boolean;\n}\n\n/** Merge the site header with a page's override. */\nexport function effectiveHeader(site: Site, page: Page | undefined): EffectiveHeader {\n const o = page?.header;\n const variant = o?.variant ?? site.header.variant;\n const transparentOnHero = o?.transparentOnHero ?? site.header.transparentOnHero;\n const hasHero = (page?.sections.filter((s) => !s.hidden).length ?? 0) > 0;\n return {\n ...site.header,\n variant,\n transparentOnHero,\n hidden: o?.hidden ?? false,\n overlay: hasHero && (variant === \"transparent-overlay\" || transparentOnHero),\n };\n}\n\ninterface ResolvedNavLeaf {\n kind: \"leaf\";\n label: string;\n href: string;\n current: boolean;\n newTab: boolean;\n}\ninterface ResolvedNavFolder {\n kind: \"folder\";\n label: string;\n current: boolean;\n items: ResolvedNavLeaf[];\n}\ntype ResolvedNav = ResolvedNavLeaf | ResolvedNavFolder;\n\nfunction resolveLeaf(\n item: NavLeaf,\n doc: SiteDocument | undefined,\n basePath: string,\n currentId: string | undefined,\n): ResolvedNavLeaf | null {\n if (item.hidden) return null;\n switch (item.type) {\n case \"page\": {\n const page = doc?.pages[item.page];\n if (doc && !page) return null;\n return {\n kind: \"leaf\",\n label: item.label ?? page?.title ?? \"Page\",\n href: page ? pagePath(page, basePath) : `${normalizeBasePath(basePath)}/`,\n current: item.page === currentId,\n newTab: false,\n };\n }\n case \"collection\":\n return {\n kind: \"leaf\",\n label: item.label,\n href: `${normalizeBasePath(basePath)}/${item.collection}/`,\n current: false,\n newTab: false,\n };\n case \"link\":\n return {\n kind: \"leaf\",\n label: item.label,\n href: item.href,\n current: false,\n newTab: item.newTab ?? false,\n };\n }\n}\n\n/** Resolve the nav tree (hidden entries and dangling pages dropped; buttons excluded). */\nexport function resolveNav(\n nav: readonly NavItem[],\n doc: SiteDocument | undefined,\n basePath: string,\n currentId: string | undefined,\n): ResolvedNav[] {\n const out: ResolvedNav[] = [];\n for (const item of nav) {\n if (item.hidden || item.type === \"button\") continue;\n if (item.type === \"folder\") {\n const items: ResolvedNavLeaf[] = [];\n if (item.page) {\n const landing = resolveLeaf({ type: \"page\", page: item.page }, doc, basePath, currentId);\n if (landing) items.push(landing);\n }\n for (const leaf of item.items) {\n const r = resolveLeaf(leaf, doc, basePath, currentId);\n if (r) items.push(r);\n }\n if (items.length)\n out.push({\n kind: \"folder\",\n label: item.label,\n current: items.some((i) => i.current),\n items,\n });\n continue;\n }\n const r = resolveLeaf(item, doc, basePath, currentId);\n if (r) out.push(r);\n }\n return out;\n}\n\nfunction NavLeafLink({ item, className }: { item: ResolvedNavLeaf; className: string }) {\n return (\n <a\n className={className}\n href={item.href}\n aria-current={item.current ? \"page\" : undefined}\n target={item.newTab ? \"_blank\" : undefined}\n rel={item.newTab ? \"noopener\" : undefined}\n >\n {item.label}\n </a>\n );\n}\n\nfunction NavList({ items, className }: { items: ResolvedNav[]; className?: string }) {\n return (\n <ul className={cx(\"os-nav__list\", className)}>\n {items.map((item, i) =>\n item.kind === \"leaf\" ? (\n // biome-ignore lint/suspicious/noArrayIndexKey: nav order is positional\n <li key={i} className=\"os-nav__item\">\n <NavLeafLink item={item} className=\"os-nav__link\" />\n </li>\n ) : (\n // biome-ignore lint/suspicious/noArrayIndexKey: nav order is positional\n <li key={i} className=\"os-nav__item os-nav__item--folder\">\n <details className=\"os-nav__folder\" data-os-folder=\"\">\n <summary className={cx(\"os-nav__link\", item.current && \"is-current\")}>\n {item.label}\n <svg\n className=\"os-nav__chevron\"\n viewBox=\"0 0 12 12\"\n width=\"12\"\n height=\"12\"\n aria-hidden=\"true\"\n focusable=\"false\"\n >\n <path d=\"M3 4.5l3 3 3-3\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"1.5\" />\n </svg>\n </summary>\n <ul className=\"os-nav__sub\">\n {item.items.map((leaf, j) => (\n // biome-ignore lint/suspicious/noArrayIndexKey: nav order is positional\n <li key={j}>\n <NavLeafLink item={leaf} className=\"os-nav__sublink\" />\n </li>\n ))}\n </ul>\n </details>\n </li>\n ),\n )}\n </ul>\n );\n}\n\nfunction Brand({ site, className }: { site: Site; className?: string }) {\n const { basePath } = useRenderContext();\n const logo = site.logo;\n return (\n <a className={cx(\"os-header__brand\", className)} href={`${normalizeBasePath(basePath)}/`}>\n {logo ? (\n <Img\n src={logo.src}\n alt={logo.alt || site.title}\n {...(logo.width ? { width: logo.width } : {})}\n {...(logo.height ? { height: logo.height } : {})}\n sizes=\"240px\"\n treatment=\"none\"\n priority\n className=\"os-header__logo\"\n />\n ) : (\n <span className=\"os-header__title\">{site.title}</span>\n )}\n </a>\n );\n}\n\nfunction MenuIcon() {\n return (\n <svg\n className=\"os-header__burger\"\n viewBox=\"0 0 24 24\"\n width=\"24\"\n height=\"24\"\n aria-hidden=\"true\"\n focusable=\"false\"\n >\n <path\n d=\"M4 7h16M4 12h16M4 17h16\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"1.6\"\n strokeLinecap=\"round\"\n />\n </svg>\n );\n}\n\nfunction CartButton() {\n return (\n <button\n type=\"button\"\n className=\"os-header__cart\"\n data-os-behavior=\"cart\"\n data-os-cart-toggle=\"\"\n aria-label=\"Cart\"\n >\n <svg viewBox=\"0 0 24 24\" width=\"22\" height=\"22\" aria-hidden=\"true\" focusable=\"false\">\n <path\n d=\"M5 7h14l-1.5 12h-11zM9 7a3 3 0 0 1 6 0\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"1.6\"\n strokeLinejoin=\"round\"\n />\n </svg>\n <span className=\"os-header__cart-count\" data-os-cart-count=\"\" />\n </button>\n );\n}\n\nexport interface HeaderProps {\n site: Site;\n page?: Page | undefined;\n /** Color theme of the first section; used when the header overlays it. */\n heroTheme?: ColorTheme | undefined;\n /** Show the cart button (sites with commerce). */\n cart?: boolean;\n}\n\n/**\n * Site header in one of eight layouts, with sticky / transparent-on-hero modes, nav folders\n * (`<details>`, so they work without JavaScript) and a mobile menu (slide, fullscreen or\n * dropdown) driven by the `menu` behavior. Without JavaScript the mobile menu is shown inline.\n */\nexport function Header({ site, page, heroTheme, cart }: HeaderProps) {\n const ctx = useRenderContext();\n const h = effectiveHeader(site, page);\n if (h.hidden) return null;\n const nav = resolveNav(site.nav, ctx.doc, ctx.basePath, page?.id ?? ctx.page?.id);\n const buttons = site.nav.filter(\n (i): i is Extract<NavItem, { type: \"button\" }> => i.type === \"button\" && !i.hidden,\n );\n const social = h.showSocial ? (site.social ?? []) : [];\n const theme: ColorTheme = h.overlay && heroTheme ? heroTheme : (h.colorTheme ?? \"light\");\n const drawer = DRAWER_VARIANTS.includes(h.variant);\n const split = h.variant === \"split-nav\";\n const half = Math.ceil(nav.length / 2);\n const menuId = \"os-menu\";\n\n const actions = (\n <div className=\"os-header__actions\">\n {social.length > 0 && <SocialLinks profiles={social} className=\"os-header__social\" />}\n {buttons.map((b, i) => (\n // biome-ignore lint/suspicious/noArrayIndexKey: nav order is positional\n <Button key={i} to={b.link} role={b.style} className=\"os-header__button\">\n {b.label}\n </Button>\n ))}\n </div>\n );\n\n let desktopNav: ReactNode = null;\n if (!drawer && nav.length) {\n desktopNav = split ? (\n <nav className=\"os-nav os-nav--split\" aria-label=\"Main\">\n <NavList items={nav.slice(0, half)} className=\"os-nav__list--start\" />\n <Brand site={site} className=\"os-header__brand--split\" />\n <NavList items={nav.slice(half)} className=\"os-nav__list--end\" />\n </nav>\n ) : (\n <nav className=\"os-nav\" aria-label=\"Main\">\n <NavList items={nav} />\n </nav>\n );\n }\n\n return (\n <header\n className={cx(\n \"os-header\",\n `os-header--${h.variant}`,\n themeClass(theme),\n h.sticky && \"is-sticky\",\n h.overlay && \"is-overlay\",\n drawer && \"is-drawer\",\n `has-menu-${h.variant === \"sidebar-drawer\" ? \"drawer\" : h.mobileMenu}`,\n )}\n data-os-header=\"\"\n data-os-behavior=\"menu\"\n >\n <div className=\"os-header__bar\">\n <Brand site={site} className={split ? \"os-header__brand--main\" : undefined} />\n {desktopNav}\n {actions}\n {cart && <CartButton />}\n <button\n type=\"button\"\n className=\"os-header__toggle\"\n aria-expanded=\"false\"\n aria-controls={menuId}\n data-os-menu-toggle=\"\"\n >\n <MenuIcon />\n <span className=\"os-visually-hidden\">Menu</span>\n </button>\n </div>\n <div\n id={menuId}\n className={cx(\n \"os-menu\",\n `os-menu--${h.variant === \"sidebar-drawer\" ? \"drawer\" : h.mobileMenu}`,\n themeClass(h.colorTheme ?? \"light\"),\n )}\n data-os-menu=\"\"\n >\n <div className=\"os-menu__head\">\n <span className=\"os-menu__title\">{site.title}</span>\n <button type=\"button\" className=\"os-menu__close\" data-os-menu-close=\"\">\n <svg viewBox=\"0 0 24 24\" width=\"24\" height=\"24\" aria-hidden=\"true\" focusable=\"false\">\n <path\n d=\"M6 6l12 12M18 6L6 18\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"1.6\"\n strokeLinecap=\"round\"\n />\n </svg>\n <span className=\"os-visually-hidden\">Close menu</span>\n </button>\n </div>\n <nav className=\"os-menu__nav\" aria-label=\"Menu\">\n <NavList items={nav} className=\"os-menu__list\" />\n </nav>\n {(buttons.length > 0 || (site.social?.length ?? 0) > 0) && (\n <div className=\"os-menu__foot\">\n {buttons.map((b, i) => (\n // biome-ignore lint/suspicious/noArrayIndexKey: nav order is positional\n <Button key={i} to={b.link} role={b.style}>\n {b.label}\n </Button>\n ))}\n {site.social && <SocialLinks profiles={site.social} />}\n </div>\n )}\n </div>\n </header>\n );\n}\n","import type { Page, SiteDocument } from \"@omniharmonic/openspace-schema\";\nimport {\n chosenCustomFont,\n customFontFaces,\n customFontPreloads,\n googleFontsUrl,\n} from \"@omniharmonic/openspace-theme\";\nimport { createElement } from \"react\";\nimport { renderToStaticMarkup } from \"react-dom/server\";\nimport { BEHAVIOR_LOADER, type BehaviorName, behaviorsInHtml } from \"./behaviors-manifest\";\nimport {\n absolute,\n compiledStylesFor,\n escapeHtml,\n jsonForScript,\n ogImageUrl,\n pageDescription,\n pageTitle,\n safeCss,\n siteUrlFor,\n} from \"./html-meta\";\nimport type { ImageMap } from \"./image-map\";\nimport { mediaUrl, normalizeBasePath, pagePath } from \"./link\";\nimport { PageView, resolvePage } from \"./page\";\nimport { BASE_CSS } from \"./styles/base-css\";\n\nexport interface RenderPageHtmlOptions {\n doc: SiteDocument;\n /** Page id, or a page object (collection item pages, unsaved drafts). */\n pageId: string | Page;\n mode?: \"production\" | \"preview\";\n /** Site base path (`/maya-yoga` on a GitHub project site); `\"\"` at a domain root. */\n basePath?: string;\n imageMap?: ImageMap;\n /** Hub origin for forms/newsletter/analytics/cart (default: `config.hub`). */\n hubUrl?: string;\n /** Where behavior modules are served (default `<basePath>/_os/behaviors`). */\n behaviorsUrl?: string;\n /**\n * Absolute site URL including the base path, for canonical and Open Graph URLs (default:\n * `https://<customDomain>` or `config.deploy.url`).\n */\n siteUrl?: string;\n /** Structured data emitted as `<script type=\"application/ld+json\">`. */\n jsonLd?: object | object[];\n /**\n * Font stylesheet URLs. Default: the pairing's Google Fonts URL (previews). Published sites\n * pass self-hosted Fontsource CSS; `[]` disables web fonts.\n */\n fontStylesheets?: string[];\n /** Link the stylesheets instead of inlining them (site-kit serves them as cacheable files). */\n stylesheets?: { base?: string; tokens?: string };\n /** Extra trusted markup appended to `<head>` (site-kit feed links etc.). */\n extraHead?: string;\n}\n\n/**\n * Until the owner uploads a browser-tab icon: the site's initial on its brand color, as an\n * inline SVG (no request, and no 404 for `/favicon.ico` in the console).\n */\nexport function monogramIcon(\n title: string,\n brand: { background?: string; heading?: string } | undefined,\n): string {\n const letter = escapeHtml((title.trim().match(/\\p{L}|\\p{N}/u)?.[0] ?? \"•\").toUpperCase());\n const bg = brand?.background ?? \"#222222\";\n const fg = brand?.heading ?? \"#ffffff\";\n const svg = `<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 64 64\"><rect width=\"64\" height=\"64\" rx=\"14\" fill=\"${bg}\"/><text x=\"32\" y=\"43\" font-family=\"system-ui,sans-serif\" font-size=\"34\" font-weight=\"600\" text-anchor=\"middle\" fill=\"${fg}\">${letter}</text></svg>`;\n return `data:image/svg+xml,${encodeURIComponent(svg)}`;\n}\n\nconst attr = (tag: string, name: string) => new RegExp(`\\\\s${name}=\"([^\"]*)\"`).exec(tag)?.[1];\n\n/** Share of a phone screen an image's `sizes` gives it (its last, unconditional length). */\nfunction phoneShare(sizes: string | undefined): number {\n const last = (sizes ?? \"100vw\").split(\",\").pop()?.trim() ?? \"100vw\";\n const vw = /^(\\d+(?:\\.\\d+)?)vw$/.exec(last);\n if (vw) return Number(vw[1]) / 100;\n const times = /\\*\\s*(\\d+(?:\\.\\d+)?)\\s*\\)$/.exec(last);\n if (times) return Number(times[1]);\n return /^calc\\(100vw/.test(last) ? 1 : 0.5;\n}\n\n/**\n * `<link rel=\"preload\" as=\"image\">` for the page's likely LCP image. Of the images the renderer\n * marked `fetchpriority=\"high\"` (the first section's lead images), it picks the one that covers\n * most of a phone screen (from its `sizes` and aspect ratio), since mobile LCP is what's\n * measured. With `imagesrcset`/`imagesizes` the browser fetches exactly the candidate the `<img>`\n * will use, before stylesheets and fonts compete for the connection. When its `<picture>` offers\n * modern formats, the preload names the first `<source>` (with its `type`, so browsers without\n * that format skip it). Attribute values are taken from the already-escaped markup.\n */\nexport function lcpImagePreload(body: string): string {\n const imgs = [...body.matchAll(/<img\\b[^>]*\\bfetchpriority=\"high\"[^>]*>/gi)].slice(0, 4);\n let best: { m: RegExpMatchArray; score: number } | null = null;\n for (const m of imgs) {\n const share = phoneShare(attr(m[0], \"sizes\"));\n const w = Number(attr(m[0], \"width\")) || 1;\n const h = Number(attr(m[0], \"height\")) || w;\n const score = share * share * (h / w);\n if (!best || score > best.score) best = { m, score };\n }\n if (!best || best.m.index === undefined) return \"\";\n const img = best.m;\n const at = best.m.index;\n const pictureStart = body.lastIndexOf(\"<picture\", at);\n const between = pictureStart >= 0 ? body.slice(pictureStart, at) : \"\";\n const source =\n pictureStart >= 0 && !between.includes(\"</picture>\")\n ? /<source\\b[^>]*>/i.exec(between)?.[0]\n : undefined;\n const tag = source ?? img[0];\n const srcset = attr(tag, \"srcset\") ?? attr(tag, \"srcSet\");\n const sizes = attr(tag, \"sizes\");\n const src = attr(img[0], \"src\");\n const type = source ? attr(source, \"type\") : undefined;\n if (!srcset && !src) return \"\";\n return `<link rel=\"preload\" as=\"image\"${srcset ? ` imagesrcset=\"${srcset}\"` : ` href=\"${src}\"`}${srcset && sizes ? ` imagesizes=\"${sizes}\"` : \"\"}${type ? ` type=\"${type}\"` : \"\"} fetchpriority=\"high\">`;\n}\n\n/**\n * Render a complete HTML document for a page: head (title, meta, Open Graph, canonical, JSON-LD,\n * fonts, token CSS, base CSS, custom CSS, head injection), the rendered body, and behavior\n * scripts only for behaviors the page actually uses. No React runtime ships.\n */\nexport function renderPageHtml(opts: RenderPageHtmlOptions): string {\n const { doc } = opts;\n const mode = opts.mode ?? \"production\";\n const page = resolvePage(doc, opts.pageId);\n const basePath = normalizeBasePath(opts.basePath);\n const hubUrl = (opts.hubUrl ?? doc.config.hub).replace(/\\/+$/, \"\");\n const behaviorsUrl = (opts.behaviorsUrl ?? `${basePath}/_os/behaviors`).replace(/\\/+$/, \"\");\n const siteUrl = siteUrlFor(doc, opts.siteUrl);\n const site = doc.site;\n const styles = compiledStylesFor(doc.styles);\n\n const body = renderToStaticMarkup(\n createElement(PageView, {\n doc,\n page,\n mode,\n basePath,\n imageMap: opts.imageMap ?? {},\n hubUrl,\n }),\n );\n\n const analytics =\n mode === \"production\" &&\n doc.config.features.analytics &&\n site.integrations?.analytics !== false;\n const behaviors = behaviorsInHtml(body);\n if (analytics) behaviors.push(\"beacon\");\n\n const title = pageTitle(doc, page);\n const description = pageDescription(doc, page);\n const canonical = page.seo?.canonical ?? absolute(siteUrl, pagePath(page));\n const noindex = mode === \"preview\" || page.seo?.noindex || site.seo?.noindex;\n const ogImageSrc = page.seo?.image ?? site.seo?.image;\n const ogImage = ogImageSrc ? ogImageUrl(ogImageSrc, siteUrl, opts.imageMap) : undefined;\n // Uploaded fonts (PRD §5.1) publish with the site; when they replace both the heading and the\n // body family, the pairing's web fonts aren't loaded at all.\n const customHeading = chosenCustomFont(doc.styles, doc.styles.choices.headingFont);\n const customBody = chosenCustomFont(doc.styles, doc.styles.choices.bodyFont);\n const fonts =\n customHeading && customBody\n ? []\n : (opts.fontStylesheets ?? [googleFontsUrl(styles.tokens.pairing)]);\n const fontFaces = customFontFaces(doc.styles, (src) => mediaUrl(src, basePath));\n const fontPreloads = customFontPreloads(doc.styles, {\n heading: styles.tokens.pairing.headingWeight,\n body: styles.tokens.pairing.bodyWeight,\n });\n const usesGoogle = fonts.some((f) => f.startsWith(\"https://fonts.googleapis.com/\"));\n\n const meta = (name: string, content: string | undefined, attr = \"name\") =>\n content ? `<meta ${attr}=\"${name}\" content=\"${escapeHtml(content)}\">` : \"\";\n const head: string[] = [\n '<meta charset=\"utf-8\">',\n '<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">',\n `<title>${escapeHtml(title)}</title>`,\n // The LCP image first: discovered before the stylesheets and fonts below.\n lcpImagePreload(body),\n meta(\"description\", description),\n noindex ? '<meta name=\"robots\" content=\"noindex\">' : \"\",\n `<link rel=\"canonical\" href=\"${escapeHtml(canonical)}\">`,\n meta(\"og:type\", \"website\", \"property\"),\n meta(\"og:site_name\", site.title, \"property\"),\n meta(\"og:title\", page.seo?.title ?? page.title, \"property\"),\n meta(\"og:description\", description, \"property\"),\n meta(\"og:url\", canonical, \"property\"),\n meta(\"og:image\", ogImage, \"property\"),\n meta(\"og:locale\", site.locale.replace(\"-\", \"_\"), \"property\"),\n meta(\"twitter:card\", ogImage ? \"summary_large_image\" : \"summary\"),\n `<link rel=\"icon\" href=\"${escapeHtml(site.favicon ? mediaUrl(site.favicon, basePath) : monogramIcon(site.title, styles.tokens.themes.brand))}\">`,\n '<meta name=\"generator\" content=\"OpenSpace\">',\n \"<script>document.documentElement.classList.add('os-js')</script>\",\n usesGoogle\n ? '<link rel=\"preconnect\" href=\"https://fonts.googleapis.com\"><link rel=\"preconnect\" href=\"https://fonts.gstatic.com\" crossorigin>'\n : \"\",\n ...fontPreloads.map(\n (src) =>\n `<link rel=\"preload\" as=\"font\" type=\"font/woff2\" href=\"${escapeHtml(mediaUrl(src, basePath))}\" crossorigin>`,\n ),\n ...fonts.map((href) => `<link rel=\"stylesheet\" href=\"${escapeHtml(href)}\">`),\n fontFaces ? `<style data-os=\"fonts\">${safeCss(fontFaces)}</style>` : \"\",\n opts.stylesheets?.tokens\n ? `<link rel=\"stylesheet\" href=\"${escapeHtml(opts.stylesheets.tokens)}\">`\n : `<style data-os=\"tokens\">${styles.css}</style>`,\n opts.stylesheets?.base\n ? `<link rel=\"stylesheet\" href=\"${escapeHtml(opts.stylesheets.base)}\">`\n : `<style data-os=\"base\">${BASE_CSS}</style>`,\n site.customCss ? `<style data-os=\"custom\">${safeCss(site.customCss)}</style>` : \"\",\n ...[opts.jsonLd ?? []]\n .flat()\n .map((ld) => `<script type=\"application/ld+json\">${jsonForScript(ld)}</script>`),\n ...behaviors.map(\n (b) => `<link rel=\"modulepreload\" href=\"${escapeHtml(`${behaviorsUrl}/${b}.js`)}\">`,\n ),\n opts.extraHead ?? \"\",\n site.headInjection ?? \"\",\n page.headInjection ?? \"\",\n ];\n\n const bodyAttrs = [\n `class=\"os-body\"`,\n `data-os-site=\"${escapeHtml(doc.config.siteId)}\"`,\n `data-os-hub=\"${escapeHtml(hubUrl)}\"`,\n `data-os-base=\"${escapeHtml(basePath)}\"`,\n `data-os-mode=\"${mode}\"`,\n analytics ? `data-os-behavior=\"beacon\"` : \"\",\n ]\n .filter(Boolean)\n .join(\" \");\n\n const scripts = behaviors.length\n ? `<script type=\"module\" src=\"${escapeHtml(`${behaviorsUrl}/${BEHAVIOR_LOADER}.js`)}\"></script>`\n : \"\";\n\n return `<!doctype html>\n<html lang=\"${escapeHtml(site.locale)}\">\n<head>\n${head.filter(Boolean).join(\"\\n\")}\n</head>\n<body ${bodyAttrs}>\n${body}\n${scripts}${site.footerInjection ?? \"\"}${page.footerInjection ?? \"\"}\n</body>\n</html>\n`;\n}\n\n/**\n * Behaviors a page needs: pass rendered HTML, or render options (the page is rendered first).\n * Includes `beacon` for production renders with analytics on.\n */\nexport function behaviorsForPage(input: string | RenderPageHtmlOptions): BehaviorName[] {\n if (typeof input === \"string\") return behaviorsInHtml(input);\n return behaviorsInHtml(renderPageHtml(input));\n}\n\nexport {\n compiledStylesFor,\n escapeHtml,\n jsonForScript,\n ogImageUrl,\n pageDescription,\n pageTitle,\n siteUrlFor,\n} from \"./html-meta\";\n","/**\n * Page metadata helpers shared by `renderPageHtml` and the Studio (titles, descriptions, URLs,\n * compiled styles). Kept apart from `html.ts` so importing them never pulls `react-dom/server`\n * into a browser bundle.\n */\nimport type { Page, SiteDocument, Styles } from \"@omniharmonic/openspace-schema\";\nimport { type CompiledStyles, compileStyles } from \"@omniharmonic/openspace-theme\";\nimport type { ImageMap } from \"./image-map\";\nimport { mediaUrl } from \"./link\";\n\nconst ESC: Record<string, string> = {\n \"&\": \"&\",\n \"<\": \"<\",\n \">\": \">\",\n '\"': \""\",\n \"'\": \"'\",\n};\nexport const escapeHtml = (s: string) => s.replace(/[&<>\"']/g, (ch) => ESC[ch] as string);\n\n/** JSON for a `<script>` element: `<`, U+2028/9 escaped so content can never close the tag. */\nexport function jsonForScript(value: unknown): string {\n return JSON.stringify(value)\n .replace(/</g, \"\\\\u003c\")\n .replace(LINE_SEP, \"\\\\u2028\")\n .replace(PARA_SEP, \"\\\\u2029\");\n}\nconst LINE_SEP = new RegExp(String.fromCharCode(0x2028), \"g\");\nconst PARA_SEP = new RegExp(String.fromCharCode(0x2029), \"g\");\n\n/** `<style>` content can't contain `</style`; neutralise it in owner-provided CSS. */\nexport const safeCss = (css: string) => css.replace(/<\\/style/gi, \"<\\\\/style\");\n\nconst compiled = new WeakMap<Styles, CompiledStyles>();\n/** `compileStyles` memoised per styles object (site-kit renders many pages per build). */\nexport function compiledStylesFor(styles: Styles): CompiledStyles {\n let hit = compiled.get(styles);\n if (!hit) {\n hit = compileStyles(styles);\n compiled.set(styles, hit);\n }\n return hit;\n}\n\n/** The site's absolute URL (with base path), ending in `/`. */\nexport function siteUrlFor(doc: SiteDocument, override?: string): string {\n const raw =\n override ??\n (doc.config.deploy.customDomain\n ? `https://${doc.config.deploy.customDomain}`\n : doc.config.deploy.url);\n return raw.endsWith(\"/\") ? raw : `${raw}/`;\n}\n\n/** Absolute URL for a site-relative path (`/about/`) — the base path is already in `siteUrl`. */\nexport function absolute(siteUrl: string, path: string): string {\n if (/^https?:\\/\\//.test(path)) return path;\n return new URL(path.replace(/^\\/+/, \"\"), siteUrl).toString();\n}\n\n/**\n * Absolute URL for a share image. Image-map srcs are already final URLs (root-relative ones\n * include the base path), so they resolve against the origin; `media/` paths resolve against\n * the site URL, which carries the base path.\n */\nexport function ogImageUrl(src: string, siteUrl: string, imageMap?: ImageMap): string {\n const mapped = imageMap?.[src]?.src;\n if (mapped) return new URL(mapped, siteUrl).toString();\n return absolute(siteUrl, mediaUrl(src));\n}\n\n/** `<title>`: SEO title, else page title, through the site's `%s` template (home: site title). */\nexport function pageTitle(doc: SiteDocument, page: Page): string {\n const own = page.seo?.title;\n if (own) return own;\n const template = doc.site.seo?.titleTemplate;\n if (page.slug === \"\") {\n return doc.site.tagline ? `${doc.site.title} — ${doc.site.tagline}` : doc.site.title;\n }\n return template ? template.replace(\"%s\", page.title) : `${page.title} — ${doc.site.title}`;\n}\n\nexport function pageDescription(doc: SiteDocument, page: Page): string | undefined {\n return page.seo?.description ?? doc.site.seo?.description ?? doc.site.tagline ?? undefined;\n}\n","import type { Page, SiteDocument } from \"@omniharmonic/openspace-schema\";\nimport type { ReactNode } from \"react\";\nimport { AnnouncementBar, Footer, SitePopup } from \"./chrome\";\nimport {\n EditorContext,\n type EditorHooks,\n ImageResolverContext,\n RenderContext,\n type RenderMode,\n} from \"./context\";\nimport { cx } from \"./cx\";\nimport { effectiveHeader, Header } from \"./header\";\nimport type { ImageMap } from \"./image-map\";\nimport { responsiveVars } from \"./layout-vars\";\nimport { normalizeBasePath } from \"./link\";\nimport { FirstSectionContext, SectionView } from \"./section\";\n\nexport interface PageViewProps {\n doc: SiteDocument;\n /** A page id in `doc.pages`, or a page object (e.g. an unsaved draft or a collection item page). */\n page: string | Page;\n mode?: RenderMode;\n basePath?: string;\n imageMap?: ImageMap;\n hubUrl?: string;\n /** Studio hooks (canvas selection affordances). */\n editor?: EditorHooks;\n /** Rendered after the footer (popups, cart drawer mount points). */\n extras?: ReactNode;\n}\n\n/** Resolve the page prop to a page object; throws for unknown ids. */\nexport function resolvePage(doc: SiteDocument, page: string | Page): Page {\n if (typeof page !== \"string\") return page;\n const found = doc.pages[page as keyof SiteDocument[\"pages\"]];\n if (!found) throw new Error(`Page ${page} does not exist`);\n return found;\n}\n\n/**\n * A whole page: skip link, announcement bar, header, the page's sections in `<main>`, footer.\n * The same component renders the Studio canvas (`mode: \"editor\"`), the Hub preview and the\n * published site.\n */\nexport function PageView(props: PageViewProps) {\n const { doc, mode = \"production\", imageMap = {}, extras } = props;\n const page = resolvePage(doc, props.page);\n const basePath = normalizeBasePath(props.basePath);\n const hubUrl = props.hubUrl ?? doc.config.hub;\n const visible = page.sections.filter((s) => !s.hidden || mode === \"editor\");\n const header = effectiveHeader(doc.site, page);\n const heroTheme = visible[0]?.style.colorTheme ?? \"light\";\n const cart = doc.site.integrations?.stripeConnected ?? false;\n const logoVars = header.logoHeight\n ? responsiveVars(\"logo-h\", header.logoHeight, (px) => `${px}px`)\n : undefined;\n\n const content = (\n <RenderContext.Provider value={{ doc, page, mode, basePath, hubUrl }}>\n <ImageResolverContext.Provider value={imageMap}>\n <div\n className={cx(\"os-page\", header.overlay && !header.hidden && \"has-overlay-header\")}\n data-os-page={page.id}\n style={logoVars}\n >\n <a className=\"os-skip-link\" href=\"#main\">\n Skip to content\n </a>\n <AnnouncementBar announcement={doc.site.announcement} />\n <Header site={doc.site} page={page} heroTheme={heroTheme} cart={cart} />\n <main id=\"main\" className=\"os-main\" tabIndex={-1}>\n {visible.map((section, i) => (\n <FirstSectionContext.Provider key={section.id} value={i === 0}>\n <SectionView section={section} />\n </FirstSectionContext.Provider>\n ))}\n </main>\n <Footer site={doc.site} />\n {mode !== \"editor\" ? <SitePopup popup={doc.site.popup} /> : null}\n {extras}\n </div>\n </ImageResolverContext.Provider>\n </RenderContext.Provider>\n );\n return props.editor ? (\n <EditorContext.Provider value={props.editor}>{content}</EditorContext.Provider>\n ) : (\n content\n );\n}\n","import type {\n BlockNode,\n InlineNode,\n Mark,\n RichTextDoc,\n TypePreset,\n} from \"@omniharmonic/openspace-schema\";\nimport { colorVar } from \"@omniharmonic/openspace-theme\";\nimport { Fragment, type ReactNode, useContext } from \"react\";\nimport { BlockFieldsContext, fieldPathOf, useEditor, useRenderContext } from \"./context\";\nimport { cx } from \"./cx\";\nimport { withBase } from \"./link\";\n\n/** Class for a typography preset: `os-type-h2`. */\nexport const typeClass = (preset: TypePreset | \"button\" | \"nav\") => `os-type-${preset}`;\n\n/** Marks are applied innermost-first in this order; links always wrap everything. */\nconst MARK_ORDER: Mark[\"type\"][] = [\n \"code\",\n \"strike\",\n \"underline\",\n \"italic\",\n \"bold\",\n \"highlight\",\n \"link\",\n];\n\nfunction wrapMark(mark: Mark, child: ReactNode, key: number, basePath: string): ReactNode {\n switch (mark.type) {\n case \"bold\":\n return <strong key={key}>{child}</strong>;\n case \"italic\":\n return <em key={key}>{child}</em>;\n case \"underline\":\n return <u key={key}>{child}</u>;\n case \"strike\":\n return <s key={key}>{child}</s>;\n case \"code\":\n return <code key={key}>{child}</code>;\n case \"highlight\": {\n const color = mark.attrs?.color;\n return (\n <mark\n key={key}\n className=\"os-highlight\"\n style={color ? { \"--hl\": `var(${colorVar(color)})` } : undefined}\n >\n {child}\n </mark>\n );\n }\n case \"link\": {\n const { href, title, newTab } = mark.attrs;\n return (\n <a\n key={key}\n href={withBase(href, basePath)}\n title={title}\n target={newTab ? \"_blank\" : undefined}\n rel={newTab ? \"noopener\" : undefined}\n >\n {child}\n </a>\n );\n }\n }\n}\n\nfunction renderInline(nodes: InlineNode[] | undefined, basePath: string): ReactNode[] {\n if (!nodes) return [];\n return nodes.map((node, i) => {\n // biome-ignore lint/suspicious/noArrayIndexKey: rich text nodes have no ids; order is stable\n if (node.type === \"hardBreak\") return <br key={i} />;\n const marks = [...(node.marks ?? [])].sort(\n (a, b) => MARK_ORDER.indexOf(a.type) - MARK_ORDER.indexOf(b.type),\n );\n let out: ReactNode = node.text;\n for (const m of marks) out = wrapMark(m, out, i, basePath);\n // biome-ignore lint/suspicious/noArrayIndexKey: rich text nodes have no ids; order is stable\n return marks.length ? out : <Fragment key={i}>{node.text}</Fragment>;\n });\n}\n\nfunction renderBlock(node: BlockNode, key: number, basePath: string): ReactNode {\n switch (node.type) {\n case \"paragraph\": {\n const preset = node.attrs?.preset;\n const children = renderInline(node.content, basePath);\n return (\n <p key={key} className={preset && preset !== \"body\" ? typeClass(preset) : undefined}>\n {children.length ? children : <br />}\n </p>\n );\n }\n case \"heading\": {\n const { level, preset } = node.attrs;\n const Tag = `h${level}` as \"h1\" | \"h2\" | \"h3\" | \"h4\";\n return (\n <Tag key={key} className={typeClass(preset ?? (`h${level}` as TypePreset))}>\n {renderInline(node.content, basePath)}\n </Tag>\n );\n }\n case \"bulletList\":\n return (\n <ul key={key}>\n {node.content.map((li, i) => (\n // biome-ignore lint/suspicious/noArrayIndexKey: rich text nodes have no ids\n <li key={i}>{li.content.map((c, j) => renderBlock(c, j, basePath))}</li>\n ))}\n </ul>\n );\n case \"orderedList\":\n return (\n <ol key={key} start={node.attrs?.start}>\n {node.content.map((li, i) => (\n // biome-ignore lint/suspicious/noArrayIndexKey: rich text nodes have no ids\n <li key={i}>{li.content.map((c, j) => renderBlock(c, j, basePath))}</li>\n ))}\n </ol>\n );\n case \"blockquote\":\n return (\n <blockquote key={key}>{node.content.map((c, j) => renderBlock(c, j, basePath))}</blockquote>\n );\n }\n}\n\nexport interface RichTextProps {\n doc: RichTextDoc | null | undefined;\n className?: string;\n /** Element wrapping the flow (default `div`). */\n as?: \"div\" | \"section\" | \"article\";\n}\n\n/**\n * Render a rich-text document (arch §3.5) to semantic HTML. Headings and paragraphs carry\n * typography preset classes; links are base-path aware; no inline styles except token\n * highlight colors.\n */\nexport function RichText({ doc, className, as: Tag = \"div\" }: RichTextProps) {\n const { basePath } = useRenderContext();\n const editor = useEditor();\n const owner = useContext(BlockFieldsContext);\n const out =\n !doc || doc.content.length === 0 ? null : (\n <Tag className={cx(\"os-rich\", className)}>\n {doc.content.map((node, i) => renderBlock(node, i, basePath))}\n </Tag>\n );\n if (editor?.renderRichText && owner && doc) {\n const fieldPath = fieldPathOf(owner.fields, doc);\n if (fieldPath)\n return (\n <>\n {editor.renderRichText({\n block: owner.block,\n fieldPath,\n doc,\n className,\n as: Tag,\n children: out,\n })}\n </>\n );\n }\n return out;\n}\n","/**\n * @omniharmonic/openspace-renderer — the one renderer (ADR-3). React components that turn OpenSpace content\n * into HTML for the Studio canvas, the Hub preview, site-kit builds and OG/email generation.\n * Published pages ship no React runtime: interactivity comes from vanilla `data-os-behavior`\n * modules (see `./behaviors-manifest` and the `@omniharmonic/openspace-renderer/node` entry for files).\n */\nexport const name = \"@omniharmonic/openspace-renderer\";\n\nexport * from \"./behaviors-manifest\";\nexport {\n alignClasses,\n BlockView,\n type BlockViewProps,\n blockStyleProps,\n blockTypeClass,\n} from \"./block\";\nexport {\n AnnouncementBar,\n Footer,\n Popup,\n type PopupProps,\n type PopupTrigger,\n popupTrigger,\n SitePopup,\n shortHash,\n} from \"./chrome\";\nexport {\n CollectionsContext,\n type CollectionsValue,\n feedKey,\n isLive,\n isUpcoming,\n itemDate,\n nextOccurrence,\n type QueryOptions,\n queryCollection,\n RECURRENCE_HORIZON_DAYS,\n type ResolvedCollections,\n type SocialFeedPost,\n useCollectionQuery,\n useCollections,\n} from \"./collections\";\nexport {\n BlockFieldsContext,\n BlockRegistryContext,\n EditorContext,\n type EditorHooks,\n fieldPathOf,\n ImageResolverContext,\n RenderContext,\n type RenderContextValue,\n type RenderMode,\n type RichTextHookArgs,\n SectionContext,\n useEditor,\n useImageMap,\n useRenderContext,\n} from \"./context\";\nexport { type CssVars, cx } from \"./cx\";\nexport {\n DRAWER_VARIANTS,\n type EffectiveHeader,\n effectiveHeader,\n Header,\n type HeaderProps,\n resolveNav,\n} from \"./header\";\nexport { behaviorsForPage, type RenderPageHtmlOptions, renderPageHtml } from \"./html\";\nexport {\n compiledStylesFor,\n escapeHtml,\n jsonForScript,\n pageDescription,\n pageTitle,\n siteUrlFor,\n} from \"./html-meta\";\nexport {\n type AboveFold,\n AboveFoldContext,\n Img,\n type ImgProps,\n REMOTE_WIDTHS,\n remoteSrcset,\n resolveImage,\n} from \"./image\";\nexport {\n collectImageSrcs,\n type ImageMap,\n type ResolvedImage,\n type ResolvedImageSource,\n} from \"./image-map\";\nexport * from \"./layout-vars\";\nexport {\n itemPath,\n Link,\n type LinkProps,\n type LinkResolveOptions,\n mediaUrl,\n normalizeBasePath,\n pagePath,\n type ResolvedLink,\n resolveLink,\n sectionFragment,\n withBase,\n} from \"./link\";\nexport { PageView, type PageViewProps, resolvePage } from \"./page\";\nexport {\n Button,\n type ButtonProps,\n type ButtonRole,\n networkLabel,\n SocialIcon,\n SocialLinks,\n} from \"./primitives\";\nexport {\n eventOn,\n expandOccurrences,\n itemKey,\n occurrenceDates,\n parseRecurrence,\n type RecurrenceRule,\n} from \"./recurrence\";\nexport {\n getBlock,\n globalRegistry,\n listBlocks,\n type RendererBlockDefinition,\n type RendererBlockRegistry,\n registerBlocks,\n unregisterBlocks,\n} from \"./registry\";\nexport { RichText, type RichTextProps, typeClass } from \"./richtext\";\nexport {\n backgroundVars,\n FirstSectionContext,\n SectionBackgroundLayer,\n SectionView,\n type SectionViewProps,\n} from \"./section\";\nexport { BASE_CSS } from \"./styles/base-css\";\n"],"mappings":"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","names":["resolve","TOKEN_VARS","useContext","name","blocks","spaceVar","TOKEN_VARS","resolve","useContext","themeClass","useContext","imageTreatmentClass","createContext","useContext","jsx","jsx","createContext","useContext","imageTreatmentClass","Fragment","jsx","jsxs","themeClass","createContext","useContext","jsx","jsxs","createContext","useContext","blocks","themeClass","jsx","jsxs","themeClass","useContext","createContext","useContext","time","createContext","useContext","themeClass","jsx","jsxs","r","themeClass","jsx","jsxs","name","attr","colorVar","Fragment","useContext","Fragment","jsx","colorVar","useContext"]}
|
package/dist/node.d.ts
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { B as BehaviorName, d as BEHAVIOR_LOADER } from './base-css-CCRQ8Nzw.js';
|
|
2
|
+
export { a as BASE_CSS } from './base-css-CCRQ8Nzw.js';
|
|
3
|
+
|
|
4
|
+
type BehaviorFile = BehaviorName | typeof BEHAVIOR_LOADER;
|
|
5
|
+
/** Every file served from the behaviors directory (behaviors + loader). */
|
|
6
|
+
declare const BEHAVIOR_FILES: readonly BehaviorFile[];
|
|
7
|
+
/** TypeScript source of a behavior (present in the monorepo / source checkouts). */
|
|
8
|
+
declare function behaviorSourcePath(name: BehaviorFile): string;
|
|
9
|
+
/** Prebuilt, minified module in `dist/behaviors/` (after `pnpm build`), if present. */
|
|
10
|
+
declare function behaviorDistPath(name: BehaviorFile): string | undefined;
|
|
11
|
+
/** Path of the built `os.css` (after `pnpm build`). Prefer {@link BASE_CSS} in code. */
|
|
12
|
+
declare const BASE_CSS_PATH: string;
|
|
13
|
+
interface BundleOptions {
|
|
14
|
+
minify?: boolean;
|
|
15
|
+
names?: readonly BehaviorFile[];
|
|
16
|
+
}
|
|
17
|
+
/** esbuild options shared by the package build and runtime bundling. */
|
|
18
|
+
declare const BEHAVIOR_ESBUILD: {
|
|
19
|
+
bundle: boolean;
|
|
20
|
+
format: "esm";
|
|
21
|
+
target: string[];
|
|
22
|
+
platform: "browser";
|
|
23
|
+
legalComments: "none";
|
|
24
|
+
write: false;
|
|
25
|
+
};
|
|
26
|
+
/** Bundle behaviors from source with esbuild: `{ name: code }`. */
|
|
27
|
+
declare function bundleBehaviors(opts?: BundleOptions): Promise<Record<string, string>>;
|
|
28
|
+
/** Write `os.css` and every behavior module into `outdir` (e.g. `dist/_os`). */
|
|
29
|
+
declare function writeAssets(outdir: string, opts?: {
|
|
30
|
+
cssDir?: string;
|
|
31
|
+
}): Promise<string[]>;
|
|
32
|
+
/** A behavior's `init(el)` (the module's default export). */
|
|
33
|
+
type BehaviorInit = (el: HTMLElement) => void;
|
|
34
|
+
/**
|
|
35
|
+
* Import a behavior module and return its `init`. Loads the TypeScript source when present
|
|
36
|
+
* (monorepo, vitest) and the built `dist/` module otherwise — for tests that run behaviors in a
|
|
37
|
+
* DOM environment such as happy-dom. The same modules are importable by specifier as
|
|
38
|
+
* `@omniharmonic/openspace-renderer/behavior-source/<name>`.
|
|
39
|
+
*/
|
|
40
|
+
declare function importBehavior(name: BehaviorFile): Promise<BehaviorInit>;
|
|
41
|
+
|
|
42
|
+
export { BASE_CSS_PATH, BEHAVIOR_ESBUILD, BEHAVIOR_FILES, type BehaviorFile, type BehaviorInit, type BundleOptions, behaviorDistPath, behaviorSourcePath, bundleBehaviors, importBehavior, writeAssets };
|
package/dist/node.js
ADDED
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import {
|
|
2
|
+
BASE_CSS,
|
|
3
|
+
BEHAVIORS,
|
|
4
|
+
BEHAVIOR_LOADER
|
|
5
|
+
} from "./chunk-RO5BKIKN.js";
|
|
6
|
+
|
|
7
|
+
// src/node.ts
|
|
8
|
+
import { existsSync } from "fs";
|
|
9
|
+
import { mkdir, writeFile } from "fs/promises";
|
|
10
|
+
import { dirname, join } from "path";
|
|
11
|
+
import { fileURLToPath, pathToFileURL } from "url";
|
|
12
|
+
var PKG_ROOT = join(dirname(fileURLToPath(import.meta.url)), "..");
|
|
13
|
+
var BEHAVIOR_FILES = [...BEHAVIORS, BEHAVIOR_LOADER];
|
|
14
|
+
function behaviorSourcePath(name) {
|
|
15
|
+
return join(PKG_ROOT, "src", "behaviors", `${name}.ts`);
|
|
16
|
+
}
|
|
17
|
+
function behaviorDistPath(name) {
|
|
18
|
+
const p = join(PKG_ROOT, "dist", "behaviors", `${name}.js`);
|
|
19
|
+
return existsSync(p) ? p : void 0;
|
|
20
|
+
}
|
|
21
|
+
var BASE_CSS_PATH = join(PKG_ROOT, "dist", "os.css");
|
|
22
|
+
var BEHAVIOR_ESBUILD = {
|
|
23
|
+
bundle: true,
|
|
24
|
+
format: "esm",
|
|
25
|
+
target: ["es2020", "safari15"],
|
|
26
|
+
platform: "browser",
|
|
27
|
+
legalComments: "none",
|
|
28
|
+
write: false
|
|
29
|
+
};
|
|
30
|
+
async function bundleBehaviors(opts = {}) {
|
|
31
|
+
const { build } = await import("esbuild");
|
|
32
|
+
const names = opts.names ?? BEHAVIOR_FILES;
|
|
33
|
+
const out = {};
|
|
34
|
+
await Promise.all(
|
|
35
|
+
names.map(async (name) => {
|
|
36
|
+
const result = await build({
|
|
37
|
+
...BEHAVIOR_ESBUILD,
|
|
38
|
+
entryPoints: [behaviorSourcePath(name)],
|
|
39
|
+
minify: opts.minify ?? true
|
|
40
|
+
});
|
|
41
|
+
out[name] = result.outputFiles?.[0]?.text ?? "";
|
|
42
|
+
})
|
|
43
|
+
);
|
|
44
|
+
return out;
|
|
45
|
+
}
|
|
46
|
+
async function writeAssets(outdir, opts = {}) {
|
|
47
|
+
const behaviorsDir = join(outdir, "behaviors");
|
|
48
|
+
await mkdir(behaviorsDir, { recursive: true });
|
|
49
|
+
const code = await bundleBehaviors();
|
|
50
|
+
const written = [];
|
|
51
|
+
for (const [name, js] of Object.entries(code)) {
|
|
52
|
+
const p = join(behaviorsDir, `${name}.js`);
|
|
53
|
+
await writeFile(p, js);
|
|
54
|
+
written.push(p);
|
|
55
|
+
}
|
|
56
|
+
const cssDir = opts.cssDir ?? outdir;
|
|
57
|
+
await mkdir(cssDir, { recursive: true });
|
|
58
|
+
const cssPath = join(cssDir, "os.css");
|
|
59
|
+
await writeFile(cssPath, BASE_CSS);
|
|
60
|
+
written.push(cssPath);
|
|
61
|
+
return written;
|
|
62
|
+
}
|
|
63
|
+
async function importBehavior(name) {
|
|
64
|
+
const src = behaviorSourcePath(name);
|
|
65
|
+
const path = existsSync(src) ? src : behaviorDistPath(name);
|
|
66
|
+
if (!path)
|
|
67
|
+
throw new Error(`behavior "${name}" not found (build @omniharmonic/openspace-renderer first)`);
|
|
68
|
+
const mod = await import(pathToFileURL(path).href);
|
|
69
|
+
return mod.default;
|
|
70
|
+
}
|
|
71
|
+
export {
|
|
72
|
+
BASE_CSS,
|
|
73
|
+
BASE_CSS_PATH,
|
|
74
|
+
BEHAVIOR_ESBUILD,
|
|
75
|
+
BEHAVIOR_FILES,
|
|
76
|
+
behaviorDistPath,
|
|
77
|
+
behaviorSourcePath,
|
|
78
|
+
bundleBehaviors,
|
|
79
|
+
importBehavior,
|
|
80
|
+
writeAssets
|
|
81
|
+
};
|
|
82
|
+
//# sourceMappingURL=node.js.map
|
package/dist/node.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/node.ts"],"sourcesContent":["/**\n * Node-only helpers (site-kit builds, the Hub dev preview, the CLI): behavior bundles and the\n * base stylesheet as files. Kept out of the main entry so the renderer stays browser-safe.\n */\nimport { existsSync } from \"node:fs\";\nimport { mkdir, writeFile } from \"node:fs/promises\";\nimport { dirname, join } from \"node:path\";\nimport { fileURLToPath, pathToFileURL } from \"node:url\";\nimport { BEHAVIOR_LOADER, BEHAVIORS, type BehaviorName } from \"./behaviors-manifest\";\nimport { BASE_CSS } from \"./styles/base-css\";\n\nconst PKG_ROOT = join(dirname(fileURLToPath(import.meta.url)), \"..\");\n\nexport type BehaviorFile = BehaviorName | typeof BEHAVIOR_LOADER;\n/** Every file served from the behaviors directory (behaviors + loader). */\nexport const BEHAVIOR_FILES: readonly BehaviorFile[] = [...BEHAVIORS, BEHAVIOR_LOADER];\n\n/** TypeScript source of a behavior (present in the monorepo / source checkouts). */\nexport function behaviorSourcePath(name: BehaviorFile): string {\n return join(PKG_ROOT, \"src\", \"behaviors\", `${name}.ts`);\n}\n\n/** Prebuilt, minified module in `dist/behaviors/` (after `pnpm build`), if present. */\nexport function behaviorDistPath(name: BehaviorFile): string | undefined {\n const p = join(PKG_ROOT, \"dist\", \"behaviors\", `${name}.js`);\n return existsSync(p) ? p : undefined;\n}\n\n/** Path of the built `os.css` (after `pnpm build`). Prefer {@link BASE_CSS} in code. */\nexport const BASE_CSS_PATH = join(PKG_ROOT, \"dist\", \"os.css\");\n\nexport interface BundleOptions {\n minify?: boolean;\n names?: readonly BehaviorFile[];\n}\n\n/** esbuild options shared by the package build and runtime bundling. */\nexport const BEHAVIOR_ESBUILD = {\n bundle: true,\n format: \"esm\" as const,\n target: [\"es2020\", \"safari15\"],\n platform: \"browser\" as const,\n legalComments: \"none\" as const,\n write: false as const,\n};\n\n/** Bundle behaviors from source with esbuild: `{ name: code }`. */\nexport async function bundleBehaviors(opts: BundleOptions = {}): Promise<Record<string, string>> {\n const { build } = await import(\"esbuild\");\n const names = opts.names ?? BEHAVIOR_FILES;\n const out: Record<string, string> = {};\n await Promise.all(\n names.map(async (name) => {\n const result = await build({\n ...BEHAVIOR_ESBUILD,\n entryPoints: [behaviorSourcePath(name)],\n minify: opts.minify ?? true,\n });\n out[name] = result.outputFiles?.[0]?.text ?? \"\";\n }),\n );\n return out;\n}\n\n/** Write `os.css` and every behavior module into `outdir` (e.g. `dist/_os`). */\nexport async function writeAssets(\n outdir: string,\n opts: { cssDir?: string } = {},\n): Promise<string[]> {\n const behaviorsDir = join(outdir, \"behaviors\");\n await mkdir(behaviorsDir, { recursive: true });\n const code = await bundleBehaviors();\n const written: string[] = [];\n for (const [name, js] of Object.entries(code)) {\n const p = join(behaviorsDir, `${name}.js`);\n await writeFile(p, js);\n written.push(p);\n }\n const cssDir = opts.cssDir ?? outdir;\n await mkdir(cssDir, { recursive: true });\n const cssPath = join(cssDir, \"os.css\");\n await writeFile(cssPath, BASE_CSS);\n written.push(cssPath);\n return written;\n}\n\n/** A behavior's `init(el)` (the module's default export). */\nexport type BehaviorInit = (el: HTMLElement) => void;\n\n/**\n * Import a behavior module and return its `init`. Loads the TypeScript source when present\n * (monorepo, vitest) and the built `dist/` module otherwise — for tests that run behaviors in a\n * DOM environment such as happy-dom. The same modules are importable by specifier as\n * `@omniharmonic/openspace-renderer/behavior-source/<name>`.\n */\nexport async function importBehavior(name: BehaviorFile): Promise<BehaviorInit> {\n const src = behaviorSourcePath(name);\n const path = existsSync(src) ? src : behaviorDistPath(name);\n if (!path)\n throw new Error(`behavior \"${name}\" not found (build @omniharmonic/openspace-renderer first)`);\n const mod = (await import(pathToFileURL(path).href)) as { default: BehaviorInit };\n return mod.default;\n}\n\nexport { BASE_CSS };\n"],"mappings":";;;;;;;AAIA,SAAS,kBAAkB;AAC3B,SAAS,OAAO,iBAAiB;AACjC,SAAS,SAAS,YAAY;AAC9B,SAAS,eAAe,qBAAqB;AAI7C,IAAM,WAAW,KAAK,QAAQ,cAAc,YAAY,GAAG,CAAC,GAAG,IAAI;AAI5D,IAAM,iBAA0C,CAAC,GAAG,WAAW,eAAe;AAG9E,SAAS,mBAAmB,MAA4B;AAC7D,SAAO,KAAK,UAAU,OAAO,aAAa,GAAG,IAAI,KAAK;AACxD;AAGO,SAAS,iBAAiB,MAAwC;AACvE,QAAM,IAAI,KAAK,UAAU,QAAQ,aAAa,GAAG,IAAI,KAAK;AAC1D,SAAO,WAAW,CAAC,IAAI,IAAI;AAC7B;AAGO,IAAM,gBAAgB,KAAK,UAAU,QAAQ,QAAQ;AAQrD,IAAM,mBAAmB;AAAA,EAC9B,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,QAAQ,CAAC,UAAU,UAAU;AAAA,EAC7B,UAAU;AAAA,EACV,eAAe;AAAA,EACf,OAAO;AACT;AAGA,eAAsB,gBAAgB,OAAsB,CAAC,GAAoC;AAC/F,QAAM,EAAE,MAAM,IAAI,MAAM,OAAO,SAAS;AACxC,QAAM,QAAQ,KAAK,SAAS;AAC5B,QAAM,MAA8B,CAAC;AACrC,QAAM,QAAQ;AAAA,IACZ,MAAM,IAAI,OAAO,SAAS;AACxB,YAAM,SAAS,MAAM,MAAM;AAAA,QACzB,GAAG;AAAA,QACH,aAAa,CAAC,mBAAmB,IAAI,CAAC;AAAA,QACtC,QAAQ,KAAK,UAAU;AAAA,MACzB,CAAC;AACD,UAAI,IAAI,IAAI,OAAO,cAAc,CAAC,GAAG,QAAQ;AAAA,IAC/C,CAAC;AAAA,EACH;AACA,SAAO;AACT;AAGA,eAAsB,YACpB,QACA,OAA4B,CAAC,GACV;AACnB,QAAM,eAAe,KAAK,QAAQ,WAAW;AAC7C,QAAM,MAAM,cAAc,EAAE,WAAW,KAAK,CAAC;AAC7C,QAAM,OAAO,MAAM,gBAAgB;AACnC,QAAM,UAAoB,CAAC;AAC3B,aAAW,CAAC,MAAM,EAAE,KAAK,OAAO,QAAQ,IAAI,GAAG;AAC7C,UAAM,IAAI,KAAK,cAAc,GAAG,IAAI,KAAK;AACzC,UAAM,UAAU,GAAG,EAAE;AACrB,YAAQ,KAAK,CAAC;AAAA,EAChB;AACA,QAAM,SAAS,KAAK,UAAU;AAC9B,QAAM,MAAM,QAAQ,EAAE,WAAW,KAAK,CAAC;AACvC,QAAM,UAAU,KAAK,QAAQ,QAAQ;AACrC,QAAM,UAAU,SAAS,QAAQ;AACjC,UAAQ,KAAK,OAAO;AACpB,SAAO;AACT;AAWA,eAAsB,eAAe,MAA2C;AAC9E,QAAM,MAAM,mBAAmB,IAAI;AACnC,QAAM,OAAO,WAAW,GAAG,IAAI,MAAM,iBAAiB,IAAI;AAC1D,MAAI,CAAC;AACH,UAAM,IAAI,MAAM,aAAa,IAAI,4DAA4D;AAC/F,QAAM,MAAO,MAAM,OAAO,cAAc,IAAI,EAAE;AAC9C,SAAO,IAAI;AACb;","names":[]}
|