/* chapter10.jsx — Chapter 10: The Blinker (the 555 timer). */

const { useState, useEffect, useRef } = React;

const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{
  "theme": "paper",
  "showChart": true,
  "audience": "adult"
}/*EDITMODE-END*/;

function BigIdeaBeat({ onView, kids }) {
  const ref = useInViewCallback(onView);
  return (
    <div className="beat" id="begin" data-screen-label="What is a 555" ref={ref}>
      <div className="beat-marker">§ 01 · the chip that blinks</div>
      {kids ? (
        <>
          <h2 className="serif">A tiny chip<br/>that <em>blinks</em>.</h2>
          <p className="lede">
            The 555 is the most famous little chip in the world. Give it a
            bucket (capacitor) and a couple of pinches (resistors), and it
            turns a light on and off, over and over, all by itself.
          </p>
          <p>It's how toys flash, how metronomes tick, how things go beep.</p>
        </>
      ) : (
        <>
          <h2 className="serif">The world's<br/>favorite <em>timer</em>.</h2>
          <p className="lede">
            The 555 has been made for fifty years and sells by the billion. In
            "astable" mode it's an oscillator: it flips its output high and low
            forever, with no input — a self-driving blinker.
          </p>
          <p>
            Everything you need is already in your toolkit: a capacitor that
            fills and drains, and resistors that set how fast. The 555 just
            watches the bucket and flips a switch at two marks.
          </p>
        </>
      )}
      <div className="pull">It's just a bucket, two marks, and a flush valve.</div>
    </div>
  );
}

function HowBeat({ onView, kids }) {
  const ref = useInViewCallback(onView);
  return (
    <div className="beat" id="how" data-screen-label="How it works" ref={ref}>
      <div className="beat-marker">§ 02 · fill, flush, repeat</div>
      <h2 className="serif">{kids ? "Fill, flush, repeat." : "Two marks and a flush."}</h2>
      <p className="lede">
        {kids
          ? <>Watch the bucket on the right. It fills up to the <b>HIGH</b> mark, then a valve opens and it drains down to the <b>LOW</b> mark, then fills again — forever. The light is ON while it's filling.</>
          : <>The 555 charges the cap toward the supply through the resistors. At <b>⅔</b> of the way it trips a comparator, opens the discharge path, and the cap drains to <b>⅓</b>, where it trips again and refills. The output is high during charging.</>}
      </p>
      <div className="card" style={{ background: "transparent", padding: "18px 20px", marginTop: 16, maxWidth: 560 }}>
        <div className="eyebrow" style={{ marginBottom: 8 }}>{kids ? "the rhythm" : "it oscillates between"}</div>
        <p style={{ margin: 0, fontSize: 16, color: "var(--ink-soft)" }}>
          {kids ? <>Up to ⅔ full → drain to ⅓ → back up to ⅔ → … The bucket never rests, so the light never stops blinking.</>
                : <>⅓ and ⅔ of the supply voltage, charging through R₁+R₂ and discharging through R₂ — a relaxation oscillator.</>}
        </p>
      </div>
    </div>
  );
}

