Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/estebanrfp/gdb/llms.txt

Use this file to discover all available pages before exploring further.

🎨 GenosDB Design Guide

Opinionated UI patterns, design tokens and page architectures for applications built on GenosDB β€” written for humans and AIs alike. If you (or your AI assistant) are building a GenosDB application and want it to look and behave like a first-class citizen of the ecosystem, follow this guide. The goal is coherence without complexity: every rule here is implementable in plain HTML + CSS + JavaScript, with no UI framework required.

Two deployment shapes, one design language

GenosDB applications ship in two shapes, and this guide applies equally to both:
  • No-build (examples, testbeds, prototypes): three files β€” index.html, styles.css, app.js β€” importing GenosDB from a CDN. Zero tooling.
  • Bundled (production apps): installed from npm and bundled into the app. Bun is the recommended bundler and runtime β€” bun build inlines GenosDB’s core, and the engine’s optional *.min.js plugins are copied next to the output bundle. See Bundler Configuration for Bun, Vite, Webpack and esbuild setups.
The design language is identical in both β€” tokens and patterns don’t care how the bytes arrived.

1. Philosophy

  1. Content is the protagonist. Chrome (navigation, session, widgets) stays visually quiet; data takes the full viewport height. Never let a fixed panel steal reading space.
  2. Dark, minimal, precise. One dark theme, generous whitespace, subtle borders instead of shadows, restrained color reserved for meaning (roles, status, actions).
  3. The API dictates the UX. GenosDB’s methods have natural interface consequences β€” mnemonic identity wants a focused modal, the security state callback wants a reactive session pill, governance roles want visible badges, realtime deltas want live DOM. Design from the API, not against it.
  4. No UI frameworks, no dependencies for style. Design tokens + plain CSS cover everything, whether the app is a three-file example or a Bun-bundled product. The only sanctioned UI dependencies are functional (e.g. DOMPurify for untrusted content).
  5. Small surface, strong opinions. When in doubt, do less.

2. Design Tokens

Copy this :root block as-is. Every color, radius and spacing in your app must reference a token β€” never hardcode values in component rules.
:root {
    /* Backgrounds (dark β†’ elevated) */
    --bg-primary: #0d0f12;      /* page */
    --bg-secondary: #14171c;    /* cards, sidebar */
    --bg-tertiary: #1c2026;     /* inputs, hover, pills */
    --bg-elevated: #22262d;     /* modals, popovers */

    /* Text */
    --text-primary: #e8eaed;
    --text-secondary: #9aa3ad;
    --text-tertiary: #5c6570;   /* hints, timestamps, addresses */

    /* Accent & status */
    --accent: #4c8dff;          /* primary actions, links */
    --accent-hover: #6ba1ff;
    --ok: #34c77b;              /* success, earned tiers */
    --warn: #f5a623;            /* drafts, moderation, caution */
    --danger: #ef5350;          /* delete, errors */
    --violet: #a78bfa;          /* superadmin / root-of-trust */

    /* Borders */
    --border-subtle: #262b33;
    --border-strong: #333a44;

    /* Shape & rhythm (8px grid) */
    --radius-sm: 6px;           /* buttons, inputs */
    --radius-md: 10px;          /* cards */
    --radius-lg: 14px;          /* modals */
    --space-2: 8px;
    --space-3: 12px;
    --space-4: 16px;
    --space-5: 24px;
    --space-6: 32px;

    /* Typography */
    --font: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Inter", "Helvetica Neue", Arial, sans-serif;
    --mono: ui-monospace, "SF Mono", SFMono-Regular, Menlo, monospace;
}

Color mode: dark only

GenosDB applications ship dark-only by default β€” examples, testbeds and instruments add no theme state at all. For consumer-facing product apps, a theme toggle is a sanctioned opt-in pattern, with exact rules:
  1. One icon button in the top bar, next to the session pill, with an aria-label. The icon shows the mode you’ll switch to (πŸŒ™ while in light, β˜€οΈ while in dark).
  2. Implementation: a data-theme attribute on <html>, a [data-theme="light"] block that redefines tokens only, localStorage persistence, and prefers-color-scheme as the first-visit default.
