From e2ff88d39781a5994f9f4391e78056c263082b51 Mon Sep 17 00:00:00 2001 From: Gert-Jan Vercauteren Date: Wed, 22 Jul 2026 15:53:44 +0800 Subject: [PATCH 1/3] [CLOV-CSS] Migrate bpk-component-overlay to CSS custom properties MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replaces rgba(tokens.\$bpk-text-primary-day, N) with color-mix(in srgb, var(--bpk-text-primary, tokens.\$bpk-text-primary-day) N%, transparent) so overlays adapt automatically between light and dark themes. Gap token \$bpk-color-sky-blue-shade-03 (tint variant) kept as bare SASS with a comment — no semantic CSS var mapping exists. Adds a DarkMode story using BpkDarkExampleWrapper. Closes #4843 Co-Authored-By: Claude Sonnet 4.6 (1M context) --- .../src/BpkOverlay.module.scss | 172 ++++++++++++++---- .../src/BpkOverlay.stories.tsx | 11 ++ 2 files changed, 149 insertions(+), 34 deletions(-) diff --git a/packages/backpack-web/src/bpk-component-overlay/src/BpkOverlay.module.scss b/packages/backpack-web/src/bpk-component-overlay/src/BpkOverlay.module.scss index 20e8e7a818..fd5997cff3 100644 --- a/packages/backpack-web/src/bpk-component-overlay/src/BpkOverlay.module.scss +++ b/packages/backpack-web/src/bpk-component-overlay/src/BpkOverlay.module.scss @@ -18,6 +18,12 @@ @use '../../bpk-mixins/tokens'; +// CSS var wrapping uses color-mix(in srgb, COLOR X%, transparent) because +// rgba() cannot accept CSS custom properties as the colour argument. +// --bpk-text-primary flips automatically between light (#161616) and dark (#ffffff). +// $bpk-color-sky-blue-shade-03 is kept as a bare SASS token — gap: raw primitive colour, +// no semantic CSS var mapping exists. + .bpk-overlay { &__wrapper { position: relative; @@ -35,20 +41,33 @@ border-radius: inherit; &--tint { + /* gap: raw primitive colour, no semantic mapping */ background: rgba(tokens.$bpk-color-sky-blue-shade-03, 0.56); } &--solid { &-low { - background: rgba(tokens.$bpk-text-primary-day, 0.15); + background: color-mix( + in srgb, + var(--bpk-text-primary, tokens.$bpk-text-primary-day) 15%, + transparent + ); } &-medium { - background: rgba(tokens.$bpk-text-primary-day, 0.3); + background: color-mix( + in srgb, + var(--bpk-text-primary, tokens.$bpk-text-primary-day) 30%, + transparent + ); } &-high { - background: rgba(tokens.$bpk-text-primary-day, 0.4); + background: color-mix( + in srgb, + var(--bpk-text-primary, tokens.$bpk-text-primary-day) 40%, + transparent + ); } } @@ -56,24 +75,39 @@ &-low { background: linear-gradient( 180deg, - rgba(tokens.$bpk-text-primary-day, 0.15) 0%, - rgba(tokens.$bpk-text-primary-day, 0) 100% + color-mix( + in srgb, + var(--bpk-text-primary, tokens.$bpk-text-primary-day) 15%, + transparent + ) + 0%, + transparent 100% ); } &-medium { background: linear-gradient( 180deg, - rgba(tokens.$bpk-text-primary-day, 0.3) 0%, - rgba(tokens.$bpk-text-primary-day, 0) 100% + color-mix( + in srgb, + var(--bpk-text-primary, tokens.$bpk-text-primary-day) 30%, + transparent + ) + 0%, + transparent 100% ); } &-high { background: linear-gradient( 180deg, - rgba(tokens.$bpk-text-primary-day, 0.4) 0%, - rgba(tokens.$bpk-text-primary-day, 0) 100% + color-mix( + in srgb, + var(--bpk-text-primary, tokens.$bpk-text-primary-day) 40%, + transparent + ) + 0%, + transparent 100% ); } } @@ -82,24 +116,39 @@ &-low { background: linear-gradient( 180deg, - rgba(tokens.$bpk-text-primary-day, 0) 0%, - rgba(tokens.$bpk-text-primary-day, 0.15) 100% + transparent 0%, + color-mix( + in srgb, + var(--bpk-text-primary, tokens.$bpk-text-primary-day) 15%, + transparent + ) + 100% ); } &-medium { background: linear-gradient( 180deg, - rgba(tokens.$bpk-text-primary-day, 0) 0%, - rgba(tokens.$bpk-text-primary-day, 0.3) 100% + transparent 0%, + color-mix( + in srgb, + var(--bpk-text-primary, tokens.$bpk-text-primary-day) 30%, + transparent + ) + 100% ); } &-high { background: linear-gradient( 180deg, - rgba(tokens.$bpk-text-primary-day, 0) 0%, - rgba(tokens.$bpk-text-primary-day, 0.4) 100% + transparent 0%, + color-mix( + in srgb, + var(--bpk-text-primary, tokens.$bpk-text-primary-day) 40%, + transparent + ) + 100% ); } } @@ -108,24 +157,39 @@ &-low { background: linear-gradient( 90deg, - rgba(tokens.$bpk-text-primary-day, 0.15) 0%, - rgba(tokens.$bpk-text-primary-day, 0) 98.5% + color-mix( + in srgb, + var(--bpk-text-primary, tokens.$bpk-text-primary-day) 15%, + transparent + ) + 0%, + transparent 98.5% ); } &-medium { background: linear-gradient( 90deg, - rgba(tokens.$bpk-text-primary-day, 0.3) 0%, - rgba(tokens.$bpk-text-primary-day, 0) 98.5% + color-mix( + in srgb, + var(--bpk-text-primary, tokens.$bpk-text-primary-day) 30%, + transparent + ) + 0%, + transparent 98.5% ); } &-high { background: linear-gradient( 90deg, - rgba(tokens.$bpk-text-primary-day, 0.4) 0%, - rgba(tokens.$bpk-text-primary-day, 0) 98.5% + color-mix( + in srgb, + var(--bpk-text-primary, tokens.$bpk-text-primary-day) 40%, + transparent + ) + 0%, + transparent 98.5% ); } } @@ -134,48 +198,88 @@ &-low { background: linear-gradient( 90deg, - rgba(tokens.$bpk-text-primary-day, 0) 0%, - rgba(tokens.$bpk-text-primary-day, 0.15) 98.5% + transparent 0%, + color-mix( + in srgb, + var(--bpk-text-primary, tokens.$bpk-text-primary-day) 15%, + transparent + ) + 98.5% ); } &-medium { background: linear-gradient( 90deg, - rgba(tokens.$bpk-text-primary-day, 0) 0%, - rgba(tokens.$bpk-text-primary-day, 0.3) 98.5% + transparent 0%, + color-mix( + in srgb, + var(--bpk-text-primary, tokens.$bpk-text-primary-day) 30%, + transparent + ) + 98.5% ); } &-high { background: linear-gradient( 90deg, - rgba(tokens.$bpk-text-primary-day, 0) 0%, - rgba(tokens.$bpk-text-primary-day, 0.4) 98.5% + transparent 0%, + color-mix( + in srgb, + var(--bpk-text-primary, tokens.$bpk-text-primary-day) 40%, + transparent + ) + 98.5% ); } } &--vignette { - box-shadow: inset 0 0 50px rgba(tokens.$bpk-text-primary-day, 0.12); + box-shadow: inset 0 0 50px + color-mix( + in srgb, + var(--bpk-text-primary, tokens.$bpk-text-primary-day) 12%, + transparent + ); } &--heavy { &-top { background: linear-gradient( 180deg, - rgba(tokens.$bpk-text-primary-day, 0.45) 0%, - rgba(tokens.$bpk-text-primary-day, 0.15) 60%, - rgba(tokens.$bpk-text-primary-day, 0.05) 80%, - rgba(tokens.$bpk-text-primary-day, 0) 100% + color-mix( + in srgb, + var(--bpk-text-primary, tokens.$bpk-text-primary-day) 45%, + transparent + ) + 0%, + color-mix( + in srgb, + var(--bpk-text-primary, tokens.$bpk-text-primary-day) 15%, + transparent + ) + 60%, + color-mix( + in srgb, + var(--bpk-text-primary, tokens.$bpk-text-primary-day) 5%, + transparent + ) + 80%, + transparent 100% ); } &-bottom { background: linear-gradient( 180deg, - rgba(tokens.$bpk-text-primary-day, 0) 0%, - rgba(tokens.$bpk-text-primary-day, 0.9) 100% + transparent 0%, + color-mix( + in srgb, + var(--bpk-text-primary, tokens.$bpk-text-primary-day) 90%, + transparent + ) + 100% ); } } diff --git a/packages/backpack-web/src/bpk-component-overlay/src/BpkOverlay.stories.tsx b/packages/backpack-web/src/bpk-component-overlay/src/BpkOverlay.stories.tsx index 5f180daa99..002879d272 100644 --- a/packages/backpack-web/src/bpk-component-overlay/src/BpkOverlay.stories.tsx +++ b/packages/backpack-web/src/bpk-component-overlay/src/BpkOverlay.stories.tsx @@ -18,6 +18,9 @@ import { ArgTypes, Markdown } from '@storybook/addon-docs/blocks'; +// @ts-expect-error Untyped import +import { BpkDarkExampleWrapper } from 'bpk-storybook-utils'; + import BpkImage from '../../bpk-component-image'; import BpkText, { TEXT_STYLES } from '../../bpk-component-text'; import { cssModules } from '../../bpk-react-utils'; @@ -333,3 +336,11 @@ export const VisualTestWithZoom = { zoomEnabled: true, }, }; + +export const DarkMode = { + render: () => ( + + + + ), +}; From 7dda63bba0b21e4e4f97fdbc35c1c80bdb943ac1 Mon Sep 17 00:00:00 2001 From: Gert-Jan Vercauteren Date: Wed, 22 Jul 2026 18:48:44 +0800 Subject: [PATCH 2/3] chore: reset non-CSS files to main --- .../bpk-component-overlay/src/BpkOverlay.stories.tsx | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/packages/backpack-web/src/bpk-component-overlay/src/BpkOverlay.stories.tsx b/packages/backpack-web/src/bpk-component-overlay/src/BpkOverlay.stories.tsx index 002879d272..5f180daa99 100644 --- a/packages/backpack-web/src/bpk-component-overlay/src/BpkOverlay.stories.tsx +++ b/packages/backpack-web/src/bpk-component-overlay/src/BpkOverlay.stories.tsx @@ -18,9 +18,6 @@ import { ArgTypes, Markdown } from '@storybook/addon-docs/blocks'; -// @ts-expect-error Untyped import -import { BpkDarkExampleWrapper } from 'bpk-storybook-utils'; - import BpkImage from '../../bpk-component-image'; import BpkText, { TEXT_STYLES } from '../../bpk-component-text'; import { cssModules } from '../../bpk-react-utils'; @@ -336,11 +333,3 @@ export const VisualTestWithZoom = { zoomEnabled: true, }, }; - -export const DarkMode = { - render: () => ( - - - - ), -}; From 5df656a3fa6fc4b9cfd7e6c011d2085ac5eb8db1 Mon Sep 17 00:00:00 2001 From: Gert-Jan Vercauteren Date: Wed, 22 Jul 2026 19:44:49 +0800 Subject: [PATCH 3/3] [CLOV-CSS] Remove gap comments from SCSS --- .../src/bpk-component-overlay/src/BpkOverlay.module.scss | 4 ---- 1 file changed, 4 deletions(-) diff --git a/packages/backpack-web/src/bpk-component-overlay/src/BpkOverlay.module.scss b/packages/backpack-web/src/bpk-component-overlay/src/BpkOverlay.module.scss index fd5997cff3..fce5bcb5a8 100644 --- a/packages/backpack-web/src/bpk-component-overlay/src/BpkOverlay.module.scss +++ b/packages/backpack-web/src/bpk-component-overlay/src/BpkOverlay.module.scss @@ -21,9 +21,6 @@ // CSS var wrapping uses color-mix(in srgb, COLOR X%, transparent) because // rgba() cannot accept CSS custom properties as the colour argument. // --bpk-text-primary flips automatically between light (#161616) and dark (#ffffff). -// $bpk-color-sky-blue-shade-03 is kept as a bare SASS token — gap: raw primitive colour, -// no semantic CSS var mapping exists. - .bpk-overlay { &__wrapper { position: relative; @@ -41,7 +38,6 @@ border-radius: inherit; &--tint { - /* gap: raw primitive colour, no semantic mapping */ background: rgba(tokens.$bpk-color-sky-blue-shade-03, 0.56); }