fix: add dark mode support to marketing site

Add dark: variants throughout the marketing page and layout so text,
backgrounds, cards, badges, and borders render properly when the
system or user preference is set to dark mode. Use invert + screen
blend mode on the logo PNG to eliminate its white background.
This commit is contained in:
Graham McIntire 2026-03-04 13:57:12 -06:00
parent dce9253afc
commit 94bc755dd8
No known key found for this signature in database
2 changed files with 134 additions and 98 deletions

View file

@ -30,20 +30,24 @@ defmodule ToweropsWeb.MarketingLayouts do
assigns = Map.put(assigns, :requires_cookie_consent, requires_cookie_consent)
~H"""
<div class="bg-white dark:bg-gray-900">
<div class="bg-white dark:bg-slate-950">
<header class="py-10">
<div class="mx-auto max-w-7xl px-4 sm:px-6 lg:px-8">
<nav class="relative z-50 flex justify-between">
<div class="flex items-center md:gap-x-12">
<div class="flex items-center md:gap-x-12 dark:bg-slate-950 dark:rounded-lg">
<.link navigate={~p"/"} aria-label="Home">
<img src="/images/towerops_logo.png" alt="Towerops" class="w-48 h-auto sm:w-64" />
<img
src="/images/towerops_logo.png"
alt="Towerops"
class="w-48 h-auto sm:w-64 dark:invert dark:mix-blend-screen"
/>
</.link>
</div>
<div class="flex items-center gap-x-5 md:gap-x-8">
<div class="hidden md:block">
<.link
navigate={~p"/users/log-in"}
class="inline-block rounded-lg px-2 py-1 text-sm text-slate-700 hover:bg-slate-100 hover:text-slate-900"
class="inline-block rounded-lg px-2 py-1 text-sm text-slate-700 dark:text-slate-300 hover:bg-slate-100 dark:hover:bg-slate-800 hover:text-slate-900 dark:hover:text-white"
>
Sign in
</.link>
@ -65,20 +69,24 @@ defmodule ToweropsWeb.MarketingLayouts do
{render_slot(@inner_block)}
</main>
<footer class="bg-slate-50">
<footer class="bg-slate-50 dark:bg-slate-900">
<div class="mx-auto max-w-7xl px-4 sm:px-6 lg:px-8">
<div class="py-16">
<img src="/images/towerops_logo.png" alt="Towerops" class="mx-auto w-48 h-auto sm:w-64" />
<img
src="/images/towerops_logo.png"
alt="Towerops"
class="mx-auto w-48 h-auto sm:w-64 dark:invert dark:mix-blend-screen"
/>
</div>
<div class="grid grid-cols-1 gap-8 border-t border-slate-400/10 py-10 lg:grid-cols-4">
<!-- Product Column -->
<div>
<h3 class="text-sm font-semibold text-slate-900 mb-4">Product</h3>
<h3 class="text-sm font-semibold text-slate-900 dark:text-white mb-4">Product</h3>
<ul class="space-y-3">
<li>
<.link
href="/#features"
class="text-sm text-slate-600 hover:text-slate-900 transition-colors"
class="text-sm text-slate-600 dark:text-slate-400 hover:text-slate-900 dark:hover:text-white transition-colors"
>
Features
</.link>
@ -86,7 +94,7 @@ defmodule ToweropsWeb.MarketingLayouts do
<li>
<.link
href="/#pricing"
class="text-sm text-slate-600 hover:text-slate-900 transition-colors"
class="text-sm text-slate-600 dark:text-slate-400 hover:text-slate-900 dark:hover:text-white transition-colors"
>
Pricing
</.link>
@ -96,12 +104,12 @@ defmodule ToweropsWeb.MarketingLayouts do
<!-- Developers Column -->
<div>
<h3 class="text-sm font-semibold text-slate-900 mb-4">Developers</h3>
<h3 class="text-sm font-semibold text-slate-900 dark:text-white mb-4">Developers</h3>
<ul class="space-y-3">
<li>
<.link
navigate={~p"/docs/api"}
class="text-sm text-slate-600 hover:text-slate-900 transition-colors"
class="text-sm text-slate-600 dark:text-slate-400 hover:text-slate-900 dark:hover:text-white transition-colors"
>
API Documentation
</.link>
@ -109,7 +117,7 @@ defmodule ToweropsWeb.MarketingLayouts do
<li>
<.link
navigate={~p"/docs/graphql"}
class="text-sm text-slate-600 hover:text-slate-900 transition-colors"
class="text-sm text-slate-600 dark:text-slate-400 hover:text-slate-900 dark:hover:text-white transition-colors"
>
GraphQL API
</.link>
@ -117,7 +125,7 @@ defmodule ToweropsWeb.MarketingLayouts do
<li>
<.link
navigate={~p"/help"}
class="text-sm text-slate-600 hover:text-slate-900 transition-colors"
class="text-sm text-slate-600 dark:text-slate-400 hover:text-slate-900 dark:hover:text-white transition-colors"
>
Help & Docs
</.link>
@ -129,20 +137,20 @@ defmodule ToweropsWeb.MarketingLayouts do
<div class="lg:col-span-2">
<div class="flex flex-col items-start gap-4 sm:flex-row sm:justify-between sm:items-end">
<div class="flex flex-col gap-2">
<p class="text-sm text-slate-500">
<p class="text-sm text-slate-500 dark:text-slate-400">
Copyright © {Date.utc_today().year} Towerops
</p>
<div class="flex gap-x-4 text-xs text-slate-500">
<div class="flex gap-x-4 text-xs text-slate-500 dark:text-slate-500">
<.link
navigate={~p"/privacy"}
class="hover:text-slate-700 underline decoration-dotted underline-offset-2"
class="hover:text-slate-700 dark:hover:text-slate-300 underline decoration-dotted underline-offset-2"
>
Privacy Policy
</.link>
<span>·</span>
<.link
navigate={~p"/terms"}
class="hover:text-slate-700 underline decoration-dotted underline-offset-2"
class="hover:text-slate-700 dark:hover:text-slate-300 underline decoration-dotted underline-offset-2"
>
Terms of Service
</.link>

View file

@ -1,16 +1,16 @@
<MarketingLayouts.marketing flash={@flash}>
<!-- Hero Section -->
<div class="mx-auto max-w-7xl px-4 sm:px-6 lg:px-8 pt-20 pb-16 text-center lg:pt-32">
<div class="inline-flex items-center rounded-full px-4 py-1.5 mb-8 bg-blue-50 text-blue-700 text-sm font-medium ring-1 ring-blue-600/20">
<div class="inline-flex items-center rounded-full px-4 py-1.5 mb-8 bg-blue-50 dark:bg-blue-950 text-blue-700 dark:text-blue-300 text-sm font-medium ring-1 ring-blue-600/20">
<span class="mr-2">📡</span> Built specifically for WISP &amp; ISP operators
</div>
<h1 class="mx-auto max-w-4xl font-display text-5xl font-medium tracking-tight text-slate-900 sm:text-7xl">
<h1 class="mx-auto max-w-4xl font-display text-5xl font-medium tracking-tight text-slate-900 dark:text-white sm:text-7xl">
See the
<span class="relative whitespace-nowrap text-blue-600">
<span class="relative whitespace-nowrap text-blue-600 dark:text-blue-400">
<svg
aria-hidden="true"
viewBox="0 0 418 42"
class="absolute top-2/3 left-0 h-[0.58em] w-full fill-blue-300/70"
class="absolute top-2/3 left-0 h-[0.58em] w-full fill-blue-300/70 dark:fill-blue-500/40"
preserveAspectRatio="none"
>
<path d="M203.371.916c-26.013-2.078-76.686 1.963-124.73 9.946L67.3 12.749C35.421 18.062 18.2 21.766 6.004 25.934 1.244 27.561.828 27.778.874 28.61c.07 1.214.828 1.121 9.595-1.176 9.072-2.377 17.15-3.92 39.246-7.496C123.565 7.986 157.869 4.492 195.942 5.046c7.461.108 19.25 1.696 19.17 2.582-.107 1.183-7.874 4.31-25.75 10.366-21.992 7.45-35.43 12.534-36.701 13.884-2.173 2.308-.202 4.407 4.442 4.734 2.654.187 3.263.157 15.593-.78 35.401-2.686 57.944-3.488 88.365-3.143 46.327.526 75.721 2.23 130.788 7.584 19.787 1.924 20.814 1.98 24.557 1.332l.066-.011c1.201-.203 1.53-1.825.399-2.335-2.911-1.31-4.893-1.604-22.048-3.261-57.509-5.556-87.871-7.36-132.059-7.842-23.239-.254-33.617-.116-50.627.674-11.629.54-42.371 2.494-46.696 2.967-2.359.259 8.133-3.625 26.504-9.81 23.239-7.825 27.934-10.149 28.304-14.005.417-4.348-3.529-6-16.878-7.066Z" />
@ -19,12 +19,12 @@
</span>
of every network event.
</h1>
<p class="mx-auto mt-6 max-w-2xl text-lg tracking-tight text-slate-700">
<p class="mx-auto mt-6 max-w-2xl text-lg tracking-tight text-slate-700 dark:text-slate-300">
TowerOps connects your network monitoring to subscriber impact and revenue.
When a tower goes down, instantly see which customers are affected, how much MRR is at risk,
and what to fix first.
</p>
<p class="mx-auto mt-4 max-w-2xl text-xl font-semibold tracking-tight text-blue-600">
<p class="mx-auto mt-4 max-w-2xl text-xl font-semibold tracking-tight text-blue-600 dark:text-blue-400">
First 10 devices always free. No credit card required.
</p>
<div class="mt-10 flex justify-center gap-x-6">
@ -36,7 +36,7 @@
</.link>
<a
href="#features"
class="group inline-flex items-center justify-center rounded-full py-3 px-6 text-sm font-semibold ring-1 ring-slate-200 text-slate-700 hover:text-slate-900 hover:ring-slate-300 active:bg-slate-100 focus-visible:outline-blue-600"
class="group inline-flex items-center justify-center rounded-full py-3 px-6 text-sm font-semibold ring-1 ring-slate-200 dark:ring-slate-700 text-slate-700 dark:text-slate-300 hover:text-slate-900 dark:hover:text-white hover:ring-slate-300 dark:hover:ring-slate-600 active:bg-slate-100 dark:active:bg-slate-800 focus-visible:outline-blue-600"
>
See how it works
</a>
@ -172,14 +172,14 @@
<section
id="how-it-works"
aria-label="How TowerOps works"
class="relative bg-slate-50 py-20 sm:py-32"
class="relative bg-slate-50 dark:bg-slate-900 py-20 sm:py-32"
>
<div class="mx-auto max-w-7xl px-4 sm:px-6 lg:px-8">
<div class="mx-auto max-w-2xl md:text-center">
<h2 class="font-display text-3xl tracking-tight text-slate-900 sm:text-4xl">
<h2 class="font-display text-3xl tracking-tight text-slate-900 dark:text-white sm:text-4xl">
Up and running in 10 minutes
</h2>
<p class="mt-4 text-lg tracking-tight text-slate-700">
<p class="mt-4 text-lg tracking-tight text-slate-700 dark:text-slate-300">
No agents to install on every device. One Docker container per network, and you're monitoring everything.
</p>
</div>
@ -190,13 +190,15 @@
<div class="flex h-10 w-10 items-center justify-center rounded-full bg-blue-600 text-white font-semibold text-lg">
1
</div>
<h3 class="text-xl font-semibold text-slate-900">Deploy a lightweight agent</h3>
<h3 class="text-xl font-semibold text-slate-900 dark:text-white">
Deploy a lightweight agent
</h3>
</div>
<p class="mt-4 text-base text-slate-600">
<p class="mt-4 text-base text-slate-600 dark:text-slate-400">
Run a single Docker container on your network. It discovers SNMP devices automatically
and starts collecting metrics. No firewall changes, no VPN, no open ports.
</p>
<div class="mt-6 rounded-lg bg-slate-900 p-4 font-mono text-sm text-green-400">
<div class="mt-6 rounded-lg bg-slate-900 dark:bg-black/50 dark:ring-1 dark:ring-white/10 p-4 font-mono text-sm text-green-400">
$ docker run -d towerops/agent
</div>
</div>
@ -206,32 +208,34 @@
<div class="flex h-10 w-10 items-center justify-center rounded-full bg-blue-600 text-white font-semibold text-lg">
2
</div>
<h3 class="text-xl font-semibold text-slate-900">Connect your tools</h3>
<h3 class="text-xl font-semibold text-slate-900 dark:text-white">
Connect your tools
</h3>
</div>
<p class="mt-4 text-base text-slate-600">
<p class="mt-4 text-base text-slate-600 dark:text-slate-400">
Add your billing platform API key for subscriber data and Preseem for QoE metrics.
TowerOps automatically maps subscribers to devices and tower sites.
</p>
<div class="mt-6 flex flex-wrap gap-2">
<span class="inline-flex items-center rounded-full bg-blue-50 px-3 py-1 text-xs font-medium text-blue-700 ring-1 ring-blue-600/20">
<span class="inline-flex items-center rounded-full bg-blue-50 dark:bg-blue-950 px-3 py-1 text-xs font-medium text-blue-700 dark:text-blue-300 ring-1 ring-blue-600/20">
Gaiia
</span>
<span class="inline-flex items-center rounded-full bg-blue-50 px-3 py-1 text-xs font-medium text-blue-700 ring-1 ring-blue-600/20">
<span class="inline-flex items-center rounded-full bg-blue-50 dark:bg-blue-950 px-3 py-1 text-xs font-medium text-blue-700 dark:text-blue-300 ring-1 ring-blue-600/20">
Sonar
</span>
<span class="inline-flex items-center rounded-full bg-blue-50 px-3 py-1 text-xs font-medium text-blue-700 ring-1 ring-blue-600/20">
<span class="inline-flex items-center rounded-full bg-blue-50 dark:bg-blue-950 px-3 py-1 text-xs font-medium text-blue-700 dark:text-blue-300 ring-1 ring-blue-600/20">
Preseem
</span>
<span class="inline-flex items-center rounded-full bg-blue-50 px-3 py-1 text-xs font-medium text-blue-700 ring-1 ring-blue-600/20">
<span class="inline-flex items-center rounded-full bg-blue-50 dark:bg-blue-950 px-3 py-1 text-xs font-medium text-blue-700 dark:text-blue-300 ring-1 ring-blue-600/20">
Splynx
</span>
<span class="inline-flex items-center rounded-full bg-blue-50 px-3 py-1 text-xs font-medium text-blue-700 ring-1 ring-blue-600/20">
<span class="inline-flex items-center rounded-full bg-blue-50 dark:bg-blue-950 px-3 py-1 text-xs font-medium text-blue-700 dark:text-blue-300 ring-1 ring-blue-600/20">
VISP
</span>
<span class="inline-flex items-center rounded-full bg-blue-50 px-3 py-1 text-xs font-medium text-blue-700 ring-1 ring-blue-600/20">
<span class="inline-flex items-center rounded-full bg-blue-50 dark:bg-blue-950 px-3 py-1 text-xs font-medium text-blue-700 dark:text-blue-300 ring-1 ring-blue-600/20">
NetBox
</span>
<span class="inline-flex items-center rounded-full bg-blue-50 px-3 py-1 text-xs font-medium text-blue-700 ring-1 ring-blue-600/20">
<span class="inline-flex items-center rounded-full bg-blue-50 dark:bg-blue-950 px-3 py-1 text-xs font-medium text-blue-700 dark:text-blue-300 ring-1 ring-blue-600/20">
PagerDuty
</span>
</div>
@ -242,18 +246,22 @@
<div class="flex h-10 w-10 items-center justify-center rounded-full bg-blue-600 text-white font-semibold text-lg">
3
</div>
<h3 class="text-xl font-semibold text-slate-900">See the full picture</h3>
<h3 class="text-xl font-semibold text-slate-900 dark:text-white">
See the full picture
</h3>
</div>
<p class="mt-4 text-base text-slate-600">
<p class="mt-4 text-base text-slate-600 dark:text-slate-400">
Your dashboard lights up with subscriber impact, revenue at risk, device health,
and site status. Help desk gets subscriber trace. NOC gets alert triage. Everyone wins.
</p>
<div class="mt-6 rounded-lg border-2 border-blue-200 dark:border-blue-800 bg-white dark:bg-white/5 p-4">
<div class="flex items-center gap-2">
<.icon name="hero-chart-bar" class="h-5 w-5 text-blue-600" />
<span class="text-sm font-medium text-slate-900">Impact Dashboard</span>
<.icon name="hero-chart-bar" class="h-5 w-5 text-blue-600 dark:text-blue-400" />
<span class="text-sm font-medium text-slate-900 dark:text-white">
Impact Dashboard
</span>
</div>
<div class="mt-2 grid grid-cols-2 gap-2 text-xs text-slate-600">
<div class="mt-2 grid grid-cols-2 gap-2 text-xs text-slate-600 dark:text-slate-400">
<div>📊 MRR at Risk</div>
<div>👥 Affected Subs</div>
<div>🔴 Active Incidents</div>
@ -269,34 +277,34 @@
<section class="py-20 sm:py-24">
<div class="mx-auto max-w-7xl px-4 sm:px-6 lg:px-8">
<div class="mx-auto max-w-2xl md:text-center">
<h2 class="font-display text-3xl tracking-tight text-slate-900 sm:text-4xl">
<h2 class="font-display text-3xl tracking-tight text-slate-900 dark:text-white sm:text-4xl">
Built by a WISP operator, for WISP operators.
</h2>
<p class="mt-4 text-lg tracking-tight text-slate-700">
<p class="mt-4 text-lg tracking-tight text-slate-700 dark:text-slate-300">
We run a network too. TowerOps exists because we got tired of the same problems you have.
</p>
</div>
<div class="mt-16 grid grid-cols-1 gap-8 sm:grid-cols-2 lg:grid-cols-3">
<div class="rounded-xl bg-slate-50 p-8">
<div class="rounded-xl bg-slate-50 dark:bg-slate-800/50 dark:ring-1 dark:ring-white/10 p-8">
<div class="text-2xl mb-4">🏗️</div>
<h3 class="text-lg font-semibold text-slate-900">For the NOC</h3>
<p class="mt-3 text-sm text-slate-600">
<h3 class="text-lg font-semibold text-slate-900 dark:text-white">For the NOC</h3>
<p class="mt-3 text-sm text-slate-600 dark:text-slate-400">
Alert triage grouped by site with severity colors and subscriber impact.
Stop wasting time on low-impact alerts when a whole tower is down.
</p>
</div>
<div class="rounded-xl bg-slate-50 p-8">
<div class="rounded-xl bg-slate-50 dark:bg-slate-800/50 dark:ring-1 dark:ring-white/10 p-8">
<div class="text-2xl mb-4">📞</div>
<h3 class="text-lg font-semibold text-slate-900">For the Help Desk</h3>
<p class="mt-3 text-sm text-slate-600">
<h3 class="text-lg font-semibold text-slate-900 dark:text-white">For the Help Desk</h3>
<p class="mt-3 text-sm text-slate-600 dark:text-slate-400">
Subscriber trace: search by name, see their device status, QoE, and whether
the whole tower is having issues. Answer "is it just me?" in seconds.
</p>
</div>
<div class="rounded-xl bg-slate-50 p-8">
<div class="rounded-xl bg-slate-50 dark:bg-slate-800/50 dark:ring-1 dark:ring-white/10 p-8">
<div class="text-2xl mb-4">📈</div>
<h3 class="text-lg font-semibold text-slate-900">For the Owner</h3>
<p class="mt-3 text-sm text-slate-600">
<h3 class="text-lg font-semibold text-slate-900 dark:text-white">For the Owner</h3>
<p class="mt-3 text-sm text-slate-600 dark:text-slate-400">
MRR at risk, revenue impact per incident, and site health scores.
Make investment decisions based on which towers affect the most revenue.
</p>
@ -306,63 +314,83 @@
</section>
<!-- Pricing Section -->
<section id="pricing" class="bg-slate-50 py-20 sm:py-32">
<section id="pricing" class="bg-slate-50 dark:bg-slate-900 py-20 sm:py-32">
<div class="mx-auto max-w-7xl px-4 sm:px-6 lg:px-8">
<div class="mx-auto max-w-2xl text-center">
<h2 class="font-display text-3xl tracking-tight text-slate-900 sm:text-4xl">
<h2 class="font-display text-3xl tracking-tight text-slate-900 dark:text-white sm:text-4xl">
Your first 10 devices are always free
</h2>
<p class="mt-4 text-lg tracking-tight text-slate-700">
<p class="mt-4 text-lg tracking-tight text-slate-700 dark:text-slate-300">
Every feature. No time limits. No credit card. Only pay when you grow past 10 devices.
</p>
</div>
<div class="mt-16 mx-auto max-w-xl">
<div class="rounded-2xl bg-white dark:bg-gray-900 p-8 shadow-lg dark:shadow-gray-900/50 ring-2 ring-blue-600 text-center">
<div class="rounded-2xl bg-white dark:bg-slate-800 p-8 shadow-lg dark:shadow-black/30 ring-2 ring-blue-600 text-center">
<div class="mt-2">
<span class="text-5xl font-bold text-slate-900">$3</span>
<span class="text-lg text-slate-500">/device/month</span>
<span class="text-5xl font-bold text-slate-900 dark:text-white">$3</span>
<span class="text-lg text-slate-500 dark:text-slate-400">/device/month</span>
</div>
<p class="mt-3 text-base text-slate-600">
First 10 devices are <strong class="text-slate-900">free forever</strong>
<p class="mt-3 text-base text-slate-600 dark:text-slate-300">
First 10 devices are
<strong class="text-slate-900 dark:text-white">free forever</strong>
— all features, no limits. Pay $3/device/month only after that.
</p>
<div class="mt-10 grid grid-cols-2 gap-x-8 gap-y-3 text-sm text-slate-600 text-left max-w-md mx-auto">
<div class="mt-10 grid grid-cols-2 gap-x-8 gap-y-3 text-sm text-slate-600 dark:text-slate-300 text-left max-w-md mx-auto">
<div class="flex items-center gap-2">
<.icon name="hero-check" class="h-5 w-5 text-blue-600 flex-shrink-0" />
Unlimited devices
<.icon
name="hero-check"
class="h-5 w-5 text-blue-600 dark:text-blue-400 flex-shrink-0"
/> Unlimited devices
</div>
<div class="flex items-center gap-2">
<.icon name="hero-check" class="h-5 w-5 text-blue-600 flex-shrink-0" />
Unlimited agents &amp; networks
<.icon
name="hero-check"
class="h-5 w-5 text-blue-600 dark:text-blue-400 flex-shrink-0"
/> Unlimited agents &amp; networks
</div>
<div class="flex items-center gap-2">
<.icon name="hero-check" class="h-5 w-5 text-blue-600 flex-shrink-0" />
SNMP monitoring &amp; alerts
<.icon
name="hero-check"
class="h-5 w-5 text-blue-600 dark:text-blue-400 flex-shrink-0"
/> SNMP monitoring &amp; alerts
</div>
<div class="flex items-center gap-2">
<.icon name="hero-check" class="h-5 w-5 text-blue-600 flex-shrink-0" />
Impact dashboard
<.icon
name="hero-check"
class="h-5 w-5 text-blue-600 dark:text-blue-400 flex-shrink-0"
/> Impact dashboard
</div>
<div class="flex items-center gap-2">
<.icon name="hero-check" class="h-5 w-5 text-blue-600 flex-shrink-0" />
All billing integrations
<.icon
name="hero-check"
class="h-5 w-5 text-blue-600 dark:text-blue-400 flex-shrink-0"
/> All billing integrations
</div>
<div class="flex items-center gap-2">
<.icon name="hero-check" class="h-5 w-5 text-blue-600 flex-shrink-0" />
Preseem &amp; PagerDuty
<.icon
name="hero-check"
class="h-5 w-5 text-blue-600 dark:text-blue-400 flex-shrink-0"
/> Preseem &amp; PagerDuty
</div>
<div class="flex items-center gap-2">
<.icon name="hero-check" class="h-5 w-5 text-blue-600 flex-shrink-0" />
Subscriber trace &amp; alert triage
<.icon
name="hero-check"
class="h-5 w-5 text-blue-600 dark:text-blue-400 flex-shrink-0"
/> Subscriber trace &amp; alert triage
</div>
<%!-- Config change tracking hidden — feature temporarily disabled --%>
<div class="flex items-center gap-2">
<.icon name="hero-check" class="h-5 w-5 text-blue-600 flex-shrink-0" />
Team access &amp; email alerts
<.icon
name="hero-check"
class="h-5 w-5 text-blue-600 dark:text-blue-400 flex-shrink-0"
/> Team access &amp; email alerts
</div>
<div class="flex items-center gap-2">
<.icon name="hero-check" class="h-5 w-5 text-blue-600 flex-shrink-0" /> API access
<.icon
name="hero-check"
class="h-5 w-5 text-blue-600 dark:text-blue-400 flex-shrink-0"
/> API access
</div>
</div>
@ -374,10 +402,10 @@
</.link>
</div>
</div>
<p class="mt-8 text-center text-sm text-slate-500">
<p class="mt-8 text-center text-sm text-slate-500 dark:text-slate-400">
No credit card required. Need a custom plan for 500+ devices? <a
href="mailto:hi@towerops.net"
class="text-blue-600 hover:text-blue-500 underline"
class="text-blue-600 dark:text-blue-400 hover:text-blue-500 dark:hover:text-blue-300 underline"
>Talk to us</a>.
</p>
</div>
@ -387,35 +415,35 @@
<section class="py-20 sm:py-24">
<div class="mx-auto max-w-7xl px-4 sm:px-6 lg:px-8">
<div class="mx-auto max-w-2xl md:text-center">
<h2 class="font-display text-3xl tracking-tight text-slate-900 sm:text-4xl">
<h2 class="font-display text-3xl tracking-tight text-slate-900 dark:text-white sm:text-4xl">
Built for network engineers
</h2>
<p class="mt-4 text-lg tracking-tight text-slate-700">
<p class="mt-4 text-lg tracking-tight text-slate-700 dark:text-slate-300">
We know you care about the details. Here's what's under the hood.
</p>
</div>
<div class="mt-16 grid grid-cols-1 gap-6 sm:grid-cols-2 lg:grid-cols-4">
<div class="rounded-lg border border-slate-200 p-6">
<h3 class="font-semibold text-slate-900">786 Device Profiles</h3>
<p class="mt-2 text-sm text-slate-600">
<div class="rounded-lg border border-slate-200 dark:border-slate-700 p-6">
<h3 class="font-semibold text-slate-900 dark:text-white">786 Device Profiles</h3>
<p class="mt-2 text-sm text-slate-600 dark:text-slate-400">
MikroTik, Ubiquiti, Cambium, Cisco, Juniper, and hundreds more. Auto-detected via SNMP sysObjectID.
</p>
</div>
<div class="rounded-lg border border-slate-200 p-6">
<h3 class="font-semibold text-slate-900">Secure Agent Architecture</h3>
<p class="mt-2 text-sm text-slate-600">
<div class="rounded-lg border border-slate-200 dark:border-slate-700 p-6">
<h3 class="font-semibold text-slate-900 dark:text-white">Secure Agent Architecture</h3>
<p class="mt-2 text-sm text-slate-600 dark:text-slate-400">
Agent initiates outbound-only connections. Your devices never touch the internet. Zero attack surface.
</p>
</div>
<div class="rounded-lg border border-slate-200 p-6">
<h3 class="font-semibold text-slate-900">SNMP v1/v2c/v3</h3>
<p class="mt-2 text-sm text-slate-600">
<div class="rounded-lg border border-slate-200 dark:border-slate-700 p-6">
<h3 class="font-semibold text-slate-900 dark:text-white">SNMP v1/v2c/v3</h3>
<p class="mt-2 text-sm text-slate-600 dark:text-slate-400">
Full SNMP support including SNMPv3 auth/priv. Custom OID polling for vendor-specific metrics.
</p>
</div>
<div class="rounded-lg border border-slate-200 p-6">
<h3 class="font-semibold text-slate-900">Real-time LiveView UI</h3>
<p class="mt-2 text-sm text-slate-600">
<div class="rounded-lg border border-slate-200 dark:border-slate-700 p-6">
<h3 class="font-semibold text-slate-900 dark:text-white">Real-time LiveView UI</h3>
<p class="mt-2 text-sm text-slate-600 dark:text-slate-400">
No page refreshes. WebSocket-powered dashboard updates in real time as metrics flow in.
</p>
</div>
@ -436,7 +464,7 @@
</p>
<.link
navigate={~p"/users/register"}
class="group inline-flex items-center justify-center rounded-full py-3 px-6 text-sm font-semibold focus-visible:outline-2 focus-visible:outline-offset-2 mt-10 bg-white dark:bg-gray-100 text-slate-900 hover:bg-blue-50 dark:hover:bg-white active:bg-blue-200 active:text-slate-600 focus-visible:outline-white"
class="group inline-flex items-center justify-center rounded-full py-3 px-6 text-sm font-semibold focus-visible:outline-2 focus-visible:outline-offset-2 mt-10 bg-white text-slate-900 hover:bg-blue-50 active:bg-blue-200 active:text-slate-600 focus-visible:outline-white"
>
Start monitoring free →
</.link>