UI Design System

Interactive showcase of every component in the Publecto design system.
Use Ctrl+K to open the command palette.

Design Tokens

CSS custom properties that encode every visual decision. All component styles use only these tokens — never hardcoded values.

Color Palette
--color-bg-primary
--color-bg-secondary
--color-bg-elevated
--color-bg-sunken
--color-text-primary
--color-text-secondary
--color-text-disabled
--color-accent
--color-accent-hover
--color-accent-subtle
--color-danger
--color-success
--color-warning
--color-info
--color-border
--color-border-strong
--color-row-hover
--color-row-selected
--color-row-stripe
Spacing Scale (4px base)
--space-1
--space-2
--space-3
--space-4
--space-5
--space-6
--space-8
--space-10
--space-12
--space-16
Border Radius
--radius-sm 4px
--radius-base 6px
--radius-md 8px
--radius-lg 12px
--radius-full 999px
Shadows
--shadow-sm
--shadow-base
--shadow-md
--shadow-lg

Typography

Type scale using Inter (sans) and JetBrains Mono (code).

--font-size-xs The quick brown fox jumps over the lazy dog.
--font-size-sm The quick brown fox jumps over the lazy dog.
--font-size-base The quick brown fox jumps over the lazy dog.
--font-size-md The quick brown fox jumps over the lazy dog.
--font-size-lg The quick brown fox jumps over the lazy dog.
--font-size-xl The quick brown fox jumps over the lazy dog.
--font-size-2xl The quick brown fox jumps over the lazy dog.
--font-size-3xl The quick brown fox jumps over the lazy dog.
const greeting = "Hello, World!"; // JetBrains Mono

Buttons

All button variants, sizes, states, and loading behavior.

Variants
Sizes
States
With Icons
Toast Triggers

Forms

All form input types with validation states, helpers, and special controls.

Text Inputs
/posts/
Enter a valid email address
This field is not editable.
Select, Textarea & Tags
Max 160 characters recommended for SEO.
php publishing saas
Checkboxes, Radios & Toggles

Cards & Info

Total Posts
1,248
+12% vs last month
Monthly Views
48,320
-3% vs last month
Active Modules
3
Blog, Migrator, Core
Recent Activity
Last 7 days
Posts published
12
Pages updated
4
Media uploaded
38 files
Comments
91
New users
7
Published Jan 18, 2024

Platform Architecture Overview

A comprehensive look at Publecto's layered architecture — Base Foundation, Site Design, Modules, and Add-Ons.

BC
Bob Chen 2,980 views

Badges, Pills & Tags

Badges
Info Success Warning Danger Neutral Accent Solid Removable
Avatars
AM
BC
DW
ET
AM
BC
DW
+4
Pills & Tags
All Published Draft php saas open-source beta deprecated

Alerts & Banners

Post Published Successfully
Your post is now live at /posts/getting-started.
Callouts
💡 Tip
You can stage posts in "Draft" status before publishing to preview how they look.
⚠️ Caution
Deleting a module removes all its data permanently. Export first.
📝 Note
Static publishing bakes output to storage/published/static/ and can be served from any CDN.

Toast Notifications

Click the buttons to fire toasts. They auto-dismiss; pause on hover.

Modals & Dialogs

Drawers

Icon Bar Position

Move the icon bar to any edge of the shell. Top and bottom positions turn it into a horizontal strip; panel tabs and sidebar offsets adapt automatically.

Position
Label position
Icon size
Label font size
Label font family

Tooltips & Popovers

Tooltips (hover)
Popovers (click)

Collapsible Panels

Post Settings

Configure SEO metadata, publishing date, canonical URL, and Open Graph images for this post.

Edit the author bio, social links, and profile photo used on post pages.

Control caching, CDN purge behavior, static generation triggers, and webhook firing conditions.

Toolbar & Ribbon

Data Table

Fully interactive: sort columns, search, paginate, select rows, expand rows. 20 rows of sample content.

Floating Window

App Shell

The shell on this very page demonstrates the full layout: header, icon bar, left sidebar, right sidebar, main content area, and footer. Drag the sidebar handles to resize.

Try it
Drag the splitter on the right edge of the sidebar to resize. Use the icon bar to switch context. Collapse the sidebar with the ‹ button in the sidebar header. On narrow viewports the sidebar slides off-canvas; use the hamburger menu.

i18n & RTL

Select Arabic from the language menu in the header. The entire shell switches to right-to-left layout.

Current: EN, Theme: light
Switching locale updates all [data-i18n] elements without a page reload. RTL mirrors the entire layout via CSS [dir="rtl"] rules.

Empty & Loading States

No posts yet
Start building your content library. Your first post is just a click away.
Skeleton Loading
Progress Bars
Storage68%
Upload100%
Processing (indeterminate)
Spinners
Result / Status Pages
Import Complete!
All 248 posts have been successfully imported from WordPress.
Connection Failed
Could not connect to the source database. Verify credentials and try again.

