Skip to content

chore: Tailwind CSS v4 migration#4139

Open
kathiekiwi wants to merge 14 commits into
mainfrom
chore/tw4
Open

chore: Tailwind CSS v4 migration#4139
kathiekiwi wants to merge 14 commits into
mainfrom
chore/tw4

Conversation

@kathiekiwi

Copy link
Copy Markdown
Collaborator

Migrates the webapp from Tailwind CSS 3.4 to 4.x.
CSS-first @theme in app/tailwind.css replaces tailwind.config.js. Semantic color tokens are CSS variables overridable per theme support.

Note: the default palette is now oklch.

Testing

Typecheck, format and lint pass. Verified visually against the local dashboard — colors, borders, scrollbars, animations and focus s

CSS-first @theme in app/tailwind.css: static palettes plus semantic color
tokens as CSS variables, overridable per theme. Tailwind runs through
@tailwindcss/postcss (Remix integration off). Plugins upgraded or replaced
with v4 equivalents; tailwind-merge bumped to v3. Utility classes codemodded
by the official upgrade tool. Fixed two invalid arbitrary variants the
upgrade surfaced (table sticky cell :has(), number input attribute variant).
prism-react-renderer passes extra props through, so key ended up in the
spread and triggered a React warning. Key is already set directly on the
elements.
@changeset-bot

changeset-bot Bot commented Jul 3, 2026

Copy link
Copy Markdown

⚠️ No Changeset found

Latest commit: 9f1a6ce

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@kathiekiwi kathiekiwi changed the title Chore/tw4 chore: Tailwind CSS v4 migration Jul 3, 2026
@coderabbitai

coderabbitai Bot commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Important

Review skipped

Too many files!

This PR contains 208 files, which is 58 over the limit of 150.

To get a review, narrow the scope:
• coderabbit review --type committed # exclude uncommitted changes
• coderabbit review --dir # limit to a subdirectory
• coderabbit review --base # compare against a closer base

Upgrade to a paid plan to raise the limit.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 2d3a63dc-90bb-4bc1-8d7a-affcac41159f

📥 Commits

