diff --git a/.forgejo/workflows/deploy.yml b/.forgejo/workflows/deploy.yml index a2796f4..517df26 100644 --- a/.forgejo/workflows/deploy.yml +++ b/.forgejo/workflows/deploy.yml @@ -3,10 +3,8 @@ name: Deploy to Pages on: push: branches: ['main'] - pull_request: branches: ['main'] - workflow_dispatch: concurrency: @@ -30,24 +28,33 @@ jobs: run: npm ci - name: Lint - run: | - npm run lint - npm run typecheck - npm run qa:no-em-dashes - npm run qa:spelling + run: npm run lint + + - name: Typecheck + run: npm run typecheck + + - name: Check for em dashes + run: npm run qa:no-em-dashes - name: Build run: npm run build - - name: QA build - run: | - npm run qa:astro-audit - npm run qa:links - npm run qa:no-js - npm run qa:overflow - npm run qa:preview-cropping + - name: Astro audit + run: npm run qa:astro-audit - - name: On main, Copy build to host pages mount + - name: Check internal links + run: npm run qa:links + + - name: Check for unexpected JavaScript + run: npm run qa:no-js + + - name: Check viewport overflow + run: npm run qa:overflow + + - name: Check preview cropping + run: npm run qa:preview-cropping + + - name: Copy build to host pages mount if: github.event_name == 'push' && github.ref == 'refs/heads/main' uses: http://forgejo:3000/andras/ci-actions/deploy-pages@main with: diff --git a/cspell.json b/cspell.json deleted file mode 100644 index 77ca04e..0000000 --- a/cspell.json +++ /dev/null @@ -1,110 +0,0 @@ -{ - "$schema": "https://raw.githubusercontent.com/streetsidesoftware/cspell/main/cspell.schema.json", - "version": "0.2", - "language": "en,en-GB", - "ignorePaths": [ - "node_modules/**", - "dist/**", - ".astro/**", - "package-lock.json", - "*.svg", - "public/**", - "todo.md" - ], - "words": [ - "acked", - "acks", - "adblocker", - "apos", - "backpressure", - "backtest", - "bgsave", - "binaryen", - "bindgen", - "bitpacking", - "blockedbyclient", - "borgmann", - "btrfs", - "cheatable", - "collab", - "conveyal", - "crewmates", - "datasheet", - "datasheets", - "decla", - "dequant", - "desync", - "domcontentloaded", - "emelt", - "érettségi", - "extensionless", - "extrapolators", - "fizika", - "forex", - "fouc", - "funimation", - "gameboy", - "glsl", - "greatai", - "hanning", - "healthcheck", - "immich", - "immich's", - "importmap", - "janky", - "jemalloc", - "keepalives", - "laion", - "loggable", - "malloc", - "metas", - "mixolydian", - "mlockall", - "mosfets", - "nixplay's", - "ntfy", - "numba", - "numpy", - "nums", - "permacomputing", - "physarum", - "pocketbase", - "powerups", - "proptest", - "refetches", - "reimplementable", - "requantised", - "rgba", - "scalex", - "scaley", - "schmelczer", - "scrollables", - "serde", - "setpoints", - "shiki", - "slugifies", - "speculationrules", - "sqlx", - "stdlib", - "stft", - "strobing", - "stucki", - "subvolume", - "syncer", - "szintű", - "tamagotchis", - "tarjan's", - "tidepool", - "tmpfs", - "tweakpane", - "unsets", - "vaultlink", - "waveshare", - "waveshare's", - "webform", - "webgpu", - "wgsl", - "writeups", - "zstd" - ] -} diff --git a/package-lock.json b/package-lock.json index 2c49e00..3351e85 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2473,7 +2473,6 @@ "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=12" }, @@ -2513,7 +2512,6 @@ "integrity": "sha512-/4XH147Ui7OGTjg3HbdWe5arnZQSbfuRzdr9Ec7TQi5I7R+ir0Rlc9GIvD4v0XZurELqA035KVXJXpR61xhiTA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "esbuild": "^0.27.0", "fdir": "^6.5.0", @@ -4805,7 +4803,6 @@ "integrity": "sha512-7igPTM53cGHMW8xWuVTydi2KO233VFiTNyF5hLJqpilHfmn8C8gPf+PS7dUT64YcXFbiMGZxS9pCSxL/Dxm/Jw==", "dev": true, "license": "MIT", - "peer": true, "bin": { "prettier": "bin/prettier.cjs" }, @@ -4822,7 +4819,6 @@ "integrity": "sha512-RiBETaaP9veVstE4vUwSIcdATj6dKmXljouXc/DDNwBSPTp8FRkLGDSGFClKsAFeeg+13SB0Z1JZvbD76bigJw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@astrojs/compiler": "^2.9.1", "prettier": "^3.0.0", @@ -5182,7 +5178,6 @@ "integrity": "sha512-pAQK9HalE84QSm4Po3EmWIZPd3FnjkShVkiMlz1iligWYkWQ7wHYd1PF/T7QZ5TVSD6uSTon5gBVMSM4JfBV+A==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@types/estree": "1.0.8" }, @@ -5504,7 +5499,6 @@ "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=12" }, @@ -5553,7 +5547,6 @@ "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", "dev": true, "license": "Apache-2.0", - "peer": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -6327,7 +6320,6 @@ "integrity": "sha512-Thbli+OlOj+iMPYFBVBfJ3OmCAnaSyNn4M1vz9T6Gka5Jt9ba/HIR56joy65tY6kx/FCF5VXNB819Y7/GUrBGA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "fast-deep-equal": "^3.1.3", "fast-uri": "^3.0.1", @@ -7840,8 +7832,7 @@ "version": "4.0.4", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", - "dev": true, - "peer": true + "dev": true }, "svgo": { "version": "4.0.1", @@ -7863,7 +7854,6 @@ "resolved": "https://registry.npmjs.org/vite/-/vite-7.3.3.tgz", "integrity": "sha512-/4XH147Ui7OGTjg3HbdWe5arnZQSbfuRzdr9Ec7TQi5I7R+ir0Rlc9GIvD4v0XZurELqA035KVXJXpR61xhiTA==", "dev": true, - "peer": true, "requires": { "esbuild": "^0.27.0", "fdir": "^6.5.0", @@ -9307,15 +9297,13 @@ "version": "3.8.3", "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.8.3.tgz", "integrity": "sha512-7igPTM53cGHMW8xWuVTydi2KO233VFiTNyF5hLJqpilHfmn8C8gPf+PS7dUT64YcXFbiMGZxS9pCSxL/Dxm/Jw==", - "dev": true, - "peer": true + "dev": true }, "prettier-plugin-astro": { "version": "0.14.1", "resolved": "https://registry.npmjs.org/prettier-plugin-astro/-/prettier-plugin-astro-0.14.1.tgz", "integrity": "sha512-RiBETaaP9veVstE4vUwSIcdATj6dKmXljouXc/DDNwBSPTp8FRkLGDSGFClKsAFeeg+13SB0Z1JZvbD76bigJw==", "dev": true, - "peer": true, "requires": { "@astrojs/compiler": "^2.9.1", "prettier": "^3.0.0", @@ -9572,7 +9560,6 @@ "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.60.3.tgz", "integrity": "sha512-pAQK9HalE84QSm4Po3EmWIZPd3FnjkShVkiMlz1iligWYkWQ7wHYd1PF/T7QZ5TVSD6uSTon5gBVMSM4JfBV+A==", "dev": true, - "peer": true, "requires": { "@rollup/rollup-android-arm-eabi": "4.60.3", "@rollup/rollup-android-arm64": "4.60.3", @@ -9793,8 +9780,7 @@ "version": "4.0.4", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", - "dev": true, - "peer": true + "dev": true } } }, @@ -9826,8 +9812,7 @@ "version": "5.9.3", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", - "dev": true, - "peer": true + "dev": true }, "typescript-auto-import-cache": { "version": "0.3.6", @@ -10292,7 +10277,6 @@ "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.20.0.tgz", "integrity": "sha512-Thbli+OlOj+iMPYFBVBfJ3OmCAnaSyNn4M1vz9T6Gka5Jt9ba/HIR56joy65tY6kx/FCF5VXNB819Y7/GUrBGA==", "dev": true, - "peer": true, "requires": { "fast-deep-equal": "^3.1.3", "fast-uri": "^3.0.1", diff --git a/package.json b/package.json index f0e268e..34fea5e 100644 --- a/package.json +++ b/package.json @@ -17,12 +17,11 @@ "audit:astro": "npm run build && node scripts/install-playwright-deps.mjs && node scripts/export-astro-audit.mjs", "qa:astro-audit": "node scripts/install-playwright-deps.mjs && node scripts/export-astro-audit.mjs --fail-on-issues", "qa:no-em-dashes": "node scripts/check-no-em-dashes.mjs", - "qa:spelling": "cspell --no-progress \"astro.config.mjs\" \"src/**/*.{astro,ts,md,css}\" \"scripts/**/*.mjs\" \"*.md\"", "qa:links": "node scripts/check-links.mjs", "qa:no-js": "node scripts/check-no-js.mjs", "qa:overflow": "node scripts/install-playwright-deps.mjs && node scripts/check-overflow.mjs", "qa:preview-cropping": "node scripts/install-playwright-deps.mjs && node scripts/check-preview-cropping.mjs", - "qa": "npm run typecheck && npm run lint && npm run qa:no-em-dashes && npm run qa:spelling && npm run build && npm run qa:astro-audit && npm run qa:links && npm run qa:no-js && npm run qa:overflow && npm run qa:preview-cropping" + "qa": "npm run typecheck && npm run lint && npm run qa:no-em-dashes && npm run build && npm run qa:astro-audit && npm run qa:links && npm run qa:no-js && npm run qa:overflow && npm run qa:preview-cropping" }, "repository": { "type": "git", @@ -46,7 +45,6 @@ "@astrojs/sitemap": "^3.7.2", "@types/node": "^22.13.0", "astro": "^6.3.1", - "cspell": "^10.0.1", "playwright": "^1.59.1", "prettier": "^3.8.3", "prettier-plugin-astro": "^0.14.1", diff --git a/public/media/video/ad_astra.vtt b/public/media/video/ad_astra.vtt new file mode 100644 index 0000000..578c7b6 --- /dev/null +++ b/public/media/video/ad_astra.vtt @@ -0,0 +1,13 @@ +WEBVTT + +00:00.000 --> 00:04.000 +No spoken dialogue. Game audio only. + +00:04.000 --> 00:35.000 +The Ad Astra handheld board runs the game on a small OLED display. + +00:35.000 --> 01:05.000 +The player controls the game through the IR input while the engine updates the display in real time. + +01:05.000 --> 01:34.600 +The clip continues showing gameplay on the custom ATtiny85-based board. diff --git a/src/components/AtAGlance.astro b/src/components/AtAGlance.astro index 1ebdfa7..37fd108 100644 --- a/src/components/AtAGlance.astro +++ b/src/components/AtAGlance.astro @@ -5,6 +5,7 @@ import ProjectLinks from './ProjectLinks.astro'; type Link = CollectionEntry<'work'>['data']['links'][number]; interface Props { + role?: string; projectPeriod?: string; stack?: string[]; scale?: string; @@ -13,9 +14,18 @@ interface Props { headingId: string; } -const { projectPeriod, stack = [], scale, outcome, links = [], headingId } = Astro.props; +const { + role, + projectPeriod, + stack = [], + scale, + outcome, + links = [], + headingId, +} = Astro.props; const rows: Array<[string, string]> = []; +if (role) rows.push(['Role', role]); if (projectPeriod) rows.push(['Period', projectPeriod]); if (stack.length > 0) rows.push(['Stack', stack.join(', ')]); if (scale) rows.push(['Scale', scale]); diff --git a/src/components/PostMediaFigure.astro b/src/components/PostMediaFigure.astro index 9277e6e..922a7a7 100644 --- a/src/components/PostMediaFigure.astro +++ b/src/components/PostMediaFigure.astro @@ -18,7 +18,7 @@ const videoHeight = item.type === 'video' ? (item.poster?.height ?? 720) : undef { item.type === 'video' ? ( // Decorative videos stay inert and hidden from assistive tech. Meaningful - // videos expose controls and an accessible name. + // videos expose controls, captions, and an accessible name. item.decorative ? ( ) ) : ( diff --git a/src/components/VideoThumbnail.astro b/src/components/VideoThumbnail.astro index 2d46ab9..0c80548 100644 --- a/src/components/VideoThumbnail.astro +++ b/src/components/VideoThumbnail.astro @@ -111,6 +111,17 @@ const playScript = ` > {video.webm && } {video.mp4 && } + { + video.captions && ( + + ) + }