Commit Graph
234 Commits
Author SHA1 Message Date
pastilhasandClaude Opus 5 16295eeea1 Shape, on a photograph block
Choose 16:9 and the band gets shorter than the picture — the ratio becomes a slot
shape and the site serves a rendition cut to it, rather than a whole photograph
scaled down by the browser.

`setContent` writes the whole content object, because the API replaces it rather
than merging: a PATCH with `{ ratio }` alone would drop the url.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-01 21:29:36 +01:00
pastilhasandClaude Opus 5 2ec48a1a76 a reload lands where you were, not at the top
The scroll ran on `rendered` changing, which is the moment the reload STARTS —
frameDoc still pointed at the outgoing document, so it scrolled the page about to
be replaced and the new one arrived at the top. Every write from the editor did
it: reorder a gallery or a partner, lose your place.

It now happens in onDocument, against the document that has just loaded. The
effect stays for the other case — a different band chosen with no reload — and
keeps its smooth scroll, because there you are watching it move.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-01 20:58:23 +01:00
pastilhasandClaude Opus 5 4435537ae2 a partners block edits the site's partners
The block places the list; it does not hold one. So this edits the singleton and
every page showing them changes together — which the panel says out loud, because
the editor sits inside a block on a page and everything else in that column
belongs to the page.

Same gesture as the gallery items: a grip on the left, live reorder, one write at
the end carrying every id. Two ordered lists, one thing to learn.

A new partner is named from its filename and renamed in the field beside it — the
API refuses one with no name, and asking in a second dialog before the logo has
been seen is a form in front of a form.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-01 20:55:07 +01:00
pastilhasandClaude Opus 5 459793a33c one gallery editor, in both places
GalleriesPanel drew its own copy of the item list — same operations, same routes,
arrows instead of a grip. It is a master list now: which galleries there are,
making one, deleting one. What is inside the selected one is announced to the
editor column and drawn by GalleryItems, which is what a gallery BLOCK already
used.

The device toggle only shows where there is a page to look at. It sets the width
the preview renders at, and Galleries, Media and Administration have none.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-01 20:44:52 +01:00
pastilhasandClaude Opus 5 54141726d6 gallery items reorder by dragging
Nine items meant eighteen arrows and four presses to move something from the
bottom to the top. A grip on the left, the row as the drop target, and the list
rearranging as the pointer crosses it — the same gesture the page rows use.

One write at the end, carrying every id in order.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-01 20:39:38 +01:00
pastilhasandClaude Opus 5 d4842c9c3e a gallery block edits its gallery
Add, remove, reorder and caption, in the editor column. A gallery block on a page
IS a gallery, and being sent to another section to reorder it means losing the
page you were arranging it for.

It reads the gallery itself from its id, so it can be dropped anywhere something
knows one.

GalleriesPanel still draws its own copy of this list. That is a real duplicate
and it should adopt this component — its version has the same operations against
the same routes, plus creating and deleting whole galleries, which this does not.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-01 20:35:15 +01:00
pastilhasandClaude Opus 5 96d917f9e1 Width, instead of a negative number to match by hand
Inside the band, whole width of main, or whole page width. The negatives are
gone from the padding select — padding is padding again.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-01 20:23:40 +01:00
pastilhasandClaude Opus 5 173e917838 read the input value before the updater runs
React nulls `currentTarget` once the handler returns, and a functional state
updater runs after that — so typing one character into a band's name threw and
took the whole editor panel down.

Three places, all mine from today. Everything older read the value eagerly.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-01 20:16:22 +01:00
pastilhasandClaude Opus 5 5b4571ddd7 guides on the page builder, and negative horizontal on a block
The measure was drawn on Layout only, and this is the screen where things are
placed against it. It also answers the question a negative margin asks: a block
escaping the gutter has to be seen escaping it, against the line it crossed.

Horizontal padding now offers negatives, built from the same scale so there is
still one list.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-01 20:09:25 +01:00
pastilhasandClaude Opus 5 c1cf908206 the media preview takes the column
A strip of a photograph tells you it is a photograph and not which one. Full
width, its own aspect, under the button rather than beside it.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-01 20:01:10 +01:00
pastilhasandClaude Opus 5 6ab2fab4ac a media block shows what is in it
"Choose media…" and nothing else asks somebody to open a dialog to find out what
they already chose. The thumbnail and the filename answer it where they stand.

