diff --git a/apps/web/src/components/nav/panels/PanelSolutions.tsx b/apps/web/src/components/nav/panels/PanelSolutions.tsx index 041bfc44d..f17f22913 100644 --- a/apps/web/src/components/nav/panels/PanelSolutions.tsx +++ b/apps/web/src/components/nav/panels/PanelSolutions.tsx @@ -59,29 +59,16 @@ export function PanelSolutions({ item }: Props) { atmosphere={ATMOSPHERE} >
- {/* Col 1: Capability stacked above Compliance */} -
+ {/* Cols 1 and 2 share one grid so the two rows of groups line up: + Capability beside By role, one divider across both, then + Compliance beside By industry. Two independent stacks drifted as + soon as the groups had different item counts. */} +
{capability && } - {compliance && ( - <> -
- - - )} -
- - {/* Col 2: By Role stacked above By Industry, on the same divider - grammar as Col 1. Col 2 held a single two-item group and ran short - against Col 1's five, so the second group lands where the panel - already had vertical room. */} -
{byRole && } - {byIndustry && ( - <> -
- - - )} +
+ {compliance && } + {byIndustry && }
{/* Col 3: FIPS featured tile */} diff --git a/apps/web/tests/e2e/impact-estimator.spec.ts b/apps/web/tests/e2e/impact-estimator.spec.ts index 5c73e16ab..5a798ae18 100644 --- a/apps/web/tests/e2e/impact-estimator.spec.ts +++ b/apps/web/tests/e2e/impact-estimator.spec.ts @@ -51,6 +51,9 @@ test.describe("impact estimator copy link @phase-web-impact-estimator", () => { test.skip(browserName !== "chromium", "clipboard permissions are only grantable in Chromium"); await context.grantPermissions(["clipboard-read", "clipboard-write"]); await page.goto(`${ROUTE}?images=60&team=15&remediation=Quarterly&release=Monthly`); + // The slider only reads 60 once the page has hydrated and adopted the URL; + // clicking before that lands on a button with no handler yet. + await expect(page.getByRole("slider", { name: "Production images" })).toHaveValue("60"); const button = page.getByRole("button", { name: "Copy link to results" }); await button.click(); @@ -69,11 +72,16 @@ test.describe("impact estimator mobile summary @phase-web-impact-estimator", () const strip = page.locator('button[aria-label^="Jump to your results"]'); await expect(strip).toHaveAttribute("aria-hidden", "true"); - // Park the inputs card just under the header: the sliders are usable and - // the gauge sits below the fold on every phone viewport. + // Scroll so the gauge is only a fifth visible at the bottom edge: the inputs + // card is on screen and the readout is not, on phones and tablets alike. A + // fixed offset from the card top would not do: at 768px the card is short + // enough that the gauge is already mostly visible, and the strip rightly + // stays hidden. await page.evaluate(() => { - const card = document.querySelector('[data-section="ImpactSimulator"] .lg\\:sticky'); - if (card) window.scrollTo({ top: card.getBoundingClientRect().top + window.scrollY - 80, behavior: "instant" }); + const gauge = document.querySelector('[data-section="ImpactSimulator"] svg[role="img"]'); + if (!gauge) return; + const r = gauge.getBoundingClientRect(); + window.scrollTo({ top: r.top + window.scrollY - window.innerHeight + r.height * 0.2, behavior: "instant" }); }); await expect(strip).toHaveAttribute("aria-hidden", "false"); await expect(strip).toHaveAttribute("aria-label", /High runtime complexity, burden 260, 7,800 hours/);