DZDEV
// UI · dzbot Pro

@dzbot/ui

The dzbot look for your own community website: the theme and the React components the dzbot web app is built with. Your site looks like your server's dzbot page, in your server's colour, and your players feel at home.

For dzbot Pro customers only. This is not a free component library. You may use it only in sites and apps built for an organization with an active dzbot Pro subscription that work with dzbot. See who may use it.

// LicenseWho may use it

@dzbot/ui is source-available under the dzbot UI License, not open source. In short:

You may

Use and change it in websites and apps built for an organization with an active dzbot Pro subscription — sites that use the dzbot API or SDK, or link to that organization's servers on dzbot.

You may not

Use it for any other product, or redistribute or republish it on its own — as a component library, design system, UI kit or theme.

When Pro ends

The right to use it ends with the subscription. Sites already running have 30 days to remove it.

The dzbot terms of service apply as well. The fonts are not part of the package and keep their own licenses (SIL Open Font License).

// InstallInstall

npm install @dzbot/ui lucide-react

Needs React 18 or newer and Tailwind CSS 4. Pairs with @dzbot/sdk for your server's data and Sign in with dzbot.

// ThemeTheme

Three lines in your main stylesheet: the fonts first (a CSS @import has to come before every other rule), then Tailwind, then the theme.

@import "@dzbot/ui/fonts.css";
@import "tailwindcss";
@import "@dzbot/ui/theme.css";

fonts.css loads Bebas Neue, Barlow, Barlow Condensed and JetBrains Mono from Google Fonts; leave it out if you serve them yourself. theme.css brings the tokens, the dark base and the shapes, and registers the components with Tailwind (@source "./dist") so their classes are generated. Tailwind skips node_modules on its own; if the classes are missing in your setup, name the package yourself, relative to your stylesheet:

@source "../node_modules/@dzbot/ui/dist";
TokenMeaning
accent-50 … accent-950The server's colour — see Colour
success, warning, danger, infoStatus: emerald, amber, red, sky. Never change with the palette
medal-gold, medal-silver, medal-bronzeRanks 1–3 on leaderboards
rounded-control, rounded-field, rounded-surface2px, for buttons, fields and cards
font-bebasDisplay: titles, big numbers
font-mono-jb, hud-labelLabels: JetBrains Mono, uppercase, wide tracking
font-barlow, font-barlow-condensedReading text; menus

// ColourYour server's colour

accent-* follows data-palette on <html> — the same palettes server owners pick for their dzbot page in Settings → General. To give one part of the page another server's colour, set it there together with data-area="guest".

<html data-palette="teal"> <!-- amber (default), teal, cyan, fuchsia, lime, orange -->
<article data-area="guest" data-palette="lime">…</article>

// SetupRouter and language

Internal links (TextLink to, NoticeAction to) render a plain <a href> until you hand over your router's link. UiProvider also takes the label a button shows after its action succeeded, and how a failed action's error becomes text. Everything is optional.

import { Link } from 'react-router'
import { UiProvider } from '@dzbot/ui'

createRoot(root).render(
  <UiProvider link={Link} doneLabel="Saved" errorText={(error, fallback) => fallback ?? String(error)}>
    <App />
  </UiProvider>,
)

// ComponentsComponents

import { Button, Card, Stat } from '@dzbot/ui'

export function Wallet({ balance, onTopUp }: { balance: number; onTopUp: () => Promise<void> }) {
  return (
    <Card title="Wallet">
      <Stat label="Balance" value={balance} detail="shared by all servers" />
      <Button variant="primary" tone="tonal" action={onTopUp}>Top up</Button>
    </Card>
  )
}
ComponentUseMain props
ButtonEvery button. Outline first; tone="tonal" for one important button that stands alone. action takes an async function and shows pending, done and error itselfvariant primary · secondary · danger · ghost · discord, tone, size sm · md · lg · icon, action, doneLabel
IconButtonAn icon-only button; the label is its tooltip and screen-reader namelabel, tone default · accent · danger, size
CardThe one surface, with an optional header bar. Card.Inset for a box inside it, Card.Label for a // label on the righttitle, aside, description, toolbar, flush, loading
StatOne number with its label, the top-left corner cutlabel, value, detail, tone, loading
NoticeCallouts and banners; NoticeAction for its buttontone info · warning · danger · success · accent, title, action, banner
StatusBadgeA status: tinted, icon plus text, never colour alonetone success · warning · danger · info · neutral · accent, icon
TagA neutral label (group, faction); color leads with a swatch. Never a statuscolor, icon
ChipA filter chipselected
Facts, FactFacts about one thing: mono label over its value, one to three columnscolumns; label, wide
AvatarA player's picture in the octagon, initials until it loadsname, src, size, tone
IconOctagonThe container for an iconsize xs – xl, tone
SectionHeading, SubLabelA section title with a rule; a // label inside a cardmeta, as
TextLinkA link in text, or on its own line with standalone; href opens a new tabto, href, standalone
Skeleton, LinesSkeleton, RowSkeletonLoading placeholders in the shape of the contentclassName; lines, rows
BlockLoaderThe small busy marker: four blocks pulsing in turnsize
cn, buttonVariantsJoin class names (later Tailwind classes win); a button's classes for a link that looks like one

// ShapesCut corner and octagon

The cut corner is dzbot's one signature shape: two opposite corners cut at 45°, or the top-left one on stat tiles. The border is drawn by the element, the surface by a layer 1px inside, so you set both colours as variables:

<div className="dz-cut p-4 [--dz-cut-border:var(--color-zinc-700)] [--dz-cut-fill:var(--color-zinc-900)]">…</div>

dz-cut cuts two corners (10px, dz-cut-sm 6px), dz-cut-tl the top-left one (12px), dz-octagon makes an octagon. Keep the cut corner rare: the lone call to action (Button tone="tonal"), Stat and dialogs.

// RulesThe rules of the look

Controls and labels speak the HUD of a game menu — square, JetBrains Mono, uppercase; what people read stays calm in Barlow. Buttons are outlines, never filled blocks; "selected" is the accent as tint, border or bar. Nothing glows, nothing is round (the octagon replaces the circle), and a status always shows icon and text, never colour alone — on an amber server, amber can't mean "pending".