/* chapter8.jsx — Chapter 8: The Wave (AC vs DC). */

const { useState, useEffect, useRef } = React;

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

function BigIdeaBeat({ onView, kids }) {
  const ref = useInViewCallback(onView);
  return (
    <div className="beat" id="begin" data-screen-label="01 Two kinds" ref={ref}>
      <div className="beat-marker">§ 01 · two kinds of flow</div>
      {kids ? (
        <>
          <h2 className="serif">Steady push,<br/>or <em>back-and-forth</em>?</h2>
          <p className="lede">
            Everything so far has been a steady, one-way flow — like water from
            a barrel. That's called <em>DC</em>.
          </p>
          <p>
            But wall plugs do something different: they push and pull, push and
            pull, super fast. The water sloshes back and forth instead of flowing
            one way. That's <em>AC</em>.
          </p>
        </>
      ) : (
        <>
          <h2 className="serif">DC flows.<br/>AC <em>sloshes</em>.</h2>
          <p className="lede">
            Every circuit so far has used <em>direct current</em> — a steady,
            one-direction flow from a battery. Constant push, constant flow.
          </p>
          <p>
            Wall power is <em>alternating current</em>: the voltage reverses
            many times a second, so charge sloshes back and forth rather than
            traveling around. It's the same water, driven very differently.
          </p>
          <div className="marg" style={{ marginTop: 12 }}>
            This is the wave the <em>Current Wars</em> were fought over — and the
            thing your Chapter 7 diode was busy taming.
          </div>
        </>
      )}
      <div className="pull">DC: one way, always. AC: there and back, fast.</div>
    </div>
  );
}

function AcDcBeat({ mode, setMode, onView, kids }) {
  const ref = useInViewCallback(onView);
  return (
    <div className="beat" id="acdc" data-screen-label="02 AC or DC" ref={ref}>
      <div className="beat-marker">§ 02 · see the difference</div>
      <div className="chip current" style={{ marginBottom: 16 }}>try it</div>
      <h2 className="serif">Flip between<br/><em>AC and DC</em>.</h2>
      <p className="lede">
        {kids
          ? <>Tap the buttons. Watch the water — does it flow one way, or slosh back and forth? Watch the screen draw the shape.</>
          : <>Switch the source. DC holds a flat line on the scope; AC traces a sine wave as the water rocks side to side.</>}
      </p>
      <div style={{ display: "flex", gap: 10, marginTop: 22, flexWrap: "wrap" }}>
        <button onClick={() => setMode("dc")} style={modeBtn(mode === "dc", "var(--water)")}>DC · steady</button>
        <button onClick={() => setMode("ac")} style={modeBtn(mode === "ac", "var(--current)")}>AC · wave</button>
      </div>
      <div className="card" style={{ background: "transparent", marginTop: 22, padding: "16px 20px" }}>
        <div className="eyebrow" style={{ marginBottom: 8 }}>what you're seeing</div>
        <p style={{ margin: 0, fontSize: 17 }}>
          {mode === "dc"
            ? <>DC — the water pushes one steady direction. On the scope, a <span className="mono" style={{ color: "var(--water)" }}>flat line</span>: voltage never changes.</>
            : <>AC — the water rocks back and forth. On the scope, a <span className="mono" style={{ color: "var(--current)" }}>sine wave</span>: voltage swings positive, then negative, over and over.</>}
        </p>
      </div>
    </div>
  );
}

