+ ${variants.map((linkVariant) => {
+ const row = renderAnchor({
+ prefix,
+ variant: linkVariant,
+ context,
+ size,
+ quiet,
+ inline,
+ lang,
+ href,
+ text: showAllVariants ? `${text} (${linkVariant})` : text,
+ showAllVariants,
+ });
+
+ const content =
+ context === 'prose'
+ ? html`
+
${row}
+ `
+ : row;
+
+ return html`
+
+ ${showAllVariants
+ ? html`
+
+ `
+ : null}
+ ${wrapStaticDemo(linkVariant, content)}
+
+ `;
+ })}
+
+ `;
+}
diff --git a/2nd-gen/packages/swc/components/typography/migration-guide.mdx b/2nd-gen/packages/swc/components/typography/migration-guide.mdx
index a3f05ca080e..ba4f701285e 100644
--- a/2nd-gen/packages/swc/components/typography/migration-guide.mdx
+++ b/2nd-gen/packages/swc/components/typography/migration-guide.mdx
@@ -39,12 +39,13 @@ import '@adobe/spectrum-wc/typography.css';
### Added in Spectrum 2
-| Addition | Notes |
-| ------------------------------------------- | ---------------------------------------------------------------------- |
-| `.swc-Title` class | New class for section and card headings |
-| `.swc-Typography--prose` modifier | Document wrapper that applies consistent margins to all child elements |
-| `.swc-Typography--emphasized` modifier | Applies italic styling to the element |
-| `--margins` modifier on individual elements | Apply margins to a single element without a wrapper |
+| Addition | Notes |
+| ------------------------------------------- | ----------------------------------------------------------------------- |
+| `.swc-Title` class | New class for section and card headings |
+| `.swc-Typography--prose` modifier | Document wrapper that applies consistent margins to all child elements |
+| `.swc-Typography--links` modifier | Link lists, footers, and sidebars — default styles for child `` elements inside **`.swc-Typography--prose`** or **`.swc-Typography--links`** receive default Spectrum link styling when `typography.css` is loaded. Anchors inherit surrounding typography in prose; import `@adobe/spectrum-wc/link.css` and apply `.swc-Link` modifier classes when you need standalone or secondary / quiet / static-color treatments. See the [Link migration guide](../link/migration-guide.mdx).
+
+```html
+
+
+
+```
+
+### 4. Remove light variants
The `--light` modifier has been removed from both Heading and Detail. Choose a size that produces the desired visual weight in your layout.
diff --git a/2nd-gen/packages/swc/components/typography/stories/typography.stories.ts b/2nd-gen/packages/swc/components/typography/stories/typography.stories.ts
index 28d9c622e97..434c71e40a5 100644
--- a/2nd-gen/packages/swc/components/typography/stories/typography.stories.ts
+++ b/2nd-gen/packages/swc/components/typography/stories/typography.stories.ts
@@ -224,6 +224,7 @@ export const MarginsModifier: Story = {
* - `h3` - Title, size L
* - `h4` - Title, size M
* - `p, li` - Body, size M
+ * - `a` - Default link styling (inherits body typography in prose)
*/
export const ProseContainer: Story = {
args: {
@@ -238,9 +239,11 @@ export const ProseContainer: Story = {
Semantic H1
Semantic H2
- Semantic paragraph. Lorem ipsum dolor sit amet, consectetur adipiscing
- elit. Donec eleifend est mollis ligula lobortis, tempus ultricies sapien
- lacinia.
+ Semantic paragraph with an
+ inline link
+ that inherits body typography. Lorem ipsum dolor sit amet, consectetur
+ adipiscing elit. Donec eleifend est mollis ligula lobortis, tempus
+ ultricies sapien lacinia.
Semantic H3
@@ -266,3 +269,23 @@ export const ProseContainer: Story = {
`,
};
+
+/**
+ * Link lists in footers, sidebars, and navigation regions use
+ * `.swc-Typography--links` so child `` elements receive default link
+ * styling without per-link classes. See [Link migration guide](/docs/link-migration-guide--docs)
+ * for modifier classes on individual anchors.
+ */
+export const LinkList: Story = {
+ tags: ['options'],
+ render: () => html`
+
+ `,
+};
diff --git a/2nd-gen/packages/swc/package.json b/2nd-gen/packages/swc/package.json
index dc0f0167ab1..0399dfa6b4a 100644
--- a/2nd-gen/packages/swc/package.json
+++ b/2nd-gen/packages/swc/package.json
@@ -41,6 +41,12 @@
"./global-elements.css": {
"default": "./dist/global-elements.css"
},
+ "./global-link.css": {
+ "default": "./dist/global-link.css"
+ },
+ "./link.css": {
+ "default": "./dist/link.css"
+ },
"./patterns/*": {
"types": "./dist/patterns/*/index.d.ts",
"import": "./dist/patterns/*/index.js"
diff --git a/2nd-gen/packages/swc/stylesheets/global/global-link.css b/2nd-gen/packages/swc/stylesheets/global/global-link.css
new file mode 100644
index 00000000000..c98a8a3344b
--- /dev/null
+++ b/2nd-gen/packages/swc/stylesheets/global/global-link.css
@@ -0,0 +1,109 @@
+/**
+ * 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.
+ */
+
+/**
+ * Opt-in baseline styling for bare `` elements application-wide.
+ *
+ * Import explicitly when the app should apply standalone Spectrum link presentation
+ * without a wrapper class or per-link BEM classes. Not included in `swc.css` and
+ * intentionally outside cascade layers so it remains easy to override.
+ *
+ * Modifier classes (`.swc-Link--secondary`, etc.) live in `link.css` — import that
+ * file alongside this one when anchors need explicit presentation control.
+ */
+
+@import url("../link.css");
+
+@media (forced-colors: active) {
+ a:where(:not([class])) {
+ --_swc-link-high-contrast-text-color: LinkText;
+ --_swc-link-high-contrast-focus-indicator-color: LinkText;
+ }
+}
+
+a:where(:not([class])) {
+ --_swc-link-focus-indicator-thickness: token("focus-indicator-thickness");
+ --_swc-link-focus-indicator-gap: token("focus-indicator-gap");
+ --_swc-link-corner-radius: token("corner-radius-100");
+ --_swc-link-font-family: token("sans-serif-font");
+ --_swc-link-line-height: token("line-height-100");
+ --_swc-link-line-height-cjk: token("cjk-line-height-100");
+ --_swc-link-font-size: token("font-size-100");
+ --_swc-link-font-style: token("default-font-style");
+ --_swc-link-font-weight: token("medium-font-weight");
+ --_swc-link-inline-font-weight: token("regular-font-weight");
+ --_swc-link-text-underline-thickness: token("text-underline-thickness");
+ --_swc-link-text-underline-gap: token("text-underline-gap");
+ --_swc-link-text-color: var(
+ --swc-link-text-color,
+ token("accent-content-color-default")
+ );
+
+ text-decoration-skip: objects;
+ font-family: var(--swc-link-font-family, var(--_swc-link-font-family));
+ font-size: var(--swc-link-font-size, var(--_swc-link-font-size));
+ font-style: var(--swc-link-font-style, var(--_swc-link-font-style));
+ font-weight: var(--swc-link-font-weight, var(--_swc-link-font-weight));
+ line-height: var(--swc-link-line-height, var(--_swc-link-line-height));
+ color: var(--_swc-link-high-contrast-text-color, var(--_swc-link-text-color));
+ text-decoration: underline;
+ text-decoration-thickness: var(
+ --swc-link-text-underline-thickness,
+ var(--_swc-link-text-underline-thickness)
+ );
+ text-underline-offset: var(
+ --swc-link-text-underline-gap,
+ var(--_swc-link-text-underline-gap)
+ );
+ background-color: transparent;
+ cursor: pointer;
+ outline: none;
+ transition: color token("animation-duration-100") ease-in-out;
+
+ &:hover {
+ --_swc-link-text-color: var(
+ --swc-link-text-color-hover,
+ token("accent-content-color-hover")
+ );
+ }
+
+ &:active {
+ --_swc-link-text-color: var(
+ --swc-link-text-color-down,
+ token("accent-content-color-down")
+ );
+ }
+
+ &:focus-visible {
+ --_swc-link-text-color: var(
+ --swc-link-text-color-focus,
+ token("accent-content-color-key-focus")
+ );
+
+ border-radius: var(--swc-link-corner-radius, var(--_swc-link-corner-radius));
+ outline: var(--_swc-link-focus-indicator-thickness) solid
+ var(
+ --_swc-link-high-contrast-focus-indicator-color,
+ var(--swc-link-focus-indicator-color, token("focus-indicator-color"))
+ );
+ outline-offset: var(--_swc-link-focus-indicator-gap);
+ }
+
+ &:lang(ja),
+ &:lang(zh),
+ &:lang(ko) {
+ line-height: var(
+ --swc-link-line-height-cjk,
+ var(--_swc-link-line-height-cjk)
+ );
+ }
+}
diff --git a/2nd-gen/packages/swc/stylesheets/link.css b/2nd-gen/packages/swc/stylesheets/link.css
new file mode 100644
index 00000000000..6f082294655
--- /dev/null
+++ b/2nd-gen/packages/swc/stylesheets/link.css
@@ -0,0 +1,125 @@
+/**
+ * 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.
+ */
+
+/**
+ * Standalone link presentation for native `` elements.
+ *
+ * Default anchor appearance inside `.swc-Typography--prose` and
+ * `.swc-Typography--links` ships with `typography.css` (generated). Import this
+ * stylesheet when authors need explicit BEM modifiers on anchors.
+ *
+ * @cssprop --swc-link-text-color - Link text color
+ * @cssprop --swc-link-text-color-hover - Link text color on hover
+ * @cssprop --swc-link-text-color-down - Link text color on active
+ * @cssprop --swc-link-text-color-focus - Link text color on focus-visible
+ * @cssprop --swc-link-focus-indicator-color - Focus ring color
+ * @cssprop --swc-link-font-family - Standalone link font family
+ * @cssprop --swc-link-font-size - Standalone link font size
+ * @cssprop --swc-link-font-weight - Standalone link font weight
+ * @cssprop --swc-link-inline-font-weight - Inline link font weight override
+ * @cssprop --swc-link-line-height - Standalone link line height
+ * @cssprop --swc-link-line-height-cjk - CJK standalone link line height
+ */
+
+@media (forced-colors: active) {
+ .swc-Link {
+ --_swc-link-high-contrast-text-color: LinkText;
+ --_swc-link-high-contrast-focus-indicator-color: LinkText;
+ }
+}
+
+.swc-Link {
+ --_swc-link-focus-indicator-thickness: token("focus-indicator-thickness");
+ --_swc-link-focus-indicator-gap: token("focus-indicator-gap");
+ --_swc-link-corner-radius: token("corner-radius-100");
+ --_swc-link-font-family: token("sans-serif-font");
+ --_swc-link-line-height: token("line-height-100");
+ --_swc-link-line-height-cjk: token("cjk-line-height-100");
+ --_swc-link-font-size: token("font-size-100");
+ --_swc-link-font-style: token("default-font-style");
+ --_swc-link-font-weight: token("medium-font-weight");
+ --_swc-link-inline-font-weight: token("regular-font-weight");
+ --_swc-link-text-underline-thickness: token("text-underline-thickness");
+ --_swc-link-text-underline-gap: token("text-underline-gap");
+ --_swc-link-text-color: var(--swc-link-text-color, token("accent-content-color-default"));
+
+ font-family: var(--swc-link-font-family, var(--_swc-link-font-family));
+ font-size: var(--swc-link-font-size, var(--_swc-link-font-size));
+ font-style: var(--swc-link-font-style, var(--_swc-link-font-style));
+ font-weight: var(--swc-link-font-weight, var(--_swc-link-font-weight));
+ line-height: var(--swc-link-line-height, var(--_swc-link-line-height));
+ color: var(--_swc-link-high-contrast-text-color, var(--_swc-link-text-color));
+ text-decoration: underline;
+ text-decoration-thickness: var(--swc-link-text-underline-thickness, var(--_swc-link-text-underline-thickness));
+ text-underline-offset: var(--swc-link-text-underline-gap, var(--_swc-link-text-underline-gap));
+ background-color: transparent;
+ cursor: pointer;
+ outline: none;
+ transition: color token("animation-duration-100") ease-in-out;
+
+ &:hover {
+ --_swc-link-text-color: var(--swc-link-text-color-hover, token("accent-content-color-hover"));
+ }
+
+ &:active {
+ --_swc-link-text-color: var(--swc-link-text-color-down, token("accent-content-color-down"));
+ }
+
+ &:focus-visible {
+ --_swc-link-text-color: var(--swc-link-text-color-focus, token("accent-content-color-key-focus"));
+
+ border-radius: var(--swc-link-corner-radius, var(--_swc-link-corner-radius));
+ outline: var(--_swc-link-focus-indicator-thickness) solid var(--_swc-link-high-contrast-focus-indicator-color, var(--swc-link-focus-indicator-color, token("focus-indicator-color")));
+ outline-offset: var(--_swc-link-focus-indicator-gap);
+ }
+
+ &:lang(ja),
+ &:lang(zh),
+ &:lang(ko) {
+ line-height: var(--swc-link-line-height-cjk, var(--_swc-link-line-height-cjk));
+ }
+}
+
+.swc-Link--inline {
+ font-weight: var(--swc-link-inline-font-weight, var(--_swc-link-inline-font-weight));
+}
+
+.swc-Link--secondary {
+ --swc-link-text-color: token("neutral-content-color-default");
+ --swc-link-text-color-hover: token("neutral-content-color-hover");
+ --swc-link-text-color-down: token("neutral-content-color-down");
+ --swc-link-text-color-focus: token("neutral-content-color-key-focus");
+}
+
+.swc-Link--quiet.swc-Link--standalone {
+ text-decoration: none;
+
+ &:hover {
+ text-decoration: underline;
+ }
+}
+
+.swc-Link--staticWhite {
+ --swc-link-text-color: token("white");
+ --swc-link-text-color-hover: token("white");
+ --swc-link-text-color-down: token("white");
+ --swc-link-text-color-focus: token("white");
+ --swc-link-focus-indicator-color: token("static-white-focus-indicator-color");
+}
+
+.swc-Link--staticBlack {
+ --swc-link-text-color: token("black");
+ --swc-link-text-color-hover: token("black");
+ --swc-link-text-color-down: token("black");
+ --swc-link-text-color-focus: token("black");
+ --swc-link-focus-indicator-color: token("static-black-focus-indicator-color");
+}
diff --git a/2nd-gen/packages/swc/stylesheets/typography.css b/2nd-gen/packages/swc/stylesheets/typography.css
index cea8fde6770..5f3004f30f1 100644
--- a/2nd-gen/packages/swc/stylesheets/typography.css
+++ b/2nd-gen/packages/swc/stylesheets/typography.css
@@ -534,3 +534,41 @@
.swc-Typography--emphasized:not(:lang(zh), :lang(ja), :lang(ko)) {
font-style: token("italic-font-style");
}
+
+/* =========================
+ Links (prose and link lists)
+ ========================= */
+.swc-Typography--prose :where(a),
+.swc-Typography--links :where(a) {
+ font-family: inherit;
+ font-size: inherit;
+ font-style: inherit;
+ font-weight: inherit;
+ line-height: inherit;
+ color: var(--swc-typography-link-text-color, token("accent-content-color-default"));
+ text-decoration: underline;
+ text-decoration-thickness: var(--swc-typography-link-text-underline-thickness, token("text-underline-thickness"));
+ text-underline-offset: var(--swc-typography-link-text-underline-gap, token("text-underline-gap"));
+ background-color: transparent;
+ cursor: pointer;
+ outline: none;
+ transition: color token("animation-duration-100") ease-in-out;
+}
+
+.swc-Typography--prose :where(a):hover,
+.swc-Typography--links :where(a):hover {
+ color: var(--swc-typography-link-text-color-hover, token("accent-content-color-hover"));
+}
+
+.swc-Typography--prose :where(a):active,
+.swc-Typography--links :where(a):active {
+ color: var(--swc-typography-link-text-color-down, token("accent-content-color-down"));
+}
+
+.swc-Typography--prose :where(a):focus-visible,
+.swc-Typography--links :where(a):focus-visible {
+ color: var(--swc-typography-link-text-color-focus, token("accent-content-color-key-focus"));
+ border-radius: token("corner-radius-100");
+ outline: token("focus-indicator-thickness") solid var(--swc-typography-link-focus-indicator-color, token("focus-indicator-color"));
+ outline-offset: token("focus-indicator-gap");
+}
diff --git a/2nd-gen/packages/tools/swc-tokens/src/typography.js b/2nd-gen/packages/tools/swc-tokens/src/typography.js
index 1ecb47b2222..2d63b27a860 100644
--- a/2nd-gen/packages/tools/swc-tokens/src/typography.js
+++ b/2nd-gen/packages/tools/swc-tokens/src/typography.js
@@ -128,10 +128,70 @@ const CJK_OVERRIDES = {
};
const PROSE_CLASS = 'Typography--prose';
+const LINKS_CLASS = 'Typography--links';
+
function proseSelector(prefix) {
return `.${prefix}-${PROSE_CLASS}`;
}
+function linksSelector(prefix) {
+ return `.${prefix}-${LINKS_CLASS}`;
+}
+
+/**
+ * Default native anchor appearance inside typography wrappers.
+ * Uses :where(a) so BEM modifiers from link.css can override.
+ */
+function generateTypographyAnchorRules(prefix) {
+ const prose = proseSelector(prefix);
+ const links = linksSelector(prefix);
+ const anchor = ':where(a)';
+ const wrapperSelectors = `${prose} ${anchor},\n${links} ${anchor}`;
+ const stateSelectors = (pseudo) =>
+ `${prose} ${anchor}${pseudo},\n${links} ${anchor}${pseudo}`;
+
+ const baseDecls = pickValidDecls({
+ 'background-color': 'transparent',
+ 'text-decoration-skip': 'objects',
+ 'text-decoration': 'underline',
+ 'text-decoration-thickness': `var(--${prefix}-typography-link-text-underline-thickness, token("text-underline-thickness"))`,
+ 'text-underline-offset': `var(--${prefix}-typography-link-text-underline-gap, token("text-underline-gap"))`,
+ transition: `color token("animation-duration-100") ease-in-out`,
+ outline: 'none',
+ cursor: 'pointer',
+ color: `var(--${prefix}-typography-link-text-color, token("accent-content-color-default"))`,
+ 'font-family': 'inherit',
+ 'font-size': 'inherit',
+ 'font-style': 'inherit',
+ 'font-weight': 'inherit',
+ 'line-height': 'inherit',
+ });
+
+ const hoverDecls = pickValidDecls({
+ color: `var(--${prefix}-typography-link-text-color-hover, token("accent-content-color-hover"))`,
+ });
+
+ const activeDecls = pickValidDecls({
+ color: `var(--${prefix}-typography-link-text-color-down, token("accent-content-color-down"))`,
+ });
+
+ const focusDecls = pickValidDecls({
+ color: `var(--${prefix}-typography-link-text-color-focus, token("accent-content-color-key-focus"))`,
+ outline: `token("focus-indicator-thickness") solid var(--${prefix}-typography-link-focus-indicator-color, token("focus-indicator-color"))`,
+ 'outline-offset': 'token("focus-indicator-gap")',
+ 'border-radius': 'token("corner-radius-100")',
+ });
+
+ return `/* =========================
+ Links (prose and link lists)
+ ========================= */
+${cssBlock(wrapperSelectors, baseDecls)}
+${cssBlock(stateSelectors(':hover'), hoverDecls)}
+${cssBlock(stateSelectors(':active'), activeDecls)}
+${cssBlock(stateSelectors(':focus-visible'), focusDecls)}
+`;
+}
+
/**
* Selector aliases let us "attach" semantic selectors to an existing variant/size class
* without duplicating styling logic. These are only applied under the `--prose` container class.
@@ -785,6 +845,9 @@ export async function generateTypographyCssString(options = {}) {
font-style: token("italic-font-style");
}\n`;
+ out += '\n';
+ out += generateTypographyAnchorRules(prefix);
+
return out;
}