docs: home page redesign (#18257)

Co-authored-by: Simon Le Marchant <simon@marchantweb.com>
This commit is contained in:
Evan You 2024-10-02 22:02:46 +08:00 committed by GitHub
parent d21bdbfcee
commit d7c8603897
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
65 changed files with 8076 additions and 161 deletions

View File

@ -77,6 +77,30 @@ export default defineConfig({
'link',
{ rel: 'alternate', type: 'application/rss+xml', href: '/blog.rss' },
],
['link', { rel: 'preconnect', href: 'https://fonts.googleapis.com' }],
[
'link',
{
rel: 'preconnect',
href: 'https://fonts.gstatic.com',
crossorigin: 'true',
},
],
[
'link',
{
rel: 'preload',
href: 'https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600&family=Manrope:wght@600&family=IBM+Plex+Mono:wght@400&display=swap',
as: 'style',
},
],
[
'link',
{
rel: 'stylesheet',
href: 'https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600&family=Manrope:wght@600&family=IBM+Plex+Mono:wght@400&display=swap',
},
],
['link', { rel: 'me', href: 'https://m.webtoo.ls/@vite' }],
['meta', { property: 'og:type', content: 'website' }],
['meta', { property: 'og:title', content: ogTitle }],
@ -139,7 +163,8 @@ export default defineConfig({
footer: {
message: `Released under the MIT License. (${commitRef})`,
copyright: 'Copyright © 2019-present Evan You & Vite Contributors',
copyright:
'Copyright © 2019-present Yuxi (Evan) You & Vite Contributors',
},
nav: [

View File

@ -23,7 +23,7 @@ const sponsors = computed(() => {
href="https://viteconf.org/?utm=vite-sidebar"
target="_blank"
>
<img width="22" height="22" src="/viteconf.svg" />
<img width="22" height="22" src="/viteconf.svg" alt="ViteConf Logo" />
<span>
<p class="extra-info">Building Together</p>
<p class="heading">ViteConf 24 - Oct 3</p>

View File

@ -1,5 +1,5 @@
<script setup lang="ts">
import { data as posts } from './blog.data'
import { data as posts } from '../../../_data/blog.data'
function getDateTime(time: number) {
return new Date(time).toISOString()

View File

@ -1,70 +0,0 @@
<script setup lang="ts">
import { VPHomeSponsors } from 'vitepress/theme'
import { useSponsor } from '../composables/sponsor'
const { data } = useSponsor()
</script>
<template>
<VPHomeSponsors
v-if="data"
message="Vite is free and open source, made possible by wonderful sponsors."
:data="data"
/>
<div class="action">
<a
class="sponsor"
href="https://github.com/sponsors/vitejs"
target="_blank"
rel="noreferrer"
>
Sponsor Vite
</a>
<a
class="sponsor"
href="https://github.com/sponsors/yyx990803"
target="_blank"
rel="noreferrer"
>
Sponsor Evan You
</a>
</div>
</template>
<style scoped>
.action {
display: flex;
justify-content: center;
gap: 1rem;
padding-top: 4rem;
}
.sponsor {
/* .VPButton */
display: inline-block;
border: 1px solid transparent;
text-align: center;
font-weight: 600;
white-space: nowrap;
transition:
color 0.25s,
border-color 0.25s,
background-color 0.25s;
/* .VPButton.medium */
border-radius: 20px;
padding: 0 20px;
line-height: 38px;
font-size: 14px;
/* .VPButton.sponsor */
border-color: var(--vp-button-sponsor-border);
color: var(--vp-button-sponsor-text);
background-color: var(--vp-button-sponsor-bg);
}
.sponsor:hover {
/* .VPButton.sponsor:hover */
border-color: var(--vp-button-sponsor-hover-border);
color: var(--vp-button-sponsor-hover-text);
background-color: var(--vp-button-sponsor-hover-bg);
}
</style>

View File

@ -0,0 +1,821 @@
<script setup lang="ts">
import { gsap } from 'gsap'
import { MotionPathPlugin } from 'gsap/dist/MotionPathPlugin'
import { onMounted, onUnmounted, Ref, ref } from 'vue'
import SvgInputs from './svg-elements/SvgInputs.vue'
import SvgOutputs from './svg-elements/SvgOutputs.vue'
import SvgBlueIndicator from './svg-elements/SvgBlueIndicator.vue'
import SvgPinkIndicator from './svg-elements/SvgPinkIndicator.vue'
import { ScrollTrigger } from 'gsap/dist/ScrollTrigger'
import { SvgNodeProps } from '../common/SvgNode.vue'
gsap.registerPlugin(MotionPathPlugin)
// Define the paths on the input side of the diagram
const inputPaths = [
'M843.505 284.659L752.638 284.659C718.596 284.659 684.866 280.049 653.251 271.077L598.822 255.629L0.675021 1.00011',
'M843.505 298.181L724.342 297.36C708.881 297.36 693.45 296.409 678.22 294.518L598.822 284.659C592.82 284.659 200.538 190.002 0.675028 164.892',
'M843.505 311.703L701.108 310.061L598.822 305.136L0.675049 256.071',
'M843.505 325.224L598.822 326.002L0.675049 321.858',
'M843.505 338.746L701.108 340.388L598.822 345.442L0.675038 387.646',
'M843.505 352.268L724.342 353.088C708.881 353.088 693.45 354.039 678.22 355.93L598.822 365.789L0.675067 478.825',
'M843.505 365.789L752.638 365.789C718.596 365.789 684.866 370.399 653.251 379.372L598.822 394.82L0.675049 642.717',
]
// Setup objects representing each input line's animation state
const inputLines: Ref<SvgNodeProps>[] = inputPaths.map((path) =>
ref({
position: 0,
visible: false,
labelVisible: false,
label: '',
dotColor: null,
glowColor: null,
path,
}),
)
// Define the file set "combinations" that can be shown on the input side
const inputFileSets = ref([
[
{ label: '.jsx' },
{ label: '.sass' },
{ label: '.svelte', color: '#ff8d67' },
],
[{ label: '.tsx' }, { label: '.scss' }, { label: '.vue', color: '#40b782' }],
[
{ label: '.js' },
{ label: '.styl' },
{ label: '.svelte', color: '#ff8d67' },
],
[{ label: '.ts' }, { label: '.less' }, { label: '.vue', color: '#40b782' }],
[{ label: '.mts' }, { label: '.html' }, { label: '.json' }],
])
// Setup objects representing each output line's animation state
const outputLines: Ref[] = [
ref({
position: 0,
visible: false,
labelVisible: false,
label: '.html',
}),
ref({
position: 0,
visible: false,
labelVisible: false,
label: '.css',
}),
ref({
position: 0,
visible: false,
labelVisible: false,
label: '.js',
}),
]
// Add some flags for whether to display various subcomponents
const blueIndicator = ref(false)
const pinkIndicator = ref(false)
const illuminateLogo = ref(false)
// Set up a reference to our ScrollTrigger instance and timeline
let scrollTriggerInstance: ScrollTrigger | null
let timeline: gsap.core.Timeline | null
// Start all animations when mounted
onMounted(() => {
scrollTriggerInstance = ScrollTrigger.create({
trigger: '#hero-diagram',
start: 'center 100%',
once: true,
onEnter: () => {
animateDiagram()
},
})
})
// Clean up the scroll trigger and timeline when unmounted
onUnmounted(() => {
scrollTriggerInstance?.kill()
timeline?.kill()
})
/**
* The core animation for the hero diagram.
* Has both a desktop and mobile variation.
*/
const animateDiagram = () => {
// Determine if we're showing the desktop or mobile variation of the animation
// This is determined on each "loop" of the animation
const isMobile = window.innerWidth < 768
// Prepare a timeline
timeline = gsap.timeline({
onComplete: animateDiagram,
})
// Animate the input nodes/lines
prepareInputs().forEach((lineIndex, fileIndex) => {
timeline.add(
isMobile
? animateSingleInputMobile(inputLines[lineIndex as number])
: animateSingleInputDesktop(inputLines[lineIndex as number]),
fileIndex * (isMobile ? 0.4 : 0.2),
)
})
// Illuminate the logo and colored indicators
timeline.set(blueIndicator, { value: true }, isMobile ? '>-2' : '>-0.2')
timeline.set(illuminateLogo, { value: true }, '<-0.3')
timeline.set(pinkIndicator, { value: true }, '<+0.3')
// Animate the output nodes/lines
timeline.addLabel('showOutput', '<')
outputLines.forEach((outputLine, index) => {
timeline.add(
isMobile
? animateSingleOutputMobile(outputLine)
: animateSingleOutputDesktop(outputLine, index),
'showOutput+=' + (isMobile ? 0.3 : 0.1) * index,
)
})
// Desktop only reset
if (!isMobile) {
// Disable the colored indicators
timeline.set(blueIndicator, { value: false }, '>-1')
timeline.set(pinkIndicator, { value: false }, '<')
// Pause briefly at the end of the animation
timeline.set({}, {}, '+=0.2')
}
}
/**
* Randomly selects a set of input file nodes and assigns them to input lines.
*/
const prepareInputs = () => {
// Randomly select a set of input file "nodes"
const inputFileSet =
inputFileSets.value[Math.floor(Math.random() * inputFileSets.value.length)]
// Choose enough unique lines for the input file nodes to slide along
const inputLineIndexes = new Set()
while (inputLineIndexes.size < 3) {
const index: number = Math.floor(Math.random() * inputLines.length)
inputLineIndexes.add(index)
}
// Assign each line it's appropriate node label
const inputs = [...inputLineIndexes]
inputs.forEach((lineIndex, fileIndex) => {
inputLines[lineIndex as number].value.label = inputFileSet[fileIndex].label
inputLines[lineIndex as number].value.dotColor = inputLines[
lineIndex as number
].value.glowColor = inputFileSet[fileIndex].color as string | null
})
return inputs
}
/**
* Animates a single output line for desktop.
* There are technically 3 output lines, but they are stacked on top of each other.x
*/
const animateSingleOutputDesktop = (
outputLine: Ref<SvgNodeProps>,
index: number,
) => {
const timeline = gsap.timeline()
// Reset the line
timeline.set(
outputLine.value,
{
position: 0,
},
0,
)
// Animate the dot in
timeline.to(
outputLine.value,
{
position: (0.7 / 3) * (index + 1) + 0.05,
duration: 1.5,
ease: 'expo.out',
},
0,
)
// Show the dot
timeline.set(
outputLine.value,
{
visible: true,
},
0,
)
// Show the label
timeline.set(
outputLine.value,
{
labelVisible: true,
},
0.4,
)
// Animate the dot out
timeline.to(
outputLine.value,
{
position: 1,
duration: 1.5,
ease: 'power3.in',
},
2,
)
// Hide the label
timeline.set(
outputLine.value,
{
labelVisible: false,
},
2.5,
)
// Hide the dot
timeline.set(
outputLine.value,
{
visible: false,
},
3,
)
return timeline
}
/**
* Animates a single output line for mobile.
* There are technically 3 output lines, but they are stacked on top of each other.
*/
const animateSingleOutputMobile = (outputLine: Ref<SvgNodeProps>) => {
const timeline = gsap.timeline()
// Reset the line
timeline.set(
outputLine.value,
{
position: 0,
},
0,
)
// Animate the dot in
timeline.to(
outputLine.value,
{
position: 0.7,
duration: 2,
ease: 'power1.inOut',
},
0.3,
)
// Show the dot
timeline.set(
outputLine.value,
{
visible: true,
},
0.75,
)
// Hide the dot
timeline.set(
outputLine.value,
{
visible: false,
},
1.2,
)
return timeline
}
/**
* Animates a single input line for desktop.
*/
const animateSingleInputDesktop = (inputLine: Ref<SvgNodeProps>) => {
const timeline = gsap.timeline()
// Reset the line
timeline.set(
inputLine.value,
{
position: 0,
},
0,
)
// Animate the dot in
timeline.to(
inputLine.value,
{
position: Math.random() * 0.1 + 0.4,
duration: 1,
ease: 'expo.out',
},
0,
)
// Show the dot
timeline.set(
inputLine.value,
{
visible: true,
},
0,
)
// Show the label
timeline.set(
inputLine.value,
{
labelVisible: true,
},
0.2,
)
// Animate the dot out
timeline.to(
inputLine.value,
{
position: 1,
duration: 1.2,
ease: 'power3.in',
},
1.2,
)
// Hide the label
timeline.set(
inputLine.value,
{
labelVisible: false,
},
1.6,
)
// Hide the dot
timeline.set(
inputLine.value,
{
visible: false,
},
1.9,
)
// Return the timeline
return timeline
}
/**
* Animates a single input line for mobile.
*/
const animateSingleInputMobile = (inputLine: Ref<SvgNodeProps>) => {
const timeline = gsap.timeline()
// Reset the line
timeline.set(
inputLine.value,
{
position: 0,
},
0,
)
// Animate the dot in
timeline.to(
inputLine.value,
{
position: 1,
duration: 1.8,
ease: 'power2.out',
},
0,
)
// Show the dot
timeline.set(
inputLine.value,
{
visible: true,
},
0,
)
// Hide the dot
timeline.set(
inputLine.value,
{
visible: false,
},
0.5,
)
// Return the timeline
return timeline
}
// Animating borders only smoothly transitions in Chromium-based browsers
// We don't need extensive checking, just see if the `chrome` key exists on the window object
const isChromiumBrowser = ref(false)
onMounted(() => {
isChromiumBrowser.value = 'chrome' in window
})
</script>
<template>
<div class="hero__diagram" id="hero-diagram">
<!-- Input Lines -->
<SvgInputs :input-lines="inputLines" />
<!-- Output Line -->
<SvgOutputs :output-lines="outputLines" />
<!-- Blue Indicator -->
<SvgBlueIndicator :active="blueIndicator" />
<!-- Pink Indicator -->
<SvgPinkIndicator :active="pinkIndicator" />
<!-- Vite Chip -->
<div class="vite-chip" :class="{ active: illuminateLogo }">
<div class="vite-chip__background">
<div class="vite-chip__border" />
<div
class="vite-chip__edge"
:class="{ 'edge--animated': isChromiumBrowser }"
></div>
</div>
<div class="vite-chip__filter" />
<img src="/logo.svg" alt="Vite Logo" class="vite-chip__logo" />
</div>
</div>
<!-- Background -->
<div class="hero__background" :class="{ active: illuminateLogo }" />
</template>
<style scoped>
.hero__diagram {
pointer-events: none;
position: relative;
width: 1630px;
overflow: hidden;
margin: -100px auto 0;
@media (max-width: 1630px) {
left: 50%;
transform: translate3d(-50%, 0, 0);
}
@media (max-width: 768px) {
left: 50%;
transform: translate3d(-50%, 0, 0) scale(0.9);
}
}
.vite-chip {
width: 134px;
height: 134px;
position: absolute;
left: 750px;
top: 260px;
border-radius: 10px;
overflow: hidden;
transition: all 0.6s ease-out;
transform: translate3d(0, 0, 0) scale(0.85);
.vite-chip__filter {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
transform: translate3d(0, 0, 0) scale(1);
transition: transform 0.3s ease-in-out;
background: linear-gradient(
130deg,
rgba(61, 61, 61, 0.3) 0%,
rgba(61, 61, 61, 0) 40%
),
linear-gradient(
130deg,
rgba(42, 33, 63, 0) 60%,
rgba(61, 61, 61, 0.3) 100%
),
linear-gradient(to bottom, rgba(16, 14, 26, 0.3) 60%, rgba(12, 12, 12, 0));
border-radius: 10px;
display: none;
@media (min-width: 768px) {
display: block;
}
&:after {
content: '';
position: absolute;
top: -10px;
left: 0;
right: 0;
bottom: 0;
z-index: 5;
background: linear-gradient(
130deg,
rgba(61, 61, 61, 0) 45%,
rgba(154, 152, 222, 0.3) 50%,
rgba(61, 61, 61, 0) 60%
);
background-size: 500%;
background-position-x: 100%;
filter: blur(8px);
border-radius: 100px;
mix-blend-mode: color-dodge;
display: none;
}
&:before {
content: '';
position: absolute;
top: -10px;
left: 0;
right: 0;
bottom: 0;
z-index: 5;
background: linear-gradient(
-130deg,
rgba(42, 33, 63, 0) 40%,
rgba(154, 152, 222, 0.2) 50%,
rgba(42, 33, 63, 0) 60%
);
background-size: 400%;
background-position-x: 100%;
filter: blur(10px);
border-radius: 100px;
mix-blend-mode: color-dodge;
display: none;
}
@media (min-width: 768px) {
&:before,
&:after {
display: block;
}
}
}
.vite-chip__edge {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
border: 2px solid;
border-image-slice: 1;
border-image-source: linear-gradient(
to bottom right,
rgba(0, 0, 0, 0) 60%,
rgba(255, 255, 255, 0.15) 65%,
rgba(0, 0, 0, 0) 90%
);
opacity: 0;
will-change: opacity, border;
transition: all 1s ease-in-out;
@media (min-width: 768px) {
border-image-source: linear-gradient(
to bottom right,
rgba(0, 0, 0, 0) 50%,
rgba(255, 255, 255, 0.15) 60%,
rgba(0, 0, 0, 0) 90%
);
}
}
.vite-chip__border {
position: absolute;
top: 0;
right: 0;
left: 0;
bottom: 0;
border-radius: 10px;
border: 0 solid rgba(89, 82, 108, 0.3);
opacity: 0.8;
background: rgba(40, 40, 40, 0.3);
@media (min-width: 768px) {
top: 2px;
right: 2px;
left: 2px;
bottom: 2px;
}
}
.vite-chip__logo {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%) scale(0.9);
width: 65px;
opacity: 0.2;
filter: grayscale(100%);
transition: all 0.2s ease;
z-index: 3;
}
&.active {
box-shadow: 0 30px 35px -10px rgba(0, 0, 0, 0.6);
transform: translate3d(0, 0, 0) scale(1);
.vite-chip__edge {
opacity: 1;
&.edge--animated {
@media (min-width: 768px) {
animation: rotateGradient 8s linear infinite;
}
}
}
.vite-chip__filter {
transform: translate3d(0, 0, 0) scale(0.97);
&:before {
animation: shimmer 8s infinite linear;
}
&:after {
animation: shimmer 6s infinite linear;
}
}
.vite-chip__border {
border-width: 5px;
transition: all 1s ease;
}
.vite-chip__logo {
opacity: 1;
filter: grayscale(0);
transform: translate(-50%, -50%) scale(1);
}
}
}
@keyframes shimmer {
to {
background-position-x: 0;
}
}
.hero__background {
position: absolute;
top: -30%;
left: 0;
right: 0;
bottom: -60%;
width: 100%;
z-index: -1;
opacity: 0.4;
transition: opacity 1s ease;
@media (min-width: 768px) {
opacity: 0.1;
}
background: url('/noise.png'),
radial-gradient(
circle at right center,
rgb(86, 50, 119) 0%,
rgba(74, 55, 140, 1) 30%,
rgb(65, 114, 194) 55%,
rgba(50, 81, 115, 0.5) 100%
);
mask-image: radial-gradient(
ellipse 300% 30% at center center,
rgba(0, 0, 0, 1) 20%,
rgba(0, 0, 0, 0.5) 50%,
rgba(0, 0, 0, 0) 100%
);
@media (min-width: 1024px) {
background: url('/noise.png'),
radial-gradient(
circle at right center,
rgba(75, 41, 105, 0.5) 0%,
rgb(86, 50, 119) 25%,
rgba(74, 55, 140, 1) 40%,
rgb(64, 102, 168) 65%,
rgba(50, 81, 115, 0.5) 100%
);
mask-image: radial-gradient(
ellipse 150% 30% at center center,
rgba(0, 0, 0, 1) 20%,
rgba(0, 0, 0, 0.5) 50%,
rgba(0, 0, 0, 0) 100%
);
}
@media (min-width: 1500px) {
background: url('/noise.png'),
radial-gradient(
circle at right center,
rgba(75, 41, 105, 0.5) 0%,
rgb(86, 50, 119) 25%,
rgba(74, 55, 140, 1) 45%,
rgb(64, 102, 168) 65%,
rgba(50, 81, 115, 0.5) 100%
);
mask-image: radial-gradient(
ellipse 80% 40% at center center,
rgba(0, 0, 0, 1) 20%,
rgba(0, 0, 0, 0.5) 50%,
rgba(0, 0, 0, 0) 100%
);
}
@media (min-width: 1800px) {
background: url('/noise.png'),
radial-gradient(
circle at right center,
rgba(75, 41, 105, 0.5) 0%,
rgb(86, 50, 119) 25%,
rgba(74, 55, 140, 1) 50%,
rgb(64, 102, 168) 70%,
rgba(50, 81, 115, 0.5) 100%
);
mask-image: radial-gradient(
ellipse 80% 40% at center center,
rgba(0, 0, 0, 1) 20%,
rgba(0, 0, 0, 0.5) 50%,
rgba(0, 0, 0, 0) 100%
);
}
&.active {
opacity: 0.4;
@media (min-width: 768px) {
opacity: 0.7;
}
}
}
@keyframes rotateGradient {
0% {
border-image-source: linear-gradient(
to bottom right,
rgba(0, 0, 0, 0) 60%,
rgba(255, 255, 255, 0.15) 65%,
rgba(0, 0, 0, 0) 90%
);
}
25% {
border-image-source: linear-gradient(
to right top,
rgba(0, 0, 0, 0) 60%,
rgba(255, 255, 255, 0.15) 65%,
rgba(0, 0, 0, 0) 90%
);
}
50% {
border-image-source: linear-gradient(
to top left,
rgba(0, 0, 0, 0) 60%,
rgba(255, 255, 255, 0.15) 65%,
rgba(0, 0, 0, 0) 90%
);
}
75% {
border-image-source: linear-gradient(
to left bottom,
rgba(0, 0, 0, 0) 60%,
rgba(255, 255, 255, 0.15) 65%,
rgba(0, 0, 0, 0) 90%
);
}
100% {
border-image-source: linear-gradient(
to bottom right,
rgba(0, 0, 0, 0) 60%,
rgba(255, 255, 255, 0.15) 65%,
rgba(0, 0, 0, 0) 90%
);
}
}
</style>

View File

@ -0,0 +1,133 @@
<script setup>
import HeroDiagram from './HeroDiagram.vue'
</script>
<template>
<div class="hero">
<div class="container">
<!-- ViteConf Replay Button -->
<a href="https://viteconf.org/" class="hero__pill" target="_blank">
<img src="/viteconf.svg" alt="Viteconf logo" width="20" height="20" />
<span>ViteConf 2024 - Oct 3rd & 4th</span>
</a>
<!-- Heading -->
<h1>The Build Tool<br />for the Web</h1>
<!-- Tagline -->
<h3>
Vite is a blazing fast frontend build tool powering the next generation
of web applications.
</h3>
<!-- CTA Buttons -->
<div class="hero__actions">
<a href="/guide/" class="btn btn--primary">Get started</a>
<a
href="https://github.com/vitejs/vite"
target="_blank"
class="btn btn--outline"
>
<img src="/github.svg" alt="GitHub logo" width="20" height="20" />
GitHub
</a>
</div>
</div>
<!-- Animated Diagram -->
<HeroDiagram />
</div>
</template>
<style scoped>
.hero {
position: relative;
z-index: 2;
margin-bottom: 0;
background-color: #101010;
@media (min-width: 768px) {
margin-bottom: 60px;
}
}
.container {
display: flex;
flex-direction: column;
max-width: 902px;
margin: 60px auto 0;
align-items: center;
position: relative;
z-index: 2;
@media (min-width: 768px) {
margin: 95px auto 0;
}
}
.hero__pill {
color: #fff;
font-family: Inter, sans-serif;
font-size: 14px;
font-style: normal;
font-weight: 500;
line-height: normal;
letter-spacing: -0.3px;
display: inline-flex;
padding: 6px 16px;
align-items: center;
gap: 8px;
border-radius: 100px;
border: 1px solid rgba(189, 52, 254, 0.5);
background: radial-gradient(
1686.42% 113.39% at 83.25% 2.56%,
rgba(189, 52, 254, 0.1) 0%,
rgba(189, 52, 254, 0) 100%
);
box-shadow: none;
margin-bottom: 40px;
@media (min-width: 768px) {
margin-bottom: 25px;
}
span {
color: #fff;
font-family: Inter, sans-serif;
font-size: 14px;
font-style: normal;
font-weight: 500;
line-height: normal;
letter-spacing: -0.28px;
}
&:hover {
animation: hero-pill-glow 1600ms ease-out infinite alternate;
}
}
@keyframes hero-pill-glow {
0% {
border-color: rgba(189, 52, 254, 0.5);
box-shadow:
0 0 5px rgba(189, 52, 254, 0.01),
inset 0 0 5px rgba(189, 52, 254, 0.1);
}
100% {
border-color: rgba(189, 52, 254, 0.6);
box-shadow:
0 0 20px rgba(189, 52, 254, 0.2),
inset 0 0 10px rgba(189, 52, 254, 0.2);
}
}
.hero__actions {
display: flex;
flex-direction: row;
gap: 20px;
margin-top: 20px;
@media (min-width: 768px) {
margin-top: 0;
}
}
</style>

View File

@ -0,0 +1,242 @@
<script setup lang="ts">
defineProps({
active: {
type: Boolean,
required: true,
default: false,
},
})
</script>
<template>
<svg
width="142"
height="82"
viewBox="0 0 142 82"
fill="none"
xmlns="http://www.w3.org/2000/svg"
class="blue-indicator"
:class="{ active: active }"
>
<g opacity="0.2" filter="url(#filter0_d_1_2)">
<path
fill-rule="evenodd"
clip-rule="evenodd"
d="M136.073 3V45.1271C136.073 51.5014 130.905 56.6688 124.531 56.6688H40.2769V54.3604H124.531C129.63 54.3604 133.764 50.2265 133.764 45.1271V3H136.073Z"
fill="#0D0D0D"
/>
<path
d="M136.361 3V2.71146H136.073H133.764H133.476V3V45.1271C133.476 50.0672 129.471 54.0719 124.531 54.0719H40.2769H39.9883V54.3604V56.6688V56.9573H40.2769H124.531C131.065 56.9573 136.361 51.6607 136.361 45.1271V3Z"
stroke="#404040"
stroke-width="0.577083"
/>
</g>
<g filter="url(#filter1_i_1_2)">
<rect
x="12"
y="69.9419"
width="30.0083"
height="30.0083"
rx="5.01812"
transform="rotate(-90 12 69.9419)"
fill="#1F1F1F"
/>
</g>
<rect
x="12"
y="69.9419"
width="30.0083"
height="30.0083"
rx="5.01812"
transform="rotate(-90 12 69.9419)"
stroke="#2C2C2C"
stroke-opacity="0.4"
stroke-width="3.75141"
/>
<path
d="M18.4048 57.9946C18.4048 57.3366 18.9382 56.8032 19.5961 56.8032H24.3614C25.0194 56.8032 25.5528 57.3366 25.5528 57.9946V62.7599C25.5528 63.4179 25.0194 63.9512 24.3614 63.9512H19.5961C18.9382 63.9512 18.4048 63.4179 18.4048 62.7599V57.9946Z"
fill="#41D1FF"
v-show="active"
/>
<path
d="M18.4048 57.9946C18.4048 57.3366 18.9382 56.8032 19.5961 56.8032H24.3614C25.0194 56.8032 25.5528 57.3366 25.5528 57.9946V62.7599C25.5528 63.4179 25.0194 63.9512 24.3614 63.9512H19.5961C18.9382 63.9512 18.4048 63.4179 18.4048 62.7599V57.9946Z"
fill="white"
fill-opacity="0.5"
/>
<path
d="M27.9354 57.9946C27.9354 57.3366 28.4688 56.8032 29.1268 56.8032H33.8921C34.5501 56.8032 35.0834 57.3366 35.0834 57.9946V62.7599C35.0834 63.4179 34.5501 63.9512 33.8921 63.9512H29.1268C28.4688 63.9512 27.9354 63.4179 27.9354 62.7599V57.9946Z"
fill="#41D1FF"
v-show="active"
/>
<path
d="M27.9354 57.9946C27.9354 57.3366 28.4688 56.8032 29.1268 56.8032H33.8921C34.5501 56.8032 35.0834 57.3366 35.0834 57.9946V62.7599C35.0834 63.4179 34.5501 63.9512 33.8921 63.9512H29.1268C28.4688 63.9512 27.9354 63.4179 27.9354 62.7599V57.9946Z"
fill="white"
fill-opacity="0.5"
/>
<path
d="M27.9354 47.6694C27.9354 47.0114 28.4688 46.478 29.1268 46.478H33.8921C34.5501 46.478 35.0834 47.0114 35.0834 47.6694V52.4347C35.0834 53.0926 34.5501 53.626 33.8921 53.626H29.1268C28.4688 53.626 27.9354 53.0926 27.9354 52.4347V47.6694Z"
fill="#41D1FF"
v-show="active"
/>
<path
d="M27.9354 47.6694C27.9354 47.0114 28.4688 46.478 29.1268 46.478H33.8921C34.5501 46.478 35.0834 47.0114 35.0834 47.6694V52.4347C35.0834 53.0926 34.5501 53.626 33.8921 53.626H29.1268C28.4688 53.626 27.9354 53.0926 27.9354 52.4347V47.6694Z"
fill="white"
fill-opacity="0.5"
/>
<path
d="M18.4048 47.6694C18.4048 47.0114 18.9382 46.478 19.5961 46.478H24.3614C25.0194 46.478 25.5528 47.0114 25.5528 47.6694V52.4347C25.5528 53.0926 25.0194 53.626 24.3614 53.626H19.5961C18.9382 53.626 18.4048 53.0926 18.4048 52.4347V47.6694Z"
fill="#41D1FF"
v-show="active"
/>
<path
d="M18.4048 47.6694C18.4048 47.0114 18.9382 46.478 19.5961 46.478H24.3614C25.0194 46.478 25.5528 47.0114 25.5528 47.6694V52.4347C25.5528 53.0926 25.0194 53.626 24.3614 53.626H19.5961C18.9382 53.626 18.4048 53.0926 18.4048 52.4347V47.6694Z"
fill="white"
fill-opacity="0.5"
/>
<g filter="url(#filter2_f_1_2)" v-show="active">
<path
d="M18.4048 57.9946C18.4048 57.3366 18.9382 56.8032 19.5961 56.8032H24.3614C25.0194 56.8032 25.5528 57.3366 25.5528 57.9946V62.7599C25.5528 63.4179 25.0194 63.9512 24.3614 63.9512H19.5961C18.9382 63.9512 18.4048 63.4179 18.4048 62.7599V57.9946Z"
fill="#41D1FF"
/>
<path
d="M27.9354 57.9946C27.9354 57.3366 28.4688 56.8032 29.1268 56.8032H33.8921C34.5501 56.8032 35.0834 57.3366 35.0834 57.9946V62.7599C35.0834 63.4179 34.5501 63.9512 33.8921 63.9512H29.1268C28.4688 63.9512 27.9354 63.4179 27.9354 62.7599V57.9946Z"
fill="#41D1FF"
/>
<path
d="M27.9354 47.6694C27.9354 47.0114 28.4688 46.478 29.1268 46.478H33.8921C34.5501 46.478 35.0834 47.0114 35.0834 47.6694V52.4347C35.0834 53.0926 34.5501 53.626 33.8921 53.626H29.1268C28.4688 53.626 27.9354 53.0926 27.9354 52.4347V47.6694Z"
fill="#41D1FF"
/>
</g>
<defs>
<filter
id="filter0_d_1_2"
x="35.0831"
y="0.114583"
width="106.183"
height="64.0563"
filterUnits="userSpaceOnUse"
color-interpolation-filters="sRGB"
>
<feFlood flood-opacity="0" result="BackgroundImageFix" />
<feColorMatrix
in="SourceAlpha"
type="matrix"
values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"
result="hardAlpha"
/>
<feOffset dy="2.30833" />
<feGaussianBlur stdDeviation="2.30833" />
<feComposite in2="hardAlpha" operator="out" />
<feColorMatrix
type="matrix"
values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.65 0"
/>
<feBlend
mode="normal"
in2="BackgroundImageFix"
result="effect1_dropShadow_1_2"
/>
<feBlend
mode="normal"
in="SourceGraphic"
in2="effect1_dropShadow_1_2"
result="shape"
/>
</filter>
<filter
id="filter1_i_1_2"
x="10.1243"
y="38.0579"
width="33.7597"
height="33.7597"
filterUnits="userSpaceOnUse"
color-interpolation-filters="sRGB"
>
<feFlood flood-opacity="0" result="BackgroundImageFix" />
<feBlend
mode="normal"
in="SourceGraphic"
in2="BackgroundImageFix"
result="shape"
/>
<feColorMatrix
in="SourceAlpha"
type="matrix"
values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"
result="hardAlpha"
/>
<feOffset />
<feGaussianBlur stdDeviation="2.30833" />
<feComposite in2="hardAlpha" operator="arithmetic" k2="-1" k3="1" />
<feColorMatrix
type="matrix"
values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.85 0"
/>
<feBlend mode="normal" in2="shape" result="effect1_innerShadow_1_2" />
</filter>
<filter
id="filter2_f_1_2"
x="0.802473"
y="28.8757"
width="51.8833"
height="52.6778"
filterUnits="userSpaceOnUse"
color-interpolation-filters="sRGB"
>
<feFlood flood-opacity="0" result="BackgroundImageFix" />
<feBlend
mode="normal"
in="SourceGraphic"
in2="BackgroundImageFix"
result="shape"
/>
<feGaussianBlur
stdDeviation="8.80116"
result="effect1_foregroundBlur_1_2"
/>
</filter>
</defs>
</svg>
<!-- Blue Glow -->
<div class="blue-glow" :class="{ active: active }" />
</template>
<style scoped>
.blue-indicator {
position: absolute;
top: 387px;
left: 680px;
opacity: 0.2;
transition: opacity 1s ease-in-out;
&.active {
transition: opacity 0.2s ease-in-out;
opacity: 0.6;
}
}
.blue-glow {
background-color: #41d1ff;
width: 100px;
aspect-ratio: 2;
position: absolute;
top: 415px;
left: 655px;
z-index: -1;
filter: blur(40px);
opacity: 0;
transition: all 3s ease-out;
will-change: opacity;
display: none;
@media (min-width: 768px) {
display: block;
filter: blur(60px);
}
&.active {
transition: all 0.2s ease-in-out;
opacity: 0.8;
}
}
</style>

View File

@ -0,0 +1,65 @@
<script setup lang="ts">
import SvgNode, { SvgNodeProps } from '../../common/SvgNode.vue'
import { Ref } from 'vue'
defineProps({
inputLines: {
type: Array as () => Ref<SvgNodeProps>[],
required: true,
},
})
</script>
<template>
<svg
xmlns="http://www.w3.org/2000/svg"
width="844"
height="644"
viewBox="0 0 844 644"
fill="none"
class="input-lines"
>
<!-- Input Lines -->
<g v-for="inputLine in inputLines" :key="inputLine.value.path">
<path
:d="inputLine.value.path"
stroke="url(#base_gradient)"
stroke-width="1.2"
style="opacity: 0.8"
/>
<SvgNode v-bind="inputLine.value" />
</g>
<defs>
<linearGradient
id="base_gradient"
x1="88.1032"
y1="324.167"
x2="843.505"
y2="324.167"
gradientUnits="userSpaceOnUse"
>
<stop offset="0" stop-color="#c6caff" stop-opacity="0" />
<stop offset="0.2" stop-color="#c6caff" stop-opacity="0.1" />
<stop offset="0.4" stop-color="white" stop-opacity="0.4" />
<stop offset="0.6" stop-color="#c6caff" stop-opacity="0.2" />
<stop offset="0.8" stop-color="#c6caff" stop-opacity="0.2" />
<stop offset="0.9" stop-color="#c6caff" stop-opacity="0" />
</linearGradient>
</defs>
</svg>
</template>
<style scoped>
.input-lines {
transform: translate3d(0, 0, 0);
&:deep(.circle-dot) {
display: none;
@media (min-width: 768px) {
display: block;
}
}
}
</style>

View File

@ -0,0 +1,56 @@
<script setup lang="ts">
import SvgNode, { SvgNodeProps } from '../../common/SvgNode.vue'
import { Ref } from 'vue'
defineProps({
outputLines: {
type: Array as () => Ref<SvgNodeProps>[],
required: true,
},
})
</script>
<template>
<svg
xmlns="http://www.w3.org/2000/svg"
width="844"
height="80"
viewBox="0 0 844 40"
fill="none"
class="output-line"
style="opacity: 0.8"
>
<path
d="M843.463 1.3315L245.316 5.47507L0.633077 4.69725"
stroke="url(#output_gradient)"
stroke-width="1.2"
/>
<g v-for="outputLine in outputLines">
<SvgNode
path="M843.463 1.3315L245.316 5.47507L0.633077 4.69725"
:position="outputLine.value.position"
:visible="outputLine.value.visible"
:label-visible="outputLine.value.labelVisible"
:label="outputLine.value.label"
dot-color="#d499ff"
glow-color="#BD34FE"
/>
</g>
<defs>
<linearGradient id="output_gradient" gradientUnits="userSpaceOnUse">
<stop offset="0.1" stop-color="#E0C8FF" stop-opacity="0" />
<stop offset="0.4" stop-color="#E0C8FF" stop-opacity="0.4" />
<stop offset="1" stop-color="#E0C8FF" stop-opacity="0" />
</linearGradient>
</defs>
</svg>
</template>
<style scoped>
.output-line {
position: absolute;
top: 300px;
left: 785px;
transform: translate3d(0, 0, 0);
}
</style>

View File

@ -0,0 +1,253 @@
<script setup lang="ts">
defineProps({
active: {
type: Boolean,
required: true,
default: false,
},
})
</script>
<template>
<svg
width="141"
height="67"
viewBox="0 0 141 67"
fill="none"
xmlns="http://www.w3.org/2000/svg"
class="pink-indicator"
:class="{ active: active }"
>
<g opacity="0.2" filter="url(#filter0_d_1_8)">
<path
fill-rule="evenodd"
clip-rule="evenodd"
d="M5.48397 58.9922L5.48397 36.8651C5.48397 30.4908 10.6514 25.3234 17.0256 25.3234L101.28 25.3234L101.28 27.6318L17.0256 27.6318C11.9262 27.6318 7.7923 31.7657 7.7923 36.8651L7.7923 58.9922L5.48397 58.9922Z"
fill="#0D0D0D"
/>
<path
d="M5.19543 58.9922L5.19543 59.2807L5.48397 59.2807L7.79231 59.2807L8.08085 59.2807L8.08085 58.9922L8.08085 36.8651C8.08085 31.925 12.0856 27.9203 17.0256 27.9203L101.28 27.9203L101.568 27.9203L101.568 27.6318L101.568 25.3234L101.568 25.0349L101.28 25.0349L17.0256 25.0349C10.492 25.0349 5.19542 30.3315 5.19543 36.8651L5.19543 58.9922Z"
stroke="#404040"
stroke-width="0.577083"
/>
</g>
<g filter="url(#filter1_i_1_8)">
<rect
x="130.134"
y="12.0518"
width="30.0083"
height="30.0083"
rx="5.01812"
transform="rotate(90 130.134 12.0518)"
fill="#1F1F1F"
/>
</g>
<rect
x="130.134"
y="12.0518"
width="30.0083"
height="30.0083"
rx="5.01812"
transform="rotate(90 130.134 12.0518)"
stroke="#2C2C2C"
stroke-opacity="0.4"
stroke-width="3.75141"
/>
<g filter="url(#filter2_f_1_8)">
<path
d="M123.152 23.9976C123.152 24.6556 122.619 25.1889 121.961 25.1889L117.196 25.1889C116.538 25.1889 116.004 24.6556 116.004 23.9976L116.004 19.2323C116.004 18.5743 116.538 18.041 117.196 18.041L121.961 18.041C122.619 18.041 123.152 18.5743 123.152 19.2323L123.152 23.9976Z"
fill="#BD34FE"
/>
<path
d="M113.622 23.9976C113.622 24.6556 113.088 25.1889 112.43 25.1889L107.665 25.1889C107.007 25.1889 106.474 24.6556 106.474 23.9976L106.474 19.2323C106.474 18.5743 107.007 18.041 107.665 18.041L112.43 18.041C113.088 18.041 113.622 18.5743 113.622 19.2323L113.622 23.9976Z"
fill="#BD34FE"
/>
<path
d="M113.622 34.3228C113.622 34.9808 113.088 35.5142 112.43 35.5142L107.665 35.5142C107.007 35.5142 106.474 34.9808 106.474 34.3228L106.474 29.5575C106.474 28.8996 107.007 28.3662 107.665 28.3662L112.43 28.3662C113.088 28.3662 113.622 28.8996 113.622 29.5575L113.622 34.3228Z"
fill="#BD34FE"
/>
</g>
<rect
x="110.513"
y="22.439"
width="9.23333"
height="9.23333"
rx="1.15417"
fill="#BD34FE"
v-show="active"
/>
<rect
x="110.513"
y="22.439"
width="9.23333"
height="9.23333"
rx="1.15417"
fill="white"
fill-opacity="0.5"
/>
<g filter="url(#filter3_f_1_8)">
<rect
x="108.205"
y="20.1309"
width="13.85"
height="13.85"
rx="1.73125"
fill="#BD34FE"
fill-opacity="0.5"
v-show="active"
/>
</g>
<defs>
<filter
id="filter0_d_1_8"
x="0.290218"
y="22.438"
width="106.183"
height="44.0563"
filterUnits="userSpaceOnUse"
color-interpolation-filters="sRGB"
>
<feFlood flood-opacity="0" result="BackgroundImageFix" />
<feColorMatrix
in="SourceAlpha"
type="matrix"
values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"
result="hardAlpha"
/>
<feOffset dy="2.30833" />
<feGaussianBlur stdDeviation="2.30833" />
<feComposite in2="hardAlpha" operator="out" />
<feColorMatrix
type="matrix"
values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.65 0"
/>
<feBlend
mode="normal"
in2="BackgroundImageFix"
result="effect1_dropShadow_1_8"
/>
<feBlend
mode="normal"
in="SourceGraphic"
in2="effect1_dropShadow_1_8"
result="shape"
/>
</filter>
<filter
id="filter1_i_1_8"
x="98.2503"
y="10.1761"
width="33.7597"
height="33.7597"
filterUnits="userSpaceOnUse"
color-interpolation-filters="sRGB"
>
<feFlood flood-opacity="0" result="BackgroundImageFix" />
<feBlend
mode="normal"
in="SourceGraphic"
in2="BackgroundImageFix"
result="shape"
/>
<feColorMatrix
in="SourceAlpha"
type="matrix"
values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"
result="hardAlpha"
/>
<feOffset />
<feGaussianBlur stdDeviation="2.30833" />
<feComposite in2="hardAlpha" operator="arithmetic" k2="-1" k3="1" />
<feColorMatrix
type="matrix"
values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.85 0"
/>
<feBlend mode="normal" in2="shape" result="effect1_innerShadow_1_8" />
</filter>
<filter
id="filter2_f_1_8"
x="88.8714"
y="0.438646"
width="51.8833"
height="52.6778"
filterUnits="userSpaceOnUse"
color-interpolation-filters="sRGB"
>
<feFlood flood-opacity="0" result="BackgroundImageFix" />
<feBlend
mode="normal"
in="SourceGraphic"
in2="BackgroundImageFix"
result="shape"
/>
<feGaussianBlur
stdDeviation="8.80116"
result="effect1_foregroundBlur_1_8"
/>
</filter>
<filter
id="filter3_f_1_8"
x="96.6634"
y="8.58919"
width="36.9333"
height="36.9333"
filterUnits="userSpaceOnUse"
color-interpolation-filters="sRGB"
>
<feFlood flood-opacity="0" result="BackgroundImageFix" />
<feBlend
mode="normal"
in="SourceGraphic"
in2="BackgroundImageFix"
result="shape"
/>
<feGaussianBlur
stdDeviation="5.77083"
result="effect1_foregroundBlur_1_8"
/>
</filter>
</defs>
</svg>
<!-- Pink Glow -->
<div class="pink-glow" :class="{ active: active }" />
</template>
<style scoped>
.pink-indicator {
position: absolute;
top: 202px;
left: 840px;
opacity: 0.2;
transition: opacity 1s ease-in-out;
&.active {
transition: opacity 0.2s ease-in-out;
opacity: 0.6;
}
}
.pink-glow {
background-color: #bd34fe;
width: 100px;
aspect-ratio: 2;
position: absolute;
top: 202px;
left: 905px;
z-index: -1;
filter: blur(40px);
opacity: 0;
transition: all 3s ease-out;
will-change: opacity;
display: none;
@media (min-width: 768px) {
display: block;
filter: blur(60px);
}
&.active {
transition: all 0.2s ease-in-out;
opacity: 0.8;
}
}
</style>

View File

@ -0,0 +1,503 @@
<script setup lang="ts">
import { Ref, ref } from 'vue'
import SvgNode from '../common/SvgNode.vue'
import { gsap } from 'gsap'
import { useSlideIn } from '../../../composables/useSlideIn'
import { useCardAnimation } from '../../../composables/useCardAnimation'
// Animation state
const glowPosition: Ref<number> = ref(0)
const glowVisible: Ref<boolean> = ref(false)
const checkmarks = Array.from({ length: 13 }, (): Ref<boolean> => ref(false))
/**
* Slide the card in when the page loads
*/
useSlideIn('#continuous-integration')
/**
* Start the animation when the card is hovered
*/
const { startAnimation, isCardActive } = useCardAnimation(
'#continuous-integration',
() => {
// Reset initial state
glowPosition.value = 0
glowVisible.value = false
// Define the timeline
const timeline = gsap.timeline()
// Move the glowing lines from top to bottom
timeline.to(
glowPosition,
{
value: 1,
duration: 1.5,
ease: 'power2.in',
},
0,
)
// Make the glowing lines visible
timeline.call(
() => {
glowVisible.value = true
},
null,
0.2,
)
// Make the glowing lines hidden shortly after
timeline.call(
() => {
glowVisible.value = false
},
null,
1.1,
)
// Stagger the checkmarks
checkmarks.forEach((checkmark, index) => {
timeline.call(
() => {
checkmark.value = true
},
null,
1.3 + index * 0.2,
)
})
// All done
return timeline
},
{
once: true,
},
)
</script>
<template>
<div
class="feature-card"
id="continuous-integration"
@mouseover.stop.prevent="startAnimation"
>
<div class="feature__visualization" :class="{ active: isCardActive }">
<div class="camera-container">
<svg
class="grid"
width="720"
height="241"
viewBox="0 0 720 241"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M1.00048 119.402L200.243 68.2732C213.283 65.4129 221.832 58.4923 221.832 50.7968V20.323V1M1.00048 136.779L231.212 68.7423C242.847 65.5523 250.195 59.0356 250.195 51.9076V20.323V1M1 165.731L263.267 69.1267C272.82 65.6348 278.558 59.7587 278.558 53.4667V20.323V1M719.001 154.23L464.019 69.1276C454.474 65.6348 448.743 59.7616 448.743 53.4731V20.323V1M719.001 125.219L496.078 68.7439C484.449 65.5528 477.106 59.0377 477.106 51.9119V20.323V1M719 107.817L527.05 68.2749C514.015 65.4134 505.469 58.4939 505.469 50.8001V20.323V1M719.001 96.2159L557.314 67.8323C543.291 65.2673 533.835 58.0756 533.835 49.976V20.323V9.78386C533.835 4.93267 529.902 1 525.051 1H505.469M1 107.817L169.982 67.8308C184.008 65.2668 193.467 58.0743 193.467 49.9735V20.323V9.78387C193.467 4.93267 197.4 1 202.251 1H221.832M221.832 1H250.195M250.195 1H278.558M278.558 1H306.924M306.924 1V20.323V55.7423C306.924 60.7337 303.306 65.5207 296.865 69.0509L62.8139 197.336C52.968 202.733 46.8471 213.068 46.8471 224.296V240.342M306.924 1H335.286M335.286 1V20.323V59.0919C335.286 62.0155 334.043 64.8989 331.656 67.5136L213.175 197.282C208.003 202.947 205.136 210.34 205.136 218.011V240.342M335.286 1H363.65M363.65 1V20.323L363.428 206.088V240.342M363.65 1H392.015M392.015 1V20.323V59.1056C392.015 62.0204 393.25 64.8954 395.624 67.5041L513.712 197.291C518.862 202.951 521.716 210.328 521.716 217.981V240.342M392.015 1H420.377M420.377 1V20.323V55.7518C420.377 60.7376 423.987 65.5197 430.415 69.0489L664.058 197.332C673.893 202.732 680.005 213.061 680.005 224.28V240.342M420.377 1H448.743M448.743 1H477.106M477.106 1H505.469"
stroke="url(#paint0_linear_0_3)"
/>
<defs>
<linearGradient
id="paint0_linear_0_3"
x1="362.013"
y1="-25.478"
x2="362.013"
y2="240.781"
gradientUnits="userSpaceOnUse"
>
<stop offset="0" stop-color="white" stop-opacity="0" />
<stop offset="0.7" stop-color="white" stop-opacity="0.35" />
<stop offset="1" stop-color="white" stop-opacity="0" />
</linearGradient>
</defs>
</svg>
<span class="ci-text">CI Tests</span>
<div class="checkmark-container">
<svg
class="checkmark"
v-for="i in 5"
:class="{ active: checkmarks[i].value }"
width="52"
height="52"
viewBox="0 0 52 52"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<g
class="circle-glow"
opacity="0.4"
filter="url(#filter-circle-glow)"
>
<circle cx="25.712" cy="25.9725" r="17.6105" fill="#13B351" />
</g>
<circle
class="circle-bg"
cx="25.712"
cy="25.9725"
r="18.0268"
fill="#171717"
/>
<circle
class="circle-specular"
cx="25.712"
cy="25.9725"
r="18.0268"
stroke="url(#radial-circle-specular)"
stroke-width="0.8"
/>
<path
class="checkmark-icon"
d="M32.4256 21.1798C32.3326 21.086 32.2219 21.0115 32.1 20.9607C31.9781 20.9099 31.8473 20.8838 31.7152 20.8838C31.5831 20.8838 31.4523 20.9099 31.3304 20.9607C31.2085 21.0115 31.0978 21.086 31.0048 21.1798L23.5504 28.6442L20.4185 25.5023C20.3219 25.409 20.2079 25.3357 20.083 25.2864C19.9581 25.2372 19.8246 25.2131 19.6904 25.2154C19.5561 25.2177 19.4236 25.2465 19.3005 25.3C19.1773 25.3535 19.0659 25.4308 18.9726 25.5273C18.8793 25.6239 18.806 25.7379 18.7568 25.8629C18.7075 25.9878 18.6834 26.1212 18.6857 26.2555C18.688 26.3897 18.7168 26.5222 18.7703 26.6454C18.8238 26.7685 18.9011 26.8799 18.9977 26.9732L22.8399 30.8155C22.933 30.9093 23.0436 30.9837 23.1656 31.0345C23.2875 31.0853 23.4183 31.1115 23.5504 31.1115C23.6824 31.1115 23.8132 31.0853 23.9352 31.0345C24.0571 30.9837 24.1678 30.9093 24.2608 30.8155L32.4256 22.6506C32.5272 22.5569 32.6082 22.4432 32.6637 22.3166C32.7191 22.1901 32.7477 22.0534 32.7477 21.9152C32.7477 21.777 32.7191 21.6403 32.6637 21.5138C32.6082 21.3872 32.5272 21.2735 32.4256 21.1798Z"
fill="#7fd5a0"
/>
<g
class="checkmark-icon__glow"
filter="url(#filter-checkmark-icon-glow)"
>
<path
d="M32.4256 21.1798C32.3326 21.086 32.2219 21.0115 32.1 20.9607C31.9781 20.9099 31.8473 20.8838 31.7152 20.8838C31.5831 20.8838 31.4523 20.9099 31.3304 20.9607C31.2085 21.0115 31.0978 21.086 31.0048 21.1798L23.5504 28.6442L20.4185 25.5023C20.3219 25.409 20.2079 25.3357 20.083 25.2864C19.9581 25.2372 19.8246 25.2131 19.6904 25.2154C19.5561 25.2177 19.4236 25.2465 19.3005 25.3C19.1773 25.3535 19.0659 25.4308 18.9726 25.5273C18.8793 25.6239 18.806 25.7379 18.7568 25.8629C18.7075 25.9878 18.6834 26.1212 18.6857 26.2555C18.688 26.3897 18.7168 26.5222 18.7703 26.6454C18.8238 26.7685 18.9011 26.8799 18.9977 26.9732L22.8399 30.8155C22.933 30.9093 23.0436 30.9837 23.1656 31.0345C23.2875 31.0853 23.4183 31.1115 23.5504 31.1115C23.6824 31.1115 23.8132 31.0853 23.9352 31.0345C24.0571 30.9837 24.1678 30.9093 24.2608 30.8155L32.4256 22.6506C32.5272 22.5569 32.6082 22.4432 32.6637 22.3166C32.7191 22.1901 32.7477 22.0534 32.7477 21.9152C32.7477 21.777 32.7191 21.6403 32.6637 21.5138C32.6082 21.3872 32.5272 21.2735 32.4256 21.1798Z"
fill="#13B351"
/>
</g>
<defs>
<filter
id="filter-circle-glow"
x="0.0968113"
y="0.357309"
width="51.2302"
height="51.2304"
filterUnits="userSpaceOnUse"
color-interpolation-filters="sRGB"
>
<feFlood flood-opacity="0" result="BackgroundImageFix" />
<feBlend
mode="normal"
in="SourceGraphic"
in2="BackgroundImageFix"
result="shape"
/>
<feGaussianBlur
stdDeviation="4.00238"
result="effect1_foregroundBlur_698_23226"
/>
</filter>
<filter
id="filter-checkmark-icon-glow"
x="-2.30491"
y="-2.04392"
width="56.0332"
height="56.0332"
filterUnits="userSpaceOnUse"
color-interpolation-filters="sRGB"
>
<feFlood flood-opacity="0" result="BackgroundImageFix" />
<feBlend
mode="normal"
in="SourceGraphic"
in2="BackgroundImageFix"
result="shape"
/>
<feGaussianBlur
stdDeviation="8.00475"
result="effect1_foregroundBlur_698_23226"
/>
</filter>
<radialGradient
id="radial-circle-specular"
cx="0"
cy="0"
r="1"
gradientUnits="userSpaceOnUse"
gradientTransform="translate(33.4166 23.1423) rotate(110.653) scale(21.8445)"
>
<stop offset="0" stop-color="white" />
<stop offset="1" stop-opacity="0" />
</radialGradient>
</defs>
</svg>
</div>
<svg
class="grid"
width="720"
height="241"
viewBox="0 0 720 241"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<SvgNode
path="M1.00048 119.402L200.243 68.2732C213.283 65.4129 221.832 58.4923 221.832 50.7968V20.323V1"
:position="glowPosition"
:visible="glowVisible"
:dot-color="false"
glow-color="#13B351"
/>
<SvgNode
path="M1.00048 136.779L231.212 68.7423C242.847 65.5523 250.195 59.0356 250.195 51.9076V20.323V1"
:position="glowPosition"
:visible="glowVisible"
:dot-color="false"
glow-color="#13B351"
/>
<SvgNode
path="M1 165.731L263.267 69.1267C272.82 65.6348 278.558 59.7587 278.558 53.4667V20.323V1"
:position="glowPosition"
:visible="glowVisible"
:dot-color="false"
glow-color="#13B351"
/>
<SvgNode
path="M719.001 154.23L464.019 69.1276C454.474 65.6348 448.743 59.7616 448.743 53.4731V20.323V1"
:position="glowPosition"
:visible="glowVisible"
:dot-color="false"
glow-color="#13B351"
/>
<SvgNode
path="M719.001 125.219L496.078 68.7439C484.449 65.5528 477.106 59.0377 477.106 51.9119V20.323V1"
:position="glowPosition"
:visible="glowVisible"
:dot-color="false"
glow-color="#13B351"
/>
<SvgNode
path="M719 107.817L527.05 68.2749C514.015 65.4134 505.469 58.4939 505.469 50.8001V20.323V1"
:position="glowPosition"
:visible="glowVisible"
:dot-color="false"
glow-color="#13B351"
/>
<SvgNode
path="M719.001 96.2159L557.314 67.8323C543.291 65.2673 533.835 58.0756 533.835 49.976V20.323V9.78386C533.835 4.93267 529.902 1 525.051 1"
:position="glowPosition"
:visible="glowVisible"
:dot-color="false"
glow-color="#13B351"
/>
<SvgNode
path="M1 107.817L169.982 67.8308C184.008 65.2668 193.467 58.0743 193.467 49.9735V20.323V9.78387C193.467 4.93267 197.4 1 202.251 1"
:position="glowPosition"
:visible="glowVisible"
:dot-color="false"
glow-color="#13B351"
/>
<SvgNode
path="M306.924 1V20.323V55.7423C306.924 60.7337 303.306 65.5207 296.865 69.0509L62.8139 197.336C52.968 202.733 46.8471 213.068 46.8471 224.296V240.342"
:position="1 - glowPosition"
:visible="glowVisible"
:dot-color="false"
glow-color="#13B351"
/>
<SvgNode
path="M335.286 1V20.323V59.0919C335.286 62.0155 334.043 64.8989 331.656 67.5136L213.175 197.282C208.003 202.947 205.136 210.34 205.136 218.011V240.342"
:position="1 - glowPosition"
:visible="glowVisible"
:dot-color="false"
glow-color="#13B351"
/>
<SvgNode
path="M363.65 1V20.323L363.428 206.088V240.342"
:position="1 - glowPosition"
:visible="glowVisible"
:dot-color="false"
glow-color="#13B351"
/>
<SvgNode
path="M392.015 1V20.323V59.1056C392.015 62.0204 393.25 64.8954 395.624 67.5041L513.712 197.291C518.862 202.951 521.716 210.328 521.716 217.981V240.342"
:position="1 - glowPosition"
:visible="glowVisible"
:dot-color="false"
glow-color="#13B351"
/>
<SvgNode
path="M420.377 1V20.323V55.7518C420.377 60.7376 423.987 65.5197 430.415 69.0489L664.058 197.332C673.893 202.732 680.005 213.061 680.005 224.28V240.342"
:position="1 - glowPosition"
:visible="glowVisible"
:dot-color="false"
glow-color="#13B351"
/>
</svg>
</div>
</div>
<div class="feature__meta meta--center">
<div class="meta__title">Continuous ecosystem integration</div>
<div class="meta__description">
Our CI continuously tests Vite changes against downstream projects,
allowing us to improve Vite with stability and confidence.
</div>
</div>
</div>
</template>
<style scoped>
.feature-card {
@media (min-width: 768px) {
transform: translate3d(60px, 0, 0);
}
.feature__meta {
max-width: 500px;
}
/* Extend height on smaller devices, to make room for text */
@media (max-width: 450px) {
height: 420px;
}
/* Even smaller in some cases */
@media (max-width: 380px) {
height: 460px;
}
}
.feature__visualization {
mask-image: linear-gradient(
to bottom,
#ffffff,
#ffffff 180px,
transparent 240px
);
position: relative;
.camera-container {
width: 720px;
left: 50%;
position: relative;
transition: transform 3s ease;
transform: translate3d(-50%, 80px, 0) scale(1.05);
}
.grid {
position: absolute;
top: 0;
left: 0;
width: 720px;
}
.ci-text {
position: absolute;
top: -10px;
left: 319px;
color: #fff;
text-align: center;
font-family:
IBM Plex Mono,
sans-serif;
font-size: 12px;
font-style: normal;
font-weight: 500;
line-height: 150%;
display: block;
border-radius: 6px;
border: 1px solid #2c2c2c;
background: #171717;
padding: 6px 14px;
z-index: 5;
}
.checkmark-container {
position: relative;
&:after {
content: '';
position: absolute;
top: 160px;
left: 0;
right: 0;
width: 100%;
height: 200px;
background: linear-gradient(
to bottom,
transparent,
rgba(19, 179, 81, 0.5)
);
transition: all 3s ease;
transform: translate3d(0, 0, 0) scaleY(0);
opacity: 0;
will-change: transform, opacity;
}
}
.checkmark {
position: absolute;
top: 220px;
filter: drop-shadow(0px 0px 0px rgba(19, 179, 81, 0));
z-index: 5;
.circle-glow,
.checkmark-icon__glow,
.checkmark-icon {
opacity: 0;
transition: opacity 0.5s ease-in-out;
}
&:nth-child(1) {
left: 22px;
}
&:nth-child(2) {
left: 180px;
}
&:nth-child(3) {
left: 338px;
}
&:nth-child(4) {
left: 497px;
}
&:nth-child(5) {
left: 655px;
}
&:not(:nth-child(3)) {
display: none;
}
@media (min-width: 500px) {
&:not(:nth-child(3)) {
display: block;
}
}
@media (min-width: 640px) {
&:not(:nth-child(3)) {
display: none;
}
}
@media (min-width: 1040px) {
&:not(:nth-child(3)) {
display: block;
}
}
&.active {
filter: drop-shadow(0px -20px 20px rgba(19, 179, 81, 0.7));
.circle-glow,
.checkmark-icon__glow,
.checkmark-icon {
transition: opacity 0.15s ease-in-out;
opacity: 1;
}
}
}
&.active {
.checkmark-container {
&:after {
transition-delay: 2.5s;
transition-duration: 0.5s;
transform: translate3d(0, 0, 0) scaleY(1);
opacity: 1;
}
}
.camera-container {
transition: transform 1.5s ease 1s;
transform: translate3d(-50%, -100px, 0) scale(1.05);
}
}
}
</style>

View File

@ -0,0 +1,557 @@
<script setup lang="ts">
import { useSlideIn } from '../../../composables/useSlideIn'
import { useCardAnimation } from '../../../composables/useCardAnimation'
/**
* Slide the card in when the page loads
*/
useSlideIn('#flexible-plugin-system')
/**
* Start the animation when the card is hovered
*/
const { isCardActive, startAnimation } = useCardAnimation(
'#flexible-plugin-system',
null,
{
once: true,
},
)
</script>
<template>
<div
class="feature-card"
id="flexible-plugin-system"
@mouseover.stop.prevent="startAnimation"
>
<div class="feature__visualization" :class="{ active: isCardActive }">
<div class="diagram">
<!-- Diagram -->
<svg
width="686"
height="218"
viewBox="0 0 686 218"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<g>
<g class="pink-chip__base">
<rect
width="35.0955"
height="35.0923"
rx="5.87331"
transform="matrix(-0.845602 0.533814 -0.895247 -0.44557 611.937 102.855)"
fill="#1F1F1F"
/>
<rect
width="35.0955"
height="35.0923"
rx="5.87331"
transform="matrix(-0.845602 0.533814 -0.895247 -0.44557 611.937 102.855)"
stroke="#2C2C2C"
stroke-opacity="0.4"
stroke-width="4"
/>
</g>
<g class="pink-chip__cube">
<path
d="M573.798 105.165L573.684 96.2398L581.79 90.9291L590.029 96.0306L590.143 104.956L582.027 109.523L573.798 105.165Z"
fill="#BD34FE"
/>
<path
d="M573.798 105.165L573.684 96.2398L581.79 90.9291L590.029 96.0306L590.143 104.956L582.027 109.523L573.798 105.165Z"
fill="white"
fill-opacity="0.5"
/>
</g>
<path
class="pink-chip__connection"
fill-rule="evenodd"
clip-rule="evenodd"
d="M440.083 64.7972L456.9 53.3972C463.204 49.4177 473.724 48.8842 480.397 52.2055L565 94.5L562.717 95.9411L478.114 53.6466C472.776 50.9895 464.359 51.4164 459.316 54.6L442.5 66L440.083 64.7972Z"
fill="#BD34FE"
stroke-width="1.2"
stroke="#BD34FE"
/>
<path
class="blue-chip__connection"
fill-rule="evenodd"
clip-rule="evenodd"
d="M270 130L230.567 154.669C224.263 158.648 213.743 159.182 207.07 155.86L122.717 113.941L125 112.5L209.353 154.419C214.691 157.076 223.108 156.65 228.151 153.466L267.583 128.797L270 130Z"
fill="#41d1ff"
stroke-width="1.2"
stroke="#41d1ff"
/>
<g class="blue-chip__base">
<rect
width="35.0955"
height="35.0923"
rx="5.87331"
transform="matrix(0.845602 -0.533814 0.895247 0.44557 76.1337 105.512)"
fill="#1F1F1F"
shape-rendering="crispEdges"
/>
<rect
width="35.0955"
height="35.0923"
rx="5.87331"
transform="matrix(0.845602 -0.533814 0.895247 0.44557 76.1337 105.512)"
stroke="#2C2C2C"
stroke-opacity="0.4"
stroke-width="4.39073"
shape-rendering="crispEdges"
/>
</g>
<g class="blue-chip__cube">
<path
d="M99.902 97.3307L99.7304 90.3097L106.066 86.0571L112.601 89.995L112.773 97.016L106.423 100.684L99.902 97.3307Z"
fill="#41D1FF"
/>
<path
d="M99.902 97.3307L99.7304 90.3097L106.066 86.0571L112.601 89.995L112.773 97.016L106.423 100.684L99.902 97.3307Z"
fill="white"
fill-opacity="0.5"
/>
<path
d="M110.272 103.431L110.1 96.4099L116.435 92.1574L122.971 96.0953L123.143 103.116L116.793 106.784L110.272 103.431Z"
fill="#41D1FF"
/>
<path
d="M110.272 103.431L110.1 96.4099L116.435 92.1574L122.971 96.0953L123.143 103.116L116.793 106.784L110.272 103.431Z"
fill="white"
fill-opacity="0.5"
/>
<path
d="M89.6627 103.976L89.491 96.9545L95.8263 92.7019L102.362 96.6398L102.533 103.661L96.1839 107.328L89.6627 103.976Z"
fill="#41D1FF"
/>
<path
d="M89.6627 103.976L89.491 96.9545L95.8263 92.7019L102.362 96.6398L102.533 103.661L96.1839 107.328L89.6627 103.976Z"
fill="white"
fill-opacity="0.5"
/>
<path
d="M99.4817 109.323L99.31 102.302L105.645 98.0495L112.181 101.987L112.352 109.008L106.003 112.676L99.4817 109.323Z"
fill="#41D1FF"
/>
<path
d="M99.4817 109.323L99.31 102.302L105.645 98.0495L112.181 101.987L112.352 109.008L106.003 112.676L99.4817 109.323Z"
fill="white"
fill-opacity="0.5"
/>
</g>
<g class="vite-chip" filter="url(#filter-chip-shadow)">
<g
class="vite-chip__highlight"
filter="url(#filter-vite-chip-highlight)"
>
<rect
width="153.998"
height="153.998"
rx="12.1578"
transform="matrix(0.895247 0.44557 -0.845602 0.533814 330.524 11.7643)"
fill="black"
fill-opacity="0.3"
/>
<rect
width="153.998"
height="153.998"
rx="12.1578"
transform="matrix(0.895247 0.44557 -0.845602 0.533814 330.524 11.7643)"
fill="url(#gradient-vite-chip-highlight)"
fill-opacity="0.1"
/>
<rect
x="-0.0335319"
y="-0.661506"
width="155.349"
height="155.349"
rx="12.8332"
transform="matrix(0.895247 0.44557 -0.845602 0.533814 329.961 11.4709)"
stroke="#111111"
stroke-opacity="0.2"
stroke-width="1.35086"
/>
</g>
<g class="vite-chip__base" opacity="0.6">
<rect
x="-0.0335319"
y="-0.661506"
width="152.647"
height="152.647"
rx="11.4823"
transform="matrix(0.895247 0.44557 -0.845602 0.533814 330.028 12.7942)"
fill="#1E1E1E"
fill-opacity="0.4"
/>
<rect
x="-0.0335319"
y="-0.661506"
width="152.647"
height="152.647"
rx="11.4823"
transform="matrix(0.895247 0.44557 -0.845602 0.533814 330.028 12.7942)"
stroke="url(#gradient-vite-chip-right-specular)"
stroke-width="1.2"
/>
<rect
x="-0.0335319"
y="-0.661506"
width="152.647"
height="152.647"
rx="11.4823"
transform="matrix(0.895247 0.44557 -0.845602 0.533814 330.028 12.7942)"
stroke="url(#gradient-vite-chip-left-specular)"
stroke-opacity="0.1"
stroke-width="1.2"
/>
</g>
<g class="vite-chip__logo">
<path
class="vite-chip__v"
opacity="0.8"
d="M395.642 83.0289L299.921 103.639C297.944 104.064 296.066 103.138 296.569 101.986L321.062 45.9169C321.611 44.6617 324.458 44.2276 325.784 45.1971L355.04 66.5878C355.227 66.7242 355.458 66.8388 355.722 66.926L396.329 80.3179C398.203 80.9357 397.789 82.5664 395.642 83.0289Z"
fill="url(#gradient-vite-chip-logo-v)"
/>
<path
class="vite-chip__bolt"
d="M385.841 66.1307L354.84 56.2356C354.33 56.0729 353.664 56.1348 353.22 56.386L325.622 71.9952C324.972 72.3629 325.084 72.9547 325.845 73.178L334.719 75.7797C335.549 76.0232 335.589 76.6913 334.794 77.0355L322.502 82.3582C321.675 82.7165 321.759 83.4171 322.656 83.6352L328.452 85.0438C329.35 85.2623 329.434 85.9642 328.604 86.3219L309.255 94.6628C308.045 95.1845 308.884 96.2149 310.314 95.9628L311.269 95.7944L373.22 80.696C374.258 80.4432 374.42 79.6472 373.495 79.3499L364.632 76.5008C363.799 76.233 363.829 75.5392 364.686 75.2218L385.79 67.4107C386.649 67.0927 386.677 66.3975 385.841 66.1307Z"
fill="url(#gradient-vite-chip-logo-bolt)"
/>
</g>
</g>
</g>
<defs>
<filter
id="filter-chip-shadow"
x="158.878"
y="-7.1193"
width="350.919"
height="231.696"
filterUnits="userSpaceOnUse"
color-interpolation-filters="sRGB"
>
<feFlood flood-opacity="0" result="BackgroundImageFix" />
<feColorMatrix
in="SourceAlpha"
type="matrix"
values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"
result="hardAlpha"
/>
<feOffset dy="21.6138" />
<feGaussianBlur stdDeviation="19.5875" />
<feComposite in2="hardAlpha" operator="out" />
<feColorMatrix
type="matrix"
values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.5 0"
/>
<feBlend
mode="normal"
in2="BackgroundImageFix"
result="effect1_dropShadow_0_5"
/>
<feBlend
mode="normal"
in="SourceGraphic"
in2="effect1_dropShadow_0_5"
result="shape"
/>
</filter>
<filter
id="filter-vite-chip-highlight"
x="177.815"
y="-12.739"
width="313.063"
height="199.83"
filterUnits="userSpaceOnUse"
color-interpolation-filters="sRGB"
>
<feFlood flood-opacity="0" result="BackgroundImageFix" />
<feGaussianBlur in="BackgroundImageFix" stdDeviation="13.5086" />
<feComposite
in2="SourceAlpha"
operator="in"
result="effect1_backgroundBlur_0_5"
/>
<feBlend
mode="normal"
in="SourceGraphic"
in2="effect1_backgroundBlur_0_5"
result="shape"
/>
</filter>
<linearGradient
id="gradient-vite-chip-highlight"
x1="6.7543"
y1="16.8858"
x2="131.709"
y2="135.086"
gradientUnits="userSpaceOnUse"
>
<stop offset="0" stop-opacity="0" />
<stop offset="0.4" stop-color="white" />
<stop offset="1" stop-opacity="0" />
</linearGradient>
<radialGradient
id="gradient-vite-chip-right-specular"
cx="0"
cy="0"
r="1"
gradientUnits="userSpaceOnUse"
gradientTransform="translate(108.744 63.4905) rotate(110.653) scale(93.8362)"
>
<stop offset="0" stop-color="white" />
<stop offset="1" stop-opacity="0" />
</radialGradient>
<radialGradient
id="gradient-vite-chip-left-specular"
cx="0"
cy="0"
r="1"
gradientUnits="userSpaceOnUse"
gradientTransform="translate(7.42974 141.165) rotate(-21.5713) scale(93.6927)"
>
<stop offset="0" stop-color="white" />
<stop offset="1" stop-opacity="0" />
</radialGradient>
<linearGradient
id="gradient-vite-chip-logo-v"
x1="325.064"
y1="42.3995"
x2="323.283"
y2="100.669"
gradientUnits="userSpaceOnUse"
>
<stop offset="0" stop-color="#41D1FF" />
<stop offset="1" stop-color="#BD34FE" />
</linearGradient>
<linearGradient
id="gradient-vite-chip-logo-bolt"
x1="365.666"
y1="57.5919"
x2="348.858"
y2="104.372"
gradientUnits="userSpaceOnUse"
>
<stop offset="0" stop-color="#FFEA83" />
<stop offset="0.08" stop-color="#FFDD35" />
<stop offset="1" stop-color="#FFA800" />
</linearGradient>
</defs>
</svg>
<!-- Blue Glow -->
<div class="blue-glow" />
<!-- Pink Glow -->
<div class="pink-glow" />
</div>
</div>
<div class="feature__meta">
<div class="meta__title">Flexible plugin system</div>
<div class="meta__description">
Vite plugins extends Rollup's well-designed plugin interface with a few
extra Vite-specific options.
</div>
</div>
</div>
</template>
<style scoped>
.feature-card {
@media (min-width: 768px) {
transform: translate3d(-60px, 0, 0);
}
.feature__meta {
max-width: 680px;
}
/* Extend height on smaller devices, to make room for text */
@media (max-width: 330px) {
height: 400px;
}
}
.feature__visualization {
.diagram {
width: fit-content;
position: absolute;
left: 50%;
transform-origin: center 40%;
transform: translate3d(-50%, 0, 0) scale(0.5);
margin-top: 0;
@media (min-width: 480px) {
transform-origin: center center;
transform: translate3d(-50%, 0, 0) scale(0.7);
}
@media (min-width: 630px) {
transform: translate3d(-50%, 0, 0) scale(1);
margin-top: 20px;
}
@media (min-width: 768px) {
transform: translate3d(-50%, 0, 0) scale(0.6);
margin-top: 0;
}
@media (min-width: 1000px) {
transform: translate3d(-50%, 0, 0) scale(0.8);
margin-top: 20px;
}
@media (min-width: 1200px) {
transform: translate3d(-50%, 0, 0) scale(1);
}
}
.blue-chip__cube,
.pink-chip__cube {
transition:
transform 0.5s ease-in-out,
filter 0.05s ease 0.45s;
will-change: filter, transform;
@media (min-width: 768px) {
transform: translate3d(0, -60px, 0);
}
}
.blue-chip__cube {
filter: grayscale(1) brightness(0.15)
drop-shadow(0 0 0rem color-mix(in srgb, #40cffd 0%, transparent));
}
.pink-chip__cube {
filter: grayscale(1) brightness(0.15)
drop-shadow(0 0 0rem color-mix(in srgb, #bc33fc 0%, transparent));
}
.vite-chip__logo {
transition: all 0.6s cubic-bezier(0.175, 0.885, 0.32, 1.2);
will-change: filter, transform;
filter: grayscale(1) brightness(0.4)
drop-shadow(0px 0px 1px rgba(0, 0, 0, 0.1));
transform: translate3d(0, 0, 0);
}
.vite-chip__v {
filter: drop-shadow(0 0 0rem color-mix(in srgb, #93bfff 0%, transparent));
will-change: filter;
transition-delay: 0.8s;
}
.blue-chip__connection {
clip-path: polygon(0 0, 0 0, 0 100%, 0 100%);
will-change: clip-path;
filter: drop-shadow(
0 0 0.2rem color-mix(in srgb, #40cffd 50%, transparent)
);
transition: all 0.6s ease-in-out;
}
.pink-chip__connection {
clip-path: polygon(100% 0, 100% 0, 100% 100%, 100% 100%);
will-change: clip-path;
filter: drop-shadow(
0 0 0.2rem color-mix(in srgb, #bc33fc 50%, transparent)
);
transition: all 0.6s ease-in-out;
}
.blue-glow {
position: absolute;
top: 50px;
left: 55px;
width: 100px;
height: 100px;
background: #41d1ff;
filter: blur(80px);
z-index: -1;
opacity: 0;
transition: opacity 0.5s ease-out;
will-change: opacity;
}
.pink-glow {
position: absolute;
top: 50px;
right: 55px;
width: 100px;
height: 100px;
background: #bd34fe;
filter: blur(80px);
z-index: -1;
opacity: 0;
transition: opacity 0.5s ease-out;
will-change: opacity;
}
&.active {
.blue-chip__cube,
.pink-chip__cube {
transform: translate3d(0px, 0, 0);
}
.blue-chip__cube {
filter: grayscale(0) brightness(1)
drop-shadow(0 0 0.5rem color-mix(in srgb, #40cffd 100%, transparent));
}
.pink-chip__cube {
filter: grayscale(0) brightness(1)
drop-shadow(0 0 0.5rem color-mix(in srgb, #bc33fc 100%, transparent));
}
.blue-chip__connection {
transition-delay: 0.3s;
clip-path: polygon(0 0, 100% 0, 100% 100%, 0% 100%);
}
.pink-chip__connection {
transition-delay: 0.3s;
clip-path: polygon(0 0, 100% 0, 100% 100%, 0% 100%);
}
.vite-chip__logo {
filter: grayscale(0) brightness(1)
drop-shadow(0px 20px 4px rgba(0, 0, 0, 0.4));
transform: translate3d(0, -20px, 0);
transition-delay: 0.8s;
}
.vite-chip__v {
filter: drop-shadow(
0 0 0.3rem color-mix(in srgb, #93bfff 20%, transparent)
);
}
.vite-chip__bolt {
filter: drop-shadow(
0 0 0.5rem color-mix(in srgb, yellow 20%, transparent)
);
}
.blue-glow {
opacity: 0.8;
}
.pink-glow {
opacity: 0.8;
}
&:hover {
.blue-glow {
opacity: 1;
}
.pink-glow {
opacity: 1;
}
}
}
}
</style>

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,623 @@
<script setup lang="ts">
import SvgNode from '../common/SvgNode.vue'
import { ref, Ref } from 'vue'
import { gsap } from 'gsap'
import { useSlideIn } from '../../../composables/useSlideIn'
import { useCardAnimation } from '../../../composables/useCardAnimation'
// Animation state
const isBoltActive: Ref<boolean> = ref(false)
const nodes = Array.from({ length: 10 }, () => {
return {
position: ref(0),
visible: ref(false),
}
})
/**
* Slide the card in when the page loads
*/
useSlideIn('#optimized-build-card')
/**
* Start the animation when the card is hovered
*/
const { startAnimation } = useCardAnimation(
'#optimized-build-card',
() => {
// Define the timeline
const timeline = gsap.timeline()
// Animate in each node
nodes.forEach((node, i) => {
let subTimeline = gsap.timeline()
subTimeline.call(() => {
node.visible.value = true
})
subTimeline.to(node.position, {
value: 1,
duration: 0.8,
ease: 'power3.out',
})
subTimeline.call(
() => {
node.visible.value = false
},
null,
'-=0.6',
)
timeline.add(subTimeline, Math.random())
})
// Animate in the bolt
timeline.call(
() => {
isBoltActive.value = true
},
null,
'-=0.5',
)
// All done
return timeline
},
{
once: true,
},
)
</script>
<template>
<div
class="feature-card"
id="optimized-build-card"
@mouseover.stop.prevent="startAnimation"
>
<div class="feature__visualization">
<!-- Left-side lines/nodes -->
<svg
class="left-lines"
width="195"
height="138"
viewBox="0 0 195 138"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M195 31.5L89.8055 30.377C76.1575 30.377 62.535 29.076 49.0906 26.4886L-21 13"
stroke="url(#ob-linear-gradient-left)"
/>
<SvgNode
path="M195 31.5L89.8055 30.377C76.1575 30.377 62.535 29.076 49.0906 26.4886L-21 13"
:position="nodes[0].position.value"
:visible="nodes[0].visible.value"
:dot-color="false"
glow-color="#FFE358"
/>
<path
d="M195 50L69.295 47.754L-21 41.016"
stroke="url(#ob-linear-gradient-left)"
/>
<SvgNode
path="M195 50L69.295 47.754L-21 41.016"
:position="nodes[1].position.value"
:visible="nodes[1].visible.value"
:dot-color="false"
glow-color="#FFE358"
/>
<path
d="M195 68.5L-21 69.5642"
stroke="url(#ob-linear-gradient-left)"
/>
<SvgNode
path="M195 68.5L-21 69.5642"
:position="nodes[2].position.value"
:visible="nodes[2].visible.value"
:dot-color="false"
glow-color="#FFE358"
/>
<path
d="M195 87L69.2951 89.2463L-21 96.1614"
stroke="url(#ob-linear-gradient-left)"
/>
<SvgNode
path="M195 87L69.2951 89.2463L-21 96.1614"
:position="nodes[3].position.value"
:visible="nodes[3].visible.value"
:dot-color="false"
glow-color="#FFE358"
/>
<path
d="M195 105.5L89.8055 106.623C76.1575 106.623 62.535 107.924 49.0906 110.511L-21 124"
stroke="url(#ob-linear-gradient-left)"
/>
<SvgNode
path="M195 105.5L89.8055 106.623C76.1575 106.623 62.535 107.924 49.0906 110.511L-21 124"
:position="nodes[4].position.value"
:visible="nodes[4].visible.value"
:dot-color="false"
glow-color="#FFE358"
/>
<defs>
<linearGradient
id="ob-linear-gradient-left"
x1="-453.247"
y1="167.386"
x2="196.189"
y2="125.855"
gradientUnits="userSpaceOnUse"
>
<stop offset="0" stop-color="white" stop-opacity="0" />
<stop offset="0.7" stop-color="white" stop-opacity="0.2" />
<stop offset="1" stop-color="white" stop-opacity="0" />
</linearGradient>
</defs>
</svg>
<!-- Right-side lines/nodes -->
<svg
class="right-lines"
width="203"
height="113"
viewBox="0 0 203 113"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M0 93.5L105.194 94.623C118.843 94.623 132.465 95.924 145.909 98.5114L216 112"
stroke="url(#ob-linear-gradient-right)"
/>
<SvgNode
path="M0 93.5L105.194 94.623C118.843 94.623 132.465 95.924 145.909 98.5114L216 112"
:position="nodes[5].position.value"
:visible="nodes[5].visible.value"
:dot-color="false"
glow-color="#FFE358"
/>
<path
d="M0 75L125.705 77.246L216 83.984"
stroke="url(#ob-linear-gradient-right)"
/>
<SvgNode
path="M0 75L125.705 77.246L216 83.984"
:position="nodes[6].position.value"
:visible="nodes[6].visible.value"
:dot-color="false"
glow-color="#FFE358"
/>
<path
d="M4.65162e-08 56.5L216 55.4358"
stroke="url(#ob-linear-gradient-right)"
/>
<SvgNode
path="M4.65162e-08 56.5L216 55.4358"
:position="nodes[7].position.value"
:visible="nodes[7].visible.value"
:dot-color="false"
glow-color="#FFE358"
/>
<path
d="M4.00455e-07 38L125.705 35.7537L216 28.8386"
stroke="url(#ob-linear-gradient-right)"
/>
<SvgNode
path="M4.00455e-07 38L125.705 35.7537L216 28.8386"
:position="nodes[8].position.value"
:visible="nodes[8].visible.value"
:dot-color="false"
glow-color="#FFE358"
/>
<path
d="M8.0866e-07 19.5L105.194 18.377C118.843 18.377 132.465 17.076 145.909 14.4887L216 1"
stroke="url(#ob-linear-gradient-right)"
/>
<SvgNode
path="M8.0866e-07 19.5L105.194 18.377C118.843 18.377 132.465 17.076 145.909 14.4887L216 1"
:position="nodes[9].position.value"
:visible="nodes[9].visible.value"
:dot-color="false"
glow-color="#FFE358"
/>
<defs>
<linearGradient
id="ob-linear-gradient-right"
x1="648.247"
y1="-42.3859"
x2="-1.18927"
y2="-0.855247"
gradientUnits="userSpaceOnUse"
>
<stop offset="0" stop-color="white" stop-opacity="0" />
<stop offset="0.7" stop-color="white" stop-opacity="0.2" />
<stop offset="1" stop-color="white" stop-opacity="0" />
</linearGradient>
</defs>
</svg>
<!-- Lightning Bolt -->
<svg
class="bolt"
:class="{ active: isBoltActive }"
width="180"
height="263"
viewBox="0 0 180 263"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<g filter="url(#filter-bolt-glow)" class="bolt__glow">
<path
d="M111.597 57.0439L61.562 69.1637C60.7396 69.3629 60.1308 70.2245 60.0812 71.2584L57.0033 135.519C56.9309 137.032 58.0553 138.207 59.2503 137.866L73.1807 133.892C74.4841 133.521 75.6618 134.94 75.3939 136.56L71.2552 161.613C70.9767 163.3 72.2573 164.741 73.5893 164.241L82.1934 161.01C83.5273 160.509 84.8089 161.955 84.5267 163.643L77.9496 202.996C77.538 205.458 80.1867 206.8 81.2913 204.689L82.0291 203.28L122.8 102.695C123.483 101.011 122.306 99.0908 120.809 99.4478L106.47 102.869C105.123 103.19 103.976 101.639 104.357 100.009L113.715 59.9023C114.096 58.2698 112.946 56.7172 111.597 57.0439Z"
fill="url(#paint0_radial_693_18989)"
/>
</g>
<g filter="url(#filter-bolt-edge-glow)" class="bolt__glow">
<path
d="M111.597 57.0361L61.562 67.0126C60.7396 67.1765 60.1308 67.8857 60.0812 68.7368L57.0033 121.633C56.9309 122.879 58.0553 123.846 59.2503 123.565L73.1807 120.294C74.4841 119.988 75.6618 121.156 75.3939 122.49L71.2552 143.113C70.9767 144.501 72.2573 145.688 73.5893 145.276L82.1934 142.616C83.5273 142.204 84.8089 143.394 84.5267 144.783L77.9496 177.177C77.538 179.203 80.1867 180.308 81.2913 178.571L82.0291 177.41L122.8 94.6142C123.483 93.2278 122.306 91.6471 120.809 91.9409L106.47 94.757C105.123 95.0214 103.976 93.7444 104.357 92.4029L113.715 59.389C114.096 58.0452 112.946 56.7672 111.597 57.0361Z"
stroke="url(#paint1_radial_693_18989)"
stroke-width="3.34777"
/>
</g>
<mask
id="bolt-mask"
style="mask-type: alpha"
maskUnits="userSpaceOnUse"
x="56"
y="56"
width="68"
height="124"
>
<path
d="M111.597 57.0361L61.562 67.0126C60.7396 67.1765 60.1308 67.8857 60.0812 68.7368L57.0033 121.633C56.9309 122.879 58.0553 123.846 59.2503 123.565L73.1807 120.294C74.4841 119.988 75.6618 121.156 75.3939 122.49L71.2552 143.113C70.9767 144.501 72.2573 145.688 73.5893 145.276L82.1934 142.616C83.5273 142.204 84.8089 143.394 84.5267 144.783L77.9496 177.177C77.538 179.203 80.1867 180.308 81.2913 178.571L82.0291 177.41L122.8 94.6142C123.483 93.2278 122.306 91.6471 120.809 91.9409L106.47 94.757C105.123 95.0214 103.976 93.7444 104.357 92.4029L113.715 59.389C114.096 58.0452 112.946 56.7672 111.597 57.0361Z"
fill="url(#linear-mask)"
/>
<path
d="M59.8424 68.7229L59.8424 68.7229L56.7646 121.619L57.0033 121.633L56.7646 121.619C56.6833 123.019 57.9486 124.116 59.305 123.798L73.2353 120.527C74.3622 120.262 75.3945 121.273 75.1595 122.443L75.3939 122.49L75.1595 122.443L71.0208 143.066C70.7081 144.624 72.147 145.972 73.6599 145.504L73.5893 145.276L73.6599 145.504L82.264 142.844C83.4168 142.488 84.54 143.516 84.2924 144.735L84.5267 144.783L84.2924 144.735L77.7152 177.129C77.255 179.395 80.235 180.678 81.4931 178.699L82.2309 177.539L82.2379 177.528L82.2436 177.516L123.015 94.7198C123.781 93.1646 122.463 91.3725 120.763 91.7063L106.424 94.5223C106.424 94.5223 106.424 94.5224 106.424 94.5224C105.259 94.7509 104.253 93.6453 104.587 92.4681L113.946 59.4542L113.946 59.4542C114.373 57.9459 113.082 56.4962 111.55 56.8016L111.597 57.0361L111.55 56.8016L61.5153 66.7781C60.5836 66.9638 59.8982 67.7658 59.8424 68.7229Z"
stroke="white"
stroke-opacity="0.3"
stroke-width="0.478253"
/>
</mask>
<g mask="url(#bolt-mask)">
<rect
class="bolt__dark"
x="41.2188"
y="57"
width="92.7811"
height="136.78"
fill="#1E1E1E"
/>
<rect
class="bolt__color"
x="41.2188"
y="57"
width="92.7811"
height="136.78"
fill="url(#radial-bolt-color)"
/>
<rect
class="bolt__highlight"
x="41.2188"
y="57"
width="92.7811"
height="136.78"
fill="white"
/>
<path
class="bolt__edge"
d="M111.597 57.0361L61.562 67.0126C60.7396 67.1765 60.1308 67.8857 60.0812 68.7368L57.0033 121.633C56.9309 122.879 58.0553 123.846 59.2503 123.565L73.1807 120.294C74.4841 119.988 75.6618 121.156 75.3939 122.49L71.2552 143.113C70.9767 144.501 72.2573 145.688 73.5893 145.276L82.1934 142.616C83.5273 142.204 84.8089 143.394 84.5267 144.783L77.9496 177.177C77.538 179.203 80.1867 180.308 81.2913 178.571L82.0291 177.41L122.8 94.6142C123.483 93.2278 122.306 91.6471 120.809 91.9409L106.47 94.757C105.123 95.0214 103.976 93.7444 104.357 92.4029L113.715 59.389C114.096 58.0452 112.946 56.7672 111.597 57.0361Z"
stroke="url(#radial-bolt-edge)"
stroke-width="3"
/>
</g>
<defs>
<filter
id="filter-bolt-glow"
x="0.0878601"
y="0.0878601"
width="179.823"
height="262.561"
filterUnits="userSpaceOnUse"
color-interpolation-filters="sRGB"
>
<feFlood flood-opacity="0" result="BackgroundImageFix" />
<feBlend
mode="normal"
in="SourceGraphic"
in2="BackgroundImageFix"
result="shape"
/>
<feGaussianBlur
stdDeviation="28.4561"
result="effect1_foregroundBlur_693_18989"
/>
</filter>
<filter
id="filter-bolt-edge-glow"
x="48.6306"
y="48.6283"
width="82.7363"
height="139.202"
filterUnits="userSpaceOnUse"
color-interpolation-filters="sRGB"
>
<feFlood flood-opacity="0" result="BackgroundImageFix" />
<feBlend
mode="normal"
in="SourceGraphic"
in2="BackgroundImageFix"
result="shape"
/>
<feGaussianBlur
stdDeviation="3.34777"
result="effect1_foregroundBlur_693_18989"
/>
</filter>
<radialGradient
id="paint0_radial_693_18989"
cx="0"
cy="0"
r="1"
gradientUnits="userSpaceOnUse"
gradientTransform="translate(79.4533 63.5007) rotate(81.9567) scale(108.196 88.8357)"
>
<stop offset="0" stop-color="#FFEA83" />
<stop offset="0.0833333" stop-color="#FFDD35" />
<stop offset="1" stop-color="#FFA800" />
</radialGradient>
<radialGradient
id="paint1_radial_693_18989"
cx="0"
cy="0"
r="1"
gradientUnits="userSpaceOnUse"
gradientTransform="translate(79.4533 62.3511) rotate(80.2589) scale(89.4759 88.4248)"
>
<stop offset="0" stop-color="#FFEA83" />
<stop offset="0.0833333" stop-color="#FFDD35" />
<stop offset="1" stop-color="#FFA800" />
</radialGradient>
<linearGradient
id="linear-mask"
x1="75.4703"
y1="59.7447"
x2="91.2207"
y2="165.923"
gradientUnits="userSpaceOnUse"
>
<stop offset="0" stop-color="#FFEA83" />
<stop offset="0.0833333" stop-color="#FFDD35" />
<stop offset="1" stop-color="#FFA800" />
</linearGradient>
<radialGradient
id="radial-bolt-color"
cx="0"
cy="0"
r="1"
gradientUnits="userSpaceOnUse"
gradientTransform="translate(72.7835 62.9782) rotate(77.8103) scale(100.793 123.282)"
>
<stop offset="0" stop-color="#FFEA83" />
<stop offset="0.0833333" stop-color="#FFDD35" />
<stop offset="1" stop-color="#FFA800" />
</radialGradient>
<radialGradient
id="radial-bolt-edge"
cx="0"
cy="0"
r="1"
gradientUnits="userSpaceOnUse"
gradientTransform="translate(79.4533 62.3511) rotate(80.2589) scale(89.4759 88.4248)"
>
<stop offset="0" stop-color="#FFDD35" />
<stop offset="1" stop-color="#FFA800" />
</radialGradient>
</defs>
</svg>
</div>
<div class="feature__meta meta--center">
<div class="meta__title">Optimized build</div>
<div class="meta__description">
Pre-configured Rollup build with multi-page and library mode support.
</div>
</div>
</div>
</template>
<style scoped>
.feature-card {
min-height: 370px;
@media (min-width: 768px) {
transform: translate3d(60px, 0, 0);
}
}
.feature__visualization {
.left-lines {
position: absolute;
top: 60px;
left: unset;
right: 50%;
@media (min-width: 455px) {
left: 0;
right: unset;
}
@media (min-width: 768px) {
left: unset;
right: 50%;
}
@media (min-width: 900px) {
left: 0;
right: unset;
}
@media (min-width: 1200px) {
left: unset;
right: 50%;
}
}
.right-lines {
position: absolute;
top: 71px;
right: unset;
left: 50%;
@media (min-width: 455px) {
right: 0;
left: unset;
}
@media (min-width: 768px) {
right: unset;
left: 50%;
}
@media (min-width: 900px) {
right: 0;
left: unset;
}
@media (min-width: 1200px) {
right: unset;
left: 50%;
}
}
.bolt {
position: absolute;
top: 10px;
left: 50%;
transform: translate3d(-50%, 0, 0);
.bolt__glow {
transition: opacity 0.3s ease;
will-change: opacity;
opacity: 0.6;
}
.bolt__color {
opacity: 0.03;
}
.bolt__edge {
opacity: 0.1;
}
.bolt__highlight {
opacity: 0;
}
&.active {
.bolt__color {
animation: bolt-color-entrance 0.5s ease forwards;
}
.bolt__edge {
animation: bolt-edge-entrance 0.5s ease forwards;
}
.bolt__glow {
opacity: 0.7;
transition: opacity 0.1s ease;
}
.bolt__highlight {
opacity: 0.6;
transition: opacity 0.1s ease;
transition-delay: 0.5s;
}
}
}
}
@keyframes bolt-edge-entrance {
0% {
opacity: 0;
}
2% {
opacity: 0.6;
}
30% {
opacity: 0.6;
}
31% {
opacity: 0.01;
}
35% {
opacity: 0.01;
}
36% {
opacity: 0.8;
}
80% {
opacity: 0.8;
}
80% {
opacity: 0.3;
}
82% {
opacity: 1;
}
100% {
opacity: 1;
}
}
@keyframes bolt-color-entrance {
0% {
opacity: 0.03;
}
2% {
opacity: 0.4;
}
30% {
opacity: 0.4;
}
31% {
opacity: 0.01;
}
35% {
opacity: 0.01;
}
36% {
opacity: 0.45;
}
80% {
opacity: 0.45;
}
80% {
opacity: 0.3;
}
82% {
opacity: 0.5;
}
100% {
opacity: 0.9;
}
}
</style>

View File

@ -0,0 +1,281 @@
<script setup>
import logoJSON from './images/json.svg'
import logoCSS from './images/css3.svg'
import logoJS from './images/js.svg'
import logoTS from './images/ts.svg'
import logoWA from './images/wa.svg'
import logoPostCSS from './images/postcss.svg'
import { useSlideIn } from '../../../composables/useSlideIn'
import { useCardAnimation } from '../../../composables/useCardAnimation'
/**
* Slide the card in when the page loads
*/
useSlideIn('#rich-features-card')
/**
* Start the animation when the card is hovered
*/
const { isCardActive, startAnimation } = useCardAnimation(
'#rich-features-card',
null,
{
once: true,
},
)
</script>
<template>
<div
class="feature-card"
id="rich-features-card"
:class="{ active: isCardActive }"
@mouseover.stop.prevent="startAnimation"
>
<div class="feature__visualization">
<div class="card-container">
<svg
class="background-cards"
width="658"
height="275"
viewBox="0 0 658 275"
d
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M105.376 201.33C105.376 193.847 111.442 187.781 118.925 187.781H176.507C183.99 187.781 190.056 193.847 190.056 201.33V258.912C190.056 266.395 183.99 272.461 176.507 272.461H118.925C111.442 272.461 105.376 266.395 105.376 258.912V201.33Z"
class="background-card"
/>
<path
d="M525.389 96.3271C525.389 88.8443 531.455 82.7783 538.937 82.7783H596.518C604 82.7783 610.066 88.8443 610.066 96.3271V153.909C610.066 161.392 604 167.458 596.518 167.458H538.937C531.455 167.458 525.389 161.392 525.389 153.909V96.3271Z"
class="background-card"
/>
<path
d="M210.38 -10.3692C210.38 -17.852 216.446 -23.9179 223.929 -23.9179H281.512C288.994 -23.9179 295.06 -17.852 295.06 -10.3692V47.2129C295.06 54.6957 288.994 60.7617 281.512 60.7617H223.929C216.446 60.7617 210.38 54.6957 210.38 47.2129V-10.3692Z"
class="background-card"
/>
<path
d="M525.389 201.33C525.389 193.847 531.455 187.781 538.937 187.781H596.518C604 187.781 610.066 193.847 610.066 201.33V258.912C610.066 266.395 604 272.461 596.518 272.461H538.937C531.455 272.461 525.389 266.395 525.389 258.912V201.33Z"
class="background-card"
/>
<path
d="M630.389 201.33C630.389 193.847 636.455 187.781 643.938 187.781H701.52C709.003 187.781 715.069 193.847 715.069 201.33V258.912C715.069 266.395 709.003 272.461 701.52 272.461H643.938C636.455 272.461 630.389 266.395 630.389 258.912V201.33Z"
class="background-card"
/>
<path
d="M0.373901 201.33C0.373901 193.847 6.4399 187.781 13.9227 187.781H71.5045C78.9873 187.781 85.0531 193.847 85.0531 201.33V258.912C85.0531 266.395 78.9873 272.461 71.5045 272.461H13.9227C6.4399 272.461 0.373901 266.395 0.373901 258.912V201.33Z"
class="background-card"
/>
<path
d="M630.389 96.3271C630.389 88.8443 636.455 82.7783 643.938 82.7783H701.52C709.003 82.7783 715.069 88.8443 715.069 96.3271V153.909C715.069 161.392 709.003 167.458 701.52 167.458H643.938C636.455 167.458 630.389 161.392 630.389 153.909V96.3271Z"
class="background-card"
/>
<path
d="M0.373901 96.3271C0.373901 88.8443 6.4399 82.7783 13.9227 82.7783H71.5045C78.9873 82.7783 85.0531 88.8443 85.0531 96.327V153.909C85.0531 161.392 78.9873 167.458 71.5045 167.458H13.9227C6.4399 167.458 0.373901 161.392 0.373901 153.909V96.3271Z"
class="background-card"
/>
<path
d="M630.389 -10.3692C630.389 -17.852 636.455 -23.918 643.938 -23.918H701.52C709.003 -23.918 715.069 -17.852 715.069 -10.3692V47.2129C715.069 54.6957 709.003 60.7616 701.52 60.7616H643.938C636.455 60.7616 630.389 54.6957 630.389 47.2129V-10.3692Z"
class="background-card"
/>
<path
d="M0.373901 -10.3692C0.373901 -17.852 6.4399 -23.9179 13.9227 -23.9179H71.5045C78.9873 -23.9179 85.0531 -17.852 85.0531 -10.3692V47.2129C85.0531 54.6957 78.9873 60.7617 71.5045 60.7617H13.9227C6.4399 60.7617 0.373901 54.6957 0.373901 47.2129V-10.3692Z"
class="background-card"
/>
<path
d="M525.389 -10.3692C525.389 -17.8519 531.455 -23.9179 538.937 -23.9179H596.518C604 -23.9179 610.066 -17.8519 610.066 -10.3692V47.213C610.066 54.6957 604 60.7617 596.518 60.7617H538.937C531.455 60.7617 525.389 54.6957 525.389 47.213V-10.3692Z"
class="background-card"
/>
<path
d="M420.386 -10.3692C420.386 -17.852 426.452 -23.9179 433.935 -23.9179H491.517C499 -23.9179 505.066 -17.852 505.066 -10.3692V47.2129C505.066 54.6957 499 60.7617 491.517 60.7617H433.935C426.452 60.7617 420.386 54.6957 420.386 47.2129V-10.3692Z"
class="background-card"
/>
<path
d="M315.383 -10.3692C315.383 -17.852 321.449 -23.9179 328.932 -23.9179H386.514C393.997 -23.9179 400.063 -17.852 400.063 -10.3692V47.2129C400.063 54.6957 393.997 60.7617 386.514 60.7617H328.932C321.449 60.7617 315.383 54.6957 315.383 47.2129V-10.3692Z"
class="background-card"
/>
<path
d="M210.38 203.023C210.38 195.541 216.446 189.475 223.929 189.475H281.512C288.994 189.475 295.06 195.541 295.06 203.023V260.605C295.06 268.088 288.994 274.154 281.512 274.154H223.929C216.446 274.154 210.38 268.088 210.38 260.605V203.023Z"
class="background-card"
/>
<path
d="M315.383 203.023C315.383 195.541 321.449 189.475 328.932 189.475H386.514C393.997 189.475 400.063 195.541 400.063 203.023V260.605C400.063 268.088 393.997 274.154 386.514 274.154H328.932C321.449 274.154 315.383 268.088 315.383 260.605V203.023Z"
class="background-card"
/>
</svg>
<div class="card card--json">
<img :src="logoJSON" alt="JSON" />
</div>
<div class="card card--css">
<img :src="logoCSS" alt="CSS3" />
</div>
<div class="card card--js">
<img :src="logoJS" alt="Javascript" />
</div>
<div class="card card--ts">
<img :src="logoTS" alt="Typescript" />
</div>
<div class="card card--wa">
<img :src="logoWA" alt="WebAssembly" />
</div>
<div class="card card--postcss">
<img :src="logoPostCSS" alt="PostCSS" />
</div>
</div>
<!-- Center glow effect -->
<div class="center-glow" />
</div>
<div class="feature__meta meta--center">
<div class="meta__title">Rich features</div>
<div class="meta__description">
Out-of-the-box support for TypeScript, JSX, CSS and more.
</div>
</div>
</div>
</template>
<style scoped>
@property --opacity {
syntax: '<number>';
initial-value: 1;
inherits: false;
}
.feature-card {
@media (min-width: 768px) {
transform: translate3d(-60px, 0, 0);
}
&.active {
.feature__visualization {
.card {
&:after {
border-color: rgba(60, 60, 60, 0.8);
--opacity: 0.8;
box-shadow: var(--card-color) 0 10px 20px -10px;
}
}
.center-glow {
opacity: 1;
}
}
}
}
.feature__visualization {
display: flex;
justify-content: center;
align-content: flex-start;
.card-container {
flex-shrink: 0;
mask-image: radial-gradient(
ellipse 50% 45% at center 25%,
rgba(0, 0, 0, 1) 50%,
rgba(0, 0, 0, 0.7) 80%,
rgba(0, 0, 0, 0) 100%
);
position: relative;
background: #141414;
.background-card {
fill: #181818;
}
}
.center-glow {
position: absolute;
top: 0;
left: 50%;
width: 300px;
height: 140px;
background: #ffffff;
filter: blur(80px);
z-index: 5;
transform: translate3d(-50%, 0, 0);
opacity: 0.5;
transition: opacity 0.3s ease;
will-change: opacity;
mix-blend-mode: overlay;
}
.card {
position: absolute;
z-index: 1;
display: flex;
background: var(--card-color);
width: 85px;
aspect-ratio: 1;
border-radius: 10px;
align-items: center;
justify-content: center;
transform: translate3d(0, 0, 0);
transition: all 0.3s ease;
will-change: box-shadow;
--card-color: #181818;
* {
position: relative;
z-index: 2;
}
&:after {
border: 1px solid rgba(60, 60, 60, 0.5);
content: '';
position: absolute;
top: -1px;
left: -1px;
right: -1px;
bottom: -1px;
border-radius: 10px;
--opacity: 0.99;
background: linear-gradient(
to bottom,
#181818 30%,
rgba(24 24 24 / var(--opacity)) 100%
);
will-change: background;
box-shadow: var(--card-color) 0 5px 10px -30px;
transition:
--opacity 0.8s ease,
box-shadow 0.5s ease;
z-index: 1;
}
&.card--json {
top: -23px;
left: 105px;
}
&.card--css {
top: 83px;
left: 105px;
--card-color: #2a53dd;
}
&.card--js {
top: 83px;
left: 210px;
--card-color: #f7e425;
}
&.card--ts {
top: 83px;
left: 315px;
--card-color: #3d95d2;
}
&.card--wa {
top: 83px;
left: 420px;
--card-color: #7259f0;
}
&.card--postcss {
top: 189px;
left: 420px;
}
}
}
</style>

View File

@ -0,0 +1,540 @@
<script setup lang="ts">
import { useSlideIn } from '../../../composables/useSlideIn'
import { useCardAnimation } from '../../../composables/useCardAnimation'
/**
* Slide the card in when the page loads
*/
useSlideIn('#ssr-support')
/**
* Start the animation when the card is hovered
*/
const { isCardActive, startAnimation } = useCardAnimation(
'#ssr-support',
undefined,
{
once: true,
},
)
</script>
<template>
<div
class="feature-card"
id="ssr-support"
@mouseover.stop.prevent="startAnimation"
>
<div class="feature__visualization" :class="{ active: isCardActive }">
<svg
width="402"
height="166"
viewBox="0 0 402 166"
fill="none"
xmlns="http://www.w3.org/2000/svg"
style="margin-top: 10px"
>
<!-- JS Box -->
<g class="js">
<g class="js__glow" filter="url(#filter-js-glow)">
<rect
x="30"
y="31.0947"
width="104"
height="104"
rx="16.2078"
fill="url(#linear-js-glow)"
/>
<rect
x="30.6753"
y="31.7701"
width="102.649"
height="102.649"
rx="15.5325"
stroke="#A3A3A3"
stroke-width="1.35065"
/>
</g>
<g class="js__bg" filter="url(#filter-js-bg)">
<rect
x="30"
y="31.0947"
width="104"
height="104"
rx="16.2078"
fill="url(#linear-js-bg)"
/>
</g>
<rect
class="js__border"
x="30.6753"
y="31.7701"
width="102.649"
height="102.649"
rx="15.5325"
stroke="#A3A3A3"
stroke-width="1.2"
/>
</g>
<!-- JS Text -->
<text class="js-text" x="80" y="120">.JS</text>
<!-- Connector -->
<path
class="connector"
opacity="0.25"
d="M133.5 84.5H164M164 84.5V58.5C164 52.4249 168.925 47.5 175 47.5H193.5M164 84.5V108C164 114.075 168.925 119 175 119H193.5"
/>
<!-- Client Transform Box -->
<g class="client" filter="url(#filter-client)">
<g clip-path="url(#clip-client)">
<rect
class="client__bg"
x="193"
y="20"
width="182"
height="54"
fill="url(#linear-client-bg)"
fill-opacity="0.1"
/>
<g class="client__glow" filter="url(#filter-client-glow)">
<rect
x="213"
y="41.5342"
width="12"
height="12"
rx="1"
fill="#FFE358"
/>
</g>
<rect
class="client__indicator"
x="212.777"
y="41.5338"
width="12"
height="12"
rx="1"
/>
</g>
<rect
class="client__border"
x="193.507"
y="22.507"
width="180.986"
height="50.0537"
rx="11.661"
stroke="#737373"
stroke-opacity="0.3"
stroke-width="1.014"
/>
</g>
<!-- Client Transform Text -->
<text class="client-text" x="236" y="53">Client transform</text>
<!-- Server Transform Box -->
<g class="server" filter="url(#filter-server)">
<g clip-path="url(#clip-server)">
<rect
class="server__bg"
x="193"
y="90"
width="186"
height="54"
fill="url(#linear-server-bg)"
fill-opacity="0.1"
/>
<g class="server__glow" filter="url(#filter-server-glow)">
<circle cx="218.933" cy="117.534" r="5.93296" fill="#FFE358" />
</g>
<rect
class="server__indicator"
x="212.777"
y="111.74"
width="12"
height="12"
rx="1"
/>
</g>
<rect
x="193.507"
y="92.7135"
width="181.402"
height="50.0537"
rx="11.661"
stroke="#737373"
stroke-opacity="0.3"
stroke-width="1.014"
/>
</g>
<!-- Server Transform Text -->
<text class="server-text" x="236" y="122">Server transform</text>
<!-- Definitions -->
<defs>
<filter
id="filter-js-glow"
x="0"
y="1.09473"
width="164"
height="164"
filterUnits="userSpaceOnUse"
color-interpolation-filters="sRGB"
>
<feFlood flood-opacity="0" result="BackgroundImageFix" />
<feBlend
mode="normal"
in="SourceGraphic"
in2="BackgroundImageFix"
result="shape"
/>
<feGaussianBlur
stdDeviation="15"
result="effect1_foregroundBlur_1_6"
/>
</filter>
<filter
id="filter-js-bg"
x="30"
y="31.0947"
width="104"
height="108"
filterUnits="userSpaceOnUse"
color-interpolation-filters="sRGB"
>
<feFlood flood-opacity="0" result="BackgroundImageFix" />
<feBlend
mode="normal"
in="SourceGraphic"
in2="BackgroundImageFix"
result="shape"
/>
<feColorMatrix
in="SourceAlpha"
type="matrix"
values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"
result="hardAlpha"
/>
<feMorphology
radius="3"
operator="erode"
in="SourceAlpha"
result="effect1_innerShadow_1_6"
/>
<feOffset dy="4" />
<feGaussianBlur stdDeviation="5" />
<feComposite in2="hardAlpha" operator="arithmetic" k2="-1" k3="1" />
<feColorMatrix
type="matrix"
values="0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0.35 0"
/>
<feBlend
mode="normal"
in2="shape"
result="effect1_innerShadow_1_6"
/>
</filter>
<filter
id="filter-client"
x="193"
y="22"
width="182"
height="55.0677"
filterUnits="userSpaceOnUse"
color-interpolation-filters="sRGB"
>
<feFlood flood-opacity="0" result="BackgroundImageFix" />
<feBlend
mode="normal"
in="SourceGraphic"
in2="BackgroundImageFix"
result="shape"
/>
<feColorMatrix
in="SourceAlpha"
type="matrix"
values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"
result="hardAlpha"
/>
<feOffset dy="4" />
<feGaussianBlur stdDeviation="2" />
<feComposite in2="hardAlpha" operator="arithmetic" k2="-1" k3="1" />
<feColorMatrix
type="matrix"
values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.25 0"
/>
<feBlend
mode="normal"
in2="shape"
result="effect1_innerShadow_1_6"
/>
</filter>
<filter
id="filter-client-glow"
x="203"
y="31.5342"
width="32"
height="32"
filterUnits="userSpaceOnUse"
color-interpolation-filters="sRGB"
>
<feFlood flood-opacity="0" result="BackgroundImageFix" />
<feBlend
mode="normal"
in="SourceGraphic"
in2="BackgroundImageFix"
result="shape"
/>
<feGaussianBlur
stdDeviation="5"
result="effect1_foregroundBlur_1_6"
/>
</filter>
<filter
id="filter-server"
x="193"
y="92.2065"
width="182.416"
height="55.0677"
filterUnits="userSpaceOnUse"
color-interpolation-filters="sRGB"
>
<feFlood flood-opacity="0" result="BackgroundImageFix" />
<feBlend
mode="normal"
in="SourceGraphic"
in2="BackgroundImageFix"
result="shape"
/>
<feColorMatrix
in="SourceAlpha"
type="matrix"
values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"
result="hardAlpha"
/>
<feOffset dy="4" />
<feGaussianBlur stdDeviation="2" />
<feComposite in2="hardAlpha" operator="arithmetic" k2="-1" k3="1" />
<feColorMatrix
type="matrix"
values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.25 0"
/>
<feBlend
mode="normal"
in2="shape"
result="effect1_innerShadow_1_6"
/>
</filter>
<filter
id="filter-server-glow"
x="203"
y="101.601"
width="31.8659"
height="31.8659"
filterUnits="userSpaceOnUse"
color-interpolation-filters="sRGB"
>
<feFlood flood-opacity="0" result="BackgroundImageFix" />
<feBlend
mode="normal"
in="SourceGraphic"
in2="BackgroundImageFix"
result="shape"
/>
<feGaussianBlur
stdDeviation="5"
result="effect1_foregroundBlur_1_6"
/>
</filter>
<linearGradient
id="linear-js-glow"
x1="130"
y1="144"
x2="22.5"
y2="23.5002"
gradientUnits="userSpaceOnUse"
>
<stop stop-color="#FFE358" />
<stop offset="1" stop-color="#FFE358" stop-opacity="0" />
</linearGradient>
<linearGradient
id="linear-js-bg"
x1="130"
y1="144"
x2="22.5"
y2="23.5002"
gradientUnits="userSpaceOnUse"
>
<stop stop-color="#FFE358" />
<stop offset="1" stop-color="#FFE358" stop-opacity="0" />
</linearGradient>
<linearGradient
id="linear-client-bg"
x1="193"
y1="47"
x2="375"
y2="47"
gradientUnits="userSpaceOnUse"
>
<stop stop-color="#FFE358" />
<stop offset="1" stop-color="#FFE358" stop-opacity="0" />
</linearGradient>
<linearGradient
id="linear-server-bg"
x1="193"
y1="117"
x2="379"
y2="117"
gradientUnits="userSpaceOnUse"
>
<stop stop-color="#FFE358" />
<stop offset="1" stop-color="#FFE358" stop-opacity="0" />
</linearGradient>
<clipPath id="clip-client">
<rect
x="193"
y="22"
width="182"
height="51.0677"
rx="12.168"
fill="white"
/>
</clipPath>
<clipPath id="clip-server">
<rect
x="193"
y="92.2065"
width="182.416"
height="51.0677"
rx="12.168"
fill="white"
/>
</clipPath>
</defs>
</svg>
</div>
<div class="feature__meta">
<div class="meta__title">First class SSR Support</div>
<div class="meta__description">
It's never been easier to setup custom SSR (Server-Side Rendering), or
build your own SSR framework.
</div>
</div>
</div>
</template>
<style scoped>
.feature-card {
@media (min-width: 768px) {
transform: translate3d(-60px, 0, 0);
}
.feature__meta {
max-width: calc(100%);
}
/* Extend height on smaller devices, to make room for text */
@media (max-width: 380px) {
height: 400px;
}
}
.feature__visualization {
margin-top: 10px;
svg {
width: calc(100% - 15px);
margin: 0 auto;
}
.js-text {
fill: #a3a3a3;
font-family: Inter, sans-serif;
font-size: 30px;
font-weight: 500;
line-height: normal;
letter-spacing: -0.5px;
user-select: none;
pointer-events: none;
transition: all 0.3s ease-in-out;
}
.connector {
stroke: #a3a3a3;
transition: all 0.3s ease-in-out;
}
.client__indicator,
.server__indicator {
fill: #1e1e1e;
transition: all 0.1s ease-in-out;
}
.client-text,
.server-text {
fill: #565656;
font-family: Inter, sans-serif;
font-size: 15px;
font-weight: 400;
user-select: none;
pointer-events: none;
transition: all 0.3s ease-in-out;
}
.js__glow {
opacity: 0;
transition: all 0.3s ease-in-out;
}
.js__bg,
.client__bg,
.client__glow,
.server__bg,
.server__glow {
opacity: 0;
transition: all 0.3s ease-in-out;
}
&.active {
.connector {
stroke: #ffe358;
transition-delay: 0.1s;
}
.client__indicator,
.server__indicator {
fill: #fdefab;
transition-delay: 0.3s;
}
.js-text {
fill: #171717;
}
.js__glow,
.js__bg,
.client__bg,
.client__glow,
.server__bg,
.server__glow {
opacity: 1;
}
.client__glow,
.server__glow,
.client__bg,
.server__bg {
transition-delay: 0.3s;
}
.client-text,
.server-text {
transition-delay: 0.3s;
fill: #fafafa;
}
}
}
</style>

View File

@ -0,0 +1,319 @@
<script setup lang="ts">
import SvgNode from '../common/SvgNode.vue'
import { onMounted, onUnmounted, Ref, ref } from 'vue'
import { gsap } from 'gsap'
const props = defineProps({
title: {
type: String,
default: null,
},
description: {
type: String,
default: null,
},
type: {
type: String,
default: 'blue',
},
})
// Animation state
const animationPercentage: Ref<number> = ref(0)
const animationVisible: Ref<boolean> = ref(false)
// GSAP timeline for the icon above the section title
let timeline: gsap.core.Timeline | null
onMounted(() => {
startAnimation()
})
onUnmounted(() => {
if (timeline) {
timeline.kill()
}
})
/**
* When the component scrolls into viewport, we start the animation.
*/
const startAnimation = () => {
timeline = gsap
.timeline({
scrollTrigger: {
trigger: `#feature_section_${props.type}`,
start: 'top 80%',
once: true,
},
})
.call(
() => {
animationVisible.value = true
},
null,
0,
)
.to(
animationPercentage,
{
value: 0.55,
duration: 2,
ease: 'expo.out',
},
0,
)
}
</script>
<template>
<section class="feature-section" :id="`feature_section_${props.type}`">
<!-- Section Title -->
<div class="feature-section__title">
<svg
xmlns="http://www.w3.org/2000/svg"
width="70"
height="61"
viewBox="0 0 70 61"
fill="none"
style="overflow: visible"
>
<path
d="M38.5 0.772461V60.5215M22.6301 60.7725V38.7905C22.6301 25.3784 17.3675 12.5156 8 3.03184M54.3699 60.7725V38.7905C54.3699 25.3784 59.6325 12.5156 69 3.03184"
stroke="url(#linear-gradient-bg-lines)"
stroke-width="2"
/>
<SvgNode
v-if="type === 'blue'"
path="M22.6301 80.7725V38.7905C22.6301 25.3784 17.3675 12.5156 8 3.03184L-20 -20"
:position="animationPercentage"
:visible="animationVisible"
/>
<SvgNode
v-if="type === 'pink'"
path="M54.3699 80.7725V38.7905C54.3699 25.3784 59.6325 12.5156 69 3.03184L90 -20"
:position="animationPercentage"
:visible="animationVisible"
dot-color="#ce9bf4"
glow-color="#BD34FE"
/>
<defs>
<linearGradient
id="linear-gradient-bg-lines"
x1="38.5"
y1="0.772461"
x2="38.5"
y2="60.7725"
gradientUnits="userSpaceOnUse"
>
<stop offset="0" stop-color="#404040" stop-opacity="0" />
<stop offset="0.5" stop-color="#737373" />
<stop offset="1" stop-color="#404040" stop-opacity="0" />
</linearGradient>
</defs>
</svg>
<h2 :style="{ '--text-color': type === 'blue' ? '#41D1FF' : '#BD34FE' }">
{{ title }}
</h2>
<h3 v-if="description">{{ description }}</h3>
</div>
<!-- Section Grid -->
<div class="feature-section__grid">
<!-- Feature Cards -->
<slot></slot>
</div>
</section>
</template>
<style>
.feature-section {
display: flex;
flex-direction: column;
margin: 0 auto;
gap: 0;
align-items: center;
position: relative;
z-index: 2;
&:nth-of-type(1) {
margin-top: -60px;
@media (min-width: 768px) {
margin-top: 0;
}
}
&:nth-of-type(2) {
margin-top: 160px;
}
svg {
position: relative;
margin-bottom: 15px;
z-index: 2;
}
h2 {
--text-color: #404040;
background: radial-gradient(
circle 300px at 30% -180%,
var(--text-color) 0%,
#ffffff 100%
);
background-clip: text;
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
text-shadow:
0 0 4px rgba(255, 255, 255, 0.1),
0 0 14px rgba(130, 168, 236, 0.2);
}
.feature-section__title {
display: flex;
flex-direction: column;
margin: 0 auto;
width: fit-content;
align-items: center;
gap: 10px;
text-align: center;
}
.feature-section__grid {
display: grid;
grid: auto / repeat(1, 1fr);
grid-gap: 30px;
margin: 45px auto 0;
width: 100%;
padding: 0 32px;
@media (min-width: 768px) {
width: 1194px;
max-width: 100%;
grid: auto / repeat(6, 1fr);
margin: 80px auto 0;
}
}
.feature-card {
border-radius: 12px;
border: 1px solid rgba(38, 38, 38, 0.7);
background: #141414;
min-height: 350px;
display: flex;
justify-content: flex-start;
align-items: flex-end;
padding: 32px;
position: relative;
overflow: hidden;
/* Extend height on smaller devices, to make room for text */
@media (max-width: 380px) {
padding: 24px;
}
.feature__meta {
max-width: 275px;
position: relative;
z-index: 2;
pointer-events: none;
.meta__title {
color: #fff;
font-family: Manrope, sans-serif;
font-size: 20px;
font-style: normal;
font-weight: 600;
line-height: normal;
letter-spacing: -0.4px;
margin-bottom: 8px;
cursor: default;
}
.meta__description {
color: #a3a3a3;
font-family: Inter, sans-serif;
font-size: 16px;
font-style: normal;
font-weight: 400;
line-height: 150%;
letter-spacing: -0.32px;
text-wrap: balance;
cursor: default;
}
&.meta--center {
margin: 0 auto;
text-align: center;
}
}
.feature__visualization {
width: 100%;
height: 100%;
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
z-index: 0;
}
&:nth-child(1),
&:nth-child(4) {
grid-column: span 1;
@media (min-width: 768px) {
grid-column: span 3;
}
@media (min-width: 1200px) {
grid-column: span 2;
}
}
&:nth-child(2),
&:nth-child(3) {
grid-column: span 1;
@media (min-width: 768px) {
grid-column: span 3;
}
@media (min-width: 1200px) {
grid-column: span 4;
}
}
}
&.feature-section--flip {
.feature-card {
&:nth-child(2),
&:nth-child(3) {
grid-column: span 1;
@media (min-width: 768px) {
grid-column: span 3;
}
@media (min-width: 1200px) {
grid-column: span 2;
}
}
&:nth-child(1),
&:nth-child(4) {
grid-column: span 1;
@media (min-width: 768px) {
grid-column: span 3;
}
@media (min-width: 1200px) {
grid-column: span 4;
}
}
}
}
}
</style>

View File

@ -0,0 +1,240 @@
<script setup lang="ts">
import { useSlideIn } from '../../../composables/useSlideIn'
import { useCardAnimation } from '../../../composables/useCardAnimation'
/**
* Slide the card in when the page loads
*/
useSlideIn('#fully-typed-api')
/**
* Start the animation when the card is hovered
*/
const { isCardActive, startAnimation } = useCardAnimation(
'#fully-typed-api',
undefined,
{
once: true,
},
)
</script>
<template>
<div
class="feature-card"
id="fully-typed-api"
@mouseover.stop.prevent="startAnimation"
>
<div class="feature__visualization" :class="{ active: isCardActive }">
<div class="ide">
<span class="code code__inactive">
<span class="code--red">import</span> { createServer }
<span class="code--red">from</span>
<span class="code--blue">'vite'</span><br /><br />
<span class="code--red">const</span> server =
<span class="code--red">await</span>
<span class="code--purple">createServer</span>({<br />
<span class="code--grey"
>&nbsp;&nbsp;&nbsp;// user config options</span
><br />
})
</span>
<span class="code code__feature">
<span class="code--red">await</span> server.<span
class="code--highlight"
>listen</span
>()<br />
<span class="code--extra"
>server.<span class="code--purple">printUrls</span>()</span
>
</span>
</div>
<div class="tooltip">
<span class="code">
(method) ViteDevServer.<span class="code--blue">listen</span
>(port<span class="code--blue">?:</span> number
<span class="code--blue">| undefined,</span> isRestart<span
class="code--blue"
>?:</span
>
boolean <span class="code--blue">| undefined</span>):
<span class="code--yellow">Promise</span
><span class="code--blue">&lt;</span>ViteDevServer<span
class="code--blue"
>&gt;</span
><br />
<span class="code--descriptor">Start the server.</span>
</span>
</div>
</div>
<div class="feature__meta meta--center">
<div class="meta__title">Fully typed API</div>
<div class="meta__description">Designed to be built on top of.</div>
</div>
</div>
</template>
<style scoped>
.feature-card {
@media (min-width: 768px) {
transform: translate3d(60px, 0, 0);
}
}
.feature__visualization {
.ide {
position: absolute;
top: 0;
left: 18px;
right: 0;
height: 195px;
border-radius: 0 0 0 12px;
overflow: hidden;
transition: all 0.4s ease-in-out;
border: 1px solid rgba(64, 64, 64, 0.5);
border-right: none;
border-top: none;
background: linear-gradient(
to top,
rgba(23, 23, 23, 0.35) 0%,
#171717 100%
);
}
.tooltip {
border-radius: 6px 0 0 6px;
border: 1px solid #262626;
background: linear-gradient(-45deg, #1f1f1f 40%, #282828 50%, #1f1f1f 60%);
background-size: 400%;
background-position-x: 100%;
animation: shimmer 7s infinite linear;
padding: 12px 2px 6px 12px;
position: absolute;
z-index: 5;
top: 25px;
left: 60px;
right: 0;
border-top: 1px solid #383838;
opacity: 0;
transition: all 0.2s ease-in-out;
transform: translate3d(0, 20px, 0);
}
.code__inactive {
opacity: 0.2;
position: absolute;
top: 15px;
left: 15px;
filter: blur(0);
transition: all 0.4s ease-in-out;
}
.code__feature {
position: absolute;
top: 140px;
left: 15px;
}
.code {
color: #fff;
text-shadow: 0 4px 4px rgba(0, 0, 0, 0.25);
font-family:
IBM Plex Mono,
sans-serif;
font-size: 11px;
font-weight: 400;
line-height: 150%;
letter-spacing: -0.2px;
display: block;
margin: 0;
user-select: none;
pointer-events: none;
.code--highlight {
display: inline-block;
position: relative;
padding: 2px;
color: #dc94ff;
transition: all 0.1s ease-in-out;
&:before {
content: '';
width: 100%;
height: 100%;
border-radius: 5px;
opacity: 0;
background: #94e2fb;
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
z-index: -1;
transition: all 0.1s ease-in-out;
}
}
.code--purple {
color: #dc94ff;
}
.code--red {
color: #ff6b6b;
}
.code--blue {
color: #94e2fb;
}
.code--grey {
color: #737373;
}
.code--yellow {
color: #ffe358;
}
.code--descriptor {
margin-top: 8px;
padding-top: 6px;
display: block;
border-top: 1px solid #363636;
}
.code--extra {
transition: opacity 0.2s ease-in-out;
opacity: 1;
}
}
&.active {
.code__inactive {
filter: blur(5px);
}
.code--highlight {
color: #94e2fb;
&:before {
opacity: 0.2;
}
}
.tooltip {
transition-delay: 0.1s;
opacity: 1;
transform: translate3d(0, 0, 0);
}
.code--extra {
opacity: 0.2;
}
}
}
@keyframes shimmer {
to {
background-position-x: 0;
}
}
</style>

View File

@ -0,0 +1,16 @@
<svg width="34" height="48" viewBox="0 0 34 48" fill="none" xmlns="http://www.w3.org/2000/svg">
<mask id="mask0_1_865" style="mask-type:luminance" maskUnits="userSpaceOnUse" x="0" y="0" width="34" height="48">
<path d="M33.8759 0.407997H0.779999V47.123H33.8759V0.407997Z" fill="white"/>
</mask>
<g mask="url(#mask0_1_865)">
<path d="M33.879 9.589L30.864 43.366L17.311 47.123L3.795 43.371L0.783005 9.589H33.879Z" fill="#264DE4"/>
<path d="M28.283 41.215L30.859 12.351H17.331V44.251L28.283 41.215Z" fill="#2965F1"/>
<path d="M7.688 24.88L8.05901 29.024H17.331V24.88H7.688Z" fill="#EBEBEB"/>
<path d="M17.332 16.494H17.317H6.942L7.319 20.637H17.332V16.494Z" fill="#EBEBEB"/>
<path d="M17.331 39.952V35.641L17.313 35.646L12.698 34.4L12.403 31.095H10.161H8.244L8.825 37.601L17.312 39.957L17.331 39.952Z" fill="#EBEBEB"/>
<path d="M8.57201 0.407997H13.59V2.507H10.671V4.605H13.59V6.704H8.57201V0.407997Z" fill="white"/>
<path d="M14.594 0.407997H19.612V2.233H16.692V2.598H19.612V6.795H14.594V4.879H17.513V4.514H14.594V0.407997Z" fill="white"/>
<path d="M20.616 0.407997H25.634V2.233H22.715V2.598H25.634V6.795H20.616V4.879H23.536V4.514H20.616V0.407997Z" fill="white"/>
<path d="M22.42 29.023L21.939 34.397L17.318 35.644V39.955L25.812 37.601L25.875 36.901L26.848 25.993L26.949 24.88L27.697 16.494H17.318V20.637H23.157L22.78 24.88H17.318V29.023H22.42Z" fill="white"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

@ -0,0 +1,9 @@
<svg width="48" height="48" viewBox="0 0 48 48" fill="none" xmlns="http://www.w3.org/2000/svg">
<mask id="mask0_1_878" style="mask-type:luminance" maskUnits="userSpaceOnUse" x="0" y="0" width="48" height="48">
<path d="M47.4286 0.407997H0.00799561V47.8286H47.4286V0.407997Z" fill="white"/>
</mask>
<g mask="url(#mask0_1_878)">
<path d="M47.428 0.407997H0.00799561V47.828H47.428V0.407997Z" fill="#F7DF1E"/>
<path d="M31.864 37.455C32.819 39.015 34.062 40.161 36.26 40.161C38.106 40.161 39.285 39.238 39.285 37.963C39.285 36.435 38.074 35.894 36.041 35.005L34.927 34.527C31.712 33.157 29.576 31.441 29.576 27.813C29.576 24.471 32.122 21.927 36.102 21.927C38.935 21.927 40.972 22.913 42.439 25.495L38.969 27.723C38.205 26.353 37.381 25.813 36.102 25.813C34.796 25.813 33.969 26.641 33.969 27.723C33.969 29.059 34.797 29.601 36.709 30.429L37.823 30.906C41.609 32.529 43.747 34.185 43.747 37.906C43.747 41.918 40.595 44.116 36.363 44.116C32.224 44.116 29.551 42.144 28.243 39.559L31.864 37.455ZM16.122 37.841C16.822 39.083 17.459 40.133 18.99 40.133C20.454 40.133 21.378 39.56 21.378 37.333V22.181H25.834V37.393C25.834 42.007 23.129 44.108 19.18 44.108C15.612 44.108 13.546 42.261 12.495 40.037L16.122 37.841Z" fill="black"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@ -0,0 +1,21 @@
<svg width="49" height="49" viewBox="0 0 49 49" fill="none" xmlns="http://www.w3.org/2000/svg">
<mask id="mask0_5_918" style="mask-type:luminance" maskUnits="userSpaceOnUse" x="0" y="0" width="49" height="49">
<path d="M48.2674 0H0V48.2674H48.2674V0Z" fill="white"/>
</mask>
<g mask="url(#mask0_5_918)">
<g opacity="0.4">
<path fill-rule="evenodd" clip-rule="evenodd" d="M24.092 35.9285C34.771 50.4856 45.221 31.8653 45.206 20.6678C45.188 7.42869 31.769 0.0292969 24.083 0.0292969C11.747 0.0292969 -0.00100708 10.2246 -0.00100708 24.1739C-0.00100708 39.6785 13.466 48.2668 24.083 48.2668C21.681 47.9209 13.674 46.2052 13.566 27.7631C13.494 15.2899 17.635 10.3066 24.066 12.4989C24.21 12.5523 31.159 15.2937 31.159 24.2493C31.159 33.1667 24.092 35.9285 24.092 35.9285Z" fill="url(#paint0_linear_5_918)"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M24.079 12.4895C17.023 10.0575 8.379 15.8731 8.379 27.5215C8.379 46.5413 22.473 48.2674 24.182 48.2674C36.518 48.2674 48.266 38.0721 48.266 24.1229C48.266 8.61818 34.799 0.0299037 24.182 0.0299037C27.123 -0.377346 40.032 3.21253 40.032 20.8564C40.032 32.3624 30.393 38.6263 24.123 35.9499C23.979 35.8965 17.03 33.1551 17.03 24.1995C17.03 15.2821 24.079 12.4895 24.079 12.4895Z" fill="url(#paint1_linear_5_918)"/>
</g>
</g>
<defs>
<linearGradient id="paint0_linear_5_918" x1="7.13799" y1="7.1379" x2="41.137" y2="41.148" gradientUnits="userSpaceOnUse">
<stop/>
<stop offset="1" stop-color="white"/>
</linearGradient>
<linearGradient id="paint1_linear_5_918" x1="41.141" y1="41.1439" x2="7.14199" y2="7.13674" gradientUnits="userSpaceOnUse">
<stop/>
<stop offset="1" stop-color="white"/>
</linearGradient>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 1.7 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 31 KiB

View File

@ -0,0 +1,10 @@
<svg width="48" height="48" viewBox="0 0 48 48" fill="none" xmlns="http://www.w3.org/2000/svg">
<mask id="mask0_1_884" style="mask-type:luminance" maskUnits="userSpaceOnUse" x="0" y="0" width="48" height="48">
<path d="M47.4326 0.407997H0.0119934V47.8286H47.4326V0.407997Z" fill="white"/>
</mask>
<g mask="url(#mask0_1_884)">
<path d="M42.801 0.407997H4.64301C2.08501 0.407997 0.0119934 2.481 0.0119934 5.039V43.197C0.0119934 45.755 2.08501 47.828 4.64301 47.828H42.801C45.359 47.828 47.432 45.755 47.432 43.197V5.039C47.432 2.481 45.359 0.407997 42.801 0.407997Z" fill="#3178C6"/>
<path d="M42.801 0.407997H4.64301C2.08501 0.407997 0.0119934 2.481 0.0119934 5.039V43.197C0.0119934 45.755 2.08501 47.828 4.64301 47.828H42.801C45.359 47.828 47.432 45.755 47.432 43.197V5.039C47.432 2.481 45.359 0.407997 42.801 0.407997Z" fill="#3178C6"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M29.366 38.142V42.779C30.12 43.165 31.011 43.455 32.04 43.648C33.069 43.842 34.154 43.938 35.294 43.938C36.406 43.938 37.461 43.832 38.462 43.619C39.462 43.407 40.339 43.057 41.092 42.569C41.846 42.081 42.443 41.444 42.883 40.656C43.322 39.869 43.542 38.896 43.542 37.737C43.542 36.896 43.416 36.16 43.165 35.527C42.914 34.895 42.552 34.332 42.078 33.839C41.605 33.347 41.037 32.905 40.375 32.513C39.713 32.122 38.966 31.753 38.135 31.405C37.527 31.154 36.981 30.91 36.497 30.673C36.014 30.437 35.604 30.195 35.265 29.949C34.927 29.703 34.666 29.442 34.483 29.166C34.299 28.891 34.207 28.58 34.207 28.232C34.207 27.913 34.289 27.626 34.454 27.37C34.618 27.114 34.85 26.894 35.149 26.71C35.449 26.527 35.816 26.384 36.251 26.283C36.686 26.182 37.169 26.131 37.701 26.131C38.087 26.131 38.495 26.16 38.925 26.218C39.355 26.276 39.788 26.365 40.223 26.486C40.658 26.607 41.08 26.759 41.491 26.942C41.902 27.126 42.281 27.338 42.629 27.58V23.248C41.923 22.977 41.153 22.777 40.317 22.646C39.481 22.516 38.522 22.451 37.44 22.451C36.338 22.451 35.294 22.569 34.309 22.806C33.323 23.042 32.456 23.412 31.707 23.914C30.958 24.416 30.366 25.056 29.931 25.834C29.496 26.611 29.279 27.541 29.279 28.623C29.279 30.004 29.677 31.183 30.475 32.158C31.272 33.134 32.482 33.96 34.106 34.636C34.744 34.897 35.338 35.153 35.889 35.404C36.439 35.655 36.915 35.916 37.316 36.186C37.717 36.457 38.034 36.752 38.266 37.07C38.498 37.389 38.614 37.751 38.614 38.157C38.614 38.456 38.541 38.734 38.396 38.99C38.251 39.246 38.031 39.468 37.737 39.657C37.442 39.845 37.075 39.992 36.635 40.098C36.195 40.205 35.681 40.258 35.091 40.258C34.086 40.258 33.091 40.082 32.105 39.729C31.12 39.376 30.207 38.848 29.366 38.142ZM21.571 26.719H27.519V22.914H10.94V26.719H16.859V43.66H21.571V26.719Z" fill="white"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.6 KiB

View File

@ -0,0 +1,9 @@
<svg width="48" height="48" viewBox="0 0 48 48" fill="none" xmlns="http://www.w3.org/2000/svg">
<mask id="mask0_1_891" style="mask-type:luminance" maskUnits="userSpaceOnUse" x="0" y="0" width="48" height="48">
<path d="M47.4436 0.0210037H0.0230103V47.4416H47.4436V0.0210037Z" fill="white"/>
</mask>
<g mask="url(#mask0_1_891)">
<path d="M29.158 0.0210037C29.158 0.105004 29.158 0.188 29.158 0.277C29.158 3.28 26.723 5.714 23.721 5.714C20.717 5.714 18.283 3.279 18.283 0.277C18.283 0.188 18.283 0.105004 18.283 0.0210037H0.0230103V47.442H47.444V0.0210037H29.158Z" fill="#654FF0"/>
<path d="M11.04 25.576H14.183L16.328 37.003H16.367L18.946 25.576H21.886L24.215 37.143H24.26L26.706 25.576H29.788L25.783 42.366H22.664L20.354 30.94H20.294L17.821 42.366H14.645L11.04 25.576ZM33.332 25.576H38.286L43.206 42.366H39.964L38.894 38.63H33.25L32.424 42.366H29.267L33.332 25.576ZM35.218 29.715L33.847 35.875H38.113L36.539 29.715H35.218Z" fill="white"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 971 B

View File

@ -0,0 +1,127 @@
<script setup lang="ts">
import { Ref, ref } from 'vue'
/**
* A single framework or tool to display in the frameworks section.
*/
export interface Framework {
/**
* The name of the framework.
*/
name?: string
/**
* A string representing the URL of the logo in SVG format.
*/
logo?: string
/**
* A string representing the hex color of the glow effect.
*/
color?: string
/**
* A string representing the URL of the framework/tool's homepage.
*/
url?: string
/**
* Whether the framework card is visible or not.
*/
visible: Ref<boolean>
}
interface Props {
framework?: Framework
}
const props = withDefaults(defineProps<Props>(), {
framework: (): Framework => ({
visible: ref(true),
}),
})
</script>
<template>
<component
:is="props.framework.url ? 'a' : 'div'"
:href="props.framework.url ? props.framework.url : undefined"
target="_blank"
rel="noopener"
class="framework-card"
:style="{ '--glow-color': props.framework.color }"
:class="{ active: props.framework.visible.value === true }"
>
<img
v-if="props.framework.logo"
:src="props.framework.logo"
:alt="props.framework.name"
/>
</component>
</template>
<style scoped>
.framework-card {
width: 96px;
height: 96px;
border-radius: 12px;
border: 1px solid rgba(38, 38, 38, 0.7);
background: #181818;
display: flex;
justify-content: center;
align-items: center;
padding: 24px;
--glow-color: rgba(0, 0, 0, 0);
opacity: 0;
transition: opacity 0.4s ease;
user-select: none;
img {
user-select: none;
filter: drop-shadow(
0 0 0.8rem color-mix(in srgb, var(--glow-color) 40%, transparent)
);
}
&.active {
opacity: 1;
}
}
.framework-card:not(:has(img)) {
transform: scale(1) translate3d(0, 0, 0);
transition: transform 3s ease;
&:hover {
transform: scale(0.9) translate3d(0, 0, 0);
transition: transform 0.2s ease-in-out;
}
}
.framework-card:has(img) {
cursor: pointer;
position: relative;
&:before {
content: '';
position: absolute;
top: 10%;
left: 10%;
right: 10%;
bottom: 10%;
background-color: var(--glow-color);
filter: blur(18px);
z-index: -1;
opacity: 0;
transition: opacity 3s ease;
will-change: opacity;
}
&:hover {
&:before {
opacity: 1;
transition: opacity 0.2s ease;
}
}
}
</style>

View File

@ -0,0 +1,411 @@
<script setup lang="ts">
import { computed, ComputedRef, onMounted, onUnmounted, Ref, ref } from 'vue'
import FrameworkCard, { Framework } from './FrameworkCard.vue'
import { gsap } from 'gsap'
import { ScrollTrigger } from 'gsap/dist/ScrollTrigger'
gsap.registerPlugin(ScrollTrigger)
// Framework assets
import logoAstro from './images/astro.svg'
import logoNuxt from './images/nuxt.svg'
import logoVue from './images/vue.svg'
import logoAnalog from './images/analog.svg'
import logoPlaywright from './images/playwright.svg'
import logoMarko from './images/marko.svg'
import logoStorybook from './images/storybook.svg'
import logoQwik from './images/qwik.svg'
import logoVitest from './images/vitest.svg'
import logoRedwood from './images/redwood.svg'
import logoSolid from './images/solid.svg'
import logoAngular from './images/angular.svg'
import logoReact from './images/react.svg'
import logoRemix from './images/remix.svg'
import logoSvelte from './images/svelte.svg'
import logoLaravel from './images/laravel.svg'
/**
* The frameworks and tools to display in this section.
*/
const frameworks: Framework[] = [
{
name: 'Vitest',
logo: logoVitest,
color: '#fac52b',
url: 'https://vitest.dev/',
visible: ref(false),
},
{
name: 'React',
logo: logoReact,
color: '#00d6fd',
url: 'https://react.dev/',
visible: ref(false),
},
{
name: 'Angular',
logo: logoAngular,
color: '#e03237',
url: 'https://angularjs.org/',
visible: ref(false),
},
{
name: 'Vue',
logo: logoVue,
color: '#40b782',
url: 'https://vuejs.org/',
visible: ref(false),
},
{
name: 'Solid',
logo: logoSolid,
color: '#75b2df',
url: 'https://www.solidjs.com/',
visible: ref(false),
},
{
name: 'Svelte',
logo: logoSvelte,
color: '#fd3e00',
url: 'https://svelte.dev/',
visible: ref(false),
},
{
name: 'Astro',
logo: logoAstro,
color: '#FFFFFF',
url: 'https://astro.build',
visible: ref(false),
},
{
name: 'Remix',
logo: logoRemix,
color: '#3991fd',
url: 'https://remix.run/',
visible: ref(false),
},
{
name: 'Nuxt',
logo: logoNuxt,
color: '#00da81',
url: 'https://nuxt.com',
visible: ref(false),
},
{
name: 'Qwik',
logo: logoQwik,
color: '#18b5f4',
url: 'https://qwik.builder.io/',
visible: ref(false),
},
{
name: 'Redwood',
logo: logoRedwood,
color: '#be4622',
url: 'https://redwoodjs.com/',
visible: ref(false),
},
{
name: 'Analog',
logo: logoAnalog,
color: '#c10f2e',
url: 'https://analogjs.org/',
visible: ref(false),
},
{
name: 'Playwright',
logo: logoPlaywright,
color: '#d45247',
url: 'https://playwright.dev/',
visible: ref(false),
},
{
name: 'Storybook',
logo: logoStorybook,
color: '#fd4684',
url: 'https://storybook.js.org/',
visible: ref(false),
},
{
name: 'Marko',
logo: logoMarko,
color: '#de2a87',
url: 'https://markojs.com/',
visible: ref(false),
},
{
name: 'Laravel',
logo: logoLaravel,
color: '#eb4432',
url: 'https://laravel.com/',
visible: ref(false),
},
]
// Starting parameters
const screenWidth: Ref<number> = ref(1920)
let resizeTimeout: ReturnType<typeof setTimeout> | null = null
let timeline: gsap.core.Timeline | null = null
/**
* When the resize event fires, update the screen width.
*/
const handleResize = () => {
screenWidth.value = window.innerWidth
}
/**
* Throttle the resize event handler.
*/
const throttledResizeHandler = () => {
if (resizeTimeout === null) {
resizeTimeout = setTimeout(() => {
handleResize()
resizeTimeout = null
}, 100)
}
}
onMounted(() => {
// Set the initial size of the screen
handleResize()
// Listen for resize events
window.addEventListener('resize', throttledResizeHandler)
// Initialize the GSAP timeline
timeline = gsap.timeline({
scrollTrigger: {
trigger: '#frameworks-section',
start: 'top 70%',
once: true,
},
})
frameworks.forEach((framework, index) => {
timeline!.set(framework.visible, { value: true }, index * 0.05)
})
})
onUnmounted(() => {
// Deregister the throttled event handler
window.removeEventListener('resize', throttledResizeHandler)
// Clear any pending execution of the resize handler
if (resizeTimeout) {
clearTimeout(resizeTimeout)
resizeTimeout = null
}
// Kill the GSAP timeline
if (timeline) {
timeline.kill()
timeline = null
}
})
/**
* How many total blocks (framework or empty) will fit in a single row?
*/
const numBlocksPerRow: ComputedRef<number> = computed(() => {
return Math.floor(screenWidth.value / (96 + 24))
})
const paddedBlocksPerSide: ComputedRef<number> = computed(() => {
if (screenWidth.value < 840) {
return 0
}
if (screenWidth.value < 1280) {
return 1
}
if (screenWidth.value < 1600) {
return 2
}
return Math.max(Math.floor((screenWidth.value - 840) / 280), 0)
})
const numFrameworksPerRow = computed(
() => numBlocksPerRow.value - paddedBlocksPerSide.value * 2,
)
/**
* The indexes of the blocks on each row that support framework cards.
*/
const centerIndexes: ComputedRef<{ start: number; end: number }> = computed(
() => {
const startIndex = paddedBlocksPerSide.value
return {
start: startIndex,
end: numBlocksPerRow.value - paddedBlocksPerSide.value,
}
},
)
/**
* How many rows do we need to display all the frameworks?
*/
const numRows: ComputedRef<number> = computed(() => {
return Math.ceil(frameworks.length / numFrameworksPerRow.value)
})
/**
* Generate CSS transformations for each row, to gracefully slide between horizontal positions.
*/
const rowStyle: ComputedRef<{ transform: string }> = computed(() => {
return {
transform: `translate3d(var(--row-offset), 0, 0)`,
}
})
</script>
<template>
<section class="frameworks-section" id="frameworks-section">
<h2>Powering your favorite frameworks and tools</h2>
<div class="frameworks-container">
<!-- Top Row -->
<div class="framework-row" :style="rowStyle">
<FrameworkCard v-for="i in numBlocksPerRow + 2" />
</div>
<!-- Logo Rows -->
<template v-for="rowIndex in numRows">
<div class="framework-row" :style="rowStyle">
<template v-for="columnIndex in numBlocksPerRow + 2">
<template
v-if="
columnIndex - 1 >= centerIndexes.start &&
columnIndex - 1 < centerIndexes.end
"
>
<FrameworkCard
:framework="
frameworks[
(rowIndex - 1) * numFrameworksPerRow +
(columnIndex - 1) -
centerIndexes.start
]
"
/>
</template>
<template v-else>
<FrameworkCard />
</template>
</template>
</div>
</template>
<!-- Bottom Row -->
<div class="framework-row" :style="rowStyle">
<FrameworkCard v-for="i in numBlocksPerRow + 2" />
</div>
</div>
</section>
</template>
<style scoped>
.frameworks-section {
margin-top: 150px;
@media (min-width: 768px) {
margin-top: 240px;
}
h2 {
background: linear-gradient(0deg, #fff 0%, rgba(255, 255, 255, 0.76) 100%);
background-clip: text;
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
width: 668px;
max-width: 100%;
margin: 0 auto;
text-align: center;
position: relative;
z-index: 3;
}
.frameworks-container {
width: 100%;
background-color: rgba(38, 38, 38, 0.15);
position: relative;
margin-top: -20px;
overflow: hidden;
@media (min-width: 840px) {
mask-image: linear-gradient(
90deg,
transparent 0%,
#ffffff 300px,
#ffffff calc(100vw - 300px),
transparent 100%
);
}
&:before {
content: '';
display: block;
width: 100%;
height: 80px;
background: linear-gradient(
0deg,
rgba(23, 23, 23, 0) 0%,
rgba(16, 16, 16, 0.7) 50%,
#101010 100%
);
position: absolute;
top: 0;
left: 0;
right: 0;
z-index: 2;
pointer-events: none;
}
&:after {
content: '';
display: block;
width: 100%;
height: 100px;
background: linear-gradient(
180deg,
rgba(23, 23, 23, 0) 0%,
rgba(16, 16, 16, 0.7) 50%,
#101010 100%
);
position: absolute;
bottom: 0;
left: 0;
right: 0;
z-index: 2;
pointer-events: none;
}
}
.framework-row {
display: grid;
grid-auto-columns: 96px;
grid-gap: 24px;
justify-content: flex-start;
margin-bottom: 24px;
position: relative;
white-space: nowrap;
grid-auto-flow: column;
&:nth-child(even) {
--row-offset: 36px;
}
&:nth-child(odd) {
--row-offset: 12px;
}
@media (min-width: 1080px) {
&:nth-child(even) {
--row-offset: 24px;
}
&:nth-child(odd) {
--row-offset: -24px;
}
}
}
}
</style>

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 8.7 KiB

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 271"><defs><linearGradient id="logosAngularIcon0" x1="25.071%" x2="96.132%" y1="90.929%" y2="55.184%"><stop offset="0%" stop-color="#E40035"/><stop offset="24%" stop-color="#F60A48"/><stop offset="35.2%" stop-color="#F20755"/><stop offset="49.4%" stop-color="#DC087D"/><stop offset="74.5%" stop-color="#9717E7"/><stop offset="100%" stop-color="#6C00F5"/></linearGradient><linearGradient id="logosAngularIcon1" x1="21.863%" x2="68.367%" y1="12.058%" y2="68.21%"><stop offset="0%" stop-color="#FF31D9"/><stop offset="100%" stop-color="#FF5BE1" stop-opacity="0"/></linearGradient></defs><path fill="url(#logosAngularIcon0)" d="m256 45.179l-9.244 145.158L158.373 0zm-61.217 187.697l-66.782 38.105l-66.784-38.105L74.8 199.958h106.4zM128.001 72.249l34.994 85.076h-69.99zM9.149 190.337L0 45.179L97.627 0z"/><path fill="url(#logosAngularIcon1)" d="m256 45.179l-9.244 145.158L158.373 0zm-61.217 187.697l-66.782 38.105l-66.784-38.105L74.8 199.958h106.4zM128.001 72.249l34.994 85.076h-69.99zM9.149 190.337L0 45.179L97.627 0z"/></svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@ -0,0 +1,11 @@
<svg xmlns="http://www.w3.org/2000/svg" width="41" height="50" viewBox="0 0 41 50" fill="none">
<g clip-path="url(#clip0_724_8504)">
<path d="M12.6534 41.7267C10.2003 39.5139 9.48427 34.8645 10.5063 31.4961C12.2784 33.6198 14.7338 34.2925 17.2771 34.6723C21.2034 35.2583 25.0593 35.0391 28.7067 33.2682C29.1239 33.0655 29.5095 32.7958 29.9655 32.5228C30.3077 33.5026 30.3967 34.4918 30.2772 35.4986C29.9865 37.9505 28.7501 39.8444 26.7834 41.2802C25.997 41.8544 25.1648 42.3678 24.3526 42.9093C21.8574 44.5736 21.1822 46.525 22.1199 49.3637C22.1422 49.4328 22.1621 49.502 22.2125 49.6707C20.9385 49.1082 20.0079 48.2889 19.2988 47.2118C18.5499 46.075 18.1936 44.8174 18.1748 43.4567C18.1655 42.7944 18.1655 42.1264 18.0752 41.4736C17.8549 39.882 17.0977 39.1694 15.6714 39.1283C14.2076 39.0862 13.0496 39.9793 12.7425 41.3856C12.7191 41.4935 12.6851 41.6001 12.6511 41.7255L12.6534 41.7267Z" fill="white"/>
<path d="M0.316406 32.5273C0.316406 32.5273 7.02394 29.2679 13.7502 29.2679L18.8216 13.612C19.0114 12.8548 19.5658 12.3403 20.1917 12.3403C20.8175 12.3403 21.3719 12.8548 21.5618 13.612L26.6331 29.2679C34.5994 29.2679 40.0669 32.5273 40.0669 32.5273C40.0669 32.5273 28.6736 1.567 28.6513 1.50489C28.3244 0.58953 27.7724 0 27.0281 0H13.3564C12.6122 0 12.0824 0.58953 11.7331 1.50489C11.7085 1.56583 0.316406 32.5273 0.316406 32.5273Z" fill="white"/>
</g>
<defs>
<clipPath id="clip0_724_8504">
<rect width="40.5063" height="50" fill="white"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 264"><path fill="#FF2D20" d="M255.856 59.62c.095.351.144.713.144 1.077v56.568c0 1.478-.79 2.843-2.073 3.578L206.45 148.18v54.18a4.135 4.135 0 0 1-2.062 3.579l-99.108 57.053c-.227.128-.474.21-.722.299c-.093.03-.18.087-.278.113a4.15 4.15 0 0 1-2.114 0c-.114-.03-.217-.093-.325-.134c-.227-.083-.464-.155-.68-.278L2.073 205.938A4.128 4.128 0 0 1 0 202.36V32.656c0-.372.052-.733.144-1.083c.031-.119.103-.227.145-.346c.077-.216.15-.438.263-.639c.077-.134.19-.242.283-.366c.119-.165.227-.335.366-.48c.119-.118.274-.206.408-.309c.15-.124.283-.258.453-.356h.005L51.613.551a4.135 4.135 0 0 1 4.125 0l49.546 28.526h.01c.165.104.305.232.454.351c.134.103.284.196.402.31c.145.149.248.32.371.484c.088.124.207.232.279.366c.118.206.185.423.268.64c.041.118.113.226.144.35c.095.351.144.714.145 1.078V138.65l41.286-23.773V60.692c0-.36.052-.727.145-1.072c.036-.124.103-.232.144-.35c.083-.217.155-.44.268-.64c.077-.134.19-.242.279-.366c.123-.165.226-.335.37-.48c.12-.118.269-.206.403-.309c.155-.124.289-.258.454-.356h.005l49.551-28.526a4.13 4.13 0 0 1 4.125 0l49.546 28.526c.175.103.309.232.464.35c.128.104.278.197.397.31c.144.15.247.32.37.485c.094.124.207.232.28.366c.118.2.185.423.267.64c.047.118.114.226.145.35Zm-8.115 55.258v-47.04l-17.339 9.981l-23.953 13.792v47.04l41.297-23.773h-.005Zm-49.546 85.095V152.9l-23.562 13.457l-67.281 38.4v47.514l90.843-52.3ZM8.259 39.796v160.177l90.833 52.294v-47.505L51.64 177.906l-.015-.01l-.02-.01c-.16-.093-.295-.227-.444-.34c-.13-.104-.279-.186-.392-.3l-.01-.015c-.134-.129-.227-.289-.34-.433c-.104-.14-.227-.258-.31-.402l-.005-.016c-.093-.154-.15-.34-.217-.515c-.067-.155-.154-.3-.196-.464v-.005c-.051-.196-.061-.403-.082-.604c-.02-.154-.062-.309-.062-.464V63.57L25.598 49.772l-17.339-9.97v-.006ZM53.681 8.893L12.399 32.656l41.272 23.762L94.947 32.65L53.671 8.893h.01Zm21.468 148.298l23.948-13.786V39.796L81.76 49.778L57.805 63.569v103.608l17.344-9.986ZM202.324 36.935l-41.276 23.762l41.276 23.763l41.271-23.768l-41.27-23.757Zm-4.13 54.676l-23.953-13.792l-17.338-9.981v47.04l23.948 13.787l17.344 9.986v-47.04Zm-94.977 106.006l60.543-34.564l30.264-17.272l-41.246-23.747l-47.489 27.34l-43.282 24.918l41.21 23.325Z"></path></svg>

After

Width:  |  Height:  |  Size: 2.3 KiB

View File

@ -0,0 +1,64 @@
<svg width="60" height="50" viewBox="0 0 60 50" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_724_8599)">
<path d="M29.9375 8.17749H38.372C35.2646 13.2709 31.83 18.8784 28.3954 24.4625H19.9608C23.3954 18.8784 26.83 13.2709 29.9375 8.17749Z" fill="#8DC220"/>
<path d="M9.98445 8.17749H18.419C16.7601 10.8878 15.0779 13.6214 13.419 16.3317L8.44239 24.4625C10.1013 27.1728 11.7601 29.9065 13.419 32.6167C15.0779 35.327 16.7368 38.0373 18.419 40.7476H9.98445C8.32557 38.0373 6.64333 35.327 4.98445 32.6167C3.32557 29.9298 1.66669 27.1962 0.0078125 24.4859L4.98445 16.3551C6.64333 13.6214 8.32557 10.9111 9.98445 8.17749Z" fill="#44BFEF"/>
<path d="M9.98413 8.17749C13.4187 13.785 16.8533 19.3924 19.9608 24.4625H28.3953C25.2879 19.3924 21.8533 13.785 18.4187 8.17749H9.98413Z" fill="#00AC71"/>
<path d="M38.372 8.17749H29.9374C31.5963 10.8878 33.2552 13.6214 34.9374 16.3317C36.5963 19.042 38.2552 21.7523 39.9374 24.4625C38.2786 27.1728 36.5963 29.9065 34.9374 32.6167C33.2786 35.327 31.6197 38.0373 29.9374 40.7476H38.372C40.0309 38.0373 41.6898 35.327 43.372 32.6167C45.0309 29.9065 46.6898 27.1962 48.372 24.4625C46.6898 21.7523 45.0309 19.042 43.372 16.3317C41.7131 13.6214 40.0309 10.9111 38.372 8.17749Z" fill="#F9BC00"/>
<path d="M34.8907 13.9253H26.4561C25.3813 15.6776 24.3066 17.4533 23.2318 19.2057C22.157 20.958 21.0823 22.7337 19.9841 24.486H28.4187C29.4935 22.7337 30.5916 20.958 31.6664 19.2057C32.7178 17.43 33.7925 15.6776 34.8907 13.9253Z" fill="url(#paint0_linear_724_8599)"/>
<path d="M23.4883 18.7382H31.9229C32.9976 16.9859 34.0724 15.2102 35.1472 13.4579C36.2219 11.7055 37.2967 9.92983 38.3715 8.17749H29.9369C28.8621 9.92983 27.7873 11.7055 26.7126 13.4579C25.6378 15.2336 24.563 16.9859 23.4883 18.7382Z" fill="url(#paint1_linear_724_8599)"/>
<path d="M44.844 18.7382H36.4094C35.3346 16.9859 34.2365 15.2102 33.1617 13.4579C32.087 11.7055 31.0122 9.92983 29.9374 8.17749H38.372C39.4468 9.92983 40.5215 11.7055 41.5963 13.4579C42.6944 15.2336 43.7692 16.9859 44.844 18.7382Z" fill="url(#paint2_linear_724_8599)"/>
<path d="M49.8212 8.17749H41.3866C43.0455 10.9111 44.7044 13.6214 46.3633 16.3317C48.0222 19.042 49.7044 21.7523 51.3633 24.4625C49.7044 27.1728 48.0222 29.9065 46.3633 32.6167C44.7044 35.327 43.0455 38.0373 41.3633 40.7476H49.7979C51.4567 38.0373 53.1156 35.327 54.7979 32.6167C56.4567 29.9065 58.1156 27.1962 59.7979 24.4625C58.139 21.7523 56.4801 19.042 54.7979 16.3317C53.1623 13.6214 51.4801 10.9111 49.8212 8.17749Z" fill="#DF1B1C"/>
<path d="M56.2933 18.7382H47.8587C46.7606 16.9859 45.6858 15.2102 44.611 13.4579C43.5362 11.7055 42.4615 9.92983 41.3867 8.17749H49.8213C50.8961 9.92983 51.9708 11.7055 53.0456 13.4579C54.1204 15.2336 55.2185 16.9859 56.2933 18.7382Z" fill="url(#paint3_linear_724_8599)"/>
<path d="M44.9141 35.0467H53.3486C54.4234 33.2944 55.4982 31.542 56.5729 29.7663C57.6477 28.014 58.7225 26.2383 59.8206 24.486H51.3627C50.2879 26.2383 49.2131 28.014 48.1384 29.7663C47.0636 31.5187 45.9888 33.271 44.9141 35.0467Z" fill="url(#paint4_linear_724_8599)"/>
<path d="M33.4648 35.0468H41.8994C42.9742 33.2945 44.049 31.5188 45.1237 29.7665C46.1985 28.0141 47.2733 26.2384 48.3714 24.4861H39.9368C38.862 26.2384 37.7873 28.0141 36.7125 29.7665C35.6144 31.5188 34.5396 33.2711 33.4648 35.0468Z" fill="url(#paint5_linear_724_8599)"/>
<path d="M14.9144 13.9253H6.47978C5.40501 15.6776 4.33024 17.4533 3.25548 19.2057C2.15735 20.958 1.08258 22.7337 0.0078125 24.486H8.44239C9.51716 22.7337 10.5919 20.9814 11.6667 19.2057C12.7415 17.4533 13.8162 15.6776 14.9144 13.9253Z" fill="url(#paint6_linear_724_8599)"/>
<path d="M3.51172 18.7382H11.9463C13.0211 16.9859 14.0958 15.2102 15.1706 13.4579C16.2687 11.7055 17.3435 9.92983 18.4183 8.17749H9.98368C8.90892 9.92983 7.83415 11.6822 6.75938 13.4579C5.68462 15.2102 4.60985 16.9859 3.51172 18.7382Z" fill="url(#paint7_linear_724_8599)"/>
<path d="M3.51172 30.2102H11.9463C13.0211 31.9625 14.0958 33.7382 15.1706 35.4906C16.2454 37.2429 17.3201 39.0186 18.3949 40.771H9.96032C8.88555 39.0186 7.78742 37.2663 6.71265 35.4906C5.66125 33.7382 4.58649 31.9859 3.51172 30.2102Z" fill="url(#paint8_linear_724_8599)"/>
<path d="M24.8907 18.7382H16.4561C15.3813 16.9859 14.3066 15.2102 13.2318 13.4579C12.1337 11.7055 11.0589 9.92983 9.98413 8.17749H18.4187C19.4935 9.92983 20.5682 11.6822 21.643 13.4579C22.7411 15.2102 23.8159 16.9859 24.8907 18.7382Z" fill="url(#paint9_linear_724_8599)"/>
</g>
<defs>
<linearGradient id="paint0_linear_724_8599" x1="763.985" y1="1069.03" x2="763.985" y2="12.9748" gradientUnits="userSpaceOnUse">
<stop stop-color="#8AC23E"/>
<stop offset="1" stop-color="#8AC23E" stop-opacity="0"/>
</linearGradient>
<linearGradient id="paint1_linear_724_8599" x1="767.409" y1="8.85338" x2="767.409" y2="1064.91" gradientUnits="userSpaceOnUse">
<stop stop-color="#698932"/>
<stop offset="1" stop-color="#698932" stop-opacity="0"/>
</linearGradient>
<linearGradient id="paint2_linear_724_8599" x1="776.159" y1="8.85338" x2="776.159" y2="1064.91" gradientUnits="userSpaceOnUse">
<stop stop-color="#FFED01"/>
<stop offset="1" stop-color="#FFED01" stop-opacity="0"/>
</linearGradient>
<linearGradient id="paint3_linear_724_8599" x1="786.967" y1="8.85338" x2="786.967" y2="1065.23" gradientUnits="userSpaceOnUse">
<stop stop-color="#E02A89"/>
<stop offset="1" stop-color="#E02A89" stop-opacity="0"/>
</linearGradient>
<linearGradient id="paint4_linear_724_8599" x1="789.69" y1="23.5144" x2="789.69" y2="1079.58" gradientUnits="userSpaceOnUse">
<stop stop-color="#7F1E4F"/>
<stop offset="1" stop-color="#7F1E4F" stop-opacity="0"/>
</linearGradient>
<linearGradient id="paint5_linear_724_8599" x1="778.27" y1="23.5145" x2="778.27" y2="1079.58" gradientUnits="userSpaceOnUse">
<stop stop-color="#E95506"/>
<stop offset="1" stop-color="#E95506" stop-opacity="0"/>
</linearGradient>
<linearGradient id="paint6_linear_724_8599" x1="744.992" y1="1069.03" x2="744.992" y2="13.6401" gradientUnits="userSpaceOnUse">
<stop stop-color="#88D0F1"/>
<stop offset="1" stop-color="#88D0F1" stop-opacity="0"/>
</linearGradient>
<linearGradient id="paint7_linear_724_8599" x1="749.152" y1="8.85338" x2="749.152" y2="1064.24" gradientUnits="userSpaceOnUse">
<stop stop-color="#00828B"/>
<stop offset="0.8325" stop-color="#00828B" stop-opacity="0"/>
</linearGradient>
<linearGradient id="paint8_linear_724_8599" x1="748.831" y1="1086.02" x2="748.831" y2="30.9601" gradientUnits="userSpaceOnUse">
<stop stop-color="#2073BA"/>
<stop offset="1" stop-color="#2073BA" stop-opacity="0"/>
</linearGradient>
<linearGradient id="paint9_linear_724_8599" x1="755.58" y1="8.85338" x2="755.58" y2="1064.24" gradientUnits="userSpaceOnUse">
<stop stop-color="#8ED0E1"/>
<stop offset="1" stop-color="#88D0F1" stop-opacity="0"/>
</linearGradient>
<clipPath id="clip0_724_8599">
<rect width="59.8281" height="50" fill="white"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 7.0 KiB

View File

@ -0,0 +1,10 @@
<svg width="50" height="50" viewBox="0 0 50 50" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_724_8513)">
<path d="M28.0504 41.6666H46.6376C47.2279 41.6666 47.8079 41.5126 48.3192 41.2201C48.8304 40.9275 49.2549 40.5066 49.55 39.9999C49.8451 39.493 50.0003 38.9182 50 38.3331C49.9997 37.748 49.8441 37.1733 49.5485 36.6667L37.0659 15.2382C36.7709 14.7315 36.3465 14.3108 35.8353 14.0182C35.3242 13.7257 34.7443 13.5716 34.1541 13.5716C33.5638 13.5716 32.9839 13.7257 32.4728 14.0182C31.9617 14.3108 31.5372 14.7315 31.2422 15.2382L28.0504 20.721L21.8101 9.99953C21.5148 9.49292 21.0902 9.0722 20.5789 8.7797C20.0676 8.48725 19.4876 8.33325 18.8973 8.33325C18.3069 8.33325 17.727 8.48725 17.2157 8.7797C16.7044 9.0722 16.2798 9.49292 15.9845 9.99953L0.451472 36.6667C0.155968 37.1733 0.000257186 37.748 3.18321e-07 38.3331C-0.000256549 38.9182 0.154949 39.493 0.450008 39.9999C0.745067 40.5066 1.16957 40.9275 1.68083 41.2201C2.19209 41.5126 2.77207 41.6666 3.36244 41.6666H15.0299C19.6527 41.6666 23.0618 39.6541 25.4076 35.7278L31.1027 25.9524L34.1532 20.721L43.3082 36.4351H31.1027L28.0504 41.6666ZM14.8397 36.4298L6.69728 36.4279L18.9027 15.4769L24.9928 25.9524L20.9152 32.9541C19.3574 35.5016 17.5876 36.4298 14.8397 36.4298Z" fill="#00DC82"/>
</g>
<defs>
<clipPath id="clip0_724_8513">
<rect width="50" height="50" fill="white"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

@ -0,0 +1,16 @@
<svg width="54" height="40" viewBox="0 0 54 40" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_724_8573)">
<path d="M18.2499 22.5728C16.2594 23.1377 14.9534 24.1282 14.0931 25.1178C14.9172 24.3969 16.0209 23.7349 17.5096 23.3129C19.0325 22.8813 20.3316 22.8844 21.4052 23.0917V22.2523C20.4893 22.1685 19.4395 22.2352 18.2499 22.5728ZM14.0021 15.5164L6.60966 17.4639C6.60966 17.4639 6.74422 17.6543 6.99376 17.9082L13.2618 16.2564C13.2618 16.2564 13.1729 17.401 12.4016 18.4248C13.8607 17.321 14.0021 15.5164 14.0021 15.5164ZM20.1904 32.8904C9.78681 35.6924 4.28277 23.6358 2.6164 17.3781C1.84654 14.4895 1.51035 12.3019 1.42078 10.8901C1.41226 10.7624 1.414 10.6342 1.42599 10.5068C0.886497 10.5391 0.628 10.8197 0.680491 11.6306C0.770059 13.0414 1.10625 15.2289 1.87611 18.1184C3.54186 24.3752 9.04652 36.4319 19.4501 33.6298C21.7145 33.0197 23.4157 31.9087 24.6929 30.4902C23.5156 31.5533 22.0426 32.3905 20.1904 32.8904ZM22.1451 8.13745V8.87795H26.2256C26.1421 8.6157 26.0577 8.37949 25.974 8.13745H22.1451Z" fill="#2D4552"/>
<path d="M27.1391 14.2353C28.9742 14.7566 29.9449 16.0433 30.4579 17.1818L32.5042 17.763C32.5042 17.763 32.2251 13.7778 28.6205 12.7541C25.2484 11.7959 23.1733 14.6277 22.9209 14.9941C23.902 14.2952 25.3342 13.723 27.1391 14.2353ZM43.4273 17.2001C40.052 16.2378 37.9778 19.0754 37.7291 19.4366C38.7108 18.7386 40.1424 18.1662 41.9465 18.6807C43.7789 19.2027 44.7485 20.4879 45.2632 21.6273L47.3122 22.2105C47.3122 22.2105 47.0287 18.2248 43.4273 17.2001ZM41.3943 27.7073L24.3727 22.9487C24.3727 22.9487 24.5571 23.8829 25.264 25.0927L39.5955 29.0991C40.7752 28.4165 41.3943 27.7073 41.3943 27.7073ZM29.5933 37.95C16.1154 34.3365 17.7447 17.1641 19.9256 9.02679C20.8235 5.67321 21.7467 3.18074 22.5124 1.50978C22.0556 1.41584 21.6771 1.65642 21.3035 2.4167C20.4903 4.06516 19.4509 6.74948 18.4452 10.5072C16.265 18.6445 14.6355 35.8165 28.1127 39.43C34.4651 41.1318 39.414 38.5454 43.103 34.4831C39.6015 37.6547 35.1306 39.4329 29.5933 37.95Z" fill="#2D4552"/>
<path d="M22.1463 28.8661V25.4007L12.5182 28.1311C12.5182 28.1311 13.2295 23.9972 18.2509 22.5729C19.7738 22.1413 21.0731 22.1442 22.1463 22.3515V8.1375H26.9673C26.4424 6.51549 25.9346 5.26675 25.508 4.39899C24.8025 2.96278 24.0793 3.9149 22.4375 5.2882C21.281 6.25428 18.3584 8.31538 13.9602 9.50038C9.56224 10.6864 6.00641 10.3719 4.52292 10.1149C2.41975 9.752 1.31973 9.29 1.42263 10.8899C1.5122 12.3009 1.84818 14.4887 2.61826 17.378C4.2838 23.635 9.78866 35.6914 20.1922 32.8894C22.9097 32.1572 24.8277 30.7098 26.1572 28.8651H22.1463V28.8659V28.8661ZM6.60985 17.464L14.0031 15.5164C14.0031 15.5164 13.7878 18.3605 11.0162 19.0912C8.24373 19.8211 6.60985 17.464 6.60985 17.464Z" fill="#E2574C"/>
<path d="M49.9713 8.30195C48.0495 8.63876 43.4389 9.05848 37.7409 7.53125C32.0413 6.00485 28.2599 3.33532 26.7616 2.08054C24.6376 0.301688 23.7034 -0.934761 22.784 0.935327C21.9712 2.58462 20.9316 5.26894 19.9255 9.02682C17.7455 17.1641 16.116 34.3359 29.5932 37.9495C43.0673 41.5599 50.2408 25.8728 52.4211 17.7349C53.4271 13.9778 53.8683 11.1329 53.9895 9.29844C54.1281 7.22047 52.7006 7.8237 49.9713 8.30195ZM22.8935 15.0343C22.8935 15.0343 25.0173 11.7309 28.6196 12.7549C32.2242 13.7787 32.5033 17.7636 32.5033 17.7636L22.8935 15.0343ZM31.6868 29.8573C25.3506 28.0014 24.3735 22.9487 24.3735 22.9487L41.3943 27.7075C41.3943 27.7067 37.9586 31.6901 31.6868 29.8571V29.8573ZM37.7045 19.4737C37.7045 19.4737 39.8256 16.1729 43.4272 17.1996C47.0287 18.225 47.3122 22.2099 47.3122 22.2099L37.7047 19.4737H37.7045Z" fill="#2EAD33"/>
<path d="M18.7802 26.3551L12.5167 28.1302C12.5167 28.1302 13.197 24.254 17.8112 22.718L14.2648 9.40747L13.9584 9.50058C9.56017 10.6866 6.00454 10.3721 4.52105 10.1151C2.41788 9.75241 1.31766 9.2902 1.42056 10.8903C1.51012 12.3013 1.84632 14.4889 2.61618 17.3782C4.28193 23.6352 9.7868 35.6916 20.1902 32.8896L20.4966 32.7934L18.7804 26.3549L18.7802 26.3551ZM6.6084 17.464L14.0017 15.5162C14.0017 15.5162 13.7863 18.3603 11.0147 19.091C8.24227 19.8208 6.6084 17.464 6.6084 17.464Z" fill="#D65348"/>
<path d="M31.9726 29.927L31.686 29.8572C25.3498 28.0013 24.3727 22.9488 24.3727 22.9488L33.1497 25.4021L37.7963 7.5461L37.7401 7.53152C32.0407 6.00491 28.2593 3.33538 26.7608 2.08039C24.637 0.301539 23.7026 -0.934702 22.7832 0.935386C21.9712 2.58468 20.9316 5.269 19.9255 9.02688C17.7455 17.1642 16.116 34.336 29.5932 37.9493L29.8694 38.0118L31.9726 29.927ZM22.8935 15.0342C22.8935 15.0342 25.0173 11.7308 28.6196 12.7548C32.2242 13.7785 32.5033 17.7635 32.5033 17.7635L22.8935 15.0342Z" fill="#1D8D22"/>
<path d="M19.1005 26.264L17.4207 26.7408C17.8178 28.9779 18.5172 31.1248 19.6149 33.0213C19.8062 32.9793 19.9957 32.943 20.1903 32.8897C20.7004 32.7522 21.1734 32.5816 21.6288 32.3958C20.4019 30.5753 19.5904 28.479 19.1005 26.264ZM18.4447 10.5076C17.5816 13.7293 16.8092 18.3666 17.0219 23.0179C17.4022 22.8527 17.8042 22.6988 18.2508 22.5721L18.5616 22.5026C18.1825 17.5343 19.0019 12.4716 19.9251 9.02702C20.144 8.21004 20.3782 7.39726 20.6277 6.58911C20.2212 6.84909 19.8062 7.0955 19.3833 7.32794C19.043 8.37952 18.73 9.43976 18.4447 10.5076Z" fill="#C04B41"/>
</g>
<defs>
<clipPath id="clip0_724_8573">
<rect width="53.3281" height="39.993" fill="white" transform="translate(0.671875 0.00341797)"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 5.2 KiB

View File

@ -0,0 +1,12 @@
<svg width="49" height="50" viewBox="0 0 49 50" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_724_8695)">
<path fill-rule="evenodd" clip-rule="evenodd" d="M24.7037 44.1171L42.3042 49.5404L33.7455 41.5849L12.9611 22.265L17.8208 17.4058L15.5835 1.97827L1.21855 19.237C0.136763 21.1107 0.136785 23.4193 1.21861 25.293L10.3387 41.0891C11.4206 42.9629 13.4198 44.1171 15.5834 44.1171H24.7037Z" fill="#18B6F6"/>
<path d="M33.8232 0.411987L15.5828 0.411989C13.4192 0.411989 11.42 1.56627 10.3382 3.44003L1.2179 19.2371L15.5828 1.97833L36.4456 22.2651L32.5583 26.1526L33.7449 41.5849L42.3035 49.5405C42.7971 49.6925 43.23 49.1754 42.9938 48.7163L39.0679 41.0892L48.188 25.2931C49.2699 23.4194 49.2699 21.1108 48.1881 19.2371L39.0678 3.44002C37.9861 1.56627 35.9869 0.411987 33.8232 0.411987Z" fill="#AC7EF4"/>
<path d="M36.4452 22.265L15.5824 1.97827L17.8198 17.4058L12.9601 22.265L33.7445 41.5849L32.558 26.1525L36.4452 22.265Z" fill="white"/>
</g>
<defs>
<clipPath id="clip0_724_8695">
<rect width="48.5929" height="49.176" fill="white" transform="translate(0.406372 0.412109)"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 5.3 KiB

View File

@ -0,0 +1,22 @@
<svg width="48" height="51" viewBox="0 0 48 51" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_724_8645)">
<g filter="url(#filter0_d_724_8645)">
<path fill-rule="evenodd" clip-rule="evenodd" d="M21.4397 1.11776C19.6612 2.01272 15.9121 3.75514 13.881 5.1451C11.85 6.5351 12.1025 7.83001 11.2133 8.72497C10.324 9.61997 7.65626 11.8574 5.87773 13.1998C4.09924 14.5423 4.54385 18.1222 4.09924 19.4646C3.65462 20.8071 2.76536 23.9394 2.32074 25.2819C1.87611 26.6243 3.20999 28.4143 4.09924 30.2042C4.98849 31.9942 7.21162 36.9165 8.10086 38.7064C8.99014 40.4964 11.6579 39.6014 13.881 41.3913C16.1042 43.1813 19.2165 45.4189 21.4397 46.7613C23.6628 48.1037 24.5521 48.1037 26.7752 46.7613C28.9983 45.4189 32.1107 43.1813 34.3338 41.3913C36.557 39.6014 39.2247 40.4964 40.114 38.7064C41.0032 36.9165 43.2263 31.9942 44.1156 30.2042C45.0047 28.4143 46.3387 26.6243 45.894 25.2819C45.4494 23.9394 44.5602 20.8071 44.1156 19.4646C43.671 18.1222 44.1156 14.5423 42.3371 13.1998C40.5586 11.8574 38.4941 10.1481 37.0016 8.72497C35.509 7.30189 36.1123 6.48756 34.3338 5.1451C32.5553 3.80266 28.5537 2.01272 26.7752 1.11776C24.9967 0.222791 23.2182 0.222791 21.4397 1.11776Z" fill="white"/>
</g>
<path fill-rule="evenodd" clip-rule="evenodd" d="M15.1601 8.8748L23.4818 14.5551C23.6696 14.6802 23.889 14.7487 24.1141 14.7525C24.3396 14.7509 24.5596 14.6822 24.7464 14.5551L33.0744 8.8557C33.398 8.62405 33.5764 8.2378 33.544 7.83931C33.5116 7.44079 33.273 7.089 32.9164 6.91347L24.5947 2.79334C24.279 2.64018 23.9113 2.64018 23.5956 2.79334L15.2993 6.91347C14.9361 7.08994 14.6944 7.44855 14.6657 7.85355C14.637 8.2586 14.8256 8.64815 15.1601 8.8748ZM26.9407 16.3382C26.9414 16.7148 27.1257 17.0672 27.4339 17.2806L34.1051 21.8402C34.5322 22.1346 35.1036 22.0978 35.49 21.751L41.0862 16.7457C41.3356 16.5229 41.4741 16.2002 41.4643 15.8646C41.4546 15.529 41.2976 15.215 41.0356 15.0073L35.6923 10.7343C35.3039 10.4257 34.7621 10.4052 34.3518 10.6833L27.4339 15.4148C27.1312 15.6244 26.9475 15.9682 26.9407 16.3382ZM10.348 22.5406C10.6176 22.7828 10.7562 23.1401 10.7211 23.5022C10.686 23.8664 10.4757 24.1901 10.1583 24.3682L6.17453 26.7563C5.77069 26.9977 5.26082 26.9628 4.89301 26.6688C4.52524 26.3748 4.37592 25.8825 4.51778 25.4317L5.99113 20.7958C6.10671 20.4285 6.3997 20.1454 6.7689 20.0444C7.13787 19.937 7.53573 20.0311 7.81863 20.2927L10.348 22.5406ZM31.9552 23.0246L24.7528 18.0957C24.37 17.8382 23.8709 17.8382 23.4881 18.0957L16.2857 23.0246C15.9992 23.2229 15.8177 23.5415 15.7925 23.8907C15.7738 24.2422 15.9131 24.5836 16.1719 24.8204L23.368 31.2585C23.5755 31.4436 23.8432 31.5455 24.1204 31.545C24.3976 31.5449 24.6651 31.4431 24.8729 31.2585L32.069 24.8204C32.3285 24.5846 32.4661 24.2418 32.4421 23.8907C32.422 23.5415 32.2421 23.2216 31.9552 23.0246ZM12.7446 21.751L7.15466 16.7457C6.90314 16.5172 6.76435 16.1888 6.77524 15.8478C6.78131 15.5118 6.93685 15.1962 7.1989 14.9882L12.5422 10.6897C12.9333 10.382 13.4762 10.3615 13.8891 10.6388L20.8006 15.3702C21.1214 15.5806 21.3149 15.9399 21.3149 16.3254C21.3149 16.7109 21.1214 17.0703 20.8006 17.2806L14.1357 21.8402C13.706 22.1333 13.1339 22.0966 12.7446 21.751ZM41.4467 28.9405L35.7556 25.5336C35.3329 25.2789 34.7949 25.3305 34.4276 25.661L27.4718 31.8698C27.1785 32.1319 27.0406 32.5282 27.1076 32.9173C27.1746 33.3064 27.4368 33.6329 27.8007 33.7802L37.4502 37.6902C37.5826 37.7452 37.7244 37.7733 37.8676 37.773C38.3155 37.7744 38.722 37.5098 38.9047 37.098L41.8956 30.3988C42.1391 29.8686 41.9452 29.239 41.4467 28.9405ZM42.2371 20.7958L43.7105 25.4317H43.6978C43.8068 25.7785 43.7448 26.1568 43.5312 26.45C43.3175 26.7432 42.9776 26.9161 42.6165 26.9155C42.4139 26.9161 42.2149 26.8611 42.0411 26.7563L38.051 24.3682C37.7401 24.1864 37.537 23.863 37.5072 23.5022C37.4699 23.1398 37.6089 22.7816 37.8802 22.5406L40.4096 20.2863C40.6954 20.0303 41.0902 19.9368 41.4593 20.038C41.8283 20.1434 42.1203 20.4279 42.2371 20.7958ZM21.1294 32.9142C21.1975 32.5266 21.061 32.1313 20.769 31.8698L13.8132 25.661C13.446 25.3305 12.908 25.2789 12.4853 25.5336L6.79421 28.9405C6.30144 29.2403 6.10649 29.862 6.33894 30.3924L9.33622 37.0916C9.58457 37.6502 10.2266 37.9116 10.7906 37.6838L20.4339 33.7738C20.7978 33.6278 21.061 33.3027 21.1294 32.9142ZM24.5441 34.8246L32.284 37.9577C32.6624 38.1196 32.9239 38.4756 32.9669 38.8874C33.0159 39.3044 32.8307 39.7142 32.4864 39.9508L24.7401 45.332C24.5545 45.4624 24.3341 45.5334 24.1078 45.5356C23.8817 45.532 23.6616 45.4611 23.4755 45.332L15.7356 39.9508C15.3899 39.7148 15.2025 39.3054 15.2486 38.8874C15.3003 38.4712 15.5712 38.1157 15.9569 37.9577L23.6968 34.8246C23.9689 34.7161 24.2719 34.7161 24.5441 34.8246Z" fill="#BF4722"/>
</g>
<defs>
<filter id="filter0_d_724_8645" x="0.232422" y="0.446533" width="47.7499" height="51.3215" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
<feOffset dy="2"/>
<feGaussianBlur stdDeviation="1"/>
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.202934 0"/>
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_724_8645"/>
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow_724_8645" result="shape"/>
</filter>
<clipPath id="clip0_724_8645">
<rect width="48" height="51" fill="white"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 5.4 KiB

View File

@ -0,0 +1,11 @@
<svg width="800" height="800" viewBox="0 0 800 800" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_4_2)">
<path fill-rule="evenodd" clip-rule="evenodd" d="M657.27 575.205C663.098 650.067 663.098 685.159 663.098 723.465H489.89C489.89 715.121 490.039 707.488 490.19 699.749C490.658 675.689 491.147 650.599 487.249 599.932C482.097 525.753 450.154 509.27 391.419 509.27H339.382H119V374.307H399.663C473.853 374.307 510.949 351.738 510.949 291.983C510.949 239.441 473.853 207.601 399.663 207.601H119V75.5353H430.576C598.535 75.5353 682 154.865 682 281.585C682 376.368 623.266 438.183 543.923 448.485C610.9 461.878 650.057 499.998 657.27 575.205Z" fill="white"/>
<path d="M119 723.465V622.855H302.142C332.733 622.855 339.375 645.543 339.375 659.075V723.465H119Z" fill="white"/>
</g>
<defs>
<clipPath id="clip0_4_2">
<rect width="800" height="800" fill="white"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 938 B

View File

@ -0,0 +1,35 @@
<svg width="49" height="46" viewBox="0 0 49 46" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_724_8658)">
<path d="M48.9977 9.9998C48.9977 9.9998 32.9266 -1.82621 20.4942 0.902735L19.5845 1.20595C17.7652 1.81239 16.2492 2.72204 15.3393 3.9349L14.7329 4.84455L10.1844 12.7286L18.0685 14.2446C21.4038 16.3674 25.6491 17.277 29.5911 16.3674L43.5396 19.0963L48.9977 9.9998Z" fill="#76B3E1"/>
<path opacity="0.3" d="M48.9977 9.9998C48.9977 9.9998 32.9266 -1.82621 20.4942 0.902735L19.5845 1.20595C17.7652 1.81239 16.2492 2.72204 15.3393 3.9349L14.7329 4.84455L10.1844 12.7286L18.0685 14.2446C21.4038 16.3674 25.6491 17.277 29.5911 16.3674L43.5396 19.0963L48.9977 9.9998Z" fill="url(#paint0_linear_724_8658)"/>
<path d="M15.3402 9.99996L14.1273 10.3032C8.97245 11.8193 7.45618 16.6709 10.1853 20.9161C13.2175 24.8581 19.5854 26.9807 24.7403 25.4646L43.5405 19.0968C43.5405 19.0968 27.4694 7.27082 15.3402 9.99996Z" fill="#518AC8"/>
<path opacity="0.3" d="M15.3402 9.99996L14.1273 10.3032C8.97245 11.8193 7.45618 16.6709 10.1853 20.9161C13.2175 24.8581 19.5854 26.9807 24.7403 25.4646L43.5405 19.0968C43.5405 19.0968 27.4694 7.27082 15.3402 9.99996Z" fill="url(#paint1_linear_724_8658)"/>
<path d="M40.2048 23.6454C36.732 19.3067 30.9752 17.5076 25.6499 19.0969L6.84968 25.1615L0.785156 35.7744L34.7467 41.5357L40.8113 30.6195C42.0241 28.497 41.7209 26.0713 40.2048 23.6454Z" fill="url(#paint2_linear_724_8658)"/>
<path d="M34.1403 34.2582C30.6674 29.9195 24.9105 28.1204 19.5853 29.7097L0.785156 35.7742C0.785156 35.7742 16.8562 47.9035 29.2887 44.8711L30.1983 44.5679C35.3532 43.0518 37.1729 38.2002 34.1403 34.2582Z" fill="url(#paint3_linear_724_8658)"/>
</g>
<defs>
<linearGradient id="paint0_linear_724_8658" x1="-217.222" y1="712.408" x2="3002.41" y2="2277.01" gradientUnits="userSpaceOnUse">
<stop offset="0.1" stop-color="#76B3E1"/>
<stop offset="0.3" stop-color="#DCF2FD"/>
<stop offset="1" stop-color="#76B3E1"/>
</linearGradient>
<linearGradient id="paint1_linear_724_8658" x1="1986.14" y1="638.668" x2="1796.53" y2="1270.12" gradientUnits="userSpaceOnUse">
<stop stop-color="#76B3E1"/>
<stop offset="0.5" stop-color="#4377BB"/>
<stop offset="1" stop-color="#1F3B77"/>
</linearGradient>
<linearGradient id="paint2_linear_724_8658" x1="437.439" y1="813.085" x2="3432.54" y2="2849.43" gradientUnits="userSpaceOnUse">
<stop stop-color="#315AA9"/>
<stop offset="0.5" stop-color="#518AC8"/>
<stop offset="1" stop-color="#315AA9"/>
</linearGradient>
<linearGradient id="paint3_linear_724_8658" x1="2159.79" y1="508.887" x2="1742.22" y2="2040.21" gradientUnits="userSpaceOnUse">
<stop stop-color="#4377BB"/>
<stop offset="0.5" stop-color="#1A336B"/>
<stop offset="1" stop-color="#1A336B"/>
</linearGradient>
<clipPath id="clip0_724_8658">
<rect width="48.2188" height="45.0117" fill="white" transform="translate(0.78125 0.494141)"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 3.0 KiB

View File

@ -0,0 +1,16 @@
<svg width="38" height="48" viewBox="0 0 38 48" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_724_8623)">
<path d="M1.60789 43.7836L0.150268 4.94068C0.101927 3.65765 1.08545 2.57034 2.36671 2.49051L35.4056 0.425596C36.7097 0.343993 37.833 1.33521 37.9146 2.63938C37.9175 2.68846 37.9191 2.73769 37.9191 2.78692V45.1133C37.9191 46.42 36.8599 47.4792 35.5532 47.4792C35.5178 47.4792 35.4823 47.4785 35.4471 47.4768L3.86617 46.0584C2.63621 46.0033 1.65416 45.014 1.60789 43.7836Z" fill="#FF4785"/>
<mask id="mask0_724_8623" style="mask-type:luminance" maskUnits="userSpaceOnUse" x="0" y="0" width="38" height="48">
<path d="M1.60594 43.7833L0.148315 4.94044C0.0999734 3.6574 1.0835 2.5701 2.36476 2.49027L35.4036 0.425352C36.7078 0.343749 37.831 1.33496 37.9126 2.63914C37.9156 2.68822 37.9172 2.73745 37.9172 2.78667V45.1131C37.9172 46.4197 36.858 47.479 35.5513 47.479C35.5158 47.479 35.4803 47.4782 35.4451 47.4766L3.86422 46.0582C2.63426 46.003 1.65221 45.0137 1.60594 43.7833Z" fill="white"/>
</mask>
<g mask="url(#mask0_724_8623)">
<path d="M28.0369 6.20488L28.2627 0.777077L32.8 0.420654L32.9954 6.01802C32.9978 6.08532 32.9809 6.15192 32.9467 6.20994C32.9125 6.26796 32.8624 6.31498 32.8024 6.34545C32.7423 6.37591 32.6748 6.38855 32.6078 6.38188C32.5407 6.3752 32.477 6.34949 32.4242 6.30777L30.6746 4.92924L28.603 6.50069C28.5497 6.54121 28.4859 6.56572 28.4192 6.57135C28.3524 6.57697 28.2854 6.56349 28.2261 6.53246C28.1667 6.50144 28.1174 6.45416 28.0839 6.39615C28.0504 6.33814 28.0341 6.2718 28.0369 6.20488ZM22.2344 18.1575C22.2344 19.0781 28.4348 18.637 29.2671 17.9903C29.2671 11.722 25.9036 8.42798 19.7445 8.42798C13.5855 8.42798 10.1346 11.7731 10.1346 16.7908C10.1346 25.5302 21.9287 25.6976 21.9287 30.4644C21.9287 31.8026 21.2733 32.597 19.8318 32.597C17.9536 32.597 17.2109 31.6376 17.2983 28.3761C17.2983 27.6686 10.1346 27.448 9.91614 28.3761C9.36 36.2801 14.2843 38.5598 19.9192 38.5598C25.3794 38.5598 29.6601 35.6495 29.6601 30.3809C29.6601 21.0142 17.6915 21.2651 17.6915 16.6236C17.6915 14.742 19.0893 14.4912 19.9193 14.4912C20.7929 14.4912 22.3654 14.6452 22.2344 18.1575Z" fill="white"/>
</g>
</g>
<defs>
<clipPath id="clip0_724_8623">
<rect width="37.8594" height="47.1584" fill="white" transform="translate(0.140747 0.420898)"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 2.3 KiB

View File

@ -0,0 +1,11 @@
<svg width="43" height="50" viewBox="0 0 43 50" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_724_8686)">
<path d="M39.7864 6.6083C35.1486 -0.0295292 25.989 -1.9969 19.3664 2.22242L7.73528 9.63573C6.16403 10.6242 4.81632 11.9297 3.77829 13.4687C2.74026 15.0076 2.03476 16.7463 1.70687 18.5734C1.152 21.6512 1.63965 24.8261 3.09258 27.5955C2.09698 29.1057 1.41793 30.8022 1.09648 32.5823C0.765155 34.4463 0.809359 36.3576 1.2265 38.2043C1.64364 40.0509 2.42533 41.7957 3.5257 43.3362C8.16434 49.9747 17.3239 51.9412 23.9457 47.7219L35.5768 40.3089C37.1482 39.3205 38.496 38.0151 39.5341 36.4761C40.5721 34.9371 41.2775 33.1983 41.6052 31.3711C42.16 28.2934 41.6727 25.1186 40.2205 22.3489C41.2158 20.8386 41.8945 19.1422 42.2156 17.3622C42.5472 15.4983 42.5031 13.5869 42.086 11.7402C41.6689 9.89352 40.887 8.14876 39.7864 6.6083Z" fill="#FF3E00"/>
<path d="M18.2297 43.9678C14.4794 44.9429 10.5192 43.4749 8.3104 40.2911C7.64834 39.3645 7.17803 38.3149 6.92705 37.204C6.67608 36.0931 6.6495 34.9433 6.84887 33.822C6.91639 33.4538 7.00931 33.0908 7.12696 32.7355L7.34611 32.0674L7.94205 32.5053C9.31868 33.5167 10.8579 34.2857 12.4934 34.7791L12.9257 34.9103L12.8859 35.3419C12.833 35.9559 12.9992 36.5687 13.355 37.0718C13.6795 37.54 14.1399 37.8974 14.674 38.0956C15.2081 38.2938 15.7902 38.3234 16.3416 38.1803C16.5945 38.1127 16.8355 38.0067 17.0563 37.8661L28.6911 30.4519C28.9758 30.2726 29.22 30.036 29.4082 29.7571C29.5964 29.4783 29.7245 29.1633 29.7843 28.8322C29.844 28.4942 29.8358 28.1478 29.7602 27.813C29.6845 27.4782 29.543 27.1619 29.3438 26.8824C29.0191 26.414 28.5586 26.0566 28.0243 25.8583C27.4901 25.6599 26.9078 25.6303 26.3562 25.7733C26.1037 25.8409 25.863 25.9467 25.6425 26.0871L21.2026 28.9173C20.4726 29.3815 19.6759 29.7313 18.8401 29.9548C15.0899 30.9299 11.1296 29.4619 8.92111 26.278C8.25901 25.3514 7.78866 24.3018 7.53766 23.191C7.28666 22.0801 7.26006 20.9303 7.45942 19.809C7.65662 18.7099 8.08103 17.6641 8.70551 16.7385C9.32999 15.8129 10.1408 15.0277 11.086 14.4333L22.7198 7.01825C23.4502 6.55334 24.2475 6.20306 25.0839 5.97961C28.8341 5.00445 32.7945 6.47247 35.0029 9.65624C35.665 10.5829 36.1354 11.6325 36.3864 12.7434C36.6374 13.8543 36.664 15.0041 36.4646 16.1254C36.3968 16.4934 36.3039 16.8564 36.1865 17.2118L35.9674 17.8799L35.3716 17.4428C33.9951 16.4307 32.4558 15.6614 30.8201 15.1679L30.3877 15.0366L30.4276 14.6051C30.48 13.9912 30.3139 13.3785 29.9584 12.8752C29.6339 12.407 29.1735 12.0496 28.6394 11.8514C28.1053 11.6531 27.5232 11.6236 26.9718 11.7668C26.7189 11.8344 26.4779 11.9403 26.2572 12.0809L14.6224 19.4955C14.3377 19.6746 14.0935 19.9111 13.9054 20.19C13.7173 20.4688 13.5894 20.7838 13.5299 21.1148C13.4698 21.4528 13.4778 21.7993 13.5533 22.1341C13.6288 22.469 13.7704 22.7854 13.9697 23.0648C14.2944 23.5332 14.7549 23.8906 15.2892 24.0889C15.8234 24.2873 16.4057 24.3169 16.9573 24.1739C17.2101 24.1062 17.4511 24.0003 17.6719 23.8598L22.111 21.0307C22.8408 20.5659 23.6375 20.2157 24.4734 19.9923C28.2235 19.0173 32.1839 20.4853 34.3925 23.6692C35.0546 24.5958 35.5249 25.6454 35.7759 26.7562C36.0268 27.867 36.0534 29.0168 35.8541 30.1381C35.6568 31.2372 35.2323 32.2831 34.6078 33.2089C33.9834 34.1347 33.1726 34.92 32.2274 35.5147L20.5937 42.9291C19.8633 43.394 19.0662 43.7443 18.2297 43.9678Z" fill="white"/>
</g>
<defs>
<clipPath id="clip0_724_8686">
<rect width="41.5625" height="50" fill="white" transform="translate(0.875)"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 3.4 KiB

View File

@ -0,0 +1,12 @@
<svg width="46" height="42" viewBox="0 0 46 42" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_724_8631)">
<path d="M34.6953 12.8271L23.867 28.4836C23.7519 28.6499 23.5859 28.7742 23.394 28.8379C23.202 28.9016 22.9944 28.9013 22.8025 28.837C22.6112 28.7727 22.446 28.6479 22.3319 28.4813C22.2182 28.315 22.162 28.1159 22.1721 27.9146L22.6056 19.2707L15.6091 17.7869C15.4598 17.7553 15.3205 17.6874 15.2036 17.5891C15.087 17.4912 14.9964 17.3659 14.94 17.2245C14.8835 17.0831 14.8628 16.9299 14.8798 16.7786C14.897 16.6271 14.9514 16.4823 15.0382 16.357L25.8668 0.700462C25.9821 0.534296 26.1482 0.410032 26.3402 0.346348C26.5321 0.282663 26.7395 0.282998 26.9313 0.347302C27.1227 0.411481 27.2879 0.536342 27.4019 0.702939C27.5157 0.86961 27.5718 1.06848 27.5617 1.26966L27.1282 9.91375L34.1245 11.3975C34.2739 11.4291 34.4132 11.497 34.5302 11.5951C34.6469 11.693 34.7376 11.8183 34.7941 11.9598C34.8505 12.1012 34.8711 12.2545 34.8538 12.4059C34.8366 12.5573 34.7822 12.7019 34.6953 12.8271Z" fill="#FCC72B"/>
<path d="M23.356 41.6193C23.068 41.6196 22.7828 41.5631 22.5167 41.4529C22.2506 41.3426 22.0089 41.1809 21.8056 40.977L11.5738 30.7462C11.1644 30.3347 10.9349 29.7776 10.9357 29.1972C10.9364 28.6167 11.1674 28.0602 11.5779 27.6498C11.9884 27.2395 12.5448 27.0087 13.1252 27.0079C13.7056 27.0071 14.2626 27.2364 14.6742 27.6456L23.356 36.3261L42.2688 17.4141C42.68 17.0029 43.2376 16.772 43.8191 16.772C44.4005 16.772 44.9582 17.003 45.3693 17.4142C45.7804 17.8253 46.0114 18.383 46.0114 18.9644C46.0114 19.5459 45.7804 20.1035 45.3692 20.5146L24.906 40.977C24.7027 41.181 24.4611 41.3427 24.1951 41.4529C23.9291 41.5632 23.644 41.6197 23.356 41.6193Z" fill="#729B1B"/>
<path d="M23.3478 41.6193C23.6358 41.6197 23.9211 41.5631 24.1871 41.4529C24.4532 41.3427 24.6949 41.181 24.8983 40.9771L35.13 30.7462C35.5393 30.3348 35.7687 29.7777 35.7678 29.1973C35.767 28.6169 35.536 28.0605 35.1256 27.65C34.7151 27.2396 34.1587 27.0086 33.5783 27.0076C32.9979 27.007 32.4409 27.2364 32.0292 27.6456L23.3478 36.3262L4.43485 17.4141C4.02224 17.0099 3.46682 16.7849 2.88925 16.7879C2.31167 16.7909 1.75861 17.0216 1.35019 17.43C0.941782 17.8384 0.711019 18.3915 0.708037 18.9691C0.705055 19.5467 0.930094 20.1021 1.33427 20.5147L21.7977 40.9771C22.001 41.181 22.2426 41.3427 22.5086 41.4529C22.7745 41.5631 23.0599 41.6197 23.3478 41.6193Z" fill="#729B1B" fill-opacity="0.5"/>
</g>
<defs>
<clipPath id="clip0_724_8631">
<rect width="45.2969" height="41.4025" fill="white" transform="translate(0.703125 0.298828)"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 2.5 KiB

View File

@ -0,0 +1,12 @@
<svg width="51" height="44" viewBox="0 0 51 44" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_724_8519)">
<path d="M40.984 0.385498H50.9991L25.9615 43.5754L0.923828 0.385498H20.0776L25.9615 10.4005L31.7201 0.385498H40.984Z" fill="#41B883"/>
<path d="M0.923828 0.385498L25.9615 43.5754L50.9991 0.385498H40.984L25.9615 26.2994L10.8137 0.385498H0.923828Z" fill="#41B883"/>
<path d="M10.8135 0.385498L25.9612 26.4246L40.9838 0.385498H31.7199L25.9612 10.4005L20.0774 0.385498H10.8135Z" fill="#35495E"/>
</g>
<defs>
<clipPath id="clip0_724_8519">
<rect width="50.0781" height="43.229" fill="white" transform="translate(0.921875 0.385498)"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 723 B

View File

@ -0,0 +1,122 @@
<script setup lang="ts">
export interface Testimonial {
/**
* The URL to the avatar image.
*/
avatar: string
/**
* The name of the Vite user.
*/
name: string
/**
* Their social media handle.
*/
handle: string
/**
* Their comment/testimonial about Vite.
*/
comment: string[]
}
defineProps<{
/**
* A testimonial from a Vite user.
*/
testimonial: Testimonial
}>()
</script>
<template>
<div class="community-card">
<div class="card__header">
<img
:src="testimonial.avatar"
:alt="testimonial.name"
class="card__avatar"
/>
<div class="card__meta">
<span class="card__name">
{{ testimonial.name }}
</span>
<span class="card__handle">
{{ testimonial.handle }}
</span>
</div>
</div>
<div class="card__content">
<p v-for="p of testimonial.comment">{{ p }}</p>
</div>
</div>
</template>
<style scoped>
.community-card {
break-inside: avoid;
width: 100%;
margin-bottom: 25px;
border-radius: 12px;
border: 1px solid rgba(38, 38, 38, 0.7);
background: #161616;
padding: 24px;
display: flex;
flex-direction: column;
gap: 12px;
.card__avatar {
width: 48px;
aspect-ratio: 1;
border-radius: 100%;
}
.card__content {
color: #a3a3a3;
font-family: Inter, sans-serif;
font-size: 16px;
font-style: normal;
font-weight: 400;
line-height: 150%;
letter-spacing: -0.32px;
text-wrap: pretty;
cursor: default;
}
.card__content p {
margin-top: 10px;
}
.card__header {
display: flex;
flex-direction: row;
gap: 20px;
align-items: center;
}
.card__meta {
display: flex;
flex-direction: column;
}
.card__name {
color: #fff;
font-family: Inter, sans-serif;
font-size: 16px;
font-style: normal;
font-weight: 500;
line-height: 150%;
letter-spacing: -0.3px;
}
.card__handle {
color: #a3a3a3;
font-family: Inter, sans-serif;
font-size: 14px;
font-style: normal;
font-weight: 500;
line-height: 150%;
letter-spacing: -0.3px;
}
}
</style>

View File

@ -0,0 +1,147 @@
<script setup lang="ts">
import CommunityCard, { Testimonial } from './CommunityCard.vue'
import placeholderAvatar from '/images/community/placeholder.jpg'
const testimonials: Testimonial[] = [
{
name: 'Ryan Carniato',
handle: '@RyanCarniato',
avatar:
'https://pbs.twimg.com/profile_images/1810837163447308292/8Piov0f6_400x400.jpg',
comment: [
`I'm loving what Vite enables. We've found building SolidStart that it is less a metaframework but a system of symbiotic Vite plugins. While built with
SolidJS in mind, they should scale from our simplest template to opinionated starter. We're building an ecosystem on Vite.`,
],
},
{
name: 'Rich Harris',
handle: '@Rich_Harris',
avatar:
'https://pbs.twimg.com/profile_images/557940120184041473/bFyXy8Pu_400x400.jpeg',
comment: [
`Vite is basically the united nations of JavaScript at this point. I'll be there as a representative of Sveltelandia`,
],
},
{
name: 'David East',
handle: '@_davideast',
avatar:
'https://pbs.twimg.com/profile_images/1691627325794725888/voQFcYjY_400x400.jpg',
comment: [
'Each and every time I use Vite, I feel a true sense of pure and unbridled joy.',
],
},
{
name: 'Mark Dalgleish',
handle: '@markdalgleish',
avatar:
'https://pbs.twimg.com/profile_images/754886061872979968/BzaOWhs1_400x400.jpg',
comment: [
`Its also a great platform to build a framework on since it provides a pluggable dev environment.`,
`Community is amazing too.`,
],
},
{
name: 'Jason Miller',
handle: '@_developit',
avatar:
'https://pbs.twimg.com/profile_images/1374778373239681025/Sc9ehtAr_400x400.jpg',
comment: [
`Every time I suspect I've hit the bounds of what Vite can do, I end up being wrong.`,
],
},
{
name: 'David Cramer',
handle: '@zeeg',
avatar:
'https://pbs.twimg.com/profile_images/1706891973553168384/zdAPOznc_400x400.jpg',
comment: ['Vite has been a game changer for the industry.'],
},
{
name: 'Dion Almaer',
handle: '@dalmaer',
avatar:
'https://pbs.twimg.com/profile_images/3380865881/f73b3687ff39b795db05fcaf35972270_400x400.jpeg',
comment: [
'I am so excited to see so many great frameworks teaming up on top of vite. So many will benefit. ❤️ to the vite team.',
],
},
{
name: 'Christoph Nakazawa',
handle: '@cpojer',
avatar:
'https://pbs.twimg.com/profile_images/1189537722286952449/OrscO0bD_400x400.jpg',
comment: ['Vite is gonna eat the (JavaScript) world.'],
},
{
name: 'Nikolaj',
handle: '@lopugit',
avatar: 'https://avatars.githubusercontent.com/u/13629190?v=4',
comment: [
'Wow, wow, wow, wow, wow, wow, Vite is..... Vite is.... Wow 🤤🤯🙏',
],
},
]
</script>
<template>
<section class="community-section">
<h2>Loved by the community</h2>
<h3>
Don't take our word for it - listen to what Vite community members have to
say.
</h3>
<div class="community-grid-container">
<div class="community-grid">
<CommunityCard
:testimonial="testimonial"
v-for="testimonial in testimonials"
:key="testimonial.name"
/>
</div>
</div>
</section>
</template>
<style scoped>
.community-section {
margin-top: 140px;
display: none;
@media (min-width: 768px) {
display: block;
}
h2 {
background: linear-gradient(0deg, #fff 0%, rgba(255, 255, 255, 0.76) 100%);
background-clip: text;
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
margin: 0 auto 10px;
text-align: center;
}
h3 {
width: 455px;
max-width: 100%;
margin: 0 auto;
text-align: center;
}
.community-grid-container {
position: relative;
}
.community-grid {
column-count: 2;
column-gap: 25px;
width: calc(100% - 50px);
margin: 40px auto 0;
@media (min-width: 1150px) {
column-count: 3;
width: 1100px;
}
}
}
</style>

View File

@ -0,0 +1,223 @@
<script setup>
import { useSponsor } from '../../../composables/sponsor'
import { VPSponsors } from 'vitepress/theme'
const { data } = useSponsor()
</script>
<template>
<div class="sponsor-section">
<svg
class="bg-lines"
width="1793"
height="1269"
viewBox="0 0 1793 1269"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M752.613 0.717285L787.634 201.189C794.351 239.643 797.729 278.606 797.729 317.642L797.729 1268.54M649.493 0.717285L704.366 138.145C736.239 217.969 752.613 303.135 752.613 389.088L752.614 1268.54M572.153 0.717285L630.175 111.432C680.966 208.35 707.498 316.138 707.498 425.558L707.498 1268.54M505.862 0.717285L564.392 97.2923C628.492 203.058 662.383 324.367 662.383 448.041L662.383 1268.54M452.46 0.717285L511.009 92.4655C580.401 201.205 617.268 327.512 617.268 456.507L617.268 1268.54M407.345 0.717285L465.894 92.4655C535.286 201.205 572.153 327.512 572.153 456.507L572.153 1268.54M362.23 0.717285L420.779 92.4655C490.17 201.205 527.038 327.512 527.038 456.507L527.038 1268.54M317.115 0.717285L375.664 92.4655C445.055 201.205 481.923 327.512 481.923 456.507L481.923 1268.54M272 0.717285L330.549 92.4655C399.94 201.205 436.808 327.512 436.808 456.507L436.808 1268.54M226.885 0.717285L285.433 92.4655C354.825 201.205 391.693 327.512 391.693 456.507L391.693 1268.54M181.77 0.717285L240.318 92.4655C309.71 201.205 346.578 327.512 346.578 456.507L346.578 1268.54M136.655 0.717285L195.203 92.4655C264.595 201.205 301.463 327.512 301.463 456.507L301.463 1268.54M91.5395 0.717285L150.088 92.4655C219.48 201.205 256.348 327.512 256.348 456.507L256.348 1268.54M46.4244 0.717285L104.973 92.4655C174.365 201.205 211.233 327.512 211.233 456.507L211.233 1268.54M1.30933 0.717285L59.8581 92.4655C129.25 201.205 166.117 327.512 166.117 456.507L166.117 1268.54M1040.8 0.717285L1005.78 201.189C999.06 239.643 995.683 278.606 995.683 317.642V1268.54M1143.92 0.717285L1089.04 138.145C1057.17 217.969 1040.8 303.135 1040.8 389.088V1268.54M1221.26 0.717285L1163.24 111.432C1112.45 208.35 1085.91 316.138 1085.91 425.558V1268.54M1287.55 0.717285L1229.02 97.2923C1164.92 203.058 1131.03 324.367 1131.03 448.041V1268.54M1340.95 0.717285L1282.4 92.4655C1213.01 201.205 1176.14 327.512 1176.14 456.507V1268.54M1386.07 0.717285L1327.52 92.4655C1258.13 201.205 1221.26 327.512 1221.26 456.507V1268.54M1431.18 0.717285L1372.63 92.4655C1303.24 201.205 1266.37 327.512 1266.37 456.507V1268.54M1476.3 0.717285L1417.75 92.4655C1348.36 201.205 1311.49 327.512 1311.49 456.507V1268.54M1521.41 0.717285L1462.86 92.4655C1393.47 201.205 1356.6 327.512 1356.6 456.507V1268.54M1566.53 0.717285L1507.98 92.4655C1438.59 201.205 1401.72 327.512 1401.72 456.507V1268.54M1611.64 0.717285L1553.09 92.4655C1483.7 201.205 1446.83 327.512 1446.83 456.507V1268.54M1656.76 0.717285L1598.21 92.4655C1528.82 201.205 1491.95 327.512 1491.95 456.507V1268.54M1701.87 0.717285L1643.32 92.4655C1573.93 201.205 1537.06 327.512 1537.06 456.507V1268.54M1746.99 0.717285L1688.44 92.4655C1619.05 201.205 1582.18 327.512 1582.18 456.507V1268.54M1792.1 0.717285L1733.55 92.4655C1664.16 201.205 1627.29 327.512 1627.29 456.507V1268.54M968.061 0.717335L950.567 258.978V1268.54M893.943 0.717285L893.943 1268.54M824.89 0.717285L842.843 258.978L842.843 1268.54"
stroke="url(#linear-sponsor-lines)"
/>
<defs>
<linearGradient
id="linear-sponsor-lines"
x1="0"
y1="0"
x2="0"
y2="1200"
gradientUnits="userSpaceOnUse"
>
<stop offset="0.1" stop-color="#1b1c20" stop-opacity="0" />
<stop offset="0.35" stop-color="#1b1c20" />
<stop offset="0.55" stop-color="#1b1c20" stop-opacity="0.2" />
<stop offset="0.6" stop-color="#1b1c20" stop-opacity="0.2" />
<stop offset="0.7" stop-color="#1b1c20" />
<stop offset="1" stop-color="#1b1c20" stop-opacity="0" />
</linearGradient>
</defs>
</svg>
<!-- Title Section -->
<img
class="icon-heart"
src="/heart.svg"
alt="Vite is made possible by our contributors, partner companies, and sponsors"
width="58"
height="55"
/>
<h2>Free &amp; open source</h2>
<h4>
Vite is MIT Licensed and will always be free and open source. This is made
possible by our contributors and these companies:
</h4>
<h4>Brought to you by</h4>
<div class="voidzero">
<a href="https://voidzero.dev" target="_blank">
<img src="./voidzero.svg" />
</a>
</div>
<!-- Sponsor Grid -->
<div class="sponsor-grid">
<VPSponsors v-if="data" :data="data" />
</div>
<!-- Sponsorship Actions -->
<div class="sponsor-actions">
<a
href="https://github.com/sponsors/vitejs"
target="_blank"
class="btn btn--outline btn--rounded"
>Become a Sponsor</a
>
</div>
</div>
</template>
<style scoped>
.sponsor-section {
margin-top: 120px;
position: relative;
max-width: 100%;
overflow: hidden;
@media (min-width: 768px) {
margin-top: 180px;
}
.bg-lines {
position: absolute;
top: 0;
left: 0;
right: 0;
width: 100%;
z-index: 0;
display: none;
pointer-events: none;
@media (min-width: 1240px) {
display: block;
}
}
.icon-heart {
margin: 0 auto 10px;
}
h2 {
background: linear-gradient(0deg, #fff 0%, rgba(255, 255, 255, 0.76) 100%);
background-clip: text;
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
margin: 0 auto 10px;
text-align: center;
}
.voidzero {
text-align: center;
img {
position: relative;
display: inline-block;
max-width: 260px;
}
}
h4 {
color: #a3a3a3;
text-align: center;
font-family: Inter, sans-serif;
font-size: 16px;
font-style: normal;
font-weight: 400;
line-height: 150%; /* 24px */
letter-spacing: -0.32px;
width: 480px;
max-width: 100%;
margin: 0 auto 40px;
}
.sponsor-grid {
width: 1200px;
margin: 40px auto 0;
@media (max-width: 1240px) {
width: 100%;
padding: 0 20px;
}
&:deep(.vp-sponsor-tier) {
color: #fff;
text-align: center;
font-family: Inter, sans-serif;
font-size: 16px;
font-style: normal;
font-weight: 500;
line-height: 150%;
letter-spacing: -0.32px;
width: 100%;
max-width: unset;
padding: 18px;
display: block;
border-radius: 12px;
border: 1px solid rgba(38, 38, 38, 0.7);
background: #161616;
margin: 20px auto !important;
@media (min-width: 768px) {
background: rgba(38, 38, 38, 0.25);
backdrop-filter: blur(1px);
}
}
&:deep(.vp-sponsor-grid) {
gap: 20px;
}
&:deep(.vp-sponsor-grid-item) {
border-radius: 12px;
border: 1px solid rgba(38, 38, 38, 0.7);
background: #161616;
@media (min-width: 768px) {
background: rgba(38, 38, 38, 0.25);
backdrop-filter: blur(1px);
}
}
&:deep(.vp-sponsor-grid[data-vp-grid='2'] .vp-sponsor-grid-item) {
width: calc((100% - 20px) / 2);
}
&:deep(.vp-sponsor-grid[data-vp-grid='3'] .vp-sponsor-grid-item) {
width: calc((100% - 20px * 2) / 3);
}
&:deep(.vp-sponsor-grid[data-vp-grid='4'] .vp-sponsor-grid-item) {
width: calc((100% - 20px * 3) / 4);
}
&:deep(.vp-sponsor-grid[data-vp-grid='5'] .vp-sponsor-grid-item) {
width: calc((100% - 20px * 4) / 5);
}
&:deep(.vp-sponsor-grid-item .vp-sponsor-grid-image) {
transition: transform 0.2s ease-in-out;
}
&:deep(.vp-sponsor-grid-item:hover .vp-sponsor-grid-image) {
filter: grayscale(1) invert(1);
transform: scale(1.05);
}
}
.sponsor-actions {
margin: 60px auto 0;
width: fit-content;
display: flex;
flex-direction: row;
gap: 20px;
}
}
</style>

View File

@ -0,0 +1,11 @@
<svg width="326" height="103" viewBox="0 0 326 103" xmlns="http://www.w3.org/2000/svg">
<path d="M82.8153 32.6886C87.0907 32.6886 90.8571 33.3672 94.1145 34.7243C97.3719 36.0815 100.12 37.9816 102.36 40.4245C104.667 42.7995 106.398 45.6835 107.551 49.0765C108.705 52.4694 109.282 56.2356 109.282 60.375C109.282 64.5822 108.705 68.3823 107.551 71.7753C106.466 75.1003 104.803 77.9843 102.563 80.4273C100.324 82.8702 97.5416 84.7363 94.2163 86.0256C90.9589 87.3149 87.1586 87.9596 82.8153 87.9596C78.54 87.9596 74.7735 87.3149 71.5161 86.0256C68.2587 84.6684 65.5102 82.8023 63.2707 80.4273C61.0991 77.9843 59.4365 75.0664 58.2828 71.6735C57.197 68.2805 56.6541 64.5144 56.6541 60.375C56.6541 56.2356 57.197 52.4694 58.2828 49.0765C59.4365 45.6835 61.1331 42.7995 63.3725 40.4245C65.612 37.9816 68.3605 36.0815 71.6179 34.7243C74.8753 33.3672 78.6078 32.6886 82.8153 32.6886ZM82.8153 77.8826C85.462 77.8826 87.7015 77.4415 89.5338 76.5593C91.4339 75.6093 92.9608 74.3539 94.1145 72.7931C95.336 71.2324 96.2183 69.4002 96.7612 67.2966C97.3719 65.193 97.6773 62.9197 97.6773 60.4768C97.6773 58.0338 97.3719 55.7606 96.7612 53.6569C96.2183 51.4855 95.336 49.6193 94.1145 48.0586C92.9608 46.4978 91.4339 45.2764 89.5338 44.3942C87.7015 43.5121 85.462 43.071 82.8153 43.071C80.2365 43.071 78.031 43.5121 76.1987 44.3942C74.3664 45.2764 72.8394 46.4978 71.6179 48.0586C70.3964 49.6193 69.4802 51.4855 68.8694 53.6569C68.3265 55.7606 68.0551 58.0338 68.0551 60.4768C68.0551 62.9197 68.3265 65.193 68.8694 67.2966C69.4802 69.4002 70.3624 71.2324 71.5161 72.7931C72.7376 74.3539 74.2646 75.6093 76.0969 76.5593C77.997 77.4415 80.2365 77.8826 82.8153 77.8826Z" fill="#fff"/>
<path d="M192.981 87.2471H182.089L181.478 79.8165C179.51 82.6666 177.033 84.7024 174.047 85.9238C171.061 87.1453 167.702 87.8239 163.969 87.9596C159.83 87.8917 156.267 87.1453 153.281 85.7203C150.295 84.2274 147.818 82.2594 145.85 79.8165C143.882 77.3058 142.423 74.4218 141.473 71.1645C140.591 67.9073 140.15 64.4465 140.15 60.7821C140.15 56.7785 140.659 53.0801 141.676 49.6872C142.762 46.2943 144.357 43.3424 146.461 40.8316C148.565 38.3209 151.143 36.3529 154.197 34.9279C157.251 33.435 160.814 32.6886 164.886 32.6886C167.804 32.6886 170.756 33.1636 173.742 34.1136C176.728 35.0636 179.273 36.828 181.376 39.4066V5.18881L192.981 14.5409V87.2471ZM166.209 43.1728C163.63 43.1728 161.425 43.6138 159.592 44.496C157.76 45.3782 156.233 46.5996 155.012 48.1604C153.858 49.7211 153.01 51.5873 152.467 53.7587C151.924 55.8624 151.652 58.1356 151.652 60.5785C151.652 63.0215 151.924 65.2947 152.467 67.3984C153.01 69.502 153.858 71.3342 155.012 72.8949C156.233 74.4557 157.76 75.7111 159.592 76.6611C161.492 77.5433 163.766 77.9843 166.413 77.9843C168.923 77.9843 171.095 77.5093 172.927 76.5593C174.828 75.5414 176.388 74.2182 177.61 72.5896C178.899 70.961 179.849 69.0948 180.46 66.9912C181.071 64.8876 181.376 62.7161 181.376 60.4768C181.376 58.1017 181.071 55.8624 180.46 53.7587C179.917 51.6551 179.035 49.8569 177.814 48.364C176.592 46.8032 175.031 45.5817 173.131 44.6996C171.231 43.7496 168.923 43.2406 166.209 43.1728Z" fill="#fff"/>
<path d="M0 32.3832H12.8261L27.6881 74.9307L42.4483 32.3832H55.2744L35.1191 86.0256H20.1553L0 32.3832Z" fill="#fff"/>
<path d="M244.344 0C240.883 4.1227 237.941 8.31299 235.518 12.5709C233.096 16.7612 231.123 21.019 229.6 25.3445C228.077 29.67 226.97 34.0292 226.278 38.4223C225.585 42.8153 225.205 47.2083 225.135 51.6014C225.274 60.5226 226.797 69.2749 229.704 77.8583C232.611 86.374 237.457 94.7546 244.24 103H230.95C227.973 99.3504 225.378 95.4305 223.163 91.2402C220.948 87.1175 219.113 82.8596 217.66 78.4666C216.206 74.0059 215.099 69.5115 214.337 64.9833C213.645 60.4551 213.299 55.9944 213.299 51.6014C213.299 47.2083 213.645 42.7477 214.337 38.2195C215.099 33.6237 216.206 29.0955 217.66 24.6348C219.183 20.1742 221.052 15.8825 223.267 11.7598C225.482 7.56955 228.077 3.6496 231.054 0H244.344Z" fill="#fff"/>
<path d="M294.955 103C301.808 94.7546 306.688 86.3402 309.595 77.7569C312.502 69.106 314.025 60.3537 314.163 51.5C314.025 42.5787 312.502 33.8264 309.595 25.2431C306.688 16.6598 301.842 8.24541 295.059 0H308.245C311.222 3.6496 313.817 7.56955 316.032 11.7598C318.247 15.8825 320.082 20.1742 321.535 24.6348C323.058 29.0279 324.166 33.5223 324.858 38.1181C325.619 42.6463 326 47.107 326 51.5C326 55.893 325.619 60.3875 324.858 64.9833C324.096 69.5115 322.954 74.0059 321.431 78.4666C319.978 82.8596 318.144 87.1175 315.929 91.2402C313.714 95.4305 311.118 99.3504 308.141 103H294.955Z" fill="#fff"/>
<path d="M297.673 51.3885C297.673 56.8851 297.096 61.9066 295.943 66.4532C294.857 70.9319 293.126 74.7659 290.751 77.9553C288.444 81.1446 285.526 83.6215 281.997 85.3858C278.468 87.1501 274.294 88.0323 269.476 88.0323C264.658 88.0323 260.484 87.1841 256.955 85.4876C253.426 83.7233 250.508 81.2803 248.201 78.1588C245.894 75.0373 244.163 71.2712 243.009 66.8604C241.856 62.4495 241.279 57.5297 241.279 52.101C241.279 46.5366 241.822 41.4472 242.908 36.8328C243.993 32.2184 245.69 28.2487 247.997 24.9236C250.305 21.5985 253.223 19.0538 256.752 17.2895C260.348 15.4573 264.59 14.5412 269.476 14.5412C274.226 14.5412 278.366 15.4233 281.895 17.1877C285.424 18.952 288.342 21.4628 290.649 24.72C293.024 27.9772 294.789 31.8791 295.943 36.4256C297.096 40.9043 297.673 45.892 297.673 51.3885ZM252.985 51.3885C252.985 55.1208 253.257 58.5816 253.8 61.7709C254.343 64.9603 255.259 67.7425 256.548 70.1176C256.729 70.4408 256.917 70.7547 257.114 71.0593C258.321 72.9288 259.829 74.4471 261.638 75.6141C262.533 76.1627 263.52 76.5946 264.6 76.9098C266.057 77.3353 267.683 77.5481 269.476 77.5481C272.53 77.5481 275.109 76.9035 277.212 75.6141C279.316 74.257 281.013 72.4248 282.302 70.1176C283.592 67.7425 284.508 64.9603 285.051 61.7709C285.593 58.5816 285.865 55.1208 285.865 51.3885C285.865 47.7242 285.593 44.2973 285.051 41.1079C284.508 37.8507 283.592 35.0685 282.302 32.7613C282.102 32.3928 281.892 32.0366 281.673 31.6926C280.477 29.8194 278.99 28.3095 277.212 27.1629C276.301 26.5748 275.3 26.1142 274.21 25.7809C272.785 25.3451 271.207 25.1272 269.476 25.1272C266.354 25.1272 263.742 25.8057 261.638 27.1629C259.534 28.5201 257.838 30.3862 256.548 32.7613C255.259 35.0685 254.343 37.8507 253.8 41.1079C253.257 44.2973 252.985 47.7242 252.985 51.3885Z" fill="#fff"/>
<path d="M130.455 27.1629H118.861V15.5701H130.455V27.1629Z" fill="#fff"/>
<path d="M130.455 32.7177V77.5571H136.046V87.2512H112.956V77.5571H118.858V42.4118H112.956V32.7177H130.455Z" fill="#fff"/>
<path d="M274.726 23.4442H283.983L264.466 79.5556H255.21L274.726 23.4442Z" fill="#fff"/>
</svg>

After

Width:  |  Height:  |  Size: 6.4 KiB

View File

@ -0,0 +1,292 @@
<template>
<div class="get-started-section">
<div class="vite-chip">
<svg
width="134"
height="134"
viewBox="0 0 134 134"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<g>
<rect
class="vite-chip__background"
x="1"
y="1"
width="132"
height="132"
rx="10"
fill="black"
fill-opacity="0.3"
/>
<rect
class="vite-chip__highlight"
x="1"
y="1"
width="132"
height="132"
rx="10"
fill="url(#linear-vite-chip-highlight)"
fill-opacity="0.1"
/>
<rect
x="1"
y="1"
width="132"
height="132"
rx="10"
stroke="#111111"
stroke-opacity="0.2"
stroke-width="1"
/>
</g>
<g opacity="0.6">
<rect
x="1"
y="1"
width="132"
height="132"
rx="10"
fill="#1E1E1E"
fill-opacity="0.4"
/>
<rect
x="1"
y="1"
width="132"
height="132"
rx="10"
stroke="url(#radial-edge)"
stroke-width="1.15417"
/>
<rect
x="1"
y="1"
width="132"
height="132"
rx="10"
stroke="url(#radial-edge-2)"
stroke-opacity="0.1"
stroke-width="1.15417"
/>
</g>
<defs>
<linearGradient
id="linear-vite-chip-highlight"
x1="6.92498"
y1="15.5812"
x2="113.685"
y2="116.571"
gradientUnits="userSpaceOnUse"
>
<stop offset="0" stop-opacity="0" />
<stop offset="0.37" stop-color="white" />
<stop offset="1" stop-opacity="0" />
</linearGradient>
<radialGradient
id="radial-edge"
cx="0"
cy="0"
r="1"
gradientUnits="userSpaceOnUse"
gradientTransform="translate(95.2187 56.5541) rotate(110.653) scale(80.173)"
>
<stop offset="0" stop-color="white" />
<stop offset="1" stop-opacity="0" />
</radialGradient>
<radialGradient
id="radial-edge-2"
cx="0"
cy="0"
r="1"
gradientUnits="userSpaceOnUse"
gradientTransform="translate(8.65624 122.919) rotate(-21.5713) scale(80.0504)"
>
<stop offset="0" stop-color="white" />
<stop offset="1" stop-opacity="0" />
</radialGradient>
</defs>
</svg>
<img src="/logo.svg" alt="Vite Logo" class="vite-chip__logo" />
</div>
<h2>Start building with Vite</h2>
<h3>
Prepare for a development environment that can finally keep pace with the
speed of your mind.
</h3>
<a href="/guide/" class="btn btn--primary">Get started</a>
<div class="glow glow--purple" />
<div class="glow glow--blue" />
</div>
</template>
<style scoped>
.get-started-section {
margin: 0 auto;
padding-top: 260px;
padding-bottom: 220px;
position: relative;
overflow: hidden;
h2 {
color: #fff;
font-size: 44px;
font-style: normal;
font-weight: 600;
line-height: 120%;
letter-spacing: -1px;
margin: 0 auto 20px;
text-align: center;
position: relative;
z-index: 1;
@media (min-width: 768px) {
font-size: 52px;
}
}
h3 {
margin: 0 auto 40px;
color: #d4d4d8;
position: relative;
z-index: 1;
}
.btn {
margin: 0 auto;
position: relative;
z-index: 1;
}
.vite-chip {
display: flex;
justify-content: center;
align-items: center;
width: 84px;
aspect-ratio: 1;
filter: drop-shadow(0px 18px 33px rgba(0, 0, 0, 0.5));
margin: 0 auto 60px;
border: 1px solid #2b4659;
border-radius: 6px;
position: relative;
z-index: 1;
&:before {
content: '';
position: absolute;
bottom: -30px;
left: -20px;
width: 80px;
height: 80px;
background: linear-gradient(180deg, #61d9ff 0%, rgba(0, 0, 0, 0) 100%);
z-index: -1;
filter: blur(30px);
}
&:after {
content: '';
position: absolute;
top: -20px;
right: -20px;
width: 80px;
height: 80px;
background: linear-gradient(
270deg,
#7a23a1 0%,
rgba(113, 94, 189, 0.9) 60%,
rgba(113, 94, 189, 0.9) 80%,
rgba(189, 52, 254, 0) 100%
);
z-index: -1;
filter: blur(30px);
}
svg {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
max-width: 100%;
z-index: 2;
border: 1px solid #2f2f2f;
border-radius: 5px;
filter: drop-shadow(0px 10px 5px rgba(0, 0, 0, 0.5));
}
.vite-chip__logo {
position: relative;
width: 50%;
opacity: 0.8;
z-index: 3;
filter: drop-shadow(
0 0 0.6rem color-mix(in srgb, #ffffad 50%, transparent)
);
}
}
.glow {
&.glow--blue {
position: absolute;
bottom: -15%;
left: -20%;
width: 80%;
aspect-ratio: 1.5;
pointer-events: none;
z-index: 0;
border-radius: 100%;
background: linear-gradient(180deg, #61d9ff 0%, rgba(0, 0, 0, 0) 100%);
filter: blur(15vw);
transform: none;
opacity: 0.5;
@media (min-width: 768px) {
filter: blur(10vw);
bottom: -30%;
left: -10%;
opacity: 0.2;
}
@media (min-width: 1025px) {
filter: blur(80px);
width: 900px;
left: calc(50% - 700px);
}
}
&.glow--purple {
position: absolute;
bottom: -15%;
right: -20%;
width: 80%;
aspect-ratio: 1.5;
pointer-events: none;
z-index: 0;
border-radius: 100%;
background: linear-gradient(
270deg,
#7a23a1 0%,
rgba(113, 94, 189, 0.9) 60%,
rgba(113, 94, 189, 0.9) 80%,
rgba(189, 52, 254, 0) 100%
);
filter: blur(15vw);
transform: none;
opacity: 0.6;
@media (min-width: 768px) {
filter: blur(10vw);
bottom: -30%;
right: -10%;
opacity: 0.3;
}
@media (min-width: 1025px) {
filter: blur(90px);
width: 1100px;
right: calc(50% - 700px);
}
}
}
}
</style>

View File

@ -0,0 +1,214 @@
<script setup lang="ts">
import { computed, Ref, ref, watch, ComputedRef } from 'vue'
import { gsap } from 'gsap'
/**
* A single glowing "node" (dot) on an SVG path.
*/
export interface SvgNodeProps {
/**
* The SVG path to draw the node on.
*/
path: string
/**
* The position of the node along the path, represented as a percentage from 0-1.
*/
position?: number
/**
* Whether the node is visible or not.
*/
visible?: boolean
/**
* Whether the node label is visible or not.
*/
labelVisible?: boolean
/**
* The label to display next to the node.
*/
label?: string
/**
* The color of the glow effect.
*/
glowColor?: string
/**
* The color of the dot.
*/
dotColor?: string | boolean
}
const props = withDefaults(defineProps<SvgNodeProps>(), {
position: 0,
visible: false,
labelVisible: false,
glowColor: '#41D1FF',
dotColor: '#9fe6fd',
})
/**
* A unique id for the path, to avoid collisions in a single SVG output.
*/
const pathId: Ref<string> = ref(Math.random().toString(36))
/**
* A ref for the path element in the SVG DOM.
*/
const pathElement: Ref<SVGPathElement | null> = ref(null)
/**
* The radius on each side of the dot, represented as a glow on the SVG path.
*/
const gradientWidth: Ref<number> = ref(30)
/**
* A scale factor for animating the gradient width.
*/
const gradientWidthScaleFactor: Ref<number> = ref(props.visible ? 1 : 0)
/**
* The length of the SVG path.
*/
const pathLength: ComputedRef<number> = computed(() => {
if (!pathElement.value) return 0
return pathElement.value.getTotalLength()
})
/**
* The position of the dot on the SVG path.
*/
const dotPosition: Ref<{ x: number; y: number }> = ref({ x: 0, y: 0 })
/**
* Watch for changes to the position of the dot.
*/
watch(
() => props.position,
() => {
if (!pathElement.value) return { x: 0, y: 0 }
const position = (1 - props.position) * pathLength.value
const { x, y } = pathElement.value.getPointAtLength(position)
dotPosition.value = { x, y }
},
)
/**
* The radius of the dot.
*/
const dotRadius: Ref<number> = ref(props.visible ? 3 : 0)
/**
* Watch for changes to the visible prop and animate the glow and dot radius.
*/
watch(
() => props.visible,
(visible) => {
gsap.to(gradientWidthScaleFactor, {
duration: 0.5,
ease: 'power2.inOut',
value: visible ? 1 : 0,
})
gsap.to(dotRadius, {
duration: 0.6,
ease: 'power2.inOut',
value: visible ? 3 : 0,
})
},
)
</script>
<template>
<g>
<path
ref="pathElement"
:d="props.path"
:stroke="`url(#glow_gradient_${pathId})`"
stroke-width="1.2"
:mask="`url(#glow_mask_${pathId})`"
class="svg-path"
/>
<circle
v-if="props.dotColor"
:cx="dotPosition.x"
:cy="dotPosition.y"
:r="dotRadius"
:fill="props.dotColor ? props.dotColor : 'transparent'"
class="circle-dot"
:style="`--dot-color: ${props.dotColor}`"
key="circle-dot"
/>
<text
v-if="props.label"
:x="dotPosition.x"
:y="dotPosition.y + 15"
fill="#a3a3a3"
font-family="Inter, sans-serif"
font-size="11px"
font-style="normal"
font-weight="400"
text-anchor="middle"
alignment-baseline="hanging"
class="label"
:class="{ 'label--visible': props.labelVisible }"
>
{{ props.label }}
</text>
<defs>
<mask :id="`glow_mask_${pathId}`">
<path :d="props.path" fill="black" />
<circle
:cx="dotPosition.x"
:cy="dotPosition.y"
:r="gradientWidth * gradientWidthScaleFactor"
fill="white"
/>
</mask>
<radialGradient
:id="`glow_gradient_${pathId}`"
:cx="dotPosition.x"
:cy="dotPosition.y"
:r="gradientWidth * gradientWidthScaleFactor"
gradientUnits="userSpaceOnUse"
>
<stop offset="0%" :stop-color="props.glowColor" :stop-opacity="1" />
<stop offset="100%" :stop-color="props.glowColor" stop-opacity="0" />
</radialGradient>
</defs>
</g>
</template>
<style scoped>
.svg-path {
transform: translate3d(0, 0, 0);
backface-visibility: hidden;
}
.label {
opacity: 0;
transition: opacity 0.4s ease-in-out;
display: none;
will-change: opacity;
@media (min-width: 1180px) {
display: block;
}
&.label--visible {
opacity: 1;
}
}
.circle-dot {
transform: translate3d(0, 0, 0);
backface-visibility: hidden;
--dot-color: white;
@media (min-width: 768px) {
filter: drop-shadow(0 0 3px var(--dot-color));
}
}
</style>

View File

@ -99,7 +99,7 @@ export function useSponsor() {
function mapSponsors(sponsors: Sponsors) {
return [
{
tier: 'Special Sponsors',
tier: 'in partnership with',
size: 'big',
items: viteSponsors['special'],
},

View File

@ -0,0 +1,107 @@
import { type Ref, onMounted, onUnmounted, ref } from 'vue'
import { gsap } from 'gsap'
import { ScrollTrigger } from 'gsap/dist/ScrollTrigger'
gsap.registerPlugin(ScrollTrigger)
/**
* A custom hook for animating a card element.
*
* @param {HTMLElement | string} el - The element or selector for the element to be animated
* @param {() => GSAPTimeline | null} animation - A function that returns a GSAP timeline for the animation
* @param {object} options - Options for the animation
*/
export function useCardAnimation(
el: HTMLElement | string,
animation: (() => GSAPTimeline) | undefined = undefined,
options?: {
/**
* A flag to indicate whether the animation should only run once, and not reset once complete.
*/
once?: boolean
},
) {
/**
* The GSAP timeline for this animation.
*/
let timeline: GSAPTimeline | null
/**
* A flag to indicate whether the card is currently active or not.
* May be inactive while the animation is still finishing up, due to CSS transitions.
*/
const isCardActive: Ref<boolean> = ref(false)
/**
* An internal flag to prevent multiple animations from running at the same time.
*/
const isAnimationRunning: Ref<boolean> = ref(false)
/**
* Starts the card's animation, managing the lifecycle internally to prevent multiple animations from running at the same time.
*/
const startAnimation = () => {
if (isAnimationRunning.value) {
return
} else {
isAnimationRunning.value = true
isCardActive.value = true
}
if (timeline) {
timeline.kill()
}
if (!animation) {
return
}
timeline = gsap.timeline({
onComplete: () => {
if (!options?.once) {
isCardActive.value = false
setTimeout(() => {
isAnimationRunning.value = false
}, 3000)
}
},
})
timeline.add(animation())
}
/**
* The ScrollTrigger instance for this card.
*/
let scrollTriggerInstance: ScrollTrigger | null = null
/**
* Trigger's the card's animation automatically on mobile devices (no hover method)
*/
onMounted(() => {
if (window.innerWidth < 768) {
scrollTriggerInstance = ScrollTrigger.create({
trigger: el,
start: 'top 60%',
onEnter: () => {
startAnimation()
},
})
}
})
/**
* Remove the ScrollTrigger and GSAP timeline instances when the component is unmounted
*/
onUnmounted(() => {
if (scrollTriggerInstance) {
scrollTriggerInstance.kill()
scrollTriggerInstance = null
}
if (timeline) {
timeline.kill()
timeline = null
}
})
return {
startAnimation,
isCardActive,
}
}

View File

@ -0,0 +1,19 @@
import { nextTick, onMounted } from 'vue'
import { gsap } from 'gsap'
export function useSlideIn(el: HTMLElement | string) {
onMounted(async () => {
await nextTick(() => {
gsap.to(el, {
x: 0,
duration: 1,
ease: 'power3.out',
scrollTrigger: {
trigger: el,
start: 'top 100%',
once: true,
},
})
})
})
}

View File

@ -4,7 +4,7 @@ import DefaultTheme from 'vitepress/theme'
import TwoslashFloatingVue from '@shikijs/vitepress-twoslash/client'
import '@shikijs/vitepress-twoslash/style.css'
import './styles/vars.css'
import HomeSponsors from './components/HomeSponsors.vue'
import './styles/landing.css'
import AsideSponsors from './components/AsideSponsors.vue'
import SvgImage from './components/SvgImage.vue'
import 'virtual:group-icons.css'
@ -13,7 +13,6 @@ export default {
extends: DefaultTheme,
Layout() {
return h(DefaultTheme.Layout, null, {
'home-features-after': () => h(HomeSponsors),
'aside-ads-before': () => h(AsideSponsors),
})
},

View File

@ -0,0 +1,218 @@
/* /////////////////////// */
/* Landing Page CSS Styles */
/* /////////////////////// */
html:has(.landing) {
background-color: #101010;
--vp-c-bg: #101010;
body {
background-color: #101010;
}
}
.landing {
overflow-x: hidden;
background-color: #101010;
* {
-webkit-font-smoothing: antialiased !important;
-moz-osx-font-smoothing: grayscale !important;
text-rendering: optimizeLegibility !important;
}
/* /////////////////// */
/* VitePress Overrides */
/* /////////////////// */
.VPNavBar,
.VPNavBar:not(.top) {
background: transparent !important;
@media (min-width: 768px) {
backdrop-filter: blur(10px);
background: rgba(15, 15, 15, 0.8) !important;
border-bottom: 1px solid #262626 !important;
}
.content-body {
background: none !important;
}
}
.VPFooter {
border-top: 1px solid #262626 !important;
background: radial-gradient(circle at top center, #0f151a 30%, #000000 80%);
}
.VPHome {
padding-bottom: 0 !important;
margin-bottom: 0 !important;
}
/* /////////////// */
/* Force Dark Mode */
/* /////////////// */
.VPNavBarAppearance {
display: none;
}
.VPNavScreenAppearance {
visibility: hidden;
}
.social-links::before {
margin-left: 0 !important;
}
/* ////////// */
/* Typography */
/* ////////// */
h1 {
text-align: center;
font-family: 'Manrope', sans-serif;
font-style: normal;
font-weight: 600;
background: linear-gradient(
180deg,
#fff 0%,
rgba(255, 255, 255, 0.31) 100%
);
background-clip: text;
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
text-wrap: balance;
cursor: default;
font-size: 44px;
line-height: 120%;
letter-spacing: -0.88px;
padding: 0 20px;
margin-bottom: 15px;
@media (min-width: 768px) {
font-size: 64px;
line-height: 81px;
letter-spacing: -1.28px;
}
@media (min-width: 1025px) {
font-size: 72px;
letter-spacing: -1.44px;
padding-bottom: 8px; /* Fix for hanging descender on "g" in "tooling" */
}
}
h2 {
display: block;
width: fit-content;
font-family: Manrope, sans-serif;
font-size: 32px;
font-style: normal;
font-weight: 600;
line-height: 120%;
letter-spacing: -0.64px;
cursor: default;
text-wrap: balance;
padding: 0 20px;
@media (min-width: 768px) {
font-size: 44px;
letter-spacing: -0.88px;
}
}
h3 {
color: #a9a9a9;
text-align: center;
font-family: Inter, sans-serif;
font-size: 20px;
font-style: normal;
font-weight: 400;
line-height: 150%;
letter-spacing: -0.4px;
max-width: 500px;
text-wrap: balance;
cursor: default;
margin-bottom: 25px;
padding: 0 20px;
}
/* /////// */
/* Buttons */
/* /////// */
.btn {
display: flex;
padding: 10px 18px;
justify-content: center;
align-items: center;
gap: 8px;
border-radius: 8px;
color: #fff;
font-family: Inter, sans-serif;
font-size: 16px;
font-style: normal;
font-weight: 500;
line-height: 24px;
text-shadow: 0 0 2px rgba(0, 0, 0, 0.2);
transition: all 0.2s ease-in-out;
width: fit-content;
&:hover {
transform: translate3d(0, -2px, 0);
}
&.btn--primary {
position: relative;
background: radial-gradient(
141.42% 141.42% at 100% 0%,
rgba(255, 255, 255, 0.4) 0%,
rgba(255, 255, 255, 0) 100%
),
radial-gradient(
140.35% 140.35% at 100% 94.74%,
#bd34fe 0%,
rgba(189, 52, 254, 0) 100%
),
radial-gradient(
89.94% 89.94% at 18.42% 15.79%,
#41d1ff 0%,
rgba(65, 209, 255, 0) 100%
);
box-shadow: 0 1px 0 0 rgba(255, 255, 255, 0.75) inset;
&:hover {
background: radial-gradient(
141.42% 141.42% at 100% 0%,
rgba(255, 255, 255, 0.5) 0%,
rgba(255, 255, 255, 0) 100%
),
radial-gradient(
140.35% 140.35% at 100% 94.74%,
#bd34fe 0%,
rgba(189, 52, 254, 0) 100%
),
radial-gradient(
89.94% 89.94% at 18.42% 15.79%,
#41d1ff 0%,
rgba(65, 209, 255, 0) 100%
);
box-shadow: 0 1.5px 0 0 rgba(255, 255, 255, 0.8) inset;
}
}
&.btn--outline {
border: 1px solid rgba(255, 255, 255, 0.2);
&:hover {
border: 1px solid rgba(255, 255, 255, 0.4);
}
}
&.btn--rounded {
border-radius: 100px;
}
}
}

View File

@ -28,38 +28,6 @@
--vp-button-brand-active-bg: var(--vp-button-brand-bg);
}
/**
* Component: Home
* -------------------------------------------------------------------------- */
:root {
--vp-home-hero-name-color: transparent;
--vp-home-hero-name-background: -webkit-linear-gradient(
120deg,
#bd34fe 30%,
#41d1ff
);
--vp-home-hero-image-background-image: linear-gradient(
-45deg,
#bd34fe 50%,
#47caff 50%
);
--vp-home-hero-image-filter: blur(40px);
}
@media (min-width: 640px) {
:root {
--vp-home-hero-image-filter: blur(56px);
}
}
@media (min-width: 960px) {
:root {
--vp-home-hero-image-filter: blur(72px);
}
}
/**
* Component: Custom Block
* -------------------------------------------------------------------------- */

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@ -1,60 +1,47 @@
---
layout: home
title: Vite
titleTemplate: Next Generation Frontend Tooling
pageClass: landing dark
hero:
name: Vite
text: Next Generation Frontend Tooling
tagline: Get ready for a development environment that can finally catch up with you.
image:
src: /logo-with-shadow.png
alt: Vite
actions:
- theme: brand
text: Get Started
link: /guide/
- theme: alt
text: Why Vite?
link: /guide/why
- theme: alt
text: View on GitHub
link: https://github.com/vitejs/vite
- theme: brand
text: ⚡ ViteConf 24!
link: https://viteconf.org/?utm=vite-homepage
features:
- icon: 💡
title: Instant Server Start
details: On demand file serving over native ESM, no bundling required!
- icon: ⚡️
title: Lightning Fast HMR
details: Hot Module Replacement (HMR) that stays fast regardless of app size.
- icon: 🛠️
title: Rich Features
details: Out-of-the-box support for TypeScript, JSX, CSS and more.
- icon: 📦
title: Optimized Build
details: Pre-configured Rollup build with multi-page and library mode support.
- icon: 🔩
title: Universal Plugins
details: Rollup-superset plugin interface shared between dev and build.
- icon: 🔑
title: Fully Typed APIs
details: Flexible programmatic APIs with full TypeScript typing.
layout: home
aside: false
editLink: false
markdownStyles: false
---
<script setup>
import { onMounted } from 'vue'
onMounted(() => {
const urlParams = new URLSearchParams(window.location.search)
if (urlParams.get('uwu') != null) {
const img = document.querySelector('.VPHero .VPImage.image-src')
img.src = '/logo-uwu.png'
img.alt = 'Vite Kawaii Logo by @icarusgkx'
}
})
import Hero from '.vitepress/theme/components/landing/1. hero-section/HeroSection.vue'
import FeatureSection from './.vitepress/theme/components/landing/2. feature-section/FeatureSection.vue'
import FrameworksSection from './.vitepress/theme/components/landing/3. frameworks-section/FrameworksSection.vue'
import CommunitySection from './.vitepress/theme/components/landing/4. community-section/CommunitySection.vue'
import SponsorSection from './.vitepress/theme/components/landing/5. sponsor-section/SponsorSection.vue'
import GetStartedSection from '.vitepress/theme/components/landing/6. get-started-section/GetStartedSection.vue'
import FeatureInstantServerStart from './.vitepress/theme/components/landing/2. feature-section/FeatureInstantServerStart.vue'
import FeatureHMR from './.vitepress/theme/components/landing/2. feature-section/FeatureHMR.vue'
import FeatureRichFeatures from './.vitepress/theme/components/landing/2. feature-section/FeatureRichFeatures.vue'
import FeatureOptimizedBuild from './.vitepress/theme/components/landing/2. feature-section/FeatureOptimizedBuild.vue'
import FeatureFlexiblePlugins from './.vitepress/theme/components/landing/2. feature-section/FeatureFlexiblePlugins.vue'
import FeatureTypedAPI from './.vitepress/theme/components/landing/2. feature-section/FeatureTypedAPI.vue'
import FeatureSSRSupport from './.vitepress/theme/components/landing/2. feature-section/FeatureSSRSupport.vue'
import FeatureCI from './.vitepress/theme/components/landing/2. feature-section/FeatureCI.vue'
</script>
<div class="VPHome">
<Hero/>
<FeatureSection title="Redefining developer experience" description="Vite makes web development simple again" type="blue">
<FeatureInstantServerStart />
<FeatureHMR />
<FeatureRichFeatures />
<FeatureOptimizedBuild />
</FeatureSection>
<FeatureSection title="A shared foundation to build upon" type="pink" class="feature-section--flip">
<FeatureFlexiblePlugins />
<FeatureTypedAPI />
<FeatureSSRSupport />
<FeatureCI />
</FeatureSection>
<FrameworksSection />
<CommunitySection />
<SponsorSection />
<GetStartedSection />
</div>

View File

@ -1,5 +1,5 @@
# temporary, we'll flip this around some day
https://vite.dev/* https://vitejs.dev/:splat 302!
https://vitejs.dev/* https://vite.dev/:splat 301!
/guide/api-vite-runtime /guide/api-environment 302
/guide/api-vite-runtime.html /guide/api-environment 302

5
docs/public/github.svg Normal file
View File

@ -0,0 +1,5 @@
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<g id="github / 24 / Outline">
<path id="Vector" d="M10.0003 1.87207C8.02158 1.87215 6.1074 2.57633 4.60032 3.85861C3.09324 5.14089 2.0916 6.91759 1.77463 8.87081C1.45765 10.824 1.84603 12.8263 2.87026 14.5194C3.8945 16.2124 5.48775 17.4858 7.36495 18.1116C7.78161 18.1846 7.93786 17.9346 7.93786 17.7158C7.93786 17.5179 7.92744 16.8616 7.92744 16.1637C5.83368 16.5491 5.29201 15.6533 5.12535 15.1846C4.94041 14.7287 4.64724 14.3247 4.27118 14.0075C3.97951 13.8512 3.56285 13.4658 4.26076 13.4554C4.52725 13.4843 4.78284 13.5771 5.00587 13.7258C5.22891 13.8744 5.41282 14.0747 5.54201 14.3096C5.65599 14.5143 5.80925 14.6946 5.99301 14.84C6.17676 14.9854 6.38741 15.0931 6.61287 15.157C6.83834 15.2209 7.07419 15.2396 7.30691 15.2122C7.53964 15.1847 7.76466 15.1116 7.96908 14.9971C8.00516 14.5734 8.19396 14.1773 8.50035 13.8825C6.64618 13.6742 4.70868 12.9554 4.70868 9.76793C4.69697 8.93972 5.00259 8.13841 5.56285 7.52835C5.30808 6.80853 5.33789 6.01858 5.64618 5.32001C5.64618 5.32001 6.34407 5.10125 7.93785 6.17418C9.30142 5.79916 10.7409 5.79916 12.1045 6.17418C13.6982 5.09085 14.3962 5.32001 14.3962 5.32001C14.7045 6.01857 14.7343 6.80853 14.4795 7.52835C15.0415 8.13737 15.3473 8.93937 15.3337 9.76793C15.3337 12.9658 13.3857 13.6742 11.5316 13.8825C11.7305 14.0841 11.8836 14.3261 11.9807 14.5921C12.0778 14.8581 12.1164 15.1419 12.0941 15.4242C12.0941 16.5388 12.0837 17.4346 12.0837 17.7158C12.0837 17.9346 12.2399 18.195 12.6566 18.1117C14.5305 17.4807 16.1192 16.2044 17.139 14.5104C18.1589 12.8165 18.5436 10.8153 18.2244 8.86393C17.9052 6.91261 16.903 5.13821 15.3966 3.8575C13.8901 2.57678 11.9776 1.8731 10.0003 1.87207Z" fill="white"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.7 KiB

137
docs/public/heart.svg Normal file
View File

@ -0,0 +1,137 @@
<svg
width="58"
height="55"
viewBox="0 0 58 55"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<g filter="url(#filter0_f_693_14740)">
<path
d="M29 43.2447L26.39 40.9494C23.36 38.2714 20.855 35.9613 18.875 34.0191C16.895 32.0769 15.32 30.333 14.15 28.7874C12.98 27.2431 12.1628 25.8235 11.6984 24.5287C11.234 23.2338 11.0012 21.9096 11 20.5559C11 17.7897 11.945 15.4796 13.835 13.6257C15.725 11.7717 18.08 10.8447 20.9 10.8447C22.46 10.8447 23.945 11.1684 25.355 11.8158C26.765 12.4633 27.98 13.3755 29 14.5526C30.02 13.3755 31.235 12.4633 32.645 11.8158C34.055 11.1684 35.54 10.8447 37.1 10.8447C39.92 10.8447 42.275 11.7717 44.165 13.6257C46.055 15.4796 47 17.7897 47 20.5559C47 21.9096 46.7672 23.2338 46.3016 24.5287C45.836 25.8235 45.0188 27.2431 43.85 28.7874C42.68 30.333 41.105 32.0769 39.125 34.0191C37.145 35.9613 34.64 38.2714 31.61 40.9494L29 43.2447Z"
fill="url(#paint0_linear_693_14740)"
/>
<path
d="M29 43.2447L26.39 40.9494C23.36 38.2714 20.855 35.9613 18.875 34.0191C16.895 32.0769 15.32 30.333 14.15 28.7874C12.98 27.2431 12.1628 25.8235 11.6984 24.5287C11.234 23.2338 11.0012 21.9096 11 20.5559C11 17.7897 11.945 15.4796 13.835 13.6257C15.725 11.7717 18.08 10.8447 20.9 10.8447C22.46 10.8447 23.945 11.1684 25.355 11.8158C26.765 12.4633 27.98 13.3755 29 14.5526C30.02 13.3755 31.235 12.4633 32.645 11.8158C34.055 11.1684 35.54 10.8447 37.1 10.8447C39.92 10.8447 42.275 11.7717 44.165 13.6257C46.055 15.4796 47 17.7897 47 20.5559C47 21.9096 46.7672 23.2338 46.3016 24.5287C45.836 25.8235 45.0188 27.2431 43.85 28.7874C42.68 30.333 41.105 32.0769 39.125 34.0191C37.145 35.9613 34.64 38.2714 31.61 40.9494L29 43.2447Z"
fill="url(#paint1_radial_693_14740)"
fill-opacity="0.7"
/>
<path
d="M29 43.2447L26.39 40.9494C23.36 38.2714 20.855 35.9613 18.875 34.0191C16.895 32.0769 15.32 30.333 14.15 28.7874C12.98 27.2431 12.1628 25.8235 11.6984 24.5287C11.234 23.2338 11.0012 21.9096 11 20.5559C11 17.7897 11.945 15.4796 13.835 13.6257C15.725 11.7717 18.08 10.8447 20.9 10.8447C22.46 10.8447 23.945 11.1684 25.355 11.8158C26.765 12.4633 27.98 13.3755 29 14.5526C30.02 13.3755 31.235 12.4633 32.645 11.8158C34.055 11.1684 35.54 10.8447 37.1 10.8447C39.92 10.8447 42.275 11.7717 44.165 13.6257C46.055 15.4796 47 17.7897 47 20.5559C47 21.9096 46.7672 23.2338 46.3016 24.5287C45.836 25.8235 45.0188 27.2431 43.85 28.7874C42.68 30.333 41.105 32.0769 39.125 34.0191C37.145 35.9613 34.64 38.2714 31.61 40.9494L29 43.2447Z"
fill="url(#paint2_radial_693_14740)"
fill-opacity="0.7"
/>
</g>
<path
d="M29.001 42.945L26.536 40.735C23.6743 38.1567 21.3085 35.9325 19.4385 34.0625C17.5685 32.1925 16.081 30.5135 14.976 29.0254C13.871 27.5385 13.0992 26.1717 12.6606 24.925C12.222 23.6783 12.0021 22.4033 12.001 21.1C12.001 18.4367 12.8935 16.2125 14.6785 14.4275C16.4635 12.6425 18.6876 11.75 21.351 11.75C22.8243 11.75 24.2268 12.0617 25.5585 12.685C26.8901 13.3083 28.0376 14.1867 29.001 15.32C29.9643 14.1867 31.1118 13.3083 32.4435 12.685C33.7751 12.0617 35.1776 11.75 36.651 11.75C39.3143 11.75 41.5385 12.6425 43.3235 14.4275C45.1085 16.2125 46.001 18.4367 46.001 21.1C46.001 22.4033 45.7811 23.6783 45.3414 24.925C44.9016 26.1717 44.1298 27.5385 43.026 29.0254C41.921 30.5135 40.4335 32.1925 38.5635 34.0625C36.6935 35.9325 34.3276 38.1567 31.466 40.735L29.001 42.945Z"
fill="#141215"
/>
<path
d="M29.001 42.945L26.536 40.735C23.6743 38.1567 21.3085 35.9325 19.4385 34.0625C17.5685 32.1925 16.081 30.5135 14.976 29.0254C13.871 27.5385 13.0992 26.1717 12.6606 24.925C12.222 23.6783 12.0021 22.4033 12.001 21.1C12.001 18.4367 12.8935 16.2125 14.6785 14.4275C16.4635 12.6425 18.6876 11.75 21.351 11.75C22.8243 11.75 24.2268 12.0617 25.5585 12.685C26.8901 13.3083 28.0376 14.1867 29.001 15.32C29.9643 14.1867 31.1118 13.3083 32.4435 12.685C33.7751 12.0617 35.1776 11.75 36.651 11.75C39.3143 11.75 41.5385 12.6425 43.3235 14.4275C45.1085 16.2125 46.001 18.4367 46.001 21.1C46.001 22.4033 45.7811 23.6783 45.3414 24.925C44.9016 26.1717 44.1298 27.5385 43.026 29.0254C41.921 30.5135 40.4335 32.1925 38.5635 34.0625C36.6935 35.9325 34.3276 38.1567 31.466 40.735L29.001 42.945Z"
fill="url(#paint3_linear_693_14740)"
/>
<path
d="M29.001 42.945L26.536 40.735C23.6743 38.1567 21.3085 35.9325 19.4385 34.0625C17.5685 32.1925 16.081 30.5135 14.976 29.0254C13.871 27.5385 13.0992 26.1717 12.6606 24.925C12.222 23.6783 12.0021 22.4033 12.001 21.1C12.001 18.4367 12.8935 16.2125 14.6785 14.4275C16.4635 12.6425 18.6876 11.75 21.351 11.75C22.8243 11.75 24.2268 12.0617 25.5585 12.685C26.8901 13.3083 28.0376 14.1867 29.001 15.32C29.9643 14.1867 31.1118 13.3083 32.4435 12.685C33.7751 12.0617 35.1776 11.75 36.651 11.75C39.3143 11.75 41.5385 12.6425 43.3235 14.4275C45.1085 16.2125 46.001 18.4367 46.001 21.1C46.001 22.4033 45.7811 23.6783 45.3414 24.925C44.9016 26.1717 44.1298 27.5385 43.026 29.0254C41.921 30.5135 40.4335 32.1925 38.5635 34.0625C36.6935 35.9325 34.3276 38.1567 31.466 40.735L29.001 42.945Z"
fill="url(#paint4_radial_693_14740)"
fill-opacity="0.7"
/>
<path
d="M29.001 42.945L26.536 40.735C23.6743 38.1567 21.3085 35.9325 19.4385 34.0625C17.5685 32.1925 16.081 30.5135 14.976 29.0254C13.871 27.5385 13.0992 26.1717 12.6606 24.925C12.222 23.6783 12.0021 22.4033 12.001 21.1C12.001 18.4367 12.8935 16.2125 14.6785 14.4275C16.4635 12.6425 18.6876 11.75 21.351 11.75C22.8243 11.75 24.2268 12.0617 25.5585 12.685C26.8901 13.3083 28.0376 14.1867 29.001 15.32C29.9643 14.1867 31.1118 13.3083 32.4435 12.685C33.7751 12.0617 35.1776 11.75 36.651 11.75C39.3143 11.75 41.5385 12.6425 43.3235 14.4275C45.1085 16.2125 46.001 18.4367 46.001 21.1C46.001 22.4033 45.7811 23.6783 45.3414 24.925C44.9016 26.1717 44.1298 27.5385 43.026 29.0254C41.921 30.5135 40.4335 32.1925 38.5635 34.0625C36.6935 35.9325 34.3276 38.1567 31.466 40.735L29.001 42.945Z"
fill="url(#paint5_radial_693_14740)"
fill-opacity="0.7"
/>
<path
d="M15.4574 28.6676L15.4573 28.6675C14.375 27.2111 13.6387 25.8979 13.2263 24.7258C12.8099 23.5421 12.6018 22.3343 12.6007 21.0997C12.6008 18.5859 13.4368 16.5174 15.1025 14.8517C16.7683 13.1859 18.8368 12.3499 21.3507 12.3499C22.7363 12.3499 24.052 12.6424 25.3039 13.2284C26.5567 13.8148 27.6353 14.64 28.5436 15.7085L29.0007 16.2464L29.4579 15.7085C30.3662 14.64 31.4448 13.8148 32.6976 13.2284C33.9495 12.6424 35.2651 12.3499 36.6507 12.3499C39.1647 12.3499 41.2332 13.1859 42.899 14.8517C44.5647 16.5175 45.4007 18.586 45.4007 21.0999C45.4007 22.3343 45.1927 23.5419 44.7753 24.7254C44.3617 25.8978 43.6253 27.2112 42.544 28.6676C41.4622 30.1245 39.9962 31.781 38.139 33.6382C36.2789 35.4983 33.9213 37.7149 31.0643 40.289C31.0642 40.2891 31.0642 40.2891 31.0641 40.2892L29.0007 42.1391L26.9374 40.2892C26.9372 40.2891 26.9371 40.2889 26.937 40.2888C24.0801 37.7148 21.7226 35.4982 19.8625 33.6382C18.0053 31.781 16.5393 30.1245 15.4574 28.6676Z"
stroke="white"
stroke-opacity="0.3"
stroke-width="1.2"
/>
<defs>
<filter
id="filter0_f_693_14740"
x="0.2"
y="0.0447264"
width="57.6"
height="54"
filterUnits="userSpaceOnUse"
color-interpolation-filters="sRGB"
>
<feFlood flood-opacity="0" result="BackgroundImageFix" />
<feBlend
mode="normal"
in="SourceGraphic"
in2="BackgroundImageFix"
result="shape"
/>
<feGaussianBlur
stdDeviation="5.4"
result="effect1_foregroundBlur_693_14740"
/>
</filter>
<linearGradient
id="paint0_linear_693_14740"
x1="29"
y1="10.8447"
x2="29"
y2="43.2447"
gradientUnits="userSpaceOnUse"
>
<stop stop-color="#BD34FE" />
<stop offset="1" stop-color="#AD00FF" stop-opacity="0.24" />
</linearGradient>
<radialGradient
id="paint1_radial_693_14740"
cx="0"
cy="0"
r="1"
gradientUnits="userSpaceOnUse"
gradientTransform="translate(40.4345 13.6435) rotate(115.368) scale(29.6563 32.7229)"
>
<stop stop-color="#FF9CF5" />
<stop offset="1" stop-color="#FFBFF9" stop-opacity="0" />
</radialGradient>
<radialGradient
id="paint2_radial_693_14740"
cx="0"
cy="0"
r="1"
gradientUnits="userSpaceOnUse"
gradientTransform="translate(11.2109 19.2521) rotate(23.4546) scale(36.0107 38.7396)"
>
<stop stop-color="white" />
<stop offset="1" stop-color="white" stop-opacity="0" />
</radialGradient>
<linearGradient
id="paint3_linear_693_14740"
x1="29.001"
y1="11.75"
x2="29.001"
y2="42.945"
gradientUnits="userSpaceOnUse"
>
<stop stop-color="#BD34FE" />
<stop offset="1" stop-color="#AD00FF" stop-opacity="0.24" />
</linearGradient>
<radialGradient
id="paint4_radial_693_14740"
cx="0"
cy="0"
r="1"
gradientUnits="userSpaceOnUse"
gradientTransform="translate(39.8002 14.4447) rotate(114.944) scale(28.4542 31.0127)"
>
<stop stop-color="#FF9CF5" />
<stop offset="1" stop-color="#FFBFF9" stop-opacity="0" />
</radialGradient>
<radialGradient
id="paint5_radial_693_14740"
cx="0"
cy="0"
r="1"
gradientUnits="userSpaceOnUse"
gradientTransform="translate(12.2002 19.8447) rotate(23.8602) scale(34.1157 37.1833)"
>
<stop stop-color="white" />
<stop offset="1" stop-color="white" stop-opacity="0" />
</radialGradient>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 9.3 KiB

46
docs/public/logo-home.svg Normal file
View File

@ -0,0 +1,46 @@
<svg width="68" height="68" viewBox="0 0 68 68" fill="none" xmlns="http://www.w3.org/2000/svg">
<g opacity="1" clip-path="url(#clip0_693_14578)">
<g style="mix-blend-mode:luminosity" opacity="0.5" filter="url(#filter0_i_693_14578)">
<path d="M65.7194 10.0473L35.6655 64.587C35.045 65.7131 33.4508 65.7197 32.821 64.5991L2.17117 10.0525C1.48502 8.83141 2.51394 7.35228 3.87747 7.59962L33.9635 13.0572C34.1555 13.092 34.3519 13.0917 34.5439 13.0562L64.0008 7.60744C65.3597 7.35608 66.3935 8.82375 65.7194 10.0473Z" fill="url(#paint0_linear_693_14578)"/>
</g>
<g style="mix-blend-mode:luminosity" filter="url(#filter1_bd_693_14578)">
<path d="M48.295 0.441298L26.0542 4.86401C25.6887 4.9367 25.418 5.25109 25.396 5.62839L24.0278 29.078C23.9957 29.6303 24.4955 30.059 25.0267 29.9346L31.2188 28.4844C31.7982 28.3488 32.3217 28.8666 32.2026 29.4579L30.3629 38.6003C30.2391 39.2156 30.8083 39.7417 31.4004 39.5592L35.225 38.38C35.8179 38.1973 36.3876 38.7249 36.2622 39.3407L33.3386 53.7014C33.1557 54.5997 34.333 55.0895 34.824 54.3193L35.152 53.805L53.275 17.1002C53.5785 16.4856 53.0552 15.7848 52.39 15.9151L46.0163 17.1635C45.4173 17.2807 44.9077 16.7146 45.0767 16.1199L49.2368 1.48437C49.406 0.888652 48.8946 0.322077 48.295 0.441298Z" fill="url(#paint1_linear_693_14578)" fill-opacity="0.6" shape-rendering="crispEdges"/>
</g>
</g>
<defs>
<filter id="filter0_i_693_14578" x="1.95264" y="7.57227" width="63.9785" height="60.1716" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape"/>
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
<feOffset dy="2.30833"/>
<feGaussianBlur stdDeviation="5.77083"/>
<feComposite in2="hardAlpha" operator="arithmetic" k2="-1" k3="1"/>
<feColorMatrix type="matrix" values="0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0.75 0"/>
<feBlend mode="normal" in2="shape" result="effect1_innerShadow_693_14578"/>
</filter>
<filter id="filter1_bd_693_14578" x="19.4097" y="-4.19137" width="38.5702" height="63.5097" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
<feGaussianBlur in="BackgroundImageFix" stdDeviation="2.30833"/>
<feComposite in2="SourceAlpha" operator="in" result="effect1_backgroundBlur_693_14578"/>
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
<feOffset dy="1.15417"/>
<feGaussianBlur stdDeviation="1.15417"/>
<feComposite in2="hardAlpha" operator="out"/>
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.25 0"/>
<feBlend mode="normal" in2="effect1_backgroundBlur_693_14578" result="effect2_dropShadow_693_14578"/>
<feBlend mode="normal" in="SourceGraphic" in2="effect2_dropShadow_693_14578" result="shape"/>
</filter>
<linearGradient id="paint0_linear_693_14578" x1="1.42283" y1="5.65045" x2="39.5455" y2="56.6664" gradientUnits="userSpaceOnUse">
<stop stop-color="#41D1FF"/>
<stop offset="1" stop-color="#BD34FE"/>
</linearGradient>
<linearGradient id="paint1_linear_693_14578" x1="32.2366" y1="1.64206" x2="39.201" y2="48.718" gradientUnits="userSpaceOnUse">
<stop stop-color="#FFEA83"/>
<stop offset="0.0833333" stop-color="#FFDD35"/>
<stop offset="1" stop-color="#FFA800"/>
</linearGradient>
<clipPath id="clip0_693_14578">
<rect width="66.9687" height="66.9687" fill="white" transform="translate(0.442871 0.180176)"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 3.7 KiB

BIN
docs/public/noise.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

View File

@ -63,6 +63,7 @@
"eslint-plugin-regexp": "^2.6.0",
"execa": "^9.4.0",
"globals": "^15.9.0",
"gsap": "^3.12.4",
"lint-staged": "^15.2.10",
"picocolors": "^1.1.0",
"playwright-chromium": "^1.47.2",

View File

@ -94,6 +94,9 @@ importers:
globals:
specifier: ^15.9.0
version: 15.9.0
gsap:
specifier: ^3.12.4
version: 3.12.5
lint-staged:
specifier: ^15.2.10
version: 15.2.10
@ -5000,6 +5003,9 @@ packages:
graphemer@1.4.0:
resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==}
gsap@3.12.5:
resolution: {integrity: sha512-srBfnk4n+Oe/ZnMIOXt3gT605BX9x5+rh/prT2F1SsNJsU1XuMiP0E2aptW481OnonOGACZWBqseH5Z7csHxhQ==}
handlebars@4.7.8:
resolution: {integrity: sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ==}
engines: {node: '>=0.4.7'}
@ -10769,6 +10775,8 @@ snapshots:
graphemer@1.4.0: {}
gsap@3.12.5: {}
handlebars@4.7.8:
dependencies:
minimist: 1.2.8