A video shows its poster rather than playing: the question is which file this is,
and a frame answers that.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-01 19:58:04 +01:00
pastilhasandClaude Opus 5 9c97773cf7 selecting a block shows its settings, not a modal
editComponent means "edit what is IN this block", and for media and galleries
that is a dialog over the whole screen. Firing it on selection threw one at you
before you had asked for it — those kinds get a button in the settings instead.

Free text keeps opening inline, because its editor is in the same column and
opening it IS showing the settings.

The text editor now only renders when it belongs to the selected block. A stale
one showed the previous block's words under the new block's title.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-01 19:55:05 +01:00
pastilhasandClaude Opus 5 1ec361d006 a block's spacing sits with its title; page settings need the page selected
Spacing had a link in the chrome painted onto the page and lost its door with the
rest of it. It belongs beside the heading: both are properties of the selected
block, and one of the two is not worth a place of its own to go to.

The page's name and address now show only when the page row itself is selected.
With a band or a block open they sat above an editor about something else and
read as belonging to it.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-01 19:50:18 +01:00
pastilhasandClaude Opus 5 361684b8c5 every block is selectable, and has a Title
canEditComponent answers "is there content to type", and a heading is not
content — so the blocks with no editor of their own are now selectable too, and
get the heading alone.

The live draft writes into [data-block] when there is one. A titled component
renders as a wrapper, and writing into the wrapper would replace the heading with
the paragraph as somebody typed.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-01 19:46:59 +01:00
pastilhasandClaude Opus 5 aaf767087e selecting a band opens its settings
Name and Title, in the editor column — the band row in the nav had only scrolled
the preview until now.

Both, not the title alone: a form showing one of two names invites somebody to
change the wrong one, and `name` could only be set when the band was created.

Last in the editor's order, so a block or a spacing editor wins — those were
opened deliberately, and the band is merely still selected underneath them.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-01 19:41:26 +01:00
pastilhasandClaude Opus 5 949d61efc6 a band lists its blocks, and selection is the URL
A fourth level under the open band only — a page of six bands with four blocks
each is thirty rows, and the nav stops being somewhere you can find anything.

Blocks are named by the same list the picker offers, so a thing is called the
same word wherever it appears.

Clicking a block in the PAGE now writes that address too, rather than calling the
handler directly. Both ways of picking a block are the same act, so neither can
disagree with the other about what is selected — and closing it is the band row.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-01 09:49:44 +01:00
pastilhasandClaude Opus 5 7c4c3f48a8 the open page lists its bands in the nav
A third level, under the selected page only — every page has bands, and listing
all of them would make the nav longer than the site.

Announced by the builder rather than fetched again: it already reads them to know
what it is looking at in the document, and it mounts exactly when a page is open.
Cleared on unmount, or the nav keeps listing the last page's bands.

Clicking one writes a third URL segment and the preview scrolls to it, keyed on
the render count too so the position survives a save replacing the frame.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-01 09:45:07 +01:00
pastilhasandClaude Opus 5 2eb9142484 the page builder draws nothing on the page
A bar on every band, Edit / Spacing / Delete above every block, dotted outlines
around blocks and columns, an add-zone at the end. Look at that and you are
looking at the editor, not the page — on the screen whose whole purpose is
judging the page.

A click selects a block and its editor opens in the panel beside the preview,
where every other control now lives. data-fofos-component stays: it is how the
panel writes a draft into the page as somebody types.

Adding a section, adding a block, deleting either and opening a spacing editor
have no door any more. The handlers are untouched and nothing calls them.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-01 09:40:34 +01:00
pastilhasandClaude Opus 5 dfc22d2d2c a page's settings sit above the editor
Menu item, address and page title — what the retired /fofos-admin/pages panel
held, moved to the column where everything else about that page is edited.

Above the device toggle, because the toggle scopes what is under it to one width
and none of these three have widths. Read from the URL rather than announced:
they belong to the page whatever is selected inside it, so picking a block must
not replace them.

A changed slug changes the page's own address, so the panel follows it — left
alone the URL would name a page the list no longer holds.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-01 09:09:35 +01:00
pastilhasandClaude Opus 5 d2ac0aca1b Home stays first, and a reorder shows in the preview
Home has no grip, and dropping onto it is refused — hiding the handle alone
would still let something be dragged above the site's front door.

