feat!: initial pre-release - Carbon v11 styles (#1881)

**carbon-components-svelte has unstable styles and interactions during this pre-release phase. See #1872 for details.**

Breaking changes

- Overall, this is a major style change the will impact the appearance and features of many components. Use caution when upgrading and test your applications.

Components

- Button has new prop values for size and kind
- Theme follows v11 conventions: g80 theme isn't supported, toggled themes adjust data-carbon-theme attribute in <html> tag (for now, tokens use bx prefix, but that may change)
- Tabs has a contained prop instead of type, and a new mobile appearance (scrolling tabs)
- ContentSwitcher size prop no longer supports size="xl"; md is the new default
- MultiSelect no longer supports xl size
- OverflowMenu no longer supports xl size
- Search no longer supports xl size
- TreeView no longer supports compact size
- UIShell has a new light theme

CSS

- Several class names have been changed due to the v11 overhaul. If you're targeting or overriding component classes, be sure to test your code
- Many tokens and CSS variables have been renamed. Details: https://carbondesignsystem.com/migrating/guide/develop
- Themes are applied to the <html> element as data-carbon-theme="g10" instead of theme="g10"
- The g80 theme no longer exists

General

- Codebase uses npm instead of yarn

--- Commit notes

* chore: depend on @carbon/styles instead of carbon-components

See upgrade guide here: https://carbondesignsystem.com/migrating/guide/develop

* chore: use v11 styles for docs

* chore: stick to `bx` instead of `cds` class prefix

* chore: migrate layout spacing to v11

See [@carbon/layout](https://github.com/carbon-design-system/carbon/blob/main/docs/migration/v11.md#carbonlayout) migration guide:

    $layout-01 	Removed, use $spacing-05 instead
    $layout-02 	Removed, use $spacing-06 instead
    $layout-03 	Removed, use $spacing-07 instead
    $layout-04 	Removed, use $spacing-09 instead
    $layout-05 	Removed, use $spacing-10 instead
    $layout-06 	Removed, use $spacing-12 instead
    $layout-07 	Removed, use $spacing-13 instead

* chore: migrate type tokens to v11

See https://github.com/carbon-design-system/carbon/blob/main/docs/migration/v11.md#type-tokens

* chore: keep flex-grid instead of css grid for the moment

Upgrading to css-grid should be separate.

* chore: v11 Tabs

In v11 [Tabs](https://carbondesignsystem.com/migrating/guide/design/#tabs-breaking) received some additional modifiers. In this commit we only want to make sure that the Svelte v10 tabs still work using v11 styles. This probably needs additional testing.

* chore: use @ibm/plex fonts

* chore: v11 Button

* dependency: @carbon/styles update

* chore: v11 ComboBox

Size `xl` changed to `lg`. For better compatibility with existing codebases size `xl` is still supported.

* chore: v11 ContentSwitcher

For better compatibility with existing code bases size `xl` is still supported.

* chore: remove legacy v10 css files

Note that further work is needed here in order to make theming work again.
Also documentation needs updating.

* chore: v11 DatePicker

For better compatibility with existing codebases size xl is still supported.

* chore: v11 Dropdown

For better compatibility with existing codebases size xl is still supported.

* chore: v11 ExpandableTile

Note that state labels `tileCollapsedLabel` and `tileExpandedLabel` are no longer supported.

* chore: v11 FileUploader

For better compatibility with existing codebases sizes `field` and `small` are still supported. Note that flagship implementation does the same thing.

* chore: v11 Toggle

This removes legacy `ToggleSkeleton`.

* chore: v11 MultiSelect

Size `xl` changed to `lg`.

* chore: v11 NumberInput

For better compatibility with existing codebases size `xl` is still supported.

* chore: v11 OverflowMenu

Size `xl` changed to `lg`. For better compatibility with existing codebases size `xl` is still supported.

* chore: v11 PasswordInput

Size `xl` changed to `lg`. For better compatibility with existing codebases size `xl` is still supported.

* chore: v11 Search

* chore: v11 Select

Size `xl` changed to `lg`. For better compatibility with existing codebases size `xl` is still supported.

* chore: v11 AspectRatio

The `bx--aspect-ratio--object` class is gone and needs to be replaced manually.

* chore: v11 TextArea

`cols` no longer has a defaults to 50 but remains at 100% width by default.

* chore: v11 TextInput

Size `xl` changed to `lg`. For better compatibility with existing codebases size `xl` is still supported.

* chore: v11 TimePicker

Size `xl` changed to `lg`. For better compatibility with existing codebases size `xl` is still supported.

* chore: v11 TreeView

Size `compact` changed to `xs`. For better compatibility with existing codebases size `compact` is still supported.

* chore: remove Truncate since it does not exist in Carbon v11

* chore: v11 UIShell

* chore: v11 Accordion

Size `xl` changed to `lg`. For better compatibility with existing codebases size `xl` is still supported.

* tmp: v11 PopoverContent

* Revert "chore: remove Truncate since it does not exist in Carbon v11"

This reverts commit 5833536199.

* chore: use truncate mixins

* docs: add truncate mixins

* chore: use `cds` class prefix in v11 styles

* build: switch to npm

* chore: set up all component styles, fonts, and themes

- Adapt documentation to new styles

* chore: add individual theme css

* feat: migrate Theme component to v11

- remove g80 theme option everywhere
- utilize new `data-carbon-theme` attribute when applying theme
- use cds instead of bx in places

* chore: use bx css prefixes for now

* chore: resolve peerDependencies

- Leaving out latest prettier for now
- Ignoring Sveld warnings for now

* chore: fix type errors and tests

---------

Co-authored-by: Gregor Wassmann <gregor.wassmann@gmail.com>
This commit is contained in:
Enrico Sacchetti 2024-01-12 11:33:59 -05:00 committed by Eric Liu
commit 4dabb827ee
186 changed files with 7886 additions and 5628 deletions

View file

@ -5,7 +5,10 @@
let events = [];
</script>
<Breakpoint bind:size on:change="{(e) => (events = [...events, e.detail])}" />
<Breakpoint
bind:size="{size}"
on:change="{(e) => (events = [...events, e.detail])}"
/>
<p>Resize the width of your browser.</p>
<h6>Breakpoint size</h6>
@ -17,10 +20,10 @@
<style>
p,
h1 {
margin-bottom: var(--cds-spacing-08);
margin-bottom: var(--bx-spacing-08);
}
h6 {
margin-bottom: var(--cds-spacing-03);
margin-bottom: var(--bx-spacing-03);
}
</style>

View file

@ -4,9 +4,9 @@
let checked = false;
</script>
<Checkbox labelText="Label text" bind:checked />
<Checkbox labelText="Label text" bind:checked="{checked}" />
<div style="margin: var(--cds-layout-01) 0">
<div style="margin: var(--bx-spacing-05) 0">
<Button on:click="{() => (checked = !checked)}">Toggle</Button>
</div>

View file

@ -6,10 +6,10 @@
</script>
{#each values as value}
<Checkbox bind:group labelText="{value}" value="{value}" />
<Checkbox bind:group="{group}" labelText="{value}" value="{value}" />
{/each}
<div style="margin: var(--cds-layout-01) 0">
<div style="margin: var(--bx-spacing-05) 0">
<Button on:click="{() => (group = ['Banana'])}">Set to ["Banana"]</Button>
</div>

View file

@ -8,9 +8,9 @@
</script>
<Toggle
bind:toggled
bind:toggled="{toggled}"
size="sm"
labelText="Trigger snippet overflow"
style="margin-bottom: var(--cds-spacing-05)"
style="margin-bottom: var(--bx-spacing-05)"
/>
<CodeSnippet type="multi" code="{code}" />

View file

@ -8,9 +8,9 @@
<Toggle
size="sm"
style="margin-bottom: var(--cds-spacing-05)"
style="margin-bottom: var(--bx-spacing-05)"
labelText="Show code snippets"
bind:toggled
bind:toggled="{toggled}"
/>
{#if toggled}

View file

@ -37,6 +37,6 @@
<style>
div {
margin: var(--cds-layout-01) 0 var(--cds-layout-03);
margin: var(--bx-spacing-05) 0 var(--bx-spacing-07);
}
</style>

View file

@ -4,7 +4,7 @@
let selectedIndex = 1;
</script>
<ContentSwitcher bind:selectedIndex>
<ContentSwitcher bind:selectedIndex="{selectedIndex}">
<Switch text="Latest news" />
<Switch text="Trending" />
<Switch text="Recommended" />
@ -24,6 +24,6 @@
<style>
div {
margin-top: var(--cds-spacing-05);
margin-top: var(--bx-spacing-05);
}
</style>

View file

@ -23,7 +23,10 @@
<ContextMenuOption indented labelText="Cut" shortcutText="⌘X" icon="{Cut}" />
<ContextMenuDivider />
<ContextMenuOption indented labelText="Export as">
<ContextMenuGroup labelText="Export options" bind:selectedIds>
<ContextMenuGroup
labelText="Export options"
bind:selectedIds="{selectedIds}"
>
<ContextMenuOption id="pdf" labelText="PDF" />
<ContextMenuOption id="txt" labelText="TXT" />
<ContextMenuOption id="mp3" labelText="MP3" />
@ -48,11 +51,11 @@
<style>
div {
position: absolute;
width: calc(100% - var(--cds-spacing-05));
height: calc(100% - var(--cds-spacing-06));
width: calc(100% - var(--bx-spacing-05));
height: calc(100% - var(--bx-spacing-06));
display: flex;
align-items: center;
justify-content: center;
color: var(--cds-text-02);
color: var(--bx-text-02);
}
</style>

View file

@ -14,7 +14,7 @@
<ContextMenu>
<ContextMenuOption indented labelText="Open" />
<ContextMenuDivider />
<ContextMenuRadioGroup bind:selectedId labelText="Radio group">
<ContextMenuRadioGroup bind:selectedId="{selectedId}" labelText="Radio group">
<ContextMenuOption id="0" labelText="Set as foreground" />
<ContextMenuOption id="1" labelText="Set as background" />
</ContextMenuRadioGroup>
@ -29,11 +29,11 @@
<style>
div {
position: absolute;
width: calc(100% - var(--cds-spacing-05));
height: calc(100% - var(--cds-spacing-06));
width: calc(100% - var(--bx-spacing-05));
height: calc(100% - var(--bx-spacing-06));
display: flex;
align-items: center;
justify-content: center;
color: var(--cds-text-02);
color: var(--bx-text-02);
}
</style>

View file

@ -46,15 +46,15 @@
<style>
div {
position: absolute;
width: calc(100% - var(--cds-spacing-05));
height: calc(100% - var(--cds-spacing-06));
width: calc(100% - var(--bx-spacing-05));
height: calc(100% - var(--bx-spacing-06));
display: flex;
align-items: center;
justify-content: center;
color: var(--cds-text-02);
color: var(--bx-text-02);
}
p {
outline: 1px solid var(--cds-interactive-01);
outline: 1px solid var(--bx-interactive-01);
}
</style>

View file

@ -51,15 +51,15 @@
<style>
div {
position: absolute;
width: calc(100% - var(--cds-spacing-05));
height: calc(100% - var(--cds-spacing-06));
width: calc(100% - var(--bx-spacing-05));
height: calc(100% - var(--bx-spacing-06));
display: flex;
align-items: center;
justify-content: center;
color: var(--cds-text-02);
color: var(--bx-text-02);
}
p {
outline: 1px solid var(--cds-interactive-01);
outline: 1px solid var(--bx-interactive-01);
}
</style>

View file

@ -37,6 +37,6 @@
<style>
div {
margin: var(--cds-layout-01) 0 var(--cds-layout-03);
margin: var(--bx-spacing-05) 0 var(--bx-spacing-07);
}
</style>

View file

@ -43,7 +43,7 @@
<style>
div {
margin-top: var(--cds-spacing-05);
padding: var(--cds-spacing-05);
margin-top: var(--bx-spacing-05);
padding: var(--bx-spacing-05);
}
</style>

View file

@ -39,6 +39,6 @@
<style>
div {
margin: var(--cds-layout-01) 0 var(--cds-layout-03);
margin: var(--bx-spacing-05) 0 var(--bx-spacing-07);
}
</style>

View file

@ -4,9 +4,9 @@
let value = null;
</script>
<NumberInput allowEmpty bind:value />
<NumberInput allowEmpty bind:value="{value}" />
<div style="margin: var(--cds-layout-01) 0">
<div style="margin: var(--bx-spacing-05) 0">
<Button on:click="{() => (value = null)}">Set to null</Button>
<Button on:click="{() => (value = 0)}">Set to 0</Button>
</div>

View file

@ -4,9 +4,9 @@
let page = 2;
</script>
<PaginationNav bind:page />
<PaginationNav bind:page="{page}" />
<div style="margin: var(--cds-layout-01) 0">
<div style="margin: var(--bx-spacing-05) 0">
<Button on:click="{() => (page = 1)}" disabled="{page === 0}">
Set page to 1
</Button>

View file

@ -8,13 +8,13 @@
<div bind:this="{ref}" style:position="relative">
<Button on:click="{() => (open = !open)}">Toggle popover</Button>
<Popover
bind:open
bind:open="{open}"
align="bottom-left"
on:click:outside="{({ detail }) => {
console.log('on:click:outside');
open = ref.contains(detail.target);
}}"
>
<div style="padding: var(--cds-spacing-05)">Content</div>
<div style="padding: var(--bx-spacing-05)">Content</div>
</Popover>
</div>

View file

@ -21,7 +21,7 @@
status="{status}"
/>
<ButtonSet style="margin-top: var(--cds-spacing-08)">
<ButtonSet style="margin-top: var(--bx-spacing-08)">
<Button
disabled="{value > 0}"
on:click="{() => {

View file

@ -9,7 +9,7 @@
let thirdStepCurrent = false;
</script>
<ProgressIndicator bind:currentIndex>
<ProgressIndicator bind:currentIndex="{currentIndex}">
<ProgressStep
complete
label="Step 1"
@ -32,7 +32,7 @@
/>
</ProgressIndicator>
<div style="margin: var(--cds-layout-02) 0">
<div style="margin: var(--bx-spacing-06) 0">
<Button
kind="{currentIndex === 2 ? 'secondary' : 'primary'}"
on:click="{() => {

View file

@ -20,7 +20,7 @@
{/each}
</RadioButtonGroup>
<div style="margin: var(--cds-layout-03) 0">
<div style="margin: var(--bx-layout-03) 0">
{#each plans as value (value)}
<Button
size="small"

View file

@ -6,7 +6,11 @@
let selected = values[1];
</script>
<TileGroup legend="Service pricing tiers" name="plan" bind:selected>
<TileGroup
legend="Service pricing tiers"
name="plan"
bind:selected="{selected}"
>
{#each values as value}
<RadioTile value="{value}">{value}</RadioTile>
{/each}
@ -26,6 +30,6 @@
<style>
div {
margin: var(--cds-spacing-05) 0;
margin: var(--bx-spacing-05) 0;
}
</style>

View file

@ -4,7 +4,7 @@
let value = "";
</script>
<Search bind:value />
<Search bind:value="{value}" />
<div>
<ButtonSet>
@ -30,6 +30,6 @@
<style>
div {
margin-top: var(--cds-spacing-05);
margin-top: var(--bx-spacing-05);
}
</style>

View file

@ -4,15 +4,14 @@
let selected = "g10";
</script>
<Select labelText="Carbon theme" bind:selected>
<Select labelText="Carbon theme" bind:selected="{selected}">
<SelectItem value="white" text="White" />
<SelectItem value="g10" text="Gray 10" />
<SelectItem value="g80" text="Gray 80" />
<SelectItem value="g90" text="Gray 90" />
<SelectItem value="g100" text="Gray 100" />
</Select>
<div style="margin: var(--cds-layout-01) 0">
<div style="margin: var(--bx-spacing-05) 0">
Selected: <strong>{selected}</strong>
</div>

View file

@ -4,7 +4,7 @@
let selected = 0;
</script>
<Tabs bind:selected>
<Tabs bind:selected="{selected}">
<Tab label="Tab label 1" />
<Tab label="Tab label 2" />
<Tab label="Tab label 3" />
@ -15,7 +15,7 @@
</svelte:fragment>
</Tabs>
<div style="margin: var(--cds-layout-01) 0">
<div style="margin: var(--bx-spacing-05) 0">
<Button on:click="{() => (selected = 1)}">Set index to 1</Button>
</div>

View file

@ -11,7 +11,7 @@
<Theme bind:theme />
<RadioButtonGroup legendText="Carbon theme" bind:selected="{theme}">
{#each ["white", "g10", "g80", "g90", "g100"] as value}
{#each ["white", "g10", "g90", "g100"] as value}
<RadioButton labelText="{value}" value="{value}" />
{/each}
</RadioButtonGroup>

View file

@ -8,10 +8,10 @@
let theme = "g90";
</script>
<Theme bind:theme persist persistKey="__carbon-theme" />
<Theme bind:theme="{theme}" persist persistKey="__carbon-theme" />
<RadioButtonGroup legendText="Carbon theme" bind:selected="{theme}">
{#each ["white", "g10", "g80", "g90", "g100"] as value}
{#each ["white", "g10", "g90", "g100"] as value}
<RadioButton labelText="{value}" value="{value}" />
{/each}
</RadioButtonGroup>

View file

@ -5,7 +5,7 @@
<Theme
render="toggle"
toggle="{{
themes: ['g10', 'g80'],
themes: ['g10', 'g90'],
labelA: 'Enable dark mode',
labelB: 'Enable dark mode',
hideLabel: true,

View file

@ -4,7 +4,7 @@
let toggled = true;
</script>
<Toggle labelText="Push notifications" bind:toggled />
<Toggle labelText="Push notifications" bind:toggled="{toggled}" />
<div>
<Button size="small" on:click="{() => (toggled = !toggled)}">
@ -17,6 +17,6 @@
<style>
div {
margin-top: var(--cds-spacing-05);
margin-top: var(--bx-spacing-05);
}
</style>

View file

@ -4,11 +4,11 @@
let open = true;
</script>
<Tooltip bind:open triggerText="Resource list" align="start">
<Tooltip bind:open="{open}" triggerText="Resource list" align="start">
<p>Resources are provisioned based on your account's organization.</p>
</Tooltip>
<div style="margin-top: var(--cds-spacing-12);">
<div style="margin-top: var(--bx-spacing-12);">
<Button size="small" on:click="{() => (open = !open)}">
{open ? "Close tooltip" : "Open tooltip"}
</Button>
@ -18,6 +18,6 @@
<style>
div {
margin-top: var(--cds-spacing-05);
margin-top: var(--bx-spacing-05);
}
</style>

View file

@ -48,8 +48,8 @@
<TreeView
labelText="Cloud Products"
children="{children}"
bind:activeId
bind:selectedIds
bind:activeId="{activeId}"
bind:selectedIds="{selectedIds}"
on:select="{({ detail }) => console.log('select', detail)}"
on:toggle="{({ detail }) => console.log('toggle', detail)}"
on:focus="{({ detail }) => console.log('focus', detail)}"
@ -60,6 +60,6 @@
<style>
div {
margin-top: var(--cds-spacing-05);
margin-top: var(--bx-spacing-05);
}
</style>

View file

@ -48,8 +48,8 @@
<TreeView
labelText="Cloud Products"
children="{children}"
bind:activeId
bind:selectedIds
bind:activeId="{activeId}"
bind:selectedIds="{selectedIds}"
on:select="{({ detail }) => console.log('select', detail)}"
on:toggle="{({ detail }) => console.log('toggle', detail)}"
on:focus="{({ detail }) => console.log('focus', detail)}"
@ -60,6 +60,6 @@
<style>
div {
margin-top: var(--cds-spacing-05);
margin-top: var(--bx-spacing-05);
}
</style>

View file

@ -51,13 +51,13 @@
<TreeView
bind:this="{treeview}"
bind:expandedIds
bind:expandedIds="{expandedIds}"
labelText="Cloud Products"
children="{children}"
/>
<style>
div {
margin-bottom: var(--cds-spacing-05);
margin-bottom: var(--bx-spacing-05);
}
</style>

View file

@ -59,13 +59,13 @@
<TreeView
bind:this="{treeview}"
bind:expandedIds
bind:expandedIds="{expandedIds}"
labelText="Cloud Products"
children="{children}"
/>
<style>
div {
margin-bottom: var(--cds-spacing-05);
margin-bottom: var(--bx-spacing-05);
}
</style>

View file

@ -56,6 +56,6 @@
<style>
div {
margin-bottom: var(--cds-spacing-05);
margin-bottom: var(--bx-spacing-05);
}
</style>

View file

@ -62,6 +62,6 @@
<style>
div {
margin-bottom: var(--cds-spacing-05);
margin-bottom: var(--bx-spacing-05);
}
</style>

View file

@ -49,9 +49,9 @@
<TreeView
labelText="Cloud Products"
children="{children}"
bind:activeId
bind:selectedIds
bind:expandedIds
bind:activeId="{activeId}"
bind:selectedIds="{selectedIds}"
bind:expandedIds="{expandedIds}"
on:select="{({ detail }) => console.log('select', detail)}"
on:toggle="{({ detail }) => console.log('toggle', detail)}"
on:focus="{({ detail }) => console.log('focus', detail)}"
@ -63,6 +63,6 @@
<style>
div {
margin-top: var(--cds-spacing-05);
margin-top: var(--bx-spacing-05);
}
</style>

View file

@ -77,8 +77,8 @@
<TreeView
labelText="Cloud Products"
children="{children}"
bind:activeId
bind:selectedIds
bind:activeId="{activeId}"
bind:selectedIds="{selectedIds}"
on:select="{({ detail }) => console.log('select', detail)}"
on:toggle="{({ detail }) => console.log('toggle', detail)}"
on:focus="{({ detail }) => console.log('focus', detail)}"
@ -89,6 +89,6 @@
<style>
div {
margin-top: var(--cds-spacing-05);
margin-top: var(--bx-spacing-05);
}
</style>

View file

@ -48,8 +48,8 @@
<TreeView
labelText="Cloud Products"
children="{children}"
bind:activeId
bind:selectedIds
bind:activeId="{activeId}"
bind:selectedIds="{selectedIds}"
on:select="{({ detail }) => console.log('select', detail)}"
on:toggle="{({ detail }) => console.log('toggle', detail)}"
on:focus="{({ detail }) => console.log('focus', detail)}"
@ -60,6 +60,6 @@
<style>
div {
margin-top: var(--cds-spacing-05);
margin-top: var(--bx-spacing-05);
}
</style>

View file

@ -28,7 +28,7 @@
];
</script>
<ButtonSet style="margin-bottom: var(--cds-spacing-05)">
<ButtonSet style="margin-bottom: var(--bx-spacing-05)">
{#each [nodeSpark, nodeBlockchain] as { id, text }}
<Button
on:click="{() => {

View file

@ -53,7 +53,7 @@
let:node
>
<span
style:color="{node.selected ? "var(--cds-interactive-04)" : "inherit"}"
style:color="{node.selected ? "var(--bx-interactive-04)" : "inherit"}"
style:text-decoration="{node.disabled ? "inherit" : "underline"}"
>
{node.text} (id: {node.id})

View file

@ -46,11 +46,11 @@
</script>
<TreeView
size="compact"
size="xs"
labelText="Cloud Products"
children="{children}"
bind:activeId
bind:selectedIds
bind:activeId="{activeId}"
bind:selectedIds="{selectedIds}"
on:select="{({ detail }) => console.log('select', detail)}"
on:toggle="{({ detail }) => console.log('toggle', detail)}"
on:focus="{({ detail }) => console.log('focus', detail)}"
@ -61,6 +61,6 @@
<style>
div {
margin-top: var(--cds-spacing-05);
margin-top: var(--bx-spacing-05);
}
</style>

View file

@ -67,10 +67,10 @@
</svelte:fragment>
<HeaderUtilities>
<HeaderSearch
bind:ref
bind:active
bind:value
bind:selectedResultIndex
bind:ref="{ref}"
bind:active="{active}"
bind:value="{value}"
bind:selectedResultIndex="{selectedResultIndex}"
placeholder="Search services"
results="{results}"
on:active="{() => {

View file

@ -15,7 +15,7 @@
// NOTE: we *do not* want to persist the theme as this can
// conflict with how the iframe is displayed in the docs.
// Instead, we want the theme to be overridden in the standalone page.
if (["white", "g10", "g80", "g90", "g100"].includes(current_theme)) {
if (["white", "g10", "g90", "g100"].includes(current_theme)) {
document.documentElement.setAttribute("theme", current_theme);
document.documentElement.style.setProperty(
"color-scheme",
@ -31,11 +31,11 @@
:global(body.framed) {
min-height: 100vh;
width: 100%;
padding: var(--cds-spacing-06) var(--cds-spacing-05);
padding: var(--bx-spacing-06) var(--bx-spacing-05);
}
:global(.framed :not(.bx--content) [class^="bx--col"]) {
outline: 1px solid var(--cds-interactive-04);
outline: 1px solid var(--bx-interactive-04);
}
:global(.framed .bx--content [class^="bx--col"]) {