diff --git a/package.json b/package.json index c21bfd76b..c15d48ac9 100644 --- a/package.json +++ b/package.json @@ -47,8 +47,8 @@ "@types/js-yaml": "^4.0.9", "prettier": "^3.5.3", "prettier-plugin-astro": "^0.14.1", - "tsx": "^4.19.4", "puppeteer": "^24.7.2", + "tsx": "^4.19.4", "typescript": "^5.8.3" }, "prettier": { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index f9de365ea..72123ad41 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -10,22 +10,22 @@ importers: dependencies: '@astro-community/astro-embed-youtube': specifier: ^0.5.6 - version: 0.5.6(astro@5.7.5(jiti@1.21.7)(rollup@4.40.1)(tsx@4.19.4)(typescript@5.8.3)(yaml@2.7.1)) + version: 0.5.6(astro@5.7.10(jiti@2.4.2)(lightningcss@1.29.2)(rollup@4.40.1)(tsx@4.19.4)(typescript@5.8.3)(yaml@2.7.1)) '@astrojs/check': specifier: ^0.9.4 version: 0.9.4(prettier-plugin-astro@0.14.1)(prettier@3.5.3)(typescript@5.8.3) '@astrojs/mdx': specifier: ^4.2.6 - version: 4.2.6(astro@5.7.5(jiti@1.21.7)(rollup@4.40.1)(tsx@4.19.4)(typescript@5.8.3)(yaml@2.7.1)) + version: 4.2.6(astro@5.7.10(jiti@2.4.2)(lightningcss@1.29.2)(rollup@4.40.1)(tsx@4.19.4)(typescript@5.8.3)(yaml@2.7.1)) '@astrojs/react': specifier: ^4.2.7 - version: 4.2.7(@types/react-dom@19.1.3(@types/react@19.1.2))(@types/react@19.1.2)(jiti@1.21.7)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)(tsx@4.19.4)(yaml@2.7.1) + version: 4.2.7(@types/react-dom@19.1.3(@types/react@19.1.2))(@types/react@19.1.2)(jiti@2.4.2)(lightningcss@1.29.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)(tsx@4.19.4)(yaml@2.7.1) '@astrojs/sitemap': specifier: ^3.3.1 version: 3.3.1 '@astrojs/tailwind': specifier: ^5.1.5 - version: 5.1.5(astro@5.7.5(jiti@1.21.7)(rollup@4.40.1)(tsx@4.19.4)(typescript@5.8.3)(yaml@2.7.1))(tailwindcss@3.4.17) + version: 5.1.5(astro@5.7.10(jiti@2.4.2)(lightningcss@1.29.2)(rollup@4.40.1)(tsx@4.19.4)(typescript@5.8.3)(yaml@2.7.1))(tailwindcss@3.4.17) '@fontsource-variable/inter': specifier: ^5.2.5 version: 5.2.5 @@ -43,16 +43,16 @@ importers: version: 19.1.3(@types/react@19.1.2) astro: specifier: ^5.7.5 - version: 5.7.5(jiti@1.21.7)(rollup@4.40.1)(tsx@4.19.4)(typescript@5.8.3)(yaml@2.7.1) + version: 5.7.10(jiti@2.4.2)(lightningcss@1.29.2)(rollup@4.40.1)(tsx@4.19.4)(typescript@5.8.3)(yaml@2.7.1) astro-delete-unused-images: specifier: ^1.0.3 version: 1.0.3 astro-meta-tags: specifier: ^0.3.1 - version: 0.3.1(astro@5.7.5(jiti@1.21.7)(rollup@4.40.1)(tsx@4.19.4)(typescript@5.8.3)(yaml@2.7.1)) + version: 0.3.1(astro@5.7.10(jiti@2.4.2)(lightningcss@1.29.2)(rollup@4.40.1)(tsx@4.19.4)(typescript@5.8.3)(yaml@2.7.1)) astro-pagefind: specifier: ^1.8.3 - version: 1.8.3(astro@5.7.5(jiti@1.21.7)(rollup@4.40.1)(tsx@4.19.4)(typescript@5.8.3)(yaml@2.7.1)) + version: 1.8.3(astro@5.7.10(jiti@2.4.2)(lightningcss@1.29.2)(rollup@4.40.1)(tsx@4.19.4)(typescript@5.8.3)(yaml@2.7.1)) astro-preload: specifier: ^1.1.2 version: 1.1.2 @@ -233,10 +233,6 @@ packages: resolution: {integrity: sha512-1gn1Up5YXka3YYAHGKpbideQ5Yjf1tDa9qYcgysz+cNCXukyLl6DjPXhD3VRwSb8c0J9tA4b2+rHEZtc6R0tlw==} engines: {node: '>=6.9.0'} - '@babel/helper-string-parser@7.25.9': - resolution: {integrity: sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==} - engines: {node: '>=6.9.0'} - '@babel/helper-string-parser@7.27.1': resolution: {integrity: sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==} engines: {node: '>=6.9.0'} @@ -257,11 +253,6 @@ packages: resolution: {integrity: sha512-FCvFTm0sWV8Fxhpp2McP5/W53GPllQ9QeQ7SiqGWjMf/LVG07lFa5+pgK05IRhVwtvafT22KF+ZSnM9I545CvQ==} engines: {node: '>=6.9.0'} - '@babel/parser@7.27.0': - resolution: {integrity: sha512-iaepho73/2Pz7w2eMS0Q5f83+0RKI7i4xmiYeBmDzfRVbQtTOG7Ts0S4HzJVsTMGI9keU8rNfuZr8DKfSt7Yyg==} - engines: {node: '>=6.0.0'} - hasBin: true - '@babel/parser@7.27.1': resolution: {integrity: sha512-I0dZ3ZpCrJ1c04OqlNsQcKiZlsrXf/kkE4FXzID9rIOYICsAbA8mMDzhW/luRNAHdCNt7os/u8wenklZDlUVUQ==} engines: {node: '>=6.0.0'} @@ -287,10 +278,6 @@ packages: resolution: {integrity: sha512-ZCYtZciz1IWJB4U61UPu4KEaqyfj+r5T1Q5mqPo+IBpcG9kHv30Z0aD8LXPgC1trYa6rK0orRyAhqUgk4MjmEg==} engines: {node: '>=6.9.0'} - '@babel/types@7.27.0': - resolution: {integrity: sha512-H45s8fVLYjbhFH62dIJ3WtmJ6RSPt/3DRO0ZcT2SUiYiQyz3BLVb9ADEnLl91m74aQPS3AzzeajZHYOalWe3bg==} - engines: {node: '>=6.9.0'} - '@babel/types@7.27.1': resolution: {integrity: sha512-+EzkxvLNfiUeKMgy/3luqfsCWFRXLb7U6wNQTk60tovuckwB15B191tJWvpp4HjiQWdJkCxO3Wbvc6jlk3Xb2Q==} engines: {node: '>=6.9.0'} @@ -783,201 +770,101 @@ packages: rollup: optional: true - '@rollup/rollup-android-arm-eabi@4.40.0': - resolution: {integrity: sha512-+Fbls/diZ0RDerhE8kyC6hjADCXA1K4yVNlH0EYfd2XjyH0UGgzaQ8MlT0pCXAThfxv3QUAczHaL+qSv1E4/Cg==} - cpu: [arm] - os: [android] - '@rollup/rollup-android-arm-eabi@4.40.1': resolution: {integrity: sha512-kxz0YeeCrRUHz3zyqvd7n+TVRlNyTifBsmnmNPtk3hQURUyG9eAB+usz6DAwagMusjx/zb3AjvDUvhFGDAexGw==} cpu: [arm] os: [android] - '@rollup/rollup-android-arm64@4.40.0': - resolution: {integrity: sha512-PPA6aEEsTPRz+/4xxAmaoWDqh67N7wFbgFUJGMnanCFs0TV99M0M8QhhaSCks+n6EbQoFvLQgYOGXxlMGQe/6w==} - cpu: [arm64] - os: [android] - '@rollup/rollup-android-arm64@4.40.1': resolution: {integrity: sha512-PPkxTOisoNC6TpnDKatjKkjRMsdaWIhyuMkA4UsBXT9WEZY4uHezBTjs6Vl4PbqQQeu6oION1w2voYZv9yquCw==} cpu: [arm64] os: [android] - '@rollup/rollup-darwin-arm64@4.40.0': - resolution: {integrity: sha512-GwYOcOakYHdfnjjKwqpTGgn5a6cUX7+Ra2HeNj/GdXvO2VJOOXCiYYlRFU4CubFM67EhbmzLOmACKEfvp3J1kQ==} - cpu: [arm64] - os: [darwin] - '@rollup/rollup-darwin-arm64@4.40.1': resolution: {integrity: sha512-VWXGISWFY18v/0JyNUy4A46KCFCb9NVsH+1100XP31lud+TzlezBbz24CYzbnA4x6w4hx+NYCXDfnvDVO6lcAA==} cpu: [arm64] os: [darwin] - '@rollup/rollup-darwin-x64@4.40.0': - resolution: {integrity: sha512-CoLEGJ+2eheqD9KBSxmma6ld01czS52Iw0e2qMZNpPDlf7Z9mj8xmMemxEucinev4LgHalDPczMyxzbq+Q+EtA==} - cpu: [x64] - os: [darwin] - '@rollup/rollup-darwin-x64@4.40.1': resolution: {integrity: sha512-nIwkXafAI1/QCS7pxSpv/ZtFW6TXcNUEHAIA9EIyw5OzxJZQ1YDrX+CL6JAIQgZ33CInl1R6mHet9Y/UZTg2Bw==} cpu: [x64] os: [darwin] - '@rollup/rollup-freebsd-arm64@4.40.0': - resolution: {integrity: sha512-r7yGiS4HN/kibvESzmrOB/PxKMhPTlz+FcGvoUIKYoTyGd5toHp48g1uZy1o1xQvybwwpqpe010JrcGG2s5nkg==} - cpu: [arm64] - os: [freebsd] - '@rollup/rollup-freebsd-arm64@4.40.1': resolution: {integrity: sha512-BdrLJ2mHTrIYdaS2I99mriyJfGGenSaP+UwGi1kB9BLOCu9SR8ZpbkmmalKIALnRw24kM7qCN0IOm6L0S44iWw==} cpu: [arm64] os: [freebsd] - '@rollup/rollup-freebsd-x64@4.40.0': - resolution: {integrity: sha512-mVDxzlf0oLzV3oZOr0SMJ0lSDd3xC4CmnWJ8Val8isp9jRGl5Dq//LLDSPFrasS7pSm6m5xAcKaw3sHXhBjoRw==} - cpu: [x64] - os: [freebsd] - '@rollup/rollup-freebsd-x64@4.40.1': resolution: {integrity: sha512-VXeo/puqvCG8JBPNZXZf5Dqq7BzElNJzHRRw3vjBE27WujdzuOPecDPc/+1DcdcTptNBep3861jNq0mYkT8Z6Q==} cpu: [x64] os: [freebsd] - '@rollup/rollup-linux-arm-gnueabihf@4.40.0': - resolution: {integrity: sha512-y/qUMOpJxBMy8xCXD++jeu8t7kzjlOCkoxxajL58G62PJGBZVl/Gwpm7JK9+YvlB701rcQTzjUZ1JgUoPTnoQA==} - cpu: [arm] - os: [linux] - '@rollup/rollup-linux-arm-gnueabihf@4.40.1': resolution: {integrity: sha512-ehSKrewwsESPt1TgSE/na9nIhWCosfGSFqv7vwEtjyAqZcvbGIg4JAcV7ZEh2tfj/IlfBeZjgOXm35iOOjadcg==} cpu: [arm] os: [linux] - '@rollup/rollup-linux-arm-musleabihf@4.40.0': - resolution: {integrity: sha512-GoCsPibtVdJFPv/BOIvBKO/XmwZLwaNWdyD8TKlXuqp0veo2sHE+A/vpMQ5iSArRUz/uaoj4h5S6Pn0+PdhRjg==} - cpu: [arm] - os: [linux] - '@rollup/rollup-linux-arm-musleabihf@4.40.1': resolution: {integrity: sha512-m39iO/aaurh5FVIu/F4/Zsl8xppd76S4qoID8E+dSRQvTyZTOI2gVk3T4oqzfq1PtcvOfAVlwLMK3KRQMaR8lg==} cpu: [arm] os: [linux] - '@rollup/rollup-linux-arm64-gnu@4.40.0': - resolution: {integrity: sha512-L5ZLphTjjAD9leJzSLI7rr8fNqJMlGDKlazW2tX4IUF9P7R5TMQPElpH82Q7eNIDQnQlAyiNVfRPfP2vM5Avvg==} - cpu: [arm64] - os: [linux] - '@rollup/rollup-linux-arm64-gnu@4.40.1': resolution: {integrity: sha512-Y+GHnGaku4aVLSgrT0uWe2o2Rq8te9hi+MwqGF9r9ORgXhmHK5Q71N757u0F8yU1OIwUIFy6YiJtKjtyktk5hg==} cpu: [arm64] os: [linux] - '@rollup/rollup-linux-arm64-musl@4.40.0': - resolution: {integrity: sha512-ATZvCRGCDtv1Y4gpDIXsS+wfFeFuLwVxyUBSLawjgXK2tRE6fnsQEkE4csQQYWlBlsFztRzCnBvWVfcae/1qxQ==} - cpu: [arm64] - os: [linux] - '@rollup/rollup-linux-arm64-musl@4.40.1': resolution: {integrity: sha512-jEwjn3jCA+tQGswK3aEWcD09/7M5wGwc6+flhva7dsQNRZZTe30vkalgIzV4tjkopsTS9Jd7Y1Bsj6a4lzz8gQ==} cpu: [arm64] os: [linux] - '@rollup/rollup-linux-loongarch64-gnu@4.40.0': - resolution: {integrity: sha512-wG9e2XtIhd++QugU5MD9i7OnpaVb08ji3P1y/hNbxrQ3sYEelKJOq1UJ5dXczeo6Hj2rfDEL5GdtkMSVLa/AOg==} - cpu: [loong64] - os: [linux] - '@rollup/rollup-linux-loongarch64-gnu@4.40.1': resolution: {integrity: sha512-ySyWikVhNzv+BV/IDCsrraOAZ3UaC8SZB67FZlqVwXwnFhPihOso9rPOxzZbjp81suB1O2Topw+6Ug3JNegejQ==} cpu: [loong64] os: [linux] - '@rollup/rollup-linux-powerpc64le-gnu@4.40.0': - resolution: {integrity: sha512-vgXfWmj0f3jAUvC7TZSU/m/cOE558ILWDzS7jBhiCAFpY2WEBn5jqgbqvmzlMjtp8KlLcBlXVD2mkTSEQE6Ixw==} - cpu: [ppc64] - os: [linux] - '@rollup/rollup-linux-powerpc64le-gnu@4.40.1': resolution: {integrity: sha512-BvvA64QxZlh7WZWqDPPdt0GH4bznuL6uOO1pmgPnnv86rpUpc8ZxgZwcEgXvo02GRIZX1hQ0j0pAnhwkhwPqWg==} cpu: [ppc64] os: [linux] - '@rollup/rollup-linux-riscv64-gnu@4.40.0': - resolution: {integrity: sha512-uJkYTugqtPZBS3Z136arevt/FsKTF/J9dEMTX/cwR7lsAW4bShzI2R0pJVw+hcBTWF4dxVckYh72Hk3/hWNKvA==} - cpu: [riscv64] - os: [linux] - '@rollup/rollup-linux-riscv64-gnu@4.40.1': resolution: {integrity: sha512-EQSP+8+1VuSulm9RKSMKitTav89fKbHymTf25n5+Yr6gAPZxYWpj3DzAsQqoaHAk9YX2lwEyAf9S4W8F4l3VBQ==} cpu: [riscv64] os: [linux] - '@rollup/rollup-linux-riscv64-musl@4.40.0': - resolution: {integrity: sha512-rKmSj6EXQRnhSkE22+WvrqOqRtk733x3p5sWpZilhmjnkHkpeCgWsFFo0dGnUGeA+OZjRl3+VYq+HyCOEuwcxQ==} - cpu: [riscv64] - os: [linux] - '@rollup/rollup-linux-riscv64-musl@4.40.1': resolution: {integrity: sha512-n/vQ4xRZXKuIpqukkMXZt9RWdl+2zgGNx7Uda8NtmLJ06NL8jiHxUawbwC+hdSq1rrw/9CghCpEONor+l1e2gA==} cpu: [riscv64] os: [linux] - '@rollup/rollup-linux-s390x-gnu@4.40.0': - resolution: {integrity: sha512-SpnYlAfKPOoVsQqmTFJ0usx0z84bzGOS9anAC0AZ3rdSo3snecihbhFTlJZ8XMwzqAcodjFU4+/SM311dqE5Sw==} - cpu: [s390x] - os: [linux] - '@rollup/rollup-linux-s390x-gnu@4.40.1': resolution: {integrity: sha512-h8d28xzYb98fMQKUz0w2fMc1XuGzLLjdyxVIbhbil4ELfk5/orZlSTpF/xdI9C8K0I8lCkq+1En2RJsawZekkg==} cpu: [s390x] os: [linux] - '@rollup/rollup-linux-x64-gnu@4.40.0': - resolution: {integrity: sha512-RcDGMtqF9EFN8i2RYN2W+64CdHruJ5rPqrlYw+cgM3uOVPSsnAQps7cpjXe9be/yDp8UC7VLoCoKC8J3Kn2FkQ==} - cpu: [x64] - os: [linux] - '@rollup/rollup-linux-x64-gnu@4.40.1': resolution: {integrity: sha512-XiK5z70PEFEFqcNj3/zRSz/qX4bp4QIraTy9QjwJAb/Z8GM7kVUsD0Uk8maIPeTyPCP03ChdI+VVmJriKYbRHQ==} cpu: [x64] os: [linux] - '@rollup/rollup-linux-x64-musl@4.40.0': - resolution: {integrity: sha512-HZvjpiUmSNx5zFgwtQAV1GaGazT2RWvqeDi0hV+AtC8unqqDSsaFjPxfsO6qPtKRRg25SisACWnJ37Yio8ttaw==} - cpu: [x64] - os: [linux] - '@rollup/rollup-linux-x64-musl@4.40.1': resolution: {integrity: sha512-2BRORitq5rQ4Da9blVovzNCMaUlyKrzMSvkVR0D4qPuOy/+pMCrh1d7o01RATwVy+6Fa1WBw+da7QPeLWU/1mQ==} cpu: [x64] os: [linux] - '@rollup/rollup-win32-arm64-msvc@4.40.0': - resolution: {integrity: sha512-UtZQQI5k/b8d7d3i9AZmA/t+Q4tk3hOC0tMOMSq2GlMYOfxbesxG4mJSeDp0EHs30N9bsfwUvs3zF4v/RzOeTQ==} - cpu: [arm64] - os: [win32] - '@rollup/rollup-win32-arm64-msvc@4.40.1': resolution: {integrity: sha512-b2bcNm9Kbde03H+q+Jjw9tSfhYkzrDUf2d5MAd1bOJuVplXvFhWz7tRtWvD8/ORZi7qSCy0idW6tf2HgxSXQSg==} cpu: [arm64] os: [win32] - '@rollup/rollup-win32-ia32-msvc@4.40.0': - resolution: {integrity: sha512-+m03kvI2f5syIqHXCZLPVYplP8pQch9JHyXKZ3AGMKlg8dCyr2PKHjwRLiW53LTrN/Nc3EqHOKxUxzoSPdKddA==} - cpu: [ia32] - os: [win32] - '@rollup/rollup-win32-ia32-msvc@4.40.1': resolution: {integrity: sha512-DfcogW8N7Zg7llVEfpqWMZcaErKfsj9VvmfSyRjCyo4BI3wPEfrzTtJkZG6gKP/Z92wFm6rz2aDO7/JfiR/whA==} cpu: [ia32] os: [win32] - '@rollup/rollup-win32-x64-msvc@4.40.0': - resolution: {integrity: sha512-lpPE1cLfP5oPzVjKMx10pgBmKELQnFJXHgvtHCtuJWOv8MxqdEIMNtgHgBFf7Ea2/7EuVwa9fodWUfXAlXZLZQ==} - cpu: [x64] - os: [win32] - '@rollup/rollup-win32-x64-msvc@4.40.1': resolution: {integrity: sha512-ECyOuDeH3C1I8jH2MK1RtBJW+YPMvSfT0a5NN0nHfQYnDSJ6tUiZH3gzwVP5/Kfh/+Tt7tpWVF9LXNTnhTJ3kA==} cpu: [x64] @@ -1195,8 +1082,8 @@ packages: astro-preload@1.1.2: resolution: {integrity: sha512-96UHdATRp/K8iVysylYu0V5QMD3FXBqqj2+cUwHOmc0/+lstY5Xnb+A5UgmecbrfHpwMws5SQaOYZ1c63cQu/A==} - astro@5.7.5: - resolution: {integrity: sha512-c59YuYiXyWWnUMOBlDczrjqKzF0dJQP20EP9vqDggcyKm//tEt9iJHNwoYq4r3UeO9UJCwlGK8FwaGTAwwF3IA==} + astro@5.7.10: + resolution: {integrity: sha512-9TQcFZqP2w6//JXXUHfw8/5PX7KUx9EkG5O3m+hISuyeUztvjY1q5+p7+C5HiXyg24Zs3KkpieoL5BGRXGCAGA==} engines: {node: ^18.17.1 || ^20.3.0 || >=22.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0'} hasBin: true @@ -1698,8 +1585,8 @@ packages: resolution: {integrity: sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==} engines: {node: '>=4'} - h3@1.15.1: - resolution: {integrity: sha512-+ORaOBttdUm1E2Uu/obAyCguiI7MbBvsLTndc3gyK3zU+SYLoZXlyCP9Xgy0gikkGufFLTZXCXD6+4BsufnmHA==} + h3@1.15.3: + resolution: {integrity: sha512-z6GknHqyX0h9aQaTx22VZDf6QyZn+0Nh+Ym8O/u0SGSkyF5cuTJYKlc8MkzW3Nzf9LE1ivcpmYC3FUGpywhuUQ==} hasown@2.0.2: resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} @@ -1851,6 +1738,10 @@ packages: resolution: {integrity: sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A==} hasBin: true + jiti@2.4.2: + resolution: {integrity: sha512-rg9zJN+G4n2nfJl5MW3BMygZX56zKPNVEYYqq7adpmMh4Jn2QNEwhvQlFy6jPVdcod7txZtKHWnyZiA3a0zP7A==} + hasBin: true + js-tokens@4.0.0: resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} @@ -1891,6 +1782,70 @@ packages: resolution: {integrity: sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==} engines: {node: '>=6'} + lightningcss-darwin-arm64@1.29.2: + resolution: {integrity: sha512-cK/eMabSViKn/PG8U/a7aCorpeKLMlK0bQeNHmdb7qUnBkNPnL+oV5DjJUo0kqWsJUapZsM4jCfYItbqBDvlcA==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [darwin] + + lightningcss-darwin-x64@1.29.2: + resolution: {integrity: sha512-j5qYxamyQw4kDXX5hnnCKMf3mLlHvG44f24Qyi2965/Ycz829MYqjrVg2H8BidybHBp9kom4D7DR5VqCKDXS0w==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [darwin] + + lightningcss-freebsd-x64@1.29.2: + resolution: {integrity: sha512-wDk7M2tM78Ii8ek9YjnY8MjV5f5JN2qNVO+/0BAGZRvXKtQrBC4/cn4ssQIpKIPP44YXw6gFdpUF+Ps+RGsCwg==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [freebsd] + + lightningcss-linux-arm-gnueabihf@1.29.2: + resolution: {integrity: sha512-IRUrOrAF2Z+KExdExe3Rz7NSTuuJ2HvCGlMKoquK5pjvo2JY4Rybr+NrKnq0U0hZnx5AnGsuFHjGnNT14w26sg==} + engines: {node: '>= 12.0.0'} + cpu: [arm] + os: [linux] + + lightningcss-linux-arm64-gnu@1.29.2: + resolution: {integrity: sha512-KKCpOlmhdjvUTX/mBuaKemp0oeDIBBLFiU5Fnqxh1/DZ4JPZi4evEH7TKoSBFOSOV3J7iEmmBaw/8dpiUvRKlQ==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [linux] + + lightningcss-linux-arm64-musl@1.29.2: + resolution: {integrity: sha512-Q64eM1bPlOOUgxFmoPUefqzY1yV3ctFPE6d/Vt7WzLW4rKTv7MyYNky+FWxRpLkNASTnKQUaiMJ87zNODIrrKQ==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [linux] + + lightningcss-linux-x64-gnu@1.29.2: + resolution: {integrity: sha512-0v6idDCPG6epLXtBH/RPkHvYx74CVziHo6TMYga8O2EiQApnUPZsbR9nFNrg2cgBzk1AYqEd95TlrsL7nYABQg==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [linux] + + lightningcss-linux-x64-musl@1.29.2: + resolution: {integrity: sha512-rMpz2yawkgGT8RULc5S4WiZopVMOFWjiItBT7aSfDX4NQav6M44rhn5hjtkKzB+wMTRlLLqxkeYEtQ3dd9696w==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [linux] + + lightningcss-win32-arm64-msvc@1.29.2: + resolution: {integrity: sha512-nL7zRW6evGQqYVu/bKGK+zShyz8OVzsCotFgc7judbt6wnB2KbiKKJwBE4SGoDBQ1O94RjW4asrCjQL4i8Fhbw==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [win32] + + lightningcss-win32-x64-msvc@1.29.2: + resolution: {integrity: sha512-EdIUW3B2vLuHmv7urfzMI/h2fmlnOQBk1xlsDxkN1tCWKjNFjfLhGxYk8C8mzpSfr+A6jFFIi8fU6LbQGsRWjA==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [win32] + + lightningcss@1.29.2: + resolution: {integrity: sha512-6b6gd/RUXKaw5keVdSEtqFVdzWnU5jMxTUjA2bVcMNPLwSQ08Sv/UodBVtETLCn7k4S1Ibxwh7k68IwLZPgKaA==} + engines: {node: '>= 12.0.0'} + lilconfig@3.1.3: resolution: {integrity: sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==} engines: {node: '>=14'} @@ -2226,8 +2181,8 @@ packages: package-json-from-dist@1.0.1: resolution: {integrity: sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==} - package-manager-detector@1.2.0: - resolution: {integrity: sha512-PutJepsOtsqVfUsxCzgTTpyXmiAgvKptIgY4th5eq5UXXFhj5PxfQ9hnGkypMeovpAvVshFRItoFHYO18TCOqA==} + package-manager-detector@1.3.0: + resolution: {integrity: sha512-ZsEbbZORsyHuO00lY1kV3/t72yp6Ysay6Pd17ZAlNGuGwmWDLCJxFpRs0IzfXfj1o4icJOkUEioexFHzyPurSQ==} pagefind@1.3.0: resolution: {integrity: sha512-8KPLGT5g9s+olKMRTU9LFekLizkVIu9tes90O1/aigJ0T5LmyPqTzGJrETnSw3meSYg58YH7JTzhTTW/3z6VAw==} @@ -2524,11 +2479,6 @@ packages: resolution: {integrity: sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==} engines: {iojs: '>=1.0.0', node: '>=0.10.0'} - rollup@4.40.0: - resolution: {integrity: sha512-Noe455xmA96nnqH5piFtLobsGbCij7Tu+tb3c1vYjNbTkfzGqXqQXG3wJaYXkRZuQ0vEYN4bhwg7QnIrqB5B+w==} - engines: {node: '>=18.0.0', npm: '>=8.0.0'} - hasBin: true - rollup@4.40.1: resolution: {integrity: sha512-C5VvvgCCyfyotVITIAv+4efVytl5F7wt+/I2i9q9GZcEXW9BP52YYOXC58igUi+LFZVHukErIIqQSWwv/M3WRw==} engines: {node: '>=18.0.0', npm: '>=8.0.0'} @@ -2782,8 +2732,8 @@ packages: unified@11.0.5: resolution: {integrity: sha512-xKvGhPWw3k84Qjh8bI3ZeJjqnyadK+GEFtazSfZv/rKeTkTjOJho6mFqh2SM96iIcZokxiOpg78GazTSg8+KHA==} - unifont@0.2.0: - resolution: {integrity: sha512-RoF14/tOhLvDa7R5K6A3PjsfJVFKvadvRpWjfV1ttabUe9704P1ie9z1ABLWEts/8SxrBVePav/XhgeFNltpsw==} + unifont@0.4.1: + resolution: {integrity: sha512-zKSY9qO8svWYns+FGKjyVdLvpGPwqmsCjeJLN1xndMiqxHWBAhoWDMYMG960MxeV48clBmG+fDP59dHY1VoZvg==} unist-util-find-after@5.0.0: resolution: {integrity: sha512-amQa0Ep2m6hE2g72AugUItjbuM8X8cGQnFoHk0pGfrFeT9GZhzN5SW8nRsiGKK7Aif4CrACPENkA6P/Lw6fHGQ==} @@ -2815,8 +2765,8 @@ packages: unist-util-visit@5.0.0: resolution: {integrity: sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg==} - unstorage@1.15.0: - resolution: {integrity: sha512-m40eHdGY/gA6xAPqo8eaxqXgBuzQTlAKfmB1iF7oCKXE1HfwHwzDJBywK+qQGn52dta+bPlZluPF7++yR3p/bg==} + unstorage@1.16.0: + resolution: {integrity: sha512-WQ37/H5A7LcRPWfYOrDa1Ys02xAbpPJq6q5GkO88FBXVSQzHd7+BjEwfRqyaSWCv9MbsJy058GWjjPjcJ16GGA==} peerDependencies: '@azure/app-configuration': ^1.8.0 '@azure/cosmos': ^4.2.0 @@ -2824,7 +2774,7 @@ packages: '@azure/identity': ^4.6.0 '@azure/keyvault-secrets': ^4.9.0 '@azure/storage-blob': ^12.26.0 - '@capacitor/preferences': ^6.0.3 + '@capacitor/preferences': ^6.0.3 || ^7.0.0 '@deno/kv': '>=0.9.0' '@netlify/blobs': ^6.5.0 || ^7.0.0 || ^8.1.0 '@planetscale/database': ^1.19.0 @@ -2892,46 +2842,6 @@ packages: vfile@6.0.3: resolution: {integrity: sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==} - vite@6.3.3: - resolution: {integrity: sha512-5nXH+QsELbFKhsEfWLkHrvgRpTdGJzqOZ+utSdmPTvwHmvU6ITTm3xx+mRusihkcI8GeC7lCDyn3kDtiki9scw==} - engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} - hasBin: true - peerDependencies: - '@types/node': ^18.0.0 || ^20.0.0 || >=22.0.0 - jiti: '>=1.21.0' - less: '*' - lightningcss: ^1.21.0 - sass: '*' - sass-embedded: '*' - stylus: '*' - sugarss: '*' - terser: ^5.16.0 - tsx: ^4.8.1 - yaml: ^2.4.2 - peerDependenciesMeta: - '@types/node': - optional: true - jiti: - optional: true - less: - optional: true - lightningcss: - optional: true - sass: - optional: true - sass-embedded: - optional: true - stylus: - optional: true - sugarss: - optional: true - terser: - optional: true - tsx: - optional: true - yaml: - optional: true - vite@6.3.4: resolution: {integrity: sha512-BiReIiMS2fyFqbqNT/Qqt4CVITDU9M9vE+DKcVAsB+ZV0wvTKd+3hMbkpxz1b+NmEDMegpVbisKiAZOnvO92Sw==} engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} @@ -3207,9 +3117,9 @@ snapshots: '@jridgewell/gen-mapping': 0.3.8 '@jridgewell/trace-mapping': 0.3.25 - '@astro-community/astro-embed-youtube@0.5.6(astro@5.7.5(jiti@1.21.7)(rollup@4.40.1)(tsx@4.19.4)(typescript@5.8.3)(yaml@2.7.1))': + '@astro-community/astro-embed-youtube@0.5.6(astro@5.7.10(jiti@2.4.2)(lightningcss@1.29.2)(rollup@4.40.1)(tsx@4.19.4)(typescript@5.8.3)(yaml@2.7.1))': dependencies: - astro: 5.7.5(jiti@1.21.7)(rollup@4.40.1)(tsx@4.19.4)(typescript@5.8.3)(yaml@2.7.1) + astro: 5.7.10(jiti@2.4.2)(lightningcss@1.29.2)(rollup@4.40.1)(tsx@4.19.4)(typescript@5.8.3)(yaml@2.7.1) lite-youtube-embed: 0.3.3 '@astrojs/check@0.9.4(prettier-plugin-astro@0.14.1)(prettier@3.5.3)(typescript@5.8.3)': @@ -3279,12 +3189,12 @@ snapshots: transitivePeerDependencies: - supports-color - '@astrojs/mdx@4.2.6(astro@5.7.5(jiti@1.21.7)(rollup@4.40.1)(tsx@4.19.4)(typescript@5.8.3)(yaml@2.7.1))': + '@astrojs/mdx@4.2.6(astro@5.7.10(jiti@2.4.2)(lightningcss@1.29.2)(rollup@4.40.1)(tsx@4.19.4)(typescript@5.8.3)(yaml@2.7.1))': dependencies: '@astrojs/markdown-remark': 6.3.1 '@mdx-js/mdx': 3.1.0(acorn@8.14.1) acorn: 8.14.1 - astro: 5.7.5(jiti@1.21.7)(rollup@4.40.1)(tsx@4.19.4)(typescript@5.8.3)(yaml@2.7.1) + astro: 5.7.10(jiti@2.4.2)(lightningcss@1.29.2)(rollup@4.40.1)(tsx@4.19.4)(typescript@5.8.3)(yaml@2.7.1) es-module-lexer: 1.7.0 estree-util-visit: 2.0.0 hast-util-to-html: 9.0.5 @@ -3302,15 +3212,15 @@ snapshots: dependencies: prismjs: 1.30.0 - '@astrojs/react@4.2.7(@types/react-dom@19.1.3(@types/react@19.1.2))(@types/react@19.1.2)(jiti@1.21.7)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)(tsx@4.19.4)(yaml@2.7.1)': + '@astrojs/react@4.2.7(@types/react-dom@19.1.3(@types/react@19.1.2))(@types/react@19.1.2)(jiti@2.4.2)(lightningcss@1.29.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)(tsx@4.19.4)(yaml@2.7.1)': dependencies: '@types/react': 19.1.2 '@types/react-dom': 19.1.3(@types/react@19.1.2) - '@vitejs/plugin-react': 4.4.1(vite@6.3.4(jiti@1.21.7)(tsx@4.19.4)(yaml@2.7.1)) + '@vitejs/plugin-react': 4.4.1(vite@6.3.4(jiti@2.4.2)(lightningcss@1.29.2)(tsx@4.19.4)(yaml@2.7.1)) react: 19.1.0 react-dom: 19.1.0(react@19.1.0) ultrahtml: 1.6.0 - vite: 6.3.4(jiti@1.21.7)(tsx@4.19.4)(yaml@2.7.1) + vite: 6.3.4(jiti@2.4.2)(lightningcss@1.29.2)(tsx@4.19.4)(yaml@2.7.1) transitivePeerDependencies: - '@types/node' - jiti @@ -3331,9 +3241,9 @@ snapshots: stream-replace-string: 2.0.0 zod: 3.24.3 - '@astrojs/tailwind@5.1.5(astro@5.7.5(jiti@1.21.7)(rollup@4.40.1)(tsx@4.19.4)(typescript@5.8.3)(yaml@2.7.1))(tailwindcss@3.4.17)': + '@astrojs/tailwind@5.1.5(astro@5.7.10(jiti@2.4.2)(lightningcss@1.29.2)(rollup@4.40.1)(tsx@4.19.4)(typescript@5.8.3)(yaml@2.7.1))(tailwindcss@3.4.17)': dependencies: - astro: 5.7.5(jiti@1.21.7)(rollup@4.40.1)(tsx@4.19.4)(typescript@5.8.3)(yaml@2.7.1) + astro: 5.7.10(jiti@2.4.2)(lightningcss@1.29.2)(rollup@4.40.1)(tsx@4.19.4)(typescript@5.8.3)(yaml@2.7.1) autoprefixer: 10.4.21(postcss@8.5.3) postcss: 8.5.3 postcss-load-config: 4.0.2(postcss@8.5.3) @@ -3425,8 +3335,6 @@ snapshots: '@babel/helper-plugin-utils@7.27.1': {} - '@babel/helper-string-parser@7.25.9': {} - '@babel/helper-string-parser@7.27.1': {} '@babel/helper-validator-identifier@7.25.9': {} @@ -3440,10 +3348,6 @@ snapshots: '@babel/template': 7.27.1 '@babel/types': 7.27.1 - '@babel/parser@7.27.0': - dependencies: - '@babel/types': 7.27.0 - '@babel/parser@7.27.1': dependencies: '@babel/types': 7.27.1 @@ -3476,11 +3380,6 @@ snapshots: transitivePeerDependencies: - supports-color - '@babel/types@7.27.0': - dependencies: - '@babel/helper-string-parser': 7.25.9 - '@babel/helper-validator-identifier': 7.25.9 - '@babel/types@7.27.1': dependencies: '@babel/helper-string-parser': 7.27.1 @@ -3867,123 +3766,63 @@ snapshots: optionalDependencies: rollup: 4.40.1 - '@rollup/rollup-android-arm-eabi@4.40.0': - optional: true - '@rollup/rollup-android-arm-eabi@4.40.1': optional: true - '@rollup/rollup-android-arm64@4.40.0': - optional: true - '@rollup/rollup-android-arm64@4.40.1': optional: true - '@rollup/rollup-darwin-arm64@4.40.0': - optional: true - '@rollup/rollup-darwin-arm64@4.40.1': optional: true - '@rollup/rollup-darwin-x64@4.40.0': - optional: true - '@rollup/rollup-darwin-x64@4.40.1': optional: true - '@rollup/rollup-freebsd-arm64@4.40.0': - optional: true - '@rollup/rollup-freebsd-arm64@4.40.1': optional: true - '@rollup/rollup-freebsd-x64@4.40.0': - optional: true - '@rollup/rollup-freebsd-x64@4.40.1': optional: true - '@rollup/rollup-linux-arm-gnueabihf@4.40.0': - optional: true - '@rollup/rollup-linux-arm-gnueabihf@4.40.1': optional: true - '@rollup/rollup-linux-arm-musleabihf@4.40.0': - optional: true - '@rollup/rollup-linux-arm-musleabihf@4.40.1': optional: true - '@rollup/rollup-linux-arm64-gnu@4.40.0': - optional: true - '@rollup/rollup-linux-arm64-gnu@4.40.1': optional: true - '@rollup/rollup-linux-arm64-musl@4.40.0': - optional: true - '@rollup/rollup-linux-arm64-musl@4.40.1': optional: true - '@rollup/rollup-linux-loongarch64-gnu@4.40.0': - optional: true - '@rollup/rollup-linux-loongarch64-gnu@4.40.1': optional: true - '@rollup/rollup-linux-powerpc64le-gnu@4.40.0': - optional: true - '@rollup/rollup-linux-powerpc64le-gnu@4.40.1': optional: true - '@rollup/rollup-linux-riscv64-gnu@4.40.0': - optional: true - '@rollup/rollup-linux-riscv64-gnu@4.40.1': optional: true - '@rollup/rollup-linux-riscv64-musl@4.40.0': - optional: true - '@rollup/rollup-linux-riscv64-musl@4.40.1': optional: true - '@rollup/rollup-linux-s390x-gnu@4.40.0': - optional: true - '@rollup/rollup-linux-s390x-gnu@4.40.1': optional: true - '@rollup/rollup-linux-x64-gnu@4.40.0': - optional: true - '@rollup/rollup-linux-x64-gnu@4.40.1': optional: true - '@rollup/rollup-linux-x64-musl@4.40.0': - optional: true - '@rollup/rollup-linux-x64-musl@4.40.1': optional: true - '@rollup/rollup-win32-arm64-msvc@4.40.0': - optional: true - '@rollup/rollup-win32-arm64-msvc@4.40.1': optional: true - '@rollup/rollup-win32-ia32-msvc@4.40.0': - optional: true - '@rollup/rollup-win32-ia32-msvc@4.40.1': optional: true - '@rollup/rollup-win32-x64-msvc@4.40.0': - optional: true - '@rollup/rollup-win32-x64-msvc@4.40.1': optional: true @@ -4110,14 +3949,14 @@ snapshots: '@ungap/structured-clone@1.3.0': {} - '@vitejs/plugin-react@4.4.1(vite@6.3.4(jiti@1.21.7)(tsx@4.19.4)(yaml@2.7.1))': + '@vitejs/plugin-react@4.4.1(vite@6.3.4(jiti@2.4.2)(lightningcss@1.29.2)(tsx@4.19.4)(yaml@2.7.1))': dependencies: '@babel/core': 7.27.1 '@babel/plugin-transform-react-jsx-self': 7.27.1(@babel/core@7.27.1) '@babel/plugin-transform-react-jsx-source': 7.27.1(@babel/core@7.27.1) '@types/babel__core': 7.20.5 react-refresh: 0.17.0 - vite: 6.3.4(jiti@1.21.7)(tsx@4.19.4)(yaml@2.7.1) + vite: 6.3.4(jiti@2.4.2)(lightningcss@1.29.2)(tsx@4.19.4)(yaml@2.7.1) transitivePeerDependencies: - supports-color @@ -4223,20 +4062,20 @@ snapshots: astro-delete-unused-images@1.0.3: {} - astro-meta-tags@0.3.1(astro@5.7.5(jiti@1.21.7)(rollup@4.40.1)(tsx@4.19.4)(typescript@5.8.3)(yaml@2.7.1)): + astro-meta-tags@0.3.1(astro@5.7.10(jiti@2.4.2)(lightningcss@1.29.2)(rollup@4.40.1)(tsx@4.19.4)(typescript@5.8.3)(yaml@2.7.1)): dependencies: - astro: 5.7.5(jiti@1.21.7)(rollup@4.40.1)(tsx@4.19.4)(typescript@5.8.3)(yaml@2.7.1) + astro: 5.7.10(jiti@2.4.2)(lightningcss@1.29.2)(rollup@4.40.1)(tsx@4.19.4)(typescript@5.8.3)(yaml@2.7.1) - astro-pagefind@1.8.3(astro@5.7.5(jiti@1.21.7)(rollup@4.40.1)(tsx@4.19.4)(typescript@5.8.3)(yaml@2.7.1)): + astro-pagefind@1.8.3(astro@5.7.10(jiti@2.4.2)(lightningcss@1.29.2)(rollup@4.40.1)(tsx@4.19.4)(typescript@5.8.3)(yaml@2.7.1)): dependencies: '@pagefind/default-ui': 1.3.0 - astro: 5.7.5(jiti@1.21.7)(rollup@4.40.1)(tsx@4.19.4)(typescript@5.8.3)(yaml@2.7.1) + astro: 5.7.10(jiti@2.4.2)(lightningcss@1.29.2)(rollup@4.40.1)(tsx@4.19.4)(typescript@5.8.3)(yaml@2.7.1) pagefind: 1.3.0 sirv: 3.0.1 astro-preload@1.1.2: {} - astro@5.7.5(jiti@1.21.7)(rollup@4.40.1)(tsx@4.19.4)(typescript@5.8.3)(yaml@2.7.1): + astro@5.7.10(jiti@2.4.2)(lightningcss@1.29.2)(rollup@4.40.1)(tsx@4.19.4)(typescript@5.8.3)(yaml@2.7.1): dependencies: '@astrojs/compiler': 2.11.0 '@astrojs/internal-helpers': 0.6.1 @@ -4275,7 +4114,7 @@ snapshots: neotraverse: 0.6.18 p-limit: 6.2.0 p-queue: 8.1.0 - package-manager-detector: 1.2.0 + package-manager-detector: 1.3.0 picomatch: 4.0.2 prompts: 2.4.2 rehype: 13.0.2 @@ -4285,12 +4124,12 @@ snapshots: tinyglobby: 0.2.13 tsconfck: 3.1.5(typescript@5.8.3) ultrahtml: 1.6.0 - unifont: 0.2.0 + unifont: 0.4.1 unist-util-visit: 5.0.0 - unstorage: 1.15.0 + unstorage: 1.16.0 vfile: 6.0.3 - vite: 6.3.3(jiti@1.21.7)(tsx@4.19.4)(yaml@2.7.1) - vitefu: 1.0.6(vite@6.3.3(jiti@1.21.7)(tsx@4.19.4)(yaml@2.7.1)) + vite: 6.3.4(jiti@2.4.2)(lightningcss@1.29.2)(tsx@4.19.4)(yaml@2.7.1) + vitefu: 1.0.6(vite@6.3.4(jiti@2.4.2)(lightningcss@1.29.2)(tsx@4.19.4)(yaml@2.7.1)) xxhash-wasm: 1.1.0 yargs-parser: 21.1.1 yocto-spinner: 0.2.2 @@ -4828,7 +4667,7 @@ snapshots: globals@11.12.0: {} - h3@1.15.1: + h3@1.15.3: dependencies: cookie-es: 1.2.2 crossws: 0.3.4 @@ -5071,6 +4910,9 @@ snapshots: jiti@1.21.7: {} + jiti@2.4.2: + optional: true + js-tokens@4.0.0: {} js-yaml@4.1.0: @@ -5095,6 +4937,52 @@ snapshots: kleur@4.1.5: {} + lightningcss-darwin-arm64@1.29.2: + optional: true + + lightningcss-darwin-x64@1.29.2: + optional: true + + lightningcss-freebsd-x64@1.29.2: + optional: true + + lightningcss-linux-arm-gnueabihf@1.29.2: + optional: true + + lightningcss-linux-arm64-gnu@1.29.2: + optional: true + + lightningcss-linux-arm64-musl@1.29.2: + optional: true + + lightningcss-linux-x64-gnu@1.29.2: + optional: true + + lightningcss-linux-x64-musl@1.29.2: + optional: true + + lightningcss-win32-arm64-msvc@1.29.2: + optional: true + + lightningcss-win32-x64-msvc@1.29.2: + optional: true + + lightningcss@1.29.2: + dependencies: + detect-libc: 2.0.4 + optionalDependencies: + lightningcss-darwin-arm64: 1.29.2 + lightningcss-darwin-x64: 1.29.2 + lightningcss-freebsd-x64: 1.29.2 + lightningcss-linux-arm-gnueabihf: 1.29.2 + lightningcss-linux-arm64-gnu: 1.29.2 + lightningcss-linux-arm64-musl: 1.29.2 + lightningcss-linux-x64-gnu: 1.29.2 + lightningcss-linux-x64-musl: 1.29.2 + lightningcss-win32-arm64-msvc: 1.29.2 + lightningcss-win32-x64-msvc: 1.29.2 + optional: true + lilconfig@3.1.3: {} lines-and-columns@1.2.4: {} @@ -5125,8 +5013,8 @@ snapshots: magicast@0.3.5: dependencies: - '@babel/parser': 7.27.0 - '@babel/types': 7.27.0 + '@babel/parser': 7.27.1 + '@babel/types': 7.27.1 source-map-js: 1.2.1 markdown-extensions@2.0.0: {} @@ -5686,7 +5574,7 @@ snapshots: package-json-from-dist@1.0.1: {} - package-manager-detector@1.2.0: {} + package-manager-detector@1.3.0: {} pagefind@1.3.0: optionalDependencies: @@ -6083,32 +5971,6 @@ snapshots: reusify@1.1.0: {} - rollup@4.40.0: - dependencies: - '@types/estree': 1.0.7 - optionalDependencies: - '@rollup/rollup-android-arm-eabi': 4.40.0 - '@rollup/rollup-android-arm64': 4.40.0 - '@rollup/rollup-darwin-arm64': 4.40.0 - '@rollup/rollup-darwin-x64': 4.40.0 - '@rollup/rollup-freebsd-arm64': 4.40.0 - '@rollup/rollup-freebsd-x64': 4.40.0 - '@rollup/rollup-linux-arm-gnueabihf': 4.40.0 - '@rollup/rollup-linux-arm-musleabihf': 4.40.0 - '@rollup/rollup-linux-arm64-gnu': 4.40.0 - '@rollup/rollup-linux-arm64-musl': 4.40.0 - '@rollup/rollup-linux-loongarch64-gnu': 4.40.0 - '@rollup/rollup-linux-powerpc64le-gnu': 4.40.0 - '@rollup/rollup-linux-riscv64-gnu': 4.40.0 - '@rollup/rollup-linux-riscv64-musl': 4.40.0 - '@rollup/rollup-linux-s390x-gnu': 4.40.0 - '@rollup/rollup-linux-x64-gnu': 4.40.0 - '@rollup/rollup-linux-x64-musl': 4.40.0 - '@rollup/rollup-win32-arm64-msvc': 4.40.0 - '@rollup/rollup-win32-ia32-msvc': 4.40.0 - '@rollup/rollup-win32-x64-msvc': 4.40.0 - fsevents: 2.3.3 - rollup@4.40.1: dependencies: '@types/estree': 1.0.7 @@ -6466,7 +6328,7 @@ snapshots: trough: 2.2.0 vfile: 6.0.3 - unifont@0.2.0: + unifont@0.4.1: dependencies: css-tree: 3.1.0 ohash: 2.0.11 @@ -6517,12 +6379,12 @@ snapshots: unist-util-is: 6.0.0 unist-util-visit-parents: 6.0.1 - unstorage@1.15.0: + unstorage@1.16.0: dependencies: anymatch: 3.1.3 chokidar: 4.0.3 destr: 2.0.5 - h3: 1.15.1 + h3: 1.15.3 lru-cache: 10.4.3 node-fetch-native: 1.6.6 ofetch: 1.4.1 @@ -6551,21 +6413,7 @@ snapshots: '@types/unist': 3.0.3 vfile-message: 4.0.2 - vite@6.3.3(jiti@1.21.7)(tsx@4.19.4)(yaml@2.7.1): - dependencies: - esbuild: 0.25.3 - fdir: 6.4.4(picomatch@4.0.2) - picomatch: 4.0.2 - postcss: 8.5.3 - rollup: 4.40.0 - tinyglobby: 0.2.13 - optionalDependencies: - fsevents: 2.3.3 - jiti: 1.21.7 - tsx: 4.19.4 - yaml: 2.7.1 - - vite@6.3.4(jiti@1.21.7)(tsx@4.19.4)(yaml@2.7.1): + vite@6.3.4(jiti@2.4.2)(lightningcss@1.29.2)(tsx@4.19.4)(yaml@2.7.1): dependencies: esbuild: 0.25.3 fdir: 6.4.4(picomatch@4.0.2) @@ -6575,13 +6423,14 @@ snapshots: tinyglobby: 0.2.13 optionalDependencies: fsevents: 2.3.3 - jiti: 1.21.7 + jiti: 2.4.2 + lightningcss: 1.29.2 tsx: 4.19.4 yaml: 2.7.1 - vitefu@1.0.6(vite@6.3.3(jiti@1.21.7)(tsx@4.19.4)(yaml@2.7.1)): + vitefu@1.0.6(vite@6.3.4(jiti@2.4.2)(lightningcss@1.29.2)(tsx@4.19.4)(yaml@2.7.1)): optionalDependencies: - vite: 6.3.3(jiti@1.21.7)(tsx@4.19.4)(yaml@2.7.1) + vite: 6.3.4(jiti@2.4.2)(lightningcss@1.29.2)(tsx@4.19.4)(yaml@2.7.1) volar-service-css@0.0.62(@volar/language-service@2.4.13): dependencies: diff --git a/public/draft.png b/public/draft.png new file mode 100644 index 000000000..aa9ce2df7 Binary files /dev/null and b/public/draft.png differ diff --git a/src/components/BaseHead.astro b/src/components/BaseHead.astro index 0bca0f0b3..d4c659292 100644 --- a/src/components/BaseHead.astro +++ b/src/components/BaseHead.astro @@ -57,3 +57,9 @@ const { title, description, image = "/social-card.png" } = Astro.props; is:inline data-domain="ep2025.europython.eu" src="https://plausible.io/js/script.js"> + + diff --git a/src/components/CardContent.astro b/src/components/CardContent.astro new file mode 100644 index 000000000..c7c1e9827 --- /dev/null +++ b/src/components/CardContent.astro @@ -0,0 +1,15 @@ +--- +import { getEntry } from "astro:content"; +import { marked } from 'marked'; +const { collection, entry:entryId } = Astro.props; + +const entry = await getEntry(collection, entryId); +const html = entry && entry.body ? marked.parse(entry.body) : ""; + +--- + + { html && +
+
+
+ } diff --git a/src/components/JobCard.astro b/src/components/JobCard.astro new file mode 100644 index 000000000..0bbd5b26c --- /dev/null +++ b/src/components/JobCard.astro @@ -0,0 +1,94 @@ +--- +import { getEntry } from "astro:content"; +const { job:jobId, sponsor:sponsorId } = Astro.props; + +const job = await getEntry("jobs", jobId); +if (!job) { + throw new Error(`Job with ID "${jobId}" not found`); +} + +const sponsor = await getEntry("sponsors", sponsorId); + +if (!sponsor) { + throw new Error(`Sponsor with ID "${sponsorId}" not found`); +} + +// TODO: add tags +const { title, location, type, level, salary, description, responsibilities, requirements, benefits, apply_link, draft } = job.data; + +--- + +
+
+ +

