diff --git a/astro.config.mjs b/astro.config.mjs index f34bcb3d..2a37b8bf 100644 --- a/astro.config.mjs +++ b/astro.config.mjs @@ -1,4 +1,4 @@ -import {defineConfig} from 'astro/config'; +import {defineConfig, fontProviders} from 'astro/config'; import {rehypeHeadingIds} from '@astrojs/markdown-remark'; import react from '@astrojs/react'; import tailwind from "@astrojs/tailwind"; @@ -10,6 +10,37 @@ import { rehypeRelativeAssets } from './src/plugins/rehype-relative-assets.mjs'; // https://astro.build/config export default defineConfig({ site: 'https://elixir.no', + // Self-vendored, preloaded web fonts (files live in src/assets/fonts, so the + // build has no network dependency and visitors never hit Google; CLS-safe). + // Body drives UI + MDX prose; display drives headings only. Both are variable + // fonts, so one file per family covers its weight range. + // Fonts API is experimental in Astro 5.x (Astro is pinned to ~5.18 for it). + experimental: { + fonts: [ + { + provider: fontProviders.local(), + name: 'Hanken Grotesk', + cssVariable: '--font-body', + fallbacks: ['ui-sans-serif', 'system-ui', 'sans-serif'], + options: { + variants: [ + { weight: '400 700', style: 'normal', src: ['./src/assets/fonts/hanken-grotesk.woff2'] }, + ], + }, + }, + { + provider: fontProviders.local(), + name: 'Bricolage Grotesque', + cssVariable: '--font-display', + fallbacks: ['ui-sans-serif', 'system-ui', 'sans-serif'], + options: { + variants: [ + { weight: '500 800', style: 'normal', src: ['./src/assets/fonts/bricolage-grotesque.woff2'] }, + ], + }, + }, + ], + }, redirects: { // ── Legacy underscore/mixed-case slugs → year/slug ────────────────────── '/events/2025-06-10_arendalsuka': { destination: '/events/2025/arendalsuka', status: 301 }, diff --git a/package.json b/package.json index 1df259a6..15754da1 100644 --- a/package.json +++ b/package.json @@ -26,8 +26,9 @@ "@astrojs/sitemap": "^3.7.2", "@astrojs/tailwind": "^6.0.2", "@headlessui/react": "^2.2.10", + "@heroicons/react": "^2.2.0", "@tailwindcss/forms": "^0.5.7", - "astro": "^5.18.1", + "astro": "~5.18.1", "dayjs": "^1.11.20", "dompurify": "^3.3.3", "framer-motion": "^12.38.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index c54ce680..dcdbb1a4 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -48,11 +48,14 @@ importers: '@headlessui/react': specifier: ^2.2.10 version: 2.2.10(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@heroicons/react': + specifier: ^2.2.0 + version: 2.2.0(react@18.3.1) '@tailwindcss/forms': specifier: ^0.5.7 version: 0.5.9(tailwindcss@3.4.14) astro: - specifier: ^5.18.1 + specifier: ~5.18.1 version: 5.18.1(@types/node@24.12.2)(jiti@1.21.6)(rollup@4.60.1)(sass@1.99.0)(typescript@5.6.3)(yaml@2.8.3) dayjs: specifier: ^1.11.20 @@ -642,6 +645,11 @@ packages: react: ^18 || ^19 || ^19.0.0-rc react-dom: ^18 || ^19 || ^19.0.0-rc + '@heroicons/react@2.2.0': + resolution: {integrity: sha512-LMcepvRaS9LYHJGsF0zzmgKCUim/X3N/DQKc4jepAXJ7l8QxJ1PmxJzqplF2Z3FE4PqBAIGyJAQ/w4B5dsqbtQ==} + peerDependencies: + react: '>= 16 || ^19.0.0-rc' + '@img/colour@1.1.0': resolution: {integrity: sha512-Td76q7j57o/tLVdgS746cYARfSyxk8iEfRxewL9h4OMzYhbW4TAcppl0mT4eyqXddh6L/jwoM75mo7ixa/pCeQ==} engines: {node: '>=18'} @@ -1817,6 +1825,7 @@ packages: glob@10.4.5: resolution: {integrity: sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==} + deprecated: Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me hasBin: true h3@1.15.9: @@ -2867,6 +2876,7 @@ packages: tsconfck@3.1.6: resolution: {integrity: sha512-ks6Vjr/jEw0P1gmOVwutM3B7fWxoWBL2KRDb1JfqGVawBmO5UsvmWOQFGHBPl5yxYz4eERr19E6L7NMv+Fej4w==} engines: {node: ^18 || >=20} + deprecated: unmaintained hasBin: true peerDependencies: typescript: ^5.0.0 @@ -3812,6 +3822,10 @@ snapshots: react-dom: 18.3.1(react@18.3.1) use-sync-external-store: 1.6.0(react@18.3.1) + '@heroicons/react@2.2.0(react@18.3.1)': + dependencies: + react: 18.3.1 + '@img/colour@1.1.0': optional: true @@ -4578,7 +4592,7 @@ snapshots: smol-toml: 1.6.1 svgo: 4.0.1 tinyexec: 1.0.4 - tinyglobby: 0.2.15 + tinyglobby: 0.2.16 tsconfck: 3.1.6(typescript@5.6.3) ultrahtml: 1.6.0 unifont: 0.7.4 diff --git a/src/assets/fonts/bricolage-grotesque.woff2 b/src/assets/fonts/bricolage-grotesque.woff2 new file mode 100644 index 00000000..86d4f45d Binary files /dev/null and b/src/assets/fonts/bricolage-grotesque.woff2 differ diff --git a/src/assets/fonts/hanken-grotesk.woff2 b/src/assets/fonts/hanken-grotesk.woff2 new file mode 100644 index 00000000..e71775f9 Binary files /dev/null and b/src/assets/fonts/hanken-grotesk.woff2 differ diff --git a/src/components/callout.tsx b/src/components/callout.tsx index 5c8c0939..9bae0199 100644 --- a/src/components/callout.tsx +++ b/src/components/callout.tsx @@ -1,4 +1,10 @@ import React from 'react'; +import { + CheckCircleIcon, + ExclamationTriangleIcon, + InformationCircleIcon, + XCircleIcon, +} from '@heroicons/react/24/outline'; const variants = { info: { @@ -7,9 +13,7 @@ const variants = { title: 'text-blue-900 dark:text-blue-200', text: 'text-blue-800 dark:text-blue-300', icon: ( - +