Skip to content

Conversation

@lukevella
Copy link
Owner

@lukevella lukevella commented Dec 11, 2025

Summary by CodeRabbit

  • UI / Styling

    • Visual refinements across the product: reduced shadow intensity, slightly smaller corner radii, subtle gradient tweaks and improved focus outlines for a cleaner, more consistent look.
    • New global style files applied to unify base theming.
  • New Features

    • Introduced a centralized Tailwind-based design system exposing shared design tokens.
  • Chores

    • Modernized build/config related to styling and updated styling toolchain for maintainability.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 11, 2025

Walkthrough

This PR migrates Tailwind tooling to a shared ESM-based config, replaces app-specific CSS with shared globals, updates PostCSS to ESM re-exports, and applies Tailwind v4 class/token syntax and small UI class refinements across apps and UI packages. Next.js configs moved from CommonJS to ESM and added explicit typing.

Changes

Cohort / File(s) Change Summary
Tailwind config package
packages/tailwind-config/package.json, packages/tailwind-config/shared-styles.css, packages/tailwind-config/postcss.config.mjs, packages/tailwind-config/tailwind.config.d.ts, packages/tailwind-config/tailwind.config.js
Converted package to ESM exports; added shared-styles.css with design tokens; added postcss.config.mjs export; removed legacy CommonJS tailwind.config and ambient d.ts.
Next.js config ESM migration
apps/landing/next.config.ts, apps/web/next.config.ts
Replaced CommonJS requires with ESM imports (Sentry, bundle-analyzer, Next types); initialize analyzer via createBundleAnalyzer(...); typed nextConfig as NextConfig.
PostCSS re-exports (apps)
apps/landing/postcss.config.js (removed), apps/landing/postcss.config.mjs, apps/web/postcss.config.js (removed), apps/web/postcss.config.mjs
Removed CommonJS PostCSS exports in apps; added ESM re-exporting of shared postcssConfig from @rallly/tailwind-config/postcss.
App-level Tailwind config removal
apps/landing/tailwind.config.js, apps/web/tailwind.config.js
Deleted app-local Tailwind config files so apps consume shared config.
Global CSS restructure (apps)
apps/landing/src/app/[locale]/globals.css, apps/landing/src/app/[locale]/layout.tsx, apps/landing/src/style.css (removed), apps/web/src/app/[locale]/globals.css, apps/web/src/app/[locale]/layout.tsx, apps/web/src/globals.css, apps/web/src/style.css (removed)
Added globals.css importing Tailwind and shared styles; updated layout imports to ./globals.css; removed legacy style.css with @layer rules.
RBC calendar CSS migration
apps/web/src/components/forms/poll-options-form/rbc-overrides.css
Replaced Tailwind @apply directives with explicit CSS properties using CSS variables and concrete rules.
App UI styling tweaks
multiple files under apps/landing/src/..., apps/web/src/... (e.g., layout.tsx, pricing/page.tsx, licensing/thank-you/page.tsx, various components)
Systematic presentational changes: shadow size reductions (e.g., shadow-smshadow-xs/shadow-2xs), radius tweaks (roundedrounded-sm/rounded-xs), gradient token swaps (bg-gradient-to-*bg-linear-to-*), blur reductions, and minor class adjustments. No logic changes.
UI package exports update
packages/ui/package.json
Changed exports map: removed ./styles and added ./style.css.
UI component token & focus/disabled updates
many files in packages/ui/src/* (e.g., badge.tsx, checkbox.tsx, dropdown-menu.tsx, select.tsx, sheet.tsx, tabs.tsx, textarea.tsx, toast.tsx, sidebar.tsx, etc.)
Large-scale migration to Tailwind v4 token syntax: arbitrary-value conversions (e.g., w-[var(...)]w-(...)), has-[[...]]has-data-[...], data-[disabled]data-disabled, outline-noneoutline-hidden/focus-visible:outline-hidden, gradient and shadow token updates. Public APIs unchanged.
UI component fine-grain refinements
packages/ui/src/avatar.tsx, packages/ui/src/breadcrumb.tsx, packages/ui/src/separator.tsx, packages/ui/src/table.tsx, etc.
Miscellaneous class and selector refinements (avatar rounding/size, breadcrumb wrap, h-[1px]h-px, selector scope adjustments, gradient token tweaks).
Dependency updates
apps/landing/package.json, apps/web/package.json, packages/tailwind-config/package.json
Bumped/added Tailwind v4 tooling and PostCSS entries: tailwindcss^4.1.18, postcss ^8.5.6, added @tailwindcss/postcss, removed some autoprefixer entries; packages/tailwind-config moved to ESM with new exports.
Docs / examples
apps/web/.cursor/rules/better-auth.md
Example change: button variant for non-active providers changed from outlineoutline-solid.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~70 minutes

  • Areas to pay extra attention:
    • packages/tailwind-config/shared-styles.css for correct token names and Tailwind v4 compatibility.
    • apps' globals.css imports and removed style.css fallout (build/runtime CSS inclusion).
    • postcss config re-exports and package export map (ESM interop).
    • Arbitrary-value syntax conversions (w-(...), has-data-[...], data-disabled) that can break class parsing.
    • rbc-overrides.css manual conversions for visual parity.

Possibly related PRs

Poem

🐇 I hopped from require to import with glee,
Shared styles planted a garden for me,
Shadows softened, outlines tucked in tight,
One CSS root grows for apps day and night,
A little rabbit celebrates the new spree! 🥕

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'Upgrade to Tailwind 4' accurately describes the primary objective of this changeset, which comprehensively upgrades the project from Tailwind CSS v3 to v4 across multiple packages and applications.
✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch tailwind-4

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 91f47e3 and 28b424c.

📒 Files selected for processing (1)
  • apps/web/package.json (4 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • apps/web/package.json
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Integration tests

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 and usage tips.

@vercel
Copy link

vercel bot commented Dec 11, 2025

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Preview Comments Updated (UTC)
app Ready Ready Preview Comment Dec 12, 2025 11:59am
1 Skipped Deployment
Project Deployment Preview Comments Updated (UTC)
landing Skipped Skipped Dec 12, 2025 11:59am

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 4

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (6)
packages/ui/src/billing-plan.tsx (1)

38-45: discount prop is declared but never rendered

BillingPlanPrice accepts a discount prop, but it’s not used anywhere in the JSX. That’s either dead API surface or a missing part of the UI.

Consider either:

  • Wiring discount into the markup (e.g. showing a struck-through old price or a “Save X%” label), or
  • Removing the discount prop from the type if it’s not needed.

Example (if you want to display a discount label inline):

-export const BillingPlanPrice = ({
-  children,
-}: React.PropsWithChildren<{ discount?: React.ReactNode }>) => {
+export const BillingPlanPrice = ({
+  children,
+  discount,
+}: React.PropsWithChildren<{ discount?: React.ReactNode }>) => {
   return (
-    <div className="flex items-center gap-4">
-      <span className="font-bold text-3xl">{children}</span>
-    </div>
+    <div className="flex items-center gap-4">
+      <span className="font-bold text-3xl">{children}</span>
+      {discount ? <span className="text-muted-foreground text-sm">{discount}</span> : null}
+    </div>
   );
 };
apps/web/src/components/vote-summary-progress-bar.tsx (1)

23-70: Guard against total === 0 to avoid invalid progress widths

The switch to rounded-sm on the container is a harmless visual tweak.

However, the width calculations:

width: `${(props.yes.length / props.total) * 100}%`;
// ... same pattern for ifNeedBe and no

will yield NaN%/Infinity% if props.total is 0, which results in invalid CSS and unpredictable bar rendering.

Consider normalizing total before using it:

-export const VoteSummaryProgressBar = (props: {
-  total: number;
-  yes: string[];
-  ifNeedBe: string[];
-  no: string[];
-}) => {
-  return (
-    <div className="flex h-1.5 grow overflow-hidden rounded-sm bg-slate-100">
+export const VoteSummaryProgressBar = (props: {
+  total: number;
+  yes: string[];
+  ifNeedBe: string[];
+  no: string[];
+}) => {
+  const total = props.total || 1;
+
+  return (
+    <div className="flex h-1.5 grow overflow-hidden rounded-sm bg-slate-100">
       {/* ... */}
-          style={{
-            width: `${(props.yes.length / props.total) * 100}%`,
-          }}
+          style={{
+            width: `${(props.yes.length / total) * 100}%`,
+          }}
       {/* repeat the same change for ifNeedBe and no */}

This keeps behavior identical for valid totals while ensuring a safe fallback (empty bar) when total happens to be 0.

apps/web/src/components/forms/poll-options-form/week-calendar.tsx (1)

159-163: Duration calculation likely incorrect (always 0 minutes)

Here:

const newEvent: DateTimeOption = {
  type: "timeSlot",
  start: formatDateWithoutTz(startDate),
  duration: dayjs(endDate).diff(endDate, "minutes"),
  end: formatDateWithoutTz(endDate),
};

dayjs(endDate).diff(endDate, "minutes") will always be 0. This looks like it was meant to be the minutes between startDate and endDate.

Consider:

-    duration: dayjs(endDate).diff(endDate, "minutes"),
+    duration: dayjs(endDate).diff(startDate, "minutes"),

so duration correctly reflects the selected slot length.

apps/web/src/components/forms/poll-options-form/month-calendar/month-calendar.tsx (1)

125-201: Calendar day cell styling is fine; fix Biome’s class‑order complaint

The shadow / border / focus tweaks on the day cells and selection overlay look good and are consistent with the rest of the Tailwind 4 visual polish.

Biome is currently flagging the class list on the inner <span> (line 190) as unsorted, which will cause biome check to fail. You can either reorder the classes manually or just run the project’s autofix script to let Biome handle it:

#!/bin/bash
# Let Biome fix Tailwind class ordering and other style nits
pnpm --filter @rallly/web biome check . --write || pnpm biome check . --write

(Based on static analysis hints for this file.)

apps/landing/package.json (1)

5-43: ESM switch requires converting CommonJS config files

Adding "type": "module" changes how .js files are parsed. Found CommonJS in config files that will break:

  • apps/landing/i18next-scanner.config.js uses require() and module.exports – convert to ESM syntax
  • apps/landing/next.config.ts uses module.exports – verify Next.js handles this correctly with ESM mode, or migrate to ESM syntax
packages/ui/src/sidebar.tsx (1)

513-528: Sort classes in sidebarMenuButtonVariants to satisfy Biome

Biome is flagging the base class string and the size.lg variant in sidebarMenuButtonVariants for unsorted classes (lint/nursery/useSortedClasses). To keep CI green and align with the configured style rules, run Biome with --fix (or equivalent) on this file so those class lists are automatically reordered.

🧹 Nitpick comments (6)
packages/ui/src/button.tsx (1)

21-21: Tailwind v4 migration looks good, but consider enhancing the focus state.

The shadow-2xs utility and opacity slash syntax (bg-destructive/90) are correct for Tailwind v4.

However, the destructive variant has focus-visible:ring-offset-1 without an actual ring, which means keyboard users won't see a visible focus indicator. The primary variant (line 19) correctly includes both ring-2 and ring-gray-300, providing a clear focus state.

Consider applying this diff to add a visible focus ring:

-          "border-destructive bg-destructive text-destructive-foreground shadow-2xs hover:bg-destructive/90 focus-visible:ring-offset-1 active:bg-destructive",
+          "border-destructive bg-destructive text-destructive-foreground shadow-2xs hover:bg-destructive/90 focus-visible:ring-2 focus-visible:ring-red-300 focus-visible:ring-offset-1 active:bg-destructive",

Note: The default and secondary variants (lines 22-25) have the same focus state issue and may benefit from a similar enhancement.

packages/ui/src/billing-plan.tsx (1)

56-69: Prefer wrapping CheckCircle2Icon with <Icon> from @rallly/ui/icon

Guidelines say icon size/colour should be controlled via the shared <Icon> component rather than per‑icon Tailwind classes. Here CheckCircle2Icon is styled directly with className.

Consider refactoring along these lines:

-import { CheckCircle2Icon } from "lucide-react";
+import { CheckCircle2Icon } from "lucide-react";
+import { Icon } from "@rallly/ui/icon";

      <CheckCircle2Icon
-        className={cn(
-          "mt-0.5 size-4 shrink-0",
-          !pro ? "text-gray-500" : "text-primary",
-        )}
+        // or wrap:
+        // <Icon asChild className={cn("mt-0.5 shrink-0", !pro ? "text-gray-500" : "text-primary")}>
+        //   <CheckCircle2Icon />
+        // </Icon>
       />

Adjust the exact pattern to match how <Icon> is used elsewhere in @rallly/ui.

As per coding guidelines, icons’ size and colour should be provided via the shared <Icon> component.

packages/ui/src/breadcrumb.tsx (1)

22-22: Breadcrumb text wrapping change is good; sort classes to satisfy Biome

The updated class list on Line 22 keeps the existing layout while switching to the new word-wrapping utility, which fits the Tailwind 4 upgrade. Biome is flagging only the class order, so you can auto-fix or apply a small manual tweak.

For example:

-      "flex flex-wrap items-center gap-1.5 wrap-break-word text-muted-foreground text-sm sm:gap-2.5",
+      "flex flex-wrap gap-1.5 items-center sm:gap-2.5 text-muted-foreground text-sm wrap-break-word",

As per coding guidelines, Biome should be the source of truth for formatting, so letting it auto-sort these is also fine.

apps/web/src/components/cookie-consent.tsx (1)

36-59: Shadow change is fine; consider localizing the cookie consent copy

The update from shadow-sm to shadow-xs on the OK button is a straightforward visual refinement and looks good.

However, the surrounding text ("Your privacy is important to us...", "Privacy Policy", and "OK") is currently hard-coded. Given the project’s guidelines that all UI text should be translatable (via the <Trans> component or useTranslation), consider refactoring this component to use <Trans> from @/components/trans with defaults strings so it can be localized in the same way as the rest of the app.

If you’d like, I can sketch a concrete refactor using <Trans> for these three strings.

apps/web/src/components/maintenance.tsx (1)

5-14: Card shadow tweak is fine; maintenance copy could be made translatable later

The change from shadow-sm to shadow-xs on the maintenance card is a harmless visual adjustment and matches the PR-wide move to lighter shadows.

As a future improvement (not blocking this PR), you may want to move the title and body text into your i18n system using <Trans>/useTranslation, so this maintenance screen respects locale like the rest of the app.

packages/tailwind-config/shared-styles.css (1)

124-160: Base border-color compatibility and utilities fit the Tailwind 4 migration

The base-layer compatibility rule restoring the pre-v4 border color default, plus the text-link and bg-diagonal-lines utilities and the global body/html styles, provide a coherent, token-driven base for all apps. As a small optional improvement, you could swap the hard-coded grays in bg-diagonal-lines for the gray design tokens to keep everything fully theme-based.

Based on learnings, this aligns shared styling with the Tailwind + custom design system strategy.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 102e5d2 and 411139c.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (72)
  • apps/landing/next.config.ts (2 hunks)
  • apps/landing/package.json (2 hunks)
  • apps/landing/postcss.config.js (1 hunks)
  • apps/landing/src/app/[locale]/(main)/layout.tsx (1 hunks)
  • apps/landing/src/app/[locale]/(main)/pricing/page.tsx (1 hunks)
  • apps/landing/src/app/[locale]/globals.css (1 hunks)
  • apps/landing/src/app/[locale]/layout.tsx (1 hunks)
  • apps/landing/src/app/[locale]/licensing/thank-you/page.tsx (1 hunks)
  • apps/landing/src/components/home/bonus-item.tsx (1 hunks)
  • apps/landing/src/style.css (0 hunks)
  • apps/landing/tailwind.config.js (0 hunks)
  • apps/web/.cursor/rules/better-auth.md (3 hunks)
  • apps/web/next.config.ts (1 hunks)
  • apps/web/package.json (4 hunks)
  • apps/web/postcss.config.js (1 hunks)
  • apps/web/src/app/[locale]/(auth)/layout.tsx (1 hunks)
  • apps/web/src/app/[locale]/(space)/(dashboard)/components/nav-user.tsx (1 hunks)
  • apps/web/src/app/[locale]/(space)/(dashboard)/components/upgrade-to-pro-alert.tsx (1 hunks)
  • apps/web/src/app/[locale]/(space)/settings/layout.tsx (1 hunks)
  • apps/web/src/app/[locale]/accept-invite/[inviteId]/page.tsx (1 hunks)
  • apps/web/src/app/[locale]/globals.css (1 hunks)
  • apps/web/src/app/[locale]/layout.tsx (1 hunks)
  • apps/web/src/app/components/page-layout.tsx (1 hunks)
  • apps/web/src/components/cookie-consent.tsx (1 hunks)
  • apps/web/src/components/description-list.tsx (1 hunks)
  • apps/web/src/components/discussion/discussion.tsx (1 hunks)
  • apps/web/src/components/empty-state.tsx (1 hunks)
  • apps/web/src/components/forms/poll-options-form/month-calendar/month-calendar.tsx (3 hunks)
  • apps/web/src/components/forms/poll-options-form/week-calendar.tsx (1 hunks)
  • apps/web/src/components/full-width-layout.tsx (1 hunks)
  • apps/web/src/components/maintenance.tsx (1 hunks)
  • apps/web/src/components/new-participant-modal.tsx (1 hunks)
  • apps/web/src/components/poll/desktop-poll.tsx (2 hunks)
  • apps/web/src/components/poll/scheduled-event.tsx (1 hunks)
  • apps/web/src/components/skeleton.tsx (1 hunks)
  • apps/web/src/components/time-zone-picker/time-zone-select.tsx (1 hunks)
  • apps/web/src/components/vote-summary-progress-bar.tsx (1 hunks)
  • apps/web/src/features/billing/components/pay-wall-dialog.tsx (2 hunks)
  • apps/web/src/features/space/components/space-dropdown.tsx (1 hunks)
  • apps/web/src/globals.css (1 hunks)
  • apps/web/src/style.css (0 hunks)
  • apps/web/tailwind.config.js (0 hunks)
  • packages/tailwind-config/package.json (1 hunks)
  • packages/tailwind-config/postcss.config.js (1 hunks)
  • packages/tailwind-config/shared-styles.css (1 hunks)
  • packages/tailwind-config/tailwind.config.d.ts (0 hunks)
  • packages/tailwind-config/tailwind.config.js (0 hunks)
  • packages/ui/package.json (1 hunks)
  • packages/ui/src/alert.tsx (1 hunks)
  • packages/ui/src/avatar.tsx (1 hunks)
  • packages/ui/src/badge.tsx (1 hunks)
  • packages/ui/src/billing-plan.tsx (1 hunks)
  • packages/ui/src/breadcrumb.tsx (1 hunks)
  • packages/ui/src/button.tsx (1 hunks)
  • packages/ui/src/card.tsx (1 hunks)
  • packages/ui/src/checkbox.tsx (1 hunks)
  • packages/ui/src/command.tsx (5 hunks)
  • packages/ui/src/dropdown-menu.tsx (5 hunks)
  • packages/ui/src/page-tabs.tsx (2 hunks)
  • packages/ui/src/popover.tsx (1 hunks)
  • packages/ui/src/progress.tsx (1 hunks)
  • packages/ui/src/radio-group.tsx (1 hunks)
  • packages/ui/src/select.tsx (3 hunks)
  • packages/ui/src/separator.tsx (1 hunks)
  • packages/ui/src/sheet.tsx (1 hunks)
  • packages/ui/src/sidebar.tsx (13 hunks)
  • packages/ui/src/switch.tsx (1 hunks)
  • packages/ui/src/table.tsx (2 hunks)
  • packages/ui/src/tabs.tsx (2 hunks)
  • packages/ui/src/textarea.tsx (1 hunks)
  • packages/ui/src/toast.tsx (4 hunks)
  • packages/ui/src/tooltip.tsx (1 hunks)
