diff --git a/astro.config.ts b/astro.config.ts index 5e391210..4dabdd91 100644 --- a/astro.config.ts +++ b/astro.config.ts @@ -1,5 +1,5 @@ import { defineConfig } from "astro/config"; -import unpluginFavicons from "@openscript/unplugin-favicons/vite"; +import unpluginFavicons from "@anolilab/unplugin-favicons/vite"; import { C } from "./src/site.config"; import mdx from "@astrojs/mdx"; import rehypeSlug from "rehype-slug"; @@ -59,4 +59,7 @@ export default defineConfig({ mdx(), sitemap({ i18n: { defaultLocale: C.DEFAULT_LOCALE, locales: C.LOCALES } }), ], + image: { + responsiveStyles: true, + }, }); diff --git a/package.json b/package.json index 1f665719..3fcafefb 100644 --- a/package.json +++ b/package.json @@ -54,7 +54,7 @@ "devDependencies": { "@changesets/cli": "^2.31.0", "@eslint/js": "^10.0.1", - "@openscript/unplugin-favicons": "^1.1.8", + "@anolilab/unplugin-favicons": "^3.0.0", "@types/mdast": "^4.0.4", "@types/node": "^25.6.2", "@typescript-eslint/parser": "^8.59.2", @@ -81,4 +81,4 @@ "sharp" ] } -} +} \ No newline at end of file diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index db794a28..3aafc01e 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -72,15 +72,15 @@ importers: specifier: ^6.0.3 version: 6.0.3 devDependencies: + '@anolilab/unplugin-favicons': + specifier: ^3.0.0 + version: 3.0.0(@types/node@25.9.3)(esbuild@0.27.7)(favicons@7.3.0)(vite@7.3.5(@types/node@25.9.3)(jiti@2.7.0)(yaml@2.8.4)) '@changesets/cli': specifier: ^2.31.0 version: 2.31.0(@types/node@25.9.3) '@eslint/js': specifier: ^10.0.1 version: 10.0.1(eslint@10.4.1(jiti@2.7.0)) - '@openscript/unplugin-favicons': - specifier: ^1.1.8 - version: 1.1.8(@types/node@25.9.3)(favicons@7.3.0)(rollup@4.61.1)(vite@7.3.5(@types/node@25.9.3)(jiti@2.7.0)(yaml@2.8.4))(yaml@2.8.4) '@types/mdast': specifier: ^4.0.4 version: 4.0.4 @@ -141,6 +141,40 @@ importers: packages: + '@anolilab/unplugin-favicons@3.0.0': + resolution: {integrity: sha512-h8xKkIFyG/xnJXrfChPY8E7SWuh4KS6BDgIBJoaVh2Tt7MrMk04FFfz3xuzufzymGNSUZg4UCy/vS09dmmvc2Q==} + engines: {node: '>=18.0.0'} + peerDependencies: + '@nuxt/kit': ^3 + '@nuxt/schema': ^3 + '@rspack/cli': ^1.1.8 + '@sveltejs/kit': '*' + esbuild: '*' + favicons: ^7.2.0 + rollup: ^3.0.1 + vite: ^8.0.16 + webpack: ^4 || ^5 + peerDependenciesMeta: + '@nuxt/kit': + optional: true + '@nuxt/schema': + optional: true + '@rspack/cli': + optional: true + '@sveltejs/kit': + optional: true + esbuild: + optional: true + rollup: + optional: true + vite: + optional: true + webpack: + optional: true + + '@antfu/install-pkg@1.1.0': + resolution: {integrity: sha512-MGQsmw10ZyI+EJo45CdSER4zEb+p31LpDAFp2Z3gkSd1yqVZGi0Ebx++YTEMonJy4oChEMLsxZ64j8FH6sSqtQ==} + '@astrojs/check@0.9.9': resolution: {integrity: sha512-A5UW8uIuErLWEoRQvzgXpO1gTjUFtK8r7nU2Z7GewAMxUb7bPvpk11qaKKgxqXlHJWlAvaaxy+Xg28A6bmQ1Tg==} hasBin: true @@ -954,40 +988,9 @@ packages: resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} engines: {node: '>= 8'} - '@npmcli/fs@5.0.0': - resolution: {integrity: sha512-7OsC1gNORBEawOa5+j2pXN9vsicaIOH5cPXxoR6fJOmH6/EXpJB2CajXOu1fPRFun2m1lktEFX11+P89hqO/og==} - engines: {node: ^20.17.0 || >=22.9.0} - - '@openscript/unplugin-favicons@1.1.8': - resolution: {integrity: sha512-AEKKZawbSCJ7JsgRVRrlnPWh80sBMfTViKqmD76L6sAKTy9ZjyVSc8Nt0jdY2nXLPl7rBeDEHhVkWUXSA3I+Cg==} - engines: {node: '>=22.0.0'} - peerDependencies: - '@nuxt/kit': ^3 || ^4.0.0 - '@nuxt/schema': ^3 || ^4.0.0 - '@rspack/cli': ^1.3.15 - '@sveltejs/kit': '*' - esbuild: ^0.25.5 - favicons: ^7.2.0 - rollup: ^3.0.0 || ^4.0.0 - vite: ^4 || ^5 || ^6 || ^7 - webpack: ^4 || ^5 - peerDependenciesMeta: - '@nuxt/kit': - optional: true - '@nuxt/schema': - optional: true - '@rspack/cli': - optional: true - '@sveltejs/kit': - optional: true - esbuild: - optional: true - rollup: - optional: true - vite: - optional: true - webpack: - optional: true + '@npmcli/fs@6.0.0': + resolution: {integrity: sha512-AheOs4swKka/XLtht6xxJDPezlQ7K2IYQ9Y8lST4JLDjnralnWuMM9AE2CdVcgQJ5omrXhsRzM7F7aYmeZBvKQ==} + engines: {node: ^22.22.2 || ^24.15.0 || >=26.0.0} '@oslojs/encoding@1.1.0': resolution: {integrity: sha512-70wQhgYmndg4GCPxPPxPGevRKqTIJ2Nh4OkiMWmDAVYsTQ+Ta7Sq+rPevXyXGdzr30/qZBnyOalCszoMxlyldQ==} @@ -1435,28 +1438,28 @@ packages: '@ungap/structured-clone@1.3.1': resolution: {integrity: sha512-mUFwbeTqrVgDQxFveS+df2yfap6iuP20NAKAsBt5jDEoOTDew+zwLAOilHCeQJOVSvmgCX4ogqIrA0mnyr08yQ==} - '@visulima/find-cache-dir@1.0.35': - resolution: {integrity: sha512-z686U0T/l+ZizdxLmvIxdS1YiP60bhsz3+U6hLxHgMhaHABgfsXnJUvExwovxg/us473CTtxA/eAImdNAruTAg==} - engines: {node: '>=18.0.0 <=23.x'} + '@visulima/find-cache-dir@2.0.7': + resolution: {integrity: sha512-70JKCdm5p5iEBnJpvq1eEKFe8CcJx/RnHB9/LyfmuJjxHZVa1cbT4PhccRNGtzoPsg/l73gu09CJHjLt135B0g==} + engines: {node: '>=20.19 <=25.x'} - '@visulima/fs@3.1.9': - resolution: {integrity: sha512-0D9iREfekQmjAgOq+L3CU9TgpeunIwQ4BISq0vxEZuv2CjOLqqHGlkgFRlEgh2pBrHO3azF0OUGbPoK/1QmCUQ==} - engines: {node: '>=18.0.0 <=23.x'} + '@visulima/fs@4.1.0': + resolution: {integrity: sha512-9bb7oupbXXXc++m8Ypj+VUBF+P1j/Y3gadoT2HQHPHqDMrpMt8pcZyXjofitw/DaYSB3EeQOvGqHdgvsY646sw==} + engines: {node: '>=20.19 <=25.x'} os: [darwin, linux, win32] peerDependencies: - yaml: ^2.7.0 + yaml: ^2.7.1 peerDependenciesMeta: yaml: optional: true - '@visulima/package@3.6.1': - resolution: {integrity: sha512-dl36K1Y1clZbk0ouomnZbUxAE+ELAi2WgQeqSyxCRgY+HesbXgZBKDsJ811l3WWXJsaTv5m4oopfGzTJI34sUg==} - engines: {node: '>=18.0.0 <=23.x'} + '@visulima/package@4.1.7': + resolution: {integrity: sha512-xGzw2GFlHBleNgLYip6ZULKMZZAZrLGE5RJ2shKj4MUcAsv7IQzafyGa3m2PRw6HJSYeEpboobPVxf8SbCfm+w==} + engines: {node: '>=20.19 <=25.x'} os: [darwin, linux, win32] - '@visulima/path@1.4.0': - resolution: {integrity: sha512-lhtA4woh4KsXWyn3BJ/qYE/HSt+agsHeSGb7j3UeHpRyf3R4ErObR25snvt+Rc4Xlqb1T68U38wjqZ2YpmUGNw==} - engines: {node: '>=18.0.0 <=23.x'} + '@visulima/path@2.0.5': + resolution: {integrity: sha512-DBQe4IeEn1Yx03HQUlxog4sDJEQiVKnr2Kdm1acK6CgdcNN0fveoTfSvPsrxTKmMqdTgBbvB6UMUFh53cV+jgg==} + engines: {node: '>=20.19 <=25.x'} os: [darwin, linux, win32] '@vitest/coverage-v8@4.1.8': @@ -1700,9 +1703,9 @@ packages: resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} engines: {node: '>=8'} - cacache@20.0.4: - resolution: {integrity: sha512-M3Lab8NPYlZU2exsL3bMVvMrMqgwCnMWfdZbK28bn3pK6APT/Te/I8hjRPNu1uwORY9a1eEQoifXbKPQMfMTOA==} - engines: {node: ^20.17.0 || >=22.9.0} + cacache@21.0.1: + resolution: {integrity: sha512-pTwz/uj3Jyp6WXdJ6fWhR+7LVxVs6RyroQSn7KJwHsSxXuyGSp0pcMVcwSwTpCFq1X2YG8QBe0W+vN+cr0SwzA==} + engines: {node: ^22.22.2 || ^24.15.0 || >=26.0.0} call-bind-apply-helpers@1.0.2: resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==} @@ -2747,6 +2750,11 @@ packages: json-stable-stringify-without-jsonify@1.0.1: resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} + json5@2.2.3: + resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} + engines: {node: '>=6'} + hasBin: true + jsonc-parser@2.3.1: resolution: {integrity: sha512-H8jvkz1O50L3dMZCsLqiuB2tA7muqbSg1AtGEkN0leAqGjsUzDJir3Zwr02BhqdcITPg3ei3mZ+HjMocAknhhg==} @@ -2809,17 +2817,10 @@ packages: longest-streak@3.1.0: resolution: {integrity: sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==} - lru-cache@11.3.6: - resolution: {integrity: sha512-Gf/KoL3C/MlI7Bt0PGI9I+TeTC/I6r/csU58N4BSNc4lppLBeKsOdFYkK+dX0ABDUMJNfCHTyPpzwwO21Awd3A==} - engines: {node: 20 || >=22} - lru-cache@11.5.1: resolution: {integrity: sha512-RPimw/7aMdv2oqRrxKwvZXcPfwBrn/JZ2xYcY9Hus/6LaS3VOAKVWKWgNLCFSiOm1ESXinjsDlidVU7JlnCN2A==} engines: {node: 20 || >=22} - magic-string@0.30.19: - resolution: {integrity: sha512-2N21sPY9Ws53PZvsEpVtNuSW+ScYbQdp4b9qUaL+9QkHUrGFKo56Lg9Emg5s9V/qrtNBmiR01sYhUOwu3H+VOw==} - magic-string@0.30.21: resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==} @@ -3049,6 +3050,9 @@ packages: mlly@1.8.0: resolution: {integrity: sha512-l8D9ODSRWLe2KHJSifWGwBqpTZXIXTeo8mlKjY+E2HAakaTeNpqAyBZ8GSqLzHgw4XmHmC8whvpjJNMbFZN7/g==} + mlly@1.8.2: + resolution: {integrity: sha512-d+ObxMQFmbt10sretNDytwt85VrbkhhUA/JBGm1MPaWJ65Cl4wOgLaB1NYvJSZ0Ef03MMEU/0xpPMXUIQ29UfA==} + mri@1.2.0: resolution: {integrity: sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==} engines: {node: '>=4'} @@ -3656,13 +3660,9 @@ packages: sprintf-js@1.0.3: resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==} - ssri@12.0.0: - resolution: {integrity: sha512-S7iGNosepx9RadX82oimUkvr0Ct7IjJbEbs4mJcTxst8um95J3sDYU1RBEOvdu6oL1Wek2ODI5i4MAw+dZ6cAQ==} - engines: {node: ^18.17.0 || >=20.5.0} - - ssri@13.0.1: - resolution: {integrity: sha512-QUiRf1+u9wPTL/76GTYlKttDEBWV1ga9ZXW8BG6kfdeyyM8LGPix9gROyg9V2+P0xNyF3X2Go526xKFdMZrHSQ==} - engines: {node: ^20.17.0 || >=22.9.0} + ssri@14.0.0: + resolution: {integrity: sha512-jQxKI0yx0ZnTKrqjKkLDV2DXkBQn3k49JVmVqDGcDwKDtGDbImD/GXsq04KD0VVzCQQ9wZJYal3RwR1GzWTSow==} + engines: {node: ^22.22.2 || ^24.15.0 || >=26.0.0} stable@0.1.8: resolution: {integrity: sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w==} @@ -3756,6 +3756,10 @@ packages: resolution: {integrity: sha512-eNRKgb3z66Yp3D2CixVujOUvXLFUTij/zVnV8KRyvFdQwpz7I5DS8UfRkTeLzb64u+dkzDSdelE24izu+zSSUg==} engines: {node: ^14.18.0 || >=16.0.0} + tagged-tag@1.0.0: + resolution: {integrity: sha512-yEFYrVhod+hdNyx7g5Bnkkb0G6si8HJurOoOEgC8B/O0uXLHlaey/65KRv6cuWBNhBgHKAROVpc7QyYqE5gFng==} + engines: {node: '>=20'} + term-size@2.2.1: resolution: {integrity: sha512-wK0Ri4fOGjv/XPy8SBHZChl8CM7uMc5VML7SqiQ0zG7+J5Vr+RMQDoHa2CNT6KHUnTGIXH34UDMkPzAUyapBZg==} engines: {node: '>=8'} @@ -3824,6 +3828,10 @@ packages: resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} engines: {node: '>= 0.8.0'} + type-fest@5.7.0: + resolution: {integrity: sha512-1URUxUqfHFM1c+zfSPsa3gnkO7Aq21qyH75SIduNYz4SzY964rn1X2vCMQaHSHhktiw+0kPa2iyb6PUpXqB6Vg==} + engines: {node: '>=20'} + typed-array-buffer@1.0.3: resolution: {integrity: sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==} engines: {node: '>= 0.4'} @@ -3917,9 +3925,38 @@ packages: resolution: {integrity: sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==} engines: {node: '>= 4.0.0'} - unplugin@2.3.11: - resolution: {integrity: sha512-5uKD0nqiYVzlmCRs01Fhs2BdkEgBS3SAVP6ndrBsuK42iC2+JHyxM05Rm9G8+5mkmRtzMZGY8Ct5+mliZxU/Ww==} - engines: {node: '>=18.12.0'} + unplugin@3.3.0: + resolution: {integrity: sha512-qa66K+crbfyE6JK10GjvbJeRrOsuC/JpbnHctfyp/i4oBTxWOzJfRZyDiOk1PtErMFRu8JhsU/wPvOdBNWe5Rg==} + engines: {node: ^20.19.0 || >=22.12.0} + peerDependencies: + '@farmfe/core': '*' + '@rspack/core': '*' + bun-types-no-globals: '*' + esbuild: '*' + rolldown: '*' + rollup: '*' + unloader: '*' + vite: '*' + webpack: '*' + peerDependenciesMeta: + '@farmfe/core': + optional: true + '@rspack/core': + optional: true + bun-types-no-globals: + optional: true + esbuild: + optional: true + rolldown: + optional: true + rollup: + optional: true + unloader: + optional: true + vite: + optional: true + webpack: + optional: true unstorage@1.17.5: resolution: {integrity: sha512-0i3iqvRfx29hkNntHyQvJTpf5W9dQ9ZadSoRU8+xVlhVtT7jAX57fazYO9EHvcRCfBCyi5YRya7XCDOsbTgkPg==} @@ -4313,6 +4350,37 @@ packages: snapshots: + '@anolilab/unplugin-favicons@3.0.0(@types/node@25.9.3)(esbuild@0.27.7)(favicons@7.3.0)(vite@7.3.5(@types/node@25.9.3)(jiti@2.7.0)(yaml@2.8.4))': + dependencies: + '@visulima/find-cache-dir': 2.0.7 + '@visulima/package': 4.1.7(@types/node@25.9.3) + cacache: 21.0.1 + consola: 3.4.2 + fast-json-stable-stringify: 2.1.0 + favicons: 7.3.0 + magic-string: 0.30.21 + mime: 4.1.0 + mlly: 1.8.2 + parse-author: 2.0.0 + parse5: 8.0.1 + ssri: 14.0.0 + unplugin: 3.3.0(esbuild@0.27.7)(vite@7.3.5(@types/node@25.9.3)(jiti@2.7.0)(yaml@2.8.4)) + optionalDependencies: + esbuild: 0.27.7 + vite: 7.3.5(@types/node@25.9.3)(jiti@2.7.0)(yaml@2.8.4) + transitivePeerDependencies: + - '@farmfe/core' + - '@rspack/core' + - '@types/node' + - bun-types-no-globals + - rolldown + - unloader + + '@antfu/install-pkg@1.1.0': + dependencies: + package-manager-detector: 1.6.0 + tinyexec: 1.2.4 + '@astrojs/check@0.9.9(prettier-plugin-astro@0.14.1)(prettier@3.8.4)(typescript@6.0.3)': dependencies: '@astrojs/language-server': 2.16.8(prettier-plugin-astro@0.14.1)(prettier@3.8.4)(typescript@6.0.3) @@ -5136,32 +5204,10 @@ snapshots: '@nodelib/fs.scandir': 2.1.5 fastq: 1.20.1 - '@npmcli/fs@5.0.0': + '@npmcli/fs@6.0.0': dependencies: semver: 7.8.4 - '@openscript/unplugin-favicons@1.1.8(@types/node@25.9.3)(favicons@7.3.0)(rollup@4.61.1)(vite@7.3.5(@types/node@25.9.3)(jiti@2.7.0)(yaml@2.8.4))(yaml@2.8.4)': - dependencies: - '@visulima/find-cache-dir': 1.0.35(yaml@2.8.4) - '@visulima/package': 3.6.1(@types/node@25.9.3)(yaml@2.8.4) - cacache: 20.0.4 - consola: 3.4.2 - fast-json-stable-stringify: 2.1.0 - favicons: 7.3.0 - magic-string: 0.30.19 - mime: 4.1.0 - mlly: 1.8.0 - parse-author: 2.0.0 - parse5: 8.0.1 - ssri: 12.0.0 - unplugin: 2.3.11 - optionalDependencies: - rollup: 4.61.1 - vite: 7.3.5(@types/node@25.9.3)(jiti@2.7.0)(yaml@2.8.4) - transitivePeerDependencies: - - '@types/node' - - yaml - '@oslojs/encoding@1.1.0': {} '@pagefind/darwin-arm64@1.5.2': @@ -5538,30 +5584,28 @@ snapshots: '@ungap/structured-clone@1.3.1': {} - '@visulima/find-cache-dir@1.0.35(yaml@2.8.4)': - dependencies: - '@visulima/fs': 3.1.9(yaml@2.8.4) - '@visulima/path': 1.4.0 - transitivePeerDependencies: - - yaml + '@visulima/find-cache-dir@2.0.7': {} - '@visulima/fs@3.1.9(yaml@2.8.4)': + '@visulima/fs@4.1.0(yaml@2.8.4)': dependencies: - '@visulima/path': 1.4.0 + '@visulima/path': 2.0.5 + type-fest: 5.7.0 optionalDependencies: yaml: 2.8.4 - '@visulima/package@3.6.1(@types/node@25.9.3)(yaml@2.8.4)': + '@visulima/package@4.1.7(@types/node@25.9.3)': dependencies: + '@antfu/install-pkg': 1.1.0 '@inquirer/confirm': 5.1.21(@types/node@25.9.3) - '@visulima/fs': 3.1.9(yaml@2.8.4) - '@visulima/path': 1.4.0 + '@visulima/fs': 4.1.0(yaml@2.8.4) + '@visulima/path': 2.0.5 + json5: 2.2.3 normalize-package-data: 8.0.0 + yaml: 2.8.4 transitivePeerDependencies: - '@types/node' - - yaml - '@visulima/path@1.4.0': {} + '@visulima/path@2.0.5': {} '@vitest/coverage-v8@4.1.8(vitest@4.1.8)': dependencies: @@ -5940,18 +5984,18 @@ snapshots: dependencies: fill-range: 7.1.1 - cacache@20.0.4: + cacache@21.0.1: dependencies: - '@npmcli/fs': 5.0.0 + '@npmcli/fs': 6.0.0 fs-minipass: 3.0.3 glob: 13.0.6 - lru-cache: 11.3.6 + lru-cache: 11.5.1 minipass: 7.1.3 minipass-collect: 2.0.1 minipass-flush: 1.0.7 minipass-pipeline: 1.2.4 p-map: 7.0.4 - ssri: 13.0.1 + ssri: 14.0.0 call-bind-apply-helpers@1.0.2: dependencies: @@ -7175,6 +7219,8 @@ snapshots: json-stable-stringify-without-jsonify@1.0.1: {} + json5@2.2.3: {} + jsonc-parser@2.3.1: {} jsonc-parser@3.3.1: {} @@ -7240,14 +7286,8 @@ snapshots: longest-streak@3.1.0: {} - lru-cache@11.3.6: {} - lru-cache@11.5.1: {} - magic-string@0.30.19: - dependencies: - '@jridgewell/sourcemap-codec': 1.5.5 - magic-string@0.30.21: dependencies: '@jridgewell/sourcemap-codec': 1.5.5 @@ -7749,6 +7789,13 @@ snapshots: pkg-types: 1.3.1 ufo: 1.6.4 + mlly@1.8.2: + dependencies: + acorn: 8.16.0 + pathe: 2.0.3 + pkg-types: 1.3.1 + ufo: 1.6.4 + mri@1.2.0: {} mrmime@2.0.1: {} @@ -7957,7 +8004,7 @@ snapshots: path-scurry@2.0.2: dependencies: - lru-cache: 11.3.6 + lru-cache: 11.5.1 minipass: 7.1.3 path-type@4.0.0: {} @@ -8530,11 +8577,7 @@ snapshots: sprintf-js@1.0.3: {} - ssri@12.0.0: - dependencies: - minipass: 7.1.3 - - ssri@13.0.1: + ssri@14.0.0: dependencies: minipass: 7.1.3 @@ -8669,6 +8712,8 @@ snapshots: dependencies: '@pkgr/core': 0.3.6 + tagged-tag@1.0.0: {} + term-size@2.2.1: {} text-hex@1.0.0: {} @@ -8718,6 +8763,10 @@ snapshots: dependencies: prelude-ls: 1.2.1 + type-fest@5.7.0: + dependencies: + tagged-tag: 1.0.0 + typed-array-buffer@1.0.3: dependencies: call-bound: 1.0.4 @@ -8851,12 +8900,14 @@ snapshots: universalify@0.1.2: {} - unplugin@2.3.11: + unplugin@3.3.0(esbuild@0.27.7)(vite@7.3.5(@types/node@25.9.3)(jiti@2.7.0)(yaml@2.8.4)): dependencies: '@jridgewell/remapping': 2.3.5 - acorn: 8.16.0 picomatch: 4.0.4 webpack-virtual-modules: 0.6.2 + optionalDependencies: + esbuild: 0.27.7 + vite: 7.3.5(@types/node@25.9.3)(jiti@2.7.0)(yaml@2.8.4) unstorage@1.17.5: dependencies: diff --git a/src/components/Button.astro b/src/components/Button.astro index 618abef3..e7b54cc9 100644 --- a/src/components/Button.astro +++ b/src/components/Button.astro @@ -1,15 +1,26 @@ --- +import { resolveSimplePath } from "../utils/paths"; import Sprite from "./Sprite.astro"; +import { currentLocale } from "astro-nanostores-i18n:runtime"; type Props = { href: string; withArrow?: boolean; + resolvePath?: boolean; + navigationSpace?: "main" | "footer"; }; -const { href, withArrow } = Astro.props; +const { href, resolvePath = false, navigationSpace = "main", withArrow } = Astro.props; + +let path; + +if (resolvePath) { + const locale = currentLocale.get(); + path = await resolveSimplePath(navigationSpace, href, locale); +} --- - + {withArrow && } diff --git a/src/components/Tile.astro b/src/components/Tile.astro new file mode 100644 index 00000000..1198914b --- /dev/null +++ b/src/components/Tile.astro @@ -0,0 +1,114 @@ +--- +type Props = { + id: string; + variant: "default" | "turnable"; + crease?: boolean; + color?: "white" | "beige"; +}; + +const { id, variant, color = "white", crease = false }: Props = Astro.props; +--- + + +
+ +
+ { + variant === "turnable" && ( +
+ +
+ ) + } +
+ + + + diff --git a/src/components/accordion/Accordion.astro b/src/components/accordion/Accordion.astro new file mode 100644 index 00000000..cc80dc16 --- /dev/null +++ b/src/components/accordion/Accordion.astro @@ -0,0 +1,44 @@ +--- +import type { AccordionItem } from "../../types/AccordionItem"; + +/** + * Accordion Component + * + * @description A fully accessible accordion component that follows WAI-ARIA guidelines + */ + +interface Props { + /** + * Additional classes to apply to the accordion container + */ + class?: string; + /** + * Accordion items to render + */ + children: AccordionItem | AccordionItem[]; + /** + * HTML attributes to spread on the accordion + */ + [key: string]: string | number | boolean | undefined | AccordionItem | AccordionItem[]; +} + +const { class: className, ...rest } = Astro.props; +--- + + + + diff --git a/src/components/accordion/AccordionItem.astro b/src/components/accordion/AccordionItem.astro new file mode 100644 index 00000000..7fee7658 --- /dev/null +++ b/src/components/accordion/AccordionItem.astro @@ -0,0 +1,267 @@ +--- +import type { HTMLAttributes } from "astro/types"; +import Heading from "./Heading.astro"; + +/** + * Accordion Item Component + * + * @description An individual accordion item that can be expanded/collapsed with smooth animations + */ + +type Props = HTMLAttributes<"li"> & { + /** + * Id of the item + */ + id: string; + + /** + * Additional classes to apply to the item + */ + class?: string; + /** + * Title text displayed in the accordion header + */ + title: string; + /** + * Optional name attribute for the details element + */ + name?: string; + /** + * Heading level for the title (h1-h6) + * @default 'h3' + */ + headingLevel?: "h1" | "h2" | "h3" | "h4" | "h5" | "h6"; + /** + * Visual size of the heading (can differ from semantic level) + * @default 'h6' + */ + headingSize?: "h1" | "h2" | "h3" | "h4" | "h5" | "h6"; + /** + * Visual style variant of the accordion + * @default 'default' + */ + variant?: "default" | "chevron"; + /** + * Whether the accordion item is initially open + * @default false + */ + open?: boolean; + + /** + * Allow item to be opened by the id in the url + */ + openOnUrlReference?: boolean; +}; + +const { + id, + class: className, + title, + name, + headingLevel = "h3", + headingSize = "h6", + variant = "default", + open = false, + openOnUrlReference = true, + ...rest +}: Props = Astro.props; +--- + +
  • +
    + +
    + + { + variant === "chevron" ? ( + <> + {title} + + + + + ) : ( + <> + + + + + + + {title} + + ) + } + +
    +
    + +
    +
    +
    + +
    +
    +
  • + + + + diff --git a/src/components/accordion/Heading.astro b/src/components/accordion/Heading.astro new file mode 100644 index 00000000..2f30ebb3 --- /dev/null +++ b/src/components/accordion/Heading.astro @@ -0,0 +1,40 @@ +--- +/** + * Heading Component + * @description A versatile heading component that handles all heading levels with proper accessibility + */ +const headingOptions = { + h1: "h1", + h2: "h2", + h3: "h3", + h4: "h4", + h5: "h5", + h6: "h6", +}; + +import type { HTMLAttributes } from "astro/types"; + +interface Props extends HTMLAttributes<"h1" | "h2" | "h3" | "h4" | "h5" | "h6"> { + /** + * The tag name of the heading + */ + level?: keyof typeof headingOptions; + /** + * The size of the heading + */ + size?: keyof typeof headingOptions; +} + +const { level = "h2", size = level, ...rest } = Astro.props; +const Tag = headingOptions[level]; +--- + + + + + + diff --git a/src/content.config.ts b/src/content.config.ts index 109b7368..89991727 100644 --- a/src/content.config.ts +++ b/src/content.config.ts @@ -65,6 +65,7 @@ const referenceCompaniesCollection = defineCollection({ logo: image(), url: z.url().optional(), archived: z.boolean().optional().default(false), + details: z.string().optional(), }), }); @@ -76,8 +77,10 @@ const referenceProjectsCollection = defineCollection({ softwareName: z.string(), title: z.string(), summary: z.string(), + details: z.string().optional(), logo: image(), path: z.url().optional(), + featured: z.boolean().optional().default(false), }), ), }); diff --git a/src/content/pages/de/past/references.mdx b/src/content/pages/de/past/references.mdx index 9d7673da..f08ad8b7 100644 --- a/src/content/pages/de/past/references.mdx +++ b/src/content/pages/de/past/references.mdx @@ -2,3 +2,86 @@ path: referenzen title: Referenzen --- + +import Divider from "../../../../components/Divider.astro"; +import Accordion from "../../../../components/accordion/Accordion.astro"; +import AccordionItem from "../../../../components/accordion/AccordionItem.astro"; +import AxaImage from "../../../references/projects/axa.placeholder.png"; +import DogliImage from "../../../references/projects/dogil.placeholder.png"; +import DocportalImage1 from "../../../references/projects/docportal.placeholder.1.png"; +import DocportalImage2 from "../../../references/projects/docportal.placeholder.2.png"; +import { Image } from "astro:assets"; + +
    + Als Firma haben wir bereits mit vielen Kunden in verschiedensten Projekten gearbeitet. Wir haben daher bereits + Erfahrung mit Webapplikationen, Handy-Apps, Kurse im Bereich IT und weiteres. +
    + + + +
    + + + Mit dem Team Dogli konnten wir eine App für Hundeliebhaber ins Leben rufen. + Die Dogli-App bietet über 300 video basierte bereichernde Lerninhalte für Zuhause ohne teures Zubehör. + + Teile deine Hundeerlebnisse mit der Dogli-Community oder verfolge die Posts des neusten Social Media Hunde-Star. + +Dogli App + + + + Das DocPortal wurde für den ZLI entwickelt und dient als Plattform zur Verwaltung von Daten sowie zur automatisierten Erstellung von PDF-Dokumenten. + Zusätzlich unterstützt die Applikation digitale Signaturen, wodurch Dokumente vollständig papierlos verarbeitet und unterzeichnet werden können. + + Mithilfe von konfigurierbaren Dokumentenvorlagen können die Dokumente von Jahr zu Jahr nach Anforderungen angepasst werden. + + Das folgende Beispiel zeigt die Datenerfassung eines Bildungsberichtes innerhalb des DocPortals. + + Datenerfassung eines Bildungsberichtes + + Daraus entsteht ein ausgefülltes PDF-Dokument. + + Generiertes PDF + + + + + openscript hat für die Axa einige Ausbildungskurse erstellt und führt diese Jährlich durch. + Diese Ausbildungskurse dienen als spezielle Weiterbildung für die Lernende der Axa bei denen Sie wichtige IT Themen kennenlernen. + Der Themenbereich deckt sich von Webtechnologien bis zu der Java persistence API und Linux in verschiedenen Kursen ab. + + Axa Kurse + + +
    + + + +
    + Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec nec risus sit amet nisl consectetur suscipit. Duis diam + dui, ultricies ut dolor vel, venenatis egestas ex. Ut vitae nibh arcu. Suspendisse varius risus id blandit fermentum. + Pellentesque dictum viverra nisi, id congue ex elementum sed. Donec bibendum libero vitae dui accumsan, ac rhoncus mi + pellentesque. Aliquam erat volutpat. Morbi bibendum feugiat dolor non tristique. Aliquam erat volutpat. +
    diff --git a/src/content/pages/en/past/references.mdx b/src/content/pages/en/past/references.mdx index 4ae6d730..e84292a5 100644 --- a/src/content/pages/en/past/references.mdx +++ b/src/content/pages/en/past/references.mdx @@ -2,3 +2,82 @@ path: references title: References --- + +import Divider from "../../../../components/Divider.astro"; +import Accordion from "../../../../components/accordion/Accordion.astro"; +import AccordionItem from "../../../../components/accordion/AccordionItem.astro"; +import AxaImage from "../../../references/projects/axa.placeholder.png"; +import DogliImage from "../../../references/projects/dogil.placeholder.png"; +import DocportalImage1 from "../../../references/projects/docportal.placeholder.1.png"; +import DocportalImage2 from "../../../references/projects/docportal.placeholder.2.png"; +import { Image } from "astro:assets"; + +
    + Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec nec risus sit amet nisl consectetur suscipit. Duis diam + dui, ultricies ut dolor vel, venenatis egestas ex. Ut vitae nibh arcu. Suspendisse varius risus id blandit fermentum. + Pellentesque dictum viverra nisi, id congue ex elementum sed. Donec bibendum libero vitae dui accumsan, ac rhoncus mi + pellentesque. Aliquam erat volutpat. Morbi bibendum feugiat dolor non tristique. Aliquam erat volutpat. +
    + + + +
    + + + Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec nec risus sit amet nisl consectetur suscipit. Duis diam + dui, ultricies ut dolor vel, venenatis egestas ex. Ut vitae nibh arcu. Suspendisse varius risus id blandit fermentum. + + Dogli App + + + + The DocPortal was developed for the "name" and serves as a platform for managing data as well as for the automated generation of PDF documents. + In addition, the application supports digital signatures, allowing documents to be processed and signed completely paperless. + + With the help of configurable document templates, the documents can be adapted from year to year according to requirements. + + The following example shows the data entry of an education report within the DocPortal. + + Datenerfassung eines Bildungsberichtes + + This results in a completed PDF document. + + Generiertes PDF + + + + + Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec nec risus sit amet nisl consectetur suscipit. Duis diam + dui, ultricies ut dolor vel, venenatis egestas ex. Ut vitae nibh arcu. Suspendisse varius risus id blandit fermentum. + + Axa Kurse + + +
    + + + +
    + Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec nec risus sit amet nisl consectetur suscipit. Duis diam + dui, ultricies ut dolor vel, venenatis egestas ex. Ut vitae nibh arcu. Suspendisse varius risus id blandit fermentum. + Pellentesque dictum viverra nisi, id congue ex elementum sed. Donec bibendum libero vitae dui accumsan, ac rhoncus mi + pellentesque. Aliquam erat volutpat. Morbi bibendum feugiat dolor non tristique. Aliquam erat volutpat. +
    diff --git a/src/content/references/companies/index.yaml b/src/content/references/companies/index.yaml index 1633596f..bb2efc79 100644 --- a/src/content/references/companies/index.yaml +++ b/src/content/references/companies/index.yaml @@ -2,35 +2,43 @@ companyName: Bundesamt für Strassen ASTRA logo: ./astra.svg url: https://www.astra.admin.ch + details: text - id: dogli companyName: DOGLi GmbH logo: ./dogli.svg url: https://dogli.app + details: text - id: haslerrail companyName: HaslerRail AG logo: ./haslerrail.svg url: https://www.haslerrail.com + details: text - id: hydrowatt companyName: Hydrowatt AG logo: ./hydrowatt.svg url: https://www.hydrowatt.com + details: text - id: schalthalle companyName: Verein Schalthalle logo: ./schalthalle.svg url: https://www.schalthalle.ch + details: text - id: sto companyName: STO Innenausbau AG logo: ./sto.svg url: https://sto-innenausbau.ch + details: text archived: true - id: uzh companyName: Universität Zürich logo: ./uzh.svg url: https://www.uzh.ch + details: text - id: wagner companyName: Wagner Unternehmungen AG logo: ./wagner.svg url: https://wagner-rohbau.ch + details: text - id: wiegand companyName: Wiegand AG logo: ./wiegand.png @@ -45,3 +53,4 @@ companyName: Zürcher Lehrbetriebsverband ICT logo: ./zli.svg url: https://zli.ch + details: text diff --git a/src/content/references/projects/axa.placeholder.png b/src/content/references/projects/axa.placeholder.png new file mode 100644 index 00000000..0458f612 Binary files /dev/null and b/src/content/references/projects/axa.placeholder.png differ diff --git a/src/content/references/projects/certification.de.md b/src/content/references/projects/certification.de.md index d7eaea2e..77dc53df 100644 --- a/src/content/references/projects/certification.de.md +++ b/src/content/references/projects/certification.de.md @@ -3,6 +3,6 @@ softwareName: Zertifizierungstool title: Unbeaufsichtigtes Online-Zertifizierungstool für eine internationale Organisation logo: ./certification.svg summary: Mit diesem Tool können Sie Ihren Zertifizierungsprozess organisieren. Es ermöglicht Personen periodisch zur Zertifizierung einzuladen, es führt den Zertifizierungsprozess durch und übergibt Ihnen nach erfolgreicher Zertifizierung schön formatierte PDF-Dokumente. +featured: true +details: Mehr text --- - - diff --git a/src/content/references/projects/certification.en.md b/src/content/references/projects/certification.en.md index d2e086fc..f2006313 100644 --- a/src/content/references/projects/certification.en.md +++ b/src/content/references/projects/certification.en.md @@ -3,6 +3,5 @@ softwareName: Certification Tool title: Unattended online certification tool for an international organization logo: ./certification.svg summary: With this tool you can organize your certification process. It lets you invite people periodically to get certified, runs the certification process and hands you nicely designed PDF documents upon successful certification. +featured: true --- - - diff --git a/src/content/references/projects/docportal.placeholder.1.png b/src/content/references/projects/docportal.placeholder.1.png new file mode 100644 index 00000000..0458f612 Binary files /dev/null and b/src/content/references/projects/docportal.placeholder.1.png differ diff --git a/src/content/references/projects/docportal.placeholder.2.png b/src/content/references/projects/docportal.placeholder.2.png new file mode 100644 index 00000000..0458f612 Binary files /dev/null and b/src/content/references/projects/docportal.placeholder.2.png differ diff --git a/src/content/references/projects/dogil.placeholder.png b/src/content/references/projects/dogil.placeholder.png new file mode 100644 index 00000000..0458f612 Binary files /dev/null and b/src/content/references/projects/dogil.placeholder.png differ diff --git a/src/content/references/projects/timelet.de.md b/src/content/references/projects/timelet.de.md index 282b5f9c..ed329d74 100644 --- a/src/content/references/projects/timelet.de.md +++ b/src/content/references/projects/timelet.de.md @@ -3,4 +3,5 @@ softwareName: Timelet title: Minimales Open-Source Zeiterfassungstool logo: ./timelet.svg summary: Dieses Produkt ist ein minimalistisches, einfach zu bedienendes Open-Source-Tool zur effizienten Zeiterfassung. Da es völlig kostenlos ist, bietet es jedem die Möglichkeit, sein Zeitmanagement professionell zu gestalten. +featured: true --- diff --git a/src/content/references/projects/timelet.en.md b/src/content/references/projects/timelet.en.md index 65c52993..cb3e54fa 100644 --- a/src/content/references/projects/timelet.en.md +++ b/src/content/references/projects/timelet.en.md @@ -3,4 +3,5 @@ softwareName: Timelet title: Minimal opensource time tracking tool logo: ./timelet.svg summary: This product is a minimalist, easy-to-use, opensource tool to track time efficiently. By it being completely free to use it gives everyone the change to handle their time management professionally. +featured: true --- diff --git a/src/content/references/projects/vialibera.de.md b/src/content/references/projects/vialibera.de.md index 563c27d0..89136803 100644 --- a/src/content/references/projects/vialibera.de.md +++ b/src/content/references/projects/vialibera.de.md @@ -3,4 +3,5 @@ softwareName: ViaLibera title: Mobiles Protokollmanagement-Tool für eine Regierungsorganisation logo: ./vialibera.svg summary: Es handelt sich um eine progressive Webanwendung, die offlinefähig ist. Nachdem das Gerät, auf dem die Anwendung läuft, wieder online ist, werden die Daten synchronisiert. Es hilft dabei, den Strassenzustand zu protokollieren und daraus Statistiken zu erstellen. +featured: true --- diff --git a/src/content/references/projects/vialibera.en.md b/src/content/references/projects/vialibera.en.md index 36ac1a9e..4af39006 100644 --- a/src/content/references/projects/vialibera.en.md +++ b/src/content/references/projects/vialibera.en.md @@ -3,4 +3,5 @@ softwareName: ViaLibera title: Mobile protocol management tool for a government organization logo: ./vialibera.svg summary: It's a progressive web application, which has offline capabilities. After the device which runs the application comes back online the data is synchronized. It helps you to log street condition and makes statistics out of it. +featured: true --- diff --git a/src/content/sections/de/Featured.mdx b/src/content/sections/de/Featured.mdx new file mode 100644 index 00000000..2661042f --- /dev/null +++ b/src/content/sections/de/Featured.mdx @@ -0,0 +1,5 @@ +import FeaturedSection from "../../../layouts/sections/FeaturedSection.astro"; + + +

    Wer uns vertraut

    +
    diff --git a/src/content/sections/de/References.mdx b/src/content/sections/de/References.mdx deleted file mode 100644 index cb9ac7a2..00000000 --- a/src/content/sections/de/References.mdx +++ /dev/null @@ -1,5 +0,0 @@ -import ReferencesSection from "../../../layouts/sections/ReferencesSection.astro"; - - -

    Wer uns vertraut

    -
    diff --git a/src/content/sections/de/Spotlight.mdx b/src/content/sections/de/Spotlight.mdx index 8bef8a2c..42a766f3 100644 --- a/src/content/sections/de/Spotlight.mdx +++ b/src/content/sections/de/Spotlight.mdx @@ -1,31 +1,37 @@ -import SpotlightSection from '../../../layouts/sections/SpotlightSection.astro'; -import BackgroundVideo from '../../../components/BackgroundVideo.astro'; -import BackgroundImage from '../../../components/BackgroundImage.astro'; -import BackgroundIcon from '../../../components/BackgroundIcon.astro'; -import Button from '../../../components/Button.astro'; -import ValuesVideo from '../../../../res/values.mp4'; -import CollaborationImage from '../../../../res/collaboration.jpg'; -import ReferenceIcon from '../../../../res/dogli.svg'; +import SpotlightSection from "../../../layouts/sections/SpotlightSection.astro"; +import BackgroundVideo from "../../../components/BackgroundVideo.astro"; +import BackgroundImage from "../../../components/BackgroundImage.astro"; +import BackgroundIcon from "../../../components/BackgroundIcon.astro"; +import Button from "../../../components/Button.astro"; +import ValuesVideo from "../../../../res/values.mp4"; +import CollaborationImage from "../../../../res/collaboration.jpg"; +import ReferenceIcon from "../../../../res/dogli.svg"; - -
    -

    Gemeinsam auf dem richtigen Weg

    -

    Finden wir gemeinsam den richtigen Weg, um Ihre Software Wirklichkeit werden zu lassen.

    - -
    - -
    -

    Nahtlos

    -

    Wir entwickeln Software, die sich nahtlos in Ihren bestehenden Arbeitsablauf integriert.

    - -
    - -
    -

    Die ultimative Hunde-Bereicherungs-App

    -

    Eine Smartphone-App mit Social-Media-Funktionen, um das Leben Ihres besten Freundes zu bereichern.

    - -
    + +
    +

    Gemeinsam auf dem richtigen Weg

    +

    Finden wir gemeinsam den richtigen Weg, um Ihre Software Wirklichkeit werden zu lassen.

    + +
    + +
    +

    Nahtlos

    +

    Wir entwickeln Software, die sich nahtlos in Ihren bestehenden Arbeitsablauf integriert.

    + +
    + +
    +

    Die ultimative Hunde-Bereicherungs-App

    +

    Eine Smartphone-App mit Social-Media-Funktionen, um das Leben Ihres besten Freundes zu bereichern.

    + +
    diff --git a/src/content/sections/en/Featured.mdx b/src/content/sections/en/Featured.mdx new file mode 100644 index 00000000..5017ffda --- /dev/null +++ b/src/content/sections/en/Featured.mdx @@ -0,0 +1,5 @@ +import FeaturedSection from "../../../layouts/sections/FeaturedSection.astro"; + + +

    Who trusts us

    +
    diff --git a/src/content/sections/en/References.mdx b/src/content/sections/en/References.mdx deleted file mode 100644 index a0facde4..00000000 --- a/src/content/sections/en/References.mdx +++ /dev/null @@ -1,5 +0,0 @@ -import ReferencesSection from "../../../layouts/sections/ReferencesSection.astro"; - - -

    Who trusts us

    -
    diff --git a/src/content/sections/en/Spotlight.mdx b/src/content/sections/en/Spotlight.mdx index 041128f7..fcfb9c3f 100644 --- a/src/content/sections/en/Spotlight.mdx +++ b/src/content/sections/en/Spotlight.mdx @@ -1,31 +1,37 @@ -import SpotlightSection from '../../../layouts/sections/SpotlightSection.astro'; -import BackgroundVideo from '../../../components/BackgroundVideo.astro'; -import BackgroundImage from '../../../components/BackgroundImage.astro'; -import BackgroundIcon from '../../../components/BackgroundIcon.astro'; -import Button from '../../../components/Button.astro'; -import ValuesVideo from '../../../../res/values.mp4'; -import CollaborationImage from '../../../../res/collaboration.jpg'; -import ReferenceIcon from '../../../../res/dogli.svg'; +import SpotlightSection from "../../../layouts/sections/SpotlightSection.astro"; +import BackgroundVideo from "../../../components/BackgroundVideo.astro"; +import BackgroundImage from "../../../components/BackgroundImage.astro"; +import BackgroundIcon from "../../../components/BackgroundIcon.astro"; +import Button from "../../../components/Button.astro"; +import ValuesVideo from "../../../../res/values.mp4"; +import CollaborationImage from "../../../../res/collaboration.jpg"; +import ReferenceIcon from "../../../../res/dogli.svg"; - -
    -

    Together on the right path

    -

    Let's find together the right path to bring your software to reality.

    - -
    - -
    -

    Seamless

    -

    We build software that integrates seamlessly into your existing workflow.

    - -
    - -
    -

    Ultimate dog enrichment app

    -

    A smartphone app with social media features to enrich your best friends life.

    - -
    + +
    +

    Together on the right path

    +

    Let's find together the right path to bring your software to reality.

    + +
    + +
    +

    Seamless

    +

    We build software that integrates seamlessly into your existing workflow.

    + +
    + +
    +

    Ultimate dog enrichment app

    +

    A smartphone app with social media features to enrich your best friends life.

    + +
    diff --git a/src/layouts/Shell.css b/src/layouts/Shell.css index ff66e125..a5146232 100644 --- a/src/layouts/Shell.css +++ b/src/layouts/Shell.css @@ -125,28 +125,28 @@ body { margin: 0; background-color: var(--color-background); - >.divider { + > .divider { z-index: 5; } } .page-padding, #ribbon, -body> :is(header, footer) { +body > :is(header, footer) { padding: 0 var(--size-page-padding); } -body> :is(header, footer) { +body > :is(header, footer) { z-index: 10; } #ribbon ::selection, -body> :is(header, footer) ::selection { +body > :is(header, footer) ::selection { background-color: var(--color-white); color: var(--color-primary); } -body> :is(header, footer, #ribbon) a { +body > :is(header, footer, #ribbon) a { text-decoration: none; color: var(--color-background); font-weight: bold; @@ -207,21 +207,21 @@ h5 { font-size: 1.05rem; } -body>main { +body > main { display: flex; flex-direction: column; flex-grow: 1; hyphens: auto; - >section { + > section { &.page-padding { padding-block: var(--size-gutter-massive); } - >header { + > header { text-align: center; - >* { + > * { margin: 0; margin-bottom: var(--size-gutter-big); } diff --git a/src/layouts/sections/CompaniesSection.astro b/src/layouts/sections/CompaniesSection.astro new file mode 100644 index 00000000..eecfffd2 --- /dev/null +++ b/src/layouts/sections/CompaniesSection.astro @@ -0,0 +1,64 @@ +--- +import { getCollection } from "astro:content"; +import { Image } from "astro:assets"; +import Tile from "../../components/Tile.astro"; + +const companies = await getCollection("referenceCompanies", (entry) => !entry.data.archived && entry.data.details); +--- + +
    + { + companies.map((c, i) => ( + +
    +
    + {c.data.companyName} + {c.data.companyName} +
    +
    +
    + {c.data.details} +
    +
    + )) + } +
    + + diff --git a/src/layouts/sections/FeaturedSection.astro b/src/layouts/sections/FeaturedSection.astro new file mode 100644 index 00000000..3f162eff --- /dev/null +++ b/src/layouts/sections/FeaturedSection.astro @@ -0,0 +1,122 @@ +--- +import { currentLocale } from "astro-nanostores-i18n:runtime"; +import { Image } from "astro:assets"; +import { getCollection } from "astro:content"; +import Tile from "../../components/Tile.astro"; + +const locale = currentLocale.get(); +const companies = await getCollection("referenceCompanies", (entry) => !entry.data.archived); +const projects = await getCollection( + "referenceProjects", + (entry) => entry.data.locale === locale && entry.data.featured, +); +--- + +
    +
    + +
    +
    + { + projects.map((p) => ( +
    + {p.data.softwareName} +

    {p.data.title}

    +

    {p.data.summary}

    +
    + )) + } +
    +
    + { + companies.map((c) => ( + + + {c.data.companyName} + {c.data.companyName} + + + )) + } +
    +
    + diff --git a/src/layouts/sections/ReferencesSection.astro b/src/layouts/sections/ReferencesSection.astro index 19f40d95..9ee3cd17 100644 --- a/src/layouts/sections/ReferencesSection.astro +++ b/src/layouts/sections/ReferencesSection.astro @@ -1,118 +1,38 @@ --- import { currentLocale } from "astro-nanostores-i18n:runtime"; -import { Image } from "astro:assets"; import { getCollection } from "astro:content"; +import Accordion from "../../components/accordion/Accordion.astro"; +import AccordionItem from "../../components/accordion/AccordionItem.astro"; +import { Image } from "astro:assets"; const locale = currentLocale.get(); -const companies = await getCollection("referenceCompanies", (entry) => !entry.data.archived); const projects = await getCollection("referenceProjects", (entry) => entry.data.locale === locale); --- -
    -
    - -
    -
    - { - projects.map((p) => ( -
    - {p.data.softwareName} -

    {p.data.title}

    -

    {p.data.summary}

    + + { + projects.map((project, i) => ( + +
    + {project.data.softwareName} + {project.data.summary}
    - )) - } -
    -
    - { - companies.map((c) => ( - - {c.data.companyName} - {c.data.companyName} - - )) - } -
    -
    - diff --git a/src/pages/[...locale]/index.astro b/src/pages/[...locale]/index.astro index 6b6fcb73..64af58c4 100644 --- a/src/pages/[...locale]/index.astro +++ b/src/pages/[...locale]/index.astro @@ -13,7 +13,7 @@ const { translations } = Astro.props; const { Content: SpotlightSection } = await render(await getEntry("sections", `${locale}/spotlight`)!); const { Content: ServicesSection } = await render(await getEntry("sections", `${locale}/services`)!); const { Content: TechnologiesSection } = await render(await getEntry("sections", `${locale}/technologies`)!); -const { Content: ReferencesSection } = await render(await getEntry("sections", `${locale}/references`)!); +const { Content: FeaturedSection } = await render(await getEntry("sections", `${locale}/featured`)!); const { Content: QuestionsSection } = await render(await getEntry("sections", `${locale}/questions`)!); --- @@ -31,7 +31,7 @@ const { Content: QuestionsSection } = await render(await getEntry("sections", `$ - + diff --git a/src/types/AccordionItem.ts b/src/types/AccordionItem.ts new file mode 100644 index 00000000..7126140d --- /dev/null +++ b/src/types/AccordionItem.ts @@ -0,0 +1,10 @@ +export type AccordionItem = { + class?: string; + title: string; + name?: string; + headingLevel?: "h1" | "h2" | "h3" | "h4" | "h5" | "h6"; + headingSize?: "h1" | "h2" | "h3" | "h4" | "h5" | "h6"; + variant?: "default" | "chevron"; + open?: boolean; + children?: unknown; +} & Record; diff --git a/src/utils/paths.ts b/src/utils/paths.ts index a3cf66f8..45b00ee3 100644 --- a/src/utils/paths.ts +++ b/src/utils/paths.ts @@ -5,6 +5,7 @@ import type { ImageMetadata } from "astro"; import { parseLocale } from "./i18n"; const PROTOCOL_DELIMITER = "://"; +const ID_DELIMITER = "#"; export const defaultPropsAndParamsOptions = { defaultLocale: C.DEFAULT_LOCALE, @@ -22,6 +23,52 @@ export const resolvePath = (...path: Array) => { return originalResolvePath(import.meta.env.BASE_URL, ...path); }; +export const resolveSimplePath = async ( + id: E, + path: string, + currentLocale: Locale, +) => { + const navigation = await getEntry("navigation", `${id}/${currentLocale}`); + if (!navigation) throw new Error(`Navigation entry not found`); + + const items = navigation.data.items; + + if (!Array.isArray(items)) { + throw new Error(`Navigation entry not found`); + } + + const [cleansedPath, param] = path.split(ID_DELIMITER); + + for (const item of items) { + const reference = findReference(item, `${currentLocale}${cleansedPath}`); + + if (reference) { + const resolved = await convertReferenceToPath(reference); + + return param ? `${resolved}#${param}` : resolved; + } + } + + throw new Error(`Path could not be resolved`); +}; + +const findReference = (item: NavigationItem, path: string): string | undefined => { + const [collection, reference] = item.path.split(PROTOCOL_DELIMITER); + if (!collection || !reference) throw new Error("Invalid path"); + + if (reference === path) { + return item.path; + } + + if (item.children) { + for (const child of item.children) { + const result = findReference(child, path); + if (result) return result; + } + } + return undefined; +}; + export const generateGetStaticIndexPaths = (routePattern: string) => { return async () => { const collection = createI18nCollection({ locales: localeSlugs, routePattern, basePath: import.meta.env.BASE_URL });