Every preview now reloads on the change channel, not just the page builder's own
writes. The Layout preview draws the top menu and had no reload token at all, so
the one screen where a reorder is visible was the one that never showed it.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-01 09:05:32 +01:00
pastilhasandClaude Opus 5 ca023eb651 pages reorder by dragging; the list panel is gone
The grip drags and the row is the drop target — a Link is draggable by default
and drags its URL, so making the row itself draggable fights the browser for what
the gesture means.

The list rearranges as the pointer crosses a row rather than on drop, and the
write happens once at the end: PUT /pages/order takes the whole set, because an
order is a property of the set.

/fofos-admin/pages was a list of cards beside a nav that already lists the pages.
Two lists of the same thing, and the one you were looking at was never the one
you had clicked. It redirects to the first page now.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-01 09:02:02 +01:00
pastilhasandClaude Opus 5 ce1eb43d51 Layout is one row; Pages always shows the pages
Top Menu, Content and Footer were a hierarchy the screen does not have — all
three are edited by the same controls at the same time, so clicking one changed
the URL and nothing else.

The pages were announced by PagesPanel and only by PagesPanel, which mounts when
Pages is open. So they were invisible in the nav until you had already been to
the page that lists them. The nav fetches them itself when nobody has said yet;
the channel stays, and is still why a rename shows here the moment it is typed.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-01 08:58:31 +01:00
pastilhasandClaude Opus 5 aab536059b the empty size option names the size
"Inherit (default)" answers a question nobody asked. What somebody wants from
that dropdown is what it is now — and a label that will not say makes them change
the setting to find out, which is the one way to lose the answer.

It reads Default (4xl) at the smallest width and Inherit (2xl) above it. The
stylesheet's own sizes come from the API, which reads them out of styles.css.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-01 08:48:51 +01:00
pastilhasandClaude Opus 5 b165e10f53 every proxied request carries who is asking
Officer's session is the only place the acting user is known, and fofos writes it
into its own change history. An email in X-Actor, because that database has no
users to point at.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-01 08:36:34 +01:00
pastilhasandClaude Opus 5 fc3b9cca4a Sections and Footer get a Gap, three fields across
The room between a band's columns: gap-8 in a two-column section, gap-x-24
gap-y-10 in the footer. Both were written into the template that drew them.

The canvas now SKIPS a utility nothing has chosen instead of stripping it. The
old rule lied twice — a section's own padding vanished while the panel was open,
and a band with no chosen gap lost the site's default.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-01 08:15:01 +01:00
pastilhasandClaude Opus 5 33f2ea4663 the editor sections fall to one column when it is narrow
A container query on the scroller, once, so a new section is responsive by being
in the column rather than by remembering to say so. Below 320px the two-column
sections stack instead of truncating every select to "Martia…".

Colors stays flex-wrap: three swatches in a two-column grid is 2 and 1.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-01 08:10:05 +01:00
pastilhasandClaude Opus 5 905e2e3325 one list of roles, named for what they are
Fonts and Font Sizes are the same four things, so they now read in the same order
under the same names — Menu, Titles, Headings, Body — from one list.

font_display is the largest statements and font_title is a section heading, which
is the reverse of what the words suggest. The labels say what the reader sees.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-01 08:08:05 +01:00
pastilhasandClaude Opus 5 5f7e4d7d61 Font Sizes, per role, per width
A fifth section between Fonts and Spacing. The same four roles the families use,
so a template asks for a role and gets both — and a role used at two sizes on
purpose collapses to one, which was the trade taken over a separate list of text
roles.

The live preview builds the same stylesheet the site renders, because a size is
three values and an inline style cannot carry a media query.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-01 08:03:21 +01:00
pastilhasandClaude Opus 5 8f26d0d3b6 Spacing says which width it is for
Every field in there writes one breakpoint, chosen by the tabs at the top of the
panel. Without the name the same six selects mean six different things depending
on something above them.

One span, not two: the trigger is justify-between and puts the chevron last.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-01 07:54:04 +01:00
pastilhasandClaude Opus 5 2a8f3b5814 no hand holding
The line under every nav row, the line under every font select, and the caption
under the preview. Each explained a control to somebody who has already found
it, and the caption was wrong as well — there is no Save to press.

The nav rows are one line now, so they centre.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-01 07:50:25 +01:00
pastilhasandClaude Opus 5 939f5bf80b a section title outranks its own fields
text-xs was the size of the labels under it, so the three headings read as one
more row of form furniture. Bigger and heavier — weight is the signal that
survives at this density without adding a second thing to look at.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-01 07:46:45 +01:00
pastilhasandClaude Opus 5 c0c88a434d the toggle drops its labels when the panel is narrow
A container query, not a screen one: this sits in a workspace panel whose width
is a divider somebody drags, so the window says nothing about the room. Below
240px the icons stand alone and the word is the tooltip.

