chore: stale Cardecky-Refs entfernt + apps/landing/ gelöscht
Some checks are pending
CI / validate (push) Waiting to run
Some checks are pending
CI / validate (push) Waiting to run
- apps/landing/ entfernt (Cardecky-Marketing-Astro-Site, war nie deployed — der nginx-Block in landings.conf zeigte auf einen Pfad ohne Inhalt) - Stale Doc-Kommentare in api+web: Cardecky → Wordeck wo passend - fsrs.ts subIndexCount: image-occlusion + audio-front Cases raus (CardType-Enum hat sie nicht mehr — der throw wäre toter Code) - fork.ts: image-occlusion-Sonderfall in subIndexCountFor weg - cards-domain tests: schemas-Test prüft jetzt Wordeck-Typen + dass image-occlusion/audio-front ABGELEHNT werden - cards-domain tests: image-occlusion-throw-Test entfernt - api tests/cards.test.ts: 3 image-occlusion-Cases zu 1 negative Tested (422 expected, weil Schema sie verbietet) 51 Tests grün (cards-domain). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
9b37243b1d
commit
c77100e85a
33 changed files with 13 additions and 2348 deletions
|
|
@ -15,7 +15,7 @@
|
|||
*
|
||||
* Fail-open im Original: bei mana-llm-Ausfall wurde `flag` gesetzt,
|
||||
* damit ein menschlicher Reviewer es trotzdem sieht. Solange wir nur
|
||||
* Cardecky-Decks publishen, ist der Stub `pass` ausreichend — Cardecky
|
||||
* Wordeck-Decks publishen, ist der Stub `pass` ausreichend — Wordeck
|
||||
* ist eine kuratierte Identität.
|
||||
*/
|
||||
|
||||
|
|
|
|||
|
|
@ -146,11 +146,6 @@ export async function forkDeckForUser(
|
|||
|
||||
function subIndexCountFor(type: string, fields: Record<string, string>): number {
|
||||
if (type === 'cloze') return subIndexCountForCloze(fields.text ?? '');
|
||||
if (type === 'image-occlusion') {
|
||||
// image-occlusion hat dynamische subIndexes via mask_regions —
|
||||
// im Marketplace-Fork bisher nicht unterstützt. Default 1.
|
||||
return 1;
|
||||
}
|
||||
return subIndexCount(type);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ import { authorBlocks, authors, deckReports, publicDecks } from '../../db/schema
|
|||
|
||||
/**
|
||||
* Moderation-Endpoints — App-Review-Pflicht für User-Generated-Content
|
||||
* (App-Store-Guideline 5.1.1(v)). Aus Cardecky-Native erreichbar als
|
||||
* (App-Store-Guideline 5.1.1(v)). Aus Wordeck-Native erreichbar als
|
||||
* „Melden" und „Author blockieren".
|
||||
*
|
||||
* - `POST /decks/:slug/report` — Meldung zu einem Deck. Idempotent
|
||||
|
|
|
|||
|
|
@ -75,7 +75,7 @@ describe('cardsRouter — Input-Validation', () => {
|
|||
expect(res.status).toBe(422);
|
||||
});
|
||||
|
||||
it('POST mit image-occlusion ohne mask_regions ist 422', async () => {
|
||||
it('POST mit image-occlusion ist 422 (CardType nicht mehr akzeptiert)', async () => {
|
||||
const { app } = buildApp();
|
||||
const res = await app.request('/api/v1/cards', {
|
||||
method: 'POST',
|
||||
|
|
@ -83,49 +83,12 @@ describe('cardsRouter — Input-Validation', () => {
|
|||
body: JSON.stringify({
|
||||
deck_id: 'd-1',
|
||||
type: 'image-occlusion',
|
||||
fields: { image_ref: 'm1' },
|
||||
fields: { image_ref: 'm1', mask_regions: '[]' },
|
||||
}),
|
||||
});
|
||||
expect(res.status).toBe(422);
|
||||
});
|
||||
|
||||
it('POST mit image-occlusion mit kaputtem mask_regions ist 422', async () => {
|
||||
const { app } = buildApp();
|
||||
const res = await app.request('/api/v1/cards', {
|
||||
method: 'POST',
|
||||
headers: { 'X-User-Id': 'u-1', 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({
|
||||
deck_id: 'd-1',
|
||||
type: 'image-occlusion',
|
||||
fields: { image_ref: 'm1', mask_regions: 'not json' },
|
||||
}),
|
||||
});
|
||||
expect(res.status).toBe(422);
|
||||
const body = (await res.json()) as { issues: string[] };
|
||||
expect(body.issues[0]).toMatch(/mask_regions/);
|
||||
});
|
||||
|
||||
it('POST mit gültiger image-occlusion erreicht Deck-Lookup (404 bei stub)', async () => {
|
||||
const { app } = buildApp();
|
||||
const res = await app.request('/api/v1/cards', {
|
||||
method: 'POST',
|
||||
headers: { 'X-User-Id': 'u-1', 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({
|
||||
deck_id: 'd-1',
|
||||
type: 'image-occlusion',
|
||||
fields: {
|
||||
image_ref: 'm1',
|
||||
mask_regions: JSON.stringify([
|
||||
{ id: 'r1', x: 0.1, y: 0.1, w: 0.1, h: 0.1 },
|
||||
]),
|
||||
},
|
||||
}),
|
||||
});
|
||||
expect(res.status).toBe(404);
|
||||
const body = (await res.json()) as { error: string };
|
||||
expect(body.error).toBe('deck_not_found');
|
||||
});
|
||||
|
||||
it('POST mit cloze-Card ohne text-Feld ist 422', async () => {
|
||||
const { app } = buildApp();
|
||||
const res = await app.request('/api/v1/cards', {
|
||||
|
|
|
|||
|
|
@ -1,12 +0,0 @@
|
|||
import { defineConfig } from 'astro/config';
|
||||
import tailwind from '@astrojs/tailwind';
|
||||
import sitemap from '@astrojs/sitemap';
|
||||
|
||||
export default defineConfig({
|
||||
site: 'https://cardecky.mana.how',
|
||||
integrations: [
|
||||
tailwind({ applyBaseStyles: false }),
|
||||
sitemap(),
|
||||
],
|
||||
output: 'static',
|
||||
});
|
||||
|
|
@ -1,21 +0,0 @@
|
|||
{
|
||||
"name": "@cards/landing",
|
||||
"type": "module",
|
||||
"version": "0.1.0",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"dev": "astro dev --port 4380",
|
||||
"build": "astro build",
|
||||
"preview": "astro preview --port 4380",
|
||||
"astro": "astro"
|
||||
},
|
||||
"dependencies": {
|
||||
"astro": "^5.8.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@astrojs/tailwind": "^6.0.2",
|
||||
"@astrojs/sitemap": "^3.4.1",
|
||||
"tailwindcss": "^3.4.17",
|
||||
"typescript": "^5.8.3"
|
||||
}
|
||||
}
|
||||
|
|
@ -1,4 +0,0 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32" fill="none">
|
||||
<rect x="2" y="6" width="18" height="14" rx="3" stroke="#16a34a" stroke-width="2.5"/>
|
||||
<rect x="12" y="12" width="18" height="14" rx="3" fill="white" stroke="#16a34a" stroke-width="2.5"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 271 B |
|
|
@ -1,75 +0,0 @@
|
|||
---
|
||||
const posts = [
|
||||
{
|
||||
href: '/blog/quizlet-paywall',
|
||||
tag: 'Migration',
|
||||
title: 'Quizlet zieht die Paywall hoch — was jetzt?',
|
||||
summary:
|
||||
'Fünf Millionen Nutzer:innen haben Quizlet in den letzten zwei Jahren verlassen. Was hinter der Bezahlschranke steckt und wie der Wechsel zu Cardecky in wenigen Minuten klappt.',
|
||||
},
|
||||
{
|
||||
href: '/blog/fsrs-algorithmus',
|
||||
tag: 'Algorithmus',
|
||||
title: 'Weniger lernen, mehr behalten: Was FSRS bedeutet',
|
||||
summary:
|
||||
'FSRS reduziert die nötigen Wiederholungen um 20–30 % bei gleicher Retention. Wie der Algorithmus funktioniert — und warum er bei anderen Apps noch nicht der Standard ist.',
|
||||
},
|
||||
{
|
||||
href: '/blog/deine-daten',
|
||||
tag: 'Datenschutz',
|
||||
title: 'Deine Karten, deine Daten',
|
||||
summary:
|
||||
'Lerndaten verraten mehr als die meisten ahnen. Was Cardecky damit macht — und was nicht — lässt sich im öffentlichen Quellcode nachprüfen.',
|
||||
},
|
||||
{
|
||||
href: '/blog/anki-zu-kompliziert',
|
||||
tag: 'Vergleich',
|
||||
title: 'Anki ist mächtig — und trotzdem schwer empfehlbar',
|
||||
summary:
|
||||
'Anki ist technisch überlegen. Trotzdem hören die meisten Nutzer:innen auf — nicht wegen des Algorithmus, sondern wegen Interface und Lernkurve.',
|
||||
},
|
||||
{
|
||||
href: '/blog/gute-lernkarten',
|
||||
tag: 'Lernen',
|
||||
title: 'Wie man Lernkarten schreibt, die wirklich funktionieren',
|
||||
summary:
|
||||
'Der beste Algorithmus nützt nichts, wenn die Karten schlecht gebaut sind. Fünf Prinzipien — mit Gegenbeispielen.',
|
||||
},
|
||||
] as const;
|
||||
---
|
||||
|
||||
<section class="border-b border-rule py-20 sm:py-28">
|
||||
<div class="mx-auto max-w-content px-6">
|
||||
<p class="section-label">Artikel</p>
|
||||
<h2 class="mt-3 font-serif text-display text-ink">Hintergrund & Methodik.</h2>
|
||||
<p class="mt-4 max-w-prose text-muted">
|
||||
Warum Spaced Repetition funktioniert, was die Konkurrenz falsch macht — und wie man
|
||||
Karten baut, die das Gehirn tatsächlich behält.
|
||||
</p>
|
||||
|
||||
<ul class="mt-12 grid gap-6 sm:grid-cols-2 lg:grid-cols-3" role="list">
|
||||
{posts.map((post) => (
|
||||
<li>
|
||||
<a
|
||||
href={post.href}
|
||||
class="group flex h-full flex-col rounded-xl border border-rule bg-paper p-6 transition-shadow hover:shadow-md"
|
||||
>
|
||||
<span class="section-label mb-3 inline-block">{post.tag}</span>
|
||||
<p class="font-serif text-lg font-semibold leading-snug text-ink group-hover:text-leaf transition-colors">
|
||||
{post.title}
|
||||
</p>
|
||||
<p class="mt-3 flex-1 text-sm leading-relaxed text-muted">
|
||||
{post.summary}
|
||||
</p>
|
||||
<span class="mt-5 inline-flex items-center gap-1 text-sm font-medium text-leaf">
|
||||
Lesen
|
||||
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true">
|
||||
<path d="M5 12h14M12 5l7 7-7 7"/>
|
||||
</svg>
|
||||
</span>
|
||||
</a>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
</section>
|
||||
|
|
@ -1,35 +0,0 @@
|
|||
---
|
||||
const APP_URL = 'https://cardecky.mana.how';
|
||||
---
|
||||
<section class="border-b border-rule bg-leaf py-20 sm:py-24">
|
||||
<div class="mx-auto max-w-content px-6 text-center">
|
||||
<h2 class="font-serif text-display text-white">
|
||||
Bereit, das Lernen neu zu denken?
|
||||
</h2>
|
||||
<p class="mt-4 text-lg text-white/80">
|
||||
Cardecky ist kostenlos. Keine Kreditkarte, keine versteckten Kosten.
|
||||
</p>
|
||||
<div class="mt-10 flex flex-wrap justify-center gap-4">
|
||||
<a
|
||||
href={APP_URL}
|
||||
class="inline-flex items-center gap-2 rounded-lg bg-white px-6 py-3 font-medium text-leaf transition-colors hover:bg-white/90"
|
||||
>
|
||||
Jetzt starten
|
||||
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true">
|
||||
<path d="M5 12h14M12 5l7 7-7 7"/>
|
||||
</svg>
|
||||
</a>
|
||||
<a
|
||||
href="https://git.mana.how/mana/cards"
|
||||
target="_blank"
|
||||
rel="noopener"
|
||||
class="inline-flex items-center gap-2 rounded-lg border border-white/30 px-6 py-3 font-medium text-white transition-colors hover:border-white/60 hover:bg-white/10"
|
||||
>
|
||||
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true">
|
||||
<path d="M9 19c-5 1.5-5-2.5-7-3m14 6v-3.87a3.37 3.37 0 0 0-.94-2.61c3.14-.35 6.44-1.54 6.44-7A5.44 5.44 0 0 0 20 4.77 5.07 5.07 0 0 0 19.91 1S18.73.65 16 2.48a13.38 13.38 0 0 0-7 0C6.27.65 5.09 1 5.09 1A5.07 5.07 0 0 0 5 4.77a5.44 5.44 0 0 0-1.5 3.78c0 5.42 3.3 6.61 6.44 7A3.37 3.37 0 0 0 9 18.13V22"/>
|
||||
</svg>
|
||||
Quellcode ansehen
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
|
@ -1,74 +0,0 @@
|
|||
---
|
||||
const types = [
|
||||
{
|
||||
name: 'Klassisch',
|
||||
tag: 'basic',
|
||||
icon: `<svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75"><rect x="3" y="5" width="18" height="14" rx="2"/><path d="M3 10h18"/></svg>`,
|
||||
desc: 'Vorderseite und Rückseite. Der Klassiker — simpel, bewährt, effektiv für einfache Fakten.',
|
||||
},
|
||||
{
|
||||
name: 'Multiple Choice',
|
||||
tag: 'multiple-choice',
|
||||
icon: `<svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75"><circle cx="12" cy="12" r="9"/><path d="M12 8v4l3 3"/></svg>`,
|
||||
desc: 'Vier Antwortoptionen zur Auswahl. Fehlende Distractors generiert das System automatisch aus dem Deck.',
|
||||
highlight: true,
|
||||
},
|
||||
{
|
||||
name: 'Lückentext',
|
||||
tag: 'cloze',
|
||||
icon: `<svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75"><path d="M4 6h16M4 12h8M4 18h12"/><rect x="13" y="10" width="7" height="4" rx="1" fill="currentColor" opacity=".15" stroke="currentColor"/></svg>`,
|
||||
desc: 'Text mit {{c1::Lücken}} — jeder markierte Cluster wird als eigene Karte abgefragt.',
|
||||
},
|
||||
{
|
||||
name: 'Bild-Okklusion',
|
||||
tag: 'image-occlusion',
|
||||
icon: `<svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75"><rect x="3" y="3" width="18" height="18" rx="2"/><circle cx="8.5" cy="8.5" r="1.5" fill="currentColor"/><path d="m21 15-5-5L5 21"/><rect x="11" y="10" width="7" height="5" rx="1" fill="currentColor" opacity=".2" stroke="currentColor"/></svg>`,
|
||||
desc: 'Bereiche auf einem Bild ausblenden — ideal für Anatomie, Landkarten, Diagramme.',
|
||||
},
|
||||
{
|
||||
name: 'Tippen',
|
||||
tag: 'typing',
|
||||
icon: `<svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75"><rect x="2" y="7" width="20" height="12" rx="2"/><path d="M8 11h.01M12 11h.01M16 11h.01M8 15h8"/></svg>`,
|
||||
desc: 'Die Antwort eintippen statt nur aufzudecken. Fuzzy-Match verzeiht kleine Tippfehler.',
|
||||
},
|
||||
{
|
||||
name: 'Audio',
|
||||
tag: 'audio-front',
|
||||
icon: `<svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75"><path d="M12 1a3 3 0 0 0-3 3v8a3 3 0 0 0 6 0V4a3 3 0 0 0-3-3z"/><path d="M19 10v2a7 7 0 0 1-14 0v-2M12 19v4M8 23h8"/></svg>`,
|
||||
desc: 'Audioclip als Prompt — perfekt für Sprachlernen, Vokabeln und Aussprache-Training.',
|
||||
},
|
||||
] as const;
|
||||
---
|
||||
<section id="kartentypen" class="border-b border-rule py-20 sm:py-28">
|
||||
<div class="mx-auto max-w-content px-6">
|
||||
<p class="section-label">Kartentypen</p>
|
||||
<h2 class="mt-3 font-serif text-display text-ink">Sechs Formate, ein System.</h2>
|
||||
<p class="mt-4 max-w-prose text-muted">
|
||||
Nicht jedes Wissen lässt sich gleich lernen. Cardecky hat für jeden Lerninhalt den richtigen
|
||||
Kartentyp — alle im gleichen Deck, alle mit FSRS-Scheduling.
|
||||
</p>
|
||||
|
||||
<div class="mt-12 grid gap-4 sm:grid-cols-2 lg:grid-cols-3">
|
||||
{types.map((type) => (
|
||||
<div class:list={[
|
||||
'group rounded-xl border p-6 transition-all',
|
||||
type.highlight
|
||||
? 'border-leaf-border bg-leaf-light'
|
||||
: 'border-rule bg-white hover:border-leaf-border hover:bg-leaf-light/40'
|
||||
]}>
|
||||
<div class:list={[
|
||||
'mb-4 inline-flex rounded-lg p-2',
|
||||
type.highlight ? 'bg-leaf/10 text-leaf' : 'bg-rule text-muted group-hover:bg-leaf/10 group-hover:text-leaf'
|
||||
]}>
|
||||
<Fragment set:html={type.icon} />
|
||||
</div>
|
||||
<div class="mb-1 flex items-center gap-2">
|
||||
<h3 class="font-medium text-ink">{type.name}</h3>
|
||||
<code class="rounded bg-rule px-1.5 py-0.5 text-xs text-muted">{type.tag}</code>
|
||||
</div>
|
||||
<p class="text-sm leading-relaxed text-muted">{type.desc}</p>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
|
@ -1,57 +0,0 @@
|
|||
---
|
||||
const features = [
|
||||
{
|
||||
icon: `<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75"><path d="M9 19c-5 1.5-5-2.5-7-3m14 6v-3.87a3.37 3.37 0 0 0-.94-2.61c3.14-.35 6.44-1.54 6.44-7A5.44 5.44 0 0 0 20 4.77 5.07 5.07 0 0 0 19.91 1S18.73.65 16 2.48a13.38 13.38 0 0 0-7 0C6.27.65 5.09 1 5.09 1A5.07 5.07 0 0 0 5 4.77a5.44 5.44 0 0 0-1.5 3.78c0 5.42 3.3 6.61 6.44 7A3.37 3.37 0 0 0 9 18.13V22"/></svg>`,
|
||||
title: 'Open Source',
|
||||
body: 'Der gesamte Quellcode liegt offen auf Forgejo. Keine Blackbox, kein Vendor-Lock-in.',
|
||||
},
|
||||
{
|
||||
icon: `<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75"><path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z"/></svg>`,
|
||||
title: 'Datensouveränität',
|
||||
body: 'Deine Daten liegen auf mana-Infrastruktur in Europa. Kein Google, kein AWS, keine Datenhändler.',
|
||||
},
|
||||
{
|
||||
icon: `<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75"><polyline points="22 12 18 12 15 21 9 3 6 12 2 12"/></svg>`,
|
||||
title: 'FSRS-Algorithmus',
|
||||
body: 'Free Spaced Repetition Scheduler — nachweislich effektiver als SM-2, das Herzstück von Anki.',
|
||||
},
|
||||
{
|
||||
icon: `<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/><polyline points="17 8 12 3 7 8"/><line x1="12" y1="3" x2="12" y2="15"/></svg>`,
|
||||
title: 'Anki-Import',
|
||||
body: '.apkg-Dateien direkt importieren — Vorlagen werden automatisch auf Cardecky-Kartentypen gemappt.',
|
||||
},
|
||||
{
|
||||
icon: `<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75"><rect x="2" y="3" width="20" height="14" rx="2"/><path d="M8 21h8M12 17v4"/></svg>`,
|
||||
title: 'Öffentliche Bibliothek',
|
||||
body: 'Kuratierte Decks zu Periodensystem, Geografie, Sprachen, Philosophie und mehr — ein Klick zum Start.',
|
||||
},
|
||||
{
|
||||
icon: `<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75"><circle cx="12" cy="12" r="10"/><line x1="2" y1="12" x2="22" y2="12"/><path d="M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z"/></svg>`,
|
||||
title: 'Föderiert im mana-Ökosystem',
|
||||
body: 'Cardecky teilt Identität und Credits mit den anderen mana-Apps — ein Login, eine Community.',
|
||||
},
|
||||
] as const;
|
||||
---
|
||||
<section id="funktionen" class="border-b border-rule py-20 sm:py-28">
|
||||
<div class="mx-auto max-w-content px-6">
|
||||
<p class="section-label">Funktionen</p>
|
||||
<h2 class="mt-3 font-serif text-display text-ink">Gebaut für ernsthaftes Lernen.</h2>
|
||||
<p class="mt-4 max-w-prose text-muted">
|
||||
Kein Feature-Bloat. Nur was du brauchst, um Wissen dauerhaft zu verankern.
|
||||
</p>
|
||||
|
||||
<div class="mt-12 grid gap-8 sm:grid-cols-2 lg:grid-cols-3">
|
||||
{features.map((f) => (
|
||||
<div class="flex gap-4">
|
||||
<div class="mt-0.5 flex-shrink-0 text-leaf">
|
||||
<Fragment set:html={f.icon} />
|
||||
</div>
|
||||
<div>
|
||||
<h3 class="font-semibold text-ink">{f.title}</h3>
|
||||
<p class="mt-1 text-sm leading-relaxed text-muted">{f.body}</p>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
|
@ -1,51 +0,0 @@
|
|||
---
|
||||
const year = new Date().getFullYear();
|
||||
---
|
||||
<footer class="bg-ink py-12 text-white/60">
|
||||
<div class="mx-auto max-w-content px-6">
|
||||
<div class="grid gap-8 sm:grid-cols-2 lg:grid-cols-4">
|
||||
<div>
|
||||
<p class="font-serif text-base font-semibold text-white">Cardecky</p>
|
||||
<p class="mt-2 text-sm leading-relaxed">
|
||||
Spaced-Repetition-App des mana e.V.<br/>
|
||||
Freie Software für freie Menschen.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<p class="text-xs font-semibold uppercase tracking-widest text-white/40">App</p>
|
||||
<ul class="mt-3 space-y-2 text-sm">
|
||||
<li><a href="https://cardecky.mana.how" class="hover:text-white transition-colors">Zur App</a></li>
|
||||
<li><a href="https://cardecky.mana.how/decks" class="hover:text-white transition-colors">Bibliothek</a></li>
|
||||
<li><a href="https://cardecky.mana.how/study" class="hover:text-white transition-colors">Lernen</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<p class="text-xs font-semibold uppercase tracking-widest text-white/40">Artikel</p>
|
||||
<ul class="mt-3 space-y-2 text-sm">
|
||||
<li><a href="/blog/quizlet-paywall" class="hover:text-white transition-colors">Quizlet-Alternative</a></li>
|
||||
<li><a href="/blog/fsrs-algorithmus" class="hover:text-white transition-colors">Was ist FSRS?</a></li>
|
||||
<li><a href="/blog/deine-daten" class="hover:text-white transition-colors">Deine Daten</a></li>
|
||||
<li><a href="/blog/anki-zu-kompliziert" class="hover:text-white transition-colors">Anki vs. Cardecky</a></li>
|
||||
<li><a href="/blog/gute-lernkarten" class="hover:text-white transition-colors">Gute Lernkarten</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<p class="text-xs font-semibold uppercase tracking-widest text-white/40">Verein</p>
|
||||
<ul class="mt-3 space-y-2 text-sm">
|
||||
<li><a href="https://mana-ev.ch" class="hover:text-white transition-colors" target="_blank" rel="noopener">mana e.V.</a></li>
|
||||
<li><a href="https://mana-ev.ch#mitglied" class="hover:text-white transition-colors" target="_blank" rel="noopener">Mitglied werden</a></li>
|
||||
<li><a href="https://git.mana.how/mana/cards" class="hover:text-white transition-colors" target="_blank" rel="noopener">Quellcode</a></li>
|
||||
<li><a href="https://mana-ev.ch/datenschutz" class="hover:text-white transition-colors" target="_blank" rel="noopener">Datenschutz</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mt-10 border-t border-white/10 pt-6 text-xs">
|
||||
© {year} mana e.V. · Cardecky ist freie Software (AGPL-3.0) ·
|
||||
<a href="https://mana-ev.ch" class="hover:text-white transition-colors">mana-ev.ch</a>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
|
|
@ -1,43 +0,0 @@
|
|||
---
|
||||
const APP_URL = 'https://cardecky.mana.how';
|
||||
---
|
||||
<section class="relative overflow-hidden border-b border-rule bg-paper py-24 sm:py-32">
|
||||
<!-- Subtle grid background -->
|
||||
<div
|
||||
class="pointer-events-none absolute inset-0 opacity-[0.03]"
|
||||
style="background-image: linear-gradient(#111812 1px, transparent 1px), linear-gradient(90deg, #111812 1px, transparent 1px); background-size: 48px 48px;"
|
||||
aria-hidden="true"
|
||||
></div>
|
||||
|
||||
<div class="relative mx-auto max-w-content px-6">
|
||||
<div class="max-w-prose">
|
||||
<p class="section-label mb-4">Spaced Repetition · mana e.V.</p>
|
||||
|
||||
<h1 class="font-serif text-hero text-ink">
|
||||
Lernkarten, die<br/>
|
||||
<span class="text-leaf">tatsächlich wirken.</span>
|
||||
</h1>
|
||||
|
||||
<p class="mt-6 text-lg leading-relaxed text-muted">
|
||||
Cardecky nutzt den FSRS-Algorithmus — den aktuellen Stand der Wissenschaft im Spaced
|
||||
Repetition — um dir jede Karte genau dann zu zeigen, wenn du sie kurz vor dem Vergessen bist.
|
||||
Keine Abos, keine Tracker, keine dark patterns.
|
||||
Freie Software des <a href="https://mana-ev.ch" class="underline underline-offset-2 hover:text-ink transition-colors">mana e.V.</a>
|
||||
</p>
|
||||
|
||||
<div class="mt-10 flex flex-wrap items-center gap-4">
|
||||
<a href={APP_URL} class="btn-primary">
|
||||
Kostenlos starten
|
||||
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true">
|
||||
<path d="M5 12h14M12 5l7 7-7 7"/>
|
||||
</svg>
|
||||
</a>
|
||||
<a href="#kartentypen" class="btn-ghost">Alle Kartentypen ansehen</a>
|
||||
</div>
|
||||
|
||||
<p class="mt-6 text-xs text-muted">
|
||||
Kein Account erforderlich für den ersten Blick · DSGVO-konform · Open Source
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
|
@ -1,35 +0,0 @@
|
|||
---
|
||||
const steps = [
|
||||
{
|
||||
n: '01',
|
||||
title: 'Deck erstellen oder importieren',
|
||||
body: 'Leg ein neues Deck an und füge Karten über das Web-Interface hinzu — oder importiere deine bestehenden Anki-Decks direkt als .apkg-Datei. Decks aus der Bibliothek mit einem Klick übernehmen.',
|
||||
},
|
||||
{
|
||||
n: '02',
|
||||
title: 'Karten anlegen',
|
||||
body: 'Wähle den passenden Kartentyp und füll die Felder aus. Für Multiple-Choice-Karten zieht das System automatisch passende Distractors aus dem restlichen Deck — du gibst nur die richtige Antwort vor.',
|
||||
},
|
||||
{
|
||||
n: '03',
|
||||
title: 'Täglich kurz lernen',
|
||||
body: 'Der FSRS-Algorithmus berechnet für jede Karte den optimalen Wiederholungszeitpunkt. Du bewertest dich selbst (Nochmal / Schwer / Gut / Leicht) — damit kalibriert sich das System auf deinen persönlichen Vergessenskurve.',
|
||||
},
|
||||
] as const;
|
||||
---
|
||||
<section class="border-b border-rule bg-white py-20 sm:py-28">
|
||||
<div class="mx-auto max-w-content px-6">
|
||||
<p class="section-label">So funktioniert's</p>
|
||||
<h2 class="mt-3 font-serif text-display text-ink">In drei Schritten zur täglichen Praxis.</h2>
|
||||
|
||||
<div class="mt-12 grid gap-10 sm:grid-cols-3">
|
||||
{steps.map((s) => (
|
||||
<div>
|
||||
<span class="font-serif text-4xl font-bold text-rule">{s.n}</span>
|
||||
<h3 class="mt-4 font-semibold text-ink">{s.title}</h3>
|
||||
<p class="mt-2 text-sm leading-relaxed text-muted">{s.body}</p>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
|
@ -1,46 +0,0 @@
|
|||
---
|
||||
---
|
||||
<section class="border-b border-rule bg-white py-20 sm:py-24">
|
||||
<div class="mx-auto max-w-content px-6">
|
||||
<div class="grid gap-12 lg:grid-cols-2 lg:items-center">
|
||||
<div>
|
||||
<p class="section-label">mana e.V.</p>
|
||||
<h2 class="mt-3 font-serif text-display text-ink">
|
||||
Software als Gemeingut.
|
||||
</h2>
|
||||
<p class="mt-4 leading-relaxed text-muted">
|
||||
Cardecky ist ein Projekt des <strong class="text-ink">mana e.V.</strong> — einem Schweizer Verein,
|
||||
der digitale Infrastruktur als Gemeingut begreift. Keine Investoren, keine Werbung,
|
||||
kein Daten-Harvesting. Finanziert durch freiwillige Mitgliedsbeiträge.
|
||||
</p>
|
||||
<p class="mt-3 leading-relaxed text-muted">
|
||||
80 % der Einnahmen fließen direkt in den Betrieb der Apps. 10 % in Langlebigkeit
|
||||
und Nachhaltigkeit. 10 % in den Vereinsbetrieb. Transparenz ist kein Marketing —
|
||||
wir veröffentlichen jeden Quartal einen Transparenzbericht.
|
||||
</p>
|
||||
<div class="mt-8 flex flex-wrap gap-4">
|
||||
<a href="https://mana-ev.ch" target="_blank" rel="noopener" class="btn-primary">
|
||||
mana-ev.ch besuchen
|
||||
</a>
|
||||
<a href="https://mana-ev.ch#mitglied" target="_blank" rel="noopener" class="btn-ghost">
|
||||
Mitglied werden
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="grid grid-cols-2 gap-4">
|
||||
{[
|
||||
{ label: 'Open Source', desc: 'Quellcode liegt offen auf git.mana.how' },
|
||||
{ label: 'Kein Tracking', desc: 'Keine Werbung, keine externen Dienste' },
|
||||
{ label: 'Europa', desc: 'Daten auf Infrastruktur in Europa' },
|
||||
{ label: 'Transparent', desc: 'Quartalsbericht zu Finanzen & Betrieb' },
|
||||
].map((item) => (
|
||||
<div class="rounded-xl border border-rule bg-paper p-5">
|
||||
<p class="font-semibold text-ink">{item.label}</p>
|
||||
<p class="mt-1 text-sm text-muted">{item.desc}</p>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
|
@ -1,24 +0,0 @@
|
|||
---
|
||||
const APP_URL = 'https://cardecky.mana.how';
|
||||
---
|
||||
<header class="sticky top-0 z-50 border-b border-rule bg-paper/90 backdrop-blur-sm">
|
||||
<div class="mx-auto flex max-w-content items-center justify-between px-6 py-3">
|
||||
<a href="/" class="flex items-center gap-2 font-serif text-lg font-semibold text-ink">
|
||||
<svg width="22" height="22" viewBox="0 0 24 24" fill="none" aria-hidden="true">
|
||||
<rect x="2" y="4" width="14" height="10" rx="2" stroke="currentColor" stroke-width="1.75" class="text-leaf"/>
|
||||
<rect x="8" y="10" width="14" height="10" rx="2" fill="white" stroke="currentColor" stroke-width="1.75"/>
|
||||
</svg>
|
||||
Cardecky
|
||||
</a>
|
||||
|
||||
<nav class="hidden items-center gap-6 text-sm text-muted sm:flex">
|
||||
<a href="#kartentypen" class="hover:text-ink transition-colors">Kartentypen</a>
|
||||
<a href="#funktionen" class="hover:text-ink transition-colors">Funktionen</a>
|
||||
<a href="https://mana-ev.ch" target="_blank" rel="noopener" class="hover:text-ink transition-colors">mana e.V.</a>
|
||||
</nav>
|
||||
|
||||
<a href={APP_URL} class="btn-primary text-xs py-2 px-4">
|
||||
Zur App →
|
||||
</a>
|
||||
</div>
|
||||
</header>
|
||||
|
|
@ -1,37 +0,0 @@
|
|||
---
|
||||
interface Props {
|
||||
title: string;
|
||||
description: string;
|
||||
ogImage?: string;
|
||||
}
|
||||
const { title, description, ogImage = '/og.png' } = Astro.props;
|
||||
const canonical = new URL(Astro.url.pathname, Astro.site);
|
||||
---
|
||||
<!doctype html>
|
||||
<html lang="de">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
|
||||
<link rel="canonical" href={canonical} />
|
||||
|
||||
<title>{title}</title>
|
||||
<meta name="description" content={description} />
|
||||
|
||||
<!-- Open Graph -->
|
||||
<meta property="og:type" content="website" />
|
||||
<meta property="og:url" content={canonical} />
|
||||
<meta property="og:title" content={title} />
|
||||
<meta property="og:description" content={description} />
|
||||
<meta property="og:image" content={new URL(ogImage, Astro.site)} />
|
||||
|
||||
<!-- Twitter -->
|
||||
<meta name="twitter:card" content="summary_large_image" />
|
||||
<meta name="twitter:title" content={title} />
|
||||
<meta name="twitter:description" content={description} />
|
||||
<meta name="twitter:image" content={new URL(ogImage, Astro.site)} />
|
||||
</head>
|
||||
<body>
|
||||
<slot />
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -1,321 +0,0 @@
|
|||
---
|
||||
import Layout from '../../layouts/Layout.astro';
|
||||
import Nav from '../../components/Nav.astro';
|
||||
import Footer from '../../components/Footer.astro';
|
||||
import '../../styles/base.css';
|
||||
|
||||
const APP_URL = 'https://cardecky.mana.how';
|
||||
const ANKI_IMPORT_URL = 'https://cardecky.mana.how/import';
|
||||
|
||||
const title = 'Anki ist mächtig — und trotzdem schwer empfehlbar | Cardecky';
|
||||
const description =
|
||||
'Anki ist der Goldstandard für Spaced Repetition. Aber die Lernkurve ist brutal, das' +
|
||||
' Interface stammt aus 2006, und einen Freund damit anzufangen ist fast unmöglich. Was' +
|
||||
' Cardecky anders macht.';
|
||||
---
|
||||
|
||||
<Layout {title} {description}>
|
||||
<Nav />
|
||||
|
||||
<main class="mx-auto max-w-prose px-6 py-16 sm:py-24">
|
||||
|
||||
<!-- Artikel-Header -->
|
||||
<header class="mb-12">
|
||||
<p class="section-label mb-4">Vergleich · Anki</p>
|
||||
<h1 class="font-serif text-4xl leading-tight text-ink sm:text-5xl">
|
||||
Anki ist mächtig — und trotzdem schwer empfehlbar
|
||||
</h1>
|
||||
<p class="mt-5 text-lg leading-relaxed text-muted">
|
||||
Anki ist der technisch überlegene Lernkarten-Standard. Die meisten Nutzer:innen scheitern
|
||||
trotzdem — nicht am Algorithmus, sondern am Interface. Was das konkret bedeutet und wo
|
||||
Cardecky ansetzt.
|
||||
</p>
|
||||
<p class="mt-4 text-xs text-muted">Stand: Mai 2026</p>
|
||||
</header>
|
||||
|
||||
<article class="prose-cardecky">
|
||||
|
||||
<!-- 1 -->
|
||||
<h2>Das Paradox: alle wissen, dass es funktioniert</h2>
|
||||
|
||||
<p>
|
||||
Wenn jemand über Lernkarten redet, fällt Anki. Wenn jemand über Spaced Repetition redet,
|
||||
fällt Anki. Medizinstudenten schwören seit Jahren darauf, Sprachenlerner haben ganze
|
||||
Karrieren darauf aufgebaut, und wer tief in der Lernforschung sitzt, kennt die Studie, die
|
||||
die Studie belegt. Anki funktioniert. Das ist nicht strittig.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Und trotzdem kennt fast jeder mindestens eine Person, die Anki angefangen und aufgehört hat.
|
||||
Nicht weil das Lernen nicht funktioniert hat — sondern weil die App selbst im Weg stand. Das
|
||||
ist das Paradox: ein Werkzeug, das technisch unbestritten ist und dessen Nutzer:innen
|
||||
massenweise aussteigen, bevor sie je richtig angefangen haben.
|
||||
</p>
|
||||
|
||||
<!-- 2 -->
|
||||
<h2>Was Anki wirklich kann</h2>
|
||||
|
||||
<p>
|
||||
Es wäre unfair, Anki nur durch den Blick auf seine Schwächen zu beschreiben. Anki ist seit
|
||||
2006 im Aufbau und hat in dieser Zeit eine Tiefe entwickelt, die kein neueres Tool auch nur
|
||||
annähernd erreicht.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Das Add-on-Ökosystem allein ist bemerkenswert: hunderte von Community-Erweiterungen, von
|
||||
automatischer Bildsuche über LaTeX-Rendering bis zu spezialisierten Scheduling-Varianten.
|
||||
Die Community-Deck-Bibliothek im Medizin-Bereich — Zanki, Lightyear und ihre Abkömmlinge
|
||||
— ist jahrelange kollektive Arbeit, die sich schlicht nicht replizieren lässt. Wer Medizin
|
||||
studiert und in dieses Ökosystem einsteigt, bekommt kuratierte, geprüfte, von Tausenden
|
||||
mitgepflegte Decks. Das ist ein realer Wert.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Seit 2024 ist zudem FSRS — Free Spaced Repetition Scheduler — als opt-in in Anki enthalten.
|
||||
FSRS modelliert zwei Gedächtnisparameter pro Karte (Stabilität und Abrufbarkeit) und passt
|
||||
Wiederholungsintervalle präziser an als der ältere SM-2-Algorithmus, auf dem Anki lange
|
||||
fuhr. Wer FSRS in Anki aktiviert, hat Stand 2026 einen der genauesten Scheduling-Algorithmen,
|
||||
die öffentlich verfügbar sind.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Anki ist außerdem Open Source, kostenlos auf Desktop und Android, und wird von einer
|
||||
kleinen Kern-Entwicklergruppe mit bemerkenswerter Kontinuität gepflegt. Das ist keine
|
||||
Selbstverständlichkeit.
|
||||
</p>
|
||||
|
||||
<!-- 3 -->
|
||||
<h2>Warum es trotzdem nicht funktioniert — für die meisten</h2>
|
||||
|
||||
<p>
|
||||
Das Problem ist nicht der Algorithmus. Das Problem ist alles darum herum.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Wer Anki zum ersten Mal öffnet, trifft auf ein Interface, das seit 2006 im Wesentlichen
|
||||
gleich geblieben ist. Das ist kein Vorwurf an die Entwickler:innen — es ist eine
|
||||
Beschreibung der Realität. Decks, Tags, Note-Types, Card-Types, Fields, Templates,
|
||||
Scheduling-Optionen, Add-on-Management: all das erwartet eine Einarbeitungszeit, die in
|
||||
keinem Verhältnis zum eigentlichen Lernziel steht. Wer Vokabeln für die nächste
|
||||
Prüfung lernen will, muss zuerst verstehen, was der Unterschied zwischen einer Note und
|
||||
einer Card ist.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Das „Notes vs. Cards"-Konzept verdient einen eigenen Absatz: Anki speichert Inhalte als
|
||||
„Notes" (das Quell-Datenpaar) und generiert daraus „Cards" (die tatsächlich wiederholten
|
||||
Einheiten). Das ist konzeptionell sauber und erlaubt Dinge wie eine Note, die
|
||||
vorwärts und rückwärts abgefragt wird. Es ist aber auch ein Konzept, das nirgendwo erklärt
|
||||
wird — man stolpert irgendwann hinein. Anfänger:innen glauben oft, sie hätten hundert
|
||||
Karten erstellt, und wundern sich dann, warum die Queue zweihundert Einträge zeigt.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Hinzu kommt die Card-Creation-Tax: Anki hat keine Abkürzungen für das Erstellen von Karten.
|
||||
Alles ist manuell, alles erfordert Entscheidungen über Felder und Vorlagen, bevor
|
||||
überhaupt der erste Inhalt steht. Für jemanden, der gerade mit Lernen anfangen will, ist
|
||||
das eine hohe Hürde. Nicht unüberwindbar, aber hoch genug, dass viele vorher aufhören.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Und dann sind da noch die Einstellungen. Anki bietet eine Einstellung namens „Maximum
|
||||
interval" mit einem Standardwert von „36500" — ohne sichtbare Einheit. 36500 was? Tage,
|
||||
wie sich herausstellt. Das ist charakteristisch für das Interface insgesamt: viel Kontrolle,
|
||||
wenig Kontext.
|
||||
</p>
|
||||
|
||||
<!-- 4 -->
|
||||
<h2>Der iOS-Preis als Zugangsbarriere</h2>
|
||||
|
||||
<p>
|
||||
Anki ist die einzige App im Vergleichsfeld, die auf einer der großen Plattformen Geld
|
||||
kostet: AnkiMobile für iOS ist $24.99. Desktop und Android sind kostenlos. Das ist kein
|
||||
Fehler, sondern eine bewusste Entscheidung des Entwicklers, der die iOS-App als primäre
|
||||
Finanzierungsquelle für das Gesamtprojekt nutzt — eine legitime und transparente Wahl.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Trotzdem ist es faktisch eine Barriere. Wer Anki auf dem Telefon nutzen will — und das
|
||||
ist die realistische Nutzungssituation für tägliche Wiederholungen —, zahlt einmalig
|
||||
$24.99. Für viele ist das in Ordnung. Für andere, gerade für Schüler:innen oder
|
||||
Studierende mit knappem Budget, ist es der Moment, an dem sie aufhören zu schauen.
|
||||
</p>
|
||||
|
||||
<!-- 5 -->
|
||||
<h2>Der Backlog-Zyklus: wie man in den Burn-out kommt</h2>
|
||||
|
||||
<p>
|
||||
Spaced Repetition funktioniert nur, wenn man es regelmäßig macht. Was passiert, wenn man
|
||||
eine Woche aussetzt — Prüfungsphase, Urlaub, einfach keine Zeit —, ist bei Anki besonders
|
||||
schmerzhaft: die übersprungenen Wiederholungen stapeln sich nicht auf morgen, sie stapeln
|
||||
sich auf heute. Wer nach zehn Tagen Pause zurückkommt, trifft auf einen Rückstand von
|
||||
mehreren hundert Karten. Nicht als Richtwert, sondern als reale Queue, die abgearbeitet
|
||||
werden will.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Das ist kein Bug von Anki, sondern eine direkte Konsequenz des Algorithmus: Karten, die
|
||||
hätten wiederholt werden sollen, werden fällig. Aber die psychologische Wirkung ist
|
||||
destruktiv. Die meisten Menschen, die nach einer Pause auf 500+ fällige Karten schauen,
|
||||
schließen die App wieder. Manche löschen das Deck. Der Backlog wird zur Mauer, die das
|
||||
Weiterlernen blockiert.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Es gibt Add-ons und manuelle Workarounds, die den Rückstand kappen oder verteilen. Aber
|
||||
auch das setzt voraus, dass man weiß, dass es sie gibt — und wie man sie konfiguriert.
|
||||
</p>
|
||||
|
||||
<!-- 6 -->
|
||||
<h2>Was Cardecky daraus gelernt hat — und was Cardecky nicht hat</h2>
|
||||
|
||||
<p>
|
||||
Cardecky ist aus der Beobachtung entstanden, dass die meisten Menschen Anki nicht wegen
|
||||
des Algorithmus verlassen, sondern wegen des Aufwands davor, danach und drumherum. Das
|
||||
ist die Zielgruppe, die Cardecky bedienen will: Nutzer:innen, die Anki wollten und
|
||||
gescheitert sind — nicht Power-User, die Anki lieben.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Was das konkret bedeutet: FSRS ist in Cardecky der Standard, kein opt-in. Card-Erstellung
|
||||
ohne Vorlage-Entscheidungen, direkt starten. Backlog-Management mit weicheren
|
||||
Auffang-Mechanismen nach Pausen. Kein Notes-vs-Cards-Konzept, das erklärt werden muss.
|
||||
Kein Interface aus 2006.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Gleichzeitig soll hier nichts beschönigt werden. Cardecky hat nicht, was Anki in zwanzig
|
||||
Jahren aufgebaut hat:
|
||||
</p>
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
<strong>Keine medizinischen Community-Decks.</strong> Zanki, Lightyear und ihre Varianten
|
||||
sind in Anki, nicht in Cardecky. Wer Medizin studiert und von diesen Decks abhängt,
|
||||
wechselt nicht zu Cardecky.
|
||||
</li>
|
||||
<li>
|
||||
<strong>Kein Add-on-Ökosystem.</strong> Die Tiefe, die Anki durch hunderte
|
||||
Community-Erweiterungen hat, gibt es bei Cardecky nicht. Was ausgeliefert wird, ist das,
|
||||
was da ist.
|
||||
</li>
|
||||
<li>
|
||||
<strong>Keine zwanzigjährige Community.</strong> Foren, Reddit-Threads, YouTube-Tutorials,
|
||||
Stack-Overflow-Fragen — all das existiert für Anki in einem Umfang, den Cardecky nicht
|
||||
hat und in absehbarer Zeit nicht haben wird.
|
||||
</li>
|
||||
<li>
|
||||
<strong>Kein Desktop-Client.</strong> Cardecky ist eine Web-App, installierbar als PWA.
|
||||
Eine native App für iOS und Android ist in Planung, aber noch nicht verfügbar.
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<p>
|
||||
Das sind reale Einschränkungen, keine Randnotizen.
|
||||
</p>
|
||||
|
||||
<!-- 7 -->
|
||||
<h2>Wer schon Anki-Decks hat: Import mitgebracht</h2>
|
||||
|
||||
<p>
|
||||
Für alle, die bereits in Anki investiert haben und den Wechsel trotzdem ausprobieren
|
||||
wollen: Cardecky liest .apkg-Dateien direkt ein. Decks und Karten werden übernommen,
|
||||
Formatierung soweit das Format es trägt. Der FSRS-Lernstand beginnt in Cardecky frisch —
|
||||
das ist eine technische Einschränkung, keine Absicht: FSRS-Parameter sind algorithmisch
|
||||
nicht direkt zwischen verschiedenen Implementierungen übertragbar.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Wer seine Anki-Decks nach <a href={ANKI_IMPORT_URL} target="_blank" rel="noopener">cardecky.mana.how/import</a>
|
||||
hochlädt, kann sofort weiterlernen. Die Queue fängt bei null an — was je nach Perspektive
|
||||
ein Nachteil oder ein Neubeginn ist.
|
||||
</p>
|
||||
|
||||
<!-- CTA -->
|
||||
<hr class="my-12 border-rule" />
|
||||
|
||||
<div class="rounded-xl border border-rule bg-paper p-8">
|
||||
<p class="font-serif text-2xl text-ink">Anki wollte, aber nicht durchgehalten?</p>
|
||||
<p class="mt-3 text-muted leading-relaxed">
|
||||
Cardecky ist für genau diesen Fall gebaut. Bestehende Anki-Decks können direkt
|
||||
importiert werden. Kein Abo, kein Kreditkartenfeld, keine Konfiguration vor dem ersten
|
||||
Lernen.
|
||||
</p>
|
||||
<div class="mt-6 flex flex-wrap gap-4">
|
||||
<a href={APP_URL} class="btn-primary">
|
||||
Cardecky öffnen
|
||||
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true">
|
||||
<path d="M5 12h14M12 5l7 7-7 7"/>
|
||||
</svg>
|
||||
</a>
|
||||
<a href={ANKI_IMPORT_URL} class="btn-ghost">Anki-Decks importieren</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</article>
|
||||
</main>
|
||||
|
||||
<Footer />
|
||||
</Layout>
|
||||
|
||||
<style>
|
||||
/* Prose-Styles für den Artikel — ohne externes @tailwindcss/typography */
|
||||
.prose-cardecky h2 {
|
||||
font-family: var(--font-serif, Georgia, serif);
|
||||
font-size: 1.375rem;
|
||||
font-weight: 600;
|
||||
color: theme('colors.ink');
|
||||
margin-top: 2.5rem;
|
||||
margin-bottom: 0.75rem;
|
||||
line-height: 1.3;
|
||||
}
|
||||
|
||||
.prose-cardecky p {
|
||||
color: theme('colors.ink');
|
||||
line-height: 1.75;
|
||||
margin-bottom: 1.25rem;
|
||||
}
|
||||
|
||||
.prose-cardecky ul,
|
||||
.prose-cardecky ol {
|
||||
margin-bottom: 1.25rem;
|
||||
padding-left: 1.5rem;
|
||||
}
|
||||
|
||||
.prose-cardecky ul {
|
||||
list-style-type: disc;
|
||||
}
|
||||
|
||||
.prose-cardecky ol {
|
||||
list-style-type: decimal;
|
||||
}
|
||||
|
||||
.prose-cardecky li {
|
||||
color: theme('colors.ink');
|
||||
line-height: 1.75;
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
|
||||
.prose-cardecky li + li {
|
||||
margin-top: 0.375rem;
|
||||
}
|
||||
|
||||
.prose-cardecky strong {
|
||||
font-weight: 600;
|
||||
color: theme('colors.ink');
|
||||
}
|
||||
|
||||
.prose-cardecky a {
|
||||
color: theme('colors.leaf');
|
||||
text-decoration: underline;
|
||||
text-underline-offset: 2px;
|
||||
}
|
||||
|
||||
.prose-cardecky a:hover {
|
||||
color: theme('colors.ink');
|
||||
}
|
||||
|
||||
.prose-cardecky hr {
|
||||
border-color: theme('colors.rule');
|
||||
}
|
||||
</style>
|
||||
|
|
@ -1,289 +0,0 @@
|
|||
---
|
||||
import Layout from '../../layouts/Layout.astro';
|
||||
import Nav from '../../components/Nav.astro';
|
||||
import Footer from '../../components/Footer.astro';
|
||||
import '../../styles/base.css';
|
||||
|
||||
const APP_URL = 'https://cardecky.mana.how';
|
||||
const GIT_URL = 'https://git.mana.how/mana/cards';
|
||||
|
||||
const title = 'Deine Karten, deine Daten — warum Data Ownership beim Lernen wichtig ist | Cardecky';
|
||||
const description =
|
||||
'Lerndaten verraten mehr als die meisten Nutzer:innen ahnen. Was Cardecky' +
|
||||
' stattdessen tut: 0 Tracker, DSGVO-Self-Service, vollständiger Export — und' +
|
||||
' warum die Vereinsform das strukturell absichert.';
|
||||
---
|
||||
|
||||
<Layout {title} {description}>
|
||||
<Nav />
|
||||
|
||||
<main class="mx-auto max-w-prose px-6 py-16 sm:py-24">
|
||||
|
||||
<header class="mb-12">
|
||||
<p class="section-label mb-4">Datenschutz · Data Ownership</p>
|
||||
<h1 class="font-serif text-4xl leading-tight text-ink sm:text-5xl">
|
||||
Deine Karten, deine Daten
|
||||
</h1>
|
||||
<p class="mt-5 text-lg leading-relaxed text-muted">
|
||||
Lerndaten sind eine der intimsten Datenkategorien, die eine App sammeln kann.
|
||||
Was Cardecky damit macht — und was nicht —, lässt sich im Code nachprüfen.
|
||||
</p>
|
||||
<p class="mt-4 text-xs text-muted">Stand: Mai 2026</p>
|
||||
</header>
|
||||
|
||||
<article class="prose-cardecky">
|
||||
|
||||
<h2>Was Lerndaten eigentlich verraten</h2>
|
||||
|
||||
<p>
|
||||
Stell dir vor, du lernst seit drei Jahren Japanisch. Jeden Morgen zehn Minuten,
|
||||
tausende Wiederholungen, ein Lernstand, der dich kennt: welche Zeichen du immer
|
||||
wieder vergisst, wie schnell du abrufst, wann du einbrichst. Diese Muster sind
|
||||
nicht banal. Sie sind ein Protokoll deines Gedächtnisses.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Ein Lernprofil über 18 Monate ist ein Fingerabdruck deiner Denkweise — präziser
|
||||
als die meisten Profile, die Werbetreibende kaufen. Was lässt sich daraus
|
||||
ableiten? Lerngeschwindigkeit und Konzentrationsmuster. Schwächen und Stärken
|
||||
nach Fachgebiet. Lernzeiten — und damit Lebensrhythmus. Bei Kindern und
|
||||
Jugendlichen kommen Schul- und Entwicklungsprofile hinzu, die besonders
|
||||
schutzbedürftig sind.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Das ist kein Paranoia-Szenario. Es ist eine nüchterne Beschreibung dessen, was
|
||||
eine App sammelt, die Spaced Repetition betreibt. Die Frage ist, wer diese Daten
|
||||
kontrolliert.
|
||||
</p>
|
||||
|
||||
<h2>Was andere Apps damit machen</h2>
|
||||
|
||||
<p>
|
||||
Quizlet hat 2022–2023 seine Kernfunktionen hinter eine Bezahlschranke gesperrt.
|
||||
Wer wechseln wollte, stand vor einem weiteren Problem: Quizlet bietet keinen
|
||||
sauberen Export. Sets lassen sich nicht als standardisiertes Dateiformat
|
||||
herunterladen. Wer geht, verliert seinen Lernstand oder muss ihn mühsam manuell
|
||||
übertragen. Das ist kein Zufall — das ist Geschäftsmodell. Lock-in hält Churn
|
||||
unten, und Churn unten zu halten ist für eine VC-finanzierte Plattform ein
|
||||
wichtigerer Wert als Portabilität.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Das zweite Problem ist weniger sichtbar: Quizlets Datenschutzerklärung erlaubt
|
||||
die Nutzung von Lerndaten für Produktverbesserungen, Forschung und
|
||||
„personalisierte Erfahrungen" — Formulierungen, die weit genug sind, um viel
|
||||
zu erlauben. Das gilt strukturell für viele ad-finanzierte oder
|
||||
VC-finanzierte Bildungsplattformen: Das Geschäftsmodell enthält einen
|
||||
Anreiz, Nutzerdaten zu verwerten. Dieser Anreiz verschwindet nicht, weil
|
||||
die App ein Lern-Interface hat.
|
||||
</p>
|
||||
|
||||
<h2>Was „0 Tracker" konkret bedeutet — und wie man es nachprüft</h2>
|
||||
|
||||
<p>
|
||||
Cardecky enthält keine Tracking-Bibliotheken. Kein PostHog, kein Plausible,
|
||||
kein Google Analytics, kein Mixpanel, kein Segment. Das ist nicht eine
|
||||
Marketing-Aussage — es ist im Quellcode nachprüfbar.
|
||||
</p>
|
||||
|
||||
<pre><code>git grep -i "posthog\|plausible\|mixpanel\|segment\|analytics" apps/web/src/</code></pre>
|
||||
|
||||
<p>
|
||||
Das Ergebnis ist leer. Wer das nicht glaubt, kann es selbst ausführen —
|
||||
der Code liegt öffentlich auf{' '}
|
||||
<a href={GIT_URL} target="_blank" rel="noopener">git.mana.how/till/cards-web</a>.
|
||||
Das ist der Unterschied zwischen einem Versprechen und einem Nachweis.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Was stattdessen passiert: Serverseitig werden funktionale Logs für Betrieb
|
||||
und Fehlerdiagnose geschrieben — Request-Zeiten, HTTP-Status-Codes, keine
|
||||
Nutzerprofile. Es gibt keine Cross-Session-Verknüpfung, keinen
|
||||
Behaviour-Graph, keine Retargeting-Pixel. Die Server stehen auf dem eigenen
|
||||
Mac Mini von mana e.V. in der Schweiz, hinter einem Cloudflare Tunnel als
|
||||
reine TLS-Terminierung — kein US-Cloud-Provider verarbeitet deine Lerndaten.
|
||||
</p>
|
||||
|
||||
<h2>DSGVO-Export und Anti-Lock-In — als aktive Features</h2>
|
||||
|
||||
<p>
|
||||
Daten-Souveränität ist in Cardecky kein Compliance-Text im Footer. Sie ist in
|
||||
konkreten Features sichtbar.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<strong>Self-Service-Export.</strong> Unter Einstellungen kannst du deine Daten
|
||||
jederzeit exportieren, ohne Support-Ticket, ohne Wartezeit. Das geht in drei
|
||||
Formaten:
|
||||
</p>
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
<strong>.apkg</strong> (Anki-Format) — der de-facto-Standard für Lernkarten,
|
||||
importierbar in Anki, AnkiDroid, AnkiMobile und jede andere
|
||||
FSRS-kompatible App
|
||||
</li>
|
||||
<li>
|
||||
<strong>.csv</strong> — lesbar in jeder Tabellenkalkulation, importierbar
|
||||
in andere Systeme
|
||||
</li>
|
||||
<li>
|
||||
<strong>FSRS-State-JSON</strong> — enthält deinen vollständigen Lernstand:
|
||||
Wiederholungshistorie, Stabilitätswerte, Fälligkeitsdaten. Damit nimmst du
|
||||
nicht nur deine Karten mit, sondern auch das Gedächtnis, das die App über
|
||||
sie aufgebaut hat
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<p>
|
||||
Das ist der Unterschied zwischen Export-als-Rückgabe und Export-als-Portabilität.
|
||||
Du kannst mit vollem Lernstand zu Anki wechseln. Du verlierst nichts.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<strong>DSGVO-Löschung ohne Ticket.</strong> Wer sein Konto löschen will, tut
|
||||
das in der App — vollständig, ohne eine E-Mail schreiben zu müssen. Das ist
|
||||
kein regulatorischer Reflex. Es folgt aus Wert 1 von mana e.V.: Daten gehören
|
||||
den Nutzer:innen, nicht uns. Wer geht, geht mit allem.
|
||||
</p>
|
||||
|
||||
<h2>Warum die Vereinsform hier einen strukturellen Unterschied macht</h2>
|
||||
|
||||
<p>
|
||||
mana e.V. ist ein Schweizer Verein nach ZGB Art. 60 ff. Kein Investor hat
|
||||
Anteile. Es gibt keine Wachstumsziele, keine Exit-Strategie, keine Runde, die
|
||||
zurückgezahlt werden muss. Der Verein finanziert sich aus Mitgliedsbeiträgen,
|
||||
Spenden und fairen Credit-Käufen — nicht aus Werbeeinnahmen oder dem Verkauf
|
||||
von Nutzerdaten.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
VC-finanzierte Apps stehen unter dem Druck, einen Return zu liefern. Das formt
|
||||
Produktentscheidungen, oft unsichtbar. Lock-in ist wertvoll, weil er Churn
|
||||
verhindert. Daten sind wertvoll, weil sie Targeting ermöglichen.
|
||||
Engagement-Maximierung ist wertvoll, weil sie Nutzungszeit erhöht. Keiner
|
||||
dieser Anreize trifft auf mana e.V. zu — nicht weil die Menschen dahinter
|
||||
besonders tugendhaft sind, sondern weil die Rechtsform diese Anreize
|
||||
strukturell nicht enthält.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Die Schweizer Rechtsform ist dabei kein Steuertrick. Sie gibt dem Verein
|
||||
politische Unabhängigkeit außerhalb der großen Blöcke EU und USA — und sie
|
||||
bedeutet: Es gibt keine Unternehmensanteile, die eine andere Firma kaufen
|
||||
könnte, um die Datenschutzversprechen anschließend wegzuverhandeln.
|
||||
</p>
|
||||
|
||||
<h2>Offene Punkte</h2>
|
||||
|
||||
<p>
|
||||
Ehrlichkeit darüber, was noch fehlt:
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<strong>Native Mobile-App.</strong> Eine SwiftUI-App für iOS und iPadOS ist in
|
||||
Entwicklung — die Kern-Lernschleife ist fertig, der App-Store-Release steht noch
|
||||
aus. Wer heute auf dem iPhone lernen will, nutzt die Web-App über den Browser.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<strong>Offline-Support.</strong> Die PWA ist online-first. Vollständiger
|
||||
Offline-Betrieb — Karten laden und bewerten ohne Verbindung, Sync beim
|
||||
nächsten Online-Gang — ist geplant, aber noch nicht live.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Das sind keine versteckten Einschränkungen. Sie stehen hier, weil eine App,
|
||||
die Transparenz als Wert nennt, das auch auf sich selbst anwenden muss.
|
||||
</p>
|
||||
|
||||
<hr class="my-12 border-rule" />
|
||||
|
||||
<div class="rounded-xl border border-rule bg-paper p-8">
|
||||
<p class="font-serif text-2xl text-ink">Lernen ohne Tracking.</p>
|
||||
<p class="mt-3 text-muted leading-relaxed">
|
||||
Konto erstellen, loslegen. Keine Werbung, kein Analytics-Code,
|
||||
jederzeit exportierbar.
|
||||
</p>
|
||||
<div class="mt-6 flex flex-wrap gap-4">
|
||||
<a href={APP_URL} class="btn-primary">
|
||||
Cardecky öffnen
|
||||
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true">
|
||||
<path d="M5 12h14M12 5l7 7-7 7"/>
|
||||
</svg>
|
||||
</a>
|
||||
<a href={GIT_URL} target="_blank" rel="noopener" class="btn-ghost">
|
||||
Code ansehen
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</article>
|
||||
</main>
|
||||
|
||||
<Footer />
|
||||
</Layout>
|
||||
|
||||
<style>
|
||||
.prose-cardecky h2 {
|
||||
font-family: var(--font-serif, Georgia, serif);
|
||||
font-size: 1.375rem;
|
||||
font-weight: 600;
|
||||
color: theme('colors.ink');
|
||||
margin-top: 2.5rem;
|
||||
margin-bottom: 0.75rem;
|
||||
line-height: 1.3;
|
||||
}
|
||||
|
||||
.prose-cardecky p {
|
||||
color: theme('colors.ink');
|
||||
line-height: 1.75;
|
||||
margin-bottom: 1.25rem;
|
||||
}
|
||||
|
||||
.prose-cardecky ul,
|
||||
.prose-cardecky ol {
|
||||
margin-bottom: 1.25rem;
|
||||
padding-left: 1.5rem;
|
||||
}
|
||||
|
||||
.prose-cardecky ul { list-style-type: disc; }
|
||||
.prose-cardecky ol { list-style-type: decimal; }
|
||||
|
||||
.prose-cardecky li {
|
||||
color: theme('colors.ink');
|
||||
line-height: 1.75;
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
|
||||
.prose-cardecky strong {
|
||||
font-weight: 600;
|
||||
color: theme('colors.ink');
|
||||
}
|
||||
|
||||
.prose-cardecky a {
|
||||
color: theme('colors.leaf');
|
||||
text-decoration: underline;
|
||||
text-underline-offset: 2px;
|
||||
}
|
||||
|
||||
.prose-cardecky a:hover { color: theme('colors.ink'); }
|
||||
|
||||
.prose-cardecky hr { border-color: theme('colors.rule'); }
|
||||
|
||||
.prose-cardecky pre {
|
||||
background: theme('colors.paper');
|
||||
border: 1px solid theme('colors.rule');
|
||||
border-radius: 0.5rem;
|
||||
padding: 1rem 1.25rem;
|
||||
overflow-x: auto;
|
||||
margin-bottom: 1.25rem;
|
||||
}
|
||||
|
||||
.prose-cardecky code {
|
||||
font-family: ui-monospace, 'Cascadia Code', monospace;
|
||||
font-size: 0.875rem;
|
||||
color: theme('colors.ink');
|
||||
}
|
||||
</style>
|
||||
|
|
@ -1,246 +0,0 @@
|
|||
---
|
||||
import Layout from '../../layouts/Layout.astro';
|
||||
import Nav from '../../components/Nav.astro';
|
||||
import Footer from '../../components/Footer.astro';
|
||||
import '../../styles/base.css';
|
||||
|
||||
const APP_URL = 'https://cardecky.mana.how';
|
||||
|
||||
const title = 'Weniger lernen, mehr behalten: Was FSRS bedeutet | Cardecky';
|
||||
const description =
|
||||
'FSRS ist der modernste Spaced-Repetition-Algorithmus — und reduziert die nötigen' +
|
||||
' Wiederholungen um 20–30 % bei gleicher Lernretention. Wie er funktioniert,' +
|
||||
' warum er noch nicht überall Standard ist, und wie Cardecky ihn einsetzt.';
|
||||
---
|
||||
|
||||
<Layout {title} {description}>
|
||||
<Nav />
|
||||
|
||||
<main class="mx-auto max-w-prose px-6 py-16 sm:py-24">
|
||||
|
||||
<header class="mb-12">
|
||||
<p class="section-label mb-4">Algorithmus · Spaced Repetition</p>
|
||||
<h1 class="font-serif text-4xl leading-tight text-ink sm:text-5xl">
|
||||
Weniger lernen, mehr behalten
|
||||
</h1>
|
||||
<p class="mt-5 text-lg leading-relaxed text-muted">
|
||||
FSRS ist der aktuell präziseste Algorithmus für Lernkarten — und er ist noch
|
||||
nicht der Standard. Was sich hinter dem Kürzel verbirgt, warum es einen
|
||||
Unterschied macht, und was er nicht lösen kann.
|
||||
</p>
|
||||
<p class="mt-4 text-xs text-muted">Stand: Mai 2026</p>
|
||||
</header>
|
||||
|
||||
<article class="prose-cardecky">
|
||||
|
||||
<h2>Das Paradox des Lernens</h2>
|
||||
|
||||
<p>
|
||||
Wer viel lernt, behält oft wenig. Das liegt nicht an mangelnder Disziplin,
|
||||
sondern an einer einfachen physiologischen Tatsache: Das Gehirn vergisst nach
|
||||
einer vorhersagbaren Kurve. Hermann Ebbinghaus hat das im 19. Jahrhundert
|
||||
empirisch beschrieben. Seitdem hat sich an der Grundkurve nichts geändert —
|
||||
aber daran, wie gut wir darauf reagieren können, hat sich einiges getan.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Die meisten Lernmethoden ignorieren die Vergessenskurve. Sie lernen in Blöcken,
|
||||
mit Wiederholungen, die zu früh kommen (egal, was man schon weiß) oder zu spät
|
||||
(wenn es bereits vergessen ist). Das Ergebnis: mehr Zeitaufwand, weniger Retention.
|
||||
Spaced Repetition ist der direkte Angriff auf dieses Problem.
|
||||
</p>
|
||||
|
||||
<h2>Was Spaced Repetition löst</h2>
|
||||
|
||||
<p>
|
||||
Das Prinzip ist einfach: Eine Karte wird genau dann wieder gezeigt, wenn man sie
|
||||
vergessen hat — oder kurz davor. Nicht jeden Tag. Nicht nach festem Zeitplan.
|
||||
Sondern genau dann, wenn das Wiederholen etwas bringt.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Eine Karte, die man immer sofort richtig beantwortet, wird seltener gezeigt.
|
||||
Eine, die man regelmäßig vergisst, kommt häufiger. Das klingt selbstverständlich.
|
||||
Die entscheidende Frage ist: Wie genau berechnet ein Algorithmus diesen Zeitpunkt?
|
||||
</p>
|
||||
|
||||
<h2>SM-2 und FSRS: Was sich geändert hat</h2>
|
||||
|
||||
<p>
|
||||
Der Algorithmus, der die letzten Jahrzehnte dominiert hat, heißt <strong>SM-2</strong>
|
||||
— entwickelt von Piotr Woźniak in den späten 1980ern und bis heute das Fundament
|
||||
der meisten Lern-Apps, einschließlich des größten Teils der Anki-Nutzerbasis.
|
||||
SM-2 funktioniert. Aber es hat strukturelle Schwächen.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
SM-2 schätzt, wie lange eine Erinnerung hält, auf Basis eines festen
|
||||
Intervall-Multiplikators und einer einfachen Bewertungsskala. Es kennt keine
|
||||
separaten Konzepte für <strong>Stability</strong> (wie lange eine Erinnerung nach
|
||||
einer Wiederholung hält) und <strong>Difficulty</strong> (wie schwer eine Karte
|
||||
grundsätzlich ist). Es behandelt beide als einen kombinierten Faktor — was
|
||||
bedeutet, dass eine Karte, die man einmal vergessen hat, dauerhaft mit schlechterer
|
||||
Scheduling-Qualität bestraft wird, auch wenn man sie danach zehnmal in Folge
|
||||
richtig beantwortet.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<strong>FSRS</strong> (Free Spaced Repetition Scheduler) arbeitet anders. Der
|
||||
Algorithmus, hauptsächlich entwickelt von Jarrett Ye und seit 2022 quelloffen
|
||||
verfügbar, modelliert Stability und Difficulty als getrennte Parameter. Er nutzt
|
||||
ein Modell, das mit realen Review-Daten trainiert wurde — nicht mit theoretischen
|
||||
Annahmen über das Gedächtnis.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Das Ergebnis: <strong>20–30 % weniger Reviews bei gleicher Retention.</strong>
|
||||
Das ist keine Marketing-Angabe, sondern das Ergebnis von Benchmarks auf realen
|
||||
Datensätzen, die beim Entwickeln von FSRS veröffentlicht wurden. Wer täglich
|
||||
200 Karten reviewt, kommt mit FSRS auf 140–160 — bei gleichem Lernergebnis.
|
||||
Über Monate und Jahre summiert sich das auf Dutzende Stunden.
|
||||
</p>
|
||||
|
||||
<h2>Warum FSRS bei anderen nicht der Standard ist</h2>
|
||||
|
||||
<p>
|
||||
Anki hat FSRS erst 2024 in den Kern integriert — und dann nur als opt-in. Wer
|
||||
Anki installiert und keine Einstellungen ändert, nutzt heute noch SM-2. Die meisten
|
||||
Nutzer:innen wissen nicht, dass FSRS existiert, geschweige denn, wie sie es
|
||||
aktivieren.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Das ist keine Kritik an Anki. Es ist eine Open-Source-App mit einem langen
|
||||
Kompatibilitäts-Vertrag gegenüber Millionen Nutzer:innen und deren bestehenden
|
||||
Decks. Defaults zu ändern ist dort riskant — technisch und in der Community.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Quizlet ist der andere relevante Name in diesem Bereich. Dort hat Spaced
|
||||
Repetition nicht den Weg ins opt-in genommen, sondern vollständig raus.
|
||||
Algorithmen, die Nutzer:innen davon abhalten, dieselbe Karte immer wieder
|
||||
zu sehen, erzeugen weniger Session-Zeit. Weniger Session-Zeit ist ein
|
||||
schlechter Wert für eine werbefinanzierte Plattform.
|
||||
</p>
|
||||
|
||||
<h2>Wie Cardecky das umsetzt</h2>
|
||||
|
||||
<p>
|
||||
Cardecky nutzt FSRS als Standard — kein opt-in, kein Versteck in den
|
||||
Einstellungen, keine Legacy-Defaults. Jede neue Karte, jede neue Wiederholung
|
||||
wird von FSRS geplant. Das ist der Ausgangspunkt, nicht ein Premium-Feature.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Der nächste Schritt ist die <strong>FSRS-Parameter-Optimierung pro Nutzer:in</strong>.
|
||||
FSRS enthält 17 Parameter, die beschreiben, wie ein individuelles Gedächtnis auf
|
||||
Wiederholungen reagiert. Die Standard-Parameter wurden auf einem großen,
|
||||
heterogenen Datensatz trainiert — sie sind gut, aber sie passen nicht perfekt
|
||||
auf jede Person und jedes Lerngebiet. Wer Vokabeln einer neuen Sprache lernt,
|
||||
vergisst anders als jemand, der medizinische Fakten büffelt. Aus der persönlichen
|
||||
Review-History lassen sich diese Parameter re-optimieren. Das ist in Cardecky
|
||||
in Arbeit.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Ebenfalls geplant: ein <strong>Transparenz-Tooltip pro Karte</strong> — „Warum
|
||||
werde ich heute gefragt?" Nicht als technische Dokumentation, sondern als
|
||||
konkreter Einblick: Stability, Difficulty, letztes Rating, berechnetes nächstes
|
||||
Intervall. Wer verstehen will, warum eine Karte jetzt auftaucht und nicht in
|
||||
drei Wochen, bekommt die Antwort direkt.
|
||||
</p>
|
||||
|
||||
<h2>Was FSRS nicht löst</h2>
|
||||
|
||||
<p>
|
||||
Ein guter Algorithmus ersetzt keine guten Karten.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
FSRS kann eine Karte optimal planen — aber wenn sie schlecht formuliert ist,
|
||||
zu viel Information auf einmal trägt, oder eine Verbindung zum eigenen Kontext
|
||||
fehlt, hilft das beste Scheduling wenig. Das Gehirn verankert Informationen,
|
||||
wenn sie bedeutungsvoll sind. Dafür ist kein Algorithmus zuständig.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Das andere offene Problem: Wer eine längere Pause macht — Urlaub, Prüfungsstress,
|
||||
Krankheit — baut sich eine Backlog-Queue auf. Anki-Nutzer:innen kennen das Gefühl,
|
||||
nach zehn Tagen Pause auf 500+ fällige Karten zu schauen. Mit einer besseren
|
||||
Scheduling-Basis ist das Problem kleiner, weil FSRS Intervalle realistischer setzt
|
||||
und weniger Überplanungen produziert — aber wer lange pausiert, kommt um den
|
||||
Backlog nicht ganz herum. Strategien dafür (selektive Queue-Verkleinerung,
|
||||
Deck-Priorisierung nach Prüfungsdatum) sind ein separates Problem vom Algorithmus.
|
||||
</p>
|
||||
|
||||
<hr class="my-12 border-rule" />
|
||||
|
||||
<div class="rounded-xl border border-rule bg-paper p-8">
|
||||
<p class="font-serif text-2xl text-ink">Mit FSRS starten — kostenlos.</p>
|
||||
<p class="mt-3 text-muted leading-relaxed">
|
||||
Cardecky nutzt FSRS by default. Kein Opt-in, kein Abo, kein Konfigurieren.
|
||||
Einfach loslegen.
|
||||
</p>
|
||||
<div class="mt-6 flex flex-wrap gap-4">
|
||||
<a href={APP_URL} class="btn-primary">
|
||||
Cardecky öffnen
|
||||
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true">
|
||||
<path d="M5 12h14M12 5l7 7-7 7"/>
|
||||
</svg>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</article>
|
||||
</main>
|
||||
|
||||
<Footer />
|
||||
</Layout>
|
||||
|
||||
<style>
|
||||
.prose-cardecky h2 {
|
||||
font-family: var(--font-serif, Georgia, serif);
|
||||
font-size: 1.375rem;
|
||||
font-weight: 600;
|
||||
color: theme('colors.ink');
|
||||
margin-top: 2.5rem;
|
||||
margin-bottom: 0.75rem;
|
||||
line-height: 1.3;
|
||||
}
|
||||
|
||||
.prose-cardecky p {
|
||||
color: theme('colors.ink');
|
||||
line-height: 1.75;
|
||||
margin-bottom: 1.25rem;
|
||||
}
|
||||
|
||||
.prose-cardecky ul,
|
||||
.prose-cardecky ol {
|
||||
margin-bottom: 1.25rem;
|
||||
padding-left: 1.5rem;
|
||||
}
|
||||
|
||||
.prose-cardecky ul { list-style-type: disc; }
|
||||
.prose-cardecky ol { list-style-type: decimal; }
|
||||
|
||||
.prose-cardecky li {
|
||||
color: theme('colors.ink');
|
||||
line-height: 1.75;
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
|
||||
.prose-cardecky strong {
|
||||
font-weight: 600;
|
||||
color: theme('colors.ink');
|
||||
}
|
||||
|
||||
.prose-cardecky a {
|
||||
color: theme('colors.leaf');
|
||||
text-decoration: underline;
|
||||
text-underline-offset: 2px;
|
||||
}
|
||||
|
||||
.prose-cardecky a:hover { color: theme('colors.ink'); }
|
||||
|
||||
.prose-cardecky hr { border-color: theme('colors.rule'); }
|
||||
</style>
|
||||
|
|
@ -1,408 +0,0 @@
|
|||
---
|
||||
import Layout from '../../layouts/Layout.astro';
|
||||
import Nav from '../../components/Nav.astro';
|
||||
import Footer from '../../components/Footer.astro';
|
||||
import '../../styles/base.css';
|
||||
|
||||
const APP_URL = 'https://cardecky.mana.how';
|
||||
|
||||
const title = 'Wie man Lernkarten schreibt, die wirklich funktionieren | Cardecky';
|
||||
const description =
|
||||
'Die meisten Lernkarten sind zu lang, zu abstrakt oder zu kontextfrei. Fünf konkrete' +
|
||||
' Prinzipien für Karten, die das Gehirn tatsächlich verankert — mit Gegenbeispielen.';
|
||||
---
|
||||
|
||||
<Layout {title} {description}>
|
||||
<Nav />
|
||||
|
||||
<main class="mx-auto max-w-prose px-6 py-16 sm:py-24">
|
||||
|
||||
<!-- Artikel-Header -->
|
||||
<header class="mb-12">
|
||||
<p class="section-label mb-4">Lernen · Methodik</p>
|
||||
<h1 class="font-serif text-4xl leading-tight text-ink sm:text-5xl">
|
||||
Wie man Lernkarten schreibt, die wirklich funktionieren
|
||||
</h1>
|
||||
<p class="mt-5 text-lg leading-relaxed text-muted">
|
||||
Der beste Algorithmus nützt nichts, wenn die Karten schlecht gebaut sind. Fünf
|
||||
Prinzipien für Karten, die das Gehirn tatsächlich behält.
|
||||
</p>
|
||||
<p class="mt-4 text-xs text-muted">Stand: Mai 2026</p>
|
||||
</header>
|
||||
|
||||
<article class="prose-cardecky">
|
||||
|
||||
<!-- Einstieg -->
|
||||
<p>
|
||||
Wer mit Spaced Repetition anfängt und nach drei Wochen merkt, dass es nicht
|
||||
funktioniert, sucht den Fehler meistens an der falschen Stelle: beim Algorithmus, bei
|
||||
der App, bei der Wiederholungsfrequenz. Die eigentliche Ursache sitzt fast immer
|
||||
früher — in den Karten selbst.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Schlechte Karten machen gutes Scheduling wertlos. Eine Karte, die drei Fakten
|
||||
gleichzeitig abfragt, hat kein definiertes Lernergebnis. Eine Karte ohne Kontext
|
||||
wird isoliert abgespeichert — und isoliert Gespeichertes verblasst, egal wie oft
|
||||
es wiederholt wird. FSRS kann berechnen, wann du eine Karte wieder sehen sollst;
|
||||
es kann nicht reparieren, was die Karte von vornherein falsch fragt.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Die folgenden fünf Prinzipien kommen aus der Lernforschung, aus Piotr Woźniaks
|
||||
„Twenty Rules of Formulating Knowledge" und aus der Praxis der Anki- und
|
||||
FSRS-Community. Sie sind nicht kompliziert — aber sie erfordern beim Schreiben
|
||||
Disziplin.
|
||||
</p>
|
||||
|
||||
<!-- Prinzip 1 -->
|
||||
<h2>1. Eine Frage, eine Antwort</h2>
|
||||
|
||||
<p>
|
||||
Das ist der häufigste Anfängerfehler, und er fühlt sich beim Schreiben nicht wie
|
||||
ein Fehler an. Man kennt ein Thema, will es „effizient" auf Karten bringen, und
|
||||
packt fünf zusammengehörige Fakten auf eine Karte. Das Ergebnis ist eine Karte, die
|
||||
du dir nie wirklich merken kannst — weil du nie weißt, ob du sie gewusst hast.
|
||||
</p>
|
||||
|
||||
<p>Beispiel einer schlechten Karte:</p>
|
||||
|
||||
<pre>F: Was sind die Eigenschaften von Mitochondrien?
|
||||
A: Doppelmembran, eigene DNA, ATP-Produktion durch
|
||||
oxidative Phosphorylierung, Apoptose-Steuerung,
|
||||
Ursprung aus endosymbiotischer Bakterien.</pre>
|
||||
|
||||
<p>Besser: fünf Karten.</p>
|
||||
|
||||
<pre>F: Welche Membran-Struktur haben Mitochondrien?
|
||||
A: Doppelmembran (Außen- und Innenmembran).
|
||||
|
||||
F: Wodurch unterscheidet sich die Mitochondrien-DNA
|
||||
von der Zellkern-DNA?
|
||||
A: Sie ist zirkulär und erinnert an Bakterien-DNA
|
||||
— Hinweis auf den endosymbiontischen Ursprung.</pre>
|
||||
|
||||
<p>
|
||||
Jede Karte hat jetzt ein klares Richtig oder Falsch. Wenn du sie beim Scheduling
|
||||
als „schwierig" markierst, weiß der Algorithmus, was du nicht weißt — und kann
|
||||
das gezielt wiederholen. Mit der Sammelkarte kann er das nicht.
|
||||
</p>
|
||||
|
||||
<!-- Prinzip 2 -->
|
||||
<h2>2. Kontext ist kein Luxus</h2>
|
||||
|
||||
<p>
|
||||
Isolierte Fakten vergisst das Gehirn schneller als eingebettete. Das ist keine
|
||||
Faustregel, sondern ein gut belegter Effekt: Bedeutungsträgern gegenüber
|
||||
bedeutungsfreien Stimuli fällt das Behalten leichter, weil das Gehirn neue
|
||||
Information an bestehende Netzwerke knüpfen kann.
|
||||
</p>
|
||||
|
||||
<p>Eine typische kontextfreie Karte:</p>
|
||||
|
||||
<pre>F: Was ist Apoptose?
|
||||
A: Programmierter Zelltod.</pre>
|
||||
|
||||
<p>Eine Karte mit Kontext:</p>
|
||||
|
||||
<pre>F: Warum ist Apoptose für die Embryonalentwicklung
|
||||
wichtig?
|
||||
A: Finger entstehen, weil die Zellen zwischen ihnen
|
||||
gezielt in Apoptose gehen — nicht, weil Finger
|
||||
wachsen, sondern weil das Material dazwischen
|
||||
verschwindet.</pre>
|
||||
|
||||
<p>
|
||||
Die zweite Karte fragt dasselbe Konzept ab — aber in einem Zusammenhang, der sich
|
||||
bildlich einprägt. „Programmierter Zelltod" bleibt ein Begriff. Finger, die sich
|
||||
aus einem Gewebeklumpen herausschälen, bleibt ein Bild.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Das bedeutet nicht, dass jede Karte einen langen Erklärungstext braucht. Ein
|
||||
einziger konkreter Anwendungsfall, ein Beispiel, ein Gegenbeispiel — das reicht
|
||||
meistens. Die Frage „in welchem Zusammenhang?" vor dem Schreiben stellen.
|
||||
</p>
|
||||
|
||||
<!-- Prinzip 3 -->
|
||||
<h2>3. Minimales, aber vollständiges Wissen</h2>
|
||||
|
||||
<p>
|
||||
Piotr Woźniak nennt das „minimum information principle": eine Karte so kurz wie
|
||||
möglich, aber nicht kürzer. Die Spannung liegt im „aber nicht kürzer" — eine Karte,
|
||||
die so gekürzt wurde, dass sie nur noch mit Vorwissen richtig beantwortet werden
|
||||
kann, das du beim Wiederholen vielleicht nicht mehr parat hast, testet nichts
|
||||
Sinnvolles.
|
||||
</p>
|
||||
|
||||
<p>Zu lang:</p>
|
||||
|
||||
<pre>F: Erkläre den Unterschied zwischen prokaryotischen
|
||||
und eukaryotischen Zellen, inklusive Beispielen,
|
||||
evolutionärem Ursprung und Zellorganellen.
|
||||
A: [langer Absatz]</pre>
|
||||
|
||||
<p>Zu kurz (und zu vage):</p>
|
||||
|
||||
<pre>F: Prokaryoten?
|
||||
A: Keine Zellkerne.</pre>
|
||||
|
||||
<p>Genau richtig:</p>
|
||||
|
||||
<pre>F: Was fehlt Prokaryoten, das Eukaryoten haben?
|
||||
A: Einen membranumhüllten Zellkern.</pre>
|
||||
|
||||
<p>
|
||||
Ein gutes Testkriterium: Wenn du eine Karte nach einem Monat Pause siehst und die
|
||||
Frage vollständig verstehst, ist sie gut formuliert. Wenn du erst rekonstruieren
|
||||
musst, was du damals gemeint hast, ist sie zu kurz oder zu vage.
|
||||
</p>
|
||||
|
||||
<!-- Prinzip 4 -->
|
||||
<h2>4. Cloze richtig einsetzen</h2>
|
||||
|
||||
<p>
|
||||
Lückentexte — in Anki-Notation <code>{{c1::Begriff}}</code> — sind nicht
|
||||
einfach eine andere Formatierung derselben Karte. Sie eignen sich besonders gut für
|
||||
Prozesse, Sequenzen und Zusammenhänge, weil der umgebende Satz als Kontext direkt
|
||||
sichtbar bleibt.
|
||||
</p>
|
||||
|
||||
<p>Klassische Frage-Antwort-Karte für einen Begriff im Kontext:</p>
|
||||
|
||||
<pre>F: Was ist das Prinzip hinter dem Krebs-Zyklus?
|
||||
A: Acetyl-CoA wird oxidiert, ATP gewonnen,
|
||||
CO₂ abgegeben.</pre>
|
||||
|
||||
<p>Als Cloze — stärker, weil der Satz als Ganzes gelernt wird:</p>
|
||||
|
||||
<pre>Der Krebs-Zyklus oxidiert {{c1::Acetyl-CoA}},
|
||||
gewinnt dabei {{c2::ATP}} und gibt
|
||||
{{c3::CO₂}} ab.</pre>
|
||||
|
||||
<p>
|
||||
Cloze ist schwächer, wenn der Lückentext rein zufällig wirkt — also wenn aus dem
|
||||
Satz nicht klar wird, was gesucht ist, und jedes beliebige Wort passen könnte.
|
||||
Dann ist eine direkte Frage ehrlicher.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Cloze ist auch kein Allheilmittel gegen das Ein-Fakt-Problem: ein Satz mit fünf
|
||||
Lücken ist immer noch eine Karte mit fünf Fakten. Besser: pro Satz eine Lücke,
|
||||
mehrere Karten.
|
||||
</p>
|
||||
|
||||
<!-- Prinzip 5 -->
|
||||
<h2>5. Eigene Worte, eigene Bilder</h2>
|
||||
|
||||
<p>
|
||||
Auswendig gelernte Definitionen verblassen schneller als selbst formulierte
|
||||
Erklärungen. Das liegt daran, dass bei der Eigenformulierung das Verstehen
|
||||
vorausgeht — wer etwas in eigene Worte übersetzt, hat es bereits verarbeitet,
|
||||
nicht nur kopiert.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Lehrbuchdefinition direkt übernommen — typische Anfänger-Karte:
|
||||
</p>
|
||||
|
||||
<pre>F: Was ist osmotischer Druck?
|
||||
A: Der Druck, der aufgewendet werden muss, um den
|
||||
osmotischen Fluss einer Lösung durch eine
|
||||
semipermeable Membran zu verhindern.</pre>
|
||||
|
||||
<p>Eigenformulierung:</p>
|
||||
|
||||
<pre>F: Was ist osmotischer Druck — in einem Satz,
|
||||
ohne Fachsprache?
|
||||
A: Das Wasser will auf die Seite mit mehr
|
||||
gelöstem Zeug; der osmotische Druck ist der
|
||||
Gegendruck, der das verhindert.</pre>
|
||||
|
||||
<p>
|
||||
Die zweite Version verliert Präzision — das ist ein echter Trade-off. Für
|
||||
klausurrelevante exakte Definitionen braucht man beide: die präzise Formulierung
|
||||
und die eigene Erklärung. Dann zwei Karten. Nicht eine Karte, die beides
|
||||
gleichzeitig will.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Bilder funktionieren nach demselben Prinzip: visuell verankerte Information hat
|
||||
mehr Anknüpfungspunkte im Gedächtnis als rein verbale. Ein Diagramm, ein
|
||||
selbst gezeichneter Sketch, ein Screenshot aus einem Lehrvideo — das schlägt
|
||||
eine nochmals kopierte Textdefinition fast immer.
|
||||
</p>
|
||||
|
||||
<!-- AI-Generierung -->
|
||||
<h2>Was AI-Generierung kann — und was nicht</h2>
|
||||
|
||||
<p>
|
||||
AI-Tools können Karten aus einem Text generieren, und das kann die Arbeit
|
||||
reduzieren: statt zwanzig Karten von Hand zu schreiben, bekommt man einen
|
||||
Entwurf, der überarbeitet werden kann. Das ist ein nützliches Werkzeug.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Es ersetzt aber nicht das Nachdenken über die eigene Formulierung. AI-generierte
|
||||
Karten folgen oft dem Muster der Lehrbuchdefinition — sie übernehmen Sprache
|
||||
aus dem Quelltext, statt sie zu übersetzen. Sie splitten zu selten von alleine
|
||||
auf ein Fakt pro Karte. Und sie können nicht wissen, welcher Kontext für dich
|
||||
der einprägsame ist.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Der sinnvolle Workflow: AI generiert einen Rohsatz von Karten, du überarbeitest
|
||||
ihn nach den fünf Prinzipien. Das ist weniger Arbeit als von null, aber es ist
|
||||
immer noch Arbeit.
|
||||
</p>
|
||||
|
||||
<!-- Cardecky-Einbindung -->
|
||||
<h2>Welche Kartentypen welches Prinzip unterstützen</h2>
|
||||
|
||||
<p>
|
||||
Cardecky hat vier native Kartentypen, die direkt auf diese Prinzipien einzahlen:
|
||||
</p>
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
<strong>Vorderseite/Rückseite</strong> — der Standard für Prinzip 1 und 3. Eine
|
||||
Frage, eine Antwort. Keine Extras.
|
||||
</li>
|
||||
<li>
|
||||
<strong>Lückentext (Cloze)</strong> — für Prinzip 4: Prozesse und Zusammenhänge,
|
||||
bei denen der umgebende Satz als Kontext stehen bleibt.
|
||||
</li>
|
||||
<li>
|
||||
<strong>Bild-Karte</strong> — für Prinzip 5: Diagramme, Sketchnotes, annotierte
|
||||
Screenshots als eigenständiger Karteninhalt.
|
||||
</li>
|
||||
<li>
|
||||
<strong>Typing-Karte</strong> — erzwingt freies Erinnern statt
|
||||
Wiedererkennen; sinnvoll für Formeln, Fachbegriffe und exakte
|
||||
Definitionen, bei denen das Erkennen zu wenig ist.
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<p>
|
||||
Multiple Choice ist ebenfalls verfügbar — nützlich für erste Annäherungen an neues
|
||||
Material, wo freies Erinnern noch nicht möglich ist. Für konsolidiertes Wissen ist
|
||||
Wiedererkennen aus Optionen aber schwächer als freies Abrufen.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
In Arbeit: ein AI-Cloze-Generator, der aus einem eigenen Text direkt
|
||||
Lückentextkarten erstellt, und ein Card-Split-Vorschlag, der Karten mit
|
||||
mehreren Fakten automatisch zur Teilung vorschlägt. Beide Features sind noch nicht
|
||||
live — sie werden ergänzt, wenn sie auf einem Qualitätsniveau sind, das die
|
||||
oben beschriebenen Prinzipien nicht untergräbt.
|
||||
</p>
|
||||
|
||||
<!-- CTA -->
|
||||
<hr class="my-12 border-rule" />
|
||||
|
||||
<div class="rounded-xl border border-rule bg-paper p-8">
|
||||
<p class="font-serif text-2xl text-ink">Karten schreiben — in Cardecky</p>
|
||||
<p class="mt-3 text-muted leading-relaxed">
|
||||
Alle fünf Kartentypen verfügbar, FSRS-Scheduling ab der ersten Karte,
|
||||
kein Abo für das eigentliche Lernen.
|
||||
</p>
|
||||
<div class="mt-6 flex flex-wrap gap-4">
|
||||
<a href={APP_URL} class="btn-primary">
|
||||
Cardecky öffnen
|
||||
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true">
|
||||
<path d="M5 12h14M12 5l7 7-7 7"/>
|
||||
</svg>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</article>
|
||||
</main>
|
||||
|
||||
<Footer />
|
||||
</Layout>
|
||||
|
||||
<style>
|
||||
/* Prose-Styles für den Artikel — ohne externes @tailwindcss/typography */
|
||||
.prose-cardecky h2 {
|
||||
font-family: var(--font-serif, Georgia, serif);
|
||||
font-size: 1.375rem;
|
||||
font-weight: 600;
|
||||
color: theme('colors.ink');
|
||||
margin-top: 2.5rem;
|
||||
margin-bottom: 0.75rem;
|
||||
line-height: 1.3;
|
||||
}
|
||||
|
||||
.prose-cardecky p {
|
||||
color: theme('colors.ink');
|
||||
line-height: 1.75;
|
||||
margin-bottom: 1.25rem;
|
||||
}
|
||||
|
||||
.prose-cardecky ul,
|
||||
.prose-cardecky ol {
|
||||
margin-bottom: 1.25rem;
|
||||
padding-left: 1.5rem;
|
||||
}
|
||||
|
||||
.prose-cardecky ul {
|
||||
list-style-type: disc;
|
||||
}
|
||||
|
||||
.prose-cardecky ol {
|
||||
list-style-type: decimal;
|
||||
}
|
||||
|
||||
.prose-cardecky li {
|
||||
color: theme('colors.ink');
|
||||
line-height: 1.75;
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
|
||||
.prose-cardecky li + li {
|
||||
margin-top: 0.375rem;
|
||||
}
|
||||
|
||||
.prose-cardecky strong {
|
||||
font-weight: 600;
|
||||
color: theme('colors.ink');
|
||||
}
|
||||
|
||||
.prose-cardecky a {
|
||||
color: theme('colors.leaf');
|
||||
text-decoration: underline;
|
||||
text-underline-offset: 2px;
|
||||
}
|
||||
|
||||
.prose-cardecky a:hover {
|
||||
color: theme('colors.ink');
|
||||
}
|
||||
|
||||
.prose-cardecky hr {
|
||||
border-color: theme('colors.rule');
|
||||
}
|
||||
|
||||
.prose-cardecky pre {
|
||||
font-family: var(--font-mono, ui-monospace, monospace);
|
||||
font-size: 0.875rem;
|
||||
line-height: 1.6;
|
||||
background-color: theme('colors.paper');
|
||||
border: 1px solid theme('colors.rule');
|
||||
border-radius: 0.5rem;
|
||||
padding: 1rem 1.25rem;
|
||||
margin-bottom: 1.25rem;
|
||||
overflow-x: auto;
|
||||
color: theme('colors.ink');
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
|
||||
.prose-cardecky code {
|
||||
font-family: var(--font-mono, ui-monospace, monospace);
|
||||
font-size: 0.875em;
|
||||
background-color: theme('colors.paper');
|
||||
border: 1px solid theme('colors.rule');
|
||||
border-radius: 0.25rem;
|
||||
padding: 0.1em 0.35em;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -1,97 +0,0 @@
|
|||
---
|
||||
import Layout from '../../layouts/Layout.astro';
|
||||
import Nav from '../../components/Nav.astro';
|
||||
import Footer from '../../components/Footer.astro';
|
||||
import '../../styles/base.css';
|
||||
|
||||
const posts = [
|
||||
{
|
||||
href: '/blog/quizlet-paywall',
|
||||
tag: 'Migration',
|
||||
title: 'Quizlet zieht die Paywall hoch — was jetzt?',
|
||||
summary:
|
||||
'Fünf Millionen Nutzer:innen haben Quizlet in den letzten zwei Jahren verlassen. Was hinter der Bezahlschranke steckt und wie der Wechsel in wenigen Minuten klappt.',
|
||||
date: 'Mai 2026',
|
||||
},
|
||||
{
|
||||
href: '/blog/fsrs-algorithmus',
|
||||
tag: 'Algorithmus',
|
||||
title: 'Weniger lernen, mehr behalten: Was FSRS bedeutet',
|
||||
summary:
|
||||
'FSRS reduziert die nötigen Wiederholungen um 20–30 % bei gleicher Retention. Wie der Algorithmus funktioniert — und warum er bei anderen Apps noch nicht der Standard ist.',
|
||||
date: 'Mai 2026',
|
||||
},
|
||||
{
|
||||
href: '/blog/deine-daten',
|
||||
tag: 'Datenschutz',
|
||||
title: 'Deine Karten, deine Daten',
|
||||
summary:
|
||||
'Lerndaten verraten mehr als die meisten ahnen. Was Cardecky damit macht — und was nicht — lässt sich im öffentlichen Quellcode nachprüfen.',
|
||||
date: 'Mai 2026',
|
||||
},
|
||||
{
|
||||
href: '/blog/anki-zu-kompliziert',
|
||||
tag: 'Vergleich',
|
||||
title: 'Anki ist mächtig — und trotzdem schwer empfehlbar',
|
||||
summary:
|
||||
'Anki ist technisch überlegen. Trotzdem hören die meisten auf — nicht wegen des Algorithmus, sondern wegen Interface und Lernkurve.',
|
||||
date: 'Mai 2026',
|
||||
},
|
||||
{
|
||||
href: '/blog/gute-lernkarten',
|
||||
tag: 'Lernen',
|
||||
title: 'Wie man Lernkarten schreibt, die wirklich funktionieren',
|
||||
summary:
|
||||
'Der beste Algorithmus nützt nichts, wenn die Karten schlecht gebaut sind. Fünf Prinzipien — mit Gegenbeispielen.',
|
||||
date: 'Mai 2026',
|
||||
},
|
||||
] as const;
|
||||
---
|
||||
|
||||
<Layout
|
||||
title="Artikel — Cardecky"
|
||||
description="Hintergrund und Methodik rund um Spaced Repetition, Lernkarten und die Cardecky-App."
|
||||
>
|
||||
<Nav />
|
||||
|
||||
<main class="mx-auto max-w-content px-6 py-16 sm:py-24">
|
||||
<p class="section-label">Blog</p>
|
||||
<h1 class="mt-3 font-serif text-display text-ink">Artikel.</h1>
|
||||
<p class="mt-4 max-w-prose text-muted">
|
||||
Hintergrund zu Spaced Repetition, Vergleiche mit anderen Apps und Methodik
|
||||
für besseres Lernen.
|
||||
</p>
|
||||
|
||||
<ul class="mt-12 space-y-4" role="list">
|
||||
{posts.map((post) => (
|
||||
<li>
|
||||
<a
|
||||
href={post.href}
|
||||
class="group flex flex-col gap-2 rounded-xl border border-rule bg-paper p-6 transition-shadow hover:shadow-md sm:flex-row sm:items-start sm:gap-8"
|
||||
>
|
||||
<div class="flex shrink-0 items-center gap-3 sm:w-40 sm:flex-col sm:items-start sm:gap-1">
|
||||
<span class="section-label">{post.tag}</span>
|
||||
<span class="text-xs text-muted">{post.date}</span>
|
||||
</div>
|
||||
<div class="flex-1">
|
||||
<p class="font-serif text-xl font-semibold leading-snug text-ink group-hover:text-leaf transition-colors">
|
||||
{post.title}
|
||||
</p>
|
||||
<p class="mt-2 text-sm leading-relaxed text-muted">
|
||||
{post.summary}
|
||||
</p>
|
||||
</div>
|
||||
<span class="hidden shrink-0 items-center gap-1 text-sm font-medium text-leaf sm:flex">
|
||||
Lesen
|
||||
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true">
|
||||
<path d="M5 12h14M12 5l7 7-7 7"/>
|
||||
</svg>
|
||||
</span>
|
||||
</a>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</main>
|
||||
|
||||
<Footer />
|
||||
</Layout>
|
||||
|
|
@ -1,309 +0,0 @@
|
|||
---
|
||||
import Layout from '../../layouts/Layout.astro';
|
||||
import Nav from '../../components/Nav.astro';
|
||||
import Footer from '../../components/Footer.astro';
|
||||
import '../../styles/base.css';
|
||||
|
||||
const APP_URL = 'https://cardecky.mana.how';
|
||||
const IMPORT_URL = 'https://cardecky.mana.how/import';
|
||||
|
||||
const title = 'Quizlet zieht die Paywall hoch — was jetzt? | Cardecky';
|
||||
const description =
|
||||
'Quizlet hat 2022–2023 Learn Mode, Test Mode und echtes Spaced Repetition hinter eine' +
|
||||
' Bezahlschranke gesperrt. Was das konkret bedeutet — und wie der Wechsel zu Cardecky in' +
|
||||
' wenigen Minuten klappt.';
|
||||
---
|
||||
|
||||
<Layout {title} {description}>
|
||||
<Nav />
|
||||
|
||||
<main class="mx-auto max-w-prose px-6 py-16 sm:py-24">
|
||||
|
||||
<!-- Artikel-Header -->
|
||||
<header class="mb-12">
|
||||
<p class="section-label mb-4">Lernkarten · Migration</p>
|
||||
<h1 class="font-serif text-4xl leading-tight text-ink sm:text-5xl">
|
||||
Quizlet zieht die Paywall hoch — was jetzt?
|
||||
</h1>
|
||||
<p class="mt-5 text-lg leading-relaxed text-muted">
|
||||
Millionen von Nutzer:innen haben jahrelang auf Quizlet gelernt. Dann kam die
|
||||
Bezahlschranke. Was dahintersteckt, was du verloren hast — und wie du in wenigen Minuten
|
||||
auf Cardecky umziehst.
|
||||
</p>
|
||||
<p class="mt-4 text-xs text-muted">Stand: Mai 2026</p>
|
||||
</header>
|
||||
|
||||
<article class="prose-cardecky">
|
||||
|
||||
<!-- 1 -->
|
||||
<h2>Was Quizlet getan hat</h2>
|
||||
|
||||
<p>
|
||||
Quizlet startete 2005 als Karteikarten-Tool ohne Geschäftsmodell. Das hat sich geändert.
|
||||
2022 und 2023 hat das Unternehmen schrittweise die Kern-Lernmodi — Learn Mode, Test Mode
|
||||
und den zugehörigen Scheduling-Algorithmus — hinter ein Abo (Quizlet Plus,
|
||||
$35.99/Jahr) gesperrt. Wer nicht zahlt, kann Karten ansehen und in simplen
|
||||
Karteikarten-Ansichten blättern. Der eigentliche Lernmechanismus, der aus dem
|
||||
Blättern ein gezieltes Üben macht, ist nur noch für Zahler zugänglich.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Quizlet hat das nicht als Einschnitt kommuniziert, sondern als
|
||||
„Premium-Erweiterung". Die Realität: wer sich über Monate eine Karten-Sammlung
|
||||
aufgebaut hat, kann diese ohne Abo kaum noch sinnvoll nutzen.
|
||||
</p>
|
||||
|
||||
<!-- 2 -->
|
||||
<h2>Was konkret hinter der Paywall verschwunden ist</h2>
|
||||
|
||||
<p>
|
||||
Das sind keine Randfeatures. Learn Mode ist der Modus, der Quizlet überhaupt vom
|
||||
einfachen Karteikarten-Blättern unterscheidet: er verfolgt deinen Fortschritt,
|
||||
wiederholt Karten, die du falsch beantwortest hast, und passt die Reihenfolge
|
||||
deiner Lernkarten dynamisch an. Test Mode erstellt automatisierte Prüfungs-
|
||||
Simulationen aus deinen Sets. Ohne diese Modi ist Quizlet ein Karten-Viewer —
|
||||
nützlich zum Nachschlagen, nicht zum Lernen.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Hinzu kommt: Quizlet sammelt Nutzungsdaten und schaltet Werbung für Nicht-Zahler.
|
||||
Der Code ist proprietär — du kannst nicht nachprüfen, welche Daten wohin gehen.
|
||||
Und Daten-Export gibt es nur in begrenztem Umfang; wer zu einem anderen Dienst
|
||||
wechseln will, hat keine einfache Brücke.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Rund fünf Millionen Nutzer:innen haben in den vergangenen zwei Jahren aktiv nach
|
||||
Alternativen gesucht. Das ist kein Protest, sondern eine vernünftige Reaktion
|
||||
darauf, dass ein Werkzeug, auf das man sich verlassen hatte, unter den Händen
|
||||
wegbricht.
|
||||
</p>
|
||||
|
||||
<!-- 3 -->
|
||||
<h2>Was „echtes Spaced Repetition" bedeutet</h2>
|
||||
|
||||
<p>
|
||||
Spaced Repetition ist ein lernpsychologisches Prinzip: Karten, die du sicher
|
||||
weißt, siehst du seltener; Karten, bei denen du schwankst oder scheitern,
|
||||
kommen früher wieder. Der Effekt ist gut belegt — das Vergessen-Intervall passt
|
||||
sich an dein tatsächliches Erinnerungsvermögen an, statt nach fester Reihenfolge
|
||||
zu laufen.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Die Qualität hängt am Algorithmus. Quizlets hauseigene Implementierung war eine
|
||||
vereinfachte Variante. Der heute wissenschaftlich bevorzugte Standard ist
|
||||
<strong>FSRS</strong> (Free Spaced Repetition Scheduler) — entwickelt 2022 von
|
||||
Jarrett Ye, inzwischen in mehreren Studien gegen ältere Algorithmen getestet,
|
||||
standardmäßig in Anki 23.10+ enthalten. FSRS modelliert zwei Gedächtnisparameter
|
||||
pro Karte (Stabilität und Abrufbarkeit) und passt die Wiederholungsabstände
|
||||
präziser an als frühere Verfahren.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Cardecky implementiert FSRS direkt — nicht als nachträgliches Feature, sondern
|
||||
als Kern des Scheduling-Systems ab Tag 1.
|
||||
</p>
|
||||
|
||||
<!-- 4 -->
|
||||
<h2>Cardecky als Alternative — was wir bieten und was noch fehlt</h2>
|
||||
|
||||
<p>
|
||||
Cardecky ist die Spaced-Repetition-App des mana e.V., eines Schweizer Vereins.
|
||||
Das ist keine Marketing-Formel, sondern eine Aussage über das Geschäftsmodell:
|
||||
kein Investor, kein Renditedruck, keine Exit-Strategie. Die App läuft auf
|
||||
selbst-betriebener Infrastruktur in Deutschland.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Was heute verfügbar ist:
|
||||
</p>
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
<strong>FSRS-Algorithmus</strong> — aktueller Stand der Forschung, serverside
|
||||
berechnet, keine Näherungslösung.
|
||||
</li>
|
||||
<li>
|
||||
<strong>Sechs Kartentypen</strong> — Vorderseite/Rückseite, Lückentext, Multiple
|
||||
Choice, Bild, Tipp-Karte, Rich Text.
|
||||
</li>
|
||||
<li>
|
||||
<strong>Quizlet-Import</strong> — direkt eingebaut. Deine Sets landen in Minuten
|
||||
in Cardecky, mit Formatierung.
|
||||
</li>
|
||||
<li>
|
||||
<strong>Anki-Import</strong> — .apkg-Dateien werden geparst, Decks und Karten
|
||||
übernommen.
|
||||
</li>
|
||||
<li>
|
||||
<strong>Kein Tracking, keine Werbung</strong> — kein Analytics-Code, nachweisbar
|
||||
im öffentlichen Quellcode unter
|
||||
<a href="https://git.mana.how/mana/cards" target="_blank" rel="noopener">
|
||||
git.mana.how/mana/cards</a>.
|
||||
</li>
|
||||
<li>
|
||||
<strong>Anti-Lock-in per Design</strong> — Export jederzeit als .apkg, CSV
|
||||
oder DSGVO-Vollexport. Wir bauen keine Karte, die du nicht mitnehmen kannst.
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<p>
|
||||
Was noch fehlt, und das soll hier nicht versteckt werden: Cardecky ist jung.
|
||||
Eine native App (iOS/Android) ist in Planung, aber noch nicht verfügbar — heute
|
||||
ist Cardecky eine Web-App, installierbar als PWA. Die kuratierte Deck-Bibliothek
|
||||
wächst; wer spezifische Fachbereiche sucht, findet dort heute noch Lücken.
|
||||
Kollaborative Decks im Team sind auf der Roadmap, noch nicht live. Wer eine
|
||||
ausgereifte Desktop-App mit jahrelanger Community erwartet, sollte auch Anki
|
||||
in Betracht ziehen — das ist keine Schwäche, sondern ein Hinweis auf den
|
||||
unterschiedlichen Stand.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Die Kernfunktionen — Karten anlegen, lernen, importieren, exportieren — sind
|
||||
vollständig und ohne Bezahlschranke zugänglich. Tiers gibt es nur für
|
||||
KI-gestützte Features (automatische Kartengenerierung, Erklärungen via mana LLM)
|
||||
und erweiterten Storage. Das eigentliche Lernen ist und bleibt kostenlos.
|
||||
</p>
|
||||
|
||||
<!-- 5 -->
|
||||
<h2>Migration in drei Schritten</h2>
|
||||
|
||||
<p>
|
||||
Der Wechsel von Quizlet zu Cardecky dauert je nach Set-Größe fünf bis fünfzehn
|
||||
Minuten.
|
||||
</p>
|
||||
|
||||
<ol>
|
||||
<li>
|
||||
<strong>Quizlet-Export vorbereiten.</strong> Öffne in Quizlet das Set, das du
|
||||
mitnehmen willst. Unter „Mehr" → „Exportieren" kannst du das Set als
|
||||
Tab-getrennte Textdatei herunterladen. Quizlet bietet diesen Export auch ohne
|
||||
Plus-Abo an.
|
||||
</li>
|
||||
<li>
|
||||
<strong>In Cardecky importieren.</strong> Gehe auf
|
||||
<a href={IMPORT_URL} target="_blank" rel="noopener">cardecky.mana.how/import</a>
|
||||
und wähle „Quizlet-Import". Lade die Textdatei hoch oder füge den Text direkt
|
||||
ein — Cardecky erkennt das Format automatisch und zeigt dir vor dem Import eine
|
||||
Vorschau der Karten.
|
||||
</li>
|
||||
<li>
|
||||
<strong>Deck einrichten und starten.</strong> Nach dem Import landet das Deck in
|
||||
deiner Bibliothek. FSRS-Scheduling startet automatisch beim ersten Lernen. Du
|
||||
musst nichts konfigurieren — das System passt sich anhand deiner Antworten an.
|
||||
</li>
|
||||
</ol>
|
||||
|
||||
<p>
|
||||
Wer bereits Anki-Decks hat, kann alternativ .apkg-Dateien direkt hochladen — der
|
||||
Import-Flow ist derselbe.
|
||||
</p>
|
||||
|
||||
<!-- 6 -->
|
||||
<h2>Datenschutz und Unabhängigkeit</h2>
|
||||
|
||||
<p>
|
||||
Cardecky wird von mana e.V. betrieben — einem Schweizer Verein ohne Investoren,
|
||||
ohne Werbepartner, ohne Renditeziel. Server stehen in Deutschland, Datenverarbeitung
|
||||
läuft ausschließlich auf Vereinsinfrastruktur. Es gibt keinen Analytics-Code,
|
||||
keinen Tracking-Pixel, keine Drittanbieter-SDK für Nutzungsauswertung. Das lässt
|
||||
sich im öffentlichen Quellcode nachprüfen.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Daten-Souveränität ist für mana kein Marketingversprechen, sondern Wert 1 in der
|
||||
Werte-Hierarchie des Vereins: Daten gehören den Nutzer:innen, nicht uns. Jederzeit
|
||||
Export, jederzeit Löschung, DSGVO-Auskunft auf Knopfdruck. Diese Versprechen
|
||||
stehen in den Vereinsstatuten und können nicht durch eine Unternehmens-Übernahme
|
||||
wegverhandelt werden — weil es keine Unternehmensanteile gibt, die man kaufen
|
||||
könnte.
|
||||
</p>
|
||||
|
||||
<!-- CTA -->
|
||||
<hr class="my-12 border-rule" />
|
||||
|
||||
<div class="rounded-xl border border-rule bg-paper p-8">
|
||||
<p class="font-serif text-2xl text-ink">Bereit für den Wechsel?</p>
|
||||
<p class="mt-3 text-muted leading-relaxed">
|
||||
Import deiner Quizlet-Sets dauert wenige Minuten. Kein Abo, kein
|
||||
Kreditkartenfeld, keine Fallstricke.
|
||||
</p>
|
||||
<div class="mt-6 flex flex-wrap gap-4">
|
||||
<a href={APP_URL} class="btn-primary">
|
||||
Cardecky öffnen
|
||||
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true">
|
||||
<path d="M5 12h14M12 5l7 7-7 7"/>
|
||||
</svg>
|
||||
</a>
|
||||
<a href={IMPORT_URL} class="btn-ghost">Direkt zum Import</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</article>
|
||||
</main>
|
||||
|
||||
<Footer />
|
||||
</Layout>
|
||||
|
||||
<style>
|
||||
/* Prose-Styles für den Artikel — ohne externes @tailwindcss/typography */
|
||||
.prose-cardecky h2 {
|
||||
font-family: var(--font-serif, Georgia, serif);
|
||||
font-size: 1.375rem;
|
||||
font-weight: 600;
|
||||
color: theme('colors.ink');
|
||||
margin-top: 2.5rem;
|
||||
margin-bottom: 0.75rem;
|
||||
line-height: 1.3;
|
||||
}
|
||||
|
||||
.prose-cardecky p {
|
||||
color: theme('colors.ink');
|
||||
line-height: 1.75;
|
||||
margin-bottom: 1.25rem;
|
||||
}
|
||||
|
||||
.prose-cardecky ul,
|
||||
.prose-cardecky ol {
|
||||
margin-bottom: 1.25rem;
|
||||
padding-left: 1.5rem;
|
||||
}
|
||||
|
||||
.prose-cardecky ul {
|
||||
list-style-type: disc;
|
||||
}
|
||||
|
||||
.prose-cardecky ol {
|
||||
list-style-type: decimal;
|
||||
}
|
||||
|
||||
.prose-cardecky li {
|
||||
color: theme('colors.ink');
|
||||
line-height: 1.75;
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
|
||||
.prose-cardecky li + li {
|
||||
margin-top: 0.375rem;
|
||||
}
|
||||
|
||||
.prose-cardecky strong {
|
||||
font-weight: 600;
|
||||
color: theme('colors.ink');
|
||||
}
|
||||
|
||||
.prose-cardecky a {
|
||||
color: theme('colors.leaf');
|
||||
text-decoration: underline;
|
||||
text-underline-offset: 2px;
|
||||
}
|
||||
|
||||
.prose-cardecky a:hover {
|
||||
color: theme('colors.ink');
|
||||
}
|
||||
|
||||
.prose-cardecky hr {
|
||||
border-color: theme('colors.rule');
|
||||
}
|
||||
</style>
|
||||
|
|
@ -1,29 +0,0 @@
|
|||
---
|
||||
import Layout from '../layouts/Layout.astro';
|
||||
import Nav from '../components/Nav.astro';
|
||||
import Hero from '../components/Hero.astro';
|
||||
import CardTypes from '../components/CardTypes.astro';
|
||||
import HowItWorks from '../components/HowItWorks.astro';
|
||||
import Features from '../components/Features.astro';
|
||||
import ManaSection from '../components/ManaSection.astro';
|
||||
import BlogTeaser from '../components/BlogTeaser.astro';
|
||||
import CTASection from '../components/CTASection.astro';
|
||||
import Footer from '../components/Footer.astro';
|
||||
import '../styles/base.css';
|
||||
---
|
||||
<Layout
|
||||
title="Cardecky — Lernkarten mit FSRS-Spaced-Repetition · mana e.V."
|
||||
description="Cardecky ist eine freie Spaced-Repetition-App des mana e.V. Sechs Kartentypen, FSRS-Algorithmus, Anki-Import und eine kuratierte Bibliothek — ohne Tracking, ohne Abo."
|
||||
>
|
||||
<Nav />
|
||||
<main>
|
||||
<Hero />
|
||||
<CardTypes />
|
||||
<HowItWorks />
|
||||
<Features />
|
||||
<ManaSection />
|
||||
<BlogTeaser />
|
||||
<CTASection />
|
||||
</main>
|
||||
<Footer />
|
||||
</Layout>
|
||||
|
|
@ -1,26 +0,0 @@
|
|||
@tailwind base;
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
|
||||
html {
|
||||
scroll-behavior: smooth;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
}
|
||||
|
||||
body {
|
||||
overflow-x: hidden;
|
||||
background-color: theme('colors.paper');
|
||||
color: theme('colors.ink');
|
||||
}
|
||||
|
||||
@layer components {
|
||||
.btn-primary {
|
||||
@apply inline-flex items-center gap-2 rounded-lg bg-leaf px-5 py-2.5 text-sm font-medium text-white transition-colors hover:bg-leaf-hover focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-leaf focus-visible:ring-offset-2;
|
||||
}
|
||||
.btn-ghost {
|
||||
@apply inline-flex items-center gap-2 rounded-lg border border-rule px-5 py-2.5 text-sm font-medium text-ink transition-colors hover:border-muted hover:bg-rule focus-visible:outline-none;
|
||||
}
|
||||
.section-label {
|
||||
@apply text-xs font-semibold uppercase tracking-widest text-leaf;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,31 +0,0 @@
|
|||
/** @type {import('tailwindcss').Config} */
|
||||
module.exports = {
|
||||
content: ['./src/**/*.{astro,html,js,jsx,ts,tsx}'],
|
||||
theme: {
|
||||
extend: {
|
||||
colors: {
|
||||
ink: '#111812',
|
||||
paper: '#f9faf7',
|
||||
muted: '#6b7a6e',
|
||||
rule: '#e2e8e0',
|
||||
leaf: '#16a34a',
|
||||
'leaf-hover': '#15803d',
|
||||
'leaf-light': '#f0fdf4',
|
||||
'leaf-border': '#bbf7d0',
|
||||
},
|
||||
fontFamily: {
|
||||
serif: ['Georgia', 'Cambria', '"Times New Roman"', 'serif'],
|
||||
sans: ['system-ui', '-apple-system', 'sans-serif'],
|
||||
},
|
||||
fontSize: {
|
||||
hero: ['clamp(2.25rem,5vw,3.5rem)', { lineHeight: '1.1', letterSpacing: '-0.02em' }],
|
||||
display: ['clamp(1.75rem,3vw,2.5rem)', { lineHeight: '1.2', letterSpacing: '-0.015em' }],
|
||||
},
|
||||
maxWidth: {
|
||||
content: '68rem',
|
||||
prose: '44rem',
|
||||
},
|
||||
},
|
||||
},
|
||||
plugins: [],
|
||||
};
|
||||
|
|
@ -1,5 +0,0 @@
|
|||
{
|
||||
"extends": "astro/tsconfigs/strict",
|
||||
"include": [".astro/types.d.ts", "**/*"],
|
||||
"exclude": ["dist"]
|
||||
}
|
||||
|
|
@ -18,7 +18,7 @@ export function exportToCsv(cards: Card[]): string {
|
|||
front = f.front ?? '';
|
||||
back = f.back ?? '';
|
||||
} else {
|
||||
// image-occlusion, audio-front etc. — not representable in CSV
|
||||
// Wordeck ist text-only — alle Card-Types sind CSV-darstellbar
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -180,7 +180,7 @@ export const de: TranslationNode = {
|
|||
what_skipped_title: 'Was nicht übernommen wird',
|
||||
what_skipped_media: '— (Bilder + Audio werden seit Phase 9k mit übernommen, siehe oben)',
|
||||
what_skipped_history: 'FSRS-Lernverlauf (Anki-Reviews werden bewusst neu aufgesetzt).',
|
||||
what_skipped_addons: 'Add-on-spezifische Card-Types (image-occlusion etc.).',
|
||||
what_skipped_addons: 'Add-on-spezifische Card-Types (nicht Teil von Wordeck text-only).',
|
||||
anki_label: 'Aus Anki importieren',
|
||||
dropzone: '📦 .apkg-Datei hier ablegen oder klicken',
|
||||
dropzone_hint: 'Basic, Basic + Reverse, Cloze · Bilder + Audio werden mit übernommen (Limit 25 MB pro Datei).',
|
||||
|
|
|
|||
|
|
@ -177,7 +177,7 @@ export const en: TranslationNode = {
|
|||
what_skipped_title: 'What is not imported',
|
||||
what_skipped_media: '— (Images + audio are imported since Sprint 9k, see above)',
|
||||
what_skipped_history: 'FSRS learning history (Anki reviews are deliberately reset).',
|
||||
what_skipped_addons: 'Add-on specific card types (image-occlusion etc.).',
|
||||
what_skipped_addons: 'Add-on specific card types (non-text etc.).',
|
||||
anki_label: 'Import from Anki',
|
||||
dropzone: '📦 Drop .apkg file here or click',
|
||||
dropzone_hint: 'Basic, Basic + Reverse, Cloze · Images + audio are imported too (limit 25 MB per file).',
|
||||
|
|
|
|||
|
|
@ -143,12 +143,6 @@ export function subIndexCount(type: string): number {
|
|||
return 2;
|
||||
case 'type-in':
|
||||
return 1;
|
||||
case 'image-occlusion':
|
||||
throw new Error(
|
||||
'subIndexCount("image-occlusion") not supported — use maskRegionCount(fields.mask_regions) from @cards/domain'
|
||||
);
|
||||
case 'audio-front':
|
||||
return 1;
|
||||
case 'typing':
|
||||
return 1;
|
||||
case 'multiple-choice':
|
||||
|
|
|
|||
|
|
@ -85,10 +85,6 @@ describe('subIndexCount', () => {
|
|||
it('cloze wirft — Caller muss subIndexCountForCloze nutzen', () => {
|
||||
expect(() => subIndexCount('cloze')).toThrow(/subIndexCountForCloze/);
|
||||
});
|
||||
|
||||
it('image-occlusion wirft — Caller muss maskRegionCount nutzen', () => {
|
||||
expect(() => subIndexCount('image-occlusion')).toThrow(/maskRegionCount/);
|
||||
});
|
||||
});
|
||||
|
||||
describe('buildScheduler', () => {
|
||||
|
|
|
|||
|
|
@ -11,17 +11,18 @@ import {
|
|||
} from '../src/schemas/index.ts';
|
||||
|
||||
describe('CardTypeSchema', () => {
|
||||
it('accepts MVP types', () => {
|
||||
it('accepts Wordeck text-only types', () => {
|
||||
expect(() => CardTypeSchema.parse('basic')).not.toThrow();
|
||||
expect(() => CardTypeSchema.parse('basic-reverse')).not.toThrow();
|
||||
expect(() => CardTypeSchema.parse('cloze')).not.toThrow();
|
||||
expect(() => CardTypeSchema.parse('image-occlusion')).not.toThrow();
|
||||
expect(() => CardTypeSchema.parse('typing')).not.toThrow();
|
||||
expect(() => CardTypeSchema.parse('multiple-choice')).not.toThrow();
|
||||
});
|
||||
|
||||
it('rejects future types not yet in MVP schema', () => {
|
||||
expect(() => CardTypeSchema.parse('type-in')).toThrow();
|
||||
it('rejects removed types (image-occlusion, audio-front)', () => {
|
||||
expect(() => CardTypeSchema.parse('image-occlusion')).toThrow();
|
||||
expect(() => CardTypeSchema.parse('audio-front')).toThrow();
|
||||
expect(() => CardTypeSchema.parse('audio')).toThrow();
|
||||
expect(() => CardTypeSchema.parse('multiple-choice')).toThrow();
|
||||
});
|
||||
});
|
||||
|
||||
|
|
@ -68,15 +69,6 @@ describe('CardCreateSchema', () => {
|
|||
expect(r.success).toBe(true);
|
||||
});
|
||||
|
||||
it('accepts an image-occlusion card with image_ref + mask_regions', () => {
|
||||
const r = CardCreateSchema.safeParse({
|
||||
deck_id: 'd-1',
|
||||
type: 'image-occlusion',
|
||||
fields: { image_ref: 'media-id', mask_regions: '[]' },
|
||||
});
|
||||
expect(r.success).toBe(true);
|
||||
});
|
||||
|
||||
it('rejects unknown type via CardTypeSchema', () => {
|
||||
const r = CardCreateSchema.safeParse({
|
||||
deck_id: 'd-1',
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue