Files
cabrits-math/plan.md
2026-07-05 11:12:45 -04:00

320 lines
34 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Implementation Plan: Term 1 Unit Plan (`unit_plan_term_1.pdf`) → Cabrits App
## 1. Context
Cabrits is an interactive mathematics teaching tool for Portsmouth Secondary School Form 1 (age 1112), used live in class by the teacher. Pages contain **interactive tools only — no lesson text** (the teacher explains verbally). Stack: Next.js 16 (App Router, `output: "standalone"`), React 19, TypeScript, Tailwind CSS v4 (`@theme inline`), KaTeX via `components/math/math-display.tsx`, custom SVG visualizations (no chart libraries), no database/auth — everything is client-side and generated on the fly.
The app currently implements the **Term 2** curriculum as Units 14 (Fractions, Decimals, Decimal Operations, Ratio & Proportion) and has already started on Term 1 material as Units 56 (Integers, Number System).
`unit_plan_term_1.pdf` (8 pages, AY 20252026, Form 1, "NUMBER" unit) specifies these topics. The website is a **resource organized by topic** — the source document's scheduling is irrelevant and must never appear in the app (no week numbers, no dates, nothing schedule-related in any UI text, slug, title, or description):
| Topic | Objectives | Content |
|-------|-----------|---------|
| Integers: define, order, compare | Define integers & negative numbers; represent on a number line; order integers (ascending/descending); compare integers with `<` / `>` | Number line, real-world contexts (temperature/thermometer, banking/overdraft, sports goal differences, time). Evaluation: order sets like `-8, -10, -4, -3, -6, 5`; fill in `<` or `>` for pairs like `-5 __ 5`, `4 __ -16`, `-6 __ -11` |
| Integers: add & subtract | Add & subtract integers, with and without number lines | Number-line movement rules; sign rules ("two like signs become +, two unlike signs become "); borrow/owe strategy. Evaluation: `5 + (-3)`, `8 - (-7)`, `-2 + 9`, `-9 - (-1)`, etc. |
| Integers: multiply & divide | Multiply & divide integers | Sign rules (` × = +` etc.); "Eat! / Do not eat!" story; thermometer word problems (e.g. "In London, temperature is 3 °C, next day it rose by 7 °C…"). Evaluation: `3 × -5`, `-2 × -9`, `-12 / 4`, `-24 / -8`, `(-2) × (-3) × (-4)` |
| Coordinates | Plot coordinates; state coordinates of points | Cartesian plane: x-axis (horizontal), y-axis (vertical), origin (0, 0). Evaluation: plot `A(-4,-8), B(-3,-9), C(-2,-8), D(-2,0), E(-5,0), F(-6,4), G(-2,5), H(2,4), I(5,0)`, join alphabetically then I→A to reveal a shape |
| Identity, inverse & zero facts | Basic operations; identity for addition (0) & multiplication (1); inverse under addition (additive inverse, e.g. inverse of 3 is 3 because `3 + (-3) = 0`); inverse under multiplication (reciprocal, e.g. inverse of 6 is 1/6 because `6 × 1/6 = 1`; inverse of 5 is 1/5); multiplication by zero → 0; division by zero → undefined | "Math Wheel" activity. Evaluation: classwork + homework on identities/inverses |
| Number laws & exponents | Commutative, associative, distributive laws; powers/exponents | Addition & multiplication are commutative/associative, subtraction & division are not; distributive law (number outside bracket multiplies every number inside). Exponents: `2⁴ = 2×2×2×2 = 16`; `a¹ = a`; `a⁰ = 1`; product rule `2⁴ × 2³ = 2⁷`; quotient rule `6⁵ / 6³ = 6²`. Evaluation quiz: `6³`, `2³ 2¹`, `5⁶ / 5⁴`, `7⁰`, `4⁴ × 4³` |
| Number systems (base 10 & base 2) | Understand & use the decimal system (base 10); understand & use the binary system (base 2) | Base-10 place value chart with powers of 10, expanded form (`983275 = 9×10⁵ + 8×10⁴ + 3×10³ + 2×10² + 7×10¹ + 5×10⁰`); binary place value with powers of 2; convert binary→denary (`111001₂ = 32+16+8+0+0+1 = 57`). Evaluation: convert `1011₂`, `111₂`, `1101₂` to denary |
## 2. Gap Analysis
**Already implemented (do NOT rebuild — leave untouched):**
| PDF topic | Existing route | Existing explorer |
|---|---|---|
| Add/subtract integers | `/lessons/unit-5-integers/add-subtract` | `components/explorers/integer-add-subtract-explorer.tsx` (number-line + sign-rules modes, step-through, inline QuickPractice) |
| Multiply/divide integers | `/lessons/unit-5-integers/multiply-divide` | `components/explorers/integer-multiply-divide-explorer.tsx` |
| Binary ↔ denary | `/lessons/unit-6-number-system/binary` | `components/explorers/binary-converter-explorer.tsx`, `denary-to-binary-explorer.tsx` |
| (bonus, not in PDF) quaternary | `/lessons/unit-6-number-system/quaternary` | `quaternary-to-denary-explorer.tsx`, `denary-to-quaternary-explorer.tsx` |
**Missing (this plan builds these):**
1. Order & compare integers (new topic in existing Unit 5)
2. Cartesian plane: plot points & read coordinates (new Unit 7)
3. Identity, inverse, zero facts (new Unit 8, topic 1)
4. Commutative/associative/distributive laws (Unit 8, topic 2)
5. Powers & exponents with index laws (Unit 8, topic 3)
6. Base-10 place value / expanded form (new topic in existing Unit 6)
## 3. Target Curriculum Structure After Implementation
- **Unit 5 Integers** (existing, violet `#7c3aed`): `order-compare` **(NEW, insert as first topic)**, `add-subtract`, `multiply-divide`
- **Unit 6 Number System** (existing, indigo `#4f46e5`): `place-value` **(NEW, insert as first topic)**, `binary`, `quaternary`
- **Unit 7 Coordinates** (NEW, green `#16a34a`): `plot-points`, `read-coordinates`
- **Unit 8 Number Properties** (NEW, rose `#e11d48`): `identity-inverse`, `number-laws`, `exponents`
New routes (7 topic pages + 2 unit overview pages):
```
/lessons/unit-5-integers/order-compare
/lessons/unit-6-number-system/place-value
/lessons/unit-7-coordinates (overview)
/lessons/unit-7-coordinates/plot-points
/lessons/unit-7-coordinates/read-coordinates
/lessons/unit-8-number-properties (overview)
/lessons/unit-8-number-properties/identity-inverse
/lessons/unit-8-number-properties/number-laws
/lessons/unit-8-number-properties/exponents
```
No existing route changes. Inserting topics at the front of a unit's `topics` array only changes the displayed numbering on overview pages (which is index-based), not URLs.
## 4. Codebase Conventions (READ THESE FILES FIRST as templates)
1. **`lib/curriculum.ts`** — single source of truth. `Unit` interface has `number: 1|2|3|4|5|6` and `color: "unit-1"|...|"unit-6"` unions that must be extended to include 7 and 8. The sidebar (`components/layout/sidebar.tsx`), mobile nav (`components/layout/mobile-nav.tsx`), lessons index (`app/lessons/page.tsx`), and landing page (`app/page.tsx`) all iterate `curriculum` automatically — but each keeps its **own hardcoded color-class map keyed by `"unit-N"`** that must gain `unit-7`/`unit-8` entries (Tailwind cannot generate class names dynamically).
2. **Topic page pattern** — see `app/lessons/unit-5-integers/add-subtract/page.tsx` (the most recent convention): a `"use client"` page containing only `<Breadcrumbs>`, an `<h1>`, and one `<XyzExplorer />` component. Breadcrumb items: `Lessons → Unit N: Title → Short topic label`.
3. **Unit overview page pattern** — see `app/lessons/unit-5-integers/page.tsx`: server component, reads `curriculum[unitIndex]`, renders a `<Badge variant="unit-N">` header and a `sm:grid-cols-2` grid of `<Card accent="unit-N" hover>` links with numbered chips (`bg-unit-N-light text-unit-N-dark`).
4. **Explorer pattern** — see `components/explorers/integer-add-subtract-explorer.tsx` (594 lines; the canonical template). Structure:
- `"use client"`, local `Step` interface `{ label: string; math: string; ...visualization payload }`
- A pure `buildXyzSteps(...)` function that returns `Step[]` narrating the worked solution
- Mode-toggle pill buttons (`rounded-full border-2 ...` with unit color classes)
- An input `<Card>` with validated number inputs and a "Go →" button; friendly error messages via a local `error` state
- A display `<Card>` showing `step.label`, `<MathDisplay math={step.math} />` (KaTeX string), and the custom SVG/div visualization that animates with the current step
- `<StepControls>` from `components/explorers/step-controls.tsx` wired via `currentStep / totalSteps / isPlaying / onStepForward / onStepBack / onTogglePlay / onReset / canStepForward / canStepBack` (note: it expects `currentStep + 1` as the 1-based display value)
- A result `<Card>` shown when steps complete
- An inline `QuickPractice` component (local to the file): random problem generator, number input, Check/Next buttons, running `score.correct/score.total` chip, Enter-key handling, correct/incorrect feedback using `border-correct bg-correct-light` / `border-incorrect bg-incorrect-light` classes
5. **Color system**`app/globals.css` defines per-unit CSS vars in `:root` (`--unit-N`, `--unit-N-light`, `--unit-N-dark`) and mirrors them in the `@theme inline` block as `--color-unit-N*` so Tailwind classes like `bg-unit-7`, `text-unit-7-dark`, `bg-unit-7-light`, `border-unit-7/40` work. Also available: `--correct`, `--incorrect` (+ `-light` variants), `--foreground`, `--muted`, `--surface`, `--border`.
6. **Practice hub**`app/practice/page.tsx` holds `TOPIC_GENERATORS` (generator functions from `lib/problems/generators/*`), a `unitColors` map (currently only units 14), and a filter-pill array `(["unit-1","unit-2","unit-3","unit-4"] as const)`. `components/practice/practice-section.tsx` renders input UI switched on `problem.answer.kind` — it already supports `"integer"` (plain number input), so all new generators should return `{ kind: "integer", value }` answers. `MathProblem` (in `lib/problems/types.ts`) requires `id`, `prompt` (may contain KaTeX-able text), `answer`, `hints: string[]`, `steps: SolutionStep[]` (`{ explanation, math? }`). `Difficulty = 1 | 2 | 3`.
7. **Landing page art**`components/home/topic-art.tsx` exports `art: Record<string, ReactNode>` keyed by `"unitSlug/topicSlug"`, each a small white-on-gradient SVG glyph inside the shared 100×75 viewBox `Frame`. Every new topic needs an entry or its tile renders without artwork.
---
## 5. Implementation Phases
Work in this order; the app must compile after every phase (`npx tsc --noEmit` and `npm run build`).
### Phase 1 — Shared infrastructure (types, colors, nav maps)
1. **`lib/curriculum.ts`**
- Extend `Unit["number"]` union to `1|2|3|4|5|6|7|8` and `Unit["color"]` union to include `"unit-7" | "unit-8"`.
- Extend `getUnitColor`'s parameter type and `colors` record with `7: "unit-7"`, `8: "unit-8"`.
- Insert into unit 5's `topics` (as the FIRST element):
```ts
{
slug: "order-compare",
title: "Order and Compare Integers",
shortTitle: "Order & Compare",
description: "Place integers on a number line, order them, and compare with < and >",
},
```
- Insert into unit 6's `topics` (as the FIRST element):
```ts
{
slug: "place-value",
title: "Denary Place Value (Base 10)",
shortTitle: "Place Value",
description: "Powers of 10 and writing numbers in expanded form",
},
```
- Append two new units after unit 6:
```ts
{
number: 7,
slug: "unit-7-coordinates",
title: "Coordinates",
description: "Plot points and read coordinates on the Cartesian plane",
color: "unit-7",
topics: [
{ slug: "plot-points", title: "Plot Points on the Cartesian Plane", shortTitle: "Plot Points", description: "Use x and y coordinates to place points and reveal hidden shapes" },
{ slug: "read-coordinates", title: "State Coordinates of Points", shortTitle: "Read Coordinates", description: "Read off the (x, y) coordinates of points in all four quadrants" },
],
},
{
number: 8,
slug: "unit-8-number-properties",
title: "Number Properties",
description: "Identity and inverse, the laws of arithmetic, and powers of numbers",
color: "unit-8",
topics: [
{ slug: "identity-inverse", title: "Identity and Inverse", shortTitle: "Identity & Inverse", description: "Identity for addition and multiplication, inverses, and the zero facts" },
{ slug: "number-laws", title: "Commutative, Associative and Distributive Laws", shortTitle: "Number Laws", description: "Which operations can be swapped, regrouped, and expanded" },
{ slug: "exponents", title: "Powers and Exponents", shortTitle: "Exponents", description: "Base and power, expanding powers, and the index laws" },
],
},
```
2. **`app/globals.css`** — add beside the existing `--unit-6` definitions in `:root`:
```css
--unit-7: #16a34a;
--unit-7-light: #dcfce7;
--unit-7-dark: #15803d;
--unit-8: #e11d48;
--unit-8-light: #ffe4e9;
--unit-8-dark: #be123c;
```
and in the `@theme inline` block (beside `--color-unit-6-dark`):
```css
--color-unit-7: var(--unit-7);
--color-unit-7-light: var(--unit-7-light);
--color-unit-7-dark: var(--unit-7-dark);
--color-unit-8: var(--unit-8);
--color-unit-8-light: var(--unit-8-light);
--color-unit-8-dark: var(--unit-8-dark);
```
3. **`components/ui/badge.tsx`** — extend `BadgeVariant` union with `"unit-7" | "unit-8"` and add to `variantStyles`:
```ts
"unit-7": "border border-unit-7/20 bg-unit-7-light text-unit-7-dark",
"unit-8": "border border-unit-8/20 bg-unit-8-light text-unit-8-dark",
```
4. **`components/ui/card.tsx`** — extend the `accent` prop union and `accentStyles` with `"unit-7": "border-l-4 border-l-unit-7"` and the unit-8 equivalent.
5. **`components/layout/sidebar.tsx`** — add `unit-7` / `unit-8` entries to `unitColorMap`, following the exact shape of the existing entries (`active`, `dot`, `heading`, `hoverBg` keys with the unit's color classes).
6. **`components/layout/mobile-nav.tsx`** — same: extend both color maps (there is a text-color map at ~line 10 and a dot/bg map at ~line 19) with unit-7/unit-8 entries.
7. **`app/page.tsx`** (landing) — add to `unitStyles`:
```ts
"unit-7": {
tile: "from-[#4ade80] to-[#15803d]",
unitCard: "border-[#86efac] bg-[#f0fdf4]",
chip: "bg-[#15803d]",
},
"unit-8": {
tile: "from-[#fb7185] to-[#be123c]",
unitCard: "border-[#fda4af] bg-[#fff1f2]",
chip: "bg-[#be123c]",
},
```
The topic tiles cycle through the `topicTiles` gradient array by index, so no per-topic change is needed there.
8. **`components/home/topic-art.tsx`** — add 7 entries to the `art` record (white SVG glyphs in the 100×75 viewBox, matching the visual weight of existing entries):
- `"unit-5-integers/order-compare"`: a horizontal number line (line + tick marks) with `<` glyph, e.g. ticks at intervals with two highlighted dots and a `<` between two numbers
- `"unit-6-number-system/place-value"`: three columns of stacked digits over small `10² 10¹ 10⁰` labels (use `<text>` with `fontSize` ~810)
- `"unit-7-coordinates/plot-points"`: a small grid (4 light `<line>`s each way), two axes drawn heavier, one bright plotted point with small crosshair lines to the axes
- `"unit-7-coordinates/read-coordinates"`: axes plus a point labelled `(3, 2)`
- `"unit-8-number-properties/identity-inverse"`: `n + 0 = n` style glyph, or two circles balancing on a seesaw with `0` at the pivot
- `"unit-8-number-properties/number-laws"`: `a + b = b + a` with a swap arrow (curved `<path>` with arrowhead)
- `"unit-8-number-properties/exponents"`: large `2` with superscript `4` and `= 16`
**Checkpoint:** `npx tsc --noEmit` passes; landing page, sidebar, and mobile nav show Units 78 with correct colors; the two new Unit 5/6 topics appear (links 404 until later phases — acceptable mid-work, but all phases must be done before merging).
### Phase 2 — Unit 5: Order & Compare Integers
**New file: `components/explorers/integer-order-compare-explorer.tsx`** — model on `integer-add-subtract-explorer.tsx`. Unit color: `unit-5` (violet). Three modes via pill toggle:
1. **"Number Line" mode** (objective 12: define/represent):
- Input: one integer from 15 to 15 (reuse the NumberLine rendering approach from the add-subtract explorer: absolute-positioned ticks over a percentage-scaled track, labels every 5 plus highlighted values).
- Step sequence: (1) show the number line with zero highlighted, label "Zero separates negative numbers (left) from positive numbers (right)"; (2) mark the entered integer with a Start-style pill marker; (3) state its type: `\text{-7 is a negative integer — it is 7 steps left of zero}` (KaTeX via `MathDisplay`).
- Below the line keep the existing convention: `← negative` / `positive →` edge labels.
- Add a context selector row of small buttons — **Thermometer 🌡, Money 💰, Sea level 🌊** — that re-labels the step text (e.g. thermometer: "7 means 7 degrees below zero"; money: "7 means owing $7"; sea level: "7 means 7 m below sea level"). This delivers the PDF's real-world contexts (temperature, banking/overdraft). A vertical thermometer variant is optional polish, not required.
2. **"Order" mode** (objective 3):
- Input: a comma-separated list of 36 integers (validate: integers, within 20…20, at least 3). Direction toggle: Ascending / Descending.
- Step sequence built by `buildOrderSteps(values, direction)`: (1) show unordered values as chips; (2) place all values as dots on the number line simultaneously; (3) one step per pick — "The smallest is the furthest LEFT on the number line: 10" — moving each chip into the ordered row; (4) final ordered list, `\text{Ascending: least} \to \text{greatest}`.
- The visualization: the shared number line with dots, plus a row of value chips that fill in as steps advance (conditionally render based on `currentStep`, same technique as the existing explorers' step-driven rendering).
3. **"Compare" mode** (objective 4):
- Input: two integers a, b. Steps: (1) plot both on the number line; (2) "Numbers to the RIGHT are always larger" with the right-hand one highlighted; (3) result `5 < 5` rendered with `MathDisplay`.
**Inline `QuickPractice`** (same Card layout/score-chip pattern as the template): alternate two question types randomly —
- *Compare*: show `a \; \square \; b` with two big `<` / `>` buttons instead of a number input (immediate check on click). Seed pairs like the PDF's evaluation: `(-5, 5)`, `(4, -16)`, `(-6, -11)`, plus randoms in 20…20.
- *Order*: show 4 shuffled integers as clickable chips; student clicks them in ascending order; each click either locks the chip (correct next pick) or flashes incorrect. Score a point when all 4 are placed without a mistake.
**New file: `app/lessons/unit-5-integers/order-compare/page.tsx`** — copy the shape of `add-subtract/page.tsx`; breadcrumbs `Lessons → Unit 5: Integers → Order & Compare`; `<h1>Order and Compare Integers</h1>`; render the new explorer.
### Phase 3 — Unit 7: Coordinates
**New file: `app/lessons/unit-7-coordinates/page.tsx`** — copy `app/lessons/unit-5-integers/page.tsx`, change `curriculum[4]` → `curriculum[6]`, `unit-5` → `unit-7` classes, badge variant `unit-7`, breadcrumb label `Unit 7: Coordinates`.
**Shared visualization — build a reusable `CartesianGrid` component** (either inside each explorer or as `components/visualizations/cartesian-grid.tsx` if `components/visualizations/` exists — check; if the repo keeps visuals inline in explorers, put it in a shared file under `components/explorers/` such as `cartesian-grid.tsx`). Spec:
- SVG `viewBox="0 0 440 440"`, responsive (`className="h-auto w-full max-w-md"`), grid from 10 to +10 both axes (21 lines each way; light `stroke="var(--border)"` gridlines, heavier axes through the origin in `var(--foreground)`), axis numeric labels every 2 (skip 0 clutter; label origin `0` once), arrowheads + `x` / `y` labels at the axis ends.
- Props: `points: { x: number; y: number; label?: string; color?: string }[]`, `segments: { from: Point; to: Point }[]` (polylines drawn so far), optional `highlight` point with **guide lines**: a dashed line from the point straight down/up to the x-axis and across to the y-axis (this is the key teaching visual for both plotting and reading), optional `onGridClick?: (x, y) => void` (attach a click handler on the SVG, invert the coordinate transform, snap to nearest integer intersection).
- Coordinate transform: `sx = 20 + (x + 10) * 20`, `sy = 20 + (10 - y) * 20`.
**New file: `components/explorers/plot-points-explorer.tsx`** — unit color `unit-7`. Two modes:
1. **"Plot a Point"**: inputs for x and y (10…10). `buildPlotSteps(x, y)`: (1) "Start at the origin (0, 0), where the axes cross"; (2) "Move ALONG the x-axis: 4 to the right" (grid shows a horizontal arrow from origin to (x, 0)); (3) "Then move UP/DOWN parallel to the y-axis: 3 up" (vertical arrow (x,0)→(x,y), dashed guides); (4) "Mark the point (4, 3) — x always comes first!". Each step's payload tells `CartesianGrid` what arrows/guides/points to draw.
2. **"Shape Reveal"** (the PDF's evaluation activity): a select of 34 preset shape datasets, the first being exactly the PDF's: `A(-4,-8), B(-3,-9), C(-2,-8), D(-2,0), E(-5,0), F(-6,4), G(-2,5), H(2,4), I(5,0)` joined A→B→…→I→A. Add 23 simpler presets (e.g. a square, a star, a house). Step-through: each step plots the next labelled point and draws the segment from the previous one; final step closes the shape (I back to A). `StepControls` drives it, so the teacher can play it like an animation.
Inline `QuickPractice`: "Click where (3, 5) is!" — random target coordinates, student clicks the grid (via `onGridClick`), snap-checked for exact match; correct → green pulse on the point, score increments; incorrect → show the clicked point in red and the target in green with guide lines.
**New file: `components/explorers/read-coordinates-explorer.tsx`** — unit color `unit-7`.
- **Explore mode**: a random (or stepped) point is shown; `buildReadSteps(x, y)`: (1) "Drop a line straight DOWN/UP to the x-axis — it lands on 4" (dashed vertical guide); (2) "Go straight ACROSS to the y-axis — it lands on 3" (dashed horizontal guide); (3) "The coordinates are (4, 3): x first, then y". Include a quadrant call-out step ("Both negative → bottom-left quadrant") since the PDF's shape spans all four quadrants.
- Inline `QuickPractice`: show a random point on the grid; two number inputs `( __ , __ )`; check both; classic error worth catching in feedback: if the student enters (y, x) swapped, say "You swapped them — x comes first!".
**New pages:** `app/lessons/unit-7-coordinates/plot-points/page.tsx` and `.../read-coordinates/page.tsx` following the standard topic-page shape (breadcrumb unit label `Unit 7: Coordinates`).
### Phase 4 — Unit 8: Number Properties
**New file: `app/lessons/unit-8-number-properties/page.tsx`** — copy the unit-overview pattern with `curriculum[7]`, `unit-8` classes.
**New file: `components/explorers/identity-inverse-explorer.tsx`** — unit color `unit-8`. Mode pills: **Identity · Inverse · Zero Facts**.
- *Identity*: input a number n; toggle Add / Multiply. Steps: `n + 0 = n` — "Adding 0 leaves the number unchanged: 0 is the identity for addition"; `n × 1 = n` — "Multiplying by 1 leaves it unchanged: 1 is the identity for multiplication". Visual: a "machine" card — number goes in, `+0`/`×1` badge in the middle, same number comes out (simple flex layout with an animated arrow; framer-motion optional, CSS transitions fine).
- *Inverse*: input n (non-zero for multiplication). Steps for addition: "The additive inverse is the number that gets you back to the identity 0" → `n + (n) = 0` (e.g. inverse of 3 is 3; inverse of 5 is 5 — flip the sign). Steps for multiplication: "The multiplicative inverse (reciprocal) gets you back to 1" → `n × \frac{1}{n} = 1`, with the PDF's note that the inverse of 5 is `\frac{1}{5}` (sign stays in front). Render fractions with KaTeX.
- *Zero Facts*: input n. Steps: `n × 0 = 0` — "Anything times zero is zero"; `n ÷ 0 = \text{undefined}` — "You cannot share among zero groups — division by zero is UNDEFINED" (style the word in `text-incorrect`). Also show `0 ÷ n = 0` for contrast.
- Inline `QuickPractice`: random prompts with integer answers — "What is the additive inverse of 8?" (answer 8), "What is 17 × 0?", "What number is the identity for multiplication?"; multiplicative-inverse questions phrased to keep integer answers ("The inverse of 6 under multiplication is 1/□ — what goes in the box?").
**New file: `components/explorers/number-laws-explorer.tsx`** — unit color `unit-8`. Mode pills: **Commutative · Associative · Distributive**.
- *Commutative*: inputs a, b; operation selector (+ × ÷). Steps compute both `a ∘ b` and `b ∘ a` side by side and conclude: for + and ×, "Same answer — addition/multiplication IS commutative ✓"; for and ÷, show the two different results and "Different answers — subtraction/division is NOT commutative ✗" (this contrast is explicitly in the PDF's evaluation questions). Visual: two mirrored expression cards with a swap arrow between them; results colored `correct`/`incorrect` by match.
- *Associative*: inputs a, b, c; operation + or × (plus a "try " demo option that shows the counterexample). Steps: evaluate `(a ∘ b) ∘ c` bracket-first, then `a ∘ (b ∘ c)`, compare.
- *Distributive*: inputs a, b, c. Steps for `a × (b + c)`: (1) show the expression; (2) "The number outside multiplies EVERY number inside" → `a×b + a×c` with curved arrows from a to each term (SVG or absolutely-positioned spans); (3) evaluate both ways to the same answer.
- Inline `QuickPractice`: e.g. "Fill in the blank: 4 × (5 + 2) = 4×5 + 4×□" (integer answer), "Does 9 4 = 4 9? Enter 9 4:" style computations.
**New file: `components/explorers/exponents-explorer.tsx`** — unit color `unit-8`. Mode pills: **Expand · Index Laws**.
- *Expand*: inputs base (212) and power (06), guard result ≤ ~1,000,000. `buildExpandSteps(base, exp)`: (1) `2^4` — "the base is 2, the power (index) is 4: multiply the base by itself 4 times"; (2) `2 × 2 × 2 × 2` shown building up factor by factor across steps with running product; (3) `= 16`. Special-case steps: power 1 → `3^1 = 3` "any number to the power 1 is itself"; power 0 → `6^0 = 1` "any number to the power 0 is 1".
- *Index Laws*: choose Multiply or Divide; inputs base b, powers m, n. Steps for multiply: (1) `b^m × b^n`; (2) expand both into factor strings side by side; (3) "count the factors: m + n of them" → `b^{m+n}`; (4) evaluated value. Divide analogously with cancellation visual (strike-through matching factors — render the expansion as individual chips and add `line-through opacity-40` to cancelled ones as steps advance) → `b^{mn}`.
- Inline `QuickPractice`: seeded directly from the PDF quiz — ``, ``, `5⁶ / 5⁴` (ask for the answer as a power's value, keep numbers small), `7⁰`, plus randoms like `a^m × a^n = a^?` (answer: the exponent, an integer).
**New pages:** `app/lessons/unit-8-number-properties/{identity-inverse,number-laws,exponents}/page.tsx` following the standard topic-page shape.
### Phase 5 — Unit 6: Denary Place Value
**New file: `components/explorers/place-value-explorer.tsx`** — unit color `unit-6` (indigo), consistent with the binary explorers it sits beside (read `binary-converter-explorer.tsx` first and mirror its table/chart styling so the base-10 and base-2 pages feel like siblings).
- Input: a whole number 1999,999.
- `buildPlaceValueSteps(n)`: (1) show the number and "each digit has a place value that is a power of 10"; (2) reveal the place-value chart header row: `10^5 = 100000 · 10^4 = 10000 · … · 10^0 = 1` (only as many columns as the number has digits); (3) one step per digit left→right: highlight the column, show `9 × 10^5 = 900000`; (4) assemble expanded form `983275 = 9×10^5 + 8×10^4 + 3×10^3 + 2×10^2 + 7×10^1 + 5×10^0` in KaTeX; (5) sum check back to the original number.
- Visual: an HTML table styled like the PDF's chart (Place Value / Digit / Product rows), current column highlighted with `bg-unit-6-light`, inside an `overflow-x-auto` wrapper for mobile.
- Inline `QuickPractice`: "In 47,382 — what is the VALUE of the digit 7?" (answer 7000); "Which power of 10 is the hundreds column? Enter the exponent" (answer 2).
**New page:** `app/lessons/unit-6-number-system/place-value/page.tsx` (breadcrumb unit label `Unit 6: Number System`).
### Phase 6 — Practice hub generators
**New file: `lib/problems/generators/integer-problems.ts`** exporting (all return `MathProblem` with `answer: { kind: "integer", value }`, difficulty-scaled ranges, unique `id` via the same scheme other generators use — check `fraction-problems.ts` for the id/random helpers and reuse its style):
- `generateIntegerAddSubtract(difficulty)` — d1: single op, values 10…10; d2: values 20…20 including double negatives like `8 (7)`; d3: three-term chains. Steps narrate the sign rules exactly as the explorer does.
- `generateIntegerMultiplyDivide(difficulty)` — d1: single product/quotient with small factors (division always exact); d2: larger values; d3: triple products like `(2) × (3) × (4)` (the PDF homework question). Steps narrate sign-counting ("two negatives → positive").
- `generateTemperatureProblem(difficulty)` — word problems modeled on the PDF: "In London, the temperature is 3 °C on Monday. The next day it rose by 7 °C. What was the temperature on Tuesday?" Vary city, start temp, rise/fall.
**New file: `lib/problems/generators/number-properties-problems.ts`** exporting:
- `generateIdentityInverse(difficulty)` — additive-inverse and zero-fact questions with integer answers.
- `generateExponentEvaluate(difficulty)` — d1: squares/cubes of 29 and `n^0`/`n^1`; d2: PDF-quiz style (`6^3`, `2^3 2^1`); d3: index-law simplifications where the answer is the resulting exponent ("`4^4 × 4^3 = 4^x` — find x").
- `generateDistributive(difficulty)` — evaluate `a × (b + c)` numerically.
**New file: `lib/problems/generators/number-system-problems.ts`** exporting:
- `generateBinaryToDenary(difficulty)` — d1: 34 bits; d2: 56 bits (the PDF's `1011₂`, `111₂`, `1101₂` range); d3: 78 bits. Steps show the power-of-2 column products and the sum.
- `generateDigitValue(difficulty)` — "value of digit d in N" questions for base 10.
**Modify `app/practice/page.tsx`:**
- Import the new generators and append `TOPIC_GENERATORS` entries for: unit-5 `order-compare`→ *(skip — comparison answers don't fit integer input; leave its practice inline in the explorer)*, unit-5 `add-subtract` (`generateIntegerAddSubtract`), unit-5 `multiply-divide` (`generateIntegerMultiplyDivide`), unit-5 temperature word problems (attach to `multiply-divide` or `add-subtract` as a second entry with label "Temperature Problems"), unit-6 `place-value` (`generateDigitValue`), unit-6 `binary` (`generateBinaryToDenary`), unit-8 all three topics.
- Extend the `TopicGenerator["unitColor"]` union to `"unit-1" | ... | "unit-8"`, add `unit-5``unit-8` entries to the `unitColors` map (labels: "Integers", "Number System", "Coordinates", "Number Properties" — include unit-7 only if a coordinates generator is added; otherwise omit unit-7 from the filter row), and extend the filter-pill `as const` array accordingly.
Coordinates practice stays inside the explorers (click-the-grid needs custom input UI that `PracticeSection` doesn't support — do NOT extend `MathAnswer` for this; it's out of scope).
### Phase 7 — Verification
1. `npx tsc --noEmit` — zero errors.
2. `npm run lint` — zero errors.
3. `npm run build` — succeeds (catches server/client component violations; every page that renders an explorer must be `"use client"` or import a `"use client"` explorer, matching the existing pattern).
4. `npm run dev` and manually visit every new route (list in §3). For each: breadcrumbs correct, unit color correct, explorer loads, "Go" produces steps, StepControls play/step/reset work, QuickPractice checks answers correctly (test at least one correct and one incorrect answer each).
5. Specifically verify: the PDF shape-reveal dataset plots correctly and closes I→A; `n ÷ 0` shows "undefined" and never computes; `7⁰ = 1`; negative coordinates plot in the correct quadrants; ordering `-8, -10, -4, -3, -6, 5` ascending yields `-10, -8, -6, -4, -3, 5`.
6. `/practice`: new topics appear, unit filter pills for the new units work, answers validate.
7. Landing page: Units 78 render with art on every topic tile (no blank tiles — confirms `topic-art.tsx` keys match `unitSlug/topicSlug` exactly).
8. Check mobile layout (narrow viewport): the Cartesian grid and place-value table must scroll or scale, not overflow the page.
## 6. Acceptance Criteria (map back to the PDF)
- [ ] Order & compare integers: explorer covers number-line placement, real-world contexts, ascending/descending ordering, and `<`/`>` comparison, including the PDF's evaluation numbers
- [ ] Integer add/subtract and multiply/divide: already live; unchanged and still passing build
- [ ] Coordinates: plot-points + read-coordinates explorers, including the PDF's AI shape activity as a preset
- [ ] Identity & inverse: explorer covers identity 0/1, additive & multiplicative inverse (with the 1/5 sign note), ×0 = 0, ÷0 undefined
- [ ] Number laws: explorer demonstrates all three laws AND the non-commutativity/non-associativity of and ÷
- [ ] Exponents: explorer covers expansion, ``, `a⁰`, product & quotient index laws; PDF quiz questions appear in QuickPractice
- [ ] Denary place value: explorer reproduces the PDF's 983275 expanded-form walkthrough for any input
- [ ] Binary system: already live (binary page)
- [ ] No week numbers, dates, or scheduling language anywhere in app UI text, slugs, titles, or descriptions
- [ ] All new topics wired into: curriculum.ts, sidebar, mobile nav, lessons index, landing page (with art), and the practice hub where applicable
- [ ] `tsc`, `lint`, and `build` all clean