// ====== ELECTRICITY EXPERIMENTS ======

// ---------- 1. Simple Circuit ----------
function SimpleCircuitExp({ category, name, catColor }) {
  const [mode, setMode] = useState('series'); // simple, series, parallel
  const [switchOn, setSwitchOn] = useState(false);
  const [batteryV, setBatteryV] = useState(3); // V
  const [bulb1On, setBulb1On] = useState(false);
  const [bulb2On, setBulb2On] = useState(false);

  const canvasW = 650, canvasH = 400;
  const cx = canvasW / 2, cy = canvasH / 2;

  // Calculate based on mode
  const R_bulb = 10; // ohms per bulb
  let totalR, current, bulb1Current, bulb2Current;

  if (mode === 'simple') {
    totalR = R_bulb;
    current = switchOn ? batteryV / totalR : 0;
    bulb1Current = current;
    bulb2Current = 0;
  } else if (mode === 'series') {
    totalR = R_bulb * 2;
    current = switchOn ? batteryV / totalR : 0;
    bulb1Current = current;
    bulb2Current = current;
  } else { // parallel
    totalR = R_bulb / 2;
    current = switchOn ? batteryV / totalR : 0;
    bulb1Current = switchOn ? batteryV / R_bulb : 0;
    bulb2Current = switchOn ? batteryV / R_bulb : 0;
  }

  const brightness = (i) => Math.min(1, i / 0.5); // normalized

  const panelTabs = [
    { id: 'controls', label: '操作' },
    { id: 'data', label: '数据/公式' },
    { id: 'principle', label: '原理' },
  ];

  const panelContent = (tab) => {
    if (tab === 'controls') return (
      <>
        <div className="panel-section">
          <div className="panel-section-title">电路类型</div>
          <div className="btn-row">
            <button className={`btn ${mode === 'simple' ? 'primary' : ''}`} style={{flex:1}} onClick={() => setMode('simple')}>简单电路</button>
            <button className={`btn ${mode === 'series' ? 'primary' : ''}`} style={{flex:1}} onClick={() => setMode('series')}>串联</button>
            <button className={`btn ${mode === 'parallel' ? 'primary' : ''}`} style={{flex:1}} onClick={() => setMode('parallel')}>并联</button>
          </div>
        </div>
        <div className="panel-section">
          <div className="panel-section-title">电源电压</div>
          <ControlSlider label="U" value={batteryV} onChange={setBatteryV} min={1} max={6} step={0.5} unit=" V" />
        </div>
        <div className="panel-section">
          <div className="panel-section-title">开关</div>
          <ControlToggle label="闭合开关" checked={switchOn} onChange={setSwitchOn} />
        </div>
      </>
    );
    if (tab === 'data') return (
      <>
        <div className="meter-row">
          <MeterCard label="电源电压" value={batteryV} unit=" V" />
          <MeterCard label="总电流" value={current.toFixed(2)} unit=" A" />
        </div>
        <div className="meter-row">
          <MeterCard label="总电阻" value={totalR.toFixed(1)} unit=" Ω" />
          <MeterCard label="灯泡1电流" value={bulb1Current.toFixed(2)} unit=" A" />
        </div>
        <FormulaBox
          expr="I = U / R"
          subs={[
            `电源电压 U = <span class="val">${batteryV} V</span>`,
            `总电阻 R = <span class="val">${totalR.toFixed(1)} Ω</span>`,
            `总电流 I = U/R = <span class="val">${current.toFixed(2)} A</span>`,
            mode === 'series'
              ? `串联：R总 = R₁ + R₂，电流处处相等`
              : mode === 'parallel'
                ? `并联：1/R总 = 1/R₁ + 1/R₂，各支路电压相等`
                : `简单电路：只有一个用电器`,
          ]}
        />
      </>
    );
    if (tab === 'principle') return (
      <ExplainBox title="电路基础">
        <p><strong>电路的组成：</strong>电源、用电器、开关、导线。</p>
        <p style={{marginTop:6}}><strong>通路：</strong>处处连通的电路，有用电器工作。</p>
        <p><strong>开路（断路）：</strong>某处断开的电路。</p>
        <p><strong>短路：</strong>直接用导线把电源两极连起来（危险！）。</p>
        <p style={{marginTop:6}}><strong>串联：</strong>用电器依次连接，只有一条电流路径。</p>
        <p>• 电流处处相等</p>
        <p>• 总电压 = 各部分电压之和</p>
        <p>• 总电阻 = 各电阻之和</p>
        <p style={{marginTop:6}}><strong>并联：</strong>用电器并列连接，有多条电流路径。</p>
        <p>• 各支路电压相等</p>
        <p>• 干路电流 = 各支路电流之和</p>
      </ExplainBox>
    );
  };

  return (
    <ExperimentShell category={category} name={name} catColor={catColor}
      panelTabs={panelTabs} panelContent={panelContent}>
      <div className="sim-canvas-wrap">
        <svg width={canvasW} height={canvasH} className="sim-canvas paper-bg">
          {/* Circuit layout: battery on left, wires forming a loop */}

          {/* wires - outer rectangle */}
          {mode === 'simple' && (
            <>
              {/* main loop */}
              <rect x="100" y="100" width="450" height="220" fill="none"
                stroke={switchOn ? '#F5D547' : '#888'}
                strokeWidth="3" strokeLinejoin="round" />

              {/* battery left side */}
              <g transform="translate(100, 190)">
                <line x1="0" y1="-20" x2="0" y2="20" stroke="#333" strokeWidth="4" />
                <line x1="-5" y1="-15" x2="5" y2="-15" stroke="#333" strokeWidth="3" />
                <text x="-8" y="-25" fill="#FF3B30" fontSize="10">+</text>
                <text x="-8" y="35" fill="#333" fontSize="10">-</text>
                <text x="-5" y="50" fill="#5E3A18" fontSize="11">{batteryV}V</text>
              </g>

              {/* switch on top */}
              <g transform="translate(250, 100)">
                <circle cx="0" cy="0" r="5" fill="#333" />
                <circle cx="40" cy="0" r="5" fill="#333" />
                {switchOn ? (
                  <line x1="0" y1="0" x2="40" y2="0" stroke="#333" strokeWidth="3" />
                ) : (
                  <line x1="0" y1="0" x2="35" y2="-20" stroke="#333" strokeWidth="3" />
                )}
                <text x="20" y="-15" textAnchor="middle" fill="#5E3A18" fontSize="11">开关</text>
              </g>

              {/* bulb on right */}
              <g transform="translate(550, 210)">
                <circle cx="0" cy="0" r="22" fill={switchOn ? '#FFEB99' : '#f0f0f0'}
                  stroke="#333" strokeWidth="2" />
                {/* filament */}
                <path d="M -10 5 Q -5 -10 0 5 Q 5 -10 10 5" fill="none"
                  stroke={switchOn ? '#FF6B3D' : '#999'} strokeWidth="1.5" />
                <text x="0" y="40" textAnchor="middle" fill="#5E3A18" fontSize="11">灯泡</text>
                {/* glow */}
                {switchOn && (
                  <circle cx="0" cy="0" r="30" fill="#FFEB99" opacity={brightness(bulb1Current) * 0.3}>
                    <animate attributeName="r" values="28;32;28" dur="2s" repeatCount="indefinite" />
                  </circle>
                )}
              </g>

              {/* current flow animation */}
              {switchOn && (
                <g>
                  {[0, 0.25, 0.5, 0.75].map((phase, i) => (
                    <circle key={i} r="4" fill="#F5D547">
                      <animateMotion
                        dur="3s"
                        repeatCount="indefinite"
                        begin={`${-i * 0.75}s`}
                        path="M 100 190 L 100 100 L 550 100 L 550 210 L 550 320 L 100 320 L 100 210" />
                    </circle>
                  ))}
                </g>
              )}
            </>
          )}

          {mode === 'series' && (
            <>
              {/* circuit loop */}
              <path d="M 100 190 L 100 100 L 550 100 L 550 210 L 550 320 L 100 320 L 100 230"
                fill="none" stroke={switchOn ? '#F5D547' : '#888'} strokeWidth="3" />

              {/* battery */}
              <g transform="translate(100, 210)">
                <line x1="0" y1="-20" x2="0" y2="20" stroke="#333" strokeWidth="4" />
                <line x1="-5" y1="-15" x2="5" y2="-15" stroke="#333" strokeWidth="3" />
                <text x="-8" y="-25" fill="#FF3B30" fontSize="10">+</text>
                <text x="10" y="0" fill="#5E3A18" fontSize="11">{batteryV}V</text>
              </g>

              {/* switch */}
              <g transform="translate(200, 100)">
                <circle cx="0" cy="0" r="5" fill="#333" />
                <circle cx="40" cy="0" r="5" fill="#333" />
                {switchOn ? (
                  <line x1="0" y1="0" x2="40" y2="0" stroke="#333" strokeWidth="3" />
                ) : (
                  <line x1="0" y1="0" x2="35" y2="-20" stroke="#333" strokeWidth="3" />
                )}
                <text x="20" y="-15" textAnchor="middle" fill="#5E3A18" fontSize="11">开关</text>
              </g>

              {/* bulb 1 */}
              <g transform="translate(400, 100)">
                <circle cx="0" cy="0" r="18" fill={switchOn ? '#FFEB99' : '#f0f0f0'}
                  stroke="#333" strokeWidth="2" />
                <path d="M -8 4 Q -4 -8 0 4 Q 4 -8 8 4" fill="none"
                  stroke={switchOn ? '#FF6B3D' : '#999'} strokeWidth="1.5" />
                <text x="0" y="-25" textAnchor="middle" fill="#5E3A18" fontSize="10">灯L₁</text>
              </g>

              {/* bulb 2 */}
              <g transform="translate(550, 210)">
                <circle cx="0" cy="0" r="22" fill={switchOn ? '#FFEB99' : '#f0f0f0'}
                  stroke="#333" strokeWidth="2" />
                <path d="M -10 5 Q -5 -10 0 5 Q 5 -10 10 5" fill="none"
                  stroke={switchOn ? '#FF6B3D' : '#999'} strokeWidth="1.5" />
                <text x="0" y="40" textAnchor="middle" fill="#5E3A18" fontSize="10">灯L₂</text>
              </g>

              {switchOn && (
                <g>
                  {[0, 0.33, 0.66].map((phase, i) => (
                    <circle key={i} r="3.5" fill="#F5D547">
                      <animateMotion dur="4s" repeatCount="indefinite" begin={`${-i * 1.33}s`}
                        path="M 100 200 L 100 100 L 550 100 L 550 320 L 100 320 L 100 220" />
                    </circle>
                  ))}
                </g>
              )}
            </>
          )}

          {mode === 'parallel' && (
            <>
              {/* main wires */}
              <path d="M 100 210 L 100 100 L 250 100" fill="none"
                stroke={switchOn ? '#F5D547' : '#888'} strokeWidth="3" />
              <path d="M 100 210 L 100 320 L 250 320" fill="none"
                stroke={switchOn ? '#F5D547' : '#888'} strokeWidth="3" />

              {/* branch 1 (top) */}
              <line x1="300" y1="100" x2="500" y2="100"
                stroke={switchOn ? '#F5D547' : '#888'} strokeWidth="3" />
              <line x1="300" y1="100" x2="300" y2="100" stroke="#888" strokeWidth="3" />

              {/* branch 2 (bottom) */}
              <line x1="300" y1="320" x2="500" y2="320"
                stroke={switchOn ? '#F5D547' : '#888'} strokeWidth="3" />

              {/* vertical connections */}
              <line x1="300" y1="100" x2="300" y2="160"
                stroke={switchOn ? '#F5D547' : '#888'} strokeWidth="3" />
              <line x1="300" y1="260" x2="300" y2="320"
                stroke={switchOn ? '#F5D547' : '#888'} strokeWidth="3" />
              <line x1="500" y1="100" x2="500" y2="160"
                stroke={switchOn ? '#F5D547' : '#888'} strokeWidth="3" />
              <line x1="500" y1="260" x2="500" y2="320"
                stroke={switchOn ? '#F5D547' : '#888'} strokeWidth="3" />

              {/* right side - common */}
              <path d="M 500 100 L 550 100 L 550 320 L 500 320" fill="none"
                stroke={switchOn ? '#F5D547' : '#888'} strokeWidth="3" />

              {/* battery */}
              <g transform="translate(100, 210)">
                <line x1="0" y1="-20" x2="0" y2="20" stroke="#333" strokeWidth="4" />
                <line x1="-5" y1="-15" x2="5" y2="-15" stroke="#333" strokeWidth="3" />
                <text x="-8" y="-25" fill="#FF3B30" fontSize="10">+</text>
                <text x="-15" y="0" fill="#5E3A18" fontSize="11">{batteryV}V</text>
              </g>

              {/* switch on main path */}
              <g transform="translate(170, 100)">
                <circle cx="0" cy="0" r="5" fill="#333" />
                <circle cx="30" cy="0" r="5" fill="#333" />
                {switchOn ? (
                  <line x1="0" y1="0" x2="30" y2="0" stroke="#333" strokeWidth="3" />
                ) : (
                  <line x1="0" y1="0" x2="27" y2="-18" stroke="#333" strokeWidth="3" />
                )}
                <text x="15" y="-15" textAnchor="middle" fill="#5E3A18" fontSize="10">总开关</text>
              </g>

              {/* bulb L1 - top branch */}
              <g transform="translate(400, 100)">
                <circle cx="0" cy="0" r="18" fill={switchOn ? '#FFEB99' : '#f0f0f0'}
                  stroke="#333" strokeWidth="2" />
                <path d="M -8 4 Q -4 -8 0 4 Q 4 -8 8 4" fill="none"
                  stroke={switchOn ? '#FF6B3D' : '#999'} strokeWidth="1.5" />
                <text x="0" y="-24" textAnchor="middle" fill="#5E3A18" fontSize="10">L₁</text>
              </g>

              {/* bulb L2 - bottom branch */}
              <g transform="translate(400, 320)">
                <circle cx="0" cy="0" r="18" fill={switchOn ? '#FFEB99' : '#f0f0f0'}
                  stroke="#333" strokeWidth="2" />
                <path d="M -8 4 Q -4 -8 0 4 Q 4 -8 8 4" fill="none"
                  stroke={switchOn ? '#FF6B3D' : '#999'} strokeWidth="1.5" />
                <text x="0" y="35" textAnchor="middle" fill="#5E3A18" fontSize="10">L₂</text>
              </g>

              {/* labels */}
              <text x="275" y="215" textAnchor="middle" fill="#5E3A18" fontSize="11">干路</text>
            </>
          )}

          <text x={cx} y="40" textAnchor="middle" fill="#5E3A18" fontSize="14" fontWeight="bold">
            {mode === 'simple' ? '简单电路' : mode === 'series' ? '串联电路' : '并联电路'}
          </text>
        </svg>
      </div>
    </ExperimentShell>
  );
}

