From 709ae125460d9669e9562324b5043da0d8a9133e Mon Sep 17 00:00:00 2001 From: hermes Date: Sun, 19 Apr 2026 20:41:10 +0000 Subject: [PATCH] Initial MatheLeicht Astro app --- src/components/ExerciseCard.astro | 12 + src/components/ExerciseTrainer.astro | 400 ++++++++++++++++++ src/data/exercises.ts | 130 ++++++ src/data/site.ts | 13 + src/layouts/BaseLayout.astro | 57 +++ src/pages/aufgaben/[slug].astro | 21 + src/pages/datenschutz.astro | 37 ++ src/pages/impressum.astro | 35 ++ src/pages/index.astro | 88 +++- src/styles/global.css | 582 +++++++++++++++++++++++++++ 10 files changed, 1361 insertions(+), 14 deletions(-) create mode 100644 src/components/ExerciseCard.astro create mode 100644 src/components/ExerciseTrainer.astro create mode 100644 src/data/exercises.ts create mode 100644 src/data/site.ts create mode 100644 src/layouts/BaseLayout.astro create mode 100644 src/pages/aufgaben/[slug].astro create mode 100644 src/pages/datenschutz.astro create mode 100644 src/pages/impressum.astro create mode 100644 src/styles/global.css diff --git a/src/components/ExerciseCard.astro b/src/components/ExerciseCard.astro new file mode 100644 index 0000000..002d1cc --- /dev/null +++ b/src/components/ExerciseCard.astro @@ -0,0 +1,12 @@ +--- +import type { Exercise } from '../data/exercises'; + +const { exercise } = Astro.props as { exercise: Exercise }; +--- + +
+
{exercise.category}
+

{exercise.title}

+

{exercise.short}

+ Aufgabe öffnen → +
diff --git a/src/components/ExerciseTrainer.astro b/src/components/ExerciseTrainer.astro new file mode 100644 index 0000000..9f6c617 --- /dev/null +++ b/src/components/ExerciseTrainer.astro @@ -0,0 +1,400 @@ +--- +import type { Exercise } from '../data/exercises'; + +const { exercise } = Astro.props as { exercise: Exercise }; +const config = JSON.stringify(exercise); +--- + +
+ + +
+
+ +
+
1 / 10
+
7 + 5 = ?
+
Wähle die richtige Antwort
+ +
+ + +
+ + + + +
+
🎉
+

Gut gemacht!

+

Du hast 0 von 10 Aufgaben richtig gelöst.

