Files
galaxy-game/ui/frontend/src/lib/active-view/report/section-votes.svelte
T
Ilia Denisov 4ad96b0ef7
Tests · UI / test (push) Successful in 2m11s
Tests · UI / test (pull_request) Successful in 2m7s
feat(ui): migrate all view bodies to design tokens (F1b)
Tokenize every remaining component <style> — calculator, order tab,
inspectors, tables, report sections, lobby, auth, mail, battle viewer,
toasts, map overlays. A scripted pass handled the unambiguous core
palette (text/bg/surface/border/accent/danger/muted), the rest were
mapped to the semantic/grey tokens by role.

Remaining colour literals are the documented exceptions only: the
battle-scene SVG data-visualisation palette (fixed dark, like the WebGL
map canvas), overlay scrims (modal / map-canvas), and directional or
deliberate drop shadows. The default theme stays dark until light
coherence is signed off across the views.

Updates ui/docs/design-system.md (migration status + exceptions).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-22 07:24:02 +02:00

131 lines
3.2 KiB
Svelte

<!--
Phase 23 Report View — votes section. Surfaces the local player's
total vote weight (`myVotes`), the recipient they cast their vote
for (`myVoteFor`), and the per-other-race table of votes received
in the last tally. The full vote graph is not reconstructable from
the client side because each race's outgoing vote target is
private; the section shows only the public datums and mirrors the
explanatory text on the races table.
-->
<script lang="ts">
import { getContext } from "svelte";
import { i18n } from "$lib/i18n/index.svelte";
import {
RENDERED_REPORT_CONTEXT_KEY,
type RenderedReportSource,
} from "$lib/rendered-report.svelte";
import { formatVotes } from "./format";
const rendered = getContext<RenderedReportSource | undefined>(
RENDERED_REPORT_CONTEXT_KEY,
);
const report = $derived(rendered?.report ?? null);
const races = $derived(report?.races ?? []);
const empty = $derived(report !== null && races.length === 0);
</script>
<section
id="report-votes"
class="grid-section"
data-testid="report-section-votes"
>
<h2>{i18n.t("game.report.section.votes.title")}</h2>
{#if report === null}
<p class="status">{i18n.t("game.report.loading")}</p>
{:else}
<dl class="kv">
<dt>{i18n.t("game.report.section.votes.mine")}</dt>
<dd data-testid="votes-mine">{formatVotes(report.myVotes)}</dd>
<dt>{i18n.t("game.report.section.votes.target")}</dt>
<dd data-testid="votes-target">
{#if report.myVoteFor === ""}
{i18n.t("game.report.section.votes.target_none")}
{:else}
{report.myVoteFor}
{/if}
</dd>
</dl>
{#if empty}
<p class="status" data-testid="votes-empty">
{i18n.t("game.report.section.votes.empty")}
</p>
{:else}
<h3>{i18n.t("game.report.section.votes.received_header")}</h3>
<table class="grid" data-testid="votes-received-table">
<thead>
<tr>
<th>{i18n.t("game.report.section.votes.column.race")}</th>
<th>{i18n.t("game.report.section.votes.column.votes")}</th>
</tr>
</thead>
<tbody>
{#each races as r (r.name)}
<tr data-testid="votes-received-row" data-race={r.name}>
<td>{r.name}</td>
<td>{formatVotes(r.votesReceived)}</td>
</tr>
{/each}
</tbody>
</table>
{/if}
{/if}
</section>
<style>
.grid-section h2 {
margin: 0 0 0.5rem;
font-size: 1.05rem;
color: var(--color-text);
}
.grid-section h3 {
margin: 1rem 0 0.4rem;
font-size: 0.85rem;
color: var(--color-text-muted);
text-transform: uppercase;
letter-spacing: 0.04em;
}
.kv {
display: grid;
grid-template-columns: max-content 1fr;
gap: 0.3rem 1rem;
margin: 0;
font-size: 0.9rem;
}
.kv dt {
color: var(--color-text-muted);
text-transform: uppercase;
letter-spacing: 0.04em;
font-size: 0.75rem;
}
.kv dd {
margin: 0;
color: var(--color-text);
font-variant-numeric: tabular-nums;
}
.status {
margin: 0;
color: var(--color-text-muted);
font-size: 0.9rem;
}
.grid {
border-collapse: collapse;
font-variant-numeric: tabular-nums;
font-size: 0.9rem;
}
.grid th,
.grid td {
padding: 0.4rem 0.6rem;
text-align: left;
border-bottom: 1px solid var(--color-border-subtle);
}
.grid th {
color: var(--color-text-muted);
text-transform: uppercase;
letter-spacing: 0.04em;
font-size: 0.75rem;
}
</style>