W WOW Studio CRM · UI Prototype GMT+8 ·

Design tokens & components

Everything on this page is rendered live from assets/tokens.css and assets/components.css. Change a token there and every prototype page follows. Admin portal is desktop-first at 1280px, light theme only in v1; the teacher portal reuses the same tokens at 360px.

Principles

  • Money and dates are never ambiguousOne format each, fixed GMT+8, tabular figures, right-aligned money. See Formats.
  • Status has one colourEvery status word in the requirements maps to exactly one badge. The same colour never means two things.
  • Dense but calmAdmins live in tables all day. 13px table text, 36px controls, generous row hover, no decorative colour.
  • Action lives top-rightPage-level primary action sits in the page header; row-level actions appear on hover; destructive actions are outlined red and confirm first.
  • Branch is always visibleThe branch switcher never scrolls away. Every list and form implicitly belongs to it.
  • Built for reviewAnything mocked or unresolved gets a yellow dashed "prototype note" so branch admins know what to comment on.

Colour

Primary is a deep plum, quiet enough for all-day use; gold accent is reserved for trials and highlights. Semantic colours are shared between badges, alerts, stat tiles and table rows.

Primary (plum)
Neutral
Semantic & accent

Aliases used in components

--bg-app --bg-surface --bg-subtle --bg-sidebar --text-primary --text-secondary --text-muted --text-link --border-default --border-strong --border-focus --status-<name> e.g. --status-paid, --status-needs-checking, --status-signed-off

Typography

Inter for UI, JetBrains Mono for anything a human might copy: date-times in inputs, invoice numbers, IC numbers. All numerals use tabular figures so columns line up.

--text-3xl 28Salary Run · August 2026page title (stat value)
--text-2xl 22Fee Runh1, page header
--text-xl 18Checking Tableh2, modal title
--text-lg 16Ballet Grade 1h3, card title
--text-base 14Fees are billed in advance; salary is paid in arrears.body
--text-sm 13Register 2026-09-15, first fee covers 2026-09-15 to 2026-10-14.tables, forms, buttons
--text-xs 12Marked by Aisyah · 2026-09-03 09:12:44meta, badges, hints
monoKL-2026-000123 · 2026-09-06 20:31:00 · 990101-14-5678identifiers, inputs

Spacing, radius, shadow

4px base. Components use 8 / 12 / 16 internally; page sections use 24 / 32. Radius: 4 inputs and tags, 6 buttons and menus, 10 cards and tables.

1 · 4
2 · 8
3 · 12
4 · 16
5 · 20
6 · 24
8 · 32
10 · 40
12 · 48
Radius & shadow
sm 4
md 6
lg 10
shadow-sm
shadow-md
shadow-lg
Layout constants
--sidebar-width 240px --topbar-height 56px --content-padding 24px --admin-min-width 1280px --mobile-min-width 360px touch target 44px

Date, time, money (section 3 rules)

These are global rules, not preferences. Every screen, export and log uses them. Helpers exist in app.js: WOW.fmtDateTime, WOW.fmtDate, WOW.fmtTime, WOW.fmtMoney.

KindRenderedClassWhere
Date-time2026-09-06 20:31:00.datetimeAudit lines, run timestamps, approvals, slot history
Date2026-09-06.dateLists, From/To pickers, invoice dates
Time20:30.timeTimetable, slot start, room bookings (:00 / :30 only)
MoneyRM 1,234.00.moneyRight-aligned in tables, always two decimals
Negative money(RM 50.00).money.negDeposit refunds, payment reversals, deductions
Live clock[data-now]Sidebar footer, run screens
Inputs
RM

Icons

Stroke icons at 16px (18px in the sidebar, 22px in mobile tabs), injected as an SVG sprite by app.js. Use <svg class="icon"><use href="#i-name"/></svg>.

Buttons

One primary per page region. Secondary for the rest. Ghost for icon-only and table rows. Danger is outlined until the confirm step, then solid.

Sizes & icon buttons
Segmented (view switcher)

Forms

Two-column grid on desktop. Labels above inputs, hints below. Required marked with a red asterisk. Errors inline in red. Selects are native for speed.

Recorded on first contact. Customer becomes a member once saved.
Inherited from Course. Override here for this enrolment only.
PREPAY12 is bound to Ballet Grade 2, not Ballet Grade 1.
Mandatory on open-amount invoices and chargeable-flag changes.
Invoice number is assigned on Issue.

