diff --git a/CHANGELOG.md b/CHANGELOG.md
index 7cdf5a9..b10f219 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -20,6 +20,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
- **Graceful error recovery.** If a page crashes, you now see a friendly error screen with a "Try again" button instead of a blank white page. Each section of the app has its own error message so you know exactly what went wrong.
- **Security headers.** All pages now include clickjacking protection, MIME-sniffing prevention, a strict referrer policy, and HSTS. Browser APIs like camera and microphone are explicitly disabled.
- **Better form experience.** Forms now auto-focus the first field when they open, text inputs enforce character limits with a visible counter when you're close, and the settings page warns you before navigating away with unsaved changes.
+- **Tighter name limits.** Site, funnel, and monitor names are now capped at 100 characters instead of 255 — long enough for any real name, short enough to not break the UI.
## [0.10.0-alpha] - 2026-02-21
diff --git a/app/sites/[id]/funnels/new/page.tsx b/app/sites/[id]/funnels/new/page.tsx
index bc950a7..74f2fa0 100644
--- a/app/sites/[id]/funnels/new/page.tsx
+++ b/app/sites/[id]/funnels/new/page.tsx
@@ -122,10 +122,10 @@ export default function CreateFunnelPage() {
placeholder="e.g. Signup Flow"
autoFocus
required
- maxLength={255}
+ maxLength={100}
/>
- {name.length > 200 && (
- 240 ? 'text-amber-500' : 'text-neutral-400'}`}>{name.length}/255
+ {name.length > 80 && (
+ 90 ? 'text-amber-500' : 'text-neutral-400'}`}>{name.length}/100
)}
diff --git a/app/sites/[id]/settings/page.tsx b/app/sites/[id]/settings/page.tsx
index 8328ffb..1f78443 100644
--- a/app/sites/[id]/settings/page.tsx
+++ b/app/sites/[id]/settings/page.tsx
@@ -501,14 +501,14 @@ export default function SiteSettingsPage() {
type="text"
id="name"
required
- maxLength={255}
+ maxLength={100}
value={formData.name}
onChange={(e) => setFormData({ ...formData, name: e.target.value })}
className="w-full px-4 py-2 border border-neutral-200 dark:border-neutral-800 rounded-lg bg-neutral-50/50 dark:bg-neutral-900/50 focus:bg-white dark:focus:bg-neutral-900
focus:border-brand-orange focus:ring-4 focus:ring-brand-orange/10 outline-none transition-all duration-200 dark:text-white"
/>
- {formData.name.length > 200 && (
- 240 ? 'text-amber-500' : 'text-neutral-400'}`}>{formData.name.length}/255
+ {formData.name.length > 80 && (
+ 90 ? 'text-amber-500' : 'text-neutral-400'}`}>{formData.name.length}/100
)}
diff --git a/app/sites/[id]/uptime/page.tsx b/app/sites/[id]/uptime/page.tsx
index deb9884..acebcb7 100644
--- a/app/sites/[id]/uptime/page.tsx
+++ b/app/sites/[id]/uptime/page.tsx
@@ -938,11 +938,11 @@ function MonitorForm({
onChange={(e) => setFormData({ ...formData, name: e.target.value })}
placeholder="e.g. API, Website, CDN"
autoFocus
- maxLength={255}
+ maxLength={100}
className="w-full px-3 py-2 rounded-lg border border-neutral-300 dark:border-neutral-600 bg-white dark:bg-neutral-800 text-neutral-900 dark:text-white placeholder-neutral-400 focus:outline-none focus:ring-2 focus:ring-brand-orange focus:border-transparent text-sm"
/>
- {formData.name.length > 200 && (
- 240 ? 'text-amber-500' : 'text-neutral-400'}`}>{formData.name.length}/255
+ {formData.name.length > 80 && (
+ 90 ? 'text-amber-500' : 'text-neutral-400'}`}>{formData.name.length}/100
)}
diff --git a/app/sites/new/page.tsx b/app/sites/new/page.tsx
index 3e3ae09..7e651d6 100644
--- a/app/sites/new/page.tsx
+++ b/app/sites/new/page.tsx
@@ -192,7 +192,7 @@ export default function NewSitePage() {
id="name"
required
autoFocus
- maxLength={255}
+ maxLength={100}
value={formData.name}
onChange={(e) => setFormData({ ...formData, name: e.target.value })}
placeholder="My Website"