const applyTheme = (t) => {
  document.documentElement.dataset.theme = t
  localStorage.theme = t
  themeBtn.textContent = t === 'dark' ? 'β˜€οΈ' : 'πŸŒ™'
}
applyTheme(localStorage.theme ?? (matchMedia('(prefers-color-scheme: light)').matches ? 'light' : 'dark'))
themeBtn.onclick = () => applyTheme(document.documentElement.dataset.theme === 'dark' ? 'light' : 'dark')
  1. The golden rule: if enabling the toggle requires touching any component CSS, the token system is broken β€” fix the tokens, never patch components. A well-built toggle costs ~25 lines total and doubles as living proof that the design tokens work.

3. Typography & Data Display

  • System font stack for UI text; monospace (--mono) is mandatory for machine data: Ethereum addresses, node IDs, hashes, timestamps, peer IDs.
  • Addresses are never shown in full. Always db.sm.abbrAddr(address) (e.g. 0x1234...abcd), rendered in --mono + --text-tertiary.
  • Timestamps localize with new Date(ts).toLocaleString() β€” never raw epoch numbers in the UI.
  • Untrusted content is always sanitized. Anything a peer can write (titles, descriptions, markdown) is escaped before innerHTML, and rendered markdown passes through DOMPurify. A P2P app has no server to sanitize for you.
  • Missing attribution (nodes created before identity existed) renders as by unknown β€” never a broken or empty label.

4. Identity & Session

This is the most GenosDB-specific chapter: the Security Manager’s methods define the flow, the guide defines its shape. (Method-level best practices live in the SM API Reference; this section covers the visual pattern.)

4.1 Login & registration: a centered modal

Identity actions live in a centered modal (native <dialog>), not in a sidebar panel or a separate page. Rationale: the mnemonic flow is short, focused and security-critical β€” a modal isolates it, keeps the app visible behind a dimmed backdrop, and disappears the instant the session activates. The modal contains, in order:
  1. A one-paragraph hint explaining the trust model (e.g. what a guest can do, how roles are earned).
  2. One <textarea> serving both purposes: paste an existing mnemonic, or display a freshly generated one (set readOnly after generating; resize: none).
  3. Action row: Generate identity Β· Copy phrase Β· Login with mnemonic Β· Protect with passkey (after generating) Β· Login with passkey (only if db.sm.hasExistingWebAuthnRegistration()).
  4. Optional demo/superadmin shortcut for showcases.
Wiring rules:
// Backdrop click closes (the dialog itself is the event target then);
// Esc is native to <dialog>. No Γ— close button in the corner: the modal
// is a door, not a window β€” a corner Γ— reads as app-window chrome and,
// in the backup phase, invites closing before the phrase is saved.
modal.onclick = (e) => { if (e.target === modal) modal.close() }
…and the security state callback closes it on login β€” the user never dismisses it manually after authenticating. The modal is a three-phase state machine (button visibility per phase):
PhaseVisibleHidden
Signed out (fresh)Generate identity Β· Login with mnemonic Β· Login with passkey (only if a WebAuthn registration exists)Copy phrase Β· Protect with passkey
After generatingCopy phrase Β· Protect with passkey (labelled Recommended) Β· Login with mnemonic (must remain β€” no dead ends)Generate identity (one identity at a time)
Session activeβ€” modal auto-closes; on logout the textarea resets to editable and phase 1 returns
No standing β€œSign in” button β€” the modal IS the door. A distributed app has no server-side login page, so don’t emulate one with a persistent button. Open the identity modal automatically on every load without an active session: the newcomer immediately learns what an identity is and how roles are earned, and returning passkey users never see it β€” their session resumes silently and the security callback closes it.
// Boot: signed-out state = the identity dialog (dismissible)
if (!db.sm.isSecurityActive()) identityModal.showModal()
  • Dismissible (backdrop click, Esc) but with no Γ— close button β€” the app stays fully usable as a read-only guest behind it.
  • Logging out returns to phase 1 with the modal open β€” signed-out is the modal’s state.
  • Re-entry without reloading is contextual, not chrome: a clickable read-only status hint, or the explanatory affordance of a gated control, re-opens the modal. The top-right area belongs to the session chip alone and stays empty while signed out.

4.2 Session: always top-right

