From 0c02ac8c6843ed416baaadc6da2a03f96c57bb23 Mon Sep 17 00:00:00 2001 From: johnchourajr Date: Sun, 12 Jan 2025 23:47:33 -0800 Subject: [PATCH] update site with shader --- example/package-lock.json | 67 +++++++- example/package.json | 4 +- .../GenThreeShader/GenThreeShader.tsx | 155 ++++++++++++++++++ .../src/components/GenThreeShader/README.md | 70 ++++++++ .../src/components/GenThreeShader/index.ts | 2 + .../GenThreeShader/shaders/index.ts | 8 + .../GenThreeShader/shaders/types.ts | 1 + .../GenThreeShader/shaders/wavesShader.ts | 53 ++++++ .../src/components/SliceHero/SliceHero.tsx | 76 ++++++++- .../src/components/SvgHeader/SvgHeader.tsx | 58 +------ example/src/components/SvgHeader/logotype.ts | 5 + 11 files changed, 440 insertions(+), 59 deletions(-) create mode 100644 example/src/components/GenThreeShader/GenThreeShader.tsx create mode 100644 example/src/components/GenThreeShader/README.md create mode 100644 example/src/components/GenThreeShader/index.ts create mode 100644 example/src/components/GenThreeShader/shaders/index.ts create mode 100644 example/src/components/GenThreeShader/shaders/types.ts create mode 100644 example/src/components/GenThreeShader/shaders/wavesShader.ts create mode 100644 example/src/components/SvgHeader/logotype.ts diff --git a/example/package-lock.json b/example/package-lock.json index 4d6db1e..72a2c67 100644 --- a/example/package-lock.json +++ b/example/package-lock.json @@ -15,13 +15,15 @@ "next": "14.2.3", "react": "^18", "react-dom": "^18", - "react-resizable": "^3.0.5" + "react-resizable": "^3.0.5", + "three": "^0.172.0" }, "devDependencies": { "@types/node": "^20", "@types/react": "^18", "@types/react-dom": "^18", "@types/react-resizable": "^3.0.7", + "@types/three": "^0.172.0", "eslint": "^8", "eslint-config-next": "14.2.3", "postcss": "^8", @@ -457,6 +459,13 @@ "tailwindcss": ">=3.2.0" } }, + "node_modules/@tweenjs/tween.js": { + "version": "23.1.3", + "resolved": "https://registry.npmjs.org/@tweenjs/tween.js/-/tween.js-23.1.3.tgz", + "integrity": "sha512-vJmvvwFxYuGnF2axRtPYocag6Clbb5YS7kLL+SO/TeVFzHqDIWrNKYtcsPMibjDx9O+bu+psAy9NKfWklassUA==", + "dev": true, + "license": "MIT" + }, "node_modules/@types/json5": { "version": "0.0.29", "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", @@ -507,6 +516,35 @@ "@types/react": "*" } }, + "node_modules/@types/stats.js": { + "version": "0.17.3", + "resolved": "https://registry.npmjs.org/@types/stats.js/-/stats.js-0.17.3.tgz", + "integrity": "sha512-pXNfAD3KHOdif9EQXZ9deK82HVNaXP5ZIF5RP2QG6OQFNTaY2YIetfrE9t528vEreGQvEPRDDc8muaoYeK0SxQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/three": { + "version": "0.172.0", + "resolved": "https://registry.npmjs.org/@types/three/-/three-0.172.0.tgz", + "integrity": "sha512-LrUtP3FEG26Zg5WiF0nbg8VoXiKokBLTcqM2iLvM9vzcfEiYmmBAPGdBgV0OYx9fvWlY3R/3ERTZcD9X5sc0NA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@tweenjs/tween.js": "~23.1.3", + "@types/stats.js": "*", + "@types/webxr": "*", + "@webgpu/types": "*", + "fflate": "~0.8.2", + "meshoptimizer": "~0.18.1" + } + }, + "node_modules/@types/webxr": { + "version": "0.5.20", + "resolved": "https://registry.npmjs.org/@types/webxr/-/webxr-0.5.20.tgz", + "integrity": "sha512-JGpU6qiIJQKUuVSKx1GtQnHJGxRjtfGIhzO2ilq43VZZS//f1h1Sgexbdk+Lq+7569a6EYhOWrUpIruR/1Enmg==", + "dev": true, + "license": "MIT" + }, "node_modules/@typescript-eslint/parser": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.2.0.tgz", @@ -640,6 +678,13 @@ "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", "dev": true }, + "node_modules/@webgpu/types": { + "version": "0.1.52", + "resolved": "https://registry.npmjs.org/@webgpu/types/-/types-0.1.52.tgz", + "integrity": "sha512-eI883Nlag2hGIkhXxAnq8s4APpqXWuPL3Gbn2ghiU12UjLvfCbVqHK4XfXl3eLRTatqcMmeK7jws7IwWsGfbzw==", + "dev": true, + "license": "BSD-3-Clause" + }, "node_modules/acorn": { "version": "8.11.3", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", @@ -1983,6 +2028,13 @@ "reusify": "^1.0.4" } }, + "node_modules/fflate": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/fflate/-/fflate-0.8.2.tgz", + "integrity": "sha512-cPJU47OaAoCbg0pBvzsgpTPhmhqI5eJjh/JIu8tPj5q+T7iLvW/JAYUqmE7KOB4R1ZyEhzBaIQpQpardBF5z8A==", + "dev": true, + "license": "MIT" + }, "node_modules/file-entry-cache": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", @@ -3038,6 +3090,13 @@ "node": ">= 8" } }, + "node_modules/meshoptimizer": { + "version": "0.18.1", + "resolved": "https://registry.npmjs.org/meshoptimizer/-/meshoptimizer-0.18.1.tgz", + "integrity": "sha512-ZhoIoL7TNV4s5B6+rx5mC//fw8/POGyNxS/DZyCJeiZ12ScLfVwRE/GfsxwiTkMYYD5DmK2/JXnEVXqL4rF+Sw==", + "dev": true, + "license": "MIT" + }, "node_modules/micromatch": { "version": "4.0.7", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.7.tgz", @@ -4400,6 +4459,12 @@ "node": ">=0.8" } }, + "node_modules/three": { + "version": "0.172.0", + "resolved": "https://registry.npmjs.org/three/-/three-0.172.0.tgz", + "integrity": "sha512-6HMgMlzU97MsV7D/tY8Va38b83kz8YJX+BefKjspMNAv0Vx6dxMogHOrnRl/sbMIs3BPUKijPqDqJ/+UwJbIow==", + "license": "MIT" + }, "node_modules/to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", diff --git a/example/package.json b/example/package.json index 57ee10d..63e7381 100644 --- a/example/package.json +++ b/example/package.json @@ -16,13 +16,15 @@ "next": "14.2.3", "react": "^18", "react-dom": "^18", - "react-resizable": "^3.0.5" + "react-resizable": "^3.0.5", + "three": "^0.172.0" }, "devDependencies": { "@types/node": "^20", "@types/react": "^18", "@types/react-dom": "^18", "@types/react-resizable": "^3.0.7", + "@types/three": "^0.172.0", "eslint": "^8", "eslint-config-next": "14.2.3", "postcss": "^8", diff --git a/example/src/components/GenThreeShader/GenThreeShader.tsx b/example/src/components/GenThreeShader/GenThreeShader.tsx new file mode 100644 index 0000000..43e47f4 --- /dev/null +++ b/example/src/components/GenThreeShader/GenThreeShader.tsx @@ -0,0 +1,155 @@ +"use client"; +import clsx from "clsx"; +import { useEffect, useMemo, useRef } from "react"; +import * as THREE from "three"; + +/** + * Configuration object for defining shader properties + * @type ShaderConfig + */ +type ShaderConfig = { + /** Optional vertex shader code. If not provided, a default vertex shader will be used */ + vertexShader?: string; + /** Required fragment shader code */ + fragmentShader: string; + /** Optional additional uniforms to pass to the shader */ + uniforms?: Record; +}; + +/** + * Props for the GenThreeShader component + * @type GenThreeShaderProps + */ +type GenThreeShaderProps = { + /** Optional CSS class name to apply to the container */ + className?: string; + /** Shader configuration object */ + shaderConfig: ShaderConfig; +}; + +const defaultVertexShader = ` + varying vec2 vUv; + void main() { + vUv = uv; + gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0); + } +`; + +export const GenThreeShader = ({ + className, + shaderConfig, +}: GenThreeShaderProps) => { + const containerRef = useRef(null); + const sceneRef = useRef(null); + const rendererRef = useRef(null); + const mouseRef = useRef<{ x: number; y: number }>({ x: 0, y: 0 }); + const materialRef = useRef(null); + const sizeRef = useRef<{ width: number; height: number }>({ + width: 0, + height: 0, + }); + + const baseUniforms = useMemo( + () => ({ + resolution: { value: new THREE.Vector2() }, + mouse: { value: new THREE.Vector2() }, + time: { value: 0 }, + noiseScale: { value: 3.0 }, + colorSpeed: { value: 1.0 }, + kaleidoSegments: { value: 6.0 }, + patternScale: { value: 1.0 }, + colorIntensity: { value: 0.7 }, + motionSpeed: { value: 1.0 }, + warpIntensity: { value: 0.5 }, + }), + [], + ); + + useEffect(() => { + if (!containerRef.current) return; + + const scene = new THREE.Scene(); + const camera = new THREE.OrthographicCamera(-1, 1, 1, -1, 0, 1); + const container = containerRef.current; + sceneRef.current = scene; + + // Initialize renderer + const renderer = new THREE.WebGLRenderer({ alpha: true }); + rendererRef.current = renderer; + container.appendChild(renderer.domElement); + + // Setup geometry and material + const geometry = new THREE.PlaneGeometry(2, 2); + const material = new THREE.ShaderMaterial({ + uniforms: { + ...baseUniforms, + ...shaderConfig.uniforms, + }, + vertexShader: shaderConfig.vertexShader || defaultVertexShader, + fragmentShader: shaderConfig.fragmentShader, + }); + + materialRef.current = material; + const mesh = new THREE.Mesh(geometry, material); + scene.add(mesh); + + // Sizing with ResizeObserver + const resizeObserver = new ResizeObserver((entries) => { + const entry = entries[0]; + if (entry) { + sizeRef.current = { + width: entry.contentRect.width, + height: entry.contentRect.height, + }; + renderer.setSize(sizeRef.current.width, sizeRef.current.height); + material.uniforms.resolution.value.set( + sizeRef.current.width, + sizeRef.current.height, + ); + renderer.render(scene, camera); + } + }); + + resizeObserver.observe(container); + + // Mouse handling + const handleMouseMove = (event: MouseEvent) => { + const bounds = container.getBoundingClientRect(); + mouseRef.current = { + x: event.clientX - bounds.left, + y: event.clientY - bounds.top, + }; + }; + + // Animation frame management + let animationFrameId: number; + const startTime = performance.now(); + + const animate = () => { + material.uniforms.time.value = (performance.now() - startTime) * 0.001; + material.uniforms.mouse.value.set(mouseRef.current.x, mouseRef.current.y); + renderer.render(scene, camera); + animationFrameId = requestAnimationFrame(animate); + }; + + // Start animation + animate(); + + return () => { + resizeObserver.disconnect(); + cancelAnimationFrame(animationFrameId); + renderer.dispose(); + scene.clear(); + container.removeChild(renderer.domElement); + container.removeEventListener("mousemove", handleMouseMove); + }; + // eslint-disable-next-line react-hooks/exhaustive-deps -- Remove onDownload from deps + }, [shaderConfig, baseUniforms]); + + return ( +
+ ); +}; diff --git a/example/src/components/GenThreeShader/README.md b/example/src/components/GenThreeShader/README.md new file mode 100644 index 0000000..40a764f --- /dev/null +++ b/example/src/components/GenThreeShader/README.md @@ -0,0 +1,70 @@ +# GenThreeShader Component + +A React component that renders customizable WebGL shaders using Three.js. + +## Usage + +```tsx +import { GenThreeShader } from './GenThreeShader'; +import { kaleidoscopeShader } from './shaders/kaleidoscopeShader'; + +const MyComponent = () => { + const shaderConfig = { + fragmentShader: kaleidoscopeShader, + uniforms: { + patternScale: { value: 1.0 }, + kaleidoSegments: { value: 6.0 }, + colorIntensity: { value: 0.7 }, + }, + }; + + return ( + + ); +}; +``` + +## Props + +- `className?: string` - Optional CSS class name for the container +- `shaderConfig: ShaderConfig` - Configuration object for the shader +- `onDownload: (ref: () => void) => void` - Callback to receive the download function + +### ShaderConfig Interface + +```typescript +type ShaderConfig = { + vertexShader?: string; // Optional custom vertex shader + fragmentShader: string; // Required fragment shader code + uniforms?: Record; // Optional uniforms +}; +``` + +## Base Uniforms + +The component automatically provides these uniforms to all shaders: + +- `resolution` - Screen resolution (vec2) +- `mouse` - Mouse position (vec2) +- `time` - Elapsed time (float) +- `noiseScale` - Base noise scale (float) +- `colorSpeed` - Color animation speed (float) + +## Example with Custom Uniforms + +```tsx +const customConfig = { + vertexShader: ` + void main() { + gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0); + } + `, + fragmentShader: myCustomShader, + uniforms: { + customValue: { value: 1.0 }, + customColor: { value: new THREE.Color(1, 0, 0) }, + }, +}; diff --git a/example/src/components/GenThreeShader/index.ts b/example/src/components/GenThreeShader/index.ts new file mode 100644 index 0000000..0921710 --- /dev/null +++ b/example/src/components/GenThreeShader/index.ts @@ -0,0 +1,2 @@ +export { GenThreeShader } from "./GenThreeShader"; +export { genShaders } from "./shaders"; diff --git a/example/src/components/GenThreeShader/shaders/index.ts b/example/src/components/GenThreeShader/shaders/index.ts new file mode 100644 index 0000000..89cc93f --- /dev/null +++ b/example/src/components/GenThreeShader/shaders/index.ts @@ -0,0 +1,8 @@ +import { ShaderVariant } from "./types"; +import { wavesShader } from "./wavesShader"; + +export const genShaders: Record = { + wavesShader, +}; + +export type { ShaderVariant } from "./types"; diff --git a/example/src/components/GenThreeShader/shaders/types.ts b/example/src/components/GenThreeShader/shaders/types.ts new file mode 100644 index 0000000..2025963 --- /dev/null +++ b/example/src/components/GenThreeShader/shaders/types.ts @@ -0,0 +1 @@ +export type ShaderVariant = "wavesShader"; diff --git a/example/src/components/GenThreeShader/shaders/wavesShader.ts b/example/src/components/GenThreeShader/shaders/wavesShader.ts new file mode 100644 index 0000000..0ef0220 --- /dev/null +++ b/example/src/components/GenThreeShader/shaders/wavesShader.ts @@ -0,0 +1,53 @@ +export const wavesShader = ` +precision mediump float; +uniform float time; +uniform float scale; +uniform float speed; +uniform float distortion; +uniform float colorIntensity; +uniform vec2 resolution; + +vec3 hsl2rgb(vec3 c) { + // Force hue to green range (around 0.33) + c.x = 0.36 + c.x * 0.1; // Limits hue to 0.36-0.43 range (green spectrum) + vec3 rgb = clamp(abs(mod(c.x * 6.0 + vec3(0.0,4.0,2.0), 6.0) - 3.0) - 1.0, 0.0, 1.0); + return c.z + c.y * (rgb - 0.5) * (1.0 - abs(2.0 * c.z - 1.0)); +} + +float wave(vec2 uv, float scale, float speed, float distortion) { + float x = uv.x; + float y = uv.y; + float diagonal = dot(uv, vec2(cos(x * distortion), -sin(y * distortion))); + float wave1 = sin(diagonal * scale + time * speed + sin(x + y)); + float wave2 = cos(diagonal * scale * 0.7 + time * (speed * 0.8) + cos(x - y)); + float wave3 = sin(diagonal * scale * 1.3 + time * (speed * 1.2) + sin(x * 0.7 + y * 1.3)); + return (wave1 + wave2 + wave3) * 0.5 + 0.5; +} + +void main() { + vec2 uv = (gl_FragCoord.xy / resolution.xy) * 2.0 - 1.0; + uv.x *= resolution.x / resolution.y; + + float w1 = wave(uv, scale * 3.0, speed * 0.5, distortion * 0.9); + float w2 = wave(uv * 0.2, scale * 4.0, speed * -0.3, distortion * 0.8); + float w3 = wave(uv * 0.2, scale * 2.0, speed * 0.2, distortion * 0.8); + + // Increased power for more contrast and larger dark areas + float waves = pow((w1 * 0.85 + w2 * 0.6 + w3 * 0.5), 8.0); // Increased power from 6.0 to 8.0 + float depth = pow(waves * 0.7 + 0.3, 2.5); // Adjusted multipliers and increased power + + // Mixed green and yellow colors + vec3 brightGreen = vec3(0.0, 1.0, 0.04); // #00ff0a + vec3 lightYellow = vec3(1.0, 1.0, 0.1); // Light yellow + vec3 midColor = vec3(0.2, 0.9, 0.1); // Transitional green + + vec3 finalColor = mix(brightGreen, lightYellow, waves); + finalColor = mix(finalColor, midColor, depth); + + // Enhance contrast more aggressively + finalColor = pow(finalColor, vec3(1.3)); // Increased from 1.1 to 1.3 + finalColor *= colorIntensity; + + gl_FragColor = vec4(finalColor, 1.0); +} +`; diff --git a/example/src/components/SliceHero/SliceHero.tsx b/example/src/components/SliceHero/SliceHero.tsx index 2a5a36c..7c1206b 100644 --- a/example/src/components/SliceHero/SliceHero.tsx +++ b/example/src/components/SliceHero/SliceHero.tsx @@ -1,11 +1,75 @@ -import { SvgHeader } from "../SvgHeader"; +"use client"; + +import { useEffect, useRef, useState } from "react"; +import { GenThreeShader } from "../GenThreeShader"; +import { wavesShader } from "../GenThreeShader/shaders/wavesShader"; +import { logotype } from "../SvgHeader/logotype"; export function SliceHero() { + const containerRef = useRef(null); + const [scale, setScale] = useState(1); + + useEffect(() => { + const updateScale = () => { + if (!containerRef.current) return; + const { width } = containerRef.current.getBoundingClientRect(); + // Adjust these values to control how the logo scales + const baseWidth = 208; // Original SVG width + const newScale = width / baseWidth; + setScale(newScale); + }; + + updateScale(); + window.addEventListener("resize", updateScale); + return () => window.removeEventListener("resize", updateScale); + }, []); + return ( - <> -
- -
- +
+
+ +
+ + + + + + + + + + +
); } diff --git a/example/src/components/SvgHeader/SvgHeader.tsx b/example/src/components/SvgHeader/SvgHeader.tsx index 5f0cf48..f926ef5 100644 --- a/example/src/components/SvgHeader/SvgHeader.tsx +++ b/example/src/components/SvgHeader/SvgHeader.tsx @@ -1,6 +1,7 @@ "use client"; import { motion } from "framer-motion"; +import { logotype } from "./logotype"; type SvgHeaderProps = { className?: string; @@ -13,59 +14,14 @@ const SvgHeader = ({ className }: SvgHeaderProps) => ( xmlns="http://www.w3.org/2000/svg" className={className} > - - - - - - - - - - - ); diff --git a/example/src/components/SvgHeader/logotype.ts b/example/src/components/SvgHeader/logotype.ts new file mode 100644 index 0000000..21bacfb --- /dev/null +++ b/example/src/components/SvgHeader/logotype.ts @@ -0,0 +1,5 @@ +export const logotype = + "M9.176 17.62h-.789v16.021H.5V.121h7.887l11.288 21.246h.79L31.752.121h7.887v33.52h-7.887v-16.02h-.789l-7.345 13.753h-7.098L9.176 17.62Zm45.909 16.514c-4.108 0-7.312-.904-9.613-2.71-2.267-1.808-3.401-4.684-3.401-8.627V7.515h7.887v13.31c0 2.202.378 3.746 1.134 4.633.756.855 2.087 1.282 3.993 1.282 1.939 0 3.27-.427 3.993-1.282.755-.887 1.133-2.431 1.133-4.633V7.515h7.887v15.282c0 3.943-1.15 6.819-3.45 8.626-2.268 1.808-5.455 2.711-9.563 2.711ZM97.117 7.515v34.013H74.44v-7.394H89.23v-5.422c-.723.821-1.676 1.446-2.86 1.873-1.183.394-2.514.592-3.992.592-3.911 0-6.77-.953-8.578-2.86-1.807-1.938-2.71-4.765-2.71-8.478V7.515h7.886v11.83c0 2.959 1.71 4.437 5.127 4.437 3.418 0 5.127-1.478 5.127-4.436V7.516h7.887Zm3.965 26.126V.121h13.753c3.779 0 6.523.723 8.232 2.169 1.709 1.446 2.563 3.401 2.563 5.866 0 2.005-.624 3.714-1.873 5.127-1.216 1.38-2.99 2.07-5.324 2.07v.789c2.794 0 4.848.674 6.162 2.02 1.348 1.348 2.021 3.221 2.021 5.62 0 3.024-.871 5.423-2.612 7.197-1.709 1.775-4.765 2.662-9.169 2.662h-13.753Zm7.887-26.126v4.683h5.373c1.249 0 2.12-.148 2.613-.443.525-.296.788-.937.788-1.923 0-.953-.263-1.577-.788-1.873-.493-.296-1.364-.444-2.613-.444h-5.373Zm0 12.077v5.67h5.866c1.413 0 2.415-.165 3.007-.494.591-.361.887-1.134.887-2.317 0-1.216-.296-1.988-.887-2.316-.592-.362-1.594-.543-3.007-.543h-5.866Zm33.17 14.542c-4.107 0-7.312-.904-9.612-2.71-2.268-1.808-3.401-4.684-3.401-8.627V7.515h7.887v13.31c0 2.202.378 3.746 1.134 4.633.755.855 2.086 1.282 3.992 1.282 1.939 0 3.27-.427 3.993-1.282.756-.887 1.134-2.431 1.134-4.633V7.515h7.887v15.282c0 3.943-1.15 6.819-3.45 8.626-2.268 1.808-5.456 2.711-9.564 2.711Zm28.008 0c-5.16 0-8.709-1.347-10.648-4.042-1.906-2.695-2.859-5.833-2.859-9.415 0-4.042.937-7.329 2.81-9.859 1.906-2.53 4.896-3.796 8.971-3.796 3.977 0 6.885 1.216 8.726 3.648 1.84 2.4 2.76 5.537 2.76 9.415v2.958h-15.084c.263 1.347.854 2.3 1.775 2.86.953.558 2.464.837 4.535.837a40.43 40.43 0 0 0 7.098-.64v7.295c-1.709.328-3.155.526-4.338.591a44.03 44.03 0 0 1-3.746.148Zm1.824-16.02c-.132-1.315-.493-2.252-1.085-2.81-.591-.592-1.462-.888-2.612-.888-1.151 0-2.021.296-2.613.888-.592.558-.953 1.495-1.085 2.81h7.395Zm27.642-3.205h-9.859v18.732h-7.887V7.515H207.5v26.126h-7.887V14.91ZM18.29 36.135 9.07 78.528H.987l9.218-42.393h8.085Zm28.97 8.38h-8.824v26.126H30.55V44.515h-8.823v-7.394H47.26v7.394Zm25.034 0v34.013H49.62v-7.394h14.788v-5.422c-.723.821-1.676 1.446-2.859 1.873-1.183.394-2.514.592-3.993.592-3.91 0-6.77-.953-8.577-2.86-1.808-1.938-2.711-4.765-2.711-8.478V44.515h7.887v11.83c0 2.959 1.709 4.437 5.127 4.437 3.417 0 5.126-1.478 5.126-4.436v-11.83h7.887Zm17.94-.493c2.333 0 4.321.608 5.965 1.824 1.676 1.216 2.94 2.86 3.795 4.93s1.282 4.338 1.282 6.802c0 2.465-.427 4.732-1.282 6.803-.854 2.07-2.12 3.713-3.795 4.93-1.644 1.215-3.632 1.823-5.965 1.823-1.479 0-2.81-.28-3.993-.838-1.183-.558-2.218-1.512-3.105-2.859v11.091h-7.888V44.515h7.888v3.204c.887-1.347 1.922-2.3 3.105-2.859 1.183-.558 2.514-.838 3.993-.838ZM88.262 63.74c3.418 0 5.127-2.054 5.127-6.162 0-4.108-1.71-6.162-5.127-6.162-3.418 0-5.126 2.054-5.126 6.162 0 4.108 1.708 6.162 5.126 6.162Zm27.515 7.394c-5.16 0-8.709-1.347-10.648-4.042-1.906-2.695-2.859-5.833-2.859-9.415 0-4.042.936-7.329 2.81-9.859 1.906-2.53 4.896-3.796 8.971-3.796 3.977 0 6.885 1.216 8.725 3.648 1.841 2.4 2.761 5.538 2.761 9.415v2.958h-15.084c.263 1.347.854 2.3 1.774 2.86.953.558 2.465.837 4.535.837 2.334 0 4.7-.214 7.099-.64v7.295c-1.709.329-3.155.526-4.338.591a44.03 44.03 0 0 1-3.746.148Zm1.823-16.02c-.131-1.315-.493-2.252-1.084-2.81-.592-.592-1.462-.888-2.613-.888-1.15 0-2.021.296-2.612.888-.592.558-.953 1.495-1.085 2.81h7.394Z"; + +export const logotypeBottom = + "M18.29 36.135 9.07 78.528H.987l9.218-42.393h8.085Zm28.97 8.38h-8.824v26.126H30.55V44.515h-8.823v-7.394H47.26v7.394Zm25.034 0v34.013H49.62v-7.394h14.788v-5.422c-.723.821-1.676 1.446-2.859 1.873-1.183.394-2.514.592-3.993.592-3.91 0-6.77-.953-8.577-2.86-1.808-1.938-2.711-4.765-2.711-8.478V44.515h7.887v11.83c0 2.959 1.709 4.437 5.127 4.437 3.417 0 5.126-1.478 5.126-4.436v-11.83h7.887Z";