From e0605b2f2e89ad8978dc6c611df8f740485599c9 Mon Sep 17 00:00:00 2001 From: Till JS Date: Wed, 20 May 2026 21:38:41 +0200 Subject: [PATCH] feat(landing): Marketing-Astro auf wordeck.com LIVE MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Astro-Landing als neuer Apex-Container (:3202), gebaut mit @mana/marketing-kit. Probe-Cutover der Welle-1-Charge (niedrigstes Compliance-Risiko, höchste Ship-Reife). Anki-Migration als Akquise-Anker; /anki-import als dedicated Long-Tail-Page mit 3-Schritt-Anleitung + FAQ + JSON-LD FAQPage (Sitemap-Priorität 0.95). - apps/landing/ — index, anki-import, ueber, mitwirken + robots/llms/sitemap-Endpoints - infrastructure/macmini/docker-compose.landing.yml — Port 3202 - .gitignore += .astro Cutover-Playbook: mana/docs/playbooks/LANDING_CUTOVER.md Domain-Status: wordeck.com → :3202 (Marketing, NEU) www.wordeck.com → :3202 (Marketing, NEU) app.wordeck.com → :5181 (Web-App, NEU als Subdomain) api.wordeck.com → :3191 (API, unverändert) Co-Authored-By: Claude Opus 4.7 (1M context) --- .gitignore | 1 + apps/landing/Dockerfile | 31 +++++ apps/landing/astro.config.mjs | 14 +++ .../macmini/docker-compose.landing.yml | 30 +++++ apps/landing/infrastructure/nginx.conf | 41 +++++++ apps/landing/package.json | 20 ++++ apps/landing/public/icon.png | Bin 0 -> 46118 bytes apps/landing/src/env.d.ts | 1 + apps/landing/src/lib/app.ts | 87 ++++++++++++++ apps/landing/src/pages/anki-import.astro | 108 ++++++++++++++++++ apps/landing/src/pages/index.astro | 88 ++++++++++++++ apps/landing/src/pages/llms.txt.ts | 42 +++++++ apps/landing/src/pages/mitwirken.astro | 62 ++++++++++ apps/landing/src/pages/robots.txt.ts | 8 ++ apps/landing/src/pages/sitemap.xml.ts | 19 +++ apps/landing/src/pages/ueber.astro | 82 +++++++++++++ apps/landing/tsconfig.json | 4 + 17 files changed, 638 insertions(+) create mode 100644 apps/landing/Dockerfile create mode 100644 apps/landing/astro.config.mjs create mode 100644 apps/landing/infrastructure/macmini/docker-compose.landing.yml create mode 100644 apps/landing/infrastructure/nginx.conf create mode 100644 apps/landing/package.json create mode 100644 apps/landing/public/icon.png create mode 100644 apps/landing/src/env.d.ts create mode 100644 apps/landing/src/lib/app.ts create mode 100644 apps/landing/src/pages/anki-import.astro create mode 100644 apps/landing/src/pages/index.astro create mode 100644 apps/landing/src/pages/llms.txt.ts create mode 100644 apps/landing/src/pages/mitwirken.astro create mode 100644 apps/landing/src/pages/robots.txt.ts create mode 100644 apps/landing/src/pages/sitemap.xml.ts create mode 100644 apps/landing/src/pages/ueber.astro create mode 100644 apps/landing/tsconfig.json diff --git a/.gitignore b/.gitignore index f696656..22fbe61 100644 --- a/.gitignore +++ b/.gitignore @@ -70,3 +70,4 @@ apps/landing/.astro # NPM Auth — Verdaccio-Token soll nie in git .npmrc +.astro diff --git a/apps/landing/Dockerfile b/apps/landing/Dockerfile new file mode 100644 index 0000000..174a7c9 --- /dev/null +++ b/apps/landing/Dockerfile @@ -0,0 +1,31 @@ +# Multi-stage build for the wordeck-landing Astro surface. +# +# Build context is the repo root (set in +# infrastructure/macmini/docker-compose.landing.yml as `../..`). +# +# NPM_AUTH_TOKEN is required at build time (BuildKit secret) so pnpm +# can fetch @mana/marketing-kit from npm.mana.how (Verdaccio). + +FROM node:20-alpine AS builder +WORKDIR /repo +RUN corepack enable && corepack prepare pnpm@9.15.9 --activate + +# Workspace shell first (cache-friendly). +COPY package.json pnpm-workspace.yaml pnpm-lock.yaml .npmrc ./ +COPY apps/landing/package.json ./apps/landing/ + +RUN --mount=type=secret,id=npm_token,env=NPM_AUTH_TOKEN \ + pnpm install --filter @wordeck/landing --frozen-lockfile 2>/dev/null \ + || pnpm install --filter @wordeck/landing + +COPY apps/landing ./apps/landing + +WORKDIR /repo/apps/landing +RUN pnpm build + +FROM nginx:1.27-alpine AS production +COPY --from=builder /repo/apps/landing/dist /usr/share/nginx/html +COPY apps/landing/infrastructure/nginx.conf /etc/nginx/conf.d/default.conf +EXPOSE 80 +HEALTHCHECK --interval=30s --timeout=5s --retries=3 \ + CMD wget -qO- http://127.0.0.1/ >/dev/null 2>&1 || exit 1 diff --git a/apps/landing/astro.config.mjs b/apps/landing/astro.config.mjs new file mode 100644 index 0000000..3493dbe --- /dev/null +++ b/apps/landing/astro.config.mjs @@ -0,0 +1,14 @@ +import { defineConfig } from 'astro/config' + +// wordeck-Marketing-Landing. +// +// Statisch, prerendered. Apex `wordeck.com` serviert das Build-Output; +// `app.wordeck.com` läuft separat (SvelteKit-App in `apps/web/`). +export default defineConfig({ + site: 'https://wordeck.com', + output: 'static', + trailingSlash: 'never', + build: { + format: 'file', + }, +}) diff --git a/apps/landing/infrastructure/macmini/docker-compose.landing.yml b/apps/landing/infrastructure/macmini/docker-compose.landing.yml new file mode 100644 index 0000000..8cf9851 --- /dev/null +++ b/apps/landing/infrastructure/macmini/docker-compose.landing.yml @@ -0,0 +1,30 @@ +# wordeck-landing — Marketing-Astro auf wordeck.com. +# +# Eigenständiger Compose-Stack neben dem App-Stack +# (apps/api + apps/web). Nutzt das gleiche `wordeck`-COMPOSE_PROJECT_NAME, +# damit die Container-Namen im selben Namespace landen. +# +# Cutover-Plan: mana/docs/playbooks/LANDING_CUTOVER.md +# Port: 3202 (siehe mana/docs/PORTS.md → Marketing-Landings) +# +# Cloudflared-Tunnel (in ~/projects/managarten/cloudflared-config.yml): +# wordeck.com → http://localhost:3202 (NEU, nach Cutover) +# www.wordeck.com → http://localhost:3202 (NEU, nach Cutover) +# app.wordeck.com → http://localhost:5181 (NEU — App-Subdomain) +# api.wordeck.com → http://localhost:3191 (unverändert) + +services: + wordeck-landing: + build: + context: ../../../.. + dockerfile: apps/landing/Dockerfile + secrets: [npm_token] + image: wordeck-landing:latest + container_name: wordeck-landing + restart: unless-stopped + ports: + - '3202:80' + +secrets: + npm_token: + file: ~/.npm_token diff --git a/apps/landing/infrastructure/nginx.conf b/apps/landing/infrastructure/nginx.conf new file mode 100644 index 0000000..b6d4e5c --- /dev/null +++ b/apps/landing/infrastructure/nginx.conf @@ -0,0 +1,41 @@ +# nginx config für wordeck-landing — Astro statisch, no SPA fallback. +# +# Astro baut mit format='file' und trailingSlash='never', d.h. +# /anki-import → /anki-import.html. try_files-Kette deckt das ab. + +server { + listen 80 default_server; + server_name _; + root /usr/share/nginx/html; + index index.html; + + # Plain-Text-Endpoints (Astro-API-Routes wurden als .txt/.xml gebaut). + location = /robots.txt { + default_type "text/plain; charset=utf-8"; + try_files $uri =404; + } + location = /llms.txt { + default_type "text/plain; charset=utf-8"; + try_files $uri =404; + } + location = /sitemap.xml { + default_type "application/xml; charset=utf-8"; + try_files $uri =404; + } + + # Canonical paths → .html siblings; unknown paths 404. + location / { + try_files $uri $uri.html $uri/ =404; + } + + # Astro asset bundles → long-cache. + location /_astro/ { + expires 1y; + add_header Cache-Control "public, immutable"; + } + + # Standard MIME-Optimierungen. + gzip on; + gzip_types text/plain text/css text/javascript application/javascript application/json application/xml application/manifest+json image/svg+xml; + gzip_min_length 1024; +} diff --git a/apps/landing/package.json b/apps/landing/package.json new file mode 100644 index 0000000..cd56d8f --- /dev/null +++ b/apps/landing/package.json @@ -0,0 +1,20 @@ +{ + "name": "@wordeck/landing", + "private": true, + "version": "0.1.0", + "type": "module", + "description": "Marketing-Landing für wordeck.com — Astro, statisch, SEO/LLM-optimiert. App selbst läuft auf app.wordeck.com.", + "scripts": { + "dev": "astro dev --port 4325", + "build": "astro build", + "preview": "astro preview --port 4326", + "check": "astro check" + }, + "dependencies": { + "@mana/marketing-kit": "^0.1.0", + "astro": "^4.16.0" + }, + "devDependencies": { + "typescript": "^5.9.3" + } +} diff --git a/apps/landing/public/icon.png b/apps/landing/public/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..76f939ec485c20d45694fb6918f255dbb6e1ca60 GIT binary patch literal 46118 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 }3f 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 literal 0 HcmV?d00001 diff --git a/apps/landing/src/env.d.ts b/apps/landing/src/env.d.ts new file mode 100644 index 0000000..9bc5cb4 --- /dev/null +++ b/apps/landing/src/env.d.ts @@ -0,0 +1 @@ +/// \ No newline at end of file diff --git a/apps/landing/src/lib/app.ts b/apps/landing/src/lib/app.ts new file mode 100644 index 0000000..ae6fbf5 --- /dev/null +++ b/apps/landing/src/lib/app.ts @@ -0,0 +1,87 @@ +import type { AppMeta, FaqItem, Feature, Stat } from '@mana/marketing-kit' + +/** + * Single Source of Truth für wordeck-Marketing-Daten. + * + * Hook ist „Anki ohne Akrobatik" — Anki-Migration als Akquise-Anker, + * analog zu pageta + Pocket-Import. Wordeck ist Welle-1-Position-2: + * höchste Ship-Reife, niedrigstes Compliance-Risiko der Welle. + */ +export const app: AppMeta = { + slug: 'wordeck', + domain: 'wordeck.com', + appDomain: 'app.wordeck.com', + hook: 'Anki ohne Akrobatik. Karten lernen in 30 Sekunden installiert.', + tagline: + 'Spaced-Repetition-Karteikarten mit FSRS. Anki-Import inklusive Cloze. Web + iOS, vereinsgetragen.', + description: + 'Wordeck ist die Karteikarten-App von mana e.V. — FSRS-Scheduler, .apkg-Anki-Import mit Cloze-Erkennung, drei Marketplace-Decks zum Start.', + theme: 'neutral', +} + +export const stats: Stat[] = [ + { value: '.apkg', label: 'Anki-Import', hint: 'Inkl. Cloze' }, + { value: 'FSRS', label: 'Scheduler', hint: 'Nachfolger von SM-2' }, + { value: 648, label: 'Karten im Marketplace', hint: '3 Decks zum Start' }, + { value: 0, label: 'Tracker', hint: 'Versprochen' }, +] + +export const features: Feature[] = [ + { + icon: '📦', + title: 'Anki-Import', + body: 'Deine .apkg-Decks aus Anki einlesen — Cloze-Karten werden als first-class behandelt, Duplikate dedupliziert per content-hash.', + }, + { + icon: '🧠', + title: 'FSRS-Scheduler', + body: 'Free Spaced Repetition Scheduler — der wissenschaftlich nachgewiesene Nachfolger von Ankis SM-2. Weniger Wiederholungen bei gleichem Retention-Ziel.', + }, + { + icon: '🛒', + title: 'Marketplace-Decks', + body: 'Drei kuratierte Decks (648 Karten) unter CC0/CC-BY-4.0 ready-to-import. Eigene Decks lassen sich teilen — kein Lock-in.', + }, + { + icon: '✍️', + title: 'Cloze first-class', + body: 'Lückentext-Karten („Albert Einstein lebte von {{c1::1879}} bis {{c2::1955}}") sind nicht eine Notlösung, sondern erste Klasse.', + }, + { + icon: '🌐', + title: 'Web + iOS', + body: 'Im Browser lernen, auf dem iPhone offline weiterlernen. Native-App auf TestFlight; Android über die PWA-Installation.', + }, + { + icon: '🔓', + title: 'Export jederzeit', + body: 'Deine Decks bleiben deine Decks — Export zurück nach Anki-kompatiblem Format ist nicht „Premium-Feature", sondern Default.', + }, +] + +export const faq: FaqItem[] = [ + { + q: 'Was unterscheidet Wordeck von Anki?', + a: 'Anki ist mächtig, aber die Mobile-Apps kosten 25€ einmalig und die UI ist 20 Jahre alt. Wordeck ist Web + Native, FSRS statt SM-2, ohne Werbung, ohne Tracker. Anki-Decks importierst du in 30 Sekunden.', + }, + { + q: 'Was ist FSRS und warum ist das wichtig?', + a: 'Free Spaced Repetition Scheduler — Open-Source-Algorithmus, der empirisch belegt weniger Wiederholungen bei gleichem Lernerfolg braucht als SM-2 (Ankis Default). Anki selbst hat FSRS seit 2024 als Opt-in; Wordeck ist FSRS-only.', + }, + { + q: 'Was passiert mit meinen Decks, wenn Wordeck verschwindet?', + a: 'Export als JSON oder Anki-.apkg ist jederzeit verfügbar. Wordeck ist vereinsgetragen, kein Exit-Risiko — aber die Export-Garantie steht davon unabhängig.', + }, + { + q: 'Kostet Wordeck etwas?', + a: 'Die Basis-App und alle Marketplace-Decks sind kostenlos. Optionale KI-Funktionen (z.B. „Karten aus Text generieren") laufen über Mana-Credits zum Selbstkostenpreis — sichtbar pro Aktion, abschaltbar.', + }, + { + q: 'Funktioniert Wordeck ohne Login?', + a: 'Marketplace-Decks ansehen und Demo-Lernen geht ohne Account. Eigene Decks anlegen und Sync zwischen Geräten brauchen einen Login.', + }, + { + q: 'Welche Sprachen sind unterstützt?', + a: 'UI heute DE/EN. Karten selbst sind sprach-agnostisch — du lernst Latein, Japanisch, Code, Botanik oder was auch immer.', + }, +] diff --git a/apps/landing/src/pages/anki-import.astro b/apps/landing/src/pages/anki-import.astro new file mode 100644 index 0000000..e1056e7 --- /dev/null +++ b/apps/landing/src/pages/anki-import.astro @@ -0,0 +1,108 @@ +--- +import AppLanding from '@mana/marketing-kit/layouts/AppLanding.astro' +import Hero from '@mana/marketing-kit/components/Hero.astro' +import StorySection from '@mana/marketing-kit/components/StorySection.astro' +import FAQ from '@mana/marketing-kit/components/FAQ.astro' +import CTABanner from '@mana/marketing-kit/components/CTABanner.astro' +import { buildSeo, faqJsonLd } from '@mana/marketing-kit' +import { app } from '../lib/app.js' + +/** + * Long-Tail-Page für „anki alternative", „anki deck import", + * „anki ios kostenlos", „fsrs scheduler". Eigene canonical, + * eigene FAQ. Höchste Akquise-Konversion der Welle nach pageta/ + * pocket-import. + */ + +const seo = buildSeo(app, { + path: '/anki-import', + title: 'Anki-Deck in Wordeck importieren — .apkg, Cloze, FSRS', + description: + 'Schritt-für-Schritt: bestehende Anki-Decks samt Cloze-Karten und Tags nach Wordeck migrieren. FSRS statt SM-2, ohne 25€-iOS-Gebühr.', +}) + +const ankiFaq = [ + { + q: 'Welche Anki-Versionen kann ich importieren?', + a: 'Wordeck liest .apkg-Dateien aus Anki 2.x (Desktop, AnkiDroid, AnkiMobile). Karten, Decks, Tags und Cloze-Notes werden übernommen. Add-on-spezifische Felder werden ignoriert, der Karten-Text bleibt unverändert.', + }, + { + q: 'Was passiert mit meinen FSRS-Parametern aus Anki?', + a: 'FSRS-Optimizer-Parameter aus Anki werden bei Import übernommen, sofern im Deck enthalten. Wenn dein Anki-Deck noch auf SM-2 läuft, startest du in Wordeck mit den FSRS-Defaults — der erste Optimizer-Lauf nach ~1000 Reviews tuned das automatisch.', + }, + { + q: 'Was ist mit meiner Lernhistorie?', + a: 'Reviews-Historie wird bei Import-Standard übernommen, damit FSRS daraus lernen kann. Du kannst optional „Frische Liste" wählen, wenn du das Deck neu starten willst.', + }, + { + q: 'Sind Cloze-Karten unterstützt?', + a: 'Ja, first-class. Cloze-Marker ({{c1::...}}) werden korrekt erkannt und als eine Notiz mit mehreren Karten behandelt — wie in Anki.', + }, + { + q: 'Was passiert mit Duplikaten?', + a: 'Dedupliziert per content-hash. Wenn du das gleiche Deck zweimal importierst, werden bereits importierte Karten übersprungen (Skip-Counter im Erfolgs-Report).', + }, + { + q: 'Kann ich später zurück zu Anki?', + a: 'Ja. Wordeck exportiert .apkg-kompatibel jederzeit — inklusive Reviews-Historie, sofern du die behalten hast. Kein „Premium-Feature", kein „nach 30 Tagen weg".', + }, +] + +const jsonLd = [faqJsonLd(ankiFaq)] +--- + + + + + +