💤 Files with no reviewable changes (6)
  • packages/tailwind-config/tailwind.config.d.ts
  • apps/web/tailwind.config.js
  • apps/landing/tailwind.config.js
  • apps/web/src/style.css
  • packages/tailwind-config/tailwind.config.js
  • apps/landing/src/style.css
🧰 Additional context used
📓 Path-based instructions (13)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursorrules)

**/*.{ts,tsx}: Use dayjs for date handling
Use react-query for data fetching
Prefer implicit return values over explicit return values
Use zod for form validation
Create separate import statements for types
Prefer using the React module APIs (e.g. React.useState) instead of standalone hooks (e.g. useState)
Prefer double quotes for strings over single quotes
Only add comments when it is necessary to explain code that isn't self-explanatory

**/*.{ts,tsx}: Only create named interfaces when they're reused or complex
When TypeScript errors occur for missing i18n keys, run pnpm i18n:scan instead of manually adding keys

Files:

  • apps/web/src/components/maintenance.tsx
  • packages/ui/src/button.tsx
  • apps/web/src/components/poll/scheduled-event.tsx
  • apps/web/src/components/skeleton.tsx
  • apps/web/src/components/vote-summary-progress-bar.tsx
  • apps/landing/src/app/[locale]/licensing/thank-you/page.tsx
  • packages/ui/src/tabs.tsx
  • apps/web/src/components/new-participant-modal.tsx
  • packages/ui/src/breadcrumb.tsx
  • apps/landing/src/app/[locale]/(main)/pricing/page.tsx
  • packages/ui/src/tooltip.tsx
  • apps/web/src/app/[locale]/layout.tsx
  • packages/ui/src/sheet.tsx
  • apps/web/src/components/forms/poll-options-form/week-calendar.tsx
  • packages/ui/src/textarea.tsx
  • apps/web/src/components/time-zone-picker/time-zone-select.tsx
  • packages/ui/src/popover.tsx
  • packages/ui/src/switch.tsx
  • apps/web/src/app/[locale]/(space)/(dashboard)/components/upgrade-to-pro-alert.tsx
  • apps/web/src/components/discussion/discussion.tsx
  • apps/web/src/features/billing/components/pay-wall-dialog.tsx
  • packages/ui/src/dropdown-menu.tsx
  • packages/ui/src/command.tsx
  • apps/landing/src/app/[locale]/layout.tsx
  • packages/ui/src/alert.tsx
  • packages/ui/src/checkbox.tsx
  • packages/ui/src/toast.tsx
  • packages/ui/src/sidebar.tsx
  • packages/ui/src/select.tsx
  • packages/ui/src/billing-plan.tsx
  • apps/web/src/components/forms/poll-options-form/month-calendar/month-calendar.tsx
  • packages/ui/src/progress.tsx
  • apps/web/src/components/cookie-consent.tsx
  • apps/web/src/app/[locale]/(space)/settings/layout.tsx
  • packages/ui/src/card.tsx
  • packages/ui/src/separator.tsx
  • apps/web/src/components/full-width-layout.tsx
  • apps/web/src/app/[locale]/(space)/(dashboard)/components/nav-user.tsx
  • apps/web/src/components/empty-state.tsx
  • apps/landing/next.config.ts
  • apps/web/src/app/[locale]/(auth)/layout.tsx
  • apps/web/src/features/space/components/space-dropdown.tsx
  • apps/landing/src/components/home/bonus-item.tsx
  • apps/web/src/components/poll/desktop-poll.tsx
  • packages/ui/src/page-tabs.tsx
  • apps/web/src/app/components/page-layout.tsx
  • packages/ui/src/table.tsx
  • packages/ui/src/badge.tsx
  • apps/web/src/app/[locale]/accept-invite/[inviteId]/page.tsx
  • apps/landing/src/app/[locale]/(main)/layout.tsx
  • apps/web/src/components/description-list.tsx
  • apps/web/next.config.ts
  • packages/ui/src/avatar.tsx
  • packages/ui/src/radio-group.tsx
**/*.{tsx,css,config.ts}

📄 CodeRabbit inference engine (.cursorrules)

Use tailwindcss for styling

Files:

  • apps/web/src/components/maintenance.tsx
  • packages/ui/src/button.tsx
  • apps/web/src/components/poll/scheduled-event.tsx
  • apps/web/src/components/skeleton.tsx
  • apps/web/src/components/vote-summary-progress-bar.tsx
  • apps/landing/src/app/[locale]/licensing/thank-you/page.tsx
  • packages/ui/src/tabs.tsx
  • apps/web/src/components/new-participant-modal.tsx
  • packages/ui/src/breadcrumb.tsx
  • apps/landing/src/app/[locale]/(main)/pricing/page.tsx
  • packages/tailwind-config/shared-styles.css
  • packages/ui/src/tooltip.tsx
  • apps/web/src/app/[locale]/layout.tsx
  • apps/web/src/app/[locale]/globals.css
  • packages/ui/src/sheet.tsx
  • apps/web/src/components/forms/poll-options-form/week-calendar.tsx
  • packages/ui/src/textarea.tsx
  • apps/web/src/components/time-zone-picker/time-zone-select.tsx
  • packages/ui/src/popover.tsx
  • packages/ui/src/switch.tsx
  • apps/web/src/app/[locale]/(space)/(dashboard)/components/upgrade-to-pro-alert.tsx
  • apps/web/src/components/discussion/discussion.tsx
  • apps/web/src/features/billing/components/pay-wall-dialog.tsx
  • packages/ui/src/dropdown-menu.tsx
  • apps/landing/src/app/[locale]/globals.css
  • packages/ui/src/command.tsx
  • apps/landing/src/app/[locale]/layout.tsx
  • packages/ui/src/alert.tsx
  • packages/ui/src/checkbox.tsx
  • packages/ui/src/toast.tsx
  • packages/ui/src/sidebar.tsx
  • packages/ui/src/select.tsx
  • packages/ui/src/billing-plan.tsx
  • apps/web/src/globals.css
  • apps/web/src/components/forms/poll-options-form/month-calendar/month-calendar.tsx
  • packages/ui/src/progress.tsx
  • apps/web/src/components/cookie-consent.tsx
  • apps/web/src/app/[locale]/(space)/settings/layout.tsx
  • packages/ui/src/card.tsx
  • packages/ui/src/separator.tsx
  • apps/web/src/components/full-width-layout.tsx
  • apps/web/src/app/[locale]/(space)/(dashboard)/components/nav-user.tsx
  • apps/web/src/components/empty-state.tsx
  • apps/landing/next.config.ts
  • apps/web/src/app/[locale]/(auth)/layout.tsx
  • apps/web/src/features/space/components/space-dropdown.tsx
  • apps/landing/src/components/home/bonus-item.tsx
  • apps/web/src/components/poll/desktop-poll.tsx
  • packages/ui/src/page-tabs.tsx
  • apps/web/src/app/components/page-layout.tsx
  • packages/ui/src/table.tsx
  • packages/ui/src/badge.tsx
  • apps/web/src/app/[locale]/accept-invite/[inviteId]/page.tsx
  • apps/landing/src/app/[locale]/(main)/layout.tsx
  • apps/web/src/components/description-list.tsx
  • apps/web/next.config.ts
  • packages/ui/src/avatar.tsx
  • packages/ui/src/radio-group.tsx
**/*.tsx

📄 CodeRabbit inference engine (.cursorrules)

**/*.tsx: Use react-hook-form for form handling
All text in the UI should be translated using either the Trans component or the useTranslation hook
Prefer composable components in the style of shadcn UI over large monolithic components
DropdownMenuItem is a flex container with a preset gap so there is no need to add margins to the children
The size and colour of an icon should be set by wrapping it with the component from @rallly/ui/icon which will give it the correct colour and size
Keep the props of a component as minimal as possible. Pass only the bare minimum amount of information needed to it
All text in the UI should be translatable
Use the component in client components from @/components/trans with the defaults prop to provide the default text
Always use a composable patterns when building components
Use cn() from @rallly/ui to compose classes
Add the "use client" directive to the top of any .tsx file that requires client-side javascript

Files:

  • apps/web/src/components/maintenance.tsx
  • packages/ui/src/button.tsx
  • apps/web/src/components/poll/scheduled-event.tsx
  • apps/web/src/components/skeleton.tsx
  • apps/web/src/components/vote-summary-progress-bar.tsx
  • apps/landing/src/app/[locale]/licensing/thank-you/page.tsx
  • packages/ui/src/tabs.tsx
  • apps/web/src/components/new-participant-modal.tsx
  • packages/ui/src/breadcrumb.tsx
  • apps/landing/src/app/[locale]/(main)/pricing/page.tsx
  • packages/ui/src/tooltip.tsx
  • apps/web/src/app/[locale]/layout.tsx
  • packages/ui/src/sheet.tsx
  • apps/web/src/components/forms/poll-options-form/week-calendar.tsx
  • packages/ui/src/textarea.tsx
  • apps/web/src/components/time-zone-picker/time-zone-select.tsx
  • packages/ui/src/popover.tsx
  • packages/ui/src/switch.tsx
  • apps/web/src/app/[locale]/(space)/(dashboard)/components/upgrade-to-pro-alert.tsx
  • apps/web/src/components/discussion/discussion.tsx
  • apps/web/src/features/billing/components/pay-wall-dialog.tsx
  • packages/ui/src/dropdown-menu.tsx
  • packages/ui/src/command.tsx
  • apps/landing/src/app/[locale]/layout.tsx
  • packages/ui/src/alert.tsx
  • packages/ui/src/checkbox.tsx
  • packages/ui/src/toast.tsx
  • packages/ui/src/sidebar.tsx
  • packages/ui/src/select.tsx
  • packages/ui/src/billing-plan.tsx
  • apps/web/src/components/forms/poll-options-form/month-calendar/month-calendar.tsx
  • packages/ui/src/progress.tsx
  • apps/web/src/components/cookie-consent.tsx
  • apps/web/src/app/[locale]/(space)/settings/layout.tsx
  • packages/ui/src/card.tsx
  • packages/ui/src/separator.tsx
  • apps/web/src/components/full-width-layout.tsx
  • apps/web/src/app/[locale]/(space)/(dashboard)/components/nav-user.tsx
  • apps/web/src/components/empty-state.tsx
  • apps/web/src/app/[locale]/(auth)/layout.tsx
  • apps/web/src/features/space/components/space-dropdown.tsx
  • apps/landing/src/components/home/bonus-item.tsx
  • apps/web/src/components/poll/desktop-poll.tsx
  • packages/ui/src/page-tabs.tsx
  • apps/web/src/app/components/page-layout.tsx
  • packages/ui/src/table.tsx
  • packages/ui/src/badge.tsx
  • apps/web/src/app/[locale]/accept-invite/[inviteId]/page.tsx
  • apps/landing/src/app/[locale]/(main)/layout.tsx
  • apps/web/src/components/description-list.tsx
  • packages/ui/src/avatar.tsx
  • packages/ui/src/radio-group.tsx
**/*.{ts,tsx,json}

📄 CodeRabbit inference engine (.cursorrules)

**/*.{ts,tsx,json}: i18n keys are in camelCase
i18nKeys should describe the message in camelCase. Ex. "lastUpdated": "Last Updated"
If the i18nKey is not intended to be reused, prefix it with the component name in camelCase

Files:

  • apps/web/src/components/maintenance.tsx
  • packages/ui/src/button.tsx
  • apps/web/src/components/poll/scheduled-event.tsx
  • apps/web/src/components/skeleton.tsx
  • apps/web/src/components/vote-summary-progress-bar.tsx
  • apps/landing/src/app/[locale]/licensing/thank-you/page.tsx
  • packages/ui/src/tabs.tsx
  • apps/web/src/components/new-participant-modal.tsx
  • packages/ui/src/breadcrumb.tsx
  • apps/landing/src/app/[locale]/(main)/pricing/page.tsx
  • packages/ui/src/tooltip.tsx
  • apps/web/src/app/[locale]/layout.tsx
  • apps/landing/package.json
  • packages/ui/src/sheet.tsx
  • apps/web/src/components/forms/poll-options-form/week-calendar.tsx
  • packages/ui/src/textarea.tsx
  • apps/web/src/components/time-zone-picker/time-zone-select.tsx
  • packages/ui/src/popover.tsx
  • packages/ui/src/switch.tsx
  • apps/web/src/app/[locale]/(space)/(dashboard)/components/upgrade-to-pro-alert.tsx
  • apps/web/src/components/discussion/discussion.tsx
  • apps/web/src/features/billing/components/pay-wall-dialog.tsx
  • packages/ui/src/dropdown-menu.tsx
  • packages/ui/src/command.tsx
  • apps/landing/src/app/[locale]/layout.tsx
  • packages/ui/src/alert.tsx
  • packages/ui/src/checkbox.tsx
  • packages/ui/src/toast.tsx
  • packages/ui/src/sidebar.tsx
  • packages/tailwind-config/package.json
  • packages/ui/src/select.tsx
  • packages/ui/src/billing-plan.tsx
  • apps/web/src/components/forms/poll-options-form/month-calendar/month-calendar.tsx
  • packages/ui/src/progress.tsx
  • apps/web/src/components/cookie-consent.tsx
  • apps/web/src/app/[locale]/(space)/settings/layout.tsx
  • packages/ui/src/card.tsx
  • packages/ui/package.json
  • packages/ui/src/separator.tsx
  • apps/web/src/components/full-width-layout.tsx
  • apps/web/src/app/[locale]/(space)/(dashboard)/components/nav-user.tsx
  • apps/web/src/components/empty-state.tsx
  • apps/landing/next.config.ts
  • apps/web/src/app/[locale]/(auth)/layout.tsx
  • apps/web/src/features/space/components/space-dropdown.tsx
  • apps/landing/src/components/home/bonus-item.tsx
  • apps/web/src/components/poll/desktop-poll.tsx
  • apps/web/package.json
  • packages/ui/src/page-tabs.tsx
  • apps/web/src/app/components/page-layout.tsx
  • packages/ui/src/table.tsx
  • packages/ui/src/badge.tsx
  • apps/web/src/app/[locale]/accept-invite/[inviteId]/page.tsx
  • apps/landing/src/app/[locale]/(main)/layout.tsx
  • apps/web/src/components/description-list.tsx
  • apps/web/next.config.ts
  • packages/ui/src/avatar.tsx
  • packages/ui/src/radio-group.tsx
**/*

📄 CodeRabbit inference engine (.cursorrules)

Always use kebab-case for file names

Files:

  • apps/web/src/components/maintenance.tsx
  • packages/ui/src/button.tsx
  • apps/web/src/components/poll/scheduled-event.tsx
  • apps/web/src/components/skeleton.tsx
  • apps/web/src/components/vote-summary-progress-bar.tsx
  • apps/landing/src/app/[locale]/licensing/thank-you/page.tsx
  • packages/ui/src/tabs.tsx
  • apps/web/src/components/new-participant-modal.tsx
  • packages/ui/src/breadcrumb.tsx
  • apps/landing/src/app/[locale]/(main)/pricing/page.tsx
  • packages/tailwind-config/shared-styles.css
  • packages/ui/src/tooltip.tsx
  • apps/web/src/app/[locale]/layout.tsx
  • apps/web/src/app/[locale]/globals.css
  • apps/landing/package.json
  • packages/ui/src/sheet.tsx
  • apps/web/src/components/forms/poll-options-form/week-calendar.tsx
  • packages/ui/src/textarea.tsx
  • apps/web/src/components/time-zone-picker/time-zone-select.tsx
  • packages/ui/src/popover.tsx
  • packages/ui/src/switch.tsx
  • apps/web/src/app/[locale]/(space)/(dashboard)/components/upgrade-to-pro-alert.tsx
  • apps/web/src/components/discussion/discussion.tsx
  • apps/web/src/features/billing/components/pay-wall-dialog.tsx
  • packages/ui/src/dropdown-menu.tsx
  • apps/landing/src/app/[locale]/globals.css
  • packages/ui/src/command.tsx
  • apps/landing/src/app/[locale]/layout.tsx
  • packages/ui/src/alert.tsx
  • packages/ui/src/checkbox.tsx
  • packages/ui/src/toast.tsx
  • packages/ui/src/sidebar.tsx
  • packages/tailwind-config/package.json
  • packages/ui/src/select.tsx
  • packages/ui/src/billing-plan.tsx
  • apps/web/src/globals.css
  • apps/web/src/components/forms/poll-options-form/month-calendar/month-calendar.tsx
  • packages/ui/src/progress.tsx
  • apps/web/src/components/cookie-consent.tsx
  • apps/web/src/app/[locale]/(space)/settings/layout.tsx
  • packages/ui/src/card.tsx
  • apps/landing/postcss.config.js
  • packages/ui/package.json
  • packages/ui/src/separator.tsx
  • apps/web/src/components/full-width-layout.tsx
  • apps/web/src/app/[locale]/(space)/(dashboard)/components/nav-user.tsx
  • apps/web/src/components/empty-state.tsx
  • apps/landing/next.config.ts
  • apps/web/src/app/[locale]/(auth)/layout.tsx
  • apps/web/src/features/space/components/space-dropdown.tsx
  • apps/landing/src/components/home/bonus-item.tsx
  • apps/web/src/components/poll/desktop-poll.tsx
  • apps/web/package.json
  • apps/web/postcss.config.js
  • packages/ui/src/page-tabs.tsx
  • apps/web/src/app/components/page-layout.tsx
  • packages/ui/src/table.tsx
  • packages/ui/src/badge.tsx
  • apps/web/src/app/[locale]/accept-invite/[inviteId]/page.tsx
  • apps/landing/src/app/[locale]/(main)/layout.tsx
  • apps/web/src/components/description-list.tsx
  • apps/web/next.config.ts
  • packages/ui/src/avatar.tsx
  • packages/tailwind-config/postcss.config.js
  • packages/ui/src/radio-group.tsx
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (CLAUDE.md)

