Register

Documentation

How to use the template and make it yours

On this page

Getting started

Open it, or publish it

The template is plain HTML, CSS and JavaScript, with no framework. Open index.html in a browser to use it, or put the folder on any web server to publish it: every link is relative, so it works from any folder.

Every page is a complete HTML file with the same frame: the sidebar, the top bar and the footer. Copy the page closest to what you need to start a new one.

Pages
449
Groups in the menu
32
Modules you can turn off
16
Browsers
The current Chrome, Edge, Firefox and Safari: the CSS uses :has(), container queries, color-mix() and logical properties, which all four support
Tested at
13 screen sizes from 320 to 1920 px wide, light and dark

Files

What is in the folder

Files
Path What it holds
*.html 449 pages, one file each; index.html is the dashboard
emails/ 22 email templates
assets/js/config.js The one configuration: the modules, the store, the demo’s date
assets/js/charts-*.js 5 starters for the chart-library pages
assets/demo/products/ 27 product photos
system/tokens.css The colours, in light and in dark
system/system.css Type, spacing, the components and the layouts
system/system.js The behaviours: menus, dialogs, tables, forms and the rest
system/icons.js The Tabler icons the pages use

Pages

Add a page, change the menu

Every page is a complete HTML file, so a new page starts as a copy of one that is close to it.

Add a page

  1. Copy a page, for example blank-page.html, and give the copy its own name.
  2. Change its <title>, and replace what is inside <main class="page">.
  3. Link it from the sidebar. The sidebar is the same in every page, so change it in all of them at once with your editor’s find and replace.

The one configuration

assets/js/config.js, read first by every page

Set a module to false and its pages, its menu groups and its widgets leave the menu and the screens; nothing else needs editing. A link elsewhere to one of its pages goes too, or keeps its words without the link, and a heading or a group it leaves empty goes with it. core is the product itself and is always on.

assets/js/config.js
window.POS_CONFIG = {
  store: 'Corner Store',
  currency: 'USD',
  locale: 'en-US',
  today: '2026-10-04',
  modules: {
    core: true,
    restaurant: false,   // tables, kitchen display, bar tabs… leave the menu and every screen
    …
  }
};
Modules
Module Pages What it covers
core 344 The product itself; always on
restaurant 5 Tables, kitchen display, bar tabs, kitchen printer, dining options
pharmacy 1 Batch and expiry at the counter
grocery 2 Weighing at the counter, the scale
fashion 1 Size and colour at the counter
booking 1 Services and appointments
kiosk 2 Self-checkout kiosk
loyalty 9 Points, rewards, cards, campaigns
multi-store 2 Several stores, transfers between them
online 15 Online store and channels
hr 10 Departments, attendance, leave, payroll
integrations 6 App directory, API keys, webhooks, syncs
saas 6 Companies, plans and subscriptions (multi-tenant)
apps 16 Calendar, mail, chat, kanban and the other workspace apps
cms 10 Pages, blog, places, FAQ
chart-libraries 6 Chart libraries
icons 13 Icons

today is the demo’s “today”: date filters count back from the day the figures were made. Remove it and they count from the real date.

Colours and themes

Tokens, light and dark

system/tokens.css holds the colour ramps and what each colour is for, in light and in dark (184 tokens); system/system.css holds the type, the spacing, the corners and the components, all drawn from tokens.

The accent is the blue ramp, --blue-50 to --blue-950, at the top of tokens.css: give it your brand’s ramp and the buttons, links, focus rings and selected states follow in both themes. Keep --accent-text at 4.5:1 or more against --bg-surface.

The theme button in the top bar sets Light, Dark or the device’s own setting, and the device remembers it (pos.theme in local storage). data-theme on <html> fixes one theme; data-theme-default="dark" opens a page dark, as the Dark layout does. Charts redraw in the new colours.

A page that is always dark
<html lang="en" data-theme="dark">

Layouts

One attribute on the frame each

Layouts
Layout What it is Turn it on
Vertical The sidebar on the left, the page on the right: the template’s default. <div class="app">
Horizontal The sections across the top under the top bar; each opens its groups and pages. Narrower than 1280 px, where the ten sections no longer fit in one row, the menu is the sidebar again (on a phone, the drawer). <div class="app" data-layout="horizontal">
Detached The sidebar as a card floating beside the page, with space around it. <div class="app" data-layout="detached">
Two column A rail of the sections, and the pages of the current section beside it. <div class="app" data-layout="two-column">
Hover-expand rail The sidebar folded to its icons; pointing at it or tabbing into it opens it over the page. <div class="app" data-sidebar="rail">
Boxed The whole app in a centred box on a wide screen, the sidebar folded to a rail that opens when you point at it. <div class="app" data-layout="boxed" data-sidebar="rail">
Right to left Mirrored for Arabic, Hebrew, Persian and Urdu: the sidebar on the right, the arrows turned. <html lang="ar" dir="rtl">
Dark The dark theme, as the page opens. The theme button in the top bar still switches it. <html data-theme="dark">

