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
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "libredb-website",
"version": "1.4.0",
"version": "1.5.0",
"private": true,
"type": "module",
"description": "libredb.org — marketing website for LibreDB Studio (Astro static + Outstatic CMS)",
Expand Down
Binary file added public/video/libredb-platform-tour.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
42 changes: 42 additions & 0 deletions src/components/home/Hero.astro
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,12 @@ const DEMO_MOBILE = '/demo/libredb-studio-demo-mobile.html';
<CopyBox command={hero.command} label="Copy the docker run command" />
<p class="hero__note">{hero.commandNote}</p>
</div>

<a class="hero__platform" href={hero.platformCta.href}>
<span class="hero__platform-tag">{hero.platformCta.tag}</span>
<span>{hero.platformCta.label}</span>
<span class="hero__arrow" aria-hidden="true">→</span>
</a>
</div>
</div>

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

.hero__platform {
margin-top: var(--space-06);
display: inline-flex;
align-items: center;
gap: var(--space-04);
/* the same 48px and 15px as the hero's two buttons, so it reads as a third
button rather than a caption under the install line */
min-height: 48px;
padding: 0 22px 0 8px;
border: var(--border-width-1) solid var(--border-strong);
border-radius: var(--radius-pill);
background: var(--surface);
font: var(--weight-medium) 15px / 1 var(--font-ui);
color: var(--text-primary);
text-align: left;
animation: lbWord 0.7s var(--ease-out) 1.18s both;
transition: background var(--duration-fast) var(--ease-out);
}
.hero__platform:hover {
background: var(--surface-hover);
color: var(--text-primary);
}
.hero__platform:hover .hero__arrow {
transform: translateX(4px);
}
.hero__platform-tag {
flex: none;
padding: 8px 12px;
border-radius: var(--radius-pill);
background: var(--action-primary);
font: var(--weight-semibold) 12px / 1 var(--font-mono);
letter-spacing: 0.06em;
text-transform: uppercase;
color: #fff;
}

