function PositionBar({ processIndex, process, stage, previous, next }) {
  const progress = ((processIndex + 1) / PCB_PROCESSES.length) * 100;
  return (
    <section className="position-bar" aria-label="현재 공정 위치">
      <div className="position-copy">
        <span className="position-count">현재 {String(processIndex + 1).padStart(2, "0")} / 12</span>
        <span className="position-divider">›</span>
        <span className="position-phase">{process.phase}</span>
        <span className="position-divider">›</span>
        <strong>{process.title}</strong>
        {stage !== process && (
          <>
            <span className="position-divider">›</span>
            <strong className="position-substage">{stage.step} {stage.title}</strong>
          </>
        )}
      </div>
      <div className="position-neighbors">
        <span>이전 <b>{previous.title}</b></span>
        <span>다음 <b>{next.title}</b></span>
      </div>
      <div className="position-progress" aria-hidden="true"><i style={{ width: `${progress}%` }}></i></div>
    </section>
  );
}

function ProcessRail({ processIndex, setProcessIndex }) {
  return (
    <nav className="process-rail" aria-label="PCB 전체 공정 위치">
      {PCB_PROCESSES.map((process, index) => (
        <button
          key={process.id}
          type="button"
          data-process-index={index}
          className={`rail-item phase-${process.phaseNo.toLowerCase()} ${index === processIndex ? "is-active" : ""}`}
          onClick={() => setProcessIndex(index)}
          aria-current={index === processIndex ? "step" : undefined}
          aria-label={`${process.step} ${process.title}: ${process.navHint}`}
        >
          <span className="rail-number">{process.step}</span>
          <strong className="rail-name">{process.title}</strong>
          <span className="rail-purpose">{process.navHint}</span>
        </button>
      ))}
    </nav>
  );
}

function SubProcessRail({ subStages, subIndex, setSubIndex }) {
  return (
    <nav className="subprocess-rail" aria-label="도금 세부 공정">
      <div className="subprocess-intro">
        <span className="micro-label">06 도금 안쪽 보기</span>
        <strong>구멍이 전기길이 되는 순서</strong>
      </div>
      <div className="subprocess-buttons">
        {subStages.map((subStage, index) => (
          <button
            key={subStage.id}
            type="button"
            className={index === subIndex ? "active" : ""}
            aria-current={index === subIndex ? "step" : undefined}
            onClick={() => setSubIndex(index)}
          >
            <span>{subStage.step}</span>
            <strong>{subStage.title}</strong>
            <small>{subStage.navHint}</small>
          </button>
        ))}
      </div>
    </nav>
  );
}

function LaminationCrossSection({ defectMode }) {
  const layerRows = [104, 139, 174, 209, 244, 279];
  return (
    <g>
      <text x="450" y="35" textAnchor="middle" className="micro">LAY-UP → VACUUM → HEAT → PRESSURE → CURE</text>
      <g>
        <path className="press-arrow" d="M300 49 h24 v20 h14 l-26 28 -26-28 h14z"></path>
        <path className="press-arrow" d="M438 49 h24 v20 h14 l-26 28 -26-28 h14z"></path>
        <path className="press-arrow" d="M576 49 h24 v20 h14 l-26 28 -26-28 h14z"></path>
      </g>
      <rect x="177" y="86" width="546" height="224" rx="5" className="board-edge"></rect>
      {layerRows.map((y, index) => (
        <g key={y}>
          {index < layerRows.length - 1 && (
            <rect x="185" y={y + 7} width="530" height="22" rx="2" className="prepreg"></rect>
          )}
          <rect x="185" y={y} width="530" height="7" className="copper-layer"></rect>
        </g>
      ))}
      {defectMode && (
        <g>
          <ellipse cx="548" cy="194" rx="42" ry="14" fill="var(--paper-2)" stroke="var(--danger)" strokeWidth="3"></ellipse>
          <path d="M282 241 C330 232 360 252 408 242" className="danger-line"></path>
          <path d="M548 179 L640 133" className="leader" style={{ stroke: "var(--danger)" }}></path>
          <text x="648" y="130" className="label" style={{ fill: "var(--danger)" }}>보이드</text>
          <text x="648" y="149" className="micro" style={{ fill: "var(--danger)" }}>AIR / CONTAMINATION</text>
          <path d="M340 245 L238 337" className="leader" style={{ stroke: "var(--danger)" }}></path>
          <text x="225" y="345" textAnchor="end" className="label" style={{ fill: "var(--danger)" }}>국부 박리</text>
        </g>
      )}
      {!defectMode && (
        <g>
          <path d="M190 182 L105 145" className="leader"></path>
          <text x="96" y="141" textAnchor="end" className="label">프리프레그</text>
          <text x="96" y="158" textAnchor="end" className="micro">FLOW + INSULATE</text>
          <path d="M714 141 L792 115" className="leader"></path>
          <text x="802" y="112" className="label">내층 회로</text>
          <text x="802" y="129" className="micro">FIXED POSITION</text>
        </g>
      )}
      <text x="450" y="345" textAnchor="middle" className="label">낱장들이 되돌리기 어려운 하나의 다층판으로 고정</text>
      <text x="450" y="370" textAnchor="middle" className="micro">CORE + PREPREG + COPPER FOIL</text>
    </g>
  );
}

