Privy
Design systemDashboard & workspace patterns

Profile

Name
Guritno Adi
Role
Workspace admin
Workspace
PT Innovation (Demo)

This is a sample profile for the navigation preview.

Log out?

Sign out of this navigation preview. Your actual session will stay active.

01 / FOUNDATION

A familiar foundation.

A working reference for interfaces that feel like Privy. Built from the components in Official Account Hermod.

#
APPLICATION DESIGN SYSTEMVersion 1.0 · 26 October 2026

One language.
Every interaction.

Warm surfaces. Clear hierarchy. Confident actions. Explore the foundations and reusable patterns behind our workspace.

DM SansTypographyLight + darkSemantic themesNative HTMLFramework independent
PIPT InnovationWorkspace
YOUR CUSTOMERSEnterprise Account
Active
NS
Nusantara StudioEnterprise account · NS001
Clear by default

Labels, status and actions explain what happens next.

Warm, with restraint

Beige and burgundy bring identity to daily work.

Consistent in every state

Keyboard, small screens and errors are part of the design.

START HERE

Getting started

Open the catalogue, choose a pattern, and keep your changes documented.

#

New to the design system?

Follow the quick guide to explore components, preview full pages, and reuse the project's visual rules.

Updating a component?

Update its specimen and guideline together, then run synchronization and the relevant checks.

02 / FOUNDATION

Color & geometry

Primitive → semantic → component. Change a role once, and every component follows.

#
Privy Red--pv-red#e60034
Heartful Burgundy--pv-burgundy#430a23
Clear Beige--pv-beige#f2e8dd
Canvas--pv-canvasvar(--pv-warm-50)
Surface--pv-surfacevar(--pv-white)
Muted--pv-mutedvar(--pv-warm-100)
Primary text--pv-textvar(--pv-warm-900)
Secondary text--pv-secondaryvar(--pv-warm-600)

Semantic states

ConfirmedAcceptedUnknownRejected

Accepted means received for processing. It does not mean delivered.

Space & shape

999px · control16px · card18px · dialog

Spacing: 4 / 8 / 12 / 16 / 20 / 24 / 32 / 48 px.

View HTML Copy this specimen
<div class="swatch-grid"><div class="swatch"><div style="background:var(--pv-red)" aria-hidden="true"></div><strong>Privy Red</strong><code>--pv-red</code><small>#e60034</small></div><div class="swatch"><div style="background:var(--pv-burgundy)" aria-hidden="true"></div><strong>Heartful Burgundy</strong><code>--pv-burgundy</code><small>#430a23</small></div><div class="swatch"><div style="background:var(--pv-beige)" aria-hidden="true"></div><strong>Clear Beige</strong><code>--pv-beige</code><small>#f2e8dd</small></div><div class="swatch"><div style="background:var(--pv-canvas)" aria-hidden="true"></div><strong>Canvas</strong><code>--pv-canvas</code><small>var(--pv-warm-50)</small></div><div class="swatch"><div style="background:var(--pv-surface)" aria-hidden="true"></div><strong>Surface</strong><code>--pv-surface</code><small>var(--pv-white)</small></div><div class="swatch"><div style="background:var(--pv-muted)" aria-hidden="true"></div><strong>Muted</strong><code>--pv-muted</code><small>var(--pv-warm-100)</small></div><div class="swatch"><div style="background:var(--pv-text)" aria-hidden="true"></div><strong>Primary text</strong><code>--pv-text</code><small>var(--pv-warm-900)</small></div><div class="swatch"><div style="background:var(--pv-secondary)" aria-hidden="true"></div><strong>Secondary text</strong><code>--pv-secondary</code><small>var(--pv-warm-600)</small></div></div><div class="grid two"><article class="specimen"><h3>Semantic states</h3><div class="row wrap"><span class="badge success"><span class="dot" aria-hidden="true"></span>Confirmed</span><span class="badge info"><span class="dot" aria-hidden="true"></span>Accepted</span><span class="badge warning"><span class="dot" aria-hidden="true"></span>Unknown</span><span class="badge error"><span class="dot" aria-hidden="true"></span>Rejected</span></div><p class="muted">Accepted means received for processing. It does not mean delivered.</p></article><article class="specimen"><h3>Space & shape</h3><div class="row wrap shape-samples"><span class="shape pill">999px · control</span><span class="shape card-shape">16px · card</span><span class="shape dialog-shape">18px · dialog</span></div><p class="muted">Spacing: 4 / 8 / 12 / 16 / 20 / 24 / 32 / 48 px.</p></article></div>
03 / FOUNDATION

Typography & content

DM Sans is the implemented project font. The older brand proposal names Google Sans Flex; this kit follows the running application.

#
PAGE · 24 / 32 · 600

Make the next step clear.

SECTION · 20 / 28 · 600

A little structure goes a long way.

SUBHEADING · 16 / 24 · 600

Everything in its right place.

BODY · 14 / 20 · 400

Use familiar words, short sentences, and a useful next action.

METADATA · 12 / 18 · 400Updated 26 October 2026 at 10:30

Inline semantics

Important, emphasized, highlighted, outdated, removed, added, H2O, 102, API, request_id, ⌘ + K.

Show the outcome the service can actually confirm.Product interface principle

Saved as a draft is clearer than a vague success message.

Macro: a reusable reply. . 25 tickets. PrivyID. ABC. 日day.

Structured content

  • Use one primary action.
  • Keep labels visible.
  1. Review the content.
  2. Confirm the recipient.
Owner
Example workspace
State
Draft
Example support team
support@example.com
status: "accepted"
request_id: "example-id"

Ready to preview · n recipients · Read usage guidance

View HTML Copy this specimen

<div class="specimen type-scale"><div><span class="eyebrow">PAGE · 24 / 32 · 600</span><p class="type-page">Make the next step clear.</p></div><div><span class="eyebrow">SECTION · 20 / 28 · 600</span><p class="type-section">A little structure goes a long way.</p></div><div><span class="eyebrow">SUBHEADING · 16 / 24 · 600</span><p class="type-subheading">Everything in its right place.</p></div><div><span class="eyebrow">BODY · 14 / 20 · 400</span><p>Use familiar words, short sentences, and a useful next action.</p></div><div><span class="eyebrow">METADATA · 12 / 18 · 400</span><small>Updated 26 October 2026 at 10:30</small></div></div>
<div class="grid two"><article class="specimen prose"><h3>Inline semantics</h3><p><strong>Important</strong>, <em>emphasized</em>, <mark>highlighted</mark>, <s>outdated</s>, <del>removed</del>, <ins>added</ins>, H<sub>2</sub>O, 10<sup>2</sup>, <abbr title="Application Programming Interface">API</abbr>, <code>request_id</code>, <kbd>⌘</kbd> + <kbd>K</kbd>.</p><blockquote>Show the outcome the service can actually confirm.<cite>Product interface principle</cite></blockquote><p><q>Saved as a draft</q> is clearer than a vague success message.</p><p><dfn>Macro</dfn>: a reusable reply. <time datetime="2026-10-26">26 October 2026</time>. <data value="25">25 tickets</data>. <bdi>PrivyID</bdi>. <bdo dir="rtl">ABC</bdo>. <ruby>日<rt>day</rt></ruby>.</p></article><article class="specimen prose"><h3>Structured content</h3><ul><li>Use one primary action.</li><li>Keep labels visible.</li></ul><ol><li>Review the content.</li><li>Confirm the recipient.</li></ol><dl><dt>Owner</dt><dd>Example workspace</dd><dt>State</dt><dd>Draft</dd></dl><address>Example support team<br>support@example.com</address><pre><code>status: "accepted"
request_id: "example-id"</code></pre><p><samp>Ready to preview</samp> · <var>n</var> recipients · <a href="#guidance">Read usage guidance</a></p></article></div>
04 / COMPONENT LIBRARY

Buttons & iconography

Match heights within an action group. Reserve the red primary action for the main next step.

#

Action hierarchy

Sizes & states

Icon-only controls need an accessible name.

Project icon set

support
comment
lock
panel-left-close
panel-left-open
maximize
minimize
chart
activity
bell
zap
smile
frown
book
home
accounts
broadcast
plus
arrow
back
search
check
chevron
down
building
briefcase
info
help
shield
edit
clock
logout
menu
more-vertical
sun
moon
file
copy
image
video
audio
play
close
trash
bold
italic
underline
strike
code
code-block
bullets
numbered
link
clear-format
View HTML Copy this specimen

