Skill / CSS-first
CSS-first interactivity
Model UI reactions with relational selectors, container/style queries, and native platform elements before adding React state, effects, or event handlers.
Goal
Keep interaction declarative, server-renderable, and JavaScript-free by expressing it in CSS the browser already resolves — reserve React state for logic that is genuinely stateful or asynchronous.
Reach for modern CSS — relational selectors, container and style queries, and native platform elements — before React state, effects, and event handlers, so interaction, sizing, and motion stay declarative, server-rendered, and JavaScript-free.
Checks
1Reveal, size, or restyle from a sibling/parent/child's state with `:has()`, `:focus-within`, and sibling combinators (Tailwind `has-*`, `group-has-*`, `peer-has-*`, `not-*`) instead of tracking hover, open, or selection in `useState` + `onMouseEnter`/`onFocus` handlers.
2Adapt layout to available width with container queries (`@container` + `@md:`/`@max-md:`) rather than a `ResizeObserver` measuring the element in JS; use `@container style(--x: y)` or a `data-*` attribute variant to branch on a token instead of reading a CSS variable in JS.
3Let native elements own open state, dismissal, and the top layer: the `popover` attribute + Popover API (Baseline widely available) and `<dialog>` replace hand-written outside-click, Escape, focus-trap, and z-index code; `<details>`/`::details-content` gives a semantic, JS-free disclosure for tool-call and reasoning surfaces.
4Style form and choice state natively: `:user-valid`/`:user-invalid` and `:in-range`/`:out-of-range` (Tailwind `user-invalid:`, `in-range:`) drive validation UI, and `peer-checked:`/`has-checked:` + `accent-color` drive custom switches and checkboxes without mirroring the value into React.
Avoid
1`useState` + `onMouseEnter`/`onMouseLeave`/`onFocus`/`onBlur` (or `useEffect` listeners) whose only job is toggling a class a selector could match.
2`ResizeObserver`/`getBoundingClientRect` used only to pick a responsive layout a container query already expresses, or `getComputedStyle` read in JS to decide a className.
3Reimplementing dropdowns, tooltips, menus, and modals from raw divs when the native popover/dialog primitives already own open state, light-dismiss, and focus.