diff --git a/crates/lanspread-tauri-deno-ts/src/components/topbar/DirectoryButton.tsx b/crates/lanspread-tauri-deno-ts/src/components/topbar/DirectoryButton.tsx
index f56978b..eedbf74 100644
--- a/crates/lanspread-tauri-deno-ts/src/components/topbar/DirectoryButton.tsx
+++ b/crates/lanspread-tauri-deno-ts/src/components/topbar/DirectoryButton.tsx
@@ -1,17 +1,27 @@
import { Icon } from '../Icon';
-import { truncatePath } from '../../lib/format';
interface Props {
- path: string;
+ path: string | null;
onClick: () => void;
}
-export const DirectoryButton = ({ path, onClick }: Props) => (
-
-);
+export const DirectoryButton = ({ path, onClick }: Props) => {
+ const isSet = !!(path && path.trim());
+ const label = isSet ? 'Game folder' : 'Set game folder';
+ const tooltip = isSet ? (path as string) : 'Please select a game folder';
+ const ariaLabel = isSet ? `Game folder: ${path}` : 'Set game folder';
+
+ return (
+
+ );
+};
diff --git a/crates/lanspread-tauri-deno-ts/src/lib/format.ts b/crates/lanspread-tauri-deno-ts/src/lib/format.ts
index 63587cb..6b8e46d 100644
--- a/crates/lanspread-tauri-deno-ts/src/lib/format.ts
+++ b/crates/lanspread-tauri-deno-ts/src/lib/format.ts
@@ -19,10 +19,6 @@ export const formatEtiVersion = (raw: string | undefined): string => {
return raw;
};
-/** Truncate a path with a leading ellipsis when it exceeds the limit. */
-export const truncatePath = (path: string, max = 36): string =>
- path.length > max ? `…${path.slice(-(max - 1))}` : path;
-
export const formatPlayers = (max?: number): string => {
if (!max || max <= 0) return '—';
return max === 1 ? '1' : `1–${max}`;
diff --git a/crates/lanspread-tauri-deno-ts/src/styles/launcher.css b/crates/lanspread-tauri-deno-ts/src/styles/launcher.css
index 616ef49..242c9ea 100644
--- a/crates/lanspread-tauri-deno-ts/src/styles/launcher.css
+++ b/crates/lanspread-tauri-deno-ts/src/styles/launcher.css
@@ -384,44 +384,57 @@
color: var(--accent);
}
-/* Directory button */
+/* Game-folder button: icon + short label + status dot.
+ Full path lives in tooltip + aria-label, not on-screen. */
.dirbtn {
+ position: relative;
display: inline-flex;
align-items: center;
gap: 8px;
height: 36px;
- padding: 0 12px;
+ padding: 0 14px 0 12px;
background: var(--bg-2);
border: 1px solid var(--bd-1);
border-radius: 8px;
- color: var(--t-2);
+ color: var(--t-1);
font: inherit;
font-size: 12.5px;
+ font-weight: 600;
cursor: pointer;
- max-width: 360px;
+ white-space: nowrap;
+ flex-shrink: 0;
transition:
border-color 0.15s,
- color 0.15s;
- flex-shrink: 1;
- min-width: 0;
+ color 0.15s,
+ background 0.15s;
}
.dirbtn:hover {
border-color: var(--bd-2);
- color: var(--t-1);
}
.dirbtn-label {
- color: var(--t-1);
- font-weight: 600;
+ line-height: 1;
+}
+.dirbtn-status-dot {
+ width: 8px;
+ height: 8px;
+ margin-left: 2px;
+ border-radius: 999px;
flex-shrink: 0;
}
-.dirbtn-path {
- color: var(--t-3);
- font-family: var(--font-mono);
- font-size: 11.5px;
- white-space: nowrap;
- overflow: hidden;
- text-overflow: ellipsis;
- min-width: 0;
+.dirbtn-set .dirbtn-status-dot {
+ background: var(--ok);
+ box-shadow: 0 0 6px color-mix(in srgb, var(--ok) 70%, transparent);
+}
+.dirbtn-unset .dirbtn-status-dot {
+ background: var(--danger);
+ box-shadow: 0 0 6px color-mix(in srgb, var(--danger) 70%, transparent);
+}
+.dirbtn-unset {
+ border-color: color-mix(in srgb, var(--danger) 35%, var(--bd-1));
+}
+.dirbtn-unset:hover {
+ border-color: color-mix(in srgb, var(--danger) 55%, var(--bd-2));
+ background: color-mix(in srgb, var(--danger) 8%, var(--bg-2));
}
/* Kebab menu */