<div class="grid two"><article class="specimen"><h3>Action hierarchy</h3><div class="row wrap"><button type="button" class="button primary" data-open="account-dialog">Create account</button><button type="button" class="button secondary" data-toast="Demo action cancelled.">Cancel</button><button type="button" class="button outline" data-toast="Demo data is up to date."><svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M22 12h-4l-3 9-6-18-3 9H2"/></svg> Sync Data</button><button type="button" class="button ghost" data-toast="See the Guidelines section for usage rules.">Learn more <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M5 12h14 M13 6l6 6-6 6"/></svg></button><button type="button" class="button danger" data-open="confirm-dialog"><svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M3 6h18 M9 6V3h6v3 M5 6l1 15h12l1-15 M10 10v7 M14 10v7"/></svg> Delete</button></div></article><article class="specimen"><h3>Sizes & states</h3><div class="row wrap"><button type="button" class="button secondary compact" data-toast="Compact: 36px minimum height.">Compact</button><button type="button" class="button primary" data-toast="Default: 44px minimum height.">Default · 44px</button><button type="button" class="button primary" disabled>Disabled</button><button type="button" class="button primary" disabled aria-busy="true"><span class="spinner" aria-hidden="true"></span> Saving…</button></div><div class="row wrap"><button type="button" class="button icon-button" aria-label="Add item" data-toast="Demo item added."><svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M12 5v14 M5 12h14"/></svg></button><button type="button" class="button icon-button" aria-label="Copy reference" data-copy="PRIVY-EXAMPLE-001"><svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M8 8h12v13H8z M16 8V3H4v13h4"/></svg></button><span class="muted">Icon-only controls need an accessible name.</span></div></article></div><article class="specimen"><h3>Project icon set</h3><div class="icon-grid"><div><svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M4 5h16v12H9l-5 4z M8 9h8 M8 13h5"/></svg><small>support</small></div><div><svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M21 11.5a8.4 8.4 0 0 1-.9 3.8 8.5 8.5 0 0 1-7.6 4.7 8.4 8.4 0 0 1-3.8-.9L3 21l1.9-5.7a8.4 8.4 0 0 1-.9-3.8 8.5 8.5 0 0 1 4.7-7.6 8.4 8.4 0 0 1 3.8-.9h.5a8.5 8.5 0 0 1 8 8z"/></svg><small>comment</small></div><div><svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M5 11h14v10H5z M8 11V7a4 4 0 1 1 8 0v4 M12 15v2"/></svg><small>lock</small></div><div><svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M3 4h18v16H3z M9 4v16 M15 9l-3 3 3 3"/></svg><small>panel-left-close</small></div><div><svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M3 4h18v16H3z M9 4v16 M15 9l3 3-3 3"/></svg><small>panel-left-open</small></div><div><svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M8 3H5a2 2 0 0 0-2 2v3 M16 3h3a2 2 0 0 1 2 2v3 M21 16v3a2 2 0 0 1-2 2h-3 M3 16v3a2 2 0 0 0 2 2h3"/></svg><small>maximize</small></div><div><svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M8 3v5H3 M16 3v5h5 M21 16h-5v5 M3 16h5v5"/></svg><small>minimize</small></div><div><svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M3 3v18h18 M8 16v-5 M13 16V6 M18 16V9"/></svg><small>chart</small></div><div><svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M22 12h-4l-3 9-6-18-3 9H2"/></svg><small>activity</small></div><div><svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M18 8a6 6 0 0 0-12 0c0 7-3 7-3 9h18c0-2-3-2-3-9 M10 21h4"/></svg><small>bell</small></div><div><svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M13 2 3 14h9l-1 8 10-12h-9z"/></svg><small>zap</small></div><div><svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M22 12a10 10 0 1 1-20 0 10 10 0 0 1 20 0 M8 14s1.5 2 4 2 4-2 4-2 M9 9h.01 M15 9h.01"/></svg><small>smile</small></div><div><svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M22 12a10 10 0 1 1-20 0 10 10 0 0 1 20 0 M8 16s1.5-2 4-2 4 2 4 2 M9 9h.01 M15 9h.01"/></svg><small>frown</small></div><div><svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M4 19.5A2.5 2.5 0 0 1 6.5 17H20 M6.5 2H20v20H6.5A2.5 2.5 0 0 1 4 19.5v-15A2.5 2.5 0 0 1 6.5 2Z"/></svg><small>book</small></div><div><svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="m3 10 9-7 9 7 M5 9v12h14V9 M9 21v-7h6v7"/></svg><small>home</small></div><div><svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2 M16 3a4 4 0 0 1 0 8 M22 21v-2a4 4 0 0 0-3-3.87 M13 7a4 4 0 1 1-8 0 4 4 0 0 1 8 0"/></svg><small>accounts</small></div><div><svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="m3 11 18-7v16L3 14z M7 15l2 6h4l-3-7 M3 11v3"/></svg><small>broadcast</small></div><div><svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M12 5v14 M5 12h14"/></svg><small>plus</small></div><div><svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M5 12h14 M13 6l6 6-6 6"/></svg><small>arrow</small></div><div><svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M19 12H5 M11 6l-6 6 6 6"/></svg><small>back</small></div><div><svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M21 21l-5-5 M18 10a8 8 0 1 1-16 0 8 8 0 0 1 16 0"/></svg><small>search</small></div><div><svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="m5 12 4 4L19 6"/></svg><small>check</small></div><div><svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="m9 5 7 7-7 7"/></svg><small>chevron</small></div><div><svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="m6 9 6 6 6-6"/></svg><small>down</small></div><div><svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M4 22V4h12v18 M16 10h4v12 M8 8h4 M8 12h4 M8 16h4 M2 22h20"/></svg><small>building</small></div><div><svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M3 7h18v14H3z M8 7V4h8v3 M3 12h18 M10 12v2h4v-2"/></svg><small>briefcase</small></div><div><svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M12 16v-4 M12 8h.01 M22 12a10 10 0 1 1-20 0 10 10 0 0 1 20 0"/></svg><small>info</small></div><div><svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M12 18h.01 M9.5 9a2.5 2.5 0 1 1 4.3 1.8c-.9.9-1.8 1.2-1.8 2.7 M22 12a10 10 0 1 1-20 0 10 10 0 0 1 20 0"/></svg><small>help</small></div><div><svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="m12 3 8 4v6c0 5-8 9-8 9s-8-4-8-9V7z m-4 9 3 3 5-5"/></svg><small>shield</small></div><div><svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="m16 3 5 5-12 12-6 1 1-6z M14 5l5 5"/></svg><small>edit</small></div><div><svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M12 6v6l4 2 M22 12a10 10 0 1 1-20 0 10 10 0 0 1 20 0"/></svg><small>clock</small></div><div><svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M9 3H3v18h6 M9 12h12 M17 8l4 4-4 4"/></svg><small>logout</small></div><div><svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M4 6h16 M4 12h16 M4 18h16"/></svg><small>menu</small></div><div><svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M12 5h.01 M12 12h.01 M12 19h.01"/></svg><small>more-vertical</small></div><div><svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M12 8a4 4 0 1 0 0 8 4 4 0 0 0 0-8 M12 2v2 M12 20v2 M2 12h2 M20 12h2 M5 5l1.5 1.5 M17.5 17.5 19 19 M5 19l1.5-1.5 M17.5 6.5 19 5"/></svg><small>sun</small></div><div><svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M21 13a9 9 0 1 1-10-10 7 7 0 0 0 10 10Z"/></svg><small>moon</small></div><div><svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M14 2H5v20h14V7z M14 2v5h5 M8 12h8 M8 16h6"/></svg><small>file</small></div><div><svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M8 8h12v13H8z M16 8V3H4v13h4"/></svg><small>copy</small></div><div><svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M4 4h16v16H4z M4 15l5-5 4 4 3-3 4 4 M14 8h.01"/></svg><small>image</small></div><div><svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M3 4h18v16H3z M10 8l6 4-6 4z"/></svg><small>video</small></div><div><svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M9 18V5l12-2v13 M9 18a3 3 0 1 1-6 0 3 3 0 0 1 6 0 M21 16a3 3 0 1 1-6 0 3 3 0 0 1 6 0"/></svg><small>audio</small></div><div><svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="m8 5 12 7-12 7z"/></svg><small>play</small></div><div><svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="m6 6 12 12 M18 6 6 18"/></svg><small>close</small></div><div><svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M3 6h18 M9 6V3h6v3 M5 6l1 15h12l1-15 M10 10v7 M14 10v7"/></svg><small>trash</small></div><div><svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M6 4h7a4 4 0 0 1 0 8H6z M6 12h8a4 4 0 0 1 0 8H6z"/></svg><small>bold</small></div><div><svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M10 4h10 M4 20h10 M15 4 9 20"/></svg><small>italic</small></div><div><svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M6 4v7a6 6 0 0 0 12 0V4 M4 21h16"/></svg><small>underline</small></div><div><svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M17 5c-2-2-9-2-10 2s3 5 5 5 M7 17c2 3 10 3 10-1 M3 12h18"/></svg><small>strike</small></div><div><svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="m8 7-5 5 5 5 M16 7l5 5-5 5"/></svg><small>code</small></div><div><svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M3 3h18v18H3z m7 5-4 4 4 4 m4-8 4 4-4 4"/></svg><small>code-block</small></div><div><svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M9 6h12 M9 12h12 M9 18h12 M3 6h.01 M3 12h.01 M3 18h.01"/></svg><small>bullets</small></div><div><svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M10 6h11 M10 12h11 M10 18h11 M3 3h2v6 M3 9h4 M3 14c0-2 4-2 4 0s-4 3-4 5h4"/></svg><small>numbered</small></div><div><svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="m10 13 4-4 M8 16l-1 1a4 4 0 0 1-6-6l4-4a4 4 0 0 1 6 0 M13 7l1-1a4 4 0 0 1 6 6l-4 4a4 4 0 0 1-6 0"/></svg><small>link</small></div><div><svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M4 4h16 M12 4v12 M8 20h5 m3-4 5 5 m0-5-5 5"/></svg><small>clear-format</small></div></div></article>
05 / COMPONENT LIBRARY

Inputs & forms

Single-line controls use a full pill radius. Textareas keep a readable 20px radius and can grow vertically.

#

Contact details

Required fields are marked *
Do not include passwords or one-time passcodes.

Field states

Use an address such as name@example.com.

Search, password & upload

PDF, JPG, or PNG. Local preview only; no upload.
Hidden inputHidden values are not authorization.
View HTML Copy this specimen

