Foundations
Style guide
Shared appearance and deliberate adaptations of the shadcn/ui reference.
Each component’s geometry, tokens and behavior are in its guide; this page covers what they share.
Design reference
Components follow the visuals, states and compositions of shadcn/ui, adapted to scoped plain HTML and Vanilla JavaScript: native semantics, token overrides, roots and lifecycle, with no React or other runtime dependency. Its theming reference informs the neutral surfaces and the text hierarchy; the token names stay Pelatform UI’s.
| Component | Difference from shadcn/ui |
|---|---|
| Button | Disabled buttons keep readable text (at least 4.5:1) instead of fading with opacity |
| Alert | Four semantic colors (info, success, warning, danger) instead of one destructive variant; the action sits in the content flow rather than in a corner |
| Card | Compact spacing comes from --plf-card-padding instead of a size variant; there is no header action slot |
| Mockup | No shadcn/ui counterpart: daisyUI’s mockup-browser and mockup-window, drawn after a macOS window with red, amber and green dots; the window’s bar and corners are compact, for small mockups; the browser’s viewport sizes, radios at the end of its bar that narrow the frame to a tablet’s or a phone’s width, are Pelatform UI’s own |
| Lightbox | No shadcn/ui counterpart: a Modal that fills the screen and stays dark in both themes, as photo viewers are, with shadcn/ui’s round outline carousel buttons; no zoom |
| Accordion, Collapsible | Native <details>: no height animation and no disabled state |
| Toggle Group | Items keep the native Tab order; there is no arrow-key navigation |
| Select | The active option keeps an outline as well as its fill, so the keyboard position stays at 3:1; a line separates option groups by itself, where shadcn/ui places a separator by hand |
| Breadcrumb | No collapsed or dropdown variant |
| Link | No shadcn/ui component: daisyUI’s link without its underline; the accent and the medium weight set a link apart in a sentence, and link-muted is an action that stands alone, muted until hovered |
| Input Group | Addon segments take a raised tint and the group’s own border as their divider, after Metronic’s joined addons, where shadcn/ui’s addons sit in the field without a fill |
| Modal | modal-floating-close is a Pelatform UI option; one modal is open at a time |
| Typography | Opt-in scoped CSS with blue links, semantic theme tokens and a compact rhythm; H2 has no automatic divider; native highlight variants are a Pelatform UI addition |
| Choice Card | A native radio button or checkbox at the start of the row, as on Checkbox and Radio, where shadcn/ui’s radio choice card puts its control at the end; an icon, image or color swatch above the row has no shadcn/ui counterpart; a switch sits at the end, as in shadcn/ui’s switch choice card |
| Number Input | No shadcn/ui component: its Button Group composition, an input with outline − and + buttons, on a native type="number" whose buttons stay out of the Tab order, as the arrow keys step it; the buttons take the input’s border, so the field has one frame |
| Editor | No shadcn/ui component: a Textarea frame around a toolbar of ghost icon buttons, as in shadcn/ui’s static toolbar example built from a Button Group, pressed in Toggle’s blue where shadcn/ui’s Toggle is grey; the text takes Typography’s sizes, and the link panel is a Popover |
| Repeater | shadcn/ui’s Array Fields as plain HTML: a remove button is disabled at the minimum, where shadcn/ui hides it, and is described by its row’s first field, where shadcn/ui numbers its name; a row’s fields wrap on narrow screens; rows move with the Sortable extension, which shadcn/ui’s form examples leave out |
| Timeline, Code Block | No shadcn/ui counterpart; they follow the same tokens and spacing |
| Sidebar | Control/Command+B toggles it only when a toggle names the shortcut in aria-keyshortcuts, where shadcn/ui always binds it; the phone Sheet is a native dialog that takes the sidebar’s own content |
| Application shell block | shadcn/ui’s dashboard-01 frame in plain HTML: the account menu sits in the header beside search, notifications and the theme, where dashboard-01 keeps it in the sidebar footer, and the Sidebar keeps its own look rather than the inset variant |
Current defaults
These are the shared defaults every component follows.
| Aspect | Current implementation |
|---|---|
| Surfaces | Neutral gray palette in light and dark; one subtle decorative border, stronger field boundaries and Tailwind CSS’s shadows |
| Accent | Tailwind CSS v4’s blue-600 in the light palette; meaningful status colors are preserved |
| Typography | System font, 1rem (16px) body; 0.875rem/500 controls; 0.875rem/400 text typed into fields |
| Spacing | Tailwind CSS’s scale, 0.25rem per step |
| Radius | Tailwind CSS’s scale: md (6px) inner items, lg (8px) controls and overlays, xl (12px) cards and dialogs |
| Controls | 2/2.25/2.5rem (32/36/40px) minimum heights; content and font overrides can grow them (Control sizes) |
| Icons | Tabler Icons from @pelatform/icons, written as icon classes, in place of shadcn/ui’s Lucide set, a deliberate adaptation for its coverage and its filled and brand icons; components draw their fixed icons; a consumer slot takes an icon class or an SVG in currentColor, and an icon-only control has a name |
| Motion | Short Core transitions; dialogs, sheets and toasts open with duration-enter/easing-enter; reduced motion and synchronous close/event timing are respected |
| Focus | One blue focus ring for every control, including fields (Focus rings) |
| Themes | Light by default; light/dark/auto configured independently per root |
Control sizes
See shared control sizing, Form and Badge.
| Target | Size |
|---|---|
| Controls | 32/36/40px minimum heights |
| Select, Combobox and Multi Select option rows | As tall as the field (32/36/40px); at least 40px on touch screens (pointer:) |
| Native choice labels | 24px with a mouse (the WCAG 2.2 minimum), 40px on touch screens (pointer:) |
| Badge | 22px minimum with 12px text and icons; 24px minimum link target |
Input-like controls take Small, Default and Large on the element with the border: Default needs no modifier, and padding, icons and embedded chips follow the size without shrinking the text or fixing the height. Choice controls, Slider, multiline fields and calendar and popup contents keep their own geometry and usable targets; each control’s guide lists its sizes.
Borders and surfaces
Focus rings and error cues stay stronger than decorative borders; selection and status add a marker besides color, and native states remain the source of truth.
| Element | Treatment |
|---|---|
| Decorative borders and dividers, including menus and popovers | --plf-color-border-subtle (30% semantic border over the surface beneath) |
| Overlays | Separate from the page through shadow rather than a heavier border |
| Neutral fills | --plf-color-surface-muted |
| Cards and floating surfaces | --plf-color-surface-elevated: the page color in light mode and a step lighter in dark, as shadcn/ui’s card and popover; dialogs and sheets keep the page color |
| Fields and outline buttons | --plf-color-field: the surface in light mode and shadcn/ui’s translucent fill in dark |
| Form and Combobox boundaries | --plf-color-input (88% semantic border over the surface, and the full border in dark mode against the field fill), so editable areas stay identifiable; enabled hover strengthens it |
| Text and weights | Neutral surfaces, readable muted text and restrained weights |
| Selected Tabs | Field fill, border and shadow on the muted list |
| Named optgroup headings | Raised full-row surface with muted, semibold uppercase text; noninteractive |
| Single native select | The Select trigger’s chevron-down in the theme’s muted text color replaces the engine arrow; multiple and listbox selects, and forced colors, keep the engine rendering |
| Checkbox and radio | Native appearance, selection accent and visible focus |
| Invalid fields | Danger boundary plus associated error wording |
Component border, hover and focus tokens preserve root and element overrides; these defaults do not change the shared semantic border other components use. See Input tokens and Combobox tokens.
Focus rings
Blue marks visible focus; in forced colors every ring uses the system highlight color.
| Control | Focus indicator |
|---|---|
| Buttons and other controls | Blue --plf-focus-width outline |
| Input, textarea, native single Select, Input Group, Select, Combobox, enhanced Multi Select | The same blue outline, just outside the field border |
| Native multiple-select fallback | Its visible outline |
| Combobox | Pointer selection and clearing keep the closed field neutral; keyboard focus shows the ring |
| Search field inside a Command or Combobox popup | Its divider in --plf-color-input, so no ring sits inside the frame; forced colors keep an outline |
| Choice Card | The card’s outline, in place of its control’s |
| Editor | The frame’s outline while its text is focused, as on Input Group; toolbar buttons keep their own outlines |
| Actions reached by keyboard | Individual outlines |
Themes and state
The palette is neutral gray after the neutral theme reference: white and neutral-50 surfaces in light, neutral-950 and neutral-900 in dark, with blue accent and status colors.
- Tokens go from the palette to semantic and component tokens, and a root or element can override each level. Internal values reset at component boundaries, so nested roots stay independent.
- Light and dark use designed color pairs, not an inversion; check contrast when you override colors.
- Keyboard focus stays visible. Styling a native or ARIA state, such as disabled, invalid or open, adds no behavior of its own.
- Styles apply to Pelatform UI elements inside a separate
[data-plf-root], with no global reset; host CSS can still override them.
Cursor cues
Cursors follow the element’s state.
| Element | Cursor |
|---|---|
| Enabled actions | pointer |
| Editable and readonly-copyable text | text |
| Disabled actions | not-allowed |
| Busy Buttons | progress |
| Links that open a Lightbox | zoom-in |
| Static content | No action cursor; it does not appear clickable |
CSS cursor cues do not prevent activation of an ARIA-disabled anchor.
Typography
Typography is opt-in Core CSS: prose styles native content inside one wrapper, because Core never styles native elements globally.
| Aspect | Rule |
|---|---|
| Rhythm | Compact: normal line-height (1.5), space-3 (12px) before paragraphs, lists and quotes, space-4 (16px) before headings, space-1 (4px) between list items, space-2 (8px) between paragraphs in a quote and above a caption, no top margin on the first block |
| Wrapper | No surface, background or maximum reading width; the container and layout utilities own width and columns |
| Links and anchors | Links are underlined with a visible focus outline; a heading link keeps the heading color, shows its # on hover, keyboard focus and touch screens, and ends the heading in RTL |
| Text formats | del and ins differ by strike-through and underline, not color alone; sub and sup keep the normal line-height (Bootstrap’s Reboot) |
| Boundaries | not-prose and nested roots end the content styles; a prose inside an excluded subtree stays off, and preformatted code uses Code Block inside not-prose. Host CSS can still override it: this is scoped styling, not Shadow DOM isolation |
| Out of scope | Syntax highlighting, image layouts, table styling and H2 separators |
The references are shadcn/ui Typography and Bootstrap Typography.
Code Block
Code Block keeps its native frame, semantic background, monospace typography, scrolling and Copy feedback; optional provider-independent token spans add syntax colors.
| Aspect | Behavior |
|---|---|
| Token colors | Light/dark foreground pairs through native light-dark, which follows the closest root’s color-scheme, so nested roots and Auto keep working |
| Fallbacks | Without light-dark the light color applies; a span without colors inherits the source foreground |
| Override | --plf-code-block-token-color on a root, frame or element |
| Implementation | Scoped CSS without !important theme rules or a browser parser; the published library supplies no highlighting helper |
| Consumer spans | Consumers may supply their own token spans, preserving the exact source text |