Standardize UI typography, charts and empty states
This commit is contained in:
@@ -106,7 +106,7 @@
|
||||
|
||||
<div class="page">
|
||||
<SectionHeader title="Configs" subtitle="Manage game baselines and scoped changes.">
|
||||
{#snippet actions()}<Button variant="primary" onclick={() => openCreate()}>New config</Button>{/snippet}
|
||||
{#snippet actions()}{#if view === 'inspect' || loading || artifacts.length || error}<Button variant="primary" onclick={() => openCreate()}>New config</Button>{/if}{/snippet}
|
||||
</SectionHeader>
|
||||
<div class="navigation"><Tabs tabs={[{id:'library',label:'Library'},{id:'inspect',label:'Inspect a server'}]} bind:value={view} ariaLabel="Config views" idPrefix="config-tabs" panelId="config-panel" /><Button variant="ghost" size="sm" onclick={load} loading={loading}>Refresh</Button></div>
|
||||
<div id="config-panel" role="tabpanel" aria-labelledby={'config-tabs-' + view} class="config-panel">
|
||||
@@ -119,12 +119,16 @@
|
||||
<select aria-label="Filter by game" bind:value={game}><option value="">All games</option>{#each gameOptions as option}<option value={option}>{option.toUpperCase()}</option>{/each}</select>
|
||||
<select aria-label="Filter by scope" bind:value={scope}><option value="">All scopes</option><option value="game">Game</option><option value="map">Map</option></select>
|
||||
<select aria-label="Filter by status" bind:value={status}><option value="">All statuses</option><option value="pending">Awaiting promotion</option><option value="promoted">Has promoted version</option><option value="beta">Active beta</option><option value="failed">Test failed</option></select>
|
||||
{#if query || game || scope || status}<Button size="sm" variant="ghost" onclick={resetFilters}>Clear</Button>{/if}
|
||||
{#if filtered.length && (query || game || scope || status)}<Button size="sm" variant="ghost" onclick={resetFilters}>Clear</Button>{/if}
|
||||
</div>{/if}
|
||||
{#if loading}<div class="loading" role="status">Loading your config library…</div>
|
||||
{:else if !artifacts.length && !error}
|
||||
<div class="welcome"><span class="eyebrow">Start with a foundation</span><h2>Your fleet, configured your way.</h2><p>Add a baseline for each game, then layer on small, focused changes for a game or map. Every change gets its own version.</p><Button variant="primary" onclick={() => openCreate('baseline')}>Create your first baseline</Button></div>
|
||||
{:else if !filtered.length && !error}<EmptyState title="No matching configs" description="Try a different search or clear your filters." />
|
||||
<EmptyState title="No configs yet" description="Configs store game baselines and scoped changes. Create a baseline to start managing configuration versions.">
|
||||
{#snippet actions()}<Button variant="primary" onclick={() => openCreate('baseline')}>Create baseline</Button>{/snippet}
|
||||
</EmptyState>
|
||||
{:else if !filtered.length && !error}<EmptyState title="No matching configs" description="Try a different search or clear your filters.">
|
||||
{#snippet actions()}<Button onclick={resetFilters}>Clear filters</Button>{/snippet}
|
||||
</EmptyState>
|
||||
{:else}
|
||||
{#if filteredBaselines.length}
|
||||
<section class="section"><h2>Baselines <span>{filteredBaselines.length}</span></h2>{@render configTable(filteredBaselines)}</section>
|
||||
@@ -181,8 +185,6 @@
|
||||
.section { display: flex; flex-direction: column; gap: 14px; }
|
||||
h2 { font-size: var(--text-md); margin: 0; letter-spacing: var(--tracking-tight); } h2 span { font-size: var(--text-xs); color: var(--text-secondary); font-weight: 400; margin-left: 8px; }
|
||||
.loading { padding: 60px 0; text-align: center; color: var(--text-secondary); }
|
||||
.welcome { padding: 56px 32px; border-radius: var(--radius-lg); background: var(--surface); border: 1px solid var(--border-strong); text-align: center; }
|
||||
.welcome h2 { margin-top: 12px; font-size: var(--text-2xl); } .welcome p { color: var(--text-secondary); max-width: 540px; margin: 16px auto 24px; }
|
||||
.eyebrow { color: var(--accent-primary-hover); font-size: var(--text-xs); }
|
||||
.error { color: var(--state-danger); padding: 12px; background: var(--surface-raised); border-radius: var(--radius-sm); font-size: var(--text-sm); }
|
||||
.warning { color: var(--state-warning); font-size: var(--text-sm); }
|
||||
@@ -199,7 +201,6 @@
|
||||
.dialog-actions { flex-wrap: wrap; } .dialog-actions p { flex: 1 1 240px; font-size: var(--text-xs); color: var(--text-secondary); }
|
||||
@media (max-width:600px) { .form-grid { grid-template-columns:1fr; } form { padding:18px; } .navigation { gap:4px; flex-wrap:wrap; } }
|
||||
.config-panel { display:grid; gap:20px; }
|
||||
.welcome { padding:24px; }
|
||||
.loading { padding:24px 0; }
|
||||
input:not([type='checkbox']):not([type='file']), select { border-color: var(--border-control); }
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user