Chat chrome docks into the rail; drop the notes-off banner

The chat header and composer are full-bleed bands inside the main
pane, which starts right at the sidebar on desktop - so both ended in
a hard vertical edge beside the floating rail card (the 12px gutter
showed the raw scene and the bands' fill + backdrop blur read as a
color step at the seam), with their hairlines starting in mid-air at
that edge. Both bands now reach the card's right edge (the rail's own
12px padding, expanded or collapsed) and their hairlines are inset to
the content box; phones keep the plain full-width borders. The chat
suite pins the dock. The "Chat is set to ignore notes text" banner
went away - the scope chip already says what the chat may read.

Version 0.5.5, SW -> freezmo-v77. Chat 104/104 (2 new), mobile
126/126, wizard 95/95, phase3 31/31, bubbles 34/34, i18n 13/13,
native 33/33, regression 44/44, contrast 0 findings, axe clean.
Full e2e: 14/14 suites.
This commit is contained in:
Martin Dvořák 2026-10-14 11:46:34 +00:00
commit a5d30a171c
8 changed files with 124 additions and 20 deletions

View file

@ -291,6 +291,58 @@ try {
await desktop.page.waitForTimeout(400);
check("desktop: AI disclaimer under the composer", await desktop.page.getByText("Freezmo uses AI and can make mistakes").isVisible());
/* The chat chrome docks into the rail: the header and the composer used to
end in a hard vertical edge beside the floating rail card (the scene
showed through the gutter and their fill/blur made it read as a color
step at the seam), and their hairlines started right at that edge. Both
bands now reach the card's right edge and their hairlines are inset to
the content box. */
const seam = await desktop.page.evaluate(() => {
const card = document.querySelector(".sidebar-surface");
const header = document.querySelector(".chat-header");
const band = document.querySelector(".chat-composer-band");
if (!card || !header || !band) return null;
const line = (el) => {
const cs = getComputedStyle(el, "::after");
return { content: cs.content, left: parseFloat(cs.left), right: parseFloat(cs.right) };
};
return {
cardRight: Math.round(card.getBoundingClientRect().right),
headerLeft: Math.round(header.getBoundingClientRect().left),
bandLeft: Math.round(band.getBoundingClientRect().left),
headerBorder: getComputedStyle(header).borderBottomWidth,
bandBorder: getComputedStyle(band).borderTopWidth,
headerLine: line(header),
bandLine: line(band.parentElement),
};
});
check(
"desktop: chat chrome docks into the rail (no seam)",
seam !== null &&
seam.headerLeft === seam.cardRight &&
seam.bandLeft === seam.cardRight &&
seam.headerBorder === "0px" &&
seam.bandBorder === "0px" &&
seam.headerLine.content !== "none" &&
seam.headerLine.left > 0 &&
seam.bandLine.content !== "none" &&
seam.bandLine.left > 0,
JSON.stringify(seam),
);
/* The notes-off banner is gone: with "keep notes text" off, chat no longer
nags at the bottom — the scope chip already says what it reads. */
const quiet = await makePage(browser, { width: 1280, height: 900, deviceScaleFactor: 1 });
await seed(quiet.page, {
decks: [DECK_NOTES],
extra: { "freezmo.settings.v1": JSON.stringify({ apiKey: "test-key", chatNotes: false }) },
});
await quiet.page.goto(`${APP}/chat`, { waitUntil: "networkidle" });
await quiet.page.waitForTimeout(900);
const quietText = await quiet.page.evaluate(() => document.body.innerText);
check("desktop: no notes-off banner with chat notes off", !/ignore notes text|ignoruje/i.test(quietText));
await quiet.context.close();
/* 6b. desktop pickers: the chip that opens also closes ---------------
(It used to only ever open, so the only way out was a choice.) */
const modelChip = () => desktop.page.getByRole("button", { name: /Stub (Text|Vision)|Chat model/ }).first();