From e0efb69bf08b7da1ef2d224c5ec2145e803da54f Mon Sep 17 00:00:00 2001 From: ddidderr Date: Thu, 21 May 2026 18:57:15 +0200 Subject: [PATCH] design docs: no green/red light on Game folder --- design/README.md | 26 +++++++++++++------------- design/design_reference/components.jsx | 1 - design/design_reference/launcher.jsx | 6 ++++-- design/design_reference/styles.css | 23 ++++++++--------------- 4 files changed, 25 insertions(+), 31 deletions(-) diff --git a/design/README.md b/design/README.md index 5e7c7af..8983845 100644 --- a/design/README.md +++ b/design/README.md @@ -40,9 +40,9 @@ The HTML mock includes two chrome variants — **A (single-row)** and **B (two-r - **Right:** game-folder button + kebab menu. - Below ~1100 px of launcher width (container query), the three zones collapse into a single left-to-right flowing row (no wrap, no centering). Implement via container query on the launcher root; viewport media query is acceptable if your codebase doesn't use container queries yet. - See "Top bar (variant A)" below for the full spec and rationale. -- **Game-directory button redesigned.** No more inline path display. The button is now an icon + short label + status dot, with the full path moved to the tooltip. Two states: - - **Set & valid:** label `Game folder`, green status dot, tooltip = full configured path. - - **Not set / invalid path:** label `Set game folder`, red status dot, subtle red border, slightly red-tinted hover, tooltip = `Please select a game folder`. "Invalid" (a path is stored but doesn't exist on disk) is treated identically to "not set" — no separate warning state for now. +- **Game-directory button redesigned.** No more inline path display. The button is now an icon + short label, with the full path moved to the tooltip. Two states: + - **Set & valid:** label `Game folder`, default border, tooltip = full configured path. + - **Not set / invalid path:** label `Set game folder`, subtle red border, slightly red-tinted hover, tooltip = `Please select a game folder`. "Invalid" (a path is stored but doesn't exist on disk) is treated identically to "not set" — no separate warning state for now. - Click behavior unchanged — opens the native folder picker via Tauri. - See "Game-folder button" below for the full spec. @@ -80,10 +80,11 @@ The default screen. A grid of game cards over a dark, gradient-tinted background - **Center zone (col 2, search alone):** - **Search field** — 36 px tall, `flex: 0 1 360px` (caps at 360 px wide so it can't elbow into the side zones). `background var(--bg-2)`, `1px solid var(--bd-1)`, `border-radius: 8px`, padding `0 12px`. Leading magnifying-glass icon (14×14, `currentColor`) and a trailing "/" kbd hint (`background rgba(255,255,255,0.06)`, `border-radius: 4px`, font `11px ui-monospace`). On focus: border `color-mix(in srgb, var(--accent) 60%, var(--bd-2))`, background `var(--bg-1)`, ring `box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 16%, transparent)`. The `/` key shortcut should focus the search. - - **Right zone (col 3, flex space-between):** - - **Sort menu** (pinned left, hugging search) — 36 px button, same surface style as search. Label `Sort: ` plus 13 px sort-bars icon and 11 px chevron. Click reveals dropdown menu below. Options: `Name (A–Z)`, `Size (largest)`, `Recently Played`, `Status`. - - **Game-folder button** (pinned right of itself, before the kebab) — see "Game-folder button" below. - - **Kebab menu** (`⋮`, pinned far-right) — 36×36 button with same surface. Menu items: `Settings` (opens Settings dialog), `Refresh library`, separator, `Unpack logs`, `About SoftLAN`. + - **Right zone (col 3, flex space-between with two sub-groups):** + - **Sort menu** (pinned left, hugging search) — 36 px button, same surface style as search. Label `Sort: ` plus 13 px sort-bars icon and 11 px chevron. Click reveals dropdown menu below. Options: `Name (A–Z)`, `Size (largest)`, `Recently Played`, `Status`. This is the only thing on the *left* side of the right zone — it's part of the search cluster, so it hugs the search. + - **Game-folder button + kebab menu** (grouped together, pinned far-right) — 12 px gap between the two. They both belong to the "app-level" controls (settings/identity/menus), so they live as a tight pair on the right edge. + - **Game-folder button** — see "Game-folder button" below. + - **Kebab menu** (`⋮`) — 36×36 button with same surface as search. Menu items: `Settings` (opens Settings dialog), `Refresh library`, separator, `Unpack logs`, `About SoftLAN`. **Narrow-window fallback** (container width < 1100 px): the grid is replaced by a single `display: flex; flex-wrap: nowrap; gap: 16px` row. All items align left-to-right in source order (brand → filter → search → sort → game-folder → kebab). The search field becomes `flex: 1 1 auto` so it absorbs remaining slack. The geometric centering is abandoned at narrow widths because there isn't enough horizontal slack for it to read cleanly. Implement via container query (`@container launcher (max-width: 1100px)`) on the launcher root; a viewport media query is an acceptable fallback if you're not using container queries yet. @@ -222,10 +223,10 @@ The top-bar control that exposes the user's currently-configured game folder (th Two visual states, driven by whether `settings.gameFolder` resolves to an accessible directory: -| State | Trigger | Label | Status dot | Border | Tooltip | -|---|---|---|---|---|---| -| **Set & valid** | path is configured and exists on disk | `Game folder` | green (`--ok` `#22c55e`) | default `--bd-1` | full configured path | -| **Not set / invalid** | path is `null`/empty, or path is set but the directory no longer exists | `Set game folder` | red (`--danger` `#ef4444`) | tinted red (`color-mix(in srgb, var(--danger) 35%, var(--bd-1))`) | `Please select a game folder` | +| State | Trigger | Label | Border | Tooltip | +|---|---|---|---|---| +| **Set & valid** | path is configured and exists on disk | `Game folder` | default `--bd-1` | full configured path | +| **Not set / invalid** | path is `null`/empty, or path is set but the directory no longer exists | `Set game folder` | tinted red (`color-mix(in srgb, var(--danger) 35%, var(--bd-1))`) | `Please select a game folder` | "Invalid" is intentionally collapsed into the same visual state as "not set" — the user's job is identical (open the picker and pick a folder), so we don't differentiate. If we later need a distinct "missing" state (e.g. to show the *last known* path so the user can re-attach an external drive), introduce a third state then; for now, keep it simple. @@ -233,13 +234,12 @@ Two visual states, driven by whether `settings.gameFolder` resolves to an access 1. **Folder icon** — `Icon.folder` from `components.jsx`, 14×14, `currentColor`. 2. **Label** — 12.5 px / 600, `var(--t-1)`, `white-space: nowrap`, `line-height: 1`. Text content depends on state (see table above). -3. **Status dot** — `8×8` px circle, `border-radius: 999px`, `margin-left: 2px`. Background `var(--ok)` (set) or `var(--danger)` (unset). Glow via `box-shadow: 0 0 6px color-mix(in srgb, 70%, transparent)`. The dot is **inline** (a flex sibling next to the label), not corner-pinned over the icon — because the button is now wider than tall, a corner badge would feel misplaced. **Hover:** border darkens to `--bd-2` (set state) or to `color-mix(in srgb, var(--danger) 55%, var(--bd-2))` with a faint `color-mix(in srgb, var(--danger) 8%, var(--bg-2))` background tint (unset state) so the bad-state hover reads as "this is the thing you need to fix". **Accessibility:** the `aria-label` carries the full state in words — `"Game folder: "` when set, `"Set game folder"` when unset — so screen readers don't have to interpret the colored dot. -**Why no inline path anymore?** The previous design squeezed the full path into the button as truncated monospace (`…/eti_games_AFTER_LAN_2025`). It rarely showed the meaningful part of the path on real-world configurations, ate horizontal space, and competed with the actual primary controls (filter / search / sort) for the top bar's attention budget. The information is still one mouseover away in the tooltip; on the surface, the dot + short label communicate the *state* of the configuration, which is what users actually need to glance at. +**Why no inline path anymore?** The previous design squeezed the full path into the button as truncated monospace (`…/eti_games_AFTER_LAN_2025`). It rarely showed the meaningful part of the path on real-world configurations, ate horizontal space, and competed with the actual primary controls (filter / search / sort) for the top bar's attention budget. The information is still one mouseover away in the tooltip; on the surface, the label communicates whether configuration is needed — which is what users actually need to glance at. **Data:** the component takes a `path: string | null` prop. `null` (or empty/whitespace string) renders the unset state; any non-empty string renders the set state. In production, derive `path` from your settings store; if you want to additionally validate existence, do the `fs.metadata` check in the store / a hook and pass `null` when the directory is missing. diff --git a/design/design_reference/components.jsx b/design/design_reference/components.jsx index cef2f9e..19c642b 100644 --- a/design/design_reference/components.jsx +++ b/design/design_reference/components.jsx @@ -365,7 +365,6 @@ function DirectoryButton({ path }) { > {label} -