34 KiB
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 11–12), 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 1–4 (Fractions, Decimals, Decimal Operations, Ratio & Proportion) and has already started on Term 1 material as Units 5–6 (Integers, Number System).
unit_plan_term_1.pdf (8 pages, AY 2025–2026, 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):
- Order & compare integers (new topic in existing Unit 5)
- Cartesian plane: plot points & read coordinates (new Unit 7)
- Identity, inverse, zero facts (new Unit 8, topic 1)
- Commutative/associative/distributive laws (Unit 8, topic 2)
- Powers & exponents with index laws (Unit 8, topic 3)
- 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)
lib/curriculum.ts— single source of truth.Unitinterface hasnumber: 1|2|3|4|5|6andcolor: "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 iteratecurriculumautomatically — but each keeps its own hardcoded color-class map keyed by"unit-N"that must gainunit-7/unit-8entries (Tailwind cannot generate class names dynamically).- 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. - Unit overview page pattern — see
app/lessons/unit-5-integers/page.tsx: server component, readscurriculum[unitIndex], renders a<Badge variant="unit-N">header and asm:grid-cols-2grid of<Card accent="unit-N" hover>links with numbered chips (bg-unit-N-light text-unit-N-dark). - Explorer pattern — see
components/explorers/integer-add-subtract-explorer.tsx(594 lines; the canonical template). Structure:"use client", localStepinterface{ label: string; math: string; ...visualization payload }- A pure
buildXyzSteps(...)function that returnsStep[]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 localerrorstate - A display
<Card>showingstep.label,<MathDisplay math={step.math} />(KaTeX string), and the custom SVG/div visualization that animates with the current step <StepControls>fromcomponents/explorers/step-controls.tsxwired viacurrentStep / totalSteps / isPlaying / onStepForward / onStepBack / onTogglePlay / onReset / canStepForward / canStepBack(note: it expectscurrentStep + 1as the 1-based display value)- A result
<Card>shown when steps complete - An inline
QuickPracticecomponent (local to the file): random problem generator, number input, Check/Next buttons, runningscore.correct/score.totalchip, Enter-key handling, correct/incorrect feedback usingborder-correct bg-correct-light/border-incorrect bg-incorrect-lightclasses
- Color system —
app/globals.cssdefines per-unit CSS vars in:root(--unit-N,--unit-N-light,--unit-N-dark) and mirrors them in the@theme inlineblock as--color-unit-N*so Tailwind classes likebg-unit-7,text-unit-7-dark,bg-unit-7-light,border-unit-7/40work. Also available:--correct,--incorrect(+-lightvariants),--foreground,--muted,--surface,--border. - Practice hub —
app/practice/page.tsxholdsTOPIC_GENERATORS(generator functions fromlib/problems/generators/*), aunitColorsmap (currently only units 1–4), and a filter-pill array(["unit-1","unit-2","unit-3","unit-4"] as const).components/practice/practice-section.tsxrenders input UI switched onproblem.answer.kind— it already supports"integer"(plain number input), so all new generators should return{ kind: "integer", value }answers.MathProblem(inlib/problems/types.ts) requiresid,prompt(may contain KaTeX-able text),answer,hints: string[],steps: SolutionStep[]({ explanation, math? }).Difficulty = 1 | 2 | 3. - Landing page art —
components/home/topic-art.tsxexportsart: Record<string, ReactNode>keyed by"unitSlug/topicSlug", each a small white-on-gradient SVG glyph inside the shared 100×75 viewBoxFrame. 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)
-
lib/curriculum.ts- Extend
Unit["number"]union to1|2|3|4|5|6|7|8andUnit["color"]union to include"unit-7" | "unit-8". - Extend
getUnitColor's parameter type andcolorsrecord with7: "unit-7",8: "unit-8". - Insert into unit 5's
topics(as the FIRST element):{ 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):{ 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:
{ 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" }, ], },
- Extend
-
app/globals.css— add beside the existing--unit-6definitions in:root:--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 inlineblock (beside--color-unit-6-dark):--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); -
components/ui/badge.tsx— extendBadgeVariantunion with"unit-7" | "unit-8"and add tovariantStyles:"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", -
components/ui/card.tsx— extend theaccentprop union andaccentStyleswith"unit-7": "border-l-4 border-l-unit-7"and the unit-8 equivalent. -
components/layout/sidebar.tsx— addunit-7/unit-8entries tounitColorMap, following the exact shape of the existing entries (active,dot,heading,hoverBgkeys with the unit's color classes). -
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. -
app/page.tsx(landing) — add tounitStyles:"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
topicTilesgradient array by index, so no per-topic change is needed there. -
components/home/topic-art.tsx— add 7 entries to theartrecord (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 small10² 10¹ 10⁰labels (use<text>withfontSize~8–10)"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 = nstyle glyph, or two circles balancing on a seesaw with0at the pivot"unit-8-number-properties/number-laws":a + b = b + awith a swap arrow (curved<path>with arrowhead)"unit-8-number-properties/exponents": large2with superscript4and= 16
Checkpoint: npx tsc --noEmit passes; landing page, sidebar, and mobile nav show Units 7–8 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:
-
"Number Line" mode (objective 1–2: 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 viaMathDisplay). - 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.
-
"Order" mode (objective 3):
- Input: a comma-separated list of 3–6 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).
-
"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 < 5rendered withMathDisplay.
- 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
Inline QuickPractice (same Card layout/score-chip pattern as the template): alternate two question types randomly —
- Compare: show
a \; \square \; bwith 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; lightstroke="var(--border)"gridlines, heavier axes through the origin invar(--foreground)), axis numeric labels every 2 (skip 0 clutter; label origin0once), arrowheads +x/ylabels at the axis ends. - Props:
points: { x: number; y: number; label?: string; color?: string }[],segments: { from: Point; to: Point }[](polylines drawn so far), optionalhighlightpoint 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), optionalonGridClick?: (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:
- "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 tellsCartesianGridwhat arrows/guides/points to draw. - "Shape Reveal" (the PDF's evaluation activity): a select of 3–4 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 2–3 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).StepControlsdrives 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/×1badge 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 intext-incorrect). Also show0 ÷ n = 0for 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 ∘ bandb ∘ aside 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 coloredcorrect/incorrectby match. - Associative: inputs a, b, c; operation + or × (plus a "try −" demo option that shows the counterexample). Steps: evaluate
(a ∘ b) ∘ cbracket-first, thena ∘ (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×cwith 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 (2–12) and power (0–6), 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 × 2shown 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 addline-through opacity-40to cancelled ones as steps advance) →b^{m−n}. - Inline
QuickPractice: seeded directly from the PDF quiz —6³,2³ − 2¹,5⁶ / 5⁴(ask for the answer as a power's value, keep numbers small),7⁰, plus randoms likea^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 1–999,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, show9 × 10^5 = 900000; (4) assemble expanded form983275 = 9×10^5 + 8×10^4 + 3×10^3 + 2×10^2 + 7×10^1 + 5×10^0in 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 anoverflow-x-autowrapper 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 like8 − (−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 2–9 andn^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)— evaluatea × (b + c)numerically.
New file: lib/problems/generators/number-system-problems.ts exporting:
generateBinaryToDenary(difficulty)— d1: 3–4 bits; d2: 5–6 bits (the PDF's1011₂,111₂,1101₂range); d3: 7–8 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_GENERATORSentries for: unit-5order-compare→ (skip — comparison answers don't fit integer input; leave its practice inline in the explorer), unit-5add-subtract(generateIntegerAddSubtract), unit-5multiply-divide(generateIntegerMultiplyDivide), unit-5 temperature word problems (attach tomultiply-divideoradd-subtractas a second entry with label "Temperature Problems"), unit-6place-value(generateDigitValue), unit-6binary(generateBinaryToDenary), unit-8 all three topics. - Extend the
TopicGenerator["unitColor"]union to"unit-1" | ... | "unit-8", addunit-5–unit-8entries to theunitColorsmap (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-pillas constarray 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
npx tsc --noEmit— zero errors.npm run lint— zero errors.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).npm run devand 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).- Specifically verify: the PDF shape-reveal dataset plots correctly and closes I→A;
n ÷ 0shows "undefined" and never computes;7⁰ = 1; negative coordinates plot in the correct quadrants; ordering-8, -10, -4, -3, -6, 5ascending yields-10, -8, -6, -4, -3, 5. /practice: new topics appear, unit filter pills for the new units work, answers validate.- Landing page: Units 7–8 render with art on every topic tile (no blank tiles — confirms
topic-art.tsxkeys matchunitSlug/topicSlugexactly). - 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 A–I 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¹,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, andbuildall clean