From bcca176137293e13659ae51efb52961fff8fed98 Mon Sep 17 00:00:00 2001 From: Basiclean <> Date: Sat, 2 May 2026 10:41:00 +0200 Subject: [PATCH] Initial commit --- .gitignore | 41 + AGENTS.md | 5 + CLAUDE.md | 1 + README.md | 36 + app/apple-icon.png | Bin 0 -> 2609 bytes app/datenschutz/page.tsx | 8 + app/error.module.css | 74 + app/error.tsx | 53 + app/favicon.ico | Bin 0 -> 15086 bytes app/globals.css | 58 + app/icon0.svg | 1 + app/icon1.png | Bin 0 -> 1548 bytes app/impressum/page.tsx | 8 + app/layout.tsx | 104 + app/loading.tsx | 7 + app/manifest.json | 21 + app/not-found.module.css | 67 + app/not-found.tsx | 32 + app/page.module.css | 0 app/page.tsx | 192 + app/robots.ts | 21 + app/sitemap.ts | 70 + app/test-error/page.tsx | 5 + app/ueberuns/page.module.css | 0 app/ueberuns/page.tsx | 8 + components/CookieConsent.module.css | 33 + components/CookieConsent.tsx | 95 + components/Footer.module.css | 154 + components/Footer.tsx | 106 + components/Header.module.css | 10 + components/Header.tsx | 10 + components/Navbar/Navbar.module.css | 219 + components/Navbar/Navbar.tsx | 151 + components/Navbar/NavbarSubMenu.module.css | 104 + components/Navbar/NavbarSubMenu.tsx | 106 + data/navigation.ts | 52 + eslint.config.mjs | 18 + hooks/useHeightVar.ts | 29 + hooks/useIsDesktop.ts | 25 + hooks/useNavToggleMenu.ts | 95 + hooks/useSupportsHover.ts | 25 + hooks/useToggleBodyOverflow.ts | 25 + next.config.ts | 12 + package-lock.json | 5968 +++++++++++++++++ package.json | 26 + public/favicon/web-app-manifest-192x192.png | Bin 0 -> 2821 bytes public/favicon/web-app-manifest-512x512.png | Bin 0 -> 12791 bytes public/fonts/nunito-sans-v19-latin-200.woff2 | Bin 0 -> 13440 bytes .../nunito-sans-v19-latin-200italic.woff2 | Bin 0 -> 13868 bytes public/fonts/nunito-sans-v19-latin-300.woff2 | Bin 0 -> 13764 bytes .../nunito-sans-v19-latin-300italic.woff2 | Bin 0 -> 14556 bytes public/fonts/nunito-sans-v19-latin-500.woff2 | Bin 0 -> 13968 bytes .../nunito-sans-v19-latin-500italic.woff2 | Bin 0 -> 14748 bytes public/fonts/nunito-sans-v19-latin-600.woff2 | Bin 0 -> 14008 bytes .../nunito-sans-v19-latin-600italic.woff2 | Bin 0 -> 14900 bytes public/fonts/nunito-sans-v19-latin-700.woff2 | Bin 0 -> 13836 bytes .../nunito-sans-v19-latin-700italic.woff2 | Bin 0 -> 14604 bytes public/fonts/nunito-sans-v19-latin-800.woff2 | Bin 0 -> 13876 bytes .../nunito-sans-v19-latin-800italic.woff2 | Bin 0 -> 14764 bytes public/fonts/nunito-sans-v19-latin-900.woff2 | Bin 0 -> 14056 bytes .../nunito-sans-v19-latin-900italic.woff2 | Bin 0 -> 14820 bytes .../fonts/nunito-sans-v19-latin-italic.woff2 | Bin 0 -> 14684 bytes .../fonts/nunito-sans-v19-latin-regular.woff2 | Bin 0 -> 13892 bytes public/fonts/poppins-v24-latin-100.woff2 | Bin 0 -> 7484 bytes .../fonts/poppins-v24-latin-100italic.woff2 | Bin 0 -> 8404 bytes public/fonts/poppins-v24-latin-200.woff2 | Bin 0 -> 7932 bytes .../fonts/poppins-v24-latin-200italic.woff2 | Bin 0 -> 8720 bytes public/fonts/poppins-v24-latin-300.woff2 | Bin 0 -> 7840 bytes .../fonts/poppins-v24-latin-300italic.woff2 | Bin 0 -> 8712 bytes public/fonts/poppins-v24-latin-500.woff2 | Bin 0 -> 7748 bytes .../fonts/poppins-v24-latin-500italic.woff2 | Bin 0 -> 8504 bytes public/fonts/poppins-v24-latin-600.woff2 | Bin 0 -> 8000 bytes .../fonts/poppins-v24-latin-600italic.woff2 | Bin 0 -> 8724 bytes public/fonts/poppins-v24-latin-700.woff2 | Bin 0 -> 7816 bytes .../fonts/poppins-v24-latin-700italic.woff2 | Bin 0 -> 8596 bytes public/fonts/poppins-v24-latin-800.woff2 | Bin 0 -> 7824 bytes .../fonts/poppins-v24-latin-800italic.woff2 | Bin 0 -> 8680 bytes public/fonts/poppins-v24-latin-900.woff2 | Bin 0 -> 7632 bytes .../fonts/poppins-v24-latin-900italic.woff2 | Bin 0 -> 8488 bytes public/fonts/poppins-v24-latin-italic.woff2 | Bin 0 -> 8668 bytes public/fonts/poppins-v24-latin-regular.woff2 | Bin 0 -> 7884 bytes public/images/envu.png | Bin 0 -> 20673 bytes public/logo/logo.svg | 1 + styles/buttons.css | 244 + styles/forms.css | 235 + styles/tokens.css | 34 + styles/typography.css | 102 + tsconfig.json | 34 + 88 files changed, 8725 insertions(+) create mode 100644 .gitignore create mode 100644 AGENTS.md create mode 100644 CLAUDE.md create mode 100644 README.md create mode 100644 app/apple-icon.png create mode 100644 app/datenschutz/page.tsx create mode 100644 app/error.module.css create mode 100644 app/error.tsx create mode 100644 app/favicon.ico create mode 100644 app/globals.css create mode 100644 app/icon0.svg create mode 100644 app/icon1.png create mode 100644 app/impressum/page.tsx create mode 100644 app/layout.tsx create mode 100644 app/loading.tsx create mode 100644 app/manifest.json create mode 100644 app/not-found.module.css create mode 100644 app/not-found.tsx create mode 100644 app/page.module.css create mode 100644 app/page.tsx create mode 100644 app/robots.ts create mode 100644 app/sitemap.ts create mode 100644 app/test-error/page.tsx create mode 100644 app/ueberuns/page.module.css create mode 100644 app/ueberuns/page.tsx create mode 100644 components/CookieConsent.module.css create mode 100644 components/CookieConsent.tsx create mode 100644 components/Footer.module.css create mode 100644 components/Footer.tsx create mode 100644 components/Header.module.css create mode 100644 components/Header.tsx create mode 100644 components/Navbar/Navbar.module.css create mode 100644 components/Navbar/Navbar.tsx create mode 100644 components/Navbar/NavbarSubMenu.module.css create mode 100644 components/Navbar/NavbarSubMenu.tsx create mode 100644 data/navigation.ts create mode 100644 eslint.config.mjs create mode 100644 hooks/useHeightVar.ts create mode 100644 hooks/useIsDesktop.ts create mode 100644 hooks/useNavToggleMenu.ts create mode 100644 hooks/useSupportsHover.ts create mode 100644 hooks/useToggleBodyOverflow.ts create mode 100644 next.config.ts create mode 100644 package-lock.json create mode 100644 package.json create mode 100644 public/favicon/web-app-manifest-192x192.png create mode 100644 public/favicon/web-app-manifest-512x512.png create mode 100644 public/fonts/nunito-sans-v19-latin-200.woff2 create mode 100644 public/fonts/nunito-sans-v19-latin-200italic.woff2 create mode 100644 public/fonts/nunito-sans-v19-latin-300.woff2 create mode 100644 public/fonts/nunito-sans-v19-latin-300italic.woff2 create mode 100644 public/fonts/nunito-sans-v19-latin-500.woff2 create mode 100644 public/fonts/nunito-sans-v19-latin-500italic.woff2 create mode 100644 public/fonts/nunito-sans-v19-latin-600.woff2 create mode 100644 public/fonts/nunito-sans-v19-latin-600italic.woff2 create mode 100644 public/fonts/nunito-sans-v19-latin-700.woff2 create mode 100644 public/fonts/nunito-sans-v19-latin-700italic.woff2 create mode 100644 public/fonts/nunito-sans-v19-latin-800.woff2 create mode 100644 public/fonts/nunito-sans-v19-latin-800italic.woff2 create mode 100644 public/fonts/nunito-sans-v19-latin-900.woff2 create mode 100644 public/fonts/nunito-sans-v19-latin-900italic.woff2 create mode 100644 public/fonts/nunito-sans-v19-latin-italic.woff2 create mode 100644 public/fonts/nunito-sans-v19-latin-regular.woff2 create mode 100644 public/fonts/poppins-v24-latin-100.woff2 create mode 100644 public/fonts/poppins-v24-latin-100italic.woff2 create mode 100644 public/fonts/poppins-v24-latin-200.woff2 create mode 100644 public/fonts/poppins-v24-latin-200italic.woff2 create mode 100644 public/fonts/poppins-v24-latin-300.woff2 create mode 100644 public/fonts/poppins-v24-latin-300italic.woff2 create mode 100644 public/fonts/poppins-v24-latin-500.woff2 create mode 100644 public/fonts/poppins-v24-latin-500italic.woff2 create mode 100644 public/fonts/poppins-v24-latin-600.woff2 create mode 100644 public/fonts/poppins-v24-latin-600italic.woff2 create mode 100644 public/fonts/poppins-v24-latin-700.woff2 create mode 100644 public/fonts/poppins-v24-latin-700italic.woff2 create mode 100644 public/fonts/poppins-v24-latin-800.woff2 create mode 100644 public/fonts/poppins-v24-latin-800italic.woff2 create mode 100644 public/fonts/poppins-v24-latin-900.woff2 create mode 100644 public/fonts/poppins-v24-latin-900italic.woff2 create mode 100644 public/fonts/poppins-v24-latin-italic.woff2 create mode 100644 public/fonts/poppins-v24-latin-regular.woff2 create mode 100644 public/images/envu.png create mode 100644 public/logo/logo.svg create mode 100644 styles/buttons.css create mode 100644 styles/forms.css create mode 100644 styles/tokens.css create mode 100644 styles/typography.css create mode 100644 tsconfig.json diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..5ef6a52 --- /dev/null +++ b/.gitignore @@ -0,0 +1,41 @@ +# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. + +# dependencies +/node_modules +/.pnp +.pnp.* +.yarn/* +!.yarn/patches +!.yarn/plugins +!.yarn/releases +!.yarn/versions + +# testing +/coverage + +# next.js +/.next/ +/out/ + +# production +/build + +# misc +.DS_Store +*.pem + +# debug +npm-debug.log* +yarn-debug.log* +yarn-error.log* +.pnpm-debug.log* + +# env files (can opt-in for committing if needed) +.env* + +# vercel +.vercel + +# typescript +*.tsbuildinfo +next-env.d.ts diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..8bd0e39 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,5 @@ + +# This is NOT the Next.js you know + +This version has breaking changes — APIs, conventions, and file structure may all differ from your training data. Read the relevant guide in `node_modules/next/dist/docs/` before writing any code. Heed deprecation notices. + diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..43c994c --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1 @@ +@AGENTS.md diff --git a/README.md b/README.md new file mode 100644 index 0000000..e215bc4 --- /dev/null +++ b/README.md @@ -0,0 +1,36 @@ +This is a [Next.js](https://nextjs.org) project bootstrapped with [`create-next-app`](https://nextjs.org/docs/app/api-reference/cli/create-next-app). + +## Getting Started + +First, run the development server: + +```bash +npm run dev +# or +yarn dev +# or +pnpm dev +# or +bun dev +``` + +Open [http://localhost:3000](http://localhost:3000) with your browser to see the result. + +You can start editing the page by modifying `app/page.tsx`. The page auto-updates as you edit the file. + +This project uses [`next/font`](https://nextjs.org/docs/app/building-your-application/optimizing/fonts) to automatically optimize and load [Geist](https://vercel.com/font), a new font family for Vercel. + +## Learn More + +To learn more about Next.js, take a look at the following resources: + +- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API. +- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial. + +You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js) - your feedback and contributions are welcome! + +## Deploy on Vercel + +The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js. + +Check out our [Next.js deployment documentation](https://nextjs.org/docs/app/building-your-application/deploying) for more details. diff --git a/app/apple-icon.png b/app/apple-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..f43af62e1e469df93b052c8b6208c9a77ec13065 GIT binary patch literal 2609 zcmeH}`#%$o8pkK)&X=#;*7w_1kr>ucBDa>?w%Q7jOSCd9Y%Y_QiZs&KtuezCElE4V zx0!A<-_LMpV#wxKhNiRy`G<*TPM)&>MB4L z005wl@Nn_mRL(y_NntZPd{VI76lap_X_6N)l$3yt#Q{8V*hn|*Mf`ap!5v4y#bQas zSn$4Z5-B>)4hoIkq@n+$VgIHU1RTkvsK{p+08oC6a5>_ADQNmG>Nc%Q=RKx1D4b$yCb$C}v3SYs(PBl?q0m6s>Z{kTrQ zz0$pcJm_PfJvw}zDUV1tP)Nhqn<(z3eMo4WE$LW3JXj-I9*Aq3m3>EHtopqwZFV-v zZ$T?{YW5&AXi4NL}1Oti+3L%nK+rck?={OX8WOOxNz$cM23XtNO#6;ZB zlpXVJj8QI6+xSDr_l>i{-ggDTI^LD5ZzCM#TITm<@tH?xM#;mDGReFGtLwsrs9?v$ z>cyp{aYq@kX5DrR@ecSg;;RH_D@T0c{A6Bd^R9iI>iwQNZ1{BQwvZYW4qG zF5lbR6S9DUx*T>m*w|T)_7`_!U20uc?*-5;=wwl=MWAa&@JCN$2**c1)f{Gb?~(QQ zk}LijE3KF72pK;sx=!c9iM`yTy5{xABfbgl1h@dFRk5fM+{u8Ev6B~a3{!;~d+Ic^ zMVKIFLElTHw?gm7&!LgUk+_<*Gp{pBUy? z`@n;plB&)8IA9hyx1L$m?#wFG3^+Eff|9AS6NBm~0O zAn7BNUM&eF-M=2}U0C857b4q`t9`iHPf%mlDeKugc^8(-Vy~|+Cnc)*eBwHA8mElM z18(tGpBGK5=zJ4J%+Qye*4^1syiMA_7LaQ1jQt`cOCaf^iO-CU7t^w!EwdoMO4~SA zTic$@d_KnEsn5e>jKb~hqm-vyY%X%7F!Wn{k$FpjnFirAQf!ZTI)vR~115p@w~Ucf zC;ID9)g_<}7p1%A#3W`sTxe`!{fy%gFwy}D0G6KPt?{|#UbGiH73Ko4tO1&~pW*pl zjFHE(;l8W%Y@?Q@Vq(-4%WGjI;<+WgS5Ig}@i6uP(Lnv4YkObA92rj}LNB*crB7DN z&Ef=5TerQy!?f_HE{+~3`VQYd3t5i@KTN2TK>E7V<#Vs`V6ptJ1Sxu8ZDtx&zdXOC4SWG^m!l~jbR zujJ*4p&0FQUAy+zQ**}w%&X%8FD5i!#!}aI>i_2j(wroHO_&(GvPhiHV%Q&b!@PPm z_l9lFO;3y-&xjo=yNNP7CCZT**1;<1e;cQMqNBx9qD3x~3$>J+ogvrlN@&0&g_!g# zPnP@9^UocxN=zXgPh@X@rD5X-WGW7{1201Eo!%{C|7@m>A6kp=0{_aKZc|@3y;NLc;`#Tw4Ew+F# zj<9}KSi}q9?`h<2Ms`O{ezsMC8`Yz%abK1RD3{&IQ>ijRWjb50dHsZaoP+7R;YSOP znwpUEj!>N?2aoHqLgeJXNY!D|#f;OjmMraGHRI@BD5UtIN@Cx^S^Od+I!0LhRO zDE~&OV`aWOtIbuc7Nb71jv7f4?fm#BdnMQYdh}t?n4?6oGNf}9lA)+IM;RrAqp+GU zpCicnx;2;AwN1@QLxw)UTCUZcY5yetRFvG)EG zs?w-&*Pz;`cdZf4fs2&;u%+gJtSrovL)XFs6@br?dq{CB66cylV$qJbZ!FWLL~}ax zYU#G60?F5Eln_<5Kp|c1>IB6F@DugFP1o zwC2X}oC5Z;K;;aw$GQp)V0LMFz0L)|0|XE0c5)OS_hWLXElN>{V*kmln*P7TwwWn| zIYv +

