Skip to content

Commit 04c4d8e

Browse files
committed
fix(styles): restore transition timing Tailwind was silently dropping
`tailwindcss-animate` adds a `duration-*` utility for `animation-duration`, which collides with core's `transition-duration`. For a named value Tailwind emits both rules, but for an arbitrary value it cannot pick one — so it drops the class entirely and warns. The result is 52 usages across 13 files that produced **no CSS at all**. Elements marked `transition-transform duration-[1700ms] ease-[cubic-bezier(0.22,1,0.36,1)]` had neither a duration nor an easing function: they snapped instead of animating. Most of it is the landing hero. Verified by compiling the stylesheet on both sides: transition-duration: 1700ms before=0 after=1 transition-duration: 420ms before=0 after=1 transition-duration: 175ms before=0 after=1 transition-timing-function: cubic-bezier(0.22,1,0.36,1) before=0 after=1 transition-timing-function: cubic-bezier(0.23,1,0.32,1) before=0 after=1 The stylesheet grows 1,425 bytes — exactly the rules that were missing — and the 16 ambiguity warnings on every dev start go to zero. Every usage is in a transition context (`transition-opacity`, `transition-transform`, `transition-[...]`); none sits alongside an `animate-*` utility, so `transition-duration`/`transition-timing-function` is the right half of the collision in all 52 cases.
1 parent 03649e9 commit 04c4d8e

13 files changed

Lines changed: 36 additions & 34 deletions

File tree

