diff --git a/README.md b/README.md
index e0b27e6a..f3c98c78 100644
--- a/README.md
+++ b/README.md
@@ -1,5 +1,98 @@
[![SATUS](https://assets.darkroom.engineering/satus/header.png)](https://github.com/darkroomengineering/satus)
+# Satus
+
+A modern React application with advanced features including WebGL graphics, animations, and CMS integration.
+
+## Project Structure
+
+```
+├── app/ # Next.js application pages and routes
+│ └── (pages)/ # Page components and layouts
+├── components/ # Reusable UI components
+│ ├── button/ # Button components
+│ ├── form/ # Form components
+│ ├── animation/ # Animation components
+│ └── ... # Other UI components
+├── cms/ # CMS integrations
+│ ├── storyblok/ # Storyblok CMS integration
+│ └── shopify/ # Shopify integration
+├── hooks/ # Custom React hooks
+│ ├── use-scroll-trigger.ts
+│ ├── use-transform.tsx
+│ └── use-device-detection.ts
+├── libs/ # Utility libraries and functions
+│ ├── utils.ts
+│ ├── maths.ts
+│ └── store.ts
+└── webgl/ # WebGL and 3D graphics
+ ├── components/ # WebGL components
+ ├── hooks/ # WebGL-specific hooks
+ └── utils/ # WebGL utilities
+```
+
+## Features
+
+- **Modern React Development**
+ - Next.js for server-side rendering and routing
+ - TypeScript for type safety
+ - Custom hooks for reusable logic
+
+- **Rich UI Components**
+ - Extensive component library
+ - Animation and interaction capabilities
+ - Responsive and accessible design
+
+- **3D Graphics and WebGL**
+ - Three.js integration
+ - Custom WebGL shaders
+ - React Three Fiber (R3F) implementation
+
+- **CMS Integration**
+ - Storyblok for content management
+ - Shopify for e-commerce
+ - Headless CMS architecture
+
+- **Developer Experience**
+ - Hot module replacement
+ - Development tools and debugging
+ - Comprehensive documentation
+
+## Getting Started
+
+1. Install dependencies:
+```bash
+npm install
+```
+
+2. Run the development server:
+```bash
+npm run dev
+```
+
+3. Build for production:
+```bash
+npm run build
+```
+
+## Documentation
+
+Each major directory contains its own README with specific documentation:
+
+- [Components Documentation](./components/README.md)
+- [Hooks Documentation](./hooks/README.md)
+- [WebGL Documentation](./webgl/README.md)
+- [CMS Integration Documentation](./cms/README.md)
+- [Utility Libraries Documentation](./libs/README.md)
+
+## Contributing
+
+Please read our contributing guidelines before submitting pull requests.
+
+## License
+
+This project is licensed under the MIT License - see the LICENSE file for details.
+
# Satūs
Satūs means start, beginning, planting, to be used as a template when starting a new project.
diff --git a/app/(pages)/(components)/wrapper/index.tsx b/app/(pages)/(components)/wrapper/index.tsx
index 6b758d24..d0fe1027 100644
--- a/app/(pages)/(components)/wrapper/index.tsx
+++ b/app/(pages)/(components)/wrapper/index.tsx
@@ -5,8 +5,8 @@ import type { LenisOptions } from 'lenis'
import { usePathname } from 'next/navigation'
import { type ComponentProps, useEffect } from 'react'
-import { Canvas } from '~/libs/webgl/components/canvas'
import type { Theme } from '~/styles/config'
+import { Canvas } from '~/webgl/components/canvas'
import { Footer } from '../footer'
import { Lenis } from '../lenis'
import { Navigation } from '../navigation'
diff --git a/app/(pages)/hubspot/(components)/subscribe/index.jsx b/app/(pages)/hubspot/(components)/subscribe/index.jsx
index 479fd314..25d8dbf9 100644
--- a/app/(pages)/hubspot/(components)/subscribe/index.jsx
+++ b/app/(pages)/hubspot/(components)/subscribe/index.jsx
@@ -1,7 +1,7 @@
'use client'
import cn from 'clsx'
-import { Messages, SubmitButton, useFormContext } from '~/libs/form'
+import { Messages, SubmitButton, useFormContext } from '~/components/form'
export const Subscribe = ({ idx = 0, form }) => {
const { errors, isActive, register } = useFormContext()
diff --git a/app/(pages)/hubspot/page.jsx b/app/(pages)/hubspot/page.jsx
index e0b08e03..c605a6e5 100644
--- a/app/(pages)/hubspot/page.jsx
+++ b/app/(pages)/hubspot/page.jsx
@@ -1,6 +1,6 @@
import { Wrapper } from '~/app/(pages)/(components)/wrapper'
-import { Form } from '~/libs/form'
-import { getForm } from '~/libs/hubspot-forms/fetch-form'
+import { Form } from '~/components/form'
+import { getForm } from '~/components/hubspot/fetch-form'
import { Subscribe } from './(components)/subscribe'
export default async function Hubspot() {
diff --git a/app/(pages)/r3f/(components)/box/index.jsx b/app/(pages)/r3f/(components)/box/index.jsx
index b2363daf..c513798d 100644
--- a/app/(pages)/r3f/(components)/box/index.jsx
+++ b/app/(pages)/r3f/(components)/box/index.jsx
@@ -2,7 +2,7 @@
import { useRect } from 'hamo'
import dynamic from 'next/dynamic'
-import { WebGLTunnel } from '~/libs/webgl/components/tunnel'
+import { WebGLTunnel } from '~/webgl/components/tunnel'
const WebGLBox = dynamic(
() => import('./webgl').then(({ WebGLBox }) => WebGLBox),
diff --git a/app/(pages)/r3f/(components)/box/webgl.jsx b/app/(pages)/r3f/(components)/box/webgl.jsx
index 8a8a2761..ecb9fae0 100644
--- a/app/(pages)/r3f/(components)/box/webgl.jsx
+++ b/app/(pages)/r3f/(components)/box/webgl.jsx
@@ -2,9 +2,9 @@
import { useFrame } from '@react-three/fiber'
import { useRef } from 'react'
-import { useCurrentSheet } from '~/libs/theatre'
-import { useTheatre } from '~/libs/theatre/hooks/use-theatre'
-import { useWebGLRect } from '~/libs/webgl/hooks/use-webgl-rect'
+import { useCurrentSheet } from '~/app/theatre'
+import { useTheatre } from '~/app/theatre/hooks/use-theatre'
+import { useWebGLRect } from '~/webgl/hooks/use-webgl-rect'
export function WebGLBox({ theatreKey = 'box', rect }) {
const meshRef = useRef()
diff --git a/app/(pages)/r3f/page.jsx b/app/(pages)/r3f/page.jsx
index bcf95e27..f5724fc1 100644
--- a/app/(pages)/r3f/page.jsx
+++ b/app/(pages)/r3f/page.jsx
@@ -1,6 +1,6 @@
import { Wrapper } from '~/app/(pages)/(components)/wrapper'
-import { TheatreProjectProvider } from '~/libs/theatre'
-import { Canvas } from '~/libs/webgl/components/canvas'
+import { TheatreProjectProvider } from '~/app/theatre'
+import { Canvas } from '~/webgl/components/canvas'
import { Box } from './(components)/box'
export default function Home() {
diff --git a/app/(pages)/shopify/(components)/customer/index.jsx b/app/(pages)/shopify/(components)/customer/index.jsx
index fa37843e..ce542765 100644
--- a/app/(pages)/shopify/(components)/customer/index.jsx
+++ b/app/(pages)/shopify/(components)/customer/index.jsx
@@ -1,7 +1,7 @@
'use client'
-import { Form, SubmitButton } from '~/libs/form'
-import { InputField } from '~/libs/form/fields'
+import { Form, SubmitButton } from '~/components/form'
+import { InputField } from '~/components/form/fields'
// import {
// LoginCustomerAction,
diff --git a/app/(pages)/shopify/(components)/product/index.jsx b/app/(pages)/shopify/(components)/product/index.jsx
index 6a2a7432..a92a4e41 100644
--- a/app/(pages)/shopify/(components)/product/index.jsx
+++ b/app/(pages)/shopify/(components)/product/index.jsx
@@ -1,6 +1,6 @@
import cn from 'clsx'
+import { getCollectionProducts } from '~/cms/shopify'
import { Image } from '~/components/image'
-import { getCollectionProducts } from '~/libs/shopify'
import { SizeAndBuy } from '../size-and-buy'
import s from './product.module.css'
diff --git a/app/(pages)/shopify/(components)/show-cart/index.jsx b/app/(pages)/shopify/(components)/show-cart/index.jsx
index 9333e313..760d41dd 100644
--- a/app/(pages)/shopify/(components)/show-cart/index.jsx
+++ b/app/(pages)/shopify/(components)/show-cart/index.jsx
@@ -1,7 +1,7 @@
'use client'
import cn from 'clsx'
-import { useCartModal } from '~/libs/shopify/cart/modal'
+import { useCartModal } from '~/cms/shopify/cart/modal'
export const ShowCart = ({ className }) => {
const { openCart } = useCartModal()
diff --git a/app/(pages)/shopify/(components)/size-and-buy/index.jsx b/app/(pages)/shopify/(components)/size-and-buy/index.jsx
index c7e64303..a1979fdc 100644
--- a/app/(pages)/shopify/(components)/size-and-buy/index.jsx
+++ b/app/(pages)/shopify/(components)/size-and-buy/index.jsx
@@ -2,8 +2,8 @@
import cn from 'clsx'
import { useState } from 'react'
+import { AddToCart } from '~/cms/shopify/cart/add-to-cart'
import { Dropdown } from '~/components/dropdown'
-import { AddToCart } from '~/libs/shopify/cart/add-to-cart'
import s from './size-and-buy.module.css'
export const SizeAndBuy = ({ product }) => {
diff --git a/app/(pages)/shopify/account/page.jsx b/app/(pages)/shopify/account/page.jsx
index 242a9370..9949d4db 100644
--- a/app/(pages)/shopify/account/page.jsx
+++ b/app/(pages)/shopify/account/page.jsx
@@ -1,6 +1,6 @@
import { Suspense } from 'react'
import { Wrapper } from '~/app/(pages)/(components)/wrapper'
-import { getCustomer } from '~/libs/shopify/customer/actions'
+import { getCustomer } from '~/cms/shopify/customer/actions'
import { LoginForm, LogoutButton, RegisterForm } from '../(components)/customer'
export default async function AccountPage() {
diff --git a/app/(pages)/shopify/page.jsx b/app/(pages)/shopify/page.jsx
index 888bffa5..227912cc 100644
--- a/app/(pages)/shopify/page.jsx
+++ b/app/(pages)/shopify/page.jsx
@@ -1,5 +1,5 @@
import { Wrapper } from '~/app/(pages)/(components)/wrapper'
-import { Cart } from '~/libs/shopify/cart'
+import { Cart } from '~/cms/shopify/cart'
import { Product } from './(components)/product'
import { ShowCart } from './(components)/show-cart'
diff --git a/app/(pages)/storyblok/(component)/tutorial/index.jsx b/app/(pages)/storyblok/(component)/tutorial/index.jsx
index 831fc2d0..9d15f7dc 100644
--- a/app/(pages)/storyblok/(component)/tutorial/index.jsx
+++ b/app/(pages)/storyblok/(component)/tutorial/index.jsx
@@ -1,7 +1,7 @@
'use client'
import { storyblokEditable } from '@storyblok/js'
-import { useStoryblokContext } from '~/libs/storyblok/context'
+import { useStoryblokContext } from '~/cms/storyblok/context'
// TODO:
// - Webhooks
diff --git a/app/(pages)/storyblok/[slug]/(component)/article/index.jsx b/app/(pages)/storyblok/[slug]/(component)/article/index.jsx
index ee793f4d..43da736a 100644
--- a/app/(pages)/storyblok/[slug]/(component)/article/index.jsx
+++ b/app/(pages)/storyblok/[slug]/(component)/article/index.jsx
@@ -1,7 +1,7 @@
'use client'
import { storyblokEditable } from '@storyblok/js'
-import { useStoryblokContext } from '~/libs/storyblok/context'
+import { useStoryblokContext } from '~/cms/storyblok/context'
export function Article() {
const {
diff --git a/app/(pages)/storyblok/[slug]/page.jsx b/app/(pages)/storyblok/[slug]/page.jsx
index b822c1b8..6d9520c2 100644
--- a/app/(pages)/storyblok/[slug]/page.jsx
+++ b/app/(pages)/storyblok/[slug]/page.jsx
@@ -1,6 +1,6 @@
import { notFound } from 'next/navigation'
-import { fetchAll, fetchStoryblokStory } from '~/libs/storyblok'
-import { StoryblokContextProvider } from '~/libs/storyblok/context'
+import { fetchAll, fetchStoryblokStory } from '~/cms/storyblok'
+import { StoryblokContextProvider } from '~/cms/storyblok/context'
import { Wrapper } from '../../(components)/wrapper'
import { Article } from './(component)/article'
diff --git a/app/(pages)/storyblok/page.jsx b/app/(pages)/storyblok/page.jsx
index e126a699..023aff82 100644
--- a/app/(pages)/storyblok/page.jsx
+++ b/app/(pages)/storyblok/page.jsx
@@ -1,5 +1,5 @@
-import { fetchStoryblokStory } from '~/libs/storyblok'
-import { StoryblokContextProvider } from '~/libs/storyblok/context'
+import { fetchStoryblokStory } from '~/cms/storyblok'
+import { StoryblokContextProvider } from '~/cms/storyblok/context'
import { Wrapper } from '../(components)/wrapper'
import { Tutorial } from './(component)/tutorial'
diff --git a/libs/orchestra/grid/grid.module.css b/app/debug/orchestra/grid/grid.module.css
similarity index 100%
rename from libs/orchestra/grid/grid.module.css
rename to app/debug/orchestra/grid/grid.module.css
diff --git a/libs/orchestra/grid/index.tsx b/app/debug/orchestra/grid/index.tsx
similarity index 100%
rename from libs/orchestra/grid/index.tsx
rename to app/debug/orchestra/grid/index.tsx
diff --git a/libs/orchestra/index.ts b/app/debug/orchestra/index.ts
similarity index 100%
rename from libs/orchestra/index.ts
rename to app/debug/orchestra/index.ts
diff --git a/libs/orchestra/minimap/index.tsx b/app/debug/orchestra/minimap/index.tsx
similarity index 100%
rename from libs/orchestra/minimap/index.tsx
rename to app/debug/orchestra/minimap/index.tsx
diff --git a/libs/orchestra/minimap/minimap.module.css b/app/debug/orchestra/minimap/minimap.module.css
similarity index 100%
rename from libs/orchestra/minimap/minimap.module.css
rename to app/debug/orchestra/minimap/minimap.module.css
diff --git a/app/debug/orchestra/page.jsx b/app/debug/orchestra/page.jsx
index e25f5b83..c302ff6a 100644
--- a/app/debug/orchestra/page.jsx
+++ b/app/debug/orchestra/page.jsx
@@ -1,8 +1,14 @@
'use client'
-import { OrchestraToggle } from '~/libs/orchestra/react'
+import dynamic from 'next/dynamic'
import s from './orchestra.module.css'
+const OrchestraToggle = dynamic(
+ () =>
+ import('~/app/debug/orchestra/react').then((mod) => mod.OrchestraToggle),
+ { ssr: false }
+)
+
function OrchestraPage() {
return (
diff --git a/libs/orchestra/react.tsx b/app/debug/orchestra/react.tsx
similarity index 100%
rename from libs/orchestra/react.tsx
rename to app/debug/orchestra/react.tsx
diff --git a/libs/orchestra/stats/index.ts b/app/debug/orchestra/stats/index.ts
similarity index 100%
rename from libs/orchestra/stats/index.ts
rename to app/debug/orchestra/stats/index.ts
diff --git a/libs/orchestra/stats/stats.module.css b/app/debug/orchestra/stats/stats.module.css
similarity index 100%
rename from libs/orchestra/stats/stats.module.css
rename to app/debug/orchestra/stats/stats.module.css
diff --git a/app/storyblok-sitemap.js b/app/storyblok-sitemap.js
deleted file mode 100644
index fc15a5c2..00000000
--- a/app/storyblok-sitemap.js
+++ /dev/null
@@ -1,57 +0,0 @@
-// this file is used to generate the sitemap websites using storyblok
-
-import { StoryblokApi } from '~/libs/storyblok'
-
-const storyblokApi = new StoryblokApi()
-
-// replace with your website url
-const URL = 'https://example.com'
-
-// add your predefined static routes
-const predefinedStaticRoutes = ['', '/blog', '/about', '/careers']
-
-async function fetchAllStories() {
- let page = 1
- let hasMoreStories = true
- let allStories = []
-
- while (hasMoreStories) {
- try {
- const { data } = await storyblokApi.get('cdn/stories', {
- version: 'published',
- per_page: 100,
- page: page,
- excluding_fields: 'body',
- })
-
- allStories = [...allStories, ...data.stories]
-
- if (data.stories.length < 100) {
- hasMoreStories = false
- } else {
- page++
- }
- } catch (error) {
- console.error('Error fetching stories:', error)
- hasMoreStories = false
- }
- }
-
- return allStories
-}
-
-export default async function sitemap() {
- const stories = await fetchAllStories()
-
- const routes = stories.map((story) => ({
- url: `${URL}/${story.full_slug}`,
- lastModified: new Date(story.published_at).toISOString(),
- }))
-
- const staticRoutes = predefinedStaticRoutes.map((route) => ({
- url: `${URL}${route}`,
- lastModified: new Date().toISOString(),
- }))
-
- return [...staticRoutes, ...routes]
-}
diff --git a/libs/theatre/hooks/use-studio.ts b/app/theatre/hooks/use-studio.ts
similarity index 95%
rename from libs/theatre/hooks/use-studio.ts
rename to app/theatre/hooks/use-studio.ts
index 2be02890..3daf3da2 100644
--- a/libs/theatre/hooks/use-studio.ts
+++ b/app/theatre/hooks/use-studio.ts
@@ -1,7 +1,7 @@
import type { ISheet } from '@theatre/core'
import type { IStudio } from '@theatre/studio'
import { useEffect, useState } from 'react'
-import { useOrchestra } from '~/libs/orchestra/react'
+import { useOrchestra } from '~/app/debug/orchestra/react'
let studioPackage: IStudio
diff --git a/libs/theatre/hooks/use-theatre.ts b/app/theatre/hooks/use-theatre.ts
similarity index 100%
rename from libs/theatre/hooks/use-theatre.ts
rename to app/theatre/hooks/use-theatre.ts
diff --git a/libs/theatre/index.tsx b/app/theatre/index.tsx
similarity index 100%
rename from libs/theatre/index.tsx
rename to app/theatre/index.tsx
diff --git a/libs/theatre/r3f.tsx b/app/theatre/r3f.tsx
similarity index 100%
rename from libs/theatre/r3f.tsx
rename to app/theatre/r3f.tsx
diff --git a/libs/theatre/studio/index.tsx b/app/theatre/studio/index.tsx
similarity index 100%
rename from libs/theatre/studio/index.tsx
rename to app/theatre/studio/index.tsx
diff --git a/libs/theatre/studio/studio.module.css b/app/theatre/studio/studio.module.css
similarity index 100%
rename from libs/theatre/studio/studio.module.css
rename to app/theatre/studio/studio.module.css
diff --git a/cms/README.md b/cms/README.md
new file mode 100644
index 00000000..78ba029a
--- /dev/null
+++ b/cms/README.md
@@ -0,0 +1,15 @@
+# CMS Integration
+
+This directory contains integrations with various Content Management Systems used in the project.
+
+## Structure
+
+- `storyblok/` - Integration with Storyblok CMS for managing content
+- `shopify/` - Integration with Shopify for e-commerce functionality
+
+## Usage
+
+The CMS integrations provide a bridge between our application and external content management systems, allowing for:
+- Dynamic content management through Storyblok
+- E-commerce functionality through Shopify
+- Separation of concerns between content and presentation
diff --git a/libs/shopify/cart/actions.js b/cms/shopify/cart/actions.js
similarity index 97%
rename from libs/shopify/cart/actions.js
rename to cms/shopify/cart/actions.js
index 219e769d..f39c7999 100644
--- a/libs/shopify/cart/actions.js
+++ b/cms/shopify/cart/actions.js
@@ -8,8 +8,8 @@ import {
getCart,
removeFromCart,
updateCart,
-} from '~/libs/shopify'
-import { TAGS } from '~/libs/shopify/constants'
+} from '~/cms/shopify'
+import { TAGS } from '~/cms/shopify/constants'
export async function removeItem(prevState, merchandiseId) {
const _cookies = await cookies()
diff --git a/libs/shopify/cart/add-to-cart/add-to-cart.module.css b/cms/shopify/cart/add-to-cart/add-to-cart.module.css
similarity index 100%
rename from libs/shopify/cart/add-to-cart/add-to-cart.module.css
rename to cms/shopify/cart/add-to-cart/add-to-cart.module.css
diff --git a/libs/shopify/cart/add-to-cart/index.js b/cms/shopify/cart/add-to-cart/index.js
similarity index 94%
rename from libs/shopify/cart/add-to-cart/index.js
rename to cms/shopify/cart/add-to-cart/index.js
index bc29252b..0633ae7f 100644
--- a/libs/shopify/cart/add-to-cart/index.js
+++ b/cms/shopify/cart/add-to-cart/index.js
@@ -1,7 +1,7 @@
'use client'
import cn from 'clsx'
-import { addItem } from '~/libs/shopify/cart/actions'
+import { addItem } from '~/cms/shopify/cart/actions'
import { useCartContext } from '../cart-context'
import { useCartModal } from '../modal'
import s from './add-to-cart.module.css'
diff --git a/libs/shopify/cart/cart-context.js b/cms/shopify/cart/cart-context.js
similarity index 98%
rename from libs/shopify/cart/cart-context.js
rename to cms/shopify/cart/cart-context.js
index a7a83350..1278c918 100644
--- a/libs/shopify/cart/cart-context.js
+++ b/cms/shopify/cart/cart-context.js
@@ -13,7 +13,7 @@ export function useCartContext() {
export function CartProvider({ children, cart }) {
const [optimisticCart, updateOptimisticCart] = useOptimistic(
cart,
- cartReconciler,
+ cartReconciler
)
function updateCartItem(merchandiseId, updateType) {
diff --git a/libs/shopify/cart/index.js b/cms/shopify/cart/index.js
similarity index 100%
rename from libs/shopify/cart/index.js
rename to cms/shopify/cart/index.js
diff --git a/libs/shopify/cart/modal/index.js b/cms/shopify/cart/modal/index.js
similarity index 100%
rename from libs/shopify/cart/modal/index.js
rename to cms/shopify/cart/modal/index.js
diff --git a/libs/shopify/cart/modal/modal.module.css b/cms/shopify/cart/modal/modal.module.css
similarity index 100%
rename from libs/shopify/cart/modal/modal.module.css
rename to cms/shopify/cart/modal/modal.module.css
diff --git a/libs/shopify/cart/optimistic-utils.js b/cms/shopify/cart/optimistic-utils.js
similarity index 100%
rename from libs/shopify/cart/optimistic-utils.js
rename to cms/shopify/cart/optimistic-utils.js
diff --git a/libs/shopify/constants.js b/cms/shopify/constants.js
similarity index 100%
rename from libs/shopify/constants.js
rename to cms/shopify/constants.js
diff --git a/libs/shopify/customer/actions.js b/cms/shopify/customer/actions.js
similarity index 98%
rename from libs/shopify/customer/actions.js
rename to cms/shopify/customer/actions.js
index 4f727d15..aa905a7b 100644
--- a/libs/shopify/customer/actions.js
+++ b/cms/shopify/customer/actions.js
@@ -1,7 +1,7 @@
'use server'
import { cookies } from 'next/headers'
-import { shopifyFetch } from '~/libs/shopify'
+import { shopifyFetch } from '~/cms/shopify'
import {
customerAccessTokenCreateMutation,
customerAccessTokenDeleteMutation,
diff --git a/libs/shopify/fragments/cart.js b/cms/shopify/fragments/cart.js
similarity index 100%
rename from libs/shopify/fragments/cart.js
rename to cms/shopify/fragments/cart.js
diff --git a/libs/shopify/fragments/image.js b/cms/shopify/fragments/image.js
similarity index 100%
rename from libs/shopify/fragments/image.js
rename to cms/shopify/fragments/image.js
diff --git a/libs/shopify/fragments/product.js b/cms/shopify/fragments/product.js
similarity index 100%
rename from libs/shopify/fragments/product.js
rename to cms/shopify/fragments/product.js
diff --git a/libs/shopify/fragments/seo.js b/cms/shopify/fragments/seo.js
similarity index 100%
rename from libs/shopify/fragments/seo.js
rename to cms/shopify/fragments/seo.js
diff --git a/libs/shopify/hooks.js b/cms/shopify/hooks.js
similarity index 100%
rename from libs/shopify/hooks.js
rename to cms/shopify/hooks.js
diff --git a/libs/shopify/index.js b/cms/shopify/index.js
similarity index 99%
rename from libs/shopify/index.js
rename to cms/shopify/index.js
index daae95ec..644af993 100644
--- a/libs/shopify/index.js
+++ b/cms/shopify/index.js
@@ -5,7 +5,7 @@ import {
HIDDEN_PRODUCT_TAG,
SHOPIFY_GRAPHQL_API_ENDPOINT,
TAGS,
-} from '~/libs/shopify/constants'
+} from '~/cms/shopify/constants'
import {
addToCartMutation,
createCartMutation,
diff --git a/libs/shopify/mutations/cart.js b/cms/shopify/mutations/cart.js
similarity index 100%
rename from libs/shopify/mutations/cart.js
rename to cms/shopify/mutations/cart.js
diff --git a/libs/shopify/mutations/customer.js b/cms/shopify/mutations/customer.js
similarity index 100%
rename from libs/shopify/mutations/customer.js
rename to cms/shopify/mutations/customer.js
diff --git a/libs/shopify/queries/cart.js b/cms/shopify/queries/cart.js
similarity index 100%
rename from libs/shopify/queries/cart.js
rename to cms/shopify/queries/cart.js
diff --git a/libs/shopify/queries/collection.js b/cms/shopify/queries/collection.js
similarity index 100%
rename from libs/shopify/queries/collection.js
rename to cms/shopify/queries/collection.js
diff --git a/libs/shopify/queries/customer.js b/cms/shopify/queries/customer.js
similarity index 100%
rename from libs/shopify/queries/customer.js
rename to cms/shopify/queries/customer.js
diff --git a/libs/shopify/queries/menu.js b/cms/shopify/queries/menu.js
similarity index 100%
rename from libs/shopify/queries/menu.js
rename to cms/shopify/queries/menu.js
diff --git a/libs/shopify/queries/page.js b/cms/shopify/queries/page.js
similarity index 100%
rename from libs/shopify/queries/page.js
rename to cms/shopify/queries/page.js
diff --git a/libs/shopify/queries/product.js b/cms/shopify/queries/product.js
similarity index 100%
rename from libs/shopify/queries/product.js
rename to cms/shopify/queries/product.js
diff --git a/docs/storyblok/README.md b/cms/storyblok/README.md
similarity index 100%
rename from docs/storyblok/README.md
rename to cms/storyblok/README.md
diff --git a/libs/storyblok/context.tsx b/cms/storyblok/context.tsx
similarity index 56%
rename from libs/storyblok/context.tsx
rename to cms/storyblok/context.tsx
index 99dcfd9a..9ad50e67 100644
--- a/libs/storyblok/context.tsx
+++ b/cms/storyblok/context.tsx
@@ -1,9 +1,9 @@
-"use client";
+'use client'
// https://www.storyblok.com/docs/Guides/storyblok-latest-js?utm_source=github.com&utm_medium=readme&utm_campaign=storyblok-js
-import type { ISbStoryData, StoryblokBridgeConfigV2 } from "@storyblok/js";
-import Script, { type ScriptProps } from "next/script";
+import type { ISbStoryData, StoryblokBridgeConfigV2 } from '@storyblok/js'
+import Script, { type ScriptProps } from 'next/script'
import {
type PropsWithChildren,
Suspense,
@@ -11,19 +11,19 @@ import {
useCallback,
useContext,
useState,
-} from "react";
-import { useIsVisualEditor } from "./use-is-visual-editor";
+} from 'react'
+import { useIsVisualEditor } from './use-is-visual-editor'
-export const StoryblokContext = createContext({});
+export const StoryblokContext = createContext({})
export function useStoryblokContext() {
- return useContext(StoryblokContext);
+ return useContext(StoryblokContext)
}
-const BRIDGE_URL = "//app.storyblok.com/f/storyblok-v2-latest.js";
+const BRIDGE_URL = '//app.storyblok.com/f/storyblok-v2-latest.js'
-function StoryblokBridge({ onLoad }: { onLoad: ScriptProps["onLoad"] }) {
- const isVisualEditor = useIsVisualEditor();
+function StoryblokBridge({ onLoad }: { onLoad: ScriptProps['onLoad'] }) {
+ const isVisualEditor = useIsVisualEditor()
// console.log('isVisualEditor', isVisualEditor)
@@ -36,35 +36,35 @@ function StoryblokBridge({ onLoad }: { onLoad: ScriptProps["onLoad"] }) {
strategy="afterInteractive"
/>
)
- );
+ )
}
type StoryblokContextProviderProps = {
- story: ISbStoryData;
- options: StoryblokBridgeConfigV2;
-};
+ story: ISbStoryData
+ options: StoryblokBridgeConfigV2
+}
export function StoryblokContextProvider({
story,
options,
children,
}: PropsWithChildren
) {
- const id = story.id;
+ const id = story.id
- const [liveStory, setLiveStory] = useState(story);
+ const [liveStory, setLiveStory] = useState(story)
const onLoad = useCallback(() => {
// console.log('StoryblokBridge loaded')
- const bridge = new window.StoryblokBridge(options);
+ const bridge = new window.StoryblokBridge(options)
- bridge.on("input", (payload) => {
- if (!payload) return;
+ bridge.on('input', (payload) => {
+ if (!payload) return
// console.log('input', story)
if (payload.story?.id === id) {
- setLiveStory(payload.story);
+ setLiveStory(payload.story)
}
- });
- }, [id, options]);
+ })
+ }, [id, options])
return (
<>
@@ -75,5 +75,5 @@ export function StoryblokContextProvider({
{children}
>
- );
+ )
}
diff --git a/libs/storyblok/index.ts b/cms/storyblok/index.ts
similarity index 100%
rename from libs/storyblok/index.ts
rename to cms/storyblok/index.ts
diff --git a/libs/storyblok/renderer.tsx b/cms/storyblok/renderer.tsx
similarity index 64%
rename from libs/storyblok/renderer.tsx
rename to cms/storyblok/renderer.tsx
index e97c1595..4923202d 100644
--- a/libs/storyblok/renderer.tsx
+++ b/cms/storyblok/renderer.tsx
@@ -8,15 +8,15 @@ import {
type RenderOptions,
type StoryblokRichtext,
render,
-} from "storyblok-rich-text-react-renderer";
-import { Image } from "~/components/image";
-import { Link } from "~/components/link";
+} from 'storyblok-rich-text-react-renderer'
+import { Image } from '~/components/image'
+import { Link } from '~/components/link'
type RenderRichTextOptions = {
- markResolvers?: RenderOptions["markResolvers"];
- nodeResolvers?: RenderOptions["nodeResolvers"];
- blokResolvers?: RenderOptions["blokResolvers"];
-};
+ markResolvers?: RenderOptions['markResolvers']
+ nodeResolvers?: RenderOptions['nodeResolvers']
+ blokResolvers?: RenderOptions['blokResolvers']
+}
export function renderRichText(
content: StoryblokRichtext | unknown,
@@ -38,19 +38,19 @@ export function renderRichText(
[NODE_HEADING]: (children, { level }) => {
switch (level) {
case 1:
- return {children}
;
+ return {children}
case 2:
- return {children}
;
+ return {children}
case 3:
- return {children}
;
+ return {children}
case 4:
- return {children}
;
+ return {children}
case 5:
- return {children}
;
+ return {children}
case 6:
- return {children}
;
+ return {children}
default:
- return null;
+ return null
}
},
[NODE_PARAGRAPH]: (children) => {children}
,
@@ -59,12 +59,12 @@ export function renderRichText(
blokResolvers: {
...blokResolvers,
},
- });
+ })
}
type RichTextProps = {
- content: StoryblokRichtext | unknown;
-} & RenderRichTextOptions;
+ content: StoryblokRichtext | unknown
+} & RenderRichTextOptions
export function RichText({
content,
@@ -76,5 +76,5 @@ export function RichText({
markResolvers,
nodeResolvers,
blokResolvers,
- });
+ })
}
diff --git a/libs/storyblok/use-is-visual-editor.ts b/cms/storyblok/use-is-visual-editor.ts
similarity index 100%
rename from libs/storyblok/use-is-visual-editor.ts
rename to cms/storyblok/use-is-visual-editor.ts
diff --git a/components/README.md b/components/README.md
new file mode 100644
index 00000000..3c108055
--- /dev/null
+++ b/components/README.md
@@ -0,0 +1,49 @@
+# UI Components
+
+This directory contains reusable UI components used throughout the application.
+
+## Component Categories
+
+### Core Components
+- `button/` - Button components with various styles and states
+- `link/` - Custom link components for navigation
+- `form/` - Form-related components and inputs
+- `image/` - Image components with optimization and lazy loading
+- `select/` - Custom select/dropdown components
+- `dropdown/` - Dropdown menu components
+
+### Animation Components
+- `animated-gradient/` - Gradient animation components
+- `gsap/` - GSAP-powered animation components
+- `marquee/` - Scrolling marquee components
+- `progress-text/` - Animated text progress indicators
+- `split-text/` - Text splitting animation components
+
+### Layout Components
+- `accordion/` - Expandable accordion components
+- `fold/` - Folding animation components
+- `real-viewport/` - Viewport-aware components
+- `scrollbar/` - Custom scrollbar components
+
+### Integration Components
+- `hubspot/` - HubSpot form integration components
+- `debug/` - Debugging and development tools
+- `console/` - Console logging components
+
+## Features
+
+- Modern, responsive design
+- Accessibility-first approach
+- Animation and interaction capabilities
+- Integration with external services
+- Debugging and development tools
+
+## Usage
+
+Import components directly from their respective directories:
+
+```typescript
+import Button from '~/components/button'
+import Link from '~/components/link'
+import Form from '~/components/form'
+```
diff --git a/components/accordion/index.tsx b/components/accordion/index.tsx
index dfe506f1..4f6ed4cb 100644
--- a/components/accordion/index.tsx
+++ b/components/accordion/index.tsx
@@ -104,14 +104,14 @@ function Body({
}: { children?: ReactNode; className?: string }) {
const { isOpen } = useAccordionContext()
- const [setRectRef, { contentRect: rect }] = useResizeObserver()
+ const [setRectRef, entry] = useResizeObserver()
return (
diff --git a/components/animated-gradient/index.tsx b/components/animated-gradient/index.tsx
index 0d76c5f5..f2006d13 100644
--- a/components/animated-gradient/index.tsx
+++ b/components/animated-gradient/index.tsx
@@ -3,7 +3,7 @@
import { useRect } from 'hamo'
import dynamic from 'next/dynamic'
import type { CSSProperties, ComponentProps } from 'react'
-import { WebGLTunnel } from '~/libs/webgl/components/tunnel'
+import { WebGLTunnel } from '~/webgl/components/tunnel'
const WebGLAnimatedGradient = dynamic(
() =>
@@ -15,6 +15,38 @@ const WebGLAnimatedGradient = dynamic(
}
)
+const toDOMRect = (
+ rect: {
+ width?: number
+ height?: number
+ top?: number
+ left?: number
+ right?: number
+ bottom?: number
+ x?: number
+ y?: number
+ } | null
+): DOMRect => ({
+ top: rect?.top ?? 0,
+ right: rect?.right ?? 0,
+ bottom: rect?.bottom ?? 0,
+ left: rect?.left ?? 0,
+ width: rect?.width ?? 0,
+ height: rect?.height ?? 0,
+ x: rect?.x ?? 0,
+ y: rect?.y ?? 0,
+ toJSON: () => ({
+ top: rect?.top ?? 0,
+ right: rect?.right ?? 0,
+ bottom: rect?.bottom ?? 0,
+ left: rect?.left ?? 0,
+ width: rect?.width ?? 0,
+ height: rect?.height ?? 0,
+ x: rect?.x ?? 0,
+ y: rect?.y ?? 0,
+ }),
+})
+
type AnimatedGradientProps = {
className?: string
style?: CSSProperties
@@ -30,7 +62,7 @@ export function AnimatedGradient({
return (
-
+
)
diff --git a/components/animated-gradient/material.ts b/components/animated-gradient/material.ts
index 68038760..e898602f 100644
--- a/components/animated-gradient/material.ts
+++ b/components/animated-gradient/material.ts
@@ -4,9 +4,9 @@ import {
Vector2,
type WebGLProgramParametersWithUniforms,
} from 'three'
-import type { Fluid } from '~/libs/webgl/utils/fluid'
-import { NOISE } from '~/libs/webgl/utils/noise'
-import type { Flowmap } from './../../libs/webgl/utils/flowmap'
+import type { Flowmap } from '~/webgl/utils/flowmap'
+import type { Fluid } from '~/webgl/utils/fluid'
+import { NOISE } from '~/webgl/utils/noise'
export class AnimatedGradientMaterial extends MeshBasicMaterial {
private uniforms: {
@@ -20,12 +20,7 @@ export class AnimatedGradientMaterial extends MeshBasicMaterial {
uColorsTexture: { value: Texture | null }
uOffset: { value: number }
uQuantize: { value: number }
- uFlowmap:
- | Flowmap
- | Fluid
- | {
- value: null
- }
+ uFlowmap: { value: Texture | null }
uDpr: { value: number }
}
@@ -59,8 +54,6 @@ export class AnimatedGradientMaterial extends MeshBasicMaterial {
transparent: true,
})
- console.log(flowmap.uniform)
-
this.uniforms = {
uTime: { value: 0 },
uAmplitude: { value: amplitude },
@@ -72,9 +65,7 @@ export class AnimatedGradientMaterial extends MeshBasicMaterial {
uColorsTexture: { value: null },
uOffset: { value: radial ? Math.random() * 1000 : 0 },
uQuantize: { value: quantize },
- uFlowmap: flowmap?.uniform || {
- value: null,
- },
+ uFlowmap: { value: flowmap?.uniform?.value ?? null },
uDpr: { value: 1 },
}
diff --git a/components/animated-gradient/webgl.tsx b/components/animated-gradient/webgl.tsx
index cd7408ad..4f3129f5 100644
--- a/components/animated-gradient/webgl.tsx
+++ b/components/animated-gradient/webgl.tsx
@@ -1,9 +1,9 @@
import { useFrame, useThree } from '@react-three/fiber'
-import { type ExtendedDOMRect, useObjectFit, useWindowSize } from 'hamo'
+import { useObjectFit, useWindowSize } from 'hamo'
import { useEffect, useMemo, useRef, useState } from 'react'
import { CanvasTexture, LinearFilter, type Mesh } from 'three'
-import { useFlowmap } from '~/libs/webgl/components/flowmap'
-import { useWebGLRect } from '~/libs/webgl/hooks/use-webgl-rect'
+import { useFlowmap } from '~/webgl/components/flowmap'
+import { useWebGLRect } from '~/webgl/hooks/use-webgl-rect'
import { AnimatedGradientMaterial } from './material'
// @refresh reset
@@ -43,7 +43,7 @@ function useGradient(colors: string[]) {
}
type WebGLAnimatedGradientProps = {
- rect: ExtendedDOMRect
+ rect: DOMRect
amplitude?: number
frequency?: number
colorAmplitude?: number
@@ -78,7 +78,7 @@ export function WebGLAnimatedGradient({
colorFrequency,
quantize,
radial,
- flowmap: hasFlowmap && flowmap,
+ flowmap: hasFlowmap ? flowmap : undefined,
})
)
diff --git a/components/debug/index.tsx b/components/debug/index.tsx
index 9d54ceee..4d80a571 100644
--- a/components/debug/index.tsx
+++ b/components/debug/index.tsx
@@ -2,23 +2,25 @@
import dynamic from 'next/dynamic'
import { useEffect } from 'react'
-import { useOrchestra } from '~/libs/orchestra/react'
+import { useOrchestra } from '~/app/debug/orchestra/react'
const Studio = dynamic(
- () => import('~/libs/theatre/studio').then(({ Studio }) => Studio),
+ () => import('~/app/theatre/studio').then(({ Studio }) => Studio),
{ ssr: false }
)
const Stats = dynamic(
- () => import('~/libs/orchestra/stats').then(({ Stats }) => Stats),
+ () => import('~/app/debug/orchestra/stats').then(({ Stats }) => Stats),
{ ssr: false }
)
const GridDebugger = dynamic(
() =>
- import('~/libs/orchestra/grid').then(({ GridDebugger }) => GridDebugger),
+ import('~/app/debug/orchestra/grid').then(
+ ({ GridDebugger }) => GridDebugger
+ ),
{ ssr: false }
)
const Minimap = dynamic(
- () => import('~/libs/orchestra/minimap').then(({ Minimap }) => Minimap),
+ () => import('~/app/debug/orchestra/minimap').then(({ Minimap }) => Minimap),
{ ssr: false }
)
diff --git a/components/fold/index.tsx b/components/fold/index.tsx
index bd4b264b..33603505 100644
--- a/components/fold/index.tsx
+++ b/components/fold/index.tsx
@@ -47,8 +47,8 @@ export function Fold({
const stickyRef = useRef
(null!)
useScrollTrigger({
- start: `${rect.top} top`,
- end: `${rect.top + windowHeight} top`,
+ start: `${rect.top ?? 0} top`,
+ end: `${(rect.top ?? 0) + windowHeight} top`,
disabled: disabled || type === 'bottom',
onProgress: ({ progress }) => {
if (overlayRef.current) {
@@ -62,8 +62,8 @@ export function Fold({
})
useScrollTrigger({
- start: `${rect.bottom - windowHeight} bottom`,
- end: `${rect.bottom} bottom`,
+ start: `${(rect.bottom ?? 0) - windowHeight} bottom`,
+ end: `${rect.bottom ?? 0} bottom`,
disabled: disabled || type === 'top',
onProgress: ({ progress }) => {
if (overlayRef.current) {
diff --git a/libs/form/fields/fields.module.css b/components/form/fields/fields.module.css
similarity index 100%
rename from libs/form/fields/fields.module.css
rename to components/form/fields/fields.module.css
diff --git a/libs/form/fields/index.tsx b/components/form/fields/index.tsx
similarity index 100%
rename from libs/form/fields/index.tsx
rename to components/form/fields/index.tsx
diff --git a/libs/form/form.module.css b/components/form/form.module.css
similarity index 100%
rename from libs/form/form.module.css
rename to components/form/form.module.css
diff --git a/libs/form/hook.ts b/components/form/hook.ts
similarity index 100%
rename from libs/form/hook.ts
rename to components/form/hook.ts
diff --git a/libs/form/index.tsx b/components/form/index.tsx
similarity index 97%
rename from libs/form/index.tsx
rename to components/form/index.tsx
index 7cd49516..b1e45d74 100644
--- a/libs/form/index.tsx
+++ b/components/form/index.tsx
@@ -10,12 +10,12 @@ import {
useEffect,
useState,
} from 'react'
-import { HubspotNewsletterAction } from '~/libs/hubspot-forms/action'
import {
CreateCustomerAction,
LoginCustomerAction,
LogoutCustomerAction,
-} from '~/libs/shopify/customer/actions'
+} from '~/cms/shopify/customer/actions'
+import { HubspotNewsletterAction } from '~/components/hubspot/action'
import s from './form.module.css'
import { useForm } from './hook'
diff --git a/libs/hubspot-forms/action.ts b/components/hubspot/action.ts
similarity index 100%
rename from libs/hubspot-forms/action.ts
rename to components/hubspot/action.ts
diff --git a/libs/hubspot-forms/embed/form.module.css b/components/hubspot/embed/form.module.css
similarity index 100%
rename from libs/hubspot-forms/embed/form.module.css
rename to components/hubspot/embed/form.module.css
diff --git a/libs/hubspot-forms/embed/index.tsx b/components/hubspot/embed/index.tsx
similarity index 100%
rename from libs/hubspot-forms/embed/index.tsx
rename to components/hubspot/embed/index.tsx
diff --git a/libs/hubspot-forms/fetch-form.ts b/components/hubspot/fetch-form.ts
similarity index 100%
rename from libs/hubspot-forms/fetch-form.ts
rename to components/hubspot/fetch-form.ts
diff --git a/components/link/index.tsx b/components/link/index.tsx
index 9d0dd6ea..ac3ed8ec 100644
--- a/components/link/index.tsx
+++ b/components/link/index.tsx
@@ -29,6 +29,8 @@ export function Link({
if (!href || typeof href !== 'string') {
const Tag = fallback
+ // TODO: review this component entirely lol
+ // @ts-expect-error
return
}
diff --git a/components/marquee/index.tsx b/components/marquee/index.tsx
index 1adf5a63..727cbce6 100644
--- a/components/marquee/index.tsx
+++ b/components/marquee/index.tsx
@@ -39,14 +39,11 @@ export function Marquee({
const [setIntersectionRef, intersection] = useIntersectionObserver()
- const lenis = useLenis() // eslint-disable-line react-hooks/exhaustive-deps
+ const lenis = useLenis()
useTempus((_, deltaTime) => {
- // @ts-expect-error
const entry = getEntry()
- const width = entry?.borderBoxSize[0]?.inlineSize
-
if (!intersection.isIntersecting) return
if (pauseOnHover && isHovered.current) return
@@ -66,6 +63,7 @@ export function Marquee({
transformRef.current += offset
}
+ const width = entry.borderBoxSize[0].inlineSize
transformRef.current = modulo(transformRef.current, width)
for (const node of elementsRef.current) {
diff --git a/components/progress-text/index.tsx b/components/progress-text/index.tsx
index 2aef70bd..fe57a1dc 100644
--- a/components/progress-text/index.tsx
+++ b/components/progress-text/index.tsx
@@ -7,7 +7,7 @@ import {
type UseScrollTriggerOptions,
useScrollTrigger,
} from '~/hooks/use-scroll-trigger'
-import { slugify } from '~/libs/slugify'
+import { slugify } from '~/libs/utils'
import s from './progress-text.module.css'
// TODO: add support for children as an array of strings and objects
diff --git a/components/scrollbar/index.tsx b/components/scrollbar/index.tsx
index 0c678553..2b7b2517 100644
--- a/components/scrollbar/index.tsx
+++ b/components/scrollbar/index.tsx
@@ -9,8 +9,8 @@ import s from './scrollbar.module.css'
export function Scrollbar() {
const thumbRef = useRef(null!)
const lenis = useLenis()
- const [innerMeasureRef, { height: innerHeight }] = useRect()
- const [thumbMeasureRef, { height: thumbHeight }] = useRect()
+ const [innerMeasureRef, { height: innerHeight = 0 }] = useRect()
+ const [thumbMeasureRef, { height: thumbHeight = 0 }] = useRect()
useLenis(
({ scroll, limit }) => {
diff --git a/components/split-text/index.tsx b/components/split-text/index.tsx
index 51013ada..2bf5241b 100644
--- a/components/split-text/index.tsx
+++ b/components/split-text/index.tsx
@@ -12,7 +12,7 @@ import {
useRef,
useState,
} from 'react'
-import { useIsVisualEditor } from '~/libs/storyblok/use-is-visual-editor'
+import { useIsVisualEditor } from '~/cms/storyblok/use-is-visual-editor'
import s from './split-text.module.css'
if (typeof window !== 'undefined') {
@@ -40,7 +40,8 @@ type SplitTextProps = {
export function SplitText({ children, className, type, ref }: SplitTextProps) {
const elementRef = useRef(null!)
const fallbackRef = useRef(null!)
- const [setRectRef, { contentRect: rect }] = useResizeObserver()
+ const [setRectRef, entry] = useResizeObserver()
+ const rect = entry?.contentRect
const [splitted, setSplitted] = useState()
diff --git a/hooks/README.md b/hooks/README.md
new file mode 100644
index 00000000..61c43ea5
--- /dev/null
+++ b/hooks/README.md
@@ -0,0 +1,26 @@
+# Custom React Hooks
+
+This directory contains reusable React hooks that provide common functionality across the application.
+
+## Available Hooks
+
+- `use-scroll-trigger.ts` - Hook for detecting and responding to scroll-based triggers and animations
+- `use-transform.tsx` - Hook for handling element transformations and animations
+- `use-device-detection.ts` - Hook for detecting device type and characteristics
+
+## Features
+
+- Scroll-based animations and triggers
+- Element transformations with GSAP integration
+- Device detection and responsive behavior
+- Type-safe implementations with TypeScript
+
+## Usage
+
+Import hooks directly from this directory:
+
+```typescript
+import { useScrollTrigger } from '~/hooks/use-scroll-trigger'
+import { useTransform } from '~/hooks/use-transform'
+import { useDeviceDetection } from '~/hooks/use-device-detection'
+```
diff --git a/hooks/use-scroll-trigger.ts b/hooks/use-scroll-trigger.ts
index 16e78175..5f58ce63 100644
--- a/hooks/use-scroll-trigger.ts
+++ b/hooks/use-scroll-trigger.ts
@@ -3,10 +3,10 @@
import { type Rect, useLazyState, useWindowSize } from 'hamo'
import { useLenis } from 'lenis/react'
import { useCallback, useEffect, useRef } from 'react'
+import { useMinimap } from '~/app/debug/orchestra/minimap'
+import { useOrchestra } from '~/app/debug/orchestra/react'
import { useTransform } from '~/hooks/use-transform'
import { clamp, mapRange } from '~/libs/maths'
-import { useMinimap } from '~/libs/orchestra/minimap'
-import { useOrchestra } from '~/libs/orchestra/react'
// @refresh reset
diff --git a/libs/README.md b/libs/README.md
new file mode 100644
index 00000000..ab2665dc
--- /dev/null
+++ b/libs/README.md
@@ -0,0 +1,39 @@
+# Utility Libraries
+
+This directory contains utility functions, type definitions, and shared libraries used throughout the application.
+
+## Files
+
+- `utils.ts` - General utility functions for string manipulation, array handling, and object transformations
+- `maths.ts` - Mathematical utility functions for calculations and transformations
+- `store.ts` - State management utilities and store configurations
+- `augment.d.ts` - TypeScript type augmentations
+- `reset.d.ts` - TypeScript reset type definitions
+
+## Features
+
+### Utility Functions
+- String manipulation (camelCase, slugify, etc.)
+- Array and object transformations
+- Number formatting and calculations
+- Type checking and validation
+
+### Mathematical Utilities
+- Viewport calculations
+- Mathematical transformations
+- Numerical operations
+
+### Type Definitions
+- Global type augmentations
+- Reset type definitions
+- Enhanced type safety
+
+## Usage
+
+Import utilities directly from their respective files:
+
+```typescript
+import { slugify, numberWithCommas } from '~/libs/utils'
+import { clamp, mapRange } from '~/libs/maths'
+import { store } from '~/libs/store'
+```
diff --git a/webgl/README.md b/webgl/README.md
new file mode 100644
index 00000000..2c11dfec
--- /dev/null
+++ b/webgl/README.md
@@ -0,0 +1,34 @@
+# WebGL and 3D Graphics
+
+This directory contains WebGL and 3D graphics components, utilities, and hooks for the application.
+
+## Structure
+
+- `components/` - Reusable WebGL and Three.js components
+- `hooks/` - Custom hooks for 3D scene management and interactions
+- `utils/` - Utility functions for WebGL and Three.js
+
+## Features
+
+- Three.js integration
+- Custom WebGL shaders
+- 3D scene management
+- Performance optimizations
+- Reusable 3D components
+
+## Usage
+
+The WebGL components and utilities are primarily used in conjunction with React Three Fiber (R3F) for creating interactive 3D experiences:
+
+```typescript
+import { useWebGLScene } from '~/webgl/hooks'
+import { ShaderMaterial } from '~/webgl/components'
+import { calculateNormals } from '~/webgl/utils'
+```
+
+## Best Practices
+
+- Use React Three Fiber for React integration
+- Implement proper cleanup in hooks
+- Optimize render performance
+- Handle WebGL context loss gracefully
diff --git a/libs/webgl/components/canvas/index.tsx b/webgl/components/canvas/index.tsx
similarity index 100%
rename from libs/webgl/components/canvas/index.tsx
rename to webgl/components/canvas/index.tsx
diff --git a/libs/webgl/components/canvas/webgl.module.css b/webgl/components/canvas/webgl.module.css
similarity index 100%
rename from libs/webgl/components/canvas/webgl.module.css
rename to webgl/components/canvas/webgl.module.css
diff --git a/libs/webgl/components/canvas/webgl.tsx b/webgl/components/canvas/webgl.tsx
similarity index 97%
rename from libs/webgl/components/canvas/webgl.tsx
rename to webgl/components/canvas/webgl.tsx
index 14dfbabc..f624bf91 100644
--- a/libs/webgl/components/canvas/webgl.tsx
+++ b/webgl/components/canvas/webgl.tsx
@@ -3,7 +3,7 @@
import { OrthographicCamera } from '@react-three/drei'
import { Canvas } from '@react-three/fiber'
import { Suspense } from 'react'
-import { SheetProvider } from '~/libs/theatre'
+import { SheetProvider } from '~/app/theatre'
import { FlowmapProvider } from '../flowmap'
import { PostProcessing } from '../postprocessing'
import { Preload } from '../preload'
diff --git a/libs/webgl/components/flowmap/index.tsx b/webgl/components/flowmap/index.tsx
similarity index 91%
rename from libs/webgl/components/flowmap/index.tsx
rename to webgl/components/flowmap/index.tsx
index 5a2fb5be..9e6325c8 100644
--- a/libs/webgl/components/flowmap/index.tsx
+++ b/webgl/components/flowmap/index.tsx
@@ -1,10 +1,10 @@
import { useFrame, useThree } from '@react-three/fiber'
import { types } from '@theatre/core'
import { createContext, useContext, useMemo } from 'react'
-import { useCurrentSheet } from '~/libs/theatre'
-import { useTheatre } from '~/libs/theatre/hooks/use-theatre'
-import { Flowmap } from '~/libs/webgl/utils/flowmap'
-import { Fluid } from '~/libs/webgl/utils/fluid'
+import { useCurrentSheet } from '~/app/theatre'
+import { useTheatre } from '~/app/theatre/hooks/use-theatre'
+import { Flowmap } from '~/webgl/utils/flowmap'
+import { Fluid } from '~/webgl/utils/fluid'
type FlowmapContextType = {
fluid: Fluid
diff --git a/libs/webgl/components/image/index.tsx b/webgl/components/image/index.tsx
similarity index 100%
rename from libs/webgl/components/image/index.tsx
rename to webgl/components/image/index.tsx
diff --git a/libs/webgl/components/image/webgl.tsx b/webgl/components/image/webgl.tsx
similarity index 94%
rename from libs/webgl/components/image/webgl.tsx
rename to webgl/components/image/webgl.tsx
index 3cf2ca33..ef89abce 100644
--- a/libs/webgl/components/image/webgl.tsx
+++ b/webgl/components/image/webgl.tsx
@@ -1,7 +1,7 @@
import { useTexture } from '@react-three/drei'
import { useRef, useState } from 'react'
import { LinearFilter, type Mesh, MeshBasicMaterial } from 'three'
-import { useWebGLRect } from '~/libs/webgl/hooks/use-webgl-rect'
+import { useWebGLRect } from '~/webgl/hooks/use-webgl-rect'
type WebGLImageProps = {
src: string | undefined
diff --git a/libs/webgl/components/postprocessing/index.ts b/webgl/components/postprocessing/index.ts
similarity index 100%
rename from libs/webgl/components/postprocessing/index.ts
rename to webgl/components/postprocessing/index.ts
diff --git a/libs/webgl/components/preload/index.ts b/webgl/components/preload/index.ts
similarity index 100%
rename from libs/webgl/components/preload/index.ts
rename to webgl/components/preload/index.ts
diff --git a/libs/webgl/components/raf/index.ts b/webgl/components/raf/index.ts
similarity index 100%
rename from libs/webgl/components/raf/index.ts
rename to webgl/components/raf/index.ts
diff --git a/libs/webgl/components/tunnel/index.tsx b/webgl/components/tunnel/index.tsx
similarity index 92%
rename from libs/webgl/components/tunnel/index.tsx
rename to webgl/components/tunnel/index.tsx
index 97e750f0..c417fd3e 100644
--- a/libs/webgl/components/tunnel/index.tsx
+++ b/webgl/components/tunnel/index.tsx
@@ -3,7 +3,7 @@
import { useContextBridge } from '@react-three/drei'
import { Fragment, type PropsWithChildren, useId } from 'react'
import { TransformContext } from '~/hooks/use-transform'
-import { useCanvas } from '~/libs/webgl/components/canvas'
+import { useCanvas } from '~/webgl/components/canvas'
export function WebGLTunnel({ children }: PropsWithChildren) {
const { WebGLTunnel } = useCanvas()
diff --git a/libs/webgl/hooks/use-texture.ts b/webgl/hooks/use-texture.ts
similarity index 100%
rename from libs/webgl/hooks/use-texture.ts
rename to webgl/hooks/use-texture.ts
diff --git a/libs/webgl/hooks/use-webgl-rect.ts b/webgl/hooks/use-webgl-rect.ts
similarity index 100%
rename from libs/webgl/hooks/use-webgl-rect.ts
rename to webgl/hooks/use-webgl-rect.ts
diff --git a/libs/webgl/utils/blend.ts b/webgl/utils/blend.ts
similarity index 100%
rename from libs/webgl/utils/blend.ts
rename to webgl/utils/blend.ts
diff --git a/libs/webgl/utils/flowmap.ts b/webgl/utils/flowmap.ts
similarity index 100%
rename from libs/webgl/utils/flowmap.ts
rename to webgl/utils/flowmap.ts
diff --git a/libs/webgl/utils/fluid.js b/webgl/utils/fluid.js
similarity index 100%
rename from libs/webgl/utils/fluid.js
rename to webgl/utils/fluid.js
diff --git a/libs/webgl/utils/functions.ts b/webgl/utils/functions.ts
similarity index 100%
rename from libs/webgl/utils/functions.ts
rename to webgl/utils/functions.ts
diff --git a/libs/webgl/utils/noise.ts b/webgl/utils/noise.ts
similarity index 100%
rename from libs/webgl/utils/noise.ts
rename to webgl/utils/noise.ts
diff --git a/libs/webgl/utils/program.ts b/webgl/utils/program.ts
similarity index 100%
rename from libs/webgl/utils/program.ts
rename to webgl/utils/program.ts