Datenschutz

+ + ); +} diff --git a/app/error.module.css b/app/error.module.css new file mode 100644 index 0000000..c2b8c7a --- /dev/null +++ b/app/error.module.css @@ -0,0 +1,74 @@ +.wrapper { + position: relative; + display: flex; + align-items: center; + justify-content: center; + min-height: 80dvh; + padding: 0 var(--space-4); + overflow: hidden; + background-color: var(--color-background); + width: 100%; +} + +.ghost { + position: absolute; + inset: 0; + display: flex; + align-items: center; + justify-content: center; + font-size: clamp(12rem, 40vw, 28rem); + font-weight: 900; + line-height: 1; + letter-spacing: -0.05em; + user-select: none; + pointer-events: none; + color: transparent; + -webkit-text-stroke: 1px rgba(23, 23, 23, 0.06); +} + +.content { + position: relative; + z-index: 1; + text-align: center; + width: 100%; +} + +.label { + font-size: var(--font-size-small); + font-weight: var(--font-weight-semibold); + letter-spacing: var(--letter-spacing-wide); + text-transform: uppercase; + color: var(--color-text-soft); + margin-bottom: var(--space-4); +} + +.heading { + margin-bottom: var(--space-4); +} + +.description { + color: var(--color-text-muted); + margin-bottom: var(--space-7); + max-width: 38ch; + margin-inline: auto; +} + +.cta { + gap: var(--btn-gap); +} + +.actions { + display: flex; + flex-wrap: wrap; + justify-content: center; + gap: var(--space-4); +} + +@media (min-width: 768px) { +} + +@media (min-width: 1024px) { + .wrapper { + padding: 0 var(--space-6); + } +} diff --git a/app/error.tsx b/app/error.tsx new file mode 100644 index 0000000..8fa29f6 --- /dev/null +++ b/app/error.tsx @@ -0,0 +1,53 @@ +"use client"; + +import { useEffect } from "react"; +import Link from "next/link"; +import styles from "./error.module.css"; +import { + ArrowCounterClockwiseIcon, + ArrowLeftIcon, +} from "@phosphor-icons/react/dist/ssr"; + +interface ErrorProps { + error: Error & { digest?: string }; + reset: () => void; +} + +export default function Error({ error, reset }: ErrorProps) { + useEffect(() => { + console.error(error); + }, [error]); + + return ( +
+ + +
+

Serverfehler

+

Etwas ist schiefgelaufen

+

+ Ein unerwarteter Fehler ist aufgetreten. Bitte versuche es erneut oder + komm später zurück. +

+ +
+ + + + + Zurück zur Startseite + +
+
+
+ ); +} diff --git a/app/favicon.ico b/app/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..9dc61f5925c27589082c6fa21ada9b550574de8f GIT binary patch literal 15086 zcmeHNL2FY%5FSaZ6 zPbi2XhvMr@li|(V?7rPi_R+MRz;<_MzWL^RUqV{83vdHE(C-7z8GOAD@B{#|Y`*UT z{J~fkXUf0d0QiJ}2Z+HEc!z`H`cenf0d+tfPzSE61G_&a+q*yimF9?jUb8;s{>9N` z$EL^E!&YO9`FK+0W$#c~#%A2uV>!d$cJKJc#c=PI6+2)9SCYKf)j|-bRJ{$}-ZT-!dudl@Wu&ML1 zw{0ETk80oU?>q{{r^MNGQ!J*(>-_QE7<@`>3jHbd#B!C4-TN?>(xd+ zg?{E}Lthgo_jS!pwK6B`WxUO`?Af&TX|UA}_wp@Y-70xo&!(8I*YM@jdrdW(QwP)m zbwC|Z2QGsH<@pO>)p`7J3UCXc$WH*TE5WEYri(`acZ!(}fiu??Io2Z&^Tz7K>fV3S zgQ`wR56)B4gRH19Y)1TOURU6g5YKqd8>`2Kr+Zo%j^{Y^o)(&*FLj{70rP(-4bbzH ziI3e&epju;$h8X}8z)X*jqDqO_wmK%wSV1#SpR(ZruVeox!UMO+RpF_!ITbmke7>%g|*Uf?1`N87P<5TDyPVwk~4mHG}80E~00`lV#^bYYj0}HA_ zG0K^E-qSfn7e|KUs-IKv-=g@awHL=-Gl9(<6PWSPeQdqdz_m1o+^v-Oi(H$(1I)d7 zhlcZ{nb*FVpU;PLD; FKLe?iB76V< literal 0 HcmV?d00001 diff --git a/app/globals.css b/app/globals.css new file mode 100644 index 0000000..785b825 --- /dev/null +++ b/app/globals.css @@ -0,0 +1,58 @@ +@import "../styles/tokens.css"; +@import "../styles/buttons.css"; +@import "../styles/forms.css"; +@import "../styles/typography.css"; + +*, +*::before, +*::after { + box-sizing: border-box; + margin: 0; + padding: 0; +} + +html { + height: 100%; + font-size: 112.5%; /* 16px × 1.125 = 18px */ +} +html.has-menu-open { + scrollbar-gutter: stable; +} + +html, +body { + max-width: 100vw; +} + +body { + min-height: 100%; + display: flex; + flex-direction: column; + color: var(--font-body-color); + background: var(--color-background); + font-family: var(--font-body); + font-size: 1rem; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + line-height: var(--line-height-body); + -webkit-tap-highlight-color: transparent; +} + +main { + width: 100%; + max-width: 1280px; + margin-inline: auto; + padding: 0 var(--space-4); +} + +@media (min-width: 768px) { + main { + padding: 0 var(--space-4); + } +} + +@media (min-width: 1024px) { + main { + padding: 0 var(--space-6); + } +} diff --git a/app/icon0.svg b/app/icon0.svg new file mode 100644 index 0000000..3341939 --- /dev/null +++ b/app/icon0.svg @@ -0,0 +1 @@ +RealFaviconGeneratorhttps://realfavicongenerator.net \ No newline at end of file diff --git a/app/icon1.png b/app/icon1.png new file mode 100644 index 0000000000000000000000000000000000000000..ce24111f5402a4f8090169b3a218083491c67f1d GIT binary patch literal 1548 zcmV+n2J`ueP)GlZe?^SnVDAM000GtNkl*mCY-94I3oTL#0d!`4qOW208%RKxN)h7N<@X=0w)wcR3wCyRw59)De(?( zgVyp#cW2(tKF`{IJ+;o8H*bEwnYCxejTHRHDFNxUckW!U0LPPn1+W0e1RQtID}V(! zCg8YxUI8q?F#*Tj^9o=AjtMyKo>u@1a7@5)_q+mFfMWuVyXO_a0vr=?+&!;=vXKf=zAVTq3mpF+Y!CVTQ~<@0Snch?ChoQnPnr=q!GfofXk z!R}6eYip}%8Xp#y$fHP!Tkt9DSkOn`5j1r23;gg=+hWtw9%g<9YDw(4#Ztm0sOR-g zHlutgFKiz>Nv;IrOZnbTEsZ-_2vp$v*etC44G;0@s6py#8TnfRYXn}fPh62$^s~;B66|-1T2bB7C=E2k&^`= zU{Qo>1?*LenxkCx`&9Yr!xY8!=G50Rh$?V>OqJ`Aj6;8j9V{ej<;!)F%N%SiI7EYq z4inKQps`-uR!Te;w=A7;Y~E3TABj--m_N8=r&(_3d*L zjhzSY+SZc7_6NXcqAex(OS5+Nyytm|UCP@^7^RutI|;H0yc*Ns0JKIK(lh@v?tY-qQ${QOd%~*g5C1gx~w~?2xn0+yp1t8&?gk#=>n^(@9@LK9O zlf0u6BO8_CtdinussUjHP;LsT#%GfkzP5deb|a?5-KoX;B&Nu5dJJ{!gy-Qu$0Yyj zYOu3E5H%hWl!A+_4B25EB;JM#nvKTZO=4&(fR!zD}xE@Kk=m1S{f|2Rmm)?srYdhQ6!XIS`Qe@uBm#@4VjIr-ZQho8l(MD$auecJDf +

impressum

+ + ); +} diff --git a/app/layout.tsx b/app/layout.tsx new file mode 100644 index 0000000..a9e4c5f --- /dev/null +++ b/app/layout.tsx @@ -0,0 +1,104 @@ +import CookieConsentBanner from "@/components/CookieConsent"; +import type { Metadata, Viewport } from "next"; +import { Manrope, Nunito_Sans } from "next/font/google"; +import "./globals.css"; + +import Footer from "@/components/Footer"; +import Header from "@/components/Header"; + +const nunitoSans = Nunito_Sans({ + subsets: ["latin"], + weight: ["400", "600", "700"], + variable: "--font-body", + display: "swap", +}); + +const manrope = Manrope({ + subsets: ["latin"], + weight: ["400", "500", "600", "700"], + variable: "--font-heading", + display: "swap", +}); + +export const viewport: Viewport = { + width: "device-width", + initialScale: 1, +}; + +const siteName = "ENVU"; +const title = "ENVU - Code Connect"; +const description = "Wir bieten Ihnen maßgeschneiderte Lösungen."; +const siteUrl = "https://envu.de"; + +const ogImage = { + url: "/images/envu.png", + alt: "Envu Wallpaper", + width: 1200, + height: 628, +}; + +export const metadata: Metadata = { + metadataBase: new URL(siteUrl), + title: { + default: title, + template: `%s | ${siteName}`, + }, + description, + keywords: "Envu, Hannover", + authors: [{ name: siteName }], + robots: "index, follow", + alternates: { + canonical: siteUrl, + }, + appleWebApp: { + title: siteName, + }, + openGraph: { + type: "website", + siteName, + locale: "de_DE", + title, + description, + images: [ogImage], + url: siteUrl, + }, + twitter: { + card: "summary_large_image", + site: "@envu", + title, + description, + images: [{ url: ogImage.url, alt: ogImage.alt }], + }, +}; + +const jsonLd = { + "@context": "https://schema.org", + "@type": "LocalBusiness", + name: siteName, + url: siteUrl, + description, + address: { + "@type": "PostalAddress", + addressLocality: "Hannover", + addressCountry: "DE", + }, +}; + +export default function RootLayout({ + children, +}: Readonly<{ children: React.ReactNode }>) { + return ( + + +