feat: strengthen design skill and refresh all showcases
Some checks failed
ci / build (push) Has been cancelled

This commit is contained in:
Yun Chan 2026-09-12 18:16:33 +09:00
parent 69e5cc1efd
commit e09d4efb1c
257 changed files with 8196 additions and 2374 deletions

View file

@ -3,15 +3,15 @@
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Pulsegate · Edge Latency &amp; Synthetic Probe Engine</title>
<title>Pulsegate · Edge Monitoring Workflow</title>
<meta
name="description"
content="Synthetic HTTP/gRPC assertions every ten seconds from bare-metal edge POPs. No agents, no sidecars. Prometheus and OpenTelemetry export."
content="An illustrative workflow for checking an endpoint from distributed edge locations. It does not create probes or provide a live service."
/>
<meta property="og:title" content="Pulsegate · Edge Latency &amp; Synthetic Probe Engine" />
<meta property="og:title" content="Pulsegate · Edge Monitoring Workflow" />
<meta
property="og:description"
content="Synthetic assertions from 28 bare-metal edge POPs. A probe is watching within 90 seconds."
content="An illustrative edge-monitoring flow with endpoints, locations, and reporting fields."
/>
<meta property="og:type" content="website" />
<meta name="theme-color" content="#0B0E12" />
@ -22,7 +22,7 @@
rel="stylesheet"
href="https://fonts.googleapis.com/css2?family=IBM+Plex+Sans:wght@400;500;600&family=IBM+Plex+Sans+KR:wght@400;500;600&family=JetBrains+Mono:wght@400;500&display=swap"
/>
<link rel="stylesheet" href="./styles/main.css?v=2" />
<link rel="stylesheet" href="./styles/main.css?v=20260912all" />
<link
rel="icon"
href="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32'%3E%3Crect width='32' height='32' fill='%230B0E12'/%3E%3Cpath d='M6 17h6l3-8 4 14 3-6h4' fill='none' stroke='%236CA3EE' stroke-width='2'/%3E%3C/svg%3E"
@ -44,49 +44,57 @@
</header>
<main id="main">
<!--
Hero. Grayscale hierarchy per research: h1 (1) → primary CTA (2) → command (3).
Cobalt exists only as text and chart ink — never as a fill or a glow.
The instrument on the right is a static frame: no pulsing dots, no live pretence.
-->
<section class="hero" aria-labelledby="hero-h">
<div class="wrap hero-grid">
<div class="hero-text">
<h1 id="hero-h" class="reveal">
A probe is watching<br />within 90&nbsp;seconds
Understand an edge<br />check at a glance
</h1>
<p class="lead reveal" style="--delay: 80ms">
Synthetic HTTP and gRPC assertions, executed every ten seconds from
bare-metal POPs in 28 transit centers. No agents on your fleet, no
sidecars to babysit — the first probe is running before you finish
reading this page.
This page illustrates how one endpoint can be checked from several
edge locations and reported with the same fields. Locations,
timings, plans, and results are examples; no probe runs from this page.
</p>
<dl class="probe-proof reveal" style="--delay: 110ms">
<div>
<dt>example endpoint</dt>
<dd><code>GET /health</code></dd>
</div>
<div>
<dt>example origin</dt>
<dd>Seoul</dd>
</div>
<div>
<dt>example cadence</dt>
<dd>10 s · 28 locations</dd>
</div>
</dl>
<div class="hero-actions reveal" style="--delay: 140ms">
<a class="btn btn-primary" href="#pricing">Start with 3 free probes</a>
<a class="link-quiet" href="#wiring">See how it is wired</a>
<a class="btn btn-primary" href="#pricing">View example plans</a>
<a class="link-quiet" href="#wiring">See the check flow</a>
</div>
<div class="command reveal" style="--delay: 200ms">
<span class="command-prompt" aria-hidden="true">$</span>
<code>curl -sL https://pulsegate.io/init | sh</code>
<div class="workflow-command">
<div class="command reveal" style="--delay: 200ms">
<span class="command-prompt" aria-hidden="true">$</span>
<code>GET /health → inspect the response</code>
</div>
<p class="hero-note reveal" style="--delay: 240ms">
Illustrative workflow only — this page does not create an account,
run a check, or collect a destination URL.
</p>
</div>
<p class="hero-note reveal" style="--delay: 240ms">
90 seconds: measured from <code>init</code> to first assertion on a
cold account, 2026-08-20.
</p>
</div>
<!-- Instrument: static 24h frame. Cobalt = one series only. -->
<figure class="instrument reveal" style="--delay: 160ms">
<figcaption class="instrument-head">
<span>EDGE LATENCY · P99 · LAST 24H</span>
<span>10s interval</span>
<span>ILLUSTRATIVE LATENCY FRAME · P99 · 24H</span>
<span>example 10s interval</span>
</figcaption>
<svg
viewBox="0 0 560 264"
role="img"
aria-label="24-hour p99 latency chart. Seoul stays under 16 ms, Tokyo under 34 ms, Frankfurt sits near 140 ms with one spike to 210 ms at 06:40 UTC."
aria-label="Illustrative 24-hour p99 latency chart with example locations and timings; it is not live monitoring data."
>
<!-- hour grid -->
<g class="chart-grid">
<line x1="0" y1="8" x2="560" y2="8" />
<line x1="0" y1="70" x2="560" y2="70" />
@ -101,23 +109,20 @@
<line x1="420" y1="0" x2="420" y2="264" />
<line x1="490" y1="0" x2="490" y2="264" />
</g>
<!-- series: FRA (faint, high) — 140ms band with 06:40 spike -->
<polyline
class="series series-faint"
points="0,96 35,94 70,97 105,92 140,95 175,93 205,88 210,74 215,60 220,74 225,90 260,95 280,93 315,96 350,94 385,97 420,93 455,96 490,94 525,97 560,95"
/>
<!-- series: NRT (muted, low-mid) -->
<polyline
class="series series-muted"
points="0,224 35,222 70,225 105,221 140,224 175,223 210,226 245,222 280,224 315,223 350,226 385,222 420,225 455,223 490,226 525,223 560,225"
/>
<!-- series: ICN (cobalt, lowest) -->
<polyline
class="series series-accent"
points="0,243 35,242 70,244 105,242 140,243 175,244 210,242 245,243 280,244 315,242 350,243 385,244 420,243 455,242 490,244 525,243 560,243"
/>
</svg>
<div class="instrument-rows" role="group" aria-label="POP readings, p99 over 24 hours">
<div class="instrument-rows" role="group" aria-label="Illustrative location readings, p99 over one example frame">
<div><span>ICN-01 · Seoul</span><span class="num">14.2 ms</span></div>
<div><span>NRT-02 · Tokyo</span><span class="num">28.6 ms</span></div>
<div><span>SIN-01 · Singapore</span><span class="num">34.0 ms</span></div>
@ -129,30 +134,22 @@
</div>
</section>
<!--
Wiring — the one scroll-motion detail (R3): a circuit trace that draws
itself as it enters the viewport. CSS animation-timeline, Chromium-gated;
every other browser (and reduced-motion) gets the fully drawn diagram.
Structure is the argument: probes → assertions → your telemetry.
-->
<section id="wiring" class="section" aria-labelledby="wiring-h">
<div class="wrap">
<h2 id="wiring-h" class="reveal">How it is wired</h2>
<h2 id="wiring-h" class="reveal">How an edge check is mapped</h2>
<p class="lead reveal" style="--delay: 80ms">
Probes run from physical tier-1 transit facilities, not shared cloud
VPCs, so what you measure is the network your users ride — not cloud
peering bias. One trace, three stations.
The diagram separates an endpoint, distributed checking locations,
and the metrics returned to a monitoring system. It is a conceptual
route, not a map of operating facilities.
</p>
</div>
<div class="wrap wiring-diagram reveal" style="--delay: 120ms">
<svg viewBox="0 0 1120 220" role="img" aria-label="Wiring diagram: 28 POPs run assertions, the engine evaluates them, results export to Prometheus and OpenTelemetry.">
<!-- drawn trace: POPs → engine → export -->
<svg viewBox="0 0 1120 220" role="img" aria-label="Illustrative workflow diagram: locations check an endpoint, an engine evaluates responses, and fields flow to a monitoring system.">
<path
class="trace"
d="M 40 60 H 300 M 40 110 H 300 M 40 160 H 300 M 300 110 H 470 M 650 110 H 820 M 820 60 V 160 M 820 60 H 1010 M 820 160 H 1010"
/>
<!-- station 1: POPs -->
<g class="station">
<rect x="40" y="44" width="14" height="14" />
<rect x="40" y="94" width="14" height="14" />
@ -161,20 +158,17 @@
<text x="66" y="105">FRA · LHR · AMS …</text>
<text x="66" y="155">SJC · IAD · ORD …</text>
</g>
<!-- station 2: engine -->
<g class="station">
<rect x="470" y="88" width="180" height="44" />
<text x="478" y="106">assertion engine</text>
<text x="478" y="124" class="mono-note">http · grpc · tcp · dns</text>
</g>
<!-- station 3: export -->
<g class="station">
<rect x="1010" y="46" width="70" height="26" />
<rect x="1010" y="146" width="70" height="26" />
<text x="1006" y="38" text-anchor="end">Prometheus</text>
<text x="1006" y="192" text-anchor="end">OpenTelemetry</text>
</g>
<!-- flow labels -->
<g class="flow-label">
<text x="310" y="100">every 10 s</text>
<text x="660" y="100">p50 · p99 · jitter</text>
@ -184,44 +178,40 @@
<div class="wrap wiring-notes">
<div class="wiring-note reveal">
<h3>Bare-metal, not lambdas</h3>
<h3>Check from the edge</h3>
<p>
Probes live in tier-1 transit facilities. The RTT you see is the
RTT your users get.
A useful check identifies where it ran and which part of the
response was measured, so results can be compared fairly.
</p>
</div>
<div class="wiring-note reveal" style="--delay: 80ms">
<h3>Assertions, not pings</h3>
<h3>Check the response, not only reachability</h3>
<p>
JSONPath body checks, gRPC status codes, TLS certificate expiry —
a check fails when your product fails, not when a packet does.
A useful workflow can compare response content, status, certificate
expiry, and timing instead of treating a reachable address as success.
</p>
</div>
<div class="wiring-note reveal" style="--delay: 160ms">
<h3>Your telemetry, your tools</h3>
<h3>Keep the reporting fields consistent</h3>
<p>
Export to the Prometheus and OpenTelemetry you already run. No
dashboard to live in, no lock-in to migrate off.
The example keeps endpoint, location, time, and response fields
together so they can be handed to an existing monitoring workflow.
</p>
</div>
</div>
</section>
<!--
Numbers — the trust band. Every value carries its measurement condition.
No invented scale claims: these are the engine's own telemetry frame.
-->
<section id="numbers" class="section band" aria-labelledby="numbers-h">
<div class="wrap">
<h2 id="numbers-h" class="reveal">One frame, all 28 POPs</h2>
<h2 id="numbers-h" class="reveal">One example frame, many locations</h2>
<p class="lead reveal" style="--delay: 80ms">
A single assertion — <code>GET /health</code> against a Seoul origin —
fanned out to every POP at the same instant.
This table shows how an endpoint, DNS, TLS, response time, and a
percentile can be read together. Its values and locations are illustrative.
</p>
<div class="table-wrap reveal" style="--delay: 120ms">
<table>
<caption class="sr-only">
Per-POP readings for one assertion: DNS, TLS, TTFB and p99 over 24 hours
Illustrative location readings: DNS, TLS, TTFB, and p99 over one example frame
</caption>
<thead>
<tr>
@ -240,50 +230,45 @@
<tr><th scope="row">SJC-04</th><td>San Jose</td><td class="num">3.0</td><td class="num">9.6</td><td class="num">88.4</td><td class="num">94.7</td></tr>
<tr><th scope="row">LHR-02</th><td>London</td><td class="num">4.0</td><td class="num">11.2</td><td class="num">126.8</td><td class="num">133.0</td></tr>
<tr><th scope="row">FRA-01</th><td>Frankfurt</td><td class="num">4.2</td><td class="num">11.8</td><td class="num">142.1</td><td class="num">151.8</td></tr>
<tr class="row-more"><td colspan="6">…22 more POPs in the console — same frame, same instant</td></tr>
<tr class="row-more"><td colspan="6">…22 more illustrative locations in the same example frame</td></tr>
</tbody>
</table>
</div>
<p class="measure-note reveal" style="--delay: 160ms">
Measured 2026-08-20 14:00 UTC · 10 s interval · n = 8,640 per POP ·
milliseconds, median of the hour shown for DNS/TLS/TTFB.
Illustrative 24-hour frame · 10 s example interval · milliseconds shown
for DNS, TLS, TTFB, and p99.
</p>
</div>
</section>
<!--
Pricing — two quiet rows, not three columns with a badge.
(research: the 3-column + "most popular" template is the highest-recurrence
slop pattern in this category — we don't run it)
-->
<section id="pricing" class="section" aria-labelledby="pricing-h">
<div class="wrap pricing-grid">
<div class="pricing-text">
<h2 id="pricing-h" class="reveal">Priced per probe,<br />not per seat</h2>
<h2 id="pricing-h" class="reveal">Example plan structure</h2>
<p class="lead reveal" style="--delay: 80ms">
A probe costs the same whether three engineers or thirty look at
the console. Downgrade, pause, or delete from the CLI.
These rows show how interval, retention, and export options can be
compared. They are not offers, prices, or an account signup flow.
</p>
</div>
<div class="pricing-rows reveal" style="--delay: 120ms">
<div class="price-row">
<div>
<h3>Free</h3>
<h3>Example Free</h3>
<p>3 probes · 60 s interval · 7-day retention</p>
</div>
<div class="price-val">
<span>$0</span>
<a class="btn btn-primary" href="#main">Create account</a>
<span>Example $0</span>
<a class="btn btn-primary" href="#pricing">View the example</a>
</div>
</div>
<div class="price-row">
<div>
<h3>Pro</h3>
<h3>Example Pro</h3>
<p>Unlimited probes · 10 s interval · 13-month retention · OTel export</p>
</div>
<div class="price-val">
<span>$0.40 <em>per probe-month</em></span>
<a class="link-quiet" href="#main">Start free, upgrade inside</a>
<span>Example $0.40 <em>per probe-month</em></span>
<a class="link-quiet" href="#pricing">Example only</a>
</div>
</div>
</div>
@ -293,14 +278,12 @@
<footer class="site-foot">
<div class="wrap foot-inner">
<p>pulsegate — distributed edge telemetry</p>
<p class="foot-meta">status: 28/28 POPs reporting · exporter protocol v2.4</p>
<p>pulsegate — illustrative edge-monitoring workflow</p>
<p class="foot-meta">no live probes, accounts, prices, or operating locations</p>
</div>
</footer>
<script>
/* Reveal only — same grammar as the rest of the studio's work.
No scroll listeners, no fake "live" loops: a static frame is honest. */
const io = new IntersectionObserver(
(entries) => {
for (const e of entries) {