fix(frontend): finish the token migration — raw grey classes -> theme tokens
UI_REDESIGN chunk 4 was never finished: 39 app/component files still used raw Tailwind greys, kept readable in light mode only by the !important override sheet. In dark mode text-gray-600 is ~2.3:1 on surface, and the light override maps it to #94a3b8 (~2.6:1 on white) — unreadable in both. Mechanical mapping (886 classes): gray-100/200 -> ink, 300/400 -> ink-2, 500/600/700 -> ink-muted, bg 950/900/800 -> page/surface/raised, border 800 -> line, 700/600 -> line-strong, plus hover/divide/placeholder. Alpha suffixes kept (tokens are color-mix, so /60 works). bg-gray-700, text-white and marketing pages left alone. text-[9px] -> text-[10px]. Frontend unverified: no Node on the authoring box (#207). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
3968b49b80
commit
bf206334e3
@@ -440,7 +440,7 @@ function RadarBadge({ meta, loop, loopClock, onLoop }: {
|
||||
else text = `Radar valid ${hhmmLocal(meta.valid)} · ${ageMin} min old`;
|
||||
return (
|
||||
<div className={`flex items-center gap-1.5 bg-surface/90 border rounded px-2 py-1 text-xs text-ink-2 pointer-events-auto ${stale ? "border-accent" : "border-line"}`}>
|
||||
{stale && <span className="bg-accent text-white rounded px-1 text-[9px] font-semibold tracking-wide"
|
||||
{stale && <span className="bg-accent text-white rounded px-1 text-[10px] font-semibold tracking-wide"
|
||||
title={`The newest radar frame is more than ${RADAR_STALE_MIN} min old, or its time could not be read`}>STALE</span>}
|
||||
<span className="tabular-nums whitespace-nowrap">{text}</span>
|
||||
{meta.valid && meta.error && <span className="text-ink-muted whitespace-nowrap" title={meta.error}>· time not refreshing</span>}
|
||||
@@ -1233,8 +1233,8 @@ function FanNodeLayer({
|
||||
className={idx < members.length - 1 ? "border-b border-gray-200 pb-2" : ""}
|
||||
>
|
||||
<p className="font-semibold text-sm text-gray-900">{node.name}</p>
|
||||
<p className="text-xs text-gray-500 font-mono">{node.node_id}</p>
|
||||
<p className="text-xs capitalize text-gray-700">{node.status}</p>
|
||||
<p className="text-xs text-ink-muted font-mono">{node.node_id}</p>
|
||||
<p className="text-xs capitalize text-ink-muted">{node.status}</p>
|
||||
{activeByNode[node.node_id] && (
|
||||
<p className="text-xs text-orange-600 mt-0.5">
|
||||
● TG {activeByNode[node.node_id].talkgroup_id ?? "—"}{" "}
|
||||
@@ -1346,8 +1346,8 @@ function FanIncidentLayer({
|
||||
<p className="text-xs capitalize font-medium" style={{ color }}>
|
||||
{isKnownSeverity(inc.severity) ? SEVERITY_LABEL[inc.severity] : "Unknown"} · {inc.type ?? "other"}
|
||||
</p>
|
||||
{inc.location && <p className="text-xs text-gray-600">{inc.location}</p>}
|
||||
<p className="text-[11px] text-gray-500">Pin: {PIN_PRECISION_LABEL[pinPrecision(inc)]}</p>
|
||||
{inc.location && <p className="text-xs text-ink-muted">{inc.location}</p>}
|
||||
<p className="text-[11px] text-ink-muted">Pin: {PIN_PRECISION_LABEL[pinPrecision(inc)]}</p>
|
||||
<a
|
||||
href={`/incidents/${inc.incident_id}`}
|
||||
onClick={(e) => { e.stopPropagation(); window.location.href = `/incidents/${inc.incident_id}`; e.preventDefault(); }}
|
||||
@@ -1490,19 +1490,19 @@ function IncidentPathLayer({
|
||||
>
|
||||
<Popup minWidth={160}>
|
||||
<div className="text-gray-900">
|
||||
<p className="text-xs text-gray-500">{heading}</p>
|
||||
<p className="text-xs text-ink-muted">{heading}</p>
|
||||
<p className="font-semibold text-sm mt-0.5">{inc.title ?? "Incident"}</p>
|
||||
{c.location && <p className="text-xs text-gray-600 mt-0.5">{c.location}</p>}
|
||||
{c.location && <p className="text-xs text-ink-muted mt-0.5">{c.location}</p>}
|
||||
{c.location_coords?.location_type === "GEOMETRIC_CENTER" && (
|
||||
<p className="text-[11px] text-gray-500">Approximate: centre of a road, junction or place</p>
|
||||
<p className="text-[11px] text-ink-muted">Approximate: centre of a road, junction or place</p>
|
||||
)}
|
||||
{s.dashedIn && !s.ghost && path.movement && (
|
||||
<p className="text-[11px] text-gray-500">Dashed in: long gap or talkgroup change — route unknown</p>
|
||||
<p className="text-[11px] text-ink-muted">Dashed in: long gap or talkgroup change — route unknown</p>
|
||||
)}
|
||||
{hasAudio(c) && (
|
||||
<div className="flex items-center gap-1.5 mt-1">
|
||||
<PlayButton callId={c.call_id} label={s.n != null ? `Play stop ${s.n}` : "Play this call"} />
|
||||
<span className="text-xs text-gray-600">Play this call</span>
|
||||
<span className="text-xs text-ink-muted">Play this call</span>
|
||||
</div>
|
||||
)}
|
||||
<a href={`/incidents/${inc.incident_id}`} className="text-xs text-blue-600 hover:underline block mt-1">
|
||||
@@ -1997,7 +1997,7 @@ function MapView({
|
||||
<span className="text-ink-2">Call location (not a pursuit)</span>
|
||||
</div>
|
||||
<div className="flex items-center gap-2">
|
||||
<span className="text-[9px] px-0.5 rounded border border-dashed border-line text-ink-2 leading-tight">merged?</span>
|
||||
<span className="text-[10px] px-0.5 rounded border border-dashed border-line text-ink-2 leading-tight">merged?</span>
|
||||
<span className="text-ink-2">Path > {MAY_BE_MERGED_KM} km — may be 2+ events</span>
|
||||
</div>
|
||||
</div>
|
||||
@@ -2114,7 +2114,7 @@ function MapView({
|
||||
<span className="uppercase tracking-wide font-semibold text-[11px]" style={{ color }}>
|
||||
{isKnownSeverity(inc.severity) ? SEVERITY_LABEL[inc.severity] : "Unknown"}
|
||||
</span>
|
||||
{live && <span className="ml-auto bg-accent text-white rounded px-1 text-[9px] font-semibold tracking-wide">ON AIR</span>}
|
||||
{live && <span className="ml-auto bg-accent text-white rounded px-1 text-[10px] font-semibold tracking-wide">ON AIR</span>}
|
||||
</div>
|
||||
<p className="text-ink font-semibold leading-snug truncate">
|
||||
{inc.title ?? "Incident"}
|
||||
|
||||
Reference in New Issue
Block a user