Use Biome for code formatting with indent of 2 spaces and double quotes

Files:

  • apps/web/src/components/maintenance.tsx
  • packages/ui/src/button.tsx
  • apps/web/src/components/poll/scheduled-event.tsx
  • apps/web/src/components/skeleton.tsx
  • apps/web/src/components/vote-summary-progress-bar.tsx
  • apps/landing/src/app/[locale]/licensing/thank-you/page.tsx
  • packages/ui/src/tabs.tsx
  • apps/web/src/components/new-participant-modal.tsx
  • packages/ui/src/breadcrumb.tsx
  • apps/landing/src/app/[locale]/(main)/pricing/page.tsx
  • packages/ui/src/tooltip.tsx
  • apps/web/src/app/[locale]/layout.tsx
  • packages/ui/src/sheet.tsx
  • apps/web/src/components/forms/poll-options-form/week-calendar.tsx
  • packages/ui/src/textarea.tsx
  • apps/web/src/components/time-zone-picker/time-zone-select.tsx
  • packages/ui/src/popover.tsx
  • packages/ui/src/switch.tsx
  • apps/web/src/app/[locale]/(space)/(dashboard)/components/upgrade-to-pro-alert.tsx
  • apps/web/src/components/discussion/discussion.tsx
  • apps/web/src/features/billing/components/pay-wall-dialog.tsx
  • packages/ui/src/dropdown-menu.tsx
  • packages/ui/src/command.tsx
  • apps/landing/src/app/[locale]/layout.tsx
  • packages/ui/src/alert.tsx
  • packages/ui/src/checkbox.tsx
  • packages/ui/src/toast.tsx
  • packages/ui/src/sidebar.tsx
  • packages/ui/src/select.tsx
  • packages/ui/src/billing-plan.tsx
  • apps/web/src/components/forms/poll-options-form/month-calendar/month-calendar.tsx
  • packages/ui/src/progress.tsx
  • apps/web/src/components/cookie-consent.tsx
  • apps/web/src/app/[locale]/(space)/settings/layout.tsx
  • packages/ui/src/card.tsx
  • apps/landing/postcss.config.js
  • packages/ui/src/separator.tsx
  • apps/web/src/components/full-width-layout.tsx
  • apps/web/src/app/[locale]/(space)/(dashboard)/components/nav-user.tsx
  • apps/web/src/components/empty-state.tsx
  • apps/landing/next.config.ts
  • apps/web/src/app/[locale]/(auth)/layout.tsx
  • apps/web/src/features/space/components/space-dropdown.tsx
  • apps/landing/src/components/home/bonus-item.tsx
  • apps/web/src/components/poll/desktop-poll.tsx
  • apps/web/postcss.config.js
  • packages/ui/src/page-tabs.tsx
  • apps/web/src/app/components/page-layout.tsx
  • packages/ui/src/table.tsx
  • packages/ui/src/badge.tsx
  • apps/web/src/app/[locale]/accept-invite/[inviteId]/page.tsx
  • apps/landing/src/app/[locale]/(main)/layout.tsx
  • apps/web/src/components/description-list.tsx
  • apps/web/next.config.ts
  • packages/ui/src/avatar.tsx
  • packages/tailwind-config/postcss.config.js
  • packages/ui/src/radio-group.tsx
**/*.{tsx,ts}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.{tsx,ts}: Prefer inline prop types over named interfaces for simple component props (e.g., function Component({ prop }: { prop: string }) instead of defining a separate interface)
Always use the useDialog hook from @rallly/ui/dialog for managing dialog state instead of manual useState for open/close state
Use TanStack Query with tRPC for server state management
Use React Context for client state (auth, preferences, etc.)
Use react-hook-form with Zod validation for form state management
Use TailwindCSS with custom design system for styling

Files:

  • apps/web/src/components/maintenance.tsx
  • packages/ui/src/button.tsx
  • apps/web/src/components/poll/scheduled-event.tsx
  • apps/web/src/components/skeleton.tsx
  • apps/web/src/components/vote-summary-progress-bar.tsx
  • apps/landing/src/app/[locale]/licensing/thank-you/page.tsx
  • packages/ui/src/tabs.tsx
  • apps/web/src/components/new-participant-modal.tsx
  • packages/ui/src/breadcrumb.tsx
  • apps/landing/src/app/[locale]/(main)/pricing/page.tsx
  • packages/ui/src/tooltip.tsx
  • apps/web/src/app/[locale]/layout.tsx
  • packages/ui/src/sheet.tsx
  • apps/web/src/components/forms/poll-options-form/week-calendar.tsx
  • packages/ui/src/textarea.tsx
  • apps/web/src/components/time-zone-picker/time-zone-select.tsx
  • packages/ui/src/popover.tsx
  • packages/ui/src/switch.tsx
  • apps/web/src/app/[locale]/(space)/(dashboard)/components/upgrade-to-pro-alert.tsx
  • apps/web/src/components/discussion/discussion.tsx
  • apps/web/src/features/billing/components/pay-wall-dialog.tsx
  • packages/ui/src/dropdown-menu.tsx
  • packages/ui/src/command.tsx
  • apps/landing/src/app/[locale]/layout.tsx
  • packages/ui/src/alert.tsx
  • packages/ui/src/checkbox.tsx
  • packages/ui/src/toast.tsx
  • packages/ui/src/sidebar.tsx
  • packages/ui/src/select.tsx
  • packages/ui/src/billing-plan.tsx
  • apps/web/src/components/forms/poll-options-form/month-calendar/month-calendar.tsx
  • packages/ui/src/progress.tsx
  • apps/web/src/components/cookie-consent.tsx
  • apps/web/src/app/[locale]/(space)/settings/layout.tsx
  • packages/ui/src/card.tsx
  • packages/ui/src/separator.tsx
  • apps/web/src/components/full-width-layout.tsx
  • apps/web/src/app/[locale]/(space)/(dashboard)/components/nav-user.tsx
  • apps/web/src/components/empty-state.tsx
  • apps/landing/next.config.ts
  • apps/web/src/app/[locale]/(auth)/layout.tsx
  • apps/web/src/features/space/components/space-dropdown.tsx
  • apps/landing/src/components/home/bonus-item.tsx
  • apps/web/src/components/poll/desktop-poll.tsx
  • packages/ui/src/page-tabs.tsx
  • apps/web/src/app/components/page-layout.tsx
  • packages/ui/src/table.tsx
  • packages/ui/src/badge.tsx
  • apps/web/src/app/[locale]/accept-invite/[inviteId]/page.tsx
  • apps/landing/src/app/[locale]/(main)/layout.tsx
  • apps/web/src/components/description-list.tsx
  • apps/web/next.config.ts
  • packages/ui/src/avatar.tsx
  • packages/ui/src/radio-group.tsx
apps/web/src/components/**

📄 CodeRabbit inference engine (CLAUDE.md)

Place shared components in apps/web/src/components/

Files:

  • apps/web/src/components/maintenance.tsx
  • apps/web/src/components/poll/scheduled-event.tsx
  • apps/web/src/components/skeleton.tsx
  • apps/web/src/components/vote-summary-progress-bar.tsx
  • apps/web/src/components/new-participant-modal.tsx
  • apps/web/src/components/forms/poll-options-form/week-calendar.tsx
  • apps/web/src/components/time-zone-picker/time-zone-select.tsx
  • apps/web/src/components/discussion/discussion.tsx
  • apps/web/src/components/forms/poll-options-form/month-calendar/month-calendar.tsx
  • apps/web/src/components/cookie-consent.tsx
  • apps/web/src/components/full-width-layout.tsx
  • apps/web/src/components/empty-state.tsx
  • apps/web/src/components/poll/desktop-poll.tsx
  • apps/web/src/components/description-list.tsx
apps/web/**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (apps/web/.cursor/rules/better-auth.md)

apps/web/**/*.{ts,tsx,js,jsx}: When using the username plugin, require all sign up endpoints to accept a username (used for login, normalized) and an optional displayUsername (raw, for display purposes).
When using the username plugin, all username values must be normalized according to the configuration function before storage or comparison (default: lowercase).
Whenever updating a user's username, always check for uniqueness and apply the normalization procedure.
Login endpoints or forms supporting username authentication must allow signing in with username and password, not just email.

Files:

  • apps/web/src/components/maintenance.tsx
  • apps/web/src/components/poll/scheduled-event.tsx
  • apps/web/src/components/skeleton.tsx
  • apps/web/src/components/vote-summary-progress-bar.tsx
  • apps/web/src/components/new-participant-modal.tsx
  • apps/web/src/app/[locale]/layout.tsx
  • apps/web/src/components/forms/poll-options-form/week-calendar.tsx
  • apps/web/src/components/time-zone-picker/time-zone-select.tsx
  • apps/web/src/app/[locale]/(space)/(dashboard)/components/upgrade-to-pro-alert.tsx
  • apps/web/src/components/discussion/discussion.tsx
  • apps/web/src/features/billing/components/pay-wall-dialog.tsx
  • apps/web/src/components/forms/poll-options-form/month-calendar/month-calendar.tsx
  • apps/web/src/components/cookie-consent.tsx
  • apps/web/src/app/[locale]/(space)/settings/layout.tsx
  • apps/web/src/components/full-width-layout.tsx
  • apps/web/src/app/[locale]/(space)/(dashboard)/components/nav-user.tsx
  • apps/web/src/components/empty-state.tsx
  • apps/web/src/app/[locale]/(auth)/layout.tsx
  • apps/web/src/features/space/components/space-dropdown.tsx
  • apps/web/src/components/poll/desktop-poll.tsx
  • apps/web/postcss.config.js
  • apps/web/src/app/components/page-layout.tsx
  • apps/web/src/app/[locale]/accept-invite/[inviteId]/page.tsx
  • apps/web/src/components/description-list.tsx
  • apps/web/next.config.ts
packages/ui/**/*.tsx

📄 CodeRabbit inference engine (.cursorrules)

shadcn-ui components should be added to packages/ui

Files:

  • packages/ui/src/button.tsx
  • packages/ui/src/tabs.tsx
  • packages/ui/src/breadcrumb.tsx
  • packages/ui/src/tooltip.tsx
  • packages/ui/src/sheet.tsx
  • packages/ui/src/textarea.tsx
  • packages/ui/src/popover.tsx
  • packages/ui/src/switch.tsx
  • packages/ui/src/dropdown-menu.tsx
  • packages/ui/src/command.tsx
  • packages/ui/src/alert.tsx
  • packages/ui/src/checkbox.tsx
  • packages/ui/src/toast.tsx
  • packages/ui/src/sidebar.tsx
  • packages/ui/src/select.tsx
  • packages/ui/src/billing-plan.tsx
  • packages/ui/src/progress.tsx
  • packages/ui/src/card.tsx
  • packages/ui/src/separator.tsx
  • packages/ui/src/page-tabs.tsx
  • packages/ui/src/table.tsx
  • packages/ui/src/badge.tsx
  • packages/ui/src/avatar.tsx
  • packages/ui/src/radio-group.tsx
apps/web/src/app/**

📄 CodeRabbit inference engine (CLAUDE.md)

Use Next.js App Router conventions for route handlers

Files:

  • apps/web/src/app/[locale]/layout.tsx
  • apps/web/src/app/[locale]/globals.css
  • apps/web/src/app/[locale]/(space)/(dashboard)/components/upgrade-to-pro-alert.tsx
  • apps/web/src/app/[locale]/(space)/settings/layout.tsx
  • apps/web/src/app/[locale]/(space)/(dashboard)/components/nav-user.tsx
  • apps/web/src/app/[locale]/(auth)/layout.tsx
  • apps/web/src/app/components/page-layout.tsx
  • apps/web/src/app/[locale]/accept-invite/[inviteId]/page.tsx
apps/web/src/features/**

📄 CodeRabbit inference engine (CLAUDE.md)

Organize features in apps/web/src/features/[feature]/ directory structure

Files:

  • apps/web/src/features/billing/components/pay-wall-dialog.tsx
  • apps/web/src/features/space/components/space-dropdown.tsx
**/*.ts

📄 CodeRabbit inference engine (.cursorrules)

On the server use the getTranslations function from @/i18n/server to get the translations

Files:

  • apps/landing/next.config.ts
  • apps/web/next.config.ts
🧠 Learnings (18)
📓 Common learnings
Learnt from: CR
Repo: lukevella/rallly PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T11:04:05.725Z
Learning: Applies to **/*.{tsx,ts} : Use TailwindCSS with custom design system for styling
Learnt from: CR
Repo: lukevella/rallly PR: 0
File: .cursorrules:0-0
Timestamp: 2025-11-25T11:03:55.173Z
Learning: Applies to **/*.{tsx,css,config.ts} : Use tailwindcss for styling
Learnt from: CR
Repo: lukevella/rallly PR: 0
File: .cursorrules:0-0
Timestamp: 2025-11-25T11:03:55.173Z
Learning: Applies to **/*.tsx : Prefer composable components in the style of shadcn UI over large monolithic components
📚 Learning: 2025-11-25T11:03:55.173Z
Learnt from: CR
Repo: lukevella/rallly PR: 0
File: .cursorrules:0-0
Timestamp: 2025-11-25T11:03:55.173Z
Learning: Applies to **/*.{tsx,css,config.ts} : Use tailwindcss for styling

Applied to files:

  • apps/web/src/components/maintenance.tsx
  • packages/tailwind-config/shared-styles.css
  • apps/web/src/app/[locale]/layout.tsx
  • apps/web/src/app/[locale]/globals.css
  • apps/landing/package.json
  • apps/web/src/components/time-zone-picker/time-zone-select.tsx
  • apps/landing/src/app/[locale]/globals.css
  • packages/ui/src/command.tsx
  • apps/landing/src/app/[locale]/layout.tsx
  • packages/ui/src/alert.tsx
  • packages/ui/src/checkbox.tsx
  • packages/ui/src/sidebar.tsx
  • packages/tailwind-config/package.json
  • apps/web/src/globals.css
  • packages/ui/src/progress.tsx
  • apps/landing/postcss.config.js
  • packages/ui/package.json
  • packages/ui/src/separator.tsx
  • apps/web/src/app/[locale]/(auth)/layout.tsx
  • apps/web/src/components/poll/desktop-poll.tsx
  • apps/web/package.json
  • apps/web/postcss.config.js
  • packages/tailwind-config/postcss.config.js
📚 Learning: 2025-11-25T11:03:55.173Z
Learnt from: CR
Repo: lukevella/rallly PR: 0
File: .cursorrules:0-0
Timestamp: 2025-11-25T11:03:55.173Z
Learning: Applies to **/*.tsx : Prefer composable components in the style of shadcn UI over large monolithic components

Applied to files:

  • apps/web/src/components/maintenance.tsx
  • packages/ui/src/tabs.tsx
  • packages/tailwind-config/shared-styles.css
  • apps/web/src/app/[locale]/layout.tsx
  • apps/web/src/components/time-zone-picker/time-zone-select.tsx
  • packages/ui/src/command.tsx
  • apps/landing/src/app/[locale]/layout.tsx
  • packages/ui/src/sidebar.tsx
  • packages/ui/src/select.tsx
  • packages/ui/src/card.tsx
  • packages/ui/package.json
  • packages/ui/src/separator.tsx
  • apps/web/src/components/full-width-layout.tsx
  • apps/landing/src/components/home/bonus-item.tsx
  • apps/web/src/app/components/page-layout.tsx
  • packages/ui/src/table.tsx
  • apps/web/src/components/description-list.tsx
📚 Learning: 2025-11-25T11:03:55.173Z
Learnt from: CR
Repo: lukevella/rallly PR: 0
File: .cursorrules:0-0
Timestamp: 2025-11-25T11:03:55.173Z
Learning: Applies to **/*.tsx : Use `cn()` from rallly/ui to compose classes

Applied to files:

  • apps/web/src/components/skeleton.tsx
  • apps/landing/src/app/[locale]/(main)/pricing/page.tsx
  • packages/ui/src/tooltip.tsx
  • apps/web/src/app/[locale]/globals.css
  • packages/ui/src/textarea.tsx
  • packages/ui/src/command.tsx
  • apps/landing/src/app/[locale]/layout.tsx
  • packages/ui/src/sidebar.tsx
  • packages/ui/src/select.tsx
  • packages/ui/src/billing-plan.tsx
  • apps/web/src/globals.css
  • packages/ui/src/card.tsx
  • packages/ui/src/separator.tsx
  • apps/web/src/app/[locale]/(auth)/layout.tsx
  • apps/web/src/components/poll/desktop-poll.tsx
  • packages/ui/src/page-tabs.tsx
  • apps/web/src/app/components/page-layout.tsx
  • packages/ui/src/table.tsx
  • packages/ui/src/badge.tsx
  • apps/landing/src/app/[locale]/(main)/layout.tsx
  • apps/web/src/components/description-list.tsx
📚 Learning: 2025-11-25T11:03:55.173Z
Learnt from: CR
Repo: lukevella/rallly PR: 0
File: .cursorrules:0-0
Timestamp: 2025-11-25T11:03:55.173Z
Learning: Applies to **/*.tsx : DropdownMenuItem is a flex container with a preset gap so there is no need to add margins to the children

Applied to files:

  • apps/web/src/components/vote-summary-progress-bar.tsx
  • packages/ui/src/dropdown-menu.tsx
  • packages/ui/src/sidebar.tsx
  • apps/web/src/app/[locale]/(space)/(dashboard)/components/nav-user.tsx
  • apps/web/src/features/space/components/space-dropdown.tsx
  • apps/landing/src/components/home/bonus-item.tsx
  • apps/web/src/app/components/page-layout.tsx
📚 Learning: 2025-11-25T11:04:05.725Z
Learnt from: CR
Repo: lukevella/rallly PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T11:04:05.725Z
Learning: Rallly is built with Next.js 15, React 19, tRPC, Prisma with PostgreSQL, NextAuth.js, TailwindCSS, and TypeScript throughout

Applied to files:

  • apps/landing/src/app/[locale]/licensing/thank-you/page.tsx
  • apps/web/src/app/[locale]/globals.css
  • apps/landing/package.json
  • apps/landing/src/app/[locale]/globals.css
  • packages/tailwind-config/package.json
  • apps/web/src/globals.css
  • apps/web/package.json
  • apps/landing/src/app/[locale]/(main)/layout.tsx
📚 Learning: 2025-11-25T11:03:55.173Z
Learnt from: CR
Repo: lukevella/rallly PR: 0
File: .cursorrules:0-0
Timestamp: 2025-11-25T11:03:55.173Z
Learning: Applies to packages/ui/**/*.tsx : shadcn-ui components should be added to packages/ui

