main
html 143 lines 5.66 KB
Raw
1 {{- if not (.Param "hideFooter") }}
2 <footer class="footer site-footer" aria-label="Site footer">
3 <div class="site-footer__inner">
4 <p class="site-footer__tagline"><strong>Claracle</strong> — Weekly tech signal from GitHub.</p>
5 {{ partial "ai-disclosure.html" . }}
6 <nav class="site-footer__nav" aria-label="Footer">
7 <a href="{{ "privacy/" | absLangURL }}">Privacy</a>
8 <button type="button" class="site-footer__link" onclick="CookieConsent.showPreferences()">Manage cookies</button>
9 <a href="https://github.com/jmservera/SquadScope" target="_blank" rel="noopener">GitHub</a>
10 <a href="{{ "index.xml" | absLangURL }}">RSS</a>
11 <a href="{{ "archive/" | absLangURL }}">Archive</a>
12 {{- with site.Params.podcast_url | strings.TrimSpace }}
13 <a href="{{ . | safeURL }}" target="_blank" rel="noopener noreferrer">Podcast</a>
14 {{- end }}
15 </nav>
16 <p class="site-footer__meta">© 2026 jmservera · Generated 2026-05-25 · Powered by <a href="https://gohugo.io/?utm_source=squadscope" rel="noopener" target="_blank">Hugo</a></p>
17 </div>
18 </footer>
19 {{- end }}
20
21 {{- if (not site.Params.disableScrollToTop) }}
22 <a href="#top" id="top-link" class="top-link hidden" aria-label="Go to top" title="Go to Top (Alt + G)" accesskey="g">
23 <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
24 stroke-linecap="round" stroke-linejoin="round" class="feather feather-chevrons-up" aria-hidden="true">
25 <polyline points="17 11 12 6 7 11"></polyline>
26 <polyline points="17 18 12 13 7 18"></polyline>
27 </svg>
28 </a>
29 {{- end }}
30
31 {{- partial "extend_footer.html" . }}
32
33 <script>
34 const menu = document.getElementById('menu');
35 if (menu) {
36 const scrollPosition = localStorage.getItem("menu-scroll-position");
37 if (scrollPosition) {
38 menu.scrollLeft = parseInt(scrollPosition, 10);
39 }
40
41 menu.onscroll = function () {
42 localStorage.setItem("menu-scroll-position", menu.scrollLeft);
43 };
44 }
45
46 document.querySelectorAll('a[href^="#"]').forEach(anchor => {
47 anchor.addEventListener("click", function (e) {
48 const id = this.getAttribute("href").slice(1);
49 const target = document.querySelector(`[id='${decodeURIComponent(id)}']`);
50 if (!target) return;
51
52 e.preventDefault();
53 if (!window.matchMedia('(prefers-reduced-motion: reduce)').matches) {
54 target.scrollIntoView({ behavior: "smooth" });
55 } else {
56 target.scrollIntoView();
57 }
58 if (id === "top") {
59 history.replaceState(null, null, " ");
60 } else {
61 history.pushState(null, null, `#${id}`);
62 }
63 if (id === "main-content") {
64 target.focus({ preventScroll: true });
65 }
66 });
67 });
68 </script>
69
70 {{- if (not site.Params.disableScrollToTop) }}
71 <script>
72 const toplink = document.getElementById("top-link");
73 window.onscroll = function () {
74 const scrollThreshold = window.innerHeight;
75 if (document.body.scrollTop > scrollThreshold || document.documentElement.scrollTop > scrollThreshold) {
76 toplink.classList.remove("hidden");
77 } else {
78 toplink.classList.add("hidden");
79 }
80 };
81 </script>
82 {{- end }}
83
84 {{- if (not site.Params.disableThemeToggle) }}
85 <script>
86 document.getElementById("theme-toggle")?.addEventListener("click", () => {
87 const html = document.querySelector("html");
88 if (html.dataset.theme === "dark") {
89 html.dataset.theme = 'light';
90 localStorage.setItem("pref-theme", 'light');
91 } else {
92 html.dataset.theme = 'dark';
93 localStorage.setItem("pref-theme", 'dark');
94 }
95 });
96 </script>
97 {{- end }}
98
99 {{- if (and (eq .Kind "page") (ne .Layout "archives") (ne .Layout "search") (.Param "ShowCodeCopyButtons")) }}
100 <script>
101 document.querySelectorAll('pre > code').forEach((codeblock) => {
102 const container = codeblock.parentNode.parentNode;
103 const copybutton = document.createElement('button');
104 copybutton.classList.add('copy-code');
105 copybutton.innerHTML = '{{- i18n "code_copy" | default "copy" }}';
106
107 function copyingDone() {
108 copybutton.innerHTML = '{{- i18n "code_copied" | default "copied!" }}';
109 setTimeout(() => {
110 copybutton.innerHTML = '{{- i18n "code_copy" | default "copy" }}';
111 }, 2000);
112 }
113
114 copybutton.addEventListener('click', () => {
115 if ('clipboard' in navigator) {
116 navigator.clipboard.writeText(codeblock.textContent);
117 copyingDone();
118 return;
119 }
120
121 const range = document.createRange();
122 range.selectNodeContents(codeblock);
123 const selection = window.getSelection();
124 selection.removeAllRanges();
125 selection.addRange(range);
126 try {
127 document.execCommand('copy');
128 copyingDone();
129 } catch (e) { };
130 selection.removeRange(range);
131 });
132
133 if (container.classList.contains("highlight")) {
134 container.appendChild(copybutton);
135 } else if (container.parentNode.firstChild == container) {
136 } else if (codeblock.parentNode.parentNode.parentNode.parentNode.parentNode.nodeName == "TABLE") {
137 codeblock.parentNode.parentNode.parentNode.parentNode.parentNode.appendChild(copybutton);
138 } else {
139 codeblock.parentNode.appendChild(copybutton);
140 }
141 });
142 </script>
143 {{- end }}