♻️ Move dashboard subscription styles off the deprecated styles (#12538)

* ♻️ Move dashboard subscription styles off the deprecated styles

The subscription stylesheet inlines the deprecated button-style and
flex-center mixins, resolves its legacy color aliases and sizes to DS
tokens, uses logical properties and the DS typography module without a
namespace. Three rules that match nothing (the arrow svg, .cta-link and
.open-arrow) are commented out with a TODO.

The subscription controls need no DS change: the plan card, the current
plan card and the manage subscription link have no DS equivalent, and
they use no legacy icons. refactor/ stays only for the power up menu
item placeholder and the shared dashboard header styles.

A visual test covers the sidebar plan card (closed and open), the team
settings plan and the members seats warnings. No visual change.

AI-assisted-by: claude-opus-5-5

* 🔥 Remove unused styles from the dashboard subscription

The SCSS refactor of the dashboard subscription left rules commented out
with a TODO because the module does not use them, or because they target
an svg inside a DS icon that is the svg itself. CSS modules scope the
classes to this module and no other source uses them, so they go:
.icon-dropdown svg, .cta-link, .open-arrow. No visual change.

AI-assisted-by: claude-opus-5-5
This commit is contained in:
Eva Marco 2026-10-27 10:23:55 +01:00 committed by GitHub
parent 411f661bdb
commit 9854f8e54f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 149 additions and 56 deletions

View File

@ -337,3 +337,104 @@ test.describe("Delete account modal", () => {
await expect(modal).toHaveScreenshot(shot);
});
});
test.describe("Subscription controls", () => {
const shot = { maxDiffPixelRatio: 0, threshold: 0 };
// An unlimited trial that the logged-in user owns, as in
// specs/subscriptions-dashboard.spec.js.
const setupSubscription = async (
page,
members,
secondTeam = true,
usage = "subscription/get-subscription-usage.json",
) => {
await DashboardPage.mockConfigFlags(page, [
"enable-subscriptions",
"disable-onboarding",
]);
await DashboardPage.mockRPC(
page,
"get-profile",
"subscription/get-profile-unlimited-subscription.json",
);
await DashboardPage.mockRPC(page, "get-subscription-usage", usage);
await DashboardPage.mockRPC(
page,
"get-team-info",
"subscription/get-team-info-subscriptions.json",
);
const dashboardPage = new DashboardPage(page);
await dashboardPage.setupDashboardFull();
await DashboardPage.mockRPC(
page,
"get-teams",
"subscription/get-teams-unlimited-subscription-owner.json",
);
if (secondTeam) {
await DashboardPage.mockRPC(
page,
"get-projects?team-id=*",
"dashboard/get-projects-second-team.json",
);
}
await DashboardPage.mockRPC(page, "get-team-members?team-id=*", members);
await DashboardPage.mockRPC(
page,
"get-team-stats?team-id=*",
"dashboard/get-team-stats.json",
);
await dashboardPage.mockRPC(
"push-audit-events",
"workspace/audit-event-empty.json",
);
return dashboardPage;
};
test("Sidebar plan card", async ({ page }) => {
const dashboardPage = await setupSubscription(
page,
"subscription/get-team-members-subscription-owner.json",
false,
"subscription/get-subscription-usage-one-editor.json",
);
await dashboardPage.goToDashboard();
const name = page.getByTestId("subscription-name");
await expect(name).toHaveText("Unlimited plan (trial)");
const card = page.locator("[class*='cta-power-up']").first();
await page.mouse.move(640, 300);
await expect(card).toHaveScreenshot(shot);
await name.click();
await page.mouse.move(640, 300);
await expect(card).toHaveScreenshot(shot);
});
test("Team settings plan", async ({ page }) => {
const dashboardPage = await setupSubscription(
page,
"subscription/get-team-members-subscription-owner.json",
);
await dashboardPage.goToSecondTeamSettingsSection();
await expect(
page.getByRole("button", { name: "Manage your subscription" }),
).toBeVisible();
await expect(
page.locator("[class$='subscription__team']"),
).toHaveScreenshot(shot);
});
test("Members seats warning", async ({ page }) => {
const dashboardPage = await setupSubscription(
page,
"subscription/get-team-members-subscription-eight-member.json",
);
await dashboardPage.goToSecondTeamMembersSection();
await expect(page.getByTestId("cta")).toHaveCount(2);
await page.mouse.move(640, 700);
await expect(page).toHaveScreenshot(shot);
});
});

View File

