managarten/packages/shared-landing-ui/src/sections/PrinciplesSection.astro
Till-JS 264149a913 feat(shared-landing-ui): unify landing pages with shared components
Add new reusable components to shared-landing-ui package:
- AppScrollerSection, TimelineSection, MasonryGridSection, PrinciplesSection
- LegalPageTemplate for privacy/terms/cookies/imprint pages
- Navigation component with mobile menu and language switcher
- GradientText and LanguageSwitcher atoms
- i18n system with getLangFromUrl, useTranslations, localizePath
- Theme files for picture (indigo), chat (blue), zitare (teal)

Add legal pages to ManaDeck and Chat landing pages:
- privacy, terms, cookies, imprint pages using shared template
- Updated footers with cookies link
2026-01-23 15:45:47 +01:00

280 lines
7 KiB
Text

---
/**
* PrinciplesSection - Horizontal cards with icons
*
* Usage:
* ```astro
* <PrinciplesSection
* principles={[
* { icon: 'lightning', title: 'Scalable with AI', description: '...' },
* { icon: 'chat', title: 'Tight Feedback Loop', description: '...' }
* ]}
* />
* ```
*/
export interface Principle {
icon:
| 'lightning'
| 'chat'
| 'globe'
| 'heart'
| 'shield'
| 'star'
| 'code'
| 'users'
| 'rocket'
| 'check';
title: string;
description: string;
}
interface Props {
principles: Principle[];
class?: string;
}
const { principles, class: className = '' } = Astro.props;
// SVG paths for icons
const iconPaths: Record<string, string> = {
lightning: 'M13 10V3L4 14h7v7l9-11h-7z',
chat: 'M8 12h.01M12 12h.01M16 12h.01M21 12c0 4.418-4.03 8-9 8a9.863 9.863 0 01-4.255-.949L3 20l1.395-3.72C3.512 15.042 3 13.574 3 12c0-4.418 4.03-8 9-8s9 3.582 9 8z',
globe:
'M3.055 11H5a2 2 0 012 2v1a2 2 0 002 2 2 2 0 012 2v2.945M8 3.935V5.5A2.5 2.5 0 0010.5 8h.5a2 2 0 012 2 2 2 0 104 0 2 2 0 012-2h1.064M15 20.488V18a2 2 0 012-2h3.064M21 12a9 9 0 11-18 0 9 9 0 0118 0z',
heart:
'M4.318 6.318a4.5 4.5 0 000 6.364L12 20.364l7.682-7.682a4.5 4.5 0 00-6.364-6.364L12 7.636l-1.318-1.318a4.5 4.5 0 00-6.364 0z',
shield:
'M9 12l2 2 4-4m5.618-4.016A11.955 11.955 0 0112 2.944a11.955 11.955 0 01-8.618 3.04A12.02 12.02 0 003 9c0 5.591 3.824 10.29 9 11.622 5.176-1.332 9-6.03 9-11.622 0-1.042-.133-2.052-.382-3.016z',
star: 'M11.049 2.927c.3-.921 1.603-.921 1.902 0l1.519 4.674a1 1 0 00.95.69h4.915c.969 0 1.371 1.24.588 1.81l-3.976 2.888a1 1 0 00-.363 1.118l1.518 4.674c.3.922-.755 1.688-1.538 1.118l-3.976-2.888a1 1 0 00-1.176 0l-3.976 2.888c-.783.57-1.838-.197-1.538-1.118l1.518-4.674a1 1 0 00-.363-1.118l-3.976-2.888c-.784-.57-.38-1.81.588-1.81h4.914a1 1 0 00.951-.69l1.519-4.674z',
code: 'M10 20l4-16m4 4l4 4-4 4M6 16l-4-4 4-4',
users:
'M12 4.354a4 4 0 110 5.292M15 21H3v-1a6 6 0 0112 0v1zm0 0h6v-1a6 6 0 00-9-5.197M13 7a4 4 0 11-8 0 4 4 0 018 0z',
rocket:
'M15.59 14.37a6 6 0 01-5.84 7.38v-4.8m5.84-2.58a14.98 14.98 0 006.16-12.12A14.98 14.98 0 009.631 8.41m5.96 5.96a14.926 14.926 0 01-5.841 2.58m-.119-8.54a6 6 0 00-7.381 5.84h4.8m2.581-5.84a14.927 14.927 0 00-2.58 5.84m2.699 2.7c-.103.021-.207.041-.311.06a15.09 15.09 0 01-2.448-2.448 14.9 14.9 0 01.06-.312m-2.24 2.39a4.493 4.493 0 00-1.757 4.306 4.493 4.493 0 004.306-1.758M16.5 9a1.5 1.5 0 11-3 0 1.5 1.5 0 013 0z',
check: 'M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z',
};
---
<section class:list={['principles-section', className]}>
<div class="principles-overlay"></div>
<div class="principles-container">
<div class="principles-grid">
{
principles.map((principle) => (
<div class="principle-card">
<div class="principle-card-inner">
<div class="principle-icon-wrapper">
<svg class="principle-icon" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d={iconPaths[principle.icon] || iconPaths.star}
/>
</svg>
</div>
<div class="principle-content">
<h3 class="principle-title">{principle.title}</h3>
<p class="principle-description">{principle.description}</p>
</div>
</div>
</div>
))
}
</div>
</div>
</section>
<style>
.principles-section {
position: relative;
background: linear-gradient(
180deg,
var(--color-background-card) 0%,
var(--color-background-page) 100%
);
padding: 160px 0;
overflow: hidden;
}
.principles-overlay {
position: absolute;
inset: 0;
background:
radial-gradient(circle at 30% 50%, var(--color-primary-glow) 0%, transparent 50%),
radial-gradient(circle at 70% 50%, var(--color-primary-glow) 0%, transparent 50%);
opacity: 0.3;
pointer-events: none;
}
.principles-container {
position: relative;
max-width: 1400px;
margin: 0 auto;
padding: 0 80px;
z-index: 10;
}
.principles-grid {
display: grid;
grid-template-columns: 1fr;
gap: 30px;
max-width: 1200px;
margin: 0 auto;
}
.principle-card {
position: relative;
transition: transform 0.4s cubic-bezier(0.4, 0, 0.2, 1);
}
.principle-card:hover {
transform: translateY(-8px);
}
.principle-card-inner {
height: 100%;
background: linear-gradient(
135deg,
var(--color-background-card) 0%,
var(--color-background-page) 100%
);
border: 1px solid var(--color-border);
border-radius: 24px;
padding: 50px;
display: grid;
grid-template-columns: auto 1fr;
gap: 40px;
align-items: center;
backdrop-filter: blur(10px);
position: relative;
overflow: hidden;
transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1);
}
.principle-card-inner::before {
content: '';
position: absolute;
inset: 0;
background: linear-gradient(135deg, transparent 0%, var(--color-primary-glow) 100%);
opacity: 0;
transition: opacity 0.4s ease;
pointer-events: none;
}
.principle-card:hover .principle-card-inner {
border-color: var(--color-primary);
box-shadow:
0 20px 40px -15px rgba(0, 0, 0, 0.5),
0 0 0 1px var(--color-primary-glow);
}
.principle-card:hover .principle-card-inner::before {
opacity: 0.1;
}
.principle-icon-wrapper {
width: 100px;
height: 100px;
flex-shrink: 0;
background: linear-gradient(
135deg,
var(--color-primary-glow) 0%,
var(--color-primary-glow) 100%
);
border-radius: 24px;
display: flex;
align-items: center;
justify-content: center;
transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1);
position: relative;
z-index: 1;
}
.principle-card:hover .principle-icon-wrapper {
background: linear-gradient(135deg, var(--color-primary-glow) 0%, var(--color-primary) 100%);
transform: scale(1.1) rotate(-5deg);
}
.principle-icon {
width: 48px;
height: 48px;
color: var(--color-primary);
transition: all 0.4s ease;
}
.principle-card:hover .principle-icon {
color: var(--color-text-primary);
filter: drop-shadow(0 0 8px var(--color-primary));
}
.principle-content {
display: grid;
grid-template-columns: 1fr 2fr;
gap: 40px;
align-items: center;
z-index: 1;
}
.principle-title {
font-size: clamp(1.75rem, 3vw, 2.25rem);
font-weight: 800;
color: var(--color-text-primary);
margin: 0;
line-height: 1.2;
letter-spacing: -0.02em;
}
.principle-description {
font-size: clamp(1rem, 2vw, 1.125rem);
line-height: 1.7;
color: var(--color-text-secondary);
margin: 0;
}
@media (max-width: 1200px) {
.principle-content {
grid-template-columns: 1fr;
gap: 15px;
}
}
@media (max-width: 1024px) {
.principles-section {
padding: 120px 0;
}
}
@media (max-width: 640px) {
.principles-section {
padding: 80px 0;
}
.principles-container {
padding: 0 40px;
}
.principle-card-inner {
grid-template-columns: 1fr;
text-align: center;
padding: 40px;
}
.principle-icon-wrapper {
width: 80px;
height: 80px;
margin: 0 auto;
}
.principle-icon {
width: 40px;
height: 40px;
}
.principle-content {
align-items: center;
}
}
</style>