| version | alpha | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| name | Solid Imager | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| description | A calm, dense, media-first workspace for searching, reviewing, and managing large image libraries. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| colors |
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| typography |
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| rounded |
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| spacing |
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| components |
|
Solid Imager is a workbench, not a marketing site. Its visual character is calm, compact, and media-first: the image collection receives the available area while navigation and metadata remain immediately reachable without competing with it.
Three sources define the system, in this order:
- The tokens in this file are the normative visual values.
- The guidance below defines why and when those values are used.
/design-labis the executable reference for layout and interaction behavior.
Use the shared components in packages/ui and continue to source primitives from
Solid UI. The design lab may compose those primitives, but must not create a
parallel component library. The lab is a migration reference; it is not evidence
that a mocked concept such as accounts or a dedicated route must exist in the
product. Controls that only demonstrate a visual state in the lab are not an API or
feature contract until the corresponding product behavior is implemented.
The governing principles are:
- Media first: use the viewport for media or actionable data, not decorative framing.
- Dense, not cramped: prefer 8–16px internal spacing and clear separators over oversized cards and empty margins.
- One task, one obvious place: Sources live in the sidebar, background work in Jobs, imports in the inbox, and data transfer under Manager tools.
- Stable context: preserve source, filters, selection, and scroll position when moving between a collection and an item. Route-specific data must always follow the current route ID.
- Progressive detail: keep frequent actions visible and move secondary actions into popovers, drawers, or “More actions”.
The palette is built from warm near-whites, charcoal text, quiet green-gray borders, and one teal interaction color. It should feel closer to a focused desktop tool than a colorful dashboard.
primarymarks the current location, primary actions, selected media, and successful completion.primary-hoveris reserved for hover/pressed states.focusis the keyboard focus ring. Do not replace it with a colorless outline.canvasis the main workspace;surfaceis an interactive panel; andsurface-subtleseparates persistent regions such as the sidebar and inspector.surface-selectedis the only large-area selection tint. Selection must also use an icon, ring,aria-current, oraria-pressedrather than color alone.borderseparates regions;border-strongdefines controls. Thedividerandinput-bordercomponent tokens represent one-pixel strokes, not filled surfaces.textis for headings and primary values.text-secondaryis for labels and metadata.text-mutedremains WCAG AA compliant for small helper text.destructiveis only for irreversible or failed actions. Warnings and information use their dedicated foreground/surface pairs and must not borrow destructive red.
Avoid broad gradients, tinted page backgrounds, and arbitrary accent colors. A black-to-transparent gradient is allowed only as a thumbnail text scrim. Do not add a gray frame behind a full-size media preview; the preview itself should use the available surface.
The current production theme and design-lab prototype predate this canonical palette: the theme still contains a zinc/black primary while parts of the lab use nearby colors inline. During migration, map the tokens above to shared CSS variables first. Do not copy the lab's one-off hex values into production components.
Use the operating-system sans-serif stack so Japanese and Latin text render consistently without a remote font dependency. Typography creates hierarchy with weight and spacing, not dramatic size jumps.
- Page titles use
page-title(20px/600). - Card and inspector titles use
section-title(16px/600). - Controls and ordinary content use
body(14px). - Form labels and secondary table data use
label(12px). - Badges, counts, file extensions, and compact status text use
metadata(11px).
Prefer sentence case. Use all caps only for very small design-lab taxonomy labels, never for ordinary navigation or actions. Filenames and identifiers may wrap or truncate according to context, but they must expose the full value through the detail view or an accessible name. A production control group uses one active locale; do not mix Japanese and English labels inside the same workflow. Explanatory copy in the design lab may remain Japanese while product localization is undecided.
The application fills 100dvh. The expanded sidebar is 216px; its collapsed rail
is 64px. The collapse control appears next to “Solid Imager” on hover or keyboard
focus and remains visible in the collapsed state. Main content is always
min-width: 0 so it can shrink without forcing page-level horizontal scrolling.
Each page has one vertical scroll owner. Persistent headers, sidebars, inspectors,
and action footers stay outside that scroll region. Use overscroll-contain and
scrollbar-gutter: stable for nested work areas; never rely on scrolling the body
to reveal content hidden inside another scroll container.
- Collection: search/toolbar at the top, responsive media grid in the center, and an inspector only when it has enough width to be useful.
- Detail: edge-to-edge media preview plus a metadata inspector. On a narrow viewport the inspector stacks below the preview at full width.
- Management: full-width list or table with compact filters; a selected-row inspector appears only on wide layouts.
- Settings: categories sit at the far left and the editor grows horizontally. Do not center the form in a narrow decorative column.
The media grid uses the same responsive rule for content and loading placeholders: between 2 and 8 columns according to the grid container, not a fixed three-column cap. When the result count is known, render the matching number of placeholders. When it is not known, fill the visible grid area rather than showing a hard-coded four-item skeleton. Loading and loaded states must not visibly change column count.
A collection inspector preview must be at least as large as one grid tile. On smaller viewports, omit the inspector and open detail or a drawer instead of showing a token preview that consumes space without adding information.
At desktop widths, the detail view assigns all remaining width and height to the
media and uses a roughly 22rem inspector. The image uses object-contain, carries
no decorative gray wrapper, and is not constrained by an arbitrary centered max
width. At narrow widths, media and metadata stack and both use the full content
width. Avoid residual overflow that makes a sufficiently large viewport scroll by
a few pixels.
Reflow before clipping. Controls may wrap into an additional row, category tabs may scroll horizontally on small screens, and inspectors may disappear or stack. Do not retain desktop max-widths that create unused vertical-screen gutters. Touch targets are at least 44px on narrow viewports; desktop controls may use the compact 36px height. Use the Tailwind breakpoints already adopted by the application (640/768/1024/1280/1536px) and add container-based thresholds when a component's available width, rather than the viewport, controls its layout.
The interface is primarily flat. One-pixel borders, background changes, and spacing
create hierarchy. Ordinary cards use at most a subtle 0 1px 2px shadow; never
stack multiple framed cards merely to separate sections.
Strong shadows are reserved for content that floats over the work area: popovers,
modals, drawers, and toasts. A centered modal scales/fades around its final center.
A right drawer enters from and exits toward the right edge. Its origin and final
position must not drift during animation. Disable nonessential transforms and
transitions under prefers-reduced-motion: reduce.
Use 6px rounding for controls, 8px for panels and overlays, and 4px for small internal elements. Pills are reserved for statuses, counts, and removable search tokens. Media thumbnails use 6px rounding; the full-size media preview itself does not need a card silhouette.
Avoid exaggerated rounding, floating “islands”, or nested rounded containers. A shape should communicate a boundary or interaction, not decorate empty space.
- Primary destinations are Library, Media Detail when contextually relevant, Manager, Jobs, and Settings.
- Search remains globally discoverable from the sidebar and collection toolbar.
- Sources are a collapsible sidebar section, not a dedicated full-screen route. Show connection/sync status and media count beside each source.
- Import inbox is a sidebar icon with its pending count. It opens a review modal where users choose a destination source and select or discard incoming posts.
- Jobs shows an active/failed count badge. Collapsed navigation retains compact badges and accessible labels.
The import inbox opens a focused modal rather than a full page. It provides the destination source, selected count, Select/Clear all, Delete, and Import actions. Incoming post cards use 2 columns on the narrowest layout, then 3 and 4 as space allows; the modal may grow to roughly 64rem but keeps its header and footer visible.
The collection uses one growing search composer that combines free text and
removable tokens. Supported prefixes are name:, tag:, -tag:, character:,
ip:, author:, and project:; comma-separated values are allowed where the
underlying filter supports multiple values. Display at most four tokens inline and
collapse the remainder into a count.
The filter popover edits the same state as the composer. “Simple” exposes frequent fields, “Detailed” opens the full condition builder, and “Similar” shows the vector source and result limit. These modes must not create competing stores or remount an input on every keystroke. Search focus and cursor position remain stable while typing.
Primary buttons represent one preferred next action per region. Secondary buttons use a white surface and strong border. Destructive styling is reserved for the specific destructive action, not the whole footer.
Disable an asynchronous trigger while its request is pending to prevent duplicate jobs. Keep the label width stable where practical, expose progress with a polite live region, and provide completion feedback outside the button. Long-running work belongs in Jobs rather than keeping a modal open.
Media tiles use a 4:3 collection aspect ratio unless source content requires a specific view. Hover/focus may reveal filename and extension; selection adds a teal ring and check indicator. Opening an item preserves collection source, filters, selected item, and scroll position. Browser Back restores that context. Opening a different route UUID must update the preview and sidebar immediately; cached blob URLs are never the identity of the route.
The detail header keeps Back, previous/next, and the two most frequent actions visible. Secondary AI, vector, download, and destructive operations belong under “More actions”. Metadata is grouped into Description, Relations, Tags, and File information without wrapping the media in an extra card.
- Popover: lightweight, non-modal settings that apply in place. The underlying collection remains interactive.
- Modal: a short, focused task requiring completion before returning. It opens and closes around the same centered position and stays within the safe-area-aware viewport height.
- Drawer: longer contextual editing while retaining awareness of the list. It is right-aligned, owns its internal scroll area, keeps its footer visible, and is at most 28rem wide.
- Discard confirmation: Escape and outside click close a clean overlay. If an overlay contains unsaved changes, both actions open a discard confirmation instead. Closing returns focus to the trigger.
Toasts appear at the top right, with a maximum of four visible notifications and an explicit close button. Use a 20px desktop offset and 10px stack gap. On narrow screens they use the available width with 12px side offsets. They never light-dismiss when another area is clicked.
- Success is confirmation-only and normally closes after about four seconds.
- Job submission stays for about seven seconds and offers one action: “View Jobs”.
- Warning stays for about eight seconds, explains a recoverable condition, and may offer one recovery action.
- Error names the failed operation, stays for about nine seconds, and may offer Retry.
Do not report continuous batch progress through repeated toasts. Send the work to Jobs, use a single submission toast, and update the Jobs view through live events.
Manager uses compact tables for IPs, Characters, and Projects, with a wide-screen selection inspector. Duplicate detection, AI tagging, and vector extraction are tools that submit Jobs. Export and restore replace the legacy dump-oriented UI and live under a Data transfer tool.
Jobs is the canonical view for queued, running, failed, and completed background work. It combines filterable rows with progress, retry/cancel actions, and a wide-screen inspector. Settings uses a left category tree on desktop, horizontal category tabs on mobile, full-width field groups, and a sticky save/discard bar only when the form is dirty.
All icon-only controls require an accessible name. Use native buttons and form
labels, aria-current for navigation, aria-pressed for selection/toggles, and
polite live regions for asynchronous feedback. Keyboard focus is always visible.
Overlays trap focus appropriately and restore it to their trigger.
Preserve route and collection state deliberately, but never preserve stale entity data across a route ID change. Direct navigation, reload, client navigation, and browser Back must render the same item or source.
- Consult this file before changing shared UI, then compare the result in
/design-labat wide and narrow viewports. - Reuse Solid UI primitives and promote recurring compositions into
packages/ui. - Give each region one scroll owner and verify direct navigation, reload, and Back.
- Use the shared spacing, radius, type, and color values instead of introducing a nearby one-off value.
- Use available area for media, tables, and forms; let wide screens become useful.
- Match skeleton count and grid geometry to the loaded collection.
- Validate this file with
bun run design:lintafter changing tokens or guidance.
- Do not cap the media grid at three columns or show a fixed four-item loading state.
- Do not create a separate Sources screen while the sidebar hierarchy is sufficient.
- Do not revive separate dump screens; use Manager → Data transfer and Jobs.
- Do not make an inspector preview smaller than the tile it is meant to clarify.
- Do not add gray image frames, decorative cards, or centered max-width wrappers that waste an otherwise usable viewport.
- Do not use a toast as a progress monitor or offer multiple competing toast actions.
- Do not silently close dirty modals or drawers on Escape or outside click.
- Do not add account/profile UI until the product has an account concept.
- Do not hard-code a new visual value without first deciding whether it belongs in the token set above.