Skip to content
Back to skills

New Lesson

ASecurity

Scaffold a new bilingual (en/es) lesson or topic for this Lessons site — creates the MDX files in the correct locale folders with valid frontmatter, wires in the reusable interactive components, and regenerates OG images. Use when the user asks to "add a lesson", "add a topic", "create a lesson about X", "new lesson", or provides a subject to teach.

  • 3 stars
  • 0 votes
  • 0 copies
  • 1 view
  • Added September 19, 2026
developmentgobashreactvuetestinggit

Works with

  • cli

Security analysis

A100/100

Scanned September 19, 2026

npx -y skills add alexfdez1010/mental-models --skill new-lesson --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of New Lesson?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for New Lesson
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/alexfdez1010-new-lesson/badge)](https://www.skillsdirectory.com/skills/alexfdez1010-new-lesson)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: new-lesson
description: Scaffold a new bilingual (en/es) lesson or topic for this Lessons site — creates the MDX files in the correct locale folders with valid frontmatter, wires in the reusable interactive components, and regenerates OG images. Use when the user asks to "add a lesson", "add a topic", "create a lesson about X", "new lesson", or provides a subject to teach.
---

# Authoring a Lesson or Topic

This project teaches the subject defined in **TOPIC.md** across multiple
slug-based **lesson** pages, in **English and Spanish**. Its mission: take a
learner with **no prior knowledge of the subject** to **complete expert**.
**Read `TOPIC.md` first** — it is the source of truth for subject, mission,
scope, and voice. Follow these steps to add content consistently.

## Mission fit (REQUIRED before scaffolding)

Every topic sits on the **zero-to-expert ladder** that `TOPIC.md` defines:

- **Assume no background** in the subject at the `beginner` tier — define every
  domain term on first use; never lean on jargon the lesson hasn't taught.
- **Set the `difficulty` frontmatter field** (`beginner` | `intermediate` |
  `advanced` | `expert`) — required, same value in the en/es twins. It renders as
  a badge on the catalog graph.
- **Wire `dependencies`** so every concept a non-`beginner` course assumes is
  taught by one of its prerequisites already on the platform.
- **`expert` means expert** — go all the way to quantitative, real-practitioner
  depth; don't stop at "intro".

## 0. Research first — then write with voice, animation, exercises

Before scaffolding, use the **`research-topic` skill** to build an accurate,
sourced brief and outline (concepts, definitions, misconceptions, analogies,
animation opportunities). Never write non-trivial lesson prose from memory.

As you write, apply the companion skills:

- **`lesson-copy`** — voice/tone: witty, lightly sarcastic, analogy-driven copy
  that is genuinely fun to study, without sacrificing accuracy.
- **`lesson-animations`** — include **at least one animation that teaches** the
  core idea (a process/relationship shown moving, not decoration).
- **`exercise-components`** — include **at least one exercise** (multi-answer
  `MCQ`, `Quiz`, or a `concept → definition` matcher), reusing/extending the
  component library rather than inlining one-off JSX.

## Interaction density (REQUIRED — not just at the end)

Lessons must be **interactive throughout**, not a text wall with one quiz at the
bottom. Retention comes from testing right after learning. Aim for **at least
one exercise per `##` section, ideally two** (a prequestion to open, a check to
close). Err on the side of *more* exercises.

- **Open each `##` with a prequestion** (`MCQ pretest`): make the learner *guess
  before reading*. Pretesting boosts encoding even when the guess is wrong, and
  pretests never count toward a `Quiz` score. See `exercise-components`.
- **Interleave checks**: after **each** explanation, add an exercise or
  animation that checks or shows what was just taught. Don't pool questions at
  the end.
- **Rotate types every time** — never the same format twice running: single
  `MCQ`, **multi-answer `MCQ`** (`allowMultiple`), `MCQ pretest`,
  concept→definition `MatchConcepts`, `Categorize` (sort into buckets),
  `FillBlank` (pick-one-of-three cloze), scored `Quiz`, `Reveal` self-checks.
- **For must-remember terms** reach for `FillBlank` — each blank is the right
  term flanked by two plausible distractors, so the learner discriminates rather
  than just recognises. Keep options equal-length; the answer must never be the
  longest. (No `StepThrough` — it was removed; use a numbered Markdown list.)
- **Spaced recall**: write some questions that reference *earlier* sections so
  the user recalls prior material; the end quiz mixes the whole lesson.
- **Animations per concept**: an animation at *each* major
  transformation/process/relationship, beside its explanation — not one hero
  animation per lesson. See `lesson-animations`.
- **Close with a chunking recap**: end every lesson with a learner-built
  `MindMap` (Mermaid "big picture" linking the section concepts) **plus** a mixed
  `Quiz` — not a passive bullet-list summary. See `lesson-animations`.

Apply the same density to the Spanish twin (parity includes exercises and
animations, with Spanish label props).

## Final exam (REQUIRED — every course ends with one)

**Every course (topic) MUST conclude with a final exam as its LAST lesson.**
This is mandatory, not optional — Claude: whenever you finish a topic, or add
the last teaching lesson to one, that topic is not "done" until a final-exam
lesson sits at the end of it. When building a brand-new topic, plan the exam as
the final lesson from the start.

- **Slug & position**: `final-exam` in both locales
  (`src/content/lessons/<lang>/<topic>/final-exam.mdx`), with `order` set to
  **one higher than every other lesson** so it sorts last. Title it as an exam
  (e.g. *"Final Exam: …"* / *"Examen final: …"*).
- **It must be genuinely hard.** The point is to verify the learner truly
  understood everything — not a victory-lap recap. Use **scenario-based,
  multi-step reasoning** with plausible distractors and subtle traps drawn from
  the misconceptions each lesson warned about.
- **Use the `FinalExam` island — NOT `Quiz` and NOT themed recap sections.**
  The final exam is a graded, **irreversible** run: one MCQ at a time, the
  learner submits, the answer **locks for good** (no Back, no Try again, no
  Restart), the result reveals instantly, and the pass/fail score appears only
  after the last question. Don't rebuild the old elaborate flow (pretest →
  `Callout` → `Categorize`/`FillBlank`/`MatchConcepts` per theme → a separate
  scored `Quiz`); that is exactly the over-complex structure `FinalExam`
  replaces. Present the questions **directly**.
