Fix dark mode inconsistencies across all pages

Add missing dark: variant classes to:
- consent_prompt, check_live/form_component: modal overlays
- error pages (404, 500): body background
- marketing_layouts: page background
- home page: pricing card, CTA button, feature card
- totp_enrollment: QR container
- admin audit_live/monitoring_live: badge colors, event borders
- alert_live: acknowledged-by text
- dashboard_live: severity color fallback
- device_live (index, show, form): status text, spinners
- settings_live: checkbox borders
- trace_live: status colors, labels, table headers
This commit is contained in:
Graham McIntire 2026-02-16 10:31:52 -06:00
parent 3f2b2a5d5e
commit 7ec2b2a00a
8 changed files with 49 additions and 49 deletions

View file

@ -293,7 +293,7 @@ defmodule ToweropsWeb.AccountLive.TotpEnrollment do
</p>
<%= if @qr_code do %>
<div class="ml-11 flex justify-center">
<div class="bg-white p-4 rounded-lg border-2 border-gray-200">
<div class="bg-white dark:bg-gray-900 p-4 rounded-lg border-2 border-gray-200 dark:border-gray-700">
<img src={@qr_code} alt="TOTP QR Code" class="w-64 h-64" />
</div>
</div>

View file

@ -454,7 +454,7 @@ defmodule ToweropsWeb.Admin.AuditLive.Index do
:danger -> "bg-red-50 text-red-700 ring-red-600/20"
:impersonation -> "bg-orange-50 text-orange-700 ring-orange-600/20"
:info -> "bg-blue-50 text-blue-700 ring-blue-600/20"
:default -> "bg-gray-50 text-gray-700 ring-gray-600/20"
:default -> "bg-gray-50 dark:bg-gray-800 text-gray-700 dark:text-gray-300 ring-gray-600/20"
end
end

View file

@ -101,7 +101,7 @@ defmodule ToweropsWeb.Admin.MonitoringLive do
defp event_border_color("completed"), do: "border-green-500"
defp event_border_color("cancelled"), do: "border-red-500"
defp event_border_color("discarded"), do: "border-gray-400"
defp event_border_color(_), do: "border-gray-300"
defp event_border_color(_), do: "border-gray-300 dark:border-gray-600"
defp event_outcome(job) do
case job.state do

View file

