@theme inline { @keyframes accordion-down { from { height: 0; } to { height: var( --radix-accordion-content-height, var(--accordion-panel-height, auto) ); } } @keyframes accordion-up { from { height: var( --radix-accordion-content-height, var(--accordion-panel-height, auto) ); } to { height: 0; } } } /* Custom variants */ @custom-variant data-open { &:where([data-state="open"]), &:where([data-open]:not([data-open="false"])) { @slot; } } @custom-variant data-closed { &:where([data-state="closed"]), &:where([data-closed]:not([data-closed="false"])) { @slot; } } @custom-variant data-checked { &:where([data-state="checked"]), &:where([data-checked]:not([data-checked="false"])) { @slot; } } @custom-variant data-unchecked { &:where([data-state="unchecked"]), &:where([data-unchecked]:not([data-unchecked="false"])) { @slot; } } @custom-variant data-selected { &:where([data-selected="true"]) { @slot; } } @custom-variant data-disabled { &:where([data-disabled="true"]), &:where([data-disabled]:not([data-disabled="false"])) { @slot; } } @custom-variant data-active { &:where([data-state="active"]), &:where([data-active]:not([data-active="false"])) { @slot; } } @custom-variant data-horizontal { &:where([data-orientation="horizontal"]) { @slot; } } @custom-variant data-vertical { &:where([data-orientation="vertical"]) { @slot; } } @utility no-scrollbar { -ms-overflow-style: none; scrollbar-width: none; &::-webkit-scrollbar { display: none; } } /* scroll-fade */ @property --scroll-fade-t { syntax: ""; inherits: false; initial-value: 0px; } @property --scroll-fade-b { syntax: ""; inherits: false; initial-value: 0px; } @property --scroll-fade-s { syntax: ""; inherits: false; initial-value: 0px; } @property --scroll-fade-e { syntax: ""; inherits: false; initial-value: 0px; } @property --scroll-fade-mask { syntax: "*"; inherits: false; } @theme inline { @keyframes scroll-fade-reveal-t { from { --scroll-fade-t: 0px; } to { --scroll-fade-t: var(--_scroll-fade-size-t, var(--scroll-fade-size, min(12%, calc(var(--spacing) * 10)))); } } @keyframes scroll-fade-reveal-b { from { --scroll-fade-b: var(--_scroll-fade-size-b, var(--scroll-fade-size, min(12%, calc(var(--spacing) * 10)))); } to { --scroll-fade-b: 0px; } } @keyframes scroll-fade-reveal-s { from { --scroll-fade-s: 0px; } to { --scroll-fade-s: var(--_scroll-fade-size-s, var(--scroll-fade-size, min(12%, calc(var(--spacing) * 10)))); } } @keyframes scroll-fade-reveal-e { from { --scroll-fade-e: var(--_scroll-fade-size-e, var(--scroll-fade-size, min(12%, calc(var(--spacing) * 10)))); } to { --scroll-fade-e: 0px; } } } @utility scroll-fade { --_scroll-fade-size-t: var( --scroll-fade-t-size, var(--scroll-fade-size, min(12%, calc(var(--spacing) * 10))) ); --_scroll-fade-size-b: var( --scroll-fade-b-size, var(--scroll-fade-size, min(12%, calc(var(--spacing) * 10))) ); --scroll-fade-block: linear-gradient( to bottom, transparent 0, #000 var(--scroll-fade-t, 0px), #000 calc(100% - var(--scroll-fade-b, 0px)), transparent 100% ); -webkit-mask-image: var(--scroll-fade-mask, var(--scroll-fade-block)); mask-image: var(--scroll-fade-mask, var(--scroll-fade-block)); -webkit-mask-composite: source-in; mask-composite: intersect; -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat; @supports (animation-timeline: scroll()) { animation: scroll-fade-reveal-t 1ms ease-in-out, scroll-fade-reveal-b 1ms ease-in-out; animation-timeline: scroll(self y), scroll(self y); animation-range: 0 var(--scroll-fade-reveal, calc(var(--spacing) * 24)), calc(100% - var(--scroll-fade-reveal, calc(var(--spacing) * 24))) 100%; animation-fill-mode: both; } @supports not (animation-timeline: scroll()) { --scroll-fade-t: var(--_scroll-fade-size-t); --scroll-fade-b: var(--_scroll-fade-size-b); } } @utility scroll-fade-y { --_scroll-fade-size-t: var( --scroll-fade-t-size, var(--scroll-fade-size, min(12%, calc(var(--spacing) * 10))) ); --_scroll-fade-size-b: var( --scroll-fade-b-size, var(--scroll-fade-size, min(12%, calc(var(--spacing) * 10))) ); --scroll-fade-block: linear-gradient( to bottom, transparent 0, #000 var(--scroll-fade-t, 0px), #000 calc(100% - var(--scroll-fade-b, 0px)), transparent 100% ); -webkit-mask-image: var(--scroll-fade-mask, var(--scroll-fade-block)); mask-image: var(--scroll-fade-mask, var(--scroll-fade-block)); -webkit-mask-composite: source-in; mask-composite: intersect; -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat; @supports (animation-timeline: scroll()) { animation: scroll-fade-reveal-t 1ms ease-in-out, scroll-fade-reveal-b 1ms ease-in-out; animation-timeline: scroll(self y), scroll(self y); animation-range: 0 var(--scroll-fade-reveal, calc(var(--spacing) * 24)), calc(100% - var(--scroll-fade-reveal, calc(var(--spacing) * 24))) 100%; animation-fill-mode: both; } @supports not (animation-timeline: scroll()) { --scroll-fade-t: var(--_scroll-fade-size-t); --scroll-fade-b: var(--_scroll-fade-size-b); } } @utility scroll-fade-x { --_scroll-fade-size-s: var( --scroll-fade-s-size, var(--scroll-fade-size, min(12%, calc(var(--spacing) * 10))) ); --_scroll-fade-size-e: var( --scroll-fade-e-size, var(--scroll-fade-size, min(12%, calc(var(--spacing) * 10))) ); --scroll-fade-inline: linear-gradient( to right, transparent 0, #000 var(--scroll-fade-s, 0px), #000 calc(100% - var(--scroll-fade-e, 0px)), transparent 100% ); &:where([dir="rtl"], [dir="rtl"] *) { --scroll-fade-inline: linear-gradient( to left, transparent 0, #000 var(--scroll-fade-s, 0px), #000 calc(100% - var(--scroll-fade-e, 0px)), transparent 100% ); } -webkit-mask-image: var(--scroll-fade-mask, var(--scroll-fade-inline)); mask-image: var(--scroll-fade-mask, var(--scroll-fade-inline)); -webkit-mask-composite: source-in; mask-composite: intersect; -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat; @supports (animation-timeline: scroll()) { animation: scroll-fade-reveal-s 1ms ease-in-out, scroll-fade-reveal-e 1ms ease-in-out; animation-timeline: scroll(self inline), scroll(self inline); animation-range: 0 var(--scroll-fade-reveal, calc(var(--spacing) * 24)), calc(100% - var(--scroll-fade-reveal, calc(var(--spacing) * 24))) 100%; animation-fill-mode: both; } @supports not (animation-timeline: scroll()) { --scroll-fade-s: var(--_scroll-fade-size-s); --scroll-fade-e: var(--_scroll-fade-size-e); } } @utility scroll-fade-t { --_scroll-fade-size-t: var( --scroll-fade-t-size, var(--scroll-fade-size, min(12%, calc(var(--spacing) * 10))) ); --scroll-fade-mask: linear-gradient( to bottom, transparent 0, #000 var(--scroll-fade-t, 0px), #000 100% ); -webkit-mask-image: var(--scroll-fade-mask); mask-image: var(--scroll-fade-mask); -webkit-mask-composite: source-in; mask-composite: intersect; -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat; @supports (animation-timeline: scroll()) { animation: scroll-fade-reveal-t 1ms ease-in-out; animation-timeline: scroll(self y); animation-range: 0 var(--scroll-fade-reveal, calc(var(--spacing) * 24)); animation-fill-mode: both; } @supports not (animation-timeline: scroll()) { --scroll-fade-t: var(--_scroll-fade-size-t); } } @utility scroll-fade-b { --_scroll-fade-size-b: var( --scroll-fade-b-size, var(--scroll-fade-size, min(12%, calc(var(--spacing) * 10))) ); --scroll-fade-mask: linear-gradient( to bottom, #000 0, #000 calc(100% - var(--scroll-fade-b, 0px)), transparent 100% ); -webkit-mask-image: var(--scroll-fade-mask); mask-image: var(--scroll-fade-mask); -webkit-mask-composite: source-in; mask-composite: intersect; -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat; @supports (animation-timeline: scroll()) { animation: scroll-fade-reveal-b 1ms ease-in-out; animation-timeline: scroll(self y); animation-range: calc( 100% - var(--scroll-fade-reveal, calc(var(--spacing) * 24)) ) 100%; animation-fill-mode: both; } @supports not (animation-timeline: scroll()) { --scroll-fade-b: var(--_scroll-fade-size-b); } } @utility scroll-fade-l { --_scroll-fade-size-s: var( --scroll-fade-s-size, var(--scroll-fade-size, min(12%, calc(var(--spacing) * 10))) ); --scroll-fade-mask: linear-gradient( to right, transparent 0, #000 var(--scroll-fade-s, 0px), #000 100% ); -webkit-mask-image: var(--scroll-fade-mask); mask-image: var(--scroll-fade-mask); -webkit-mask-composite: source-in; mask-composite: intersect; -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat; @supports (animation-timeline: scroll()) { animation: scroll-fade-reveal-s 1ms ease-in-out; animation-timeline: scroll(self x); animation-range: 0 var(--scroll-fade-reveal, calc(var(--spacing) * 24)); animation-fill-mode: both; } @supports not (animation-timeline: scroll()) { --scroll-fade-s: var(--_scroll-fade-size-s); } } @utility scroll-fade-r { --_scroll-fade-size-e: var( --scroll-fade-e-size, var(--scroll-fade-size, min(12%, calc(var(--spacing) * 10))) ); --scroll-fade-mask: linear-gradient( to right, #000 0, #000 calc(100% - var(--scroll-fade-e, 0px)), transparent 100% ); -webkit-mask-image: var(--scroll-fade-mask); mask-image: var(--scroll-fade-mask); -webkit-mask-composite: source-in; mask-composite: intersect; -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat; @supports (animation-timeline: scroll()) { animation: scroll-fade-reveal-e 1ms ease-in-out; animation-timeline: scroll(self x); animation-range: calc( 100% - var(--scroll-fade-reveal, calc(var(--spacing) * 24)) ) 100%; animation-fill-mode: both; } @supports not (animation-timeline: scroll()) { --scroll-fade-e: var(--_scroll-fade-size-e); } } @utility scroll-fade-s { --_scroll-fade-size-s: var( --scroll-fade-s-size, var(--scroll-fade-size, min(12%, calc(var(--spacing) * 10))) ); --scroll-fade-mask: linear-gradient( to right, transparent 0, #000 var(--scroll-fade-s, 0px), #000 100% ); &:where([dir="rtl"], [dir="rtl"] *) { --scroll-fade-mask: linear-gradient( to left, transparent 0, #000 var(--scroll-fade-s, 0px), #000 100% ); } -webkit-mask-image: var(--scroll-fade-mask); mask-image: var(--scroll-fade-mask); -webkit-mask-composite: source-in; mask-composite: intersect; -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat; @supports (animation-timeline: scroll()) { animation: scroll-fade-reveal-s 1ms ease-in-out; animation-timeline: scroll(self inline); animation-range: 0 var(--scroll-fade-reveal, calc(var(--spacing) * 24)); animation-fill-mode: both; } @supports not (animation-timeline: scroll()) { --scroll-fade-s: var(--_scroll-fade-size-s); } } @utility scroll-fade-e { --_scroll-fade-size-e: var( --scroll-fade-e-size, var(--scroll-fade-size, min(12%, calc(var(--spacing) * 10))) ); --scroll-fade-mask: linear-gradient( to right, #000 0, #000 calc(100% - var(--scroll-fade-e, 0px)), transparent 100% ); &:where([dir="rtl"], [dir="rtl"] *) { --scroll-fade-mask: linear-gradient( to left, #000 0, #000 calc(100% - var(--scroll-fade-e, 0px)), transparent 100% ); } -webkit-mask-image: var(--scroll-fade-mask); mask-image: var(--scroll-fade-mask); -webkit-mask-composite: source-in; mask-composite: intersect; -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat; @supports (animation-timeline: scroll()) { animation: scroll-fade-reveal-e 1ms ease-in-out; animation-timeline: scroll(self inline); animation-range: calc( 100% - var(--scroll-fade-reveal, calc(var(--spacing) * 24)) ) 100%; animation-fill-mode: both; } @supports not (animation-timeline: scroll()) { --scroll-fade-e: var(--_scroll-fade-size-e); } } @utility scroll-fade-* { --scroll-fade-size: calc(var(--spacing) * --value(integer)); --scroll-fade-size: --value([length], [percentage]); } @utility scroll-fade-t-* { --scroll-fade-t-size: calc(var(--spacing) * --value(integer)); --scroll-fade-t-size: --value([length], [percentage]); } @utility scroll-fade-b-* { --scroll-fade-b-size: calc(var(--spacing) * --value(integer)); --scroll-fade-b-size: --value([length], [percentage]); } @utility scroll-fade-s-* { --scroll-fade-s-size: calc(var(--spacing) * --value(integer)); --scroll-fade-s-size: --value([length], [percentage]); } @utility scroll-fade-e-* { --scroll-fade-e-size: calc(var(--spacing) * --value(integer)); --scroll-fade-e-size: --value([length], [percentage]); } @utility scroll-fade-none { --scroll-fade-mask: none; } /* shimmer */ @property --shimmer-angle { syntax: ""; inherits: true; initial-value: 20deg; } @property --shimmer-image { syntax: "*"; inherits: false; } @property --shimmer-text-fill { syntax: "*"; inherits: false; } @theme inline { @keyframes tw-shimmer { from { background-position: 100% 0; } to { background-position: 0 0; } } } @utility shimmer { --_spread: var(--shimmer-spread, calc(3ch + 40px)); --_base: currentColor; --_highlight: var( --shimmer-color, oklch(from currentColor l c h / calc(alpha* 0.2)) ); background-image: var( --shimmer-image, linear-gradient( calc(90deg + var(--shimmer-angle)), var(--_base) calc(50% - var(--_spread)), color-mix(in oklch, var(--_highlight), var(--_base) 50%) calc(50% - var(--_spread) * 0.5), var(--_highlight) 50%, color-mix(in oklch, var(--_highlight), var(--_base) 50%) calc(50% + var(--_spread) * 0.5), var(--_base) calc(50% + var(--_spread)) ) ); background-repeat: no-repeat; background-size: calc(200% + var(--_spread) * 2) 100%; background-position: 0 0; background-clip: text; -webkit-background-clip: text; -webkit-text-fill-color: var(--shimmer-text-fill, transparent); animation: tw-shimmer var(--shimmer-duration, 2s) linear infinite; @variant dark { --_highlight: var( --shimmer-color, oklch(from currentColor max(0.8, calc(l + 0.4)) c h / calc(alpha + 0.4)) ); } &:where([dir="rtl"], [dir="rtl"] *) { animation-direction: reverse; } } @utility shimmer-once { animation-iteration-count: 1; } @utility shimmer-reverse { animation-direction: reverse; } @utility shimmer-none { --shimmer-image: none; --shimmer-text-fill: currentColor; } @utility shimmer-color-* { --shimmer-color: --value(--color, [color]); --shimmer-color: color-mix( in oklch, --value(--color, [color]) calc(--modifier(integer) * 1%), transparent ); } @utility shimmer-duration-* { --shimmer-duration: calc(--value(integer) * 1ms); } @utility shimmer-spread-* { --shimmer-spread: calc(var(--spacing) * --value(integer)); --shimmer-spread: --value([length], [percentage]); } @utility shimmer-angle-* { --shimmer-angle: calc(--value(integer) * 1deg); } @media (prefers-reduced-motion: reduce) { .shimmer { animation: none; background-image: none; -webkit-text-fill-color: currentColor; } }