Right to left

Arabic, Hebrew, Persian and Urdu

Set dir="rtl", with your language, on <html>. The layout mirrors: the sidebar moves to the right, arrows turn, and every margin and padding is logical, so it follows. Text takes its direction from its own words, so an English line keeps its full stop at its end and figures read left to right; code blocks stay left to right.

ApexCharts draws left to right in either direction (its canvas is fixed to it); Chart.js legends and tooltips read right to left.

A right-to-left page
<html lang="ar" dir="rtl">

See the right-to-left layout

Behaviours

Added by attribute, no script of your own

system.js wires every behaviour by attribute: add the attribute and the behaviour comes with it, with its keyboard support. The UI kit pages show each one working, with its markup to copy.

Behaviours
Attribute What it does
data-dialog="id" Opens the dialog with that id: focus moves in and stays there, Escape closes it, focus comes back to the button.
data-drawer="id" The same for a drawer from the side.
data-edit="name" On a row’s Edit button that opens its list’s Add form: the form opens as the edit form for that row.
data-popover="id" Opens a menu or popover under the button; Escape or a press outside closes it.
data-side="end" With data-popover: opens the popover beside the button instead, on the other side when there is no room.
data-tabs On a role="tablist": the arrow keys move between the tabs, each tab shows its own panel.
data-radios On a role="radiogroup": one Tab stop, the arrow keys choose.
data-collapse On a button with aria-expanded and aria-controls: shows or hides that panel.
data-dismiss Removes the alert it sits in and says so.
data-confirm In a confirm dialog: does what the dialog asks (removes the row) and says so.
data-copy="id" Copies the text of the element with that id and says it was copied.
data-toast="text" Shows a short message at the corner of the screen.
data-validate On a form: checks each field when it is sent, names what is wrong under it and moves focus to the first.
data-mask="phone" Formats what is typed: phone, date, card, expiry, zip, money or sku.
data-pad A number pad that types into its field, as money or as a PIN.
data-period The Today, 7 days and 30 days switch: every figure marked data-by-period follows it.
data-chart A chart drawn by ApexCharts from the JSON in the attribute, in the theme’s colours.
data-scroller="name" A box that scrolls sideways becomes a named region and a Tab stop while it scrolls.
data-wizard Steps shown one at a time, with Back and Next and the step list.
data-sortable A list put in order by dragging, or by each row’s Move up and Move down.
data-carousel One slide at a time, with previous, next and a dot for each; nothing moves by itself.
data-combobox A searchable select: it looks like a select; open, a search box sits at the top of its list; with data-multi each choice is a chip.
data-daterange A field for a range of dates: opens the calendar with the preset ranges. On a desk, every date field opens the same calendar and reads in the store’s format.
data-cal A calendar: Today, ‹ › and the views move between its month, week, day and list pages; a day’s number (data-cal-day) opens that day.
data-md="swap" Mail and chat: an opened item (data-md-open) takes the list’s place, with Back (data-md-back) and ‹ › (data-md-step); "split" keeps the list beside it on a wide screen.
data-check-all="id" A box that ticks every row box (data-row-check) of that list.
data-menu-toggle A menu button that shows or hides its menu, as the shop’s header does on a phone.
data-photo-tiles On a drop zone’s list: the chosen photos show as tiles, each with a remove button.
data-order-parts On a data-sortable list beside a preview: the preview’s parts follow the list’s order.
data-fit-width A sheet drawn at its real size, zoomed to fit its box.
data-toast-on-change="text" On a file field: says how many files were taken.
data-toc An “On this page” list that marks the section being read.
data-module="name" Hidden when that module is off in assets/js/config.js.
data-fallback="page.html" On a link to a page of a module: where it goes instead when that module is off.

Charts

ApexCharts 3.54.1

A chart is described in JSON in data-chart and drawn by ApexCharts in the theme’s colours, so it follows a change of theme. Each chart also has its figures in a table for screen readers.

The Charts pages show 20 kinds on the store’s figures; the Chart libraries pages draw the same figures with 6 libraries, for a team that already uses one.

Icons

Tabler Icons 3.48.0

The template draws Tabler Icons as inline SVG: write <i class="ti ti-NAME"></i> and system/icons.js puts the icon in its place. icons.js holds the icons the pages use; to add one, copy its SVG paths from tabler.io/icons into icons.js under its name.

The Icons pages show 13 sets; each one loads from a CDN on its own page only.

Accessibility