Applied to files:

  • packages/ui/src/tabs.tsx
  • packages/ui/src/tooltip.tsx
  • apps/web/src/app/[locale]/layout.tsx
  • packages/ui/src/command.tsx
  • packages/ui/src/sidebar.tsx
  • packages/ui/src/select.tsx
  • packages/ui/src/billing-plan.tsx
  • packages/ui/src/progress.tsx
  • packages/ui/src/card.tsx
  • packages/ui/package.json
  • apps/landing/src/components/home/bonus-item.tsx
  • packages/ui/src/table.tsx
📚 Learning: 2025-11-25T11:04:05.725Z
Learnt from: CR
Repo: lukevella/rallly PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T11:04:05.725Z
Learning: Applies to **/*.{tsx,ts} : Use TailwindCSS with custom design system for styling

Applied to files:

  • packages/tailwind-config/shared-styles.css
  • apps/web/src/app/[locale]/layout.tsx
  • apps/web/src/app/[locale]/globals.css
  • apps/landing/package.json
  • apps/web/src/components/time-zone-picker/time-zone-select.tsx
  • apps/landing/src/app/[locale]/globals.css
  • packages/ui/src/command.tsx
  • apps/landing/src/app/[locale]/layout.tsx
  • packages/ui/src/alert.tsx
  • packages/ui/src/sidebar.tsx
  • packages/tailwind-config/package.json
  • apps/web/src/globals.css
  • packages/ui/src/progress.tsx
  • apps/landing/postcss.config.js
  • packages/ui/package.json
  • packages/ui/src/separator.tsx
  • apps/web/src/app/[locale]/(auth)/layout.tsx
  • apps/web/package.json
  • apps/web/postcss.config.js
  • packages/tailwind-config/postcss.config.js
📚 Learning: 2025-11-25T11:03:55.173Z
Learnt from: CR
Repo: lukevella/rallly PR: 0
File: .cursorrules:0-0
Timestamp: 2025-11-25T11:03:55.173Z
Learning: Applies to **/*.tsx : The size and colour of an icon should be set by wrapping it with the <Icon> component from rallly/ui/icon which will give it the correct colour and size

Applied to files:

  • packages/tailwind-config/shared-styles.css
  • packages/ui/src/tooltip.tsx
  • apps/web/src/features/billing/components/pay-wall-dialog.tsx
  • packages/ui/src/alert.tsx
  • packages/ui/src/sidebar.tsx
  • packages/ui/src/select.tsx
  • apps/web/src/components/empty-state.tsx
  • apps/landing/src/components/home/bonus-item.tsx
  • apps/landing/src/app/[locale]/(main)/layout.tsx
  • packages/ui/src/avatar.tsx
📚 Learning: 2025-11-25T11:03:55.173Z
Learnt from: CR
Repo: lukevella/rallly PR: 0
File: .cursorrules:0-0
Timestamp: 2025-11-25T11:03:55.173Z
Learning: Applies to **/*.tsx : All text in the UI should be translatable

Applied to files:

  • apps/web/src/app/[locale]/layout.tsx
  • apps/landing/src/app/[locale]/layout.tsx
  • packages/ui/src/table.tsx
  • apps/landing/src/app/[locale]/(main)/layout.tsx
📚 Learning: 2025-09-12T21:37:47.353Z
Learnt from: lukevella
Repo: lukevella/rallly PR: 1951
File: packages/ui/src/dialog.tsx:23-25
Timestamp: 2025-09-12T21:37:47.353Z
Learning: React.ElementRef is deprecated and has been replaced by React.ComponentRef for TypeScript ref typing in React components, including Radix UI forwardRef components.

Applied to files:

  • packages/ui/src/switch.tsx
📚 Learning: 2025-11-25T11:04:05.725Z
Learnt from: CR
Repo: lukevella/rallly PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T11:04:05.725Z
Learning: Applies to **/*.{tsx,ts} : Always use the `useDialog` hook from `rallly/ui/dialog` for managing dialog state instead of manual `useState` for open/close state

Applied to files:

  • packages/ui/src/command.tsx
📚 Learning: 2025-11-25T11:03:55.173Z
Learnt from: CR
Repo: lukevella/rallly PR: 0
File: .cursorrules:0-0
Timestamp: 2025-11-25T11:03:55.173Z
Learning: Applies to **/*.tsx : Use the <Trans> component in client components from @/components/trans with the `defaults` prop to provide the default text

Applied to files:

  • packages/ui/src/select.tsx
  • packages/ui/src/table.tsx
📚 Learning: 2025-11-25T11:03:55.173Z
Learnt from: CR
Repo: lukevella/rallly PR: 0
File: .cursorrules:0-0
Timestamp: 2025-11-25T11:03:55.173Z
Learning: Applies to **/*.{ts,tsx,json} : i18n keys are in camelCase

Applied to files:

  • packages/ui/package.json
📚 Learning: 2025-11-25T11:03:55.173Z
Learnt from: CR
Repo: lukevella/rallly PR: 0
File: .cursorrules:0-0
Timestamp: 2025-11-25T11:03:55.173Z
Learning: Applies to **/*.tsx : Add the "use client" directive to the top of any .tsx file that requires client-side javascript

Applied to files:

  • packages/ui/package.json
📚 Learning: 2025-11-25T11:03:55.173Z
Learnt from: CR
Repo: lukevella/rallly PR: 0
File: .cursorrules:0-0
Timestamp: 2025-11-25T11:03:55.173Z
Learning: Applies to **/*.{ts,tsx} : Create separate import statements for types

Applied to files:

  • packages/ui/package.json
  • apps/landing/next.config.ts
  • apps/web/next.config.ts
📚 Learning: 2025-11-25T11:04:05.725Z
Learnt from: CR
Repo: lukevella/rallly PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T11:04:05.725Z
Learning: Applies to apps/web/src/app/** : Use Next.js App Router conventions for route handlers

Applied to files:

  • apps/landing/next.config.ts
  • apps/web/next.config.ts
📚 Learning: 2025-11-25T11:03:55.173Z
Learnt from: CR
Repo: lukevella/rallly PR: 0
File: .cursorrules:0-0
Timestamp: 2025-11-25T11:03:55.173Z
Learning: Applies to **/*.tsx : All text in the UI should be translated using either the Trans component or the useTranslation hook

Applied to files:

  • packages/ui/src/table.tsx
🧬 Code graph analysis (5)
apps/landing/src/app/[locale]/licensing/thank-you/page.tsx (1)
apps/landing/src/i18n/client/link.tsx (1)
  • LinkBase (7-26)
apps/web/src/components/new-participant-modal.tsx (1)
packages/ui/src/lib/utils.ts (1)
  • cn (5-7)
apps/web/src/components/time-zone-picker/time-zone-select.tsx (1)
packages/ui/src/command.tsx (1)
  • CommandList (192-192)
apps/web/postcss.config.js (1)
packages/tailwind-config/postcss.config.js (2)
  • postcssConfig (2-6)
  • postcssConfig (2-6)
apps/landing/src/app/[locale]/(main)/layout.tsx (1)
apps/landing/src/i18n/client/link.tsx (1)
  • LinkBase (7-26)
🪛 Biome (2.1.2)
packages/ui/src/breadcrumb.tsx

[error] 22-22: These CSS classes should be sorted.

Safe fix: Sort the classes.

(lint/nursery/useSortedClasses)

packages/ui/src/command.tsx

[error] 39-39: These CSS classes should be sorted.

Safe fix: Sort the classes.

(lint/nursery/useSortedClasses)

packages/ui/src/sidebar.tsx

[error] 513-513: These CSS classes should be sorted.

Safe fix: Sort the classes.

(lint/nursery/useSortedClasses)


[error] 527-527: These CSS classes should be sorted.

Safe fix: Sort the classes.

(lint/nursery/useSortedClasses)

apps/web/src/components/forms/poll-options-form/month-calendar/month-calendar.tsx

[error] 190-190: These CSS classes should be sorted.

Safe fix: Sort the classes.

(lint/nursery/useSortedClasses)

apps/web/src/components/description-list.tsx

[error] 42-42: These CSS classes should be sorted.

Safe fix: Sort the classes.

(lint/nursery/useSortedClasses)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Integration tests

<Button
onClick={() => authClient.signIn.email({...})}
variant={lastMethod === "email" ? "default" : "outline"}
variant={lastMethod === "email" ? "default" : "outline-solid"}
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

# Find Button component definition files
fd -type f -name "*Button*" apps/web/src packages/ui/src 2>/dev/null | head -20

Repository: lukevella/rallly

Length of output: 42


🏁 Script executed:

# Search for Button component exports and variant definitions
rg -l "export.*Button" --type ts --type tsx apps/web/src packages/ui/src 2>/dev/null | head -10

Repository: lukevella/rallly

Length of output: 42


🏁 Script executed:

# Search for variant type definitions or variant usage with "outline"
rg "outline-solid|outline.*variant" --type ts --type tsx apps/web/src packages/ui/src 2>/dev/null | head -30

Repository: lukevella/rallly

Length of output: 42


🏁 Script executed:

# Look for design system variant definitions
fd -type f -name "*variants*" -o -name "*button*" apps/web/src packages/ui/src 2>/dev/null | grep -E "\.(ts|tsx)$" | head -15

Repository: lukevella/rallly

Length of output: 42


🏁 Script executed:

# Check repository structure
git ls-files | head -30

Repository: lukevella/rallly

Length of output: 900


🏁 Script executed:

# Find all markdown files in cursor rules
find . -type f -name "*.md" -path "*cursor*" 2>/dev/null | head -20

Repository: lukevella/rallly

Length of output: 135


🏁 Script executed:

# Look for any Button-related files
find . -type f -name "*[Bb]utton*" 2>/dev/null | head -20

Repository: lukevella/rallly

Length of output: 1028


🏁 Script executed:

# Check top-level directory structure
ls -la | grep -E "^d"

Repository: lukevella/rallly

Length of output: 582


🏁 Script executed:

# Read the Button component to see available variants
cat -n packages/ui/src/button.tsx

Repository: lukevella/rallly

Length of output: 3761


🏁 Script executed:

# Read the better-auth.md file to see the context around the specified lines
wc -l apps/web/.cursor/rules/better-auth.md

Repository: lukevella/rallly

Length of output: 103


🏁 Script executed:

# Get the specific lines mentioned in the review comment
sed -n '24700,24740p' apps/web/.cursor/rules/better-auth.md | cat -n

Repository: lukevella/rallly

Length of output: 1988


"outline-solid" is not a valid Button variant; remove or replace with an existing variant.

The documentation examples use variant="outline-solid" on lines 24706, 24720, and 24733, but this variant does not exist in the Button component definition. The available variants are: primary, destructive, default, secondary, ghost, actionBar, and link. Replace "outline-solid" with an appropriate existing variant or remove the variant prop to use the default.

🤖 Prompt for AI Agents
In apps/web/.cursor/rules/better-auth.md around line 24706 the Button uses
variant="outline-solid", which is not a supported variant; update those
occurrences (lines ~24706, 24720, 24733) to use one of the supported variants
(primary, destructive, default, secondary, ghost, actionBar, or link) or remove
the variant prop to fall back to the default; choose the variant that matches
the intended visual (e.g., replace "outline-solid" with "default" or
"secondary") and ensure consistency across the three instances.

Comment on lines 5 to 9
"type": "module",
"exports": {
".": "./shared-styles.css",
"./postcss": "./postcss.config.js"
},
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

rg -n '@rallly/tailwind-config' --glob '*.{js,jsx,ts,tsx}' -A 2 -B 2

Repository: lukevella/rallly

Length of output: 1075


🏁 Script executed:

cat -n packages/tailwind-config/package.json | grep -A 10 '"exports"'

Repository: lukevella/rallly

Length of output: 403


🏁 Script executed:

ls -la packages/tailwind-config/ | grep -E '\.js|\.ts|\.css'

Repository: lukevella/rallly

Length of output: 258


The exports structure breaks an existing import in packages/ui/tailwind.config.js

packages/ui/tailwind.config.js line 1 requires "@rallly/tailwind-config/tailwind.config", but this export path is not defined in package.json and the file does not exist in packages/tailwind-config/. Either remove this import or add tailwind.config.js to the package and update the exports map.

🤖 Prompt for AI Agents
In packages/tailwind-config/package.json around lines 5 to 9, the exports map
does not expose "tailwind.config" but packages/ui/tailwind.config.js imports
"@rallly/tailwind-config/tailwind.config", causing a broken import; either (A)
add a tailwind.config.js file to packages/tailwind-config and add an exports
entry like "./tailwind.config": "./tailwind.config.js" to package.json, or (B)
remove/replace the import in packages/ui/tailwind.config.js to reference an
existing export (e.g., "@rallly/tailwind-config" or the shared-styles.css) so
the import path matches the package's exports.

Comment on lines +4 to +114
@theme {
--shadow-huge:
0px 51px 78px rgb(17 7 53 / 5%), 0px 21.3066px 35.4944px rgb(17 7 53 / 4%),
0px 11.3915px 18.9418px rgb(17 7 53 / 3%),
0px 6.38599px 9.8801px rgb(17 7 53 / 3%),
0px 3.39155px 4.58665px rgb(17 7 53 / 2%),
0px 1.4113px 1.55262px rgb(17 7 53 / 1%),
inset 0px 1px 0px rgb(41 56 78 / 5%);

--color-primary-50: #eef2ff;
--color-primary-100: #e0e7ff;
--color-primary-200: #c7d2fe;
--color-primary-300: #a5b4fc;
--color-primary-400: #818cf8;
--color-primary-500: #6366f1;
--color-primary-600: #4f46e5;
--color-primary-700: #4338ca;
--color-primary-800: #3730a3;
--color-primary-900: #312e81;
--color-primary-950: #1e1b4b;
--color-primary: #4f46e5;
--color-primary-foreground: #eef2ff;
--color-primary-background: #eef2ff;

--color-secondary-background: #eef2ff;
--color-secondary: #eef2ff;
--color-secondary-foreground: #4f46e5;

--color-gray-50: #f9fafb;
--color-gray-100: #f3f4f6;
--color-gray-200: #e5e7eb;
--color-gray-300: #d1d5db;
--color-gray-400: #9ca3af;
--color-gray-500: #6b7280;
--color-gray-600: #4b5563;
--color-gray-700: #374151;
--color-gray-800: #1f2937;
--color-gray-900: #111827;
--color-gray-950: #030712;

--color-border: #e5e7eb;

--color-input: #e5e7eb;
--color-input-background: #fff;
--color-input-foreground: #374151;

--color-ring: #d1d5db;

--color-destructive: #e11d48;
--color-destructive-background: #fff1f2;
--color-destructive-foreground: #fff1f2;

--color-background: #fff;
--color-foreground: #374151;

--color-accent: #f3f4f6;

--color-action-bar: #1f2937;
--color-action-bar-foreground: #f9fafb;

--color-muted: #f3f4f6;
--color-muted-background: #f9fafb;
--color-muted-foreground: #6b7280;

--color-popover: #fff;
--color-popover-foreground: #374151;

--color-card: #fff;
--color-card-background: #fff;
--color-card-foreground: #374151;

--color-sidebar: #f3f4f6;
--color-sidebar-foreground: #374151;
--color-sidebar-border: #e5e7eb;

--color-sidebar-accent: #e5e7eb;
--color-sidebar-accent-foreground: #1f2937;

--animate-wiggle: wiggle 0.2s ease-in-out;
--animate-pop-in: popIn 0.1s ease-out;

--breakpoint-xs: 375px;

--ease-in-expo: cubic-bezier(0.68, -0.6, 0.32, 1.6);
--ease-out-expo: cubic-bezier(0.19, 1, 0.22, 1);

--font-sans:
var(--font-inter), ui-sans-serif, system-ui, sans-serif,
'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji';

@keyframes wiggle {
0%,
100% {
transform: rotate(-1deg);
}
50% {
transform: rotate(1deg);
}
}
@keyframes popIn {
0% {
transform: scale(0.8) translateY(-10px);
opacity: 0;
}
100% {
transform: scale(1) translateY(0px);
opacity: 1;
translate-y: 0;
}
}
}
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Design tokens + keyframes look solid; drop invalid translate-y property

The @theme block cleanly defines shadows, color tokens, typography, and animation tokens, and the wiggle/popIn keyframes align with the rest of the design system. One small correctness issue: translate-y in @keyframes popIn isn’t a valid CSS property and will be ignored by the browser.

You can safely remove it:

   @keyframes popIn {
     0% {
       transform: scale(0.8) translateY(-10px);
       opacity: 0;
     }
     100% {
       transform: scale(1) translateY(0px);
       opacity: 1;
-      translate-y: 0;
     }
   }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