apps/sim/app/(landing)/components/hero/components/hero-platform-loop/hero-platform-loop.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,7 @@ export function HeroPlatformLoop() {
163163
</div>
164164
<div
165165
className={cn(
166-
'h-full shrink-0 overflow-hidden border-[var(--border)] bg-[var(--bg)] transition-[width,min-width,border-width] duration-200 ease-[cubic-bezier(0.25,0.1,0.25,1)]',
166+
'h-full shrink-0 overflow-hidden border-[var(--border)] bg-[var(--bg)] transition-[width,min-width,border-width] duration-200 [transition-timing-function:cubic-bezier(0.25,0.1,0.25,1)]',
167167
stageOpen ? 'w-1/2 border-l' : 'w-0 min-w-0 border-l-0'
168168
)}
169169
>

apps/sim/app/(landing)/components/hero/components/hero-platform-loop/hero-workflow-stage.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,7 @@ export function HeroWorkflowStage({
143143
stroke='var(--workflow-edge)'
144144
strokeWidth={2}
145145
strokeLinecap='round'
146-
className='transition-[stroke-dashoffset] duration-500 ease-[cubic-bezier(0.22,1,0.36,1)] [stroke-dasharray:1]'
146+
className='transition-[stroke-dashoffset] duration-500 [stroke-dasharray:1] [transition-timing-function:cubic-bezier(0.22,1,0.36,1)]'
147147
style={{ strokeDashoffset: visible ? 0 : 1 } as CSSProperties}
148148
/>
149149
)
@@ -156,7 +156,7 @@ export function HeroWorkflowStage({
156156
<div
157157
key={block.id}
158158
className={cn(
159-
'pointer-events-none absolute transition-[opacity,scale] duration-300 ease-[cubic-bezier(0.22,1,0.36,1)]',
159+
'pointer-events-none absolute transition-[opacity,scale] duration-300 [transition-timing-function:cubic-bezier(0.22,1,0.36,1)]',
160160
built ? 'scale-100 opacity-100' : 'scale-[0.94] opacity-0'
161161
)}
162162
style={{ left: block.x, top: block.y, width: BLOCK_WIDTH }}

apps/sim/app/(landing)/components/hero/components/hero-visual/block-handles.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ export function BlockHandles({ block, handlesVisible = true }: BlockHandlesProps
2121
<span
2222
aria-hidden
2323
className={cn(
24-
'-translate-y-1/2 absolute top-5 left-[-7px] h-5 w-[7px] rounded-l-[2px] bg-[var(--workflow-edge)] transition-opacity duration-[360ms] ease-[cubic-bezier(0.22,1,0.36,1)]',
24+
'-translate-y-1/2 absolute top-5 left-[-7px] h-5 w-[7px] rounded-l-[2px] bg-[var(--workflow-edge)] transition-opacity [transition-duration:360ms] [transition-timing-function:cubic-bezier(0.22,1,0.36,1)]',
2525
handlesVisible ? 'opacity-100' : 'opacity-0'
2626
)}
2727
/>
@@ -30,7 +30,7 @@ export function BlockHandles({ block, handlesVisible = true }: BlockHandlesProps
3030
<span
3131
aria-hidden
3232
className={cn(
33-
'-translate-y-1/2 absolute top-5 right-[-7px] h-5 w-[7px] rounded-r-[2px] bg-[var(--workflow-edge)] transition-opacity duration-[360ms] ease-[cubic-bezier(0.22,1,0.36,1)]',
33+
'-translate-y-1/2 absolute top-5 right-[-7px] h-5 w-[7px] rounded-r-[2px] bg-[var(--workflow-edge)] transition-opacity [transition-duration:360ms] [transition-timing-function:cubic-bezier(0.22,1,0.36,1)]',
3434
handlesVisible ? 'opacity-100' : 'opacity-0'
3535
)}
3636
/>

apps/sim/app/(landing)/components/hero/components/hero-visual/hero-visual.tsx

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -962,7 +962,7 @@ export function HeroVisual() {
962962
GitHub block. FOCUS is the identity transform (block 1 centered); only
963963
the pull-out animates. */}
964964
<div
965-
className='absolute inset-0 transform-gpu transition-transform duration-[1700ms] ease-[cubic-bezier(0.22,1,0.36,1)] will-change-transform'
965+
className='absolute inset-0 transform-gpu transition-transform will-change-transform [transition-duration:1700ms] [transition-timing-function:cubic-bezier(0.22,1,0.36,1)]'
966966
style={{
967967
transform: sceneTransform,
968968
transformOrigin: 'center',
@@ -971,7 +971,7 @@ export function HeroVisual() {
971971
>
972972
{showCard && (
973973
<div
974-
className='absolute inset-0 translate-y-0 scale-100 transition-opacity duration-[420ms] ease-[cubic-bezier(0.22,1,0.36,1)]'
974+
className='absolute inset-0 translate-y-0 scale-100 transition-opacity [transition-duration:420ms] [transition-timing-function:cubic-bezier(0.22,1,0.36,1)]'
975975
style={{ opacity: workflowContentFaded ? 0 : 1 }}
976976
>
977977
<div
@@ -987,7 +987,7 @@ export function HeroVisual() {
987987
// slide beats are written imperatively (a transition here would
988988
// fight the per-frame writes).
989989
(phase === 'toSend' || phase === 'zoomSend' || phase === 'answer') &&
990-
'transition-transform duration-[850ms] ease-[cubic-bezier(0.65,0,0.35,1)]'
990+
'transition-transform [transition-duration:850ms] [transition-timing-function:cubic-bezier(0.65,0,0.35,1)]'
991991
)}
992992
style={zoomStyle}
993993
>
@@ -1030,7 +1030,7 @@ export function HeroVisual() {
10301030
{/* Edges (scene space, origin = panel center). Drawn as the camera
10311031
follows the connection to each revealed block. */}
10321032
<svg
1033-
className='absolute top-1/2 left-1/2 overflow-visible transition-opacity duration-[420ms] ease-[cubic-bezier(0.22,1,0.36,1)]'
1033+
className='absolute top-1/2 left-1/2 overflow-visible transition-opacity [transition-duration:420ms] [transition-timing-function:cubic-bezier(0.22,1,0.36,1)]'
10341034
width='1'
10351035
height='1'
10361036
fill='none'
@@ -1047,7 +1047,7 @@ export function HeroVisual() {
10471047
stroke='var(--workflow-edge)'
10481048
strokeWidth={2 * WORKFLOW_FOCUS_SCALE}
10491049
strokeLinecap='round'
1050-
className='transition-[stroke-dashoffset] ease-[cubic-bezier(0.22,1,0.36,1)] [stroke-dasharray:1]'
1050+
className='transition-[stroke-dashoffset] [stroke-dasharray:1] [transition-timing-function:cubic-bezier(0.22,1,0.36,1)]'
10511051
style={
10521052
{
10531053
strokeDashoffset: drawn ? 0 : 1,
@@ -1078,7 +1078,7 @@ export function HeroVisual() {
10781078
<div
10791079
key={block.id}
10801080
className={cn(
1081-
'absolute transform-gpu transition-[opacity,transform,width,height,top,left] duration-[520ms] ease-[cubic-bezier(0.22,1,0.36,1)] will-change-transform',
1081+
'absolute transform-gpu transition-[opacity,transform,width,height,top,left] will-change-transform [transition-duration:520ms] [transition-timing-function:cubic-bezier(0.22,1,0.36,1)]',
10821082
showKbShell &&
10831083
'overflow-hidden rounded-xl border border-[var(--border-muted)] bg-[var(--surface-4)] p-[3px] shadow-[var(--shadow-overlay)]'
10841084
)}
@@ -1143,7 +1143,7 @@ export function HeroVisual() {
11431143
// GPU-promoted: its per-frame transform writes composite on their own
11441144
// layer, so the slide + dock read as smooth sub-pixel motion instead of
11451145
// jittering as the position pixel-snaps each frame.
1146-
'pointer-events-none absolute top-0 left-0 z-20 transform-gpu transition-opacity duration-300 ease-[cubic-bezier(0.23,1,0.32,1)] will-change-transform',
1146+
'pointer-events-none absolute top-0 left-0 z-20 transform-gpu transition-opacity duration-300 will-change-transform [transition-timing-function:cubic-bezier(0.23,1,0.32,1)]',
11471147
loaderFading ? 'opacity-0' : 'opacity-100'
11481148
)}
11491149
style={{ transformOrigin: '0 0' }}
@@ -1164,7 +1164,7 @@ export function HeroVisual() {
11641164

11651165
<div
11661166
ref={cursorElRef}
1167-
className='pointer-events-none absolute top-0 left-0 z-30 transition-opacity duration-200 ease-[cubic-bezier(0.23,1,0.32,1)]'
1167+
className='pointer-events-none absolute top-0 left-0 z-30 transition-opacity duration-200 [transition-timing-function:cubic-bezier(0.23,1,0.32,1)]'
11681168
style={{ opacity: showCursor ? 1 : 0 }}
11691169
>
11701170
<svg

apps/sim/app/(landing)/components/hero/components/hero-visual/stage-home.tsx

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,8 @@ interface StageHomeProps {
9898
}
9999

100100
/** Staggered enter for a chat bubble - translateY + opacity + blur, interruptible. */
101-
const ENTER_BASE = 'transition-[opacity,transform,filter] ease-[cubic-bezier(0.2,0,0,1)]'
101+
const ENTER_BASE =
102+
'transition-[opacity,transform,filter] [transition-timing-function:cubic-bezier(0.2,0,0,1)]'
102103
const enterState = (shown: boolean) =>
103104
shown ? 'translate-y-0 opacity-100 blur-0' : 'translate-y-1.5 opacity-0 blur-[3px]'
104105

@@ -220,7 +221,7 @@ export function StageHome({
220221
morphs to a block. */}
221222
<div
222223
className={cn(
223-
'overflow-hidden text-center transition-[height,opacity] duration-300 ease-[cubic-bezier(0.23,1,0.32,1)]',
224+
'overflow-hidden text-center transition-[height,opacity] duration-300 [transition-timing-function:cubic-bezier(0.23,1,0.32,1)]',
224225
mode === 'compose'
225226
? 'h-[40px] opacity-100'
226227
: mode === 'sending' || mode === 'thinking'
@@ -251,8 +252,8 @@ export function StageHome({
251252
// and read as jitter. Every other beat eases width/height/transform with
252253
// the shared curve.
253254
holdCardHeight
254-
? 'transition-[width,transform] duration-[620ms] ease-[cubic-bezier(0.22,1,0.36,1)]'
255-
: 'transition-[width,height,transform] duration-[620ms] ease-[cubic-bezier(0.22,1,0.36,1)]',
255+
? 'transition-[width,transform] [transition-duration:620ms] [transition-timing-function:cubic-bezier(0.22,1,0.36,1)]'
256+
: 'transition-[width,height,transform] [transition-duration:620ms] [transition-timing-function:cubic-bezier(0.22,1,0.36,1)]',
256257
// Nudge up to cancel the chat column's greeting+gap offset, so the
257258
// card centers exactly where the focused workflow block lands.
258259
isBlock && '-translate-y-[10px]'
@@ -282,7 +283,7 @@ export function StageHome({
282283
<div
283284
ref={contentRef}
284285
className={cn(
285-
'absolute inset-x-0 flex flex-col gap-2 px-2.5 py-2 transition-opacity duration-[220ms] ease-[cubic-bezier(0.23,1,0.32,1)]',
286+
'absolute inset-x-0 flex flex-col gap-2 px-2.5 py-2 transition-opacity [transition-duration:220ms] [transition-timing-function:cubic-bezier(0.23,1,0.32,1)]',
286287
holdCardHeight ? 'bottom-0' : 'top-0',
287288
isBlock && 'pointer-events-none opacity-0'
288289
)}
@@ -297,7 +298,7 @@ export function StageHome({
297298
<div
298299
ref={inputRef}
299300
className={cn(
300-
'min-h-[24px] px-1 py-1 font-body text-[15px] text-[var(--text-primary)] leading-[24px] tracking-[-0.015em] transition-opacity duration-200 ease-[cubic-bezier(0.23,1,0.32,1)]',
301+
'min-h-[24px] px-1 py-1 font-body text-[15px] text-[var(--text-primary)] leading-[24px] tracking-[-0.015em] transition-opacity duration-200 [transition-timing-function:cubic-bezier(0.23,1,0.32,1)]',
301302
isCompose ? 'opacity-100' : 'opacity-0',
302303
!inputInFlow && 'pointer-events-none absolute inset-x-0 top-0'
303304
)}
@@ -346,7 +347,7 @@ export function StageHome({
346347
ref={sendRef}
347348
aria-hidden='true'
348349
className={cn(
349-
'flex size-[28px] shrink-0 items-center justify-center rounded-full bg-[#383838] transition-[opacity,transform,background-color] duration-150 ease-[cubic-bezier(0.23,1,0.32,1)]',
350+
'flex size-[28px] shrink-0 items-center justify-center rounded-full bg-[#383838] transition-[opacity,transform,background-color] duration-150 [transition-timing-function:cubic-bezier(0.23,1,0.32,1)]',
350351
// Visible only while composing; once send is hit the root loader's
351352
// settled orb takes its place (it stays laid out as the loader's
352353
// measure + slide-from target).
@@ -370,7 +371,7 @@ export function StageHome({
370371
strokeLinecap='round'
371372
strokeLinejoin='round'
372373
className={cn(
373-
'transition-[stroke-dashoffset] duration-[520ms] ease-[cubic-bezier(0.23,1,0.32,1)] [stroke-dasharray:1]',
374+
'transition-[stroke-dashoffset] [stroke-dasharray:1] [transition-duration:520ms] [transition-timing-function:cubic-bezier(0.23,1,0.32,1)]',
374375
isCompose ? '[stroke-dashoffset:0]' : '[stroke-dashoffset:1]'
375376
)}
376377
/>
@@ -386,7 +387,7 @@ export function StageHome({
386387
<div
387388
aria-hidden='true'
388389
className={cn(
389-
'absolute inset-x-0 top-0 transition-opacity duration-300 ease-[cubic-bezier(0.23,1,0.32,1)]',
390+
'absolute inset-x-0 top-0 transition-opacity duration-300 [transition-timing-function:cubic-bezier(0.23,1,0.32,1)]',
390391
// Hold off until the chat content (≈220ms fade) is gone, then fade in.
391392
isBlock ? 'opacity-100 [transition-delay:280ms]' : 'pointer-events-none opacity-0'
392393
)}

apps/sim/app/(landing)/components/hero/components/hero-visual/stage-workflow.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,8 @@ export function StageWorkflow({ stage }: StageWorkflowProps) {
7777
<div
7878
className={cn(
7979
'absolute top-0 left-0',
80-
animate && 'transition-transform duration-[1700ms] ease-[cubic-bezier(0.22,1,0.36,1)]'
80+
animate &&
81+
'transition-transform [transition-duration:1700ms] [transition-timing-function:cubic-bezier(0.22,1,0.36,1)]'
8182
)}
8283
style={{
8384
width: CANVAS.width,
@@ -102,7 +103,7 @@ export function StageWorkflow({ stage }: StageWorkflowProps) {
102103
stroke='var(--workflow-edge)'
103104
strokeWidth={2}
104105
strokeLinecap='round'
105-
className='transition-[stroke-dashoffset] duration-[700ms] ease-[cubic-bezier(0.22,1,0.36,1)] [stroke-dasharray:1]'
106+
className='transition-[stroke-dashoffset] [stroke-dasharray:1] [transition-duration:700ms] [transition-timing-function:cubic-bezier(0.22,1,0.36,1)]'
106107
// Edges stay undrawn while focused; once the camera pulls out they
107108
// draw in order (the second trails the first) as each target is revealed.
108109
style={

apps/sim/app/(landing)/components/hero/components/hero-visual/workflow-block.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ export function WorkflowBlock({
2626
<div className='relative w-[250px] rounded-[13px] border border-[var(--border-1)] bg-[var(--surface-2)] shadow-sm'>
2727
<div
2828
className={cn(
29-
'transition-opacity duration-[360ms] ease-[cubic-bezier(0.22,1,0.36,1)]',
29+
'transition-opacity [transition-duration:360ms] [transition-timing-function:cubic-bezier(0.22,1,0.36,1)]',
3030
contentVisible ? 'opacity-100' : 'opacity-0'
3131
)}
3232
>

apps/sim/app/(landing)/components/landing-preview/components/landing-preview-chat/landing-preview-chat.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ export function LandingPreviewChat({ chat, chatName, animationKey }: LandingPrev
8989
<>
9090
<div
9191
className={cn(
92-
'max-w-[85%] self-end rounded-2xl bg-[var(--surface-1)] px-3.5 py-2 text-[13.5px] text-[var(--text-primary)] leading-[1.45] transition-[opacity,transform] duration-300 ease-[cubic-bezier(0.2,0,0,1)]',
92+
'max-w-[85%] self-end rounded-2xl bg-[var(--surface-1)] px-3.5 py-2 text-[13.5px] text-[var(--text-primary)] leading-[1.45] transition-[opacity,transform] duration-300 [transition-timing-function:cubic-bezier(0.2,0,0,1)]',
9393
showUser ? 'translate-y-0 opacity-100' : 'translate-y-1.5 opacity-0'
9494
)}
9595
>
@@ -101,7 +101,7 @@ export function LandingPreviewChat({ chat, chatName, animationKey }: LandingPrev
101101
{showAssistant && (
102102
<p
103103
className={cn(
104-
'max-w-[92%] text-[13.5px] text-[var(--text-primary)] leading-[1.5] transition-[opacity,transform] duration-300 ease-[cubic-bezier(0.2,0,0,1)]',
104+
'max-w-[92%] text-[13.5px] text-[var(--text-primary)] leading-[1.5] transition-[opacity,transform] duration-300 [transition-timing-function:cubic-bezier(0.2,0,0,1)]',
105105
showAssistant ? 'translate-y-0 opacity-100' : 'translate-y-1.5 opacity-0'
106106
)}
107107
>

apps/sim/app/(landing)/components/navbar/components/logo-mark/logo-mark.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ export function LogoMark({ children }: LogoMarkProps) {
5151
>
5252
<span
5353
className={cn(
54-
'relative z-10 transition-opacity duration-100 ease-[cubic-bezier(0.23,1,0.32,1)]',
54+
'relative z-10 transition-opacity duration-100 [transition-timing-function:cubic-bezier(0.23,1,0.32,1)]',
5555
hovered && 'opacity-0'
5656
)}
5757
>

apps/sim/app/(landing)/enterprise/components/enterprise-platform-loop/enterprise-platform-loop.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ export function EnterprisePlatformLoop({
113113
</div>
114114
<div
115115
className={cn(
116-
'h-full shrink-0 overflow-hidden border-[var(--border)] bg-[var(--bg)] transition-[width,min-width,border-width] duration-200 ease-[cubic-bezier(0.25,0.1,0.25,1)]',
116+
'h-full shrink-0 overflow-hidden border-[var(--border)] bg-[var(--bg)] transition-[width,min-width,border-width] duration-200 [transition-timing-function:cubic-bezier(0.25,0.1,0.25,1)]',
117117
stageOpen ? 'w-1/2 border-l' : 'w-0 min-w-0 border-l-0'
118118
)}
119119
>

0 commit comments

Comments
 (0)