+
+ + Zur Startseite +
+
+
+
+ + + + diff --git a/src/data/exercises.ts b/src/data/exercises.ts new file mode 100644 index 0000000..0fc50b5 --- /dev/null +++ b/src/data/exercises.ts @@ -0,0 +1,130 @@ +export type Level = { + id: string; + label: string; + min: number; + max: number; +}; + +export type Exercise = { + slug: string; + title: string; + category: 'Grundschule' | 'Jugendliche' | 'Erwachsene'; + categoryIntro: string; + short: string; + description: string; + operation: 'addition' | 'subtraction' | 'multiplication' | 'division' | 'percentage'; + accent: 'coral' | 'lavender' | 'mint' | 'yellow'; + levels: Level[]; +}; + +export const exercises: Exercise[] = [ + { + slug: 'addieren-bis-20', + title: 'Addieren bis 20', + category: 'Grundschule', + categoryIntro: 'Für erste Plusaufgaben mit kleinen Zahlen und schnellen Erfolgserlebnissen.', + short: 'Einfache Plusaufgaben für Kinder in der Grundschule.', + description: 'Ideal für einen lockeren Einstieg: kleine Summen, klares Feedback und kurze Übungsrunden.', + operation: 'addition', + accent: 'coral', + levels: [ + { id: 'leicht', label: 'Leicht', min: 1, max: 10 }, + { id: 'mittel', label: 'Mittel', min: 1, max: 20 }, + { id: 'knifflig', label: 'Knifflig', min: 5, max: 20 }, + ], + }, + { + slug: 'subtrahieren-bis-100', + title: 'Subtrahieren bis 100', + category: 'Grundschule', + categoryIntro: 'Minusaufgaben Schritt für Schritt mit passenden Zahlenbereichen.', + short: 'Subtraktion üben – vom kleinen Rechnen bis zu größeren Zahlen.', + description: 'Geeignet zum Festigen von Minusaufgaben mit verständlichen Schwierigkeitsstufen.', + operation: 'subtraction', + accent: 'yellow', + levels: [ + { id: 'leicht', label: 'Leicht', min: 1, max: 20 }, + { id: 'mittel', label: 'Mittel', min: 10, max: 50 }, + { id: 'stark', label: 'Stark', min: 20, max: 100 }, + ], + }, + { + slug: 'einmaleins', + title: 'Kleines Einmaleins', + category: 'Grundschule', + categoryIntro: 'Das Einmaleins mit spielerischem Tempo festigen.', + short: 'Malaufgaben für die wichtigsten Reihen und sichere Grundlagen.', + description: 'Trainiert das schnelle Wiedererkennen von Multiplikationsaufgaben und Ergebnissen.', + operation: 'multiplication', + accent: 'lavender', + levels: [ + { id: 'leicht', label: 'Leicht', min: 1, max: 5 }, + { id: 'mittel', label: 'Mittel', min: 2, max: 10 }, + { id: 'stark', label: 'Stark', min: 4, max: 12 }, + ], + }, + { + slug: 'dividieren', + title: 'Dividieren ohne Rest', + category: 'Jugendliche', + categoryIntro: 'Geteilt-Aufgaben mit glatten Ergebnissen und klaren Mustern.', + short: 'Division üben, ohne sich direkt mit Resten aufzuhalten.', + description: 'Eine gute Zwischenstufe für Lernende, die sicher mit Malaufgaben werden wollen.', + operation: 'division', + accent: 'mint', + levels: [ + { id: 'leicht', label: 'Leicht', min: 2, max: 5 }, + { id: 'mittel', label: 'Mittel', min: 2, max: 10 }, + { id: 'stark', label: 'Stark', min: 3, max: 12 }, + ], + }, + { + slug: 'kopfrechnen', + title: 'Kopfrechnen Mix', + category: 'Jugendliche', + categoryIntro: 'Schnelle Aufgaben für ein besseres Gefühl für Zahlen.', + short: 'Gemischte Rechenaufgaben für mehr Sicherheit im Alltag und in der Schule.', + description: 'Abwechslung aus Plus, Minus und Mal – direkt im Browser, ohne Anmeldung.', + operation: 'addition', + accent: 'coral', + levels: [ + { id: 'leicht', label: 'Leicht', min: 5, max: 30 }, + { id: 'mittel', label: 'Mittel', min: 20, max: 80 }, + { id: 'stark', label: 'Stark', min: 50, max: 150 }, + ], + }, + { + slug: 'prozente-im-alltag', + title: 'Prozente im Alltag', + category: 'Erwachsene', + categoryIntro: 'Rabatte, Trinkgeld und einfache Prozentrechnungen sicher beherrschen.', + short: 'Praktische Prozentaufgaben für Alltag, Beruf und Einkauf.', + description: 'Trainiert typische Prozentrechnungen mit verständlichen Zahlen und direktem Feedback.', + operation: 'percentage', + accent: 'lavender', + levels: [ + { id: 'leicht', label: 'Leicht', min: 10, max: 100 }, + { id: 'mittel', label: 'Mittel', min: 20, max: 250 }, + { id: 'stark', label: 'Stark', min: 50, max: 500 }, + ], + }, +]; + +export function getExercise(slug: string) { + return exercises.find((exercise) => exercise.slug === slug); +} + +export const categories = [ + { + title: 'Grundschule', + intro: 'Spielerische Aufgaben für Kinder mit klarer Struktur, großen Zahlen und einfachem Feedback.', + }, + { + title: 'Jugendliche', + intro: 'Mehr Tempo, mehr Sicherheit und abwechslungsreiche Aufgaben für Schule und Alltag.', + }, + { + title: 'Erwachsene', + intro: 'Praktisches Rechnen für Alltagssituationen – ohne unnötigen Ballast und ohne Login.', + }, +] as const; diff --git a/src/data/site.ts b/src/data/site.ts new file mode 100644 index 0000000..e79927f --- /dev/null +++ b/src/data/site.ts @@ -0,0 +1,13 @@ +export const site = { + name: 'MatheLeicht', + url: 'https://matheleicht.de', + title: 'MatheLeicht – Einfach Mathe üben', + description: + 'MatheLeicht ist eine einfache Lernplattform für Kinder, Jugendliche und Erwachsene. Rechnen üben ohne Login – direkt im Browser.', + owner: 'Justin Michael Eckenweber', + email: 'hey@unverpackt-finder.de', + phone: '028160031948', + address1: 'Rühlestraße 5', + address2: '45147 Essen', + country: 'Deutschland', +}; diff --git a/src/layouts/BaseLayout.astro b/src/layouts/BaseLayout.astro new file mode 100644 index 0000000..9e60ed0 --- /dev/null +++ b/src/layouts/BaseLayout.astro @@ -0,0 +1,57 @@ +--- +import '../styles/global.css'; +import { site } from '../data/site'; + +interface Props { + title?: string; + description?: string; +} + +const { title = site.title, description = site.description } = Astro.props; +const canonical = new URL(Astro.url.pathname, site.url).toString(); +--- + + + + + + + + + + + + + + + + + + {title} + + + + +
+ +
+ + diff --git a/src/pages/aufgaben/[slug].astro b/src/pages/aufgaben/[slug].astro new file mode 100644 index 0000000..cbff6be --- /dev/null +++ b/src/pages/aufgaben/[slug].astro @@ -0,0 +1,21 @@ +--- +import BaseLayout from '../../layouts/BaseLayout.astro'; +import ExerciseTrainer from '../../components/ExerciseTrainer.astro'; +import { exercises } from '../../data/exercises'; + +export function getStaticPaths() { + return exercises.map((exercise) => ({ params: { slug: exercise.slug }, props: { exercise } })); +} + +const { exercise } = Astro.props; +--- + + +
+ ← Zurück zur Übersicht +
{exercise.category}
+

