mirror of
https://github.com/DavidHDev/vue-bits.git
synced 2026-03-07 06:29:30 -07:00
Updated Landing Page
This commit is contained in:
16
src/assets/common/landing-blur.svg
Normal file
16
src/assets/common/landing-blur.svg
Normal file
@@ -0,0 +1,16 @@
|
||||
<svg width="1001" height="1001" viewBox="0 0 1001 1001" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g filter="url(#filter0_f_1370_60)">
|
||||
<rect x="200.957" y="200.171" width="600" height="600" rx="300" fill="url(#paint0_radial_1370_60)"/>
|
||||
</g>
|
||||
<defs>
|
||||
<filter id="filter0_f_1370_60" x="0.957031" y="0.171387" width="1000" height="1000" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||
<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape"/>
|
||||
<feGaussianBlur stdDeviation="100" result="effect1_foregroundBlur_1370_60"/>
|
||||
</filter>
|
||||
<radialGradient id="paint0_radial_1370_60" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="translate(500.957 500.171) rotate(90) scale(619.368)">
|
||||
<stop stop-color="#060010"/>
|
||||
<stop offset="1" stop-color="#060010" stop-opacity="0"/>
|
||||
</radialGradient>
|
||||
</defs>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 918 B |
@@ -113,6 +113,9 @@
|
||||
backdrop-filter: blur(25px);
|
||||
-webkit-backdrop-filter: blur(25px);
|
||||
color: #fff;
|
||||
border-top: 1px solid rgba(255, 255, 255, 0.07);
|
||||
border-bottom: 1px solid rgba(255, 255, 255, 0.07);
|
||||
border-right: 1px solid rgba(255, 255, 255, 0.07);
|
||||
border: none;
|
||||
border-radius: 50px;
|
||||
cursor: pointer;
|
||||
@@ -126,7 +129,7 @@
|
||||
.cta-button span {
|
||||
background-color: #0b0b0b;
|
||||
margin-left: 1em;
|
||||
margin-right: calc(1em - 8px);
|
||||
margin-right: calc(1em - 10px);
|
||||
padding-top: 0.1em;
|
||||
height: 45px;
|
||||
border-radius: 50px;
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
.features-section {
|
||||
position: relative;
|
||||
margin-top: 12em;
|
||||
padding: 8rem 2rem 4em;
|
||||
padding: 0 2rem 4em;
|
||||
padding-bottom: 0 !important;
|
||||
z-index: 22;
|
||||
transform: translateY(-4rem);
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
@@ -12,59 +12,22 @@
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.features-header {
|
||||
text-align: center;
|
||||
margin-bottom: 4rem;
|
||||
}
|
||||
|
||||
.features-title {
|
||||
font-size: 4rem;
|
||||
font-weight: 600;
|
||||
letter-spacing: -2px;
|
||||
color: #fff;
|
||||
margin-bottom: 0.2rem;
|
||||
background: linear-gradient(135deg, #fff 0%, #60fa89 20%, #55f788 40%, #00ff62 60%, #55f799 80%, #fff 100%);
|
||||
background-size: 200% 200%;
|
||||
-webkit-background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
background-clip: text;
|
||||
text-align: center;
|
||||
animation: gradientShift 4s ease-in-out infinite;
|
||||
display: inline-block;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.features-title * {
|
||||
background: inherit;
|
||||
background-size: inherit;
|
||||
-webkit-background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
background-clip: text;
|
||||
animation: inherit;
|
||||
}
|
||||
|
||||
@keyframes gradientShift {
|
||||
0%,
|
||||
100% {
|
||||
background-position: 0% 50%;
|
||||
}
|
||||
|
||||
50% {
|
||||
background-position: 100% 50%;
|
||||
@media (max-width: 1024px) {
|
||||
.features-section {
|
||||
position: relative;
|
||||
margin-top: 4rem;
|
||||
padding: 0 2rem 4em;
|
||||
padding-bottom: 0 !important;
|
||||
z-index: 22;
|
||||
transform: translateY(0);
|
||||
user-select: none;
|
||||
}
|
||||
}
|
||||
|
||||
.features-subtitle {
|
||||
font-size: 1.2rem;
|
||||
color: #fff;
|
||||
text-shadow:
|
||||
0 0 2px rgba(255, 255, 255, 0.1),
|
||||
0 0 4px rgba(255, 255, 255, 0.3),
|
||||
0 0 8px rgba(255, 255, 255, 0.4),
|
||||
0 0 136px rgba(0, 255, 98, 0.9);
|
||||
font-weight: 400;
|
||||
margin: 0;
|
||||
text-align: center;
|
||||
@media (max-width: 768px) {
|
||||
}
|
||||
|
||||
@media (max-width: 480px) {
|
||||
}
|
||||
|
||||
.bento-grid {
|
||||
@@ -367,9 +330,8 @@
|
||||
|
||||
@media (max-width: 479px) {
|
||||
.features-section {
|
||||
padding: 4rem 1rem 2rem;
|
||||
padding: 0 1rem 2rem;
|
||||
padding-bottom: 0;
|
||||
margin-top: 4em;
|
||||
}
|
||||
|
||||
.features-title {
|
||||
@@ -449,8 +411,7 @@
|
||||
|
||||
@media (min-width: 768px) {
|
||||
.features-section {
|
||||
padding: 6rem 2rem 3rem;
|
||||
margin-top: 6em;
|
||||
padding: 0 2rem 3rem;
|
||||
}
|
||||
|
||||
.feature-card {
|
||||
@@ -496,9 +457,8 @@
|
||||
|
||||
@media (min-width: 50rem) {
|
||||
.features-section {
|
||||
padding: 8rem 2rem 4rem;
|
||||
padding: 0 2rem 4rem;
|
||||
padding-bottom: 0;
|
||||
margin-top: 8em;
|
||||
}
|
||||
|
||||
.bento-grid {
|
||||
@@ -543,8 +503,7 @@
|
||||
|
||||
@media (max-height: 500px) and (orientation: landscape) {
|
||||
.features-section {
|
||||
margin-top: 2em;
|
||||
padding: 2rem 1rem;
|
||||
padding: 0 2rem 1rem;
|
||||
}
|
||||
|
||||
.feature-card {
|
||||
|
||||
@@ -1,11 +1,6 @@
|
||||
<template>
|
||||
<div class="features-section">
|
||||
<div class="features-container">
|
||||
<div class="features-header">
|
||||
<h3 class="features-title">Zero cost, all the cool.</h3>
|
||||
<p class="features-subtitle">Everything you need to add flair to your websites</p>
|
||||
</div>
|
||||
|
||||
<div class="bento-grid" ref="gridRef">
|
||||
<ParticleCard class="feature-card card1" :disable-animations="isMobile">
|
||||
<div class="messages-gif-wrapper">
|
||||
@@ -29,7 +24,7 @@
|
||||
<CountUp v-else :to="80" />
|
||||
+
|
||||
</h2>
|
||||
<h3>Curated Components</h3>
|
||||
<h3>Creative Components</h3>
|
||||
<p>Growing weekly & only getting better</p>
|
||||
</ParticleCard>
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
.landing-footer {
|
||||
position: relative;
|
||||
margin-top: 8rem;
|
||||
margin-top: 4rem;
|
||||
padding: 2.4rem;
|
||||
border-top: 1px solid rgba(149, 184, 148, 0.1);
|
||||
background: linear-gradient(to bottom, transparent, #0b0b0b);
|
||||
|
||||
@@ -1,10 +1,38 @@
|
||||
<template>
|
||||
<div class="landing-content">
|
||||
<img
|
||||
:src="landingBlur"
|
||||
alt=""
|
||||
aria-hidden="true"
|
||||
class="landing-gradient-blur"
|
||||
draggable="false"
|
||||
:style="{ zIndex: 5 }"
|
||||
/>
|
||||
|
||||
<img
|
||||
:src="landingBlur"
|
||||
alt=""
|
||||
aria-hidden="true"
|
||||
class="landing-gradient-blur"
|
||||
draggable="false"
|
||||
:style="{ zIndex: 5 }"
|
||||
/>
|
||||
|
||||
<div class="hero-main-content">
|
||||
<FadeContent class="hero-tag-fade" blur>
|
||||
<router-link to="/backgrounds/gradient-blinds" class="hero-new-badge-container">
|
||||
<span class="hero-new-badge">New 🎉</span>
|
||||
<div class="hero-new-badge-text">
|
||||
<span>Gradient Blinds</span>
|
||||
<GoArrowRight />
|
||||
</div>
|
||||
</router-link>
|
||||
</FadeContent>
|
||||
|
||||
<h1 class="landing-title">
|
||||
<ResponsiveSplitText
|
||||
:is-mobile="isMobile"
|
||||
text="Animated Vue components"
|
||||
text="Vue Components"
|
||||
class-name="hero-split"
|
||||
split-type="chars"
|
||||
:delay="30"
|
||||
@@ -16,7 +44,7 @@
|
||||
|
||||
<ResponsiveSplitText
|
||||
:is-mobile="isMobile"
|
||||
text="for creative developers"
|
||||
text="For Creative Developers"
|
||||
class-name="hero-split"
|
||||
split-type="chars"
|
||||
:delay="30"
|
||||
@@ -29,9 +57,9 @@
|
||||
:is-mobile="isMobile"
|
||||
class-name="landing-subtitle"
|
||||
split-type="words"
|
||||
:delay="10"
|
||||
:delay="25"
|
||||
:duration="1"
|
||||
text="Eighty-plus snippets, ready to be dropped into your Vue projects"
|
||||
text="Highly customizable animated components that make your React projects truly stand out"
|
||||
/>
|
||||
|
||||
<router-link to="/text-animations/split-text" class="landing-button">
|
||||
@@ -44,45 +72,14 @@
|
||||
</div>
|
||||
</router-link>
|
||||
</div>
|
||||
|
||||
<div v-if="!isMobile" class="hero-cards-container">
|
||||
<div class="hero-card hero-card-1" @click="openUrl('https://vue-bits.dev/backgrounds/dot-grid')">
|
||||
<div class="w-full h-full relative hero-dot-grid">
|
||||
<DotGrid
|
||||
base-color="#ffffff"
|
||||
active-color="rgba(138, 43, 226, 0.9)"
|
||||
:dot-size="8"
|
||||
:gap="16"
|
||||
:proximity="50"
|
||||
/>
|
||||
|
||||
<div class="placeholder-card"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="hero-cards-row">
|
||||
<div class="hero-card hero-card-2" @click="openUrl('https://vue-bits.dev/backgrounds/letter-glitch')">
|
||||
<LetterGlitch class-name="hero-glitch" :glitch-colors="['#ffffff', '#999999', '#333333']" />
|
||||
|
||||
<div class="placeholder-card"></div>
|
||||
</div>
|
||||
|
||||
<div class="hero-card hero-card-3" @click="openUrl('https://vue-bits.dev/backgrounds/squares')">
|
||||
<Squares border-color="#fff" :speed="0.2" direction="diagonal" hover-fill-color="#fff" />
|
||||
|
||||
<div class="placeholder-card"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, onMounted, onUnmounted, h, defineComponent } from 'vue';
|
||||
import DotGrid from '@/content/Backgrounds/DotGrid/DotGrid.vue';
|
||||
import SplitText from '@/content/TextAnimations/SplitText/SplitText.vue';
|
||||
import LetterGlitch from '@/content/Backgrounds/LetterGlitch/LetterGlitch.vue';
|
||||
import Squares from '@/content/Backgrounds/Squares/Squares.vue';
|
||||
import { defineComponent, h, onMounted, onUnmounted, ref } from 'vue';
|
||||
import landingBlur from '../../../assets/common/landing-blur.svg';
|
||||
import FadeContent from '../../../content/Animations/FadeContent/FadeContent.vue';
|
||||
|
||||
const ResponsiveSplitText = defineComponent({
|
||||
props: {
|
||||
@@ -122,10 +119,6 @@ const ResponsiveSplitText = defineComponent({
|
||||
}
|
||||
});
|
||||
|
||||
const openUrl = (url: string) => {
|
||||
window.open(url);
|
||||
};
|
||||
|
||||
const isMobile = ref(false);
|
||||
|
||||
const checkIsMobile = () => {
|
||||
|
||||
392
src/components/landing/PlasmaWave/PlasmaWaveV2.vue
Normal file
392
src/components/landing/PlasmaWave/PlasmaWaveV2.vue
Normal file
@@ -0,0 +1,392 @@
|
||||
<script setup lang="ts">
|
||||
import { Camera, Geometry, Mesh, Program, Renderer, Transform } from 'ogl';
|
||||
import { onBeforeUnmount, onMounted, onUnmounted, ref, watch } from 'vue';
|
||||
|
||||
const vertex = /* glsl */ `
|
||||
attribute vec2 position;
|
||||
varying vec2 vUv;
|
||||
void main() {
|
||||
vUv = position * 0.5 + 0.5;
|
||||
gl_Position = vec4(position, 0.0, 1.0);
|
||||
}
|
||||
`;
|
||||
|
||||
const fragment = /* glsl */ `
|
||||
precision mediump float;
|
||||
uniform float iTime;
|
||||
uniform vec2 iResolution;
|
||||
uniform vec2 uOffset;
|
||||
uniform float uRotation;
|
||||
uniform float focalLength;
|
||||
uniform float speed1;
|
||||
uniform float speed2;
|
||||
uniform float dir2;
|
||||
uniform float bend1;
|
||||
uniform float bend2;
|
||||
uniform float bendAdj1;
|
||||
uniform float bendAdj2;
|
||||
uniform float uOpacity;
|
||||
|
||||
const float lt = 0.3;
|
||||
const float pi = 3.141592653589793;
|
||||
const float pi2 = pi * 2.0;
|
||||
const float pi_2 = pi * 0.5;
|
||||
#define MAX_STEPS 15
|
||||
|
||||
void mainImage(out vec4 C, in vec2 U) {
|
||||
float t = iTime * pi;
|
||||
float s = 1.0;
|
||||
float d = 0.0;
|
||||
vec2 R = iResolution;
|
||||
vec2 m = vec2(0.0);
|
||||
|
||||
vec3 o = vec3(0.0, 0.0, -7.0);
|
||||
vec3 u = normalize(vec3((U - 0.5 * R) / R.y, focalLength));
|
||||
vec3 k = vec3(0.0);
|
||||
vec3 p;
|
||||
|
||||
float t1 = t * 0.7;
|
||||
float t2 = t * 0.9;
|
||||
float tSpeed1 = t * speed1;
|
||||
float tSpeed2 = t * speed2 * dir2;
|
||||
|
||||
for (int step = 0; step < MAX_STEPS; ++step) {
|
||||
p = o + u * d;
|
||||
p.x -= 15.0;
|
||||
|
||||
float px = p.x;
|
||||
float wob1 = bend1 + bendAdj1 + sin(t1 + px * 0.8) * 0.1;
|
||||
float wob2 = bend2 + bendAdj2 + cos(t2 + px * 1.1) * 0.1;
|
||||
|
||||
float px2 = px + pi_2;
|
||||
vec2 baseOffset = vec2(px, px2);
|
||||
vec2 sinOffset = sin(baseOffset + tSpeed1) * wob1;
|
||||
vec2 cosOffset = cos(baseOffset + tSpeed2) * wob2;
|
||||
|
||||
vec2 yz = p.yz;
|
||||
float wSin = length(yz - sinOffset) - lt;
|
||||
float wCos = length(yz - cosOffset) - lt;
|
||||
|
||||
k.x = max(px + lt, wSin);
|
||||
k.y = max(px + lt, wCos);
|
||||
|
||||
float current = min(k.x, k.y);
|
||||
s = min(s, current);
|
||||
if (s < 0.001 || d > 400.0) break;
|
||||
d += s * 0.7;
|
||||
}
|
||||
|
||||
vec3 c = max(cos(d * pi2) - s * sqrt(d) - k, 0.0);
|
||||
c.gb += 0.1;
|
||||
|
||||
vec3 vueGreen = vec3(0.259, 0.722, 0.514); // #42B883
|
||||
vec3 vueDark = vec3(0.208, 0.286, 0.369); // #35495e
|
||||
|
||||
vec3 finalColor = vec3(0.0);
|
||||
if (k.x < k.y) {
|
||||
finalColor = vueGreen * c.x;
|
||||
} else {
|
||||
finalColor = vueDark * c.y;
|
||||
}
|
||||
|
||||
float intensity = max(finalColor.r, max(finalColor.g, finalColor.b));
|
||||
if (intensity < 0.15) discard;
|
||||
finalColor = finalColor * 0.4 + finalColor.brg * 0.6 + finalColor * finalColor;
|
||||
C = vec4(clamp(finalColor, 0.0, 1.0), uOpacity);
|
||||
}
|
||||
|
||||
void main() {
|
||||
vec2 coord = gl_FragCoord.xy + uOffset;
|
||||
coord -= 0.5 * iResolution;
|
||||
float c = cos(uRotation), s = sin(uRotation);
|
||||
coord = mat2(c, -s, s, c) * coord;
|
||||
coord += 0.5 * iResolution;
|
||||
|
||||
vec4 color;
|
||||
mainImage(color, coord);
|
||||
gl_FragColor = color;
|
||||
}
|
||||
`;
|
||||
|
||||
interface AnimationConfig {
|
||||
xOffset: number;
|
||||
yOffset: number;
|
||||
rotationDeg: number;
|
||||
focalLength: number;
|
||||
speed1: number;
|
||||
speed2: number;
|
||||
dir2: number;
|
||||
bend1: number;
|
||||
bend2: number;
|
||||
fadeInDuration: number;
|
||||
}
|
||||
|
||||
const props = withDefaults(defineProps<Partial<AnimationConfig>>(), {
|
||||
xOffset: 0,
|
||||
yOffset: 0,
|
||||
rotationDeg: 0,
|
||||
focalLength: 1,
|
||||
speed1: 0.1,
|
||||
speed2: 0.1,
|
||||
dir2: 1.0,
|
||||
bend1: 0.9,
|
||||
bend2: 0.6,
|
||||
fadeInDuration: 2000
|
||||
});
|
||||
|
||||
const isMobile = ref(false);
|
||||
const isVisible = ref(true);
|
||||
const containerRef = ref<HTMLElement | null>(null);
|
||||
const uniformOffset = ref(new Float32Array([props.xOffset, props.yOffset]));
|
||||
const uniformResolution = ref(new Float32Array([1, 1]));
|
||||
const rendererRef = ref<Renderer | null>(null);
|
||||
const fadeStartTime = ref<number | null>(null);
|
||||
const lastTimeRef = ref(0);
|
||||
const pausedTimeRef = ref(0);
|
||||
|
||||
const propsRef = ref({
|
||||
xOffset: props.xOffset,
|
||||
yOffset: props.yOffset,
|
||||
rotationDeg: props.rotationDeg,
|
||||
focalLength: props.focalLength,
|
||||
speed1: props.speed1,
|
||||
speed2: props.speed2,
|
||||
dir2: props.dir2,
|
||||
bend1: props.bend1,
|
||||
bend2: props.bend2,
|
||||
fadeInDuration: props.fadeInDuration
|
||||
});
|
||||
propsRef.value = {
|
||||
xOffset: props.xOffset,
|
||||
yOffset: props.yOffset,
|
||||
rotationDeg: props.rotationDeg,
|
||||
focalLength: props.focalLength,
|
||||
speed1: props.speed1,
|
||||
speed2: props.speed2,
|
||||
dir2: props.dir2,
|
||||
bend1: props.bend1,
|
||||
bend2: props.bend2,
|
||||
fadeInDuration: props.fadeInDuration
|
||||
};
|
||||
|
||||
let removeResizeListener: (() => void) | null = null;
|
||||
let removeObserver: (() => void) | null = null;
|
||||
|
||||
const handleResize = () => {
|
||||
const checkIsMobile = () => {
|
||||
isMobile.value = window.innerWidth <= 768;
|
||||
};
|
||||
|
||||
checkIsMobile();
|
||||
window.addEventListener('resize', checkIsMobile);
|
||||
|
||||
removeResizeListener = () => {
|
||||
window.removeEventListener('resize', checkIsMobile);
|
||||
};
|
||||
};
|
||||
|
||||
const handleObserver = () => {
|
||||
if (!containerRef.value || isMobile) return;
|
||||
|
||||
const observer = new IntersectionObserver(
|
||||
([entry]) => {
|
||||
isVisible.value = entry.isIntersecting;
|
||||
},
|
||||
{
|
||||
rootMargin: '50px',
|
||||
threshold: 0.1
|
||||
}
|
||||
);
|
||||
|
||||
observer.observe(containerRef.value);
|
||||
|
||||
removeObserver = () => observer.disconnect();
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
handleResize();
|
||||
handleObserver();
|
||||
});
|
||||
|
||||
onUnmounted(() => {
|
||||
removeResizeListener?.();
|
||||
removeObserver?.();
|
||||
});
|
||||
|
||||
watch(
|
||||
isMobile,
|
||||
() => {
|
||||
handleObserver();
|
||||
},
|
||||
{
|
||||
deep: true
|
||||
}
|
||||
);
|
||||
|
||||
let cleanup: (() => void) | null = null;
|
||||
|
||||
const setup = () => {
|
||||
if (isMobile.value) {
|
||||
return;
|
||||
}
|
||||
|
||||
const renderer = new Renderer({
|
||||
alpha: true,
|
||||
dpr: Math.min(window.devicePixelRatio, 1),
|
||||
antialias: false,
|
||||
depth: false,
|
||||
stencil: false,
|
||||
powerPreference: 'high-performance'
|
||||
});
|
||||
rendererRef.value = renderer;
|
||||
|
||||
const gl = renderer.gl;
|
||||
gl.clearColor(0, 0, 0, 0);
|
||||
if (containerRef.value) {
|
||||
containerRef.value.appendChild(gl.canvas);
|
||||
}
|
||||
|
||||
const camera = new Camera(gl);
|
||||
const scene = new Transform();
|
||||
|
||||
const geometry = new Geometry(gl, {
|
||||
position: { size: 2, data: new Float32Array([-1, -1, 3, -1, -1, 3]) }
|
||||
});
|
||||
|
||||
const program = new Program(gl, {
|
||||
vertex,
|
||||
fragment,
|
||||
uniforms: {
|
||||
iTime: { value: 0 },
|
||||
iResolution: { value: uniformResolution.value },
|
||||
uOffset: { value: uniformOffset.value },
|
||||
uRotation: { value: 0 },
|
||||
focalLength: { value: props.focalLength },
|
||||
speed1: { value: props.speed1 },
|
||||
speed2: { value: props.speed2 },
|
||||
dir2: { value: props.dir2 },
|
||||
bend1: { value: props.bend1 },
|
||||
bend2: { value: props.bend2 },
|
||||
bendAdj1: { value: 0 },
|
||||
bendAdj2: { value: 0 },
|
||||
uOpacity: { value: 0 }
|
||||
}
|
||||
});
|
||||
new Mesh(gl, { geometry, program }).setParent(scene);
|
||||
|
||||
const resize = () => {
|
||||
const { width, height } = containerRef.value?.getBoundingClientRect() || { width: 0, height: 0 };
|
||||
renderer.setSize(width, height);
|
||||
uniformResolution.value[0] = width * renderer.dpr;
|
||||
uniformResolution.value[1] = height * renderer.dpr;
|
||||
gl.viewport(0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight);
|
||||
gl.clear(gl.COLOR_BUFFER_BIT);
|
||||
};
|
||||
resize();
|
||||
const ro = new ResizeObserver(resize);
|
||||
if (containerRef.value) {
|
||||
ro.observe(containerRef.value);
|
||||
}
|
||||
|
||||
let rafId: number;
|
||||
|
||||
const loop = (now: number) => {
|
||||
const {
|
||||
xOffset: xOff,
|
||||
yOffset: yOff,
|
||||
rotationDeg: rot,
|
||||
focalLength: fLen,
|
||||
fadeInDuration: fadeDur
|
||||
} = propsRef.value;
|
||||
|
||||
if (isVisible.value) {
|
||||
if (lastTimeRef.value === 0) {
|
||||
lastTimeRef.value = now - pausedTimeRef.value;
|
||||
}
|
||||
|
||||
const t = (now - lastTimeRef.value) * 0.001;
|
||||
|
||||
if (fadeStartTime.value === null && t > 0.1) {
|
||||
fadeStartTime.value = now;
|
||||
}
|
||||
|
||||
let opacity = 0;
|
||||
if (fadeStartTime.value !== null) {
|
||||
const fadeElapsed = now - fadeStartTime.value;
|
||||
opacity = Math.min(fadeElapsed / fadeDur, 1);
|
||||
opacity = 1 - Math.pow(1 - opacity, 3);
|
||||
}
|
||||
|
||||
uniformOffset.value[0] = xOff;
|
||||
uniformOffset.value[1] = yOff;
|
||||
|
||||
program.uniforms.iTime.value = t;
|
||||
program.uniforms.uRotation.value = (rot * Math.PI) / 180;
|
||||
program.uniforms.focalLength.value = fLen;
|
||||
program.uniforms.uOpacity.value = opacity;
|
||||
|
||||
renderer.render({ scene, camera });
|
||||
} else {
|
||||
if (lastTimeRef.value !== 0) {
|
||||
pausedTimeRef.value = now - lastTimeRef.value;
|
||||
lastTimeRef.value = 0;
|
||||
}
|
||||
}
|
||||
|
||||
rafId = requestAnimationFrame(loop);
|
||||
};
|
||||
rafId = requestAnimationFrame(loop);
|
||||
|
||||
cleanup = () => {
|
||||
cancelAnimationFrame(rafId);
|
||||
ro.disconnect();
|
||||
renderer.gl.canvas.remove();
|
||||
};
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
setup();
|
||||
});
|
||||
|
||||
onBeforeUnmount(() => {
|
||||
cleanup?.();
|
||||
});
|
||||
|
||||
watch(
|
||||
() => [isMobile, isVisible],
|
||||
() => {
|
||||
cleanup?.();
|
||||
setup();
|
||||
},
|
||||
{
|
||||
deep: true
|
||||
}
|
||||
);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div
|
||||
v-if="!isMobile"
|
||||
ref="containerRef"
|
||||
:style="{
|
||||
position: 'absolute',
|
||||
inset: 0,
|
||||
overflow: 'hidden',
|
||||
width: '100vw',
|
||||
height: '100vh'
|
||||
}"
|
||||
>
|
||||
<div
|
||||
:style="{
|
||||
position: 'absolute',
|
||||
bottom: 0,
|
||||
left: 0,
|
||||
right: 0,
|
||||
height: 200,
|
||||
background: 'linear-gradient(to top, #060010, transparent)',
|
||||
pointerEvents: 'none',
|
||||
zIndex: 1
|
||||
}"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
@@ -17,10 +17,11 @@
|
||||
max-width: 1200px;
|
||||
user-select: none;
|
||||
margin: 0 auto;
|
||||
background: linear-gradient(135deg, #3aed6d, rgba(24, 255, 93, 0.6));
|
||||
background: linear-gradient(135deg, rgba(58, 237, 109, 1), rgba(23, 255, 66, 0.6));
|
||||
background-size: 200% 200%;
|
||||
border-radius: 16px;
|
||||
border-radius: 50px;
|
||||
padding: 4rem 3rem;
|
||||
box-shadow: 0 8px 32px 0 rgba(31, 38, 135, 0.5);
|
||||
backdrop-filter: blur(10px);
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
@@ -40,9 +41,9 @@
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-image: url('/assets/grain.webp');
|
||||
filter: brightness(3);
|
||||
background-size: 500px 500px;
|
||||
filter: invert(100%);
|
||||
mix-blend-mode: multiply;
|
||||
mix-blend-mode: lighten;
|
||||
background-repeat: repeat;
|
||||
opacity: 1;
|
||||
pointer-events: none;
|
||||
@@ -56,9 +57,8 @@
|
||||
|
||||
.start-building-title {
|
||||
color: #0b0b0b;
|
||||
font-size: 2.6rem;
|
||||
font-weight: 600;
|
||||
margin: 0;
|
||||
font-size: 3rem;
|
||||
font-weight: 500;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
@@ -66,19 +66,20 @@
|
||||
color: #0b0b0b;
|
||||
font-size: 1.2rem;
|
||||
font-weight: 500;
|
||||
margin: -1rem 0 0 0;
|
||||
opacity: 0.9;
|
||||
opacity: 0.6;
|
||||
max-width: 600px;
|
||||
line-height: 1.4;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
.start-building-button {
|
||||
background: transparent;
|
||||
background: white;
|
||||
border: 1px solid white;
|
||||
color: #0b0b0b;
|
||||
border: 2px solid #0b0b0b;
|
||||
padding: 0.6rem 1.6rem;
|
||||
font-size: 1.1rem;
|
||||
font-weight: 600;
|
||||
padding: 0.6rem 1.8rem;
|
||||
font-size: 1rem;
|
||||
font-weight: 500;
|
||||
letter-spacing: -0.2px;
|
||||
border-radius: 50px;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s ease;
|
||||
@@ -111,7 +112,6 @@
|
||||
|
||||
.start-building-card {
|
||||
padding: 3rem 2rem;
|
||||
border-radius: 12px;
|
||||
gap: 1.25rem;
|
||||
}
|
||||
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
<section class="start-building-section">
|
||||
<div class="start-building-container">
|
||||
<div class="start-building-card">
|
||||
<h2 class="start-building-title">Start exploring Vue Bits</h2>
|
||||
<p class="start-building-subtitle">Animations, components, backgrounds - it's all here</p>
|
||||
<h2 class="start-building-title">Start Exploring</h2>
|
||||
<p class="start-building-subtitle">Animations, Components, Backgrounds - One Click Away</p>
|
||||
|
||||
<router-link to="/text-animations/split-text" class="start-building-button">Browse Components</router-link>
|
||||
</div>
|
||||
|
||||
@@ -10,51 +10,102 @@
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
height: 100%;
|
||||
height: 100dvh;
|
||||
max-width: calc(1200px + 6em);
|
||||
margin: 0 auto;
|
||||
padding: 0 4em;
|
||||
margin-top: 250px;
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
.landing-title {
|
||||
text-align: center;
|
||||
user-select: none;
|
||||
white-space: nowrap !important;
|
||||
font-size: 3.6rem;
|
||||
font-weight: 500;
|
||||
font-size: 5rem;
|
||||
font-weight: 400;
|
||||
position: relative;
|
||||
z-index: 6;
|
||||
color: #fff;
|
||||
margin-bottom: 1rem;
|
||||
margin-bottom: 3rem;
|
||||
max-width: 22ch;
|
||||
letter-spacing: -3px;
|
||||
line-height: 1;
|
||||
text-shadow:
|
||||
0 0 2px rgba(255, 255, 255, 0.1),
|
||||
0 0 4px rgba(255, 255, 255, 0.3),
|
||||
0 0 8px rgba(255, 255, 255, 0.4),
|
||||
0 0 8px rgba(255, 255, 255, 0.2),
|
||||
0 0 136px rgba(60, 255, 79, 0.4);
|
||||
}
|
||||
|
||||
.landing-subtitle {
|
||||
user-select: none;
|
||||
text-align: center;
|
||||
overflow: visible !important;
|
||||
font-size: 1.2rem;
|
||||
text-align: left !important;
|
||||
font-size: 1.4rem;
|
||||
font-weight: 300;
|
||||
line-height: 1.2;
|
||||
color: #a7ef9e;
|
||||
max-width: 30ch;
|
||||
margin-bottom: 2rem;
|
||||
text-shadow:
|
||||
0 0 2px rgba(255, 255, 255, 0.1),
|
||||
0 0 4px rgba(255, 255, 255, 0.3),
|
||||
0 0 8px rgba(255, 255, 255, 0.4),
|
||||
0 0 136px rgba(60, 255, 79, 0.8);
|
||||
line-height: 1.6;
|
||||
color: #ccc;
|
||||
max-width: 40ch;
|
||||
margin-bottom: 1.5rem;
|
||||
z-index: 6;
|
||||
}
|
||||
|
||||
.landing-gradient-blur {
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
top: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
aspect-ratio: 1;
|
||||
height: 1200px;
|
||||
}
|
||||
|
||||
.hero-new-badge-container {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.8rem;
|
||||
border: 1px solid rgba(255, 255, 255, 0.07);
|
||||
background: rgba(255, 255, 255, 0.01);
|
||||
box-shadow: 0 8px 32px 0 rgba(31, 38, 135, 0.15);
|
||||
backdrop-filter: blur(15px);
|
||||
-webkit-backdrop-filter: blur(15px);
|
||||
padding: 0.6em 0.8em 0.6em 0.6em;
|
||||
border-radius: 50px;
|
||||
margin-bottom: 1.5rem;
|
||||
color: #ccc;
|
||||
z-index: 6;
|
||||
transition: all 0.4s cubic-bezier(0.175, 0.885, 0.32, 1.275);
|
||||
}
|
||||
|
||||
.hero-tag-fade {
|
||||
position: relative;
|
||||
z-index: 8;
|
||||
}
|
||||
|
||||
.hero-new-badge {
|
||||
font-size: 14px;
|
||||
background: #3aef43;
|
||||
padding: 0.2em 0.8em;
|
||||
border-radius: 50px;
|
||||
color: black;
|
||||
}
|
||||
|
||||
.hero-new-badge-text {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.4em;
|
||||
}
|
||||
|
||||
.hero-new-badge-container:hover {
|
||||
box-shadow:
|
||||
0 0 60px rgba(58, 237, 112, 0.4),
|
||||
0 0 120px rgba(92, 246, 138, 0.35),
|
||||
0 0 180px rgba(40, 217, 64, 0.3),
|
||||
0 12px 40px rgba(0, 0, 0, 0.6);
|
||||
transform: translateY(-4px) scale(1.01);
|
||||
transition: all 0.4s cubic-bezier(0.175, 0.885, 0.32, 1.275);
|
||||
animation-duration: 1.5s;
|
||||
}
|
||||
|
||||
.hero-split {
|
||||
white-space: nowrap !important;
|
||||
overflow: visible !important;
|
||||
@@ -62,34 +113,35 @@
|
||||
|
||||
.landing-button {
|
||||
position: relative;
|
||||
background: linear-gradient(135deg, rgb(30, 160, 63), rgba(24, 47, 255, 0.6));
|
||||
background: linear-gradient(135deg, rgb(30, 160, 63), rgba(24, 47, 255, 1));
|
||||
background-size: 200% 200%;
|
||||
font-weight: 600;
|
||||
font-size: 1.1rem;
|
||||
font-weight: 500;
|
||||
font-size: 1rem;
|
||||
border-radius: 50px;
|
||||
border: none;
|
||||
padding: 1rem 1rem 1rem 2.5rem;
|
||||
letter-spacing: -0.2px;
|
||||
height: 55px;
|
||||
padding: 0 2em 0 2em;
|
||||
color: white;
|
||||
cursor: pointer;
|
||||
isolation: isolate;
|
||||
z-index: 15;
|
||||
box-shadow:
|
||||
0 0 40px rgba(58, 237, 112, 0.4),
|
||||
0 0 80px rgba(92, 246, 138, 0.3),
|
||||
0 8px 32px rgba(0, 0, 0, 0.3);
|
||||
0 0 40px rgba(58, 237, 112, 0.1),
|
||||
0 0 80px rgba(92, 246, 138, 0.1),
|
||||
0 8px 32px rgba(0, 0, 0, 0.1);
|
||||
transition: all 0.4s cubic-bezier(0.175, 0.885, 0.32, 1.275);
|
||||
animation: glow-pulse 3s ease-in-out infinite alternate;
|
||||
text-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
|
||||
letter-spacing: 0.5px;
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 1.6rem;
|
||||
gap: 0.8rem;
|
||||
}
|
||||
|
||||
.button-arrow-circle {
|
||||
display: flex;
|
||||
display: none;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 38px;
|
||||
@@ -105,7 +157,6 @@
|
||||
|
||||
.landing-button:hover .button-arrow-circle {
|
||||
background: rgba(255, 255, 255, 1);
|
||||
transform: translateX(4px);
|
||||
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
|
||||
}
|
||||
|
||||
@@ -300,118 +351,10 @@
|
||||
|
||||
.hero-main-content {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
max-width: 60%;
|
||||
}
|
||||
|
||||
.hero-cards-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 2.4rem;
|
||||
max-width: 40%;
|
||||
margin-left: 0.6rem;
|
||||
}
|
||||
|
||||
.hero-cards-row {
|
||||
display: flex;
|
||||
gap: 2.4rem;
|
||||
}
|
||||
|
||||
.hero-glitch {
|
||||
mix-blend-mode: screen;
|
||||
border-radius: 30px !important;
|
||||
}
|
||||
|
||||
.hero-dot-grid {
|
||||
overflow: hidden !important;
|
||||
transform: translateY(5px) translateX(5px);
|
||||
}
|
||||
|
||||
.hero-metaballs {
|
||||
mix-blend-mode: screen;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.hero-falling-text .falling-text-canvas {
|
||||
width: 100% !important;
|
||||
height: 100% !important;
|
||||
}
|
||||
|
||||
.hero-lines {
|
||||
width: 100% !important;
|
||||
height: 100% !important;
|
||||
}
|
||||
|
||||
.hero-card {
|
||||
width: 200px;
|
||||
height: 200px;
|
||||
background: linear-gradient(135deg, rgba(58, 237, 109, 0.2), rgba(40, 217, 72, 0.2));
|
||||
border: 2px solid rgba(255, 255, 255, 0.2);
|
||||
border-radius: 30px;
|
||||
box-shadow:
|
||||
0 30px 100px rgba(0, 16, 5, 0.95),
|
||||
0 20px 70px rgba(0, 16, 5, 0.9),
|
||||
0 15px 50px rgba(0, 16, 5, 0.8),
|
||||
0 10px 30px rgba(0, 16, 7, 0.7),
|
||||
0 8px 32px rgba(58, 237, 121, 0.4),
|
||||
inset 0 1px 0 rgba(255, 255, 255, 0.2);
|
||||
backdrop-filter: blur(20px);
|
||||
-webkit-backdrop-filter: blur(20px);
|
||||
transition: all 0.3s ease;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
cursor: pointer;
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.hero-card-1 {
|
||||
animation: fadeInUpRotate1 0.8s ease-out forwards;
|
||||
animation-delay: 0.2s;
|
||||
transform: translateY(0) scale(1) rotate(-13deg);
|
||||
}
|
||||
|
||||
.hero-card-2 {
|
||||
animation: fadeInUpRotate2 0.8s ease-out forwards;
|
||||
animation-delay: 0.4s;
|
||||
transform: translateY(0) scale(1) rotate(10deg);
|
||||
}
|
||||
|
||||
.hero-card-3 {
|
||||
animation: fadeInUpRotate3 0.8s ease-out forwards;
|
||||
animation-delay: 0.6s;
|
||||
transform: translateY(0) scale(1) rotate(-5deg);
|
||||
}
|
||||
|
||||
.hero-card:hover {
|
||||
filter: grayscale(50%);
|
||||
box-shadow:
|
||||
0 50px 140px rgba(0, 16, 5, 0.98),
|
||||
0 35px 100px rgba(0, 16, 4, 0.95),
|
||||
0 25px 70px rgba(0, 16, 4, 0.9),
|
||||
0 15px 50px rgba(0, 16, 4, 0.8),
|
||||
0 12px 40px rgba(58, 237, 115, 0.6),
|
||||
inset 0 1px 0 rgba(255, 255, 255, 0.3);
|
||||
backdrop-filter: blur(25px);
|
||||
-webkit-backdrop-filter: blur(25px);
|
||||
}
|
||||
|
||||
.hero-card::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: -100%;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.2), transparent);
|
||||
transition: left 0.5s ease;
|
||||
}
|
||||
|
||||
.hero-card:hover::before {
|
||||
left: 100%;
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
@media (max-width: 1440px) {
|
||||
@@ -422,10 +365,6 @@
|
||||
.landing-subtitle {
|
||||
font-size: 1.3rem;
|
||||
}
|
||||
|
||||
.landing-content {
|
||||
margin-top: 250px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 1366px) {
|
||||
@@ -436,10 +375,6 @@
|
||||
.landing-subtitle {
|
||||
font-size: 1.2rem;
|
||||
}
|
||||
|
||||
.landing-content {
|
||||
margin-top: 250px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 1200px) {
|
||||
@@ -450,10 +385,6 @@
|
||||
.landing-subtitle {
|
||||
font-size: 1.1rem;
|
||||
}
|
||||
|
||||
.landing-content {
|
||||
margin-top: 250px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 1100px) {
|
||||
@@ -464,10 +395,6 @@
|
||||
.landing-subtitle {
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
.landing-content {
|
||||
margin-top: 250px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 1024px) {
|
||||
@@ -480,58 +407,14 @@
|
||||
}
|
||||
|
||||
.landing-content {
|
||||
margin-top: 300px;
|
||||
margin-top: 250px;
|
||||
height: auto;
|
||||
padding: 0 2em;
|
||||
max-width: calc(1200px + 2em);
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.hero-main-content {
|
||||
max-width: 100%;
|
||||
align-items: center;
|
||||
text-align: center;
|
||||
margin-bottom: 2rem;
|
||||
}
|
||||
|
||||
.hero-cards-container {
|
||||
max-width: 100%;
|
||||
width: 100%;
|
||||
margin-left: 0;
|
||||
margin-top: 2rem;
|
||||
flex-direction: row;
|
||||
gap: 1.5rem;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.hero-cards-row {
|
||||
display: contents;
|
||||
}
|
||||
|
||||
.hero-card {
|
||||
flex: 1;
|
||||
height: 120px;
|
||||
max-width: calc(33.333% - 1rem);
|
||||
}
|
||||
|
||||
.hero-card-1 {
|
||||
animation: fadeInUpMobileRotate1 0.8s ease-out forwards;
|
||||
animation-delay: 0.2s;
|
||||
transform: translateY(0) scale(1) rotate(-13deg);
|
||||
}
|
||||
|
||||
.hero-card-2 {
|
||||
animation: fadeInUpMobileRotate2 0.8s ease-out forwards;
|
||||
animation-delay: 0.4s;
|
||||
transform: translateY(0) scale(1) rotate(10deg);
|
||||
}
|
||||
|
||||
.hero-card-3 {
|
||||
animation: fadeInUpMobileRotate3 0.8s ease-out forwards;
|
||||
animation-delay: 0.6s;
|
||||
transform: translateY(0) scale(1) rotate(-5deg);
|
||||
}
|
||||
|
||||
.landing-wrapper > div[style*='position: absolute'][style*='width: 100vw'][style*='height: 100vh'] {
|
||||
opacity: 0.7;
|
||||
}
|
||||
@@ -546,10 +429,6 @@
|
||||
font-size: 0.9rem;
|
||||
text-align: center !important;
|
||||
}
|
||||
|
||||
.landing-content {
|
||||
margin-top: 290px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 900px) {
|
||||
@@ -562,10 +441,6 @@
|
||||
text-align: center !important;
|
||||
}
|
||||
|
||||
.landing-content {
|
||||
margin-top: 280px;
|
||||
}
|
||||
|
||||
.landing-wrapper::before {
|
||||
width: 100px;
|
||||
}
|
||||
@@ -583,10 +458,6 @@
|
||||
.landing-subtitle {
|
||||
font-size: 0.8rem;
|
||||
}
|
||||
|
||||
.landing-content {
|
||||
margin-top: 270px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
@@ -599,7 +470,7 @@
|
||||
.landing-subtitle {
|
||||
font-size: 0.75rem;
|
||||
text-align: center !important;
|
||||
max-width: 100%;
|
||||
max-width: 80%;
|
||||
}
|
||||
|
||||
.landing-content {
|
||||
@@ -609,7 +480,7 @@
|
||||
}
|
||||
|
||||
.landing-button {
|
||||
padding: 0.8rem 0.8rem 0.8rem 1.8rem;
|
||||
padding: 0 2em 0 2em;
|
||||
font-size: 1rem;
|
||||
gap: 1.2rem;
|
||||
}
|
||||
@@ -619,41 +490,6 @@
|
||||
height: 32px;
|
||||
}
|
||||
|
||||
.hero-cards-container {
|
||||
flex-direction: row;
|
||||
gap: 1.2rem;
|
||||
width: 100%;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.hero-cards-row {
|
||||
display: contents;
|
||||
}
|
||||
|
||||
.hero-card {
|
||||
flex: 1;
|
||||
height: 120px;
|
||||
max-width: calc(33.333% - 0.8rem);
|
||||
}
|
||||
|
||||
.hero-card-1 {
|
||||
animation: fadeInUpMobileRotate1 0.8s ease-out forwards;
|
||||
animation-delay: 0.2s;
|
||||
transform: translateY(0) scale(1) rotate(-13deg);
|
||||
}
|
||||
|
||||
.hero-card-2 {
|
||||
animation: fadeInUpMobileRotate2 0.8s ease-out forwards;
|
||||
animation-delay: 0.4s;
|
||||
transform: translateY(0) scale(1) rotate(10deg);
|
||||
}
|
||||
|
||||
.hero-card-3 {
|
||||
animation: fadeInUpMobileRotate3 0.8s ease-out forwards;
|
||||
animation-delay: 0.6s;
|
||||
transform: translateY(0) scale(1) rotate(-5deg);
|
||||
}
|
||||
|
||||
.landing-wrapper > div[style*='position: absolute'][style*='width: 100vw'][style*='height: 100vh'] {
|
||||
opacity: 0.5;
|
||||
}
|
||||
@@ -670,7 +506,7 @@
|
||||
.landing-subtitle {
|
||||
font-size: 1rem;
|
||||
text-align: center !important;
|
||||
max-width: 100%;
|
||||
max-width: 80%;
|
||||
}
|
||||
|
||||
.landing-content {
|
||||
@@ -689,7 +525,7 @@
|
||||
|
||||
.landing-subtitle {
|
||||
text-align: center !important;
|
||||
max-width: 100%;
|
||||
max-width: 80%;
|
||||
}
|
||||
|
||||
.landing-content {
|
||||
@@ -708,7 +544,7 @@
|
||||
|
||||
.landing-subtitle {
|
||||
text-align: center !important;
|
||||
max-width: 100%;
|
||||
max-width: 80%;
|
||||
}
|
||||
|
||||
.landing-content {
|
||||
@@ -727,7 +563,7 @@
|
||||
|
||||
.landing-subtitle {
|
||||
text-align: center !important;
|
||||
max-width: 100%;
|
||||
max-width: 80%;
|
||||
}
|
||||
|
||||
.landing-content {
|
||||
@@ -746,7 +582,7 @@
|
||||
|
||||
.landing-subtitle {
|
||||
text-align: center !important;
|
||||
max-width: 100%;
|
||||
max-width: 80%;
|
||||
}
|
||||
|
||||
.landing-content {
|
||||
@@ -756,7 +592,7 @@
|
||||
}
|
||||
|
||||
.landing-button {
|
||||
padding: 0.7rem 0.7rem 0.7rem 1.5rem;
|
||||
padding: 0 2em 0 2em;
|
||||
font-size: 0.95rem;
|
||||
gap: 1rem;
|
||||
}
|
||||
@@ -766,41 +602,6 @@
|
||||
height: 28px;
|
||||
}
|
||||
|
||||
.hero-cards-container {
|
||||
flex-direction: row;
|
||||
gap: 1rem;
|
||||
width: 100%;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.hero-cards-row {
|
||||
display: contents;
|
||||
}
|
||||
|
||||
.hero-card {
|
||||
flex: 1;
|
||||
height: 120px;
|
||||
max-width: calc(33.333% - 0.666rem);
|
||||
}
|
||||
|
||||
.hero-card-1 {
|
||||
animation: fadeInUpMobileRotate1 0.8s ease-out forwards;
|
||||
animation-delay: 0.2s;
|
||||
transform: translateY(0) scale(1) rotate(-13deg);
|
||||
}
|
||||
|
||||
.hero-card-2 {
|
||||
animation: fadeInUpMobileRotate2 0.8s ease-out forwards;
|
||||
animation-delay: 0.4s;
|
||||
transform: translateY(0) scale(1) rotate(10deg);
|
||||
}
|
||||
|
||||
.hero-card-3 {
|
||||
animation: fadeInUpMobileRotate3 0.8s ease-out forwards;
|
||||
animation-delay: 0.6s;
|
||||
transform: translateY(0) scale(1) rotate(-5deg);
|
||||
}
|
||||
|
||||
.landing-wrapper > div[style*='position: absolute'][style*='width: 100vw'][style*='height: 100vh'] {
|
||||
opacity: 0.3;
|
||||
}
|
||||
@@ -816,7 +617,7 @@
|
||||
|
||||
.landing-subtitle {
|
||||
text-align: center !important;
|
||||
max-width: 100%;
|
||||
max-width: 80%;
|
||||
}
|
||||
|
||||
.landing-content {
|
||||
@@ -836,7 +637,7 @@
|
||||
|
||||
.landing-subtitle {
|
||||
text-align: center !important;
|
||||
max-width: 100%;
|
||||
max-width: 80%;
|
||||
}
|
||||
|
||||
.landing-content {
|
||||
@@ -856,7 +657,7 @@
|
||||
|
||||
.landing-subtitle {
|
||||
text-align: center !important;
|
||||
max-width: 100%;
|
||||
max-width: 80%;
|
||||
}
|
||||
|
||||
.landing-content {
|
||||
@@ -866,7 +667,7 @@
|
||||
}
|
||||
|
||||
.landing-button {
|
||||
padding: 0.6rem 0.6rem 0.6rem 1.2rem;
|
||||
padding: 0 2em 0 2em;
|
||||
font-size: 0.9rem;
|
||||
gap: 0.8rem;
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
/>
|
||||
</div>
|
||||
|
||||
<PlasmaWave :y-offset="-300" :x-offset="100" :rotation-deg="-30" />
|
||||
<PlasmaWaveV2 :yOffset="0" :xOffset="40" :rotationDeg="-35" />
|
||||
<Hero />
|
||||
<FeatureCards />
|
||||
<StartBuilding />
|
||||
@@ -20,7 +20,7 @@
|
||||
<script setup lang="ts">
|
||||
import { ref, onMounted, onUnmounted } from 'vue';
|
||||
import Hero from '../components/landing/Hero/Hero.vue';
|
||||
import PlasmaWave from '@/components/landing/PlasmaWave/PlasmaWave.vue';
|
||||
import PlasmaWaveV2 from '@/components/landing/PlasmaWave/PlasmaWaveV2.vue';
|
||||
import Footer from '@/components/landing/Footer/Footer.vue';
|
||||
import FeatureCards from '@/components/landing/FeatureCards/FeatureCards.vue';
|
||||
import StartBuilding from '@/components/landing/StartBuilding/StartBuilding.vue';
|
||||
|
||||
Reference in New Issue
Block a user