function BoardBase({ holeX, showHole }) {
  const layers = [112, 149, 186, 223, 260, 297];
  return (
    <g>
      <rect x="178" y="92" width="544" height="226" rx="5" className="board-body"></rect>
      <rect x="178" y="92" width="544" height="226" rx="5" className="board-edge"></rect>
      {layers.map((y) => <rect key={y} x="178" y={y} width="544" height="7" className="copper-layer"></rect>)}
      {showHole && <rect x={holeX} y="92" width="76" height="226" className="hole"></rect>}
      <text x="145" y="116" textAnchor="end" className="micro">L1</text>
      <text x="145" y="190" textAnchor="end" className="micro">L3</text>
      <text x="145" y="264" textAnchor="end" className="micro">L5</text>
    </g>
  );
}

function DrillCrossSection({ defectMode }) {
  const holeX = defectMode ? 505 : 412;
  return (
    <g>
      <text x="450" y="35" textAnchor="middle" className="micro">MECHANICAL HOLE — NOT YET CONDUCTIVE</text>
      <BoardBase holeX={holeX} showHole={true}></BoardBase>
      <g className="drill-bit" transform={`translate(${holeX + 38} 0)`}>
        <path d="M-25 25 h50 l-9 53 -16 22 -16-22z"></path>
        <path d="M-14 37 L14 65 M-16 56 L12 84" fill="none" stroke="var(--paper-2)" strokeWidth="2"></path>
      </g>
      <rect x={holeX - 10} y="102" width="96" height="17" rx="8" className="pad"></rect>
      <rect x={holeX - 10} y="176" width="96" height="17" rx="8" className="pad"></rect>
      <rect x={holeX} y="92" width="76" height="226" className="hole"></rect>
      <g>
        <rect x={holeX - 2} y="146" width="8" height="17" rx="3" className="danger-mark" opacity="0.8"></rect>
        <rect x={holeX + 70} y="218" width="8" height="15" rx="3" className="danger-mark" opacity="0.8"></rect>
        <text x="802" y="215" className="label" style={{ fill: defectMode ? "var(--danger)" : "var(--sub)" }}>{defectMode ? "패드 중심 이탈" : "홀 벽 스미어"}</text>
        <path d={`M${holeX + 76} 224 L790 219`} className="leader" style={{ stroke: defectMode ? "var(--danger)" : "var(--faint)" }}></path>
      </g>
      {defectMode ? (
        <g>
          <path d={`M${holeX - 3} 109 q-34 0 -50 -18`} className="danger-line"></path>
          <circle cx={holeX + 38} cy="184" r="59" className="pulse-ring" style={{ stroke: "var(--danger)" }}></circle>
          <text x="92" y="335" className="label" style={{ fill: "var(--danger)" }}>브레이크아웃</text>
          <text x="92" y="354" className="micro" style={{ fill: "var(--danger)" }}>REGISTRATION ERROR</text>
        </g>
      ) : (
        <g>
          <path d={`M${holeX + 38} 318 L${holeX + 38} 358`} className="leader"></path>
          <text x={holeX + 38} y="382" textAnchor="middle" className="label">빈 통로만 생성</text>
          <text x={holeX + 38} y="399" textAnchor="middle" className="micro">NO COPPER BARREL YET</text>
        </g>
      )}
    </g>
  );
}

