This commit is contained in:
Sabrina Hennrich 2025-06-08 18:26:21 +02:00
parent 5ba26358df
commit a6d01b73da
7 changed files with 314 additions and 101 deletions

18
app.vue
View File

@ -1,6 +1,11 @@
<template> <template>
<NuxtLayout> <NuxtLayout>
<NuxtPage /> <NuxtPage
:transition="{
name: 'page',
mode: 'out-in'
}"
/>
</NuxtLayout> </NuxtLayout>
</template> </template>
@ -40,3 +45,14 @@ const handleResize = () => {
mainStore.setScreenWidth(window.innerWidth) mainStore.setScreenWidth(window.innerWidth)
} }
</script> </script>
<style lang="sass" scoped>
.page-enter-active,
.page-leave-active
transition: opacity 0.3s ease, transform 0.3s ease
.page-enter-from,
.page-leave-to
opacity: 0
transform: scale(1.02)
</style>

View File

@ -1,26 +1,48 @@
<template> <template>
<nav v-if="breadcrumbs.length" class="breadcrumbs" aria-label="Breadcrumb"> <nav
<ul> v-if="breadcrumbs.length"
<li> class="breadcrumbs"
<router-link to="/" aria-label="Startseite"> :class="{ expanded: isOpen }"
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" aria-hidden="true" focusable="false"> aria-label="Breadcrumb"
<title>Startseite</title> >
<path d="M575.8 255.5c0 18-15 32.1-32 32.1l-32 0 .7 160.2c0 2.7-.2 5.4-.5 8.1l0 16.2c0 22.1-17.9 40-40 40l-16 0c-1.1 0-2.2 0-3.3-.1c-1.4 .1-2.8 .1-4.2 .1L416 512l-24 0c-22.1 0-40-17.9-40-40l0-24 0-64c0-17.7-14.3-32-32-32l-64 0c-17.7 0-32 14.3-32 32l0 64 0 24c0 22.1-17.9 40-40 40l-24 0-31.9 0c-1.5 0-3-.1-4.5-.2c-1.2 .1-2.4 .2-3.6 .2l-16 0c-22.1 0-40-17.9-40-40l0-112c0-.9 0-1.9 .1-2.8l0-69.7-32 0c-18 0-32-14-32-32.1c0-9 3-17 10-24L266.4 8c7-7 15-8 22-8s15 2 21 7L564.8 231.5c8 7 12 15 11 24z"/> <div class="breadcrumb-container">
</svg> <div class="breadcrumb-trigger" @click="toggleOpen" aria-label="Breadcrumb öffnen">
</router-link> <svg
</li> xmlns="http://www.w3.org/2000/svg"
<li v-for="(crumb, index) in breadcrumbs" :key="index"> viewBox="0 0 576 512"
<router-link v-if="index < breadcrumbs.length - 1" :to="crumb.to" :title="crumb.labelFull"> aria-hidden="true"
{{ crumb.label }} focusable="false"
</router-link> >
<span v-else :title="crumb.labelFull">{{ crumb.label }}</span> <title>Startseite</title>
</li> <path
</ul> d="M575.8 255.5c0 18-15 32.1-32 32.1l-32 0 .7 160.2c0 2.7-.2 5.4-.5 8.1l0 16.2c0 22.1-17.9 40-40 40l-16 0c-1.1 0-2.2 0-3.3-.1c-1.4 .1-2.8 .1-4.2 .1L416 512l-24 0c-22.1 0-40-17.9-40-40l0-24 0-64c0-17.7-14.3-32-32-32l-64 0c-17.7 0-32 14.3-32 32l0 64 0 24c0 22.1-17.9 40-40 40l-24 0-31.9 0c-1.5 0-3-.1-4.5-.2c-1.2 .1-2.4 .2-3.6 .2l-16 0c-22.1 0-40-17.9-40-40l0-112c0-.9 0-1.9 .1-2.8l0-69.7-32 0c-18 0-32-14-32-32.1c0-9 3-17 10-24L266.4 8c7-7 15-8 22-8s15 2 21 7L564.8 231.5c8 7 12 15 11 24z"
/>
</svg>
</div>
<!-- Breadcrumbs selbst (ein- und ausklappbar) -->
<ul :class="{ open: isOpen, closed: !isOpen }">
<li
v-for="(crumb, index) in breadcrumbs"
:key="index"
>
<router-link
v-if="index < breadcrumbs.length - 1"
:to="crumb.to"
:title="crumb.labelFull"
>{{ crumb.label }}
</router-link>
<span v-else :title="crumb.labelFull"><span v-if="breadcrumbs.length > 1" class="between"></span>{{ crumb.label }}</span>
</li>
<li class="close-btn" @click="isOpen = false" title="Schließen"></li>
</ul>
</div>
</nav> </nav>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { computed } from 'vue' import { computed, ref, watch } from 'vue'
import { useI18n } from 'vue-i18n' import { useI18n } from 'vue-i18n'
import { useRoute } from 'vue-router' import { useRoute } from 'vue-router'
import { i18nPages } from '~/i18n/i18n-pages' import { i18nPages } from '~/i18n/i18n-pages'
@ -31,6 +53,12 @@ interface Breadcrumb {
to: string to: string
} }
const isOpen = ref(false)
function toggleOpen() {
isOpen.value = !isOpen.value
}
function formatLabel(segment: string): { label: string; labelFull: string } { function formatLabel(segment: string): { label: string; labelFull: string } {
const labelFull = segment.charAt(0).toUpperCase() + segment.slice(1).replace(/-/g, ' ') const labelFull = segment.charAt(0).toUpperCase() + segment.slice(1).replace(/-/g, ' ')
let label = labelFull let label = labelFull
@ -55,7 +83,6 @@ const breadcrumbs = computed<Breadcrumb[]>(() => {
const pathWithoutLang = route.path.replace(`/${loc}`, '') const pathWithoutLang = route.path.replace(`/${loc}`, '')
const segments = pathWithoutLang.split('/').filter(Boolean) const segments = pathWithoutLang.split('/').filter(Boolean)
// Ausnahme 1: /projekt/:slug /references
if (segments.length === 2 && segments[0] === 'projekt') { if (segments.length === 2 && segments[0] === 'projekt') {
const referencesPath = i18nPages.references?.[loc] || '/references' const referencesPath = i18nPages.references?.[loc] || '/references'
const referencesLabel = t('references') || 'References' const referencesLabel = t('references') || 'References'
@ -76,7 +103,6 @@ const breadcrumbs = computed<Breadcrumb[]>(() => {
return [first, second] return [first, second]
} }
// Ausnahme 2: /artikel/:slug /magazin
if (segments.length === 2 && segments[0] === 'artikel') { if (segments.length === 2 && segments[0] === 'artikel') {
const magazinePath = i18nPages.magazin?.[loc] || '/magazin' const magazinePath = i18nPages.magazin?.[loc] || '/magazin'
const magazineLabel = t('magazin') || 'Magazin' const magazineLabel = t('magazin') || 'Magazin'
@ -97,7 +123,6 @@ const breadcrumbs = computed<Breadcrumb[]>(() => {
return [first, second] return [first, second]
} }
// Standard-Fall
let path = '' let path = ''
return segments.map(segment => { return segments.map(segment => {
path += '/' + segment path += '/' + segment
@ -110,70 +135,114 @@ const breadcrumbs = computed<Breadcrumb[]>(() => {
}) })
}) })
watch(() => route.fullPath, () => {
isOpen.value = false
})
</script> </script>
<style lang="sass" scoped> <style lang="sass" scoped>
.breadcrumbs .breadcrumbs
position: fixed position: fixed
top: 22vh top: 22vh
left: 0 left: -5px
text-align: left
padding: 1rem .25rem 1rem .5rem
background-color: rgba(white, .98) background-color: rgba(white, .98)
border: 1px solid darken($lightgrey, 5%) border: 1px solid darken($lightgrey, 5%)
writing-mode: vertical-rl
transform: rotate(180deg)
border-top-left-radius: .8rem
border-bottom-left-radius: .8rem
text-transform: uppercase
letter-spacing: .05rem
z-index: 22 z-index: 22
ul padding: .25rem
display: flex border-top-right-radius: .8rem
flex-wrap: wrap border-bottom-right-radius: .8rem
list-style: none transition: all 0.4s ease
padding: 0
margin: 0
gap: 0.5rem
cursor: pointer
li .breadcrumb-container
display: flex
align-items: center
gap: 0.5rem
.breadcrumb-trigger
cursor: pointer
display: flex display: flex
align-items: center align-items: center
color: darken($primaryColor, 10%) justify-content: center
font-size: .7rem width: 1.8rem
height: 1.8rem
svg svg
width: .8rem width: 1rem
height: .8rem height: 1rem
transform: rotate(90deg)
margin-bottom: .35rem
transition: .3s
path path
fill: darken($lightgrey, 20%) fill: darken($lightgrey, 20%)
&:hover &:hover path
transform: scale(1.3) rotate(90deg) fill: darken($lightgrey, 30%)
path
fill: darken($lightgrey, 30%)
&::after // Animierbarer Breadcrumb-Block
content: '>' ul
margin: 0 0.5rem display: flex
color: $pink flex-wrap: wrap
gap: 0.5rem
list-style: none
margin: 0
padding: 0
overflow: hidden
max-width: 0
opacity: 0
transition: all 0.4s ease
&:last-child::after &.open
content: '' max-width: 500px
opacity: 1
a &.closed
color: #007BFF max-height: 0
text-decoration: none opacity: 0
li
font-size: 1.2rem
display: flex
padding: .5rem
align-items: center
color: $darkgrey
a
color: darken($primaryColor, 10%)
.between
margin-right: 1.5rem
font-size: 1.5rem
font-family: 'Mainfont-Bold'
.close-btn
cursor: pointer
font-size: 1.4rem
font-weight: bold
background-color: darken($beige, 10%)
color: white
width: 1.5rem
height: 1.5rem
border-radius: 50%
position: relative
margin: .5rem .5rem 0 2rem
&::before
position: absolute
content: '<'
color: white
top: 50%
left: 50%
transform: translate(-50%, -50%)
&:hover &:hover
transform: scale(1.2) color: darken($primaryColor, 15%)
a
color: #007BFF
text-decoration: none
&:hover
transform: scale(1.2)
span
font-weight: bold
span
font-weight: bold
</style> </style>

View File

@ -14,9 +14,6 @@
alt="" alt=""
class="service-bg" class="service-bg"
aria-hidden="true" aria-hidden="true"
priority
loading="eager"
fetchpriority="high"
/> />
<div class="overlay"></div> <div class="overlay"></div>
<div class="serviceContent"> <div class="serviceContent">

View File

@ -33,9 +33,8 @@
</div> </div>
<ul <ul
v-show="isActiveSubNav(link.label)" class="submenu"
class="submenu" :class="{ open: isActiveSubNav(link.label) }"
:class="{ open: isActiveSubNav(link.label) }"
> >
<li v-for="sublink in link.subNav" :key="sublink.label"> <li v-for="sublink in link.subNav" :key="sublink.label">
<NuxtLinkLocale :to="sublink.routeKey" @click.native="handleMobileClose"> <NuxtLinkLocale :to="sublink.routeKey" @click.native="handleMobileClose">
@ -156,6 +155,7 @@
width: 4rem width: 4rem
height: 4rem height: 4rem
border-radius: 50% border-radius: 50%
border: 1px solid darken($lightgrey, 35%)
background-color: $darkgrey background-color: $darkgrey
display: flex display: flex
align-items: center align-items: center
@ -177,6 +177,7 @@
&.open &.open
background-color: transparent background-color: transparent
margin: 1.2rem 1rem margin: 1.2rem 1rem
border: 1px solid transparent
span span
height: 3px height: 3px
&:nth-child(1) &:nth-child(1)
@ -193,8 +194,11 @@
a a
text-decoration: none text-decoration: none
color: $darkgrey color: $darkgrey
display: inline-block
transition: .4s
&:hover &:hover
transform: scale(1.1) transform: scale(1.04)
.arrow .arrow
display: inline-block display: inline-block
margin-left: 0.5rem margin-left: 0.5rem
@ -213,9 +217,9 @@
opacity: 0 opacity: 0
overflow: hidden overflow: hidden
visibility: hidden visibility: hidden
transition: max-height 0.5s ease, opacity 0.5s ease transition: max-height 0.4s ease-in-out, opacity 0.4s ease-in-out, visibility 0.4s ease-in-out
&.open &.open
max-height: 500px // hoch genug für deinen Content max-height: 500px
opacity: 1 opacity: 1
visibility: visible visibility: visible
@ -243,14 +247,9 @@
.nav-item .nav-item
position: relative position: relative
padding: .5rem 1rem padding: 0rem 1rem
cursor: pointer cursor: pointer
a
transition: .5s
:hover
transform: scale(1.1)
.submenu .submenu
position: absolute position: absolute
top: 100% top: 100%
@ -267,8 +266,8 @@
.mobile-menu .mobile-menu
list-style: none list-style: none
padding: 5rem 8% padding: 5rem 10%
background-color: rgba($darkgrey, .95) background-color: rgba($darkgrey, .97)
width: 6rem width: 6rem
display: flex display: flex
flex-direction: column flex-direction: column
@ -279,13 +278,17 @@
right: 0 right: 0
&.active &.active
width: 80vw max-width: 90vw
width: auto
max-height: 100vh max-height: 100vh
min-height: 70vh
height: auto
border-bottom-left-radius: 2rem border-bottom-left-radius: 2rem
.nav-item .nav-item
position: relative position: relative
padding: .5rem 1rem padding: 1rem 1rem
cursor: pointer cursor: pointer
font-size: 1.25rem
color: white color: white
&::before &::before
content: '' content: ''
@ -294,7 +297,7 @@
background-color: rgba($primaryColor, .9) background-color: rgba($primaryColor, .9)
border-radius: $loopShape border-radius: $loopShape
position: absolute position: absolute
top: .8rem top: 1.3rem
left: -.4rem left: -.4rem
border-radius: 20px border-radius: 20px
@ -303,11 +306,11 @@
list-style: none list-style: none
a a
text-transform: none text-transform: none
font-size: 1.1rem
li, a li, a
transition: .5s transition: .5s
color: white color: white
:hover
transform: scale(1.1)
</style> </style>

View File

@ -20,7 +20,7 @@
</g> </g>
</svg> </svg>
</div> </div>
<div class="container-5"> <div class="container-10">
<div class="row align-items-end"> <div class="row align-items-end">
<div class="col-lg-4 mb-4"> <div class="col-lg-4 mb-4">
<p> <p>

View File

@ -70,12 +70,61 @@
<section class="sectionSolutions">
<svg class="sectionWave wave-top" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 500 20">
<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>
<div class="container-10">
<h2>Unsere Branchenlösungen mit Vorher-/Nachher-Effekt</h2>
<div class="sectorsBox">
<div class="sector">
<NuxtImg
provider="strapi"
src="/uploads/watercolor_da8a37ce48.webp"
alt=""
aria-hidden="true"
class="bgImage"
/>
<div class="contentBox">
<ImageComparisonSlider
before-image="/uploads/Image_Comp_BSK_Before_1ae2a67e1b.png"
after-image="/uploads/BSK_After_9de7feda0b.webp"
/>
<h3>Webseiten für Schulen und Bildungseinrichtungen</h3>
<p v-show="false">Wir gestalten barrierefreie, DSGVO-konforme Schulwebseiten mit modernem Content-Management-System und einfacher Pflege durch das Schulpersonal.</p>
<NuxtLinkLocale :to="'sectors-schools'" class="btn">Informationen zu Schulhompages</NuxtLinkLocale>
</div>
</div>
<div class="sector">
<NuxtImg
provider="strapi"
src="/uploads/filmhintergrundcollage_a0c4b0e99d.webp"
alt=""
aria-hidden="true"
class="bgImage"
/>
<div class="contentBox">
<ImageComparisonSlider
before-image="/uploads/herb_X_vorher_Image_5cef5738f9.webp"
after-image="/uploads/herb_X_nachher_Image_e2d2a388ff.webp"
/>
<h3>Webauftritte für die Film- und Fernsehbranche</h3>
<p v-show="false">Maßgeschneiderte Weblösungen für Produktionen, Studios und Agenturen. Visuell stark, technisch top und bereit für Awards.</p>
<NuxtLinkLocale :to="'sectors-film'" class="btn">Informationen für die Filmbranche</NuxtLinkLocale>
</div>
</div>
</div>
</div>
<svg class="sectionWave wave-bottom" style="transform: scale(1,-1)" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 500 20">
<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="compBox">
<section class="compBox">
<svg class="sectionWave wave-top" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 500 20"> <svg class="sectionWave wave-top" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 500 20">
<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"/> <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> </svg>
@ -102,7 +151,7 @@
<svg class="sectionWave wave-bottom" style="transform: scale(1,-1)" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 500 20"> <svg class="sectionWave wave-bottom" style="transform: scale(1,-1)" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 500 20">
<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"/> <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> </svg>
</section> </section> -->
<CallToActionBox <CallToActionBox
:headline="$t('pages.home.finalCall.title')" :headline="$t('pages.home.finalCall.title')"
@ -123,10 +172,6 @@ import { storeToRefs } from 'pinia';
const mainStore = useMainStore(); const mainStore = useMainStore();
const { customers } = storeToRefs(mainStore); const { customers } = storeToRefs(mainStore);
const toggleContactBubble = () => mainStore.toggleContactBubble();
const logoItems = computed(() => { const logoItems = computed(() => {
return customers.value.map(customer => ({ return customers.value.map(customer => ({
@ -139,7 +184,6 @@ const logoItems = computed(() => {
}) })
</script> </script>
<style lang="sass"> <style lang="sass">
.homePage .homePage
.whatWeDo .whatWeDo
@ -199,11 +243,12 @@ const logoItems = computed(() => {
left: 0 left: 0
width: 100% width: 100%
height: auto height: auto
object-fit: contain object-fit: cover
object-position: center center object-position: center center
z-index: 0 z-index: 0
pointer-events: none pointer-events: none
.content .content
position: relative position: relative
z-index: 1 z-index: 1
@ -230,6 +275,86 @@ const logoItems = computed(() => {
.homeImageTop .homeImageTop
margin: 4.5rem 0 8vh 3rem !important margin: 4.5rem 0 8vh 3rem !important
.sectionSolutions
background-image: linear-gradient(to bottom right, $beige, white, $beige)
min-height: 200px
padding: 5rem 0 7rem 0
position: relative
overflow: hidden
.sectorsBox
display: flex
gap: 5%
justify-content: space-arround
flex-wrap: wrap
.sector
position: relative
flex: 1 1 30%
background: #f9f9f9
padding: 2rem
border-radius: 1rem
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.05)
transition: transform 0.3s ease
border-radius: 1rem
max-width: 350px
margin-bottom: 2rem
.bgImage
position: absolute
inset: 0
width: 100%
height: 100%
object-fit: cover
object-position: center
z-index: 0
border-radius: 1rem
.contentBox
position: relative
z-index: 2
background-image: linear-gradient(to top, rgba(white, .9), rgba(white, .7))
width: 100%
padding: 2rem
border-radius: 1rem
transform: rotate(-1deg)
.image-comparison-container
text-align: center
width: 80%
max-width: 300px
margin: 0 auto 2rem auto
h3
font-size: 1.25rem
margin: 1rem 0 0.5rem
z-index: 3
hyphens: auto
p
font-size: 1rem
color: #333
margin-bottom: 1.5rem
min-height: 4.5rem
z-index: 3
.btn
text-transform: none
hyphens: auto
font-size: 1.1rem
font-family: 'Mainfont-Bold'
@media screen and (max-width: $breakPointMD)
flex-direction: column
.sector
flex: 1 1 100%
max-width: 100%
padding: 1rem
.btn
font-size: 1.05rem
.compBox .compBox
background-image: url(https://strapi.digimedialoop.de/uploads/watercolor_da8a37ce48.webp) background-image: url(https://strapi.digimedialoop.de/uploads/watercolor_da8a37ce48.webp)
background-size: cover background-size: cover

View File

@ -60,7 +60,7 @@
provider="strapi" provider="strapi"
class="ref-img" class="ref-img"
/> />
<h3><a href="#" target="_blank" rel="noopener noreferrer">Michael Bully Herbig Schauspieler & Regisseur</a></h3> <h3>Michael Bully Herbig Schauspieler & Regisseur</h3>
<p>Ein kreativer Kopf mit großer Reichweite. Wir haben seine Künstlerseite technisch und optisch auf den Punkt gebracht. <p>Ein kreativer Kopf mit großer Reichweite. Wir haben seine Künstlerseite technisch und optisch auf den Punkt gebracht.
Modern, dynamisch und benutzerfreundlich.</p> Modern, dynamisch und benutzerfreundlich.</p>
<a href="/projekt/relaunch-kuenstlerseite-von-michael-bully-herbig" class="btn whiteBtn">Zum Projekt</a> <a href="/projekt/relaunch-kuenstlerseite-von-michael-bully-herbig" class="btn whiteBtn">Zum Projekt</a>
@ -72,7 +72,7 @@
provider="strapi" provider="strapi"
class="ref-img" class="ref-img"
/> />
<h3><a href="#" target="_blank" rel="noopener noreferrer">Produktionsfirma herbX</a></h3> <h3>Produktionsfirma herbX</h3>
<p>Professionelle Produktionsfirma mit Anspruch auf Performance und Design. Für herbX haben wir eine Webseite gebaut, <p>Professionelle Produktionsfirma mit Anspruch auf Performance und Design. Für herbX haben wir eine Webseite gebaut,
die Flexibilität und einfache Content-Pflege ermöglicht.</p> die Flexibilität und einfache Content-Pflege ermöglicht.</p>
<a href="/projekt/relaunch-herb-x-film-webauftritt" class="btn whiteBtn">Zum Projekt</a> <a href="/projekt/relaunch-herb-x-film-webauftritt" class="btn whiteBtn">Zum Projekt</a>
@ -248,6 +248,9 @@ import { useMainStore } from '@/stores/main'
flex: 1 1 45% flex: 1 1 45%
text-align: center text-align: center
h3
font-family: 'Comfortaa-Bold'
@media (max-width: $breakPointMD) @media (max-width: $breakPointMD)
.reference-content .reference-content
flex-direction: column flex-direction: column