diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 00000000..4a0a6c5f --- /dev/null +++ b/.gitattributes @@ -0,0 +1,5 @@ +*.png binary +*.jpg binary +*.jpeg binary +*.avif binary +*.webp binary diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 0b411b37..15d51c3e 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -30,19 +30,19 @@ jobs: - uses: actions/setup-node@v4 with: - node-version: 18 + node-version: 26 - - name: install pnpm - run: npm i -g pnpm + - name: install node / pm + run: npm install -g @nubjs/nub - name: Install Dependencies - run: pnpm i + run: nub i - name: Run Tests - run: pnpm run test + run: nub run test - name: Build Site - run: pnpm run build + run: nub run build - name: Merge MFCC Widget run: | diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml index c5974231..e6eb773d 100644 --- a/.github/workflows/pr.yml +++ b/.github/workflows/pr.yml @@ -13,13 +13,13 @@ jobs: - uses: actions/setup-node@v4 with: - node-version: 18 + node-version: 26 - - name: install pnpm - run: npm i -g pnpm + - name: install node / pm + run: npm install -g @nubjs/nub - name: Install Dependencies - run: pnpm i + run: nub i - name: Run Tests run: pnpm run test diff --git a/.nvmrc b/.nvmrc index 0f9eb824..6f4247a6 100644 --- a/.nvmrc +++ b/.nvmrc @@ -1 +1 @@ -18.15 \ No newline at end of file +26 diff --git a/package.json b/package.json index b9d16578..682ad907 100644 --- a/package.json +++ b/package.json @@ -2,9 +2,12 @@ "name": "learn-2.0", "version": "0.0.1", "private": true, + "engines": { + "node": "^26.0.0" + }, "scripts": { "dev": "node scripts/preprocess.js && vite dev", - "build": "node scripts/preprocess.js && vite build", + "build": "node scripts/preprocess.js && node scripts/optimise-images.js && vite build", "preview": "vite preview", "check": "svelte-kit sync && svelte-check --tsconfig ./jsconfig.json", "check:watch": "svelte-kit sync && svelte-check --tsconfig ./jsconfig.json --watch", @@ -31,6 +34,7 @@ "prettier-plugin-svelte": "^2.10.1", "rehype-autolink-headings": "^6.1.1", "rehype-slug": "^5.1.0", + "sharp": "^0.35.3", "svelte": "^4.2.12", "svelte-check": "^3.6.4", "svelte-preprocess": "^5.1.3", @@ -63,5 +67,9 @@ "two.js": "^0.8.13", "umap-js": "^1.3.3", "waveform-data": "^4.5.0" + }, + "allowScripts": { + "sharp@0.34.5": true, + "esbuild@0.21.5": true } -} \ No newline at end of file +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index fd83acb5..9818946b 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -43,7 +43,7 @@ importers: version: 4.17.21 meyda: specifier: ^5.6.2 - version: 5.6.2 + version: 5.6.2(supports-color@7.2.0) numpy-parser: specifier: ^1.2.3 version: 1.2.3 @@ -64,7 +64,7 @@ importers: version: 5.8.3 svelte-youtube: specifier: ^0.0.2 - version: 0.0.2(svelte@4.2.12) + version: 0.0.2(supports-color@7.2.0)(svelte@4.2.12) tone: specifier: ^15.0.4 version: 15.0.4 @@ -80,22 +80,22 @@ importers: devDependencies: '@sveltejs/adapter-static': specifier: ^3.0.1 - version: 3.0.1(@sveltejs/kit@2.5.1(@sveltejs/vite-plugin-svelte@3.0.2(svelte@4.2.12)(vite@5.1.4(@types/node@20.11.20)))(svelte@4.2.12)(vite@5.1.4(@types/node@20.11.20))) + version: 3.0.1(@sveltejs/kit@2.5.1(@sveltejs/vite-plugin-svelte@3.0.2(supports-color@7.2.0)(svelte@4.2.12)(vite@5.1.4(@types/node@20.11.20)))(svelte@4.2.12)(vite@5.1.4(@types/node@20.11.20))) '@sveltejs/kit': specifier: ^2.5.1 - version: 2.5.1(@sveltejs/vite-plugin-svelte@3.0.2(svelte@4.2.12)(vite@5.1.4(@types/node@20.11.20)))(svelte@4.2.12)(vite@5.1.4(@types/node@20.11.20)) + version: 2.5.1(@sveltejs/vite-plugin-svelte@3.0.2(supports-color@7.2.0)(svelte@4.2.12)(vite@5.1.4(@types/node@20.11.20)))(svelte@4.2.12)(vite@5.1.4(@types/node@20.11.20)) '@sveltejs/vite-plugin-svelte': specifier: ^3.0.2 - version: 3.0.2(svelte@4.2.12)(vite@5.1.4(@types/node@20.11.20)) + version: 3.0.2(supports-color@7.2.0)(svelte@4.2.12)(vite@5.1.4(@types/node@20.11.20)) eslint: specifier: ^8.57.0 - version: 8.57.0 + version: 8.57.0(supports-color@7.2.0) eslint-config-prettier: specifier: ^8.10.0 - version: 8.10.0(eslint@8.57.0) + version: 8.10.0(eslint@8.57.0(supports-color@7.2.0)) eslint-plugin-svelte3: specifier: ^4.0.0 - version: 4.0.0(eslint@8.57.0)(svelte@4.2.12) + version: 4.0.0(eslint@8.57.0(supports-color@7.2.0))(svelte@4.2.12) front-matter: specifier: ^4.0.2 version: 4.0.2 @@ -129,6 +129,9 @@ importers: rehype-slug: specifier: ^5.1.0 version: 5.1.0 + sharp: + specifier: ^0.35.3 + version: 0.35.3(@types/node@20.11.20) svelte: specifier: ^4.2.12 version: 4.2.12 @@ -140,13 +143,13 @@ importers: version: 5.1.3(postcss@8.4.35)(svelte@4.2.12)(typescript@5.3.3) tap-mocha-reporter: specifier: ^5.0.4 - version: 5.0.4 + version: 5.0.4(supports-color@7.2.0) vite: specifier: ^5.1.4 version: 5.1.4(@types/node@20.11.20) vitest: specifier: ^1.3.1 - version: 1.3.1(@types/node@20.11.20) + version: 1.3.1(@types/node@20.11.20)(supports-color@7.2.0) packages: @@ -162,6 +165,9 @@ packages: resolution: {integrity: sha512-VBj9MYyDb9tuLq7yzqjgzt6Q+IBQLrGZfdjOekyEirZPHxXWoTSGUTMrpsfi58Up73d13NfYLv8HT9vmznjzhQ==} engines: {node: '>=6.9.0'} + '@emnapi/runtime@1.11.3': + resolution: {integrity: sha512-Xz4Tpyki7XyrpbUK1jR1AhdAdaXyhhY4lZ3neLodmhpuWfy2PAQN5B46sAiU4liOXGLkHypn/qU+jvfWSCYYLA==} + '@esbuild/aix-ppc64@0.19.12': resolution: {integrity: sha512-bmoCYyWdEL3wDQIVbcyzRyeKLgk2WtWLTWz1ZIAZF/EGbNOwSA6ew3PftJ1PqMiOOGu0OyFMzG53L0zqIpPeNA==} engines: {node: '>=12'} @@ -335,6 +341,7 @@ packages: '@humanwhocodes/config-array@0.11.14': resolution: {integrity: sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==} engines: {node: '>=10.10.0'} + deprecated: Use @eslint/config-array instead '@humanwhocodes/module-importer@1.0.1': resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==} @@ -342,6 +349,169 @@ packages: '@humanwhocodes/object-schema@2.0.2': resolution: {integrity: sha512-6EwiSjwWYP7pTckG6I5eyFANjPhmPjUX9JRLUSfNPC7FX7zK9gyZAfUEaECL6ALTpGX5AjnBq3C9XmVWPitNpw==} + deprecated: Use @eslint/object-schema instead + + '@img/colour@1.1.0': + resolution: {integrity: sha512-Td76q7j57o/tLVdgS746cYARfSyxk8iEfRxewL9h4OMzYhbW4TAcppl0mT4eyqXddh6L/jwoM75mo7ixa/pCeQ==} + engines: {node: '>=18'} + + '@img/sharp-darwin-arm64@0.35.3': + resolution: {integrity: sha512-RMnFX7YQsMoh7lWfcM4NEHHymBX/rLuKNPVM84XE9ONPcaSCDgE7CHIHpSgPcO2xcRthgBy1HfNO319mwhIAkg==} + engines: {node: '>=20.9.0'} + cpu: [arm64] + os: [darwin] + + '@img/sharp-darwin-x64@0.35.3': + resolution: {integrity: sha512-Xo+5uFBtLN0BKqieTxiFzFPQAUlBbbH5iBKyRX/z1JrbnYsHTfKJnUfL8+p2TPXr1pXqao4eeL4Rl144uDpK9w==} + engines: {node: '>=20.9.0'} + cpu: [x64] + os: [darwin] + + '@img/sharp-freebsd-wasm32@0.35.3': + resolution: {integrity: sha512-lUxcqWIj2wMQ9BrwNjngcr1gWUr5xgaGThBRqPPalIC2n67Cqj1uPh8NnA/ZhAg8hUbKl+kVHKwgUIwe6ZYPrg==} + engines: {node: '>=20.9.0'} + os: [freebsd] + + '@img/sharp-libvips-darwin-arm64@1.3.2': + resolution: {integrity: sha512-9J6ypZFpQBj4YnePGoq/S38w6nz+vqg5WZLrLGY4YuSemdMq47GMLBPO42MzwdGwpg/agZ7xzZcFHa48xlywfg==} + cpu: [arm64] + os: [darwin] + + '@img/sharp-libvips-darwin-x64@1.3.2': + resolution: {integrity: sha512-m2pW1n6cns9VaubNwsZ+c3CRYjxNQWgJ5gPlnL1nbBcpkBvFm6SCFN5o0psFHI8w9n11NKhFkeEDns98tiqbEw==} + cpu: [x64] + os: [darwin] + + '@img/sharp-libvips-linux-arm64@1.3.2': + resolution: {integrity: sha512-dqVSFynCox4C/J8kT16V7SIFAns0IjgLwkvYT7p8LQVmJ5OS5b6tI9IGflxTeuBS//zXeFIUbwt5dwxyZ17cnA==} + cpu: [arm64] + os: [linux] + libc: [glibc] + + '@img/sharp-libvips-linux-arm@1.3.2': + resolution: {integrity: sha512-1eMLzy92I4J6rmi4mAT8yC3HxOtniyGELlzGbNMLLeqe052ahFQ0h6LFq+lh5DsDIdYViIDst08abvSbcEdLXQ==} + cpu: [arm] + os: [linux] + libc: [glibc] + + '@img/sharp-libvips-linux-ppc64@1.3.2': + resolution: {integrity: sha512-3z0NHDxD6n5I9gc05U1eW1AyRm+Gznzq3naMrthPNqE6oYykcogW0l/jfpJdjYnuNl8R7yI9pNbE1XiUeyq0Aw==} + cpu: [ppc64] + os: [linux] + libc: [glibc] + + '@img/sharp-libvips-linux-riscv64@1.3.2': + resolution: {integrity: sha512-bsb4rI+NldGOsXuej2r8OdSS8+zXDVaCWxyWrcv6kneTOlgAHtZABRzBBCwdsPiD90J4myNJuHpg6kA20ImW/w==} + cpu: [riscv64] + os: [linux] + libc: [glibc] + + '@img/sharp-libvips-linux-s390x@1.3.2': + resolution: {integrity: sha512-/ABshyj8gCpyIrNXnHn4LorDJ0HHm1VhXPBlxZ8zAtfVPAaSafXPGn+sUSIRiwaSBy0mmFjSjiXI5mkcwdChKQ==} + cpu: [s390x] + os: [linux] + libc: [glibc] + + '@img/sharp-libvips-linux-x64@1.3.2': + resolution: {integrity: sha512-ITPEtgffGJ0S6G9dRyw/366tJQqFRcHWPHhC+Stpg3Z8AEMrDrTr2lhdz4f/Y/HMbRh//7Z5mBzEpVdi62Oc3w==} + cpu: [x64] + os: [linux] + libc: [glibc] + + '@img/sharp-libvips-linuxmusl-arm64@1.3.2': + resolution: {integrity: sha512-zE9EdiUzUmg5mDT5a1rk5fYJ6GWPloTwWBYDS14naqHsL+EaMpDj1AWnpLgh3u0YCORv2Tt50wrcrpYqkP97Kw==} + cpu: [arm64] + os: [linux] + libc: [musl] + + '@img/sharp-libvips-linuxmusl-x64@1.3.2': + resolution: {integrity: sha512-m0lrLiUt+lBYnCFr8qV/65yMR4E/c7/wf78I5eKTdkEakFAlZ9QlzEM3QIhhAwVeUhLAHLcCq7a7Vszq/oFNZQ==} + cpu: [x64] + os: [linux] + libc: [musl] + + '@img/sharp-linux-arm64@0.35.3': + resolution: {integrity: sha512-QgKDspHPnrU+GQ55XPhGwyhC8acLVOOSyAvo1oVfFmrIXLkDNmGWzAfDZ4xK8oSA1qBQrALcHX0G5UZni/SuFQ==} + engines: {node: '>=20.9.0'} + cpu: [arm64] + os: [linux] + libc: [glibc] + + '@img/sharp-linux-arm@0.35.3': + resolution: {integrity: sha512-affVWCTLooy8TSxbDx2qkzuDeaWLNVBA+P//FNBirHsXpP2fuBhk5AuboYUnrDnzoXes8GFjpTx0SBFOCRg+FA==} + engines: {node: '>=20.9.0'} + cpu: [arm] + os: [linux] + libc: [glibc] + + '@img/sharp-linux-ppc64@0.35.3': + resolution: {integrity: sha512-sMd8rDxmpLOwv/7N44klFjOD5DUO7FLdjiXDI0hoxYaf7Ar262dQIEkosE98bps+5HPLtp/EvNqeqQtOycP/IA==} + engines: {node: '>=20.9.0'} + cpu: [ppc64] + os: [linux] + libc: [glibc] + + '@img/sharp-linux-riscv64@0.35.3': + resolution: {integrity: sha512-0Eob78yjlYPfL5vMNWAW55l3R9Y6BQS/gOfe0ZcP9mEz9ohhKSt4im1hayiknXgf8AWrFqMvJcKIdmLmEe7yeQ==} + engines: {node: '>=20.9.0'} + cpu: [riscv64] + os: [linux] + libc: [glibc] + + '@img/sharp-linux-s390x@0.35.3': + resolution: {integrity: sha512-KgAxQ0DxpNOq1rG2t5cgTgShJFGSuU7XO45cqC+1NVOuZnP6tlgZRuSYOfNupGkHID0o3cJOsw4DVeJpMovcGw==} + engines: {node: '>=20.9.0'} + cpu: [s390x] + os: [linux] + libc: [glibc] + + '@img/sharp-linux-x64@0.35.3': + resolution: {integrity: sha512-8pqvxubL2PGdhlPy6GLqzDYMUjyRmKAwKHYKixpdJYBUK7PJ0C029XdsnpFIdgRZG68fZiGdHVWcKPvtiPB4cA==} + engines: {node: '>=20.9.0'} + cpu: [x64] + os: [linux] + libc: [glibc] + + '@img/sharp-linuxmusl-arm64@0.35.3': + resolution: {integrity: sha512-Vz0iQjzzcSX3HCbfwFfCSG/9SCIqyO0mH2sXyiHaAYfBk0cRsCWXRyQYX0ovCK/PAQBbTzQ0dsPQHh5MAFL59w==} + engines: {node: '>=20.9.0'} + cpu: [arm64] + os: [linux] + libc: [musl] + + '@img/sharp-linuxmusl-x64@0.35.3': + resolution: {integrity: sha512-6O1NPKcDVj9QEdg7Hx549EX8U0rp6yXQERqru6yRN7fGBn32UvIRJUlWnk+8xDCiG76hXVBbX82NZ/ZKr0euIg==} + engines: {node: '>=20.9.0'} + cpu: [x64] + os: [linux] + libc: [musl] + + '@img/sharp-wasm32@0.35.3': + resolution: {integrity: sha512-cZ0XkcYGpHZkqW6iCkqTcmUC0CD9DhD5d/qeZlZkfRBn6GnHniZXLUo5+9xw8Iv76YE6LQFN9YNBlKREcCG76w==} + engines: {node: '>=20.9.0'} + + '@img/sharp-webcontainers-wasm32@0.35.3': + resolution: {integrity: sha512-2rnq7bX3NzeR2T4YWgz8qiG4h3TSdMe+vN1iQXpJleSJ3SM5zQ8Fy2SyyXAWlbxpEZ2Y+Z4u1BePgJEYbSy80Q==} + engines: {node: '>=20.9.0'} + cpu: [wasm32] + + '@img/sharp-win32-arm64@0.35.3': + resolution: {integrity: sha512-4bPwFdMbeC4JQ8L8LOyWp6nsHcboP5fxkp6iPOXz2Vg49R42TuMs2whkJ5OAP4/Ul035qOzy0AecOF9VOscn4w==} + engines: {node: '>=20.9.0'} + cpu: [arm64] + os: [win32] + + '@img/sharp-win32-ia32@0.35.3': + resolution: {integrity: sha512-r53mXsBN6lFUDiST764SvgwUdHAqM4rPAiDzAmf4fLoB6X/rkfyTrLCg6+g17wJJiCmB3JYgHuUldCWUIRFSXw==} + engines: {node: ^20.9.0} + cpu: [ia32] + os: [win32] + + '@img/sharp-win32-x64@0.35.3': + resolution: {integrity: sha512-D4y1vNeZrIIJCN+uHaWVtH86B+aCrdMYYjicy9pXHvbGZeGYLLSd3wdVuC37FxVXlU1ARsk84eKWfWMXGYEqvA==} + engines: {node: '>=20.9.0'} + cpu: [x64] + os: [win32] '@jest/schemas@29.6.3': resolution: {integrity: sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==} @@ -423,26 +593,31 @@ packages: resolution: {integrity: sha512-0fZBq27b+D7Ar5CQMofVN8sggOVhEtzFUwOwPppQt0k+VR+7UHMZZY4y+64WJ06XOhBTKXtQB/Sv0NwQMXyNAA==} cpu: [arm64] os: [linux] + libc: [glibc] '@rollup/rollup-linux-arm64-musl@4.12.0': resolution: {integrity: sha512-eTvzUS3hhhlgeAv6bfigekzWZjaEX9xP9HhxB0Dvrdbkk5w/b+1Sxct2ZuDxNJKzsRStSq1EaEkVSEe7A7ipgQ==} cpu: [arm64] os: [linux] + libc: [musl] '@rollup/rollup-linux-riscv64-gnu@4.12.0': resolution: {integrity: sha512-ix+qAB9qmrCRiaO71VFfY8rkiAZJL8zQRXveS27HS+pKdjwUfEhqo2+YF2oI+H/22Xsiski+qqwIBxVewLK7sw==} cpu: [riscv64] os: [linux] + libc: [glibc] '@rollup/rollup-linux-x64-gnu@4.12.0': resolution: {integrity: sha512-TenQhZVOtw/3qKOPa7d+QgkeM6xY0LtwzR8OplmyL5LrgTWIXpTQg2Q2ycBf8jm+SFW2Wt/DTn1gf7nFp3ssVA==} cpu: [x64] os: [linux] + libc: [glibc] '@rollup/rollup-linux-x64-musl@4.12.0': resolution: {integrity: sha512-LfFdRhNnW0zdMvdCb5FNuWlls2WbbSridJvxOvYWgSBOYZtgBfW9UGNJG//rwMqTX1xQE9BAodvMH9tAusKDUw==} cpu: [x64] os: [linux] + libc: [musl] '@rollup/rollup-win32-arm64-msvc@4.12.0': resolution: {integrity: sha512-JPDxovheWNp6d7AHCgsUlkuCKvtu3RB55iNEkaQcf0ttsDU/JZF+iQnYcQJSk/7PtT4mjjVG8N1kpwnI9SLYaw==} @@ -562,6 +737,7 @@ packages: '@ungap/structured-clone@1.2.0': resolution: {integrity: sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==} + deprecated: Potential CWE-502 - Update to 1.3.1 or higher '@vitest/expect@1.3.1': resolution: {integrity: sha512-xofQFwIzfdmLLlHa6ag0dPV8YsnKOCP1KdAeVVh34vSjN2dcUiXYCD9htu/9eM7t8Xln4v03U9HLxLpPlsXdZw==} @@ -966,6 +1142,10 @@ packages: resolution: {integrity: sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA==} engines: {node: '>=8'} + detect-libc@2.1.2: + resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==} + engines: {node: '>=8'} + devalue@4.3.2: resolution: {integrity: sha512-KqFl6pOgOW+Y6wJgu80rHpo2/3H07vr8ntR9rkkFIRETewbf5GaYYcakYfiKz89K+sLsuPkQIZaXDMjUObZwWg==} @@ -1048,6 +1228,7 @@ packages: eslint@8.57.0: resolution: {integrity: sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + deprecated: This version is no longer supported. Please see https://eslint.org/version-support for other options. hasBin: true esm-env@1.0.0: @@ -1191,6 +1372,7 @@ packages: glob@7.2.3: resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} + deprecated: Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me globals@13.24.0: resolution: {integrity: sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==} @@ -1261,6 +1443,7 @@ packages: inflight@1.0.6: resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==} + deprecated: This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful. inherits@2.0.4: resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} @@ -1505,6 +1688,7 @@ packages: node-domexception@1.0.0: resolution: {integrity: sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==} engines: {node: '>=10.5.0'} + deprecated: Use your platform's native DOMException instead node-fetch@2.6.13: resolution: {integrity: sha512-StxNAxh15zr77QvvkmveSQ8uCQ4+v5FkvNTj0OESmiHu+VRi/gXArXtkWMElOsOUNLtUEvI4yS+rdtOHZTwlQA==} @@ -1699,10 +1883,12 @@ packages: rimraf@2.7.1: resolution: {integrity: sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==} + deprecated: Rimraf versions prior to v4 are no longer supported hasBin: true rimraf@3.0.2: resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==} + deprecated: Rimraf versions prior to v4 are no longer supported hasBin: true robust-predicates@3.0.2: @@ -1749,9 +1935,23 @@ packages: engines: {node: '>=10'} hasBin: true + semver@7.8.5: + resolution: {integrity: sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==} + engines: {node: '>=10'} + hasBin: true + set-cookie-parser@2.6.0: resolution: {integrity: sha512-RVnVQxTXuerk653XfuliOxBP81Sf0+qfQE73LIYKcyMYHG94AuH0kgrQpRDuTZnSmjpysHmzxJXKNfa6PjFhyQ==} + sharp@0.35.3: + resolution: {integrity: sha512-ej0zVHuZGHCiABXcNxeYhpRnPNPAcvbG8RMdBAhDAxLKkCRVSpK3Iyu7qbqw3JMzoj0REeM6f3tJLtVwl0023Q==} + engines: {node: '>=20.9.0'} + peerDependencies: + '@types/node': '*' + peerDependenciesMeta: + '@types/node': + optional: true + shebang-command@2.0.0: resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} engines: {node: '>=8'} @@ -2175,6 +2375,11 @@ snapshots: dependencies: regenerator-runtime: 0.14.1 + '@emnapi/runtime@1.11.3': + dependencies: + tslib: 2.7.0 + optional: true + '@esbuild/aix-ppc64@0.19.12': optional: true @@ -2244,17 +2449,17 @@ snapshots: '@esbuild/win32-x64@0.19.12': optional: true - '@eslint-community/eslint-utils@4.4.0(eslint@8.57.0)': + '@eslint-community/eslint-utils@4.4.0(eslint@8.57.0(supports-color@7.2.0))': dependencies: - eslint: 8.57.0 + eslint: 8.57.0(supports-color@7.2.0) eslint-visitor-keys: 3.4.3 '@eslint-community/regexpp@4.10.0': {} - '@eslint/eslintrc@2.1.4': + '@eslint/eslintrc@2.1.4(supports-color@7.2.0)': dependencies: ajv: 6.12.6 - debug: 4.3.4 + debug: 4.3.4(supports-color@7.2.0) espree: 9.6.1 globals: 13.24.0 ignore: 5.3.1 @@ -2282,10 +2487,10 @@ snapshots: dependencies: '@tensorflow/tfjs': 4.17.0(seedrandom@3.0.5) - '@humanwhocodes/config-array@0.11.14': + '@humanwhocodes/config-array@0.11.14(supports-color@7.2.0)': dependencies: '@humanwhocodes/object-schema': 2.0.2 - debug: 4.3.4 + debug: 4.3.4(supports-color@7.2.0) minimatch: 3.1.2 transitivePeerDependencies: - supports-color @@ -2294,6 +2499,112 @@ snapshots: '@humanwhocodes/object-schema@2.0.2': {} + '@img/colour@1.1.0': {} + + '@img/sharp-darwin-arm64@0.35.3': + optionalDependencies: + '@img/sharp-libvips-darwin-arm64': 1.3.2 + optional: true + + '@img/sharp-darwin-x64@0.35.3': + optionalDependencies: + '@img/sharp-libvips-darwin-x64': 1.3.2 + optional: true + + '@img/sharp-freebsd-wasm32@0.35.3': + dependencies: + '@img/sharp-wasm32': 0.35.3 + optional: true + + '@img/sharp-libvips-darwin-arm64@1.3.2': + optional: true + + '@img/sharp-libvips-darwin-x64@1.3.2': + optional: true + + '@img/sharp-libvips-linux-arm64@1.3.2': + optional: true + + '@img/sharp-libvips-linux-arm@1.3.2': + optional: true + + '@img/sharp-libvips-linux-ppc64@1.3.2': + optional: true + + '@img/sharp-libvips-linux-riscv64@1.3.2': + optional: true + + '@img/sharp-libvips-linux-s390x@1.3.2': + optional: true + + '@img/sharp-libvips-linux-x64@1.3.2': + optional: true + + '@img/sharp-libvips-linuxmusl-arm64@1.3.2': + optional: true + + '@img/sharp-libvips-linuxmusl-x64@1.3.2': + optional: true + + '@img/sharp-linux-arm64@0.35.3': + optionalDependencies: + '@img/sharp-libvips-linux-arm64': 1.3.2 + optional: true + + '@img/sharp-linux-arm@0.35.3': + optionalDependencies: + '@img/sharp-libvips-linux-arm': 1.3.2 + optional: true + + '@img/sharp-linux-ppc64@0.35.3': + optionalDependencies: + '@img/sharp-libvips-linux-ppc64': 1.3.2 + optional: true + + '@img/sharp-linux-riscv64@0.35.3': + optionalDependencies: + '@img/sharp-libvips-linux-riscv64': 1.3.2 + optional: true + + '@img/sharp-linux-s390x@0.35.3': + optionalDependencies: + '@img/sharp-libvips-linux-s390x': 1.3.2 + optional: true + + '@img/sharp-linux-x64@0.35.3': + optionalDependencies: + '@img/sharp-libvips-linux-x64': 1.3.2 + optional: true + + '@img/sharp-linuxmusl-arm64@0.35.3': + optionalDependencies: + '@img/sharp-libvips-linuxmusl-arm64': 1.3.2 + optional: true + + '@img/sharp-linuxmusl-x64@0.35.3': + optionalDependencies: + '@img/sharp-libvips-linuxmusl-x64': 1.3.2 + optional: true + + '@img/sharp-wasm32@0.35.3': + dependencies: + '@emnapi/runtime': 1.11.3 + optional: true + + '@img/sharp-webcontainers-wasm32@0.35.3': + dependencies: + '@img/sharp-wasm32': 0.35.3 + optional: true + + '@img/sharp-win32-arm64@0.35.3': + optional: true + + '@img/sharp-win32-ia32@0.35.3': + optional: true + + '@img/sharp-win32-x64@0.35.3': + optional: true + '@jest/schemas@29.6.3': dependencies: '@sinclair/typebox': 0.27.8 @@ -2400,13 +2711,13 @@ snapshots: '@sinclair/typebox@0.27.8': {} - '@sveltejs/adapter-static@3.0.1(@sveltejs/kit@2.5.1(@sveltejs/vite-plugin-svelte@3.0.2(svelte@4.2.12)(vite@5.1.4(@types/node@20.11.20)))(svelte@4.2.12)(vite@5.1.4(@types/node@20.11.20)))': + '@sveltejs/adapter-static@3.0.1(@sveltejs/kit@2.5.1(@sveltejs/vite-plugin-svelte@3.0.2(supports-color@7.2.0)(svelte@4.2.12)(vite@5.1.4(@types/node@20.11.20)))(svelte@4.2.12)(vite@5.1.4(@types/node@20.11.20)))': dependencies: - '@sveltejs/kit': 2.5.1(@sveltejs/vite-plugin-svelte@3.0.2(svelte@4.2.12)(vite@5.1.4(@types/node@20.11.20)))(svelte@4.2.12)(vite@5.1.4(@types/node@20.11.20)) + '@sveltejs/kit': 2.5.1(@sveltejs/vite-plugin-svelte@3.0.2(supports-color@7.2.0)(svelte@4.2.12)(vite@5.1.4(@types/node@20.11.20)))(svelte@4.2.12)(vite@5.1.4(@types/node@20.11.20)) - '@sveltejs/kit@2.5.1(@sveltejs/vite-plugin-svelte@3.0.2(svelte@4.2.12)(vite@5.1.4(@types/node@20.11.20)))(svelte@4.2.12)(vite@5.1.4(@types/node@20.11.20))': + '@sveltejs/kit@2.5.1(@sveltejs/vite-plugin-svelte@3.0.2(supports-color@7.2.0)(svelte@4.2.12)(vite@5.1.4(@types/node@20.11.20)))(svelte@4.2.12)(vite@5.1.4(@types/node@20.11.20))': dependencies: - '@sveltejs/vite-plugin-svelte': 3.0.2(svelte@4.2.12)(vite@5.1.4(@types/node@20.11.20)) + '@sveltejs/vite-plugin-svelte': 3.0.2(supports-color@7.2.0)(svelte@4.2.12)(vite@5.1.4(@types/node@20.11.20)) '@types/cookie': 0.6.0 cookie: 0.6.0 devalue: 4.3.2 @@ -2422,19 +2733,19 @@ snapshots: tiny-glob: 0.2.9 vite: 5.1.4(@types/node@20.11.20) - '@sveltejs/vite-plugin-svelte-inspector@2.0.0(@sveltejs/vite-plugin-svelte@3.0.2(svelte@4.2.12)(vite@5.1.4(@types/node@20.11.20)))(svelte@4.2.12)(vite@5.1.4(@types/node@20.11.20))': + '@sveltejs/vite-plugin-svelte-inspector@2.0.0(@sveltejs/vite-plugin-svelte@3.0.2(supports-color@7.2.0)(svelte@4.2.12)(vite@5.1.4(@types/node@20.11.20)))(supports-color@7.2.0)(svelte@4.2.12)(vite@5.1.4(@types/node@20.11.20))': dependencies: - '@sveltejs/vite-plugin-svelte': 3.0.2(svelte@4.2.12)(vite@5.1.4(@types/node@20.11.20)) - debug: 4.3.4 + '@sveltejs/vite-plugin-svelte': 3.0.2(supports-color@7.2.0)(svelte@4.2.12)(vite@5.1.4(@types/node@20.11.20)) + debug: 4.3.4(supports-color@7.2.0) svelte: 4.2.12 vite: 5.1.4(@types/node@20.11.20) transitivePeerDependencies: - supports-color - '@sveltejs/vite-plugin-svelte@3.0.2(svelte@4.2.12)(vite@5.1.4(@types/node@20.11.20))': + '@sveltejs/vite-plugin-svelte@3.0.2(supports-color@7.2.0)(svelte@4.2.12)(vite@5.1.4(@types/node@20.11.20))': dependencies: - '@sveltejs/vite-plugin-svelte-inspector': 2.0.0(@sveltejs/vite-plugin-svelte@3.0.2(svelte@4.2.12)(vite@5.1.4(@types/node@20.11.20)))(svelte@4.2.12)(vite@5.1.4(@types/node@20.11.20)) - debug: 4.3.4 + '@sveltejs/vite-plugin-svelte-inspector': 2.0.0(@sveltejs/vite-plugin-svelte@3.0.2(supports-color@7.2.0)(svelte@4.2.12)(vite@5.1.4(@types/node@20.11.20)))(supports-color@7.2.0)(svelte@4.2.12)(vite@5.1.4(@types/node@20.11.20)) + debug: 4.3.4(supports-color@7.2.0) deepmerge: 4.3.1 kleur: 4.1.5 magic-string: 0.30.7 @@ -2944,13 +3255,17 @@ snapshots: dct@0.1.0: {} - debug@2.6.9: + debug@2.6.9(supports-color@7.2.0): dependencies: ms: 2.0.0 + optionalDependencies: + supports-color: 7.2.0 - debug@4.3.4: + debug@4.3.4(supports-color@7.2.0): dependencies: ms: 2.1.2 + optionalDependencies: + supports-color: 7.2.0 deep-eql@4.1.3: dependencies: @@ -2970,6 +3285,8 @@ snapshots: detect-indent@6.1.0: {} + detect-libc@2.1.2: {} + devalue@4.3.2: {} diff-sequences@29.6.3: {} @@ -3041,13 +3358,13 @@ snapshots: escape-string-regexp@4.0.0: {} - eslint-config-prettier@8.10.0(eslint@8.57.0): + eslint-config-prettier@8.10.0(eslint@8.57.0(supports-color@7.2.0)): dependencies: - eslint: 8.57.0 + eslint: 8.57.0(supports-color@7.2.0) - eslint-plugin-svelte3@4.0.0(eslint@8.57.0)(svelte@4.2.12): + eslint-plugin-svelte3@4.0.0(eslint@8.57.0(supports-color@7.2.0))(svelte@4.2.12): dependencies: - eslint: 8.57.0 + eslint: 8.57.0(supports-color@7.2.0) svelte: 4.2.12 eslint-scope@7.2.2: @@ -3057,20 +3374,20 @@ snapshots: eslint-visitor-keys@3.4.3: {} - eslint@8.57.0: + eslint@8.57.0(supports-color@7.2.0): dependencies: - '@eslint-community/eslint-utils': 4.4.0(eslint@8.57.0) + '@eslint-community/eslint-utils': 4.4.0(eslint@8.57.0(supports-color@7.2.0)) '@eslint-community/regexpp': 4.10.0 - '@eslint/eslintrc': 2.1.4 + '@eslint/eslintrc': 2.1.4(supports-color@7.2.0) '@eslint/js': 8.57.0 - '@humanwhocodes/config-array': 0.11.14 + '@humanwhocodes/config-array': 0.11.14(supports-color@7.2.0) '@humanwhocodes/module-importer': 1.0.1 '@nodelib/fs.walk': 1.2.8 '@ungap/structured-clone': 1.2.0 ajv: 6.12.6 chalk: 4.1.2 cross-spawn: 7.0.3 - debug: 4.3.4 + debug: 4.3.4(supports-color@7.2.0) doctrine: 3.0.0 escape-string-regexp: 4.0.0 eslint-scope: 7.2.2 @@ -3466,12 +3783,12 @@ snapshots: merge2@1.4.1: {} - meyda@5.6.2: + meyda@5.6.2(supports-color@7.2.0): dependencies: dct: 0.1.0 fftjs: 0.0.4 node-getopt: 0.3.2 - wav: 1.0.2 + wav: 1.0.2(supports-color@7.2.0) transitivePeerDependencies: - supports-color @@ -3803,8 +4120,43 @@ snapshots: lru-cache: 6.0.0 optional: true + semver@7.8.5: {} + set-cookie-parser@2.6.0: {} + sharp@0.35.3(@types/node@20.11.20): + dependencies: + '@img/colour': 1.1.0 + detect-libc: 2.1.2 + semver: 7.8.5 + optionalDependencies: + '@img/sharp-darwin-arm64': 0.35.3 + '@img/sharp-darwin-x64': 0.35.3 + '@img/sharp-freebsd-wasm32': 0.35.3 + '@img/sharp-libvips-darwin-arm64': 1.3.2 + '@img/sharp-libvips-darwin-x64': 1.3.2 + '@img/sharp-libvips-linux-arm': 1.3.2 + '@img/sharp-libvips-linux-arm64': 1.3.2 + '@img/sharp-libvips-linux-ppc64': 1.3.2 + '@img/sharp-libvips-linux-riscv64': 1.3.2 + '@img/sharp-libvips-linux-s390x': 1.3.2 + '@img/sharp-libvips-linux-x64': 1.3.2 + '@img/sharp-libvips-linuxmusl-arm64': 1.3.2 + '@img/sharp-libvips-linuxmusl-x64': 1.3.2 + '@img/sharp-linux-arm': 0.35.3 + '@img/sharp-linux-arm64': 0.35.3 + '@img/sharp-linux-ppc64': 0.35.3 + '@img/sharp-linux-riscv64': 0.35.3 + '@img/sharp-linux-s390x': 0.35.3 + '@img/sharp-linux-x64': 0.35.3 + '@img/sharp-linuxmusl-arm64': 0.35.3 + '@img/sharp-linuxmusl-x64': 0.35.3 + '@img/sharp-webcontainers-wasm32': 0.35.3 + '@img/sharp-win32-arm64': 0.35.3 + '@img/sharp-win32-ia32': 0.35.3 + '@img/sharp-win32-x64': 0.35.3 + '@types/node': 20.11.20 + shebang-command@2.0.0: dependencies: shebang-regex: 3.0.0 @@ -3846,9 +4198,9 @@ snapshots: std-env@3.7.0: {} - stream-parser@0.3.1: + stream-parser@0.3.1(supports-color@7.2.0): dependencies: - debug: 2.6.9 + debug: 2.6.9(supports-color@7.2.0) transitivePeerDependencies: - supports-color @@ -3933,10 +4285,10 @@ snapshots: dependencies: svelte-floating-ui: 1.5.8 - svelte-youtube@0.0.2(svelte@4.2.12): + svelte-youtube@0.0.2(supports-color@7.2.0)(svelte@4.2.12): dependencies: svelte: 4.2.12 - youtube-player: 5.6.0 + youtube-player: 5.6.0(supports-color@7.2.0) transitivePeerDependencies: - supports-color @@ -3957,10 +4309,10 @@ snapshots: magic-string: 0.30.7 periscopic: 3.1.0 - tap-mocha-reporter@5.0.4: + tap-mocha-reporter@5.0.4(supports-color@7.2.0): dependencies: color-support: 1.1.3 - debug: 4.3.4 + debug: 4.3.4(supports-color@7.2.0) diff: 4.0.2 escape-string-regexp: 2.0.0 glob: 7.2.3 @@ -4104,10 +4456,10 @@ snapshots: unist-util-stringify-position: 3.0.3 vfile-message: 3.1.4 - vite-node@1.3.1(@types/node@20.11.20): + vite-node@1.3.1(@types/node@20.11.20)(supports-color@7.2.0): dependencies: cac: 6.7.14 - debug: 4.3.4 + debug: 4.3.4(supports-color@7.2.0) pathe: 1.1.2 picocolors: 1.0.0 vite: 5.1.4(@types/node@20.11.20) @@ -4134,7 +4486,7 @@ snapshots: optionalDependencies: vite: 5.1.4(@types/node@20.11.20) - vitest@1.3.1(@types/node@20.11.20): + vitest@1.3.1(@types/node@20.11.20)(supports-color@7.2.0): dependencies: '@vitest/expect': 1.3.1 '@vitest/runner': 1.3.1 @@ -4143,7 +4495,7 @@ snapshots: '@vitest/utils': 1.3.1 acorn-walk: 8.3.2 chai: 4.4.1 - debug: 4.3.4 + debug: 4.3.4(supports-color@7.2.0) execa: 8.0.1 local-pkg: 0.5.0 magic-string: 0.30.7 @@ -4154,7 +4506,7 @@ snapshots: tinybench: 2.6.0 tinypool: 0.8.2 vite: 5.1.4(@types/node@20.11.20) - vite-node: 1.3.1(@types/node@20.11.20) + vite-node: 1.3.1(@types/node@20.11.20)(supports-color@7.2.0) why-is-node-running: 2.2.2 optionalDependencies: '@types/node': 20.11.20 @@ -4167,13 +4519,13 @@ snapshots: - supports-color - terser - wav@1.0.2: + wav@1.0.2(supports-color@7.2.0): dependencies: buffer-alloc: 1.2.0 buffer-from: 1.1.2 - debug: 2.6.9 + debug: 2.6.9(supports-color@7.2.0) readable-stream: 1.1.14 - stream-parser: 0.3.1 + stream-parser: 0.3.1(supports-color@7.2.0) transitivePeerDependencies: - supports-color @@ -4230,9 +4582,9 @@ snapshots: yocto-queue@1.0.0: {} - youtube-player@5.6.0: + youtube-player@5.6.0(supports-color@7.2.0): dependencies: - debug: 4.3.4 + debug: 4.3.4(supports-color@7.2.0) load-script: 1.0.0 sister: 3.0.2 transitivePeerDependencies: diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml new file mode 100644 index 00000000..0996ae77 --- /dev/null +++ b/pnpm-workspace.yaml @@ -0,0 +1,5 @@ +allowBuilds: + '@sveltejs/kit': true + core-js: true + esbuild: true + svelte-preprocess: true diff --git a/scripts/optimise-images.js b/scripts/optimise-images.js new file mode 100644 index 00000000..4fe89839 --- /dev/null +++ b/scripts/optimise-images.js @@ -0,0 +1,84 @@ +import fs from 'node:fs'; +import path from 'node:path'; +import sharp from 'sharp'; + +const STATIC_DIR = 'static'; +const WIDTHS = [640, 960, 1280]; +const IMAGE_EXTS = new Set(['.png', '.jpg', '.jpeg', '.webp', '.gif']); +const JPEG_OPTIONS = { quality: 88, mozjpeg: true }; + +let total = 0; +let skipped = 0; +let generated = 0; + +function* walkImages(dir) { + const entries = fs.readdirSync(dir, { withFileTypes: true }); + for (const entry of entries) { + const full = path.join(dir, entry.name); + if (entry.isDirectory() && !entry.name.startsWith('.')) { + yield* walkImages(full); + } else if (entry.isFile() && IMAGE_EXTS.has(path.extname(entry.name).toLowerCase())) { + // Skip generated variants (e.g., img-480w.jpeg) + if (/-\d+w\.jpe?g$/i.test(entry.name)) continue; + yield full; + } + } +} + +async function processImage(filePath) { + total++; + + const ext = path.extname(filePath); + const baseName = filePath.slice(0, -ext.length); + + // Get original dimensions + let metadata; + try { + metadata = await sharp(filePath).metadata(); + } catch { + console.warn(` ⚠ Cannot read: ${filePath}`); + return; + } + + const nativeW = metadata.width; + if (!nativeW) { + console.warn(` ⚠ No width metadata: ${filePath}`); + return; + } + + for (const w of WIDTHS) { + // Don't upscale — clamp to native width if image is smaller than the target + const resizeW = Math.min(w, nativeW); + + const jpegDest = `${baseName}-${w}w.jpeg`; + + // Skip if already generated and source hasn't changed + const srcMtime = fs.statSync(filePath).mtimeMs; + + if (fs.existsSync(jpegDest) && fs.statSync(jpegDest).mtimeMs > srcMtime) { + skipped++; + continue; + } + + try { + const pipeline = sharp(filePath).resize(resizeW).withMetadata(false); + + // Generate JPEG + await pipeline.clone().jpeg(JPEG_OPTIONS).toFile(jpegDest); + + generated++; + } catch (err) { + console.warn(` ⚠ Failed ${filePath} @ ${w}w: ${err.message}`); + } + } +} + +console.log('Optimizing images in static/ ...\n'); + +for (const filePath of walkImages(STATIC_DIR)) { + const rel = path.relative(STATIC_DIR, filePath); + process.stdout.write(` ${rel.padEnd(60)}\r`); + await processImage(filePath); +} + +console.log(`\nDone. ${total} images → ${generated} variants generated, ${skipped} skipped (up to date).\n`); diff --git a/src/lib/components/Image.svelte b/src/lib/components/Image.svelte index 3bf8bd6d..8543f496 100644 --- a/src/lib/components/Image.svelte +++ b/src/lib/components/Image.svelte @@ -1,23 +1,46 @@
- (loaded = true)} - class:loaded - /> + + + (loaded = true)} + class:loaded + /> + {#if label}
@@ -49,6 +72,7 @@ img { display: block; max-width: 100%; + height: auto; padding-top: var(--space-4); padding-bottom: var(--space-4); opacity: 0; diff --git a/src/lib/components/cards/Article.svelte b/src/lib/components/cards/Article.svelte index 4b80ef75..83b429de 100644 --- a/src/lib/components/cards/Article.svelte +++ b/src/lib/components/cards/Article.svelte @@ -4,6 +4,11 @@ import _ from 'lodash'; export let data = {}; + + $: featuredSrc = data.feature.featuredimage || + _.sample(data.feature.images) || + '/general/learn_default.jpeg'; + $: featuredBase = featuredSrc.replace(/\.(png|jpe?g|webp|gif)$/i, ''); @@ -13,12 +18,15 @@
-
+ + + {data.title} +

{data.blurb}

@@ -70,11 +78,9 @@ .card-image { width: 100%; - height: 10em; + height: 100%; + object-fit: cover; border: 1px solid var(--color-neutral-200); - background-position: center; - background-repeat: no-repeat; - background-size: cover; border-radius: var(--radius-sm); transition: transform 0.5s ease; } diff --git a/src/lib/components/mosaic/Article.svelte b/src/lib/components/mosaic/Article.svelte index ada59ad2..8d77cd3e 100644 --- a/src/lib/components/mosaic/Article.svelte +++ b/src/lib/components/mosaic/Article.svelte @@ -1,5 +1,6 @@
- {item.title} + + + {item.title} +
{item.flair}
diff --git a/src/routes/(content)/get-started/Map.svelte b/src/routes/(content)/get-started/Map.svelte index 87ef2fef..d79a3a38 100644 --- a/src/routes/(content)/get-started/Map.svelte +++ b/src/routes/(content)/get-started/Map.svelte @@ -1,6 +1,6 @@