// ---------- 2. Ohm's Law / V-A method ----------
function OhmsLawExp({ category, name, catColor }) {
  const [voltage, setVoltage] = useState(3); // V
  const [resistance, setResistance] = useState(10); // Ω
  const [isOn, setIsOn] = useState(false);
  const [uHistory, setUHistory] = useState([]);
  const [iHistory, setIHistory] = useState([]);

  const current = isOn ? voltage / resistance : 0;
  const power = voltage * current;

  // accumulate data for I-U curve
  useEffect(() => {
    if (isOn) {
      setUHistory(h => [...h.slice(-50), voltage]);
      setIHistory(h => [...h.slice(-50), current]);
    }
  }, [voltage, isOn, current]);

  const reset = () => {
    setIsOn(false);
    setUHistory([]);
    setIHistory([]);
  };

  const canvasW = 650, canvasH = 400;

  const panelTabs = [
    { id: 'controls', label: '操作' },
    { id: 'data', label: '数据/曲线' },
    { id: 'principle', label: '原理' },
  ];

  const panelContent = (tab) => {
    if (tab === 'controls') return (
      <>
        <div className="panel-section">
          <div className="panel-section-title">电路参数</div>
          <ControlSlider label="电源电压 U" value={voltage} onChange={setVoltage} min={0.5} max={6} step={0.1} unit=" V" />
          <ControlSlider label="电阻 R" value={resistance} onChange={setResistance} min={1} max={20} step={0.5} unit=" Ω" />
        </div>
        <div className="panel-section">
          <div className="panel-section-title">开关</div>
          <ControlToggle label="闭合开关" checked={isOn} onChange={setIsOn} />
        </div>
        <div className="panel-section">
          <button className="btn" style={{ width: '100%', justifyContent: 'center' }} onClick={reset}>
            ↺ 重置数据
          </button>
        </div>
      </>
    );
    if (tab === 'data') return (
      <>
        <div className="meter-row">
          <MeterCard label="电压表 V" value={isOn ? voltage.toFixed(1) : '0.0'} unit=" V" />
          <MeterCard label="电流表 A" value={current.toFixed(2)} unit=" A" />
        </div>
        <div className="meter-row">
          <MeterCard label="电阻 R" value={resistance} unit=" Ω" sub="R = U/I" />
          <MeterCard label="电功率 P" value={power.toFixed(2)} unit=" W" />
        </div>
        <FormulaBox
          expr="I = U / R"
          subs={[
            `U = <span class="val">${voltage} V</span>`,
            `R = <span class="val">${resistance} Ω</span>`,
            `I = U/R = ${voltage}/${resistance} = <span class="val">${current.toFixed(2)} A</span>`,
            `电阻一定时，电流与电压成正比`,
          ]}
        />
        <div className="chart-box" style={{ height: 160 }}>
          <MiniChart data={iHistory} xLabel="U" yLabel="I" color={catColor} />
        </div>
      </>
    );
    if (tab === 'principle') return (
      <ExplainBox title="欧姆定律">
        <p><strong>内容：</strong>导体中的电流，跟导体两端的电压成正比，跟导体的电阻成反比。</p>
        <p style={{textAlign:'center', fontSize: 18, fontWeight: 'bold', color: 'var(--accent)', margin: '8px 0'}}>
          I = U / R
        </p>
        <p><strong>单位：</strong>I→安(A)，U→伏(V)，R→欧(Ω)</p>
        <p style={{marginTop:6}}><strong>伏安法测电阻：</strong></p>
        <p>用电压表测电压U，电流表测电流I，由 R = U/I 求电阻。</p>
        <p style={{marginTop:6}}><strong>滑动变阻器的作用：</strong></p>
        <p>• 改变电阻两端电压和电流</p>
        <p>• 多次测量求平均值，减小误差</p>
        <p>• 保护电路</p>
      </ExplainBox>
    );
  };

  // Needle angles for analog meters
  const vAngle = -90 + (voltage / 8) * 180; // 0-8V range
  const aAngle = -90 + (current / 1) * 180; // 0-1A range

  return (
    <ExperimentShell category={category} name={name} catColor={catColor}
      panelTabs={panelTabs} panelContent={panelContent}>
      <div className="sim-canvas-wrap">
        <svg width={canvasW} height={canvasH} className="sim-canvas paper-bg">
          {/* Circuit: battery, switch, resistor, ammeter (series), voltmeter (parallel) */}

          {/* main circuit loop */}
          <path d="M 100 200 L 100 120 L 550 120 L 550 280 L 100 280 L 100 240"
            fill="none" stroke={isOn ? '#F5D547' : '#999'} strokeWidth="2.5" />

          {/* battery */}
          <g transform="translate(100, 220)">
            <line x1="0" y1="-20" x2="0" y2="20" stroke="#333" strokeWidth="4" />
            <line x1="-6" y1="-14" x2="6" y2="-14" stroke="#333" strokeWidth="3" />
            <text x="-10" y="-25" fill="#FF3B30" fontSize="10">+</text>
            <text x="12" y="5" fill="#5E3A18" fontSize="10">{voltage}V</text>
          </g>

          {/* switch */}
          <g transform="translate(200, 120)">
            <circle cx="0" cy="0" r="4" fill="#333" />
            <circle cx="30" cy="0" r="4" fill="#333" />
            {isOn ? (
              <line x1="0" y1="0" x2="30" y2="0" stroke="#333" strokeWidth="2.5" />
            ) : (
              <line x1="0" y1="0" x2="26" y2="-16" stroke="#333" strokeWidth="2.5" />
            )}
            <text x="15" y="-12" textAnchor="middle" fill="#5E3A18" fontSize="9">S</text>
          </g>

          {/* resistor */}
          <g transform="translate(320, 120)">
            <rect x="-20" y="-8" width="40" height="16" fill="#e0e0e0" stroke="#333" strokeWidth="1.5" rx="2" />
            {/* bands */}
            <rect x="-15" y="-8" width="3" height="16" fill="#8B4513" />
            <rect x="-9" y="-8" width="3" height="16" fill="#000" />
            <rect x="-3" y="-8" width="3" height="16" fill="#FF0000" />
            <text x="0" y="-14" textAnchor="middle" fill="#5E3A18" fontSize="9">R = {resistance}Ω</text>
          </g>

          {/* ammeter (series) */}
          <g transform="translate(450, 120)">
            <circle cx="0" cy="0" r="22" fill="#fff" stroke="#333" strokeWidth="2" />
            <text x="0" y="-10" textAnchor="middle" fontSize="10" fill="#333" fontWeight="bold">A</text>
            {/* needle */}
            <line x1="0" y1="0"
              x2={Math.cos(aAngle * Math.PI/180) * 14}
              y2={Math.sin(aAngle * Math.PI/180) * 14}
              stroke="#FF3B30" strokeWidth="1.5" />
            <circle cx="0" cy="0" r="2" fill="#333" />
            <text x="0" y="25" textAnchor="middle" fill="#5E3A18" fontSize="9">电流表</text>
          </g>

          {/* voltmeter (parallel) - connected across resistor */}
          <line x1="300" y1="120" x2="300" y2="60" stroke={isOn ? '#F5D547' : '#999'} strokeWidth="2" />
          <line x1="340" y1="120" x2="340" y2="60" stroke={isOn ? '#F5D547' : '#999'} strokeWidth="2" />
          <g transform="translate(320, 60)">
            <circle cx="0" cy="0" r="22" fill="#fff" stroke="#333" strokeWidth="2" />
            <text x="0" y="-10" textAnchor="middle" fontSize="10" fill="#333" fontWeight="bold">V</text>
            <line x1="0" y1="0"
              x2={Math.cos(vAngle * Math.PI/180) * 14}
              y2={Math.sin(vAngle * Math.PI/180) * 14}
              stroke="#FF3B30" strokeWidth="1.5" />
            <circle cx="0" cy="0" r="2" fill="#333" />
            <text x="0" y="35" textAnchor="middle" fill="#5E3A18" fontSize="9">电压表</text>
          </g>

          {/* numeric readings */}
          <g transform="translate(480, 280)">
            <rect x="0" y="0" width="140" height="70" rx="6" fill="#141416" stroke="#333" strokeWidth="1" />
            <text x="10" y="20" fill="#8FA3BD" fontSize="10">电压 U</text>
            <text x="10" y="42" fill={catColor} fontSize="18" fontWeight="bold" fontFamily="JetBrains Mono, monospace">
              {isOn ? voltage.toFixed(1) : '0.0'} V
            </text>
            <text x="80" y="42" fill="#52C795" fontSize="14" fontWeight="bold" fontFamily="JetBrains Mono, monospace">
              {current.toFixed(2)} A
            </text>
            <text x="80" y="20" fill="#8FA3BD" fontSize="10">电流 I</text>
          </g>

          <text x={canvasW/2} y="20" textAnchor="middle" fill="#5E3A18" fontSize="13" fontWeight="bold">
            伏安法测电阻 R = U/I
          </text>
        </svg>
      </div>
    </ExperimentShell>
  );
}

