diff options
| author | Danilo M. <danix@danix.xyz> | 2026-05-11 11:32:35 +0200 |
|---|---|---|
| committer | Danilo M. <danix@danix.xyz> | 2026-05-11 11:32:51 +0200 |
| commit | c5078a2adf338703d7b7a3d62e6594fe2831bc5d (patch) | |
| tree | b5e7e4e51c2fdca0d298fa9323a0bae9135c7956 | |
| parent | 563e87afd4ce4ef48acef4f29927579ca69d01cb (diff) | |
| download | danixxyz-theme-c5078a2adf338703d7b7a3d62e6594fe2831bc5d.tar.gz danixxyz-theme-c5078a2adf338703d7b7a3d62e6594fe2831bc5d.zip | |
feat: hero name glitch effect on homepage
Chromatic aberration glitch on h1.hero-name. Gravatar moved from
markdown shortcode to template. JS fires randomly every 4-11s.
Respects prefers-reduced-motion.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
| -rw-r--r-- | assets/css/main.css | 65 | ||||
| -rw-r--r-- | assets/css/main.min.css | 106 | ||||
| -rw-r--r-- | assets/js/hero-glitch.js | 12 | ||||
| -rw-r--r-- | layouts/_default/baseof.html | 6 | ||||
| -rw-r--r-- | layouts/index.html | 35 |
5 files changed, 202 insertions, 22 deletions
diff --git a/assets/css/main.css b/assets/css/main.css index 2455103..e5ebf14 100644 --- a/assets/css/main.css +++ b/assets/css/main.css @@ -1993,3 +1993,68 @@ html.theme-light .prose-invert .cta-block a { font-family: monospace; display: block; } + +/* Hero name glitch effect */ +.hero-name { + font-family: var(--font-head); + font-size: clamp(3rem, 12vw, 7rem); + font-weight: 800; + line-height: 0.95; + letter-spacing: -0.04em; + color: var(--text); + text-shadow: 0 0 80px rgba(168,85,247,0.18), 0 0 120px rgba(168,85,247,0.08); + display: inline-block; + position: relative; + width: 100%; + margin-bottom: 1.5rem; +} + +html.theme-light .hero-name { + text-shadow: 0 0 80px rgba(124,58,237,0.12), 0 0 120px rgba(124,58,237,0.05); +} + +.hero-name::before, +.hero-name::after { + content: attr(data-text); + position: absolute; + top: 0; + left: 0; + width: 100%; + opacity: 0; + font-family: inherit; + font-size: inherit; + font-weight: inherit; + line-height: inherit; + letter-spacing: inherit; +} + +.hero-name::before { color: #ff2b6d; } +.hero-name::after { color: #00e5ff; } + +.hero-name.is-glitching::before { + opacity: 0.8; + animation: glitch-red 0.45s steps(3) forwards; +} +.hero-name.is-glitching::after { + opacity: 0.8; + animation: glitch-cyn 0.45s steps(3) forwards; +} + +@keyframes glitch-red { + 0% { transform: translate(-5px, 1px); clip-path: inset(8% 0 78% 0); } + 33% { transform: translate(4px, -2px); clip-path: inset(42% 0 38% 0); } + 66% { transform: translate(-3px, 2px); clip-path: inset(68% 0 12% 0); } + 100% { transform: translate(0); clip-path: inset(0 0 100% 0); opacity: 0; } +} + +@keyframes glitch-cyn { + 0% { transform: translate(5px, -1px); clip-path: inset(22% 0 62% 0); } + 33% { transform: translate(-4px, 2px); clip-path: inset(55% 0 28% 0); } + 66% { transform: translate(3px, -2px); clip-path: inset(15% 0 70% 0); } + 100% { transform: translate(0); clip-path: inset(0 0 100% 0); opacity: 0; } +} + +@media (prefers-reduced-motion: reduce) { + .hero-name::before, + .hero-name::after { display: none; } +} diff --git a/assets/css/main.min.css b/assets/css/main.min.css index 056f17d..ac8360d 100644 --- a/assets/css/main.min.css +++ b/assets/css/main.min.css @@ -4733,6 +4733,112 @@ html.theme-light .prose-invert .cta-block a { display: block; } +/* Hero name glitch effect */ + +.hero-name { + font-family: var(--font-head); + font-size: clamp(3rem, 12vw, 7rem); + font-weight: 800; + line-height: 0.95; + letter-spacing: -0.04em; + color: var(--text); + text-shadow: 0 0 80px rgba(168,85,247,0.18), 0 0 120px rgba(168,85,247,0.08); + display: inline-block; + position: relative; + width: 100%; + margin-bottom: 1.5rem; +} + +html.theme-light .hero-name { + text-shadow: 0 0 80px rgba(124,58,237,0.12), 0 0 120px rgba(124,58,237,0.05); +} + +.hero-name::before, +.hero-name::after { + content: attr(data-text); + position: absolute; + top: 0; + left: 0; + width: 100%; + opacity: 0; + font-family: inherit; + font-size: inherit; + font-weight: inherit; + line-height: inherit; + letter-spacing: inherit; +} + +.hero-name::before { + color: #ff2b6d; +} + +.hero-name::after { + color: #00e5ff; +} + +.hero-name.is-glitching::before { + opacity: 0.8; + animation: glitch-red 0.45s steps(3) forwards; +} + +.hero-name.is-glitching::after { + opacity: 0.8; + animation: glitch-cyn 0.45s steps(3) forwards; +} + +@keyframes glitch-red { + 0% { + transform: translate(-5px, 1px); + clip-path: inset(8% 0 78% 0); + } + + 33% { + transform: translate(4px, -2px); + clip-path: inset(42% 0 38% 0); + } + + 66% { + transform: translate(-3px, 2px); + clip-path: inset(68% 0 12% 0); + } + + 100% { + transform: translate(0); + clip-path: inset(0 0 100% 0); + opacity: 0; + } +} + +@keyframes glitch-cyn { + 0% { + transform: translate(5px, -1px); + clip-path: inset(22% 0 62% 0); + } + + 33% { + transform: translate(-4px, 2px); + clip-path: inset(55% 0 28% 0); + } + + 66% { + transform: translate(3px, -2px); + clip-path: inset(15% 0 70% 0); + } + + 100% { + transform: translate(0); + clip-path: inset(0 0 100% 0); + opacity: 0; + } +} + +@media (prefers-reduced-motion: reduce) { + .hero-name::before, + .hero-name::after { + display: none; + } +} + .hover\:bg-surface:hover { background-color: var(--surface); } diff --git a/assets/js/hero-glitch.js b/assets/js/hero-glitch.js new file mode 100644 index 0000000..1b39b2f --- /dev/null +++ b/assets/js/hero-glitch.js @@ -0,0 +1,12 @@ +(function () { + var name = document.querySelector('.hero-name'); + if (!name) return; + if (window.matchMedia('(prefers-reduced-motion: reduce)').matches) return; + + function glitch() { + name.classList.add('is-glitching'); + setTimeout(function () { name.classList.remove('is-glitching'); }, 500); + setTimeout(glitch, 4000 + Math.random() * 7000); + } + setTimeout(glitch, 3500); +})(); diff --git a/layouts/_default/baseof.html b/layouts/_default/baseof.html index 3736a9f..20f428d 100644 --- a/layouts/_default/baseof.html +++ b/layouts/_default/baseof.html @@ -137,5 +137,11 @@ <!-- Contribution graph widget --> {{ $contribScript := resources.Get "js/contribution-graph.js" | minify }} <script src="{{ $contribScript.RelPermalink }}"></script> + + <!-- Hero glitch effect (homepage only) --> + {{ if .IsHome }} + {{ $heroScript := resources.Get "js/hero-glitch.js" | minify }} + <script src="{{ $heroScript.RelPermalink }}"></script> + {{ end }} </body> </html> diff --git a/layouts/index.html b/layouts/index.html index fd3cfa0..a76505a 100644 --- a/layouts/index.html +++ b/layouts/index.html @@ -1,23 +1,22 @@ {{ define "main" }} <section class="min-h-[calc(100vh-200px)] flex items-center justify-center px-4 py-12"> - <div class="max-w-4xl w-full"> - <!-- Profile Image (optional) --> - {{ if .Params.image }} - <div class="flex justify-center mb-8"> + <div class="max-w-4xl w-full text-center"> + + <!-- Gravatar --> + <div class="flex justify-center mb-6"> + {{- $email := .Site.Params.email -}} + {{- $hash := $email | lower | md5 -}} <img - src="{{ .Params.image }}" + src="https://www.gravatar.com/avatar/{{ $hash }}?s=192&d=mp" alt="{{ .Site.Params.author }}" loading="lazy" class="w-32 h-32 md:w-48 md:h-48 rounded-full border-4 border-accent object-cover" > </div> - {{ end }} - <!-- Author Name --> -<!-- <h1 class="text-4xl md:text-5xl font-bold text-accent text-center mb-4"> - {{ .Site.Params.author }} - </h1> - --> + <!-- Hero Name (glitch effect) --> + <h1 class="hero-name" data-text="{{ .Site.Params.author }}">{{ .Site.Params.author }}</h1> + <!-- Bio (from page content) --> <div class="text-xl text-text-dim text-center mb-8 leading-relaxed prose prose-invert max-w-none"> {{ .Content }} @@ -33,19 +32,10 @@ {{ $contactUrl = "/it/is/here/" }} {{ end }} - <!-- Articles Button (Primary) --> - <a - href="{{ $articlesUrl }}" - class="btn btn-primary btn-lg" - > + <a href="{{ $articlesUrl }}" class="btn btn-primary btn-lg"> {{ i18n "articles" }} </a> - - <!-- Contact Button (Outline) --> - <a - href="{{ $contactUrl }}" - class="btn btn-outline btn-lg" - > + <a href="{{ $contactUrl }}" class="btn btn-outline btn-lg"> {{ i18n "contact" }} </a> </div> @@ -54,6 +44,7 @@ <div class="mt-16 pt-8 border-t border-border"> {{ partial "tag-cloud.html" (dict "page" . "showCount" true "wrapInWidget" false) }} </div> + </div> </section> {{ end }} |