<form class="specimen" id="sample-form" novalidate><div class="row spread"><h3>Contact details</h3><span class="muted">Required fields are marked *</span></div><div class="grid two"><div class="field"><label for="contact-name">Full name <span class="required" aria-hidden="true">*</span></label><input id="contact-name" name="name" autocomplete="name" required placeholder="Enter full name" aria-describedby="name-error"><small id="name-error" class="field-error" hidden>Enter a full name.</small></div><div class="field"><label for="contact-email">Email address <span class="required" aria-hidden="true">*</span></label><input id="contact-email" name="email" type="email" autocomplete="email" required placeholder="name@example.com" aria-describedby="email-error"><small id="email-error" class="field-error" hidden>Enter a valid email address.</small></div><div class="field"><label for="field-phone-number">Phone number</label><input id="field-phone-number" type="tel" autocomplete="tel" placeholder="08… or +62…"></div><div class="field"><label for="field-website">Website</label><input id="field-website" type="url" placeholder="https://example.com"></div></div><div class="field"><label for="message">Message <span class="optional">Optional</span></label><textarea id="message" name="message" rows="5" placeholder="Add context for the team…"></textarea><small>Do not include passwords or one-time passcodes.</small></div><div class="form-actions"><button type="reset" class="button secondary">Reset</button><button type="submit" class="button primary">Save details</button></div><p class="form-result" id="form-result" role="status"></p></form>
<div class="grid two"><article class="specimen"><h3>Field states</h3><div class="field"><label for="field-default">Default</label><input id="field-default" type="text" placeholder="Enter a value"></div><div class="field"><label for="field-read-only">Read only</label><input id="field-read-only" type="text" value="PRIVY001" readonly></div><div class="field"><label for="field-disabled">Disabled</label><input id="field-disabled" type="text" value="Unavailable" disabled></div><div class="field"><label for="invalid-email">Error state</label><input id="invalid-email" type="email" value="not-an-email" aria-invalid="true" aria-describedby="invalid-help"><small class="field-error" id="invalid-help">Use an address such as name@example.com.</small></div></article><article class="specimen"><h3>Search, password & upload</h3><div class="field"><label for="search-example">Search</label><div class="search"><span><svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M21 21l-5-5 M18 10a8 8 0 1 1-16 0 8 8 0 0 1 16 0"/></svg></span><input id="search-example" type="search" placeholder="Search ticket, PrivyID, or name…"></div></div><div class="field"><label for="password">Password</label><div class="password-control"><input id="password" type="password" autocomplete="new-password" value="sample-password"><button type="button" class="icon-button" id="toggle-password" aria-label="Show password" aria-pressed="false"><svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M5 11h14v10H5z M8 11V7a4 4 0 1 1 8 0v4 M12 15v2"/></svg></button></div></div><div class="field"><label for="upload">NPWP document</label><input id="upload" type="file" accept=".pdf,.jpg,.png"><small id="upload-name">PDF, JPG, or PNG. Local preview only; no upload.</small></div><label class="field">Hidden input<input type="hidden" name="example-token" value="demo-only"><small>Hidden values are not authorization.</small></label></article></div>
06 / COMPONENT LIBRARY

Selection & native controls

Use native controls first, with visible labels and a consistent focus treatment.

#
Topics Multiple selection
Notification preferences
Audience
Preview only; brand tokens remain unchanged.

Date, time & numeric inputs

Native picker appearance varies by browser. Always state the scheduling timezone in production.

View HTML Copy this specimen

<div class="grid two"><article class="specimen"><div class="field"><label for="business-field">Business field</label><select id="business-field"><option value="">Select business field</option>Technology</option>Financial services</option>Retail</option></select></div><div class="field"><label for="grouped-select">Assign team</label><select id="grouped-select"><optgroup label="Customer operations"><option>Customer Support</option><option>Enterprise Support</option></optgroup><optgroup label="Engineering"><option>Platform</option></optgroup></select></div><div class="field"><span class="field-label">Topics <span class="optional">Multiple selection</span></span><div id="multi-select" class="topic-choices" role="group" aria-label="Topics, multiple selection"><label class="topic-choice"><input type="checkbox" name="topics" value="Account"><span>Account</span></label><label class="topic-choice"><input type="checkbox" name="topics" value="Verification"><span>Verification</span></label><label class="topic-choice"><input type="checkbox" name="topics" value="Document signing"><span>Document signing</span></label></div></div><div class="field"><label for="city">City autocomplete</label><input id="city" list="cities" placeholder="Type a city"><datalist id="cities"><option value="Jakarta"><option value="Yogyakarta"><option value="Surabaya"></datalist></div></article><article class="specimen"><fieldset><legend>Notification preferences</legend><label class="choice"><input type="checkbox" checked> Email notifications</label><label class="choice"><input type="checkbox"> Browser notifications</label><label class="choice"><input type="checkbox" disabled> SMS notifications unavailable</label></fieldset><fieldset><legend>Audience</legend><label class="choice"><input type="radio" name="audience" checked> All enterprise members</label><label class="choice"><input type="radio" name="audience"> Selected members</label></fieldset><label class="switch"><input type="checkbox" role="switch" checked><span aria-hidden="true"></span> Enable e-seal and stamp feature</label><div class="field range-field"><label for="volume">Volume <output for="volume" id="volume-value">60%</output></label><input id="volume" type="range" min="0" max="100" value="60"></div><div class="field"><label for="accent">Accent preview</label><input id="accent" type="color" value="#e60034"><small>Preview only; brand tokens remain unchanged.</small></div></article></div><article class="specimen"><h3>Date, time & numeric inputs</h3><div class="grid three"><div class="field"><label for="field-quantity">Quantity</label><input id="field-quantity" type="number" min="1" max="500" value="25"></div><div class="field"><label for="field-date">Date</label><input id="field-date" type="date" value="2026-10-26"></div><div class="field"><label for="field-time">Time</label><input id="field-time" type="time" value="10:30"></div><div class="field"><label for="field-schedule">Schedule</label><input id="field-schedule" type="datetime-local" value="2026-10-26T10:30"></div><div class="field"><label for="field-month">Month</label><input id="field-month" type="month" value="2026-10"></div><div class="field"><label for="field-week">Week</label><input id="field-week" type="week" value="2026-W44"></div></div><p class="muted">Native picker appearance varies by browser. Always state the scheduling timezone in production.</p></article>
08 / COMPONENT LIBRARY

Tables, cards & identity

Keep the object, owner, status, and next action visible. Use a scroll region for tables on small screens.

#

Enterprise accounts

3 accounts
Example enterprise accounts and status
CompanyPrivyIDStatusAction
NSNusantara StudioNS001Active
PIPT InnovationPI002Pending
ADAwan DigitalAD003Inactive
Sample data · no connected accounts
Account

Get started with your account

Help customers access their workspace and find the right team.


Read article
YOUR WORKSPACE

24Active

Open tickets

An example metric, not live reporting.

Avatars & chips

ALNSPI
Account Verification
View HTML Copy this specimen

<article class="specimen table-specimen"><div class="row spread"><h3>Enterprise accounts</h3><span class="badge neutral"><span class="dot" aria-hidden="true"></span>3 accounts</span></div><div class="table-scroll" role="region" aria-label="Enterprise account table" tabindex="0"><table><caption class="sr-only">Example enterprise accounts and status</caption><thead><tr><th scope="col">Company</th><th scope="col">PrivyID</th><th scope="col">Status</th><th scope="col">Action</th></tr></thead><tbody><tr><th scope="row"><span class="identity"><span class="avatar small">NS</span>Nusantara Studio</span></th><td><code>NS001</code></td><td><span class="badge success"><span class="dot" aria-hidden="true"></span>Active</span></td><td><button type="button" class="button ghost compact" data-toast="Demo account: Nusantara Studio.">View <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M5 12h14 M13 6l6 6-6 6"/></svg></button></td></tr><tr><th scope="row"><span class="identity"><span class="avatar small">PI</span>PT Innovation</span></th><td><code>PI002</code></td><td><span class="badge warning"><span class="dot" aria-hidden="true"></span>Pending</span></td><td><button type="button" class="button ghost compact" data-toast="Demo account: PT Innovation.">View <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M5 12h14 M13 6l6 6-6 6"/></svg></button></td></tr><tr><th scope="row"><span class="identity"><span class="avatar small">AD</span>Awan Digital</span></th><td><code>AD003</code></td><td><span class="badge neutral"><span class="dot" aria-hidden="true"></span>Inactive</span></td><td><button type="button" class="button ghost compact" data-toast="Demo account: Awan Digital.">View <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M5 12h14 M13 6l6 6-6 6"/></svg></button></td></tr></tbody><tfoot><tr><td colspan="4">Sample data · no connected accounts</td></tr></tfoot></table></div></article><div class="grid three"><article class="specimen resource-card"><span class="tile-icon"><svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M4 19.5A2.5 2.5 0 0 1 6.5 17H20 M6.5 2H20v20H6.5A2.5 2.5 0 0 1 4 19.5v-15A2.5 2.5 0 0 1 6.5 2Z"/></svg></span><span class="badge neutral"><span class="dot" aria-hidden="true"></span>Account</span><h3>Get started with your account</h3><p class="muted">Help customers access their workspace and find the right team.</p><hr><a href="#overlays">Read article <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M5 12h14 M13 6l6 6-6 6"/></svg></a></article><article class="specimen"><span class="eyebrow">YOUR WORKSPACE</span><p class="metric">24<span class="badge success">Active</span></p><h3>Open tickets</h3><p class="muted">An example metric, not live reporting.</p></article><article class="specimen"><h3>Avatars & chips</h3><div class="row wrap"><span class="avatar small">AL</span><span class="avatar">NS</span><span class="avatar large">PI</span></div><div class="row wrap"><span class="chip">Account <button type="button" class="button chip-close" aria-label="Remove Account filter" data-remove-chip><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="m6 6 12 12 M18 6 6 18"/></svg></button></span><span class="chip">Verification <button type="button" class="button chip-close" aria-label="Remove Verification filter" data-remove-chip><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="m6 6 12 12 M18 6 6 18"/></svg></button></span></div></article></div>
09 / COMPONENT LIBRARY

Status & feedback

Use words as well as color. Errors explain recovery; unknown outcomes never pretend to be success.

#

Inline notices

Ready for review

Check the message before sending.

Changes saved

Your workspace details are up to date.

Outcome unconfirmed

Refresh before retrying the action.

Could not load data

Check your connection and try again.

Progress & loading

65%65% complete75 of 100

No tickets in this queue

New conversations will appear here.

Access required

Ask your workspace administrator for permission.

View guidance
View HTML Copy this specimen