- **Keep the page flat and short:** a one-paragraph intro → a
  `Callout variant="warning"` "How this exam works" box (states: answers are
  final, no retries, score shown at the end, pass mark `70%`) → the
  `<FinalExam client:visible passPercent={70} questions={[…]} />` island →
  `## Course Recap` `MindMap` → `## Key Takeaways` `Callout variant="success"`.
- **Question pool: 20–30 fresh MCQs**, covering ALL prior lessons roughly
  proportionally. Mostly single-answer; include **2–4 multi-answer** questions
  (`allowMultiple: true`, multiple options marked `correct: true`). No `pretest`
  here — an exam tests, it doesn't pre-teach.
- **VARIETY IS MANDATORY — repetition is the #1 failure mode.** Vary every axis:
  question *type* (numeric/calculation with the arithmetic shown in the
  explanation, scenario/application, "which statement is TRUE", spot-the-trap,
  definition, side-by-side comparison, cause→effect, ranking-as-single-answer),
  *stem wording* (never reuse the same sentence frame twice in a row; don't open
  five questions with "Which of the following…"), and *difficulty*. Every
  question carries a concise `explanation` teaching the why.
- **Same rules as any lesson**: keep numbers/LaTeX in MDX prose and tables, never
  baked into island option/question text (put numeric scenarios in a table right
  above the island and phrase the question conceptually); ship a full es-ES twin
  with Spanish label props.

## 1. Decide: new topic or new lesson in an existing topic?

- List existing topics: look under `src/content/topics/en/`.
- A **topic** needs `src/content/topics/en/<topic>.mdx` + the `es` twin.
- A **lesson** goes in `src/content/lessons/en/<topic>/<lesson>.mdx` + the `es` twin.

Slugs must be kebab-case and SEO-friendly (e.g. `getting-started`).

## 2. Topic frontmatter (`src/content/topics/<lang>/<topic>.mdx`)

```mdx
---
title: Getting Started
description: A one-line summary used on cards and as the default meta description.
tagline: From the basics to genuine mastery.       # optional, shown under the hero
icon: 🚀                                            # emoji chip
order: 1                                            # sort order in the catalog
accent: brand                                       # 'brand' (blue) | 'accent' (sky)
---

Short intro prose for the topic landing page (rendered in `.prose-lesson`).
```

The Spanish file is identical structure under `.../es/<topic>.mdx`, translated.

## 3. Lesson frontmatter (`src/content/lessons/<lang>/<topic>/<lesson>.mdx`)

```mdx
---
title: Your First Lesson
description: SEO meta description (≤155 chars), specific and compelling.
topic: "en/getting-started"        # MUST be the owning topic's id: "<lang>/<topic>"
order: 1                            # position within the topic
minutes: 6                         # estimated time
updated: 2026-05-30                # ISO date
---
```

- For the Spanish twin, set `topic: "es/getting-started"`.
- Use `##` and `###` headings — they generate the on-page Table of Contents.

## 4. Use the reusable components (import via the `@` alias)

At the top of the MDX body:

```mdx
import { Callout, MCQ, Quiz, FinalExam, Reveal,
         MatchConcepts, Categorize, FillBlank, MindMap } from '@/components/react';
```

