One interface, ten skins — yours to pick
Every Sierra Hub module reads its colours, fonts, corners, and shadows from a single shared token set — the whole platform can wear any of these skins by swapping one block of values. And the choice is personal: each staff member will pick their preferred skin in the new Profile & settings module (me.sierrahub.ca → Appearance tab), and their pick follows them to every module on every device. Votes here decide two things: (a) which theme is the default for anyone who never picks, and (b) which themes make the personal picker. Below, the exact same sample screen (a mini Lead 360 cockpit) is rendered ten times, once per theme.
Each theme below shows the same mini cockpit: top bar, three KPI tiles, an outstanding-treatment worklist, hygiene coaching bars, an AI synthesis card, a Workspace banner, and the two button styles. Under each sample: the eight core colour tokens, the non-colour changes (typography, corner radius, shadow, blob character), and your voting row.
Vote 👍/👎 for gut reaction, pick Ship it / Maybe / No for the verdict, and leave a note if you want a hybrid (mixing is cheap — e.g. Porcelain's restraint with Editorial's serif). Use Compare side-by-side in the sticky bar to pit any two head-to-head.
Every card's blob is dictated by its meaning, and the mapping is identical in all ten themes — only the saturation and tone adapt to each palette (the dark theme glows brighter so the tints still read). This same semantic system runs across all the module pages (Lead 360, Dentist 360, Workspace, …): a gold corner always means money, a rose corner always means risk — whichever skin you're in.
Every module page carries the same token block — colours, fonts,
radii, shadows, semantic blob tints. Pages never hardcode a hex; they only ever say "primary", "risk",
"money", "AI". Each theme on this board is a complete, drop-in token set. What changed: the winner is no
longer forced on everyone. The vote crowns the platform default and picks the shortlist;
each staff member then chooses their own skin in Profile & settings (me.sierrahub.ca →
Appearance). Their pick is stored once (app.user_prefs.theme_key)
and applied as a class on the app shell at sign-in — one row, every module, every device. Per-practice
theming (Midpark blue, Springbank green) still layers on top of whichever base skin the person chose.
◆ For Elijah — per-user theming, end to end
Data
New table app.user_prefs: user_id uuid PK REFERENCES auth.users(id),
theme_key text NOT NULL DEFAULT 'vz1' (allowed values = the shortlist this board
produces, VZ1–VZ10), updated_at timestamptz. RLS: own-row read/write; exec read-all.
Any view over it: security_invoker = true.
Resolver order (app shell, at login)
1. User pick — user_prefs.theme_key → class theme-<key> on
the app shell. 2. Per-practice theme — the existing §0t classes
(.theme-midpark etc.) layer on top for practice-branded chrome, untouched.
3. Platform default — this board's winning theme, for anyone with no row.
Picker surface
me.sierrahub.ca — Profile & settings, Appearance tab: renders this page's
mini-cockpit once per shortlisted theme; one tap calls server action setThemePref(themeKey)
which upserts user_prefs and re-applies the shell class without reload.
Votes + deploy surface
Verdicts here persist to app.future_votes (item_ids VZ1–VZ10; VZ1–VZ6 are
the original six, so earlier votes stay valid). Until the modules fold into the Next.js app, the 12
subdomain mockups (leads, hyg, ast, adm, hr, ortho, tc, cdgadmin, schedules, dentists, execs, visuals)
keep their static token blocks — the default-winning set is a copy-paste swap into each page's
<style> head.
Ship order
1. Migration: user_prefs + RLS. 2. Shell resolver in app/(app)/layout.tsx.
3. Appearance tab on me.sierrahub.ca with the shortlisted themes. 4. Token classes .t1–.t10
from this file become the canonical theme definitions in app/globals.css.