function SpeedBeat({ R, C, setR, setC, onView, kids }) {
  const ref = useInViewCallback(onView);
  const blinkHz = (1.0 / Math.max(0.3, (R * C) / 6) / 2).toFixed(2);
  return (
    <div className="beat" id="speed" data-screen-label="Blink speed" ref={ref}>
      <div className="beat-marker">§ 03 · faster, slower</div>
      <h2 className="serif">Set the<br/><em>blink rate</em>.</h2>
      <SonifyHint text="Sound's on — listen: the 555 clicks in time with the blink." />
      <p className="lede">
        {kids
          ? <>Bigger bucket or tighter pinch = slower blink. Smaller bucket or looser pinch = faster blink. Try it!</>
          : <>The blink rate is set by R and C: a bigger R·C means a slower fill and drain, so a slower blink. The classic formula is f ≈ 1.44 / ((R₁+2R₂)·C).</>}
      </p>
      <div className="rule">try it</div>
      <Slider name={kids ? "Pinch (R)" : "Resistance · R"} value={R} min={1} max={12} step={0.5}
              unit="" accent="" onChange={setR} />
      <Slider name={kids ? "Bucket (C)" : "Capacitance · C"} value={C} min={0.5} max={8} step={0.5}
              unit="" accent="water" onChange={setC} />
      <div className="card" style={{ background: "transparent", marginTop: 16, padding: "14px 18px", maxWidth: 420 }}>
        <div className="eyebrow" style={{ marginBottom: 6 }}>{kids ? "blinks per second" : "blink rate"}</div>
        <div className="mono" style={{ fontSize: 22, color: "var(--current)" }}>≈ {blinkHz} Hz</div>
      </div>
    </div>
  );
}

function PredictBeat({ onView, kids }) {
  const ref = useInViewCallback(onView);
  return (
    <div className="beat" id="predict" data-screen-label="Predict" ref={ref}>
      <div className="beat-marker">§ 04 · check your gut</div>
      <h2 className="serif">A quick<br/><em>prediction</em>.</h2>
      <PredictReveal
        question={kids
          ? "You swap in a MUCH bigger bucket (capacitor). What happens to the blinking?"
          : "You increase C. What happens to the blink rate?"}
        options={kids
          ? ["It blinks faster", "It blinks slower", "It stops", "It gets brighter"]
          : ["Faster (higher frequency)", "Slower (lower frequency)", "Unchanged", "It stops oscillating"]}
        correct={1}
        explanation={kids
          ? "A bigger bucket takes longer to fill and drain, so each blink lasts longer — it blinks slower."
          : "Period scales with R·C. Bigger C → longer fill/drain → lower frequency. Same reason as the RC timer in Chapter 4."}
        accent="water"
      />
      <PredictReveal
        question={kids
          ? "What makes the 555 keep blinking without you touching it?"
          : "What keeps a 555 astable oscillating with no input?"}
        options={kids
          ? ["A hidden battery inside", "The bucket filling and draining between two marks", "Magic", "You have to keep pressing a button"]
          : ["An external clock signal", "The cap charging/discharging between ⅓ and ⅔ thresholds", "A spinning motor", "Nothing — it needs a push each cycle"]}
        correct={1}
        explanation={kids
          ? "The bucket never rests: every time it hits a mark, the valve flips. Fill, flush, fill, flush — forever."
          : "The comparators flip the discharge transistor at the two thresholds, so the cap endlessly cycles between ⅓ and ⅔ — a self-sustaining relaxation oscillator."}
        accent="current"
      />
    </div>
  );
}

const PG_TARGETS = [
  { hz: 0.5, adult: "a lazy pulse",          kids: "a slow, sleepy blink" },
  { hz: 1.0, adult: "the classic 1 Hz blink", kids: "one blink a second" },
  { hz: 1.5, adult: "a quick flash",          kids: "a fast flicker" },
];

