From 9a9519ce29af167ad56eacae964791279fc8b7c7 Mon Sep 17 00:00:00 2001 From: ordinarthur <@arthurbarre.js@gmail.com> Date: Sat, 11 Apr 2026 17:42:39 +0200 Subject: [PATCH] update site --- .astro/data-store.json | 2 +- .astro/types.d.ts | 1 + .gitea/workflows/deploy.yml | 99 +++++++ k8s/configmap.yml | 44 +++ k8s/deployment.yml | 144 ++++++++++ k8s/namespace.yml | 4 + k8s/service.yml | 43 +++ migrate-images.mjs | 30 ++ public/style.css | 66 ++++- sanity/package.json | 8 +- sanity/pnpm-lock.yaml | 449 +++++++++++++++--------------- sanity/sanity.config.ts | 21 +- sanity/schemas/homePage.ts | 167 +++++++++++ sanity/schemas/index.ts | 3 +- sanity/schemas/product.ts | 32 ++- seed-sanity-homepage.mjs | 54 ++++ server.mjs | 2 +- src/layouts/Base.astro | 4 +- src/lib/sanity.mjs | 29 +- src/pages/collection/[slug].astro | 21 +- src/pages/index.astro | 91 ++++-- src/scripts/main.js | 90 +++++- 22 files changed, 1105 insertions(+), 299 deletions(-) create mode 100644 .gitea/workflows/deploy.yml create mode 100644 k8s/configmap.yml create mode 100644 k8s/deployment.yml create mode 100644 k8s/namespace.yml create mode 100644 k8s/service.yml create mode 100644 migrate-images.mjs create mode 100644 sanity/schemas/homePage.ts create mode 100644 seed-sanity-homepage.mjs diff --git a/.astro/data-store.json b/.astro/data-store.json index 0caf620..8f3d298 100644 --- a/.astro/data-store.json +++ b/.astro/data-store.json @@ -1 +1 @@ -[["Map",1,2],"meta::meta",["Map",3,4,5,6],"astro-version","5.18.1","astro-config-digest","{\"root\":{},\"srcDir\":{},\"publicDir\":{},\"outDir\":{},\"cacheDir\":{},\"compressHTML\":true,\"base\":\"/\",\"trailingSlash\":\"ignore\",\"output\":\"static\",\"scopedStyleStrategy\":\"attribute\",\"build\":{\"format\":\"directory\",\"client\":{},\"server\":{},\"assets\":\"_astro\",\"serverEntry\":\"entry.mjs\",\"redirects\":true,\"inlineStylesheets\":\"auto\",\"concurrency\":1},\"server\":{\"open\":false,\"host\":false,\"port\":4321,\"streaming\":true,\"allowedHosts\":[]},\"redirects\":{},\"image\":{\"endpoint\":{\"route\":\"/_image\"},\"service\":{\"entrypoint\":\"astro/assets/services/sharp\",\"config\":{}},\"domains\":[],\"remotePatterns\":[],\"responsiveStyles\":false},\"devToolbar\":{\"enabled\":true},\"markdown\":{\"syntaxHighlight\":{\"type\":\"shiki\",\"excludeLangs\":[\"math\"]},\"shikiConfig\":{\"langs\":[],\"langAlias\":{},\"theme\":\"github-dark\",\"themes\":{},\"wrap\":false,\"transformers\":[]},\"remarkPlugins\":[],\"rehypePlugins\":[],\"remarkRehype\":{},\"gfm\":true,\"smartypants\":true},\"security\":{\"checkOrigin\":true,\"allowedDomains\":[],\"actionBodySizeLimit\":1048576},\"env\":{\"schema\":{},\"validateSecrets\":false},\"experimental\":{\"clientPrerender\":false,\"contentIntellisense\":false,\"headingIdCompat\":false,\"preserveScriptOrder\":false,\"liveContentCollections\":false,\"csp\":false,\"staticImportMetaEnv\":false,\"chromeDevtoolsWorkspace\":false,\"failOnPrerenderConflict\":false,\"svgo\":false},\"legacy\":{\"collections\":false}}"] \ No newline at end of file +[["Map",1,2],"meta::meta",["Map",3,4,5,6],"astro-version","5.18.1","astro-config-digest","{\"root\":{},\"srcDir\":{},\"publicDir\":{},\"outDir\":{},\"cacheDir\":{},\"compressHTML\":true,\"base\":\"/\",\"trailingSlash\":\"ignore\",\"output\":\"server\",\"scopedStyleStrategy\":\"attribute\",\"build\":{\"format\":\"directory\",\"client\":{},\"server\":{},\"assets\":\"_astro\",\"serverEntry\":\"entry.mjs\",\"redirects\":false,\"inlineStylesheets\":\"auto\",\"concurrency\":1},\"server\":{\"open\":false,\"host\":false,\"port\":4321,\"streaming\":true,\"allowedHosts\":[]},\"redirects\":{},\"image\":{\"endpoint\":{\"route\":\"/_image\",\"entrypoint\":\"astro/assets/endpoint/dev\"},\"service\":{\"entrypoint\":\"astro/assets/services/sharp\",\"config\":{}},\"domains\":[],\"remotePatterns\":[],\"responsiveStyles\":false},\"devToolbar\":{\"enabled\":true},\"markdown\":{\"syntaxHighlight\":{\"type\":\"shiki\",\"excludeLangs\":[\"math\"]},\"shikiConfig\":{\"langs\":[],\"langAlias\":{},\"theme\":\"github-dark\",\"themes\":{},\"wrap\":false,\"transformers\":[]},\"remarkPlugins\":[],\"rehypePlugins\":[],\"remarkRehype\":{},\"gfm\":true,\"smartypants\":true},\"security\":{\"checkOrigin\":true,\"allowedDomains\":[],\"actionBodySizeLimit\":1048576},\"env\":{\"schema\":{},\"validateSecrets\":false},\"experimental\":{\"clientPrerender\":false,\"contentIntellisense\":false,\"headingIdCompat\":false,\"preserveScriptOrder\":false,\"liveContentCollections\":false,\"csp\":false,\"staticImportMetaEnv\":false,\"chromeDevtoolsWorkspace\":false,\"failOnPrerenderConflict\":false,\"svgo\":false},\"legacy\":{\"collections\":false},\"session\":{\"driver\":\"fs-lite\",\"options\":{\"base\":\"/Users/arthurbarre/dev/freelance/rebours/node_modules/.astro/sessions\"}}}"] \ No newline at end of file diff --git a/.astro/types.d.ts b/.astro/types.d.ts index f964fe0..03d7cc4 100644 --- a/.astro/types.d.ts +++ b/.astro/types.d.ts @@ -1 +1,2 @@ /// +/// \ No newline at end of file diff --git a/.gitea/workflows/deploy.yml b/.gitea/workflows/deploy.yml new file mode 100644 index 0000000..c759bd6 --- /dev/null +++ b/.gitea/workflows/deploy.yml @@ -0,0 +1,99 @@ +name: Build & Deploy to K3s + +on: + push: + branches: [main] + +env: + REGISTRY: git.arthurbarre.fr + SSR_IMAGE: git.arthurbarre.fr/ordinarthur/rebours-ssr + API_IMAGE: git.arthurbarre.fr/ordinarthur/rebours-api + REGISTRY_USER: ordinarthur + +jobs: + build-and-deploy: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Login to Gitea Container Registry + run: | + echo "${{ secrets.REGISTRY_PASSWORD }}" | \ + docker login ${{ env.REGISTRY }} -u ${{ env.REGISTRY_USER }} --password-stdin + + - name: Build SSR image + run: | + docker build \ + -f Dockerfile.ssr \ + -t ${{ env.SSR_IMAGE }}:${{ github.sha }} \ + -t ${{ env.SSR_IMAGE }}:latest \ + . + + - name: Build API image + run: | + docker build \ + -f Dockerfile.api \ + -t ${{ env.API_IMAGE }}:${{ github.sha }} \ + -t ${{ env.API_IMAGE }}:latest \ + . + + - name: Push SSR image + run: | + docker push ${{ env.SSR_IMAGE }}:${{ github.sha }} + docker push ${{ env.SSR_IMAGE }}:latest + + - name: Push API image + run: | + docker push ${{ env.API_IMAGE }}:${{ github.sha }} + docker push ${{ env.API_IMAGE }}:latest + + - name: Install kubectl + run: | + curl -LO "https://dl.k8s.io/release/$(curl -Ls https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl" + chmod +x kubectl + mv kubectl /usr/local/bin/kubectl + + - name: Configure kubeconfig + run: | + mkdir -p ~/.kube + echo "${{ secrets.KUBECONFIG }}" | base64 -d > ~/.kube/config + + - name: Apply namespace and shared resources + run: | + kubectl apply -f k8s/namespace.yml + kubectl apply -f k8s/configmap.yml + kubectl apply -f k8s/service.yml + + - name: Create image pull secret + run: | + kubectl -n rebours create secret docker-registry gitea-registry-secret \ + --docker-server=${{ env.REGISTRY }} \ + --docker-username=${{ env.REGISTRY_USER }} \ + --docker-password="${{ secrets.REGISTRY_PASSWORD }}" \ + --dry-run=client -o yaml | kubectl apply -f - + + - name: Create app secrets + run: | + kubectl -n rebours create secret generic rebours-secrets \ + --from-literal=STRIPE_SECRET_KEY="${{ secrets.STRIPE_SECRET_KEY }}" \ + --from-literal=STRIPE_WEBHOOK_SECRET="${{ secrets.STRIPE_WEBHOOK_SECRET }}" \ + --from-literal=SANITY_API_TOKEN="${{ secrets.SANITY_API_TOKEN }}" \ + --dry-run=client -o yaml | kubectl apply -f - + + - name: Deploy workloads + run: | + kubectl apply -f k8s/deployment.yml + + kubectl -n rebours set image deployment/rebours-ssr \ + rebours-ssr=${{ env.SSR_IMAGE }}:${{ github.sha }} + kubectl -n rebours set image deployment/rebours-api \ + rebours-api=${{ env.API_IMAGE }}:${{ github.sha }} + + kubectl -n rebours rollout status deployment/rebours-api --timeout=120s + kubectl -n rebours rollout status deployment/rebours-ssr --timeout=180s + kubectl -n rebours rollout status deployment/rebours-proxy --timeout=60s + + - name: Cleanup old images + run: | + docker image prune -f diff --git a/k8s/configmap.yml b/k8s/configmap.yml new file mode 100644 index 0000000..e73b77b --- /dev/null +++ b/k8s/configmap.yml @@ -0,0 +1,44 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: rebours-config + namespace: rebours +data: + NODE_ENV: "production" + SANITY_PROJECT_ID: "y821x5qu" + SANITY_DATASET: "production" + DOMAIN: "https://rebours.studio" + FASTIFY_PORT: "3000" + ASTRO_PORT: "4321" + proxy.conf: | + server { + listen 80; + server_name _; + + client_max_body_size 10M; + + # API → Fastify + location /api/ { + proxy_pass http://rebours-api:3000; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto https; + } + + # Static assets from Astro client build (cached) + location /_astro/ { + proxy_pass http://rebours-ssr:4321; + proxy_set_header Host $host; + add_header Cache-Control "public, max-age=31536000, immutable"; + } + + # SSR → Astro + location / { + proxy_pass http://rebours-ssr:4321; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto https; + } + } diff --git a/k8s/deployment.yml b/k8s/deployment.yml new file mode 100644 index 0000000..fc116df --- /dev/null +++ b/k8s/deployment.yml @@ -0,0 +1,144 @@ +# --- Astro SSR --- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: rebours-ssr + namespace: rebours + labels: + app: rebours-ssr +spec: + replicas: 1 + selector: + matchLabels: + app: rebours-ssr + template: + metadata: + labels: + app: rebours-ssr + spec: + imagePullSecrets: + - name: gitea-registry-secret + containers: + - name: rebours-ssr + image: git.arthurbarre.fr/ordinarthur/rebours-ssr:latest + ports: + - containerPort: 4321 + envFrom: + - configMapRef: + name: rebours-config + - secretRef: + name: rebours-secrets + resources: + requests: + memory: "128Mi" + cpu: "100m" + limits: + memory: "512Mi" + cpu: "500m" + readinessProbe: + httpGet: + path: / + port: 4321 + initialDelaySeconds: 10 + periodSeconds: 10 + livenessProbe: + httpGet: + path: / + port: 4321 + initialDelaySeconds: 15 + periodSeconds: 30 +--- +# --- Fastify API --- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: rebours-api + namespace: rebours + labels: + app: rebours-api +spec: + replicas: 1 + selector: + matchLabels: + app: rebours-api + template: + metadata: + labels: + app: rebours-api + spec: + imagePullSecrets: + - name: gitea-registry-secret + containers: + - name: rebours-api + image: git.arthurbarre.fr/ordinarthur/rebours-api:latest + ports: + - containerPort: 3000 + envFrom: + - configMapRef: + name: rebours-config + - secretRef: + name: rebours-secrets + resources: + requests: + memory: "128Mi" + cpu: "100m" + limits: + memory: "256Mi" + cpu: "300m" + readinessProbe: + httpGet: + path: /api/health + port: 3000 + initialDelaySeconds: 5 + periodSeconds: 10 + livenessProbe: + httpGet: + path: /api/health + port: 3000 + initialDelaySeconds: 10 + periodSeconds: 30 +--- +# --- Nginx Proxy --- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: rebours-proxy + namespace: rebours + labels: + app: rebours-proxy +spec: + replicas: 1 + selector: + matchLabels: + app: rebours-proxy + template: + metadata: + labels: + app: rebours-proxy + spec: + containers: + - name: nginx + image: nginx:alpine + ports: + - containerPort: 80 + volumeMounts: + - name: proxy-config + mountPath: /etc/nginx/conf.d/default.conf + subPath: proxy.conf + resources: + requests: + memory: "32Mi" + cpu: "25m" + limits: + memory: "64Mi" + cpu: "100m" + readinessProbe: + httpGet: + path: / + port: 80 + initialDelaySeconds: 5 + periodSeconds: 10 + volumes: + - name: proxy-config + configMap: + name: rebours-config diff --git a/k8s/namespace.yml b/k8s/namespace.yml new file mode 100644 index 0000000..206289a --- /dev/null +++ b/k8s/namespace.yml @@ -0,0 +1,4 @@ +apiVersion: v1 +kind: Namespace +metadata: + name: rebours diff --git a/k8s/service.yml b/k8s/service.yml new file mode 100644 index 0000000..d6d779b --- /dev/null +++ b/k8s/service.yml @@ -0,0 +1,43 @@ +# --- SSR (ClusterIP — internal) --- +apiVersion: v1 +kind: Service +metadata: + name: rebours-ssr + namespace: rebours +spec: + selector: + app: rebours-ssr + ports: + - name: http + port: 4321 + targetPort: 4321 +--- +# --- API (ClusterIP — internal) --- +apiVersion: v1 +kind: Service +metadata: + name: rebours-api + namespace: rebours +spec: + selector: + app: rebours-api + ports: + - name: http + port: 3000 + targetPort: 3000 +--- +# --- Proxy (NodePort — external access) --- +apiVersion: v1 +kind: Service +metadata: + name: rebours-proxy + namespace: rebours +spec: + type: NodePort + selector: + app: rebours-proxy + ports: + - name: http + port: 80 + targetPort: 80 + nodePort: 30083 diff --git a/migrate-images.mjs b/migrate-images.mjs new file mode 100644 index 0000000..65135e3 --- /dev/null +++ b/migrate-images.mjs @@ -0,0 +1,30 @@ +/** + * Migration: product.image (single) → product.images (array) + * Run: node migrate-images.mjs + */ +import 'dotenv/config' +import { createClient } from '@sanity/client' + +const sanity = createClient({ + projectId: process.env.SANITY_PROJECT_ID, + dataset: process.env.SANITY_DATASET || 'production', + apiVersion: '2024-01-01', + useCdn: false, + token: process.env.SANITY_API_TOKEN, +}) + +const products = await sanity.fetch('*[_type == "product" && defined(image)]{ _id, image }') + +console.log(`Found ${products.length} products to migrate`) + +for (const p of products) { + console.log(`Migrating ${p._id}...`) + await sanity + .patch(p._id) + .set({ images: [p.image] }) + .unset(['image']) + .commit() + console.log(` ✓ done`) +} + +console.log('Migration complete!') diff --git a/public/style.css b/public/style.css index 4ff8f9c..f9a647d 100644 --- a/public/style.css +++ b/public/style.css @@ -492,10 +492,18 @@ hr { border-right: var(--border); background: #1a1a1a; display: flex; + flex-direction: column; + overflow: hidden; + position: relative; +} + +.panel-gallery { + flex: 1; + display: flex; align-items: center; justify-content: center; overflow: hidden; - position: relative; + min-height: 0; } #panel-img { @@ -506,6 +514,52 @@ hr { opacity: 0.92; } +/* Gallery navigation */ +.panel-gallery-nav { + display: flex; + align-items: center; + justify-content: center; + gap: 8px; + padding: 12px 0; + background: #1a1a1a; + border-top: 1px solid rgba(232, 168, 0, 0.15); +} + +.gallery-dot { + width: 8px; + height: 8px; + border-radius: 50%; + border: 1px solid var(--amber); + background: transparent; + cursor: pointer; + padding: 0; + transition: background 0.2s; +} + +.gallery-dot.active { + background: var(--amber); +} + +.gallery-dot:hover { + background: rgba(232, 168, 0, 0.5); +} + +.gallery-arrow { + background: none; + border: 1px solid rgba(232, 168, 0, 0.3); + color: var(--amber); + font-family: 'Space Mono', monospace; + font-size: 0.75rem; + cursor: pointer; + padding: 2px 8px; + transition: border-color 0.2s, background 0.2s; +} + +.gallery-arrow:hover { + border-color: var(--amber); + background: rgba(232, 168, 0, 0.1); +} + /* Colonne infos : scrollable */ .panel-info-col { overflow-y: auto; @@ -981,18 +1035,17 @@ hr { position: fixed; inset: 0; z-index: 1001; - display: flex; + display: none; align-items: center; justify-content: center; opacity: 0; - visibility: hidden; pointer-events: none; - transition: opacity 0.3s ease, visibility 0.3s ease; + transition: opacity 0.3s ease; } .contact-modal.is-open { + display: flex; opacity: 1; - visibility: visible; pointer-events: auto; } @@ -1092,6 +1145,7 @@ hr { color: var(--clr-black); pointer-events: auto; resize: vertical; + width: 100%; } .contact-field input::placeholder, @@ -1136,7 +1190,7 @@ hr { .hero-left { border-right: none; border-bottom: var(--border); - min-height: 70vw; + min-height: auto; padding: 3rem var(--pad); order: -1; } diff --git a/sanity/package.json b/sanity/package.json index ecfe2ba..4f73d43 100644 --- a/sanity/package.json +++ b/sanity/package.json @@ -9,10 +9,10 @@ "deploy": "sanity deploy" }, "dependencies": { - "@sanity/vision": "^3", - "react": "^18", - "react-dom": "^18", - "sanity": "^3", + "@sanity/vision": "^3.99.0", + "react": "^19.2.4", + "react-dom": "^19.2.4", + "sanity": "^3.99.0", "styled-components": "^6" }, "devDependencies": { diff --git a/sanity/pnpm-lock.yaml b/sanity/pnpm-lock.yaml index 162ef2d..e6f37f9 100644 --- a/sanity/pnpm-lock.yaml +++ b/sanity/pnpm-lock.yaml @@ -9,20 +9,20 @@ importers: .: dependencies: '@sanity/vision': - specifier: ^3 - version: 3.99.0(@babel/runtime@7.29.2)(@codemirror/lint@6.9.5)(@codemirror/theme-one-dark@6.1.3)(@emotion/is-prop-valid@1.4.0)(codemirror@6.0.2)(react-dom@18.3.1(react@18.3.1))(react-is@18.3.1)(react@18.3.1)(styled-components@6.3.12(react-dom@18.3.1(react@18.3.1))(react@18.3.1)) + specifier: ^3.99.0 + version: 3.99.0(@babel/runtime@7.29.2)(@codemirror/lint@6.9.5)(@codemirror/theme-one-dark@6.1.3)(@emotion/is-prop-valid@1.4.0)(codemirror@6.0.2)(react-dom@19.2.4(react@19.2.4))(react-is@18.3.1)(react@19.2.4)(styled-components@6.3.12(react-dom@19.2.4(react@19.2.4))(react@19.2.4)) react: - specifier: ^18 - version: 18.3.1 + specifier: ^19.2.4 + version: 19.2.4 react-dom: - specifier: ^18 - version: 18.3.1(react@18.3.1) + specifier: ^19.2.4 + version: 19.2.4(react@19.2.4) sanity: - specifier: ^3 - version: 3.99.0(@emotion/is-prop-valid@1.4.0)(@types/node@25.5.0)(@types/react@19.2.14)(immer@10.2.0)(jiti@2.6.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(styled-components@6.3.12(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(typescript@5.9.3)(yaml@2.8.3) + specifier: ^3.99.0 + version: 3.99.0(@emotion/is-prop-valid@1.4.0)(@types/node@25.5.0)(@types/react@19.2.14)(immer@10.2.0)(jiti@2.6.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(styled-components@6.3.12(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(typescript@5.9.3)(yaml@2.8.3) styled-components: specifier: ^6 - version: 6.3.12(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + version: 6.3.12(react-dom@19.2.4(react@19.2.4))(react@19.2.4) devDependencies: '@sanity/eslint-config-studio': specifier: ^4 @@ -705,6 +705,9 @@ packages: '@codemirror/view@6.40.0': resolution: {integrity: sha512-WA0zdU7xfF10+5I3HhUUq3kqOx3KjqmtQ9lqZjfK7jtYk4G72YW9rezcSywpaUMCWOMlq+6E0pO1IWg1TNIhtg==} + '@codemirror/view@6.41.0': + resolution: {integrity: sha512-6H/qadXsVuDY219Yljhohglve8xf4B8xJkVOEWfA5uiYKiTFppjqsvsfR5iPA0RbvRBoOyTZpbLIxe9+0UR8xA==} + '@csstools/color-helpers@5.1.0': resolution: {integrity: sha512-S11EXWJyy0Mz5SYvRmY8nJYTFFd1LCNV+7cXyAgQtOOuzb4EsgfqDufL+9esx72/eLhsRdGZwaldu/h+E4t4BA==} engines: {node: '>=18'} @@ -4259,10 +4262,10 @@ packages: peerDependencies: react: ^17.0.0 || ^18.0.0 || ^19.0.0 || ^0.0.0-experimental - react-dom@18.3.1: - resolution: {integrity: sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==} + react-dom@19.2.4: + resolution: {integrity: sha512-AXJdLo8kgMbimY95O2aKQqsz2iWi9jMgKJhRBAxECE4IFxfcazB2LmzloIoibJI3C12IlY20+KFaLv+71bUJeQ==} peerDependencies: - react: ^18.3.1 + react: ^19.2.4 react-fast-compare@3.2.2: resolution: {integrity: sha512-nsO+KSNgo1SbJqJEYRE9ERzo7YtYbou/OqjSQKxV7jcKox7+usiUVZOAC+XnDOABXggQTno0Y1CpVnuWEc1boQ==} @@ -4310,8 +4313,8 @@ packages: react: ^18.3 || >=19.0.0-0 rxjs: ^7 - react@18.3.1: - resolution: {integrity: sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==} + react@19.2.4: + resolution: {integrity: sha512-9nfp2hYpCwOjAN+8TZFGhtWEwgvWHXqESH8qT89AT/lWklpLON22Lc8pEtnpsZz7VmawabSU0gCjnj8aC0euHQ==} engines: {node: '>=0.10.0'} read-pkg-up@7.0.1: @@ -4513,8 +4516,8 @@ packages: resolution: {integrity: sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==} engines: {node: '>=v12.22.7'} - scheduler@0.23.2: - resolution: {integrity: sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==} + scheduler@0.27.0: + resolution: {integrity: sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==} scroll-into-view-if-needed@3.1.0: resolution: {integrity: sha512-49oNpRjWRvnU8NyGVmUaYG4jtTkNonFZI86MmGRDqBphEK2EXT9gdEUoQPZhuBM8yWHxCWbobltqYO5M4XrUvQ==} @@ -6286,7 +6289,7 @@ snapshots: dependencies: '@codemirror/language': 6.12.3 '@codemirror/state': 6.6.0 - '@codemirror/view': 6.40.0 + '@codemirror/view': 6.41.0 '@lezer/highlight': 1.2.3 '@codemirror/view@6.40.0': @@ -6296,6 +6299,13 @@ snapshots: style-mod: 4.1.3 w3c-keyname: 2.2.8 + '@codemirror/view@6.41.0': + dependencies: + '@codemirror/state': 6.6.0 + crelt: 1.0.6 + style-mod: 4.1.3 + w3c-keyname: 2.2.8 + '@csstools/color-helpers@5.1.0': {} '@csstools/color-helpers@6.0.2': {} @@ -6344,36 +6354,36 @@ snapshots: '@date-fns/utc@2.1.1': {} - '@dnd-kit/accessibility@3.1.1(react@18.3.1)': + '@dnd-kit/accessibility@3.1.1(react@19.2.4)': dependencies: - react: 18.3.1 + react: 19.2.4 tslib: 2.8.1 - '@dnd-kit/core@6.3.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@dnd-kit/core@6.3.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: - '@dnd-kit/accessibility': 3.1.1(react@18.3.1) - '@dnd-kit/utilities': 3.2.2(react@18.3.1) - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) + '@dnd-kit/accessibility': 3.1.1(react@19.2.4) + '@dnd-kit/utilities': 3.2.2(react@19.2.4) + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) tslib: 2.8.1 - '@dnd-kit/modifiers@6.0.1(@dnd-kit/core@6.3.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)': + '@dnd-kit/modifiers@6.0.1(@dnd-kit/core@6.3.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(react@19.2.4)': dependencies: - '@dnd-kit/core': 6.3.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@dnd-kit/utilities': 3.2.2(react@18.3.1) - react: 18.3.1 + '@dnd-kit/core': 6.3.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@dnd-kit/utilities': 3.2.2(react@19.2.4) + react: 19.2.4 tslib: 2.8.1 - '@dnd-kit/sortable@7.0.2(@dnd-kit/core@6.3.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)': + '@dnd-kit/sortable@7.0.2(@dnd-kit/core@6.3.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(react@19.2.4)': dependencies: - '@dnd-kit/core': 6.3.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@dnd-kit/utilities': 3.2.2(react@18.3.1) - react: 18.3.1 + '@dnd-kit/core': 6.3.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@dnd-kit/utilities': 3.2.2(react@19.2.4) + react: 19.2.4 tslib: 2.8.1 - '@dnd-kit/utilities@3.2.2(react@18.3.1)': + '@dnd-kit/utilities@3.2.2(react@19.2.4)': dependencies: - react: 18.3.1 + react: 19.2.4 tslib: 2.8.1 '@emotion/is-prop-valid@1.4.0': @@ -6496,11 +6506,11 @@ snapshots: '@floating-ui/core': 1.7.5 '@floating-ui/utils': 0.2.11 - '@floating-ui/react-dom@2.1.8(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@floating-ui/react-dom@2.1.8(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: '@floating-ui/dom': 1.7.6 - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) '@floating-ui/utils@0.2.11': {} @@ -6697,22 +6707,22 @@ snapshots: dependencies: mux-embed: 5.17.10 - '@mux/mux-player-react@3.11.7(@types/react@19.2.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@mux/mux-player-react@3.11.7(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: - '@mux/mux-player': 3.11.7(react@18.3.1) + '@mux/mux-player': 3.11.7(react@19.2.4) '@mux/playback-core': 0.33.3 prop-types: 15.8.1 - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) optionalDependencies: '@types/react': 19.2.14 - '@mux/mux-player@3.11.7(react@18.3.1)': + '@mux/mux-player@3.11.7(react@19.2.4)': dependencies: '@mux/mux-video': 0.30.5 '@mux/playback-core': 0.33.3 - media-chrome: 4.18.3(react@18.3.1) - player.style: 0.3.1(react@18.3.1) + media-chrome: 4.18.3(react@19.2.4) + player.style: 0.3.1(react@19.2.4) transitivePeerDependencies: - react @@ -6832,7 +6842,7 @@ snapshots: get-random-values-esm: 1.0.2 lodash: 4.17.23 - '@portabletext/editor@1.58.1(@sanity/schema@3.99.0(@types/react@19.2.14)(debug@4.4.3))(@sanity/types@3.99.0(@types/react@19.2.14)(debug@4.4.3))(@types/react@19.2.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(rxjs@7.8.2)': + '@portabletext/editor@1.58.1(@sanity/schema@3.99.0(@types/react@19.2.14)(debug@4.4.3))(@sanity/types@3.99.0(@types/react@19.2.14)(debug@4.4.3))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(rxjs@7.8.2)': dependencies: '@portabletext/block-tools': 1.1.38(@sanity/types@3.99.0(@types/react@19.2.14)(debug@4.4.3))(@types/react@19.2.14) '@portabletext/keyboard-shortcuts': 1.1.0 @@ -6840,19 +6850,19 @@ snapshots: '@portabletext/to-html': 2.0.17 '@sanity/schema': 3.99.0(@types/react@19.2.14)(debug@4.4.3) '@sanity/types': 3.99.0(@types/react@19.2.14)(debug@4.4.3) - '@xstate/react': 6.1.0(@types/react@19.2.14)(react@18.3.1)(xstate@5.30.0) + '@xstate/react': 6.1.0(@types/react@19.2.14)(react@19.2.4)(xstate@5.30.0) debug: 4.4.3(supports-color@8.1.1) get-random-values-esm: 1.0.2 immer: 10.2.0 lodash: 4.17.23 lodash.startcase: 4.4.0 - react: 18.3.1 - react-compiler-runtime: 19.1.0-rc.2(react@18.3.1) + react: 19.2.4 + react-compiler-runtime: 19.1.0-rc.2(react@19.2.4) rxjs: 7.8.2 slate: 0.117.2 slate-dom: 0.116.0(slate@0.117.2) - slate-react: 0.117.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(slate-dom@0.116.0(slate@0.117.2))(slate@0.117.2) - use-effect-event: 1.0.2(react@18.3.1) + slate-react: 0.117.3(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(slate-dom@0.116.0(slate@0.117.2))(slate@0.117.2) + use-effect-event: 1.0.2(react@19.2.4) xstate: 5.30.0 transitivePeerDependencies: - '@types/react' @@ -6866,11 +6876,11 @@ snapshots: '@sanity/diff-match-patch': 3.2.0 lodash: 4.17.23 - '@portabletext/react@3.2.4(react@18.3.1)': + '@portabletext/react@3.2.4(react@19.2.4)': dependencies: '@portabletext/toolkit': 2.0.18 '@portabletext/types': 2.0.15 - react: 18.3.1 + react: 19.2.4 '@portabletext/to-html@2.0.17': dependencies: @@ -6883,16 +6893,16 @@ snapshots: '@portabletext/types@2.0.15': {} - '@rexxars/react-json-inspector@9.0.1(react@18.3.1)': + '@rexxars/react-json-inspector@9.0.1(react@19.2.4)': dependencies: debounce: 1.2.1 md5-o-matic: 0.1.1 - react: 18.3.1 + react: 19.2.4 - '@rexxars/react-split-pane@1.0.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@rexxars/react-split-pane@1.0.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) '@rolldown/pluginutils@1.0.0-beta.27': {} @@ -6980,13 +6990,13 @@ snapshots: nanoid: 3.3.11 rxjs: 7.8.2 - '@sanity/cli@3.99.0(@types/node@25.5.0)(@types/react@19.2.14)(react@18.3.1)(typescript@5.9.3)(yaml@2.8.3)': + '@sanity/cli@3.99.0(@types/node@25.5.0)(@types/react@19.2.14)(react@19.2.4)(typescript@5.9.3)(yaml@2.8.3)': dependencies: '@babel/traverse': 7.29.0 '@sanity/client': 7.20.0(debug@4.4.3) '@sanity/codegen': 3.99.0 '@sanity/runtime-cli': 9.2.0(@types/node@25.5.0)(debug@4.4.3)(typescript@5.9.3)(yaml@2.8.3) - '@sanity/telemetry': 0.8.1(react@18.3.1) + '@sanity/telemetry': 0.8.1(react@19.2.4) '@sanity/template-validator': 2.4.6 '@sanity/util': 3.99.0(@types/react@19.2.14)(debug@4.4.3) chalk: 4.1.2 @@ -7129,9 +7139,9 @@ snapshots: '@sanity/generate-help-url@3.0.1': {} - '@sanity/icons@3.7.4(react@18.3.1)': + '@sanity/icons@3.7.4(react@19.2.4)': dependencies: - react: 18.3.1 + react: 19.2.4 '@sanity/id-utils@1.0.0': dependencies: @@ -7168,24 +7178,24 @@ snapshots: - '@types/react' - supports-color - '@sanity/insert-menu@1.1.13(@emotion/is-prop-valid@1.4.0)(@sanity/types@3.99.0(@types/react@19.2.14)(debug@4.4.3))(react-dom@18.3.1(react@18.3.1))(react-is@18.3.1)(react@18.3.1)(styled-components@6.3.12(react-dom@18.3.1(react@18.3.1))(react@18.3.1))': + '@sanity/insert-menu@1.1.13(@emotion/is-prop-valid@1.4.0)(@sanity/types@3.99.0(@types/react@19.2.14)(debug@4.4.3))(react-dom@19.2.4(react@19.2.4))(react-is@18.3.1)(react@19.2.4)(styled-components@6.3.12(react-dom@19.2.4(react@19.2.4))(react@19.2.4))': dependencies: - '@sanity/icons': 3.7.4(react@18.3.1) + '@sanity/icons': 3.7.4(react@19.2.4) '@sanity/types': 3.99.0(@types/react@19.2.14)(debug@4.4.3) - '@sanity/ui': 2.16.22(@emotion/is-prop-valid@1.4.0)(react-dom@18.3.1(react@18.3.1))(react-is@18.3.1)(react@18.3.1)(styled-components@6.3.12(react-dom@18.3.1(react@18.3.1))(react@18.3.1)) + '@sanity/ui': 2.16.22(@emotion/is-prop-valid@1.4.0)(react-dom@19.2.4(react@19.2.4))(react-is@18.3.1)(react@19.2.4)(styled-components@6.3.12(react-dom@19.2.4(react@19.2.4))(react@19.2.4)) lodash: 4.17.23 - react: 18.3.1 - react-compiler-runtime: 19.1.0-rc.2(react@18.3.1) - react-dom: 18.3.1(react@18.3.1) + react: 19.2.4 + react-compiler-runtime: 19.1.0-rc.2(react@19.2.4) + react-dom: 19.2.4(react@19.2.4) react-is: 18.3.1 transitivePeerDependencies: - '@emotion/is-prop-valid' - styled-components - '@sanity/logos@2.2.2(react@18.3.1)': + '@sanity/logos@2.2.2(react@19.2.4)': dependencies: '@sanity/color': 3.0.6 - react: 18.3.1 + react: 19.2.4 '@sanity/media-library-types@1.2.0': {} @@ -7240,13 +7250,13 @@ snapshots: - '@sanity/client' - '@sanity/types' - '@sanity/preview-url-secret@2.1.16(@sanity/client@7.20.0(debug@4.4.3))(@sanity/icons@3.7.4(react@18.3.1))(sanity@3.99.0(@emotion/is-prop-valid@1.4.0)(@types/node@25.5.0)(@types/react@19.2.14)(immer@10.2.0)(jiti@2.6.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(styled-components@6.3.12(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(typescript@5.9.3)(yaml@2.8.3))': + '@sanity/preview-url-secret@2.1.16(@sanity/client@7.20.0(debug@4.4.3))(@sanity/icons@3.7.4(react@19.2.4))(sanity@3.99.0(@emotion/is-prop-valid@1.4.0)(@types/node@25.5.0)(@types/react@19.2.14)(immer@10.2.0)(jiti@2.6.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(styled-components@6.3.12(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(typescript@5.9.3)(yaml@2.8.3))': dependencies: '@sanity/client': 7.20.0(debug@4.4.3) '@sanity/uuid': 3.0.2 optionalDependencies: - '@sanity/icons': 3.7.4(react@18.3.1) - sanity: 3.99.0(@emotion/is-prop-valid@1.4.0)(@types/node@25.5.0)(@types/react@19.2.14)(immer@10.2.0)(jiti@2.6.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(styled-components@6.3.12(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(typescript@5.9.3)(yaml@2.8.3) + '@sanity/icons': 3.7.4(react@19.2.4) + sanity: 3.99.0(@emotion/is-prop-valid@1.4.0)(@types/node@25.5.0)(@types/react@19.2.14)(immer@10.2.0)(jiti@2.6.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(styled-components@6.3.12(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(typescript@5.9.3)(yaml@2.8.3) '@sanity/runtime-cli@9.2.0(@types/node@25.5.0)(debug@4.4.3)(typescript@5.9.3)(yaml@2.8.3)': dependencies: @@ -7307,7 +7317,7 @@ snapshots: - debug - supports-color - '@sanity/sdk@0.0.0-alpha.25(@types/react@19.2.14)(debug@4.4.3)(immer@10.2.0)(react@18.3.1)(use-sync-external-store@1.6.0(react@18.3.1))': + '@sanity/sdk@0.0.0-alpha.25(@types/react@19.2.14)(debug@4.4.3)(immer@10.2.0)(react@19.2.4)(use-sync-external-store@1.6.0(react@19.2.4))': dependencies: '@sanity/client': 6.29.1(debug@4.4.3) '@sanity/comlink': 3.1.1 @@ -7318,7 +7328,7 @@ snapshots: lodash-es: 4.17.23 reselect: 5.1.1 rxjs: 7.8.2 - zustand: 5.0.12(@types/react@19.2.14)(immer@10.2.0)(react@18.3.1)(use-sync-external-store@1.6.0(react@18.3.1)) + zustand: 5.0.12(@types/react@19.2.14)(immer@10.2.0)(react@19.2.4)(use-sync-external-store@1.6.0(react@19.2.4)) transitivePeerDependencies: - '@types/react' - debug @@ -7326,10 +7336,10 @@ snapshots: - react - use-sync-external-store - '@sanity/telemetry@0.8.1(react@18.3.1)': + '@sanity/telemetry@0.8.1(react@19.2.4)': dependencies: lodash: 4.17.23 - react: 18.3.1 + react: 19.2.4 rxjs: 7.8.2 typeid-js: 0.3.0 @@ -7354,21 +7364,21 @@ snapshots: transitivePeerDependencies: - debug - '@sanity/ui@2.16.22(@emotion/is-prop-valid@1.4.0)(react-dom@18.3.1(react@18.3.1))(react-is@18.3.1)(react@18.3.1)(styled-components@6.3.12(react-dom@18.3.1(react@18.3.1))(react@18.3.1))': + '@sanity/ui@2.16.22(@emotion/is-prop-valid@1.4.0)(react-dom@19.2.4(react@19.2.4))(react-is@18.3.1)(react@19.2.4)(styled-components@6.3.12(react-dom@19.2.4(react@19.2.4))(react@19.2.4))': dependencies: - '@floating-ui/react-dom': 2.1.8(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@floating-ui/react-dom': 2.1.8(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@juggle/resize-observer': 3.4.0 '@sanity/color': 3.0.6 - '@sanity/icons': 3.7.4(react@18.3.1) + '@sanity/icons': 3.7.4(react@19.2.4) csstype: 3.2.3 - motion: 12.38.0(@emotion/is-prop-valid@1.4.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - react: 18.3.1 - react-compiler-runtime: 1.0.0(react@18.3.1) - react-dom: 18.3.1(react@18.3.1) + motion: 12.38.0(@emotion/is-prop-valid@1.4.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + react: 19.2.4 + react-compiler-runtime: 1.0.0(react@19.2.4) + react-dom: 19.2.4(react@19.2.4) react-is: 18.3.1 - react-refractor: 2.2.0(react@18.3.1) - styled-components: 6.3.12(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - use-effect-event: 2.0.3(react@18.3.1) + react-refractor: 2.2.0(react@19.2.4) + styled-components: 6.3.12(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + use-effect-event: 2.0.3(react@19.2.4) transitivePeerDependencies: - '@emotion/is-prop-valid' @@ -7401,7 +7411,7 @@ snapshots: '@types/uuid': 8.3.4 uuid: 8.3.2 - '@sanity/vision@3.99.0(@babel/runtime@7.29.2)(@codemirror/lint@6.9.5)(@codemirror/theme-one-dark@6.1.3)(@emotion/is-prop-valid@1.4.0)(codemirror@6.0.2)(react-dom@18.3.1(react@18.3.1))(react-is@18.3.1)(react@18.3.1)(styled-components@6.3.12(react-dom@18.3.1(react@18.3.1))(react@18.3.1))': + '@sanity/vision@3.99.0(@babel/runtime@7.29.2)(@codemirror/lint@6.9.5)(@codemirror/theme-one-dark@6.1.3)(@emotion/is-prop-valid@1.4.0)(codemirror@6.0.2)(react-dom@19.2.4(react@19.2.4))(react-is@18.3.1)(react@19.2.4)(styled-components@6.3.12(react-dom@19.2.4(react@19.2.4))(react@19.2.4))': dependencies: '@codemirror/autocomplete': 6.20.1 '@codemirror/commands': 6.10.3 @@ -7412,25 +7422,25 @@ snapshots: '@codemirror/view': 6.40.0 '@juggle/resize-observer': 3.4.0 '@lezer/highlight': 1.2.3 - '@rexxars/react-json-inspector': 9.0.1(react@18.3.1) - '@rexxars/react-split-pane': 1.0.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@rexxars/react-json-inspector': 9.0.1(react@19.2.4) + '@rexxars/react-split-pane': 1.0.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@sanity/color': 3.0.6 - '@sanity/icons': 3.7.4(react@18.3.1) - '@sanity/ui': 2.16.22(@emotion/is-prop-valid@1.4.0)(react-dom@18.3.1(react@18.3.1))(react-is@18.3.1)(react@18.3.1)(styled-components@6.3.12(react-dom@18.3.1(react@18.3.1))(react@18.3.1)) + '@sanity/icons': 3.7.4(react@19.2.4) + '@sanity/ui': 2.16.22(@emotion/is-prop-valid@1.4.0)(react-dom@19.2.4(react@19.2.4))(react-is@18.3.1)(react@19.2.4)(styled-components@6.3.12(react-dom@19.2.4(react@19.2.4))(react@19.2.4)) '@sanity/uuid': 3.0.2 - '@uiw/react-codemirror': 4.25.9(@babel/runtime@7.29.2)(@codemirror/autocomplete@6.20.1)(@codemirror/language@6.12.3)(@codemirror/lint@6.9.5)(@codemirror/search@6.6.0)(@codemirror/state@6.6.0)(@codemirror/theme-one-dark@6.1.3)(@codemirror/view@6.40.0)(codemirror@6.0.2)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@uiw/react-codemirror': 4.25.9(@babel/runtime@7.29.2)(@codemirror/autocomplete@6.20.1)(@codemirror/language@6.12.3)(@codemirror/lint@6.9.5)(@codemirror/search@6.6.0)(@codemirror/state@6.6.0)(@codemirror/theme-one-dark@6.1.3)(@codemirror/view@6.40.0)(codemirror@6.0.2)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) is-hotkey-esm: 1.0.0 json-2-csv: 5.5.10 json5: 2.2.3 lodash: 4.17.23 quick-lru: 5.1.1 - react: 18.3.1 - react-compiler-runtime: 19.1.0-rc.2(react@18.3.1) + react: 19.2.4 + react-compiler-runtime: 19.1.0-rc.2(react@19.2.4) react-fast-compare: 3.2.2 - react-rx: 4.2.2(react@18.3.1)(rxjs@7.8.2) + react-rx: 4.2.2(react@19.2.4)(rxjs@7.8.2) rxjs: 7.8.2 - styled-components: 6.3.12(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - use-effect-event: 2.0.3(react@18.3.1) + styled-components: 6.3.12(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + use-effect-event: 2.0.3(react@19.2.4) transitivePeerDependencies: - '@babel/runtime' - '@codemirror/lint' @@ -7474,24 +7484,24 @@ snapshots: '@sentry/core@8.55.1': {} - '@sentry/react@8.55.1(react@18.3.1)': + '@sentry/react@8.55.1(react@19.2.4)': dependencies: '@sentry/browser': 8.55.1 '@sentry/core': 8.55.1 hoist-non-react-statics: 3.3.2 - react: 18.3.1 + react: 19.2.4 - '@tanstack/react-table@8.21.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@tanstack/react-table@8.21.3(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: '@tanstack/table-core': 8.21.3 - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) - '@tanstack/react-virtual@3.13.23(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@tanstack/react-virtual@3.13.23(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: '@tanstack/virtual-core': 3.13.23 - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) '@tanstack/table-core@8.21.3': {} @@ -7666,7 +7676,7 @@ snapshots: '@codemirror/state': 6.6.0 '@codemirror/view': 6.40.0 - '@uiw/react-codemirror@4.25.9(@babel/runtime@7.29.2)(@codemirror/autocomplete@6.20.1)(@codemirror/language@6.12.3)(@codemirror/lint@6.9.5)(@codemirror/search@6.6.0)(@codemirror/state@6.6.0)(@codemirror/theme-one-dark@6.1.3)(@codemirror/view@6.40.0)(codemirror@6.0.2)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@uiw/react-codemirror@4.25.9(@babel/runtime@7.29.2)(@codemirror/autocomplete@6.20.1)(@codemirror/language@6.12.3)(@codemirror/lint@6.9.5)(@codemirror/search@6.6.0)(@codemirror/state@6.6.0)(@codemirror/theme-one-dark@6.1.3)(@codemirror/view@6.40.0)(codemirror@6.0.2)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: '@babel/runtime': 7.29.2 '@codemirror/commands': 6.10.3 @@ -7675,8 +7685,8 @@ snapshots: '@codemirror/view': 6.40.0 '@uiw/codemirror-extensions-basic-setup': 4.25.9(@codemirror/autocomplete@6.20.1)(@codemirror/commands@6.10.3)(@codemirror/language@6.12.3)(@codemirror/lint@6.9.5)(@codemirror/search@6.6.0)(@codemirror/state@6.6.0)(@codemirror/view@6.40.0) codemirror: 6.0.2 - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) transitivePeerDependencies: - '@codemirror/autocomplete' - '@codemirror/language' @@ -7699,11 +7709,11 @@ snapshots: transitivePeerDependencies: - supports-color - '@xstate/react@6.1.0(@types/react@19.2.14)(react@18.3.1)(xstate@5.30.0)': + '@xstate/react@6.1.0(@types/react@19.2.14)(react@19.2.4)(xstate@5.30.0)': dependencies: - react: 18.3.1 - use-isomorphic-layout-effect: 1.2.1(@types/react@19.2.14)(react@18.3.1) - use-sync-external-store: 1.6.0(react@18.3.1) + react: 19.2.4 + use-isomorphic-layout-effect: 1.2.1(@types/react@19.2.14)(react@19.2.4) + use-sync-external-store: 1.6.0(react@19.2.4) optionalDependencies: xstate: 5.30.0 transitivePeerDependencies: @@ -8063,9 +8073,9 @@ snapshots: dependencies: custom-media-element: 1.4.6 - ce-la-react@0.3.2(react@18.3.1): + ce-la-react@0.3.2(react@19.2.4): dependencies: - react: 18.3.1 + react: 19.2.4 chalk@2.4.2: dependencies: @@ -8144,7 +8154,7 @@ snapshots: '@codemirror/lint': 6.9.5 '@codemirror/search': 6.6.0 '@codemirror/state': 6.6.0 - '@codemirror/view': 6.40.0 + '@codemirror/view': 6.41.0 color-convert@1.9.3: dependencies: @@ -8927,15 +8937,15 @@ snapshots: hasown: 2.0.2 mime-types: 2.1.35 - framer-motion@12.38.0(@emotion/is-prop-valid@1.4.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + framer-motion@12.38.0(@emotion/is-prop-valid@1.4.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4): dependencies: motion-dom: 12.38.0 motion-utils: 12.36.0 tslib: 2.8.1 optionalDependencies: '@emotion/is-prop-valid': 1.4.0 - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) from2@2.3.0: dependencies: @@ -9716,22 +9726,22 @@ snapshots: mdn-data@2.27.1: {} - media-chrome@4.11.1(react@18.3.1): + media-chrome@4.11.1(react@19.2.4): dependencies: '@vercel/edge': 1.2.2 - ce-la-react: 0.3.2(react@18.3.1) + ce-la-react: 0.3.2(react@19.2.4) transitivePeerDependencies: - react - media-chrome@4.16.1(react@18.3.1): + media-chrome@4.16.1(react@19.2.4): dependencies: - ce-la-react: 0.3.2(react@18.3.1) + ce-la-react: 0.3.2(react@19.2.4) transitivePeerDependencies: - react - media-chrome@4.18.3(react@18.3.1): + media-chrome@4.18.3(react@19.2.4): dependencies: - ce-la-react: 0.3.2(react@18.3.1) + ce-la-react: 0.3.2(react@19.2.4) transitivePeerDependencies: - react @@ -9842,14 +9852,14 @@ snapshots: motion-utils@12.36.0: {} - motion@12.38.0(@emotion/is-prop-valid@1.4.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + motion@12.38.0(@emotion/is-prop-valid@1.4.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4): dependencies: - framer-motion: 12.38.0(@emotion/is-prop-valid@1.4.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + framer-motion: 12.38.0(@emotion/is-prop-valid@1.4.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) tslib: 2.8.1 optionalDependencies: '@emotion/is-prop-valid': 1.4.0 - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) ms@2.0.0: {} @@ -10152,15 +10162,15 @@ snapshots: dependencies: find-up: 5.0.0 - player.style@0.1.10(react@18.3.1): + player.style@0.1.10(react@19.2.4): dependencies: - media-chrome: 4.11.1(react@18.3.1) + media-chrome: 4.11.1(react@19.2.4) transitivePeerDependencies: - react - player.style@0.3.1(react@18.3.1): + player.style@0.3.1(react@19.2.4): dependencies: - media-chrome: 4.16.1(react@18.3.1) + media-chrome: 4.16.1(react@19.2.4) transitivePeerDependencies: - react @@ -10250,72 +10260,69 @@ snapshots: dependencies: performance-now: 2.1.0 - react-clientside-effect@1.2.8(react@18.3.1): + react-clientside-effect@1.2.8(react@19.2.4): dependencies: '@babel/runtime': 7.29.2 - react: 18.3.1 + react: 19.2.4 - react-compiler-runtime@1.0.0(react@18.3.1): + react-compiler-runtime@1.0.0(react@19.2.4): dependencies: - react: 18.3.1 + react: 19.2.4 - react-compiler-runtime@19.1.0-rc.2(react@18.3.1): + react-compiler-runtime@19.1.0-rc.2(react@19.2.4): dependencies: - react: 18.3.1 + react: 19.2.4 - react-dom@18.3.1(react@18.3.1): + react-dom@19.2.4(react@19.2.4): dependencies: - loose-envify: 1.4.0 - react: 18.3.1 - scheduler: 0.23.2 + react: 19.2.4 + scheduler: 0.27.0 react-fast-compare@3.2.2: {} - react-focus-lock@2.13.7(@types/react@19.2.14)(react@18.3.1): + react-focus-lock@2.13.7(@types/react@19.2.14)(react@19.2.4): dependencies: '@babel/runtime': 7.29.2 focus-lock: 1.3.6 prop-types: 15.8.1 - react: 18.3.1 - react-clientside-effect: 1.2.8(react@18.3.1) - use-callback-ref: 1.3.3(@types/react@19.2.14)(react@18.3.1) - use-sidecar: 1.1.3(@types/react@19.2.14)(react@18.3.1) + react: 19.2.4 + react-clientside-effect: 1.2.8(react@19.2.4) + use-callback-ref: 1.3.3(@types/react@19.2.14)(react@19.2.4) + use-sidecar: 1.1.3(@types/react@19.2.14)(react@19.2.4) optionalDependencies: '@types/react': 19.2.14 - react-i18next@14.0.2(i18next@23.16.8)(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + react-i18next@14.0.2(i18next@23.16.8)(react-dom@19.2.4(react@19.2.4))(react@19.2.4): dependencies: '@babel/runtime': 7.29.2 html-parse-stringify: 3.0.1 i18next: 23.16.8 - react: 18.3.1 + react: 19.2.4 optionalDependencies: - react-dom: 18.3.1(react@18.3.1) + react-dom: 19.2.4(react@19.2.4) react-is@16.13.1: {} react-is@18.3.1: {} - react-refractor@2.2.0(react@18.3.1): + react-refractor@2.2.0(react@19.2.4): dependencies: - react: 18.3.1 + react: 19.2.4 refractor: 3.6.0 unist-util-filter: 2.0.3 unist-util-visit-parents: 3.1.1 react-refresh@0.17.0: {} - react-rx@4.2.2(react@18.3.1)(rxjs@7.8.2): + react-rx@4.2.2(react@19.2.4)(rxjs@7.8.2): dependencies: observable-callback: 1.0.3(rxjs@7.8.2) - react: 18.3.1 - react-compiler-runtime: 1.0.0(react@18.3.1) + react: 19.2.4 + react-compiler-runtime: 1.0.0(react@19.2.4) rxjs: 7.8.2 - use-effect-event: 2.0.3(react@18.3.1) + use-effect-event: 2.0.3(react@19.2.4) - react@18.3.1: - dependencies: - loose-envify: 1.4.0 + react@19.2.4: {} read-pkg-up@7.0.1: dependencies: @@ -10561,22 +10568,22 @@ snapshots: safer-buffer@2.1.2: {} - sanity@3.99.0(@emotion/is-prop-valid@1.4.0)(@types/node@25.5.0)(@types/react@19.2.14)(immer@10.2.0)(jiti@2.6.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(styled-components@6.3.12(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(typescript@5.9.3)(yaml@2.8.3): + sanity@3.99.0(@emotion/is-prop-valid@1.4.0)(@types/node@25.5.0)(@types/react@19.2.14)(immer@10.2.0)(jiti@2.6.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(styled-components@6.3.12(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(typescript@5.9.3)(yaml@2.8.3): dependencies: - '@dnd-kit/core': 6.3.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@dnd-kit/modifiers': 6.0.1(@dnd-kit/core@6.3.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1) - '@dnd-kit/sortable': 7.0.2(@dnd-kit/core@6.3.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1) - '@dnd-kit/utilities': 3.2.2(react@18.3.1) + '@dnd-kit/core': 6.3.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@dnd-kit/modifiers': 6.0.1(@dnd-kit/core@6.3.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(react@19.2.4) + '@dnd-kit/sortable': 7.0.2(@dnd-kit/core@6.3.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(react@19.2.4) + '@dnd-kit/utilities': 3.2.2(react@19.2.4) '@juggle/resize-observer': 3.4.0 - '@mux/mux-player-react': 3.11.7(@types/react@19.2.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@mux/mux-player-react': 3.11.7(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@portabletext/block-tools': 1.1.38(@sanity/types@3.99.0(@types/react@19.2.14)(debug@4.4.3))(@types/react@19.2.14) - '@portabletext/editor': 1.58.1(@sanity/schema@3.99.0(@types/react@19.2.14)(debug@4.4.3))(@sanity/types@3.99.0(@types/react@19.2.14)(debug@4.4.3))(@types/react@19.2.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(rxjs@7.8.2) - '@portabletext/react': 3.2.4(react@18.3.1) + '@portabletext/editor': 1.58.1(@sanity/schema@3.99.0(@types/react@19.2.14)(debug@4.4.3))(@sanity/types@3.99.0(@types/react@19.2.14)(debug@4.4.3))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(rxjs@7.8.2) + '@portabletext/react': 3.2.4(react@19.2.4) '@portabletext/toolkit': 2.0.18 - '@rexxars/react-json-inspector': 9.0.1(react@18.3.1) + '@rexxars/react-json-inspector': 9.0.1(react@19.2.4) '@sanity/asset-utils': 2.3.0 '@sanity/bifur-client': 0.4.1 - '@sanity/cli': 3.99.0(@types/node@25.5.0)(@types/react@19.2.14)(react@18.3.1)(typescript@5.9.3)(yaml@2.8.3) + '@sanity/cli': 3.99.0(@types/node@25.5.0)(@types/react@19.2.14)(react@19.2.4)(typescript@5.9.3)(yaml@2.8.3) '@sanity/client': 7.20.0(debug@4.4.3) '@sanity/color': 3.0.6 '@sanity/comlink': 3.1.1 @@ -10585,28 +10592,28 @@ snapshots: '@sanity/diff-patch': 5.0.0 '@sanity/eventsource': 5.0.2 '@sanity/export': 3.45.3(@types/react@19.2.14) - '@sanity/icons': 3.7.4(react@18.3.1) + '@sanity/icons': 3.7.4(react@19.2.4) '@sanity/id-utils': 1.0.0 '@sanity/image-url': 1.2.0 '@sanity/import': 3.38.3(@types/react@19.2.14) - '@sanity/insert-menu': 1.1.13(@emotion/is-prop-valid@1.4.0)(@sanity/types@3.99.0(@types/react@19.2.14)(debug@4.4.3))(react-dom@18.3.1(react@18.3.1))(react-is@18.3.1)(react@18.3.1)(styled-components@6.3.12(react-dom@18.3.1(react@18.3.1))(react@18.3.1)) - '@sanity/logos': 2.2.2(react@18.3.1) + '@sanity/insert-menu': 1.1.13(@emotion/is-prop-valid@1.4.0)(@sanity/types@3.99.0(@types/react@19.2.14)(debug@4.4.3))(react-dom@19.2.4(react@19.2.4))(react-is@18.3.1)(react@19.2.4)(styled-components@6.3.12(react-dom@19.2.4(react@19.2.4))(react@19.2.4)) + '@sanity/logos': 2.2.2(react@19.2.4) '@sanity/media-library-types': 1.2.0 '@sanity/message-protocol': 0.13.3 '@sanity/migrate': 3.99.0(@types/react@19.2.14) '@sanity/mutator': 3.99.0(@types/react@19.2.14) '@sanity/presentation-comlink': 1.0.33(@sanity/client@7.20.0(debug@4.4.3))(@sanity/types@3.99.0(@types/react@19.2.14)(debug@4.4.3)) - '@sanity/preview-url-secret': 2.1.16(@sanity/client@7.20.0(debug@4.4.3))(@sanity/icons@3.7.4(react@18.3.1))(sanity@3.99.0(@emotion/is-prop-valid@1.4.0)(@types/node@25.5.0)(@types/react@19.2.14)(immer@10.2.0)(jiti@2.6.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(styled-components@6.3.12(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(typescript@5.9.3)(yaml@2.8.3)) + '@sanity/preview-url-secret': 2.1.16(@sanity/client@7.20.0(debug@4.4.3))(@sanity/icons@3.7.4(react@19.2.4))(sanity@3.99.0(@emotion/is-prop-valid@1.4.0)(@types/node@25.5.0)(@types/react@19.2.14)(immer@10.2.0)(jiti@2.6.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(styled-components@6.3.12(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(typescript@5.9.3)(yaml@2.8.3)) '@sanity/schema': 3.99.0(@types/react@19.2.14)(debug@4.4.3) - '@sanity/sdk': 0.0.0-alpha.25(@types/react@19.2.14)(debug@4.4.3)(immer@10.2.0)(react@18.3.1)(use-sync-external-store@1.6.0(react@18.3.1)) - '@sanity/telemetry': 0.8.1(react@18.3.1) + '@sanity/sdk': 0.0.0-alpha.25(@types/react@19.2.14)(debug@4.4.3)(immer@10.2.0)(react@19.2.4)(use-sync-external-store@1.6.0(react@19.2.4)) + '@sanity/telemetry': 0.8.1(react@19.2.4) '@sanity/types': 3.99.0(@types/react@19.2.14)(debug@4.4.3) - '@sanity/ui': 2.16.22(@emotion/is-prop-valid@1.4.0)(react-dom@18.3.1(react@18.3.1))(react-is@18.3.1)(react@18.3.1)(styled-components@6.3.12(react-dom@18.3.1(react@18.3.1))(react@18.3.1)) + '@sanity/ui': 2.16.22(@emotion/is-prop-valid@1.4.0)(react-dom@19.2.4(react@19.2.4))(react-is@18.3.1)(react@19.2.4)(styled-components@6.3.12(react-dom@19.2.4(react@19.2.4))(react@19.2.4)) '@sanity/util': 3.99.0(@types/react@19.2.14)(debug@4.4.3) '@sanity/uuid': 3.0.2 - '@sentry/react': 8.55.1(react@18.3.1) - '@tanstack/react-table': 8.21.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@tanstack/react-virtual': 3.13.23(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@sentry/react': 8.55.1(react@19.2.4) + '@tanstack/react-table': 8.21.3(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@tanstack/react-virtual': 3.13.23(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@types/react-is': 19.2.0 '@types/shallow-equals': 1.0.3 '@types/speakingurl': 13.0.6 @@ -10614,7 +10621,7 @@ snapshots: '@types/use-sync-external-store': 1.5.0 '@types/which': 3.0.4 '@vitejs/plugin-react': 4.7.0(vite@6.4.1(@types/node@25.5.0)(jiti@2.6.1)(yaml@2.8.3)) - '@xstate/react': 6.1.0(@types/react@19.2.14)(react@18.3.1)(xstate@5.30.0) + '@xstate/react': 6.1.0(@types/react@19.2.14)(react@19.2.4)(xstate@5.30.0) archiver: 7.0.1 arrify: 2.0.1 async-mutex: 0.4.1 @@ -10633,7 +10640,7 @@ snapshots: exif-component: 1.0.1 fast-deep-equal: 3.1.3 form-data: 4.0.5 - framer-motion: 12.38.0(@emotion/is-prop-valid@1.4.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + framer-motion: 12.38.0(@emotion/is-prop-valid@1.4.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) get-it: 8.7.0(debug@4.4.3) get-random-values-esm: 1.0.2 groq-js: 1.29.0 @@ -10663,22 +10670,22 @@ snapshots: path-to-regexp: 6.3.0 peek-stream: 1.1.3 pirates: 4.0.7 - player.style: 0.1.10(react@18.3.1) + player.style: 0.1.10(react@19.2.4) pluralize-esm: 9.0.5 polished: 4.3.1 preferred-pm: 4.1.1 pretty-ms: 7.0.1 quick-lru: 5.1.1 raf: 3.4.1 - react: 18.3.1 - react-compiler-runtime: 19.1.0-rc.2(react@18.3.1) - react-dom: 18.3.1(react@18.3.1) + react: 19.2.4 + react-compiler-runtime: 19.1.0-rc.2(react@19.2.4) + react-dom: 19.2.4(react@19.2.4) react-fast-compare: 3.2.2 - react-focus-lock: 2.13.7(@types/react@19.2.14)(react@18.3.1) - react-i18next: 14.0.2(i18next@23.16.8)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react-focus-lock: 2.13.7(@types/react@19.2.14)(react@19.2.4) + react-i18next: 14.0.2(i18next@23.16.8)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) react-is: 18.3.1 - react-refractor: 2.2.0(react@18.3.1) - react-rx: 4.2.2(react@18.3.1)(rxjs@7.8.2) + react-refractor: 2.2.0(react@19.2.4) + react-rx: 4.2.2(react@19.2.4)(rxjs@7.8.2) read-pkg-up: 7.0.1 refractor: 3.6.0 resolve-from: 5.0.0 @@ -10692,15 +10699,15 @@ snapshots: semver: 7.7.4 shallow-equals: 1.0.0 speakingurl: 14.0.1 - styled-components: 6.3.12(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + styled-components: 6.3.12(react-dom@19.2.4(react@19.2.4))(react@19.2.4) tar-fs: 2.1.4 tar-stream: 3.1.8 tinyglobby: 0.2.15 urlpattern-polyfill: 10.1.0 - use-device-pixel-ratio: 1.1.2(react@18.3.1) - use-effect-event: 2.0.3(react@18.3.1) - use-hot-module-reload: 2.0.0(react@18.3.1) - use-sync-external-store: 1.6.0(react@18.3.1) + use-device-pixel-ratio: 1.1.2(react@19.2.4) + use-effect-event: 2.0.3(react@19.2.4) + use-hot-module-reload: 2.0.0(react@19.2.4) + use-sync-external-store: 1.6.0(react@19.2.4) uuid: 11.1.0 vite: 6.4.1(@types/node@25.5.0)(jiti@2.6.1)(yaml@2.8.3) which: 5.0.0 @@ -10737,9 +10744,7 @@ snapshots: dependencies: xmlchars: 2.2.0 - scheduler@0.23.2: - dependencies: - loose-envify: 1.4.0 + scheduler@0.27.0: {} scroll-into-view-if-needed@3.1.0: dependencies: @@ -10846,14 +10851,14 @@ snapshots: slate: 0.117.2 tiny-invariant: 1.3.1 - slate-react@0.117.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(slate-dom@0.116.0(slate@0.117.2))(slate@0.117.2): + slate-react@0.117.3(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(slate-dom@0.116.0(slate@0.117.2))(slate@0.117.2): dependencies: '@juggle/resize-observer': 3.4.0 direction: 1.0.4 is-hotkey: 0.2.0 lodash: 4.17.23 - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) scroll-into-view-if-needed: 3.1.0 slate: 0.117.2 slate-dom: 0.116.0(slate@0.117.2) @@ -11020,7 +11025,7 @@ snapshots: style-mod@4.1.3: {} - styled-components@6.3.12(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + styled-components@6.3.12(react-dom@19.2.4(react@19.2.4))(react@19.2.4): dependencies: '@emotion/is-prop-valid': 1.4.0 '@emotion/unitless': 0.10.0 @@ -11028,12 +11033,12 @@ snapshots: css-to-react-native: 3.2.0 csstype: 3.2.3 postcss: 8.4.49 - react: 18.3.1 + react: 19.2.4 shallowequal: 1.1.0 stylis: 4.3.6 tslib: 2.8.1 optionalDependencies: - react-dom: 18.3.1(react@18.3.1) + react-dom: 19.2.4(react@19.2.4) stylis@4.3.6: {} @@ -11326,46 +11331,46 @@ snapshots: urlpattern-polyfill@10.1.0: {} - use-callback-ref@1.3.3(@types/react@19.2.14)(react@18.3.1): + use-callback-ref@1.3.3(@types/react@19.2.14)(react@19.2.4): dependencies: - react: 18.3.1 + react: 19.2.4 tslib: 2.8.1 optionalDependencies: '@types/react': 19.2.14 - use-device-pixel-ratio@1.1.2(react@18.3.1): + use-device-pixel-ratio@1.1.2(react@19.2.4): dependencies: - react: 18.3.1 + react: 19.2.4 - use-effect-event@1.0.2(react@18.3.1): + use-effect-event@1.0.2(react@19.2.4): dependencies: - react: 18.3.1 + react: 19.2.4 - use-effect-event@2.0.3(react@18.3.1): + use-effect-event@2.0.3(react@19.2.4): dependencies: - react: 18.3.1 + react: 19.2.4 - use-hot-module-reload@2.0.0(react@18.3.1): + use-hot-module-reload@2.0.0(react@19.2.4): dependencies: - react: 18.3.1 + react: 19.2.4 - use-isomorphic-layout-effect@1.2.1(@types/react@19.2.14)(react@18.3.1): + use-isomorphic-layout-effect@1.2.1(@types/react@19.2.14)(react@19.2.4): dependencies: - react: 18.3.1 + react: 19.2.4 optionalDependencies: '@types/react': 19.2.14 - use-sidecar@1.1.3(@types/react@19.2.14)(react@18.3.1): + use-sidecar@1.1.3(@types/react@19.2.14)(react@19.2.4): dependencies: detect-node-es: 1.1.0 - react: 18.3.1 + react: 19.2.4 tslib: 2.8.1 optionalDependencies: '@types/react': 19.2.14 - use-sync-external-store@1.6.0(react@18.3.1): + use-sync-external-store@1.6.0(react@19.2.4): dependencies: - react: 18.3.1 + react: 19.2.4 util-deprecate@1.0.2: {} @@ -11593,9 +11598,9 @@ snapshots: zod@3.25.76: {} - zustand@5.0.12(@types/react@19.2.14)(immer@10.2.0)(react@18.3.1)(use-sync-external-store@1.6.0(react@18.3.1)): + zustand@5.0.12(@types/react@19.2.14)(immer@10.2.0)(react@19.2.4)(use-sync-external-store@1.6.0(react@19.2.4)): optionalDependencies: '@types/react': 19.2.14 immer: 10.2.0 - react: 18.3.1 - use-sync-external-store: 1.6.0(react@18.3.1) + react: 19.2.4 + use-sync-external-store: 1.6.0(react@19.2.4) diff --git a/sanity/sanity.config.ts b/sanity/sanity.config.ts index 1686a47..4b3127a 100644 --- a/sanity/sanity.config.ts +++ b/sanity/sanity.config.ts @@ -9,6 +9,25 @@ export default defineConfig({ projectId: 'y821x5qu', dataset: 'production', - plugins: [structureTool()], + plugins: [ + structureTool({ + structure: (S) => + S.list() + .title('Contenu') + .items([ + S.listItem() + .title('Page d\'accueil') + .id('homePage') + .child( + S.document() + .schemaType('homePage') + .documentId('homePage') + .title('Page d\'accueil') + ), + S.divider(), + S.documentTypeListItem('product').title('Produits'), + ]), + }), + ], schema: { types: schemaTypes }, }) diff --git a/sanity/schemas/homePage.ts b/sanity/schemas/homePage.ts new file mode 100644 index 0000000..dafa4fc --- /dev/null +++ b/sanity/schemas/homePage.ts @@ -0,0 +1,167 @@ +import { defineType, defineField } from 'sanity' + +export default defineType({ + name: 'homePage', + title: 'Page d\'accueil', + type: 'document', + groups: [ + { name: 'hero', title: 'Hero' }, + { name: 'collection', title: 'Collection' }, + { name: 'contact', title: 'Contact / WhatsApp' }, + { name: 'footer', title: 'Footer' }, + { name: 'seo', title: 'SEO' }, + ], + fields: [ + // ── HERO ────────────────────────────────────────────────── + defineField({ + name: 'heroLabel', + title: 'Label hero', + type: 'string', + initialValue: '// ARCHIVE_001 — 2026', + group: 'hero', + }), + defineField({ + name: 'heroTitle', + title: 'Titre hero', + type: 'string', + initialValue: 'REBOURS STUDIO', + description: 'Utiliser | pour un retour à la ligne (ex: REBOURS|STUDIO)', + group: 'hero', + validation: (rule) => rule.required(), + }), + defineField({ + name: 'heroSubtitle', + title: 'Sous-titre hero', + type: 'text', + rows: 2, + initialValue: 'Mobilier d\'art contemporain.\nSpace Age × Memphis.', + group: 'hero', + }), + defineField({ + name: 'heroStatus', + title: 'Status hero', + type: 'text', + rows: 2, + initialValue: 'STATUS: [PROTOTYPE EN COURS]\nCOLLECTION_001 — BIENTÔT DISPONIBLE', + group: 'hero', + }), + defineField({ + name: 'heroImage', + title: 'Image hero', + type: 'image', + options: { hotspot: true }, + description: 'Image principale du hero. Si vide, utilise l\'image du premier produit.', + group: 'hero', + fields: [ + defineField({ + name: 'alt', + title: 'Texte alternatif', + type: 'string', + }), + ], + }), + + // ── COLLECTION ──────────────────────────────────────────── + defineField({ + name: 'collectionLabel', + title: 'Label collection', + type: 'string', + initialValue: '// COLLECTION_001', + group: 'collection', + }), + defineField({ + name: 'collectionCta', + title: 'Texte d\'action collection', + type: 'string', + initialValue: 'CLIQUER POUR OUVRIR', + description: 'Affiché après le nombre d\'objets', + group: 'collection', + }), + + // ── CONTACT / WHATSAPP ──────────────────────────────────── + defineField({ + name: 'contactLabel', + title: 'Label contact', + type: 'string', + initialValue: '// CONTACT', + group: 'contact', + }), + defineField({ + name: 'contactTitle', + title: 'Titre contact', + type: 'string', + initialValue: 'UNE QUESTION ? PARLONS-EN', + description: 'Utiliser | pour un retour à la ligne', + group: 'contact', + }), + defineField({ + name: 'contactDescription', + title: 'Description contact', + type: 'text', + rows: 2, + initialValue: 'Commandes sur mesure, questions techniques,\nou simplement dire bonjour.', + group: 'contact', + }), + defineField({ + name: 'whatsappNumber', + title: 'Numéro WhatsApp', + type: 'string', + initialValue: '33651755191', + description: 'Format international sans + (ex: 33612345678)', + group: 'contact', + validation: (rule) => rule.required(), + }), + defineField({ + name: 'whatsappButtonText', + title: 'Texte bouton WhatsApp', + type: 'string', + initialValue: 'CONTACTEZ-NOUS SUR WHATSAPP', + group: 'contact', + }), + defineField({ + name: 'contactResponseTime', + title: 'Temps de réponse', + type: 'string', + initialValue: 'RÉPONSE SOUS 24H', + group: 'contact', + }), + + // ── FOOTER ──────────────────────────────────────────────── + defineField({ + name: 'footerText', + title: 'Texte footer', + type: 'string', + initialValue: '© 2026 REBOURS STUDIO — PARIS', + group: 'footer', + }), + defineField({ + name: 'instagramUrl', + title: 'Lien Instagram', + type: 'url', + initialValue: 'https://instagram.com/rebour.studio', + group: 'footer', + }), + + // ── SEO ─────────────────────────────────────────────────── + defineField({ + name: 'seoTitle', + title: 'Titre SEO', + type: 'string', + initialValue: 'REBOURS — Mobilier d\'art contemporain | Collection 001', + group: 'seo', + }), + defineField({ + name: 'seoDescription', + title: 'Description SEO', + type: 'text', + rows: 3, + initialValue: 'REBOURS Studio crée du mobilier d\'art contemporain inspiré du Space Age et du mouvement Memphis. Pièces uniques fabriquées à Paris. Collection 001 en cours.', + group: 'seo', + }), + ], + preview: { + prepare() { + return { title: 'Page d\'accueil' } + }, + }, +}) diff --git a/sanity/schemas/index.ts b/sanity/schemas/index.ts index d6478e5..414f465 100644 --- a/sanity/schemas/index.ts +++ b/sanity/schemas/index.ts @@ -1,3 +1,4 @@ import product from './product' +import homePage from './homePage' -export const schemaTypes = [product] +export const schemaTypes = [product, homePage] diff --git a/sanity/schemas/product.ts b/sanity/schemas/product.ts index d47b517..4fefbde 100644 --- a/sanity/schemas/product.ts +++ b/sanity/schemas/product.ts @@ -103,18 +103,24 @@ export default defineType({ rows: 4, }), defineField({ - name: 'image', - title: 'Image produit', - type: 'image', - options: { hotspot: true }, - validation: (rule) => rule.required(), - fields: [ - defineField({ - name: 'alt', - title: 'Texte alternatif', - type: 'string', - description: 'Description de l\'image pour le SEO et l\'accessibilité', - }), + name: 'images', + title: 'Images produit', + type: 'array', + description: 'La première image est utilisée comme image principale', + validation: (rule) => rule.required().min(1), + of: [ + { + type: 'image', + options: { hotspot: true }, + fields: [ + defineField({ + name: 'alt', + title: 'Texte alternatif', + type: 'string', + description: 'Description de l\'image pour le SEO et l\'accessibilité', + }), + ], + }, ], }), defineField({ @@ -174,7 +180,7 @@ export default defineType({ select: { title: 'productDisplayName', subtitle: 'type', - media: 'image', + media: 'images.0', }, }, }) diff --git a/seed-sanity-homepage.mjs b/seed-sanity-homepage.mjs new file mode 100644 index 0000000..bdda069 --- /dev/null +++ b/seed-sanity-homepage.mjs @@ -0,0 +1,54 @@ +import { createClient } from '@sanity/client' +import dotenv from 'dotenv' + +dotenv.config() + +const client = createClient({ + projectId: process.env.SANITY_PROJECT_ID, + dataset: process.env.SANITY_DATASET || 'production', + apiVersion: '2024-01-01', + useCdn: false, + token: process.env.SANITY_API_TOKEN, +}) + +const homePage = { + _id: 'homePage', + _type: 'homePage', + + // Hero + heroLabel: '// ARCHIVE_001 — 2026', + heroTitle: 'REBOURS|STUDIO', + heroSubtitle: 'Mobilier d\'art contemporain.\nSpace Age × Memphis.', + heroStatus: 'STATUS: [PROTOTYPE EN COURS]\nCOLLECTION_001 — BIENTÔT DISPONIBLE', + + // Collection + collectionLabel: '// COLLECTION_001', + collectionCta: 'CLIQUER POUR OUVRIR', + + // Contact / WhatsApp + contactLabel: '// CONTACT', + contactTitle: 'UNE QUESTION ?|PARLONS-EN', + contactDescription: 'Commandes sur mesure, questions techniques,\nou simplement dire bonjour.', + whatsappNumber: '33651755191', + whatsappButtonText: 'CONTACTEZ-NOUS SUR WHATSAPP', + contactResponseTime: 'RÉPONSE SOUS 24H', + + // Footer + footerText: '© 2026 REBOURS STUDIO — PARIS', + instagramUrl: 'https://instagram.com/rebour.studio', + + // SEO + seoTitle: 'REBOURS — Mobilier d\'art contemporain | Collection 001', + seoDescription: 'REBOURS Studio crée du mobilier d\'art contemporain inspiré du Space Age et du mouvement Memphis. Pièces uniques fabriquées à Paris. Collection 001 en cours.', +} + +async function seed() { + console.log('Creating homePage document...') + const result = await client.createOrReplace(homePage) + console.log(`✓ homePage created: ${result._id}`) +} + +seed().catch((err) => { + console.error('Error:', err.message) + process.exit(1) +}) diff --git a/server.mjs b/server.mjs index 4fd5522..fd421ee 100644 --- a/server.mjs +++ b/server.mjs @@ -71,7 +71,7 @@ app.post('/api/checkout', async (request, reply) => { description, price, currency, - "imageUrl": image.asset->url, + "imageUrl": images[0].asset->url, "slug": slug.current }`, { slug } diff --git a/src/layouts/Base.astro b/src/layouts/Base.astro index cd314b7..bd8fb6b 100644 --- a/src/layouts/Base.astro +++ b/src/layouts/Base.astro @@ -12,6 +12,8 @@ const { ogImage = 'https://rebours.studio/assets/lamp-violet.jpg', canonical = 'https://rebours.studio/', } = Astro.props; + +const cssVersion = Date.now(); --- @@ -56,7 +58,7 @@ const { - + diff --git a/src/lib/sanity.mjs b/src/lib/sanity.mjs index ee4a0bf..1f7ad7b 100644 --- a/src/lib/sanity.mjs +++ b/src/lib/sanity.mjs @@ -29,8 +29,8 @@ const PRODUCT_FIELDS = ` description, specs, notes, - image, - "imageAlt": image.alt, + images, + "imageAlt": images[0].alt, seoTitle, seoDescription, price, @@ -51,3 +51,28 @@ export async function getProductBySlug(slug) { { slug } ) } + +export async function getHomePage() { + return sanity.fetch( + `*[_type == "homePage" && _id == "homePage"][0] { + heroLabel, + heroTitle, + heroSubtitle, + heroStatus, + heroImage, + "heroImageAlt": heroImage.alt, + collectionLabel, + collectionCta, + contactLabel, + contactTitle, + contactDescription, + whatsappNumber, + whatsappButtonText, + contactResponseTime, + footerText, + instagramUrl, + seoTitle, + seoDescription + }` + ) +} diff --git a/src/pages/collection/[slug].astro b/src/pages/collection/[slug].astro index 5f97675..d8585e6 100644 --- a/src/pages/collection/[slug].astro +++ b/src/pages/collection/[slug].astro @@ -12,7 +12,7 @@ if (!product) { const name = product.name; const title = product.seoTitle || `REBOURS — ${product.productDisplayName} | Collection 001`; const description = product.seoDescription || product.description?.substring(0, 155) || ''; -const ogImage = product.image ? urlFor(product.image).width(1200).url() : ''; +const ogImage = product.images?.[0] ? urlFor(product.images[0]).width(1200).url() : ''; const productName = product.productDisplayName; const price = product.price ? String(product.price / 100) : null; const availability = product.availability || 'https://schema.org/PreOrder'; @@ -76,7 +76,10 @@ const schemaBreadcrumb = {
- Image produit REBOURS Studio + +