+ In Anki: Datei → Exportieren wählen, Deck auswählen, Format + „Anki Deck Package (.apkg)" — mit oder ohne Lernfortschritt, ganz wie + du magst. Funktioniert auch in AnkiDroid und AnkiMobile. +

+
+ + +

+ Auf app.wordeck.com mit E-Mail + registrieren. Email-Verifikation, kein Telefon-Theater, keine + Social-OAuth-Pflicht. Account ist in unter zwei Minuten fertig. +

+
+ + +

+ In Wordeck: Decks → „Importieren" → .apkg-Datei auswählen. Wordeck + parst das Paket, dedupliziert, übernimmt Tags und Cloze-Karten, + zeigt eine Live-Statistik (importiert / übersprungen / Fehler). +

+
+ + +
    +
  • Deck — alle Karten, Tags, Cloze-Notes
  • +
  • FSRS-Scheduler aktiviert, mit deinen Anki-Parametern (falls vorhanden)
  • +
  • Reviews-Historie übernommen (optional)
  • +
  • Web + iOS — sofort auf beiden Plattformen lernbar
  • +
  • Export jederzeit zurück nach .apkg verfügbar
  • +
+
+ + + + +
diff --git a/apps/landing/src/pages/index.astro b/apps/landing/src/pages/index.astro new file mode 100644 index 0000000..6bed990 --- /dev/null +++ b/apps/landing/src/pages/index.astro @@ -0,0 +1,88 @@ +--- +import AppLanding from '@mana/marketing-kit/layouts/AppLanding.astro' +import Hero from '@mana/marketing-kit/components/Hero.astro' +import StorySection from '@mana/marketing-kit/components/StorySection.astro' +import StatsRow from '@mana/marketing-kit/components/StatsRow.astro' +import FeatureGrid from '@mana/marketing-kit/components/FeatureGrid.astro' +import FAQ from '@mana/marketing-kit/components/FAQ.astro' +import CTABanner from '@mana/marketing-kit/components/CTABanner.astro' +import { buildSeo, faqJsonLd } from '@mana/marketing-kit' + +import { app, stats, features, faq } from '../lib/app.js' + +const seo = buildSeo(app, { + path: '/', + title: `wordeck — ${app.hook}`, + description: app.tagline, +}) + +const jsonLd = [faqJsonLd(faq)] +--- + + + + + + + +

