summaryrefslogtreecommitdiffstats
path: root/themes
diff options
context:
space:
mode:
authorDanilo M. <danix@danix.xyz>2026-04-18 20:54:50 +0200
committerDanilo M. <danix@danix.xyz>2026-04-18 20:54:50 +0200
commit05f33a6e1059e84c309c5f674e094ed3b1105134 (patch)
treeb18378428ead69deecc636c384f561054d3fec45 /themes
parent7b645976739619faf514083e5c74bcf187ba93a1 (diff)
downloaddanixxyz-05f33a6e1059e84c309c5f674e094ed3b1105134.tar.gz
danixxyz-05f33a6e1059e84c309c5f674e094ed3b1105134.zip
feat: add prev/next article navigation with shell prompt style
Add top and bottom navigation between sequential articles with hacker aesthetic: - Top nav: [visitor@danix.xyz articles]$ cd - Bottom nav: [visitor@danix.xyz articles]$ ls ../ - Missing link shows dimmed placeholder (beginning/end) - Only renders on articles, not static pages - New partial: article-nav.html - Styling: monospace prompt in accent color, hover links with transition Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
Diffstat (limited to 'themes')
-rw-r--r--themes/danix-xyz-hacker/assets/css/main.css22
-rw-r--r--themes/danix-xyz-hacker/assets/css/main.min.css54
-rw-r--r--themes/danix-xyz-hacker/layouts/_default/single.html10
-rw-r--r--themes/danix-xyz-hacker/layouts/articles/single.html6
-rw-r--r--themes/danix-xyz-hacker/layouts/partials/article-nav.html46
5 files changed, 138 insertions, 0 deletions
diff --git a/themes/danix-xyz-hacker/assets/css/main.css b/themes/danix-xyz-hacker/assets/css/main.css
index f618f2d..298c38b 100644
--- a/themes/danix-xyz-hacker/assets/css/main.css
+++ b/themes/danix-xyz-hacker/assets/css/main.css
@@ -574,6 +574,28 @@ html.theme-light picture img[src="/images/default_thumbnail_dark.png"] {
.section-title {
font-size: clamp(1.5rem, 3vw + 0.5rem, 2.5rem);
}
+
+ /* ---- Article prev/next navigation ---- */
+ .article-nav {
+ @apply border-t border-border pt-6;
+ }
+
+ .article-nav-prompt {
+ @apply font-mono text-sm mb-2;
+ color: var(--accent);
+ }
+
+ .article-nav-links {
+ @apply flex justify-between items-center font-mono text-sm;
+ }
+
+ .article-nav-link {
+ @apply hover:text-accent transition-colors text-text;
+ }
+
+ .article-nav-placeholder {
+ @apply text-text-dim opacity-40;
+ }
}
/* 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 d928b7a..942d401 100644
--- a/themes/danix-xyz-hacker/assets/css/main.min.css
+++ b/themes/danix-xyz-hacker/assets/css/main.min.css
@@ -1632,6 +1632,56 @@ article.border.border-border\/30.rounded-lg.card.group.bg-bg {
/* Hero typography with fluid sizing */
+/* ---- Article prev/next navigation ---- */
+
+.article-nav {
+ border-color: var(--border);
+}
+
+
+ .frosted-bar.article-nav {
+ border-color: var(--border);
+}
+
+.article-nav {
+ border-top-width: 1px;
+ border-color: var(--border);
+ padding-top: 1.5rem;
+}
+
+.article-nav-prompt {
+ margin-bottom: 0.5rem;
+ font-family: JetBrains Mono, monospace;
+ font-size: 0.875rem;
+ line-height: 1.25rem;
+ color: var(--accent);
+}
+
+.article-nav-links {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ font-family: JetBrains Mono, monospace;
+ font-size: 0.875rem;
+ line-height: 1.25rem;
+}
+
+.article-nav-link {
+ color: var(--text);
+ transition-property: color, background-color, border-color, text-decoration-color, fill, stroke;
+ transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
+ transition-duration: 150ms;
+}
+
+.article-nav-link:hover {
+ color: var(--accent);
+}
+
+.article-nav-placeholder {
+ color: var(--text-dim);
+ opacity: 0.4;
+}
+
.sr-only {
position: absolute;
width: 1px;
@@ -1935,6 +1985,10 @@ article.border.border-border\/30.rounded-lg.card.group.bg-bg {
max-width: 80rem;
}
+.max-w-\[45\%\] {
+ max-width: 45%;
+}
+
.max-w-lg {
max-width: 32rem;
}
diff --git a/themes/danix-xyz-hacker/layouts/_default/single.html b/themes/danix-xyz-hacker/layouts/_default/single.html
index 0d3c6fa..62e4a64 100644
--- a/themes/danix-xyz-hacker/layouts/_default/single.html
+++ b/themes/danix-xyz-hacker/layouts/_default/single.html
@@ -3,6 +3,11 @@
<div class="grid md:grid-cols-3 gap-8 max-w-7xl mx-auto content-grid">
<!-- Article section -->
<div class="md:col-span-2">
+ <!-- Top article navigation (articles only) -->
+ {{ if eq .Section "articles" }}
+ {{ partial "article-nav.html" (dict "page" . "variant" "top") }}
+ {{ end }}
+
<!-- Breadcrumb -->
{{ partial "breadcrumb.html" . }}
@@ -35,6 +40,11 @@
</div>
</div>
{{ end }}
+
+ <!-- Bottom article navigation (articles only) -->
+ {{ if eq .Section "articles" }}
+ {{ partial "article-nav.html" (dict "page" . "variant" "bottom") }}
+ {{ end }}
</div>
<!-- Sidebar -->
diff --git a/themes/danix-xyz-hacker/layouts/articles/single.html b/themes/danix-xyz-hacker/layouts/articles/single.html
index 4e97fb3..e646639 100644
--- a/themes/danix-xyz-hacker/layouts/articles/single.html
+++ b/themes/danix-xyz-hacker/layouts/articles/single.html
@@ -5,6 +5,9 @@
<div class="grid md:grid-cols-3 gap-8 max-w-7xl mx-auto content-grid">
<!-- Article section -->
<div class="md:col-span-2">
+ <!-- Top article navigation -->
+ {{ partial "article-nav.html" (dict "page" . "variant" "top") }}
+
<!-- Breadcrumb -->
{{ partial "breadcrumb.html" . }}
@@ -35,6 +38,9 @@
</div>
</div>
{{ end }}
+
+ <!-- Bottom article navigation -->
+ {{ partial "article-nav.html" (dict "page" . "variant" "bottom") }}
</div>
<!-- Sidebar -->
diff --git a/themes/danix-xyz-hacker/layouts/partials/article-nav.html b/themes/danix-xyz-hacker/layouts/partials/article-nav.html
new file mode 100644
index 0000000..d7f8ca3
--- /dev/null
+++ b/themes/danix-xyz-hacker/layouts/partials/article-nav.html
@@ -0,0 +1,46 @@
+{{ $page := .page }}
+{{ $variant := .variant | default "bottom" }}
+{{ $prev := $page.PrevInSection }}
+{{ $next := $page.NextInSection }}
+
+{{/* Shell prompt command varies by position */}}
+{{ $cmd := "ls ../" }}
+{{ if eq $variant "top" }}
+ {{ $cmd = "cd" }}
+{{ end }}
+
+<nav class="article-nav {{ if eq $variant "bottom" }}mt-8{{ else }}mb-8{{ end }}"
+ aria-label="Article navigation">
+ <p class="article-nav-prompt" aria-hidden="true">
+ [visitor@danix.xyz articles]$ {{ $cmd }}
+ </p>
+ <div class="article-nav-links">
+ {{/* ---- Previous (left side) ---- */}}
+ {{ if $prev }}
+ <a href="{{ $prev.Permalink }}"
+ class="article-nav-link truncate max-w-[45%]"
+ rel="prev"
+ title="{{ $prev.Title }}">
+ ◄ {{ $prev.Title }}
+ </a>
+ {{ else }}
+ <span class="article-nav-placeholder" aria-label="Beginning of articles">
+ ◄ (beginning)
+ </span>
+ {{ end }}
+
+ {{/* ---- Next (right side) ---- */}}
+ {{ if $next }}
+ <a href="{{ $next.Permalink }}"
+ class="article-nav-link truncate max-w-[45%] text-right"
+ rel="next"
+ title="{{ $next.Title }}">
+ {{ $next.Title }} ►
+ </a>
+ {{ else }}
+ <span class="article-nav-placeholder text-right" aria-label="End of articles">
+ (end) ►
+ </span>
+ {{ end }}
+ </div>
+</nav>