create-ginko 0.4.0 → 0.5.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.
Files changed (1685) hide show
  1. package/CHANGELOG.md +28 -0
  2. package/README.md +15 -8
  3. package/index.mjs +115 -44
  4. package/package.json +6 -1
  5. package/presets/gastro/app/pages/index.vue +6 -4
  6. package/presets/gastro-de/app/pages/index.vue +6 -4
  7. package/template-files.mjs +377 -0
  8. package/templates/blog/.env.example +8 -0
  9. package/templates/blog/.github/screenshots/home-dark.png +0 -0
  10. package/templates/blog/.github/screenshots/home-light.png +0 -0
  11. package/templates/blog/.github/workflows/ci.yml +27 -0
  12. package/templates/blog/DESIGN.md +197 -0
  13. package/templates/blog/LICENSE +21 -0
  14. package/templates/blog/MEDIA.md +29 -0
  15. package/templates/blog/NOTES.md +16 -0
  16. package/templates/blog/README.md +274 -0
  17. package/templates/blog/app/app.config.ts +29 -0
  18. package/templates/blog/app/app.vue +7 -0
  19. package/templates/blog/app/assets/css/main.css +18 -0
  20. package/templates/blog/app/assets/css/tokens.css +400 -0
  21. package/templates/blog/app/components/InitialsAvatar.vue +18 -0
  22. package/templates/blog/app/components/ProseBody.vue +13 -0
  23. package/templates/blog/app/components/block/Cards.vue +54 -0
  24. package/templates/blog/app/components/block/Cta.vue +26 -0
  25. package/templates/blog/app/components/block/Empty.vue +26 -0
  26. package/templates/blog/app/components/block/Features.vue +24 -0
  27. package/templates/blog/app/components/block/Hero.vue +47 -0
  28. package/templates/blog/app/components/block/PageHeader.vue +21 -0
  29. package/templates/blog/app/components/block/Section.vue +31 -0
  30. package/templates/blog/app/components/blog/Byline.vue +22 -0
  31. package/templates/blog/app/components/blog/PostList.vue +33 -0
  32. package/templates/blog/app/components/blog/TagList.vue +17 -0
  33. package/templates/blog/app/components/home/LatestPost.vue +31 -0
  34. package/templates/blog/app/components/people/List.vue +41 -0
  35. package/templates/blog/app/components/site/Contact.vue +38 -0
  36. package/templates/blog/app/components/site/Footer.vue +81 -0
  37. package/templates/blog/app/components/site/FooterStatus.vue +24 -0
  38. package/templates/blog/app/components/site/Header.vue +52 -0
  39. package/templates/blog/app/components/site/LanguageSwitch.vue +34 -0
  40. package/templates/blog/app/components/site/Logo.vue +17 -0
  41. package/templates/blog/app/components/site/NavLink.vue +19 -0
  42. package/templates/blog/app/components/site/NavSheet.vue +63 -0
  43. package/templates/blog/app/components/site/Notice.vue +21 -0
  44. package/templates/blog/app/components/site/PageCta.vue +14 -0
  45. package/templates/blog/app/components/site/SkipLink.vue +15 -0
  46. package/templates/blog/app/components/site/ThemeToggle.vue +28 -0
  47. package/templates/blog/app/components/ui/button/Button.vue +30 -0
  48. package/templates/blog/app/components/ui/button/index.ts +44 -0
  49. package/templates/blog/app/components/ui/sheet/Sheet.vue +16 -0
  50. package/templates/blog/app/components/ui/sheet/SheetClose.vue +13 -0
  51. package/templates/blog/app/components/ui/sheet/SheetContent.vue +54 -0
  52. package/templates/blog/app/components/ui/sheet/SheetDescription.vue +23 -0
  53. package/templates/blog/app/components/ui/sheet/SheetOverlay.vue +22 -0
  54. package/templates/blog/app/components/ui/sheet/SheetTitle.vue +23 -0
  55. package/templates/blog/app/components/ui/sheet/SheetTrigger.vue +13 -0
  56. package/templates/blog/app/components/ui/sheet/index.ts +7 -0
  57. package/templates/blog/app/composables/useBlog.ts +103 -0
  58. package/templates/blog/app/composables/usePageSeo.ts +50 -0
  59. package/templates/blog/app/composables/useSiteAppConfig.ts +79 -0
  60. package/templates/blog/app/error.vue +35 -0
  61. package/templates/blog/app/layouts/default.vue +23 -0
  62. package/templates/blog/app/lib/utils.ts +26 -0
  63. package/templates/blog/app/pages/about/[slug].vue +48 -0
  64. package/templates/blog/app/pages/index.vue +54 -0
  65. package/templates/blog/app/pages/legal/[slug].vue +46 -0
  66. package/templates/blog/app/pages/news/[slug].vue +94 -0
  67. package/templates/blog/app/pages/news/index.vue +54 -0
  68. package/templates/blog/app/pages/news/tags/[tag].vue +41 -0
  69. package/templates/blog/app/pages/team.vue +40 -0
  70. package/templates/blog/app/routes.ts +31 -0
  71. package/templates/blog/app/utils/telHref.ts +3 -0
  72. package/templates/blog/components.json +21 -0
  73. package/templates/blog/content/home.de.md +4 -0
  74. package/templates/blog/content/home.md +4 -0
  75. package/templates/blog/content/legal/1.privacy.de.md +30 -0
  76. package/templates/blog/content/legal/1.privacy.md +30 -0
  77. package/templates/blog/content/legal/2.terms.de.md +22 -0
  78. package/templates/blog/content/legal/2.terms.md +23 -0
  79. package/templates/blog/content/legal/3.imprint.de.md +14 -0
  80. package/templates/blog/content/legal/3.imprint.md +15 -0
  81. package/templates/blog/content/notices/1.sample.de.md +3 -0
  82. package/templates/blog/content/notices/1.sample.md +4 -0
  83. package/templates/blog/content/people/1.ida-wren.de.md +4 -0
  84. package/templates/blog/content/people/1.ida-wren.md +5 -0
  85. package/templates/blog/content/people/2.tom-marsh.de.md +4 -0
  86. package/templates/blog/content/people/2.tom-marsh.md +5 -0
  87. package/templates/blog/content/posts/counting-street-trees.de.md +24 -0
  88. package/templates/blog/content/posts/counting-street-trees.md +25 -0
  89. package/templates/blog/content/posts/forest-at-the-end-of-the-line.de.md +26 -0
  90. package/templates/blog/content/posts/forest-at-the-end-of-the-line.md +28 -0
  91. package/templates/blog/content/posts/lichen-on-the-old-bridge.de.md +11 -0
  92. package/templates/blog/content/posts/lichen-on-the-old-bridge.md +14 -0
  93. package/templates/blog/content/posts/owls-in-the-old-cemetery.de.md +22 -0
  94. package/templates/blog/content/posts/owls-in-the-old-cemetery.md +23 -0
  95. package/templates/blog/content/posts/rock-pools-at-low-tide.de.md +25 -0
  96. package/templates/blog/content/posts/rock-pools-at-low-tide.md +26 -0
  97. package/templates/blog/content/posts/rock-pools.jpg +0 -0
  98. package/templates/blog/content/posts/swifts-over-the-car-park.de.md +22 -0
  99. package/templates/blog/content/posts/swifts-over-the-car-park.md +23 -0
  100. package/templates/blog/content/posts/ten-minute-notebook.de.md +36 -0
  101. package/templates/blog/content/posts/ten-minute-notebook.md +38 -0
  102. package/templates/blog/content/posts/why-we-keep-field-notes.de.md +24 -0
  103. package/templates/blog/content/posts/why-we-keep-field-notes.md +25 -0
  104. package/templates/blog/content/posts/winter-birds-by-the-bike-shed.de.md +22 -0
  105. package/templates/blog/content/posts/winter-birds-by-the-bike-shed.md +23 -0
  106. package/templates/blog/content/site.md +4 -0
  107. package/templates/blog/eslint.config.mjs +12 -0
  108. package/templates/blog/eslint.tailwind.mjs +33 -0
  109. package/templates/blog/ginko.config.ts +59 -0
  110. package/templates/blog/gitignore +7 -0
  111. package/templates/blog/i18n/blog/de.json +18 -0
  112. package/templates/blog/i18n/blog/en.json +18 -0
  113. package/templates/blog/i18n/de.json +31 -0
  114. package/templates/blog/i18n/en.json +27 -0
  115. package/templates/blog/i18n/people/de.json +6 -0
  116. package/templates/blog/i18n/people/en.json +6 -0
  117. package/templates/blog/i18n/site/de.json +39 -0
  118. package/templates/blog/i18n/site/en.json +39 -0
  119. package/templates/blog/modules/feature-messages.ts +19 -0
  120. package/templates/blog/modules/feeds/index.ts +22 -0
  121. package/templates/blog/modules/feeds/routes.ts +13 -0
  122. package/templates/blog/modules/page-paths/index.ts +26 -0
  123. package/templates/blog/modules/page-paths/paths.ts +48 -0
  124. package/templates/blog/nuxt.config.ts +27 -0
  125. package/templates/blog/package.json +57 -0
  126. package/templates/blog/pnpm-workspace.yaml +6 -0
  127. package/templates/blog/public/media/forest-path.jpg +0 -0
  128. package/templates/blog/public/media/notebook.jpg +0 -0
  129. package/templates/blog/server/middleware/news-feed.ts +37 -0
  130. package/templates/blog/server/plugins/font-preload.ts +17 -0
  131. package/templates/blog/site-url.ts +21 -0
  132. package/templates/blog/tsconfig.json +9 -0
  133. package/templates/blog.json +11 -0
  134. package/templates/company/.env.example +8 -0
  135. package/templates/company/.github/screenshots/home-dark.png +0 -0
  136. package/templates/company/.github/screenshots/home-light.png +0 -0
  137. package/templates/company/.github/workflows/ci.yml +27 -0
  138. package/templates/company/DESIGN.md +197 -0
  139. package/templates/company/LICENSE +21 -0
  140. package/templates/company/MEDIA.md +32 -0
  141. package/templates/company/NOTES.md +19 -0
  142. package/templates/company/README.md +254 -0
  143. package/templates/company/app/app.config.ts +33 -0
  144. package/templates/company/app/app.vue +7 -0
  145. package/templates/company/app/assets/css/main.css +22 -0
  146. package/templates/company/app/assets/css/tokens.css +400 -0
  147. package/templates/company/app/bricks/logos-quotes.ts +47 -0
  148. package/templates/company/app/bricks/pages.ts +38 -0
  149. package/templates/company/app/bricks/services.ts +64 -0
  150. package/templates/company/app/components/InitialsAvatar.vue +18 -0
  151. package/templates/company/app/components/ProseBody.vue +13 -0
  152. package/templates/company/app/components/ServiceLine.vue +15 -0
  153. package/templates/company/app/components/block/Cards.vue +54 -0
  154. package/templates/company/app/components/block/Cta.vue +26 -0
  155. package/templates/company/app/components/block/Empty.vue +26 -0
  156. package/templates/company/app/components/block/Features.vue +24 -0
  157. package/templates/company/app/components/block/Hero.vue +47 -0
  158. package/templates/company/app/components/block/Logos.vue +22 -0
  159. package/templates/company/app/components/block/PageHeader.vue +21 -0
  160. package/templates/company/app/components/block/Quote.vue +19 -0
  161. package/templates/company/app/components/block/Section.vue +31 -0
  162. package/templates/company/app/components/blog/Byline.vue +22 -0
  163. package/templates/company/app/components/blog/PostList.vue +33 -0
  164. package/templates/company/app/components/blog/TagList.vue +17 -0
  165. package/templates/company/app/components/downloads/FileButton.vue +21 -0
  166. package/templates/company/app/components/downloads/List.vue +37 -0
  167. package/templates/company/app/components/event/Upcoming.vue +25 -0
  168. package/templates/company/app/components/jobs/List.vue +26 -0
  169. package/templates/company/app/components/people/List.vue +41 -0
  170. package/templates/company/app/components/people/TeamContact.vue +37 -0
  171. package/templates/company/app/components/site/Contact.vue +38 -0
  172. package/templates/company/app/components/site/Footer.vue +81 -0
  173. package/templates/company/app/components/site/Header.vue +52 -0
  174. package/templates/company/app/components/site/LanguageSwitch.vue +34 -0
  175. package/templates/company/app/components/site/Logo.vue +17 -0
  176. package/templates/company/app/components/site/NavLink.vue +19 -0
  177. package/templates/company/app/components/site/NavSheet.vue +63 -0
  178. package/templates/company/app/components/site/Notice.vue +21 -0
  179. package/templates/company/app/components/site/SkipLink.vue +15 -0
  180. package/templates/company/app/components/site/ThemeToggle.vue +28 -0
  181. package/templates/company/app/components/ui/button/Button.vue +30 -0
  182. package/templates/company/app/components/ui/button/index.ts +44 -0
  183. package/templates/company/app/components/ui/sheet/Sheet.vue +16 -0
  184. package/templates/company/app/components/ui/sheet/SheetClose.vue +13 -0
  185. package/templates/company/app/components/ui/sheet/SheetContent.vue +54 -0
  186. package/templates/company/app/components/ui/sheet/SheetDescription.vue +23 -0
  187. package/templates/company/app/components/ui/sheet/SheetOverlay.vue +22 -0
  188. package/templates/company/app/components/ui/sheet/SheetTitle.vue +23 -0
  189. package/templates/company/app/components/ui/sheet/SheetTrigger.vue +13 -0
  190. package/templates/company/app/components/ui/sheet/index.ts +7 -0
  191. package/templates/company/app/composables/useBlog.ts +103 -0
  192. package/templates/company/app/composables/useDownloads.ts +54 -0
  193. package/templates/company/app/composables/useEvents.ts +182 -0
  194. package/templates/company/app/composables/useJobs.ts +108 -0
  195. package/templates/company/app/composables/usePageSeo.ts +50 -0
  196. package/templates/company/app/composables/useServiceLine.ts +10 -0
  197. package/templates/company/app/composables/useServices.ts +93 -0
  198. package/templates/company/app/composables/useSiteAppConfig.ts +79 -0
  199. package/templates/company/app/error.vue +35 -0
  200. package/templates/company/app/layouts/default.vue +23 -0
  201. package/templates/company/app/lib/utils.ts +26 -0
  202. package/templates/company/app/pages/[...slug].vue +36 -0
  203. package/templates/company/app/pages/downloads.vue +20 -0
  204. package/templates/company/app/pages/events/[slug].vue +106 -0
  205. package/templates/company/app/pages/events/index.vue +20 -0
  206. package/templates/company/app/pages/index.vue +84 -0
  207. package/templates/company/app/pages/jobs/[slug].vue +63 -0
  208. package/templates/company/app/pages/jobs/index.vue +36 -0
  209. package/templates/company/app/pages/legal/[slug].vue +46 -0
  210. package/templates/company/app/pages/news/[slug].vue +94 -0
  211. package/templates/company/app/pages/news/index.vue +54 -0
  212. package/templates/company/app/pages/news/tags/[tag].vue +41 -0
  213. package/templates/company/app/pages/services/[slug].vue +90 -0
  214. package/templates/company/app/pages/services/index.vue +18 -0
  215. package/templates/company/app/pages/team.vue +40 -0
  216. package/templates/company/app/routes.ts +33 -0
  217. package/templates/company/app/utils/telHref.ts +3 -0
  218. package/templates/company/components.json +21 -0
  219. package/templates/company/content/downloads/hk-centrifugal-pumps.de.md +4 -0
  220. package/templates/company/content/downloads/hk-centrifugal-pumps.md +7 -0
  221. package/templates/company/content/downloads/pumping-stations.de.md +4 -0
  222. package/templates/company/content/downloads/pumping-stations.md +7 -0
  223. package/templates/company/content/downloads/ts-submersible-pumps.de.md +4 -0
  224. package/templates/company/content/downloads/ts-submersible-pumps.md +7 -0
  225. package/templates/company/content/events/1.municipal-water-forum.de.md +9 -0
  226. package/templates/company/content/events/1.municipal-water-forum.md +14 -0
  227. package/templates/company/content/events/2.pump-days-north.de.md +7 -0
  228. package/templates/company/content/events/2.pump-days-north.md +12 -0
  229. package/templates/company/content/events/3.industrial-water-expo.de.md +7 -0
  230. package/templates/company/content/events/3.industrial-water-expo.md +12 -0
  231. package/templates/company/content/home.de.md +6 -0
  232. package/templates/company/content/home.md +7 -0
  233. package/templates/company/content/jobs/apprenticeship-industrial-mechanic.de.md +22 -0
  234. package/templates/company/content/jobs/apprenticeship-industrial-mechanic.md +26 -0
  235. package/templates/company/content/jobs/sales-engineer.de.md +25 -0
  236. package/templates/company/content/jobs/sales-engineer.md +29 -0
  237. package/templates/company/content/jobs/service-technician.de.md +25 -0
  238. package/templates/company/content/jobs/service-technician.md +29 -0
  239. package/templates/company/content/jobs/summer-internship-assembly.de.md +8 -0
  240. package/templates/company/content/jobs/summer-internship-assembly.md +14 -0
  241. package/templates/company/content/legal/1.privacy.de.md +18 -0
  242. package/templates/company/content/legal/1.privacy.md +20 -0
  243. package/templates/company/content/legal/2.terms.de.md +19 -0
  244. package/templates/company/content/legal/2.terms.md +21 -0
  245. package/templates/company/content/legal/3.imprint.de.md +16 -0
  246. package/templates/company/content/legal/3.imprint.md +18 -0
  247. package/templates/company/content/logos/1.public-works.md +6 -0
  248. package/templates/company/content/logos/2.water-board.md +6 -0
  249. package/templates/company/content/logos/3.brewery.md +6 -0
  250. package/templates/company/content/logos/4.treatment-works.md +6 -0
  251. package/templates/company/content/notices/1.municipal-water-forum.de.md +3 -0
  252. package/templates/company/content/notices/1.municipal-water-forum.md +4 -0
  253. package/templates/company/content/pages/1.about.de.md +19 -0
  254. package/templates/company/content/pages/1.about.md +20 -0
  255. package/templates/company/content/people/1.katrin-albers.de.md +4 -0
  256. package/templates/company/content/people/1.katrin-albers.md +7 -0
  257. package/templates/company/content/people/2.tobias-brandt.de.md +4 -0
  258. package/templates/company/content/people/2.tobias-brandt.md +7 -0
  259. package/templates/company/content/people/3.miriam-ostendorf.de.md +4 -0
  260. package/templates/company/content/people/3.miriam-ostendorf.md +7 -0
  261. package/templates/company/content/people/4.sabine-krueger.de.md +4 -0
  262. package/templates/company/content/people/4.sabine-krueger.md +7 -0
  263. package/templates/company/content/posts/apprentices-start.de.md +12 -0
  264. package/templates/company/content/posts/apprentices-start.md +14 -0
  265. package/templates/company/content/posts/saturday-service.de.md +12 -0
  266. package/templates/company/content/posts/saturday-service.md +14 -0
  267. package/templates/company/content/posts/treatment-works-pumps.de.md +20 -0
  268. package/templates/company/content/posts/treatment-works-pumps.md +23 -0
  269. package/templates/company/content/posts/ts-pumps-atex.de.md +12 -0
  270. package/templates/company/content/posts/ts-pumps-atex.md +14 -0
  271. package/templates/company/content/quotes/1.public-works.de.md +4 -0
  272. package/templates/company/content/quotes/1.public-works.md +5 -0
  273. package/templates/company/content/quotes/2.brewery.de.md +4 -0
  274. package/templates/company/content/quotes/2.brewery.md +5 -0
  275. package/templates/company/content/serviceLine.de.md +3 -0
  276. package/templates/company/content/serviceLine.md +5 -0
  277. package/templates/company/content/services/1.hk-centrifugal-pumps.de.md +31 -0
  278. package/templates/company/content/services/1.hk-centrifugal-pumps.md +35 -0
  279. package/templates/company/content/services/2.ts-submersible-pumps.de.md +26 -0
  280. package/templates/company/content/services/2.ts-submersible-pumps.md +30 -0
  281. package/templates/company/content/services/3.pumping-stations.de.md +29 -0
  282. package/templates/company/content/services/3.pumping-stations.md +33 -0
  283. package/templates/company/content/services/4.pump-check.de.md +25 -0
  284. package/templates/company/content/services/4.pump-check.md +30 -0
  285. package/templates/company/content/services/5.repair-and-overhaul.de.md +20 -0
  286. package/templates/company/content/services/5.repair-and-overhaul.md +23 -0
  287. package/templates/company/content/site.de.md +3 -0
  288. package/templates/company/content/site.md +12 -0
  289. package/templates/company/eslint.config.mjs +12 -0
  290. package/templates/company/eslint.tailwind.mjs +33 -0
  291. package/templates/company/ginko.config.ts +98 -0
  292. package/templates/company/gitignore +7 -0
  293. package/templates/company/i18n/blog/de.json +18 -0
  294. package/templates/company/i18n/blog/en.json +18 -0
  295. package/templates/company/i18n/de.json +60 -0
  296. package/templates/company/i18n/downloads/de.json +6 -0
  297. package/templates/company/i18n/downloads/en.json +6 -0
  298. package/templates/company/i18n/en.json +58 -0
  299. package/templates/company/i18n/events/de.json +20 -0
  300. package/templates/company/i18n/events/en.json +20 -0
  301. package/templates/company/i18n/jobs/de.json +35 -0
  302. package/templates/company/i18n/jobs/en.json +35 -0
  303. package/templates/company/i18n/people/de.json +6 -0
  304. package/templates/company/i18n/people/en.json +6 -0
  305. package/templates/company/i18n/services/de.json +20 -0
  306. package/templates/company/i18n/services/en.json +20 -0
  307. package/templates/company/i18n/site/de.json +39 -0
  308. package/templates/company/i18n/site/en.json +39 -0
  309. package/templates/company/modules/feature-messages.ts +19 -0
  310. package/templates/company/modules/feeds/index.ts +22 -0
  311. package/templates/company/modules/feeds/routes.ts +13 -0
  312. package/templates/company/modules/page-paths/index.ts +26 -0
  313. package/templates/company/modules/page-paths/paths.ts +48 -0
  314. package/templates/company/nuxt.config.ts +29 -0
  315. package/templates/company/package.json +64 -0
  316. package/templates/company/pnpm-workspace.yaml +6 -0
  317. package/templates/company/public/logos/customer-four.svg +6 -0
  318. package/templates/company/public/logos/customer-one.svg +5 -0
  319. package/templates/company/public/logos/customer-three.svg +5 -0
  320. package/templates/company/public/logos/customer-two.svg +4 -0
  321. package/templates/company/public/media/pipework.jpg +0 -0
  322. package/templates/company/public/media/process-pumps.jpg +0 -0
  323. package/templates/company/public/media/pump-check.jpg +0 -0
  324. package/templates/company/public/media/treatment-works.jpg +0 -0
  325. package/templates/company/public/media/works-hall.jpg +0 -0
  326. package/templates/company/public/sheets/hk-centrifugal-pumps.pdf +0 -0
  327. package/templates/company/public/sheets/pumping-stations.pdf +0 -0
  328. package/templates/company/public/sheets/ts-submersible-pumps.pdf +0 -0
  329. package/templates/company/server/middleware/news-feed.ts +37 -0
  330. package/templates/company/server/plugins/font-preload.ts +17 -0
  331. package/templates/company/site-url.ts +21 -0
  332. package/templates/company/tsconfig.json +9 -0
  333. package/templates/company.json +18 -0
  334. package/templates/docs/.env.example +9 -0
  335. package/templates/docs/.github/screenshots/home-light.png +0 -0
  336. package/templates/docs/.github/screenshots/page-dark.png +0 -0
  337. package/templates/docs/.github/workflows/ci.yml +27 -0
  338. package/templates/docs/DESIGN.md +77 -0
  339. package/templates/docs/LICENSE +21 -0
  340. package/templates/docs/MEDIA.md +14 -0
  341. package/templates/docs/NOTES.md +18 -0
  342. package/templates/docs/README.md +255 -0
  343. package/templates/docs/app/app.config.ts +26 -0
  344. package/templates/docs/app/assets/css/main.css +14 -0
  345. package/templates/docs/content/changelog/v1-6-0.de.md +13 -0
  346. package/templates/docs/content/changelog/v1-6-0.md +18 -0
  347. package/templates/docs/content/changelog/v2-0-0.de.md +14 -0
  348. package/templates/docs/content/changelog/v2-0-0.md +19 -0
  349. package/templates/docs/content/changelog/v2-1-0.de.md +9 -0
  350. package/templates/docs/content/changelog/v2-1-0.md +14 -0
  351. package/templates/docs/content/docs/1.introduction.de.md +32 -0
  352. package/templates/docs/content/docs/1.introduction.md +31 -0
  353. package/templates/docs/content/docs/10.incidents-and-checks.de.md +82 -0
  354. package/templates/docs/content/docs/10.incidents-and-checks.md +81 -0
  355. package/templates/docs/content/docs/11.error-codes.de.md +36 -0
  356. package/templates/docs/content/docs/11.error-codes.md +35 -0
  357. package/templates/docs/content/docs/2.getting-started.de.md +57 -0
  358. package/templates/docs/content/docs/2.getting-started.md +56 -0
  359. package/templates/docs/content/docs/3.authentication.de.md +55 -0
  360. package/templates/docs/content/docs/3.authentication.md +54 -0
  361. package/templates/docs/content/docs/4.pagination.de.md +45 -0
  362. package/templates/docs/content/docs/4.pagination.md +44 -0
  363. package/templates/docs/content/docs/5.errors-and-retries.de.md +69 -0
  364. package/templates/docs/content/docs/5.errors-and-retries.md +66 -0
  365. package/templates/docs/content/docs/6.webhooks.de.md +53 -0
  366. package/templates/docs/content/docs/6.webhooks.md +52 -0
  367. package/templates/docs/content/docs/7.upgrading-to-v2.md +73 -0
  368. package/templates/docs/content/docs/8.client.de.md +57 -0
  369. package/templates/docs/content/docs/8.client.md +56 -0
  370. package/templates/docs/content/docs/9.monitors.de.md +96 -0
  371. package/templates/docs/content/docs/9.monitors.md +95 -0
  372. package/templates/docs/content/home.de.md +47 -0
  373. package/templates/docs/content/home.md +54 -0
  374. package/templates/docs/eslint.config.mjs +7 -0
  375. package/templates/docs/ginko.config.ts +36 -0
  376. package/templates/docs/gitignore +7 -0
  377. package/templates/docs/i18n/de.json +5 -0
  378. package/templates/docs/i18n/en.json +5 -0
  379. package/templates/docs/nuxt.config.ts +18 -0
  380. package/templates/docs/package.json +42 -0
  381. package/templates/docs/pnpm-workspace.yaml +6 -0
  382. package/templates/docs/public/favicon.svg +1 -0
  383. package/templates/docs/public/logo-dark.svg +1 -0
  384. package/templates/docs/public/logo.svg +1 -0
  385. package/templates/docs/site-url.ts +21 -0
  386. package/templates/docs/tsconfig.json +9 -0
  387. package/templates/docs.json +7 -0
  388. package/templates/events/.env.example +8 -0
  389. package/templates/events/.github/screenshots/home-dark.png +0 -0
  390. package/templates/events/.github/screenshots/home-light.png +0 -0
  391. package/templates/events/.github/workflows/ci.yml +27 -0
  392. package/templates/events/DESIGN.md +197 -0
  393. package/templates/events/LICENSE +21 -0
  394. package/templates/events/MEDIA.md +32 -0
  395. package/templates/events/NOTES.md +13 -0
  396. package/templates/events/README.md +247 -0
  397. package/templates/events/app/app.config.ts +30 -0
  398. package/templates/events/app/app.vue +7 -0
  399. package/templates/events/app/assets/css/main.css +22 -0
  400. package/templates/events/app/assets/css/tokens.css +400 -0
  401. package/templates/events/app/bricks/logos-quotes.ts +47 -0
  402. package/templates/events/app/bricks/pages.ts +38 -0
  403. package/templates/events/app/components/InitialsAvatar.vue +18 -0
  404. package/templates/events/app/components/ProseBody.vue +13 -0
  405. package/templates/events/app/components/block/Cards.vue +54 -0
  406. package/templates/events/app/components/block/Cta.vue +26 -0
  407. package/templates/events/app/components/block/Empty.vue +26 -0
  408. package/templates/events/app/components/block/Faq.vue +19 -0
  409. package/templates/events/app/components/block/Features.vue +24 -0
  410. package/templates/events/app/components/block/Gallery.vue +81 -0
  411. package/templates/events/app/components/block/Hero.vue +47 -0
  412. package/templates/events/app/components/block/Logos.vue +22 -0
  413. package/templates/events/app/components/block/PageHeader.vue +21 -0
  414. package/templates/events/app/components/block/Quote.vue +19 -0
  415. package/templates/events/app/components/block/Section.vue +31 -0
  416. package/templates/events/app/components/event/Programme.vue +16 -0
  417. package/templates/events/app/components/event/Upcoming.vue +25 -0
  418. package/templates/events/app/components/pages/Top.vue +11 -0
  419. package/templates/events/app/components/session/NowNext.vue +54 -0
  420. package/templates/events/app/components/session/Programme.vue +40 -0
  421. package/templates/events/app/components/session/Row.vue +61 -0
  422. package/templates/events/app/components/session/Speakers.vue +28 -0
  423. package/templates/events/app/components/site/Contact.vue +38 -0
  424. package/templates/events/app/components/site/Footer.vue +81 -0
  425. package/templates/events/app/components/site/Header.vue +52 -0
  426. package/templates/events/app/components/site/LanguageSwitch.vue +34 -0
  427. package/templates/events/app/components/site/Lightbox.vue +62 -0
  428. package/templates/events/app/components/site/Logo.vue +17 -0
  429. package/templates/events/app/components/site/NavLink.vue +19 -0
  430. package/templates/events/app/components/site/NavSheet.vue +63 -0
  431. package/templates/events/app/components/site/Notice.vue +21 -0
  432. package/templates/events/app/components/site/SkipLink.vue +15 -0
  433. package/templates/events/app/components/site/ThemeToggle.vue +28 -0
  434. package/templates/events/app/components/ui/accordion/Accordion.vue +16 -0
  435. package/templates/events/app/components/ui/accordion/AccordionContent.vue +26 -0
  436. package/templates/events/app/components/ui/accordion/AccordionItem.vue +24 -0
  437. package/templates/events/app/components/ui/accordion/AccordionTrigger.vue +35 -0
  438. package/templates/events/app/components/ui/accordion/index.ts +5 -0
  439. package/templates/events/app/components/ui/button/Button.vue +30 -0
  440. package/templates/events/app/components/ui/button/index.ts +44 -0
  441. package/templates/events/app/components/ui/sheet/Sheet.vue +16 -0
  442. package/templates/events/app/components/ui/sheet/SheetClose.vue +13 -0
  443. package/templates/events/app/components/ui/sheet/SheetContent.vue +54 -0
  444. package/templates/events/app/components/ui/sheet/SheetDescription.vue +23 -0
  445. package/templates/events/app/components/ui/sheet/SheetOverlay.vue +22 -0
  446. package/templates/events/app/components/ui/sheet/SheetTitle.vue +23 -0
  447. package/templates/events/app/components/ui/sheet/SheetTrigger.vue +13 -0
  448. package/templates/events/app/components/ui/sheet/index.ts +7 -0
  449. package/templates/events/app/composables/useEvents.ts +182 -0
  450. package/templates/events/app/composables/usePageSeo.ts +50 -0
  451. package/templates/events/app/composables/useSessions.ts +111 -0
  452. package/templates/events/app/composables/useSiteAppConfig.ts +79 -0
  453. package/templates/events/app/error.vue +35 -0
  454. package/templates/events/app/layouts/default.vue +23 -0
  455. package/templates/events/app/lib/utils.ts +26 -0
  456. package/templates/events/app/pages/[...slug].vue +36 -0
  457. package/templates/events/app/pages/events/[slug].vue +106 -0
  458. package/templates/events/app/pages/events/index.vue +20 -0
  459. package/templates/events/app/pages/faq.vue +39 -0
  460. package/templates/events/app/pages/index.vue +134 -0
  461. package/templates/events/app/pages/legal/[slug].vue +46 -0
  462. package/templates/events/app/pages/programme.vue +42 -0
  463. package/templates/events/app/pages/speakers/[slug].vue +62 -0
  464. package/templates/events/app/pages/speakers/index.vue +31 -0
  465. package/templates/events/app/routes.ts +31 -0
  466. package/templates/events/app/utils/sessions.ts +64 -0
  467. package/templates/events/app/utils/telHref.ts +3 -0
  468. package/templates/events/components.json +21 -0
  469. package/templates/events/content/events/1.open-data-days.de.md +9 -0
  470. package/templates/events/content/events/1.open-data-days.md +19 -0
  471. package/templates/events/content/events/2.open-data-meetup.de.md +7 -0
  472. package/templates/events/content/events/2.open-data-meetup.md +14 -0
  473. package/templates/events/content/events/3.last-edition.de.md +5 -0
  474. package/templates/events/content/events/3.last-edition.md +12 -0
  475. package/templates/events/content/events/4.next-edition.de.md +5 -0
  476. package/templates/events/content/events/4.next-edition.md +13 -0
  477. package/templates/events/content/faq/1.getting-there.de.md +4 -0
  478. package/templates/events/content/faq/1.getting-there.md +4 -0
  479. package/templates/events/content/faq/2.accessibility.de.md +4 -0
  480. package/templates/events/content/faq/2.accessibility.md +4 -0
  481. package/templates/events/content/faq/3.tickets.de.md +4 -0
  482. package/templates/events/content/faq/3.tickets.md +4 -0
  483. package/templates/events/content/faq/4.food.de.md +4 -0
  484. package/templates/events/content/faq/4.food.md +4 -0
  485. package/templates/events/content/faq/5.code-of-conduct.de.md +4 -0
  486. package/templates/events/content/faq/5.code-of-conduct.md +4 -0
  487. package/templates/events/content/faq/6.language.de.md +4 -0
  488. package/templates/events/content/faq/6.language.md +4 -0
  489. package/templates/events/content/faq/7.recordings.de.md +4 -0
  490. package/templates/events/content/faq/7.recordings.md +4 -0
  491. package/templates/events/content/faq/8.ticket-transfer.de.md +4 -0
  492. package/templates/events/content/faq/8.ticket-transfer.md +4 -0
  493. package/templates/events/content/gallery.de.md +9 -0
  494. package/templates/events/content/gallery.md +12 -0
  495. package/templates/events/content/home.de.md +6 -0
  496. package/templates/events/content/home.md +7 -0
  497. package/templates/events/content/legal/1.privacy.de.md +19 -0
  498. package/templates/events/content/legal/1.privacy.md +20 -0
  499. package/templates/events/content/legal/2.terms.de.md +19 -0
  500. package/templates/events/content/legal/2.terms.md +20 -0
  501. package/templates/events/content/legal/3.imprint.de.md +19 -0
  502. package/templates/events/content/legal/3.imprint.md +20 -0
  503. package/templates/events/content/logos/1.kaltenegger-it.md +6 -0
  504. package/templates/events/content/logos/2.nordlicht-hosting.md +6 -0
  505. package/templates/events/content/logos/3.hallgarten-stiftung.md +6 -0
  506. package/templates/events/content/logos/4.kanalcafe.md +6 -0
  507. package/templates/events/content/notices/1.ticket-sales.de.md +3 -0
  508. package/templates/events/content/notices/1.ticket-sales.md +4 -0
  509. package/templates/events/content/pages/1.venue.de.md +36 -0
  510. package/templates/events/content/pages/1.venue.md +37 -0
  511. package/templates/events/content/pages/2.code-of-conduct.de.md +25 -0
  512. package/templates/events/content/pages/2.code-of-conduct.md +25 -0
  513. package/templates/events/content/pages/3.sponsoring.de.md +17 -0
  514. package/templates/events/content/pages/3.sponsoring.md +17 -0
  515. package/templates/events/content/people/1.lena-hofer.de.md +4 -0
  516. package/templates/events/content/people/1.lena-hofer.md +6 -0
  517. package/templates/events/content/people/2.tobias-wagner.de.md +4 -0
  518. package/templates/events/content/people/2.tobias-wagner.md +6 -0
  519. package/templates/events/content/people/3.amira-haddad.de.md +4 -0
  520. package/templates/events/content/people/3.amira-haddad.md +6 -0
  521. package/templates/events/content/people/4.jonas-leitner.de.md +4 -0
  522. package/templates/events/content/people/4.jonas-leitner.md +6 -0
  523. package/templates/events/content/people/5.sophie-brunner.de.md +4 -0
  524. package/templates/events/content/people/5.sophie-brunner.md +6 -0
  525. package/templates/events/content/people/6.david-okafor.de.md +4 -0
  526. package/templates/events/content/people/6.david-okafor.md +6 -0
  527. package/templates/events/content/people/7.katrin-moser.de.md +4 -0
  528. package/templates/events/content/people/7.katrin-moser.md +6 -0
  529. package/templates/events/content/people/8.nina-pichler.de.md +4 -0
  530. package/templates/events/content/people/8.nina-pichler.md +6 -0
  531. package/templates/events/content/people/9.felix-gruber.de.md +3 -0
  532. package/templates/events/content/people/9.felix-gruber.md +5 -0
  533. package/templates/events/content/sessions/balcony-sensors.de.md +4 -0
  534. package/templates/events/content/sessions/balcony-sensors.md +10 -0
  535. package/templates/events/content/sessions/budget-stories.de.md +4 -0
  536. package/templates/events/content/sessions/budget-stories.md +11 -0
  537. package/templates/events/content/sessions/closing.de.md +4 -0
  538. package/templates/events/content/sessions/closing.md +11 -0
  539. package/templates/events/content/sessions/doors-open.de.md +3 -0
  540. package/templates/events/content/sessions/doors-open.md +9 -0
  541. package/templates/events/content/sessions/honest-charts.de.md +4 -0
  542. package/templates/events/content/sessions/honest-charts.md +11 -0
  543. package/templates/events/content/sessions/keynote-city.de.md +4 -0
  544. package/templates/events/content/sessions/keynote-city.md +11 -0
  545. package/templates/events/content/sessions/lightning-talks.de.md +4 -0
  546. package/templates/events/content/sessions/lightning-talks.md +10 -0
  547. package/templates/events/content/sessions/lunch-1.de.md +3 -0
  548. package/templates/events/content/sessions/lunch-1.md +9 -0
  549. package/templates/events/content/sessions/lunch-2.de.md +3 -0
  550. package/templates/events/content/sessions/lunch-2.md +9 -0
  551. package/templates/events/content/sessions/next-edition-keynote.de.md +3 -0
  552. package/templates/events/content/sessions/next-edition-keynote.md +9 -0
  553. package/templates/events/content/sessions/open-data-schools.de.md +4 -0
  554. package/templates/events/content/sessions/open-data-schools.md +11 -0
  555. package/templates/events/content/sessions/open-statistics.de.md +4 -0
  556. package/templates/events/content/sessions/open-statistics.md +11 -0
  557. package/templates/events/content/sessions/panel-who-pays.de.md +4 -0
  558. package/templates/events/content/sessions/panel-who-pays.md +11 -0
  559. package/templates/events/content/sessions/privacy-line.de.md +4 -0
  560. package/templates/events/content/sessions/privacy-line.md +11 -0
  561. package/templates/events/content/sessions/readable-metadata.de.md +4 -0
  562. package/templates/events/content/sessions/readable-metadata.md +11 -0
  563. package/templates/events/content/sessions/transport-data.de.md +4 -0
  564. package/templates/events/content/sessions/transport-data.md +11 -0
  565. package/templates/events/content/sessions/welcome.de.md +3 -0
  566. package/templates/events/content/sessions/welcome.md +10 -0
  567. package/templates/events/content/sessions/workshop-charts.de.md +4 -0
  568. package/templates/events/content/sessions/workshop-charts.md +11 -0
  569. package/templates/events/content/sessions/workshop-clean-data.de.md +4 -0
  570. package/templates/events/content/sessions/workshop-clean-data.md +11 -0
  571. package/templates/events/content/sessions/workshop-portal.de.md +4 -0
  572. package/templates/events/content/sessions/workshop-portal.md +11 -0
  573. package/templates/events/content/site.md +10 -0
  574. package/templates/events/eslint.config.mjs +12 -0
  575. package/templates/events/eslint.tailwind.mjs +33 -0
  576. package/templates/events/ginko.config.ts +75 -0
  577. package/templates/events/gitignore +7 -0
  578. package/templates/events/i18n/de.json +37 -0
  579. package/templates/events/i18n/en.json +37 -0
  580. package/templates/events/i18n/events/de.json +20 -0
  581. package/templates/events/i18n/events/en.json +20 -0
  582. package/templates/events/i18n/faq/de.json +6 -0
  583. package/templates/events/i18n/faq/en.json +6 -0
  584. package/templates/events/i18n/gallery/de.json +8 -0
  585. package/templates/events/i18n/gallery/en.json +8 -0
  586. package/templates/events/i18n/sessions/de.json +33 -0
  587. package/templates/events/i18n/sessions/en.json +33 -0
  588. package/templates/events/i18n/site/de.json +39 -0
  589. package/templates/events/i18n/site/en.json +39 -0
  590. package/templates/events/modules/feature-messages.ts +19 -0
  591. package/templates/events/modules/feeds/index.ts +22 -0
  592. package/templates/events/modules/feeds/routes.ts +13 -0
  593. package/templates/events/modules/page-paths/index.ts +26 -0
  594. package/templates/events/modules/page-paths/paths.ts +48 -0
  595. package/templates/events/nuxt.config.ts +27 -0
  596. package/templates/events/package.json +61 -0
  597. package/templates/events/pnpm-workspace.yaml +6 -0
  598. package/templates/events/public/logos/hallgarten-stiftung.svg +4 -0
  599. package/templates/events/public/logos/kaltenegger-it.svg +4 -0
  600. package/templates/events/public/logos/kanalcafe.svg +4 -0
  601. package/templates/events/public/logos/nordlicht-hosting.svg +4 -0
  602. package/templates/events/public/media/coffee-break.jpg +0 -0
  603. package/templates/events/public/media/hero.jpg +0 -0
  604. package/templates/events/public/media/talk.jpg +0 -0
  605. package/templates/events/public/media/venue.jpg +0 -0
  606. package/templates/events/public/media/workshop-tables.jpg +0 -0
  607. package/templates/events/server/plugins/font-preload.ts +17 -0
  608. package/templates/events/site-url.ts +21 -0
  609. package/templates/events/tsconfig.json +9 -0
  610. package/templates/events.json +18 -0
  611. package/templates/local-business/.env.example +8 -0
  612. package/templates/local-business/.github/screenshots/home-dark.png +0 -0
  613. package/templates/local-business/.github/screenshots/home-light.png +0 -0
  614. package/templates/local-business/.github/workflows/ci.yml +27 -0
  615. package/templates/local-business/DESIGN.md +197 -0
  616. package/templates/local-business/LICENSE +21 -0
  617. package/templates/local-business/MEDIA.md +27 -0
  618. package/templates/local-business/NOTES.md +31 -0
  619. package/templates/local-business/README.md +256 -0
  620. package/templates/local-business/app/app.config.ts +32 -0
  621. package/templates/local-business/app/app.vue +7 -0
  622. package/templates/local-business/app/assets/css/main.css +18 -0
  623. package/templates/local-business/app/assets/css/tokens.css +400 -0
  624. package/templates/local-business/app/bricks/pages.ts +38 -0
  625. package/templates/local-business/app/bricks/services.ts +64 -0
  626. package/templates/local-business/app/components/InitialsAvatar.vue +18 -0
  627. package/templates/local-business/app/components/ProseBody.vue +13 -0
  628. package/templates/local-business/app/components/block/Cards.vue +54 -0
  629. package/templates/local-business/app/components/block/Cta.vue +26 -0
  630. package/templates/local-business/app/components/block/Empty.vue +26 -0
  631. package/templates/local-business/app/components/block/Faq.vue +19 -0
  632. package/templates/local-business/app/components/block/Features.vue +24 -0
  633. package/templates/local-business/app/components/block/Gallery.vue +81 -0
  634. package/templates/local-business/app/components/block/Hero.vue +47 -0
  635. package/templates/local-business/app/components/block/PageHeader.vue +21 -0
  636. package/templates/local-business/app/components/block/Section.vue +31 -0
  637. package/templates/local-business/app/components/hours/Table.vue +119 -0
  638. package/templates/local-business/app/components/hours/Today.vue +55 -0
  639. package/templates/local-business/app/components/people/List.vue +41 -0
  640. package/templates/local-business/app/components/services/Actions.vue +18 -0
  641. package/templates/local-business/app/components/site/Contact.vue +38 -0
  642. package/templates/local-business/app/components/site/Footer.vue +81 -0
  643. package/templates/local-business/app/components/site/FooterStatus.vue +9 -0
  644. package/templates/local-business/app/components/site/Header.vue +52 -0
  645. package/templates/local-business/app/components/site/LanguageSwitch.vue +34 -0
  646. package/templates/local-business/app/components/site/Lightbox.vue +62 -0
  647. package/templates/local-business/app/components/site/Logo.vue +17 -0
  648. package/templates/local-business/app/components/site/NavLink.vue +19 -0
  649. package/templates/local-business/app/components/site/NavSheet.vue +63 -0
  650. package/templates/local-business/app/components/site/Notice.vue +21 -0
  651. package/templates/local-business/app/components/site/SkipLink.vue +15 -0
  652. package/templates/local-business/app/components/site/ThemeToggle.vue +28 -0
  653. package/templates/local-business/app/components/ui/accordion/Accordion.vue +16 -0
  654. package/templates/local-business/app/components/ui/accordion/AccordionContent.vue +26 -0
  655. package/templates/local-business/app/components/ui/accordion/AccordionItem.vue +24 -0
  656. package/templates/local-business/app/components/ui/accordion/AccordionTrigger.vue +35 -0
  657. package/templates/local-business/app/components/ui/accordion/index.ts +5 -0
  658. package/templates/local-business/app/components/ui/button/Button.vue +30 -0
  659. package/templates/local-business/app/components/ui/button/index.ts +44 -0
  660. package/templates/local-business/app/components/ui/sheet/Sheet.vue +16 -0
  661. package/templates/local-business/app/components/ui/sheet/SheetClose.vue +13 -0
  662. package/templates/local-business/app/components/ui/sheet/SheetContent.vue +54 -0
  663. package/templates/local-business/app/components/ui/sheet/SheetDescription.vue +23 -0
  664. package/templates/local-business/app/components/ui/sheet/SheetOverlay.vue +22 -0
  665. package/templates/local-business/app/components/ui/sheet/SheetTitle.vue +23 -0
  666. package/templates/local-business/app/components/ui/sheet/SheetTrigger.vue +13 -0
  667. package/templates/local-business/app/components/ui/sheet/index.ts +7 -0
  668. package/templates/local-business/app/components/visit/Book.vue +46 -0
  669. package/templates/local-business/app/composables/useHours.ts +81 -0
  670. package/templates/local-business/app/composables/usePageSeo.ts +50 -0
  671. package/templates/local-business/app/composables/useServices.ts +93 -0
  672. package/templates/local-business/app/composables/useSiteAppConfig.ts +79 -0
  673. package/templates/local-business/app/composables/useVisit.ts +19 -0
  674. package/templates/local-business/app/error.vue +35 -0
  675. package/templates/local-business/app/layouts/default.vue +23 -0
  676. package/templates/local-business/app/lib/utils.ts +26 -0
  677. package/templates/local-business/app/pages/[...slug].vue +36 -0
  678. package/templates/local-business/app/pages/contact.vue +62 -0
  679. package/templates/local-business/app/pages/faq.vue +39 -0
  680. package/templates/local-business/app/pages/index.vue +114 -0
  681. package/templates/local-business/app/pages/legal/[slug].vue +46 -0
  682. package/templates/local-business/app/pages/services/[slug].vue +90 -0
  683. package/templates/local-business/app/pages/services/index.vue +18 -0
  684. package/templates/local-business/app/pages/team.vue +40 -0
  685. package/templates/local-business/app/routes.ts +31 -0
  686. package/templates/local-business/app/utils/hours.ts +58 -0
  687. package/templates/local-business/app/utils/telHref.ts +3 -0
  688. package/templates/local-business/components.json +21 -0
  689. package/templates/local-business/content/faq/1.prescription.de.md +4 -0
  690. package/templates/local-business/content/faq/1.prescription.md +4 -0
  691. package/templates/local-business/content/faq/2.insurance.de.md +4 -0
  692. package/templates/local-business/content/faq/2.insurance.md +4 -0
  693. package/templates/local-business/content/faq/3.bring.de.md +4 -0
  694. package/templates/local-business/content/faq/3.bring.md +4 -0
  695. package/templates/local-business/content/faq/4.cancel.de.md +4 -0
  696. package/templates/local-business/content/faq/4.cancel.md +4 -0
  697. package/templates/local-business/content/faq/5.sessions.de.md +4 -0
  698. package/templates/local-business/content/faq/5.sessions.md +4 -0
  699. package/templates/local-business/content/faq/6.payment.de.md +4 -0
  700. package/templates/local-business/content/faq/6.payment.md +4 -0
  701. package/templates/local-business/content/gallery.de.md +7 -0
  702. package/templates/local-business/content/gallery.md +9 -0
  703. package/templates/local-business/content/home.de.md +5 -0
  704. package/templates/local-business/content/home.md +7 -0
  705. package/templates/local-business/content/hourPlans/1.summer-hours.de.md +3 -0
  706. package/templates/local-business/content/hourPlans/1.summer-hours.md +31 -0
  707. package/templates/local-business/content/hours.de.md +5 -0
  708. package/templates/local-business/content/hours.md +40 -0
  709. package/templates/local-business/content/legal/1.privacy.de.md +39 -0
  710. package/templates/local-business/content/legal/1.privacy.md +38 -0
  711. package/templates/local-business/content/legal/2.terms.de.md +22 -0
  712. package/templates/local-business/content/legal/2.terms.md +22 -0
  713. package/templates/local-business/content/legal/3.imprint.de.md +17 -0
  714. package/templates/local-business/content/legal/3.imprint.md +17 -0
  715. package/templates/local-business/content/notices/1.courtyard-works.de.md +3 -0
  716. package/templates/local-business/content/notices/1.courtyard-works.md +4 -0
  717. package/templates/local-business/content/pages/1.about.de.md +23 -0
  718. package/templates/local-business/content/pages/1.about.md +24 -0
  719. package/templates/local-business/content/people/1.anna-hofer.de.md +4 -0
  720. package/templates/local-business/content/people/1.anna-hofer.md +5 -0
  721. package/templates/local-business/content/people/2.lukas-brandstaetter.de.md +4 -0
  722. package/templates/local-business/content/people/2.lukas-brandstaetter.md +5 -0
  723. package/templates/local-business/content/people/3.mira-kovac.de.md +4 -0
  724. package/templates/local-business/content/people/3.mira-kovac.md +5 -0
  725. package/templates/local-business/content/people/4.elisabeth-gruber.de.md +4 -0
  726. package/templates/local-business/content/people/4.elisabeth-gruber.md +5 -0
  727. package/templates/local-business/content/services/1.physiotherapy.de.md +22 -0
  728. package/templates/local-business/content/services/1.physiotherapy.md +25 -0
  729. package/templates/local-business/content/services/2.manual-therapy.de.md +11 -0
  730. package/templates/local-business/content/services/2.manual-therapy.md +15 -0
  731. package/templates/local-business/content/services/3.sports-physiotherapy.de.md +18 -0
  732. package/templates/local-business/content/services/3.sports-physiotherapy.md +22 -0
  733. package/templates/local-business/content/services/4.lymphatic-drainage.de.md +18 -0
  734. package/templates/local-business/content/services/4.lymphatic-drainage.md +22 -0
  735. package/templates/local-business/content/services/5.massage.de.md +11 -0
  736. package/templates/local-business/content/services/5.massage.md +14 -0
  737. package/templates/local-business/content/services/6.home-visits.de.md +11 -0
  738. package/templates/local-business/content/services/6.home-visits.md +12 -0
  739. package/templates/local-business/content/site.de.md +3 -0
  740. package/templates/local-business/content/site.md +11 -0
  741. package/templates/local-business/content/visit.de.md +6 -0
  742. package/templates/local-business/content/visit.md +7 -0
  743. package/templates/local-business/eslint.config.mjs +12 -0
  744. package/templates/local-business/eslint.tailwind.mjs +33 -0
  745. package/templates/local-business/ginko.config.ts +97 -0
  746. package/templates/local-business/gitignore +7 -0
  747. package/templates/local-business/i18n/de.json +49 -0
  748. package/templates/local-business/i18n/en.json +49 -0
  749. package/templates/local-business/i18n/faq/de.json +6 -0
  750. package/templates/local-business/i18n/faq/en.json +6 -0
  751. package/templates/local-business/i18n/gallery/de.json +8 -0
  752. package/templates/local-business/i18n/gallery/en.json +8 -0
  753. package/templates/local-business/i18n/hours/de.json +27 -0
  754. package/templates/local-business/i18n/hours/en.json +27 -0
  755. package/templates/local-business/i18n/people/de.json +6 -0
  756. package/templates/local-business/i18n/people/en.json +6 -0
  757. package/templates/local-business/i18n/services/de.json +20 -0
  758. package/templates/local-business/i18n/services/en.json +20 -0
  759. package/templates/local-business/i18n/site/de.json +39 -0
  760. package/templates/local-business/i18n/site/en.json +39 -0
  761. package/templates/local-business/modules/feature-messages.ts +19 -0
  762. package/templates/local-business/modules/feeds/index.ts +22 -0
  763. package/templates/local-business/modules/feeds/routes.ts +13 -0
  764. package/templates/local-business/modules/page-paths/index.ts +26 -0
  765. package/templates/local-business/modules/page-paths/paths.ts +48 -0
  766. package/templates/local-business/nuxt.config.ts +29 -0
  767. package/templates/local-business/package.json +62 -0
  768. package/templates/local-business/pnpm-workspace.yaml +6 -0
  769. package/templates/local-business/public/media/massage.jpg +0 -0
  770. package/templates/local-business/public/media/treatment-room.jpg +0 -0
  771. package/templates/local-business/server/plugins/font-preload.ts +17 -0
  772. package/templates/local-business/site-url.ts +21 -0
  773. package/templates/local-business/tsconfig.json +9 -0
  774. package/templates/local-business.json +11 -0
  775. package/templates/nonprofit/.env.example +8 -0
  776. package/templates/nonprofit/.github/screenshots/home-dark.png +0 -0
  777. package/templates/nonprofit/.github/screenshots/home-light.png +0 -0
  778. package/templates/nonprofit/.github/workflows/ci.yml +27 -0
  779. package/templates/nonprofit/DESIGN.md +197 -0
  780. package/templates/nonprofit/LICENSE +21 -0
  781. package/templates/nonprofit/MEDIA.md +34 -0
  782. package/templates/nonprofit/NOTES.md +18 -0
  783. package/templates/nonprofit/README.md +227 -0
  784. package/templates/nonprofit/app/app.config.ts +34 -0
  785. package/templates/nonprofit/app/app.vue +7 -0
  786. package/templates/nonprofit/app/assets/css/main.css +35 -0
  787. package/templates/nonprofit/app/assets/css/tokens.css +400 -0
  788. package/templates/nonprofit/app/bricks/logos-quotes.ts +47 -0
  789. package/templates/nonprofit/app/bricks/pages.ts +38 -0
  790. package/templates/nonprofit/app/bricks/projects.ts +114 -0
  791. package/templates/nonprofit/app/components/InitialsAvatar.vue +18 -0
  792. package/templates/nonprofit/app/components/ProseBody.vue +13 -0
  793. package/templates/nonprofit/app/components/block/Cards.vue +54 -0
  794. package/templates/nonprofit/app/components/block/Cta.vue +26 -0
  795. package/templates/nonprofit/app/components/block/Empty.vue +26 -0
  796. package/templates/nonprofit/app/components/block/Features.vue +24 -0
  797. package/templates/nonprofit/app/components/block/Hero.vue +47 -0
  798. package/templates/nonprofit/app/components/block/Logos.vue +22 -0
  799. package/templates/nonprofit/app/components/block/PageHeader.vue +21 -0
  800. package/templates/nonprofit/app/components/block/Quote.vue +19 -0
  801. package/templates/nonprofit/app/components/block/Section.vue +31 -0
  802. package/templates/nonprofit/app/components/blog/Byline.vue +22 -0
  803. package/templates/nonprofit/app/components/blog/PostList.vue +33 -0
  804. package/templates/nonprofit/app/components/blog/TagList.vue +17 -0
  805. package/templates/nonprofit/app/components/downloads/FileButton.vue +21 -0
  806. package/templates/nonprofit/app/components/downloads/List.vue +37 -0
  807. package/templates/nonprofit/app/components/event/Next.vue +24 -0
  808. package/templates/nonprofit/app/components/event/Upcoming.vue +25 -0
  809. package/templates/nonprofit/app/components/pages/Top.vue +19 -0
  810. package/templates/nonprofit/app/components/people/List.vue +41 -0
  811. package/templates/nonprofit/app/components/people/TeamContact.vue +7 -0
  812. package/templates/nonprofit/app/components/site/Contact.vue +38 -0
  813. package/templates/nonprofit/app/components/site/Footer.vue +81 -0
  814. package/templates/nonprofit/app/components/site/Header.vue +52 -0
  815. package/templates/nonprofit/app/components/site/LanguageSwitch.vue +34 -0
  816. package/templates/nonprofit/app/components/site/Logo.vue +17 -0
  817. package/templates/nonprofit/app/components/site/NavLink.vue +19 -0
  818. package/templates/nonprofit/app/components/site/NavSheet.vue +63 -0
  819. package/templates/nonprofit/app/components/site/Notice.vue +21 -0
  820. package/templates/nonprofit/app/components/site/SkipLink.vue +15 -0
  821. package/templates/nonprofit/app/components/site/ThemeToggle.vue +28 -0
  822. package/templates/nonprofit/app/components/ui/button/Button.vue +30 -0
  823. package/templates/nonprofit/app/components/ui/button/index.ts +44 -0
  824. package/templates/nonprofit/app/components/ui/sheet/Sheet.vue +16 -0
  825. package/templates/nonprofit/app/components/ui/sheet/SheetClose.vue +13 -0
  826. package/templates/nonprofit/app/components/ui/sheet/SheetContent.vue +54 -0
  827. package/templates/nonprofit/app/components/ui/sheet/SheetDescription.vue +23 -0
  828. package/templates/nonprofit/app/components/ui/sheet/SheetOverlay.vue +22 -0
  829. package/templates/nonprofit/app/components/ui/sheet/SheetTitle.vue +23 -0
  830. package/templates/nonprofit/app/components/ui/sheet/SheetTrigger.vue +13 -0
  831. package/templates/nonprofit/app/components/ui/sheet/index.ts +7 -0
  832. package/templates/nonprofit/app/composables/useBlog.ts +103 -0
  833. package/templates/nonprofit/app/composables/useDownloads.ts +54 -0
  834. package/templates/nonprofit/app/composables/useEvents.ts +182 -0
  835. package/templates/nonprofit/app/composables/usePageSeo.ts +50 -0
  836. package/templates/nonprofit/app/composables/useProjects.ts +31 -0
  837. package/templates/nonprofit/app/composables/useSiteAppConfig.ts +79 -0
  838. package/templates/nonprofit/app/error.vue +35 -0
  839. package/templates/nonprofit/app/layouts/default.vue +23 -0
  840. package/templates/nonprofit/app/lib/utils.ts +26 -0
  841. package/templates/nonprofit/app/pages/[...slug].vue +36 -0
  842. package/templates/nonprofit/app/pages/downloads.vue +20 -0
  843. package/templates/nonprofit/app/pages/events/[slug].vue +106 -0
  844. package/templates/nonprofit/app/pages/events/index.vue +20 -0
  845. package/templates/nonprofit/app/pages/index.vue +64 -0
  846. package/templates/nonprofit/app/pages/legal/[slug].vue +46 -0
  847. package/templates/nonprofit/app/pages/news/[slug].vue +94 -0
  848. package/templates/nonprofit/app/pages/news/index.vue +54 -0
  849. package/templates/nonprofit/app/pages/news/tags/[tag].vue +41 -0
  850. package/templates/nonprofit/app/pages/projects/[slug].vue +49 -0
  851. package/templates/nonprofit/app/pages/projects/index.vue +24 -0
  852. package/templates/nonprofit/app/pages/team.vue +40 -0
  853. package/templates/nonprofit/app/routes.ts +32 -0
  854. package/templates/nonprofit/app/utils/telHref.ts +3 -0
  855. package/templates/nonprofit/components.json +21 -0
  856. package/templates/nonprofit/content/downloads/annual-report.ar.md +4 -0
  857. package/templates/nonprofit/content/downloads/annual-report.de.md +4 -0
  858. package/templates/nonprofit/content/downloads/annual-report.fr.md +4 -0
  859. package/templates/nonprofit/content/downloads/annual-report.md +7 -0
  860. package/templates/nonprofit/content/events/1.winter-clean-up.ar.md +9 -0
  861. package/templates/nonprofit/content/events/1.winter-clean-up.de.md +9 -0
  862. package/templates/nonprofit/content/events/1.winter-clean-up.fr.md +9 -0
  863. package/templates/nonprofit/content/events/1.winter-clean-up.md +14 -0
  864. package/templates/nonprofit/content/events/2.members-meeting.ar.md +9 -0
  865. package/templates/nonprofit/content/events/2.members-meeting.de.md +9 -0
  866. package/templates/nonprofit/content/events/2.members-meeting.fr.md +9 -0
  867. package/templates/nonprofit/content/events/2.members-meeting.md +15 -0
  868. package/templates/nonprofit/content/events/3.spring-clean-up.ar.md +9 -0
  869. package/templates/nonprofit/content/events/3.spring-clean-up.de.md +9 -0
  870. package/templates/nonprofit/content/events/3.spring-clean-up.fr.md +9 -0
  871. package/templates/nonprofit/content/events/3.spring-clean-up.md +14 -0
  872. package/templates/nonprofit/content/home.ar.md +6 -0
  873. package/templates/nonprofit/content/home.de.md +6 -0
  874. package/templates/nonprofit/content/home.fr.md +6 -0
  875. package/templates/nonprofit/content/home.md +7 -0
  876. package/templates/nonprofit/content/legal/1.privacy.ar.md +18 -0
  877. package/templates/nonprofit/content/legal/1.privacy.de.md +18 -0
  878. package/templates/nonprofit/content/legal/1.privacy.fr.md +18 -0
  879. package/templates/nonprofit/content/legal/1.privacy.md +20 -0
  880. package/templates/nonprofit/content/legal/2.terms.ar.md +17 -0
  881. package/templates/nonprofit/content/legal/2.terms.de.md +17 -0
  882. package/templates/nonprofit/content/legal/2.terms.fr.md +17 -0
  883. package/templates/nonprofit/content/legal/2.terms.md +19 -0
  884. package/templates/nonprofit/content/legal/3.imprint.ar.md +16 -0
  885. package/templates/nonprofit/content/legal/3.imprint.de.md +16 -0
  886. package/templates/nonprofit/content/legal/3.imprint.fr.md +16 -0
  887. package/templates/nonprofit/content/legal/3.imprint.md +18 -0
  888. package/templates/nonprofit/content/logos/1.partner-one.md +6 -0
  889. package/templates/nonprofit/content/logos/2.partner-two.md +6 -0
  890. package/templates/nonprofit/content/logos/3.partner-three.md +6 -0
  891. package/templates/nonprofit/content/notices/1.annual-report-online.ar.md +3 -0
  892. package/templates/nonprofit/content/notices/1.annual-report-online.de.md +3 -0
  893. package/templates/nonprofit/content/notices/1.annual-report-online.fr.md +3 -0
  894. package/templates/nonprofit/content/notices/1.annual-report-online.md +4 -0
  895. package/templates/nonprofit/content/pages/1.about.ar.md +21 -0
  896. package/templates/nonprofit/content/pages/1.about.de.md +21 -0
  897. package/templates/nonprofit/content/pages/1.about.fr.md +21 -0
  898. package/templates/nonprofit/content/pages/1.about.md +21 -0
  899. package/templates/nonprofit/content/pages/2.get-involved.ar.md +19 -0
  900. package/templates/nonprofit/content/pages/2.get-involved.de.md +19 -0
  901. package/templates/nonprofit/content/pages/2.get-involved.fr.md +19 -0
  902. package/templates/nonprofit/content/pages/2.get-involved.md +20 -0
  903. package/templates/nonprofit/content/pages/3.donate.ar.md +26 -0
  904. package/templates/nonprofit/content/pages/3.donate.de.md +26 -0
  905. package/templates/nonprofit/content/pages/3.donate.fr.md +26 -0
  906. package/templates/nonprofit/content/pages/3.donate.md +27 -0
  907. package/templates/nonprofit/content/people/1.jana-becker.ar.md +4 -0
  908. package/templates/nonprofit/content/people/1.jana-becker.de.md +4 -0
  909. package/templates/nonprofit/content/people/1.jana-becker.fr.md +4 -0
  910. package/templates/nonprofit/content/people/1.jana-becker.md +5 -0
  911. package/templates/nonprofit/content/people/2.yusuf-demir.ar.md +4 -0
  912. package/templates/nonprofit/content/people/2.yusuf-demir.de.md +4 -0
  913. package/templates/nonprofit/content/people/2.yusuf-demir.fr.md +4 -0
  914. package/templates/nonprofit/content/people/2.yusuf-demir.md +5 -0
  915. package/templates/nonprofit/content/people/3.claire-martin.ar.md +4 -0
  916. package/templates/nonprofit/content/people/3.claire-martin.de.md +4 -0
  917. package/templates/nonprofit/content/people/3.claire-martin.fr.md +4 -0
  918. package/templates/nonprofit/content/people/3.claire-martin.md +5 -0
  919. package/templates/nonprofit/content/people/4.lukas-hoffmann.ar.md +4 -0
  920. package/templates/nonprofit/content/people/4.lukas-hoffmann.de.md +4 -0
  921. package/templates/nonprofit/content/people/4.lukas-hoffmann.fr.md +4 -0
  922. package/templates/nonprofit/content/people/4.lukas-hoffmann.md +6 -0
  923. package/templates/nonprofit/content/posts/a-home-for-our-tools.ar.md +10 -0
  924. package/templates/nonprofit/content/posts/a-home-for-our-tools.de.md +10 -0
  925. package/templates/nonprofit/content/posts/a-home-for-our-tools.fr.md +10 -0
  926. package/templates/nonprofit/content/posts/a-home-for-our-tools.md +12 -0
  927. package/templates/nonprofit/content/posts/autumn-clean-up.ar.md +20 -0
  928. package/templates/nonprofit/content/posts/autumn-clean-up.de.md +20 -0
  929. package/templates/nonprofit/content/posts/autumn-clean-up.fr.md +20 -0
  930. package/templates/nonprofit/content/posts/autumn-clean-up.md +23 -0
  931. package/templates/nonprofit/content/posts/hedge-planting-plan.md +12 -0
  932. package/templates/nonprofit/content/posts/water-tests-with-schools.ar.md +16 -0
  933. package/templates/nonprofit/content/posts/water-tests-with-schools.de.md +16 -0
  934. package/templates/nonprofit/content/posts/water-tests-with-schools.fr.md +16 -0
  935. package/templates/nonprofit/content/posts/water-tests-with-schools.md +18 -0
  936. package/templates/nonprofit/content/posts/winter-clean-up.ar.md +14 -0
  937. package/templates/nonprofit/content/posts/winter-clean-up.de.md +14 -0
  938. package/templates/nonprofit/content/posts/winter-clean-up.fr.md +14 -0
  939. package/templates/nonprofit/content/posts/winter-clean-up.md +16 -0
  940. package/templates/nonprofit/content/projects/1.clean-banks.ar.md +9 -0
  941. package/templates/nonprofit/content/projects/1.clean-banks.de.md +9 -0
  942. package/templates/nonprofit/content/projects/1.clean-banks.fr.md +9 -0
  943. package/templates/nonprofit/content/projects/1.clean-banks.md +10 -0
  944. package/templates/nonprofit/content/projects/2.water-tests.ar.md +9 -0
  945. package/templates/nonprofit/content/projects/2.water-tests.de.md +9 -0
  946. package/templates/nonprofit/content/projects/2.water-tests.fr.md +9 -0
  947. package/templates/nonprofit/content/projects/2.water-tests.md +10 -0
  948. package/templates/nonprofit/content/projects/3.hedge-campaign.ar.md +10 -0
  949. package/templates/nonprofit/content/projects/3.hedge-campaign.de.md +10 -0
  950. package/templates/nonprofit/content/projects/3.hedge-campaign.fr.md +10 -0
  951. package/templates/nonprofit/content/projects/3.hedge-campaign.md +13 -0
  952. package/templates/nonprofit/content/projects/4.gloves-appeal.md +9 -0
  953. package/templates/nonprofit/content/quotes/1.volunteer.ar.md +4 -0
  954. package/templates/nonprofit/content/quotes/1.volunteer.de.md +4 -0
  955. package/templates/nonprofit/content/quotes/1.volunteer.fr.md +4 -0
  956. package/templates/nonprofit/content/quotes/1.volunteer.md +5 -0
  957. package/templates/nonprofit/content/quotes/2.teacher.ar.md +4 -0
  958. package/templates/nonprofit/content/quotes/2.teacher.de.md +4 -0
  959. package/templates/nonprofit/content/quotes/2.teacher.fr.md +4 -0
  960. package/templates/nonprofit/content/quotes/2.teacher.md +5 -0
  961. package/templates/nonprofit/content/site.ar.md +3 -0
  962. package/templates/nonprofit/content/site.de.md +3 -0
  963. package/templates/nonprofit/content/site.fr.md +3 -0
  964. package/templates/nonprofit/content/site.md +11 -0
  965. package/templates/nonprofit/eslint.config.mjs +12 -0
  966. package/templates/nonprofit/eslint.tailwind.mjs +33 -0
  967. package/templates/nonprofit/ginko.config.ts +77 -0
  968. package/templates/nonprofit/gitignore +7 -0
  969. package/templates/nonprofit/i18n/ar.json +37 -0
  970. package/templates/nonprofit/i18n/blog/ar.json +18 -0
  971. package/templates/nonprofit/i18n/blog/de.json +18 -0
  972. package/templates/nonprofit/i18n/blog/en.json +18 -0
  973. package/templates/nonprofit/i18n/blog/fr.json +18 -0
  974. package/templates/nonprofit/i18n/de.json +37 -0
  975. package/templates/nonprofit/i18n/downloads/ar.json +6 -0
  976. package/templates/nonprofit/i18n/downloads/de.json +6 -0
  977. package/templates/nonprofit/i18n/downloads/en.json +6 -0
  978. package/templates/nonprofit/i18n/downloads/fr.json +6 -0
  979. package/templates/nonprofit/i18n/en.json +37 -0
  980. package/templates/nonprofit/i18n/events/ar.json +20 -0
  981. package/templates/nonprofit/i18n/events/de.json +20 -0
  982. package/templates/nonprofit/i18n/events/en.json +20 -0
  983. package/templates/nonprofit/i18n/events/fr.json +20 -0
  984. package/templates/nonprofit/i18n/fr.json +37 -0
  985. package/templates/nonprofit/i18n/people/ar.json +6 -0
  986. package/templates/nonprofit/i18n/people/de.json +6 -0
  987. package/templates/nonprofit/i18n/people/en.json +6 -0
  988. package/templates/nonprofit/i18n/people/fr.json +6 -0
  989. package/templates/nonprofit/i18n/projects/ar.json +7 -0
  990. package/templates/nonprofit/i18n/projects/de.json +7 -0
  991. package/templates/nonprofit/i18n/projects/en.json +7 -0
  992. package/templates/nonprofit/i18n/projects/fr.json +7 -0
  993. package/templates/nonprofit/i18n/site/ar.json +39 -0
  994. package/templates/nonprofit/i18n/site/de.json +39 -0
  995. package/templates/nonprofit/i18n/site/en.json +39 -0
  996. package/templates/nonprofit/i18n/site/fr.json +39 -0
  997. package/templates/nonprofit/modules/feature-messages.ts +19 -0
  998. package/templates/nonprofit/modules/feeds/index.ts +22 -0
  999. package/templates/nonprofit/modules/feeds/routes.ts +13 -0
  1000. package/templates/nonprofit/modules/page-paths/index.ts +26 -0
  1001. package/templates/nonprofit/modules/page-paths/paths.ts +48 -0
  1002. package/templates/nonprofit/nuxt.config.ts +36 -0
  1003. package/templates/nonprofit/package.json +63 -0
  1004. package/templates/nonprofit/pnpm-workspace.yaml +6 -0
  1005. package/templates/nonprofit/public/files/annual-report-2025.pdf +0 -0
  1006. package/templates/nonprofit/public/logos/partner-one.svg +5 -0
  1007. package/templates/nonprofit/public/logos/partner-three.svg +5 -0
  1008. package/templates/nonprofit/public/logos/partner-two.svg +4 -0
  1009. package/templates/nonprofit/public/media/bank-clean-up.jpg +0 -0
  1010. package/templates/nonprofit/public/media/forest-stream.jpg +0 -0
  1011. package/templates/nonprofit/public/media/green-bank.jpg +0 -0
  1012. package/templates/nonprofit/public/media/planting.jpg +0 -0
  1013. package/templates/nonprofit/public/media/river-town.jpg +0 -0
  1014. package/templates/nonprofit/public/media/workshop.jpg +0 -0
  1015. package/templates/nonprofit/server/middleware/news-feed.ts +37 -0
  1016. package/templates/nonprofit/server/plugins/font-preload.ts +17 -0
  1017. package/templates/nonprofit/site-url.ts +21 -0
  1018. package/templates/nonprofit/tsconfig.json +9 -0
  1019. package/templates/nonprofit.json +20 -0
  1020. package/templates/portfolio/.env.example +8 -0
  1021. package/templates/portfolio/.github/screenshots/home-dark.png +0 -0
  1022. package/templates/portfolio/.github/screenshots/home-light.png +0 -0
  1023. package/templates/portfolio/.github/workflows/ci.yml +27 -0
  1024. package/templates/portfolio/DESIGN.md +197 -0
  1025. package/templates/portfolio/LICENSE +21 -0
  1026. package/templates/portfolio/MEDIA.md +35 -0
  1027. package/templates/portfolio/NOTES.md +18 -0
  1028. package/templates/portfolio/README.md +267 -0
  1029. package/templates/portfolio/app/app.config.ts +27 -0
  1030. package/templates/portfolio/app/app.vue +7 -0
  1031. package/templates/portfolio/app/assets/css/main.css +56 -0
  1032. package/templates/portfolio/app/assets/css/tokens.css +400 -0
  1033. package/templates/portfolio/app/bricks/pages.ts +38 -0
  1034. package/templates/portfolio/app/bricks/projects.ts +114 -0
  1035. package/templates/portfolio/app/components/InitialsAvatar.vue +18 -0
  1036. package/templates/portfolio/app/components/ProseBody.vue +13 -0
  1037. package/templates/portfolio/app/components/StartProject.vue +15 -0
  1038. package/templates/portfolio/app/components/block/Cards.vue +54 -0
  1039. package/templates/portfolio/app/components/block/Cta.vue +26 -0
  1040. package/templates/portfolio/app/components/block/Empty.vue +26 -0
  1041. package/templates/portfolio/app/components/block/Features.vue +24 -0
  1042. package/templates/portfolio/app/components/block/Gallery.vue +81 -0
  1043. package/templates/portfolio/app/components/block/Hero.vue +47 -0
  1044. package/templates/portfolio/app/components/block/PageHeader.vue +21 -0
  1045. package/templates/portfolio/app/components/block/Section.vue +31 -0
  1046. package/templates/portfolio/app/components/blog/Byline.vue +22 -0
  1047. package/templates/portfolio/app/components/blog/PostList.vue +33 -0
  1048. package/templates/portfolio/app/components/blog/TagList.vue +17 -0
  1049. package/templates/portfolio/app/components/pages/Top.vue +12 -0
  1050. package/templates/portfolio/app/components/people/List.vue +41 -0
  1051. package/templates/portfolio/app/components/people/TeamContact.vue +9 -0
  1052. package/templates/portfolio/app/components/projects/Body.vue +62 -0
  1053. package/templates/portfolio/app/components/projects/List.vue +38 -0
  1054. package/templates/portfolio/app/components/site/Contact.vue +38 -0
  1055. package/templates/portfolio/app/components/site/Footer.vue +81 -0
  1056. package/templates/portfolio/app/components/site/Header.vue +52 -0
  1057. package/templates/portfolio/app/components/site/LanguageSwitch.vue +34 -0
  1058. package/templates/portfolio/app/components/site/Lightbox.vue +62 -0
  1059. package/templates/portfolio/app/components/site/Logo.vue +17 -0
  1060. package/templates/portfolio/app/components/site/NavLink.vue +19 -0
  1061. package/templates/portfolio/app/components/site/NavSheet.vue +63 -0
  1062. package/templates/portfolio/app/components/site/Notice.vue +21 -0
  1063. package/templates/portfolio/app/components/site/SkipLink.vue +15 -0
  1064. package/templates/portfolio/app/components/site/ThemeToggle.vue +28 -0
  1065. package/templates/portfolio/app/components/ui/button/Button.vue +30 -0
  1066. package/templates/portfolio/app/components/ui/button/index.ts +44 -0
  1067. package/templates/portfolio/app/components/ui/sheet/Sheet.vue +16 -0
  1068. package/templates/portfolio/app/components/ui/sheet/SheetClose.vue +13 -0
  1069. package/templates/portfolio/app/components/ui/sheet/SheetContent.vue +54 -0
  1070. package/templates/portfolio/app/components/ui/sheet/SheetDescription.vue +23 -0
  1071. package/templates/portfolio/app/components/ui/sheet/SheetOverlay.vue +22 -0
  1072. package/templates/portfolio/app/components/ui/sheet/SheetTitle.vue +23 -0
  1073. package/templates/portfolio/app/components/ui/sheet/SheetTrigger.vue +13 -0
  1074. package/templates/portfolio/app/components/ui/sheet/index.ts +7 -0
  1075. package/templates/portfolio/app/composables/useBlog.ts +103 -0
  1076. package/templates/portfolio/app/composables/usePageSeo.ts +50 -0
  1077. package/templates/portfolio/app/composables/useProjectJsonLd.ts +26 -0
  1078. package/templates/portfolio/app/composables/useProjects.ts +31 -0
  1079. package/templates/portfolio/app/composables/useSiteAppConfig.ts +79 -0
  1080. package/templates/portfolio/app/composables/useStartProject.ts +12 -0
  1081. package/templates/portfolio/app/error.vue +35 -0
  1082. package/templates/portfolio/app/layouts/default.vue +23 -0
  1083. package/templates/portfolio/app/lib/utils.ts +26 -0
  1084. package/templates/portfolio/app/pages/[...slug].vue +36 -0
  1085. package/templates/portfolio/app/pages/index.vue +60 -0
  1086. package/templates/portfolio/app/pages/legal/[slug].vue +46 -0
  1087. package/templates/portfolio/app/pages/news/[slug].vue +94 -0
  1088. package/templates/portfolio/app/pages/news/index.vue +54 -0
  1089. package/templates/portfolio/app/pages/news/tags/[tag].vue +41 -0
  1090. package/templates/portfolio/app/pages/projects/[slug].vue +49 -0
  1091. package/templates/portfolio/app/pages/projects/index.vue +24 -0
  1092. package/templates/portfolio/app/pages/team.vue +40 -0
  1093. package/templates/portfolio/app/routes.ts +30 -0
  1094. package/templates/portfolio/app/utils/telHref.ts +3 -0
  1095. package/templates/portfolio/components.json +21 -0
  1096. package/templates/portfolio/content/home.de.md +4 -0
  1097. package/templates/portfolio/content/home.md +4 -0
  1098. package/templates/portfolio/content/legal/1.privacy.de.md +19 -0
  1099. package/templates/portfolio/content/legal/1.privacy.md +21 -0
  1100. package/templates/portfolio/content/legal/2.imprint.de.md +15 -0
  1101. package/templates/portfolio/content/legal/2.imprint.md +17 -0
  1102. package/templates/portfolio/content/notices/1.holm-chair.de.md +3 -0
  1103. package/templates/portfolio/content/notices/1.holm-chair.md +4 -0
  1104. package/templates/portfolio/content/pages/1.how-we-work.de.md +23 -0
  1105. package/templates/portfolio/content/pages/1.how-we-work.md +23 -0
  1106. package/templates/portfolio/content/people/1.maren-holt.de.md +4 -0
  1107. package/templates/portfolio/content/people/1.maren-holt.md +6 -0
  1108. package/templates/portfolio/content/people/2.ole-petersen.de.md +4 -0
  1109. package/templates/portfolio/content/people/2.ole-petersen.md +6 -0
  1110. package/templates/portfolio/content/posts/full-size-drawings.de.md +11 -0
  1111. package/templates/portfolio/content/posts/full-size-drawings.md +13 -0
  1112. package/templates/portfolio/content/posts/lime-plaster.de.md +11 -0
  1113. package/templates/portfolio/content/posts/lime-plaster.md +13 -0
  1114. package/templates/portfolio/content/projects/1.attic-flat-ottensen.de.md +19 -0
  1115. package/templates/portfolio/content/projects/1.attic-flat-ottensen.md +22 -0
  1116. package/templates/portfolio/content/projects/2.elbsand-vases.de.md +18 -0
  1117. package/templates/portfolio/content/projects/2.elbsand-vases.md +21 -0
  1118. package/templates/portfolio/content/projects/3.werftblick-entrance-hall.de.md +18 -0
  1119. package/templates/portfolio/content/projects/3.werftblick-entrance-hall.md +22 -0
  1120. package/templates/portfolio/content/projects/4.holm-chair.de.md +18 -0
  1121. package/templates/portfolio/content/projects/4.holm-chair.md +21 -0
  1122. package/templates/portfolio/content/site.md +13 -0
  1123. package/templates/portfolio/eslint.config.mjs +12 -0
  1124. package/templates/portfolio/eslint.tailwind.mjs +33 -0
  1125. package/templates/portfolio/ginko.config.ts +70 -0
  1126. package/templates/portfolio/gitignore +7 -0
  1127. package/templates/portfolio/i18n/blog/de.json +18 -0
  1128. package/templates/portfolio/i18n/blog/en.json +18 -0
  1129. package/templates/portfolio/i18n/de.json +47 -0
  1130. package/templates/portfolio/i18n/en.json +47 -0
  1131. package/templates/portfolio/i18n/gallery/de.json +8 -0
  1132. package/templates/portfolio/i18n/gallery/en.json +8 -0
  1133. package/templates/portfolio/i18n/people/de.json +6 -0
  1134. package/templates/portfolio/i18n/people/en.json +6 -0
  1135. package/templates/portfolio/i18n/projects/de.json +7 -0
  1136. package/templates/portfolio/i18n/projects/en.json +7 -0
  1137. package/templates/portfolio/i18n/site/de.json +39 -0
  1138. package/templates/portfolio/i18n/site/en.json +39 -0
  1139. package/templates/portfolio/modules/feature-messages.ts +19 -0
  1140. package/templates/portfolio/modules/feeds/index.ts +22 -0
  1141. package/templates/portfolio/modules/feeds/routes.ts +13 -0
  1142. package/templates/portfolio/modules/page-paths/index.ts +26 -0
  1143. package/templates/portfolio/modules/page-paths/paths.ts +48 -0
  1144. package/templates/portfolio/nuxt.config.ts +30 -0
  1145. package/templates/portfolio/package.json +60 -0
  1146. package/templates/portfolio/pnpm-workspace.yaml +6 -0
  1147. package/templates/portfolio/public/media/attic-light.jpg +0 -0
  1148. package/templates/portfolio/public/media/ceramic-vases.jpg +0 -0
  1149. package/templates/portfolio/public/media/concrete-stair.jpg +0 -0
  1150. package/templates/portfolio/public/media/material-samples.jpg +0 -0
  1151. package/templates/portfolio/public/media/oak-chair.jpg +0 -0
  1152. package/templates/portfolio/public/media/workshop-drawings.jpg +0 -0
  1153. package/templates/portfolio/server/middleware/news-feed.ts +37 -0
  1154. package/templates/portfolio/server/plugins/font-preload.ts +17 -0
  1155. package/templates/portfolio/site-url.ts +21 -0
  1156. package/templates/portfolio/tsconfig.json +9 -0
  1157. package/templates/portfolio.json +11 -0
  1158. package/templates/restaurant/.env.example +8 -0
  1159. package/templates/restaurant/.github/screenshots/home-dark.png +0 -0
  1160. package/templates/restaurant/.github/screenshots/home-light.png +0 -0
  1161. package/templates/restaurant/.github/workflows/ci.yml +27 -0
  1162. package/templates/restaurant/DESIGN.md +197 -0
  1163. package/templates/restaurant/LICENSE +21 -0
  1164. package/templates/restaurant/MEDIA.md +37 -0
  1165. package/templates/restaurant/README.md +249 -0
  1166. package/templates/restaurant/app/app.config.ts +33 -0
  1167. package/templates/restaurant/app/app.vue +7 -0
  1168. package/templates/restaurant/app/assets/css/main.css +20 -0
  1169. package/templates/restaurant/app/assets/css/tokens.css +400 -0
  1170. package/templates/restaurant/app/bricks/pages.ts +38 -0
  1171. package/templates/restaurant/app/components/InitialsAvatar.vue +18 -0
  1172. package/templates/restaurant/app/components/ProseBody.vue +13 -0
  1173. package/templates/restaurant/app/components/block/Cards.vue +54 -0
  1174. package/templates/restaurant/app/components/block/Cta.vue +26 -0
  1175. package/templates/restaurant/app/components/block/Empty.vue +26 -0
  1176. package/templates/restaurant/app/components/block/Features.vue +24 -0
  1177. package/templates/restaurant/app/components/block/Gallery.vue +81 -0
  1178. package/templates/restaurant/app/components/block/Hero.vue +47 -0
  1179. package/templates/restaurant/app/components/block/PageHeader.vue +21 -0
  1180. package/templates/restaurant/app/components/block/Section.vue +31 -0
  1181. package/templates/restaurant/app/components/event/Upcoming.vue +25 -0
  1182. package/templates/restaurant/app/components/hours/Table.vue +119 -0
  1183. package/templates/restaurant/app/components/hours/Today.vue +55 -0
  1184. package/templates/restaurant/app/components/menu/AllergenKey.vue +17 -0
  1185. package/templates/restaurant/app/components/menu/Allergens.vue +24 -0
  1186. package/templates/restaurant/app/components/menu/Diet.vue +16 -0
  1187. package/templates/restaurant/app/components/menu/Dish.vue +30 -0
  1188. package/templates/restaurant/app/components/menu/LunchDays.vue +42 -0
  1189. package/templates/restaurant/app/components/site/Contact.vue +38 -0
  1190. package/templates/restaurant/app/components/site/Footer.vue +81 -0
  1191. package/templates/restaurant/app/components/site/FooterStatus.vue +9 -0
  1192. package/templates/restaurant/app/components/site/Header.vue +52 -0
  1193. package/templates/restaurant/app/components/site/LanguageSwitch.vue +34 -0
  1194. package/templates/restaurant/app/components/site/Lightbox.vue +62 -0
  1195. package/templates/restaurant/app/components/site/Logo.vue +17 -0
  1196. package/templates/restaurant/app/components/site/NavLink.vue +19 -0
  1197. package/templates/restaurant/app/components/site/NavSheet.vue +63 -0
  1198. package/templates/restaurant/app/components/site/Notice.vue +21 -0
  1199. package/templates/restaurant/app/components/site/SkipLink.vue +15 -0
  1200. package/templates/restaurant/app/components/site/ThemeToggle.vue +28 -0
  1201. package/templates/restaurant/app/components/ui/button/Button.vue +30 -0
  1202. package/templates/restaurant/app/components/ui/button/index.ts +44 -0
  1203. package/templates/restaurant/app/components/ui/sheet/Sheet.vue +16 -0
  1204. package/templates/restaurant/app/components/ui/sheet/SheetClose.vue +13 -0
  1205. package/templates/restaurant/app/components/ui/sheet/SheetContent.vue +54 -0
  1206. package/templates/restaurant/app/components/ui/sheet/SheetDescription.vue +23 -0
  1207. package/templates/restaurant/app/components/ui/sheet/SheetOverlay.vue +22 -0
  1208. package/templates/restaurant/app/components/ui/sheet/SheetTitle.vue +23 -0
  1209. package/templates/restaurant/app/components/ui/sheet/SheetTrigger.vue +13 -0
  1210. package/templates/restaurant/app/components/ui/sheet/index.ts +7 -0
  1211. package/templates/restaurant/app/composables/useEvents.ts +182 -0
  1212. package/templates/restaurant/app/composables/useHours.ts +81 -0
  1213. package/templates/restaurant/app/composables/useMenu.ts +76 -0
  1214. package/templates/restaurant/app/composables/usePageSeo.ts +50 -0
  1215. package/templates/restaurant/app/composables/useSiteAppConfig.ts +79 -0
  1216. package/templates/restaurant/app/error.vue +35 -0
  1217. package/templates/restaurant/app/layouts/default.vue +23 -0
  1218. package/templates/restaurant/app/layouts/print.vue +9 -0
  1219. package/templates/restaurant/app/lib/utils.ts +26 -0
  1220. package/templates/restaurant/app/pages/[...slug].vue +36 -0
  1221. package/templates/restaurant/app/pages/events/[slug].vue +106 -0
  1222. package/templates/restaurant/app/pages/events/index.vue +20 -0
  1223. package/templates/restaurant/app/pages/gallery.vue +17 -0
  1224. package/templates/restaurant/app/pages/index.vue +163 -0
  1225. package/templates/restaurant/app/pages/legal/[slug].vue +46 -0
  1226. package/templates/restaurant/app/pages/lunch.vue +30 -0
  1227. package/templates/restaurant/app/pages/menu/index.vue +46 -0
  1228. package/templates/restaurant/app/pages/menu/print.vue +69 -0
  1229. package/templates/restaurant/app/pages/reservations.vue +52 -0
  1230. package/templates/restaurant/app/routes.ts +33 -0
  1231. package/templates/restaurant/app/utils/hours.ts +58 -0
  1232. package/templates/restaurant/app/utils/telHref.ts +3 -0
  1233. package/templates/restaurant/components.json +21 -0
  1234. package/templates/restaurant/content/events/1.wine-evening.de.md +10 -0
  1235. package/templates/restaurant/content/events/1.wine-evening.it.md +10 -0
  1236. package/templates/restaurant/content/events/1.wine-evening.md +16 -0
  1237. package/templates/restaurant/content/events/2.cooking-class.de.md +10 -0
  1238. package/templates/restaurant/content/events/2.cooking-class.it.md +10 -0
  1239. package/templates/restaurant/content/events/2.cooking-class.md +16 -0
  1240. package/templates/restaurant/content/gallery.de.md +15 -0
  1241. package/templates/restaurant/content/gallery.it.md +15 -0
  1242. package/templates/restaurant/content/gallery.md +21 -0
  1243. package/templates/restaurant/content/home.de.md +6 -0
  1244. package/templates/restaurant/content/home.it.md +6 -0
  1245. package/templates/restaurant/content/home.md +7 -0
  1246. package/templates/restaurant/content/hourPlans/1.winter-hours.de.md +3 -0
  1247. package/templates/restaurant/content/hourPlans/1.winter-hours.it.md +3 -0
  1248. package/templates/restaurant/content/hourPlans/1.winter-hours.md +41 -0
  1249. package/templates/restaurant/content/hours.de.md +4 -0
  1250. package/templates/restaurant/content/hours.it.md +4 -0
  1251. package/templates/restaurant/content/hours.md +45 -0
  1252. package/templates/restaurant/content/legal/1.privacy.de.md +28 -0
  1253. package/templates/restaurant/content/legal/1.privacy.it.md +28 -0
  1254. package/templates/restaurant/content/legal/1.privacy.md +29 -0
  1255. package/templates/restaurant/content/legal/2.terms.de.md +21 -0
  1256. package/templates/restaurant/content/legal/2.terms.it.md +21 -0
  1257. package/templates/restaurant/content/legal/2.terms.md +22 -0
  1258. package/templates/restaurant/content/legal/3.imprint.de.md +15 -0
  1259. package/templates/restaurant/content/legal/3.imprint.it.md +15 -0
  1260. package/templates/restaurant/content/legal/3.imprint.md +16 -0
  1261. package/templates/restaurant/content/lunch.de.md +3 -0
  1262. package/templates/restaurant/content/lunch.it.md +3 -0
  1263. package/templates/restaurant/content/lunch.md +25 -0
  1264. package/templates/restaurant/content/menu/1.liptauer.de.md +4 -0
  1265. package/templates/restaurant/content/menu/1.liptauer.it.md +4 -0
  1266. package/templates/restaurant/content/menu/1.liptauer.md +8 -0
  1267. package/templates/restaurant/content/menu/10.kaiserschmarrn.de.md +4 -0
  1268. package/templates/restaurant/content/menu/10.kaiserschmarrn.it.md +4 -0
  1269. package/templates/restaurant/content/menu/10.kaiserschmarrn.md +8 -0
  1270. package/templates/restaurant/content/menu/11.apple-strudel.de.md +4 -0
  1271. package/templates/restaurant/content/menu/11.apple-strudel.it.md +4 -0
  1272. package/templates/restaurant/content/menu/11.apple-strudel.md +8 -0
  1273. package/templates/restaurant/content/menu/12.apple-spritzer.de.md +4 -0
  1274. package/templates/restaurant/content/menu/12.apple-spritzer.it.md +4 -0
  1275. package/templates/restaurant/content/menu/12.apple-spritzer.md +8 -0
  1276. package/templates/restaurant/content/menu/13.elderflower-soda.de.md +3 -0
  1277. package/templates/restaurant/content/menu/13.elderflower-soda.it.md +3 -0
  1278. package/templates/restaurant/content/menu/13.elderflower-soda.md +7 -0
  1279. package/templates/restaurant/content/menu/14.melange.de.md +4 -0
  1280. package/templates/restaurant/content/menu/14.melange.it.md +4 -0
  1281. package/templates/restaurant/content/menu/14.melange.md +8 -0
  1282. package/templates/restaurant/content/menu/15.gruener-veltliner.de.md +4 -0
  1283. package/templates/restaurant/content/menu/15.gruener-veltliner.it.md +4 -0
  1284. package/templates/restaurant/content/menu/15.gruener-veltliner.md +8 -0
  1285. package/templates/restaurant/content/menu/16.zweigelt.de.md +4 -0
  1286. package/templates/restaurant/content/menu/16.zweigelt.it.md +4 -0
  1287. package/templates/restaurant/content/menu/16.zweigelt.md +8 -0
  1288. package/templates/restaurant/content/menu/17.maerzen.de.md +4 -0
  1289. package/templates/restaurant/content/menu/17.maerzen.it.md +4 -0
  1290. package/templates/restaurant/content/menu/17.maerzen.md +8 -0
  1291. package/templates/restaurant/content/menu/2.cured-char.de.md +4 -0
  1292. package/templates/restaurant/content/menu/2.cured-char.it.md +4 -0
  1293. package/templates/restaurant/content/menu/2.cured-char.md +8 -0
  1294. package/templates/restaurant/content/menu/3.frittaten-soup.de.md +4 -0
  1295. package/templates/restaurant/content/menu/3.frittaten-soup.it.md +4 -0
  1296. package/templates/restaurant/content/menu/3.frittaten-soup.md +8 -0
  1297. package/templates/restaurant/content/menu/4.pumpkin-soup.de.md +4 -0
  1298. package/templates/restaurant/content/menu/4.pumpkin-soup.it.md +4 -0
  1299. package/templates/restaurant/content/menu/4.pumpkin-soup.md +8 -0
  1300. package/templates/restaurant/content/menu/5.wiener-schnitzel.de.md +4 -0
  1301. package/templates/restaurant/content/menu/5.wiener-schnitzel.it.md +4 -0
  1302. package/templates/restaurant/content/menu/5.wiener-schnitzel.md +8 -0
  1303. package/templates/restaurant/content/menu/6.tafelspitz.de.md +4 -0
  1304. package/templates/restaurant/content/menu/6.tafelspitz.it.md +4 -0
  1305. package/templates/restaurant/content/menu/6.tafelspitz.md +8 -0
  1306. package/templates/restaurant/content/menu/7.roast-pork.de.md +4 -0
  1307. package/templates/restaurant/content/menu/7.roast-pork.it.md +4 -0
  1308. package/templates/restaurant/content/menu/7.roast-pork.md +8 -0
  1309. package/templates/restaurant/content/menu/8.kasnocken.de.md +4 -0
  1310. package/templates/restaurant/content/menu/8.kasnocken.it.md +4 -0
  1311. package/templates/restaurant/content/menu/8.kasnocken.md +8 -0
  1312. package/templates/restaurant/content/menu/9.lentil-goulash.de.md +4 -0
  1313. package/templates/restaurant/content/menu/9.lentil-goulash.it.md +4 -0
  1314. package/templates/restaurant/content/menu/9.lentil-goulash.md +8 -0
  1315. package/templates/restaurant/content/notices/1.cook-wanted.de.md +3 -0
  1316. package/templates/restaurant/content/notices/1.cook-wanted.it.md +3 -0
  1317. package/templates/restaurant/content/notices/1.cook-wanted.md +4 -0
  1318. package/templates/restaurant/content/pages/1.about.de.md +23 -0
  1319. package/templates/restaurant/content/pages/1.about.it.md +23 -0
  1320. package/templates/restaurant/content/pages/1.about.md +24 -0
  1321. package/templates/restaurant/content/reservations.de.md +20 -0
  1322. package/templates/restaurant/content/reservations.it.md +20 -0
  1323. package/templates/restaurant/content/reservations.md +20 -0
  1324. package/templates/restaurant/content/site.de.md +3 -0
  1325. package/templates/restaurant/content/site.it.md +3 -0
  1326. package/templates/restaurant/content/site.md +12 -0
  1327. package/templates/restaurant/eslint.config.mjs +12 -0
  1328. package/templates/restaurant/eslint.tailwind.mjs +33 -0
  1329. package/templates/restaurant/ginko.config.ts +78 -0
  1330. package/templates/restaurant/gitignore +7 -0
  1331. package/templates/restaurant/i18n/de.json +31 -0
  1332. package/templates/restaurant/i18n/en.json +31 -0
  1333. package/templates/restaurant/i18n/events/de.json +20 -0
  1334. package/templates/restaurant/i18n/events/en.json +20 -0
  1335. package/templates/restaurant/i18n/events/it.json +20 -0
  1336. package/templates/restaurant/i18n/gallery/de.json +8 -0
  1337. package/templates/restaurant/i18n/gallery/en.json +8 -0
  1338. package/templates/restaurant/i18n/gallery/it.json +8 -0
  1339. package/templates/restaurant/i18n/hours/de.json +27 -0
  1340. package/templates/restaurant/i18n/hours/en.json +27 -0
  1341. package/templates/restaurant/i18n/hours/it.json +27 -0
  1342. package/templates/restaurant/i18n/it.json +31 -0
  1343. package/templates/restaurant/i18n/menu/de.json +54 -0
  1344. package/templates/restaurant/i18n/menu/en.json +54 -0
  1345. package/templates/restaurant/i18n/menu/it.json +54 -0
  1346. package/templates/restaurant/i18n/site/de.json +39 -0
  1347. package/templates/restaurant/i18n/site/en.json +39 -0
  1348. package/templates/restaurant/i18n/site/it.json +39 -0
  1349. package/templates/restaurant/modules/feature-messages.ts +19 -0
  1350. package/templates/restaurant/modules/feeds/index.ts +22 -0
  1351. package/templates/restaurant/modules/feeds/routes.ts +13 -0
  1352. package/templates/restaurant/modules/page-paths/index.ts +26 -0
  1353. package/templates/restaurant/modules/page-paths/paths.ts +48 -0
  1354. package/templates/restaurant/nuxt.config.ts +27 -0
  1355. package/templates/restaurant/package.json +61 -0
  1356. package/templates/restaurant/pnpm-workspace.yaml +6 -0
  1357. package/templates/restaurant/public/media/garten.jpg +0 -0
  1358. package/templates/restaurant/public/media/gastraum.jpg +0 -0
  1359. package/templates/restaurant/public/media/gaststube.jpg +0 -0
  1360. package/templates/restaurant/public/media/kueche.jpg +0 -0
  1361. package/templates/restaurant/public/media/schnitzel.jpg +0 -0
  1362. package/templates/restaurant/public/media/strudel.jpg +0 -0
  1363. package/templates/restaurant/public/media/weinabend.jpg +0 -0
  1364. package/templates/restaurant/server/plugins/font-preload.ts +17 -0
  1365. package/templates/restaurant/site-url.ts +21 -0
  1366. package/templates/restaurant/tsconfig.json +9 -0
  1367. package/templates/restaurant.json +19 -0
  1368. package/templates/saas/.env.example +8 -0
  1369. package/templates/saas/.github/screenshots/home-dark.png +0 -0
  1370. package/templates/saas/.github/screenshots/home-light.png +0 -0
  1371. package/templates/saas/.github/workflows/ci.yml +27 -0
  1372. package/templates/saas/DESIGN.md +197 -0
  1373. package/templates/saas/LICENSE +21 -0
  1374. package/templates/saas/MEDIA.md +20 -0
  1375. package/templates/saas/NOTES.md +23 -0
  1376. package/templates/saas/README.md +264 -0
  1377. package/templates/saas/app/app.config.ts +37 -0
  1378. package/templates/saas/app/app.vue +7 -0
  1379. package/templates/saas/app/assets/css/main.css +30 -0
  1380. package/templates/saas/app/assets/css/tokens.css +400 -0
  1381. package/templates/saas/app/bricks/logos-quotes.ts +47 -0
  1382. package/templates/saas/app/bricks/pages.ts +38 -0
  1383. package/templates/saas/app/bricks/pricing.ts +60 -0
  1384. package/templates/saas/app/components/DocsPageEnd.vue +8 -0
  1385. package/templates/saas/app/components/InitialsAvatar.vue +18 -0
  1386. package/templates/saas/app/components/ProseBody.vue +13 -0
  1387. package/templates/saas/app/components/block/Cards.vue +54 -0
  1388. package/templates/saas/app/components/block/Cta.vue +26 -0
  1389. package/templates/saas/app/components/block/Empty.vue +26 -0
  1390. package/templates/saas/app/components/block/Faq.vue +19 -0
  1391. package/templates/saas/app/components/block/Features.vue +24 -0
  1392. package/templates/saas/app/components/block/Hero.vue +47 -0
  1393. package/templates/saas/app/components/block/Logos.vue +22 -0
  1394. package/templates/saas/app/components/block/PageHeader.vue +21 -0
  1395. package/templates/saas/app/components/block/Quote.vue +19 -0
  1396. package/templates/saas/app/components/block/Section.vue +31 -0
  1397. package/templates/saas/app/components/blog/Byline.vue +22 -0
  1398. package/templates/saas/app/components/blog/PostList.vue +33 -0
  1399. package/templates/saas/app/components/blog/TagList.vue +17 -0
  1400. package/templates/saas/app/components/changelog/Latest.vue +32 -0
  1401. package/templates/saas/app/components/help/Contact.vue +14 -0
  1402. package/templates/saas/app/components/pages/Top.vue +30 -0
  1403. package/templates/saas/app/components/pricing/More.vue +21 -0
  1404. package/templates/saas/app/components/pricing/Plans.vue +60 -0
  1405. package/templates/saas/app/components/site/Contact.vue +38 -0
  1406. package/templates/saas/app/components/site/Footer.vue +81 -0
  1407. package/templates/saas/app/components/site/Header.vue +52 -0
  1408. package/templates/saas/app/components/site/LanguageSwitch.vue +34 -0
  1409. package/templates/saas/app/components/site/Logo.vue +17 -0
  1410. package/templates/saas/app/components/site/NavLink.vue +19 -0
  1411. package/templates/saas/app/components/site/NavSheet.vue +63 -0
  1412. package/templates/saas/app/components/site/Notice.vue +21 -0
  1413. package/templates/saas/app/components/site/PageCta.vue +12 -0
  1414. package/templates/saas/app/components/site/SkipLink.vue +15 -0
  1415. package/templates/saas/app/components/site/ThemeToggle.vue +28 -0
  1416. package/templates/saas/app/components/ui/accordion/Accordion.vue +16 -0
  1417. package/templates/saas/app/components/ui/accordion/AccordionContent.vue +26 -0
  1418. package/templates/saas/app/components/ui/accordion/AccordionItem.vue +24 -0
  1419. package/templates/saas/app/components/ui/accordion/AccordionTrigger.vue +35 -0
  1420. package/templates/saas/app/components/ui/accordion/index.ts +5 -0
  1421. package/templates/saas/app/components/ui/button/Button.vue +30 -0
  1422. package/templates/saas/app/components/ui/button/index.ts +44 -0
  1423. package/templates/saas/app/components/ui/sheet/Sheet.vue +16 -0
  1424. package/templates/saas/app/components/ui/sheet/SheetClose.vue +13 -0
  1425. package/templates/saas/app/components/ui/sheet/SheetContent.vue +54 -0
  1426. package/templates/saas/app/components/ui/sheet/SheetDescription.vue +23 -0
  1427. package/templates/saas/app/components/ui/sheet/SheetOverlay.vue +22 -0
  1428. package/templates/saas/app/components/ui/sheet/SheetTitle.vue +23 -0
  1429. package/templates/saas/app/components/ui/sheet/SheetTrigger.vue +13 -0
  1430. package/templates/saas/app/components/ui/sheet/index.ts +7 -0
  1431. package/templates/saas/app/composables/useBlog.ts +103 -0
  1432. package/templates/saas/app/composables/useChangelog.ts +54 -0
  1433. package/templates/saas/app/composables/usePageSeo.ts +50 -0
  1434. package/templates/saas/app/composables/usePricing.ts +110 -0
  1435. package/templates/saas/app/composables/useSiteAppConfig.ts +79 -0
  1436. package/templates/saas/app/error.vue +35 -0
  1437. package/templates/saas/app/layouts/default.vue +23 -0
  1438. package/templates/saas/app/lib/utils.ts +26 -0
  1439. package/templates/saas/app/pages/[...slug].vue +36 -0
  1440. package/templates/saas/app/pages/changelog.vue +47 -0
  1441. package/templates/saas/app/pages/faq.vue +39 -0
  1442. package/templates/saas/app/pages/help/index.vue +21 -0
  1443. package/templates/saas/app/pages/index.vue +67 -0
  1444. package/templates/saas/app/pages/legal/[slug].vue +46 -0
  1445. package/templates/saas/app/pages/news/[slug].vue +94 -0
  1446. package/templates/saas/app/pages/news/index.vue +54 -0
  1447. package/templates/saas/app/pages/news/tags/[tag].vue +41 -0
  1448. package/templates/saas/app/pages/pricing.vue +27 -0
  1449. package/templates/saas/app/routes.ts +31 -0
  1450. package/templates/saas/app/utils/telHref.ts +3 -0
  1451. package/templates/saas/components.json +21 -0
  1452. package/templates/saas/content/changelog/v4-3-0.de.md +18 -0
  1453. package/templates/saas/content/changelog/v4-3-0.fr.md +18 -0
  1454. package/templates/saas/content/changelog/v4-3-0.md +20 -0
  1455. package/templates/saas/content/changelog/v4-4-0.de.md +15 -0
  1456. package/templates/saas/content/changelog/v4-4-0.fr.md +15 -0
  1457. package/templates/saas/content/changelog/v4-4-0.md +17 -0
  1458. package/templates/saas/content/changelog/v4-4-1.de.md +11 -0
  1459. package/templates/saas/content/changelog/v4-4-1.fr.md +11 -0
  1460. package/templates/saas/content/changelog/v4-4-1.md +13 -0
  1461. package/templates/saas/content/changelog/v4-5-0.de.md +19 -0
  1462. package/templates/saas/content/changelog/v4-5-0.fr.md +19 -0
  1463. package/templates/saas/content/changelog/v4-5-0.md +21 -0
  1464. package/templates/saas/content/changelog/v4-6-0.de.md +19 -0
  1465. package/templates/saas/content/changelog/v4-6-0.fr.md +19 -0
  1466. package/templates/saas/content/changelog/v4-6-0.md +21 -0
  1467. package/templates/saas/content/docs/1.getting-started.de.md +33 -0
  1468. package/templates/saas/content/docs/1.getting-started.fr.md +33 -0
  1469. package/templates/saas/content/docs/1.getting-started.md +32 -0
  1470. package/templates/saas/content/docs/2.shifts.de.md +24 -0
  1471. package/templates/saas/content/docs/2.shifts.fr.md +24 -0
  1472. package/templates/saas/content/docs/2.shifts.md +23 -0
  1473. package/templates/saas/content/docs/3.export.de.md +21 -0
  1474. package/templates/saas/content/docs/3.export.fr.md +21 -0
  1475. package/templates/saas/content/docs/3.export.md +20 -0
  1476. package/templates/saas/content/faq/1.billing.de.md +4 -0
  1477. package/templates/saas/content/faq/1.billing.fr.md +4 -0
  1478. package/templates/saas/content/faq/1.billing.md +4 -0
  1479. package/templates/saas/content/faq/2.cancellation.de.md +4 -0
  1480. package/templates/saas/content/faq/2.cancellation.fr.md +4 -0
  1481. package/templates/saas/content/faq/2.cancellation.md +4 -0
  1482. package/templates/saas/content/faq/3.data-export.de.md +4 -0
  1483. package/templates/saas/content/faq/3.data-export.fr.md +4 -0
  1484. package/templates/saas/content/faq/3.data-export.md +4 -0
  1485. package/templates/saas/content/faq/4.change-plan.de.md +4 -0
  1486. package/templates/saas/content/faq/4.change-plan.fr.md +4 -0
  1487. package/templates/saas/content/faq/4.change-plan.md +4 -0
  1488. package/templates/saas/content/faq/5.trial.de.md +4 -0
  1489. package/templates/saas/content/faq/5.trial.fr.md +4 -0
  1490. package/templates/saas/content/faq/5.trial.md +4 -0
  1491. package/templates/saas/content/faq/6.data-location.de.md +4 -0
  1492. package/templates/saas/content/faq/6.data-location.fr.md +4 -0
  1493. package/templates/saas/content/faq/6.data-location.md +4 -0
  1494. package/templates/saas/content/faq/7.data-processing.de.md +4 -0
  1495. package/templates/saas/content/faq/7.data-processing.fr.md +4 -0
  1496. package/templates/saas/content/faq/7.data-processing.md +4 -0
  1497. package/templates/saas/content/home.de.md +24 -0
  1498. package/templates/saas/content/home.fr.md +24 -0
  1499. package/templates/saas/content/home.md +26 -0
  1500. package/templates/saas/content/legal/1.privacy.de.md +20 -0
  1501. package/templates/saas/content/legal/1.privacy.fr.md +20 -0
  1502. package/templates/saas/content/legal/1.privacy.md +22 -0
  1503. package/templates/saas/content/legal/2.terms.de.md +20 -0
  1504. package/templates/saas/content/legal/2.terms.fr.md +20 -0
  1505. package/templates/saas/content/legal/2.terms.md +22 -0
  1506. package/templates/saas/content/legal/3.imprint.de.md +16 -0
  1507. package/templates/saas/content/legal/3.imprint.fr.md +16 -0
  1508. package/templates/saas/content/legal/3.imprint.md +18 -0
  1509. package/templates/saas/content/logos/1.sonnenlinde.md +6 -0
  1510. package/templates/saas/content/logos/2.elsterau.md +6 -0
  1511. package/templates/saas/content/logos/3.rosental.md +6 -0
  1512. package/templates/saas/content/logos/4.muldental.md +6 -0
  1513. package/templates/saas/content/notices/5.swap-requests.de.md +3 -0
  1514. package/templates/saas/content/notices/5.swap-requests.fr.md +3 -0
  1515. package/templates/saas/content/notices/5.swap-requests.md +4 -0
  1516. package/templates/saas/content/pages/1.security.de.md +25 -0
  1517. package/templates/saas/content/pages/1.security.fr.md +25 -0
  1518. package/templates/saas/content/pages/1.security.md +25 -0
  1519. package/templates/saas/content/pages/2.about.de.md +17 -0
  1520. package/templates/saas/content/pages/2.about.fr.md +17 -0
  1521. package/templates/saas/content/pages/2.about.md +17 -0
  1522. package/templates/saas/content/pages/3.contact.de.md +15 -0
  1523. package/templates/saas/content/pages/3.contact.fr.md +15 -0
  1524. package/templates/saas/content/pages/3.contact.md +15 -0
  1525. package/templates/saas/content/people/1.lena-hartmann.de.md +4 -0
  1526. package/templates/saas/content/people/1.lena-hartmann.fr.md +4 -0
  1527. package/templates/saas/content/people/1.lena-hartmann.md +5 -0
  1528. package/templates/saas/content/people/2.jonas-pohl.de.md +4 -0
  1529. package/templates/saas/content/people/2.jonas-pohl.fr.md +4 -0
  1530. package/templates/saas/content/people/2.jonas-pohl.md +5 -0
  1531. package/templates/saas/content/posts/rest-periods.de.md +20 -0
  1532. package/templates/saas/content/posts/rest-periods.fr.md +20 -0
  1533. package/templates/saas/content/posts/rest-periods.md +22 -0
  1534. package/templates/saas/content/posts/summer-holidays.de.md +16 -0
  1535. package/templates/saas/content/posts/summer-holidays.fr.md +16 -0
  1536. package/templates/saas/content/posts/summer-holidays.md +18 -0
  1537. package/templates/saas/content/posts/swap-requests.de.md +18 -0
  1538. package/templates/saas/content/posts/swap-requests.fr.md +18 -0
  1539. package/templates/saas/content/posts/swap-requests.md +20 -0
  1540. package/templates/saas/content/pricing/1.small.de.md +11 -0
  1541. package/templates/saas/content/pricing/1.small.fr.md +11 -0
  1542. package/templates/saas/content/pricing/1.small.md +15 -0
  1543. package/templates/saas/content/pricing/2.standard.de.md +11 -0
  1544. package/templates/saas/content/pricing/2.standard.fr.md +11 -0
  1545. package/templates/saas/content/pricing/2.standard.md +16 -0
  1546. package/templates/saas/content/pricing/3.group.de.md +11 -0
  1547. package/templates/saas/content/pricing/3.group.fr.md +11 -0
  1548. package/templates/saas/content/pricing/3.group.md +12 -0
  1549. package/templates/saas/content/quotes/1.ward-lead.de.md +4 -0
  1550. package/templates/saas/content/quotes/1.ward-lead.fr.md +4 -0
  1551. package/templates/saas/content/quotes/1.ward-lead.md +5 -0
  1552. package/templates/saas/content/site.de.md +3 -0
  1553. package/templates/saas/content/site.fr.md +3 -0
  1554. package/templates/saas/content/site.md +12 -0
  1555. package/templates/saas/eslint.config.mjs +12 -0
  1556. package/templates/saas/eslint.tailwind.mjs +33 -0
  1557. package/templates/saas/ginko.config.ts +108 -0
  1558. package/templates/saas/gitignore +7 -0
  1559. package/templates/saas/i18n/blog/de.json +18 -0
  1560. package/templates/saas/i18n/blog/en.json +18 -0
  1561. package/templates/saas/i18n/blog/fr.json +18 -0
  1562. package/templates/saas/i18n/changelog/de.json +9 -0
  1563. package/templates/saas/i18n/changelog/en.json +9 -0
  1564. package/templates/saas/i18n/changelog/fr.json +9 -0
  1565. package/templates/saas/i18n/de.json +48 -0
  1566. package/templates/saas/i18n/en.json +48 -0
  1567. package/templates/saas/i18n/faq/de.json +6 -0
  1568. package/templates/saas/i18n/faq/en.json +6 -0
  1569. package/templates/saas/i18n/faq/fr.json +6 -0
  1570. package/templates/saas/i18n/fr.json +48 -0
  1571. package/templates/saas/i18n/pricing/de.json +14 -0
  1572. package/templates/saas/i18n/pricing/en.json +14 -0
  1573. package/templates/saas/i18n/pricing/fr.json +14 -0
  1574. package/templates/saas/i18n/site/de.json +39 -0
  1575. package/templates/saas/i18n/site/en.json +39 -0
  1576. package/templates/saas/i18n/site/fr.json +39 -0
  1577. package/templates/saas/modules/feature-messages.ts +19 -0
  1578. package/templates/saas/modules/feeds/index.ts +22 -0
  1579. package/templates/saas/modules/feeds/routes.ts +13 -0
  1580. package/templates/saas/modules/page-paths/index.ts +26 -0
  1581. package/templates/saas/modules/page-paths/paths.ts +48 -0
  1582. package/templates/saas/nuxt.config.ts +30 -0
  1583. package/templates/saas/package.json +63 -0
  1584. package/templates/saas/pnpm-workspace.yaml +6 -0
  1585. package/templates/saas/public/logos/care-home-four.svg +4 -0
  1586. package/templates/saas/public/logos/care-home-one.svg +4 -0
  1587. package/templates/saas/public/logos/care-home-two.svg +4 -0
  1588. package/templates/saas/public/logos/clinic-three.svg +4 -0
  1589. package/templates/saas/public/media/rota.svg +76 -0
  1590. package/templates/saas/server/middleware/changelog-feed.ts +50 -0
  1591. package/templates/saas/server/middleware/news-feed.ts +37 -0
  1592. package/templates/saas/server/plugins/font-preload.ts +17 -0
  1593. package/templates/saas/shared/utils/changelog.ts +13 -0
  1594. package/templates/saas/site-url.ts +21 -0
  1595. package/templates/saas/tsconfig.json +9 -0
  1596. package/templates/saas.json +12 -0
  1597. package/templates/starter/.env.example +8 -0
  1598. package/templates/starter/.github/screenshots/home-dark.png +0 -0
  1599. package/templates/starter/.github/screenshots/home-light.png +0 -0
  1600. package/templates/starter/.github/workflows/ci.yml +27 -0
  1601. package/templates/starter/DESIGN.md +197 -0
  1602. package/templates/starter/LICENSE +21 -0
  1603. package/templates/starter/MEDIA.md +11 -0
  1604. package/templates/starter/README.md +199 -0
  1605. package/templates/starter/app/app.config.ts +21 -0
  1606. package/templates/starter/app/app.vue +7 -0
  1607. package/templates/starter/app/assets/css/main.css +19 -0
  1608. package/templates/starter/app/assets/css/tokens.css +400 -0
  1609. package/templates/starter/app/bricks/pages.ts +38 -0
  1610. package/templates/starter/app/components/InitialsAvatar.vue +18 -0
  1611. package/templates/starter/app/components/ProseBody.vue +13 -0
  1612. package/templates/starter/app/components/block/Cards.vue +54 -0
  1613. package/templates/starter/app/components/block/Cta.vue +26 -0
  1614. package/templates/starter/app/components/block/Empty.vue +26 -0
  1615. package/templates/starter/app/components/block/Features.vue +24 -0
  1616. package/templates/starter/app/components/block/Hero.vue +47 -0
  1617. package/templates/starter/app/components/block/PageHeader.vue +21 -0
  1618. package/templates/starter/app/components/block/Section.vue +31 -0
  1619. package/templates/starter/app/components/pages/Top.vue +11 -0
  1620. package/templates/starter/app/components/site/Contact.vue +38 -0
  1621. package/templates/starter/app/components/site/Footer.vue +81 -0
  1622. package/templates/starter/app/components/site/Header.vue +52 -0
  1623. package/templates/starter/app/components/site/LanguageSwitch.vue +34 -0
  1624. package/templates/starter/app/components/site/Logo.vue +17 -0
  1625. package/templates/starter/app/components/site/NavLink.vue +19 -0
  1626. package/templates/starter/app/components/site/NavSheet.vue +63 -0
  1627. package/templates/starter/app/components/site/Notice.vue +21 -0
  1628. package/templates/starter/app/components/site/SkipLink.vue +15 -0
  1629. package/templates/starter/app/components/site/ThemeToggle.vue +28 -0
  1630. package/templates/starter/app/components/ui/button/Button.vue +30 -0
  1631. package/templates/starter/app/components/ui/button/index.ts +44 -0
  1632. package/templates/starter/app/components/ui/sheet/Sheet.vue +16 -0
  1633. package/templates/starter/app/components/ui/sheet/SheetClose.vue +13 -0
  1634. package/templates/starter/app/components/ui/sheet/SheetContent.vue +54 -0
  1635. package/templates/starter/app/components/ui/sheet/SheetDescription.vue +23 -0
  1636. package/templates/starter/app/components/ui/sheet/SheetOverlay.vue +22 -0
  1637. package/templates/starter/app/components/ui/sheet/SheetTitle.vue +23 -0
  1638. package/templates/starter/app/components/ui/sheet/SheetTrigger.vue +13 -0
  1639. package/templates/starter/app/components/ui/sheet/index.ts +7 -0
  1640. package/templates/starter/app/composables/usePageSeo.ts +50 -0
  1641. package/templates/starter/app/composables/useSiteAppConfig.ts +79 -0
  1642. package/templates/starter/app/error.vue +35 -0
  1643. package/templates/starter/app/layouts/default.vue +23 -0
  1644. package/templates/starter/app/lib/utils.ts +26 -0
  1645. package/templates/starter/app/pages/[...slug].vue +36 -0
  1646. package/templates/starter/app/pages/index.vue +24 -0
  1647. package/templates/starter/app/pages/legal/[slug].vue +46 -0
  1648. package/templates/starter/app/routes.ts +14 -0
  1649. package/templates/starter/app/utils/telHref.ts +3 -0
  1650. package/templates/starter/components.json +21 -0
  1651. package/templates/starter/content/home.de.md +16 -0
  1652. package/templates/starter/content/home.md +16 -0
  1653. package/templates/starter/content/legal/1.privacy.de.md +28 -0
  1654. package/templates/starter/content/legal/1.privacy.md +29 -0
  1655. package/templates/starter/content/legal/2.terms.de.md +21 -0
  1656. package/templates/starter/content/legal/2.terms.md +22 -0
  1657. package/templates/starter/content/legal/3.imprint.de.md +16 -0
  1658. package/templates/starter/content/legal/3.imprint.md +16 -0
  1659. package/templates/starter/content/notices/1.welcome.de.md +4 -0
  1660. package/templates/starter/content/notices/1.welcome.md +5 -0
  1661. package/templates/starter/content/pages/1.about.de.md +20 -0
  1662. package/templates/starter/content/pages/1.about.md +18 -0
  1663. package/templates/starter/content/pages/2.contact.de.md +17 -0
  1664. package/templates/starter/content/pages/2.contact.md +15 -0
  1665. package/templates/starter/content/site.md +12 -0
  1666. package/templates/starter/eslint.config.mjs +12 -0
  1667. package/templates/starter/eslint.tailwind.mjs +33 -0
  1668. package/templates/starter/ginko.config.ts +42 -0
  1669. package/templates/starter/gitignore +7 -0
  1670. package/templates/starter/i18n/de.json +6 -0
  1671. package/templates/starter/i18n/en.json +6 -0
  1672. package/templates/starter/i18n/site/de.json +39 -0
  1673. package/templates/starter/i18n/site/en.json +39 -0
  1674. package/templates/starter/modules/feature-messages.ts +19 -0
  1675. package/templates/starter/modules/feeds/index.ts +22 -0
  1676. package/templates/starter/modules/feeds/routes.ts +13 -0
  1677. package/templates/starter/modules/page-paths/index.ts +26 -0
  1678. package/templates/starter/modules/page-paths/paths.ts +48 -0
  1679. package/templates/starter/nuxt.config.ts +27 -0
  1680. package/templates/starter/package.json +55 -0
  1681. package/templates/starter/pnpm-workspace.yaml +6 -0
  1682. package/templates/starter/server/plugins/font-preload.ts +17 -0
  1683. package/templates/starter/site-url.ts +21 -0
  1684. package/templates/starter/tsconfig.json +9 -0
  1685. package/templates/starter.json +11 -0