Every editor section starts open. It opened on one, from ?tab=, which is what
tabs want — these are not tabs, and a collapsed column asks somebody to go
looking for the setting they came for. ?tab= is gone with it.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-01 07:44:15 +01:00
pastilhasandClaude Opus 5 d218d3c7a8 the device toggle is three labelled tabs
Icons alone told three things apart by proportion at 12 pixels. Full width, one
of three filled, and the word from DEVICES.

The `size` prop is gone with the bar that needed the small one, and so is the
second copy inside Spacing — the panel header scopes the whole editor now.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-01 07:41:09 +01:00
pastilhasandClaude Opus 5 e45e3d84a8 the bar is gone; the device toggle is the editor's
It sat across the top of the detail panel with Sync, Build and Publish — three
things that act on the site, beside one that decides how you are looking at it.
The toggle belongs with the settings it scopes: a spacing is chosen per width,
so the control saying which width is the first thing in that column.

Sync, Build and Publish are unmounted until they have a place of their own.
ViewModeProvider stays; it was never the bar's.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-01 07:38:43 +01:00
pastilhasandClaude Opus 5 b5ca67e68e every control writes itself
The Save button is gone, and so is the SaveTarget context that announced it.
Every screen here is a preview of the thing being edited, so a change is already
visible before it is written — a button then asks somebody to confirm what they
can see.

useAutosave debounces a burst into one request. It takes the unsaved state as a
string rather than a flag, so a failed save is not retried on the next render,
and it flushes on unmount so a section change loses nothing.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-01 07:34:34 +01:00
pastilhasandClaude Opus 5 6717402331 the preview is as tall as the page
The frame took all the room the panel had, so a short page left a band of white
under the footer with the measure guides running down through it. An iframe has
no height: fit-content, so the page is measured inside it and the frame follows.

The wrapper, not the body — body is min-h-screen, so measuring it would ask the
frame how tall the frame is.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-01 07:29:08 +01:00
pastilhasandClaude Opus 5 6242fb03a6 routing is this plugin's, not the manifest's
The platform hands over the whole subtree under the mount. Which paths exist and
what they mean is web/routes.ts.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-01 07:17:38 +01:00
pastilhasandClaude Opus 5 a7fc07c52f sections are paths, not a query string
The admin declares its routes in the manifest, so /fofos-admin/layout/header and
/fofos-admin/pages/home are real URLs. One reader takes the two segments after
the mount; links carry no query string at all, so nothing leaks between
sections.

What stays in the query is how you are looking — device, tab, view — rather than
at what.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-01 04:57:29 +01:00
pastilhasandClaude Opus 5 4d7162363b sections take vertical padding, not a gap
Space between became Vertical padding: space-y hangs its margin below the box,
and the box's bottom border is the separator, so the room never landed above a
rule. The canvas now rewrites both axes on a band.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-01 04:36:22 +01:00
pastilhasandClaude Opus 5 8307591712 spacing is three bands, not one gutter
Top Nav, Sections and Footer each get their own horizontal padding, plus the
one space that band owns: the room under the rule, the gap between bands, the
room above the footer.

The preview marker now names its band, so a change moves one band and not all
three.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-01 04:24:05 +01:00
pastilhas 9c904040c4 label the padding as Top Nav's 2026-09-01 04:05:25 +01:00
pastilhas ed900bc2d3 one padding value, for the device on the toggle
The three columns became one select. Which breakpoint it writes comes from the device control above it,
so the value you see is the value for the view you are looking at.
2026-09-01 04:02:37 +01:00
pastilhas 89380a69d6 the device control spans the section
No label, full width, three across. It scopes the fields below it, so it reads as their header.
2026-09-01 03:55:12 +01:00
pastilhasandClaude Opus 5 852c53dd09 one device control, read from the URL
Spacing's settings are per width, so the section has to say which width it is editing — and the answer
must be the one the preview is already showing, not a second selector able to disagree with it.

It reads `?device=` rather than the ViewMode context, and that is not a preference. The editor is a
SIBLING panel: an element built inside the detail panel resolves context where it is RENDERED, so a
toggle handed over would look up a tree with no provider in it and quietly show the default forever.