{title}

+
+ + + {sponsor.data.name} + + + { level && type && location && +

{level} • {type} • {location}

+ } +

{salary}

+

{description}

+ + { responsibilities && +

Responsibilities

+ + } + + { requirements && +

Requirements

+ + } + + { benefits && +

Benefits

+ + } + + + Apply Now + +
+
+ + diff --git a/src/components/Search.astro b/src/components/Search.astro index f740c6a2c..512c8add0 100644 --- a/src/components/Search.astro +++ b/src/components/Search.astro @@ -33,7 +33,6 @@ document.addEventListener("DOMContentLoaded", function () { let selectedIndex = -1; function openSearch() { - console.log("open"); openModal.click(); if (searchInput) { searchInput.value = "Tips"; diff --git a/src/components/SponsorCard.astro b/src/components/SponsorCard.astro new file mode 100644 index 000000000..07ef4065d --- /dev/null +++ b/src/components/SponsorCard.astro @@ -0,0 +1,298 @@ +--- +import { type CollectionEntry, getEntry } from "astro:content"; +import { Image } from "astro:assets"; +import { sponsorLogos } from "@data/sponsorLogos"; +import Icon from "@ui/Icon.astro"; + +const { sponsor: sponsorId, showJobs=false } = Astro.props; +const sponsor = await getEntry("sponsors", sponsorId); + +if (!sponsor) { + throw new Error(`Sponsor with ID "${sponsorId}" not found`); +} + +const { + name: title, + url: website, + location, + industry, + description, + socials, + tier, + logo_padding = false, + draft +} = sponsor.data; + +const jobFiles = import.meta.glob("../content/sponsors/*/!(index).md"); +const sponsorsJobsMap = {}; + +for (const path in jobFiles) { + const match = path.match(/\.\.\/content\/sponsors\/([^/]+)\/([^/]+)\.md$/); + if (match) { + const sponsorId = match[1]; + if (!sponsorsJobsMap[sponsorId]) sponsorsJobsMap[sponsorId] = []; + sponsorsJobsMap[sponsorId].push( + await getEntry("jobs", `${sponsorId}/${match[2]}`), + ); + } +} + +const jobs: CollectionEntry<"jobs">[] = sponsorsJobsMap[sponsor.id]; + +const isSponsorPage = Astro.url.pathname == `/sponsor/${sponsor.id}`; + +const logo = sponsorLogos[sponsor.id]; + +const socialLinks = [ + { key: "linkedin", icon: "linkedin-in", label: "LinkedIn Profile" }, + { key: "twitter", icon: "twitter", label: "Twitter Profile" }, + { key: "discord", icon: "discord", label: "Discord Profile" }, + { key: "mastodon", icon: "mastodon", label: "Mastodon Profile" }, + { key: "bluesky", icon: "bluesky", label: "Bluesky Profile" }, + { key: "facebook", icon: "facebook-f", label: "Facebook Profile" }, + { key: "github", icon: "github", label: "GitHub Profile" }, + { key: "instagram", icon: "instagram", label: "Instagram Profile" }, +]; +--- + +
+
+ { + logo && ( + {`${title} + ) + } +
+ + { + description && ( +
+

+ { !isSponsorPage ? + + {title} + : + <>{title} + } +

+

+ {industry} {industry && location && <>—} {location} +

+ +

{description}

+ + + {showJobs && jobs && ( +
+

Job offers

+ +
+ )} + + + {(tier !== "Partners") && website && ( +
+ + { !isSponsorPage && sponsor.body && + + About {title} + + } + + + Visit Website + +
+ )} + + + { (tier !== "Partners") && + + } +
+ ) + } +
+ + diff --git a/src/components/SponsorDisplay.astro b/src/components/SponsorDisplay.astro new file mode 100644 index 000000000..4968dcd65 --- /dev/null +++ b/src/components/SponsorDisplay.astro @@ -0,0 +1,28 @@ +--- +import { getEntry } from "astro:content"; +import { Image } from "astro:assets"; +const { sponsor: sponsorId } = Astro.props; + + +const sponsor = await getEntry("sponsors", sponsorId); + +if (!sponsor) { + throw new Error(`Sponsor with ID "${sponsorId}" not found`); +} + + +import { sponsorDisplay } from "@data/sponsorDisplay"; +const image = sponsorDisplay[sponsor.id] +--- + +{ image && +
+ Image +
+} diff --git a/src/components/SponsorLogo.astro b/src/components/SponsorLogo.astro new file mode 100644 index 000000000..bc708bfb8 --- /dev/null +++ b/src/components/SponsorLogo.astro @@ -0,0 +1,56 @@ +--- +import { getEntry } from "astro:content"; +import { Image } from "astro:assets"; +import { sponsorLogos } from "@data/sponsorLogos"; + +const { sponsor: sponsorId } = Astro.props; + + +const sponsor = await getEntry("sponsors", sponsorId); + +if (!sponsor) { + throw new Error(`Sponsor with ID "${sponsorId}" not found`); +} + +const { + name: title, + url: website, + logo_padding = false, +} = sponsor.data; + +const logo = sponsorLogos[sponsor.id]; +--- + +
+
+ { + website ? ( + + + {`${title} + + ): + {`${title} + } +
+
diff --git a/src/components/TwoCols.astro b/src/components/TwoCols.astro new file mode 100644 index 000000000..6b8cbbdb9 --- /dev/null +++ b/src/components/TwoCols.astro @@ -0,0 +1,12 @@ +--- +--- +
+
+
+ +
+
+ +
+
+
diff --git a/src/components/sections/subscribe.astro b/src/components/sections/subscribe.astro index cf521f398..8cb5e5de3 100644 --- a/src/components/sections/subscribe.astro +++ b/src/components/sections/subscribe.astro @@ -2,7 +2,7 @@ import Button from "@ui/Button.astro"; import Section from "@ui/Section.astro" const socialLinks = [ - { href: "https://linkedin.com/company/europython/", icon: "linkedin" }, + { href: "https://linkedin.com/sponsor/europython/", icon: "linkedin" }, { href: "https://instagram.com/europython/", icon: "instagram" }, { href: "https://youtube.com/channel/UC98CzaYuFNAA_gOINFB0e4Q", icon: "youtube" }, { href: "https://fosstodon.org/@europython", icon: "mastodon" }, diff --git a/src/components/sponsor-tiers/sponsor-tiers.astro b/src/components/sponsor-tiers/sponsor-tiers.astro index cbc2fd7bb..aa4045258 100644 --- a/src/components/sponsor-tiers/sponsor-tiers.astro +++ b/src/components/sponsor-tiers/sponsor-tiers.astro @@ -174,7 +174,7 @@ const formatPrice = (price: number | string) => {

Most Popular Options

- Ideal for companies seeking high brand visibility and strong participant + Ideal for sponsors seeking high brand visibility and strong participant engagement

@@ -243,7 +243,7 @@ const formatPrice = (price: number | string) => {

Major Supporters

- Unique sponsorship tiers designed to make your company stand out from the + Unique sponsorship tiers designed to make your sponsor stand out from the rest

@@ -301,7 +301,7 @@ const formatPrice = (price: number | string) => {

Starter Tiers

- Perfect opportunity for companies with more modest budgets + Perfect opportunity for sponsors with more modest budgets

{sponsor.data.name} tier.name === "Keystone"); ) : (

Sponsoring EuroPython guarantees you highly targeted visibility - and the opportunity to present yourself and your company to one + and the opportunity to present yourself and your sponsor to one of the largest and most diverse Python communities in Europe and beyond.

diff --git a/src/components/ticket-tiers/ticket-tiers.astro b/src/components/ticket-tiers/ticket-tiers.astro index f143e321f..5f18f7607 100644 --- a/src/components/ticket-tiers/ticket-tiers.astro +++ b/src/components/ticket-tiers/ticket-tiers.astro @@ -39,7 +39,7 @@ const tiers: TicketTierProps[] = [ icon: "❌", }, { - text: "Does NOT include access to sponsor booths with opportunities to connect with sponsoring companies", + text: "Does NOT include access to sponsor booths with opportunities to connect with sponsoring sponsors", icon: "❌", }, { text: "Access to Sprint Weekend (19-20 July)" }, @@ -74,7 +74,7 @@ const tiers: TicketTierProps[] = [ { text: "Access to open spaces throughout the three conference days" }, { text: "Access to Sprint Weekend (19-20 July)" }, { - text: "Access to sponsor booths with opportunities to connect with sponsoring companies", + text: "Access to sponsor booths with opportunities to connect with sponsoring sponsors", }, { text: "Access to Sprint Weekend (19-20 July)" }, { text: "Limited access to specific sponsored workshops" }, @@ -103,7 +103,7 @@ const tiers: TicketTierProps[] = [ }, { text: "Access to open spaces throughout the three conference days" }, { - text: "Access to sponsor booths with opportunities to connect with sponsoring companies", + text: "Access to sponsor booths with opportunities to connect with sponsoring sponsors", }, { text: "Access to Sprint Weekend (19-20 July)" }, { text: "Limited access to specific sponsored workshops" }, diff --git a/src/components/ui/Icon.astro b/src/components/ui/Icon.astro index d8c1c287a..860200573 100644 --- a/src/components/ui/Icon.astro +++ b/src/components/ui/Icon.astro @@ -2,6 +2,7 @@ const { name, svg = false, + style="solid", class: className = "", size = "", // Default size (Tailwind) label = "", @@ -20,7 +21,7 @@ const { ) : ( - z.object({ - name: z.string(), - url: z.string(), - image: image(), - tier: z.enum(tiers), - }), -}); - const keynoters = defineCollection({ type: "content", schema: ({ image }) => @@ -215,12 +191,57 @@ const days = defineCollection({ }), }); +const sponsors = defineCollection({ + loader: glob({ pattern: "*/index.md", base: "./src/content/sponsors" }), + schema: z.object({ + name: z.string(), + url: z.string().url(), + tier: z.string().nullable(), + location: z.string().optional(), + industry: z.string().optional(), + description: z.string().optional(), + socials: z + .object({ + linkedin: z.string().url().optional().nullable(), + twitter: z.string().url().optional().nullable(), + github: z.string().url().optional().nullable(), + discord: z.string().url().optional().nullable(), + mastodon: z.string().url().optional().nullable(), + bluesky: z.string().url().optional().nullable(), + }) + .optional(), + logo_padding: z.string().optional(), + draft: z.boolean().optional().default(false), + jobs: z.array(reference("jobs")).optional().default([]), + }), +}); + +const jobs = defineCollection({ + loader: glob({ pattern: "*/!(index).md", base: "./src/content/sponsors" }), + schema: z.object({ + title: z.string(), + location: z.string().nullable(), + type: z.string().nullable(), // e.g., Full-Time + level: z.string().nullable(), // e.g., Senior + salary: z.string().nullable(), + tags: z.array(z.string()).nullable(), + description: z.string().nullable(), + responsibilities: z.array(z.string()).nullable(), + requirements: z.array(z.string()).nullable(), + benefits: z.array(z.string()).nullable(), + apply_link: z.string().url().optional(), + draft: z.boolean().optional().default(false), + sponsor: reference("sponsors").optional(), + }), +}); + export const collections = { days, pages, deadlines, - sponsors, sessions, speakers, keynoters, + sponsors, + jobs, }; diff --git a/src/content/sponsors/.gitkeep b/src/content/sponsors/.gitkeep deleted file mode 100644 index e69de29bb..000000000 diff --git a/src/content/sponsors/1password.yaml b/src/content/sponsors/1password.yaml deleted file mode 100644 index be4a1f4c4..000000000 --- a/src/content/sponsors/1password.yaml +++ /dev/null @@ -1,4 +0,0 @@ -name: 1Password -url: https://1password.com/ -image: ./1password.svg -tier: Supporters diff --git a/src/content/sponsors/1password.svg b/src/content/sponsors/1password/1password.svg similarity index 100% rename from src/content/sponsors/1password.svg rename to src/content/sponsors/1password/1password.svg diff --git a/src/content/sponsors/1password/index.md b/src/content/sponsors/1password/index.md new file mode 100644 index 000000000..c9e0750e0 --- /dev/null +++ b/src/content/sponsors/1password/index.md @@ -0,0 +1,20 @@ +--- +name: "1Password" +url: "https://1password.com" +location: "Toronto, Ontario, Canada" +industry: "Cybersecurity & Privacy" +description: + "1Password is a leading provider of password management solutions, offering + secure tools for individuals and businesses to protect sensitive data and + combat shadow IT. Founded in 2005, the company prioritizes user experience, + privacy, and security across its cross-platform applications." +socials: + linkedin: + twitter: + github: + discord: + mastodon: + bluesky: +tier: Supporters +logo_padding: 30px 10px +--- diff --git a/src/content/sponsors/djangocon.yaml b/src/content/sponsors/djangocon.yaml deleted file mode 100644 index e7b88c6f6..000000000 --- a/src/content/sponsors/djangocon.yaml +++ /dev/null @@ -1,4 +0,0 @@ -name: DjangoCon Europe -url: https://2025.djangocon.eu/ -image: ./djangocon.png -tier: Partners diff --git a/src/content/sponsors/djangocon/display.png b/src/content/sponsors/djangocon/display.png new file mode 100644 index 000000000..fedf914bf Binary files /dev/null and b/src/content/sponsors/djangocon/display.png differ diff --git a/src/content/sponsors/djangocon.png b/src/content/sponsors/djangocon/djangocon.png similarity index 100% rename from src/content/sponsors/djangocon.png rename to src/content/sponsors/djangocon/djangocon.png diff --git a/src/content/sponsors/djangocon/index.md b/src/content/sponsors/djangocon/index.md new file mode 100644 index 000000000..3282addc0 --- /dev/null +++ b/src/content/sponsors/djangocon/index.md @@ -0,0 +1,18 @@ +--- +name: DjangoCon Europe +url: https://2025.djangocon.eu/ +industry: "Technology & Open Source Community" +description: + "DjangoCon Europe is a volunteer-driven, non-profit conference dedicated to + fostering the growth and development of the Django community. It brings + together developers, designers, and enthusiasts to share knowledge and + collaborate on open-source projects." +socials: + linkedin: "https://linkedin.com/company/djangoconeurope" + twitter: "https://twitter.com/DjangoConEurope" + github: + discord: + mastodon: + bluesky: +tier: Partners +--- diff --git a/src/content/sponsors/eps.yaml b/src/content/sponsors/eps.yaml deleted file mode 100644 index 875315ee9..000000000 --- a/src/content/sponsors/eps.yaml +++ /dev/null @@ -1,4 +0,0 @@ -name: EuroPython Society -url: https://www.europython-society.org/ -image: ./eps.svg -tier: Financial Aid diff --git a/src/content/sponsors/eps/display.png b/src/content/sponsors/eps/display.png new file mode 100644 index 000000000..32e744322 Binary files /dev/null and b/src/content/sponsors/eps/display.png differ diff --git a/src/content/sponsors/eps.svg b/src/content/sponsors/eps/eps.svg similarity index 100% rename from src/content/sponsors/eps.svg rename to src/content/sponsors/eps/eps.svg diff --git a/src/content/sponsors/eps/index.md b/src/content/sponsors/eps/index.md new file mode 100644 index 000000000..02797ad83 --- /dev/null +++ b/src/content/sponsors/eps/index.md @@ -0,0 +1,26 @@ +--- +name: EuroPython Society +url: https://www.europython-society.org/ +location: "Sweden" +industry: "Technology & Non-Profit" +description: | + The EuroPython Society (EPS) is a Swedish non-profit organization dedicated to supporting Python communities across Europe. It organizes EuroPython conferences, sponsors initiatives like financial aid programs, and promotes diversity and inclusion in the tech ecosystem. +socials: + linkedin: "https://linkedin.com/company/europython" + twitter: "https://twitter.com/EuroPython" + github: + discord: + mastodon: + bluesky: +tier: Financial Aid +draft: true +--- + +## About EuroPython Society + +The EuroPython Society (EPS) is a Swedish non-profit organization dedicated to +supporting Python communities across Europe and organizing EuroPython +conferences. Founded in 2004, EPS provides a legal framework for EuroPython +events and champions the growth of the Python ecosystem through initiatives like +sponsoring PyCon+Web 2025. By fostering collaboration and innovation, EPS plays +a critical role in advancing Python programming across the continent. diff --git a/src/content/sponsors/evolabel.yaml b/src/content/sponsors/evolabel.yaml deleted file mode 100644 index 9e2de2305..000000000 --- a/src/content/sponsors/evolabel.yaml +++ /dev/null @@ -1,4 +0,0 @@ -name: evolabel -url: https://www.evolabel.com/ -image: ./evolabel.svg -tier: Supporters diff --git a/src/content/sponsors/evolabel/digital-marketing-manager.md b/src/content/sponsors/evolabel/digital-marketing-manager.md new file mode 100644 index 000000000..2b0b3f774 --- /dev/null +++ b/src/content/sponsors/evolabel/digital-marketing-manager.md @@ -0,0 +1,27 @@ +--- +title: "Digital Marketing Manager" +location: "Sweden (new office)" +type: "Full-Time" +level: "Mid-Level" +salary: "Competitive" +tags: + - "Digital Marketing" + - "Graphic Design" + - "Reseller Support" +description: | + Evolabel is hiring a Digital Marketing Manager to create graphic materials and provide tailored support to resellers [[5]]. +responsibilities: + - "Design and execute digital marketing campaigns." + - "Create engaging graphic materials for marketing assets." + - "Collaborate with resellers to deliver customized solutions." +requirements: + - "Proven experience in digital marketing or related field." + - "Strong graphic design skills (Adobe Suite, etc.)." + - "Ability to work in a dynamic, fast-paced environment." +benefits: + - "Opportunity to join a growing AI-driven company." + - "Work in a newly established office in Sweden [[1]]." + - "Support for professional development." +apply_link: "https://evolabel.com/careers" +draft: true +--- diff --git a/src/content/sponsors/evolabel/display.png b/src/content/sponsors/evolabel/display.png new file mode 100644 index 000000000..a163b4cda Binary files /dev/null and b/src/content/sponsors/evolabel/display.png differ diff --git a/src/content/sponsors/evolabel.svg b/src/content/sponsors/evolabel/evolabel.svg similarity index 100% rename from src/content/sponsors/evolabel.svg rename to src/content/sponsors/evolabel/evolabel.svg diff --git a/src/content/sponsors/evolabel/index.md b/src/content/sponsors/evolabel/index.md new file mode 100644 index 000000000..ea9f79280 --- /dev/null +++ b/src/content/sponsors/evolabel/index.md @@ -0,0 +1,27 @@ +--- +name: "Evolabel" +url: "https://www.evolabel.com" +location: "France" +industry: "AI & Data Labeling" +description: + "Evolabel specializes in AI training data solutions, providing high-quality + labeling services for machine learning projects. While specific 2025 + partnerships aren’t detailed in available data, Evolabel remains a key player + in scalable AI development." +socials: + linkedin: "https://linkedin.com/company/evolabel" + twitter: + github: + discord: + mastodon: + bluesky: +tier: Supporters +logo_padding: 30px 0 +draft: true +--- + +## About Evolabel + +Evolabel focuses on democratizing AI through efficient data annotation tools and +workflows. Though 2025 updates are sparse, its role in enabling accurate machine +learning models remains critical for industries leveraging AI. diff --git a/src/content/sponsors/jetbrains.yaml b/src/content/sponsors/jetbrains.yaml deleted file mode 100644 index 9edc8c7b4..000000000 --- a/src/content/sponsors/jetbrains.yaml +++ /dev/null @@ -1,4 +0,0 @@ -name: JetBrains -url: https://www.jetbrains.com/ -image: ./jetbrains.svg -tier: Gold diff --git a/src/content/sponsors/jetbrains/data-scientist.md b/src/content/sponsors/jetbrains/data-scientist.md new file mode 100644 index 000000000..dd96f02ca --- /dev/null +++ b/src/content/sponsors/jetbrains/data-scientist.md @@ -0,0 +1,27 @@ +--- +title: "Data Scientist/ML Engineer" +location: "Worldwide (Remote/Onsite)" +type: "Full-Time" +level: "Mid-Level" +salary: "Competitive" +tags: + - "Machine Learning" + - "Data Science" + - "Python" +description: | + JetBrains is hiring Data Scientists/ML Engineers to enhance its intelligent IDEs like PyCharm and IntelliJ IDEA. With 50–100 open roles at any time [[3]], this position focuses on improving developer tools through data-driven insights. +responsibilities: + - "Develop ML models to improve code analysis and IDE features." + - "Collaborate with cross-functional teams to integrate AI solutions." + - "Analyze large datasets to optimize user experiences." +requirements: + - "Strong background in data science or machine learning." + - "Proficiency in Python and related libraries (e.g., TensorFlow, PyTorch)" + - "Experience with scalable data processing frameworks." +benefits: + - "Global, flexible work environment." + - "Opportunity to work on cutting-edge developer tools." + - "Professional growth and mentorship programs." +apply_link: "https://careers.jetbrains.com" +draft: true +--- diff --git a/src/content/sponsors/jetbrains/display.png b/src/content/sponsors/jetbrains/display.png new file mode 100644 index 000000000..407179e8e Binary files /dev/null and b/src/content/sponsors/jetbrains/display.png differ diff --git a/src/content/sponsors/jetbrains/index.md b/src/content/sponsors/jetbrains/index.md new file mode 100644 index 000000000..727ed4440 --- /dev/null +++ b/src/content/sponsors/jetbrains/index.md @@ -0,0 +1,27 @@ +--- +name: "JetBrains" +url: "https://jetbrains.com" +location: "Czech Republic" +industry: "Software Development Tools" +description: + "JetBrains develops intelligent IDEs like PyCharm and IntelliJ IDEA, + supporting developers globally. In 2025, JetBrains sponsored the International + Olympiad in Informatics (IOI) with free software licenses and participated in + GDC 2025, while running its annual Developer Ecosystem Survey." +socials: + linkedin: "https://linkedin.com/company/jetbrains" + twitter: "https://twitter.com/JetBrains" + github: "https://github.com/JetBrains" + discord: + mastodon: + bluesky: +tier: Gold +logo_padding: 20px 10px +draft: true +--- + +## About JetBrains + +JetBrains is a global leader in developer productivity tools, offering solutions +for Python, Java, JavaScript, and more. In 2025, it supported community events +with free licenses and expanded its presence at industry conferences like GDC. diff --git a/src/content/sponsors/jetbrains.svg b/src/content/sponsors/jetbrains/jetbrains.svg similarity index 100% rename from src/content/sponsors/jetbrains.svg rename to src/content/sponsors/jetbrains/jetbrains.svg diff --git a/src/content/sponsors/numberly.yaml b/src/content/sponsors/numberly.yaml deleted file mode 100644 index 0fac177fe..000000000 --- a/src/content/sponsors/numberly.yaml +++ /dev/null @@ -1,4 +0,0 @@ -name: Numberly -url: https://numberly.com/ -image: ./numberly.svg -tier: Gold diff --git a/src/content/sponsors/numberly/display.png b/src/content/sponsors/numberly/display.png new file mode 100644 index 000000000..5148f41e1 Binary files /dev/null and b/src/content/sponsors/numberly/display.png differ diff --git a/src/content/sponsors/numberly/index.md b/src/content/sponsors/numberly/index.md new file mode 100644 index 000000000..11687ae40 --- /dev/null +++ b/src/content/sponsors/numberly/index.md @@ -0,0 +1,27 @@ +--- +name: Numberly +url: https://numberly.com/ +description: + Numberly, Marketing Technologist, met la data au service de la relation + client. Le groupe permet aux entreprises de comprendre les besoins de leurs + prospects et clients et d’interagir avec chacun de manière performante et + pertinente. +socials: + linkedin: https://www.linkedin.com/company/numberly/ + twitter: https://x.com/Numberly +tier: Gold +logo_padding: 30px +--- + +Numberly, Marketing Technologist, met la data au service de la relation client. +Le groupe permet aux entreprises de comprendre les besoins de leurs prospects et +clients et d’interagir avec chacun de manière performante et pertinente. + +Nos experts en orchestration omnicanal, en activation programmatique et en +plateformes conversationnelles développent et mettent en place des expériences à +fort impact. Nous opérons dans plus de 50 pays : le groupe, résolument +international, poursuit son expansion depuis 25 ans. + +Plus de 500 collaborateurs, basés à Paris, Londres, Montréal, New York et Dubaï, +contribuent tous les jours à la qualité d’exécution et la satisfaction client, +en restant curieux, agiles et innovants, un état d’esprit qui anime Numberly. diff --git a/src/content/sponsors/numberly/internship-software-engineer-backend-fullstack.md b/src/content/sponsors/numberly/internship-software-engineer-backend-fullstack.md new file mode 100644 index 000000000..8bddbf496 --- /dev/null +++ b/src/content/sponsors/numberly/internship-software-engineer-backend-fullstack.md @@ -0,0 +1,54 @@ +--- +title: "Internship - Software Engineer - Backend / Fullstack" +location: "Paris" +type: "Hybrid" +level: "Intern" +salary: +tags: + [ + "FastAPI", + "Vue 3", + "PostgreSQL", + "MSSQL", + "Kafka", + "Kubernetes", + "Docker", + "GitLab CI/CD", + "Cypress", + "Pytest", + "Grafana", + "Sentry", + "Prometheus", + "Graylog", + ] +description: | + Numberly is recognized as one of the world's leading data marketing specialists with nearly 500 employees and 8 offices worldwide serving more than 500 blue-chip clients (L'Oréal, Sanofi, Moleskine, Campari, Nestlé, HSBC..). By putting technology to work for brands and consumers, Numberly is at the heart of business growth and everyone's desire for more sustainable and relevant marketing. Numberly leverages the latest advances in data processing, analysis and activation, incorporating artificial intelligence technologies. This approach is part of a virtuous circle in which business competitiveness goes hand in hand with greater respect for privacy and data protection. +responsibilities: + - Supporting the operational run of your assigned squad + - Improving deployment and monitoring processes while keeping our technical + stack updated + - Collaborating with product owners and UX/UI designers to develop new + features + - Proposing technical and organizational improvements to enhance platform + performance and maintainability +requirements: + - Collaborative mindset with strong teamwork and stakeholder communication + skills + - Preference for Linux use (not mandatory) + - Familiarity with our tech stack (especially backend technologies like + Python/FastAPI) + - Vue 3 knowledge is a plus but not required + - Open-source contributions experience is a bonus + - Ability to document and advocate for technical decisions +benefits: + - Fast onboarding with mentorship and cross-team rotations + - Global team collaboration via monthly "Happy Meetings" + - Freedom of speech and collaborative decision-making culture + - Social impact initiatives (1000mercis, Open Source contributions) + - Diverse, inclusive workplace (30+ nationalities, 97/100 gender equity score) + - Modern offices with amenities (library, music studio, pet-friendly) + - Remote work flexibility and international office mobility + - Swile meal vouchers, Gymlib access, and mystery lunches + - Support for people with disabilities +apply_link: https://joinus.numberly.com/jobs/5783005-internship-software-engineer-backend-fullstack +--- diff --git a/src/content/sponsors/numberly/it-security-compliance-manager.md b/src/content/sponsors/numberly/it-security-compliance-manager.md new file mode 100644 index 000000000..27445a1d4 --- /dev/null +++ b/src/content/sponsors/numberly/it-security-compliance-manager.md @@ -0,0 +1,56 @@ +--- +title: "IT/Security Compliance Manager" +location: "Paris" +type: "Hybrid" +level: "Manager" +salary: null +tags: + [ + "Linux", + "Windows Server", + "Kubernetes", + "Hadoop", + "PostgreSQL", + "GitLab", + "Google Workspace", + "Yubikey", + "GitLab SAST/DAST", + "Renovate", + "gitleaks", + "Falco", + "CyberVadis", + "ISO27001", + "SOC2", + "DevSecOps", + "GRC", + "Formation cyber", + ] +description: | + Numberly est un leader mondial du Data Marketing, avec 500 collaborateurs et 8 bureaux dans le monde, servant des clients de premier plan comme L'Oréal, HSBC et Moleskine. Notre engagement pour une sécurité renforcée des données s'inscrit dans une approche vertueuse alliant compétitivité et respect de la vie privée. En tant que IT/Security Compliance Manager, vous piloterez la conformité IT et la gestion des risques, en soutien à notre certification ISO27001 et nos projets futurs (SecNumCloud, SOC2). Vous animerez un système de management de la sécurité des informations (SMSI) et participerez à des audits clients et formations internes. +responsibilities: + - Représenter la sécurité vis-à-vis des collaborateurs et clients + - Coordonner la gestion des risques IT et cyber + - Formaliser les contrôles de sécurité conformément aux normes (ISO27001, + SOC2) + - Animer et améliorer le SMSI (Système de Management de la Sécurité de + l'Information) + - Développer et suivre les formations sécurité (phishing, développeurs) + - Répondre aux audits clients et questionnaires de conformité + - Représenter Numberly lors de réunions de due diligence avec les clients +requirements: + - Expérience dans un poste de sécurité IT/Compliance ou similaire + - Participation à un audit ISO27001 ou SOC2 + - Connaissance des environnements techniques internes (hébergement, + développement) + - Excellentes compétences rédactionnelles et communicationnelles + - Maîtrise des outils DevSecOps et gestion des risques +benefits: + - Onboarding intensif avec mentorat et rotations inter-équipes + - Culture d'innovation (logiciels libres, infrastructure internalisée) + - Flexibilité hybride et possibilité de télétravail ponctuel + - Écosystème international (30+ nationalités, score équité genre 97/100) + - Bureaux innovants (studio de musique, bibliothèque, espaces animaux) + - "Avantages : Swile, Gymlib, formations continues, mystery lunches" + - Engagement RSE (1000mercis, Open Source) +apply_link: https://joinus.numberly.com/jobs/5198895-it-security-compliance-manager +--- diff --git a/src/content/sponsors/numberly.svg b/src/content/sponsors/numberly/numberly.svg similarity index 100% rename from src/content/sponsors/numberly.svg rename to src/content/sponsors/numberly/numberly.svg diff --git a/src/content/sponsors/numberly/software-engineer-backend-fullstack.md b/src/content/sponsors/numberly/software-engineer-backend-fullstack.md new file mode 100644 index 000000000..11239f7e2 --- /dev/null +++ b/src/content/sponsors/numberly/software-engineer-backend-fullstack.md @@ -0,0 +1,51 @@ +--- +title: "Software Engineer - Backend / Fullstack" +location: "Paris" +type: "Hybrid" +level: null +salary: null +tags: + [ + "FastAPI", + "Vue 3", + "PostgreSQL", + "MSSQL", + "Kafka", + "GitLab", + "Kubernetes", + "Docker", + "Cypress", + "pytest", + ] +description: | + Numberly uses technology for marketing: we help clients better understand their customers by implementing systems to collect, analyze, and use data. With over 150 engineers (a third of Numberly's talents), we work in autonomous teams to ensure everyone can influence technical and organizational choices. The NMP team develops and maintains the Numberly MarTech Platform, a suite of applications for campaign management across digital channels like email, SMS, push notifications, and social media. We prioritize code quality, modern technical stacks, and efficient processes. We seek a curious, autonomous individual with backend experience to contribute quickly to our team. +responsibilities: + - Collaborating with a product owner and UX/UI designers to develop new + features + - Improving platform performance and user experience + - Documenting technical changes and sharing progress with the team + - Monitoring advancements in tools and libraries + - Proposing technical and organizational improvements +requirements: + - Strong communicator able to explain complex ideas and listen actively + - Desire to grow personally and mentor others technically and professionally + - Confidence in making trade-offs to drive project progress + - Experience writing code and managing deployments + - Professional English proficiency (international teams) + - Preference for Linux use + - Familiarity with our technical stack (especially backend) + - Vue 3 knowledge (a plus) + - Open-source contributions (a plus) +benefits: + - Fast onboarding with mentorship and team rotations + - Monthly global team meetings (Happy Meetings) + - Freedom of speech and collaborative decision-making + - Social impact initiatives (1000mercis, Open Source contributions) + - Diverse workplace (30+ nationalities, 97/100 gender equity score) + - Modern offices with amenities (library, music studio, pet-friendly) + - Remote flexibility (up to 50% remote, 60-day consecutive remote option) + - Swile meal vouchers and international office mobility + - Perks like Gymlib, sports classes, themed parties + - Unlimited coffee/tea/infusions and mystery lunches +apply_link: https://joinus.numberly.com/jobs/4553435-software-engineer-backend-fullstack +--- diff --git a/src/content/sponsors/picnic.yaml b/src/content/sponsors/picnic.yaml deleted file mode 100644 index c64ec5fd6..000000000 --- a/src/content/sponsors/picnic.yaml +++ /dev/null @@ -1,4 +0,0 @@ -name: picnic -url: https://jobs.picnic.app/en/home -image: ./picnic.svg -tier: Gold diff --git a/src/content/sponsors/picnic/data-engineer.md b/src/content/sponsors/picnic/data-engineer.md new file mode 100644 index 000000000..5ee9df4fb --- /dev/null +++ b/src/content/sponsors/picnic/data-engineer.md @@ -0,0 +1,27 @@ +--- +title: "Data Engineer" +location: "Worldwide" +type: "Full-Time" +level: "Mid-Level" +salary: "Competitive" +tags: + - "Data Engineering" + - "Big Data" + - "Python" +description: | + Picnic is hiring Data Engineers to support its AI-driven grocery logistics platform. Roles include building scalable pipelines for real-time analytics and supply chain optimization [[9]]. +responsibilities: + - "Design and maintain data pipelines for logistics systems." + - "Collaborate with data scientists to implement ML models." + - "Optimize data storage and querying for large-scale datasets." +requirements: + - "Experience with big data technologies (e.g., Spark, Kafka)." + - "Proficiency in Python or Scala." + - "Understanding of cloud infrastructure (AWS/GCP)." +benefits: + - "Remote-friendly culture with global teams." + - "Impact-driven work in sustainable e-commerce." + - "Access to learning and development resources." +apply_link: "https://picnic.wiki/careers" +draft: true +--- diff --git a/src/content/sponsors/picnic/display.png b/src/content/sponsors/picnic/display.png new file mode 100644 index 000000000..2c27ae91c Binary files /dev/null and b/src/content/sponsors/picnic/display.png differ diff --git a/src/content/sponsors/picnic/index.md b/src/content/sponsors/picnic/index.md new file mode 100644 index 000000000..9c9e859db --- /dev/null +++ b/src/content/sponsors/picnic/index.md @@ -0,0 +1,25 @@ +--- +name: "Picnic" +url: "https://picnic.wiki" +location: "Germany" +industry: "Grocery Delivery" +description: + "Picnic is a sustainable grocery delivery service operating in Europe. While + no 2025 sponsorships appear in current data, Picnic focuses on eco-friendly + logistics and affordable shopping experiences." +socials: + linkedin: "https://linkedin.com/company/picnic-supermarket" + twitter: "https://twitter.com/Picnic" + github: + discord: + mastodon: + bluesky: +tier: Gold +draft: true +--- + +## About Picnic + +Picnic leverages AI and automation to streamline grocery delivery, reducing +costs and environmental impact. Though not explicitly tied to 2025 events in +available data, it remains a key player in Europe’s e-commerce sector. diff --git a/src/content/sponsors/picnic.svg b/src/content/sponsors/picnic/picnic.svg similarity index 100% rename from src/content/sponsors/picnic.svg rename to src/content/sponsors/picnic/picnic.svg diff --git a/src/content/sponsors/pretalx.yaml b/src/content/sponsors/pretalx.yaml deleted file mode 100644 index b080d2229..000000000 --- a/src/content/sponsors/pretalx.yaml +++ /dev/null @@ -1,4 +0,0 @@ -name: pretalx -url: https://pretalx.com/p/about/ -image: ./pretalx.svg -tier: Supporters diff --git a/src/content/sponsors/pretalx/display.png b/src/content/sponsors/pretalx/display.png new file mode 100644 index 000000000..4d80552d9 Binary files /dev/null and b/src/content/sponsors/pretalx/display.png differ diff --git a/src/content/sponsors/pretalx/index.md b/src/content/sponsors/pretalx/index.md new file mode 100644 index 000000000..56e15b0ee --- /dev/null +++ b/src/content/sponsors/pretalx/index.md @@ -0,0 +1,25 @@ +--- +name: "Pretalx" +url: "https://pretalx.org" +location: "Germany" +industry: "Open Source Event Management" +description: + "Pretalx is an open-source platform for managing conference submissions and + schedules. Used by PyCon events and others, it prioritizes privacy and + flexibility for organizers and attendees." +socials: + linkedin: + twitter: "https://twitter.com/pretalx" + github: "https://github.com/pretalx/pretalx" + discord: "https://discord.gg/pretalx" + mastodon: + bluesky: +tier: Supporters +draft: true +--- + +## About Pretalx + +Pretalx simplifies event logistics with a free, privacy-focused tool for +call-for-papers, scheduling, and attendee engagement. It powers conferences like +PyCon and Pretix events globally. diff --git a/src/content/sponsors/pretalx.svg b/src/content/sponsors/pretalx/pretalx.svg similarity index 100% rename from src/content/sponsors/pretalx.svg rename to src/content/sponsors/pretalx/pretalx.svg diff --git a/src/content/sponsors/pretix.yaml b/src/content/sponsors/pretix.yaml deleted file mode 100644 index 3c6e23b3f..000000000 --- a/src/content/sponsors/pretix.yaml +++ /dev/null @@ -1,4 +0,0 @@ -name: pretix -url: https://pretix.eu/ -image: ./pretix.svg -tier: Silver diff --git a/src/content/sponsors/pretix/display.png b/src/content/sponsors/pretix/display.png new file mode 100644 index 000000000..1d2ca3cc9 Binary files /dev/null and b/src/content/sponsors/pretix/display.png differ diff --git a/src/content/sponsors/pretix/index.md b/src/content/sponsors/pretix/index.md new file mode 100644 index 000000000..1c46055a5 --- /dev/null +++ b/src/content/sponsors/pretix/index.md @@ -0,0 +1,25 @@ +--- +name: "Pretix" +url: "https://pretix.eu" +location: "Germany" +industry: "Open Source Ticketing" +description: + "Pretix is a free, open-source ticketing system designed for privacy and + scalability. It supports events of all sizes, from small meetups to large + conferences, with customizable features." +socials: + linkedin: + twitter: "https://twitter.com/pretix" + github: "https://github.com/pretix/pretix" + discord: "https://discord.gg/pretix" + mastodon: + bluesky: +tier: Silver +draft: true +--- + +## About Pretix + +Pretix enables event organizers to manage ticket sales and registrations without +vendor lock-in. Its open-source model and focus on data protection make it a +trusted choice for community-driven events. diff --git a/src/content/sponsors/pretix.svg b/src/content/sponsors/pretix/pretix.svg similarity index 100% rename from src/content/sponsors/pretix.svg rename to src/content/sponsors/pretix/pretix.svg diff --git a/src/content/sponsors/pycon-at.yaml b/src/content/sponsors/pycon-at.yaml deleted file mode 100644 index 320abf3a9..000000000 --- a/src/content/sponsors/pycon-at.yaml +++ /dev/null @@ -1,4 +0,0 @@ -name: PyCon Austria -url: https://pycon.pyug.at/en/ -image: ./pycon-at.png -tier: Partners diff --git a/src/content/sponsors/pycon-at/display.png b/src/content/sponsors/pycon-at/display.png new file mode 100644 index 000000000..1125300b2 Binary files /dev/null and b/src/content/sponsors/pycon-at/display.png differ diff --git a/src/content/sponsors/pycon-at/index.md b/src/content/sponsors/pycon-at/index.md new file mode 100644 index 000000000..20ca54a93 --- /dev/null +++ b/src/content/sponsors/pycon-at/index.md @@ -0,0 +1,19 @@ +--- +name: "PyCon Austria" +url: "https://pycon.at" +location: "Austria" +industry: "Technology & Non-Profit" +description: + "PyCon Austria is a volunteer-run conference promoting Python programming in + Central Europe. As part of the global PyCon network, it fosters collaboration + among developers, educators, and businesses." +socials: + linkedin: + twitter: "https://twitter.com/pyconat" + github: + discord: + mastodon: + bluesky: +tier: Partners +logo_padding: 10px 0 +--- diff --git a/src/content/sponsors/pycon-at.png b/src/content/sponsors/pycon-at/pycon-at.png similarity index 100% rename from src/content/sponsors/pycon-at.png rename to src/content/sponsors/pycon-at/pycon-at.png diff --git a/src/content/sponsors/pycon-fr.yaml b/src/content/sponsors/pycon-fr.yaml deleted file mode 100644 index b03df844c..000000000 --- a/src/content/sponsors/pycon-fr.yaml +++ /dev/null @@ -1,4 +0,0 @@ -name: PyCon France -url: https://www.pycon.fr/2025 -image: ./pycon-fr.svg -tier: Partners diff --git a/src/content/sponsors/pycon-fr/display.png b/src/content/sponsors/pycon-fr/display.png new file mode 100644 index 000000000..ee15844f5 Binary files /dev/null and b/src/content/sponsors/pycon-fr/display.png differ diff --git a/src/content/sponsors/pycon-fr/index.md b/src/content/sponsors/pycon-fr/index.md new file mode 100644 index 000000000..d72f2f036 --- /dev/null +++ b/src/content/sponsors/pycon-fr/index.md @@ -0,0 +1,18 @@ +--- +name: "PyCon France" +url: "https://pycon.fr/2025" +location: "France" +industry: "Technology & Non-Profit" +description: + "PyCon France is a community-driven conference celebrating Python in France. + It highlights technical talks, workshops, and networking opportunities for + developers across industries." +socials: + linkedin: + twitter: "https://twitter.com/pyconfr" + github: + discord: + mastodon: + bluesky: +tier: Partners +--- diff --git a/src/content/sponsors/pycon-fr.svg b/src/content/sponsors/pycon-fr/pycon-fr.svg similarity index 100% rename from src/content/sponsors/pycon-fr.svg rename to src/content/sponsors/pycon-fr/pycon-fr.svg diff --git a/src/content/sponsors/pycon-gr.yaml b/src/content/sponsors/pycon-gr.yaml deleted file mode 100644 index 6531d6843..000000000 --- a/src/content/sponsors/pycon-gr.yaml +++ /dev/null @@ -1,4 +0,0 @@ -name: PyCon Greece -url: https://2025.pycon.gr/en -image: ./pycon-gr.svg -tier: Partners diff --git a/src/content/sponsors/pycon-gr/display.png b/src/content/sponsors/pycon-gr/display.png new file mode 100644 index 000000000..c3f00bb70 Binary files /dev/null and b/src/content/sponsors/pycon-gr/display.png differ diff --git a/src/content/sponsors/pycon-gr/index.md b/src/content/sponsors/pycon-gr/index.md new file mode 100644 index 000000000..4d39b498d --- /dev/null +++ b/src/content/sponsors/pycon-gr/index.md @@ -0,0 +1,19 @@ +--- +name: PyCon Greece +url: https://2025.pycon.gr/en +location: "Greece" +industry: "Technology & Non-Profit" +description: + "PyCon Greece connects Python developers, educators, and businesses in + Southeastern Europe. Its annual conference emphasizes inclusivity, education, + and open-source collaboration." +socials: + linkedin: + twitter: "https://twitter.com/pycongr" + github: + discord: + mastodon: + bluesky: +tier: Partners +logo_padding: 10px +--- diff --git a/src/content/sponsors/pycon-gr.svg b/src/content/sponsors/pycon-gr/pycon-gr.svg similarity index 100% rename from src/content/sponsors/pycon-gr.svg rename to src/content/sponsors/pycon-gr/pycon-gr.svg diff --git a/src/content/sponsors/pycon-it.yaml b/src/content/sponsors/pycon-it.yaml deleted file mode 100644 index a8bd6ae67..000000000 --- a/src/content/sponsors/pycon-it.yaml +++ /dev/null @@ -1,4 +0,0 @@ -name: PyCon Italia -url: https://2025.pycon.it/en -image: ./pycon-it.png -tier: Partners diff --git a/src/content/sponsors/pycon-it/display.png b/src/content/sponsors/pycon-it/display.png new file mode 100644 index 000000000..9193bce45 Binary files /dev/null and b/src/content/sponsors/pycon-it/display.png differ diff --git a/src/content/sponsors/pycon-it/index.md b/src/content/sponsors/pycon-it/index.md new file mode 100644 index 000000000..bb41dd948 --- /dev/null +++ b/src/content/sponsors/pycon-it/index.md @@ -0,0 +1,19 @@ +--- +name: PyCon Italia +url: https://2025.pycon.it/en +location: "Italy" +industry: "Technology & Non-Profit" +description: + "PyCon Italy is the largest Italian event for Python developers, featuring + talks, sprints, and networking. It emphasizes diversity and innovation within + the Python community." +socials: + linkedin: + twitter: "https://twitter.com/pyconit" + github: + discord: + mastodon: + bluesky: +tier: Partners +logo_padding: 10px 0 +--- diff --git a/src/content/sponsors/pycon-it.png b/src/content/sponsors/pycon-it/pycon-it.png similarity index 100% rename from src/content/sponsors/pycon-it.png rename to src/content/sponsors/pycon-it/pycon-it.png diff --git a/src/content/sponsors/pycon-pt.yaml b/src/content/sponsors/pycon-pt.yaml deleted file mode 100644 index 992431bc4..000000000 --- a/src/content/sponsors/pycon-pt.yaml +++ /dev/null @@ -1,4 +0,0 @@ -name: PyCon Portugal -url: https://2025.pycon.pt/ -image: ./pycon-pt.svg -tier: Partners diff --git a/src/content/sponsors/pycon-pt/display.png b/src/content/sponsors/pycon-pt/display.png new file mode 100644 index 000000000..016383dc5 Binary files /dev/null and b/src/content/sponsors/pycon-pt/display.png differ diff --git a/src/content/sponsors/pycon-pt/index.md b/src/content/sponsors/pycon-pt/index.md new file mode 100644 index 000000000..65a45a431 --- /dev/null +++ b/src/content/sponsors/pycon-pt/index.md @@ -0,0 +1,18 @@ +--- +name: PyCon Portugal +url: https://2025.pycon.pt/ +location: "Portugal" +industry: "Technology & Non-Profit" +description: + "PyCon Portugal promotes Python programming across Iberia through conferences, + workshops, and open-source advocacy. It highlights practical applications in + tech, science, and education." +socials: + linkedin: + twitter: "https://twitter.com/pyconpt" + github: + discord: + mastodon: + bluesky: +tier: Partners +--- diff --git a/src/content/sponsors/pycon-pt.svg b/src/content/sponsors/pycon-pt/pycon-pt.svg similarity index 100% rename from src/content/sponsors/pycon-pt.svg rename to src/content/sponsors/pycon-pt/pycon-pt.svg diff --git a/src/content/sponsors/pyvec.yaml b/src/content/sponsors/pyvec.yaml deleted file mode 100644 index af297592a..000000000 --- a/src/content/sponsors/pyvec.yaml +++ /dev/null @@ -1,4 +0,0 @@ -name: Pyvec Czech Republic -url: https://pyvec.org/en/ -image: ./pyvec.svg -tier: Partners diff --git a/src/content/sponsors/pyvec/display.png b/src/content/sponsors/pyvec/display.png new file mode 100644 index 000000000..32ceddada Binary files /dev/null and b/src/content/sponsors/pyvec/display.png differ diff --git a/src/content/sponsors/pyvec/index.md b/src/content/sponsors/pyvec/index.md new file mode 100644 index 000000000..2c18c7cb7 --- /dev/null +++ b/src/content/sponsors/pyvec/index.md @@ -0,0 +1,19 @@ +--- +name: Pyvec Czech Republic +url: https://pyvec.org/en/ +location: "Czech Republic" +industry: "Technology & Non-Profit" +description: + "PyVEC is the Czech Python community organization supporting Python + development and education. It organizes PyCon CZ and initiatives to grow + Python adoption in Central Europe." +socials: + linkedin: + twitter: "https://twitter.com/pyvec" + github: + discord: + mastodon: + bluesky: +tier: Partners +logo_padding: 30px 20px +--- diff --git a/src/content/sponsors/pyvec.svg b/src/content/sponsors/pyvec/pyvec.svg similarity index 100% rename from src/content/sponsors/pyvec.svg rename to src/content/sponsors/pyvec/pyvec.svg diff --git a/src/content/sponsors/sentry.yaml b/src/content/sponsors/sentry.yaml deleted file mode 100644 index d009f90dd..000000000 --- a/src/content/sponsors/sentry.yaml +++ /dev/null @@ -1,4 +0,0 @@ -name: Sentry -url: https://sentry.io/welcome -image: ./sentry.svg -tier: Bronze diff --git a/src/content/sponsors/sentry/display.png b/src/content/sponsors/sentry/display.png new file mode 100644 index 000000000..8c73af559 Binary files /dev/null and b/src/content/sponsors/sentry/display.png differ diff --git a/src/content/sponsors/sentry/index.md b/src/content/sponsors/sentry/index.md new file mode 100644 index 000000000..b3203c269 --- /dev/null +++ b/src/content/sponsors/sentry/index.md @@ -0,0 +1,26 @@ +--- +name: Sentry +url: https://sentry.io/welcome +location: "USA" +industry: "Developer Tools & Error Tracking" +description: + "Sentry provides real-time error tracking for developers, helping teams + monitor and fix issues in code. While no 2025 sponsorships appear in current + data, Sentry remains a key tool for application stability." +socials: + linkedin: "https://linkedin.com/company/sentry" + twitter: "https://twitter.com/sentry" + github: "https://github.com/getsentry/sentry" + discord: + mastodon: + bluesky: +tier: Bronze +logo_padding: 20px 0 +draft: true +--- + +## About Sentry + +Sentry’s platform streamlines debugging and performance monitoring for apps +across platforms. Though 2025 partnerships aren’t listed here, its integration +with modern dev workflows ensures ongoing relevance. diff --git a/src/content/sponsors/sentry.svg b/src/content/sponsors/sentry/sentry.svg similarity index 100% rename from src/content/sponsors/sentry.svg rename to src/content/sponsors/sentry/sentry.svg diff --git a/src/content/sponsors/snowflake.yaml b/src/content/sponsors/snowflake.yaml deleted file mode 100644 index c16f3348b..000000000 --- a/src/content/sponsors/snowflake.yaml +++ /dev/null @@ -1,4 +0,0 @@ -name: Snowflake -url: https://snowflake.com/ -image: ./snowflake.svg -tier: Silver diff --git a/src/content/sponsors/snowflake/display.png b/src/content/sponsors/snowflake/display.png new file mode 100644 index 000000000..acdb22a4d Binary files /dev/null and b/src/content/sponsors/snowflake/display.png differ diff --git a/src/content/sponsors/snowflake/index.md b/src/content/sponsors/snowflake/index.md new file mode 100644 index 000000000..172b0c5ab --- /dev/null +++ b/src/content/sponsors/snowflake/index.md @@ -0,0 +1,26 @@ +--- +name: Snowflake +url: https://snowflake.com/ +location: "USA" +industry: "Cloud Data Platforms" +description: + "Snowflake delivers a cloud-based data warehouse for scalable analytics and + AI. While 2025-specific sponsorships aren’t detailed in current data, + Snowflake continues to lead in data infrastructure innovation." +socials: + linkedin: "https://linkedin.com/company/snowflake" + twitter: "https://twitter.com/snowflake" + github: + discord: + mastodon: + bluesky: +tier: Silver +logo_padding: 20px 0 +draft: true +--- + +## About Snowflake + +Snowflake’s data platform enables organizations to store, process, and analyze +massive datasets efficiently. Though no 2025 event ties are listed, its role in +cloud computing remains foundational. diff --git a/src/content/sponsors/snowflake.svg b/src/content/sponsors/snowflake/snowflake.svg similarity index 100% rename from src/content/sponsors/snowflake.svg rename to src/content/sponsors/snowflake/snowflake.svg diff --git a/src/data/links.json b/src/data/links.json index d1db56583..b28b7d932 100644 --- a/src/data/links.json +++ b/src/data/links.json @@ -130,6 +130,10 @@ "path": "/childcare" } ] + }, + { + "name": "Jobs", + "path": "/jobs" } ], "footer": [ diff --git a/src/data/sponsorDisplay.ts b/src/data/sponsorDisplay.ts new file mode 100644 index 000000000..f85ab6ba6 --- /dev/null +++ b/src/data/sponsorDisplay.ts @@ -0,0 +1,14 @@ +const logoImports = import.meta.glob( + "../content/sponsors/*/display.png", + { eager: true } +); + +export const sponsorDisplay: Record = {}; + +for (const path in logoImports) { + const match = path.match(/\/sponsors\/([^/]+)\/display\.png$/); + if (match) { + const sponsorId = match[1]; + sponsorDisplay[sponsorId] = logoImports[path].default; + } +} diff --git a/src/data/sponsorLogos.ts b/src/data/sponsorLogos.ts new file mode 100644 index 000000000..358392ba9 --- /dev/null +++ b/src/data/sponsorLogos.ts @@ -0,0 +1,14 @@ +const logoImports = import.meta.glob( + "../content/sponsors/*/{logo,*}.@(svg|png|webp)", + { eager: true } +); + +export const sponsorLogos: Record = {}; + +for (const path in logoImports) { + const match = path.match(/\/sponsors\/([^/]+)\/(?:\1|logo)\.(svg|png|webp)$/); + if (match) { + const sponsorId = match[1]; + sponsorLogos[sponsorId] = logoImports[path].default; + } +} diff --git a/src/layouts/Layout.astro b/src/layouts/Layout.astro index d47e64031..8aa0dcb8d 100644 --- a/src/layouts/Layout.astro +++ b/src/layouts/Layout.astro @@ -31,7 +31,6 @@ const externalDomain = new URL(Astro.site || "").hostname; -
diff --git a/src/layouts/SectionLayout.astro b/src/layouts/SectionLayout.astro new file mode 100644 index 000000000..1a8d69a47 --- /dev/null +++ b/src/layouts/SectionLayout.astro @@ -0,0 +1,14 @@ +--- +import Layout from "@layouts/Layout.astro"; +import Section from "@ui/Section.astro"; + +import "../styles/markdown.css"; + +const { title, description } = Astro.props; +--- + + +
+ +
+
diff --git a/src/pages/_sponsors2.astro b/src/pages/_sponsors2.astro new file mode 100644 index 000000000..d62014efc --- /dev/null +++ b/src/pages/_sponsors2.astro @@ -0,0 +1,52 @@ +--- +import { type CollectionEntry, getCollection, getEntry } from "astro:content"; +import Layout from "@layouts/SectionLayout.astro"; +import SponsorCard from "@components/SponsorCard.astro"; + +const sponsors = await getCollection("sponsors"); + +const jobFiles = import.meta.glob("../content/sponsors/*/!(index).md"); +const sponsorsJobsMap: Record[]> = {}; + +for (const path in jobFiles) { + const match = path.match(/\.\.\/content\/sponsors\/([^/]+)\/([^/]+)\.md$/); + if (match) { + const sponsorId = match[1]; + const jobId = match[2]; + + const entry = await getEntry("jobs", `${sponsorId}/${jobId}`); + if (entry) { + if (!sponsorsJobsMap[sponsorId]) { + sponsorsJobsMap[sponsorId] = []; + } + sponsorsJobsMap[sponsorId].push(entry); + } else { + console.warn(`Job entry not found for: ${sponsorId}/${jobId}`); + } + } +} + +const sponsorsWithDescription: CollectionEntry<"sponsors">[] = sponsors.filter(c => c.data.description?.trim()); +const sponsorsWithoutDescription: CollectionEntry<"sponsors">[] = sponsors.filter(c => !c.data.description?.trim()); +--- + + +{sponsorsWithDescription.length > 0 && ( +
+ {sponsorsWithDescription.map((sponsor) => ( + + ))} +
+)} + +{sponsorsWithoutDescription.length > 0 && ( +
+ {sponsorsWithoutDescription.map((sponsor) => ( + + ))} +
+)} +
diff --git a/src/pages/test_components.astro b/src/pages/_test_components.astro similarity index 100% rename from src/pages/test_components.astro rename to src/pages/_test_components.astro diff --git a/src/pages/community-partners.astro b/src/pages/community-partners.astro new file mode 100644 index 000000000..5e168b12b --- /dev/null +++ b/src/pages/community-partners.astro @@ -0,0 +1,33 @@ +--- +import { getCollection } from "astro:content"; +import Layout from "@layouts/SectionLayout.astro"; +import SponsorCard from "@components/SponsorCard.astro"; +import Headline from "@ui/Headline.astro"; + +const sponsors = await getCollection("sponsors", ({ data }) => { + const isProd = import.meta.env.MODE === "production"; + const notDraft = !isProd || data.draft !== true; + const isPartner = data.tier === "Partners"; + return notDraft && isPartner; +}); + +--- + + + + + +

+ EuroPython is a community-driven conference, we wouldn't be able to make as much impact without the support of our brilliant Community Partners. Get to know our partners better below (alphabetical order). +

+ {sponsors.length > 0 && ( +
+ {sponsors.map((sponsor) => ( + + ))} +
+ )} +
diff --git a/src/pages/jobs.astro b/src/pages/jobs.astro new file mode 100644 index 000000000..10f8d4933 --- /dev/null +++ b/src/pages/jobs.astro @@ -0,0 +1,76 @@ +--- +import { type CollectionEntry, getEntry, getCollection } from "astro:content"; + +import Layout from "@layouts/SectionLayout.astro"; + +import SponsorCard from "@components/SponsorCard.astro"; +import JobCard from "@components/JobCard.astro"; +import TwoCols from "@components/TwoCols.astro"; + +const sponsors = await getCollection("sponsors", ({ data }) => { + return import.meta.env.MODE === "production" ? data.draft !== true : true; +}); + +const jobs = await getCollection("jobs", ({ data }) => { + return import.meta.env.MODE === "production" ? data.draft !== true : true; +}); + +const jobsMap = Object.fromEntries(jobs.map((job) => [job.id, job])); + +const jobFiles = import.meta.glob("../content/sponsors/*/!(index).md"); +const sponsorsJobsMap: Record[]> = {}; + +for (const path in jobFiles) { + const match = path.match(/\.\.\/content\/sponsors\/([^/]+)\/([^/]+)\.md$/); + if (match) { + const sponsorId = match[1]; + const jobId = match[2]; + + const entry: CollectionEntry<"jobs"> = jobsMap[`${sponsorId}/${jobId}`]; + const sponsor = await getEntry("sponsors", sponsorId); + if (entry && entry.data) { + entry.data.sponsor = sponsor; + if (!sponsorsJobsMap[sponsorId]) { + sponsorsJobsMap[sponsorId] = []; + } + sponsorsJobsMap[sponsorId].push(entry); + } else { + console.warn(`Job entry not found for: ${sponsorId}/${jobId}`); + } + } +} + +sponsors.forEach((sponsor) => { + sponsor.data.jobs = (sponsorsJobsMap[sponsor.id] || []).map((job) => ({ + id: job.id, + collection: "jobs", + })); +}); +--- + + + { + sponsors.map((sponsor) => { + if (!(sponsor.data.jobs && sponsor.data.jobs.length > 0)) return; + return ( + + + + {sponsor.data.jobs && sponsor.data.jobs.length > 0 && ( + <> + {sponsor.data.jobs.map((job) => ( + + ))} + + )} + + + ); + }) + } + diff --git a/src/pages/sponsor/[sponsor]/[job].astro b/src/pages/sponsor/[sponsor]/[job].astro new file mode 100644 index 000000000..67cb031ba --- /dev/null +++ b/src/pages/sponsor/[sponsor]/[job].astro @@ -0,0 +1,53 @@ +--- +import Layout from "@layouts/SectionLayout.astro"; +import JobCard from "@components/JobCard.astro"; +import SponsorCard from "@components/SponsorCard.astro"; +import TwoCols from "@components/TwoCols.astro"; +import { getCollection } from "astro:content"; + + +const { sponsor, job: jobId } = Astro.params; + +const job = `${sponsor}/${jobId}`; + +export async function getStaticPaths() { + + + const jobs = await getCollection("jobs", ({ data }) => { + return import.meta.env.MODE === "production" ? data.draft !== true : true; + }); + const jobIds = new Set(jobs.map((job) => job.id)); + + const jobFiles = import.meta.glob("@src/content/sponsors/*/!(index).md"); + return Object.keys(jobFiles) + .map((path) => { + const match = path.match(/\/sponsors\/([^/]+)\/([^/]+)\.md$/); + if (!match) return null; + + const [, sponsorId, jobId] = match; + + if (!jobIds.has(`${sponsorId}/${jobId}`)) return null; + + return { + params: { sponsor: sponsorId, job: jobId }, + }; + }) + .filter(Boolean); +} + + +--- + + + + + + + + {()} + + + diff --git a/src/pages/sponsor/[sponsor]/index.astro b/src/pages/sponsor/[sponsor]/index.astro new file mode 100644 index 000000000..d9fefdc92 --- /dev/null +++ b/src/pages/sponsor/[sponsor]/index.astro @@ -0,0 +1,39 @@ +--- +import Layout from "@layouts/SectionLayout.astro"; +import SponsorCard from "@components/SponsorCard.astro"; +import CardContent from "@components/CardContent.astro"; +import SponsorDisplay from "@components/SponsorDisplay.astro"; +import TwoCols from "@components/TwoCols.astro"; + +import { getCollection } from "astro:content"; + +const {sponsor } = Astro.params; + +export async function getStaticPaths() { + +const sponsors = await getCollection("sponsors", ({ data }) => { + return import.meta.env.MODE === "production" ? data.draft !== true : true; +}); + + return sponsors.map((sponsor: any) => ({ + params: { + sponsor: sponsor.id, + }, + })); +} +--- + + + + + + + + + + + + diff --git a/src/pages/sponsors.astro b/src/pages/sponsors.astro new file mode 100644 index 000000000..0fc77c656 --- /dev/null +++ b/src/pages/sponsors.astro @@ -0,0 +1,58 @@ +--- +import { type CollectionEntry, getCollection } from "astro:content"; +import Layout from "@layouts/SectionLayout.astro"; +import SponsorLogo from "@components/SponsorLogo.astro"; +import Headline from "@ui/Headline.astro"; + +import { slugify } from "@utils/content"; + +const sponsors = await getCollection("sponsors"); + +const tiers = [ + "Keystone", + "Diamond", + "Platinum", + "Platinum X", + "Gold", + "Silver", + "Bronze", + "Patron", + "Financial Aid", + "Supporters", + "Partners", +] as const; + +// Group sponsors by their tier +const grouped = sponsors.reduce((acc, sponsor) => { + const tier = sponsor.data.tier; + const key = tier ?? 'unknown'; + if (!acc[key]) { + acc[key] = []; + } + acc[key].push(sponsor); + return acc; +}, {} as Record[]>); +--- + + + + + + + {tiers.map((tier) => { + const tiersponsors = grouped[tier]; + return tiersponsors?.length ? ( +
+ +
+ {tiersponsors.map((sponsor) => ( + + ))} +
+
+ ) : null; + })} +
diff --git a/src/styles/global.css b/src/styles/global.css index 96f8e54f5..9ff40d31c 100644 --- a/src/styles/global.css +++ b/src/styles/global.css @@ -118,30 +118,10 @@ summary h4::after { content: "👇"; } -.list-disc li { - list-style: none; - position: relative; -} - -ul.list-disc li::before { - content: ""; - display: inline-block; - width: 25px; - height: 20px; - /*background-image: url(/img/list-item.svg);*/ - background-size: 100%; - background-repeat: no-repeat; - background-position: 50% 50%; - position: absolute; - left: -30px; - top: 0.2em; -} - -ul ul.list-disc li { - list-style: disc; -} -ul ul.list-disc li::before { - display: none; +ul.list-disc li { + list-style: square; + list-style-position: outside; + margin-left: 30px; } p.tick::before { @@ -284,3 +264,9 @@ main a[href^="#"]::before { font-size: 0; visibility: hidden; } + +.draft { + background: url("/draft.png"); + background-size: 65%; + background-color: white; +} diff --git a/tailwind.config.mjs b/tailwind.config.mjs index 6a46ab835..0fc84d063 100644 --- a/tailwind.config.mjs +++ b/tailwind.config.mjs @@ -1,7 +1,7 @@ /** @type {import('tailwindcss').Config} */ + export default { content: ["./src/**/*.{astro,html,js,jsx,md,mdx,svelte,ts,tsx,vue}"], - theme: { colors: { black: "#000", @@ -83,7 +83,7 @@ export default { DEFAULT: { css: { color: theme("colors.text"), - "--tw-prose-headings": theme("colors.white"), + "--tw-prose-headings": theme("colors.black"), }, }, }),