<div class="grid two"><article class="specimen"><h3>Inline notices</h3><div class="notice info"><span><svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M12 16v-4 M12 8h.01 M22 12a10 10 0 1 1-20 0 10 10 0 0 1 20 0"/></svg></span><div><strong>Ready for review</strong><p>Check the message before sending.</p></div><button type="button" class="button icon-button" aria-label="Dismiss Ready for review notice" data-dismiss><svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="m6 6 12 12 M18 6 6 18"/></svg></button></div><div class="notice success"><span><svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="m5 12 4 4L19 6"/></svg></span><div><strong>Changes saved</strong><p>Your workspace details are up to date.</p></div><button type="button" class="button icon-button" aria-label="Dismiss Changes saved notice" data-dismiss><svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="m6 6 12 12 M18 6 6 18"/></svg></button></div><div class="notice warning"><span><svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M12 6v6l4 2 M22 12a10 10 0 1 1-20 0 10 10 0 0 1 20 0"/></svg></span><div><strong>Outcome unconfirmed</strong><p>Refresh before retrying the action.</p></div><button type="button" class="button icon-button" aria-label="Dismiss Outcome unconfirmed notice" data-dismiss><svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="m6 6 12 12 M18 6 6 18"/></svg></button></div><div class="notice error"><span><svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M12 16v-4 M12 8h.01 M22 12a10 10 0 1 1-20 0 10 10 0 0 1 20 0"/></svg></span><div><strong>Could not load data</strong><p>Check your connection and try again.</p></div><button type="button" class="button icon-button" aria-label="Dismiss Could not load data notice" data-dismiss><svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="m6 6 12 12 M18 6 6 18"/></svg></button></div></article><article class="specimen"><h3>Progress & loading</h3><label for="upload-progress">Uploading document</label><progress id="upload-progress" value="65" max="100">65%</progress><small>65% complete</small><label for="capacity">Account capacity</label><meter id="capacity" value="75" min="0" max="100" low="30" high="85" optimum="50">75 of 100</meter><div class="skeleton" role="status" aria-label="Loading example"><span class="skeleton-circle"></span><span><i></i><i></i></span></div><button type="button" class="button secondary" data-toast="Changes saved. This is a demo notification.">Show notification</button></article></div><div class="grid two"><article class="specimen empty-state"><svg width="40" height="40" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M4 5h16v12H9l-5 4z M8 9h8 M8 13h5"/></svg><h3>No tickets in this queue</h3><p>New conversations will appear here.</p><button type="button" class="button primary" data-open="account-dialog"><svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M12 5v14 M5 12h14"/></svg> Create ticket</button></article><article class="specimen empty-state"><span class="tile-icon"><svg width="28" height="28" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M5 11h14v10H5z M8 11V7a4 4 0 1 1 8 0v4 M12 15v2"/></svg></span><h3>Access required</h3><p>Ask your workspace administrator for permission.</p><a class="button secondary" href="#guidance">View guidance</a></article></div>

Broadcast batch results

Partially accepted

Some recipients were accepted for processing and others were rejected. Acceptance does not confirm delivery or reading. Do not automatically resend the entire audience.

Synthetic broadcast result by batch
BatchAttemptedStatusRejected recipients
1100Accepted0
22Rejected2
View rejected recipients
  • DEMO001 · HTTP 404 · Actor not found
  • DEMO002 · HTTP 404 · Actor not found
Synthetic result · 102 recipients attempted. A single unknown batch makes the overall result unknown. No resend action is included.

Broadcast delivery results

Request completed

The broadcast request was accepted for processing. This does not confirm delivery or read status.

Request activity

  1. Submitting request…28 Oct 2026, 12:03:25 WIB (UTC+7)
  2. Accepted for processing28 Oct 2026, 12:03:26 WIB (UTC+7)
  3. Request completedDelivery request28 Oct 2026, 12:03:30 WIB (UTC+7)
Total recipients
0
Sent
0
Failed to send
0
Delivered
0
Read
0
100%

29 / 29 recipients processed.

Started
28 Oct 2026, 12:03:26 WIB
Completed
28 Oct 2026, 12:03:30 WIB
Last checked
28 Oct 2026, 12:10:02 WIB

Local fixture only. In the application, poll queued/running jobs while visible and online; refresh receipts manually after completion. Missing delivery never becomes zero counts and never hides the saved request.

10 / COMPONENT LIBRARY

Dialogs & disclosure

Dialogs share the same shell, action spacing, and close control. Use full width for content authoring.

#

Form dialog

Rounded fields, inline required marks, 24px action spacing.

Content authoring

Viewport minus 32px, with a taller content field.

Confirmation

Explain the action. Keep Cancel easy to reach.

Logout confirmation

Confirm before leaving an account. Cancel keeps the current session.

Demo only. No real session will end.

Accordion

When should I use a modal?

For a focused task that can be completed without losing the current context.

How does keyboard focus work?

Move focus into the dialog, support Escape, and return focus to its trigger.

Action disclosure

More actions

Native disclosure keeps this menu available without a framework.

Log out of your account?

You will need to sign in again to access your workspace.

This is a preview. Your actual session will stay active.

View HTML Copy this specimen
<div class="grid two"><article class="specimen"><span class="tile-icon"><svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="m16 3 5 5-12 12-6 1 1-6z M14 5l5 5"/></svg></span><h3>Form dialog</h3><p class="muted">Rounded fields, inline required marks, 24px action spacing.</p><button type="button" class="button primary" data-open="account-dialog">Create account</button></article><article class="specimen"><span class="tile-icon"><svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M4 19.5A2.5 2.5 0 0 1 6.5 17H20 M6.5 2H20v20H6.5A2.5 2.5 0 0 1 4 19.5v-15A2.5 2.5 0 0 1 6.5 2Z"/></svg></span><h3>Content authoring</h3><p class="muted">Viewport minus 32px, with a taller content field.</p><button type="button" class="button secondary" data-open="editor-dialog">Add knowledge article</button></article><article class="specimen"><span class="tile-icon"><svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M3 6h18 M9 6V3h6v3 M5 6l1 15h12l1-15 M10 10v7 M14 10v7"/></svg></span><h3>Confirmation</h3><p class="muted">Explain the action. Keep Cancel easy to reach.</p><button type="button" class="button outline" data-open="confirm-dialog">Delete example</button></article><article class="specimen" id="logout-confirmation"><span class="tile-icon"><svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M9 4H4v16h5 M9 12h12 m-4-4 4 4-4 4"/></svg></span><h3>Logout confirmation</h3><p class="muted">Confirm before leaving an account. Cancel keeps the current session.</p><button type="button" class="button outline" data-open="logout-dialog" aria-haspopup="dialog" aria-controls="logout-dialog">Log out</button><p id="logout-demo-status" class="muted demo-note" role="status">Demo only. No real session will end.</p></article></div><div class="grid two"><article class="specimen"><h3>Accordion</h3><details class="accordion"><summary>When should I use a modal?</summary><p>For a focused task that can be completed without losing the current context.</p></details><details class="accordion"><summary>How does keyboard focus work?</summary><p>Move focus into the dialog, support Escape, and return focus to its trigger.</p></details></article><article class="specimen"><h3>Action disclosure</h3><details class="action-disclosure"><summary>More actions <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="m6 9 6 6 6-6"/></svg></summary><div><button type="button" class="button ghost" data-toast="Example duplicated locally."><svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M8 8h12v13H8z M16 8V3H4v13h4"/></svg> Duplicate</button><button type="button" class="button ghost" data-open="account-dialog"><svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="m16 3 5 5-12 12-6 1 1-6z M14 5l5 5"/></svg> Rename</button></div></details><p class="muted">Native disclosure keeps this menu available without a framework.</p></article></div><dialog class="small-dialog" id="logout-dialog" aria-labelledby="logout-title" aria-describedby="logout-description logout-demo-note"><div class="dialog-header"><h2 id="logout-title">Log out of your account?</h2><button type="button" class="icon-button" data-close aria-label="Close logout confirmation"><svg class="close-icon" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" aria-hidden="true"><path d="m5 5 14 14 M19 5 5 19"/></svg></button></div><p id="logout-description">You will need to sign in again to access your workspace.</p><p id="logout-demo-note" class="muted demo-note">This is a preview. Your actual session will stay active.</p><form method="dialog" id="logout-form" class="form-actions"><button type="submit" class="button secondary" value="cancel" autofocus>Cancel</button><button type="submit" class="button primary" value="logout">Log out</button></form></dialog>
11 / COMPONENT LIBRARY

Support composer

Macros sit to the left of the reply placeholder. Press / in an empty composer to open the macro picker.

#
SJ
Samantha JasmineExample conversation
Open
Hello, I need help accessing my account.Customer · 10:30
Hi Samantha, happy to help.Agent · 10:31

Formatted message input

Select text, then choose a format.
Project markers: **bold**, ++italic++, __underline__, ~strike~, `code`.
View HTML Copy this specimen

<article class="chat-demo"><div class="chat-header"><span class="avatar small">SJ</span><div><strong>Samantha Jasmine</strong><small>Example conversation</small></div><span class="badge info"><span class="dot" aria-hidden="true"></span>Open</span></div><div class="chat-history" id="chat-history" role="log" aria-label="Demo conversation"><div class="bubble">Hello, I need help accessing my account.<small>Customer · 10:30</small></div><div class="bubble outgoing">Hi Samantha, happy to help.<small>Agent · 10:31</small></div></div><form id="composer-form" class="composer-form"><div class="composer-box"><button type="button" class="icon-button macro-trigger" id="macro-trigger" aria-label="Insert a macro" aria-expanded="false" aria-controls="macro-picker"><svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M13 2 3 14h9l-1 8 10-12h-9z"/></svg></button><label class="sr-only" for="reply">Reply to Samantha Jasmine</label><textarea id="reply" rows="3" placeholder="Reply to Samantha Jasmine…"></textarea><div class="macro-picker" id="macro-picker" hidden><strong>Insert a macro · review before sending</strong><button type="button" data-macro="Hello Samantha, thank you for contacting Privy. How can I help?">Welcome<small>Greeting</small></button><button type="button" data-macro="Your report has been received. Please share the error message and time of the issue. Do not share a password or OTP.">Confirm issue received<small>Acknowledge</small></button></div></div><div class="composer-footer"><span class="muted">Demo only · messages stay on this page</span><button type="submit" class="button primary">Send reply <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M5 12h14 M13 6l6 6-6 6"/></svg></button></div></form></article>
<article class="specimen"><div class="row spread"><h3>Formatted message input</h3><span class="muted">Select text, then choose a format.</span></div><div class="editor-tools" role="group" aria-label="Message formatting"><button type="button" class="button icon-button" data-format="**" aria-label="Bold"><svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M6 4h7a4 4 0 0 1 0 8H6z M6 12h8a4 4 0 0 1 0 8H6z"/></svg></button><button type="button" class="button icon-button" data-format="++" aria-label="Italic"><svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M10 4h10 M4 20h10 M15 4 9 20"/></svg></button><button type="button" class="button icon-button" data-format="__" aria-label="Underline"><svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M6 4v7a6 6 0 0 0 12 0V4 M4 21h16"/></svg></button><button type="button" class="button icon-button" data-format="~" aria-label="Strikethrough"><svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M17 5c-2-2-9-2-10 2s3 5 5 5 M7 17c2 3 10 3 10-1 M3 12h18"/></svg></button><button type="button" class="button icon-button" data-format="`" aria-label="Inline code"><svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="m8 7-5 5 5 5 M16 7l5 5-5 5"/></svg></button><button type="button" class="button icon-button" data-format="list" aria-label="Bulleted list"><svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M9 6h12 M9 12h12 M9 18h12 M3 6h.01 M3 12h.01 M3 18h.01"/></svg></button><button type="button" class="button icon-button" data-format="clear" aria-label="Clear formatting"><svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M4 4h16 M12 4v12 M8 20h5 m3-4 5 5 m0-5-5 5"/></svg></button></div><label class="sr-only" for="formatted-message">Formatted message</label><textarea id="formatted-message" rows="6">Hello **Samantha**, your report has been received.</textarea><small>Project markers: **bold**, ++italic++, __underline__, ~strike~, `code`.</small><div class="message-preview" id="message-preview" aria-label="Message preview"></div></article>
12 / COMPONENT LIBRARY