{exercise.title}

+

{exercise.description}

+ +
+
diff --git a/src/pages/datenschutz.astro b/src/pages/datenschutz.astro new file mode 100644 index 0000000..2bf6fbd --- /dev/null +++ b/src/pages/datenschutz.astro @@ -0,0 +1,37 @@ +--- +import BaseLayout from '../layouts/BaseLayout.astro'; +import { site } from '../data/site'; +--- + + +
+ +
+
diff --git a/src/pages/impressum.astro b/src/pages/impressum.astro new file mode 100644 index 0000000..947b6b6 --- /dev/null +++ b/src/pages/impressum.astro @@ -0,0 +1,35 @@ +--- +import BaseLayout from '../layouts/BaseLayout.astro'; +import { site } from '../data/site'; +--- + + +
+ +
+
diff --git a/src/pages/index.astro b/src/pages/index.astro index 561196b..177215b 100644 --- a/src/pages/index.astro +++ b/src/pages/index.astro @@ -1,17 +1,77 @@ --- +import BaseLayout from '../layouts/BaseLayout.astro'; +import ExerciseCard from '../components/ExerciseCard.astro'; +import { categories, exercises } from '../data/exercises'; +--- ---- + +
+
+
+
+
+
+
✨ Ohne Anmeldung · Direkt losrechnen
+

Mathe üben kann auch leicht und freundlich sein.

+

+ MatheLeicht ist eine kleine Lernplattform für einfache Rechenaufgaben. Kinder, Jugendliche und Erwachsene + können direkt im Browser üben – ohne Login, ohne Ablenkung, mit klaren Schwierigkeitsstufen. +

+ +
- - - - - - - - Astro - - -

Astro

- - +
+
Beispielaufgabe
+
8 + 7 = ?
+
+
13
+
15
+
17
+
16
+
+
⭐ Sofortiges Feedback
+
🔥 Kleine Erfolgsmomente
+
+
+
+ +
+
+
Kategorien
+

Für verschiedene Lernstände gemacht

+

+ Jede Kategorie ist so gedacht, dass sie sich natürlich anfühlt: einfache Grundlagen für Kinder, + alltagstaugliches Üben für Jugendliche und praktische Rechenaufgaben für Erwachsene. +

+ +
+ {categories.map((category) => ( +
+

{category.title}

+

{category.intro}

+
+ ))} +
+
+ +
+
Aufgaben
+

Wähle eine Übung und starte direkt

