-
-
Notifications
You must be signed in to change notification settings - Fork 480
⬆️ Upgrade to Tailwind 4 #2069
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
⬆️ Upgrade to Tailwind 4 #2069
Conversation
WalkthroughThis 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
Estimated code review effort🎯 4 (Complex) | ⏱️ ~70 minutes
Possibly related PRs
Poem
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✨ Finishing touches🧪 Generate unit tests (beta)
📜 Recent review detailsConfiguration used: CodeRabbit UI Review profile: CHILL Plan: Pro 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
⏰ 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)
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. Comment |
There was a problem hiding this 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:discountprop is declared but never rendered
BillingPlanPriceaccepts adiscountprop, 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
discountinto the markup (e.g. showing a struck-through old price or a “Save X%” label), or- Removing the
discountprop 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 againsttotal === 0to avoid invalid progress widthsThe switch to
rounded-smon the container is a harmless visual tweak.However, the width calculations:
width: `${(props.yes.length / props.total) * 100}%`; // ... same pattern for ifNeedBe and nowill yield
NaN%/Infinity%ifprops.totalis0, which results in invalid CSS and unpredictable bar rendering.Consider normalizing
totalbefore 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
totalhappens to be0.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 be0. This looks like it was meant to be the minutes betweenstartDateandendDate.Consider:
- duration: dayjs(endDate).diff(endDate, "minutes"), + duration: dayjs(endDate).diff(startDate, "minutes"),so
durationcorrectly 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 complaintThe 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 causebiome checkto 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 filesAdding
"type": "module"changes how.jsfiles are parsed. Found CommonJS in config files that will break:
apps/landing/i18next-scanner.config.jsusesrequire()andmodule.exports– convert to ESM syntaxapps/landing/next.config.tsusesmodule.exports– verify Next.js handles this correctly with ESM mode, or migrate to ESM syntaxpackages/ui/src/sidebar.tsx (1)
513-528: Sort classes insidebarMenuButtonVariantsto satisfy BiomeBiome is flagging the base class string and the
size.lgvariant insidebarMenuButtonVariantsfor 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-2xsutility and opacity slash syntax (bg-destructive/90) are correct for Tailwind v4.However, the destructive variant has
focus-visible:ring-offset-1without an actual ring, which means keyboard users won't see a visible focus indicator. Theprimaryvariant (line 19) correctly includes bothring-2andring-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
defaultandsecondaryvariants (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 wrappingCheckCircle2Iconwith<Icon>from@rallly/ui/iconGuidelines say icon size/colour should be controlled via the shared
<Icon>component rather than per‑icon Tailwind classes. HereCheckCircle2Iconis styled directly withclassName.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 BiomeThe 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 copyThe update from
shadow-smtoshadow-xson 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 oruseTranslation), consider refactoring this component to use<Trans>from@/components/transwithdefaultsstrings 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 laterThe change from
shadow-smtoshadow-xson 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 migrationThe base-layer compatibility rule restoring the pre-v4 border color default, plus the
text-linkandbg-diagonal-linesutilities and the globalbody/htmlstyles, provide a coherent, token-driven base for all apps. As a small optional improvement, you could swap the hard-coded grays inbg-diagonal-linesfor 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
⛔ Files ignored due to path filters (1)
pnpm-lock.yamlis 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, runpnpm i18n:scaninstead of manually adding keys
Files:
apps/web/src/components/maintenance.tsxpackages/ui/src/button.tsxapps/web/src/components/poll/scheduled-event.tsxapps/web/src/components/skeleton.tsxapps/web/src/components/vote-summary-progress-bar.tsxapps/landing/src/app/[locale]/licensing/thank-you/page.tsxpackages/ui/src/tabs.tsxapps/web/src/components/new-participant-modal.tsxpackages/ui/src/breadcrumb.tsxapps/landing/src/app/[locale]/(main)/pricing/page.tsxpackages/ui/src/tooltip.tsxapps/web/src/app/[locale]/layout.tsxpackages/ui/src/sheet.tsxapps/web/src/components/forms/poll-options-form/week-calendar.tsxpackages/ui/src/textarea.tsxapps/web/src/components/time-zone-picker/time-zone-select.tsxpackages/ui/src/popover.tsxpackages/ui/src/switch.tsxapps/web/src/app/[locale]/(space)/(dashboard)/components/upgrade-to-pro-alert.tsxapps/web/src/components/discussion/discussion.tsxapps/web/src/features/billing/components/pay-wall-dialog.tsxpackages/ui/src/dropdown-menu.tsxpackages/ui/src/command.tsxapps/landing/src/app/[locale]/layout.tsxpackages/ui/src/alert.tsxpackages/ui/src/checkbox.tsxpackages/ui/src/toast.tsxpackages/ui/src/sidebar.tsxpackages/ui/src/select.tsxpackages/ui/src/billing-plan.tsxapps/web/src/components/forms/poll-options-form/month-calendar/month-calendar.tsxpackages/ui/src/progress.tsxapps/web/src/components/cookie-consent.tsxapps/web/src/app/[locale]/(space)/settings/layout.tsxpackages/ui/src/card.tsxpackages/ui/src/separator.tsxapps/web/src/components/full-width-layout.tsxapps/web/src/app/[locale]/(space)/(dashboard)/components/nav-user.tsxapps/web/src/components/empty-state.tsxapps/landing/next.config.tsapps/web/src/app/[locale]/(auth)/layout.tsxapps/web/src/features/space/components/space-dropdown.tsxapps/landing/src/components/home/bonus-item.tsxapps/web/src/components/poll/desktop-poll.tsxpackages/ui/src/page-tabs.tsxapps/web/src/app/components/page-layout.tsxpackages/ui/src/table.tsxpackages/ui/src/badge.tsxapps/web/src/app/[locale]/accept-invite/[inviteId]/page.tsxapps/landing/src/app/[locale]/(main)/layout.tsxapps/web/src/components/description-list.tsxapps/web/next.config.tspackages/ui/src/avatar.tsxpackages/ui/src/radio-group.tsx
**/*.{tsx,css,config.ts}
📄 CodeRabbit inference engine (.cursorrules)
Use tailwindcss for styling
Files:
apps/web/src/components/maintenance.tsxpackages/ui/src/button.tsxapps/web/src/components/poll/scheduled-event.tsxapps/web/src/components/skeleton.tsxapps/web/src/components/vote-summary-progress-bar.tsxapps/landing/src/app/[locale]/licensing/thank-you/page.tsxpackages/ui/src/tabs.tsxapps/web/src/components/new-participant-modal.tsxpackages/ui/src/breadcrumb.tsxapps/landing/src/app/[locale]/(main)/pricing/page.tsxpackages/tailwind-config/shared-styles.csspackages/ui/src/tooltip.tsxapps/web/src/app/[locale]/layout.tsxapps/web/src/app/[locale]/globals.csspackages/ui/src/sheet.tsxapps/web/src/components/forms/poll-options-form/week-calendar.tsxpackages/ui/src/textarea.tsxapps/web/src/components/time-zone-picker/time-zone-select.tsxpackages/ui/src/popover.tsxpackages/ui/src/switch.tsxapps/web/src/app/[locale]/(space)/(dashboard)/components/upgrade-to-pro-alert.tsxapps/web/src/components/discussion/discussion.tsxapps/web/src/features/billing/components/pay-wall-dialog.tsxpackages/ui/src/dropdown-menu.tsxapps/landing/src/app/[locale]/globals.csspackages/ui/src/command.tsxapps/landing/src/app/[locale]/layout.tsxpackages/ui/src/alert.tsxpackages/ui/src/checkbox.tsxpackages/ui/src/toast.tsxpackages/ui/src/sidebar.tsxpackages/ui/src/select.tsxpackages/ui/src/billing-plan.tsxapps/web/src/globals.cssapps/web/src/components/forms/poll-options-form/month-calendar/month-calendar.tsxpackages/ui/src/progress.tsxapps/web/src/components/cookie-consent.tsxapps/web/src/app/[locale]/(space)/settings/layout.tsxpackages/ui/src/card.tsxpackages/ui/src/separator.tsxapps/web/src/components/full-width-layout.tsxapps/web/src/app/[locale]/(space)/(dashboard)/components/nav-user.tsxapps/web/src/components/empty-state.tsxapps/landing/next.config.tsapps/web/src/app/[locale]/(auth)/layout.tsxapps/web/src/features/space/components/space-dropdown.tsxapps/landing/src/components/home/bonus-item.tsxapps/web/src/components/poll/desktop-poll.tsxpackages/ui/src/page-tabs.tsxapps/web/src/app/components/page-layout.tsxpackages/ui/src/table.tsxpackages/ui/src/badge.tsxapps/web/src/app/[locale]/accept-invite/[inviteId]/page.tsxapps/landing/src/app/[locale]/(main)/layout.tsxapps/web/src/components/description-list.tsxapps/web/next.config.tspackages/ui/src/avatar.tsxpackages/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 thedefaultsprop to provide the default text
Always use a composable patterns when building components
Usecn()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.tsxpackages/ui/src/button.tsxapps/web/src/components/poll/scheduled-event.tsxapps/web/src/components/skeleton.tsxapps/web/src/components/vote-summary-progress-bar.tsxapps/landing/src/app/[locale]/licensing/thank-you/page.tsxpackages/ui/src/tabs.tsxapps/web/src/components/new-participant-modal.tsxpackages/ui/src/breadcrumb.tsxapps/landing/src/app/[locale]/(main)/pricing/page.tsxpackages/ui/src/tooltip.tsxapps/web/src/app/[locale]/layout.tsxpackages/ui/src/sheet.tsxapps/web/src/components/forms/poll-options-form/week-calendar.tsxpackages/ui/src/textarea.tsxapps/web/src/components/time-zone-picker/time-zone-select.tsxpackages/ui/src/popover.tsxpackages/ui/src/switch.tsxapps/web/src/app/[locale]/(space)/(dashboard)/components/upgrade-to-pro-alert.tsxapps/web/src/components/discussion/discussion.tsxapps/web/src/features/billing/components/pay-wall-dialog.tsxpackages/ui/src/dropdown-menu.tsxpackages/ui/src/command.tsxapps/landing/src/app/[locale]/layout.tsxpackages/ui/src/alert.tsxpackages/ui/src/checkbox.tsxpackages/ui/src/toast.tsxpackages/ui/src/sidebar.tsxpackages/ui/src/select.tsxpackages/ui/src/billing-plan.tsxapps/web/src/components/forms/poll-options-form/month-calendar/month-calendar.tsxpackages/ui/src/progress.tsxapps/web/src/components/cookie-consent.tsxapps/web/src/app/[locale]/(space)/settings/layout.tsxpackages/ui/src/card.tsxpackages/ui/src/separator.tsxapps/web/src/components/full-width-layout.tsxapps/web/src/app/[locale]/(space)/(dashboard)/components/nav-user.tsxapps/web/src/components/empty-state.tsxapps/web/src/app/[locale]/(auth)/layout.tsxapps/web/src/features/space/components/space-dropdown.tsxapps/landing/src/components/home/bonus-item.tsxapps/web/src/components/poll/desktop-poll.tsxpackages/ui/src/page-tabs.tsxapps/web/src/app/components/page-layout.tsxpackages/ui/src/table.tsxpackages/ui/src/badge.tsxapps/web/src/app/[locale]/accept-invite/[inviteId]/page.tsxapps/landing/src/app/[locale]/(main)/layout.tsxapps/web/src/components/description-list.tsxpackages/ui/src/avatar.tsxpackages/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.tsxpackages/ui/src/button.tsxapps/web/src/components/poll/scheduled-event.tsxapps/web/src/components/skeleton.tsxapps/web/src/components/vote-summary-progress-bar.tsxapps/landing/src/app/[locale]/licensing/thank-you/page.tsxpackages/ui/src/tabs.tsxapps/web/src/components/new-participant-modal.tsxpackages/ui/src/breadcrumb.tsxapps/landing/src/app/[locale]/(main)/pricing/page.tsxpackages/ui/src/tooltip.tsxapps/web/src/app/[locale]/layout.tsxapps/landing/package.jsonpackages/ui/src/sheet.tsxapps/web/src/components/forms/poll-options-form/week-calendar.tsxpackages/ui/src/textarea.tsxapps/web/src/components/time-zone-picker/time-zone-select.tsxpackages/ui/src/popover.tsxpackages/ui/src/switch.tsxapps/web/src/app/[locale]/(space)/(dashboard)/components/upgrade-to-pro-alert.tsxapps/web/src/components/discussion/discussion.tsxapps/web/src/features/billing/components/pay-wall-dialog.tsxpackages/ui/src/dropdown-menu.tsxpackages/ui/src/command.tsxapps/landing/src/app/[locale]/layout.tsxpackages/ui/src/alert.tsxpackages/ui/src/checkbox.tsxpackages/ui/src/toast.tsxpackages/ui/src/sidebar.tsxpackages/tailwind-config/package.jsonpackages/ui/src/select.tsxpackages/ui/src/billing-plan.tsxapps/web/src/components/forms/poll-options-form/month-calendar/month-calendar.tsxpackages/ui/src/progress.tsxapps/web/src/components/cookie-consent.tsxapps/web/src/app/[locale]/(space)/settings/layout.tsxpackages/ui/src/card.tsxpackages/ui/package.jsonpackages/ui/src/separator.tsxapps/web/src/components/full-width-layout.tsxapps/web/src/app/[locale]/(space)/(dashboard)/components/nav-user.tsxapps/web/src/components/empty-state.tsxapps/landing/next.config.tsapps/web/src/app/[locale]/(auth)/layout.tsxapps/web/src/features/space/components/space-dropdown.tsxapps/landing/src/components/home/bonus-item.tsxapps/web/src/components/poll/desktop-poll.tsxapps/web/package.jsonpackages/ui/src/page-tabs.tsxapps/web/src/app/components/page-layout.tsxpackages/ui/src/table.tsxpackages/ui/src/badge.tsxapps/web/src/app/[locale]/accept-invite/[inviteId]/page.tsxapps/landing/src/app/[locale]/(main)/layout.tsxapps/web/src/components/description-list.tsxapps/web/next.config.tspackages/ui/src/avatar.tsxpackages/ui/src/radio-group.tsx
**/*
📄 CodeRabbit inference engine (.cursorrules)
Always use kebab-case for file names
Files:
apps/web/src/components/maintenance.tsxpackages/ui/src/button.tsxapps/web/src/components/poll/scheduled-event.tsxapps/web/src/components/skeleton.tsxapps/web/src/components/vote-summary-progress-bar.tsxapps/landing/src/app/[locale]/licensing/thank-you/page.tsxpackages/ui/src/tabs.tsxapps/web/src/components/new-participant-modal.tsxpackages/ui/src/breadcrumb.tsxapps/landing/src/app/[locale]/(main)/pricing/page.tsxpackages/tailwind-config/shared-styles.csspackages/ui/src/tooltip.tsxapps/web/src/app/[locale]/layout.tsxapps/web/src/app/[locale]/globals.cssapps/landing/package.jsonpackages/ui/src/sheet.tsxapps/web/src/components/forms/poll-options-form/week-calendar.tsxpackages/ui/src/textarea.tsxapps/web/src/components/time-zone-picker/time-zone-select.tsxpackages/ui/src/popover.tsxpackages/ui/src/switch.tsxapps/web/src/app/[locale]/(space)/(dashboard)/components/upgrade-to-pro-alert.tsxapps/web/src/components/discussion/discussion.tsxapps/web/src/features/billing/components/pay-wall-dialog.tsxpackages/ui/src/dropdown-menu.tsxapps/landing/src/app/[locale]/globals.csspackages/ui/src/command.tsxapps/landing/src/app/[locale]/layout.tsxpackages/ui/src/alert.tsxpackages/ui/src/checkbox.tsxpackages/ui/src/toast.tsxpackages/ui/src/sidebar.tsxpackages/tailwind-config/package.jsonpackages/ui/src/select.tsxpackages/ui/src/billing-plan.tsxapps/web/src/globals.cssapps/web/src/components/forms/poll-options-form/month-calendar/month-calendar.tsxpackages/ui/src/progress.tsxapps/web/src/components/cookie-consent.tsxapps/web/src/app/[locale]/(space)/settings/layout.tsxpackages/ui/src/card.tsxapps/landing/postcss.config.jspackages/ui/package.jsonpackages/ui/src/separator.tsxapps/web/src/components/full-width-layout.tsxapps/web/src/app/[locale]/(space)/(dashboard)/components/nav-user.tsxapps/web/src/components/empty-state.tsxapps/landing/next.config.tsapps/web/src/app/[locale]/(auth)/layout.tsxapps/web/src/features/space/components/space-dropdown.tsxapps/landing/src/components/home/bonus-item.tsxapps/web/src/components/poll/desktop-poll.tsxapps/web/package.jsonapps/web/postcss.config.jspackages/ui/src/page-tabs.tsxapps/web/src/app/components/page-layout.tsxpackages/ui/src/table.tsxpackages/ui/src/badge.tsxapps/web/src/app/[locale]/accept-invite/[inviteId]/page.tsxapps/landing/src/app/[locale]/(main)/layout.tsxapps/web/src/components/description-list.tsxapps/web/next.config.tspackages/ui/src/avatar.tsxpackages/tailwind-config/postcss.config.jspackages/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.tsxpackages/ui/src/button.tsxapps/web/src/components/poll/scheduled-event.tsxapps/web/src/components/skeleton.tsxapps/web/src/components/vote-summary-progress-bar.tsxapps/landing/src/app/[locale]/licensing/thank-you/page.tsxpackages/ui/src/tabs.tsxapps/web/src/components/new-participant-modal.tsxpackages/ui/src/breadcrumb.tsxapps/landing/src/app/[locale]/(main)/pricing/page.tsxpackages/ui/src/tooltip.tsxapps/web/src/app/[locale]/layout.tsxpackages/ui/src/sheet.tsxapps/web/src/components/forms/poll-options-form/week-calendar.tsxpackages/ui/src/textarea.tsxapps/web/src/components/time-zone-picker/time-zone-select.tsxpackages/ui/src/popover.tsxpackages/ui/src/switch.tsxapps/web/src/app/[locale]/(space)/(dashboard)/components/upgrade-to-pro-alert.tsxapps/web/src/components/discussion/discussion.tsxapps/web/src/features/billing/components/pay-wall-dialog.tsxpackages/ui/src/dropdown-menu.tsxpackages/ui/src/command.tsxapps/landing/src/app/[locale]/layout.tsxpackages/ui/src/alert.tsxpackages/ui/src/checkbox.tsxpackages/ui/src/toast.tsxpackages/ui/src/sidebar.tsxpackages/ui/src/select.tsxpackages/ui/src/billing-plan.tsxapps/web/src/components/forms/poll-options-form/month-calendar/month-calendar.tsxpackages/ui/src/progress.tsxapps/web/src/components/cookie-consent.tsxapps/web/src/app/[locale]/(space)/settings/layout.tsxpackages/ui/src/card.tsxapps/landing/postcss.config.jspackages/ui/src/separator.tsxapps/web/src/components/full-width-layout.tsxapps/web/src/app/[locale]/(space)/(dashboard)/components/nav-user.tsxapps/web/src/components/empty-state.tsxapps/landing/next.config.tsapps/web/src/app/[locale]/(auth)/layout.tsxapps/web/src/features/space/components/space-dropdown.tsxapps/landing/src/components/home/bonus-item.tsxapps/web/src/components/poll/desktop-poll.tsxapps/web/postcss.config.jspackages/ui/src/page-tabs.tsxapps/web/src/app/components/page-layout.tsxpackages/ui/src/table.tsxpackages/ui/src/badge.tsxapps/web/src/app/[locale]/accept-invite/[inviteId]/page.tsxapps/landing/src/app/[locale]/(main)/layout.tsxapps/web/src/components/description-list.tsxapps/web/next.config.tspackages/ui/src/avatar.tsxpackages/tailwind-config/postcss.config.jspackages/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 theuseDialoghook from@rallly/ui/dialogfor managing dialog state instead of manualuseStatefor 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.tsxpackages/ui/src/button.tsxapps/web/src/components/poll/scheduled-event.tsxapps/web/src/components/skeleton.tsxapps/web/src/components/vote-summary-progress-bar.tsxapps/landing/src/app/[locale]/licensing/thank-you/page.tsxpackages/ui/src/tabs.tsxapps/web/src/components/new-participant-modal.tsxpackages/ui/src/breadcrumb.tsxapps/landing/src/app/[locale]/(main)/pricing/page.tsxpackages/ui/src/tooltip.tsxapps/web/src/app/[locale]/layout.tsxpackages/ui/src/sheet.tsxapps/web/src/components/forms/poll-options-form/week-calendar.tsxpackages/ui/src/textarea.tsxapps/web/src/components/time-zone-picker/time-zone-select.tsxpackages/ui/src/popover.tsxpackages/ui/src/switch.tsxapps/web/src/app/[locale]/(space)/(dashboard)/components/upgrade-to-pro-alert.tsxapps/web/src/components/discussion/discussion.tsxapps/web/src/features/billing/components/pay-wall-dialog.tsxpackages/ui/src/dropdown-menu.tsxpackages/ui/src/command.tsxapps/landing/src/app/[locale]/layout.tsxpackages/ui/src/alert.tsxpackages/ui/src/checkbox.tsxpackages/ui/src/toast.tsxpackages/ui/src/sidebar.tsxpackages/ui/src/select.tsxpackages/ui/src/billing-plan.tsxapps/web/src/components/forms/poll-options-form/month-calendar/month-calendar.tsxpackages/ui/src/progress.tsxapps/web/src/components/cookie-consent.tsxapps/web/src/app/[locale]/(space)/settings/layout.tsxpackages/ui/src/card.tsxpackages/ui/src/separator.tsxapps/web/src/components/full-width-layout.tsxapps/web/src/app/[locale]/(space)/(dashboard)/components/nav-user.tsxapps/web/src/components/empty-state.tsxapps/landing/next.config.tsapps/web/src/app/[locale]/(auth)/layout.tsxapps/web/src/features/space/components/space-dropdown.tsxapps/landing/src/components/home/bonus-item.tsxapps/web/src/components/poll/desktop-poll.tsxpackages/ui/src/page-tabs.tsxapps/web/src/app/components/page-layout.tsxpackages/ui/src/table.tsxpackages/ui/src/badge.tsxapps/web/src/app/[locale]/accept-invite/[inviteId]/page.tsxapps/landing/src/app/[locale]/(main)/layout.tsxapps/web/src/components/description-list.tsxapps/web/next.config.tspackages/ui/src/avatar.tsxpackages/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.tsxapps/web/src/components/poll/scheduled-event.tsxapps/web/src/components/skeleton.tsxapps/web/src/components/vote-summary-progress-bar.tsxapps/web/src/components/new-participant-modal.tsxapps/web/src/components/forms/poll-options-form/week-calendar.tsxapps/web/src/components/time-zone-picker/time-zone-select.tsxapps/web/src/components/discussion/discussion.tsxapps/web/src/components/forms/poll-options-form/month-calendar/month-calendar.tsxapps/web/src/components/cookie-consent.tsxapps/web/src/components/full-width-layout.tsxapps/web/src/components/empty-state.tsxapps/web/src/components/poll/desktop-poll.tsxapps/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 ausername(used for login, normalized) and an optionaldisplayUsername(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.tsxapps/web/src/components/poll/scheduled-event.tsxapps/web/src/components/skeleton.tsxapps/web/src/components/vote-summary-progress-bar.tsxapps/web/src/components/new-participant-modal.tsxapps/web/src/app/[locale]/layout.tsxapps/web/src/components/forms/poll-options-form/week-calendar.tsxapps/web/src/components/time-zone-picker/time-zone-select.tsxapps/web/src/app/[locale]/(space)/(dashboard)/components/upgrade-to-pro-alert.tsxapps/web/src/components/discussion/discussion.tsxapps/web/src/features/billing/components/pay-wall-dialog.tsxapps/web/src/components/forms/poll-options-form/month-calendar/month-calendar.tsxapps/web/src/components/cookie-consent.tsxapps/web/src/app/[locale]/(space)/settings/layout.tsxapps/web/src/components/full-width-layout.tsxapps/web/src/app/[locale]/(space)/(dashboard)/components/nav-user.tsxapps/web/src/components/empty-state.tsxapps/web/src/app/[locale]/(auth)/layout.tsxapps/web/src/features/space/components/space-dropdown.tsxapps/web/src/components/poll/desktop-poll.tsxapps/web/postcss.config.jsapps/web/src/app/components/page-layout.tsxapps/web/src/app/[locale]/accept-invite/[inviteId]/page.tsxapps/web/src/components/description-list.tsxapps/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.tsxpackages/ui/src/tabs.tsxpackages/ui/src/breadcrumb.tsxpackages/ui/src/tooltip.tsxpackages/ui/src/sheet.tsxpackages/ui/src/textarea.tsxpackages/ui/src/popover.tsxpackages/ui/src/switch.tsxpackages/ui/src/dropdown-menu.tsxpackages/ui/src/command.tsxpackages/ui/src/alert.tsxpackages/ui/src/checkbox.tsxpackages/ui/src/toast.tsxpackages/ui/src/sidebar.tsxpackages/ui/src/select.tsxpackages/ui/src/billing-plan.tsxpackages/ui/src/progress.tsxpackages/ui/src/card.tsxpackages/ui/src/separator.tsxpackages/ui/src/page-tabs.tsxpackages/ui/src/table.tsxpackages/ui/src/badge.tsxpackages/ui/src/avatar.tsxpackages/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.tsxapps/web/src/app/[locale]/globals.cssapps/web/src/app/[locale]/(space)/(dashboard)/components/upgrade-to-pro-alert.tsxapps/web/src/app/[locale]/(space)/settings/layout.tsxapps/web/src/app/[locale]/(space)/(dashboard)/components/nav-user.tsxapps/web/src/app/[locale]/(auth)/layout.tsxapps/web/src/app/components/page-layout.tsxapps/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.tsxapps/web/src/features/space/components/space-dropdown.tsx
**/*.ts
📄 CodeRabbit inference engine (.cursorrules)
On the server use the
getTranslationsfunction from @/i18n/server to get the translations
Files:
apps/landing/next.config.tsapps/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.tsxpackages/tailwind-config/shared-styles.cssapps/web/src/app/[locale]/layout.tsxapps/web/src/app/[locale]/globals.cssapps/landing/package.jsonapps/web/src/components/time-zone-picker/time-zone-select.tsxapps/landing/src/app/[locale]/globals.csspackages/ui/src/command.tsxapps/landing/src/app/[locale]/layout.tsxpackages/ui/src/alert.tsxpackages/ui/src/checkbox.tsxpackages/ui/src/sidebar.tsxpackages/tailwind-config/package.jsonapps/web/src/globals.csspackages/ui/src/progress.tsxapps/landing/postcss.config.jspackages/ui/package.jsonpackages/ui/src/separator.tsxapps/web/src/app/[locale]/(auth)/layout.tsxapps/web/src/components/poll/desktop-poll.tsxapps/web/package.jsonapps/web/postcss.config.jspackages/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.tsxpackages/ui/src/tabs.tsxpackages/tailwind-config/shared-styles.cssapps/web/src/app/[locale]/layout.tsxapps/web/src/components/time-zone-picker/time-zone-select.tsxpackages/ui/src/command.tsxapps/landing/src/app/[locale]/layout.tsxpackages/ui/src/sidebar.tsxpackages/ui/src/select.tsxpackages/ui/src/card.tsxpackages/ui/package.jsonpackages/ui/src/separator.tsxapps/web/src/components/full-width-layout.tsxapps/landing/src/components/home/bonus-item.tsxapps/web/src/app/components/page-layout.tsxpackages/ui/src/table.tsxapps/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.tsxapps/landing/src/app/[locale]/(main)/pricing/page.tsxpackages/ui/src/tooltip.tsxapps/web/src/app/[locale]/globals.csspackages/ui/src/textarea.tsxpackages/ui/src/command.tsxapps/landing/src/app/[locale]/layout.tsxpackages/ui/src/sidebar.tsxpackages/ui/src/select.tsxpackages/ui/src/billing-plan.tsxapps/web/src/globals.csspackages/ui/src/card.tsxpackages/ui/src/separator.tsxapps/web/src/app/[locale]/(auth)/layout.tsxapps/web/src/components/poll/desktop-poll.tsxpackages/ui/src/page-tabs.tsxapps/web/src/app/components/page-layout.tsxpackages/ui/src/table.tsxpackages/ui/src/badge.tsxapps/landing/src/app/[locale]/(main)/layout.tsxapps/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.tsxpackages/ui/src/dropdown-menu.tsxpackages/ui/src/sidebar.tsxapps/web/src/app/[locale]/(space)/(dashboard)/components/nav-user.tsxapps/web/src/features/space/components/space-dropdown.tsxapps/landing/src/components/home/bonus-item.tsxapps/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.tsxapps/web/src/app/[locale]/globals.cssapps/landing/package.jsonapps/landing/src/app/[locale]/globals.csspackages/tailwind-config/package.jsonapps/web/src/globals.cssapps/web/package.jsonapps/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.tsxpackages/ui/src/tooltip.tsxapps/web/src/app/[locale]/layout.tsxpackages/ui/src/command.tsxpackages/ui/src/sidebar.tsxpackages/ui/src/select.tsxpackages/ui/src/billing-plan.tsxpackages/ui/src/progress.tsxpackages/ui/src/card.tsxpackages/ui/package.jsonapps/landing/src/components/home/bonus-item.tsxpackages/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.cssapps/web/src/app/[locale]/layout.tsxapps/web/src/app/[locale]/globals.cssapps/landing/package.jsonapps/web/src/components/time-zone-picker/time-zone-select.tsxapps/landing/src/app/[locale]/globals.csspackages/ui/src/command.tsxapps/landing/src/app/[locale]/layout.tsxpackages/ui/src/alert.tsxpackages/ui/src/sidebar.tsxpackages/tailwind-config/package.jsonapps/web/src/globals.csspackages/ui/src/progress.tsxapps/landing/postcss.config.jspackages/ui/package.jsonpackages/ui/src/separator.tsxapps/web/src/app/[locale]/(auth)/layout.tsxapps/web/package.jsonapps/web/postcss.config.jspackages/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.csspackages/ui/src/tooltip.tsxapps/web/src/features/billing/components/pay-wall-dialog.tsxpackages/ui/src/alert.tsxpackages/ui/src/sidebar.tsxpackages/ui/src/select.tsxapps/web/src/components/empty-state.tsxapps/landing/src/components/home/bonus-item.tsxapps/landing/src/app/[locale]/(main)/layout.tsxpackages/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.tsxapps/landing/src/app/[locale]/layout.tsxpackages/ui/src/table.tsxapps/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.tsxpackages/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.jsonapps/landing/next.config.tsapps/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.tsapps/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"} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🏁 Script executed:
# Find Button component definition files
fd -type f -name "*Button*" apps/web/src packages/ui/src 2>/dev/null | head -20Repository: 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 -10Repository: 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 -30Repository: 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 -15Repository: lukevella/rallly
Length of output: 42
🏁 Script executed:
# Check repository structure
git ls-files | head -30Repository: 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 -20Repository: lukevella/rallly
Length of output: 135
🏁 Script executed:
# Look for any Button-related files
find . -type f -name "*[Bb]utton*" 2>/dev/null | head -20Repository: 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.tsxRepository: 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.mdRepository: 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 -nRepository: 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.
| "type": "module", | ||
| "exports": { | ||
| ".": "./shared-styles.css", | ||
| "./postcss": "./postcss.config.js" | ||
| }, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🏁 Script executed:
rg -n '@rallly/tailwind-config' --glob '*.{js,jsx,ts,tsx}' -A 2 -B 2Repository: 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.
| @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; | ||
| } | ||
| } | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
| @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.
There was a problem hiding this 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
📒 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, runpnpm i18n:scaninstead of manually adding keys
Files:
packages/ui/src/sidebar.tsxpackages/ui/src/breadcrumb.tsx
**/*.{tsx,css,config.ts}
📄 CodeRabbit inference engine (.cursorrules)
Use tailwindcss for styling
Files:
packages/ui/src/sidebar.tsxapps/web/src/components/forms/poll-options-form/rbc-overrides.csspackages/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 thedefaultsprop to provide the default text
Always use a composable patterns when building components
Usecn()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.tsxpackages/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.tsxpackages/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.tsxpackages/ui/src/breadcrumb.tsx
**/*
📄 CodeRabbit inference engine (.cursorrules)
Always use kebab-case for file names
Files:
packages/ui/src/sidebar.tsxapps/web/src/components/forms/poll-options-form/rbc-overrides.csspackages/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.tsxpackages/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 theuseDialoghook from@rallly/ui/dialogfor managing dialog state instead of manualuseStatefor 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.tsxpackages/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-hiddenis a valid v4 utility that hides the default browser focus outline while preserving high-contrast mode support- Shadow tokens
shadow-xsandshadow-2xsare new v4 utilities with defined default values- Selector variants
has-data-[variant=inset]andin-data-[side=left]are valid composable data variants in v4No changes needed.
| .rbc-time-content > * + * > * { | ||
| @apply border-gray-200; | ||
| border-color: var(--color-gray-200); | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
There was a problem hiding this 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
⛔ Files ignored due to path filters (1)
pnpm-lock.yamlis 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.mjsapps/web/postcss.config.mjsapps/landing/postcss.config.mjspackages/tailwind-config/package.jsonapps/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.jsonapps/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.mjsapps/web/postcss.config.mjsapps/landing/postcss.config.mjspackages/tailwind-config/package.jsonapps/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.mjsapps/web/postcss.config.mjsapps/landing/postcss.config.mjspackages/tailwind-config/package.jsonapps/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.jsonapps/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
"."toshared-styles.cssplus"./postcss"topostcss.config.mjsmatches how the apps import from@rallly/tailwind-config/postcssand 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
postcssConfigwith@tailwindcss/postcsskeeps 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/postcssand 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.mjskeeps 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 inapps/web/package.jsonandpackages/tailwind-config/package.json. No version skew in the workspace.
| "postcss": "^8.5.6", | ||
| "tailwindcss": "^4.1.18" | ||
| }, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 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 -10Repository: 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.jsonRepository: lukevella/rallly
Length of output: 644
🏁 Script executed:
cat -n packages/tailwind-config/postcss.config.mjsRepository: 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.mjsRepository: 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 -100Repository: lukevella/rallly
Length of output: 2403
🏁 Script executed:
# Search for @tailwindcss/postcss in the entire repo
rg "@tailwindcss/postcss" --type json -B2 -A2Repository: 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 jsonRepository: 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.
08ef4b9 to
91f47e3
Compare
There was a problem hiding this 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.configpath
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/postcssin this package (exported config references it)
packages/tailwind-config/postcss.config.mjsuses@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 invalidtranslate-yproperty (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 updatingReact.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; considerElementRef->ComponentReffor consistency.
44-49: TabsContent outline-hidden change is fine; considerElementRef->ComponentReffor consistency.packages/ui/src/radio-group.tsx (1)
28-33: RadioGroupItem focus outline migration looks correct; considerElementRef->ComponentRef.packages/ui/src/page-tabs.tsx (2)
26-32: Page TabsTrigger outline-hidden change is good; considerElementRef->ComponentReffor consistency.
42-47: Page TabsContent outline-hidden change is good; considerElementRef->ComponentReffor consistency.apps/landing/next.config.ts (1)
16-18: Remove redundant JSDoc type now thatnextConfigis typed
Line 16 is unnecessary once you haveconst nextConfig: NextConfig = ...(Line 17).
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
pnpm-lock.yamlis 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, runpnpm i18n:scaninstead of manually adding keys
Files:
packages/ui/src/page-tabs.tsxpackages/ui/src/toast.tsxpackages/ui/src/tabs.tsxapps/web/src/features/space/components/space-dropdown.tsxpackages/ui/src/switch.tsxapps/web/src/app/[locale]/(auth)/layout.tsxpackages/ui/src/popover.tsxpackages/ui/src/button.tsxapps/web/src/app/[locale]/(space)/(dashboard)/components/upgrade-to-pro-alert.tsxpackages/ui/src/command.tsxapps/landing/next.config.tspackages/ui/src/checkbox.tsxapps/web/src/components/poll/scheduled-event.tsxpackages/ui/src/sidebar.tsxapps/web/src/components/forms/poll-options-form/month-calendar/month-calendar.tsxpackages/ui/src/radio-group.tsx
**/*.{tsx,css,config.ts}
📄 CodeRabbit inference engine (.cursorrules)
Use tailwindcss for styling
Files:
packages/ui/src/page-tabs.tsxpackages/ui/src/toast.tsxpackages/ui/src/tabs.tsxapps/web/src/features/space/components/space-dropdown.tsxpackages/ui/src/switch.tsxapps/web/src/app/[locale]/(auth)/layout.tsxpackages/ui/src/popover.tsxpackages/ui/src/button.tsxapps/web/src/app/[locale]/(space)/(dashboard)/components/upgrade-to-pro-alert.tsxpackages/ui/src/command.tsxpackages/tailwind-config/shared-styles.cssapps/landing/next.config.tspackages/ui/src/checkbox.tsxapps/web/src/components/poll/scheduled-event.tsxpackages/ui/src/sidebar.tsxapps/web/src/components/forms/poll-options-form/month-calendar/month-calendar.tsxpackages/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 thedefaultsprop to provide the default text
Always use a composable patterns when building components
Usecn()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.tsxpackages/ui/src/toast.tsxpackages/ui/src/tabs.tsxapps/web/src/features/space/components/space-dropdown.tsxpackages/ui/src/switch.tsxapps/web/src/app/[locale]/(auth)/layout.tsxpackages/ui/src/popover.tsxpackages/ui/src/button.tsxapps/web/src/app/[locale]/(space)/(dashboard)/components/upgrade-to-pro-alert.tsxpackages/ui/src/command.tsxpackages/ui/src/checkbox.tsxapps/web/src/components/poll/scheduled-event.tsxpackages/ui/src/sidebar.tsxapps/web/src/components/forms/poll-options-form/month-calendar/month-calendar.tsxpackages/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.tsxpackages/ui/src/toast.tsxpackages/ui/src/tabs.tsxapps/web/src/features/space/components/space-dropdown.tsxpackages/ui/src/switch.tsxapps/landing/package.jsonapps/web/src/app/[locale]/(auth)/layout.tsxpackages/ui/src/popover.tsxpackages/ui/src/button.tsxapps/web/src/app/[locale]/(space)/(dashboard)/components/upgrade-to-pro-alert.tsxpackages/ui/src/command.tsxapps/landing/next.config.tspackages/ui/src/checkbox.tsxapps/web/src/components/poll/scheduled-event.tsxpackages/ui/src/sidebar.tsxapps/web/src/components/forms/poll-options-form/month-calendar/month-calendar.tsxpackages/ui/src/radio-group.tsxpackages/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.tsxpackages/ui/src/toast.tsxpackages/ui/src/tabs.tsxpackages/ui/src/switch.tsxpackages/ui/src/popover.tsxpackages/ui/src/button.tsxpackages/ui/src/command.tsxpackages/ui/src/checkbox.tsxpackages/ui/src/sidebar.tsxpackages/ui/src/radio-group.tsx
**/*
📄 CodeRabbit inference engine (.cursorrules)
Always use kebab-case for file names
Files:
packages/ui/src/page-tabs.tsxpackages/ui/src/toast.tsxpackages/ui/src/tabs.tsxapps/web/src/features/space/components/space-dropdown.tsxpackages/ui/src/switch.tsxapps/landing/package.jsonapps/web/src/app/[locale]/(auth)/layout.tsxpackages/ui/src/popover.tsxpackages/ui/src/button.tsxapps/web/src/app/[locale]/(space)/(dashboard)/components/upgrade-to-pro-alert.tsxpackages/ui/src/command.tsxpackages/tailwind-config/shared-styles.cssapps/landing/postcss.config.mjsapps/landing/next.config.tspackages/ui/src/checkbox.tsxapps/web/src/components/poll/scheduled-event.tsxpackages/ui/src/sidebar.tsxapps/web/src/components/forms/poll-options-form/month-calendar/month-calendar.tsxpackages/ui/src/radio-group.tsxpackages/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.tsxpackages/ui/src/toast.tsxpackages/ui/src/tabs.tsxapps/web/src/features/space/components/space-dropdown.tsxpackages/ui/src/switch.tsxapps/web/src/app/[locale]/(auth)/layout.tsxpackages/ui/src/popover.tsxpackages/ui/src/button.tsxapps/web/src/app/[locale]/(space)/(dashboard)/components/upgrade-to-pro-alert.tsxpackages/ui/src/command.tsxapps/landing/next.config.tspackages/ui/src/checkbox.tsxapps/web/src/components/poll/scheduled-event.tsxpackages/ui/src/sidebar.tsxapps/web/src/components/forms/poll-options-form/month-calendar/month-calendar.tsxpackages/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 theuseDialoghook from@rallly/ui/dialogfor managing dialog state instead of manualuseStatefor 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.tsxpackages/ui/src/toast.tsxpackages/ui/src/tabs.tsxapps/web/src/features/space/components/space-dropdown.tsxpackages/ui/src/switch.tsxapps/web/src/app/[locale]/(auth)/layout.tsxpackages/ui/src/popover.tsxpackages/ui/src/button.tsxapps/web/src/app/[locale]/(space)/(dashboard)/components/upgrade-to-pro-alert.tsxpackages/ui/src/command.tsxapps/landing/next.config.tspackages/ui/src/checkbox.tsxapps/web/src/components/poll/scheduled-event.tsxpackages/ui/src/sidebar.tsxapps/web/src/components/forms/poll-options-form/month-calendar/month-calendar.tsxpackages/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 ausername(used for login, normalized) and an optionaldisplayUsername(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.tsxapps/web/src/app/[locale]/(auth)/layout.tsxapps/web/src/app/[locale]/(space)/(dashboard)/components/upgrade-to-pro-alert.tsxapps/web/src/components/poll/scheduled-event.tsxapps/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.tsxapps/web/src/app/[locale]/(space)/(dashboard)/components/upgrade-to-pro-alert.tsx
**/*.ts
📄 CodeRabbit inference engine (.cursorrules)
On the server use the
getTranslationsfunction 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.tsxapps/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.tsxapps/web/src/app/[locale]/(auth)/layout.tsxpackages/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.tsxpackages/ui/src/command.tsxpackages/tailwind-config/shared-styles.csspackages/ui/src/checkbox.tsxpackages/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.tsxpackages/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.tsxpackages/ui/src/command.tsxpackages/tailwind-config/shared-styles.csspackages/ui/src/checkbox.tsxpackages/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.jsonapps/web/src/app/[locale]/(auth)/layout.tsxpackages/tailwind-config/shared-styles.cssapps/landing/postcss.config.mjspackages/ui/src/checkbox.tsxpackages/ui/src/sidebar.tsxpackages/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.jsonapps/web/src/app/[locale]/(auth)/layout.tsxpackages/tailwind-config/shared-styles.cssapps/landing/postcss.config.mjspackages/ui/src/checkbox.tsxpackages/ui/src/sidebar.tsxpackages/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.jsonpackages/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.csspackages/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 v4shadow-xsswap 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; verifyshadow-xsis available in your Tailwind v4 theme output.If shadows are customized via your shared tokens/theme, make sure
shadow-xscompiles 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-(--...)). Thevar()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 syntaxmask-[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, andlink.For the outlined appearance shown in these examples, use
variant="ghost"orvariant="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 viafocus-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: CommandInputoutline-hiddenmigration 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]toz-100correctly 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]totranslate-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-nonetofocus:outline-hiddencorrectly implements Tailwind v4's breaking change whereoutline-nonenow only removes outline style, andoutline-hiddenmust be used to completely remove the outline.
79-79: Correct Tailwind v4 outline utility migration.The change from
focus:outline-nonetofocus:outline-hiddencorrectly 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:roundedtofocus:rounded-smmakes the border radius size more explicit, improving code clarity.
190-192: LGTM: Z-index cleanup.The change from
-z-0toz-0removes a redundant negative sign (since negative zero equals zero). Theshadow-xschange is consistent with line 125 and covered in the previous verification request.apps/landing/next.config.ts (1)
74-76: Redirect destination fix for/profilelooks correct
Passing an explicit subpath tocreateAppUrl("/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-smtoshadow-2xsaligns 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 syntaxw-(--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-nonetooutline-hiddenis correct. In Tailwind v4,outline-noneonly removes the outline style, whileoutline-hiddenremoves 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 selectorsin-data-[side=left]for ancestor state targetingpeer-data-[...]for peer relationshipsAll 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-xsutility aligns with Tailwind v4's refined shadow scale, maintaining consistent visual depth for the floating sidebar variant.
| import type { NextConfig } from "next"; | ||
|
|
||
| import createBundleAnalyzer from "@next/bundle-analyzer"; | ||
|
|
||
| const withBundleAnalyzer = createBundleAnalyzer({ | ||
| enabled: process.env.ANALYZE === "true", | ||
| }); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🏁 Script executed:
git ls-files apps/landing/next.config.tsRepository: lukevella/rallly
Length of output: 176
🏁 Script executed:
cat -n apps/landing/next.config.tsRepository: 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
- Next.js — TypeScript / next.config.ts (docs). [1]
- Next.js — TypeScript (config) (mirror). [2]
- Next.js — TypeScript examples (docs). [3]
- 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.
| 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; | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
| "react-use": "^17.6.0", | ||
| "tailwindcss": "^4.1.18" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🏁 Script executed:
# Check the current package.json structure in apps/landing
cat apps/landing/package.json | head -100Repository: 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/landingRepository: 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/landingRepository: 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
- 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]
- 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]
- 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]
- 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]
- 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)))]" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 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/srcRepository: 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.tsxRepository: 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.jsRepository: 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 -20Repository: 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.jsonRepository: lukevella/rallly
Length of output: 504
🏁 Script executed:
# Check the shared styles CSS file for variable definitions
cat packages/tailwind-config/shared-styles.cssRepository: 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).
Summary by CodeRabbit
UI / Styling
New Features
Chores
✏️ Tip: You can customize this high-level summary in your review settings.