@@ -168,9 +171,9 @@ const schemaBreadcrumb = {

STATUS: [PROTOTYPE EN COURS]
COLLECTION_001 — BIENTÔT DISPONIBLE

- {allProducts[0]?.image && ( + {allProducts[0]?.images?.[0] && ( REBOURS — Mobilier d'art contemporain, Paris 2026 {allProducts.map((p, i) => { - const imgUrl = p.image ? urlFor(p.image).width(800).url() : ''; + const mainImg = p.images?.[0]; + const imgUrl = mainImg ? urlFor(mainImg).width(800).url() : ''; const alt = p.imageAlt || `${p.productDisplayName} — mobilier d'art contemporain, REBOURS Studio Paris`; + const allImgs = (p.images || []).map(img => ({ + url: urlFor(img).width(1200).url(), + alt: img.alt || alt, + })); return (
@@ -54,7 +80,10 @@ const schemaOrg = {
- Image produit REBOURS Studio + +

@@ -141,15 +170,15 @@ const schemaOrg = {
-

// ARCHIVE_001 — 2026

-

REBOURS
STUDIO

-

Mobilier d'art contemporain.
Space Age × Memphis.

-

STATUS: [PROTOTYPE EN COURS]
COLLECTION_001 — BIENTÔT DISPONIBLE

+

{heroLabel}

+

{heroTitleParts.map((part, i) => <>{i > 0 &&
}{part})}

+

')} /> +

')} />

REBOURS — Mobilier d'art contemporain, Paris 2026 @@ -161,14 +190,19 @@ const schemaOrg = {
-

// COLLECTION_001

- {products.length} OBJETS — CLIQUER POUR OUVRIR +

{collectionLabel}

+ {products.length} OBJETS — {collectionCta}
{products.map((p, i) => { - const imgUrl = p.image ? urlFor(p.image).width(800).url() : ''; + const mainImg = p.images?.[0]; + const imgUrl = mainImg ? urlFor(mainImg).width(800).url() : ''; const alt = p.imageAlt || `${p.productDisplayName} — mobilier d'art contemporain, REBOURS Studio Paris`; + const allImgs = (p.images || []).map(img => ({ + url: urlFor(img).width(1200).url(), + alt: img.alt || alt, + })); return (
@@ -225,9 +260,9 @@ const schemaOrg = {
- © 2026 REBOURS STUDIO — PARIS + {footerText} @@ -236,7 +271,7 @@ const schemaOrg = {
-