// ---------- 3. Series/Parallel Current & Voltage Rules ----------
function SeriesParallelExp({ category, name, catColor }) {
  const [mode, setMode] = useState('series');
  const [U, setU] = useState(6);
  const [R1, setR1] = useState(10);
  const [R2, setR2] = useState(15);
  const [isOn, setIsOn] = useState(false);

  let totalR, I_total, U1, U2, I1, I2;
  if (mode === 'series') {
    totalR = R1 + R2;
    I_total = isOn ? U / totalR : 0;
    I1 = I_total;
    I2 = I_total;
    U1 = I_total * R1;
    U2 = I_total * R2;
  } else {
    totalR = (R1 * R2) / (R1 + R2);
    I_total = isOn ? U / totalR : 0;
    I1 = isOn ? U / R1 : 0;
    I2 = isOn ? U / R2 : 0;
    U1 = U;
    U2 = U;
  }

  const canvasW = 650, canvasH = 420;

  const panelTabs = [
    { id: 'controls', label: '操作' },
    { id: 'data', label: '数据/规律' },
    { id: 'principle', label: '原理' },
  ];

  const panelContent = (tab) => {
    if (tab === 'controls') return (
      <>
        <div className="panel-section">
          <div className="panel-section-title">电路类型</div>
          <div className="btn-row">
            <button className={`btn ${mode === 'series' ? 'primary' : ''}`} style={{flex:1}} onClick={() => setMode('series')}>串联电路</button>
            <button className={`btn ${mode === 'parallel' ? 'primary' : ''}`} style={{flex:1}} onClick={() => setMode('parallel')}>并联电路</button>
          </div>
        </div>
        <div className="panel-section">
          <div className="panel-section-title">电路参数</div>
          <ControlSlider label="电源电压" value={U} onChange={setU} min={1} max={12} step={0.5} unit=" V" />
          <ControlSlider label="电阻 R₁" value={R1} onChange={setR1} min={5} max={30} step={1} unit=" Ω" />
          <ControlSlider label="电阻 R₂" value={R2} onChange={setR2} min={5} max={30} step={1} unit=" Ω" />
        </div>
        <div className="panel-section">
          <ControlToggle label="闭合开关" checked={isOn} onChange={setIsOn} />
        </div>
      </>
    );
    if (tab === 'data') return (
      <>
        <div className="meter-row">
          <MeterCard label="R₁电压 U₁" value={U1.toFixed(2)} unit=" V" />
          <MeterCard label="R₂电压 U₂" value={U2.toFixed(2)} unit=" V" />
        </div>
        <div className="meter-row">
          <MeterCard label="R₁电流 I₁" value={I1.toFixed(3)} unit=" A" />
          <MeterCard label="R₂电流 I₂" value={I2.toFixed(3)} unit=" A" />
        </div>
        <div className="meter-row">
          <MeterCard label="总电压" value={U} unit=" V" full />
          <MeterCard label="干路电流" value={I_total.toFixed(3)} unit=" A" />
          <MeterCard label="总电阻" value={totalR.toFixed(1)} unit=" Ω" />
        </div>
        <FormulaBox
          expr={mode === 'series' ? '串联：I = I₁ = I₂，U = U₁ + U₂' : '并联：U = U₁ = U₂，I = I₁ + I₂'}
          subs={
            mode === 'series'
              ? [
                `电流处处相等：I = I₁ = I₂ = <span class="val">${I_total.toFixed(3)} A</span>`,
                `总电压等于各部分之和：U = U₁ + U₂ = ${U1.toFixed(2)} + ${U2.toFixed(2)} = <span class="val">${(U1+U2).toFixed(2)} V</span>`,
                `总电阻：R = R₁ + R₂ = <span class="val">${totalR} Ω</span>`,
                `电压之比 = 电阻之比：U₁:U₂ = R₁:R₂ = ${R1}:${R2}`,
              ]
              : [
                `各支路电压相等：U = U₁ = U₂ = <span class="val">${U} V</span>`,
                `干路电流等于各支路之和：I = I₁ + I₂ = ${I1.toFixed(3)} + ${I2.toFixed(3)} = <span class="val">${(I1+I2).toFixed(3)} A</span>`,
                `总电阻：1/R = 1/R₁ + 1/R₂，R = <span class="val">${totalR.toFixed(1)} Ω</span>`,
                `电流之比 = 电阻反比：I₁:I₂ = R₂:R₁`,
              ]
          }
        />
      </>
    );
    if (tab === 'principle') return (
      <ExplainBox title="串并联电路的电流、电压规律">
        <p><strong>串联电路：</strong></p>
        <p>• 电流处处相等：I = I₁ = I₂</p>
        <p>• 总电压等于各部分电压之和：U = U₁ + U₂</p>
        <p>• 总电阻等于各电阻之和：R = R₁ + R₂</p>
        <p>• 电压分配：U₁/U₂ = R₁/R₂</p>
        <p style={{marginTop:8}}><strong>并联电路：</strong></p>
        <p>• 各支路电压相等：U = U₁ = U₂</p>
        <p>• 干路电流等于各支路电流之和：I = I₁ + I₂</p>
        <p>• 总电阻的倒数等于各电阻倒数之和</p>
        <p>• 电流分配：I₁/I₂ = R₂/R₁</p>
      </ExplainBox>
    );
  };

  return (
    <ExperimentShell category={category} name={name} catColor={catColor}
      panelTabs={panelTabs} panelContent={panelContent}>
      <div className="sim-canvas-wrap">
        <svg width={canvasW} height={canvasH} className="sim-canvas paper-bg">

          {mode === 'series' ? (
            <g>
              {/* series circuit */}
              <path d="M 80 250 L 80 120 L 580 120 L 580 250"
                fill="none" stroke={isOn ? '#F5D547' : '#999'} strokeWidth="2.5" />

              {/* battery */}
              <g transform="translate(80, 220)">
                <line x1="0" y1="-30" x2="0" y2="30" stroke="#333" strokeWidth="5" />
                <line x1="-7" y1="-22" x2="7" y2="-22" stroke="#333" strokeWidth="4" />
                <text x="-12" y="-35" fill="#FF3B30" fontSize="12">+</text>
                <text x="12" y="-10" fill="#5E3A18" fontSize="11">{U}V</text>
              </g>

              {/* switch */}
              <g transform="translate(170, 120)">
                <circle cx="0" cy="0" r="5" fill="#333" />
                <circle cx="35" cy="0" r="5" fill="#333" />
                {isOn ? (
                  <line x1="0" y1="0" x2="35" y2="0" stroke="#333" strokeWidth="3" />
                ) : (
                  <line x1="0" y1="0" x2="31" y2="-20" stroke="#333" strokeWidth="3" />
                )}
              </g>

              {/* R1 */}
              <g transform="translate(290, 120)">
                <rect x="-25" y="-10" width="50" height="20" fill="#e0e0e0" stroke="#333" strokeWidth="1.5" rx="2" />
                <text x="0" y="-14" textAnchor="middle" fill="#5E3A18" fontSize="10">R₁ = {R1}Ω</text>
                <text x="0" y="24" textAnchor="middle" fill="#FF3B30" fontSize="10">{U1.toFixed(2)}V</text>
              </g>

              {/* R2 */}
              <g transform="translate(430, 120)">
                <rect x="-25" y="-10" width="50" height="20" fill="#e0e0e0" stroke="#333" strokeWidth="1.5" rx="2" />
                <text x="0" y="-14" textAnchor="middle" fill="#5E3A18" fontSize="10">R₂ = {R2}Ω</text>
                <text x="0" y="24" textAnchor="middle" fill="#FF3B30" fontSize="10">{U2.toFixed(2)}V</text>
              </g>

              {/* ammeter */}
              <g transform="translate(550, 120)">
                <circle cx="0" cy="0" r="18" fill="#fff" stroke="#333" strokeWidth="2" />
                <text x="0" y="3" textAnchor="middle" fontSize="11" fill="#333" fontWeight="bold">A</text>
                <text x="0" y="30" textAnchor="middle" fill="#52C795" fontSize="10">{I_total.toFixed(3)}A</text>
              </g>

              {/* current labels */}
              <text x="80" y="175" fill="#52C795" fontSize="10">I = {I_total.toFixed(3)}A</text>
              <text x="350" y="80" textAnchor="middle" fill="#5E3A18" fontSize="12" fontWeight="bold">
                串联电路
              </text>
            </g>
          ) : (
            <g>
              {/* parallel circuit */}
              <path d="M 100 200 L 100 100 L 250 100" fill="none" stroke={isOn ? '#F5D547' : '#999'} strokeWidth="2.5" />
              <path d="M 100 200 L 100 300 L 250 300" fill="none" stroke={isOn ? '#F5D547' : '#999'} strokeWidth="2.5" />
              <line x1="500" y1="100" x2="580" y2="100" stroke={isOn ? '#F5D547' : '#999'} strokeWidth="2.5" />
              <line x1="500" y1="300" x2="580" y2="300" stroke={isOn ? '#F5D547' : '#999'} strokeWidth="2.5" />
              <path d="M 580 100 L 580 200" fill="none" stroke={isOn ? '#F5D547' : '#999'} strokeWidth="2.5" />

              {/* branches */}
              <line x1="280" y1="100" x2="470" y2="100" stroke={isOn ? '#F5D547' : '#999'} strokeWidth="2.5" />
              <line x1="280" y1="300" x2="470" y2="300" stroke={isOn ? '#F5D547' : '#999'} strokeWidth="2.5" />
              <line x1="250" y1="100" x2="250" y2="100" stroke="#888" strokeWidth="1" />

              {/* vertical connect */}
              <line x1="250" y1="100" x2="250" y2="130" stroke={isOn ? '#F5D547' : '#999'} strokeWidth="2.5" />
              <line x1="250" y1="270" x2="250" y2="300" stroke={isOn ? '#F5D547' : '#999'} strokeWidth="2.5" />
              <line x1="500" y1="100" x2="500" y2="130" stroke={isOn ? '#F5D547' : '#999'} strokeWidth="2.5" />
              <line x1="500" y1="270" x2="500" y2="300" stroke={isOn ? '#F5D547' : '#999'} strokeWidth="2.5" />

              {/* battery */}
              <g transform="translate(100, 200)">
                <line x1="0" y1="-25" x2="0" y2="25" stroke="#333" strokeWidth="4" />
                <line x1="-6" y1="-18" x2="6" y2="-18" stroke="#333" strokeWidth="3" />
                <text x="-10" y="-30" fill="#FF3B30" fontSize="11">+</text>
                <text x="10" y="0" fill="#5E3A18" fontSize="11">{U}V</text>
              </g>

              {/* switch */}
              <g transform="translate(170, 100)">
                <circle cx="0" cy="0" r="4" fill="#333" />
                <circle cx="30" cy="0" r="4" fill="#333" />
                {isOn ? (
                  <line x1="0" y1="0" x2="30" y2="0" stroke="#333" strokeWidth="2.5" />
                ) : (
                  <line x1="0" y1="0" x2="26" y2="-18" stroke="#333" strokeWidth="2.5" />
                )}
                <text x="15" y="-12" textAnchor="middle" fill="#5E3A18" fontSize="9">S</text>
              </g>

              {/* R1 - top branch */}
              <g transform="translate(340, 100)">
                <rect x="-25" y="-9" width="50" height="18" fill="#e0e0e0" stroke="#333" strokeWidth="1.5" rx="2" />
                <text x="0" y="-14" textAnchor="middle" fill="#5E3A18" fontSize="10">R₁={R1}Ω</text>
                <text x="0" y="22" textAnchor="middle" fill="#52C795" fontSize="9">I₁={I1.toFixed(3)}A</text>
              </g>

              {/* R2 - bottom branch */}
              <g transform="translate(340, 300)">
                <rect x="-25" y="-9" width="50" height="18" fill="#e0e0e0" stroke="#333" strokeWidth="1.5" rx="2" />
                <text x="0" y="-14" textAnchor="middle" fill="#5E3A18" fontSize="10">R₂={R2}Ω</text>
                <text x="0" y="22" textAnchor="middle" fill="#52C795" fontSize="9">I₂={I2.toFixed(3)}A</text>
              </g>

              {/* ammeter on dry path */}
              <g transform="translate(540, 200)">
                <circle cx="0" cy="0" r="20" fill="#fff" stroke="#333" strokeWidth="2" />
                <text x="0" y="4" textAnchor="middle" fontSize="11" fill="#333" fontWeight="bold">A</text>
                <text x="0" y="32" textAnchor="middle" fill="#52C795" fontSize="10">干路 {I_total.toFixed(3)}A</text>
              </g>

              <text x="320" y="60" textAnchor="middle" fill="#5E3A18" fontSize="12" fontWeight="bold">
                并联电路
              </text>
            </g>
          )}

          {/* summary box */}
          <g transform="translate(60, 340)">
            <rect x="0" y="0" width="530" height="50" rx="6" fill="#f5f0e0" stroke="#8B6914" strokeWidth="1" />
            <text x="15" y="20" fill="#5E3A18" fontSize="12" fontWeight="bold">
              {mode === 'series'
                ? '串联规律：I = I₁ = I₂ ， U = U₁ + U₂ ， R = R₁ + R₂'
                : '并联规律：U = U₁ = U₂ ， I = I₁ + I₂ ， 1/R = 1/R₁ + 1/R₂'}
            </text>
            <text x="15" y="40" fill="#8B6914" fontSize="11">
              {mode === 'series'
                ? `验证：U₁ + U₂ = ${U1.toFixed(2)} + ${U2.toFixed(2)} = ${(U1+U2).toFixed(2)} V = 总电压 ${U} V`
                : `验证：I₁ + I₂ = ${I1.toFixed(3)} + ${I2.toFixed(3)} = ${(I1+I2).toFixed(3)} A = 干路电流 ${I_total.toFixed(3)} A`}
            </text>
          </g>
        </svg>
      </div>
    </ExperimentShell>
  );
}

