Added
- Functional contact form — Formspree async integration in
ContactSection.vuewithidle / sending / success / errorstates and bilingual feedback messages src/data/contact.ts— single source of truth for GitHub / LinkedIn / email / location; imported by Footer and Contact section- SEO meta tags — OpenGraph, Twitter Card, canonical URL, description, keywords added to
index.html - Scroll reveal animation — new
useScrollRevealcomposable (IntersectionObserver-based) with.sr-hidden / .sr-visibletransitions applied to About / Projects / TechStack / Stats / Contact src/analytics.ts— runtime Google Analytics loader that injectsgtag.jsonly whenVITE_GA_IDis set (true no-op by default)- Environment variables —
VITE_GA_ID(optional GA4 tracking) andVITE_FORMSPREE_ID(optional contact-form backend), documented in bilingual README and CLAUDE.md - Third-party utility skills tracked in repo —
.claude/skills/now includespdf,docx,canvas-design,frontend-design,theme-factory,playwright-skill
Fixed
- Typing animation language-switch bug —
useTypingnow acceptsRef/ComputedRefand restarts cleanly when locale changes - Hardcoded header initials — replaced
LCliteral witht('hero.initials')so template users see their own initials after/update-resume - Invalid GA script request — removed the
%VITE_GA_ID%block fromindex.htmlthat emitted a Vite build warning and fetched the URL with the literal placeholder when the env var was unset
Changed
- Footer and Contact section now source social/email data from
src/data/contact.ts - Contact form endpoint built at runtime from
import.meta.env.VITE_FORMSPREE_ID; absent env var produces a friendly error toast with zero network calls src/vite-env.d.tsextended with typed declarations for the new env vars
Full Changelog: v1.1.0...v1.2.0