+ {categories.map((category) => { + const items = exercises.filter((exercise) => exercise.category === category.title); + return ( +
+

{category.title}

+

{category.intro}

+
+ {items.map((exercise) => )} +
+
+ ); + })} +
+
+
diff --git a/src/styles/global.css b/src/styles/global.css new file mode 100644 index 0000000..a40aef7 --- /dev/null +++ b/src/styles/global.css @@ -0,0 +1,582 @@ +body { + margin: 0; + font-family: 'Nunito Sans', system-ui, sans-serif; + background: #fdf8f0; + color: #3b2b1e; +} + +* { + box-sizing: border-box; +} + +a { + color: inherit; + text-decoration: none; +} + +:root { + --cream: #fdf8f0; + --coral: #ff8c65; + --coral-lt: #ffd4c2; + --lav: #b89ddb; + --lav-lt: #eae3f7; + --mint: #74c69d; + --mint-lt: #d4f1e4; + --yellow: #ffce63; + --yellow-lt: #fff3cc; + --ink: #3b2b1e; + --ink-mid: #7a5f4e; + --ink-soft: #b8a090; + --card-r: 24px; +} + +.container { + width: min(1180px, calc(100% - 32px)); + margin: 0 auto; +} + +nav.site-nav { + position: sticky; + top: 0; + z-index: 100; + display: flex; + align-items: center; + justify-content: space-between; + padding: 0 6vw; + height: 68px; + background: rgba(253, 248, 240, 0.88); + backdrop-filter: blur(12px); + border-bottom: 1.5px solid rgba(255, 140, 101, 0.15); +} + +.nav-logo { + font-family: 'Nunito', system-ui, sans-serif; + font-weight: 900; + font-size: 1.5rem; + color: var(--coral); +} + +.nav-logo .dot { + color: var(--lav); +} + +.nav-links { + display: flex; + gap: 1.5rem; + flex-wrap: wrap; + align-items: center; +} + +.nav-links a { + font-family: 'Nunito', system-ui, sans-serif; + font-weight: 700; + color: var(--ink-mid); +} + +.nav-links a:hover, +.footer-links a:hover, +.exercise-link:hover { + color: var(--coral); +} + +.nav-cta { + background: var(--coral); + color: white; + padding: 10px 18px; + border-radius: 999px; + font-family: 'Nunito', system-ui, sans-serif; + font-weight: 800; + box-shadow: 0 4px 16px rgba(255, 140, 101, 0.32); +} + +.hero { + position: relative; + overflow: hidden; + padding: 4.5rem 0 3rem; +} + +.hero-grid { + display: grid; + grid-template-columns: 1.1fr 0.9fr; + gap: 3rem; + align-items: center; +} + +.blob { + position: absolute; + border-radius: 50%; + filter: blur(80px); + opacity: 0.35; + pointer-events: none; +} + +.blob-1 { width: 520px; height: 520px; background: var(--coral-lt); top: -80px; right: -60px; } +.blob-2 { width: 340px; height: 340px; background: var(--lav-lt); bottom: 10px; left: -70px; } +.blob-3 { width: 260px; height: 260px; background: var(--mint-lt); top: 40%; right: 20%; } + +.hero-badge, +.section-badge { + display: inline-flex; + align-items: center; + gap: 8px; + background: var(--yellow-lt); + border: 1.5px solid var(--yellow); + color: #9b7a00; + font-family: 'Nunito', system-ui, sans-serif; + font-weight: 800; + font-size: 0.82rem; + padding: 7px 14px; + border-radius: 999px; + margin-bottom: 1.2rem; +} + +.hero h1 { + font-family: 'Nunito', system-ui, sans-serif; + font-size: clamp(2.5rem, 4.8vw, 4.2rem); + line-height: 1.08; + font-weight: 900; + margin: 0 0 1rem; +} + +.hero h1 em { + font-style: normal; + color: var(--coral); +} + +.hero p, +.section-intro, +.category-intro, +.card p, +li { + color: var(--ink-mid); + line-height: 1.7; +} + +.button-row { + display: flex; + gap: 1rem; + flex-wrap: wrap; + margin-top: 1.7rem; +} + +.button-primary, +.button-secondary, +.button-inline { + display: inline-flex; + align-items: center; + gap: 8px; + font-family: 'Nunito', system-ui, sans-serif; + font-weight: 800; + border-radius: 999px; +} + +.button-primary { + background: var(--coral); + color: white; + padding: 14px 26px; + box-shadow: 0 6px 24px rgba(255, 140, 101, 0.36); +} + +.button-secondary { + color: var(--ink-mid); +} + +.button-inline { + color: var(--coral); +} + +.hero-card { + background: white; + border-radius: 32px; + padding: 2rem 2.4rem; + box-shadow: 0 20px 60px rgba(59, 43, 30, 0.12); + position: relative; +} + +.mock-label { + font-family: 'Nunito', system-ui, sans-serif; + font-size: 0.78rem; + font-weight: 800; + letter-spacing: 0.08em; + text-transform: uppercase; + color: var(--ink-soft); + margin-bottom: 0.7rem; +} + +.mock-question { + font-family: 'Nunito', system-ui, sans-serif; + font-size: 2.8rem; + font-weight: 900; + margin-bottom: 1rem; +} + +.mock-question .op { + color: var(--coral); +} + +.mock-answers { + display: grid; + grid-template-columns: repeat(2, 1fr); + gap: 0.8rem; +} + +.mock-answer { + padding: 14px; + text-align: center; + border-radius: 18px; + background: var(--cream); + font-family: 'Nunito', system-ui, sans-serif; + font-weight: 900; + border: 2px solid transparent; +} + +.mock-answer.good { + background: var(--mint-lt); + border-color: var(--mint); + color: #2d8a5a; +} + +.float-badge { + position: absolute; + background: white; + border-radius: 16px; + padding: 10px 14px; + box-shadow: 0 8px 24px rgba(59, 43, 30, 0.12); + font-family: 'Nunito', system-ui, sans-serif; + font-weight: 800; +} + +.fb-1 { top: -14px; right: -20px; color: var(--lav); } +.fb-2 { bottom: -12px; left: -14px; color: var(--mint); } + +main section { + padding: 3rem 0; +} + +.category-block { + margin-top: 2rem; +} + +.exercise-grid { + display: grid; + grid-template-columns: repeat(3, minmax(0, 1fr)); + gap: 1.2rem; + margin-top: 1.2rem; +} + +.card { + background: white; + border-radius: var(--card-r); + padding: 1.4rem; + box-shadow: 0 10px 34px rgba(59, 43, 30, 0.07); +} + +.card h3 { + font-family: 'Nunito', system-ui, sans-serif; + font-size: 1.2rem; + font-weight: 900; + margin-top: 0.1rem; + margin-bottom: 0.5rem; +} + +.card-tag { + display: inline-flex; + padding: 6px 11px; + border-radius: 999px; + font-family: 'Nunito', system-ui, sans-serif; + font-weight: 800; + font-size: 0.8rem; + margin-bottom: 0.9rem; +} + +.card-tag.coral { background: var(--coral-lt); color: var(--coral); } +.card-tag.lavender { background: var(--lav-lt); color: var(--lav); } +.card-tag.mint { background: var(--mint-lt); color: #37956a; } +.card-tag.yellow { background: var(--yellow-lt); color: #9b7a00; } + +.exercise-link { + display: inline-flex; + margin-top: 1rem; + font-family: 'Nunito', system-ui, sans-serif; + font-weight: 800; + color: var(--ink); +} + +.info-grid { + display: grid; + grid-template-columns: 1fr 1fr; + gap: 1.2rem; +} + +footer { + border-top: 1.5px solid rgba(255, 140, 101, 0.15); + padding: 2rem 0 3rem; + margin-top: 2rem; +} + +.footer-inner { + display: flex; + align-items: center; + justify-content: space-between; + gap: 1rem; + flex-wrap: wrap; +} + +.footer-links { + display: flex; + gap: 1rem; + flex-wrap: wrap; + font-family: 'Nunito', system-ui, sans-serif; + font-weight: 700; + color: var(--ink-mid); +} + +.legal-wrap, +.exercise-layout { + display: grid; + grid-template-columns: 280px 1fr; + gap: 1.5rem; +} + +.panel { + background: white; + border-radius: 24px; + padding: 1.3rem; + box-shadow: 0 10px 34px rgba(59, 43, 30, 0.07); +} + +.panel h2, +.panel h3 { + font-family: 'Nunito', system-ui, sans-serif; +} + +.control-label { + font-family: 'Nunito', system-ui, sans-serif; + font-weight: 800; + font-size: 0.78rem; + letter-spacing: 0.08em; + text-transform: uppercase; + color: var(--ink-soft); + margin-bottom: 0.6rem; +} + +.button-list { + display: grid; + gap: 0.45rem; + margin-bottom: 1.2rem; +} + +.option-button { + width: 100%; + text-align: left; + border: 2px solid transparent; + background: #fff; + color: var(--ink-mid); + border-radius: 14px; + padding: 11px 14px; + font-family: 'Nunito', system-ui, sans-serif; + font-weight: 800; + cursor: pointer; +} + +.option-button.active { + border-color: var(--coral); + background: var(--coral-lt); + color: var(--coral); +} + +.stat-grid { + display: grid; + grid-template-columns: repeat(2, 1fr); + gap: 0.7rem; +} + +.stat-box { + background: var(--cream); + border-radius: 14px; + padding: 12px; + text-align: center; +} + +.stat-number { + display: block; + font-family: 'Nunito', system-ui, sans-serif; + font-size: 1.4rem; + font-weight: 900; + color: var(--coral); +} + +.progress-wrap { + background: white; + height: 8px; + border-radius: 999px; + overflow: hidden; + margin-bottom: 1.4rem; +} + +.progress-fill { + height: 100%; + width: 0%; + background: linear-gradient(90deg, var(--coral), var(--yellow)); + transition: width 0.35s ease; +} + +.task-card { + background: white; + border-radius: 32px; + padding: 2.2rem; + box-shadow: 0 12px 48px rgba(59, 43, 30, 0.08); + min-height: 360px; + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + position: relative; +} + +.task-counter { + position: absolute; + top: 20px; + right: 24px; + font-family: 'Nunito', system-ui, sans-serif; + font-weight: 800; + color: var(--ink-soft); +} + +.task-title { + font-family: 'Nunito', system-ui, sans-serif; + font-size: clamp(2.4rem, 5vw, 4rem); + font-weight: 900; + text-align: center; + margin-bottom: 0.7rem; +} + +.task-title .op { + color: var(--coral); +} + +.task-hint { + color: var(--ink-soft); + font-weight: 700; + margin-bottom: 1.8rem; +} + +.answer-grid { + display: grid; + grid-template-columns: repeat(2, 1fr); + gap: 12px; + width: 100%; + max-width: 430px; +} + +.answer-chip, +.submit-btn, +.next-btn { + font-family: 'Nunito', system-ui, sans-serif; + font-weight: 900; +} + +.answer-chip { + padding: 16px; + border-radius: 18px; + border: 2px solid #edeae4; + background: var(--cream); + font-size: 1.35rem; + text-align: center; + cursor: pointer; +} + +.answer-chip.correct { background: var(--mint-lt); border-color: var(--mint); color: #2d8a5a; } +.answer-chip.wrong { background: #ffe8e8; border-color: #ff8080; color: #cc4444; } +.answer-chip.reveal { background: var(--mint-lt); border-color: var(--mint); color: #2d8a5a; } +.answer-chip.disabled { cursor: default; } + +.input-wrap { + width: 100%; + max-width: 340px; + display: grid; + gap: 12px; +} + +.answer-input { + width: 100%; + padding: 18px 20px; + border-radius: 18px; + border: 2px solid #edeae4; + background: var(--cream); + font-family: 'Nunito', system-ui, sans-serif; + font-weight: 900; + font-size: 2rem; + text-align: center; + outline: none; +} + +.answer-input.correct { border-color: var(--mint); background: var(--mint-lt); color: #2d8a5a; } +.answer-input.wrong { border-color: #ff8080; background: #ffe8e8; color: #cc4444; } + +.submit-btn, +.next-btn { + border: 0; + background: var(--coral); + color: white; + border-radius: 999px; + padding: 14px 22px; + cursor: pointer; + box-shadow: 0 4px 16px rgba(255, 140, 101, 0.35); +} + +.feedback-bar { + min-height: 56px; + display: flex; + align-items: center; + justify-content: center; + margin-top: 1rem; + border-radius: 18px; + padding: 0 1.1rem; + font-family: 'Nunito', system-ui, sans-serif; + font-weight: 800; +} + +.feedback-bar.correct { background: var(--mint-lt); color: #2d8a5a; } +.feedback-bar.wrong { background: #ffe8e8; color: #cc4444; } + +.result-card { + display: none; + text-align: center; +} + +.result-card.visible { + display: block; +} + +.result-emoji { + font-size: 3rem; + margin-bottom: 0.7rem; +} + +canvas.confetti { + position: fixed; + inset: 0; + pointer-events: none; +} + +.legal-content { + background: white; + border-radius: 28px; + padding: 2rem; + box-shadow: 0 12px 40px rgba(59, 43, 30, 0.08); +} + +@media (max-width: 980px) { + .hero-grid, + .exercise-grid, + .info-grid, + .legal-wrap, + .exercise-layout { + grid-template-columns: 1fr; + } + + .nav-links { + display: none; + } +}