From 17a0b9e0b5f20112f28b82000077e2ebe8029c4d Mon Sep 17 00:00:00 2001 From: Waleed Latif Date: Wed, 12 Aug 2026 11:51:05 -0700 Subject: [PATCH 1/3] improvement(workflow): smooth the running hatch's slanted edges MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The marks read as stepped rather than slanted. A repeating gradient is sampled once per pixel with no coverage term, so a hard colour stop on an edge 15° off vertical can only land wholly on one side or the other — there is no partial value to soften the transition, and the staircase is the whole edge on a mark this thin. Ramp each edge over 0.75px, roughly a device pixel, instead of switching colour at a single offset. That hands the rasterizer the intermediate values antialiasing would have produced: measured deviation of the edge from its own straight line falls from 0.28 device px — pure quantization — to 0.05. The ramps are centred on the offsets the hard stops used, so the 50%-coverage line does not move: same 75° lean, same 24/2 rhythm, same 26px scroll period. --- .../components/action-bar/action-bar.tsx | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/action-bar/action-bar.tsx b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/action-bar/action-bar.tsx index c2882134000..7c7016ae593 100644 --- a/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/action-bar/action-bar.tsx +++ b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/action-bar/action-bar.tsx @@ -66,10 +66,24 @@ const ACTION_BUTTON_STYLES = [ * 25.11px of period. Writing 24/26 directly would render ~3.5% wide and drift * out of the squares' rhythm across the row. * + * Each edge ramps over 0.75px rather than switching colour at a single offset, + * which is why the stops come in pairs 0.375px either side of 23.18 and 25.11. + * A gradient is sampled once per pixel with no coverage term, so a hard stop on + * a 15°-off-vertical edge can only ever land wholly on one side or the other — + * the marks came out visibly stepped, which is the one thing a shape this thin + * cannot hide. Ramping across roughly a device pixel gives the rasterizer the + * intermediate values antialiasing would have produced, and measured edge + * deviation drops from 0.28 device px (pure quantization) to 0.05. + * + * The ramps are centred on the old offsets, so the 50%-coverage line — the edge + * the eye actually locates — has not moved and the 24/2 rhythm is untouched. + * Widening the feather further would keep smoothing, but the gap is only 1.93px + * of stop, so it comes straight out of the mark's dark core. + * * `--surface-2` is the same fill the slots used; only where it is painted moved. */ const RUNNING_FILL = - 'bg-[repeating-linear-gradient(75deg,var(--surface-2)_0_23.18px,transparent_23.18px_25.11px)]' + 'bg-[repeating-linear-gradient(75deg,var(--surface-2)_0_22.805px,transparent_23.555px_24.735px,var(--surface-2)_25.11px)]' /** Left edge of the fill: clears the run/stop button, which stays live mid-run. */ const RUNNING_FILL_INSET_SWELL = 'left-[42px]' From a84e69f7fe53d25b130ae7178ca4463741aa7290 Mon Sep 17 00:00:00 2001 From: Waleed Latif Date: Wed, 12 Aug 2026 11:57:52 -0700 Subject: [PATCH 2/3] improvement(workflow): sit the running hatch in the slot's own box MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The hatch was inset 4px into a 24px row, so it stood 16px tall inside a swell whose slots are 24px — it read as a shorter bar floating inside the row rather than as the slots themselves filling, and its right end stopped short of where a hovered slot's fill ends. Span the row instead. The row already sits inside the container's 2px/3.2px inset, so occupying it outright puts the hatch in exactly the box a slot's hover fill occupies: same height, same padding in from the swell on every side. The end taper has to move with it, since its two numbers were read off the slot's diagonal at the old overlay's top and bottom (y=4 and y=20). Continuing that same edge — slope 20/24 — across the full row gives 20px in at the top and flush at the bottom, so the hatch still ends on the slot's own diagonal. --- .../components/action-bar/action-bar.tsx | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/action-bar/action-bar.tsx b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/action-bar/action-bar.tsx index 7c7016ae593..ba130dd1939 100644 --- a/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/action-bar/action-bar.tsx +++ b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/action-bar/action-bar.tsx @@ -98,12 +98,15 @@ const RUNNING_FILL_INSET_PLAIN = 'left-[26px]' * inside it at the bottom — the fill visibly ran off the block. The per-slot * version never did, because each button's own clip contained it. * - * Same taper, read off that path: the edge sits 16.67px in from the row's right - * at the overlay's top (y=4) and 3.33px at its bottom (y=20), a slope of 20/24. - * Changing the end silhouette means changing these two numbers with it. + * Same taper, read off that path. Its straight run — (22.4, 2.88) to + * (36.59, 19.9) in the slot's own 40×24 box — has a slope of 20/24, so across + * the full row it moves from 20px in at the top to flush at the bottom. The + * overlay spans the row, so those are its two numbers; they are the slot's own + * edge continued, which is what puts the hatch's end exactly where a hovered + * slot's fill ends. Changing the end silhouette means changing them with it. */ const RUNNING_FILL_END_TAPER = - '[clip-path:polygon(0_0,calc(100%_-_16.67px)_0,calc(100%_-_3.33px)_100%,0_100%)]' + '[clip-path:polygon(0_0,calc(100%_-_20px)_0,100%_100%,0_100%)]' const ICON_SIZE = 'size-[14px]' @@ -429,7 +432,11 @@ export const ActionBar = memo(