Windowed startup at 50%x70% instead of maximized; overlay legend now
defaults off (it covers the camera image); square slider handles with
grip-line PNG assets (the round handle clipped flat); warmer sunrise
gradient bottom; abr/beam-mark layout tweaks; hover cues on the
beamline-state entries; DPI/font-aware pop-out titlebar icons; the
out-of-date Tutorial menu entries are hidden until content is redone.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The reference table gets a display-only '#' column (like the Dewar
list) with sort indices shifted around it; the sample dock switches to
the Auxiliary puck tab on entering alignment/maintenance states and
back to Dewar elsewhere, only on state transitions so a manual choice
sticks.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Status-bar flags get status_colors(theme) (Mocha variants on Sunset) via
a new set_theme; sample tables stop hard-filling rows WHITE and pin dark
ink on tinted rows via ForegroundRole; dewar tab and log panel get solid
dark surfaces (transparent renders black on the non-composited X11
container); developer help cards go square for the same reason.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
draw_busy_badge in busy_overlay renders the title+subtext pill once;
the sample camera and axis video overlays both delegate to it instead
of keeping diverging copies. The axis panel's dot+label status pill and
its per-theme QSS go away with it.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Banners in the root layout shifted the whole UI on every message; now
they float over the content root (repositioned on resize) and the baton
toast anchors as a compact pill under the camera view, auto-clearing in
4s instead of 10s.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The two tabified bottom docks left their switcher tabs stranded at the
window bottom; one Information dock with proper tabs mirrors the Sample
List dock's layout. LogDock becomes the LogPanel widget with mirror
views for the pop-out and a reveal_requested signal so the owner
controls visibility (Ctrl+Shift+L, notifications).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Diff coverage vs main was 77%, under the 80% CI gate; the new camera
help/error/badge code and the theme+layout main_window paths were the
uncovered bulk. Locally: 82%.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Copied from aare_banner_w.svg; the black glyphs vanished on the dark
splash panel, the white fills read on it.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The diff-vs-main basedpyright gate flags QRect(self._press_geom) because
only _press_global was narrowed; both are set together in
mousePressEvent, so the extra check is a no-op at runtime.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
load_spreadsheet/load_reference_tools log a GET they never send every
~12.5s poll while base_url is None; fix later by demoting to debug or
logging once on the None->set edge.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
A window state saved during the watch-only fold restores as every dock
hidden (the vanished-Sample-List-on-restart bug). Fall back to the
default layout when a restore comes back all-hidden, and put the
pre-watch layout back before saving state in closeEvent.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The controls cheatsheet gets its own help badge/overlay instead of
riding the detection legend; the camera-unavailable state now draws the
actual error reason bottom-center (pushed from MainWindow to all three
camera views); the session badge shows hover feedback and the vacant
overlay reads 'In viewing mode' with a grab-baton hint.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Sunrise/sunset replace the original/portrait tokens (QSettings values
migrate on restore); bluebird is sunrise with a flat sky. The light
palette is repainted with Catppuccin Latte across alerts, chips, cards,
log, splash, inputs, and status flags, plus button/input height caps
and hover rules in the QSS.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Narrow QApplication.instance() before use, wrap the theme QSettings
read in str(), hand QPropertyAnimation a real QByteArray, and declare
the lazily-set watch-mode attributes on the class.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Energy unit moves from spinbox suffix to the label (the suffix ate
field width next to the new spin arrows); samcam exposure/gain get a
3:2 stretch so 3-decimal exposure isn't cut; the Exp. Config. tab bar
gets a BANNER_TAB_GAP spacer under its banner.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Legacy/Portrait themes become Sunrise (default)/Sunset. Automation View
and Portrait (now Playlist) Mode leave the menubar for the View menu
with in-progress labels; Return to Main View stays top-level since it
only shows inside the automation view.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
A transparent top-level renders black on the container's non-composited
X11, so floating docks get a dynamic floating property feeding the
QSS [floating="true"] opaque face, and PopoutWindow sets
WA_StyledBackground. Pop-out titlebar glyphs are now painted in the
palette's WindowText color and re-tint on PaletteChange, so they stay
visible after a theme flip.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Without the baton the GUI now shows only the camera stream and status
bar; every operating surface (panels, docks, pop-out mirrors) is hidden
outright. Regaining the baton restores dock layout via saveState/
restoreState — per-dock visibility snapshots lose docks tabbed behind
others — so LogDock gains the objectName restoreState requires.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Separators stay invisible until the mouse rests on one for ~1s (or a
drag starts); the QSS ::separator:hover rule does the hit-testing and a
dynamic separatorHint property gates it, so event() never needs to know
where separators are.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
QSS cannot set cursors and per-widget setCursor calls get forgotten as
widgets are added, so an app-level filter catches every Polish event on
buttons, combos, and sliders — dialogs and pop-outs included.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Freeze the old look in a click-through screenshot overlay and fade it
out over the restyled window — QSS has no transitions and animating the
palette would re-polish every widget per frame. Sunset also flips the
app-palette text roles so native primitives QSS can't recolor (spin and
combo arrow glyphs) follow the theme.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The panel paints availability/message colors in code per DAQ tick, so
QSS can't retint it — state_colors(theme) hands it a per-theme dict
(Catppuccin Mocha inks for Sunset) and _apply_theme pushes theme flips.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Both stylesheets move to transparent children over a gradient painted
only by top-level windows; inputs, buttons, headers, and menus get
opaque faces back. Sunset drops Catppuccin Macchiato for the Daemmerung
dusk palette. Spin/combo arrows and check indicators become theme-tinted
PNGs. Widgets stop carrying inline input/text stylesheets so the theme
QSS can win (empty stylesheet = theme reset).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The Optional _popout_view is assert-narrowed once after opening; the
unguarded accesses were the last three diff-gate violations.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
New tests for what the port added: status tint priority and
context-dependent chip filters on the dewar/queue model, the
right-button wheel guard (motor protection), PopoutWindow edge maths,
manual-resize fallback, close-hides behavior and DockTitleBar, the
chip drag-drop relabeling, and the console-log pop-out mirror. The
widgets' __main__ self-checks are superseded by these and removed.
Brings PR diff coverage from 70% to 81% (gate: 80%).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The sample-name labels are created in __init__ now (the build helper
only styles and mounts them) so reportUninitializedInstanceVariable
stops firing on the ported styling lines, and the queue placeholder
uses the scoped Qt.AlignmentFlag.AlignCenter.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The sandbox port was ruff-check clean but not ruff-format clean (CI
formats before linting); splash_screen's alignment flags move to the
scoped enum since the port put that line into the diff gate's scope.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>