Link
Words that go somewhere: in the accent and a weight heavier than the sentence, with a line that comes under the pointer and the keyboard.
Try it
What has just happened and needs no place is a toast; what stays true beside a part of the page is an alert. The rule for how long a message may stay is WCAG 2.2.1 (opens in a new tab).
In secondary text, where the accent and the words are closest: how the colours were measured.
Move the pointer over one, or Tab to it: the line and the ring arrive together.
No line at rest
The usual link is underlined, and for a reason: colour must not be the only thing that tells a link from the words around it, and this accent does not stand far enough from them to try.
| Against | Light | Dark |
|---|---|---|
text/primary | 2.73:1 | 1.64:1 |
text/secondary | 2.06:1 | 1.03:1 |
The system keeps its sentences clean of underlines all the same, a decision made on 2026-09-21 with these numbers on the table. What carries the link, beside its colour, is its weight: Medium in a sentence that is Regular, which is a difference of shape and not of hue. The line comes under the pointer and under the keyboard’s focus, with the ring. It follows that a link does not belong inside words that are already Medium or heavier, a table header or a button’s label: there it goes on a line of its own.
A link, or a button
| When | Use |
|---|---|
| It goes to another page or place, inside a sentence | Link |
| It goes somewhere, on a line of its own: “All locations” | Link, standalone |
| It goes somewhere and is the main thing to do here: “Create account” | Button with href |
| It does something here: saves, deletes, opens a dialog | Button |
Both are an a. The look says how much the page wants it pressed; the element says what it does, to the browser’s menu, to a new tab, to a screen reader. A Link has no button variant and needs none.
Accessibility
An external link opens a new tab with rel="noreferrer", and says “opens in a new tab” after its name, in words that are read and not shown; externalLabel says them in another language. An icon is not part of the name. A standalone link is a target of its own and is 24 tall (WCAG 2.5.8 exempts only a link in a sentence). There is no colour for a visited link: in an application it says nothing, and the theme has no token for it.
Using it
import { Link, Button } from 'alpenglow';
import NextLink from 'next/link';
<p>What just happened is a <Link href="/toast">toast</Link>.</p>
<Link variant="standalone" href="/locations" iconEnd={<ArrowRight size={16} />}>
All locations
</Link>
<Link href="https://www.w3.org/TR/WCAG22/" external>WCAG 2.2</Link>
// A router's link takes the props and is the element.
<Link href="/settings" render={(props) => <NextLink {...props} />}>Settings</Link>
// What looks like a button and goes somewhere is a Button with an href.
<Button href="/signup">Create account</Button>| Prop | Type | Default |
|---|---|---|
href | string | required |
variant | 'inline' | 'standalone' | 'inline' |
iconEnd | React | — |
external | boolean | false |
externalLabel | string | 'opens in a new tab' |
render | (props: Link | — |
…anchor | target, rel, download, aria-current and the rest of an anchor’s | — |