summaryrefslogtreecommitdiffstats
path: root/themes
diff options
context:
space:
mode:
authorDanilo M. <danix@danix.xyz>2026-04-20 12:46:49 +0200
committerDanilo M. <danix@danix.xyz>2026-04-20 12:46:49 +0200
commit133a26b48c13c2ca6ffa01624552d995b5ab8fab (patch)
treeb83f8e54c4ce12828c3264cf280976b42cd2555f /themes
parent9140e36f40918f774ad2aaf28c2b9b17db2a831d (diff)
downloaddanixxyz-133a26b48c13c2ca6ffa01624552d995b5ab8fab.tar.gz
danixxyz-133a26b48c13c2ca6ffa01624552d995b5ab8fab.zip
feat: redesign footer with fortune cookie, about terminal readout, and tech/feature badges
New footer structure: 3 equal columns (Fortune Cookie | About Credentials | Stack & Features badges) + full-width copyright bar with emoji personality line. Fortune Cookie: - data/quotes.yaml with 13 curated quotes - fortune.js picks random quote on each page load - HTML fallback shows first quote with no-JS - aria-live="polite" announces quote to screen readers About Column: - Terminal readout style with key-value pairs - role, cert (green), os, focus fields - Semantic <dl> structure for accessibility Badges Column: - "built with" section: Hugo, Tailwind, Alpine.js, HTML5, CSS3, JS (purple badges) - "features" section: WCAG 2.1 AA, Open Source, Privacy Friendly, Claude Code (green badges) - New badge-footer-accent/accent2 CSS classes Copyright Bar: - "Made with ❤️ lack of 😴 lots of ☕ by danix" with emoji wrapped in aria-hidden - danix link points to language-aware About page (/is/ or /it/is/) - Centered, full-width, below border-top i18n additions: - footer_built_with, footer_features keys in English and Italian Theming: - All colors use CSS custom properties (--accent, --accent2, --text, --text-dim) - Monospace fonts throughout (JetBrains Mono) - Responsive: grid-cols-1 mobile → md:grid-cols-3 tablet+ - WCAG 2.1 AA compliant: ≥4.5:1 contrast ratios, keyboard accessible, screen reader tested Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
Diffstat (limited to 'themes')
-rw-r--r--themes/danix-xyz-hacker/assets/css/main.css15
-rw-r--r--themes/danix-xyz-hacker/assets/css/main.min.css81
-rw-r--r--themes/danix-xyz-hacker/assets/js/fortune.js9
-rw-r--r--themes/danix-xyz-hacker/layouts/partials/footer.html87
4 files changed, 170 insertions, 22 deletions
diff --git a/themes/danix-xyz-hacker/assets/css/main.css b/themes/danix-xyz-hacker/assets/css/main.css
index 298c38b..163505f 100644
--- a/themes/danix-xyz-hacker/assets/css/main.css
+++ b/themes/danix-xyz-hacker/assets/css/main.css
@@ -596,6 +596,21 @@ html.theme-light picture img[src="/images/default_thumbnail_dark.png"] {
.article-nav-placeholder {
@apply text-text-dim opacity-40;
}
+
+ /* ---- Footer badge variants ---- */
+ .badge-footer-accent {
+ @apply inline-flex items-center px-2.5 py-1 rounded text-xs font-mono font-semibold whitespace-nowrap;
+ border: 1px solid rgba(168, 85, 247, 0.35);
+ background: rgba(168, 85, 247, 0.1);
+ color: var(--accent);
+ }
+
+ .badge-footer-accent2 {
+ @apply inline-flex items-center px-2.5 py-1 rounded text-xs font-mono font-semibold whitespace-nowrap;
+ border: 1px solid rgba(0, 255, 136, 0.35);
+ background: rgba(0, 255, 136, 0.1);
+ color: var(--accent2);
+ }
}
/* Prose overrides for light theme */
diff --git a/themes/danix-xyz-hacker/assets/css/main.min.css b/themes/danix-xyz-hacker/assets/css/main.min.css
index 942d401..4e6e482 100644
--- a/themes/danix-xyz-hacker/assets/css/main.min.css
+++ b/themes/danix-xyz-hacker/assets/css/main.min.css
@@ -1284,6 +1284,10 @@ button,
color: var(--accent);
}
+.text-accent2 {
+ color: var(--accent2);
+}
+
.text-text {
color: var(--text);
}
@@ -1682,6 +1686,44 @@ article.border.border-border\/30.rounded-lg.card.group.bg-bg {
opacity: 0.4;
}
+/* ---- Footer badge variants ---- */
+
+.badge-footer-accent {
+ display: inline-flex;
+ align-items: center;
+ white-space: nowrap;
+ border-radius: 0.25rem;
+ padding-left: 0.625rem;
+ padding-right: 0.625rem;
+ padding-top: 0.25rem;
+ padding-bottom: 0.25rem;
+ font-family: JetBrains Mono, monospace;
+ font-size: 0.75rem;
+ line-height: 1rem;
+ font-weight: 600;
+ border: 1px solid rgba(168, 85, 247, 0.35);
+ background: rgba(168, 85, 247, 0.1);
+ color: var(--accent);
+}
+
+.badge-footer-accent2 {
+ display: inline-flex;
+ align-items: center;
+ white-space: nowrap;
+ border-radius: 0.25rem;
+ padding-left: 0.625rem;
+ padding-right: 0.625rem;
+ padding-top: 0.25rem;
+ padding-bottom: 0.25rem;
+ font-family: JetBrains Mono, monospace;
+ font-size: 0.75rem;
+ line-height: 1rem;
+ font-weight: 600;
+ border: 1px solid rgba(0, 255, 136, 0.35);
+ background: rgba(0, 255, 136, 0.1);
+ color: var(--accent2);
+}
+
.sr-only {
position: absolute;
width: 1px;
@@ -1807,6 +1849,10 @@ article.border.border-border\/30.rounded-lg.card.group.bg-bg {
margin-bottom: 2rem;
}
+.mb-1 {
+ margin-bottom: 0.25rem;
+}
+
.mb-12 {
margin-bottom: 3rem;
}
@@ -1957,6 +2003,10 @@ article.border.border-border\/30.rounded-lg.card.group.bg-bg {
width: 0.25rem;
}
+.w-20 {
+ width: 5rem;
+}
+
.w-32 {
width: 8rem;
}
@@ -2013,6 +2063,10 @@ article.border.border-border\/30.rounded-lg.card.group.bg-bg {
flex-shrink: 0;
}
+.shrink-0 {
+ flex-shrink: 0;
+}
+
.translate-x-0 {
--tw-translate-x: 0px;
transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
@@ -2067,6 +2121,10 @@ article.border.border-border\/30.rounded-lg.card.group.bg-bg {
gap: 0.25rem;
}
+.gap-1\.5 {
+ gap: 0.375rem;
+}
+
.gap-2 {
gap: 0.5rem;
}
@@ -2087,6 +2145,12 @@ article.border.border-border\/30.rounded-lg.card.group.bg-bg {
gap: 2rem;
}
+.space-y-1 > :not([hidden]) ~ :not([hidden]) {
+ --tw-space-y-reverse: 0;
+ margin-top: calc(0.25rem * calc(1 - var(--tw-space-y-reverse)));
+ margin-bottom: calc(0.25rem * var(--tw-space-y-reverse));
+}
+
.space-y-2 > :not([hidden]) ~ :not([hidden]) {
--tw-space-y-reverse: 0;
margin-top: calc(0.5rem * calc(1 - var(--tw-space-y-reverse)));
@@ -2229,6 +2293,11 @@ article.border.border-border\/30.rounded-lg.card.group.bg-bg {
padding: 2rem;
}
+.px-1 {
+ padding-left: 0.25rem;
+ padding-right: 0.25rem;
+}
+
.px-2 {
padding-left: 0.5rem;
padding-right: 0.5rem;
@@ -2401,6 +2470,10 @@ article.border.border-border\/30.rounded-lg.card.group.bg-bg {
color: var(--accent);
}
+.text-accent2 {
+ color: var(--accent2);
+}
+
.text-bg {
color: var(--bg);
}
@@ -3650,6 +3723,10 @@ article.toast.border-border\/30.rounded-lg.overflow-hidden.group.bg-bg {
color: var(--accent);
}
+.hover\:text-accent2:hover {
+ color: var(--accent2);
+}
+
.hover\:text-text:hover {
color: var(--text);
}
@@ -3698,6 +3775,10 @@ article.toast.border-border\/30.rounded-lg.overflow-hidden.group.bg-bg {
color: var(--accent);
}
+.hover\:text-accent2:hover {
+ color: var(--accent2);
+}
+
.hover\:text-text:hover {
color: var(--text);
}
diff --git a/themes/danix-xyz-hacker/assets/js/fortune.js b/themes/danix-xyz-hacker/assets/js/fortune.js
new file mode 100644
index 0000000..d4f981b
--- /dev/null
+++ b/themes/danix-xyz-hacker/assets/js/fortune.js
@@ -0,0 +1,9 @@
+(function() {
+ const el = document.getElementById('fortune-quote');
+ if (!el) return;
+ const quotes = JSON.parse(el.dataset.quotes);
+ if (!quotes || quotes.length === 0) return;
+ const q = quotes[Math.floor(Math.random() * quotes.length)];
+ el.querySelector('.fortune-text').textContent = '"' + q.text + '"';
+ el.querySelector('.fortune-author').textContent = '— ' + q.author;
+})();
diff --git a/themes/danix-xyz-hacker/layouts/partials/footer.html b/themes/danix-xyz-hacker/layouts/partials/footer.html
index c649e84..006714b 100644
--- a/themes/danix-xyz-hacker/layouts/partials/footer.html
+++ b/themes/danix-xyz-hacker/layouts/partials/footer.html
@@ -1,38 +1,81 @@
+{{- $quotes := .Site.Data.quotes.quotes -}}
+
<footer class="mt-16 frosted-bar border-t py-12 relative z-20">
<div class="container mx-auto px-4">
- <div class="grid md:grid-cols-3 gap-8 mb-8">
- <!-- About -->
+ <div class="grid grid-cols-1 md:grid-cols-3 gap-8 mb-8">
+
+ <!-- Column 1: Fortune Cookie -->
<div>
- <h3 class="font-bold text-accent mb-3 font-oxanium">{{ .Site.Title }}</h3>
- <p class="text-sm text-text-dim">{{ .Site.Params.siteDescription }}</p>
+ <p class="font-mono text-xs text-text-dim mb-2">$ fortune danix</p>
+ <div id="fortune-quote" aria-live="polite" data-quotes='{{ $quotes | jsonify }}'>
+ <blockquote>
+ <p class="fortune-text font-mono text-sm text-text italic leading-relaxed">
+ "{{ (index $quotes 0).text }}"
+ </p>
+ <cite class="fortune-author font-mono text-xs text-text-dim not-italic mt-2 block">
+ — {{ (index $quotes 0).author }}
+ </cite>
+ </blockquote>
+ </div>
</div>
- <!-- Quick links -->
+ <!-- Column 2: About (Terminal Readout) -->
<div>
- <h4 class="font-semibold text-accent mb-3">{{ i18n "links" }}</h4>
- <ul class="space-y-2">
- {{ range .Site.Menus.main }}
- <li>
- <a href="{{ .URL }}" class="text-sm text-text-dim hover:text-accent transition-colors">
- {{ i18n .Name }}
- </a>
- </li>
- {{ end }}
- </ul>
+ <dl class="space-y-1">
+ <div class="flex gap-2">
+ <dt class="text-text-dim font-mono text-xs w-20 shrink-0">role:</dt>
+ <dd class="text-text font-mono text-xs">Cybersecurity Specialist</dd>
+ </div>
+ <div class="flex gap-2">
+ <dt class="text-text-dim font-mono text-xs w-20 shrink-0">cert:</dt>
+ <dd class="text-accent2 font-mono text-xs font-semibold">eJPT</dd>
+ </div>
+ <div class="flex gap-2">
+ <dt class="text-text-dim font-mono text-xs w-20 shrink-0">os:</dt>
+ <dd class="text-text font-mono text-xs">Slackware <span class="text-text-dim">(2005–present)</span></dd>
+ </div>
+ <div class="flex gap-2">
+ <dt class="text-text-dim font-mono text-xs w-20 shrink-0">focus:</dt>
+ <dd class="text-text font-mono text-xs">open-source · privacy</dd>
+ </div>
+ </dl>
</div>
- <!-- Social (if configured) -->
+ <!-- Column 3: Stack & Feature Badges -->
<div>
- <h4 class="font-semibold text-accent mb-3">{{ i18n "contact" }}</h4>
- <a href="mailto:{{ .Site.Params.email }}" class="text-sm text-text-dim hover:text-accent transition-colors">
- {{ i18n "email" }}: {{ .Site.Params.email }}
- </a>
+ <p class="text-text-dim font-mono text-xs mb-1">{{ i18n "footer_built_with" }}</p>
+ <div class="flex flex-wrap gap-1.5 mb-3">
+ <span class="badge-footer-accent">Hugo</span>
+ <span class="badge-footer-accent">Tailwind CSS</span>
+ <span class="badge-footer-accent">Alpine.js</span>
+ <span class="badge-footer-accent">HTML5</span>
+ <span class="badge-footer-accent">CSS3</span>
+ <span class="badge-footer-accent">JavaScript</span>
+ </div>
+
+ <p class="text-text-dim font-mono text-xs mb-1">{{ i18n "footer_features" }}</p>
+ <div class="flex flex-wrap gap-1.5">
+ <span class="badge-footer-accent2">WCAG 2.1 AA</span>
+ <span class="badge-footer-accent2">Open Source</span>
+ <span class="badge-footer-accent2">Privacy Friendly</span>
+ <span class="badge-footer-accent2">Claude Code</span>
+ </div>
</div>
</div>
- <!-- Copyright -->
- <div class="pt-8 border-t border-border text-center text-xs text-text-dim">
+ <!-- Copyright Bar -->
+ <div class="pt-8 border-t border-border text-center text-xs text-text-dim space-y-1">
+ <p>
+ Made with <span aria-hidden="true">❤️</span><span class="sr-only">love</span>,
+ lack of <span aria-hidden="true">😴</span><span class="sr-only">sleep</span>,
+ lots of <span aria-hidden="true">☕</span><span class="sr-only">coffee</span>
+ by <a href="{{ .Site.LanguagePrefix }}/is/" class="text-accent hover:text-accent2 transition-colors py-2 px-1">danix</a>
+ </p>
<p>&copy; {{ now.Year }} {{ .Site.Params.author }}. {{ i18n "allRightsReserved" }}</p>
</div>
</div>
+
+ <!-- Fortune.js: Pick a random quote on each page load -->
+ {{- $fortuneJS := resources.Get "js/fortune.js" | minify -}}
+ <script src="{{ $fortuneJS.RelPermalink }}"></script>
</footer>