Drop Tailwind for plain CSS modules - #624
Open
kcarnold wants to merge 1 commit into
Open
Conversation
The app only ever used a thin layer of Tailwind utilities, mostly for layout and one-off colors. This ports the remaining ones to CSS modules alongside the styles they sit next to, and removes the toolchain. Preflight is kept, vendored as `src/preflight.css` and left in `@layer base` where `@import 'tailwindcss'` put it. All CSS modules here are written against that reset -- universal `box-sizing: border-box`, zeroed margin/padding/border, `font: inherit` on form controls, unstyled links -- and only a handful declare `box-sizing` themselves. Removing the import without keeping the reset would have restyled every page. The layer matters as much as the contents: unlayered CSS beats layered CSS regardless of specificity, which is what lets `components/markdown/styles.module.css` put list markers and heading sizes back with a single class and no `!important`. Vendoring preflight unlayered would silently flip those contests. The `@tailwindcss/typography` plugin is dropped outright: nothing ever applied a `prose` class, so its `.prose` overrides in `taskpane.css` were dead. `editor/styles.css` had nothing left but the two Tailwind imports, so `editor/index.tsx` now imports the reset directly. Comments and docs that attributed the reset to Tailwind now point at `src/preflight.css` -- the mechanism they describe is unchanged, and `@layer base` still holds. Touches `docs/markdown-rendering.md`, `frontend/CLAUDE.md`, and the two `components/markdown/` files. Build/dependency effects: - 41 packages leave the lockfile, including the native `@tailwindcss/ oxide` and `lightningcss` binaries for all 9 target platforms. - `postcss.config.js` is now just reshaped's config, unwrapped. - eslint no longer references a `tailwind.config.js` that never existed. Verified: typecheck, lint, 239 tests, and both `vite build` and `BUILD_TARGET=google-docs vite build`. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
kcarnold
force-pushed
the
chore/remove-tailwind
branch
from
August 27, 2026 23:38
96159c8 to
ff1e131
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Rebased onto
mainnow that #621 and #623 have landed.The app only ever used a thin layer of Tailwind utilities, mostly for layout and one-off colors. This ports the remaining ones to CSS modules alongside the styles they sit next to, and removes the toolchain.
Preflight is the load-bearing part
@import 'tailwindcss'brings in Tailwind's reset, and this app leans on it hard: nearly every CSS module assumes zeroed margin/padding/border and universalbox-sizing: border-box, but only a handful declarebox-sizingthemselves. It also suppliesfont: inheriton form controls anda { color: inherit; text-decoration: inherit }. So preflight is vendored assrc/preflight.css— verbatim, with--theme(--x, fallback)calls resolved to their fallbacks.It stays in
@layer base, where@import 'tailwindcss'put it. The layer matters as much as the contents: unlayered CSS beats layered CSS regardless of specificity, which is exactly what letscomponents/markdown/styles.module.css(from #621) put list markers and heading sizes back with a single class and no!important. Vendoring preflight unlayered would silently flip those contests. Verified@layer basesurvives into the emitted CSS.Doc and comment updates
Four places attributed the reset to Tailwind. The mechanism they describe is unchanged — only the source moves, and
@layer basestill holds:docs/markdown-rendering.md(intro + the preflight section)frontend/CLAUDE.mdcomponents/markdown/index.tsxcomponents/markdown/styles.module.csseditor/styles.cssno longer exists, so references to it are gone too.Build and dependency effects
@tailwindcss/oxideandlightningcssbinaries for all 9 target platforms — the meaningful win for Docker build time and image size.postcss.config.jscollapses to reshaped's config, unwrapped.tailwind.config.jsthat never existed here.Also dropped as dead
@tailwindcss/typographyand the.proserules intaskpane.css— nothing ever applied aproseclass, and Fix markdown rendering in Chat: tables, list formatting, and doctext citations #621 wrote its own.markdownelement styles rather than using it..container inputblock inlogs/styles.module.css—containeris a DOM id (getElementById('container')), so that CSS-module class never matched anything. Fix markdown rendering in Chat: tables, list formatting, and doctext citations #621 noted the file was imported nowhere; this branch imports it and drops the dead block.editor/styles.css, which had nothing left but the two Tailwind imports.Colors
Ported values are the v4 palette. Tailwind v4 ships colors in oklch, so v3 hex codes are wrong here —
blue-300is#8ec5ff, not#bfdbfe(that's blue-200), andblue-500,green-500andred-600all differ visibly. Values were converted fromtheme.cssrather than transcribed, so this should be a pixel no-op and needs no snapshot regeneration.Verified
npm run typecheck,npm run lint,npm test(239 passing),npm run format:check(unchanged at 5 pre-existing warnings),npm run build, andBUILD_TARGET=google-docs vite build.🤖 Generated with Claude Code