@ -11,10 +11,10 @@
<h1 class="text-lg font-bold text-gray-900 dark:text-white">
{@current_scope.organization.name}
</h1>
<span class="text-xs text-gray-400 dark:text-gray-500 font-mono">NOC</span>
<span class="text-xs text-gray-400 dark:text-gray-500 dark:text-gray-400 font-mono">NOC</span>
</div>
<%= if assigns[:last_updated] do %>
<div class="flex items-center gap-2 text-xs text-gray-400 dark:text-gray-500 font-mono">
<div class="flex items-center gap-2 text-xs text-gray-400 dark:text-gray-500 dark:text-gray-400 font-mono">
<span title="Last refresh">
{ToweropsWeb.TimeHelpers.format_time_ago(@last_updated)}
</span>
@ -158,7 +158,7 @@
do: "100",
else: :erlang.float_to_binary(@uptime_percentage, decimals: 1)}%
</span>
<span class="text-gray-400 dark:text-gray-500">
<span class="text-gray-400 dark:text-gray-500 dark:text-gray-400">
{@device_up}/{@device_count}
</span>
<%= if @device_down > 0 do %>
@ -213,7 +213,7 @@
</span>
<%!-- Financial data: role-gated --%>
<%= if @can_view_financials do %>
<span class="text-gray-400 dark:text-gray-500">
<span class="text-gray-400 dark:text-gray-500 dark:text-gray-400">
{format_mrr(@summary.subscribers.total_mrr)}/mo
</span>
<% end %>
@ -315,7 +315,7 @@
</.link>
<span
:if={incident.site_name}
class="text-[10px] text-gray-400 dark:text-gray-500"
class="text-[10px] text-gray-400 dark:text-gray-500 dark:text-gray-400"
>
@ {incident.site_name}
</span>
@ -355,16 +355,16 @@
<thead class="bg-gray-50/80 dark:bg-gray-800/80">
<tr>
<th class="w-1 p-0"></th>
<th class="px-3 py-1.5 text-left text-[10px] font-medium uppercase tracking-wider text-gray-400 dark:text-gray-500">
<th class="px-3 py-1.5 text-left text-[10px] font-medium uppercase tracking-wider text-gray-400 dark:text-gray-500 dark:text-gray-400">
{t("Device")}
</th>
<th class="px-3 py-1.5 text-left text-[10px] font-medium uppercase tracking-wider text-gray-400 dark:text-gray-500">
<th class="px-3 py-1.5 text-left text-[10px] font-medium uppercase tracking-wider text-gray-400 dark:text-gray-500 dark:text-gray-400">
{t("Alert")}
</th>
<th class="px-3 py-1.5 text-right text-[10px] font-medium uppercase tracking-wider text-gray-400 dark:text-gray-500">
<th class="px-3 py-1.5 text-right text-[10px] font-medium uppercase tracking-wider text-gray-400 dark:text-gray-500 dark:text-gray-400">
{t("Impact")}
</th>
<th class="px-3 py-1.5 text-right text-[10px] font-medium uppercase tracking-wider text-gray-400 dark:text-gray-500">
<th class="px-3 py-1.5 text-right text-[10px] font-medium uppercase tracking-wider text-gray-400 dark:text-gray-500 dark:text-gray-400">
{t("When")}
</th>
<th class="px-3 py-1.5 w-12"></th>
@ -403,14 +403,14 @@
</.link>
<span
:if={alert.device.ip_address}
class="font-mono text-[11px] text-gray-400 dark:text-gray-500"
class="font-mono text-[11px] text-gray-400 dark:text-gray-500 dark:text-gray-400"
>
{alert.device.ip_address}
</span>
</div>
<span
:if={alert.device.site}
class="text-[10px] text-gray-400 dark:text-gray-500"
class="text-[10px] text-gray-400 dark:text-gray-500 dark:text-gray-400"
>
{alert.device.site.name}
</span>
@ -429,7 +429,7 @@
<.timestamp
datetime={alert.triggered_at}
timezone={@timezone}
class="font-mono text-[11px] text-gray-400 dark:text-gray-500"
class="font-mono text-[11px] text-gray-400 dark:text-gray-500 dark:text-gray-400"
/>
</td>
<td class="px-3 py-1.5 text-right">
@ -486,22 +486,22 @@
<table class="min-w-full">
<thead class="bg-gray-50/80 dark:bg-gray-800/80">
<tr>
<th class="px-3 py-1.5 text-left text-[10px] font-medium uppercase tracking-wider text-gray-400 dark:text-gray-500">
<th class="px-3 py-1.5 text-left text-[10px] font-medium uppercase tracking-wider text-gray-400 dark:text-gray-500 dark:text-gray-400">
{t("Site")}
</th>
<th class="px-3 py-1.5 text-right text-[10px] font-medium uppercase tracking-wider text-gray-400 dark:text-gray-500">
<th class="px-3 py-1.5 text-right text-[10px] font-medium uppercase tracking-wider text-gray-400 dark:text-gray-500 dark:text-gray-400">
{t("Devices")}
</th>
<th class="px-3 py-1.5 text-right text-[10px] font-medium uppercase tracking-wider text-gray-400 dark:text-gray-500">
<th class="px-3 py-1.5 text-right text-[10px] font-medium uppercase tracking-wider text-gray-400 dark:text-gray-500 dark:text-gray-400">
{t("Down")}
</th>
<th class="px-3 py-1.5 text-right text-[10px] font-medium uppercase tracking-wider text-gray-400 dark:text-gray-500">
<th class="px-3 py-1.5 text-right text-[10px] font-medium uppercase tracking-wider text-gray-400 dark:text-gray-500 dark:text-gray-400">
{t("QoE")}
</th>
<th class="px-3 py-1.5 text-right text-[10px] font-medium uppercase tracking-wider text-gray-400 dark:text-gray-500">
<th class="px-3 py-1.5 text-right text-[10px] font-medium uppercase tracking-wider text-gray-400 dark:text-gray-500 dark:text-gray-400">
{t("Subs")}
</th>
<th class="px-3 py-1.5 text-right text-[10px] font-medium uppercase tracking-wider text-gray-400 dark:text-gray-500">
<th class="px-3 py-1.5 text-right text-[10px] font-medium uppercase tracking-wider text-gray-400 dark:text-gray-500 dark:text-gray-400">
{t("Affected")}
</th>
</tr>
@ -679,7 +679,7 @@
type="button"
phx-click="dismiss_insight"
phx-value-id={insight.id}
class="rounded p-0.5 text-gray-300 hover:text-gray-500 dark:text-gray-600 dark:hover:text-gray-400 opacity-0 group-hover:opacity-100 transition"
class="rounded p-0.5 text-gray-300 hover:text-gray-500 dark:text-gray-400 dark:text-gray-600 dark:hover:text-gray-400 opacity-0 group-hover:opacity-100 transition"
title="Dismiss"
>
<.icon name="hero-x-mark" class="h-3 w-3" />
@ -754,7 +754,7 @@
<div class="hidden">
<div class="flex items-center justify-between mb-2">
<h2 class="text-xs font-semibold uppercase tracking-wider text-gray-500 dark:text-gray-400">
Config Changes <span class="font-normal text-gray-400 dark:text-gray-500">(7d)</span>
Config Changes <span class="font-normal text-gray-400 dark:text-gray-500 dark:text-gray-400">(7d)</span>
</h2>
<.link
navigate={~p"/insights"}
@ -774,13 +774,13 @@
<span class="text-xs font-medium text-gray-900 dark:text-white truncate">
{if change.device, do: change.device.name, else: "Unknown"}
</span>
<span class="font-mono text-[10px] text-gray-400 dark:text-gray-500 flex-shrink-0">
<span class="font-mono text-[10px] text-gray-400 dark:text-gray-500 dark:text-gray-400 flex-shrink-0">
{change.change_size}L
</span>
<span class="text-[10px] text-gray-400 dark:text-gray-500 truncate">
<span class="text-[10px] text-gray-400 dark:text-gray-500 dark:text-gray-400 truncate">
{Enum.join(Enum.take(change.sections_changed, 2), ", ")}
</span>
<span class="ml-auto flex-shrink-0 font-mono text-[10px] text-gray-400 dark:text-gray-500">
<span class="ml-auto flex-shrink-0 font-mono text-[10px] text-gray-400 dark:text-gray-500 dark:text-gray-400">
{format_short_datetime(change.changed_at, @timezone)}
</span>
</.link>
@ -788,7 +788,7 @@
</div>
<% else %>
<div class="rounded-md border border-gray-200 dark:border-white/10 bg-white dark:bg-gray-800/50 px-3 py-6 text-center">
<span class="text-xs text-gray-400 dark:text-gray-500">
<span class="text-xs text-gray-400 dark:text-gray-500 dark:text-gray-400">
No config changes in 7 days
</span>
</div>
@ -821,7 +821,7 @@
<p class="text-xs text-gray-700 dark:text-gray-300 min-w-0 flex-1 truncate">
{activity.summary}
</p>
<span class="flex-shrink-0 font-mono text-[10px] text-gray-400 dark:text-gray-500">
<span class="flex-shrink-0 font-mono text-[10px] text-gray-400 dark:text-gray-500 dark:text-gray-400">
{format_short_datetime(activity.timestamp, @timezone)}
</span>
</div>
@ -834,20 +834,20 @@
═══════════════════════════════════════════════ --%>
<div class="mt-6 flex items-center justify-center border-t border-gray-100 dark:border-white/5 pt-4 pb-2">
<span class="text-[10px] text-gray-300 dark:text-gray-600">
<kbd class="px-1 py-0.5 rounded border border-gray-200 dark:border-gray-700 font-mono text-gray-400 dark:text-gray-500">
<kbd class="px-1 py-0.5 rounded border border-gray-200 dark:border-gray-700 font-mono text-gray-400 dark:text-gray-500 dark:text-gray-400">
⌘K
</kbd>
<span class="ml-1">to search</span>
<span class="mx-2">·</span>
<.link navigate={~p"/devices/new"} class="hover:text-gray-500 dark:hover:text-gray-400">
<.link navigate={~p"/devices/new"} class="hover:text-gray-500 dark:text-gray-400 dark:hover:text-gray-400">
+ device
</.link>
<span class="mx-2">·</span>
<.link navigate={~p"/trace"} class="hover:text-gray-500 dark:hover:text-gray-400">
<.link navigate={~p"/trace"} class="hover:text-gray-500 dark:text-gray-400 dark:hover:text-gray-400">
trace
</.link>
<span class="mx-2">·</span>
<.link navigate={~p"/network-map"} class="hover:text-gray-500 dark:hover:text-gray-400">
<.link navigate={~p"/network-map"} class="hover:text-gray-500 dark:text-gray-400 dark:hover:text-gray-400">
map
</.link>
</span>

View file

@ -175,7 +175,7 @@
prompt="No site (ungrouped)"
options={Enum.map(@available_sites, &{&1.name, &1.id})}
/>
<p class="mt-1 text-sm text-gray-500">
<p class="mt-1 text-sm text-gray-500 dark:text-gray-400">
{t("Optionally group this device into a site (office, datacenter, etc.)")}
</p>
</div>

View file

@ -138,7 +138,7 @@
<%= if !@has_devices do %>
<div class="text-center py-16">
<.icon name="hero-server" class="mx-auto h-12 w-12 text-gray-400 dark:text-gray-500" />
<.icon name="hero-server" class="mx-auto h-12 w-12 text-gray-400 dark:text-gray-500 dark:text-gray-400" />
<h3 class="mt-4 text-lg font-semibold text-gray-900 dark:text-white">
{t("No devices")}
</h3>
@ -367,7 +367,7 @@
</div>
<span
:if={row.site && row.site.location}
class="text-xs text-gray-400 dark:text-gray-500"
class="text-xs text-gray-400 dark:text-gray-500 dark:text-gray-400"
>
<.icon name="hero-map-pin" class="inline h-3 w-3" /> {row.site.location}
</span>
@ -467,7 +467,7 @@
>
<.icon
name={device_type_icon(row.device.device_role)}
class="h-3.5 w-3.5 text-gray-400 dark:text-gray-500 flex-shrink-0"
class="h-3.5 w-3.5 text-gray-400 dark:text-gray-500 dark:text-gray-400 flex-shrink-0"
/>
<span class="text-xs text-gray-600 dark:text-gray-400">
{(row.device.device_role || :unknown)
@ -544,7 +544,7 @@
<div class="text-center py-16">
<.icon
name="hero-magnifying-glass"
class="mx-auto h-12 w-12 text-gray-400 dark:text-gray-500"
class="mx-auto h-12 w-12 text-gray-400 dark:text-gray-500 dark:text-gray-400"
/>
<h3 class="mt-4 text-lg font-semibold text-gray-900 dark:text-white">
{t("No discovered devices")}
@ -592,7 +592,7 @@
</span>
</div>
<% _ -> %>
<span class="text-sm text-gray-500">Unknown</span>
<span class="text-sm text-gray-500 dark:text-gray-400">Unknown</span>
<% end %>
</:col>
<:col :let={discovered} label={t("Hostname")}>
@ -608,7 +608,7 @@
<div class="flex items-center gap-2">
<.icon
name={device_type_icon(discovered.device_type)}
class="h-4 w-4 text-gray-500"
class="h-4 w-4 text-gray-500 dark:text-gray-400"
/>
<span class="text-sm text-gray-900 dark:text-white">
{device_type_label(discovered.device_type)}
@ -632,7 +632,7 @@
>
{first.device_name}
</.link>
<span class="text-xs text-gray-500"> ({first.interface})</span>
<span class="text-xs text-gray-500 dark:text-gray-400"> ({first.interface})</span>
<% else %>
<span>{length(discovered.discovered_by)} devices</span>
<% end %>

View file

@ -420,7 +420,7 @@
{@available_firmware.version}
</span>
<%= if @available_firmware.release_date do %>
<span class="text-gray-500 dark:text-gray-500">
<span class="text-gray-500 dark:text-gray-400 dark:text-gray-500 dark:text-gray-400">
(released {format_date(
@available_firmware.release_date
)})
@ -653,7 +653,7 @@
{s}
</span>
</div>
<span class="text-gray-500 text-xs">{event.change_size} lines</span>
<span class="text-gray-500 dark:text-gray-400 text-xs">{event.change_size} lines</span>
</div>
<% end %>
</div>
@ -1785,7 +1785,7 @@
{t("Primary")}
</span>
<% else %>
<span class="text-gray-400 dark:text-gray-500">-</span>
<span class="text-gray-400 dark:text-gray-500 dark:text-gray-400">-</span>
<% end %>
</td>
</tr>
@ -2441,14 +2441,14 @@
<%= if check.last_check_at do %>
{get_latest_value(check)}
<% else %>
<span class="text-gray-400 dark:text-gray-500">Pending</span>
<span class="text-gray-400 dark:text-gray-500 dark:text-gray-400">Pending</span>
<% end %>
</td>
<td class="px-4 py-3 whitespace-nowrap text-sm text-gray-500 dark:text-gray-400">
<%= if check.last_check_at do %>
{format_relative_time(check.last_check_at)}
<% else %>
<span class="text-gray-400 dark:text-gray-500">Never</span>
<span class="text-gray-400 dark:text-gray-500 dark:text-gray-400">Never</span>
<% end %>
</td>
<td class="px-4 py-3 whitespace-nowrap text-right text-sm font-medium">

View file

@ -1326,7 +1326,7 @@
name="integration[sync_devices]"
value="true"
checked={@netbox_config["sync_devices"]}
class="mt-0.5 h-4 w-4 rounded border-gray-300 text-indigo-600 focus:ring-indigo-600"
class="mt-0.5 h-4 w-4 rounded border-gray-300 dark:border-gray-600 text-indigo-600 focus:ring-indigo-600"
/>
<div>
<span class="text-sm font-medium text-gray-900 dark:text-white">
@ -1348,7 +1348,7 @@
name="integration[sync_sites]"
value="true"
checked={@netbox_config["sync_sites"]}
class="mt-0.5 h-4 w-4 rounded border-gray-300 text-indigo-600 focus:ring-indigo-600"
class="mt-0.5 h-4 w-4 rounded border-gray-300 dark:border-gray-600 text-indigo-600 focus:ring-indigo-600"
/>
<div>
<span class="text-sm font-medium text-gray-900 dark:text-white">
@ -1370,7 +1370,7 @@
name="integration[sync_ip_addresses]"
value="true"
checked={@netbox_config["sync_ip_addresses"]}
class="mt-0.5 h-4 w-4 rounded border-gray-300 text-indigo-600 focus:ring-indigo-600"
class="mt-0.5 h-4 w-4 rounded border-gray-300 dark:border-gray-600 text-indigo-600 focus:ring-indigo-600"
/>
<div>
<span class="text-sm font-medium text-gray-900 dark:text-white">
@ -1392,7 +1392,7 @@
name="integration[sync_interfaces]"
value="true"
checked={@netbox_config["sync_interfaces"]}
class="mt-0.5 h-4 w-4 rounded border-gray-300 text-indigo-600 focus:ring-indigo-600"
class="mt-0.5 h-4 w-4 rounded border-gray-300 dark:border-gray-600 text-indigo-600 focus:ring-indigo-600"
/>
<div>
<span class="text-sm font-medium text-gray-900 dark:text-white">