# Signal — Developer Tool Landing Page Template

> For a CLI or observability tool: a dark-first developer tool landing page template with docs, a changelog, a cost estimator and an incident page. 8 routes.

- Price: $24, one-time
- License: Standard
- Version: 2.8.4
- Category: SaaS landing page
- Editions: React, HTML
- Dark mode: Yes
- Stack: Next.js >=15, React >=19, Tailwind CSS >=4
- Dependencies: `lucide-react`

## What's inside

- 8 pages
- 38 components
- 73 design tokens plus 73 dark overrides

## Pages

| Path | Sections |
| --- | --- |
| `/` | `site-header`, `terminal-hero`, `incident-band`, `integrations`, `feature-grid`, `changelog-section`, `cta`, `site-footer` |
| `/pricing` | `site-header`, `cost-estimator`, `pricing-plans`, `faq`, `cta`, `site-footer` |
| `/changelog` | `site-header`, `changelog-section`, `cta`, `site-footer` |
| `/docs` | `site-header`, `ui/page-hero`, `docs-shell`, `site-footer` |
| `/cli` | `site-header`, `ui/terminal-window`, `docs-shell`, `site-footer` |
| `/contact` | `site-header`, `contact-card`, `cta`, `site-footer` |
| `/incident` | `site-header`, `incident-header`, `trace-comparison`, `deploy-diff`, `evidence-timeline`, `failure-cluster`, `resolution-receipt`, `site-footer` |
| `/components` | `site-header`, `terminal-hero`, `incident-band`, `integrations`, `feature-grid`, `pricing-plans`, `cost-estimator`, `contact-card`, `changelog-section`, `incident-header`, `trace-comparison`, `deploy-diff`, `evidence-timeline`, `failure-cluster`, `resolution-receipt`, `cta`, `docs-shell`, `site-footer`, `ui/button`, `ui/badge`, `ui/theme-toggle`, `ui/copy-button`, `ui/code-block`, `ui/terminal-window`, `ui/section-heading`, `ui/page-hero`, `ui/field`, `ui/inline-code` |

## Components

