Commit Graph
4 Commits
Author SHA1 Message Date
pastilhasandClaude Opus 5 9d3cd7702f a media slot is the picture, at the shape the page will show it
It was a read-only text box holding a path and a Browse button beside it. A path is not what anybody is
choosing — somebody picking the header photograph is choosing a PHOTOGRAPH, and reading
`ABOUT US/HEADER.jpg` to find out whether you picked the right one is doing the computer's job for it.

MediaField is the slot: empty, it is a dashed box at the page's own aspect ratio that you click or drop
onto; filled, it is the picture, with Change and Remove appearing over it on hover. The panel also stops
changing height as things are chosen, so a page with three slots starts to look like the page rather
than like a form.

── The aspect ratio is a prop and has to be ──

The header is 21:9, the product video 16:9, a gallery slot square. The component cannot know that and
must not guess: the SITE decides what shape a slot is, and a component that guessed would be a second
opinion to keep in step with the stylesheet. Both callers name the ratio their partial draws.

── Dropping ──

It accepts a drag from Officer's own file browser, which carries paths under
`application/x-officer-files` — the same payload that moves files between windows. So dragging a
photograph out of Media onto a slot is one gesture and no upload.

It does not accept a file from the desktop. That is an upload into originals/, a different operation
with its own failure modes, and the Media section already does it properly.

── Also ──

`thumbUrl` was copied into GalleriesPanel and RecordsPanel and was about to be copied a third time. It
is a module now: three copies of a URL shape is three places to be wrong about the rung when the ladder
changes, which it did four times in a day.

A file that has gone since it was chosen falls back to the empty state rather than a browser's
broken-image glyph, and says so.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-30 23:43:12 +01:00
pastilhasandClaude Opus 5 abdb519e8b one Save, in the panel's bar
Every section had its own Save buttons — four on About, two on Home, one per record — and on a page
long enough to scroll, the button you wanted was the one that had just left the screen.

Now there is one, beside Publish, pinned above the scroll. The section announces whether it has unsaved
changes, whether it is busy, and how to save; the bar renders that. Neither knows what the other is,
which is what keeps DetailPanel a map of keys to components rather than a place that has to know what
each section can do.

── What this replaces ──

The per-card saves existed because the API treats an absent key as "leave it alone", so a Save carrying
everything meant a half-written manifesto shipping with a photograph somebody meant to change. With one
Save that is the model rather than an accident: one press writes the page you are looking at.

The cost, stated plainly: there is no longer a way to commit one part of a page and leave the rest.
Nothing here needed that, and if something ever does it wants its own verb rather than four buttons all
called Save.

── Dirty is a comparison, not a flag ──

Against what the server last returned, field by field. A flag says "something was typed" and stays true
after you undo it by hand; a comparison says "this differs from what is stored", which is the question
a Save button is actually answering — and it is what lets the button be dead when there is nothing to
do, which is the whole value of having one.

The gallery picker on Home is deliberately outside it and still writes on selection: a <select> that
needs a second press to mean anything is a control people believe they have already used.

Sections with nothing to save render no button rather than a dead one. A permanently disabled control
invites a press and teaches that pressing does nothing.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-30 23:22:35 +01:00
pastilhasandClaude Opus 5 9fd5ffd925 the detail panels scroll
Four sections could not be scrolled: About, and Gallery, Drops and Collabs, which are three
configurations of one panel. Both of those panels were written yesterday with `overflow-auto` and no
height, so they grew to fit their content and ran off the bottom of the workspace instead of scrolling
inside it.

`overflow-auto` only does something on an element with a height to overflow. DetailPanel gives its
child `min-h-0 flex-1` inside a `size-full` column, so a panel that says `size-full` fills exactly that
box and scrolls within it — which is what Home, Galleries and Administration were already doing and
what these two were copied from without.

Messages had the same fault in a different shape. Its list is a flex child with `flex-1 overflow-auto`,
and a flex child defaults to `min-height: auto` — it refuses to shrink below its content, so the list
grew the panel rather than scrolling. `min-h-0` is what lets it shrink, and therefore what makes the
overflow mean anything.

Audited the rest rather than fixing the reported ones: every panel with an `overflow-auto` now pairs it
with a height, and the two that have none are centred single screens with nothing to scroll.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-30 22:37:23 +01:00
pastilhasandClaude Opus 5 0dce8fcb3c About Us
Four bands in the order the page shows them, which is the sitemap's shape exactly: a HEADER of a
photograph and a phrase, then ABOUT US, then PRODUTO with a video beside its text, then MANIFESTO.

No schema change and no API change — `about_content` already carries every one of those columns and
`aboutRouter` already reads and writes them. This is the screen that was missing, not the data.

One save per band, the rule Home follows and for the same reason: `take()` treats an absent key as
"leave it alone", so a single Save carrying every field would let a half-finished manifesto ride along
with a photograph somebody meant to change.

Both media slots go through MediaPicker rather than a text field. A path somebody types is a path that
is wrong by one character and renders as a broken image. One picker serves both, with `picking` naming
which slot asked — two would be two copies of a modal that already knows how to browse originals/.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-30 22:33:45 +01:00