Reviewing files that changed from the base of the PR and between 5e83039 and 9f1a6ce.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (208)
  • .server-changes/theme-color-tokens.md
  • apps/webapp/app/components/AskAI.tsx
  • apps/webapp/app/components/BlankStatePanels.tsx
  • apps/webapp/app/components/DefinitionTooltip.tsx
  • apps/webapp/app/components/ListPagination.tsx
  • apps/webapp/app/components/LoginPageLayout.tsx
  • apps/webapp/app/components/ProductHuntBanner.tsx
  • apps/webapp/app/components/UserProfilePhoto.tsx
  • apps/webapp/app/components/admin/FeatureFlagsDialog.tsx
  • apps/webapp/app/components/admin/backOffice/MaxProjectsSection.tsx
  • apps/webapp/app/components/admin/backOffice/RateLimitSection.tsx
  • apps/webapp/app/components/billing/FreePlanUsage.tsx
  • apps/webapp/app/components/billing/UsageBar.tsx
  • apps/webapp/app/components/code/AIQueryInput.tsx
  • apps/webapp/app/components/code/ChartConfigPanel.tsx
  • apps/webapp/app/components/code/CodeBlock.tsx
  • apps/webapp/app/components/code/InlineCode.tsx
  • apps/webapp/app/components/code/QueryResultsChart.tsx
  • apps/webapp/app/components/code/TSQLEditor.tsx
  • apps/webapp/app/components/code/TSQLResultsTable.tsx
  • apps/webapp/app/components/code/codeMirrorTheme.ts
  • apps/webapp/app/components/code/shikiTheme.ts
  • apps/webapp/app/components/dashboard-agent/AgentChart.tsx
  • apps/webapp/app/components/dashboard-agent/DashboardAgentComposer.tsx
  • apps/webapp/app/components/dashboard-agent/DashboardAgentContextBanner.tsx
  • apps/webapp/app/components/dashboard-agent/DashboardAgentHeader.tsx
  • apps/webapp/app/components/dashboard-agent/DashboardAgentHistory.tsx
  • apps/webapp/app/components/dashboard-agent/DashboardAgentMessages.tsx
  • apps/webapp/app/components/dashboard-agent/DashboardAgentSuggestedPrompts.tsx
  • apps/webapp/app/components/dashboard-agent/RunDiagnosisCard.tsx
  • apps/webapp/app/components/dashboard-agent/dashboardAgentLauncher.tsx
  • apps/webapp/app/components/environments/RegenerateApiKeyModal.tsx
  • apps/webapp/app/components/errors/ConfigureErrorAlerts.tsx
  • apps/webapp/app/components/integrations/VercelBuildSettings.tsx
  • apps/webapp/app/components/integrations/VercelOnboardingModal.tsx
  • apps/webapp/app/components/layout/AppLayout.tsx
  • apps/webapp/app/components/logs/LogDetailView.tsx
  • apps/webapp/app/components/logs/LogsLevelFilter.tsx
  • apps/webapp/app/components/logs/LogsTable.tsx
  • apps/webapp/app/components/metrics/SaveToDashboardDialog.tsx
  • apps/webapp/app/components/metrics/ScopeFilter.tsx
  • apps/webapp/app/components/navigation/AccountSideMenu.tsx
  • apps/webapp/app/components/navigation/DashboardDialogs.tsx
  • apps/webapp/app/components/navigation/DashboardList.tsx
  • apps/webapp/app/components/navigation/EnvironmentSelector.tsx
  • apps/webapp/app/components/navigation/HelpAndFeedbackPopover.tsx
  • apps/webapp/app/components/navigation/NotificationCard.tsx
  • apps/webapp/app/components/navigation/OrganizationSettingsSideMenu.tsx
  • apps/webapp/app/components/navigation/SideMenu.tsx
  • apps/webapp/app/components/navigation/SideMenuHeader.tsx
  • apps/webapp/app/components/navigation/SideMenuItem.tsx
  • apps/webapp/app/components/navigation/SideMenuSection.tsx
  • apps/webapp/app/components/onboarding/TechnologyPicker.tsx
  • apps/webapp/app/components/primitives/AppliedFilter.tsx
  • apps/webapp/app/components/primitives/Badge.tsx
  • apps/webapp/app/components/primitives/Buttons.tsx
  • apps/webapp/app/components/primitives/Calendar.tsx
  • apps/webapp/app/components/primitives/Callout.tsx
  • apps/webapp/app/components/primitives/Checkbox.tsx
  • apps/webapp/app/components/primitives/CheckboxIndicator.tsx
  • apps/webapp/app/components/primitives/ClientTabs.tsx
  • apps/webapp/app/components/primitives/ClipboardField.tsx
  • apps/webapp/app/components/primitives/CopyButton.tsx
  • apps/webapp/app/components/primitives/CopyableText.tsx
  • apps/webapp/app/components/primitives/DateField.tsx
  • apps/webapp/app/components/primitives/DateTimePicker.tsx
  • apps/webapp/app/components/primitives/DetailCell.tsx
  • apps/webapp/app/components/primitives/Dialog.tsx
  • apps/webapp/app/components/primitives/Icon.tsx
  • apps/webapp/app/components/primitives/Input.tsx
  • apps/webapp/app/components/primitives/InputNumberStepper.tsx
  • apps/webapp/app/components/primitives/InputOTP.tsx
  • apps/webapp/app/components/primitives/PageHeader.tsx
  • apps/webapp/app/components/primitives/Pagination.tsx
  • apps/webapp/app/components/primitives/Popover.tsx
  • apps/webapp/app/components/primitives/RadioButton.tsx
  • apps/webapp/app/components/primitives/Resizable.tsx
  • apps/webapp/app/components/primitives/SearchInput.tsx
  • apps/webapp/app/components/primitives/SegmentedControl.tsx
  • apps/webapp/app/components/primitives/Select.tsx
  • apps/webapp/app/components/primitives/Sheet.tsx
  • apps/webapp/app/components/primitives/SheetV3.tsx
  • apps/webapp/app/components/primitives/ShortcutKey.tsx
  • apps/webapp/app/components/primitives/SimpleSelect.tsx
  • apps/webapp/app/components/primitives/Slider.tsx
  • apps/webapp/app/components/primitives/StepNumber.tsx
  • apps/webapp/app/components/primitives/Switch.tsx
  • apps/webapp/app/components/primitives/Table.tsx
  • apps/webapp/app/components/primitives/Tabs.tsx
  • apps/webapp/app/components/primitives/TextArea.tsx
  • apps/webapp/app/components/primitives/TreeView/TreeView.tsx
  • apps/webapp/app/components/primitives/UsageSparkline.tsx
  • apps/webapp/app/components/primitives/charts/Chart.tsx
  • apps/webapp/app/components/primitives/charts/ChartBar.tsx
  • apps/webapp/app/components/primitives/charts/ChartBlankState.tsx
  • apps/webapp/app/components/primitives/charts/ChartLegendCompound.tsx
  • apps/webapp/app/components/primitives/charts/ChartLine.tsx
  • apps/webapp/app/components/primitives/charts/ChartLoading.tsx
  • apps/webapp/app/components/primitives/charts/ChartZoom.tsx
  • apps/webapp/app/components/primitives/charts/statusColors.ts
  • apps/webapp/app/components/query/QueryEditor.tsx
  • apps/webapp/app/components/runs/v3/AIFilterInput.tsx
  • apps/webapp/app/components/runs/v3/BatchFilters.tsx
  • apps/webapp/app/components/runs/v3/DeploymentStatus.tsx
  • apps/webapp/app/components/runs/v3/PromptSpanDetails.tsx
  • apps/webapp/app/components/runs/v3/ReplayRunDialog.tsx
  • apps/webapp/app/components/runs/v3/RunFilters.tsx
  • apps/webapp/app/components/runs/v3/RunTag.tsx
  • apps/webapp/app/components/runs/v3/ScheduleFilters.tsx
  • apps/webapp/app/components/runs/v3/SharedFilters.tsx
  • apps/webapp/app/components/runs/v3/SpanHorizontalTimeline.tsx
  • apps/webapp/app/components/runs/v3/SpanTitle.tsx
  • apps/webapp/app/components/runs/v3/TaskRunAttemptStatus.tsx
  • apps/webapp/app/components/runs/v3/TaskRunStatus.tsx
  • apps/webapp/app/components/runs/v3/TaskRunsTable.tsx
  • apps/webapp/app/components/runs/v3/WaitpointTokenFilters.tsx
  • apps/webapp/app/components/runs/v3/agent/AgentMessageView.tsx
  • apps/webapp/app/components/runs/v3/ai/AIChatMessages.tsx
  • apps/webapp/app/components/runs/v3/ai/AIEmbedSpanDetails.tsx
  • apps/webapp/app/components/runs/v3/ai/AIModelSummary.tsx
  • apps/webapp/app/components/runs/v3/ai/AISpanDetails.tsx
  • apps/webapp/app/components/runs/v3/ai/AIToolCallSpanDetails.tsx
  • apps/webapp/app/components/runs/v3/ai/AIToolsInventory.tsx
  • apps/webapp/app/components/runs/v3/ai/SpanMetricRow.tsx
  • apps/webapp/app/components/scheduled/timezones.tsx
  • apps/webapp/app/components/schedules/ScheduleInspector.tsx
  • apps/webapp/app/components/sessions/v1/SessionFilters.tsx
  • apps/webapp/app/components/sessions/v1/SessionsTable.tsx
  • apps/webapp/app/root.tsx
  • apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam._index/route.tsx
  • apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.agents.$agentParam/route.tsx
  • apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.alerts/route.tsx
  • apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.batches.$batchParam/route.tsx
  • apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.branches/route.tsx
  • apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.bulk-actions.$bulkActionParam/route.tsx
  • apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.dashboards.$dashboardKey/route.tsx
  • apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.dashboards._index/route.tsx
  • apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.deployments.$deploymentParam/route.tsx
  • apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.dev-branches/route.tsx
  • apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.environment-variables.new/route.tsx
  • apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.environment-variables/route.tsx
  • apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.errors.$fingerprint/route.tsx
  • apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.errors._index/route.tsx
  • apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.models._index/route.tsx
  • apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.playground.$agentParam/route.tsx
  • apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.prompts.$promptSlug/route.tsx
  • apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.prompts._index/route.tsx
  • apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.query/AITabContent.tsx
  • apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.query/QueryHelpSidebar.tsx
  • apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.query/QueryHistoryPopover.tsx
  • apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.query/TRQLGuideContent.tsx
  • apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.query/TableSchemaContent.tsx
  • apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.regions/route.tsx
  • apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.runs.$runParam/route.tsx
  • apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.sessions.$sessionParam/route.tsx
  • apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.tasks.dashboard/route.tsx
  • apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.tasks.scheduled.$taskParam/route.tsx
  • apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.tasks.standard.$taskParam/route.tsx
  • apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.test.tasks.$taskParam/AIPayloadTabContent.tsx
  • apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.test.tasks.$taskParam/TestSidebarTabs.tsx
  • apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.test.tasks.$taskParam/route.tsx
  • apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.waitpoints.tokens.$waitpointParam/route.tsx
  • apps/webapp/app/routes/_app.orgs.$organizationSlug.settings._index/route.tsx
  • apps/webapp/app/routes/_app.orgs.$organizationSlug.settings.integrations.slack.tsx
  • apps/webapp/app/routes/_app.orgs.$organizationSlug.settings.private-connections._index/route.tsx
  • apps/webapp/app/routes/_app.orgs.$organizationSlug.settings.private-connections.new/route.tsx
  • apps/webapp/app/routes/_app.orgs.$organizationSlug.settings.roles/route.tsx
  • apps/webapp/app/routes/_app.orgs.$organizationSlug.settings.sso/route.tsx
  • apps/webapp/app/routes/_app.orgs.$organizationSlug.settings.team/route.tsx
  • apps/webapp/app/routes/_app.orgs.$organizationSlug_.projects.new/route.tsx
  • apps/webapp/app/routes/_app.orgs.$organizationSlug_.select-plan/route.tsx
  • apps/webapp/app/routes/_app.orgs.new/route.tsx
  • apps/webapp/app/routes/_app.timezones/route.tsx
  • apps/webapp/app/routes/account.tokens/route.tsx
  • apps/webapp/app/routes/admin.feature-flags.tsx
  • apps/webapp/app/routes/admin.llm-models.$modelId.tsx
  • apps/webapp/app/routes/admin.llm-models._index.tsx
  • apps/webapp/app/routes/admin.llm-models.missing.$model.tsx
  • apps/webapp/app/routes/admin.llm-models.new.tsx
  • apps/webapp/app/routes/admin.notifications.tsx
  • apps/webapp/app/routes/confirm-basic-details.tsx
  • apps/webapp/app/routes/invites.tsx
  • apps/webapp/app/routes/login._index/route.tsx
  • apps/webapp/app/routes/resources.orgs.$organizationSlug.projects.$projectParam.env.$envParam.runs.$runParam.spans.$spanParam/route.tsx
  • apps/webapp/app/routes/resources.orgs.$organizationSlug.projects.$projectParam.env.$envParam.runs.$runParam.streams.$streamKey/route.tsx
  • apps/webapp/app/routes/resources.orgs.$organizationSlug.projects.$projectParam.env.$envParam.runs.bulkaction.tsx
  • apps/webapp/app/routes/resources.orgs.$organizationSlug.projects.$projectParam.env.$envParam.schedules.new/route.tsx
  • apps/webapp/app/routes/resources.orgs.$organizationSlug.projects.$projectParam.env.$envParam.waitpoints.$waitpointFriendlyId.complete/route.tsx
  • apps/webapp/app/routes/resources.orgs.$organizationSlug.projects.$projectParam.schedules.new.natural-language.tsx
  • apps/webapp/app/routes/resources.orgs.$organizationSlug.select-plan.tsx
  • apps/webapp/app/routes/storybook.animated-panel/route.tsx
  • apps/webapp/app/routes/storybook.buttons/route.tsx
  • apps/webapp/app/routes/storybook.charts/route.tsx
  • apps/webapp/app/routes/storybook.detail-cell/route.tsx
  • apps/webapp/app/routes/storybook.page-header/route.tsx
  • apps/webapp/app/routes/storybook.popover/route.tsx
  • apps/webapp/app/routes/storybook.spinner/route.tsx
  • apps/webapp/app/routes/storybook.streamdown/route.tsx
  • apps/webapp/app/routes/storybook.tabs.$tabNumber/route.tsx
  • apps/webapp/app/routes/storybook.tabs/route.tsx
  • apps/webapp/app/routes/storybook.timeline/route.tsx
  • apps/webapp/app/routes/storybook.tree-view/route.tsx
  • apps/webapp/app/routes/storybook.tsql-editor/route.tsx
  • apps/webapp/app/routes/storybook.unordered-list/route.tsx
  • apps/webapp/app/routes/storybook/route.tsx
  • apps/webapp/app/routes/vercel.onboarding.tsx
  • apps/webapp/app/tailwind.css
  • apps/webapp/package.json

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Walkthrough

