Marks, lines, and a table that breaks

A long table lay straight across the gap between two sheets with a row
cut in half, and a shorter one jumped to the next sheet whole leaving
the rest of the first blank. Tables are broken between their rows now,
which is where a table breaks on paper. The spacer there is a tr with
one borderless cell: a div inside a tbody is not something the browser
keeps. Its own spacer rows are subtracted again on the next measurement
and counted into the shift every block below inherits — miss that and
everything under a broken table is measured a page too high.

A dialog closed in the middle of an edit if a selection was dragged past
its edge: the click lands on the nearest common ancestor of press and
release, which is the backdrop, and every dialog read that as "clicked
beside me". They remember where the press began now. All ten.

A note and a chapter can wear a mark of their own beside the name,
chosen from a short list searched by what a thing is for rather than
from the system emoji keyboard — a different thing on every machine, and
three thousand pictures for a decision that is "which of these is the
invoice notebook". A separator takes its own colour and one of five
shapes, and a chapter can be divided like the notebook it sits in: both
places a chapter is shown draw it with one component now, so it cannot
be divisible in the column and not in the unfolded block.

Also: a chapter's colour could not be cleared, because the update rode
on COALESCE and null there means "leave it alone". A table's header row
is legible on the dark theme. Three entries in the table's own menu were
still German. Opening a notebook opens its first note, on a wide screen
only — on a phone the list is the screen.

Fourteen suites green: 364 browser checks, 241 unit tests.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
marcandClaude Opus 5 committed 2026-08-16 23:23:16 +02:00
1 parent 0c312e53c2
commit f1d3e38f8f
29 files changed
+1335 -149

No files matched your search

+34 -5
View File
@@ -439,9 +439,10 @@ docker compose -f docker-compose.dev.yml up -d --build # must be running
| `attachments-lifecycle` | 10 | a picture is kept while any version shows it, and freed once none does |
| `conflict` | 10 | a late write wins but the state it buries survives as a version |
| `export` | 21 | the downloaded bytes are real Markdown, ZIP and PNG, unpacked and read back |
| `organise` | 58 | a hand-made order survives a search; separators hold their place; a note exported and imported comes back whole |
| `chapters` | 36 | a filed note stays filed across a sync; the notebook's separators survive a chapter being opened; handles appear only while rearranging |
| `organise` | 60 | a hand-made order survives a search; separators hold their place; a note exported and imported comes back whole |
| `chapters` | 46 | a filed note stays filed across a sync; the notebook's separators survive a chapter being opened; handles appear only while rearranging |
| `offline` | 17 | a cold page load with the network off still opens notes and searches them — and a note made, written and drawn on offline arrives whole once there is a connection |
| `tables` | 8 | a long table is broken between its rows, with none left lying across the gap, and no page furniture reaches the stored note |
| `sync` | 7 | a PDF written on one device — document, drawing and pinned notes — reaches a second one, which can find it by its contents without opening it |
Each suite creates a throwaway account through the admin API and deletes it
@@ -526,9 +527,22 @@ appear in an export. Two tests hold that down — one asks whether any block sit
in a gap, the other reads the stored body back and looks for them.
The unit is a whole block. A paragraph that would be split moves down entire,
which is what a page break means on paper. A single block taller than a page — a
long table, a tall image — is left where it is and runs over the gap: splitting
one would mean laying out its insides ourselves.
which is what a page break means on paper.
**A table is the exception, and has to be.** Moved whole it either jumps to the
next sheet leaving the rest of this one blank, or — being longer than a sheet —
has nowhere to jump to and lies straight across the gap with a row cut in half.
So a table is broken **between its rows**, which is where a table breaks on paper
too. The spacer there is a row of its own: a `div` inside a `tbody` is not a
thing the browser will keep, while a `tr` with one borderless cell pushes the
rows after it down exactly as far as needed. Its own spacer rows are subtracted
again on the next measurement, and counted into the shift every block below it
inherits — miss that and everything under a broken table is measured a page too
high.
Anything else too tall to fit anywhere — a full-page image — is left where it is
and runs over the gap: moving it down only puts the same problem one sheet
further on.
Two details that are easy to get wrong and were:
@@ -1094,6 +1108,15 @@ never re-derived from what is on screen, so two rules hold it up:
questions asked of every notebook at once, so there is nothing for an
arrangement to belong to and nowhere to keep it.
**Icons.** A note and a chapter can each wear a mark of their own beside the
name — chosen from a short searchable list rather than the system emoji keyboard,
which is a different thing on every machine and offers three thousand pictures
for a decision that is "which of these is the invoice notebook". The list is
searched by what a thing is *for* ("invoice", "house", "travel"), because nobody
hunts a pictogram grid by shape. The same glyph shows in the list and above the
editor, so a note is recognised by one sign in both places. A note's mark takes a
colour too; a chapter's uses the colour the chapter already has.
**Separators** are lines drawn between notes, optionally named, stored on the
notebook beside the sort mode. Renaming and removing are both right-click, which
is how everything else in that list is acted on: a left-click on the label used
@@ -1106,6 +1129,12 @@ notes around them are renamed, edited or opened.
One press draws the line; it is named afterwards from its own menu, the same way
it is renamed. A line reads perfectly well unnamed, so nothing is asked first.
From that menu it also takes **its own colour and one of five shapes** — solid,
dashed, dotted, double or a thick band. Three lines through one notebook are
easier to tell apart when they differ; grey-on-grey they read as the same line
repeated. **A chapter can be divided the same way**: its lines carry its id and
stay in it, and both places a chapter is shown draw them from one component, so
it cannot be divisible in the column and not in the unfolded block.
They are shown only in the manual order: in "newest first" the notes would slide
past the line on every edit — and **the button that draws one is only there in