Status badges & tags

Badges carry status and always show a dot. Tags are plain labels (style, branch, role) with no dot. Every status word from the requirements is below; nothing else gets a badge.

Lead pipeline
NewContactedTrial BookedTrial AttendedConvertedLost
Slot lifecycle & chargeable flag
ScheduledUsedCancelledReleasedRescheduled·ChargeableNot chargeable
Invoice & Fee Run buckets
DraftIssuedPartially PaidPaidVoid·UnpaidNeeds checking
Salary sheet & rows
DraftConfirmedSigned offRejected·Flagged · fee not paid
Room booking · Attendance · Customer
TentativeLocked·PresentLateAbsentPendingProof received·Trial customerMember
Variants
PaidIssuedSigned offVoid
Tags & capacity
BalletPianoKuala LumpurOwnerPer slotSyllabus· 8 / 12 12 / 12

Stat tiles & cards

Active students
184
+6 this month
Needs checking
4
Fee Run · Sep 2026
Unpaid
RM3,120.00
11 invoices issued
Paid
RM41,600.00
162 enrolments

Customer

Member
Name
Tan Mei Ling
IC
820405-10-5566
Phone
012-345 6789
Students
Tan Jia Yi (Ballet Grade 2), Tan Jia Hao (Kids Jazz)
Replacement count
2.5 credits · expire 2026-12-31
Outstanding
RM 240.00

Salary sheet · Ms C · Aug 2026

Draft
Draft 2 Confirmed 3 Signed off
2 slots pending attendanceConfirm is blocked until attendance is marked.

Tables

Sticky uppercase header, 13px rows, hover reveals row actions, money right-aligned, totals in a footer. A flagged row is tinted red; a selected row plum. Toolbar sits above with search and filters; pagination below.

Fee Run · 2026-09-012026-09-30 · run by Aisyah at 2026-09-02 09:14:10
StudentClassProductPeriodFee dueMatchedBucket
Tan Jia YiParent: Tan Mei LingBallet Grade 2 · Sat 10:00Syllabus RM 120/mth2026-09-01 → 2026-09-30RM 120.00RM 120.00Paid
Lim Wei JunAdult studentPiano 1-to-1 · Mon 14:00Per slot RM 80/slot2026-09-01 → 2026-09-30RM 320.00RM 160.00Partially paid
Nurul AisyahParent: Rahim bin OsmanKids Jazz Group · Wed 16:30Syllabus RM 90/mth2026-09-01 → 2026-09-30RM 90.00Unpaid
Chong Zi XuanParent: Chong Kah Wai · started 2026-09-15Ballet Grade 1 · Sat 09:00Syllabus RM 100/mth2026-09-15 → 2026-09-30RM 100.00RM 50.00 open amount, 2 classesNeeds checking
Ho Yee ChingPrepaid Jul–Dec 2026 · PREPAY12Ballet Grade 2 · Sat 10:00Syllabus RM 120/mth2026-09-01 → 2026-09-30RM 108.00RM 108.00Paid lump sum
5 enrolmentsRM 738.00RM 538.001 needs checking · 1 unpaid
Compact variant (dashboard widgets, mobile lists)
SlotClassTeacherStatus
2026-09-05 10:00Ballet Grade 1Ms APending
2026-09-05 11:30Kids Jazz GroupMs CPending

Tabs

Used inside detail pages (Customer, Class, Salary sheet). Counts are optional. Click to switch below.

Enrolment list goes here.

Alerts & toasts

Alerts are inline and persistent (blockers, warnings, run summaries). Toasts are transient confirmations at bottom-right and never carry a decision.

Fees are billed in advanceThis run covers 2026-09-012026-09-30. Re-running the same period recalculates and shows diffs; it never duplicates invoices.
Run complete162 enrolments · 148 Paid · 3 Partially paid · 7 Unpaid (7 invoices issued) · 4 Needs checking.
Holiday collisionBallet Grade 1 falls on 2026-09-16 (Malaysia Day). Shift the slot to another date; slots are never skipped.
Room double-bookedStudio A is already taken 2026-09-10 16:0017:30 by a locked rental.

Modal & drawer

