diff --git a/.gitignore b/.gitignore
index 022205870..acbb2a07f 100644
--- a/.gitignore
+++ b/.gitignore
@@ -51,6 +51,7 @@ temp
.cursor
.codegraph
.superpowers
+.migration
# Local Storage Data
/data
diff --git a/apps/web/src/features/auth/layout.tsx b/apps/web/src/features/auth/layout.tsx
index 5bcfbdb7b..8eb0b1dd5 100644
--- a/apps/web/src/features/auth/layout.tsx
+++ b/apps/web/src/features/auth/layout.tsx
@@ -3,7 +3,7 @@ import { BrandIcon } from "@reactive-resume/ui/components/brand-icon";
export function AuthLayout() {
return (
-
+
-
+
);
diff --git a/apps/web/src/routes/builder/$resumeId/-sidebar/right/shared/section-base.tsx b/apps/web/src/routes/builder/$resumeId/-sidebar/right/shared/section-base.tsx
index c428bce61..bbe1ed814 100644
--- a/apps/web/src/routes/builder/$resumeId/-sidebar/right/shared/section-base.tsx
+++ b/apps/web/src/routes/builder/$resumeId/-sidebar/right/shared/section-base.tsx
@@ -38,13 +38,7 @@ export function SectionBase({ type, className, ...props }: Props) {
-
+
);
diff --git a/packages/ui/src/components/accordion.tsx b/packages/ui/src/components/accordion.tsx
index 062c1c87e..5288c1e7e 100644
--- a/packages/ui/src/components/accordion.tsx
+++ b/packages/ui/src/components/accordion.tsx
@@ -18,7 +18,7 @@ function AccordionTrigger({ className, children, ...props }: AccordionPrimitive.
svg]:pointer-events-none [&>svg]:size-3!",
+ "group/badge inline-flex h-5 w-fit shrink-0 items-center justify-center gap-1 overflow-hidden whitespace-nowrap rounded-4xl border border-transparent px-2 py-0.5 font-medium text-xs transition focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 has-data-[icon=inline-start]:ps-1.5 has-data-[icon=inline-end]:pe-1.5 aria-invalid:border-destructive aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 [&>svg]:pointer-events-none [&>svg]:size-3!",
{
variants: {
variant: {
diff --git a/packages/ui/src/components/button.tsx b/packages/ui/src/components/button.tsx
index 18afd7d0e..597253706 100644
--- a/packages/ui/src/components/button.tsx
+++ b/packages/ui/src/components/button.tsx
@@ -4,7 +4,7 @@ import { cva } from "class-variance-authority";
import { cn } from "@reactive-resume/utils/style";
const buttonVariants = cva(
- "group/button inline-flex shrink-0 select-none items-center justify-center whitespace-nowrap rounded-lg border border-transparent bg-clip-padding font-medium text-sm outline-none transition-all focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 active:not-aria-[haspopup]:translate-y-px disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 [&_svg:not([class*='size-'])]:size-4 [&_svg]:pointer-events-none [&_svg]:shrink-0",
+ "group/button inline-flex shrink-0 select-none items-center justify-center whitespace-nowrap rounded-lg border border-transparent bg-clip-padding font-medium text-sm outline-none transition focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 active:not-aria-[haspopup]:scale-[0.97] disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 [&_svg:not([class*='size-'])]:size-4 [&_svg]:pointer-events-none [&_svg]:shrink-0",
{
variants: {
variant: {
diff --git a/packages/ui/src/components/combobox.tsx b/packages/ui/src/components/combobox.tsx
index ad47e9cfe..8c2bf220f 100644
--- a/packages/ui/src/components/combobox.tsx
+++ b/packages/ui/src/components/combobox.tsx
@@ -102,7 +102,7 @@ function ComboboxContent({
data-slot="combobox-content"
data-chips={!!anchor}
className={cn(
- "group/combobox-content data-[side=bottom]:slide-in-from-top-2 data-[side=inline-end]:slide-in-from-start-2 data-[side=inline-start]:slide-in-from-end-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 data-open:fade-in-0 data-open:zoom-in-95 data-closed:fade-out-0 data-closed:zoom-out-95 relative max-h-(--available-height) w-fit min-w-[calc(var(--anchor-width)+--spacing(7))] max-w-(--available-width) origin-(--transform-origin) animate-none! overflow-hidden rounded-lg bg-popover/70 text-popover-foreground shadow-md ring-1 ring-foreground/10 duration-100 before:pointer-events-none before:absolute before:inset-0 before:-z-1 before:rounded-[inherit] before:backdrop-blur-2xl before:backdrop-saturate-150 data-[chips=true]:min-w-(--anchor-width) data-closed:animate-out data-open:animate-in **:data-[slot$=-item]:data-highlighted:bg-foreground/10 *:data-[slot=input-group]:m-1 *:data-[slot=input-group]:mb-0 *:data-[slot=input-group]:h-9 *:data-[slot=input-group]:border-input/30 **:data-[slot$=-separator]:bg-foreground/5 *:data-[slot=input-group]:bg-input/30 **:data-[variant=destructive]:**:text-accent-foreground! **:data-[variant=destructive]:text-accent-foreground! *:data-[slot=input-group]:shadow-none **:data-[slot$=-trigger]:aria-expanded:bg-foreground/10! **:data-[slot$=-item]:focus:bg-foreground/10 **:data-[slot$=-trigger]:focus:bg-foreground/10 **:data-[variant=destructive]:focus:bg-foreground/10!",
+ "group/combobox-content relative max-h-(--available-height) w-fit min-w-[calc(var(--anchor-width)+--spacing(7))] max-w-(--available-width) origin-(--transform-origin) overflow-hidden rounded-lg bg-popover/70 text-popover-foreground shadow-md ring-1 ring-foreground/10 transition-[opacity,scale] duration-150 ease-(--ease-out-strong) before:pointer-events-none before:absolute before:inset-0 before:-z-1 before:rounded-[inherit] before:backdrop-blur-2xl before:backdrop-saturate-150 data-[chips=true]:min-w-(--anchor-width) data-ending-style:scale-95 data-starting-style:scale-95 data-ending-style:opacity-0 data-starting-style:opacity-0 data-ending-style:duration-100 **:data-[slot$=-item]:data-highlighted:bg-foreground/10 *:data-[slot=input-group]:m-1 *:data-[slot=input-group]:mb-0 *:data-[slot=input-group]:h-9 *:data-[slot=input-group]:border-input/30 **:data-[slot$=-separator]:bg-foreground/5 *:data-[slot=input-group]:bg-input/30 **:data-[variant=destructive]:**:text-accent-foreground! **:data-[variant=destructive]:text-accent-foreground! *:data-[slot=input-group]:shadow-none **:data-[slot$=-trigger]:aria-expanded:bg-foreground/10! **:data-[slot$=-item]:focus:bg-foreground/10 **:data-[slot$=-trigger]:focus:bg-foreground/10 **:data-[variant=destructive]:focus:bg-foreground/10!",
className,
)}
{...props}
diff --git a/packages/ui/src/components/command.tsx b/packages/ui/src/components/command.tsx
index 346532c87..233933a4a 100644
--- a/packages/ui/src/components/command.tsx
+++ b/packages/ui/src/components/command.tsx
@@ -45,7 +45,7 @@ function CommandDialog({
{description}
{children}
diff --git a/packages/ui/src/components/context-menu.tsx b/packages/ui/src/components/context-menu.tsx
index 041144769..4c8a3fda1 100644
--- a/packages/ui/src/components/context-menu.tsx
+++ b/packages/ui/src/components/context-menu.tsx
@@ -42,7 +42,7 @@ function ContextMenuContent({
diff --git a/packages/ui/src/components/dialog.tsx b/packages/ui/src/components/dialog.tsx
index 6e3f2161b..494256a7d 100644
--- a/packages/ui/src/components/dialog.tsx
+++ b/packages/ui/src/components/dialog.tsx
@@ -25,7 +25,7 @@ function DialogOverlay({ className, ...props }: DialogPrimitive.Backdrop.Props)
{body}
diff --git a/packages/ui/src/components/hover-card.tsx b/packages/ui/src/components/hover-card.tsx
index f10ef54da..a9400619f 100644
--- a/packages/ui/src/components/hover-card.tsx
+++ b/packages/ui/src/components/hover-card.tsx
@@ -30,7 +30,7 @@ function HoverCardContent({
);
diff --git a/packages/ui/src/components/tabs.tsx b/packages/ui/src/components/tabs.tsx
index 0e4bc0c19..13babf152 100644
--- a/packages/ui/src/components/tabs.tsx
+++ b/packages/ui/src/components/tabs.tsx
@@ -15,7 +15,7 @@ function Tabs({ className, orientation = "horizontal", ...props }: TabsPrimitive
}
const tabsListVariants = cva(
- "group/tabs-list inline-flex w-fit items-center justify-center rounded-lg p-[3px] text-muted-foreground data-[variant=line]:rounded-none group-data-horizontal/tabs:h-9 group-data-vertical/tabs:h-fit group-data-vertical/tabs:flex-col",
+ "group/tabs-list relative inline-flex w-fit items-center justify-center rounded-lg p-[3px] text-muted-foreground data-[variant=line]:rounded-none group-data-horizontal/tabs:h-9 group-data-vertical/tabs:h-fit group-data-vertical/tabs:flex-col",
{
variants: {
variant: {
@@ -32,6 +32,7 @@ const tabsListVariants = cva(
function TabsList({
className,
variant = "default",
+ children,
...props
}: TabsPrimitive.List.Props & VariantProps) {
return (
@@ -40,6 +41,22 @@ function TabsList({
data-variant={variant}
className={cn(tabsListVariants({ variant }), className)}
{...props}
+ >
+ {variant === "default" && }
+ {children}
+
+ );
+}
+
+function TabsIndicator({ className, ...props }: TabsPrimitive.Indicator.Props) {
+ return (
+
);
}
@@ -49,9 +66,9 @@ function TabsTrigger({ className, ...props }: TabsPrimitive.Tab.Props) {
;
}
diff --git a/packages/ui/src/styles/globals.css b/packages/ui/src/styles/globals.css
index 830eae27a..442b768cc 100644
--- a/packages/ui/src/styles/globals.css
+++ b/packages/ui/src/styles/globals.css
@@ -85,6 +85,11 @@
@theme inline {
--font-sans: var(--font-body);
+ /* Strong easing curves — built-in CSS easings are too weak for UI motion. */
+ --ease-out-strong: cubic-bezier(0.23, 1, 0.32, 1);
+ --ease-in-out-strong: cubic-bezier(0.77, 0, 0.175, 1);
+ --ease-drawer: cubic-bezier(0.32, 0.72, 0, 1);
+
--color-background: var(--background);
--color-foreground: var(--foreground);
--color-card: var(--card);