Seven chat surfaces on one axis, from a solid primary send to no surface at all, with the reaction pill already drawn into every one of them and switched off.
Bubble Group - none: 420 × 214 - a column of three bubbles, 8 apart
Using the Bubble
Why is Variant the only axis?
Because the other things the source exposes do not multiply the matrix. Reactions are a layer that every variant already carries, hidden, and revealing one does not move the bubble. Which side a message sits on belongs to the row it is in, not to the bubble. So seven variants covers it, and nothing has to be drawn twice.
What is base.bubble-tinted?
A colour the kit did not have. Tinted sits between base.secondary and base.muted, and neither of them was the right value, so a token was added rather than a literal typed in: #E8E8E8 in light, #2E2E2E in dark. It themes with everything else, which a hex would not.
How does the reaction pill avoid moving the bubble?
It hangs off the bottom edge with a 3px ring in base.card, so it reads as sitting on top of whatever is behind rather than as another row inside. The bubble stays 66 tall whether the pill is showing or not, which is why Reactions is a hidden layer instead of an axis.
Why does Ghost exist?
For text that belongs in the thread without being a message. No fill, no padding, no radius, 46 tall against everyone else's 66. In the usage frame it is the timestamp under a failed send, which is exactly the case the source describes as unframed assistant text.
Where does left and right come from?
From the bubble inside the group, not from a property on the group. A real thread alternates sides, so a two-value axis on Bubble Group could not express it; each bubble is aligned where it belongs and the group only handles the 8px rhythm between them.