function DesmearCrossSection({ defectMode }) {
  const holeX = 412;
  return (
    <g>
      <text x="450" y="35" textAnchor="middle" className="micro">REMOVE RESIN SMEAR — EXPOSE INNER-LAYER COPPER</text>
      <BoardBase holeX={holeX} showHole={true}></BoardBase>
      <rect x={holeX - 10} y="176" width="96" height="17" rx="8" className="pad"></rect>
      <rect x={holeX} y="92" width="76" height="226" className="hole"></rect>
      <path d={`M${holeX + 18} 103 v200 M${holeX + 58} 103 v200`} className="chem-stroke"></path>
      {!defectMode && (
        <g>
          <circle cx={holeX + 8} cy="160" r="4" className="particle"></circle>
          <circle cx={holeX + 64} cy="227" r="3" className="particle" style={{ animationDelay: "0.45s" }}></circle>
          <circle cx={holeX + 10} cy="268" r="3" className="particle" style={{ animationDelay: "0.9s" }}></circle>
          <path d={`M${holeX} 184 L305 150`} className="leader"></path>
          <text x="293" y="144" textAnchor="end" className="label">내층 구리 노출</text>
          <text x="293" y="162" textAnchor="end" className="micro">CLEAN CONTACT</text>
        </g>
      )}
      {defectMode && (
        <g>
          <rect x={holeX - 2} y="171" width="15" height="27" rx="4" className="danger-mark"></rect>
          <rect x={holeX + 61} y="249" width="17" height="24" rx="4" className="danger-mark"></rect>
          <circle cx={holeX + 5} cy="184" r="34" className="pulse-ring" style={{ stroke: "var(--danger)" }}></circle>
          <path d={`M${holeX + 4} 184 L742 140`} className="leader" style={{ stroke: "var(--danger)" }}></path>
          <text x="752" y="137" className="label" style={{ fill: "var(--danger)" }}>스미어 잔류</text>
          <text x="752" y="155" className="micro" style={{ fill: "var(--danger)" }}>CONTACT BLOCKED</text>
        </g>
      )}
      <text x="450" y="368" textAnchor="middle" className="label">청소의 목적은 ‘예쁘게’가 아니라 기존 구리 접점을 다시 드러내는 것</text>
    </g>
  );
}

function ElectrolessCrossSection({ defectMode }) {
  const x = 412;
  return (
    <g>
      <text x="450" y="35" textAnchor="middle" className="micro">CHEMICAL DEPOSITION — THIN CONTINUOUS SEED LAYER</text>
      <BoardBase holeX={x} showHole={true}></BoardBase>
      <rect x={x - 10} y="176" width="96" height="17" rx="8" className="pad"></rect>
      <rect x={x} y="92" width="76" height="226" className="hole"></rect>
      <rect x={x} y="92" width="5" height="226" className="seed"></rect>
      {defectMode ? (
        <g>
          <rect x={x + 71} y="92" width="5" height="73" className="seed"></rect>
          <rect x={x + 71} y="223" width="5" height="95" className="seed"></rect>
          <path d={`M${x + 73} 167 L${x + 73} 221`} className="danger-line"></path>
          <circle cx={x + 73} cy="194" r="31" className="pulse-ring" style={{ stroke: "var(--danger)" }}></circle>
          <path d={`M${x + 75} 194 L746 153`} className="leader" style={{ stroke: "var(--danger)" }}></path>
          <text x="756" y="148" className="label" style={{ fill: "var(--danger)" }}>씨앗층 단절</text>
          <text x="756" y="166" className="micro" style={{ fill: "var(--danger)" }}>SKIP PLATING</text>
        </g>
      ) : (
        <g>
          <rect x={x + 71} y="92" width="5" height="226" className="seed"></rect>
          <path d={`M${x + 76} 124 L748 102`} className="leader"></path>
          <text x="758" y="99" className="label">얇고 연속적인 씨앗층</text>
          <text x="758" y="117" className="micro">CONDUCTIVE PATH</text>
        </g>
      )}
      <rect x={x + 5} y="92" width="66" height="226" className="hole"></rect>
      <circle cx={x + 38} cy="205" r="65" className="pulse-ring"></circle>
      <path d={`M${x + 2} 272 L250 320`} className="leader"></path>
      <text x="240" y="320" textAnchor="end" className="label">전기 없이 화학 반응</text>
      <text x="240" y="338" textAnchor="end" className="micro">SEED, NOT FINAL THICKNESS</text>
    </g>
  );
}

