2025-05-25 21:45:54 +02:00

243 lines
6.5 KiB
Vue

<template>
<div>
<section class="heroBox" :aria-label="$t('pages.services.hero.ariaLabel')">
<NuxtImg
provider="strapi"
src="/uploads/BG_technology_b6b0083811.png"
class="hero-bg"
sizes="sm:100vw md:100vw lg:100vw"
alt=""
aria-hidden="true"
priority
loading="eager"
preload
fetchpriority="high"
/>
<div class="container-10">
<h1>{{ $t('pages.services.hero.headline1') }}</h1>
<h2>{{ $t('pages.services.hero.headline2') }}</h2>
<h3>{{ $t('pages.services.hero.headline3') }}</h3>
</div>
<!-- Nach dem Container: Spiegelwelle unten -->
<svg class="sectionWave wave-bottom" style="" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 500 20" aria-hidden="true">
<path d="M 0 0 L 500 0 L 500 14 Q 354.4 -2.8 250 11 Q 145.6 24.8 0 14 L 0 0 Z" fill="#FFF"/>
</svg>
</section>
<section class="explainBox" :aria-label="$t('pages.services.explain.ariaLabel')">
<NuxtImg
src="/uploads/Human_Maschine_BG_5c91e9100f.webp"
provider="strapi"
format="webp"
sizes="100vw"
class="background-image"
alt=""
aria-hidden="true"
/>
<div class="container-15 content">
<h2>{{ $t('pages.services.explain.headline1') }}</h2>
<h3>{{ $t('pages.services.explain.headline2') }}</h3>
<p>{{ $t('pages.services.explain.paragraph') }}</p>
<ul class="check">
<li>{{ t('pages.services.explain.bullet1') }}</li>
<li>{{ t('pages.services.explain.bullet2') }}</li>
<li>{{ t('pages.services.explain.bullet3') }}</li>
<li>{{ t('pages.services.explain.bullet4') }}</li>
<li>{{ t('pages.services.explain.bullet5') }}</li>
</ul>
</div>
</section>
<MarqueeBanner
:items="projectItems"
:logoHeight="200"
:title="$t('pages.services.marquee.title')"
link="projekt"
:aria-label="$t('pages.services.marquee.title')"
speed="15"
/>
<CallToActionBox
:headline="$t('pages.services.ctaBox.headline')"
:text="$t('pages.services.ctaBox.text')"
:buttonText="$t('pages.services.ctaBox.button')"
/>
</div>
</template>
<script setup>
import { storeToRefs } from 'pinia';
import { useMainStore } from '@/stores/main';
import { useI18n } from 'vue-i18n';
import { computed } from 'vue';
const runtimeConfig = useRuntimeConfig()
const origin = runtimeConfig.public.appUrl
const { t } = useI18n();
const mainStore = useMainStore();
const { projects, companyinfo } = storeToRefs(mainStore)
const projectItems = computed(() => {
return projects.value
.filter(project => project.customer && project.projectImages.length > 0)
.map(project => ({
text: project.customer?.company || '',
image: {
url: project.projectImages[0]?.url || '',
alternativeText: project.projectImages[0]?.alternativeText || project.customer?.company || ''
},
link: project.link || ''
}))
})
const logoUrl = computed(() => {
if (!companyinfo) return origin + '/logo.svg';
return companyinfo.logo?.data?.attributes?.url
? origin + companyinfo.logo.data.attributes.url
: origin + '/logo.svg';
})
// JSON_LD für Services
const jsonLdServices = computed(() => {
if (!companyinfo?.value || !companyinfo.value.company) return null;
return {
"@context": "https://schema.org",
"@type": "ProfessionalService",
"name": companyinfo.value.company,
"url": origin,
"logo": logoUrl.value || (origin + '/logo.svg'),
"description": "Spezialisiert auf JAMstack-Webentwicklung, Headless CMS-Integration und moderne Frontend-Lösungen.",
"address": {
"@type": "PostalAddress",
"streetAddress": companyinfo.value.street || '',
"addressLocality": companyinfo.value.city || '',
"addressRegion": "Bayern",
"postalCode": companyinfo.value.postalcode || '',
"addressCountry": "DE"
},
"hasOfferCatalog": {
"@type": "OfferCatalog",
"name": "Leistungen",
"itemListElement": [
{
"@type": "Offer",
"itemOffered": {
"@type": "Service",
"name": "JAMstack-Webentwicklung",
"description": "Moderne Webentwicklung mit statischen Seiten und Headless CMS."
}
},
{
"@type": "Offer",
"itemOffered": {
"@type": "Service",
"name": "Headless CMS Integration",
"description": "Flexible CMS-Lösungen für maximale Freiheit im Frontend."
}
},
{
"@type": "Offer",
"itemOffered": {
"@type": "Service",
"name": "Frontend-Entwicklung",
"description": "Moderne Frontend-Frameworks und UI/UX Design."
}
}
]
}
}
})
watchEffect(() => {
if (companyinfo.value && jsonLdServices.value) {
useHead({
script: [
{
type: 'application/ld+json',
children: JSON.stringify(jsonLdServices.value)
}
]
})
}
})
</script>
<style lang="sass">
.heroBox
position: relative
min-height: 35rem
height: 70vh
display: flex
align-items: center
justify-content: center
overflow: hidden
.hero-bg
position: absolute
inset: 0
width: 100%
height: 100%
object-fit: cover
object-position: center center
z-index: 0
.container-10, h1, h2, h3
position: relative
z-index: 1
h1, h2, h3
color: white
z-index: 2
line-height: 1.5
max-width: 70%
@media (max-width: $breakPointMD)
max-width: 100%
h1
margin-top: 0
font-size: clamp(2rem, 1.4rem + 3vw, 2.8rem)
margin-bottom: 0
font-family: 'Comfortaa'
h2
font-size: clamp(1.2rem, .7rem + 2vw, 2rem)
margin: .8rem 0 .8rem 0
font-family: 'Comfortaa'
h3
font-size: 1.2rem
.explainBox
position: relative
overflow: hidden
min-height: 400px
margin: 5vh 0
padding: 8vh 0
.background-image
position: absolute
top: 0
left: 0
width: 100%
height: auto
object-fit: contain
object-position: center center
z-index: 0
pointer-events: none
.content
position: relative
z-index: 1
padding-left: 10%
h3
font-family: 'Mainfont-Bold'
font-size: 1.2rem
</style>