"""
    plot_pke_results(t, X, U, plant, Q_sg; title="", savepath=nothing)

Four-panel visualization of a closed-loop PKE + T/H simulation result.
Analog of `plant-model/plot_pke_results.m`.  Uses `Plots.jl` with GR
backend (default; no extra dependencies).

Panels:
  (1) Normalized power and Q_sg demand
  (2) Coolant temperatures (T_cold, T_avg, T_hot)
  (3) Fuel temperature
  (4) External reactivity u (in dollars)
"""
function plot_pke_results(t, X, U, plant, Q_sg; title="", savepath=nothing)
    CtoF(T) = T * 9/5 + 32

    n_trace  = X[:, 1]
    T_f      = X[:, 8]
    T_c      = X[:, 9]
    T_cold   = X[:, 10]
    T_hot    = 2 .* T_c .- T_cold

    Q_trace  = [Q_sg(ti) / plant.P0 for ti in t]
    u_dollars = U ./ plant.beta

    p1 = plot(t, n_trace, lw=1.8, label="n (normalized power)",
              xlabel="Time [s]", ylabel="n", legend=:right)
    plot!(p1, t, Q_trace, lw=1.2, ls=:dash,
          label="Q_sg / P_0 (demand)")

    p2 = plot(t, CtoF.(T_cold), lw=1.8, label="T_cold",
              xlabel="Time [s]", ylabel="T [F]", legend=:right)
    plot!(p2, t, CtoF.(T_c),    lw=1.8, label="T_avg")
    plot!(p2, t, CtoF.(T_hot),  lw=1.8, label="T_hot")

    p3 = plot(t, CtoF.(T_f), lw=1.8, label="T_fuel",
              xlabel="Time [s]", ylabel="T [F]", legend=:right)

    p4 = plot(t, u_dollars, lw=1.8, label="u [\$]",
              xlabel="Time [s]", ylabel="Reactivity [\$]", legend=:right)

    fig = plot(p1, p2, p3, p4, layout=(2,2), size=(1100, 700),
               plot_title=title, plot_titlefontsize=11)

    if savepath !== nothing
        savefig(fig, savepath)
    end

    return fig
end
