diff --git a/site/src/components/Analytics.astro b/site/src/components/Analytics.astro index 41cd153..71f6cbd 100644 --- a/site/src/components/Analytics.astro +++ b/site/src/components/Analytics.astro @@ -97,6 +97,16 @@ const enabled = Boolean(measurementId) && import.meta.env.PROD; }); }); + // The copy button writes through the Clipboard API, which raises no + // copy event. It announces itself instead, so both paths are counted + // the same way. + document.addEventListener("fanout:copy", function (event) { + gtag("event", "copy_command", { + action: event.detail || "unknown", + location: "closing_cta", + }); + }); + var tag = document.createElement("script"); tag.async = true; tag.src = "https://www.googletagmanager.com/gtag/js?id=" + encodeURIComponent(measurementId); diff --git a/site/src/components/landing/Benchmark.astro b/site/src/components/landing/Benchmark.astro index be1514b..e5f2d44 100644 --- a/site/src/components/landing/Benchmark.astro +++ b/site/src/components/landing/Benchmark.astro @@ -21,7 +21,7 @@ const signals = [ const gates = ["server drops 0", "no restarts", "Parquet verified"]; --- -
+
Publication candidate @@ -143,8 +143,8 @@ const gates = ["server drops 0", "no restarts", "Parquet verified"]; + + diff --git a/site/src/components/landing/Hero.astro b/site/src/components/landing/Hero.astro index 9b31eb7..e58c671 100644 --- a/site/src/components/landing/Hero.astro +++ b/site/src/components/landing/Hero.astro @@ -65,16 +65,16 @@ const { title = data.title, tagline, actions = [] } = data.hero ?? {};
@@ -273,7 +273,7 @@ const { title = data.title, tagline, actions = [] } = data.hero ?? {}; } .fo-scope-at { - color: #f26d78; + color: var(--fo-status-bad); } .fo-scope-readout { @@ -320,7 +320,7 @@ const { title = data.title, tagline, actions = [] } = data.hero ?? {}; } .fo-up { - color: #f26d78 !important; + color: var(--fo-status-bad) !important; } /* The question, in the words a person would use. Set as a quotation rather @@ -346,7 +346,7 @@ const { title = data.title, tagline, actions = [] } = data.hero ?? {}; } .fo-scope-found :global(svg) { - color: #7fd962; + color: var(--fo-status-ok); margin-top: 0.15rem; } diff --git a/site/src/components/landing/Preview.astro b/site/src/components/landing/Preview.astro index 0130de2..e3c45de 100644 --- a/site/src/components/landing/Preview.astro +++ b/site/src/components/landing/Preview.astro @@ -30,7 +30,7 @@ const state = { ok: "healthy", warn: "degraded", bad: "unhealthy" }; const spark = "M0,30 L12,26 L24,28 L36,20 L48,24 L60,16 L72,19 L84,12 L96,15 L108,9 L120,13 L132,22 L144,31 L156,27 L168,18 L180,13 L192,9 L200,7"; --- -
+
demo.fanout.run · Overview @@ -69,6 +69,7 @@ const spark = "M0,30 L12,26 L24,28 L36,20 L48,24 L60,16 L72,19 L84,12 L96,15 L10
+

5 of 47 services · worst first

@@ -161,6 +162,34 @@ const spark = "M0,30 L12,26 L24,28 L36,20 L48,24 L60,16 L72,19 L84,12 L96,15 L10 background: var(--sl-color-gray-6); } + /* Closes the left pane. Without it the table stopped halfway down a panel + whose neighbour runs to the bottom, which read as a rendering fault rather + than as a short list. The count agrees with the Services tile beside it. */ + .fo-panel-foot { + margin: 1.1rem 0 0; + padding-top: 0.8rem; + border-top: 1px solid var(--sl-color-hairline-shade); + font-family: var(--fo-font-display); + font-size: 0.66rem; + letter-spacing: 0.06em; + color: var(--sl-color-gray-4); + } + + .fo-panel { + display: flex; + flex-direction: column; + } + + .fo-panel .table-wrap { + flex: 1; + } + + /* The scroll wrapper is a documentation-content affordance and carries that + stylesheet's top margin; inside a panel the heading already sets the gap. */ + .fo-panel .table-wrap { + margin-top: 0; + } + .fo-panel h3 { font-family: var(--fo-font-display); font-size: 0.66rem; @@ -203,13 +232,24 @@ const spark = "M0,30 L12,26 L24,28 L36,20 L48,24 L60,16 L72,19 L84,12 L96,15 L10 color: var(--sl-color-white); } + /* Right-aligned, and the last column loses its trailing padding: with every + column left-aligned the table's slack collected in the final cell, so the + numbers huddled against the service names with an empty half-pane beside + them. Aligning on the right also lets the figures compare down a column. */ + .fo-panel th:nth-child(n + 3), .fo-num { + text-align: right; font-variant-numeric: tabular-nums; } + .fo-panel th:last-child, + .fo-panel td:last-child { + padding-inline-end: 0; + } + .fo-delta { margin-inline-start: 0.4rem; - color: #f26d78; + color: var(--fo-status-bad); } /* The three status hues are the palette's load-bearing ones: they mean the @@ -226,9 +266,9 @@ const spark = "M0,30 L12,26 L24,28 L36,20 L48,24 L60,16 L72,19 L84,12 L96,15 L10 border-radius: 50%; } - .fo-ok i { background: #7fd962; } - .fo-warn i { background: #ffb454; } - .fo-bad i { background: #f26d78; } + .fo-ok i { background: var(--fo-status-ok); } + .fo-warn i { background: var(--fo-status-warn); } + .fo-bad i { background: var(--fo-status-bad); } .fo-kpis { display: grid; @@ -262,7 +302,7 @@ const spark = "M0,30 L12,26 L24,28 L36,20 L48,24 L60,16 L72,19 L84,12 L96,15 L10 font-variant-numeric: tabular-nums; } - .fo-hot { color: #f26d78 !important; } + .fo-hot { color: var(--fo-status-bad) !important; } .fo-kpi em { font-family: var(--fo-font-body); diff --git a/site/src/components/landing/Section.astro b/site/src/components/landing/Section.astro index 2c4d58c..e152755 100644 --- a/site/src/components/landing/Section.astro +++ b/site/src/components/landing/Section.astro @@ -64,7 +64,12 @@ const { eyebrow } = Astro.props; overflow-wrap: normal; } - .fo-sec :global(p) { + /* Direct children only. As a descendant rule this reached every paragraph + inside the slotted components too, overriding their own margins and type + because a class-plus-element selector outranks the single class they style + themselves with — which is why components had started defending themselves + with doubled selectors and an id. */ + .fo-sec > :global(p:not(.fo-eyebrow)) { font-family: var(--fo-font-body); font-size: 1rem; line-height: 1.7; diff --git a/site/src/content/docs/index.mdx b/site/src/content/docs/index.mdx index fd6be0d..920dd3c 100644 --- a/site/src/content/docs/index.mdx +++ b/site/src/content/docs/index.mdx @@ -72,28 +72,6 @@ disagree.
-
- -## Nearly 300,000 OpenTelemetry items a second. One binary. - -In a five-minute publication-candidate run, Fanout accepted **296,196 spans, -log records and metric data points per second** on a machine with eight logical -CPUs and 15.6 GiB of memory. -Fanout reported zero dropped rows, the process did not restart, and the -resulting Parquet store passed verification. The load generators shared the -machine, so this is an observed whole-host result—not an isolated -storage-engine ceiling. - - - -It is labeled a candidate because it is a single run: the published headline -waits on a clean harness repeating it three times. -[Read the methodology and every qualification](/explanation/performance), or -[run the same open-source harness](https://github.com/labstack/fanout-bench) on -your own host. - -
-
## Five services, or one process. @@ -124,6 +102,28 @@ it to answer. The data directory it writes is the whole of its state.
+
+ +## Nearly 300,000 OpenTelemetry items a second. One binary. + +In a five-minute publication-candidate run, Fanout accepted **296,196 spans, +log records and metric data points per second** on a machine with eight logical +CPUs and 15.6 GiB of memory. +Fanout reported zero dropped rows, the process did not restart, and the +resulting Parquet store passed verification. The load generators shared the +machine, so this is an observed whole-host result—not an isolated +storage-engine ceiling. + + + +It is labeled a candidate because it is a single run: the published headline +waits on a clean harness repeating it three times. +[Read the methodology and every qualification](/explanation/performance), or +[run the same open-source harness](https://github.com/labstack/fanout-bench) on +your own host. + +
+
## What Fanout will not do. diff --git a/site/src/styles/fanout.css b/site/src/styles/fanout.css index 47890e3..cb9070e 100644 --- a/site/src/styles/fanout.css +++ b/site/src/styles/fanout.css @@ -65,6 +65,15 @@ --sl-color-gray-5: #1d2433; --sl-color-gray-6: #131721; --sl-color-black: #0b0e14; + + /* Healthy, degraded, unhealthy. These three are load-bearing: they mean the + same thing on this site as they do inside the product, and three landing + components were each carrying their own copy of the hex. Tokens because + the dark values wash out on a light background — the pale green and coral + that read clearly on Ayu surfaces fall under 4.5:1 on white. */ + --fo-status-ok: #7fd962; + --fo-status-warn: #ffb454; + --fo-status-bad: #f26d78; } :root[data-theme="light"] { @@ -78,6 +87,9 @@ --sl-color-gray-4: #a4abb4; --sl-color-gray-5: #d6d9dd; --sl-color-gray-6: #eceef0; + --fo-status-ok: #3c7a2a; + --fo-status-warn: #9a5b00; + --fo-status-bad: #b3352c; --sl-color-gray-7: #f3f4f5; --sl-color-black: #fcfcfc; } @@ -312,5 +324,8 @@ h1#_top { --sl-color-gray-6: #eceef0; --sl-color-gray-7: #f3f4f5; --sl-color-black: #ffffff; + --fo-status-ok: #3c7a2a; + --fo-status-warn: #9a5b00; + --fo-status-bad: #b3352c; } }