Cloud & teams
A built deck is one self-contained .html you can host anywhere. liebstoeckel cloud
(the hosted control plane) adds a private, always-on home for your decks behind a login.
For teams, it adds a shared library with members, roles, and invitations.
Sign in from the terminal
Section titled “Sign in from the terminal”Authentication is passwordless. login runs the OAuth 2.0 device-authorization grant:
the CLI prints a URL, you open it, sign in with a one-time email code, and approve.
liebstoeckel login --api https://<your-control-plane-host>The token is stored in ~/.config/liebstoeckel/credentials.json (mode 600).
Push a deck
Section titled “Push a deck”liebstoeckel build # → ./dist/<deck-slug>.htmlliebstoeckel push # uploads the built deck in ./distThe deck’s title comes from its embedded <title> (or an explicit --title
override), and its cover thumbnail is read from the slide thumbnails already baked
into the file, so there is nothing extra to send. The server reads both straight out of
the uploaded file, which means titles with em-dashes, smart quotes, or emoji just work.
The deck appears in your dashboard immediately.
Organizations: personal and teams
Section titled “Organizations: personal and teams”Every account has a personal workspace (just you) and can create or join team organizations. A deck always belongs to exactly one organization, the active one.
- In the dashboard, switch the active workspace with the switcher in the top-left.
- From the CLI, list your workspaces and choose where
pushlands:
liebstoeckel orgs # list workspaces; → marks the push defaultliebstoeckel orgs use acme # make the "acme" team the defaultliebstoeckel push --org acme # …or target a team for one pushTeams: shared library, members & roles
Section titled “Teams: shared library, members & roles”Every deck pushed to a team is visible to all its members as a shared library, with “uploaded by” attribution. Who can do what is governed by three roles:
| Role | Can |
|---|---|
| owner | everything, incl. manage any deck, manage members, delete the org |
| admin | manage any deck, invite/remove members, change roles |
| member | upload decks; manage their own decks; view all team decks |
Manage all of this on the dashboard’s Team page:
- Invite a colleague by email. They get a link, sign in with a one-time code, and join automatically (still passwordless).
- Change roles or remove members.
- Leave a team you no longer need (your personal workspace always stays).
Share a deck publicly
Section titled “Share a deck publicly”Any deck can be published to a time-limited public link served on a separate domain, with provenance chrome and an abuse-report path. Open a deck’s share action in the dashboard to set:
- Expiry: how long the link lives (7 days on the free plan; longer, or no expiry, on paid).
- White-label (paid): drop the “Published with liebstoeckel” banner. The abuse-report path always remains.
Present live from the dashboard
Section titled “Present live from the dashboard”Turn any hosted deck into a live, interactive session straight from the browser, with no CLI and no local runtime. Open a deck’s ● present live action and Start live session:
- A presenter view opens (you drive the slides), and a shareable audience link appears that you can copy or hand out. Your audience opens it on any device and follows along, voting in polls, asking questions, and reacting in real time.
- Press End session when you’re done. The audience link stops working immediately.
The deck runs in an isolated sandbox for the audience, and the relay that carries the session never executes deck code, the same isolation as a public relay. Audience members can only interact through plugins (votes, questions, reactions); they can’t drive navigation or tamper with results.
Free gives you a real, usable live session with a capped audience and duration, and results aren’t kept once the session ends. Pro / Team raise the limits, drop the audience watermark, and persist results: open a past session under present live to see decoded poll tallies, the Q&A backlog, and reaction totals.
Shared brand
Section titled “Shared brand”Your org is an authenticated registry, speaking the same protocol as liebstoeckel add
but private to your team. A brand (a theme token set: colours, fonts, glow, and an
ordered chart palette) is its first item type; custom company components can ride the
same rails later.
- Define it once: push a
defineTheme(...)file (liebstoeckel brand push ./brand.ts --default) or edit it visually in the dashboard’s Brand page. - Use it:
liebstoeckel brand pull <name>writesbrands/<name>.tsinto a deck, andliebstoeckel newauto-applies the org default brand. The brand is owned source, baked into the deck at build: self-contained and WYSIWYG, never a serve-time surprise. - Update it: change the brand centrally, then authors (or CI) re-pull + rebuild. Deliberate, not silent.
Shared brand is a Pro/Team feature.
Generate a starting point
Section titled “Generate a starting point”Not sure where to start? The Brand page’s Generate button rolls a complete brand
(colours, fonts, glow, and chart palette) in one click. It is constrained, not random:
a single seed picks a base hue, a colour-harmony scheme (analogous / complementary /
triadic / …), and a font-pairing recipe (minimal / editorial / modern / …), then every
token is derived by rule in the perceptual OKLCH space, with each colour floored to a
legible contrast on the dark background. Fonts are drawn from the catalog, so a generated
brand always ships its webfonts on pull. Re-roll until you like it, then tweak any field
by hand. The generated values are an editable starting point, never locked in.
The Brand page’s Heading, Body, and Mono fields are a picker over a curated
catalog of Fontsource variable fonts (grouped sans / serif /
display / monospace), with a Custom… option for any other font-family you type. The
preview shows the real typeface as you choose.
When you liebstoeckel brand pull <name>, a catalog font comes with its webfont: the
generated brands/<name>.ts imports the matching @fontsource-variable/* package, and
pull runs bun add to install it, so the font is inlined into your single-file deck at
build with no CDN involved. liebstoeckel new does the same for the org default brand.
Pass --no-install to write the files and install the font packages yourself. A
Custom… font carries no package; supply its @font-face yourself, or it falls back to
the system font.
If you author a brand as a file instead (brand push ./brand.ts), any font family that
isn’t in the catalog is accepted but flagged with a warning (with a did you mean when
it’s close, e.g. "Inter" → "Inter Variable"), so the file path is as honest as the
picker about which fonts actually ship a webfont.
Chart palette
Section titled “Chart palette”A brand also carries an ordered chart-series palette (viz): the colours charts cycle
through, exposed as --brand-viz-0..n. Edit it on the Brand page (add / reorder / remove
swatches) or set viz: [...] in a pushed defineTheme(...). It’s baked into pulled decks
so charts match the brand, not just the page chrome.
Versions
Section titled “Versions”A deck has a stable identity across re-pushes. push keys a deck by its folder name
(or --name), so editing and pushing again updates the same deck at the same URL;
the share link and view counts carry over. --new starts a separate deck.
- Free keeps the latest version (a re-push replaces it; the URL and stats are preserved).
- Pro / Team keep full version history with one-click rollback: open a deck’s
Versions panel to see every version, preview one (
/d/:id?v=N), or make an older version current.
View analytics
Section titled “View analytics”Every deck shows view counts (total and unique), for both private opens and public share links. Counts are privacy-preserving (no raw IP/UA is stored). Expand a deck to see a 14-day history strip on paid plans; the free plan shows counts only.
Public share links also carry a view cap on the free plan, a built-in guardrail against abuse that doubles as the upgrade nudge; paid plans are uncapped.
Workspaces are free by default. Paid plans (Pro / Team) unlock uncapped share
views, view history with longer retention, white-label shares, longer/no-expiry links, and
larger live sessions with persisted results.
Plans attach to the organization (one subscription per workspace). The CLI shows your
current plan under liebstoeckel orgs.
Code-first presentations your agent can author. One file out, no server.
Comments