diff --git a/src/components/app/study-paths/study-path-question-card-skeleton.tsx b/src/components/app/study-paths/study-path-question-card-skeleton.tsx
index 090244cf6..cf832f931 100644
--- a/src/components/app/study-paths/study-path-question-card-skeleton.tsx
+++ b/src/components/app/study-paths/study-path-question-card-skeleton.tsx
@@ -11,7 +11,7 @@ export default function StudyPathQuestionCardSkeleton({ className }: { className
>
diff --git a/src/components/app/study-paths/study-path-question-card.tsx b/src/components/app/study-paths/study-path-question-card.tsx
index 51352d8fd..a58c84e82 100644
--- a/src/components/app/study-paths/study-path-question-card.tsx
+++ b/src/components/app/study-paths/study-path-question-card.tsx
@@ -24,7 +24,7 @@ export default async function StudyPathQuestionCard({
href={href}
key={questionData.uid}
className={cn(
- 'flex flex-col gap-y-5 items-start bg-[#090909] border border-black-50 hover:border-black-100 duration-300 p-5 rounded-lg group w-full relative overflow-hidden group-has-[[data-pending]]:animate-pulse',
+ 'flex flex-col gap-y-5 items-start bg-[#090909] border border-black-50 hover:border-black-100 duration-300 p-5 rounded-lg group w-full relative overflow-hidden group-has-data-pending:animate-pulse',
className
)}
>
@@ -32,14 +32,14 @@ export default async function StudyPathQuestionCard({
{questionData.userAnswers && questionData.userAnswers.length > 0 ? (
questionData.userAnswers[0].correctAnswer ? (
-
+
) : (
-
+
)
) : (
-
+
)}
-
{title}
+ {title}
diff --git a/src/components/app/study-paths/study-path-sidebar.tsx b/src/components/app/study-paths/study-path-sidebar.tsx
index 3cca42db8..614ccbc94 100644
--- a/src/components/app/study-paths/study-path-sidebar.tsx
+++ b/src/components/app/study-paths/study-path-sidebar.tsx
@@ -140,7 +140,7 @@ export default async function StudyPathSidebar({ studyPath }: { studyPath: Study
/>
-
+
Earn rewards for your progress
diff --git a/src/components/marketing/features/leaderboard/leaderboard-features.tsx b/src/components/marketing/features/leaderboard/leaderboard-features.tsx
index c40d96a16..78580653f 100644
--- a/src/components/marketing/features/leaderboard/leaderboard-features.tsx
+++ b/src/components/marketing/features/leaderboard/leaderboard-features.tsx
@@ -7,7 +7,7 @@ export default function LeaderboardFeatures() {
-
+
Learning to code does not have to be boring.
diff --git a/src/components/marketing/features/leaderboard/leaderboard-hero.tsx b/src/components/marketing/features/leaderboard/leaderboard-hero.tsx
index bfa6d0d1f..00f37d5cb 100644
--- a/src/components/marketing/features/leaderboard/leaderboard-hero.tsx
+++ b/src/components/marketing/features/leaderboard/leaderboard-hero.tsx
@@ -8,10 +8,10 @@ import { cn } from '@/lib/utils';
export default function LeaderboardHero() {
return (
-
+
-
+
Coding leaderboards.
@@ -21,7 +21,7 @@ export default function LeaderboardHero() {
Get started for free
@@ -38,7 +38,7 @@ export default function LeaderboardHero() {
'absolute inset-0 pt-44 [mask-image:radial-gradient(400px_circle_at_center,white,transparent)]'
)}
/>
-
+
);
}
diff --git a/src/components/marketing/features/roadmap/grid/roadmap-feature-box-animation.tsx b/src/components/marketing/features/roadmap/grid/roadmap-feature-box-animation.tsx
index 25fc07e68..fce4cd27f 100644
--- a/src/components/marketing/features/roadmap/grid/roadmap-feature-box-animation.tsx
+++ b/src/components/marketing/features/roadmap/grid/roadmap-feature-box-animation.tsx
@@ -58,7 +58,7 @@ export default function RoadmapFeatureBoxAnimation({ absolute }: { absolute: boo
animate="visible"
exit="exit"
>
-
+
diff --git a/src/components/marketing/features/roadmap/grid/roadmap-grid-item-one.tsx b/src/components/marketing/features/roadmap/grid/roadmap-grid-item-one.tsx
index d99e5e8b6..a0a269b71 100644
--- a/src/components/marketing/features/roadmap/grid/roadmap-grid-item-one.tsx
+++ b/src/components/marketing/features/roadmap/grid/roadmap-grid-item-one.tsx
@@ -33,8 +33,8 @@ export default function RoadmapGridItemOne() {
-
-
+
+
);
diff --git a/src/components/marketing/features/roadmap/roadmap-customisation.tsx b/src/components/marketing/features/roadmap/roadmap-customisation.tsx
index a089addef..b2860b9e1 100644
--- a/src/components/marketing/features/roadmap/roadmap-customisation.tsx
+++ b/src/components/marketing/features/roadmap/roadmap-customisation.tsx
@@ -66,7 +66,7 @@ export default function FeatureRoadmapCustomizationBlock({
>
-
+
{header || 'Your personalized coding roadmap.'}
@@ -92,8 +92,8 @@ export default function FeatureRoadmapCustomizationBlock({
/>
))}
-
-
+
+
);
}
diff --git a/src/components/marketing/features/roadmap/roadmap-hero.tsx b/src/components/marketing/features/roadmap/roadmap-hero.tsx
index e7ef78d2b..f3c00b902 100644
--- a/src/components/marketing/features/roadmap/roadmap-hero.tsx
+++ b/src/components/marketing/features/roadmap/roadmap-hero.tsx
@@ -6,10 +6,10 @@ import { cn } from '@/lib/utils';
export default function FeatureRoadmapHeroBlock() {
return (
-
+
-
+
Personalized coding roadmaps.
@@ -19,7 +19,7 @@ export default function FeatureRoadmapHeroBlock() {
Get started for free
@@ -40,7 +40,7 @@ export default function FeatureRoadmapHeroBlock() {
'absolute inset-0 pt-44 [mask-image:radial-gradient(400px_circle_at_center,white,transparent)]'
)}
/>
-
+
);
}
diff --git a/src/components/marketing/features/statistics/stats-hero.tsx b/src/components/marketing/features/statistics/stats-hero.tsx
index a12dc4836..1964bb5f7 100644
--- a/src/components/marketing/features/statistics/stats-hero.tsx
+++ b/src/components/marketing/features/statistics/stats-hero.tsx
@@ -6,10 +6,10 @@ import { ArrowDown, ChevronRight } from 'lucide-react';
export default function StatsHero() {
return (
-
+
-
+
Track coding progress with ease.
@@ -23,7 +23,7 @@ export default function StatsHero() {
Try it now
@@ -40,7 +40,7 @@ export default function StatsHero() {
'absolute inset-0 pt-44 [mask-image:radial-gradient(400px_circle_at_center,white,transparent)]'
)}
/>
-
+
);
}
diff --git a/src/components/marketing/features/statistics/stats-report-section.tsx b/src/components/marketing/features/statistics/stats-report-section.tsx
index be8473fca..6b2cc4d97 100644
--- a/src/components/marketing/features/statistics/stats-report-section.tsx
+++ b/src/components/marketing/features/statistics/stats-report-section.tsx
@@ -85,7 +85,7 @@ export default function StatsReportSection(opts: {
className="py-8 sm:py-12 md:py-28 px-4 flex flex-col gap-y-8 sm:gap-y-12 md:gap-y-16 relative"
>
-
+
{header ? (
header
) : (
@@ -110,7 +110,7 @@ export default function StatsReportSection(opts: {
-
+
Customised Questions
@@ -125,7 +125,7 @@ export default function StatsReportSection(opts: {
className="left-1/2 top-0 w-full center pointer-events-none absolute h-px max-w-full -translate-x-1/2 -translate-y-1/2 bg-black-50"
>
-
+
Tag overview
@@ -175,7 +175,7 @@ export default function StatsReportSection(opts: {
-
+
Progress report
@@ -188,8 +188,8 @@ export default function StatsReportSection(opts: {
-
-
+
+
diff --git a/src/components/marketing/global/blocks/call-to-action-block.tsx b/src/components/marketing/global/blocks/call-to-action-block.tsx
index a3eb50084..fcb5d7165 100644
--- a/src/components/marketing/global/blocks/call-to-action-block.tsx
+++ b/src/components/marketing/global/blocks/call-to-action-block.tsx
@@ -31,7 +31,7 @@ export default function CallToActionBlock(opts: {
}}
>
-
+
{title}
{description}
@@ -43,7 +43,7 @@ export default function CallToActionBlock(opts: {
{leftCta?.title || 'Get Started'}
@@ -70,7 +70,7 @@ export default function CallToActionBlock(opts: {
)}
-
+
);
}
diff --git a/src/components/marketing/global/blocks/content-grid.tsx b/src/components/marketing/global/blocks/content-grid.tsx
index ab7a986a9..6a508bf60 100644
--- a/src/components/marketing/global/blocks/content-grid.tsx
+++ b/src/components/marketing/global/blocks/content-grid.tsx
@@ -23,7 +23,7 @@ export default function MarketingContentGrid({
}: MarketingContentGridComponentProps) {
return (
-
+
{title}
{subheading && (
diff --git a/src/components/marketing/global/blocks/faqs.tsx b/src/components/marketing/global/blocks/faqs.tsx
index 9ab5d595f..39e0acafe 100644
--- a/src/components/marketing/global/blocks/faqs.tsx
+++ b/src/components/marketing/global/blocks/faqs.tsx
@@ -23,7 +23,7 @@ export default function FAQsBlock(opts: {
{showSpan &&
}
-
+
{title || 'Frequently asked questions'}
{description && {description}
}
diff --git a/src/components/marketing/global/blocks/homepage-user-stats.tsx b/src/components/marketing/global/blocks/homepage-user-stats.tsx
index f839e8013..79a2aa3a0 100644
--- a/src/components/marketing/global/blocks/homepage-user-stats.tsx
+++ b/src/components/marketing/global/blocks/homepage-user-stats.tsx
@@ -14,7 +14,7 @@ export default async function HomepageUserStats({ userCountPromise }: HomepageUs
A growing community with
-
+
{QUESTIONS_COUNT}+ challenges
{userCount}+ users
Unlimited practice
diff --git a/src/components/marketing/global/blocks/question-marquee.tsx b/src/components/marketing/global/blocks/question-marquee.tsx
index 17485f0b4..09c6ab8e0 100644
--- a/src/components/marketing/global/blocks/question-marquee.tsx
+++ b/src/components/marketing/global/blocks/question-marquee.tsx
@@ -140,8 +140,8 @@ export default function QuestionMarquee({
))}
-
-
+
+
);
diff --git a/src/components/marketing/global/blocks/user-stats-floating-chips.tsx b/src/components/marketing/global/blocks/user-stats-floating-chips.tsx
index eceaf6e4c..34884e311 100644
--- a/src/components/marketing/global/blocks/user-stats-floating-chips.tsx
+++ b/src/components/marketing/global/blocks/user-stats-floating-chips.tsx
@@ -109,7 +109,7 @@ const FloatingChip: React.FC
= ({ Icon, href, mouseX, mouseY,
return (
);
diff --git a/src/components/marketing/global/navigation/mobile-menu.tsx b/src/components/marketing/global/navigation/mobile-menu.tsx
index 1ff6d9da3..70f75024d 100644
--- a/src/components/marketing/global/navigation/mobile-menu.tsx
+++ b/src/components/marketing/global/navigation/mobile-menu.tsx
@@ -163,7 +163,7 @@ export function MobileMenu() {
{isLoggedIn ? (
setIsOpen(false)}
aria-label="Dashboard link"
>
@@ -183,7 +183,7 @@ export function MobileMenu() {
setIsOpen(false)}
aria-label="Get started link"
>
diff --git a/src/components/marketing/global/navigation/navigation-buttons.tsx b/src/components/marketing/global/navigation/navigation-buttons.tsx
index d91f7500a..3e7af6db1 100644
--- a/src/components/marketing/global/navigation/navigation-buttons.tsx
+++ b/src/components/marketing/global/navigation/navigation-buttons.tsx
@@ -30,7 +30,7 @@ export default async function NavigationButtons() {
Get started
diff --git a/src/components/marketing/global/navigation/navigation-items.tsx b/src/components/marketing/global/navigation/navigation-items.tsx
index 3372a0502..e5b1d4dcf 100644
--- a/src/components/marketing/global/navigation/navigation-items.tsx
+++ b/src/components/marketing/global/navigation/navigation-items.tsx
@@ -133,7 +133,7 @@ export function NavigationMenuItems() {
href="/pricing"
legacyBehavior
passHref
- className="!text-white focus:!text-white"
+ className="text-white! focus:text-white!"
aria-label="Navigate to Pricing"
>
@@ -154,7 +154,7 @@ const ListItem = React.forwardRef, React.ComponentPropsWit
href={props.href || '/'}
ref={ref}
className={cn(
- 'group block select-none space-y-1 rounded-md p-3 leading-none no-underline outline-none transition-colors hover:bg-accent hover:text-accent-foreground focus:bg-accent focus:text-white hover:!text-white !font-onest',
+ 'group block select-none space-y-1 rounded-md p-3 leading-none no-underline outline-hidden transition-colors hover:bg-accent hover:text-accent-foreground focus:bg-accent focus:text-white hover:text-white! font-onest!',
className
)}
{...props}
diff --git a/src/components/marketing/global/navigation/navigation.tsx b/src/components/marketing/global/navigation/navigation.tsx
index d81f44672..4531e7319 100644
--- a/src/components/marketing/global/navigation/navigation.tsx
+++ b/src/components/marketing/global/navigation/navigation.tsx
@@ -7,7 +7,7 @@ import { GithubStars } from '@/components/marketing/global/navigation/navigation
export default function MarketingNavigation() {
return (
-
+
diff --git a/src/components/marketing/global/open-source/open-source-block.tsx b/src/components/marketing/global/open-source/open-source-block.tsx
index ef3173e8f..cad00a448 100644
--- a/src/components/marketing/global/open-source/open-source-block.tsx
+++ b/src/components/marketing/global/open-source/open-source-block.tsx
@@ -60,7 +60,7 @@ export default function OpenSourceBlock(opts: { linkToInternalPage?: boolean })
return (
-
+
Secrets are for Magicians, Not Software
@@ -83,7 +83,7 @@ export default function OpenSourceBlock(opts: { linkToInternalPage?: boolean })
{/** illustration / GH card area */}
-
+
{/** 'timeline' line */}
))}
-
+
);
diff --git a/src/components/marketing/global/social-proof.tsx b/src/components/marketing/global/social-proof.tsx
index d221e6af6..4f1b164f8 100644
--- a/src/components/marketing/global/social-proof.tsx
+++ b/src/components/marketing/global/social-proof.tsx
@@ -26,7 +26,7 @@ export default function SocialProof({
-
+
Empowering Developers Worldwide
diff --git a/src/components/marketing/homepage/comparison/code-comparison.tsx b/src/components/marketing/homepage/comparison/code-comparison.tsx
index 2db528d08..6bc98e0ad 100644
--- a/src/components/marketing/homepage/comparison/code-comparison.tsx
+++ b/src/components/marketing/homepage/comparison/code-comparison.tsx
@@ -50,7 +50,7 @@ export default function CodeComparisonDemo() {
lightTheme="one-dark-pro"
darkTheme="one-dark-pro"
/>
-
+
);
}
diff --git a/src/components/marketing/homepage/comparison/comparison-block.tsx b/src/components/marketing/homepage/comparison/comparison-block.tsx
index 0e8063a09..3f65c0f5c 100644
--- a/src/components/marketing/homepage/comparison/comparison-block.tsx
+++ b/src/components/marketing/homepage/comparison/comparison-block.tsx
@@ -6,7 +6,7 @@ export default async function ComparisonBlock(opts: { header?: string; subheader
return (
-
+
{header ? (
header
) : (
diff --git a/src/components/marketing/homepage/features/features-bento-grid.tsx b/src/components/marketing/homepage/features/features-bento-grid.tsx
index 6b99ccb83..11f41278b 100644
--- a/src/components/marketing/homepage/features/features-bento-grid.tsx
+++ b/src/components/marketing/homepage/features/features-bento-grid.tsx
@@ -25,7 +25,7 @@ export default async function FeaturesBentoGrid() {
-
+
Build your future in tech with personalized tools
diff --git a/src/components/marketing/homepage/hero/hero-images.tsx b/src/components/marketing/homepage/hero/hero-images.tsx
index 3d9f55624..762281ca1 100644
--- a/src/components/marketing/homepage/hero/hero-images.tsx
+++ b/src/components/marketing/homepage/hero/hero-images.tsx
@@ -110,7 +110,7 @@ const HomepageHeroImages: FC = ({
)}
diff --git a/src/components/marketing/homepage/hero/hero.tsx b/src/components/marketing/homepage/hero/hero.tsx
index e40a77f31..39f31f4bf 100644
--- a/src/components/marketing/homepage/hero/hero.tsx
+++ b/src/components/marketing/homepage/hero/hero.tsx
@@ -36,7 +36,7 @@ export default function HomepageHero() {
-
+
Learning to code
diff --git a/src/components/marketing/homepage/personalized/block.tsx b/src/components/marketing/homepage/personalized/block.tsx
index 68189de64..54b61121e 100644
--- a/src/components/marketing/homepage/personalized/block.tsx
+++ b/src/components/marketing/homepage/personalized/block.tsx
@@ -7,7 +7,7 @@ export default function Personalized() {
-
+
Learn to code faster with AI-powered feedback
diff --git a/src/components/marketing/homepage/personalized/left.tsx b/src/components/marketing/homepage/personalized/left.tsx
index cdff79bfe..06d3ef170 100644
--- a/src/components/marketing/homepage/personalized/left.tsx
+++ b/src/components/marketing/homepage/personalized/left.tsx
@@ -14,7 +14,7 @@ export default function PersonalizedLeft() {
}>
-
+
diff --git a/src/components/marketing/homepage/personalized/right.tsx b/src/components/marketing/homepage/personalized/right.tsx
index e98fa5e71..6ccec078a 100644
--- a/src/components/marketing/homepage/personalized/right.tsx
+++ b/src/components/marketing/homepage/personalized/right.tsx
@@ -66,11 +66,11 @@ export default function PersonalizedRight() {
target="_blank"
>
{question.question}
-
+
))}
-
+
Custom Code Challenges
diff --git a/src/components/marketing/resources/open-source/open-source-hero.tsx b/src/components/marketing/resources/open-source/open-source-hero.tsx
index 994f6dd88..ff0223ab8 100644
--- a/src/components/marketing/resources/open-source/open-source-hero.tsx
+++ b/src/components/marketing/resources/open-source/open-source-hero.tsx
@@ -6,10 +6,10 @@ import { Star } from 'lucide-react';
export default function ResourceOpenSourceHeroBlock() {
return (
-
+
-
+
Open Source
@@ -29,7 +29,7 @@ export default function ResourceOpenSourceHeroBlock() {
*/}
on GitHub!
@@ -46,7 +46,7 @@ export default function ResourceOpenSourceHeroBlock() {
'absolute inset-0 pt-44 [mask-image:radial-gradient(400px_circle_at_center,white,transparent)]'
)}
/>
-
+
);
}
diff --git a/src/components/shared/Card.tsx b/src/components/shared/Card.tsx
index 48ee0af71..9beea7935 100644
--- a/src/components/shared/Card.tsx
+++ b/src/components/shared/Card.tsx
@@ -15,7 +15,7 @@ export default function Card({
{header}
- {children}
+ {children}
{footer && (
<>
diff --git a/src/components/shared/hero.tsx b/src/components/shared/hero.tsx
index 6ae121722..5a59e02b5 100644
--- a/src/components/shared/hero.tsx
+++ b/src/components/shared/hero.tsx
@@ -33,7 +33,7 @@ export default function Hero(opts: {
{/* Fade-out gradient overlay */}
-
+
);
}
diff --git a/src/components/shared/payment/upgrade-page.tsx b/src/components/shared/payment/upgrade-page.tsx
index 1bb637a07..8b2e7868f 100644
--- a/src/components/shared/payment/upgrade-page.tsx
+++ b/src/components/shared/payment/upgrade-page.tsx
@@ -29,9 +29,9 @@ export default async function UpgradePage({
return (
-
+
Unlock a{' '}
-
+
personalized{' '}
{' '}
learning experience
diff --git a/src/components/ui/animated-span.tsx b/src/components/ui/animated-span.tsx
index 577eb3aa5..88052ed9c 100644
--- a/src/components/ui/animated-span.tsx
+++ b/src/components/ui/animated-span.tsx
@@ -4,7 +4,7 @@ export default function AnimatedSpan(opts: { content: string | ReactNode }) {
const { content } = opts;
return (
-
+
{content}
diff --git a/src/components/ui/badge.tsx b/src/components/ui/badge.tsx
index 19132c081..8d0e4b731 100644
--- a/src/components/ui/badge.tsx
+++ b/src/components/ui/badge.tsx
@@ -4,15 +4,15 @@ import { cva, type VariantProps } from 'class-variance-authority';
import { cn } from '@/lib/utils';
const badgeVariants = cva(
- 'inline-flex items-center rounded-md border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2',
+ 'inline-flex items-center rounded-md border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-hidden focus:ring-2 focus:ring-ring focus:ring-offset-2',
{
variants: {
variant: {
- default: 'border-transparent bg-primary text-primary-foreground shadow hover:bg-primary/80',
+ default: 'border-transparent bg-primary text-primary-foreground shadow-sm hover:bg-primary/80',
secondary:
'border-transparent bg-secondary text-secondary-foreground hover:bg-secondary/80',
destructive:
- 'border-transparent bg-destructive text-destructive-foreground shadow hover:bg-destructive/80',
+ 'border-transparent bg-destructive text-destructive-foreground shadow-sm hover:bg-destructive/80',
outline: 'text-foreground',
},
},
diff --git a/src/components/ui/button.tsx b/src/components/ui/button.tsx
index ad57eaf65..2e9c3cc83 100644
--- a/src/components/ui/button.tsx
+++ b/src/components/ui/button.tsx
@@ -20,21 +20,21 @@ export interface ButtonProps extends VariantProps {
}
const buttonVariants = cva(
- 'inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 font-onest',
+ 'inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-hidden focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 font-onest',
{
variants: {
variant: {
default:
- 'bg-primary text-primary-foreground shadow hover:bg-primary/90 border border-black-50',
- destructive: 'bg-red-600 text-destructive-foreground shadow-sm hover:bg-destructive/90',
- outline: 'border border-input bg-background shadow-sm hover:bg-accent hover:text-white',
- secondary: 'bg-secondary text-secondary-foreground shadow-sm hover:bg-secondary/80',
+ 'bg-primary text-primary-foreground shadow-sm hover:bg-primary/90 border border-black-50',
+ destructive: 'bg-red-600 text-destructive-foreground shadow-xs hover:bg-destructive/90',
+ outline: 'border border-input bg-background shadow-xs hover:bg-accent hover:text-white',
+ secondary: 'bg-secondary text-secondary-foreground shadow-xs hover:bg-secondary/80',
ghost: 'hover:text-gray-400 duration-300',
link: 'text-primary underline-offset-4 hover:underline',
- accent: 'bg-accent text-white shadow-sm hover:bg-accent/90 font-onest',
+ accent: 'bg-accent text-white shadow-xs hover:bg-accent/90 font-onest',
// premium is accent but with a shimmering effect
premium:
- 'font-onest !bg-gradient-to-r !from-accent !via-accent/80 !to-accent animate-shimmer bg-[length:200%_100%] transition-colors',
+ 'font-onest bg-linear-to-r! from-accent! via-accent/80! to-accent! animate-shimmer bg-[length:200%_100%] transition-colors',
},
size: {
default: 'h-9 px-4 py-2',
@@ -55,7 +55,7 @@ const buttonVariants = cva(
lg: 'rounded-2xl hover:rounded-xl',
},
padding: {
- none: '!p-0',
+ none: 'p-0!',
sm: 'px-2 py-1',
md: 'px-4 py-2',
lg: 'px-8 py-4',
diff --git a/src/components/ui/card.tsx b/src/components/ui/card.tsx
index 1dfa6e0c5..6387b16c0 100644
--- a/src/components/ui/card.tsx
+++ b/src/components/ui/card.tsx
@@ -6,7 +6,7 @@ const Card = React.forwardRef (
)
diff --git a/src/components/ui/chart.tsx b/src/components/ui/chart.tsx
index d036ebd75..6184bd7a4 100644
--- a/src/components/ui/chart.tsx
+++ b/src/components/ui/chart.tsx
@@ -51,7 +51,7 @@ const ChartContainer = React.forwardRef<
data-chart={chartId}
ref={ref}
className={cn(
- "flex aspect-video justify-center text-xs [&_.recharts-cartesian-axis-tick_text]:fill-muted-foreground [&_.recharts-cartesian-grid_line[stroke='#ccc']]:stroke-border/50 [&_.recharts-curve.recharts-tooltip-cursor]:stroke-border [&_.recharts-dot[stroke='#fff']]:stroke-transparent [&_.recharts-layer]:outline-none [&_.recharts-polar-grid_[stroke='#ccc']]:stroke-border [&_.recharts-radial-bar-background-sector]:fill-muted [&_.recharts-rectangle.recharts-tooltip-cursor]:fill-muted [&_.recharts-reference-line_[stroke='#ccc']]:stroke-border [&_.recharts-sector[stroke='#fff']]:stroke-transparent [&_.recharts-sector]:outline-none [&_.recharts-surface]:outline-none",
+ "flex aspect-video justify-center text-xs [&_.recharts-cartesian-axis-tick_text]:fill-muted-foreground [&_.recharts-cartesian-grid_line[stroke='#ccc']]:stroke-border/50 [&_.recharts-curve.recharts-tooltip-cursor]:stroke-border [&_.recharts-dot[stroke='#fff']]:stroke-transparent [&_.recharts-layer]:outline-hidden [&_.recharts-polar-grid_[stroke='#ccc']]:stroke-border [&_.recharts-radial-bar-background-sector]:fill-muted [&_.recharts-rectangle.recharts-tooltip-cursor]:fill-muted [&_.recharts-reference-line_[stroke='#ccc']]:stroke-border [&_.recharts-sector[stroke='#fff']]:stroke-transparent [&_.recharts-sector]:outline-hidden [&_.recharts-surface]:outline-hidden",
className
)}
{...props}
@@ -191,7 +191,7 @@ const ChartTooltipContent = React.forwardRef<
!hideIndicator && (
{
return (
);
@@ -42,7 +42,7 @@ export default async function CodeComparison({
return (
-
+
-
+
{children}
{showCloseButton ? (
-
+
Close
diff --git a/src/components/ui/dropdown-menu.tsx b/src/components/ui/dropdown-menu.tsx
index 84751c91f..999049e7c 100644
--- a/src/components/ui/dropdown-menu.tsx
+++ b/src/components/ui/dropdown-menu.tsx
@@ -27,7 +27,7 @@ const DropdownMenuSubTrigger = React.forwardRef<
-
+
(
{...props}
className="
bg-transparent w-full p-2 placeholder:text-white/50 autofill:!bg-transparent border border-black-50
- focus-visible:outline-none focus-visible:ring-0 disabled:cursor-not-allowed disabled:opacity-50 px-4
+ focus-visible:outline-hidden focus-visible:ring-0 disabled:cursor-not-allowed disabled:opacity-50 px-4
hover:border-white/50
"
/>
diff --git a/src/components/ui/input.tsx b/src/components/ui/input.tsx
index f0cb6fbd2..01656cf23 100644
--- a/src/components/ui/input.tsx
+++ b/src/components/ui/input.tsx
@@ -10,7 +10,7 @@ const Input = React.forwardRef(
(({ className, children, ...props }, ref) => (
{children}{' '}
@@ -65,7 +65,7 @@ const NavigationMenuContent = React.forwardRef<
,
React.ComponentPropsWithoutRef
>(({ className, ...props }, ref) => (
-
+
span]:line-clamp-1 [&>span]:text-white',
+ 'flex h-auto w-full items-center justify-between whitespace-nowrap rounded-md border border-input bg-transparent px-3 py-2 text-xs shadow-xs ring-offset-background placeholder:text-muted-foreground focus:outline-hidden focus:ring-1 focus:ring-ring disabled:cursor-not-allowed disabled:opacity-50 [&>span]:line-clamp-1 [&>span]:text-white',
className
)}
{...props}
@@ -111,7 +111,7 @@ const SelectItem = React.forwardRef<
-
+
Close
diff --git a/src/components/ui/sidebar.tsx b/src/components/ui/sidebar.tsx
index b70c7d4d9..6cd7aa87c 100644
--- a/src/components/ui/sidebar.tsx
+++ b/src/components/ui/sidebar.tsx
@@ -130,7 +130,7 @@ const SidebarProvider = React.forwardRef<
} as React.CSSProperties
}
className={cn(
- 'group/sidebar-wrapper flex min-h-svh w-full has-[[data-variant=inset]]:bg-sidebar',
+ 'group/sidebar-wrapper flex min-h-svh w-full has-data-[variant=inset]:bg-sidebar',
className
)}
ref={ref}
@@ -170,7 +170,7 @@ const Sidebar = React.forwardRef<
return (
{children}
@@ -289,9 +289,9 @@ const SidebarRail = React.forwardRef
svg]:size-4 [&>svg]:shrink-0',
+ 'duration-200 flex h-8 shrink-0 items-center rounded-md px-2 text-xs font-medium text-sidebar-foreground/70 outline-hidden ring-sidebar-ring transition-[margin,opa] ease-linear focus-visible:ring-2 [&>svg]:size-4 [&>svg]:shrink-0',
'group-data-[collapsible=icon]:-mt-8 group-data-[collapsible=icon]:opacity-0',
className
)}
@@ -444,9 +444,9 @@ const SidebarGroupAction = React.forwardRef<
ref={ref}
data-sidebar="group-action"
className={cn(
- 'absolute right-3 top-3.5 flex aspect-square w-5 items-center justify-center rounded-md p-0 text-sidebar-foreground outline-none ring-sidebar-ring transition-transform hover:bg-sidebar-accent hover:text-sidebar-accent-foreground focus-visible:ring-2 [&>svg]:size-4 [&>svg]:shrink-0',
+ 'absolute right-3 top-3.5 flex aspect-square w-5 items-center justify-center rounded-md p-0 text-sidebar-foreground outline-hidden ring-sidebar-ring transition-transform hover:bg-sidebar-accent hover:text-sidebar-accent-foreground focus-visible:ring-2 [&>svg]:size-4 [&>svg]:shrink-0',
// Increases the hit area of the button on mobile.
- 'after:absolute after:-inset-2 after:lg:hidden',
+ 'after:absolute after:-inset-2 lg:after:hidden',
'group-data-[collapsible=icon]:hidden',
className
)}
@@ -493,7 +493,7 @@ const SidebarMenuItem = React.forwardRefspan:last-child]:truncate [&>svg]:size-4 [&>svg]:shrink-0',
+ 'peer/menu-button flex w-full items-center gap-2 overflow-hidden rounded-md p-2 pr-1 text-left text-sm outline-hidden ring-sidebar-ring transition-[width,height,padding] hover:bg-sidebar-accent hover:text-sidebar-accent-foreground focus-visible:ring-2 active:bg-sidebar-accent active:text-sidebar-accent-foreground disabled:pointer-events-none disabled:opacity-50 group-has-data-[sidebar=menu-action]/menu-item:pr-8 aria-disabled:pointer-events-none aria-disabled:opacity-50 data-[active=true]:bg-sidebar-accent data-[active=true]:font-medium data-[active=true]:text-sidebar-accent-foreground data-[state=open]:hover:bg-sidebar-accent data-[state=open]:hover:text-sidebar-accent-foreground group-data-[collapsible=icon]:size-8! group-data-[collapsible=icon]:p-2! [&>span:last-child]:truncate [&>svg]:size-4 [&>svg]:shrink-0',
{
variants: {
variant: {
@@ -504,7 +504,7 @@ const sidebarMenuButtonVariants = cva(
size: {
default: 'h-8 text-sm',
sm: 'h-7 text-xs',
- lg: 'h-12 text-sm group-data-[collapsible=icon]:!p-0',
+ lg: 'h-12 text-sm group-data-[collapsible=icon]:p-0!',
},
},
defaultVariants: {
@@ -587,9 +587,9 @@ const SidebarMenuAction = React.forwardRef<
ref={ref}
data-sidebar="menu-action"
className={cn(
- 'absolute right-1 top-1.5 flex aspect-square w-5 items-center justify-center rounded-md p-0 text-sidebar-foreground outline-none ring-sidebar-ring transition-transform hover:bg-sidebar-accent hover:text-sidebar-accent-foreground focus-visible:ring-2 [&>svg]:size-4 [&>svg]:shrink-0',
+ 'absolute right-1 top-1.5 flex aspect-square w-5 items-center justify-center rounded-md p-0 text-sidebar-foreground outline-hidden ring-sidebar-ring transition-transform hover:bg-sidebar-accent hover:text-sidebar-accent-foreground focus-visible:ring-2 [&>svg]:size-4 [&>svg]:shrink-0',
// Increases the hit area of the button on mobile.
- 'after:absolute after:-inset-2 after:lg:hidden',
+ 'after:absolute after:-inset-2 lg:after:hidden',
'peer-data-[size=sm]/menu-button:top-1',
'peer-data-[size=default]/menu-button:top-1.5',
'peer-data-[size=lg]/menu-button:top-2.5',
@@ -610,7 +610,7 @@ const SidebarMenuBadge = React.forwardRef
{showIcon && }
span:last-child]:truncate [&>svg]:size-4 [&>svg]:shrink-0 [&>svg]:text-sidebar-accent-foreground',
+ 'flex h-7 min-w-0 -translate-x-px items-center gap-2 overflow-hidden rounded-md px-2 text-sidebar-foreground outline-hidden ring-sidebar-ring hover:bg-sidebar-accent hover:text-sidebar-accent-foreground focus-visible:ring-2 active:bg-sidebar-accent active:text-sidebar-accent-foreground disabled:pointer-events-none disabled:opacity-50 aria-disabled:pointer-events-none aria-disabled:opacity-50 [&>span:last-child]:truncate [&>svg]:size-4 [&>svg]:shrink-0 [&>svg]:text-sidebar-accent-foreground',
'data-[active=true]:bg-sidebar-accent data-[active=true]:text-sidebar-accent-foreground',
size === 'sm' && 'text-xs',
size === 'md' && 'text-sm',
diff --git a/src/components/ui/switch.tsx b/src/components/ui/switch.tsx
index ff90e0ca8..0f32261ec 100644
--- a/src/components/ui/switch.tsx
+++ b/src/components/ui/switch.tsx
@@ -11,7 +11,7 @@ const Switch = React.forwardRef<
>(({ className, ...props }, ref) => (
tr]:last:border-b-0',
+ 'border-t border-black-50 bg-black-25 font-medium last:[&>tr]:border-b-0',
className
)}
{...props}
diff --git a/src/components/ui/tabs.tsx b/src/components/ui/tabs.tsx
index 933e3ca4e..dc6e4c31d 100644
--- a/src/components/ui/tabs.tsx
+++ b/src/components/ui/tabs.tsx
@@ -31,7 +31,7 @@ const TabsTrigger = React.forwardRef<
(
return (
diff --git a/tailwind.config.ts b/tailwind.config.ts
index 63de4753b..931e38e5e 100644
--- a/tailwind.config.ts
+++ b/tailwind.config.ts
@@ -202,13 +202,7 @@ const config = {
},
},
},
- plugins: [
- require('tailwindcss-animate'),
- addVariablesForColors,
- addMatchUtils,
- require('tailwind-container-break-out'),
- fluid,
- ],
+ plugins: [],
} satisfies Config;
function addMatchUtils({ matchUtilities, theme }: any) {
From 230a79f1b5fa8c6259273663d24c0f753bc6d486 Mon Sep 17 00:00:00 2001
From: Logan Ford <110533855+Logannford@users.noreply.github.com>
Date: Fri, 28 Feb 2025 23:39:29 +0000
Subject: [PATCH 5/8] feat: more progress with v4 migration
---
package.json | 42 ++++---
src/app/(marketing)/layout.tsx | 2 +-
src/app/globals.css | 121 +++++++++++++-------
src/app/layout.tsx | 7 +-
src/components/providers/theme-provider.tsx | 31 +++++
src/components/ui/bento-grid.tsx | 2 +-
src/types/lucide-react.d.ts | 8 ++
tailwind.config.ts | 94 +++++++--------
8 files changed, 187 insertions(+), 120 deletions(-)
create mode 100644 src/components/providers/theme-provider.tsx
create mode 100644 src/types/lucide-react.d.ts
diff --git a/package.json b/package.json
index 04c0a4eb1..3e4833701 100644
--- a/package.json
+++ b/package.json
@@ -27,26 +27,26 @@
"@next/mdx": "^15.1.3",
"@number-flow/react": "^0.4.2",
"@prisma/client": "6.4.0",
- "@radix-ui/react-accordion": "^1.2.1",
- "@radix-ui/react-alert-dialog": "^1.1.2",
- "@radix-ui/react-avatar": "^1.1.1",
- "@radix-ui/react-checkbox": "^1.1.1",
- "@radix-ui/react-collapsible": "^1.1.1",
- "@radix-ui/react-dialog": "^1.1.2",
- "@radix-ui/react-dropdown-menu": "^2.1.1",
+ "@radix-ui/react-accordion": "^1.2.3",
+ "@radix-ui/react-alert-dialog": "^1.1.6",
+ "@radix-ui/react-avatar": "^1.1.3",
+ "@radix-ui/react-checkbox": "^1.1.4",
+ "@radix-ui/react-collapsible": "^1.1.3",
+ "@radix-ui/react-dialog": "^1.1.6",
+ "@radix-ui/react-dropdown-menu": "^2.1.6",
"@radix-ui/react-hover-card": "1.1.6",
"@radix-ui/react-icons": "^1.3.2",
- "@radix-ui/react-label": "^2.1.0",
- "@radix-ui/react-navigation-menu": "^1.2.1",
- "@radix-ui/react-popover": "^1.1.1",
- "@radix-ui/react-progress": "^1.1.0",
- "@radix-ui/react-scroll-area": "^1.2.2",
- "@radix-ui/react-select": "^2.1.2",
- "@radix-ui/react-separator": "^1.1.0",
+ "@radix-ui/react-label": "^2.1.2",
+ "@radix-ui/react-navigation-menu": "^1.2.5",
+ "@radix-ui/react-popover": "^1.1.6",
+ "@radix-ui/react-progress": "^1.1.2",
+ "@radix-ui/react-scroll-area": "^1.2.3",
+ "@radix-ui/react-select": "^2.1.6",
+ "@radix-ui/react-separator": "^1.1.2",
"@radix-ui/react-slot": "^1.1.2",
- "@radix-ui/react-switch": "^1.1.1",
- "@radix-ui/react-tabs": "^1.1.2",
- "@radix-ui/react-tooltip": "^1.1.3",
+ "@radix-ui/react-switch": "^1.1.3",
+ "@radix-ui/react-tabs": "^1.1.3",
+ "@radix-ui/react-tooltip": "^1.1.8",
"@react-email/components": "0.0.31",
"@stripe/react-stripe-js": "^2.8.1",
"@stripe/stripe-js": "^4.8.0",
@@ -73,7 +73,7 @@
"framer-motion": "^11.18.1",
"lodash": "^4.17.21",
"lowlight": "^3.1.0",
- "lucide-react": "^0.439.0",
+ "lucide-react": "^0.477.0",
"mini-svg-data-uri": "^1.4.4",
"motion": "^11.12.0",
"nanoid": "^5.0.9",
@@ -93,7 +93,7 @@
"react-intersection-observer": "9.15.1",
"react-markdown": "^9.0.3",
"react-timer-hook": "^3.0.7",
- "recharts": "^2.13.0-alpha.5",
+ "recharts": "^2.15.1",
"rehype-autolink-headings": "^7.1.0",
"rehype-pretty-code": "^0.14.0",
"rehype-slug": "^6.0.0",
@@ -102,8 +102,7 @@
"shiki": "^1.24.4",
"sonner": "^1.5.0",
"stripe": "^17.2.1",
- "tailwind-container-break-out": "^2.0.9",
- "tailwind-merge": "^2.6.0",
+ "tailwind-merge": "^3.0.2",
"tailwindcss-animate": "^1.0.7",
"uniqid": "^5.4.0",
"unist-util-visit": "^5.0.0",
@@ -123,7 +122,6 @@
"@types/uniqid": "^5.3.4",
"eslint": "^8",
"eslint-config-next": "14.2.9",
- "fluid-tailwind": "1.0.4",
"knip": "^5.41.1",
"postcss": "^8.4.47",
"postcss-preset-mantine": "^1.17.0",
diff --git a/src/app/(marketing)/layout.tsx b/src/app/(marketing)/layout.tsx
index 660a95ae6..dcd09196b 100644
--- a/src/app/(marketing)/layout.tsx
+++ b/src/app/(marketing)/layout.tsx
@@ -35,7 +35,7 @@ export default function Layout({
-
+
diff --git a/src/app/globals.css b/src/app/globals.css
index 223266a47..769b77b7f 100644
--- a/src/app/globals.css
+++ b/src/app/globals.css
@@ -180,49 +180,80 @@
}
}
-@layer base {
- :root {
- --background: hsl(0 0% 100%);
- --foreground: hsl(240 10% 3.9%);
- --card: hsl(0 0% 5% 1);
- --card-foreground: hsl(240 10% 3.9%);
- --popover: hsl(0 0% 100%);
- --popover-foreground: hsl(240 10% 3.9%);
- --primary: hsl(240 5.9% 10%);
- --primary-foreground: hsl(0 0% 98%);
- --secondary: hsl(240 4.8% 95.9%);
- --secondary-foreground: hsl(240 5.9% 10%);
- --muted: 240 4.8% 95.9%;
- --muted-foreground: 240 3.8% 46.1%;
- --accent: 237 59.3% 60%;
- --accent-foreground: 240 5.9% 10%;
- --destructive: 0 84.2% 60.2%;
- --destructive-foreground: 0 0% 98%;
- --border: 240 5.9% 90%;
- --input: 240 5.9% 90%;
- --ring: 240 10% 3.9%;
- --chart-1: 12 76% 61%;
- --chart-2: 173 58% 39%;
- --chart-3: 197 37% 24%;
- --chart-4: 43 74% 66%;
- --chart-5: 27 87% 67%;
- --radius: 0.5rem;
- --sidebar-background: 0 0% 7%;
- --sidebar-foreground: 240 4.8% 95.9%;
- --sidebar-primary: 224.3 76.3% 48%;
- --sidebar-primary-foreground: 0 0% 100%;
- --sidebar-accent: 240 3.7% 15.9%;
- --sidebar-accent-foreground: 240 4.8% 95.9%;
- --sidebar-border: 240 3.7% 15.9%;
- --sidebar-ring: 217.2 91.2% 59.8%;
- --mantine-color-text: var(--foreground) !important;
- --mantine-color-red-6: var(--foreground) !important;
- --mantine-primary-color-filled: rgb(94, 102, 214) !important;
- --mantine-primary-color-filled-hover: rgb(94, 102, 214, 0.5) !important;
- --mantine-primary-color-light: rgba(94, 102, 214, 0.1) !important;
- --mantine-primary-color-light-hover: rgba(94, 102, 214, 0.12) !important;
- --mantine-color-gray-0: var(--background) !important;
- }
+:root {
+ --background: hsl(0 0% 100%);
+ --foreground: hsl(240 10% 3.9%);
+ --card: hsl(0 0% 5% / 1);
+ --card-foreground: hsl(240 10% 3.9%);
+ --popover: hsl(0 0% 100%);
+ --popover-foreground: hsl(240 10% 3.9%);
+ --primary: hsl(240 5.9% 10%);
+ --primary-foreground: hsl(0 0% 98%);
+ --secondary: hsl(240 4.8% 95.9%);
+ --secondary-foreground: hsl(240 5.9% 10%);
+ --muted: hsl(240 4.8% 95.9%);
+ --muted-foreground: hsl(240 3.8% 46.1%);
+ --accent: hsl(237 59.3% 60%);
+ --accent-foreground: hsl(240 5.9% 10%);
+ --destructive: hsl(0 84.2% 60.2%);
+ --destructive-foreground: hsl(0 0% 98%);
+ --border: hsl(240 5.9% 90%);
+ --input: hsl(240 5.9% 90%);
+ --ring: hsl(240 10% 3.9%);
+ --chart-1: hsl(12 76% 61%);
+ --chart-2: hsl(173 58% 39%);
+ --chart-3: hsl(197 37% 24%);
+ --chart-4: hsl(43 74% 66%);
+ --chart-5: hsl(27 87% 67%);
+}
+
+.dark {
+ --background: hsl(0 0% 3.9%);
+ --foreground: hsl(0 0% 98%);
+ --card: hsl(0 0% 3.9%);
+ --card-foreground: hsl(0 0% 98%);
+ --popover: hsl(0 0% 3.9%);
+ --popover-foreground: hsl(0 0% 98%);
+ --primary: hsl(0 0% 98%);
+ --primary-foreground: hsl(240 5.9% 10%);
+ --secondary: hsl(240 3.7% 15.9%);
+ --secondary-foreground: hsl(0 0% 98%);
+ --muted: hsl(240 3.7% 15.9%);
+ --muted-foreground: hsl(240 5% 64.9%);
+ --accent: hsl(237 59.3% 60%);
+ --accent-foreground: hsl(0 0% 98%);
+ --destructive: hsl(0 62.8% 30.6%);
+ --destructive-foreground: hsl(0 0% 98%);
+ --border: hsl(240 3.7% 15.9%);
+ --input: hsl(240 3.7% 15.9%);
+ --ring: hsl(240 4.9% 83.9%);
+}
+
+@theme inline {
+ --color-background: var(--background);
+ --color-foreground: var(--foreground);
+ --color-card: var(--card);
+ --color-card-foreground: var(--card-foreground);
+ --color-popover: var(--popover);
+ --color-popover-foreground: var(--popover-foreground);
+ --color-primary: var(--primary);
+ --color-primary-foreground: var(--primary-foreground);
+ --color-secondary: var(--secondary);
+ --color-secondary-foreground: var(--secondary-foreground);
+ --color-muted: var(--muted);
+ --color-muted-foreground: var(--muted-foreground);
+ --color-accent: var(--accent);
+ --color-accent-foreground: var(--accent-foreground);
+ --color-destructive: var(--destructive);
+ --color-destructive-foreground: var(--destructive-foreground);
+ --color-border: var(--border);
+ --color-input: var(--input);
+ --color-ring: var(--ring);
+ --color-chart-1: var(--chart-1);
+ --color-chart-2: var(--chart-2);
+ --color-chart-3: var(--chart-3);
+ --color-chart-4: var(--chart-4);
+ --color-chart-5: var(--chart-5);
}
@layer base {
@@ -241,6 +272,10 @@
h6 {
@apply font-onest font-medium!;
}
+
+ .text-gradient {
+ @apply bg-clip-text text-transparent bg-linear-to-b;
+ }
}
@layer utilities {
diff --git a/src/app/layout.tsx b/src/app/layout.tsx
index 21eed0993..f1ed9bf8a 100644
--- a/src/app/layout.tsx
+++ b/src/app/layout.tsx
@@ -1,4 +1,5 @@
import { ReactQueryClientProvider } from '@/components/shared/react-query-client-provider';
+import { ThemeProvider } from '@/components/providers/theme-provider';
import { OnestFont } from './styles/fonts/font';
import { UbuntuFont } from './styles/fonts/font';
import { SatoshiFont } from './styles/fonts/font';
@@ -8,12 +9,12 @@ import './globals.css';
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
-
+
- {children}
+ {children}
diff --git a/src/components/providers/theme-provider.tsx b/src/components/providers/theme-provider.tsx
new file mode 100644
index 000000000..0e739c40d
--- /dev/null
+++ b/src/components/providers/theme-provider.tsx
@@ -0,0 +1,31 @@
+'use client';
+
+import { ThemeProvider as NextThemesProvider } from 'next-themes';
+import { type ThemeProviderProps } from 'next-themes/dist/types';
+import { useEffect, useState } from 'react';
+
+export function ThemeProvider({ children, ...props }: ThemeProviderProps) {
+ const [mounted, setMounted] = useState(false);
+
+ // Ensure this component only renders on the client to avoid hydration mismatch
+ useEffect(() => {
+ setMounted(true);
+ }, []);
+
+ if (!mounted) {
+ return <>{children}>;
+ }
+
+ return (
+
+ {children}
+
+ );
+}
diff --git a/src/components/ui/bento-grid.tsx b/src/components/ui/bento-grid.tsx
index 072ac7145..b084e860b 100644
--- a/src/components/ui/bento-grid.tsx
+++ b/src/components/ui/bento-grid.tsx
@@ -60,7 +60,7 @@ export const BentoGridItem = ({
};
const baseClasses = cn(
- 'rounded-xl group/bento overflow-hidden hover:shadow-xl transition duration-200 shadow-input border border-black-50 justify-between flex flex-col',
+ 'rounded-xl group/bento overflow-hidden hover:shadow-xl transition duration-200 shadow-black border border-black-50 justify-between flex flex-col',
header || title || description || icon ? 'space-y-3 md:space-y-4' : '',
className,
padded ? 'p-3 md:p-4' : ''
diff --git a/src/types/lucide-react.d.ts b/src/types/lucide-react.d.ts
new file mode 100644
index 000000000..0581cbbb6
--- /dev/null
+++ b/src/types/lucide-react.d.ts
@@ -0,0 +1,8 @@
+declare module 'lucide-react' {
+ import { ComponentType, SVGProps } from 'react';
+ export type Icon = ComponentType>;
+
+ export const ArrowRight: Icon;
+ export const ChevronRight: Icon;
+ // Add other icons as needed
+}
diff --git a/tailwind.config.ts b/tailwind.config.ts
index 931e38e5e..41b1e00a5 100644
--- a/tailwind.config.ts
+++ b/tailwind.config.ts
@@ -1,38 +1,15 @@
import type { Config } from 'tailwindcss';
-import fluid, { extract, screens, fontSize } from 'fluid-tailwind';
-
-const svgToDataUri = require('mini-svg-data-uri');
-
-const { default: flattenColorPalette } = require('tailwindcss/lib/util/flattenColorPalette');
+import svgToDataUri from 'mini-svg-data-uri';
const config = {
- darkMode: ['class'],
- content: {
- files: [
- './src/pages/**/*.{js,ts,jsx,tsx,mdx}',
- './src/components/**/*.{js,ts,jsx,tsx,mdx}',
- './src/app/**/*.{js,ts,jsx,tsx,mdx}',
- './node_modules/onborda/dist/**/*.{js,ts,jsx,tsx}',
- ],
- extract,
- },
- safelist: [
- 'bg-yellow',
- 'hover:bg-yellow',
- 'text-yellow',
- 'hover:text-yellow',
- 'border-yellow',
- 'hover:border-yellow',
- 'bg-blue',
- 'hover:bg-blue',
- 'text-blue',
- 'hover:text-blue',
- 'border-blue',
- 'hover:border-blue',
+ darkMode: 'class',
+ content: [
+ './src/pages/**/*.{js,ts,jsx,tsx,mdx}',
+ './src/components/**/*.{js,ts,jsx,tsx,mdx}',
+ './src/app/**/*.{js,ts,jsx,tsx,mdx}',
+ './node_modules/onborda/dist/**/*.{js,ts,jsx,tsx}',
],
theme: {
- screens,
- fontSize,
extend: {
fontFamily: {
inter: ['var(--font-inter)'],
@@ -40,6 +17,23 @@ const config = {
ubuntu: ['var(--font-ubuntu)'],
onest: ['var(--font-onest)'],
},
+ container: {
+ center: true,
+ padding: {
+ DEFAULT: '1rem',
+ sm: '2rem',
+ lg: '4rem',
+ xl: '5rem',
+ '2xl': '6rem',
+ },
+ screens: {
+ sm: '640px',
+ md: '768px',
+ lg: '1024px',
+ xl: '1280px',
+ '2xl': '1400px',
+ },
+ },
colors: {
background: 'hsl(var(--background))',
foreground: 'hsl(var(--foreground))',
@@ -108,13 +102,6 @@ const config = {
ring: 'hsl(var(--sidebar-ring))',
},
},
- container: {
- center: true,
- padding: '2rem',
- screens: {
- '2xl': '1400px',
- },
- },
borderRadius: {
lg: 'var(--radius)',
md: 'calc(var(--radius) - 2px)',
@@ -202,45 +189,52 @@ const config = {
},
},
},
- plugins: [],
+ plugins: [require('tailwindcss-animate'), addRootVariables, addBackgroundUtilities],
} satisfies Config;
-function addMatchUtils({ matchUtilities, theme }: any) {
+// Updated utility functions for Tailwind v4
+function addBackgroundUtilities({ matchUtilities, theme }: { matchUtilities: any; theme: any }) {
matchUtilities(
{
- 'bg-grid': (value: any) => ({
+ 'bg-grid': (value: string) => ({
backgroundImage: `url("${svgToDataUri(
` `
)}")`,
}),
- 'bg-grid-small': (value: any) => ({
+ 'bg-grid-small': (value: string) => ({
backgroundImage: `url("${svgToDataUri(
` `
)}")`,
}),
- 'bg-dot': (value: any) => ({
+ 'bg-dot': (value: string) => ({
backgroundImage: `url("${svgToDataUri(
` `
)}")`,
}),
- 'bg-dot-thick': (value: any) => ({
+ 'bg-dot-thick': (value: string) => ({
backgroundImage: `url("${svgToDataUri(
` `
)}")`,
}),
},
- { values: flattenColorPalette(theme('backgroundColor')), type: 'color' }
+ { values: theme('backgroundColor') }
);
}
-function addVariablesForColors({ addBase, theme }: any) {
- let allColors = flattenColorPalette(theme('colors'));
- let newVars = Object.fromEntries(
- Object.entries(allColors).map(([key, val]) => [`--${key}`, val])
- );
+// Create CSS variables from theme colors
+function addRootVariables({ addBase, theme }: { addBase: any; theme: any }) {
+ const colors = theme('colors') || {};
+ const colorEntries = Object.entries(colors).flatMap(([key, value]) => {
+ if (typeof value === 'object' && value !== null) {
+ return Object.entries(value).map(([shade, color]) => {
+ return [`--${key}${shade === 'DEFAULT' ? '' : `-${shade}`}`, color];
+ });
+ }
+ return [[`--${key}`, value]];
+ });
addBase({
- ':root': newVars,
+ ':root': Object.fromEntries(colorEntries),
});
}
From c473621f8d5239d0fd32eb9c8fcebdef5532a722 Mon Sep 17 00:00:00 2001
From: Logan Ford <110533855+Logannford@users.noreply.github.com>
Date: Fri, 28 Feb 2025 23:54:43 +0000
Subject: [PATCH 6/8] more progress (this is a nightmare, thanks tailwind <3)
---
src/app/(app)/layout.tsx | 4 +++-
src/app/(no_nav)/layout.tsx | 2 +-
src/app/(questions)/question/[slug]/layout.tsx | 2 +-
src/app/globals.css | 15 ++++++++++-----
src/app/layout.tsx | 2 +-
.../marketing/global/blocks/question-marquee.tsx | 6 +++---
src/components/ui/button.tsx | 2 +-
src/components/ui/marquee.tsx | 2 +-
src/components/ui/resizable-layout.tsx | 2 +-
src/types/lucide-react.d.ts | 8 --------
10 files changed, 22 insertions(+), 23 deletions(-)
delete mode 100644 src/types/lucide-react.d.ts
diff --git a/src/app/(app)/layout.tsx b/src/app/(app)/layout.tsx
index 2c56c6888..b0be849ed 100644
--- a/src/app/(app)/layout.tsx
+++ b/src/app/(app)/layout.tsx
@@ -51,7 +51,9 @@ export default async function RootLayout({ children }: { children: React.ReactNo
- {children}
+
+ {children}
+
diff --git a/src/app/(no_nav)/layout.tsx b/src/app/(no_nav)/layout.tsx
index 5c1a22745..f71c027c0 100644
--- a/src/app/(no_nav)/layout.tsx
+++ b/src/app/(no_nav)/layout.tsx
@@ -16,7 +16,7 @@ export default function Layout({
suppressHydrationWarning
>
{/* Scrollable content */}
- {children}
+ {children}
diff --git a/src/app/(questions)/question/[slug]/layout.tsx b/src/app/(questions)/question/[slug]/layout.tsx
index 6de780dd9..7e8e1c21f 100644
--- a/src/app/(questions)/question/[slug]/layout.tsx
+++ b/src/app/(questions)/question/[slug]/layout.tsx
@@ -141,7 +141,7 @@ export default async function QuestionUidLayout({
userAnswered={userAnswered}
suggestedQuestions={suggestedQuestions}
>
-
+
diff --git a/src/app/globals.css b/src/app/globals.css
index 769b77b7f..db75a29a9 100644
--- a/src/app/globals.css
+++ b/src/app/globals.css
@@ -205,6 +205,7 @@
--chart-3: hsl(197 37% 24%);
--chart-4: hsl(43 74% 66%);
--chart-5: hsl(27 87% 67%);
+ --radius: 0.5rem;
}
.dark {
@@ -214,10 +215,10 @@
--card-foreground: hsl(0 0% 98%);
--popover: hsl(0 0% 3.9%);
--popover-foreground: hsl(0 0% 98%);
- --primary: hsl(0 0% 98%);
- --primary-foreground: hsl(240 5.9% 10%);
- --secondary: hsl(240 3.7% 15.9%);
- --secondary-foreground: hsl(0 0% 98%);
+ --primary: hsl(240 5.9% 10%);
+ --primary-foreground: hsl(0 0% 98%);
+ --secondary: hsl(240 4.8% 95.9%);
+ --secondary-foreground: hsl(240 5.9% 10%);
--muted: hsl(240 3.7% 15.9%);
--muted-foreground: hsl(240 5% 64.9%);
--accent: hsl(237 59.3% 60%);
@@ -270,7 +271,11 @@
h4,
h5,
h6 {
- @apply font-onest font-medium!;
+ @apply font-onest font-medium! text-white;
+ }
+
+ p {
+ @apply text-white;
}
.text-gradient {
diff --git a/src/app/layout.tsx b/src/app/layout.tsx
index f1ed9bf8a..5406d0ed3 100644
--- a/src/app/layout.tsx
+++ b/src/app/layout.tsx
@@ -11,7 +11,7 @@ export default function RootLayout({ children }: { children: React.ReactNode })
{children}
diff --git a/src/components/marketing/global/blocks/question-marquee.tsx b/src/components/marketing/global/blocks/question-marquee.tsx
index 09c6ab8e0..8efa9aae0 100644
--- a/src/components/marketing/global/blocks/question-marquee.tsx
+++ b/src/components/marketing/global/blocks/question-marquee.tsx
@@ -111,7 +111,7 @@ export default function QuestionMarquee({
return (
@@ -140,8 +140,8 @@ export default function QuestionMarquee({
))}
-
-
+
+
);
diff --git a/src/components/ui/button.tsx b/src/components/ui/button.tsx
index 2e9c3cc83..c89f3ac66 100644
--- a/src/components/ui/button.tsx
+++ b/src/components/ui/button.tsx
@@ -20,7 +20,7 @@ export interface ButtonProps extends VariantProps
{
}
const buttonVariants = cva(
- 'inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-hidden focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 font-onest',
+ 'inline-flex items-center justify-center whitespace-nowrap rounded-lg text-sm font-medium transition-colors focus-visible:outline-hidden focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 font-onest',
{
variants: {
variant: {
diff --git a/src/components/ui/marquee.tsx b/src/components/ui/marquee.tsx
index 2f7ce1ac5..96f18c98c 100644
--- a/src/components/ui/marquee.tsx
+++ b/src/components/ui/marquee.tsx
@@ -45,7 +45,7 @@ export default function Marquee({
= ({
return (
>;
-
- export const ArrowRight: Icon;
- export const ChevronRight: Icon;
- // Add other icons as needed
-}
From 0159bd4857448d30f0e96c6419c9c463a8416212 Mon Sep 17 00:00:00 2001
From: Logan Ford <110533855+Logannford@users.noreply.github.com>
Date: Sat, 1 Mar 2025 23:53:02 +0000
Subject: [PATCH 7/8] chore: starting to amend breaking changes from v3 -> v4
---
src/actions/ai/questions/question-help.ts | 22 +++++--------------
.../(roadmaps)/roadmaps/page.tsx | 4 ++--
src/app/(app)/providers.tsx | 2 +-
src/components/shared/hero.tsx | 6 ++++-
4 files changed, 13 insertions(+), 21 deletions(-)
diff --git a/src/actions/ai/questions/question-help.ts b/src/actions/ai/questions/question-help.ts
index 335e8283e..d8d42ff0b 100644
--- a/src/actions/ai/questions/question-help.ts
+++ b/src/actions/ai/questions/question-help.ts
@@ -40,7 +40,7 @@ export const generateQuestionHelp = async (
if (!user) {
console.error('User not found');
return {
- object: null,
+ object: 'User not found',
content: null,
tokensUsed: 0,
};
@@ -52,7 +52,7 @@ export const generateQuestionHelp = async (
if (!hasTokens) {
console.error('User does not have enough tokens');
return {
- object: null,
+ object: 'User does not have enough tokens',
content: null,
tokensUsed: 0,
};
@@ -94,7 +94,7 @@ export const generateQuestionHelp = async (
if (!question) {
console.error('No question found');
return {
- object: null,
+ object: 'No question found',
content: null,
tokensUsed: 0,
};
@@ -112,7 +112,7 @@ export const generateQuestionHelp = async (
const deducted = await deductUserTokens(user);
if (!deducted) {
return {
- object: null,
+ object: 'Cannot deduct tokens',
content: null,
tokensUsed: 0,
};
@@ -179,17 +179,5 @@ export const generateQuestionHelp = async (
}
})();
- // Determine token count for the response
- const tokensUsed =
- questionType === 'regular'
- ? user.aiQuestionHelpTokens
- ? user.aiQuestionHelpTokens - 1
- : 0
- : Number.POSITIVE_INFINITY;
-
- return {
- object: stream.value,
- content: null,
- tokensUsed: tokensUsed,
- };
+ return { object: stream.value };
};
diff --git a/src/app/(app)/(default_layout)/(roadmaps)/roadmaps/page.tsx b/src/app/(app)/(default_layout)/(roadmaps)/roadmaps/page.tsx
index 2aecd9f90..21c8e172d 100644
--- a/src/app/(app)/(default_layout)/(roadmaps)/roadmaps/page.tsx
+++ b/src/app/(app)/(default_layout)/(roadmaps)/roadmaps/page.tsx
@@ -129,8 +129,8 @@ export default async function ExploreQuestionsPage() {
dangerouslySetInnerHTML={{ __html: JSON.stringify(jsonLd) }}
/>
-
-
+
+
{Object.entries(studyPathsByCategory).map(([category, paths]) => (
diff --git a/src/app/(app)/providers.tsx b/src/app/(app)/providers.tsx
index e8aa50a8b..63d9e0e6c 100644
--- a/src/app/(app)/providers.tsx
+++ b/src/app/(app)/providers.tsx
@@ -7,7 +7,7 @@ export default function RootProvider({ children }: { children: React.ReactNode }
return (
-
+
{chip}
{typeof heading === 'string' ? (
From a93a679b7b400aafb43107a86e741db2ba31a902 Mon Sep 17 00:00:00 2001
From: Logan Ford <110533855+Logannford@users.noreply.github.com>
Date: Sun, 2 Mar 2025 16:13:32 +0000
Subject: [PATCH 8/8] progress with v4, but an absolute nightmare.
---
src/app/globals.css | 4 ++++
.../app/navigation/sidebar-footer.tsx | 2 +-
.../app/navigation/sidebar-submenu-item.tsx | 6 +++--
src/components/app/navigation/sidebar.tsx | 23 ++++++++++++-------
.../code-editor/test-case-section.tsx | 4 ++--
.../single/layout/change-code-theme.tsx | 2 +-
.../single/layout/question-action-buttons.tsx | 17 +++++++-------
.../app/shared/question/question-tabs.tsx | 2 +-
src/components/ui/icons/document.tsx | 2 +-
src/components/ui/profile-picture.tsx | 2 +-
src/components/ui/sidebar.tsx | 13 +++++------
11 files changed, 45 insertions(+), 32 deletions(-)
diff --git a/src/app/globals.css b/src/app/globals.css
index db75a29a9..01f4ea452 100644
--- a/src/app/globals.css
+++ b/src/app/globals.css
@@ -278,6 +278,10 @@
@apply text-white;
}
+ span {
+ @apply text-white;
+ }
+
.text-gradient {
@apply bg-clip-text text-transparent bg-linear-to-b;
}
diff --git a/src/components/app/navigation/sidebar-footer.tsx b/src/components/app/navigation/sidebar-footer.tsx
index 3c0a0eb48..3c17f47f6 100644
--- a/src/components/app/navigation/sidebar-footer.tsx
+++ b/src/components/app/navigation/sidebar-footer.tsx
@@ -14,7 +14,7 @@ export default function SidebarFooter({ user }: SidebarFooterProps) {
const pathname = usePathname();
return (
-
+
{!user && (
diff --git a/src/components/app/navigation/sidebar-submenu-item.tsx b/src/components/app/navigation/sidebar-submenu-item.tsx
index 8dd9aa7a4..fc34fe358 100644
--- a/src/components/app/navigation/sidebar-submenu-item.tsx
+++ b/src/components/app/navigation/sidebar-submenu-item.tsx
@@ -23,8 +23,10 @@ export default function AppSidebarSubMenuItem(opts: { item: SidebarItem }) {
{subItem.title}
diff --git a/src/components/app/navigation/sidebar.tsx b/src/components/app/navigation/sidebar.tsx
index 0149e2e12..db91c8d33 100644
--- a/src/components/app/navigation/sidebar.tsx
+++ b/src/components/app/navigation/sidebar.tsx
@@ -43,6 +43,7 @@ const LeaderboardIcon = () => (
const roadmapIcon = () => ;
const houseIcon = () => ;
+const documentIcon = () => ;
interface AppSidebarProps {
user: UserRecord | null;
@@ -73,7 +74,7 @@ export function AppSidebar({ user, profile, suggestion }: AppSidebarProps) {
{
title: 'Challenges',
url: '/questions',
- icon: Document,
+ icon: documentIcon,
tooltip: 'Challenges',
},
{
@@ -133,7 +134,7 @@ export function AppSidebar({ user, profile, suggestion }: AppSidebarProps) {
{
title: 'Challenges',
url: '/questions',
- icon: Document,
+ icon: documentIcon,
tooltip: 'Challenges',
},
{
@@ -265,7 +266,7 @@ export function AppSidebar({ user, profile, suggestion }: AppSidebarProps) {
if ('groupLabel' in item) {
return (
-
+
{item.groupLabel}
@@ -279,7 +280,11 @@ export function AppSidebar({ user, profile, suggestion }: AppSidebarProps) {
{state === 'collapsed' ? (
-
+
{item.icon && }
{item.title}
@@ -292,7 +297,7 @@ export function AppSidebar({ user, profile, suggestion }: AppSidebarProps) {
) : (
-
+
{item.icon &&
}
{item.title}
@@ -320,7 +325,7 @@ export function AppSidebar({ user, profile, suggestion }: AppSidebarProps) {
isActive={isActive(item.url)}
>
{item.disabled ? (
-
+
{item.icon &&
}
{item.title}
@@ -333,8 +338,10 @@ export function AppSidebar({ user, profile, suggestion }: AppSidebarProps) {
{item.icon && }
diff --git a/src/components/app/questions/code-editor/test-case-section.tsx b/src/components/app/questions/code-editor/test-case-section.tsx
index ff72507e6..88ee206ee 100644
--- a/src/components/app/questions/code-editor/test-case-section.tsx
+++ b/src/components/app/questions/code-editor/test-case-section.tsx
@@ -90,13 +90,13 @@ export default function TestCaseSection() {
Input:
-
+
{JSON.stringify(testCase.input[0], null, 2)}
Expected Output:
-
+
{JSON.stringify(testCase.expected, null, 2)}
diff --git a/src/components/app/questions/single/layout/change-code-theme.tsx b/src/components/app/questions/single/layout/change-code-theme.tsx
index 5ccae08e2..5c03dc051 100644
--- a/src/components/app/questions/single/layout/change-code-theme.tsx
+++ b/src/components/app/questions/single/layout/change-code-theme.tsx
@@ -27,7 +27,7 @@ export default function ChangeCodeTheme({ user }: { user: UserRecord | null }) {
return (
-
+
-
+
@@ -120,7 +120,7 @@ export default function QuestionActionButtons() {
exit={{ scale: 0.5, opacity: 0 }}
transition={{ type: 'spring', stiffness: 200, damping: 10 }}
>
-
+
) : (
-
+
)}
@@ -143,7 +143,7 @@ export default function QuestionActionButtons() {
exit={{ opacity: 0, scale: 0.8 }}
transition={{ duration: 0.2, ease: 'easeOut' }}
>
-
+
)}
@@ -156,7 +156,7 @@ export default function QuestionActionButtons() {
exit={{ opacity: 0, scale: 0.8 }}
transition={{ duration: 0.2, ease: 'easeOut' }}
>
-
+
)}
@@ -177,7 +177,7 @@ export default function QuestionActionButtons() {
{isSubmitting ? (
) : (
setActiveTab(tab.value)}
- className="flex items-center justify-center text-sm font-medium transition-colors rounded-md text-gray-400 data-[state=active]:text-white data-[state=active]:bg-transparent data-[state=active]:underline border-0 w-fit px-0"
+ className="flex items-center justify-center text-xs font-medium transition-colors rounded-md text-gray-400 data-[state=active]:text-white data-[state=active]:bg-transparent data-[state=active]:underline border-0 w-fit px-0"
>
{activeTab === tab.value ? tab.activeIcon : tab.icon}
{tab.label}
diff --git a/src/components/ui/icons/document.tsx b/src/components/ui/icons/document.tsx
index adbe21cd4..13158cd51 100644
--- a/src/components/ui/icons/document.tsx
+++ b/src/components/ui/icons/document.tsx
@@ -10,7 +10,7 @@ type iconProps = {
};
function Document(props: iconProps) {
- const fill = props.fill || 'currentColor';
+ const fill = props.fill || 'white';
const width = props.width || '1em';
const height = props.height || '1em';
const title = props.title || 'document';
diff --git a/src/components/ui/profile-picture.tsx b/src/components/ui/profile-picture.tsx
index d51de6983..0785c013d 100644
--- a/src/components/ui/profile-picture.tsx
+++ b/src/components/ui/profile-picture.tsx
@@ -20,7 +20,7 @@ export default function ProfilePicture(opts: {
className
)}
>
-
+
);
}
diff --git a/src/components/ui/sidebar.tsx b/src/components/ui/sidebar.tsx
index 6cd7aa87c..2e71129cb 100644
--- a/src/components/ui/sidebar.tsx
+++ b/src/components/ui/sidebar.tsx
@@ -493,18 +493,17 @@ const SidebarMenuItem = React.forwardRef
span:last-child]:truncate [&>svg]:size-4 [&>svg]:shrink-0',
+ 'inline-flex items-center justify-start gap-2 rounded-md px-3 py-2 text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 group/sidebar-menu-button',
{
variants: {
variant: {
- default: 'hover:bg-sidebar-accent hover:text-sidebar-accent-foreground',
- outline:
- 'bg-background shadow-[0_0_0_1px_hsl(var(--sidebar-border))] hover:bg-sidebar-accent hover:text-sidebar-accent-foreground hover:shadow-[0_0_0_1px_hsl(var(--sidebar-accent))]',
+ default: 'hover:bg-sidebar-accent hover:text-white',
+ outline: 'border border-sidebar-muted hover:bg-sidebar-accent/50 hover:text-white',
+ ghost: 'hover:bg-sidebar-accent/50 hover:text-white',
},
size: {
- default: 'h-8 text-sm',
- sm: 'h-7 text-xs',
- lg: 'h-12 text-sm group-data-[collapsible=icon]:p-0!',
+ default: 'h-10',
+ icon: 'h-9 w-9',
},
},
defaultVariants: {