The URL is the shared state, which means there is nothing to share. Three components read one
parameter, so they cannot disagree, and the preview follows without being subscribed to anything — it
reads the same value. More editor sections can take the control by rendering it.

The bar's own toggle is now the same component. It had its own copy of the options and the handler,
which is exactly how two controls for one thing start to differ.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-01 03:53:02 +01:00
pastilhas 53d6a0324d Padding is called Spacing
The heading only. What it does is unchanged for now — the word is widening ahead of the behaviour,
which is the right order: the section is about to hold more than one kind of space, and Padding names
only one of them.
2026-09-01 03:49:16 +01:00
pastilhasandClaude Opus 5 59e1218060 a nav link carries only what it means
Pressing Layout while a band was open gave `?section=layout&band=footer`, so the row for the whole
section led to one part of it. Pressing a section carried whatever the last one had left behind.

Every link built a copy of the current query string and deleted the parameters known to be scoped —
`media`, then `page`, and `band` would have been the third. That is a list of exceptions that has to
grow every time a section gains a parameter, and it fails silently when somebody forgets: the link
still works, it just goes somewhere more specific than it says.

Starting from an empty query string inverts the default. A parameter survives a navigation only if the
link says so, which is one decision at each link rather than a list of everything that must not leak.

So a section row is `?section=x`, and a sub-item is that plus its own `band` or `page`. Nothing else
rides along, including the device and the open tab — both are restored to their defaults by the panel
that owns them, which is where a default belongs.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-01 03:33:48 +01:00
pastilhasandClaude Opus 5 5cc4742119 Colors, Fonts, and two by two
The two headings take the site's own spelling and the shorter word. "Typefaces" is the more precise
term and "Fonts" is the one everybody reaches for; a section heading is a signpost, not a definition.

The fonts go two by two. Four across existed to keep this section the same height as Colours, because
as tabs they shared one grid cell and a taller panel moved everything below it. Stacked sections do not
have that constraint — each is as tall as it is and nothing above it moves — so the reason expired with
the tabs.

What four across cost was the labels: in a panel this narrow every select truncated to "Martia…", so
the row said four times that a font had been chosen and never which one. Two columns give each the room
to be read, which is the only thing the control is for.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-01 03:31:03 +01:00
pastilhasandClaude Opus 5 dd10a4df45 Layout's controls are stacked sections, not tabs
Three tabs became three collapsible sections in a column, because there are going to be more than
three. A tab strip works while the names fit on one line and degrades the moment they do not — it wraps,
or it scrolls, and either way the set stops being visible at a glance.

`type="multiple"`, so more than one can be open. Tabs enforced exactly one, which is right when the
panels are alternatives and wrong when they are parts of the same thing: the colours and the padding of
a layout are read together as often as separately.

The grid overlay went with them. Every panel shared one cell so the block stayed as tall as the tallest
and did not jump when the tab changed — a real problem that stacked sections do not have, because a
section that is closed occupies nothing and one that is open is as tall as it is.

`?tab=` still seeds which section starts open, so an old link keeps working and lands on the thing it
named.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-01 03:28:15 +01:00
pastilhasandClaude Opus 5 ba2f98c7fb the width label goes outside the measure
It sat just inside the left guide, which is on top of the page — over the logo, on this site — and it
is not part of the page. The margin is the one strip on screen belonging to the editor rather than to
the site, so the number describing the measure lives there.

Right rather than left: the eye reads the guide and then the width, so the label is the answer to the
line beside it, and the right margin is the one a wide frame has room in.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-01 03:25:43 +01:00
pastilhasandClaude Opus 5 cee2f5c8e2 Desktop is the panel's width, and the guides are the only marking
Two things, both asked for after looking at it.

The tint came out. Shading the margins was meant to say "the page does not use this", and against a
white page it read as a blue background — a colour the site does not have, on the screen that exists to
show the site's colours. The two hairlines say the same thing without claiming anything.

And Desktop is fluid. `width: null` means the frame takes whatever the panel gives it, which is the
honest answer for a device that has no width: a desktop is whatever window somebody opened. 1440 was a
guess that then had to be centred and scrolled inside the panel — a page rendered at one width and
looked at inside another, with dark room either side of it.

Tablet and mobile stay pinned, because 834 and 390 are claims about real devices and pinning them is
the only way the preview can answer "what does this look like on a phone".

Fluid, the frame IS a desktop window: the site's media queries answer the panel's real width, and the
measure guides mark where the content stops in the pixels you are actually looking at.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-01 03:24:23 +01:00