An authenticated session renders anchored to the top-right of the content area (the universal convention users scan for), in the canonical format β€” abbreviated address first, role second:
0x1234...abcd [role]   Logout
The address is --mono + --text-secondary; the role reads as a quiet bracketed tag. Restraint over decoration: no saturated filled pills, no competing colors β€” the session area is chrome, not content.
  • Signed out β†’ the spot stays empty: the auto-opened modal is the door (Β§4.1), and contextual CTAs re-open it. No standing Sign-in button.
  • The top bar is position: sticky over the content scroll, with a subtle bottom border.
  • db.sm.setSecurityStateChangeCallback(...) is the single source of truth: it toggles the pill/button, closes the modal, and resets the mnemonic textarea on logout. No UI state duplicates it.

4.3 Role badges

The live role (watched reactively on the user:<address> node) renders as a quiet uppercase tag β€” tier color applied to the text (or a subtle border), never a filled background. Map ascending trust tiers to a fixed color ramp so every GenosDB app reads the same way:
TierTokenMeaning
Base / guest--text-tertiary (gray)Read-only newcomer
First earned tier--ok (green)Can write
Mid tier--accent (blue)Extra capability (e.g. publish)
Elevated tier--warn (orange)Moderation powers
Superadmin--violetRoot of trust β€” signs promotions
Permission-gated controls (a β€œNew post” button, a publish selector) show or hide from the same watched role β€” the UI reflects permissions, while the engine enforces them.

4.4 Presence & contribution: gate by degrees

Realtime collaboration surfaces are not all equal. Gate each one by the smallest trust step it actually needs β€” read-only guests stay welcome, while every contribution becomes attributable:
SurfaceRequiresWhy
Watching (content, live updates, remote cursors)NothingZero-trust guests read for free
Broadcasting yourself (camera / mic streams)A signed-in identityEveryone should know who is on screen
Contributing content (edits, messages, files)An earned write rolePersistent, signed, verified by peers
Moderating (deleting others’ content)An elevated tierSame ramp as the role badges
Two implementation rules:
  • Disable gated controls, don’t hide them (disabled + an explanatory title such as β€œSign in to share your camera”): a visible-but-locked control teaches the trust model; a missing one just looks broken.
  • Ephemeral channel traffic (GenosRTC) does not pass through the graph’s RBAC β€” the role gate on the UI keeps honest peers silent, and the signed graph remains the source of truth that corrects any transient view.

5. Page Architecture by Application Type

All layouts share the same skeleton: sidebar (brand + nav + widgets) Β· sticky top bar (identity) Β· full-height content. What changes is the content organism.
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ brand   β”‚                 [session pill]β”‚
β”‚ nav     β”‚  H1                           β”‚
β”‚         β”‚  β”Œβ”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”     β”‚
β”‚ widget: β”‚  β”‚card β”‚ β”‚card β”‚ β”‚card β”‚     β”‚
β”‚ recent  β”‚  β””β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”˜     β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
  • Responsive card grid: grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)).
  • Cards: --bg-secondary, --border-subtle, --radius-md, hover = translateY(-2px) + --border-strong. Image on top (object-fit: cover), title, two-line clamped description, footer row with author tag (mono) and owner-only actions.
  • Secondary lists (β€œlatest”, β€œrecent activity”) are sidebar widgets β€” never a fixed bottom panel.

5.2 Admin panels & dashboards

Same skeleton; content organized as stat cards first, tables second. Tables use --border-subtle row separators (no zebra striping), mono for IDs/addresses, and row actions revealed on hover. Destructive actions are always --danger outline buttons, never filled by default.

5.3 Social / chat / realtime feeds

Single centered column (max-width ~680px) for the feed; composer pinned at the natural top or bottom of the column (not fixed over content). Presence (β€œN peers online”) belongs in the top bar next to the session pill, in --text-tertiary.

5.4 Instruments & testbeds (monitors, probes, benches)

Centered narrow column (~440px), no sidebar. An uppercase eyebrow label, a large title, a one-line hint, then stat cards in a row (mono values) and proportional bars (grey track --bg-tertiary, solid --accent fill). These tools measure β€” every pixel should feel like an instrument, not a website.

