feat: enhance API and middleware functionality: add public API routes, implement program and course member checks, and improve rate limiting for invite acceptance. Update OpenAPI spec generation to focus on public API endpoints and add new middleware for automation key scopes. Include new documentation for lesson AI features and public API tests.
This commit is contained in:
@@ -2,7 +2,6 @@
|
||||
"$schema": "https://shadcn-svelte.com/schema.json",
|
||||
"style": "new-york",
|
||||
"tailwind": {
|
||||
"config": "tailwind.config.ts",
|
||||
"css": "src/app.css",
|
||||
"baseColor": "zinc"
|
||||
},
|
||||
|
||||
@@ -19,26 +19,26 @@
|
||||
"@sveltejs/adapter-auto": "^3.0.0",
|
||||
"@sveltejs/kit": "^2.9.0",
|
||||
"@sveltejs/vite-plugin-svelte": "^5.0.0",
|
||||
"autoprefixer": "^10.4.20",
|
||||
"bits-ui": "^0.21.16",
|
||||
"@tailwindcss/postcss": "^4.2.2",
|
||||
"bits-ui": "^2.16.1",
|
||||
"clsx": "^2.1.1",
|
||||
"postcss": "^8.5.6",
|
||||
"prettier": "^3.3.2",
|
||||
"prettier-plugin-svelte": "^3.2.6",
|
||||
"prettier-plugin-tailwindcss": "^0.6.5",
|
||||
"prettier-plugin-tailwindcss": "^0.7.2",
|
||||
"svelte": "^5.0.0",
|
||||
"svelte-check": "^4.0.0",
|
||||
"svelte-sonner": "^0.3.28",
|
||||
"tailwind-merge": "^2.5.5",
|
||||
"tailwind-variants": "^0.3.0",
|
||||
"tailwindcss": "^3.4.9",
|
||||
"tailwindcss": "^4.2.2",
|
||||
"typescript": "^5.0.0",
|
||||
"vite": "^6.0.0",
|
||||
"vitest": "^2.0.4"
|
||||
},
|
||||
"dependencies": {
|
||||
"@tailwindcss/container-queries": "^0.1.1",
|
||||
"@tailwindcss/forms": "^0.5.9",
|
||||
"@tailwindcss/typography": "^0.5.15",
|
||||
"@cio/ui": "workspace:*",
|
||||
"@lucide/svelte": "^0.562.0",
|
||||
"lucide-svelte": "^0.468.0",
|
||||
"mode-watcher": "^1.1.0",
|
||||
"posthog-js": "^1.180.1",
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
export default {
|
||||
plugins: {
|
||||
tailwindcss: {},
|
||||
autoprefixer: {}
|
||||
'@tailwindcss/postcss': {}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,6 +1,66 @@
|
||||
@tailwind base;
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
@import 'tailwindcss';
|
||||
@import '@cio/ui/output.css';
|
||||
@import '../../../packages/ui/src/custom/animation/marketing-layers.css';
|
||||
|
||||
@custom-variant dark (&:where(.dark, .dark *));
|
||||
|
||||
@source './**/*.{html,js,svelte,ts}';
|
||||
@source '../../../packages/ui/src/custom/animation/**/*.svelte';
|
||||
|
||||
/* Theme tokens (colors, fonts, radii, motion) + 2xl breakpoint for layout (e.g. `max-w-(--breakpoint-2xl)`). */
|
||||
@theme inline {
|
||||
--breakpoint-2xl: 1400px;
|
||||
|
||||
--font-sans:
|
||||
ui-sans-serif, system-ui, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol',
|
||||
'Noto Color Emoji';
|
||||
--font-drawn:
|
||||
Virgil, ui-sans-serif, system-ui, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji',
|
||||
'Segoe UI Symbol', 'Noto Color Emoji';
|
||||
|
||||
--radius-sm: calc(var(--radius) - 4px);
|
||||
--radius-md: calc(var(--radius) - 2px);
|
||||
--radius-lg: var(--radius);
|
||||
|
||||
--color-border: hsl(var(--border) / <alpha-value>);
|
||||
--color-input: hsl(var(--input) / <alpha-value>);
|
||||
--color-ring: hsl(var(--ring) / <alpha-value>);
|
||||
--color-background: hsl(var(--background) / <alpha-value>);
|
||||
--color-foreground: hsl(var(--foreground) / <alpha-value>);
|
||||
--color-primary: hsl(var(--primary) / <alpha-value>);
|
||||
--color-primary-foreground: hsl(var(--primary-foreground) / <alpha-value>);
|
||||
--color-secondary: hsl(var(--secondary) / <alpha-value>);
|
||||
--color-secondary-foreground: hsl(var(--secondary-foreground) / <alpha-value>);
|
||||
--color-destructive: hsl(var(--destructive) / <alpha-value>);
|
||||
--color-destructive-foreground: hsl(var(--destructive-foreground) / <alpha-value>);
|
||||
--color-muted: hsl(var(--muted) / <alpha-value>);
|
||||
--color-muted-foreground: hsl(var(--muted-foreground) / <alpha-value>);
|
||||
--color-accent: hsl(var(--accent) / <alpha-value>);
|
||||
--color-accent-foreground: hsl(var(--accent-foreground) / <alpha-value>);
|
||||
--color-popover: hsl(var(--popover) / <alpha-value>);
|
||||
--color-popover-foreground: hsl(var(--popover-foreground) / <alpha-value>);
|
||||
--color-card: hsl(var(--card) / <alpha-value>);
|
||||
--color-card-foreground: hsl(var(--card-foreground) / <alpha-value>);
|
||||
|
||||
--animate-border-beam: border-beam calc(var(--duration) * 1s) infinite linear;
|
||||
--animate-meteor: meteor 5s linear infinite;
|
||||
--animate-shimmer: shimmer 8s infinite;
|
||||
--animate-spin-around: spin-around calc(var(--speed) * 2) infinite linear;
|
||||
--animate-magicslide: magicslide var(--speed) ease-in-out infinite alternate;
|
||||
}
|
||||
|
||||
/* Used by ShinnyText (`animate-shimmer`); marketing-layers uses `shimmer-marketing` for other UIs. */
|
||||
@keyframes shimmer {
|
||||
0%,
|
||||
90%,
|
||||
100% {
|
||||
background-position: calc(-100% - var(--shimmer-width)) 0;
|
||||
}
|
||||
30%,
|
||||
60% {
|
||||
background-position: calc(100% + var(--shimmer-width)) 0;
|
||||
}
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Virgil';
|
||||
|
||||
@@ -1,48 +0,0 @@
|
||||
<script lang="ts">
|
||||
import { Motion, AnimatePresence } from 'svelte-motion';
|
||||
import { inview } from 'svelte-inview';
|
||||
import { cn } from '$lib/utils';
|
||||
|
||||
let {
|
||||
duration = 0.4,
|
||||
delay = 0,
|
||||
yOffset = 6,
|
||||
inViewMargin = '-50px',
|
||||
blur = '6px',
|
||||
once = false,
|
||||
class: className = ''
|
||||
} = $props();
|
||||
let id = $state(crypto.randomUUID().slice(0, 8));
|
||||
let isInView = $state('hidden');
|
||||
|
||||
let defaultVariants = {
|
||||
hidden: { opacity: 0, y: yOffset, filter: `blur(${blur})` },
|
||||
visible: { opacity: 1, y: 0, filter: `blur(0px)` }
|
||||
};
|
||||
</script>
|
||||
|
||||
<AnimatePresence let:item list={[{ key: id }]}>
|
||||
<Motion
|
||||
initial="hidden"
|
||||
animate={isInView}
|
||||
exit="hidden"
|
||||
variants={defaultVariants}
|
||||
transition={{
|
||||
delay: 0.04 + delay,
|
||||
duration,
|
||||
ease: 'easeOut'
|
||||
}}
|
||||
let:motion
|
||||
>
|
||||
<div
|
||||
use:inview={{ rootMargin: inViewMargin, unobserveOnEnter: once }}
|
||||
use:motion
|
||||
oninview_change={({ detail }) => {
|
||||
isInView = detail.inView ? 'visible' : 'hidden';
|
||||
}}
|
||||
class={cn(className)}
|
||||
>
|
||||
<slot>Default</slot>
|
||||
</div>
|
||||
</Motion>
|
||||
</AnimatePresence>
|
||||
@@ -1 +0,0 @@
|
||||
export { default as BlurFade } from './blurfade.svelte';
|
||||
@@ -1,36 +0,0 @@
|
||||
<script lang="ts">
|
||||
import { cn } from "$lib/utils";
|
||||
import { Motion } from "svelte-motion";
|
||||
|
||||
export let variant: {
|
||||
hidden: { filter: string; opacity: number };
|
||||
visible: { filter: string; opacity: number };
|
||||
} = {
|
||||
hidden: { filter: "blur(10px)", opacity: 0 },
|
||||
visible: { filter: "blur(0px)", opacity: 1 },
|
||||
};
|
||||
export let duration: number = 1;
|
||||
let className = "font-display text-4xl font-bold tracking-[-0.02em] drop-shadow-sm md:text-7xl md:leading-[5rem]";
|
||||
export { className as class };
|
||||
|
||||
let defaultVariants = {
|
||||
hidden: { filter: "blur(10px)", opacity: 0 },
|
||||
visible: { filter: "blur(0px)", opacity: 1 },
|
||||
};
|
||||
let combinedVariants = variant || defaultVariants;
|
||||
</script>
|
||||
|
||||
<Motion
|
||||
initial="hidden"
|
||||
animate="visible"
|
||||
transition={{ duration }}
|
||||
variants={combinedVariants}
|
||||
let:motion
|
||||
>
|
||||
<h1
|
||||
class={cn(className)}
|
||||
use:motion
|
||||
>
|
||||
<slot />
|
||||
</h1>
|
||||
</Motion>
|
||||
@@ -1 +0,0 @@
|
||||
export { default as BlurIn } from './blurin.svelte';
|
||||
@@ -1,35 +0,0 @@
|
||||
<script lang="ts">
|
||||
import { cn } from '$lib/utils';
|
||||
|
||||
export let size = 200;
|
||||
export let duration = 15;
|
||||
export let anchor = 90;
|
||||
export let borderWidth = 1.5;
|
||||
export let colorFrom = '#ffaa40';
|
||||
export let colorTo = '#9c40ff';
|
||||
export let delay = 0;
|
||||
let delaySec = delay + 's';
|
||||
|
||||
let className: any = '';
|
||||
export { className as class };
|
||||
</script>
|
||||
|
||||
<div
|
||||
style:--border-width={borderWidth}
|
||||
style:--size={size}
|
||||
style:--color-from={colorFrom}
|
||||
style:--color-to={colorTo}
|
||||
style:--delay={delaySec}
|
||||
style:--anchor={anchor}
|
||||
style:--duration={duration}
|
||||
class={cn(
|
||||
'pointer-events-none absolute inset-[0] rounded-[inherit] [border:calc(var(--border-width)*1px)_solid_transparent]',
|
||||
|
||||
// mask styles
|
||||
'![mask-clip:padding-box,border-box] ![mask-composite:intersect] [mask:linear-gradient(transparent,transparent),linear-gradient(white,white)]',
|
||||
|
||||
// pseudo styles
|
||||
'after:animate-border-beam after:absolute after:aspect-square after:w-[calc(var(--size)*1px)] after:[animation-delay:var(--delay)] after:[background:linear-gradient(to_left,var(--color-from),var(--color-to),transparent)] after:[offset-anchor:calc(var(--anchor)*1%)_50%] after:[offset-path:rect(0_auto_auto_0_round_calc(var(--size)*1px))]',
|
||||
className
|
||||
)}
|
||||
></div>
|
||||
@@ -1 +0,0 @@
|
||||
export { default as BorderBeam } from './border-beam.svelte';
|
||||
@@ -1,21 +0,0 @@
|
||||
<script lang="ts">
|
||||
import { cn } from '$lib/utils';
|
||||
|
||||
let { children, className } = $props();
|
||||
|
||||
// let cardContent = {
|
||||
// title: 'Svelte is Vibe',
|
||||
// description: 'Svelte is a fun way to build web applications.'
|
||||
// };
|
||||
</script>
|
||||
|
||||
<div class={cn('p-4 text-left', className)}>
|
||||
<!-- <h3 class="mb-1 text-lg font-bold text-gray-900 dark:text-gray-100">
|
||||
{cardContent.title}
|
||||
</h3>
|
||||
<p class="text-gray-700 dark:text-gray-300">
|
||||
{cardContent.description}
|
||||
</p> -->
|
||||
|
||||
{@render children()}
|
||||
</div>
|
||||
@@ -1,30 +0,0 @@
|
||||
<script lang="ts">
|
||||
import { cn } from '$lib/utils';
|
||||
import Ellipses from './ellipses.svelte';
|
||||
|
||||
type Props = {
|
||||
className?: string;
|
||||
};
|
||||
|
||||
let { className }: Props = $props();
|
||||
</script>
|
||||
|
||||
<div
|
||||
class={cn(
|
||||
'relative mx-auto w-full border border-dashed border-zinc-300 px-8 shadow-sm sm:px-6 md:px-8 dark:border-zinc-800 dark:bg-[#09090B]',
|
||||
className
|
||||
)}
|
||||
>
|
||||
<div
|
||||
class="absolute left-0 top-4 -z-0 h-px w-full bg-zinc-400 sm:top-6 md:top-8 dark:bg-zinc-700"
|
||||
></div>
|
||||
<div
|
||||
class="absolute bottom-4 left-0 z-0 h-px w-full bg-zinc-400 sm:bottom-6 md:bottom-8 dark:bg-zinc-700"
|
||||
></div>
|
||||
<div class="relative w-full border-x border-zinc-400 dark:border-zinc-700">
|
||||
<Ellipses />
|
||||
<div class="relative z-20 mx-auto py-8">
|
||||
<slot>Default</slot>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -1,13 +0,0 @@
|
||||
<script>
|
||||
let sharedClass =
|
||||
'rounded-full outline outline-8 dark:outline-gray-950 sm:my-6 md:my-8 size-1 my-4 outline-gray-50 bg-green-400';
|
||||
</script>
|
||||
|
||||
<div class="absolute z-0 grid h-full w-full items-center gap-8 lg:grid-cols-2">
|
||||
<section class="absolute z-0 grid h-full w-full grid-cols-2 place-content-between">
|
||||
<div class="{sharedClass} -mx-[2.5px]"></div>
|
||||
<div class="{sharedClass} -mx-[2px] place-self-end"></div>
|
||||
<div class="{sharedClass} -mx-[2.5px]"></div>
|
||||
<div class="{sharedClass} -mx-[2px] place-self-end"></div>
|
||||
</section>
|
||||
</div>
|
||||
@@ -1,2 +0,0 @@
|
||||
export { default as CardContainer } from './container.svelte';
|
||||
export { default as CardBody } from './body.svelte';
|
||||
@@ -1,37 +0,0 @@
|
||||
<script lang="ts">
|
||||
import { cn } from '$lib/utils';
|
||||
export let width: string | number = 16;
|
||||
export let height: string | number = 16;
|
||||
export let x = 0;
|
||||
export let y = 0;
|
||||
export let cx = 1;
|
||||
export let cy = 1;
|
||||
export let cr = 1;
|
||||
export let fillColor = 'rgb(163 163 163 / 0.8)';
|
||||
|
||||
let className: any = '';
|
||||
export { className as class };
|
||||
let id = crypto.randomUUID().toString().slice(0, 10); // generating a unique ID for Components
|
||||
</script>
|
||||
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
class={cn('pointer-events-none absolute inset-0 h-full w-full ', className)}
|
||||
{...$$restProps}
|
||||
fill={fillColor}
|
||||
>
|
||||
<defs>
|
||||
<pattern
|
||||
{id}
|
||||
{width}
|
||||
{height}
|
||||
patternUnits="userSpaceOnUse"
|
||||
patternContentUnits="userSpaceOnUse"
|
||||
{x}
|
||||
{y}
|
||||
>
|
||||
<circle id="pattern-circle" {cx} {cy} r={cr} />
|
||||
</pattern>
|
||||
</defs>
|
||||
<rect width="100%" height="100%" stroke-width={0} fill={`url(#${id})`} />
|
||||
</svg>
|
||||
@@ -1 +0,0 @@
|
||||
export { default as DotPattern } from './dot-pattern.svelte';
|
||||
@@ -1,42 +0,0 @@
|
||||
<script lang="ts">
|
||||
import { cn } from '$lib/utils';
|
||||
import { AnimatePresence, Motion } from 'svelte-motion';
|
||||
|
||||
let className: any = 'Gradual Spacing';
|
||||
export { className as class };
|
||||
|
||||
export let words = 'Gradual Spacing';
|
||||
export let duration = 0.5;
|
||||
export let delayMultiple = 0.04;
|
||||
export let framerProps = {
|
||||
hidden: { opacity: 0, x: -20 },
|
||||
visible: { opacity: 1, x: 0 }
|
||||
};
|
||||
let wordsspilit = words.split('');
|
||||
</script>
|
||||
|
||||
<div class="flex justify-center space-x-1">
|
||||
<AnimatePresence let:item list={[{ key: wordsspilit }]}>
|
||||
{#each wordsspilit as char, i}
|
||||
<Motion
|
||||
initial="hidden"
|
||||
animate="visible"
|
||||
exit="hidden"
|
||||
variants={framerProps}
|
||||
transition={{
|
||||
duration: duration,
|
||||
delay: i * delayMultiple
|
||||
}}
|
||||
let:motion
|
||||
>
|
||||
<span use:motion class={cn('drop-shadow-sm', className)}>
|
||||
{#if char === ' '}
|
||||
<span> </span>
|
||||
{:else}
|
||||
{char}
|
||||
{/if}
|
||||
</span>
|
||||
</Motion>
|
||||
{/each}
|
||||
</AnimatePresence>
|
||||
</div>
|
||||
@@ -1 +0,0 @@
|
||||
export { default as GradualSpacing } from './gradual-spacing.svelte';
|
||||
-193
@@ -1,193 +0,0 @@
|
||||
<script lang="ts">
|
||||
import { writable } from 'svelte/store';
|
||||
import { AnimatePresence, Motion } from 'svelte-motion';
|
||||
import { Play, X } from 'lucide-svelte';
|
||||
|
||||
type AnimationStyle =
|
||||
| 'from-bottom'
|
||||
| 'from-center'
|
||||
| 'from-top'
|
||||
| 'from-left'
|
||||
| 'from-right'
|
||||
| 'fade'
|
||||
| 'top-in-bottom-out'
|
||||
| 'left-in-right-out';
|
||||
|
||||
// interface HeroVideoProps {
|
||||
// animationStyle?: AnimationStyle;
|
||||
// videoSrc: string;
|
||||
// thumbnailSrc: string;
|
||||
// thumbnailAlt?: string;
|
||||
// }
|
||||
|
||||
export let animationStyle: AnimationStyle = 'from-center';
|
||||
export let videoSrc: string;
|
||||
export let thumbnailSrc: string;
|
||||
export let thumbnailAlt: string = 'Video thumbnail';
|
||||
export let iconColor: string = 'white';
|
||||
|
||||
const isVideoOpen = writable(false);
|
||||
const isCloseHovered = writable(false);
|
||||
const isPlayHovered = writable(false);
|
||||
|
||||
function openVideo() {
|
||||
isVideoOpen.set(true);
|
||||
}
|
||||
|
||||
function closeVideo() {
|
||||
isVideoOpen.set(false);
|
||||
}
|
||||
|
||||
let animationVariants = {
|
||||
'from-bottom': {
|
||||
initial: { y: 100, opacity: 0 },
|
||||
animate: { y: 0, opacity: 1 },
|
||||
exit: { y: 100, opacity: 0 }
|
||||
},
|
||||
'from-center': {
|
||||
initial: { scale: 0.5, opacity: 0 },
|
||||
animate: { scale: 1, opacity: 1 },
|
||||
exit: { scale: 0.5, opacity: 0 }
|
||||
},
|
||||
'from-top': {
|
||||
initial: { y: -100, opacity: 0 },
|
||||
animate: { y: 0, opacity: 1 },
|
||||
exit: { y: -100, opacity: 0 }
|
||||
},
|
||||
'from-left': {
|
||||
initial: { x: -100, opacity: 0 },
|
||||
animate: { x: 0, opacity: 1 },
|
||||
exit: { x: -100, opacity: 0 }
|
||||
},
|
||||
'from-right': {
|
||||
initial: { x: 100, opacity: 0 },
|
||||
animate: { x: 0, opacity: 1 },
|
||||
exit: { x: 100, opacity: 0 }
|
||||
},
|
||||
fade: {
|
||||
initial: { opacity: 0 },
|
||||
animate: { opacity: 1 },
|
||||
exit: { opacity: 0 }
|
||||
},
|
||||
'top-in-bottom-out': {
|
||||
initial: { y: -100, opacity: 0 },
|
||||
animate: { y: 0, opacity: 1 },
|
||||
exit: { y: 200, opacity: 0 }
|
||||
},
|
||||
'left-in-right-out': {
|
||||
initial: { x: -100, opacity: 0 },
|
||||
animate: { x: 0, opacity: 1 },
|
||||
exit: { x: 200, opacity: 0 }
|
||||
}
|
||||
};
|
||||
|
||||
$: selectedAnimation = animationVariants[animationStyle];
|
||||
</script>
|
||||
|
||||
<div class="relative">
|
||||
<!-- Thumbnail -->
|
||||
<!-- svelte-ignore a11y-no-static-element-interactions -->
|
||||
<!-- svelte-ignore a11y-click-events-have-key-events -->
|
||||
<div class="relative cursor-pointer" on:click={openVideo}>
|
||||
<img
|
||||
src={thumbnailSrc}
|
||||
alt={thumbnailAlt}
|
||||
width={1920}
|
||||
height={1080}
|
||||
class="w-full rounded-2xl transition-all duration-200"
|
||||
/>
|
||||
<!-- {$isPlayHovered===true ? 'blur-[2px]' :'' } to make background blur put this in above img class -->
|
||||
<div class="absolute inset-0 flex items-center justify-center">
|
||||
<!-- svelte-ignore a11y-no-static-element-interactions -->
|
||||
<div
|
||||
class="flex size-24 items-center justify-center rounded-full border border-neutral-400 bg-black backdrop-blur-md transition-transform duration-300 ease-out"
|
||||
on:mouseenter={() => isPlayHovered.set(true)}
|
||||
on:mouseleave={() => isPlayHovered.set(false)}
|
||||
>
|
||||
<div
|
||||
class="relative flex size-20 items-center justify-center rounded-full border border-neutral-400 bg-black backdrop-blur-2xl transition-all duration-300 ease-out"
|
||||
class:isPlayHovered={$isPlayHovered}
|
||||
>
|
||||
<Play
|
||||
strokeWidth={1.7}
|
||||
class="size-8"
|
||||
style="transform: scale({$isPlayHovered ? 1.1 : 1}); transition: transform 0.3s ease;
|
||||
color: {iconColor};
|
||||
"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<AnimatePresence let:item list={[{ key: $isVideoOpen }]}>
|
||||
{#if item.key}
|
||||
<Motion initial={{ opacity: 0 }} animate={{ opacity: 1 }} exit={{ opacity: 0 }} let:motion>
|
||||
<div
|
||||
use:motion
|
||||
class="fixed inset-0 z-50 flex items-center justify-center bg-black/50 backdrop-blur-md"
|
||||
>
|
||||
<!-- Modal Content -->
|
||||
<Motion
|
||||
initial={selectedAnimation.initial}
|
||||
animate={selectedAnimation.animate}
|
||||
exit={selectedAnimation.exit}
|
||||
transition={{ type: 'spring', damping: 30, stiffness: 300 }}
|
||||
let:motion
|
||||
>
|
||||
<div use:motion class="relative mx-4 aspect-video w-full max-w-4xl md:mx-0">
|
||||
<Motion let:motion whileHover={{ scale: 1.1 }} whileTap={{ scale: 0.95 }}>
|
||||
<button
|
||||
use:motion
|
||||
class="absolute -top-16 right-0 rounded-full bg-neutral-900/50 p-2 text-xl text-white ring-1 backdrop-blur-md"
|
||||
on:click={closeVideo}
|
||||
on:mouseenter={() => isCloseHovered.set(true)}
|
||||
on:mouseleave={() => isCloseHovered.set(false)}
|
||||
>
|
||||
<X class="size-5" />
|
||||
</button>
|
||||
</Motion>
|
||||
<Motion
|
||||
animate={{ scale: $isCloseHovered ? 0.98 : 1 }}
|
||||
transition={{ duration: 0.2 }}
|
||||
let:motion
|
||||
>
|
||||
<div
|
||||
use:motion
|
||||
class="relative isolate z-[1] size-full overflow-hidden rounded-2xl border-2 border-white"
|
||||
>
|
||||
<!-- svelte-ignore a11y-missing-attribute -->
|
||||
<iframe
|
||||
src={videoSrc}
|
||||
class="size-full rounded-2xl"
|
||||
allowfullscreen
|
||||
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share"
|
||||
></iframe>
|
||||
</div>
|
||||
</Motion>
|
||||
</div>
|
||||
</Motion>
|
||||
</div>
|
||||
</Motion>
|
||||
{/if}
|
||||
</AnimatePresence>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.size-24 {
|
||||
width: 6rem;
|
||||
height: 6rem;
|
||||
}
|
||||
.size-20 {
|
||||
width: 5rem;
|
||||
height: 5rem;
|
||||
}
|
||||
.size-8 {
|
||||
width: 2rem;
|
||||
height: 2rem;
|
||||
}
|
||||
.size-full {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
</style>
|
||||
@@ -1 +0,0 @@
|
||||
export { default as HeroVideoDialog } from './hero-video-dialog.svelte';
|
||||
@@ -1 +0,0 @@
|
||||
export { default as MagicCard } from './magic-card.svelte';
|
||||
@@ -1,72 +0,0 @@
|
||||
<script lang="ts">
|
||||
import { Motion, useMotionValue, useMotionTemplate } from 'svelte-motion';
|
||||
import { onMount } from 'svelte';
|
||||
import { cn } from '$lib/utils';
|
||||
|
||||
export let gradientSize: number = 200;
|
||||
export let gradientColor: string = '#262626';
|
||||
export let gradientOpacity: number = 0.8;
|
||||
let className: string = '';
|
||||
export { className as class };
|
||||
|
||||
let gradSize = useMotionValue(gradientSize);
|
||||
let gradColor = useMotionValue(gradientColor);
|
||||
let mouseX = useMotionValue(-gradientSize);
|
||||
let mouseY = useMotionValue(-gradientSize);
|
||||
|
||||
function handleMouseMove(e: MouseEvent) {
|
||||
const rect = (e.currentTarget as HTMLDivElement).getBoundingClientRect();
|
||||
mouseX.set(e.clientX - rect.left);
|
||||
mouseY.set(e.clientY - rect.top);
|
||||
}
|
||||
|
||||
function handleMouseLeave() {
|
||||
mouseX.set(-gradientSize);
|
||||
mouseY.set(-gradientSize);
|
||||
}
|
||||
|
||||
onMount(() => {
|
||||
mouseX.set(-gradientSize);
|
||||
mouseY.set(-gradientSize);
|
||||
});
|
||||
let bg = useMotionTemplate`radial-gradient(${gradSize}px circle at ${mouseX}px ${mouseY}px, ${gradColor}, transparent 100%)`;
|
||||
</script>
|
||||
|
||||
<!-- svelte-ignore a11y-no-static-element-interactions -->
|
||||
<!-- I have added py-4 in below code, you can customize the component as per needs -->
|
||||
<div
|
||||
on:mousemove={handleMouseMove}
|
||||
on:mouseleave={handleMouseLeave}
|
||||
class={cn(
|
||||
'group relative flex size-full justify-center overflow-hidden rounded-xl border bg-neutral-100 py-4 text-black dark:bg-neutral-900 dark:text-white',
|
||||
className
|
||||
)}
|
||||
>
|
||||
<div class="relative z-10">
|
||||
<!-- Default -->
|
||||
<slot>
|
||||
<div class="flex h-full items-center justify-center text-center">
|
||||
<p class="text-2xl">Magic Card</p>
|
||||
</div>
|
||||
</slot>
|
||||
</div>
|
||||
<Motion
|
||||
style={{
|
||||
background: bg,
|
||||
opacity: gradientOpacity
|
||||
}}
|
||||
let:motion
|
||||
>
|
||||
<div
|
||||
use:motion
|
||||
class="pointer-events-none absolute -inset-px rounded-xl opacity-0 transition-opacity duration-300 group-hover:opacity-100"
|
||||
/>
|
||||
</Motion>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.size-full {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
</style>
|
||||
@@ -1 +0,0 @@
|
||||
export { default as Meteors } from './meteors.svelte';
|
||||
@@ -1,36 +0,0 @@
|
||||
<script lang="ts">
|
||||
import { cn } from '$lib/utils';
|
||||
import { onMount } from 'svelte';
|
||||
|
||||
export let number = 10;
|
||||
let meteorStyles: any = [];
|
||||
let changeMeteors = (num: number) => {
|
||||
meteorStyles = [];
|
||||
const styles = [...new Array(num)].map(() => ({
|
||||
top: -20,
|
||||
left: Math.floor(Math.random() * 700) + 'px',
|
||||
animationDelay: Math.random() * 1 + 0.2 + 's',
|
||||
animationDuration: Math.floor(Math.random() * 8 + 2.9) + 's'
|
||||
}));
|
||||
meteorStyles = styles;
|
||||
};
|
||||
onMount(() => {
|
||||
changeMeteors(number);
|
||||
});
|
||||
// $: changeMeteors(number);
|
||||
</script>
|
||||
|
||||
{#each meteorStyles as style, idx}
|
||||
<span
|
||||
id="meteor-{idx + 1}"
|
||||
class={cn(
|
||||
'animate-meteor pointer-events-none absolute left-1/2 top-1/2 size-[2.4px] rotate-[215deg] rounded-full bg-slate-500 shadow-[0_0_0_1px_#ffffff10]'
|
||||
)}
|
||||
style="top: {style.top}px; left: {style.left}; animation-delay: {style.animationDelay}; animation-duration: {style.animationDuration};"
|
||||
>
|
||||
<!-- Meteor Tail -->
|
||||
<div
|
||||
class="pointer-events-none absolute top-1/2 -z-10 h-px w-[50px] -translate-y-1/2 bg-gradient-to-r from-slate-500 via-blue-600/30 to-transparent"
|
||||
/>
|
||||
</span>
|
||||
{/each}
|
||||
@@ -1 +0,0 @@
|
||||
export { default as ShimmerButton } from './shimmerbutton.svelte';
|
||||
@@ -1,67 +0,0 @@
|
||||
<script lang="ts">
|
||||
import { cn } from '$lib/utils';
|
||||
|
||||
export let href: string;
|
||||
export let target: string = '';
|
||||
export let rel: string = '';
|
||||
export let shimmerColor = '#ffffff';
|
||||
export let shimmerSize = '0.05em';
|
||||
export let shimmerDuration = '3s';
|
||||
export let borderRadius = '100px';
|
||||
export let background = 'rgba(0, 0, 0, 1)';
|
||||
let className: any = '';
|
||||
export { className as class };
|
||||
</script>
|
||||
|
||||
<a
|
||||
style:--spread="90deg"
|
||||
style:--shimmer-color={shimmerColor}
|
||||
style:--radius={borderRadius}
|
||||
style:--speed={shimmerDuration}
|
||||
style:--cut={shimmerSize}
|
||||
style:--bg={background}
|
||||
class={cn(
|
||||
'group relative z-0 flex cursor-pointer items-center justify-center overflow-hidden whitespace-nowrap border border-white/10 px-6 py-3 text-white [background:var(--bg)] [border-radius:var(--radius)] dark:text-white',
|
||||
'transform-gpu transition-transform duration-300 ease-in-out active:translate-y-[1px]',
|
||||
className
|
||||
)}
|
||||
{href}
|
||||
{target}
|
||||
{rel}
|
||||
data-rewardful
|
||||
>
|
||||
<div class={cn('-z-30 blur-[2px]', 'absolute inset-0 overflow-visible [container-type:size]')}>
|
||||
<div
|
||||
class="animate-magicslide absolute inset-0 h-[100cqh] [aspect-ratio:1] [border-radius:0] [mask:none]"
|
||||
>
|
||||
<!-- spark before -->
|
||||
<div
|
||||
class="animate-spin-around absolute inset-[-100%] w-auto rotate-0 [background:conic-gradient(from_calc(270deg-(var(--spread)*0.5)),transparent_0,var(--shimmer-color)_var(--spread),transparent_var(--spread))] [translate:0_0]"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<slot>Shimmer Button</slot>
|
||||
<!-- Highlight -->
|
||||
<div
|
||||
class={cn(
|
||||
'insert-0 absolute h-full w-full',
|
||||
|
||||
'rounded-2xl px-4 py-1.5 text-sm font-medium shadow-[inset_0_-8px_10px_#ffffff1f]',
|
||||
|
||||
// transition
|
||||
'transform-gpu transition-all duration-300 ease-in-out',
|
||||
|
||||
// on hover
|
||||
'group-hover:shadow-[inset_0_-6px_10px_#ffffff3f]',
|
||||
|
||||
// on click
|
||||
'group-active:shadow-[inset_0_-10px_10px_#ffffff3f]'
|
||||
)}
|
||||
></div>
|
||||
<!-- backdrop -->
|
||||
<div
|
||||
class={cn(
|
||||
'absolute -z-20 [background:var(--bg)] [border-radius:var(--radius)] [inset:var(--cut)]'
|
||||
)}
|
||||
></div>
|
||||
</a>
|
||||
@@ -1 +0,0 @@
|
||||
export { default as ShinnyText } from './shinny-text.svelte';
|
||||
@@ -1,24 +0,0 @@
|
||||
<script lang="ts">
|
||||
import { cn } from '$lib/utils';
|
||||
|
||||
export let shimmerWidth = 100;
|
||||
let className: any = '';
|
||||
export { className as class };
|
||||
</script>
|
||||
|
||||
<p
|
||||
style:--shimmer-width="{shimmerWidth}px"
|
||||
class={cn(
|
||||
'mx-auto max-w-md text-neutral-600/50 dark:text-neutral-400/50 ',
|
||||
|
||||
// Shimmer effect
|
||||
'animate-shimmer bg-clip-text bg-no-repeat [background-position:0_0] [background-size:var(--shimmer-width)_100%] [transition:background-position_1s_cubic-bezier(.6,.6,0,1)_infinite]',
|
||||
|
||||
// Shimmer gradient
|
||||
'bg-gradient-to-r from-transparent via-black/80 via-50% to-transparent dark:via-white/80',
|
||||
|
||||
className
|
||||
)}
|
||||
>
|
||||
<slot>Shimmer Animation</slot>
|
||||
</p>
|
||||
@@ -1 +0,0 @@
|
||||
export { default as Sparkle } from './sparkle-text.svelte';
|
||||
@@ -1,73 +0,0 @@
|
||||
<script lang="ts">
|
||||
interface TSparkle {
|
||||
id: string;
|
||||
x: string;
|
||||
y: string;
|
||||
color: string;
|
||||
delay: number;
|
||||
scale: number;
|
||||
lifespan: number;
|
||||
}
|
||||
|
||||
export let text: string = 'Hello World';
|
||||
export let colors = {
|
||||
first: '#9E7AFF',
|
||||
second: '#FE8BBB'
|
||||
};
|
||||
export let sparklesCount = 5;
|
||||
|
||||
let className = '';
|
||||
export { className as class };
|
||||
|
||||
let sparkles: TSparkle[] = [];
|
||||
import { onMount, onDestroy } from 'svelte';
|
||||
import Sparkle from './sparkle.svelte';
|
||||
|
||||
let generateStar = () => {
|
||||
let starX = `${Math.random() * 100}%`;
|
||||
let starY = `${Math.random() * 100}%`;
|
||||
let color = Math.random() > 0.5 ? colors.first : colors.second;
|
||||
let delay = Math.random() * 4;
|
||||
let scale = Math.random() * 1 + 0.3;
|
||||
let lifespan = Math.random() * 10 + 5;
|
||||
let id = `${starX}-${starY}-${Date.now()}`;
|
||||
return { id, x: starX, y: starY, color, delay, scale, lifespan };
|
||||
};
|
||||
|
||||
let initializeStars = async () => {
|
||||
let newSparkles = Array.from({ length: sparklesCount }, generateStar);
|
||||
sparkles = newSparkles;
|
||||
};
|
||||
|
||||
const updateStars = () => {
|
||||
let temp = sparkles.map((star) => {
|
||||
if (star.lifespan <= 0) {
|
||||
return generateStar();
|
||||
} else {
|
||||
return { ...star, lifespan: star.lifespan - 0.1 };
|
||||
}
|
||||
});
|
||||
sparkles = temp;
|
||||
};
|
||||
|
||||
let interval: NodeJS.Timer;
|
||||
onMount(async () => {
|
||||
initializeStars();
|
||||
interval = setInterval(updateStars, 100);
|
||||
});
|
||||
onDestroy(() => clearInterval(interval));
|
||||
</script>
|
||||
|
||||
<div
|
||||
style:--sparkles-first-color="{colors.first};"
|
||||
style:--sparkles-second-color="{colors.second};"
|
||||
class={className}
|
||||
{...$$restProps}
|
||||
>
|
||||
<span class="relative inline-block">
|
||||
{#each sparkles as item, _}
|
||||
<Sparkle {...item} />
|
||||
{/each}
|
||||
<strong>{text}</strong>
|
||||
</span>
|
||||
</div>
|
||||
@@ -1,35 +0,0 @@
|
||||
<script lang="ts">
|
||||
import { Motion } from "svelte-motion";
|
||||
|
||||
export let id;
|
||||
export let x;
|
||||
export let y;
|
||||
export let color;
|
||||
export let delay;
|
||||
export let scale;
|
||||
</script>
|
||||
|
||||
<Motion
|
||||
initial={{ opacity: 0, left: x, top: y }}
|
||||
animate={{
|
||||
opacity: [0, 1, 0],
|
||||
scale: [0, scale, 0],
|
||||
rotate: [75, 120, 150],
|
||||
}}
|
||||
transition={{ duration: 0.8, repeat: Infinity, delay }}
|
||||
let:motion
|
||||
>
|
||||
<svg
|
||||
{id}
|
||||
use:motion
|
||||
class="pointer-events-none absolute z-20"
|
||||
width="21"
|
||||
height="21"
|
||||
viewBox="0 0 21 21"
|
||||
>
|
||||
<path
|
||||
d="M9.82531 0.843845C10.0553 0.215178 10.9446 0.215178 11.1746 0.843845L11.8618 2.72026C12.4006 4.19229 12.3916 6.39157 13.5 7.5C14.6084 8.60843 16.8077 8.59935 18.2797 9.13822L20.1561 9.82534C20.7858 10.0553 20.7858 10.9447 20.1561 11.1747L18.2797 11.8618C16.8077 12.4007 14.6084 12.3916 13.5 13.5C12.3916 14.6084 12.4006 16.8077 11.8618 18.2798L11.1746 20.1562C10.9446 20.7858 10.0553 20.7858 9.82531 20.1562L9.13819 18.2798C8.59932 16.8077 8.60843 14.6084 7.5 13.5C6.39157 12.3916 4.19225 12.4007 2.72023 11.8618L0.843814 11.1747C0.215148 10.9447 0.215148 10.0553 0.843814 9.82534L2.72023 9.13822C4.19225 8.59935 6.39157 8.60843 7.5 7.5C8.60843 6.39157 8.59932 4.19229 9.13819 2.72026L9.82531 0.843845Z"
|
||||
fill={color}
|
||||
/>
|
||||
</svg>
|
||||
</Motion>
|
||||
@@ -1,9 +0,0 @@
|
||||
<script lang="ts">
|
||||
import { cn } from '$lib/utils';
|
||||
|
||||
let { children, className } = $props();
|
||||
</script>
|
||||
|
||||
<div class={cn('text-left', className)}>
|
||||
{@render children()}
|
||||
</div>
|
||||
@@ -1,21 +0,0 @@
|
||||
<script lang="ts">
|
||||
import { cn } from '$lib/utils';
|
||||
|
||||
let className: any = '';
|
||||
export { className as class };
|
||||
</script>
|
||||
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
width={24}
|
||||
height={24}
|
||||
stroke-width="1"
|
||||
stroke-linecap="round"
|
||||
stroke="currentColor"
|
||||
class={cn('absolute text-black dark:text-white', className)}
|
||||
{...$$restProps}
|
||||
>
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M12 6v12m6-6H6" />
|
||||
</svg>
|
||||
@@ -1,2 +0,0 @@
|
||||
export { default as SquareCardBody } from './body.svelte';
|
||||
export { default as SquareCardIcon } from './icon.svelte';
|
||||
@@ -1,7 +1,7 @@
|
||||
<script lang="ts">
|
||||
import { buttonVariants } from '$lib/components/ui/button';
|
||||
import { ShimmerButton } from '$lib/components/animation/shimmerbutton';
|
||||
import * as Dialog from '$lib/components/ui/dialog';
|
||||
import { buttonVariants } from '@cio/ui/base/button';
|
||||
import { ShimmerButton } from '@cio/ui/custom/animation';
|
||||
import * as Dialog from '@cio/ui/base/dialog';
|
||||
import { cn } from '$lib/utils';
|
||||
import BadgeCheck from 'lucide-svelte/icons/badge-check';
|
||||
|
||||
@@ -19,10 +19,6 @@
|
||||
</script>
|
||||
|
||||
<Dialog.Root>
|
||||
<!-- <span
|
||||
class="absolute inset-0 z-30 flex items-center justify-center bg-black/50 opacity-0 transition-all duration-500 hover:opacity-80"
|
||||
>
|
||||
</span> -->
|
||||
<Dialog.Trigger class={cn(buttonVariants({ variant: 'default' }), `z-20 ${ctaClass}`)}>
|
||||
{ctaLabel}
|
||||
</Dialog.Trigger>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<script lang="ts">
|
||||
import { toast } from 'svelte-sonner';
|
||||
import { ShinnyText } from '$lib/components/animation/shinny-text';
|
||||
import { ShinnyText } from '@cio/ui/custom/animation';
|
||||
import Copy from 'lucide-svelte/icons/copy';
|
||||
import { cn } from '$lib/utils';
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
)}
|
||||
>
|
||||
<ShinnyText
|
||||
class="animate-gradient inline-flex items-center justify-center bg-gradient-to-r from-[#ffaa40] via-[#9c40ff] to-[#ffaa40] bg-[length:var(--bg-size)_100%] bg-clip-text px-4 py-1 text-transparent text-white transition ease-out hover:text-neutral-400 hover:duration-300"
|
||||
class="animate-gradient inline-flex items-center justify-center bg-linear-to-r from-[#ffaa40] via-[#9c40ff] to-[#ffaa40] bg-size-[var(--bg-size)_100%] bg-clip-text px-4 py-1 text-transparent text-white transition ease-out hover:text-neutral-400 hover:duration-300"
|
||||
>
|
||||
<span>{command}</span>
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
</script>
|
||||
|
||||
<header
|
||||
class="sticky top-0 z-50 w-full border-b border-border/40 bg-background/95 backdrop-blur supports-[backdrop-filter]:bg-background/60"
|
||||
class="sticky top-0 z-50 w-full border-b border-border/40 bg-background/95 backdrop-blur supports-backdrop-filter:bg-background/60"
|
||||
>
|
||||
<p class="bg-blue-700 py-1.5 text-center text-sm font-medium text-white">
|
||||
brought to you by
|
||||
@@ -35,7 +35,7 @@
|
||||
</svg>
|
||||
</a>
|
||||
</p>
|
||||
<div class="container flex h-14 max-w-screen-2xl items-center">
|
||||
<div class="flex h-14 max-w-5xl mx-auto items-center">
|
||||
<div class="mr-4 flex">
|
||||
<a href="/" class="mr-6 flex items-center">
|
||||
<img src="/logo-512.png" alt="Course App" class="h-8 w-8" />
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
<script lang="ts">
|
||||
import Santa from './santa.svg';
|
||||
import { BorderBeam } from '$lib/components/animation/border-beam';
|
||||
import { DotPattern } from '$lib/components/animation/dot-pattern';
|
||||
import { BorderBeam, DotPattern } from '@cio/ui/custom/animation';
|
||||
import { BuyTemplate } from '$lib/components/buy-template';
|
||||
</script>
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
<SeparatorPrimitive.Root
|
||||
class={cn(
|
||||
"bg-border shrink-0",
|
||||
orientation === "horizontal" ? "h-[1px] w-full" : "min-h-full w-[1px]",
|
||||
orientation === "horizontal" ? "h-px w-full" : "min-h-full w-px",
|
||||
className
|
||||
)}
|
||||
{orientation}
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
</script>
|
||||
|
||||
<Sonner
|
||||
theme={$mode}
|
||||
theme={mode.current}
|
||||
class="toaster group"
|
||||
toastOptions={{
|
||||
classes: {
|
||||
|
||||
@@ -1,16 +1,19 @@
|
||||
<script lang="ts">
|
||||
import { CardBody, CardContainer } from '$lib/components/animation/card';
|
||||
import { BlurFade } from '$lib/components/animation/blurfade';
|
||||
import { BlurIn } from '$lib/components/animation/blurin';
|
||||
import { Button } from '$lib/components/ui/button';
|
||||
import { TemplateCard, CustomTemplate } from '$lib/components/template-card';
|
||||
import { Meteors } from '$lib/components/animation/meteors';
|
||||
import { Separator } from '$lib/components/ui/separator';
|
||||
import { BorderBeam } from '$lib/components/animation/border-beam';
|
||||
import { ShimmerButton } from '$lib/components/animation/shimmerbutton';
|
||||
import { BuyTemplate } from '$lib/components/buy-template';
|
||||
import { Sparkle } from '$lib/components/animation/sparkle';
|
||||
import { HeroVideoDialog } from '$lib/components/animation/hero-video-dialog';
|
||||
import {
|
||||
BlurFade,
|
||||
BlurIn,
|
||||
BorderBeam,
|
||||
CardBody,
|
||||
CardContainer,
|
||||
HeroVideoDialog,
|
||||
Meteors,
|
||||
ShimmerButton,
|
||||
Sparkle
|
||||
} from '@cio/ui/custom/animation';
|
||||
|
||||
const templates = [
|
||||
{
|
||||
@@ -93,7 +96,7 @@
|
||||
className="py-10 max-w-4xl mx-auto flex flex-col items-center justify-center px-30 gap-2 md:gap-5"
|
||||
>
|
||||
<BlurIn
|
||||
class="pointer-events-none flex max-w-2xl flex-col items-center whitespace-pre-wrap bg-gradient-to-b from-black to-gray-300/80 bg-clip-text text-center text-2xl font-semibold leading-none tracking-tighter text-transparent md:mb-4 md:block md:text-4xl lg:text-6xl"
|
||||
class="pointer-events-none flex max-w-2xl flex-col items-center whitespace-pre-wrap bg-linear-to-b from-black to-gray-300/80 bg-clip-text text-center text-2xl font-semibold leading-none tracking-tighter text-transparent md:mb-4 md:block md:text-4xl lg:text-6xl"
|
||||
>
|
||||
Create a <span class="font-mono italic text-blue-700">Course</span>
|
||||
<span>Site for your Product in</span>
|
||||
@@ -157,7 +160,7 @@
|
||||
|
||||
<!-- Templates -->
|
||||
<section id="templates" class="my-5 w-full pt-0 md:my-0 md:pt-24">
|
||||
<div class="px-4 md:container">
|
||||
<div class="px-4 max-w- mx-auto">
|
||||
<h2 class="mb-5 text-center text-3xl font-semibold md:mb-20 md:text-start md:text-5xl">
|
||||
Browse Templates
|
||||
</h2>
|
||||
|
||||
@@ -1,23 +1,23 @@
|
||||
import adapter from '@sveltejs/adapter-auto';
|
||||
import path from 'path';
|
||||
import { fileURLToPath } from 'url';
|
||||
import { vitePreprocess } from '@sveltejs/vite-plugin-svelte';
|
||||
|
||||
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
||||
|
||||
/** @type {import('@sveltejs/kit').Config} */
|
||||
const config = {
|
||||
// Consult https://svelte.dev/docs/kit/integrations
|
||||
// for more information about preprocessors
|
||||
preprocess: vitePreprocess({
|
||||
script: true
|
||||
}),
|
||||
|
||||
kit: {
|
||||
// adapter-auto only supports some environments, see https://svelte.dev/docs/kit/adapter-auto for a list.
|
||||
// If your environment is not supported, or you settled on a specific environment, switch out the adapter.
|
||||
// See https://svelte.dev/docs/kit/adapters for more information about adapters.
|
||||
adapter: adapter(),
|
||||
|
||||
alias: {
|
||||
$lib: './src/lib',
|
||||
$lib: './src/lib/*'
|
||||
$lib: path.resolve(__dirname, './src/lib'),
|
||||
'@cio/ui': path.resolve(__dirname, './node_modules/@cio/ui/src'),
|
||||
'@cio/ui/*': path.resolve(__dirname, './node_modules/@cio/ui/src/*')
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,128 +0,0 @@
|
||||
import { fontFamily } from 'tailwindcss/defaultTheme';
|
||||
import type { Config } from 'tailwindcss';
|
||||
|
||||
const config: Config = {
|
||||
darkMode: ['class'],
|
||||
content: ['./src/**/*.{html,js,svelte,ts}'],
|
||||
safelist: ['dark'],
|
||||
theme: {
|
||||
container: {
|
||||
center: true,
|
||||
padding: '2rem',
|
||||
screens: {
|
||||
'2xl': '1400px'
|
||||
}
|
||||
},
|
||||
extend: {
|
||||
colors: {
|
||||
border: 'hsl(var(--border) / <alpha-value>)',
|
||||
input: 'hsl(var(--input) / <alpha-value>)',
|
||||
ring: 'hsl(var(--ring) / <alpha-value>)',
|
||||
background: 'hsl(var(--background) / <alpha-value>)',
|
||||
foreground: 'hsl(var(--foreground) / <alpha-value>)',
|
||||
primary: {
|
||||
DEFAULT: 'hsl(var(--primary) / <alpha-value>)',
|
||||
foreground: 'hsl(var(--primary-foreground) / <alpha-value>)'
|
||||
},
|
||||
secondary: {
|
||||
DEFAULT: 'hsl(var(--secondary) / <alpha-value>)',
|
||||
foreground: 'hsl(var(--secondary-foreground) / <alpha-value>)'
|
||||
},
|
||||
destructive: {
|
||||
DEFAULT: 'hsl(var(--destructive) / <alpha-value>)',
|
||||
foreground: 'hsl(var(--destructive-foreground) / <alpha-value>)'
|
||||
},
|
||||
muted: {
|
||||
DEFAULT: 'hsl(var(--muted) / <alpha-value>)',
|
||||
foreground: 'hsl(var(--muted-foreground) / <alpha-value>)'
|
||||
},
|
||||
accent: {
|
||||
DEFAULT: 'hsl(var(--accent) / <alpha-value>)',
|
||||
foreground: 'hsl(var(--accent-foreground) / <alpha-value>)'
|
||||
},
|
||||
popover: {
|
||||
DEFAULT: 'hsl(var(--popover) / <alpha-value>)',
|
||||
foreground: 'hsl(var(--popover-foreground) / <alpha-value>)'
|
||||
},
|
||||
card: {
|
||||
DEFAULT: 'hsl(var(--card) / <alpha-value>)',
|
||||
foreground: 'hsl(var(--card-foreground) / <alpha-value>)'
|
||||
}
|
||||
},
|
||||
borderRadius: {
|
||||
lg: 'var(--radius)',
|
||||
md: 'calc(var(--radius) - 2px)',
|
||||
sm: 'calc(var(--radius) - 4px)'
|
||||
},
|
||||
fontFamily: {
|
||||
sans: [...fontFamily.sans],
|
||||
drawn: [
|
||||
'Virgil',
|
||||
'ui-sans-serif',
|
||||
'system-ui',
|
||||
'sans-serif',
|
||||
'Apple Color Emoji',
|
||||
'Segoe UI Emoji',
|
||||
'Segoe UI Symbol',
|
||||
'Noto Color Emoji'
|
||||
]
|
||||
},
|
||||
|
||||
animation: {
|
||||
'border-beam': 'border-beam calc(var(--duration)*1s) infinite linear',
|
||||
meteor: 'meteor 5s linear infinite',
|
||||
shimmer: 'shimmer 8s infinite',
|
||||
'spin-around': 'spin-around calc(var(--speed) * 2) infinite linear',
|
||||
magicslide: 'magicslide var(--speed) ease-in-out infinite alternate'
|
||||
},
|
||||
|
||||
keyframes: {
|
||||
'border-beam': {
|
||||
'100%': {
|
||||
'offset-distance': '100%'
|
||||
}
|
||||
},
|
||||
|
||||
meteor: {
|
||||
'0%': { transform: 'rotate(215deg) translateX(0)', opacity: '1' },
|
||||
'70%': { opacity: '1' },
|
||||
'100%': {
|
||||
transform: 'rotate(215deg) translateX(-500px)',
|
||||
opacity: '0'
|
||||
}
|
||||
},
|
||||
shimmer: {
|
||||
'0%, 90%, 100%': {
|
||||
'background-position': 'calc(-100% - var(--shimmer-width)) 0'
|
||||
},
|
||||
'30%, 60%': {
|
||||
'background-position': 'calc(100% + var(--shimmer-width)) 0'
|
||||
}
|
||||
},
|
||||
|
||||
'spin-around': {
|
||||
'0%': {
|
||||
transform: 'translateZ(0) rotate(0)'
|
||||
},
|
||||
'15%, 35%': {
|
||||
transform: 'translateZ(0) rotate(90deg)'
|
||||
},
|
||||
'65%, 85%': {
|
||||
transform: 'translateZ(0) rotate(270deg)'
|
||||
},
|
||||
'100%': {
|
||||
transform: 'translateZ(0) rotate(360deg)'
|
||||
}
|
||||
},
|
||||
|
||||
magicslide: {
|
||||
to: {
|
||||
transform: 'translate(calc(100cqw - 100%), 0)'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
export default config;
|
||||
Reference in New Issue
Block a user