PNG written: artifacts\spectrogram_qpsk_01.png
window: samples 0…32768 (0.0005…0.0315 s), nfft=1024

--- reference tone (+100 kHz) ---
  matplotlib (full resolution): peak +100.000 kHz  (bin 1000 Hz)
  terminal (pooled)          : peak row +96.0 kHz  (row height ~21.3 kHz)
  OK: the full-resolution peak is at +100 kHz (within one bin)
  OK: the terminal peak row contains +100 kHz

--- burst time spans ---
  qpsk: annotation 0.0030…0.0230 s  (-323.2…-236.8 kHz)
      matplotlib measurement: 0.0035…0.0225 s  (diff +0.5 / -0.5 ms)
      terminal measurement  : 0.0030…0.0225 s
      OK: within the 5 ms tolerance

--- power curve step edges vs annotation ---
  annotation           : 0.00300…0.02300 s
  expected offset      : +325.3 / -325.3 samples - the half-power point of the 512-sample Hann ramp
  block=512  (drawn curve): 0.00337…0.02263 s  diff +0.366 / -0.365 ms  (+374 / -374 samples)
  block=32   (fine grid): 0.00333…0.02266 s  diff +0.333 / -0.338 ms  (+341 / -346 samples)
  block grid effect    : 34 / 28 samples - a 512-sample block squeezes the 512-sample ramp into one block and pushes the edge outwards
  OK: on the fine grid the offset converges on the ramp's half-power point;
      what remains is block grid resolution, not a systematic error

RESULT: every check passed
