Files
galaxy-game/ui/frontend/src/lib/active-view/report/section-approaching-groups.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

100 lines
2.7 KiB
Svelte

<!--
Phase 23 Report View — approaching groups section. Renders the wire
`incomingGroup[]` projection as a compact grid: origin → destination
along with distance / speed / mass. The wire field carries no
ship-class info (a true blip on radar); the player only learns the
class when the group lands and a battle roster forms.
-->
<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 { formatFloat, planetLabel } from "./format";
const rendered = getContext<RenderedReportSource | undefined>(
RENDERED_REPORT_CONTEXT_KEY,
);
const report = $derived(rendered?.report ?? null);
const rows = $derived(report?.incomingShipGroups ?? []);
const planets = $derived(report?.planets ?? []);
</script>
<section
id="report-approaching-groups"
class="grid-section"
data-testid="report-section-approaching-groups"
>
<h2>{i18n.t("game.report.section.approaching_groups.title")}</h2>
{#if report === null}
<p class="status">{i18n.t("game.report.loading")}</p>
{:else if rows.length === 0}
<p class="status" data-testid="approaching-groups-empty">
{i18n.t("game.report.section.approaching_groups.empty")}
</p>
{:else}
<table class="grid" data-testid="approaching-groups-table">
<thead>
<tr>
<th>{i18n.t("game.report.section.approaching_groups.column.from")}</th>
<th>{i18n.t("game.report.section.approaching_groups.column.to")}</th>
<th>
{i18n.t("game.report.section.approaching_groups.column.distance")}
</th>
<th>{i18n.t("game.report.section.approaching_groups.column.speed")}</th>
<th>{i18n.t("game.report.section.approaching_groups.column.mass")}</th>
</tr>
</thead>
<tbody>
{#each rows as r, i (i)}
<tr data-testid="approaching-groups-row">
<td>{planetLabel(r.origin, planets)}</td>
<td>{planetLabel(r.destination, planets)}</td>
<td>{formatFloat(r.distance)}</td>
<td>{formatFloat(r.speed)}</td>
<td>{formatFloat(r.mass)}</td>
</tr>
{/each}
</tbody>
</table>
{/if}
</section>
<style>
.grid-section h2 {
margin: 0 0 0.5rem;
font-size: 1.05rem;
color: var(--color-text);
}
.status {
margin: 0;
color: var(--color-text-muted);
font-size: 0.9rem;
}
.grid {
border-collapse: collapse;
width: 100%;
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;
}
.grid tbody tr:hover {
background: var(--color-surface);
}
</style>