diff --git a/.prettierrc.js b/.prettierrc.js deleted file mode 100644 index 7aca5df..0000000 --- a/.prettierrc.js +++ /dev/null @@ -1,6 +0,0 @@ -export default { - semi: true, - trailingComma: 'all', - singleQuote: true, - useTabs: true, -}; diff --git a/biome.json b/biome.json new file mode 100644 index 0000000..f340327 --- /dev/null +++ b/biome.json @@ -0,0 +1,34 @@ +{ + "$schema": "https://biomejs.dev/schemas/2.2.5/schema.json", + "vcs": { + "enabled": false, + "clientKind": "git", + "useIgnoreFile": true + }, + "files": { + "ignoreUnknown": false + }, + "formatter": { + "enabled": true, + "indentStyle": "tab" + }, + "linter": { + "enabled": true, + "rules": { + "recommended": true + } + }, + "javascript": { + "formatter": { + "quoteStyle": "double" + } + }, + "assist": { + "enabled": true, + "actions": { + "source": { + "organizeImports": "on" + } + } + } +} diff --git a/package-lock.json b/package-lock.json index 98ccc84..f5ca9f9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,6 +12,7 @@ "@11ty/eleventy": "^3.1.2" }, "devDependencies": { + "@biomejs/biome": "2.2.5", "autoprefixer": "^10.4.21", "postcss": "^8.5.6", "postcss-csso": "^6.0.1", @@ -199,6 +200,169 @@ "node": ">=18" } }, + "node_modules/@biomejs/biome": { + "version": "2.2.5", + "resolved": "https://registry.npmjs.org/@biomejs/biome/-/biome-2.2.5.tgz", + "integrity": "sha512-zcIi+163Rc3HtyHbEO7CjeHq8DjQRs40HsGbW6vx2WI0tg8mYQOPouhvHSyEnCBAorfYNnKdR64/IxO7xQ5faw==", + "dev": true, + "license": "MIT OR Apache-2.0", + "bin": { + "biome": "bin/biome" + }, + "engines": { + "node": ">=14.21.3" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/biome" + }, + "optionalDependencies": { + "@biomejs/cli-darwin-arm64": "2.2.5", + "@biomejs/cli-darwin-x64": "2.2.5", + "@biomejs/cli-linux-arm64": "2.2.5", + "@biomejs/cli-linux-arm64-musl": "2.2.5", + "@biomejs/cli-linux-x64": "2.2.5", + "@biomejs/cli-linux-x64-musl": "2.2.5", + "@biomejs/cli-win32-arm64": "2.2.5", + "@biomejs/cli-win32-x64": "2.2.5" + } + }, + "node_modules/@biomejs/cli-darwin-arm64": { + "version": "2.2.5", + "resolved": "https://registry.npmjs.org/@biomejs/cli-darwin-arm64/-/cli-darwin-arm64-2.2.5.tgz", + "integrity": "sha512-MYT+nZ38wEIWVcL5xLyOhYQQ7nlWD0b/4mgATW2c8dvq7R4OQjt/XGXFkXrmtWmQofaIM14L7V8qIz/M+bx5QQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT OR Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=14.21.3" + } + }, + "node_modules/@biomejs/cli-darwin-x64": { + "version": "2.2.5", + "resolved": "https://registry.npmjs.org/@biomejs/cli-darwin-x64/-/cli-darwin-x64-2.2.5.tgz", + "integrity": "sha512-FLIEl73fv0R7dI10EnEiZLw+IMz3mWLnF95ASDI0kbx6DDLJjWxE5JxxBfmG+udz1hIDd3fr5wsuP7nwuTRdAg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT OR Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=14.21.3" + } + }, + "node_modules/@biomejs/cli-linux-arm64": { + "version": "2.2.5", + "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-arm64/-/cli-linux-arm64-2.2.5.tgz", + "integrity": "sha512-5DjiiDfHqGgR2MS9D+AZ8kOfrzTGqLKywn8hoXpXXlJXIECGQ32t+gt/uiS2XyGBM2XQhR6ztUvbjZWeccFMoQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT OR Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=14.21.3" + } + }, + "node_modules/@biomejs/cli-linux-arm64-musl": { + "version": "2.2.5", + "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-arm64-musl/-/cli-linux-arm64-musl-2.2.5.tgz", + "integrity": "sha512-5Ov2wgAFwqDvQiESnu7b9ufD1faRa+40uwrohgBopeY84El2TnBDoMNXx6iuQdreoFGjwW8vH6k68G21EpNERw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT OR Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=14.21.3" + } + }, + "node_modules/@biomejs/cli-linux-x64": { + "version": "2.2.5", + "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-x64/-/cli-linux-x64-2.2.5.tgz", + "integrity": "sha512-fq9meKm1AEXeAWan3uCg6XSP5ObA6F/Ovm89TwaMiy1DNIwdgxPkNwxlXJX8iM6oRbFysYeGnT0OG8diCWb9ew==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT OR Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=14.21.3" + } + }, + "node_modules/@biomejs/cli-linux-x64-musl": { + "version": "2.2.5", + "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-x64-musl/-/cli-linux-x64-musl-2.2.5.tgz", + "integrity": "sha512-AVqLCDb/6K7aPNIcxHaTQj01sl1m989CJIQFQEaiQkGr2EQwyOpaATJ473h+nXDUuAcREhccfRpe/tu+0wu0eQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT OR Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=14.21.3" + } + }, + "node_modules/@biomejs/cli-win32-arm64": { + "version": "2.2.5", + "resolved": "https://registry.npmjs.org/@biomejs/cli-win32-arm64/-/cli-win32-arm64-2.2.5.tgz", + "integrity": "sha512-xaOIad4wBambwJa6mdp1FigYSIF9i7PCqRbvBqtIi9y29QtPVQ13sDGtUnsRoe6SjL10auMzQ6YAe+B3RpZXVg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT OR Apache-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=14.21.3" + } + }, + "node_modules/@biomejs/cli-win32-x64": { + "version": "2.2.5", + "resolved": "https://registry.npmjs.org/@biomejs/cli-win32-x64/-/cli-win32-x64-2.2.5.tgz", + "integrity": "sha512-F/jhuXCssPFAuciMhHKk00xnCAxJRS/pUzVfXYmOMUp//XW7mO6QeCjsjvnm8L4AO/dG2VOB0O+fJPiJ2uXtIw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT OR Apache-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=14.21.3" + } + }, "node_modules/@csstools/selector-resolve-nested": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/@csstools/selector-resolve-nested/-/selector-resolve-nested-3.1.0.tgz", diff --git a/package.json b/package.json index 933f19a..d7f19ca 100644 --- a/package.json +++ b/package.json @@ -24,6 +24,7 @@ "@11ty/eleventy": "^3.1.2" }, "devDependencies": { + "@biomejs/biome": "2.2.5", "autoprefixer": "^10.4.21", "postcss": "^8.5.6", "postcss-csso": "^6.0.1", diff --git a/src/content/_data/metadata.js b/src/content/_data/metadata.js index 237676d..1283b4b 100644 --- a/src/content/_data/metadata.js +++ b/src/content/_data/metadata.js @@ -1,8 +1,25 @@ export default { + // Basic site identity siteUrl: 'https://j-m.es', siteName: 'James Loveridge', jobTitle: 'Software Engineer', - bluesky: 'j-m.es', - github: 'j-mes', - linkedin: 'j-mes' + + // Short description used in meta description and social previews + description: 'Intermittent notes written by James Loveridge', + + // Social / federated profiles (fill with full profile URLs if you prefer) + bluesky: 'https://bsky.app/profile/j-m.es', + mastodon: '', + github: 'https://github.com/j-mes', + linkedin: 'https://www.linkedin.com/in/j-mes', + + // Social embed / sharing defaults + // socialImage: '/images/social-share.png', + // twitterHandle: '', // include @ if you wish, e.g. '@jmes' + // fbAppId: '', + + // Misc + robots: 'index, follow', + // themeColor: '#0a0a0a', + // manifest: '/manifest.json' }; diff --git a/src/layouts/archive.njk b/src/layouts/archive.njk index 0aca519..1a675ef 100644 --- a/src/layouts/archive.njk +++ b/src/layouts/archive.njk @@ -1,12 +1,12 @@ {% extends "main.njk" %} {% block content %} -
-

{{ entries.title }}

+
+

{{ entries.title }}

{% if content %} -
+
{{ content | safe }} -
+ {% endif %} {% if collectionKey %} @@ -15,12 +15,14 @@ {% if items and items | length > 0 %} {% if groupByYear %} {% for year in items | groupByYear %} -
-

{{ year.year }}

+
+

{{ year.year }}

    {% for entry in year.items %}
  • - {{ entry.data.title }} + {{ entry.data.title }} + – +
  • {% endfor %}
@@ -30,16 +32,20 @@
    {% for entry in items %}
  • - {{ entry.data.title }} + {{ entry.data.title }} + – +
  • {% endfor %}
{% endif %} {% else %} -

No entries found.

+

No entries found.

{% endif %} {% else %} -
No collectionKey set in frontmatter or data file for this archive page.
+
+
No collectionKey set in frontmatter or data file for this archive page.
+
{% endif %}
diff --git a/src/layouts/home.njk b/src/layouts/home.njk index 848e7e7..2687947 100644 --- a/src/layouts/home.njk +++ b/src/layouts/home.njk @@ -1,7 +1,7 @@ {# src/layouts/home.njk #} {% extends "main.njk" %} {% block content %} -
+
{{ content | safe }} {%- if collections.notes -%} @@ -12,17 +12,17 @@ {%- endif -%} {% if latest %} -
-

Latest intermittent note

+
+

Latest intermittent note

{{ latest.data.title or latest.data.page.title or latest.fileSlug }}

-
- {{ latest.templateContent | striptags(true) | truncateWords(80)| safe }} +
+

{{ latest.templateContent | striptags(true) | truncateWords(80)| safe }}

{% endif %} -
-

Here's the other things for intermittent notes

+
+

Here's the other things for intermittent notes

    {% if collections.notes %}
  • Archives
  • diff --git a/src/layouts/main.njk b/src/layouts/main.njk index c16bbb0..f26e379 100644 --- a/src/layouts/main.njk +++ b/src/layouts/main.njk @@ -2,16 +2,24 @@ + {{ title }} | {{ metadata.siteName }} – {{ metadata.jobTitle }} - + {% include 'meta-tags.njk' %} -
    - {{ metadata.siteName }} – {{ metadata.jobTitle }} -

    {{ title }}

    + Skip to main content +
    + +

    {{ title }}

    + +
    {% block content %}{% endblock %} -
    +
    + +
    {# Do something nice here? #}
    diff --git a/src/layouts/meta-tags.njk b/src/layouts/meta-tags.njk new file mode 100644 index 0000000..58122d3 --- /dev/null +++ b/src/layouts/meta-tags.njk @@ -0,0 +1,55 @@ +{# Reusable head meta partial used by layouts/main.njk #} + + + + +{# Open Graph / Facebook / generic social #} + + + + + +{% if page.data.image or metadata.socialImage %} + +{% endif %} +{% if metadata.fbAppId %} + +{% endif %} + +{# Twitter card #} + +{% if metadata.twitterHandle %} + + +{% endif %} + + +{% if page.data.image or metadata.socialImage %} + +{% endif %} + +{# oEmbed discovery (JSON and XML) - some platforms may use this for rich embeds #} +{% if page.data.oembed or metadata.oembed %} + + +{% endif %} + +{# rel-me links for decentralised identity (Bluesky, Mastodon, etc.) #} +{% if metadata.bluesky %} + +{% endif %} +{% if metadata.mastodon %} + +{% endif %} + +{# Robots / PWA hints #} + +{% if metadata.themeColor %} + +{% endif %} +{% if metadata.manifest %} + +{% endif %} + +{# Generic RSS/feed link for discoverability #} + diff --git a/src/layouts/post.njk b/src/layouts/post.njk index 2d79c3c..4c6a574 100644 --- a/src/layouts/post.njk +++ b/src/layouts/post.njk @@ -1,9 +1,17 @@ -{# src/layouts/post.njk #} -{% extends "main.njk" %} +{# src/layouts/post.njk #} +{% extends "main.njk" %} {% block content %} -
    - {{ content | safe }} - {{ date.toLocaleDateString('en-GB', { day: "numeric", month: "long", year: "numeric" }) }} -

    ↩ Back to notes

    +
    +
    +

    {{ title }}

    + +
    + +
    {{ content | safe }}
    + + +
    {% endblock %} diff --git a/src/styles/index.css b/src/styles/index.css index b83d99f..9a0d32f 100644 --- a/src/styles/index.css +++ b/src/styles/index.css @@ -84,3 +84,34 @@ footer li { fill: var(--colour-link-alt); } } + +/* Accessible skip-to-content link (classless) */ +/* Target the page anchor used in templates: href="#main-content" */ +a[href="#main-content"] { + position: absolute; + left: -999px; + width: 1px; + height: 1px; + overflow: hidden; + clip: rect(1px, 1px, 1px, 1px); /* legacy */ + white-space: nowrap; + border: 0; + padding: 0; +} + +a[href="#main-content"]:focus, +a[href="#main-content"]:focus-visible { + position: fixed; + top: 1rem; + left: 1rem; + width: auto; + height: auto; + overflow: visible; + clip: auto; + background: var(--colour-dark); + color: var(--colour-light); + padding: 0.25rem 0.5rem; + border-radius: 4px; + z-index: 1000; + text-decoration: none; +}