+ Spaced Repetition funktioniert — das ist seit Jahrzehnten unstrittig. + Anki ist die offene Referenz-Implementierung, und sie ist großartig. + Aber: die iOS-App kostet einmalig 25€, das Web-UI ist optisch in der + Mitte der 2000er stehen geblieben, und die FSRS-Umstellung ist + optional und versteckt. +

+

+ Wordeck nimmt dieselben Konzepte (Cards, Decks, Cloze, SRS), schreibt + die UI von 2026 her, setzt FSRS als Default — und importiert deine + bestehenden Anki-Decks in 30 Sekunden. +

+
+ + + + +
    +
  • Keine Streak-Manipulation. Kein „du hast deine 47-Tage-Serie gebrochen"-Schmerz-Theater.
  • +
  • Kein Algorithmus-Feed. Keine „Empfohlene Decks"-Endlos-Liste.
  • +
  • Keine Werbung, kein Tracker. Auch nicht „nativ", auch nicht „kuratiert".
  • +
  • Kein Lock-in. Export nach Anki-Format jederzeit.
  • +
  • Kein Exit-Risiko. Wordeck gehört dem Verein — kein Käufer kann es abschalten.
  • +
+
+ + +

+ Wordeck ist ein Projekt von mana e.V. — + Schweizer Verein in Gründung. Wir bauen 16 gemeinnützige Software-Werkzeuge + (Lesen, Lernen, Aufschreiben, Pflanzen, Spuren). Finanziert über + Mitgliedsbeiträge und einen + Selbstkostenpreis-Tarif für optionale + KI-Funktionen. +