This PR migrates the webapp from Tailwind CSS v3 to v4. It rewrites tailwind.css using v4's @import, @theme, @utility, and @plugin syntax, updates PostCSS/Remix build configuration to route through @tailwindcss/postcss, removes tailwind.config.js, and updates package dependencies. Widespread className updates across components and routes replace v3-specific syntax (e.g., outline-none to outline-hidden, ! prefix modifiers to suffix form, bracketed arbitrary values to token-based utilities). Additionally, an unrelated change renames the "shadow" realtime backend/template mode identifier to "shadow-sm" in feature flags, resolver logic, and the compute template creation service, plus a corresponding update in a random-words utility.

Changes

Area Changes
Build/config Updated package.json, postcss.config.js, remix.config.js; removed tailwind.config.js; narrowed cn.ts merge config; added migration changelog
Global styles Rewrote tailwind.css with v4 theme/utility/layer syntax
Primitives Updated focus/outline, blur, spacing, and modifier syntax across shared UI primitives (Buttons, Dialog, Table, Popover, Select, Checkbox, Switch, Slider, Calendar, Charts, etc.)
Navigation Updated padding, width, and important-modifier syntax in SideMenu, SideMenuItem, EnvironmentSelector, popovers
Feature components Updated className syntax across runs, sessions, code, metrics, and query components
Routes Updated container widths, tooltip wrapping, popover sizing, and focus utilities across route files
Realtime backend Renamed "shadow" to "shadow-sm" in feature flags, resolver, template creation service, and word list