Exercise islands: `MCQ` (add `pretest` for prequestions, `allowMultiple` for
multi-answer), `Quiz`, `MatchConcepts`, `Categorize`, `FillBlank`. `FinalExam` is
the graded, lock-on-submit island reserved for a course's final-exam lesson (see
above). Recap visual: `MindMap`. See `exercise-components` and `lesson-animations`
for each.

Interactive islands need `client:visible`; `Callout` is presentational (no directive).

These are the **only** islands the template ships in `@/components/react`: `MCQ`,
`Quiz`, `FinalExam`, `Reveal`, `Callout`, `FillBlank`, `MatchConcepts`,
`Categorize`, `MindMap`, `CourseGraph`, `LessonComplete`, `CourseComplete`,
`ProgressTransfer`. **No subject-specific chart or animation islands exist** —
those you build for your topic (see `lesson-animations` and `exercise-components`
for how to author one the right way).

```mdx
<Callout variant="tip" title="Key idea">State the one thing the learner must remember.</Callout>

<MCQ
  client:visible
  question="What is the core point of this section?"
  options={[
    { text: 'The correct, precise answer', correct: true },
    { text: 'A plausible near-miss' },
    { text: 'A common misconception' },
  ]}
  explanation="Explain why the right answer holds and the distractors don't."
/>

<Quiz client:visible questions={[ /* array of MCQ prop objects */ ]} />

<FillBlank
  client:visible
  text="The {{correct-term|sibling-term|another-sibling}} is what makes this idea {{work|fail|repeat}}."
/>

<Reveal client:visible><Callout>Animates in on scroll.</Callout></Reveal>
```

**Spanish lessons must pass Spanish label props** so the UI is fully localized, e.g.
`<MCQ ... checkLabel="Comprobar" retryLabel="Reintentar" />`,
`<Quiz ... questionLabel="Pregunta" ofLabel="de" scoreLabel="Tu puntuación" restartLabel="Reiniciar" nextLabel="Siguiente" backLabel="Atrás" />`,
`<FillBlank ... checkLabel="Comprobar" retryLabel="Reintentar" instructions="Elige la opción correcta para cada hueco y comprueba." />`.
The `FinalExam` island needs its own Spanish props:
`<FinalExam ... questionLabel="Pregunta" ofLabel="de" submitLabel="Enviar respuesta" lockWarningLabel="Atención: una vez que envíes, esta respuesta es definitiva. No podrás cambiarla." selectHintLabel="Selecciona una respuesta para continuar." nextLabel="Siguiente pregunta" seeResultsLabel="Ver resultados" correctLabel="Correcto" incorrectLabel="Incorrecto" correctAnswerLabel="Respuesta correcta" explanationLabel="Explicación" completeTitleLabel="Examen completado" scoreLabel="Has acertado" passLabel="Aprobado" passMessage="Has superado el listón: buen trabajo." failLabel="No superado" failMessage="Esta vez por debajo del aprobado: repasa las lecciones y vuelve a intentarlo." reviewLabel="Tus respuestas" />`.
See `DESIGN.md` for the full prop reference of every component.

## 5. Always create BOTH locales

Every English file needs a Spanish twin at the mirrored `es` path. This keeps `hreflang`,
the sitemap, and the header language switcher correct. If a translation is genuinely
unavailable, the alternates helper falls back to the locale home — but prefer real twins.

## 6. Verify

```bash
bun run check       # check:latex + astro check + tsc — must be 0 errors
bun run check:latex # standalone: renders every $...$/$$...$$ through KaTeX, fails on parse errors
bun run build       # routes for the new pages should appear
```

**LaTeX gotcha — `\$` inside a `$...$` span breaks rendering.** `rehype-katex`
renders bad math as silent red error text (build stays green), so it's easy to
miss. The classic trap: writing a currency amount *inside* inline math, e.g.
`$0.08 \times 1000 = \$80$`. The math-delimiter scanner closes the span at that
`$`, leaving a stray `\` → KaTeX parse error. **Fix: keep currency OUT of the
math span** — `$0.08 \times 1000$, i.e. \$80`. `bun run check:latex` (also run
inside `bun run check` and `pre-commit`) catches this class of bug across en+es.

Routes appear automatically (no route file edits needed) because pages use
`getStaticPaths` over the content collections.

## 7. Regenerate OG images

```bash
bun run og:build   # build, then Playwright screenshots new /og cards into public/og/
```

(`bun run pre-commit` also does this; run it before committing, then `git add public/og`.)

## Conventions recap

- `@` import alias only — never relative `../`.
- Tailwind design tokens only (no raw hex) — see `DESIGN.md`.
- Keep content accurate, concise, and genuinely interactive — at least one exercise per lesson.

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.