Judgement calls for review. Mechanical rules live in oxlint (packages/oxlint-config, frontend/.oxlintrc.json) — not repeated here.
- Tailwind classes via the
classprop. Conditional classes:class={cn("base", { "opacity-0": cond() })}(frontend/src/ts/utils/cn.ts, tailwind-merge — later classes win). - Colors: only those defined in the Tailwind config. No hex/rgb literals, no inline
stylefor anything Tailwind can express (arbitrary values likegrid-cols-[...]are fine).
- Legacy (vanilla) code:
<i class="fas fa-...">FontAwesome tags. - Solid code:
Facomponent (frontend/src/ts/components/common/Fa.tsx).
- Callback ref assignment:
let inputRef: HTMLInputElement | undefined;+ref={(el) => (inputRef = el)}. Not thelet ref!: Tdefinite-assignment pattern. - Act on refs in
onMount, notcreateEffect.
New Solid modal must be registered in both:
frontend/src/ts/components/modals/Modals.tsx— render itfrontend/src/ts/states/modals.ts— add itsModalId
Missing either → modal never shows.
- When migrating a module, convert its importers to named imports too, and rename overly generic exports (
getState→getClientState) so named imports stay readable.
- A diff that changes behaviour updates the comments describing it: search comments for every name the diff removes or renames (functions, components, files, docs).