Skip to content

feat(chat): make the reply quote Liquid Glass over the transcript - #730

Merged
bmc08gt merged 4 commits into
mainfrom
feat/chat-reply-surface-variants
Sep 6, 2026
Merged

feat(chat): make the reply quote Liquid Glass over the transcript#730
bmc08gt merged 4 commits into
mainfrom
feat/chat-reply-surface-variants

Conversation

@bmc08gt

@bmc08gt bmc08gt commented Sep 6, 2026

Copy link
Copy Markdown
Collaborator

Follows #645 — the reply feature itself is already on main. This is the surface work on top of it, driven by review on device.

The seam

Lifting the bar's slab to backgroundSecondary for a reply drew a hard horizontal line across the screen at the keyboard's top edge. Not a gap in the bleed — the surface already runs past the safe area — but a 12-level colour step against the keyboard's own container, which is matched to background and cannot be repainted. The slab now stays one colour in every state, and the reply's elevation moves onto the quote.

The fade

BarSurfaceBackground was applied to the whole stack, so the 33pt ramp that dissolves the transcript into the composer anchored to the bar's current top edge. A reply moved the dissolve 50pt up the screen and put its opaque tail behind the quote. It is now on the composer row alone: the ramp stays at the input, and the quote sits over live transcript.

The quote

  • Shaped and sized like the rest of the bar — a 14pt rounded rect at BarMetrics.contentHeight, the height the Send Cash button morphs at while a composer is beside it. A minimum, so a wrapped snippet still grows.
  • One 12pt margin on all four sides. The bar already pads its own row, so the strip adds only the remainder below; padding both ends equally left the gap under the quote twice the one above it.
  • The author's rule is 6pt and overlaid on the pinned frame. As a member of the row it took the row's natural height, which the frame then centred inside contentHeight, leaving it short at both ends. Thickness cannot make it rectangular — the 14pt radius leaves the leading edge straight for only contentHeight - 28 regardless of width — but 6pt gives the tapered ends enough mass to read as caps.
  • On glass the rule takes a tint instead of a solid fill, through a new glassBackground(cornerRadius:tint:) in FlipcashUI.

What ships on

glassReplyQuote is default-on, so the quote is Liquid Glass floating over the transcript. The flag and the opaque-card variant stay behind it in the developer section — which of the two reads better against a scrolling transcript is a call for product review, and the flag is how that comparison gets made on a real build.

Also

The bubble's quote panel goes to two lines, matching the composer's strip. One line truncated most quoted sentences mid-clause, leaving the reply pointing at something the reader still had to open.

No proto or schema changes; ChatQuote is a display model built by the transcript mapper and never persisted.

Replying lifted the whole bar slab to backgroundSecondary (37,37,38). The slab
already bleeds past the safe area and runs behind the keyboard, so the hard line
across the screen was never a gap — it was a colour step against the keyboard's
own container, which paints within a level of `background` (25,25,26) and which
we cannot repaint. At rest the two matched and there was no line; the reply fill
was the line.

So the slab keeps one paint in every state, and the ground that sets a reply
apart is drawn on the quote instead, inset from the bar's edges. Two styles,
because it isn't obvious which reads better against a keyboard: an opaque panel
on the bar's surface, and a Liquid Glass capsule floating clear of it. The
`glassReplyQuote` developer flag picks between them; panel is the default.

The strip's edge-to-edge rule goes with the flush layout it belonged to. The
panel clips its rule to the corner radius; the capsule insets it, since a clip
would shave the specular edge off the glass.
The glass variant was a capsule while the field and the Send Cash button under
it are 14pt rounded rects, so the quote read as a different kind of object from
the controls it sits above. Both variants now take BarMetrics.cornerRadius, and
the only thing left between them is the material.

Matching the corner also gets the author's rule back onto the edge. The clip
moves onto the content and the ground goes behind it: the rule is rounded off at
the two corners it passes, while the glass stays outside the clip and keeps the
specular edge a clip was shaving off. So the rule sits flush in either style,
the way it did before the quote had a ground at all.
The quote was whatever the two stacked fonts and 8pt of padding came to —
about 49pt against the Send Cash button's 50, near enough to read as a
mistake rather than as a deliberately different size. Pin it to
`BarMetrics.contentHeight`, as a minimum so a snippet that wraps to a second
line can still grow.

Its margin was 12 at the sides and 8 top and bottom, and the 8 underneath
stacked with the bar's own row padding, so the gap below the quote was twice
the gap above it. Both are now `inset`, with the bar's padding subtracted
from the bottom so the three gaps match.

Also names the Send Cash button in the flag description, which still called
the glass variant a capsule from before the shape matched the bar's.
The bar's surface was painted behind the whole stack, so the 33pt ramp that
dissolves the transcript into the composer anchored to whatever the bar's top
edge was. Opening a reply moved that dissolve 50pt up the screen and put the
opaque tail behind the quote. It is now painted behind the composer row alone:
the ramp stays at the input, and the quote sits over live transcript.

That is what the glass variant needed to have anything to sample, so it ships
on — `glassReplyQuote` is now default-on. The flag and the opaque card stay
behind it, toggleable from the developer section, because which of the two
reads better against a scrolling transcript is a call for product review.

The author's rule goes to 6pt and moves to an overlay on the pinned frame.
Standing in the row it took the row's natural height, which the frame then
centred, leaving it a fraction short at both ends. Width alone cannot make it
look rectangular — the 14pt radius leaves the leading edge straight for only
`contentHeight - 28`, and thickening lengthens the taper rather than the
straight core — but 6pt carries enough mass for the ends to read as caps. On
glass it takes a tint rather than a solid fill, via a new
`glassBackground(cornerRadius:tint:)`, so it is part of the surface instead of
a sticker on it.

The bubble's quote goes to two lines, matching the composer's strip. One line
truncated most quoted sentences mid-clause, which left the reply pointing at
something the reader still had to open to understand.
@bmc08gt bmc08gt self-assigned this Sep 6, 2026
@bmc08gt
bmc08gt merged commit bf84c18 into main Sep 6, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant