From 5a71023ac92a7ff16392e3dcb51ce40731e9f6f8 Mon Sep 17 00:00:00 2001 From: David Montero Crespo Date: Tue, 4 Aug 2026 16:12:50 +0200 Subject: [PATCH] fix(camera-toggle): toolbar-wide ant line gone; ants only while running The toggle's attention border reused the .velxio-ants class name, which is ALSO the canvas selection outline whose ::after is position:absolute - on the non-positioned button it anchored to the toolbar and drew a marching-ant line across its full width. Renamed the button variant to .velxio-btn-ants. The ants also showed while the simulation was stopped; now they only run when the sketch is running and the camera is off (the only moment the button is actually asking for a click). --- frontend/src/App.css | 10 +++++++--- .../src/components/simulator/CameraToggle.tsx | 15 +++++++++------ 2 files changed, 16 insertions(+), 9 deletions(-) diff --git a/frontend/src/App.css b/frontend/src/App.css index 0593211d..b8c3bf29 100644 --- a/frontend/src/App.css +++ b/frontend/src/App.css @@ -457,11 +457,15 @@ body { four thin repeating-gradient strips, one per edge, sliding one dash period per cycle. Drawn as backgrounds rather than a border because a CSS border cannot animate its dash offset. Uses currentColor so the - ants inherit the button's state colour (grey idle, red on error). */ + ants inherit the button's state colour (grey idle, red on error). + NOT named .velxio-ants: that class is the canvas selection outline + (SimulatorCanvas.css) whose ::after is position:absolute — on a + non-positioned button it anchored to the toolbar and drew a + toolbar-wide ant line. */ @keyframes velxio-marching-ants { to { background-position: 12px 0, -12px 100%, 0 -12px, 100% 12px; } } -.velxio-ants { +.velxio-btn-ants { background-image: repeating-linear-gradient(90deg, currentColor 0 6px, transparent 6px 12px), repeating-linear-gradient(90deg, currentColor 0 6px, transparent 6px 12px), @@ -473,7 +477,7 @@ body { animation: velxio-marching-ants 0.7s linear infinite; } @media (prefers-reduced-motion: reduce) { - .velxio-ants { animation: none; } + .velxio-btn-ants { animation: none; } } /* ── Editor: toolbar riding inside the header ───────────────────────────── diff --git a/frontend/src/components/simulator/CameraToggle.tsx b/frontend/src/components/simulator/CameraToggle.tsx index ec3289e3..f6d189a6 100644 --- a/frontend/src/components/simulator/CameraToggle.tsx +++ b/frontend/src/components/simulator/CameraToggle.tsx @@ -103,11 +103,14 @@ export const CameraToggle: React.FC = ({ boardId }) => { onClick={handleClick} disabled={!boardId || status === 'requesting'} title={tooltip} - // Ants while the button wants a click (idle after a failed/stopped - // auto-start, denied, error). Solid border once streaming or asking. + // Ants while the button wants a click DURING a run (idle after a + // failed/stopped auto-start, denied, error): a camera sketch is + // starving without frames. Never while the sim is stopped — the + // button is not asking for anything then. Solid border once + // streaming or asking. className={ - boardId && status !== 'streaming' && status !== 'requesting' - ? 'velxio-ants' + running && boardId && status !== 'streaming' && status !== 'requesting' + ? 'velxio-btn-ants' : undefined } style={{ @@ -126,8 +129,8 @@ export const CameraToggle: React.FC = ({ boardId }) => { fontSize: 13, cursor: boardId ? 'pointer' : 'not-allowed', // Inline only while requesting. 'none' here would OVERRIDE the - // .velxio-ants class animation (inline beats class), which is exactly - // how the ants shipped dead the first time. + // .velxio-btn-ants class animation (inline beats class), which is + // exactly how the ants shipped dead the first time. animation: status === 'requesting' ? 'velxio-pulse 1s ease-in-out infinite'