- tsdown.config.ts gains the three CSS virtual loaders mirrored verbatim
from packages/client/tsdown.client.ts: .module.css (lightningcss-hashed
class map + tagged injection), .css?inline (compiled text), and plain
.css (unhashed tagged injection), each registered as a watch dependency
- src/client/styles.ts (223 rules as a string array) becomes
src/client/styles.css — real stylesheet authoring, minified by
lightningcss at build (client bundle 134.8 -> 130.3 kB)
- injection now happens at factory materialization with the official tag
shape (data-plugin + data-plugin-css + dedupe guard), replacing the
hand-rolled ctx.effect; the HMR receiver owns removal by data-plugin,
so the hmr spec pins that lifecycle instead of fiber disposal
- Decision: class names keep the flat lc-* namespace (the anti-collision
discipline, per the research note) instead of per-component hashed
modules — the stylesheet's rules are interconnected across components
(parent:hover child, shared state classes) and 241 test selectors read
literal classes off the built bundle, which a content hash would make
unknowable; the hashed .module.css channel is mirrored and available
for future self-contained components
- globals.d.ts declares the *.css / *.module.css module shapes for the
strict typecheck