From d7367266fe015cd978280623b168922e957997f1 Mon Sep 17 00:00:00 2001 From: maxnorm Date: Sun, 22 Feb 2026 14:28:45 -0500 Subject: [PATCH 1/7] improve homepage header on mobile --- website/src/components/DiamondScene/index.js | 67 +++++---- .../src/components/DiamondScene/shaders.js | 8 +- website/src/css/variables.css | 4 +- website/src/hooks/useIsMobile.js | 21 +++ website/src/pages/home/HomepageHeader.js | 121 +++++++++------- .../src/pages/home/homepageHeader.module.css | 136 +++++++++++++++--- 6 files changed, 253 insertions(+), 104 deletions(-) create mode 100644 website/src/hooks/useIsMobile.js diff --git a/website/src/components/DiamondScene/index.js b/website/src/components/DiamondScene/index.js index 07b35f73..2ac230eb 100644 --- a/website/src/components/DiamondScene/index.js +++ b/website/src/components/DiamondScene/index.js @@ -4,7 +4,7 @@ import gsap from 'gsap'; import { DiamondShader, ParticleShader, FacetHighlightShader } from './shaders'; import { createDiamondGeometry, addFacetIds } from './geometry'; -export default function DiamondScene({ className, onHoverChange }) { +export default function DiamondScene({ className, onHoverChange, inline = false }) { const canvasContainerRef = useRef(null); useEffect(() => { @@ -81,34 +81,39 @@ export default function DiamondScene({ className, onHoverChange }) { diamondGroup.add(highlightMesh); diamondGroup.add(wireframe); - // PARTICLES: FLOATING WAVE (PRO GRADE - DENSE & UNORDERED) + // Inline mode: centered diamond (e.g. mobile hero) — larger for visibility + if (inline) { + diamondGroup.scale.setScalar(2); + } + + // PARTICLES: FLOATING WAVE — desktop = dense; mobile (inline) = fewer, tighter for performance and balance const particlesGeometry = new THREE.BufferGeometry(); - const countX = 200; - const countZ = 100; + const countX = inline ? 80 : 200; + const countZ = inline ? 50 : 100; const particlesCount = countX * countZ; const posArray = new Float32Array(particlesCount * 3); - - let i = 0; - const separation = 0.5; + const separation = 0.5; const offsetX = (countX * separation) / 2; const offsetZ = (countZ * separation) / 2; - for(let x = 0; x < countX; x++) { - for(let z = 0; z < countZ; z++) { + let i = 0; + for (let x = 0; x < countX; x++) { + for (let z = 0; z < countZ; z++) { posArray[i] = (x * separation) - offsetX + (Math.random() - 0.5) * separation * 0.8; - posArray[i+1] = 0; - posArray[i+2] = (z * separation) - offsetZ + (Math.random() - 0.5) * separation * 0.8; + posArray[i + 1] = 0; + posArray[i + 2] = (z * separation) - offsetZ + (Math.random() - 0.5) * separation * 0.8; i += 3; } } - + particlesGeometry.setAttribute('position', new THREE.BufferAttribute(posArray, 3)); - + const particlesMaterial = new THREE.ShaderMaterial({ uniforms: { ...ParticleShader.uniforms, uWidth: { value: countX * separation }, - uDepth: { value: countZ * separation } + uDepth: { value: countZ * separation }, + uPointSizeScale: { value: inline ? 0.5 : 1.0 } }, vertexShader: ParticleShader.vertexShader, fragmentShader: ParticleShader.fragmentShader, @@ -116,21 +121,25 @@ export default function DiamondScene({ className, onHoverChange }) { blending: THREE.AdditiveBlending, depthWrite: false }); - + const particlesMesh = new THREE.Points(particlesGeometry, particlesMaterial); - + const particlesGroup = new THREE.Group(); particlesGroup.add(particlesMesh); - - particlesGroup.position.y = -1; - particlesGroup.position.z = -1; - particlesGroup.rotation.x = 0.05; - + + particlesGroup.position.y = inline ? -1.5 : -1; + particlesGroup.position.z = inline ? -1 : -1; + particlesGroup.rotation.x = 0.05; + + if (inline) { + particlesGroup.scale.setScalar(0.7); + } + scene.add(diamondGroup); scene.add(particlesGroup); - // INITIAL POSITION - diamondGroup.position.x = window.innerWidth > 1024 ? 2.2 : 0; + // INITIAL POSITION: inline = always centered; desktop = offset right + diamondGroup.position.x = inline ? 0 : (window.innerWidth > 1024 ? 2.2 : 0); diamondGroup.position.y = 0.1; diamondGroup.rotation.x = 0.25; @@ -157,8 +166,8 @@ export default function DiamondScene({ className, onHoverChange }) { const mouse = new THREE.Vector2(-100, -100); // Start off-screen const onMouseMove = (event) => { - // Disable interaction on mobile - if (window.innerWidth <= 1024) { + // Disable interaction on mobile or when inline (small hero diamond) + if (inline || window.innerWidth <= 1024) { mouse.x = -100; mouse.y = -100; return; @@ -240,7 +249,11 @@ export default function DiamondScene({ className, onHoverChange }) { const isDesktop = window.innerWidth > 1024; - if (isDesktop) { + if (inline) { + gsap.to(diamondGroup.position, { x: 0, duration: 0.5 }); + mesh.material.opacity = 1.0; + wireframe.material.opacity = 0.25; + } else if (isDesktop) { gsap.to(diamondGroup.position, { x: 2.2, duration: 0.5 }); mesh.material.opacity = 1.0; wireframe.material.opacity = 0.2; @@ -267,7 +280,7 @@ export default function DiamondScene({ className, onHoverChange }) { particlesGeometry.dispose(); renderer.dispose(); }; - }, [onHoverChange]); // Depend on callback + }, [onHoverChange, inline]); // Depend on callback and inline return
; } diff --git a/website/src/components/DiamondScene/shaders.js b/website/src/components/DiamondScene/shaders.js index 13db4279..74982b42 100644 --- a/website/src/components/DiamondScene/shaders.js +++ b/website/src/components/DiamondScene/shaders.js @@ -186,11 +186,13 @@ export const ParticleShader = { uTime: { value: 0 }, uColor: { value: new THREE.Color('#3b82f6') }, // Blue-500 uPixelSize: { value: 2.0 }, - uWidth: { value: 100.0 } // Width of the field for wrapping + uWidth: { value: 100.0 }, // Width of the field for wrapping + uPointSizeScale: { value: 1.0 } // Scale point size (e.g. 0.5 for smaller on mobile) }, vertexShader: ` uniform float uTime; uniform float uWidth; + uniform float uPointSizeScale; varying vec3 vPos; varying float vDist; @@ -230,8 +232,8 @@ export const ParticleShader = { // Calculate distance for depth fade vDist = length(mvPosition.xyz); - // Size attenuation - Dust Size - gl_PointSize = (4.0 * 12.0) / -mvPosition.z; + // Size attenuation - Dust Size (uPointSizeScale for mobile) + gl_PointSize = (4.0 * 12.0 * uPointSizeScale) / -mvPosition.z; } `, fragmentShader: ` diff --git a/website/src/css/variables.css b/website/src/css/variables.css index 036408cb..b86dc09b 100644 --- a/website/src/css/variables.css +++ b/website/src/css/variables.css @@ -51,9 +51,9 @@ --compose-primary-500: #3b82f6; /* ifm primary */ --compose-primary-600: #2563eb; - /* Hero gradient - Blue focused */ + /* Hero gradient - Blue focused (lighter for docs title readability on white) */ --hero-gradient: linear-gradient(135deg, var(--compose-primary-500) 0%, #1e40af 100%); - --hero-gradient-alt: linear-gradient(135deg, #60a5fa 0%, var(--compose-primary-600) 100%); + --hero-gradient-alt: linear-gradient(135deg, #93c5fd 0%, #60a5fa 50%, #3b82f6 100%); /* Homepage hero tokens */ --hero-bg-start: #0f172a; diff --git a/website/src/hooks/useIsMobile.js b/website/src/hooks/useIsMobile.js new file mode 100644 index 00000000..38613eed --- /dev/null +++ b/website/src/hooks/useIsMobile.js @@ -0,0 +1,21 @@ +import { useState, useEffect } from 'react'; + +const MOBILE_BREAKPOINT = 996; + +/** + * Returns true when viewport width is at or below the mobile breakpoint (996px). + * Used to switch hero layout: full-screen diamond + side content vs. small centered diamond with content around it. + */ +export function useIsMobile() { + const [isMobile, setIsMobile] = useState(false); + + useEffect(() => { + const mql = window.matchMedia(`(max-width: ${MOBILE_BREAKPOINT}px)`); + const update = () => setIsMobile(mql.matches); + update(); + mql.addEventListener('change', update); + return () => mql.removeEventListener('change', update); + }, []); + + return isMobile; +} diff --git a/website/src/pages/home/HomepageHeader.js b/website/src/pages/home/HomepageHeader.js index d1482b22..899447b9 100644 --- a/website/src/pages/home/HomepageHeader.js +++ b/website/src/pages/home/HomepageHeader.js @@ -1,75 +1,96 @@ import React from 'react'; import clsx from 'clsx'; import Link from '@docusaurus/Link'; -import useDocusaurusContext from '@docusaurus/useDocusaurusContext'; import Heading from '@theme/Heading'; import Icon from '../../components/ui/Icon'; import styles from './homepageHeader.module.css'; import DiamondScene from '../../components/DiamondScene'; import { useFacetBadges } from '../../components/DiamondScene/useFacetBadges'; import { FacetBadge } from '../../components/DiamondScene/FacetBadge'; +import { useIsMobile } from '../../hooks/useIsMobile'; export default function HomepageHeader() { const { activeFacetName, handleHover } = useFacetBadges(); + const isMobile = useIsMobile(); + + const badgeAndTitle = ( + <> +
+ + Early Stage - Not Production Ready + +
+ + Build the future of
+ Smart Contracts +
+ + ); + + const descriptionCtaAndLinks = ( + <> +
+

+ A smart contract library for diamond-based systems. Build with an onchain standard set of facets. +

+
+
+ + Get Started + + + + Learn Core Concepts + +
+
+ + + GitHub + + + + Join Discord + + + + Contribute + +
+ + ); return ( -
- - - {/* Floating Badge for Diamond Interaction */} - +
+ {!isMobile && ( + <> + + + + )}
- -
-
-
- - Early Stage - Not Production Ready - -
- - Build the future of
- Smart Contracts -
-
-

- Compose is a smart contract library for building diamond-based systems with an onchain - standard library of facets. -

-

- Write code that's designed to be understood, maintained, and scaled. -

-
-
- - Get Started - - - - Learn Core Concepts - + +
+ {isMobile ? ( +
+
{badgeAndTitle}
+
+ +
+
{descriptionCtaAndLinks}
-
- - - GitHub - - - - Join Discord - - - - Contribute - + ) : ( +
+ {badgeAndTitle} + {descriptionCtaAndLinks}
-
+ )}
- +
diff --git a/website/src/pages/home/homepageHeader.module.css b/website/src/pages/home/homepageHeader.module.css index afcd2846..7344ffc0 100644 --- a/website/src/pages/home/homepageHeader.module.css +++ b/website/src/pages/home/homepageHeader.module.css @@ -53,6 +53,48 @@ z-index: 0; /* Behind content */ } +/* ----- Mobile: content around small centered diamond ----- */ +.heroBannerMobile { + padding: 3rem 0 6rem; + align-items: flex-start; +} + +.heroGridMobile { + display: grid; + grid-template-rows: auto auto auto; + gap: 0; + width: 100%; + max-width: 100%; + text-align: center; +} + +.heroContentTop { + margin-bottom: 0.5rem; +} + +.heroContentBottom { + margin-top: 0.5rem; +} + +.diamondSlot { + position: relative; + width: 100%; + height: 260px; + min-height: 260px; + display: flex; + align-items: center; + justify-content: center; + margin: 0.75rem 0; +} + +.diamondInline { + width: 100%; + height: 100%; + position: relative; + border-radius: 0.75rem; + overflow: hidden; +} + .heroContent { position: relative; z-index: 1; @@ -90,16 +132,14 @@ color: white; margin-bottom: 1.5rem; animation: fadeInUp var(--motion-duration-normal) var(--motion-ease-standard) 0.2s both; - text-shadow: 0 4px 12px rgba(0, 0, 0, 0.5); } .heroTitleGradient { - background: linear-gradient(135deg, #60a5fa 0%, #3b82f6 50%, #2563eb 100%); + background: linear-gradient(135deg, #3b82f6 0%, #4087F6 100%); -webkit-background-clip: text; -webkit-text-fill-color: transparent; background-clip: text; display: inline-block; - filter: drop-shadow(0 0 20px rgba(6, 37, 88, 0.6)); } .heroDescriptionWrapper { @@ -221,15 +261,10 @@ /* Responsive */ @media screen and (max-width: 1024px) { - .heroBanner { padding: 8rem 0 10rem; min-height: 80vh; } - - /* Reset canvas container on mobile */ - .canvasContainer { - /* Still absolute, but maybe we center diamond via JS */ - } + .heroBanner:not(.heroBannerMobile) { padding: 8rem 0 10rem; min-height: 80vh; } .heroContent { - text-align: center; /* Center text on mobile */ + text-align: center; margin: 0 auto; max-width: 100%; } @@ -237,13 +272,6 @@ .heroDescriptionWrapper { margin: 0 auto 1.5rem; text-align: center; - background: rgba(15, 23, 42, 0.6); - backdrop-filter: blur(12px); - -webkit-backdrop-filter: blur(12px); - border: 1px solid rgba(255, 255, 255, 0.1); - border-radius: 1rem; - padding: 1.5rem; - box-shadow: 0 4px 24px rgba(0, 0, 0, 0.2); } .heroSubtitle, .heroDescription { @@ -253,7 +281,6 @@ } .heroDescription { - /* Remove previous mobile-only styles since wrapper handles it */ background: none; backdrop-filter: none; -webkit-backdrop-filter: none; @@ -265,21 +292,86 @@ .heroLinks { justify-content: center; } } +/* Mobile grid layout uses heroBannerMobile; these refine non-mobile tablet */ @media screen and (max-width: 768px) { - .heroBanner { padding: 6rem 0 8rem; min-height: auto; } + .heroBanner:not(.heroBannerMobile) { padding: 6rem 0 8rem; min-height: auto; } .heroTitle { font-size: 2.5rem; margin-bottom: 1rem; } .heroSubtitle { font-size: 1.125rem; margin-bottom: 1rem; } .heroDescription { font-size: 1rem;} - .heroCta { flex-direction: column; gap: 0.75rem; margin-bottom: 2rem; } - .ctaButton { width: 100%; max-width: 320px; justify-content: center; } + .heroCta { flex-direction: row; flex-wrap: wrap; justify-content: center; gap: 0.75rem; margin-bottom: 2rem; } + .ctaButton { width: auto; flex: 0 1 auto; justify-content: center; } .heroLinks { flex-direction: column; gap: 0.75rem; } .heroLink { width: 100%; max-width: 320px; justify-content: center; } } + +/* Mobile-first de-clutter: smaller badge, tighter hero, compact links */ +@media screen and (max-width: 996px) { + .heroBannerMobile .badgeWrapper { + margin-bottom: 1rem; + } + .heroBannerMobile .badge { + font-size: 0.75rem; + padding: 0.5rem 1rem; + } + .heroBannerMobile .heroTitle { + font-size: 1.875rem; + margin-bottom: 0.75rem; + } + .heroBannerMobile .heroDescriptionWrapper { + margin-bottom: 1.25rem; + padding: 1rem 1.25rem; + } + .heroBannerMobile .heroSubtitle { + font-size: 1rem; + margin-bottom: 0.5rem; + } + .heroBannerMobile .heroDescription { + font-size: 0.9375rem; + } + .heroBannerMobile .heroCta { + flex-direction: row; + flex-wrap: wrap; + justify-content: center; + gap: 0.75rem; + margin-bottom: 1rem; + } + .heroBannerMobile .ctaButton { + width: auto; + flex: 0 1 auto; + justify-content: center; + padding: 0.875rem 1.5rem; + font-size: 0.9375rem; + } + .heroBannerMobile .heroLinks { + flex-direction: row; + justify-content: center; + gap: 0.5rem; + flex-wrap: wrap; + } + .heroBannerMobile .heroLink { + width: auto; + max-width: none; + padding: 0.5rem 0.75rem; + font-size: 0.8125rem; + } + .heroBannerMobile .diamondSlot { + height: 240px; + min-height: 240px; + } +} + @media screen and (max-width: 480px) { - .heroBanner { padding: 5rem 0 6rem; } + .heroBanner:not(.heroBannerMobile) { padding: 5rem 0 6rem; } .heroTitle { font-size: 2rem; } .heroSubtitle { font-size: 1rem; } .badge { font-size: 0.8125rem; padding: 0.625rem 1.25rem; } + .heroBannerMobile .heroTitle { + font-size: 1.625rem; + } + .heroBannerMobile .diamondSlot { + height: 200px; + min-height: 200px; + } } /* Theme-specific wave colors */ From 831f809db9b119b91a24b6933ac1ecb80edde97a Mon Sep 17 00:00:00 2001 From: maxnorm Date: Sun, 22 Feb 2026 14:40:57 -0500 Subject: [PATCH 2/7] fix mobile button display, rename "library" to "module" --- website/src/pages/home/CodeShowcase.js | 6 +-- .../src/pages/home/homepageHeader.module.css | 41 +++++++++++++------ 2 files changed, 32 insertions(+), 15 deletions(-) diff --git a/website/src/pages/home/CodeShowcase.js b/website/src/pages/home/CodeShowcase.js index a5045232..41294b70 100644 --- a/website/src/pages/home/CodeShowcase.js +++ b/website/src/pages/home/CodeShowcase.js @@ -11,10 +11,10 @@ export default function CodeShowcase() {
Shared Storage Architecture - Facets and Libraries Working Together + Facets and Modules Working Together

- Both facets and libraries access the same storage in your diamond. + Both facets and modules access the same storage in your diamond. Your custom facets can extend Compose functionality without inheritance.

@@ -32,7 +32,7 @@ export default function CodeShowcase() {
-

Libraries

+

Modules

Helper functions for custom facets

diff --git a/website/src/pages/home/homepageHeader.module.css b/website/src/pages/home/homepageHeader.module.css index 7344ffc0..e739021d 100644 --- a/website/src/pages/home/homepageHeader.module.css +++ b/website/src/pages/home/homepageHeader.module.css @@ -292,16 +292,16 @@ .heroLinks { justify-content: center; } } -/* Mobile grid layout uses heroBannerMobile; these refine non-mobile tablet */ +/* Mobile grid layout uses heroBannerMobile; these refine non-mobile tablet only */ @media screen and (max-width: 768px) { .heroBanner:not(.heroBannerMobile) { padding: 6rem 0 8rem; min-height: auto; } .heroTitle { font-size: 2.5rem; margin-bottom: 1rem; } .heroSubtitle { font-size: 1.125rem; margin-bottom: 1rem; } .heroDescription { font-size: 1rem;} - .heroCta { flex-direction: row; flex-wrap: wrap; justify-content: center; gap: 0.75rem; margin-bottom: 2rem; } - .ctaButton { width: auto; flex: 0 1 auto; justify-content: center; } - .heroLinks { flex-direction: column; gap: 0.75rem; } - .heroLink { width: 100%; max-width: 320px; justify-content: center; } + .heroBanner:not(.heroBannerMobile) .heroCta { flex-direction: row; flex-wrap: wrap; justify-content: center; gap: 0.75rem; margin-bottom: 2rem; } + .heroBanner:not(.heroBannerMobile) .ctaButton { width: auto; flex: 0 1 auto; justify-content: center; } + .heroBanner:not(.heroBannerMobile) .heroLinks { flex-direction: column; gap: 0.75rem; } + .heroBanner:not(.heroBannerMobile) .heroLink { width: 100%; max-width: 320px; justify-content: center; } } /* Mobile-first de-clutter: smaller badge, tighter hero, compact links */ @@ -330,23 +330,28 @@ } .heroBannerMobile .heroCta { flex-direction: row; - flex-wrap: wrap; + flex-wrap: nowrap; justify-content: center; - gap: 0.75rem; + gap: 0.5rem; margin-bottom: 1rem; } .heroBannerMobile .ctaButton { - width: auto; - flex: 0 1 auto; + flex: 1 1 auto; + min-width: 0; justify-content: center; - padding: 0.875rem 1.5rem; - font-size: 0.9375rem; + padding: 0.75rem 1rem; + font-size: 0.875rem; + gap: 0.375rem; + } + .heroBannerMobile .ctaButton svg { + width: 16px; + height: 16px; } .heroBannerMobile .heroLinks { flex-direction: row; + flex-wrap: wrap; justify-content: center; gap: 0.5rem; - flex-wrap: wrap; } .heroBannerMobile .heroLink { width: auto; @@ -368,6 +373,18 @@ .heroBannerMobile .heroTitle { font-size: 1.625rem; } + .heroBannerMobile .heroCta { + gap: 0.375rem; + } + .heroBannerMobile .ctaButton { + padding: 0.625rem 0.75rem; + font-size: 0.8125rem; + gap: 0.25rem; + } + .heroBannerMobile .ctaButton svg { + width: 14px; + height: 14px; + } .heroBannerMobile .diamondSlot { height: 200px; min-height: 200px; From 597952ef6965b24875ad1feda6c6b657599bd294 Mon Sep 17 00:00:00 2001 From: maxnorm Date: Sun, 22 Feb 2026 14:45:56 -0500 Subject: [PATCH 3/7] add max-width on buttons, update code example to Mod --- website/src/pages/home/CodeShowcase.js | 16 +++++----------- website/src/pages/home/homepageHeader.module.css | 3 +++ 2 files changed, 8 insertions(+), 11 deletions(-) diff --git a/website/src/pages/home/CodeShowcase.js b/website/src/pages/home/CodeShowcase.js index 41294b70..78a96b40 100644 --- a/website/src/pages/home/CodeShowcase.js +++ b/website/src/pages/home/CodeShowcase.js @@ -55,16 +55,11 @@ export default function CodeShowcase() {
-
- - - -
GameNFTFacet.sol
-{`// Your custom facet uses LibERC721
-import {LibERC721} from "compose/LibERC721.sol";
+{`// Your custom facet uses the ERC721 module
+import { ERC721Mod } from "compose/ERC721Mod.sol";
 
 contract GameNFTFacet {
     function mintWithGameLogic(
@@ -77,11 +72,10 @@ contract GameNFTFacet {
             "Not enough points"
         );
 
-        // Use LibERC721 - same storage!
-        LibERC721.mint(player, tokenId);
+        // Use ERC721Mod - same storage
+        ERC721Mod.mint(player, tokenId);
 
-        // Standard ERC721Facet functions
-        // work seamlessly
+        // Standard ERC721Facet functions work seamlessly
         updatePlayerStats(player);
     }
 }`}
diff --git a/website/src/pages/home/homepageHeader.module.css b/website/src/pages/home/homepageHeader.module.css
index e739021d..f451ee4d 100644
--- a/website/src/pages/home/homepageHeader.module.css
+++ b/website/src/pages/home/homepageHeader.module.css
@@ -180,6 +180,7 @@
 .ctaButton {
   display: inline-flex;
   align-items: center;
+  justify-content: center;
   gap: 0.625rem;
   padding: 1rem 2rem;
   font-size: 1rem;
@@ -190,6 +191,7 @@
   border: 2px solid transparent;
   white-space: nowrap;
   box-shadow: 0 4px 6px rgba(0,0,0,0.2);
+  max-width: 220px;
 }
 
 .ctaPrimary {
@@ -236,6 +238,7 @@
   text-decoration: none;
   transition: all 0.25s ease;
   box-shadow: 0 2px 4px rgba(0,0,0,0.2);
+  max-width: 160px;
 }
 .heroLink:hover { background: rgba(255, 255, 255, 0.08); border-color: rgba(255, 255, 255, 0.15); color: white; transform: translateY(-1px); }
 .heroLink svg { flex-shrink: 0; opacity: 0.9; }

From 08becd86d7491dbc921b6780152cc87aee826848 Mon Sep 17 00:00:00 2001
From: maxnorm 
Date: Sun, 22 Feb 2026 14:51:19 -0500
Subject: [PATCH 4/7] reduce bottom padding on header

---
 website/src/pages/home/homepageHeader.module.css | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/website/src/pages/home/homepageHeader.module.css b/website/src/pages/home/homepageHeader.module.css
index f451ee4d..f75a8fcb 100644
--- a/website/src/pages/home/homepageHeader.module.css
+++ b/website/src/pages/home/homepageHeader.module.css
@@ -55,7 +55,7 @@
 
 /* ----- Mobile: content around small centered diamond ----- */
 .heroBannerMobile {
-  padding: 3rem 0 6rem;
+  padding: 3rem 0 4rem;
   align-items: flex-start;
 }
 

From 016d4ca34be51363f21fdcf1a57def2fd1c8f4de Mon Sep 17 00:00:00 2001
From: maxnorm 
Date: Sun, 22 Feb 2026 15:07:22 -0500
Subject: [PATCH 5/7] adjust homepage card grid

---
 website/src/pages/home/statsSection.module.css | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/website/src/pages/home/statsSection.module.css b/website/src/pages/home/statsSection.module.css
index a0f3ece4..00d848a2 100644
--- a/website/src/pages/home/statsSection.module.css
+++ b/website/src/pages/home/statsSection.module.css
@@ -3,7 +3,11 @@
 .statsSection { padding: 6rem 0; background: var(--compose-bg-900); position: relative; overflow: hidden; }
 .statsSection::before { content: ''; position: absolute; inset: 0; background: radial-gradient(ellipse 60% 50% at 50% 50%, rgba(59,130,246,0.1), transparent); pointer-events: none; }
 
-.statsGrid { position: relative; display: grid; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); gap: 2rem; max-width: 1200px; margin: 0 auto; }
+/* 2 col on mobile/tablet → 4 col on desktop; never 3+1 orphan */
+.statsGrid { position: relative; display: grid; grid-template-columns: repeat(2, 1fr); gap: 2rem; max-width: 1200px; margin: 0 auto; }
+@media screen and (min-width: 960px) {
+  .statsGrid { grid-template-columns: repeat(4, 1fr); }
+}
 
 .statCard { position: relative; text-align: center; padding: 3rem 2rem; background: rgba(255,255,255,0.03); backdrop-filter: blur(12px); -webkit-backdrop-filter: blur(12px); border: 1px solid rgba(255,255,255,0.08); border-radius: 1.25rem; transition: all var(--motion-duration-normal) var(--motion-ease-standard); overflow: hidden; display: flex; flex-direction: column; align-items: center; justify-content: center; min-height: 220px; }
 .statCard::before { content: ''; position: absolute; top: 0; left: 0; right: 0; height: 3px; background: linear-gradient(90deg, #60a5fa, var(--compose-primary-500), var(--compose-primary-600)); opacity: 0; transition: opacity var(--motion-duration-normal) ease; }
@@ -18,7 +22,7 @@
 /* Responsive */
 @media screen and (max-width: 768px) {
   .statsSection { padding: 4rem 0; }
-  .statsGrid { grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); gap: 1.25rem; }
+  .statsGrid { gap: 1.25rem; }
   .statCard { padding: 2rem 1rem; }
   .statIcon { font-size: 2.5rem; margin-bottom: 1rem; }
   .statValue { font-size: 2rem; }

From 6e7acc88237a60c6658a347f4cd2f6b232cbb630 Mon Sep 17 00:00:00 2001
From: maxnorm 
Date: Sun, 22 Feb 2026 15:08:11 -0500
Subject: [PATCH 6/7] add dynamic og images

---
 website/docusaurus.config.js  |   13 +-
 website/lib/ImageRenderers.js |  117 +++
 website/package-lock.json     | 1322 ++++++++++++++++++++++++++++++++-
 website/package.json          |    4 +-
 4 files changed, 1452 insertions(+), 4 deletions(-)
 create mode 100644 website/lib/ImageRenderers.js

diff --git a/website/docusaurus.config.js b/website/docusaurus.config.js
index b88dfc94..dcf585b2 100644
--- a/website/docusaurus.config.js
+++ b/website/docusaurus.config.js
@@ -6,10 +6,12 @@
 
 import path from 'path';
 import {fileURLToPath} from 'url';
+import {createRequire} from 'module';
 import dotenv from 'dotenv';
 import {themes as prismThemes} from 'prism-react-renderer';
 
 const __dirname = path.dirname(fileURLToPath(import.meta.url));
+const require = createRequire(import.meta.url);
 
 dotenv.config();
 
@@ -294,7 +296,16 @@ const config = {
     }),
   plugins: [
     path.join(__dirname, 'plugins', 'markdown-source-docs.js'),
-    
+    [
+      '@acid-info/docusaurus-og',
+      {
+        path: './preview-images',
+        imageRenderers: {
+          'docusaurus-plugin-content-docs': require('./lib/ImageRenderers.js').docs,
+          'docusaurus-plugin-content-blog': require('./lib/ImageRenderers.js').blog,
+        },
+      },
+    ],
     process.env.POSTHOG_API_KEY && [
       "posthog-docusaurus",
       {
diff --git a/website/lib/ImageRenderers.js b/website/lib/ImageRenderers.js
new file mode 100644
index 00000000..7edbb68f
--- /dev/null
+++ b/website/lib/ImageRenderers.js
@@ -0,0 +1,117 @@
+'use strict';
+
+const fs = require('fs');
+const path = require('path');
+const React = require('react');
+
+const WIDTH = 1200;
+const HEIGHT = 630;
+
+// Inter from @fontsource (woff); Satori accepts ArrayBuffer
+const fontPath = path.join(__dirname, '../node_modules/@fontsource/inter/files/inter-latin-400-normal.woff');
+const fontData = fs.readFileSync(fontPath);
+const fontBuffer = fontPath.endsWith('.woff2')
+  ? fontData.buffer
+  : fontData; // Node Buffer works as ArrayBuffer for Satori
+
+const fontConfig = [
+  {
+    name: 'Inter',
+    data: fontBuffer,
+    weight: 400,
+    style: 'normal',
+  },
+];
+
+const options = {
+  width: WIDTH,
+  height: HEIGHT,
+  fonts: fontConfig,
+};
+
+function truncateTitle(title, maxChars = 60) {
+  if (!title || typeof title !== 'string') return 'Compose';
+  const t = title.trim();
+  if (t.length <= maxChars) return t;
+  return t.slice(0, maxChars - 3).trim() + '...';
+}
+
+function buildLayout(title, subtitle = 'Smart Contract Oriented Programming for ERC-2535 Diamonds') {
+  return React.createElement(
+    'div',
+    {
+      style: {
+        display: 'flex',
+        flexDirection: 'column',
+        width: '100%',
+        height: '100%',
+        background: 'linear-gradient(135deg, #0f172a 0%, #1e293b 100%)',
+        color: '#f8fafc',
+        fontFamily: 'Inter',
+        padding: 80,
+        justifyContent: 'center',
+      },
+    },
+    React.createElement(
+      'div',
+      {
+        style: {
+          fontSize: 28,
+          marginBottom: 24,
+          opacity: 0.9,
+        },
+      },
+      'Compose'
+    ),
+    React.createElement(
+      'div',
+      {
+        style: {
+          fontSize: 56,
+          fontWeight: 700,
+          lineHeight: 1.2,
+          marginBottom: 16,
+        },
+      },
+      truncateTitle(title)
+    ),
+    subtitle
+      ? React.createElement(
+          'div',
+          {
+            style: {
+              fontSize: 24,
+              opacity: 0.85,
+              lineHeight: 1.4,
+              maxWidth: 900,
+            },
+          },
+          typeof subtitle === 'string' && subtitle.length > 120 ? subtitle.slice(0, 120) + '...' : subtitle
+        )
+      : null
+  );
+}
+
+/**
+ * Docs image renderer. Receives { metadata, version, plugin, document, websiteOutDir }, context.
+ */
+function docs(data, context) {
+  const title = data.metadata?.title ?? 'Compose';
+  const description = data.metadata?.description ?? null;
+  return [buildLayout(title, description), options];
+}
+
+/**
+ * Blog image renderer. Receives { data, plugin, pageType, permalink, document, websiteOutDir }, context.
+ * Only meaningful for pageType 'post'; list/tags/archive may use default or skip.
+ */
+function blog(data, context) {
+  const isPost = data.pageType === 'post';
+  const title = isPost
+    ? (data.data?.metadata?.title ?? data.data?.title ?? 'Compose')
+    : (data.data?.label ?? data.data?.title ?? 'Blog');
+  const description = isPost && data.data?.metadata?.description ? data.data.metadata.description : null;
+  return [buildLayout(title, description), options];
+}
+
+module.exports = { docs, blog };
diff --git a/website/package-lock.json b/website/package-lock.json
index 665162cd..6a2f9a72 100644
--- a/website/package-lock.json
+++ b/website/package-lock.json
@@ -8,6 +8,7 @@
       "name": "Compose Documentation",
       "version": "0.0.0",
       "dependencies": {
+        "@acid-info/docusaurus-og": "^1.0.3-beta.2",
         "@docusaurus/core": "3.9.2",
         "@docusaurus/preset-classic": "3.9.2",
         "@docusaurus/theme-mermaid": "^3.9.2",
@@ -26,10 +27,512 @@
       },
       "devDependencies": {
         "@docusaurus/module-type-aliases": "3.9.2",
-        "@docusaurus/types": "3.9.2"
+        "@docusaurus/types": "3.9.2",
+        "@fontsource/inter": "^5.2.8"
+      },
+      "engines": {
+        "node": ">=20.0"
+      }
+    },
+    "node_modules/@acid-info/docusaurus-og": {
+      "version": "1.0.3-beta.2",
+      "resolved": "https://registry.npmjs.org/@acid-info/docusaurus-og/-/docusaurus-og-1.0.3-beta.2.tgz",
+      "integrity": "sha512-clVVnLTcPGi073381+hVCC6x/HSQndCs+kSJ4+98akg2NAQkZkweGHvRdgDv66jdKADe9h+K3f3hF6Rdn7jntQ==",
+      "license": "MIT",
+      "dependencies": {
+        "@docusaurus/core": "3.8.1",
+        "@docusaurus/module-type-aliases": "3.8.1",
+        "@docusaurus/types": "3.8.1",
+        "@docusaurus/utils": "3.8.1",
+        "@docusaurus/utils-common": "3.8.1",
+        "@docusaurus/utils-validation": "3.8.1",
+        "lodash": "^4.17.21",
+        "node-html-parser": "^6.1.5",
+        "object-hash": "^3.0.0",
+        "satori": "^0.10.1",
+        "sharp": "^0.32.1"
+      },
+      "engines": {
+        "node": ">=20.0"
+      }
+    },
+    "node_modules/@acid-info/docusaurus-og/node_modules/@docusaurus/babel": {
+      "version": "3.8.1",
+      "resolved": "https://registry.npmjs.org/@docusaurus/babel/-/babel-3.8.1.tgz",
+      "integrity": "sha512-3brkJrml8vUbn9aeoZUlJfsI/GqyFcDgQJwQkmBtclJgWDEQBKKeagZfOgx0WfUQhagL1sQLNW0iBdxnI863Uw==",
+      "license": "MIT",
+      "dependencies": {
+        "@babel/core": "^7.25.9",
+        "@babel/generator": "^7.25.9",
+        "@babel/plugin-syntax-dynamic-import": "^7.8.3",
+        "@babel/plugin-transform-runtime": "^7.25.9",
+        "@babel/preset-env": "^7.25.9",
+        "@babel/preset-react": "^7.25.9",
+        "@babel/preset-typescript": "^7.25.9",
+        "@babel/runtime": "^7.25.9",
+        "@babel/runtime-corejs3": "^7.25.9",
+        "@babel/traverse": "^7.25.9",
+        "@docusaurus/logger": "3.8.1",
+        "@docusaurus/utils": "3.8.1",
+        "babel-plugin-dynamic-import-node": "^2.3.3",
+        "fs-extra": "^11.1.1",
+        "tslib": "^2.6.0"
+      },
+      "engines": {
+        "node": ">=18.0"
+      }
+    },
+    "node_modules/@acid-info/docusaurus-og/node_modules/@docusaurus/bundler": {
+      "version": "3.8.1",
+      "resolved": "https://registry.npmjs.org/@docusaurus/bundler/-/bundler-3.8.1.tgz",
+      "integrity": "sha512-/z4V0FRoQ0GuSLToNjOSGsk6m2lQUG4FRn8goOVoZSRsTrU8YR2aJacX5K3RG18EaX9b+52pN4m1sL3MQZVsQA==",
+      "license": "MIT",
+      "dependencies": {
+        "@babel/core": "^7.25.9",
+        "@docusaurus/babel": "3.8.1",
+        "@docusaurus/cssnano-preset": "3.8.1",
+        "@docusaurus/logger": "3.8.1",
+        "@docusaurus/types": "3.8.1",
+        "@docusaurus/utils": "3.8.1",
+        "babel-loader": "^9.2.1",
+        "clean-css": "^5.3.3",
+        "copy-webpack-plugin": "^11.0.0",
+        "css-loader": "^6.11.0",
+        "css-minimizer-webpack-plugin": "^5.0.1",
+        "cssnano": "^6.1.2",
+        "file-loader": "^6.2.0",
+        "html-minifier-terser": "^7.2.0",
+        "mini-css-extract-plugin": "^2.9.2",
+        "null-loader": "^4.0.1",
+        "postcss": "^8.5.4",
+        "postcss-loader": "^7.3.4",
+        "postcss-preset-env": "^10.2.1",
+        "terser-webpack-plugin": "^5.3.9",
+        "tslib": "^2.6.0",
+        "url-loader": "^4.1.1",
+        "webpack": "^5.95.0",
+        "webpackbar": "^6.0.1"
+      },
+      "engines": {
+        "node": ">=18.0"
+      },
+      "peerDependencies": {
+        "@docusaurus/faster": "*"
+      },
+      "peerDependenciesMeta": {
+        "@docusaurus/faster": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/@acid-info/docusaurus-og/node_modules/@docusaurus/core": {
+      "version": "3.8.1",
+      "resolved": "https://registry.npmjs.org/@docusaurus/core/-/core-3.8.1.tgz",
+      "integrity": "sha512-ENB01IyQSqI2FLtOzqSI3qxG2B/jP4gQPahl2C3XReiLebcVh5B5cB9KYFvdoOqOWPyr5gXK4sjgTKv7peXCrA==",
+      "license": "MIT",
+      "dependencies": {
+        "@docusaurus/babel": "3.8.1",
+        "@docusaurus/bundler": "3.8.1",
+        "@docusaurus/logger": "3.8.1",
+        "@docusaurus/mdx-loader": "3.8.1",
+        "@docusaurus/utils": "3.8.1",
+        "@docusaurus/utils-common": "3.8.1",
+        "@docusaurus/utils-validation": "3.8.1",
+        "boxen": "^6.2.1",
+        "chalk": "^4.1.2",
+        "chokidar": "^3.5.3",
+        "cli-table3": "^0.6.3",
+        "combine-promises": "^1.1.0",
+        "commander": "^5.1.0",
+        "core-js": "^3.31.1",
+        "detect-port": "^1.5.1",
+        "escape-html": "^1.0.3",
+        "eta": "^2.2.0",
+        "eval": "^0.1.8",
+        "execa": "5.1.1",
+        "fs-extra": "^11.1.1",
+        "html-tags": "^3.3.1",
+        "html-webpack-plugin": "^5.6.0",
+        "leven": "^3.1.0",
+        "lodash": "^4.17.21",
+        "open": "^8.4.0",
+        "p-map": "^4.0.0",
+        "prompts": "^2.4.2",
+        "react-helmet-async": "npm:@slorber/react-helmet-async@1.3.0",
+        "react-loadable": "npm:@docusaurus/react-loadable@6.0.0",
+        "react-loadable-ssr-addon-v5-slorber": "^1.0.1",
+        "react-router": "^5.3.4",
+        "react-router-config": "^5.1.1",
+        "react-router-dom": "^5.3.4",
+        "semver": "^7.5.4",
+        "serve-handler": "^6.1.6",
+        "tinypool": "^1.0.2",
+        "tslib": "^2.6.0",
+        "update-notifier": "^6.0.2",
+        "webpack": "^5.95.0",
+        "webpack-bundle-analyzer": "^4.10.2",
+        "webpack-dev-server": "^4.15.2",
+        "webpack-merge": "^6.0.1"
+      },
+      "bin": {
+        "docusaurus": "bin/docusaurus.mjs"
+      },
+      "engines": {
+        "node": ">=18.0"
+      },
+      "peerDependencies": {
+        "@mdx-js/react": "^3.0.0",
+        "react": "^18.0.0 || ^19.0.0",
+        "react-dom": "^18.0.0 || ^19.0.0"
+      }
+    },
+    "node_modules/@acid-info/docusaurus-og/node_modules/@docusaurus/cssnano-preset": {
+      "version": "3.8.1",
+      "resolved": "https://registry.npmjs.org/@docusaurus/cssnano-preset/-/cssnano-preset-3.8.1.tgz",
+      "integrity": "sha512-G7WyR2N6SpyUotqhGznERBK+x84uyhfMQM2MmDLs88bw4Flom6TY46HzkRkSEzaP9j80MbTN8naiL1fR17WQug==",
+      "license": "MIT",
+      "dependencies": {
+        "cssnano-preset-advanced": "^6.1.2",
+        "postcss": "^8.5.4",
+        "postcss-sort-media-queries": "^5.2.0",
+        "tslib": "^2.6.0"
+      },
+      "engines": {
+        "node": ">=18.0"
+      }
+    },
+    "node_modules/@acid-info/docusaurus-og/node_modules/@docusaurus/logger": {
+      "version": "3.8.1",
+      "resolved": "https://registry.npmjs.org/@docusaurus/logger/-/logger-3.8.1.tgz",
+      "integrity": "sha512-2wjeGDhKcExEmjX8k1N/MRDiPKXGF2Pg+df/bDDPnnJWHXnVEZxXj80d6jcxp1Gpnksl0hF8t/ZQw9elqj2+ww==",
+      "license": "MIT",
+      "dependencies": {
+        "chalk": "^4.1.2",
+        "tslib": "^2.6.0"
+      },
+      "engines": {
+        "node": ">=18.0"
+      }
+    },
+    "node_modules/@acid-info/docusaurus-og/node_modules/@docusaurus/mdx-loader": {
+      "version": "3.8.1",
+      "resolved": "https://registry.npmjs.org/@docusaurus/mdx-loader/-/mdx-loader-3.8.1.tgz",
+      "integrity": "sha512-DZRhagSFRcEq1cUtBMo4TKxSNo/W6/s44yhr8X+eoXqCLycFQUylebOMPseHi5tc4fkGJqwqpWJLz6JStU9L4w==",
+      "license": "MIT",
+      "dependencies": {
+        "@docusaurus/logger": "3.8.1",
+        "@docusaurus/utils": "3.8.1",
+        "@docusaurus/utils-validation": "3.8.1",
+        "@mdx-js/mdx": "^3.0.0",
+        "@slorber/remark-comment": "^1.0.0",
+        "escape-html": "^1.0.3",
+        "estree-util-value-to-estree": "^3.0.1",
+        "file-loader": "^6.2.0",
+        "fs-extra": "^11.1.1",
+        "image-size": "^2.0.2",
+        "mdast-util-mdx": "^3.0.0",
+        "mdast-util-to-string": "^4.0.0",
+        "rehype-raw": "^7.0.0",
+        "remark-directive": "^3.0.0",
+        "remark-emoji": "^4.0.0",
+        "remark-frontmatter": "^5.0.0",
+        "remark-gfm": "^4.0.0",
+        "stringify-object": "^3.3.0",
+        "tslib": "^2.6.0",
+        "unified": "^11.0.3",
+        "unist-util-visit": "^5.0.0",
+        "url-loader": "^4.1.1",
+        "vfile": "^6.0.1",
+        "webpack": "^5.88.1"
+      },
+      "engines": {
+        "node": ">=18.0"
+      },
+      "peerDependencies": {
+        "react": "^18.0.0 || ^19.0.0",
+        "react-dom": "^18.0.0 || ^19.0.0"
+      }
+    },
+    "node_modules/@acid-info/docusaurus-og/node_modules/@docusaurus/module-type-aliases": {
+      "version": "3.8.1",
+      "resolved": "https://registry.npmjs.org/@docusaurus/module-type-aliases/-/module-type-aliases-3.8.1.tgz",
+      "integrity": "sha512-6xhvAJiXzsaq3JdosS7wbRt/PwEPWHr9eM4YNYqVlbgG1hSK3uQDXTVvQktasp3VO6BmfYWPozueLWuj4gB+vg==",
+      "license": "MIT",
+      "dependencies": {
+        "@docusaurus/types": "3.8.1",
+        "@types/history": "^4.7.11",
+        "@types/react": "*",
+        "@types/react-router-config": "*",
+        "@types/react-router-dom": "*",
+        "react-helmet-async": "npm:@slorber/react-helmet-async@1.3.0",
+        "react-loadable": "npm:@docusaurus/react-loadable@6.0.0"
+      },
+      "peerDependencies": {
+        "react": "*",
+        "react-dom": "*"
+      }
+    },
+    "node_modules/@acid-info/docusaurus-og/node_modules/@docusaurus/types": {
+      "version": "3.8.1",
+      "resolved": "https://registry.npmjs.org/@docusaurus/types/-/types-3.8.1.tgz",
+      "integrity": "sha512-ZPdW5AB+pBjiVrcLuw3dOS6BFlrG0XkS2lDGsj8TizcnREQg3J8cjsgfDviszOk4CweNfwo1AEELJkYaMUuOPg==",
+      "license": "MIT",
+      "dependencies": {
+        "@mdx-js/mdx": "^3.0.0",
+        "@types/history": "^4.7.11",
+        "@types/react": "*",
+        "commander": "^5.1.0",
+        "joi": "^17.9.2",
+        "react-helmet-async": "npm:@slorber/react-helmet-async@1.3.0",
+        "utility-types": "^3.10.0",
+        "webpack": "^5.95.0",
+        "webpack-merge": "^5.9.0"
+      },
+      "peerDependencies": {
+        "react": "^18.0.0 || ^19.0.0",
+        "react-dom": "^18.0.0 || ^19.0.0"
+      }
+    },
+    "node_modules/@acid-info/docusaurus-og/node_modules/@docusaurus/types/node_modules/webpack-merge": {
+      "version": "5.10.0",
+      "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-5.10.0.tgz",
+      "integrity": "sha512-+4zXKdx7UnO+1jaN4l2lHVD+mFvnlZQP/6ljaJVb4SZiwIKeUnrT5l0gkT8z+n4hKpC+jpOv6O9R+gLtag7pSA==",
+      "license": "MIT",
+      "dependencies": {
+        "clone-deep": "^4.0.1",
+        "flat": "^5.0.2",
+        "wildcard": "^2.0.0"
+      },
+      "engines": {
+        "node": ">=10.0.0"
+      }
+    },
+    "node_modules/@acid-info/docusaurus-og/node_modules/@docusaurus/utils": {
+      "version": "3.8.1",
+      "resolved": "https://registry.npmjs.org/@docusaurus/utils/-/utils-3.8.1.tgz",
+      "integrity": "sha512-P1ml0nvOmEFdmu0smSXOqTS1sxU5tqvnc0dA4MTKV39kye+bhQnjkIKEE18fNOvxjyB86k8esoCIFM3x4RykOQ==",
+      "license": "MIT",
+      "dependencies": {
+        "@docusaurus/logger": "3.8.1",
+        "@docusaurus/types": "3.8.1",
+        "@docusaurus/utils-common": "3.8.1",
+        "escape-string-regexp": "^4.0.0",
+        "execa": "5.1.1",
+        "file-loader": "^6.2.0",
+        "fs-extra": "^11.1.1",
+        "github-slugger": "^1.5.0",
+        "globby": "^11.1.0",
+        "gray-matter": "^4.0.3",
+        "jiti": "^1.20.0",
+        "js-yaml": "^4.1.0",
+        "lodash": "^4.17.21",
+        "micromatch": "^4.0.5",
+        "p-queue": "^6.6.2",
+        "prompts": "^2.4.2",
+        "resolve-pathname": "^3.0.0",
+        "tslib": "^2.6.0",
+        "url-loader": "^4.1.1",
+        "utility-types": "^3.10.0",
+        "webpack": "^5.88.1"
+      },
+      "engines": {
+        "node": ">=18.0"
+      }
+    },
+    "node_modules/@acid-info/docusaurus-og/node_modules/@docusaurus/utils-common": {
+      "version": "3.8.1",
+      "resolved": "https://registry.npmjs.org/@docusaurus/utils-common/-/utils-common-3.8.1.tgz",
+      "integrity": "sha512-zTZiDlvpvoJIrQEEd71c154DkcriBecm4z94OzEE9kz7ikS3J+iSlABhFXM45mZ0eN5pVqqr7cs60+ZlYLewtg==",
+      "license": "MIT",
+      "dependencies": {
+        "@docusaurus/types": "3.8.1",
+        "tslib": "^2.6.0"
+      },
+      "engines": {
+        "node": ">=18.0"
+      }
+    },
+    "node_modules/@acid-info/docusaurus-og/node_modules/@docusaurus/utils-validation": {
+      "version": "3.8.1",
+      "resolved": "https://registry.npmjs.org/@docusaurus/utils-validation/-/utils-validation-3.8.1.tgz",
+      "integrity": "sha512-gs5bXIccxzEbyVecvxg6upTwaUbfa0KMmTj7HhHzc016AGyxH2o73k1/aOD0IFrdCsfJNt37MqNI47s2MgRZMA==",
+      "license": "MIT",
+      "dependencies": {
+        "@docusaurus/logger": "3.8.1",
+        "@docusaurus/utils": "3.8.1",
+        "@docusaurus/utils-common": "3.8.1",
+        "fs-extra": "^11.2.0",
+        "joi": "^17.9.2",
+        "js-yaml": "^4.1.0",
+        "lodash": "^4.17.21",
+        "tslib": "^2.6.0"
+      },
+      "engines": {
+        "node": ">=18.0"
+      }
+    },
+    "node_modules/@acid-info/docusaurus-og/node_modules/@types/retry": {
+      "version": "0.12.0",
+      "resolved": "https://registry.npmjs.org/@types/retry/-/retry-0.12.0.tgz",
+      "integrity": "sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA==",
+      "license": "MIT"
+    },
+    "node_modules/@acid-info/docusaurus-og/node_modules/memfs": {
+      "version": "3.5.3",
+      "resolved": "https://registry.npmjs.org/memfs/-/memfs-3.5.3.tgz",
+      "integrity": "sha512-UERzLsxzllchadvbPs5aolHh65ISpKpM+ccLbOJ8/vvpBKmAWf+la7dXFy7Mr0ySHbdHrFv5kGFCUHHe6GFEmw==",
+      "license": "Unlicense",
+      "dependencies": {
+        "fs-monkey": "^1.0.4"
+      },
+      "engines": {
+        "node": ">= 4.0.0"
+      }
+    },
+    "node_modules/@acid-info/docusaurus-og/node_modules/mime-db": {
+      "version": "1.52.0",
+      "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
+      "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
+      "license": "MIT",
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/@acid-info/docusaurus-og/node_modules/mime-types": {
+      "version": "2.1.35",
+      "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
+      "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
+      "license": "MIT",
+      "dependencies": {
+        "mime-db": "1.52.0"
+      },
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/@acid-info/docusaurus-og/node_modules/p-retry": {
+      "version": "4.6.2",
+      "resolved": "https://registry.npmjs.org/p-retry/-/p-retry-4.6.2.tgz",
+      "integrity": "sha512-312Id396EbJdvRONlngUx0NydfrIQ5lsYu0znKVUzVvArzEIt08V1qhtyESbGVd1FGX7UKtiFp5uwKZdM8wIuQ==",
+      "license": "MIT",
+      "dependencies": {
+        "@types/retry": "0.12.0",
+        "retry": "^0.13.1"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/@acid-info/docusaurus-og/node_modules/range-parser": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
+      "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==",
+      "license": "MIT",
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/@acid-info/docusaurus-og/node_modules/webpack-dev-middleware": {
+      "version": "5.3.4",
+      "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-5.3.4.tgz",
+      "integrity": "sha512-BVdTqhhs+0IfoeAf7EoH5WE+exCmqGerHfDM0IL096Px60Tq2Mn9MAbnaGUe6HiMa41KMCYF19gyzZmBcq/o4Q==",
+      "license": "MIT",
+      "dependencies": {
+        "colorette": "^2.0.10",
+        "memfs": "^3.4.3",
+        "mime-types": "^2.1.31",
+        "range-parser": "^1.2.1",
+        "schema-utils": "^4.0.0"
       },
       "engines": {
-        "node": ">=20.0"
+        "node": ">= 12.13.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/webpack"
+      },
+      "peerDependencies": {
+        "webpack": "^4.0.0 || ^5.0.0"
+      }
+    },
+    "node_modules/@acid-info/docusaurus-og/node_modules/webpack-dev-server": {
+      "version": "4.15.2",
+      "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-4.15.2.tgz",
+      "integrity": "sha512-0XavAZbNJ5sDrCbkpWL8mia0o5WPOd2YGtxrEiZkBK9FjLppIUK2TgxK6qGD2P3hUXTJNNPVibrerKcx5WkR1g==",
+      "license": "MIT",
+      "dependencies": {
+        "@types/bonjour": "^3.5.9",
+        "@types/connect-history-api-fallback": "^1.3.5",
+        "@types/express": "^4.17.13",
+        "@types/serve-index": "^1.9.1",
+        "@types/serve-static": "^1.13.10",
+        "@types/sockjs": "^0.3.33",
+        "@types/ws": "^8.5.5",
+        "ansi-html-community": "^0.0.8",
+        "bonjour-service": "^1.0.11",
+        "chokidar": "^3.5.3",
+        "colorette": "^2.0.10",
+        "compression": "^1.7.4",
+        "connect-history-api-fallback": "^2.0.0",
+        "default-gateway": "^6.0.3",
+        "express": "^4.17.3",
+        "graceful-fs": "^4.2.6",
+        "html-entities": "^2.3.2",
+        "http-proxy-middleware": "^2.0.3",
+        "ipaddr.js": "^2.0.1",
+        "launch-editor": "^2.6.0",
+        "open": "^8.0.9",
+        "p-retry": "^4.5.0",
+        "rimraf": "^3.0.2",
+        "schema-utils": "^4.0.0",
+        "selfsigned": "^2.1.1",
+        "serve-index": "^1.9.1",
+        "sockjs": "^0.3.24",
+        "spdy": "^4.0.2",
+        "webpack-dev-middleware": "^5.3.4",
+        "ws": "^8.13.0"
+      },
+      "bin": {
+        "webpack-dev-server": "bin/webpack-dev-server.js"
+      },
+      "engines": {
+        "node": ">= 12.13.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/webpack"
+      },
+      "peerDependencies": {
+        "webpack": "^4.37.0 || ^5.0.0"
+      },
+      "peerDependenciesMeta": {
+        "webpack": {
+          "optional": true
+        },
+        "webpack-cli": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/@acid-info/docusaurus-og/node_modules/ws": {
+      "version": "8.19.0",
+      "resolved": "https://registry.npmjs.org/ws/-/ws-8.19.0.tgz",
+      "integrity": "sha512-blAT2mjOEIi0ZzruJfIhb3nps74PRWTCz1IjglWEEpQl5XS/UNama6u2/rjFkDDouqr4L67ry+1aGIALViWjDg==",
+      "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/@ai-sdk/gateway": {
@@ -4120,6 +4623,16 @@
         "node": ">=20.0"
       }
     },
+    "node_modules/@fontsource/inter": {
+      "version": "5.2.8",
+      "resolved": "https://registry.npmjs.org/@fontsource/inter/-/inter-5.2.8.tgz",
+      "integrity": "sha512-P6r5WnJoKiNVV+zvW2xM13gNdFhAEpQ9dQJHt3naLvfg+LkF2ldgSLiF4T41lf1SQCM9QmkqPTn4TH568IRagg==",
+      "dev": true,
+      "license": "OFL-1.1",
+      "funding": {
+        "url": "https://github.com/sponsors/ayuhito"
+      }
+    },
     "node_modules/@giscus/react": {
       "version": "3.1.0",
       "resolved": "https://registry.npmjs.org/@giscus/react/-/react-3.1.0.tgz",
@@ -4542,6 +5055,22 @@
       "integrity": "sha512-wwQAWhWSuHaag8c4q/KN/vCoeOJYshAIvMQwD4GpSb3OiZklFfvAgmj0VCBBImRpuF/aFgIRzllXlVX93Jevww==",
       "license": "MIT"
     },
+    "node_modules/@shuding/opentype.js": {
+      "version": "1.4.0-beta.0",
+      "resolved": "https://registry.npmjs.org/@shuding/opentype.js/-/opentype.js-1.4.0-beta.0.tgz",
+      "integrity": "sha512-3NgmNyH3l/Hv6EvsWJbsvpcpUba6R8IREQ83nH83cyakCw7uM1arZKNfHwv1Wz6jgqrF/j4x5ELvR6PnK9nTcA==",
+      "license": "MIT",
+      "dependencies": {
+        "fflate": "^0.7.3",
+        "string.prototype.codepointat": "^0.2.1"
+      },
+      "bin": {
+        "ot": "bin/ot"
+      },
+      "engines": {
+        "node": ">= 8.0.0"
+      }
+    },
     "node_modules/@sideway/address": {
       "version": "4.1.5",
       "resolved": "https://registry.npmjs.org/@sideway/address/-/address-4.1.5.tgz",
@@ -6083,6 +6612,20 @@
         "postcss": "^8.1.0"
       }
     },
+    "node_modules/b4a": {
+      "version": "1.8.0",
+      "resolved": "https://registry.npmjs.org/b4a/-/b4a-1.8.0.tgz",
+      "integrity": "sha512-qRuSmNSkGQaHwNbM7J78Wwy+ghLEYF1zNrSeMxj4Kgw6y33O3mXcQ6Ie9fRvfU/YnxWkOchPXbaLb73TkIsfdg==",
+      "license": "Apache-2.0",
+      "peerDependencies": {
+        "react-native-b4a": "*"
+      },
+      "peerDependenciesMeta": {
+        "react-native-b4a": {
+          "optional": true
+        }
+      }
+    },
     "node_modules/babel-loader": {
       "version": "9.2.1",
       "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-9.2.1.tgz",
@@ -6173,6 +6716,107 @@
       "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
       "license": "MIT"
     },
+    "node_modules/bare-events": {
+      "version": "2.8.2",
+      "resolved": "https://registry.npmjs.org/bare-events/-/bare-events-2.8.2.tgz",
+      "integrity": "sha512-riJjyv1/mHLIPX4RwiK+oW9/4c3TEUeORHKefKAKnZ5kyslbN+HXowtbaVEqt4IMUB7OXlfixcs6gsFeo/jhiQ==",
+      "license": "Apache-2.0",
+      "peerDependencies": {
+        "bare-abort-controller": "*"
+      },
+      "peerDependenciesMeta": {
+        "bare-abort-controller": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/bare-fs": {
+      "version": "4.5.4",
+      "resolved": "https://registry.npmjs.org/bare-fs/-/bare-fs-4.5.4.tgz",
+      "integrity": "sha512-POK4oplfA7P7gqvetNmCs4CNtm9fNsx+IAh7jH7GgU0OJdge2rso0R20TNWVq6VoWcCvsTdlNDaleLHGaKx8CA==",
+      "license": "Apache-2.0",
+      "optional": true,
+      "dependencies": {
+        "bare-events": "^2.5.4",
+        "bare-path": "^3.0.0",
+        "bare-stream": "^2.6.4",
+        "bare-url": "^2.2.2",
+        "fast-fifo": "^1.3.2"
+      },
+      "engines": {
+        "bare": ">=1.16.0"
+      },
+      "peerDependencies": {
+        "bare-buffer": "*"
+      },
+      "peerDependenciesMeta": {
+        "bare-buffer": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/bare-os": {
+      "version": "3.6.2",
+      "resolved": "https://registry.npmjs.org/bare-os/-/bare-os-3.6.2.tgz",
+      "integrity": "sha512-T+V1+1srU2qYNBmJCXZkUY5vQ0B4FSlL3QDROnKQYOqeiQR8UbjNHlPa+TIbM4cuidiN9GaTaOZgSEgsvPbh5A==",
+      "license": "Apache-2.0",
+      "optional": true,
+      "engines": {
+        "bare": ">=1.14.0"
+      }
+    },
+    "node_modules/bare-path": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/bare-path/-/bare-path-3.0.0.tgz",
+      "integrity": "sha512-tyfW2cQcB5NN8Saijrhqn0Zh7AnFNsnczRcuWODH0eYAXBsJ5gVxAUuNr7tsHSC6IZ77cA0SitzT+s47kot8Mw==",
+      "license": "Apache-2.0",
+      "optional": true,
+      "dependencies": {
+        "bare-os": "^3.0.1"
+      }
+    },
+    "node_modules/bare-stream": {
+      "version": "2.8.0",
+      "resolved": "https://registry.npmjs.org/bare-stream/-/bare-stream-2.8.0.tgz",
+      "integrity": "sha512-reUN0M2sHRqCdG4lUK3Fw8w98eeUIZHL5c3H7Mbhk2yVBL+oofgaIp0ieLfD5QXwPCypBpmEEKU2WZKzbAk8GA==",
+      "license": "Apache-2.0",
+      "optional": true,
+      "dependencies": {
+        "streamx": "^2.21.0",
+        "teex": "^1.0.1"
+      },
+      "peerDependencies": {
+        "bare-buffer": "*",
+        "bare-events": "*"
+      },
+      "peerDependenciesMeta": {
+        "bare-buffer": {
+          "optional": true
+        },
+        "bare-events": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/bare-url": {
+      "version": "2.3.2",
+      "resolved": "https://registry.npmjs.org/bare-url/-/bare-url-2.3.2.tgz",
+      "integrity": "sha512-ZMq4gd9ngV5aTMa5p9+UfY0b3skwhHELaDkhEHetMdX0LRkW9kzaym4oo/Eh+Ghm0CCDuMTsRIGM/ytUc1ZYmw==",
+      "license": "Apache-2.0",
+      "optional": true,
+      "dependencies": {
+        "bare-path": "^3.0.0"
+      }
+    },
+    "node_modules/base64-js": {
+      "version": "0.0.8",
+      "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-0.0.8.tgz",
+      "integrity": "sha512-3XSA2cR/h/73EzlXXdU6YNycmYI7+kicTxks4eJg2g39biHR84slg2+des+p7iHYhbRg/udIS4TD53WabcOUkw==",
+      "license": "MIT",
+      "engines": {
+        "node": ">= 0.4"
+      }
+    },
     "node_modules/baseline-browser-mapping": {
       "version": "2.8.25",
       "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.8.25.tgz",
@@ -6209,6 +6853,17 @@
         "url": "https://github.com/sponsors/sindresorhus"
       }
     },
+    "node_modules/bl": {
+      "version": "4.1.0",
+      "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz",
+      "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==",
+      "license": "MIT",
+      "dependencies": {
+        "buffer": "^5.5.0",
+        "inherits": "^2.0.4",
+        "readable-stream": "^3.4.0"
+      }
+    },
     "node_modules/body-parser": {
       "version": "1.20.3",
       "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.3.tgz",
@@ -6350,12 +7005,56 @@
         "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7"
       }
     },
+    "node_modules/buffer": {
+      "version": "5.7.1",
+      "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz",
+      "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==",
+      "funding": [
+        {
+          "type": "github",
+          "url": "https://github.com/sponsors/feross"
+        },
+        {
+          "type": "patreon",
+          "url": "https://www.patreon.com/feross"
+        },
+        {
+          "type": "consulting",
+          "url": "https://feross.org/support"
+        }
+      ],
+      "license": "MIT",
+      "dependencies": {
+        "base64-js": "^1.3.1",
+        "ieee754": "^1.1.13"
+      }
+    },
     "node_modules/buffer-from": {
       "version": "1.1.2",
       "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz",
       "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==",
       "license": "MIT"
     },
+    "node_modules/buffer/node_modules/base64-js": {
+      "version": "1.5.1",
+      "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
+      "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==",
+      "funding": [
+        {
+          "type": "github",
+          "url": "https://github.com/sponsors/feross"
+        },
+        {
+          "type": "patreon",
+          "url": "https://www.patreon.com/feross"
+        },
+        {
+          "type": "consulting",
+          "url": "https://feross.org/support"
+        }
+      ],
+      "license": "MIT"
+    },
     "node_modules/bundle-name": {
       "version": "4.1.0",
       "resolved": "https://registry.npmjs.org/bundle-name/-/bundle-name-4.1.0.tgz",
@@ -6485,6 +7184,15 @@
         "url": "https://github.com/sponsors/sindresorhus"
       }
     },
+    "node_modules/camelize": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/camelize/-/camelize-1.0.1.tgz",
+      "integrity": "sha512-dU+Tx2fsypxTgtLoE36npi3UqcjSSMNYfkqgmoEhtZrraP5VWq0K7FkWVTYa8eMPtnU/G2txVsfdCJTn9uzpuQ==",
+      "license": "MIT",
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
     "node_modules/caniuse-api": {
       "version": "3.0.0",
       "resolved": "https://registry.npmjs.org/caniuse-api/-/caniuse-api-3.0.0.tgz",
@@ -6680,6 +7388,12 @@
         "fsevents": "~2.3.2"
       }
     },
+    "node_modules/chownr": {
+      "version": "1.1.4",
+      "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz",
+      "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==",
+      "license": "ISC"
+    },
     "node_modules/chrome-trace-event": {
       "version": "1.0.4",
       "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.4.tgz",
@@ -6814,6 +7528,19 @@
         "url": "https://github.com/sponsors/wooorm"
       }
     },
+    "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",
@@ -6832,6 +7559,16 @@
       "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
       "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/colord": {
       "version": "2.9.3",
       "resolved": "https://registry.npmjs.org/colord/-/colord-2.9.3.tgz",
@@ -7229,6 +7966,12 @@
         "url": "https://github.com/sponsors/sindresorhus"
       }
     },
+    "node_modules/css-background-parser": {
+      "version": "0.1.0",
+      "resolved": "https://registry.npmjs.org/css-background-parser/-/css-background-parser-0.1.0.tgz",
+      "integrity": "sha512-2EZLisiZQ+7m4wwur/qiYJRniHX4K5Tc9w93MT3AS0WS1u5kaZ4FKXlOTBhOjc+CgEgPiGY+fX1yWD8UwpEqUA==",
+      "license": "MIT"
+    },
     "node_modules/css-blank-pseudo": {
       "version": "7.0.1",
       "resolved": "https://registry.npmjs.org/css-blank-pseudo/-/css-blank-pseudo-7.0.1.tgz",
@@ -7267,6 +8010,21 @@
         "node": ">=4"
       }
     },
+    "node_modules/css-box-shadow": {
+      "version": "1.0.0-3",
+      "resolved": "https://registry.npmjs.org/css-box-shadow/-/css-box-shadow-1.0.0-3.tgz",
+      "integrity": "sha512-9jaqR6e7Ohds+aWwmhe6wILJ99xYQbfmK9QQB9CcMjDbTxPZjwEmUQpU91OG05Xgm8BahT5fW+svbsQGjS/zPg==",
+      "license": "MIT"
+    },
+    "node_modules/css-color-keywords": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/css-color-keywords/-/css-color-keywords-1.0.0.tgz",
+      "integrity": "sha512-FyyrDHZKEjXDpNJYvVsV960FiqQyXc/LlYmsxl2BcdMb2WPx0OGRVgTg55rPSyLSNMqP52R9r8geSp7apN3Ofg==",
+      "license": "ISC",
+      "engines": {
+        "node": ">=4"
+      }
+    },
     "node_modules/css-declaration-sorter": {
       "version": "7.3.0",
       "resolved": "https://registry.npmjs.org/css-declaration-sorter/-/css-declaration-sorter-7.3.0.tgz",
@@ -7458,6 +8216,17 @@
         "url": "https://github.com/sponsors/fb55"
       }
     },
+    "node_modules/css-to-react-native": {
+      "version": "3.2.0",
+      "resolved": "https://registry.npmjs.org/css-to-react-native/-/css-to-react-native-3.2.0.tgz",
+      "integrity": "sha512-e8RKaLXMOFii+02mOlqwjbD00KSEKqblnpO9e++1aXS1fPQOpS1YoqdVHBqPjHNoxeF2mimzVqawm2KCbEdtHQ==",
+      "license": "MIT",
+      "dependencies": {
+        "camelize": "^1.0.0",
+        "css-color-keywords": "^1.0.0",
+        "postcss-value-parser": "^4.0.2"
+      }
+    },
     "node_modules/css-tree": {
       "version": "2.3.1",
       "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.3.1.tgz",
@@ -8282,6 +9051,18 @@
         "url": "https://github.com/sponsors/sindresorhus"
       }
     },
+    "node_modules/default-gateway": {
+      "version": "6.0.3",
+      "resolved": "https://registry.npmjs.org/default-gateway/-/default-gateway-6.0.3.tgz",
+      "integrity": "sha512-fwSOJsbbNzZ/CUFpqFBqYfYNLj1NbMPm8MMCIzHjC83iSJRBEGmDUxU+WP661BaBQImeC2yHwXtz+P/O9o+XEg==",
+      "license": "BSD-2-Clause",
+      "dependencies": {
+        "execa": "^5.0.0"
+      },
+      "engines": {
+        "node": ">= 10"
+      }
+    },
     "node_modules/defer-to-connect": {
       "version": "2.0.1",
       "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.1.tgz",
@@ -8371,6 +9152,15 @@
         "npm": "1.2.8000 || >= 1.4.16"
       }
     },
+    "node_modules/detect-libc": {
+      "version": "2.1.2",
+      "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz",
+      "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==",
+      "license": "Apache-2.0",
+      "engines": {
+        "node": ">=8"
+      }
+    },
     "node_modules/detect-node": {
       "version": "2.1.0",
       "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz",
@@ -8645,6 +9435,15 @@
         "node": ">= 0.8"
       }
     },
+    "node_modules/end-of-stream": {
+      "version": "1.4.5",
+      "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.5.tgz",
+      "integrity": "sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==",
+      "license": "MIT",
+      "dependencies": {
+        "once": "^1.4.0"
+      }
+    },
     "node_modules/enhanced-resolve": {
       "version": "5.18.3",
       "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.18.3.tgz",
@@ -9002,6 +9801,15 @@
         "node": ">=0.8.x"
       }
     },
+    "node_modules/events-universal": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/events-universal/-/events-universal-1.0.1.tgz",
+      "integrity": "sha512-LUd5euvbMLpwOF8m6ivPCbhQeSiYVNb8Vs0fQ8QjXo0JTkEHpz8pxdQf0gStltaPpw0Cca8b39KxvK9cfKRiAw==",
+      "license": "Apache-2.0",
+      "dependencies": {
+        "bare-events": "^2.7.0"
+      }
+    },
     "node_modules/eventsource-parser": {
       "version": "3.0.6",
       "resolved": "https://registry.npmjs.org/eventsource-parser/-/eventsource-parser-3.0.6.tgz",
@@ -9034,6 +9842,15 @@
         "url": "https://github.com/sindresorhus/execa?sponsor=1"
       }
     },
+    "node_modules/expand-template": {
+      "version": "2.0.3",
+      "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz",
+      "integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==",
+      "license": "(MIT OR WTFPL)",
+      "engines": {
+        "node": ">=6"
+      }
+    },
     "node_modules/express": {
       "version": "4.21.2",
       "resolved": "https://registry.npmjs.org/express/-/express-4.21.2.tgz",
@@ -9152,6 +9969,12 @@
       "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
       "license": "MIT"
     },
+    "node_modules/fast-fifo": {
+      "version": "1.3.2",
+      "resolved": "https://registry.npmjs.org/fast-fifo/-/fast-fifo-1.3.2.tgz",
+      "integrity": "sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==",
+      "license": "MIT"
+    },
     "node_modules/fast-glob": {
       "version": "3.3.3",
       "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz",
@@ -9236,6 +10059,12 @@
         "node": ">=0.4.0"
       }
     },
+    "node_modules/fflate": {
+      "version": "0.7.4",
+      "resolved": "https://registry.npmjs.org/fflate/-/fflate-0.7.4.tgz",
+      "integrity": "sha512-5u2V/CDW15QM1XbbgS+0DfPxVB+jUKhWEKuuFuHncbk3tEEqzmoXL+2KyOFuKGqOnmdIy0/davWF1CkuwtibCw==",
+      "license": "MIT"
+    },
     "node_modules/figures": {
       "version": "3.2.0",
       "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz",
@@ -9483,6 +10312,12 @@
         "node": ">= 0.6"
       }
     },
+    "node_modules/fs-constants": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz",
+      "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==",
+      "license": "MIT"
+    },
     "node_modules/fs-extra": {
       "version": "11.3.2",
       "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.3.2.tgz",
@@ -9497,6 +10332,18 @@
         "node": ">=14.14"
       }
     },
+    "node_modules/fs-monkey": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/fs-monkey/-/fs-monkey-1.1.0.tgz",
+      "integrity": "sha512-QMUezzXWII9EV5aTFXW1UBVUO77wYPpjqIF8/AviUCThNeSYZykpoTixUeaNNBwmCev0AMDWMAni+f8Hxb1IFw==",
+      "license": "Unlicense"
+    },
+    "node_modules/fs.realpath": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
+      "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==",
+      "license": "ISC"
+    },
     "node_modules/fsevents": {
       "version": "2.3.3",
       "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
@@ -9593,12 +10440,39 @@
         "lit": "^3.2.1"
       }
     },
+    "node_modules/github-from-package": {
+      "version": "0.0.0",
+      "resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz",
+      "integrity": "sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==",
+      "license": "MIT"
+    },
     "node_modules/github-slugger": {
       "version": "1.5.0",
       "resolved": "https://registry.npmjs.org/github-slugger/-/github-slugger-1.5.0.tgz",
       "integrity": "sha512-wIh+gKBI9Nshz2o46B0B3f5k/W+WI9ZAv6y5Dn5WJ5SK1t0TnDimB4WE5rmTD05ZAIn8HALCZVmCsvj0w0v0lw==",
       "license": "ISC"
     },
+    "node_modules/glob": {
+      "version": "7.2.3",
+      "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
+      "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
+      "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me",
+      "license": "ISC",
+      "dependencies": {
+        "fs.realpath": "^1.0.0",
+        "inflight": "^1.0.4",
+        "inherits": "2",
+        "minimatch": "^3.1.1",
+        "once": "^1.3.0",
+        "path-is-absolute": "^1.0.0"
+      },
+      "engines": {
+        "node": "*"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/isaacs"
+      }
+    },
     "node_modules/glob-parent": {
       "version": "5.1.2",
       "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
@@ -10052,6 +10926,18 @@
         "he": "bin/he"
       }
     },
+    "node_modules/hex-rgb": {
+      "version": "4.3.0",
+      "resolved": "https://registry.npmjs.org/hex-rgb/-/hex-rgb-4.3.0.tgz",
+      "integrity": "sha512-Ox1pJVrDCyGHMG9CFg1tmrRUMRPRsAWYc/PinY0XzJU4K7y7vjNoLKIQ7BR5UJMCxNN8EM1MNDmHWA/B3aZUuw==",
+      "license": "MIT",
+      "engines": {
+        "node": ">=6"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
     "node_modules/history": {
       "version": "4.10.1",
       "resolved": "https://registry.npmjs.org/history/-/history-4.10.1.tgz",
@@ -10123,6 +11009,22 @@
         "safe-buffer": "~5.1.0"
       }
     },
+    "node_modules/html-entities": {
+      "version": "2.6.0",
+      "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-2.6.0.tgz",
+      "integrity": "sha512-kig+rMn/QOVRvr7c86gQ8lWXq+Hkv6CbAH1hLu+RG338StTpE8Z0b44SDVaqVu7HGKf27frdmUYEs9hTUX/cLQ==",
+      "funding": [
+        {
+          "type": "github",
+          "url": "https://github.com/sponsors/mdevils"
+        },
+        {
+          "type": "patreon",
+          "url": "https://patreon.com/mdevils"
+        }
+      ],
+      "license": "MIT"
+    },
     "node_modules/html-escaper": {
       "version": "2.0.2",
       "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz",
@@ -10401,6 +11303,26 @@
         "postcss": "^8.1.0"
       }
     },
+    "node_modules/ieee754": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
+      "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==",
+      "funding": [
+        {
+          "type": "github",
+          "url": "https://github.com/sponsors/feross"
+        },
+        {
+          "type": "patreon",
+          "url": "https://www.patreon.com/feross"
+        },
+        {
+          "type": "consulting",
+          "url": "https://feross.org/support"
+        }
+      ],
+      "license": "BSD-3-Clause"
+    },
     "node_modules/ignore": {
       "version": "5.3.2",
       "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz",
@@ -10474,6 +11396,17 @@
         "node": ">=12"
       }
     },
+    "node_modules/inflight": {
+      "version": "1.0.6",
+      "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
+      "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==",
+      "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.",
+      "license": "ISC",
+      "dependencies": {
+        "once": "^1.3.0",
+        "wrappy": "1"
+      }
+    },
     "node_modules/inherits": {
       "version": "2.0.4",
       "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
@@ -11136,6 +12069,16 @@
         "url": "https://github.com/sponsors/antonk52"
       }
     },
+    "node_modules/linebreak": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/linebreak/-/linebreak-1.1.0.tgz",
+      "integrity": "sha512-MHp03UImeVhB7XZtjd0E4n6+3xr5Dq/9xI/5FptGk5FrbDR3zagPa2DS6U8ks/3HjbKWG9Q1M2ufOzxV2qLYSQ==",
+      "license": "MIT",
+      "dependencies": {
+        "base64-js": "0.0.8",
+        "unicode-trie": "^2.0.0"
+      }
+    },
     "node_modules/lines-and-columns": {
       "version": "1.2.4",
       "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz",
@@ -13764,6 +14707,12 @@
         "url": "https://github.com/sponsors/ljharb"
       }
     },
+    "node_modules/mkdirp-classic": {
+      "version": "0.5.3",
+      "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz",
+      "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==",
+      "license": "MIT"
+    },
     "node_modules/mlly": {
       "version": "1.8.0",
       "resolved": "https://registry.npmjs.org/mlly/-/mlly-1.8.0.tgz",
@@ -13839,6 +14788,12 @@
         "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
       }
     },
+    "node_modules/napi-build-utils": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-2.0.0.tgz",
+      "integrity": "sha512-GEbrYkbfF7MoNaoh2iGG84Mnf/WZfB0GdGEsM8wz7Expx/LlWf5U8t9nvJKXSp3qr5IsEbK04cBGhol/KwOsWA==",
+      "license": "MIT"
+    },
     "node_modules/negotiator": {
       "version": "0.6.4",
       "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.4.tgz",
@@ -13864,6 +14819,24 @@
         "tslib": "^2.0.3"
       }
     },
+    "node_modules/node-abi": {
+      "version": "3.87.0",
+      "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.87.0.tgz",
+      "integrity": "sha512-+CGM1L1CgmtheLcBuleyYOn7NWPVu0s0EJH2C4puxgEZb9h8QpR9G2dBfZJOAUhi7VQxuBPMd0hiISWcTyiYyQ==",
+      "license": "MIT",
+      "dependencies": {
+        "semver": "^7.3.5"
+      },
+      "engines": {
+        "node": ">=10"
+      }
+    },
+    "node_modules/node-addon-api": {
+      "version": "6.1.0",
+      "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-6.1.0.tgz",
+      "integrity": "sha512-+eawOlIgy680F0kBzPUNFhMZGtJ1YmqM6l4+Crf4IkImjYrO/mqPwRMh352g23uIaQKFItcQ64I7KMaJxHgAVA==",
+      "license": "MIT"
+    },
     "node_modules/node-emoji": {
       "version": "2.2.0",
       "resolved": "https://registry.npmjs.org/node-emoji/-/node-emoji-2.2.0.tgz",
@@ -13888,6 +14861,16 @@
         "node": ">= 6.13.0"
       }
     },
+    "node_modules/node-html-parser": {
+      "version": "6.1.13",
+      "resolved": "https://registry.npmjs.org/node-html-parser/-/node-html-parser-6.1.13.tgz",
+      "integrity": "sha512-qIsTMOY4C/dAa5Q5vsobRpOOvPfC4pB61UVW2uSwZNUp0QU/jCekTal1vMmbO0DgdHeLUJpv/ARmDqErVxA3Sg==",
+      "license": "MIT",
+      "dependencies": {
+        "css-select": "^5.1.0",
+        "he": "1.2.0"
+      }
+    },
     "node_modules/node-releases": {
       "version": "2.0.27",
       "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.27.tgz",
@@ -14032,6 +15015,15 @@
         "node": ">=0.10.0"
       }
     },
+    "node_modules/object-hash": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz",
+      "integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==",
+      "license": "MIT",
+      "engines": {
+        "node": ">= 6"
+      }
+    },
     "node_modules/object-inspect": {
       "version": "1.13.4",
       "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz",
@@ -14100,6 +15092,15 @@
         "node": ">= 0.8"
       }
     },
+    "node_modules/once": {
+      "version": "1.4.0",
+      "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
+      "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
+      "license": "ISC",
+      "dependencies": {
+        "wrappy": "1"
+      }
+    },
     "node_modules/onetime": {
       "version": "5.1.2",
       "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz",
@@ -14273,6 +15274,12 @@
       "integrity": "sha512-uBj69dVlYe/+wxj8JOpr97XfsxH/eumMt6HqjNTmJDf/6NO9s+0uxeOneIz3AsPt2m6y9PqzDzd3ATcU17MNfw==",
       "license": "MIT"
     },
+    "node_modules/pako": {
+      "version": "0.2.9",
+      "resolved": "https://registry.npmjs.org/pako/-/pako-0.2.9.tgz",
+      "integrity": "sha512-NUcwaKxUxWrZLpDG+z/xZaCgQITkA/Dv4V/T6bw7VON6l1Xz/VnrBqrYjZQ12TamKHzITTfOEIYUj48y2KXImA==",
+      "license": "MIT"
+    },
     "node_modules/param-case": {
       "version": "3.0.4",
       "resolved": "https://registry.npmjs.org/param-case/-/param-case-3.0.4.tgz",
@@ -14295,6 +15302,16 @@
         "node": ">=6"
       }
     },
+    "node_modules/parse-css-color": {
+      "version": "0.2.1",
+      "resolved": "https://registry.npmjs.org/parse-css-color/-/parse-css-color-0.2.1.tgz",
+      "integrity": "sha512-bwS/GGIFV3b6KS4uwpzCFj4w297Yl3uqnSgIPsoQkx7GMLROXfMnWvxfNkL0oh8HVhZA4hvJoEoEIqonfJ3BWg==",
+      "license": "MIT",
+      "dependencies": {
+        "color-name": "^1.1.4",
+        "hex-rgb": "^4.1.0"
+      }
+    },
     "node_modules/parse-entities": {
       "version": "4.0.2",
       "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-4.0.2.tgz",
@@ -14415,6 +15432,15 @@
         "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
       }
     },
+    "node_modules/path-is-absolute": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
+      "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==",
+      "license": "MIT",
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
     "node_modules/path-is-inside": {
       "version": "1.0.2",
       "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz",
@@ -15988,6 +17014,61 @@
         "node": ">=10.15.1"
       }
     },
+    "node_modules/prebuild-install": {
+      "version": "7.1.3",
+      "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.1.3.tgz",
+      "integrity": "sha512-8Mf2cbV7x1cXPUILADGI3wuhfqWvtiLA1iclTDbFRZkgRQS0NqsPZphna9V+HyTEadheuPmjaJMsbzKQFOzLug==",
+      "deprecated": "No longer maintained. Please contact the author of the relevant native addon; alternatives are available.",
+      "license": "MIT",
+      "dependencies": {
+        "detect-libc": "^2.0.0",
+        "expand-template": "^2.0.3",
+        "github-from-package": "0.0.0",
+        "minimist": "^1.2.3",
+        "mkdirp-classic": "^0.5.3",
+        "napi-build-utils": "^2.0.0",
+        "node-abi": "^3.3.0",
+        "pump": "^3.0.0",
+        "rc": "^1.2.7",
+        "simple-get": "^4.0.0",
+        "tar-fs": "^2.0.0",
+        "tunnel-agent": "^0.6.0"
+      },
+      "bin": {
+        "prebuild-install": "bin.js"
+      },
+      "engines": {
+        "node": ">=10"
+      }
+    },
+    "node_modules/prebuild-install/node_modules/tar-fs": {
+      "version": "2.1.4",
+      "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.4.tgz",
+      "integrity": "sha512-mDAjwmZdh7LTT6pNleZ05Yt65HC3E+NiQzl672vQG38jIrehtJk/J3mNwIg+vShQPcLF/LV7CMnDW6vjj6sfYQ==",
+      "license": "MIT",
+      "dependencies": {
+        "chownr": "^1.1.1",
+        "mkdirp-classic": "^0.5.2",
+        "pump": "^3.0.0",
+        "tar-stream": "^2.1.4"
+      }
+    },
+    "node_modules/prebuild-install/node_modules/tar-stream": {
+      "version": "2.2.0",
+      "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz",
+      "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==",
+      "license": "MIT",
+      "dependencies": {
+        "bl": "^4.0.3",
+        "end-of-stream": "^1.4.1",
+        "fs-constants": "^1.0.0",
+        "inherits": "^2.0.3",
+        "readable-stream": "^3.1.1"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
     "node_modules/pretty-error": {
       "version": "4.0.0",
       "resolved": "https://registry.npmjs.org/pretty-error/-/pretty-error-4.0.0.tgz",
@@ -16097,6 +17178,16 @@
         "node": ">= 0.10"
       }
     },
+    "node_modules/pump": {
+      "version": "3.0.3",
+      "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.3.tgz",
+      "integrity": "sha512-todwxLMY7/heScKmntwQG8CXVkWUOdYxIvY2s0VWAAMh/nd8SoYiRaKjlr7+iCs984f2P8zvrfWcDDYVb73NfA==",
+      "license": "MIT",
+      "dependencies": {
+        "end-of-stream": "^1.1.0",
+        "once": "^1.3.1"
+      }
+    },
     "node_modules/punycode": {
       "version": "2.3.1",
       "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz",
@@ -16963,6 +18054,22 @@
         "node": ">=0.10.0"
       }
     },
+    "node_modules/rimraf": {
+      "version": "3.0.2",
+      "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
+      "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
+      "deprecated": "Rimraf versions prior to v4 are no longer supported",
+      "license": "ISC",
+      "dependencies": {
+        "glob": "^7.1.3"
+      },
+      "bin": {
+        "rimraf": "bin.js"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/isaacs"
+      }
+    },
     "node_modules/robust-predicates": {
       "version": "3.0.2",
       "resolved": "https://registry.npmjs.org/robust-predicates/-/robust-predicates-3.0.2.tgz",
@@ -17066,6 +18173,33 @@
       "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
       "license": "MIT"
     },
+    "node_modules/satori": {
+      "version": "0.10.14",
+      "resolved": "https://registry.npmjs.org/satori/-/satori-0.10.14.tgz",
+      "integrity": "sha512-abovcqmwl97WKioxpkfuMeZmndB1TuDFY/R+FymrZyiGP+pMYomvgSzVPnbNMWHHESOPosVHGL352oFbdAnJcA==",
+      "license": "MPL-2.0",
+      "dependencies": {
+        "@shuding/opentype.js": "1.4.0-beta.0",
+        "css-background-parser": "^0.1.0",
+        "css-box-shadow": "1.0.0-3",
+        "css-to-react-native": "^3.0.0",
+        "emoji-regex": "^10.2.1",
+        "escape-html": "^1.0.3",
+        "linebreak": "^1.1.0",
+        "parse-css-color": "^0.2.1",
+        "postcss-value-parser": "^4.2.0",
+        "yoga-wasm-web": "^0.3.3"
+      },
+      "engines": {
+        "node": ">=16"
+      }
+    },
+    "node_modules/satori/node_modules/emoji-regex": {
+      "version": "10.6.0",
+      "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.6.0.tgz",
+      "integrity": "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==",
+      "license": "MIT"
+    },
     "node_modules/sax": {
       "version": "1.4.3",
       "resolved": "https://registry.npmjs.org/sax/-/sax-1.4.3.tgz",
@@ -17383,6 +18517,29 @@
       "integrity": "sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ==",
       "license": "MIT"
     },
+    "node_modules/sharp": {
+      "version": "0.32.6",
+      "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.32.6.tgz",
+      "integrity": "sha512-KyLTWwgcR9Oe4d9HwCwNM2l7+J0dUQwn/yf7S0EnTtb0eVS4RxO0eUSvxPtzT4F3SY+C4K6fqdv/DO27sJ/v/w==",
+      "hasInstallScript": true,
+      "license": "Apache-2.0",
+      "dependencies": {
+        "color": "^4.2.3",
+        "detect-libc": "^2.0.2",
+        "node-addon-api": "^6.1.0",
+        "prebuild-install": "^7.1.1",
+        "semver": "^7.5.4",
+        "simple-get": "^4.0.1",
+        "tar-fs": "^3.0.4",
+        "tunnel-agent": "^0.6.0"
+      },
+      "engines": {
+        "node": ">=14.15.0"
+      },
+      "funding": {
+        "url": "https://opencollective.com/libvips"
+      }
+    },
     "node_modules/shebang-command": {
       "version": "2.0.0",
       "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
@@ -17494,6 +18651,66 @@
       "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==",
       "license": "ISC"
     },
+    "node_modules/simple-concat": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz",
+      "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==",
+      "funding": [
+        {
+          "type": "github",
+          "url": "https://github.com/sponsors/feross"
+        },
+        {
+          "type": "patreon",
+          "url": "https://www.patreon.com/feross"
+        },
+        {
+          "type": "consulting",
+          "url": "https://feross.org/support"
+        }
+      ],
+      "license": "MIT"
+    },
+    "node_modules/simple-get": {
+      "version": "4.0.1",
+      "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-4.0.1.tgz",
+      "integrity": "sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==",
+      "funding": [
+        {
+          "type": "github",
+          "url": "https://github.com/sponsors/feross"
+        },
+        {
+          "type": "patreon",
+          "url": "https://www.patreon.com/feross"
+        },
+        {
+          "type": "consulting",
+          "url": "https://feross.org/support"
+        }
+      ],
+      "license": "MIT",
+      "dependencies": {
+        "decompress-response": "^6.0.0",
+        "once": "^1.3.1",
+        "simple-concat": "^1.0.0"
+      }
+    },
+    "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/simple-swizzle/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/sirv": {
       "version": "2.0.4",
       "resolved": "https://registry.npmjs.org/sirv/-/sirv-2.0.4.tgz",
@@ -17700,6 +18917,17 @@
       "integrity": "sha512-5GS12FdOZNliM5mAOxFRg7Ir0pWz8MdpYm6AY6VPkGpbA7ZzmbzNcBJQ0GPvvyWgcY7QAhCgf9Uy89I03faLkg==",
       "license": "MIT"
     },
+    "node_modules/streamx": {
+      "version": "2.23.0",
+      "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.23.0.tgz",
+      "integrity": "sha512-kn+e44esVfn2Fa/O0CPFcex27fjIL6MkVae0Mm6q+E6f0hWv578YCERbv+4m02cjxvDsPKLnmxral/rR6lBMAg==",
+      "license": "MIT",
+      "dependencies": {
+        "events-universal": "^1.0.0",
+        "fast-fifo": "^1.3.2",
+        "text-decoder": "^1.1.0"
+      }
+    },
     "node_modules/string_decoder": {
       "version": "1.3.0",
       "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz",
@@ -17753,6 +18981,12 @@
         "url": "https://github.com/chalk/strip-ansi?sponsor=1"
       }
     },
+    "node_modules/string.prototype.codepointat": {
+      "version": "0.2.1",
+      "resolved": "https://registry.npmjs.org/string.prototype.codepointat/-/string.prototype.codepointat-0.2.1.tgz",
+      "integrity": "sha512-2cBVCj6I4IOvEnjgO/hWqXjqBGsY+zwPmHl12Srk9IXSZ56Jwwmy+66XO5Iut/oQVR7t5ihYdLB0GMa4alEUcg==",
+      "license": "MIT"
+    },
     "node_modules/stringify-entities": {
       "version": "4.0.4",
       "resolved": "https://registry.npmjs.org/stringify-entities/-/stringify-entities-4.0.4.tgz",
@@ -17953,6 +19187,41 @@
         "url": "https://opencollective.com/webpack"
       }
     },
+    "node_modules/tar-fs": {
+      "version": "3.1.1",
+      "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-3.1.1.tgz",
+      "integrity": "sha512-LZA0oaPOc2fVo82Txf3gw+AkEd38szODlptMYejQUhndHMLQ9M059uXR+AfS7DNo0NpINvSqDsvyaCrBVkptWg==",
+      "license": "MIT",
+      "dependencies": {
+        "pump": "^3.0.0",
+        "tar-stream": "^3.1.5"
+      },
+      "optionalDependencies": {
+        "bare-fs": "^4.0.1",
+        "bare-path": "^3.0.0"
+      }
+    },
+    "node_modules/tar-stream": {
+      "version": "3.1.7",
+      "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-3.1.7.tgz",
+      "integrity": "sha512-qJj60CXt7IU1Ffyc3NJMjh6EkuCFej46zUqJ4J7pqYlThyd9bO0XBTmcOIhSzZJVWfsLks0+nle/j538YAW9RQ==",
+      "license": "MIT",
+      "dependencies": {
+        "b4a": "^1.6.4",
+        "fast-fifo": "^1.2.0",
+        "streamx": "^2.15.0"
+      }
+    },
+    "node_modules/teex": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/teex/-/teex-1.0.1.tgz",
+      "integrity": "sha512-eYE6iEI62Ni1H8oIa7KlDU6uQBtqr4Eajni3wX7rpfXD8ysFx8z0+dri+KWEPWpBsxXfxu58x/0jvTVT1ekOSg==",
+      "license": "MIT",
+      "optional": true,
+      "dependencies": {
+        "streamx": "^2.12.5"
+      }
+    },
     "node_modules/terser": {
       "version": "5.44.1",
       "resolved": "https://registry.npmjs.org/terser/-/terser-5.44.1.tgz",
@@ -18040,6 +19309,15 @@
       "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==",
       "license": "MIT"
     },
+    "node_modules/text-decoder": {
+      "version": "1.2.7",
+      "resolved": "https://registry.npmjs.org/text-decoder/-/text-decoder-1.2.7.tgz",
+      "integrity": "sha512-vlLytXkeP4xvEq2otHeJfSQIRyWxo/oZGEbXrtEEF9Hnmrdly59sUbzZ/QgyWuLYHctCHxFF4tRQZNQ9k60ExQ==",
+      "license": "Apache-2.0",
+      "dependencies": {
+        "b4a": "^1.6.4"
+      }
+    },
     "node_modules/thingies": {
       "version": "2.5.0",
       "resolved": "https://registry.npmjs.org/thingies/-/thingies-2.5.0.tgz",
@@ -18080,6 +19358,12 @@
       "integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==",
       "license": "MIT"
     },
+    "node_modules/tiny-inflate": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/tiny-inflate/-/tiny-inflate-1.0.3.tgz",
+      "integrity": "sha512-pkY1fj1cKHb2seWDy0B16HeWyczlJA9/WW3u3c4z/NiWDsO3DOU5D7nhTLE9CF0yXv/QZFY7sEJmj24dK+Rrqw==",
+      "license": "MIT"
+    },
     "node_modules/tiny-invariant": {
       "version": "1.3.3",
       "resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.3.3.tgz",
@@ -18191,6 +19475,18 @@
       "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==",
       "license": "0BSD"
     },
+    "node_modules/tunnel-agent": {
+      "version": "0.6.0",
+      "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz",
+      "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==",
+      "license": "Apache-2.0",
+      "dependencies": {
+        "safe-buffer": "^5.0.1"
+      },
+      "engines": {
+        "node": "*"
+      }
+    },
     "node_modules/type-fest": {
       "version": "2.19.0",
       "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-2.19.0.tgz",
@@ -18307,6 +19603,16 @@
         "node": ">=4"
       }
     },
+    "node_modules/unicode-trie": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/unicode-trie/-/unicode-trie-2.0.0.tgz",
+      "integrity": "sha512-x7bc76x0bm4prf1VLg79uhAzKw8DVboClSN5VxJuQ+LKDOVEW9CdH+VY7SP+vX7xCYQqzzgQpFqz15zeLvAtZQ==",
+      "license": "MIT",
+      "dependencies": {
+        "pako": "^0.2.5",
+        "tiny-inflate": "^1.0.0"
+      }
+    },
     "node_modules/unified": {
       "version": "11.0.5",
       "resolved": "https://registry.npmjs.org/unified/-/unified-11.0.5.tgz",
@@ -19317,6 +20623,12 @@
         "url": "https://github.com/chalk/strip-ansi?sponsor=1"
       }
     },
+    "node_modules/wrappy": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
+      "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==",
+      "license": "ISC"
+    },
     "node_modules/write-file-atomic": {
       "version": "3.0.3",
       "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz",
@@ -19422,6 +20734,12 @@
         "url": "https://github.com/sponsors/sindresorhus"
       }
     },
+    "node_modules/yoga-wasm-web": {
+      "version": "0.3.3",
+      "resolved": "https://registry.npmjs.org/yoga-wasm-web/-/yoga-wasm-web-0.3.3.tgz",
+      "integrity": "sha512-N+d4UJSJbt/R3wqY7Coqs5pcV0aUj2j9IaQ3rNj9bVCLld8tTGKRa2USARjnvZJWVx1NDmQev8EknoczaOQDOA==",
+      "license": "MIT"
+    },
     "node_modules/zod": {
       "version": "4.1.12",
       "resolved": "https://registry.npmjs.org/zod/-/zod-4.1.12.tgz",
diff --git a/website/package.json b/website/package.json
index b6a93ef0..7c24befb 100644
--- a/website/package.json
+++ b/website/package.json
@@ -14,6 +14,7 @@
     "write-heading-ids": "docusaurus write-heading-ids"
   },
   "dependencies": {
+    "@acid-info/docusaurus-og": "^1.0.3-beta.2",
     "@docusaurus/core": "3.9.2",
     "@docusaurus/preset-classic": "3.9.2",
     "@docusaurus/theme-mermaid": "^3.9.2",
@@ -32,7 +33,8 @@
   },
   "devDependencies": {
     "@docusaurus/module-type-aliases": "3.9.2",
-    "@docusaurus/types": "3.9.2"
+    "@docusaurus/types": "3.9.2",
+    "@fontsource/inter": "^5.2.8"
   },
   "browserslist": {
     "production": [

From a55f12748b1c48a5a2ef36a446626c6980dcd900 Mon Sep 17 00:00:00 2001
From: maxnorm 
Date: Sun, 22 Feb 2026 15:32:43 -0500
Subject: [PATCH 7/7] improve og img rendering, fix wrong page descriptions

---
 .../documentation/all-components.mdx          |   2 +-
 website/docs/facets/authentication.mdx        |   2 +-
 website/docs/facets/facets-and-modules.mdx    |   2 +-
 website/docs/foundations/overview.mdx         |   2 +-
 website/docs/foundations/solidity-modules.mdx |   2 +-
 website/lib/ImageRenderers.js                 |  62 ++++++++++++++----
 website/static/img/logo-og-white.png          | Bin 0 -> 2038 bytes
 7 files changed, 56 insertions(+), 16 deletions(-)
 create mode 100644 website/static/img/logo-og-white.png

diff --git a/website/docs/contribution/documentation/all-components.mdx b/website/docs/contribution/documentation/all-components.mdx
index 46aecd12..e4ecf566 100644
--- a/website/docs/contribution/documentation/all-components.mdx
+++ b/website/docs/contribution/documentation/all-components.mdx
@@ -1,7 +1,7 @@
 ---
 sidebar_position: 2
 title: All Components - Complete Reference
-description: Complete guide to all 30+ components with live examples, detailed documentation, and usage
+description: Complete reference of all documentation UI components—Badge, Callout, Accordion, APIReference, and more—with usage examples for Compose docs.
 draft: true
 ---
 
diff --git a/website/docs/facets/authentication.mdx b/website/docs/facets/authentication.mdx
index 8b158421..76739e98 100644
--- a/website/docs/facets/authentication.mdx
+++ b/website/docs/facets/authentication.mdx
@@ -1,7 +1,7 @@
 ---
 sidebar_position: 2
 title: Authentication
-description: Complete guide to all 30+ components with live examples, detailed documentation, and usage
+description: Access control and permission management for diamond contracts. Implement role-based access control (RBAC) and secure your Compose facets.
 draft: true
 ---
 
diff --git a/website/docs/facets/facets-and-modules.mdx b/website/docs/facets/facets-and-modules.mdx
index 35e3cd63..e4856b10 100644
--- a/website/docs/facets/facets-and-modules.mdx
+++ b/website/docs/facets/facets-and-modules.mdx
@@ -1,7 +1,7 @@
 ---
 sidebar_position: 3
 title: Facets & Modules
-description: Complete guide to all 30+ components with live examples, detailed documentation, and usage
+description: How facets and modules work together through shared storage. When to use facets vs modules and how to build composable smart contract systems.
 draft: true
 ---
 
diff --git a/website/docs/foundations/overview.mdx b/website/docs/foundations/overview.mdx
index 0c9fb410..733e1038 100644
--- a/website/docs/foundations/overview.mdx
+++ b/website/docs/foundations/overview.mdx
@@ -1,7 +1,7 @@
 ---
 sidebar_position: 10
 title: Overview
-description: Complete guide to all 30+ components with live examples, detailed documentation, and usage
+description: Overview of Compose foundations—core concepts, authentication, facets and modules, diamond standard, and storage patterns for diamond-based smart contract development.
 draft: true
 ---
 
diff --git a/website/docs/foundations/solidity-modules.mdx b/website/docs/foundations/solidity-modules.mdx
index c6a6935d..d8d40e16 100644
--- a/website/docs/foundations/solidity-modules.mdx
+++ b/website/docs/foundations/solidity-modules.mdx
@@ -1,7 +1,7 @@
 ---
 sidebar_position: 3
 title: Solidity Modules
-description: Description of what Solidity modules are and how they are used in Compose.
+description: What Solidity modules are, how they differ from contracts and libraries, and how Compose uses them for reusable facet logic and shared storage.
 ---
 
 
diff --git a/website/lib/ImageRenderers.js b/website/lib/ImageRenderers.js
index 7edbb68f..6df2af77 100644
--- a/website/lib/ImageRenderers.js
+++ b/website/lib/ImageRenderers.js
@@ -29,6 +29,20 @@ const options = {
   fonts: fontConfig,
 };
 
+// Logo as PNG data URI (Satori does not reliably render SVG in img; use pre-generated PNG)
+const logoPngPath = path.join(__dirname, '../static/img/logo-og-white.png');
+let logoDataUri = null;
+function getLogoDataUri() {
+  if (logoDataUri !== null) return logoDataUri;
+  try {
+    const png = fs.readFileSync(logoPngPath);
+    logoDataUri = 'data:image/png;base64,' + png.toString('base64');
+  } catch (_) {
+    logoDataUri = '';
+  }
+  return logoDataUri;
+}
+
 function truncateTitle(title, maxChars = 60) {
   if (!title || typeof title !== 'string') return 'Compose';
   const t = title.trim();
@@ -36,7 +50,11 @@ function truncateTitle(title, maxChars = 60) {
   return t.slice(0, maxChars - 3).trim() + '...';
 }
 
+// Same blue gradient as default socialcard-compose.png: dark (top-left) to medium blue (bottom-right)
+const BACKGROUND_GRADIENT = 'linear-gradient(135deg, #0F172A 0%, #1A3B8A 100%)';
+
 function buildLayout(title, subtitle = 'Smart Contract Oriented Programming for ERC-2535 Diamonds') {
+  const logoSrc = getLogoDataUri();
   return React.createElement(
     'div',
     {
@@ -45,23 +63,44 @@ function buildLayout(title, subtitle = 'Smart Contract Oriented Programming for
         flexDirection: 'column',
         width: '100%',
         height: '100%',
-        background: 'linear-gradient(135deg, #0f172a 0%, #1e293b 100%)',
-        color: '#f8fafc',
+        background: BACKGROUND_GRADIENT,
+        color: '#ffffff',
         fontFamily: 'Inter',
         padding: 80,
         justifyContent: 'center',
       },
     },
+    // Logo + "Compose" in one row (like default social card)
     React.createElement(
       'div',
       {
         style: {
-          fontSize: 28,
-          marginBottom: 24,
-          opacity: 0.9,
+          display: 'flex',
+          flexDirection: 'row',
+          alignItems: 'center',
+          marginBottom: 32,
+          gap: 20,
         },
       },
-      'Compose'
+      logoSrc
+        ? React.createElement('img', {
+            src: logoSrc,
+            width: 100,
+            height: 100,
+            style: { display: 'flex' },
+          })
+        : null,
+      React.createElement(
+        'div',
+        {
+          style: {
+            fontSize: 56,
+            fontWeight: 600,
+            opacity: 0.95,
+          },
+        },
+        'Compose'
+      )
     ),
     React.createElement(
       'div',
@@ -80,13 +119,14 @@ function buildLayout(title, subtitle = 'Smart Contract Oriented Programming for
           'div',
           {
             style: {
-              fontSize: 24,
-              opacity: 0.85,
-              lineHeight: 1.4,
-              maxWidth: 900,
+              fontSize: 26,
+              opacity: 0.95,
+              lineHeight: 1.5,
+              maxWidth: 880,
+              marginTop: 1,
             },
           },
-          typeof subtitle === 'string' && subtitle.length > 120 ? subtitle.slice(0, 120) + '...' : subtitle
+          typeof subtitle === 'string' && subtitle.length > 140 ? subtitle.slice(0, 140).trim() + '...' : subtitle
         )
       : null
   );
diff --git a/website/static/img/logo-og-white.png b/website/static/img/logo-og-white.png
new file mode 100644
index 0000000000000000000000000000000000000000..603cf3f4a045bdb5de2019e22c26b047ccc49673
GIT binary patch
literal 2038
zcmZ`)`#TegAKspE-@_RoC
zQ`pkX!PD3+Q;a=wJPrU*QvXRHfX&eX0H77F&IkPBIiDv!R{Q(wcP&P+RU)?^AC+R$
zhKFDEU9Z?#Wh0QNBcXJ{(h%qfMPq46^Fg^Y#J(0YjpPw}05y4?=#^ECa7
zp2hOBBF@Z{c8A)>%gKcLrFTgq$pgsc69@034F3ZpBcgU}$$~T+2|5H0Vi3aE3(}lb
z)`FhrK6tQnt+lj79A&Q@{CRD)R7B5Y)Sq3@4oh8--iCt)pag=uT*Jvs!CE7p%NU2;
z7+%kA6Ey?*215TrMdyjA8nrO2*zO*+8wWUN7!1`AT?Z+UIf34hu<}()s~%nJTk)Tc!7R4L
ztIIQ6ekMR5X2hixzljFSS_q+;Y(gZs?6Hj-L~Dy5H40^S(SuTX#wt=
zYltT4LCTY-4I6&*ee#2nGoqwiPlS1anvsI;vYzD~{U(W#bD;dbwXf05HGATW+^2NJ
zc;LHJEgL@Ari{20E!NOql59y*AgD@F6*#I>muM^_7Y$xO4NsN9dg=usa#A!yjR;dc
ze%b%C41A8{@xhGN$dY*j#Ze^K*H^rr9;sx&?1|SIL^=(a_jmcIorl8nTd?vEV2v|Uf~s|A1G%hKdvD}sfj|=MrcdbiVQX2`rP1q(4~iB
zexDmV*0!nyaYasYu*h<|hYPL7>H6My==UI?MtM8v&Ymjc+-nPy=(hV3azndKP=`x^
z%;PG6DhXB~JI?mbtbfa7yY6d@FyNVm}Y)vZ89f-8P;XOc0#`}VWI
zFpKkR12!+;0zt^%&1K_joXCtJnS&LD1)u)E_#iilAWHErarm8U^6Vt;rwsI=^-R_fiq3q
z`x!H7%#^10iVo!)cb_W0Ui!A!Pq?y!qhF|=V*3Z>GT1>sVP{j2g1%5^rC}o8J~17A
zX?eEwXbRFF(nc(NcT_^@SSieI+r2)5e>ld9RS8dM^nvyaJm9fnYQ(F2dbI9HVGE+p
z5c3szY5GtgQ;d#~A2MF=++C(9wih+jyy~Y2p^B8>wnTwD2`
zZgh=3#ERjF?fDGsm3BK|DoAfJ!lkxjblZMO_@jLT_{J${$7~SPWEK?TQ&(0Q6R4T5
zBQofcg%o^KudPWEWzzd^N06~=v|@m2zIAOycdUap_t!D3J+p&;%XGj|SPh?i8zbs~
z49pwI?(!*FG5;U2wTOaQVXT>7p$P_$1BkE{WQXnkN^DXz*rtt+GhXz&m
zuI%@HM2PTslZRqbggn_5n3xhF?=nvNrQkVIlwsBi=_P5mJZe+)(iPc0YoQH0;4Oo=
z%>WqorF%P{KLPcS&og?&$hBZ#VhpFa&e=Q1=M%FtzA7mMq1k
z4n?a_+xkyqeNx?qPCl7AF|$G2ovXRY`+!T0y^smaD>_~p*^KGQ9rQKZo5socl%mZ(
zF|$&rNaOyP)T~q@y#hz_@5ocHIy%@{82df#LbQ&usMV58;{OQE-%ox>$PCO!{{n1=
zjD2dFDfvE8G2~Y+i7VH7E-96slv_IX2&3&w^ba7ajqJrXr1|)fTu-9aScc(pO~ExF
zmt=6Y^|?FT!(CZ3+-&C?Ic(77Z4Gg2u$01hVLM%y!Q+0GFe5h@ED!n`jty(DM
z>vtMW>E03tRTf!gz29@s=IkBwMWhH~esxh(wDPUOg~p1_Gto+~XJiy<@G>CNWhTLO
z7qmlhyz%uDIBqHUU6DAeXB^Ibzcl~mPn@{wd#5{BhRf&6;k;EENuJ?(wONt7mG(~w
zv``lx*1n$2y8u{OQJS
GyY??3P`o+-

literal 0
HcmV?d00001