+

+ Wordeck-Basis ist und bleibt kostenlos. Marketplace-Decks sind unter + freien Lizenzen (CC0, CC-BY-4.0) — du darfst kopieren, in deinen + Unterricht einbauen, weiterverwenden. +

+
+ + + + +
diff --git a/apps/landing/src/pages/llms.txt.ts b/apps/landing/src/pages/llms.txt.ts new file mode 100644 index 0000000..cf75c39 --- /dev/null +++ b/apps/landing/src/pages/llms.txt.ts @@ -0,0 +1,42 @@ +import type { APIRoute } from 'astro' +import { llmsTxt } from '@mana/marketing-kit' +import { app } from '../lib/app.js' + +// llms.txt für wordeck. Ziel: wenn jemand „Anki-Alternative" oder +// „karteikarten app open source" fragt, soll der AI-Assistent +// Wordeck finden — samt Anki-Import-Pfad und FSRS-Hinweis. +export const GET: APIRoute = () => { + const body = llmsTxt({ + app, + what: + 'Spaced-Repetition-Karteikarten-App mit FSRS-Scheduler. Anki-Deck-Import (.apkg) inkl. Cloze. Vereinsgetragen, Web + iOS, kostenlos.', + allmende: [ + '3 Marketplace-Decks (648 Karten) unter CC0 / CC-BY-4.0', + 'Anki-Import: .apkg-Pakete inkl. Cloze-Notes, Tags, optional Reviews-Historie', + 'Export zurück nach Anki-kompatiblem Format jederzeit (kein Lock-in)', + 'Source-Code auf https://git.mana.how/till/wordeck', + ], + additionalSections: [ + { + title: 'Wichtige Marketing-Seiten', + items: [ + { label: 'Anki-Import (Schritt-für-Schritt)', href: 'https://wordeck.com/anki-import' }, + { label: 'Über Wordeck (FSRS + Verein)', href: 'https://wordeck.com/ueber' }, + { label: 'Mitwirken', href: 'https://wordeck.com/mitwirken' }, + ], + }, + { + title: 'App', + items: [ + { label: 'App öffnen', href: `https://${app.appDomain}/` }, + { label: 'Marketplace', href: `https://${app.appDomain}/marketplace` }, + { label: 'Anki-Import (direkt)', href: `https://${app.appDomain}/import` }, + ], + }, + ], + }) + + return new Response(body, { + headers: { 'Content-Type': 'text/plain; charset=utf-8' }, + }) +} diff --git a/apps/landing/src/pages/mitwirken.astro b/apps/landing/src/pages/mitwirken.astro new file mode 100644 index 0000000..65d686e --- /dev/null +++ b/apps/landing/src/pages/mitwirken.astro @@ -0,0 +1,62 @@ +--- +import AppLanding from '@mana/marketing-kit/layouts/AppLanding.astro' +import StorySection from '@mana/marketing-kit/components/StorySection.astro' +import CTABanner from '@mana/marketing-kit/components/CTABanner.astro' +import { buildSeo } from '@mana/marketing-kit' +import { app } from '../lib/app.js' + +const seo = buildSeo(app, { + path: '/mitwirken', + title: 'Mitwirken bei Wordeck — Decks veröffentlichen, Code, Verein', + description: + 'Drei Wege: eigene Decks im Marketplace veröffentlichen, Code-Beiträge auf git.mana.how, Vereinsmitgliedschaft.', +}) +--- + + + +