@theme {
--shadow-huge:
0px 51px 78px rgb(17 7 53 / 5%), 0px 21.3066px 35.4944px rgb(17 7 53 / 4%),
0px 11.3915px 18.9418px rgb(17 7 53 / 3%),
0px 6.38599px 9.8801px rgb(17 7 53 / 3%),
0px 3.39155px 4.58665px rgb(17 7 53 / 2%),
0px 1.4113px 1.55262px rgb(17 7 53 / 1%),
inset 0px 1px 0px rgb(41 56 78 / 5%);
--color-primary-50: #eef2ff;
--color-primary-100: #e0e7ff;
--color-primary-200: #c7d2fe;
--color-primary-300: #a5b4fc;
--color-primary-400: #818cf8;
--color-primary-500: #6366f1;
--color-primary-600: #4f46e5;
--color-primary-700: #4338ca;
--color-primary-800: #3730a3;
--color-primary-900: #312e81;
--color-primary-950: #1e1b4b;
--color-primary: #4f46e5;
--color-primary-foreground: #eef2ff;
--color-primary-background: #eef2ff;
--color-secondary-background: #eef2ff;
--color-secondary: #eef2ff;
--color-secondary-foreground: #4f46e5;
--color-gray-50: #f9fafb;
--color-gray-100: #f3f4f6;
--color-gray-200: #e5e7eb;
--color-gray-300: #d1d5db;
--color-gray-400: #9ca3af;
--color-gray-500: #6b7280;
--color-gray-600: #4b5563;
--color-gray-700: #374151;
--color-gray-800: #1f2937;
--color-gray-900: #111827;
--color-gray-950: #030712;
--color-border: #e5e7eb;
--color-input: #e5e7eb;
--color-input-background: #fff;
--color-input-foreground: #374151;
--color-ring: #d1d5db;
--color-destructive: #e11d48;
--color-destructive-background: #fff1f2;
--color-destructive-foreground: #fff1f2;
--color-background: #fff;
--color-foreground: #374151;
--color-accent: #f3f4f6;
--color-action-bar: #1f2937;
--color-action-bar-foreground: #f9fafb;
--color-muted: #f3f4f6;
--color-muted-background: #f9fafb;
--color-muted-foreground: #6b7280;
--color-popover: #fff;
--color-popover-foreground: #374151;
--color-card: #fff;
--color-card-background: #fff;
--color-card-foreground: #374151;
--color-sidebar: #f3f4f6;
--color-sidebar-foreground: #374151;
--color-sidebar-border: #e5e7eb;
--color-sidebar-accent: #e5e7eb;
--color-sidebar-accent-foreground: #1f2937;
--animate-wiggle: wiggle 0.2s ease-in-out;
--animate-pop-in: popIn 0.1s ease-out;
--breakpoint-xs: 375px;
--ease-in-expo: cubic-bezier(0.68, -0.6, 0.32, 1.6);
--ease-out-expo: cubic-bezier(0.19, 1, 0.22, 1);
--font-sans:
var(--font-inter), ui-sans-serif, system-ui, sans-serif,
'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji';
@keyframes wiggle {
0%,
100% {
transform: rotate(-1deg);
}
50% {
transform: rotate(1deg);
}
}
@keyframes popIn {
0% {
transform: scale(0.8) translateY(-10px);
opacity: 0;
}
100% {
transform: scale(1) translateY(0px);
opacity: 1;
translate-y: 0;
}
}
}
@theme {
--shadow-huge:
0px 51px 78px rgb(17 7 53 / 5%), 0px 21.3066px 35.4944px rgb(17 7 53 / 4%),
0px 11.3915px 18.9418px rgb(17 7 53 / 3%),
0px 6.38599px 9.8801px rgb(17 7 53 / 3%),
0px 3.39155px 4.58665px rgb(17 7 53 / 2%),
0px 1.4113px 1.55262px rgb(17 7 53 / 1%),
inset 0px 1px 0px rgb(41 56 78 / 5%);
--color-primary-50: #eef2ff;
--color-primary-100: #e0e7ff;
--color-primary-200: #c7d2fe;
--color-primary-300: #a5b4fc;
--color-primary-400: #818cf8;
--color-primary-500: #6366f1;
--color-primary-600: #4f46e5;
--color-primary-700: #4338ca;
--color-primary-800: #3730a3;
--color-primary-900: #312e81;
--color-primary-950: #1e1b4b;
--color-primary: #4f46e5;
--color-primary-foreground: #eef2ff;
--color-primary-background: #eef2ff;
--color-secondary-background: #eef2ff;
--color-secondary: #eef2ff;
--color-secondary-foreground: #4f46e5;
--color-gray-50: #f9fafb;
--color-gray-100: #f3f4f6;
--color-gray-200: #e5e7eb;
--color-gray-300: #d1d5db;
--color-gray-400: #9ca3af;
--color-gray-500: #6b7280;
--color-gray-600: #4b5563;
--color-gray-700: #374151;
--color-gray-800: #1f2937;
--color-gray-900: #111827;
--color-gray-950: #030712;
--color-border: #e5e7eb;
--color-input: #e5e7eb;
--color-input-background: #fff;
--color-input-foreground: #374151;
--color-ring: #d1d5db;
--color-destructive: #e11d48;
--color-destructive-background: #fff1f2;
--color-destructive-foreground: #fff1f2;
--color-background: #fff;
--color-foreground: #374151;
--color-accent: #f3f4f6;
--color-action-bar: #1f2937;
--color-action-bar-foreground: #f9fafb;
--color-muted: #f3f4f6;
--color-muted-background: #f9fafb;
--color-muted-foreground: #6b7280;
--color-popover: #fff;
--color-popover-foreground: #374151;
--color-card: #fff;
--color-card-background: #fff;
--color-card-foreground: #374151;
--color-sidebar: #f3f4f6;
--color-sidebar-foreground: #374151;
--color-sidebar-border: #e5e7eb;
--color-sidebar-accent: #e5e7eb;
--color-sidebar-accent-foreground: #1f2937;
--animate-wiggle: wiggle 0.2s ease-in-out;
--animate-pop-in: popIn 0.1s ease-out;
--breakpoint-xs: 375px;
--ease-in-expo: cubic-bezier(0.68, -0.6, 0.32, 1.6);
--ease-out-expo: cubic-bezier(0.19, 1, 0.22, 1);
--font-sans:
var(--font-inter), ui-sans-serif, system-ui, sans-serif,
'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji';
@keyframes wiggle {
0%,
100% {
transform: rotate(-1deg);
}
50% {
transform: rotate(1deg);
}
}
@keyframes popIn {
0% {
transform: scale(0.8) translateY(-10px);
opacity: 0;
}
100% {
transform: scale(1) translateY(0px);
opacity: 1;
}
}
}
🤖 Prompt for AI Agents
In packages/tailwind-config/shared-styles.css around lines 4 to 114, the
@keyframes popIn contains an invalid CSS property "translate-y" which should be
removed; edit the 100% keyframe to drop the "translate-y: 0;" line so only valid
transform and opacity properties remain.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 411139c and 380e868.

📒 Files selected for processing (7)
  • apps/web/src/components/description-list.tsx (1 hunks)
  • apps/web/src/components/forms/poll-options-form/month-calendar/month-calendar.tsx (3 hunks)
  • apps/web/src/components/forms/poll-options-form/rbc-overrides.css (1 hunks)
  • apps/web/src/components/new-participant-modal.tsx (1 hunks)
  • packages/ui/src/breadcrumb.tsx (1 hunks)
  • packages/ui/src/command.tsx (5 hunks)
  • packages/ui/src/sidebar.tsx (13 hunks)
🚧 Files skipped from review as they are similar to previous changes (4)
  • apps/web/src/components/forms/poll-options-form/month-calendar/month-calendar.tsx
  • apps/web/src/components/new-participant-modal.tsx
  • apps/web/src/components/description-list.tsx
  • packages/ui/src/command.tsx
🧰 Additional context used
📓 Path-based instructions (9)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursorrules)

**/*.{ts,tsx}: Use dayjs for date handling
Use react-query for data fetching
Prefer implicit return values over explicit return values
Use zod for form validation
Create separate import statements for types
Prefer using the React module APIs (e.g. React.useState) instead of standalone hooks (e.g. useState)
Prefer double quotes for strings over single quotes
Only add comments when it is necessary to explain code that isn't self-explanatory

**/*.{ts,tsx}: Only create named interfaces when they're reused or complex
When TypeScript errors occur for missing i18n keys, run pnpm i18n:scan instead of manually adding keys

Files:

  • packages/ui/src/sidebar.tsx
  • packages/ui/src/breadcrumb.tsx
**/*.{tsx,css,config.ts}

📄 CodeRabbit inference engine (.cursorrules)

Use tailwindcss for styling

Files:

  • packages/ui/src/sidebar.tsx
  • apps/web/src/components/forms/poll-options-form/rbc-overrides.css
  • packages/ui/src/breadcrumb.tsx
**/*.tsx

📄 CodeRabbit inference engine (.cursorrules)

**/*.tsx: Use react-hook-form for form handling
All text in the UI should be translated using either the Trans component or the useTranslation hook
Prefer composable components in the style of shadcn UI over large monolithic components
DropdownMenuItem is a flex container with a preset gap so there is no need to add margins to the children
The size and colour of an icon should be set by wrapping it with the component from @rallly/ui/icon which will give it the correct colour and size
Keep the props of a component as minimal as possible. Pass only the bare minimum amount of information needed to it
All text in the UI should be translatable
Use the component in client components from @/components/trans with the defaults prop to provide the default text
Always use a composable patterns when building components
Use cn() from @rallly/ui to compose classes
Add the "use client" directive to the top of any .tsx file that requires client-side javascript

Files:

  • packages/ui/src/sidebar.tsx
  • packages/ui/src/breadcrumb.tsx
**/*.{ts,tsx,json}

📄 CodeRabbit inference engine (.cursorrules)

**/*.{ts,tsx,json}: i18n keys are in camelCase
i18nKeys should describe the message in camelCase. Ex. "lastUpdated": "Last Updated"
If the i18nKey is not intended to be reused, prefix it with the component name in camelCase

Files:

  • packages/ui/src/sidebar.tsx
  • packages/ui/src/breadcrumb.tsx
packages/ui/**/*.tsx

📄 CodeRabbit inference engine (.cursorrules)

shadcn-ui components should be added to packages/ui

Files:

  • packages/ui/src/sidebar.tsx
  • packages/ui/src/breadcrumb.tsx
**/*

📄 CodeRabbit inference engine (.cursorrules)

Always use kebab-case for file names

Files:

  • packages/ui/src/sidebar.tsx
  • apps/web/src/components/forms/poll-options-form/rbc-overrides.css
  • packages/ui/src/breadcrumb.tsx
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (CLAUDE.md)

Use Biome for code formatting with indent of 2 spaces and double quotes

Files:

  • packages/ui/src/sidebar.tsx
  • packages/ui/src/breadcrumb.tsx
**/*.{tsx,ts}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.{tsx,ts}: Prefer inline prop types over named interfaces for simple component props (e.g., function Component({ prop }: { prop: string }) instead of defining a separate interface)
Always use the useDialog hook from @rallly/ui/dialog for managing dialog state instead of manual useState for open/close state
Use TanStack Query with tRPC for server state management
Use React Context for client state (auth, preferences, etc.)
Use react-hook-form with Zod validation for form state management
Use TailwindCSS with custom design system for styling

Files:

  • packages/ui/src/sidebar.tsx
  • packages/ui/src/breadcrumb.tsx
apps/web/src/components/**

📄 CodeRabbit inference engine (CLAUDE.md)

Place shared components in apps/web/src/components/

Files:

  • apps/web/src/components/forms/poll-options-form/rbc-overrides.css
🧠 Learnings (8)
📓 Common learnings
Learnt from: CR
Repo: lukevella/rallly PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T11:04:05.725Z
Learning: Applies to **/*.{tsx,ts} : Use TailwindCSS with custom design system for styling
Learnt from: CR
Repo: lukevella/rallly PR: 0
File: .cursorrules:0-0
Timestamp: 2025-11-25T11:03:55.173Z
Learning: Applies to **/*.{tsx,css,config.ts} : Use tailwindcss for styling
📚 Learning: 2025-11-25T11:04:05.725Z
Learnt from: CR
Repo: lukevella/rallly PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T11:04:05.725Z
Learning: Applies to **/*.{tsx,ts} : Use TailwindCSS with custom design system for styling

Applied to files:

  • packages/ui/src/sidebar.tsx
📚 Learning: 2025-11-25T11:03:55.173Z
Learnt from: CR
Repo: lukevella/rallly PR: 0
File: .cursorrules:0-0
Timestamp: 2025-11-25T11:03:55.173Z
Learning: Applies to **/*.tsx : Prefer composable components in the style of shadcn UI over large monolithic components

Applied to files:

  • packages/ui/src/sidebar.tsx
📚 Learning: 2025-11-25T11:03:55.173Z
Learnt from: CR
Repo: lukevella/rallly PR: 0
File: .cursorrules:0-0
Timestamp: 2025-11-25T11:03:55.173Z
Learning: Applies to **/*.{tsx,css,config.ts} : Use tailwindcss for styling

Applied to files:

  • packages/ui/src/sidebar.tsx
📚 Learning: 2025-11-25T11:03:55.173Z
Learnt from: CR
Repo: lukevella/rallly PR: 0
File: .cursorrules:0-0
Timestamp: 2025-11-25T11:03:55.173Z
Learning: Applies to packages/ui/**/*.tsx : shadcn-ui components should be added to packages/ui

Applied to files:

  • packages/ui/src/sidebar.tsx
📚 Learning: 2025-11-25T11:03:55.173Z
Learnt from: CR
Repo: lukevella/rallly PR: 0
File: .cursorrules:0-0
Timestamp: 2025-11-25T11:03:55.173Z
Learning: Applies to **/*.tsx : Use `cn()` from rallly/ui to compose classes

Applied to files:

  • packages/ui/src/sidebar.tsx
📚 Learning: 2025-11-25T11:03:55.173Z
Learnt from: CR
Repo: lukevella/rallly PR: 0
File: .cursorrules:0-0
Timestamp: 2025-11-25T11:03:55.173Z
Learning: Applies to **/*.tsx : DropdownMenuItem is a flex container with a preset gap so there is no need to add margins to the children

Applied to files:

  • packages/ui/src/sidebar.tsx
📚 Learning: 2025-11-25T11:03:55.173Z
Learnt from: CR
Repo: lukevella/rallly PR: 0
File: .cursorrules:0-0
Timestamp: 2025-11-25T11:03:55.173Z
Learning: Applies to **/*.tsx : The size and colour of an icon should be set by wrapping it with the <Icon> component from rallly/ui/icon which will give it the correct colour and size

Applied to files:

  • packages/ui/src/sidebar.tsx
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Integration tests
🔇 Additional comments (1)
packages/ui/src/sidebar.tsx (1)

136-136: All Tailwind 4 syntax changes are correct and valid.

The conversions from Tailwind v3 to v4 follow proper syntax:

  • CSS variables use the new parentheses shorthand: w-(--sidebar-width) (v4 introduced (--var) as shorthand for [var(--var)])
  • outline-hidden is a valid v4 utility that hides the default browser focus outline while preserving high-contrast mode support
  • Shadow tokens shadow-xs and shadow-2xs are new v4 utilities with defined default values
  • Selector variants has-data-[variant=inset] and in-data-[side=left] are valid composable data variants in v4

No changes needed.

Comment on lines 11 to 13
.rbc-time-content > * + * > * {
@apply border-gray-200;
border-color: var(--color-gray-200);
}
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

Remove duplicate selector.

The .rbc-time-content > * + * > * selector appears twice (lines 11–13 and 72–74) with identical styling. Keep only one instance.

 .rbc-time-content > * + * > * {
   border-color: var(--color-gray-200);
 }
 
 .rbc-time-content {
   border-top: 0;
 }
 
 .rbc-time-view .rbc-allday-cell {
   display: none;
 }
 
 .rbc-current-time-indicator {
   background-color: #fb7185;
 }
 
 .rbc-header + .rbc-header {
   border-left: 0;
 }
 
 .rbc-time-slot {
   padding-left: 0.5rem;
   padding-top: 0.25rem;
 }
 
 .rbc-timeslot-group {
   border-color: var(--color-gray-100);
 }
 
 .rbc-day-slot .rbc-time-slot {
   border-style: dashed;
   border-color: var(--color-gray-50);
 }
 
 .rbc-day-slot .rbc-events-container {
   margin-right: 0.5rem;
 }
 
 .rbc-slot-selection {
   background-color: color-mix(in srgb, var(--color-gray-100) 50%, transparent);
   line-height: 1.25;
   color: var(--color-gray-600);
 }
 
 .rbc-header.rbc-today {
   background-color: var(--color-background);
   color: #e11d48;
 }
 
 .rbc-button-link {
   pointer-events: none;
   margin: 0.25rem;
   width: 100%;
 }
 
-.rbc-time-content > * + * > * {
-  border-color: var(--color-gray-100);
-}
-
 .rbc-time-header-gutter {
   border-bottom: 1px solid var(--color-gray-100);
 }

Also applies to: 72-74

🤖 Prompt for AI Agents
In apps/web/src/components/forms/poll-options-form/rbc-overrides.css around
lines 11-13 (and duplicate at 72-74), the selector `.rbc-time-content > * + * >
*` is duplicated with identical rules; remove the redundant occurrence and keep
a single definition. Pick one of the two blocks (prefer the one in the more
semantically appropriate section or the earlier occurrence), delete the other,
and run a quick CSS lint/format to ensure no leftover blank lines or ordering
changes.


.rbc-current-time-indicator {
@apply bg-rose-400;
background-color: #fb7185;
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Replace hardcoded color values with CSS variables to maintain design system consistency.

The hardcoded hex colors #fb7185 (line 30, rose-400) and #e11d48 (line 63, rose-600) break the pattern of using CSS variables established throughout the rest of this file and contradict the PR's goal of centralizing the design system.

Verify that corresponding CSS variables exist in your design system (e.g., --color-rose-400, --color-rose-600, or an equivalent), then apply this diff:

 .rbc-current-time-indicator {
-  background-color: #fb7185;
+  background-color: var(--color-rose-400);
 }
 
 ...
 
 .rbc-header.rbc-today {
   background-color: var(--color-background);
-  color: #e11d48;
+  color: var(--color-rose-600);
 }

Also applies to: 63-63

🤖 Prompt for AI Agents
In apps/web/src/components/forms/poll-options-form/rbc-overrides.css around
lines 30 and 63, replace the hardcoded hex colors (#fb7185 at line 30 and
#e11d48 at line 63) with the corresponding design-system CSS variables (e.g.,
--color-rose-400 and --color-rose-600 or their project equivalents); verify the
exact variable names exist in the design system and then update the rules to use
var(--color-rose-400) and var(--color-rose-600) respectively so the file stays
consistent with the centralized theme.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 380e868 and 08ef4b9.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (6)
  • apps/landing/package.json (1 hunks)
  • apps/landing/postcss.config.mjs (1 hunks)
  • apps/web/package.json (4 hunks)
  • apps/web/postcss.config.mjs (1 hunks)
  • packages/tailwind-config/package.json (1 hunks)
  • packages/tailwind-config/postcss.config.mjs (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • apps/web/package.json
🧰 Additional context used
📓 Path-based instructions (2)
**/*

📄 CodeRabbit inference engine (.cursorrules)

Always use kebab-case for file names

Files:

  • packages/tailwind-config/postcss.config.mjs
  • apps/web/postcss.config.mjs
  • apps/landing/postcss.config.mjs
  • packages/tailwind-config/package.json
  • apps/landing/package.json