// ---------- 4. Sliding Rheostat ----------
function RheostatExp({ category, name, catColor }) {
  const [resistance, setResistance] = useState(10); // Ω (from the rheostat)
  const [maxResistance] = useState(20); // Ω
  const [voltage, setVoltage] = useState(6); // V
  const [bulbR, setBulbR] = useState(8); // Ω (bulb resistance approx)
  const [isOn, setIsOn] = useState(false);

  const totalR = resistance + bulbR;
  const current = isOn ? voltage / totalR : 0;
  const bulbVoltage = current * bulbR;
  const rheoVoltage = current * resistance;
  const bulbPower = bulbVoltage * current;
  const brightness = Math.min(1, bulbPower / 5); // normalize

  const sliderPos = resistance / maxResistance; // 0 to 1

  const canvasW = 650, canvasH = 400;

  const panelTabs = [
    { id: 'controls', label: '操作' },
    { id: 'data', label: '数据/公式' },
    { id: 'principle', label: '原理' },
  ];

  const panelContent = (tab) => {
    if (tab === 'controls') return (
      <>
        <div className="panel-section">
          <div className="panel-section-title">滑动变阻器</div>
          <ControlSlider label="接入电阻 R变" value={resistance} onChange={setResistance} min={0} max={maxResistance} step={0.5} unit=" Ω" />
          <div style={{ fontSize: 11, color: 'var(--text-muted)', textAlign: 'center' }}>
            最大阻值：{maxResistance}Ω，滑片左移电阻减小
          </div>
        </div>
        <div className="panel-section">
          <div className="panel-section-title">电路参数</div>
          <ControlSlider label="电源电压" value={voltage} onChange={setVoltage} min={1} max={12} step={0.5} unit=" V" />
          <ControlSlider label="灯泡电阻" value={bulbR} onChange={setBulbR} min={2} max={20} step={1} unit=" Ω" />
        </div>
        <div className="panel-section">
          <ControlToggle label="闭合开关" checked={isOn} onChange={setIsOn} />
        </div>
      </>
    );
    if (tab === 'data') return (
      <>
        <div className="meter-row">
          <MeterCard label="电流 I" value={current.toFixed(3)} unit=" A" />
          <MeterCard label="灯泡电压" value={bulbVoltage.toFixed(2)} unit=" V" />
        </div>
        <div className="meter-row">
          <MeterCard label="灯泡功率" value={bulbPower.toFixed(2)} unit=" W" sub={brightness > 0.7 ? '很亮' : brightness > 0.3 ? '正常' : '暗'} />
          <MeterCard label="总电阻" value={totalR.toFixed(1)} unit=" Ω" />
        </div>
        <FormulaBox
          expr="滑动变阻器：改变电阻，从而改变电流"
          subs={[
            `滑动变阻器接入：<span class="val">${resistance} Ω</span>`,
            `总电阻 R = ${resistance} + ${bulbR} = <span class="val">${totalR} Ω</span>`,
            `电流 I = U/R = ${voltage}/${totalR} = <span class="val">${current.toFixed(3)} A</span>`,
            `电阻越大 → 电流越小 → 灯泡越暗`,
            `电阻越小 → 电流越大 → 灯泡越亮`,
          ]}
        />
      </>
    );
    if (tab === 'principle') return (
      <ExplainBox title="滑动变阻器">
        <p><strong>原理：</strong>通过改变接入电路中电阻丝的长度来改变电阻。</p>
        <p style={{marginTop:6}}><strong>构造：</strong>瓷筒、电阻丝、滑片、金属杆、接线柱。</p>
        <p style={{marginTop:6}}><strong>使用方法：</strong>"一上一下"接线。</p>
        <p>• 接上面两个：电阻为0（相当于导线）</p>
        <p>• 接下面两个：电阻最大且不变</p>
        <p>• 一上一下：可改变电阻</p>
        <p style={{marginTop:6}}><strong>作用：</strong></p>
        <p>• 改变电路中的电流</p>
        <p>• 改变用电器两端的电压</p>
        <p>• 保护电路</p>
        <p style={{marginTop:6}}>闭合开关前，滑片应置于最大阻值处。</p>
      </ExplainBox>
    );
  };

  // Rheostat visual
  const rheoX = 250, rheoY = 180;
  const rheoW = 200, rheoH = 60;

  return (
    <ExperimentShell category={category} name={name} catColor={catColor}
      panelTabs={panelTabs} panelContent={panelContent}>
      <div className="sim-canvas-wrap">
        <svg width={canvasW} height={canvasH} className="sim-canvas paper-bg">

          {/* circuit loop */}
          <path d="M 80 250 L 80 120 L 200 120 L 200 180"
            fill="none" stroke={isOn ? '#F5D547' : '#999'} strokeWidth="2.5" />
          <path d="M 500 180 L 500 120 L 580 120 L 580 280 L 80 280 L 80 270"
            fill="none" stroke={isOn ? '#F5D547' : '#999'} strokeWidth="2.5" />

          {/* battery */}
          <g transform="translate(80, 260)">
            <line x1="0" y1="-10" x2="0" y2="10" stroke="#333" strokeWidth="4" />
            <line x1="-5" y1="-7" x2="5" y2="-7" stroke="#333" strokeWidth="3" />
            <text x="-10" y="-14" fill="#FF3B30" fontSize="9">+</text>
            <text x="10" y="3" fill="#5E3A18" fontSize="10">{voltage}V</text>
          </g>

          {/* switch */}
          <g transform="translate(140, 120)">
            <circle cx="0" cy="0" r="4" fill="#333" />
            <circle cx="25" cy="0" r="4" fill="#333" />
            {isOn ? (
              <line x1="0" y1="0" x2="25" y2="0" stroke="#333" strokeWidth="2.5" />
            ) : (
              <line x1="0" y1="0" x2="22" y2="-15" stroke="#333" strokeWidth="2.5" />
            )}
          </g>

          {/* sliding rheostat */}
          <g transform={`translate(${rheoX}, ${rheoY})`}>
            {/* ceramic tube */}
            <rect x="0" y="20" width={rheoW} height="25" fill="#ddd" stroke="#888" strokeWidth="1.5" rx="3" />

            {/* resistance wire winding (visual) */}
            {Array.from({length: 20}, (_, i) => (
              <line key={i}
                x1={i * 10 + 5} y1="18"
                x2={i * 10 + 10} y2="44"
                stroke="#B87333" strokeWidth="2" />
            ))}

            {/* metal bar on top */}
            <rect x="10" y="0" width={rheoW - 20} height="6" fill="#c0c0c0" stroke="#888" strokeWidth="1" rx="2" />

            {/* slider */}
            <g transform={`translate(${sliderPos * (rheoW - 40) + 10}, 0)`}>
              <rect x="-12" y="-4" width="24" height="14" fill="#888" stroke="#555" strokeWidth="1" rx="2" />
              <line x1="0" y1="10" x2="0" y2="22" stroke="#555" strokeWidth="2" />
              <polygon points="-6,22 6,22 0,30" fill="#555" />
              <text x="0" y="-8" textAnchor="middle" fill="#333" fontSize="9">滑片</text>
            </g>

            {/* terminals */}
            <circle cx="0" cy="32" r="5" fill="#666" stroke="#333" strokeWidth="1" />
            <circle cx={rheoW} cy="32" r="5" fill="#666" stroke="#333" strokeWidth="1" />
            <circle cx="10" cy="3" r="4" fill="#c0c0c0" stroke="#888" strokeWidth="1" />

            {/* labels */}
            <text x={rheoW/2} y="60" textAnchor="middle" fill="#5E3A18" fontSize="11">
              滑动变阻器（接入 {resistance.toFixed(1)}Ω）
            </text>
          </g>

          {/* wires to rheostat */}
          <line x1="200" y1="180" x2={rheoX} y2={rheoY + 32}
            stroke={isOn ? '#F5D547' : '#999'} strokeWidth="2.5" />
          <line x1={rheoX + rheoW} y1={rheoY + 32} x2={500} y2={rheoY + 32}
            stroke={isOn ? '#F5D547' : '#999'} strokeWidth="2.5" />
          <line x1="500" y1={rheoY + 32} x2="500" y2="120"
            stroke={isOn ? '#F5D547' : '#999'} strokeWidth="2.5" />

          {/* bulb */}
          <g transform="translate(540, 200)">
            <circle cx="0" cy="0" r="24"
              fill={isOn ? `rgba(255,235,153,${0.4 + brightness * 0.6})` : '#f0f0f0'}
              stroke="#333" strokeWidth="2" />
            <path d="M -12 6 Q -6 -12 0 6 Q 6 -12 12 6" fill="none"
              stroke={isOn ? '#FF6B3D' : '#999'} strokeWidth="1.5" />
            {/* glow */}
            {isOn && brightness > 0.1 && (
              <circle cx="0" cy="0" r={28 + brightness * 15}
                fill="#FFEB99" opacity={brightness * 0.3}>
                <animate attributeName="r" values={`${28 + brightness*10};${32 + brightness*15};${28 + brightness*10}`} dur="2s" repeatCount="indefinite" />
              </circle>
            )}
            <text x="0" y="45" textAnchor="middle" fill="#5E3A18" fontSize="10">
              {bulbPower.toFixed(2)}W
            </text>
          </g>

          {/* ammeter */}
          <g transform="translate(200, 280)">
            <circle cx="0" cy="0" r="18" fill="#fff" stroke="#333" strokeWidth="2" />
            <text x="0" y="4" textAnchor="middle" fontSize="11" fill="#333" fontWeight="bold">A</text>
            <text x="0" y="30" textAnchor="middle" fill="#52C795" fontSize="10">{current.toFixed(3)}A</text>
          </g>

          <text x={canvasW/2} y="40" textAnchor="middle" fill="#5E3A18" fontSize="13" fontWeight="bold">
            滑动变阻器改变灯泡亮度
          </text>
        </svg>
      </div>
    </ExperimentShell>
  );
}

