Skip to content
Dial

v1.0Dial UI Kit

Interfaces you can almost feel.

A tactile UI kit for Tailwind CSS and React. Keys that press, switches that snap, knobs that turn and readouts that glow, built on accessible patterns and a single set of tokens.

  • 52 elements · 40 sections · 9 layouts
  • HTML + Tailwind
  • React + TypeScript
  • Light & dark

DL-1 · Control surface

Live

Gain

62%

Gain

62%

Tone

40%
70%
Sync to tempo

01What's inside

Pieces that are ready to drop in

Every piece ships as plain HTML with Tailwind classes and as a typed React component. Copy one, or start from a full layout.

02Quick start

Two minutes to your first panel

Tailwind v3 or v4, plain HTML or React. The tokens are CSS variables, so themes switch without a rebuild.

HTML + Tailwind v3

Add the preset, load the tokens and fonts, then paste any snippet.

Setup
// tailwind.config.js
module.exports = {
  presets: [require("./tokens/dial-preset.cjs")],
  content: ["./**/*.html"],
};

<!-- index.html -->
<link rel="stylesheet" href="tokens/dial.css">
<link rel="stylesheet" href="fonts/fonts.css">
<script src="html/dial.js" defer></script>

React + TypeScript

Components are plain TSX. Interactive ones use a tiny hook with no dependencies. Copy images/ to public/img/.

App.tsx
import "./dial/tokens/dial.css";
import "./dial/fonts/fonts.css";
import { Knob } from "./dial/react/components/elements/Knob";
import { HeroDevice } from "./dial/react/components/sections/HeroDevice";

export default function App() {
  return (
    <main className="bg-canvas text-ink">
      <HeroDevice />
      <Knob />
    </main>
  );
}

03Tokens

Bone, graphite and one cobalt accent

Twenty-seven color roles with light and dark values, plus depth, radius, type and motion. Edit tokens.json and regenerate, or override the CSS variables.

  • canvas

    #ECE9E2

    Page background (bone / graphite)

  • panel

    #F7F5F0

    Card and panel surface

  • raised

    #FDFCFA

    Key caps, inputs on panels, popovers

  • sunken

    #E3DFD6

    Recessed wells, tracks, inset areas

  • line

    #D5D0C5

    Hairlines and dividers

  • line-strong

    #B8B2A5

    Control outlines, ticks

  • ink

    #17181B

    Primary text

  • ink-2

    #45474D

    Secondary text

  • ink-3

    #5F6167

    Muted text, engraved labels

  • accent

    #2A3EE8

    Cobalt: primary actions, focus

  • accent-hover

    #2233CC

    Primary hover

  • on-accent

    #FFFFFF

    Text on cobalt

  • accent-soft

    #DFE3FF

    Cobalt tint backgrounds

  • accent-text

    #2233CC

    Cobalt text and links

  • ok

    #3DBE4A

    Lime LED: success

  • ok-soft

    #E3F5E3

    Success tint

  • ok-text

    #1A6E26

    Success text

  • warn

    #F2A516

    Amber LED: warning

  • warn-soft

    #FBF0D9

    Warning tint

  • warn-text

    #825400

    Warning text

  • danger

    #D93036

    Red LED: errors, destructive

  • danger-soft

    #FBE4E2

    Error tint

  • danger-text

    #B42318

    Error text

  • lcd

    #101114

    LCD readout glass (dark in both modes)

  • lcd-ink

    #9CF06C

    LCD digits

  • lcd-dim

    #2B3A26

    Unlit LCD segments

Type scale

Archivo (variable width + weight) for UI and display, JetBrains Mono for engraved labels and readouts. Both SIL OFL 1.1.

7xlTactile76px/76px
5xlTactile48px/52px
3xlTactile30px/38px
xlTactile20px/30px
baseTactile16px/26px
smTactile14px/20px

JetBrains Mono · 0123456789 · ⌘K

Engraved label · tracking 0.14em

Depth

Shadows flip with the theme through three variables.

key
key-press
key-accent
well
panel
float
led
lcd

Radius & motion

xs 4px
sm 6px
md 10px
lg 14px
xl 20px
2xl 28px
instant
90ms
fast
160ms
base
240ms
slow
420ms

Easings: press, detent (a small overshoot, like a switch snapping into place) and out. Every animation is wrapped in motion-safe:.

04Accessibility

Built to be used, not just looked at

