Give the composer footer a bottom padding #240

Merged
robbertbos merged 3 commits from fix/composer-footer-padding into main 2026-08-06 18:04:50 +00:00
Owner

Three composers - the thread reply, the new message and the card notes - looked different from each other in ways nobody chose. This makes them one look, with per-consumer differences left as options rather than CSS.

What differed, measured

The inset is always the same sum: box padding + 1px border + 8px inner padding. Only the first term varied.

Box padding Text inset Send button Footer padding
Reply 4px 13px 43px 4/8/8/0
New message 8px 17px 43px 4/8/8/0
Notes 4px 13px n/a 4/0/0/0

Three changes

One box padding. Field.vue defaulted to 8px where the other two use 4px. --field-padding and --field-min-height were never overridden anywhere - knobs with no users that could only produce drift. Both removed, the value hardwired to 4px.

One row height. The send button was 43px against 32px icon buttons. The centres lined up exactly, which is why it read as "the icons sit high" rather than "the button is tall": a row of controls is read on its bottom edge, and the filled pill set that edge 12px below the icons.

43px is not a size NLDD has (the scale is 24/32/44/56). It is what the button inherits from the body's 18px/27px after d13909b removed its font-size. Everything else in this footer is already sm, and sm is what the app uses for compact surfaces generally - 17 usages across FormatToolbar, DiscardButton, LinkBar, TargetPicker and Toast - against md for page and dialog actions. So the send button joins them rather than the row growing.

One footer rule. .composer-footer joins .field-box in base.css. NotesEditor carried only the top padding, so its toolbar sat on the border of its own box. It now gains the 8px under and beside it that the other two already had.

Measured result

Box padding 8px to 4px, box height 131 to 113, send button 43 to 32. Both composers render identically; notes gains 8px of bottom air.

What this does not do

MessageEditor still does not own the box, so the frame is declared per consumer. That is the next step and it is what makes this class of drift impossible rather than merely fixed. Rebased on #235, whose FormatToolbar rewrite made part of the original plan unnecessary: the hand-rolled .heading and .moreBtn controls it was going to resize no longer exist.

Verification

vue-tsc, eslint (0 errors), vitest 692 in 95 files, vite build, release-script tests. Box padding, box height and button heights measured in Chromium on the built bundle.

