Initial website — Astro + Tailwind + Sanity schema, 9 pages
This commit is contained in:
5
.env.example
Normal file
5
.env.example
Normal file
@@ -0,0 +1,5 @@
|
||||
# Sanity-Projekt-ID — aus sanity.io/manage
|
||||
PUBLIC_SANITY_PROJECT_ID=xxxxxxxx
|
||||
|
||||
# Dataset — in der Regel "production"
|
||||
PUBLIC_SANITY_DATASET=production
|
||||
24
.gitignore
vendored
Normal file
24
.gitignore
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
# build output
|
||||
dist/
|
||||
# generated types
|
||||
.astro/
|
||||
|
||||
# dependencies
|
||||
node_modules/
|
||||
|
||||
# logs
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
pnpm-debug.log*
|
||||
|
||||
|
||||
# environment variables
|
||||
.env
|
||||
.env.production
|
||||
|
||||
# macOS-specific files
|
||||
.DS_Store
|
||||
|
||||
# jetbrains setting folder
|
||||
.idea/
|
||||
4
.vscode/extensions.json
vendored
Normal file
4
.vscode/extensions.json
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"recommendations": ["astro-build.astro-vscode"],
|
||||
"unwantedRecommendations": []
|
||||
}
|
||||
11
.vscode/launch.json
vendored
Normal file
11
.vscode/launch.json
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"command": "./node_modules/.bin/astro dev",
|
||||
"name": "Development server",
|
||||
"request": "launch",
|
||||
"type": "node-terminal"
|
||||
}
|
||||
]
|
||||
}
|
||||
43
README.md
Normal file
43
README.md
Normal file
@@ -0,0 +1,43 @@
|
||||
# Astro Starter Kit: Minimal
|
||||
|
||||
```sh
|
||||
npm create astro@latest -- --template minimal
|
||||
```
|
||||
|
||||
> 🧑🚀 **Seasoned astronaut?** Delete this file. Have fun!
|
||||
|
||||
## 🚀 Project Structure
|
||||
|
||||
Inside of your Astro project, you'll see the following folders and files:
|
||||
|
||||
```text
|
||||
/
|
||||
├── public/
|
||||
├── src/
|
||||
│ └── pages/
|
||||
│ └── index.astro
|
||||
└── package.json
|
||||
```
|
||||
|
||||
Astro looks for `.astro` or `.md` files in the `src/pages/` directory. Each page is exposed as a route based on its file name.
|
||||
|
||||
There's nothing special about `src/components/`, but that's where we like to put any Astro/React/Vue/Svelte/Preact components.
|
||||
|
||||
Any static assets, like images, can be placed in the `public/` directory.
|
||||
|
||||
## 🧞 Commands
|
||||
|
||||
All commands are run from the root of the project, from a terminal:
|
||||
|
||||
| Command | Action |
|
||||
| :------------------------ | :----------------------------------------------- |
|
||||
| `npm install` | Installs dependencies |
|
||||
| `npm run dev` | Starts local dev server at `localhost:4321` |
|
||||
| `npm run build` | Build your production site to `./dist/` |
|
||||
| `npm run preview` | Preview your build locally, before deploying |
|
||||
| `npm run astro ...` | Run CLI commands like `astro add`, `astro check` |
|
||||
| `npm run astro -- --help` | Get help using the Astro CLI |
|
||||
|
||||
## 👀 Want to learn more?
|
||||
|
||||
Feel free to check [our documentation](https://docs.astro.build) or jump into our [Discord server](https://astro.build/chat).
|
||||
13
astro.config.mjs
Normal file
13
astro.config.mjs
Normal file
@@ -0,0 +1,13 @@
|
||||
// @ts-check
|
||||
import { defineConfig } from "astro/config";
|
||||
import tailwindcss from "@tailwindcss/vite";
|
||||
|
||||
export default defineConfig({
|
||||
site: "https://kitafreunde-regenbogen.de",
|
||||
vite: {
|
||||
plugins: [tailwindcss()],
|
||||
},
|
||||
// Für Cloudflare Pages: output auf "static" (default)
|
||||
// Wenn Server-Features gewünscht: output: "server", adapter: cloudflare()
|
||||
output: "static",
|
||||
});
|
||||
5694
package-lock.json
generated
Normal file
5694
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
21
package.json
Normal file
21
package.json
Normal file
@@ -0,0 +1,21 @@
|
||||
{
|
||||
"name": "kitafreunde-regenbogen",
|
||||
"type": "module",
|
||||
"version": "0.0.1",
|
||||
"engines": {
|
||||
"node": ">=22.12.0"
|
||||
},
|
||||
"scripts": {
|
||||
"dev": "astro dev",
|
||||
"build": "astro build",
|
||||
"preview": "astro preview",
|
||||
"astro": "astro"
|
||||
},
|
||||
"dependencies": {
|
||||
"@portabletext/to-html": "^5.0.2",
|
||||
"@sanity/client": "^7.22.1",
|
||||
"@tailwindcss/vite": "^4.3.0",
|
||||
"astro": "^6.4.4",
|
||||
"tailwindcss": "^4.3.0"
|
||||
}
|
||||
}
|
||||
BIN
public/favicon.ico
Normal file
BIN
public/favicon.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 655 B |
9
public/favicon.svg
Normal file
9
public/favicon.svg
Normal file
@@ -0,0 +1,9 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 128 128">
|
||||
<path d="M50.4 78.5a75.1 75.1 0 0 0-28.5 6.9l24.2-65.7c.7-2 1.9-3.2 3.4-3.2h29c1.5 0 2.7 1.2 3.4 3.2l24.2 65.7s-11.6-7-28.5-7L67 45.5c-.4-1.7-1.6-2.8-2.9-2.8-1.3 0-2.5 1.1-2.9 2.7L50.4 78.5Zm-1.1 28.2Zm-4.2-20.2c-2 6.6-.6 15.8 4.2 20.2a17.5 17.5 0 0 1 .2-.7 5.5 5.5 0 0 1 5.7-4.5c2.8.1 4.3 1.5 4.7 4.7.2 1.1.2 2.3.2 3.5v.4c0 2.7.7 5.2 2.2 7.4a13 13 0 0 0 5.7 4.9v-.3l-.2-.3c-1.8-5.6-.5-9.5 4.4-12.8l1.5-1a73 73 0 0 0 3.2-2.2 16 16 0 0 0 6.8-11.4c.3-2 .1-4-.6-6l-.8.6-1.6 1a37 37 0 0 1-22.4 2.7c-5-.7-9.7-2-13.2-6.2Z" />
|
||||
<style>
|
||||
path { fill: #000; }
|
||||
@media (prefers-color-scheme: dark) {
|
||||
path { fill: #FFF; }
|
||||
}
|
||||
</style>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 749 B |
30
sanity/sanity.config.ts
Normal file
30
sanity/sanity.config.ts
Normal file
@@ -0,0 +1,30 @@
|
||||
import { defineConfig } from "sanity";
|
||||
import { structureTool } from "sanity/structure";
|
||||
import { visionTool } from "@sanity/vision";
|
||||
import { schemaTypes } from "./schemas";
|
||||
|
||||
export default defineConfig({
|
||||
name: "kitafreunde-regenbogen",
|
||||
title: "Kitafreunde Regenbogen",
|
||||
|
||||
projectId: process.env.SANITY_STUDIO_PROJECT_ID!,
|
||||
dataset: process.env.SANITY_STUDIO_DATASET ?? "production",
|
||||
|
||||
plugins: [
|
||||
structureTool({
|
||||
structure: (S) =>
|
||||
S.list()
|
||||
.title("Inhalt")
|
||||
.items([
|
||||
S.documentTypeListItem("post").title("Aktuelles / Blog"),
|
||||
S.documentTypeListItem("project").title("Projekte"),
|
||||
S.documentTypeListItem("teamMember").title("Vorstand"),
|
||||
S.divider(),
|
||||
S.documentTypeListItem("siteSettings").title("Website-Einstellungen"),
|
||||
]),
|
||||
}),
|
||||
visionTool(),
|
||||
],
|
||||
|
||||
schema: { types: schemaTypes },
|
||||
});
|
||||
6
sanity/schemas/index.ts
Normal file
6
sanity/schemas/index.ts
Normal file
@@ -0,0 +1,6 @@
|
||||
import post from "./post";
|
||||
import project from "./project";
|
||||
import teamMember from "./teamMember";
|
||||
import siteSettings from "./siteSettings";
|
||||
|
||||
export const schemaTypes = [post, project, teamMember, siteSettings];
|
||||
39
sanity/schemas/post.ts
Normal file
39
sanity/schemas/post.ts
Normal file
@@ -0,0 +1,39 @@
|
||||
import { defineType, defineField } from "sanity";
|
||||
|
||||
export default defineType({
|
||||
name: "post",
|
||||
title: "Aktuelles / Blog",
|
||||
type: "document",
|
||||
fields: [
|
||||
defineField({ name: "title", title: "Titel", type: "string", validation: (r) => r.required() }),
|
||||
defineField({ name: "slug", title: "URL-Slug", type: "slug", options: { source: "title" }, validation: (r) => r.required() }),
|
||||
defineField({ name: "publishedAt", title: "Veröffentlicht am", type: "datetime", validation: (r) => r.required() }),
|
||||
defineField({ name: "excerpt", title: "Kurzbeschreibung", type: "text", rows: 3 }),
|
||||
defineField({ name: "coverImage", title: "Titelbild", type: "image", options: { hotspot: true } }),
|
||||
defineField({
|
||||
name: "body",
|
||||
title: "Inhalt",
|
||||
type: "array",
|
||||
of: [
|
||||
{ type: "block" },
|
||||
{ type: "image", options: { hotspot: true } },
|
||||
],
|
||||
}),
|
||||
defineField({
|
||||
name: "category",
|
||||
title: "Kategorie",
|
||||
type: "string",
|
||||
options: {
|
||||
list: [
|
||||
{ title: "Vereinsnews", value: "news" },
|
||||
{ title: "Projekte", value: "projects" },
|
||||
{ title: "Veranstaltungen", value: "events" },
|
||||
{ title: "Presse", value: "press" },
|
||||
],
|
||||
},
|
||||
}),
|
||||
],
|
||||
preview: {
|
||||
select: { title: "title", subtitle: "publishedAt", media: "coverImage" },
|
||||
},
|
||||
});
|
||||
38
sanity/schemas/project.ts
Normal file
38
sanity/schemas/project.ts
Normal file
@@ -0,0 +1,38 @@
|
||||
import { defineType, defineField } from "sanity";
|
||||
|
||||
export default defineType({
|
||||
name: "project",
|
||||
title: "Projekte",
|
||||
type: "document",
|
||||
fields: [
|
||||
defineField({ name: "title", title: "Projektname", type: "string", validation: (r) => r.required() }),
|
||||
defineField({ name: "slug", title: "URL-Slug", type: "slug", options: { source: "title" }, validation: (r) => r.required() }),
|
||||
defineField({ name: "date", title: "Zeitraum", type: "string", description: 'z.B. "Sommer 2024" oder "März–Mai 2024"' }),
|
||||
defineField({ name: "summary", title: "Kurzbeschreibung", type: "text", rows: 3, validation: (r) => r.required() }),
|
||||
defineField({
|
||||
name: "body",
|
||||
title: "Ausführliche Beschreibung",
|
||||
type: "array",
|
||||
of: [{ type: "block" }, { type: "image", options: { hotspot: true } }],
|
||||
}),
|
||||
defineField({ name: "image", title: "Hauptbild", type: "image", options: { hotspot: true } }),
|
||||
defineField({ name: "targetGroup", title: "Für wen", type: "string", description: 'z.B. "Alle Kinder" oder "Gruppe Schmetterlinge"' }),
|
||||
defineField({ name: "featured", title: "Auf Startseite hervorheben?", type: "boolean", initialValue: false }),
|
||||
defineField({
|
||||
name: "status",
|
||||
title: "Status",
|
||||
type: "string",
|
||||
options: {
|
||||
list: [
|
||||
{ title: "Geplant", value: "planned" },
|
||||
{ title: "Laufend", value: "active" },
|
||||
{ title: "Abgeschlossen", value: "done" },
|
||||
],
|
||||
},
|
||||
initialValue: "done",
|
||||
}),
|
||||
],
|
||||
preview: {
|
||||
select: { title: "title", subtitle: "date", media: "image" },
|
||||
},
|
||||
});
|
||||
62
sanity/schemas/siteSettings.ts
Normal file
62
sanity/schemas/siteSettings.ts
Normal file
@@ -0,0 +1,62 @@
|
||||
import { defineType, defineField } from "sanity";
|
||||
|
||||
export default defineType({
|
||||
name: "siteSettings",
|
||||
title: "Website-Einstellungen",
|
||||
type: "document",
|
||||
// Singleton — nur ein Dokument
|
||||
__experimental_actions: ["update", "publish"],
|
||||
fields: [
|
||||
defineField({
|
||||
name: "contact",
|
||||
title: "Kontakt",
|
||||
type: "object",
|
||||
fields: [
|
||||
{ name: "email", title: "E-Mail", type: "string" },
|
||||
{ name: "phone", title: "Telefon (optional)", type: "string" },
|
||||
{ name: "address", title: "Adresse", type: "string", initialValue: "Keilerstraße 23, 13503 Berlin" },
|
||||
],
|
||||
}),
|
||||
defineField({
|
||||
name: "bank",
|
||||
title: "Bankverbindung",
|
||||
type: "object",
|
||||
fields: [
|
||||
{ name: "iban", title: "IBAN", type: "string" },
|
||||
{ name: "bic", title: "BIC", type: "string" },
|
||||
{ name: "bank", title: "Bankname", type: "string" },
|
||||
{ name: "accountHolder", title: "Kontoinhaber", type: "string", initialValue: "Kitafreunde Regenbogen e.V." },
|
||||
],
|
||||
}),
|
||||
defineField({
|
||||
name: "social",
|
||||
title: "Social Media",
|
||||
type: "object",
|
||||
fields: [
|
||||
{ name: "instagram", title: "Instagram-URL", type: "url" },
|
||||
{ name: "facebook", title: "Facebook-URL", type: "url" },
|
||||
],
|
||||
}),
|
||||
defineField({
|
||||
name: "memberFees",
|
||||
title: "Mitgliedsbeiträge",
|
||||
type: "object",
|
||||
fields: [
|
||||
{ name: "active", title: "Aktives Mitglied (Mindestbeitrag €/Jahr)", type: "number", initialValue: 12 },
|
||||
{ name: "supporting", title: "Fördermitglied (Mindestbeitrag €/Jahr)", type: "number", initialValue: 6 },
|
||||
{ name: "admissionFee", title: "Aufnahmegebühr €", type: "number", initialValue: 5 },
|
||||
],
|
||||
}),
|
||||
defineField({
|
||||
name: "stats",
|
||||
title: "Zahlen für die Startseite",
|
||||
type: "object",
|
||||
fields: [
|
||||
{ name: "members", title: "Mitgliederzahl", type: "number" },
|
||||
{ name: "fundsPerYear", title: "Fördersumme €/Jahr", type: "number" },
|
||||
{ name: "projectsTotal", title: "Projekte gesamt", type: "number" },
|
||||
],
|
||||
}),
|
||||
],
|
||||
preview: { select: { title: "contact.email" } },
|
||||
});
|
||||
31
sanity/schemas/teamMember.ts
Normal file
31
sanity/schemas/teamMember.ts
Normal file
@@ -0,0 +1,31 @@
|
||||
import { defineType, defineField } from "sanity";
|
||||
|
||||
export default defineType({
|
||||
name: "teamMember",
|
||||
title: "Vorstandsmitglieder",
|
||||
type: "document",
|
||||
fields: [
|
||||
defineField({ name: "name", title: "Name", type: "string", validation: (r) => r.required() }),
|
||||
defineField({
|
||||
name: "role",
|
||||
title: "Funktion",
|
||||
type: "string",
|
||||
options: {
|
||||
list: [
|
||||
{ title: "Vorsitzende/r", value: "chair" },
|
||||
{ title: "Stellvertretung", value: "deputy" },
|
||||
{ title: "Kassenwart/in", value: "treasurer" },
|
||||
{ title: "Beisitz", value: "board" },
|
||||
],
|
||||
},
|
||||
validation: (r) => r.required(),
|
||||
}),
|
||||
defineField({ name: "bio", title: "Kurz-Bio", type: "text", rows: 2 }),
|
||||
defineField({ name: "photo", title: "Foto", type: "image", options: { hotspot: true } }),
|
||||
defineField({ name: "order", title: "Reihenfolge", type: "number", initialValue: 99 }),
|
||||
],
|
||||
orderings: [{ title: "Reihenfolge", name: "orderAsc", by: [{ field: "order", direction: "asc" }] }],
|
||||
preview: {
|
||||
select: { title: "name", subtitle: "role", media: "photo" },
|
||||
},
|
||||
});
|
||||
48
src/components/Footer.astro
Normal file
48
src/components/Footer.astro
Normal file
@@ -0,0 +1,48 @@
|
||||
---
|
||||
const year = new Date().getFullYear();
|
||||
---
|
||||
|
||||
<footer class="mt-24 border-t border-[var(--color-border)] bg-[var(--color-surface-alt)]">
|
||||
<div class="rainbow-bar"></div>
|
||||
<div class="max-w-6xl mx-auto px-4 py-12 grid grid-cols-1 md:grid-cols-3 gap-8">
|
||||
|
||||
<div>
|
||||
<p class="font-brand text-xl text-[var(--color-primary)] mb-3">🌈 Kitafreunde Regenbogen</p>
|
||||
<p class="text-sm text-[var(--color-text-muted)] leading-relaxed">
|
||||
Förderverein der Integrationskindertagesstätte Regenbogen<br>
|
||||
Keilerstraße 23 · 13503 Berlin
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<p class="font-semibold text-sm mb-3">Navigation</p>
|
||||
<ul class="text-sm text-[var(--color-text-muted)] space-y-2">
|
||||
<li><a href="/ueber-uns" class="hover:text-[var(--color-primary)]">Über uns</a></li>
|
||||
<li><a href="/was-wir-tun" class="hover:text-[var(--color-primary)]">Was wir tun</a></li>
|
||||
<li><a href="/projekte" class="hover:text-[var(--color-primary)]">Projekte</a></li>
|
||||
<li><a href="/aktuelles" class="hover:text-[var(--color-primary)]">Aktuelles</a></li>
|
||||
<li><a href="/presse" class="hover:text-[var(--color-primary)]">Presse</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<p class="font-semibold text-sm mb-3">Mitmachen</p>
|
||||
<ul class="text-sm text-[var(--color-text-muted)] space-y-2">
|
||||
<li><a href="/mitglied-werden" class="hover:text-[var(--color-primary)]">Mitglied werden</a></li>
|
||||
<li><a href="/unterstuetzen" class="hover:text-[var(--color-primary)]">Spenden</a></li>
|
||||
<li><a href="/kontakt" class="hover:text-[var(--color-primary)]">Kontakt</a></li>
|
||||
</ul>
|
||||
<p class="text-xs text-[var(--color-text-muted)] mt-4">
|
||||
Gemeinnützig anerkannt · Spenden steuerlich absetzbar
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="border-t border-[var(--color-border)] max-w-6xl mx-auto px-4 py-4 flex flex-col md:flex-row justify-between text-xs text-[var(--color-text-muted)]">
|
||||
<span>© {year} Kitafreunde Regenbogen e.V.</span>
|
||||
<div class="flex gap-4 mt-2 md:mt-0">
|
||||
<a href="/impressum" class="hover:text-[var(--color-primary)]">Impressum</a>
|
||||
<a href="/datenschutz" class="hover:text-[var(--color-primary)]">Datenschutz</a>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
68
src/components/Header.astro
Normal file
68
src/components/Header.astro
Normal file
@@ -0,0 +1,68 @@
|
||||
---
|
||||
const nav = [
|
||||
{ href: "/ueber-uns", label: "Über uns" },
|
||||
{ href: "/was-wir-tun", label: "Was wir tun" },
|
||||
{ href: "/projekte", label: "Projekte" },
|
||||
{ href: "/aktuelles", label: "Aktuelles" },
|
||||
{ href: "/unterstuetzen", label: "Unterstützen" },
|
||||
];
|
||||
|
||||
const pathname = Astro.url.pathname;
|
||||
---
|
||||
|
||||
<header class="sticky top-0 z-50 bg-white/95 backdrop-blur border-b border-[var(--color-border)]">
|
||||
<div class="rainbow-bar"></div>
|
||||
<div class="max-w-6xl mx-auto px-4 flex items-center justify-between h-16">
|
||||
<a href="/" class="flex items-center gap-2 font-brand text-xl text-[var(--color-primary)]">
|
||||
🌈 Kitafreunde Regenbogen
|
||||
</a>
|
||||
|
||||
<!-- Desktop Nav -->
|
||||
<nav class="hidden md:flex items-center gap-6 text-sm font-medium">
|
||||
{nav.map(({ href, label }) => (
|
||||
<a
|
||||
href={href}
|
||||
class:list={[
|
||||
"transition-colors hover:text-[var(--color-primary)]",
|
||||
pathname.startsWith(href)
|
||||
? "text-[var(--color-primary)] font-semibold"
|
||||
: "text-[var(--color-text-muted)]"
|
||||
]}
|
||||
>
|
||||
{label}
|
||||
</a>
|
||||
))}
|
||||
</nav>
|
||||
|
||||
<a href="/mitglied-werden" class="btn-primary text-sm hidden md:inline-flex">
|
||||
Mitglied werden
|
||||
</a>
|
||||
|
||||
<!-- Mobile Menu Button -->
|
||||
<button
|
||||
id="mobile-menu-btn"
|
||||
class="md:hidden p-2 rounded-lg text-[var(--color-text-muted)]"
|
||||
aria-label="Menü öffnen"
|
||||
>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="w-6 h-6" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 12h16M4 18h16"/>
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<!-- Mobile Nav -->
|
||||
<div id="mobile-menu" class="hidden md:hidden border-t border-[var(--color-border)] bg-white">
|
||||
<div class="px-4 py-4 flex flex-col gap-4 text-sm font-medium">
|
||||
{nav.map(({ href, label }) => (
|
||||
<a href={href} class="text-[var(--color-text)] hover:text-[var(--color-primary)]">{label}</a>
|
||||
))}
|
||||
<a href="/mitglied-werden" class="btn-primary text-center">Mitglied werden</a>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<script>
|
||||
const btn = document.getElementById("mobile-menu-btn");
|
||||
const menu = document.getElementById("mobile-menu");
|
||||
btn?.addEventListener("click", () => menu?.classList.toggle("hidden"));
|
||||
</script>
|
||||
52
src/layouts/Layout.astro
Normal file
52
src/layouts/Layout.astro
Normal file
@@ -0,0 +1,52 @@
|
||||
---
|
||||
import Header from "../components/Header.astro";
|
||||
import Footer from "../components/Footer.astro";
|
||||
import "../styles/global.css";
|
||||
|
||||
interface Props {
|
||||
title: string;
|
||||
description?: string;
|
||||
ogImage?: string;
|
||||
}
|
||||
|
||||
const {
|
||||
title,
|
||||
description = "Der Förderverein der Integrationskita Regenbogen in Berlin-Tegel. Für das Besondere. Für alle Kinder.",
|
||||
ogImage = "/og-default.jpg",
|
||||
} = Astro.props;
|
||||
|
||||
const canonicalURL = new URL(Astro.url.pathname, "https://kitafreunde-regenbogen.de");
|
||||
---
|
||||
|
||||
<!doctype html>
|
||||
<html lang="de">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
|
||||
<link rel="canonical" href={canonicalURL} />
|
||||
|
||||
<title>{title} | Kitafreunde Regenbogen e.V.</title>
|
||||
<meta name="description" content={description} />
|
||||
|
||||
<!-- Open Graph -->
|
||||
<meta property="og:title" content={`${title} | Kitafreunde Regenbogen e.V.`} />
|
||||
<meta property="og:description" content={description} />
|
||||
<meta property="og:url" content={canonicalURL} />
|
||||
<meta property="og:image" content={ogImage} />
|
||||
<meta property="og:type" content="website" />
|
||||
<meta property="og:locale" content="de_DE" />
|
||||
|
||||
<!-- Google Fonts fallback (bis Apex Brush eingebettet ist) -->
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
||||
<link href="https://fonts.googleapis.com/css2?family=Pacifico&family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet" />
|
||||
</head>
|
||||
<body>
|
||||
<Header />
|
||||
<main>
|
||||
<slot />
|
||||
</main>
|
||||
<Footer />
|
||||
</body>
|
||||
</html>
|
||||
88
src/lib/sanity.ts
Normal file
88
src/lib/sanity.ts
Normal file
@@ -0,0 +1,88 @@
|
||||
import { createClient } from "@sanity/client";
|
||||
|
||||
export const client = createClient({
|
||||
projectId: import.meta.env.PUBLIC_SANITY_PROJECT_ID ?? "placeholder",
|
||||
dataset: import.meta.env.PUBLIC_SANITY_DATASET ?? "production",
|
||||
apiVersion: "2024-01-01",
|
||||
useCdn: true,
|
||||
});
|
||||
|
||||
// Bildurl aus Sanity-Asset
|
||||
export function imageUrl(asset: any, width = 800): string {
|
||||
if (!asset?.asset?._ref) return "";
|
||||
const [, id, dimensions, format] = asset.asset._ref.split("-");
|
||||
return `https://cdn.sanity.io/images/${import.meta.env.PUBLIC_SANITY_PROJECT_ID}/production/${id}-${dimensions}.${format}?w=${width}&auto=format`;
|
||||
}
|
||||
|
||||
// --- Queries ---
|
||||
|
||||
export async function getSettings() {
|
||||
try {
|
||||
return await client.fetch(`*[_type == "siteSettings"][0]{
|
||||
contact, bank, social, memberFees, stats
|
||||
}`);
|
||||
} catch { return null; }
|
||||
}
|
||||
|
||||
export async function getFeaturedProjects() {
|
||||
try {
|
||||
return await client.fetch(`*[_type == "project" && featured == true] | order(_createdAt desc)[0..5]{
|
||||
title, slug, date, summary, status,
|
||||
image{ asset->{ url } }
|
||||
}`);
|
||||
} catch { return []; }
|
||||
}
|
||||
|
||||
export async function getAllProjects() {
|
||||
try {
|
||||
return await client.fetch(`*[_type == "project"] | order(_createdAt desc){
|
||||
title, slug, date, summary, status, targetGroup,
|
||||
image{ asset->{ url } }
|
||||
}`);
|
||||
} catch { return []; }
|
||||
}
|
||||
|
||||
export async function getProject(slug: string) {
|
||||
try {
|
||||
return await client.fetch(`*[_type == "project" && slug.current == $slug][0]{
|
||||
title, slug, date, summary, body, status, targetGroup,
|
||||
image{ asset->{ url } }
|
||||
}`, { slug });
|
||||
} catch { return null; }
|
||||
}
|
||||
|
||||
export async function getLatestPosts(limit = 6) {
|
||||
try {
|
||||
return await client.fetch(`*[_type == "post"] | order(publishedAt desc)[0..${limit - 1}]{
|
||||
title, slug, publishedAt, excerpt, category,
|
||||
coverImage{ asset->{ url } }
|
||||
}`);
|
||||
} catch { return []; }
|
||||
}
|
||||
|
||||
export async function getAllPosts() {
|
||||
try {
|
||||
return await client.fetch(`*[_type == "post"] | order(publishedAt desc){
|
||||
title, slug, publishedAt, excerpt, category,
|
||||
coverImage{ asset->{ url } }
|
||||
}`);
|
||||
} catch { return []; }
|
||||
}
|
||||
|
||||
export async function getPost(slug: string) {
|
||||
try {
|
||||
return await client.fetch(`*[_type == "post" && slug.current == $slug][0]{
|
||||
title, slug, publishedAt, excerpt, body, category,
|
||||
coverImage{ asset->{ url } }
|
||||
}`, { slug });
|
||||
} catch { return null; }
|
||||
}
|
||||
|
||||
export async function getTeam() {
|
||||
try {
|
||||
return await client.fetch(`*[_type == "teamMember"] | order(order asc){
|
||||
name, role, bio,
|
||||
photo{ asset->{ url } }
|
||||
}`);
|
||||
} catch { return []; }
|
||||
}
|
||||
55
src/pages/aktuelles/[slug].astro
Normal file
55
src/pages/aktuelles/[slug].astro
Normal file
@@ -0,0 +1,55 @@
|
||||
---
|
||||
import Layout from "../../layouts/Layout.astro";
|
||||
import { getAllPosts, getPost } from "../../lib/sanity";
|
||||
import { toHTML } from "@portabletext/to-html";
|
||||
|
||||
export async function getStaticPaths() {
|
||||
const posts = await getAllPosts();
|
||||
return posts.map((p: any) => ({ params: { slug: p.slug.current } }));
|
||||
}
|
||||
|
||||
const { slug } = Astro.params;
|
||||
const post = await getPost(slug!);
|
||||
|
||||
if (!post) return Astro.redirect("/aktuelles");
|
||||
|
||||
const bodyHtml = post.body ? toHTML(post.body) : "";
|
||||
const dateFormatted = new Date(post.publishedAt).toLocaleDateString("de-DE", {
|
||||
day: "numeric", month: "long", year: "numeric",
|
||||
});
|
||||
---
|
||||
|
||||
<Layout
|
||||
title={post.title}
|
||||
description={post.excerpt}
|
||||
ogImage={post.coverImage?.asset?.url}
|
||||
>
|
||||
<div class="max-w-6xl mx-auto px-4 pt-6">
|
||||
<a href="/aktuelles" class="text-sm text-[var(--color-text-muted)] hover:text-[var(--color-primary)]">← Alle Beiträge</a>
|
||||
</div>
|
||||
|
||||
{post.coverImage?.asset?.url && (
|
||||
<div class="max-w-6xl mx-auto px-4 mt-6">
|
||||
<div class="aspect-video rounded-3xl overflow-hidden">
|
||||
<img src={`${post.coverImage.asset.url}?w=1200&auto=format`} alt={post.title} class="w-full h-full object-cover" />
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<article class="section max-w-3xl">
|
||||
<time class="text-sm text-[var(--color-text-muted)]" datetime={post.publishedAt}>{dateFormatted}</time>
|
||||
<h1 class="font-brand text-4xl md:text-5xl text-[var(--color-text)] mt-3 mb-6 leading-tight">{post.title}</h1>
|
||||
{post.excerpt && <p class="text-xl text-[var(--color-text-muted)] mb-8 leading-relaxed">{post.excerpt}</p>}
|
||||
{bodyHtml && (
|
||||
<div class="prose prose-lg max-w-none text-[var(--color-text-muted)]" set:html={bodyHtml} />
|
||||
)}
|
||||
</article>
|
||||
|
||||
<div class="max-w-3xl mx-auto px-4 pb-16">
|
||||
<div class="rainbow-bar rounded-full mb-8"></div>
|
||||
<div class="flex flex-col sm:flex-row gap-4">
|
||||
<a href="/mitglied-werden" class="btn-primary">Mitglied werden</a>
|
||||
<a href="/aktuelles" class="btn-secondary">Mehr Beiträge</a>
|
||||
</div>
|
||||
</div>
|
||||
</Layout>
|
||||
57
src/pages/aktuelles/index.astro
Normal file
57
src/pages/aktuelles/index.astro
Normal file
@@ -0,0 +1,57 @@
|
||||
---
|
||||
import Layout from "../../layouts/Layout.astro";
|
||||
import { getAllPosts } from "../../lib/sanity";
|
||||
|
||||
const posts = await getAllPosts();
|
||||
|
||||
const categoryLabel: Record<string, string> = {
|
||||
news: "Vereinsnews",
|
||||
projects: "Projekte",
|
||||
events: "Veranstaltungen",
|
||||
press: "Presse",
|
||||
};
|
||||
---
|
||||
|
||||
<Layout title="Aktuelles" description="Neuigkeiten vom Kitafreunde Regenbogen e.V. — Projekte, Veranstaltungen, Vereinsleben.">
|
||||
<section class="section pt-16 pb-0">
|
||||
<p class="text-sm font-semibold tracking-widest uppercase text-[var(--color-primary)] mb-3">Aktuelles</p>
|
||||
<h1 class="font-brand text-5xl text-[var(--color-text)] mb-4">Was gerade<br><span class="rainbow-text">bei uns passiert.</span></h1>
|
||||
</section>
|
||||
<div class="rainbow-bar max-w-6xl mx-auto px-4 my-10"></div>
|
||||
|
||||
<section class="section pt-0">
|
||||
{posts.length === 0 ? (
|
||||
<div class="card text-center py-16 bg-[var(--color-surface-alt)]">
|
||||
<p class="text-4xl mb-4">✍️</p>
|
||||
<h2 class="text-xl font-bold mb-2">Bald mehr hier</h2>
|
||||
<p class="text-[var(--color-text-muted)]">Wir befüllen den Blog gerade. Schau bald wieder rein!</p>
|
||||
</div>
|
||||
) : (
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
|
||||
{posts.map((post: any) => (
|
||||
<a href={`/aktuelles/${post.slug.current}`} class="card group">
|
||||
{post.coverImage?.asset?.url ? (
|
||||
<div class="aspect-video rounded-xl overflow-hidden mb-4 bg-[var(--color-surface-alt)]">
|
||||
<img src={`${post.coverImage.asset.url}?w=600&auto=format`} alt={post.title} class="w-full h-full object-cover group-hover:scale-105 transition-transform duration-300" />
|
||||
</div>
|
||||
) : (
|
||||
<div class="aspect-video rounded-xl mb-4 bg-[var(--color-surface-alt)] flex items-center justify-center text-4xl">📰</div>
|
||||
)}
|
||||
<div class="flex items-center gap-2 mb-2">
|
||||
{post.category && (
|
||||
<span class="text-xs font-semibold text-[var(--color-primary)] bg-[var(--color-surface-alt)] px-2 py-0.5 rounded-full">
|
||||
{categoryLabel[post.category] ?? post.category}
|
||||
</span>
|
||||
)}
|
||||
<time class="text-xs text-[var(--color-text-muted)]" datetime={post.publishedAt}>
|
||||
{new Date(post.publishedAt).toLocaleDateString("de-DE", { day: "numeric", month: "long", year: "numeric" })}
|
||||
</time>
|
||||
</div>
|
||||
<h3 class="font-bold leading-snug group-hover:text-[var(--color-primary)] transition-colors">{post.title}</h3>
|
||||
{post.excerpt && <p class="text-sm text-[var(--color-text-muted)] mt-2 line-clamp-3">{post.excerpt}</p>}
|
||||
</a>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
</section>
|
||||
</Layout>
|
||||
172
src/pages/index.astro
Normal file
172
src/pages/index.astro
Normal file
@@ -0,0 +1,172 @@
|
||||
---
|
||||
import Layout from "../layouts/Layout.astro";
|
||||
import { getSettings, getFeaturedProjects, getLatestPosts } from "../lib/sanity";
|
||||
|
||||
const settings = await getSettings();
|
||||
const featuredProjects = await getFeaturedProjects();
|
||||
const latestPosts = await getLatestPosts(3);
|
||||
|
||||
const stats = settings?.stats;
|
||||
---
|
||||
|
||||
<Layout
|
||||
title="Mehr als Kita. Mehr als genug."
|
||||
description="Der Kitafreunde Regenbogen e.V. ist der Förderverein der Integrationskita Regenbogen in Berlin-Tegel. Für das Besondere. Für alle Kinder."
|
||||
>
|
||||
<!-- Hero -->
|
||||
<section class="relative overflow-hidden bg-gradient-to-br from-[var(--color-surface-alt)] to-white">
|
||||
<div class="section py-24 md:py-32 text-center">
|
||||
<p class="text-sm font-semibold tracking-widest uppercase text-[var(--color-primary)] mb-4">
|
||||
Berlin-Tegel · Integrationskita Regenbogen
|
||||
</p>
|
||||
<h1 class="font-brand text-5xl md:text-7xl text-[var(--color-text)] mb-6 leading-tight">
|
||||
Mehr als Kita.<br>
|
||||
<span class="rainbow-text">Mehr als genug.</span>
|
||||
</h1>
|
||||
<p class="text-xl text-[var(--color-text-muted)] max-w-2xl mx-auto mb-10 leading-relaxed">
|
||||
Wir schaffen die Momente, die Kinder ihr Leben lang mit sich tragen —
|
||||
Kulturprojekte, Naturerfahrungen, Gemeinschaft. Und dafür, dass kein Kind
|
||||
außen vor bleibt.
|
||||
</p>
|
||||
<div class="flex flex-col sm:flex-row gap-4 justify-center">
|
||||
<a href="/mitglied-werden" class="btn-primary text-base">Jetzt Mitglied werden</a>
|
||||
<a href="/was-wir-tun" class="btn-secondary text-base">Was wir tun</a>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Decorative rainbow -->
|
||||
<div class="rainbow-bar absolute bottom-0 left-0 right-0"></div>
|
||||
</section>
|
||||
|
||||
<!-- Drei-Sätze -->
|
||||
<section class="section-sm text-center">
|
||||
<p class="text-2xl md:text-3xl font-semibold text-[var(--color-text)] max-w-3xl mx-auto leading-snug">
|
||||
Die Kita stellt die Grundversorgung sicher. Das Land zahlt das Nötige.
|
||||
<span class="text-[var(--color-primary)]">Wir bezahlen das Besondere.</span>
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<!-- Drei Säulen -->
|
||||
<section class="section">
|
||||
<div class="grid grid-cols-1 md:grid-cols-3 gap-6">
|
||||
{[
|
||||
{
|
||||
icon: "🎭",
|
||||
color: "var(--color-rb-violet)",
|
||||
title: "Erleben",
|
||||
text: "Theater, Musik, Natur, Kunst. Erlebnisse, die keine Lehrplan-Vorgabe anordnet — und die man nicht vergisst.",
|
||||
href: "/was-wir-tun#erleben",
|
||||
},
|
||||
{
|
||||
icon: "🤝",
|
||||
color: "var(--color-rb-green)",
|
||||
title: "Teilhabe",
|
||||
text: "Kein Kind bleibt beim Ausflug zuhause, weil die Familie sich den Beitrag nicht leisten kann. Punkt.",
|
||||
href: "/was-wir-tun#teilhabe",
|
||||
},
|
||||
{
|
||||
icon: "🌍",
|
||||
color: "var(--color-rb-orange)",
|
||||
title: "Gemeinschaft",
|
||||
text: "Eltern, Erzieher*innen, Nachbarschaft, lokale Unternehmen. Der Verein verbindet, wer die Kita trägt.",
|
||||
href: "/was-wir-tun#gemeinschaft",
|
||||
},
|
||||
].map(({ icon, color, title, text, href }) => (
|
||||
<a href={href} class="card group cursor-pointer">
|
||||
<div class="text-4xl mb-4">{icon}</div>
|
||||
<h3 class="text-xl font-bold mb-2 group-hover:text-[var(--color-primary)] transition-colors"
|
||||
style={`color: ${color}`}>{title}</h3>
|
||||
<p class="text-[var(--color-text-muted)] leading-relaxed text-sm">{text}</p>
|
||||
<p class="mt-4 text-sm font-semibold text-[var(--color-primary)]">Mehr erfahren →</p>
|
||||
</a>
|
||||
))}
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Zahlen -->
|
||||
{stats && (stats.members || stats.fundsPerYear || stats.projectsTotal) && (
|
||||
<section class="bg-[var(--color-primary)] text-white">
|
||||
<div class="max-w-6xl mx-auto px-4 py-16 grid grid-cols-1 md:grid-cols-3 gap-8 text-center">
|
||||
{stats.members && (
|
||||
<div>
|
||||
<p class="font-brand text-5xl mb-2">{stats.members}</p>
|
||||
<p class="text-white/80">Mitglieder unterstützen den Verein</p>
|
||||
</div>
|
||||
)}
|
||||
{stats.fundsPerYear && (
|
||||
<div>
|
||||
<p class="font-brand text-5xl mb-2">{stats.fundsPerYear.toLocaleString("de")} €</p>
|
||||
<p class="text-white/80">jährlich für die Kinder</p>
|
||||
</div>
|
||||
)}
|
||||
{stats.projectsTotal && (
|
||||
<div>
|
||||
<p class="font-brand text-5xl mb-2">{stats.projectsTotal}</p>
|
||||
<p class="text-white/80">Projekte seit Vereinsgründung</p>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</section>
|
||||
)}
|
||||
|
||||
<!-- Aktuelle Projekte -->
|
||||
{featuredProjects.length > 0 && (
|
||||
<section class="section">
|
||||
<h2 class="text-3xl font-bold mb-2">Aktuelle Projekte</h2>
|
||||
<p class="text-[var(--color-text-muted)] mb-8">Was wir gerade machen und was geplant ist.</p>
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
|
||||
{featuredProjects.map((p: any) => (
|
||||
<a href={`/projekte/${p.slug.current}`} class="card group">
|
||||
{p.image?.asset && (
|
||||
<div class="aspect-video bg-[var(--color-surface-alt)] rounded-xl mb-4 overflow-hidden">
|
||||
<img src={p.image.asset.url} alt={p.title} class="w-full h-full object-cover group-hover:scale-105 transition-transform duration-300" />
|
||||
</div>
|
||||
)}
|
||||
<p class="text-xs text-[var(--color-text-muted)] mb-1">{p.date}</p>
|
||||
<h3 class="font-bold text-lg group-hover:text-[var(--color-primary)] transition-colors">{p.title}</h3>
|
||||
<p class="text-sm text-[var(--color-text-muted)] mt-2 line-clamp-2">{p.summary}</p>
|
||||
</a>
|
||||
))}
|
||||
</div>
|
||||
<div class="mt-8 text-center">
|
||||
<a href="/projekte" class="btn-secondary">Alle Projekte →</a>
|
||||
</div>
|
||||
</section>
|
||||
)}
|
||||
|
||||
<!-- Aktuelles -->
|
||||
{latestPosts.length > 0 && (
|
||||
<section class="section bg-[var(--color-surface-alt)] rounded-3xl">
|
||||
<h2 class="text-3xl font-bold mb-8">Aktuelles</h2>
|
||||
<div class="grid grid-cols-1 md:grid-cols-3 gap-6">
|
||||
{latestPosts.map((post: any) => (
|
||||
<a href={`/aktuelles/${post.slug.current}`} class="card group">
|
||||
<p class="text-xs text-[var(--color-text-muted)] mb-2">
|
||||
{new Date(post.publishedAt).toLocaleDateString("de-DE", { day: "numeric", month: "long", year: "numeric" })}
|
||||
</p>
|
||||
<h3 class="font-bold leading-snug group-hover:text-[var(--color-primary)] transition-colors">{post.title}</h3>
|
||||
{post.excerpt && <p class="text-sm text-[var(--color-text-muted)] mt-2 line-clamp-3">{post.excerpt}</p>}
|
||||
</a>
|
||||
))}
|
||||
</div>
|
||||
<div class="mt-8">
|
||||
<a href="/aktuelles" class="btn-secondary">Alle Beiträge →</a>
|
||||
</div>
|
||||
</section>
|
||||
)}
|
||||
|
||||
<!-- CTA -->
|
||||
<section class="section text-center">
|
||||
<div class="max-w-2xl mx-auto">
|
||||
<div class="rainbow-bar w-24 mx-auto mb-8 rounded-full" style="height: 4px;"></div>
|
||||
<h2 class="font-brand text-4xl md:text-5xl text-[var(--color-text)] mb-4">Ab 1 € im Monat.</h2>
|
||||
<p class="text-lg text-[var(--color-text-muted)] mb-8">
|
||||
Kein Aufwand. Kein Ehrenamt verpflichtend.<br>
|
||||
Nur Kinder, die mehr bekommen.
|
||||
</p>
|
||||
<a href="/mitglied-werden" class="btn-primary text-lg px-8 py-4">Jetzt Mitglied werden</a>
|
||||
<p class="text-sm text-[var(--color-text-muted)] mt-4">
|
||||
Gemeinnützig anerkannt · Beiträge steuerlich absetzbar
|
||||
</p>
|
||||
</div>
|
||||
</section>
|
||||
</Layout>
|
||||
91
src/pages/kontakt.astro
Normal file
91
src/pages/kontakt.astro
Normal file
@@ -0,0 +1,91 @@
|
||||
---
|
||||
import Layout from "../layouts/Layout.astro";
|
||||
import { getSettings } from "../lib/sanity";
|
||||
|
||||
const settings = await getSettings();
|
||||
const contact = settings?.contact;
|
||||
const social = settings?.social;
|
||||
---
|
||||
|
||||
<Layout title="Kontakt" description="Kontakt zum Kitafreunde Regenbogen e.V. — schreib uns, werde Mitglied oder bring eine Idee ein.">
|
||||
<section class="section pt-16">
|
||||
<p class="text-sm font-semibold tracking-widest uppercase text-[var(--color-primary)] mb-3">Kontakt</p>
|
||||
<h1 class="font-brand text-5xl text-[var(--color-text)] mb-6">Schreib uns.</h1>
|
||||
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-12 mt-8">
|
||||
<!-- Kontaktinfos -->
|
||||
<div class="space-y-6">
|
||||
<div class="card">
|
||||
<h2 class="font-bold mb-3">Kitafreunde Regenbogen e.V.</h2>
|
||||
<p class="text-sm text-[var(--color-text-muted)] leading-relaxed">
|
||||
c/o Integrationskita Regenbogen<br>
|
||||
Keilerstraße 23<br>
|
||||
13503 Berlin
|
||||
</p>
|
||||
</div>
|
||||
{contact?.email && (
|
||||
<div class="card">
|
||||
<h3 class="font-bold mb-2 text-sm uppercase tracking-wide text-[var(--color-text-muted)]">E-Mail</h3>
|
||||
<a href={`mailto:${contact.email}`} class="text-[var(--color-primary)] font-medium text-lg">
|
||||
{contact.email}
|
||||
</a>
|
||||
</div>
|
||||
)}
|
||||
<div class="card">
|
||||
<h3 class="font-bold mb-3">Mitglied werden?</h3>
|
||||
<p class="text-sm text-[var(--color-text-muted)] mb-3">
|
||||
Beitrittserklärung herunterladen und ausgefüllt im Kitabüro abgeben oder per Mail schicken.
|
||||
</p>
|
||||
<a href="/mitglied-werden" class="btn-primary text-sm">Zur Mitgliedschaftsseite →</a>
|
||||
</div>
|
||||
{(social?.instagram || social?.facebook) && (
|
||||
<div class="card">
|
||||
<h3 class="font-bold mb-3">Social Media</h3>
|
||||
<div class="flex gap-3">
|
||||
{social.instagram && (
|
||||
<a href={social.instagram} target="_blank" rel="noopener" class="btn-secondary text-sm">Instagram</a>
|
||||
)}
|
||||
{social.facebook && (
|
||||
<a href={social.facebook} target="_blank" rel="noopener" class="btn-secondary text-sm">Facebook</a>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<!-- Formular (statisches HTML, ohne Backend) -->
|
||||
<div class="card">
|
||||
<h2 class="font-bold mb-4">Direkte Nachricht</h2>
|
||||
<p class="text-sm text-[var(--color-text-muted)] mb-6">
|
||||
Dieses Formular öffnet deinen E-Mail-Client.
|
||||
</p>
|
||||
<form
|
||||
action={`mailto:${contact?.email ?? "info@kitafreunde-regenbogen.de"}`}
|
||||
method="get"
|
||||
enctype="text/plain"
|
||||
class="space-y-4"
|
||||
>
|
||||
<div>
|
||||
<label for="subject" class="block text-sm font-medium mb-1">Betreff</label>
|
||||
<select id="subject" name="subject" class="w-full border border-[var(--color-border)] rounded-xl px-4 py-2.5 text-sm focus:outline-none focus:border-[var(--color-primary)]">
|
||||
<option value="Mitgliedschaft">Mitgliedschaft</option>
|
||||
<option value="Projektidee">Projektidee einbringen</option>
|
||||
<option value="Spende/Kooperation">Spende / Kooperation</option>
|
||||
<option value="Presseanfrage">Presseanfrage</option>
|
||||
<option value="Allgemeine Anfrage">Allgemeine Anfrage</option>
|
||||
</select>
|
||||
</div>
|
||||
<div>
|
||||
<label for="body" class="block text-sm font-medium mb-1">Nachricht</label>
|
||||
<textarea id="body" name="body" rows="5"
|
||||
class="w-full border border-[var(--color-border)] rounded-xl px-4 py-2.5 text-sm focus:outline-none focus:border-[var(--color-primary)] resize-none"
|
||||
placeholder="Deine Nachricht..."></textarea>
|
||||
</div>
|
||||
<button type="submit" class="btn-primary w-full justify-center">
|
||||
E-Mail öffnen →
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</Layout>
|
||||
122
src/pages/mitglied-werden.astro
Normal file
122
src/pages/mitglied-werden.astro
Normal file
@@ -0,0 +1,122 @@
|
||||
---
|
||||
import Layout from "../layouts/Layout.astro";
|
||||
import { getSettings } from "../lib/sanity";
|
||||
|
||||
const settings = await getSettings();
|
||||
const fees = settings?.memberFees;
|
||||
const bank = settings?.bank;
|
||||
---
|
||||
|
||||
<Layout
|
||||
title="Mitglied werden"
|
||||
description="Mitglied beim Kitafreunde Regenbogen e.V. werden. Steuerlich absetzbar. Keine Verpflichtungen. Direkte Wirkung für Kinder in Berlin-Tegel."
|
||||
>
|
||||
<section class="section pt-16 pb-0">
|
||||
<p class="text-sm font-semibold tracking-widest uppercase text-[var(--color-primary)] mb-3">Mitglied werden</p>
|
||||
<h1 class="font-brand text-5xl md:text-6xl text-[var(--color-text)] mb-6 leading-tight">
|
||||
Dabei sein.<br><span class="rainbow-text">So einfach wie möglich.</span>
|
||||
</h1>
|
||||
</section>
|
||||
<div class="rainbow-bar max-w-6xl mx-auto px-4 mb-12"></div>
|
||||
|
||||
<!-- Warum -->
|
||||
<section class="section pt-0">
|
||||
<div class="max-w-2xl">
|
||||
<p class="text-2xl text-[var(--color-text)] leading-relaxed mb-2">Du musst keine Zeit haben.</p>
|
||||
<p class="text-2xl text-[var(--color-text)] leading-relaxed mb-2">Du musst nicht auf Sitzungen kommen.</p>
|
||||
<p class="text-2xl text-[var(--color-text)] leading-relaxed mb-8">Du musst nicht tischlern, backen oder organisieren können.</p>
|
||||
<p class="text-2xl font-bold text-[var(--color-primary)] leading-relaxed">
|
||||
Du musst nur wollen, dass die Kita in deiner Nachbarschaft ein bisschen mehr kann als ohne dich.
|
||||
</p>
|
||||
<p class="text-3xl font-brand text-[var(--color-text)] mt-6">Das ist alles.</p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Mitgliedschaftstypen -->
|
||||
<section class="section">
|
||||
<h2 class="text-3xl font-bold mb-8">Drei Wege mitzumachen</h2>
|
||||
<div class="grid grid-cols-1 md:grid-cols-3 gap-6">
|
||||
<div class="card border-2 border-[var(--color-primary)]">
|
||||
<p class="text-sm font-semibold text-[var(--color-primary)] uppercase tracking-wide mb-2">Aktives Mitglied</p>
|
||||
<p class="font-brand text-4xl text-[var(--color-text)] mb-1">
|
||||
ab {fees?.active ?? 12} €<span class="text-lg font-normal">/Jahr</span>
|
||||
</p>
|
||||
<p class="text-sm text-[var(--color-text-muted)] mb-4">zzgl. einmalig {fees?.admissionFee ?? 5} € Aufnahmegebühr</p>
|
||||
<ul class="text-sm text-[var(--color-text-muted)] space-y-2 mb-6">
|
||||
<li class="flex gap-2"><span class="text-[var(--color-rb-green)] font-bold">✓</span> Stimmrecht auf der Mitgliederversammlung</li>
|
||||
<li class="flex gap-2"><span class="text-[var(--color-rb-green)] font-bold">✓</span> Mitgestaltung von Projekten und Zielen</li>
|
||||
<li class="flex gap-2"><span class="text-[var(--color-rb-green)] font-bold">✓</span> Voller Überblick über Vereinsgeschehen</li>
|
||||
</ul>
|
||||
<p class="text-xs text-[var(--color-text-muted)]">Für alle, die mitentscheiden wollen.</p>
|
||||
</div>
|
||||
|
||||
<div class="card">
|
||||
<p class="text-sm font-semibold text-[var(--color-accent)] uppercase tracking-wide mb-2">Fördermitglied</p>
|
||||
<p class="font-brand text-4xl text-[var(--color-text)] mb-1">
|
||||
ab {fees?.supporting ?? 6} €<span class="text-lg font-normal">/Jahr</span>
|
||||
</p>
|
||||
<p class="text-sm text-[var(--color-text-muted)] mb-4">keine Aufnahmegebühr</p>
|
||||
<ul class="text-sm text-[var(--color-text-muted)] space-y-2 mb-6">
|
||||
<li class="flex gap-2"><span class="text-[var(--color-rb-green)] font-bold">✓</span> Beitrag geht direkt an die Projekte</li>
|
||||
<li class="flex gap-2"><span class="text-[var(--color-rb-green)] font-bold">✓</span> Kein Aufwand, keine Verpflichtung</li>
|
||||
<li class="flex gap-2"><span class="text-[var(--color-rb-green)] font-bold">✓</span> Volle Wirkung, null Bürokratie</li>
|
||||
</ul>
|
||||
<p class="text-xs text-[var(--color-text-muted)]">Für alle, die einfach dabei sein wollen.</p>
|
||||
</div>
|
||||
|
||||
<div class="card bg-[var(--color-surface-alt)]">
|
||||
<p class="text-sm font-semibold text-[var(--color-rb-blue)] uppercase tracking-wide mb-2">Unternehmen</p>
|
||||
<p class="font-brand text-4xl text-[var(--color-text)] mb-4">Auf Anfrage</p>
|
||||
<ul class="text-sm text-[var(--color-text-muted)] space-y-2 mb-6">
|
||||
<li class="flex gap-2"><span class="text-[var(--color-rb-green)] font-bold">✓</span> Sichtbare lokale Verantwortung</li>
|
||||
<li class="flex gap-2"><span class="text-[var(--color-rb-green)] font-bold">✓</span> Projektpatenschaften möglich</li>
|
||||
<li class="flex gap-2"><span class="text-[var(--color-rb-green)] font-bold">✓</span> Erwähnung in Kommunikation</li>
|
||||
</ul>
|
||||
<a href="/kontakt" class="btn-secondary text-sm w-full justify-center">Gespräch anfragen →</a>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- So geht's -->
|
||||
<section class="section bg-[var(--color-surface-alt)] rounded-3xl">
|
||||
<h2 class="text-3xl font-bold mb-8">So wirst du Mitglied</h2>
|
||||
<div class="grid grid-cols-1 md:grid-cols-3 gap-8">
|
||||
{[
|
||||
{ step: "1", title: "Beitrittserklärung ausfüllen", text: "Als PDF ausdrucken und unterschreiben — oder im Kitabüro abholen." },
|
||||
{ step: "2", title: "Beitrag überweisen", text: `Jahresbeitrag + einmalige Aufnahmegebühr (${fees?.admissionFee ?? 5} €) auf unser Vereinskonto.` },
|
||||
{ step: "3", title: "Fertig — du bist dabei.", text: "Willkommen bei den Kitafreunden. Wir freuen uns." },
|
||||
].map(({ step, title, text }) => (
|
||||
<div class="text-center">
|
||||
<div class="w-14 h-14 rounded-full bg-[var(--color-primary)] text-white font-brand text-2xl flex items-center justify-center mx-auto mb-4">{step}</div>
|
||||
<h3 class="font-bold mb-2">{title}</h3>
|
||||
<p class="text-sm text-[var(--color-text-muted)]">{text}</p>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
<div class="mt-10 text-center">
|
||||
<a href="/Beitrittserklarung-Kitafreunde-Regenbogen.pdf" class="btn-primary" download>
|
||||
Beitrittserklärung als PDF
|
||||
</a>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Bank -->
|
||||
{bank?.iban && (
|
||||
<section class="section">
|
||||
<div class="card max-w-xl">
|
||||
<h3 class="font-bold mb-4">Bankverbindung</h3>
|
||||
<dl class="text-sm space-y-2 text-[var(--color-text-muted)]">
|
||||
<div class="flex gap-2"><dt class="font-medium text-[var(--color-text)] w-32">Empfänger</dt><dd>{bank.accountHolder}</dd></div>
|
||||
<div class="flex gap-2"><dt class="font-medium text-[var(--color-text)] w-32">IBAN</dt><dd class="font-mono">{bank.iban}</dd></div>
|
||||
{bank.bic && <div class="flex gap-2"><dt class="font-medium text-[var(--color-text)] w-32">BIC</dt><dd class="font-mono">{bank.bic}</dd></div>}
|
||||
{bank.bank && <div class="flex gap-2"><dt class="font-medium text-[var(--color-text)] w-32">Bank</dt><dd>{bank.bank}</dd></div>}
|
||||
<div class="flex gap-2"><dt class="font-medium text-[var(--color-text)] w-32">Verwendung</dt><dd>Mitgliedsbeitrag [Dein Name]</dd></div>
|
||||
</dl>
|
||||
</div>
|
||||
<p class="text-sm text-[var(--color-text-muted)] mt-4">
|
||||
Mitgliedsbeiträge und Spenden sind steuerlich absetzbar (gemeinnützig anerkannt).
|
||||
Spendenquittung auf Anfrage.
|
||||
</p>
|
||||
</section>
|
||||
)}
|
||||
</Layout>
|
||||
66
src/pages/presse.astro
Normal file
66
src/pages/presse.astro
Normal file
@@ -0,0 +1,66 @@
|
||||
---
|
||||
import Layout from "../layouts/Layout.astro";
|
||||
import { getSettings } from "../lib/sanity";
|
||||
|
||||
const settings = await getSettings();
|
||||
const contact = settings?.contact;
|
||||
---
|
||||
|
||||
<Layout title="Presse" description="Pressekontakt und Informationen zum Kitafreunde Regenbogen e.V., Förderverein der Integrationskita Regenbogen in Berlin-Tegel.">
|
||||
<section class="section pt-16">
|
||||
<p class="text-sm font-semibold tracking-widest uppercase text-[var(--color-primary)] mb-3">Presse</p>
|
||||
<h1 class="font-brand text-5xl text-[var(--color-text)] mb-6">Kontakt für Presse<br>und Medien.</h1>
|
||||
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-12 mt-12">
|
||||
<div>
|
||||
<h2 class="text-xl font-bold mb-4">Pressekontakt</h2>
|
||||
{contact?.email ? (
|
||||
<div class="card">
|
||||
<p class="font-semibold mb-1">Kitafreunde Regenbogen e.V.</p>
|
||||
<p class="text-sm text-[var(--color-text-muted)] mb-3">Keilerstraße 23 · 13503 Berlin</p>
|
||||
<a href={`mailto:${contact.email}?subject=Presseanfrage`} class="text-[var(--color-primary)] font-medium">
|
||||
{contact.email}
|
||||
</a>
|
||||
</div>
|
||||
) : (
|
||||
<div class="card">
|
||||
<p class="text-sm text-[var(--color-text-muted)] italic">Pressekontakt folgt</p>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div class="mt-8">
|
||||
<h3 class="font-bold mb-3">Pressekit (Download)</h3>
|
||||
<ul class="text-sm text-[var(--color-text-muted)] space-y-2">
|
||||
<li>🖼️ Logo in PNG und SVG (alle Varianten)</li>
|
||||
<li>📄 Kurzbeschreibung (150 Wörter)</li>
|
||||
<li>📄 Langprofil</li>
|
||||
<li>📷 Projektfotos (DSGVO-konform)</li>
|
||||
</ul>
|
||||
<a href="/presse-kit.zip" class="btn-secondary text-sm mt-4 inline-flex">Pressekit anfragen</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Boilerplate -->
|
||||
<div>
|
||||
<h2 class="text-xl font-bold mb-4">Über den Verein</h2>
|
||||
<div class="card bg-[var(--color-surface-alt)] prose prose-sm max-w-none text-[var(--color-text-muted)]">
|
||||
<p>
|
||||
Der Kitafreunde Regenbogen e.V. ist der gemeinnützige Förderverein der
|
||||
Integrationskindertagesstätte „Regenbogen" in Berlin-Tegel (Keilerstraße 23,
|
||||
13503 Berlin). Der Verein ermöglicht Projekte, Erlebnisse und Teilhabe, die über
|
||||
die staatlich finanzierte Grundversorgung hinausgehen.
|
||||
</p>
|
||||
<p>
|
||||
Schwerpunkte sind kulturelle Bildung, Naturerfahrung und die finanzielle Unterstützung
|
||||
von Kindern aus einkommensschwachen Familien. Als Förderverein einer Integrationskita
|
||||
setzt sich der Kitafreunde Regenbogen e.V. dafür ein, dass ein Ort, an dem Kinder mit
|
||||
und ohne Behinderung gemeinsam aufwachsen, mehr kann als das Minimum.
|
||||
</p>
|
||||
<p class="text-xs">
|
||||
Vereinssitz: Berlin · Gemeinnützig anerkannt
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</Layout>
|
||||
58
src/pages/projekte/[slug].astro
Normal file
58
src/pages/projekte/[slug].astro
Normal file
@@ -0,0 +1,58 @@
|
||||
---
|
||||
import Layout from "../../layouts/Layout.astro";
|
||||
import { getAllProjects, getProject } from "../../lib/sanity";
|
||||
import { toHTML } from "@portabletext/to-html";
|
||||
|
||||
export async function getStaticPaths() {
|
||||
const projects = await getAllProjects();
|
||||
return projects.map((p: any) => ({ params: { slug: p.slug.current } }));
|
||||
}
|
||||
|
||||
const { slug } = Astro.params;
|
||||
const project = await getProject(slug!);
|
||||
|
||||
if (!project) return Astro.redirect("/projekte");
|
||||
|
||||
const bodyHtml = project.body ? toHTML(project.body) : "";
|
||||
---
|
||||
|
||||
<Layout
|
||||
title={project.title}
|
||||
description={project.summary}
|
||||
ogImage={project.image?.asset?.url}
|
||||
>
|
||||
<!-- Breadcrumb -->
|
||||
<div class="max-w-6xl mx-auto px-4 pt-6">
|
||||
<a href="/projekte" class="text-sm text-[var(--color-text-muted)] hover:text-[var(--color-primary)]">← Alle Projekte</a>
|
||||
</div>
|
||||
|
||||
{project.image?.asset?.url && (
|
||||
<div class="max-w-6xl mx-auto px-4 mt-6">
|
||||
<div class="aspect-video rounded-3xl overflow-hidden">
|
||||
<img src={`${project.image.asset.url}?w=1200&auto=format`} alt={project.title} class="w-full h-full object-cover" />
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<section class="section">
|
||||
<div class="max-w-3xl">
|
||||
<div class="flex items-center gap-3 mb-4 text-sm text-[var(--color-text-muted)]">
|
||||
{project.date && <span>📅 {project.date}</span>}
|
||||
{project.targetGroup && <span>👥 {project.targetGroup}</span>}
|
||||
</div>
|
||||
<h1 class="font-brand text-4xl md:text-5xl text-[var(--color-text)] mb-6">{project.title}</h1>
|
||||
<p class="text-xl text-[var(--color-text-muted)] leading-relaxed mb-8">{project.summary}</p>
|
||||
{bodyHtml && (
|
||||
<div class="prose prose-lg max-w-none text-[var(--color-text-muted)]" set:html={bodyHtml} />
|
||||
)}
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="section text-center border-t border-[var(--color-border)] pt-12">
|
||||
<p class="text-[var(--color-text-muted)] mb-4">Solche Projekte werden durch Mitgliedsbeiträge und Spenden möglich.</p>
|
||||
<div class="flex flex-col sm:flex-row gap-4 justify-center">
|
||||
<a href="/mitglied-werden" class="btn-primary">Mitglied werden</a>
|
||||
<a href="/unterstuetzen" class="btn-secondary">Spenden</a>
|
||||
</div>
|
||||
</section>
|
||||
</Layout>
|
||||
79
src/pages/projekte/index.astro
Normal file
79
src/pages/projekte/index.astro
Normal file
@@ -0,0 +1,79 @@
|
||||
---
|
||||
import Layout from "../../layouts/Layout.astro";
|
||||
import { getAllProjects } from "../../lib/sanity";
|
||||
|
||||
const projects = await getAllProjects();
|
||||
|
||||
const statusLabel: Record<string, string> = {
|
||||
planned: "Geplant",
|
||||
active: "Laufend",
|
||||
done: "Abgeschlossen",
|
||||
};
|
||||
const statusColor: Record<string, string> = {
|
||||
planned: "var(--color-rb-blue)",
|
||||
active: "var(--color-rb-green)",
|
||||
done: "var(--color-text-muted)",
|
||||
};
|
||||
---
|
||||
|
||||
<Layout
|
||||
title="Projekte"
|
||||
description="Aktuelle und vergangene Projekte des Kitafreunde Regenbogen e.V.: Theater, Natur, Musik, Ausflüge — für alle Kinder der Integrationskita Regenbogen Berlin."
|
||||
>
|
||||
<section class="section pt-16 pb-0">
|
||||
<p class="text-sm font-semibold tracking-widest uppercase text-[var(--color-primary)] mb-3">Projekte</p>
|
||||
<h1 class="font-brand text-5xl text-[var(--color-text)] mb-4">Was wir schon gemacht haben.<br><span class="rainbow-text">Was als nächstes kommt.</span></h1>
|
||||
<p class="text-xl text-[var(--color-text-muted)] max-w-2xl leading-relaxed">
|
||||
Jedes Projekt erzählt, warum der Verein existiert. Konkret, sichtbar, für alle.
|
||||
</p>
|
||||
</section>
|
||||
<div class="rainbow-bar max-w-6xl mx-auto px-4 my-10"></div>
|
||||
|
||||
{projects.length === 0 ? (
|
||||
<section class="section pt-0">
|
||||
<div class="card text-center py-16 bg-[var(--color-surface-alt)]">
|
||||
<p class="text-4xl mb-4">🚀</p>
|
||||
<h2 class="text-xl font-bold mb-2">Projekte folgen</h2>
|
||||
<p class="text-[var(--color-text-muted)]">Wir befüllen den Bereich gerade. Schau bald wieder vorbei!</p>
|
||||
</div>
|
||||
</section>
|
||||
) : (
|
||||
<section class="section pt-0">
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
|
||||
{projects.map((p: any) => (
|
||||
<a href={`/projekte/${p.slug.current}`} class="card group">
|
||||
{p.image?.asset?.url ? (
|
||||
<div class="aspect-video rounded-xl overflow-hidden mb-4 bg-[var(--color-surface-alt)]">
|
||||
<img src={`${p.image.asset.url}?w=600&auto=format`} alt={p.title} class="w-full h-full object-cover group-hover:scale-105 transition-transform duration-300" />
|
||||
</div>
|
||||
) : (
|
||||
<div class="aspect-video rounded-xl mb-4 bg-[var(--color-surface-alt)] flex items-center justify-center text-4xl">🎭</div>
|
||||
)}
|
||||
<div class="flex items-center gap-2 mb-2">
|
||||
<span class="text-xs font-semibold px-2 py-0.5 rounded-full bg-current/10"
|
||||
style={`color: ${statusColor[p.status ?? "done"]}`}>
|
||||
{statusLabel[p.status ?? "done"]}
|
||||
</span>
|
||||
{p.date && <span class="text-xs text-[var(--color-text-muted)]">{p.date}</span>}
|
||||
</div>
|
||||
<h3 class="font-bold text-lg mb-2 group-hover:text-[var(--color-primary)] transition-colors">{p.title}</h3>
|
||||
<p class="text-sm text-[var(--color-text-muted)] line-clamp-3">{p.summary}</p>
|
||||
{p.targetGroup && (
|
||||
<p class="text-xs text-[var(--color-text-muted)] mt-3">👥 {p.targetGroup}</p>
|
||||
)}
|
||||
</a>
|
||||
))}
|
||||
</div>
|
||||
</section>
|
||||
)}
|
||||
|
||||
<!-- Idee einbringen -->
|
||||
<section class="section text-center">
|
||||
<div class="card max-w-lg mx-auto bg-[var(--color-surface-alt)] border-0 py-10">
|
||||
<p class="text-2xl mb-3">💡</p>
|
||||
<h2 class="font-bold text-xl mb-2">Du hast eine Idee?</h2>
|
||||
<p class="text-[var(--color-text-muted)] text-sm mb-4">Neue Projektvorschläge sind immer willkommen.</p>
|
||||
<a href="/kontakt" class="btn-primary text-sm">Idee einbringen →</a>
|
||||
</div>
|
||||
</section>
|
||||
</Layout>
|
||||
148
src/pages/ueber-uns.astro
Normal file
148
src/pages/ueber-uns.astro
Normal file
@@ -0,0 +1,148 @@
|
||||
---
|
||||
import Layout from "../layouts/Layout.astro";
|
||||
import { getTeam } from "../lib/sanity";
|
||||
|
||||
const team = await getTeam();
|
||||
|
||||
const roleLabel: Record<string, string> = {
|
||||
chair: "Vorsitzende/r",
|
||||
deputy: "Stellvertretung",
|
||||
treasurer: "Kassenwart/in",
|
||||
board: "Beisitz",
|
||||
};
|
||||
---
|
||||
|
||||
<Layout
|
||||
title="Über uns"
|
||||
description="Wer sind die Kitafreunde Regenbogen? Der Förderverein der Integrationskita Regenbogen Berlin — gegründet von Eltern, getragen von einer Gemeinschaft."
|
||||
>
|
||||
<!-- Hero -->
|
||||
<section class="section pt-16 pb-0">
|
||||
<div class="max-w-3xl">
|
||||
<p class="text-sm font-semibold tracking-widest uppercase text-[var(--color-primary)] mb-3">Über uns</p>
|
||||
<h1 class="font-brand text-5xl md:text-6xl text-[var(--color-text)] mb-6 leading-tight">
|
||||
Wir sind die<br><span class="rainbow-text">Kitafreunde.</span>
|
||||
</h1>
|
||||
</div>
|
||||
</section>
|
||||
<div class="rainbow-bar max-w-6xl mx-auto px-4 my-8"></div>
|
||||
|
||||
<!-- Geschichte -->
|
||||
<section class="section pt-0">
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-16 items-start">
|
||||
<div class="prose prose-lg max-w-none text-[var(--color-text-muted)] leading-relaxed space-y-5">
|
||||
<p>
|
||||
Irgendwann haben Eltern angefangen zu fragen: Was bräuchte die Kita, wenn sie dürfte?
|
||||
Was würde den Kindern gut tun, wenn das Budget keine Rolle spielt?
|
||||
</p>
|
||||
<p>
|
||||
Die Antworten waren überraschend konkret. Ein Theaterstück. Eine Woche Garten und Kompost.
|
||||
Trommelkurse. Ein Ausflug zum See für alle — wirklich für alle. Und dafür, dass kein Kind
|
||||
fehlt, weil zuhause gerade kein Geld da ist.
|
||||
</p>
|
||||
<p>
|
||||
Der Kitafreunde Regenbogen e.V. wurde gegründet, weil diese Antworten umsetzbar sind.
|
||||
Nicht durch das Land. Nicht durch den Träger. Durch uns.
|
||||
</p>
|
||||
<p>
|
||||
Die Kita Regenbogen ist eine Integrationskita — Kinder mit und ohne Behinderung lernen,
|
||||
spielen und wachsen gemeinsam. Das ist keine Besonderheit, die man erklärt. Das ist einfach,
|
||||
wie es richtig ist. Und der Förderverein trägt diese Haltung nach außen:
|
||||
Alle sind dabei. Alle zählen. Kein Abstrich, kein Sonderfall.
|
||||
</p>
|
||||
<p>
|
||||
Zwischenzeitlich war der Verein ruhiger geworden. Jetzt erwacht er neu — mit frischen
|
||||
Mitgliedern, klaren Zielen und dem Willen, der Kita Regenbogen den Rücken zu stärken,
|
||||
den sie verdient.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<!-- Leitbild -->
|
||||
<div class="space-y-6">
|
||||
<div class="card bg-[var(--color-surface-alt)]">
|
||||
<h2 class="text-xl font-bold mb-4 text-[var(--color-primary)]">Unser Leitbild</h2>
|
||||
<p class="font-semibold text-[var(--color-text)] mb-3">
|
||||
Wir sind nicht für das Alltägliche zuständig. Das ist Aufgabe des Landes.
|
||||
</p>
|
||||
<p class="text-[var(--color-text-muted)] text-sm leading-relaxed">
|
||||
Wir sind für das, was darüber hinausgeht. Das i-Tüpfelchen. Die Erinnerung.
|
||||
Die Chance, die sonst keine Chance hätte.
|
||||
</p>
|
||||
</div>
|
||||
<div class="space-y-4">
|
||||
{[
|
||||
{ icon: "🌈", text: "Jedes Kind zählt — unabhängig von Herkunft, Behinderung oder dem Kontostand der Eltern" },
|
||||
{ icon: "🎯", text: "Wirkung vor Verwaltung — jeder Euro geht an die Kinder, nicht in den Apparat" },
|
||||
{ icon: "🤝", text: "Gemeinschaft ist kein Ziel, sie ist das Mittel" },
|
||||
].map(({ icon, text }) => (
|
||||
<div class="flex gap-3 items-start">
|
||||
<span class="text-2xl mt-0.5">{icon}</span>
|
||||
<p class="text-[var(--color-text)] leading-relaxed">{text}</p>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Team -->
|
||||
{team.length > 0 && (
|
||||
<section class="section bg-[var(--color-surface-alt)] rounded-3xl">
|
||||
<h2 class="text-3xl font-bold mb-2">Der Vorstand</h2>
|
||||
<p class="text-[var(--color-text-muted)] mb-8">
|
||||
Wir sind Eltern. Wir haben Kinder in der Kita. Wir kennen den Unterschied zwischen dem, was ist, und dem, was sein könnte.
|
||||
</p>
|
||||
<div class="grid grid-cols-2 md:grid-cols-4 gap-6">
|
||||
{team.map((member: any) => (
|
||||
<div class="text-center">
|
||||
<div class="w-20 h-20 mx-auto mb-3 rounded-full bg-[var(--color-primary-light)] flex items-center justify-center text-white text-2xl overflow-hidden">
|
||||
{member.photo?.asset
|
||||
? <img src={member.photo.asset.url} alt={member.name} class="w-full h-full object-cover" />
|
||||
: "👤"}
|
||||
</div>
|
||||
<p class="font-semibold">{member.name}</p>
|
||||
<p class="text-sm text-[var(--color-primary)]">{roleLabel[member.role] ?? member.role}</p>
|
||||
{member.bio && <p class="text-xs text-[var(--color-text-muted)] mt-1">{member.bio}</p>}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</section>
|
||||
)}
|
||||
|
||||
<!-- FAQ -->
|
||||
<section class="section">
|
||||
<h2 class="text-3xl font-bold mb-8">Häufige Fragen</h2>
|
||||
<div class="space-y-4 max-w-3xl">
|
||||
{[
|
||||
{
|
||||
q: "Was ist ein Förderverein eigentlich?",
|
||||
a: "Ein eingetragener, gemeinnütziger Verein, der eine Einrichtung unterstützt — nicht als Ersatz für staatliche Leistungen, sondern als Ergänzung für das, was darüber hinaus geht.",
|
||||
},
|
||||
{
|
||||
q: "Wer kann Mitglied werden?",
|
||||
a: "Alle. Eltern, Großeltern, Nachbar*innen, ehemalige Kitafamilien, Menschen ohne jeden Kita-Bezug. Natürliche und juristische Personen.",
|
||||
},
|
||||
{
|
||||
q: "Muss ich aktiv mitarbeiten?",
|
||||
a: "Nein. Wer möchte, kann — wer nicht möchte oder kann, zahlt einfach den Beitrag. Beides hilft.",
|
||||
},
|
||||
{
|
||||
q: "Wofür wird mein Beitrag verwendet?",
|
||||
a: "Ausschließlich für Vereinszwecke: Projekte, Veranstaltungen, Materialien und die finanzielle Unterstützung von Kindern, die es brauchen. Kein Vorstandsmitglied erhält eine Vergütung.",
|
||||
},
|
||||
].map(({ q, a }) => (
|
||||
<div class="card">
|
||||
<h3 class="font-bold mb-2">{q}</h3>
|
||||
<p class="text-[var(--color-text-muted)] text-sm leading-relaxed">{a}</p>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- CTA -->
|
||||
<section class="section text-center">
|
||||
<a href="/mitglied-werden" class="btn-primary text-lg">Jetzt Mitglied werden</a>
|
||||
<span class="mx-4 text-[var(--color-text-muted)]">oder</span>
|
||||
<a href="/kontakt" class="btn-secondary text-lg">Schreib uns</a>
|
||||
</section>
|
||||
</Layout>
|
||||
103
src/pages/unterstuetzen.astro
Normal file
103
src/pages/unterstuetzen.astro
Normal file
@@ -0,0 +1,103 @@
|
||||
---
|
||||
import Layout from "../layouts/Layout.astro";
|
||||
import { getSettings } from "../lib/sanity";
|
||||
|
||||
const settings = await getSettings();
|
||||
const bank = settings?.bank;
|
||||
const contact = settings?.contact;
|
||||
---
|
||||
|
||||
<Layout
|
||||
title="Unterstützen & Spenden"
|
||||
description="Einmalspende, Projektpatenschaft oder Unternehmenspartnerschaft — jede Unterstützung kommt direkt bei den Kindern der Kita Regenbogen an."
|
||||
>
|
||||
<section class="section pt-16 pb-0">
|
||||
<p class="text-sm font-semibold tracking-widest uppercase text-[var(--color-primary)] mb-3">Unterstützen</p>
|
||||
<h1 class="font-brand text-5xl md:text-6xl text-[var(--color-text)] mb-6 leading-tight">
|
||||
Du musst kein Mitglied sein,<br>
|
||||
<span class="rainbow-text">um zu helfen.</span>
|
||||
</h1>
|
||||
<p class="text-xl text-[var(--color-text-muted)] max-w-2xl leading-relaxed">
|
||||
Einmalspenden, Sachspenden, Projektpatenschaften — jede Form der Unterstützung
|
||||
landet direkt bei den Kindern.
|
||||
</p>
|
||||
</section>
|
||||
<div class="rainbow-bar max-w-6xl mx-auto px-4 my-12"></div>
|
||||
|
||||
<section class="section pt-0">
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
|
||||
|
||||
<!-- Einmalspende -->
|
||||
<div class="card">
|
||||
<div class="text-4xl mb-4">💸</div>
|
||||
<h2 class="text-xl font-bold mb-3">Einmalspende</h2>
|
||||
<p class="text-[var(--color-text-muted)] text-sm leading-relaxed mb-4">
|
||||
Überweise direkt auf unser Vereinskonto. Kein Formular, kein Aufwand.
|
||||
Spendenquittung auf Wunsch.
|
||||
</p>
|
||||
{bank?.iban ? (
|
||||
<div class="bg-[var(--color-surface-alt)] rounded-xl p-4 text-sm space-y-1">
|
||||
<p><span class="font-medium">Empfänger:</span> {bank.accountHolder}</p>
|
||||
<p><span class="font-medium">IBAN:</span> <span class="font-mono">{bank.iban}</span></p>
|
||||
{bank.bic && <p><span class="font-medium">BIC:</span> <span class="font-mono">{bank.bic}</span></p>}
|
||||
<p><span class="font-medium">Verwendung:</span> Spende Kitafreunde Regenbogen</p>
|
||||
</div>
|
||||
) : (
|
||||
<p class="text-sm text-[var(--color-text-muted)] italic">Bankverbindung folgt</p>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<!-- Projektpatenschaft -->
|
||||
<div class="card">
|
||||
<div class="text-4xl mb-4">🎯</div>
|
||||
<h2 class="text-xl font-bold mb-3">Projektpatenschaft</h2>
|
||||
<p class="text-[var(--color-text-muted)] text-sm leading-relaxed mb-4">
|
||||
Du willst, dass ein konkretes Projekt stattfindet? Finanziere es gezielt.
|
||||
Wir dokumentieren die Wirkung und berichten dir zurück — mit echten Fotos
|
||||
und echter Geschichte.
|
||||
</p>
|
||||
<a href="/kontakt" class="btn-primary text-sm">Projekt anfragen →</a>
|
||||
</div>
|
||||
|
||||
<!-- Sachspenden -->
|
||||
<div class="card">
|
||||
<div class="text-4xl mb-4">🎁</div>
|
||||
<h2 class="text-xl font-bold mb-3">Sachspenden</h2>
|
||||
<p class="text-[var(--color-text-muted)] text-sm leading-relaxed mb-4">
|
||||
Spielzeug, Bücher, Materialien, Werkzeug, Pflanzen für den Garten —
|
||||
frag uns, was gerade gebraucht wird. Wir stimmen mit der Kita ab.
|
||||
</p>
|
||||
{contact?.email && (
|
||||
<a href={`mailto:${contact.email}?subject=Sachspende`} class="btn-secondary text-sm">
|
||||
{contact.email}
|
||||
</a>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<!-- Unternehmenspartnerschaft -->
|
||||
<div class="card bg-[var(--color-surface-alt)]">
|
||||
<div class="text-4xl mb-4">🏢</div>
|
||||
<h2 class="text-xl font-bold mb-3">Unternehmenspartnerschaft</h2>
|
||||
<p class="text-[var(--color-text-muted)] text-sm leading-relaxed mb-4">
|
||||
Lokale Verantwortung, sichtbare Wirkung. Als Vereinspartner oder Sponsor
|
||||
unterstützt du konkrete Projekte — und wir machen das sichtbar: auf der Website,
|
||||
bei Veranstaltungen und in unserer Kommunikation.
|
||||
</p>
|
||||
<a href="/kontakt" class="btn-secondary text-sm">Gespräch anfragen →</a>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Transparenz -->
|
||||
<section class="section">
|
||||
<div class="card bg-[var(--color-primary)] text-white border-0 text-center py-12">
|
||||
<h2 class="font-brand text-3xl mb-4">Wo dein Geld landet.</h2>
|
||||
<p class="text-white/80 max-w-xl mx-auto leading-relaxed">
|
||||
Jeder Euro geht an die Kinder — für Projekte, Ausflüge und Teilhabe.
|
||||
Kein Vorstandsmitglied erhält eine Vergütung. Wir veröffentlichen regelmäßig,
|
||||
was wir mit den Mitteln gemacht haben.
|
||||
</p>
|
||||
<p class="text-white/60 text-sm mt-4">Gemeinnützig anerkannt · Spenden steuerlich absetzbar</p>
|
||||
</div>
|
||||
</section>
|
||||
</Layout>
|
||||
148
src/pages/was-wir-tun.astro
Normal file
148
src/pages/was-wir-tun.astro
Normal file
@@ -0,0 +1,148 @@
|
||||
---
|
||||
import Layout from "../layouts/Layout.astro";
|
||||
---
|
||||
|
||||
<Layout
|
||||
title="Was wir tun"
|
||||
description="Nicht das Pflichtprogramm — das Besondere. Kulturelle Bildung, Naturerfahrungen, Chancengleichheit für alle Kinder der Kita Regenbogen."
|
||||
>
|
||||
<section class="section pt-16 pb-0">
|
||||
<p class="text-sm font-semibold tracking-widest uppercase text-[var(--color-primary)] mb-3">Was wir tun</p>
|
||||
<h1 class="font-brand text-5xl md:text-6xl text-[var(--color-text)] mb-4 leading-tight">
|
||||
Nicht das Pflichtprogramm.<br>
|
||||
<span class="rainbow-text">Das Besondere.</span>
|
||||
</h1>
|
||||
<p class="text-xl text-[var(--color-text-muted)] max-w-2xl leading-relaxed mb-8">
|
||||
Der Staat finanziert die Grundversorgung. Der Träger stellt den Rahmen.
|
||||
Der Förderverein füllt den Raum, der danach kommt.
|
||||
</p>
|
||||
</section>
|
||||
<div class="rainbow-bar max-w-6xl mx-auto px-4 mb-16"></div>
|
||||
|
||||
<!-- Erleben -->
|
||||
<section id="erleben" class="section pt-0">
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-12 items-center">
|
||||
<div>
|
||||
<div class="text-5xl mb-4">🎭</div>
|
||||
<h2 class="text-3xl font-bold mb-4" style="color: var(--color-rb-violet)">Erleben</h2>
|
||||
<p class="text-[var(--color-text-muted)] leading-relaxed mb-4">
|
||||
Kinder brauchen mehr als Struktur. Sie brauchen Staunen.
|
||||
</p>
|
||||
<p class="text-[var(--color-text-muted)] leading-relaxed mb-4">
|
||||
Der Verein ermöglicht Projekte, die im normalen Kitaalltag keinen Platz finden:
|
||||
Theaterprojekte, bei denen Kinder selbst auf der Bühne stehen. Musikworkshops ohne
|
||||
Vorkenntnisse. Naturerfahrungen, die zeigen, dass Erde nicht nur Schmutz ist, sondern
|
||||
Leben. Ausflüge in Museen, Theater, Parks und Orte, die Berliner Kinder kennen sollten.
|
||||
</p>
|
||||
<p class="font-semibold text-[var(--color-text)]">
|
||||
Das sind keine Extras für besondere Kinder. Das ist das, was alle Kinder brauchen.
|
||||
</p>
|
||||
</div>
|
||||
<div class="grid grid-cols-2 gap-4">
|
||||
{[
|
||||
{ icon: "🎪", label: "Theaterprojekte & Besuche" },
|
||||
{ icon: "🎵", label: "Musik, Tanz & Kreativworkshops" },
|
||||
{ icon: "🌱", label: "Garten- & Naturprojekte" },
|
||||
{ icon: "🚌", label: "Ausflüge & Tagesreisen" },
|
||||
{ icon: "🤸", label: "Zirkus & Bewegung" },
|
||||
{ icon: "📚", label: "Lesungen & Kunst" },
|
||||
].map(({ icon, label }) => (
|
||||
<div class="card text-center py-4">
|
||||
<div class="text-3xl mb-2">{icon}</div>
|
||||
<p class="text-sm font-medium">{label}</p>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<div class="rainbow-bar max-w-6xl mx-auto px-4 my-12"></div>
|
||||
|
||||
<!-- Teilhabe -->
|
||||
<section id="teilhabe" class="section py-0">
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-12 items-center">
|
||||
<div class="order-2 md:order-1 bg-[var(--color-surface-alt)] rounded-3xl p-8">
|
||||
<blockquote class="text-2xl font-semibold text-[var(--color-text)] leading-snug mb-6">
|
||||
„Kein Kind fragt. Kein Kind wird gefragt."
|
||||
</blockquote>
|
||||
<div class="space-y-4">
|
||||
{[
|
||||
"Übernahme von Beiträgen für Ausflüge und Veranstaltungen",
|
||||
"Unterstützung bei Materialien und Bedarf",
|
||||
"Diskret, unbürokratisch, selbstverständlich",
|
||||
].map((item) => (
|
||||
<div class="flex gap-3 items-start">
|
||||
<span class="text-[var(--color-rb-green)] text-xl font-bold mt-0.5">✓</span>
|
||||
<p class="text-[var(--color-text-muted)]">{item}</p>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
<div class="order-1 md:order-2">
|
||||
<div class="text-5xl mb-4">🤝</div>
|
||||
<h2 class="text-3xl font-bold mb-4" style="color: var(--color-rb-green)">Teilhabe</h2>
|
||||
<p class="text-[var(--color-text-muted)] leading-relaxed mb-4">
|
||||
Manche Familien können sich den Ausflugsbeitrag nicht leisten. Manche können das
|
||||
Kostüm fürs Theaterstück nicht kaufen. Manche möchten nicht, dass ihr Kind angefragt
|
||||
wird, ob das Budget reicht.
|
||||
</p>
|
||||
<p class="text-[var(--color-text-muted)] leading-relaxed mb-4">
|
||||
Der Förderverein schließt diese Lücken — diskret, unbürokratisch und ohne dass ein
|
||||
Kind erklären muss, warum.
|
||||
</p>
|
||||
<p class="font-semibold text-[var(--color-text)]">
|
||||
Das ist kein Sozialprogramm. Das ist Selbstverständlichkeit.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<div class="rainbow-bar max-w-6xl mx-auto px-4 my-12"></div>
|
||||
|
||||
<!-- Gemeinschaft -->
|
||||
<section id="gemeinschaft" class="section py-0">
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-12 items-center">
|
||||
<div>
|
||||
<div class="text-5xl mb-4">🌍</div>
|
||||
<h2 class="text-3xl font-bold mb-4" style="color: var(--color-rb-orange)">Gemeinschaft</h2>
|
||||
<p class="text-[var(--color-text-muted)] leading-relaxed mb-4">
|
||||
Eine Kita ist stärker, wenn das Umfeld sie trägt. Der Förderverein baut diese
|
||||
Verbindung: zwischen Eltern, Erzieher*innen, Nachbarschaft und lokalen Unternehmen.
|
||||
</p>
|
||||
<p class="text-[var(--color-text-muted)] leading-relaxed mb-6">
|
||||
Das bedeutet: gemeinsame Feste, die Menschen zusammenbringen. Kooperationen mit
|
||||
lokalen Partnern. Eine Öffentlichkeit, die weiß, was hier passiert und warum es sich
|
||||
lohnt, dabei zu sein.
|
||||
</p>
|
||||
<div class="space-y-3">
|
||||
{[
|
||||
"🎉 Sommer- und Frühlingsfeste",
|
||||
"🛍️ Basare und Gemeinschaftsevents",
|
||||
"🏢 Kooperationen mit lokalen Unternehmen",
|
||||
"📣 Öffentlichkeitsarbeit für die Kita",
|
||||
].map((item) => (
|
||||
<p class="text-[var(--color-text-muted)]">{item}</p>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
<div class="card bg-[var(--color-accent-light)] border-0 p-8 text-center">
|
||||
<p class="font-brand text-6xl text-[var(--color-accent)] mb-4">+</p>
|
||||
<p class="text-lg font-semibold text-[var(--color-text)] mb-2">Du hast eine Idee?</p>
|
||||
<p class="text-[var(--color-text-muted)] mb-6">
|
||||
Der Verein ist offen für neue Projekte, Kooperationsideen und Initiativen.
|
||||
</p>
|
||||
<a href="/kontakt" class="btn-primary" style="background: var(--color-accent)">Idee einbringen</a>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- CTA -->
|
||||
<section class="section text-center">
|
||||
<h2 class="font-brand text-4xl mb-4">Dabei sein.</h2>
|
||||
<p class="text-[var(--color-text-muted)] mb-8">Ab 1 € im Monat. Keine Verpflichtungen.</p>
|
||||
<div class="flex flex-col sm:flex-row gap-4 justify-center">
|
||||
<a href="/mitglied-werden" class="btn-primary">Mitglied werden</a>
|
||||
<a href="/unterstuetzen" class="btn-secondary">Einmalig spenden</a>
|
||||
</div>
|
||||
</section>
|
||||
</Layout>
|
||||
82
src/styles/global.css
Normal file
82
src/styles/global.css
Normal file
@@ -0,0 +1,82 @@
|
||||
@import "tailwindcss";
|
||||
|
||||
@theme {
|
||||
/* Regenbogen CI — aus dem Logoguide */
|
||||
--color-rb-red: #E8192C;
|
||||
--color-rb-orange: #F5820D;
|
||||
--color-rb-yellow: #F9C80E;
|
||||
--color-rb-green: #00A651;
|
||||
--color-rb-cyan: #00AEEF;
|
||||
--color-rb-blue: #3B4FA8;
|
||||
--color-rb-violet: #6B3FA0;
|
||||
|
||||
--color-primary: #6B3FA0;
|
||||
--color-primary-dark: #4D2C78;
|
||||
--color-primary-light: #9B6FC8;
|
||||
--color-accent: #F5820D;
|
||||
--color-accent-light: #FEF3E8;
|
||||
|
||||
--color-surface: #FAFAFA;
|
||||
--color-surface-alt: #F4EFF9;
|
||||
--color-text: #1A1A2E;
|
||||
--color-text-muted: #6B7280;
|
||||
--color-border: #E5E7EB;
|
||||
|
||||
--font-brand: "Apex Brush", "Pacifico", cursive;
|
||||
--font-body: "Inter", system-ui, sans-serif;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: "Apex Brush";
|
||||
src: url("/fonts/ApexBrush-Regular.woff2") format("woff2"),
|
||||
url("/fonts/ApexBrush-Regular.woff") format("woff");
|
||||
font-weight: normal;
|
||||
font-display: swap;
|
||||
}
|
||||
|
||||
html { scroll-behavior: smooth; }
|
||||
|
||||
body {
|
||||
font-family: var(--font-body);
|
||||
color: var(--color-text);
|
||||
background: var(--color-surface);
|
||||
}
|
||||
|
||||
.font-brand { font-family: var(--font-brand); }
|
||||
|
||||
.rainbow-bar {
|
||||
height: 4px;
|
||||
background: linear-gradient(
|
||||
to right,
|
||||
#E8192C, #F5820D, #F9C80E, #00A651, #00AEEF, #3B4FA8, #6B3FA0
|
||||
);
|
||||
}
|
||||
|
||||
.rainbow-text {
|
||||
background: linear-gradient(135deg, #6B3FA0, #3B4FA8, #00A651);
|
||||
-webkit-background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
background-clip: text;
|
||||
}
|
||||
|
||||
.btn-primary {
|
||||
@apply inline-flex items-center gap-2 px-6 py-3 rounded-full font-semibold text-white transition-all duration-200;
|
||||
background: var(--color-primary);
|
||||
}
|
||||
.btn-primary:hover { background: var(--color-primary-dark); transform: translateY(-1px); }
|
||||
|
||||
.btn-secondary {
|
||||
@apply inline-flex items-center gap-2 px-6 py-3 rounded-full font-semibold transition-all duration-200;
|
||||
border: 2px solid var(--color-primary);
|
||||
color: var(--color-primary);
|
||||
}
|
||||
.btn-secondary:hover { background: var(--color-surface-alt); }
|
||||
|
||||
.card {
|
||||
@apply rounded-2xl bg-white border p-6 transition-shadow duration-200;
|
||||
border-color: var(--color-border);
|
||||
}
|
||||
.card:hover { box-shadow: 0 8px 30px rgba(107,63,160,0.12); }
|
||||
|
||||
.section { @apply py-16 px-4 max-w-6xl mx-auto; }
|
||||
.section-sm { @apply py-10 px-4 max-w-6xl mx-auto; }
|
||||
5
tsconfig.json
Normal file
5
tsconfig.json
Normal file
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"extends": "astro/tsconfigs/strict",
|
||||
"include": [".astro/types.d.ts", "**/*"],
|
||||
"exclude": ["dist"]
|
||||
}
|
||||
Reference in New Issue
Block a user