Media & embedded content

Preserve aspect ratios, provide alternatives, and let the user start playback.

#
Privy
Original project logo. Preserve its aspect ratio and colors.

Audio & video controls

Audio description: two short, quiet tones. No speech.

Video shell only; no sample video is attached. Replace it with approved media and captions in a product.

Canvas with an alternative

Queue volume: Monday 12, Tuesday 20, Wednesday 16.

Example queue volume: Mon 12 · Tue 20 · Wed 16. Synthetic data.

Embedded content

Provide a title and a deliberate sandbox policy.
View HTML Copy this specimen

<div class="grid two"><figure class="specimen media-figure"><picture><img src="assets/logo-privy.png" alt="Privy" width="970" height="257" loading="lazy"></picture><figcaption>Original project logo. Preserve its aspect ratio and colors.</figcaption></figure><article class="specimen"><h3>Audio & video controls</h3><audio id="sample-audio" controls preload="metadata" aria-label="Example two-tone audio"><source src="assets/sample-audio.wav" type="audio/wav">Your browser does not support audio playback.</audio><p class="muted">Audio description: two short, quiet tones. No speech.</p><video id="sample-video" controls playsinline preload="none" poster="assets/media-poster.svg" aria-label="Video control specimen"><track kind="captions" label="English" srclang="en" src="assets/sample.vtt" default>Your browser does not support video.</video><small>Video shell only; no sample video is attached. Replace it with approved media and captions in a product.</small></article></div><div class="grid two"><article class="specimen"><h3>Canvas with an alternative</h3><canvas id="sample-canvas" width="640" height="200" aria-label="Example queue volume: Monday 12, Tuesday 20, Wednesday 16">Queue volume: Monday 12, Tuesday 20, Wednesday 16.</canvas><p class="muted">Example queue volume: Mon 12 · Tue 20 · Wed 16. Synthetic data.</p></article><article class="specimen"><h3>Embedded content</h3><iframe title="Example embedded document" src="assets/embed.html" loading="lazy" sandbox></iframe><small>Provide a title and a deliberate sandbox policy.</small></article></div>
13 / COMPONENT LIBRARY

HTML element coverage

Native elements are grouped by purpose. Deprecated tags and unrelated platform APIs are not presented as product components.

#

Native action inputs


Heading level four

Heading level five
Heading level six

