Thinner glass everywhere, chat answers as bubbles in Aero

Two asks. "Slightly more transparent": the veils drop another notch
(recipe 0.15 -> 0.12, tokens ~0.03 less, tab bar / wizard bar / gloss
likewise). "Some buttons aren't themed": the recipe now catches the
flows' hand-rolled frost by attribute selectors - the study activities'
bg-white/xx chips (multiple choice, matching, ordering, fill blank),
the exam rows that used bg-[var(--surface)] (an opaque white in Aero),
and everything on the surface tokens (chat chips, homework chips,
inputs, dropzones). Inside sheets the same shapes stay flat; the
dropzones lost their press-scale (a transform re-anchors the fixed
backdrop) and shade inward instead.

And the chat: the assistant answers are bubble-less by design and the
user bubble's thin tint washed out over the bright wallpaper, so the
longest text in the app sat straight on the photo. In Aero both roles
get a real pane now - chat-answer wraps the markdown in a bubble, the
user turn carries chat-bubble, with a stronger veil than the shared
glass for comfortable reading. Light and dark keep the bubble-less
assistant design (styled only under .aero).

Contrast: 0 below-minimum findings, 0 axe violations. Chat 101/101,
mobile 123/123, regression 44/44, i18n 13/13, native 33/33.
Version 0.3.5, SW -> freezmo-v65.
This commit is contained in:
Martin Dvořák 2026-10-13 12:43:46 +00:00
commit 5eec310e16
5 changed files with 102 additions and 25 deletions

View file

@ -43,7 +43,7 @@ export function MessageRow({
if (message.role === "user") {
return (
<div className="flex flex-col items-end gap-1">
<div className="max-w-[88%] rounded-3xl rounded-br-lg border border-[var(--glass-border)] bg-[var(--surface-strong)] px-3.5 py-2.5">
<div className="chat-bubble max-w-[88%] rounded-3xl rounded-br-lg border border-[var(--glass-border)] bg-[var(--surface-strong)] px-3.5 py-2.5">
<p className="whitespace-pre-wrap break-words text-[15px] leading-relaxed text-[var(--text)]">{message.content}</p>
{message.attachments && message.attachments.length > 0 ? (
<p className="mt-1.5 text-[11.5px] text-[var(--text-subtle)]">
@ -69,7 +69,9 @@ export function MessageRow({
<div className="space-y-2">
{message.thinking ? <ThinkingRow thinking={message.thinking} streaming={streaming && !message.content} /> : null}
{message.content ? (
<Markdown text={message.content} />
<div className="chat-answer">
<Markdown text={message.content} />
</div>
) : streaming ? (
<span className="flex items-center gap-1 py-1" role="status" aria-label={t("chat.thinking")}>
{[0, 1, 2].map((dot) => (