Repository navigation
fix: classes that compiled to nothing, SSR column mismatches, and a CI guard - #6850
tsahimatsliah wants to merge 10 commits into
Conversation
…I guard The phone shell (#6767) broke desktop feed settings by splitting `w-74` into `tablet:w-74 w-full`: `w-74` had never existed, so the no-op turned into a desktop regression (#6840 fixed it). This sweeps the rest of the classes that compile to nothing and guards against new ones. Dead classes, now real: - Spotlight: `animate-spotlight-scrim-in`, `-panel-in` and `-list-fade` were never defined; keyframes and animations added. - `bg-<token>/NN` alpha modifiers cannot apply to CSS-variable colours (hot takes sparks and blobs, composer spam warning): `color-mix`. - `opacity-70/80` -> `opacity-64`, `z-10` -> `z-1`, `z-20` -> `z-[20]`, `hover:opacity-90` on the brand button -> `hover:brightness-90`, `hover:bg-action-blueCheese-hober` -> `hover:bg-accent-blueCheese-flat`. - `shadow-1`, `line-clamp-10`, `scale-60`, `scale-80` added to the config so the three places that already use them render. Hydration: - `MainFeedLayout`'s `--num-cards` and the tag page's follow grid rendered the client's column count on the hydration pass while the server rendered one column. In production React keeps a mismatched attribute, so the layout stayed one column until a later re-render. `useIsHydrated` renders the server value on that pass and the real one after mount; later mounts start hydrated, so client navigation does not flash. CI: - `scripts/check-dead-classes.mjs` compiles every class added by a branch through the real Tailwind config and fails on tokens with no selector. Runs as `dead_classes_changed` next to the strict typecheck. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
- Alpha modifiers work on the accent, text and status tokens (`withAlpha` wraps each variable with Tailwind's `<alpha-value>`), so the hot takes and composer classes are written as `bg-x/40` or, for an alpha outside the opacity scale, `bg-x/[0.35]`, not color-mix literals. - The three classes that never applied are deleted rather than replaced: the analytics button's hover (its Secondary pressed fill was the shipped look), the feedback caption's opacity (contrast), and the brand button's hover. - `useIsHydrated` reads React's own hydration state through `useSyncExternalStore`, so a boundary hydrated after the first effects still renders the server value; `MainLayoutHeader` uses it too. - The spotlight animations fade opacity only, so `both` leaves no transform on the scrolling list or the panel. - The checker skips tokens that touch an interpolation, scans whole files and keeps the literals that reach an added line, and follows the repo's Prettier config. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
tsahimatsliah
left a comment
There was a problem hiding this comment.
Reviewed the diff, compiled the Tailwind config on main and on this branch, and read the failing CI logs.
Blocking
- CI is red.
lint_sharedand the lint step intest_webappfail withtailwindcss/classnames-orderin files this PR doesn't touch:PostFocusCard.tsx:794,SidebarDesktopV2.tsx:2544,Spotlight.tsx:1016and:1103, andDevCardStep2.tsx:249. The cause is that registeringshadow-1,scale-60/80andanimate-spotlight-*as real utilities changes where the sorter puts them. Runningeslint --fixon those five files should fix it. caret-text-linkbreaks on every text field (inline comment onwithAlpha.ts).
Non-blocking
- The SSR column fix covers two consumers, but
FeedContainerwrites the same--num-cardswithout the gate (inline). - 6 existing
/10,/20and/30usages still compile to nothing, and the diff-only guard won't flag them (inline). eslint-plugin-tailwindcssis already installed, and itsno-custom-classnamerule covers what the new script does (inline).- Classes that never applied before now render, so several surfaces change visually. Before/after screenshots are needed (inline).
- Scope: this PR combines a change to every
text-*,accent-*andstatus-*utility (each now compiles tocolor-mix), a new hydration hook, a new CI tool and several visual changes. Splitting the colour-token change and the CI guard into their own PRs would make each one cheaper to review and to revert.
Reviewed by AI.
Review follow-up (c094692)Blocking
Non-blocking
Verified locally on c094692: lint clean in shared, webapp and extension; webapp typecheck clean (shared and extension each have one pre-existing spec typing error this branch does not touch); 518 shared suites (3,827 tests) and 110 webapp suites (850 tests) pass. |
… hydration gate - The custom `caret` plugin wrote theme colours straight into `caret-color` and passed `<alpha-value>` through; core Tailwind generates the same `caret-*` classes from `theme.colors` and resolves the placeholder, so the plugin is gone. - `withAlpha` also wraps the surface, background and overlay tokens, and every alpha modifier in the repo that is off the opacity scale is an arbitrary alpha (`bg-x/[0.1]`), so no `/NN` on a token compiles to nothing any more. - The hydration gate lives in `FeedLayoutProvider`: it serves the default column count on the hydration render and the real one after mount, which covers `FeedContainer`, `Feed`, `useFeed` and the two call sites that had their own gate. - `shadow-1`, `scale-60`, `scale-80` and the two `z-1`s only changed looks and were never designed in; the classes are deleted instead of made real. - Class order fixed in the files the new utilities re-sorted. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…lpha class Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
|
CI is green on 0b0c4c7. The one failure after the last round was |
It guards future PRs rather than fixing anything here; it will be proposed separately, folded into the no-custom-classname lint rule. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Why
The phone shell (#6767) broke desktop feed settings by splitting
w-74intotablet:w-74 w-full.w-74had never existed in our Tailwind config, so a no-op became a desktop regression (#6840 fixed it). A sweep of the files the shell PRs touched found more classes that compile to nothing and two SSR mismatches. This PR fixes what the sweep found.Changes
Alpha modifiers work on tokens
bg-accent-avocado-default/40and friends compiled to nothing because the token colours were barevar(--theme-…)strings.withAlphawraps the accent, text, status, surface, background and overlay tokens with Tailwind's<alpha-value>placeholder, so/NNworks for an alpha on the opacity scale (16, 24, 32, 40, 50, 64) and/[0.35]for any other value. Every off-scale modifier in the repo is written in the bracket form now. The plain utilities compile to the same colour as before.caretplugin is removed: it wrote theme colours straight intocaret-colorand would have passed the placeholder through. Core Tailwind generates the samecaret-*classes fromtheme.colors.Dead classes
animate-spotlight-scrim-in,animate-spotlight-panel-inandanimate-spotlight-list-fadewere never defined (since feat: spotlight feature #6011). All three fade opacity only, so thebothfill leaves no transform on the scrolling list or the panel.opacity-70→opacity-64(the scale has no 70),z-20→z-[20](keeps its place under thez-[21]overlay),line-clamp-10added to the config.shadow-1,scale-60,scale-80, twoz-10s, the post analytics button'shover:bg-action-blueCheese-hober, the feedback caption'sopacity-80, the squad brand button'shover:opacity-90.Hydration
MainFeedLayout's--num-cardsand the tag page's follow grid rendered the client's column count on the hydration pass while the server rendered one column (dev warned on/searchat tablet width and on every tag page). In production React keeps a mismatched attribute, so the layout stayed one column until something re-rendered the component.FeedLayoutProvidernow serves the default column count on the hydration render and the real one after mount, throughuseIsHydrated, which reads React's own hydration state viauseSyncExternalStore(so a boundary hydrated after the first effects still gets the server value, and later mounts never flash).MainLayoutHeaderdrops its localhasHydratedstate for it.numCardsis not in any query key, so nothing refetches.Verified
packages/webapp/tailwind.config.ts(checked with a one-off script, not part of this PR).mainand the branch.Events
No new event names.
Experiment
None.
🤖 Generated with Claude Code
Preview domain
https://dead-classes-hydration-dailydotd.preview.app.daily.dev