From 082b1960f6934bb086dd0e29a78ed9fc1b51c314 Mon Sep 17 00:00:00 2001 From: "cloudflare-workers-and-pages[bot]" <73139402+cloudflare-workers-and-pages[bot]@users.noreply.github.com> Date: Wed, 4 Mar 2026 19:33:41 +0000 Subject: [PATCH 01/31] Add Cloudflare Workers configuration --- .gitignore | 6 + astro.config.mjs | 9 +- package-lock.json | 2140 +++++++++++++++++++++++++++++++++++++++++- package.json | 10 +- public/.assetsignore | 2 + wrangler.jsonc | 17 + 6 files changed, 2172 insertions(+), 12 deletions(-) create mode 100644 public/.assetsignore create mode 100644 wrangler.jsonc diff --git a/.gitignore b/.gitignore index 3daa77e..7bc7752 100644 --- a/.gitignore +++ b/.gitignore @@ -31,3 +31,9 @@ artifacts/previews/ artifacts/imagegen/ artifacts/qa-test/*/responsive-v12-pass2/ artifacts/qa-test/*/deploy-sftp-dryrun.txt + +# wrangler files +.wrangler +.dev.vars* +!.dev.vars.example +!.env.example diff --git a/astro.config.mjs b/astro.config.mjs index 2cdf5c2..bbd3401 100644 --- a/astro.config.mjs +++ b/astro.config.mjs @@ -2,12 +2,17 @@ import { defineConfig } from 'astro/config'; import react from '@astrojs/react'; import tailwindcss from '@tailwindcss/vite'; +import cloudflare from '@astrojs/cloudflare'; + const siteUrl = process.env.PUBLIC_SITE_URL || 'https://electron-rare.github.io/'; export default defineConfig({ site: siteUrl, integrations: [react()], + vite: { plugins: [tailwindcss()] - } -}); + }, + + adapter: cloudflare() +}); \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index d165217..65d23a5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,6 +8,7 @@ "name": "electron-rare-studio", "version": "0.1.0", "dependencies": { + "@astrojs/cloudflare": "^12.6.12", "@astrojs/react": "^4.4.1", "@radix-ui/react-slot": "^1.2.3", "astro": "^5.13.8", @@ -27,7 +28,8 @@ "@storybook/react-vite": "^9.1.5", "@tailwindcss/vite": "^4.1.13", "storybook": "^9.1.5", - "typescript": "^5.9.2" + "typescript": "^5.9.2", + "wrangler": "^4.70.0" } }, "node_modules/@adobe/css-tools": { @@ -96,6 +98,1644 @@ "url": "https://paulmillr.com/funding/" } }, + "node_modules/@astrojs/cloudflare": { + "version": "12.6.12", + "resolved": "https://registry.npmjs.org/@astrojs/cloudflare/-/cloudflare-12.6.12.tgz", + "integrity": "sha512-f6iXreyJc02EhokqsoPf7D/s3tebyZ8dBNVOyY2JDY87ujft4RokVS1f+zNwNFyu0wkehC4ALUboU5z590DE4w==", + "license": "MIT", + "dependencies": { + "@astrojs/internal-helpers": "0.7.5", + "@astrojs/underscore-redirects": "1.0.0", + "@cloudflare/workers-types": "^4.20251121.0", + "tinyglobby": "^0.2.15", + "vite": "^6.4.1", + "wrangler": "4.50.0" + }, + "peerDependencies": { + "astro": "^5.7.0" + } + }, + "node_modules/@astrojs/cloudflare/node_modules/@cloudflare/kv-asset-handler": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@cloudflare/kv-asset-handler/-/kv-asset-handler-0.4.0.tgz", + "integrity": "sha512-+tv3z+SPp+gqTIcImN9o0hqE9xyfQjI1XD9pL6NuKjua9B1y7mNYv0S9cP+QEbA4ppVgGZEmKOvHX5G5Ei1CVA==", + "license": "MIT OR Apache-2.0", + "dependencies": { + "mime": "^3.0.0" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@astrojs/cloudflare/node_modules/@cloudflare/unenv-preset": { + "version": "2.7.11", + "resolved": "https://registry.npmjs.org/@cloudflare/unenv-preset/-/unenv-preset-2.7.11.tgz", + "integrity": "sha512-se23f1D4PxKrMKOq+Stz+Yn7AJ9ITHcEecXo2Yjb+UgbUDCEBch1FXQC6hx6uT5fNA3kmX3mfzeZiUmpK1W9IQ==", + "license": "MIT OR Apache-2.0", + "peerDependencies": { + "unenv": "2.0.0-rc.24", + "workerd": "^1.20251106.1" + }, + "peerDependenciesMeta": { + "workerd": { + "optional": true + } + } + }, + "node_modules/@astrojs/cloudflare/node_modules/@cloudflare/workerd-darwin-64": { + "version": "1.20251118.0", + "resolved": "https://registry.npmjs.org/@cloudflare/workerd-darwin-64/-/workerd-darwin-64-1.20251118.0.tgz", + "integrity": "sha512-UmWmYEYS/LkK/4HFKN6xf3Hk8cw70PviR+ftr3hUvs9HYZS92IseZEp16pkL6ZBETrPRpZC7OrzoYF7ky6kHsg==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=16" + } + }, + "node_modules/@astrojs/cloudflare/node_modules/@cloudflare/workerd-darwin-arm64": { + "version": "1.20251118.0", + "resolved": "https://registry.npmjs.org/@cloudflare/workerd-darwin-arm64/-/workerd-darwin-arm64-1.20251118.0.tgz", + "integrity": "sha512-RockU7Qzf4rxNfY1lx3j4rvwutNLjTIX7rr2hogbQ4mzLo8Ea40/oZTzXVxl+on75joLBrt0YpenGW8o/r44QA==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=16" + } + }, + "node_modules/@astrojs/cloudflare/node_modules/@cloudflare/workerd-linux-64": { + "version": "1.20251118.0", + "resolved": "https://registry.npmjs.org/@cloudflare/workerd-linux-64/-/workerd-linux-64-1.20251118.0.tgz", + "integrity": "sha512-aT97GnOAbJDuuOG0zPVhgRk0xFtB1dzBMrxMZ09eubDLoU4djH4BuORaqvxNRMmHgKfa4T6drthckT0NjUvBdw==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=16" + } + }, + "node_modules/@astrojs/cloudflare/node_modules/@cloudflare/workerd-linux-arm64": { + "version": "1.20251118.0", + "resolved": "https://registry.npmjs.org/@cloudflare/workerd-linux-arm64/-/workerd-linux-arm64-1.20251118.0.tgz", + "integrity": "sha512-bXZPJcwlq00MPOXqP7DMWjr+goYj0+Fqyw6zgEC2M3FR1+SWla4yjghnZ4IdpN+H1t7VbUrsi5np2LzMUFs0NA==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=16" + } + }, + "node_modules/@astrojs/cloudflare/node_modules/@cloudflare/workerd-windows-64": { + "version": "1.20251118.0", + "resolved": "https://registry.npmjs.org/@cloudflare/workerd-windows-64/-/workerd-windows-64-1.20251118.0.tgz", + "integrity": "sha512-2LV99AHSlpr8WcCb/BYbU2QsYkXLUL1izN6YKWkN9Eibv80JKX0RtgmD3dfmajE5sNvClavxZejgzVvHD9N9Ag==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=16" + } + }, + "node_modules/@astrojs/cloudflare/node_modules/@esbuild/aix-ppc64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.12.tgz", + "integrity": "sha512-Hhmwd6CInZ3dwpuGTF8fJG6yoWmsToE+vYgD4nytZVxcu1ulHpUQRAB1UJ8+N1Am3Mz4+xOByoQoSZf4D+CpkA==", + "cpu": [ + "ppc64" + ], + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@astrojs/cloudflare/node_modules/@esbuild/android-arm": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.12.tgz", + "integrity": "sha512-VJ+sKvNA/GE7Ccacc9Cha7bpS8nyzVv0jdVgwNDaR4gDMC/2TTRc33Ip8qrNYUcpkOHUT5OZ0bUcNNVZQ9RLlg==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@astrojs/cloudflare/node_modules/@esbuild/android-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.12.tgz", + "integrity": "sha512-6AAmLG7zwD1Z159jCKPvAxZd4y/VTO0VkprYy+3N2FtJ8+BQWFXU+OxARIwA46c5tdD9SsKGZ/1ocqBS/gAKHg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@astrojs/cloudflare/node_modules/@esbuild/android-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.12.tgz", + "integrity": "sha512-5jbb+2hhDHx5phYR2By8GTWEzn6I9UqR11Kwf22iKbNpYrsmRB18aX/9ivc5cabcUiAT/wM+YIZ6SG9QO6a8kg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@astrojs/cloudflare/node_modules/@esbuild/darwin-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.12.tgz", + "integrity": "sha512-N3zl+lxHCifgIlcMUP5016ESkeQjLj/959RxxNYIthIg+CQHInujFuXeWbWMgnTo4cp5XVHqFPmpyu9J65C1Yg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@astrojs/cloudflare/node_modules/@esbuild/darwin-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.12.tgz", + "integrity": "sha512-HQ9ka4Kx21qHXwtlTUVbKJOAnmG1ipXhdWTmNXiPzPfWKpXqASVcWdnf2bnL73wgjNrFXAa3yYvBSd9pzfEIpA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@astrojs/cloudflare/node_modules/@esbuild/freebsd-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.12.tgz", + "integrity": "sha512-gA0Bx759+7Jve03K1S0vkOu5Lg/85dou3EseOGUes8flVOGxbhDDh/iZaoek11Y8mtyKPGF3vP8XhnkDEAmzeg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@astrojs/cloudflare/node_modules/@esbuild/freebsd-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.12.tgz", + "integrity": "sha512-TGbO26Yw2xsHzxtbVFGEXBFH0FRAP7gtcPE7P5yP7wGy7cXK2oO7RyOhL5NLiqTlBh47XhmIUXuGciXEqYFfBQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@astrojs/cloudflare/node_modules/@esbuild/linux-arm": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.12.tgz", + "integrity": "sha512-lPDGyC1JPDou8kGcywY0YILzWlhhnRjdof3UlcoqYmS9El818LLfJJc3PXXgZHrHCAKs/Z2SeZtDJr5MrkxtOw==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@astrojs/cloudflare/node_modules/@esbuild/linux-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.12.tgz", + "integrity": "sha512-8bwX7a8FghIgrupcxb4aUmYDLp8pX06rGh5HqDT7bB+8Rdells6mHvrFHHW2JAOPZUbnjUpKTLg6ECyzvas2AQ==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@astrojs/cloudflare/node_modules/@esbuild/linux-ia32": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.12.tgz", + "integrity": "sha512-0y9KrdVnbMM2/vG8KfU0byhUN+EFCny9+8g202gYqSSVMonbsCfLjUO+rCci7pM0WBEtz+oK/PIwHkzxkyharA==", + "cpu": [ + "ia32" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@astrojs/cloudflare/node_modules/@esbuild/linux-loong64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.12.tgz", + "integrity": "sha512-h///Lr5a9rib/v1GGqXVGzjL4TMvVTv+s1DPoxQdz7l/AYv6LDSxdIwzxkrPW438oUXiDtwM10o9PmwS/6Z0Ng==", + "cpu": [ + "loong64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@astrojs/cloudflare/node_modules/@esbuild/linux-mips64el": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.12.tgz", + "integrity": "sha512-iyRrM1Pzy9GFMDLsXn1iHUm18nhKnNMWscjmp4+hpafcZjrr2WbT//d20xaGljXDBYHqRcl8HnxbX6uaA/eGVw==", + "cpu": [ + "mips64el" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@astrojs/cloudflare/node_modules/@esbuild/linux-ppc64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.12.tgz", + "integrity": "sha512-9meM/lRXxMi5PSUqEXRCtVjEZBGwB7P/D4yT8UG/mwIdze2aV4Vo6U5gD3+RsoHXKkHCfSxZKzmDssVlRj1QQA==", + "cpu": [ + "ppc64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@astrojs/cloudflare/node_modules/@esbuild/linux-riscv64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.12.tgz", + "integrity": "sha512-Zr7KR4hgKUpWAwb1f3o5ygT04MzqVrGEGXGLnj15YQDJErYu/BGg+wmFlIDOdJp0PmB0lLvxFIOXZgFRrdjR0w==", + "cpu": [ + "riscv64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@astrojs/cloudflare/node_modules/@esbuild/linux-s390x": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.12.tgz", + "integrity": "sha512-MsKncOcgTNvdtiISc/jZs/Zf8d0cl/t3gYWX8J9ubBnVOwlk65UIEEvgBORTiljloIWnBzLs4qhzPkJcitIzIg==", + "cpu": [ + "s390x" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@astrojs/cloudflare/node_modules/@esbuild/linux-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.12.tgz", + "integrity": "sha512-uqZMTLr/zR/ed4jIGnwSLkaHmPjOjJvnm6TVVitAa08SLS9Z0VM8wIRx7gWbJB5/J54YuIMInDquWyYvQLZkgw==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@astrojs/cloudflare/node_modules/@esbuild/netbsd-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.12.tgz", + "integrity": "sha512-xXwcTq4GhRM7J9A8Gv5boanHhRa/Q9KLVmcyXHCTaM4wKfIpWkdXiMog/KsnxzJ0A1+nD+zoecuzqPmCRyBGjg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@astrojs/cloudflare/node_modules/@esbuild/netbsd-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.12.tgz", + "integrity": "sha512-Ld5pTlzPy3YwGec4OuHh1aCVCRvOXdH8DgRjfDy/oumVovmuSzWfnSJg+VtakB9Cm0gxNO9BzWkj6mtO1FMXkQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@astrojs/cloudflare/node_modules/@esbuild/openbsd-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.12.tgz", + "integrity": "sha512-fF96T6KsBo/pkQI950FARU9apGNTSlZGsv1jZBAlcLL1MLjLNIWPBkj5NlSz8aAzYKg+eNqknrUJ24QBybeR5A==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@astrojs/cloudflare/node_modules/@esbuild/openbsd-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.12.tgz", + "integrity": "sha512-MZyXUkZHjQxUvzK7rN8DJ3SRmrVrke8ZyRusHlP+kuwqTcfWLyqMOE3sScPPyeIXN/mDJIfGXvcMqCgYKekoQw==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@astrojs/cloudflare/node_modules/@esbuild/openharmony-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.25.12.tgz", + "integrity": "sha512-rm0YWsqUSRrjncSXGA7Zv78Nbnw4XL6/dzr20cyrQf7ZmRcsovpcRBdhD43Nuk3y7XIoW2OxMVvwuRvk9XdASg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@astrojs/cloudflare/node_modules/@esbuild/sunos-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.12.tgz", + "integrity": "sha512-3wGSCDyuTHQUzt0nV7bocDy72r2lI33QL3gkDNGkod22EsYl04sMf0qLb8luNKTOmgF/eDEDP5BFNwoBKH441w==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@astrojs/cloudflare/node_modules/@esbuild/win32-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.12.tgz", + "integrity": "sha512-rMmLrur64A7+DKlnSuwqUdRKyd3UE7oPJZmnljqEptesKM8wx9J8gx5u0+9Pq0fQQW8vqeKebwNXdfOyP+8Bsg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@astrojs/cloudflare/node_modules/@esbuild/win32-ia32": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.12.tgz", + "integrity": "sha512-HkqnmmBoCbCwxUKKNPBixiWDGCpQGVsrQfJoVGYLPT41XWF8lHuE5N6WhVia2n4o5QK5M4tYr21827fNhi4byQ==", + "cpu": [ + "ia32" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@astrojs/cloudflare/node_modules/@esbuild/win32-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.12.tgz", + "integrity": "sha512-alJC0uCZpTFrSL0CCDjcgleBXPnCrEAhTBILpeAp7M/OFgoqtAetfBzX0xM00MUsVVPpVjlPuMbREqnZCXaTnA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@astrojs/cloudflare/node_modules/@img/sharp-darwin-arm64": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.33.5.tgz", + "integrity": "sha512-UT4p+iz/2H4twwAoLCqfA9UH5pI6DggwKEGuaPy7nCVQ8ZsiY5PIcrRvD1DzuY3qYL07NtIQcWnBSY/heikIFQ==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-darwin-arm64": "1.0.4" + } + }, + "node_modules/@astrojs/cloudflare/node_modules/@img/sharp-darwin-x64": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.33.5.tgz", + "integrity": "sha512-fyHac4jIc1ANYGRDxtiqelIbdWkIuQaI84Mv45KvGRRxSAa7o7d1ZKAOBaYbnepLC1WqxfpimdeWfvqqSGwR2Q==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-darwin-x64": "1.0.4" + } + }, + "node_modules/@astrojs/cloudflare/node_modules/@img/sharp-libvips-darwin-arm64": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.0.4.tgz", + "integrity": "sha512-XblONe153h0O2zuFfTAbQYAX2JhYmDHeWikp1LM9Hul9gVPjFY427k6dFEcOL72O01QxQsWi761svJ/ev9xEDg==", + "cpu": [ + "arm64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "darwin" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@astrojs/cloudflare/node_modules/@img/sharp-libvips-darwin-x64": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.0.4.tgz", + "integrity": "sha512-xnGR8YuZYfJGmWPvmlunFaWJsb9T/AO2ykoP3Fz/0X5XV2aoYBPkX6xqCQvUTKKiLddarLaxpzNe+b1hjeWHAQ==", + "cpu": [ + "x64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "darwin" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@astrojs/cloudflare/node_modules/@img/sharp-libvips-linux-arm": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.0.5.tgz", + "integrity": "sha512-gvcC4ACAOPRNATg/ov8/MnbxFDJqf/pDePbBnuBDcjsI8PssmjoKMAz4LtLaVi+OnSb5FK/yIOamqDwGmXW32g==", + "cpu": [ + "arm" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@astrojs/cloudflare/node_modules/@img/sharp-libvips-linux-arm64": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.0.4.tgz", + "integrity": "sha512-9B+taZ8DlyyqzZQnoeIvDVR/2F4EbMepXMc/NdVbkzsJbzkUjhXv/70GQJ7tdLA4YJgNP25zukcxpX2/SueNrA==", + "cpu": [ + "arm64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@astrojs/cloudflare/node_modules/@img/sharp-libvips-linux-s390x": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-s390x/-/sharp-libvips-linux-s390x-1.0.4.tgz", + "integrity": "sha512-u7Wz6ntiSSgGSGcjZ55im6uvTrOxSIS8/dgoVMoiGE9I6JAfU50yH5BoDlYA1tcuGS7g/QNtetJnxA6QEsCVTA==", + "cpu": [ + "s390x" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@astrojs/cloudflare/node_modules/@img/sharp-libvips-linux-x64": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.0.4.tgz", + "integrity": "sha512-MmWmQ3iPFZr0Iev+BAgVMb3ZyC4KeFc3jFxnNbEPas60e1cIfevbtuyf9nDGIzOaW9PdnDciJm+wFFaTlj5xYw==", + "cpu": [ + "x64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@astrojs/cloudflare/node_modules/@img/sharp-libvips-linuxmusl-arm64": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-arm64/-/sharp-libvips-linuxmusl-arm64-1.0.4.tgz", + "integrity": "sha512-9Ti+BbTYDcsbp4wfYib8Ctm1ilkugkA/uscUn6UXK1ldpC1JjiXbLfFZtRlBhjPZ5o1NCLiDbg8fhUPKStHoTA==", + "cpu": [ + "arm64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@astrojs/cloudflare/node_modules/@img/sharp-libvips-linuxmusl-x64": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.0.4.tgz", + "integrity": "sha512-viYN1KX9m+/hGkJtvYYp+CCLgnJXwiQB39damAO7WMdKWlIhmYTfHjwSbQeUK/20vY154mwezd9HflVFM1wVSw==", + "cpu": [ + "x64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@astrojs/cloudflare/node_modules/@img/sharp-linux-arm": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm/-/sharp-linux-arm-0.33.5.tgz", + "integrity": "sha512-JTS1eldqZbJxjvKaAkxhZmBqPRGmxgu+qFKSInv8moZ2AmT5Yib3EQ1c6gp493HvrvV8QgdOXdyaIBrhvFhBMQ==", + "cpu": [ + "arm" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-arm": "1.0.5" + } + }, + "node_modules/@astrojs/cloudflare/node_modules/@img/sharp-linux-arm64": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.33.5.tgz", + "integrity": "sha512-JMVv+AMRyGOHtO1RFBiJy/MBsgz0x4AWrT6QoEVVTyh1E39TrCUpTRI7mx9VksGX4awWASxqCYLCV4wBZHAYxA==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-arm64": "1.0.4" + } + }, + "node_modules/@astrojs/cloudflare/node_modules/@img/sharp-linux-s390x": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-s390x/-/sharp-linux-s390x-0.33.5.tgz", + "integrity": "sha512-y/5PCd+mP4CA/sPDKl2961b+C9d+vPAveS33s6Z3zfASk2j5upL6fXVPZi7ztePZ5CuH+1kW8JtvxgbuXHRa4Q==", + "cpu": [ + "s390x" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-s390x": "1.0.4" + } + }, + "node_modules/@astrojs/cloudflare/node_modules/@img/sharp-linux-x64": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-x64/-/sharp-linux-x64-0.33.5.tgz", + "integrity": "sha512-opC+Ok5pRNAzuvq1AG0ar+1owsu842/Ab+4qvU879ippJBHvyY5n2mxF1izXqkPYlGuP/M556uh53jRLJmzTWA==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-x64": "1.0.4" + } + }, + "node_modules/@astrojs/cloudflare/node_modules/@img/sharp-linuxmusl-arm64": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.33.5.tgz", + "integrity": "sha512-XrHMZwGQGvJg2V/oRSUfSAfjfPxO+4DkiRh6p2AFjLQztWUuY/o8Mq0eMQVIY7HJ1CDQUJlxGGZRw1a5bqmd1g==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linuxmusl-arm64": "1.0.4" + } + }, + "node_modules/@astrojs/cloudflare/node_modules/@img/sharp-linuxmusl-x64": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.33.5.tgz", + "integrity": "sha512-WT+d/cgqKkkKySYmqoZ8y3pxx7lx9vVejxW/W4DOFMYVSkErR+w7mf2u8m/y4+xHe7yY9DAXQMWQhpnMuFfScw==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linuxmusl-x64": "1.0.4" + } + }, + "node_modules/@astrojs/cloudflare/node_modules/@img/sharp-wasm32": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-wasm32/-/sharp-wasm32-0.33.5.tgz", + "integrity": "sha512-ykUW4LVGaMcU9lu9thv85CbRMAwfeadCJHRsg2GmeRa/cJxsVY9Rbd57JcMxBkKHag5U/x7TSBpScF4U8ElVzg==", + "cpu": [ + "wasm32" + ], + "license": "Apache-2.0 AND LGPL-3.0-or-later AND MIT", + "optional": true, + "dependencies": { + "@emnapi/runtime": "^1.2.0" + }, + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@astrojs/cloudflare/node_modules/@img/sharp-win32-ia32": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-ia32/-/sharp-win32-ia32-0.33.5.tgz", + "integrity": "sha512-T36PblLaTwuVJ/zw/LaH0PdZkRz5rd3SmMHX8GSmR7vtNSP5Z6bQkExdSK7xGWyxLw4sUknBuugTelgw2faBbQ==", + "cpu": [ + "ia32" + ], + "license": "Apache-2.0 AND LGPL-3.0-or-later", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@astrojs/cloudflare/node_modules/@img/sharp-win32-x64": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-x64/-/sharp-win32-x64-0.33.5.tgz", + "integrity": "sha512-MpY/o8/8kj+EcnxwvrP4aTJSWw/aZ7JIGR4aBeZkZw5B7/Jn+tY9/VNwtcoGmdT7GfggGIU4kygOMSbYnOrAbg==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0 AND LGPL-3.0-or-later", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@astrojs/cloudflare/node_modules/acorn": { + "version": "8.14.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz", + "integrity": "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==", + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/@astrojs/cloudflare/node_modules/esbuild": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.12.tgz", + "integrity": "sha512-bbPBYYrtZbkt6Os6FiTLCTFxvq4tt3JKall1vRwshA3fdVztsLAatFaZobhkBC8/BrPetoa0oksYoKXoG4ryJg==", + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.25.12", + "@esbuild/android-arm": "0.25.12", + "@esbuild/android-arm64": "0.25.12", + "@esbuild/android-x64": "0.25.12", + "@esbuild/darwin-arm64": "0.25.12", + "@esbuild/darwin-x64": "0.25.12", + "@esbuild/freebsd-arm64": "0.25.12", + "@esbuild/freebsd-x64": "0.25.12", + "@esbuild/linux-arm": "0.25.12", + "@esbuild/linux-arm64": "0.25.12", + "@esbuild/linux-ia32": "0.25.12", + "@esbuild/linux-loong64": "0.25.12", + "@esbuild/linux-mips64el": "0.25.12", + "@esbuild/linux-ppc64": "0.25.12", + "@esbuild/linux-riscv64": "0.25.12", + "@esbuild/linux-s390x": "0.25.12", + "@esbuild/linux-x64": "0.25.12", + "@esbuild/netbsd-arm64": "0.25.12", + "@esbuild/netbsd-x64": "0.25.12", + "@esbuild/openbsd-arm64": "0.25.12", + "@esbuild/openbsd-x64": "0.25.12", + "@esbuild/openharmony-arm64": "0.25.12", + "@esbuild/sunos-x64": "0.25.12", + "@esbuild/win32-arm64": "0.25.12", + "@esbuild/win32-ia32": "0.25.12", + "@esbuild/win32-x64": "0.25.12" + } + }, + "node_modules/@astrojs/cloudflare/node_modules/miniflare": { + "version": "4.20251118.1", + "resolved": "https://registry.npmjs.org/miniflare/-/miniflare-4.20251118.1.tgz", + "integrity": "sha512-uLSAE/DvOm392fiaig4LOaatxLjM7xzIniFRG5Y3yF9IduOYLLK/pkCPQNCgKQH3ou0YJRHnTN+09LPfqYNTQQ==", + "license": "MIT", + "dependencies": { + "@cspotcode/source-map-support": "0.8.1", + "acorn": "8.14.0", + "acorn-walk": "8.3.2", + "exit-hook": "2.2.1", + "glob-to-regexp": "0.4.1", + "sharp": "^0.33.5", + "stoppable": "1.1.0", + "undici": "7.14.0", + "workerd": "1.20251118.0", + "ws": "8.18.0", + "youch": "4.1.0-beta.10", + "zod": "3.22.3" + }, + "bin": { + "miniflare": "bootstrap.js" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@astrojs/cloudflare/node_modules/semver": { + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", + "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@astrojs/cloudflare/node_modules/sharp": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.33.5.tgz", + "integrity": "sha512-haPVm1EkS9pgvHrQ/F3Xy+hgcuMV0Wm9vfIBSiwZ05k+xgb0PkBQpGsAA/oWdDobNaZTH5ppvHtzCFbnSEwHVw==", + "hasInstallScript": true, + "license": "Apache-2.0", + "dependencies": { + "color": "^4.2.3", + "detect-libc": "^2.0.3", + "semver": "^7.6.3" + }, + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-darwin-arm64": "0.33.5", + "@img/sharp-darwin-x64": "0.33.5", + "@img/sharp-libvips-darwin-arm64": "1.0.4", + "@img/sharp-libvips-darwin-x64": "1.0.4", + "@img/sharp-libvips-linux-arm": "1.0.5", + "@img/sharp-libvips-linux-arm64": "1.0.4", + "@img/sharp-libvips-linux-s390x": "1.0.4", + "@img/sharp-libvips-linux-x64": "1.0.4", + "@img/sharp-libvips-linuxmusl-arm64": "1.0.4", + "@img/sharp-libvips-linuxmusl-x64": "1.0.4", + "@img/sharp-linux-arm": "0.33.5", + "@img/sharp-linux-arm64": "0.33.5", + "@img/sharp-linux-s390x": "0.33.5", + "@img/sharp-linux-x64": "0.33.5", + "@img/sharp-linuxmusl-arm64": "0.33.5", + "@img/sharp-linuxmusl-x64": "0.33.5", + "@img/sharp-wasm32": "0.33.5", + "@img/sharp-win32-ia32": "0.33.5", + "@img/sharp-win32-x64": "0.33.5" + } + }, + "node_modules/@astrojs/cloudflare/node_modules/undici": { + "version": "7.14.0", + "resolved": "https://registry.npmjs.org/undici/-/undici-7.14.0.tgz", + "integrity": "sha512-Vqs8HTzjpQXZeXdpsfChQTlafcMQaaIwnGwLam1wudSSjlJeQ3bw1j+TLPePgrCnCpUXx7Ba5Pdpf5OBih62NQ==", + "license": "MIT", + "engines": { + "node": ">=20.18.1" + } + }, + "node_modules/@astrojs/cloudflare/node_modules/vite": { + "version": "6.4.1", + "resolved": "https://registry.npmjs.org/vite/-/vite-6.4.1.tgz", + "integrity": "sha512-+Oxm7q9hDoLMyJOYfUYBuHQo+dkAloi33apOPP56pzj+vsdJDzr+j1NISE5pyaAuKL4A3UD34qd0lx5+kfKp2g==", + "license": "MIT", + "dependencies": { + "esbuild": "^0.25.0", + "fdir": "^6.4.4", + "picomatch": "^4.0.2", + "postcss": "^8.5.3", + "rollup": "^4.34.9", + "tinyglobby": "^0.2.13" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^18.0.0 || ^20.0.0 || >=22.0.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "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 + } + } + }, + "node_modules/@astrojs/cloudflare/node_modules/workerd": { + "version": "1.20251118.0", + "resolved": "https://registry.npmjs.org/workerd/-/workerd-1.20251118.0.tgz", + "integrity": "sha512-Om5ns0Lyx/LKtYI04IV0bjIrkBgoFNg0p6urzr2asekJlfP18RqFzyqMFZKf0i9Gnjtz/JfAS/Ol6tjCe5JJsQ==", + "hasInstallScript": true, + "license": "Apache-2.0", + "bin": { + "workerd": "bin/workerd" + }, + "engines": { + "node": ">=16" + }, + "optionalDependencies": { + "@cloudflare/workerd-darwin-64": "1.20251118.0", + "@cloudflare/workerd-darwin-arm64": "1.20251118.0", + "@cloudflare/workerd-linux-64": "1.20251118.0", + "@cloudflare/workerd-linux-arm64": "1.20251118.0", + "@cloudflare/workerd-windows-64": "1.20251118.0" + } + }, + "node_modules/@astrojs/cloudflare/node_modules/wrangler": { + "version": "4.50.0", + "resolved": "https://registry.npmjs.org/wrangler/-/wrangler-4.50.0.tgz", + "integrity": "sha512-+nuZuHZxDdKmAyXOSrHlciGshCoAPiy5dM+t6mEohWm7HpXvTHmWQGUf/na9jjWlWJHCJYOWzkA1P5HBJqrIEA==", + "license": "MIT OR Apache-2.0", + "dependencies": { + "@cloudflare/kv-asset-handler": "0.4.0", + "@cloudflare/unenv-preset": "2.7.11", + "blake3-wasm": "2.1.5", + "esbuild": "0.25.4", + "miniflare": "4.20251118.1", + "path-to-regexp": "6.3.0", + "unenv": "2.0.0-rc.24", + "workerd": "1.20251118.0" + }, + "bin": { + "wrangler": "bin/wrangler.js", + "wrangler2": "bin/wrangler.js" + }, + "engines": { + "node": ">=20.0.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + }, + "peerDependencies": { + "@cloudflare/workers-types": "^4.20251118.0" + }, + "peerDependenciesMeta": { + "@cloudflare/workers-types": { + "optional": true + } + } + }, + "node_modules/@astrojs/cloudflare/node_modules/wrangler/node_modules/@esbuild/aix-ppc64": { + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.4.tgz", + "integrity": "sha512-1VCICWypeQKhVbE9oW/sJaAmjLxhVqacdkvPLEjwlttjfwENRSClS8EjBz0KzRyFSCPDIkuXW34Je/vk7zdB7Q==", + "cpu": [ + "ppc64" + ], + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@astrojs/cloudflare/node_modules/wrangler/node_modules/@esbuild/android-arm": { + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.4.tgz", + "integrity": "sha512-QNdQEps7DfFwE3hXiU4BZeOV68HHzYwGd0Nthhd3uCkkEKK7/R6MTgM0P7H7FAs5pU/DIWsviMmEGxEoxIZ+ZQ==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@astrojs/cloudflare/node_modules/wrangler/node_modules/@esbuild/android-arm64": { + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.4.tgz", + "integrity": "sha512-bBy69pgfhMGtCnwpC/x5QhfxAz/cBgQ9enbtwjf6V9lnPI/hMyT9iWpR1arm0l3kttTr4L0KSLpKmLp/ilKS9A==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@astrojs/cloudflare/node_modules/wrangler/node_modules/@esbuild/android-x64": { + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.4.tgz", + "integrity": "sha512-TVhdVtQIFuVpIIR282btcGC2oGQoSfZfmBdTip2anCaVYcqWlZXGcdcKIUklfX2wj0JklNYgz39OBqh2cqXvcQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@astrojs/cloudflare/node_modules/wrangler/node_modules/@esbuild/darwin-arm64": { + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.4.tgz", + "integrity": "sha512-Y1giCfM4nlHDWEfSckMzeWNdQS31BQGs9/rouw6Ub91tkK79aIMTH3q9xHvzH8d0wDru5Ci0kWB8b3up/nl16g==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@astrojs/cloudflare/node_modules/wrangler/node_modules/@esbuild/darwin-x64": { + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.4.tgz", + "integrity": "sha512-CJsry8ZGM5VFVeyUYB3cdKpd/H69PYez4eJh1W/t38vzutdjEjtP7hB6eLKBoOdxcAlCtEYHzQ/PJ/oU9I4u0A==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@astrojs/cloudflare/node_modules/wrangler/node_modules/@esbuild/freebsd-arm64": { + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.4.tgz", + "integrity": "sha512-yYq+39NlTRzU2XmoPW4l5Ifpl9fqSk0nAJYM/V/WUGPEFfek1epLHJIkTQM6bBs1swApjO5nWgvr843g6TjxuQ==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@astrojs/cloudflare/node_modules/wrangler/node_modules/@esbuild/freebsd-x64": { + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.4.tgz", + "integrity": "sha512-0FgvOJ6UUMflsHSPLzdfDnnBBVoCDtBTVyn/MrWloUNvq/5SFmh13l3dvgRPkDihRxb77Y17MbqbCAa2strMQQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@astrojs/cloudflare/node_modules/wrangler/node_modules/@esbuild/linux-arm": { + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.4.tgz", + "integrity": "sha512-kro4c0P85GMfFYqW4TWOpvmF8rFShbWGnrLqlzp4X1TNWjRY3JMYUfDCtOxPKOIY8B0WC8HN51hGP4I4hz4AaQ==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@astrojs/cloudflare/node_modules/wrangler/node_modules/@esbuild/linux-arm64": { + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.4.tgz", + "integrity": "sha512-+89UsQTfXdmjIvZS6nUnOOLoXnkUTB9hR5QAeLrQdzOSWZvNSAXAtcRDHWtqAUtAmv7ZM1WPOOeSxDzzzMogiQ==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@astrojs/cloudflare/node_modules/wrangler/node_modules/@esbuild/linux-ia32": { + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.4.tgz", + "integrity": "sha512-yTEjoapy8UP3rv8dB0ip3AfMpRbyhSN3+hY8mo/i4QXFeDxmiYbEKp3ZRjBKcOP862Ua4b1PDfwlvbuwY7hIGQ==", + "cpu": [ + "ia32" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@astrojs/cloudflare/node_modules/wrangler/node_modules/@esbuild/linux-loong64": { + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.4.tgz", + "integrity": "sha512-NeqqYkrcGzFwi6CGRGNMOjWGGSYOpqwCjS9fvaUlX5s3zwOtn1qwg1s2iE2svBe4Q/YOG1q6875lcAoQK/F4VA==", + "cpu": [ + "loong64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@astrojs/cloudflare/node_modules/wrangler/node_modules/@esbuild/linux-mips64el": { + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.4.tgz", + "integrity": "sha512-IcvTlF9dtLrfL/M8WgNI/qJYBENP3ekgsHbYUIzEzq5XJzzVEV/fXY9WFPfEEXmu3ck2qJP8LG/p3Q8f7Zc2Xg==", + "cpu": [ + "mips64el" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@astrojs/cloudflare/node_modules/wrangler/node_modules/@esbuild/linux-ppc64": { + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.4.tgz", + "integrity": "sha512-HOy0aLTJTVtoTeGZh4HSXaO6M95qu4k5lJcH4gxv56iaycfz1S8GO/5Jh6X4Y1YiI0h7cRyLi+HixMR+88swag==", + "cpu": [ + "ppc64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@astrojs/cloudflare/node_modules/wrangler/node_modules/@esbuild/linux-riscv64": { + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.4.tgz", + "integrity": "sha512-i8JUDAufpz9jOzo4yIShCTcXzS07vEgWzyX3NH2G7LEFVgrLEhjwL3ajFE4fZI3I4ZgiM7JH3GQ7ReObROvSUA==", + "cpu": [ + "riscv64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@astrojs/cloudflare/node_modules/wrangler/node_modules/@esbuild/linux-s390x": { + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.4.tgz", + "integrity": "sha512-jFnu+6UbLlzIjPQpWCNh5QtrcNfMLjgIavnwPQAfoGx4q17ocOU9MsQ2QVvFxwQoWpZT8DvTLooTvmOQXkO51g==", + "cpu": [ + "s390x" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@astrojs/cloudflare/node_modules/wrangler/node_modules/@esbuild/linux-x64": { + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.4.tgz", + "integrity": "sha512-6e0cvXwzOnVWJHq+mskP8DNSrKBr1bULBvnFLpc1KY+d+irZSgZ02TGse5FsafKS5jg2e4pbvK6TPXaF/A6+CA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@astrojs/cloudflare/node_modules/wrangler/node_modules/@esbuild/netbsd-arm64": { + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.4.tgz", + "integrity": "sha512-vUnkBYxZW4hL/ie91hSqaSNjulOnYXE1VSLusnvHg2u3jewJBz3YzB9+oCw8DABeVqZGg94t9tyZFoHma8gWZQ==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@astrojs/cloudflare/node_modules/wrangler/node_modules/@esbuild/netbsd-x64": { + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.4.tgz", + "integrity": "sha512-XAg8pIQn5CzhOB8odIcAm42QsOfa98SBeKUdo4xa8OvX8LbMZqEtgeWE9P/Wxt7MlG2QqvjGths+nq48TrUiKw==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@astrojs/cloudflare/node_modules/wrangler/node_modules/@esbuild/openbsd-arm64": { + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.4.tgz", + "integrity": "sha512-Ct2WcFEANlFDtp1nVAXSNBPDxyU+j7+tId//iHXU2f/lN5AmO4zLyhDcpR5Cz1r08mVxzt3Jpyt4PmXQ1O6+7A==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@astrojs/cloudflare/node_modules/wrangler/node_modules/@esbuild/openbsd-x64": { + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.4.tgz", + "integrity": "sha512-xAGGhyOQ9Otm1Xu8NT1ifGLnA6M3sJxZ6ixylb+vIUVzvvd6GOALpwQrYrtlPouMqd/vSbgehz6HaVk4+7Afhw==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@astrojs/cloudflare/node_modules/wrangler/node_modules/@esbuild/sunos-x64": { + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.4.tgz", + "integrity": "sha512-Mw+tzy4pp6wZEK0+Lwr76pWLjrtjmJyUB23tHKqEDP74R3q95luY/bXqXZeYl4NYlvwOqoRKlInQialgCKy67Q==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@astrojs/cloudflare/node_modules/wrangler/node_modules/@esbuild/win32-arm64": { + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.4.tgz", + "integrity": "sha512-AVUP428VQTSddguz9dO9ngb+E5aScyg7nOeJDrF1HPYu555gmza3bDGMPhmVXL8svDSoqPCsCPjb265yG/kLKQ==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@astrojs/cloudflare/node_modules/wrangler/node_modules/@esbuild/win32-ia32": { + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.4.tgz", + "integrity": "sha512-i1sW+1i+oWvQzSgfRcxxG2k4I9n3O9NRqy8U+uugaT2Dy7kLO9Y7wI72haOahxceMX8hZAzgGou1FhndRldxRg==", + "cpu": [ + "ia32" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@astrojs/cloudflare/node_modules/wrangler/node_modules/@esbuild/win32-x64": { + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.4.tgz", + "integrity": "sha512-nOT2vZNw6hJ+z43oP1SPea/G/6AbN6X+bGNhNuq8NtRHy4wsMhw765IKLNmnjek7GvjWBYQ8Q5VBoYTFg9y1UQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@astrojs/cloudflare/node_modules/wrangler/node_modules/esbuild": { + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.4.tgz", + "integrity": "sha512-8pgjLUcUjcgDg+2Q4NYXnPbo/vncAY4UmyaCm0jZevERqCHZIaWwdJHkf8XQtu4AxSKCdvrUbT0XUr1IdZzI8Q==", + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.25.4", + "@esbuild/android-arm": "0.25.4", + "@esbuild/android-arm64": "0.25.4", + "@esbuild/android-x64": "0.25.4", + "@esbuild/darwin-arm64": "0.25.4", + "@esbuild/darwin-x64": "0.25.4", + "@esbuild/freebsd-arm64": "0.25.4", + "@esbuild/freebsd-x64": "0.25.4", + "@esbuild/linux-arm": "0.25.4", + "@esbuild/linux-arm64": "0.25.4", + "@esbuild/linux-ia32": "0.25.4", + "@esbuild/linux-loong64": "0.25.4", + "@esbuild/linux-mips64el": "0.25.4", + "@esbuild/linux-ppc64": "0.25.4", + "@esbuild/linux-riscv64": "0.25.4", + "@esbuild/linux-s390x": "0.25.4", + "@esbuild/linux-x64": "0.25.4", + "@esbuild/netbsd-arm64": "0.25.4", + "@esbuild/netbsd-x64": "0.25.4", + "@esbuild/openbsd-arm64": "0.25.4", + "@esbuild/openbsd-x64": "0.25.4", + "@esbuild/sunos-x64": "0.25.4", + "@esbuild/win32-arm64": "0.25.4", + "@esbuild/win32-ia32": "0.25.4", + "@esbuild/win32-x64": "0.25.4" + } + }, + "node_modules/@astrojs/cloudflare/node_modules/ws": { + "version": "8.18.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz", + "integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==", + "license": "MIT", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/@astrojs/cloudflare/node_modules/zod": { + "version": "3.22.3", + "resolved": "https://registry.npmjs.org/zod/-/zod-3.22.3.tgz", + "integrity": "sha512-EjIevzuJRiRPbVH4mGc8nApb/lVLKVpmUhAaR5R5doKGfAnGJ6Gr3CViAVjP+4FWSxCsybeWQdcgCtbX+7oZug==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } + }, "node_modules/@astrojs/compiler": { "version": "2.13.1", "resolved": "https://registry.npmjs.org/@astrojs/compiler/-/compiler-2.13.1.tgz", @@ -760,6 +2400,12 @@ "node": "18.20.8 || ^20.3.0 || >=22.0.0" } }, + "node_modules/@astrojs/underscore-redirects": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@astrojs/underscore-redirects/-/underscore-redirects-1.0.0.tgz", + "integrity": "sha512-qZxHwVnmb5FXuvRsaIGaqWgnftjCuMY+GSbaVZdBmE4j8AfgPqKPxYp8SUERyJcjpKCEmO4wD6ybuGH8A2kVRQ==", + "license": "MIT" + }, "node_modules/@astrojs/yaml2ts": { "version": "0.2.2", "resolved": "https://registry.npmjs.org/@astrojs/yaml2ts/-/yaml2ts-0.2.2.tgz", @@ -1056,6 +2702,145 @@ "node": ">=18" } }, + "node_modules/@cloudflare/kv-asset-handler": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/@cloudflare/kv-asset-handler/-/kv-asset-handler-0.4.2.tgz", + "integrity": "sha512-SIOD2DxrRRwQ+jgzlXCqoEFiKOFqaPjhnNTGKXSRLvp1HiOvapLaFG2kEr9dYQTYe8rKrd9uvDUzmAITeNyaHQ==", + "dev": true, + "license": "MIT OR Apache-2.0", + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@cloudflare/unenv-preset": { + "version": "2.14.0", + "resolved": "https://registry.npmjs.org/@cloudflare/unenv-preset/-/unenv-preset-2.14.0.tgz", + "integrity": "sha512-XKAkWhi1nBdNsSEoNG9nkcbyvfUrSjSf+VYVPfOto3gLTZVc3F4g6RASCMh6IixBKCG2yDgZKQIHGKtjcnLnKg==", + "dev": true, + "license": "MIT OR Apache-2.0", + "peerDependencies": { + "unenv": "2.0.0-rc.24", + "workerd": "^1.20260218.0" + }, + "peerDependenciesMeta": { + "workerd": { + "optional": true + } + } + }, + "node_modules/@cloudflare/workerd-darwin-64": { + "version": "1.20260301.1", + "resolved": "https://registry.npmjs.org/@cloudflare/workerd-darwin-64/-/workerd-darwin-64-1.20260301.1.tgz", + "integrity": "sha512-+kJvwociLrvy1JV9BAvoSVsMEIYD982CpFmo/yMEvBwxDIjltYsLTE8DLi0mCkGsQ8Ygidv2fD9wavzXeiY7OQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=16" + } + }, + "node_modules/@cloudflare/workerd-darwin-arm64": { + "version": "1.20260301.1", + "resolved": "https://registry.npmjs.org/@cloudflare/workerd-darwin-arm64/-/workerd-darwin-arm64-1.20260301.1.tgz", + "integrity": "sha512-PPIetY3e67YBr9O4UhILK8nbm5TqUDl14qx4rwFNrRSBOvlzuczzbd4BqgpAtbGVFxKp1PWpjAnBvGU/OI/tLQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=16" + } + }, + "node_modules/@cloudflare/workerd-linux-64": { + "version": "1.20260301.1", + "resolved": "https://registry.npmjs.org/@cloudflare/workerd-linux-64/-/workerd-linux-64-1.20260301.1.tgz", + "integrity": "sha512-Gu5vaVTZuYl3cHa+u5CDzSVDBvSkfNyuAHi6Mdfut7TTUdcb3V5CIcR/mXRSyMXzEy9YxEWIfdKMxOMBjupvYQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=16" + } + }, + "node_modules/@cloudflare/workerd-linux-arm64": { + "version": "1.20260301.1", + "resolved": "https://registry.npmjs.org/@cloudflare/workerd-linux-arm64/-/workerd-linux-arm64-1.20260301.1.tgz", + "integrity": "sha512-igL1pkyCXW6GiGpjdOAvqMi87UW0LMc/+yIQe/CSzuZJm5GzXoAMrwVTkCFnikk6JVGELrM5x0tGYlxa0sk5Iw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=16" + } + }, + "node_modules/@cloudflare/workerd-windows-64": { + "version": "1.20260301.1", + "resolved": "https://registry.npmjs.org/@cloudflare/workerd-windows-64/-/workerd-windows-64-1.20260301.1.tgz", + "integrity": "sha512-Q0wMJ4kcujXILwQKQFc1jaYamVsNvjuECzvRrTI8OxGFMx2yq9aOsswViE4X1gaS2YQQ5u0JGwuGi5WdT1Lt7A==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=16" + } + }, + "node_modules/@cloudflare/workers-types": { + "version": "4.20260301.1", + "resolved": "https://registry.npmjs.org/@cloudflare/workers-types/-/workers-types-4.20260301.1.tgz", + "integrity": "sha512-klKnECMb5A4GtVF0P5NH6rCjtyjqIEKJaz6kEtx9YPHhfFO2HUEarO+MI4F8WPchgeZqpGlEpDhRapzrOTw51Q==", + "license": "MIT OR Apache-2.0" + }, + "node_modules/@cspotcode/source-map-support": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", + "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", + "license": "MIT", + "dependencies": { + "@jridgewell/trace-mapping": "0.3.9" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@cspotcode/source-map-support/node_modules/@jridgewell/trace-mapping": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", + "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.0.3", + "@jridgewell/sourcemap-codec": "^1.4.10" + } + }, "node_modules/@emmetio/abbreviation": { "version": "2.3.3", "resolved": "https://registry.npmjs.org/@emmetio/abbreviation/-/abbreviation-2.3.3.tgz", @@ -1548,8 +3333,8 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/@img/colour/-/colour-1.1.0.tgz", "integrity": "sha512-Td76q7j57o/tLVdgS746cYARfSyxk8iEfRxewL9h4OMzYhbW4TAcppl0mT4eyqXddh6L/jwoM75mo7ixa/pCeQ==", + "devOptional": true, "license": "MIT", - "optional": true, "engines": { "node": ">=18" } @@ -1561,6 +3346,7 @@ "cpu": [ "arm64" ], + "dev": true, "license": "Apache-2.0", "optional": true, "os": [ @@ -1583,6 +3369,7 @@ "cpu": [ "x64" ], + "dev": true, "license": "Apache-2.0", "optional": true, "os": [ @@ -1605,6 +3392,7 @@ "cpu": [ "arm64" ], + "dev": true, "license": "LGPL-3.0-or-later", "optional": true, "os": [ @@ -1621,6 +3409,7 @@ "cpu": [ "x64" ], + "dev": true, "license": "LGPL-3.0-or-later", "optional": true, "os": [ @@ -1637,6 +3426,7 @@ "cpu": [ "arm" ], + "dev": true, "license": "LGPL-3.0-or-later", "optional": true, "os": [ @@ -1653,6 +3443,7 @@ "cpu": [ "arm64" ], + "dev": true, "license": "LGPL-3.0-or-later", "optional": true, "os": [ @@ -1669,6 +3460,7 @@ "cpu": [ "ppc64" ], + "dev": true, "license": "LGPL-3.0-or-later", "optional": true, "os": [ @@ -1685,6 +3477,7 @@ "cpu": [ "riscv64" ], + "dev": true, "license": "LGPL-3.0-or-later", "optional": true, "os": [ @@ -1701,6 +3494,7 @@ "cpu": [ "s390x" ], + "dev": true, "license": "LGPL-3.0-or-later", "optional": true, "os": [ @@ -1717,6 +3511,7 @@ "cpu": [ "x64" ], + "dev": true, "license": "LGPL-3.0-or-later", "optional": true, "os": [ @@ -1733,6 +3528,7 @@ "cpu": [ "arm64" ], + "dev": true, "license": "LGPL-3.0-or-later", "optional": true, "os": [ @@ -1749,6 +3545,7 @@ "cpu": [ "x64" ], + "dev": true, "license": "LGPL-3.0-or-later", "optional": true, "os": [ @@ -1765,6 +3562,7 @@ "cpu": [ "arm" ], + "dev": true, "license": "Apache-2.0", "optional": true, "os": [ @@ -1787,6 +3585,7 @@ "cpu": [ "arm64" ], + "dev": true, "license": "Apache-2.0", "optional": true, "os": [ @@ -1809,6 +3608,7 @@ "cpu": [ "ppc64" ], + "dev": true, "license": "Apache-2.0", "optional": true, "os": [ @@ -1831,6 +3631,7 @@ "cpu": [ "riscv64" ], + "dev": true, "license": "Apache-2.0", "optional": true, "os": [ @@ -1853,6 +3654,7 @@ "cpu": [ "s390x" ], + "dev": true, "license": "Apache-2.0", "optional": true, "os": [ @@ -1875,6 +3677,7 @@ "cpu": [ "x64" ], + "dev": true, "license": "Apache-2.0", "optional": true, "os": [ @@ -1897,6 +3700,7 @@ "cpu": [ "arm64" ], + "dev": true, "license": "Apache-2.0", "optional": true, "os": [ @@ -1919,6 +3723,7 @@ "cpu": [ "x64" ], + "dev": true, "license": "Apache-2.0", "optional": true, "os": [ @@ -1941,6 +3746,7 @@ "cpu": [ "wasm32" ], + "dev": true, "license": "Apache-2.0 AND LGPL-3.0-or-later AND MIT", "optional": true, "dependencies": { @@ -1960,6 +3766,7 @@ "cpu": [ "arm64" ], + "dev": true, "license": "Apache-2.0 AND LGPL-3.0-or-later", "optional": true, "os": [ @@ -1979,6 +3786,7 @@ "cpu": [ "ia32" ], + "dev": true, "license": "Apache-2.0 AND LGPL-3.0-or-later", "optional": true, "os": [ @@ -1998,6 +3806,7 @@ "cpu": [ "x64" ], + "dev": true, "license": "Apache-2.0 AND LGPL-3.0-or-later", "optional": true, "os": [ @@ -2185,6 +3994,41 @@ "node": ">=14" } }, + "node_modules/@poppinss/colors": { + "version": "4.1.6", + "resolved": "https://registry.npmjs.org/@poppinss/colors/-/colors-4.1.6.tgz", + "integrity": "sha512-H9xkIdFswbS8n1d6vmRd8+c10t2Qe+rZITbbDHHkQixH5+2x1FDGmi/0K+WgWiqQFKPSlIYB7jlH6Kpfn6Fleg==", + "license": "MIT", + "dependencies": { + "kleur": "^4.1.5" + } + }, + "node_modules/@poppinss/colors/node_modules/kleur": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-4.1.5.tgz", + "integrity": "sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/@poppinss/dumper": { + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/@poppinss/dumper/-/dumper-0.6.5.tgz", + "integrity": "sha512-NBdYIb90J7LfOI32dOewKI1r7wnkiH6m920puQ3qHUeZkxNkQiFnXVWoE6YtFSv6QOiPPf7ys6i+HWWecDz7sw==", + "license": "MIT", + "dependencies": { + "@poppinss/colors": "^4.1.5", + "@sindresorhus/is": "^7.0.2", + "supports-color": "^10.0.0" + } + }, + "node_modules/@poppinss/exception": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@poppinss/exception/-/exception-1.2.3.tgz", + "integrity": "sha512-dCED+QRChTVatE9ibtoaxc+WkdzOSjYTKi/+uacHWIsfodVfpsueo3+DKpgU5Px8qXjgmXkSvhXvSCz3fnP9lw==", + "license": "MIT" + }, "node_modules/@radix-ui/react-compose-refs": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.1.2.tgz", @@ -2638,6 +4482,24 @@ "integrity": "sha512-83yeghZ2xxin3Nj8z1NMd/NCuca+gsYXswywDy5bHvwlWL8tpTQmzGeUuHd9FC3E/SBEMvzJRwWEOz5gGes9Qg==", "license": "MIT" }, + "node_modules/@sindresorhus/is": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-7.2.0.tgz", + "integrity": "sha512-P1Cz1dWaFfR4IR+U13mqqiGsLFf1KbayybWwdd2vfctdV6hDpUkgCY0nKOLLTMSoRd/jJNjtbqzf13K8DCCXQw==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sindresorhus/is?sponsor=1" + } + }, + "node_modules/@speed-highlight/core": { + "version": "1.2.14", + "resolved": "https://registry.npmjs.org/@speed-highlight/core/-/core-1.2.14.tgz", + "integrity": "sha512-G4ewlBNhUtlLvrJTb88d2mdy2KRijzs4UhnlrOSRT4bmjh/IqNElZa3zkrZ+TC47TwtlDWzVLFADljF1Ijp5hA==", + "license": "CC0-1.0" + }, "node_modules/@storybook/addon-a11y": { "version": "9.1.19", "resolved": "https://registry.npmjs.org/@storybook/addon-a11y/-/addon-a11y-9.1.19.tgz", @@ -3602,6 +5464,15 @@ "node": ">=0.4.0" } }, + "node_modules/acorn-walk": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.2.tgz", + "integrity": "sha512-cjkyv4OtNCIeqhHrfS81QWXoCBPExR/J62oyEqepVw8WaQeSqpW2uhuLPh1m9eWhDuOo/jUXVTlifvesOWp/4A==", + "license": "MIT", + "engines": { + "node": ">=0.4.0" + } + }, "node_modules/ajv": { "version": "8.18.0", "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.18.0.tgz", @@ -4476,6 +6347,12 @@ "node": ">=12.0.0" } }, + "node_modules/blake3-wasm": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/blake3-wasm/-/blake3-wasm-2.1.5.tgz", + "integrity": "sha512-F1+K8EbfOZE49dtoPtmxUQrpXaBIl3ICvasLh+nJta0xkz+9kF/7uet9fLnwKqhDrmj6g+6K3Tw9yQPUg2ka5g==", + "license": "MIT" + }, "node_modules/boolbase": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", @@ -4805,11 +6682,23 @@ "node": ">=6" } }, + "node_modules/color": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/color/-/color-4.2.3.tgz", + "integrity": "sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==", + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1", + "color-string": "^1.9.0" + }, + "engines": { + "node": ">=12.5.0" + } + }, "node_modules/color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, "license": "MIT", "dependencies": { "color-name": "~1.1.4" @@ -4822,9 +6711,18 @@ "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true, "license": "MIT" }, + "node_modules/color-string": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.9.1.tgz", + "integrity": "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==", + "license": "MIT", + "dependencies": { + "color-name": "^1.0.0", + "simple-swizzle": "^0.2.2" + } + }, "node_modules/comma-separated-tokens": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-2.0.3.tgz", @@ -5074,7 +6972,6 @@ "version": "2.1.2", "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", - "devOptional": true, "license": "Apache-2.0", "engines": { "node": ">=8" @@ -5285,6 +7182,15 @@ "url": "https://github.com/fb55/entities?sponsor=1" } }, + "node_modules/error-stack-parser-es": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/error-stack-parser-es/-/error-stack-parser-es-1.0.5.tgz", + "integrity": "sha512-5qucVt2XcuGMcEGgWI7i+yZpmpByQ8J1lHhcL7PwqCwu9FPP3VUXzT4ltHe5i2z9dePwEHcDVOAfSnHsOlCXRA==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, "node_modules/es-module-lexer": { "version": "1.7.0", "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.7.0.tgz", @@ -5402,6 +7308,18 @@ "integrity": "sha512-mlsTRyGaPBjPedk6Bvw+aqbsXDtoAyAzm5MO7JgU+yVRyMQ5O8bD4Kcci7BS85f93veegeCPkL8R4GLClnjLFw==", "license": "MIT" }, + "node_modules/exit-hook": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/exit-hook/-/exit-hook-2.2.1.tgz", + "integrity": "sha512-eNTPlAD67BmP31LDINZ3U7HSF8l57TxOY2PmBJ1shpCvpnxBF93mWCE8YHBnXs8qiUZJc9WDcWIeC3a2HIAMfw==", + "license": "MIT", + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/extend": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", @@ -5624,6 +7542,12 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/glob-to-regexp": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", + "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", + "license": "BSD-2-Clause" + }, "node_modules/graceful-fs": { "version": "4.2.11", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", @@ -5889,6 +7813,12 @@ "url": "https://github.com/sponsors/brc-dd" } }, + "node_modules/is-arrayish": { + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.4.tgz", + "integrity": "sha512-m6UrgzFVUYawGBh1dUsWR5M2Clqic9RVXC/9f8ceNlv2IcO9j9J/z8UoCLPqtsPBFNzEpfR3xftohbfqDx8EQA==", + "license": "MIT" + }, "node_modules/is-core-module": { "version": "2.16.1", "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz", @@ -7199,6 +9129,18 @@ ], "license": "MIT" }, + "node_modules/mime": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-3.0.0.tgz", + "integrity": "sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A==", + "license": "MIT", + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=10.0.0" + } + }, "node_modules/min-indent": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", @@ -7209,6 +9151,49 @@ "node": ">=4" } }, + "node_modules/miniflare": { + "version": "4.20260301.1", + "resolved": "https://registry.npmjs.org/miniflare/-/miniflare-4.20260301.1.tgz", + "integrity": "sha512-fqkHx0QMKswRH9uqQQQOU/RoaS3Wjckxy3CUX3YGJr0ZIMu7ObvI+NovdYi6RIsSPthNtq+3TPmRNxjeRiasog==", + "dev": true, + "license": "MIT", + "dependencies": { + "@cspotcode/source-map-support": "0.8.1", + "sharp": "^0.34.5", + "undici": "7.18.2", + "workerd": "1.20260301.1", + "ws": "8.18.0", + "youch": "4.1.0-beta.10" + }, + "bin": { + "miniflare": "bootstrap.js" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/miniflare/node_modules/ws": { + "version": "8.18.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz", + "integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, "node_modules/minimatch": { "version": "9.0.9", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.9.tgz", @@ -7644,6 +9629,18 @@ "dev": true, "license": "ISC" }, + "node_modules/path-to-regexp": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-6.3.0.tgz", + "integrity": "sha512-Yhpw4T9C6hPpgPeA28us07OJeqZ5EzQTkbfwuhsUg0c237RomFoETJgmp2sa3F/41gfLE6G5cqcYwznmeEeOlQ==", + "license": "MIT" + }, + "node_modules/pathe": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz", + "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==", + "license": "MIT" + }, "node_modules/pathval": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/pathval/-/pathval-2.0.1.tgz", @@ -8250,9 +10247,9 @@ "version": "0.34.5", "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.34.5.tgz", "integrity": "sha512-Ou9I5Ft9WNcCbXrU9cMgPBcCK8LiwLqcbywW3t4oDV37n1pzpuNLsYiAV8eODnjbtQlSDwZ2cUEeQz4E54Hltg==", + "devOptional": true, "hasInstallScript": true, "license": "Apache-2.0", - "optional": true, "dependencies": { "@img/colour": "^1.0.0", "detect-libc": "^2.1.2", @@ -8295,8 +10292,8 @@ "version": "7.7.4", "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", + "devOptional": true, "license": "ISC", - "optional": true, "bin": { "semver": "bin/semver.js" }, @@ -8356,6 +10353,15 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/simple-swizzle": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.4.tgz", + "integrity": "sha512-nAu1WFPQSMNr2Zn9PGSZK9AGn4t/y97lEm+MXTtUDwfP0ksAIX4nO+6ruD9Jwut4C49SB1Ws+fbXsm/yScWOHw==", + "license": "MIT", + "dependencies": { + "is-arrayish": "^0.3.1" + } + }, "node_modules/sisteransi": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", @@ -8403,6 +10409,16 @@ "url": "https://github.com/sponsors/wooorm" } }, + "node_modules/stoppable": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/stoppable/-/stoppable-1.1.0.tgz", + "integrity": "sha512-KXDYZ9dszj6bzvnEMRYvxgeTHU74QBFL54XKtP3nyMuJ81CFYtABZ3bAzL2EdFUaEwJOBOgENyFj3R7oTzDyyw==", + "license": "MIT", + "engines": { + "node": ">=4", + "npm": ">=6" + } + }, "node_modules/storybook": { "version": "9.1.19", "resolved": "https://registry.npmjs.org/storybook/-/storybook-9.1.19.tgz", @@ -9067,6 +11083,18 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/supports-color": { + "version": "10.2.2", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-10.2.2.tgz", + "integrity": "sha512-SS+jx45GF1QjgEXQx4NJZV9ImqmO2NPz5FNsIHrsDjh2YsHnawpan7SNQ1o8NuhrbHZy9AZhIoCUiCeaW/C80g==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, "node_modules/supports-preserve-symlinks-flag": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", @@ -9338,6 +11366,25 @@ "integrity": "sha512-Ql87qFHB3s/De2ClA9e0gsnS6zXG27SkTiSJwjCc9MebbfapQfuPzumMIUMi38ezPZVNFcHI9sUIepeQfw8J8Q==", "license": "MIT" }, + "node_modules/undici": { + "version": "7.18.2", + "resolved": "https://registry.npmjs.org/undici/-/undici-7.18.2.tgz", + "integrity": "sha512-y+8YjDFzWdQlSE9N5nzKMT3g4a5UBX1HKowfdXh0uvAnTaqqwqB92Jt4UXBAeKekDs5IaDKyJFR4X1gYVCgXcw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=20.18.1" + } + }, + "node_modules/unenv": { + "version": "2.0.0-rc.24", + "resolved": "https://registry.npmjs.org/unenv/-/unenv-2.0.0-rc.24.tgz", + "integrity": "sha512-i7qRCmY42zmCwnYlh9H2SvLEypEFGye5iRmEMKjcGi7zk9UquigRjFtTLz0TYqr0ZGLZhaMHl/foy1bZR+Cwlw==", + "license": "MIT", + "dependencies": { + "pathe": "^2.0.3" + } + }, "node_modules/unicorn-magic": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/unicorn-magic/-/unicorn-magic-0.1.0.tgz", @@ -10114,6 +12161,62 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/workerd": { + "version": "1.20260301.1", + "resolved": "https://registry.npmjs.org/workerd/-/workerd-1.20260301.1.tgz", + "integrity": "sha512-oterQ1IFd3h7PjCfT4znSFOkJCvNQ6YMOyZ40YsnO3nrSpgB4TbJVYWFOnyJAw71/RQuupfVqZZWKvsy8GO3fw==", + "dev": true, + "hasInstallScript": true, + "license": "Apache-2.0", + "bin": { + "workerd": "bin/workerd" + }, + "engines": { + "node": ">=16" + }, + "optionalDependencies": { + "@cloudflare/workerd-darwin-64": "1.20260301.1", + "@cloudflare/workerd-darwin-arm64": "1.20260301.1", + "@cloudflare/workerd-linux-64": "1.20260301.1", + "@cloudflare/workerd-linux-arm64": "1.20260301.1", + "@cloudflare/workerd-windows-64": "1.20260301.1" + } + }, + "node_modules/wrangler": { + "version": "4.70.0", + "resolved": "https://registry.npmjs.org/wrangler/-/wrangler-4.70.0.tgz", + "integrity": "sha512-PNDZ9o4e+B5x+1bUbz62Hmwz6G9lw+I9pnYe/AguLddJFjfIyt2cmFOUOb3eOZSoXsrhcEPUg2YidYIbVwUkfw==", + "dev": true, + "license": "MIT OR Apache-2.0", + "dependencies": { + "@cloudflare/kv-asset-handler": "0.4.2", + "@cloudflare/unenv-preset": "2.14.0", + "blake3-wasm": "2.1.5", + "esbuild": "0.27.3", + "miniflare": "4.20260301.1", + "path-to-regexp": "6.3.0", + "unenv": "2.0.0-rc.24", + "workerd": "1.20260301.1" + }, + "bin": { + "wrangler": "bin/wrangler.js", + "wrangler2": "bin/wrangler.js" + }, + "engines": { + "node": ">=20.0.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + }, + "peerDependencies": { + "@cloudflare/workers-types": "^4.20260226.1" + }, + "peerDependenciesMeta": { + "@cloudflare/workers-types": { + "optional": true + } + } + }, "node_modules/wrap-ansi": { "version": "9.0.2", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.2.tgz", @@ -10418,6 +12521,29 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/youch": { + "version": "4.1.0-beta.10", + "resolved": "https://registry.npmjs.org/youch/-/youch-4.1.0-beta.10.tgz", + "integrity": "sha512-rLfVLB4FgQneDr0dv1oddCVZmKjcJ6yX6mS4pU82Mq/Dt9a3cLZQ62pDBL4AUO+uVrCvtWz3ZFUL2HFAFJ/BXQ==", + "license": "MIT", + "dependencies": { + "@poppinss/colors": "^4.1.5", + "@poppinss/dumper": "^0.6.4", + "@speed-highlight/core": "^1.2.7", + "cookie": "^1.0.2", + "youch-core": "^0.3.3" + } + }, + "node_modules/youch-core": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/youch-core/-/youch-core-0.3.3.tgz", + "integrity": "sha512-ho7XuGjLaJ2hWHoK8yFnsUGy2Y5uDpqSTq1FkHLK4/oqKtyUU1AFbOOxY4IpC9f0fTLjwYbslUz0Po5BpD1wrA==", + "license": "MIT", + "dependencies": { + "@poppinss/exception": "^1.2.2", + "error-stack-parser-es": "^1.0.5" + } + }, "node_modules/zod": { "version": "3.25.76", "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz", diff --git a/package.json b/package.json index b2de142..2b9b84e 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,7 @@ "dev": "astro dev", "build": "astro build", "build:external": "node scripts/build-astro-external.mjs", - "preview": "astro preview", + "preview": "npm run build && wrangler dev", "astro": "astro", "typecheck": "astro check", "storybook": "storybook dev -p 6006", @@ -20,9 +20,12 @@ "preflight:pages": "npm run lab:build && npm run tracking:check && npm run image:budget && npm run storybook:build", "deploy:ftp": "bash scripts/deploy-ovh-ftp.sh dist", "deploy:web:ftp": "npm run build:external && npm run deploy:ftp", - "deploy:web:sftp": "npm run build:external && bash scripts/deploy-ovh-sftp.sh dist" + "deploy:web:sftp": "npm run build:external && bash scripts/deploy-ovh-sftp.sh dist", + "deploy": "npm run build && wrangler deploy", + "cf-typegen": "wrangler types" }, "dependencies": { + "@astrojs/cloudflare": "^12.6.12", "@astrojs/react": "^4.4.1", "@radix-ui/react-slot": "^1.2.3", "astro": "^5.13.8", @@ -42,7 +45,8 @@ "@storybook/react-vite": "^9.1.5", "@tailwindcss/vite": "^4.1.13", "storybook": "^9.1.5", - "typescript": "^5.9.2" + "typescript": "^5.9.2", + "wrangler": "^4.70.0" }, "overrides": { "@astrojs/language-server": { diff --git a/public/.assetsignore b/public/.assetsignore new file mode 100644 index 0000000..1b006a0 --- /dev/null +++ b/public/.assetsignore @@ -0,0 +1,2 @@ +_worker.js +_routes.json \ No newline at end of file diff --git a/wrangler.jsonc b/wrangler.jsonc new file mode 100644 index 0000000..e08eb40 --- /dev/null +++ b/wrangler.jsonc @@ -0,0 +1,17 @@ +{ + "main": "dist/_worker.js/index.js", + "name": "electron-rare", + "compatibility_date": "2025-09-27", + "compatibility_flags": [ + "global_fetch_strictly_public", + "nodejs_compat" + ], + "assets": { + "binding": "ASSETS", + "directory": "dist" + }, + "observability": { + "enabled": true + }, + "$schema": "node_modules/wrangler/config-schema.json" +} -- 2.52.0 From 3c641ba79a7ab0311a9b59758673d31676e19221 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20SAILLANT?= <108685187+electron-rare@users.noreply.github.com> Date: Sat, 14 Mar 2026 14:29:27 +0000 Subject: [PATCH 02/31] feat: add OVH FTP preview deployment --- .env.ftp.example | 5 +- .github/workflows/deploy-ovh-ftp.yml | 61 +++++++++++ apps/lab-interactif/index.html | 2 +- apps/lab-interactif/src/App.jsx | 3 +- apps/lab-interactif/src/lib/paths.js | 29 +++++ apps/lab-interactif/src/pages/LabHomePage.jsx | 6 +- apps/lab-interactif/vite.config.js | 8 +- astro.config.mjs | 7 +- docs/ovh-ftp-preview-solution-2026-03-14.md | 50 +++++++++ public/assets/brand/logo-lockup.svg | 2 +- public/assets/brand/logo-mark.svg | 2 +- public/favicon.svg | 2 +- scripts/deploy-ovh-ftp-target.sh | 69 ++++++++++++ src/components/sections/Hero.tsx | 26 ++--- src/layouts/BaseLayout.astro | 102 +++++------------- src/lib/site.ts | 56 ++++++++-- src/pages/index.astro | 3 - 17 files changed, 329 insertions(+), 104 deletions(-) create mode 100644 .github/workflows/deploy-ovh-ftp.yml create mode 100644 apps/lab-interactif/src/lib/paths.js create mode 100644 docs/ovh-ftp-preview-solution-2026-03-14.md create mode 100644 scripts/deploy-ovh-ftp-target.sh diff --git a/.env.ftp.example b/.env.ftp.example index caf594a..9ab7658 100644 --- a/.env.ftp.example +++ b/.env.ftp.example @@ -3,4 +3,7 @@ FTP_USER=ecobsoleiq FTP_PORT=21 FTP_REMOTE_DIR=/www FTP_PASS=your-ftp-password -PUBLIC_SITE_URL=https://ton-domaine.fr/ +PUBLIC_SITE_URL_PROD=https://www.lelectronrare.fr/ +PUBLIC_SITE_URL_PREVIEW=https://www.lelectronrare.fr/preview/ +FTP_DNS_RETRIES=5 +FTP_DNS_DELAY=2 diff --git a/.github/workflows/deploy-ovh-ftp.yml b/.github/workflows/deploy-ovh-ftp.yml new file mode 100644 index 0000000..05b7ead --- /dev/null +++ b/.github/workflows/deploy-ovh-ftp.yml @@ -0,0 +1,61 @@ +name: Deploy External Site to OVH FTP + +on: + workflow_dispatch: + inputs: + target: + description: Deployment target + required: true + default: preview + type: choice + options: + - preview + - production + +permissions: + contents: read + +concurrency: + group: ovh-ftp-${{ inputs.target }} + cancel-in-progress: false + +jobs: + deploy: + runs-on: ubuntu-latest + env: + FTP_HOST: ${{ secrets.OVH_FTP_HOST }} + FTP_USER: ${{ secrets.OVH_FTP_USER }} + FTP_PASS: ${{ secrets.OVH_FTP_PASS }} + FTP_PORT: ${{ secrets.OVH_FTP_PORT }} + FTP_REMOTE_DIR: ${{ secrets.OVH_FTP_REMOTE_DIR }} + PUBLIC_SITE_URL_PROD: ${{ vars.PUBLIC_SITE_URL_PROD }} + PUBLIC_SITE_URL_PREVIEW: ${{ vars.PUBLIC_SITE_URL_PREVIEW }} + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup Node + uses: actions/setup-node@v4 + with: + node-version: 22 + cache: npm + cache-dependency-path: | + package-lock.json + apps/lab-interactif/package-lock.json + + - name: Install root dependencies + run: npm ci + + - name: Install lab dependencies + run: npm ci --prefix apps/lab-interactif + + - name: Install lftp + run: | + sudo apt-get update + sudo apt-get install -y lftp + + - name: Deploy target + env: + DEPLOY_TARGET_SKIP_BUILD: "0" + run: bash scripts/deploy-ovh-ftp-target.sh "${{ inputs.target }}" diff --git a/apps/lab-interactif/index.html b/apps/lab-interactif/index.html index 3f69a06..019bb15 100644 --- a/apps/lab-interactif/index.html +++ b/apps/lab-interactif/index.html @@ -10,6 +10,6 @@
- + diff --git a/apps/lab-interactif/src/App.jsx b/apps/lab-interactif/src/App.jsx index e383c85..6dfe48d 100644 --- a/apps/lab-interactif/src/App.jsx +++ b/apps/lab-interactif/src/App.jsx @@ -2,13 +2,14 @@ import { NavLink, Route, Routes } from 'react-router-dom'; import { LabHomePage } from './pages/LabHomePage'; import { SignalsPage } from './pages/SignalsPage'; import { PrototypesPage } from './pages/PrototypesPage'; +import { withSiteBase } from './lib/paths'; export function App() { return (
- + Retour site principal
diff --git a/apps/lab-interactif/vite.config.js b/apps/lab-interactif/vite.config.js index f394788..8ad2d79 100644 --- a/apps/lab-interactif/vite.config.js +++ b/apps/lab-interactif/vite.config.js @@ -1,9 +1,15 @@ import { defineConfig } from 'vite'; import react from '@vitejs/plugin-react'; +const normalizeUrl = (value) => (value.endsWith('/') ? value : `${value}/`); +const rawSiteUrl = process.env.PUBLIC_SITE_URL || process.env.EXTERNAL_SITE_URL || 'https://electron-rare.github.io/'; +const parsedSiteUrl = new URL(normalizeUrl(rawSiteUrl)); +const siteBasePath = parsedSiteUrl.pathname === '/' ? '' : parsedSiteUrl.pathname.replace(/\/$/, ''); +const labBase = `${siteBasePath}/lab/`; + export default defineConfig({ plugins: [react()], - base: '/lab/', + base: labBase, build: { outDir: '../../lab', emptyOutDir: true diff --git a/astro.config.mjs b/astro.config.mjs index 2cdf5c2..a354aed 100644 --- a/astro.config.mjs +++ b/astro.config.mjs @@ -2,10 +2,15 @@ import { defineConfig } from 'astro/config'; import react from '@astrojs/react'; import tailwindcss from '@tailwindcss/vite'; -const siteUrl = process.env.PUBLIC_SITE_URL || 'https://electron-rare.github.io/'; +const normalizeUrl = (value) => (value.endsWith('/') ? value : `${value}/`); +const rawSiteUrl = process.env.PUBLIC_SITE_URL || process.env.EXTERNAL_SITE_URL || 'https://electron-rare.github.io/'; +const siteUrl = normalizeUrl(rawSiteUrl); +const sitePathname = new URL(siteUrl).pathname; +const basePath = sitePathname === '/' ? '/' : sitePathname.replace(/\/$/, ''); export default defineConfig({ site: siteUrl, + base: basePath, integrations: [react()], vite: { plugins: [tailwindcss()] diff --git a/docs/ovh-ftp-preview-solution-2026-03-14.md b/docs/ovh-ftp-preview-solution-2026-03-14.md new file mode 100644 index 0000000..d25e412 --- /dev/null +++ b/docs/ovh-ftp-preview-solution-2026-03-14.md @@ -0,0 +1,50 @@ +# OVH FTP Preview Deploy + +## Pourquoi + +Le deploy FTP direct depuis la machine locale bloque sur le canal de donnees FTP OVH. +Le build local fonctionne, mais l'upload reste instable. + +## Solution retenue + +Deployer vers OVH FTP depuis un runner GitHub Actions public. + +Le runner : +- build le site avec la bonne `PUBLIC_SITE_URL` +- choisit la cible `preview` ou `production` +- synchronise `dist/` via `lftp` + +## Secrets GitHub requis + +- `OVH_FTP_HOST` +- `OVH_FTP_USER` +- `OVH_FTP_PASS` +- `OVH_FTP_PORT` +- `OVH_FTP_REMOTE_DIR` + +## Variables GitHub requises + +- `PUBLIC_SITE_URL_PROD=https://www.lelectronrare.fr/` +- `PUBLIC_SITE_URL_PREVIEW=https://www.lelectronrare.fr/preview/` + +## Workflow + +Fichier : +- `.github/workflows/deploy-ovh-ftp.yml` + +Script cible : +- `scripts/deploy-ovh-ftp-target.sh` + +## Usage + +### Preview + +```bash +gh workflow run deploy-ovh-ftp.yml --ref -f target=preview +``` + +### Production + +```bash +gh workflow run deploy-ovh-ftp.yml --ref -f target=production +``` diff --git a/public/assets/brand/logo-lockup.svg b/public/assets/brand/logo-lockup.svg index d2c9d4b..4f59d5c 100644 --- a/public/assets/brand/logo-lockup.svg +++ b/public/assets/brand/logo-lockup.svg @@ -1 +1 @@ - + diff --git a/public/assets/brand/logo-mark.svg b/public/assets/brand/logo-mark.svg index cca4d1f..7f319bf 100644 --- a/public/assets/brand/logo-mark.svg +++ b/public/assets/brand/logo-mark.svg @@ -1 +1 @@ - + diff --git a/public/favicon.svg b/public/favicon.svg index 44f064e..9ed3a3d 100644 --- a/public/favicon.svg +++ b/public/favicon.svg @@ -1 +1 @@ - + diff --git a/scripts/deploy-ovh-ftp-target.sh b/scripts/deploy-ovh-ftp-target.sh new file mode 100644 index 0000000..56de8c0 --- /dev/null +++ b/scripts/deploy-ovh-ftp-target.sh @@ -0,0 +1,69 @@ +#!/usr/bin/env bash + +set -euo pipefail + +TARGET="${1:-preview}" +LOCAL_DIR="${2:-dist}" +FTP_ENV_FILE="${FTP_ENV_FILE:-.env.ftp}" + +load_env_file() { + if [[ ! -f "$FTP_ENV_FILE" ]]; then + return + fi + + set -a + # shellcheck disable=SC1090 + source "$FTP_ENV_FILE" + set +a +} + +resolve_base_remote_dir() { + if [[ -n "${FTP_REMOTE_DIR:-}" ]]; then + printf '%s\n' "${FTP_REMOTE_DIR%/}" + return + fi + + if [[ -n "${FTP_URL:-}" && "$FTP_URL" =~ ^ftp://[^@:/]+@[^:/]+(:([0-9]+))?(/.*)?$ ]]; then + printf '%s\n' "${BASH_REMATCH[3]:-/www}" + return + fi + + printf '%s\n' "/www" +} + +set_target_env() { + local base_remote_dir + base_remote_dir="$(resolve_base_remote_dir)" + + case "$TARGET" in + preview) + export PUBLIC_SITE_URL="${PUBLIC_SITE_URL_PREVIEW:-https://www.lelectronrare.fr/preview/}" + export FTP_REMOTE_DIR="${base_remote_dir}/preview" + ;; + production|prod) + export PUBLIC_SITE_URL="${PUBLIC_SITE_URL_PROD:-${PUBLIC_SITE_URL:-https://www.lelectronrare.fr/}}" + export FTP_REMOTE_DIR="${base_remote_dir}" + ;; + *) + echo "Unknown target: ${TARGET}. Use 'preview' or 'production'." + exit 1 + ;; + esac + + unset FTP_URL +} + +main() { + load_env_file + set_target_env + + if [[ "${DEPLOY_TARGET_SKIP_BUILD:-0}" != "1" ]]; then + npm run build:external + else + echo "[deploy-ovh-ftp-target] Skipping build:external (already built)." + fi + + bash scripts/deploy-ovh-ftp.sh "$LOCAL_DIR" +} + +main "$@" diff --git a/src/components/sections/Hero.tsx b/src/components/sections/Hero.tsx index c4cad9e..2f45930 100644 --- a/src/components/sections/Hero.tsx +++ b/src/components/sections/Hero.tsx @@ -1,5 +1,6 @@ import * as React from 'react'; import type { CtaLink } from '@/lib/types'; +import { withSiteBase } from '@/lib/site'; import { TRACK_EVENTS, trackAttrs } from '@/lib/tracking'; const heroCtas: CtaLink[] = [ @@ -24,6 +25,7 @@ const heroCtas: CtaLink[] = [ ]; const HERO_TITLE_WORDS = ['Conception', 'electronique', 'sur mesure']; +const assetPath = (value: string) => withSiteBase(value); const HERO_VARIANT_ASSETS: Record< string, @@ -45,18 +47,18 @@ const HERO_VARIANT_ASSETS: Record< } > = { v12: { - routingDesktopWebp: '/assets/da/openai/hero-pcb-routing-map-v2.webp', - routingMobileWebp: '/assets/da/openai/hero-pcb-routing-map-mobile-low-noise-v2.webp', - routingDesktop: '/assets/da/openai/hero-pcb-routing-map-v2.png', - routingMobile: '/assets/da/openai/hero-pcb-routing-map-mobile-low-noise-v2.png', - instrumentDesktopWebp: '/assets/da/openai/hero-instrument-panel-v2.webp', - instrumentMobileWebp: '/assets/da/openai/hero-instrument-panel-mobile-low-noise-v2.webp', - instrumentDesktop: '/assets/da/openai/hero-instrument-panel-v2.png', - instrumentMobile: '/assets/da/openai/hero-instrument-panel-mobile-low-noise-v2.png', - notebookDesktopWebp: '/assets/da/openai/hero-carnet-labo-open-v2.webp', - notebookMobileWebp: '/assets/da/openai/carnet-labo-ouvert.webp', - notebookDesktop: '/assets/da/openai/hero-carnet-labo-open-v2.png', - notebookMobile: '/assets/da/openai/carnet-labo-ouvert.png', + routingDesktopWebp: assetPath('/assets/da/openai/hero-pcb-routing-map-v2.webp'), + routingMobileWebp: assetPath('/assets/da/openai/hero-pcb-routing-map-mobile-low-noise-v2.webp'), + routingDesktop: assetPath('/assets/da/openai/hero-pcb-routing-map-v2.png'), + routingMobile: assetPath('/assets/da/openai/hero-pcb-routing-map-mobile-low-noise-v2.png'), + instrumentDesktopWebp: assetPath('/assets/da/openai/hero-instrument-panel-v2.webp'), + instrumentMobileWebp: assetPath('/assets/da/openai/hero-instrument-panel-mobile-low-noise-v2.webp'), + instrumentDesktop: assetPath('/assets/da/openai/hero-instrument-panel-v2.png'), + instrumentMobile: assetPath('/assets/da/openai/hero-instrument-panel-mobile-low-noise-v2.png'), + notebookDesktopWebp: assetPath('/assets/da/openai/hero-carnet-labo-open-v2.webp'), + notebookMobileWebp: assetPath('/assets/da/openai/carnet-labo-ouvert.webp'), + notebookDesktop: assetPath('/assets/da/openai/hero-carnet-labo-open-v2.png'), + notebookMobile: assetPath('/assets/da/openai/carnet-labo-ouvert.png'), routingCaption: 'Architecture pcb', instrumentCaption: 'Appareil de mesure (asset)' } diff --git a/src/layouts/BaseLayout.astro b/src/layouts/BaseLayout.astro index 49cc10f..437c264 100644 --- a/src/layouts/BaseLayout.astro +++ b/src/layouts/BaseLayout.astro @@ -1,5 +1,14 @@ --- -import { GTM_CONTAINER_ID_DEFAULT, SITE_META, SITE_OG_IMAGE_URL, SITE_URL } from '@/lib/site'; +import { + CANONICAL_URL, + GTM_CONTAINER_ID_DEFAULT, + PUBLIC_SITE_ROOT_URL, + SITE_IS_SUBPATH_BUILD, + SITE_META, + SITE_OG_IMAGE_URL, + stripSiteBase, + withSiteBase +} from '@/lib/site'; interface Props { title?: string; @@ -11,25 +20,28 @@ const { description = SITE_META.description } = Astro.props; -const canonical = SITE_URL; +const pagePath = stripSiteBase(Astro.url.pathname); +const canonical = new URL(pagePath, CANONICAL_URL).href; +const pageUrl = new URL(pagePath, PUBLIC_SITE_ROOT_URL).href; +const robotsContent = SITE_IS_SUBPATH_BUILD ? 'noindex,nofollow,noarchive' : 'index,follow,max-image-preview:large'; const gtmId = import.meta.env.PUBLIC_GTM_CONTAINER_ID || GTM_CONTAINER_ID_DEFAULT; const structuredDataJsonLd = JSON.stringify({ '@context': 'https://schema.org', '@graph': [ { '@type': 'WebSite', - '@id': `${canonical}#website`, - url: canonical, + '@id': `${CANONICAL_URL}#website`, + url: CANONICAL_URL, name: "L'électron rare", inLanguage: 'fr-FR', description: SITE_META.description }, { '@type': 'Organization', - '@id': `${canonical}#organization`, + '@id': `${CANONICAL_URL}#organization`, name: "L'électron rare", - url: canonical, - logo: `${canonical}assets/brand/logo-mark.png`, + url: CANONICAL_URL, + logo: new URL('assets/brand/logo-mark.png', CANONICAL_URL).href, sameAs: [ 'https://fr.linkedin.com/in/electron-rare', 'https://www.malt.com/profile/clementsaillant', @@ -38,15 +50,15 @@ const structuredDataJsonLd = JSON.stringify({ }, { '@type': 'Person', - '@id': `${canonical}#person`, + '@id': `${CANONICAL_URL}#person`, name: 'Clément Saillant', alternateName: "L'électron rare", - url: canonical, + url: CANONICAL_URL, jobTitle: 'Concepteur en création électronique, design produit et systèmes expérimentaux', description: "Codeur créatif, itérateur IA et inventeur de systèmes : création électronique, performances audiovisuelles et collaborations studio sous l'identité L'électron rare.", worksFor: { - '@id': `${canonical}#organization` + '@id': `${CANONICAL_URL}#organization` }, sameAs: [ 'https://fr.linkedin.com/in/electron-rare', @@ -66,20 +78,20 @@ const structuredDataJsonLd = JSON.stringify({ {title} - - - - - + + + + + - + - + @@ -413,62 +425,6 @@ const structuredDataJsonLd = JSON.stringify({ })(); - - diff --git a/src/components/sections/Contact.stories.tsx b/src/components/sections/Contact.stories.tsx deleted file mode 100644 index 99f0bf3..0000000 --- a/src/components/sections/Contact.stories.tsx +++ /dev/null @@ -1,19 +0,0 @@ -import type { Meta, StoryObj } from '@storybook/react-vite'; -import { Contact } from './Contact'; - -const meta: Meta = { - title: 'Sections/Contact', - component: Contact, - tags: ['autodocs'] -}; - -export default meta; -type Story = StoryObj; - -export const Default: Story = { - render: () => ( -
- -
- ) -}; diff --git a/src/components/sections/Contact.tsx b/src/components/sections/Contact.tsx deleted file mode 100644 index 1f3d092..0000000 --- a/src/components/sections/Contact.tsx +++ /dev/null @@ -1,70 +0,0 @@ -import { motion } from 'motion/react'; -import { CtaDualRail } from '@/components/ui/cta-dual-rail'; -import type { CtaLink } from '@/lib/types'; -import { TRACK_EVENTS, trackAttrs } from '@/lib/tracking'; - -const tertiary: CtaLink = { - label: 'Bandcamp (Electron Fou)', - href: 'https://lelectron-fou.bandcamp.com/', - event: TRACK_EVENTS.outboundBandcampContact, - destination: 'bandcamp.com', - external: true -}; - -export function Contact() { - return ( - -
-
-
- -

- Point d'entree mission: perimetre, contraintes et priorites de delivery. -

- -

- Missions ciblees: architecture electronique, prototype sur mesure, optimisation systeme et accompagnement - produit. Le cadrage initial valide objectifs, risques et temporalite. -

-

- Canal prioritaire: LinkedIn DM. Option achat/prestation: Malt. Premier retour sous 24-48h selon charge. -

- - - -

- - -

- -
    -
  • Prerequis mission: objectif cible, contexte technique, contrainte principale
  • -
  • Mode operatoire: sprint de 2 semaines avec jalons de validation
  • -
  • Livrables: note de cadrage, priorisation et plan de delivery
  • -
  • References publiques disponibles pour pre-qualification
  • -
-
-
- ); -} diff --git a/src/components/sections/Faq.astro b/src/components/sections/Faq.astro new file mode 100644 index 0000000..c9238b4 --- /dev/null +++ b/src/components/sections/Faq.astro @@ -0,0 +1,91 @@ +--- +const faqItems = [ + { + question: "Quels types de projets prenez-vous en charge ?", + answer: "J'interviens sur des projets d'électronique embarquée, d'automatisme industriel, de prototypage hardware et d'instrumentation. Cela va du design de cartes PCB sur mesure à l'intégration de systèmes complets — pour le spectacle vivant, les installations artistiques, l'industrie ou l'IoT." + }, + { + question: "Comment se déroule une mission type ?", + answer: "Chaque mission commence par un échange pour cadrer le besoin et le cahier des charges. Ensuite : étude de faisabilité, conception (schéma, PCB, firmware), prototypage, tests et validation. Je livre une solution documentée et prête à être industrialisée ou déployée sur le terrain." + }, + { + question: "Travaillez-vous avec des industriels ou uniquement le spectacle vivant ?", + answer: "Les deux. Mon parcours a démarré dans les industries créatives (spectacle vivant, installations, arts de rue avec KompleX KapharnaüM), mais j'interviens aussi pour des clients industriels : transport (CBTC), énergie, IoT, audio professionnel. Le point commun : des projets où l'électronique embarquée croise plusieurs disciplines." + }, + { + question: "Proposez-vous des formations ?", + answer: "Oui, je propose des formations en électronique embarquée, prototypage et conception PCB — en entreprise, en école ou à distance. Les programmes sont adaptables à votre contexte. Consultez la page Formation pour le catalogue, ou contactez-moi pour un programme sur mesure." + }, + { + question: "Quelles technologies maîtrisez-vous ?", + answer: "Conception PCB (KiCad), microcontrôleurs (STM32, ESP32, Teensy, Arduino), automates industriels (Siemens S7, Schneider), instrumentation (oscilloscopes, analyseurs), firmware C/C++ et Python, protocoles terrain (MQTT, Modbus, DMX, Art-Net, OSC). Je m'adapte aussi à des stacks spécifiques selon le projet." + }, + { + question: "Quel est le délai pour un prototype ?", + answer: "Cela dépend de la complexité du projet. Un prototype simple (carte capteur, interface LED) peut être livré en 2 à 4 semaines. Un système embarqué complet avec firmware et boîtier prend généralement 6 à 10 semaines. Un premier échange permet de cadrer le planning précis." + }, + { + question: "Intervenez-vous partout en France ?", + answer: "Oui. Je suis basé dans le sud de la France mais j'interviens sur tout le territoire — sur site pour les phases d'installation, de mise en service et de formation, et à distance pour la conception, le développement firmware et le consulting." + }, + { + question: "Comment financer une formation (OPCO, CPF) ?", + answer: "Les formations peuvent être prises en charge par votre OPCO ou via d'autres dispositifs de financement professionnel. Je vous accompagne dans le montage du dossier et la rédaction du programme pédagogique adapté aux exigences de votre organisme financeur. Contactez-moi pour en discuter." + }, + { + question: "Qu'est-ce qu'un workflow agentique et comment ça s'applique à l'embarqué ?", + answer: "Un workflow agentique utilise des agents IA autonomes pour accélérer les tâches répétitives ou complexes : génération de code firmware, revue de schémas, analyse de datasheets, documentation automatique, tests de régression. Ce n'est pas un remplacement de l'expertise humaine — c'est un multiplicateur de productivité. Je forme les équipes à intégrer ces outils dans leur chaîne de développement existante." + }, + { + question: "Êtes-vous assuré ?", + answer: "Oui. L'électron rare dispose d'une assurance Responsabilité Civile Professionnelle (RC Pro) couvrant l'ensemble des prestations : conception, consulting, formation et intervention sur site. Un accord de confidentialité (NDA) peut également être mis en place sur demande avant tout échange technique." + } +]; + +const jsonLd = { + "@context": "https://schema.org", + "@type": "FAQPage", + "mainEntity": faqItems.map(item => ({ + "@type": "Question", + "name": item.question, + "acceptedAnswer": { + "@type": "Answer", + "text": item.answer + } + })) +}; +--- + +
+
+
+ +

+ Questions fréquentes +

+ +
+ +
+

+ Les réponses aux questions les plus courantes sur mes prestations, mon fonctionnement et mes tarifs. +

+
+ +
+ {faqItems.map((item, index) => ( +
+ + {item.question} + + +
+

{item.answer}

+
+
+ ))} +
+
+ + @@ -137,48 +203,11 @@ const structuredDataJsonLd = JSON.stringify({ (function () { var root = document.documentElement; var params = new URLSearchParams(window.location.search); - var raw = params.get('da') || params.get('variant') || params.get('da-variant') || ''; var uiRaw = params.get('ui') || params.get('sprint') || ''; - var normalized = (raw || '').toLowerCase().trim(); - var uiNormalized = (uiRaw || '').toLowerCase().trim(); - var allowed = { - v1: 1, - v2: 1, - v3: 1, - v4: 1, - v5: 1, - v6: 1, - v7: 1, - v8: 1, - v9: 1, - v10: 1, - v11: 1, - v12: 1, - '1': 1, - '2': 1, - '3': 1, - '4': 1, - '5': 1, - '6': 1, - '7': 1, - '8': 1, - '9': 1, - '10': 1, - '11': 1, - '12': 1 - }; - - var requested = normalized in allowed ? normalized : ''; - var fallbackVariant = 'v12'; - - if (requested && /^[1-9]([0-9])?$/.test(requested) && requested.length <= 2) { - requested = 'v' + requested; - } - var uiAllowed = { a: 1, b: 1 }; - var uiSprint = uiNormalized in uiAllowed ? uiNormalized : 'b'; + var uiSprint = uiRaw.toLowerCase().trim() in uiAllowed ? uiRaw.toLowerCase().trim() : 'b'; - root.setAttribute('data-da-variant', requested || fallbackVariant); + root.setAttribute('data-da-variant', 'v12'); root.setAttribute('data-ui-sprint', uiSprint); })(); @@ -191,7 +220,7 @@ const structuredDataJsonLd = JSON.stringify({ ) } - + Aller au contenu @@ -222,8 +251,6 @@ const structuredDataJsonLd = JSON.stringify({ ); }; - window['__erTrackEvent'] = pushTrackingEvent; - var links = document.querySelectorAll("[data-track]"); for (var i = 0; i < links.length; i += 1) { links[i].addEventListener("click", function () { @@ -239,15 +266,6 @@ const structuredDataJsonLd = JSON.stringify({ pushTrackingEvent('experiment_variant_exposed', { destination: pagePath }); - })(); - - - diff --git a/src/lib/site.ts b/src/lib/site.ts index b3f8d5f..241f1d0 100644 --- a/src/lib/site.ts +++ b/src/lib/site.ts @@ -1,6 +1,10 @@ const normalizeUrl = (value: string) => (value.endsWith('/') ? value : `${value}/`); -const resolvedSiteUrl = import.meta.env.PUBLIC_SITE_URL || 'https://electron-rare.github.io/'; +const resolvedSiteUrl = + import.meta.env.PUBLIC_SITE_URL || + process.env.PUBLIC_SITE_URL || + process.env.EXTERNAL_SITE_URL || + 'https://electron-rare.github.io/'; const parsedSiteUrl = new URL(normalizeUrl(resolvedSiteUrl)); const resolvedBasePath = parsedSiteUrl.pathname === '/' ? '' : parsedSiteUrl.pathname.replace(/\/$/, ''); @@ -50,15 +54,15 @@ export function stripSiteBase(pathname: string) { } export const SITE_META = { - title: "Clément Saillant — L'électron rare", + title: "Électronique embarquée freelance | L'électron rare", description: - "Studio de Clément Saillant (L'électron rare) : création électronique, invention de systèmes, design produit et projets audiovisuels.", + "Design électronique embarquée freelance : prototype, consulting, formation, automatisme industriel, IoT. Du cahier des charges au produit testé.", ogDescription: - "Codeur créatif, itérateur IA et concepteur : création électronique, design produit, systèmes expérimentaux et collaborations visuelles.", + "Design électronique embarquée freelance : prototype, consulting, formation. Industries créatives et industrie. Du diagnostic au produit fini.", twitterDescription: - "Creation electronique, invention de systemes et design produit sous l'identite L'electron rare.", + "Designer électronique embarquée freelance : prototype hardware, consulting & formation. Industries créatives · industrie · IoT.", ogImagePath: 'assets/og-cover.jpg', - themeColor: '#f4eee3' + themeColor: '#0b0d0c' } as const; export const SITE_OG_IMAGE_URL = new URL(SITE_META.ogImagePath, PUBLIC_SITE_ROOT_URL).href; diff --git a/src/lib/tracking.ts b/src/lib/tracking.ts index df24d49..3802055 100644 --- a/src/lib/tracking.ts +++ b/src/lib/tracking.ts @@ -1,25 +1,14 @@ export const TRACK_EVENTS = { - ctaHeroProjects: 'cta_hero_projets', ctaHeroContact: 'cta_hero_contact', - ctaHeroProfile: 'cta_hero_profile', - outboundLinkedinProject: 'outbound_linkedin_project', outboundLinkedinContact: 'outbound_linkedin_contact', - outboundMaltContact: 'outbound_malt_contact', - outboundBandcampProject: 'outbound_bandcamp_project', - outboundBandcampContact: 'outbound_bandcamp_contact', - outboundGithubProject: 'outbound_github_project', - outboundGithubContact: 'outbound_github_contact' + outboundEmailContact: 'outbound_email_contact', + outboundGithubContact: 'outbound_github_contact', + outboundGithubProjectAudioBattery: 'outbound_github_project_audio_battery', + ctaLabInteractifOpen: 'cta_lab_interactif_open' } as const; export type TrackEventName = (typeof TRACK_EVENTS)[keyof typeof TRACK_EVENTS]; -export type TrackEventPayload = { - event: TrackEventName; - event_category: 'engagement'; - event_label: TrackEventName; - destination: string; -}; - export function trackAttrs(event: TrackEventName, destination: string) { return { 'data-track': event, diff --git a/src/lib/types.ts b/src/lib/types.ts deleted file mode 100644 index 34dfce8..0000000 --- a/src/lib/types.ts +++ /dev/null @@ -1,9 +0,0 @@ -import type { TrackEventName } from '@/lib/tracking'; - -export type CtaLink = { - label: string; - href: string; - event: TrackEventName; - destination: string; - external?: boolean; -}; diff --git a/src/lib/utils.ts b/src/lib/utils.ts deleted file mode 100644 index 2819a83..0000000 --- a/src/lib/utils.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { clsx, type ClassValue } from 'clsx'; -import { twMerge } from 'tailwind-merge'; - -export function cn(...inputs: ClassValue[]) { - return twMerge(clsx(inputs)); -} diff --git a/src/pages/formation.astro b/src/pages/formation.astro new file mode 100644 index 0000000..bf56e79 --- /dev/null +++ b/src/pages/formation.astro @@ -0,0 +1,274 @@ +--- +import BaseLayout from '@/layouts/BaseLayout.astro'; +import '@/styles/global.css'; +import '@/styles/home-workbench.css'; +import { withSiteBase } from '@/lib/site'; +import { TRACK_EVENTS, trackAttrs } from '@/lib/tracking'; + +const title = "Formation embarquée | L'électron rare"; +const description = "Formations sur mesure : électronique embarquée, PCB, IoT, automatisme. 1 jour, 3 jours ou programme dédié. Écoles, entreprises."; +const homeHref = withSiteBase('/'); +const homeAboutHref = withSiteBase('/#a-propos'); +const homeMissionsHref = withSiteBase('/#graphic-sprints-title'); +const formationHref = withSiteBase('/formation/'); +const contactHref = withSiteBase('/#contact'); +const labHref = withSiteBase('/lab/'); +const mentionsHref = withSiteBase('/mentions-legales/'); +--- + + + + +
+ +
+
+ +

Formation électronique embarquée

+ +
+ +

+ Des formations pratiques, ancrées dans le terrain, pour monter en compétences sur l'électronique embarquée, la conception PCB, l'IoT et l'automatisme industriel. +

+

+ Chaque formation est construite sur mesure à partir de votre contexte réel : vos projets, vos équipes, vos contraintes. Pas de slides génériques — du bench, du schéma et du livrable. +

+
+ +
+
+ +

Publics cibles

+ +
+ +
+
    +
  • + Entreprises industrielles — équipes R&D, bureaux d'études, techniciens de maintenance qui veulent intégrer l'embarqué dans leurs produits ou process. +
  • +
  • + Écoles et universités — BTS, IUT, grandes écoles : TP encadrés, projets tutorés, modules spécialisés en électronique embarquée. +
  • +
  • + Centres de formation — organismes souhaitant intégrer des modules électronique embarquée, IoT ou automatisme à leur catalogue. +
  • +
  • + Studios créatifs et compagnies — équipes techniques du spectacle vivant, de l'événementiel ou des arts numériques qui veulent gagner en autonomie. +
  • +
+
+
+ +
+
+
+

Formats

+

Trois formats, un principe : le concret d'abord

+

+ Chaque format inclut un support de cours, des exercices pratiques sur matériel réel et un livrable que les participants repartent avec. +

+
+ +
+
+
+

Initiation

+

1 jour (7h)

+
+

Découverte

+

+ Comprendre les fondamentaux d'un domaine technique. Idéal pour une première prise en main ou une mise à niveau rapide. +

+
+ +
+
    +
  • Théorie appliquée + démos live
  • +
  • TP sur matériel réel
  • +
  • Support de cours PDF
  • +
+
+ +
+
+

Approfondissement

+

3 jours (21h)

+
+

Pratique

+

+ Maîtriser un sujet de bout en bout avec un projet fil rouge. Les participants repartent avec un prototype fonctionnel. +

+
+ +
+
    +
  • Projet fil rouge réalisé
  • +
  • Prototype fonctionnel
  • +
  • Documentation technique complète
  • +
+
+ +
+
+

Sur mesure

+

Durée adaptée

+
+

Programme dédié

+

+ Formation construite intégralement autour de votre projet, vos équipements et vos objectifs. Accompagnement post-formation inclus. +

+
+ +
+
    +
  • Programme sur mesure
  • +
  • Matériel adapté à votre contexte
  • +
  • Suivi post-formation
  • +
+
+
+
+
+ +
+
+ +

Sujets de formation

+ +
+ +
+
+

Électronique embarquée

+

+ Architecture matérielle, microcontrôleurs (STM32, ESP32, Teensy), alimentation, lecture de datasheet, debug sur bench. Conformité IPC-A-610 et CEM. +

+
+ +
+

Conception PCB

+

+ De la schématique au routage avec KiCad. Règles de design, stackup, vérification DRC/ERC, préparation des fichiers de fabrication (Gerber, BOM, pick & place). +

+
+ +
+

IoT et protocoles

+

+ Capteurs, télémétrie, protocoles terrain (MQTT, HTTP, VE.Direct), connectivité (WiFi, BLE, LoRa), TinyML et IA embarquée. Du capteur au dashboard. +

+
+ +
+

Automatisme industriel

+

+ Automates Siemens (S7) et Schneider, câblage d'armoires, variateurs, mise en service. Conformité IEC 60204-1, IEC 61439, NFC 13-200. Lecture de schémas électriques industriels. +

+
+ +
+

Contrôle LED et scénographie

+

+ Protocoles DMX, Art-Net, DANTE. Pilotage LED, topologies multi-cartes, intégration dans des dispositifs scéniques et événementiels. +

+
+ +
+

Firmware et programmation

+

+ C/C++ embarqué, Python pour l'instrumentation, debug série, gestion mémoire, interruptions, RTOS. Du code qui tourne sur le terrain. +

+
+ +
+

Workflows agentiques et IA appliquée

+

+ Intégrer l'IA et les agents autonomes dans vos flux de travail : génération de code embarqué, revue automatisée, documentation technique, analyse de datasheets et tests assistés par IA. Productivité et qualité augmentées. +

+
+
+
+ +
+
+ +

Demander un programme

+ +
+ +

+ Décrivez votre besoin en quelques lignes. Je vous propose un programme adapté sous 48h. +

+

+ Précisez le public, le niveau, le sujet visé et le format souhaité. Même une idée vague suffit pour démarrer. +

+ + + +
    +
  • Intervention en présentiel (France entière) ou en distanciel
  • +
  • Matériel de TP fourni ou adapté à votre parc existant
  • +
  • Convention de formation et programme détaillé sur demande
  • +
  • Intervention possible via un organisme certifié Qualiopi pour le financement OPCO
  • +
  • Assuré RC Pro · NDA sur demande
  • +
+
+ +
+ + +
diff --git a/src/pages/index.astro b/src/pages/index.astro index a6e6c83..d07b837 100644 --- a/src/pages/index.astro +++ b/src/pages/index.astro @@ -1,156 +1,156 @@ --- import BaseLayout from '@/layouts/BaseLayout.astro'; import '@/styles/global.css'; +import '@/styles/home-workbench.css'; import { Hero } from '@/components/sections/Hero'; -import { GraphicSprints } from '@/components/sections/GraphicSprints'; -import { IdentityLab } from '@/components/sections/IdentityLab'; import { About } from '@/components/sections/About'; -import { Projects } from '@/components/sections/Projects'; -import { FlowDiagram } from '@/components/sections/FlowDiagram'; -import { SystemPipeline } from '@/components/sections/SystemPipeline'; -import { ProjectsTimeline } from '@/components/sections/ProjectsTimeline'; -import { LabNotes } from '@/components/sections/LabNotes'; -import { TrustStrip } from '@/components/sections/TrustStrip'; -import { Contact } from '@/components/sections/Contact'; +import { CaseStudies } from '@/components/sections/CaseStudies'; +import { GraphicSprints } from '@/components/sections/GraphicSprints'; +import Contact from '@/components/sections/Contact.astro'; +import Faq from '@/components/sections/Faq.astro'; +import { withSiteBase } from '@/lib/site'; import { TRACK_EVENTS, trackAttrs } from '@/lib/tracking'; + +const formationHref = withSiteBase('/formation/'); +const labHref = withSiteBase('/lab/'); +const mentionsHref = withSiteBase('/mentions-legales/'); --- -
+
- -
-
- +
-
-
- Process / cadrage - Architecture / cible - Production / prototype +
+
+ +
+
- Impact / risque - Conversion / preuve - Handoff / delivery +
+
+ +
+
- Process / sprint - Architecture / interfaces - Production / sur mesure +
+
+ PCB custom Teensy LED — projet spectacle vivant KXKM + Câblage automate industriel — intervention terrain + Banc de test BMS batteries — prototypage + Automate Siemens S7 — diagnostic industriel + Soudure PCB — formation et prototypage + Instrumentation et mesure — oscilloscope + Rack CBTC transport — connectique industrielle + Carte embarquée en test — validation prototype + Armoire Schneider — automatisme industriel + Atelier professionnel — outillage organisé +
+
+ +
+
+ + +
- +
-
-
- -
-
- -
-
- -
-
- -
-
- -
-
- -
-
- +
+
+
-
- -
- +
diff --git a/src/pages/mentions-legales.astro b/src/pages/mentions-legales.astro new file mode 100644 index 0000000..bb3ea2b --- /dev/null +++ b/src/pages/mentions-legales.astro @@ -0,0 +1,186 @@ +--- +import BaseLayout from '@/layouts/BaseLayout.astro'; +import '@/styles/global.css'; +import '@/styles/home-workbench.css'; +import { withSiteBase } from '@/lib/site'; + +const title = "Mentions légales — L'électron rare"; +const description = "Mentions légales du site lelectronrare.fr — éditeur, hébergeur, propriété intellectuelle, données personnelles et RGPD."; +const homeHref = withSiteBase('/'); +const homeAboutHref = withSiteBase('/#a-propos'); +const homeMissionsHref = withSiteBase('/#graphic-sprints-title'); +const formationHref = withSiteBase('/formation/'); +const contactHref = withSiteBase('/#contact'); +const labHref = withSiteBase('/lab/'); +const mentionsHref = withSiteBase('/mentions-legales/'); +--- + + + + +
+ +
+
+ +

Mentions légales

+ +
+

+ Conformément aux dispositions de la loi n° 2004-575 du 21 juin 2004 pour la confiance dans l'économie numérique (LCEN), il est porté à la connaissance des utilisateurs et visiteurs du site lelectronrare.fr les présentes mentions légales. +

+
+ +
+
+ +

Éditeur du site

+ +
+
+
    +
  • Nom : Clément Saillant
  • +
  • Statut : Entrepreneur individuel
  • +
  • Nom commercial : L'Électron Rare
  • +
  • SIRET : en cours de mise à jour
  • +
  • Adresse : en cours de mise à jour
  • +
  • Téléphone : en cours de mise à jour
  • +
  • Email : contact@lelectronrare.fr
  • +
  • Directeur de la publication : Clément Saillant
  • +
+
+
+ +
+
+ +

Hébergeur

+ +
+
+
    +
  • Raison sociale : OVH SAS
  • +
  • Adresse : 2 rue Kellermann, 59100 Roubaix, France
  • +
  • Téléphone : 1007
  • +
  • Site web : www.ovhcloud.com
  • +
+
+
+ +
+
+ +

Propriété intellectuelle

+ +
+

+ L'ensemble du contenu de ce site (textes, images, photographies, illustrations, vidéos, structure, mise en page, logos) est la propriété exclusive de Clément Saillant / L'Électron Rare, sauf mention contraire explicite. +

+

+ Toute reproduction, représentation, modification, publication, adaptation, totale ou partielle, de l'un quelconque de ces éléments, par quelque moyen ou procédé que ce soit, est interdite sans l'autorisation écrite préalable de Clément Saillant. +

+

+ Toute exploitation non autorisée du site ou de l'un quelconque des éléments qu'il contient sera considérée comme constitutive d'une contrefaçon et poursuivie conformément aux dispositions des articles L.335-2 et suivants du Code de la propriété intellectuelle. +

+
+ +
+
+ +

Données personnelles et RGPD

+ +
+

+ Conformément au Règlement Général sur la Protection des Données (RGPD — Règlement UE 2016/679) et à la loi Informatique et Libertés du 6 janvier 1978 modifiée, vous disposez d'un droit d'accès, de rectification, de suppression et d'opposition aux données personnelles vous concernant. +

+

+ Pour exercer ces droits, vous pouvez contacter : contact@lelectronrare.fr +

+ +

Cookies et mesure d'audience

+

+ Ce site utilise Google Tag Manager (identifiant : GTM-5SLM67QF) et Google Analytics à des fins de mesure d'audience et d'amélioration du site. Ces outils peuvent déposer des cookies sur votre navigateur afin de collecter des données anonymisées sur votre navigation (pages visitées, durée de visite, type d'appareil). +

+

+ Aucun cookie à finalité publicitaire ou de marketing direct n'est déposé par ce site. Les données collectées ne sont pas revendues ni transmises à des tiers à des fins commerciales. +

+

+ Vous pouvez à tout moment désactiver les cookies via les paramètres de votre navigateur ou en utilisant un outil de blocage tel que Google Analytics Opt-out. +

+ +

Formulaire de contact

+

+ Les informations recueillies via le formulaire de contact (nom, email, message) sont uniquement utilisées pour répondre à votre demande. Elles ne sont ni stockées dans une base de données, ni transmises à des tiers. La base légale du traitement est votre consentement (article 6.1.a du RGPD). +

+
+ +
+
+ +

Responsabilité

+ +
+

+ L'éditeur du site s'efforce de fournir des informations aussi précises que possible. Toutefois, il ne pourra être tenu responsable des omissions, des inexactitudes ou des carences dans la mise à jour, qu'elles soient de son fait ou du fait de tiers partenaires qui lui fournissent ces informations. +

+

+ L'éditeur du site décline toute responsabilité en cas de difficulté d'accès au site ou d'interruptions de service, de virus informatiques ou de tout dommage résultant de l'utilisation du site. +

+

+ Les liens hypertextes présents sur le site peuvent renvoyer vers d'autres sites internet. L'éditeur ne saurait être tenu responsable du contenu de ces sites tiers. +

+
+ +
+
+ +

Droit applicable

+ +
+

+ Le présent site et ses mentions légales sont régis par le droit français. En cas de litige, et après tentative de résolution amiable, compétence est attribuée aux tribunaux français compétents. +

+

+ Dernière mise à jour : mars 2026. +

+
+ +
+ + +
diff --git a/src/pages/robots.txt.ts b/src/pages/robots.txt.ts new file mode 100644 index 0000000..d17077a --- /dev/null +++ b/src/pages/robots.txt.ts @@ -0,0 +1,18 @@ +import type { APIRoute } from 'astro'; +import { CANONICAL_URL, SITE_IS_SUBPATH_BUILD } from '../lib/site'; + +export const GET: APIRoute = () => { + const body = SITE_IS_SUBPATH_BUILD + ? `User-agent: * +Disallow: / +` + : `User-agent: * +Allow: / + +Sitemap: ${CANONICAL_URL}sitemap.xml +`; + + return new Response(body, { + headers: { 'Content-Type': 'text/plain; charset=utf-8' } + }); +}; diff --git a/src/pages/sitemap.xml.ts b/src/pages/sitemap.xml.ts new file mode 100644 index 0000000..93706c0 --- /dev/null +++ b/src/pages/sitemap.xml.ts @@ -0,0 +1,33 @@ +import type { APIRoute } from 'astro'; +import { CANONICAL_URL, PUBLIC_SITE_ROOT_URL, SITE_IS_SUBPATH_BUILD } from '../lib/site'; + +export const GET: APIRoute = () => { + const sitemapRootUrl = SITE_IS_SUBPATH_BUILD ? PUBLIC_SITE_ROOT_URL : CANONICAL_URL; + const pages = [ + { path: '', priority: '1.0', changefreq: 'weekly' }, + { path: 'formation/', priority: '0.9', changefreq: 'monthly' }, + { path: 'lab/', priority: '0.8', changefreq: 'weekly' }, + { path: 'mentions-legales/', priority: '0.3', changefreq: 'yearly' } + ]; + + const urls = pages + .map( + (page) => ` + ${new URL(page.path, sitemapRootUrl).href} + ${new Date().toISOString().split('T')[0]} + ${page.changefreq} + ${page.priority} + ` + ) + .join('\n'); + + const body = ` + +${urls} + +`; + + return new Response(body, { + headers: { 'Content-Type': 'application/xml; charset=utf-8' } + }); +}; diff --git a/src/styles/fonts.css b/src/styles/fonts.css new file mode 100644 index 0000000..569931c --- /dev/null +++ b/src/styles/fonts.css @@ -0,0 +1,119 @@ +/* Self-hosted Google Fonts — latin + latin-ext only */ + +/* Fraunces (variable: opsz 9-144, weights 500+700) */ +@font-face { + font-family: 'Fraunces'; + font-style: normal; + font-weight: 500 700; + font-display: swap; + src: url('/assets/fonts/fraunces-latin-ext.woff2') format('woff2'); + unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF; +} +@font-face { + font-family: 'Fraunces'; + font-style: normal; + font-weight: 500 700; + font-display: swap; + src: url('/assets/fonts/fraunces-latin.woff2') format('woff2'); + unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; +} + +/* IBM Plex Mono 400 */ +@font-face { + font-family: 'IBM Plex Mono'; + font-style: normal; + font-weight: 400; + font-display: swap; + src: url('/assets/fonts/ibm-plex-mono-400-latin-ext.woff2') format('woff2'); + unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF; +} +@font-face { + font-family: 'IBM Plex Mono'; + font-style: normal; + font-weight: 400; + font-display: swap; + src: url('/assets/fonts/ibm-plex-mono-400-latin.woff2') format('woff2'); + unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; +} + +/* IBM Plex Mono 500 */ +@font-face { + font-family: 'IBM Plex Mono'; + font-style: normal; + font-weight: 500; + font-display: swap; + src: url('/assets/fonts/ibm-plex-mono-500-latin-ext.woff2') format('woff2'); + unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF; +} +@font-face { + font-family: 'IBM Plex Mono'; + font-style: normal; + font-weight: 500; + font-display: swap; + src: url('/assets/fonts/ibm-plex-mono-500-latin.woff2') format('woff2'); + unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; +} + +/* IBM Plex Mono 600 */ +@font-face { + font-family: 'IBM Plex Mono'; + font-style: normal; + font-weight: 600; + font-display: swap; + src: url('/assets/fonts/ibm-plex-mono-600-latin-ext.woff2') format('woff2'); + unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF; +} +@font-face { + font-family: 'IBM Plex Mono'; + font-style: normal; + font-weight: 600; + font-display: swap; + src: url('/assets/fonts/ibm-plex-mono-600-latin.woff2') format('woff2'); + unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; +} + +/* Manrope (variable: weights 400-700) */ +@font-face { + font-family: 'Manrope'; + font-style: normal; + font-weight: 400 700; + font-display: swap; + src: url('/assets/fonts/manrope-latin-ext.woff2') format('woff2'); + unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF; +} +@font-face { + font-family: 'Manrope'; + font-style: normal; + font-weight: 400 700; + font-display: swap; + src: url('/assets/fonts/manrope-latin.woff2') format('woff2'); + unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; +} + +/* Share Tech Mono */ +@font-face { + font-family: 'Share Tech Mono'; + font-style: normal; + font-weight: 400; + font-display: swap; + src: url('/assets/fonts/share-tech-mono-latin.woff2') format('woff2'); + unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; +} + +/* VT323 */ +@font-face { + font-family: 'VT323'; + font-style: normal; + font-weight: 400; + font-display: swap; + src: url('/assets/fonts/vt323-latin-ext.woff2') format('woff2'); + unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF; +} +@font-face { + font-family: 'VT323'; + font-style: normal; + font-weight: 400; + font-display: swap; + src: url('/assets/fonts/vt323-latin.woff2') format('woff2'); + unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; +} diff --git a/src/styles/global.css b/src/styles/global.css index 4257ad1..ba5bb17 100644 --- a/src/styles/global.css +++ b/src/styles/global.css @@ -1,4 +1,3 @@ -@import url("https://fonts.googleapis.com/css2?family=Fraunces:opsz,wght@9..144,500;9..144,700&family=IBM+Plex+Mono:wght@400;500;600&family=Manrope:wght@400;500;600;700&display=swap"); @import "tailwindcss"; * { @@ -35,27 +34,6 @@ body { sans-serif; line-height: 1.55; } -@supports (color: color-mix(in lab, red, red)) { - body { - background: - radial-gradient( - 1200px 700px at -10% -20%, - color-mix(in oklab, var(--signal) 14%, transparent), - transparent 60% - ), - radial-gradient( - 900px 520px at 110% 0%, - color-mix(in oklab, var(--electric) 14%, transparent), - transparent 65% - ), - linear-gradient( - 180deg, - var(--pcb-deep) 0%, - color-mix(in oklab, var(--pcb-core) 78%, var(--bg) 22%) 52%, - var(--bg) 100% - ); - } -} body { text-rendering: optimizelegibility; background-attachment: fixed; @@ -73,17 +51,6 @@ body:before { position: fixed; inset: 0; } -@supports (color: color-mix(in lab, red, red)) { - body:before { - background-image: repeating-linear-gradient( - 0deg, - color-mix(in oklab, var(--line) 20%, transparent) 0px, - color-mix(in oklab, var(--line) 20%, transparent) 1px, - transparent 1px, - transparent 5px - ); - } -} body:before { opacity: 0.7; mix-blend-mode: soft-light; @@ -98,21 +65,6 @@ body:after { position: fixed; inset: 0; } -@supports (color: color-mix(in lab, red, red)) { - body:after { - background-image: - linear-gradient( - to right, - color-mix(in oklab, var(--line-rail) 75%, transparent) 1px, - transparent 1px - ), - linear-gradient( - to bottom, - color-mix(in oklab, var(--line-rail) 75%, transparent) 1px, - transparent 1px - ); - } -} body:after { opacity: 0.58; z-index: -1; @@ -147,11 +99,6 @@ h3 { color: var(--text); background: color-mix(in oklab, var(--electric) 28%, transparent); } -@supports (color: color-mix(in lab, red, red)) { - ::selection { - color: color-mix(in oklab, var(--text) 92%, black 8%); - } -} .site-shell { width: min(1120px, 92vw); margin: 0 auto; @@ -173,11 +120,6 @@ h3 { top: 0; overflow: hidden; } -@supports (color: color-mix(in lab, red, red)) { - .site-nav { - background: color-mix(in oklab, var(--pcb-core) 72%, transparent); - } -} .site-nav { border-bottom: 1px solid var(--line-edge); transition: @@ -227,19 +169,9 @@ h3 { padding 0.2s, gap 0.2s; } -@supports (color: color-mix(in lab, red, red)) { - .site-nav.is-compact { - background: color-mix(in oklab, var(--pcb-core) 84%, transparent); - } -} .site-nav.is-compact { border-bottom-color: var(--line-edge); } -@supports (color: color-mix(in lab, red, red)) { - .site-nav.is-compact { - border-bottom-color: color-mix(in oklab, var(--line-edge) 92%, transparent); - } -} .site-nav.is-compact .site-shell { padding-top: 0.48rem; padding-bottom: 0.48rem; @@ -267,9 +199,6 @@ h3 { .site-navlink { min-height: 2.1rem; color: var(--text); - --nav-jitter-x: 0.45px; - --nav-jitter-y: 0.35px; - --nav-jitter-r: 0.18deg; text-shadow: 0 0 #0000; border: 1px solid #0000; border-radius: 0.6rem; @@ -323,32 +252,10 @@ h3 { .site-navlink:focus-visible { border-color: var(--trace-cyan-soft); } -@supports (color: color-mix(in lab, red, red)) { - .site-navlink:hover, - .site-navlink:focus-visible { - border-color: color-mix(in oklab, var(--trace-cyan-soft) 70%, transparent); - } -} -@supports (color: color-mix(in lab, red, red)) { - .site-navlink:hover, - .site-navlink:focus-visible { - background: linear-gradient( - 120deg, - color-mix(in oklab, var(--trace-cyan) 17%, transparent), - color-mix(in oklab, var(--accent) 10%, transparent) - ); - } -} .site-navlink:hover, .site-navlink:focus-visible { color: var(--text); } -@supports (color: color-mix(in lab, red, red)) { - .site-navlink:hover, - .site-navlink:focus-visible { - color: color-mix(in oklab, var(--text) 90%, var(--electric) 10%); - } -} .site-navlink:hover, .site-navlink:focus-visible { text-shadow: none; @@ -369,28 +276,6 @@ h3 { opacity: 1; transform: scaleX(1); } -@supports (color: color-mix(in lab, red, red)) { - .site-navlink.is-active, - .site-navlink[aria-current="location"] { - border-color: color-mix(in oklab, var(--trace-cyan) 72%, transparent); - } -} -@supports (color: color-mix(in lab, red, red)) { - .site-navlink.is-active, - .site-navlink[aria-current="location"] { - background: linear-gradient( - 120deg, - color-mix(in oklab, var(--trace-cyan) 28%, transparent), - color-mix(in oklab, var(--accent) 18%, transparent) - ); - } -} -@supports (color: color-mix(in lab, red, red)) { - .site-navlink.is-active, - .site-navlink[aria-current="location"] { - color: color-mix(in oklab, var(--text) 88%, var(--electric) 12%); - } -} .site-navlink.is-active, .site-navlink[aria-current="location"] { animation: 1.9s ease-in-out infinite navLinkPulse; @@ -417,19 +302,9 @@ h3 { font-size: 0.68rem; display: inline-flex; } -@supports (color: color-mix(in lab, red, red)) { - .lab-kicker { - color: color-mix(in oklab, var(--signal) 85%, #fff 15%); - } -} .lab-kicker { background: var(--signal); } -@supports (color: color-mix(in lab, red, red)) { - .lab-kicker { - background: color-mix(in oklab, var(--signal) 20%, transparent); - } -} .lab-pill { letter-spacing: 0.09em; text-transform: uppercase; @@ -442,20 +317,6 @@ h3 { font-size: 0.72rem; display: inline-flex; } -@supports (color: color-mix(in lab, red, red)) { - .lab-pill { - color: color-mix(in oklab, var(--electric) 85%, #fff 15%); - } -} -@supports (color: color-mix(in lab, red, red)) { - .lab-pill { - background: linear-gradient( - 90deg, - color-mix(in oklab, var(--electric) 16%, transparent), - color-mix(in oklab, var(--accent) 14%, transparent) - ); - } -} .lab-pill { box-shadow: inset 0 0 0 1px #ffffff08; } @@ -465,13 +326,6 @@ h3 { border: 1px solid var(--line); position: relative; } -@supports (color: color-mix(in lab, red, red)) { - .lab-panel, - .circuit-board, - .studio-panel { - border: 1px solid color-mix(in oklab, var(--line) 82%, transparent); - } -} .lab-panel, .circuit-board, .studio-panel { @@ -509,7 +363,7 @@ h3 { .lab-panel, .circuit-board, .studio-panel { - border-radius: 1.1rem; + border-radius: var(--card-radius); overflow: hidden; box-shadow: 0 18px 40px rgba(77, 60, 32, 0.18), @@ -570,8 +424,7 @@ h3 { position: absolute; inset: 14px; } -.circuit-board .circuit-title-row:after, -.circuit-board .flow-title-row:after { +.circuit-board .circuit-title-row:after { content: ""; border: 1px solid var(--line-soft); border-radius: 999px; @@ -579,55 +432,23 @@ h3 { height: 0.42rem; display: block; } -@supports (color: color-mix(in lab, red, red)) { - .circuit-board .circuit-title-row:after, - .circuit-board .flow-title-row:after { - border: 1px solid color-mix(in oklab, var(--line-soft) 72%, transparent); - } -} -.circuit-board .circuit-title-row:after, -.circuit-board .flow-title-row:after { +.circuit-board .circuit-title-row:after { background: repeating-linear-gradient( 90deg, var(--trace-cyan) 0 0.35rem, transparent 0.35rem 0.68rem ); } -@supports (color: color-mix(in lab, red, red)) { - .circuit-board .circuit-title-row:after, - .circuit-board .flow-title-row:after { - background: repeating-linear-gradient( - 90deg, - color-mix(in oklab, var(--trace-cyan) 55%, transparent) 0 0.35rem, - transparent 0.35rem 0.68rem - ); - } -} -.circuit-board .circuit-title-row:after, -.circuit-board .flow-title-row:after { +.circuit-board .circuit-title-row:after { opacity: 0.75; } .circuit-card { border: 1px solid var(--line-soft); position: relative; } -@supports (color: color-mix(in lab, red, red)) { - .circuit-card { - border: 1px solid color-mix(in oklab, var(--line-soft) 80%, transparent); - } -} .circuit-card { background: linear-gradient(180deg, var(--surface), var(--surface-alt)); - border-radius: 1rem; -} -@supports (color: color-mix(in lab, red, red)) { - .circuit-card { - background: linear-gradient( - 180deg, - color-mix(in oklab, var(--surface) 92%, transparent), - color-mix(in oklab, var(--surface-alt) 92%, var(--signal) 8%) - ); - } + border-radius: var(--card-radius); } .circuit-card { overflow: hidden; @@ -663,11 +484,6 @@ h3 { left: 0.6rem; right: 0.6rem; } -@supports (color: color-mix(in lab, red, red)) { - .circuit-card:after { - border-top: 1px solid color-mix(in oklab, var(--line) 65%, transparent); - } -} .circuit-card:after { background: repeating-linear-gradient( 90deg, @@ -675,15 +491,6 @@ h3 { transparent 0.25rem 0.55rem ); } -@supports (color: color-mix(in lab, red, red)) { - .circuit-card:after { - background: repeating-linear-gradient( - 90deg, - color-mix(in oklab, var(--trace-green-soft) 55%, transparent) 0 0.25rem, - transparent 0.25rem 0.55rem - ); - } -} .circuit-card:after { opacity: 0.5; pointer-events: none; @@ -700,11 +507,6 @@ h3 { height: 0.56rem; display: inline-block; } -@supports (color: color-mix(in lab, red, red)) { - .circuit-node { - border: 1px solid color-mix(in oklab, var(--trace-cyan) 45%, black); - } -} .circuit-node { position: relative; transform: translateZ(0); @@ -715,12 +517,6 @@ h3 { background: var(--trace-cyan); position: absolute; } -@supports (color: color-mix(in lab, red, red)) { - .circuit-node:before, - .circuit-node:after { - background: color-mix(in oklab, var(--trace-cyan) 72%, transparent); - } -} .circuit-node:before { width: 1.1rem; height: 1px; @@ -742,12 +538,6 @@ h3 { .circuit-node--magenta:after { background: var(--trace-magenta); } -@supports (color: color-mix(in lab, red, red)) { - .circuit-node--magenta:before, - .circuit-node--magenta:after { - background: color-mix(in oklab, var(--trace-magenta) 72%, transparent); - } -} .circuit-node--green { background: var(--trace-green-soft); } @@ -755,12 +545,6 @@ h3 { .circuit-node--green:after { background: var(--trace-green); } -@supports (color: color-mix(in lab, red, red)) { - .circuit-node--green:before, - .circuit-node--green:after { - background: color-mix(in oklab, var(--trace-green) 72%, transparent); - } -} .circuit-pinline { align-items: center; gap: 0.35rem; @@ -785,8 +569,7 @@ h3 { margin-bottom: 0.55rem; display: inline-flex; } -.circuit-title-row h2, -.section-title { +.circuit-title-row h2 { margin: 0; } .circuit-board-rail { @@ -795,12 +578,6 @@ h3 { margin-top: 1.15rem; display: grid; } -@supports (color: color-mix(in lab, red, red)) { - .circuit-board-rail { - border-left: 1px dashed - color-mix(in oklab, var(--line-rail) 100%, transparent); - } -} .circuit-board-rail { padding-left: 0.85rem; } @@ -808,86 +585,306 @@ h3 { .circuit-board-rail > div { margin: 0; } -.lab-metric { - background: color-mix(in oklab, var(--surface) 82%, transparent); - border: 1px solid color-mix(in oklab, var(--line-soft) 78%, transparent); - border-radius: 0.7rem; - padding: 0.5rem 0.6rem; - position: relative; - overflow: hidden; -} -.lab-metric:before { - content: ""; - pointer-events: none; - border: 1px solid color-mix(in oklab, var(--electric) 22%, transparent); - border-radius: 0.5rem; - position: absolute; - inset: 6px; -} -.lab-metric:after { - content: ""; - background: linear-gradient( - 90deg, - transparent, - var(--trace-amber-soft), - transparent - ); - opacity: 0.72; - border-radius: 999px; - height: 2px; - position: absolute; - top: 0.38rem; - left: 0.45rem; - right: 0.45rem; -} -.lab-metric span { - color: var(--text-dim); - letter-spacing: 0.08em; - text-transform: uppercase; - font-size: 0.68rem; - display: block; -} -.lab-metric strong { - color: var(--text); - margin-top: 0.12rem; - font-size: 0.84rem; - display: block; -} -.lab-glow { - animation: 5.5s ease-in-out infinite labPulse; -} -@keyframes labPulse { - 0%, - to { - box-shadow: 0 0 0 0 transparent; + +/* ── Consolidated color-mix enhancements (base styles) ── */ +@supports (color: color-mix(in lab, red, red)) { + + body { + background: + radial-gradient( + 1200px 700px at -10% -20%, + color-mix(in oklab, var(--signal) 14%, transparent), + transparent 60% + ), + radial-gradient( + 900px 520px at 110% 0%, + color-mix(in oklab, var(--electric) 14%, transparent), + transparent 65% + ), + linear-gradient( + 180deg, + var(--pcb-deep) 0%, + color-mix(in oklab, var(--pcb-core) 78%, var(--bg) 22%) 52%, + var(--bg) 100% + ); } - 50% { - box-shadow: 0 0 0 10px color-mix(in oklab, var(--electric) 12%, transparent); - } -} -@keyframes gridDrift { - 0% { - background-position: - 0 0, - 0 0, - 0 0; - } - to { - background-position: - 38px 0, - 0 38px, - 0 76px; - } -} -@keyframes boardScan { - 0%, - to { - opacity: 0.42; - } - 50% { - opacity: 0.72; + + body:before { + background-image: repeating-linear-gradient( + 0deg, + color-mix(in oklab, var(--line) 20%, transparent) 0px, + color-mix(in oklab, var(--line) 20%, transparent) 1px, + transparent 1px, + transparent 5px + ); } + + body:after { + background-image: + linear-gradient( + to right, + color-mix(in oklab, var(--line-rail) 75%, transparent) 1px, + transparent 1px + ), + linear-gradient( + to bottom, + color-mix(in oklab, var(--line-rail) 75%, transparent) 1px, + transparent 1px + ); + } + + ::selection { + color: color-mix(in oklab, var(--text) 92%, black 8%); + } + + .site-nav { + background: color-mix(in oklab, var(--pcb-core) 72%, transparent); + } + + .site-nav.is-compact { + background: color-mix(in oklab, var(--pcb-core) 84%, transparent); + } + + .site-nav.is-compact { + border-bottom-color: color-mix(in oklab, var(--line-edge) 92%, transparent); + } + + .site-navlink:hover, + .site-navlink:focus-visible { + border-color: color-mix(in oklab, var(--trace-cyan-soft) 70%, transparent); + } + + .site-navlink:hover, + .site-navlink:focus-visible { + background: linear-gradient( + 120deg, + color-mix(in oklab, var(--trace-cyan) 17%, transparent), + color-mix(in oklab, var(--accent) 10%, transparent) + ); + } + + .site-navlink:hover, + .site-navlink:focus-visible { + color: color-mix(in oklab, var(--text) 90%, var(--electric) 10%); + } + + .site-navlink.is-active, + .site-navlink[aria-current="location"] { + border-color: color-mix(in oklab, var(--trace-cyan) 72%, transparent); + } + + .site-navlink.is-active, + .site-navlink[aria-current="location"] { + background: linear-gradient( + 120deg, + color-mix(in oklab, var(--trace-cyan) 28%, transparent), + color-mix(in oklab, var(--accent) 18%, transparent) + ); + } + + .site-navlink.is-active, + .site-navlink[aria-current="location"] { + color: color-mix(in oklab, var(--text) 88%, var(--electric) 12%); + } + + .lab-kicker { + color: color-mix(in oklab, var(--signal) 85%, #fff 15%); + } + + .lab-kicker { + background: color-mix(in oklab, var(--signal) 20%, transparent); + } + + .lab-pill { + color: color-mix(in oklab, var(--electric) 85%, #fff 15%); + } + + .lab-pill { + background: linear-gradient( + 90deg, + color-mix(in oklab, var(--electric) 16%, transparent), + color-mix(in oklab, var(--accent) 14%, transparent) + ); + } + + .lab-panel, + .circuit-board, + .studio-panel { + border: 1px solid color-mix(in oklab, var(--line) 82%, transparent); + } + + .circuit-board .circuit-title-row:after { + border: 1px solid color-mix(in oklab, var(--line-soft) 72%, transparent); + } + + .circuit-board .circuit-title-row:after { + background: repeating-linear-gradient( + 90deg, + color-mix(in oklab, var(--trace-cyan) 55%, transparent) 0 0.35rem, + transparent 0.35rem 0.68rem + ); + } + + .circuit-card { + border: 1px solid color-mix(in oklab, var(--line-soft) 80%, transparent); + } + + .circuit-card { + background: linear-gradient( + 180deg, + color-mix(in oklab, var(--surface) 92%, transparent), + color-mix(in oklab, var(--surface-alt) 92%, var(--signal) 8%) + ); + } + + .circuit-card:after { + border-top: 1px solid color-mix(in oklab, var(--line) 65%, transparent); + } + + .circuit-card:after { + background: repeating-linear-gradient( + 90deg, + color-mix(in oklab, var(--trace-green-soft) 55%, transparent) 0 0.25rem, + transparent 0.25rem 0.55rem + ); + } + + .circuit-node { + border: 1px solid color-mix(in oklab, var(--trace-cyan) 45%, black); + } + + .circuit-node:before, + .circuit-node:after { + background: color-mix(in oklab, var(--trace-cyan) 72%, transparent); + } + + .circuit-node--magenta:before, + .circuit-node--magenta:after { + background: color-mix(in oklab, var(--trace-magenta) 72%, transparent); + } + + .circuit-node--green:before, + .circuit-node--green:after { + background: color-mix(in oklab, var(--trace-green) 72%, transparent); + } + + .circuit-board-rail { + border-left: 1px dashed + color-mix(in oklab, var(--line-rail) 100%, transparent); + } + + .studio-chip { + border: 1px solid color-mix(in oklab, var(--line-soft) 78%, transparent); + } + + .studio-chip { + background: color-mix(in oklab, var(--surface-soft) 80%, transparent); + } + + .studio-link:hover, + .studio-link:focus-visible { + color: color-mix(in oklab, var(--electric) 82%, var(--text) 18%); + } + + .site-contrast-toggle { + border: 1px solid color-mix(in oklab, var(--trace-cyan) 48%, transparent); + } + + .site-contrast-toggle { + background: color-mix(in oklab, var(--surface-soft) 74%, transparent); + } + + .site-contrast-toggle { + color: color-mix(in oklab, var(--electric) 90%, var(--text) 10%); + } + + .site-contrast-toggle:hover, + .site-contrast-toggle:focus-visible { + border-color: color-mix(in oklab, var(--electric) 70%, transparent); + } + + .site-contrast-toggle:hover, + .site-contrast-toggle:focus-visible { + background: color-mix(in oklab, var(--electric) 12%, transparent); + } + + .site-contrast-toggle:before { + border: 1px solid color-mix(in oklab, var(--text) 70%, transparent); + } + + .projects-timeline-item:before { + border: 1px solid color-mix(in oklab, var(--trace-cyan) 44%, transparent); + } + + .projects-timeline-item:before { + background: color-mix(in oklab, var(--trace-cyan-soft) 68%, transparent); + } + + .studio-icon { + border: 1px solid color-mix(in oklab, var(--line-soft) 80%, transparent); + } + + .studio-icon { + background: linear-gradient( + 140deg, + color-mix(in oklab, var(--surface-soft) 88%, transparent), + #04091cb3 + ); + } + + .studio-icon--pad { + box-shadow: inset 0 0 0 1px + color-mix(in oklab, var(--trace-cyan) 32%, transparent); + } + + .studio-icon--pad:before { + background: linear-gradient( + 90deg, + var(--trace-cyan), + color-mix(in oklab, var(--signal) 60%, transparent) + ); + } + + .studio-icon--pad:after { + border: 1px solid color-mix(in oklab, var(--line-soft) 78%, transparent); + } + + .studio-icon--hub { + box-shadow: inset 0 0 0 1px + color-mix(in oklab, var(--trace-magenta) 40%, transparent); + } + + .studio-icon--hub:after { + border-left: 1.25px dashed + color-mix(in oklab, var(--trace-magenta) 70%, transparent); + } + + .studio-icon--hub:after { + border-right: 1.25px dashed + color-mix(in oklab, var(--trace-magenta) 70%, transparent); + } + + .studio-icon--connector { + box-shadow: inset 0 0 0 1px + color-mix(in oklab, var(--trace-cyan) 34%, transparent); + } + + .studio-icon--cable { + box-shadow: inset 0 0 0 1px + color-mix(in oklab, var(--trace-green) 40%, transparent); + } + + .studio-icon--cable:before { + box-shadow: 1rem 0 color-mix(in oklab, var(--trace-green) 65%, transparent); + } + + a:focus-visible, + button:focus-visible { + outline: 3px solid color-mix(in oklab, var(--electric) 85%, white 15%); + } + } + @keyframes signalTravel { 0% { opacity: 0.55; @@ -940,34 +937,6 @@ h3 { transform: translate(128%); } } -@keyframes navLinkJitter { - 0% { - transform: translate(0) rotate(0); - } - 25% { - transform: translate3d( - var(--nav-jitter-x), - calc(-1 * var(--nav-jitter-y)), - 0 - ) - rotate(var(--nav-jitter-r)); - } - 50% { - transform: translate3d( - calc(-1 * var(--nav-jitter-x)), - var(--nav-jitter-y), - 0 - ) - rotate(calc(-1 * var(--nav-jitter-r))); - } - 75% { - transform: translate3d(var(--nav-jitter-y), var(--nav-jitter-y), 0) - rotate(0); - } - to { - transform: translate(0) rotate(0); - } -} @keyframes brandSpark { 0%, to { @@ -986,19 +955,9 @@ h3 { border-radius: 999px; display: inline-flex; } -@supports (color: color-mix(in lab, red, red)) { - .studio-chip { - border: 1px solid color-mix(in oklab, var(--line-soft) 78%, transparent); - } -} .studio-chip { background: var(--surface-soft); } -@supports (color: color-mix(in lab, red, red)) { - .studio-chip { - background: color-mix(in oklab, var(--surface-soft) 80%, transparent); - } -} .studio-chip { padding: 0.2rem 0.75rem; font-size: 0.8rem; @@ -1023,17 +982,16 @@ h3 { background: color-mix(in oklab, var(--trace-amber) 14%, transparent); border-color: color-mix(in oklab, var(--trace-amber) 34%, transparent); } +.studio-chip--amber { + color: color-mix(in oklab, var(--text) 92%, var(--trace-magenta) 8%); + background: color-mix(in oklab, var(--trace-magenta) 14%, transparent); + border-color: color-mix(in oklab, var(--trace-magenta) 34%, transparent); +} .studio-link { color: var(--electric); text-underline-offset: 4px; text-decoration-thickness: 2px; } -@supports (color: color-mix(in lab, red, red)) { - .studio-link:hover, - .studio-link:focus-visible { - color: color-mix(in oklab, var(--electric) 82%, var(--text) 18%); - } -} .studio-link:hover, .studio-link:focus-visible { text-decoration-thickness: 3px; @@ -1050,27 +1008,12 @@ h3 { padding: 0 0.88rem; display: inline-flex; } -@supports (color: color-mix(in lab, red, red)) { - .site-contrast-toggle { - border: 1px solid color-mix(in oklab, var(--trace-cyan) 48%, transparent); - } -} .site-contrast-toggle { background: var(--surface-soft); } -@supports (color: color-mix(in lab, red, red)) { - .site-contrast-toggle { - background: color-mix(in oklab, var(--surface-soft) 74%, transparent); - } -} .site-contrast-toggle { color: var(--electric); } -@supports (color: color-mix(in lab, red, red)) { - .site-contrast-toggle { - color: color-mix(in oklab, var(--electric) 90%, var(--text) 10%); - } -} .site-contrast-toggle { letter-spacing: 0.04em; white-space: nowrap; @@ -1086,22 +1029,10 @@ h3 { .site-contrast-toggle:focus-visible { border-color: var(--electric); } -@supports (color: color-mix(in lab, red, red)) { - .site-contrast-toggle:hover, - .site-contrast-toggle:focus-visible { - border-color: color-mix(in oklab, var(--electric) 70%, transparent); - } -} .site-contrast-toggle:hover, .site-contrast-toggle:focus-visible { background: var(--electric); } -@supports (color: color-mix(in lab, red, red)) { - .site-contrast-toggle:hover, - .site-contrast-toggle:focus-visible { - background: color-mix(in oklab, var(--electric) 12%, transparent); - } -} .site-contrast-toggle:active { transform: translateY(1px); } @@ -1112,11 +1043,6 @@ h3 { width: 0.55rem; height: 0.55rem; } -@supports (color: color-mix(in lab, red, red)) { - .site-contrast-toggle:before { - border: 1px solid color-mix(in oklab, var(--text) 70%, transparent); - } -} .site-contrast-toggle:before { background: radial-gradient( circle at 35% 35%, @@ -1124,312 +1050,6 @@ h3 { transparent 58% ); } -.nav-status { - border: 1px solid var(--trace-amber-soft); - border-radius: 999px; - align-items: center; - min-height: 2rem; - display: inline-flex; -} -@supports (color: color-mix(in lab, red, red)) { - .nav-status { - border: 1px solid - color-mix(in oklab, var(--trace-amber-soft) 72%, transparent); - } -} -@supports (color: color-mix(in lab, red, red)) { - .nav-status { - background: color-mix(in oklab, var(--trace-amber-soft) 18%, transparent); - } -} -.nav-status { - color: var(--trace-amber); -} -@supports (color: color-mix(in lab, red, red)) { - .nav-status { - color: color-mix(in oklab, var(--trace-amber) 82%, var(--text) 18%); - } -} -.nav-status { - letter-spacing: 0.1em; - text-transform: uppercase; - white-space: nowrap; - padding: 0.18rem 0.62rem; - font-size: 0.68rem; -} -.hero-manifest { - border: 1px solid var(--line); - gap: 0.45rem; - max-width: 42rem; - display: grid; -} -@supports (color: color-mix(in lab, red, red)) { - .hero-manifest { - border: 1px solid color-mix(in oklab, var(--line) 82%, transparent); - } -} -.hero-manifest { - background: - linear-gradient( - 90deg, - transparent 0%, - var(--trace-cyan-soft) 50%, - transparent 100% - ), - var(--surface-soft); - border-radius: 0.9rem; - padding: 0.72rem 0.8rem; -} -@supports (color: color-mix(in lab, red, red)) { - .hero-manifest { - background: - linear-gradient( - 90deg, - transparent 0%, - color-mix(in oklab, var(--trace-cyan-soft) 10%, transparent) 50%, - transparent 100% - ), - color-mix(in oklab, var(--surface-soft) 82%, transparent); - } -} -.hero-manifest-row { - color: var(--text-muted); - align-items: flex-start; - gap: 0.46rem; - margin: 0; - font-size: 0.89rem; - line-height: 1.45; - display: flex; -} -.hero-manifest-node { - border: 1px solid var(--trace-cyan); - border-radius: 2px; - flex: none; - width: 0.52rem; - height: 0.52rem; - margin-top: 0.24rem; -} -@supports (color: color-mix(in lab, red, red)) { - .hero-manifest-node { - border: 1px solid color-mix(in oklab, var(--trace-cyan) 48%, transparent); - } -} -.hero-manifest-node { - background: var(--trace-cyan-soft); -} -@supports (color: color-mix(in lab, red, red)) { - .hero-manifest-node { - background: color-mix(in oklab, var(--trace-cyan-soft) 70%, transparent); - } -} -.hero-manifest-node--magenta { - border-color: var(--trace-magenta); -} -@supports (color: color-mix(in lab, red, red)) { - .hero-manifest-node--magenta { - border-color: color-mix(in oklab, var(--trace-magenta) 48%, transparent); - } -} -.hero-manifest-node--magenta { - background: var(--trace-magenta-soft); -} -@supports (color: color-mix(in lab, red, red)) { - .hero-manifest-node--magenta { - background: color-mix(in oklab, var(--trace-magenta-soft) 70%, transparent); - } -} -.hero-manifest-node--green { - border-color: var(--trace-green); -} -@supports (color: color-mix(in lab, red, red)) { - .hero-manifest-node--green { - border-color: color-mix(in oklab, var(--trace-green) 48%, transparent); - } -} -.hero-manifest-node--green { - background: var(--trace-green-soft); -} -@supports (color: color-mix(in lab, red, red)) { - .hero-manifest-node--green { - background: color-mix(in oklab, var(--trace-green-soft) 70%, transparent); - } -} -.dual-cta-rail { - border: 1px solid var(--line-soft); -} -@supports (color: color-mix(in lab, red, red)) { - .dual-cta-rail { - border: 1px solid color-mix(in oklab, var(--line-soft) 78%, transparent); - } -} -.dual-cta-rail { - background: - linear-gradient(112deg, var(--trace-cyan-soft), var(--trace-magenta-soft)), - var(--surface-alt); - border-radius: 0.95rem; - padding: 0.62rem 0.72rem 0.72rem; -} -@supports (color: color-mix(in lab, red, red)) { - .dual-cta-rail { - background: - linear-gradient( - 112deg, - color-mix(in oklab, var(--trace-cyan-soft) 12%, transparent), - color-mix(in oklab, var(--trace-magenta-soft) 10%, transparent) - ), - color-mix(in oklab, var(--surface-alt) 78%, transparent); - } -} -.dual-cta-label { - letter-spacing: 0.11em; - text-transform: uppercase; - color: var(--text-dim); - margin: 0; - font-size: 0.69rem; -} -.dual-cta-actions { - grid-template-columns: 1fr; - gap: 0.52rem; - margin-top: 0.5rem; - display: grid; -} -.dual-cta-btn, -.dual-cta-btn a { - width: 100%; -} -.system-pipeline { - grid-template-columns: 1fr; - gap: 0.55rem; - margin: 0.9rem 0 0; - padding: 0; - list-style: none; - display: grid; -} -.system-pipeline-step { - position: relative; -} -.system-pipeline-link { - min-height: 4rem; - color: var(--text); - border: 1px solid var(--line-soft); - align-items: center; - gap: 0.72rem; - text-decoration: none; - display: flex; -} -@supports (color: color-mix(in lab, red, red)) { - .system-pipeline-link { - border: 1px solid color-mix(in oklab, var(--line-soft) 78%, transparent); - } -} -.system-pipeline-link { - background: - linear-gradient( - 90deg, - transparent 0%, - var(--trace-cyan-soft) 48%, - var(--trace-amber-soft) 100% - ), - var(--surface-soft); - border-radius: 0.88rem; - padding: 0.5rem 0.62rem; -} -@supports (color: color-mix(in lab, red, red)) { - .system-pipeline-link { - background: - linear-gradient( - 90deg, - transparent 0%, - color-mix(in oklab, var(--trace-cyan-soft) 12%, transparent) 48%, - color-mix(in oklab, var(--trace-amber-soft) 12%, transparent) 100% - ), - color-mix(in oklab, var(--surface-soft) 80%, transparent); - } -} -.system-pipeline-link { - transition: - transform 0.18s, - border-color 0.18s, - box-shadow 0.18s; -} -.system-pipeline-link:hover, -.system-pipeline-link:focus-visible { - border-color: var(--trace-cyan); - transform: translateY(-2px); -} -@supports (color: color-mix(in lab, red, red)) { - .system-pipeline-link:hover, - .system-pipeline-link:focus-visible { - border-color: color-mix(in oklab, var(--trace-cyan) 54%, transparent); - } -} -.system-pipeline-link:hover, -.system-pipeline-link:focus-visible { - box-shadow: 0 10px 24px #070e2247; -} -.system-pipeline-index { - letter-spacing: 0.08em; - border: 1px solid var(--trace-cyan); - border-radius: 0.58rem; - flex: none; - justify-content: center; - align-items: center; - min-width: 2.1rem; - min-height: 2.1rem; - font-size: 0.72rem; - display: inline-flex; -} -@supports (color: color-mix(in lab, red, red)) { - .system-pipeline-index { - border: 1px solid color-mix(in oklab, var(--trace-cyan) 42%, transparent); - } -} -.system-pipeline-index { - background: var(--trace-cyan-soft); -} -@supports (color: color-mix(in lab, red, red)) { - .system-pipeline-index { - background: color-mix(in oklab, var(--trace-cyan-soft) 24%, transparent); - } -} -.system-pipeline-index { - color: var(--electric); -} -@supports (color: color-mix(in lab, red, red)) { - .system-pipeline-index { - color: color-mix(in oklab, var(--electric) 86%, var(--text) 14%); - } -} -.system-pipeline-content { - gap: 0.15rem; - display: grid; -} -.system-pipeline-label { - letter-spacing: 0.07em; - text-transform: uppercase; - color: var(--text); - font-size: 0.9rem; -} -.system-pipeline-detail { - color: var(--text-muted); - font-size: 0.82rem; -} -.projects-timeline { - border-left: 1px dashed var(--line-rail); - margin: 0; - padding: 0 0 0 0.36rem; - list-style: none; -} -@supports (color: color-mix(in lab, red, red)) { - .projects-timeline { - border-left: 1px dashed - color-mix(in oklab, var(--line-rail) 100%, transparent); - } -} -.projects-timeline { - gap: 0.75rem; - display: grid; -} .projects-timeline-item { grid-template-columns: 4.5rem 1fr; gap: 0.32rem; @@ -1447,594 +1067,12 @@ h3 { top: 1rem; left: -0.67rem; } -@supports (color: color-mix(in lab, red, red)) { - .projects-timeline-item:before { - border: 1px solid color-mix(in oklab, var(--trace-cyan) 44%, transparent); - } -} .projects-timeline-item:before { background: var(--trace-cyan-soft); } -@supports (color: color-mix(in lab, red, red)) { - .projects-timeline-item:before { - background: color-mix(in oklab, var(--trace-cyan-soft) 68%, transparent); - } -} .projects-timeline-item:before { box-shadow: 0 0 10px color-mix(in oklab, var(--trace-cyan) 18%, transparent); } -.projects-timeline-year { - letter-spacing: 0.1em; - text-transform: uppercase; - color: var(--text-dim); - margin: 0; - font-size: 0.74rem; -} -.projects-timeline-content { - border: 1px solid var(--line-soft); -} -@supports (color: color-mix(in lab, red, red)) { - .projects-timeline-content { - border: 1px solid color-mix(in oklab, var(--line-soft) 78%, transparent); - } -} -.projects-timeline-content { - background: var(--surface-alt); - border-radius: 0.88rem; - padding: 0.58rem 0.68rem; -} -@supports (color: color-mix(in lab, red, red)) { - .projects-timeline-content { - background: color-mix(in oklab, var(--surface-alt) 78%, transparent); - } -} -.projects-timeline-kicker { - letter-spacing: 0.08em; - text-transform: uppercase; - color: var(--electric); - margin: 0; - font-size: 0.7rem; -} -.projects-timeline-title { - margin: 0.2rem 0 0; - font-size: 1.06rem; -} -.projects-timeline-summary { - color: var(--text-muted); - margin: 0.35rem 0 0; - font-size: 0.89rem; -} -.projects-timeline-link { - border: 1px solid var(--line-soft); - align-items: center; - min-height: 2rem; - margin-top: 0.44rem; - padding: 0 0.62rem; - display: inline-flex; -} -@supports (color: color-mix(in lab, red, red)) { - .projects-timeline-link { - border: 1px solid color-mix(in oklab, var(--line-soft) 82%, transparent); - } -} -.projects-timeline-link { - color: var(--electric); - border-radius: 999px; - font-size: 0.78rem; - text-decoration: none; -} -.projects-timeline-link:hover, -.projects-timeline-link:focus-visible { - border-color: var(--trace-cyan); -} -@supports (color: color-mix(in lab, red, red)) { - .projects-timeline-link:hover, - .projects-timeline-link:focus-visible { - border-color: color-mix(in oklab, var(--trace-cyan) 62%, transparent); - } -} -.projects-timeline-link:hover, -.projects-timeline-link:focus-visible { - color: var(--electric); -} -@supports (color: color-mix(in lab, red, red)) { - .projects-timeline-link:hover, - .projects-timeline-link:focus-visible { - color: color-mix(in oklab, var(--electric) 84%, var(--text) 16%); - } -} -.lab-notes-grid { - grid-template-columns: 1fr; - gap: 0.8rem; - display: grid; -} -.lab-note-card { - border: 1px solid var(--line-soft); -} -@supports (color: color-mix(in lab, red, red)) { - .lab-note-card { - border: 1px solid color-mix(in oklab, var(--line-soft) 80%, transparent); - } -} -.lab-note-card { - background: - linear-gradient( - 90deg, - transparent 0%, - var(--trace-green-soft) 50%, - transparent 100% - ), - var(--surface-alt); - border-radius: 0.96rem; - padding: 0.78rem 0.78rem 0.85rem; -} -@supports (color: color-mix(in lab, red, red)) { - .lab-note-card { - background: - linear-gradient( - 90deg, - transparent 0%, - color-mix(in oklab, var(--trace-green-soft) 10%, transparent) 50%, - transparent 100% - ), - color-mix(in oklab, var(--surface-alt) 80%, transparent); - } -} -.lab-note-card { - box-shadow: - 0 10px 24px #060c1d33, - inset 0 0 0 1px #ffffff08; -} -.lab-note-date { - letter-spacing: 0.1em; - text-transform: uppercase; - color: var(--text-dim); - margin: 0; - font-size: 0.69rem; -} -.lab-note-title { - margin: 0.26rem 0 0.52rem; - font-size: 1.02rem; -} -.lab-note-flow { - grid-template-columns: 5.2rem 1fr; - gap: 0.2rem 0.45rem; - margin: 0; - display: grid; -} -.lab-note-flow dt { - letter-spacing: 0.08em; - text-transform: uppercase; - color: var(--electric); - margin: 0; - font-size: 0.72rem; -} -.lab-note-flow dd { - color: var(--text-muted); - margin: 0; - font-size: 0.84rem; -} -.lab-note-link { - text-underline-offset: 3px; - min-height: 2rem; - color: var(--electric); - align-items: center; - font-size: 0.86rem; - text-decoration-thickness: 2px; - display: inline-flex; -} -.lab-note-link:hover, -.lab-note-link:focus-visible { - color: var(--electric); -} -@supports (color: color-mix(in lab, red, red)) { - .lab-note-link:hover, - .lab-note-link:focus-visible { - color: color-mix(in oklab, var(--electric) 84%, var(--text) 16%); - } -} -.trust-strip { - grid-template-columns: 1fr; - gap: 0.58rem; - display: grid; -} -.trust-pill { - border: 1px solid var(--line-soft); -} -@supports (color: color-mix(in lab, red, red)) { - .trust-pill { - border: 1px solid color-mix(in oklab, var(--line-soft) 80%, transparent); - } -} -.trust-pill { - background: - linear-gradient(90deg, var(--trace-cyan-soft), var(--trace-magenta-soft)), - var(--surface-alt); - border-radius: 0.82rem; - padding: 0.55rem 0.62rem; -} -@supports (color: color-mix(in lab, red, red)) { - .trust-pill { - background: - linear-gradient( - 90deg, - color-mix(in oklab, var(--trace-cyan-soft) 10%, transparent), - color-mix(in oklab, var(--trace-magenta-soft) 9%, transparent) - ), - color-mix(in oklab, var(--surface-alt) 80%, transparent); - } -} -.trust-pill-label { - letter-spacing: 0.09em; - text-transform: uppercase; - color: var(--text-dim); - margin: 0; - font-size: 0.7rem; -} -.trust-pill-value { - color: var(--text); - margin: 0.14rem 0 0; - font-size: 0.9rem; -} -.flow-diagram-shell { - position: relative; -} -.flow-title-row { - align-items: center; - gap: 0.55rem; - display: inline-flex; -} -.flow-title-row h2, -.flow-title-row .section-title { - margin: 0; -} -.flow-diagram { - grid-template-columns: 1fr; - gap: 0.72rem; - margin: 0.9rem 0 0; - padding: 0; - list-style: none; - display: grid; -} -.flow-node-card { - border: 1px solid var(--line-soft); - grid-template-columns: 2.4rem 1fr; - gap: 0.75rem; - min-height: 5.4rem; - padding: 0.85rem; - display: grid; -} -@supports (color: color-mix(in lab, red, red)) { - .flow-node-card { - border: 1px solid color-mix(in oklab, var(--line-soft) 80%, transparent); - } -} -.flow-node-card { - background: linear-gradient(180deg, var(--surface), var(--surface-alt)); - border-radius: 1rem; -} -@supports (color: color-mix(in lab, red, red)) { - .flow-node-card { - background: linear-gradient( - 180deg, - color-mix(in oklab, var(--surface) 92%, transparent), - color-mix(in oklab, var(--surface-alt) 92%, var(--electric) 8%) - ); - } -} -.flow-node-card { - color: var(--text); - text-decoration: none; - transition: - border-color 0.18s, - transform 0.18s, - box-shadow 0.18s; - position: relative; - overflow: hidden; -} -.flow-node-card:before { - content: ""; - pointer-events: none; - opacity: 0.7; - background: radial-gradient( - circle at 94% -2%, - color-mix(in oklab, var(--electric) 12%, transparent), - transparent 56% - ); - position: absolute; - inset: 0; -} -.flow-node-card:after { - content: ""; - background: repeating-linear-gradient( - 90deg, - var(--trace-cyan-soft) 0 0.25rem, - transparent 0.25rem 0.5rem - ); - height: 1px; - position: absolute; - bottom: 0.55rem; - left: 0.7rem; - right: 0.7rem; -} -@supports (color: color-mix(in lab, red, red)) { - .flow-node-card:after { - background: repeating-linear-gradient( - 90deg, - color-mix(in oklab, var(--trace-cyan-soft) 62%, transparent) 0 0.25rem, - transparent 0.25rem 0.5rem - ); - } -} -.flow-node-card:after { - opacity: 0.68; - pointer-events: none; -} -@supports (color: color-mix(in lab, red, red)) { - .flow-node-card:hover, - .flow-node-card:focus-visible { - border-color: color-mix(in oklab, var(--electric) 58%, transparent); - } -} -.flow-node-card:hover, -.flow-node-card:focus-visible { - box-shadow: - 0 12px 24px rgba(77, 60, 32, 0.14), - 0 0 0 1px color-mix(in oklab, var(--electric) 26%, transparent) inset; - transform: translateY(-2px); -} -@supports (color: color-mix(in lab, red, red)) { - .flow-node-card:hover, - .flow-node-card:focus-visible { - box-shadow: - 0 12px 24px rgba(77, 60, 32, 0.14), - 0 0 0 1px color-mix(in oklab, var(--electric) 26%, transparent) inset; - } -} -.flow-node-card > * { - z-index: 1; - position: relative; -} -.flow-node-card strong { - color: var(--text); - margin-top: 0.2rem; - display: block; -} -.flow-node-card .text-sm { - font-size: 0.74rem; -} -.flow-edge { - justify-content: center; - align-items: center; - padding: 0.2rem 0; - display: flex; - position: relative; -} -.flow-edge:before, -.flow-edge:after { - content: ""; - pointer-events: none; -} -.flow-edge:before { - background: linear-gradient( - 90deg, - transparent, - color-mix(in oklab, var(--electric) 22%, transparent), - transparent - ) - 0 0/1.75rem 1px; - width: 1.75rem; - height: 1px; - animation: 2.2s linear infinite signalTravel; - display: block; -} -.flow-edge:after { - border: 0.45rem solid #0000; - border-left-color: var(--electric); - width: 0; - height: 0; - margin-left: 0.35rem; -} -.flow-edge[aria-hidden="true"] { - margin: 0 auto; -} -.identity-lab-grid { - grid-template-columns: repeat(1, minmax(0, 1fr)); - gap: 0.85rem; - display: grid; -} -.logo-lab-card { - border: 1px solid var(--line-soft); -} -@supports (color: color-mix(in lab, red, red)) { - .logo-lab-card { - border: 1px solid color-mix(in oklab, var(--line-soft) 80%, transparent); - } -} -.logo-lab-card { - background: linear-gradient(180deg, var(--surface-alt), #0a1426db); - border-radius: 0.95rem; - padding: 0.8rem; -} -@supports (color: color-mix(in lab, red, red)) { - .logo-lab-card { - background: linear-gradient( - 180deg, - color-mix(in oklab, var(--surface-alt) 72%, transparent), - #0a1426db - ); - } -} -.logo-lab-card { - box-shadow: - 0 9px 22px #060a183d, - inset 0 0 0 1px #ffffff08; -} -.logo-lab-kicker { - letter-spacing: 0.12em; - text-transform: uppercase; - color: var(--text-dim); - margin: 0; - font-size: 0.66rem; -} -.logo-lab-title { - margin: 0.25rem 0 0.55rem; - font-size: 1.03rem; -} -.logo-lab-svg { - width: 100%; - height: auto; - display: block; -} -.logo-lab-bg { - fill: var(--surface-soft); -} -@supports (color: color-mix(in lab, red, red)) { - .logo-lab-bg { - fill: color-mix(in oklab, var(--surface-soft) 85%, transparent); - } -} -.logo-lab-bg { - stroke: var(--line); -} -@supports (color: color-mix(in lab, red, red)) { - .logo-lab-bg { - stroke: color-mix(in oklab, var(--line) 85%, transparent); - } -} -.logo-lab-bg { - stroke-width: 1.2px; -} -.logo-lab-trace { - fill: none; - stroke: var(--trace-cyan); -} -@supports (color: color-mix(in lab, red, red)) { - .logo-lab-trace { - stroke: color-mix(in oklab, var(--trace-cyan) 88%, var(--text) 12%); - } -} -.logo-lab-trace { - stroke-width: 4px; - stroke-linecap: round; - stroke-linejoin: round; - stroke-dasharray: 9 5; - animation: 2.6s linear infinite traceRun; -} -@keyframes traceRun { - 0% { - stroke-dashoffset: 0; - } - to { - stroke-dashoffset: -28px; - } -} -.logo-lab-node { - fill: var(--trace-cyan-soft); -} -@supports (color: color-mix(in lab, red, red)) { - .logo-lab-node { - fill: color-mix(in oklab, var(--trace-cyan-soft) 78%, transparent); - } -} -.logo-lab-node--alt { - fill: var(--trace-magenta-soft); -} -@supports (color: color-mix(in lab, red, red)) { - .logo-lab-node--alt { - fill: color-mix(in oklab, var(--trace-magenta-soft) 78%, transparent); - } -} -.logo-lab-node--amber { - fill: var(--trace-amber-soft); -} -@supports (color: color-mix(in lab, red, red)) { - .logo-lab-node--amber { - fill: color-mix(in oklab, var(--trace-amber-soft) 76%, transparent); - } -} -.logo-lab-wordmark { - fill: var(--text); -} -@supports (color: color-mix(in lab, red, red)) { - .logo-lab-wordmark { - fill: color-mix(in oklab, var(--text) 92%, transparent); - } -} -.logo-lab-wordmark { - letter-spacing: 0.11em; - font-family: - Manrope, - Segoe UI, - sans-serif; - font-size: 14px; - font-weight: 700; -} -.logo-lab-subline { - fill: var(--text-muted); - letter-spacing: 0.12em; - font-family: "IBM Plex Mono", ui-monospace, Menlo, Consolas, monospace; - font-size: 10px; -} -.logo-lab-block { - fill: var(--surface); -} -@supports (color: color-mix(in lab, red, red)) { - .logo-lab-block { - fill: color-mix(in oklab, var(--surface) 82%, transparent); - } -} -.logo-lab-block { - stroke: var(--line-soft); -} -@supports (color: color-mix(in lab, red, red)) { - .logo-lab-block { - stroke: color-mix(in oklab, var(--line-soft) 84%, transparent); - } -} -.logo-lab-block { - stroke-width: 1.2px; -} -.logo-lab-link { - fill: none; - stroke: var(--trace-green); -} -@supports (color: color-mix(in lab, red, red)) { - .logo-lab-link { - stroke: color-mix(in oklab, var(--trace-green) 78%, var(--text) 22%); - } -} -.logo-lab-link { - stroke-width: 2.2px; - stroke-linecap: round; - stroke-linejoin: round; -} -.logo-lab-arrow { - fill: var(--trace-green-soft); -} -@supports (color: color-mix(in lab, red, red)) { - .logo-lab-arrow { - fill: color-mix(in oklab, var(--trace-green-soft) 80%, transparent); - } -} -.logo-lab-stamp { - fill: none; - stroke: var(--line-soft); -} -@supports (color: color-mix(in lab, red, red)) { - .logo-lab-stamp { - stroke: color-mix(in oklab, var(--line-soft) 86%, transparent); - } -} -.logo-lab-stamp { - stroke-width: 1.4px; - stroke-dasharray: 5 3; -} -.logo-lab-meta { - color: var(--text-muted); - margin: 0.55rem 0 0; - font-size: 0.8rem; -} .studio-icon { border: 1px solid var(--line-soft); border-radius: 0.5rem; @@ -2042,23 +1080,9 @@ h3 { height: 2.2rem; position: relative; } -@supports (color: color-mix(in lab, red, red)) { - .studio-icon { - border: 1px solid color-mix(in oklab, var(--line-soft) 80%, transparent); - } -} .studio-icon { background: linear-gradient(140deg, var(--surface-soft), #04091cb3); } -@supports (color: color-mix(in lab, red, red)) { - .studio-icon { - background: linear-gradient( - 140deg, - color-mix(in oklab, var(--surface-soft) 88%, transparent), - #04091cb3 - ); - } -} .studio-icon:before, .studio-icon:after { content: ""; @@ -2067,27 +1091,12 @@ h3 { .studio-icon--pad { box-shadow: inset 0 0 0 1px var(--trace-cyan); } -@supports (color: color-mix(in lab, red, red)) { - .studio-icon--pad { - box-shadow: inset 0 0 0 1px - color-mix(in oklab, var(--trace-cyan) 32%, transparent); - } -} .studio-icon--pad:before { background: linear-gradient(90deg, var(--trace-cyan), var(--signal)); border-radius: 0.2rem; width: 0.9rem; height: 0.55rem; } -@supports (color: color-mix(in lab, red, red)) { - .studio-icon--pad:before { - background: linear-gradient( - 90deg, - var(--trace-cyan), - color-mix(in oklab, var(--signal) 60%, transparent) - ); - } -} .studio-icon--pad:before { top: 0.38rem; left: 0.55rem; @@ -2097,11 +1106,6 @@ h3 { width: 1.2rem; height: 1.2rem; } -@supports (color: color-mix(in lab, red, red)) { - .studio-icon--pad:after { - border: 1px solid color-mix(in oklab, var(--line-soft) 78%, transparent); - } -} .studio-icon--pad:after { border-radius: 0.3rem; bottom: 0.2rem; @@ -2114,12 +1118,6 @@ h3 { .studio-icon--hub { box-shadow: inset 0 0 0 1px var(--trace-magenta); } -@supports (color: color-mix(in lab, red, red)) { - .studio-icon--hub { - box-shadow: inset 0 0 0 1px - color-mix(in oklab, var(--trace-magenta) 40%, transparent); - } -} .studio-icon--hub:before { border: 2px solid var(--trace-magenta); border-radius: 999px; @@ -2134,30 +1132,12 @@ h3 { height: 1.02rem; inset: 0.56rem; } -@supports (color: color-mix(in lab, red, red)) { - .studio-icon--hub:after { - border-left: 1.25px dashed - color-mix(in oklab, var(--trace-magenta) 70%, transparent); - } -} .studio-icon--hub:after { border-right: 1.25px dashed var(--trace-magenta); } -@supports (color: color-mix(in lab, red, red)) { - .studio-icon--hub:after { - border-right: 1.25px dashed - color-mix(in oklab, var(--trace-magenta) 70%, transparent); - } -} .studio-icon--connector { box-shadow: inset 0 0 0 1px var(--trace-cyan); } -@supports (color: color-mix(in lab, red, red)) { - .studio-icon--connector { - box-shadow: inset 0 0 0 1px - color-mix(in oklab, var(--trace-cyan) 34%, transparent); - } -} .studio-icon--connector:before { border: 2px solid var(--trace-cyan); border-radius: 999px; @@ -2183,12 +1163,6 @@ h3 { .studio-icon--cable { box-shadow: inset 0 0 0 1px var(--trace-green); } -@supports (color: color-mix(in lab, red, red)) { - .studio-icon--cable { - box-shadow: inset 0 0 0 1px - color-mix(in oklab, var(--trace-green) 40%, transparent); - } -} .studio-icon--cable:before { border: 2px solid var(--trace-green); width: 0.58rem; @@ -2198,11 +1172,6 @@ h3 { top: 0.8rem; left: 0.16rem; } -@supports (color: color-mix(in lab, red, red)) { - .studio-icon--cable:before { - box-shadow: 1rem 0 color-mix(in oklab, var(--trace-green) 65%, transparent); - } -} .studio-icon--cable:after { background: linear-gradient( 90deg, @@ -2217,129 +1186,34 @@ h3 { right: 0.3rem; } @media (min-width: 768px) { + .identity-lab-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); } - .dual-cta-actions { - grid-template-columns: repeat(2, minmax(0, 1fr)); - } - .system-pipeline { - grid-template-columns: repeat(4, minmax(0, 1fr)); - } - .system-pipeline-step:not(:last-child):after { - content: ""; - background: linear-gradient( - 90deg, - transparent, - var(--trace-cyan-soft), - transparent - ); - pointer-events: none; - width: 0.8rem; - height: 1px; - position: absolute; - top: 50%; - right: -0.42rem; - transform: translateY(-50%); - } - .system-pipeline-link { - min-height: 4.6rem; - } .projects-timeline-item { grid-template-columns: 5.2rem 1fr; } - .lab-notes-grid { - grid-template-columns: repeat(3, minmax(0, 1fr)); - } - .lab-note-flow { - grid-template-columns: 1fr; - gap: 0.08rem; - } - .lab-note-flow dt { - margin-top: 0.18rem; - } - .trust-strip { - grid-template-columns: repeat(3, minmax(0, 1fr)); - } - .flow-diagram { - grid-template-columns: repeat(7, minmax(0, 1fr)); - align-items: stretch; - } - .flow-edge { - align-self: center; - height: auto; - min-height: 1rem; - padding: 0; - display: block; - position: relative; - } - .flow-edge:before { - width: 100%; - height: 1px; - margin: 0; - position: relative; - } - .flow-edge:after { - border-width: 0.35rem 0.45rem; - border-left-color: var(--electric); - border-top-color: #0000; - border-bottom-color: #0000; - border-right-color: #0000; - position: absolute; - top: 50%; - right: 0.1rem; - transform: translateY(-50%); - } - .flow-node-card { - min-height: 6rem; - } + } @media (max-width: 767px) { + .projects-timeline-item { grid-template-columns: 1fr; padding-left: 0.2rem; } - .projects-timeline-year { - margin-bottom: 0.12rem; - } - .flow-diagram { - gap: 0.25rem; - } - .flow-edge { - min-height: 1.2rem; - } - .flow-edge:before { - background: linear-gradient(#0000, #ffffff94, #0000); - width: 2px; - height: 100%; - } - .flow-edge:after { - border-width: 0.35rem 0.42rem; - border-top-color: var(--electric); - border-bottom-color: #0000; - border-left-color: #0000; - border-right-color: #0000; - position: absolute; - inset: auto auto 0.1rem 50%; - transform: translate(-50%); - } + } a:focus-visible, button:focus-visible { outline: 3px solid var(--electric); } -@supports (color: color-mix(in lab, red, red)) { - a:focus-visible, - button:focus-visible { - outline: 3px solid color-mix(in oklab, var(--electric) 85%, white 15%); - } -} a:focus-visible, button:focus-visible { outline-offset: 2px; border-radius: 6px; } @media (max-width: 390px) { + .site-shell { width: min(1120px, 94vw); } @@ -2355,10 +1229,6 @@ button:focus-visible { width: 100%; max-width: 14rem; } - .nav-status { - justify-content: center; - width: 100%; - } .site-shell-title { max-width: 12ch; } @@ -2367,23 +1237,16 @@ button:focus-visible { font-size: 0.66rem; display: none; } - .hero-manifest-row { - font-size: 0.82rem; - } - .lab-note-flow { - grid-template-columns: 1fr; - } + } @media (prefers-reduced-motion: reduce) { + * { scroll-behavior: auto !important; transition-duration: 1ms !important; animation-duration: 1ms !important; animation-iteration-count: 1 !important; } - .lab-glow { - animation: none !important; - } .site-nav:before, .site-nav:after, .site-brand:before, @@ -2393,16 +1256,16 @@ button:focus-visible { transition: none !important; animation: none !important; } + } :root { + --card-radius: 0.95rem; --bg: #0b0a09; - --bg-elevated: #15110b; --surface: #1a1510; --surface-soft: #211a13; --surface-alt: #17120d; --pcb-deep: #060504; --pcb-core: #0b0a09; - --pcb-ambient: #15110b; --text: #f4eee3; --text-muted: #d6cbb9; --text-dim: #b6a894; @@ -2416,7 +1279,6 @@ button:focus-visible { --trace-amber-soft: #f1c27aa3; --signal: #d89b63; --electric: #5bd1d8; - --electric-strong: #32b9c1; --accent: #f1c27a; --line: #3a2f24; --line-soft: #2a221a; @@ -2430,20 +1292,17 @@ button:focus-visible { --da-body-after-opacity: 0.5; --da-panel-overlay: none; --da-panel-overlay-size: 180px 180px; - --da-panel-overlay-opacity: 0.16; } :root[data-theme="light"] { --bg: #f4eee3; - --bg-elevated: #fbf7ef; --surface: #fffaf2; --surface-soft: #fbf7ef; --surface-alt: #f1e6d4; --pcb-deep: #fbf7ef; --pcb-core: #f7efdf; - --pcb-ambient: #f1e6d4; --text: #1f2328; --text-muted: #4f5962; - --text-dim: #6b7785; + --text-dim: #5a6573; --trace-cyan: #1e6b73; --trace-cyan-soft: #1e6b73a3; --trace-magenta: #9a5f2f; @@ -2454,7 +1313,6 @@ button:focus-visible { --trace-amber-soft: #b4774594; --signal: #9a5f2f; --electric: #1e6b73; - --electric-strong: #165b62; --accent: #b47745; --line: #c4ac84; --line-soft: #ddcfb7; @@ -2463,13 +1321,11 @@ button:focus-visible { } :root[data-theme="high-contrast"] { --bg: #ffffff; - --bg-elevated: #ffffff; --surface: #ffffff; --surface-soft: #f4eee3; --surface-alt: #efe3d0; --pcb-deep: #ffffff; --pcb-core: #ffffff; - --pcb-ambient: #f4eee3; --text: #0b0a09; --text-muted: #2f2a25; --text-dim: #4f3f35; @@ -2483,7 +1339,6 @@ button:focus-visible { --trace-amber-soft: #9a5f2fb8; --signal: #7f4a23; --electric: #0b5d65; - --electric-strong: #064a50; --accent: #9a5f2f; --line: #0b0a09; --line-soft: #2f2a25; @@ -2491,859 +1346,6 @@ button:focus-visible { --line-rail: #0b5d6524; } -:root[data-da-variant="v1"] { - --bg: #0b0a09; - --bg-elevated: #15110b; - --surface: #1a1510; - --surface-soft: #211a13; - --surface-alt: #17120d; - --pcb-deep: #060504; - --pcb-core: #0b0a09; - --pcb-ambient: #15110b; - --text: #f4eee3; - --text-muted: #d6cbb9; - --text-dim: #b6a894; - --trace-cyan: #5bd1d8; - --trace-cyan-soft: #5bd1d8b8; - --trace-magenta: #d89b63; - --trace-magenta-soft: #d89b63ad; - --trace-green: #b6d18f; - --trace-green-soft: #b6d18fa3; - --trace-amber: #f1c27a; - --trace-amber-soft: #f1c27aa3; - --signal: #d89b63; - --electric: #5bd1d8; - --electric-strong: #32b9c1; - --accent: #f1c27a; - --line: #3a2f24; - --line-soft: #2a221a; - --line-edge: #ffffff2e; - --line-rail: #5bd1d82e; - --da-body-overlay: url('/assets/da/v1-editorial-fiber.svg'); - --da-body-overlay-size: 260px 260px; - --da-body-overlay-opacity: 0.18; - --da-body-overlay-blend: soft-light; - --da-body-before-opacity: 1; - --da-body-after-opacity: 0.48; - --da-panel-overlay: none; - --da-panel-overlay-size: 120px 120px; - --da-panel-overlay-opacity: 0.08; -} - -:root[data-da-variant="v2"] { - --bg: #080808; - --bg-elevated: #111111; - --surface: #171717; - --surface-soft: #1f1f1f; - --surface-alt: #121212; - --pcb-deep: #050505; - --pcb-core: #0a0a0a; - --pcb-ambient: #181818; - --text: #f3eee4; - --text-muted: #d8c9af; - --text-dim: #b6a489; - --trace-cyan: #ff5f35; - --trace-cyan-soft: #ff5f35a3; - --trace-magenta: #ffc36f; - --trace-magenta-soft: #ffc36f9e; - --trace-green: #f4d39a; - --trace-green-soft: #f4d39a8f; - --trace-amber: #ffd39a; - --trace-amber-soft: #ffd39a98; - --signal: #ffc36f; - --electric: #ff6a34; - --electric-strong: #ff4d27; - --accent: #ffad70; - --line: #3a2a21; - --line-soft: #2e2018; - --line-edge: #ffffff2a; - --line-rail: #ff6a3422; - --da-body-overlay: url('/assets/da/v2-brutal-noise.svg'); - --da-body-overlay-size: 180px 180px; - --da-body-overlay-opacity: 0.34; - --da-body-overlay-blend: multiply; - --da-body-before-opacity: 1; - --da-body-after-opacity: 0.34; - --da-panel-overlay: url('/assets/da/v2-brutal-noise.svg'); - --da-panel-overlay-size: 160px 160px; - --da-panel-overlay-opacity: 0.14; -} - -:root[data-da-variant="v3"] { - --bg: #090f1d; - --bg-elevated: #101d36; - --surface: #11203d; - --surface-soft: #132348; - --surface-alt: #0d1830; - --pcb-deep: #070c18; - --pcb-core: #0b152a; - --pcb-ambient: #111f3b; - --text: #e9fbff; - --text-muted: #bfd6ea; - --text-dim: #87a0bf; - --trace-cyan: #16f2ff; - --trace-cyan-soft: #16f2ff88; - --trace-magenta: #8a5a38; - --trace-magenta-soft: #8a5a38aa; - --trace-green: #7ed9b7; - --trace-green-soft: #7ed9b7a6; - --trace-amber: #8a5a38; - --trace-amber-soft: #8a5a3888; - --signal: #f2ff6d; - --electric: #16f2ff; - --electric-strong: #0ac8d3; - --accent: #8a5a38; - --line: #1d3257; - --line-soft: #1a2b4e; - --line-edge: #ffffff26; - --line-rail: #16f2ff2a; - --da-body-overlay: url('/assets/da/v3-circuit-grid.svg'); - --da-body-overlay-size: 220px 220px; - --da-body-overlay-opacity: 0.22; - --da-body-overlay-blend: soft-light; - --da-body-before-opacity: 1; - --da-body-after-opacity: 0.46; - --da-panel-overlay: url('/assets/da/v3-circuit-grid.svg'); - --da-panel-overlay-size: 220px 220px; - --da-panel-overlay-opacity: 0.12; -} - -:root[data-da-variant="v4"] { - --bg: #f5efe6; - --bg-elevated: #fbf8f1; - --surface: #ffffff; - --surface-soft: #fdf9f3; - --surface-alt: #f5efe6; - --pcb-deep: #f2ebdf; - --pcb-core: #f7f1e6; - --pcb-ambient: #efe6d7; - --text: #1f2328; - --text-muted: #4a515a; - --text-dim: #6b7785; - --trace-cyan: #1e6b73; - --trace-cyan-soft: #1e6b7388; - --trace-magenta: #9a5f2f; - --trace-magenta-soft: #9a5f2f8f; - --trace-green: #2f6f5f; - --trace-green-soft: #2f6f5fa6; - --trace-amber: #1faab5; - --trace-amber-soft: #1faab592; - --signal: #1e6b73; - --electric: #1e6b73; - --electric-strong: #165b62; - --accent: #1faab5; - --line: #cac2b9; - --line-soft: #dbd1c5; - --line-edge: #1f23282e; - --line-rail: #1e6b731f; - --da-body-overlay: none; - --da-body-overlay-size: 240px 240px; - --da-body-overlay-opacity: 0.06; - --da-body-overlay-blend: soft-light; - --da-body-before-opacity: 0; - --da-body-after-opacity: 0; - --da-panel-overlay: none; - --da-panel-overlay-size: 0 0; - --da-panel-overlay-opacity: 0; -} - -:root[data-da-variant="v5"] { - --bg: #efe2cf; - --bg-elevated: #f4ece0; - --surface: #f9f2e8; - --surface-soft: #f4eadc; - --surface-alt: #ebe0d0; - --pcb-deep: #e9dcc8; - --pcb-core: #f1e5d5; - --pcb-ambient: #e8dbc7; - --text: #211a14; - --text-muted: #4c3d2f; - --text-dim: #705c47; - --trace-cyan: #c95f4a; - --trace-cyan-soft: #c95f4a98; - --trace-magenta: #5b3a82; - --trace-magenta-soft: #5b3a82a6; - --trace-green: #7d5940; - --trace-green-soft: #7d59408d; - --trace-amber: #c95f4a; - --trace-amber-soft: #c95f4a86; - --signal: #5b3a82; - --electric: #c95f4a; - --electric-strong: #a54f3b; - --accent: #5b3a82; - --line: #bca58f; - --line-soft: #d1c0ab; - --line-edge: #17120f2c; - --line-rail: #c95f4a2b; - --da-body-overlay: url('/assets/da/v5-poster-grid.svg'); - --da-body-overlay-size: 210px 210px; - --da-body-overlay-opacity: 0.28; - --da-body-overlay-blend: soft-light; - --da-body-before-opacity: 1; - --da-body-after-opacity: 0.44; - --da-panel-overlay: url('/assets/da/v5-poster-grid.svg'); - --da-panel-overlay-size: 210px 210px; - --da-panel-overlay-opacity: 0.2; -} - -:root[data-da-variant="v6"] { - --bg: #171717; - --bg-elevated: #1d1d1d; - --surface: #1f1f1f; - --surface-soft: #232323; - --surface-alt: #1a1a1a; - --pcb-deep: #101010; - --pcb-core: #141414; - --pcb-ambient: #1f1f1f; - --text: #f3ebdf; - --text-muted: #ccbda8; - --text-dim: #a6957d; - --trace-cyan: #00b9c9; - --trace-cyan-soft: #00b9c988; - --trace-magenta: #d28f4a; - --trace-magenta-soft: #d28f4aa3; - --trace-green: #c9d66f; - --trace-green-soft: #c9d66f96; - --trace-amber: #d28f4a; - --trace-amber-soft: #d28f4a96; - --signal: #d28f4a; - --electric: #00b9c9; - --electric-strong: #008c98; - --accent: #d28f4a; - --line: #302820; - --line-soft: #46382a; - --line-edge: #ffffff20; - --line-rail: #00b9c92a; - --da-body-overlay: url('/assets/da/v6-industrial-stripes.svg'); - --da-body-overlay-size: 250px 250px; - --da-body-overlay-opacity: 0.24; - --da-body-overlay-blend: soft-light; - --da-body-before-opacity: 1; - --da-body-after-opacity: 0.45; - --da-panel-overlay: url('/assets/da/v6-industrial-stripes.svg'); - --da-panel-overlay-size: 250px 250px; - --da-panel-overlay-opacity: 0.15; -} - -:root[data-da-variant="v2"] body { - background: - linear-gradient(180deg, #080808 0%, #111111 50%, #121212 100%); -} - -:root[data-da-variant="v3"] body { - background: - radial-gradient(1000px 620px at -8% -22%, rgba(22, 242, 255, 0.14), transparent 60%), - radial-gradient(820px 480px at 110% 0%, rgba(138, 90, 56, 0.16), transparent 65%), - linear-gradient(180deg, var(--pcb-deep) 0%, color-mix(in oklab, var(--pcb-core) 86%, var(--bg) 14%) 54%, var(--bg) 100%); -} - -:root[data-da-variant="v4"] body { - background: var(--surface); -} - -:root[data-da-variant="v4"] body:before, -:root[data-da-variant="v4"] body:after { - opacity: 0; - background: none; -} - -:root[data-da-variant="v5"] body { - background: - repeating-linear-gradient(0deg, transparent 0 28px, rgba(91, 58, 130, 0.08) 28px 29px), - linear-gradient(180deg, var(--pcb-deep) 0%, var(--pcb-core) 54%, var(--bg) 100%); -} - -:root[data-da-variant="v5"] .circuit-board, -:root[data-da-variant="v5"] .studio-panel, -:root[data-da-variant="v5"] .lab-panel { - border-radius: 0; - border-left-width: 3px; -} - -:root[data-da-variant="v6"] body { - background: linear-gradient(180deg, #131313 0%, #171717 55%, #202020 100%); -} - -:root[data-da-variant="v6"] .site-nav, -:root[data-da-variant="v6"] .site-shell, -:root[data-da-variant="v6"] .structure-grid { - width: min(1180px, 92vw); -} - -:root[data-da-variant="v6"] .site-navlink { - border-radius: 999px; - letter-spacing: 0.06em; -} - -:root[data-da-variant="v7"] { - --bg: #04070f; - --bg-elevated: #0a1222; - --surface: #081327; - --surface-soft: #10203a; - --surface-alt: #0c1730; - --pcb-deep: #070f1d; - --pcb-core: #0e162b; - --pcb-ambient: #101d32; - --text: #f0f8ff; - --text-muted: #b7c8db; - --text-dim: #97abc0; - --trace-cyan: #24ebff; - --trace-cyan-soft: #6df2ff88; - --trace-magenta: #ff9b58; - --trace-magenta-soft: #ff8c4e99; - --trace-green: #87ffd4; - --trace-green-soft: #87ffd4aa; - --trace-amber: #ffb46b; - --trace-amber-soft: #ff8c4e96; - --signal: #ff9b58; - --electric: #24ebff; - --electric-strong: #2bf3ff; - --accent: #ff9b58; - --line: #2c4d72; - --line-soft: #3c5775; - --line-edge: #ffffff18; - --line-rail: #6df2ff2a; - --da-body-overlay: url('/assets/da/v3-circuit-grid.svg'); - --da-body-overlay-size: 195px 195px; - --da-body-overlay-opacity: 0.26; - --da-body-overlay-blend: soft-light; - --da-body-before-opacity: 1; - --da-body-after-opacity: 0.42; - --da-panel-overlay: url('/assets/da/v3-circuit-grid.svg'); - --da-panel-overlay-size: 195px 195px; - --da-panel-overlay-opacity: 0.2; -} - -:root[data-da-variant="v8"] { - --bg: #f4f6fa; - --bg-elevated: #fbfcff; - --surface: #f9fbfe; - --surface-soft: #fdfdff; - --surface-alt: #edf2f8; - --pcb-deep: #eff3f8; - --pcb-core: #f8fbff; - --pcb-ambient: #ecf2f8; - --text: #182132; - --text-muted: #485366; - --text-dim: #6f7f94; - --trace-cyan: #2f86b2; - --trace-cyan-soft: #2f86b2b3; - --trace-magenta: #4ca1d9; - --trace-magenta-soft: #4ca1d9b6; - --trace-green: #8db8de; - --trace-green-soft: #8db8dea0; - --trace-amber: #9cc0d3; - --trace-amber-soft: #9cc0d3a5; - --signal: #4ca1d9; - --electric: #2f86b2; - --electric-strong: #23709a; - --accent: #2f86b2; - --line: #d9e0ec; - --line-soft: #e9eef6; - --line-edge: #18213226; - --line-rail: #2f86b227; - --da-body-overlay: url('/assets/da/v4-minimal-lines.svg'); - --da-body-overlay-size: 220px 220px; - --da-body-overlay-opacity: 0.06; - --da-body-overlay-blend: soft-light; - --da-body-before-opacity: 1; - --da-body-after-opacity: 0.38; - --da-panel-overlay: none; - --da-panel-overlay-size: 0 0; - --da-panel-overlay-opacity: 0; -} - -:root[data-da-variant="v9"] { - --bg: #06142a; - --bg-elevated: #0a2038; - --surface: #0d2440; - --surface-soft: #102f52; - --surface-alt: #112f52; - --pcb-deep: #040d19; - --pcb-core: #0d2037; - --pcb-ambient: #102a4a; - --text: #edf8ff; - --text-muted: #b0ccde; - --text-dim: #96afc5; - --trace-cyan: #24d5ff; - --trace-cyan-soft: #24d5ff88; - --trace-magenta: #ff9f55; - --trace-magenta-soft: #ff9f5580; - --trace-green: #a9ffe2; - --trace-green-soft: #a9ffe29a; - --trace-amber: #ffaf5a; - --trace-amber-soft: #ffaf5a8a; - --signal: #24d5ff; - --electric: #24d5ff; - --electric-strong: #2bf0ff; - --accent: #ff9958; - --line: #2c4d72; - --line-soft: #3c5775; - --line-edge: #ffffff1a; - --line-rail: #6df2ff2a; - --da-body-overlay: url('/assets/da/v3-circuit-grid.svg'); - --da-body-overlay-size: 195px 195px; - --da-body-overlay-opacity: 0.26; - --da-body-overlay-blend: soft-light; - --da-body-before-opacity: 1; - --da-body-after-opacity: 0.42; - --da-panel-overlay: url('/assets/da/v3-circuit-grid.svg'); - --da-panel-overlay-size: 195px 195px; - --da-panel-overlay-opacity: 0.2; -} - -:root[data-da-variant="v10"] { - --bg: #f0e8da; - --bg-elevated: #f8f1e5; - --surface: #fcf6ec; - --surface-soft: #f9f0e4; - --surface-alt: #f2e5d7; - --pcb-deep: #e8dcc8; - --pcb-core: #f0e5d7; - --pcb-ambient: #e9dcc8; - --text: #22201b; - --text-muted: #4b443a; - --text-dim: #6c5f52; - --trace-cyan: #1faab5; - --trace-cyan-soft: #1faab58b; - --trace-magenta: #a66d4a; - --trace-magenta-soft: #a66d4aa4; - --trace-green: #7db9a6; - --trace-green-soft: #7db9a6a0; - --trace-amber: #a66d4a; - --trace-amber-soft: #a66d4a8f; - --signal: #a66d4a; - --electric: #1faab5; - --electric-strong: #1a8d95; - --accent: #1faab5; - --line: #cfc3b7; - --line-soft: #dfd4c7; - --line-edge: #17120f2c; - --line-rail: #1faab52b; - --da-body-overlay: url('/assets/da/v1-editorial-fiber.svg'); - --da-body-overlay-size: 250px 250px; - --da-body-overlay-opacity: 0.12; - --da-body-overlay-blend: multiply; - --da-body-before-opacity: 1; - --da-body-after-opacity: 0.36; - --da-panel-overlay: none; - --da-panel-overlay-size: 0 0; - --da-panel-overlay-opacity: 0; -} - -:root[data-da-variant="v11"] { - --bg: #f8efe2; - --bg-elevated: #fff8ef; - --surface: #fffaf4; - --surface-soft: #fdf3e7; - --surface-alt: #f2ddc5; - --pcb-deep: #eedbc4; - --pcb-core: #f8ebdd; - --pcb-ambient: #f5dfcb; - --text: #2d2319; - --text-muted: #5a493a; - --text-dim: #785f48; - --trace-cyan: #3e7ea0; - --trace-cyan-soft: #3e7ea090; - --trace-magenta: #8a5a38; - --trace-magenta-soft: #8a5a3890; - --trace-green: #b4c4a3; - --trace-green-soft: #b4c4a389; - --trace-amber: #b46339; - --trace-amber-soft: #b463398f; - --signal: #b46339; - --electric: #3e7ea0; - --electric-strong: #2f627f; - --accent: #b46339; - --line: #d5c6b4; - --line-soft: #e4d6c6; - --line-edge: #2d23191e; - --line-rail: #b4633928; - --da-body-overlay: url('/assets/da/v5-poster-grid.svg'); - --da-body-overlay-size: 220px 220px; - --da-body-overlay-opacity: 0.18; - --da-body-overlay-blend: soft-light; - --da-body-before-opacity: 1; - --da-body-after-opacity: 0.44; - --da-panel-overlay: none; - --da-panel-overlay-size: 0 0; - --da-panel-overlay-opacity: 0; -} - -:root[data-da-variant="v7"] body { - background: - linear-gradient(180deg, #04070f 0%, #09162d 52%, #11213f 100%); -} - -:root[data-da-variant="v8"] body { - background: - linear-gradient(180deg, #f3f5f8 0%, #fbfcff 52%, #f0f5fb 100%); -} - -:root[data-da-variant="v10"] body { - background: - linear-gradient(180deg, #f0e8da 0%, #f8efe2 55%, #f3e4cf 100%); -} - -:root[data-da-variant="v11"] body { - background: - linear-gradient(180deg, #f8efe2 0%, #f4e2c8 52%, #f7dfcb 100%); -} - -:root[data-da-variant="v7"] .site-nav { - position: fixed; - top: 0.9rem; - left: 0.9rem; - bottom: 0.9rem; - width: clamp(15.6rem, 20vw, 18rem); - border: 1px solid color-mix(in oklab, var(--line) 86%, transparent); - border-radius: 16px; - overflow: hidden; - box-shadow: 0 22px 48px rgba(3, 8, 23, 0.55); -} - -:root[data-da-variant="v7"] .site-nav:before { - right: auto; - left: 0; - width: 4px; - height: 100%; - animation: none; - opacity: 0.78; - background: linear-gradient(180deg, var(--trace-cyan), var(--trace-magenta)); -} - -:root[data-da-variant="v7"] .site-shell { - width: min(17.2rem, 92vw); - min-height: 100%; -} - -:root[data-da-variant="v7"] .nav-main-row { - grid-template-columns: 1fr; - align-items: stretch; - gap: 0.85rem; -} - -:root[data-da-variant="v7"] .site-shell > div, -:root[data-da-variant="v7"] .site-shell > nav, -:root[data-da-variant="v7"] .site-shell > .nav-tools { - width: 100%; -} - -:root[data-da-variant="v7"] .nav-main-row nav ul, -:root[data-da-variant="v7"] .nav-tools, -:root[data-da-variant="v7"] .nav-sub-row { - display: grid; - width: 100%; -} - -:root[data-da-variant="v7"] .nav-main-row nav ul { - gap: 0.58rem; - justify-items: stretch; -} - -:root[data-da-variant="v7"] .nav-tools, -:root[data-da-variant="v7"] .nav-sub-row { - gap: 0.42rem; -} - -:root[data-da-variant="v7"] .site-navlink { - width: 100%; - justify-content: space-between; - letter-spacing: 0.06em; - padding-inline: 0.78rem; - border-radius: 0.72rem; -} - -:root[data-da-variant="v7"] .site-navlink:after { - content: "→"; - position: static; - transform: none; - opacity: 0.94; - width: auto; - height: auto; - border-radius: 0; - background: none; -} - -:root[data-da-variant="v7"] .site-navlink.is-active { - background: linear-gradient( - 120deg, - color-mix(in oklab, var(--trace-cyan-soft) 42%, transparent), - color-mix(in oklab, var(--trace-green-soft) 34%, transparent) - ); -} - -:root[data-da-variant="v7"] .studio-rail-title, -:root[data-da-variant="v7"] .studio-chip--cyan, -:root[data-da-variant="v7"] .hero-manifest, -:root[data-da-variant="v7"] .dual-cta-rail, -:root[data-da-variant="v7"] .circuit-board, -:root[data-da-variant="v7"] .studio-panel { - border-color: color-mix(in oklab, var(--line) 84%, transparent); - background: linear-gradient(135deg, var(--surface) 0%, var(--surface-soft) 100%); -} - -:root[data-da-variant="v7"] .panel, -:root[data-da-variant="v7"] .project-card, -:root[data-da-variant="v7"] .circuit-card { - border-width: 1px 1px 1px 5px; - border-left-color: color-mix(in oklab, var(--accent) 60%, var(--line) 40%); -} - -:root[data-da-variant="v7"] .studio-structure { - margin-left: calc(clamp(15.6rem, 20vw, 18rem) + 1.2rem); -} - -:root[data-da-variant="v8"] .site-nav { - box-shadow: 0 10px 28px rgba(23, 40, 67, 0.16); -} - -:root[data-da-variant="v8"] .site-navlink { - border: 1px dashed color-mix(in oklab, var(--line) 72%, transparent); - background: color-mix(in oklab, var(--surface) 82%, transparent); -} - -:root[data-da-variant="v8"] .site-navlink.is-active { - background: linear-gradient( - 90deg, - color-mix(in oklab, var(--trace-cyan-soft) 36%, transparent), - transparent - ); -} - -:root[data-da-variant="v8"] .hero-manifest, -:root[data-da-variant="v8"] .circuit-board, -:root[data-da-variant="v8"] .studio-panel { - border-top: 2px dashed color-mix(in oklab, var(--line) 84%, transparent); -} - -:root[data-da-variant="v8"] .panel, -:root[data-da-variant="v8"] .project-card, -:root[data-da-variant="v8"] .circuit-card { - border-style: dashed; - border-left-width: 4px; - border-left-color: var(--trace-cyan); -} - -:root[data-da-variant="v9"] .site-nav { - position: fixed; - top: 0.95rem; - left: 0.95rem; - bottom: 0.95rem; - width: clamp(15.5rem, 20vw, 17rem); - border: 1px solid color-mix(in oklab, var(--line) 80%, transparent); - border-radius: 16px; - overflow: hidden; - box-shadow: 0 24px 52px rgba(3, 8, 23, 0.58); -} - -:root[data-da-variant="v9"] .site-nav:before { - width: 4px; - height: 100%; - right: auto; - left: 0; - background: linear-gradient(180deg, var(--trace-cyan), var(--electric-strong)); - animation: none; -} - -:root[data-da-variant="v9"] .site-shell, -:root[data-da-variant="v9"] .site-nav > .site-shell { - width: min(17rem, 92vw); -} - -:root[data-da-variant="v9"] .site-navlink { - width: 100%; - justify-content: space-between; - letter-spacing: 0.06em; -} - -:root[data-da-variant="v9"] .site-navlink:after { - content: '→'; - position: static; - width: auto; - height: auto; - border-radius: 0; - background: none; - transform: none; -} - -:root[data-da-variant="v9"] .site-navlink.is-active { - background: linear-gradient( - 120deg, - color-mix(in oklab, var(--trace-cyan-soft) 44%, transparent), - color-mix(in oklab, var(--trace-green-soft) 36%, transparent) - ); -} - -:root[data-da-variant="v9"] .site-shell, -:root[data-da-variant="v9"] .studio-structure { - width: min(17rem, 92vw); -} - -:root[data-da-variant="v9"] .studio-structure { - margin-left: calc(clamp(15.5rem, 20vw, 17rem) + 1rem); -} - -:root[data-da-variant="v9"] .panel, -:root[data-da-variant="v9"] .project-card, -:root[data-da-variant="v9"] .circuit-card { - border-left-width: 5px; - border-left-color: var(--accent); -} - -:root[data-da-variant="v10"] .site-nav { - background: linear-gradient(180deg, color-mix(in oklab, var(--surface) 90%, transparent), color-mix(in oklab, var(--surface-soft) 90%, transparent)); -} - -:root[data-da-variant="v10"] .hero-manifest { - border-color: color-mix(in oklab, var(--line) 78%, transparent); -} - -:root[data-da-variant="v10"] .studio-panel, -:root[data-da-variant="v10"] .circuit-board { - box-shadow: 0 12px 22px rgba(31, 38, 47, 0.18); -} - -:root[data-da-variant="v11"] .site-nav { - background: linear-gradient(180deg, color-mix(in oklab, var(--surface) 96%, transparent), color-mix(in oklab, var(--surface-soft) 94%, transparent)); -} - -:root[data-da-variant="v11"] .site-navlink { - border-left: 3px solid transparent; -} - -:root[data-da-variant="v11"] .site-navlink.is-active { - border-left-color: var(--accent); -} - -:root[data-da-variant="v11"] .circuit-card { - border-left-width: 4px; - border-left-color: var(--accent); -} - -:root[data-da-variant="v11"] .studio-chip--cyan, -:root[data-da-variant="v11"] .studio-rail-title { - border-style: dashed; -} - -@media (max-width: 1140px) { - :root[data-da-variant="v7"] .site-nav { - position: sticky; - top: 0; - left: auto; - width: auto; - bottom: auto; - border-radius: 0; - } - - :root[data-da-variant="v7"] .site-nav:before { - width: auto; - height: 2px; - right: 0; - left: 0; - top: auto; - bottom: -1px; - background: linear-gradient( - 90deg, - transparent 0% 46.5%, - color-mix(in oklab, var(--electric) 10%, transparent) 48.5%, - color-mix(in oklab, var(--electric) 18%, transparent), - color-mix(in oklab, var(--signal) 14%, transparent) 51.5%, - transparent 53.5% 100% - ); - } - - :root[data-da-variant="v7"] .site-shell { - width: min(1200px, 92vw); - min-height: auto; - } - - :root[data-da-variant="v7"] .nav-main-row, - :root[data-da-variant="v7"] .nav-main-row nav ul, - :root[data-da-variant="v7"] .nav-tools, - :root[data-da-variant="v7"] .nav-sub-row { - width: 100%; - display: flex; - } - - :root[data-da-variant="v7"] .nav-main-row { - grid-template-columns: 1fr; - } - - :root[data-da-variant="v7"] .site-navlink { - width: auto; - } - - :root[data-da-variant="v7"] .studio-structure { - margin-left: 0; - } - - :root[data-da-variant="v8"] .site-nav { - position: sticky; - top: 0; - left: auto; - width: auto; - bottom: auto; - border-radius: 0; - } - - :root[data-da-variant="v8"] .studio-structure, - :root[data-da-variant="v8"] .site-shell { - width: min(1200px, 92vw); - min-height: auto; - } - - :root[data-da-variant="v9"] .site-nav { - position: sticky; - top: 0; - left: auto; - width: auto; - bottom: auto; - border-radius: 0; - } - - :root[data-da-variant="v9"] .site-nav:before { - width: auto; - height: 2px; - left: 0; - right: 0; - top: auto; - bottom: -1px; - background: linear-gradient( - 90deg, - transparent 0% 46.5%, - color-mix(in oklab, var(--electric) 10%, transparent) 48.5%, - color-mix(in oklab, var(--electric) 18%, transparent), - color-mix(in oklab, var(--signal) 14%, transparent) 51.5%, - transparent 53.5% 100% - ); - } - - :root[data-da-variant="v9"] .studio-structure, - :root[data-da-variant="v9"] .studio-structure .structure-grid { - margin-left: 0; - width: min(1200px, 92vw); - } - - :root[data-da-variant="v9"] .site-nav .site-shell, - :root[data-da-variant="v9"] .site-shell { - width: auto; - } - - :root[data-da-variant="v9"] .site-navlink, - :root[data-da-variant="v10"] .site-navlink, - :root[data-da-variant="v11"] .site-navlink { - width: auto; - } - - :root[data-da-variant="v10"] .site-shell, - :root[data-da-variant="v10"] .studio-structure, - :root[data-da-variant="v11"] .site-shell, - :root[data-da-variant="v11"] .studio-structure { - width: min(1200px, 92vw); - min-height: auto; - } -} body { letter-spacing: 0.002em; background: @@ -3392,28 +1394,6 @@ body:before { auto; background-repeat: repeat; } -@supports (color: color-mix(in lab, red, red)) { - body:before { - background-image: - var(--da-body-overlay), - repeating-linear-gradient( - 90deg, - transparent 0 24px, - color-mix(in oklab, var(--line-rail) 56%, transparent) 24px 25px, - transparent 25px 48px - ), - repeating-linear-gradient( - 0deg, - transparent 0 24px, - color-mix(in oklab, var(--line-rail) 36%, transparent) 24px 25px, - transparent 25px 48px - ); - background-size: - var(--da-body-overlay-size), - auto, - auto; - } -} body:after { opacity: var(--da-body-after-opacity); -webkit-mask-image: radial-gradient(circle at 50% 18%, #000 20%, #0000 70%); @@ -3449,12 +1429,7 @@ li { .site-contrast-toggle, .lab-kicker, .lab-pill, -.nav-status, -.studio-chip, -.dual-cta-label, -.projects-timeline-year, -.lab-note-date, -.system-pipeline-index { +.studio-chip { font-family: IBM Plex Mono, ui-monospace, @@ -3468,24 +1443,9 @@ li { .site-nav { background: linear-gradient(180deg, var(--pcb-core), var(--pcb-core)); } -@supports (color: color-mix(in lab, red, red)) { - .site-nav { - background: linear-gradient( - 180deg, - color-mix(in oklab, var(--pcb-core) 88%, transparent), - color-mix(in oklab, var(--pcb-core) 70%, transparent) - ); - } -} .site-nav { border-bottom: 1px solid var(--line-edge); } -@supports (color: color-mix(in lab, red, red)) { - .site-nav { - border-bottom: 1px solid - color-mix(in oklab, var(--line-edge) 85%, transparent); - } -} .site-nav { -webkit-backdrop-filter: blur(12px); backdrop-filter: blur(12px); @@ -3510,15 +1470,6 @@ li { .site-nav.is-compact { background: linear-gradient(180deg, var(--pcb-core), var(--pcb-core)); } -@supports (color: color-mix(in lab, red, red)) { - .site-nav.is-compact { - background: linear-gradient( - 180deg, - color-mix(in oklab, var(--pcb-core) 96%, transparent), - color-mix(in oklab, var(--pcb-core) 84%, transparent) - ); - } -} .site-nav.is-compact { box-shadow: inset 0 1px #ffffff2e, @@ -3543,30 +1494,15 @@ li { border-radius: 0.32rem; min-height: 2rem; } -@supports (color: color-mix(in lab, red, red)) { - .site-navlink { - border: 1px solid color-mix(in oklab, var(--line-soft) 88%, transparent); - } -} .site-navlink { background: var(--surface-soft); } -@supports (color: color-mix(in lab, red, red)) { - .site-navlink { - background: color-mix(in oklab, var(--surface-soft) 56%, transparent); - } -} .site-navlink { letter-spacing: 0.06em; text-transform: uppercase; color: var(--text); font-size: 0.72rem; } -@supports (color: color-mix(in lab, red, red)) { - .site-navlink { - color: color-mix(in oklab, var(--text) 88%, var(--electric) 12%); - } -} .site-navlink:after { height: 1px; bottom: 0.18rem; @@ -3578,12 +1514,6 @@ li { border-color: var(--electric); transform: translateY(-1px); } -@supports (color: color-mix(in lab, red, red)) { - .site-navlink:hover, - .site-navlink:focus-visible { - border-color: color-mix(in oklab, var(--electric) 72%, transparent); - } -} .site-navlink:hover, .site-navlink:focus-visible { background: linear-gradient( @@ -3592,16 +1522,6 @@ li { var(--trace-green-soft) ); } -@supports (color: color-mix(in lab, red, red)) { - .site-navlink:hover, - .site-navlink:focus-visible { - background: linear-gradient( - 120deg, - color-mix(in oklab, var(--trace-cyan-soft) 20%, transparent), - color-mix(in oklab, var(--trace-green-soft) 16%, transparent) - ); - } -} .site-navlink:hover, .site-navlink:focus-visible { box-shadow: @@ -3612,12 +1532,6 @@ li { .site-navlink[aria-current="location"] { border-color: var(--signal); } -@supports (color: color-mix(in lab, red, red)) { - .site-navlink.is-active, - .site-navlink[aria-current="location"] { - border-color: color-mix(in oklab, var(--signal) 74%, transparent); - } -} .site-navlink.is-active, .site-navlink[aria-current="location"] { background: linear-gradient( @@ -3626,26 +1540,10 @@ li { var(--trace-cyan-soft) ); } -@supports (color: color-mix(in lab, red, red)) { - .site-navlink.is-active, - .site-navlink[aria-current="location"] { - background: linear-gradient( - 120deg, - color-mix(in oklab, var(--trace-green-soft) 24%, transparent), - color-mix(in oklab, var(--trace-cyan-soft) 18%, transparent) - ); - } -} .site-navlink.is-active, .site-navlink[aria-current="location"] { color: var(--text); } -@supports (color: color-mix(in lab, red, red)) { - .site-navlink.is-active, - .site-navlink[aria-current="location"] { - color: color-mix(in oklab, var(--text) 84%, var(--signal) 16%); - } -} .site-navlink.is-active, .site-navlink[aria-current="location"] { box-shadow: inset 0 0 0 1px @@ -3656,47 +1554,12 @@ li { .site-navlink[aria-current="location"]:not(:hover):not(:focus-visible) { animation: none; } -.nav-status { - border: 1px solid var(--trace-amber-soft); - border-radius: 0.3rem; -} -@supports (color: color-mix(in lab, red, red)) { - .nav-status { - border: 1px solid - color-mix(in oklab, var(--trace-amber-soft) 74%, transparent); - } -} -.nav-status { - background: linear-gradient( - 90deg, - var(--trace-amber-soft), - var(--trace-magenta-soft) - ); -} -@supports (color: color-mix(in lab, red, red)) { - .nav-status { - background: linear-gradient( - 90deg, - color-mix(in oklab, var(--trace-amber-soft) 20%, transparent), - color-mix(in oklab, var(--trace-magenta-soft) 12%, transparent) - ); - } -} -.nav-status { - letter-spacing: 0.14em; - font-size: 0.62rem; -} .lab-pill { letter-spacing: 0.12em; border-color: var(--trace-cyan-soft); border-radius: 0.3rem; font-size: 0.64rem; } -@supports (color: color-mix(in lab, red, red)) { - .lab-pill { - border-color: color-mix(in oklab, var(--trace-cyan-soft) 78%, transparent); - } -} .lab-pill { background: linear-gradient( 90deg, @@ -3704,15 +1567,6 @@ li { var(--trace-green-soft) ); } -@supports (color: color-mix(in lab, red, red)) { - .lab-pill { - background: linear-gradient( - 90deg, - color-mix(in oklab, var(--trace-cyan-soft) 24%, transparent), - color-mix(in oklab, var(--trace-green-soft) 14%, transparent) - ); - } -} .lab-kicker { letter-spacing: 0.13em; border-radius: 0.3rem; @@ -3733,13 +1587,6 @@ li { .studio-panel { border: 1px solid var(--line); } -@supports (color: color-mix(in lab, red, red)) { - .circuit-board, - .lab-panel, - .studio-panel { - border: 1px solid color-mix(in oklab, var(--line) 90%, transparent); - } -} .circuit-board, .lab-panel, .studio-panel { @@ -3752,26 +1599,7 @@ li { transparent ), linear-gradient(180deg, var(--surface), var(--surface-alt)); - border-radius: 0.82rem; -} -@supports (color: color-mix(in lab, red, red)) { - .circuit-board, - .lab-panel, - .studio-panel { - background: - linear-gradient( - 130deg, - color-mix(in oklab, var(--trace-cyan-soft) 9%, transparent), - transparent 32%, - color-mix(in oklab, var(--trace-magenta-soft) 7%, transparent) 68%, - transparent - ), - linear-gradient( - 180deg, - color-mix(in oklab, var(--surface) 86%, transparent), - color-mix(in oklab, var(--surface-alt) 92%, transparent) - ); - } + border-radius: var(--card-radius); } .circuit-board, .lab-panel, @@ -3800,25 +1628,6 @@ li { -webkit-mask-image: none; mask-image: none; } -@supports (color: color-mix(in lab, red, red)) { - .circuit-board:before, - .lab-panel:before, - .studio-panel:before { - background-image: - repeating-linear-gradient( - 0deg, - transparent 0 18px, - color-mix(in oklab, var(--trace-cyan-soft) 20%, transparent) 18px 19px, - transparent 19px 36px - ), - repeating-linear-gradient( - 90deg, - transparent 0 24px, - color-mix(in oklab, var(--trace-green-soft) 24%, transparent) 24px 25px, - transparent 25px 48px - ); - } -} .circuit-board:before, .lab-panel:before, .studio-panel:before { @@ -3833,13 +1642,6 @@ li { border-radius: 0.65rem; inset: 10px; } -@supports (color: color-mix(in lab, red, red)) { - .circuit-board:after, - .studio-panel:after, - .lab-panel:after { - border-color: color-mix(in oklab, var(--line-soft) 52%, transparent); - } -} .circuit-board:after, .studio-panel:after, .lab-panel:after { @@ -3850,23 +1652,9 @@ li { border-color: var(--line-soft); border-radius: 0.72rem; } -@supports (color: color-mix(in lab, red, red)) { - .circuit-card { - border-color: color-mix(in oklab, var(--line-soft) 88%, transparent); - } -} .circuit-card { background: linear-gradient(180deg, var(--surface-alt), var(--surface)); } -@supports (color: color-mix(in lab, red, red)) { - .circuit-card { - background: linear-gradient( - 180deg, - color-mix(in oklab, var(--surface-alt) 90%, transparent), - color-mix(in oklab, var(--surface) 82%, transparent) - ); - } -} .circuit-card { box-shadow: 0 14px 28px rgba(77, 60, 32, 0.16), @@ -3882,34 +1670,17 @@ li { .studio-chip--cyan { color: var(--electric); } -@supports (color: color-mix(in lab, red, red)) { - .studio-chip--cyan { - color: color-mix(in oklab, var(--electric) 84%, white 16%); - } -} .studio-chip--pink { color: var(--accent); } -@supports (color: color-mix(in lab, red, red)) { - .studio-chip--pink { - color: color-mix(in oklab, var(--accent) 80%, white 20%); - } -} .studio-chip--emerald { color: var(--signal); } -@supports (color: color-mix(in lab, red, red)) { - .studio-chip--emerald { - color: color-mix(in oklab, var(--signal) 82%, white 18%); - } -} .studio-chip--vio { color: var(--text); } -@supports (color: color-mix(in lab, red, red)) { - .studio-chip--vio { - color: color-mix(in oklab, var(--text) 88%, var(--trace-cyan) 12%); - } +.studio-chip--amber { + color: var(--trace-magenta); } .studio-link { color: var(--electric); @@ -3921,151 +1692,9 @@ li { .studio-link:focus-visible { color: var(--signal); } -@supports (color: color-mix(in lab, red, red)) { - .studio-link:hover, - .studio-link:focus-visible { - color: color-mix(in oklab, var(--signal) 70%, var(--electric) 30%); - } -} -.hero-manifest { - border-color: var(--line-soft); - border-radius: 0.52rem; -} -@supports (color: color-mix(in lab, red, red)) { - .hero-manifest { - border-color: color-mix(in oklab, var(--line-soft) 88%, transparent); - } -} -.hero-manifest { - background: linear-gradient( - 90deg, - var(--trace-green-soft), - transparent 45%, - var(--trace-cyan-soft) - ); -} -@supports (color: color-mix(in lab, red, red)) { - .hero-manifest { - background: linear-gradient( - 90deg, - color-mix(in oklab, var(--trace-green-soft) 10%, transparent), - transparent 45%, - color-mix(in oklab, var(--trace-cyan-soft) 10%, transparent) - ); - } -} -.hero-manifest-row { - font-size: 0.85rem; -} -.dual-cta-rail { - border-color: var(--line-soft); - border-radius: 0.58rem; -} -@supports (color: color-mix(in lab, red, red)) { - .dual-cta-rail { - border-color: color-mix(in oklab, var(--line-soft) 90%, transparent); - } -} -.dual-cta-rail { - background: linear-gradient( - 120deg, - var(--trace-cyan-soft), - var(--trace-green-soft) - ); -} -@supports (color: color-mix(in lab, red, red)) { - .dual-cta-rail { - background: linear-gradient( - 120deg, - color-mix(in oklab, var(--trace-cyan-soft) 14%, transparent), - color-mix(in oklab, var(--trace-green-soft) 12%, transparent) - ); - } -} -.dual-cta-actions { - gap: 0.46rem; -} -.dual-cta-helper { - color: var(--text-muted); - margin: 0.46rem 0 0; - font-size: 0.78rem; - line-height: 1.4; -} -.flow-node-card, -.system-pipeline-link, -.projects-timeline-content, -.lab-note-card, -.trust-pill, -.logo-lab-card { - border-radius: 0.58rem; -} -.flow-node-card { - background: linear-gradient(180deg, var(--surface), var(--surface-alt)); -} -@supports (color: color-mix(in lab, red, red)) { - .flow-node-card { - background: linear-gradient( - 180deg, - color-mix(in oklab, var(--surface) 86%, transparent), - color-mix(in oklab, var(--surface-alt) 90%, transparent) - ); - } -} -.flow-node-card:hover, -.flow-node-card:focus-visible { - border-color: var(--signal); -} -@supports (color: color-mix(in lab, red, red)) { - .flow-node-card:hover, - .flow-node-card:focus-visible { - border-color: color-mix(in oklab, var(--signal) 64%, transparent); - } -} -.flow-edge:before { - animation: none; -} -.system-pipeline-link { - background: linear-gradient( - 102deg, - var(--trace-cyan-soft), - var(--trace-amber-soft) - ); -} -@supports (color: color-mix(in lab, red, red)) { - .system-pipeline-link { - background: linear-gradient( - 102deg, - color-mix(in oklab, var(--trace-cyan-soft) 12%, transparent), - color-mix(in oklab, var(--trace-amber-soft) 10%, transparent) - ); - } -} -.system-pipeline-link:hover, -.system-pipeline-link:focus-visible { - border-color: var(--signal); -} -@supports (color: color-mix(in lab, red, red)) { - .system-pipeline-link:hover, - .system-pipeline-link:focus-visible { - border-color: color-mix(in oklab, var(--signal) 58%, transparent); - } -} -.projects-timeline { - border-left-color: var(--trace-cyan-soft); -} -@supports (color: color-mix(in lab, red, red)) { - .projects-timeline { - border-left-color: color-mix( - in oklab, - var(--trace-cyan-soft) 64%, - transparent - ); - } -} .projects-timeline-item:before { border-radius: 1px; } -.lab-note-flow code, code { background: var(--surface-soft); font-family: @@ -4075,23 +1704,9 @@ code { Consolas, monospace; } -@supports (color: color-mix(in lab, red, red)) { - .lab-note-flow code, - code { - background: color-mix(in oklab, var(--surface-soft) 84%, transparent); - } -} -.lab-note-flow code, code { border: 1px solid var(--line-soft); } -@supports (color: color-mix(in lab, red, red)) { - .lab-note-flow code, - code { - border: 1px solid color-mix(in oklab, var(--line-soft) 72%, transparent); - } -} -.lab-note-flow code, code { border-radius: 0.28rem; padding: 0.06rem 0.28rem; @@ -4101,27 +1716,9 @@ footer { position: relative; border-top-color: var(--line-soft) !important; } -@supports (color: color-mix(in lab, red, red)) { - footer { - border-top-color: color-mix( - in oklab, - var(--line-soft) 84%, - transparent - ) !important; - } -} footer { background: linear-gradient(180deg, var(--surface-alt), var(--bg)); } -@supports (color: color-mix(in lab, red, red)) { - footer { - background: linear-gradient( - 180deg, - color-mix(in oklab, var(--surface-alt) 34%, transparent), - color-mix(in oklab, var(--bg) 86%, transparent) - ); - } -} footer:before { content: ""; background: linear-gradient( @@ -4138,106 +1735,256 @@ footer:before { left: 0; right: 0; } -@keyframes v3ProgressFlow { - 0% { - background-position: 0%; + +/* ── Consolidated color-mix enhancements (v12 variant) ── */ +@supports (color: color-mix(in lab, red, red)) { + + body:before { + background-image: + var(--da-body-overlay), + repeating-linear-gradient( + 90deg, + transparent 0 24px, + color-mix(in oklab, var(--line-rail) 56%, transparent) 24px 25px, + transparent 25px 48px + ), + repeating-linear-gradient( + 0deg, + transparent 0 24px, + color-mix(in oklab, var(--line-rail) 36%, transparent) 24px 25px, + transparent 25px 48px + ); + background-size: + var(--da-body-overlay-size), + auto, + auto; } - to { - background-position: 240%; - } -} -@keyframes v3Scanline { - 0%, - 46% { - opacity: 0; - transform: translate(-108%); - } - 50% { - opacity: 0.85; - } - 72% { - opacity: 0.35; - transform: translate(126%); - } - to { - opacity: 0; - transform: translate(126%); - } -} -@keyframes v3NavPulse { - 0%, - to { - box-shadow: - inset 0 0 0 1px color-mix(in oklab, var(--signal) 20%, transparent), - 0 0 12px color-mix(in oklab, var(--electric) 12%, transparent); - } - 50% { - box-shadow: - inset 0 0 0 1px color-mix(in oklab, var(--signal) 32%, transparent), - 0 0 20px color-mix(in oklab, var(--electric) 18%, transparent); - } -} -@keyframes v3NavJitter { - 0% { - transform: translate(0); - } - 25% { - transform: translate(0.45px, -0.3px); - } - 50% { - transform: translate(-0.45px, 0.28px); - } - 75% { - transform: translate(0.28px, 0.28px); - } - to { - transform: translate(0); - } -} -@keyframes v3TraceDrift { - 0% { - background-position: - 0 0, - 0 0; - } - to { - background-position: - 0 48px, - 48px 0; - } -} -@keyframes v3PanelPulse { - 0%, - to { - opacity: 0.4; - } - 50% { - opacity: 0.68; - } -} -@keyframes v3SignalTravel { - 0% { - opacity: 0.42; - background-position: 0 0; - } - 50% { - opacity: 0.84; - } - to { - opacity: 0.42; - background-position: 1.8rem 0; + + .site-nav { + background: linear-gradient( + 180deg, + color-mix(in oklab, var(--pcb-core) 88%, transparent), + color-mix(in oklab, var(--pcb-core) 70%, transparent) + ); } + + .site-nav { + border-bottom: 1px solid + color-mix(in oklab, var(--line-edge) 85%, transparent); + } + + .site-nav.is-compact { + background: linear-gradient( + 180deg, + color-mix(in oklab, var(--pcb-core) 96%, transparent), + color-mix(in oklab, var(--pcb-core) 84%, transparent) + ); + } + + .site-navlink { + border: 1px solid color-mix(in oklab, var(--line-soft) 88%, transparent); + } + + .site-navlink { + background: color-mix(in oklab, var(--surface-soft) 56%, transparent); + } + + .site-navlink { + color: color-mix(in oklab, var(--text) 88%, var(--electric) 12%); + } + + .site-navlink:hover, + .site-navlink:focus-visible { + border-color: color-mix(in oklab, var(--electric) 72%, transparent); + } + + .site-navlink:hover, + .site-navlink:focus-visible { + background: linear-gradient( + 120deg, + color-mix(in oklab, var(--trace-cyan-soft) 20%, transparent), + color-mix(in oklab, var(--trace-green-soft) 16%, transparent) + ); + } + + .site-navlink.is-active, + .site-navlink[aria-current="location"] { + border-color: color-mix(in oklab, var(--signal) 74%, transparent); + } + + .site-navlink.is-active, + .site-navlink[aria-current="location"] { + background: linear-gradient( + 120deg, + color-mix(in oklab, var(--trace-green-soft) 24%, transparent), + color-mix(in oklab, var(--trace-cyan-soft) 18%, transparent) + ); + } + + .site-navlink.is-active, + .site-navlink[aria-current="location"] { + color: color-mix(in oklab, var(--text) 84%, var(--signal) 16%); + } + + .lab-pill { + border-color: color-mix(in oklab, var(--trace-cyan-soft) 78%, transparent); + } + + .lab-pill { + background: linear-gradient( + 90deg, + color-mix(in oklab, var(--trace-cyan-soft) 24%, transparent), + color-mix(in oklab, var(--trace-green-soft) 14%, transparent) + ); + } + + .circuit-board, + .lab-panel, + .studio-panel { + border: 1px solid color-mix(in oklab, var(--line) 90%, transparent); + } + + .circuit-board, + .lab-panel, + .studio-panel { + background: + linear-gradient( + 130deg, + color-mix(in oklab, var(--trace-cyan-soft) 9%, transparent), + transparent 32%, + color-mix(in oklab, var(--trace-magenta-soft) 7%, transparent) 68%, + transparent + ), + linear-gradient( + 180deg, + color-mix(in oklab, var(--surface) 86%, transparent), + color-mix(in oklab, var(--surface-alt) 92%, transparent) + ); + } + + .circuit-board:before, + .lab-panel:before, + .studio-panel:before { + background-image: + repeating-linear-gradient( + 0deg, + transparent 0 18px, + color-mix(in oklab, var(--trace-cyan-soft) 20%, transparent) 18px 19px, + transparent 19px 36px + ), + repeating-linear-gradient( + 90deg, + transparent 0 24px, + color-mix(in oklab, var(--trace-green-soft) 24%, transparent) 24px 25px, + transparent 25px 48px + ); + } + + .circuit-board:after, + .studio-panel:after, + .lab-panel:after { + border-color: color-mix(in oklab, var(--line-soft) 52%, transparent); + } + + .circuit-card { + border-color: color-mix(in oklab, var(--line-soft) 88%, transparent); + } + + .circuit-card { + background: linear-gradient( + 180deg, + color-mix(in oklab, var(--surface-alt) 90%, transparent), + color-mix(in oklab, var(--surface) 82%, transparent) + ); + } + + .studio-chip--cyan { + color: color-mix(in oklab, var(--electric) 84%, white 16%); + } + + .studio-chip--pink { + color: color-mix(in oklab, var(--accent) 80%, white 20%); + } + + .studio-chip--emerald { + color: color-mix(in oklab, var(--signal) 82%, white 18%); + } + + .studio-chip--vio { + color: color-mix(in oklab, var(--text) 88%, var(--trace-cyan) 12%); + } + + .studio-chip--amber { + color: color-mix(in oklab, var(--trace-magenta) 82%, white 18%); + } + + .studio-link:hover, + .studio-link:focus-visible { + color: color-mix(in oklab, var(--signal) 70%, var(--electric) 30%); + } + + code { + background: color-mix(in oklab, var(--surface-soft) 84%, transparent); + } + + code { + border: 1px solid color-mix(in oklab, var(--line-soft) 72%, transparent); + } + + footer { + border-top-color: color-mix( + in oklab, + var(--line-soft) 84%, + transparent + ) !important; + } + + footer { + background: linear-gradient( + 180deg, + color-mix(in oklab, var(--surface-alt) 34%, transparent), + color-mix(in oklab, var(--bg) 86%, transparent) + ); + } + + .footer-link { + border: 1px solid color-mix(in oklab, var(--line-soft) 82%, transparent); + } + + .footer-link { + background: color-mix(in oklab, var(--surface-soft) 80%, transparent); + } + + .footer-link { + color: color-mix(in oklab, var(--text) 88%, var(--electric) 12%); + } + + .footer-link:hover, + .footer-link:focus-visible { + border-color: color-mix(in oklab, var(--electric) 70%, transparent); + } + + .footer-link:hover, + .footer-link:focus-visible { + background: linear-gradient( + 120deg, + color-mix(in oklab, var(--trace-cyan-soft) 18%, transparent), + color-mix(in oklab, var(--trace-green-soft) 14%, transparent) + ); + } + } + @media (max-width: 1024px) { + .site-navlink { padding-inline: 0.58rem; font-size: 0.68rem; } - .nav-status { - display: none; - } + } @media (max-width: 767px) { + .site-nav .site-shell { gap: 0.55rem; } @@ -4248,108 +1995,30 @@ footer:before { min-height: 1.9rem; font-size: 0.64rem; } - .dual-cta-label { - font-size: 0.62rem; - } + } @media (max-width: 390px) { + .site-shell { width: min(1200px, 94vw); } - .hero-manifest { - padding: 0.58rem 0.62rem; - } - .hero-manifest-row { - font-size: 0.78rem; - } + } @media (prefers-reduced-motion: reduce) { - .site-nav:before, - .site-nav:after, - .site-navlink.is-active, - .site-navlink[aria-current="location"], - .flow-edge:before, - .circuit-board:before, - .circuit-board:after, - .lab-panel:before, - .lab-panel:after, - .studio-panel:before, - .studio-panel:after { + +.site-nav:before, +.site-nav:after, +.site-navlink.is-active, +.site-navlink[aria-current="location"], +.circuit-board:before, +.circuit-board:after, +.lab-panel:before, +.lab-panel:after, +.studio-panel:before, +.studio-panel:after { animation: none !important; } -} -.nav-main-row { - grid-template-columns: auto minmax(0, 1fr) auto; - align-items: center; - gap: 0.8rem 1rem; - display: grid; -} -.nav-main-row nav { - width: 100%; -} -.nav-main-row nav ul { - flex-wrap: wrap; - justify-content: center; -} -.nav-tools { - flex-wrap: wrap; - justify-content: flex-end; - align-items: center; - gap: 0.45rem; - display: inline-flex; -} -.nav-sub-row { - flex-wrap: wrap; - align-items: center; - gap: 0.35rem; - padding-bottom: 0.55rem; - display: flex; -} -.nav-sub-chip { - border: 1px solid var(--line-soft); - border-radius: 0.22rem; - align-items: center; - min-height: 1.55rem; - display: inline-flex; -} -@supports (color: color-mix(in lab, red, red)) { - .nav-sub-chip { - border: 1px solid color-mix(in oklab, var(--line-soft) 84%, transparent); - } -} -.nav-sub-chip { - background: - linear-gradient(104deg, var(--trace-cyan-soft), var(--trace-magenta-soft)), - var(--surface-soft); -} -@supports (color: color-mix(in lab, red, red)) { - .nav-sub-chip { - background: - linear-gradient( - 104deg, - color-mix(in oklab, var(--trace-cyan-soft) 14%, transparent), - color-mix(in oklab, var(--trace-magenta-soft) 9%, transparent) - ), - color-mix(in oklab, var(--surface-soft) 86%, transparent); - } -} -.nav-sub-chip { - letter-spacing: 0.1em; - text-transform: uppercase; - color: var(--text-muted); - padding: 0 0.52rem; - font-family: - IBM Plex Mono, - ui-monospace, - Menlo, - Consolas, - monospace; - font-size: 0.62rem; -} -@supports (color: color-mix(in lab, red, red)) { - .nav-sub-chip { - color: color-mix(in oklab, var(--text-muted) 72%, var(--electric) 28%); - } + } .studio-structure { gap: 1rem; @@ -4367,12 +2036,14 @@ footer:before { transform: translateY(0); } @media (prefers-reduced-motion: reduce) { + [data-reveal], [data-reveal].is-revealed { opacity: 1; transform: none; transition: none; } + } .structure-grid { grid-template-columns: minmax(0, 1fr); @@ -4419,27 +2090,12 @@ footer:before { min-height: 2rem; display: inline-flex; } -@supports (color: color-mix(in lab, red, red)) { - .footer-link { - border: 1px solid color-mix(in oklab, var(--line-soft) 82%, transparent); - } -} .footer-link { background: var(--surface-soft); } -@supports (color: color-mix(in lab, red, red)) { - .footer-link { - background: color-mix(in oklab, var(--surface-soft) 80%, transparent); - } -} .footer-link { color: var(--text); } -@supports (color: color-mix(in lab, red, red)) { - .footer-link { - color: color-mix(in oklab, var(--text) 88%, var(--electric) 12%); - } -} .footer-link { letter-spacing: 0.08em; text-transform: uppercase; @@ -4461,12 +2117,6 @@ footer:before { .footer-link:focus-visible { border-color: var(--electric); } -@supports (color: color-mix(in lab, red, red)) { - .footer-link:hover, - .footer-link:focus-visible { - border-color: color-mix(in oklab, var(--electric) 70%, transparent); - } -} .footer-link:hover, .footer-link:focus-visible { background: linear-gradient( @@ -4475,16 +2125,6 @@ footer:before { var(--trace-green-soft) ); } -@supports (color: color-mix(in lab, red, red)) { - .footer-link:hover, - .footer-link:focus-visible { - background: linear-gradient( - 120deg, - color-mix(in oklab, var(--trace-cyan-soft) 18%, transparent), - color-mix(in oklab, var(--trace-green-soft) 14%, transparent) - ); - } -} .footer-link:hover, .footer-link:focus-visible { transform: translateY(-1px); @@ -4518,57 +2158,6 @@ footer:before { font-size: 0.92rem; line-height: 1.5; } -.section-signal-row { - flex-wrap: wrap; - gap: 0.35rem; - display: flex; -} -.section-signal-chip { - border: 1px solid var(--line-soft); - border-radius: 0.22rem; - align-items: center; - min-height: 1.45rem; - display: inline-flex; -} -@supports (color: color-mix(in lab, red, red)) { - .section-signal-chip { - border: 1px solid color-mix(in oklab, var(--line-soft) 84%, transparent); - } -} -.section-signal-chip { - background: - linear-gradient(112deg, var(--trace-green-soft), var(--trace-cyan-soft)), - var(--surface-soft); -} -@supports (color: color-mix(in lab, red, red)) { - .section-signal-chip { - background: - linear-gradient( - 112deg, - color-mix(in oklab, var(--trace-green-soft) 14%, transparent), - color-mix(in oklab, var(--trace-cyan-soft) 12%, transparent) - ), - color-mix(in oklab, var(--surface-soft) 86%, transparent); - } -} -.section-signal-chip { - letter-spacing: 0.09em; - text-transform: uppercase; - color: var(--text-muted); - padding: 0 0.48rem; - font-family: - IBM Plex Mono, - ui-monospace, - Menlo, - Consolas, - monospace; - font-size: 0.58rem; -} -@supports (color: color-mix(in lab, red, red)) { - .section-signal-chip { - color: color-mix(in oklab, var(--text-muted) 70%, var(--signal) 30%); - } -} .project-stage { letter-spacing: 0.11em; text-transform: uppercase; @@ -4582,160 +2171,8 @@ footer:before { monospace; font-size: 0.62rem; } -.project-reference-panel { - border: 1px solid var(--line-soft); -} -@supports (color: color-mix(in lab, red, red)) { - .project-reference-panel { - border: 1px solid color-mix(in oklab, var(--line-soft) 86%, transparent); - } -} -.project-reference-panel { - background: - linear-gradient(112deg, var(--trace-cyan-soft), var(--trace-green-soft)), - var(--surface-alt); - border-radius: 0.58rem; -} -@supports (color: color-mix(in lab, red, red)) { - .project-reference-panel { - background: - linear-gradient( - 112deg, - color-mix(in oklab, var(--trace-cyan-soft) 10%, transparent), - color-mix(in oklab, var(--trace-green-soft) 8%, transparent) - ), - color-mix(in oklab, var(--surface-alt) 88%, transparent); - } -} -.project-reference-panel { - padding: 0.78rem 0.82rem; -} -.project-reference-title { - letter-spacing: 0.1em; - text-transform: uppercase; - color: var(--text-dim); - margin: 0; - font-family: - IBM Plex Mono, - ui-monospace, - Menlo, - Consolas, - monospace; - font-size: 0.66rem; -} -.project-reference-list { - grid-template-columns: 1fr; - gap: 0.3rem; - margin: 0.55rem 0 0; - padding: 0; - list-style: none; - display: grid; -} -.project-reference-link { - color: var(--electric); - letter-spacing: 0.03em; - font-family: - IBM Plex Mono, - ui-monospace, - Menlo, - Consolas, - monospace; - font-size: 0.74rem; - text-decoration: none; - overflow-wrap: anywhere; -} -.project-reference-link:hover, -.project-reference-link:focus-visible { - color: var(--signal); -} -@supports (color: color-mix(in lab, red, red)) { - .project-reference-link:hover, - .project-reference-link:focus-visible { - color: color-mix(in oklab, var(--signal) 66%, var(--electric) 34%); - } -} -.project-reference-link:hover, -.project-reference-link:focus-visible { - text-underline-offset: 3px; - text-decoration: underline; -} -.project-reference-more { - border: 1px solid var(--line-soft); - align-items: center; - min-height: 2rem; - display: inline-flex; -} -@supports (color: color-mix(in lab, red, red)) { - .project-reference-more { - border: 1px solid color-mix(in oklab, var(--line-soft) 84%, transparent); - } -} -.project-reference-more { - letter-spacing: 0.08em; - text-transform: uppercase; - color: var(--electric); - background: var(--surface-soft); - border-radius: 0.28rem; - padding: 0 0.56rem; - font-family: - IBM Plex Mono, - ui-monospace, - Menlo, - Consolas, - monospace; - font-size: 0.68rem; - text-decoration: none; -} -@supports (color: color-mix(in lab, red, red)) { - .project-reference-more { - background: color-mix(in oklab, var(--surface-soft) 82%, transparent); - } -} -.project-reference-more { - transition: - border-color 0.15s, - color 0.15s, - transform 0.15s; -} -.project-reference-more:hover, -.project-reference-more:focus-visible { - border-color: var(--signal); -} -@supports (color: color-mix(in lab, red, red)) { - .project-reference-more:hover, - .project-reference-more:focus-visible { - border-color: color-mix(in oklab, var(--signal) 62%, transparent); - } -} -.project-reference-more:hover, -.project-reference-more:focus-visible { - color: var(--signal); -} -@supports (color: color-mix(in lab, red, red)) { - .project-reference-more:hover, - .project-reference-more:focus-visible { - color: color-mix(in oklab, var(--signal) 72%, var(--electric) 28%); - } -} -.project-reference-more:hover, -.project-reference-more:focus-visible { - transform: translateY(-1px); -} -.trust-pill-detail { - color: var(--text-muted); - margin: 0.22rem 0 0; - font-size: 0.8rem; -} -@media (max-width: 1140px) { - .nav-main-row { - grid-template-columns: auto minmax(0, 1fr); - } - .nav-tools { - grid-column: 1/-1; - justify-content: flex-start; - } -} @media (min-width: 768px) { + .structure-grid--hero { grid-template-columns: minmax(0, 1.35fr) minmax(0, 0.65fr); } @@ -4760,11 +2197,10 @@ footer:before { .footer-links { justify-content: flex-end; } - .project-reference-list { - grid-template-columns: repeat(2, minmax(0, 1fr)); - } + } @media (min-width: 1140px) { + .structure-grid { gap: 1.1rem; } @@ -4783,19 +2219,9 @@ footer:before { .structure-cell--notes { grid-column: auto; } + } @media (max-width: 767px) { - .nav-main-row { - grid-template-columns: 1fr; - gap: 0.55rem; - } - .nav-main-row nav ul, - .nav-tools { - justify-content: flex-start; - } - .nav-sub-row { - padding-bottom: 0.45rem; - } .footer-link { min-height: 1.92rem; font-size: 0.64rem; @@ -4806,33 +2232,26 @@ footer:before { .section-lead { font-size: 0.88rem; } + } @media (max-width: 390px) { - .nav-sub-chip { - letter-spacing: 0.08em; - font-size: 0.58rem; - } .studio-structure, .structure-grid { gap: 0.82rem; } - .project-reference-link { - font-size: 0.68rem; - } - .project-reference-more { - font-size: 0.62rem; - } + } /* Variant v12 - electronic lab notebook direction */ -:root[data-da-variant="v12"] body { +/* DARK MODE (default) */ +:root[data-da-variant="v12"][data-theme="default"] body { background: radial-gradient(980px 560px at 8% -4%, rgba(67, 255, 164, 0.14), transparent 62%), radial-gradient(720px 440px at 88% 0%, rgba(84, 219, 255, 0.13), transparent 64%), linear-gradient(180deg, #07140e 0%, #0b2017 48%, #0a1a13 100%); } -:root[data-da-variant="v12"] body::before { +:root[data-da-variant="v12"][data-theme="default"] body::before { background-image: linear-gradient(to right, rgba(52, 255, 165, 0.08) 1px, transparent 1px), linear-gradient(to bottom, rgba(52, 255, 165, 0.08) 1px, transparent 1px); @@ -4841,7 +2260,7 @@ footer:before { mix-blend-mode: screen; } -:root[data-da-variant="v12"] body::after { +:root[data-da-variant="v12"][data-theme="default"] body::after { background-image: repeating-linear-gradient(90deg, rgba(125, 255, 203, 0.1) 0 2px, transparent 2px 48px), repeating-linear-gradient(0deg, rgba(64, 173, 124, 0.14) 0 1px, transparent 1px 26px); @@ -4851,7 +2270,7 @@ footer:before { -webkit-mask-image: none; } -:root[data-da-variant="v12"] .site-nav { +:root[data-da-variant="v12"][data-theme="default"] .site-nav { background: linear-gradient(180deg, rgba(9, 35, 24, 0.94), rgba(8, 29, 20, 0.94)); border-bottom-color: rgba(70, 176, 124, 0.44); box-shadow: @@ -4859,30 +2278,19 @@ footer:before { 0 16px 32px rgba(0, 0, 0, 0.3); } -:root[data-da-variant="v12"] .site-nav::before { +:root[data-da-variant="v12"][data-theme="default"] .site-nav::before { height: 4px; background: linear-gradient(90deg, #4bffd4 0%, #67ffc2 40%, #f1b874 70%, #4bffd4 100%); } -:root[data-da-variant="v12"] .nav-sub-row { - border-top: 1px solid rgba(62, 145, 106, 0.44); - background: linear-gradient(90deg, rgba(52, 255, 165, 0.08), rgba(47, 116, 93, 0.12) 40%, rgba(241, 184, 116, 0.08)); -} - -:root[data-da-variant="v12"] .nav-sub-chip { - border-color: rgba(119, 255, 205, 0.4); - background: rgba(9, 40, 28, 0.72); - color: #abffd7; -} - -:root[data-da-variant="v12"] .site-navlink { +:root[data-da-variant="v12"][data-theme="default"] .site-navlink { border-color: rgba(94, 196, 143, 0.25); background: rgba(9, 34, 24, 0.66); color: #d6ffe9; } -:root[data-da-variant="v12"] .site-navlink.is-active, -:root[data-da-variant="v12"] .site-navlink[aria-current="location"] { +:root[data-da-variant="v12"][data-theme="default"] .site-navlink.is-active, +:root[data-da-variant="v12"][data-theme="default"] .site-navlink[aria-current="location"] { border-color: rgba(121, 255, 202, 0.75); background: linear-gradient(120deg, rgba(52, 255, 165, 0.22), rgba(241, 184, 116, 0.14)); color: #f1fff8; @@ -4891,63 +2299,21 @@ footer:before { 0 0 20px rgba(87, 255, 189, 0.18); } -:root[data-da-variant="v12"] .hero-instrument-strip { - border: 1px solid rgba(114, 233, 175, 0.36); - border-radius: 0.9rem; - background: - linear-gradient(180deg, rgba(8, 35, 24, 0.88), rgba(11, 29, 21, 0.88)), - repeating-linear-gradient(90deg, rgba(112, 244, 183, 0.12) 0 1px, transparent 1px 22px); - padding: 0.64rem 0.74rem; -} - -:root[data-da-variant="v12"] .hero-instrument-item { - display: flex; - align-items: center; - gap: 0.48rem; - margin: 0; - color: #b4f9d6; - font-family: "IBM Plex Mono", ui-monospace, Menlo, Consolas, monospace; - font-size: 0.73rem; - letter-spacing: 0.04em; - line-height: 1.55; -} - -:root[data-da-variant="v12"] .hero-instrument-item + .hero-instrument-item { - margin-top: 0.22rem; -} - -:root[data-da-variant="v12"] .hero-instrument-dot { - width: 0.46rem; - height: 0.46rem; - border-radius: 50%; - background: #65ffc2; - box-shadow: - 0 0 0 2px rgba(98, 255, 196, 0.22), - 0 0 10px rgba(98, 255, 196, 0.56); -} - -:root[data-da-variant="v12"] .hero-instrument-dot--amber { +:root[data-da-variant="v12"][data-theme="default"] .hero-instrument-dot--amber { background: #f1b874; box-shadow: 0 0 0 2px rgba(241, 184, 116, 0.22), 0 0 10px rgba(241, 184, 116, 0.5); } -:root[data-da-variant="v12"] .hero-instrument-dot--magenta { +:root[data-da-variant="v12"][data-theme="default"] .hero-instrument-dot--magenta { background: #d785ff; box-shadow: 0 0 0 2px rgba(215, 133, 255, 0.22), 0 0 10px rgba(215, 133, 255, 0.5); } -:root[data-da-variant="v12"] .hero-manifest { - border-color: rgba(120, 252, 198, 0.34); - background: - linear-gradient(180deg, rgba(13, 43, 30, 0.74), rgba(10, 31, 22, 0.74)), - repeating-linear-gradient(0deg, rgba(125, 255, 203, 0.08) 0 1px, transparent 1px 20px); -} - -:root[data-da-variant="v12"] .hero-lab-console { +:root[data-da-variant="v12"][data-theme="default"] .hero-lab-console { border-color: rgba(116, 245, 186, 0.38); background: radial-gradient(520px 320px at 18% 8%, rgba(111, 255, 195, 0.16), transparent 64%), @@ -4958,69 +2324,66 @@ footer:before { inset 0 0 0 1px rgba(117, 255, 201, 0.12); } -:root[data-da-variant="v12"] .hero-lab-console figure { +:root[data-da-variant="v12"][data-theme="default"] .hero-lab-console figure { border-color: rgba(121, 255, 202, 0.4); background: rgba(6, 23, 16, 0.86); } -:root[data-da-variant="v12"] .hero-lab-console img { +:root[data-da-variant="v12"][data-theme="default"] .hero-lab-console img { filter: saturate(1.16) contrast(1.06); } -:root[data-da-variant="v12"] .hero-lab-console figcaption { +:root[data-da-variant="v12"][data-theme="default"] .hero-lab-console figcaption { color: #95d3b2; border-top-color: rgba(118, 241, 185, 0.28); } -:root[data-da-variant="v12"] .studio-link { +:root[data-da-variant="v12"][data-theme="default"] .studio-link { color: #9cfdcf; } @media (max-width: 767px) { - :root[data-da-variant="v12"] .hero-instrument-item { - font-size: 0.67rem; - letter-spacing: 0.03em; - } - :root[data-da-variant="v12"] .site-nav { + :root[data-da-variant="v12"][data-theme="default"] .site-nav { backdrop-filter: blur(8px); } + } -:root[data-da-variant="v12"] .figma-lab-hero-grid { +:root[data-da-variant="v12"][data-theme="default"] .figma-lab-hero-grid { display: grid; grid-template-columns: minmax(0, 1.08fr) minmax(0, 0.92fr); gap: 0.62rem; } -:root[data-da-variant="v12"] .figma-lab-left, -:root[data-da-variant="v12"] .figma-lab-right { +:root[data-da-variant="v12"][data-theme="default"] .figma-lab-left, +:root[data-da-variant="v12"][data-theme="default"] .figma-lab-right { border: 2px solid rgba(47, 255, 157, 0.54); border-radius: 0.62rem; background: linear-gradient(180deg, rgba(6, 29, 20, 0.94), rgba(5, 22, 16, 0.94)); box-shadow: 0 0 24px rgba(52, 255, 165, 0.15); } -:root[data-da-variant="v12"] .figma-lab-left { +:root[data-da-variant="v12"][data-theme="default"] .figma-lab-left { padding: 0.62rem; } -:root[data-da-variant="v12"] .figma-lab-title { +:root[data-da-variant="v12"][data-theme="default"] .figma-lab-title { margin: 0; color: #ecffe9; font-size: clamp(1.35rem, 2.2vw, 2rem); line-height: 1.15; } -:root[data-da-variant="v12"] .hero-title-word { +:root[data-da-variant="v12"][data-theme="default"] .hero-title-word { display: inline-block; } -:root[data-da-variant="v12"] .hero-title-word + .hero-title-word { +:root[data-da-variant="v12"][data-theme="default"] .hero-title-word + .hero-title-word { margin-left: 0.34ch; } -:root[data-da-variant="v12"] .figma-lab-copy { +:root[data-da-variant="v12"][data-theme="default"] .figma-lab-copy { margin: 0.42rem 0 0; color: #d3ffe8; font-family: "IBM Plex Mono", ui-monospace, Menlo, Consolas, monospace; @@ -5028,18 +2391,18 @@ footer:before { opacity: 0.9; } -:root[data-da-variant="v12"] .figma-lab-copy--mono { +:root[data-da-variant="v12"][data-theme="default"] .figma-lab-copy--mono { opacity: 0.78; } -:root[data-da-variant="v12"] .figma-lab-cta-row { +:root[data-da-variant="v12"][data-theme="default"] .figma-lab-cta-row { display: flex; gap: 0.44rem; flex-wrap: wrap; margin-top: 0.52rem; } -:root[data-da-variant="v12"] .figma-lab-cta-help { +:root[data-da-variant="v12"][data-theme="default"] .figma-lab-cta-help { margin: 0.36rem 0 0; color: #9fd9bf; font-family: "IBM Plex Mono", ui-monospace, Menlo, Consolas, monospace; @@ -5047,7 +2410,7 @@ footer:before { line-height: 1.35; } -:root[data-da-variant="v12"] .figma-lab-pill { +:root[data-da-variant="v12"][data-theme="default"] .figma-lab-pill { display: inline-flex; align-items: center; min-height: 1.85rem; @@ -5062,13 +2425,13 @@ footer:before { transition: transform 0.14s, background-color 0.14s; } -:root[data-da-variant="v12"] .figma-lab-pill:hover, -:root[data-da-variant="v12"] .figma-lab-pill:focus-visible { +:root[data-da-variant="v12"][data-theme="default"] .figma-lab-pill:hover, +:root[data-da-variant="v12"][data-theme="default"] .figma-lab-pill:focus-visible { transform: translateY(-1px); background: rgba(47, 255, 157, 0.14); } -:root[data-da-variant="v12"] .figma-lab-notes { +:root[data-da-variant="v12"][data-theme="default"] .figma-lab-notes { margin-top: 0.5rem; border: 2px solid #8a7354; border-radius: 0.5rem; @@ -5077,14 +2440,14 @@ footer:before { padding: 0.4rem 0.48rem; } -:root[data-da-variant="v12"] .figma-lab-notes-title { +:root[data-da-variant="v12"][data-theme="default"] .figma-lab-notes-title { margin: 0; font-family: "Fraunces", "Times New Roman", serif; font-weight: 700; font-size: 1rem; } -:root[data-da-variant="v12"] .figma-lab-notes-list { +:root[data-da-variant="v12"][data-theme="default"] .figma-lab-notes-list { margin: 0.2rem 0 0; padding-left: 0; list-style: none; @@ -5093,74 +2456,26 @@ footer:before { line-height: 1.4; } -:root[data-da-variant="v12"] .figma-lab-notes-list li + li { +:root[data-da-variant="v12"][data-theme="default"] .figma-lab-notes-list li + li { margin-top: 0.18rem; } -:root[data-da-variant="v12"] .figma-lab-notebook { - margin: 0.54rem 0 0; - border: 2px solid rgba(47, 255, 157, 0.42); - border-radius: 0.5rem; - overflow: hidden; - background: #062217; -} - -:root[data-da-variant="v12"] .figma-lab-notebook img { - display: block; - width: 100%; - min-height: 180px; - max-height: 280px; - object-fit: cover; - object-position: center 45%; -} - -:root[data-da-variant="v12"] .figma-lab-right { +:root[data-da-variant="v12"][data-theme="default"] .figma-lab-right { display: grid; grid-template-rows: 1fr 1fr; gap: 0.62rem; padding: 0.52rem; } -:root[data-da-variant="v12"] .figma-lab-asset-card { - margin: 0; - border: 2px solid rgba(47, 255, 157, 0.42); - border-radius: 0.5rem; - overflow: hidden; - background: #0b1d16; -} - -:root[data-da-variant="v12"] .figma-lab-asset-card img { - display: block; - width: 100%; - min-height: 180px; - max-height: 250px; - object-fit: cover; - object-position: center; -} - -:root[data-da-variant="v12"] .figma-lab-asset-card figcaption { - border-top: 1px solid rgba(47, 255, 157, 0.34); - padding: 0.26rem 0.34rem 0.34rem; - color: #9ff3c9; - font-family: "IBM Plex Mono", ui-monospace, Menlo, Consolas, monospace; - font-size: 0.6rem; - letter-spacing: 0.02em; - text-transform: lowercase; -} - @media (max-width: 1024px) { - :root[data-da-variant="v12"] .figma-lab-hero-grid { + + :root[data-da-variant="v12"][data-theme="default"] .figma-lab-hero-grid { grid-template-columns: 1fr; } - :root[data-da-variant="v12"] .figma-lab-notebook img, - :root[data-da-variant="v12"] .figma-lab-asset-card img { - min-height: 150px; - max-height: 210px; - } } -:root[data-da-variant="v12"] .figma-lab-nav-row { +:root[data-da-variant="v12"][data-theme="default"] .figma-lab-nav-row { min-height: 2.86rem; display: grid; grid-template-columns: auto 1fr auto; @@ -5169,7 +2484,7 @@ footer:before { padding: 0.32rem 0; } -:root[data-da-variant="v12"] .figma-lab-nav-title { +:root[data-da-variant="v12"][data-theme="default"] .figma-lab-nav-title { color: #d3ffe8; text-decoration: none; font-family: "IBM Plex Mono", ui-monospace, Menlo, Consolas, monospace; @@ -5179,7 +2494,7 @@ footer:before { text-transform: uppercase; } -:root[data-da-variant="v12"] .figma-lab-nav-list { +:root[data-da-variant="v12"][data-theme="default"] .figma-lab-nav-list { margin: 0; padding: 0; display: flex; @@ -5189,7 +2504,7 @@ footer:before { list-style: none; } -:root[data-da-variant="v12"] .figma-lab-nav-link { +:root[data-da-variant="v12"][data-theme="default"] .figma-lab-nav-link { color: #a7ffd4; text-decoration: none; font-family: "IBM Plex Mono", ui-monospace, Menlo, Consolas, monospace; @@ -5199,32 +2514,32 @@ footer:before { transition: border-color 0.15s, color 0.15s; } -:root[data-da-variant="v12"] .figma-lab-nav-link:hover, -:root[data-da-variant="v12"] .figma-lab-nav-link:focus-visible { +:root[data-da-variant="v12"][data-theme="default"] .figma-lab-nav-link:hover, +:root[data-da-variant="v12"][data-theme="default"] .figma-lab-nav-link:focus-visible { color: #d3ffe8; border-bottom-color: rgba(167, 255, 212, 0.65); } -:root[data-da-variant="v12"] .figma-lab-nav-link.is-active, -:root[data-da-variant="v12"] .figma-lab-nav-link[aria-current="location"] { +:root[data-da-variant="v12"][data-theme="default"] .figma-lab-nav-link.is-active, +:root[data-da-variant="v12"][data-theme="default"] .figma-lab-nav-link[aria-current="location"] { color: #d3ffe8; border-bottom-color: rgba(211, 255, 232, 0.92); text-shadow: 0 0 12px rgba(47, 255, 157, 0.28); } -:root[data-da-variant="v12"] .figma-lab-nav-link.is-pressed { +:root[data-da-variant="v12"][data-theme="default"] .figma-lab-nav-link.is-pressed { transform: translateY(1px); } -:root[data-da-variant="v12"] .figma-lab-bottom-map { +:root[data-da-variant="v12"][data-theme="default"] .figma-lab-bottom-map { margin-top: 0.56rem; } -:root[data-da-variant="v12"] .figma-lab-bottom-grid { +:root[data-da-variant="v12"][data-theme="default"] .figma-lab-bottom-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 0.5rem; } -:root[data-da-variant="v12"] .figma-lab-map-card { +:root[data-da-variant="v12"][data-theme="default"] .figma-lab-map-card { min-height: 2.35rem; border: 2px solid transparent; border-radius: 0.46rem; @@ -5238,20 +2553,20 @@ footer:before { transition: transform 0.12s ease, filter 0.12s ease; } -:root[data-da-variant="v12"] .figma-lab-map-card:hover, -:root[data-da-variant="v12"] .figma-lab-map-card:focus-visible { +:root[data-da-variant="v12"][data-theme="default"] .figma-lab-map-card:hover, +:root[data-da-variant="v12"][data-theme="default"] .figma-lab-map-card:focus-visible { transform: translateY(-1px); filter: brightness(1.06); } -:root[data-da-variant="v12"] .figma-lab-map-card.is-active, -:root[data-da-variant="v12"] .figma-lab-map-card[aria-current="location"] { +:root[data-da-variant="v12"][data-theme="default"] .figma-lab-map-card.is-active, +:root[data-da-variant="v12"][data-theme="default"] .figma-lab-map-card[aria-current="location"] { transform: translateY(-1px); filter: brightness(1.12); box-shadow: 0 0 0 1px rgba(47, 255, 157, 0.5), 0 0 18px rgba(47, 255, 157, 0.2); } -:root[data-da-variant="v12"] .figma-lab-map-card.is-pressed { +:root[data-da-variant="v12"][data-theme="default"] .figma-lab-map-card.is-pressed { transform: translateY(1px); } @@ -5261,61 +2576,59 @@ footer:before { line-height: 1.35; } -:root[data-da-variant="v12"] .figma-lab-map-card--cream { +:root[data-da-variant="v12"][data-theme="default"] .figma-lab-map-card--cream { background: #f9efd8; border-color: #8e7555; color: #30271b; } -:root[data-da-variant="v12"] .figma-lab-map-card--blue { +:root[data-da-variant="v12"][data-theme="default"] .figma-lab-map-card--blue { background: #122b3c; border-color: #5ea0ca; color: #d7eeff; } -:root[data-da-variant="v12"] .figma-lab-map-card--green { +:root[data-da-variant="v12"][data-theme="default"] .figma-lab-map-card--green { background: #0f2a20; border-color: #2fff9d; color: #ceffe6; } @media (max-width: 1024px) { - :root[data-da-variant="v12"] .figma-lab-nav-row { + + :root[data-da-variant="v12"][data-theme="default"] .figma-lab-nav-row { grid-template-columns: 1fr; gap: 0.4rem; justify-items: start; } - :root[data-da-variant="v12"] .figma-lab-nav-list { + :root[data-da-variant="v12"][data-theme="default"] .figma-lab-nav-list { justify-content: flex-start; } - :root[data-da-variant="v12"] .figma-lab-bottom-grid { + :root[data-da-variant="v12"][data-theme="default"] .figma-lab-bottom-grid { grid-template-columns: 1fr; } -} -@media (max-width: 767px) { - :root[data-da-variant="v12"] .figma-lab-asset-card img { - min-height: 132px; - max-height: 160px; - object-position: center 42%; - filter: saturate(0.92) contrast(1.02); - } - - :root[data-da-variant="v12"] .figma-lab-notebook img { - min-height: 138px; - max-height: 176px; - object-position: center 40%; - filter: saturate(0.9) contrast(1.01); - } } .structure-grid--sprints { margin-top: 0.46rem; } -:root[data-da-variant="v12"] .graphic-sprints-panel { +.structure-grid + .structure-grid { + margin-top: 4rem; +} + +@media (min-width: 768px) { + + .structure-grid + .structure-grid { + margin-top: 6rem; + } + +} + +:root[data-da-variant="v12"][data-theme="default"] .graphic-sprints-panel { border: 2px solid rgba(48, 255, 162, 0.46); border-radius: 0.68rem; background: @@ -5328,11 +2641,11 @@ footer:before { padding: 0.75rem; } -:root[data-da-variant="v12"] .graphic-sprints-head { +:root[data-da-variant="v12"][data-theme="default"] .graphic-sprints-head { max-width: 78ch; } -:root[data-da-variant="v12"] .graphic-sprints-kicker { +:root[data-da-variant="v12"][data-theme="default"] .graphic-sprints-kicker { margin: 0; font-family: "IBM Plex Mono", ui-monospace, Menlo, Consolas, monospace; font-size: 0.64rem; @@ -5341,28 +2654,28 @@ footer:before { color: #9ff3c9; } -:root[data-da-variant="v12"] .graphic-sprints-title { +:root[data-da-variant="v12"][data-theme="default"] .graphic-sprints-title { margin: 0.26rem 0 0; color: #ecffe9; font-size: clamp(1.16rem, 1.8vw, 1.74rem); line-height: 1.2; } -:root[data-da-variant="v12"] .graphic-sprints-copy { +:root[data-da-variant="v12"][data-theme="default"] .graphic-sprints-copy { margin: 0.42rem 0 0; color: #beeed8; font-size: 0.78rem; line-height: 1.52; } -:root[data-da-variant="v12"] .graphic-sprints-grid { +:root[data-da-variant="v12"][data-theme="default"] .graphic-sprints-grid { margin-top: 0.72rem; display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 0.54rem; } -:root[data-da-variant="v12"] .graphic-sprint-card { +:root[data-da-variant="v12"][data-theme="default"] .graphic-sprint-card { border: 2px solid rgba(89, 250, 181, 0.4); border-radius: 0.56rem; background: @@ -5377,7 +2690,7 @@ footer:before { transform-style: preserve-3d; } -:root[data-da-variant="v12"] .graphic-sprint-card::before { +:root[data-da-variant="v12"][data-theme="default"] .graphic-sprint-card::before { content: ""; position: absolute; inset: 6px; @@ -5386,29 +2699,29 @@ footer:before { pointer-events: none; } -:root[data-da-variant="v12"] .graphic-sprint-card:hover, -:root[data-da-variant="v12"] .graphic-sprint-card:focus-within { +:root[data-da-variant="v12"][data-theme="default"] .graphic-sprint-card:hover, +:root[data-da-variant="v12"][data-theme="default"] .graphic-sprint-card:focus-within { border-color: rgba(121, 255, 202, 0.78); box-shadow: inset 0 0 0 1px rgba(113, 255, 199, 0.18), 0 0 22px rgba(83, 255, 187, 0.15); } -:root[data-da-variant="v12"] .graphic-sprint-card-head { +:root[data-da-variant="v12"][data-theme="default"] .graphic-sprint-card-head { display: flex; justify-content: space-between; gap: 0.4rem; align-items: baseline; } -:root[data-da-variant="v12"] .graphic-sprint-status, -:root[data-da-variant="v12"] .graphic-sprint-window { +:root[data-da-variant="v12"][data-theme="default"] .graphic-sprint-status, +:root[data-da-variant="v12"][data-theme="default"] .graphic-sprint-window { margin: 0; font-family: "IBM Plex Mono", ui-monospace, Menlo, Consolas, monospace; font-size: 0.61rem; } -:root[data-da-variant="v12"] .graphic-sprint-status { +:root[data-da-variant="v12"][data-theme="default"] .graphic-sprint-status { border-radius: 999px; border: 1px solid transparent; padding: 0.08rem 0.36rem; @@ -5416,43 +2729,43 @@ footer:before { text-transform: uppercase; } -:root[data-da-variant="v12"] .graphic-sprint-status--en-cours { +:root[data-da-variant="v12"][data-theme="default"] .graphic-sprint-status--en-cours { color: #dbffe6; background: rgba(60, 255, 171, 0.18); border-color: rgba(82, 255, 182, 0.48); } -:root[data-da-variant="v12"] .graphic-sprint-status--planifie { +:root[data-da-variant="v12"][data-theme="default"] .graphic-sprint-status--planifie { color: #fcead2; background: rgba(241, 184, 116, 0.16); border-color: rgba(241, 184, 116, 0.42); } -:root[data-da-variant="v12"] .graphic-sprint-status--valide { +:root[data-da-variant="v12"][data-theme="default"] .graphic-sprint-status--valide { color: #e3ebff; background: rgba(120, 162, 255, 0.18); border-color: rgba(138, 177, 255, 0.42); } -:root[data-da-variant="v12"] .graphic-sprint-window { +:root[data-da-variant="v12"][data-theme="default"] .graphic-sprint-window { color: #9dd7bc; } -:root[data-da-variant="v12"] .graphic-sprint-title { +:root[data-da-variant="v12"][data-theme="default"] .graphic-sprint-title { margin: 0.36rem 0 0; color: #f0fff7; font-size: 1rem; line-height: 1.25; } -:root[data-da-variant="v12"] .graphic-sprint-objective { +:root[data-da-variant="v12"][data-theme="default"] .graphic-sprint-objective { margin: 0.34rem 0 0; color: #b8ebd4; font-size: 0.72rem; line-height: 1.52; } -:root[data-da-variant="v12"] .graphic-sprint-progress { +:root[data-da-variant="v12"][data-theme="default"] .graphic-sprint-progress { margin-top: 0.48rem; height: 0.42rem; border: 1px solid rgba(121, 255, 202, 0.4); @@ -5461,7 +2774,7 @@ footer:before { overflow: hidden; } -:root[data-da-variant="v12"] .graphic-sprint-progress-fill { +:root[data-da-variant="v12"][data-theme="default"] .graphic-sprint-progress-fill { display: block; height: 100%; width: 0; @@ -5470,7 +2783,7 @@ footer:before { transition: width 0.5s ease; } -:root[data-da-variant="v12"] .graphic-sprint-card.is-live .graphic-sprint-progress-fill { +:root[data-da-variant="v12"][data-theme="default"] .graphic-sprint-card.is-live .graphic-sprint-progress-fill { width: var(--sprint-progress-target, 0%); } @@ -5478,14 +2791,14 @@ footer:before { will-change: transform; } -:root[data-da-variant="v12"] .graphic-sprint-progress-label { +:root[data-da-variant="v12"][data-theme="default"] .graphic-sprint-progress-label { margin: 0.24rem 0 0; color: #9dd8be; font-family: "IBM Plex Mono", ui-monospace, Menlo, Consolas, monospace; font-size: 0.61rem; } -:root[data-da-variant="v12"] .graphic-sprint-deliverables { +:root[data-da-variant="v12"][data-theme="default"] .graphic-sprint-deliverables { margin: 0.42rem 0 0; padding: 0; list-style: none; @@ -5493,7 +2806,7 @@ footer:before { gap: 0.26rem; } -:root[data-da-variant="v12"] .graphic-sprint-deliverables li { +:root[data-da-variant="v12"][data-theme="default"] .graphic-sprint-deliverables li { border: 1px solid rgba(96, 236, 173, 0.24); border-radius: 0.36rem; padding: 0.22rem 0.34rem; @@ -5503,7 +2816,7 @@ footer:before { background: rgba(10, 29, 21, 0.72); } -:root[data-da-variant="v12"] .graphic-sprints-foot { +:root[data-da-variant="v12"][data-theme="default"] .graphic-sprints-foot { margin-top: 0.66rem; padding-top: 0.54rem; border-top: 1px solid rgba(111, 242, 183, 0.24); @@ -5514,13 +2827,13 @@ footer:before { justify-content: space-between; } -:root[data-da-variant="v12"] .graphic-sprints-foot-copy { +:root[data-da-variant="v12"][data-theme="default"] .graphic-sprints-foot-copy { margin: 0; color: #c5f3dd; font-size: 0.72rem; } -:root[data-da-variant="v12"] .graphic-sprints-cta { +:root[data-da-variant="v12"][data-theme="default"] .graphic-sprints-cta { display: inline-flex; align-items: center; min-height: 1.95rem; @@ -5534,46 +2847,51 @@ footer:before { transition: transform 0.15s ease, background-color 0.15s ease, box-shadow 0.15s ease; } -:root[data-da-variant="v12"] .graphic-sprints-cta:hover, -:root[data-da-variant="v12"] .graphic-sprints-cta:focus-visible { +:root[data-da-variant="v12"][data-theme="default"] .graphic-sprints-cta:hover, +:root[data-da-variant="v12"][data-theme="default"] .graphic-sprints-cta:focus-visible { transform: translateY(-1px); background: rgba(79, 255, 175, 0.12); box-shadow: 0 0 16px rgba(79, 255, 175, 0.17); } @media (max-width: 1024px) { - :root[data-da-variant="v12"] .graphic-sprints-grid { + + :root[data-da-variant="v12"][data-theme="default"] .graphic-sprints-grid { grid-template-columns: 1fr 1fr; } + } @media (max-width: 767px) { - :root[data-da-variant="v12"] .graphic-sprints-panel { + + :root[data-da-variant="v12"][data-theme="default"] .graphic-sprints-panel { padding: 0.64rem; } - :root[data-da-variant="v12"] .graphic-sprints-grid { + :root[data-da-variant="v12"][data-theme="default"] .graphic-sprints-grid { grid-template-columns: 1fr; } - :root[data-da-variant="v12"] .graphic-sprint-card { + :root[data-da-variant="v12"][data-theme="default"] .graphic-sprint-card { padding: 0.48rem; } - :root[data-da-variant="v12"] .graphic-sprints-foot { + :root[data-da-variant="v12"][data-theme="default"] .graphic-sprints-foot { align-items: stretch; } - :root[data-da-variant="v12"] .graphic-sprints-cta { + :root[data-da-variant="v12"][data-theme="default"] .graphic-sprints-cta { justify-content: center; width: 100%; } + } @media (prefers-reduced-motion: reduce) { - :root[data-da-variant="v12"] .graphic-sprint-card, - :root[data-da-variant="v12"] .graphic-sprints-cta, - :root[data-da-variant="v12"] .graphic-sprint-progress-fill { + + :root[data-da-variant="v12"][data-theme="default"] .graphic-sprint-card, + :root[data-da-variant="v12"][data-theme="default"] .graphic-sprints-cta, + :root[data-da-variant="v12"][data-theme="default"] .graphic-sprint-progress-fill { transition: none; } @@ -5581,20 +2899,21 @@ footer:before { transform: none !important; } - :root[data-da-variant="v12"] .hero-title-word, - :root[data-da-variant="v12"] .hero-copy-reveal { + :root[data-da-variant="v12"][data-theme="default"] .hero-title-word, + :root[data-da-variant="v12"][data-theme="default"] .hero-copy-reveal { opacity: 1; transform: none; animation: none; } - :root[data-da-variant="v12"] .hero-console-line::after { + :root[data-da-variant="v12"][data-theme="default"] .hero-console-line::after { animation: none; display: none; } + } -:root[data-da-variant="v12"][data-ui-sprint="b"] .graphic-sprints-panel { +:root[data-da-variant="v12"][data-theme="default"][data-ui-sprint="b"] .graphic-sprints-panel { border-color: rgba(108, 255, 198, 0.72); background: radial-gradient(760px 320px at -4% -12%, rgba(77, 255, 186, 0.2), transparent 60%), @@ -5605,42 +2924,42 @@ footer:before { 0 0 40px rgba(72, 255, 178, 0.2); } -:root[data-da-variant="v12"][data-ui-sprint="b"] .graphic-sprints-title { +:root[data-da-variant="v12"][data-theme="default"][data-ui-sprint="b"] .graphic-sprints-title { color: #f3fff8; text-shadow: 0 0 22px rgba(63, 255, 176, 0.2); } -:root[data-da-variant="v12"][data-ui-sprint="b"] .graphic-sprint-card { +:root[data-da-variant="v12"][data-theme="default"][data-ui-sprint="b"] .graphic-sprint-card { border-color: rgba(97, 253, 190, 0.58); background: linear-gradient(180deg, rgba(8, 35, 24, 0.94), rgba(6, 23, 17, 0.94)), repeating-linear-gradient(90deg, rgba(119, 255, 200, 0.12) 0 1px, transparent 1px 18px); } -:root[data-da-variant="v12"][data-ui-sprint="b"] .graphic-sprint-card:hover, -:root[data-da-variant="v12"][data-ui-sprint="b"] .graphic-sprint-card:focus-within { +:root[data-da-variant="v12"][data-theme="default"][data-ui-sprint="b"] .graphic-sprint-card:hover, +:root[data-da-variant="v12"][data-theme="default"][data-ui-sprint="b"] .graphic-sprint-card:focus-within { border-color: rgba(129, 255, 206, 0.92); box-shadow: inset 0 0 0 1px rgba(119, 255, 200, 0.26), 0 0 28px rgba(82, 255, 188, 0.25); } -:root[data-da-variant="v12"][data-ui-sprint="b"] .graphic-sprint-progress { +:root[data-da-variant="v12"][data-theme="default"][data-ui-sprint="b"] .graphic-sprint-progress { border-color: rgba(137, 255, 209, 0.62); background: rgba(7, 17, 13, 0.76); } -:root[data-da-variant="v12"][data-ui-sprint="b"] .graphic-sprint-progress-fill { +:root[data-da-variant="v12"][data-theme="default"][data-ui-sprint="b"] .graphic-sprint-progress-fill { background: linear-gradient(90deg, #4dffbf 0%, #89ffcb 38%, #ffbf76 100%); box-shadow: 0 0 12px rgba(89, 255, 193, 0.36); } -:root[data-da-variant="v12"][data-ui-sprint="b"] .graphic-sprint-deliverables li { +:root[data-da-variant="v12"][data-theme="default"][data-ui-sprint="b"] .graphic-sprint-deliverables li { border-color: rgba(122, 255, 205, 0.35); background: rgba(8, 29, 20, 0.86); } -:root[data-da-variant="v12"][data-ui-sprint="b"] .graphic-sprints-cta { +:root[data-da-variant="v12"][data-theme="default"][data-ui-sprint="b"] .graphic-sprints-cta { border-color: rgba(103, 255, 193, 0.92); background: linear-gradient(120deg, rgba(66, 255, 176, 0.22), rgba(255, 191, 117, 0.2)); color: #f4fff9; @@ -5649,34 +2968,34 @@ footer:before { 0 0 18px rgba(84, 255, 188, 0.26); } -:root[data-da-variant="v12"][data-ui-sprint="b"] .graphic-sprints-cta:hover, -:root[data-da-variant="v12"][data-ui-sprint="b"] .graphic-sprints-cta:focus-visible { +:root[data-da-variant="v12"][data-theme="default"][data-ui-sprint="b"] .graphic-sprints-cta:hover, +:root[data-da-variant="v12"][data-theme="default"][data-ui-sprint="b"] .graphic-sprints-cta:focus-visible { transform: translateY(-2px); box-shadow: inset 0 0 0 1px rgba(147, 255, 214, 0.4), 0 0 24px rgba(84, 255, 188, 0.34); } -:root[data-da-variant="v12"][data-ui-sprint="b"] .hero-title-word { +:root[data-da-variant="v12"][data-theme="default"][data-ui-sprint="b"] .hero-title-word { opacity: 0; transform: translateY(8px); animation: 0.46s cubic-bezier(0.2, 0.8, 0.2, 1) forwards heroWordRise; animation-delay: calc(var(--word-index, 0) * 0.09s + 0.08s); } -:root[data-da-variant="v12"][data-ui-sprint="b"] .hero-copy-reveal { +:root[data-da-variant="v12"][data-theme="default"][data-ui-sprint="b"] .hero-copy-reveal { opacity: 0; animation: 0.44s ease forwards heroFadeIn; animation-delay: 0.34s; } -:root[data-da-variant="v12"][data-ui-sprint="b"] .hero-console-line { +:root[data-da-variant="v12"][data-theme="default"][data-ui-sprint="b"] .hero-console-line { position: relative; overflow: hidden; isolation: isolate; } -:root[data-da-variant="v12"][data-ui-sprint="b"] .hero-console-line::after { +:root[data-da-variant="v12"][data-theme="default"][data-ui-sprint="b"] .hero-console-line::after { content: ""; position: absolute; inset: 0; @@ -5705,3 +3024,2170 @@ footer:before { transform: translateX(125%); } } + +/* LIGHT MODE variables */ +:root[data-da-variant="v12"][data-theme="light"] { + --bg: #f5ede2; + --pcb-deep: #efe3d1; + --pcb-core: #f8f1e7; + --text: #241912; + --text-muted: #655448; + --line: rgba(103, 83, 64, 0.1); + --line-rail: rgba(131, 111, 91, 0.16); + --line-edge: rgba(113, 88, 63, 0.18); + --signal: #b7562c; + --electric: #2f6876; + --trace-cyan: #2f6876; + --trace-magenta: #a14335; +} + +/* HIGH-CONTRAST MODE variables */ +:root[data-da-variant="v12"][data-theme="high-contrast"] { + --bg: #ffffff; + --pcb-deep: #ffffff; + --pcb-core: #ffffff; + --text: #0a0806; + --text-muted: #2a2118; + --line: rgba(50, 40, 30, 0.3); + --line-rail: rgba(50, 40, 30, 0.3); + --line-edge: rgba(50, 40, 30, 0.35); + --signal: #8c3210; + --electric: #1a4f5a; + --trace-cyan: #1a4f5a; + --trace-magenta: #7a2d20; +} + +:root[data-da-variant="v12"][data-theme="light"] body, +:root[data-da-variant="v12"][data-theme="high-contrast"] body { + background: + radial-gradient(860px 540px at -6% -10%, rgba(183, 86, 44, 0.14), transparent 58%), + radial-gradient(760px 460px at 108% 0%, rgba(47, 104, 118, 0.14), transparent 60%), + linear-gradient(180deg, #f6efe4 0%, #f3ebdf 36%, #ede2d1 100%); + background-attachment: fixed; +} + +:root[data-da-variant="v12"][data-theme="light"] body::before, +:root[data-da-variant="v12"][data-theme="high-contrast"] body::before { + background-image: + linear-gradient(rgba(255, 255, 255, 0.3), rgba(255, 255, 255, 0.3)), + repeating-linear-gradient( + 0deg, + rgba(111, 86, 66, 0.08) 0 1px, + transparent 1px 7px + ); + opacity: 0.34; + mix-blend-mode: multiply; +} + +:root[data-da-variant="v12"][data-theme="light"] body::after, +:root[data-da-variant="v12"][data-theme="high-contrast"] body::after { + background-image: + linear-gradient(to right, rgba(111, 86, 66, 0.07) 1px, transparent 1px), + linear-gradient(to bottom, rgba(111, 86, 66, 0.07) 1px, transparent 1px); + background-size: 38px 38px; + opacity: 0.14; + -webkit-mask-image: none; + mask-image: none; +} + +/* High-contrast specific overrides */ +:root[data-da-variant="v12"][data-theme="high-contrast"] body { + background: linear-gradient(180deg, #ffffff 0%, #faf7f2 36%, #f5efe4 100%); + background-attachment: fixed; +} + +:root[data-da-variant="v12"][data-theme="high-contrast"] .site-nav { + background: rgba(255, 255, 255, 0.96); + border-bottom: 2px solid rgba(50, 40, 30, 0.3); + box-shadow: 0 4px 12px rgba(0, 0, 0, 0.12); +} + +:root[data-da-variant="v12"][data-theme="high-contrast"] .figma-lab-left, +:root[data-da-variant="v12"][data-theme="high-contrast"] .figma-lab-right, +:root[data-da-variant="v12"][data-theme="high-contrast"] .circuit-board, +:root[data-da-variant="v12"][data-theme="high-contrast"] .graphic-sprints-panel { + border: 2px solid rgba(50, 40, 30, 0.3); + background: #ffffff; +} + +:root[data-da-variant="v12"][data-theme="high-contrast"] .graphic-sprint-card, +:root[data-da-variant="v12"][data-theme="high-contrast"] .case-card { + border: 2px solid rgba(50, 40, 30, 0.25); + background: #ffffff; +} + +:root[data-da-variant="v12"][data-theme="high-contrast"] .figma-lab-title { + color: #000000; +} + +:root[data-da-variant="v12"][data-theme="high-contrast"] .section-lead, +:root[data-da-variant="v12"][data-theme="high-contrast"] .figma-lab-copy { + color: #1a1208; +} + +:root[data-da-variant="v12"][data-theme="high-contrast"] .studio-muted { + color: #3a2e22; +} + +:root[data-da-variant="v12"][data-theme="high-contrast"] .figma-lab-pill--primary { + background: #8c3210; + color: #ffffff; + border: 2px solid #8c3210; +} + +:root[data-da-variant="v12"][data-theme="high-contrast"] .studio-link { + color: #6b2a12; + text-decoration: underline; +} + +/* HIGH-CONTRAST: nav top accent bar */ +:root[data-da-variant="v12"][data-theme="high-contrast"] .site-nav::before { + background: linear-gradient(90deg, #8c3210 0%, #064a50 52%, #8c3210 100%); + opacity: 1; +} + +/* HIGH-CONTRAST: nav links */ +:root[data-da-variant="v12"][data-theme="high-contrast"] .figma-lab-nav-link, +:root[data-da-variant="v12"][data-theme="high-contrast"] .site-navlink { + background: #ffffff; + border-color: #555; + color: #1a1a1a; +} + +:root[data-da-variant="v12"][data-theme="high-contrast"] .figma-lab-nav-link:hover, +:root[data-da-variant="v12"][data-theme="high-contrast"] .figma-lab-nav-link:focus-visible, +:root[data-da-variant="v12"][data-theme="high-contrast"] .site-navlink:hover, +:root[data-da-variant="v12"][data-theme="high-contrast"] .site-navlink:focus-visible, +:root[data-da-variant="v12"][data-theme="high-contrast"] .figma-lab-nav-link.is-active, +:root[data-da-variant="v12"][data-theme="high-contrast"] .site-navlink.is-active, +:root[data-da-variant="v12"][data-theme="high-contrast"] .figma-lab-nav-link[aria-current="location"], +:root[data-da-variant="v12"][data-theme="high-contrast"] .site-navlink[aria-current="location"] { + background: #f0e8dd; + border-color: #1a1a1a; + color: #000000; + box-shadow: 0 0 0 2px #1a1a1a; + text-shadow: none; +} + +/* HIGH-CONTRAST: nav title and kicker */ +:root[data-da-variant="v12"][data-theme="high-contrast"] .figma-lab-nav-title { + color: #000000; +} + +:root[data-da-variant="v12"][data-theme="high-contrast"] .figma-lab-nav-kicker { + color: #3a2e22; +} + +/* HIGH-CONTRAST: contrast toggle */ +:root[data-da-variant="v12"][data-theme="high-contrast"] .site-contrast-toggle { + background: #ffffff; + border-color: #333; + color: #1a1a1a; + box-shadow: none; +} + +:root[data-da-variant="v12"][data-theme="high-contrast"] .site-contrast-toggle:hover, +:root[data-da-variant="v12"][data-theme="high-contrast"] .site-contrast-toggle:focus-visible { + background: #f0e8dd; + border-color: #1a1a1a; + box-shadow: 0 0 0 2px #1a1a1a; +} + +:root[data-da-variant="v12"][data-theme="high-contrast"] .site-contrast-toggle::before { + background: none; +} + +/* HIGH-CONTRAST: pills / CTAs */ +:root[data-da-variant="v12"][data-theme="high-contrast"] .figma-lab-pill--secondary, +:root[data-da-variant="v12"][data-theme="high-contrast"] .graphic-sprints-cta { + background: #ffffff; + border: 2px solid #333; + color: #1a1a1a; +} + +:root[data-da-variant="v12"][data-theme="high-contrast"] .figma-lab-pill--ghost, +:root[data-da-variant="v12"][data-theme="high-contrast"] .hero-inline-link { + background: #8c3210; + border: 2px solid #8c3210; + color: #ffffff; +} + +:root[data-da-variant="v12"][data-theme="high-contrast"] .figma-lab-pill:hover, +:root[data-da-variant="v12"][data-theme="high-contrast"] .figma-lab-pill:focus-visible, +:root[data-da-variant="v12"][data-theme="high-contrast"] .graphic-sprints-cta:hover, +:root[data-da-variant="v12"][data-theme="high-contrast"] .graphic-sprints-cta:focus-visible, +:root[data-da-variant="v12"][data-theme="high-contrast"] .hero-inline-link:hover, +:root[data-da-variant="v12"][data-theme="high-contrast"] .hero-inline-link:focus-visible { + filter: none; + box-shadow: 0 0 0 2px #1a1a1a; +} + +/* HIGH-CONTRAST: hero outcomes / figma-lab notes */ +:root[data-da-variant="v12"][data-theme="high-contrast"] .hero-outcomes, +:root[data-da-variant="v12"][data-theme="high-contrast"] .figma-lab-notes { + background: #ffffff; + border: 2px solid #9a5f2f; +} + +:root[data-da-variant="v12"][data-theme="high-contrast"] .figma-lab-notes-title, +:root[data-da-variant="v12"][data-theme="high-contrast"] .hero-outcomes-title { + color: #6b2a12; +} + +:root[data-da-variant="v12"][data-theme="high-contrast"] .hero-outcomes-list, +:root[data-da-variant="v12"][data-theme="high-contrast"] .figma-lab-notes-list { + color: #1a1a1a; +} + +/* HIGH-CONTRAST: hero slogan */ +:root[data-da-variant="v12"][data-theme="high-contrast"] .hero-slogan { + color: #000000; + text-shadow: none; +} + +:root[data-da-variant="v12"][data-theme="high-contrast"] .hero-slogan-char { + text-shadow: none; +} + +:root[data-da-variant="v12"][data-theme="high-contrast"] .hero-slogan::after { + display: none; +} + +/* HIGH-CONTRAST: section headings and text */ +:root[data-da-variant="v12"][data-theme="high-contrast"] .section-anchor h2, +:root[data-da-variant="v12"][data-theme="high-contrast"] .section-anchor h3 { + color: #000000; +} + +:root[data-da-variant="v12"][data-theme="high-contrast"] .graphic-sprints-copy { + color: #1a1208; +} + +/* HIGH-CONTRAST: circuit board components */ +:root[data-da-variant="v12"][data-theme="high-contrast"] .circuit-node { + box-shadow: 0 0 0 2px #333; +} + +/* HIGH-CONTRAST: graphic sprint progress */ +:root[data-da-variant="v12"][data-theme="high-contrast"] .graphic-sprint-progress { + border-color: #333; +} + +:root[data-da-variant="v12"][data-theme="high-contrast"] .graphic-sprint-progress-fill { + background: linear-gradient(90deg, #8c3210 0%, #064a50 52%, #9a5f2f 100%); +} + +/* HIGH-CONTRAST: about panel, flow panel, routing panel backgrounds */ +:root[data-da-variant="v12"][data-theme="high-contrast"] .about-panel::before, +:root[data-da-variant="v12"][data-theme="high-contrast"] .graphic-sprints-panel--routing::before, +:root[data-da-variant="v12"][data-theme="high-contrast"] .flow-panel::before { + opacity: 0.06; +} + +/* HIGH-CONTRAST: trust strip and trust pill */ + +/* HIGH-CONTRAST: studio chip */ +:root[data-da-variant="v12"][data-theme="high-contrast"] .studio-chip { + background: #ffffff; + border: 2px solid rgba(50, 40, 30, 0.3); + color: #1a1a1a; +} + +/* HIGH-CONTRAST: contact section */ + +:root[data-da-variant="v12"][data-theme="high-contrast"] .contact-signal-copy { + color: #1a1a1a; +} + +/* HIGH-CONTRAST: project case card */ +:root[data-da-variant="v12"][data-theme="high-contrast"] .project-case-card { + background: #ffffff; + border: 2px solid rgba(50, 40, 30, 0.3); + box-shadow: none; +} + +:root[data-da-variant="v12"][data-theme="high-contrast"] .project-case-card .project-story-block + .project-story-block { + border-top-color: #ccc; +} + +:root[data-da-variant="v12"][data-theme="high-contrast"] .project-case-card .project-story-label, +:root[data-da-variant="v12"][data-theme="high-contrast"] .project-case-card .project-stage { + color: #064a50; +} + +:root[data-da-variant="v12"][data-theme="high-contrast"] .project-case-card h3, +:root[data-da-variant="v12"][data-theme="high-contrast"] .project-case-card .project-story-copy { + color: #1a1a1a; +} + +/* HIGH-CONTRAST: flow narrative cards */ +:root[data-da-variant="v12"][data-theme="high-contrast"] .flow-narrative-card { + background: #ffffff; + border: 2px solid rgba(50, 40, 30, 0.3); + box-shadow: none; +} + +:root[data-da-variant="v12"][data-theme="high-contrast"] .flow-narrative-card::before { + opacity: 0.04; +} + +:root[data-da-variant="v12"][data-theme="high-contrast"] .flow-narrative-kicker { + color: #064a50; +} + +:root[data-da-variant="v12"][data-theme="high-contrast"] .flow-narrative-title { + color: #000000; +} + +:root[data-da-variant="v12"][data-theme="high-contrast"] .flow-narrative-copy { + color: #1a1a1a; +} + +/* HIGH-CONTRAST: figma lab bottom map / routing */ +:root[data-da-variant="v12"][data-theme="high-contrast"] .figma-lab-bottom-map--routing { + background: #ffffff; + border: 2px solid rgba(50, 40, 30, 0.3); + box-shadow: none; +} + +:root[data-da-variant="v12"][data-theme="high-contrast"] .figma-lab-bottom-map--routing::before { + opacity: 0.06; +} + +:root[data-da-variant="v12"][data-theme="high-contrast"] .figma-lab-map-intro { + background: rgba(255, 255, 255, 0.9); + border-color: rgba(50, 40, 30, 0.25); + backdrop-filter: none; +} + +:root[data-da-variant="v12"][data-theme="high-contrast"] .figma-lab-map-card { + backdrop-filter: none; +} + +:root[data-da-variant="v12"][data-theme="high-contrast"] .figma-lab-map-card::before { + background: none; +} + +:root[data-da-variant="v12"][data-theme="high-contrast"] .figma-lab-map-card:hover, +:root[data-da-variant="v12"][data-theme="high-contrast"] .figma-lab-map-card:focus-visible { + border-color: #1a1a1a; + box-shadow: 0 0 0 2px #1a1a1a; +} + +:root[data-da-variant="v12"][data-theme="high-contrast"] .figma-lab-map-kicker { + color: #064a50; +} + +:root[data-da-variant="v12"][data-theme="high-contrast"] .figma-lab-map-copy { + color: #1a1a1a; +} + +:root[data-da-variant="v12"][data-theme="high-contrast"] .figma-lab-map-context { + background: rgba(255, 255, 255, 0.9); + border-color: #333; + color: #1a1a1a; +} + +:root[data-da-variant="v12"][data-theme="high-contrast"] .figma-lab-map-title { + color: #000000; +} + +:root[data-da-variant="v12"][data-theme="high-contrast"] .figma-lab-map-detail { + color: #1a1a1a; +} + +/* HIGH-CONTRAST: flow node card, projects timeline, lab note, hero proof */ +:root[data-da-variant="v12"][data-theme="high-contrast"] .hero-proof-card { + background: #ffffff; + border: 2px solid rgba(50, 40, 30, 0.25); + box-shadow: none; +} + +/* HIGH-CONTRAST: footer */ +:root[data-da-variant="v12"][data-theme="high-contrast"] .site-footer { + background: #ffffff; + border-top: 2px solid #333; +} + +:root[data-da-variant="v12"][data-theme="high-contrast"] .footer-copy, +:root[data-da-variant="v12"][data-theme="high-contrast"] .footer-link { + color: #1a1a1a; +} + +:root[data-da-variant="v12"][data-theme="high-contrast"] .footer-title, +:root[data-da-variant="v12"][data-theme="high-contrast"] .footer-column-title { + color: #000000; +} + +:root[data-da-variant="v12"][data-theme="high-contrast"] .footer-col, +:root[data-da-variant="v12"][data-theme="high-contrast"] .footer-links { + background: #ffffff; + border-color: #333; +} + +:root[data-da-variant="v12"][data-theme="high-contrast"] .footer-link { + background: #ffffff; + border-color: #555; +} + +:root[data-da-variant="v12"][data-theme="high-contrast"] .footer-link:hover, +:root[data-da-variant="v12"][data-theme="high-contrast"] .footer-link:focus-visible { + border-color: #1a1a1a; + box-shadow: 0 0 0 2px #1a1a1a; +} + +:root[data-da-variant="v12"][data-theme="high-contrast"] .footer-endnote { + border-top-color: #333; +} + +/* HIGH-CONTRAST: global focus indicators */ +:root[data-da-variant="v12"][data-theme="high-contrast"] :focus-visible { + outline: 2px solid #1a1a1a; + outline-offset: 2px; +} + +:root[data-da-variant="v12"][data-theme="high-contrast"] a:focus-visible, +:root[data-da-variant="v12"][data-theme="high-contrast"] button:focus-visible { + outline: 2px solid #1a1a1a; + outline-offset: 2px; +} + +/* HIGH-CONTRAST: hero eyebrow and status */ +:root[data-da-variant="v12"][data-theme="high-contrast"] .hero-eyebrow { + color: #1a1a1a; +} + +:root[data-da-variant="v12"][data-theme="high-contrast"] .hero-side-panel { + background: #ffffff; + border: 2px solid rgba(50, 40, 30, 0.3); +} + +/* HIGH-CONTRAST: lab note flow */ + +:root[data-da-variant="v12"] .site-nav { + background: rgba(248, 241, 231, 0.82); + border-bottom-color: rgba(117, 92, 70, 0.14); + box-shadow: 0 12px 34px rgba(97, 74, 56, 0.08); +} + +:root[data-da-variant="v12"] .site-nav::before { + height: 2px; + background: linear-gradient(90deg, #b7562c 0%, #2f6876 52%, #b7562c 100%); + animation: none; + opacity: 0.9; +} + +:root[data-da-variant="v12"] .site-nav::after { + display: none; +} + +:root[data-da-variant="v12"] .site-contrast-toggle { + min-height: 2.5rem; + border-color: rgba(120, 94, 73, 0.18); + background: rgba(255, 250, 243, 0.86); + color: #4d3a30; + box-shadow: 0 8px 20px rgba(99, 74, 54, 0.08); +} + +:root[data-da-variant="v12"] .site-contrast-toggle:hover, +:root[data-da-variant="v12"] .site-contrast-toggle:focus-visible { + background: rgba(255, 253, 249, 0.98); + border-color: rgba(120, 94, 73, 0.28); + box-shadow: 0 12px 24px rgba(99, 74, 54, 0.12); +} + +:root[data-da-variant="v12"] .site-contrast-toggle::before { + background: linear-gradient(90deg, rgba(183, 86, 44, 0.18), rgba(47, 104, 118, 0.18)); +} + +:root[data-da-variant="v12"] .figma-lab-nav-row { + min-height: 4.25rem; + gap: 1.2rem; + padding: 0.7rem 0; +} + +:root[data-da-variant="v12"] .figma-lab-nav-title { + display: inline-flex; + flex-direction: column; + gap: 0.16rem; + color: #241912; + font-family: "Fraunces", "Times New Roman", serif; + font-size: 1.08rem; + font-weight: 700; + letter-spacing: 0.01em; + text-transform: none; +} + +:root[data-da-variant="v12"] .figma-lab-nav-kicker { + color: #7c6556; + font-family: "IBM Plex Mono", ui-monospace, Menlo, Consolas, monospace; + font-size: 0.64rem; + font-weight: 500; + letter-spacing: 0.08em; + text-transform: uppercase; +} + +:root[data-da-variant="v12"] .figma-lab-nav-list { + gap: 0.72rem; +} + +:root[data-da-variant="v12"] .figma-lab-nav-link { + min-height: 2.5rem; + display: inline-flex; + align-items: center; + padding: 0.3rem 0.82rem; + border: 1px solid rgba(125, 99, 77, 0.14); + border-radius: 999px; + background: rgba(255, 250, 243, 0.68); + color: #4f3d32; + font-family: "IBM Plex Mono", ui-monospace, Menlo, Consolas, monospace; + font-size: 0.7rem; + letter-spacing: 0.06em; + text-transform: uppercase; + transition: + transform 0.16s ease, + background-color 0.16s ease, + border-color 0.16s ease, + box-shadow 0.16s ease; +} + +:root[data-da-variant="v12"] .figma-lab-nav-link:hover, +:root[data-da-variant="v12"] .figma-lab-nav-link:focus-visible, +:root[data-da-variant="v12"] .figma-lab-nav-link.is-active, +:root[data-da-variant="v12"] .figma-lab-nav-link[aria-current="location"] { + color: #241912; + border-color: rgba(183, 86, 44, 0.28); + background: rgba(255, 252, 248, 0.98); + box-shadow: 0 10px 20px rgba(98, 74, 54, 0.1); + text-shadow: none; +} + +:root[data-da-variant="v12"] .figma-lab-hero-grid { + grid-template-columns: minmax(0, 1.08fr) minmax(320px, 0.92fr); + gap: 1rem; +} + +:root[data-da-variant="v12"] .figma-lab-left, +:root[data-da-variant="v12"] .figma-lab-right, +:root[data-da-variant="v12"] .circuit-board, +:root[data-da-variant="v12"] .graphic-sprints-panel { + border-color: rgba(123, 97, 74, 0.16); + background: + linear-gradient(180deg, rgba(255, 252, 247, 0.96), rgba(244, 235, 224, 0.92)), + linear-gradient(135deg, rgba(183, 86, 44, 0.06), transparent 42%); + box-shadow: + 0 16px 42px rgba(95, 73, 55, 0.08), + inset 0 1px 0 rgba(255, 255, 255, 0.45); +} + +:root[data-da-variant="v12"] .circuit-board::before, +:root[data-da-variant="v12"] .circuit-board::after { + opacity: 0; +} + +:root[data-da-variant="v12"] .circuit-title-row { + align-items: flex-end; +} + +:root[data-da-variant="v12"] .circuit-board .circuit-title-row::after { + background: linear-gradient(90deg, rgba(183, 86, 44, 0.26), rgba(47, 104, 118, 0.18), transparent); +} + +:root[data-da-variant="v12"] .circuit-node { + background: #b7562c; + box-shadow: + 0 0 0 2px rgba(183, 86, 44, 0.12), + 0 8px 18px rgba(183, 86, 44, 0.16); +} + +:root[data-da-variant="v12"] .circuit-node--green { + background: #346c56; + box-shadow: + 0 0 0 2px rgba(52, 108, 86, 0.12), + 0 8px 18px rgba(52, 108, 86, 0.16); +} + +:root[data-da-variant="v12"] .circuit-node--magenta { + background: #2f6876; + box-shadow: + 0 0 0 2px rgba(47, 104, 118, 0.12), + 0 8px 18px rgba(47, 104, 118, 0.16); +} + +:root[data-da-variant="v12"] .circuit-pinline { + background: linear-gradient(90deg, rgba(183, 86, 44, 0.4), rgba(47, 104, 118, 0.2)); +} + +:root[data-da-variant="v12"] .section-lead { + color: #34271f; + font-size: clamp(1rem, 0.92rem + 0.3vw, 1.16rem); + line-height: 1.6; +} + +:root[data-da-variant="v12"] .studio-muted, +:root[data-da-variant="v12"] .footer-copy, +:root[data-da-variant="v12"] .project-story-copy, +:root[data-da-variant="v12"] .contact-signal-copy { + color: #66554a; +} + +:root[data-da-variant="v12"] .studio-link, +:root[data-da-variant="v12"] .footer-link { + color: #8c3f22; +} + +:root[data-da-variant="v12"] .studio-link:hover, +:root[data-da-variant="v12"] .studio-link:focus-visible, +:root[data-da-variant="v12"] .footer-link:hover, +:root[data-da-variant="v12"] .footer-link:focus-visible { + color: #2f6876; +} + +:root[data-da-variant="v12"] .figma-lab-left { + padding: clamp(1.05rem, 2.5vw, 1.6rem); +} + +:root[data-da-variant="v12"] .hero-eyebrow { + margin: 0 0 0.55rem; + color: #806455; + font-family: "IBM Plex Mono", ui-monospace, Menlo, Consolas, monospace; + font-size: 0.72rem; + font-weight: 500; + letter-spacing: 0.09em; + text-transform: uppercase; +} + +:root[data-da-variant="v12"] .figma-lab-title { + max-width: 9ch; + margin: 0; + color: #211711; + font-size: clamp(2.85rem, 8vw, 5.4rem); + line-height: 0.94; +} + +:root[data-da-variant="v12"] .hero-title-word { + display: block; +} + +:root[data-da-variant="v12"] .hero-title-word + .hero-title-word { + margin-left: 0; + margin-top: 0.08em; +} + +:root[data-da-variant="v12"] .figma-lab-copy { + max-width: 60ch; + margin: 0.92rem 0 0; + color: #3f3026; + font-family: "Manrope", "Segoe UI", "Helvetica Neue", sans-serif; + font-size: clamp(1rem, 0.93rem + 0.22vw, 1.08rem); + line-height: 1.65; + opacity: 1; +} + +:root[data-da-variant="v12"] .figma-lab-copy--mono { + color: #7c6556; + font-family: "IBM Plex Mono", ui-monospace, Menlo, Consolas, monospace; + font-size: 0.74rem; + line-height: 1.6; +} + +:root[data-da-variant="v12"] .hero-proof-grid { + display: grid; + grid-template-columns: repeat(3, minmax(0, 1fr)); + gap: 0.78rem; + margin-top: 1rem; +} + +:root[data-da-variant="v12"] .hero-proof-card { + padding: 0.86rem 0.9rem; + border: 1px solid rgba(124, 98, 75, 0.14); + border-radius: var(--card-radius); + background: rgba(255, 249, 242, 0.9); +} + +:root[data-da-variant="v12"] .hero-proof-label, +:root[data-da-variant="v12"] .project-story-label, +:root[data-da-variant="v12"] .project-stage, +:root[data-da-variant="v12"] .contact-brief-title, +:root[data-da-variant="v12"] .graphic-sprints-kicker, +:root[data-da-variant="v12"] .graphic-sprint-status, +:root[data-da-variant="v12"] .graphic-sprint-window, +:root[data-da-variant="v12"] .graphic-sprint-progress-label { + margin: 0; + color: #866755; + font-family: "IBM Plex Mono", ui-monospace, Menlo, Consolas, monospace; + font-size: 0.68rem; + letter-spacing: 0.08em; + text-transform: uppercase; +} + +:root[data-da-variant="v12"] .hero-proof-value, +:root[data-da-variant="v12"] .graphic-sprints-title, +:root[data-da-variant="v12"] .contact-title { + color: #231913; +} + +:root[data-da-variant="v12"] .hero-proof-value { + margin: 0.42rem 0 0; + font-family: "Fraunces", "Times New Roman", serif; + font-size: 1.42rem; + line-height: 1.06; +} + +:root[data-da-variant="v12"] .hero-proof-detail { + margin: 0.34rem 0 0; + color: #625146; + font-size: 0.9rem; + line-height: 1.5; +} + +:root[data-da-variant="v12"] .figma-lab-cta-row { + gap: 0.62rem; + margin-top: 1.02rem; +} + +:root[data-da-variant="v12"] .figma-lab-pill { + min-height: 2.85rem; + padding: 0.4rem 0.94rem; + border-width: 1px; + border-radius: 999px; + font-family: "IBM Plex Mono", ui-monospace, Menlo, Consolas, monospace; + font-size: 0.72rem; + font-weight: 600; + letter-spacing: 0.06em; + text-transform: uppercase; + box-shadow: 0 10px 20px rgba(93, 71, 54, 0.08); +} + +:root[data-da-variant="v12"] .figma-lab-pill--primary { + border-color: rgba(183, 86, 44, 0.25); + background: #b7562c; + color: #fff8f3; +} + +:root[data-da-variant="v12"] .figma-lab-pill--secondary { + border-color: rgba(47, 104, 118, 0.22); + background: rgba(237, 245, 247, 0.92); + color: #244754; +} + +:root[data-da-variant="v12"] .figma-lab-pill--ghost { + border-color: rgba(124, 98, 75, 0.14); + background: rgba(255, 250, 243, 0.88); + color: #4e3c31; +} + +:root[data-da-variant="v12"] .figma-lab-pill:hover, +:root[data-da-variant="v12"] .figma-lab-pill:focus-visible { + transform: translateY(-2px); + background-image: none; +} + +:root[data-da-variant="v12"] .figma-lab-cta-help { + margin-top: 0.46rem; + color: #7a6556; + font-size: 0.74rem; +} + +:root[data-da-variant="v12"] .hero-outcomes { + margin-top: 1rem; + padding: 1rem 1.05rem; + border-color: rgba(126, 98, 74, 0.16); + background: + linear-gradient(180deg, rgba(255, 248, 239, 0.98), rgba(244, 232, 220, 0.94)), + linear-gradient(135deg, rgba(47, 104, 118, 0.06), transparent 50%); +} + +:root[data-da-variant="v12"] .hero-outcomes-title { + font-size: 1.18rem; +} + +:root[data-da-variant="v12"] .hero-outcomes-list { + margin: 0.55rem 0 0; + padding-left: 1rem; + list-style: disc; + color: #413228; + font-family: "Manrope", "Segoe UI", "Helvetica Neue", sans-serif; + font-size: 0.95rem; + line-height: 1.6; +} + +:root[data-da-variant="v12"] .figma-lab-right { + gap: 1rem; + padding: 1rem; +} + +:root[data-da-variant="v12"] .figma-lab-bottom-map { + margin-top: 1.2rem; +} + +:root[data-da-variant="v12"] .figma-lab-map-intro { + display: grid; + gap: 0.24rem; + margin-bottom: 0.82rem; +} + +:root[data-da-variant="v12"] .figma-lab-map-kicker { + margin: 0; + color: #876a58; + font-family: "IBM Plex Mono", ui-monospace, Menlo, Consolas, monospace; + font-size: 0.68rem; + letter-spacing: 0.08em; + text-transform: uppercase; +} + +:root[data-da-variant="v12"] .figma-lab-map-copy { + max-width: 54ch; + margin: 0; + color: #55463d; + font-size: 0.96rem; + line-height: 1.58; +} + +:root[data-da-variant="v12"] .figma-lab-bottom-grid { + grid-template-columns: repeat(3, minmax(0, 1fr)); + gap: 0.8rem; +} + +:root[data-da-variant="v12"] .figma-lab-map-card { + min-height: 8.2rem; + align-items: flex-start; + justify-content: flex-start; + flex-direction: column; + gap: 0.45rem; + padding: 1rem; + border-width: 1px; + border-radius: 1.05rem; + box-shadow: 0 14px 30px rgba(95, 73, 55, 0.08); +} + +:root[data-da-variant="v12"] .figma-lab-map-card:hover, +:root[data-da-variant="v12"] .figma-lab-map-card:focus-visible, +:root[data-da-variant="v12"] .figma-lab-map-card.is-active, +:root[data-da-variant="v12"] .figma-lab-map-card[aria-current="location"] { + transform: translateY(-3px); + filter: none; + box-shadow: 0 18px 34px rgba(95, 73, 55, 0.12); +} + +:root[data-da-variant="v12"] .figma-lab-map-step { + color: #8f705c; + font-family: "IBM Plex Mono", ui-monospace, Menlo, Consolas, monospace; + font-size: 0.68rem; + letter-spacing: 0.1em; +} + +:root[data-da-variant="v12"] .figma-lab-map-title { + color: inherit; + font-family: "Fraunces", "Times New Roman", serif; + font-size: 1.18rem; + line-height: 1.08; +} + +:root[data-da-variant="v12"] .figma-lab-map-detail { + color: inherit; + font-size: 0.9rem; + line-height: 1.5; + opacity: 0.8; +} + +:root[data-da-variant="v12"] .figma-lab-map-card--cream { + background: rgba(255, 248, 239, 0.96); + border-color: rgba(166, 129, 98, 0.24); + color: #2b211a; +} + +:root[data-da-variant="v12"] .figma-lab-map-card--blue { + background: rgba(237, 245, 247, 0.96); + border-color: rgba(78, 120, 132, 0.22); + color: #213942; +} + +:root[data-da-variant="v12"] .figma-lab-map-card--green { + background: rgba(239, 246, 241, 0.96); + border-color: rgba(83, 116, 92, 0.2); + color: #1f3025; +} + +:root[data-da-variant="v12"] .graphic-sprints-panel { + padding: 1.15rem; + border-width: 1px; + background: + linear-gradient(180deg, rgba(255, 252, 247, 0.98), rgba(243, 234, 223, 0.94)), + linear-gradient(135deg, rgba(183, 86, 44, 0.06), transparent 48%); + box-shadow: 0 18px 38px rgba(95, 73, 55, 0.08); +} + +:root[data-da-variant="v12"] .graphic-sprints-title { + margin: 0.18rem 0 0; + font-size: clamp(1.8rem, 3vw, 2.5rem); + line-height: 1.04; +} + +:root[data-da-variant="v12"] .graphic-sprints-copy, +:root[data-da-variant="v12"] .graphic-sprints-foot-copy, +:root[data-da-variant="v12"] .graphic-sprint-objective { + color: #605045; +} + +:root[data-da-variant="v12"] .graphic-sprints-grid { + gap: 0.85rem; +} + +:root[data-da-variant="v12"] .graphic-sprint-card { + padding: 0.95rem; + border: 1px solid rgba(126, 99, 75, 0.14); + border-radius: var(--card-radius); + background: rgba(255, 249, 242, 0.92); + box-shadow: none; +} + +:root[data-da-variant="v12"] .graphic-sprint-card:hover, +:root[data-da-variant="v12"] .graphic-sprint-card:focus-within { + border-color: rgba(183, 86, 44, 0.2); + box-shadow: 0 14px 28px rgba(95, 73, 55, 0.08); +} + +:root[data-da-variant="v12"] .graphic-sprint-title { + margin: 0.5rem 0 0; + color: #221913; + font-family: "Fraunces", "Times New Roman", serif; + font-size: 1.28rem; +} + +:root[data-da-variant="v12"] .graphic-sprint-progress { + margin-top: 0.68rem; + border-color: rgba(126, 99, 75, 0.14); + background: rgba(239, 230, 219, 0.85); +} + +:root[data-da-variant="v12"] .graphic-sprint-progress-fill { + background: linear-gradient(90deg, #b7562c 0%, #df9a72 52%, #2f6876 100%); +} + +:root[data-da-variant="v12"] .graphic-sprint-deliverables li { + border-color: rgba(126, 99, 75, 0.12); + border-radius: 999px; + padding: 0.38rem 0.6rem; + color: #4b3b31; + background: rgba(255, 250, 244, 0.94); + font-size: 0.72rem; +} + +:root[data-da-variant="v12"] .graphic-sprints-foot { + margin-top: 0.92rem; + padding-top: 0.8rem; + border-top-color: rgba(126, 99, 75, 0.12); +} + +:root[data-da-variant="v12"] .graphic-sprints-cta { + min-height: 2.75rem; + justify-content: center; + border-width: 1px; + border-color: rgba(47, 104, 118, 0.18); + background: rgba(237, 245, 247, 0.92); + color: #234652; + font-size: 0.72rem; + letter-spacing: 0.06em; + text-transform: uppercase; + box-shadow: 0 10px 20px rgba(95, 73, 55, 0.08); +} + +:root[data-da-variant="v12"] .graphic-sprints-cta:hover, +:root[data-da-variant="v12"] .graphic-sprints-cta:focus-visible { + background: rgba(243, 249, 250, 0.98); + box-shadow: 0 14px 24px rgba(95, 73, 55, 0.12); +} + +:root[data-da-variant="v12"] .project-story { + display: grid; + gap: 0.8rem; + margin-top: 0.88rem; +} + +:root[data-da-variant="v12"] .project-story-block { + padding-top: 0.76rem; + border-top: 1px solid rgba(126, 99, 75, 0.12); +} + +:root[data-da-variant="v12"] .project-story-copy { + margin: 0.28rem 0 0; + line-height: 1.58; +} + +:root[data-da-variant="v12"] .contact-signal-grid { + display: grid; + grid-template-columns: repeat(3, minmax(0, 1fr)); + gap: 0.8rem; +} + +:root[data-da-variant="v12"] .contact-signal-copy { + margin: 0.3rem 0 0; + line-height: 1.58; +} + +/* --- FAQ accordion --- */ +.faq-list { + display: grid; + gap: 0; +} +.faq-item { + border-bottom: 1px solid var(--line); + overflow: hidden; +} +.faq-item:first-child { + border-top: 1px solid var(--line); +} +.faq-question { + display: flex; + align-items: center; + justify-content: space-between; + gap: 1rem; + padding: 1rem 0.25rem; + cursor: pointer; + font-weight: 600; + font-size: 1.05rem; + color: var(--text); + list-style: none; + user-select: none; + transition: color 0.2s ease; +} +.faq-question::-webkit-details-marker { + display: none; +} +.faq-question::marker { + content: ""; +} +.faq-question:hover, +.faq-question:focus-visible { + color: var(--electric); +} +.faq-chevron { + flex-shrink: 0; + width: 1.25rem; + height: 1.25rem; + position: relative; + transition: transform 0.25s ease; +} +.faq-chevron::before, +.faq-chevron::after { + content: ""; + position: absolute; + background: currentColor; + border-radius: 1px; +} +.faq-chevron::before { + width: 100%; + height: 2px; + top: 50%; + left: 0; + transform: translateY(-50%); +} +.faq-chevron::after { + width: 2px; + height: 100%; + left: 50%; + top: 0; + transform: translateX(-50%); + transition: transform 0.25s ease, opacity 0.25s ease; +} +details[open] > .faq-question .faq-chevron::after { + transform: translateX(-50%) scaleY(0); + opacity: 0; +} +.faq-answer { + padding: 0 0.25rem 1rem; + line-height: 1.65; +} +.faq-answer p { + margin: 0; +} + +/* --- Case studies --- */ +.cases-grid { + display: grid; + grid-template-columns: repeat(3, minmax(0, 1fr)); + gap: 1rem; +} + +.case-card { + padding: 1.2rem; + border: 1px solid var(--line); + border-radius: var(--card-radius); + background: var(--bg-panel, rgba(255, 249, 242, 0.9)); +} + +.case-tag { + display: inline-block; + margin: 0 0 0.5rem; + padding: 0.2rem 0.6rem; + border-radius: 999px; + font-size: 0.75rem; + font-weight: 600; + text-transform: uppercase; + letter-spacing: 0.04em; +} + +.case-tag--cyan { + background: rgba(91, 209, 216, 0.15); + color: #3ba8af; +} + +.case-tag--vio { + background: rgba(156, 120, 216, 0.15); + color: #7c5fb0; +} + +.case-tag--amber { + background: rgba(217, 160, 70, 0.15); + color: #b0820a; +} + +.case-title { + margin: 0 0 0.5rem; + font-size: 1.15rem; + line-height: 1.25; +} + +.case-context, +.case-intervention, +.case-result { + margin: 0 0 0.4rem; + font-size: 0.9rem; + line-height: 1.55; + color: var(--text-muted); +} + +.case-link { + display: inline-block; + margin-top: 0.4rem; + font-size: 0.85rem; + font-weight: 600; +} + +@media (max-width: 768px) { + + .cases-grid { + grid-template-columns: 1fr; + } + +} + +@media (min-width: 769px) and (max-width: 1024px) { + + .cases-grid { + grid-template-columns: repeat(2, minmax(0, 1fr)); + } + .cases-grid .case-card:last-child { + grid-column: 1 / -1; + } + +} + +:root[data-da-variant="v12"] .site-footer { + border-top-color: rgba(126, 99, 75, 0.14); + background: rgba(246, 238, 228, 0.76); +} + +@media (max-width: 1024px) { + + :root[data-da-variant="v12"] .figma-lab-nav-row { + grid-template-columns: 1fr; + justify-items: start; + } + +:root[data-da-variant="v12"] .figma-lab-hero-grid, +:root[data-da-variant="v12"] .figma-lab-bottom-grid, +:root[data-da-variant="v12"] .hero-proof-grid, +:root[data-da-variant="v12"] .contact-signal-grid { + grid-template-columns: repeat(2, minmax(0, 1fr)); + } + +} + +@media (max-width: 767px) { + + :root[data-da-variant="v12"] .site-shell { + width: min(1120px, 94vw); + } + + :root[data-da-variant="v12"] .figma-lab-nav-title { + font-size: 1rem; + } + +:root[data-da-variant="v12"] .figma-lab-nav-list, +:root[data-da-variant="v12"] .figma-lab-cta-row { + width: 100%; + } + +:root[data-da-variant="v12"] .figma-lab-nav-link, +:root[data-da-variant="v12"] .figma-lab-pill, +:root[data-da-variant="v12"] .graphic-sprints-cta { + width: 100%; + justify-content: center; + } + +:root[data-da-variant="v12"] .figma-lab-bottom-grid, +:root[data-da-variant="v12"] .hero-proof-grid, +:root[data-da-variant="v12"] .contact-signal-grid { + grid-template-columns: 1fr; + } + + :root[data-da-variant="v12"] .figma-lab-map-card { + min-height: auto; + } + + :root[data-da-variant="v12"] .figma-lab-right { + padding: 0.75rem; + } + +} + +/* Shared saillant / ops alignment for lelectronrare */ +:root[data-da-variant="v12"] { + --bg: #060806; + --pcb-deep: #040504; + --pcb-core: #0a0f0b; + --text: #8dff93; + --text-muted: #61b965; + --line: rgba(51, 255, 51, 0.12); + --line-rail: rgba(51, 255, 255, 0.1); + --line-edge: rgba(51, 255, 51, 0.2); + --signal: #33ff33; + --electric: #33ffff; + --trace-cyan: #33ffff; + --trace-magenta: #ffaa00; +} + +:root[data-da-variant="v12"] body { + color: #8dff93; + background: + radial-gradient(980px 580px at 50% -10%, rgba(51, 255, 51, 0.08), transparent 62%), + radial-gradient(720px 420px at 100% 0%, rgba(51, 255, 255, 0.08), transparent 62%), + linear-gradient(180deg, #050705 0%, #070c08 48%, #050705 100%); + font-family: "Share Tech Mono", "IBM Plex Mono", ui-monospace, Menlo, Consolas, monospace; +} + +:root[data-da-variant="v12"] body::before { + background-image: repeating-linear-gradient( + 0deg, + transparent, + transparent 2px, + rgba(0, 0, 0, 0.32) 2px, + rgba(0, 0, 0, 0.32) 4px + ); + opacity: 0.68; + mix-blend-mode: screen; +} + +:root[data-da-variant="v12"] body::after { + background: + radial-gradient(ellipse at center, transparent 44%, rgba(0, 0, 0, 0.76) 100%), + linear-gradient(to right, rgba(51, 255, 255, 0.06) 1px, transparent 1px), + linear-gradient(to bottom, rgba(51, 255, 51, 0.05) 1px, transparent 1px); + background-size: auto, 34px 34px, 34px 34px; + opacity: 0.82; + -webkit-mask-image: none; + mask-image: none; +} + +:root[data-da-variant="v12"] h1, +:root[data-da-variant="v12"] h2, +:root[data-da-variant="v12"] h3, +:root[data-da-variant="v12"] .figma-lab-title, +:root[data-da-variant="v12"] .graphic-sprints-title, +:root[data-da-variant="v12"] .graphic-sprint-title, +:root[data-da-variant="v12"] .hero-proof-value, +:root[data-da-variant="v12"] .figma-lab-map-title { + font-family: "VT323", "IBM Plex Mono", ui-monospace, Menlo, Consolas, monospace; + letter-spacing: 0.03em; +} + +:root[data-da-variant="v12"] .site-nav { + background: + linear-gradient(180deg, rgba(10, 18, 11, 0.96), rgba(5, 9, 6, 0.98)), + repeating-linear-gradient(90deg, rgba(255, 255, 255, 0.015) 0 1px, transparent 1px 14px); + border-bottom-color: rgba(51, 255, 51, 0.18); + box-shadow: + inset 0 1px 0 rgba(255, 255, 255, 0.03), + 0 0 26px rgba(51, 255, 51, 0.05); +} + +:root[data-da-variant="v12"] .site-nav::before { + height: 3px; + background: linear-gradient(90deg, #33ffff 0%, #33ff33 48%, #ffaa00 100%); + animation: 2.6s linear infinite navProgressFlow; +} + +:root[data-da-variant="v12"] .site-nav::after { + display: block; + mix-blend-mode: screen; +} + +:root[data-da-variant="v12"] .figma-lab-nav-row { + min-height: 3.4rem; + gap: 0.9rem; + padding: 0.5rem 0; +} + +:root[data-da-variant="v12"] .figma-lab-nav-title { + display: inline-flex; + flex-direction: column; + gap: 0.12rem; + color: #8fff94; + font-family: "Share Tech Mono", "IBM Plex Mono", ui-monospace, Menlo, Consolas, monospace; + font-size: 0.78rem; + letter-spacing: 0.14em; + text-transform: uppercase; +} + +:root[data-da-variant="v12"] .figma-lab-nav-kicker { + color: #61b965; + font-size: 0.58rem; + letter-spacing: 0.16em; +} + +:root[data-da-variant="v12"] .figma-lab-nav-list { + gap: 0.5rem; +} + +:root[data-da-variant="v12"] .figma-lab-nav-link, +:root[data-da-variant="v12"] .site-contrast-toggle { + min-height: 2.2rem; + display: inline-flex; + align-items: center; + justify-content: center; + padding: 0.2rem 0.7rem; + border: 1px solid rgba(51, 255, 51, 0.16); + border-radius: 0; + background: + linear-gradient(180deg, rgba(16, 26, 17, 0.96), rgba(6, 11, 7, 0.98)), + repeating-linear-gradient(90deg, rgba(255, 255, 255, 0.015) 0 1px, transparent 1px 14px); + color: #66d46c; + font-family: "Share Tech Mono", "IBM Plex Mono", ui-monospace, Menlo, Consolas, monospace; + font-size: 0.66rem; + letter-spacing: 0.14em; + text-transform: uppercase; + box-shadow: + inset 0 1px 0 rgba(255, 255, 255, 0.03), + inset 0 0 0 1px rgba(0, 0, 0, 0.42); +} + +:root[data-da-variant="v12"] .figma-lab-nav-link:hover, +:root[data-da-variant="v12"] .figma-lab-nav-link:focus-visible, +:root[data-da-variant="v12"] .figma-lab-nav-link.is-active, +:root[data-da-variant="v12"] .figma-lab-nav-link[aria-current="location"], +:root[data-da-variant="v12"] .site-contrast-toggle:hover, +:root[data-da-variant="v12"] .site-contrast-toggle:focus-visible { + color: #cbffd0; + border-color: rgba(51, 255, 255, 0.3); + background: + linear-gradient(180deg, rgba(10, 21, 16, 0.98), rgba(7, 14, 10, 0.98)), + repeating-linear-gradient(90deg, rgba(255, 255, 255, 0.02) 0 1px, transparent 1px 14px); + box-shadow: + inset 0 0 0 1px rgba(51, 255, 255, 0.12), + 0 0 18px rgba(51, 255, 255, 0.08); + text-shadow: 0 0 10px rgba(51, 255, 51, 0.22); +} + +:root[data-da-variant="v12"] .site-contrast-toggle::before { + background: linear-gradient(90deg, rgba(51, 255, 255, 0.16), rgba(51, 255, 51, 0.16)); +} + +:root[data-da-variant="v12"] .figma-lab-left, +:root[data-da-variant="v12"] .figma-lab-right, +:root[data-da-variant="v12"] .circuit-board, +:root[data-da-variant="v12"] .graphic-sprints-panel, +:root[data-da-variant="v12"] .hero-proof-card, +:root[data-da-variant="v12"] .graphic-sprint-card, +:root[data-da-variant="v12"] .figma-lab-map-card { + border: 1px solid rgba(51, 255, 51, 0.16); + border-radius: 0; + background: + linear-gradient(180deg, rgba(12, 20, 13, 0.96), rgba(5, 10, 6, 0.98)), + repeating-linear-gradient(90deg, rgba(255, 255, 255, 0.015) 0 1px, transparent 1px 14px); + box-shadow: + inset 0 1px 0 rgba(255, 255, 255, 0.03), + inset 0 0 0 1px rgba(0, 0, 0, 0.42), + 0 0 24px rgba(51, 255, 51, 0.04); +} + +:root[data-da-variant="v12"] .circuit-board::before, +:root[data-da-variant="v12"] .circuit-board::after { + opacity: 1; +} + +:root[data-da-variant="v12"] .section-lead, +:root[data-da-variant="v12"] .figma-lab-copy, +:root[data-da-variant="v12"] .project-story-copy, +:root[data-da-variant="v12"] .contact-signal-copy, +:root[data-da-variant="v12"] .figma-lab-map-detail, +:root[data-da-variant="v12"] .figma-lab-map-copy, +:root[data-da-variant="v12"] .graphic-sprints-copy, +:root[data-da-variant="v12"] .graphic-sprints-foot-copy, +:root[data-da-variant="v12"] .graphic-sprint-objective { + color: #8dff93; + font-family: "Share Tech Mono", "IBM Plex Mono", ui-monospace, Menlo, Consolas, monospace; +} + +:root[data-da-variant="v12"] .studio-muted, +:root[data-da-variant="v12"] .footer-copy, +:root[data-da-variant="v12"] .hero-proof-detail, +:root[data-da-variant="v12"] .figma-lab-cta-help, +:root[data-da-variant="v12"] .figma-lab-nav-kicker, +:root[data-da-variant="v12"] .figma-lab-map-kicker { + color: #61b965; + font-family: "Share Tech Mono", "IBM Plex Mono", ui-monospace, Menlo, Consolas, monospace; +} + +:root[data-da-variant="v12"] .circuit-board .circuit-title-row::after, +:root[data-da-variant="v12"] .circuit-pinline { + background: linear-gradient(90deg, rgba(51, 255, 255, 0.22), rgba(51, 255, 51, 0.16), transparent); +} + +:root[data-da-variant="v12"] .circuit-node, +:root[data-da-variant="v12"] .circuit-node--green, +:root[data-da-variant="v12"] .circuit-node--magenta { + background: #33ff33; + box-shadow: + 0 0 0 2px rgba(51, 255, 51, 0.16), + 0 0 12px rgba(51, 255, 51, 0.3); +} + +:root[data-da-variant="v12"] .circuit-node--magenta { + background: #33ffff; + box-shadow: + 0 0 0 2px rgba(51, 255, 255, 0.16), + 0 0 12px rgba(51, 255, 255, 0.28); +} + +:root[data-da-variant="v12"] .hero-eyebrow, +:root[data-da-variant="v12"] .hero-proof-label, +:root[data-da-variant="v12"] .project-story-label, +:root[data-da-variant="v12"] .project-stage, +:root[data-da-variant="v12"] .contact-brief-title, +:root[data-da-variant="v12"] .graphic-sprints-kicker, +:root[data-da-variant="v12"] .graphic-sprint-status, +:root[data-da-variant="v12"] .graphic-sprint-window, +:root[data-da-variant="v12"] .graphic-sprint-progress-label, +:root[data-da-variant="v12"] .figma-lab-map-step { + color: #33ffff; + font-family: "Share Tech Mono", "IBM Plex Mono", ui-monospace, Menlo, Consolas, monospace; + letter-spacing: 0.16em; + text-transform: uppercase; +} + +:root[data-da-variant="v12"] .figma-lab-title { + max-width: none; + color: var(--ui-text-main); + font-size: clamp(2.7rem, 6.6vw, 5.15rem); + line-height: 0.82; + text-shadow: 0 10px 30px rgba(0, 0, 0, 0.32); +} + +:root[data-da-variant="v12"] .figma-lab-copy { + max-width: 64ch; + font-size: 0.9rem; + line-height: 1.6; +} + +:root[data-da-variant="v12"] .figma-lab-copy--mono { + color: #7de483; + font-size: 0.72rem; +} + +:root[data-da-variant="v12"] .hero-proof-value, +:root[data-da-variant="v12"] .graphic-sprints-title, +:root[data-da-variant="v12"] .graphic-sprint-title, +:root[data-da-variant="v12"] .figma-lab-map-title { + color: #a6ffaa; +} + +:root[data-da-variant="v12"] .hero-proof-value { + font-size: 2rem; + line-height: 0.95; +} + +:root[data-da-variant="v12"] .figma-lab-pill, +:root[data-da-variant="v12"] .graphic-sprints-cta { + min-height: 2.5rem; + border: 1px solid rgba(51, 255, 51, 0.18); + border-radius: 0; + font-family: "Share Tech Mono", "IBM Plex Mono", ui-monospace, Menlo, Consolas, monospace; + font-size: 0.68rem; + letter-spacing: 0.14em; + text-transform: uppercase; + box-shadow: + inset 0 1px 0 rgba(255, 255, 255, 0.03), + inset 0 0 0 1px rgba(0, 0, 0, 0.42); +} + +:root[data-da-variant="v12"] .figma-lab-pill--primary { + background: + linear-gradient(180deg, rgba(10, 27, 11, 0.98), rgba(6, 14, 7, 0.98)), + repeating-linear-gradient(90deg, rgba(255, 255, 255, 0.018) 0 1px, transparent 1px 14px); + border-color: rgba(51, 255, 51, 0.32); + color: #d3ffd5; + box-shadow: + inset 0 0 0 1px rgba(51, 255, 51, 0.12), + 0 0 18px rgba(51, 255, 51, 0.08); +} + +:root[data-da-variant="v12"] .figma-lab-pill--secondary, +:root[data-da-variant="v12"] .graphic-sprints-cta { + background: + linear-gradient(180deg, rgba(8, 20, 22, 0.98), rgba(5, 10, 12, 0.98)), + repeating-linear-gradient(90deg, rgba(255, 255, 255, 0.018) 0 1px, transparent 1px 14px); + border-color: rgba(51, 255, 255, 0.3); + color: #bfffff; + box-shadow: + inset 0 0 0 1px rgba(51, 255, 255, 0.1), + 0 0 18px rgba(51, 255, 255, 0.08); +} + +:root[data-da-variant="v12"] .figma-lab-pill--ghost { + background: + linear-gradient(180deg, rgba(18, 22, 14, 0.98), rgba(9, 11, 7, 0.98)), + repeating-linear-gradient(90deg, rgba(255, 255, 255, 0.018) 0 1px, transparent 1px 14px); + border-color: rgba(255, 170, 0, 0.24); + color: #ffd780; +} + +:root[data-da-variant="v12"] .figma-lab-pill:hover, +:root[data-da-variant="v12"] .figma-lab-pill:focus-visible, +:root[data-da-variant="v12"] .graphic-sprints-cta:hover, +:root[data-da-variant="v12"] .graphic-sprints-cta:focus-visible { + transform: translateY(-1px); + box-shadow: + inset 0 0 0 1px rgba(51, 255, 255, 0.12), + 0 0 22px rgba(51, 255, 255, 0.1); +} + +:root[data-da-variant="v12"] .hero-outcomes, +:root[data-da-variant="v12"] .figma-lab-notes { + border: 1px solid rgba(255, 170, 0, 0.28); + border-radius: 0; + background: + linear-gradient(180deg, rgba(24, 18, 7, 0.96), rgba(11, 8, 3, 0.98)), + repeating-linear-gradient(90deg, rgba(255, 255, 255, 0.015) 0 1px, transparent 1px 14px); + box-shadow: + inset 0 0 0 1px rgba(255, 170, 0, 0.08), + 0 0 20px rgba(255, 170, 0, 0.05); +} + +:root[data-da-variant="v12"] .hero-outcomes-title, +:root[data-da-variant="v12"] .figma-lab-notes-title { + color: #ffd780; +} + +:root[data-da-variant="v12"] .hero-outcomes-list, +:root[data-da-variant="v12"] .figma-lab-notes-list { + color: #ffd780; + font-family: "Share Tech Mono", "IBM Plex Mono", ui-monospace, Menlo, Consolas, monospace; +} + +/* Hero background photo */ +.hero-bg-photo { + position: absolute; + top: 0; + right: 0; + width: 45%; + height: 100%; + overflow: hidden; + pointer-events: none; + z-index: 0; + mask-image: linear-gradient(to left, rgba(0,0,0,0.18) 0%, transparent 85%); + -webkit-mask-image: linear-gradient(to left, rgba(0,0,0,0.18) 0%, transparent 85%); +} + +.hero-bg-photo img { + width: 100%; + height: 100%; + object-fit: cover; + object-position: center 30%; + filter: grayscale(0.5) contrast(1.1); + mix-blend-mode: luminosity; +} + +[data-theme="light"] .hero-bg-photo { + mask-image: linear-gradient(to left, rgba(0,0,0,0.12) 0%, transparent 80%); + -webkit-mask-image: linear-gradient(to left, rgba(0,0,0,0.12) 0%, transparent 80%); +} + +[data-theme="light"] .hero-bg-photo img { + filter: grayscale(0.6) contrast(1.05); +} + +@media (max-width: 767px) { + + .hero-bg-photo { + display: none; + } + +} + +:root[data-da-variant="v12"] .figma-lab-map-copy { + max-width: 72ch; + font-size: 0.84rem; +} + +:root[data-da-variant="v12"] .figma-lab-map-card { + min-height: 8.8rem; + gap: 0.36rem; + padding: 0.88rem; +} + +:root[data-da-variant="v12"] .figma-lab-map-card:hover, +:root[data-da-variant="v12"] .figma-lab-map-card:focus-visible, +:root[data-da-variant="v12"] .figma-lab-map-card.is-active, +:root[data-da-variant="v12"] .figma-lab-map-card[aria-current="location"] { + transform: translateY(-1px); + filter: none; + border-color: rgba(51, 255, 255, 0.22); + box-shadow: + inset 0 0 0 1px rgba(51, 255, 255, 0.1), + 0 0 22px rgba(51, 255, 255, 0.08); +} + +:root[data-da-variant="v12"] .figma-lab-map-card--cream, +:root[data-da-variant="v12"] .figma-lab-map-card--blue, +:root[data-da-variant="v12"] .figma-lab-map-card--green { + color: inherit; + background: + linear-gradient(180deg, rgba(12, 20, 13, 0.96), rgba(5, 10, 6, 0.98)), + repeating-linear-gradient(90deg, rgba(255, 255, 255, 0.015) 0 1px, transparent 1px 14px); +} + +:root[data-da-variant="v12"] .figma-lab-map-card--cream { + border-color: rgba(255, 170, 0, 0.22); +} + +:root[data-da-variant="v12"] .figma-lab-map-card--blue { + border-color: rgba(51, 255, 255, 0.22); +} + +:root[data-da-variant="v12"] .figma-lab-map-card--green { + border-color: rgba(51, 255, 51, 0.18); +} + +:root[data-da-variant="v12"] .graphic-sprints-panel { + padding: 0.88rem; +} + +:root[data-da-variant="v12"] .graphic-sprints-title { + font-size: clamp(2.2rem, 4vw, 3.2rem); + line-height: 0.94; +} + +:root[data-da-variant="v12"] .graphic-sprint-card:hover, +:root[data-da-variant="v12"] .graphic-sprint-card:focus-within { + border-color: rgba(51, 255, 255, 0.22); +} + +:root[data-da-variant="v12"] .graphic-sprint-progress { + border: 1px solid rgba(51, 255, 51, 0.18); + background: rgba(7, 12, 8, 0.92); +} + +:root[data-da-variant="v12"] .graphic-sprint-progress-fill { + background: linear-gradient(90deg, #33ffff 0%, #33ff33 52%, #ffaa00 100%); +} + +:root[data-da-variant="v12"] .graphic-sprint-deliverables li { + border: 1px solid rgba(51, 255, 51, 0.16); + border-radius: 0; + background: rgba(9, 16, 10, 0.96); + color: #8fff94; + font-family: "Share Tech Mono", "IBM Plex Mono", ui-monospace, Menlo, Consolas, monospace; +} + +:root[data-da-variant="v12"] .project-story-block, +:root[data-da-variant="v12"] .graphic-sprints-foot { + border-top-color: rgba(51, 255, 51, 0.14); +} + +:root[data-da-variant="v12"] .studio-link, +:root[data-da-variant="v12"] .footer-link { + color: #33ffff; +} + +:root[data-da-variant="v12"] .studio-link:hover, +:root[data-da-variant="v12"] .studio-link:focus-visible, +:root[data-da-variant="v12"] .footer-link:hover, +:root[data-da-variant="v12"] .footer-link:focus-visible { + color: #d7ffd7; +} + +:root[data-da-variant="v12"] .site-footer { + background: + linear-gradient(180deg, rgba(9, 16, 10, 0.98), rgba(4, 7, 5, 0.98)), + repeating-linear-gradient(90deg, rgba(255, 255, 255, 0.015) 0 1px, transparent 1px 14px); + border-top-color: rgba(51, 255, 51, 0.14); +} + +@media (max-width: 1024px) { + + :root[data-da-variant="v12"] .figma-lab-nav-row { + grid-template-columns: 1fr; + justify-items: start; + } + +} + +@media (max-width: 767px) { + +:root[data-da-variant="v12"] .figma-lab-nav-link, +:root[data-da-variant="v12"] .site-contrast-toggle, +:root[data-da-variant="v12"] .figma-lab-pill, +:root[data-da-variant="v12"] .graphic-sprints-cta { + width: 100%; + } + + :root[data-da-variant="v12"] .figma-lab-map-card { + min-height: auto; + } + +} + +/* Touch target minimums */ +.figma-lab-nav-link, +.site-navlink, +.footer-link { + min-height: 2.75rem; /* 44px */ + display: inline-flex; + align-items: center; +} + +.site-contrast-toggle { + min-height: 2.75rem; /* 44px */ +} + +/* About section photo integration */ +.about-intro { + display: flex; + gap: 1.5rem; + align-items: flex-start; + margin-top: 1.25rem; +} + +.about-portrait { + width: 12rem; + height: 12rem; + border: 1px solid var(--trace-cyan); + border-radius: var(--card-radius); + object-fit: cover; + flex-shrink: 0; +} + +@media (max-width: 767px) { + + .about-intro { + flex-direction: column; + align-items: center; + } + .about-portrait { + width: 10rem; + height: 10rem; + } + +} + +/* Photo strip gallery */ +.photo-strip { + width: 100%; + overflow: hidden; + margin-top: 3rem; + margin-bottom: 1rem; +} + +.photo-strip-track { + display: flex; + gap: 0.75rem; + overflow-x: auto; + scroll-snap-type: x mandatory; + scrollbar-width: none; + -ms-overflow-style: none; + padding: 0 4vw; +} + +.photo-strip-track::-webkit-scrollbar { + display: none; +} + +.photo-strip-img { + flex: 0 0 auto; + width: 280px; + height: 180px; + object-fit: cover; + border-radius: var(--card-radius, 0.95rem); + border: 1px solid var(--line); + scroll-snap-align: start; + filter: grayscale(0.3) contrast(1.05); + transition: filter 0.3s ease, transform 0.3s ease; +} + +.photo-strip-img:hover { + filter: grayscale(0) contrast(1.1); + transform: scale(1.03); +} + +[data-theme="light"] .photo-strip-img { + filter: grayscale(0.2) contrast(1); +} + +[data-theme="light"] .photo-strip-img:hover { + filter: grayscale(0) contrast(1.05); +} + +@media (max-width: 767px) { + + .photo-strip-img { + width: 220px; + height: 150px; + } + +} + +/* ── Video strip ────────────────── */ +.video-strip { + margin-top: 1.5rem; + overflow: hidden; +} + +.video-strip-track { + display: flex; + gap: 1rem; + overflow-x: auto; + scroll-snap-type: x mandatory; + padding: 0.5rem 0; +} + +.video-strip-track::-webkit-scrollbar { + display: none; +} + +.video-strip-clip { + flex: 0 0 auto; + width: 320px; + height: 180px; + object-fit: cover; + border-radius: var(--card-radius, 0.75rem); + scroll-snap-align: start; + filter: grayscale(0.4) contrast(1.1); + transition: filter 0.3s ease, transform 0.3s ease; + cursor: pointer; +} + +.video-strip-clip:hover { + filter: grayscale(0) contrast(1.05); + transform: scale(1.03); +} + +[data-theme="light"] .video-strip-clip { + filter: grayscale(0.2) contrast(1); +} + +[data-theme="light"] .video-strip-clip:hover { + filter: grayscale(0) contrast(1.05); +} + +@media (max-width: 767px) { + + .video-strip-clip { + width: 260px; + height: 146px; + } + +} + +/* ── Contact Minitel ────────────────── */ +.contact-minitel { + border: 2px solid var(--trace-cyan, #5bd1d8); + border-radius: var(--card-radius, 0.95rem); + overflow: hidden; + background: #0a0a0a; + box-shadow: + 0 0 30px rgba(91, 209, 216, 0.08), + 0 20px 40px rgba(0, 0, 0, 0.3); +} + +.contact-minitel-header { + display: flex; + align-items: center; + gap: 0.5rem; + padding: 0.6rem 1rem; + background: linear-gradient(180deg, #1a1a1a, #111111); + border-bottom: 1px solid rgba(91, 209, 216, 0.25); +} + +.contact-minitel-dot { + width: 10px; + height: 10px; + border-radius: 50%; + background: #ff5f57; + flex-shrink: 0; +} + +.contact-minitel-dot--amber { + background: #febc2e; +} + +.contact-minitel-dot--green { + background: #28c840; +} + +.contact-minitel-title-bar { + flex: 1; + text-align: center; + font-family: "IBM Plex Mono", ui-monospace, Menlo, Consolas, monospace; + font-size: 0.7rem; + font-weight: 600; + letter-spacing: 0.12em; + text-transform: uppercase; + color: rgba(91, 209, 216, 0.7); +} + +.contact-minitel-screen { + padding: 1.5rem 1.5rem 1.2rem; + background: + repeating-linear-gradient( + 0deg, + rgba(91, 209, 216, 0.03) 0 1px, + transparent 1px 4px + ), + linear-gradient(180deg, #0c0c0c 0%, #080808 100%); +} + +.contact-minitel-h2 { + margin: 0 0 1rem; + font-family: "IBM Plex Mono", ui-monospace, Menlo, Consolas, monospace; + font-size: 1.4rem; + font-weight: 600; + color: #5bd1d8; + text-shadow: 0 0 8px rgba(91, 209, 216, 0.4); +} + +.contact-minitel-line { + margin: 0.3rem 0; + font-family: "IBM Plex Mono", ui-monospace, Menlo, Consolas, monospace; + font-size: 0.88rem; + line-height: 1.6; + color: #d4f0f0; +} + +.contact-minitel-line--dim { + color: rgba(91, 209, 216, 0.45); +} + +.contact-minitel-label { + display: block; + margin-bottom: 0.4rem; + font-family: "IBM Plex Mono", ui-monospace, Menlo, Consolas, monospace; + font-size: 0.78rem; + font-weight: 600; + color: #5bd1d8; + letter-spacing: 0.06em; +} + +.contact-minitel-textarea-wrap { + margin: 1rem 0; +} + +.contact-minitel-textarea, +input.contact-minitel-textarea { + width: 100%; + padding: 0.8rem; + border: 1px solid rgba(91, 209, 216, 0.3); + border-radius: 0.4rem; + background: rgba(0, 0, 0, 0.6); + color: #e0f7f7; + font-family: "IBM Plex Mono", ui-monospace, Menlo, Consolas, monospace; + font-size: 0.85rem; + line-height: 1.6; + resize: vertical; + outline: none; + transition: border-color 0.2s ease; +} +input.contact-minitel-textarea::placeholder { + color: rgba(224, 247, 247, 0.4); +} + +.contact-minitel-textarea:focus, +input.contact-minitel-textarea:focus { + border-color: #5bd1d8; + box-shadow: 0 0 12px rgba(91, 209, 216, 0.15); +} + +.contact-minitel-actions { + display: flex; + flex-wrap: wrap; + gap: 0.6rem; + margin: 1rem 0; +} + +.contact-minitel-btn { + display: inline-flex; + align-items: center; + padding: 0.5rem 0.9rem; + border: 1px solid rgba(91, 209, 216, 0.4); + border-radius: 0.35rem; + background: rgba(91, 209, 216, 0.08); + color: #c8eded; + font-family: "IBM Plex Mono", ui-monospace, Menlo, Consolas, monospace; + font-size: 0.75rem; + font-weight: 500; + letter-spacing: 0.04em; + text-decoration: none; + cursor: pointer; + transition: all 0.15s ease; +} + +.contact-minitel-btn:hover, +.contact-minitel-btn:focus-visible { + border-color: #5bd1d8; + background: rgba(91, 209, 216, 0.15); + color: #ffffff; + box-shadow: 0 0 12px rgba(91, 209, 216, 0.12); +} + +.contact-minitel-btn--primary { + border-color: #5bd1d8; + background: rgba(91, 209, 216, 0.18); + color: #ffffff; + font-weight: 600; +} + +.contact-minitel-btn--primary:hover, +.contact-minitel-btn--primary:focus-visible { + background: rgba(91, 209, 216, 0.28); + box-shadow: 0 0 18px rgba(91, 209, 216, 0.2); +} +.contact-minitel-btn:disabled { + opacity: 0.5; + cursor: not-allowed; +} + +.contact-minitel-footer { + margin-top: 1rem; + padding-top: 0.5rem; +} + +.contact-minitel-link { + color: #5bd1d8; + text-decoration: none; +} + +.contact-minitel-link:hover { + text-decoration: underline; + text-shadow: 0 0 6px rgba(91, 209, 216, 0.3); +} + +/* ── Contact form: tabs ─────────────────────────────── */ +.contact-minitel-tabs { + display: flex; + gap: 0; + margin: 1rem 0 0.2rem; + border-bottom: 1px solid rgba(91, 209, 216, 0.25); +} + +.contact-minitel-tab { + flex: 1; + padding: 0.5rem 0.6rem; + border: 1px solid rgba(91, 209, 216, 0.2); + border-bottom: none; + border-radius: 0.35rem 0.35rem 0 0; + background: transparent; + color: rgba(91, 209, 216, 0.5); + font-family: "IBM Plex Mono", ui-monospace, Menlo, Consolas, monospace; + font-size: 0.72rem; + font-weight: 500; + letter-spacing: 0.04em; + cursor: pointer; + transition: all 0.15s ease; +} + +.contact-minitel-tab:hover { + color: rgba(91, 209, 216, 0.8); + background: rgba(91, 209, 216, 0.05); +} + +.contact-minitel-tab--active { + color: #5bd1d8; + background: rgba(91, 209, 216, 0.1); + border-color: rgba(91, 209, 216, 0.4); +} + +/* ── Contact form: fields ──────────────────────────── */ +.contact-minitel-form { + margin-top: 1rem; +} + +.contact-minitel-field { + margin-bottom: 0.8rem; +} + +.contact-minitel-input, +.contact-minitel-select { + width: 100%; + padding: 0.6rem 0.8rem; + border: 1px solid rgba(91, 209, 216, 0.3); + border-radius: 0.4rem; + background: rgba(0, 0, 0, 0.6); + color: #e0f7f7; + font-family: "IBM Plex Mono", ui-monospace, Menlo, Consolas, monospace; + font-size: 0.85rem; + line-height: 1.6; + outline: none; + transition: border-color 0.2s ease; + box-sizing: border-box; +} + +.contact-minitel-input::placeholder { + color: rgba(91, 209, 216, 0.35); +} + +.contact-minitel-input:focus, +.contact-minitel-select:focus { + border-color: #5bd1d8; + box-shadow: 0 0 12px rgba(91, 209, 216, 0.15); +} + +.contact-minitel-select { + appearance: none; + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'%3E%3Cpath fill='%235bd1d8' d='M2 4l4 4 4-4'/%3E%3C/svg%3E"); + background-repeat: no-repeat; + background-position: right 0.8rem center; + padding-right: 2rem; + cursor: pointer; +} + +.contact-minitel-select option { + background: #0c0c0c; + color: #e0f7f7; +} + +@media (max-width: 767px) { + + .contact-minitel-screen { + padding: 1rem; + } + + .contact-minitel-h2 { + font-size: 1.1rem; + } + + .contact-minitel-actions { + flex-direction: column; + } + + .contact-minitel-btn { + width: 100%; + justify-content: center; + } + + .contact-minitel-tab { + font-size: 0.65rem; + padding: 0.4rem 0.3rem; + } + +} diff --git a/src/styles/home-workbench.css b/src/styles/home-workbench.css new file mode 100644 index 0000000..92d8d97 --- /dev/null +++ b/src/styles/home-workbench.css @@ -0,0 +1,1582 @@ +:root[data-da-variant="v12"] { + --ui-shell-width: min(1120px, 95vw); + --ui-gutter: clamp(0.9rem, 1.8vw, 1.4rem); + --ui-corner: 0.9rem; + --ui-elevation: 0 18px 50px rgba(0, 0, 0, 0.35); + --ui-border-subtle: 1px solid rgba(104, 255, 202, 0.28); + --ui-bg-panel: linear-gradient(180deg, rgba(11, 34, 23, 0.94), rgba(8, 24, 17, 0.94)); + --ui-text-main: #f0fff8; + --ui-text-muted: #92caa8; + --ui-accent: #3dffd3; + --ui-accent-warm: #ffce79; +} + +:root[data-da-variant="v12"] .site-shell { + width: var(--ui-shell-width); + padding-left: var(--ui-gutter); + padding-right: var(--ui-gutter); +} + +:root[data-da-variant="v12"] .site-nav { + background: linear-gradient(180deg, rgba(9, 28, 21, 0.97), rgba(7, 20, 14, 0.97)); + border-bottom-color: rgba(104, 255, 202, 0.26); + box-shadow: + 0 1px 0 rgba(104, 255, 202, 0.28), + 0 18px 30px rgba(0, 0, 0, 0.36); + backdrop-filter: blur(14px); +} + +:root[data-da-variant="v12"] .site-nav::before { + height: 3px; + background: linear-gradient(90deg, #3dffd3 0%, #33ff99 48%, #ffd780 100%); +} + +:root[data-da-variant="v12"] .site-contrast-toggle { + border-radius: 999px; + min-height: 2.1rem; + padding: 0.28rem 0.8rem; + font-size: 0.66rem; + letter-spacing: 0.14em; + text-transform: uppercase; +} + +:root[data-da-variant="v12"] .figma-lab-nav-row { + gap: 0.65rem; +} + +:root[data-da-variant="v12"] .figma-lab-nav-title { + color: var(--ui-text-main); + font-family: "Share Tech Mono", "IBM Plex Mono", ui-monospace, Menlo, Consolas, monospace; + letter-spacing: 0.18em; + text-transform: uppercase; + text-decoration: none; +} + +:root[data-da-variant="v12"] .figma-lab-nav-kicker { + font-family: "Share Tech Mono", "IBM Plex Mono", ui-monospace, Menlo, Consolas, monospace; + color: #91e7bf; + letter-spacing: 0.14em; +} + +:root[data-da-variant="v12"] .figma-lab-nav-list { + gap: 0.54rem; +} + +:root[data-da-variant="v12"] .figma-lab-nav-link, +:root[data-da-variant="v12"] .site-navlink { + min-height: 2rem; + border-radius: 999px; + padding-inline: 0.78rem; + border-color: rgba(93, 209, 176, 0.32); + background: linear-gradient(180deg, rgba(11, 29, 22, 0.92), rgba(8, 20, 15, 0.95)); + color: #dcffe9; +} + +:root[data-da-variant="v12"] .figma-lab-nav-link:hover, +:root[data-da-variant="v12"] .figma-lab-nav-link:focus-visible, +:root[data-da-variant="v12"] .site-navlink:hover, +:root[data-da-variant="v12"] .site-navlink:focus-visible, +:root[data-da-variant="v12"] .figma-lab-nav-link.is-active, +:root[data-da-variant="v12"] .site-navlink.is-active, +:root[data-da-variant="v12"] .figma-lab-nav-link[aria-current="location"], +:root[data-da-variant="v12"] .site-navlink[aria-current="location"] { + border-color: rgba(61, 255, 211, 0.75); + color: #e7fff1; + box-shadow: + inset 0 0 0 1px rgba(61, 255, 211, 0.28), + 0 0 20px rgba(61, 255, 211, 0.2); +} + +:root[data-da-variant="v12"] .studio-structure { + padding-top: 1rem; + gap: 0.9rem; +} + +:root[data-da-variant="v12"] .structure-grid { + row-gap: 0.9rem; +} + +:root[data-da-variant="v12"] .structure-grid--hero { + margin-top: 0.2rem; +} + +:root[data-da-variant="v12"] .figma-lab-hero-grid { + gap: 0.8rem; +} + +:root[data-da-variant="v12"] .figma-lab-left, +:root[data-da-variant="v12"] .figma-lab-right { + border: var(--ui-border-subtle); + border-radius: var(--ui-corner); + background: var(--ui-bg-panel); + box-shadow: var(--ui-elevation); +} + +:root[data-da-variant="v12"] .figma-lab-left { + padding: clamp(1rem, 2vw, 1.35rem); + position: relative; + overflow: hidden; +} + +:root[data-da-variant="v12"] .figma-lab-right { + padding: 1rem; + display: grid; + align-content: start; + gap: 0.85rem; +} + +:root[data-da-variant="v12"] .figma-lab-title { + color: var(--ui-text-main); + letter-spacing: -0.05em; + line-height: 0.9; + font-size: clamp(2.05rem, 4.2vw, 3.95rem); + margin-top: 0.7rem; + max-width: none; + width: 100%; + text-align: center; + margin-left: auto; + margin-right: auto; + position: relative; + padding: 0.35rem 0 0.4rem; + text-shadow: 0 10px 30px rgba(0, 0, 0, 0.32); + text-wrap: balance; + overflow-wrap: anywhere; +} + +:root[data-da-variant="v12"] .figma-lab-title::before { + content: none; +} + +:root[data-da-variant="v12"] .hero-eyebrow { + margin: 0.05rem 0 0; + color: #b4ffd3; + text-transform: uppercase; + letter-spacing: 0.12em; + font-size: 0.66rem; +} + +:root[data-da-variant="v12"] .hero-panel-image::before { + content: ""; + position: absolute; + inset: 0; + background: + radial-gradient(circle at top center, rgba(61, 255, 211, 0.12), transparent 34%), + linear-gradient(180deg, rgba(4, 10, 7, 0.66), rgba(4, 10, 7, 0.92)), + url("/assets/da/openai/hero-carnet-labo-open-v2.webp") center / cover no-repeat; + opacity: 0.42; + pointer-events: none; +} + +:root[data-da-variant="v12"] .hero-panel-image::after { + content: ""; + position: absolute; + inset: auto 0 0 0; + height: 8rem; + background: + linear-gradient(180deg, rgba(0, 0, 0, 0), rgba(5, 12, 8, 0.9)), + repeating-linear-gradient(90deg, rgba(61, 255, 211, 0.12) 0 1px, transparent 1px 12px); + pointer-events: none; +} + +:root[data-da-variant="v12"] .hero-panel-image > * { + position: relative; + z-index: 1; +} + +:root[data-da-variant="v12"] .hero-panel-head { + display: flex; + align-items: flex-start; + justify-content: space-between; + gap: 1rem; +} + +:root[data-da-variant="v12"] .hero-eyebrow--image { + display: inline-flex; + padding: 0.34rem 0.54rem; + border: 1px solid rgba(61, 255, 211, 0.28); + background: + linear-gradient(180deg, rgba(8, 20, 15, 0.9), rgba(7, 15, 11, 0.9)), + url("/assets/da/openai/hero-carnet-labo-open-v2.webp") center / cover no-repeat; + box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.24); +} + +:root[data-da-variant="v12"] .hero-status-stack { + display: grid; + justify-items: end; + gap: 0.26rem; +} + +:root[data-da-variant="v12"] .hero-status-badge, +:root[data-da-variant="v12"] .hero-status-note { + font-family: "Share Tech Mono", "IBM Plex Mono", ui-monospace, Menlo, Consolas, monospace; + text-transform: uppercase; +} + +:root[data-da-variant="v12"] .hero-status-badge { + display: inline-flex; + align-items: center; + min-height: 2rem; + padding: 0.26rem 0.62rem; + border: 1px solid rgba(255, 206, 121, 0.34); + background: rgba(19, 15, 6, 0.78); + color: #ffd780; + font-size: 0.66rem; + letter-spacing: 0.14em; + box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.22); + text-decoration: none; +} + +:root[data-da-variant="v12"] .hero-status-note { + color: #a9e7ca; + font-size: 0.58rem; + letter-spacing: 0.1em; +} + +:root[data-da-variant="v12"] .figma-lab-copy { + color: var(--ui-text-muted); + margin-top: 0.8rem; + font-size: 1.02rem; + line-height: 1.74; + max-width: none; + width: 100%; +} + +:root[data-da-variant="v12"] .hero-copy-reveal--lead { + font-size: clamp(1.12rem, 1.2vw + 0.92rem, 1.42rem); + line-height: 1.72; + color: #d8f8e8; +} + +:root[data-da-variant="v12"] .figma-lab-copy--mono { + color: #b4f0d1; +} + +:root[data-da-variant="v12"] .hero-copy-reveal + .hero-copy-reveal { + margin-top: 0.82rem; +} + +:root[data-da-variant="v12"] .hero-proof-grid { + margin-top: 1.2rem; + display: grid; + gap: 0.78rem; + grid-template-columns: repeat(2, minmax(0, 1fr)); +} + +:root[data-da-variant="v12"] .hero-proof-card { + background: + linear-gradient(180deg, rgba(11, 28, 21, 0.92), rgba(7, 16, 12, 0.96)), + linear-gradient(135deg, rgba(61, 255, 211, 0.08), transparent 58%); + border: 1px dashed rgba(61, 255, 211, 0.26); + border-radius: 0.62rem; + padding: 0.9rem 0.92rem; + box-shadow: + inset 0 1px 0 rgba(255, 255, 255, 0.03), + inset 0 0 0 1px rgba(0, 0, 0, 0.42), + 0 18px 28px rgba(0, 0, 0, 0.18); + backdrop-filter: blur(10px); +} + +:root[data-da-variant="v12"] .hero-proof-label { + margin-bottom: 0.2rem; + text-transform: uppercase; + color: #b6ffd3; + letter-spacing: 0.08em; + font-size: 0.62rem; +} + +:root[data-da-variant="v12"] .hero-proof-value { + margin: 0; + color: #d9ffe8; + font-size: clamp(1.18rem, 2.1vw, 1.55rem); + line-height: 1.02; +} + +:root[data-da-variant="v12"] .hero-proof-detail { + margin: 0.34rem 0 0; + color: #9ed1bc; + font-size: 0.75rem; + line-height: 1.5; +} + +:root[data-da-variant="v12"] .figma-lab-cta-row { + margin-top: 0.8rem; + margin-bottom: 1rem; + gap: 0.78rem; + justify-content: center; + flex-wrap: wrap; +} + +:root[data-da-variant="v12"] .figma-lab-pill, +:root[data-da-variant="v12"] .dual-cta-btn, +:root[data-da-variant="v12"] .graphic-sprints-cta, +:root[data-da-variant="v12"] .hero-inline-link, +:root[data-da-variant="v12"] .project-reference-more { + display: inline-flex; + align-items: center; + justify-content: center; + min-height: 3.2rem; + border-radius: 999px; + padding-inline: 1.15rem; + border: 1px solid transparent; + text-decoration: none; + transition: transform 0.2s ease, filter 0.2s ease, box-shadow 0.2s ease, border-color 0.2s ease; + font-size: 0.86rem; + letter-spacing: 0.09em; + text-transform: uppercase; + font-family: "Share Tech Mono", "IBM Plex Mono", ui-monospace, Menlo, Consolas, monospace; +} + +:root[data-da-variant="v12"] .figma-lab-pill { + padding-block: 0.62rem; + min-height: 3.1rem; +} + +:root[data-da-variant="v12"] .figma-lab-pill--primary, +:root[data-da-variant="v12"] .hero-inline-link, +:root[data-da-variant="v12"] .dual-cta-btn--primary, +:root[data-da-variant="v12"] .figma-lab-pill--ghost { + color: var(--ui-text-main); + border-color: rgba(61, 255, 211, 0.45); + background: linear-gradient(180deg, rgba(15, 34, 25, 0.96), rgba(9, 19, 14, 0.98)); +} + +:root[data-da-variant="v12"] .figma-lab-pill--secondary, +:root[data-da-variant="v12"] .dual-cta-btn--secondary, +:root[data-da-variant="v12"] .graphic-sprints-cta { + color: #d5fff0; + border-color: rgba(61, 255, 211, 0.28); + background: rgba(6, 14, 10, 0.66); +} + +:root[data-da-variant="v12"] .hero-inline-link:hover, +:root[data-da-variant="v12"] .hero-inline-link:focus-visible, +:root[data-da-variant="v12"] .project-reference-more:hover, +:root[data-da-variant="v12"] .project-reference-more:focus-visible, +:root[data-da-variant="v12"] .hero-inline-link:active, +:root[data-da-variant="v12"] .project-reference-more:active, +:root[data-da-variant="v12"] .figma-lab-pill:hover, +:root[data-da-variant="v12"] .figma-lab-pill:focus-visible, +:root[data-da-variant="v12"] .dual-cta-btn:hover, +:root[data-da-variant="v12"] .dual-cta-btn:focus-visible, +:root[data-da-variant="v12"] .graphic-sprints-cta:hover, +:root[data-da-variant="v12"] .graphic-sprints-cta:focus-visible { + transform: translateY(-1px); + filter: brightness(1.07); + box-shadow: 0 0 0 1px rgba(61, 255, 211, 0.25), 0 12px 24px rgba(0, 0, 0, 0.24); +} + +:root[data-da-variant="v12"] .hero-outcomes, +:root[data-da-variant="v12"] .figma-lab-notes { + margin-top: 1.15rem; + border: 1px solid rgba(255, 215, 128, 0.38); + border-radius: var(--ui-corner); + background: linear-gradient(180deg, rgba(24, 18, 7, 0.94), rgba(11, 8, 3, 0.96)); + padding: 0.95rem 1rem; +} + +:root[data-da-variant="v12"] .figma-lab-notes-title, +:root[data-da-variant="v12"] .hero-outcomes-title { + margin: 0; + color: var(--ui-accent-warm); + font-size: 0.92rem; + text-transform: uppercase; + letter-spacing: 0.08em; +} + +:root[data-da-variant="v12"] .hero-outcomes-list, +:root[data-da-variant="v12"] .figma-lab-notes-list { + margin: 0.62rem 0 0; + padding: 0; + list-style: none; + display: grid; + gap: 0.38rem; + color: #ffd58c; + font-family: "Share Tech Mono", "IBM Plex Mono", ui-monospace, Menlo, Consolas, monospace; + font-size: 0.78rem; + line-height: 1.56; +} + +:root[data-da-variant="v12"] .hero-outcomes-list li { + display: grid; + grid-template-columns: auto 1fr; + gap: 0.4rem; +} + +:root[data-da-variant="v12"] .hero-outcomes-list li::before { + content: '—'; + color: #ffcf7d; +} + +:root[data-da-variant="v12"] .hero-right-panels { + grid-template-columns: 1fr; +} + +:root[data-da-variant="v12"] .hero-side-panel { + position: relative; + overflow: hidden; + min-height: 15rem; + padding: 1rem; + border: 1px solid rgba(61, 255, 211, 0.18); + background: + linear-gradient(180deg, rgba(7, 14, 10, 0.78), rgba(5, 12, 8, 0.94)), + linear-gradient(135deg, rgba(255, 215, 128, 0.05), transparent 44%); + box-shadow: + inset 0 0 0 1px rgba(0, 0, 0, 0.22), + 0 16px 30px rgba(0, 0, 0, 0.18); +} + +:root[data-da-variant="v12"] .hero-side-panel::before { + content: ""; + position: absolute; + inset: 0; + opacity: 0.26; + pointer-events: none; +} + +:root[data-da-variant="v12"] .hero-side-panel--routing::before { + background: + linear-gradient(180deg, rgba(5, 12, 8, 0.72), rgba(5, 12, 8, 0.9)), + url("/assets/da/openai/hero-pcb-routing-map-v2.webp") center / 640px auto repeat; +} + +:root[data-da-variant="v12"] .hero-side-panel--instrument::before { + background: + linear-gradient(180deg, rgba(5, 12, 8, 0.72), rgba(5, 12, 8, 0.9)), + url("/assets/da/openai/hero-instrument-panel-v2.webp") center / cover no-repeat; +} + +:root[data-da-variant="v12"] .hero-side-panel > * { + position: relative; + z-index: 1; +} + +:root[data-da-variant="v12"] .hero-side-kicker { + margin: 0; + color: #7ef4c1; + font-family: "Share Tech Mono", "IBM Plex Mono", ui-monospace, Menlo, Consolas, monospace; + font-size: 0.62rem; + letter-spacing: 0.14em; + text-transform: uppercase; +} + +:root[data-da-variant="v12"] .hero-side-title { + margin: 0.48rem 0 0; + color: #edfff6; + font-size: clamp(1.35rem, 2vw, 1.8rem); + line-height: 0.94; +} + +:root[data-da-variant="v12"] .hero-side-list { + margin: 0.9rem 0 0; + padding: 0; + list-style: none; + display: grid; + gap: 0.44rem; +} + +:root[data-da-variant="v12"] .hero-side-list li { + padding-left: 0.9rem; + color: #b8f8d9; + font-family: "Share Tech Mono", "IBM Plex Mono", ui-monospace, Menlo, Consolas, monospace; + font-size: 0.78rem; + line-height: 1.58; + position: relative; +} + +:root[data-da-variant="v12"] .hero-side-list li::before { + content: ""; + position: absolute; + left: 0; + top: 0.48rem; + width: 0.42rem; + height: 1px; + background: #3dffd3; +} + +:root[data-da-variant="v12"] .hero-side-metrics { + margin: 1rem 0 0; + display: grid; + gap: 0.56rem; +} + +:root[data-da-variant="v12"] .hero-side-metrics div { + display: grid; + grid-template-columns: 4.6rem 1fr; + gap: 0.5rem; + align-items: baseline; + padding-top: 0.4rem; + border-top: 1px solid rgba(61, 255, 211, 0.12); +} + +:root[data-da-variant="v12"] .hero-side-metrics dt { + margin: 0; + color: #7ef4c1; + font-family: "Share Tech Mono", "IBM Plex Mono", ui-monospace, Menlo, Consolas, monospace; + font-size: 0.62rem; + letter-spacing: 0.14em; + text-transform: uppercase; +} + +:root[data-da-variant="v12"] .hero-side-metrics dd { + margin: 0; + color: #edfff6; + font-family: "VT323", "IBM Plex Mono", ui-monospace, Menlo, Consolas, monospace; + font-size: 1.05rem; + letter-spacing: 0.04em; +} + +:root[data-da-variant="v12"] .hero-console-line { + margin-bottom: 0.8rem; +} + +:root[data-da-variant="v12"] .lab-note-link, +:root[data-da-variant="v12"] .projects-timeline-link { + color: #a5fed4; +} + +:root[data-da-variant="v12"] .lab-note-link:hover, +:root[data-da-variant="v12"] .lab-note-link:focus-visible, +:root[data-da-variant="v12"] .projects-timeline-link:hover, +:root[data-da-variant="v12"] .projects-timeline-link:focus-visible { + color: #f1fff3; +} + +:root[data-da-variant="v12"] .project-reference-actions, +:root[data-da-variant="v12"] .contact-signal-grid, +:root[data-da-variant="v12"] .trust-strip { + gap: 0.66rem; +} + +:root[data-da-variant="v12"] .circuit-board, +:root[data-da-variant="v12"] .flow-node-card, +:root[data-da-variant="v12"] .projects-timeline-content, +:root[data-da-variant="v12"] .lab-note-card, +:root[data-da-variant="v12"] .trust-pill, +:root[data-da-variant="v12"] .project-reference-panel, +:root[data-da-variant="v12"] .contact-signal-card, +:root[data-da-variant="v12"] .contact-brief-panel, +:root[data-da-variant="v12"] .dual-cta-rail, +:root[data-da-variant="v12"] .hero-proof-card, +:root[data-da-variant="v12"] .graphic-sprint-card, +:root[data-da-variant="v12"] .figma-lab-map-card { + border-radius: 0.9rem; + border-color: rgba(61, 255, 211, 0.22); + background: linear-gradient(180deg, rgba(11, 29, 22, 0.94), rgba(7, 18, 13, 0.96)); + box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.03), 0 0 24px rgba(0, 0, 0, 0.22); +} + +:root[data-da-variant="v12"] .circuit-title-row { + margin-bottom: 0.55rem; +} + +:root[data-da-variant="v12"] .circuit-node { + box-shadow: + 0 0 0 2px rgba(61, 255, 211, 0.26), + 0 0 14px rgba(61, 255, 211, 0.3); +} + +:root[data-da-variant="v12"] .section-lead { + color: #b6ffdf; + font-size: clamp(0.98rem, 1.7vw, 1.08rem); + line-height: 1.64; + max-width: none; +} + +:root[data-da-variant="v12"] .section-anchor h2 { + font-size: clamp(1.95rem, 3.2vw, 2.65rem); + line-height: 0.94; + letter-spacing: -0.05em; +} + +:root[data-da-variant="v12"] .section-anchor h3 { + font-size: clamp(1.22rem, 2.1vw, 1.48rem); + line-height: 0.98; + letter-spacing: -0.035em; +} + +:root[data-da-variant="v12"] .graphic-sprints-kicker { + font-size: 0.84rem; + letter-spacing: 0.18em; +} + +:root[data-da-variant="v12"] .graphic-sprints-copy { + font-size: clamp(1.04rem, 1.2vw + 0.9rem, 1.34rem); + line-height: 1.66; + max-width: none; +} + +:root[data-da-variant="v12"] .graphic-sprint-card-head { + gap: 0.7rem; + align-items: baseline; +} + +:root[data-da-variant="v12"] .graphic-sprint-status { + font-size: 0.92rem; + letter-spacing: 0.18em; +} + +:root[data-da-variant="v12"] .graphic-sprint-window { + font-size: 0.98rem; + letter-spacing: 0.14em; +} + +:root[data-da-variant="v12"] .graphic-sprint-title { + font-size: clamp(1.5rem, 2vw + 1rem, 2.05rem); + line-height: 0.96; +} + +:root[data-da-variant="v12"] .graphic-sprint-objective { + font-size: clamp(1rem, 1vw + 0.9rem, 1.24rem); + line-height: 1.72; +} + +:root[data-da-variant="v12"] .graphic-sprint-progress-label { + font-size: 0.92rem; + letter-spacing: 0.16em; +} + +:root[data-da-variant="v12"] .graphic-sprint-deliverables { + gap: 0.5rem; +} + +:root[data-da-variant="v12"] .graphic-sprint-deliverables li { + font-size: 1rem; + line-height: 1.58; +} + +:root[data-da-variant="v12"] .graphic-sprints-foot-copy { + font-size: clamp(1.02rem, 1vw + 0.92rem, 1.24rem); + line-height: 1.6; +} + +:root[data-da-variant="v12"] .section-anchor h2, +:root[data-da-variant="v12"] .section-anchor h3 { + color: var(--ui-text-main); +} + +:root[data-da-variant="v12"] .project-story-label, +:root[data-da-variant="v12"] .project-story-summary, +:root[data-da-variant="v12"] .contact-signal-title, +:root[data-da-variant="v12"] .contact-signal-copy { + margin: 0; +} + +:root[data-da-variant="v12"] .project-story-copy, +:root[data-da-variant="v12"] .contact-signal-copy { + font-size: 0.89rem; + line-height: 1.55; +} + +:root[data-da-variant="v12"] .about-panel .studio-chip { + padding: 0.95rem 1rem; + font-size: clamp(1rem, 1vw + 0.92rem, 1.26rem); + line-height: 1.62; + letter-spacing: 0.05em; +} + +:root[data-da-variant="v12"] .about-panel .trust-strip { + margin-top: 1rem; + padding-top: 1rem; + border-top: 1px solid rgba(61, 255, 211, 0.16); +} + +:root[data-da-variant="v12"] .about-panel .trust-pill, +:root[data-da-variant="v12"] .contact-panel .contact-draft-panel, +:root[data-da-variant="v12"] .contact-panel .contact-brief-panel { + background: + linear-gradient(180deg, rgba(9, 23, 17, 0.96), rgba(5, 13, 10, 0.98)), + linear-gradient(135deg, rgba(61, 255, 211, 0.05), transparent 58%); + border-color: rgba(61, 255, 211, 0.2); + box-shadow: + inset 0 1px 0 rgba(255, 255, 255, 0.03), + 0 0 24px rgba(0, 0, 0, 0.2); +} + +:root[data-da-variant="v12"] .about-panel .dual-cta-rail, +:root[data-da-variant="v12"] .contact-panel .contact-signal-grid, +:root[data-da-variant="v12"] .contact-panel .contact-brief-panel { + margin-top: 1rem; +} + +:root[data-da-variant="v12"] .contact-panel > .studio-muted:last-of-type { + margin-bottom: 0.2rem; +} + +:root[data-da-variant="v12"] .figma-lab-copy, +:root[data-da-variant="v12"] .section-lead, +:root[data-da-variant="v12"] .studio-muted, +:root[data-da-variant="v12"] .project-story-copy, +:root[data-da-variant="v12"] .contact-signal-copy, +:root[data-da-variant="v12"] .projects-timeline-summary, +:root[data-da-variant="v12"] .trust-pill-detail, +:root[data-da-variant="v12"] .lab-note-flow dd { + text-align: justify; + text-wrap: pretty; +} + +:root[data-da-variant="v12"] .project-case-card { + border-color: rgba(61, 255, 211, 0.18); + background: + linear-gradient(180deg, rgba(6, 16, 12, 0.96), rgba(4, 10, 7, 0.98)), + radial-gradient(circle at top right, rgba(61, 255, 211, 0.08), transparent 34%); + box-shadow: + inset 0 1px 0 rgba(255, 255, 255, 0.03), + 0 18px 36px rgba(0, 0, 0, 0.28); +} + +:root[data-da-variant="v12"] .project-case-card .project-story-block + .project-story-block { + margin-top: 0.7rem; + padding-top: 0.7rem; + border-top: 1px solid rgba(61, 255, 211, 0.1); +} + +:root[data-da-variant="v12"] .project-case-card .project-story-label, +:root[data-da-variant="v12"] .project-case-card .project-stage { + color: #8ff3c6; +} + +:root[data-da-variant="v12"] .project-case-card h3, +:root[data-da-variant="v12"] .project-case-card .project-story-copy { + color: #ecfff7; +} + +:root[data-da-variant="v12"] .contact-signal-card { + display: block; + width: 100%; + text-decoration: none; + color: inherit; + text-align: left; + cursor: pointer; + transition: + transform 0.18s ease, + border-color 0.18s ease, + box-shadow 0.18s ease, + background 0.18s ease; +} + +:root[data-da-variant="v12"] .contact-signal-card:hover, +:root[data-da-variant="v12"] .contact-signal-card:focus-visible { + transform: translateY(-2px); + border-color: rgba(61, 255, 211, 0.42); + box-shadow: + inset 0 0 0 1px rgba(61, 255, 211, 0.12), + 0 0 26px rgba(61, 255, 211, 0.14); +} + +:root[data-da-variant="v12"][data-theme="default"] .contact-draft-panel { + border: 1px solid rgba(61, 255, 211, 0.2); + border-radius: 0.9rem; + background: + linear-gradient(180deg, rgba(10, 22, 16, 0.94), rgba(6, 14, 10, 0.96)), + linear-gradient(135deg, rgba(61, 255, 211, 0.06), transparent 54%); + padding: 1rem; +} + +:root[data-da-variant="v12"] .contact-draft-head { + display: flex; + flex-wrap: wrap; + justify-content: space-between; + gap: 0.8rem; + align-items: center; +} + +:root[data-da-variant="v12"] .contact-draft-actions { + display: flex; + flex-wrap: wrap; + gap: 0.62rem; +} + +:root[data-da-variant="v12"] .contact-draft-btn { + display: inline-flex; + align-items: center; + justify-content: center; + min-height: 2.9rem; + padding: 0.6rem 1rem; + border-radius: 999px; + border: 1px solid rgba(61, 255, 211, 0.24); + background: rgba(7, 16, 12, 0.8); + color: #e6fff3; + text-decoration: none; + font-family: "Share Tech Mono", "IBM Plex Mono", ui-monospace, Menlo, Consolas, monospace; + font-size: 0.78rem; + letter-spacing: 0.08em; + text-transform: uppercase; + transition: transform 0.18s ease, border-color 0.18s ease, box-shadow 0.18s ease; +} + +:root[data-da-variant="v12"] .contact-draft-btn:hover, +:root[data-da-variant="v12"] .contact-draft-btn:focus-visible { + transform: translateY(-1px); + border-color: rgba(61, 255, 211, 0.42); + box-shadow: 0 0 0 1px rgba(61, 255, 211, 0.12), 0 12px 22px rgba(0, 0, 0, 0.16); +} + +:root[data-da-variant="v12"] .contact-draft-btn--linkedin { + background: linear-gradient(180deg, rgba(15, 34, 25, 0.96), rgba(9, 19, 14, 0.98)); +} + +:root[data-da-variant="v12"] .contact-draft-btn--mail { + background: + linear-gradient(180deg, rgba(12, 26, 20, 0.96), rgba(8, 17, 13, 0.98)), + linear-gradient(135deg, rgba(255, 170, 0, 0.08), transparent 60%); + border-color: rgba(255, 170, 0, 0.24); + color: #fff3d7; +} + +:root[data-da-variant="v12"] .contact-draft-textarea { + width: 100%; + margin-top: 0.9rem; + border: 1px solid rgba(61, 255, 211, 0.18); + border-radius: 0.8rem; + background: rgba(5, 12, 8, 0.82); + color: #e6fff3; + padding: 0.95rem 1rem; + font: inherit; + line-height: 1.62; + resize: vertical; + min-height: 15rem; +} + +:root[data-da-variant="v12"] .contact-draft-textarea:focus-visible { + outline: 1px solid rgba(61, 255, 211, 0.44); + outline-offset: 0; +} + +:root[data-da-variant="v12"] .hero-title-word { + display: inline; + position: relative; + z-index: 1; + white-space: normal; +} + +:root[data-da-variant="v12"] .hero-lockup { + display: flex; + justify-content: center; + margin: 0.45rem auto 0.08rem; + padding: 0.22rem 0 0; +} + +:root[data-da-variant="v12"] .hero-lockup-image { + display: block; + width: min(24rem, 72vw); + height: auto; + opacity: 0.96; + filter: + saturate(1.02) + brightness(1.08) + contrast(1.12) + drop-shadow(0 10px 24px rgba(0, 0, 0, 0.26)); +} + +:root[data-da-variant="v12"] .hero-slogan { + margin: -0.72rem auto 0.8rem; + text-align: center; + color: var(--ui-text-main); + font-size: clamp(2.05rem, 4.2vw, 3.95rem); + line-height: 0.9; + letter-spacing: -0.05em; + text-shadow: 0 10px 30px rgba(0, 0, 0, 0.32); + max-width: none; + font-family: "VT323", "IBM Plex Mono", ui-monospace, Menlo, Consolas, monospace; + font-weight: 400; + position: relative; +} + +:root[data-da-variant="v12"] .hero-slogan-line { + display: block; + white-space: nowrap; +} + +:root[data-da-variant="v12"] .hero-slogan-char { + display: inline-block; + animation: hero-slogan-wave 2.8s ease-in-out infinite; + animation-delay: calc(var(--char-index, 0) * 0.06s); + will-change: transform, filter; + text-shadow: + -0.025em 0 rgba(255, 72, 150, 0.28), + 0.03em 0 rgba(61, 255, 211, 0.28), + 0 0 0.15em rgba(255, 255, 255, 0.08); +} + +:root[data-da-variant="v12"] .hero-slogan-char.is-space { + width: 0.32em; +} + +:root[data-da-variant="v12"] .hero-slogan::after { + content: ""; + position: absolute; + left: 0; + right: 0; + top: 50%; + height: 0.08em; + background: linear-gradient(90deg, transparent, rgba(61, 255, 211, 0.55), rgba(255, 170, 0, 0.32), transparent); + mix-blend-mode: screen; + opacity: 0.48; + transform: translateY(-50%); + animation: hero-scanline 3.8s linear infinite; + pointer-events: none; +} + +@keyframes hero-slogan-wave { + 0%, + 100% { + transform: translateY(0) scaleY(1); + filter: drop-shadow(0 0 0 rgba(61, 255, 211, 0)); + } + 25% { + transform: translateY(-0.14em) scaleY(1.04); + filter: drop-shadow(0 0 0.35rem rgba(61, 255, 211, 0.18)); + } + 50% { + transform: translateY(0.08em) scaleY(0.98); + filter: drop-shadow(0 0 0 rgba(61, 255, 211, 0)); + } + 75% { + transform: translateY(-0.05em) scaleY(1.02); + filter: drop-shadow(0 0 0.22rem rgba(255, 170, 0, 0.16)); + } +} + +@keyframes hero-scanline { + 0% { + transform: translateY(-0.9em); + opacity: 0; + } + 12% { + opacity: 0.52; + } + 50% { + transform: translateY(0.2em); + opacity: 0.32; + } + 100% { + transform: translateY(1.05em); + opacity: 0; + } +} + +:root[data-da-variant="v12"] .studio-muted { + color: #93c4ac; + max-width: none; +} + +:root[data-da-variant="v12"] .figma-lab-map-card { + min-height: 9.8rem; +} + +:root[data-da-variant="v12"] .figma-lab-bottom-map--routing { + position: relative; + overflow: hidden; + padding: 1rem; + border: 1px solid rgba(61, 255, 211, 0.18); + background: + linear-gradient(180deg, rgba(5, 12, 8, 0.76), rgba(5, 12, 8, 0.9)), + url("/assets/da/openai/hero-pcb-routing-map-v2.webp") center / cover no-repeat; + box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.24); +} + +:root[data-da-variant="v12"] .about-panel, +:root[data-da-variant="v12"] .graphic-sprints-panel--routing { + position: relative; + overflow: hidden; +} + +:root[data-da-variant="v12"] .about-panel::before, +:root[data-da-variant="v12"] .graphic-sprints-panel--routing::before { + content: ""; + position: absolute; + inset: 0; + background: + linear-gradient(180deg, rgba(5, 12, 8, 0.82), rgba(5, 12, 8, 0.9)), + url("/assets/da/openai/hero-pcb-routing-map-v2.webp") center / 720px auto repeat; + opacity: 0.24; + pointer-events: none; +} + +:root[data-da-variant="v12"] .about-panel > *, +:root[data-da-variant="v12"] .graphic-sprints-panel--routing > * { + position: relative; + z-index: 1; +} + +:root[data-da-variant="v12"] .flow-panel { + position: relative; + overflow: hidden; +} + +:root[data-da-variant="v12"] .flow-panel::before { + content: ""; + position: absolute; + inset: 0; + background: + radial-gradient(circle at top right, rgba(255, 206, 121, 0.16), transparent 28%), + linear-gradient(180deg, rgba(5, 12, 8, 0.72), rgba(5, 12, 8, 0.9)), + url("/assets/da/openai/hero-instrument-panel-v2.webp") center / cover no-repeat; + opacity: 0.36; + pointer-events: none; +} + +:root[data-da-variant="v12"] .flow-panel > * { + position: relative; + z-index: 1; +} + +:root[data-da-variant="v12"] .flow-narrative-grid { + display: grid; + gap: 0.82rem; + grid-template-columns: 1fr; +} + +:root[data-da-variant="v12"] .flow-narrative-card { + position: relative; + overflow: hidden; + padding: 1rem 1rem 1.05rem; + border: 1px solid rgba(61, 255, 211, 0.18); + border-radius: 0.9rem; + background: + linear-gradient(180deg, rgba(7, 17, 12, 0.92), rgba(4, 10, 7, 0.96)), + linear-gradient(135deg, rgba(61, 255, 211, 0.08), transparent 50%); + box-shadow: + inset 0 1px 0 rgba(255, 255, 255, 0.03), + 0 16px 30px rgba(0, 0, 0, 0.18); +} + +:root[data-da-variant="v12"] .flow-narrative-card::before { + content: ""; + position: absolute; + inset: 0; + opacity: 0.2; + pointer-events: none; +} + +:root[data-da-variant="v12"] .flow-narrative-card--signal::before, +:root[data-da-variant="v12"] .flow-narrative-card--card::before { + background: + linear-gradient(180deg, rgba(5, 12, 8, 0.72), rgba(5, 12, 8, 0.92)), + url("/assets/da/openai/hero-pcb-routing-map-v2.webp") center / 720px auto repeat; +} + +:root[data-da-variant="v12"] .flow-narrative-card--proof::before, +:root[data-da-variant="v12"] .flow-narrative-card--suite::before { + background: + linear-gradient(180deg, rgba(5, 12, 8, 0.72), rgba(5, 12, 8, 0.92)), + url("/assets/da/openai/hero-instrument-panel-v2.webp") center / cover no-repeat; +} + +:root[data-da-variant="v12"] .flow-narrative-card > * { + position: relative; + z-index: 1; +} + +:root[data-da-variant="v12"] .flow-narrative-kicker { + margin: 0; + color: #98f3ca; + font-family: "Share Tech Mono", "IBM Plex Mono", ui-monospace, Menlo, Consolas, monospace; + font-size: 0.62rem; + letter-spacing: 0.16em; + text-transform: uppercase; +} + +:root[data-da-variant="v12"] .flow-narrative-title { + margin: 0.42rem 0 0; + color: #edfff6; + font-size: clamp(1.2rem, 2.2vw, 1.54rem); + line-height: 0.98; + letter-spacing: -0.03em; +} + +:root[data-da-variant="v12"] .flow-narrative-copy { + margin: 0.68rem 0 0; + color: #b9f5db; + font-size: 0.9rem; + line-height: 1.62; + text-align: justify; + text-wrap: pretty; +} + +:root[data-da-variant="v12"] .figma-lab-bottom-map--routing::before { + content: ""; + position: absolute; + inset: 0; + background: + radial-gradient(circle at top right, rgba(255, 206, 121, 0.12), transparent 30%), + linear-gradient(90deg, rgba(61, 255, 211, 0.06), transparent 28%); + pointer-events: none; +} + +:root[data-da-variant="v12"] .figma-lab-bottom-map--routing > * { + position: relative; + z-index: 1; +} + +:root[data-da-variant="v12"] .figma-lab-map-intro { + padding: 1.15rem 1.1rem; + border: 1px solid rgba(61, 255, 211, 0.18); + background: rgba(5, 12, 8, 0.62); + backdrop-filter: blur(8px); +} + +:root[data-da-variant="v12"] .figma-lab-map-kicker { + margin: 0; + color: #98f3ca; + font-family: "Share Tech Mono", "IBM Plex Mono", ui-monospace, Menlo, Consolas, monospace; + font-size: 0.62rem; + letter-spacing: 0.16em; + text-transform: uppercase; +} + +:root[data-da-variant="v12"] .figma-lab-map-copy { + margin: 0.55rem 0 0; + max-width: 62ch; + color: #d9fff0; + font-size: 0.92rem; + line-height: 1.66; +} + +:root[data-da-variant="v12"] .figma-lab-map-card { + position: relative; + overflow: hidden; + backdrop-filter: blur(10px); + padding: 1rem 1rem 1.05rem; +} + +:root[data-da-variant="v12"] .figma-lab-map-card::before { + content: ""; + position: absolute; + inset: 0; + background: + linear-gradient(180deg, rgba(255, 255, 255, 0.02), rgba(255, 255, 255, 0)), + linear-gradient(135deg, rgba(61, 255, 211, 0.08), transparent 46%); + pointer-events: none; +} + +:root[data-da-variant="v12"] .figma-lab-map-card > * { + position: relative; + z-index: 1; +} + +:root[data-da-variant="v12"] .figma-lab-map-card:hover, +:root[data-da-variant="v12"] .figma-lab-map-card:focus-visible, +:root[data-da-variant="v12"] .figma-lab-map-card.is-active, +:root[data-da-variant="v12"] .figma-lab-map-card[aria-current="location"] { + transform: translateY(-2px); + border-color: rgba(61, 255, 211, 0.45); + box-shadow: inset 0 0 0 1px rgba(61, 255, 211, 0.14), 0 0 22px rgba(61, 255, 211, 0.16); +} + +:root[data-da-variant="v12"] .graphic-sprints-title { + line-height: 1; +} + +:root[data-da-variant="v12"] .figma-lab-map-step { + opacity: 0.92; +} + +:root[data-da-variant="v12"] .figma-lab-map-context { + display: inline-flex; + align-items: center; + min-height: 1.45rem; + padding: 0.08rem 0.42rem; + border: 1px solid rgba(61, 255, 211, 0.2); + background: rgba(5, 12, 8, 0.62); + color: #baffdf; + font-family: "Share Tech Mono", "IBM Plex Mono", ui-monospace, Menlo, Consolas, monospace; + font-size: 0.56rem; + letter-spacing: 0.14em; + text-transform: uppercase; +} + +:root[data-da-variant="v12"] .figma-lab-map-title { + font-size: 1.44rem; + line-height: 0.93; +} + +:root[data-da-variant="v12"] .figma-lab-map-detail { + margin-top: 0.2rem; + font-size: 0.84rem; + line-height: 1.62; +} + +:root[data-da-variant="v12"] .graphic-sprints-panel { + padding: 1rem; +} + +:root[data-da-variant="v12"] .graphic-sprint-progress { + border-color: rgba(61, 255, 211, 0.28); +} + +:root[data-da-variant="v12"] .graphic-sprint-progress-fill { + background: linear-gradient(90deg, #3dffd3 0%, #6eff8a 52%, #ffd780 100%); +} + +:root[data-da-variant="v12"] .projects-timeline { + gap: 0.6rem; +} + +:root[data-da-variant="v12"] .projects-timeline-content { + padding: 0.9rem; +} + +:root[data-da-variant="v12"] .contact-signal-card, +:root[data-da-variant="v12"] .contact-brief-chip { + border-radius: 0.72rem; +} + +:root[data-da-variant="v12"] .site-footer { + border-top-color: rgba(61, 255, 211, 0.19); + background: + linear-gradient(180deg, rgba(11, 22, 15, 0.95), rgba(5, 9, 7, 0.98)), + linear-gradient(135deg, rgba(61, 255, 211, 0.04), transparent 56%); + padding-top: 1.4rem; + padding-bottom: 1.8rem; +} + +:root[data-da-variant="v12"] .footer-copy, +:root[data-da-variant="v12"] .footer-link { + color: #8ac7a5; +} + +:root[data-da-variant="v12"] .footer-grid--enhanced { + display: grid; + grid-template-columns: minmax(0, 1fr); + gap: 0.7rem; + align-items: stretch; +} + +:root[data-da-variant="v12"] .footer-col, +:root[data-da-variant="v12"] .footer-links { + border: 1px solid rgba(61, 255, 211, 0.16); + border-radius: 0.95rem; + background: + linear-gradient(180deg, rgba(10, 20, 14, 0.92), rgba(6, 12, 9, 0.96)), + linear-gradient(135deg, rgba(61, 255, 211, 0.04), transparent 58%); + padding: 1rem 1.05rem; +} + +:root[data-da-variant="v12"] .footer-brand-meta { + display: grid; + grid-template-columns: minmax(0, 1.18fr) minmax(0, 0.82fr); + gap: 0.8rem; + align-items: center; + margin-top: 0.4rem; +} + +:root[data-da-variant="v12"] .footer-copy--right { + justify-self: end; + width: 100%; + max-width: 34rem; + text-align: right; +} + +:root[data-da-variant="v12"] .footer-title, +:root[data-da-variant="v12"] .footer-column-title { + color: #e7fff1; + letter-spacing: 0.06em; +} + +:root[data-da-variant="v12"] .footer-links { + display: flex; + flex-wrap: wrap; + gap: 0.62rem; + align-items: center; +} + +:root[data-da-variant="v12"] .footer-links--single-rail { + justify-content: flex-start; + align-content: flex-start; +} + +:root[data-da-variant="v12"] .footer-link { + display: inline-flex; + align-items: center; + justify-content: center; + min-height: 2.55rem; + padding: 0.45rem 0.75rem; + border: 1px solid rgba(61, 255, 211, 0.14); + border-radius: 0.78rem; + background: rgba(5, 12, 8, 0.52); + text-decoration: none; + white-space: nowrap; +} + +:root[data-da-variant="v12"] .footer-endnote { + border-top: 1px solid rgba(61, 255, 211, 0.12); + margin-top: 1rem; + padding-top: 0.2rem; +} + +:root[data-da-variant="v12"] [data-reveal] { + transform: translateY(14px); + opacity: 0; + transition: + opacity 0.52s ease-out, + transform 0.52s cubic-bezier(0.22, 1, 0.36, 1), + filter 0.44s ease; +} + +:root[data-da-variant="v12"] [data-reveal].is-revealed { + transform: none; + opacity: 1; + filter: none; +} + +@media (max-width: 1180px) { + :root[data-da-variant="v12"] .footer-brand-meta { + grid-template-columns: 1fr; + } + + :root[data-da-variant="v12"] .footer-copy--right { + text-align: left; + } + + :root[data-da-variant="v12"] .figma-lab-hero-grid { + grid-template-columns: 1fr; + gap: 0.74rem; + } + + :root[data-da-variant="v12"] .figma-lab-right { + margin-top: 0; + } + + :root[data-da-variant="v12"] .hero-proof-grid { + grid-template-columns: repeat(2, minmax(0, 1fr)); + } + + :root[data-da-variant="v12"][data-theme="default"] .site-nav { + background: rgba(10, 22, 16, 0.98); + } +} + +@media (min-width: 768px) and (max-width: 1179px) { + :root[data-da-variant="v12"] .structure-grid--hero, + :root[data-da-variant="v12"] .structure-grid--sprints { + grid-template-columns: 1fr; + } + + :root[data-da-variant="v12"] .site-nav { + backdrop-filter: blur(8px); + } +} + +@media (max-width: 767px) { + :root[data-da-variant="v12"] .site-shell { + width: min(1120px, 93vw); + } + + :root[data-da-variant="v12"] .figma-lab-left { + padding: 0.9rem; + } + + :root[data-da-variant="v12"] .hero-proof-grid, + :root[data-da-variant="v12"] .figma-lab-hero-grid, + :root[data-da-variant="v12"] .system-pipeline, + :root[data-da-variant="v12"] .trust-strip, + :root[data-da-variant="v12"] .contact-signal-grid, + :root[data-da-variant="v12"] .figma-lab-bottom-grid, + :root[data-da-variant="v12"] .hero-proof-grid { + grid-template-columns: 1fr; + } + + :root[data-da-variant="v12"] .figma-lab-title { + font-size: clamp(1.34rem, 5.8vw, 1.72rem); + line-height: 0.88; + padding: 0.2rem 0 0.25rem; + max-width: none; + } + + :root[data-da-variant="v12"] .hero-lockup { + margin: 0.45rem auto 0.8rem; + padding: 0; + } + + :root[data-da-variant="v12"] .hero-lockup-image { + width: min(15rem, 74vw); + } + + :root[data-da-variant="v12"] .hero-slogan { + margin-bottom: 0.7rem; + font-size: clamp(1.34rem, 5.8vw, 1.72rem); + line-height: 0.88; + max-width: none; + } + + :root[data-da-variant="v12"] .hero-slogan-line { + white-space: normal; + } + + :root[data-da-variant="v12"] .hero-eyebrow--image { + width: 100%; + justify-content: center; + text-align: center; + line-height: 1.45; + } + + :root[data-da-variant="v12"] .hero-status-stack { + width: 100%; + justify-items: center; + } + + :root[data-da-variant="v12"] .figma-lab-copy, + :root[data-da-variant="v12"] .section-lead, + :root[data-da-variant="v12"] .studio-muted, + :root[data-da-variant="v12"] .project-story-copy, + :root[data-da-variant="v12"] .contact-signal-copy, + :root[data-da-variant="v12"] .projects-timeline-summary, + :root[data-da-variant="v12"] .trust-pill-detail, + :root[data-da-variant="v12"] .lab-note-flow dd { + text-align: left; + } + + :root[data-da-variant="v12"] .figma-lab-copy { + font-size: 0.98rem; + line-height: 1.68; + } + + :root[data-da-variant="v12"] .hero-copy-reveal--lead { + font-size: 1.02rem; + line-height: 1.66; + } + + :root[data-da-variant="v12"] .hero-proof-card { + padding: 0.6rem; + } + + :root[data-da-variant="v12"] .hero-secondary-actions, + :root[data-da-variant="v12"] .figma-lab-cta-row, + :root[data-da-variant="v12"] .project-reference-actions, + :root[data-da-variant="v12"] .dual-cta-actions { + flex-direction: column; + align-items: stretch; + width: 100%; + gap: 0.52rem; + } + + :root[data-da-variant="v12"] .figma-lab-pill, + :root[data-da-variant="v12"] .hero-inline-link, + :root[data-da-variant="v12"] .project-reference-more, + :root[data-da-variant="v12"] .graphic-sprints-cta, + :root[data-da-variant="v12"] .dual-cta-btn { + width: 100%; + } + + :root[data-da-variant="v12"] .site-footer { + padding-inline: 0.85rem; + } + + :root[data-da-variant="v12"] .hero-panel-head { + flex-direction: column; + align-items: stretch; + gap: 0.7rem; + } + + :root[data-da-variant="v12"] .hero-status-stack { + justify-items: center; + } + + :root[data-da-variant="v12"] .hero-side-panel { + min-height: auto; + padding: 0.85rem; + } + + :root[data-da-variant="v12"] .figma-lab-map-intro, + :root[data-da-variant="v12"] .graphic-sprints-panel, + :root[data-da-variant="v12"] .projects-timeline-content, + :root[data-da-variant="v12"] .project-case-card, + :root[data-da-variant="v12"] .flow-narrative-card { + padding: 0.85rem; + } + + :root[data-da-variant="v12"] .figma-lab-map-card { + min-height: auto; + padding: 0.85rem 0.85rem 0.9rem; + } + + :root[data-da-variant="v12"] .figma-lab-map-title { + font-size: 1.22rem; + } + + :root[data-da-variant="v12"] .section-anchor h2 { + font-size: clamp(1.55rem, 8vw, 2rem); + line-height: 0.96; + } + + :root[data-da-variant="v12"] .section-anchor h3 { + font-size: 1.14rem; + } + + :root[data-da-variant="v12"] .hero-side-metrics div { + grid-template-columns: 1fr; + } + + :root[data-da-variant="v12"] .flow-narrative-copy { + text-align: left; + } + + :root[data-da-variant="v12"] .contact-draft-head, + :root[data-da-variant="v12"] .contact-draft-actions { + flex-direction: column; + align-items: stretch; + } + +} + +:root[data-da-variant="v12"] .structure-grid, +:root[data-da-variant="v12"] .structure-grid--hero, +:root[data-da-variant="v12"] .structure-grid--sprints, +:root[data-da-variant="v12"] .structure-grid--systems, +:root[data-da-variant="v12"] .structure-grid--production, +:root[data-da-variant="v12"] .structure-grid--conversion, +:root[data-da-variant="v12"] .footer-grid, +:root[data-da-variant="v12"] .figma-lab-hero-grid, +:root[data-da-variant="v12"] .figma-lab-bottom-grid, +:root[data-da-variant="v12"] .hero-proof-grid, +:root[data-da-variant="v12"] .graphic-sprints-grid, +:root[data-da-variant="v12"] .system-pipeline, +:root[data-da-variant="v12"] .lab-notes-grid, +:root[data-da-variant="v12"] .trust-strip, +:root[data-da-variant="v12"] .contact-signal-grid, +:root[data-da-variant="v12"] .project-reference-list, +:root[data-da-variant="v12"] .dual-cta-actions, +:root[data-da-variant="v12"] .lab-note-flow, +:root[data-da-variant="v12"] .projects-timeline-item, +:root[data-da-variant="v12"] .flow-diagram { + grid-template-columns: 1fr !important; +} + +:root[data-da-variant="v12"] .footer-grid--enhanced { + grid-template-columns: 1fr !important; +} + +:root[data-da-variant="v12"] .footer-links--single-rail { + display: flex !important; + flex-wrap: wrap !important; +} + +:root[data-da-variant="v12"] .flow-edge { + min-height: 1.2rem !important; + align-self: auto !important; + display: flex !important; + justify-content: center; + align-items: center; + position: relative; +} + +:root[data-da-variant="v12"] .flow-edge:before { + background: linear-gradient(#0000, #ffffff94, #0000) !important; + width: 2px !important; + height: 100% !important; + margin: 0 !important; + animation: none !important; +} + +:root[data-da-variant="v12"] .flow-edge:after { + border-width: 0.35rem 0.42rem !important; + border-top-color: var(--electric) !important; + border-bottom-color: #0000 !important; + border-left-color: #0000 !important; + border-right-color: #0000 !important; + position: absolute !important; + inset: auto auto 0.1rem 50% !important; + transform: translate(-50%) !important; + margin-left: 0 !important; +} -- 2.52.0 From 4a1d3a2c18c6159b0a9e9737713f3ff911329660 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20SAILLANT?= <108685187+electron-rare@users.noreply.github.com> Date: Sat, 14 Mar 2026 17:32:27 +0000 Subject: [PATCH 05/31] Switch Electron Rare to white-contrast default --- docs/EXECUTION-IMMÉDIATE-2026-03-02.md | 182 ++---- docs/SPRINT-PLAYBOOK-2026-03-02.md | 589 +++--------------- docs/da-01-implementation-backlog.md | 270 ++++---- ...design-memory-2026-03-14-white-contrast.md | 53 ++ docs/project-master-todos.md | 118 ++-- src/components/sections/CaseStudies.tsx | 2 +- src/components/sections/Faq.astro | 2 +- src/layouts/BaseLayout.astro | 9 +- src/lib/site.ts | 3 +- src/styles/global.css | 166 +++++ src/styles/home-workbench.css | 301 ++++++++- 11 files changed, 812 insertions(+), 883 deletions(-) create mode 100644 docs/design-memory-2026-03-14-white-contrast.md diff --git a/docs/EXECUTION-IMMÉDIATE-2026-03-02.md b/docs/EXECUTION-IMMÉDIATE-2026-03-02.md index c175117..4f8dd4b 100644 --- a/docs/EXECUTION-IMMÉDIATE-2026-03-02.md +++ b/docs/EXECUTION-IMMÉDIATE-2026-03-02.md @@ -1,141 +1,65 @@ -# EXECUTIVE SUMMARY — Actions à faire immédiatement +# EXECUTION IMMEDIATE - White Contrast Rollout -**Date** : 2 mars 2026 -**Sévérité** : 🔴 CRITIQUE — Impact direct sur conversion -**Effort estimé** : 48-72h pour P0/P1 +Updated: 2026-03-14 +Severite: critique pour coherence visuelle et lisibilite ---- +## 3 actions prioritaires -## 🎯 3 ACTIONS PRIORITAIRES (Ce week-end) +### 1. Basculer tout le site sur une DA blanche par defaut +Probleme: +- la home synchronisee OVH est la bonne base, mais une partie du CSS reste encore oriente sombre +- le runtime pointait encore vers `data-theme="default"` -### **1️⃣ Optimiser images hero — GAIN IMMÉDIAT +30-40% CONVERSION** +Action: +- passer le layout sur un theme clair par defaut +- reposer les surfaces principales sur blanc/ivoire +- reprendre les accents en teal/rust +- traiter explicitement les ilots a risque: + - hero photo + - photo strip + - video strip + - `contact-minitel` + - FAQ focus -**Problème** : -- Image hero = **6.4 MB** (3.1 MB + 2.3 MB) -- LCP actuel : **~3.5 secondes** -- Mobile users : **40%+ bounce avant voir CTA** +Fichiers cle: +- `src/layouts/BaseLayout.astro` +- `src/lib/site.ts` +- `src/styles/global.css` +- `src/styles/home-workbench.css` -**Solution** (3-4h) : +### 2. Rebuilder et verifier le preview OVH +Action: +- builder la variante preview avec le bon `PUBLIC_SITE_URL` +- verifier que tous les liens et assets sortent en `/preview/` +- publier sur OVH seulement apres build propre + +Commande de base: ```bash -# 1. Installer convertisseur -brew install imagemagick webp - -# 2. Convertir 2 images hero en AVIF (meilleur ratio) -# hero-pcb-routing-map.png 3.1 MB → 160 KB AVIF -# proof-prototype-bench.png 2.3 MB → 140 KB AVIF - -# 3. Ajouter responsive srcset -# → Servir 390px/768px/1440px différentes - -# 4. Lazy-load secondary image -# → Primary eager = LCP, Secondary lazy +cd /home/zacus/electron-rare-preview-ovh +PUBLIC_SITE_URL=https://www.lelectronrare.fr/preview/ npm run build:external ``` -**Résultat** : -- LCP : 3.5s → **<700ms** ✅ -- Conversion : +35-45% (mobile stops bounce) -- Page weight : 6.4 MB → **350 KB hero** +### 3. Revalider la production actuelle apres preview +Action: +- tester les pages et ancres reelles du site +- verifier la suppression du contraste sombre sur les surfaces critiques +- confirmer tracking et meta minimums -**Files à toucher** : -- [index.html](index.html#L197-L208) -- [script.js](script.js#L5-95) -- `/public/assets/da/openai/*.png` (convert to AVIF/WebP) +Routes a verifier: +- `/` +- `/formation/` +- `/mentions-legales/` +- `/lab/` +- `/robots.txt` +- `/sitemap.xml` ---- +## Cible de sortie +- theme blanc contraste par defaut +- contact lisible et clavier-friendly +- preview valide avant push prod +- docs alignees sur Astro + OVH + GitHub Actions FTP -### **2️⃣ Fixer typecheck CI — Éviter futur blocage** - -**Problème** : -- `npm run typecheck` échoue -- Risque bloquer CI dans 2-3 sprints - -**Solution** (1h) : -```bash -# Modifier tsconfig.json : -# Ajouter "exclude": ["tmp/**", "node_modules"] - -# Test : -npm run typecheck # ✅ doit passer -``` - -**Files** : [tsconfig.json](tsconfig.json) - ---- - -### **3️⃣ Valider GA4 Realtime — Confirmer acquisition fonctionne** - -**Problème** : -- Tracking implémenté mais **non validé en production** -- Risque conversion non mesurée - -**Solution** (1h) : -```bash -# 1. Ouvrir GA4 DebugView -# https://analytics.google.com/ → Admin → GTM-5SLM67QF - -# 2. Tester events live : -# - Visit https://electron-rare.github.io -# - Click CTA (Projets, Contact, LinkedIn) -# - Verify events appear en Realtime ✅ - -# 3. Archive : screenshot DebugView + events log -``` - ---- - -## 📊 IMPACT RÉSUMÉ - -| Action | Complexité | Impact | Timeline | -|--------|-----------|--------|----------| -| **Images AVIF** | ⭐⭐ | +35% conversion | 4h | -| **Figures responsive** | ⭐⭐⭐ | +15% mobile UX | 2h | -| **typecheck fix** | ⭐ | Risk mitigation | 1h | -| **GA4 validation** | ⭐ | Measurement trust | 1h | -| **Deploy + test** | ⭐⭐ | Verification | 2h | -| **TOTAL** | | **+50% overall UX** | **10h = 1.25 jours** | - ---- - -## 🚀 EXÉCUTION PROPOSÉE - -**Vendredi 2026-03-05** (finish line) : -- [ ] 09:00 : images conversion start -- [ ] 11:00 : HTML/script.js edits -- [ ] 13:00 : typecheck fix + test build -- [ ] 15:00 : GA4 validation + screenshot -- [ ] 16:30 : deploy + Lighthouse verify -- [ ] 17:30 : archive evidence + commit - -**Aftermath** : -- Week-end : monitor GA4 Realtime data -- Lundi : Lighthouse >85, LCP <2.5s validation - ---- - -## 💡 PROCHAINE ÉTAPE (Semaine 2) - -**Si images réussies (expected) :** -1. SEO enrichissement (JSON-LD WebSite, Organization) -2. GSC property claim + sitemap submit -3. Monitor indexation (7 jours) - -**Si complications** : -1. Revert images → fallback PNG optimisé (moins idéal mais rapide) -2. Continue sans AVIF (WebP+PNG suffisant) - ---- - -## 📞 SUPPORT TOOLS - -**Image conversion online** (backup) : -- https://cloudconvert.com/png-to-avif -- https://squoosh.app/ (Google, local) - -**Validation** : -- Lighthouse : Chrome DevTools F12 -- GA4 : https://analytics.google.com -- Schema : https://search.google.com/test/rich-results - ---- - -**Questions ?** → Lire [docs/audit-plan-amelioration-2026-03-02.md](audit-plan-amelioration-2026-03-02.md) pour détails complets. +## Regles +- ne plus documenter `index.html`, `script.js`, ou GitHub Pages root files comme source de prod +- ne plus parler de `#projets`, Malt, ou du bouton contraste +- ne plus relancer l'ancienne DA `studio/figma` diff --git a/docs/SPRINT-PLAYBOOK-2026-03-02.md b/docs/SPRINT-PLAYBOOK-2026-03-02.md index 5b32d2c..9c57592 100644 --- a/docs/SPRINT-PLAYBOOK-2026-03-02.md +++ b/docs/SPRINT-PLAYBOOK-2026-03-02.md @@ -1,543 +1,98 @@ -# SPRINT PLAYBOOK — Commands & Checklists +# Sprint Playbook - White Contrast / Preview / Prod -**Updated** : 2026-03-02 +Updated: 2026-03-14 +Repo: `/home/zacus/electron-rare-preview-ovh` ---- +## Sprint A - Theme clair -## SPRINT A — Performance (48-72h) - -### A1 — Image Conversion AVIF/WebP - -**Setup environment** : -```bash -cd /Users/cils/Documents/Lelectron_rare/electron-rare.github.io - -# Check tools disponibles -which convert # ImageMagick -which cwebp # WebP encoder - -# Si manquant : -brew install imagemagick libwebp -``` - -**Target images** : -```bash -# Collection des 2 images hero principales (v12 baseline) -SOURCE_PRIMARY="/public/assets/da/openai/hero-pcb-routing-map.png" -SOURCE_SECONDARY="/public/assets/da/openai/proof-prototype-bench.png" - -# Vérifier tailles actuelles -du -h "$SOURCE_PRIMARY" "$SOURCE_SECONDARY" -# Expected: 3.1 MB + 2.3 MB = 6.4 MB total - -# Créer répertoire optimisé -mkdir -p public/assets/da/openai/optimized -``` - -**Conversion AVIF** (best compression) : -```bash -# Primary image -convert "${SOURCE_PRIMARY}" \ - -quality 80 \ - -define webp:method=6 \ - -strip \ - "public/assets/da/openai/optimized/hero-pcb-routing-map.avif" - -# Secondary image -convert "${SOURCE_SECONDARY}" \ - -quality 80 \ - -define webp:method=6 \ - -strip \ - "public/assets/da/openai/optimized/proof-prototype-bench.avif" - -# Vérifier résultat -du -h public/assets/da/openai/optimized/*.avif -# Target: 150-180 KB each -``` - -**Conversion WebP** (fallback browser support) : -```bash -# Primary -> WebP -cwebp -q 85 "${SOURCE_PRIMARY}" \ - -o "public/assets/da/openai/optimized/hero-pcb-routing-map.webp" - -# Secondary -> WebP -cwebp -q 85 "${SOURCE_SECONDARY}" \ - -o "public/assets/da/openai/optimized/proof-prototype-bench.webp" - -# Verify -du -h public/assets/da/openai/optimized/*.webp -# Target: 200-250 KB each -``` - -**Comparaison avant/après** : -```bash -# Create comparison log -cat > artifacts/optimization-log-2026-03-02.txt << 'EOF' -IMAGE OPTIMIZATION SUMMARY -========================== - -Primary (hero-pcb-routing-map) : - Before: 3.1 MB PNG - After: - - 160 KB AVIF (-95%) - - 220 KB WebP (-93%) - - 3.1 MB PNG (fallback) - -Secondary (proof-prototype-bench) : - Before: 2.3 MB PNG - After: - - 140 KB AVIF (-94%) - - 190 KB WebP (-92%) - - 2.3 MB PNG (fallback) - -Total hero payload : - Before: 6.4 MB - After: 350 KB (AVIF primary) - Gain: -95% or 6.05 MB saved -EOF - -cat artifacts/optimization-log-2026-03-02.txt -``` - ---- - -### A2 — HTML Picture Element avec srcset - -**Edit [index.html](index.html)** → Find & replace hero images : - -**Before** (lines 197-208) : -```html -
- Plan de routage PCB avec traces et vias -
- - -
- Banc de test prototype avec instruments -
-``` - -**After** (with picture + srcset) : -```html - -
- - - - - - - - - Plan de routage PCB avec traces et vias - -
Routage PCB — voie signal, couche, décisions
-
- - -
- - - - - - - - - Prototype validé — preuve terrain et tests - -
Test de stabilité — responsiveness et fiabilité
-
-``` - -**Update [script.js](script.js)** → Ajuster paths dynaxmiques pour variants : - -```javascript -// line 5-95 : heroAssetByVariant object -// Add responsive paths for each variant : - -var heroAssetByVariant = { - v1: { - primary: { - avif: '/assets/da/openai/optimized/hero-pcb-routing-map.avif', - webp: '/assets/da/openai/optimized/hero-pcb-routing-map.webp', - png: '/assets/da/openai/hero-pcb-routing-map.png' - }, - secondary: { - avif: '/assets/da/openai/optimized/hero-measurement-rig.avif', - webp: '/assets/da/openai/optimized/hero-measurement-rig.webp', - png: '/assets/da/openai/hero-measurement-rig.png' - }, - // ... etc for v2-v12 - } -}; - -// Update img src setting logic: -if (heroPrimaryImage) { - // Fallback to PNG for old browsers (script.js sets primary src) - heroPrimaryImage.src = heroAssets.primary.png || heroAssets.primary; -} -``` - ---- - -### A3 — Responsive Image Variants - -**Generate 3 sizes per image** (390px, 768px, 1440px) : - -```bash -#!/bin/bash -# scripts/generate-responsive-images.sh - -SOURCES=( - "public/assets/da/openai/optimized/hero-pcb-routing-map" - "public/assets/da/openai/optimized/proof-prototype-bench" -) - -SIZES=(390 768 1440) - -for source in "${SOURCES[@]}"; do - base=$(basename "$source" .avif) - - for size in "${SIZES[@]}"; do - # AVIF variant - convert "${source}.png" \ - -resize "${size}x" \ - -quality 80 \ - "${source}-${size}.avif" - - # WebP variant - cwebp -q 85 \ - -resize "${size}" \ - "${source}.png" \ - -o "${source}-${size}.webp" - done -done - -echo "✅ Responsive variants generated" -du -h public/assets/da/openai/optimized/*-*.avif -``` - -**Run** : -```bash -bash scripts/generate-responsive-images.sh -``` - ---- - -### A4 — Test Locally - -```bash -# Build project -npm run build:external - -# Open locally -open dist/index.html -# or -npx http-server dist -p 8000 - -# Test Lighthouse Performance -# Chrome DevTools → Lighthouse → Measure page load -# Expected: Performance >85, LCP <800ms -``` - -**Capture** : -```bash -# Screenshot Lighthouse mobile report -# Save to artifacts/performance/lh-mobile-after.html -``` - ---- - -### A5 — Image Budget CI - -**Enhance [scripts/check-image-budget.mjs](scripts/check-image-budget.mjs)** : - -```javascript -// Add size limits check -const LIMITS = { - 'hero-pcb-routing-map.avif': 180_000, // 180 KB - 'hero-pcb-routing-map.webp': 250_000, // 250 KB - 'proof-prototype-bench.avif': 160_000, // 160 KB - 'proof-prototype-bench.webp': 230_000, // 230 KB -}; - -// Fail build if limits exceeded -Object.entries(LIMITS).forEach(([file, limit]) => { - const actual = fs.statSync(`public/assets/da/openai/optimized/${file}`).size; - if (actual > limit) { - console.error(`❌ ${file}: ${actual} > ${limit}`); - process.exit(1); - } -}); - -console.log('✅ All images within budget'); -``` - -**Test** : -```bash -npm run image:budget -# Expected: ✅ pass -``` - ---- - -## SPRINT B — SEO & QA - -### B1 — Fix typecheck - -**Edit [tsconfig.json](tsconfig.json)** : - -```json -{ - "extends": "astro/tsconfigs/strict", - "exclude": [ - "tmp/**", - "node_modules", - "dist/**", - ".astro/**" - ] -} -``` - -**Test** : +### A1 - Checks locaux ```bash +cd /home/zacus/electron-rare-preview-ovh +git status --short --branch npm run typecheck -# Expected: ✅ pass (0 errors) +npm run tracking:check +PUBLIC_SITE_URL=https://www.lelectronrare.fr/preview/ npm run build:external ``` ---- +### A2 - Zones a verifier dans le build +- nav et hero +- approche et cas concrets +- photo strip et video strip +- formats de mission +- FAQ +- contact `minitel` clair +- footer +- pages `/formation/` et `/mentions-legales/` -### B2 — GA4 Realtime Validation +### A3 - Points d'attention +- pas de `Mode contraste` +- pas de retour a l'ancienne DA sombre +- pas d'ancre legacy `#projets` +- focus visible sur FAQ et formulaire -**Checklist** : -- [ ] Open https://electron-rare.github.io/ in browser -- [ ] Open DevTools → Console -- [ ] Execute : - ```javascript - console.log(window.dataLayer); - // Should show GTM events - ``` -- [ ] Navigate to GA4 DebugView - - [ ] https://analytics.google.com/ - - [ ] Admin → GTM account → Container - - [ ] Preview mode ON (blue banner) -- [ ] Click CTA buttons on site → Events appear in DebugView -- [ ] Take screenshot evidence +## Sprint B - Preview OVH -**Expected events** : -``` -✅ page_view (auto) -✅ cta_hero_projets (click "#projets" button) -✅ cta_hero_contact (click "#contact" button) -✅ cta_hero_profile (click LinkedIn button) -✅ outbound_linkedin_contact (if click external) -``` - -**Archive evidence** : +### B1 - Build preview ```bash -mkdir -p artifacts/tracking/2026-03-02 -# Save DebugView screenshot to: -# artifacts/tracking/2026-03-02/ga4-debugview.png +cd /home/zacus/electron-rare-preview-ovh +PUBLIC_SITE_URL=https://www.lelectronrare.fr/preview/ npm run build:external ``` ---- - -### B3 — Deploy & Verify +### B2 - Deploy preview +- workflow GitHub Actions: `deploy-ovh-ftp.yml` +- target: `preview` +- remote attendu: `/www/preview` +### B3 - Verification preview ```bash -# Full flow -npm run build:external - -# Test local first -npm run preview - -# Deploy to OVH (if ready) -npm run deploy:web:sftp - -# Verify live -open https://electron-rare.github.io/ - -# Lighthouse final check -# Chrome DevTools → Run Lighthouse -# Measure → Full page audit +curl -fsSI https://www.lelectronrare.fr/preview/ +curl -fsSI https://www.lelectronrare.fr/preview/formation/ +curl -fsSI https://www.lelectronrare.fr/preview/mentions-legales/ ``` -**Expected results** : -``` -Performance: >85 (was <60) -LCP: <800ms (was 3.5s) -CLS: <0.1 -``` +## Sprint C - Production ---- +### C1 - Preconditions +- preview valide visuellement +- build propre +- pas de regression tracking evidente -## SPRINT C — SEO & Long-term - -### C1 — Google Search Console - -**Setup** : -1. Go to https://search.google.com/search-console -2. Select "URL prefix" → https://electron-rare.github.io/ -3. Verify ownership (HTML meta tag or file upload) -4. Add sitemap → /sitemap.xml -5. Request indexation for: - - `/` - - `/lab/` - -**Monitoring** (daily for 7-14 days) : -- Coverage report → no errors -- Indexation status → target 100% -- Mobile usability → no errors - ---- - -### C2 — Create Lighthouse Baseline Report +### C2 - Deploy production +- workflow GitHub Actions: `deploy-ovh-ftp.yml` +- target: `production` +- remote attendu: `/www` +### C3 - Verification production ```bash -# Generate and save baseline -npm run build - -# Install lighthouse globally (if needed) -npm install -g lighthouse - -# Run reports -lighthouse https://electron-rare.github.io/ \ - --output=html \ - --output-path=artifacts/audit-2026-03-02/lh-mobile-final.html \ - --preset=mobile - -lighthouse https://electron-rare.github.io/ \ - --output=html \ - --output-path=artifacts/audit-2026-03-02/lh-desktop-final.html \ - --preset=desktop - -# View results -open artifacts/audit-2026-03-02/lh-mobile-final.html +curl -fsSI https://www.lelectronrare.fr/ +curl -fsSI https://www.lelectronrare.fr/formation/ +curl -fsSI https://www.lelectronrare.fr/mentions-legales/ +curl -fsSI https://www.lelectronrare.fr/robots.txt +curl -fsSI https://www.lelectronrare.fr/sitemap.xml ``` ---- +## Sprint D - Tracking / SEO -## POST-DEPLOYMENT CHECKLIST +### D1 - Events a verifier +- `cta_hero_contact` +- `outbound_linkedin_contact` +- `outbound_email_contact` +- `outbound_github_contact` +- `cta_lab_interactif_open` +- `experiment_variant_exposed` +- `engagement_scroll_depth` +- `engagement_section_view` +- `cwv_metric` -```bash -# 1. Full test suite -npm run build:external # ✅ Build passes -npm run tracking:check # ✅ Tracking OK -npm run image:budget # ✅ Budget OK -npm run preflight:pages # ✅ Preflight OK -npm run typecheck # ✅ Types OK +### D2 - Pages/meta a verifier +- canonical +- robots +- sitemap +- OG/Twitter +- `theme-color` -# 2. Live verification -curl -I https://electron-rare.github.io/ -# Expected: HTTP 200 - -# 3. Lighthouse mobile -open https://electron-rare.github.io/ -# DevTools F12 → Lighthouse → Run -# Expected: Performance >85, LCP <800ms - -# 4. GA4 Realtime check -# https://analytics.google.com/ -# DebugView should show live events - -# 5. Archive evidence -mkdir -p artifacts/deployment-2026-03-02 -# Save screenshots & reports - -# 6. Final commit -git add . -git commit -m "perf: hero image optimization (AVIF/WebP, responsive srcset)" -git push origin main - -# 7. Verify deployment -# Wait 2-3 min for GitHub Pages -open https://electron-rare.github.io/ -# Verify rendered correctly -``` - ---- - -## COMMON TROUBLESHOOTING - -### Image conversion fails -**Solution** : -```bash -brew uninstall imagemagick -brew install imagemagick@7 -export PATH="/usr/local/opt/imagemagick@7/bin:$PATH" -``` - -### AVIF too large (>200 KB) -**Solution** : Reduce quality or pre-compress PNG : -```bash -# Reduce PNG first -pngquant 256 hero.png -o hero-256.png -# Then convert to AVIF with lower quality (70 instead of 80) -convert hero-256.png -quality 70 hero.avif -``` - -### Build error with Astro -**Solution** : -```bash -rm -rf node_modules dist .astro -npm ci -npm run build:external -``` - -### GA4 events not appearing -**Solution** : -```javascript -// Check DataLayer in console -window.dataLayer - -// Should show GTM events -// If empty: GTM script may not be loaded -// Check: GTM-5SLM67QF ID is correct in index.html -``` - ---- - -**For detailed context, see** : -[docs/audit-plan-amelioration-2026-03-02.md](audit-plan-amelioration-2026-03-02.md) +## Definition de done +- preview publie et valide +- prod publiee et validee +- theme blanc contraste par defaut confirme en live +- docs alignees sur Astro/OVH actuel diff --git a/docs/da-01-implementation-backlog.md b/docs/da-01-implementation-backlog.md index 79062c2..30e0f9c 100644 --- a/docs/da-01-implementation-backlog.md +++ b/docs/da-01-implementation-backlog.md @@ -1,191 +1,141 @@ -# Backlog DA-01 — Decision Complet +# Backlog DA-01 - White Contrast Consolidation -Date: 2026-03-02 -Source: Sprint DA-00 (brief + wireflow conversion) +Updated: 2026-03-14 +Source: homepage Astro synchronisee avec la base OVH ## Objectif -Implémenter la refonte complète selon le wireflow validé, sans modifier les contrats publics (anchors core, tracking, SEO). +Consolider la DA actuelle en version claire, contraste blanc, sans reintroduire l'ancienne variante `studio/figma` ni le vieux modele GitHub Pages statique. -## Etat d'avancement DA (2026-03-02) -- [x] Mapping section/composants finalisé en phase de refonte. -- [x] DA-00 intégré: structure Header/Hero/Systems/Production/Conversion/Footer et zones mobiles définies. -- [x] Contrat tokens/typographie/couleurs maintenu dans `src/styles/global.css`. -- [x] Validation finale pré-production en cours (preflight + checks build locaux + captures Figma consolidées). -- [ ] Plan de version web hors GitHub réservé (build Astro externe) en attente de besoin produit. -- [ ] Revue de dérive visuelle et conversion à refaire sur chaque release majeure. +## Sources de verite +- Structure homepage: `src/pages/index.astro` +- Sections actives: `Hero`, `About`, `CaseStudies`, `GraphicSprints`, `Faq`, `Contact` +- Copy et donnees: `src/content/home-content.ts` +- Theme et layout: `src/layouts/BaseLayout.astro`, `src/styles/global.css`, `src/styles/home-workbench.css` +- Tracking: `src/lib/tracking.ts` + `src/layouts/BaseLayout.astro` +- Deploiement: `docs/ovh-ftp-preview-solution-2026-03-14.md` -## 1) Mapping section -> composants +## Decisions DA +- Theme par defaut: `high-contrast` clair, oriente blanc/ivoire. +- Palette de travail: + - fonds `#ffffff`, `#faf7f2`, `#f5efe4` + - texte `#0b0a09`, `#2f2a25` + - accent froid `#0b5d65` + - accent chaud `#7f4a23` +- Bouton contraste: non expose au public. Pas de toggle tant qu'il n'existe pas comme fonctionnalite produit reelle. +- Rendition souhaitee: + - surfaces blanches nettes + - contraste fort mais pas clinique + - traces teal/rust en accent, pas en fond systematique + - motion reduite et discrète -1. `Header_ControlRoom` +## Mapping section -> composants reels +1. `Header_Navigation` - Cible: `src/pages/index.astro` + `src/layouts/BaseLayout.astro` -- Eléments: - - nav niveau 1 (labels libres) - - bus posture (niveau 2) - - status + contrast toggle +- Elements: + - marque + - nav anchors + - acces direct formation, lab, FAQ, contact -2. `Hero_Impact` +2. `Hero_Conversion` - Cible: `src/components/sections/Hero.tsx` -- Eléments: - - hook visuel - - manifeste 3 lignes - - CTA dual rail +- Elements: + - promesse + - statut/disponibilite + - CTA contact + - fond photo + lockup -3. `Identity_Proof` -- Cible: `src/components/sections/IdentityLab.tsx` + `TrustStrip.tsx` -- Eléments: - - identité studio - - preuves rapides +3. `About_Approche` +- Cible: `src/components/sections/About.tsx` +- Elements: + - portrait + - expertise + - secteurs + - chips d'offres / familles de sujets -4. `Systems_Block` -- Cible: `FlowDiagram.tsx` + `SystemPipeline.tsx` + `About.tsx` -- Eléments: - - explication process - - architecture systeme +4. `Cases_Proof` +- Cible: `src/components/sections/CaseStudies.tsx` +- Elements: + - cas concrets + - preuve de terrain + - articulation industrie / culture / produit -5. `Production_Block` -- Cible: `Projects.tsx` + `ProjectsTimeline.tsx` + `LabNotes.tsx` -- Eléments: - - portfolio systemique - - chronologie - - protocole Intent->Result - -6. `Conversion_Block` -- Cible: `TrustStrip.tsx` + `Contact.tsx` -- Eléments: - - reassurance - - contact 2 voies (LinkedIn/Malt) - -7. `Footer_Knowledge` +5. `Field_Media` - Cible: `src/pages/index.astro` + `src/styles/global.css` -- Eléments: - - liens process/stack/contact +- Elements: + - photo strip + - video strip -## 2) Mapping token -> CSS var +6. `Mission_Formats` +- Cible: `src/components/sections/GraphicSprints.tsx` +- Elements: + - 3 formats + - progression + - CTA de contact -Fichier cible: `src/styles/global.css` +7. `Faq_Trust` +- Cible: `src/components/sections/Faq.astro` +- Elements: + - details/summary + - reponse rapide aux objections -### Palette -- `--bg`, `--bg-elevated`, `--surface`, `--surface-soft`, `--surface-alt` -- `--trace-cyan`, `--trace-magenta`, `--trace-green`, `--trace-amber` -- `--electric`, `--accent`, `--signal` -- `--line`, `--line-soft`, `--line-edge`, `--line-rail` +8. `Contact_ClearTerminal` +- Cible: `src/components/sections/Contact.astro` +- Elements: + - bloc contact type minitel mais en rendition claire + - email draft + - formulaire direct + - LinkedIn -### Typographie -- display serif editorial -- body sans -- micro labels mono +9. `Footer_Knowledge` +- Cible: `src/pages/index.astro` +- Elements: + - navigation secondaire + - ressources + - contact direct -### Layout -- `site-shell` largeur max desktop -- grilles desktop/mobile (1440/390) -- rules sections `structure-grid` / `structure-cell` +## Backlog P0 +- [ ] Forcer la cascade sur la DA blanche dans `BaseLayout.astro`, `site.ts`, `global.css`, `home-workbench.css`. +- [ ] Relever les derniers blocs sombres restants: `hero-bg-photo`, `photo-strip`, `video-strip`, `contact-minitel`, FAQ focus. +- [ ] Verifier la lisibilite des CTA sur blanc. +- [ ] Verifier que la home et `formation` partagent bien le meme socle visuel. -## 3) Mapping interaction -> motion rule +## Backlog P1 +- [ ] Supprimer les references documentaires a `#projets`, Malt, GitHub Pages static prod, dual-rail hero, contrast toggle. +- [ ] Verifier les events `data-track` sur les CTA actifs uniquement. +- [ ] Valider preview OVH puis prod. -### Navigation -- progress line header -- etat actif sur section visible -- micro-jitter actif uniquement sur lien actif - -### Sections -- reveal par bloc (opacity + translateY) -- cadence differenciee par bloc (Hero > Systems > Conversion) - -### CTA -- etat hover/focus/active explicite -- primaire > secondaire visuellement - -### Accessibilite motion -- `prefers-reduced-motion`: desactiver animations non essentielles - -## 4) Interfaces internes a standardiser - -### CTA contract -Type logique: -- `label: string` -- `href: string` -- `event: TrackEventName` -- `destination: string` -- `external?: boolean` - -Usage: -- Hero, About, Projects, Contact, Trust utilisent le meme contrat. - -### Proof card contract -Type logique: -- `label: string` -- `value: string` -- `priority?: "high" | "medium"` - -### Timeline/LabNotes contract -Type logique: -- `date/year` -- `title` -- `category` -- `summary` -- `href/event/destination` optionnels - -## 5) Gates de validation DA-01 +## Backlog P2 +- [ ] Supprimer les reliquats `.site-contrast-toggle` du CSS global. +- [ ] Evaluer si un vrai theme secondaire doit exister plus tard ou si le mode blanc reste la seule version publique. +- [ ] Consolider une archive explicite des anciens artefacts DA pour eviter toute reintroduction. +## Gates de validation ### Gate Build - `npm run typecheck` -- `npm run build` -- `npm run preflight:pages` +- `npm run build:external` - `npm run tracking:check` ### Gate UX -- ancres `#a-propos`, `#projets`, `#contact` fonctionnelles -- CTA primary/secondary lisibles -- mobile 390 sans overflow -- validation 390/768/1024/1440 conservée dans evidence - -### Gate Tracking -- events declenches sans duplication -- params `event_category/event_label/destination` conformes +- Aucun panneau critique ne reste sur fond sombre. +- Mobile 390/768 sans debordement. +- CTA primary/secondary lisibles sur fond clair. +- Contact completement utilisable. ### Gate Accessibilite -- focus visible -- ordre tab coherent -- reduced-motion OK +- Focus visible sur nav, FAQ, CTA, formulaire. +- Contraste texte/fond conforme sur les composants critiques. +- `prefers-reduced-motion` conserve. -### Gate SEO -- robots/sitemap accessibles -- canonical + OG/Twitter presents +### Gate Tracking +- Aucun event legacy mort. +- Clics hero/contact/lab/linkedin/email visibles dans la dataLayer. -## 6) Ordre d’implementation recommande +### Gate Deploy +- Preview OK avant production. +- Verification live des URL et ancres. -### P0 -1. Recomposer la structure de `src/pages/index.astro` -2. Harmoniser tokens/layout de `src/styles/global.css` -3. Verifier ancres core + tracking - -### P1 -1. Harmoniser les sections (Hero, Systems, Production, Conversion) -2. Finaliser footer knowledge/protocoles -3. QA responsive + accessibilite - -### P2 -1. Storybook coverage structure + sections -2. Optimisation bundle/motion - -## 7) Risques et parades - -1. Risque: surcharge visuelle -- Parade: matrice arbitrage DA vs conversion appliquee - -2. Risque: regression tracking -- Parade: tests manuels click-by-click + check dataLayer - -3. Risque: degrade mobile -- Parade: validation systematique 390/768/1024/1440 - -## 8) Version duale (prod immédiate + web hors GitHub) -- Production immédiate: GitHub Pages conserve la version `index.html/styles.css/script.js` pour stabilité. -- Version web hors GitHub: build Astro `dist/` prévu comme variante de long terme (non déployé pour le moment). -- Règle: aucun changement d'UI ne doit diverger sans mise à jour explicite des 2 cahiers de preuve (scope statique + scope web externe). - -## 9) Definition of done DA-01 -1. Structure cible implementee en code. -2. DA conforme au brief v2.2.0 (reset innovant). -3. Contrats publics preserves. -4. Tests passes et evidence mise a jour. +## Definition of done +1. Le site public sert par defaut une version blanc contraste coherente. +2. Aucun element critique de l'ancienne DA sombre ne reste visible. +3. Les docs actives parlent du vrai site OVH/Astro actuel. +4. Preview et production sont verifiees sur cette base. diff --git a/docs/design-memory-2026-03-14-white-contrast.md b/docs/design-memory-2026-03-14-white-contrast.md new file mode 100644 index 0000000..3a5d336 --- /dev/null +++ b/docs/design-memory-2026-03-14-white-contrast.md @@ -0,0 +1,53 @@ +# Design Memory - White Contrast Baseline + +Date: 2026-03-14 +Status: active + +## Decision +La version publique de L'Electron Rare repart sur une base claire, contraste blanc, par defaut. + +## Pourquoi +- la homepage OVH synchronisee est la bonne base produit +- l'ancienne DA sombre et experimentale brouillait la lisibilite +- le site doit inspirer precision, methode et confiance avant de projeter un univers +- l'accessibilite et la lecture rapide gagnent avec des surfaces claires et des accents plus disciplinés + +## Regles visuelles +- fonds: blanc, ivoire, creme tres legere +- texte principal: noir chaud / brun tres fonce +- accent froid: teal technique +- accent chaud: cuivre / brun signal +- panneaux: clairs, nets, ombres courtes +- pas de halo neon comme logique dominante +- pas de glitch ou scanline comme effet de signature principal + +## Ce qui reste autorise +- texture subtile de trame ou de grille +- references bench / signal / PCB en couche legere +- typography mono sur certains labels et statuts +- accents rust/teal sur CTA, badges, progression et reperes + +## Ce qui est interdit +- retour a la home `studio/figma` +- bouton contraste sans vraie fonctionnalite produit +- docs qui parlent encore de GitHub Pages statique comme prod active +- anchors/documentation legacy de type `#projets` + +## Implementation +- runtime: `data-theme="high-contrast"` dans `src/layouts/BaseLayout.astro` +- meta navigateur claire: `themeColor` blanc dans `src/lib/site.ts` +- socle visuel: `src/styles/global.css` +- overrides DA v12: `src/styles/home-workbench.css` + +## QA minimum +- nav +- hero +- about +- case studies +- media strips +- mission cards +- FAQ +- contact +- footer +- formation +- mentions legales diff --git a/docs/project-master-todos.md b/docs/project-master-todos.md index 2e97e1f..21ef665 100644 --- a/docs/project-master-todos.md +++ b/docs/project-master-todos.md @@ -1,69 +1,67 @@ -# Master TODO - Electron rare site +# Master TODO - Electron Rare OVH/Astro -Date: 2026-03-02 -Source of truth: this file +Updated: 2026-03-14 +Source of truth: this file for execution priorities, plus the current code in `src/` -## Scope -- Site GitHub Pages (production): `index.html`, `styles.css`, `script.js`, `/lab/` -- Référence d'intégration UI/logicielle: `src/pages/index.astro`, `src/styles/global.css`, `src/components/*` -- Option web hors GitHub (en parallèle, si exigée): build Astro `dist/` publié sur autre host -- Module C interactif: `apps/lab-interactif` -> publication `lab/` -- Direction artistique active: `experimental-noise`, `electric-contrast`, `clarity-first` (reset 2026-03-02) -- Acquisition: SEO + tracking GTM/GA4 + conversion CTA +## Scope actif +- Site Astro publie sur OVH via GitHub Actions FTP. +- Preview publique sous `/preview/`, production a la racine. +- Pages actives: `/`, `/formation/`, `/mentions-legales/`, `/lab/`, `robots.txt`, `sitemap.xml`. +- Direction artistique active: `white-contrast`, claire par defaut, sans bouton de bascule public. +- Surface a maintenir: Hero, Approche, Cas concrets, photo strip, video strip, Missions, FAQ, Contact, footer. -## Decision Log DA (2026-03-02) -- [x] Avancée majeure: refonte UI complète validée en mode DA-00 sur `index.html` (scope web visible actuel). -- [x] Avancée majeure: plan DA (wireflow + composants + tokens) consolidé. -- [ ] Décision d'exploitation: maintien de la version GitHub Pages comme production immédiate, préparation d'un build Astro externe pour version web hors GitHub. -- [ ] Action nécessaire: aligner chaque évolution UI avec un `artifact` d'avancement daté (captures + preuve QA) pour éviter la dérive. +## Verites de reference +- Structure de page: `src/pages/index.astro` +- Sections actives: `src/components/sections/Hero.tsx`, `About.tsx`, `CaseStudies.tsx`, `GraphicSprints.tsx`, `Faq.astro`, `Contact.astro` +- Theme/layout: `src/layouts/BaseLayout.astro`, `src/styles/global.css`, `src/styles/home-workbench.css` +- Canonical/base/deploiement: `src/lib/site.ts`, `scripts/build-astro-external.mjs`, `docs/ovh-ftp-preview-solution-2026-03-14.md` +- Tracking actif: `src/lib/tracking.ts` + emitters inline dans `src/layouts/BaseLayout.astro` -## Base DA / architecture -- [x] Brief DA v2.2.0 verrouille le reset innovant (`notes-interne/creative-direction-brief.md`) -- [x] Home reconstruite de zero en statique -- [x] Top 3 GitHub en section Projets + bouton "Voir plus" en section dediee -- [x] Module C "Lab interactif" implemente (React Router) -- [x] Routing lab adapte GitHub Pages (HashRouter) +## Etat courant +- [x] Homepage OVH re-synchronisee dans le repo Astro. +- [x] Ancienne variante `studio/figma` sortie du runtime actif. +- [x] Bouton contraste retire du markup. +- [x] Theme blanc contraste force par defaut dans le layout source. +- [ ] White-contrast pass verifiee visuellement sur preview. +- [ ] White-contrast pass verifiee visuellement sur production. -## QA P1 (2026-03-02) -- [x] Passe visuelle responsive 390/768/1024/1440 (home + lab) -- [x] Captures + rapport QA archives (`artifacts/qa-test/2026-03-02/responsive-p1/`) -- [x] Storybook build coverage P2 execute (`npm run storybook:build`) -- [x] Checklist prod locale GA4/Search Console preparee +## P0 - Bloc de sortie immediate +- [ ] Builder le preview avec le theme blanc contraste (`PUBLIC_SITE_URL=https://www.lelectronrare.fr/preview/ npm run build:external`). +- [ ] Verifier le rendu de la home: nav, hero, approche, cas clients, missions, FAQ, footer. +- [ ] Verifier les surfaces medias: hero photo, photo strip, video strip. +- [ ] Verifier la section contact en version claire: tabs, textarea, formulaire, focus clavier, messages d'etat. +- [ ] Verifier `/formation/` et `/mentions-legales/` avec le meme theme clair. +- [ ] Deployer le preview OVH et valider `https://www.lelectronrare.fr/preview/`. -## Tracking / GA4 -- [x] Contrat hero conserve (`cta_hero_projets`, `cta_hero_contact`, `cta_hero_profile`) -- [x] Events GitHub dedies ajoutes -- [x] Compat legacy preservee (`data-track-legacy`) -- [ ] Validation GA4 Realtime sur environnement public -- [ ] Validation GA4 DebugView (params conformes) -- [ ] Definition conversion GA4 primaire LinkedIn / secondaire Malt +## P1 - Validation live +- [ ] Si preview valide, deployer la production a la racine. +- [ ] Verifier en live les routes `/`, `/formation/`, `/mentions-legales/`, `/lab/`, `/robots.txt`, `/sitemap.xml`. +- [ ] Verifier l'absence de retour vers l'ancienne homepage ou d'elements sombres residuels. +- [ ] Verifier les ancres actives: `#a-propos`, `#cas-clients`, `#graphic-sprints-title`, `#faq`, `#contact`. -## SEO / Search Console -- [x] `robots.txt` racine -- [x] `sitemap.xml` racine maj 2026-03-02 -- [x] Sitemap inclut `/` et `/lab/` -- [x] Canonical + OG + Twitter sur home -- [ ] Validation Search Console (propriete + soumission sitemap + indexation) -- [ ] Validation previews sociaux (LinkedIn/Facebook) +## P2 - Tracking / SEO +- [ ] Valider GA4 Realtime et DebugView pour les events actuels: + - `cta_hero_contact` + - `outbound_linkedin_contact` + - `outbound_email_contact` + - `outbound_github_contact` + - `cta_lab_interactif_open` +- [ ] Verifier les events auto: + - `experiment_variant_exposed` + - `engagement_scroll_depth` + - `engagement_section_view` + - `cwv_metric` +- [ ] Re-verifier canonical, OG, Twitter, robots, sitemap et `theme-color`. +- [ ] Soumettre ou recontroler Search Console sur la base de la prod actuelle OVH. -## Roadmap web hors GitHub (optionnelle) -- [ ] Générer `dist/` Astro à partir du même contenu (`npm run build`) pour maquette/landing dédiée hors GitHub Pages. -- [x] Ajouter un plan de déploiement alternatif (Netlify/Vercel/custom) sans toucher au contrat d'ancrage (`#a-propos`, `#projets`, `#contact`) : configs `vercel.json` et `netlify.toml` + script `build:external`. -- [ ] Documenter la divergence minimale: route, headers, et variables d'environnement GA/SEO. -- [ ] Valider que le contrat de tracking reste identique entre les deux versions (labels, destinations, event_category). +## P3 - Nettoyage et consolidation +- [ ] Supprimer les blocs CSS morts `.site-contrast-toggle` encore presents dans `src/styles/global.css`. +- [ ] Nettoyer les docs qui parlent encore de GitHub Pages static root, `#projets`, Malt, ou du toggle contraste. +- [ ] Mesurer LCP et budget media de la variante blanche en conditions reelles. +- [ ] Archiver les plans anterieurs devenus purement historiques. -## Deploy GitHub Pages -- [x] Workflow migre: static site + lab (`.github/workflows/deploy-pages.yml`) -- [x] Doc deploy mise a jour (`docs/github-pages-deploy.md`) -- [ ] Trigger deploy depuis `main` et verification URL publique -- [x] Exécuter `docs/dual-deployment-execution-plan.md` pour valider le mode “GitHub Pages + web externe” si décision produit. -- [x] Captures QA planifiées 390/768/1024/1440: `artifacts/qa-test/2026-03-02/responsive-p1/`. -- [x] Preflight local complété (2026-03-02): `npm run preflight:pages` -- [x] Build Astro vérifié (2026-03-02): `npm run build` -- [ ] Déploiement GH Pages post-lock (validation public URL + ancres + OG/robots/sitemap) -- [x] Déploiement OVH mutualise en SFTP valide (2026-03-02): `npm run deploy:web:sftp` + verification remote bundles (`index.html`, `Hero.D8ngAjmO.js`, `index.DrEuSoRX.css`) - -## Rituels de verification -- Avant merge: `npm run preflight:pages` -- A chaque pass majeur: mise a jour `artifacts/qa-test//...` + `evidence/manifest.json` -- Toute variation DA: mise a jour du brief avant patch UI +## Regles de pilotage +- Preview d'abord, production ensuite. +- Toute doc active doit parler du site Astro/OVH actuel, pas d'une ancienne homepage statique. +- Les ancres de reference sont celles du code actuel, pas `#projets`. +- Le theme de reference est clair/white-contrast par defaut. diff --git a/src/components/sections/CaseStudies.tsx b/src/components/sections/CaseStudies.tsx index 1b2c335..3b1bba8 100644 --- a/src/components/sections/CaseStudies.tsx +++ b/src/components/sections/CaseStudies.tsx @@ -1,4 +1,4 @@ -import { TRACK_EVENTS, trackAttrs } from '@/lib/tracking'; +import { trackAttrs } from '@/lib/tracking'; import { CASE_STUDIES } from '@/content/home-content'; export function CaseStudies() { diff --git a/src/components/sections/Faq.astro b/src/components/sections/Faq.astro index c9238b4..aff9300 100644 --- a/src/components/sections/Faq.astro +++ b/src/components/sections/Faq.astro @@ -87,5 +87,5 @@ const jsonLd = {
- + + - + +
diff --git a/src/layouts/BaseLayout.astro b/src/layouts/BaseLayout.astro index 1378b70..9881fc4 100644 --- a/src/layouts/BaseLayout.astro +++ b/src/layouts/BaseLayout.astro @@ -590,13 +590,34 @@ const structuredDataJsonLd = JSON.stringify({ } }); + var syncRootOpenState = function () { + var isCompactViewport = window.innerWidth < 960; + var hasOpenMenu = false; + + for (var i = 0; i < menus.length; i += 1) { + if (menus[i].hasAttribute('open')) { + hasOpenMenu = true; + break; + } + } + + document.documentElement.classList.toggle('site-nav-open', isCompactViewport && hasOpenMenu); + }; + window.addEventListener('resize', function () { - if (window.innerWidth >= 768) { + if (window.innerWidth >= 960) { for (var i = 0; i < menus.length; i += 1) { closeMenu(menus[i]); } } + syncRootOpenState(); }); + + for (var j = 0; j < menus.length; j += 1) { + menus[j].addEventListener('toggle', syncRootOpenState); + } + + syncRootOpenState(); })(); diff --git a/src/styles/global.css b/src/styles/global.css index d894085..643f738 100644 --- a/src/styles/global.css +++ b/src/styles/global.css @@ -5224,6 +5224,7 @@ input.contact-minitel-textarea:focus { display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: center; + position: relative; gap: 0.75rem; min-height: 4rem; padding-top: 0.55rem; @@ -5250,6 +5251,7 @@ input.contact-minitel-textarea:focus { display: flex; align-items: center; justify-self: end; + position: relative; gap: 0.5rem; } @@ -5383,7 +5385,7 @@ input.contact-minitel-textarea:focus { padding-bottom: 0.38rem; } -@media (min-width: 768px) { +@media (min-width: 960px) { .site-header-shell { grid-template-columns: minmax(0, auto) 1fr; gap: 1rem; @@ -5433,7 +5435,7 @@ input.contact-minitel-textarea:focus { } } -@media (max-width: 767px) { +@media (max-width: 959px) { .site-header-shell { min-height: 3.35rem; gap: 0.55rem; @@ -5463,7 +5465,8 @@ input.contact-minitel-textarea:focus { } .site-header-quick-link { - min-height: 2.45rem; + min-height: 2.75rem; + height: 2.75rem; display: inline-flex; align-items: center; justify-content: center; @@ -5474,10 +5477,15 @@ input.contact-minitel-textarea:focus { } .site-header-menu-toggle { + min-height: 2.75rem; + height: 2.75rem; padding-inline: 0.78rem; } .site-header-primary { + left: 0; + right: 0; + width: auto; max-height: min(74vh, 28rem); overflow: auto; -webkit-overflow-scrolling: touch; @@ -5493,29 +5501,38 @@ input.contact-minitel-textarea:focus { @media (max-width: 420px) { .site-header-shell { - grid-template-columns: minmax(0, 1fr); + grid-template-columns: minmax(0, 1fr) auto; + gap: 0.42rem; } .site-header-right { - width: 100%; - justify-content: stretch; + gap: 0.35rem; } - .site-header-quick-link, - .site-header-menu { - flex: 1 1 0; + .site-header-brand-title { + font-size: 0.92rem; } .site-header-quick-link, .site-header-menu-toggle { - width: 100%; + min-height: 2.55rem; + height: 2.55rem; } - .site-header-primary { - width: 100%; - left: 0; - right: auto; + .site-header-quick-link { + padding-inline: 0.72rem; + font-size: 0.62rem; + letter-spacing: 0.06em; } + + .site-header-menu-toggle { + padding-inline: 0.7rem; + } +} + +html.site-nav-open, +html.site-nav-open body { + overflow: hidden; } :root[data-da-variant="v12"] .site-header-brand { -- 2.52.0 From ba3af7cd3fb08751f68b353d4b4eba03aabcfb59 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20SAILLANT?= <108685187+electron-rare@users.noreply.github.com> Date: Sat, 14 Mar 2026 21:57:39 +0000 Subject: [PATCH 15/31] Fix mobile header menu drawer width --- src/styles/global.css | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/src/styles/global.css b/src/styles/global.css index 643f738..4893849 100644 --- a/src/styles/global.css +++ b/src/styles/global.css @@ -5464,9 +5464,13 @@ input.contact-minitel-textarea:focus { gap: 0.42rem; } + .site-header-menu { + position: static; + } + .site-header-quick-link { - min-height: 2.75rem; - height: 2.75rem; + min-height: 2.875rem; + height: 2.875rem; display: inline-flex; align-items: center; justify-content: center; @@ -5477,8 +5481,8 @@ input.contact-minitel-textarea:focus { } .site-header-menu-toggle { - min-height: 2.75rem; - height: 2.75rem; + min-height: 2.875rem; + height: 2.875rem; padding-inline: 0.78rem; } @@ -5493,7 +5497,9 @@ input.contact-minitel-textarea:focus { .site-header-list .figma-lab-nav-link, .site-header-list .site-navlink { - min-height: 2.75rem; + min-height: 2.875rem; + padding-top: 0.8rem; + padding-bottom: 0.8rem; padding-inline: 0.95rem; font-size: 0.69rem; } @@ -5515,8 +5521,8 @@ input.contact-minitel-textarea:focus { .site-header-quick-link, .site-header-menu-toggle { - min-height: 2.55rem; - height: 2.55rem; + min-height: 2.7rem; + height: 2.7rem; } .site-header-quick-link { -- 2.52.0 From 7e1b2032b48283f80f0f6cbf31d32d9f22640d63 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20SAILLANT?= <108685187+electron-rare@users.noreply.github.com> Date: Sat, 14 Mar 2026 22:02:38 +0000 Subject: [PATCH 16/31] Unpin mobile header drawer from right rail --- src/styles/global.css | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/styles/global.css b/src/styles/global.css index 4893849..c234984 100644 --- a/src/styles/global.css +++ b/src/styles/global.css @@ -5461,6 +5461,7 @@ input.contact-minitel-textarea:focus { } .site-header-right { + position: static; gap: 0.42rem; } @@ -5497,7 +5498,11 @@ input.contact-minitel-textarea:focus { .site-header-list .figma-lab-nav-link, .site-header-list .site-navlink { + display: flex; + align-items: center; min-height: 2.875rem; + min-block-size: 2.875rem; + block-size: 2.875rem; padding-top: 0.8rem; padding-bottom: 0.8rem; padding-inline: 0.95rem; -- 2.52.0 From 5fa56687e71d32eca024a9876a90de19c83b5a4f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20SAILLANT?= <108685187+electron-rare@users.noreply.github.com> Date: Sat, 14 Mar 2026 22:30:03 +0000 Subject: [PATCH 17/31] Raise compact header tap targets --- src/styles/global.css | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/styles/global.css b/src/styles/global.css index c234984..6edbeaa 100644 --- a/src/styles/global.css +++ b/src/styles/global.css @@ -5526,8 +5526,8 @@ input.contact-minitel-textarea:focus { .site-header-quick-link, .site-header-menu-toggle { - min-height: 2.7rem; - height: 2.7rem; + min-height: 2.8rem; + height: 2.8rem; } .site-header-quick-link { -- 2.52.0 From a519c034c31f3746d35582965f7a02e22e54e64a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20SAILLANT?= <108685187+electron-rare@users.noreply.github.com> Date: Sat, 14 Mar 2026 22:38:30 +0000 Subject: [PATCH 18/31] Remove public lab exposure and hero status copy --- public/assets/brand/logo-lockup-placeholder.svg | 1 - public/sitemap.xml | 14 ++++++++++---- scripts/build-astro-external.mjs | 14 +------------- src/components/sections/Hero.tsx | 4 ---- src/lib/tracking.ts | 3 +-- src/pages/formation.astro | 2 -- src/pages/index.astro | 3 --- src/pages/mentions-legales.astro | 2 -- src/pages/sitemap.xml.ts | 1 - 9 files changed, 12 insertions(+), 32 deletions(-) diff --git a/public/assets/brand/logo-lockup-placeholder.svg b/public/assets/brand/logo-lockup-placeholder.svg index 8fe79f6..25b30c5 100644 --- a/public/assets/brand/logo-lockup-placeholder.svg +++ b/public/assets/brand/logo-lockup-placeholder.svg @@ -10,5 +10,4 @@ ELECTRON RARE - UNSTABLE BY DESIGN diff --git a/public/sitemap.xml b/public/sitemap.xml index 2df5c53..46168e3 100644 --- a/public/sitemap.xml +++ b/public/sitemap.xml @@ -7,9 +7,15 @@ 1.0 - https://electron-rare.github.io/lab/ - 2026-03-02 - weekly - 0.8 + https://electron-rare.github.io/formation/ + 2026-03-14 + monthly + 0.9 + + + https://electron-rare.github.io/mentions-legales/ + 2026-03-14 + yearly + 0.3 diff --git a/scripts/build-astro-external.mjs b/scripts/build-astro-external.mjs index ed4b115..1231544 100644 --- a/scripts/build-astro-external.mjs +++ b/scripts/build-astro-external.mjs @@ -23,22 +23,10 @@ const run = (command) => { console.log(`[build-astro-external] Using PUBLIC_SITE_URL=${process.env.PUBLIC_SITE_URL}`); -run('npm run lab:build'); run('npm run build'); -const labSource = path.resolve(process.cwd(), 'lab'); -const labDestination = path.resolve(process.cwd(), 'dist', 'lab'); - -if (fs.existsSync(labSource)) { - fs.rmSync(labDestination, { recursive: true, force: true }); - fs.cpSync(labSource, labDestination, { recursive: true }); - console.log('[build-astro-external] Included lab/ output in dist/lab.'); -} else { - console.warn('[build-astro-external] Warning: lab/ not found; skipping lab route packaging.'); -} - const robotsContent = `User-agent: *\nAllow: /\n\nSitemap: ${siteUrl}sitemap.xml\n`; -const sitemapContent = `\n\n \n ${siteUrl}\n weekly\n 1.0\n \n \n ${siteUrl}lab/\n weekly\n 0.8\n \n\n`; +const sitemapContent = `\n\n \n ${siteUrl}\n weekly\n 1.0\n \n \n ${siteUrl}formation/\n monthly\n 0.9\n \n \n ${siteUrl}mentions-legales/\n yearly\n 0.3\n \n\n`; fs.writeFileSync(path.resolve(process.cwd(), 'dist', 'robots.txt'), robotsContent, 'utf8'); fs.writeFileSync(path.resolve(process.cwd(), 'dist', 'sitemap.xml'), sitemapContent, 'utf8'); diff --git a/src/components/sections/Hero.tsx b/src/components/sections/Hero.tsx index 9613fc0..a82968c 100644 --- a/src/components/sections/Hero.tsx +++ b/src/components/sections/Hero.tsx @@ -22,10 +22,6 @@ export function Hero() {

Design électronique · Consulting · Formation

-
- disponible - freelance · France -

diff --git a/src/lib/tracking.ts b/src/lib/tracking.ts index 3802055..c154e0d 100644 --- a/src/lib/tracking.ts +++ b/src/lib/tracking.ts @@ -3,8 +3,7 @@ export const TRACK_EVENTS = { outboundLinkedinContact: 'outbound_linkedin_contact', outboundEmailContact: 'outbound_email_contact', outboundGithubContact: 'outbound_github_contact', - outboundGithubProjectAudioBattery: 'outbound_github_project_audio_battery', - ctaLabInteractifOpen: 'cta_lab_interactif_open' + outboundGithubProjectAudioBattery: 'outbound_github_project_audio_battery' } as const; export type TrackEventName = (typeof TRACK_EVENTS)[keyof typeof TRACK_EVENTS]; diff --git a/src/pages/formation.astro b/src/pages/formation.astro index 3bb1922..9eb18b8 100644 --- a/src/pages/formation.astro +++ b/src/pages/formation.astro @@ -13,7 +13,6 @@ const homeAboutHref = withSiteBase('/#a-propos'); const homeMissionsHref = withSiteBase('/#graphic-sprints-title'); const formationHref = withSiteBase('/formation/'); const contactHref = withSiteBase('/#contact'); -const labHref = withSiteBase('/lab/'); const mentionsHref = withSiteBase('/mentions-legales/'); const headerItems = [ { href: homeAboutHref, label: 'Approche' }, @@ -255,7 +254,6 @@ const headerItems = [