Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 16 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,17 @@
# Web Analytics for Umbraco
<p align="center">
<img src="https://raw.githubusercontent.com/thebuilder/web-analytics/refs/heads/main/apps/docs/public/logo-mark.svg" width="112" height="112" alt="Web Analytics logo" />
</p>

<h1 align="center">Web Analytics for Umbraco</h1>

<p align="center">
See the traffic your site sends to Vercel Web Analytics or Plausible<br />
inside the Umbraco backoffice, site-wide and per page.
</p>

[![NuGet version](https://img.shields.io/nuget/v/TheBuilder.WebAnalytics)](https://www.nuget.org/packages/TheBuilder.WebAnalytics)
[![NuGet downloads](https://img.shields.io/nuget/dt/TheBuilder.WebAnalytics)](https://www.nuget.org/packages/TheBuilder.WebAnalytics)
[![Umbraco Marketplace](https://img.shields.io/badge/Umbraco-Marketplace-3544b1)](https://marketplace.umbraco.com/package/thebuilder.webanalytics)
[![License](https://img.shields.io/github/license/thebuilder/web-analytics)](https://github.com/thebuilder/web-analytics/blob/main/LICENSE)

Read the traffic your site already sends to Vercel Web Analytics or Plausible, and report it inside the Umbraco backoffice. Editors get the site-wide numbers and the numbers for the page they are editing, without leaving Umbraco.
Expand Down Expand Up @@ -99,7 +109,7 @@ Connections are normally created through the Settings screen, but deployment aut

## Documentation

The documentation site covers everything above in more depth, plus the reporting UI and per-provider capabilities:
The [documentation site](https://web-analytics.thebuilder.dk/) covers everything above in more depth, plus the reporting UI and per-provider capabilities:

- [Quickstart](https://web-analytics.thebuilder.dk/quickstart): install, connect a provider, and verify the dashboard.
- [Understanding your reports](https://web-analytics.thebuilder.dk/guides/reports): what each metric, breakdown, and control means.
Expand All @@ -109,3 +119,7 @@ The documentation site covers everything above in more depth, plus the reporting
## Contributing

Contributions are welcome. [CONTRIBUTING.md](CONTRIBUTING.md) covers the repository layout, local development setup, and how to open a pull request. [docs/releasing.md](docs/releasing.md) covers NuGet publishing. GitHub Releases are the authoritative changelog and are mirrored in the [documentation changelog](https://web-analytics.thebuilder.dk/changelog/).

## License

MIT. See [LICENSE](LICENSE).
5 changes: 4 additions & 1 deletion apps/docs/blume.config.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { docsTheme } from "@thebuilder/umbraco-docs";
import { defineConfig } from "blume";
import { vercel } from "blume/analytics";
import { custom, filesystem } from "blume/sources";
Expand All @@ -11,7 +12,7 @@ export default defineConfig({
title: webAnalyticsPackage.name,
description: webAnalyticsPackage.summary,
logo: {
image: "/logo.png",
image: "/logo-mark.svg",
text: "Web Analytics",
},
github: {
Expand Down Expand Up @@ -46,6 +47,8 @@ export default defineConfig({
// Disable Blume's generated /og routes so it cannot overwrite them.
og: { enabled: false },
},
// The docs family's shared accent and fonts, so every package site looks alike.
theme: { ...docsTheme },
analytics: [vercel()],
agents: {
llmsTxt: true,
Expand Down
7 changes: 4 additions & 3 deletions apps/docs/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,10 @@
"check:og": "umbraco-docs-og --check"
},
"devDependencies": {
"@thebuilder/umbraco-docs": "^1.2.0",
"@types/node": "24.10.1",
"@thebuilder/umbraco-docs": "^1.5.2",
"@types/node": "24.19.2",
"blume": "2.2.3",
"sharp": "0.35.4"
"sharp": "0.35.5",
"vgpu": "0.6.0"
}
}
185 changes: 16 additions & 169 deletions apps/docs/pages/_home/home.css
Original file line number Diff line number Diff line change
Expand Up @@ -13,179 +13,23 @@
.home {
/* Echoes the logo's blue -> purple -> pink for subtle gradient accents. */
--brand-gradient: linear-gradient(105deg, #60a5fa, #a78bfa 52%, #f472b6);
overflow: clip;
/* Only sideways: the particles reach up behind the header, above this element. */
overflow-x: clip;
}

/* Avoid orphaned words and ragged wraps on every heading. */
.home :is(h1, h2, h3) {
text-wrap: pretty;
}

/* ---------- Hero ---------- */
.hero {
position: relative;
padding-top: clamp(3rem, 8vw, 6rem);
}

.hero__glow {
position: absolute;
inset: -20% -10% auto -10%;
height: 640px;
background:
radial-gradient(42% 55% at 32% 0%, color-mix(in oklab, #60a5fa 24%, transparent), transparent 72%),
radial-gradient(40% 52% at 55% 4%, color-mix(in oklab, #a78bfa 22%, transparent), transparent 72%),
radial-gradient(42% 50% at 76% 0%, color-mix(in oklab, #f472b6 16%, transparent), transparent 72%);
filter: blur(10px);
pointer-events: none;
z-index: 0;
}

.hero__mark {
width: 72px;
height: 72px;
margin-bottom: 0.5rem;
filter: drop-shadow(0 10px 28px color-mix(in oklab, #8b5cf6 40%, transparent));
}

.hero__inner {
position: relative;
z-index: 1;
display: flex;
flex-direction: column;
align-items: center;
text-align: center;
gap: 1.5rem;
}

.hero__compat {
margin: 0;
font-size: 0.85rem;
color: var(--blume-muted-foreground);
}

.hero__title {
font-family: var(--blume-font-display);
font-weight: 700;
letter-spacing: -0.02em;
line-height: 1.05;
font-size: clamp(2.4rem, 6vw, 4rem);
max-width: 18ch;
margin: 0;
}
.hero__accent {
background: var(--brand-gradient);
-webkit-background-clip: text;
background-clip: text;
color: transparent;
}

.hero__lede {
max-width: 44rem;
margin: 0;
font-size: clamp(1.05rem, 1.6vw, 1.25rem);
line-height: 1.65;
color: var(--blume-muted-foreground);
}

.hero__actions {
display: flex;
flex-wrap: wrap;
gap: 0.75rem;
justify-content: center;
}

/* ---------- Buttons ---------- */
.btn {
display: inline-flex;
align-items: center;
gap: 0.5rem;
padding: 0.7rem 1.25rem;
border-radius: var(--blume-radius);
font-size: 0.95rem;
font-weight: 600;
text-decoration: none;
border: 1px solid transparent;
transition: transform 0.12s ease, background 0.15s ease, border-color 0.15s ease, color 0.15s ease, box-shadow 0.25s ease;
}
.btn:active { transform: translateY(1px); }
.btn--primary {
position: relative;
isolation: isolate;
background: var(--blume-accent);
color: var(--blume-accent-foreground);
}
/* Fade the brand gradient in on hover for a smooth solid -> gradient reveal. */
.btn--primary::before {
content: "";
position: absolute;
/* Bleed over the 1px transparent border so the gradient reaches the edge and
the solid-blue background does not show as a ring on hover. */
inset: -1px;
z-index: -1;
border-radius: inherit;
/* Deeper, less saturated than the headline gradient so the CTA reads rich,
not neon. */
background: linear-gradient(102deg, #3576e0, #6a55d8 56%, #a65189);
opacity: 0;
transition: opacity 0.25s ease;
}
.btn--primary:hover::before {
opacity: 1;
}
.btn--primary:hover {
box-shadow: 0 6px 16px color-mix(in oklab, #6a55d8 26%, transparent);
}
.btn--ghost {
color: var(--blume-foreground);
border-color: var(--blume-border);
background: color-mix(in oklab, var(--blume-muted) 40%, transparent);
}
.btn--ghost:hover {
border-color: color-mix(in oklab, var(--blume-accent) 45%, var(--blume-border));
background: color-mix(in oklab, var(--blume-muted) 75%, transparent);
}
.btn--on-panel {
background: color-mix(in oklab, var(--blume-background) 12%, transparent);
border-color: color-mix(in oklab, var(--blume-foreground) 18%, transparent);
}

/* ---------- Install command ---------- */
.install {
display: inline-flex;
align-items: center;
gap: 0.75rem;
padding: 0.55rem 0.6rem 0.55rem 1rem;
border-radius: var(--blume-radius);
border: 1px solid var(--blume-border);
background: var(--blume-code-background);
color: var(--blume-foreground);
font-family: var(--blume-font-mono);
font-size: 0.9rem;
max-width: 100%;
}
.install__prompt { color: var(--blume-muted-foreground); user-select: none; }
.install__code {
color: var(--blume-foreground);
white-space: nowrap;
overflow-x: auto;
}
.install__copy {
display: inline-grid;
place-items: center;
width: 2rem;
height: 2rem;
border-radius: calc(var(--blume-radius) * 0.75);
border: 1px solid transparent;
background: transparent;
color: var(--blume-muted-foreground);
cursor: pointer;
transition: background 0.15s ease, color 0.15s ease;
}
.install__copy:hover { background: color-mix(in oklab, var(--blume-foreground) 8%, transparent); color: var(--blume-foreground); }
.install__icon { grid-area: 1 / 1; }
.install__icon--done { opacity: 0; transform: scale(0.6); transition: opacity 0.15s ease, transform 0.15s ease; }
.install__copy.is-copied .install__icon--copy { opacity: 0; }
.install__copy.is-copied .install__icon--done { opacity: 1; transform: scale(1); color: var(--blume-accent); }
.home .button { display: inline-flex; min-height: 2.75rem; align-items: center; justify-content: center; padding-inline: 1.25rem; border: 1px solid var(--blume-border); border-radius: var(--blume-radius); color: var(--blume-foreground); font-weight: 600; text-decoration: none; }
.home .button:hover { border-color: var(--blume-accent); }
/* Frosted over the hero particles; the shared styles blur what's behind it. */
.home .button--secondary { border-color: color-mix(in oklab, var(--blume-foreground) 18%, transparent); background: color-mix(in oklab, var(--blume-background) 55%, transparent); }
/* Blume picks the label color that meets AA on the accent: white in light mode, dark in dark mode. */
.home .button--primary { border-color: var(--blume-accent); background: var(--blume-accent); color: var(--blume-accent-foreground); box-shadow: 0 .625rem 1.9rem color-mix(in oklab, var(--blume-accent) 23%, transparent); }
.home .button--primary:hover { background: color-mix(in oklab, var(--blume-accent) 88%, black); color: var(--blume-accent-foreground); }

/* ---------- Screenshot frame ---------- */
.shot {
Expand Down Expand Up @@ -406,7 +250,13 @@
font-size: 1.05rem;
line-height: 1.6;
}
.cta .hero__actions { position: relative; }
.cta__actions {
position: relative;
display: flex;
flex-wrap: wrap;
gap: 0.75rem;
justify-content: center;
}

/* ---------- Footer ---------- */
.home-footer {
Expand Down Expand Up @@ -440,12 +290,9 @@
.features { grid-template-columns: repeat(2, 1fr); }
.split, .steps-grid { grid-template-columns: 1fr; }
.split__copy { text-align: center; }
.split__copy .btn { margin-inline: auto; }
}
@media (max-width: 620px) {
.providers, .features { grid-template-columns: 1fr; }
.install { width: 100%; }
.btn { flex: 1 1 auto; justify-content: center; }
}

/* ---------- Reveal animation (opt-in via JS, motion-safe) ---------- */
Expand Down
Loading
Loading