Appearance
Bulma → Tailwind CSS platform
Last updated: 2026-08-11
This document is the source of truth for the SafeCall web admin SPA CSS platform (Tailwind CSS v4). The Bulma → Tailwind migration is complete (#62 / umbrella #52). Historical playbooks remain under docs/ai/tailwind/.
| Related | Role |
|---|---|
| Umbrella | sourcecontrollers/safecall#52 (closed with #62) |
| Playbooks | docs/ai/tailwind/ |
| Web overview | docs/web/index.md |
| Build | docs/web/build.md |
| GitLab workflow | docs/ai/gitlab-issues.md |
| Agent rule | .cursor/rules/tailwind-theming.mdc (repo root; not part of this docs site) |
| Agent skill | .cursor/skills/tailwind-ui/SKILL.md (repo root; not part of this docs site) |
Audience: coding agents and operators maintaining the web UI CSS platform—not a visual redesign.
Current state (post-cutover)
| Fact | Detail |
|---|---|
| Framework | Tailwind CSS v4 via @tailwindcss/cli in web/build.ts |
| Theme | data-theme="dark" on <html> (light tokens defined for parity; no product toggle) |
| Custom CSS | Source under web/src/css/; compiled to web/build/css/tailwind.css |
| Build | Bun web/build.ts bundles JS + compiles Tailwind (theme + preflight + utilities + catalog) |
| Icons | Font Awesome |
| Agent guidance | Always-on tailwind-theming rule + tailwind-ui skill |
Locked decisions (still in force)
| Decision | Choice |
|---|---|
| Framework | Tailwind CSS v4 via @tailwindcss/cli |
| Primitives | Small @layer components catalog (.btn, .tag, .notification, .modal, .field, …) + utilities for layout/spacing |
| Soft/solid | Explicit variants (tag-info-soft) — never a bare “light” modifier |
| Theme API | data-theme on <html> (dark default). Do not use class="dark" |
| Icons | Keep Font Awesome |
| CSS source | App CSS under web/src/css/; web/build/css/ is compile/static output |
| Notifications | UiNotification → catalog classes |
Sequence (completed)
mermaid
flowchart LR
S53[53_Toolchain]
S54[54_SharedHelpers]
S55[55_ShellAuth]
S56[56_UserSurfaces]
S57[57_AdminAssetCRUD]
S58[58_AdminSpatial]
S59[59_AdminEinkSensors]
S60[60_AdminTools]
S61[61_AdminRemaining]
S62[62_DropBulma]
S53 --> S54 --> S55 --> S56
S55 --> S57 --> S58 --> S59 --> S60 --> S61 --> S62
S56 --> S62| Order | Issue | Playbook | Scope |
|---|---|---|---|
| 1 | #53 | 53-tailwind-toolchain.md | Tailwind v4 + tokens + catalog; Bulma coexistence |
| 2 | #54 | 54-shared-helpers-tailwind.md | Notifications, modals, enum, shared class builders |
| 3 | #55 | 55-shell-auth-tailwind.md | Navbar, login, settings, generic delete modal |
| 4 | #56 | 56-user-surfaces-tailwind.md | User sensors / RTLS / directory / events / maintenance |
| 5 | #57 | 57-admin-asset-crud-tailwind.md | Users, devices, beacons, gateways |
| 6 | #58 | 58-admin-spatial-tailwind.md | Locations, maps, zones, navigation |
| 7 | #59 | 59-admin-eink-sensors-tailwind.md | Eink suite + admin sensors overview |
| 8 | #60 | 60-admin-tools-tailwind.md | Standalone admin tools |
| 9 | #61 | 61-admin-remaining-tailwind.md | Dashboard, translations, bug-tracker, interface-templates; leftover CSS |
| 10 | #62 | 62-drop-bulma-preflight.md | Remove Bulma; enable preflight; agent docs |
Checklist
- [x] #53 Toolchain + tokens + catalog
- [x] #54 Shared helpers
- [x] #55 Shell + auth + settings
- [x] #56 User surfaces
- [x] #57 Admin asset CRUD
- [x] #58 Admin spatial
- [x] #59 Admin eink + sensors
- [x] #60 Admin tools
- [x] #61 Admin remaining
- [x] #62 Drop Bulma + preflight
- [x] Close umbrella #52 after #62
Exit criteria (umbrella #52) — met
- Web app builds and runs without Bulma
- Dark-first semantic tokens + component catalog in use across migrated surfaces
data-themetheming (notheme-dark/class="dark")- Agent rules/skill updated;
docs/web/*describe Tailwind as the stack - Grep gate clean of Bulma-only leftovers (
is-lightas sole chip color,--bulma-*,bulmapackage)
Out of scope (whole program)
- Visual redesign / new brand palette (beyond mapping current dark UI to tokens)
- Shipping a light-mode toggle product feature (tokens may exist for future use)
- Migrating away from Font Awesome
- Mobile app or VitePress docs site theming
- Wiring
Brand.primary_colorinto runtime CSS (optional follow-up)