Move body-text muted callers to the semantic token

A handful of helper texts, descriptions, and side counts used
text-slate-500 directly, so they didn't pick up the contrast fix in
e4f38d5. Switch each body-text caller to text-muted: AI settings
dialog helper text, AI provider helper text and link rows, ResourcePicker
empty-state copy / resource IDs / "+N more tags" / "N selected" footer,
AIModelSelectionSection "(loading...)" tag, ConfiguredNodeTables cluster
node count, and the PatrolIntelligenceHeader plan-restriction note.

Live contrast measurement after the change: every visible muted-style
text on the Patrol page now reads between 6.92 and 7.58 on its
resolved background — well above the WCAG AA 4.5 floor it was missing
on bg-surface-alt.

Icon-tint usages of text-slate-500 (Lucide icons, chevron rotations,
hover-state controls) are left as-is — those are deliberate color
choices, not muted-text intent.
This commit is contained in:
rcourtman 2026-05-10 22:32:48 +01:00
parent e4f38d5556
commit 9bb157f3f0
6 changed files with 12 additions and 12 deletions

View file

@ -184,7 +184,7 @@ export const AIModelSelectionSection: Component<AIModelSelectionSectionProps> =
<div class="flex items-center justify-between mb-1">
<label class={labelClass()}>
Shared Default Model
{state.modelsLoading() && <span class="ml-2 text-xs text-slate-500">(loading...)</span>}
{state.modelsLoading() && <span class="ml-2 text-xs text-muted">(loading...)</span>}
</label>
<button
type="button"

View file

@ -207,11 +207,11 @@ export const AIProviderConfigurationSection: Component<AIProviderConfigurationSe
/>
<Show when={config.helperText}>
<p class="text-xs text-slate-500">{config.helperText}</p>
<p class="text-xs text-muted">{config.helperText}</p>
</Show>
<div class="flex items-center justify-between">
<p class="text-xs text-slate-500">
<p class="text-xs text-muted">
<a
href={config.actionLinkHref}
target="_blank"

View file

@ -126,7 +126,7 @@ export const AISettingsDialogs: Component<AISettingsDialogsProps> = (props) => {
placeholder={setupProviderConfig().placeholder}
class="w-full px-3 py-2 border border-border rounded-md bg-surface focus:ring-2 focus:ring-blue-500 focus:border-transparent"
/>
<p class="text-xs text-slate-500 mt-1.5">
<p class="text-xs text-muted mt-1.5">
<a
href={setupProviderConfig().actionLinkHref}
target="_blank"
@ -150,7 +150,7 @@ export const AISettingsDialogs: Component<AISettingsDialogsProps> = (props) => {
placeholder="http://localhost:11434"
class="w-full px-3 py-2 border border-border rounded-md focus:ring-2 focus:ring-blue-500 focus:border-transparent"
/>
<p class="text-xs text-slate-500 mt-1.5">
<p class="text-xs text-muted mt-1.5">
Ollama runs locally - no API key needed
</p>
</div>

View file

@ -95,7 +95,7 @@ export const PveNodesTable: Component<PveNodesTableProps> = (props) => {
<div class="rounded-md border border-border bg-surface-alt px-3 py-2 space-y-2">
<div class="flex items-center gap-2 text-xs font-semibold text-base-content">
<span>{clusterName()} Cluster</span>
<span class="ml-auto text-[0.65rem] font-normal text-slate-500">
<span class="ml-auto text-[0.65rem] font-normal text-muted">
{clusterEndpoints().length} nodes
</span>
</div>

View file

@ -191,7 +191,7 @@ export function ResourcePicker(props: ResourcePickerProps) {
fallback={
<div class="p-8 text-center text-slate-400">
<p class="text-sm">{getResourcePickerEmptyState(false).title}</p>
<p class="text-xs mt-1 text-slate-500">
<p class="text-xs mt-1 text-muted">
{getResourcePickerEmptyState(false).description}
</p>
</div>
@ -259,7 +259,7 @@ export function ResourcePicker(props: ResourcePickerProps) {
>
{getPreferredInfrastructureDisplayName(resource)}
</div>
<div class="text-xs text-slate-500 sm:truncate break-all" title={resource.id}>
<div class="text-xs text-muted sm:truncate break-all" title={resource.id}>
{resource.id}
</div>
<div class="mt-1 flex flex-wrap items-center gap-1 sm:hidden">
@ -275,7 +275,7 @@ export function ResourcePicker(props: ResourcePickerProps) {
)}
</For>
<Show when={(resource.tags?.length ?? 0) > 2}>
<span class="text-xs text-slate-500">
<span class="text-xs text-muted">
+{(resource.tags?.length ?? 0) - 2}
</span>
</Show>
@ -301,7 +301,7 @@ export function ResourcePicker(props: ResourcePickerProps) {
)}
</For>
<Show when={(resource.tags?.length ?? 0) > 2}>
<span class="text-xs text-slate-500">
<span class="text-xs text-muted">
+{(resource.tags?.length ?? 0) - 2}
</span>
</Show>
@ -336,7 +336,7 @@ export function ResourcePicker(props: ResourcePickerProps) {
</button>
</Show>
</div>
<span class="text-xs sm:text-sm text-slate-500">
<span class="text-xs sm:text-sm text-muted">
{props.selected().length} selected
<Show when={props.selected().length >= maxSelection()}>
<span class="text-amber-400 ml-1">(max)</span>

View file

@ -372,7 +372,7 @@ export function PatrolIntelligenceHeader(props: { state: PatrolIntelligenceState
<Show
when={!presentationPolicyHidesUpgradePrompts() && state.autoFixLocked()}
>
<div class="pl-1 text-[11px] text-slate-500">
<div class="pl-1 text-[11px] text-muted">
Investigation and safe remediation workflows are not enabled on this plan.
</div>
</Show>