@ -4,10 +4,16 @@
//
// Copyright (c) KALEIDOS SUBSIDIARY SL
// refactor/ stays for the menu item placeholder (%menu-item-base) of the
// power up submenu.
@use "refactor/common-refactor.scss" as deprecated;
// The shared dashboard header styles move in their own change: they are
// used by ten dashboard modules.
@use "common/refactor/common-dashboard";
@use "ds/typography.scss" as t;
@use "ds/typography.scss" as *;
@use "ds/_borders.scss" as *;
@use "ds/_utils.scss" as *;
@use "ds/spacing.scss" as *;
.cta-power-up {
@ -26,8 +32,9 @@
}
.cta-top-section {
@include deprecated.button-style;
border: none;
background: none;
cursor: pointer;
display: grid;
color: var(--color-foreground-secondary);
grid-template-columns: 1fr auto;
@ -44,17 +51,11 @@
}
.icon-dropdown {
@include deprecated.flex-center;
height: 100%;
width: var(--sp-l);
}
.icon-dropdown svg {
@extend %button-icon-small;
stroke: var(--icon-foreground);
transform: rotate(90deg);
display: flex;
justify-content: center;
align-items: center;
block-size: 100%;
inline-size: var(--sp-l);
}
.cta-bottom-section {
@ -69,12 +70,14 @@
}
.cta-bottom-section .content {
@include t.use-typography("body-medium");
@include deprecated.button-style;
@include use-typography("body-medium");
border: none;
background: none;
cursor: pointer;
color: var(--color-foreground-secondary);
display: inline-block;
text-align: left;
text-align: start;
}
.cta-bottom-button {
@ -87,72 +90,67 @@
.cta-text,
.cta-title {
text-align: left;
text-align: start;
}
.cta-title {
@include t.use-typography("body-small");
@include use-typography("body-small");
margin-block-end: var(--sp-xs);
}
.highlighted .cta-title {
@include t.use-typography("body-medium");
@include use-typography("body-medium");
margin-block-end: 0;
}
.cta-text {
@include t.use-typography("title-small");
@include use-typography("title-small");
}
.highlighted .cta-text {
@include t.use-typography("body-large");
@include use-typography("body-large");
color: var(--color-foreground-primary);
}
.cta-bottom-section .content a {
@include t.use-typography("body-medium");
@include use-typography("body-medium");
color: var(--color-accent-tertiary);
margin-inline-start: var(--sp-xs);
}
.cta-link {
@include deprecated.button-style;
align-self: end;
margin-inline-start: var(--sp-xs);
}
.team {
display: grid;
grid-auto-rows: min-content;
gap: var(--sp-s);
max-width: deprecated.$s-1000;
width: 100%;
max-inline-size: px2rem(1000);
inline-size: 100%;
}
.team-label {
@include t.use-typography("headline-small");
@include use-typography("headline-small");
color: var(--title-foreground-color);
color: var(--color-foreground-secondary);
}
.team-text {
@include t.use-typography("title-medium");
@include use-typography("title-medium");
color: var(--color-foreground-primary);
}
.manage-subscription-link {
@include deprecated.button-style;
@include t.use-typography("body-medium");
@include use-typography("body-medium");
border: none;
background: none;
cursor: pointer;
color: var(--color-accent-tertiary);
display: flex;
margin-block-start: -8px;
margin-block-start: calc(-1 * var(--sp-s));
padding: 0;
}
@ -178,21 +176,15 @@
cursor: pointer;
&:hover {
color: var(--menu-foreground-color-hover);
.open-arrow {
svg {
stroke: var(--menu-foreground-color-hover);
}
}
color: var(--color-foreground-primary);
}
}
.members-cta {
height: fit-content;
block-size: fit-content;
margin-block-start: var(--sp-s);
margin-inline-start: deprecated.$s-52;
max-width: deprecated.$s-220;
margin-inline-start: px2rem(52);
max-inline-size: px2rem(220);
.cta-title {
line-height: 1.2;
@ -200,7 +192,7 @@
}
.dashboard-cta {
height: fit-content;
block-size: fit-content;
margin: var(--sp-l);
.cta-title {
@ -209,7 +201,7 @@
}
.cta-message {
@include t.use-typography("body-small");
@include use-typography("body-small");
color: var(--color-foreground-secondary);
line-height: 1;
@ -231,13 +223,13 @@
}
.nitrate-title {
@include t.use-typography("body-large");
@include use-typography("body-large");
color: var(--color-foreground-primary);
}
.nitrate-info {
@include t.use-typography("body-medium");
@include use-typography("body-medium");
color: var(--color-foreground-secondary);
margin-block: var(--sp-s) var(--sp-xxl);
@ -249,8 +241,8 @@
}
.nitrate-bottom-button {
width: fit-content;
height: fit-content;
inline-size: fit-content;
block-size: fit-content;
padding: var(--sp-s) var(--sp-m);
}
@ -271,14 +263,14 @@
}
.nitrate-current-plan-label {
@include t.use-typography("body-small");
@include use-typography("body-small");
padding-block-end: var(--sp-xs);
color: var(--color-foreground-secondary);
}
.nitrate-current-plan-text {
@include t.use-typography("body-medium");
@include use-typography("body-medium");
color: var(--color-foreground-primary);
}