R7: test reconciliation + visual baseline lock

- Regenerated all 7 @visual darwin baselines for the restyled surfaces
  (login, workspace home, chat welcome, computer panel, credits) and
  added two new ones: the marketing landing (full page) and the Team
  org-chart tab.
- Credits visual made deterministic: balance + the whole usage card are
  masked (testids), and the runway line always renders so the card
  height is constant — shared-backend credit spend during the full run
  no longer shifts the diff.
- Full gate sweep green end to end: 173 Rust tests + clippy/fmt clean,
  83 frontend unit + lint + typecheck, all 37 Playwright journeys
  (functional + visual), axe serious/critical at zero across every
  surface, LOC ≤1250 and no-placeholder gates.

The interface now matches the reference design system across the app,
the Computer panel, the global pages, and a new light-theme marketing
site — design system only, our brand throughout.

Co-Authored-By: Claude Fable 5 <[email protected]>
This commit is contained in:
Omar Sobh
2026-06-10 20:26:10 -05:00
co-authored by Claude Fable 5
parent 51677fef2d
commit 337f059afd
9 changed files with 35 additions and 8 deletions
@@ -51,7 +51,7 @@ export default async function CreditsPage() {
<BuyCredits /> <BuyCredits />
</Card> </Card>
<Card> <Card data-testid="usage-card">
<p className="text-xs tracking-wide text-muted-foreground uppercase"> <p className="text-xs tracking-wide text-muted-foreground uppercase">
Usage · last 7 days Usage · last 7 days
</p> </p>
@@ -61,11 +61,11 @@ export default async function CreditsPage() {
tokens ({usage.tokens_in.toLocaleString("en-US")} in /{" "} tokens ({usage.tokens_in.toLocaleString("en-US")} in /{" "}
{usage.tokens_out.toLocaleString("en-US")} out) {usage.tokens_out.toLocaleString("en-US")} out)
</p> </p>
{runwayDays !== null && (
<p className="pt-1 text-xs text-muted-foreground"> <p className="pt-1 text-xs text-muted-foreground">
~{runwayDays} days of runway at this pace. {runwayDays !== null
? `~${runwayDays} days of runway at this pace.`
: "No usage yet this week."}
</p> </p>
)}
</Card> </Card>
<PromoRedeem /> <PromoRedeem />
+29 -2
View File
@@ -60,10 +60,37 @@ test("credits page looks right @visual", async ({ page }) => {
await expect(page).toHaveScreenshot("credits.png", { await expect(page).toHaveScreenshot("credits.png", {
...SCREENSHOT, ...SCREENSHOT,
// Balance and usage are live numbers — mask them, lock the layout. // Balance and usage are live numbers — mask them, lock the layout.
// Balance and the whole usage card are live (and the runway line
// appears/disappears with burn) — mask them, lock the layout.
mask: [ mask: [
page.getByTestId("credit-balance"), page.getByTestId("credit-balance"),
page.getByText(/credits ·/), page.getByTestId("usage-card"),
page.getByText(/days of runway/),
], ],
}); });
}); });
test("marketing landing looks right @visual", async ({ page, context }) => {
await context.clearCookies();
await page.goto("/");
await expect(
page.getByRole("heading", { name: /AI coworkers/ }),
).toBeVisible();
await page.evaluate(() =>
Promise.allSettled(document.getAnimations().map((a) => a.finished)),
);
await expect(page).toHaveScreenshot("marketing.png", {
...SCREENSHOT,
fullPage: true,
});
});
test("team org chart looks right @visual", async ({ page }) => {
await signIn(page);
await page.getByRole("link", { name: "Team", exact: true }).click();
await page.getByRole("tab", { name: "Claw org chart" }).click();
await expect(page.getByRole("tab", { name: "Claw org chart" })).toHaveAttribute(
"aria-selected",
"true",
);
await expect(page).toHaveScreenshot("team-orgchart.png", SCREENSHOT);
});
Binary file not shown.

Before

Width:  |  Height:  |  Size: 41 KiB

After

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 187 KiB

After

Width:  |  Height:  |  Size: 139 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 30 KiB

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 283 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 17 KiB