**/*.{ts,tsx,json}

📄 CodeRabbit inference engine (.cursorrules)

**/*.{ts,tsx,json}: i18n keys are in camelCase
i18nKeys should describe the message in camelCase. Ex. "lastUpdated": "Last Updated"
If the i18nKey is not intended to be reused, prefix it with the component name in camelCase

Files:

  • packages/tailwind-config/package.json
  • apps/landing/package.json
🧠 Learnings (4)
📓 Common learnings
Learnt from: CR
Repo: lukevella/rallly PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T11:04:05.725Z
Learning: Applies to **/*.{tsx,ts} : Use TailwindCSS with custom design system for styling
Learnt from: CR
Repo: lukevella/rallly PR: 0
File: .cursorrules:0-0
Timestamp: 2025-11-25T11:03:55.173Z
Learning: Applies to **/*.{tsx,css,config.ts} : Use tailwindcss for styling
📚 Learning: 2025-11-25T11:03:55.173Z
Learnt from: CR
Repo: lukevella/rallly PR: 0
File: .cursorrules:0-0
Timestamp: 2025-11-25T11:03:55.173Z
Learning: Applies to **/*.{tsx,css,config.ts} : Use tailwindcss for styling

Applied to files:

  • packages/tailwind-config/postcss.config.mjs
  • apps/web/postcss.config.mjs
  • apps/landing/postcss.config.mjs
  • packages/tailwind-config/package.json
  • apps/landing/package.json
📚 Learning: 2025-11-25T11:04:05.725Z
Learnt from: CR
Repo: lukevella/rallly PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T11:04:05.725Z
Learning: Applies to **/*.{tsx,ts} : Use TailwindCSS with custom design system for styling

Applied to files:

  • packages/tailwind-config/postcss.config.mjs
  • apps/web/postcss.config.mjs
  • apps/landing/postcss.config.mjs
  • packages/tailwind-config/package.json
  • apps/landing/package.json
📚 Learning: 2025-11-25T11:04:05.725Z
Learnt from: CR
Repo: lukevella/rallly PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T11:04:05.725Z
Learning: Rallly is built with Next.js 15, React 19, tRPC, Prisma with PostgreSQL, NextAuth.js, TailwindCSS, and TypeScript throughout

Applied to files:

  • packages/tailwind-config/package.json
  • apps/landing/package.json
🧬 Code graph analysis (2)
apps/web/postcss.config.mjs (1)
packages/tailwind-config/postcss.config.mjs (2)
  • postcssConfig (2-6)
  • postcssConfig (2-6)
apps/landing/postcss.config.mjs (1)
packages/tailwind-config/postcss.config.mjs (2)
  • postcssConfig (2-6)
  • postcssConfig (2-6)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Integration tests
🔇 Additional comments (5)
packages/tailwind-config/package.json (1)

5-9: ESM package type and exports map look appropriate for the shared Tailwind config.

Marking the package as ESM and exporting "." to shared-styles.css plus "./postcss" to postcss.config.mjs matches how the apps import from @rallly/tailwind-config/postcss and consume shared styles.

packages/tailwind-config/postcss.config.mjs (1)

1-6: Shared PostCSS config is minimal and aligned with Tailwind 4 usage.

Centralizing the PostCSS plugins into postcssConfig with @tailwindcss/postcss keeps app-level configs thin and consistent; structure looks good.

apps/web/postcss.config.mjs (1)

1-3: Re-exporting the shared PostCSS config keeps web app setup DRY.

Importing { postcssConfig } from @rallly/tailwind-config/postcss and exporting it as default cleanly wires the web app into the centralized Tailwind/PostCSS pipeline.

apps/landing/postcss.config.mjs (1)

1-3: Landing app correctly reuses the centralized PostCSS config.

Mirroring the web app’s postcss.config.mjs keeps Tailwind/PostCSS behavior consistent across apps and avoids local config drift.

apps/landing/package.json (1)

40-41: Tailwind dependency addition is consistent across the monorepo.

Adding tailwindcss ^4.1.18 here aligns with the versions used in apps/web/package.json and packages/tailwind-config/package.json. No version skew in the workspace.

Comment on lines +11 to 13
"postcss": "^8.5.6",
"tailwindcss": "^4.1.18"
},
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Check where @tailwindcss/postcss is declared as a dependency in the repo
rg -n '"@tailwindcss/postcss"' package.json -S -C2 || echo "No @tailwindcss/postcss dependency found in package.json files."

Repository: lukevella/rallly

Length of output: 123


🏁 Script executed:

#!/bin/bash
# Check the postcss.config.mjs file to see what plugins it uses
find . -name "postcss.config.mjs" -o -name "postcss.config.js" | head -10

Repository: lukevella/rallly

Length of output: 169


🏁 Script executed:

#!/bin/bash
# Get the full content of the tailwind-config package.json
cat -n packages/tailwind-config/package.json

Repository: lukevella/rallly

Length of output: 644


🏁 Script executed:

cat -n packages/tailwind-config/postcss.config.mjs

Repository: lukevella/rallly

Length of output: 249


🏁 Script executed:

# Also check the other postcss.config.mjs files to see the pattern
cat -n apps/landing/postcss.config.mjs
cat -n apps/web/postcss.config.mjs

Repository: lukevella/rallly

Length of output: 292


🏁 Script executed:

# Check root package.json for @tailwindcss/postcss
cat -n package.json | grep -A5 -B5 "@tailwindcss/postcss" || echo "Checking full root package.json..."

Repository: lukevella/rallly

Length of output: 94


🏁 Script executed:

# Get root package.json to see all dependencies
cat -n package.json | head -100

Repository: lukevella/rallly

Length of output: 2403


🏁 Script executed:

# Search for @tailwindcss/postcss in the entire repo
rg "@tailwindcss/postcss" --type json -B2 -A2

Repository: lukevella/rallly

Length of output: 367


🏁 Script executed:

# Check which other packages might be consuming @rallly/tailwind-config/postcss
rg "@rallly/tailwind-config/postcss" --type json

Repository: lukevella/rallly

Length of output: 42


🏁 Script executed:

# Verify if tailwindcss 4.1.18 lists @tailwindcss/postcss as a dependency
# by checking npm/package info (this helps understand if it's a peer dependency)
npm info [email protected] 2>/dev/null | head -50 || echo "Checking if there's a node_modules version..."

Repository: lukevella/rallly

Length of output: 749


Add @tailwindcss/postcss as an explicit dependency in packages/tailwind-config/package.json.

packages/tailwind-config/postcss.config.mjs uses the @tailwindcss/postcss plugin, and this package exports the config via the "./postcss" entry point. Currently, @tailwindcss/postcss is not declared as a dependency here, creating an implicit reliance on hoisting from other packages (like apps/web which declares @tailwindcss/postcss@^4.1.17). To ensure the exported postcss config is self-contained and works reliably in any consuming package, declare @tailwindcss/postcss explicitly in dependencies or devDependencies with a version compatible with tailwindcss@^4.1.18.

🤖 Prompt for AI Agents
In packages/tailwind-config/package.json lines 11-13, the package uses the
@tailwindcss/postcss plugin in postcss.config.mjs but does not declare it as a
dependency, creating an implicit hoist reliance; add "@tailwindcss/postcss" to
dependencies or devDependencies with a version compatible with
tailwindcss@^4.1.18 (for example "^4.1.17" or "^4.1.18") so the exported postcss
entry ("./postcss") is self-contained and resolves reliably for consumers.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 4

♻️ Duplicate comments (3)
packages/tailwind-config/package.json (2)

5-9: Exports map: ensure no remaining imports reference the removed @rallly/tailwind-config/tailwind.config path
This was already flagged in prior review comments; still worth confirming given the new "exports" map.

#!/bin/bash
set -euo pipefail

# Expectation: no remaining imports of the removed entrypoint.
rg -nP --glob '*.{js,jsx,ts,tsx}' '\b@rallly/tailwind-config/tailwind\.config\b' -C2 || true

# Also check other possible deep imports.
rg -nP --glob '*.{js,jsx,ts,tsx}' '\b@rallly/tailwind-config/(?!postcss\b)[^"\s]+' -C2 || true

