The single-row top bar was a flat flex row, which made the search field
drift left or right depending on how wide the surrounding clusters were.
Rework it as a 3-column CSS grid (left zone, search, right zone) so the
search input lands at the geometric center of the window regardless of
the side-zone widths.
Mechanics:
- `.topbar-single` becomes `display: grid` with
`grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr)` and a 16 px
column gap. The middle (auto) column holds only the search, which is
capped at `flex: 0 1 360px` so it cannot push into the side columns.
- The left and right zones are flex containers with
`justify-content: space-between`, so brand pins far-left while filter
pills hug the search, and sort hugs the search while the kebab pins
far-right. The filter pills are now grouped semantically with the
search (they scope it) instead of floating next to the brand.
- A `@container launcher (max-width: 1100px)` rule collapses the layout
back to a single nowrap flex row at narrow widths — the geometric
centering stops reading at narrow widths and would otherwise force
awkward truncation, so we abandon it rather than fight it.
- The `.launcher` root opts into container queries via
`container-type: inline-size; container-name: launcher`.
`launcher.jsx` now wraps the existing children in `.topbar-left`,
`.topbar-center`, `.topbar-right` (plus a `.topbar-left-trail` /
`.topbar-right-lead` for the inner space-between alignment), but each
control component is otherwise untouched.
The README's "Top bar" section is rewritten to spec the new layout, and
a new "Changes since v2" section calls it out at the top of the
handoff. The game-directory button line is left as-is in this commit
and addressed separately.
Test Plan
- Open `design_reference/SoftLAN Launcher.html` in a static server and
inspect variant A at full width: the search input's horizontal center
should match the window's horizontal center, regardless of accent /
density choices in the Tweaks panel.
- Shrink the launcher artboard below 1100 px and confirm the row
collapses to a single left-to-right strip with no overlap.
Add the `design/` directory containing the design handoff document and
HTML/React reference prototypes for the planned Steam-inspired redesign
of the launcher UI.
Contents:
- `design/README.md` — handoff spec. Defines screens (main library,
game detail overlay, in-app Settings dialog), the game card anatomy,
interaction behavior, transitions, state shape, design tokens
(colors, typography, spacing, shadows) and out-of-scope items.
Selects layout variant A (single-row top bar) as the primary
direction. High-fidelity: colors / typography / spacing / animations
are decided, pixel-fidelity to the mock is the goal.
- `design/design_reference/` — Babel-in-browser React prototypes built
to communicate intended look and behavior. Includes:
* `SoftLAN Launcher.html` — entry that wires React + Babel and
mounts the design canvas with all variants side-by-side.
* `styles.css` — full visual spec as CSS custom properties + named
component classes (`.topbar`, `.seg`, `.card`, `.modal`, etc.).
* `data.jsx` — mock game catalog plus filter/sort helpers and a
mock STORAGE record used by the storage meter.
* `components.jsx` — reusable building blocks (Icon set, GameCover
placeholder generator, StateChip, ActionButton, GameCard,
SegmentedFilters, UnderlineFilters, SearchField, SortMenu,
StorageMeter, DirectoryButton, KebabMenu, GameDetailModal,
SettingsDialog).
* `launcher.jsx` — composes top bar + grid + modals into a complete
launcher screen, in both `single`-row and `two`-row chrome
variants.
These files are reference material, not production code. They are not
imported by the Vite/Tauri build and ship outside the frontend crate
(`crates/lanspread-tauri-deno-ts/`). They are committed so the design
intent is reviewable in-repo and surviving across implementations.
The accompanying production implementation against this spec is in
follow-up commits.
Trailer
-------
Refs: design/README.md (canonical handoff)