function ElectrolyticCrossSection({ defectMode }) {
  const x = 412;
  return (
    <g>
      <text x="450" y="35" textAnchor="middle" className="micro">CURRENT-DRIVEN COPPER GROWTH — FUNCTIONAL BARREL</text>
      <BoardBase holeX={x} showHole={true}></BoardBase>
      <rect x={x - 10} y="176" width="96" height="17" rx="8" className="pad"></rect>
      <rect x={x} y="92" width="76" height="226" className="hole"></rect>
      <rect x={x} y="92" width="16" height="226" className="plated"></rect>
      {defectMode ? (
        <g>
          <rect x={x + 60} y="92" width="16" height="70" className="plated"></rect>
          <rect x={x + 69} y="162" width="7" height="88" className="plated"></rect>
          <rect x={x + 60} y="250" width="16" height="68" className="plated"></rect>
          <path d={`M${x + 67} 175 q-22 28 0 57`} className="danger-line"></path>
          <path d={`M${x + 70} 205 L744 150`} className="leader" style={{ stroke: "var(--danger)" }}></path>
          <text x="754" y="146" className="label" style={{ fill: "var(--danger)" }}>홀 중앙 박막</text>
          <text x="754" y="164" className="micro" style={{ fill: "var(--danger)" }}>THIN CENTER BARREL</text>
        </g>
      ) : (
        <g>
          <rect x={x + 60} y="92" width="16" height="226" className="plated"></rect>
          <path d={`M${x + 76} 205 L748 166`} className="leader"></path>
          <text x="758" y="162" className="label">기능 두께로 성장</text>
          <text x="758" y="180" className="micro">CHECK THE HOLE CENTER</text>
        </g>
      )}
      <rect x={x + 16} y="92" width={defectMode ? 53 : 44} height="226" className="hole"></rect>
      <path d={`M${x + 38} 329 L${x + 38} 365`} className="leader"></path>
      <text x={x + 38} y="388" textAnchor="middle" className="label">층간 전기 통로 완성</text>
      <text x="228" y="162" textAnchor="end" className="label">표면 두께 ≠ 홀 중앙 두께</text>
      <text x="228" y="180" textAnchor="end" className="micro">HIGH ASPECT RATIO RISK</text>
      <path d={`M240 172 L${x + 3} 204`} className="leader"></path>
    </g>
  );
}

function HPLCrossSection({ defectMode }) {
  const x = 412;
  return (
    <g>
      <text x="450" y="35" textAnchor="middle" className="micro">FILL → PLANARIZE → BUILD LAND / PAD ABOVE</text>
      <BoardBase holeX={x} showHole={true}></BoardBase>
      <rect x={x} y="92" width="16" height="226" className="plated"></rect>
      <rect x={x + 60} y="92" width="16" height="226" className="plated"></rect>
      <rect x={x + 16} y="92" width="44" height="226" className="fill-material"></rect>
      <rect x={x - 24} y="84" width="124" height="18" rx="8" className="pad"></rect>
      <rect x={x - 10} y="176" width="96" height="17" rx="8" className="pad"></rect>
      {defectMode && (
        <g>
          <ellipse cx={x + 38} cy="220" rx="18" ry="29" fill="var(--paper-2)" stroke="var(--danger)" strokeWidth="3"></ellipse>
          <path d={`M${x + 17} 95 Q${x + 38} 112 ${x + 59} 95`} fill="var(--paper-2)" stroke="var(--danger)" strokeWidth="2"></path>
          <path d={`M${x + 57} 220 L744 177`} className="leader" style={{ stroke: "var(--danger)" }}></path>
          <text x="754" y="173" className="label" style={{ fill: "var(--danger)" }}>충진 보이드</text>
          <text x="754" y="191" className="micro" style={{ fill: "var(--danger)" }}>VOID + DIMPLE</text>
        </g>
      )}
      {!defectMode && (
        <g>
          <path d={`M${x + 100} 92 L752 116`} className="leader"></path>
          <text x="762" y="112" className="label">상부 랜드/패드</text>
          <text x="762" y="130" className="micro">USE THE SPACE ABOVE VIA</text>
          <path d={`M${x + 38} 215 L250 267`} className="leader"></path>
          <text x="240" y="265" textAnchor="end" className="label">충진 + 평탄화</text>
          <text x="240" y="283" textAnchor="end" className="micro">ROUTE VARIES BY PRODUCT</text>
        </g>
      )}
      <text x="450" y="370" textAnchor="middle" className="label">HPL = Hole Plugging Land · 적층 프레스가 아님</text>
    </g>
  );
}

