From 0f3fff92f4ddf820cab02fa61100398fa15f592c Mon Sep 17 00:00:00 2001 From: Josh Knapp Date: Wed, 2 Sep 2026 11:34:02 -0700 Subject: [PATCH] Lay the notes panel out by its own width, not the window's MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The panel splits master/detail unconditionally: a 192px title column beside the editor. That fits the Project Home tab and does not fit the dock. At the dock's 352px default the editor gets 157px, and its action row wants ~200px, so the Delete button lands outside the dock's `overflow-hidden` with no scrollbar to reach it, and the textarea collapses to a two-word column. The two surfaces differ in width while sharing a viewport, so this is a container query rather than a `md:` breakpoint — a viewport query reads the window and hands both surfaces the same answer, which is wrong for one of them. Tailwind v4 has these in core; verified as real `@container (min-width: 32rem)` rules in the built CSS, since a variant that silently compiles to nothing looks identical in review. The threshold is arithmetic: side by side needs the 192px list, an editor wide enough for its own buttons (~280px), and the divider. `@lg` (512px) is the first stop clearing ~473px. Below it the titles become a capped strip above the editor, so the note being written keeps the height. The action row now wraps, which is the part that holds at *any* width rather than on one side of a threshold: the buttons are a group that does not shrink, the title field shrinks to 96px, and past that the title takes one row and the buttons the next. Nothing can be pushed out of the panel. Not covered by the suite — jsdom has no layout engine, so 711 tests pass before and after. This needs eyes on the dock at its minimum, default and maximum widths. Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_011YPqHpjV4EL6RNEwrRKqQm --- app/src/components/notes/NoteEditor.tsx | 24 ++++++++++++++-------- app/src/components/notes/NotesPanel.tsx | 27 +++++++++++++++++++------ 2 files changed, 37 insertions(+), 14 deletions(-) diff --git a/app/src/components/notes/NoteEditor.tsx b/app/src/components/notes/NoteEditor.tsx index fa230db..8384249 100644 --- a/app/src/components/notes/NoteEditor.tsx +++ b/app/src/components/notes/NoteEditor.tsx @@ -30,21 +30,29 @@ export default function NoteEditor({ }: Props) { return (
-
+ {/* Wraps rather than overflows. The two buttons are a group with a fixed + appetite (~190px) and the title field can shrink only so far, so in a + narrow dock the title takes the first row and the buttons the second. + Without the wrap the group is simply clipped by the dock's + `overflow-hidden`, which puts Delete off-window with no scrollbar to + reach it. */} +
onTitleChange(e.target.value)} onBlur={onCommit} placeholder="Note title" aria-label="Note title" - className="flex-1 min-w-0 px-2 h-8 bg-[var(--bg-primary)] border border-[var(--border-color)] rounded-[var(--radius-control)] text-[13px] text-[var(--text-primary)] focus:border-[var(--accent)] transition-colors" + className="flex-1 min-w-24 px-2 h-8 bg-[var(--bg-primary)] border border-[var(--border-color)] rounded-[var(--radius-control)] text-[13px] text-[var(--text-primary)] focus:border-[var(--accent)] transition-colors" /> - {/* The live editor text, not `note.body` — what is on screen is what - gets sent. */} - - +
+ {/* The live editor text, not `note.body` — what is on screen is what + gets sent. */} + + +