Initial commit: personal homepage with live Harbor registry
build / image (push) Failing after 15s

- Linktree-style homepage with photo, social links, and self-hosted
  services (container registry, Git server)
- Registry pages rendered on demand from Harbor via a live content
  collection, cached in memory (60s fresh, 10min stale-while-revalidate)
- Pinned registry images (PINNED_IMAGES) shown first with a star
- Node standalone server with security headers; self-contained server
  build so the Docker image ships no node_modules
- Gitea workflow building multi-arch images for Flux

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-09-29 10:23:02 +02:00
co-authored by Claude Opus 5.5
commit 7b670010b1
33 changed files with 5004 additions and 0 deletions
+50
View File
@@ -0,0 +1,50 @@
---
interface Props {
text: string;
label?: string;
}
const { text, label = 'Copy' } = Astro.props;
---
<copy-button data-text={text}>
<button type="button" aria-label={`${label}: ${text}`} hidden>{label}</button>
</copy-button>
<script>
// Progressive enhancement: the button only appears when the Clipboard API is available.
class CopyButton extends HTMLElement {
connectedCallback() {
const button = this.querySelector('button');
const text = this.dataset.text;
if (!button || !text || !navigator.clipboard) return;
button.hidden = false;
const original = button.textContent;
button.addEventListener('click', async () => {
await navigator.clipboard.writeText(text);
button.textContent = 'Copied';
setTimeout(() => (button.textContent = original), 1500);
});
}
}
customElements.define('copy-button', CopyButton);
</script>
<style>
button {
font: inherit;
font-size: 0.8rem;
padding: 0.2rem 0.6rem;
border: 1px solid var(--border);
border-radius: var(--radius);
background: var(--surface);
color: var(--text);
cursor: pointer;
}
button:hover {
border-color: var(--accent);
}
</style>