FIX: mpa, nuxt4 future, improvements in intro and services
Added mpa support, nuxt4 future compatibility, improvements in intro and services
This commit is contained in:
parent
078d4bfd82
commit
9642496e5a
35 changed files with 324 additions and 172 deletions
|
@ -25,3 +25,15 @@ useSeoMeta({
|
|||
twitterUrl: 'https://webfussel.de',
|
||||
})
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.page-enter-active,
|
||||
.page-leave-active {
|
||||
transition: all 0.4s;
|
||||
}
|
||||
.page-enter-from,
|
||||
.page-leave-to {
|
||||
opacity: 0;
|
||||
filter: blur(.5rem);
|
||||
}
|
||||
</style>
|
75
app/assets/css/button.css
Normal file
75
app/assets/css/button.css
Normal file
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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;
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
16
app/assets/css/technology.css
Normal file
16
app/assets/css/technology.css
Normal file
|
@ -0,0 +1,16 @@
|
|||
.Technology {
|
||||
position: relative;
|
||||
align-items: center;
|
||||
|
||||
&.s img {
|
||||
height: 15px;
|
||||
}
|
||||
|
||||
&.m img {
|
||||
height: 30px;
|
||||
}
|
||||
|
||||
&.l img {
|
||||
height: 50px;
|
||||
}
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
<template>
|
||||
<component :is="type" v-bind="actualProps()" class="Button">
|
||||
{{ label }}
|
||||
<component :is="type" v-bind="actualProps()" class="Button" :class="[design]">
|
||||
<slot />
|
||||
</component>
|
||||
</template>
|
||||
|
||||
|
@ -9,13 +9,13 @@
|
|||
type Props = {
|
||||
type ?: 'a' | 'button'
|
||||
href ?: string
|
||||
label : string
|
||||
design ?: string
|
||||
}
|
||||
|
||||
const {
|
||||
type = 'a',
|
||||
href,
|
||||
label,
|
||||
href = '#',
|
||||
design = 'default',
|
||||
} = defineProps<Props>()
|
||||
|
||||
const actualProps = () => {
|
|
@ -38,7 +38,7 @@
|
|||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { css, pcss, html, js, njs, nuxt, scss, ts, tw, vue, flutter, dart, android } from '~/Skills'
|
||||
import { android, css, dart, flutter, html, js, njs, nuxt, pcss, scss, ts, tw, vue } from '../utils/skills'
|
||||
|
||||
const customers = [
|
||||
{
|
84
app/components/Footer.vue
Normal file
84
app/components/Footer.vue
Normal file
|
@ -0,0 +1,84 @@
|
|||
<template>
|
||||
<footer class="Footer flex-col default-gap">
|
||||
<ul class="sitemap default-gap">
|
||||
<li v-for="{ label, ...rest} in nav" :key="label">
|
||||
<NuxtLink v-bind="rest">{{label}}</NuxtLink>
|
||||
</li>
|
||||
</ul>
|
||||
<ul class="sitemap default-gap">
|
||||
<li v-for="({icon, ...rest}) in socials" :key="rest.href">
|
||||
<a v-bind="rest" target="_blank">
|
||||
<Icon :name="icon" :alt="rest['aria-label']" size="1.5em" mode="svg" />
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
<ul class="sitemap default-gap">
|
||||
<li class="tip-container">
|
||||
<Icon name="material-symbols:cookie-off-outline" size="1.5rem" mode="svg" />
|
||||
<span class="tip">Ohne Cookies</span>
|
||||
</li>
|
||||
<li class="tip-container">
|
||||
<Icon name="material-symbols:fingerprint-off" size="1.5rem" mode="svg" />
|
||||
<span class="tip">Ohne Tracker</span>
|
||||
</li>
|
||||
</ul>
|
||||
<p>© 2024 by <a href="https://webfussel.de">webfussel</a></p>
|
||||
</footer>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
|
||||
|
||||
const nav = [
|
||||
{
|
||||
to: `/#intro`,
|
||||
label: 'Über mich',
|
||||
'aria-label': 'Link dieser Seite: Über mich'
|
||||
}, {
|
||||
to: `/#skills`,
|
||||
label: 'Meine Expertise',
|
||||
'aria-label': 'Link dieser Seite: Meine Expertise'
|
||||
}, {
|
||||
to: `/#customers`,
|
||||
label: 'Kunden',
|
||||
'aria-label': 'Link dieser Seite: Kunden'
|
||||
}, {
|
||||
to: `/#services`,
|
||||
label: 'Services',
|
||||
'aria-label': 'Link dieser Seite: Services'
|
||||
}, {
|
||||
to: `/#network`,
|
||||
label: 'Mein Netzwerk',
|
||||
'aria-label': 'Link dieser Seite: Mein Netzwerk'
|
||||
}, {
|
||||
to: '/imp',
|
||||
label: 'Impressum',
|
||||
'aria-label': 'Link dieser Seite: Impressum'
|
||||
}
|
||||
]
|
||||
|
||||
|
||||
const socials = [
|
||||
{
|
||||
href: 'https://www.linkedin.com/in/webfussel/',
|
||||
icon: 'ri:linkedin-box-line',
|
||||
'aria-label': 'Externer Link: LinkedIn Profil'
|
||||
},
|
||||
{
|
||||
href: 'https://mastodontech.de/@webfussel',
|
||||
icon: 'ri:mastodon-line',
|
||||
rel: 'me',
|
||||
'aria-label': 'Externer Link: Mastodon Profil'
|
||||
},
|
||||
{
|
||||
href: 'https://bsky.app/profile/webfussel.de',
|
||||
icon: 'ri:bluesky-line',
|
||||
'aria-label': 'Externer Link: Bluesky Profil'
|
||||
},
|
||||
{
|
||||
href: 'https://ko-fi.com/webfussel',
|
||||
icon: 'wf:kofi',
|
||||
'aria-label': 'Externer Link: KoFi Profil'
|
||||
},
|
||||
]
|
||||
</script>
|
|
@ -28,15 +28,8 @@
|
|||
</label>
|
||||
<nav>
|
||||
<ul class="main-nav">
|
||||
<li v-for="({label, ...rest}) in nav" :key="label" @click="isBurgerOpen = false">
|
||||
<NuxtLink v-bind="rest">{{ label }}</NuxtLink>
|
||||
</li>
|
||||
</ul>
|
||||
<ul class="socials">
|
||||
<li v-for="({icon, ...rest}) in socials" :key="rest.href" @click="isBurgerOpen = false">
|
||||
<a v-bind="rest" target="_blank">
|
||||
<Icon :name="icon" :alt="rest['aria-label']" size="1.5em" mode="svg" />
|
||||
</a>
|
||||
<li v-for="({label, to, aria}) in nav" :key="label" @click="isBurgerOpen = false">
|
||||
<NuxtLink :to="to" :aria-label="aria" active-class="active">{{ label }}</NuxtLink>
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
|
@ -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)
|
|
@ -9,17 +9,21 @@
|
|||
Component <span class="highlight">&</span> API Entwicklerin
|
||||
</h2>
|
||||
<p class="fulltext">
|
||||
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.
|
||||
</p>
|
||||
<p class="fulltext">
|
||||
Mit über 20 Jahren Erfahrung in der Webentwicklung habe ich
|
||||
inzwischen so ziemlich jeden Stuff miterlebt.
|
||||
</p>
|
||||
<p class="fulltext">
|
||||
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.
|
||||
</p>
|
||||
<Button href="#services" class="cta" label="Lass mal reden" />
|
||||
<Button class="cta" href="#skills">
|
||||
<Icon name="ph:lightbulb-duotone" size="1.5em" mode="svg" />
|
||||
Fussel erklärt's dir
|
||||
</Button>
|
||||
</div>
|
||||
<div class="intro-img">
|
||||
<picture>
|
||||
|
@ -29,3 +33,5 @@
|
|||
</div>
|
||||
</section>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
</script>
|
|
@ -13,7 +13,9 @@
|
|||
<span v-for="tag in tags">{{tag}}</span>
|
||||
</p>
|
||||
<p class="flavour">{{flavour}}</p>
|
||||
<Button :href="link" class="button" target="_blank" rel="noreferrer noopener" label="Zur Homepage" :aria-label="`Externer Link zur Homepage von ${name}`" />
|
||||
<Button :href="link" class="button" target="_blank" rel="noreferrer noopener" :aria-label="`Externer Link zur Homepage von ${name}`">
|
||||
Zur Homepage
|
||||
</Button>
|
||||
</article>
|
||||
</template>
|
||||
|
|
@ -12,10 +12,13 @@
|
|||
</h3>
|
||||
<span class="chip">{{service.availability}}</span>
|
||||
<p>{{service.smallClaim}}</p>
|
||||
<Button :href="service.link" class="cta" :label="service.button" aria-label="Zur externen Seite von zur Terminbuchung" />
|
||||
<Button :href="service.link" class="cta" aria-label="Zur externen Seite von zur Terminbuchung">
|
||||
{{ service.button }}
|
||||
<Icon :name="`ph:${service.icon}-duotone`" size="1.5em" mode="svg"></Icon>
|
||||
</Button>
|
||||
<ul class="flex-col">
|
||||
<li v-for="point in service.list">
|
||||
<Icon class="color-icon" name="ri:check-double-line" aria-hidden="true" alt="checkmark icon" size="1.5em" mode="svg" />
|
||||
<Icon class="color-icon" name="ph:caret-circle-double-right-duotone" aria-hidden="true" alt="checkmark icon" size="1.5em" mode="svg" />
|
||||
<span>{{point}}</span>
|
||||
</li>
|
||||
</ul>
|
||||
|
@ -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: [
|
|
@ -20,17 +20,22 @@
|
|||
</ul>
|
||||
</article>
|
||||
<div class="bottom flex-col margin-top default-gap">
|
||||
<h3>Du brauchst was davon? Kein Ding.</h3>
|
||||
<Button href="#services" class="cta" label="Lass mal reden" />
|
||||
<h3>Manche von euch haben hier sicher kein Wort verstanden.</h3>
|
||||
<Button href="#services" class="cta">
|
||||
<span class="animate-up-down">
|
||||
<Icon name="ph:caret-double-down-duotone" size="1.5em" mode="svg" />
|
||||
</span>
|
||||
Für normale Menschen
|
||||
</Button>
|
||||
</div>
|
||||
</section>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
|
||||
import { gl, webstorm, njs, nuxt, pcss, react, rust, ts, vitest, vue } from '~/Skills'
|
||||
import { gl, njs, nuxt, pcss, react, rust, ts, vitest, vue, webstorm } from '../utils/skills'
|
||||
|
||||
const technologies = [nuxt, ts, pcss, vue, react, njs, vitest, gl, webstorm]
|
||||
const technologies = [nuxt, ts, pcss, vue, react, njs, vitest, gl, webstorm, rust]
|
||||
|
||||
const skills = [
|
||||
{
|
|
@ -1,5 +1,5 @@
|
|||
<template>
|
||||
<div class="Technology flex-col" :class="[size]">
|
||||
<div class="Technology flex-col tip-container" :class="[size]">
|
||||
<a v-if="link" :href="link" target="_blank" rel="noopener noreferrer">
|
||||
<img loading="lazy" :src="img" :alt="altText()" :height="getPixelForSize()" :width="getWidth()" />
|
||||
</a>
|
6
app/pages/index.vue
Normal file
6
app/pages/index.vue
Normal file
|
@ -0,0 +1,6 @@
|
|||
<template>
|
||||
<div>
|
||||
<Intro />
|
||||
<Skills />
|
||||
</div>
|
||||
</template>
|
5
app/pages/references.vue
Normal file
5
app/pages/references.vue
Normal file
|
@ -0,0 +1,5 @@
|
|||
<template>
|
||||
<div>
|
||||
<Customers />
|
||||
</div>
|
||||
</template>
|
5
app/pages/services.vue
Normal file
5
app/pages/services.vue
Normal file
|
@ -0,0 +1,5 @@
|
|||
<template>
|
||||
<div>
|
||||
<Services />
|
||||
</div>
|
||||
</template>
|
|
@ -31,7 +31,6 @@ export const flutter: ISkill = {name: 'Flutter', img: flutterImg, link: 'https:/
|
|||
export const gl: ISkill = {name: 'GitLab', img: glImg, link: 'https://gitlab.com', width: 55}
|
||||
export const html: ISkill = {name: 'HTML', img: htmlImg, width: 44}
|
||||
export const js: ISkill = {name: 'JavaScript', img: jsImg}
|
||||
export const webstorm: ISkill = {name: 'JetBrains IDEs', img: webstormImg, link: 'https://www.jetbrains.com/webstorm'}
|
||||
export const njs: ISkill = {name: 'Nodejs', img: njsImg, link: 'https://nodejs.org/en', width: 46}
|
||||
export const nuxt: ISkill = {name: 'Nuxt', img: nuxtImg, link: 'https://nuxt.com', width: 75}
|
||||
export const pcss: ISkill = {name: 'PostCSS', img: postCssImg, link: 'https://postcss.org'}
|
||||
|
@ -42,3 +41,4 @@ export const tw: ISkill = {name: 'Tailwind', img: twImg, width: 84}
|
|||
export const ts: ISkill = {name: 'TypeScript', img: tsImg, link: 'https://www.typescriptlang.org'}
|
||||
export const vitest: ISkill = {name: 'Vitest', img: vitestImg, link: 'https://vitest.dev', width: 55}
|
||||
export const vue: ISkill = {name: 'Vue', img: vueImg, link: 'https://vuejs.org', width: 58}
|
||||
export const webstorm: ISkill = {name: 'JetBrains IDEs', img: webstormImg, link: 'https://www.jetbrains.com/webstorm'}
|
|
@ -1,24 +0,0 @@
|
|||
.Button {
|
||||
all: unset;
|
||||
transition: 250ms;
|
||||
background: var(--color-orange);
|
||||
color: var(--color-black);
|
||||
cursor: pointer;
|
||||
padding: 1rem 1.5rem;
|
||||
outline: 3px solid transparent;
|
||||
box-shadow: 0 0 0 0 var(--color-orange);
|
||||
border-radius: 99999px;
|
||||
text-align: center;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
&:hover {
|
||||
outline-color: var(--color-black);
|
||||
box-shadow: 0 0 0 6px var(--color-orange);
|
||||
}
|
||||
|
||||
&.cta {
|
||||
font-size: clamp(1rem, 2vw, 1.5rem);
|
||||
}
|
||||
}
|
|
@ -1,32 +0,0 @@
|
|||
.Technology {
|
||||
position: relative;
|
||||
align-items: center;
|
||||
|
||||
&.s img {
|
||||
height: 15px;
|
||||
}
|
||||
|
||||
&.m img {
|
||||
height: 30px;
|
||||
}
|
||||
|
||||
&.l img {
|
||||
height: 50px;
|
||||
}
|
||||
|
||||
& span {
|
||||
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;
|
||||
}
|
||||
|
||||
&:hover span {
|
||||
scale: 1;
|
||||
}
|
||||
}
|
|
@ -1,44 +0,0 @@
|
|||
<template>
|
||||
<footer class="Footer flex-col default-gap">
|
||||
<ul class="sitemap default-gap">
|
||||
<li v-for="{ label, ...rest} in nav" :key="label">
|
||||
<NuxtLink v-bind="rest">{{label}}</NuxtLink>
|
||||
</li>
|
||||
</ul>
|
||||
<div class="notes">
|
||||
<p>Natürlich ohne Cookies und Tracker.</p>
|
||||
<p>Made with nuxt, typescript & postcss.</p>
|
||||
</div>
|
||||
<p>© 2024 by <a href="https://webfussel.de">webfussel</a></p>
|
||||
</footer>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
const nav = [
|
||||
{
|
||||
to: `/#intro`,
|
||||
label: 'Über mich',
|
||||
'aria-label': 'Link dieser Seite: Über mich'
|
||||
}, {
|
||||
to: `/#skills`,
|
||||
label: 'Meine Expertise',
|
||||
'aria-label': 'Link dieser Seite: Meine Expertise'
|
||||
}, {
|
||||
to: `/#customers`,
|
||||
label: 'Kunden',
|
||||
'aria-label': 'Link dieser Seite: Kunden'
|
||||
}, {
|
||||
to: `/#services`,
|
||||
label: 'Services',
|
||||
'aria-label': 'Link dieser Seite: Services'
|
||||
}, {
|
||||
to: `/#network`,
|
||||
label: 'Mein Netzwerk',
|
||||
'aria-label': 'Link dieser Seite: Mein Netzwerk'
|
||||
}, {
|
||||
to: '/imp',
|
||||
label: 'Impressum',
|
||||
'aria-label': 'Link dieser Seite: Impressum'
|
||||
}
|
||||
]
|
||||
</script>
|
|
@ -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: [
|
||||
|
|
11
package-lock.json
generated
11
package-lock.json
generated
|
@ -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",
|
||||
|
|
|
@ -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",
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue