Skip to content

Commit e76b632

Browse files
platform: a page that sells it, a one-minute tour and a waiting list (#78)
The header and the hero now lead to /platform. The page is rewritten against the libredb-platform README: six roles, one organisation per install, Keycloak single sign-on, sealed credentials, per-person grants and the query audit log, with the limits stated next to them. Platform is no longer called a beta anywhere; the licence is free for 1 admin and 3 users for 12 months and paid beyond that. The tour plays from YouTube, but only after the visitor presses play: the page shows our own poster and makes no request to Google until then. The privacy policy promises that a visitor who declines cookies loads nothing from Google, and it now says the same about the player. The waiting list is a form that composes an email to info@libredb.org in the visitor's own mail app. Production is GitHub Pages and cannot take a form post; a form relay would put visitors' details through a processor the privacy policy does not name. The policy now says what happens to those emails.
1 parent 84858b6 commit e76b632

11 files changed

Lines changed: 621 additions & 70 deletions

File tree

‎package.json‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "libredb-website",
3-
"version": "1.4.0",
3+
"version": "1.5.0",
44
"private": true,
55
"type": "module",
66
"description": "libredb.org — marketing website for LibreDB Studio (Astro static + Outstatic CMS)",
115 KB
Loading

‎src/components/home/Hero.astro‎

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,12 @@ const DEMO_MOBILE = '/demo/libredb-studio-demo-mobile.html';
6767
<CopyBox command={hero.command} label="Copy the docker run command" />
6868
<p class="hero__note">{hero.commandNote}</p>
6969
</div>
70+
71+
<a class="hero__platform" href={hero.platformCta.href}>
72+
<span class="hero__platform-tag">{hero.platformCta.tag}</span>
73+
<span>{hero.platformCta.label}</span>
74+
<span class="hero__arrow" aria-hidden="true">→</span>
75+
</a>
7076
</div>
7177
</div>
7278

@@ -274,6 +280,42 @@ const DEMO_MOBILE = '/demo/libredb-studio-demo-mobile.html';
274280
color: var(--text-tertiary);
275281
}
276282

