Hover a company name on the About page and a small card appears with a logo, a line about the place and a link, the way Wikipedia previews a linked article. It is a small feature, and the part that took the work was not the card. It was deciding where the card goes.

Cards that cover the text are worse than no card
The first version put the card next to the word, over the page. It worked until the card covered the very sentence the reader was in the middle of. Preview cards exist to be glanced at and dismissed, so a card that hides the prose it annotates trades one problem for another.
The second approach was a search: find an empty patch of page near the word and put the card there. That went through several rounds of patching (pad the busy area, cap how far the search may send the card, measure text nodes instead of leaf elements) and it never felt right. A short card would turn up in a place with no visible connection to its word.
The version that stayed is much simpler, and it is stated at the top of the component:
The card stays in the page margin, level with the word that opened it. It never searches the page for an empty patch. When there is no usable margin, the card remains closed rather than covering the prose.

The rule, in code
The article column is the protected reading area. For each side, the card gets whatever width the margin allows, and is skipped if that is under 200 px or the card would not fit the viewport. Of the candidates that remain, the nearest margin wins, and a caller can name a preferred side:
const right = column.right + GAP;
addCandidate("right", vw - right - EDGE, () => right);
addCandidate("left", column.left - GAP - EDGE, (width) => column.left - GAP - width);
candidates.sort(
(a, b) =>
Number(b.mode === side) - Number(a.mode === side) ||
a.distance - b.distance,
);
Vertically, the card is centred on the word and then clamped between the fixed header and the bottom of the viewport. The ceiling is the header, not the top of the screen, because a card that slid under the header would be half hidden.
When neither margin is wide enough, nothing opens. On a 700 px wide window there is no margin, and hovering the same name does nothing:

That looked like a gap at first. It is the rule working: a card that cannot sit beside the text does not sit on it.
The details that bit
The card lives in the body. It is rendered through a portal, not next to the word. Any ancestor with a transform becomes the containing block for position: fixed children, and this page has a few (the header, the entrance animation). A card inside one of them is placed relative to that ancestor, not the viewport. It is also measured only after it is laid out, because a hidden card reports a shorter height than it renders at.
The visible right edge is not clientWidth. The page reserves a scrollbar gutter, and clientWidth can still count it, so a card placed into the gutter was clipped. The code now takes the smallest of the document width, the <html> box's right edge, and the visual viewport:
const vw = Math.min(
document.documentElement.clientWidth,
document.documentElement.getBoundingClientRect().right,
vv ? vv.offsetLeft + vv.width : Infinity,
);
The visual viewport term is for pinch zoom. When the page is zoomed, fixed elements are placed in the layout viewport, which then extends past the screen, so a card could land off to the side where nobody can see it.
A left card hugs the text, not the screen. On a wide monitor the left margin is far wider than the card. Anchoring the card to the screen's edge stranded it a long way from its word, so it now sits snug against the column's left edge.
Leaving does not close it at once. The pointer needs a moment to cross the gap and reach the card, or its links could never be clicked. Closing waits 400 ms. Focus works too: the name is focusable and opens the card on focus, so the feature is not mouse-only.
Seeing it without a pointer
Hover states are awkward to screenshot. In development, ?open-ref=Name holds that card open, and the code is compiled out of production builds. The first image above was taken that way. It is a small thing, but a feature you can put into a given state from the URL is a feature you will actually test.