Text pairs are measured in both themes and listed below, and every interactive piece works with a keyboard alone.

  • Keyboard firstTabs, menus, listboxes, sliders, the knob and dialogs follow WAI-ARIA patterns: arrows, Home, End, Esc and visible focus.
  • Screen readersReal roles and states: aria-pressed, aria-checked, aria-expanded, aria-valuetext and live regions for toasts.
  • AA contrastEvery text token passes WCAG AA on its surfaces in light and dark. LEDs always come with a text label.
  • 44px targetsButtons, links in menus and form controls are at least 44px tall on touch screens.
  • Reduced motionAnimations are opt-in through motion-safe, so people who prefer less motion get a calm UI.
Contrast ratios of text tokens on their surfaces, light and dark themes
Text on surfaceSampleLightDark
ink / canvasAa 12314.64:1 AAA16.17:1 AAA
ink-2 / canvasAa 1237.66:1 AAA9.68:1 AAA
ink-3 / canvasAa 1235.11:1 AA6.19:1 AA
ink-3 / panelAa 1235.68:1 AA5.73:1 AA
ink-3 / sunkenAa 1234.66:1 AA6.43:1 AA
ink-2 / raisedAa 1239.06:1 AAA7.97:1 AAA
accent-text / canvasAa 1237.18:1 AAA8.83:1 AAA
accent-text / accent-softAa 1236.87:1 AA7.07:1 AAA
on-accent / accentAa 1237.11:1 AAA4.86:1 AA
on-accent / dangerAa 1234.74:1 AA4.74:1 AA
ok-text / ok-softAa 1235.58:1 AA8.58:1 AAA
warn-text / warn-softAa 1235.77:1 AA9.04:1 AAA
danger-text / danger-softAa 1235.42:1 AA7.12:1 AAA
lcd-ink / lcdAa 12313.57:1 AAA14.16:1 AAA

05In the download

Everything in one tidy folder

dial-tactile-ui-kit/
├─ tokens/     tokens.json · dial.css · dial-preset.cjs · dial-v4.css
├─ html/       elements/ · sections/ · layouts/ · dial.js · dial.css
├─ react/      components/{elements,sections,layouts} · useDial.ts
├─ docs/       this documentation site, offline
├─ fonts/      Archivo + JetBrains Mono (OFL 1.1)
├─ images/     AI-generated product photos (WebP)
├─ AGENTS.md   notes for AI coding assistants
└─ README.md · LICENSE · LICENSE-THIRD-PARTY.md

Use it anywhere

Use Dial in unlimited personal and client projects. Icons are Lucide (ISC). Fonts are SIL OFL 1.1. Images are AI-generated and included for use in your projects.

Guides

OverviewDocs Design tokensDocs AccessibilityDocs Quick startDocs

Elements

ButtonsActions Button statesActions Icon buttonsActions KeypadActions Segmented controlActions LinksActions Text inputForms Input add-onsForms TextareaForms SelectForms Search fieldForms CheckboxForms Radio groupForms Radio cardsForms SwitchForms Rocker switchForms Fader sliderForms Rotary knobForms Number stepperForms One-time codeForms File dropForms BadgesDisplay ChipsDisplay AvatarsDisplay Keyboard keysDisplay Status LEDsDisplay DividersDisplay CardDisplay LCD readoutDisplay StatDisplay Data tableDisplay CalendarDisplay TimelineDisplay Empty stateDisplay Bar chartDisplay TabsNavigation AccordionNavigation BreadcrumbsNavigation PaginationNavigation StepperNavigation Dropdown menuNavigation Command paletteNavigation TooltipFeedback PopoverFeedback DialogFeedback DrawerFeedback ToastFeedback AlertsFeedback ProgressFeedback GaugeFeedback SpinnersFeedback SkeletonFeedback

Sections

Announcement barMarketing NavbarNavigation App headerApplication Hero · deviceMarketing Hero · centeredMarketing Hero · consoleMarketing Logo stripMarketing How it worksMarketing Features · gridMarketing Features · bentoMarketing Features · alternatingMarketing Spec sheetMarketing Stats · LCDMarketing Stats · metersMarketing Pricing · three tiersMarketing Pricing · compare tableMarketing Pricing · singleMarketing Testimonials · gridMarketing Testimonial · large quoteMarketing CTA · panelMarketing CTA · newsletterMarketing FAQ · accordionMarketing FAQ · two columnsMarketing Team gridMarketing Blog · cardsContent Blog · featuredContent Contact · split formMarketing Contact · cardsMarketing Footer · largeNavigation Footer · simpleNavigation Dashboard · KPIsApplication Dashboard · chartApplication Dashboard · tableApplication Dashboard · activityApplication Dashboard · sidebarApplication Settings panelApplication Auth · sign inApplication Auth · sign upApplication Auth · verify codeApplication Error · 404Content

Layouts

Landing pageLayout DashboardLayout SettingsLayout Pricing pageLayout Blog indexLayout ArticleLayout Contact pageLayout Sign inLayout 404Layout
↑↓ move↵ openEsc close