+ Wordeck wächst, wenn Menschen Decks teilen und Code beitragen. Drei + Ebenen, keine zwingt zur anderen. +

+
+ + +

+ Wenn du ein gutes Deck gebaut hast (Vokabeln, Anatomie, Code-Snippets, + Botanik, was auch immer): teile es im Wordeck-Marketplace, mit + Lizenz-Wahl beim Publish (CC0, CC-BY-4.0 empfohlen). Reviewer-Stop + vorher — wir prüfen Atomicity, Source-Coverage, kein Spam. +

+
+ + +

+ Quellcode auf git.mana.how/till/wordeck. + SvelteKit-Frontend, Hono+Bun-API, Drizzle/Postgres, FSRS in pure-TS. + Konventionen im + CLAUDE.md. +

+

+ Besonders willkommen: FSRS-Optimizer-Verbesserungen, + Marketplace-Curation, i18n (heute DE/EN, FR/IT/ES für Vereins-Sprachen + ergänzen). +

+
+ + +

+ mana e.V. nimmt Fördermitglieder auf — der strukturellste Weg, + Wordeck plus die anderen 15 Apps zu tragen. + Mitgliedschafts-Infos. +

+
+ + +
diff --git a/apps/landing/src/pages/robots.txt.ts b/apps/landing/src/pages/robots.txt.ts new file mode 100644 index 0000000..129a256 --- /dev/null +++ b/apps/landing/src/pages/robots.txt.ts @@ -0,0 +1,8 @@ +import type { APIRoute } from 'astro' +import { robotsTxt } from '@mana/marketing-kit' +import { app } from '../lib/app.js' + +export const GET: APIRoute = () => + new Response(robotsTxt(app), { + headers: { 'Content-Type': 'text/plain; charset=utf-8' }, + }) diff --git a/apps/landing/src/pages/sitemap.xml.ts b/apps/landing/src/pages/sitemap.xml.ts new file mode 100644 index 0000000..f4a0352 --- /dev/null +++ b/apps/landing/src/pages/sitemap.xml.ts @@ -0,0 +1,19 @@ +import type { APIRoute } from 'astro' +import { sitemapXml } from '@mana/marketing-kit' +import { app } from '../lib/app.js' + +export const GET: APIRoute = () => { + const today = new Date().toISOString().slice(0, 10) + const body = sitemapXml(app, [ + { path: '/', lastmod: today, changefreq: 'weekly', priority: 1.0 }, + // anki-import bewusst hohe Priorität — Akquise-Page für + // „anki alternative" Long-Tail. + { path: '/anki-import', lastmod: today, changefreq: 'weekly', priority: 0.95 }, + { path: '/ueber', lastmod: today, changefreq: 'monthly', priority: 0.8 }, + { path: '/mitwirken', lastmod: today, changefreq: 'monthly', priority: 0.7 }, + ]) + + return new Response(body, { + headers: { 'Content-Type': 'application/xml; charset=utf-8' }, + }) +} diff --git a/apps/landing/src/pages/ueber.astro b/apps/landing/src/pages/ueber.astro new file mode 100644 index 0000000..3754289 --- /dev/null +++ b/apps/landing/src/pages/ueber.astro @@ -0,0 +1,82 @@ +--- +import AppLanding from '@mana/marketing-kit/layouts/AppLanding.astro' +import StorySection from '@mana/marketing-kit/components/StorySection.astro' +import CTABanner from '@mana/marketing-kit/components/CTABanner.astro' +import { buildSeo } from '@mana/marketing-kit' +import { app } from '../lib/app.js' + +const seo = buildSeo(app, { + path: '/ueber', + title: 'Über Wordeck — Verein, FSRS, Marketplace', + description: + 'Hintergrund: warum FSRS statt SM-2, was die Marketplace-Decks bedeuten, warum Wordeck vereinsgetragen ist.', +}) +--- + + + +

+ Spaced Repetition gibt es seit den 1970ern. Anki seit 2006. Die + Methode ist nicht das Problem — das Werkzeug ist es. Anki ist + mächtig, aber die Mobile-Variante kostet 25€ und die UI ist + zwei Jahrzehnte alt. Quizlet hat sich in eine SaaS-Falle + gepivotiert. Mochi und RemNote sind gut, aber Lock-in. +

+

+ Wordeck nimmt das, was an Anki gut ist (SRS, Decks, Cloze, .apkg + als de-facto-Format) und kombiniert es mit dem, was bei den anderen + gut ist (UI von 2026, Mobile-First, kostenlos). Plus: FSRS als + Default, weil der Algorithmus empirisch besser ist. +

+
+ + +

+ Anki hat FSRS seit 2024 als Opt-in. Die meisten User wissen davon + nicht und bleiben auf SM-2 (Default). Das ist eine UX-Wahl, kein + technischer Engpass. +

+

+ Wordeck ist FSRS-only — kein „du musst es in den Settings + aktivieren". Der Scheduler kalibriert sich nach ~1000 Reviews auf + deine persönliche Vergessens-Kurve. Bis dahin laufen sinnvolle + Defaults. +

+
+ + +

+ Wordeck startet nicht leer. Drei kuratierte Decks (648 Karten gesamt) + sind ab Tag-1 verfügbar — unter CC0 oder CC-BY-4.0, also frei + weiterverwendbar. Eigene Decks kannst du im Marketplace teilen, mit + Lizenz-Auswahl beim Publish. +

+

+ Wachstum kommt über Mitwirkende — der Marketplace ist Allmende, + nicht Plattform-Lock-in. +

+
+ + +

+ Hinter Wordeck steht mana e.V. Wir + bauen 16 gemeinnützige Software-Werkzeuge, finanziert über + Mitgliedsbeiträge und Selbstkostenpreis-Mana-Tarif für KI-Aktionen. + Wordeck-Basis ist und bleibt kostenlos; optionale KI-Funktionen + („Karten aus Text generieren") sind transparent bepreist. +

+

+ Mission und Werte · + Quartalsberichte · + Quellcode +

+
+ + +
diff --git a/apps/landing/tsconfig.json b/apps/landing/tsconfig.json new file mode 100644 index 0000000..895c62e --- /dev/null +++ b/apps/landing/tsconfig.json @@ -0,0 +1,4 @@ +{ + "extends": "astro/tsconfigs/strict", + "include": ["src/**/*", "astro.config.mjs"] +}