--- /dev/null
+<div
+ x-data="{ visible: false }"
+ @scroll.window="visible = (window.scrollY / (document.documentElement.scrollHeight - window.innerHeight)) >= 0.33"
+>
+ <button
+ x-show="visible"
+ x-cloak
+ x-transition:enter="transition ease-out duration-300"
+ x-transition:enter-start="opacity-0 translate-y-4"
+ x-transition:enter-end="opacity-100 translate-y-0"
+ x-transition:leave="transition ease-in duration-200"
+ x-transition:leave-start="opacity-100 translate-y-0"
+ x-transition:leave-end="opacity-0 translate-y-4"
+ class="back-to-top"
+ aria-label="{{ i18n "back_to_top" | default "Back to top" }}"
+ type="button"
+ @click="window.scrollTo({ top: 0, behavior: window.matchMedia('(prefers-reduced-motion: reduce)').matches ? 'auto' : 'smooth' })"
+ >
+ <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
+ <polyline points="18 15 12 9 6 15"></polyline>
+ </svg>
+ </button>
+</div>