diff --git a/.gitignore b/.gitignore index 032c022..7cb1adf 100644 --- a/.gitignore +++ b/.gitignore @@ -12,6 +12,9 @@ node_modules .DS_Store Thumbs.db +# Claude Code +.claude/ + # Env .env .env.* diff --git a/AGENTS.md b/AGENTS.md index 77c1401..83c08c8 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -25,6 +25,10 @@ Guidance for ewancroft.uk, a SvelteKit 2/Svelte 5 site deployed to Vercel's Node - `ATPROTO_APP_PASSWORD`, `KOFI_VERIFICATION_TOKEN`, `GITHUB_WEBHOOK_SECRET`, `GITHUB_TOKEN`, and any future server credential are private. `PUBLIC_*` values are bundled. Keep `.env.example` and README accurate without inserting real values; note that the current examples omit several webhook/write variables. - Public endpoints must validate/query-cap inputs, avoid leaking upstream error bodies or credentials, and set caching that matches data mutability. OG text is bounded, but font/WASM initialization, CPU/memory cost, cache cardinality, and error responses still need abuse testing. +## Identity + +- `static/pgp-key.asc` is Ewan's public PGP key, served verbatim at `/pgp-key.asc` and linked/fingerprinted from the Identity section of `src/routes/about/+page.svelte` (`pgpFingerprint` constant). It is intentionally public and committed; only ever replace it with a new public key export, never a private key. + ## UI and working conventions - Reuse the OKLCH tokens and existing components. Keep the “traditional meets technical” register, Sabbat/seasonal behavior, responsive layout, semantic headings/links/buttons, visible focus, reduced motion, contrast, and minimal client JavaScript. diff --git a/src/lib/styles/pages.css b/src/lib/styles/pages.css index b979aa6..8801cd9 100644 --- a/src/lib/styles/pages.css +++ b/src/lib/styles/pages.css @@ -627,6 +627,13 @@ max-width: 100%; } + .id-pgp { + display: flex; + flex-direction: column; + align-items: flex-start; + gap: var(--space-2xs); + } + /* Copy button (about + support) */ .copy-btn { align-self: flex-start; diff --git a/src/routes/about/+page.svelte b/src/routes/about/+page.svelte index 4c2a324..686fcd2 100644 --- a/src/routes/about/+page.svelte +++ b/src/routes/about/+page.svelte @@ -54,9 +54,11 @@ return `${monthNames[parseInt(month)] ?? 'Jan'} ${year}`; } - let copiedIndex = $state<'did' | null>(null); + const pgpFingerprint = 'C918 A4FC C656 BEBF 0EB7 AE01 4CB2 0882 06DB 0B7D'; - async function copyToClipboard(text: string, id: 'did') { + let copiedIndex = $state<'did' | 'pgp' | null>(null); + + async function copyToClipboard(text: string, id: 'did' | 'pgp') { // navigator.clipboard is undefined outside secure contexts, and // writeText() rejects when permission is denied. try { @@ -297,6 +299,19 @@
{profile.handle}eurosky.social{pgpFingerprint}
+
+ Download key