A closed field in six states, a panel in four colours, and a row that keeps the tick's width whether or not the tick is there.
Five components, twenty-eight variants
Select - State × Size: Default · Filled · Focus · Filled (Focus) · Disabled · Invalid × default · sm - 200 × 32 and 200 × 28
Select Menu / Item - Variant × State × Size: Default · Checkbox × Default · Hover · Hover (Translucent) × default · sm - 292 × 28 and 292 × 24
Select / Menu - Color × Appearance: Default · Inverted × Solid · Translucent - 324 × 172, Translucent at 70 percent
Select Menu / Label - none: 292 × 24 - 12px medium in base.muted-foreground
Select Menu / Separator - none: 292 × 8 - a 1px base.border line that fills the board
Using the Select
Why is Filled a state rather than just different text?
Because the colour changes with it. A placeholder is base.muted-foreground and a chosen value is base.foreground, and that difference is the only thing telling you whether the field has been answered. Typing over the placeholder in an instance gives you the right words in the wrong grey, so the file draws both.
Why is there a Filled (Focus) as well?
Because the two are independent and Penpot needs the combination spelled out. A field can hold a value and still be the one you are on. Making Filled a second axis would have doubled the container for one extra useful cell, so the six State names carry the four combinations that actually occur.
What is the Spacer in every row for?
Keeping the width honest. Each row ends with a 20 by 16 Spacer, and the tick is an absolute child positioned inside it. A chosen row and an unchosen one are therefore exactly the same width, and picking a value does not shift every label in the list sideways by sixteen pixels.
What does the Checkbox variant actually mean?
Chosen. Both of its states draw the tick, so it is the variant you place on the currently selected row while everything else stays Default. In a multi-select every ticked row takes it. The name describes the mark, not a different kind of row.
Why are there two hover states?
One per surface. Hover fills with base.muted and reads on a white panel, keeping its label at base.foreground because a hover is a background change and nothing more. Hover (Translucent) fills with base.foreground and reads on the Inverted one, where a pale grey would vanish, and it does flip its label - the row has gone nearly black underneath it. The name is still misleading: the fill is fully opaque; it is the hover for the translucent panel, not a translucent hover.
Why is the panel two boards deep?
So the colour and the edge can move independently. The outer board owns the base.foreground border, the radius.lg corner and the two drop shadows; the inner Surface owns the fill and the 4 of padding. Inverted changes the Surface's fill and the outer edge without either having to know about the other.