| Name | What it renders |
| --- | --- |
| `site-header` | Sticky nav: wordmark, five links, a quiet non-interactive star-count chip, a light/dark icon toggle that writes to localStorage, sign-in and CTA, plus a JS-free &lt;details&gt; mobile menu |
| `terminal-hero` | Version badge, headline, install command row and the signature terminal: an annotated `sgl watch` transcript with a brand title bar and a status line, overhanging the container to the right. Sits over a generated contour field that is masked, not coloured, so it re-tints with --primary |
| `incident-band` | The hero's regression narrative as a drawn figure: a p95 latency series flat inside its 24h rolling envelope, a deploy marker, and the step up 24 seconds later. Inline SVG computed from two editable point arrays, token-coloured (rebrand-safe), server-rendered and static |
| `integrations` | Full-bleed hairline grid of eight supported data sources, one lucide glyph each describing what the source does — the page container break |
| `feature-grid` | Four feature cards carrying nine lines each of real YAML/TypeScript/shell, a named outcome quote, and three supporting cards that each name a command |
| `changelog-section` | Dated release entries with icon-marked added/improved/fixed/breaking notes; breaking releases carry an `sgl migrate config` transcript strip. Three latest on home; on /changelog it opens the page behind a live per-tag filter with counts read off the log and closes on a full-bleed release-cadence band |
| `pricing-plans` | Three plans on one usage price model — free tier, per-gigabyte usage, and a self-hosted collector that leads with what differs rather than repeating the rate — then the definition of a billed gigabyte beside a ledger of the six things that are never metered |
| `cost-estimator` | Working cost estimator, and the section that opens /pricing: a volume slider and number input plus five sample-rate presets drive a mono tabular ledger and a display-size monthly total, with the free-tier floor handled as a floor and not a credit |
| `contact-card` | The company surface, and the section that opens /contact: four engineering contact routes with mailto addresses and stated response times, a full-bleed operations band of regions, retention, sub-processors and uptime, and the legal minimum at #legal |
| `cta` | Closing panel: headline, two buttons, an init command and four answers to cost, risk and effort, over a radial wash |
| `site-footer` | Three link columns of real destinations, product blurb, build string and an operational status line |
| `docs-shell` | Documentation layout in two variants: grouped sidebar, on-this-page rail, and route-specific closing evidence. quickstart renders a five-step guide with a local request/result excerpt; cli renders seven commands and the annotated trace payoff |
| `incident-header` | Incident identity, status, affected service, explicit onset, baseline and incident p95, plus investigating, identified, monitoring, and resolved server variants |
| `trace-comparison` | Direct-labelled baseline and incident span comparison on one scale, followed by an exact table, sample completeness, missing-span handling, and clock-skew disclosure |
| `deploy-diff` | Selected deploy metadata and exact before, incident, and rollback values with selected, no-diff, and reverted server variants |
| `evidence-timeline` | Semantic ordered UTC evidence from deploy through resolution, with dense and grouped server variants |
| `failure-cluster` | Ranked failure signatures with counts, shares, and non-colour rank labels, plus empty and uncertain server variants |
| `resolution-receipt` | Rollback, verification window, samples, resolved time, and separately refreshed current health, plus monitoring and rolled-back server variants |
| `ui/button` | Anchor or button in primary/secondary/ghost at three sizes, with a token state ramp for hover and press, optical padding on the icon side, a visible focus outline, and disabled and pending states that swap the whole variant rather than fading it — pending carries aria-busy on the independent info family |
| `ui/badge` | Monospace pill in neutral (tinted surface) or accent (filled amber) tone — version tags and changelog labels |
| `ui/theme-toggle` | The navbar light/dark switch: a sun or moon glyph carrying aria-pressed, writing the choice to localStorage and setting the mode class on the nearest .tt-signal wrapper or on documentElement, with a disabled state for a host that pinned the mode |
| `ui/copy-button` | Copy-to-clipboard for a command string on the library's part: a three-frame glyph swap, a counted live-region receipt so a second refusal is still announced, focus returned after the browser's permission prompt, and a blocked state that widens the control, prints the word and puts it in the accessible name. |
| `ui/container` | The content column at two declared widths: max-w-6xl marketing measure, max-w-7xl data measure |
| `ui/logo` | Wordmark: inline pulse glyph plus the lowercase monospace product name |
| `ui/code-block` | Framed code sample with filename bar and dependency-free highlighting in four token colours plus a weight role; signed numbers read as deltas and take the accent |
| `ui/terminal-window` | Terminal chrome with a brand title bar, scrollable body, optional status line, and shared Dim, Ok, Positive, and Hot roles that separate CLI syntax from verified success |
| `ui/section-heading` | Eyebrow, heading and lede at the one shared type scale |
| `ui/page-hero` | Masthead with a required counterweight in the right half: eyebrow, title, lede and meta row beside the page’s own evidence. One route uses it (/docs) — every other page opens with its own instrument |
| `ui/field` | The form family on the library's shell: a mono uppercase label, an optional marker in words, a read-only sentence, and one supporting line whose precedence runs error over success over description. The control arrives through a render prop already carrying its id, aria-invalid and aria-describedby, so Input and Textarea read the verdict rather than being told it twice. |
| `ui/inline-code` | Inline CLI strings, flags and filenames in mono on a tinted chip; never breaks a flag across a line |
| `ui/type` | The type vocabulary: the only place a font size is named, pairing every rung of the 1.200 ladder with its leading and optical tracking |
| `ui/accordion-disclosure` | A ruled disclosure on the library's part: chevron marker, 250ms height tween, and Escape from inside the panel collapsing it back onto its summary. Two surfaces — a standalone card and a row in a stack — plus the header's burger on the same skeleton. |
| `faq` | Six priced objections answered on the pricing page: what happens above the free tier, what sampling drops, self-hosting, retention, export and the absence of a contract. Built on ui/accordion-disclosure, so the answers stay in the page a crawler reads. |
| `ui/status-badge` | A domain status as glyph, word and semantic tone on a mono pill. The glyph is a required prop, so the state survives a greyscale capture. |
| `ui/alert-callout` | A bounded notice with a label, a glyph and one of five semantic tones, at two densities. role="alert" when critical, role="status" otherwise. |
| `ui/state-card` | The compact tone box every incident section renders for one of its states: a mono label, an optional glyph, one sentence, and the state name on data-state. |
| `ui/command-row` | One shell command ready to run: the prompt, the command scrolling inside its own box rather than truncating, an optional figure, and the copy control. |
| `ui/icon-chip` | The bordered box a glyph sits in, square or round, on the tinted surface or on one of the four semantic grounds. |
## Design tokens