function CrossSection({ processIndex, platingSubIndex, defectMode }) {
  const process = PCB_PROCESSES[processIndex];
  const platingViews = [
    <DesmearCrossSection defectMode={defectMode}></DesmearCrossSection>,
    <ElectrolessCrossSection defectMode={defectMode}></ElectrolessCrossSection>,
    <ElectrolyticCrossSection defectMode={defectMode}></ElectrolyticCrossSection>,
    <HPLCrossSection defectMode={defectMode}></HPLCrossSection>
  ];
  const processViews = {
    cutting: <CuttingVisual defectMode={defectMode}></CuttingVisual>,
    inner: <InnerCircuitVisual defectMode={defectMode}></InnerCircuitVisual>,
    aoi: <AOIVisual defectMode={defectMode}></AOIVisual>,
    lamination: <LaminationCrossSection defectMode={defectMode}></LaminationCrossSection>,
    drill: <DrillCrossSection defectMode={defectMode}></DrillCrossSection>,
    plating: platingViews[platingSubIndex],
    outer: <OuterCircuitVisual defectMode={defectMode}></OuterCircuitVisual>,
    mask: <MaskVisual defectMode={defectMode}></MaskVisual>,
    finish: <FinishVisual defectMode={defectMode}></FinishVisual>,
    routing: <RoutingVisual defectMode={defectMode}></RoutingVisual>,
    etest: <ETestVisual defectMode={defectMode}></ETestVisual>,
    shipping: <ShippingVisual defectMode={defectMode}></ShippingVisual>
  };
  return (
    <svg className="pcb-svg" viewBox="0 0 900 420" role="img" aria-label={`${process.title} 공정 ${defectMode ? "불량 예시" : "정상 예시"}`}>
      {processViews[process.id]}
    </svg>
  );
}

function StageHeader({ stage }) {
  return (
    <header className="stage-header">
      <div className="stage-number">{stage.step}</div>
      <div>
        <p className="stage-tag">{stage.tag}</p>
        <h1 className="stage-title">{stage.title}<span>{stage.verb}</span></h1>
      </div>
      <p className="stage-change">{stage.change}</p>
    </header>
  );
}

function ExplanationPanel({ stage, defectMode, onDefectMode, depthMode, onDepthMode }) {
  return (
    <aside className="explain-zone" aria-label="공정 설명">
      <div className="mode-strip">
        <div className="segmented" aria-label="정상 불량 비교">
          <button className={!defectMode ? "active" : ""} onClick={() => onDefectMode(false)}>정상</button>
          <button className={`danger ${defectMode ? "active" : ""}`} onClick={() => onDefectMode(true)}>불량</button>
        </div>
        <div className="segmented" aria-label="설명 깊이">
          <button className={depthMode === "quick" ? "active" : ""} onClick={() => onDepthMode("quick")}>10초</button>
          <button className={depthMode === "field" ? "active" : ""} onClick={() => onDepthMode("field")}>현장</button>
        </div>
      </div>
      <div className="explain-stack">
        <section className="definition-block">
          <span className="micro-label">WHAT CHANGES</span>
          <h2>{stage.oneLine}</h2>
          {depthMode === "field" && <p>단면에서 보면: {stage.change}</p>}
        </section>
        <section className="why-chain">
          <span className="panel-label">WHY — 이유 사슬</span>
          {stage.why.map((item, index) => (
            <div className="why-step" key={item}>
              <span className="why-index">{index + 1}</span>
              <span>{item}</span>
            </div>
          ))}
        </section>
        <section className="analogy-block">
          <span className="panel-label">ANALOGY — 기억 비유</span>
          <div className="analogy-title">{stage.analogyTitle}</div>
          <p>{stage.analogy}</p>
        </section>
        <section className="risk-block">
          <span className="panel-label">IF WRONG — 잘못하면</span>
          <p>{stage.risk}</p>
        </section>
      </div>
    </aside>
  );
}

function Playback({ processIndex, setProcessIndex, autoPlay, setAutoPlay }) {
  const previousIndex = (processIndex - 1 + PCB_PROCESSES.length) % PCB_PROCESSES.length;
  const nextIndex = (processIndex + 1) % PCB_PROCESSES.length;
  const previous = () => setProcessIndex(previousIndex);
  const next = () => setProcessIndex(nextIndex);
  return (
    <div className="playback" aria-label="공정 단계 재생">
      <button className="jump-button previous" onClick={previous} aria-label={`이전 공정 ${PCB_PROCESSES[previousIndex].title}`}>
        <span>‹ 이전</span><strong>{PCB_PROCESSES[previousIndex].step} {PCB_PROCESSES[previousIndex].title}</strong>
      </button>
      <button className="step-button primary" onClick={() => setAutoPlay(!autoPlay)} aria-label={autoPlay ? "자동 재생 정지" : "12공정 자동 재생"}>{autoPlay ? "Ⅱ" : "▶"}</button>
      <button className="jump-button next" onClick={next} aria-label={`다음 공정 ${PCB_PROCESSES[nextIndex].title}`}>
        <span>다음 ›</span><strong>{PCB_PROCESSES[nextIndex].step} {PCB_PROCESSES[nextIndex].title}</strong>
      </button>
    </div>
  );
}