function PlaygroundBeat({ R, C, setR, setC, onView, kids }) {
  const ref = useInViewCallback(onView);
  const blinkHz = 1.0 / Math.max(0.3, (R * C) / 6) / 2;
  const TOL = 0.05;
  const [hit, setHit] = useState({});
  useEffect(() => {
    setHit(h => {
      let nh = h, changed = false;
      for (const t of PG_TARGETS) {
        if (!h[t.hz] && Math.abs(blinkHz - t.hz) <= TOL) {
          if (!changed) { nh = { ...h }; changed = true; }
          nh[t.hz] = true;
        }
      }
      return changed ? nh : h;
    });
  }, [blinkHz]);
  const allHit = PG_TARGETS.every(t => hit[t.hz]);
  return (
    <div className="beat" id="playground" data-screen-label="05 Challenge" ref={ref}>
      <div className="beat-marker">§ 05 · drive the blinker</div>
      <h2 className="serif">Drive the<br/><em>blinker</em>.</h2>
      <p className="lede">
        {kids ? <>Your mission: dial the pinch and bucket to hit each blink speed below. Land one and it locks in ✓</>
              : <>Mission: tune R and C to hit each target rate — the 555's blink is yours to command. Land each one and it locks in.</>}
      </p>
      <div style={{ marginTop: 18, display: "flex", flexDirection: "column", gap: 6 }}>
        <Slider name={kids ? "Pinch (R)" : "Resistance · R"} value={R} min={1} max={12} step={0.5}
                unit="" accent="" onChange={setR} />
        <Slider name={kids ? "Bucket (C)" : "Capacitance · C"} value={C} min={0.5} max={8} step={0.5}
                unit="" accent="water" onChange={setC} />
      </div>
      <div className="card" style={{ background: "transparent", marginTop: 16, padding: "14px 18px", maxWidth: 420 }}>
        <div className="eyebrow" style={{ marginBottom: 6 }}>{kids ? "blinks per second" : "blink rate"}</div>
        <div className="mono" style={{ fontSize: 22, color: "var(--current)" }}>≈ {blinkHz.toFixed(2)} Hz</div>
      </div>
      <div className="rule" style={{ marginTop: 20 }}>{kids ? "hit all three" : "your targets"}</div>
      <div style={{ display: "grid", gridTemplateColumns: "repeat(auto-fit, minmax(110px, 1fr))", gap: 10, marginTop: 4 }}>
        {PG_TARGETS.map(t => {
          const done = !!hit[t.hz];
          const near = !done && Math.abs(blinkHz - t.hz) <= 0.15;
          return (
            <div key={t.hz} style={{
              padding: "12px 14px", borderRadius: 10,
              border: done ? "1.5px solid var(--current)" : near ? "1.5px dashed var(--water)" : "1px solid var(--rule-strong)",
              background: done ? "var(--bg-deeper)" : "transparent",
              transition: "border-color .2s, background .2s",
            }}>
              <div className="eyebrow" style={{ marginBottom: 4, color: done ? "var(--current)" : near ? "var(--water)" : "var(--ink-faint)" }}>
                {done ? "✓ locked in" : near ? "so close…" : "target"}
              </div>
              <div className="mono" style={{ fontSize: 18, color: done ? "var(--current)" : "var(--ink)" }}>{t.hz.toFixed(1)} Hz</div>
              <div style={{ fontSize: 12.5, color: "var(--ink-soft)", marginTop: 4 }}>{kids ? t.kids : t.adult}</div>
            </div>
          );
        })}
      </div>
      {allHit && (
        <div className="pull" style={{ marginTop: 18 }}>
          {kids ? <>All three! You can drive the blinker at any speed you want. ✦</>
                : <>All three, dialed in by feel. Now watch a pro pick exact parts for a clean 1 Hz →</>}
        </div>
      )}
    </div>
  );
}

function LessonScrollyteller({ showChart, kids }) {
  const [R, setR] = useState(5);
  const [C, setC] = useState(2);
  const [nav, setNav] = useState("begin");
  const { level, high } = use555Sim({ R, C, running: true });
  const blinkHz = 1.0 / Math.max(0.3, (R * C) / 6) / 2;
  // audible 555: click in time with the blink (sound-gated)
  useBlinkBeep(blinkHz, true, null);
  const visHeight = showChart ? 340 : 540;
  return (
    <section className="lesson">
      <div className="lesson-scroll">
        <BigIdeaBeat onView={() => setNav("begin")} kids={kids} />
        <HowBeat onView={() => setNav("how")} kids={kids} />
        <SpeedBeat R={R} C={C} setR={setR} setC={setC} onView={() => setNav("speed")} kids={kids} />
        <PredictBeat onView={() => setNav("predict")} kids={kids} />
        <PlaygroundBeat R={R} C={C} setR={setR} setC={setC} onView={() => setNav("playground")} kids={kids} />
      </div>
      <aside className="lesson-sticky" data-single={showChart ? "0" : "1"}>
        {showChart && <VisTabs labels={["WATER", "OUTPUT"]} />}
        <div className="vis-block">
          <div className="stage-label">WATER · the bucket oscillates</div>
          <Astable555Scene R={R} C={C} level={level} high={high} height={visHeight} />
        </div>
        {showChart && (
          <div className="vis-block">
            <div className="stage-label">OUTPUT · the blink over time</div>
            <Blink555Chart high={high} R={R} C={C} height={visHeight} />
          </div>
        )}
      </aside>
    </section>
  );
}

function WorkedExampleSection({ kids }) {
  if (kids) return null;
  return (
    <section className="section" id="example" data-screen-label="Worked example">
      <div className="marker">§ 06 · a real blinker</div>
      <div className="section-inner">
        <div className="two-col">
          <div>
            <h2 className="serif">A real<br/><em>1 Hz blinker</em>.</h2>
            <p className="lede">
              The "hello world" of electronics: a 555 that blinks an LED once
              per second. With the standard astable formula, you pick parts to
              hit f ≈ 1 Hz.
            </p>
            <p>It's the first thing most people ever build that <em>moves</em>.</p>
          </div>
          <div>
            <div className="card" style={{ padding: "24px 26px" }}>
              <div className="eyebrow" style={{ marginBottom: 12 }}>the classic recipe</div>
              <div className="mono" style={{ fontSize: 15, lineHeight: 1.8 }}>
                f = 1.44 / ((R₁ + 2·R₂)·C)<br/>
                R₁ = 1 kΩ, R₂ = 470 kΩ<br/>
                C = 1 µF<br/>
                f ≈ 1.44 / (0.941 × 1) ≈ <span style={{ color: "var(--current)" }}>1.5 Hz</span>
              </div>
              <p className="marg" style={{ marginTop: 14 }}>
                Bump C to 1.5 µF and you land near a tidy 1 Hz. Swap the LED
                for a speaker and you've got an audible tone instead of a blink.
              </p>
            </div>
          </div>
        </div>
      </div>
    </section>
  );
}

const QUIZ_ADULT = [
  { q: "In astable mode, the 555 output is…", kind: "concept", options: ["always high", "always low", "a square wave that flips forever", "a smooth sine wave"], correct: 2, explain: "Astable = free-running oscillator. The output flips high/low endlessly." },
  { q: "The capacitor in a 555 astable charges and discharges between…", kind: "concept", options: ["0 and full supply", "⅓ and ⅔ of the supply", "1 V and 2 V always", "−V and +V"], correct: 1, explain: "The two comparators set thresholds at ⅓ and ⅔ of Vcc." },
  { q: "To make the LED blink SLOWER, you could…", kind: "math", options: ["use a smaller capacitor", "use a bigger R or C", "remove the resistor", "add more supply voltage"], correct: 1, explain: "Period grows with R·C — increase either to slow the blink." },
  { q: "Which Chapter 4 idea is the 555 built on?", kind: "concept", options: ["the diode", "the inductor", "the capacitor charging/discharging", "the transformer"], correct: 2, explain: "It's an RC timer watched by comparators — pure Chapter 4." },
  { q: "Swap the 555's LED for a small speaker and you get…", kind: "concept", options: ["nothing", "an audible tone", "a brighter light", "a motor"], correct: 1, explain: "Fast enough blinking becomes a tone you can hear — that's a buzzer/oscillator." },
  { q: "The 555 keeps oscillating with…", kind: "concept", options: ["no external input", "a computer telling it to", "a person pressing a button each cycle", "a spinning magnet"], correct: 0, explain: "It's self-running: the cap endlessly cycles between the thresholds." },
  {
    q: "In a 555 astable, making the timing capacitor BIGGER…", kind: "math",
    options: ["blinks faster", "blinks slower", "stops the blink", "changes nothing"],
    correct: 1,
    explain: "A bigger bucket takes longer to fill and drain — the whole period stretches.",
  },
  {
    q: "The two comparators inside the 555 watch the capacitor against…", kind: "concept",
    options: ["0 V and 9 V", "⅓ and ⅔ of the supply", "1 V and 2 V exactly", "whatever you program"],
    correct: 1,
    explain: "The three internal 5 kΩ resistors set ⅓ and ⅔ Vcc; the cap sawtooths between them.",
  },
  {
    q: "Storage + a threshold + a switch gives you…", kind: "concept",
    options: ["an amplifier", "a steady rhythm — an oscillator", "a battery", "a fuse"],
    correct: 1,
    explain: "Fill, trip, dump, repeat. Every clock and blinker is some version of this loop.",
  },
  {
    q: "Why does the 555's period depend on R times C, not just one or the other?",
    kind: "concept",
    options: [
      "It doesn't — only C matters",
      "R sets how fast charge moves; C sets how much charge is needed — together they set the time",
      "R and C cancel each other out",
      "Only R matters",
    ],
    correct: 1,
    explain: "Same as Chapter 4's τ = RC: the resistor is the rate, the capacitor is the tank size. Change either and the period shifts proportionally.",
  },
  {
    q: "The '555' in the name refers to…",
    options: ["its price in 1972", "three internal 5 kΩ resistors that set the ⅓/⅔ thresholds", "the year it launched", "its pin count"],
    correct: 1,
    explain: "A resistor ladder of three 5 kΩ resistors divides the supply into thirds — hence the name and the ⅓/⅔ trip points.",
  },
  {
    q: "Could you build the same blinking behavior WITHOUT a 555, using earlier chapters' parts?",
    options: [
      "No, it needs a special unrepeatable chip",
      "Yes — transistors switching a capacitor's charge/discharge (an RC astable) do the same job, just with more discrete parts",
      "No, only digital chips can blink",
      "Yes, but only with a capacitor and nothing else",
    ],
    correct: 1,
    explain: "The 555 is a convenient PACKAGE of a comparator + switch around an RC timer — the underlying idea (fill, trip, dump, repeat) is exactly what a two-transistor astable does too.",
  },
];
const QUIZ_KIDS = [
  { q: "What does a 555 timer do in blink mode?", kind: "concept", options: ["Nothing", "Turns a light on and off over and over", "Makes heat", "Stores water"], correct: 1, explain: "It blinks — on, off, on, off, forever!" },
  { q: "A BIGGER bucket (capacitor) makes the blink…", kind: "concept", options: ["faster", "slower", "stop", "brighter"], correct: 1, explain: "Bigger bucket = longer to fill and drain = slower blink." },
  { q: "The light is ON while the bucket is…", kind: "concept", options: ["filling", "empty forever", "broken", "frozen"], correct: 0, explain: "The output is high (ON) while the bucket fills up." },
  { q: "What keeps it blinking by itself?", kind: "concept", options: ["A person", "The bucket filling and draining between two marks", "A motor", "Magic"], correct: 1, explain: "The bucket never rests — it bounces between the HIGH and LOW marks." },
  { q: "Swap the light for a speaker and you hear…", kind: "concept", options: ["nothing", "a beep/tone", "music from a radio", "silence"], correct: 1, explain: "Fast blinking turns into a sound you can hear — beep!" },
  {
    q: "To blink FASTER, you make the bucket…", kind: "concept",
    options: ["bigger", "smaller", "wetter", "taller"],
    correct: 1,
    explain: "A smaller bucket fills and empties quicker — faster blink!",
  },
  {
    q: "Inside the 555, the referee flips the light when the bucket hits…", kind: "concept",
    options: ["the very top", "⅓ and ⅔ full", "any random level", "the bottom only"],
    correct: 1,
    explain: "Two marks: ⅔ full = empty it, ⅓ full = fill it again. Tick, tock.",
  },
  {
    q: "A blinker is really just a bucket plus a…", kind: "concept",
    options: ["bigger bucket", "switch that flips at a mark", "longer pipe", "second battery"],
    correct: 1,
    explain: "Something has to flip when the level hits the mark — that switch makes the rhythm.",
  },
  {
    q: "Why does the SIZE of the bucket change the blink speed but not the marks?",
    kind: "concept",
    options: ["It doesn't", "A bigger bucket takes longer to fill to the SAME marks", "The marks move with the bucket", "Bigger buckets skip the marks"],
    correct: 1,
    explain: "The marks (⅓ and ⅔ full) stay put — a bigger bucket just takes longer to reach them, so the blink slows down.",
  },
];

function App() {
  const [t, setTweak] = useTweaks(TWEAK_DEFAULTS);
  useCrossChapterPersistence(t, setTweak);
  useEffect(() => { document.body.setAttribute("data-theme", t.theme); }, [t.theme]);
  const kids = t.audience === "kids";
  const navItems = [
    { id: "cover", label: "Cover" },
    { id: "begin", label: kids ? "The chip" : "The 555" },
    { id: "how", label: kids ? "Fill & flush" : "How it works" },
    { id: "speed", label: kids ? "Speed" : "Blink rate" },
    { id: "predict", label: "Predict" },
    { id: "playground", label: kids ? "Mission" : "Challenge" },
    ...(kids ? [] : [{ id: "example", label: "1 Hz build" }]),
    { id: "practice", label: "Practice" },
    { id: "whats-next", label: "What's next" },
  ];
  return (
    <>
      <ChapterStartMarker chapterN="10" />
      <ProgressBar />
      <TopBar currentN="10" chapterLabel="Ch. 10 — The Blinker"
              audience={t.audience} setAudience={(v) => setTweak("audience", v)} />
      <ChapterNav items={navItems} />
      <main>
        <CoverPage chapterN="10"
                   chapterTitle={<>The <em>Blinker</em>.</>}
                   chapterSub="Chapter 10 · The 555 timer"
                   kids={kids}
                   lede={kids
                     ? <>The most famous little chip in the world. With a bucket and two pinches, it blinks a light all by itself — the first real gadget most people ever build.</>
                     : <>A capstone of the passive world: the 555 timer turns a capacitor and two resistors into a self-running blinker. Everything you learned about RC timing, made into a chip that never stops.</>} />
        <LessonScrollyteller showChart={t.showChart} kids={kids} />

        <CheckpointQuiz kids={kids} label="Checkpoint 1" pick={2}
          title={kids ? "Quick check!" : "Did it stick?"}
          questions={[
            {
              q: "The 555 blinks by…",
              options: ["Filling and draining a bucket between two level marks, forever", "Counting your button presses", "Heating and cooling a wire", "Magic"],
              correct: 0,
              explain: kids ? "Fill to the high mark — flip! Drain to the low mark — flip back! The chip just watches the bucket and works the valves."
                            : "The cap charges and discharges between ⅓ and ⅔ of the supply; the chip's comparators flip the output at each threshold. RC timing, automated.",
            },
            {
              q: "Swap in a BIGGER bucket (larger C). The blinking…",
              options: ["Slows down — each fill and drain takes longer", "Speeds up", "Stops", "Gets brighter"],
              correct: 0,
              explain: kids ? "A bigger bucket takes longer to fill to the high mark and longer to drain to the low one — lazy, slow blinks."
                            : "Period scales with R·C. More capacitance, more charge to move per cycle, longer period — straight from chapter 4.",
            },
            {
              q: "Tighten the pinches (bigger R). The blinking…",
              options: ["Slows down — the bucket fills and drains lazily", "Speeds up", "Reverses", "Doesn't care"],
              correct: 0,
              explain: kids ? "Tighter squeezes mean slower filling AND slower draining — the whole rhythm stretches out."
                            : "Same τ = R·C lever from the other side: the resistors throttle the charge/discharge currents, stretching both halves of the cycle.",
            },
            {
              q: "What makes the 555 SELF-running, unlike a switch you flip?",
              options: ["Each full/empty trip flips its own valves, starting the next trip", "You must press a button for every blink", "The battery pulses by itself", "It isn't — it secretly stops"],
              correct: 0,
              explain: kids ? "Reaching a mark flips the valves; flipping the valves sends the bucket toward the other mark. It feeds itself forever — no hands!"
                            : "Feedback: the output state controls the charging direction, and the cap's level controls the output state. Closed loop = oscillation, no input required.",
            },
          ]} />

        <WorkedExampleSection kids={kids} />

        <CheckpointQuiz kids={kids} label="Checkpoint 2" pick={2}
          title={kids ? "Spot it in real life!" : "Out in the wild."}
          intro={kids ? "Self-made rhythms are ticking all around you." : "Oscillators in the wild."}
          questions={[
            {
              q: "Turn signals, metronomes, beeping kitchen timers — what do they all need at heart?",
              options: ["A steady self-made rhythm — an oscillator", "A human flipping a switch in time", "Random noise", "A very long wire"],
              correct: 0,
              explain: kids ? "Anything that goes tick-tick-tick by itself has a self-flipping loop inside — a bucket and valves keeping their own beat."
                            : "Any periodic behavior needs an oscillator. The 555 is the classic hobbyist one; the idea scales from blinkers to clock crystals.",
            },
            {
              q: "To make your bike light blink twice as fast, you'd…",
              options: [kids ? "Use a smaller bucket or looser pinches" : "Halve the R·C — smaller cap or smaller resistors", "Double the battery push", "Use a longer wire", "Shake it"],
              correct: 0,
              explain: kids ? "Faster rhythm = quicker fills and drains. Shrink the bucket or open the squeezes and the beat doubles."
                            : "Period ∝ R·C, so halving either halves the period. (Supply voltage cancels out — the thresholds scale with it. Elegant.)",
            },
            {
              q: "A musical greeting card plays different pitches by…",
              options: ["Switching different pinch/bucket pairs — different fill-drain speeds for each note", "Heating the chip", "Changing batteries per note", "Tiny bells"],
              correct: 0,
              explain: kids ? "Each note is just a different blink speed — so fast it becomes a hum! Different squeeze-and-bucket pairs make different notes."
                            : "Run an oscillator at audio rates and the period becomes pitch: each note is a different effective R·C. A blinker and a tone generator are the same circuit at different speeds.",
            },
            {
              q: "Your microwave's clock keeps decent time by…",
              options: ["Counting the ticks of a steady oscillator", "Measuring how hot the food gets", "Checking the door switch", "Guessing"],
              correct: 0,
              explain: kids ? "Inside is a super-steady ticker, and the clock just counts ticks. Count enough ticks, that's a second; count enough seconds, that's dinner time."
                            : "All digital timekeeping is oscillator-plus-counter — whether a quartz crystal or the mains' own 50/60 Hz used as the tick source.",
            },
          ]} />

        <PracticeProblems chapterN="10" kids={kids} problems={[
          (rng) => {
            const r1k = rng.pick([1, 2, 4.7]), r2k = rng.pick([1, 4.7, 10]), uf = rng.pick([10, 47, 100, 470]);
            const bottom = (r1k * 1000 + 2 * r2k * 1000) * (uf * 1e-6);
            const f = +(1.44 / bottom).toFixed(2);
            return {
              q: { adult: `A 555 astable uses R₁ = ${r1k} kΩ, R₂ = ${r2k} kΩ, C = ${uf} µF. What is the blink frequency? Use f = 1.44 ÷ ((R₁ + 2R₂)·C).`, kids: `Plug in: f = 1.44 ÷ ((${r1k * 1000} + 2×${r2k * 1000}) × ${+(uf * 1e-6).toPrecision(6)}). About how many blinks per second?` },
              unit: "Hz", answer: f, tol: 0.08,
              hint: `R₁ + 2R₂ = ${r1k * 1000 + 2 * r2k * 1000} Ω; C = ${+(uf * 1e-6).toPrecision(6)} F.`,
              solution: { adult: `f = 1.44 ÷ (${r1k * 1000 + 2 * r2k * 1000} × ${+(uf * 1e-6).toPrecision(6)}) = 1.44 ÷ ${+bottom.toFixed(3)} ≈ ${f} Hz.`, kids: `Bottom = ${r1k * 1000 + 2 * r2k * 1000} × ${+(uf * 1e-6).toPrecision(6)} = ${+bottom.toFixed(3)}. 1.44 ÷ ${+bottom.toFixed(3)} ≈ ${f}.` } };
          },
          (rng) => {
            const f = rng.pick([1.5, 2, 2.5, 4, 5]);
            const t = +(1 / f).toFixed(2);
            return {
              q: { adult: `A 555 blinks at ${f} Hz. How long is each full blink cycle? (Answer in seconds.)`, kids: `It blinks ${f} times a second. How long is one blink? (in seconds)` },
              unit: "s", answer: t, tol: 0.04,
              hint: "Period = 1 ÷ f.",
              solution: { adult: `T = 1 ÷ f = 1 ÷ ${f} = ${t} s.`, kids: `1 ÷ ${f} = ${t}.` } };
          },
          (rng) => {
            const f0 = rng.pick([2, 4, 6]), factor = rng.pick([2, 3]);
            const nf = +(f0 / factor).toFixed(2);
            return {
              q: { adult: `If you multiply the timing capacitor by ${factor}, what happens to a blink frequency that was ${f0} Hz? (Answer the new frequency in Hz.)`, kids: `Frequency and capacitor are opposites — ${factor}× the bucket, frequency ÷ ${factor}. Old speed was ${f0}. New speed?` },
              unit: "Hz", answer: nf, tol: 0.04,
              hint: `Frequency is inversely proportional to C: ${factor}× C → f ÷ ${factor}.`,
              solution: { adult: `f ∝ 1 ÷ C, so ${factor}× C divides the frequency by ${factor}: ${f0} Hz → ${nf} Hz.`, kids: `${factor}× the bucket → ${factor}× slower: ${f0} → ${nf}.` } };
          },
        ]} />

        <ChapterQuiz chapterN="10"
          title={kids ? "Quick quiz!" : "Check your understanding."}
          intro={kids ? "Five questions about the blinking chip." : "The 555 oscillator. 70% to pass; retry freely."}
          questions={kids ? QUIZ_KIDS : QUIZ_ADULT} pick={5} />
        <WhatsNext currentN="10" kids={kids}
          summary={kids
            ? <>You finished the whole theory track — and met the chip that blinks! Next: one big look back at every part you've met, all on one shelf.</>
            : <>You've completed Level 1's theory arc, capped by a real oscillator. Next: a recap of the whole shelf — every component, why it exists, how they team up — then the capstone.</>}
          prevHref="chapter9.html" prevLabel="Ch 9 · The Flywheel"
          nextHref="recap.html" nextLabel="The Recap →" />
      </main>
      <TweaksPanel title="Tweaks">
        <CommonTweaks t={t} setTweak={setTweak}
          animationToggles={[{ key: "showChart", label: "Show chart" }]} />
      </TweaksPanel>
      <GlossaryFab />
    </>
  );
}

ReactDOM.createRoot(document.getElementById("root")).render(<App />);
