From: Danilo M. Date: Tue, 21 Apr 2026 08:00:30 +0000 (+0200) Subject: chore: add back-to-top button planning and design docs, update local settings X-Git-Tag: release_22042026-1342~50 X-Git-Url: https://git.danix.xyz/?a=commitdiff_plain;h=5b1e212af64a1a7acef75ef24760b91eda481f43;p=danix.xyz-2.git chore: add back-to-top button planning and design docs, update local settings Co-Authored-By: Claude Haiku 4.5 --- diff --git a/.claude/settings.local.json b/.claude/settings.local.json index ab7c2d9..7eaaefd 100644 --- a/.claude/settings.local.json +++ b/.claude/settings.local.json @@ -17,7 +17,12 @@ "Bash(hugo config *)", "Bash(hugo --debug)", "Bash(hugo)", - "Bash(hugo -D)" + "Bash(hugo -D)", + "Bash(curl -s http://localhost:1313/)", + "Bash(curl -s http://localhost:1313/articles/haiku-2/)", + "Bash(curl -s http://localhost:1313/articles/)", + "Bash(curl -s http://localhost:1313/css/main.min.css)", + "Bash(hugo version *)" ] } } diff --git a/docs/superpowers/plans/2026-04-20-back-to-top-button.md b/docs/superpowers/plans/2026-04-20-back-to-top-button.md new file mode 100644 index 0000000..e61aad2 --- /dev/null +++ b/docs/superpowers/plans/2026-04-20-back-to-top-button.md @@ -0,0 +1,220 @@ +# Back-to-Top Button Implementation Plan + +> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. + +**Goal:** Add a fixed bottom-right back-to-top button that appears after 33% scroll depth on article/single pages, with slide-up animation, full accessibility, and hacker-theme styling. + +**Architecture:** A new `back-to-top.html` partial uses inline Alpine.js `x-data` with `@scroll.window` to track scroll depth; the button is conditionally included in `baseof.html` on `.Kind "page"` pages (same condition as reading progress bar). CSS lives in a new `.back-to-top` component class in `main.css`. + +**Tech Stack:** Hugo partials, Alpine.js 3.x (inline x-data), Tailwind CSS (@apply), Feather Icons (chevron-up inlined SVG) + +--- + +## File Map + +| Action | File | Responsibility | +|---|---|---| +| Create | `themes/danix-xyz-hacker/layouts/partials/back-to-top.html` | Button markup + Alpine logic | +| Modify | `themes/danix-xyz-hacker/assets/css/main.css` | `.back-to-top` component class | +| Modify | `themes/danix-xyz-hacker/layouts/_default/baseof.html` | Include partial on `.Kind "page"` | +| Modify | `themes/danix-xyz-hacker/i18n/en.yaml` | `back_to_top` key | +| Modify | `themes/danix-xyz-hacker/i18n/it.yaml` | `back_to_top` key (Italian) | + +--- + +### Task 1: Add `.back-to-top` CSS component class + +**Files:** +- Modify: `themes/danix-xyz-hacker/assets/css/main.css` (append inside `@layer components`, after `.toast-container`) + +- [ ] **Step 1: Open `main.css` and locate the end of `@layer components`** + +Find the closing `}` of `@layer components`. It ends around line 1165 (after `.tooltip-text`). Add the new class block just before that closing brace. + +- [ ] **Step 2: Add the `.back-to-top` class** + +```css + /* Back to top button */ + .back-to-top { + @apply fixed bottom-6 right-6 z-40 w-11 h-11 rounded-full flex items-center justify-content-center; + background: var(--accent); + box-shadow: 0 0 12px rgba(168, 85, 247, 0.4); + transition: background 200ms ease, box-shadow 200ms ease; + color: #fff; + } + .back-to-top:hover { + background: #9333ea; + box-shadow: 0 0 20px var(--accent); + } + .back-to-top:focus-visible { + outline: 2px solid var(--accent); + outline-offset: 2px; + } +``` + +- [ ] **Step 3: Rebuild CSS** + +```bash +cd /home/danix/Programming/GIT/danix.xyz-hacker-theme && npm run build +``` + +Expected: exits 0, `themes/danix-xyz-hacker/static/css/main.min.css` updated. + +- [ ] **Step 4: Commit** + +```bash +git add themes/danix-xyz-hacker/assets/css/main.css themes/danix-xyz-hacker/static/css/main.min.css +git commit -m "style: add .back-to-top component class" +``` + +--- + +### Task 2: Create `back-to-top.html` partial + +**Files:** +- Create: `themes/danix-xyz-hacker/layouts/partials/back-to-top.html` + +- [ ] **Step 1: Create the partial file** + +```html +
+ +
+``` + +Note: SVG is Feather `chevron-up` inlined to avoid race condition with `feather.replace()` running before Alpine shows the button. `aria-hidden="true"` on the SVG because the button has `aria-label`. + +- [ ] **Step 2: Add i18n keys** + +In `themes/danix-xyz-hacker/i18n/en.yaml`, add: +```yaml +back_to_top: "Back to top" +``` + +In `themes/danix-xyz-hacker/i18n/it.yaml`, add: +```yaml +back_to_top: "Torna in cima" +``` + +- [ ] **Step 3: Commit** + +```bash +git add themes/danix-xyz-hacker/layouts/partials/back-to-top.html themes/danix-xyz-hacker/i18n/en.yaml themes/danix-xyz-hacker/i18n/it.yaml +git commit -m "feat: add back-to-top partial with Alpine.js and i18n" +``` + +--- + +### Task 3: Include partial in `baseof.html` + +**Files:** +- Modify: `themes/danix-xyz-hacker/layouts/_default/baseof.html` + +- [ ] **Step 1: Locate the `.Kind "page"` block for reading-progress (lines ~28–34)** + +```html +{{ if eq .Kind "page" }} +
+{{ end }} +``` + +- [ ] **Step 2: Add the partial include inside the same condition block** + +```html +{{ if eq .Kind "page" }} +
+{{ partial "back-to-top.html" . }} +{{ end }} +``` + +- [ ] **Step 3: Commit** + +```bash +git add themes/danix-xyz-hacker/layouts/_default/baseof.html +git commit -m "feat: include back-to-top button on single pages" +``` + +--- + +### Task 4: Verify end-to-end + +- [ ] **Step 1: Start Hugo dev server** + +```bash +cd /home/danix/Programming/GIT/danix.xyz-hacker-theme && hugo server -D +``` + +- [ ] **Step 2: Open an article page and scroll past 33%** + +Navigate to any article. Confirm the purple circle button slides up from bottom-right. + +- [ ] **Step 3: Scroll back above 33%** + +Confirm button fades/slides out. + +- [ ] **Step 4: Click button** + +Confirm smooth scroll to top. + +- [ ] **Step 5: Keyboard accessibility** + +Tab to the button when visible. Confirm focus ring (purple outline). Press Enter — confirm scroll to top. + +- [ ] **Step 6: Reduced motion** + +DevTools → Rendering → "Emulate prefers-reduced-motion: reduce". Scroll past 33% — button appears instantly (no animation). Click — page jumps instantly (no smooth scroll). + +- [ ] **Step 7: z-index layering** + +Confirm button sits below fixed header, search modal, and toast notifications. + +- [ ] **Step 8: Non-article pages** + +Navigate to home or list page. Confirm no button appears. + +- [ ] **Step 9: Final CSS rebuild and commit** + +```bash +npm run build +git add themes/danix-xyz-hacker/static/css/main.min.css +git commit -m "build: rebuild CSS for back-to-top button" +``` + +- [ ] **Step 10: Update TODO.md** + +```markdown +- [✅] add back-to-top button +``` + +```bash +git add TODO.md +git commit -m "chore: mark back-to-top as complete in TODO" +``` diff --git a/docs/superpowers/specs/2026-04-20-back-to-top-button-design.md b/docs/superpowers/specs/2026-04-20-back-to-top-button-design.md new file mode 100644 index 0000000..bc5959f --- /dev/null +++ b/docs/superpowers/specs/2026-04-20-back-to-top-button-design.md @@ -0,0 +1,133 @@ +# Back-to-Top Button — Design Spec + +**Date:** 2026-04-20 +**Status:** Approved + +--- + +## Context + +The TODO list includes "add back-to-top button". Article pages can be long and users currently have no quick way to return to the top. The button should integrate cleanly with the existing hacker-aesthetic theme, follow Alpine.js patterns already in use, and meet WCAG 2.1 AA accessibility standards. + +--- + +## Design Decisions + +| Decision | Choice | Rationale | +|---|---|---| +| Position | Fixed bottom-right | Conventional, expected UX | +| Shape | Circle solid | Consistent with theme energy; always-visible purple matches accent | +| Trigger | 33% scroll depth | Balanced — not too early, not too late | +| Animation | Slide up + fade (300ms) | Reuses existing `slideUp` keyframe | +| Pages | `.Kind "page"` only | Articles and singles — same condition as reading progress bar | +| Implementation | Inline Alpine.js in a partial | Consistent with `social-share.html`, `header.html` patterns | + +--- + +## Behaviour + +- **Appears** when `window.scrollY / (document.documentElement.scrollHeight - window.innerHeight) >= 0.33` +- **Disappears** when scroll drops back below 33% +- **On click**: smooth-scrolls to top (`window.scrollTo({ top: 0, behavior: 'smooth' })`) +- **Reduced motion**: CSS global `prefers-reduced-motion` rule already suppresses all animations; the button still appears/disappears (via Alpine `x-show`) but without the slide animation. The `smooth` scroll behavior should also be skipped — handled in the click handler by checking `window.matchMedia('(prefers-reduced-motion: reduce)').matches`. +- **z-index**: `z-40` — sits below toasts (`z-50`), modals (`z-50`), and reading progress bar (`z-9999`). Toasts stack above it naturally. + +--- + +## Visual Spec + +``` +Position: fixed bottom-6 right-6 (24px from edges) +Size: 44×44px circle +Default: bg: var(--accent) #a855f7, glow: box-shadow 0 0 12px rgba(168,85,247,0.4) +Hover: bg: #9333ea (one shade darker), glow: box-shadow 0 0 20px var(--accent) +Icon: Feather Icons `chevron-up` (already loaded globally via CDN) +Entrance: slideUp keyframe, 300ms ease-out +Exit: opacity fade (Alpine x-show transition), 200ms +``` + +--- + +## Accessibility + +- `aria-label="Back to top"` on the button element +- `role="button"` implicit (native ` + +``` + +**`.back-to-top` CSS class** (added to `main.css` `@layer components`): +```css +.back-to-top { + @apply fixed bottom-6 right-6 z-40 w-11 h-11 rounded-full flex items-center justify-center; + background: var(--accent); + box-shadow: 0 0 12px rgba(168, 85, 247, 0.4); + transition: background 200ms ease, box-shadow 200ms ease; + color: #fff; +} +.back-to-top:hover { + background: #9333ea; + box-shadow: 0 0 20px var(--accent); +} +.back-to-top:focus-visible { + outline: 2px solid var(--accent); + outline-offset: 2px; +} +``` + +--- + +## Verification + +1. Start Hugo dev server (`hugo server`) +2. Open any article page +3. Scroll past 33% — button slides up from bottom-right +4. Scroll back up — button disappears +5. Click button — smooth scroll to top +6. Tab to button — focus ring visible +7. Press Enter while focused — smooth scroll to top +8. Test with `prefers-reduced-motion: reduce` in browser devtools — button appears without animation, click scrolls instantly +9. Confirm toasts (if triggered) render above the button +10. Check on mobile (narrow viewport) — button sits at bottom-right without overlapping content