.hero__demo {
position: relative;
max-width: 1440px;
Expand Down
3 changes: 3 additions & 0 deletions src/data/home.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ export const navLinks = [
{ href: '#product', label: 'Product' },
{ href: '#open-source', label: 'Open source' },
{ href: '#deploy', label: 'Deploy' },
{ href: '/platform/', label: 'Platform' },
] as const;

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

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

export const status = {
/** Shown in the badge. Never say "live" while the host does not answer. */
label: 'Beta · self-hosted · by request',
headline: { before: 'Stop distributing ', gradient: 'connection strings' },
label: 'Self-hosted · free for 1 admin + 3 users',
headline: { before: 'Stop handing out ', gradient: 'connection strings' },
intro:
'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.',
'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.',
};

/** Where waiting-list requests and licence questions go. The Platform README
* names this address for licence keys; it is not the vendor's general inbox
* in company.ts. */
export const contact = {
email: 'info@libredb.org',
subject: 'LibreDB Platform — waiting list',
} as const;

/**
* The 60-second tour, on the LibreDB YouTube channel (uploaded in 4K).
*
* CLICK TO LOAD. The page shows only our own poster until the visitor presses
* play; the YouTube player is created then, from the youtube-nocookie.com
* domain (src/scripts/youtube-facade.ts). The privacy policy promises that a
* visitor who declines cookies loads nothing from Google, so an iframe present
* at page load would break that promise. Do not "simplify" this into a plain
* embed.
*
* The video burns its own caption cards into the picture, so do not upload a
* captions track to YouTube either — the two sets would sit on top of each
* other.
*/
export const tour = {
/** The YouTube thumbnail, kept here so the poster needs no request to Google. */
poster: '/video/libredb-platform-tour.jpg',
title: 'LibreDB Platform in 60 seconds',
youtube: 'https://www.youtube.com/watch?v=YTf8dEG_Zo0',
/** Canonical embed URL, for structured data. */
youtubeEmbed: 'https://www.youtube.com/embed/YTf8dEG_Zo0',
/** What the play button actually loads. */
player: 'https://www.youtube-nocookie.com/embed/YTf8dEG_Zo0?autoplay=1&rel=0',
uploadDate: '2026-10-19',
duration: 'PT59S',
};

export interface Capability {
Expand All @@ -50,34 +89,77 @@ export interface Capability {

export const capabilities: Capability[] = [
{
name: 'Multi-tenant organisations',
detail: 'Isolated data per organisation, so one deployment serves several teams without them seeing each other.',
name: 'One sign-in for everyone',
detail:
'People sign in through Keycloak single sign-on, connected to the identity provider you already run. Joiners and leavers stay one system’s problem.',
},
{
name: 'Five-role RBAC',
name: 'Passwords nobody sees',
detail:
'Platform Admin, Platform Tech, Tenant Admin, Editor and Viewer — least privilege as the starting point rather than as a hardening step.',
'Database credentials are sealed to Studio’s public key when an admin registers a connection. People get access to a database — never its password.',
},
{
name: 'Connection governance',
name: 'Access, person by person',
detail:
'Encrypted credentials behind a permission matrix per connection. Access is granted to a person; the password is never handed over.',
'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.',
},
{
name: 'Query audit log',
detail: 'Every query recorded with who ran it, how long it took and how it ended. Accountability, not telemetry.',
name: 'Every query on the record',
detail:
'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.',
},
{
name: 'SSO through your provider',
detail: 'Vendor-agnostic OIDC — Auth0, Keycloak, Okta, Entra ID. Joiners and leavers stay one system’s problem.',
name: 'Roles that start at least privilege',
detail:
'Six system roles — Platform Admin, Platform Tech, Platform Support, Tenant Admin, Editor and Viewer — plus custom roles of your own.',
},
{
name: 'Licensing',
name: 'Studio, managed centrally',
detail:
'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.',
'Your analysts work in LibreDB Studio, the full editor for every engine. Its settings are set once from Platform and apply without a restart.',
},
];

/**
* The limits, stated beside the capabilities as everywhere else on this site.
* Each one is in the Platform README; keep them in step with it.
*/
export const limits: { term: string; detail: string }[] = [
{
term: 'Install',
detail:
'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.',
},
{
term: 'Licence key',
detail:
'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.',
},
{
term: 'Audit',
detail:
'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.',
},
{
term: 'Licence terms',
detail:
'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.',
},
];

/** The licence offer, as the waiting list states it. `choices` is the form's
* licence question: two answers, so nobody has to work out where free ends. */
export const offer = {
seats: '1 admin and 3 users',
term: '12 months',
headline: 'Join the waiting list',
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.',
choices: [
{ value: 'Free licence — 1 admin + 3 users', label: '1 admin + 3 users', note: 'Free for 12 months' },
{ value: 'Paid licence — more seats', label: 'More than that', note: 'Paid — we send a price' },
],
};

/**
* The open-core line, stated as two rows rather than as a feature comparison.
* A capability table here would invite the reading that Studio is the crippled
Expand All @@ -94,8 +176,10 @@ export const tiers = [
},
{
tier: 'LibreDB Platform',
line: 'Beta · self-hosted · not sold yet',
line: 'Self-hosted · Elastic License 2.0 · paid beyond 4 seats',
detail:
'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.',
'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.',
href: '#waitlist',
cta: 'Join the waiting list →',
},
];
13 changes: 8 additions & 5 deletions src/pages/llms-full.txt.ts
Original file line number Diff line number Diff line change
Expand Up @@ -124,11 +124,14 @@ key-value core with key-value, document and relational lenses over it, zero runt
dependencies, crash recovery proven by deterministic simulation testing. It is an early
beta aimed at test and development data. Described at ${site.url}/libredb-database.

## The product that is intended to cost money one day: LibreDB Platform

Multi-tenant database access governance for teams — organisations, five-role RBAC,
per-connection permissions and a query audit log, self-hosted. In beta, not sold today,
and with no plan to sell it within the next year; the editor itself stays MIT and free. Described at ${site.url}/platform.
## The product that costs money: LibreDB Platform

Database access governance for teams — Keycloak single sign-on, credentials sealed so
users never see them, per-person grants that can be revoked live, six system roles and
a query audit log, self-hosted with Docker on one Linux host (Kubernetes in the next
release). Source-available under the Elastic License 2.0; every install needs a licence
key. The licence is free for 1 admin and 3 users for 12 months and paid for more
seats, requested through the waiting list; the editor itself stays MIT and free. Described at ${site.url}/platform.

## FAQ

Expand Down
7 changes: 4 additions & 3 deletions src/pages/llms.txt.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ const DESCRIPTIONS: Record<string, string> = {
'Who may change the source, who approves a release for signing, and what the software sends over the network.',
'/support': 'The vendor of record, the supported Kubernetes and runtime versions, and how to reach support.',
'/platform':
'LibreDB Platform: multi-tenant database access governance for teams. Beta, self-hosted, not currently sold.',
'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.',
'/compare': 'Desktop client, hosted editor, or deployed beside the data — what each approach costs you.',
'/faq': 'The questions asked before adopting it.',
'/blog': 'Release notes and engineering writing.',
Expand Down Expand Up @@ -102,8 +102,9 @@ ${engineList}
## Licence

${site.license}. Every capability, every engine, no paid tier of the editor.
LibreDB Platform is governance on top of it, issued at no charge during the beta
and not sold today, described at ${site.url}/platform.
LibreDB Platform is governance on top of it, source-available under the Elastic
License 2.0. Its licence is free for 1 admin and 3 users for 12 months and paid
for more seats, requested through the waiting list at ${site.url}/platform.
`;
};

Expand Down
Loading
Loading