UI copy is Traditional Chinese; tab routing maps zh-TW names to URL paths. Adding an admin tab touches TAB_NAMES, TAB_PATHS, dividers and the render switch in src/pages/admin/[[...adminArgs]].tsx plus a new src/components/admin/<Name>.tsx.
Zustand persistence is keyed by suffix: state keys ending _local persist to localStorage, _session to sessionStorage (custom storage in store/index.ts). A new persisted key needs BOTH the suffix and an entry in partialize. Unsuffixed keys are memory-only.
Server state belongs in react-query via tRPC hooks; cache freshness is driven by Pusher events (see realtime) — do not add polling.
Images use a custom Next loader; build URLs with getResourceUrl() / getResourceUrlByWidth() (src/lib/common.ts, size variants xs/sm/md/lg). Uploads go to Cloudflare R2 via presigned URLs (src/lib/server/r2.ts + image router).
Tailwind state styling uses twData({ selected, loading, busy, available }) which writes a data-ui attribute; variants target it (see tailwind.config.cjs). Merge classes with twMerge.
Formatting: prettier with semi: false, single quotes, prettier-plugin-tailwindcss. No ESLint config — prettier is the only formatter.