diff --git a/app.vue b/app/app.vue similarity index 85% rename from app.vue rename to app/app.vue index 8847d80..4d40d81 100644 --- a/app.vue +++ b/app/app.vue @@ -25,3 +25,15 @@ useSeoMeta({ twitterUrl: 'https://webfussel.de', }) + + diff --git a/app/assets/css/button.css b/app/assets/css/button.css new file mode 100644 index 0000000..7fc1733 --- /dev/null +++ b/app/assets/css/button.css @@ -0,0 +1,75 @@ +.Button { + all: unset; + transition: 250ms; + cursor: pointer; + padding: 1rem 1.5rem; + outline: 3px solid transparent; + box-shadow: 0 0 0 0 var(--color-orange); + border-radius: 99999px; + display: flex; + align-items: center; + justify-content: center; + gap: 1rem; + + &.default { + background: var(--color-orange); + color: var(--color-black); + } + + &.white { + background: var(--color-white); + color: var(--color-black); + } + + &:hover { + outline-color: var(--color-black); + box-shadow: 0 0 0 6px var(--color-orange); + } + + &.cta { + font-size: clamp(1rem, 2vw, 1.5rem); + } +} + +.DualButton { + --size: 2.2rem; + display: flex; + width: 100%; + + & .divider { + display: flex; + align-items: center; + justify-content: center; + background-color: var(--color-black); + color: var(--color-white); + border-radius: 9999px; + width: var(--size); + height: var(--size); + padding: var(--size); + font-size: 1.2rem; + z-index: 1; + margin-left: calc(var(--size) * -1 - 25px); + border: 2px solid var(--color-black); + } + + .Button { + border: 2px solid currentColor; + } + + & .Button:hover { + outline: none; + box-shadow: none; + background-color: var(--color-black); + color: var(--color-white); + border-color: var(--color-orange); + } + + & .Button:first-child { + padding-right: calc(var(--size) * 2); + } + + & .Button:last-child { + padding-left: calc(var(--size) * 2); + margin-left: calc(var(--size) * -1 - 25px); + } +} \ No newline at end of file diff --git a/assets/css/customers.css b/app/assets/css/customers.css similarity index 100% rename from assets/css/customers.css rename to app/assets/css/customers.css diff --git a/assets/css/fonts.css b/app/assets/css/fonts.css similarity index 100% rename from assets/css/fonts.css rename to app/assets/css/fonts.css diff --git a/assets/css/footer.css b/app/assets/css/footer.css similarity index 100% rename from assets/css/footer.css rename to app/assets/css/footer.css diff --git a/assets/css/global.css b/app/assets/css/global.css similarity index 83% rename from assets/css/global.css rename to app/assets/css/global.css index 82402e2..243a345 100644 --- a/assets/css/global.css +++ b/app/assets/css/global.css @@ -73,6 +73,7 @@ body { background: var(--color-black); } +.h1, .h2, .h3, .h4, .h5, .h6, h1, h2, h3, h4, h5, h6 { text-align: left; font-family: 'Roboto Condensed', sans-serif; @@ -82,8 +83,11 @@ h1 { font-size: 4rem; } +.h2, +h2, h3 { font-size: 1.5rem; + font-weight: bold; } a { @@ -198,6 +202,43 @@ span.chip { box-shadow: 0 19px 38px rgba(0, 0, 0, 0.30), 0 15px 12px rgba(0, 0, 0, 0.22); } +.tip-container { + position: relative; + display: flex; + flex-direction: column; + align-items: center; +} + +.tip-container .tip { + scale: 0; + position: absolute; + top: -3rem; + width: max-content; + border: 1px solid var(--color-white); + border-radius: 999px; + background-color: var(--color-black); + padding: .5em 1.5rem; + transition: 150ms; +} + +.tip-container:hover .tip { + scale: 1; +} + +.animate-up-down { + animation: up-down 1.5s ease-in-out alternate-reverse infinite; +} + +@keyframes up-down { + 0% { + translate: 0 -0.1rem; + } + + 100% { + translate: 0 0.4em; + } +} + @media (width <= 780px) { h1, h2, h3, h4, h5, h6, p { text-align: center; diff --git a/assets/css/header.css b/app/assets/css/header.css similarity index 93% rename from assets/css/header.css rename to app/assets/css/header.css index b69e92e..9c98e86 100644 --- a/assets/css/header.css +++ b/app/assets/css/header.css @@ -10,10 +10,6 @@ position: fixed; z-index: 1000; - & .socials { - gap: 1rem; - } - & .logo { fill-rule: evenodd; clip-rule: evenodd; @@ -51,19 +47,23 @@ } & nav { - flex: 3; position: relative; font-weight: normal; font-size: 1.2rem; display: flex; justify-content: space-between; align-items: center; + + & .active { + color: var(--color-orange); + } } & > .wrapper { display: flex; align-items: center; - padding: 15px 30px; + justify-content: space-between; + padding: 15px 22px; transition: 750ms; backdrop-filter: blur(10px); border-radius: 0; @@ -174,13 +174,6 @@ color: var(--color-white); flex-direction: column; - & .socials { - flex-direction: row; - height: max-content; - gap: 3rem; - padding-bottom: 2rem; - } - & ul { flex-direction: column; justify-content: center; @@ -188,7 +181,7 @@ gap: 8vh; & li { - font-size: 10vw; + font-size: clamp(1rem, 10vw, 3rem); } } } diff --git a/assets/css/intro.css b/app/assets/css/intro.css similarity index 100% rename from assets/css/intro.css rename to app/assets/css/intro.css diff --git a/assets/css/person.css b/app/assets/css/person.css similarity index 100% rename from assets/css/person.css rename to app/assets/css/person.css diff --git a/assets/css/services.css b/app/assets/css/services.css similarity index 100% rename from assets/css/services.css rename to app/assets/css/services.css diff --git a/assets/css/skills.css b/app/assets/css/skills.css similarity index 100% rename from assets/css/skills.css rename to app/assets/css/skills.css diff --git a/app/assets/css/technology.css b/app/assets/css/technology.css new file mode 100644 index 0000000..2e2d0b1 --- /dev/null +++ b/app/assets/css/technology.css @@ -0,0 +1,16 @@ +.Technology { + position: relative; + align-items: center; + + &.s img { + height: 15px; + } + + &.m img { + height: 30px; + } + + &.l img { + height: 50px; + } +} diff --git a/components/Button.vue b/app/components/Button.vue similarity index 69% rename from components/Button.vue rename to app/components/Button.vue index a5f93d7..8c9095d 100644 --- a/components/Button.vue +++ b/app/components/Button.vue @@ -1,6 +1,6 @@ @@ -9,13 +9,13 @@ type Props = { type ?: 'a' | 'button' href ?: string - label : string + design ?: string } const { type = 'a', - href, - label, + href = '#', + design = 'default', } = defineProps() const actualProps = () => { diff --git a/components/Customers.vue b/app/components/Customers.vue similarity index 98% rename from components/Customers.vue rename to app/components/Customers.vue index e9ed5b3..a16dcdf 100644 --- a/components/Customers.vue +++ b/app/components/Customers.vue @@ -38,7 +38,7 @@ diff --git a/components/Header.vue b/app/components/Header.vue similarity index 70% rename from components/Header.vue rename to app/components/Header.vue index 889621e..c8b221c 100644 --- a/components/Header.vue +++ b/app/components/Header.vue @@ -28,15 +28,8 @@ @@ -57,47 +50,31 @@ const burgerLabel = computed(() => isBurgerOpen.value ? burgerCloseLabel : burge const nav = [ { - to: `/#intro`, - label: 'Über mich', - 'aria-label': 'Link dieser Seite: Über mich' - }, { - to: `/#customers`, - label: 'Kunden', - 'aria-label': 'Link dieser Seite: Kunden' - }, { - to: `/#services`, - label: 'Services', - 'aria-label': 'Link dieser Seite: Services' - } -] - -const socials = [ - { - href: 'https://www.linkedin.com/in/webfussel/', - icon: 'ri:linkedin-box-line', - 'aria-label': 'Externer Link: LinkedIn Profil' + to: `/`, + label: 'home', + 'aria-label': 'Link dieser Seite: Startseite' }, { - href: 'https://mastodontech.de/@webfussel', - icon: 'ri:mastodon-line', - rel: 'me', - 'aria-label': 'Externer Link: Mastodon Profil' + to: `/services`, + label: 'leistungen', + aria: 'Link dieser Seite: Leistungen' }, { - href: 'https://bsky.app/profile/webfussel.de', - icon: 'ri:bluesky-line', - 'aria-label': 'Externer Link: Bluesky Profil' + to: `/references`, + label: 'referenzen', + aria: 'Link dieser Seite: Referenzen' }, { - href: 'https://ko-fi.com/webfussel', - icon: 'wf:kofi', - 'aria-label': 'Externer Link: KoFi Profil' + to: `/contact`, + label: 'kontakt', + aria: 'Link dieser Seite: Kontakt' }, ] onMounted(() => { observer = new IntersectionObserver(([entry]) => { - const {isIntersecting} = entry + if (!entry) return + const { isIntersecting } = entry header.value?.classList.toggle('sticks', !isIntersecting) headerWrapper.value?.classList.toggle('z-4', !isIntersecting) headerWrapper.value?.classList.toggle('z-0', isIntersecting) diff --git a/components/Intro.vue b/app/components/Intro.vue similarity index 63% rename from components/Intro.vue rename to app/components/Intro.vue index 9c3b240..52d3364 100644 --- a/components/Intro.vue +++ b/app/components/Intro.vue @@ -9,17 +9,21 @@ Component & API Entwicklerin

- Ich unterstütze Unternehmen dabei, ihre Daten so richtig nice zusammen zu sammeln - und in wunderschöne Komponenten zu gießen. + Ich unterstütze Unternehmen dabei, ihre Daten von verschiedenen Endpunkten sauber aufzubereiten + und anschließend in einer Webapplication schön zu verpacken.

Mit über 20 Jahren Erfahrung in der Webentwicklung habe ich inzwischen so ziemlich jeden Stuff miterlebt.

- Du brauchst großartige Komponenten und saubere Schnittstellen? + Egal, ob Komponenten, Schnittstellen oder Anbindung an Headless CMS. + Ich biete dir genau das, was du brauchst, um eine individuelle WebApp in Fahrt zu bringen, deren Inhalte einfach zu verändern sind.

-
@@ -29,3 +33,5 @@
+ \ No newline at end of file diff --git a/components/Person.vue b/app/components/Person.vue similarity index 87% rename from components/Person.vue rename to app/components/Person.vue index f40dba3..5fbb0b9 100644 --- a/components/Person.vue +++ b/app/components/Person.vue @@ -13,7 +13,9 @@ {{tag}}

{{flavour}}

- diff --git a/components/Services.vue b/app/components/Services.vue similarity index 92% rename from components/Services.vue rename to app/components/Services.vue index eb433a4..d27fdb6 100644 --- a/components/Services.vue +++ b/app/components/Services.vue @@ -12,10 +12,13 @@ {{service.availability}}

{{service.smallClaim}}

- @@ -59,6 +62,7 @@ const services = [ price: '149 € / Einmalig', availability: 'Frei', smallClaim: 'Du hast eine Homepage und willst mal drüber schauen lassen?', + icon: 'magnifying-glass', button: 'Jetzt untersuchen', link: 'https://tidycal.com/webfussel/quick-check', list: [ @@ -73,6 +77,7 @@ const services = [ price: 'ab 999 € je nach Umfang', availability: slotsLabel, smallClaim: 'Umsetzung deiner Vision. Von einzelnen Tickets bis hin zu kompletten Anwendungen.', + icon: 'trend-up', button: 'Jetzt durchstarten', link: 'https://tidycal.com/webfussel/project-booking', list: [ @@ -86,6 +91,7 @@ const services = [ availability: `Frei ab ${readableDate}`, price: '105 € / Stunde', smallClaim: 'Du brauchst einfach Unterstützung im Team, bis sich der Trubel legt?', + icon: 'timer', button: 'Jetzt buchen', link: 'https://tidycal.com/webfussel/hourly-booking', list: [ diff --git a/components/Skills.vue b/app/components/Skills.vue similarity index 84% rename from components/Skills.vue rename to app/components/Skills.vue index 70ed0d0..6fb234f 100644 --- a/components/Skills.vue +++ b/app/components/Skills.vue @@ -20,17 +20,22 @@
-

Du brauchst was davon? Kein Ding.

-
diff --git a/nuxt.config.ts b/nuxt.config.ts index 434d31a..84558c4 100644 --- a/nuxt.config.ts +++ b/nuxt.config.ts @@ -1,5 +1,8 @@ export default defineNuxtConfig({ ssr: true, + future: { + compatibilityVersion: 4, + }, nitro: { prerender: { @@ -36,6 +39,10 @@ export default defineNuxtConfig({ }, app: { + pageTransition: { + name: 'page', + mode: 'out-in', + }, head: { htmlAttrs: { lang: 'de' }, link: [ diff --git a/package-lock.json b/package-lock.json index d48f081..3b3765a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -7,6 +7,7 @@ "name": "nuxt-app", "hasInstallScript": true, "devDependencies": { + "@iconify-json/material-symbols": "^1.2.14", "@iconify-json/ri": "^1.2.5", "@nuxt/icon": "^1.10.3", "nuxt": "^3.15.3", @@ -1037,6 +1038,16 @@ "node": ">=18" } }, + "node_modules/@iconify-json/material-symbols": { + "version": "1.2.14", + "resolved": "https://registry.npmjs.org/@iconify-json/material-symbols/-/material-symbols-1.2.14.tgz", + "integrity": "sha512-S0AAFFQPVr8Dkrprspz/otNjxdD3rJRXDGZjbO8a8zn8ZR5mO8jAF81lVoTfUWxPH6SCtH2lK1JQGXHGPxld7g==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@iconify/types": "*" + } + }, "node_modules/@iconify-json/ri": { "version": "1.2.5", "resolved": "https://registry.npmjs.org/@iconify-json/ri/-/ri-1.2.5.tgz", diff --git a/package.json b/package.json index 545325d..aa10823 100644 --- a/package.json +++ b/package.json @@ -14,6 +14,7 @@ "build:deploy": "nuxt build && firebase deploy --only hosting" }, "devDependencies": { + "@iconify-json/material-symbols": "^1.2.14", "@iconify-json/ri": "^1.2.5", "@nuxt/icon": "^1.10.3", "nuxt": "^3.15.3",