function FlowTab({ stage }) {
  return (
    <div className="flow-grid">
      {stage.flow.map((item, index) => (
        <div className="flow-step" key={item}>
          <span className="flow-index">0{index + 1}</span>
          <strong className="flow-name">{item}</strong>
        </div>
      ))}
    </div>
  );
}

function ControlsTab({ stage }) {
  return (
    <div className="control-grid">
      {stage.controls.map(([title, body], index) => (
        <article className="control-card" key={title}>
          <span className="panel-label">CONTROL 0{index + 1}</span>
          <h3>{title}</h3>
          <p>{body}</p>
        </article>
      ))}
    </div>
  );
}

function DefectsTab({ stage }) {
  return (
    <table className="defect-table">
      <thead><tr><th>원인</th><th></th><th>지금 보이는 이상</th><th></th><th>뒤에서 커지는 문제</th></tr></thead>
      <tbody>
        {stage.defects.map(([cause, now, later]) => (
          <tr key={cause}>
            <td>{cause}</td><td className="arrow-cell">→</td><td>{now}</td><td className="arrow-cell">→</td><td>{later}</td>
          </tr>
        ))}
      </tbody>
    </table>
  );
}

function CeoTab({ stage }) {
  return (
    <div className="ceo-grid">
      {stage.ceo.map((question, index) => (
        <article className="ceo-card" key={question}>
          <span className="panel-label">CEO QUESTION 0{index + 1}</span>
          <span className="q-mark">?</span>
          <h3>숫자와 사실로 답받을 질문</h3>
          <p>{question}</p>
        </article>
      ))}
    </div>
  );
}

function QuizTab({ stage }) {
  const [selected, setSelected] = React.useState(null);
  React.useEffect(() => setSelected(null), [stage.id]);
  return (
    <div className="quiz-wrap">
      <section className="quiz-question">
        <span className="panel-label">10-SECOND RECALL</span>
        <h3>{stage.quiz.q}</h3>
      </section>
      <section>
        <div className="quiz-options">
          {stage.quiz.options.map((option, index) => {
            const judged = selected !== null;
            const state = judged && index === stage.quiz.answer ? "correct" : judged && index === selected ? "wrong" : "";
            return <button className={`quiz-option ${state}`} key={option} onClick={() => setSelected(index)}>{index + 1}. {option}</button>;
          })}
        </div>
        {selected !== null && <p className="quiz-feedback">{selected === stage.quiz.answer ? "정답. " : "다시 연결해 보면: "}{stage.quiz.explain}</p>}
      </section>
    </div>
  );
}

function KnowledgeDock({ stage, activeTab, setActiveTab }) {
  const tabs = [["flow", "작업 흐름"], ["controls", "관리 포인트"], ["defects", "불량 전파"], ["ceo", "CEO 질문"], ["quiz", "기억 확인"]];
  return (
    <section className="knowledge-dock" data-screen-label="현장 상세">
      <div className="tab-list" role="tablist">
        {tabs.map(([id, label]) => <button key={id} className={`tab-button ${activeTab === id ? "active" : ""}`} onClick={() => setActiveTab(id)} role="tab">{label}</button>)}
      </div>
      <div className="tab-panel">
        {activeTab === "flow" && <FlowTab stage={stage}></FlowTab>}
        {activeTab === "controls" && <ControlsTab stage={stage}></ControlsTab>}
        {activeTab === "defects" && <DefectsTab stage={stage}></DefectsTab>}
        {activeTab === "ceo" && <CeoTab stage={stage}></CeoTab>}
        {activeTab === "quiz" && <QuizTab stage={stage}></QuizTab>}
      </div>
    </section>
  );
}

Object.assign(window, {
  PositionBar,
  ProcessRail,
  SubProcessRail,
  CrossSection,
  StageHeader,
  ExplanationPanel,
  Playback,
  KnowledgeDock
});
