diff --git a/packages/web/src/App.tsx b/packages/web/src/App.tsx index f82c4a4..e81d324 100644 --- a/packages/web/src/App.tsx +++ b/packages/web/src/App.tsx @@ -357,7 +357,15 @@ function App() { {/* Header */}

diff --git a/packages/web/src/components/DataInspectionPanel.tsx b/packages/web/src/components/DataInspectionPanel.tsx index fc56235..ea45902 100644 --- a/packages/web/src/components/DataInspectionPanel.tsx +++ b/packages/web/src/components/DataInspectionPanel.tsx @@ -72,6 +72,11 @@ export function DataInspectionPanel({ width: side === 'right' ? size : '100%', height: side === 'bottom' ? size : '100%', flexShrink: 0, + // Sit above DataPixel (z=1000) so a carrot mid-flight can't paint + // over the inspector when the canvas pane lets it bleed past its + // bounds. + position: 'relative', + zIndex: 1001, } const handleStyle: React.CSSProperties = { @@ -409,7 +414,10 @@ export function BookmarkTab({ open, onToggle, edge, label, ariaLabel }: Bookmark top: '50%', transform: 'translateY(-50%)', [edge === 'right' ? 'right' : 'left']: 0, - zIndex: 20, + // Above DataPixel (z=1000) — same reason the header/sidebars + // sit above carrots: pixels in mid-flight can extend past the + // canvas pane bounds. + zIndex: 1001, width: 24, minWidth: 24, minHeight: 76, diff --git a/packages/web/src/components/FlowCanvas.tsx b/packages/web/src/components/FlowCanvas.tsx index 12787ba..c8baf85 100644 --- a/packages/web/src/components/FlowCanvas.tsx +++ b/packages/web/src/components/FlowCanvas.tsx @@ -678,7 +678,7 @@ function FlowCanvasInner({ restart() }} > - {'⏮'} + - {'⏪'} + - {playing ? '⏸' : '▶'} + {playing ? : } = flowSteps.length - 1 } > - {'⏩'} +

@@ -803,11 +803,11 @@ function PlaybackButton({ border: '1px solid #1a4a22', color: disabled ? '#3a5a42' : '#7fffaa', cursor: disabled ? 'default' : 'pointer', - fontSize: 14, - fontFamily: 'monospace', - lineHeight: 1, padding: 0, borderRadius: 3, + display: 'inline-flex', + alignItems: 'center', + justifyContent: 'center', }} > {children} @@ -815,6 +815,81 @@ function PlaybackButton({ ) } +// Inline SVG icons keep the playback chrome monochrome — emoji glyphs +// (⏮ ⏪ ▶ ⏸ ⏩) get rendered in the platform's color emoji font on most +// systems, ignoring the button's color and showing as Apple-blue or +// Win11-pink depending on the OS. SVG with currentColor + a sharp 16px +// viewBox keeps the buttons in the green accent the rest of the chrome +// uses. + +function ICON_FRAME(children: React.ReactNode) { + return ( + + ) +} + +function RestartIcon() { + // Counter-clockwise circular arrow with an arrowhead at the tail — + // unambiguous "start over" affordance instead of the skip-back glyph + // (⏮) the emoji set used. + return ( + + ) +} + +function PrevIcon() { + return ICON_FRAME( + <> + + + + ) +} + +function NextIcon() { + return ICON_FRAME( + <> + + + + ) +} + +function PlayIcon() { + return ICON_FRAME() +} + +function PauseIcon() { + return ICON_FRAME( + <> + + + + ) +} + export function FlowCanvas(props: FlowCanvasProps) { return ( diff --git a/packages/web/src/components/Sidebar.tsx b/packages/web/src/components/Sidebar.tsx index bf16870..42136a3 100644 --- a/packages/web/src/components/Sidebar.tsx +++ b/packages/web/src/components/Sidebar.tsx @@ -479,7 +479,13 @@ export function Sidebar({ return (