// ---------- 5. Electric Power ----------
function ElectricPowerExp({ category, name, catColor }) {
  const [U_real, setU_real] = useState(2.5); // V (actual voltage)
  const [U_rated, setU_rated] = useState(2.5); // V (rated voltage)
  const [R, setR] = useState(10); // Ω
  const [isOn, setIsOn] = useState(false);

  const I_real = isOn ? U_real / R : 0;
  const P_real = U_real * I_real;
  const P_rated = (U_rated * U_rated) / R;
  const I_rated = U_rated / R;

  const brightnessRatio = P_real / P_rated;
  const brightness = Math.min(1, Math.max(0, brightnessRatio));

  const state = U_real > U_rated * 1.1 ? '过亮（过压）'
    : Math.abs(U_real - U_rated) < U_rated * 0.1 ? '正常发光'
    : U_real > 0 ? '偏暗（欠压）'
    : '未通电';

  const canvasW = 620, canvasH = 400;

  const panelTabs = [
    { id: 'controls', label: '操作' },
    { id: 'data', label: '数据/公式' },
    { id: 'principle', label: '原理' },
  ];

  const panelContent = (tab) => {
    if (tab === 'controls') return (
      <>
        <div className="panel-section">
          <div className="panel-section-title">参数调节</div>
          <ControlSlider label="实际电压 U" value={U_real} onChange={setU_real} min={0} max={5} step={0.1} unit=" V" />
          <ControlSlider label="额定电压 U额" value={U_rated} onChange={setU_rated} min={1.5} max={4} step={0.1} unit=" V" />
          <ControlSlider label="灯丝电阻 R" value={R} onChange={setR} min={5} max={20} step={0.5} unit=" Ω" />
        </div>
        <div className="panel-section">
          <ControlToggle label="闭合开关" checked={isOn} onChange={setIsOn} />
          <div className="btn-row" style={{ marginTop: 10 }}>
            <button className="btn sm" onClick={() => setU_real(U_rated)}>额定电压</button>
            <button className="btn sm" onClick={() => setU_real(U_rated * 1.2)}>1.2倍U额</button>
            <button className="btn sm" onClick={() => setU_real(U_rated * 0.8)}>0.8倍U额</button>
          </div>
        </div>
      </>
    );
    if (tab === 'data') return (
      <>
        <div className="meter-row">
          <MeterCard label="实际电压" value={U_real.toFixed(2)} unit=" V"
            sub={`额定 ${U_rated}V`} />
          <MeterCard label="实际功率" value={P_real.toFixed(3)} unit=" W"
            sub={state} />
        </div>
        <div className="meter-row">
          <MeterCard label="额定功率" value={P_rated.toFixed(3)} unit=" W"
            sub={`I额=${I_rated.toFixed(2)}A`} />
          <MeterCard label="亮度" value={(brightnessRatio * 100).toFixed(0)} unit=" %"
            sub={brightnessRatio > 1.1 ? '过亮' : brightnessRatio < 0.5 ? '暗' : '正常'} />
        </div>
        <FormulaBox
          expr="P = U · I = U² / R"
          subs={[
            `额定电压 U额 = <span class="val">${U_rated} V</span>`,
            `额定功率 P额 = U额²/R = ${U_rated}²/${R} = <span class="val">${P_rated.toFixed(3)} W</span>`,
            `实际电压 U实 = <span class="val">${U_real} V</span>`,
            `实际功率 P实 = U实²/R = ${U_real.toFixed(2)}²/${R} = <span class="val">${P_real.toFixed(3)} W</span>`,
            `亮度由实际功率决定：P实/P额 = ${(brightnessRatio*100).toFixed(0)}%`,
            brightnessRatio > 1.1
              ? `<span style="color:#111114">U实 > U额，P实 > P额，灯泡过亮，易烧坏</span>`
              : brightnessRatio < 0.9
                ? `<span style="color:#111114">U实 < U额，P实 < P额，灯泡偏暗</span>`
                : `<span style="color:#111114">正常发光</span>`,
          ]}
        />
      </>
    );
    if (tab === 'principle') return (
      <ExplainBox title="电功率">
        <p><strong>电功率：</strong>电流在单位时间内所做的功，表示电流做功的快慢。</p>
        <p style={{textAlign:'center', fontSize: 16, fontWeight: 'bold', color: 'var(--accent)', margin: '8px 0'}}>
          P = W / t = UI
        </p>
        <p><strong>单位：</strong>瓦(W)、千瓦(kW)</p>
        <p style={{marginTop:6}}><strong>额定电压：</strong>用电器正常工作时的电压。</p>
        <p><strong>额定功率：</strong>用电器在额定电压下的功率。</p>
        <p style={{marginTop:6}}><strong>实际功率：</strong>用电器在实际电压下的功率。</p>
        <p>• U实 = U额 → P实 = P额 → 正常发光</p>
        <p>• U实 {'>'} U额 → P实 {'>'} P额 → 灯更亮（易烧坏）</p>
        <p>• U实 {'<'} U额 → P实 {'<'} P额 → 灯较暗</p>
        <p style={{marginTop:6}}>灯泡的亮度由实际功率决定。</p>
      </ExplainBox>
    );
  };

  return (
    <ExperimentShell category={category} name={name} catColor={catColor}
      panelTabs={panelTabs} panelContent={panelContent}>
      <div className="sim-canvas-wrap">
        <svg width={canvasW} height={canvasH} className="sim-canvas paper-bg">
          {/* simple circuit: battery, switch, bulb, voltmeter, ammeter */}
          <path d="M 100 250 L 100 120 L 520 120 L 520 280 L 100 280 L 100 270"
            fill="none" stroke={isOn ? '#F5D547' : '#999'} strokeWidth="2.5" />

          {/* battery */}
          <g transform="translate(100, 260)">
            <line x1="0" y1="-10" x2="0" y2="10" stroke="#333" strokeWidth="4" />
            <line x1="-5" y1="-7" x2="5" y2="-7" stroke="#333" strokeWidth="3" />
            <text x="-12" y="-14" fill="#FF3B30" fontSize="9">+</text>
            <text x="10" y="3" fill="#5E3A18" fontSize="10">{U_real.toFixed(1)}V</text>
          </g>

          {/* switch */}
          <g transform="translate(180, 120)">
            <circle cx="0" cy="0" r="4" fill="#333" />
            <circle cx="30" cy="0" r="4" fill="#333" />
            {isOn ? (
              <line x1="0" y1="0" x2="30" y2="0" stroke="#333" strokeWidth="2.5" />
            ) : (
              <line x1="0" y1="0" x2="26" y2="-18" stroke="#333" strokeWidth="2.5" />
            )}
            <text x="15" y="-12" textAnchor="middle" fill="#5E3A18" fontSize="9">S</text>
          </g>

          {/* ammeter */}
          <g transform="translate(260, 120)">
            <circle cx="0" cy="0" r="20" fill="#fff" stroke="#333" strokeWidth="2" />
            <text x="0" y="4" textAnchor="middle" fontSize="11" fill="#333" fontWeight="bold">A</text>
          </g>

          {/* bulb */}
          <g transform="translate(400, 120)">
            <circle cx="0" cy="0" r="28"
              fill={isOn ? `rgba(255,235,153,${0.3 + brightness * 0.7})` : '#f0f0f0'}
              stroke="#333" strokeWidth="2" />
            {/* filament */}
            <path d="M -14 8 Q -7 -16 0 8 Q 7 -16 14 8" fill="none"
              stroke={isOn ? '#FF6B3D' : '#999'} strokeWidth="1.5" />
            {/* glow */}
            {isOn && brightness > 0.05 && (
              <circle cx="0" cy="0" r={30 + brightness * 20}
                fill="#FFEB99" opacity={brightness * 0.4}>
                <animate attributeName="r" values={`${30+brightness*15};${35+brightness*20};${30+brightness*15}`} dur="1.5s" repeatCount="indefinite" />
              </circle>
            )}
            <text x="0" y="-35" textAnchor="middle" fill="#5E3A18" fontSize="10">
              额定 {U_rated}V / {P_rated.toFixed(2)}W
            </text>
          </g>

          {/* voltmeter (parallel across bulb) */}
          <line x1="370" y1="120" x2="370" y2="70" stroke={isOn ? '#F5D547' : '#999'} strokeWidth="2" />
          <line x1="430" y1="120" x2="430" y2="70" stroke={isOn ? '#F5D547' : '#999'} strokeWidth="2" />
          <g transform="translate(400, 70)">
            <circle cx="0" cy="0" r="22" fill="#fff" stroke="#333" strokeWidth="2" />
            <text x="0" y="4" textAnchor="middle" fontSize="11" fill="#333" fontWeight="bold">V</text>
          </g>

          {/* readings panel */}
          <g transform="translate(80, 320)">
            <rect x="0" y="0" width="460" height="60" rx="8" fill="#141416" stroke="#333" strokeWidth="1" />
            <text x="20" y="22" fill="#8FA3BD" fontSize="10">电压 U</text>
            <text x="20" y="45" fill={catColor} fontSize="18" fontWeight="bold" fontFamily="JetBrains Mono, monospace">
              {U_real.toFixed(2)} V
            </text>
            <text x="130" y="22" fill="#8FA3BD" fontSize="10">电流 I</text>
            <text x="130" y="45" fill="#52C795" fontSize="18" fontWeight="bold" fontFamily="JetBrains Mono, monospace">
              {I_real.toFixed(3)} A
            </text>
            <text x="260" y="22" fill="#8FA3BD" fontSize="10">实际功率 P</text>
            <text x="260" y="45" fill="#FF6B3D" fontSize="18" fontWeight="bold" fontFamily="JetBrains Mono, monospace">
              {P_real.toFixed(3)} W
            </text>
            <text x="400" y="22" fill="#8FA3BD" fontSize="10">额定功率</text>
            <text x="400" y="45" fill="#FFB84D" fontSize="18" fontWeight="bold" fontFamily="JetBrains Mono, monospace">
              {P_rated.toFixed(2)} W
            </text>
          </g>

          <text x={canvasW/2} y="30" textAnchor="middle" fill="#5E3A18" fontSize="13" fontWeight="bold">
            测量小灯泡的电功率
          </text>
        </svg>
      </div>
    </ExperimentShell>
  );
}

Object.assign(window, {
  SimpleCircuitExp,
  OhmsLawExp,
  SeriesParallelExp,
  RheostatExp,
  ElectricPowerExp,
});