@@ -0,0 +1,26 @@
1
+ // Synced from templates/_features/ui/app/lib/utils.ts by `pnpm templates sync`. Edit the source, not this copy.
2
+ import type { ClassValue } from 'clsx'
3
+ import { clsx } from 'clsx'
4
+ import { extendTailwindMerge } from 'tailwind-merge'
5
+
6
+ /**
7
+ * tailwind-merge, told about the theme of tokens.css. Without it, `text-small` reads as a colour and `p-gutter` or
8
+ * `max-w-page` as unknown, so a conflicting class would not replace the component's own.
9
+ */
10
+ const twMerge = extendTailwindMerge({
11
+ extend: {
12
+ theme: {
13
+ text: ['h1', 'h2', 'h3', 'lead', 'body', 'small', 'xs'],
14
+ font: ['display'],
15
+ radius: ['block'],
16
+ shadow: ['overlay'],
17
+ spacing: ['section', 'gutter'],
18
+ container: ['page', 'prose'],
19
+ },
20
+ },
21
+ })
22
+
23
+ /** Joins class names (strings, arrays, `{ class: condition }`); a later class wins over a conflicting earlier one. */
24
+ export function cn(...inputs: ClassValue[]) {
25
+ return twMerge(clsx(inputs))
26
+ }
@@ -0,0 +1,36 @@
1
+ <!-- Synced from templates/_features/pages/app/pages/[...slug].vue by `pnpm templates sync`. Edit the source, not this copy. -->
2
+ <script setup lang="ts">
3
+ import type { Component } from 'vue'
4
+ import { safeHref } from '@lupinum/ginko'
5
+
6
+ // A page of content/pages/ at /<slug> (in other languages /<code>/<slug>). An unknown address is a real 404.
7
+ // A template can show more at the top of its pages with app/components/pages/Top.vue (prop `id`: the entry id, such
8
+ // as `pages/get-involved`); without that file, nothing is added.
9
+ const route = useRoute()
10
+ const page = useGinkoEntry('pages', () => route.params.slug)
11
+ const PagesTop = Object.values(import.meta.glob<Component>('~/components/pages/Top.vue', { eager: true, import: 'default' }))[0]
12
+ const action = computed(() => {
13
+ const href = safeHref(page.value.data.actionUrl)
14
+ return href && page.value.data.actionLabel ? { label: page.value.data.actionLabel, href } : undefined
15
+ })
16
+ usePageSeo(() => ({
17
+ title: page.value.data.title,
18
+ description: page.value.data.summary,
19
+ image: page.value.data.image,
20
+ }))
21
+ </script>
22
+
23
+ <template>
24
+ <article>
25
+ <BlockPageHeader :title="page.data.title" :lead="page.data.summary">
26
+ <Button v-if="action" as-child size="lg" class="self-start max-sm:self-stretch">
27
+ <a :href="action.href">{{ action.label }}</a>
28
+ </Button>
29
+ </BlockPageHeader>
30
+ <component :is="PagesTop" v-if="PagesTop" :id="page.id" />
31
+ <div v-if="page.data.image" class="mx-auto max-w-page px-gutter pb-10">
32
+ <GinkoImage :image="page.data.image" eager sizes="(min-width: 1216px) 1152px, 100vw" class="aspect-video w-full rounded-block bg-muted object-cover" />
33
+ </div>
34
+ <ProseBody :value="page.data.body" />
35
+ </article>
36
+ </template>
@@ -0,0 +1,20 @@
1
+ <!-- Synced from templates/_features/downloads/app/pages/downloads.vue by `pnpm templates sync`. Edit the source, not this copy. -->
2
+ <script setup lang="ts">
3
+ // Documents to download, newest first (content/downloads/, the files in public/). The address per language comes
4
+ // from `pages.downloads` in ginko.config.ts.
5
+ const downloads = useGinko('downloads')
6
+ const { t } = useI18n('downloads')
7
+ usePageSeo(() => ({ title: t('title'), description: t('lead') }))
8
+ </script>
9
+
10
+ <template>
11
+ <div>
12
+ <BlockPageHeader :title="t('title')" :lead="t('lead')" />
13
+ <div class="mx-auto max-w-page px-gutter">
14
+ <div class="max-w-4xl">
15
+ <DownloadsList v-if="downloads.items.length" :items="downloads.items" />
16
+ <BlockEmpty v-else :title="t('empty')" path="content/downloads/" />
17
+ </div>
18
+ </div>
19
+ </div>
20
+ </template>
@@ -0,0 +1,106 @@
1
+ <!-- Synced from templates/_features/events/app/pages/events/[slug].vue by `pnpm templates sync`. Edit the source, not this copy. -->
2
+ <script setup lang="ts">
3
+ import type { Component, ComputedRef } from 'vue'
4
+ import { safeHref } from '@lupinum/ginko'
5
+ import type { SessionJsonLdInput } from '@lupinum/ginko/basics'
6
+ import { ArrowLeft, Mail, Phone } from '@lucide/vue'
7
+
8
+ // One event: date with weekday and time (site time zone), place (its location, else the online link, else the
9
+ // site's name and address when app.config `events.atTheBusiness` is true; otherwise no row: content/site.md is the organiser, not the venue), price, the description, and how to take part: the
10
+ // booking link until `bookingUntil`, else phone and email of the business (content/site.md); "fully booked" or
11
+ // "booking has closed" replaces both. Event JSON-LD with the time zone offset. An unknown or past event is a 404.
12
+ // A feature may show more after the description with app/components/event/Programme.vue (prop `id`: the event's
13
+ // entry id), and give the event's sessions to its JSON-LD with `useSessionsLd` in app/composables/useSessions.ts;
14
+ // the sessions feature brings both: the event's programme. Without those files, nothing is added.
15
+ const EventProgramme = Object.values(import.meta.glob<Component>('~/components/event/Programme.vue', { eager: true, import: 'default' }))[0]
16
+ type SessionsLd = (event: () => string) => ComputedRef<SessionJsonLdInput[]>
17
+ const useSessionsLd = Object.values(import.meta.glob<SessionsLd>('~/composables/useSessions.ts', { eager: true, import: 'useSessionsLd' }))[0]
18
+ const route = useRoute()
19
+ const event = useGinkoEntry('events', () => route.params.slug)
20
+ const site = useGinko('site')
21
+ const { t } = useI18n('events')
22
+ const { dates, times, price, ltr } = useEventText()
23
+ const venue = useEventVenue()
24
+ const path = useGinkoPath()
25
+ const langOf = useGinkoLang()
26
+ const description = await useGinkoMarkdown(() => event.value.data.description)
27
+ const sessions = useSessionsLd?.(() => event.value.id)
28
+ const jsonLd = useEventJsonLd(() => ({ ...event.value.data, url: event.value.url ?? route.path }), () => description.value, () => sessions?.value)
29
+ // The meta description is plain text: the isolate marks of a right-to-left page stay out of it.
30
+ const metaDescription = () => `${dates(event.value.data)}${times(event.value.data) ? `, ${times(event.value.data)}` : ''}`.replace(/[\u2066\u2069]/g, '')
31
+ usePageSeo(() => ({ title: event.value.data.title, description: metaDescription(), image: event.value.data.image ?? undefined, jsonLd: [jsonLd.value] }))
32
+
33
+ const contact = computed(() => site.value.data)
34
+ const bookingOf = useEventBooking()
35
+ const closedOf = useBookingClosed()
36
+ const booking = computed(() => bookingOf(event.value.data))
37
+ const closed = computed(() => closedOf(event.value.data))
38
+ const online = computed(() => safeHref(event.value.data.online ?? undefined))
39
+ const atBusiness = computed(() => (event.value.data.location || online.value ? undefined : venue(event.value.data)))
40
+ const place = computed(() => event.value.data.location || (online.value ? t('online') : atBusiness.value?.name))
41
+ const businessAddress = computed(() => {
42
+ const a = atBusiness.value?.address
43
+ return a && [a.street, [a.postalCode, a.city].filter(Boolean).join(' ')].filter(Boolean).join(', ')
44
+ })
45
+ </script>
46
+
47
+ <template>
48
+ <article>
49
+ <div class="mx-auto max-w-page px-gutter pt-8 md:pt-12">
50
+ <NuxtLink :to="path('events')" class="-ms-1 inline-flex min-h-11 items-center gap-2 px-1 text-small font-medium text-muted-foreground underline-offset-4 hover:text-foreground hover:underline">
51
+ <ArrowLeft class="size-4 rtl:-scale-x-100" aria-hidden="true" />
52
+ {{ t('all') }}
53
+ </NuxtLink>
54
+ </div>
55
+ <header class="mx-auto max-w-page px-gutter pt-4 pb-8 md:pb-12">
56
+ <div class="flex max-w-3xl flex-col gap-5">
57
+ <h1 class="text-h1" :lang="langOf(event, 'title')">{{ event.data.title }}</h1>
58
+ <dl class="grid gap-x-8 gap-y-3 sm:grid-cols-[auto_1fr]">
59
+ <dt class="text-small text-muted-foreground">{{ t('date') }}</dt>
60
+ <dd class="font-medium tabular-nums">{{ dates(event.data) }}</dd>
61
+ <template v-if="times(event.data)">
62
+ <dt class="text-small text-muted-foreground">{{ t('time') }}</dt>
63
+ <dd class="font-medium tabular-nums">{{ times(event.data) }}</dd>
64
+ </template>
65
+ <template v-if="place">
66
+ <dt class="text-small text-muted-foreground">{{ t('place') }}</dt>
67
+ <dd class="font-medium">
68
+ <a v-if="!event.data.location && online" :href="online" rel="noopener" class="text-primary underline">{{ place }}</a>
69
+ <span v-else>{{ place }}</span>
70
+ <span v-if="businessAddress" class="block font-normal text-muted-foreground">{{ businessAddress }}</span>
71
+ </dd>
72
+ </template>
73
+ <template v-if="price(event.data)">
74
+ <dt class="text-small text-muted-foreground">{{ t('price') }}</dt>
75
+ <dd class="font-medium tabular-nums">{{ price(event.data) }}</dd>
76
+ </template>
77
+ </dl>
78
+ <p v-if="event.data.soldOut" class="text-lead font-semibold">{{ t('soldOut') }}</p>
79
+ <p v-else-if="closed" class="text-lead font-semibold">{{ t('bookingClosed') }}</p>
80
+ <div v-else-if="booking" class="flex flex-wrap gap-3">
81
+ <Button as-child size="lg" class="max-sm:w-full">
82
+ <a :href="booking" rel="noopener">{{ t('book') }}</a>
83
+ </Button>
84
+ </div>
85
+ <div v-else-if="contact.phone || contact.email" class="flex flex-col gap-3">
86
+ <p class="text-muted-foreground">{{ t('reserve') }}</p>
87
+ <div class="flex flex-wrap gap-3">
88
+ <Button v-if="contact.phone" as-child size="lg" class="max-sm:w-full">
89
+ <a :href="telHref(contact.phone)"><Phone aria-hidden="true" />{{ t('call', { phone: ltr(contact.phone) }) }}</a>
90
+ </Button>
91
+ <Button v-if="contact.email" as-child size="lg" :variant="contact.phone ? 'outline' : 'default'" class="max-sm:w-full">
92
+ <a :href="`mailto:${contact.email}`"><Mail aria-hidden="true" />{{ t('email') }}</a>
93
+ </Button>
94
+ </div>
95
+ </div>
96
+ </div>
97
+ </header>
98
+ <div v-if="event.data.image" class="mx-auto max-w-page px-gutter pb-10">
99
+ <GinkoImage :image="event.data.image" eager sizes="(min-width: 1216px) 1152px, 100vw" class="aspect-video w-full rounded-block bg-muted object-cover" :lang="langOf(event, 'image.alt')" />
100
+ </div>
101
+ <div :lang="langOf(event, 'description')">
102
+ <ProseBody :value="event.data.description" />
103
+ </div>
104
+ <component :is="EventProgramme" v-if="EventProgramme" :id="event.id" />
105
+ </article>
106
+ </template>
@@ -0,0 +1,20 @@
1
+ <!-- Synced from templates/_features/events/app/pages/events/index.vue by `pnpm templates sync`. Edit the source, not this copy. -->
2
+ <script setup lang="ts">
3
+ // Upcoming events (content/events/), the next first, with weekday, date, time, price and "fully booked". An event
4
+ // leaves this list, the sitemap and search engines after its last day. The cards' titles are h3: a hidden h2 keeps the
5
+ // heading order (h1, h2, h3) for screen readers.
6
+ const cards = useUpcomingEvents()
7
+ const { t } = useI18n('events')
8
+ usePageSeo(() => ({ title: t('title'), description: t('lead') }))
9
+ </script>
10
+
11
+ <template>
12
+ <div>
13
+ <BlockPageHeader :title="t('title')" :lead="t('lead')" />
14
+ <div class="mx-auto max-w-page px-gutter">
15
+ <h2 v-if="cards.length" class="sr-only">{{ t('upcoming') }}</h2>
16
+ <BlockCards v-if="cards.length" :items="cards" :columns="3" />
17
+ <p v-else class="max-w-prose text-lead text-muted-foreground">{{ t('none') }}</p>
18
+ </div>
19
+ </div>
20
+ </template>
@@ -0,0 +1,84 @@
1
+ <script setup lang="ts">
2
+ import { ArrowRight } from '@lucide/vue'
3
+ import type { Card } from '~/components/block/Cards.vue'
4
+
5
+ // The home page answers "what do you make, and can it solve my problem?" in the first screen: what the company makes
6
+ // in one sentence (content/home.md), one main action, contact sales, and the service line for a pump that has
7
+ // stopped. Then the products and services, the references (customer logos and one quote), the latest news, the open
8
+ // jobs and the next trade fair, and a closing band with the way to sales and the office's phone. A section whose list
9
+ // is empty is left out.
10
+ const home = useGinko('home')
11
+ const site = useGinko('site')
12
+ const quotes = useGinko('quotes')
13
+ const logos = useGinko('logos')
14
+ const fairs = useGinko('events')
15
+ const services = useServiceCards(() => 3)
16
+ const posts = useBlogPosts()
17
+ const jobs = useOpenJobs()
18
+ const { when } = useEventText()
19
+ const path = useGinkoPath()
20
+ const { t } = useI18n()
21
+ const { name } = useGinkoSite()
22
+ const latest = computed(() => posts.value.slice(0, 3))
23
+ const quote = computed(() => quotes.value.items[0])
24
+ const contact = computed(() => site.value.data)
25
+
26
+ // Open jobs and the next trade fair, as two cards: the jobs card always shows (with no open job it invites an open
27
+ // application), the fair card only while a fair is coming up.
28
+ const next = computed<Card[]>(() => {
29
+ const fair = fairs.value.items[0]
30
+ const count = jobs.value.length
31
+ return [
32
+ { key: 'jobs', title: t('home.jobs.title', { name }), to: path('jobs'), meta: count ? t('home.jobs.count', { count }) : t('home.jobs.none'), text: t('home.jobs.text') },
33
+ ...(fair ? [{ key: fair.id, title: fair.data.title, to: fair.url, meta: when(fair.data, 'short'), text: fair.data.location ?? undefined }] : []),
34
+ ]
35
+ })
36
+ // The tab and search result say what the company makes; the share card keeps the sentence of the first screen.
37
+ usePageSeo(() => ({ home: true, title: t('home.title'), description: home.value.data.lead, image: home.value.data.image }))
38
+ </script>
39
+
40
+ <template>
41
+ <div>
42
+ <BlockHero
43
+ :title="home.data.title"
44
+ :lead="home.data.lead"
45
+ :image="home.data.image"
46
+ :primary="{ label: t('home.sales'), to: path('team') }"
47
+ :secondary="{ label: t('home.catalogue'), to: path('services') }"
48
+ >
49
+ <ServiceLine />
50
+ </BlockHero>
51
+
52
+ <BlockSection v-if="services.length" :title="t('home.products')" :side="false">
53
+ <BlockCards :items="services" compact />
54
+ <NuxtLink :to="path('services')" class="mt-6 inline-flex min-h-11 items-center gap-2 font-medium text-primary underline-offset-4 hover:underline">
55
+ {{ t('home.allProducts') }}<ArrowRight class="size-4 rtl:-scale-x-100" aria-hidden="true" />
56
+ </NuxtLink>
57
+ </BlockSection>
58
+
59
+ <BlockSection v-if="logos.items.length || quote" :title="t('home.references')" :lead="t('home.referencesLead')">
60
+ <div class="flex flex-col gap-12">
61
+ <BlockLogos v-if="logos.items.length" :items="logos.items" />
62
+ <BlockQuote v-if="quote" :text="quote.data.text" :name="quote.data.name" :role="quote.data.role" />
63
+ </div>
64
+ </BlockSection>
65
+
66
+ <BlockSection v-if="latest.length" :title="t('home.news')">
67
+ <BlogPostList :items="latest" heading-level="h3" />
68
+ <NuxtLink :to="path('news')" class="mt-6 inline-flex min-h-11 items-center gap-2 font-medium text-primary underline-offset-4 hover:underline">
69
+ {{ t('blog.latest') }}<ArrowRight class="size-4 rtl:-scale-x-100" aria-hidden="true" />
70
+ </NuxtLink>
71
+ </BlockSection>
72
+
73
+ <BlockSection v-if="next.length" :title="t('home.next')" :side="false">
74
+ <BlockCards :items="next" :columns="2" />
75
+ </BlockSection>
76
+
77
+ <BlockCta :title="t('home.cta.title')" :text="t('home.cta.text')" :action="{ label: t('home.sales'), to: path('team') }">
78
+ <p v-if="contact.phone || contact.email" class="flex flex-wrap gap-x-6 text-body">
79
+ <a v-if="contact.phone" :href="telHref(contact.phone)" dir="ltr" class="inline-flex min-h-11 items-center font-medium tabular-nums underline underline-offset-4">{{ contact.phone }}</a>
80
+ <a v-if="contact.email" :href="`mailto:${contact.email}`" dir="ltr" class="inline-flex min-h-11 items-center font-medium underline underline-offset-4">{{ contact.email }}</a>
81
+ </p>
82
+ </BlockCta>
83
+ </div>
84
+ </template>
@@ -0,0 +1,63 @@
1
+ <!-- Synced from templates/_features/jobs/app/pages/jobs/[slug].vue by `pnpm templates sync`. Edit the source, not this copy. -->
2
+ <script setup lang="ts">
3
+ import { ArrowLeft, Mail } from '@lucide/vue'
4
+
5
+ // One job: title, short description, place, employment, work place and the last day to apply, the text, and how to
6
+ // apply (an email with the job title in the subject, or the job's application page; no form on this site), at the
7
+ // top and again below the text. JobPosting JSON-LD with `validThrough`. A job after its `validUntil` day, and an
8
+ // unknown one, is a 404.
9
+ const route = useRoute()
10
+ const job = useGinkoEntry('jobs', () => route.params.slug)
11
+ const path = useGinkoPath()
12
+ const { t } = useI18n('jobs')
13
+ const { employment, workplace, deadline } = useJobText()
14
+ const apply = useApplyLink(() => job.value.data)
15
+ const body = await useGinkoMarkdown(() => job.value.data.body)
16
+ const jsonLd = useJobJsonLd(() => ({ ...job.value.data, url: job.value.url, updatedAt: job.value.updatedAt }), () => body.value)
17
+ usePageSeo(() => ({ title: job.value.data.title, description: job.value.data.description, jsonLd: [jsonLd.value] }))
18
+ </script>
19
+
20
+ <template>
21
+ <article>
22
+ <div class="mx-auto max-w-page px-gutter pt-8 md:pt-12">
23
+ <NuxtLink :to="path('jobs')" class="-ms-1 inline-flex min-h-11 items-center gap-2 px-1 text-small font-medium text-muted-foreground underline-offset-4 hover:text-foreground hover:underline">
24
+ <ArrowLeft class="size-4 rtl:-scale-x-100" aria-hidden="true" />
25
+ {{ t('all') }}
26
+ </NuxtLink>
27
+ </div>
28
+ <header class="mx-auto max-w-page px-gutter pt-4 pb-8 md:pb-12">
29
+ <div class="flex max-w-3xl flex-col gap-5">
30
+ <h1 class="text-h1">{{ job.data.title }}</h1>
31
+ <p class="text-lead text-muted-foreground">{{ job.data.description }}</p>
32
+ <dl class="grid gap-x-8 gap-y-3 sm:grid-cols-[auto_1fr]">
33
+ <dt class="text-small text-muted-foreground">{{ t('location') }}</dt>
34
+ <dd class="font-medium">{{ job.data.location }}</dd>
35
+ <dt class="text-small text-muted-foreground">{{ t('employmentLabel') }}</dt>
36
+ <dd class="font-medium">{{ employment(job.data) }}</dd>
37
+ <dt class="text-small text-muted-foreground">{{ t('workplaceLabel') }}</dt>
38
+ <dd class="font-medium">{{ workplace(job.data) }}</dd>
39
+ <dt class="text-small text-muted-foreground">{{ t('deadline') }}</dt>
40
+ <dd class="font-medium tabular-nums"><time :datetime="job.data.validUntil">{{ deadline(job.data) }}</time></dd>
41
+ </dl>
42
+ <div v-if="apply" class="flex flex-wrap gap-3">
43
+ <Button as-child size="lg" class="max-sm:w-full">
44
+ <a :href="apply.href" :rel="apply.email ? undefined : 'noopener'"><Mail v-if="apply.email" aria-hidden="true" />{{ apply.email ? t('applyEmail') : t('applyOnline') }}</a>
45
+ </Button>
46
+ </div>
47
+ </div>
48
+ </header>
49
+ <ProseBody :value="job.data.body" />
50
+ <section v-if="apply" aria-labelledby="job-apply" class="mx-auto max-w-page px-gutter pt-10">
51
+ <div class="flex max-w-prose flex-col items-start gap-4 border-t pt-8">
52
+ <h2 id="job-apply" class="text-h3">{{ t('how') }}</h2>
53
+ <p class="text-muted-foreground">
54
+ <template v-if="apply.email">{{ t('howEmail', { email: apply.email, date: deadline(job.data) }) }}</template>
55
+ <template v-else>{{ t('howOnline', { date: deadline(job.data) }) }}</template>
56
+ </p>
57
+ <Button as-child variant="outline" size="lg" class="max-sm:w-full">
58
+ <a :href="apply.href" :rel="apply.email ? undefined : 'noopener'"><Mail v-if="apply.email" aria-hidden="true" />{{ apply.email ? t('applyEmail') : t('applyOnline') }}</a>
59
+ </Button>
60
+ </div>
61
+ </section>
62
+ </article>
63
+ </template>
@@ -0,0 +1,36 @@
1
+ <!-- Synced from templates/_features/jobs/app/pages/jobs/index.vue by `pnpm templates sync`. Edit the source, not this copy. -->
2
+ <script setup lang="ts">
3
+ import { Mail } from '@lucide/vue'
4
+
5
+ // The open jobs (content/jobs/). A job leaves this list, its page, the sitemap and the JSON-LD after its
6
+ // `validUntil` day by itself. With no open job the page says so and asks for an open application by email, to the
7
+ // business's address in content/site.md. The address per language comes from `pages.jobs` in ginko.config.ts.
8
+ const jobs = useOpenJobs()
9
+ const open = useApplyLink(() => undefined)
10
+ const { t } = useI18n('jobs')
11
+ usePageSeo(() => ({ title: t('title'), description: t('lead') }))
12
+ </script>
13
+
14
+ <template>
15
+ <div>
16
+ <BlockPageHeader :title="t('title')" :lead="t('lead')" />
17
+ <div class="mx-auto max-w-page px-gutter">
18
+ <div class="max-w-4xl">
19
+ <template v-if="jobs.length">
20
+ <JobsList :items="jobs" />
21
+ <p v-if="open" class="mt-6 text-muted-foreground">
22
+ {{ t('open.more') }}
23
+ <a :href="open.href" class="inline-flex min-h-11 items-center font-medium text-primary underline underline-offset-4">{{ t('open.action') }}</a>
24
+ </p>
25
+ </template>
26
+ <div v-else class="flex max-w-prose flex-col items-start gap-4">
27
+ <p class="text-lead font-medium">{{ t('none') }}</p>
28
+ <p class="text-muted-foreground">{{ t('open.text') }}</p>
29
+ <Button v-if="open" as-child size="lg" class="max-sm:w-full">
30
+ <a :href="open.href"><Mail aria-hidden="true" />{{ t('open.action') }}</a>
31
+ </Button>
32
+ </div>
33
+ </div>
34
+ </div>
35
+ </div>
36
+ </template>
@@ -0,0 +1,46 @@
1
+ <!-- Synced from templates/_features/site/app/pages/legal/[slug].vue by `pnpm templates sync`. Edit the source, not this copy. -->
2
+ <script setup lang="ts">
3
+ // One legal text (content/legal/): privacy policy, terms, imprint. Address: /legal/<slug> in every language.
4
+ // The imprint starts with the details of content/site.md (name, address, register, VAT number, email, phone), so the
5
+ // owner writes them once; the text below adds what site.md cannot hold. A detail site.md does not have is left out.
6
+ // Email and phone are links (mailto:, tel:), like on the contact page.
7
+ const route = useRoute()
8
+ const entry = useGinkoEntry('legal', () => route.params.slug)
9
+ const site = useGinko('site')
10
+ const { t, format } = useI18n('site')
11
+ const details = computed(() => {
12
+ const d = site.value.data
13
+ if (entry.value.data.legalType !== 'imprint') return []
14
+ const rows: { label: string, value?: string, href?: string }[] = [
15
+ { label: t('imprint.address'), value: [d.legalName, d.street, d.city ? `${d.postalCode ?? ''} ${d.city}` : undefined].filter(Boolean).join('\n') },
16
+ { label: t('imprint.registry'), value: [d.registryCourt, d.registryNumber].filter(Boolean).join(', ') },
17
+ { label: t('imprint.vat'), value: d.vatId },
18
+ { label: t('imprint.email'), value: d.email, href: d.email ? `mailto:${d.email}` : undefined },
19
+ { label: t('imprint.phone'), value: d.phone, href: d.phone ? telHref(d.phone) : undefined },
20
+ ]
21
+ return rows.filter((row) => row.value)
22
+ })
23
+ usePageSeo(() => ({ title: entry.value.data.title, description: entry.value.data.description }))
24
+ </script>
25
+
26
+ <template>
27
+ <div>
28
+ <BlockPageHeader
29
+ :title="entry.data.title"
30
+ :lead="entry.data.description"
31
+ :meta="t('updated', { date: format.date(entry.data.updatedAt) })"
32
+ />
33
+ <!-- Each value keeps the direction of its own text (bdi), as in the footer. A link gets its 44 px tap height from
34
+ padding with a negative margin, so it stays on its label's line. -->
35
+ <dl v-if="details.length" class="mx-auto grid max-w-page gap-x-8 gap-y-1 px-gutter pb-10 sm:grid-cols-[auto_1fr] sm:gap-y-3">
36
+ <template v-for="row in details" :key="row.label">
37
+ <dt class="text-small text-muted-foreground max-sm:not-first:mt-3">{{ row.label }}</dt>
38
+ <dd class="whitespace-pre-line">
39
+ <a v-if="row.href" :href="row.href" dir="ltr" class="-my-2.5 inline-block py-2.5 underline underline-offset-4">{{ row.value }}</a>
40
+ <bdi v-else>{{ row.value }}</bdi>
41
+ </dd>
42
+ </template>
43
+ </dl>
44
+ <ProseBody :value="entry.data.body" />
45
+ </div>
46
+ </template>
@@ -0,0 +1,94 @@
1
+ <!-- Synced from templates/_features/blog/app/pages/news/[slug].vue by `pnpm templates sync`. Edit the source, not this copy. -->
2
+ <script setup lang="ts">
3
+ import type { Component } from 'vue'
4
+ import { postJsonLd } from '@lupinum/ginko/basics'
5
+ import { ArrowLeft, ArrowRight } from '@lucide/vue'
6
+
7
+ // One post: title, summary, date and reading time, authors (initials and role, linked to their page when people have
8
+ // one), cover (3:2), text and tags (linked to their pages), with BlogPosting JSON-LD; then the older and the newer
9
+ // post and a link to all news, so a visitor who comes from a share or the feed does not end above the footer. A template
10
+ // may bring `app/components/site/PageCta.vue`, its closing band: it shows at the end of the post.
11
+ const cta = Object.values(import.meta.glob<Component>('../../components/site/PageCta.vue', { eager: true, import: 'default' }))[0]
12
+ const route = useRoute()
13
+ const entry = useGinkoEntry('posts', () => route.params.slug)
14
+ const posts = useBlogPosts()
15
+ const tagPath = useTagPath()
16
+ const path = useGinkoPath()
17
+ const { url } = useGinkoSite()
18
+ const { t, format, language } = useI18n('blog')
19
+ // Read the entry first: it answers 404 for an unknown or hidden slug, also in a language whose list is empty (there
20
+ // `find` never calls its callback). Past that line the entry is visible, so the list has it.
21
+ const index = computed(() => {
22
+ const id = entry.value.id
23
+ return posts.value.findIndex((item) => item.id === id)
24
+ })
25
+ const post = computed(() => posts.value[index.value]!)
26
+ // The list is newest first: the newer post comes before this one, the older one after it.
27
+ const newer = computed(() => posts.value[index.value - 1])
28
+ const older = computed(() => posts.value[index.value + 1])
29
+ const absolute = (path: string) => new URL(path, url).href
30
+ usePageSeo(() => ({
31
+ title: post.value.title,
32
+ description: post.value.description,
33
+ image: post.value.image,
34
+ jsonLd: [postJsonLd({
35
+ title: post.value.title,
36
+ url: absolute(route.path),
37
+ date: post.value.date,
38
+ modified: entry.value.updatedAt,
39
+ description: post.value.description,
40
+ image: post.value.image ? absolute(post.value.image.url) : undefined,
41
+ authors: post.value.authors.map((author) => ({ name: author.name, url: author.to ? absolute(author.to) : undefined })),
42
+ tags: post.value.tags,
43
+ lang: language.value,
44
+ })],
45
+ }))
46
+ </script>
47
+
48
+ <template>
49
+ <div>
50
+ <article>
51
+ <BlockPageHeader :title="post.title" :lead="post.description">
52
+ <p class="text-small text-muted-foreground tabular-nums">
53
+ <time :datetime="post.date">{{ format.date(post.date) }}</time>
54
+ <template v-if="post.minutes"><span aria-hidden="true"> · </span><span class="sr-only">, </span>{{ t('minutes', { count: post.minutes }) }}</template>
55
+ </p>
56
+ <BlogByline :authors="post.authors" />
57
+ </BlockPageHeader>
58
+ <div v-if="post.image" class="mx-auto max-w-page px-gutter pb-10">
59
+ <GinkoImage :image="post.image" eager sizes="(min-width: 1216px) 896px, 100vw" class="aspect-3/2 w-full max-w-4xl rounded-block bg-muted object-cover" />
60
+ </div>
61
+ <ProseBody :value="entry.data.body" />
62
+ <div v-if="post.tags.length" class="mx-auto max-w-page px-gutter pt-10">
63
+ <h2 class="sr-only">{{ t('tags') }}</h2>
64
+ <ul class="flex flex-wrap gap-2">
65
+ <li v-for="tag in post.tags" :key="tag">
66
+ <NuxtLink :to="tagPath(tag)" rel="tag" class="inline-flex min-h-11 items-center rounded-md border px-4 text-small transition-[color,background-color,border-color] duration-150 hover:bg-accent">{{ tagLabel(tag) }}</NuxtLink>
67
+ </li>
68
+ </ul>
69
+ </div>
70
+ <nav v-if="older || newer" :aria-label="t('pager')" class="mx-auto max-w-page px-gutter pt-10">
71
+ <ul class="grid max-w-4xl gap-3 sm:grid-cols-2">
72
+ <li v-if="older">
73
+ <NuxtLink :to="older.to" rel="prev" class="flex h-full min-h-11 flex-col gap-1 rounded-block border p-5 transition-colors duration-150 hover:bg-accent">
74
+ <span class="inline-flex items-center gap-2 text-small text-muted-foreground"><ArrowLeft class="size-4 rtl:-scale-x-100" aria-hidden="true" />{{ t('older') }}</span>
75
+ <span class="font-medium">{{ older.title }}</span>
76
+ </NuxtLink>
77
+ </li>
78
+ <li v-if="newer" class="sm:col-start-2">
79
+ <NuxtLink :to="newer.to" rel="next" class="flex h-full min-h-11 flex-col items-end gap-1 rounded-block border p-5 text-end transition-colors duration-150 hover:bg-accent">
80
+ <span class="inline-flex items-center gap-2 text-small text-muted-foreground">{{ t('newer') }}<ArrowRight class="size-4 rtl:-scale-x-100" aria-hidden="true" /></span>
81
+ <span class="font-medium">{{ newer.title }}</span>
82
+ </NuxtLink>
83
+ </li>
84
+ </ul>
85
+ </nav>
86
+ <div class="mx-auto max-w-page px-gutter pt-10">
87
+ <NuxtLink :to="path('news')" class="inline-flex min-h-11 items-center gap-2 font-medium text-primary underline-offset-4 hover:underline">
88
+ {{ t('latest') }}<ArrowRight class="size-4 rtl:-scale-x-100" aria-hidden="true" />
89
+ </NuxtLink>
90
+ </div>
91
+ </article>
92
+ <component :is="cta" v-if="cta" />
93
+ </div>
94
+ </template>
@@ -0,0 +1,54 @@
1
+ <!-- Synced from templates/_features/blog/app/pages/news/index.vue by `pnpm templates sync`. Edit the source, not this copy. -->
2
+ <script setup lang="ts">
3
+ import { Rss } from '@lucide/vue'
4
+ import type { BlogPost } from '~/composables/useBlog'
5
+
6
+ // The news: every post, newest first (content/posts/), grouped by year once they span more than one, with the tags
7
+ // as links to their pages above them. The feed of this language is linked in the head and below the list. The address
8
+ // per language comes from `pages.news` in ginko.config.ts.
9
+ const posts = useBlogPosts()
10
+ const tags = useBlogTags()
11
+ const feed = useFeedPath()
12
+ const route = useRoute()
13
+ const { name, url } = useGinkoSite()
14
+ const { t, language } = useI18n('blog')
15
+ const years = computed(() => {
16
+ const groups: { year: string, posts: BlogPost[] }[] = []
17
+ for (const post of posts.value) {
18
+ const year = post.date.slice(0, 4)
19
+ if (groups.at(-1)?.year === year) groups.at(-1)!.posts.push(post)
20
+ else groups.push({ year, posts: [post] })
21
+ }
22
+ return groups
23
+ })
24
+ useHead(() => ({ link: [{ rel: 'alternate', type: 'application/rss+xml', title: t('feed'), href: feed.value }] }))
25
+ usePageSeo(() => ({
26
+ title: t('title'),
27
+ description: t('lead'),
28
+ jsonLd: [{ '@context': 'https://schema.org', '@type': 'Blog', name: `${name}: ${t('title')}`, description: t('lead'), url: new URL(route.path, url).href, inLanguage: language.value }],
29
+ }))
30
+ </script>
31
+
32
+ <template>
33
+ <div>
34
+ <BlockPageHeader :title="t('title')" :lead="t('lead')" />
35
+ <div class="mx-auto max-w-page px-gutter">
36
+ <div class="max-w-4xl">
37
+ <nav v-if="tags.length" :aria-label="t('tags')" class="pb-8">
38
+ <BlogTagList :tags="tags" />
39
+ </nav>
40
+ <template v-if="years.length > 1">
41
+ <section v-for="group in years" :key="group.year" :aria-labelledby="`year-${group.year}`" class="pt-6 first:pt-0">
42
+ <h2 :id="`year-${group.year}`" class="pb-2 text-h3 tabular-nums">{{ group.year }}</h2>
43
+ <BlogPostList :items="group.posts" heading-level="h3" />
44
+ </section>
45
+ </template>
46
+ <BlogPostList v-else-if="posts.length" :items="posts" />
47
+ <BlockEmpty v-else :title="t('empty')" path="content/posts/" />
48
+ <a :href="feed" class="mt-6 inline-flex min-h-11 items-center gap-2 text-small text-muted-foreground underline-offset-4 hover:text-foreground hover:underline">
49
+ <Rss class="size-4" aria-hidden="true" />{{ t('feed') }}
50
+ </a>
51
+ </div>
52
+ </div>
53
+ </div>
54
+ </template>
@@ -0,0 +1,41 @@
1
+ <!-- Synced from templates/_features/blog/app/pages/news/tags/[tag].vue by `pnpm templates sync`. Edit the source, not this copy. -->
2
+ <script setup lang="ts">
3
+ import { ArrowRight } from '@lucide/vue'
4
+
5
+ // One tag: the posts that carry it, newest first. Tags are free text in each language's files, so a tag has no
6
+ // translation: the page names only its own language as alternate (a link to another language's news page would be a
7
+ // false hreflang), so the switch shows it as not translated. A tag no visible post carries is a 404. The address is
8
+ // the news page's, then the word for `tags` in app/routes.ts (`segments`), then the tag.
9
+ definePageMeta({
10
+ i18nAlternates: (to, { locale }) => ({ [locale]: to.path }),
11
+ })
12
+ const route = useRoute()
13
+ const posts = useBlogPosts()
14
+ const tags = useBlogTags()
15
+ const path = useGinkoPath()
16
+ const { t } = useI18n('blog')
17
+ const slug = computed(() => String(route.params.tag))
18
+ // Thrown on every read while no post carries the tag, like useGinkoEntry: fatal, so client navigation shows the 404.
19
+ const tag = toRef(() => {
20
+ const found = tags.value.find((item) => item.slug === slug.value)
21
+ if (!found) throw createError({ statusCode: 404, statusMessage: 'Not found', fatal: true })
22
+ return found
23
+ })
24
+ const tagged = computed(() => posts.value.filter((post) => post.tags.some((name) => tagSlug(name) === tag.value.slug)))
25
+ const title = computed(() => t('tagged', { tag: tag.value.name }))
26
+ usePageSeo(() => ({ title: title.value, description: t('count', { count: tag.value.count }) }))
27
+ </script>
28
+
29
+ <template>
30
+ <div>
31
+ <BlockPageHeader :title="title" :meta="t('count', { count: tag.count })" />
32
+ <div class="mx-auto max-w-page px-gutter">
33
+ <div class="max-w-4xl">
34
+ <BlogPostList :items="tagged" />
35
+ <NuxtLink :to="path('news')" class="mt-6 inline-flex min-h-11 items-center gap-2 font-medium text-primary underline-offset-4 hover:underline">
36
+ {{ t('all') }}<ArrowRight class="size-4 rtl:-scale-x-100" aria-hidden="true" />
37
+ </NuxtLink>
38
+ </div>
39
+ </div>
40
+ </div>
41
+ </template>