Three composers - the thread reply, the new message and the card notes - looked different from each other in ways nobody chose. This makes them one look, with per-consumer differences left as options rather than CSS. ## What differed, measured The inset is always the same sum: **box padding + 1px border + 8px inner padding**. Only the first term varied. | | Box padding | Text inset | Send button | Footer padding | |---|---|---|---|---| | Reply | 4px | 13px | 43px | 4/8/8/0 | | New message | **8px** | **17px** | 43px | 4/8/8/0 | | Notes | 4px | 13px | n/a | **4/0/0/0** | ## Three changes **One box padding.** `Field.vue` defaulted to 8px where the other two use 4px. `--field-padding` and `--field-min-height` were never overridden anywhere - knobs with no users that could only produce drift. Both removed, the value hardwired to 4px. **One row height.** The send button was 43px against 32px icon buttons. The centres lined up exactly, which is why it read as "the icons sit high" rather than "the button is tall": a row of controls is read on its bottom edge, and the filled pill set that edge 12px below the icons. 43px is not a size NLDD has (the scale is 24/32/44/56). It is what the button inherits from the body's 18px/27px after `d13909b` removed its `font-size`. Everything else in this footer is already `sm`, and `sm` is what the app uses for compact surfaces generally - 17 usages across `FormatToolbar`, `DiscardButton`, `LinkBar`, `TargetPicker` and `Toast` - against `md` for page and dialog actions. So the send button joins them rather than the row growing. **One footer rule.** `.composer-footer` joins `.field-box` in `base.css`. `NotesEditor` carried only the top padding, so its toolbar sat on the border of its own box. It now gains the 8px under and beside it that the other two already had. ## Measured result Box padding 8px to 4px, box height 131 to 113, send button 43 to 32. Both composers render identically; notes gains 8px of bottom air. ## What this does not do `MessageEditor` still does not own the box, so the frame is declared per consumer. That is the next step and it is what makes this class of drift impossible rather than merely fixed. Rebased on #235, whose `FormatToolbar` rewrite made part of the original plan unnecessary: the hand-rolled `.heading` and `.moreBtn` controls it was going to resize no longer exist. ## Verification `vue-tsc`, eslint (0 errors), vitest 692 in 95 files, `vite build`, release-script tests. Box padding, box height and button heights measured in Chromium on the built bundle.
Give the composer footer a bottom padding
Some checks failed
CI / pre-commit (pull_request) Successful in 1m33s
CI / frontend-test (pull_request) Successful in 6m15s
CI / release-scripts (pull_request) Successful in 11s
security-scan / Python SAST (bandit) (pull_request) Successful in 42s
security-scan / Python SCA (pip-audit) (pull_request) Successful in 1m5s
security-scan / Filesystem scan (trivy fs) (pull_request) Successful in 29s
security-scan / JS SCA (npm audit) (pull_request) Successful in 44s
security-scan / SBOM (trivy) (pull_request) Successful in 19s
test-build / build (backend) (pull_request) Successful in 2m14s
test-build / build (frontend) (pull_request) Successful in 2m32s
test-build / build (pull_request) Successful in 0s
CI / backend-test (pull_request) Successful in 12m45s
CI / e2e (pull_request) Failing after 12m38s
66a83cec49
The send button sat on the bottom border of the field box: MessageEditor's
.footer sets padding-top and padding-right but no padding-bottom, and it is the
box's last child, so only the box's own 4px was left. Measured 13/14/13/5 in the
reply composer and 17/18/17/9 in the new-message window.

Older than it looks: the asymmetry is there since the initial commit 72a135a.
2f31b5e halved the field-box padding, which is what made it visible - so
reverting that commit is not the fix.

One rule covers both consumers: reply 13/14/13/13, new message 17/18/17/17.
robbertbos force-pushed fix/composer-footer-padding from 66a83cec49
Some checks failed
CI / pre-commit (pull_request) Successful in 1m33s
CI / frontend-test (pull_request) Successful in 6m15s
CI / release-scripts (pull_request) Successful in 11s
security-scan / Python SAST (bandit) (pull_request) Successful in 42s
security-scan / Python SCA (pip-audit) (pull_request) Successful in 1m5s
security-scan / Filesystem scan (trivy fs) (pull_request) Successful in 29s
security-scan / JS SCA (npm audit) (pull_request) Successful in 44s
security-scan / SBOM (trivy) (pull_request) Successful in 19s
test-build / build (backend) (pull_request) Successful in 2m14s
test-build / build (frontend) (pull_request) Successful in 2m32s
test-build / build (pull_request) Successful in 0s
CI / backend-test (pull_request) Successful in 12m45s
CI / e2e (pull_request) Failing after 12m38s
to 713fbb7667
All checks were successful
CI / release-scripts (pull_request) Successful in 9s
security-scan / SBOM (trivy) (pull_request) Successful in 20s
security-scan / Filesystem scan (trivy fs) (pull_request) Successful in 20s
security-scan / JS SCA (npm audit) (pull_request) Successful in 22s
security-scan / Python SAST (bandit) (pull_request) Successful in 28s
CI / pre-commit (pull_request) Successful in 34s
security-scan / Python SCA (pip-audit) (pull_request) Successful in 46s
test-build / build (frontend) (pull_request) Successful in 1m0s
test-build / build (backend) (pull_request) Successful in 1m2s
test-build / build (pull_request) Successful in 0s
CI / frontend-test (pull_request) Successful in 1m14s
CI / backend-test (pull_request) Successful in 1m43s
CI / e2e (pull_request) Successful in 4m8s
2026-08-06 14:58:05 +00:00
Compare
One box padding and one row height for the composer
All checks were successful
CI / release-scripts (pull_request) Successful in 7s
security-scan / SBOM (trivy) (pull_request) Successful in 9s
security-scan / Filesystem scan (trivy fs) (pull_request) Successful in 15s
security-scan / JS SCA (npm audit) (pull_request) Successful in 16s
security-scan / Python SAST (bandit) (pull_request) Successful in 19s
CI / pre-commit (pull_request) Successful in 28s
security-scan / Python SCA (pip-audit) (pull_request) Successful in 40s
test-build / build (frontend) (pull_request) Successful in 55s
test-build / build (backend) (pull_request) Successful in 56s
test-build / build (pull_request) Successful in 0s
CI / frontend-test (pull_request) Successful in 1m5s
CI / backend-test (pull_request) Successful in 1m31s
CI / e2e (pull_request) Successful in 3m54s
50e75075b5
The composer's inset is always the same sum: box padding + 1px border + 8px
inner padding. Only the first term differed, and only in one place: Field
defaulted to 8px where ReplyComposer and NotesEditor both use 4px, so the new
message window sat at 17px where the other two sit at 13px. --field-padding and
--field-min-height were never overridden anywhere, so they were knobs with no
users that could only ever produce drift. Both are gone.

