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}
PDS
eurosky.social
+
PGP
+
+ {pgpFingerprint} + + Download key +
Name
About my name
diff --git a/static/pgp-key.asc b/static/pgp-key.asc new file mode 100755 index 0000000..fb6e2b5 --- /dev/null +++ b/static/pgp-key.asc @@ -0,0 +1,14 @@ +-----BEGIN PGP PUBLIC KEY BLOCK----- + +mDMEampA6xYJKwYBBAHaRw8BAQdAtCPU1XkdB4pcozLla5cznw0/ZHwKcUJ0eZvI +qNViZ1C0IUV3YW4gQ3JvZnQgPGNvbnRhY3RAZXdhbmNyb2Z0LnVrPoi1BBMWCgBd +FiEEyRik/MZWvr8Ot64BTLIIggbbC30FAmpqQOsbFIAAAAAABAAObWFudTIsMi41 +KzEuMTIsMCwzAhsDBQkFo5qABQsJCAcCAiICBhUKCQgLAgQWAgMBAh4HAheAAAoJ +EEyyCIIG2wt99BwA/iiTqrk1volEELeNL5T4wjOJtd0PzhqlHmaC9iWSF97sAQCM +NMgufw4GzjVIDae2qvepv9oN9iiuuQ3F8h8wkLrxA7g4BGpqQOsSCisGAQQBl1UB +BQEBB0CrmewEpIiTpO2YXTDfAGK9BnAVXkc9SjGYxXFtl9VjMwMBCAeIlAQYFgoA +PBYhBMkYpPzGVr6/DreuAUyyCIIG2wt9BQJqakDrGxSAAAAAAAQADm1hbnUyLDIu +NSsxLjEyLDAsMwIbDAAKCRBMsgiCBtsLfRHKAP9h5gTIsr6B6Af/OnyroxeduI1S +P2rpa9KEt5yWkVqUYQD+P9e0pXgehaBPV/Ofwfc3Ah8q49foP8YRbseWxi3naQw= +=bhYm +-----END PGP PUBLIC KEY BLOCK-----