Init
This commit is contained in:
152
app/components/CommonFooter.vue
Normal file
152
app/components/CommonFooter.vue
Normal file
@@ -0,0 +1,152 @@
|
||||
<script setup lang="ts">
|
||||
const currentYear = new Date().getFullYear()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<footer class="footer">
|
||||
<div class="footer-content">
|
||||
<div class="footer-main">
|
||||
<!-- Logo & Description Column -->
|
||||
<div class="footer-section">
|
||||
<div class="footer-logo">
|
||||
<NuxtLink to="/">
|
||||
<img src="/img/experimenta-logo-white.svg" alt="experimenta Logo" class="footer-logo-svg" />
|
||||
</NuxtLink>
|
||||
</div>
|
||||
<p>
|
||||
experimenta ist Deutschlands größtes Science Center. Mit über 275 Mitmachstationen, vier
|
||||
Kreativstudios, neun Laboren und einer Sternwarte.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<!-- Quick Links Column -->
|
||||
<div class="footer-section">
|
||||
<h3>Rechtliches</h3>
|
||||
<ul class="footer-links">
|
||||
<li><a href="#">Impressum</a></li>
|
||||
<li><a href="#">Datenschutz</a></li>
|
||||
<li><a href="#">AGB</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<!-- Info Column -->
|
||||
<div class="footer-section">
|
||||
<h3>Über uns</h3>
|
||||
<ul class="footer-links">
|
||||
<li><a href="#">experimenta Shop</a></li>
|
||||
<li><a href="#">Kontakt</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<!-- Contact Column -->
|
||||
<div class="footer-section">
|
||||
<h3>Kontakt</h3>
|
||||
<p>experimenta gGmbH<br />Kranenstraße 14<br />74072 Heilbronn</p>
|
||||
<p>
|
||||
<a href="mailto:info@experimenta.science" class="footer-link">info@experimenta.science</a>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Footer Bottom -->
|
||||
<div class="footer-bottom">
|
||||
<p>© {{ currentYear }} experimenta gGmbH. Alle Rechte vorbehalten.</p>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.footer {
|
||||
background: linear-gradient(135deg, #1a0a3a 0%, #0f051d 100%);
|
||||
margin-top: 80px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.footer-content {
|
||||
max-width: 1200px;
|
||||
margin: 0 auto;
|
||||
padding: 60px 20px 30px;
|
||||
}
|
||||
|
||||
.footer-main {
|
||||
display: grid;
|
||||
grid-template-columns: 2.5fr 1fr 1fr 1.5fr;
|
||||
gap: 50px;
|
||||
margin-bottom: 50px;
|
||||
}
|
||||
|
||||
.footer-section h3 {
|
||||
color: #f59d24;
|
||||
margin-bottom: 20px;
|
||||
font-size: 1.25rem;
|
||||
font-weight: 600;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.5px;
|
||||
}
|
||||
|
||||
.footer-section p {
|
||||
margin-bottom: 15px;
|
||||
color: rgba(255, 255, 255, 0.8);
|
||||
line-height: 1.6;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.footer-links {
|
||||
list-style: none;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.footer-links li {
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.footer-links a,
|
||||
.footer-link {
|
||||
color: rgba(255, 255, 255, 0.8);
|
||||
text-decoration: none;
|
||||
font-size: 14px;
|
||||
transition: color 0.3s ease;
|
||||
}
|
||||
|
||||
.footer-links a:hover,
|
||||
.footer-link:hover {
|
||||
color: #ff4081;
|
||||
}
|
||||
|
||||
.footer-logo {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.footer-logo-svg {
|
||||
width: 200px;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
.footer-bottom {
|
||||
border-top: 1px solid rgba(255, 255, 255, 0.1);
|
||||
padding-top: 30px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.footer-bottom p {
|
||||
color: rgba(255, 255, 255, 0.8);
|
||||
font-size: 14px;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
/* Responsive Design */
|
||||
@media (max-width: 768px) {
|
||||
.footer-main {
|
||||
grid-template-columns: 1fr;
|
||||
gap: 30px;
|
||||
}
|
||||
|
||||
.footer-logo-svg {
|
||||
width: 150px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
63
app/components/CommonHeader.vue
Normal file
63
app/components/CommonHeader.vue
Normal file
@@ -0,0 +1,63 @@
|
||||
<script setup lang="ts">
|
||||
// experimenta header with branding
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<header class="header-wrapper">
|
||||
<div class="header-content">
|
||||
<NuxtLink to="/" class="logo">
|
||||
<img src="/img/experimenta-logo-white.svg" alt="experimenta Logo" class="logo-svg" />
|
||||
</NuxtLink>
|
||||
</div>
|
||||
</header>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.header-wrapper {
|
||||
background: rgba(46, 16, 101, 0.95);
|
||||
backdrop-filter: blur(10px);
|
||||
position: relative;
|
||||
z-index: 100;
|
||||
padding: 30px 0;
|
||||
}
|
||||
|
||||
.header-content {
|
||||
max-width: 1200px;
|
||||
margin: 0 auto;
|
||||
padding: 0 20px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.logo {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
text-decoration: none;
|
||||
color: white;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.logo:hover {
|
||||
transform: scale(1.05);
|
||||
}
|
||||
|
||||
.logo-svg {
|
||||
width: 300px;
|
||||
height: auto;
|
||||
filter: drop-shadow(0 4px 8px rgba(0, 0, 0, 0.3));
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.logo-svg {
|
||||
width: 250px;
|
||||
max-width: 90%;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 480px) {
|
||||
.logo-svg {
|
||||
width: 200px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
28
app/components/ui/button/Button.vue
Normal file
28
app/components/ui/button/Button.vue
Normal file
@@ -0,0 +1,28 @@
|
||||
<script setup lang="ts">
|
||||
import type { PrimitiveProps } from 'reka-ui'
|
||||
import type { HTMLAttributes } from 'vue'
|
||||
import type { ButtonVariants } from '.'
|
||||
import { Primitive } from 'reka-ui'
|
||||
import { cn } from '~/lib/utils'
|
||||
import { buttonVariants } from '.'
|
||||
|
||||
interface Props extends PrimitiveProps {
|
||||
variant?: ButtonVariants['variant']
|
||||
size?: ButtonVariants['size']
|
||||
class?: HTMLAttributes['class']
|
||||
}
|
||||
|
||||
const props = withDefaults(defineProps<Props>(), {
|
||||
as: 'button',
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Primitive
|
||||
:as="as"
|
||||
:as-child="asChild"
|
||||
:class="cn(buttonVariants({ variant, size }), props.class)"
|
||||
>
|
||||
<slot />
|
||||
</Primitive>
|
||||
</template>
|
||||
36
app/components/ui/button/index.ts
Normal file
36
app/components/ui/button/index.ts
Normal file
@@ -0,0 +1,36 @@
|
||||
import type { VariantProps } from 'class-variance-authority'
|
||||
import { cva } from 'class-variance-authority'
|
||||
|
||||
export { default as Button } from './Button.vue'
|
||||
|
||||
export const buttonVariants = cva(
|
||||
'inline-flex items-center justify-center gap-2 whitespace-nowrap text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0',
|
||||
{
|
||||
variants: {
|
||||
variant: {
|
||||
default: 'btn-experimenta',
|
||||
destructive: 'bg-destructive text-destructive-foreground hover:bg-destructive/90 rounded-md',
|
||||
outline: 'border border-input bg-background hover:bg-accent hover:text-accent-foreground rounded-md',
|
||||
secondary: 'bg-secondary text-secondary-foreground hover:bg-secondary/80 rounded-md',
|
||||
ghost: 'hover:bg-accent hover:text-accent-foreground rounded-md',
|
||||
link: 'text-primary underline-offset-4 hover:underline',
|
||||
experimenta: 'btn-experimenta',
|
||||
},
|
||||
size: {
|
||||
default: 'px-[30px] py-[10px] text-lg leading-[1.7em]',
|
||||
sm: 'h-9 rounded-md px-3',
|
||||
lg: 'h-11 rounded-md px-8',
|
||||
icon: 'h-10 w-10',
|
||||
'icon-sm': 'size-9',
|
||||
'icon-lg': 'size-11',
|
||||
experimenta: 'px-[30px] py-[10px] text-lg leading-[1.7em]',
|
||||
},
|
||||
},
|
||||
defaultVariants: {
|
||||
variant: 'default',
|
||||
size: 'default',
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
export type ButtonVariants = VariantProps<typeof buttonVariants>
|
||||
Reference in New Issue
Block a user