Auth & Login Patterns

Centered authentication card, CSRF hidden field, error state, and subdirectory-safe form action patterns introduced in Wave 002B.

Login Card (default state)
Publecto
Sign in

Enter your credentials to continue.

© 2026 All rights reserved.
Login Card (error state — invalid credentials)
Publecto
Sign in

Enter your credentials to continue.

Invalid email or password.
Pattern Notes
  • All mutating forms (POST) must include <input type="hidden" name="_csrf_token" value="…"> populated from CsrfService::getSessionToken().
  • The action attribute must use the $baseUrl prefix passed from the route handler: action="<?= $e(($baseUrl ?? '') . '/login') ?>". This ensures subdirectory deployments (e.g. XAMPP /publecto.com/public/) work correctly.
  • The next hidden field carries the intended post-login destination. The server validates it is a relative path to prevent open-redirect attacks.
  • On invalid credentials the server re-renders with HTTP 401 and 'error' => 'invalid_credentials'. Inputs receive aria-invalid="true". The error message is always generic (never leaks which field was wrong).
  • The outer body uses flex centering; the card has max-width: 400px and box-shadow. Background is --color-bg-secondary to distinguish from the card surface.
  • All design tokens (colors, spacing, radius, shadow) are from the token system — no hardcoded values.

Admin Security Patterns

Admin table layout, permission badge, empty-state, action-confirmation (assign / revoke), and flash feedback patterns introduced in Wave 002C.

Admin User Table
Users
All registered users — uuid (first 8 chars), email, status, joined
UUID Email Status Joined
a1b2c3d4… alice@example.com active 2024-01-15
e5f6a7b8… bob@example.com inactive 2024-02-20
c9d0e1f2… carol@example.com active 2024-03-01
Permission & Role Badges (Canonical Role Taxonomy — Wave 002C.1)
Platform Super Admin Site Owner Site Admin Editor Contributor Member Viewer
Suspended ← account status badge (not a role)
Permission keys: resources.access sites.preview roles.assign settings.manage
Empty State — DB Unavailable
Database unavailable
User data cannot be loaded. Check your database connection and try again.
Empty State — No Records
No users yet
No registered users found. Users will appear here after registration is enabled.
Assign Role Form (action confirmation)
Assign Role
Select a user and a role to assign. Scope defaults to global.
Revoke Assignment — Inline Confirm Button
User Role Scope Assigned Action
alice@example.com platform_admin global 2024-03-10
Flash Feedback — Success & Error Banners
Role assigned successfully.
Role assignment revoked.
Role assignment failed. Check that the user and role exist and try again.
Pattern Notes
  • All admin POST actions (assign, revoke) must carry _csrf_token verified server-side by CsrfService::verifyToken().
  • UUIDs are displayed as first-8-chars + "…" in tables; full UUID is never shown in UI but is preserved in forms as hidden values.
  • Role/permission keys use font-family: var(--font-family-mono) to signal machine-readable identifiers.
  • Flash messages are stored in $_SESSION['admin_flash'], read once on GET, then cleared. Values map to i18n keys via $t('admin_' . $flash).
  • Revoke buttons use onclick="return confirm(…)" as a lightweight confirmation guard for the demo; production should use a modal dialog for better UX.
  • password_hash is never exposed in any user-facing listing, API response, or audit log — only uuid, email, status, and created_at.
  • Audit events (assign / revoke) use actor_uuid in metadata because actorId (BIGINT) cannot store a UUID. actorId is set to null.

Runtime Readiness Patterns

Status badge, readiness category card, per-item check row, and deferred-action patterns introduced in Wave 002D. All static demo — no DB required.

Status Badges
Ready Warning Blocked Unavailable Unknown
Readiness Category Card
Environment
Ready
PHP Version
PHP 8.2.x (requires >= 8.2)
Ready
Required Extensions Ready
.env File Ready
DB Config Ready
Writable Directories Ready
Mixed Status Example (Warning + Stale)
Migrations
Warning
Migrations Applied
2 migration(s) pending — run: php scripts/migrate.php run
Warning
Stale Applied Migrations
1 applied migration name(s) not found on disk
Warning
Deferred Action Pattern
🚫 Web-triggered operations are not available
Migrations, database seeding, and bootstrap admin creation must be performed via CLI. Web-triggered versions are deferred.
These actions are read-only in the console. Use CLI scripts to perform them.
Pattern Notes
  • Status badges use inline styles (5 fixed colors) — no extra CSS classes needed.
  • Category cards use the standard .card / .card-header / .card-body components.
  • Check rows use a borderless table inside .card-body with padding:0.
  • All detail text comes from i18n keys (detail_key + detail_params) — never raw English strings from the service.
  • Readiness checks are all read-only. Deferred actions use disabled + aria-disabled="true" to signal unavailability without removing the button from the accessibility tree.
  • The live console at /admin/runtime-readiness requires settings.manage permission. The demo on this page is DB-independent.