Preserve semantic heading order when applying compact text sizes. Attention and alternate voice retain native semantics. LongReferenceCanWrapHere.

  • Actions
  • Forms
  • This inventory is generated from the actual HTML. Document infrastructure includes html, head, meta, title, link, style, script, and template. Semantic examples include section, article, aside, header, footer, main, nav, form, and address.

    Specialized tags such as object/embed, image maps, MathML, and custom elements require a use case and separate implementation review. Native file/date/color/media control internals vary by browser.

    View HTML Copy this specimen
    <article class="specimen"><div id="element-reference"></div><p class="muted">This inventory is generated from the actual HTML. Document infrastructure includes html, head, meta, title, link, style, script, and template. Semantic examples include section, article, aside, header, footer, main, nav, form, and address.</p><noscript>Interactive demos require JavaScript. Forms, native controls, links, and this document remain readable.</noscript><template id="toast-template"><div class="toast"><span></span><button type="button" class="icon-button" aria-label="Dismiss notification">×</button></div></template><p class="muted">Specialized tags such as object/embed, image maps, MathML, and custom elements require a use case and separate implementation review. Native file/date/color/media control internals vary by browser.</p></article>
    APPLICATION NAVIGATION

    Top navbar & menu bar

    Pair a compact workspace header with clear page navigation, grouped links, and an accessible mobile menu.

    #

    Two-row header

    Privy
    PT Innovation (Demo)Workspace navigation preview
    CURRENT PAGE

    Workspace overview

    Keep the selected page visible. Use dropdowns for related destinations and a separate primary action for the page.

    Single-row header

    Privy
    PT Innovation (Demo)Workspace navigation preview

    Navigation in one bar

    Keep the logo, workspace, page menus, and search together. On smaller screens, Menu reveals the same destinations below the header.

    Single-row header · left-aligned menus & account

    Privy
    PT Innovation (Demo)Workspace navigation preview

    Left-aligned navigation with account actions

    Keep page menus beside the workspace on the left, with search and account actions on the right. Profile and logout are interactive local previews.

    Profile

    Name
    Guritno Adi
    Role
    Workspace admin
    Workspace
    PT Innovation (Demo)

    This is a sample profile for the navigation preview.

    Log out?

    Sign out of this navigation preview. Your actual session will stay active.

    Tab moves through navigation. Enter or Space opens a group; Arrow Down/Up moves through its links. Escape closes the group and restores focus. On small screens, use Menu to reveal the navigation. Links open local examples.

    APPLICATION PATTERNS

    Application navbar

    Workspace and product navigation with search, language, notifications, and account actions.

    #
    Privy
    PT Innovation (Demo) ▾
    Customer Support ▾
    Notifications 2

    Knowledge article published.

    Your export is ready.

    GA ▾
    Guritno AdiSupport adminDesign guidelines

    Local preview. Workspace and language changes affect this specimen only.

    APPLICATION PATTERNS

    Searchable dropdowns

    Filter options with the keyboard and remove selections individually.

    #

    Assign a member

    Topics with removable chips

    APPLICATION PATTERNS

    Detail drawer

    Keep context visible while viewing or editing a customer. Unsaved edits require confirmation.

    #

    Right panel on desktop; bottom sheet on mobile. Escape restores focus to the opener.

    APPLICATION PATTERNS

    Interactive data table

    Search, sort, filter, paginate, select rows, and archive selected demo records.

    #
    0 selected
    Enterprise accounts
    Account IDStatus
    WORKSPACE PATTERNS · LOCAL DEMO

    Compact page-heading summaries

    Keep three to five labeled counts near the page title, without turning them into large dashboard cards.

    #

    Users

    Manage workspace access and assigned roles.

    All synthetic workspace users · Independent of table pagination and search. A user can have more than one role; counts are not a unique-user total.

    WORKSPACE PATTERNS · LOCAL DEMO

    Table pagination & remote states

    A page-size control inside the footer, plus a local simulation of remote filtering, sorting and pagination.

    #
    Try remote-data states

    Local timer-based simulation. No API calls are made.

    Users and assigned roles. Activate a column heading to sort the full result set.
    RolesActions

    Changing page size, search, role or sort returns to page 1. Page-size selection stays available when results are empty or a request fails.

    Vue/Persona table integration recipe

    User details

    APPLICATION PATTERNS

    File upload

    Validate type and size, preview images, and retry a failed upload.

    #
    Drop documents here

    PDF, JPEG, PNG · up to 10 MB each · maximum 5 files

      Progress is simulated locally. Files are never uploaded.
      APPLICATION PATTERNS

      Date range filter

      Use a preset or an inclusive date range in Asia/Jakarta.

      #

      All dates · Asia/Jakarta (UTC+7)

      APPLICATION PATTERNS

      Tooltip & popover

      Short guidance on hover or focus; richer information in a dismissible popover.

      #
      A unique identifier for a verified Privy account.
      How roles work
      Support roles

      Agents handle tickets. Support admins manage team access.

      Read the guidance
      APPLICATION PATTERNS

      Multi-step form

      Validate each step, review the details, and confirm before discarding edits.

      #

      Three steps: Account → Preferences → Review. No backend request is made.

      APPLICATION PATTERNS

      Connection & session

      Keep failures actionable and never resend an unconfirmed mutation automatically.

      #

      APPLICATION PATTERNS

      Member lists

      Rows grow with their content. Avatars, metadata, selection, and focus remain aligned.

      #

      Choose a member to continue.

      APPLICATION PATTERNS

      Skeleton & shimmer

      Match loading placeholders to the content layout and announce loading once.

      #

      Loading preview content…

      APPLICATION PATTERNS

      Complete page examples

      Inspect the patterns together at desktop and mobile sizes.

      Open responsive preview →

      #

      Dashboard Overview

      KPI cards, operational summaries, eight reporting charts, and local downloads.

      Open example →
      Enterprise Account

      Account directory, filters, bulk actions, creation flow.

      Open example →

      Knowledge & Macros

      Searchable resource cards with formatted previews.

      Open example →

      Support Inbox

      Ticket selection, composer autofocus, macros, and local replies.

      Open example →

      Recruitment workspace

      Scoped candidates, pipeline, interviews, job forms and consent-aware talent follow-up.

      Open example →

      Contract lifecycle workspace

      Requests, documents, approvals, signing and post-signing operations.

      Open example →
      PERSONA COVERAGE

      Input groups, password & PIN

      Connected controls, show/hide password, strength feedback, and a single accessible OTP field.

      #

      Input group

      IDR.00

      Use a long, unique password.

      Strength feedback is illustrative; production needs a dedicated estimator.

      Input PIN

      Enter any six digits. This does not verify a real account.

      Inputs with units

      Keep the unit visible while editing the value.

      days
      %
      IDR
      DASHBOARD PATTERNS · LOCAL DEMO

      Dashboard input patterns

      Useful field combinations for budgets, contacts, settings and filters. All checks run locally.

      #

      Formatted amount

      Use for budgets and spending limits, with a plain numeric form value.

      IDR
      Grouping appears after editing. Enter 0–999,999,999,999; no decimals.

      Phone with country code

      Use for contact details and notification recipients.

      Enter the number without its country code or leading zero. Spaces, hyphens and parentheses are accepted.

      Formatting only. This does not verify a phone number or send a message.

      URL with format feedback

      Use for website addresses and webhook settings.

      HTTP or HTTPS. A missing protocol becomes https://. The preview does not contact the address.

      Minimum–maximum range

      Use for amount, volume and count filters.

      Whole numbers from 0 to 1,000,000. Minimum may equal maximum.

      Freeform tags

      Use for labels, categories and saved-filter keywords.

      Enter or Add tag to confirm. Paste comma-separated tags. Up to 5 tags, 24 characters each.

      Search with clear action

      Use for short directories and in-page lists.

        FORM WORKFLOWS · LOCAL DEMO

        Advanced form patterns

        Build a notification rule with repeatable fields, dependent choices and a review before saving. Nothing is sent or stored.

        #

        Notification rule

        Required fields are labeled. Changes stay in this tab.

        Form density
        Try error states

        For the rule ID, try taken (unavailable) or offline (check failed).

        1. Rule details

        Give the rule a recognizable name and a unique identifier.

        A clear name for your team.
        3–32 lowercase letters, numbers or hyphens.

        Availability is checked when you leave the field.

        2. Delivery channel

        Only the selected channel’s fields are included in the rule.

        Channel
        Keep the subject concise.
        Demo sender; no email is sent.

        3. Assignment

        Changing a parent clears its dependent choices. Lookups use local demo data.

        Choose the organization.
        Options depend on the company.
        Options depend on the division.

        Choose a company to try a dependent lookup.

        4. Escalation contacts

        Add up to five contacts. Each contact needs a name and email.

        5. Delivery preferences

        Choose retry behavior and optional reporting.

        1–5 attempts. You can also type a whole number.
        Reporting options
        No unsaved changes

        Local demo only.

        Review changes

        Compare the last saved rule with your draft.

        CONTENT TOOLS · LOCAL DEMO

        HTML & JSON editor

        Compose HTML, define template variables and inspect a local preview with sample data.

        #

        Message template

        Dark code surfaces, clear labels and a focused preview. No data is uploaded.

        HTML Content0 characters

        Use {{variable_name}} in text. Preview supports static content and inline styles; scripts, links, forms and remote assets are omitted.

        An array of unique names, types (string, number, boolean) and required flags.
        A JSON object. Required values must match the declared types.

        Local preview only. Tab moves to the next control.

        PERSONA COVERAGE

        Calendar & time picker

        An inline calendar with keyboard navigation and a time control with an explicit timezone.

        #

        Choose a date.

        Schedule a time

        09:00 · UTC+7

        PERSONA COVERAGE

        Button groups, nested menus & tour

        Grouped actions, contextual controls, nested disclosure, and an introductory walkthrough.

        #

        Button group

        List view selected.

        2 items selected

        The interactive table demonstrates bulk actions on actual demo rows.

        Dropdown subitem

        Workspace actionsManage team
        Export
        Spread: left contentRight action

        Welcome to your workspace

        PERSONA COVERAGE

        Camera & cropper

        Capture only after permission, or choose a local image. Preview and export a square crop.

        #

        Camera

        Camera is off. HTTPS or localhost may be required by your browser.

        Image cropper

        Choose an image to begin. Images stay on this device.

        PERSONA COVERAGE

        Signature & QR code

        Draw or type a signature preview, and scan a real QR code linking to the public documentation.

        #

        Draw signature

        Visual preview only. No signing or identity verification takes place.

        PERSONA COVERAGE

        PDF viewer & placement

        A local sample PDF plus a placement surface for text and signature fields.

        #
        Native PDF viewer

        Use Open sample PDF if your browser does not support embedded PDFs.

        Placement controls

        Click to add, drag to place, or move the selected field with arrow keys. Shift + arrow moves in larger steps.

        No fields placed.

        Sample agreement

        Company: PT Innovation (Demo)


        This is a synthetic one-page document for UI previews.

        Placement coordinates are local UI state. This preview does not modify or cryptographically sign the PDF.
        PERSONA COVERAGE

        Rich text editor

        Editable formatted content with a keyboard-accessible toolbar and plain-text paste.

        #

        Write a helpful answer for your customer.

        WORKSPACE PATTERNS

        Applied filters

        Combine filters, remove individual criteria, and reset the result set without losing context.

        #

          View HTML
          <article class="specimen"><form id="filter-form"><div class="grid three"><label class="field">Search tickets<input type="search" id="filter-query" placeholder="Subject or ticket ID…"></label><label class="field">Status<select id="filter-status"><option value="all">All statuses</option><option>Open</option><option>Resolved</option></select></label><label class="field">Priority<select id="filter-priority"><option value="all">All priorities</option><option>High</option><option>Normal</option></select></label></div><div class="row wrap"><button class="button primary" type="submit">Apply filters</button><button class="button secondary" type="reset">Reset</button></div></form><div id="applied-filter-chips" class="chip-list demo-note" aria-label="Applied filters"></div><p id="filter-count" class="demo-note muted" role="status"></p><ul id="filtered-tickets" class="pattern-list"></ul></article>
          WORKSPACE PATTERNS

          Tree navigation

          Navigate nested knowledge categories using arrow keys, Home/End, and type-ahead.

          #

          Knowledge library

          • Account
            • Create an account
            • Verify your identity
          • Archived articles Unavailable

          Select an article

          Expand a category, then choose an article to preview it here.

          View HTML
          <div class="grid two"><article class="specimen"><h3>Knowledge library</h3><ul id="knowledge-tree" class="pattern-tree" role="tree" aria-label="Knowledge library"><li role="treeitem" tabindex="0" aria-expanded="true" aria-selected="false" aria-labelledby="tree-account-label"><span class="tree-label" id="tree-account-label"><span aria-hidden="true">▾</span> Account</span><ul role="group"><li role="treeitem" tabindex="-1" aria-selected="false" data-resource="Create an account"><span class="tree-label">Create an account</span></li><li role="treeitem" tabindex="-1" aria-selected="false" data-resource="Verify your identity"><span class="tree-label">Verify your identity</span></li></ul></li><li role="treeitem" tabindex="-1" aria-expanded="false" aria-selected="false" aria-labelledby="tree-signing-label"><span class="tree-label" id="tree-signing-label"><span aria-hidden="true">▸</span> Document signing</span><ul role="group" hidden><li role="treeitem" tabindex="-1" aria-selected="false" data-resource="Sign a document"><span class="tree-label">Sign a document</span></li><li role="treeitem" tabindex="-1" aria-selected="false" data-resource="Check signing status"><span class="tree-label">Check signing status</span></li></ul></li><li role="treeitem" tabindex="-1" aria-selected="false" aria-disabled="true"><span class="tree-label">Archived articles <small>Unavailable</small></span></li></ul></article><article class="specimen"><h3 id="tree-preview-title">Select an article</h3><p id="tree-preview-copy">Expand a category, then choose an article to preview it here.</p><p id="tree-status" class="demo-note muted" role="status"></p></article></div>
          WORKSPACE PATTERNS

          Activity timeline

          Show who changed what and when, with a filter and explicit timestamps.

          #

          Ticket activity

            View HTML
            <article class="specimen"><div class="row wrap spread"><h3>Ticket activity</h3><label class="field">Activity type<select id="activity-filter"><option value="all">All activity</option><option value="message">Messages</option><option value="assignment">Assignments</option><option value="status">Status changes</option></select></label></div><ol id="activity-list" class="activity-list"></ol><button class="button secondary demo-note" id="activity-more">Load earlier activity</button><p id="activity-summary" class="demo-note muted" role="status"></p></article>
            WORKSPACE PATTERNS

            Notification center

            Review read and unread notifications, mark individual items, and recover from loading failures.

            #

            Notifications 2 unread

              View HTML
              <article class="specimen"><div class="row wrap spread"><h3>Notifications <span class="badge info" id="notification-count">2 unread</span></h3><button class="button secondary compact" id="notifications-read-all">Mark all as read</button></div><div class="row wrap"><label class="field grow">Show<select id="notification-filter"><option value="all">All notifications</option><option value="unread">Unread only</option></select></label><label class="field grow">Preview state<select id="notification-state"><option value="ready">Ready</option><option value="loading">Loading</option><option value="empty">Empty</option><option value="error">Error</option></select></label></div><div id="notification-content" aria-busy="false"><ul id="notification-items" class="pattern-list"></ul><p id="notification-feedback" role="status"></p></div><button class="button secondary demo-note" id="notification-retry" hidden>Retry</button></article>
              WORKSPACE PATTERNS

              Reorderable list

              Reorder macro steps by dragging or using Move up/Move down. Changes are announced and can be reset.

              #

              Macro steps

              Drag a row, use its arrow buttons, or press Alt + Up/Down on the row handle.

                Three steps. No changes saved to a server.

                View HTML
                <article class="specimen"><div class="row wrap spread"><h3>Macro steps</h3><button class="button secondary compact" id="sort-reset">Reset order</button></div><p class="muted">Drag a row, use its arrow buttons, or press Alt + Up/Down on the row handle.</p><ol id="sortable-items" class="sortable-items demo-note"></ol><p id="sort-status" class="demo-note muted" role="status">Three steps. No changes saved to a server.</p></article>
                WORKSPACE PATTERNS

                Customer satisfaction rating

                Collect a clear one-to-five rating with optional feedback and an explicit submit action.

                #
                How was your support experience?

                Choose one rating. Your response is only stored in this local preview.

                No rating selected.

                View HTML
                <form id="rating-form" class="specimen" novalidate><fieldset class="rating-fieldset" aria-describedby="rating-description rating-error"><legend>How was your support experience?</legend><p id="rating-description" class="muted">Choose one rating. Your response is only stored in this local preview.</p><div class="rating-options"><label class="rating-choice"><input type="radio" name="satisfaction" value="1" required><span class="rating-star" aria-hidden="true">★</span><span class="sr-only">1 — Very dissatisfied</span><small aria-hidden="true">1</small></label><label class="rating-choice"><input type="radio" name="satisfaction" value="2" required><span class="rating-star" aria-hidden="true">★</span><span class="sr-only">2 — Dissatisfied</span><small aria-hidden="true">2</small></label><label class="rating-choice"><input type="radio" name="satisfaction" value="3" required><span class="rating-star" aria-hidden="true">★</span><span class="sr-only">3 — Neutral</span><small aria-hidden="true">3</small></label><label class="rating-choice"><input type="radio" name="satisfaction" value="4" required><span class="rating-star" aria-hidden="true">★</span><span class="sr-only">4 — Satisfied</span><small aria-hidden="true">4</small></label><label class="rating-choice"><input type="radio" name="satisfaction" value="5" required><span class="rating-star" aria-hidden="true">★</span><span class="sr-only">5 — Very satisfied</span><small aria-hidden="true">5</small></label></div><p id="rating-value" role="status">No rating selected.</p></fieldset><label class="field demo-note">Tell us more <span class="optional">Optional</span><textarea id="rating-comment" rows="3" maxlength="300" placeholder="What could we improve?" aria-describedby="rating-counter"></textarea><small id="rating-counter">0 / 300 characters</small></label><p id="rating-error" class="field-error" role="alert"></p><div class="row wrap"><button type="submit" class="button primary" id="rating-submit">Submit feedback</button><button type="reset" class="button secondary">Reset</button></div><p id="rating-result" class="demo-note" role="status"></p></form>
                WORKSPACE PATTERNS

                Resizable split pane

                Resize a desktop detail panel with the pointer or keyboard. On small screens, panels stack vertically.

                #

                Ticket workspace

                Drag the divider or focus it and use Left/Right. Home/End selects the minimum/maximum width.

                Inbox

                Signing issue

                Select a ticket from the inbox to view its details.

                Local preview

                Inbox width: 35%.

                View HTML
                <article class="specimen"><div class="row wrap spread"><h3>Ticket workspace</h3><button class="button secondary compact" id="split-reset">Reset width</button></div><p id="split-help" class="muted">Drag the divider or focus it and use Left/Right. Home/End selects the minimum/maximum width.</p><div class="split-layout demo-note" id="split-layout"><section class="split-panel" id="split-queue" aria-labelledby="split-queue-title"><h4 id="split-queue-title">Inbox</h4><button class="member-row" data-split-ticket="Signing issue" aria-pressed="true"><span class="member-copy"><strong>Signing issue</strong><small>Samantha Jasmine · Open</small></span></button><button class="member-row" data-split-ticket="Verification request" aria-pressed="false"><span class="member-copy"><strong>Verification request</strong><small>Bani El Rehab · Pending</small></span></button></section><div id="split-divider" class="split-divider" role="separator" tabindex="0" aria-label="Inbox width" aria-orientation="vertical" aria-controls="split-queue" aria-valuemin="25" aria-valuemax="60" aria-valuenow="35" aria-valuetext="35 percent" aria-describedby="split-help"></div><section class="split-panel" aria-labelledby="split-detail-title"><h4 id="split-detail-title">Signing issue</h4><p class="demo-note">Select a ticket from the inbox to view its details.</p><span class="badge info demo-note">Local preview</span></section></div><p id="split-status" class="muted demo-note" role="status">Inbox width: 35%.</p></article>
                WORKSPACE PATTERNS

                Page states & recovery

                Error pages for missing content, access restrictions and service interruptions, plus empty and loading states.

                #

                Error pages

                A clear explanation. A useful next step.

                Companion examples
                PrivyWorkspace
                MISSING CONTENT

                We can’t find that page

                The link may be out of date, or the page may have moved. Return to your workspace to find what you need.

                404 preview selected.

                View HTML
                <article class="specimen error-pages" id="error-pages"><div class="error-pages-heading"><div><h3>Error pages</h3><p class="muted">A clear explanation. A useful next step.</p></div><span class="badge info">Companion examples</span></div><div class="error-page-options" role="group" aria-label="Choose an error page preview"><button type="button" class="error-page-option" data-error-page="400" aria-pressed="false" aria-controls="error-page-preview"><strong>400</strong><span>Bad request</span></button><button type="button" class="error-page-option" data-error-page="401" aria-pressed="false" aria-controls="error-page-preview"><strong>401</strong><span>Sign-in required</span></button><button type="button" class="error-page-option" data-error-page="403" aria-pressed="false" aria-controls="error-page-preview"><strong>403</strong><span>Access denied</span></button><button type="button" class="error-page-option" data-error-page="404" aria-pressed="true" aria-controls="error-page-preview"><strong>404</strong><span>Not found</span></button><button type="button" class="error-page-option" data-error-page="408" aria-pressed="false" aria-controls="error-page-preview"><strong>408</strong><span>Request timeout</span></button><button type="button" class="error-page-option" data-error-page="429" aria-pressed="false" aria-controls="error-page-preview"><strong>429</strong><span>Too many requests</span></button><button type="button" class="error-page-option" data-error-page="500" aria-pressed="false" aria-controls="error-page-preview"><strong>500</strong><span>Server error</span></button><button type="button" class="error-page-option" data-error-page="502" aria-pressed="false" aria-controls="error-page-preview"><strong>502</strong><span>Bad gateway</span></button><button type="button" class="error-page-option" data-error-page="503" aria-pressed="false" aria-controls="error-page-preview"><strong>503</strong><span>Unavailable</span></button><button type="button" class="error-page-option" data-error-page="504" aria-pressed="false" aria-controls="error-page-preview"><strong>504</strong><span>Gateway timeout</span></button><button type="button" class="error-page-option" data-error-page="offline" aria-pressed="false" aria-controls="error-page-preview"><strong>OFFLINE</strong><span>Offline</span></button></div><div id="error-page-preview" class="error-page-preview" role="region" aria-labelledby="error-page-title"><div class="error-page-brand"><img src="assets/logo-privy.png" alt="Privy" width="970" height="257"><span class="muted">Workspace</span></div><div class="error-page-body"><div class="error-page-art" aria-hidden="true"><svg id="error-page-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h5 M14 2v6h6v3 M14 2l6 6 M8 7h2 M8 11h4 M19 16a4 4 0 1 1-8 0 4 4 0 0 1 8 0Z M18 19l4 3"/></svg><span id="error-page-code">404</span><span id="error-page-kind">Page not found</span></div><div class="error-page-copy"><span class="eyebrow" id="error-page-category">MISSING CONTENT</span><h4 id="error-page-title">We can’t find that page</h4><p id="error-page-description">The link may be out of date, or the page may have moved. Return to your workspace to find what you need.</p><div class="error-page-actions"><button type="button" class="button primary" id="error-page-action" hidden>Try again</button><a href="examples/dashboard.html" class="button primary" id="error-page-home">Back to workspace</a></div></div></div><div class="error-page-footer"><span>Preview only · No real requests or session changes.</span><span id="error-page-reference">HTTP 404</span></div></div><p id="error-page-feedback" class="demo-note" role="status" aria-atomic="true">404 preview selected.</p></article><article class="specimen"><label class="field">Preview page state<select id="page-state"><option value="empty">First use</option><option value="filtered">No matching results</option><option value="loading">Loading</option><option value="error">Service error</option><option value="forbidden">Access required</option><option value="missing">Not found</option><option value="ready">Ready</option></select></label><div id="state-preview" class="state-preview" aria-busy="false"><div id="state-symbol" class="state-symbol" aria-hidden="true"></div><h3 id="state-title"></h3><p id="state-description" class="muted"></p><div id="state-loading" class="state-loading" hidden aria-hidden="true"><span class="pv-skeleton line"></span><span class="pv-skeleton line short"></span></div><button class="button primary" id="state-action"></button></div><p id="state-result" class="demo-note" role="status"></p></article>
                DASHBOARD BUILDING BLOCKS

                Dashboard cards & overview

                Reusable KPI, trend, chart, progress, status, activity, team, quick-action, and service-health cards.

                #
                Workspace performance

                Synthetic data for layout and interaction previews.

                Tickets createdvs previous period · demo
                Tickets resolvedvs previous period · demo
                Within SLAvs previous period · demo
                Active agentsvs previous period · demo

                Ticket volume

                Created tickets by day or week.

                View chart data
                Created tickets in the selected period
                PeriodCreated

                Resolution target

                Progress towards the team target.

                Next step

                Review unresolved tickets before the end of the period.

                Open inbox

                Recent activity

                1. Ticket assignedMaya Chen · Signing issue
                2. Article updatedAlex Morgan · Account verification
                3. Team member invitedGuritno Adi · Customer Support

                Service health

                API connectionOperationalMessage deliveryOperationalExport queueDelayed
                Illustrative statuses · no live monitoring

                Attention needed

                Requires review

                Open tickets approaching their SLA deadline.

                Review tickets
                REPORTING TOOLKIT

                Reporting, charts & downloads

                Explore the same synthetic delivery data through eight chart patterns. Every chart has an accessible data table.

                Reporting guide

                Messages sentTotal selected messages · synthetic
                Delivery rateDelivered ÷ sent
                Open rateOpened ÷ delivered · illustrative channel events

                Recent downloads

                Files generated in this tab, up to 10 entries. A browser download request does not confirm that a file was saved. No scheduled jobs or emails are created.

                No files prepared yet. Download a report or chart to get started.

                  WORKFLOW PATTERNS · LOCAL DEMO

                  Advanced data table

                  Choose and pin columns, expand records, and edit names with validation.

                  #
                  Choose columns
                  Enterprise directory · synthetic data

                  WORKFLOW PATTERNS · LOCAL DEMO

                  Saved views & advanced filters

                  Apply AND/OR criteria, save a named view, and restore its filters.

                  #

                    WORKFLOW PATTERNS · LOCAL DEMO

                    CSV import wizard

                    Map columns, review invalid or duplicate rows, and import only valid records.

                    #
                    1. 1. File
                    2. 2. Mapping
                    3. 3. Review
                    4. 4. Result

                    Local preview · UTF-8 CSV, at most 100 KB and 500 data rows. Import never uploads a file.

                    WORKFLOW PATTERNS · LOCAL DEMO

                    Background job center

                    Track queued and running jobs, cancel or retry failures, and download completed exports.

                    #

                    Simulated jobs run only while this page is open. Retry creates a new attempt; expired files require a new export.

                      WORKFLOW PATTERNS · LOCAL DEMO

                      Roles & permission matrix

                      Preview changes to feature permissions and data scope before applying them.

                      #
                      Local role permissions · workspace admin is protected
                      CapabilityWorkspace adminSupervisorAgent

                      WORKFLOW PATTERNS · LOCAL DEMO

                      Approval workflow

                      Review a request, approve or reject with a reason, and retain the decision history.

                      #

                      Broadcast approval · BR-104

                      Pending review
                      Requested by
                      Maya Chen
                      Audience
                      250 verified contacts
                      Message
                      Scheduled service update for your workspace.

                      Decision history

                        WORKFLOW PATTERNS · LOCAL DEMO

                        Recurring scheduler

                        Preview explicit timezones and upcoming runs, then pause or resume a schedule.

                        #
                        Not scheduled

                        Upcoming runs

                          WORKFLOW PATTERNS · LOCAL DEMO

                          Report drill-down & saved reports

                          Select a metric and channel to inspect matching rows; save and restore the report definition.

                          #

                          Select a metric, then a bar to inspect its records. Counts are synthetic messages.

                          All records
                          Report details
                          CampaignChannelSentDeliveredFailed

                          WORKFLOW PATTERNS · LOCAL DEMO

                          Drafts, publishing & version history

                          Autosave a local draft, publish snapshots, compare versions, and restore a version into a draft.

                          #
                          Draft

                            WORKFLOW PATTERNS · LOCAL DEMO

                            Kanban work queue

                            Assign work and move cards between columns with capacity limits and keyboard alternatives.

                            #

                            Drag a card or use its Move to control. In progress allows at most two cards.

                            WORKFLOW PATTERNS · LOCAL DEMO

                            Integration operations

                            Inspect webhook delivery attempts, explicitly retry failures, and rotate a demo API key.

                            #
                            Webhook delivery log · synthetic events
                            EventResultAttemptsActions

                            API key

                            Demo key · ••••a1b2

                            WORKFLOW PATTERNS · LOCAL DEMO

                            Profile, preferences & sessions

                            Save profile and notification preferences, choose a timezone, and revoke other demo sessions.

                            #
                            Notification preferences

                            Active sessions

                              WORKFLOW PATTERNS · LOCAL DEMO

                              Conflicts, partial results, undo & stale data

                              Preserve user work and distinguish confirmed failures from unconfirmed outcomes.

                              #

                              Concurrent editing conflict

                              Server version: Original verification steps

                              Bulk action: partial outcome

                                Time-limited undo

                                Draft: October newsletter

                                Stale data after refresh failure

                                132 open tickets

                                Last successful snapshot: 10:00 Asia/Jakarta

                                RECRUITMENT · SYNTHETIC DEMO

                                Recruitment workspace

                                Team-scoped candidates, hiring stages, profile details, pipeline and interview review.

                                #

                                Hiring workspace

                                Synthetic records · October 2026 · WIB (UTC+07:00)

                                Open full-page example

                                Role switching is a demo. Real access must be enforced by the server.

                                Metrics use the same team scope and applications received 1–31 October 2026. Filters below affect the list and board only.

                                Candidates in your permitted scope
                                Role / teamStageApplied (WIB)Actions

                                Application pipeline

                                Use Move stage or drag a card to review a transition. Rejected and Withdrawn are alternative outcomes.

                                Interview schedule & reviews

                                All times show WIB. HR and interviewer reviews stay separate.

                                Candidate profile

                                Move application

                                Required for rejection. Never included in the candidate message.

                                Interview review

                                Use factual observations. Minimum 10 characters.

                                Schedule interview

                                Times are interpreted in Asia/Jakarta, UTC+07:00.

                                RECRUITMENT · SYNTHETIC DEMO

                                Job openings & forms

                                Draft, publish or close a scoped opening using a reusable job form.

                                #

                                Job templates and openings use the team scope selected in Hiring workspace. Only Published openings accept applications.

                                Create or edit an opening

                                Nothing is published outside this demo.

                                RECRUITMENT · SYNTHETIC DEMO

                                Talent pool & saved pipeline

                                Keep future-opportunity consent, outreach and archives separate from applications.

                                #

                                Talent pool membership is separate from active applications. Future-opportunity consent is versioned separately from application consent.

                                Talent follow-up

                                Record the real interaction and date. Consent or rejection alone is not outreach.

                                CONTRACT LIFECYCLE · SYNTHETIC DEMO

                                Contract repository & workspace

                                Find, filter, inspect and report on the permitted contract portfolio.

                                #

                                Contract workspace

                                Synthetic portfolio · Snapshot 27 October 2026 · WIB

                                Open full-page example

                                All access, approval, signature and extraction events are local fixtures. No contract is sent, signed or published.

                                Saved views live in this tab. The JSON download bundles selected document text and metadata; it is not a PDF or signature certificate.

                                Metrics and exports use the same permitted, filtered contracts and fixed snapshot date. Currency totals are kept separate.

                                Contract repository
                                Counterparty / ownerValueWorkflow / signatureTerm / action

                                Workflow distribution and cycle times

                                Contract detail workspace

                                CONTRACT LIFECYCLE · SYNTHETIC DEMO

                                Contract requests, templates & metadata

                                Create a structured request, reuse approved wording and review extracted values.

                                #

                                Request a contract

                                Create a local draft with conditional fields and supporting file metadata.

                                Up to 3 PDF/DOCX files, 5 MB each. Only filenames and sizes are kept in memory.

                                  Templates & clause library

                                  Approved snippets are illustrative; they are not legal advice or a production playbook.

                                  Metadata extraction review

                                  Synthetic suggestions with source evidence. Review values and explicitly confirm selected corrections.

                                  CONTRACT LIFECYCLE · SYNTHETIC DEMO

                                  Contract review & approval

                                  Compare versions, discuss clauses and approve the exact document version.

                                  #

                                  Document workspace

                                  Plain-text contract specimen. Signed documents and in-flight envelopes are locked.

                                  Compare document versions

                                  Clause comments & negotiation

                                  Version-bound approval route

                                  Finance is required at IDR 100 million or USD 10,000 and above. This is a demo routing rule.

                                  CONTRACT LIFECYCLE · SYNTHETIC DEMO

                                  Signature preparation & tracking

                                  Prepare signer fields and inspect envelope states without sending real documents.

                                  #

                                  Prepare signature fields

                                  Select a signer, field and page; set its position using keyboard-accessible coordinates.

                                  Simulate signature provider events

                                  Fixture events only. A signature image or button click is not an electronic-signature integration.

                                  CONTRACT LIFECYCLE · SYNTHETIC DEMO

                                  Obligations, renewals & amendments

                                  Track commitments, notice deadlines and relationships after signing.

                                  #

                                  Obligations & evidence

                                  Renewal & notice calendar

                                  Related agreements & amendments

                                  The signed original remains immutable. A draft replacement does not supersede the original until signed and effective.

                                  Discard document edits?

                                  Your unsaved document text will be discarded.

                                  Complete obligation

                                  Use a factual reference. Files are not uploaded by this demo.

                                  MESSAGING · LOCAL DEMO

                                  Bot messages & request recovery

                                  Separate bot availability, message outcomes and secret handling. These fixtures do not send messages or call an API.

                                  #

                                  Bot availability & conversation

                                  Sending is available. History remains readable.

                                  1. Ana · Customer

                                    Where can I find my document?

                                    10:20 WIB
                                  2. Service Bot

                                    Your documents are available in your workspace.

                                    10:21 WIB

                                  One-time webhook secret

                                  Rotation invalidates the previous secret. Reveal it only after a successful response; closing removes it from the preview.

                                  Use a confirmation before rotation. A lost response requires reconciliation, not automatic replay.

                                  Rate-limit feedback

                                  Use the server’s Retry-After duration. Keep drafts intact and show the remaining wait without announcing every second.

                                  Recover an unconfirmed request

                                  Preserve the original review ID and exact schedule intent. Checking an unknown result reuses the same identifier; it does not create another logical send.

                                  No request yet.

                                  Rotate demo secret?

                                  The previous demo secret will stop working. No real credentials are involved.

                                  14 / COMPONENT LIBRARY

                                  Build with consistency

                                  Keep the implementation and its written contract together. A design change is not complete until both are updated.

                                  #

                                  When changing a component

                                  1. Read GUIDELINES.md and reuse semantic tokens.
                                  2. Update the example, states, and behavior in the HTML/CSS/JS.
                                  3. Update the relevant written guidance and changelog.
                                  4. Run python3 scripts/sync.py --note "Describe the change".
                                  5. Run python3 scripts/sync.py --check and test light/dark, keyboard, and mobile.

                                  Project alignment

                                  Derived from Official Account Hermod: main.css, AppIcon, SupportResources, SupportConfirmDialog, StatusBadge, and the message composer.

                                  Full-rounded fields follow the current Support forms. Native controls not yet present in the product are companion examples using the same tokens.

                                  View HTML Copy this specimen
                                  <div class="grid two"><article class="specimen"><h3>When changing a component</h3><ol class="steps-list"><li>Read <a href="GUIDELINES.md">GUIDELINES.md</a> and reuse semantic tokens.</li><li>Update the example, states, and behavior in the HTML/CSS/JS.</li><li>Update the relevant written guidance and changelog.</li><li>Run <code>python3 scripts/sync.py --note "Describe the change"</code>.</li><li>Run <code>python3 scripts/sync.py --check</code> and test light/dark, keyboard, and mobile.</li></ol></article><article class="specimen"><h3>Project alignment</h3><p>Derived from Official Account Hermod: main.css, AppIcon, SupportResources, SupportConfirmDialog, StatusBadge, and the message composer.</p><p>Full-rounded fields follow the current Support forms. Native controls not yet present in the product are companion examples using the same tokens.</p><div class="row wrap"><a class="button secondary" href="GUIDELINES.md">Guidelines</a><a class="button outline" href="CHANGELOG.md">Changelog</a><a class="button ghost" href="README.md">Getting started</a></div></article></div>

                                  Create Enterprise Account

                                  Demonstration only. No account is created.

                                  Add knowledge article

                                  Delete this example?

                                  This is a demonstration. No stored data will be removed.

                                  Search workspace

                                  Customer details

                                  Active account

                                  Enterprise ID · ENT001

                                  Create Enterprise Account

                                  1. Account
                                  2. Preferences
                                  3. Review
                                  Demo only. No account will be created.

                                  Discard unsaved changes?

                                  Your edits will be lost if you leave this form.