diff --git a/web/src/lib/styles/tokens.css b/web/src/lib/styles/tokens.css index 431fb60..009ab12 100644 --- a/web/src/lib/styles/tokens.css +++ b/web/src/lib/styles/tokens.css @@ -45,6 +45,9 @@ --border: light-dark(rgba(48, 52, 63, 0.1), rgba(255, 217, 218, 0.08)); --border-on-code: light-dark(rgba(48, 52, 63, 0.08), rgba(255, 217, 218, 0.08)); --accent: light-dark(var(--dark-raspberry), var(--blush-rose)); + /* Danger / error state — distinct from accent. Warm red that reads as + "something is wrong" rather than "this is a link." */ + --danger: light-dark(#dc2626, #f87171); /* Eyebrow / accent label colour — slightly different on each side: dark prefers blush-rose for legibility on carbon, light wants the deep raspberry for contrast on cream. */ diff --git a/web/src/routes/pool/+page.svelte b/web/src/routes/pool/+page.svelte index d555fe8..1427793 100644 --- a/web/src/routes/pool/+page.svelte +++ b/web/src/routes/pool/+page.svelte @@ -220,13 +220,15 @@ } // Health dot helpers - function healthLabel(h: number, pending: boolean): string { + function healthLabel(h: number, pending: boolean, revoked: boolean): string { + if (revoked) return 'revoked'; if (pending) return 'pending validation'; if (h === 1) return 'healthy'; - if (h === 2) return 'unauthorized — exhausted or hit limit; retrying daily'; + if (h === 2) return 'unauthorized — retrying daily'; return 'unknown — not yet probed'; } - function healthClass(h: number, pending: boolean): string { + function healthClass(h: number, pending: boolean, revoked: boolean): string { + if (revoked) return 'health-revoked'; if (pending) return 'health-pending'; if (h === 1) return 'health-healthy'; if (h === 2) return 'health-unauth'; @@ -382,10 +384,10 @@ {#each keys as key (key.id)} - +
- ● + ● {#if editingId === key.id} saveLabel(key.id)} @@ -401,7 +403,11 @@ {key.owner_name || key.owner_email} - 0.8} class:syncing={syncing.has(key.id)}>{syncing.has(key.id) ? '…' : fmtMicros(key.today_micros)} + {#if key.pioneer_health === 2 || key.revoked} + — + {:else} + 0.8} class:syncing={syncing.has(key.id)}>{syncing.has(key.id) ? '…' : fmtMicros(key.today_micros)} + {/if} editingLimitsId === key.id && e.stopPropagation()}> {#if key.mine && editingLimitsId === key.id && limitsPos} @@ -745,9 +751,6 @@ .keys-table td.num { text-align: right; font-feature-settings: "tnum" 1; } .keys-table td.actions-cell { text-align: right; } - .keys-table tr.inactive td { - opacity: 0.5; - } .keys-table tr.mine { background: light-dark(oklch(98% 0.005 350), oklch(22% 0.01 350)); } @@ -790,9 +793,12 @@ } .over { - color: var(--danger, #f87171); + color: var(--danger); font-weight: 600; } + .stale-val { + color: var(--text-muted); + } .menu-wrap { position: relative; @@ -895,6 +901,7 @@ } .health-healthy { color: #4ade80; } .health-unauth { color: light-dark(#f59e0b, #fbbf24); } + .health-revoked { color: var(--danger); } .health-pending { color: light-dark(#60a5fa, #93c5fd); } .health-unknown { color: var(--text-muted); }