Modal for a decision that needs a reason (void, reject, flip chargeable). Drawer for a record detail you peek at without leaving the list (slot, invoice, lead).

Empty & loading

No pending work

Every slot older than 24 hours has attendance marked. Salary sheets can be confirmed.

Timeline & stepper

Timeline for follow-up logs, slot history and approval history. Stepper for the salary approval state and the convert-to-client wizard.

Follow-up log (lead)
  • Farah (Operator)2026-09-04 11:20:05Trial Booked
    Booked free trial in Ballet Grade 1, 2026-09-08 10:00. Next action 2026-09-09: call after trial.
  • Farah (Operator)2026-09-02 15:41:18Contacted
    Called. Interested in Saturday morning ballet for 6-year-old. Source: Facebook.
  • System2026-09-01 20:03:55New
    Lead created from walk-in form.
Salary approval
Draft Confirmed Signed off
Draft! Rejected by Owner3 Signed off
Convert-to-client wizard
Customer2 Student3 Parent4 Enrolment5 Invoice

Timetable primitives

Week grid in 30-minute rows (dashed half-hour lines). Slot chips are coloured by Style, striped cells are holidays or off-days, green cells are idle capacity on the room availability grid. Trial and rescheduled variants shown.

Mon07
Tue08
Wed09
Thu10
Fri11
10:00
Ballet Grade 1
Ms A · Studio A · 8/12
Ballet Grade 1
+ Nurul (trial)
11:00
Piano 1-to-1 · Lim Wei Jun
Kids Jazz Group
Moved from 09-16 (holiday)
12:00
Rental · Dance Co.
Studio A · Locked
Contemporary Open
Year view cells
1415161718 · 293031 Legend:PHPublic holidayTBTerm break (5th week)ODBranch off-day
Style colours on chips
BalletJazzPianoContemporaryRentalMore styles get colours from the same list as they are added in Settings.

Pipeline cards (CRM)

New 3
Siti Nurhaliza
Child 6 · Ballet · Facebook
KLFollow up today
Dance Co. Sdn Bhd
Renter · Studio A, Saturdays
RenterFarah
Contacted 2
Rahim bin Osman
Child 8 · Jazz · Referral
KLNext 2026-09-09
Trial Booked 1
Nurul Aisyah
Trial 2026-09-08 10:00 · Free
Trial customer
Trial Attended 0

Mobile shell (teacher portal)

360px minimum. Top bar shows the branch (switchable for multi-branch teachers), four bottom tabs, and attendance buttons at 40px height with full-width targets. Same tokens, same badges.

Home
Kuala Lumpur · Ms A
2 slots pending attendanceOlder than 24 hours.
Today · 2026-09-07
Ballet Grade 1
10:0011:00 · Studio A · 8 students
Marked
Ballet Grade 2
11:3012:30 · Studio A · 10 students
Pending
Ballet Grade 1
2026-09-05 10:00
Pending
Ballet Private · Chong Zi Xuan
2026-09-04 17:00
Pending
Home
Schedule
Students
My Salary
Ballet Grade 2
2026-09-07 11:30 · Studio A
Scheduled
Tan Jia Yi2.5 credits
Ho Yee ChingFee unpaid
Lee Xin Yi

Phone numbers hidden (per-teacher setting).

Home
Schedule
Students
My Salary

Do / don't

  • Use the status badge component for every statusNever a coloured word, never a custom colour. If a new status appears, add it to tokens first.
  • Don't show 12-hour time, month names or "ago"No "3:30 PM", no "6 Sep", no "2 hours ago". The strict formats are the only ones.
  • Right-align money, left-align text, centre nothingMoney columns get .money. Totals in tfoot.
  • Don't put two primary buttons on one screenOne primary in the page header, one in a modal footer. Everything else is secondary or ghost.
  • Every destructive or money-changing action needs a reason fieldVoid, reject, flip chargeable, salary override, deposit refund.
  • Don't pro-rate, auto-run or auto-fill anything in the UIFee Run and Salary Run are buttons; pro-rating is a manual open-amount invoice; attendance is marked by a person.
  • Show who and when on anything approved or overriddenName · yyyy-MM-dd HH:mm:ss, inline next to the status.
  • Don't mix branches in one listExcept under "All branches" for Super Admin, which is read-only and shows a Branch column.