Hard layout rules (learned the hard way)

  • The content column owns the full viewport height. No global fixed footers.
  • One responsive breakpoint is enough for examples: at max-width: 820px collapse to a single column (sidebar becomes a top block).
  • overflow-y lives on the content column, not on body.

6. Canonical Components

Minimal CSS contracts β€” copy and restyle only via tokens. Toast (never alert()): fixed bottom-center pill, --bg-elevated + --border-strong, slides up on .show, --danger border for errors, auto-dismiss ~3s. All operation feedback (saved, deleted, permission denied) goes through it: security errors from executeWithPermission read cleanly in a toast. Modal: native <dialog> + ::backdrop dim with slight blur; --bg-elevated, --radius-lg; backdrop-click / Esc to dismiss β€” no close Γ—. Forms: labels above fields (small, --text-secondary, 600 weight); inputs on --bg-secondary with --border-strong, focus swaps border to --accent (no outlines, no glows). Read-only fields (e.g. auto-generated slugs) drop to --text-tertiary on --bg-primary. Empty states: one sentence in --text-secondary that tells the user how to earn the change they’re looking at (e.g. β€œNo posts yet. Earn the author role and create one!”) β€” in a governance world, empty states teach the ladder. Permission hints: when a control is hidden by role, show a quiet --warn-tinted note explaining how to unlock it, instead of leaving users wondering.

7. Realtime UI Rules

  1. The DOM is the state. Subscribe once with db.map(options, callback) and let deltas mutate the interface directly β€” no mirrored arrays or Maps for a single view. (An app-wide store fed by one subscription is legitimate when many views consume the same data.)
  2. Handle all four actions explicitly β€” initial, added, updated, removed β€” each with its own branch. The canonical DOM gestures: initial β†’ append (arrives already sorted when you pass field/order), added β†’ prepend (newest by definition), updated β†’ rebuild and move to top, removed β†’ remove. The full event contract ({ id, value, edges, timestamp, action }) lives in the MAP Guide β€” reference it, don’t re-document it.
  3. Let the engine own the ordering and the window. Pass field + order instead of sorting in the app; pass $limit and let the engine emit added/removed as nodes enter or leave the window. Cursors ($after/$before) are only meaningful over an explicit field order.
  4. Live-first verification: after any data-loading change, test with two browsers β€” creation in one must appear in the other without reloads.

8. Accessibility & Semantics

  • Semantic elements: <dialog>, <nav>, <main>, <article>, <button> (never clickable <div>s).
  • Text contrast on --bg-primary meets WCAG AA with the token palette β€” don’t lighten borders/text below the provided tertiary values.
  • Every icon-only button carries aria-label.
  • No inline styles; all styling flows from CSS classes and tokens.

9. Checklist (for AIs and humans)

Before shipping a GenosDB app or example, verify:
  1. ☐ All colors/spacing/radii come from the token block β€” zero hardcoded values in components.
  2. ☐ Dark theme only; no toggle unless the product truly requires it.
  3. ☐ Login/registration lives in a centered <dialog> with the single-textarea mnemonic flow; it auto-opens on every session-less load (dismissible via backdrop/Esc β€” no Γ— button) β€” no standing Sign-in button, re-entry via contextual CTAs.
  4. ☐ Session sits top-right in the abbrAddr [role] format (mono address, quiet tag, no filled pills); signed-out leaves that spot empty.
  5. ☐ Role badges follow the gray β†’ green β†’ blue β†’ orange β†’ violet trust ramp.
  6. ☐ Addresses abbreviated + monospace; timestamps localized; remote content sanitized.
  7. ☐ Content column takes full height; secondary lists are sidebar widgets, not fixed panels.
  8. ☐ Feedback via toasts β€” no alert()/confirm() except destructive-action confirms.
  9. ☐ Realtime: one subscription, four actions handled, ordering/window delegated to the engine.
  10. ☐ Presence gated by degrees: watch anonymously · broadcast with an identity · contribute with an earned role (gated controls disabled, not hidden).
  11. ☐ Verified live with two browsers.

Where this guide fits

  • Token values and component contracts here are the reference implementation targets for the official examples and testbeds.
  • Method-level identity flows: SM API Reference Β· query/realtime contracts: MAP Guide Β· pagination: Cursor-Based Pagination.

Build docs developers (and LLMs) love