slimcore-website/src/pages/dev/components.astro
Pascal Oelmann 968945fc86
All checks were successful
Deploy Marketing-Site / Build, Test und Deploy (push) Successful in 1m9s
font-serif → font-sans (Outfit) familienweit, --font-serif-Token raus
Brand-System hat seit Mai-Update keine Serif mehr (Wechsel zu Outfit
single-font). Der Tailwind-Klassen-Alias font-serif → Outfit war ein
Backwards-Compat-Hack ohne Grund — entfernt.

- Submodule docs/brand-system: Outfit + JBM (e4d9f95)
- src/styles/global.css: --font-serif-Token entfernt
- Alle Tailwind-font-serif-Klassen → font-sans (~50 Stellen)
- CLAUDE.md §5.3: Doc des Alias entfernt

Visual identisch (Token zeigte schon vorher auf Outfit), nur Klassen-Namen
sind nun semantisch korrekt.
2026-05-05 03:04:49 +02:00

255 lines
11 KiB
Text
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
import BaseLayout from '@/layouts/BaseLayout.astro';
import Eyebrow from '@/components/marketing/Eyebrow.astro';
import StatusDot from '@/components/marketing/StatusDot.astro';
import SectionHeading from '@/components/marketing/SectionHeading.astro';
import NumberedItem from '@/components/marketing/NumberedItem.astro';
import ModuleCard from '@/components/marketing/ModuleCard.astro';
import ModuleGrid from '@/components/marketing/ModuleGrid.astro';
import TechStrip from '@/components/marketing/TechStrip.astro';
import SovereigntyBlock from '@/components/marketing/SovereigntyBlock.astro';
import RoadmapTimeline from '@/components/marketing/RoadmapTimeline.astro';
import ObjectionAnswer from '@/components/marketing/ObjectionAnswer.astro';
import CTABlock from '@/components/marketing/CTABlock.astro';
import type { ModuleStatus } from '@/content/module';
const allStatuses: ModuleStatus[] = ['available', 'developing', 'planned', 'vision'];
const sovereigntyItems = [
{ label: '01 · HOSTING', body: 'Hetzner-Rechenzentren in Falkenstein und Nürnberg. Deutsches Recht, DSGVO, kein US-Anbieter im Datenfluss.' },
{ label: '02 · STACK', body: 'PostgreSQL, PostgREST, Docker. Ausschließlich Open-Source-Komponenten unter freien Lizenzen.' },
{ label: '03 · EXPORT', body: 'Volle Datenexporte in offenen Formaten — jederzeit, ohne Aufpreis, ohne Zustimmung von uns.' },
{ label: '04 · EGRESS', body: 'Optionaler Compliance-Layer mit Egress-Audit und -Proxy. Sie sehen, was Ihr Mandant sendet.' },
];
const roadmapPhases = [
{
label: 'Heute',
description: 'Was heute produktiv genutzt wird.',
current: true,
items: [
{ name: 'CRM', status: 'available' as const },
{ name: 'Lager', status: 'available' as const },
{ name: 'Bestellungen', status: 'available' as const },
{ name: 'Belege', status: 'available' as const },
{ name: 'Zahlungen', status: 'available' as const },
{ name: 'BuHa-Export (DATEV)', status: 'available' as const },
],
},
{
label: 'Q3Q4 2026',
description: 'Im aktiven Bau, kommt in den nächsten Monaten.',
items: [
{ name: 'Team-E-Mail', status: 'developing' as const },
{ name: 'Artikel', status: 'developing' as const },
{ name: 'Verkaufskanäle', status: 'developing' as const },
{ name: 'Versand', status: 'developing' as const },
{ name: 'Rechnungen (ZUGFeRD)', status: 'developing' as const },
{ name: 'Aufgaben', status: 'developing' as const },
],
},
{
label: '2027',
description: 'Feste Roadmap, Reihenfolge nach Tester-Feedback.',
items: [
{ name: 'Helpdesk', status: 'planned' as const },
{ name: 'Telefonie', status: 'planned' as const },
{ name: 'Einkauf', status: 'planned' as const },
{ name: 'Projekte', status: 'planned' as const },
{ name: 'Zeiterfassung', status: 'planned' as const },
{ name: 'Personal', status: 'planned' as const },
],
},
{
label: 'Vision',
description: 'Richtung, kein Versprechen.',
items: [
{ name: 'WhatsApp Business', status: 'vision' as const },
{ name: 'KI-Assistent', status: 'vision' as const },
],
},
];
const stackItems = ['PostgreSQL', 'PostgREST', 'Hetzner DE', 'DSGVO', 'ZUGFeRD 2.0', 'DATEV'];
const sectionDivider = 'mt-20 border-t border-[var(--color-border)] pt-12';
const componentLabel = 'mb-6 inline-block bg-[var(--color-text-primary)] px-2 py-1 font-mono text-[10px] font-medium uppercase tracking-[0.08em] text-[var(--color-bg-base)]';
---
<BaseLayout title="Component Showcase (Dev)" description="Interne Komponenten-Übersicht für visuelle Regression.">
<div class="mx-auto max-w-[1100px] px-6 py-16 md:px-10 md:py-20 xl:px-12">
<Eyebrow tone="accent" prefix="▸">Dev · Component Showcase</Eyebrow>
<h1 class="mt-3 font-sans text-[2.5rem] font-medium leading-[1.1] text-[var(--color-text-primary)]">
Komponenten-Bibliothek
</h1>
<p class="mt-4 max-w-[60ch] text-[1.0625rem] leading-relaxed text-[var(--color-text-secondary)]">
Diese Seite ist nur intern. Sie zeigt jede Komponente in jeder Variante zur visuellen Abnahme. Nicht im Sitemap verlinkt.
</p>
{/* — 1. Eyebrow — */}
<section class={sectionDivider}>
<span class={componentLabel}>Eyebrow</span>
<div class="flex flex-col gap-4 bg-[var(--color-bg-surface)] p-6">
<Eyebrow>Default · tertiärer Ton</Eyebrow>
<Eyebrow tone="accent" prefix="▸">Hero-Variante mit Persimmon und ▸-Prefix</Eyebrow>
<Eyebrow status="IN ENTWICKLUNG">Mit Status-Pille</Eyebrow>
</div>
<div class="mt-2 bg-[#0E0F14] p-6">
<Eyebrow tone="inverse">Inverse-Variante (auf dunklem Grund)</Eyebrow>
</div>
</section>
{/* — 2. StatusDot — */}
<section class={sectionDivider}>
<span class={componentLabel}>StatusDot</span>
<div class="flex flex-col gap-6">
<div class="flex flex-wrap gap-8 bg-[var(--color-bg-surface)] p-6">
{allStatuses.map((s) => <StatusDot status={s} label />)}
</div>
<div class="flex flex-wrap gap-8 bg-[#0E0F14] p-6 text-[#F5F5F0]">
{allStatuses.map((s) => <StatusDot status={s} label inverse />)}
</div>
</div>
</section>
{/* — 3. SectionHeading — */}
<section class={sectionDivider}>
<span class={componentLabel}>SectionHeading</span>
<div class="flex flex-col gap-10 bg-[var(--color-bg-surface)] p-6">
<SectionHeading
eyebrow="WAS UNS TRENNT"
subtitle="Best-Practices der großen Tools, bedienbar wie ein modernes SaaS."
>
Drei Differenzierungen, die zählen.
</SectionHeading>
<SectionHeading display>
Display-Variante ohne Eyebrow.
</SectionHeading>
</div>
</section>
{/* — 4. NumberedItem — */}
<section class={sectionDivider}>
<span class={componentLabel}>NumberedItem</span>
<div class="grid grid-cols-1 gap-8 bg-[var(--color-bg-surface)] p-6 md:grid-cols-3">
<NumberedItem number="01" title="Schlank von Tag 1">
Sie aktivieren das, was Sie heute brauchen — meistens CRM, Belege und Aufgaben.
</NumberedItem>
<NumberedItem number="02" title="Wächst mit">
Wenn aus Ihnen drei werden, dann fünfzehn, bleiben Sie in derselben Software.
</NumberedItem>
<NumberedItem number="03" title="Souverän">
In Deutschland gehostet, Open-Source-Stack, Datenexport jederzeit.
</NumberedItem>
</div>
</section>
{/* — 5. ModuleCard (einzeln) — */}
<section class={sectionDivider}>
<span class={componentLabel}>ModuleCard (einzeln)</span>
<div class="grid grid-cols-1 gap-4 md:grid-cols-2">
<ModuleCard
pillarNumber="01"
pillarTitle="Kunden & Kommunikation"
modules={[
{ name: 'CRM', status: 'available' },
{ name: 'Team-E-Mail', status: 'developing' },
{ name: 'Helpdesk', status: 'planned' },
{ name: 'Telefonie', status: 'planned' },
{ name: 'WhatsApp', status: 'vision' },
]}
/>
<ModuleCard
pillarNumber="03"
pillarTitle="Belege & Finanzen"
modules={[
{ name: 'Belege', status: 'available' },
{ name: 'Rechnungen', status: 'developing' },
{ name: 'Zahlungen', status: 'available' },
{ name: 'BuHa-Export', status: 'available' },
]}
/>
</div>
</section>
{/* — 6. ModuleGrid (komplett) — */}
<section class={sectionDivider}>
<span class={componentLabel}>ModuleGrid</span>
<ModuleGrid />
</section>
</div>
{/* — 7. TechStrip (full-bleed) — */}
<section class="mt-12">
<div class="mx-auto max-w-[1100px] px-6 md:px-10 xl:px-12">
<span class={componentLabel}>TechStrip · dark</span>
</div>
<TechStrip items={stackItems} variant="dark" />
<div class="mx-auto max-w-[1100px] px-6 md:px-10 xl:px-12">
<span class={`${componentLabel} mt-8`}>TechStrip · light</span>
</div>
<TechStrip items={stackItems} variant="light" />
</section>
<div class="mx-auto max-w-[1100px] px-6 md:px-10 xl:px-12">
{/* — 8. SovereigntyBlock — */}
<section class={sectionDivider}>
<span class={componentLabel}>SovereigntyBlock</span>
<SovereigntyBlock
headlineLines={['Ihre Daten.', 'Ihr Land.', 'Ihre Kontrolle.']}
lead="Souveränität ist bei SlimCore kein Marketing-Begriff, sondern eine Architektur-Entscheidung. Vier konkrete Punkte zeigen, was das im Alltag bedeutet."
items={sovereigntyItems}
/>
</section>
{/* — 9. RoadmapTimeline — */}
<section class={sectionDivider}>
<span class={componentLabel}>RoadmapTimeline</span>
<RoadmapTimeline phases={roadmapPhases} />
</section>
{/* — 10. ObjectionAnswer — */}
<section class={sectionDivider}>
<span class={componentLabel}>ObjectionAnswer</span>
<div class="grid grid-cols-1 gap-8 md:grid-cols-2">
<ObjectionAnswer question="Wir sind nur zwei. Lohnt sich das?">
Genau für Sie gebaut. Drei Module reichen zum Start — und wachsen mit, wenn Sie wachsen.
</ObjectionAnswer>
<ObjectionAnswer question="Was, wenn ihr verschwindet?">
Voller Export in offenem Schema. Jeder PostgreSQL-Hoster führt Ihren Mandanten weiter.
</ObjectionAnswer>
</div>
</section>
{/* — 11. CTABlock — */}
<section class={sectionDivider}>
<span class={componentLabel}>CTABlock · light</span>
<CTABlock
eyebrow="TESTER-PROGRAMM · PHASE 1"
headline="Sie kennen die Lücken besser als jeder Berater."
body="Helfen Sie uns, die Geschäftssoftware zu bauen, die Sie hoffentlich die nächsten zehn Jahre nutzen wollen."
ctas={[
{ label: 'Tester werden', href: '/tester', variant: 'primary' },
{ label: 'hallo@slimcore.io', href: 'mailto:hallo@slimcore.io', variant: 'ghost' },
]}
/>
</section>
</div>
<section class="mt-20 bg-[#0E0F14] py-20">
<div class="mx-auto max-w-[1100px] px-6 md:px-10 xl:px-12">
<span class="mb-6 inline-block bg-[#F5F5F0] px-2 py-1 font-mono text-[10px] font-medium uppercase tracking-[0.08em] text-[#0E0F14]">
CTABlock · inverse
</span>
<CTABlock
inverse
eyebrow="30 MINUTEN · UNVERBINDLICH"
headline="Lassen Sie uns ehrlich gucken, ob SlimCore zu Ihrer Situation passt."
ctas={[
{ label: 'Tester werden', href: '/tester', variant: 'primary' },
{ label: 'Termin vereinbaren', href: 'https://calendly.com/digiformer/quick-call', variant: 'secondary' },
]}
/>
</div>
</section>
</BaseLayout>