diff --git a/site/docs-typr/getting-started.md b/site/docs-typr/getting-started.md
index 18ddde29bd..38b984844b 100644
--- a/site/docs-typr/getting-started.md
+++ b/site/docs-typr/getting-started.md
@@ -5,101 +5,26 @@ sidebar_position: 2
# Getting Started with Typr
-Typr is a type-safe code generator for JVM languages. It reads your database schemas and OpenAPI specifications, then generates fully-typed code that the compiler can verify.
+Typr is a type-safe code generator for JVM languages. It reads your database schemas, OpenAPI specifications, and Avro/Kafka events, then generates fully-typed code that the compiler can verify end-to-end.
-:::info Private Beta
+:::info Closed Beta
-Typr is currently in private beta. We're working with select teams to refine the experience before public release in **early 2026**.
+Typr is currently in **closed beta**. We're working with a small set of teams to harden the CLI, the DSL, and the unified-types story before opening signups more broadly. Public release is scheduled for **early 2026**.
-:::
-
-
-Installation (available in beta)
-
-### Via Coursier (Recommended)
-
-```bash
-cs install typr --channel https://typr.dev/channel
-```
-
-### Via Homebrew (macOS)
-
-```bash
-brew install oyvindberg/tap/typr
-```
-
-### Via npm (Cross-platform)
-
-```bash
-npm install -g @typr/cli
-```
-
-### Direct Download
-
-```bash
-# Download the latest release
-curl -L https://github.com/oyvindberg/typr/releases/latest/download/typr -o typr
-chmod +x typr
-
-# Or as a JAR file
-curl -L https://github.com/oyvindberg/typr/releases/latest/download/typr.jar -o typr.jar
-java -jar typr.jar --help
-```
-
-
+Want a beta seat? Email [oyvind@typr.dev](mailto:oyvind@typr.dev) — we're prioritising teams running multiple boundaries (database + API, or database + Kafka) where the unified-types work earns its keep fastest.
-
-Quick Start (available in beta)
-
-### 1. Initialize
-
-```bash
-typr init
-```
-
-Creates `typr.yaml`. You'll be prompted for language and first data source.
-
-### 2. Configure
-
-Edit `typr.yaml`:
-
-```yaml
-sources:
- postgres:
- type: postgresql
- host: localhost
- database: myapp
- username: ${POSTGRES_USER}
- password: ${POSTGRES_PASSWORD}
-
-output:
- path: ./generated
- package: com.myapp
- language: java
-```
-
-### 3. Generate
-
-```bash
-typr
-```
-
-That's it. Running `typr` without arguments generates code.
-
-### 4. Use
+:::
-```java
-// Generated types are ready to use
-UserRow user = userRepo.selectById(new UserId(123));
+## What's available right now
-// Type-safe - can't mix up ID types
-// userRepo.selectById(new OrderId(123)); // Compile error!
-```
+You can read and link to all the documentation:
-
+- [Databases](/typr/boundaries/databases/) — how Typr generates code from your schema
+- [REST APIs](/typr/boundaries/apis/) — server + client generation from OpenAPI
+- [Events (Avro/Kafka)](/typr/boundaries/events/) — typed records from Avro schemas
+- [Unified Types](/typr/unified-types/) — one domain type across every boundary
+- [Comparison](/typr/comparison/) — how Typr compares to alternatives
-## What's Next?
+## What's *not* available right now
-- [Databases](/typr/boundaries/databases/) - Database code generation
-- [REST APIs](/typr/boundaries/apis/) - OpenAPI code generation
-- [Unified Types](/typr/unified-types/) - Share types across boundaries
+Installation instructions and a public CLI download are gated behind the closed beta. Once the beta opens up, this page will publish step-by-step setup for Coursier, Homebrew, SDKMAN, JBang, and Scoop, plus a `typr init`-flavoured walkthrough.
diff --git a/site/docusaurus.config.js b/site/docusaurus.config.js
index 87f9582efb..39fc1f4476 100644
--- a/site/docusaurus.config.js
+++ b/site/docusaurus.config.js
@@ -85,8 +85,8 @@ const config = {
respectPrefersColorScheme: true,
},
announcementBar: {
- id: 'under_development',
- content: '🚧 Under Development — This site and product are launching early 2026.',
+ id: 'closed_beta',
+ content: '🚧 Closed Beta — Typr is in closed beta with public release in early 2026. Request a seat →',
backgroundColor: '#0c1a2b',
textColor: '#f4f0e6',
isCloseable: false,
diff --git a/site/src/css/custom.css b/site/src/css/custom.css
index 7826635cea..b2c1e86a15 100644
--- a/site/src/css/custom.css
+++ b/site/src/css/custom.css
@@ -1120,3 +1120,22 @@ article header h1 {
[data-theme="dark"] main {
background: var(--typr-paper);
}
+
+/* =============================================================================
+ Mobile navbar — keep the hamburger and dark-mode toggle reachable.
+ The default Docusaurus rules hide both the toggle (.colorModeToggle) and
+ any custom !important from earlier rules can swallow the hamburger.
+ ============================================================================= */
+@media (max-width: 996px) {
+ .navbar__toggle {
+ display: inline-flex !important;
+ color: var(--typr-ink) !important;
+ }
+ /* Surface the color-mode toggle in the navbar on mobile too — Docusaurus
+ hides it by default expecting the slide-out menu to carry it, but the
+ direct toggle is friendlier. The class is hashed by CSS modules so we
+ match by attribute prefix to stay stable across Docusaurus rebuilds. */
+ .navbar__items--right [class*="colorModeToggle"] {
+ display: inline-flex !important;
+ }
+}
diff --git a/site/src/pages/index.js b/site/src/pages/index.js
index b09a4e8573..cda3f41d62 100644
--- a/site/src/pages/index.js
+++ b/site/src/pages/index.js
@@ -286,12 +286,41 @@ function ManifestoSection() {
+
);
}
+function BlueprintDiagramMobile() {
+ const stations = [
+ { tag: "A", name: "postgres", policy: "anchor" },
+ { tag: "B", name: "mariadb", policy: "superset" },
+ { tag: "C", name: "openapi", policy: "exact" },
+ { tag: "D", name: "kafka / avro", policy: "subset" },
+ ];
+ return (
+
+
One domain type, four boundaries
+
+ -
+ ·
+ Customer (domain)
+ canonical
+
+ {stations.map((s) => (
+ -
+ {s.tag}
+ {s.name}
+ {s.policy}
+
+ ))}
+
+
+ );
+}
+
function BlueprintDiagram() {
// Domain fields (canonical Customer)
const fields = [
diff --git a/site/src/pages/index.module.css b/site/src/pages/index.module.css
index 6ff3f0ad10..0373838a59 100644
--- a/site/src/pages/index.module.css
+++ b/site/src/pages/index.module.css
@@ -41,6 +41,7 @@
font-feature-settings: 'ss01', 'ss02', 'cv01';
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
+ overflow-x: hidden;
/* Hand‑placed paper grain so it reads as printed, not pixel‑perfect */
background-image:
@@ -529,6 +530,63 @@
}
.diagramScroll .diagram { display: block; min-width: 980px; border: none; background: transparent; }
+/* On phones the diagram becomes a horizontal-scroll trap and the text alone
+ carries the section. Hide it; the mobile fallback below keeps the beat. */
+@media (max-width: 700px) {
+ .diagramFigure { display: none; }
+ .diagramMobile {
+ display: block;
+ grid-column: 1 / -1;
+ margin-top: 1.5rem;
+ border: 1px solid var(--hairline);
+ background: var(--paper-warm);
+ padding: 1.25rem 1rem;
+ }
+}
+.diagramMobile { display: none; }
+.diagramMobileHeading {
+ font-family: var(--mono);
+ font-size: 0.72rem;
+ letter-spacing: 0.18em;
+ text-transform: uppercase;
+ color: var(--vermillion);
+ margin: 0 0 0.75rem 0;
+}
+.diagramMobileList {
+ list-style: none;
+ margin: 0;
+ padding: 0;
+ display: grid;
+ gap: 0.6rem;
+}
+.diagramMobileItem {
+ display: grid;
+ grid-template-columns: auto 1fr auto;
+ gap: 0.75rem;
+ align-items: baseline;
+ padding: 0.55rem 0;
+ border-top: 1px solid var(--hairline);
+}
+.diagramMobileItem:first-child { border-top: none; }
+.diagramMobileTag {
+ font-family: var(--mono);
+ font-size: 0.72rem;
+ color: var(--vermillion);
+ font-weight: 700;
+}
+.diagramMobileName {
+ font-family: var(--serif);
+ font-size: 1.05rem;
+ color: var(--ink);
+}
+.diagramMobilePolicy {
+ font-family: var(--mono);
+ font-size: 0.7rem;
+ color: var(--sub-ink);
+ text-transform: uppercase;
+ letter-spacing: 0.12em;
+}
+
.diagramCaption {
margin-top: 0.85rem;
display: flex;