WCAG 2.2 AA

  • Text, controls and their edges meet the AA contrast ratios in both themes.
  • Everything works from the keyboard: menus, dialogs, tabs and radio groups follow the WAI-ARIA patterns, and focus can always be seen.
  • Targets are at least 24 px; at the counter they are larger, for a touchscreen.
  • A page reflows to 320 px wide, and keeps working with text spacing increased (WCAG 1.4.10 and 1.4.12).
  • Movement stops when the device asks for reduced motion.
  • Every chart has its figures in a table for screen readers.

Libraries and credits

What the pages load, and its licence

Libraries
Library Kind Version Licence From Used on
Geist Mono Fonts current SIL OFL 1.1 fonts.googleapis.com Every page
Inter Fonts current SIL OFL 1.1 fonts.googleapis.com Every page
Bootstrap Icons Icons 1.11.3 MIT cdnjs.cloudflare.com Bootstrap
Feather Icons 4.29.2 MIT cdnjs.cloudflare.com Feather
Flag Icons Icons 7.2.3 MIT cdnjs.cloudflare.com Flags
Font Awesome Icons 6.5.2 Icons CC BY 4.0, font SIL OFL 1.1, code MIT cdnjs.cloudflare.com Font Awesome
Ionicons Icons 7.4.0 MIT cdn.jsdelivr.net Ionicons
Line Awesome Icons 1.3.0 MIT cdnjs.cloudflare.com Line Awesome
Material Symbols Icons Outlined Apache 2.0 fonts.googleapis.com Material
Remix Icon Icons 4.2.0 Apache 2.0 cdnjs.cloudflare.com Remix
Simple Line Icons Icons 2.5.5 MIT cdnjs.cloudflare.com Simple Line
Tabler Icons Icons 3.48.0 MIT system/icons.js, inline SVG Every page
Themify Icons Icons 0.1.2 Font SIL OFL 1.1, code MIT cdn.jsdelivr.net Themify
Typicons Icons 2.1.2 Icons CC BY-SA 4.0, font SIL OFL 1.1 cdn.jsdelivr.net Typicons
Weather Icons Icons 2.0.12 Font SIL OFL 1.1, code MIT cdnjs.cloudflare.com Weather
ApexCharts Charts 3.54.1 MIT cdnjs.cloudflare.com 55 pages
C3 Charts 0.7.20 MIT cdnjs.cloudflare.com C3
Chart.js Charts 4.4.1 MIT cdn.jsdelivr.net Chart.js
D3 Charts 5.16.0 BSD-3-Clause cdnjs.cloudflare.com C3
Flot Charts 0.8.3 MIT cdnjs.cloudflare.com Flot
jQuery Charts 3.7.1 MIT cdnjs.cloudflare.com Flot, Morris, Peity
Morris.js Charts 0.5.1 BSD-2-Clause cdnjs.cloudflare.com Morris
Peity Charts 3.3.0 MIT cdnjs.cloudflare.com Peity
Raphaël Charts 2.3.0 MIT cdnjs.cloudflare.com Morris
QR Code Generator Codes 1.4.4 MIT cdnjs.cloudflare.com 5 pages

Product photos in the demo: 23 from Unsplash and 4 from Pexels, under the Unsplash and Pexels licences, which allow commercial use without credit. The download carries placeholders in their place.

Product photos
Photo Photographer From
Oat flat white Jeremy Yap Unsplash
Cappuccino Anubhav Arora Unsplash
Matcha latte Jason Leung Unsplash
Hot chocolate Elena Leya Unsplash
Espresso Katt Galvan Unsplash
Chai latte Kamal Preet Kaur Unsplash
Cold brew pariwat pannium Unsplash
Sparkling water Sam Mai Pexels
Orange juice Greg Rosenke Unsplash
Iced tea Mae Mu Unsplash
Lemonade Laura Chouette Unsplash
Kombucha Geraud pfeiffer Pexels
Butter croissant Vicky Nguyen Unsplash
Raspberry tart Alexandra Kusper Unsplash
Pain au chocolat Skyler Ewing Unsplash
Chocolate cookie Ellie Ellien Unsplash
Banana bread Cody Chan Unsplash
Blueberry muffin Tayla Brand Unsplash
Cinnamon roll Yosep Sugiarto Unsplash
Sourdough loaf Monika Grabkowska Unsplash
Whole milk, 1 L Mary Skrynnikova Unsplash
Free-range eggs, 12 Morgane Perraud Unsplash
Oat milk, 1 L hello aesthe Pexels
Granola, 500 g Sollange Brenis Unsplash
Wildflower honey Art Rachen Unsplash
Gift box Baibhav Kumar Unsplash
Tote bag Mr. Mockup Pexels