diff --git a/2nd-gen/packages/core/components/accordion/Accordion.base.ts b/2nd-gen/packages/core/components/accordion/Accordion.base.ts
new file mode 100644
index 00000000000..883ad39f1ea
--- /dev/null
+++ b/2nd-gen/packages/core/components/accordion/Accordion.base.ts
@@ -0,0 +1,208 @@
+/**
+ * Copyright 2026 Adobe. All rights reserved.
+ * This file is licensed to you under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License. You may obtain a copy
+ * of the License at http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under
+ * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
+ * OF ANY KIND, either express or implied. See the License for the specific language
+ * governing permissions and limitations under the License.
+ */
+
+import { PropertyValues } from 'lit';
+import { property } from 'lit/decorators.js';
+
+import { SpectrumElement } from '@spectrum-web-components/core/element/index.js';
+import { SizedMixin } from '@spectrum-web-components/core/mixins/index.js';
+
+import {
+ ACCORDION_VALID_SIZES,
+ type AccordionDensity,
+ type AccordionHeadingLevel,
+ type AccordionSize,
+ SWC_ACCORDION_ITEM_TOGGLE_EVENT,
+} from './Accordion.types.js';
+import { AccordionItemBase } from './AccordionItem.base.js';
+
+/**
+ * Base class for accordion components. Manages item propagation, heading
+ * level, density, and the exclusive-open constraint.
+ *
+ * @attribute {boolean} allowMultiple - Reflected as `allow-multiple`. When set,
+ * multiple items may be open at the same time.
+ * @attribute {number} level - Heading level (2–6) applied to every item header.
+ * Values outside that range are clamped.
+ * @attribute {AccordionSize} size - Size applied to all items.
+ * @attribute {AccordionDensity} density - Vertical spacing between items.
+ * @attribute {boolean} quiet - Renders the accordion in its quiet visual variant.
+ * @attribute {boolean} disabled - Disables all items in the accordion.
+ *
+ * @slot - One or more `swc-accordion-item` elements.
+ */
+export abstract class AccordionBase extends SizedMixin(SpectrumElement, {
+ validSizes: ACCORDION_VALID_SIZES,
+ defaultSize: 'm',
+}) {
+ // ──────────────────
+ // PUBLIC API
+ // ──────────────────
+
+ /**
+ * When set, multiple items may be open at the same time. By default only
+ * one item can be open.
+ */
+ @property({ type: Boolean, reflect: true, attribute: 'allow-multiple' })
+ public allowMultiple: boolean = false;
+
+ /**
+ * Heading level applied to every item header (2–6). Defaults to 3.
+ * Values outside that range are clamped.
+ */
+ @property({ type: Number, reflect: true })
+ public level: AccordionHeadingLevel = 3;
+
+ /**
+ * Size applied to all items. Defaults to `m`.
+ */
+ declare public size: AccordionSize;
+
+ /**
+ * Controls vertical spacing between items.
+ *
+ * @default regular
+ */
+ @property({ type: String, reflect: true })
+ public density: AccordionDensity = 'regular';
+
+ /**
+ * Renders the accordion in its quiet (no-border) visual variant.
+ */
+ @property({ type: Boolean, reflect: true })
+ public quiet: boolean = false;
+
+ /**
+ * Disables all items in the accordion. Individual items may also be
+ * disabled independently.
+ */
+ @property({ type: Boolean, reflect: true })
+ public disabled: boolean = false;
+
+ // ──────────────────────
+ // IMPLEMENTATION
+ // ──────────────────────
+
+ private assignedItems(): AccordionItemBase[] {
+ const slot = this.renderRoot?.querySelector('slot');
+ if (!slot) {
+ return [];
+ }
+ return slot
+ .assignedElements({ flatten: true })
+ .filter((el): el is AccordionItemBase => el instanceof AccordionItemBase);
+ }
+
+ private closeSiblingsOnOpen = (event: Event): void => {
+ if (this.disabled) {
+ event.preventDefault();
+ return;
+ }
+ if (this.allowMultiple) {
+ return;
+ }
+ const toggling = event.target;
+ if (!(toggling instanceof AccordionItemBase)) {
+ return;
+ }
+ // Defer until after dispatch returns so that a canceled toggle (where the
+ // item reverts open back to false) does not incorrectly close siblings.
+ queueMicrotask(() => {
+ if (!toggling.open) {
+ return;
+ }
+ for (const item of this.assignedItems()) {
+ if (item !== toggling) {
+ item.open = false;
+ }
+ }
+ });
+ };
+
+ protected syncAccordionItems(): void {
+ for (const item of this.assignedItems()) {
+ item.setManagedHeading(this.level);
+ item.size = this.size;
+ item.setManagedParentDisabled(this.disabled);
+ }
+ }
+
+ private enforceExclusiveOpen(): void {
+ let foundOpen = false;
+ for (const item of this.assignedItems()) {
+ if (item.open) {
+ if (foundOpen) {
+ item.open = false;
+ } else {
+ foundOpen = true;
+ }
+ }
+ }
+ }
+
+ public override connectedCallback(): void {
+ super.connectedCallback();
+ this.addEventListener(
+ SWC_ACCORDION_ITEM_TOGGLE_EVENT,
+ this.closeSiblingsOnOpen
+ );
+ }
+
+ public override disconnectedCallback(): void {
+ super.disconnectedCallback();
+ this.removeEventListener(
+ SWC_ACCORDION_ITEM_TOGGLE_EVENT,
+ this.closeSiblingsOnOpen
+ );
+ }
+
+ protected override update(changedProperties: PropertyValues): void {
+ if (changedProperties.has('level')) {
+ const clamped = Math.min(
+ 6,
+ Math.max(2, this.level)
+ ) as AccordionHeadingLevel;
+ if (this.level !== clamped) {
+ this.level = clamped;
+ }
+ }
+ if (
+ changedProperties.has('level') ||
+ changedProperties.has('size') ||
+ changedProperties.has('disabled')
+ ) {
+ this.syncAccordionItems();
+ }
+ // changedProperties.get() returns the previous value; this fires only when
+ // disabled transitions from true → false (re-enable).
+ if (
+ changedProperties.has('disabled') &&
+ changedProperties.get('disabled') === true &&
+ !this.allowMultiple
+ ) {
+ this.enforceExclusiveOpen();
+ }
+ super.update(changedProperties);
+ }
+
+ protected override firstUpdated(changedProperties: PropertyValues): void {
+ super.firstUpdated(changedProperties);
+ if (window.__swc?.DEBUG && !this.hasAttribute('density')) {
+ window.__swc.warn(
+ this,
+ `<${this.localName}> should have an explicit "density" attribute set. Defaulting to "regular".`,
+ 'https://opensource.adobe.com/spectrum-web-components/components/accordion/',
+ { type: 'api', level: 'low' }
+ );
+ }
+ }
+}
diff --git a/2nd-gen/packages/core/components/accordion/Accordion.types.ts b/2nd-gen/packages/core/components/accordion/Accordion.types.ts
new file mode 100644
index 00000000000..fbf4da59f9b
--- /dev/null
+++ b/2nd-gen/packages/core/components/accordion/Accordion.types.ts
@@ -0,0 +1,33 @@
+/**
+ * Copyright 2026 Adobe. All rights reserved.
+ * This file is licensed to you under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License. You may obtain a copy
+ * of the License at http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under
+ * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
+ * OF ANY KIND, either express or implied. See the License for the specific language
+ * governing permissions and limitations under the License.
+ */
+
+import type { ElementSize } from '@spectrum-web-components/core/mixins/index.js';
+
+export const ACCORDION_VALID_SIZES = [
+ 's',
+ 'm',
+ 'l',
+ 'xl',
+] as const satisfies readonly ElementSize[];
+export type AccordionSize = (typeof ACCORDION_VALID_SIZES)[number];
+
+export const ACCORDION_DENSITIES = ['compact', 'regular', 'spacious'] as const;
+export type AccordionDensity = (typeof ACCORDION_DENSITIES)[number];
+
+export const ACCORDION_HEADING_LEVELS = [2, 3, 4, 5, 6] as const;
+export type AccordionHeadingLevel = (typeof ACCORDION_HEADING_LEVELS)[number];
+
+export const SWC_ACCORDION_ITEM_TOGGLE_EVENT = 'swc-accordion-item-toggle';
+export const SWC_ACCORDION_ITEM_OPEN_EVENT = 'swc-open';
+export const SWC_ACCORDION_ITEM_CLOSE_EVENT = 'swc-close';
+export const SWC_ACCORDION_ITEM_AFTER_OPEN_EVENT = 'swc-after-open';
+export const SWC_ACCORDION_ITEM_AFTER_CLOSE_EVENT = 'swc-after-close';
diff --git a/2nd-gen/packages/core/components/accordion/AccordionItem.base.ts b/2nd-gen/packages/core/components/accordion/AccordionItem.base.ts
new file mode 100644
index 00000000000..950f61cf9c2
--- /dev/null
+++ b/2nd-gen/packages/core/components/accordion/AccordionItem.base.ts
@@ -0,0 +1,183 @@
+/**
+ * Copyright 2026 Adobe. All rights reserved.
+ * This file is licensed to you under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License. You may obtain a copy
+ * of the License at http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under
+ * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
+ * OF ANY KIND, either express or implied. See the License for the specific language
+ * governing permissions and limitations under the License.
+ */
+
+import { property, state } from 'lit/decorators.js';
+
+import { SpectrumElement } from '@spectrum-web-components/core/element/index.js';
+import { ObserveSlotPresence } from '@spectrum-web-components/core/mixins/observe-slot-presence.js';
+
+import {
+ type AccordionHeadingLevel,
+ type AccordionSize,
+ SWC_ACCORDION_ITEM_AFTER_CLOSE_EVENT,
+ SWC_ACCORDION_ITEM_AFTER_OPEN_EVENT,
+ SWC_ACCORDION_ITEM_CLOSE_EVENT,
+ SWC_ACCORDION_ITEM_OPEN_EVENT,
+ SWC_ACCORDION_ITEM_TOGGLE_EVENT,
+} from './Accordion.types.js';
+
+/**
+ * Base class for accordion item components. Manages open/disabled state,
+ * heading level (set by the parent accordion), and the toggle event.
+ *
+ * @attribute {boolean} open - Whether the accordion item panel is expanded.
+ * @attribute {boolean} disabled - Whether the accordion item is disabled.
+ * @attribute {AccordionSize} size - Size of the item. Inherited from the parent
+ * accordion when slotted; controls the chevron icon when used standalone.
+ *
+ * @slot label - The heading text for this accordion item.
+ * @slot actions - Optional actions rendered adjacent to the heading, outside
+ * the toggle button so they remain independently interactive.
+ * @slot - The panel content revealed when the item is open.
+ */
+export abstract class AccordionItemBase extends ObserveSlotPresence(
+ SpectrumElement,
+ '[slot="actions"]'
+) {
+ // ──────────────────
+ // PUBLIC API
+ // ──────────────────
+
+ /**
+ * Whether the accordion item panel is expanded.
+ */
+ @property({ type: Boolean, reflect: true })
+ public get open(): boolean {
+ return this._open;
+ }
+
+ public set open(value: boolean) {
+ if (this.hasUpdated && !this.mayExpand() && value !== this._open) {
+ return;
+ }
+ if (value === this._open) {
+ return;
+ }
+ const oldValue = this._open;
+ this._open = value;
+ if (value) {
+ this.setAttribute('open', '');
+ } else {
+ this.removeAttribute('open');
+ }
+ this.requestUpdate('open', oldValue);
+ }
+
+ /**
+ * Whether the accordion item is disabled. A disabled item keeps its header
+ * in the tab order but blocks toggling.
+ */
+ @property({ type: Boolean, reflect: true })
+ public disabled: boolean = false;
+
+ /**
+ * The size of the item. Inherited from the parent accordion; controls which
+ * chevron icon is displayed. Has no effect when the item is used standalone.
+ */
+ @property({ type: String, reflect: true })
+ public size?: AccordionSize;
+
+ private _open = false;
+
+ // ──────────────────────
+ // INTERNAL STATE
+ // ──────────────────────
+
+ /**
+ * @internal
+ * Heading level (2–6) propagated by the parent accordion. Defaults to 3
+ * for standalone items.
+ */
+ @state()
+ protected headingLevel: AccordionHeadingLevel = 3;
+
+ /**
+ * @internal
+ * Set by the parent accordion when its own `disabled` is true. Causes the
+ * item to render as disabled (aria-disabled + inert panel) without clobbering
+ * the item's own `disabled` property, so the per-item state is preserved
+ * when the accordion is re-enabled.
+ */
+ @state()
+ protected parentDisabled: boolean = false;
+
+ // ──────────────────────
+ // IMPLEMENTATION
+ // ──────────────────────
+
+ /**
+ * @internal
+ * Whether the item may change `open` (expand or collapse). When false, the
+ * `open` setter and `toggle()` leave state unchanged.
+ */
+ protected mayExpand(): boolean {
+ return !this.disabled && !this.parentDisabled;
+ }
+
+ /**
+ * @internal
+ * Toggles the item open state. Guards for disabled, flips `open`, dispatches
+ * the toggle event, and reverts if the event is canceled. On success, dispatches
+ * `swc-after-open` or `swc-after-close` after the next render cycle.
+ */
+ protected toggle(): void {
+ if (!this.mayExpand()) {
+ return;
+ }
+ this.open = !this.open;
+ const toggleEvent = new Event(SWC_ACCORDION_ITEM_TOGGLE_EVENT, {
+ bubbles: true,
+ composed: true,
+ cancelable: true,
+ });
+ if (!this.dispatchEvent(toggleEvent)) {
+ this.open = !this.open;
+ return;
+ }
+ const isOpen = this.open;
+ this.dispatchEvent(
+ new Event(
+ isOpen ? SWC_ACCORDION_ITEM_OPEN_EVENT : SWC_ACCORDION_ITEM_CLOSE_EVENT,
+ {
+ bubbles: true,
+ composed: true,
+ }
+ )
+ );
+ void this.updateComplete.then(() => {
+ this.dispatchEvent(
+ new Event(
+ isOpen
+ ? SWC_ACCORDION_ITEM_AFTER_OPEN_EVENT
+ : SWC_ACCORDION_ITEM_AFTER_CLOSE_EVENT,
+ { bubbles: true, composed: true }
+ )
+ );
+ });
+ }
+
+ /**
+ * @internal
+ * Synchronizes parent-managed heading level onto the item.
+ */
+ public setManagedHeading(heading: AccordionHeadingLevel): void {
+ this.headingLevel = heading;
+ }
+
+ /**
+ * @internal
+ * Synchronizes parent-managed disabled state onto the item.
+ */
+ public setManagedParentDisabled(disabled: boolean): void {
+ this.parentDisabled = disabled;
+ }
+}
diff --git a/2nd-gen/packages/core/components/accordion/index.ts b/2nd-gen/packages/core/components/accordion/index.ts
new file mode 100644
index 00000000000..058e18a5674
--- /dev/null
+++ b/2nd-gen/packages/core/components/accordion/index.ts
@@ -0,0 +1,15 @@
+/**
+ * Copyright 2026 Adobe. All rights reserved.
+ * This file is licensed to you under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License. You may obtain a copy
+ * of the License at http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under
+ * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
+ * OF ANY KIND, either express or implied. See the License for the specific language
+ * governing permissions and limitations under the License.
+ */
+
+export * from './Accordion.base.js';
+export * from './AccordionItem.base.js';
+export * from './Accordion.types.js';
diff --git a/2nd-gen/packages/core/package.json b/2nd-gen/packages/core/package.json
index 86b4009e996..b4626a67e89 100644
--- a/2nd-gen/packages/core/package.json
+++ b/2nd-gen/packages/core/package.json
@@ -19,6 +19,10 @@
"types": "./dist/components/alert-banner/index.d.ts",
"import": "./dist/components/alert-banner/index.js"
},
+ "./components/accordion": {
+ "types": "./dist/components/accordion/index.d.ts",
+ "import": "./dist/components/accordion/index.js"
+ },
"./components/asset": {
"types": "./dist/components/asset/index.d.ts",
"import": "./dist/components/asset/index.js"
@@ -148,6 +152,9 @@
"components/alert-banner": [
"dist/components/alert-banner/index.d.ts"
],
+ "components/accordion": [
+ "dist/components/accordion/index.d.ts"
+ ],
"components/asset": [
"dist/components/asset/index.d.ts"
],
diff --git a/2nd-gen/packages/swc/.storybook/preview.ts b/2nd-gen/packages/swc/.storybook/preview.ts
index 73e4673e0ab..68e75baf54d 100644
--- a/2nd-gen/packages/swc/.storybook/preview.ts
+++ b/2nd-gen/packages/swc/.storybook/preview.ts
@@ -324,11 +324,7 @@ const preview = {
'Components',
[
'Accordion',
- [
- 'Accessibility migration analysis',
- 'Migration plan',
- 'Rendering and styling migration analysis',
- ],
+ ['Accessibility migration analysis', 'Migration plan'],
'Action button',
['Rendering and styling migration analysis'],
'Action group',
diff --git a/2nd-gen/packages/swc/components/accordion/Accordion.ts b/2nd-gen/packages/swc/components/accordion/Accordion.ts
new file mode 100644
index 00000000000..92d112150e6
--- /dev/null
+++ b/2nd-gen/packages/swc/components/accordion/Accordion.ts
@@ -0,0 +1,45 @@
+/**
+ * Copyright 2026 Adobe. All rights reserved.
+ * This file is licensed to you under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License. You may obtain a copy
+ * of the License at http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under
+ * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
+ * OF ANY KIND, either express or implied. See the License for the specific language
+ * governing permissions and limitations under the License.
+ */
+
+import { CSSResultArray, html, TemplateResult } from 'lit';
+
+import { AccordionBase } from '@spectrum-web-components/core/components/accordion';
+
+import styles from './accordion.css';
+
+/**
+ * An accordion component that groups expandable content sections.
+ *
+ * @element swc-accordion
+ * @since 2.0.0
+ *
+ * @example
+ *