From 5ea2b032f5246dcc71a45ac60f7765714171f409 Mon Sep 17 00:00:00 2001 From: eti Date: Thu, 30 Jul 2026 14:31:37 +0200 Subject: [PATCH] web/components: stop ButtonGroup doubling its selected segment's edge MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit a joined group's segments each drew their own 1px top/bottom border in the same token as the group's own, and the two lines landed adjacent rather than overlapping, so the selected tab read as a 2px edge with the ::before inset shadow stacking a third band under it. the -my-px meant to pull them together never applied: items-center left the segments at their natural height instead of stretching, so the margins only shrank the flex line the group had already outgrown. follows the appview's .btn-group instead — the group is the only thing drawing a horizontal border, its segments take border-y-0 and stretch to fill the inner box. the x seams are unchanged, still one divider each via -ml-px. the recessed surface also needed dark:bg-background-canvas: subtle sits below default in light (#f9fafb vs #fff) but above it in dark (#374151 vs #1f2937), so an unselected segment came out lighter than the selected one. canvas (#111827) is the appview's gray-900. Signed-off-by: eti --- web/src/lib/components/ui/ButtonGroup.svelte | 21 ++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/web/src/lib/components/ui/ButtonGroup.svelte b/web/src/lib/components/ui/ButtonGroup.svelte index 7ec3968e..791e21a7 100644 --- a/web/src/lib/components/ui/ButtonGroup.svelte +++ b/web/src/lib/components/ui/ButtonGroup.svelte @@ -5,15 +5,24 @@ export const buttonGroup = tv({ base: "inline-flex items-center", variants: { - // joined groups are the segmented control from Figma: the group draws the outer - // border and the recessed surface, and each segment's own 1px border is pulled - // onto it (-m-px) so an unselected segment shows the group's surface while a - // selected one covers it and reads as a raised card. + // joined groups are the segmented control from Figma, built the way the appview's + // .btn-group is: the group alone draws the outer border and the recessed surface, + // its segments drop their own top/bottom border entirely (border-y-0) and stretch + // to fill the inner box. that matters because a segment's y-border is the same + // token as the group's, so keeping both stacks two 1px lines into one 2px-looking + // edge above and below the selected segment. horizontally the segments keep their + // border and it's pulled onto the neighbour's (-ml-px) so each seam collapses to a + // single divider, and the outer ones onto the group's own edge. + // + // the recessed surface has to stay darker than the selected segment's + // bg-background-default, and no single token does that in both modes — subtle is + // below default in light (#f9fafb vs #fff) but above it in dark (#374151 vs + // #1f2937) — so dark falls back to canvas (#111827), i.e. the appview's gray-900. spaced: { true: "gap-2", false: [ - "gap-0 rounded border border-border-default bg-background-subtle", - "*:relative *:-my-px", + "items-stretch gap-0 rounded border border-border-default bg-background-subtle dark:bg-background-canvas", + "*:relative [&>*]:border-y-0", "[&>*:first-child]:-ml-px [&>*:last-child]:-mr-px", "[&>*:not(:first-child)]:-ml-px [&>*:not(:first-child)]:[--btn-radius-l:0px]", "[&>*:not(:last-child)]:[--btn-radius-r:0px]", -- 2.51.2