Files
edbridge-scholars/src/pages/student/lessons/EBRWFormStructureSenseLesson.tsx
2026-03-12 02:39:34 +06:00

942 lines
38 KiB
TypeScript

import React, { useRef, useState, useEffect } from "react";
import {
Check,
BookOpen,
AlertTriangle,
Zap,
Clock,
Users,
GitBranch,
} from "lucide-react";
import { PracticeFromDataset } from "../../../components/lessons/LessonShell";
import {
FORM_STRUCTURE_EASY,
FORM_STRUCTURE_MEDIUM,
} from "../../../data/rw/form-structure-sense";
import DecisionTreeWidget, {
type TreeScenario,
type TreeNode,
} from "../../../components/lessons/DecisionTreeWidget";
import RevealCardGrid, {
type RevealCard,
} from "../../../components/lessons/RevealCardGrid";
import useScrollReveal from "../../../components/lessons/useScrollReveal";
interface LessonProps {
onFinish?: () => void;
}
/* ── Data for RevealCardGrid widgets ── */
const SVA_DISGUISES: RevealCard[] = [
{
label: "Prepositional Phrase Decoy",
sublabel: "The list [of requirements] __ long.",
content: 'Cross out the phrase. "List" is singular → IS long.',
},
{
label: "Inverted Order (There is/are)",
sublabel: "There __ many reasons for the decision.",
content:
'"Many reasons" is the subject (plural) → THERE ARE. Flip: "Many reasons there are."',
},
{
label: "Gerund Subject",
sublabel: "Studying the data __ essential.",
content:
"A gerund (-ing phrase) as subject is always singular → IS essential.",
},
{
label: "Collective Nouns",
sublabel: "The committee __ voted unanimously.",
content:
"Committee = one group = singular → HAS voted. Same for team, group, family, audience, class.",
},
{
label: "Indefinite Pronouns",
sublabel: "Each of the participants __ required.",
content: "Each is always singular → IS required.",
},
{
label: "Neither/Nor Proximity",
sublabel: "Neither the principal nor the teachers __",
content:
"Or/nor: agree with the NEAREST noun → teachers (plural) → ARE responsible.",
},
];
const PRONOUN_RULES: RevealCard[] = [
{
label: "Number Agreement",
content:
'Pronoun must match its antecedent in number. "Each student should bring their own materials" is accepted on SAT for singular "they."',
},
{
label: "This/That Must Have a Clear Referent",
content:
'Always make sure "this" or "that" refers to a specific noun, not a vague idea. If unclear, replace with the noun.',
},
{
label: "Emphatic Pronouns",
content:
'These (himself/herself/themselves) can NEVER be the subject. ✗ "Himself was the only one who knew." ✓ "He himself was the only one who knew."',
},
{
label: "Missing Antecedent",
content:
'Every pronoun must refer to a specific named noun. If "they" could refer to two different nouns, replace it with the noun it means.',
},
{
label: "Person Consistency",
content:
'Do not switch between "one," "you," and "we" within the same passage. Match the pronoun person already established.',
},
];
const SVA_TREE: TreeNode = {
id: "sva-root",
question:
"Is there a prepositional phrase or interrupting clause BETWEEN the subject and verb?",
hint: 'Cross out everything introduced by "of," "in," "with," "for," "by," "including," etc., up to the next punctuation.',
yesLabel: "Yes — there is interrupting material",
noLabel: "No — subject and verb are adjacent",
yes: {
id: "cross-out",
question:
"After crossing out the interrupting material, is the true subject singular or plural?",
hint: "The true subject is the noun BEFORE the interrupting phrase. Ignore the noun inside the phrase.",
yesLabel: "Singular subject",
noLabel: "Plural subject",
yes: {
id: "singular-verb",
question: "",
result:
"✓ Use a SINGULAR verb (is, was, has, does). The interrupting phrase cannot change the subject.",
resultType: "correct",
ruleRef: 'The list [of requirements] IS long — not "are"',
},
no: {
id: "plural-verb",
question: "",
result:
"✓ Use a PLURAL verb (are, were, have, do). The interrupting phrase cannot change the subject.",
resultType: "correct",
ruleRef: 'The scientists [in the lab] ARE conducting — not "is"',
},
},
no: {
id: "no-interrupt",
question:
"Is the subject an indefinite pronoun (each, every, either, neither, anyone, everyone, someone, nobody)?",
hint: "These pronouns are always grammatically singular even when they refer to groups.",
yesLabel: "Yes — indefinite pronoun subject",
noLabel: "No — regular noun or pronoun",
yes: {
id: "indefinite",
question: "",
result:
"✓ Use a SINGULAR verb. Each, every, either, neither, anyone, everyone, someone, nobody are all grammatically singular.",
resultType: "correct",
ruleRef: 'Each of the students IS responsible — not "are"',
},
no: {
id: "regular-agree",
question: "",
result:
"✓ Match the verb to the subject normally: singular noun = singular verb; plural noun = plural verb.",
resultType: "info",
ruleRef: "Standard agreement: The dog barks / The dogs bark",
},
},
};
const TREE_SCENARIOS: TreeScenario[] = [
{
label: "SVA 1",
sentence:
"The collection of ancient manuscripts were donated to the university library.",
tree: SVA_TREE,
},
{
label: "SVA 2",
sentence:
"Neither of the proposed solutions address the root cause of the problem.",
tree: SVA_TREE,
},
{
label: "SVA 3",
sentence:
"The team of researchers have published their findings in three separate journals.",
tree: SVA_TREE,
},
];
const EBRWFormStructureSenseLesson: React.FC<LessonProps> = ({ onFinish }) => {
const [activeSection, setActiveSection] = useState(0);
const sectionsRef = useRef<(HTMLElement | null)[]>([]);
useEffect(() => {
const observers: IntersectionObserver[] = [];
sectionsRef.current.forEach((el, idx) => {
if (!el) return;
const obs = new IntersectionObserver(
([entry]) => {
if (entry.isIntersecting) setActiveSection(idx);
},
{ threshold: 0.3 },
);
obs.observe(el);
observers.push(obs);
});
return () => observers.forEach((o) => o.disconnect());
}, []);
useScrollReveal();
const scrollToSection = (index: number) => {
setActiveSection(index);
sectionsRef.current[index]?.scrollIntoView({ behavior: "smooth" });
};
const SectionMarker = ({
index,
title,
icon: Icon,
}: {
index: number;
title: string;
icon: React.ElementType;
}) => {
const isActive = activeSection === index;
const isPast = activeSection > index;
return (
<button
onClick={() => scrollToSection(index)}
className={`flex items-center gap-3 p-3 w-full rounded-lg text-left transition-all ${isActive ? "bg-purple-50" : "hover:bg-slate-50"}`}
>
<div
className={`w-8 h-8 rounded-full flex items-center justify-center shrink-0
${isActive ? "bg-purple-600 text-white" : isPast ? "bg-purple-400 text-white" : "bg-slate-200 text-slate-500"}`}
>
{isPast ? (
<Check className="w-4 h-4" />
) : (
// @ts-ignore
<Icon className="w-4 h-4" />
)}
</div>
<p
className={`text-sm font-bold ${isActive ? "text-purple-900" : "text-slate-600"}`}
>
{title}
</p>
</button>
);
};
return (
<div className="flex flex-col lg:flex-row min-h-screen">
<aside className="w-full lg:w-64 lg:fixed lg:top-14 lg:bottom-0 lg:overflow-y-auto p-4 border-r border-slate-200 bg-slate-50 z-0 hidden lg:block">
<nav className="space-y-2 pt-6">
<SectionMarker
index={0}
title="Subject-Verb Agreement"
icon={BookOpen}
/>
<SectionMarker
index={1}
title="Verb Forms &amp; Tense"
icon={Clock}
/>
<SectionMarker
index={2}
title="Pronouns &amp; Apostrophes"
icon={Users}
/>
<SectionMarker
index={3}
title="Modifiers &amp; Parallel"
icon={AlertTriangle}
/>
<SectionMarker index={4} title="SVA Decision Tree" icon={GitBranch} />
<SectionMarker index={5} title="Practice Questions" icon={Zap} />
</nav>
</aside>
<div className="flex-1 lg:ml-64 md:p-12 max-w-full mx-auto">
{/* ── Section 0: Subject-Verb Agreement ── */}
<section
ref={(el) => {
sectionsRef.current[0] = el;
}}
className="min-h-screen flex flex-col justify-center mb-24 pt-20 lg:pt-0"
>
<div className="inline-flex items-center gap-2 bg-purple-100 text-purple-700 px-3 py-1 rounded-full text-xs font-bold uppercase tracking-wider mb-4 w-fit">
Standard English Conventions Domain 3
</div>
<h2 className="text-4xl font-extrabold text-slate-900 mb-2">
Form, Structure &amp; Sense
</h2>
<p className="text-lg text-slate-500 mb-8">
Seven grammar skills: subject-verb agreement, verb forms, pronouns,
apostrophes, modification, parallel structure, and comma usage.
</p>
{/* §8.1 SVA */}
<div className="scroll-reveal stagger-1 rounded-2xl p-6 mb-8 bg-purple-50 border border-purple-200 space-y-4">
<h3 className="text-lg font-bold text-purple-900">
Subject-Verb Agreement: All 6 Disguises
</h3>
<p className="text-sm text-slate-700">
The SAT hides the subject behind phrases and structural tricks.
Tap each disguise to see how to solve it:
</p>
<RevealCardGrid
cards={SVA_DISGUISES}
columns={3}
accentColor="purple"
/>
<div className="bg-white border border-purple-200 rounded-xl p-4">
<p className="font-bold text-purple-800 text-sm mb-2">
Indefinite Pronoun Quick Reference
</p>
<div className="overflow-x-auto">
<table className="w-full text-xs border-collapse rounded-xl overflow-hidden">
<thead>
<tr className="bg-purple-100">
<th className="px-3 py-1 text-left text-purple-800">
Always Singular
</th>
<th className="px-3 py-1 text-left text-purple-800">
Always Plural
</th>
<th className="px-3 py-1 text-left text-purple-800">
Context-Dependent
</th>
</tr>
</thead>
<tbody>
<tr className="bg-white">
<td className="px-3 py-2 text-slate-600">
each, every, either, neither, one, anyone, everyone,
someone, no one, nobody, somebody, everybody, anything,
everything, something, nothing
</td>
<td className="px-3 py-2 text-slate-600">
both, few, many, several, others
</td>
<td className="px-3 py-2 text-slate-600">
all, any, more, most, none, some match to the noun in
the "of" phrase: "most of the water IS" / "most of the
results ARE"
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</section>
{/* ── Section 1: Verb Forms & Tense ── */}
<section
ref={(el) => {
sectionsRef.current[1] = el;
}}
className="min-h-screen flex flex-col justify-center mb-24"
>
<h2 className="text-4xl font-extrabold text-slate-900 mb-2">
Verb Forms &amp; Tense
</h2>
<p className="text-lg text-slate-500 mb-8">
The SAT tests specific verb form errors, not just tense consistency.
</p>
{/* Tense Table */}
<div className="scroll-reveal stagger-1 rounded-2xl p-6 mb-8 bg-purple-50 border border-purple-200 space-y-4">
<h3 className="text-lg font-bold text-purple-900">
Tense Consistency
</h3>
<div className="overflow-x-auto">
<table className="w-full text-sm border-collapse rounded-xl overflow-hidden">
<thead>
<tr className="bg-purple-600 text-white">
<th className="px-3 py-2 text-left text-xs">Tense</th>
<th className="px-3 py-2 text-left text-xs">
Signal Words
</th>
<th className="px-3 py-2 text-left text-xs">Example</th>
</tr>
</thead>
<tbody>
{[
[
"Simple Present",
"now, every day, always, usually, generally",
"The study examines 500 participants.",
],
[
"Simple Past",
"yesterday, last year, in 1990, ago",
"The study examined 500 participants.",
],
[
"Present Perfect",
"since, for, recently, already, yet",
"Researchers have found new evidence.",
],
[
"Past Perfect",
"before, by the time, had already",
"By 2020, scientists had confirmed the theory.",
],
[
"Future",
"tomorrow, next year, will",
"The team will publish next month.",
],
[
"Progressive",
"currently, at the moment, was/is + -ing",
"She was collecting data when the power failed.",
],
].map(([tense, signals, ex], i) => (
<tr
key={tense}
className={i % 2 === 0 ? "bg-white" : "bg-purple-50"}
>
<td className="px-3 py-2 font-bold text-purple-800 text-xs">
{tense}
</td>
<td className="px-3 py-2 text-slate-500 text-xs">
{signals}
</td>
<td className="px-3 py-2 text-slate-700 text-xs italic">
{ex}
</td>
</tr>
))}
</tbody>
</table>
</div>
</div>
{/* Past Conditional */}
<div className="scroll-reveal stagger-2 rounded-2xl p-6 mb-8 bg-white border border-slate-200 space-y-4">
<h3 className="text-lg font-bold text-slate-900">
Past Conditional &amp; Irregular Past Participles
</h3>
<div className="bg-purple-50 border border-purple-200 rounded-xl p-4">
<p className="font-bold text-purple-800 text-sm mb-2">
Past Conditional (Counterfactual)
</p>
<p className="text-xs text-slate-600 mb-2">
Use <span className="font-bold">had + past participle</span> in
the "if" clause and{" "}
<span className="font-bold">would have + past participle</span>{" "}
in the result clause.
</p>
<ul className="space-y-1 text-xs">
<li className="text-red-600">
"If she would have studied harder, she would have passed."
</li>
<li className="text-green-700">
"If she <strong>had studied</strong> harder, she{" "}
<strong>would have passed</strong>."
</li>
<li className="text-slate-400 italic mt-1">
The SAT frequently places "would have" in the if-clause
always wrong.
</li>
</ul>
</div>
<div className="overflow-x-auto">
<table className="w-full text-xs border-collapse rounded-xl overflow-hidden">
<thead>
<tr className="bg-slate-700 text-white">
<th className="px-3 py-2 text-left">Base Form</th>
<th className="px-3 py-2 text-left">Simple Past</th>
<th className="px-3 py-2 text-left">
Past Participle (with have/had)
</th>
</tr>
</thead>
<tbody>
{[
["go", "went", "gone (had gone ✓ / had went ✗)"],
["rise", "rose", "risen (had risen ✓ / had rose ✗)"],
["lie (recline)", "lay", "lain (had lain ✓)"],
["lay (place)", "laid", "laid (had laid ✓)"],
["choose", "chose", "chosen (had chosen ✓)"],
["swim", "swam", "swum (had swum ✓ / had swam ✗)"],
["begin", "began", "begun (had begun ✓ / had began ✗)"],
["see", "saw", "seen (had seen ✓ / had saw ✗)"],
].map(([base, past, participle], i) => (
<tr
key={base}
className={i % 2 === 0 ? "bg-white" : "bg-slate-50"}
>
<td className="px-3 py-2 font-bold text-purple-800">
{base}
</td>
<td className="px-3 py-2 text-slate-600">{past}</td>
<td className="px-3 py-2 text-slate-700">{participle}</td>
</tr>
))}
</tbody>
</table>
</div>
<div className="bg-amber-50 border border-amber-200 rounded-xl p-4">
<p className="font-bold text-amber-800 text-sm mb-2">
To vs. -ing After Certain Verbs
</p>
<div className="grid grid-cols-1 sm:grid-cols-3 gap-3 text-xs">
{[
{
label: "Verbs that take TO",
words:
"want, hope, plan, decide, need, agree, refuse, offer, expect, seem",
},
{
label: "Verbs that take -ING",
words:
"enjoy, avoid, finish, consider, deny, practice, suggest, admit, keep, quit",
},
{
label: "Meaning changes",
words:
"stop to do (pause) / stop doing (cease); remember to do / remember doing",
},
].map((v) => (
<div key={v.label}>
<p className="font-bold text-amber-700 mb-1">{v.label}</p>
<p className="text-slate-600">{v.words}</p>
</div>
))}
</div>
</div>
<div className="bg-purple-50 border border-purple-200 rounded-xl p-4">
<p className="font-bold text-purple-800 text-sm mb-2">
Passive Voice
</p>
<p className="text-xs text-slate-600 mb-3">
Passive voice reverses the usual subject-verb-object order: the
receiver of the action becomes the grammatical subject. The SAT
does not treat passive voice as inherently wrong but it tests
whether you can identify the correct form.
</p>
<ul className="space-y-1 text-xs mb-3">
<li className="text-slate-600">
<span className="font-bold">Active:</span> "The researcher
collected the data."
</li>
<li className="text-slate-600">
<span className="font-bold">Passive:</span> "The data was
collected by the researcher."
</li>
</ul>
<p className="text-xs text-slate-500 italic">
Passive is formed with a form of 'be' + past participle. On the
SAT, check whether the passive form matches the correct tense
and whether the subject-verb agreement is correct in the passive
construction.
</p>
</div>
</div>
</section>
{/* ── Section 2: Pronouns & Apostrophes ── */}
<section
ref={(el) => {
sectionsRef.current[2] = el;
}}
className="min-h-screen flex flex-col justify-center mb-24"
>
<h2 className="text-4xl font-extrabold text-slate-900 mb-2">
Pronouns &amp; Apostrophes
</h2>
<p className="text-lg text-slate-500 mb-8">
Pronoun errors are among the most commonly tested items in Form,
Structure &amp; Sense.
</p>
{/* Relative Pronouns */}
<div className="scroll-reveal stagger-1 rounded-2xl p-6 mb-8 bg-purple-50 border border-purple-200 space-y-4">
<h3 className="text-lg font-bold text-purple-900">Pronoun Rules</h3>
<div className="overflow-x-auto">
<table className="w-full text-sm border-collapse rounded-xl overflow-hidden">
<thead>
<tr className="bg-purple-600 text-white">
<th className="px-3 py-2 text-left text-xs">Pronoun</th>
<th className="px-3 py-2 text-left text-xs">Used For</th>
<th className="px-3 py-2 text-left text-xs">Example</th>
</tr>
</thead>
<tbody>
{[
[
"who / whom",
"People only",
'"the researcher who discovered…" / "the scientist whom they selected…"',
],
[
"which",
"Things / non-people (non-essential)",
'"the study, which examined 500 people…" — always gets a comma',
],
[
"that",
"Things / non-people (essential)",
'"the study that confirmed the theory" — no comma',
],
[
"where",
"Places",
'"the laboratory where the experiment occurred…"',
],
["when", "Times", '"the decade when the research began…"'],
].map(([pron, use, ex], i) => (
<tr
key={pron}
className={i % 2 === 0 ? "bg-white" : "bg-purple-50"}
>
<td className="px-3 py-2 font-bold text-purple-800 text-xs whitespace-nowrap">
{pron}
</td>
<td className="px-3 py-2 text-slate-600 text-xs">
{use}
</td>
<td className="px-3 py-2 text-slate-600 text-xs italic">
{ex}
</td>
</tr>
))}
</tbody>
</table>
</div>
<div className="bg-purple-900 text-white rounded-xl p-4">
<p className="font-bold text-sm mb-1">
Who vs. Whom Substitution Test
</p>
<ul className="text-xs text-purple-100 space-y-1">
<li>
<span className="font-bold">Who</span> = subject (substitutes
he/she): "Who wrote the report?" "He wrote it."
</li>
<li>
<span className="font-bold">Whom</span> = object (substitutes
him/her): "To whom did you give it?" "You gave it to him."
</li>
</ul>
</div>
<p className="text-sm font-semibold text-slate-800">
Additional Pronoun Rules tap to reveal:
</p>
<RevealCardGrid
cards={PRONOUN_RULES}
columns={3}
accentColor="purple"
/>
</div>
{/* Apostrophes */}
<div className="scroll-reveal stagger-2 rounded-2xl p-6 mb-8 bg-white border border-slate-200 space-y-4">
<h3 className="text-lg font-bold text-slate-900">Apostrophes</h3>
<div className="grid grid-cols-1 sm:grid-cols-2 gap-4">
<div className="card-tilt bg-purple-50 border border-purple-200 rounded-xl p-4">
<p className="font-bold text-purple-800 text-sm mb-2">
Noun Apostrophes (Possession)
</p>
<ul className="space-y-1 text-xs text-slate-700">
<li>
<span className="font-bold">Singular noun:</span> add 's →
the scientist's data
</li>
<li>
<span className="font-bold">Plural noun ending in s:</span>{" "}
add ' → the scientists' lab
</li>
<li>
<span className="font-bold">
Plural noun NOT ending in s:
</span>{" "}
add 's → the children's results
</li>
</ul>
</div>
<div className="card-tilt bg-purple-50 border border-purple-200 rounded-xl p-4">
<p className="font-bold text-purple-800 text-sm mb-2">
Pronoun Apostrophes (Contractions Only)
</p>
<div className="grid grid-cols-2 gap-x-2 gap-y-1 text-xs">
{[
["its", "possessive"],
["it's", "it is / it has"],
["their", "possessive"],
["they're", "they are"],
["whose", "possessive"],
["who's", "who is / who has"],
["your", "possessive"],
["you're", "you are"],
].map(([form, meaning]) => (
<div key={form} className="flex gap-1">
<span className="font-bold text-purple-700">{form}</span>
<span className="text-slate-500">= {meaning}</span>
</div>
))}
</div>
</div>
</div>
<div className="bg-amber-50 border border-amber-200 rounded-xl p-4">
<p className="font-bold text-amber-800 text-sm mb-1">
Apostrophe Shortcut
</p>
<p className="text-xs text-slate-700">
If you can read the word as two words (it is it's), it's a
contraction use the apostrophe. Pronouns{" "}
<span className="font-bold">never</span> use apostrophes for
possession (opposite of nouns).
</p>
</div>
</div>
</section>
{/* ── Section 3: Modifiers, Parallel Structure & Commas ── */}
<section
ref={(el) => {
sectionsRef.current[3] = el;
}}
className="min-h-screen flex flex-col justify-center mb-24"
>
<h2 className="text-4xl font-extrabold text-slate-900 mb-2">
Modifiers, Parallel Structure &amp; Commas
</h2>
<p className="text-lg text-slate-500 mb-8">
Three interrelated skills that test whether elements are correctly
placed and balanced.
</p>
{/* §8.5 Modification */}
<div className="scroll-reveal stagger-1 rounded-2xl p-6 mb-8 bg-purple-50 border border-purple-200 space-y-4">
<h3 className="text-lg font-bold text-purple-900">
Modification Errors
</h3>
<div className="space-y-3">
<div className="card-tilt bg-white border border-red-200 rounded-xl p-4">
<p className="font-bold text-red-800 text-sm mb-2">
Dangling Modifier
</p>
<p className="text-xs text-slate-500 mb-2">
The modifier has no logical subject in the sentence, or the
subject it should modify does not immediately follow it.
</p>
<ul className="space-y-1 text-xs">
<li className="text-red-600">
"Running quickly, the bus was missed." The bus isn't
running.
</li>
<li className="text-green-700">
✓ "Running quickly, she missed the bus." — She was running;
subject appears right after comma.
</li>
<li className="text-amber-700 italic mt-1">
Possessive Trap: "Wishing to pass,{" "}
<strong>the student's</strong> exam" — the possessive makes
"exam" the subject. Use: "Wishing to pass,{" "}
<strong>the student</strong> reviewed"
</li>
</ul>
</div>
<div className="card-tilt bg-white border border-amber-200 rounded-xl p-4">
<p className="font-bold text-amber-800 text-sm mb-2">
Misplaced Modifier
</p>
<p className="text-xs text-slate-500 mb-2">
The modifier is positioned too far from the noun it modifies.
</p>
<ul className="space-y-1 text-xs">
<li className="text-red-600">
✗ "She only eats salad." — only implies she does nothing
else?
</li>
<li className="text-green-700">
✓ "She eats only salad." — only modifies "salad."
</li>
</ul>
</div>
<div className="card-tilt bg-white border border-slate-200 rounded-xl p-4">
<p className="font-bold text-purple-800 text-sm mb-2">
Parenthetical Modifiers — Matching Punctuation
</p>
<p className="text-xs text-slate-500 mb-2">
A non-essential phrase must be enclosed in matching
punctuation: two commas, two dashes, or two parentheses. Never
mix them.
</p>
<ul className="space-y-1 text-xs">
<li className="text-red-600">
✗ "The researcher, who had published 40 papers presented
her findings."
</li>
<li className="text-green-700">
✓ "The researcher, who had published 40 papers, presented
her findings."
</li>
<li className="text-green-700">
✓ "The researcher who had published 40 papers presented
her findings."
</li>
</ul>
</div>
</div>
</div>
{/* §8.6 Parallel Structure */}
<div className="scroll-reveal stagger-2 rounded-2xl p-6 mb-8 bg-white border border-slate-200 space-y-4">
<h3 className="text-lg font-bold text-slate-900">
Parallel Structure
</h3>
<div className="space-y-2">
{[
{
type: "Lists",
bad: "She enjoys hiking, to swim, and reading.",
good: "She enjoys hiking, swimming, and reading.",
note: "All items must be the same grammatical form.",
},
{
type: "Correlative Pairs (not onlybut also, bothand, eitheror)",
bad: "He not only speaks French but also is fluent in German.",
good: "He not only speaks French but also speaks German.",
note: 'What follows "not only" must be parallel to what follows "but also."',
},
{
type: "Comparisons",
bad: "Running is healthier than to sit all day.",
good: "Running is healthier than sitting all day.",
note: "Both sides of a comparison must be the same form.",
},
{
type: "Semicolon Lists",
bad: "The study examined diet; the exercise habits; and their stress levels.",
good: "The study examined diet; exercise habits; and stress levels.",
note: "Items separated by semicolons must be parallel.",
},
].map((p) => (
<div
key={p.type}
className="card-tilt bg-slate-50 border border-slate-200 rounded-xl p-4"
>
<p className="font-bold text-purple-800 text-xs mb-1">
{p.type}
</p>
<p className="text-xs text-red-600">✗ {p.bad}</p>
<p className="text-xs text-green-700">✓ {p.good}</p>
<p className="text-xs text-slate-400 italic mt-1">{p.note}</p>
</div>
))}
</div>
</div>
{/* §8.7 Commas */}
<div className="scroll-reveal stagger-3 rounded-2xl p-6 mb-8 bg-purple-50 border border-purple-200 space-y-4">
<h3 className="text-lg font-bold text-purple-900">Comma Rules</h3>
<div className="grid grid-cols-1 sm:grid-cols-2 gap-4">
<div className="card-tilt bg-white border border-green-200 rounded-xl p-4">
<p className="font-bold text-green-800 text-sm mb-2">
When a Comma IS Required
</p>
<ul className="space-y-1 text-xs text-slate-700">
<li>
✓ After an introductory element at the start of a sentence.
</li>
<li>
✓ Before and after a non-essential (parenthetical) clause.
</li>
<li>✓ Before a FANBOYS joining two independent clauses.</li>
<li>✓ Between items in a list of three or more.</li>
<li>
✓ Between coordinate adjectives that independently modify
the noun.
</li>
</ul>
</div>
<div className="card-tilt bg-white border border-red-200 rounded-xl p-4">
<p className="font-bold text-red-800 text-sm mb-2">
When a Comma Is NOT Used
</p>
<ul className="space-y-1 text-xs text-slate-700">
<li>✗ Between a subject and its verb.</li>
<li>
✗ Before a subordinate clause that follows the main clause
("left because she was tired" — no comma before "because").
</li>
<li>
✗ Before a FANBOYS when one side is a phrase, not an IC.
</li>
<li>✗ After a FANBOYS conjunction.</li>
<li>✗ Between a verb and its object or complement.</li>
</ul>
</div>
</div>
</div>
<div className="scroll-reveal-scale golden-rule-glow bg-purple-900 text-white rounded-2xl p-5 mb-8">
<p className="font-bold mb-1">Golden Rule</p>
<p className="text-sm text-purple-100">
For SVA: always cross out the material between subject and verb.
For modifiers: the noun being modified must immediately follow the
modifying phrase. For apostrophes: pronouns never use apostrophes
for possession — only for contractions.
</p>
</div>
</section>
{/* ── Section 4: SVA Decision Tree ── */}
<section
ref={(el) => {
sectionsRef.current[4] = el;
}}
className="min-h-screen flex flex-col justify-center mb-24"
>
<h2 className="text-4xl font-extrabold text-slate-900 mb-2">
SVA Decision Tree
</h2>
<p className="text-lg text-slate-500 mb-8">
Work through subject-verb agreement step by step. Find the true
subject, then match the verb.
</p>
<DecisionTreeWidget scenarios={TREE_SCENARIOS} accentColor="purple" />
</section>
{/* ── Section 5: Practice ── */}
<section
ref={(el) => {
sectionsRef.current[5] = el;
}}
className="min-h-screen flex flex-col justify-center mb-24"
>
<h2 className="text-4xl font-extrabold text-slate-900 mb-6">
Practice Questions
</h2>
{FORM_STRUCTURE_EASY.slice(0, 2).map((q) => (
<PracticeFromDataset key={q.id} question={q} color="purple" />
))}
{FORM_STRUCTURE_MEDIUM.slice(0, 1).map((q) => (
<PracticeFromDataset key={q.id} question={q} color="purple" />
))}
<div className="mt-8 text-center">
<button
onClick={onFinish}
className="px-6 py-3 bg-purple-900 text-white font-bold rounded-full hover:bg-purple-700 transition-colors"
>
Finish Lesson
</button>
</div>
</section>
</div>
</div>
);
};
export default EBRWFormStructureSenseLesson;