mordoc 0.1.13 → 1.0.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 +7 -0
- package/bin/cli.js +24 -71
- package/dist/cli/asset-rewrite.d.ts +40 -0
- package/dist/cli/asset-rewrite.d.ts.map +1 -0
- package/dist/cli/asset-rewrite.js +67 -0
- package/dist/cli/asset-rewrite.js.map +1 -0
- package/dist/cli/build.d.ts +45 -15
- package/dist/cli/build.d.ts.map +1 -1
- package/dist/cli/build.js +186 -101
- package/dist/cli/build.js.map +1 -1
- package/dist/cli/dev.d.ts +26 -14
- package/dist/cli/dev.d.ts.map +1 -1
- package/dist/cli/dev.js +116 -159
- package/dist/cli/dev.js.map +1 -1
- package/dist/cli/pagefind-indexer.d.ts +15 -0
- package/dist/cli/pagefind-indexer.d.ts.map +1 -0
- package/dist/cli/pagefind-indexer.js +68 -0
- package/dist/cli/pagefind-indexer.js.map +1 -0
- package/dist/cli/paths.d.ts +26 -0
- package/dist/cli/paths.d.ts.map +1 -0
- package/dist/cli/paths.js +32 -0
- package/dist/cli/paths.js.map +1 -0
- package/dist/cli/ssg-runner.d.ts +58 -0
- package/dist/cli/ssg-runner.d.ts.map +1 -0
- package/dist/cli/ssg-runner.js +126 -0
- package/dist/cli/ssg-runner.js.map +1 -0
- package/dist/config/assets-loader.d.ts +11 -0
- package/dist/config/assets-loader.d.ts.map +1 -0
- package/dist/config/assets-loader.js +46 -0
- package/dist/config/assets-loader.js.map +1 -0
- package/dist/config/language-loader.d.ts +11 -0
- package/dist/config/language-loader.d.ts.map +1 -0
- package/dist/config/language-loader.js +61 -0
- package/dist/config/language-loader.js.map +1 -0
- package/dist/config/language.d.ts +11 -0
- package/dist/config/language.d.ts.map +1 -0
- package/dist/config/language.js +61 -0
- package/dist/config/language.js.map +1 -0
- package/dist/config/sidenav-loader.d.ts +14 -0
- package/dist/config/sidenav-loader.d.ts.map +1 -0
- package/dist/config/sidenav-loader.js +78 -0
- package/dist/config/sidenav-loader.js.map +1 -0
- package/dist/config/site-loader.d.ts +11 -0
- package/dist/config/site-loader.d.ts.map +1 -0
- package/dist/config/site-loader.js +72 -0
- package/dist/config/site-loader.js.map +1 -0
- package/dist/config/site.d.ts +11 -0
- package/dist/config/site.d.ts.map +1 -0
- package/dist/config/site.js +72 -0
- package/dist/config/site.js.map +1 -0
- package/dist/config/topnav-loader.d.ts +10 -0
- package/dist/config/topnav-loader.d.ts.map +1 -0
- package/dist/config/topnav-loader.js +78 -0
- package/dist/config/topnav-loader.js.map +1 -0
- package/dist/config/translations-loader.d.ts +7 -0
- package/dist/config/translations-loader.d.ts.map +1 -0
- package/dist/config/translations-loader.js +51 -0
- package/dist/config/translations-loader.js.map +1 -0
- package/dist/content/content-loader.d.ts +16 -0
- package/dist/content/content-loader.d.ts.map +1 -0
- package/dist/content/content-loader.js +126 -0
- package/dist/content/content-loader.js.map +1 -0
- package/dist/content/content-parser.d.ts +12 -0
- package/dist/content/content-parser.d.ts.map +1 -0
- package/dist/content/content-parser.js +54 -0
- package/dist/content/content-parser.js.map +1 -0
- package/dist/content/content-transformer.d.ts +17 -0
- package/dist/content/content-transformer.d.ts.map +1 -0
- package/dist/content/content-transformer.js +94 -0
- package/dist/content/content-transformer.js.map +1 -0
- package/dist/content/markdoc-config.d.ts +13 -0
- package/dist/content/markdoc-config.d.ts.map +1 -0
- package/dist/content/markdoc-config.js +210 -0
- package/dist/content/markdoc-config.js.map +1 -0
- package/dist/content/slug.d.ts +26 -0
- package/dist/content/slug.d.ts.map +1 -0
- package/dist/content/slug.js +31 -0
- package/dist/content/slug.js.map +1 -0
- package/dist/pipeline.d.ts +61 -0
- package/dist/pipeline.d.ts.map +1 -0
- package/dist/pipeline.js +123 -0
- package/dist/pipeline.js.map +1 -0
- package/dist/types/assets.d.ts +15 -0
- package/dist/types/assets.d.ts.map +1 -0
- package/dist/types/assets.js +2 -0
- package/dist/types/assets.js.map +1 -0
- package/dist/types/content.d.ts +114 -32
- package/dist/types/content.d.ts.map +1 -1
- package/dist/types/content.js +1 -6
- package/dist/types/content.js.map +1 -1
- package/dist/types/language.d.ts +9 -0
- package/dist/types/language.d.ts.map +1 -0
- package/dist/types/language.js +2 -0
- package/dist/types/language.js.map +1 -0
- package/dist/types/navigation.d.ts +24 -36
- package/dist/types/navigation.d.ts.map +1 -1
- package/dist/types/navigation.js +1 -6
- package/dist/types/navigation.js.map +1 -1
- package/dist/types/pipeline.d.ts +70 -0
- package/dist/types/pipeline.d.ts.map +1 -0
- package/dist/types/pipeline.js +2 -0
- package/dist/types/pipeline.js.map +1 -0
- package/dist/types/site.d.ts +20 -0
- package/dist/types/site.d.ts.map +1 -0
- package/dist/types/site.js +2 -0
- package/dist/types/site.js.map +1 -0
- package/dist/utils/lang-utils.d.ts +23 -0
- package/dist/utils/lang-utils.d.ts.map +1 -0
- package/dist/utils/lang-utils.js +40 -0
- package/dist/utils/lang-utils.js.map +1 -0
- package/dist/utils/paths.d.ts +25 -0
- package/dist/utils/paths.d.ts.map +1 -0
- package/dist/utils/paths.js +31 -0
- package/dist/utils/paths.js.map +1 -0
- package/dist/vite/plugin.d.ts +93 -0
- package/dist/vite/plugin.d.ts.map +1 -0
- package/dist/vite/plugin.js +435 -0
- package/dist/vite/plugin.js.map +1 -0
- package/package.json +46 -61
- package/src/app/App.module.css +82 -0
- package/src/app/App.tsx +95 -0
- package/src/app/content/Content.module.css +357 -0
- package/src/app/content/Content.tsx +212 -0
- package/src/app/content/callout/Callout.module.css +110 -0
- package/src/app/content/callout/Callout.tsx +82 -0
- package/src/app/content/card/Card.module.css +146 -0
- package/src/app/content/card/Card.tsx +110 -0
- package/src/app/content/card/CardGrid.module.css +22 -0
- package/src/app/content/card/CardGrid.tsx +34 -0
- package/src/app/content/code-block/CodeBlock.module.css +237 -0
- package/src/app/content/code-block/CodeBlock.tsx +123 -0
- package/src/app/content/heading/Heading.module.css +52 -0
- package/src/app/content/heading/Heading.tsx +75 -0
- package/src/app/content/image/Image.module.css +113 -0
- package/src/app/content/image/Image.tsx +98 -0
- package/src/app/content/link/ContentLink.tsx +46 -0
- package/src/app/data-context.tsx +39 -0
- package/src/app/entry-server.tsx +58 -0
- package/src/app/footer/Footer.module.css +36 -0
- package/src/app/footer/Footer.tsx +28 -0
- package/src/app/globals.d.ts +40 -0
- package/src/app/header/Header.module.css +205 -0
- package/src/app/header/Header.tsx +188 -0
- package/src/app/header/LanguagePicker.module.css +97 -0
- package/src/app/header/LanguagePicker.tsx +174 -0
- package/src/app/header/SearchBar.module.css +92 -0
- package/src/app/header/SearchBar.tsx +37 -0
- package/src/app/header/SearchModal.module.css +185 -0
- package/src/app/header/SearchModal.tsx +245 -0
- package/src/app/header/Topnav.module.css +37 -0
- package/src/app/header/Topnav.tsx +30 -0
- package/src/app/index.css +119 -0
- package/src/app/index.html +13 -0
- package/src/app/landing/LandingPage.module.css +14 -0
- package/src/app/landing/LandingPage.tsx +62 -0
- package/src/app/landing/button/Button.module.css +37 -0
- package/src/app/landing/button/Button.tsx +50 -0
- package/src/app/landing/hero/Hero.module.css +108 -0
- package/src/app/landing/hero/Hero.tsx +81 -0
- package/src/app/landing/section/Section.module.css +100 -0
- package/src/app/landing/section/Section.tsx +61 -0
- package/src/app/lang-utils.ts +11 -0
- package/src/app/main.tsx +67 -0
- package/src/app/not-found/NotFound.module.css +92 -0
- package/src/app/not-found/NotFound.tsx +34 -0
- package/src/app/routes.tsx +86 -0
- package/src/app/sidenav/Sidenav.module.css +239 -0
- package/src/app/sidenav/Sidenav.tsx +182 -0
- package/src/app/skeleton/Skeleton.module.css +100 -0
- package/src/app/skeleton/Skeleton.tsx +75 -0
- package/src/app/toc/Toc.module.css +59 -0
- package/src/app/toc/Toc.tsx +77 -0
- package/src/app/tsconfig.json +18 -0
- package/src/app/virtual-modules.d.ts +74 -0
- package/dist/assets/fonts/inter/Inter-Italic-VariableFont_opsz,wght.ttf +0 -0
- package/dist/assets/fonts/inter/Inter-VariableFont_opsz,wght.ttf +0 -0
- package/dist/assets/fonts/inter/OFL.txt +0 -93
- package/dist/build/Builder.d.ts +0 -92
- package/dist/build/Builder.d.ts.map +0 -1
- package/dist/build/Builder.js +0 -394
- package/dist/build/Builder.js.map +0 -1
- package/dist/build/ClientBundler.d.ts +0 -48
- package/dist/build/ClientBundler.d.ts.map +0 -1
- package/dist/build/ClientBundler.js +0 -169
- package/dist/build/ClientBundler.js.map +0 -1
- package/dist/build/HtmlGenerator.d.ts +0 -46
- package/dist/build/HtmlGenerator.d.ts.map +0 -1
- package/dist/build/HtmlGenerator.js +0 -190
- package/dist/build/HtmlGenerator.js.map +0 -1
- package/dist/build/SearchIndexer.d.ts +0 -31
- package/dist/build/SearchIndexer.d.ts.map +0 -1
- package/dist/build/SearchIndexer.js +0 -116
- package/dist/build/SearchIndexer.js.map +0 -1
- package/dist/bundles/client.js +0 -126
- package/dist/cli/create-app.d.ts +0 -14
- package/dist/cli/create-app.d.ts.map +0 -1
- package/dist/cli/create-app.js +0 -241
- package/dist/cli/create-app.js.map +0 -1
- package/dist/client/App.d.ts +0 -17
- package/dist/client/App.d.ts.map +0 -1
- package/dist/client/App.js +0 -91
- package/dist/client/App.js.map +0 -1
- package/dist/client/contexts/ConfigContext.d.ts +0 -22
- package/dist/client/contexts/ConfigContext.d.ts.map +0 -1
- package/dist/client/contexts/ConfigContext.js +0 -27
- package/dist/client/contexts/ConfigContext.js.map +0 -1
- package/dist/client/contexts/ContentContext.d.ts +0 -31
- package/dist/client/contexts/ContentContext.d.ts.map +0 -1
- package/dist/client/contexts/ContentContext.js +0 -46
- package/dist/client/contexts/ContentContext.js.map +0 -1
- package/dist/client/contexts/SearchContext.d.ts +0 -38
- package/dist/client/contexts/SearchContext.d.ts.map +0 -1
- package/dist/client/contexts/SearchContext.js +0 -185
- package/dist/client/contexts/SearchContext.js.map +0 -1
- package/dist/client/contexts/ThemeContext.d.ts +0 -23
- package/dist/client/contexts/ThemeContext.d.ts.map +0 -1
- package/dist/client/contexts/ThemeContext.js +0 -53
- package/dist/client/contexts/ThemeContext.js.map +0 -1
- package/dist/client/hooks/useContent.d.ts +0 -12
- package/dist/client/hooks/useContent.d.ts.map +0 -1
- package/dist/client/hooks/useContent.js +0 -74
- package/dist/client/hooks/useContent.js.map +0 -1
- package/dist/client/hooks/useNavigation.d.ts +0 -15
- package/dist/client/hooks/useNavigation.d.ts.map +0 -1
- package/dist/client/hooks/useNavigation.js +0 -101
- package/dist/client/hooks/useNavigation.js.map +0 -1
- package/dist/client/hooks/useSearch.d.ts +0 -22
- package/dist/client/hooks/useSearch.d.ts.map +0 -1
- package/dist/client/hooks/useSearch.js +0 -64
- package/dist/client/hooks/useSearch.js.map +0 -1
- package/dist/client/main.d.ts +0 -5
- package/dist/client/main.d.ts.map +0 -1
- package/dist/client/main.js +0 -66
- package/dist/client/main.js.map +0 -1
- package/dist/components/Callout.d.ts +0 -9
- package/dist/components/Callout.d.ts.map +0 -1
- package/dist/components/Callout.js +0 -24
- package/dist/components/Callout.js.map +0 -1
- package/dist/components/Card.d.ts +0 -10
- package/dist/components/Card.d.ts.map +0 -1
- package/dist/components/Card.js +0 -15
- package/dist/components/Card.js.map +0 -1
- package/dist/components/CardGrid.d.ts +0 -8
- package/dist/components/CardGrid.d.ts.map +0 -1
- package/dist/components/CardGrid.js +0 -9
- package/dist/components/CardGrid.js.map +0 -1
- package/dist/components/CodeBlock.d.ts +0 -28
- package/dist/components/CodeBlock.d.ts.map +0 -1
- package/dist/components/CodeBlock.js +0 -80
- package/dist/components/CodeBlock.js.map +0 -1
- package/dist/components/ContentPage.d.ts +0 -9
- package/dist/components/ContentPage.d.ts.map +0 -1
- package/dist/components/ContentPage.js +0 -102
- package/dist/components/ContentPage.js.map +0 -1
- package/dist/components/Header.d.ts +0 -14
- package/dist/components/Header.d.ts.map +0 -1
- package/dist/components/Header.js +0 -30
- package/dist/components/Header.js.map +0 -1
- package/dist/components/Heading.d.ts +0 -16
- package/dist/components/Heading.d.ts.map +0 -1
- package/dist/components/Heading.js +0 -31
- package/dist/components/Heading.js.map +0 -1
- package/dist/components/Image.d.ts +0 -8
- package/dist/components/Image.d.ts.map +0 -1
- package/dist/components/Image.js +0 -24
- package/dist/components/Image.js.map +0 -1
- package/dist/components/Layout.d.ts +0 -14
- package/dist/components/Layout.d.ts.map +0 -1
- package/dist/components/Layout.js +0 -32
- package/dist/components/Layout.js.map +0 -1
- package/dist/components/MarkdocRenderer.d.ts +0 -15
- package/dist/components/MarkdocRenderer.d.ts.map +0 -1
- package/dist/components/MarkdocRenderer.js +0 -73
- package/dist/components/MarkdocRenderer.js.map +0 -1
- package/dist/components/MobileMenu.d.ts +0 -14
- package/dist/components/MobileMenu.d.ts.map +0 -1
- package/dist/components/MobileMenu.js +0 -45
- package/dist/components/MobileMenu.js.map +0 -1
- package/dist/components/PageNavigation.d.ts +0 -9
- package/dist/components/PageNavigation.d.ts.map +0 -1
- package/dist/components/PageNavigation.js +0 -23
- package/dist/components/PageNavigation.js.map +0 -1
- package/dist/components/SearchModal.d.ts +0 -9
- package/dist/components/SearchModal.d.ts.map +0 -1
- package/dist/components/SearchModal.js +0 -74
- package/dist/components/SearchModal.js.map +0 -1
- package/dist/components/SideNav.d.ts +0 -9
- package/dist/components/SideNav.d.ts.map +0 -1
- package/dist/components/SideNav.js +0 -66
- package/dist/components/SideNav.js.map +0 -1
- package/dist/components/TableOfContents.d.ts +0 -10
- package/dist/components/TableOfContents.d.ts.map +0 -1
- package/dist/components/TableOfContents.js +0 -151
- package/dist/components/TableOfContents.js.map +0 -1
- package/dist/config/ConfigLoader.d.ts +0 -50
- package/dist/config/ConfigLoader.d.ts.map +0 -1
- package/dist/config/ConfigLoader.js +0 -214
- package/dist/config/ConfigLoader.js.map +0 -1
- package/dist/config/StyleCompiler.d.ts +0 -17
- package/dist/config/StyleCompiler.d.ts.map +0 -1
- package/dist/config/StyleCompiler.js +0 -116
- package/dist/config/StyleCompiler.js.map +0 -1
- package/dist/config/ThemeGenerator.d.ts +0 -14
- package/dist/config/ThemeGenerator.d.ts.map +0 -1
- package/dist/config/ThemeGenerator.js +0 -129
- package/dist/config/ThemeGenerator.js.map +0 -1
- package/dist/content/ContentLoader.d.ts +0 -70
- package/dist/content/ContentLoader.d.ts.map +0 -1
- package/dist/content/ContentLoader.js +0 -146
- package/dist/content/ContentLoader.js.map +0 -1
- package/dist/content/ContentProcessor.d.ts +0 -84
- package/dist/content/ContentProcessor.d.ts.map +0 -1
- package/dist/content/ContentProcessor.js +0 -380
- package/dist/content/ContentProcessor.js.map +0 -1
- package/dist/content/RouteManager.d.ts +0 -69
- package/dist/content/RouteManager.d.ts.map +0 -1
- package/dist/content/RouteManager.js +0 -143
- package/dist/content/RouteManager.js.map +0 -1
- package/dist/styles/components/callout.d.ts +0 -11
- package/dist/styles/components/callout.d.ts.map +0 -1
- package/dist/styles/components/callout.js +0 -87
- package/dist/styles/components/callout.js.map +0 -1
- package/dist/styles/components/card.d.ts +0 -11
- package/dist/styles/components/card.d.ts.map +0 -1
- package/dist/styles/components/card.js +0 -179
- package/dist/styles/components/card.js.map +0 -1
- package/dist/styles/components/codeblock.d.ts +0 -11
- package/dist/styles/components/codeblock.d.ts.map +0 -1
- package/dist/styles/components/codeblock.js +0 -251
- package/dist/styles/components/codeblock.js.map +0 -1
- package/dist/styles/components/content.d.ts +0 -11
- package/dist/styles/components/content.d.ts.map +0 -1
- package/dist/styles/components/content.js +0 -197
- package/dist/styles/components/content.js.map +0 -1
- package/dist/styles/components/fonts.d.ts +0 -11
- package/dist/styles/components/fonts.d.ts.map +0 -1
- package/dist/styles/components/fonts.js +0 -34
- package/dist/styles/components/fonts.js.map +0 -1
- package/dist/styles/components/header.d.ts +0 -11
- package/dist/styles/components/header.d.ts.map +0 -1
- package/dist/styles/components/header.js +0 -293
- package/dist/styles/components/header.js.map +0 -1
- package/dist/styles/components/heading.d.ts +0 -11
- package/dist/styles/components/heading.d.ts.map +0 -1
- package/dist/styles/components/heading.js +0 -115
- package/dist/styles/components/heading.js.map +0 -1
- package/dist/styles/components/layout.d.ts +0 -11
- package/dist/styles/components/layout.d.ts.map +0 -1
- package/dist/styles/components/layout.js +0 -79
- package/dist/styles/components/layout.js.map +0 -1
- package/dist/styles/components/mobilemenu.d.ts +0 -11
- package/dist/styles/components/mobilemenu.d.ts.map +0 -1
- package/dist/styles/components/mobilemenu.js +0 -112
- package/dist/styles/components/mobilemenu.js.map +0 -1
- package/dist/styles/components/reset.d.ts +0 -11
- package/dist/styles/components/reset.d.ts.map +0 -1
- package/dist/styles/components/reset.js +0 -131
- package/dist/styles/components/reset.js.map +0 -1
- package/dist/styles/components/searchmodal.d.ts +0 -11
- package/dist/styles/components/searchmodal.d.ts.map +0 -1
- package/dist/styles/components/searchmodal.js +0 -333
- package/dist/styles/components/searchmodal.js.map +0 -1
- package/dist/styles/components/sidenav.d.ts +0 -11
- package/dist/styles/components/sidenav.d.ts.map +0 -1
- package/dist/styles/components/sidenav.js +0 -212
- package/dist/styles/components/sidenav.js.map +0 -1
- package/dist/styles/components/toc.d.ts +0 -11
- package/dist/styles/components/toc.d.ts.map +0 -1
- package/dist/styles/components/toc.js +0 -120
- package/dist/styles/components/toc.js.map +0 -1
- package/dist/styles/components/typography.d.ts +0 -11
- package/dist/styles/components/typography.d.ts.map +0 -1
- package/dist/styles/components/typography.js +0 -248
- package/dist/styles/components/typography.js.map +0 -1
- package/dist/styles/components/utility.d.ts +0 -11
- package/dist/styles/components/utility.d.ts.map +0 -1
- package/dist/styles/components/utility.js +0 -231
- package/dist/styles/components/utility.js.map +0 -1
- package/dist/styles/types.d.ts +0 -79
- package/dist/styles/types.d.ts.map +0 -1
- package/dist/styles/types.js +0 -7
- package/dist/styles/types.js.map +0 -1
- package/dist/styles/utils.d.ts +0 -21
- package/dist/styles/utils.d.ts.map +0 -1
- package/dist/styles/utils.js +0 -50
- package/dist/styles/utils.js.map +0 -1
- package/dist/styles/variables/main.d.ts +0 -15
- package/dist/styles/variables/main.d.ts.map +0 -1
- package/dist/styles/variables/main.js +0 -116
- package/dist/styles/variables/main.js.map +0 -1
- package/dist/types/config.d.ts +0 -43
- package/dist/types/config.d.ts.map +0 -1
- package/dist/types/config.js +0 -7
- package/dist/types/config.js.map +0 -1
- package/dist/utils/language-utils.d.ts +0 -41
- package/dist/utils/language-utils.d.ts.map +0 -1
- package/dist/utils/language-utils.js +0 -79
- package/dist/utils/language-utils.js.map +0 -1
- package/dist/utils/slugify.d.ts +0 -20
- package/dist/utils/slugify.d.ts.map +0 -1
- package/dist/utils/slugify.js +0 -44
- package/dist/utils/slugify.js.map +0 -1
- package/templates/default/config/favicon.ico +0 -0
- package/templates/default/config/logo-dark.png +0 -0
- package/templates/default/config/logo.png +0 -0
- package/templates/default/config/sidenav.yaml +0 -36
- package/templates/default/config/site.json +0 -16
- package/templates/default/config/styles/main.json +0 -6
- package/templates/default/config/styles/typography.json +0 -6
- package/templates/default/content/en/changelog.md +0 -35
- package/templates/default/content/en/faq.md +0 -50
- package/templates/default/content/en/field-manual/engines.md +0 -59
- package/templates/default/content/en/field-manual/relativity.md +0 -46
- package/templates/default/content/en/field-manual/safety.md +0 -44
- package/templates/default/content/en/field-manual.md +0 -22
- package/templates/default/content/en/flight-school/navigation.md +0 -61
- package/templates/default/content/en/flight-school/primer.md +0 -64
- package/templates/default/content/en/flight-school.md +0 -48
- package/templates/default/content/en/index.md +0 -83
- package/templates/default/content/en/ship-systems/flux-sails.md +0 -33
- package/templates/default/content/en/ship-systems/photonic-core.md +0 -39
- package/templates/default/content/en/ship-systems.md +0 -25
- package/templates/default/package.json +0 -21
- package/templates/default/public/icons/academy.svg +0 -15
- package/templates/default/public/icons/manual.svg +0 -16
- package/templates/default/public/icons/relativity.svg +0 -16
- package/templates/default/public/icons/systems.svg +0 -14
- package/templates/default/public/icons/warning.svg +0 -14
- package/templates/default/public/images/flux-sails.svg +0 -33
- package/templates/default/public/images/photonic-core.svg +0 -44
- package/templates/default/public/images/starwake.svg +0 -49
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* LandingPage — full-width route component for pages with `layout: landing`.
|
|
3
|
+
*
|
|
4
|
+
* Rendered instead of Content when a page's frontmatter declares
|
|
5
|
+
* `layout: landing`. The App shell suppresses the sidenav and hamburger
|
|
6
|
+
* for these routes (detected via the route handle set in routes.tsx).
|
|
7
|
+
*
|
|
8
|
+
* Unlike Content, LandingPage has no article chrome: no breadcrumb, no
|
|
9
|
+
* TOC column, no read-time badge, no frontmatter title/description header.
|
|
10
|
+
* The author composes the page entirely via Markdoc tags. The .content
|
|
11
|
+
* wrapper has no horizontal padding — hero and section components each
|
|
12
|
+
* own their inner padding so full-bleed backgrounds reach the viewport edge.
|
|
13
|
+
*
|
|
14
|
+
* The same loader mechanism as Content — lazy virtual:mordoc/page/<routePath>
|
|
15
|
+
* — supplies the PageData, so SSR, SSG, and HMR all work identically.
|
|
16
|
+
*
|
|
17
|
+
* CJS interop: same Markdoc default-import constraint as Content.tsx.
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
import { useEffect } from 'react';
|
|
21
|
+
import { useLoaderData } from 'react-router';
|
|
22
|
+
import React from 'react';
|
|
23
|
+
import Markdoc from '@markdoc/markdoc';
|
|
24
|
+
import { useMordocData } from '../data-context.js';
|
|
25
|
+
import { Footer } from '../footer/Footer.js';
|
|
26
|
+
import { CodeBlock } from '../content/code-block/CodeBlock.js';
|
|
27
|
+
import { Image } from '../content/image/Image.js';
|
|
28
|
+
import { Callout } from '../content/callout/Callout.js';
|
|
29
|
+
import { Card } from '../content/card/Card.js';
|
|
30
|
+
import { CardGrid } from '../content/card/CardGrid.js';
|
|
31
|
+
import { ContentLink } from '../content/link/ContentLink.js';
|
|
32
|
+
import { Heading } from '../content/heading/Heading.js';
|
|
33
|
+
import { Hero } from './hero/Hero.js';
|
|
34
|
+
import { Section } from './section/Section.js';
|
|
35
|
+
import { Button } from './button/Button.js';
|
|
36
|
+
import type { PageData } from '../../types/content.js';
|
|
37
|
+
import styles from './LandingPage.module.css';
|
|
38
|
+
|
|
39
|
+
export function LandingPage() {
|
|
40
|
+
const pageData = useLoaderData() as PageData;
|
|
41
|
+
const { site } = useMordocData();
|
|
42
|
+
|
|
43
|
+
useEffect(() => {
|
|
44
|
+
const pageTitle = pageData.frontmatter.title;
|
|
45
|
+
document.title = pageTitle ? `${pageTitle} — ${site.name}` : site.name;
|
|
46
|
+
}, [pageData.frontmatter.title, site.name]);
|
|
47
|
+
|
|
48
|
+
const rendered = Markdoc.renderers.react(pageData.renderable, React, {
|
|
49
|
+
components: { CodeBlock, Image, Callout, Card, CardGrid, ContentLink, Heading, Hero, Section, Button },
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
return (
|
|
53
|
+
<div className={styles.landing}>
|
|
54
|
+
<div className={styles.content} data-pagefind-body>
|
|
55
|
+
{rendered}
|
|
56
|
+
</div>
|
|
57
|
+
<Footer />
|
|
58
|
+
</div>
|
|
59
|
+
);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export default LandingPage;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/* ── Button ───────────────────────────────────────────────────── */
|
|
2
|
+
|
|
3
|
+
.button {
|
|
4
|
+
display: inline-flex;
|
|
5
|
+
align-items: center;
|
|
6
|
+
justify-content: center;
|
|
7
|
+
height: 2.625rem;
|
|
8
|
+
padding: 0 1.375rem;
|
|
9
|
+
border-radius: var(--radius-md);
|
|
10
|
+
font-size: 0.9375rem;
|
|
11
|
+
font-weight: 600;
|
|
12
|
+
line-height: 1;
|
|
13
|
+
text-decoration: none;
|
|
14
|
+
white-space: nowrap;
|
|
15
|
+
cursor: pointer;
|
|
16
|
+
border: 1.5px solid transparent;
|
|
17
|
+
transition: background-color 0.15s ease, color 0.15s ease, border-color 0.15s ease, box-shadow 0.15s ease;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/* ── Primary ──────────────────────────────────────────────────── */
|
|
21
|
+
|
|
22
|
+
.primary {
|
|
23
|
+
background: var(--accent);
|
|
24
|
+
color: var(--accent-on);
|
|
25
|
+
border-color: var(--accent);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
.primary:hover {
|
|
29
|
+
background: var(--accent-strong);
|
|
30
|
+
border-color: var(--accent-strong);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/* Markdoc wraps button body text in <p> — collapse it so the button
|
|
34
|
+
renders cleanly without affecting inline-flex layout */
|
|
35
|
+
.button :global(p) {
|
|
36
|
+
display: contents;
|
|
37
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Button — styled CTA link for landing pages and content pages.
|
|
3
|
+
*
|
|
4
|
+
* Renders as a React Router Link for internal paths (starting with "/")
|
|
5
|
+
* or a plain <a target="_blank"> for external URLs.
|
|
6
|
+
*
|
|
7
|
+
* Markdoc wraps the button's body text in a <p> tag because the tag is
|
|
8
|
+
* block-level. The CSS collapses it with `display: contents` so the
|
|
9
|
+
* button renders as a clean inline-flex element regardless.
|
|
10
|
+
*
|
|
11
|
+
* Registered as a Markdoc tag (`button`) in markdoc-config.ts and in
|
|
12
|
+
* LandingPage.tsx's components map. Also registered in Content.tsx so it
|
|
13
|
+
* can be used in regular content pages.
|
|
14
|
+
*
|
|
15
|
+
* The prop is named `path` (not `href`) to match Mordoc's authoring
|
|
16
|
+
* convention — consistent with sidenav/topnav YAML and card tags.
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
import { Link } from 'react-router';
|
|
20
|
+
import React from 'react';
|
|
21
|
+
import styles from './Button.module.css';
|
|
22
|
+
|
|
23
|
+
interface ButtonProps {
|
|
24
|
+
path: string;
|
|
25
|
+
children?: React.ReactNode;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function isExternal(path: string) {
|
|
29
|
+
return path.startsWith('http://') || path.startsWith('https://') || path.startsWith('//');
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export function Button({ path, children }: ButtonProps) {
|
|
33
|
+
const className = `${styles.button} ${styles.primary}`;
|
|
34
|
+
|
|
35
|
+
if (isExternal(path)) {
|
|
36
|
+
return (
|
|
37
|
+
<a href={path} className={className} target="_blank" rel="noopener noreferrer" data-pagefind-ignore>
|
|
38
|
+
{children}
|
|
39
|
+
</a>
|
|
40
|
+
);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
return (
|
|
44
|
+
<Link to={path} className={className} data-pagefind-ignore>
|
|
45
|
+
{children}
|
|
46
|
+
</Link>
|
|
47
|
+
);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export default Button;
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
/* ============================================================
|
|
2
|
+
HERO TOKENS
|
|
3
|
+
============================================================ */
|
|
4
|
+
:root {
|
|
5
|
+
--hero-inner-max: 72rem;
|
|
6
|
+
--hero-title-size: clamp(2rem, 4vw, 3.125rem);
|
|
7
|
+
--hero-desc-size: 1.125rem;
|
|
8
|
+
--hero-v-padding: 7rem;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
/* ── Base ─────────────────────────────────────────────────────── */
|
|
12
|
+
|
|
13
|
+
.hero {
|
|
14
|
+
position: relative;
|
|
15
|
+
width: 100%;
|
|
16
|
+
background-size: cover;
|
|
17
|
+
background-position: center;
|
|
18
|
+
background-repeat: no-repeat;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/* ── Inner — always a centered column ────────────────────────── */
|
|
22
|
+
|
|
23
|
+
.inner {
|
|
24
|
+
position: relative;
|
|
25
|
+
display: flex;
|
|
26
|
+
flex-direction: column;
|
|
27
|
+
align-items: center;
|
|
28
|
+
width: 100%;
|
|
29
|
+
max-width: var(--hero-inner-max);
|
|
30
|
+
margin: 0 auto;
|
|
31
|
+
padding: var(--hero-v-padding) var(--page-gutter);
|
|
32
|
+
gap: 2.5rem;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/* ── Text block — narrower than inner for readability ─────────── */
|
|
36
|
+
|
|
37
|
+
.heroText {
|
|
38
|
+
display: flex;
|
|
39
|
+
flex-direction: column;
|
|
40
|
+
align-items: center;
|
|
41
|
+
text-align: center;
|
|
42
|
+
gap: 1.25rem;
|
|
43
|
+
max-width: 42rem;
|
|
44
|
+
width: 100%;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/* ── Title ────────────────────────────────────────────────────── */
|
|
48
|
+
|
|
49
|
+
.heroTitle {
|
|
50
|
+
font-size: var(--hero-title-size);
|
|
51
|
+
font-weight: 700;
|
|
52
|
+
line-height: 1.12;
|
|
53
|
+
letter-spacing: -0.025em;
|
|
54
|
+
color: var(--hero-title-color, var(--color-fg));
|
|
55
|
+
margin: 0;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/* Second title line — accent color by default, overridable per-hero */
|
|
59
|
+
.titleAccent {
|
|
60
|
+
color: var(--hero-title-accent-color, var(--accent-emphasis));
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/* ── Description ──────────────────────────────────────────────── */
|
|
64
|
+
|
|
65
|
+
.heroDescription {
|
|
66
|
+
font-size: var(--hero-desc-size);
|
|
67
|
+
line-height: 1.7;
|
|
68
|
+
color: var(--hero-desc-color, var(--color-fg-muted));
|
|
69
|
+
margin: 0;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/* ── CTAs ─────────────────────────────────────────────────────── */
|
|
73
|
+
|
|
74
|
+
.heroCtas {
|
|
75
|
+
display: flex;
|
|
76
|
+
flex-wrap: wrap;
|
|
77
|
+
gap: 0.75rem;
|
|
78
|
+
align-items: center;
|
|
79
|
+
justify-content: center;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/* Markdoc may wrap button tags in a <p> — collapse it */
|
|
83
|
+
.heroCtas :global(p) {
|
|
84
|
+
display: contents;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/* ── Foreground image — full inner width, below CTAs ─────────── */
|
|
88
|
+
|
|
89
|
+
.heroImageWrap {
|
|
90
|
+
width: 100%;
|
|
91
|
+
display: flex;
|
|
92
|
+
justify-content: center;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
.heroImage {
|
|
96
|
+
width: 100%;
|
|
97
|
+
border-radius: var(--radius-lg);
|
|
98
|
+
box-shadow: var(--shadow-md);
|
|
99
|
+
display: block;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/* ── Responsive ───────────────────────────────────────────────── */
|
|
103
|
+
|
|
104
|
+
@media (max-width: 600px) {
|
|
105
|
+
:root {
|
|
106
|
+
--hero-v-padding: 4rem;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Hero — full-width landing page hero section.
|
|
3
|
+
*
|
|
4
|
+
* Always renders as a centered column. When `image` is provided it appears
|
|
5
|
+
* below the CTAs (full inner width), giving a "product preview" feel.
|
|
6
|
+
*
|
|
7
|
+
* Title supports two lines via `title` + `titleAccent`. `titleAccent` is
|
|
8
|
+
* rendered on a new line in the accent color so authors can highlight a key
|
|
9
|
+
* phrase without any custom CSS.
|
|
10
|
+
*
|
|
11
|
+
* `background` sets a background image or color but applies no overlay —
|
|
12
|
+
* the author is responsible for preparing an image that works with the
|
|
13
|
+
* existing text colors.
|
|
14
|
+
*
|
|
15
|
+
* Registered as a Markdoc tag (`hero`) in markdoc-config.ts and in
|
|
16
|
+
* LandingPage.tsx's components map.
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
import React from 'react';
|
|
20
|
+
import styles from './Hero.module.css';
|
|
21
|
+
|
|
22
|
+
interface HeroProps {
|
|
23
|
+
title: string;
|
|
24
|
+
titleAccent?: string;
|
|
25
|
+
description?: string;
|
|
26
|
+
image?: string;
|
|
27
|
+
background?: string;
|
|
28
|
+
titleColor?: string;
|
|
29
|
+
titleAccentColor?: string;
|
|
30
|
+
descriptionColor?: string;
|
|
31
|
+
children?: React.ReactNode;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export function Hero({ title, titleAccent, description, image, background, titleColor, titleAccentColor, descriptionColor, children }: HeroProps) {
|
|
35
|
+
const style: React.CSSProperties = {};
|
|
36
|
+
if (background) {
|
|
37
|
+
const isImagePath =
|
|
38
|
+
background.startsWith('/') ||
|
|
39
|
+
background.startsWith('http://') ||
|
|
40
|
+
background.startsWith('https://');
|
|
41
|
+
if (isImagePath) {
|
|
42
|
+
style.backgroundImage = `url(${background})`;
|
|
43
|
+
} else {
|
|
44
|
+
style.backgroundColor = background;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
if (titleColor) (style as Record<string, string>)['--hero-title-color'] = titleColor;
|
|
48
|
+
if (titleAccentColor) (style as Record<string, string>)['--hero-title-accent-color'] = titleAccentColor;
|
|
49
|
+
if (descriptionColor) (style as Record<string, string>)['--hero-desc-color'] = descriptionColor;
|
|
50
|
+
|
|
51
|
+
return (
|
|
52
|
+
<section className={styles.hero} style={style}>
|
|
53
|
+
<div className={styles.inner}>
|
|
54
|
+
<div className={styles.heroText}>
|
|
55
|
+
<h1 className={styles.heroTitle}>
|
|
56
|
+
<span>{title}</span>
|
|
57
|
+
{titleAccent && (
|
|
58
|
+
<>
|
|
59
|
+
<br />
|
|
60
|
+
<span className={styles.titleAccent}>{titleAccent}</span>
|
|
61
|
+
</>
|
|
62
|
+
)}
|
|
63
|
+
</h1>
|
|
64
|
+
{description && (
|
|
65
|
+
<p className={styles.heroDescription}>{description}</p>
|
|
66
|
+
)}
|
|
67
|
+
{children && (
|
|
68
|
+
<div className={styles.heroCtas}>{children}</div>
|
|
69
|
+
)}
|
|
70
|
+
</div>
|
|
71
|
+
{image && (
|
|
72
|
+
<div className={styles.heroImageWrap}>
|
|
73
|
+
<img src={image} alt="" className={styles.heroImage} />
|
|
74
|
+
</div>
|
|
75
|
+
)}
|
|
76
|
+
</div>
|
|
77
|
+
</section>
|
|
78
|
+
);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
export default Hero;
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
/* ── Section ──────────────────────────────────────────────────── */
|
|
2
|
+
|
|
3
|
+
.section {
|
|
4
|
+
position: relative;
|
|
5
|
+
width: 100%;
|
|
6
|
+
background-size: cover;
|
|
7
|
+
background-position: center;
|
|
8
|
+
background-repeat: no-repeat;
|
|
9
|
+
overflow: hidden;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
/* Dark overlay for image backgrounds */
|
|
13
|
+
.overlay {
|
|
14
|
+
position: absolute;
|
|
15
|
+
inset: 0;
|
|
16
|
+
background: rgba(0, 0, 0, 0.5);
|
|
17
|
+
z-index: 0;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/* ── Inner container ──────────────────────────────────────────── */
|
|
21
|
+
|
|
22
|
+
.inner {
|
|
23
|
+
position: relative;
|
|
24
|
+
z-index: 1;
|
|
25
|
+
max-width: 72rem;
|
|
26
|
+
margin: 0 auto;
|
|
27
|
+
padding: 4rem var(--page-gutter);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/* ── Section title ────────────────────────────────────────────── */
|
|
31
|
+
|
|
32
|
+
.sectionTitle {
|
|
33
|
+
font-size: 1.75rem;
|
|
34
|
+
font-weight: 700;
|
|
35
|
+
line-height: 1.2;
|
|
36
|
+
letter-spacing: -0.018em;
|
|
37
|
+
color: var(--color-fg);
|
|
38
|
+
margin: 0 0 2rem 0;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
.hasBackgroundImage .sectionTitle {
|
|
42
|
+
color: #ffffff;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/* ── Content area ─────────────────────────────────────────────── */
|
|
46
|
+
|
|
47
|
+
.content :global(h2) {
|
|
48
|
+
font-size: 1.5rem;
|
|
49
|
+
font-weight: 700;
|
|
50
|
+
line-height: 1.25;
|
|
51
|
+
letter-spacing: -0.015em;
|
|
52
|
+
color: var(--color-fg);
|
|
53
|
+
margin: 2.5rem 0 1rem;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
.content :global(h2):first-child {
|
|
57
|
+
margin-top: 0;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
.content :global(h3) {
|
|
61
|
+
font-size: 1.125rem;
|
|
62
|
+
font-weight: 600;
|
|
63
|
+
line-height: 1.35;
|
|
64
|
+
color: var(--color-fg);
|
|
65
|
+
margin: 2rem 0 0.75rem;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
.content :global(p) {
|
|
69
|
+
font-size: 1rem;
|
|
70
|
+
line-height: 1.7;
|
|
71
|
+
color: var(--color-fg-muted);
|
|
72
|
+
margin: 0 0 1rem;
|
|
73
|
+
max-width: 60ch;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
.content :global(p):last-child {
|
|
77
|
+
margin-bottom: 0;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/* Image bg — push prose text to white */
|
|
81
|
+
.hasBackgroundImage .content :global(h2),
|
|
82
|
+
.hasBackgroundImage .content :global(h3) {
|
|
83
|
+
color: #ffffff;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
.hasBackgroundImage .content :global(p) {
|
|
87
|
+
color: rgba(255, 255, 255, 0.8);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/* ── Responsive ───────────────────────────────────────────────── */
|
|
91
|
+
|
|
92
|
+
@media (max-width: 600px) {
|
|
93
|
+
.inner {
|
|
94
|
+
padding: 2.5rem var(--page-gutter);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
.sectionTitle {
|
|
98
|
+
font-size: 1.375rem;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Section — full-width landing page content block.
|
|
3
|
+
*
|
|
4
|
+
* Provides a visual grouping container with optional background and an
|
|
5
|
+
* optional title rendered as an <h2>. The inner content is constrained
|
|
6
|
+
* to a readable max-width and centered.
|
|
7
|
+
*
|
|
8
|
+
* Background via `background` attribute:
|
|
9
|
+
* - image path (/... or http...) → background-image
|
|
10
|
+
* - CSS color (#hex, rgb, named…) → background-color
|
|
11
|
+
* - omitted → transparent
|
|
12
|
+
*
|
|
13
|
+
* Children can be any mix of Markdoc block content (headings, paragraphs,
|
|
14
|
+
* lists, code fences) and custom tags (cardGrid, card, callout, button).
|
|
15
|
+
*
|
|
16
|
+
* Registered as a Markdoc tag (`section`) in markdoc-config.ts and in
|
|
17
|
+
* LandingPage.tsx's components map.
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
import React from 'react';
|
|
21
|
+
import styles from './Section.module.css';
|
|
22
|
+
|
|
23
|
+
interface SectionProps {
|
|
24
|
+
title?: string;
|
|
25
|
+
background?: string;
|
|
26
|
+
children?: React.ReactNode;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export function Section({ title, background, children }: SectionProps) {
|
|
30
|
+
const style: React.CSSProperties = {};
|
|
31
|
+
let isImageBg = false;
|
|
32
|
+
|
|
33
|
+
if (background) {
|
|
34
|
+
const isImagePath =
|
|
35
|
+
background.startsWith('/') ||
|
|
36
|
+
background.startsWith('http://') ||
|
|
37
|
+
background.startsWith('https://');
|
|
38
|
+
if (isImagePath) {
|
|
39
|
+
style.backgroundImage = `url(${background})`;
|
|
40
|
+
isImageBg = true;
|
|
41
|
+
} else {
|
|
42
|
+
style.backgroundColor = background;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
const className = [
|
|
47
|
+
styles.section,
|
|
48
|
+
isImageBg ? styles.hasBackgroundImage : '',
|
|
49
|
+
].filter(Boolean).join(' ');
|
|
50
|
+
|
|
51
|
+
return (
|
|
52
|
+
<section className={className} style={style}>
|
|
53
|
+
<div className={styles.inner}>
|
|
54
|
+
{title && <h2 className={styles.sectionTitle}>{title}</h2>}
|
|
55
|
+
<div className={styles.content}>{children}</div>
|
|
56
|
+
</div>
|
|
57
|
+
</section>
|
|
58
|
+
);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export default Section;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Re-exports all lang utilities from the shared `src/utils/lang-utils.ts`.
|
|
3
|
+
* The shared location is importable by both the React app and Node-side code
|
|
4
|
+
* (pipeline, SSG runner). App-side imports continue to use this path unchanged.
|
|
5
|
+
*/
|
|
6
|
+
export {
|
|
7
|
+
detectCurrentLang,
|
|
8
|
+
buildLangPrefix,
|
|
9
|
+
stripLangPrefix,
|
|
10
|
+
resolveLabel,
|
|
11
|
+
} from '../utils/lang-utils.js';
|
package/src/app/main.tsx
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { StrictMode } from 'react';
|
|
2
|
+
import { createRoot, hydrateRoot } from 'react-dom/client';
|
|
3
|
+
import { RouterProvider } from 'react-router';
|
|
4
|
+
import site from 'virtual:mordoc/site';
|
|
5
|
+
import language from 'virtual:mordoc/language';
|
|
6
|
+
import navigation from 'virtual:mordoc/navigation';
|
|
7
|
+
import assets from 'virtual:mordoc/assets';
|
|
8
|
+
import pagesIndex from 'virtual:mordoc/pages-index';
|
|
9
|
+
import translations from 'virtual:mordoc/translations';
|
|
10
|
+
import type { ShellData } from '../types/pipeline.js';
|
|
11
|
+
import './index.css';
|
|
12
|
+
import 'virtual:mordoc/theme';
|
|
13
|
+
import { MordocDataContext } from './data-context.js';
|
|
14
|
+
import { createAppRouter } from './routes.js';
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Browser entry. Assembles `ShellData` from the eager virtual modules
|
|
18
|
+
* and hydrates the React tree.
|
|
19
|
+
*
|
|
20
|
+
* This is the only file in `src/app/` that imports the
|
|
21
|
+
* eager `virtual:mordoc/*` modules directly — every other shell
|
|
22
|
+
* component reads them via `useMordocData()`. Keeping the imports
|
|
23
|
+
* pinned here is what guarantees CSR/SSR symmetry: the server entry
|
|
24
|
+
* doesn't need any virtual imports because its `render(request, data)`
|
|
25
|
+
* receives the same `ShellData` from the dev middleware (or, later,
|
|
26
|
+
* from the SSG runner).
|
|
27
|
+
*
|
|
28
|
+
* `createBrowserRouter` is given `hydrationData` from the
|
|
29
|
+
* `<script>window.__staticRouterHydrationData = ...</script>` tag that
|
|
30
|
+
* `<StaticRouterProvider>` emits during SSR. Without this, the data
|
|
31
|
+
* router would re-run the initial route's loader on first mount,
|
|
32
|
+
* triggering a redundant fetch of the same lazy page chunk that the
|
|
33
|
+
* server already used to produce the initial HTML.
|
|
34
|
+
*/
|
|
35
|
+
const container = document.getElementById('app');
|
|
36
|
+
if (!container) {
|
|
37
|
+
throw new Error('mordoc: #app element not found in HTML shell');
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
const shellData: ShellData = {
|
|
41
|
+
site,
|
|
42
|
+
language,
|
|
43
|
+
navigation,
|
|
44
|
+
assets,
|
|
45
|
+
pagesIndex,
|
|
46
|
+
translations,
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
const hydrationData = window.__staticRouterHydrationData;
|
|
50
|
+
const router = createAppRouter(hydrationData);
|
|
51
|
+
|
|
52
|
+
const app = (
|
|
53
|
+
<StrictMode>
|
|
54
|
+
<MordocDataContext.Provider value={shellData}>
|
|
55
|
+
<RouterProvider router={router} />
|
|
56
|
+
</MordocDataContext.Provider>
|
|
57
|
+
</StrictMode>
|
|
58
|
+
);
|
|
59
|
+
|
|
60
|
+
// SSR/SSG (production): server-rendered HTML is in the container — hydrate to
|
|
61
|
+
// preserve it and attach event listeners without a full re-render.
|
|
62
|
+
// Dev: container is empty — mount fresh via createRoot.
|
|
63
|
+
if (hydrationData) {
|
|
64
|
+
hydrateRoot(container, app);
|
|
65
|
+
} else {
|
|
66
|
+
createRoot(container).render(app);
|
|
67
|
+
}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
/* ── Page shell — mirrors the article-column layout from Content ── */
|
|
2
|
+
|
|
3
|
+
.page {
|
|
4
|
+
display: flex;
|
|
5
|
+
flex-direction: column;
|
|
6
|
+
flex: 1;
|
|
7
|
+
min-height: calc(100svh - var(--header-total));
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
.articleArea {
|
|
11
|
+
flex: 1;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
.article {
|
|
15
|
+
max-width: var(--content-max-width);
|
|
16
|
+
width: 100%;
|
|
17
|
+
margin: 0 auto;
|
|
18
|
+
padding: 3rem 1.5rem;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
@media (min-width: 768px) {
|
|
22
|
+
.article {
|
|
23
|
+
padding: 3rem 2rem;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/* ── 404 display number ─────────────────────────────────────── */
|
|
28
|
+
|
|
29
|
+
.code404 {
|
|
30
|
+
margin: 0 0 0.5rem;
|
|
31
|
+
font-size: 7rem;
|
|
32
|
+
font-weight: 700;
|
|
33
|
+
line-height: 1;
|
|
34
|
+
letter-spacing: -0.04em;
|
|
35
|
+
color: var(--color-fg-muted);
|
|
36
|
+
opacity: 0.3;
|
|
37
|
+
user-select: none;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/* ── Heading + description ──────────────────────────────────── */
|
|
41
|
+
|
|
42
|
+
.title {
|
|
43
|
+
margin: 0 0 0.75rem;
|
|
44
|
+
font-size: 40px;
|
|
45
|
+
font-weight: 700;
|
|
46
|
+
line-height: 1.2;
|
|
47
|
+
letter-spacing: -0.02em;
|
|
48
|
+
color: var(--color-fg);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
.description {
|
|
52
|
+
margin: 0 0 2rem;
|
|
53
|
+
font-size: 1rem;
|
|
54
|
+
line-height: 1.7;
|
|
55
|
+
color: var(--color-content-fg);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/* Inline code pill for the path — matches prose inline-code style */
|
|
59
|
+
.path {
|
|
60
|
+
padding: 0.1em 0.375em;
|
|
61
|
+
background: var(--color-surface);
|
|
62
|
+
color: var(--color-content-fg);
|
|
63
|
+
border: 1px solid var(--color-border);
|
|
64
|
+
border-radius: var(--radius-sm);
|
|
65
|
+
font-family: var(--font-mono);
|
|
66
|
+
font-size: 0.875em;
|
|
67
|
+
font-weight: 500;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/* ── Go home button ─────────────────────────────────────────── */
|
|
71
|
+
|
|
72
|
+
.homeButton {
|
|
73
|
+
display: inline-flex;
|
|
74
|
+
align-items: center;
|
|
75
|
+
padding: 0.5rem 1.125rem;
|
|
76
|
+
background: var(--accent-emphasis);
|
|
77
|
+
color: var(--accent-on);
|
|
78
|
+
border-radius: var(--radius-md);
|
|
79
|
+
font-size: 0.9375rem;
|
|
80
|
+
font-weight: 500;
|
|
81
|
+
text-decoration: none;
|
|
82
|
+
transition: background 150ms ease;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
.homeButton:hover {
|
|
86
|
+
background: var(--accent-strong);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
.homeButton:focus-visible {
|
|
90
|
+
outline: 2px solid var(--accent-emphasis);
|
|
91
|
+
outline-offset: 2px;
|
|
92
|
+
}
|