Inline navigation inside prose — text that takes you somewhere. The boundary against Button is a test, not a feeling: if the destination could be opened in a new tab, it is a link; if it performs an action instead of moving you, it is a Button wearing link styling, and middle-click, copy-link, and the browser's own status bar all quietly stop working.
A link carries no scale of its own. It inherits the size, weight, and line height of the prose around it — that is what makes it a link rather than a control — so it has no variant or size axes, only states.
The underline is the affordance and is present at rest, always. Link inherits the surrounding foreground, so it stays dark on a light surface, light on a dark one, and hue-matched on a paired color surface. Its underline uses that same currentColor at 45% presence, then rises to full strength on hover with no ink, weight, or metric change.
| Example | State | Driver | Roles | Usage |
|---|---|---|---|---|
| Read the contract | Rest | — | inherit · currentColor 45% | The parent owns the contrast pair; the underline keeps its hue at lower presence |
| Read the contract | Hover | :hover | currentColor | The underline rises to the text's own ink; nothing else moves |
| Read the contract | Focus | :focus-visible | focus.ring | The shared ring on the link's radius.small box — keyboard only |
There is no disabled state: an anchor cannot be disabled, and a destination that is unavailable is not a link — render it as plain text. Visited is deliberately unstyled; :visited exposes browsing history and browsers restrict what it can paint, so the base leaves it alone and a consumer that genuinely needs it owns that decision.
A link is only ever seen inside running text, so the canvas shows it there rather than standing alone — at the paragraph's own size, weight, and line height, wrapping with the line like any other word.
Components are built from the color roles and the type scale, and re-decide nothing.
Links inherit the prose's size, weight, and foreground. Nothing separates them from the sentence but the quieter same-hue underline — which is why the rest state keeps it.
A link names where it goes and then goes there.
| Verdict | Rule |
|---|---|
| Do | Use a link to navigate and a button to act — if the target cannot be opened in a new tab, it is a button. |
| Do | Always ship a real href. A span or button styled as a link loses middle-click, copy-link, and keyboard semantics. |
| Do | Keep the underline. Color alone never marks a link, and in the monochrome default there is no color difference at all. |
| Do | Let the parent own contrast. Link inherits the surrounding foreground; use --ds-link-color only when an alternate ink has been contrast-gated on that exact surface. |
| Do | Write the destination into the label — never “click here”, “read more”, or a bare URL, which are meaningless out of context and to a screen reader listing links. |
| Do | Let the link inherit the prose's size and weight; a link that needs its own scale is a button or a nav item. |
| Do | Mark links that leave the page or open a new tab in the label or with an adjacent icon, so the jump is not a surprise. |
| Don’t | Nest a link inside a button or a button inside a link — the activation target becomes ambiguous for pointer and keyboard alike. |
| Don’t | Restyle :visited in the base; it leaks history and browsers restrict it. A consumer that needs it owns the decision. |