Sequence Diagram(s)

Not applicable — this PR consists of styling/className updates and a string identifier rename with no new interaction flows.

Related PRs: None identified.

Suggested labels: frontend, dependencies, chore

Suggested reviewers: webapp maintainers familiar with Tailwind CSS and the design system primitives

Poem

A rabbit hopped through classNames wide,
Swapping outlines, none to hide,
Brackets shed for tokens neat,
v4's theme now feels complete,
Shadow renamed to "shadow-sm" bright—
Hop, hop, ship it, all feels right! 🐇

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Description check ⚠️ Warning It covers the migration and testing, but it omits required template sections like Closes #, checklist, changelog, and screenshots. Add the missing template sections: Closes #, checklist items, a fuller Testing section, a short Changelog, and Screenshots or a note that none are needed.
✅ Passed checks (4 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Title check ✅ Passed The title clearly states the main change: migrating Tailwind CSS to v4.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch chore/tw4

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@pkg-pr-new

pkg-pr-new Bot commented Jul 3, 2026

Copy link
Copy Markdown

Open in StackBlitz

@trigger.dev/build

npm i https://pkg.pr.new/@trigger.dev/build@9f1a6ce

trigger.dev

npm i https://pkg.pr.new/trigger.dev@9f1a6ce

@trigger.dev/core

npm i https://pkg.pr.new/@trigger.dev/core@9f1a6ce

@trigger.dev/python

npm i https://pkg.pr.new/@trigger.dev/python@9f1a6ce

@trigger.dev/react-hooks

npm i https://pkg.pr.new/@trigger.dev/react-hooks@9f1a6ce

@trigger.dev/redis-worker

npm i https://pkg.pr.new/@trigger.dev/redis-worker@9f1a6ce

@trigger.dev/rsc

npm i https://pkg.pr.new/@trigger.dev/rsc@9f1a6ce

@trigger.dev/schema-to-json

npm i https://pkg.pr.new/@trigger.dev/schema-to-json@9f1a6ce

@trigger.dev/sdk

npm i https://pkg.pr.new/@trigger.dev/sdk@9f1a6ce

commit: 9f1a6ce

Adds surface (background-deep/hover/raised, surface-control/-hover/-active),
border (border-bright/brighter/brightest) and text (text-faint) tokens to the
themable layer, and sweeps ~930 raw charcoal-* usages across the dashboard to
use them. Remaining raw charcoal usages are contrast-fixed decoration on
colored accents, intentionally theme-independent.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🧹 Nitpick comments (4)
apps/webapp/app/components/runs/v3/TaskTriggerSource.tsx (1)

16-22: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Minor inconsistency: size-[1.125rem] left as bracket syntax while min-w was converted.

min-w-[1.125rem]min-w-4.5, but the adjacent size-[1.125rem] on the same elements wasn't converted to the equivalent size-4.5. Purely cosmetic consistency in the token-based utility codemod.

♻️ Optional consistency fix
-      return <TaskIconSmall className={cn("size-[1.125rem] min-w-4.5 text-tasks", className)} />;
+      return <TaskIconSmall className={cn("size-4.5 min-w-4.5 text-tasks", className)} />;
apps/webapp/package.json (1)

289-289: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Inconsistent version pinning for tailwindcss.

tailwindcss is pinned to an exact version (4.3.1) while other Tailwind-related devDependencies (@tailwindcss/forms, @tailwindcss/postcss, tailwind-scrollbar) use ^ ranges. If intentional (to lock the core engine during migration), consider a brief comment; otherwise align the range style.

apps/webapp/app/tailwind.css (2)

309-315: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

::-moz-selection vendor-prefix lint error is likely a required exception.

selector-no-vendor-prefix flags line 313, but ::-moz-selection can't be combined into the standard ::selection selector (older Firefox ignores the rule if grouped) — the duplication here is typically intentional. Suggest a scoped stylelint-disable-next-line instead of removing the prefix.

Source: Linters/SAST tools


229-276: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Consider deduplicating animated-gradient-glow and animated-gradient-glow-small.

Both utilities repeat the identical 5-color conic-gradient definition, differing only in inset, filter: blur(...), and opacity. Parameterizing via CSS custom properties (set per-utility, consumed by a single shared rule) would avoid having to keep two gradient stops lists in sync.


ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 05461b5b-921c-4d80-834d-b439b5fbd3da

📥 Commits

Reviewing files that changed from the base of the PR and between 20f9c78 and 5e83039.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (133)
  • .server-changes/tailwind-v4-migration.md
  • apps/webapp/app/components/AskAI.tsx
  • apps/webapp/app/components/BackgroundWrapper.tsx
  • apps/webapp/app/components/DefinitionTooltip.tsx
  • apps/webapp/app/components/Feedback.tsx
  • apps/webapp/app/components/GitMetadata.tsx
  • apps/webapp/app/components/ListPagination.tsx
  • apps/webapp/app/components/ProductHuntBanner.tsx
  • apps/webapp/app/components/WarmStarts.tsx
  • apps/webapp/app/components/code/AIQueryInput.tsx
  • apps/webapp/app/components/code/ChartConfigPanel.tsx
  • apps/webapp/app/components/code/CodeBlock.tsx
  • apps/webapp/app/components/code/TSQLResultsTable.tsx
  • apps/webapp/app/components/dashboard-agent/DashboardAgentComposer.tsx
  • apps/webapp/app/components/dashboard-agent/DashboardAgentHistory.tsx
  • apps/webapp/app/components/logs/LogsTable.tsx
  • apps/webapp/app/components/metrics/BigNumber.tsx
  • apps/webapp/app/components/metrics/QueryWidget.tsx
  • apps/webapp/app/components/metrics/SaveToDashboardDialog.tsx
  • apps/webapp/app/components/metrics/TitleWidget.tsx
  • apps/webapp/app/components/navigation/EnvironmentSelector.tsx
  • apps/webapp/app/components/navigation/HelpAndFeedbackPopover.tsx
  • apps/webapp/app/components/navigation/NotificationPanel.tsx
  • apps/webapp/app/components/navigation/SideMenu.tsx
  • apps/webapp/app/components/navigation/SideMenuItem.tsx
  • apps/webapp/app/components/onboarding/TechnologyPicker.tsx
  • apps/webapp/app/components/primitives/Alert.tsx
  • apps/webapp/app/components/primitives/AnimatingArrow.tsx
  • apps/webapp/app/components/primitives/AppliedFilter.tsx
  • apps/webapp/app/components/primitives/Avatar.tsx
  • apps/webapp/app/components/primitives/Buttons.tsx
  • apps/webapp/app/components/primitives/Calendar.tsx
  • apps/webapp/app/components/primitives/Callout.tsx
  • apps/webapp/app/components/primitives/Checkbox.tsx
  • apps/webapp/app/components/primitives/ClientTabs.tsx
  • apps/webapp/app/components/primitives/ClipboardField.tsx
  • apps/webapp/app/components/primitives/DateField.tsx
  • apps/webapp/app/components/primitives/DateTimePicker.tsx
  • apps/webapp/app/components/primitives/Dialog.tsx
  • apps/webapp/app/components/primitives/Input.tsx
  • apps/webapp/app/components/primitives/InputNumberStepper.tsx
  • apps/webapp/app/components/primitives/InputOTP.tsx
  • apps/webapp/app/components/primitives/LoadingBarDivider.tsx
  • apps/webapp/app/components/primitives/Pagination.tsx
  • apps/webapp/app/components/primitives/Popover.tsx
  • apps/webapp/app/components/primitives/RadioButton.tsx
  • apps/webapp/app/components/primitives/Resizable.tsx
  • apps/webapp/app/components/primitives/SegmentedControl.tsx
  • apps/webapp/app/components/primitives/Select.tsx
  • apps/webapp/app/components/primitives/ShortcutKey.tsx
  • apps/webapp/app/components/primitives/SimpleSelect.tsx
  • apps/webapp/app/components/primitives/Slider.tsx
  • apps/webapp/app/components/primitives/Switch.tsx
  • apps/webapp/app/components/primitives/Table.tsx
  • apps/webapp/app/components/primitives/Tooltip.tsx
  • apps/webapp/app/components/primitives/TreeView/TreeView.tsx
  • apps/webapp/app/components/primitives/UsageSparkline.tsx
  • apps/webapp/app/components/primitives/charts/BigNumberCard.tsx
  • apps/webapp/app/components/primitives/charts/Chart.tsx
  • apps/webapp/app/components/primitives/charts/ChartCard.tsx
  • apps/webapp/app/components/primitives/charts/ChartLegendCompound.tsx
  • apps/webapp/app/components/primitives/charts/ChartRoot.tsx
  • apps/webapp/app/components/primitives/charts/ChartZoom.tsx
  • apps/webapp/app/components/query/QueryEditor.tsx
  • apps/webapp/app/components/run/RunTimeline.tsx
  • apps/webapp/app/components/runs/v3/AIFilterInput.tsx
  • apps/webapp/app/components/runs/v3/ReplayRunDialog.tsx
  • apps/webapp/app/components/runs/v3/RunStatusCellTooltip.tsx
  • apps/webapp/app/components/runs/v3/RunTag.tsx
  • apps/webapp/app/components/runs/v3/SharedFilters.tsx
  • apps/webapp/app/components/runs/v3/TaskRunsTable.tsx
  • apps/webapp/app/components/runs/v3/TaskTriggerSource.tsx
  • apps/webapp/app/components/runs/v3/agent/AgentMessageView.tsx
  • apps/webapp/app/components/runs/v3/ai/AIChatMessages.tsx
  • apps/webapp/app/components/runs/v3/ai/AIModelSummary.tsx
  • apps/webapp/app/components/runs/v3/ai/AISpanDetails.tsx
  • apps/webapp/app/components/runs/v3/ai/SpanMetricRow.tsx
  • apps/webapp/app/components/sessions/v1/SessionsTable.tsx
  • apps/webapp/app/routes/_app.orgs.$organizationSlug.invite/route.tsx
  • apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam._index/route.tsx
  • apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.batches/route.tsx
  • apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.bulk-actions/route.tsx
  • apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.dashboards._index/route.tsx
  • apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.dashboards.custom.$dashboardId/route.tsx
  • apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.deployments.$deploymentParam/route.tsx
  • apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.deployments/route.tsx
  • apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.environment-variables/route.tsx
  • apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.errors.$fingerprint/route.tsx
  • apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.errors._index/route.tsx
  • apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.models._index/route.tsx
  • apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.playground.$agentParam/route.tsx
  • apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.prompts.$promptSlug/route.tsx
  • apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.prompts._index/route.tsx
  • apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.query/AITabContent.tsx
  • apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.query/QueryHistoryPopover.tsx
  • apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.queues/route.tsx
  • apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.regions/route.tsx
  • apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.runs.$runParam/route.tsx
  • apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.sessions.$sessionParam/route.tsx
  • apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.tasks.scheduled.$taskParam/route.tsx
  • apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.test.tasks.$taskParam/AIPayloadTabContent.tsx
  • apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.test.tasks.$taskParam/route.tsx
  • apps/webapp/app/routes/_app.orgs.$organizationSlug_.projects.new/route.tsx
  • apps/webapp/app/routes/_app.orgs.$organizationSlug_.select-plan/route.tsx
  • apps/webapp/app/routes/_app.orgs.new/route.tsx
  • apps/webapp/app/routes/_app.timezones/route.tsx
  • apps/webapp/app/routes/account.authorization-code.$authorizationCode/route.tsx
  • apps/webapp/app/routes/account.security/route.tsx
  • apps/webapp/app/routes/confirm-basic-details.tsx
  • apps/webapp/app/routes/invites.tsx
  • apps/webapp/app/routes/login._index/route.tsx
  • apps/webapp/app/routes/resources.incidents.tsx
  • apps/webapp/app/routes/resources.orgs.$organizationSlug.projects.$projectParam.env.$envParam.runs.$runParam.spans.$spanParam/route.tsx
  • apps/webapp/app/routes/resources.orgs.$organizationSlug.projects.$projectParam.env.$envParam.vercel.tsx
  • apps/webapp/app/routes/resources.orgs.$organizationSlug.projects.$projectParam.schedules.new.natural-language.tsx
  • apps/webapp/app/routes/resources.orgs.$organizationSlug.select-plan.tsx
  • apps/webapp/app/routes/storybook.agent-ui/route.tsx
  • apps/webapp/app/routes/storybook.popover/route.tsx
  • apps/webapp/app/routes/storybook.table/route.tsx
  • apps/webapp/app/routes/storybook.timeline/route.tsx
  • apps/webapp/app/routes/unsubscribe.$userId.$token.tsx
  • apps/webapp/app/routes/vercel.onboarding.tsx
  • apps/webapp/app/services/realtime/resolveRealtimeStreamClient.server.ts
  • apps/webapp/app/services/realtime/shadowRealtimeClientInstance.server.ts
  • apps/webapp/app/tailwind.css
  • apps/webapp/app/utils/cn.ts
  • apps/webapp/app/utils/randomWords.ts
  • apps/webapp/app/v3/featureFlags.ts
  • apps/webapp/app/v3/services/computeTemplateCreation.server.ts
  • apps/webapp/package.json
  • apps/webapp/postcss.config.js
  • apps/webapp/remix.config.js
  • apps/webapp/tailwind.config.js
💤 Files with no reviewable changes (1)
  • apps/webapp/tailwind.config.js

disabled={isLoading}
rows={5}
className="m-0 min-h-10 w-full resize-none border-0 bg-background-bright px-3 py-2.5 text-sm text-text-bright scrollbar-thin scrollbar-track-transparent scrollbar-thumb-charcoal-600 placeholder:text-text-dimmed focus:border-0 focus:outline-none focus:ring-0 focus-visible:outline-none focus-visible:ring-0 focus-visible:ring-offset-0 disabled:cursor-not-allowed disabled:opacity-50"
className="m-0 min-h-10 w-full resize-none border-0 bg-background-bright px-3 py-2.5 text-sm text-text-bright scrollbar-thin scrollbar-track-transparent scrollbar-thumb-charcoal-600 placeholder:text-text-dimmed focus:border-0 focus:outline-hidden focus:ring-0 focus-visible:outline-hidden focus-visible:ring-0 focus-visible:ring-offset-0 disabled:cursor-not-allowed disabled:opacity-50"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Restore a visible keyboard focus style on the textarea.

outline-hidden plus both ring-0 overrides remove the only focus cue here, so keyboard users lose track of the active field. Keep a visible ring/outline on focus-visible.

Comment thread apps/webapp/app/tailwind.css Outdated
Comment thread apps/webapp/app/v3/featureFlags.ts Outdated
kathiekiwi added 10 commits July 3, 2026 12:45
Run-status and chart colors in JS now reference var(--color-*) tokens
(run-status palette added to the theme). Streamdown container vars derive
from semantic tokens instead of hardcoded dark HSL values; removed dead
forced-dark code block overrides. dark: variant is now driven by data-theme
on <html> (set to dark) instead of the OS preference, with color-scheme
following the theme.
Shiki (streamdown), prism (CodeBlock) and CodeMirror themes now read from
--color-code-* and --color-editor-* palettes declared in tailwind.css; callout
variants use --color-callout-* tokens. A light theme can restyle all of them
by overriding variables only.
Activity sparkbars on the project index use the shared run-status palette;
chart grids, ticks, reference lines and loading skeletons read semantic
tokens; usage meter and progress colors use success/warning/error tokens.
The upgrade codemod treated string literals in .ts files as utility classes:
realtimeBackend "shadow" flag values, compute template creation "shadow"
mode, and randomWords dictionary entries were renamed to shadow-sm/ring-3/
outline-solid. Restores the original values so persisted flags keep parsing.
@kathiekiwi kathiekiwi marked this pull request as ready for review July 3, 2026 14:16

@devin-ai-integration devin-ai-integration Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Devin Review found 2 potential issues.

Open in Devin Review

>
<ResizablePanel id="payload" min="300px">
<div className="rounded-smbg-charcoal-900 mb-3 h-full min-h-40 overflow-y-auto scrollbar-thin scrollbar-track-transparent scrollbar-thumb-charcoal-600">
<div className="rounded-smbg-background-deep mb-3 h-full min-h-40 overflow-y-auto scrollbar-thin scrollbar-track-transparent scrollbar-thumb-surface-control">

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Missing space between two CSS classes causes the replay dialog's editor container to lose its rounded corners and background color

Two CSS class names are concatenated without a space (rounded-smbg-background-deep at apps/webapp/app/components/runs/v3/ReplayRunDialog.tsx:239), so neither rounded-sm nor bg-background-deep is applied.

Impact: The JSON editor container in the replay-run dialog renders without rounded corners and without its dark background.

Concatenated class token produces a single unknown utility

The old code already had this bug (rounded-smbg-charcoal-900), and the PR carried it forward by replacing only the color token (charcoal-900background-deep) without inserting the missing space. Tailwind sees rounded-smbg-background-deep as one unknown class and silently drops it, so neither rounded-sm (border-radius) nor bg-background-deep (background-color) takes effect on the <div> wrapping the <JSONEditor>.

Suggested change
<div className="rounded-smbg-background-deep mb-3 h-full min-h-40 overflow-y-auto scrollbar-thin scrollbar-track-transparent scrollbar-thumb-surface-control">
<div className="rounded-sm bg-background-deep mb-3 h-full min-h-40 overflow-y-auto scrollbar-thin scrollbar-track-transparent scrollbar-thumb-surface-control">
Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

Comment on lines +12 to +18
[
"var(--color-success)",
"var(--color-success)",
"var(--color-warning)",
"var(--color-error)",
"var(--color-error)",
]

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🚩 CSS variables in framer-motion color interpolation may not animate smoothly

The useTransform hook from framer-motion at apps/webapp/app/components/billing/FreePlanUsage.tsx:9-18 was changed from hex color strings (#22C55E, #F59E0B, #F43F5E) to CSS variable references (var(--color-success), var(--color-warning), var(--color-error)). Framer-motion's useTransform interpolates between output values by parsing color strings into numeric components. CSS variable references like var(--color-success) are opaque strings that framer-motion cannot parse or interpolate — the color will likely snap between values at the breakpoints rather than smoothly transitioning. Given the breakpoints are [0, 74, 75, 95, 100] with duplicate colors at the edges, the interpolation window is very narrow (1 unit at 74→75, 5 units at 95→100), so the visual impact may be minimal, but the behavior has changed from smooth interpolation to discrete snapping.

Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant