diff --git a/assets/css/app.css b/assets/css/app.css
index 8b7e64c7..72ec14e9 100644
--- a/assets/css/app.css
+++ b/assets/css/app.css
@@ -6,92 +6,78 @@
@source "../js";
@source "../../lib/towerops_web";
-/* A Tailwind plugin that makes "hero-#{ICON}" classes available.
- The heroicons installation itself is managed by your mix.exs */
+/* ── Custom color palette ── */
+@theme {
+ --color-sweet-salmon-50: #ffe7e6;
+ --color-sweet-salmon-100: #fed0cd;
+ --color-sweet-salmon-200: #fea19a;
+ --color-sweet-salmon-300: #fd7268;
+ --color-sweet-salmon-400: #fd4235;
+ --color-sweet-salmon-500: #fc1303;
+ --color-sweet-salmon-600: #ca0f02;
+ --color-sweet-salmon-700: #970c02;
+ --color-sweet-salmon-800: #650801;
+ --color-sweet-salmon-900: #320401;
+ --color-sweet-salmon-950: #230300;
+
+ --color-desert-sand-50: #faf0eb;
+ --color-desert-sand-100: #f5e2d6;
+ --color-desert-sand-200: #ebc5ad;
+ --color-desert-sand-300: #e0a885;
+ --color-desert-sand-400: #d68b5c;
+ --color-desert-sand-500: #cc6e33;
+ --color-desert-sand-600: #a35829;
+ --color-desert-sand-700: #7a421f;
+ --color-desert-sand-800: #522c14;
+ --color-desert-sand-900: #29160a;
+ --color-desert-sand-950: #1d0f07;
+
+ --color-wheat-50: #faf4eb;
+ --color-wheat-100: #f5e9d6;
+ --color-wheat-200: #ebd3ad;
+ --color-wheat-300: #e0bd85;
+ --color-wheat-400: #d6a75c;
+ --color-wheat-500: #cc9133;
+ --color-wheat-600: #a37429;
+ --color-wheat-700: #7a571f;
+ --color-wheat-800: #523a14;
+ --color-wheat-900: #291d0a;
+ --color-wheat-950: #1d1407;
+
+ --color-cool-steel-50: #f0f3f4;
+ --color-cool-steel-100: #e1e7ea;
+ --color-cool-steel-200: #c4cfd4;
+ --color-cool-steel-300: #a6b7bf;
+ --color-cool-steel-400: #89a0a9;
+ --color-cool-steel-500: #6b8894;
+ --color-cool-steel-600: #566d76;
+ --color-cool-steel-700: #405159;
+ --color-cool-steel-800: #2b363b;
+ --color-cool-steel-900: #151b1e;
+ --color-cool-steel-950: #0f1315;
+
+ --color-cerulean-50: #edf4f8;
+ --color-cerulean-100: #dbe9f0;
+ --color-cerulean-200: #b6d3e2;
+ --color-cerulean-300: #92bcd3;
+ --color-cerulean-400: #6da6c5;
+ --color-cerulean-500: #4990b6;
+ --color-cerulean-600: #3a7392;
+ --color-cerulean-700: #2c566d;
+ --color-cerulean-800: #1d3a49;
+ --color-cerulean-900: #0f1d24;
+ --color-cerulean-950: #0a141a;
+
+ /* Design tokens (replaces daisyUI semantic variables) */
+ --radius-selector: 0.25rem;
+ --radius-field: 0.25rem;
+ --radius-box: 0.5rem;
+}
+
+/* Heroicons plugin */
@plugin "../vendor/heroicons";
-/* daisyUI Tailwind Plugin. You can update this file by fetching the latest version with:
- curl -sLO https://github.com/saadeghi/daisyui/releases/latest/download/daisyui.js
- Make sure to look at the daisyUI changelog: https://daisyui.com/docs/changelog/ */
-@plugin "../vendor/daisyui" {
- themes: false;
-}
-
-/* daisyUI theme plugin. You can update this file by fetching the latest version with:
- curl -sLO https://github.com/saadeghi/daisyui/releases/latest/download/daisyui-theme.js
- We ship with two themes, a light one inspired on Phoenix colors and a dark one inspired
- on Elixir colors. Build your own at: https://daisyui.com/theme-generator/ */
-@plugin "../vendor/daisyui-theme" {
- name: "dark";
- default: false;
- prefersdark: true;
- color-scheme: "dark";
- --color-base-100: oklch(30.33% 0.016 252.42);
- --color-base-200: oklch(25.26% 0.014 253.1);
- --color-base-300: oklch(20.15% 0.012 254.09);
- --color-base-content: oklch(97.807% 0.029 256.847);
- --color-primary: oklch(58% 0.233 277.117);
- --color-primary-content: oklch(96% 0.018 272.314);
- --color-secondary: oklch(58% 0.233 277.117);
- --color-secondary-content: oklch(96% 0.018 272.314);
- --color-accent: oklch(60% 0.25 292.717);
- --color-accent-content: oklch(96% 0.016 293.756);
- --color-neutral: oklch(37% 0.044 257.287);
- --color-neutral-content: oklch(98% 0.003 247.858);
- --color-info: oklch(58% 0.158 241.966);
- --color-info-content: oklch(97% 0.013 236.62);
- --color-success: oklch(60% 0.118 184.704);
- --color-success-content: oklch(98% 0.014 180.72);
- --color-warning: oklch(66% 0.179 58.318);
- --color-warning-content: oklch(98% 0.022 95.277);
- --color-error: oklch(58% 0.253 17.585);
- --color-error-content: oklch(96% 0.015 12.422);
- --radius-selector: 0.25rem;
- --radius-field: 0.25rem;
- --radius-box: 0.5rem;
- --size-selector: 0.21875rem;
- --size-field: 0.21875rem;
- --border: 1.5px;
- --depth: 1;
- --noise: 0;
-}
-
-@plugin "../vendor/daisyui-theme" {
- name: "light";
- default: true;
- prefersdark: false;
- color-scheme: "light";
- --color-base-100: oklch(98% 0 0);
- --color-base-200: oklch(96% 0.001 286.375);
- --color-base-300: oklch(92% 0.004 286.32);
- --color-base-content: oklch(21% 0.006 285.885);
- --color-primary: oklch(70% 0.213 47.604);
- --color-primary-content: oklch(98% 0.016 73.684);
- --color-secondary: oklch(55% 0.027 264.364);
- --color-secondary-content: oklch(98% 0.002 247.839);
- --color-accent: oklch(0% 0 0);
- --color-accent-content: oklch(100% 0 0);
- --color-neutral: oklch(44% 0.017 285.786);
- --color-neutral-content: oklch(98% 0 0);
- --color-info: oklch(62% 0.214 259.815);
- --color-info-content: oklch(97% 0.014 254.604);
- --color-success: oklch(70% 0.14 182.503);
- --color-success-content: oklch(98% 0.014 180.72);
- --color-warning: oklch(66% 0.179 58.318);
- --color-warning-content: oklch(98% 0.022 95.277);
- --color-error: oklch(58% 0.253 17.585);
- --color-error-content: oklch(96% 0.015 12.422);
- --radius-selector: 0.25rem;
- --radius-field: 0.25rem;
- --radius-box: 0.5rem;
- --size-selector: 0.21875rem;
- --size-field: 0.21875rem;
- --border: 1.5px;
- --depth: 1;
- --noise: 0;
-}
-
-/* Add variants based on LiveView classes */
+/* ── Custom variants ── */
@custom-variant phx-click-loading (.phx-click-loading&, .phx-click-loading &);
@custom-variant phx-submit-loading (.phx-submit-loading&, .phx-submit-loading &);
@custom-variant phx-change-loading (.phx-change-loading&, .phx-change-loading &);
@@ -99,6 +85,56 @@
/* Use the data attribute for dark mode */
@custom-variant dark (&:where([data-theme=dark], [data-theme=dark] *));
+/* ── Reusable utility classes (replaces daisyUI component classes) ── */
+
+/* Card — replaces daisyUI `card card-body bg-base-100 border-base-200` */
+@utility card {
+ border-radius: var(--radius-box);
+ border: 1px solid var(--color-cool-steel-200);
+ background: var(--color-cool-steel-50);
+ padding: 1.5rem;
+}
+[data-theme="dark"] .card {
+ border-color: var(--color-cool-steel-700);
+ background: var(--color-cool-steel-900);
+}
+
+/* Badge — replaces daisyUI `badge` */
+@utility badge {
+ display: inline-flex;
+ align-items: center;
+ border-radius: 9999px;
+ padding-inline: 0.625rem;
+ padding-block: 0.125rem;
+ font-size: 0.75rem;
+ font-weight: 500;
+ line-height: 1.25rem;
+}
+
+/* Button base — replaces daisyUI `btn` (for standalone usage outside core_components) */
+@utility btn {
+ display: inline-flex;
+ align-items: center;
+ gap: 0.5rem;
+ border-radius: var(--radius-field);
+ padding-inline: 1rem;
+ padding-block: 0.5rem;
+ font-size: 0.875rem;
+ font-weight: 500;
+ line-height: 1.25rem;
+ cursor: pointer;
+ border: 1px solid transparent;
+ background: var(--color-cool-steel-200);
+ color: var(--color-cool-steel-900);
+ transition: color 0.15s ease, background-color 0.15s ease, border-color 0.15s ease;
+}
+[data-theme="dark"] .btn {
+ background: var(--color-cool-steel-700);
+ color: var(--color-cool-steel-50);
+}
+
+/* ── Base element styles (replaces daisyUI resets) ── */
+
/* Make LiveView wrapper divs transparent for layout */
[data-phx-session], [data-phx-teleported-src] { display: contents }
@@ -107,10 +143,11 @@
/* Sidebar layout */
#app-sidebar {
- @apply w-56 transition-all duration-200;
+ width: 14rem;
+ transition: width 0.2s ease;
}
html.sidebar-collapsed #app-sidebar {
- @apply w-16;
+ width: 4rem;
}
html.sidebar-collapsed [data-sidebar-text] {
display: none;
@@ -144,10 +181,10 @@ html.sidebar-collapsed [data-sidebar-tooltip]:hover::after {
pointer-events: none;
}
#main-wrapper {
- @apply transition-all duration-200;
+ transition: width 0.2s ease;
}
-/* This file is for your main application CSS */
+/* ── Animations ── */
/* Page transitions */
@keyframes fadeIn {
@@ -157,7 +194,7 @@ html.sidebar-collapsed [data-sidebar-tooltip]:hover::after {
.page-fade-in { animation: fadeIn 0.15s ease-out; }
/* Smooth transitions on interactive elements */
-.card, .btn, .badge, .alert {
+.card, .btn, .badge {
transition: box-shadow 0.15s ease, transform 0.15s ease;
}
@@ -179,40 +216,6 @@ html.sidebar-collapsed [data-sidebar-tooltip]:hover::after {
}
.status-pulse { animation: statusPulse 2s ease-in-out infinite; }
-/* Scrollbar styling for webkit */
-::-webkit-scrollbar { width: 6px; height: 6px; }
-::-webkit-scrollbar-track { background: transparent; }
-::-webkit-scrollbar-thumb { background: rgba(0, 0, 0, 0.15); border-radius: 3px; }
-::-webkit-scrollbar-thumb:hover { background: rgba(0, 0, 0, 0.25); }
-[data-theme="dark"] ::-webkit-scrollbar-thumb { background: rgba(255, 255, 255, 0.15); }
-[data-theme="dark"] ::-webkit-scrollbar-thumb:hover { background: rgba(255, 255, 255, 0.25); }
-
-/* Table row hover highlight */
-tbody tr:hover td { background-color: rgba(59, 130, 246, 0.04); }
-[data-theme="dark"] tbody tr:hover td { background-color: rgba(59, 130, 246, 0.08); }
-
-/* Focus ring styling */
-:focus-visible {
- outline: 2px solid oklch(58% 0.233 277.117);
- outline-offset: 2px;
-}
-
-/* Global smooth transitions for interactive elements */
-a, button, input, select, textarea {
- transition: color 0.15s ease, background-color 0.15s ease, border-color 0.15s ease, box-shadow 0.15s ease;
-}
-
-/* Dark mode body transition */
-body, .bg-gray-50, .bg-white, .dark\:bg-gray-950, .dark\:bg-gray-900 {
- transition: background-color 0.2s ease;
-}
-
-/* Password strength indicator (JS-driven via classes) */
-.password-strength-bar.strength-weak { background-color: #ef4444; }
-.password-strength-bar.strength-fair { background-color: #f59e0b; }
-.password-strength-bar.strength-good { background-color: #22c55e; }
-.password-strength-bar.strength-strong { background-color: #16a34a; }
-
/* Skeleton shimmer effect */
@keyframes shimmer {
0% { background-position: -200% 0; }
@@ -223,3 +226,34 @@ body, .bg-gray-50, .bg-white, .dark\:bg-gray-950, .dark\:bg-gray-900 {
background-size: 200% 100%;
animation: shimmer 1.5s ease-in-out infinite;
}
+
+/* ── Global element styles ── */
+
+/* Scrollbar styling for webkit */
+::-webkit-scrollbar { width: 6px; height: 6px; }
+::-webkit-scrollbar-track { background: transparent; }
+::-webkit-scrollbar-thumb { background: rgba(0, 0, 0, 0.15); border-radius: 3px; }
+::-webkit-scrollbar-thumb:hover { background: rgba(0, 0, 0, 0.25); }
+[data-theme="dark"] ::-webkit-scrollbar-thumb { background: rgba(255, 255, 255, 0.15); }
+[data-theme="dark"] ::-webkit-scrollbar-thumb:hover { background: rgba(255, 255, 255, 0.25); }
+
+/* Table row hover highlight */
+tbody tr:hover td { background-color: rgba(73, 144, 182, 0.06); }
+[data-theme="dark"] tbody tr:hover td { background-color: rgba(73, 144, 182, 0.12); }
+
+/* Focus ring styling */
+:focus-visible {
+ outline: 2px solid var(--color-cerulean-500);
+ outline-offset: 2px;
+}
+
+/* Global smooth transitions for interactive elements */
+a, button, input, select, textarea {
+ transition: color 0.15s ease, background-color 0.15s ease, border-color 0.15s ease, box-shadow 0.15s ease;
+}
+
+/* Password strength indicator (JS-driven via classes) */
+.password-strength-bar.strength-weak { background-color: var(--color-sweet-salmon-500); }
+.password-strength-bar.strength-fair { background-color: var(--color-wheat-500); }
+.password-strength-bar.strength-good { background-color: #22c55e; }
+.password-strength-bar.strength-strong { background-color: #16a34a; }
diff --git a/lib/towerops_web/components/breadcrumbs.ex b/lib/towerops_web/components/breadcrumbs.ex
index cb24c454..4d765740 100644
--- a/lib/towerops_web/components/breadcrumbs.ex
+++ b/lib/towerops_web/components/breadcrumbs.ex
@@ -1,6 +1,6 @@
defmodule ToweropsWeb.Components.Breadcrumbs do
@moduledoc """
- Reusable breadcrumb navigation component using DaisyUI.
+ Reusable breadcrumb navigation component.
"""
use Phoenix.Component
@@ -25,7 +25,7 @@ defmodule ToweropsWeb.Components.Breadcrumbs do
def breadcrumb(assigns) do
~H"""
-
+
<%= for {item, idx} <- Enum.with_index(@items) do %>
-
diff --git a/lib/towerops_web/controllers/user_settings_html/edit.html.heex b/lib/towerops_web/controllers/user_settings_html/edit.html.heex
index 621160e3..fdb478f3 100644
--- a/lib/towerops_web/controllers/user_settings_html/edit.html.heex
+++ b/lib/towerops_web/controllers/user_settings_html/edit.html.heex
@@ -20,7 +20,7 @@
-
+
<.form :let={f} for={@password_changeset} action={~p"/users/settings"} id="update_password">
@@ -44,7 +44,7 @@
-
+
diff --git a/lib/towerops_web/live/activity_feed_live.html.heex b/lib/towerops_web/live/activity_feed_live.html.heex
index 156f0728..1b0e3718 100644
--- a/lib/towerops_web/live/activity_feed_live.html.heex
+++ b/lib/towerops_web/live/activity_feed_live.html.heex
@@ -32,7 +32,7 @@
value={@search}
placeholder={t("Search by device name, IP, site, or keyword...")}
phx-debounce="300"
- class="input input-bordered w-full pl-10 pr-10 bg-white dark:bg-gray-800 dark:border-gray-700 dark:text-white dark:placeholder-gray-500"
+ class="w-full pl-10 pr-10 rounded-field border border-cool-steel-300 bg-cool-steel-50 px-3 py-2 text-sm text-cool-steel-900 placeholder:text-cool-steel-400 focus:border-cerulean-500 focus:ring-1 focus:ring-cerulean-500 dark:border-cool-steel-600 dark:bg-cool-steel-900 dark:text-cool-steel-100 dark:placeholder:text-cool-steel-500"
/>
@@ -285,7 +285,7 @@
diff --git a/lib/towerops_web/live/changelog_live.ex b/lib/towerops_web/live/changelog_live.ex
index e15335c2..7abee550 100644
--- a/lib/towerops_web/live/changelog_live.ex
+++ b/lib/towerops_web/live/changelog_live.ex
@@ -19,20 +19,25 @@ defmodule ToweropsWeb.ChangelogLive do
>
What's New
-
Latest updates and improvements to TowerOps.
+
+ Latest updates and improvements to TowerOps.
+
-
-
+
+
-
+
{Calendar.strftime(entry.date, "%b %d, %Y")}
{entry.title}
diff --git a/lib/towerops_web/live/config_timeline_live.ex b/lib/towerops_web/live/config_timeline_live.ex
index c8f373aa..901ef20e 100644
--- a/lib/towerops_web/live/config_timeline_live.ex
+++ b/lib/towerops_web/live/config_timeline_live.ex
@@ -89,17 +89,20 @@ defmodule ToweropsWeb.ConfigTimelineLive do
Config Timeline
-
- <.link navigate={~p"/devices/#{@device.id}?tab=overview"} class="link link-hover">
+
+ <.link
+ navigate={~p"/devices/#{@device.id}?tab=overview"}
+ class="text-cerulean-600 hover:text-cerulean-700 hover:underline dark:text-cerulean-400 dark:hover:text-cerulean-300"
+ >
{@device.name}
— Config changes vs performance metrics
-
+
<%!-- Timeline chart area --%>
-
-
-
Performance & Config Changes
+
+
+
Performance & Config Changes
<%!-- QoE metrics chart placeholder — rendered via hook --%>
-
@@ -130,15 +133,17 @@ defmodule ToweropsWeb.ConfigTimelineLive do
<%!-- Change events list --%>
-
-
-
Config Changes ({length(@change_events)})
+
+
+
Config Changes ({length(@change_events)})
<%= if Enum.empty?(@change_events) do %>
-
No config changes in this period.
+
+ No config changes in this period.
+
<% else %>
-
+
| When |
@@ -150,7 +155,7 @@ defmodule ToweropsWeb.ConfigTimelineLive do
@@ -160,13 +165,13 @@ defmodule ToweropsWeb.ConfigTimelineLive do
|
{section}
|
-
+
{event.change_size} lines
|
@@ -175,7 +180,7 @@ defmodule ToweropsWeb.ConfigTimelineLive do
navigate={
~p"/devices/#{@device.id}/backups/compare?before=#{event.backup_before_id}&after=#{event.backup_after_id}"
}
- class="btn btn-xs btn-ghost"
+ class="btn text-xs !py-0.5 !px-2 bg-transparent hover:bg-cool-steel-200 dark:hover:bg-cool-steel-700"
>
View Diff
@@ -190,35 +195,44 @@ defmodule ToweropsWeb.ConfigTimelineLive do
<%!-- Selected event detail modal --%>
<%= if @selected_event do %>
-
-
+
+
-
+
Change Details — {Calendar.strftime(@selected_event.changed_at, "%b %d, %H:%M UTC")}
-
+
-
Sections Changed
+
+ Sections Changed
+
{s}
Unknown
-
Lines Changed
+
+ Lines Changed
+
{@selected_event.change_size}
@@ -226,7 +240,7 @@ defmodule ToweropsWeb.ConfigTimelineLive do
navigate={
~p"/devices/#{@device.id}/backups/compare?before=#{@selected_event.backup_before_id}&after=#{@selected_event.backup_after_id}"
}
- class="btn btn-sm btn-primary"
+ class="btn text-sm !py-1 !px-3 bg-sweet-salmon-500 text-white hover:bg-sweet-salmon-600 dark:bg-sweet-salmon-600 dark:hover:bg-sweet-salmon-700"
>
Full Diff View →
@@ -235,8 +249,10 @@ defmodule ToweropsWeb.ConfigTimelineLive do
<%= if @selected_event.diff_summary do %>
-
Diff Summary
-
{@selected_event.diff_summary}
+
+ Diff Summary
+
+
{@selected_event.diff_summary}
<% end %>
@@ -267,7 +283,11 @@ defmodule ToweropsWeb.ConfigTimelineLive do
end
@doc false
- def change_size_class(size) when is_integer(size) and size > 50, do: "badge-error"
- def change_size_class(size) when is_integer(size) and size > 20, do: "badge-warning"
- def change_size_class(_), do: "badge-info"
+ def change_size_class(size) when is_integer(size) and size > 50,
+ do: "bg-sweet-salmon-100 text-sweet-salmon-800 dark:bg-sweet-salmon-900/30 dark:text-sweet-salmon-400"
+
+ def change_size_class(size) when is_integer(size) and size > 20,
+ do: "bg-yellow-100 text-yellow-800 dark:bg-yellow-900/30 dark:text-yellow-400"
+
+ def change_size_class(_), do: "bg-blue-100 text-blue-800 dark:bg-blue-900/30 dark:text-blue-400"
end
diff --git a/lib/towerops_web/live/coverage_live/form.html.heex b/lib/towerops_web/live/coverage_live/form.html.heex
index f626e6be..24ea1a88 100644
--- a/lib/towerops_web/live/coverage_live/form.html.heex
+++ b/lib/towerops_web/live/coverage_live/form.html.heex
@@ -231,7 +231,10 @@
- <.link navigate={~p"/coverage"} class="btn btn-outline">
+ <.link
+ navigate={~p"/coverage"}
+ class="btn border border-cool-steel-300 bg-transparent dark:border-cool-steel-600"
+ >
{t("Cancel")}
<.button type="submit" variant="primary">
diff --git a/lib/towerops_web/live/coverage_live/index.html.heex b/lib/towerops_web/live/coverage_live/index.html.heex
index c4894254..c534c034 100644
--- a/lib/towerops_web/live/coverage_live/index.html.heex
+++ b/lib/towerops_web/live/coverage_live/index.html.heex
@@ -21,18 +21,20 @@
<%= cond do %>
<% @sites == [] -> %>
-
-
+
+
<.icon name="hero-signal" class="h-12 w-12 text-blue-500 dark:text-blue-400" />
-
{t("Add a site first")}
+
+ {t("Add a site first")}
+
{t(
"Coverage predictions are computed from a site's location. Add a site, then return here to plan its coverage."
)}
-
+
<.button navigate={~p"/sites/new"} variant="primary">
<.icon name="hero-plus" class="h-4 w-4" /> {t("Add Site")}
@@ -42,16 +44,18 @@
<% @coverages == [] -> %>
-
-
+
+
<.icon name="hero-signal" class="h-12 w-12 text-blue-500 dark:text-blue-400" />
-
{t("No coverages yet")}
+
+ {t("No coverages yet")}
+
{t("Create your first coverage to predict where a tower's antenna reaches.")}
-
+
<.button navigate={~p"/coverage/new"} variant="primary">
<.icon name="hero-plus" class="h-4 w-4" /> {t("New Coverage")}
diff --git a/lib/towerops_web/live/coverage_live/map.html.heex b/lib/towerops_web/live/coverage_live/map.html.heex
index b13a55cf..7261d672 100644
--- a/lib/towerops_web/live/coverage_live/map.html.heex
+++ b/lib/towerops_web/live/coverage_live/map.html.heex
@@ -10,7 +10,10 @@
{t("All ready coverages overlaid. Click any point to query each tower's predicted RSSI.")}
<:actions>
- <.link navigate={~p"/coverage/list"} class="btn btn-outline btn-sm gap-1.5">
+ <.link
+ navigate={~p"/coverage/list"}
+ class="btn text-sm !py-1 !px-3 border border-cool-steel-300 bg-transparent dark:border-cool-steel-600 gap-1.5"
+ >
<.icon name="hero-list-bullet" class="h-4 w-4" /> {t("List view")}
<.button navigate={~p"/coverage/new"} variant="primary">
@@ -21,18 +24,20 @@
<%= if @coverages == [] do %>
-
-
+
+
<.icon name="hero-signal" class="h-12 w-12 text-blue-500 dark:text-blue-400" />
-
{t("No ready coverages")}
+
+ {t("No ready coverages")}
+
{t(
"Coverage maps appear here once the background compute finishes. Create or wait for a coverage to finish."
)}
-
+
<.button navigate={~p"/coverage/new"} variant="primary">
<.icon name="hero-plus" class="h-4 w-4" /> {t("New Coverage")}
diff --git a/lib/towerops_web/live/coverage_live/show.html.heex b/lib/towerops_web/live/coverage_live/show.html.heex
index 97b42836..c24514e2 100644
--- a/lib/towerops_web/live/coverage_live/show.html.heex
+++ b/lib/towerops_web/live/coverage_live/show.html.heex
@@ -33,13 +33,16 @@
- <.link navigate={~p"/coverage/#{@coverage.id}/edit"} class="btn btn-outline btn-sm gap-1.5">
+ <.link
+ navigate={~p"/coverage/#{@coverage.id}/edit"}
+ class="btn text-sm !py-1 !px-3 border border-cool-steel-300 bg-transparent dark:border-cool-steel-600 gap-1.5"
+ >
<.icon name="hero-pencil-square" class="h-4 w-4" /> {t("Edit")}
<.button phx-click="recompute" variant="primary">
diff --git a/lib/towerops_web/live/device_live/show.html.heex b/lib/towerops_web/live/device_live/show.html.heex
index 5af170ba..50980ec8 100644
--- a/lib/towerops_web/live/device_live/show.html.heex
+++ b/lib/towerops_web/live/device_live/show.html.heex
@@ -770,7 +770,7 @@
{s}
diff --git a/lib/towerops_web/live/insights_live/index.html.heex b/lib/towerops_web/live/insights_live/index.html.heex
index aafd3131..5d04d8ca 100644
--- a/lib/towerops_web/live/insights_live/index.html.heex
+++ b/lib/towerops_web/live/insights_live/index.html.heex
@@ -178,15 +178,17 @@
<%= if @insights == [] do %>
-
-
+
+
<.icon
name="hero-light-bulb-solid"
class="h-12 w-12 text-amber-500 dark:text-amber-400"
/>
-
{t("No Insights Yet")}
+
+ {t("No Insights Yet")}
+
<%= cond do %>
<% @filter_status == "dismissed" -> %>
@@ -199,8 +201,8 @@
{t("Connect Preseem or enable SNMP monitoring to get started.")}
<% end %>
-
-
+
+
{t("Go to your org settings to connect an integration.")}
diff --git a/lib/towerops_web/live/org/settings_live.html.heex b/lib/towerops_web/live/org/settings_live.html.heex
index 9f62325e..0d125f41 100644
--- a/lib/towerops_web/live/org/settings_live.html.heex
+++ b/lib/towerops_web/live/org/settings_live.html.heex
@@ -1096,11 +1096,17 @@
<%= if @organization.subscription_plan == "free" do %>
- <.button phx-click="upgrade_to_paid" class="btn-primary">
+ <.button
+ phx-click="upgrade_to_paid"
+ class="bg-sweet-salmon-500 text-white hover:bg-sweet-salmon-600 dark:bg-sweet-salmon-600 dark:hover:bg-sweet-salmon-700"
+ >
{t("Upgrade to Paid Plan")}
<% else %>
- <.button phx-click="manage_billing" class="btn-secondary">
+ <.button
+ phx-click="manage_billing"
+ class="bg-cerulean-500 text-white hover:bg-cerulean-600 dark:bg-cerulean-600 dark:hover:bg-cerulean-700"
+ >
{t("Manage Billing")}
<% end %>
diff --git a/lib/towerops_web/live/site_live/index.html.heex b/lib/towerops_web/live/site_live/index.html.heex
index 862107f1..bbbe9b17 100644
--- a/lib/towerops_web/live/site_live/index.html.heex
+++ b/lib/towerops_web/live/site_live/index.html.heex
@@ -8,7 +8,10 @@
{@page_title}
<:subtitle>{t("Manage your site locations and hierarchy")}
<:actions>
- <.link navigate={~p"/sites-map"} class="btn btn-outline btn-sm gap-1.5 mr-2">
+ <.link
+ navigate={~p"/sites-map"}
+ class="btn text-sm !py-1 !px-3 border border-cool-steel-300 bg-transparent dark:border-cool-steel-600 gap-1.5 mr-2"
+ >
<.icon name="hero-map" class="h-4 w-4" /> Map View
<.button navigate={~p"/sites/new"} variant="primary">
@@ -19,16 +22,16 @@
<%= if @sites == [] do %>
-
-
+
+
<.icon name="hero-map-pin-solid" class="h-12 w-12 text-blue-500 dark:text-blue-400" />
-
{t("No Sites Yet")}
+
{t("No Sites Yet")}
{t("Create your first site to organize devices by tower location.")}
-
+
<.button navigate={~p"/sites/new"} variant="primary">
<.icon name="hero-plus" class="h-4 w-4" /> Add Site
diff --git a/lib/towerops_web/live/site_live/show.html.heex b/lib/towerops_web/live/site_live/show.html.heex
index e2698dac..56c44253 100644
--- a/lib/towerops_web/live/site_live/show.html.heex
+++ b/lib/towerops_web/live/site_live/show.html.heex
@@ -42,7 +42,7 @@
<.button
type="button"
phx-click="force_rediscover_all"
- class="btn-sm"
+ class="btn text-sm !py-1 !px-3"
data-confirm={
t("This will trigger SNMP discovery for all devices at this site. Continue?")
}
@@ -54,18 +54,22 @@
<%!-- Quick Actions --%>
- <.button navigate={~p"/devices/new?site_id=#{@site.id}"} variant="primary" class="btn-sm">
+ <.button
+ navigate={~p"/devices/new?site_id=#{@site.id}"}
+ variant="primary"
+ class="btn text-sm !py-1 !px-3"
+ >
<.icon name="hero-plus" class="h-4 w-4" /> {t("Add Device")}
<%= if @site.latitude && @site.longitude do %>
<.button
navigate={~p"/sites-map?lat=#{@site.latitude}&lng=#{@site.longitude}&zoom=15"}
- class="btn-sm"
+ class="btn text-sm !py-1 !px-3"
>
<.icon name="hero-map" class="h-4 w-4" /> {t("View on Map")}
<% end %>
- <.button navigate={~p"/sites/#{@site.id}/edit"} class="btn-sm">
+ <.button navigate={~p"/sites/#{@site.id}/edit"} class="btn text-sm !py-1 !px-3">
<.icon name="hero-pencil" class="h-4 w-4" /> {t("Edit Site")}
@@ -286,7 +290,7 @@
-
<.link
navigate={~p"/sites/#{@site.parent_site.id}"}
- class="link link-primary text-sm"
+ class="text-sm text-cerulean-600 hover:text-cerulean-700 hover:underline dark:text-cerulean-400 dark:hover:text-cerulean-300"
>
{@site.parent_site.name}
@@ -307,13 +311,16 @@
<% end %>
<%= if @site.child_sites != [] do %>
-
+
{t("Child Sites")}
-
- <.link navigate={~p"/sites/#{child.id}"} class="link link-primary text-sm">
+ <.link
+ navigate={~p"/sites/#{child.id}"}
+ class="text-sm text-cerulean-600 hover:text-cerulean-700 hover:underline dark:text-cerulean-400 dark:hover:text-cerulean-300"
+ >
{child.name}
@@ -388,7 +395,10 @@
{time_ago(change.detected_at)}
-
+
{change_size_label(change.diff_size || 0)}
@@ -410,7 +420,7 @@
<.button
navigate={~p"/devices/new?site_id=#{@site.id}"}
variant="primary"
- class="btn-sm"
+ class="btn text-sm !py-1 !px-3"
>
<.icon name="hero-plus" class="h-4 w-4" /> Add
diff --git a/lib/towerops_web/live/trace_live/index.ex b/lib/towerops_web/live/trace_live/index.ex
index 52faa1dd..9a156383 100644
--- a/lib/towerops_web/live/trace_live/index.ex
+++ b/lib/towerops_web/live/trace_live/index.ex
@@ -31,7 +31,10 @@ defmodule ToweropsWeb.TraceLive.Index do
assigns = assign(assigns, :issues, Enum.reverse(issues))
~H"""
-
+
<.icon name="hero-exclamation-triangle" class="h-5 w-5" />
Issues Detected
@@ -53,15 +56,15 @@ defmodule ToweropsWeb.TraceLive.Index do
:good -> "border-green-200 dark:border-green-800"
:warning -> "border-yellow-200 dark:border-yellow-800"
:bad -> "border-red-200 dark:border-red-800"
- _ -> "border-base-200"
+ _ -> "border-cool-steel-200 dark:border-cool-steel-700"
end
assigns = assign(assigns, :color, color)
~H"""
-
-
{@label}
-
{@value}
+
"""
end
@@ -133,12 +136,14 @@ defmodule ToweropsWeb.TraceLive.Index do
|> push_patch(to: ~p"/trace")}
end
- def type_badge_class(:account), do: "badge-primary"
- def type_badge_class(:inventory_item), do: "badge-secondary"
- def type_badge_class(:site), do: "badge-warning"
- def type_badge_class(:device), do: "badge-accent"
- def type_badge_class(:access_point), do: "badge-info"
- def type_badge_class(_), do: "badge-ghost"
+ def type_badge_class(:account),
+ do: "bg-sweet-salmon-100 text-sweet-salmon-800 dark:bg-sweet-salmon-900/30 dark:text-sweet-salmon-400"
+
+ def type_badge_class(:inventory_item), do: "bg-purple-100 text-purple-800 dark:bg-purple-900/30 dark:text-purple-400"
+ def type_badge_class(:site), do: "bg-yellow-100 text-yellow-800 dark:bg-yellow-900/30 dark:text-yellow-400"
+ def type_badge_class(:device), do: "bg-cyan-100 text-cyan-800 dark:bg-cyan-900/30 dark:text-cyan-400"
+ def type_badge_class(:access_point), do: "bg-blue-100 text-blue-800 dark:bg-blue-900/30 dark:text-blue-400"
+ def type_badge_class(_), do: "text-cool-steel-700 dark:text-cool-steel-300"
def type_badge_label(:account), do: "Account"
def type_badge_label(:inventory_item), do: "Inventory"
@@ -148,10 +153,13 @@ defmodule ToweropsWeb.TraceLive.Index do
def type_badge_label(_), do: "Unknown"
@doc false
- def status_badge_class("active"), do: "badge-success"
- def status_badge_class("suspended"), do: "badge-warning"
- def status_badge_class("cancelled"), do: "badge-error"
- def status_badge_class(_), do: "badge-ghost"
+ def status_badge_class("active"), do: "bg-green-100 text-green-800 dark:bg-green-900/30 dark:text-green-400"
+ def status_badge_class("suspended"), do: "bg-yellow-100 text-yellow-800 dark:bg-yellow-900/30 dark:text-yellow-400"
+
+ def status_badge_class("cancelled"),
+ do: "bg-sweet-salmon-100 text-sweet-salmon-800 dark:bg-sweet-salmon-900/30 dark:text-sweet-salmon-400"
+
+ def status_badge_class(_), do: "text-cool-steel-700 dark:text-cool-steel-300"
@doc false
def device_status_color(:up), do: "text-green-600 dark:text-green-400"
diff --git a/lib/towerops_web/live/trace_live/index.html.heex b/lib/towerops_web/live/trace_live/index.html.heex
index a4c34cf6..d005161f 100644
--- a/lib/towerops_web/live/trace_live/index.html.heex
+++ b/lib/towerops_web/live/trace_live/index.html.heex
@@ -21,8 +21,8 @@
<%!-- Search Bar --%>
-
-
+
+
<.icon name="hero-magnifying-glass" class="h-6 w-6 text-gray-400 flex-shrink-0" />