73 lines
3.1 KiB
Vue
73 lines
3.1 KiB
Vue
<template>
|
||
<section id="about" class="py-24 px-4">
|
||
<div class="max-w-4xl mx-auto">
|
||
<div class="section-hidden" ref="sectionRef">
|
||
<h2 class="text-3xl md:text-4xl font-bold text-white mb-4">
|
||
О себе
|
||
</h2>
|
||
<div class="w-16 h-1 bg-indigo-500 mb-10 rounded-full" />
|
||
<div class="grid md:grid-cols-2 gap-8">
|
||
<div>
|
||
<p class="text-gray-400 text-lg leading-relaxed mb-6">
|
||
Привет! Я fullstack-разработчик с более чем 5 годами опыта создания
|
||
масштабируемых веб-приложений. Специализируюсь на экосистеме Node.js
|
||
и современных JavaScript-фреймворках.
|
||
</p>
|
||
<p class="text-gray-400 text-lg leading-relaxed">
|
||
Люблю чистую архитектуру, хорошо задокументированный код и всё, что
|
||
связано с DevOps-практиками. Открыт к интересным проектам и
|
||
долгосрочному сотрудничеству.
|
||
</p>
|
||
</div>
|
||
<div class="space-y-4">
|
||
<UCard class="bg-gray-900 border-gray-800">
|
||
<div class="flex items-center gap-3">
|
||
<UIcon name="i-heroicons-map-pin" class="text-indigo-400 w-5 h-5" />
|
||
<span class="text-gray-300">Москва, Россия</span>
|
||
</div>
|
||
</UCard>
|
||
<UCard class="bg-gray-900 border-gray-800">
|
||
<div class="flex items-center gap-3">
|
||
<UIcon name="i-heroicons-briefcase" class="text-indigo-400 w-5 h-5" />
|
||
<span class="text-gray-300">5+ лет опыта</span>
|
||
</div>
|
||
</UCard>
|
||
<UCard class="bg-gray-900 border-gray-800">
|
||
<div class="flex items-center gap-3">
|
||
<UIcon name="i-heroicons-language" class="text-indigo-400 w-5 h-5" />
|
||
<span class="text-gray-300">Русский, English (B2)</span>
|
||
</div>
|
||
</UCard>
|
||
<UCard class="bg-gray-900 border-gray-800">
|
||
<div class="flex items-center gap-3">
|
||
<UIcon name="i-heroicons-check-circle" class="text-indigo-400 w-5 h-5" />
|
||
<span class="text-gray-300">Доступен для фриланса</span>
|
||
</div>
|
||
</UCard>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
</template>
|
||
|
||
<script setup lang="ts">
|
||
const sectionRef = ref<HTMLElement | null>(null);
|
||
|
||
onMounted(() => {
|
||
const observer = new IntersectionObserver(
|
||
(entries) => {
|
||
entries.forEach((entry) => {
|
||
if (entry.isIntersecting) {
|
||
entry.target.classList.remove('section-hidden');
|
||
entry.target.classList.add('section-visible');
|
||
observer.unobserve(entry.target);
|
||
}
|
||
});
|
||
},
|
||
{ threshold: 0.15 },
|
||
);
|
||
if (sectionRef.value) observer.observe(sectionRef.value);
|
||
});
|
||
</script>
|