283+
.hero__platform {
284+
margin-top: var(--space-06);
285+
display: inline-flex;
286+
align-items: center;
287+
gap: var(--space-04);
288+
/* the same 48px and 15px as the hero's two buttons, so it reads as a third
289+
button rather than a caption under the install line */
290+
min-height: 48px;
291+
padding: 0 22px 0 8px;
292+
border: var(--border-width-1) solid var(--border-strong);
293+
border-radius: var(--radius-pill);
294+
background: var(--surface);
295+
font: var(--weight-medium) 15px / 1 var(--font-ui);
296+
color: var(--text-primary);
297+
text-align: left;
298+
animation: lbWord 0.7s var(--ease-out) 1.18s both;
299+
transition: background var(--duration-fast) var(--ease-out);
300+
}
301+
.hero__platform:hover {
302+
background: var(--surface-hover);
303+
color: var(--text-primary);
304+
}
305+
.hero__platform:hover .hero__arrow {
306+
transform: translateX(4px);
307+
}
308+
.hero__platform-tag {
309+
flex: none;
310+
padding: 8px 12px;
311+
border-radius: var(--radius-pill);
312+
background: var(--action-primary);
313+
font: var(--weight-semibold) 12px / 1 var(--font-mono);
314+
letter-spacing: 0.06em;
315+
text-transform: uppercase;
316+
color: #fff;
317+
}
318+
277319
.hero__demo {
278320
position: relative;
279321
max-width: 1440px;

‎src/data/home.ts‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ export const navLinks = [
1313
{ href: '#product', label: 'Product' },
1414
{ href: '#open-source', label: 'Open source' },
1515
{ href: '#deploy', label: 'Deploy' },
16+
{ href: '/platform/', label: 'Platform' },
1617
] as const;
1718

1819
/* --- hero ----------------------------------------------------------------- */
@@ -28,6 +29,8 @@ export const hero = {
2829
secondaryCta: { label: 'Deploy in one click', href: '#deploy' },
2930
command: 'docker run -p 3000:3000 libredb/libredb-studio',
3031
commandNote: 'or npx @libredb/studio — no Docker needed. Running in about ten seconds.',
32+
/** The one door from the homepage to the governed product, under the install line. */
33+
platformCta: { tag: 'Platform', label: 'Governed access for teams', href: '/platform/' },
3134
frameAddress: 'studio.internal — live product tour',
3235
} as const;
3336

‎src/data/platform.ts‎

Lines changed: 115 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,46 +1,85 @@
11
/**
22
* LibreDB Platform — the governed form of Studio, and the only thing on this
3-
* site that is intended to cost money one day.
3+
* site that costs money: free up to 1 admin and 3 users, paid beyond that.
44
*
55
* Why this page exists: without it the site never says that a paid product
66
* exists, which leaves the open-core story with a hole in it. "Studio is free
77
* and always will be" is a much weaker sentence when a visitor cannot see what
88
* is NOT free, because the obvious next thought is that the catch is hidden
99
* somewhere.
1010
*
11-
* STATUS DISCIPLINE. The previous site badged this "Live · beta" and linked to
11+
* STATUS DISCIPLINE. The previous site badged this "Live" and linked to
1212
* https://platform.libredb.org. That host does not serve: DNS resolves to a
1313
* live server, but the TLS handshake is answered with an internal-error alert
1414
* and no certificate for the name, and plain HTTP returns 404 — the reverse
1515
* proxy has no vhost for it. So this page:
1616
*
17-
* - does NOT call the product live,
1817
* - does NOT link to platform.libredb.org,
19-
* - routes interest to the vendor's address instead.
18+
* - routes interest to the waiting list, which is an email to `contact.email`.
2019
*
2120
* Restore the link in the same change that makes the host serve, and not
2221
* before. A dead link on the page that names the eventual paid product is the
2322
* most expensive dead link on the site.
2423
*
25-
* PRICE DISCIPLINE (2026-09-01). The beta is issued at NO CHARGE, and every
26-
* surface here must say so in the same breath as the word "licence". This page
27-
* once carried three sentences of sales vocabulary — "no online checkout yet",
28-
* "a licence is arranged directly", "plan tiers" — around a motion that does
29-
* not exist, while the tiers row underneath said "not for sale yet". Nothing
30-
* was untrue on its own; together they contradicted each other, and a reviewer
31-
* who opens this page is exactly who notices. If a price ever appears, change
32-
* ALL of these together: this file, the "Getting it" lead in platform.astro,
33-
* and the Licence section of llms.txt.ts.
24+
* PRICE DISCIPLINE (2026-10-19). Platform is a released product, not a beta —
25+
* do not call it one anywhere. The free licence covers 1 admin seat and 3 user
26+
* seats for 12 months; more seats are paid, priced on request. Every surface
27+
* that names the free licence must name the paid line in the same breath. If
28+
* the offer changes, change ALL of these together: `offer` below, the tiers
29+
* row, the hero chip in home.ts, the form's licence choice in platform.astro,
30+
* and the Platform sections of llms.txt.ts and llms-full.txt.ts.
3431
*
35-
* SOURCE OF TRUTH: libredb-platform → README.md and docs/product-map.md.
32+
* THE WAITING LIST IS AN EMAIL. Production is GitHub Pages, which cannot
33+
* receive a form post, and a third-party form relay would put visitors' details
34+
* through a processor the privacy policy does not name. So the form composes a
35+
* message in the visitor's own mail app (src/scripts/waitlist.ts); nothing
36+
* leaves this site. The address is printed beside the form for anyone without a
37+
* mail app.
38+
*
39+
* SOURCE OF TRUTH: libredb-platform → README.md (Features, Install, License).
3640
*/
3741

3842
export const status = {
3943
/** Shown in the badge. Never say "live" while the host does not answer. */
40-
label: 'Beta · self-hosted · by request',
41-
headline: { before: 'Stop distributing ', gradient: 'connection strings' },
44+
label: 'Self-hosted · free for 1 admin + 3 users',
45+
headline: { before: 'Stop handing out ', gradient: 'connection strings' },
4246
intro:
43-
'LibreDB Platform is the governed, multi-team form of LibreDB: admins decide who can reach which database, every query is logged against a person, and nobody is emailed a password. It is self-hosted on your infrastructure, like Studio — the difference is who is accountable for the access, not where it runs.',
47+
'LibreDB Platform puts one door in front of every database your team uses. Admins decide who reaches which database, people sign in with the company’s single sign-on, every query is logged against a name — and nobody is ever emailed a password. It runs on your own servers, next to your data.',
48+
};
49+
50+
/** Where waiting-list requests and licence questions go. The Platform README
51+
* names this address for licence keys; it is not the vendor's general inbox
52+
* in company.ts. */
53+
export const contact = {
54+
email: 'info@libredb.org',
55+
subject: 'LibreDB Platform — waiting list',
56+
} as const;
57+
58+
/**
59+
* The 60-second tour, on the LibreDB YouTube channel (uploaded in 4K).
60+
*
61+
* CLICK TO LOAD. The page shows only our own poster until the visitor presses
62+
* play; the YouTube player is created then, from the youtube-nocookie.com
63+
* domain (src/scripts/youtube-facade.ts). The privacy policy promises that a
64+
* visitor who declines cookies loads nothing from Google, so an iframe present
65+
* at page load would break that promise. Do not "simplify" this into a plain
66+
* embed.
67+
*
68+
* The video burns its own caption cards into the picture, so do not upload a
69+
* captions track to YouTube either — the two sets would sit on top of each
70+
* other.
71+
*/
72+
export const tour = {
73+
/** The YouTube thumbnail, kept here so the poster needs no request to Google. */
74+
poster: '/video/libredb-platform-tour.jpg',
75+
title: 'LibreDB Platform in 60 seconds',
76+
youtube: 'https://www.youtube.com/watch?v=YTf8dEG_Zo0',
77+
/** Canonical embed URL, for structured data. */
78+
youtubeEmbed: 'https://www.youtube.com/embed/YTf8dEG_Zo0',
79+
/** What the play button actually loads. */
80+
player: 'https://www.youtube-nocookie.com/embed/YTf8dEG_Zo0?autoplay=1&rel=0',
81+
uploadDate: '2026-10-19',
82+
duration: 'PT59S',
4483
};
4584

4685
export interface Capability {
@@ -50,34 +89,77 @@ export interface Capability {
5089

5190
export const capabilities: Capability[] = [
5291
{
53-
name: 'Multi-tenant organisations',
54-
detail: 'Isolated data per organisation, so one deployment serves several teams without them seeing each other.',
92+
name: 'One sign-in for everyone',
93+
detail:
94+
'People sign in through Keycloak single sign-on, connected to the identity provider you already run. Joiners and leavers stay one system’s problem.',
5595
},
5696
{
57-
name: 'Five-role RBAC',
97+
name: 'Passwords nobody sees',
5898
detail:
59-
'Platform Admin, Platform Tech, Tenant Admin, Editor and Viewer — least privilege as the starting point rather than as a hardening step.',
99+
'Database credentials are sealed to Studio’s public key when an admin registers a connection. People get access to a database — never its password.',
60100
},
61101
{
62-
name: 'Connection governance',
102+
name: 'Access, person by person',
63103
detail:
64-
'Encrypted credentials behind a permission matrix per connection. Access is granted to a person; the password is never handed over.',
104+
'Grant a connection to a named user from the access panel, read-only or with write. Revoke it and it is gone from their Studio — no password to rotate.',
65105
},
66106
{
67-
name: 'Query audit log',
68-
detail: 'Every query recorded with who ran it, how long it took and how it ended. Accountability, not telemetry.',
107+
name: 'Every query on the record',
108+
detail:
109+
'The audit log shows each query with who ran it, how long it took and how it ended. Accountability your auditors can read, not telemetry.',
69110
},
70111
{
71-
name: 'SSO through your provider',
72-
detail: 'Vendor-agnostic OIDC — Auth0, Keycloak, Okta, Entra ID. Joiners and leavers stay one system’s problem.',
112+
name: 'Roles that start at least privilege',
113+
detail:
114+
'Six system roles — Platform Admin, Platform Tech, Platform Support, Tenant Admin, Editor and Viewer — plus custom roles of your own.',
73115
},
74116
{
75-
name: 'Licensing',
117+
name: 'Studio, managed centrally',
76118
detail:
77-
'Per-organisation licence keys, self-hosted, with plan tiers configurable at runtime. The beta licence is issued at no charge; there is nothing to buy.',
119+
'Your analysts work in LibreDB Studio, the full editor for every engine. Its settings are set once from Platform and apply without a restart.',
78120
},
79121
];
80122

123+
/**
124+
* The limits, stated beside the capabilities as everywhere else on this site.
125+
* Each one is in the Platform README; keep them in step with it.
126+
*/
127+
export const limits: { term: string; detail: string }[] = [
128+
{
129+
term: 'Install',
130+
detail:
131+
'One installer deploys PostgreSQL, Keycloak, Platform, Studio and a Caddy edge with Docker on a single x86_64 Linux host. Kubernetes support follows in the next release.',
132+
},
133+
{
134+
term: 'Licence key',
135+
detail:
136+
'Every self-hosted install needs a licence key, and Platform does not start without one. The key sets the admin and user seats and the expiry.',
137+
},
138+
{
139+
term: 'Audit',
140+
detail:
141+
'The audit log records the queries Studio reports. Access that bypasses Platform — a password someone still holds — is outside it, which is why credentials are sealed.',
142+
},
143+
{
144+
term: 'Licence terms',
145+
detail:
146+
'Platform is source-available under the Elastic License 2.0: use, modify and self-host it, but not offer it to others as a hosted service. Studio stays MIT.',
147+
},
148+
];
149+
150+
/** The licence offer, as the waiting list states it. `choices` is the form's
151+
* licence question: two answers, so nobody has to work out where free ends. */
152+
export const offer = {
153+
seats: '1 admin and 3 users',
154+
term: '12 months',
155+
headline: 'Join the waiting list',
156+
lead: 'The licence for 1 admin and 3 users is free for 12 months — no card, nothing to buy. Need more seats? Those are paid, and we will send a price for the number you need. Tell us a little about your team and we will come back with a licence key and the installer.',
157+
choices: [
158+
{ value: 'Free licence — 1 admin + 3 users', label: '1 admin + 3 users', note: 'Free for 12 months' },
159+
{ value: 'Paid licence — more seats', label: 'More than that', note: 'Paid — we send a price' },
160+
],
161+
};
162+
81163
/**
82164
* The open-core line, stated as two rows rather than as a feature comparison.
83165
* A capability table here would invite the reading that Studio is the crippled
@@ -94,8 +176,10 @@ export const tiers = [
94176
},
95177
{
96178
tier: 'LibreDB Platform',
97-
line: 'Beta · self-hosted · not sold yet',
179+
line: 'Self-hosted · Elastic License 2.0 · paid beyond 4 seats',
98180
detail:
99-
'Governance on top of that editor for an organisation that has to answer who reached which data, and when. It is issued at no charge today and there is no plan to sell it within the next year; it is here so the part that is intended to cost money one day is visible rather than hidden.',
181+
'Governance on top of that editor, for an organisation that has to answer who reached which data, and when. The licence is free for 1 admin and 3 users for 12 months; more seats are paid. It is here so the part that costs money is visible rather than hidden.',
182+
href: '#waitlist',
183+
cta: 'Join the waiting list →',
100184
},
101185
];

‎src/pages/llms-full.txt.ts‎

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -124,11 +124,14 @@ key-value core with key-value, document and relational lenses over it, zero runt
124124
dependencies, crash recovery proven by deterministic simulation testing. It is an early
125125
beta aimed at test and development data. Described at ${site.url}/libredb-database.
126126
127-
## The product that is intended to cost money one day: LibreDB Platform
128-
129-
Multi-tenant database access governance for teams — organisations, five-role RBAC,
130-
per-connection permissions and a query audit log, self-hosted. In beta, not sold today,
131-
and with no plan to sell it within the next year; the editor itself stays MIT and free. Described at ${site.url}/platform.
127+
## The product that costs money: LibreDB Platform
128+
129+
Database access governance for teams — Keycloak single sign-on, credentials sealed so
130+
users never see them, per-person grants that can be revoked live, six system roles and
131+
a query audit log, self-hosted with Docker on one Linux host (Kubernetes in the next
132+
release). Source-available under the Elastic License 2.0; every install needs a licence
133+
key. The licence is free for 1 admin and 3 users for 12 months and paid for more
134+
seats, requested through the waiting list; the editor itself stays MIT and free. Described at ${site.url}/platform.
132135
133136
## FAQ
134137

‎src/pages/llms.txt.ts‎

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ const DESCRIPTIONS: Record<string, string> = {
4040
'Who may change the source, who approves a release for signing, and what the software sends over the network.',
4141
'/support': 'The vendor of record, the supported Kubernetes and runtime versions, and how to reach support.',
4242
'/platform':
43-
'LibreDB Platform: multi-tenant database access governance for teams. Beta, self-hosted, not currently sold.',
43+
'LibreDB Platform: database access governance for teams, a 60-second tour, and the waiting list. Self-hosted; free for 1 admin and 3 users for 12 months, paid beyond that.',
4444
'/compare': 'Desktop client, hosted editor, or deployed beside the data — what each approach costs you.',
4545
'/faq': 'The questions asked before adopting it.',
4646
'/blog': 'Release notes and engineering writing.',
@@ -102,8 +102,9 @@ ${engineList}
102102
## Licence
103103
104104
${site.license}. Every capability, every engine, no paid tier of the editor.
105-
LibreDB Platform is governance on top of it, issued at no charge during the beta
106-
and not sold today, described at ${site.url}/platform.
105+
LibreDB Platform is governance on top of it, source-available under the Elastic
106+
License 2.0. Its licence is free for 1 admin and 3 users for 12 months and paid
107+
for more seats, requested through the waiting list at ${site.url}/platform.
107108
`;
108109
};
109110

0 commit comments

Comments
 (0)