154 lines
3.5 KiB
Vue
154 lines
3.5 KiB
Vue
<template>
|
|
<div id="app">
|
|
<!-- Snowflake effect as global background -->
|
|
<div class="snowflakes" aria-hidden="true">
|
|
<div class="snowflake" v-for="i in 50" :key="i">❅</div>
|
|
</div>
|
|
|
|
<!-- Router view for page content -->
|
|
<router-view />
|
|
</div>
|
|
</template>
|
|
|
|
<script setup>
|
|
import { onMounted } from 'vue'
|
|
|
|
onMounted(() => {
|
|
// Create snowflake animation
|
|
const snowflakes = document.querySelectorAll('.snowflake')
|
|
|
|
snowflakes.forEach((snowflake, index) => {
|
|
const delay = Math.random() * 5
|
|
const duration = 3 + Math.random() * 2
|
|
const size = 0.5 + Math.random() * 0.8
|
|
const opacity = 0.3 + Math.random() * 0.7
|
|
const leftPosition = Math.random() * 100
|
|
|
|
snowflake.style.left = leftPosition + '%'
|
|
snowflake.style.animationDelay = delay + 's'
|
|
snowflake.style.animationDuration = duration + 's'
|
|
snowflake.style.fontSize = size + 'rem'
|
|
snowflake.style.opacity = opacity
|
|
})
|
|
})
|
|
</script>
|
|
|
|
<style>
|
|
@import url('https://fonts.googleapis.com/css2?family=Montserrat:wght@300;400;600;700&display=swap');
|
|
|
|
:root {
|
|
--primary-color: #e63946;
|
|
--secondary-color: #a8dadc;
|
|
--dark-color: #1d3557;
|
|
--light-color: #f1faee;
|
|
--accent-color: #457b9d;
|
|
--transition: all 0.4s cubic-bezier(0.25, 0.8, 0.25, 1);
|
|
--card-shadow: 0 15px 30px rgba(0, 0, 0, 0.2);
|
|
--card-hover-shadow: 0 20px 40px rgba(231, 57, 70, 0.3);
|
|
}
|
|
|
|
* {
|
|
margin: 0;
|
|
padding: 0;
|
|
box-sizing: border-box;
|
|
}
|
|
|
|
body {
|
|
font-family: 'Montserrat', 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
|
min-height: 100vh;
|
|
overflow-x: hidden;
|
|
line-height: 1.6;
|
|
color: var(--light-color);
|
|
position: relative;
|
|
background: #0b0000; /* Deep black background */
|
|
}
|
|
|
|
body::before {
|
|
content: '';
|
|
position: fixed;
|
|
top: 0;
|
|
left: 0;
|
|
width: 100%;
|
|
height: 100%;
|
|
background:
|
|
radial-gradient(circle at 30% 20%, rgba(230, 57, 70, 0.25), transparent 40%),
|
|
radial-gradient(circle at 70% 80%, rgba(230, 57, 70, 0.1), transparent 40%),
|
|
radial-gradient(circle at 50% 50%, rgba(230, 57, 70, 0.15), transparent 50%),
|
|
linear-gradient(135deg, rgba(20, 0, 0, 0.9), rgba(11, 0, 0, 0.95));
|
|
backdrop-filter: blur(25px);
|
|
-webkit-backdrop-filter: blur(25px);
|
|
z-index: -2;
|
|
}
|
|
|
|
body::after {
|
|
content: '';
|
|
position: fixed;
|
|
top: 0;
|
|
left: 0;
|
|
width: 100%;
|
|
height: 100%;
|
|
background:
|
|
radial-gradient(circle at 10% 20%, rgba(255, 100, 100, 0.1), transparent 20%),
|
|
radial-gradient(circle at 90% 60%, rgba(255, 80, 80, 0.08), transparent 25%),
|
|
radial-gradient(circle at 50% 50%, rgba(255, 120, 120, 0.05), transparent 30%);
|
|
animation: glowEffect 15s infinite alternate;
|
|
z-index: -1;
|
|
mix-blend-mode: overlay;
|
|
}
|
|
|
|
@keyframes glowEffect {
|
|
0% {
|
|
opacity: 0.6;
|
|
background-position: 0% 0%;
|
|
}
|
|
33% {
|
|
opacity: 0.7;
|
|
background-position: 30% 30%;
|
|
}
|
|
66% {
|
|
opacity: 0.8;
|
|
background-position: 70% 70%;
|
|
}
|
|
100% {
|
|
opacity: 0.9;
|
|
background-position: 100% 100%;
|
|
}
|
|
}
|
|
|
|
#app {
|
|
position: relative;
|
|
min-height: 100vh;
|
|
}
|
|
|
|
/* Snowflake animation styles */
|
|
.snowflakes {
|
|
position: fixed;
|
|
top: 0;
|
|
left: 0;
|
|
width: 100%;
|
|
height: 100%;
|
|
pointer-events: none;
|
|
z-index: 1;
|
|
}
|
|
|
|
.snowflake {
|
|
position: absolute;
|
|
top: -10px;
|
|
color: rgba(255, 200, 200, 0.8);
|
|
user-select: none;
|
|
pointer-events: none;
|
|
opacity: 0.5;
|
|
text-shadow: 0 0 10px rgba(230, 57, 70, 0.5);
|
|
animation: fall linear infinite;
|
|
}
|
|
|
|
@keyframes fall {
|
|
0% {
|
|
transform: translateY(-100vh) rotate(0deg);
|
|
}
|
|
100% {
|
|
transform: translateY(100vh) rotate(360deg);
|
|
}
|
|
}
|
|
</style>
|