| Token | Light | Dark override |
| --- | --- | --- |
| `--background` | `#f2f3f4` | `#0b0c0d` |
| `--foreground` | `#151719` | `#eceff1` |
| `--card` | `#ffffff` | `#151719` |
| `--card-foreground` | `#151719` | `#eceff1` |
| `--surface-sunken` | `#eceef0` | `#111315` |
| `--surface-raised` | `#ffffff` | `#1d2023` |
| `--surface-overlay` | `#ffffff` | `#282c30` |
| `--primary` | `#006470` | `#2cacbe` |
| `--primary-foreground` | `#f5feff` | `#000709` |
| `--primary-hover` | `#00525c` | `#46bfd1` |
| `--primary-active` | `#004149` | `#5dd3e5` |
| `--secondary` | `#e6e8ea` | `#1d2023` |
| `--secondary-foreground` | `#34393f` | `#cbd0d5` |
| `--muted` | `#eceef0` | `#111315` |
| `--muted-foreground` | `#596169` | `#9ba3aa` |
| `--accent` | `#7e5100` | `#eeac53` |
| `--accent-foreground` | `#fffbf6` | `#1d1102` |
| `--border` | `#c9cdd1` | `#30343a` |
| `--ring` | `#006470` | `#2cacbe` |
| `--surface-tint` | `#e1e4e7` | `#202328` |
| `--shadow-raised` | `0 18px 48px -24px #15171933` | `0 18px 48px -24px #00000066` |
| `--shadow-overlay` | `0 24px 64px -28px #1517194d` | `0 24px 64px -28px #00000080` |
| `--field` | `#ffffff` | `#111315` |
| `--field-border` | `#747b82` | `#777f87` |
| `--control-border` | `#747b82` | `#777f87` |
| `--selection` | `#dce0e3` | `#282c30` |
| `--selection-foreground` | `#151719` | `#eceff1` |
| `--selection-border` | `#747b82` | `#9aa3ab` |
| `--link` | `#005866` | `#55c4d4` |
| `--link-hover` | `#00434d` | `#75d8e5` |
| `--info` | `#135f91` | `#78b7e5` |
| `--info-foreground` | `#ffffff` | `#07131c` |
| `--info-soft` | `#e6f2fa` | `#111f2a` |
| `--info-border` | `#135f91` | `#78b7e5` |
| `--positive` | `#176b43` | `#66c391` |
| `--positive-foreground` | `#ffffff` | `#07140d` |
| `--positive-soft` | `#e4f4eb` | `#11231a` |
| `--positive-border` | `#176b43` | `#66c391` |
| `--warning` | `#7a5200` | `#f1c36b` |
| `--warning-foreground` | `#ffffff` | `#1c1202` |
| `--warning-soft` | `#f8eed7` | `#271e0e` |
| `--warning-border` | `#7a5200` | `#f1c36b` |
| `--critical` | `#9a2f37` | `#f08c8c` |
| `--critical-foreground` | `#ffffff` | `#200708` |
| `--critical-soft` | `#fbe9ea` | `#2a1517` |
| `--critical-border` | `#9a2f37` | `#f08c8c` |
| `--radius` | `0.5rem` | `0.5rem` |
| `--radius-inner` | `0.3125rem` | `0.3125rem` |
| `--weight-display` | `700` | `600` |
| `--text-caption` | `0.75rem` | `0.75rem` |
| `--leading-caption` | `1.4` | `1.4` |
| `--text-small` | `0.875rem` | `0.875rem` |
| `--leading-small` | `1.45` | `1.45` |
| `--text-body` | `1rem` | `1rem` |
| `--leading-body` | `1.55` | `1.55` |
| `--text-lead` | `1.125rem` | `1.125rem` |
| `--leading-lead` | `1.6` | `1.6` |
| `--text-d1` | `1.5rem` | `1.5rem` |
| `--leading-d1` | `1.25` | `1.25` |
| `--text-d2` | `1.8rem` | `1.8rem` |
| `--leading-d2` | `1.2` | `1.2` |
| `--text-d3` | `clamp(1.8rem, 1.651rem + 0.637vw, 2.16rem)` | `clamp(1.8rem, 1.651rem + 0.637vw, 2.16rem)` |
| `--leading-d3` | `1.15` | `1.15` |
| `--text-d4` | `clamp(2.16rem, 1.981rem + 0.764vw, 2.592rem)` | `clamp(2.16rem, 1.981rem + 0.764vw, 2.592rem)` |
| `--leading-d4` | `1.06` | `1.06` |
| `--tracking-d1` | `-0.01em` | `-0.01em` |
| `--tracking-d2` | `-0.01em` | `-0.01em` |
| `--tracking-d3` | `-0.01em` | `-0.01em` |
| `--tracking-d4` | `-0.02em` | `-0.02em` |
| `--tracking-label` | `0.08em` | `0.08em` |
| `--font-text` | `var(--font-plex-sans), ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif` | `var(--font-plex-sans), ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif` |
| `--font-sans` | `var(--font-text)` | `var(--font-text)` |
| `--font-mono` | `var(--font-plex-mono), ui-monospace, "SFMono-Regular", "SF Mono", Menlo, Consolas, "Liberation Mono", monospace` | `var(--font-plex-mono), ui-monospace, "SFMono-Regular", "SF Mono", Menlo, Consolas, "Liberation Mono", monospace` |
## Use it

- Registry: `bunx shadcn add https://tailthemes.com/r/signal.json`
- MCP: [https://tailthemes.com/api/mcp](https://tailthemes.com/api/mcp)
- Download: [https://tailthemes.com/api/download/signal](https://tailthemes.com/api/download/signal)

## Links

- Product page: [https://tailthemes.com/themes/signal](https://tailthemes.com/themes/signal)
- Live preview: [https://tailthemes.com/preview/signal](https://tailthemes.com/preview/signal)
- Docs: [https://tailthemes.com/docs/signal](https://tailthemes.com/docs/signal)
- Manifest JSON: [https://tailthemes.com/api/themes/signal](https://tailthemes.com/api/themes/signal)
- Registry item: [https://tailthemes.com/r/signal.json](https://tailthemes.com/r/signal.json)
