Each panel's root was a plain div with padding, so anything past the panel's
height was simply not reachable — the gallery showed its first two rows of
sixty images, and the Providers panel cut off mid-card. The shell hands a
panel a fixed-height box and does not scroll it for you; plugins/music has
had `h-full overflow-y-auto` on every panel root since it was written.
Collections gets it in both places, the list and the detail view, which are
two separate returns in one file and would otherwise disagree.
`IntegrationsSettings/index.tsx` has carried the rule since email was extracted
on 2026-08-18: a plugin contributes panels, not settings sections. the
extraction brief said the opposite and the brief was wrong.
settings living in the platform mean this plugin is not self-contained — it
cannot be configured on an older platform, and uninstalling would leave a dead
"Atelier" section in the settings screen for someone to delete by hand.
so: a fourth panel, `atelier-providers`, and the default layout stacks it under
Collections in the right column. smallest and last because it is configured once
and then ignored — but it has to be REACHABLE, which is the whole point.
Generate's empty state pointed at "Settings → Integrations → Atelier". it now
points at the Providers panel, which is where the key actually goes.
ported from the standalone app's hash-tab UI. The panels do not coordinate through props (the panel
contract only ever hands a component its panelId) or usePanelChannel-as-selection:
- Gallery's lightbox is ?selected=<id>, Collections' detail is ?collection=<id> — different names
since both panels render on the same route at once
- Generate bumps useAtelierRefresh (added to officerdev/src/channels.ts) when a job finishes;
Gallery subscribes to it — a genuine signal, not a selection, so it stays a channel
images render through GET /files/:filename with a ?token= query param appended client-side
(lib/api.ts's fileUrl), the same escape hatch FileViewer and the music plugin use for exactly this:
a browser cannot set an Authorization header on an <img src>.
Providers is not here — see PLUGIN.md for why it became a platform settings screen instead.
assets/icon.png and assets/splash.png are [placeholder] flat swatches, not real artwork — see
assets/PLACEHOLDER.md.