diff --git a/src/elements/selection-expansion-panel/selection-expansion-panel.visual.spec.ts b/src/elements/selection-expansion-panel/selection-expansion-panel.visual.spec.ts
new file mode 100644
index 0000000000..690454ae31
--- /dev/null
+++ b/src/elements/selection-expansion-panel/selection-expansion-panel.visual.spec.ts
@@ -0,0 +1,152 @@
+import { html, nothing, type TemplateResult } from 'lit';
+
+import {
+ describeEach,
+ describeViewports,
+ visualDiffDefault,
+ visualDiffFocus,
+ visualRegressionFixture,
+} from '../core/testing/private.js';
+
+import './selection-expansion-panel.js';
+import '../card/card-badge.js';
+import '../checkbox/checkbox-panel.js';
+import '../checkbox/checkbox-group.js';
+import '../form-error.js';
+import '../icon.js';
+import '../link/block-link-button.js';
+import '../radio-button/radio-button-panel.js';
+import '../radio-button/radio-button-group.js';
+
+describe(`sbb-selection-expansion-panel`, () => {
+ let root: HTMLElement;
+
+ const cases = {
+ borderless: [false, true],
+ checked: [false, true],
+ color: ['white', 'milk'],
+ disabled: [false, true],
+ };
+
+ const inputPanelContent = (): TemplateResult => html`
+ Value one
+ Subtext
+
+
+
+ CHF 40.00
+
+
+ %
+ `;
+
+ const innerContent = (): TemplateResult => html`
+
+ Inner Content
+
+ Link
+
+
+ `;
+
+ type ParamsType = { [K in keyof typeof cases]: (typeof cases)[K][number] } & {
+ forceOpen?: boolean;
+ value?: string;
+ };
+ const withCheckboxPanel = (params: Partial): TemplateResult => html`
+
+
+ ${inputPanelContent()}
+
+ ${innerContent()}
+
+ `;
+
+ const withRadioPanel = (params: Partial): TemplateResult => html`
+
+
+ ${inputPanelContent()}
+
+ ${innerContent()}
+
+ `;
+
+ describeViewports({ viewports: ['zero', 'medium'] }, () => {
+ for (const input of ['checkbox', 'radio']) {
+ describe(`with ${input}`, () => {
+ describeEach(cases, (params) => {
+ beforeEach(async function () {
+ root = await visualRegressionFixture(html`
+ ${input === 'checkbox' ? withCheckboxPanel(params) : withRadioPanel(params)}
+ `);
+ });
+
+ it(
+ visualDiffDefault.name,
+ visualDiffDefault.with((setup) => {
+ setup.withSnapshotElement(root);
+ }),
+ );
+ });
+
+ for (const state of [visualDiffDefault, visualDiffFocus]) {
+ it(
+ `force-open ${state.name}`,
+ state.with(async (setup) => {
+ await setup.withFixture(html`
+ ${input === 'checkbox'
+ ? withCheckboxPanel({ forceOpen: true })
+ : withRadioPanel({ forceOpen: true })}
+ `);
+ }),
+ );
+ }
+ });
+
+ it(
+ `checkbox group with error`,
+ visualDiffDefault.with(async (setup) => {
+ await setup.withFixture(html`
+
+ ${withCheckboxPanel({ checked: true })} ${withCheckboxPanel({})}
+ ${withCheckboxPanel({})}
+
+ Error message
+ `);
+ }),
+ );
+
+ it(
+ `radio button group with error`,
+ visualDiffDefault.with(async (setup) => {
+ await setup.withFixture(html`
+
+ ${withRadioPanel({ checked: true, value: '1' })} ${withRadioPanel({ value: '2' })}
+ ${withRadioPanel({ value: '3' })}
+
+ Error message
+ `);
+ }),
+ );
+ }
+ });
+});