terminal: anchor tail pill outside .terminal-wrap stacking context (#375)

#375 set `z-index: 35` on the agent page's tail pill so it'd float
above the fixed composer (z-index 30). The fix only landed because
nothing else in `.agent-main` created a stacking context. But the
pill is anchored inside `.terminal-wrap`, which carries
`backdrop-filter: blur(...) saturate(...)` for the frost effect —
and `backdrop-filter` CREATES A STACKING CONTEXT. The pill's
z-index 35 was trapped inside that context and never got to compete
with the composer's z-index 30 in the root stacking context, so the
operator still saw the badge clipped under the input box.

Same root cause on the flow page — `.flow-main .terminal-wrap`
inherits the same backdrop-filter rule.

Fix: anchor the pill in `.agent-main` / `.flow-main` instead of
`log.parentElement` (= `.terminal-wrap`). Both ancestors are
`position: absolute` with `overflow: hidden` but NO backdrop-filter
or other stacking-context creators, so the pill's z-index reaches
the root and properly floats above the composer.

Geometry unchanged — `.agent-main` / `.flow-main` and the
`.terminal-wrap` they contain both `inset: 0` the same area, so the
pill's `bottom: calc(--composer-h + 0.6em)` lands at the same y.

Also added `.flow-main .tail-pill { z-index: 35 }` (the flow page
was missing the per-page z-index bump that the agent page already
had).

`pillAnchor` is an existing opt in @hive/shared/terminal.js (the
default is `log.parentElement`); both consumers now set it explicitly.
This commit is contained in:
iris 2026-05-25 00:52:51 +02:00
parent 9975be9c08
commit 47403595f1
3 changed files with 29 additions and 0 deletions

View file

@ -1143,6 +1143,18 @@ window.marked = marked;
const term = HiveTerminal.create({
logEl: log,
// Anchor the `↓ N new` pill in `.agent-main` (NOT the default
// `log.parentElement` = `.terminal-wrap`). `.terminal-wrap`
// applies `backdrop-filter` for the frost effect, which
// creates a CSS stacking context — the pill's z-index 35
// (agent.css #375) then gets TRAPPED inside that context and
// can't compete with the fixed composer's z-index 30 in the
// root stacking context. Anchoring in `.agent-main` (no
// backdrop-filter, no other stacking-context creators) lets
// the pill's z-index reach the root and properly float above
// the composer. Geometry unchanged — `.agent-main` and
// `.terminal-wrap` both `inset: 0` fill the same area.
pillAnchor: $('agent-main'),
historyUrl: '/events/history',
streamUrl: '/events/stream',
renderers: {