Initial commit for Greenlens

This commit is contained in:
Timo Knuth
2026-03-16 21:31:46 +01:00
parent 307135671f
commit 05d4f6e78b
573 changed files with 54233 additions and 1891 deletions

View File

@@ -0,0 +1,165 @@
'use client'
import Image from 'next/image'
import { useLang } from '@/context/LangContext'
const featurePillIcons = [
<svg key="a" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="var(--green-light)" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
<path d="M12 2.69l5.66 5.66a8 8 0 1 1-11.31 0z" />
</svg>,
<svg key="b" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="var(--green-light)" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
<path d="M22 12h-2.48a2 2 0 0 0-1.93 1.46l-2.35 8.36a.25.25 0 0 1-.48 0L9.24 2.18a.25.25 0 0 0-.48 0l-2.35 8.36A2 2 0 0 1 4.49 12H2" />
</svg>,
<svg key="c" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="var(--green-light)" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
<path d="M20 10c0 6-8 12-8 12s-8-6-8-12a8 8 0 0 1 16 0Z" />
<circle cx="12" cy="10" r="3" />
</svg>,
]
const PILL_KEYS = [
{ titleKey: 'pillRemindersTitle', descKey: 'pillRemindersDesc' },
{ titleKey: 'pillDiagTitle', descKey: 'pillDiagDesc' },
{ titleKey: 'pillLocationTitle', descKey: 'pillLocationDesc' },
] as const
const PILL_TEXT = {
de: [
{ title: 'Smarte Erinnerungen', desc: 'Vergiss nie mehr das Gießen personalisiert für jede Pflanze.' },
{ title: 'Diagnose & Hilfe', desc: 'KI erkennt Krankheiten und Schädlinge sofort.' },
{ title: 'Standort-Tipps', desc: 'Pflegehinweise basierend auf deinem Klima und Licht.' },
],
en: [
{ title: 'Smart Reminders', desc: 'Never forget watering again personalized for every plant.' },
{ title: 'Diagnosis & Help', desc: 'AI detects diseases and pests instantly.' },
{ title: 'Location Tips', desc: 'Care advice based on your climate and light conditions.' },
],
es: [
{ title: 'Recordatorios inteligentes', desc: 'Nunca olvides regar personalizado para cada planta.' },
{ title: 'Diagnóstico y ayuda', desc: 'La IA detecta enfermedades y plagas al instante.' },
{ title: 'Consejos por ubicación', desc: 'Consejos basados en tu clima y condiciones de luz.' },
],
}
const CARD_TEXT = {
de: {
chip1: 'KI Scan', h3a: 'Scan it.', pa: 'Richte die Kamera auf jede Pflanze GreenLens erkennt sie in Sekundenbruchteilen und liefert alle Infos.',
chip2: 'Tracking', h3b: 'Track it.', pb: 'Gießplan, Lichtbedarf und Wachstum alles in einer Timeline.',
chip3: 'Sammlung', h3c: 'Grow it.', pc: 'Baue deine digitale Pflanzenbibliothek auf mit Fotos und Notizen.',
altA: 'Person scannt eine Pflanze mit der GreenLens App',
altB: 'Pflanzen auf einem Regal mit Pflegeplänen',
altC: 'Pflanzensammlung im Urban Jungle Stil',
},
en: {
chip1: 'AI Scan', h3a: 'Scan it.', pa: 'Point your camera at any plant GreenLens identifies it in milliseconds and delivers all the info.',
chip2: 'Tracking', h3b: 'Track it.', pb: 'Watering schedule, light needs and growth all in one timeline.',
chip3: 'Collection', h3c: 'Grow it.', pc: 'Build your digital plant library with photos and notes.',
altA: 'Person scanning a plant with the GreenLens app',
altB: 'Plants on a shelf with care plans',
altC: 'Plant collection in urban jungle style',
},
es: {
chip1: 'Escaneo IA', h3a: 'Escanéala.', pa: 'Apunta la cámara a cualquier planta GreenLens la identifica en milisegundos y entrega toda la información.',
chip2: 'Seguimiento', h3b: 'Monitoréala.', pb: 'Plan de riego, necesidades de luz y crecimiento todo en una línea de tiempo.',
chip3: 'Colección', h3c: 'Hazla crecer.', pc: 'Construye tu biblioteca digital de plantas con fotos y notas.',
altA: 'Persona escaneando una planta con la app GreenLens',
altB: 'Plantas en un estante con planes de cuidado',
altC: 'Colección de plantas estilo jungla urbana',
},
}
export default function Features() {
const { lang, t } = useLang()
const cards = CARD_TEXT[lang]
const pills = PILL_TEXT[lang]
return (
<section className="features" id="features" aria-labelledby="features-heading">
<div className="container">
{/* Header */}
<header className="features-header reveal">
<p className="tag">{t.features.tag}</p>
<h2 id="features-heading">
{t.features.h2a}<br />{t.features.h2b}
</h2>
<p>{t.features.desc}</p>
</header>
{/* Bento grid */}
<div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: '1rem' }}>
{/* Left large card: Scan it */}
<div className="bento-card bento-large reveal">
<Image
src="/scan-feature.png"
alt={cards.altA}
fill
sizes="(max-width: 768px) 100vw, 50vw"
className="bento-card-img"
style={{ objectFit: 'cover' }}
/>
<div className="bento-card-overlay" />
<div className="bento-card-content">
<span className="bento-chip">{cards.chip1}</span>
<h3>{cards.h3a}</h3>
<p>{cards.pa}</p>
</div>
</div>
{/* Right two stacked cards */}
<div style={{ display: 'grid', gridTemplateRows: '1fr 1fr', gap: '1rem' }}>
<div className="bento-card bento-small reveal delay-1">
<Image
src="/track-feature.png"
alt={cards.altB}
fill
sizes="(max-width: 768px) 100vw, 25vw"
className="bento-card-img"
style={{ objectFit: 'cover' }}
/>
<div className="bento-card-overlay" />
<div className="bento-card-content">
<span className="bento-chip">{cards.chip2}</span>
<h3>{cards.h3b}</h3>
<p>{cards.pb}</p>
</div>
</div>
<div className="bento-card bento-small reveal delay-2">
<Image
src="/plant-collection.png"
alt={cards.altC}
fill
sizes="(max-width: 768px) 100vw, 25vw"
className="bento-card-img"
style={{ objectFit: 'cover' }}
/>
<div className="bento-card-overlay" />
<div className="bento-card-content">
<span className="bento-chip">{cards.chip3}</span>
<h3>{cards.h3c}</h3>
<p>{cards.pc}</p>
</div>
</div>
</div>
</div>
{/* Feature pills */}
<div className="features-pills">
{pills.map((f, i) => (
<div className={`feature-pill reveal delay-${i + 1}`} key={f.title}>
<div className="feature-pill-icon">{featurePillIcons[i]}</div>
<div className="feature-pill-text">
<h4>{f.title}</h4>
<p>{f.desc}</p>
</div>
</div>
))}
</div>
</div>
</section>
)
}