10-13: Declare @tailwindcss/postcss in this package (exported config references it)
packages/tailwind-config/postcss.config.mjs uses @tailwindcss/postcss; without declaring it here, consumers can break depending on hoisting.

 {
@@
   "dependencies": {
+    "@tailwindcss/postcss": "^4.1.18",
     "postcss": "^8.5.6",
     "tailwindcss": "^4.1.18"
   },
For Tailwind CSS v4.1.x, is `@tailwindcss/postcss` required as a direct dependency of packages exporting a PostCSS config that references it?
packages/tailwind-config/shared-styles.css (1)

103-113: Remove invalid translate-y property (ignored by browsers)
This matches the existing prior review note on this PR.

 @keyframes popIn {
@@
   100% {
     transform: scale(1) translateY(0px);
     opacity: 1;
-    translate-y: 0;
   }
 }
🧹 Nitpick comments (7)
packages/ui/src/switch.tsx (1)

14-18: Tailwind v4 outline-hidden change is good; consider updating React.ElementRef -> React.ComponentRef. Aligns this component with the newer ref-typing pattern already used elsewhere (e.g. command.tsx).

-const Switch = React.forwardRef<
-  React.ElementRef<typeof SwitchPrimitives.Root>,
+const Switch = React.forwardRef<
+  React.ComponentRef<typeof SwitchPrimitives.Root>,
   React.ComponentPropsWithoutRef<typeof SwitchPrimitives.Root> & {
     icon?: React.ReactNode;
   }
 >(({ className, ...props }, ref) => (
packages/ui/src/tabs.tsx (2)

30-34: TabsTrigger outline-hidden change is fine; consider ElementRef -> ComponentRef for consistency.


44-49: TabsContent outline-hidden change is fine; consider ElementRef -> ComponentRef for consistency.

packages/ui/src/radio-group.tsx (1)

28-33: RadioGroupItem focus outline migration looks correct; consider ElementRef -> ComponentRef.

packages/ui/src/page-tabs.tsx (2)

26-32: Page TabsTrigger outline-hidden change is good; consider ElementRef -> ComponentRef for consistency.


42-47: Page TabsContent outline-hidden change is good; consider ElementRef -> ComponentRef for consistency.

apps/landing/next.config.ts (1)

16-18: Remove redundant JSDoc type now that nextConfig is typed
Line 16 is unnecessary once you have const nextConfig: NextConfig = ... (Line 17).

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 08ef4b9 and 91f47e3.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (75)
  • apps/landing/next.config.ts (2 hunks)
  • apps/landing/package.json (1 hunks)
  • apps/landing/postcss.config.js (0 hunks)
  • apps/landing/postcss.config.mjs (1 hunks)
  • apps/landing/src/app/[locale]/(main)/layout.tsx (1 hunks)
  • apps/landing/src/app/[locale]/(main)/pricing/page.tsx (1 hunks)
  • apps/landing/src/app/[locale]/globals.css (1 hunks)
  • apps/landing/src/app/[locale]/layout.tsx (1 hunks)
  • apps/landing/src/app/[locale]/licensing/thank-you/page.tsx (1 hunks)
  • apps/landing/src/components/home/bonus-item.tsx (1 hunks)
  • apps/landing/src/style.css (0 hunks)
  • apps/landing/tailwind.config.js (0 hunks)
  • apps/web/.cursor/rules/better-auth.md (3 hunks)
  • apps/web/next.config.ts (1 hunks)
  • apps/web/package.json (4 hunks)
  • apps/web/postcss.config.js (0 hunks)
  • apps/web/postcss.config.mjs (1 hunks)
  • apps/web/src/app/[locale]/(auth)/layout.tsx (1 hunks)
  • apps/web/src/app/[locale]/(space)/(dashboard)/components/nav-user.tsx (1 hunks)
  • apps/web/src/app/[locale]/(space)/(dashboard)/components/upgrade-to-pro-alert.tsx (1 hunks)
  • apps/web/src/app/[locale]/(space)/settings/layout.tsx (1 hunks)
  • apps/web/src/app/[locale]/accept-invite/[inviteId]/page.tsx (1 hunks)
  • apps/web/src/app/[locale]/globals.css (1 hunks)
  • apps/web/src/app/[locale]/layout.tsx (1 hunks)
  • apps/web/src/app/components/page-layout.tsx (1 hunks)
  • apps/web/src/components/cookie-consent.tsx (1 hunks)
  • apps/web/src/components/description-list.tsx (1 hunks)
  • apps/web/src/components/discussion/discussion.tsx (1 hunks)
  • apps/web/src/components/empty-state.tsx (1 hunks)
  • apps/web/src/components/forms/poll-options-form/month-calendar/month-calendar.tsx (3 hunks)
  • apps/web/src/components/forms/poll-options-form/rbc-overrides.css (1 hunks)
  • apps/web/src/components/forms/poll-options-form/week-calendar.tsx (1 hunks)
  • apps/web/src/components/full-width-layout.tsx (1 hunks)
  • apps/web/src/components/maintenance.tsx (1 hunks)
  • apps/web/src/components/new-participant-modal.tsx (1 hunks)
  • apps/web/src/components/poll/desktop-poll.tsx (2 hunks)
  • apps/web/src/components/poll/scheduled-event.tsx (1 hunks)
  • apps/web/src/components/skeleton.tsx (1 hunks)
  • apps/web/src/components/time-zone-picker/time-zone-select.tsx (1 hunks)
  • apps/web/src/components/vote-summary-progress-bar.tsx (1 hunks)
  • apps/web/src/features/billing/components/pay-wall-dialog.tsx (2 hunks)
  • apps/web/src/features/space/components/space-dropdown.tsx (1 hunks)
  • apps/web/src/globals.css (1 hunks)
  • apps/web/src/style.css (0 hunks)
  • apps/web/tailwind.config.js (0 hunks)
  • packages/tailwind-config/package.json (1 hunks)
  • packages/tailwind-config/postcss.config.mjs (1 hunks)
  • packages/tailwind-config/shared-styles.css (1 hunks)
  • packages/tailwind-config/tailwind.config.d.ts (0 hunks)
  • packages/tailwind-config/tailwind.config.js (0 hunks)
  • packages/ui/package.json (1 hunks)
  • packages/ui/src/alert.tsx (1 hunks)
  • packages/ui/src/avatar.tsx (1 hunks)
  • packages/ui/src/badge.tsx (1 hunks)
  • packages/ui/src/billing-plan.tsx (1 hunks)
  • packages/ui/src/breadcrumb.tsx (1 hunks)
  • packages/ui/src/button.tsx (1 hunks)
  • packages/ui/src/card.tsx (1 hunks)
  • packages/ui/src/checkbox.tsx (1 hunks)
  • packages/ui/src/command.tsx (5 hunks)
  • packages/ui/src/dropdown-menu.tsx (5 hunks)
  • packages/ui/src/page-tabs.tsx (2 hunks)
  • packages/ui/src/popover.tsx (1 hunks)
  • packages/ui/src/progress.tsx (1 hunks)
  • packages/ui/src/radio-group.tsx (1 hunks)
  • packages/ui/src/select.tsx (3 hunks)
  • packages/ui/src/separator.tsx (1 hunks)
  • packages/ui/src/sheet.tsx (1 hunks)
  • packages/ui/src/sidebar.tsx (13 hunks)
  • packages/ui/src/switch.tsx (1 hunks)
  • packages/ui/src/table.tsx (2 hunks)
  • packages/ui/src/tabs.tsx (2 hunks)
  • packages/ui/src/textarea.tsx (1 hunks)
  • packages/ui/src/toast.tsx (4 hunks)
  • packages/ui/src/tooltip.tsx (1 hunks)
💤 Files with no reviewable changes (8)
  • apps/web/src/style.css
  • packages/tailwind-config/tailwind.config.d.ts
  • apps/landing/src/style.css
  • packages/tailwind-config/tailwind.config.js
  • apps/landing/tailwind.config.js
  • apps/web/postcss.config.js
  • apps/web/tailwind.config.js
  • apps/landing/postcss.config.js
✅ Files skipped from review due to trivial changes (1)
  • apps/web/src/components/forms/poll-options-form/week-calendar.tsx
🚧 Files skipped from review as they are similar to previous changes (45)
  • apps/landing/src/app/[locale]/licensing/thank-you/page.tsx
  • apps/landing/src/components/home/bonus-item.tsx
  • apps/landing/src/app/[locale]/layout.tsx
  • packages/ui/src/select.tsx
  • apps/landing/src/app/[locale]/(main)/pricing/page.tsx
  • packages/ui/src/badge.tsx
  • packages/ui/src/card.tsx
  • apps/web/src/app/[locale]/(space)/(dashboard)/components/nav-user.tsx
  • apps/web/src/components/cookie-consent.tsx
  • packages/ui/package.json
  • packages/ui/src/tooltip.tsx
  • apps/web/src/components/poll/desktop-poll.tsx
  • apps/web/src/app/[locale]/(space)/settings/layout.tsx
  • packages/ui/src/table.tsx
  • apps/web/src/components/new-participant-modal.tsx
  • apps/web/src/components/skeleton.tsx
  • apps/web/src/features/billing/components/pay-wall-dialog.tsx
  • packages/ui/src/avatar.tsx
  • packages/ui/src/alert.tsx
  • packages/ui/src/textarea.tsx
  • apps/web/src/components/description-list.tsx
  • apps/web/package.json
  • apps/web/src/globals.css
  • apps/web/src/components/empty-state.tsx
  • packages/ui/src/dropdown-menu.tsx
  • apps/web/src/app/[locale]/accept-invite/[inviteId]/page.tsx
  • apps/web/src/app/components/page-layout.tsx
  • packages/ui/src/billing-plan.tsx
  • apps/web/src/components/maintenance.tsx
  • packages/ui/src/progress.tsx
  • apps/web/postcss.config.mjs
  • apps/web/src/components/time-zone-picker/time-zone-select.tsx
  • apps/web/src/components/discussion/discussion.tsx
  • apps/web/src/app/[locale]/globals.css
  • packages/tailwind-config/postcss.config.mjs
  • apps/web/next.config.ts
  • packages/ui/src/sheet.tsx
  • apps/web/src/components/vote-summary-progress-bar.tsx
  • packages/ui/src/breadcrumb.tsx
  • apps/web/src/components/forms/poll-options-form/rbc-overrides.css
  • apps/web/src/components/full-width-layout.tsx
  • apps/landing/src/app/[locale]/(main)/layout.tsx
  • apps/web/src/app/[locale]/layout.tsx
  • packages/ui/src/separator.tsx
  • apps/landing/src/app/[locale]/globals.css
🧰 Additional context used
📓 Path-based instructions (13)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursorrules)

**/*.{ts,tsx}: Use dayjs for date handling
Use react-query for data fetching
Prefer implicit return values over explicit return values
Use zod for form validation
Create separate import statements for types
Prefer using the React module APIs (e.g. React.useState) instead of standalone hooks (e.g. useState)
Prefer double quotes for strings over single quotes
Only add comments when it is necessary to explain code that isn't self-explanatory

**/*.{ts,tsx}: Only create named interfaces when they're reused or complex
When TypeScript errors occur for missing i18n keys, run pnpm i18n:scan instead of manually adding keys

Files:

  • packages/ui/src/page-tabs.tsx
  • packages/ui/src/toast.tsx
  • packages/ui/src/tabs.tsx
  • apps/web/src/features/space/components/space-dropdown.tsx
  • packages/ui/src/switch.tsx
  • apps/web/src/app/[locale]/(auth)/layout.tsx
  • packages/ui/src/popover.tsx
  • packages/ui/src/button.tsx
  • apps/web/src/app/[locale]/(space)/(dashboard)/components/upgrade-to-pro-alert.tsx
  • packages/ui/src/command.tsx
  • apps/landing/next.config.ts
  • packages/ui/src/checkbox.tsx
  • apps/web/src/components/poll/scheduled-event.tsx
  • packages/ui/src/sidebar.tsx
  • apps/web/src/components/forms/poll-options-form/month-calendar/month-calendar.tsx
  • packages/ui/src/radio-group.tsx
**/*.{tsx,css,config.ts}

📄 CodeRabbit inference engine (.cursorrules)

Use tailwindcss for styling

Files:

  • packages/ui/src/page-tabs.tsx
  • packages/ui/src/toast.tsx
  • packages/ui/src/tabs.tsx
  • apps/web/src/features/space/components/space-dropdown.tsx
  • packages/ui/src/switch.tsx
  • apps/web/src/app/[locale]/(auth)/layout.tsx
  • packages/ui/src/popover.tsx
  • packages/ui/src/button.tsx
  • apps/web/src/app/[locale]/(space)/(dashboard)/components/upgrade-to-pro-alert.tsx
  • packages/ui/src/command.tsx
  • packages/tailwind-config/shared-styles.css
  • apps/landing/next.config.ts
  • packages/ui/src/checkbox.tsx
  • apps/web/src/components/poll/scheduled-event.tsx
  • packages/ui/src/sidebar.tsx
  • apps/web/src/components/forms/poll-options-form/month-calendar/month-calendar.tsx
  • packages/ui/src/radio-group.tsx
**/*.tsx

📄 CodeRabbit inference engine (.cursorrules)

**/*.tsx: Use react-hook-form for form handling
All text in the UI should be translated using either the Trans component or the useTranslation hook
Prefer composable components in the style of shadcn UI over large monolithic components
DropdownMenuItem is a flex container with a preset gap so there is no need to add margins to the children
The size and colour of an icon should be set by wrapping it with the component from @rallly/ui/icon which will give it the correct colour and size
Keep the props of a component as minimal as possible. Pass only the bare minimum amount of information needed to it
All text in the UI should be translatable
Use the component in client components from @/components/trans with the defaults prop to provide the default text
Always use a composable patterns when building components
Use cn() from @rallly/ui to compose classes
Add the "use client" directive to the top of any .tsx file that requires client-side javascript

Files:

  • packages/ui/src/page-tabs.tsx
  • packages/ui/src/toast.tsx
  • packages/ui/src/tabs.tsx
  • apps/web/src/features/space/components/space-dropdown.tsx
  • packages/ui/src/switch.tsx
  • apps/web/src/app/[locale]/(auth)/layout.tsx
  • packages/ui/src/popover.tsx
  • packages/ui/src/button.tsx
  • apps/web/src/app/[locale]/(space)/(dashboard)/components/upgrade-to-pro-alert.tsx
  • packages/ui/src/command.tsx
  • packages/ui/src/checkbox.tsx
  • apps/web/src/components/poll/scheduled-event.tsx
  • packages/ui/src/sidebar.tsx
  • apps/web/src/components/forms/poll-options-form/month-calendar/month-calendar.tsx
  • packages/ui/src/radio-group.tsx
**/*.{ts,tsx,json}

📄 CodeRabbit inference engine (.cursorrules)

**/*.{ts,tsx,json}: i18n keys are in camelCase
i18nKeys should describe the message in camelCase. Ex. "lastUpdated": "Last Updated"
If the i18nKey is not intended to be reused, prefix it with the component name in camelCase

Files:

  • packages/ui/src/page-tabs.tsx
  • packages/ui/src/toast.tsx
  • packages/ui/src/tabs.tsx
  • apps/web/src/features/space/components/space-dropdown.tsx
  • packages/ui/src/switch.tsx
  • apps/landing/package.json
  • apps/web/src/app/[locale]/(auth)/layout.tsx
  • packages/ui/src/popover.tsx
  • packages/ui/src/button.tsx
  • apps/web/src/app/[locale]/(space)/(dashboard)/components/upgrade-to-pro-alert.tsx
  • packages/ui/src/command.tsx
  • apps/landing/next.config.ts
  • packages/ui/src/checkbox.tsx
  • apps/web/src/components/poll/scheduled-event.tsx
  • packages/ui/src/sidebar.tsx
  • apps/web/src/components/forms/poll-options-form/month-calendar/month-calendar.tsx
  • packages/ui/src/radio-group.tsx
  • packages/tailwind-config/package.json
packages/ui/**/*.tsx

📄 CodeRabbit inference engine (.cursorrules)

shadcn-ui components should be added to packages/ui

Files:

  • packages/ui/src/page-tabs.tsx
  • packages/ui/src/toast.tsx
  • packages/ui/src/tabs.tsx
  • packages/ui/src/switch.tsx
  • packages/ui/src/popover.tsx
  • packages/ui/src/button.tsx
  • packages/ui/src/command.tsx
  • packages/ui/src/checkbox.tsx
  • packages/ui/src/sidebar.tsx
  • packages/ui/src/radio-group.tsx
**/*

📄 CodeRabbit inference engine (.cursorrules)

Always use kebab-case for file names

Files:

  • packages/ui/src/page-tabs.tsx
  • packages/ui/src/toast.tsx
  • packages/ui/src/tabs.tsx
  • apps/web/src/features/space/components/space-dropdown.tsx
  • packages/ui/src/switch.tsx
  • apps/landing/package.json
  • apps/web/src/app/[locale]/(auth)/layout.tsx
  • packages/ui/src/popover.tsx
  • packages/ui/src/button.tsx
  • apps/web/src/app/[locale]/(space)/(dashboard)/components/upgrade-to-pro-alert.tsx
  • packages/ui/src/command.tsx
  • packages/tailwind-config/shared-styles.css
  • apps/landing/postcss.config.mjs
  • apps/landing/next.config.ts
  • packages/ui/src/checkbox.tsx
  • apps/web/src/components/poll/scheduled-event.tsx
  • packages/ui/src/sidebar.tsx
  • apps/web/src/components/forms/poll-options-form/month-calendar/month-calendar.tsx
  • packages/ui/src/radio-group.tsx
  • packages/tailwind-config/package.json
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (CLAUDE.md)

Use Biome for code formatting with indent of 2 spaces and double quotes

Files:

  • packages/ui/src/page-tabs.tsx
  • packages/ui/src/toast.tsx
  • packages/ui/src/tabs.tsx
  • apps/web/src/features/space/components/space-dropdown.tsx
  • packages/ui/src/switch.tsx
  • apps/web/src/app/[locale]/(auth)/layout.tsx
  • packages/ui/src/popover.tsx
  • packages/ui/src/button.tsx
  • apps/web/src/app/[locale]/(space)/(dashboard)/components/upgrade-to-pro-alert.tsx
  • packages/ui/src/command.tsx
  • apps/landing/next.config.ts
  • packages/ui/src/checkbox.tsx
  • apps/web/src/components/poll/scheduled-event.tsx
  • packages/ui/src/sidebar.tsx
  • apps/web/src/components/forms/poll-options-form/month-calendar/month-calendar.tsx
  • packages/ui/src/radio-group.tsx
**/*.{tsx,ts}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.{tsx,ts}: Prefer inline prop types over named interfaces for simple component props (e.g., function Component({ prop }: { prop: string }) instead of defining a separate interface)
Always use the useDialog hook from @rallly/ui/dialog for managing dialog state instead of manual useState for open/close state
Use TanStack Query with tRPC for server state management
Use React Context for client state (auth, preferences, etc.)
Use react-hook-form with Zod validation for form state management
Use TailwindCSS with custom design system for styling

Files:

  • packages/ui/src/page-tabs.tsx
  • packages/ui/src/toast.tsx
  • packages/ui/src/tabs.tsx
  • apps/web/src/features/space/components/space-dropdown.tsx
  • packages/ui/src/switch.tsx
  • apps/web/src/app/[locale]/(auth)/layout.tsx
  • packages/ui/src/popover.tsx
  • packages/ui/src/button.tsx
  • apps/web/src/app/[locale]/(space)/(dashboard)/components/upgrade-to-pro-alert.tsx
  • packages/ui/src/command.tsx
  • apps/landing/next.config.ts
  • packages/ui/src/checkbox.tsx
  • apps/web/src/components/poll/scheduled-event.tsx
  • packages/ui/src/sidebar.tsx
  • apps/web/src/components/forms/poll-options-form/month-calendar/month-calendar.tsx
  • packages/ui/src/radio-group.tsx
apps/web/src/features/**

📄 CodeRabbit inference engine (CLAUDE.md)

Organize features in apps/web/src/features/[feature]/ directory structure

Files:

  • apps/web/src/features/space/components/space-dropdown.tsx
apps/web/**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (apps/web/.cursor/rules/better-auth.md)

apps/web/**/*.{ts,tsx,js,jsx}: When using the username plugin, require all sign up endpoints to accept a username (used for login, normalized) and an optional displayUsername (raw, for display purposes).
When using the username plugin, all username values must be normalized according to the configuration function before storage or comparison (default: lowercase).
Whenever updating a user's username, always check for uniqueness and apply the normalization procedure.
Login endpoints or forms supporting username authentication must allow signing in with username and password, not just email.

Files:

  • apps/web/src/features/space/components/space-dropdown.tsx
  • apps/web/src/app/[locale]/(auth)/layout.tsx
  • apps/web/src/app/[locale]/(space)/(dashboard)/components/upgrade-to-pro-alert.tsx
  • apps/web/src/components/poll/scheduled-event.tsx
  • apps/web/src/components/forms/poll-options-form/month-calendar/month-calendar.tsx
apps/web/src/app/**

📄 CodeRabbit inference engine (CLAUDE.md)

Use Next.js App Router conventions for route handlers

Files:

  • apps/web/src/app/[locale]/(auth)/layout.tsx
  • apps/web/src/app/[locale]/(space)/(dashboard)/components/upgrade-to-pro-alert.tsx
**/*.ts

📄 CodeRabbit inference engine (.cursorrules)

On the server use the getTranslations function from @/i18n/server to get the translations

Files:

  • apps/landing/next.config.ts
apps/web/src/components/**

📄 CodeRabbit inference engine (CLAUDE.md)

Place shared components in apps/web/src/components/

Files:

  • apps/web/src/components/poll/scheduled-event.tsx
  • apps/web/src/components/forms/poll-options-form/month-calendar/month-calendar.tsx
🧠 Learnings (13)
📓 Common learnings
Learnt from: CR
Repo: lukevella/rallly PR: 0
File: .cursorrules:0-0
Timestamp: 2025-11-25T11:03:55.173Z
Learning: Applies to **/*.{tsx,css,config.ts} : Use tailwindcss for styling
Learnt from: CR
Repo: lukevella/rallly PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T11:04:05.725Z
Learning: Applies to **/*.{tsx,ts} : Use TailwindCSS with custom design system for styling
📚 Learning: 2025-11-25T11:03:55.173Z
Learnt from: CR
Repo: lukevella/rallly PR: 0
File: .cursorrules:0-0
Timestamp: 2025-11-25T11:03:55.173Z
Learning: Applies to **/*.tsx : Use `cn()` from rallly/ui to compose classes

Applied to files:

  • packages/ui/src/page-tabs.tsx
  • apps/web/src/app/[locale]/(auth)/layout.tsx
  • packages/ui/src/sidebar.tsx
📚 Learning: 2025-11-25T11:03:55.173Z
Learnt from: CR
Repo: lukevella/rallly PR: 0
File: .cursorrules:0-0
Timestamp: 2025-11-25T11:03:55.173Z
Learning: Applies to packages/ui/**/*.tsx : shadcn-ui components should be added to packages/ui

Applied to files:

  • packages/ui/src/tabs.tsx
  • packages/ui/src/command.tsx
  • packages/tailwind-config/shared-styles.css
  • packages/ui/src/checkbox.tsx
  • packages/ui/src/sidebar.tsx
📚 Learning: 2025-11-25T11:03:55.173Z
Learnt from: CR
Repo: lukevella/rallly PR: 0
File: .cursorrules:0-0
Timestamp: 2025-11-25T11:03:55.173Z
Learning: Applies to **/*.tsx : DropdownMenuItem is a flex container with a preset gap so there is no need to add margins to the children

Applied to files:

  • apps/web/src/features/space/components/space-dropdown.tsx
  • packages/ui/src/sidebar.tsx
📚 Learning: 2025-11-25T11:03:55.173Z
Learnt from: CR
Repo: lukevella/rallly PR: 0
File: .cursorrules:0-0
Timestamp: 2025-11-25T11:03:55.173Z
Learning: Applies to **/*.tsx : Prefer composable components in the style of shadcn UI over large monolithic components

Applied to files:

  • packages/ui/src/switch.tsx
  • packages/ui/src/command.tsx
  • packages/tailwind-config/shared-styles.css
  • packages/ui/src/checkbox.tsx
  • packages/ui/src/sidebar.tsx
📚 Learning: 2025-09-12T21:37:47.353Z
Learnt from: lukevella
Repo: lukevella/rallly PR: 1951
File: packages/ui/src/dialog.tsx:23-25
Timestamp: 2025-09-12T21:37:47.353Z
Learning: React.ElementRef is deprecated and has been replaced by React.ComponentRef for TypeScript ref typing in React components, including Radix UI forwardRef components.

Applied to files:

  • packages/ui/src/switch.tsx
📚 Learning: 2025-11-25T11:03:55.173Z
Learnt from: CR
Repo: lukevella/rallly PR: 0
File: .cursorrules:0-0
Timestamp: 2025-11-25T11:03:55.173Z
Learning: Applies to **/*.{tsx,css,config.ts} : Use tailwindcss for styling

Applied to files:

  • apps/landing/package.json
  • apps/web/src/app/[locale]/(auth)/layout.tsx
  • packages/tailwind-config/shared-styles.css
  • apps/landing/postcss.config.mjs
  • packages/ui/src/checkbox.tsx
  • packages/ui/src/sidebar.tsx
  • packages/tailwind-config/package.json
📚 Learning: 2025-11-25T11:04:05.725Z
Learnt from: CR
Repo: lukevella/rallly PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T11:04:05.725Z
Learning: Applies to **/*.{tsx,ts} : Use TailwindCSS with custom design system for styling

Applied to files:

  • apps/landing/package.json
  • apps/web/src/app/[locale]/(auth)/layout.tsx
  • packages/tailwind-config/shared-styles.css
  • apps/landing/postcss.config.mjs
  • packages/ui/src/checkbox.tsx
  • packages/ui/src/sidebar.tsx
  • packages/tailwind-config/package.json
📚 Learning: 2025-11-25T11:04:05.725Z
Learnt from: CR
Repo: lukevella/rallly PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T11:04:05.725Z
Learning: Rallly is built with Next.js 15, React 19, tRPC, Prisma with PostgreSQL, NextAuth.js, TailwindCSS, and TypeScript throughout

Applied to files:

  • apps/landing/package.json
  • packages/tailwind-config/package.json
📚 Learning: 2025-11-25T11:04:05.725Z
Learnt from: CR
Repo: lukevella/rallly PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T11:04:05.725Z
Learning: Applies to **/*.{ts,tsx,js,jsx} : Use Biome for code formatting with indent of 2 spaces and double quotes

Applied to files:

  • packages/ui/src/command.tsx
📚 Learning: 2025-11-25T11:03:55.173Z
Learnt from: CR
Repo: lukevella/rallly PR: 0
File: .cursorrules:0-0
Timestamp: 2025-11-25T11:03:55.173Z
Learning: Applies to **/*.tsx : The size and colour of an icon should be set by wrapping it with the <Icon> component from rallly/ui/icon which will give it the correct colour and size

Applied to files:

  • packages/tailwind-config/shared-styles.css
  • packages/ui/src/sidebar.tsx
📚 Learning: 2025-11-25T11:04:05.725Z
Learnt from: CR
Repo: lukevella/rallly PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T11:04:05.725Z
Learning: Applies to apps/web/src/app/** : Use Next.js App Router conventions for route handlers

Applied to files:

  • apps/landing/next.config.ts
📚 Learning: 2025-11-25T11:03:55.173Z
Learnt from: CR
Repo: lukevella/rallly PR: 0
File: .cursorrules:0-0
Timestamp: 2025-11-25T11:03:55.173Z
Learning: Applies to **/*.{ts,tsx} : Create separate import statements for types

Applied to files:

  • apps/landing/next.config.ts
🧬 Code graph analysis (1)
apps/landing/postcss.config.mjs (1)
packages/tailwind-config/postcss.config.mjs (2)
  • postcssConfig (2-6)
  • postcssConfig (2-6)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Integration tests
🔇 Additional comments (26)
apps/web/src/app/[locale]/(space)/(dashboard)/components/upgrade-to-pro-alert.tsx (1)

11-11: Tailwind v4 shadow-xs swap looks safe. This is a purely visual change and should align with the broader v4 migration.

apps/web/src/components/poll/scheduled-event.tsx (1)

71-74: Looks good; verify shadow-xs is available in your Tailwind v4 theme output.

If shadows are customized via your shared tokens/theme, make sure shadow-xs compiles and matches the intended visual.

apps/web/src/features/space/components/space-dropdown.tsx (1)

82-82: LGTM! Correct Tailwind v4 CSS variable syntax.

The change correctly migrates the CSS variable syntax from Tailwind v3 (min-w-[var(--...)]) to Tailwind v4 (min-w-(--...)). The var() wrapper is no longer needed and parentheses replace square brackets for arbitrary CSS variable values.

apps/web/src/app/[locale]/(auth)/layout.tsx (1)

37-37: LGTM! Correct Tailwind v4 arbitrary value syntax.

The change from arbitrary CSS property syntax [mask-image:radial-gradient(...)] to the standard arbitrary value syntax mask-[radial-gradient(...)] is the correct approach for Tailwind v4. This aligns with Tailwind's conventions for applying arbitrary values to utilities.

apps/web/.cursor/rules/better-auth.md (1)

24706-24706: Replace invalid variant "outline-solid" with a valid Button variant.

The Button component does not support variant="outline-solid". Valid variants are: primary, destructive, default, secondary, ghost, actionBar, and link.

For the outlined appearance shown in these examples, use variant="ghost" or variant="secondary" instead at lines 24706, 24720, and 24733.

packages/ui/src/checkbox.tsx (1)

16-19: Tailwind v4 focus outline migration looks correct (outline-hidden). Keeps the focus affordance via focus-visible:ring-1, so accessibility shouldn’t regress.

packages/ui/src/popover.tsx (1)

22-25: PopoverContent outline-none -> outline-hidden is a safe Tailwind v4 alignment. No behavior impact expected.

packages/ui/src/command.tsx (5)

39-41: Selector/class updates on CommandDialog look consistent with Tailwind v4 + cmdk patterns. No functional impact expected.


60-63: CommandInput outline-hidden migration is consistent with the rest of the UI kit.


103-106: CommandGroup selector updates look fine; keeps styling localized to cmdk attributes.


131-134: CommandItem focus outline change is fine (outline-hidden).


147-150: CommandItemShortcut focus outline change is fine (outline-hidden).

packages/ui/src/toast.tsx (4)

18-18: Correct Tailwind v4 migration for z-index.

The change from z-[100] to z-100 correctly applies Tailwind v4's dynamic utility value syntax.


27-27: Correct Tailwind v4 CSS variable syntax migration.

The changes from translate-x-[--radix-toast-swipe-*-x] to translate-x-(--radix-toast-swipe-*-x) correctly implement Tailwind v4's breaking change requiring parentheses for CSS variables instead of brackets.


64-64: Correct Tailwind v4 outline utility migration.

The change from focus:outline-none to focus:outline-hidden correctly implements Tailwind v4's breaking change where outline-none now only removes outline style, and outline-hidden must be used to completely remove the outline.


79-79: Correct Tailwind v4 outline utility migration.

The change from focus:outline-none to focus:outline-hidden correctly implements Tailwind v4's breaking change, consistent with the ToastAction component.

apps/web/src/components/forms/poll-options-form/month-calendar/month-calendar.tsx (2)

177-177: LGTM: More explicit focus rounding.

The change from focus:rounded to focus:rounded-sm makes the border radius size more explicit, improving code clarity.


190-192: LGTM: Z-index cleanup.

The change from -z-0 to z-0 removes a redundant negative sign (since negative zero equals zero). The shadow-xs change is consistent with line 125 and covered in the previous verification request.

apps/landing/next.config.ts (1)

74-76: Redirect destination fix for /profile looks correct
Passing an explicit subpath to createAppUrl("/profile") is clearer/safer than relying on an implicit default.

apps/landing/postcss.config.mjs (1)

1-3: Clean re-export of shared PostCSS config
Keeps PostCSS config centralized and avoids drift across apps.

packages/ui/src/button.tsx (1)

21-21: LGTM! Shadow utility correctly updated for Tailwind v4.

The migration from shadow-sm to shadow-2xs aligns with Tailwind v4's refined shadow scale, maintaining consistent visual depth across the design system.

packages/ui/src/sidebar.tsx (5)

176-176: CSS variable syntax correctly migrated to Tailwind v4.

The migration from bracket syntax w-[--sidebar-width] to parentheses syntax w-(--sidebar-width) is correct per Tailwind v4 requirements. All CSS variable references have been consistently updated throughout the component.

Also applies to: 193-193, 223-223, 228-228, 233-233, 240-240, 673-673


513-513: Important modifier syntax correctly updated for Tailwind v4.

The important modifier placement has been correctly migrated from prefix (!size-8) to suffix (size-8!) as required by Tailwind v4.

Also applies to: 527-527


440-440: Outline utilities correctly migrated to Tailwind v4.

The migration from outline-none to outline-hidden is correct. In Tailwind v4, outline-none only removes the outline style, while outline-hidden removes the outline completely.

Also applies to: 461-461, 610-610, 726-726


136-136: Data attribute selectors correctly migrated to Tailwind v4.

The migration to new data attribute selector syntax is correct:

  • has-data-[variant=inset] for parent selectors
  • in-data-[side=left] for ancestor state targeting
  • peer-data-[...] for peer relationships

All align with Tailwind v4's enhanced data attribute handling.

Also applies to: 302-302, 324-324


247-247: Shadow utility correctly updated for Tailwind v4.

The shadow-xs utility aligns with Tailwind v4's refined shadow scale, maintaining consistent visual depth for the floating sidebar variant.

Comment on lines +1 to 7
import type { NextConfig } from "next";

import createBundleAnalyzer from "@next/bundle-analyzer";

const withBundleAnalyzer = createBundleAnalyzer({
enabled: process.env.ANALYZE === "true",
});
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

git ls-files apps/landing/next.config.ts

Repository: lukevella/rallly

Length of output: 176


🏁 Script executed:

cat -n apps/landing/next.config.ts

Repository: lukevella/rallly

Length of output: 3765


🌐 Web query:

Next.js 15 next.config.ts module.exports vs export default ESM imports

💡 Result:

Short answer: use export default in next.config.ts for TypeScript configs (Next.js treats next.config.ts as ESM-capable but module resolution is currently limited to CommonJS), and use module.exports in next.config.js when you want CommonJS. If you need full ESM behavior (top‑level await, importing ESM‑only packages) prefer next.config.mjs / next.config.mts or an ESM project ("type":"module") — Node’s native TypeScript resolver (Node v22.10+ / enabled by default v22.18+) can make next.config.ts behave as ESM, but Next.js does not enable that feature for you by default. [1][2][3]

Key points and recommendations

  • next.config.js (CommonJS): show examples using module.exports. Use this for the default CommonJS workflow. [4]
  • next.config.ts: Next.js examples use export default and typed NextConfig, but module resolution in next.config.ts is limited to CommonJS and can break ESM‑only packages. [1][2][3]
  • For explicit ESM: use next.config.mjs / next.config.mts or set "type":"module" in package.json; Node’s native TS resolver can allow ESM syntax in .ts when available/opted-in. [1][4]
  • If you run into import errors for ESM-only packages from next.config.ts, switch to next.config.mts/.mjs or change project/module type. [1][3]

Sources: Next.js docs on TypeScript/next.config and next.config.js examples. [1][2][4]

References

  1. Next.js — TypeScript / next.config.ts (docs). [1]
  2. Next.js — TypeScript (config) (mirror). [2]
  3. Next.js — TypeScript examples (docs). [3]
  4. Next.js — next.config.js / .mjs (docs). [4]

Replace module.exports with export default for consistency with ESM imports in next.config.ts

The file uses ESM import statements (lines 1, 3) but exports using CommonJS module.exports (line 119). For next.config.ts, Next.js documentation recommends using export default with typed configuration.

 import type { NextConfig } from "next";

 import createBundleAnalyzer from "@next/bundle-analyzer";

 const withBundleAnalyzer = createBundleAnalyzer({
   enabled: process.env.ANALYZE === "true",
 });

@@
-// Make sure adding Sentry options is the last code to run before exporting, to
-// ensure that your source maps include changes from all other Webpack plugins
-module.exports = withBundleAnalyzer(nextConfig);
+export default withBundleAnalyzer(nextConfig);

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In apps/landing/next.config.ts around lines 1 to 119, the file mixes ESM imports
with a CommonJS export at the end; replace the CommonJS module.exports with an
ESM default export: define your NextConfig object (typed as NextConfig) as
before, wrap it with withBundleAnalyzer if needed, then export it using export
default nextConfig (or export default withBundleAnalyzer(nextConfig)); remove
module.exports entirely and ensure the exported value is the typed config.

Comment on lines 9 to 14
const appBaseUrl = process.env.NEXT_PUBLIC_APP_BASE_URL;

function createAppUrl(subpath) {
function createAppUrl(subpath: string) {
const url = new URL(subpath, appBaseUrl);
return url.href;
}
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Fail fast if NEXT_PUBLIC_APP_BASE_URL is missing/invalid to avoid build-time URL crashes
new URL(subpath, appBaseUrl) will throw if appBaseUrl is undefined (Line 12).

 const appBaseUrl = process.env.NEXT_PUBLIC_APP_BASE_URL;

 function createAppUrl(subpath: string) {
+  if (!appBaseUrl) {
+    throw new Error("Missing NEXT_PUBLIC_APP_BASE_URL (required for redirects)");
+  }
   const url = new URL(subpath, appBaseUrl);
   return url.href;
 }
🤖 Prompt for AI Agents
In apps/landing/next.config.ts around lines 9 to 14, the function createAppUrl
calls new URL(subpath, appBaseUrl) but appBaseUrl may be undefined/invalid which
will throw at build time; fix by validating NEXT_PUBLIC_APP_BASE_URL at module
load: read process.env.NEXT_PUBLIC_APP_BASE_URL into a const, if falsy throw a
clear Error (or call process.exit(1)) with a message identifying the missing
env; additionally attempt to construct new URL(appBaseUrl) inside a try/catch to
ensure it is a valid base URL and throw a descriptive Error if invalid, then use
the validated base when creating URLs in createAppUrl.

Comment on lines +40 to +41
"react-use": "^17.6.0",
"tailwindcss": "^4.1.18"
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

# Check the current package.json structure in apps/landing
cat apps/landing/package.json | head -100

Repository: lukevella/rallly

Length of output: 1737


🏁 Script executed:

# Check if there's a postcss config
fd -e postcss.config -e postcss.config.js -e postcss.config.ts apps/landing

Repository: lukevella/rallly

Length of output: 413


🏁 Script executed:

# Check for tailwind config
fd -e tailwind.config -e tailwind.config.js -e tailwind.config.ts apps/landing

Repository: lukevella/rallly

Length of output: 413


🌐 Web query:

Next.js Tailwind CSS dependency vs devDependency best practices monorepo

💡 Result:

Short answer

  • Put Tailwind (tailwindcss + PostCSS/autoprefixer/plugins) in devDependencies of whichever package actually runs the build (usually each Next.js app or the monorepo root build workspace). That’s the common, recommended approach because Tailwind is a build-time tool. [1][4][6]

Best-practice checklist for monorepos

  1. Install Tailwind where builds run
    • If each app builds separately, add Tailwind as a devDependency in each app’s package.json (or in the root if you run a single root build step). This ensures the build process can find the tool. [1][2]
  2. Share config, not runtime package
    • Put shared tailwind.config (or a shared package exporting config) in a workspace (packages/tailwind-config) and reference it from apps. Use workspace: protocol so installs link it. This keeps Tailwind config centralized while still treating tailwind itself as a devDependency. [2][8]
  3. If you package a UI library
    • Option A: Ship compiled CSS from the UI package (so apps only consume CSS). The UI package’s build should have tailwind in its devDependencies. Consumers then don’t need tailwind at runtime.
    • Option B: Export source classes from the UI package and ensure apps that consume it run Tailwind in their build (tailwind must see those source paths via content/@source). Either way, Tailwind is a build-time concern. [3][6]
  4. Tooling and CI/CD
    • Ensure CI/build systems install devDependencies (most builders do) or install with --include=dev / NODE_ENV not set to production so tailwind is available during build. If your build environment strips devDependencies, move tailwind to the package where the build runs or ensure CI installs dev deps. (Common failure: “Cannot find module 'tailwindcss'” during Next build when tailwind isn’t available to the builder.) [4][3]
  5. Tailwind v4 notes
    • Tailwind v4 introduces CSS-first/automatic source detection and changes to config usage; in monorepos you may need to explicitly add @source/@config or ensure PostCSS setup is correct in the package that builds. Test dev + production builds after upgrading. [6]

Practical patterns

  • Per-app builds: tailwind as devDep in each app + shared tailwind-config package for central rules. [2][8]
  • Single-build root: tailwind as a root devDependency and apps reference shared config/content; make sure content paths include workspace packages. [2][6]
  • UI library that ships CSS: tailwind as devDep in the library package (build-time only); consumers import the built CSS. [3]

If you want, tell me your repo layout (npm/pnpm/yarn, turborepo/turbo, where builds run) and I’ll give an exact package.json + workspace setup example and the minimal install commands.

Sources
[1] pnpm workspaces docs — workspace linking and where to put packages.
[2] Stack Overflow / community answers on Tailwind in monorepos (sharing config, content paths, build-time use).
[3] Turborepo / Vercel monorepo examples (showing shared UI and Tailwind setups).
[4] Next.js GitHub discussion: missing tailwind in build — devDependency vs build environment issues.
[6] Tailwind v4 monorepo guidance (CSS-first, @source/@config changes).


Move tailwindcss to devDependencies
tailwindcss is a build-time tool used only during Next.js builds via PostCSS. The shared @rallly/tailwind-config workspace package can remain in dependencies, but tailwindcss itself should be in devDependencies.

🤖 Prompt for AI Agents
In apps/landing/package.json around lines 40 to 41, tailwindcss is listed under
dependencies but it is a build-time tool and should be moved to devDependencies;
remove the "tailwindcss": "^4.1.18" entry from dependencies and add the same
entry under devDependencies (keeping the version), then run the workspace
package manager (yarn/npm pnpm) install to update the lockfile so the change is
reflected.

variant === "floating" || variant === "inset"
? "group-data-[collapsible=icon]:w-[calc(var(--sidebar-width-icon)_+_theme(spacing.4))]"
: "group-data-[collapsible=icon]:w-[--sidebar-width-icon]",
? "group-data-[collapsible=icon]:w-[calc(var(--sidebar-width-icon)+(--spacing(4)))]"
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🌐 Web query:

Tailwind CSS v4 calc() arbitrary values CSS variables token syntax

💡 Result:

Short answer: In Tailwind v4 you can use calc() inside arbitrary values but you must provide a valid CSS value (use var() to reference CSS variables) and remove or replace spaces (underscores) inside the bracket. Examples:

  • Using a CSS variable inside calc:

    • w-[calc(100%_-_var(--spacing-my-custom-height-2))]. [1][2]
  • Short-hand for direct CSS-var value (no calc):

    • fill-(--my-brand-color) → expands to fill: var(--my-brand-color). [3]

Notes:

  • The value inside [] must be valid CSS as-is (so use var(--...) to reference Tailwind theme tokens exposed as CSS variables). [2]
  • You can remove spaces or replace them with underscores when using calc(), min(), etc., because class-names cannot contain spaces. [1][3]

Sources: [1] Cruip “How to Use calc() in Tailwind CSS”; [2] Stack Overflow discussion on custom spacing + calc() (Tailwind v4); [3] Tailwind v4 syntax gist (arbitrary value / CSS-variable shorthand).


🏁 Script executed:

# Check the actual file to see the context and line numbers
fd sidebar.tsx packages/ui/src

Repository: lukevella/rallly

Length of output: 87


🏁 Script executed:

# Look at lines around 227 and 239 to understand context
cat -n packages/ui/src/sidebar.tsx | sed -n '220,245p'

Repository: lukevella/rallly

Length of output: 1653


🏁 Script executed:

# Search for CSS variable definitions or spacing references
rg "spacing" packages/ui/src/sidebar.tsx

Repository: lukevella/rallly

Length of output: 265


🏁 Script executed:

# Look for CSS files related to sidebar
fd -e css -e scss -e postcss sidebar packages/ui/src/

Repository: lukevella/rallly

Length of output: 42


🏁 Script executed:

# Search for --spacing definitions in the entire packages/ui directory
rg "\\-\\-spacing" packages/ui/src/

Repository: lukevella/rallly

Length of output: 578


🏁 Script executed:

# Check if there's a Tailwind config that might define these tokens
fd tailwind.config packages/

Repository: lukevella/rallly

Length of output: 116


🏁 Script executed:

# Check the tailwind config
cat packages/ui/tailwind.config.js

Repository: lukevella/rallly

Length of output: 128


🏁 Script executed:

# Also check if there's a main tailwind config
cat packages/tailwind-config/tailwind.config.js 2>/dev/null || echo "Not found"

Repository: lukevella/rallly

Length of output: 69


🏁 Script executed:

# Search for how spacing is used elsewhere in the codebase
rg "var\\(--spacing" packages/ui/src/ | head -20

Repository: lukevella/rallly

Length of output: 316


🏁 Script executed:

# Find the tailwind config package
fd tailwind.config packages/tailwind-config/

Repository: lukevella/rallly

Length of output: 42


🏁 Script executed:

# List the packages directory structure
ls -la packages/ | grep -E "^d"

Repository: lukevella/rallly

Length of output: 734


🏁 Script executed:

# List all files in the tailwind-config package
ls -la packages/tailwind-config/

Repository: lukevella/rallly

Length of output: 373


🏁 Script executed:

# Look for any config or index files
fd . packages/tailwind-config/

Repository: lukevella/rallly

Length of output: 184


🏁 Script executed:

# Check the tailwind-config package.json
cat packages/tailwind-config/package.json

Repository: lukevella/rallly

Length of output: 504


🏁 Script executed:

# Check the shared styles CSS file for variable definitions
cat packages/tailwind-config/shared-styles.css

Repository: lukevella/rallly

Length of output: 4167


Fix invalid calc() syntax: use var(--spacing) instead of (--spacing(4)).

The syntax (--spacing(4)) is not valid CSS or Tailwind v4. The --spacing variable is defined as a CSS custom property (0.25rem), so it should be referenced with var(). Use var(--spacing) * 4 to multiply the spacing value by 4, or reference it directly with var(--spacing) as shown in alert.tsx.

Also applies to: 239-239

🤖 Prompt for AI Agents
In packages/ui/src/sidebar.tsx around lines 227 and 239, the class string uses
an invalid calc() token "(--spacing(4))"; replace it with a valid var()
expression such as "calc(var(--spacing) * 4)" or "var(--spacing)" as appropriate
so the Tailwind/CSS calc is valid (e.g., change
group-data-[collapsible=icon]:w-[calc(var(--sidebar-width-icon)+(--spacing(4)))]
to use calc(var(--sidebar-width-icon) + calc(var(--spacing) * 4)) or the simpler
equivalent used in alert.tsx).

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.

2 participants