front page enhancements

This commit is contained in:
2026-06-11 06:42:50 -04:00
parent e44f19fd07
commit 1648454f94
11 changed files with 234 additions and 51 deletions

View File

@@ -0,0 +1,222 @@
import type { ReactNode } from "react";
/**
* Decorative SVG artwork for the Topic Explorer tiles on the landing page.
* Each topic gets a simple math-themed illustration drawn in white over the
* tile's gradient background.
*/
function Frame({ children }: { children: ReactNode }) {
return (
<svg
viewBox="0 0 100 75"
className="pointer-events-none absolute inset-0 h-full w-full"
aria-hidden="true"
>
<circle cx="88" cy="8" r="14" fill="white" opacity="0.08" />
<circle cx="8" cy="66" r="18" fill="white" opacity="0.08" />
{children}
</svg>
);
}
const glyphText = {
fill: "white",
fontWeight: 800,
fontFamily: "inherit",
} as const;
const art: Record<string, ReactNode> = {
// Unit 1 — Fractions
"unit-1-fractions/add-subtract": (
<>
<circle cx="30" cy="32" r="15" fill="white" opacity="0.3" />
<path d="M30 17 A15 15 0 0 1 45 32 L30 32 Z" fill="white" opacity="0.9" />
<text x="63" y="32" fontSize="22" textAnchor="middle" dominantBaseline="middle" {...glyphText}>+</text>
<text x="82" y="32" fontSize="22" textAnchor="middle" dominantBaseline="middle" {...glyphText}>&minus;</text>
</>
),
"unit-1-fractions/multiply": (
<>
<text x="30" y="20" fontSize="14" textAnchor="middle" dominantBaseline="middle" {...glyphText}>1</text>
<rect x="20" y="28" width="20" height="3" rx="1.5" fill="white" />
<text x="30" y="44" fontSize="14" textAnchor="middle" dominantBaseline="middle" {...glyphText}>2</text>
<text x="52" y="32" fontSize="20" textAnchor="middle" dominantBaseline="middle" {...glyphText}>&times;</text>
<text x="73" y="20" fontSize="14" textAnchor="middle" dominantBaseline="middle" {...glyphText}>3</text>
<rect x="63" y="28" width="20" height="3" rx="1.5" fill="white" />
<text x="73" y="44" fontSize="14" textAnchor="middle" dominantBaseline="middle" {...glyphText}>4</text>
</>
),
"unit-1-fractions/divide": (
<>
<circle cx="50" cy="16" r="5" fill="white" />
<rect x="26" y="29" width="48" height="5" rx="2.5" fill="white" />
<circle cx="50" cy="47" r="5" fill="white" />
</>
),
"unit-1-fractions/mixed-operations": (
<>
<text x="22" y="32" fontSize="30" textAnchor="middle" dominantBaseline="middle" {...glyphText}>(</text>
<text x="42" y="32" fontSize="16" textAnchor="middle" dominantBaseline="middle" {...glyphText}>+</text>
<text x="58" y="32" fontSize="16" textAnchor="middle" dominantBaseline="middle" {...glyphText}>&times;</text>
<text x="78" y="32" fontSize="30" textAnchor="middle" dominantBaseline="middle" {...glyphText}>)</text>
</>
),
"unit-1-fractions/fraction-of-quantity": (
<>
{[0, 1, 2, 3].map((col) =>
[0, 1].map((row) => (
<circle
key={`${col}-${row}`}
cx={26 + col * 16}
cy={24 + row * 16}
r="6"
fill="white"
opacity={col < 2 ? 0.95 : 0.3}
/>
)),
)}
</>
),
"unit-1-fractions/whole-from-fractions": (
<>
<path d="M50 32 L50 14 A18 18 0 1 1 35 47 Z" fill="white" opacity="0.9" />
<path d="M50 32 L50 14 A18 18 0 0 0 35 47 Z" fill="white" opacity="0.25" />
<text x="40" y="29" fontSize="12" textAnchor="middle" dominantBaseline="middle" {...glyphText}>?</text>
</>
),
// Unit 2 — Decimals
"unit-2-decimals/compare-order": (
<>
<text x="26" y="32" fontSize="16" textAnchor="middle" dominantBaseline="middle" {...glyphText}>0.3</text>
<text x="50" y="32" fontSize="22" textAnchor="middle" dominantBaseline="middle" {...glyphText}>&lt;</text>
<text x="74" y="32" fontSize="16" textAnchor="middle" dominantBaseline="middle" {...glyphText}>0.7</text>
</>
),
"unit-2-decimals/approximate": (
<>
<text x="50" y="30" fontSize="34" textAnchor="middle" dominantBaseline="middle" {...glyphText}>&asymp;</text>
</>
),
"unit-2-decimals/standard-form": (
<>
<text x="34" y="34" fontSize="18" textAnchor="middle" dominantBaseline="middle" {...glyphText}>&times;10</text>
<text x="62" y="22" fontSize="12" textAnchor="middle" dominantBaseline="middle" {...glyphText}>n</text>
</>
),
// Unit 3 — Decimal Operations
"unit-3-decimal-operations/convert": (
<>
<text x="26" y="20" fontSize="10" textAnchor="middle" dominantBaseline="middle" {...glyphText}>1</text>
<rect x="19" y="25" width="14" height="2.5" rx="1.25" fill="white" />
<text x="26" y="35" fontSize="10" textAnchor="middle" dominantBaseline="middle" {...glyphText}>2</text>
<path d="M40 22 H62 M62 22 l-5 -4 M62 22 l-5 4" stroke="white" strokeWidth="2.5" strokeLinecap="round" fill="none" />
<path d="M62 36 H40 M40 36 l5 -4 M40 36 l5 4" stroke="white" strokeWidth="2.5" strokeLinecap="round" fill="none" />
<text x="77" y="28" fontSize="13" textAnchor="middle" dominantBaseline="middle" {...glyphText}>0.5</text>
</>
),
"unit-3-decimal-operations/add-subtract": (
<>
<text x="56" y="18" fontSize="13" textAnchor="end" dominantBaseline="middle" {...glyphText}>2.50</text>
<text x="56" y="34" fontSize="13" textAnchor="end" dominantBaseline="middle" {...glyphText}>1.25</text>
<text x="28" y="34" fontSize="13" textAnchor="middle" dominantBaseline="middle" {...glyphText}>+</text>
<rect x="22" y="42" width="38" height="2.5" rx="1.25" fill="white" />
</>
),
"unit-3-decimal-operations/multiply-divide": (
<>
<text x="34" y="30" fontSize="24" textAnchor="middle" dominantBaseline="middle" {...glyphText}>&times;</text>
<text x="66" y="30" fontSize="24" textAnchor="middle" dominantBaseline="middle" {...glyphText}>&divide;</text>
</>
),
// Unit 4 — Ratio & Proportion
"unit-4-ratio-proportion/define-ratio": (
<>
<circle cx="26" cy="24" r="6" fill="white" />
<circle cx="26" cy="40" r="6" fill="white" />
<text x="48" y="31" fontSize="22" textAnchor="middle" dominantBaseline="middle" {...glyphText}>:</text>
<circle cx="68" cy="18" r="6" fill="white" opacity="0.85" />
<circle cx="68" cy="32" r="6" fill="white" opacity="0.85" />
<circle cx="68" cy="46" r="6" fill="white" opacity="0.85" />
</>
),
"unit-4-ratio-proportion/fractions-and-ratios": (
<>
<text x="28" y="20" fontSize="12" textAnchor="middle" dominantBaseline="middle" {...glyphText}>1</text>
<rect x="20" y="26" width="16" height="2.5" rx="1.25" fill="white" />
<text x="28" y="37" fontSize="12" textAnchor="middle" dominantBaseline="middle" {...glyphText}>3</text>
<text x="50" y="28" fontSize="14" textAnchor="middle" dominantBaseline="middle" {...glyphText}>=</text>
<text x="72" y="28" fontSize="15" textAnchor="middle" dominantBaseline="middle" {...glyphText}>1:2</text>
</>
),
"unit-4-ratio-proportion/simplify-ratios": (
<>
<text x="24" y="30" fontSize="14" textAnchor="middle" dominantBaseline="middle" {...glyphText}>6:9</text>
<path d="M42 30 H60 M60 30 l-5 -4 M60 30 l-5 4" stroke="white" strokeWidth="2.5" strokeLinecap="round" fill="none" />
<text x="76" y="30" fontSize="15" textAnchor="middle" dominantBaseline="middle" {...glyphText}>2:3</text>
</>
),
"unit-4-ratio-proportion/divide-in-ratio": (
<>
<rect x="18" y="24" width="26" height="14" rx="2" fill="white" opacity="0.95" />
<rect x="46" y="24" width="13" height="14" rx="2" fill="white" opacity="0.6" />
<rect x="61" y="24" width="13" height="14" rx="2" fill="white" opacity="0.6" />
<text x="46" y="52" fontSize="12" textAnchor="middle" dominantBaseline="middle" {...glyphText}>2 : 1 : 1</text>
</>
),
"unit-4-ratio-proportion/word-problems": (
<>
<path
d="M26 14 h48 a5 5 0 0 1 5 5 v22 a5 5 0 0 1 -5 5 H44 l-9 9 v-9 h-9 a5 5 0 0 1 -5 -5 V19 a5 5 0 0 1 5 -5 Z"
fill="white"
opacity="0.3"
/>
<text x="50" y="30" fontSize="18" textAnchor="middle" dominantBaseline="middle" {...glyphText}>?</text>
</>
),
// Unit 5 — Integers
"unit-5-integers/add-subtract": (
<>
<path d="M14 36 H86 M20 36 v-6 M35 36 v-6 M50 36 v-8 M65 36 v-6 M80 36 v-6" stroke="white" strokeWidth="2.5" strokeLinecap="round" fill="none" />
<text x="20" y="20" fontSize="10" textAnchor="middle" dominantBaseline="middle" {...glyphText}>&minus;2</text>
<text x="50" y="18" fontSize="10" textAnchor="middle" dominantBaseline="middle" {...glyphText}>0</text>
<text x="80" y="20" fontSize="10" textAnchor="middle" dominantBaseline="middle" {...glyphText}>+2</text>
</>
),
"unit-5-integers/multiply-divide": (
<>
<text x="30" y="24" fontSize="16" textAnchor="middle" dominantBaseline="middle" {...glyphText}>&minus;&times;&minus;</text>
<path d="M58 24 H72 M72 24 l-4 -3 M72 24 l-4 3" stroke="white" strokeWidth="2.5" strokeLinecap="round" fill="none" />
<text x="82" y="24" fontSize="16" textAnchor="middle" dominantBaseline="middle" {...glyphText}>+</text>
</>
),
// Unit 6 — Number System
"unit-6-number-system/binary": (
<>
<text x="50" y="24" fontSize="16" textAnchor="middle" dominantBaseline="middle" letterSpacing="3" {...glyphText}>1011</text>
<text x="50" y="44" fontSize="11" textAnchor="middle" dominantBaseline="middle" opacity="0.8" {...glyphText}>base 2</text>
</>
),
"unit-6-number-system/quaternary": (
<>
<text x="50" y="24" fontSize="16" textAnchor="middle" dominantBaseline="middle" letterSpacing="3" {...glyphText}>1230</text>
<text x="50" y="44" fontSize="11" textAnchor="middle" dominantBaseline="middle" opacity="0.8" {...glyphText}>base 4</text>
</>
),
};
const fallback: ReactNode = (
<>
<circle cx="34" cy="30" r="10" fill="white" opacity="0.6" />
<rect x="56" y="20" width="20" height="20" rx="3" fill="white" opacity="0.6" />
</>
);
export function TopicArt({ unitSlug, topicSlug }: { unitSlug: string; topicSlug: string }) {
return <Frame>{art[`${unitSlug}/${topicSlug}`] ?? fallback}</Frame>;
}

View File

@@ -22,7 +22,7 @@ export function Header() {
</Link>
<div className="flex items-center gap-2 text-xs font-bold sm:text-sm">
<span className="rounded-full bg-[#1a49b6] px-3 py-1">Ages 12-16</span>
<span className="rounded-full bg-[#1a49b6] px-3 py-1">Form 1 Term 2</span>
<span className="rounded-full bg-[#1a49b6] px-3 py-1">Form 1</span>
</div>
</div>
<nav className="flex flex-wrap gap-1 bg-[#1b49b5] px-2 pb-2 pt-1">