- Rename "Weather Satellites" sub-tab to "SAT"
- Add "Predictions" view: next 24 h flyby table for 13 ham sats
(ISS, AO-91, AO-92, SO-50, AO-73, JO-97, PO-101, LilacSat-2,
CAS-4B, EO-88, RS-44, SALSAT, GREENCUBE)
- trx-core/geo: add PassPrediction, HAM_SATS, compute_upcoming_passes(),
find_passes_for_sat(), compute_az_el() helpers; spawn_tle_refresh_task
now also fetches CelesTrak amateur group on startup and every 24 h
- trx-frontend-http: add GET /sat_passes endpoint
- app.js: locator tooltips now accumulate all receivers per station
via remotes Set; _detailPassesRigFilter checks the Set
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
Replace flat image list with two switchable views:
- Live: decoder state cards (Idle/Listening), descriptions, latest image
- History: filterable table with columns for time, type, satellite,
channels, lines, and download link. Supports text filter, type filter
(All/APT/LRPT), and sort order (newest/oldest).
https://claude.ai/code/session_01JA13DHuzuHUL4nSBBRU83f
Signed-off-by: Claude <noreply@anthropic.com>
Statistics panels (longest paths, strongest/weakest signals) now respect
all active map filters — source type, rig selector, band, search, and
history. Locator tooltips display which rig received each decoded frame.
https://claude.ai/code/session_01LT7zBnb2kQiYpeTuWNXHsT
Signed-off-by: Claude <noreply@anthropic.com>
Increase sig-strength-display min-width to 7.5rem so the field no longer
resizes when the value switches between two-digit and three-digit numbers.
Reposition the fast BW overlay immediately when bandwidth changes arrive
via SSE, and force-display on bookmark apply so freq+bw render atomically
instead of the BW bars wiggling from a stale intermediate state.
https://claude.ai/code/session_01R2XBFEBL8CrsTx5inu25MA
Signed-off-by: Claude <noreply@anthropic.com>
Add a new "Sig Strength" display field in the freq row that shows
the measured signal strength. Clicking the field cycles through
three units: dBFS (default), dBf, and dBm. The selected unit is
persisted in localStorage.
https://claude.ai/code/session_01EvRV8UgsVtbrcH4t2hmFBF
Signed-off-by: Claude <noreply@anthropic.com>
Estimate Co-Channel Interference (CCI) from pilot tone quadrature
leakage and coherence degradation. Estimate Adjacent Channel
Interference (ACI) from CMA equalizer tap deviation from identity.
Both metrics (0-100 scale) are surfaced through RigFilterState and
displayed as colour-coded bars in the WFM control panel.
The RDS decoder quality parameter is now adaptively penalised when
CCI/ACI levels are elevated, reducing block-error rate under
interference conditions.
https://claude.ai/code/session_016EKzep42RCvE4GxvvRaCwu
Signed-off-by: Claude <noreply@anthropic.com>
The Auto button now toggles between Off and Auto states. Default is Off.
First click sets squelch to noise floor + 6 dB; second click resets to
Open (0%). Button shows active state with green highlight when engaged.
https://claude.ai/code/session_01TDQyrZiPKfWGATVWPsLmHT
Signed-off-by: Claude <noreply@anthropic.com>
Add an "Auto" button next to the SQL slider that sets the squelch
threshold to the current noise floor (estimated from spectrum bins)
plus a 6 dB margin. Uses the existing estimateNoiseFloorDb() heuristic.
https://claude.ai/code/session_01TDQyrZiPKfWGATVWPsLmHT
Signed-off-by: Claude <noreply@anthropic.com>
Remove overkill peak frequency labels from spectrum view. Set waterfall
height to match spectrum height (1:1 split) instead of fixed 120px.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
Add 8 enhancements to the spectrum display:
1. Noise floor reference line — dashed horizontal line at estimated
noise floor (15th-percentile heuristic)
2. Peak frequency labels — top 5 strongest peaks labeled with
frequency text on the spectrum canvas
3. Crosshair lines — vertical + horizontal guide lines follow
cursor on hover for precise frequency/dB reading
4. Zoom indicator + minimap — shows current zoom level (e.g. "4.0x")
and a minimap showing the visible window within the full span
5. dB range control — new Range input alongside Floor, with Auto
button updating both; allows direct control of vertical span
6. Keyboard shortcuts — Arrow Left/Right to pan, +/- to zoom,
0 to reset zoom; documented in hint bar
7. Full waterfall panel — WebGL waterfall canvas below the spectrum
plot, synchronized with zoom/pan, with scroll/click/drag support
8. Signal overlay extended — overlay height now includes waterfall
canvas for consistent BW/bookmark/freq marker coverage
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
Nudge state watch when server_connected goes false so SSE delivers the change. Frontend applies a desaturated frost + banner instead of a blocking overlay, keeping the last-known state visible.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
Press F1 to toggle a help overlay listing available keyboard shortcuts.
Dismiss with F1, Escape, or clicking the backdrop. Refactored the
global keydown handler to route all shortcuts through one listener.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
Radio paths now originate from the rig that decoded the message rather
than the currently selected rig. Bookmark locators no longer draw radio
paths. Rig switch no longer tears down decode pipeline since it is
rig-independent. Mobile spectrum controls use flex-wrap for better layout.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
Add latitude/longitude to /rigs API response. Map now displays receiver
markers for all configured rigs, de-duplicated by location. Decode history
is no longer filtered to the active rig so all remotes contribute to the map.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
Replace synchronous drawSignalOverlay() calls in freq/BW change handlers
with lightweight CSS div elements repositioned via transform: translateX().
This is GPU-composited with zero layout/paint cost, making frequency and
bandwidth changes appear instantaneous. The full WebGL overlay catches up
on the next requestAnimationFrame.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
The .audio-active state was using --accent-green which is actually
orange (#c24b1a). Match the regular play button's hardcoded #00d17f
green so the header button visually matches.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
Bump selector specificity to .header-bar-btn.header-audio-btn so the
padding: 0 rule wins over the generic .header-bar-btn padding, and
switch the SVG to width/height: 100% so it expands to fill the button.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
Rig switch needs the server call so SSE/audio follow the selected rig. Play button now uses a fixed triangle icon sized to match header controls.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
Add checkbox column to bookmark table with select-all support and a
Delete Selected button for batch removal. New POST /bookmarks/batch_delete
API endpoint accepts an array of IDs and removes them in one request.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
Replace the fixed max-height: 360px on FT8/FT4/FT2/WSPR message
containers with flex-based layout so they grow to fill the available
space. Make #content, .tab-panel, and .sub-tab-panel flex containers
that propagate height down the layout chain.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stanislaw Grams <stanislawgrams@gmail.com>
Allow the main frontend card to grow past the previous 1280px cap
on large screens while keeping side gutters for bookmark stacks.
Only widen the desktop layout at 1440px+ and cap it at 1600px so the
main content stays readable with room for side bookmarks.
Co-Authored-By: OpenAI Codex <noreply@openai.com>
Signed-off-by: Stanislaw Grams <stanislawgrams@gmail.com>
Row gap 0.5→0.75rem and label-to-input gap 0.2→0.35rem, scoped
to #sch-entry-form so the bookmark form is unaffected.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: Stanislaw Grams <stanislawgrams@gmail.com>
Replace the inline always-visible add-row with a modal overlay
(same fixed + blurred-backdrop pattern as the bookmark add/edit
form). The "+ Add Entry" button opens the modal; each row now has
Edit and Remove buttons. Edit pre-fills the modal and updates the
entry in-place on save. CSS reuses the existing bookmark modal
selectors rather than duplicating rules.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: Stanislaw Grams <stanislawgrams@gmail.com>
querySelectorAll("span") was picking up the inner .spectrum-bookmark-name
spans added in the previous commit, causing chips[i] to map to the wrong
element during left-position assignment. Switch to :scope > span to
select only direct-child chip spans.
Also revert axis bar from height:auto (which breaks the CSS transition and
collapses the bar) to height:38px with overflow:visible to accommodate
two-line labels while keeping the open/close animation intact.
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: Stanislaw Grams <stanislawgrams@gmail.com>
Suppress stroke-dashoffset animation and drop-shadow filter on all
contact/radio paths when decodeContactPaths.size > 20 by toggling
.map-paths-static on #aprs-map, avoiding per-frame GPU compositing
with large decode histories.
Wrap non-sideStack bookmark chip labels in
<span class="spectrum-bookmark-name"> and allow word-break on axis
chips so long names split across two lines instead of being clipped.
Axis bar switches to min-height so it grows to fit taller chips.
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: Stanislaw Grams <stanislawgrams@gmail.com>
Side-panel chips used white-space: normal + word-break: break-word,
causing names longer than ~16 characters to wrap onto a second line.
Switch to nowrap + overflow: hidden + text-overflow: ellipsis so long
names are clipped cleanly in a single line.
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: Stanislaw Grams <stanislawgrams@gmail.com>
Apply #ft8-messages container style (border, rounded corners, monospace
font, max-height with scroll) to #ft4-messages, #ft2-messages, and
#wspr-messages which were missing it.
Add #ft4-decode-toggle-btn and #ft2-decode-toggle-btn to the narrow-
screen white-space:nowrap media query rule alongside FT8/WSPR.
Cap DOM rows rendered per history view to 200 (FT8_MAX_DOM_ROWS,
FT4_MAX_DOM_ROWS, FT2_MAX_DOM_ROWS). Full history is retained in
memory; only the DOM representation is bounded. This prevents tab
switching from becoming sluggish after a long decode session where
thousands of rows accumulate in the DOM.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
Override the global button chrome on longest-QSO cards so they keep
the intended card layout instead of inheriting fixed control sizing.
Co-authored-by: OpenAI Codex <codex@openai.com>
Signed-off-by: Stan Grams <sjg@haxx.space>