function FrequencyBeat({ freq, setFreq, amp, setAmp, onView, kids }) {
  const ref = useInViewCallback(onView);
  const tone = useToneFollow();
  const idle = React.useRef(null);
  // hear the wave: pitch tracks frequency, loudness tracks amplitude
  const sing = (f, a) => {
    tone.set((f - 0.3) / 3.7, Math.min(1, a / 1.5));
    if (idle.current) clearTimeout(idle.current);
    idle.current = setTimeout(() => tone.stop(), 320);
  };
  const onF = (x) => { setFreq(x); sing(x, amp); };
  const onA = (x) => { setAmp(x); sing(freq, x); };
  return (
    <div className="beat" id="frequency" data-screen-label="03 Frequency" ref={ref}>
      <div className="beat-marker">§ 03 · how fast & how big</div>
      <h2 className="serif">{kids ? "Faster and bigger" : "Frequency & amplitude"}.</h2>
      <SonifyHint text="Sound's on — drag frequency and you'll hear the pitch rise. That's the wave." />
      {kids ? (
        <p className="lede">
          Two things describe a wave: how <em>fast</em> it sloshes, and how
          <em> big</em> each slosh is. Drag the sliders and watch the screen.
        </p>
      ) : (
        <>
          <p className="lede">
            A wave needs two numbers. <em>Frequency</em> — how many full cycles
            per second, measured in <span className="mono">hertz (Hz)</span>. And
            <em> amplitude</em> — how far the voltage swings.
          </p>
          <p>
            US wall power is <span className="mono">60 Hz</span>; most of the
            world is <span className="mono">50 Hz</span>. Your wifi? Billions of
            Hz. Same idea — wildly different speed.
          </p>
        </>
      )}
      <div className="rule">try it</div>
      <Slider name={kids ? "How fast (frequency)" : "Frequency"} value={freq} min={0.3} max={4} step={0.1}
              unit={kids ? "" : "× speed"} accent="current" onChange={onF} />
      <Slider name={kids ? "How big (amplitude)" : "Amplitude"} value={amp} min={0.3} max={1.5} step={0.1}
              unit="" accent="water" onChange={onA} />
      <div className="marg" style={{ marginTop: 12 }}>
        {kids
          ? <>Faster = more wiggles on the screen. Bigger = taller wiggles.</>
          : <>Frequency packs more cycles across the screen; amplitude makes them taller. They're independent.</>}
      </div>
    </div>
  );
}

function PredictBeat({ onView, kids }) {
  const ref = useInViewCallback(onView);
  return (
    <div className="beat" id="predict" data-screen-label="04 Predict" ref={ref}>
      <div className="beat-marker">§ 04 · check your gut</div>
      <h2 className="serif">A puzzle<br/>(or two).</h2>
      <PredictReveal
        question={kids
          ? "On the scope, what does steady DC look like?"
          : "How does DC appear on an oscilloscope?"}
        options={["A tall wave", "A flat horizontal line", "A circle", "Nothing at all"]}
        correct={1}
        explanation={kids
          ? "DC never changes, so it draws a flat line — no wiggles!"
          : "Constant voltage = a flat horizontal trace. No variation over time."}
        accent="water" />
      <PredictReveal
        question={kids
          ? "Why does the wall plug use the back-and-forth kind (AC)?"
          : "Why is AC used for the power grid instead of DC?"}
        options={[
          "It looks nicer",
          "It can be sent long distances efficiently (via transformers)",
          "It's safer to touch",
          "Batteries make it naturally"]}
        correct={1}
        explanation={kids
          ? "AC can travel really far across wires without fading — that's why Tesla's way won the Current Wars!"
          : "AC voltage can be stepped up with transformers for low-loss long-distance transmission, then stepped back down for homes. That efficiency won the Current Wars."}
        accent="current" />
    </div>
  );
}

function PlaygroundBeat({ mode, setMode, freq, setFreq, amp, setAmp, onView, kids }) {
  const ref = useInViewCallback(onView);
  return (
    <div className="beat" id="playground" data-screen-label="05 Playground" ref={ref}>
      <div className="beat-marker">§ 05 · all knobs unlocked</div>
      <h2 className="serif">Drive the<br/><em>wave</em>.</h2>
      <p className="lede">
        {kids ? <>Mix it all: pick AC or DC, then change how fast and how big.</>
              : <>Combine everything. Switch modes and shape the wave; note DC ignores frequency entirely.</>}
      </p>
      <div style={{ display: "flex", gap: 10, marginTop: 20, flexWrap: "wrap" }}>
        <button onClick={() => setMode("dc")} style={modeBtn(mode === "dc", "var(--water)")}>DC</button>
        <button onClick={() => setMode("ac")} style={modeBtn(mode === "ac", "var(--current)")}>AC</button>
      </div>
      <div style={{ marginTop: 18, opacity: mode === "dc" ? 0.4 : 1, pointerEvents: mode === "dc" ? "none" : "auto" }}>
        <Slider name={kids ? "How fast" : "Frequency"} value={freq} min={0.3} max={4} step={0.1}
                unit={kids ? "" : "× speed"} accent="current" onChange={setFreq} />
      </div>
      <Slider name={kids ? "How big" : "Amplitude"} value={amp} min={0.3} max={1.5} step={0.1}
              unit="" accent="water" onChange={setAmp} />
      <div className="card" style={{ background: "transparent", marginTop: 18, padding: "16px 20px" }}>
        <div className="eyebrow" style={{ marginBottom: 8 }}>now showing</div>
        <p style={{ margin: 0, fontSize: 17 }}>
          {mode === "dc"
            ? <>Steady DC. Frequency doesn't apply — the line is flat no matter what.</>
            : <>AC at <span className="mono" style={{ color: "var(--current)" }}>{freq.toFixed(1)}× speed</span>, swing <span className="mono">{amp.toFixed(1)}</span>.</>}
        </p>
      </div>
    </div>
  );
}

function modeBtn(active, color) {
  return {
    appearance: "none",
    border: `2px solid ${active ? color : "var(--rule-strong)"}`,
    background: active ? color : "transparent",
    color: active ? "var(--bg-card)" : "var(--ink)",
    padding: "11px 24px", borderRadius: 8, cursor: "pointer",
    fontFamily: "'IBM Plex Mono', monospace", fontSize: 13,
    letterSpacing: "0.1em", textTransform: "uppercase", fontWeight: 500,
  };
}

function LessonScrollyteller({ showScope, kids }) {
  const [mode, setMode] = useState("ac");   // AcDc compare + Playground (user-driven)
  const [freq, setFreq] = useState(1);
  const [amp, setAmp] = useState(1);
  const [nav, setNav] = useState("begin");
  const phase = useAcPhase(freq, true);     // always animating at freq
  const visHeight = showScope ? 330 : 530;

  // a self-contained sticky visual fixed to a given mode
  const stickyFor = (m) => (
    <aside className="lesson-sticky" data-single={showScope ? "0" : "1"}>
        {showScope && <VisTabs labels={["WATER", "SCOPE"]} />}
      <div className="vis-block">
        <div className="stage-label">WATER · the sloshing tube</div>
        <AcWaterScene mode={m} amp={amp} phase={phase} height={visHeight} />
      </div>
      {showScope && (
        <div className="vis-block">
          <div className="stage-label">SCOPE · voltage over time</div>
          <ScopeScene mode={m} amp={amp} freq={freq} phase={phase} height={visHeight} />
        </div>
      )}
      <div className="vis-readout">
        <div className="ro-v ro-active">
          <span className="ro-name">Mode</span>
          <span className="ro-val" style={{ fontSize: 20, color: m === "ac" ? "var(--current)" : "var(--water)" }}>
            {m.toUpperCase()}
          </span>
        </div>
        <div className="ro-r">
          <span className="ro-name">{kids ? "Speed" : "Frequency"}</span>
          <span className="ro-val">{m === "ac" ? fmt(freq, 1) : "—"}<span className="ro-unit">{m === "ac" ? "×" : ""}</span></span>
        </div>
        <div className="ro-i">
          <span className="ro-name">{kids ? "Size" : "Amplitude"}</span>
          <span className="ro-val">{fmt(amp, 1)}</span>
        </div>
        <div className="ro-p">
          <span className="ro-name">Shape</span>
          <span className="ro-val" style={{ fontSize: 18 }}>{m === "ac" ? "WAVE" : "FLAT"}</span>
        </div>
      </div>
    </aside>
  );

  return (
    <div className="lesson-stack">
      {/* Big idea — full-width intro, no visual */}
      <div className="lesson-solo">
        <BigIdeaBeat onView={() => setNav("begin")} kids={kids} />
      </div>

      {/* DC vs AC — the visual follows the user's own toggle in this beat */}
      <section className="lesson" data-mode="acdc">
        <div className="lesson-scroll">
          <AcDcBeat mode={mode} setMode={setMode} onView={() => setNav("acdc")} kids={kids} />
        </div>
        {stickyFor(mode)}
      </section>

      {/* Frequency — always AC, its own fixed wave visual */}
      <section className="lesson" data-mode="frequency">
        <div className="lesson-scroll">
          <FrequencyBeat freq={freq} setFreq={setFreq} amp={amp} setAmp={setAmp}
                         onView={() => setNav("frequency")} kids={kids} />
        </div>
        {stickyFor("ac")}
      </section>

      {/* Predict — full-width text */}
      <div className="lesson-solo">
        <PredictBeat onView={() => setNav("predict")} kids={kids} />
      </div>

      {/* Playground — user drives everything */}
      <section className="lesson" data-mode="playground">
        <div className="lesson-scroll">
          <PlaygroundBeat mode={mode} setMode={setMode} freq={freq} setFreq={setFreq}
                          amp={amp} setAmp={setAmp} onView={() => setNav("playground")} kids={kids} />
        </div>
        {stickyFor(mode)}
      </section>
    </div>
  );
}

function WorkedExampleSection({ kids }) {
  if (kids) return null;
  return (
    <section className="section" id="example" data-screen-label="06 The grid">
      <div className="marker">§ 06 · why your wall is AC</div>
      <div className="section-inner">
        <div className="two-col">
          <div>
            <h2 className="serif">A practical story:<br/><em>the power grid</em>.</h2>
            <p className="lede">
              Power plants are far from cities. Sending power that far as DC
              wastes enormous energy as heat in the wires (remember P = I²R from
              Chapter 3 — long wires have real resistance).
            </p>
            <p>
              The fix: send it at very high voltage, which means very low
              current, which means tiny losses. But you can't safely use
              hundreds of thousands of volts in a home.
            </p>
            <p>
              AC's superpower is the <em>transformer</em> — a device that steps
              voltage up or down, but only works with a changing (AC) signal.
              Step up for the journey, step down for the house. That single trick
              is why the wall socket alternates.
            </p>
          </div>
          <div>
            <div className="card" style={{ padding: "24px 26px" }}>
              <div className="eyebrow" style={{ marginBottom: 14 }}>the journey</div>
              <div className="mono" style={{ fontSize: 14.5, lineHeight: 1.9 }}>
                Plant … 25,000 V<br/>
                ↑ step up … <span style={{ color: "var(--current)" }}>400,000 V</span><br/>
                — long transmission lines —<br/>
                ↓ step down … 7,200 V<br/>
                ↓ step down … <span style={{ color: "var(--water)" }}>120 / 240 V</span><br/>
                … your outlet
              </div>
              <p className="marg" style={{ marginTop: 16 }}>
                High voltage = low current = low I²R loss. Transformers only work
                on AC. That's the whole reason.
              </p>
            </div>
            <div className="marg" style={{ marginTop: 18 }}>
              Inside your devices, a diode rectifier (Chapter 7) turns that AC
              back into the DC the electronics actually want. Full circle.
            </div>
          </div>
        </div>
      </div>
    </section>
  );
}

/* ─── GridGame — run the grid yourself ────────────────────────────
   Plant → long line → town. Two transformer slots (step-up at the plant,
   step-down at the town) and an AC/DC choice. Place both on AC and the
   houses light bright; miss one and you either starve the town or fry it. */
function GridGameSection({ kids }) {
  // Each slot cycles: empty → step-up (×16) → step-down (÷16) → empty.
  const CYCLE = [null, "up", "down"];
  const [slotA, setSlotA] = useState(null);   // at the plant
  const [slotB, setSlotB] = useState(null);   // at the town gate
  const [ac, setAc] = useState(true);
  const cycle = (v) => CYCLE[(CYCLE.indexOf(v) + 1) % CYCLE.length];

  // ── the voltage chain ──────────────────────────────────────────────
  const PLANT_KV = 25;
  const xform = (kv, t) => (!ac || !t) ? kv : (t === "up" ? kv * 16 : kv / 16);
  const lineKV = xform(PLANT_KV, slotA);
  const townKV = xform(lineKV, slotB);
  const fmtKV = (kv) => kv >= 100 ? Math.round(kv).toLocaleString() : (kv >= 10 ? kv.toFixed(0) : kv.toFixed(1));

  // line loss ∝ (1/V)² — 25 kV → 62 %, 400 kV → ~0.2 %, 1.6 kV → ~97 %
  const loss = Math.min(0.97, 0.62 * Math.pow(PLANT_KV / lineKV, 2));
  const delivered = Math.round((1 - loss) * 100);
  // the line itself: a FIXED 4 Ω of copper — transformers never touch it.
  // Current on the trip: same power, taller push → thinner flow. I = P/V.
  const P_MW = 100;
  const lineI = P_MW * 1000 / lineKV;   // kA→A: 100 MW ÷ kV = A×10³ … displayed below
  const fmtI = (a) => a >= 1000 ? `${(a / 1000).toFixed(0)},000 A` : a >= 100 ? `${Math.round(a)} A` : `${a.toFixed(0)} A`;

  // the town's gate gear expects 25 kV (its own pole transformers handle the last step to 120 V)
  const fried = townKV > PLANT_KV + 1;
  const weak = townKV < PLANT_KV - 1;
  const townOK = !fried && !weak;
  const bright = townOK && delivered > 80;
  // transformers are inert iron on DC — they only act on AC
  const upOn = ac && slotA === "up";
  const downOn = ac && slotB === "down";

  const verdict = (!ac && (slotA || slotB))
    ? (kids ? "Transformers only work on wiggly (AC) power — your boxes are just sitting there! Flip to AC." : "Transformers need a CHANGING current — on DC they're inert iron. Your slots do nothing. (This is what decided the Current Wars.)")
    : fried
    ? (kids ? `✗ ${fmtKV(townKV)} kV at the houses — WAY too strong! Step it DOWN before the town.` : `✗ ${fmtKV(townKV)} kV at the gate — the town expects 25 kV. Step DOWN before delivery.`)
    : weak
    ? (kids ? `✗ Only ${fmtKV(townKV)} kV reaches the town — too gentle for its gear. You squished the push too early!` : `✗ ${fmtKV(townKV)} kV at the gate — under the 25 kV the town's gear expects. You stepped down in the wrong place.`)
    : bright
    ? (kids ? `✓ Bright houses! Tall push for the trip (${fmtKV(lineKV)} kV), gentle again at the gate.` : `✓ ${delivered}% delivered at the right push. Travel at ${fmtKV(lineKV)} kV, arrive at 25 kV — the whole grid in one trick.`)
    : lineKV < PLANT_KV
    ? (kids ? "Right push at the gate — but the trip was made all squished-down, and the wire ate nearly everything!" : `Right voltage at the gate, but you made the TRIP at ${fmtKV(lineKV)} kV — I²R ate ${Math.round(loss * 100)}%. Step UP first, down later.`)
    : (kids ? "The houses work, but the long wire ate most of the power. Make the push TALLER for the trip." : `Only ${delivered}% survives the trip at ${PLANT_KV} kV. The line's I²R heat eats the rest — step UP before the journey.`);

  // ── slot renderer ──────────────────────────────────────────────────
  const slot = (val, x, setter, name) => {
    const cx = x + 32;
    const placed = !!val;
    const inert = placed && !ac;
    return (
      <g style={{ cursor: "pointer" }} onClick={() => setter(cycle(val))}>
        <rect x={x} y={112} width="64" height="82" rx="6"
              fill={placed ? "var(--bg-card)" : "transparent"}
              stroke={placed ? "var(--ink)" : "var(--ink-faint)"}
              strokeWidth="2" strokeDasharray={placed ? "" : "5 5"} />
        {placed ? (
          <g pointerEvents="none" opacity={inert ? 0.4 : 1}>
            <line x1={cx - 2} y1={128} x2={cx - 2} y2={168} stroke="var(--ink)" strokeWidth="2" />
            <line x1={cx + 2} y1={128} x2={cx + 2} y2={168} stroke="var(--ink)" strokeWidth="2" />
            {[0, 1, 2].map(i => (
              <circle key={i} cx={cx - 10} cy={136 + i * 13} r="5.5" fill="none" stroke="var(--water)" strokeWidth="2" />
            ))}
            {[0, 1, 2].map(i => (
              <circle key={i} cx={cx + 10} cy={136 + i * 13} r="5.5" fill="none" stroke="var(--current)" strokeWidth="2" />
            ))}
            <text x={cx} y={188} textAnchor="middle" fontFamily="IBM Plex Mono, monospace"
                  fontSize="13.5" fontWeight="600" fill={val === "up" ? "var(--current-deep)" : "var(--water-deep)"}>
              {val === "up" ? "▲ ×16" : "▼ ÷16"}
            </text>
          </g>
        ) : (
          <text x={cx} y={160} textAnchor="middle" pointerEvents="none"
                fontFamily="IBM Plex Mono, monospace" fontSize="24" fill="var(--ink-faint)">+</text>
        )}
        <text x={cx} y={212} textAnchor="middle" pointerEvents="none"
              fontFamily="IBM Plex Mono, monospace" fontSize="12"
              fill="var(--ink-faint)" letterSpacing="0.06em">
          {placed ? (inert ? "(inert on DC)" : (kids ? "tap to change" : "tap: change / remove")) : name}
        </text>
      </g>
    );
  };

  // ── voltage chip ───────────────────────────────────────────────────
  const chip = (x, kv, ok, label) => (
    <g>
      <rect x={x - 40} y={78} width="80" height="24" rx="12"
            fill="var(--bg-card)" stroke={ok ? "var(--water)" : "oklch(0.62 0.19 35)"} strokeWidth="1.8" />
      <text x={x} y={94} textAnchor="middle" fontFamily="IBM Plex Mono, monospace" fontSize="13" fontWeight="600"
            fill={ok ? "var(--water-deep)" : "oklch(0.5 0.18 35)"}>{fmtKV(kv)} kV</text>
      <text x={x} y={70} textAnchor="middle" fontFamily="IBM Plex Mono, monospace" fontSize="10.5"
            fill="var(--ink-faint)" letterSpacing="0.1em">{label}</text>
    </g>
  );

  return (
    <section className="section" id="grid-game" data-screen-label="07 Run the grid"
             style={{ background: "var(--bg-deeper)" }}>
      <div className="marker">§ {kids ? "06" : "07"} · run the grid yourself</div>
      <div className="section-inner">
        <h2 className="serif">Get the power<br/>to the <em>town</em>.</h2>
        <p className="lede" style={{ maxWidth: 640 }}>
          {kids
            ? <>The plant makes its push at <b>25 kV</b>. The town's gear also wants <b>25 kV</b> at its gate. Tap the dashed boxes — each tap changes what's inside (nothing → make-it-taller → make-it-gentler). Watch the voltage chips change!</>
            : <>The plant generates at <b>25 kV</b>; the town's gate gear expects <b>25 kV</b> back (its own pole transformers handle the last drop to 120 V). Each dashed slot cycles through: empty → step-up ×16 → step-down ÷16. Watch the voltage chips — where you transform matters as much as whether.</>}
        </p>
        <div style={{ display: "flex", gap: 10, margin: "18px 0 6px" }}>
          <button onClick={() => setAc(true)} style={modeBtn(ac, "var(--current)")}>AC plant</button>
          <button onClick={() => setAc(false)} style={modeBtn(!ac, "var(--water)")}>DC plant</button>
        </div>
        <div className="card" style={{ padding: "10px 14px 16px", marginTop: 12 }}>
          <svg viewBox="0 0 850 290" width="100%" style={{ display: "block" }}>
            {/* power plant */}
            <g>
              <rect x="40" y="120" width="100" height="74" fill="var(--bg-card)" stroke="var(--ink)" strokeWidth="2.5" rx="3" />
              <rect x="56" y="84" width="18" height="36" fill="var(--bg-card)" stroke="var(--ink)" strokeWidth="2.5" />
              <rect x="86" y="96" width="18" height="24" fill="var(--bg-card)" stroke="var(--ink)" strokeWidth="2.5" />
              <path d="M 60 150 q 10 -14 20 0 q 10 14 20 0 q 10 -14 20 0" fill="none"
                    stroke={ac ? "var(--current)" : "var(--ink-faint)"} strokeWidth="2.5" />
              {!ac && <line x1="60" y1="172" x2="120" y2="172" stroke="var(--water)" strokeWidth="2.5" />}
              <text x="90" y="230" textAnchor="middle" fontFamily="IBM Plex Mono, monospace"
                    fontSize="12.5" fill="var(--ink-soft)" letterSpacing="0.08em">{kids ? "PLANT" : "PLANT · GENERATES"}</text>
              {chip(90, PLANT_KV, true, kids ? "starts at" : "SOURCE")}
            </g>

            {/* wire plant → slot A */}
            <line x1="140" y1="157" x2="200" y2="157" stroke="var(--ink)" strokeWidth="2.5" />
            {slot(slotA, 200, setSlotA, kids ? "tap me!" : "SLOT A · at the plant")}

            {/* the long line — with pylons; glows red with loss */}
            <line x1="264" y1="157" x2="560" y2="157"
                  stroke={loss > 0.3 ? "oklch(0.62 0.19 35)" : "var(--ink)"}
                  strokeWidth={loss > 0.3 ? 4 : 2.5} />
            {[330, 412, 494].map(x => (
              <g key={x} stroke="var(--ink-faint)" strokeWidth="1.6">
                <line x1={x} y1={157} x2={x - 11} y2={196} />
                <line x1={x} y1={157} x2={x + 11} y2={196} />
                <line x1={x - 7} y1={182} x2={x + 7} y2={182} />
              </g>
            ))}
            {loss > 0.3 && [350, 420, 490].map((x, i) => (
              <path key={x} d={`M ${x} 146 q 4 -7 0 -13 q -4 -6 0 -12`} fill="none"
                    stroke="oklch(0.62 0.19 35)" strokeWidth="1.8" opacity="0.7">
                <animate attributeName="opacity" values="0.2;0.8;0.2" dur="1.1s"
                         begin={`-${i * 0.33}s`} repeatCount="indefinite" />
              </path>
            ))}
            {chip(412, lineKV, loss <= 0.3, kids ? "on the long trip" : "THE LONG LINE")}
            <text x="412" y="222" textAnchor="middle" fontFamily="IBM Plex Mono, monospace"
                  fontSize="12.5" fill={loss > 0.3 ? "oklch(0.55 0.17 35)" : "var(--ink-faint)"} letterSpacing="0.08em">
              {Math.round(loss * 100)}% LOST AS HEAT (I²R)
            </text>
            <text x="412" y="240" textAnchor="middle" fontFamily="IBM Plex Mono, monospace"
                  fontSize="12" fill="var(--ink-soft)" letterSpacing="0.06em">
              {kids
                ? `flow on the trip: ${fmtI(lineI)} · wire squeeze: never changes`
                : `I = ${fmtI(lineI)} · R = 4 Ω (the wire — FIXED)`}
            </text>

            {slot(slotB, 560, setSlotB, kids ? "tap me!" : "SLOT B · at the town")}
            <line x1="624" y1="157" x2="668" y2="157" stroke="var(--ink)" strokeWidth="2.5" />

            {/* the town — three houses */}
            {[0, 1, 2].map(i => {
              const hx = 672 + i * 50, hy = 134;
              const winFill = fried ? "oklch(0.6 0.21 30)"
                : townOK && delivered > 15 ? `oklch(${0.55 + 0.35 * (delivered / 100)} ${0.05 + 0.13 * (delivered / 100)} 85)`
                : "var(--bg-deeper)";
              return (
                <g key={i}>
                  <path d={`M ${hx} ${hy + 14} L ${hx + 19} ${hy} L ${hx + 38} ${hy + 14} L ${hx + 38} ${hy + 46} L ${hx} ${hy + 46} Z`}
                        fill="var(--bg-card)" stroke="var(--ink)" strokeWidth="2" />
                  <rect x={hx + 11} y={hy + 22} width="16" height="13" fill={winFill} stroke="var(--ink)" strokeWidth="1.4" />
                  {fried && (
                    <text x={hx + 19} y={hy - 6} textAnchor="middle" fontSize="15" fill="oklch(0.55 0.2 30)">⚡</text>
                  )}
                </g>
              );
            })}
            {chip(745, townKV, townOK, kids ? "at the houses" : "TOWN GATE · WANTS 25")}
            <text x="745" y="222" textAnchor="middle" fontFamily="IBM Plex Mono, monospace"
                  fontSize="12.5" fill="var(--ink-soft)" letterSpacing="0.08em">
              {fried ? "✗ FRIED" : weak ? "✗ TOO WEAK" : `${delivered}% POWER`}
            </text>

            {/* delivered meter */}
            <rect x="40" y="262" width="770" height="10" fill="var(--bg-deeper)" stroke="var(--rule)" />
            <rect x="40" y="262" width={770 * ((townOK ? delivered : 0) / 100)} height="10"
                  fill={bright ? "var(--water)" : "oklch(0.62 0.17 35)"} style={{ transition: "width 300ms ease" }} />
          </svg>
          {/* per-stage stats — where the volts and amps actually go */}
          <div style={{ display: "grid", gridTemplateColumns: "repeat(auto-fit, minmax(180px, 1fr))", gap: 10, marginTop: 14 }}>
            {(() => {
              const P = 10;                                    // MW leaving the plant
              const iLine = Math.round(P * 1000 / lineKV);     // A on the line
              const heatMW = +(loss * P).toFixed(loss > 0.05 ? 1 : 2);
              const townV = fried ? "400,000 V ⚡" : downOn ? "120 V" : `${(lineKV * 1000).toLocaleString()} V`;
              const cell = (tag, rows) => (
                <div key={tag} style={{ border: "1.5px solid var(--rule)", borderRadius: 8, padding: "10px 14px", background: "var(--bg-deeper)" }}>
                  <div className="eyebrow" style={{ marginBottom: 6, fontSize: 10.5 }}>{tag}</div>
                  {rows.map((r, i) => (
                    <div key={i} style={{ display: "flex", justifyContent: "space-between", gap: 8, fontFamily: "IBM Plex Mono, monospace", fontSize: 12.5, padding: "2px 0" }}>
                      <span style={{ color: "var(--ink-faint)" }}>{r[0]}</span>
                      <span style={{ color: r[2] || "var(--ink)" }}>{r[1]}</span>
                    </div>
                  ))}
                </div>
              );
              return [
                cell(kids ? "AT THE PLANT" : "PLANT · OUT", [
                  [kids ? "push" : "V", "25,000 V"],
                  [kids ? "flow" : "I", "400 A"],
                  [kids ? "power" : "P", "10 MW"],
                ]),
                cell(kids ? "ON THE LONG WIRE" : "LINE · EN ROUTE", [
                  [kids ? "push" : "V", `${lineKV.toLocaleString()},000 V`, upOn ? "var(--water-deep)" : undefined],
                  [kids ? "flow" : "I", `${iLine} A`, upOn ? "var(--water-deep)" : undefined],
                  [kids ? "wire squeeze" : "R (wire)", "39 Ω · fixed"],
                  [kids ? "wasted as heat" : "I²R heat", `${heatMW} MW`, loss > 0.05 ? "oklch(0.55 0.17 35)" : "var(--water-deep)"],
                ]),
                cell(kids ? "AT THE HOUSES" : "TOWN · ARRIVING", [
                  [kids ? "push" : "V", townV, fried ? "oklch(0.55 0.17 35)" : undefined],
                  [kids ? "power left" : "P delivered", fried ? "—" : `${(P * delivered / 100).toFixed(1)} MW`],
                ]),
              ];
            })()}
          </div>
          <div className="branch-readout" style={{ marginTop: 12 }}>
            <span>{kids ? "how's the town doing?" : "verdict"}</span>
            <span style={{ fontFamily: "IBM Plex Mono, monospace", fontSize: 13.5,
                           color: bright && ac ? "var(--water-deep)" : "var(--ink-soft)" }}>{verdict}</span>
          </div>
        </div>
        <div className="marg" style={{ marginTop: 14, maxWidth: 640 }}>
          {kids
            ? <>Watch the middle card when you add the step-up: the push gets 16× TALLER and the flow gets 16× smaller — the same power, carried differently. The wire's squeeze never changes; it just gets a much gentler flow to chew on, so it wastes way less heat.</>
            : <>Read the line card as you toggle the step-up: V ×16, I ÷16 — the product (power) is conserved; a transformer trades push for flow. The wire's resistance never changes. What changes is the heat: P = I²R, so 16× less current = 256× less waste. That's the entire reason the grid bothers with 400,000 V.</>}
        </div>
        <div className="marg" style={{ marginTop: 14, maxWidth: 640 }}>
          {kids
            ? <>Try every combo! Taller-then-gentler wins. Gentler-then-taller gets the push right at the end — but the skinny trip already wasted it all. WHERE you change the push matters.</>
            : <>Same physics as chapter 3: the line wastes P = I²R, so the lever is shrinking I — same power as a taller, skinnier push. Try ÷16 at the plant and ×16 at the town: the gate voltage comes out right, yet almost nothing arrives. Order matters. Edison's DC couldn't change heights at all; that's the whole Current War, in one toy.</>}
        </div>
      </div>
    </section>
  );
}

/* ─── RMS — two ways to measure a wave (must precede the RMS practice) ── */
function RmsSection({ kids }) {
  return (
    <section className="section" id="rms" data-screen-label="08 Peak vs RMS">
      <div className="marker">§ {kids ? "07" : "08"} · how tall is a wave, really?</div>
      <div className="section-inner">
        <div className="two-col">
          <div>
            <h2 className="serif">Peak, and<br/><em>RMS</em>.</h2>
            <p className="lede">
              {kids
                ? <>A wave's push keeps changing — so what number do you write on the label? Two honest answers: the <em>tallest</em> the wave ever gets (the peak), and the steady push that would <em>work as hard</em> (the "effective" value).</>
                : <>A wave's voltage is always changing — so which single number describes it? Two conventions: the <em>peak</em> (the top of the swing) and the <em>RMS</em> or "effective" value — the steady DC voltage that would deliver the same heating power to a load.</>}
            </p>
            <p>
              {kids
                ? <>The "works as hard" number is smaller than the peak — because the wave only touches its tallest point for an instant. For a smooth wave it's the peak ÷ 1.414.</>
                : <>For a sine wave, <span className="mono">V_rms = V_peak ÷ √2 ≈ 0.707 × V_peak</span> — smaller than the peak because the wave only kisses its maximum for an instant, spending most of each cycle lower. (RMS stands for root-mean-square, after the recipe used to compute it; you'll never need to run that recipe by hand here.)</>}
            </p>
            <div className="marg" style={{ marginTop: 14 }}>
              {kids
                ? <>Surprise: the "120" on a wall plug is the works-as-hard number. The wave actually swings up to about 170!</>
                : <>The famous "120 V" of North American mains <em>is</em> the RMS. The actual wave swings ±170 V, sixty times a second. Ratings on outlets, multimeter AC readings, audio specs — nearly always RMS.</>}
            </div>
          </div>
          <div>
            <div className="card" style={{ padding: "20px 24px" }}>
              <div className="eyebrow" style={{ marginBottom: 12 }}>one wave, two rulers</div>
              <svg viewBox="0 0 360 200" width="100%" style={{ display: "block" }}>
                <line x1="16" y1="100" x2="344" y2="100" stroke="var(--rule-strong)" strokeWidth="1" />
                {/* sine wave */}
                <path d={Array.from({ length: 81 }, (_, i) => {
                  const x = 16 + i * 4.1, y = 100 - 62 * Math.sin(i / 80 * Math.PI * 4);
                  return (i ? "L" : "M") + x.toFixed(1) + " " + y.toFixed(1);
                }).join(" ")} fill="none" stroke="var(--current)" strokeWidth="2.5" />
                {/* peak line */}
                <line x1="16" y1="38" x2="344" y2="38" stroke="var(--ink-faint)" strokeWidth="1.2" strokeDasharray="5 5" />
                <text x="20" y="30" fontFamily="IBM Plex Mono, monospace" fontSize="12.5" fill="var(--ink-faint)">
                  {kids ? "tallest point · 170" : "peak · 170 V"}
                </text>
                {/* rms line */}
                <line x1="16" y1="56.2" x2="344" y2="56.2" stroke="var(--water)" strokeWidth="1.6" strokeDasharray="7 4" />
                <text x="178" y="74" fontFamily="IBM Plex Mono, monospace" fontSize="12.5" fill="var(--water-deep)">
                  {kids ? "works-as-hard line · 120" : "RMS · 120 V — same heat as steady DC here"}
                </text>
              </svg>
              {!kids && (
                <div className="eq" style={{ fontSize: 24, marginTop: 10 }}>
                  <span>V<sub style={{ fontSize: "0.55em" }}>rms</sub></span>
                  <span className="op">=</span>
                  <span className="frac"><span className="top">V<sub style={{ fontSize: "0.55em" }}>peak</sub></span><span className="bar"></span><span className="bot">√2</span></span>
                </div>
              )}
            </div>
          </div>
        </div>
      </div>
    </section>
  );
}

const Q_ADULT = [
  { q: "DC stands for direct current, which means the flow…", kind: "concept", options: ["reverses constantly", "goes one steady direction", "is always large", "only exists in wires"], correct: 1, explain: "Direct current is steady, one-direction flow — like a battery." },
  { q: "AC (alternating current) does what?", kind: "concept", options: ["holds steady", "reverses direction many times per second", "only flows once", "stores charge"], correct: 1, explain: "AC periodically reverses — charge sloshes back and forth." },
  { q: "On an oscilloscope, steady DC looks like…", kind: "concept", options: ["a sine wave", "a flat horizontal line", "a spiral", "random dots"], correct: 1, explain: "Constant voltage = a flat line over time." },
  { q: "Frequency is measured in…", kind: "concept", options: ["volts", "ohms", "hertz (Hz)", "watts"], correct: 2, explain: "Hertz = cycles per second. US grid is 60 Hz." },
  { q: "AC won the grid because it can be…", kind: "concept", options: ["stored in batteries", "stepped up/down by transformers for efficient transmission", "touched safely", "made without power plants"], correct: 1, explain: "Transformers (AC-only) enable high-voltage, low-loss long-distance transmission." },
  { q: "Inside your laptop charger, AC is turned back into DC by a…", kind: "concept", options: ["resistor", "rectifier (diodes)", "switch", "battery"], correct: 1, explain: "A diode rectifier converts AC to DC for the electronics." },
  {
    q: "Mains power in a wall outlet reverses direction about…", kind: "concept",
    options: ["once a minute", "50–60 times a second", "a million times a second", "never"],
    correct: 1,
    explain: "50 Hz (Europe) or 60 Hz (North America) — the water sloshes back and forth that fast.",
  },
  {
    q: "Why is the power GRID run on AC rather than DC?", kind: "concept",
    options: ["AC is safer to touch", "AC's voltage is easy to step up/down with transformers for efficient travel", "DC doesn't work in wires", "AC is newer"],
    correct: 1,
    explain: "Transformers only work on AC. Step voltage up, current (and loss) drops for the long haul, then step back down.",
  },
  {
    q: "Your phone charger's real job is to…", kind: "concept",
    options: ["make AC from DC", "convert wall AC into low-voltage DC", "store electricity", "slow the electrons down"],
    correct: 1,
    explain: "Gadgets run on DC. The charger steps the AC down and rectifies it into steady DC.",
  },
  {
    q: "A transformer steps voltage UP for the power line. What happens to the current?",
    kind: "concept",
    options: ["It also goes up", "It drops proportionally — power (V×I) stays the same", "It stays exactly the same", "It reverses direction"],
    correct: 1,
    explain: "A transformer trades push for flow, not power: V×I is conserved. Step V up 16× and I drops to 1/16th.",
  },
  {
    q: "Why does stepping current DOWN matter so much for a long power line?",
    kind: "concept",
    options: [
      "It doesn't — only voltage matters",
      "Line loss is P = I²R, so halving current cuts wasted heat to a QUARTER",
      "Lower current means the wire gets longer",
      "It makes the wave frequency higher",
    ],
    correct: 1,
    explain: "Heat loss depends on current SQUARED. Shrinking I by 16× (via a step-up transformer) cuts wasted power by 256×.",
  },
  {
    q: "The 120 V (or 230 V) marked on a wall outlet is…",
    kind: "concept",
    options: ["the wave's peak voltage", "the RMS — the 'works as hard as steady DC' value", "the lowest the wave ever reaches", "an average that includes negative dips"],
    correct: 1,
    explain: "RMS is the steady-DC-equivalent number. The actual wave swings well above and below it — up to ~170 V for a 120 V RMS mains line.",
  },
  {
    q: "Why couldn't Edison's all-DC grid change voltage at all?",
    kind: "concept",
    options: [
      "DC is too dangerous to step up",
      "Transformers only work on a CHANGING signal — DC never changes, so there's nothing for them to grab onto",
      "DC moves too fast for transformers",
      "It could — the Current War was about something else",
    ],
    correct: 1,
    explain: "Transformers work by induction, which needs a changing field — AC provides that every cycle; steady DC gives it nothing to work with.",
  },
];
const Q_KIDS = [
  { q: "DC flow goes…", kind: "concept", options: ["one steady way", "back and forth", "in circles only", "nowhere"], correct: 0, explain: "One steady direction — like a battery!" },
  { q: "AC flow…", kind: "concept", options: ["holds still", "sloshes back and forth", "only flows once", "is a bucket"], correct: 1, explain: "Back and forth, super fast!" },
  { q: "On a screen, steady DC is a…", kind: "concept", options: ["wave", "flat line", "star", "circle"], correct: 1, explain: "A flat line — it never changes." },
  { q: "AC on a screen looks like a…", kind: "concept", options: ["flat line", "wave", "dot", "box"], correct: 1, explain: "A wiggly wave going up and down!" },
  { q: "The wall plug uses AC because it can travel…", kind: "concept", options: ["a short way", "very far across wires", "only underwater", "by air"], correct: 1, explain: "Very far without fading — that's AC's superpower." },
  {
    q: "DC water flows…", kind: "concept",
    options: ["back and forth", "steadily one way", "in circles only", "not at all"],
    correct: 1,
    explain: "DC = one steady direction, like a barrel draining downhill.",
  },
  {
    q: "AC water moves…", kind: "concept",
    options: ["one way forever", "back and forth, over and over", "only at night", "slower every day"],
    correct: 1,
    explain: "AC sloshes back and forth on a schedule — at home, 50–60 times every second!",
  },
  {
    q: "Hertz (Hz) counts…", kind: "concept",
    options: ["how heavy it is", "how many back-and-forths each second", "how hot it gets", "how long the wire is"],
    correct: 1,
    explain: "One hertz = one full slosh per second.",
  },
  {
    q: "A power-line transformer makes the push MUCH taller. What happens to the flow?",
    kind: "concept",
    options: ["It gets taller too", "It shrinks way down", "Nothing changes", "It reverses"],
    correct: 1,
    explain: "Taller push, smaller flow — same total power, just traded! That's the transformer's whole trick.",
  },
  {
    q: "Why do power lines want a SMALL flow, even with a huge push?",
    kind: "concept",
    options: ["Small flow makes way less wasted heat in the wire", "Small flow travels slower", "It doesn't matter at all", "Small flow is louder"],
    correct: 0,
    explain: "Heat wasted in a wire grows fast with flow — shrink the flow and you save a LOT of heat over a long line.",
  },
];

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 ? "Two kinds" : "AC vs DC" },
    { id: "acdc", label: "Compare" },
    { id: "frequency", label: kids ? "Fast & big" : "Frequency" },
    { id: "predict", label: "Predict" },
    { id: "playground", label: "Playground" },
    ...(kids ? [] : [{ id: "example", label: "The grid" }]),
    { id: "practice", label: "Practice" },
    { id: "quiz", label: "Quiz" },
    { id: "whats-next", label: "What's next" },
  ];
  return (
    <>
      <ChapterStartMarker chapterN="08" />
      <ProgressBar />
      <TopBar currentN="08" chapterLabel="Ch. 08 — The Wave"
              audience={t.audience} setAudience={(v) => setTweak("audience", v)} />
      <ChapterNav items={navItems} />
      <main>
        <CoverPage chapterN="08"
                   chapterTitle={<>The <em>Wave</em>.</>}
                   chapterSub="Chapter 8 · AC, DC & frequency"
                   kids={kids}
                   lede={kids
                     ? <>Until now, water flowed one steady way. But wall plugs push and pull super fast, so the water <em>sloshes</em>. Meet AC — the back-and-forth wave.</>
                     : <>Everything so far was direct current — steady, one-way. Wall power alternates, sloshing back and forth many times a second. We'll see why, what frequency means, and how it ties back to the diode and the grid.</>} />
        <LessonScrollyteller showScope={t.showScope} kids={kids} />

        <CheckpointQuiz kids={kids} label="Checkpoint 1" pick={2}
          title={kids ? "Quick check!" : "Did it stick?"}
          questions={[
            {
              q: "AC means the water…",
              options: ["Sloshes back and forth, over and over", "Flows one way forever", "Stands perfectly still", "Only flows at night"],
              correct: 0,
              explain: kids ? "Alternating = back-and-forth. The push swaps direction again and again, so the flow sloshes with it."
                            : "Alternating current: the voltage reverses polarity periodically, so charge oscillates in place rather than marching one way.",
            },
            {
              q: kids ? "'Frequency' counts…" : "Frequency (hertz) counts…",
              options: ["How many complete sloshes happen each second", "How hard the push is", "How big the pipe is", "How hot the wire gets"],
              correct: 0,
              explain: kids ? "One full back-AND-forth is one slosh. Count the sloshes in a second — that's the frequency."
                            : "Hz = full cycles per second. Mains runs at 50 or 60 Hz; pitch, radio dials, and CPU clocks are all the same quantity at different scales.",
            },
            {
              q: "Steady DC on the scope draws…",
              options: ["A flat horizontal line — the push never changes", "A wave", "A staircase", "Nothing at all"],
              correct: 0,
              explain: kids ? "If the push just sits there, the pen never wiggles — flat line. Waves only appear when something CHANGES."
                            : "The trace plots voltage against time: constant voltage = zero variation = a flat line at that level.",
            },
            {
              q: "Mains power reverses 50–60 times a second, yet your lamp doesn't visibly flicker because…",
              options: ["It's far too fast for your eyes (and filaments stay hot between sloshes)", "The bulb stores light", "It actually flickers and you blink in sync", "The wall smooths it"],
              correct: 0,
              explain: kids ? "Your eyes can't catch anything that fast — and a glowing wire stays hot through the tiny gaps anyway."
                            : "Persistence of vision plus thermal inertia: the filament barely cools between half-cycles, and 100–120 brightness ripples/sec exceed flicker fusion.",
            },
          ]} />

        <WorkedExampleSection kids={kids} />
        <GridGameSection kids={kids} />
        <RmsSection kids={kids} />

        <CheckpointQuiz kids={kids} label="Checkpoint 2" pick={2}
          title={kids ? "Spot it in real life!" : "Out in the wild."}
          intro={kids ? "Waves are pouring out of your walls and speakers right now." : "The wave, at work around you."}
          questions={[
            {
              q: "Why does the grid ship AC across the country instead of DC?",
              options: ["AC is easy to step up and down with transformers — travel at high push, deliver at low", "AC is safe to touch", "DC can't travel through long wires at all", "AC is newer"],
              correct: 0,
              explain: kids ? "Sloshing water is easy to trade between 'tall and skinny' and 'short and wide' pushes. Travel tall (less waste), arrive short (safe for homes)."
                            : "Transformers only work on changing current. Stepping up to hundreds of kV slashes I²R line losses; stepping down makes it usable. That won the AC/DC war.",
            },
            {
              q: "Your laptop's power brick exists to…",
              options: ["Turn the wall's AC into the steady DC the chips need", "Turn DC into AC", "Store extra electricity", "Cool the laptop"],
              correct: 0,
              explain: kids ? "Chips want a calm one-way flow, but the wall hands you sloshing. The brick is the translator between them."
                            : "Rectify (ch. 7's valves), smooth (ch. 4's buckets), regulate — the brick converts 50/60 Hz mains into clean low-voltage DC.",
            },
            {
              q: "A bass note and a squeaky high note differ, electrically, in…",
              options: ["Frequency — slow sloshes for bass, fast for treble", "Wire thickness", "Battery size", "Color"],
              correct: 0,
              explain: kids ? "Slow sloshes wobble the speaker slowly — a deep boom. Fast sloshes wobble it fast — a squeak!"
                            : "Audio is AC: the signal's frequency is the pitch (≈20 Hz–20 kHz), and the speaker cone traces the wave directly.",
            },
            {
              q: "A radio tuner picks ONE station out of the air by…",
              options: ["Answering to just one frequency — like a swing that only pumps at its own rhythm", "Using a thicker antenna", "Turning up the power", "Luck"],
              correct: 0,
              explain: kids ? "Every station sloshes at its own speed. The tuner is a swing that only swings big for ONE rhythm — everyone else's pushes barely move it."
                            : "An LC circuit resonates at one frequency; tuning shifts that resonance to the chosen carrier. Frequency is how the air carries many channels at once.",
            },
          ]} />

        <PracticeProblems chapterN="08" kids={kids} problems={[
          (rng) => {
            const f = rng.pick([50, 60, 100, 25]);
            const ms = +(1000 / f).toFixed(1);
            return {
              q: { adult: `Mains AC runs at ${f} Hz. What is the period of one cycle? (Answer in milliseconds.)`, kids: `The wave repeats ${f} times a second. How long is one wave? (in thousandths of a second)` },
              unit: "ms", answer: ms, tol: 0.04,
              hint: "T = 1 ÷ f, then ×1000 for ms.",
              solution: { adult: `T = 1 ÷ f = 1 ÷ ${f} = ${+(1 / f).toFixed(4)} s = ${ms} ms.`, kids: `1 ÷ ${f} = ${ms} thousandths.` } };
          },
          (rng) => {
            const vp = rng.pick([5, 10, 12, 15, 20]);
            const rms = +(vp / Math.SQRT2).toFixed(2);
            return {
              q: { adult: `An AC signal has a peak voltage of ${vp} V. What is its RMS (effective) voltage?`, kids: `The wave's tallest point is ${vp}. The 'effective' value is the peak ÷ 1.414. What is it?` },
              unit: "V", answer: rms, tol: 0.03,
              hint: "V_rms = V_peak ÷ √2.",
              solution: { adult: `V_rms = V_peak ÷ √2 = ${vp} ÷ 1.414 = ${rms} V.`, kids: `${vp} ÷ 1.414 ≈ ${rms}.` } };
          },
          (rng) => {
            const ms = rng.pick([5, 10, 20, 25, 40]);
            const f = +(1000 / ms).toFixed(0);
            return {
              q: { adult: `A waveform has a period of ${ms} ms. What is its frequency?`, kids: `One wave takes ${ms} thousandths of a second. How many per second?` },
              unit: "Hz", answer: f, tol: 0.04,
              hint: `f = 1 ÷ T, with T in seconds (${ms} ms = ${ms / 1000} s).`,
              solution: { adult: `f = 1 ÷ T = 1 ÷ ${ms / 1000} s = ${f} Hz.`, kids: `1 ÷ ${ms / 1000} = ${f}.` } };
          },
        ]} />

        <ChapterQuiz chapterN="08"
          title={kids ? "Quick quiz!" : "Check your understanding."}
          intro={kids ? "Five quick questions about waves." : "AC, DC & frequency. 70% to pass; retry freely."}
          questions={kids ? Q_KIDS : Q_ADULT} pick={5} />
        <WhatsNext currentN="08" kids={kids}
          summary={kids
            ? <>You learned the back-and-forth wave! Next: a heavy spinning wheel that fights changes in flow — the inductor.</>
            : <>You've got AC, frequency, and why the grid alternates. Next: the inductor — a flywheel for current, and the mirror image of the capacitor.</>}
          prevHref="chapter7.html" prevLabel="Chapter 7"
          nextHref="chapter9.html" nextLabel="Chapter 9 · The Flywheel" />
      </main>
      <TweaksPanel title="Tweaks">
        <CommonTweaks t={t} setTweak={setTweak}
          animationToggles={[{ key: "showScope", label: "Show scope" }]} />
      </TweaksPanel>
      <GlossaryFab />
    </>
  );
}

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