The send button was 43px against 32px icon buttons and a 28px heading control.
The centres lined up exactly, which is why it read as "the icons sit high"
rather than "the button is tall": a row of controls is read on its bottom edge,
and the filled pill set that edge 12px below the icons.

43px is not a size NLDD has. It is what the button inherits from the body's
18px/27px after d13909b removed its font-size. Everything else in this footer is
already sm - the formatting controls, the link bar, DiscardButton - and sm is
what the app uses for compact surfaces generally, against md for page and dialog
actions. So the send button joins them at 32px rather than the row growing.

Measured on the built bundle: box padding 8px -> 4px, box height 131 -> 113,
send button 43 -> 32. Both composers now render identically.
robbertbos force-pushed fix/composer-footer-padding from 50e75075b5
All checks were successful
CI / release-scripts (pull_request) Successful in 7s
security-scan / SBOM (trivy) (pull_request) Successful in 9s
security-scan / Filesystem scan (trivy fs) (pull_request) Successful in 15s
security-scan / JS SCA (npm audit) (pull_request) Successful in 16s
security-scan / Python SAST (bandit) (pull_request) Successful in 19s
CI / pre-commit (pull_request) Successful in 28s
security-scan / Python SCA (pip-audit) (pull_request) Successful in 40s
test-build / build (frontend) (pull_request) Successful in 55s
test-build / build (backend) (pull_request) Successful in 56s
test-build / build (pull_request) Successful in 0s
CI / frontend-test (pull_request) Successful in 1m5s
CI / backend-test (pull_request) Successful in 1m31s
CI / e2e (pull_request) Successful in 3m54s
to 3b8007f832
All checks were successful
security-scan / SBOM (trivy) (pull_request) Successful in 11s
CI / release-scripts (pull_request) Successful in 6s
security-scan / JS SCA (npm audit) (pull_request) Successful in 15s
security-scan / Filesystem scan (trivy fs) (pull_request) Successful in 14s
security-scan / Python SAST (bandit) (pull_request) Successful in 20s
CI / pre-commit (pull_request) Successful in 27s
security-scan / Python SCA (pip-audit) (pull_request) Successful in 38s
test-build / build (frontend) (pull_request) Successful in 54s
test-build / build (backend) (pull_request) Successful in 55s
test-build / build (pull_request) Successful in 0s
CI / frontend-test (pull_request) Successful in 1m5s
CI / backend-test (pull_request) Successful in 1m34s
CI / e2e (pull_request) Successful in 3m53s
2026-08-06 18:00:31 +00:00
Compare
robbertbos deleted branch fix/composer-footer-padding 2026-08-06 18:04:50 +00:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
robbertbos/waggle!240
No description provided.