menu and services

This commit is contained in:
haniyeroozmand
2026-05-17 10:32:53 +03:30
parent 470511f28c
commit 54b1e83983
9 changed files with 2335 additions and 206 deletions

683
package-lock.json generated
View File

@@ -8,19 +8,25 @@
"name": "mugit3", "name": "mugit3",
"version": "0.1.0", "version": "0.1.0",
"dependencies": { "dependencies": {
"@react-three/drei": "^10.7.7",
"@react-three/fiber": "^9.6.1",
"@react-three/postprocessing": "^3.0.4",
"framer-motion": "^12.38.0", "framer-motion": "^12.38.0",
"lucide-react": "^1.14.0", "lucide-react": "^1.14.0",
"motion": "^12.0.6", "motion": "^12.0.6",
"next": "16.2.5", "next": "16.2.5",
"next-themes": "^0.4.6", "next-themes": "^0.4.6",
"postprocessing": "^6.39.1",
"react": "19.2.4", "react": "19.2.4",
"react-dom": "19.2.4" "react-dom": "19.2.4",
"three": "^0.184.0"
}, },
"devDependencies": { "devDependencies": {
"@tailwindcss/postcss": "^4", "@tailwindcss/postcss": "^4",
"@types/node": "^20", "@types/node": "^20",
"@types/react": "^19", "@types/react": "^19",
"@types/react-dom": "^19", "@types/react-dom": "^19",
"@types/three": "^0.184.1",
"babel-plugin-react-compiler": "1.0.0", "babel-plugin-react-compiler": "1.0.0",
"tailwindcss": "^4", "tailwindcss": "^4",
"typescript": "^5" "typescript": "^5"
@@ -56,6 +62,14 @@
"node": ">=6.9.0" "node": ">=6.9.0"
} }
}, },
"node_modules/@babel/runtime": {
"version": "7.29.2",
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.29.2.tgz",
"integrity": "sha512-JiDShH45zKHWyGe4ZNVRrCjBz8Nh9TMmZG1kh4QTK8hCBTWBi8Da+i7s1fJw7/lYpM4ccepSNfqzZ/QvABBi5g==",
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/types": { "node_modules/@babel/types": {
"version": "7.29.0", "version": "7.29.0",
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.0.tgz", "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.0.tgz",
@@ -69,6 +83,11 @@
"node": ">=6.9.0" "node": ">=6.9.0"
} }
}, },
"node_modules/@dimforge/rapier3d-compat": {
"version": "0.12.0",
"resolved": "https://registry.npmjs.org/@dimforge/rapier3d-compat/-/rapier3d-compat-0.12.0.tgz",
"integrity": "sha512-uekIGetywIgopfD97oDL5PfeezkFpNhwlzlaEYNOA0N6ghdsOvh/HYjSMek5Q2O1PYvRSDFcqFVJl4r4ZBwOow=="
},
"node_modules/@emnapi/runtime": { "node_modules/@emnapi/runtime": {
"version": "1.10.0", "version": "1.10.0",
"resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.10.0.tgz", "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.10.0.tgz",
@@ -564,6 +583,22 @@
"@jridgewell/sourcemap-codec": "^1.4.14" "@jridgewell/sourcemap-codec": "^1.4.14"
} }
}, },
"node_modules/@mediapipe/tasks-vision": {
"version": "0.10.17",
"resolved": "https://registry.npmjs.org/@mediapipe/tasks-vision/-/tasks-vision-0.10.17.tgz",
"integrity": "sha512-CZWV/q6TTe8ta61cZXjfnnHsfWIdFhms03M9T7Cnd5y2mdpylJM0rF1qRq+wsQVRMLz1OYPVEBU9ph2Bx8cxrg=="
},
"node_modules/@monogrid/gainmap-js": {
"version": "3.4.0",
"resolved": "https://registry.npmjs.org/@monogrid/gainmap-js/-/gainmap-js-3.4.0.tgz",
"integrity": "sha512-2Z0FATFHaoYJ8b+Y4y4Hgfn3FRFwuU5zRrk+9dFWp4uGAdHGqVEdP7HP+gLA3X469KXHmfupJaUbKo1b/aDKIg==",
"dependencies": {
"promise-worker-transferable": "^1.0.4"
},
"peerDependencies": {
"three": ">= 0.159.0"
}
},
"node_modules/@next/env": { "node_modules/@next/env": {
"version": "16.2.5", "version": "16.2.5",
"resolved": "https://registry.npmjs.org/@next/env/-/env-16.2.5.tgz", "resolved": "https://registry.npmjs.org/@next/env/-/env-16.2.5.tgz",
@@ -689,6 +724,116 @@
"node": ">= 10" "node": ">= 10"
} }
}, },
"node_modules/@react-three/drei": {
"version": "10.7.7",
"resolved": "https://registry.npmjs.org/@react-three/drei/-/drei-10.7.7.tgz",
"integrity": "sha512-ff+J5iloR0k4tC++QtD/j9u3w5fzfgFAWDtAGQah9pF2B1YgOq/5JxqY0/aVoQG5r3xSZz0cv5tk2YuBob4xEQ==",
"dependencies": {
"@babel/runtime": "^7.26.0",
"@mediapipe/tasks-vision": "0.10.17",
"@monogrid/gainmap-js": "^3.0.6",
"@use-gesture/react": "^10.3.1",
"camera-controls": "^3.1.0",
"cross-env": "^7.0.3",
"detect-gpu": "^5.0.56",
"glsl-noise": "^0.0.0",
"hls.js": "^1.5.17",
"maath": "^0.10.8",
"meshline": "^3.3.1",
"stats-gl": "^2.2.8",
"stats.js": "^0.17.0",
"suspend-react": "^0.1.3",
"three-mesh-bvh": "^0.8.3",
"three-stdlib": "^2.35.6",
"troika-three-text": "^0.52.4",
"tunnel-rat": "^0.1.2",
"use-sync-external-store": "^1.4.0",
"utility-types": "^3.11.0",
"zustand": "^5.0.1"
},
"peerDependencies": {
"@react-three/fiber": "^9.0.0",
"react": "^19",
"react-dom": "^19",
"three": ">=0.159"
},
"peerDependenciesMeta": {
"react-dom": {
"optional": true
}
}
},
"node_modules/@react-three/fiber": {
"version": "9.6.1",
"resolved": "https://registry.npmjs.org/@react-three/fiber/-/fiber-9.6.1.tgz",
"integrity": "sha512-zF0rsKcVYpcJwbFEnv2HkHX9cvOEgsfQo/X8lwmR2dn13S4qEQJXir9fxf5js2LQFoXqxOY7MDkOkYx2uZ4gSg==",
"dependencies": {
"@babel/runtime": "^7.17.8",
"@types/webxr": "*",
"base64-js": "^1.5.1",
"buffer": "^6.0.3",
"its-fine": "^2.0.0",
"react-use-measure": "^2.1.7",
"scheduler": "^0.27.0",
"suspend-react": "^0.1.3",
"use-sync-external-store": "^1.4.0",
"zustand": "^5.0.3"
},
"peerDependencies": {
"expo": ">=43.0",
"expo-asset": ">=8.4",
"expo-file-system": ">=11.0",
"expo-gl": ">=11.0",
"react": ">=19 <19.3",
"react-dom": ">=19 <19.3",
"react-native": ">=0.78",
"three": ">=0.156"
},
"peerDependenciesMeta": {
"expo": {
"optional": true
},
"expo-asset": {
"optional": true
},
"expo-file-system": {
"optional": true
},
"expo-gl": {
"optional": true
},
"react-dom": {
"optional": true
},
"react-native": {
"optional": true
}
}
},
"node_modules/@react-three/postprocessing": {
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/@react-three/postprocessing/-/postprocessing-3.0.4.tgz",
"integrity": "sha512-e4+F5xtudDYvhxx3y0NtWXpZbwvQ0x1zdOXWTbXMK6fFLVDd4qucN90YaaStanZGS4Bd5siQm0lGL/5ogf8iDQ==",
"dependencies": {
"maath": "^0.6.0",
"n8ao": "^1.9.4",
"postprocessing": "^6.36.6"
},
"peerDependencies": {
"@react-three/fiber": "^9.0.0",
"react": "^19.0",
"three": ">= 0.156.0"
}
},
"node_modules/@react-three/postprocessing/node_modules/maath": {
"version": "0.6.0",
"resolved": "https://registry.npmjs.org/maath/-/maath-0.6.0.tgz",
"integrity": "sha512-dSb2xQuP7vDnaYqfoKzlApeRcR2xtN8/f7WV/TMAkBC8552TwTLtOO0JTcSygkYMjNDPoo6V01jTw/aPi4JrMw==",
"peerDependencies": {
"@types/three": ">=0.144.0",
"three": ">=0.144.0"
}
},
"node_modules/@swc/helpers": { "node_modules/@swc/helpers": {
"version": "0.5.15", "version": "0.5.15",
"resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.15.tgz", "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.15.tgz",
@@ -953,6 +1098,16 @@
"tailwindcss": "4.2.4" "tailwindcss": "4.2.4"
} }
}, },
"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=="
},
"node_modules/@types/draco3d": {
"version": "1.4.10",
"resolved": "https://registry.npmjs.org/@types/draco3d/-/draco3d-1.4.10.tgz",
"integrity": "sha512-AX22jp8Y7wwaBgAixaSvkoG4M/+PlAcm3Qs4OW8yT9DM4xUpWKeFhLueTAyZF39pviAdcDdeJoACapiAceqNcw=="
},
"node_modules/@types/node": { "node_modules/@types/node": {
"version": "20.19.39", "version": "20.19.39",
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.19.39.tgz", "resolved": "https://registry.npmjs.org/@types/node/-/node-20.19.39.tgz",
@@ -962,11 +1117,15 @@
"undici-types": "~6.21.0" "undici-types": "~6.21.0"
} }
}, },
"node_modules/@types/offscreencanvas": {
"version": "2019.7.3",
"resolved": "https://registry.npmjs.org/@types/offscreencanvas/-/offscreencanvas-2019.7.3.tgz",
"integrity": "sha512-ieXiYmgSRXUDeOntE1InxjWyvEelZGP63M+cGuquuRLuIKKT1osnkXjxev9B7d1nXSug5vpunx+gNlbVxMlC9A=="
},
"node_modules/@types/react": { "node_modules/@types/react": {
"version": "19.2.14", "version": "19.2.14",
"resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.14.tgz", "resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.14.tgz",
"integrity": "sha512-ilcTH/UniCkMdtexkoCN0bI7pMcJDvmQFPvuPvmEaYA/NSfFTAgdUSLAoVjaRJm7+6PvcM+q1zYOwS4wTYMF9w==", "integrity": "sha512-ilcTH/UniCkMdtexkoCN0bI7pMcJDvmQFPvuPvmEaYA/NSfFTAgdUSLAoVjaRJm7+6PvcM+q1zYOwS4wTYMF9w==",
"dev": true,
"dependencies": { "dependencies": {
"csstype": "^3.2.2" "csstype": "^3.2.2"
} }
@@ -980,6 +1139,53 @@
"@types/react": "^19.2.0" "@types/react": "^19.2.0"
} }
}, },
"node_modules/@types/react-reconciler": {
"version": "0.28.9",
"resolved": "https://registry.npmjs.org/@types/react-reconciler/-/react-reconciler-0.28.9.tgz",
"integrity": "sha512-HHM3nxyUZ3zAylX8ZEyrDNd2XZOnQ0D5XfunJF5FLQnZbHHYq4UWvW1QfelQNXv1ICNkwYhfxjwfnqivYB6bFg==",
"peerDependencies": {
"@types/react": "*"
}
},
"node_modules/@types/stats.js": {
"version": "0.17.4",
"resolved": "https://registry.npmjs.org/@types/stats.js/-/stats.js-0.17.4.tgz",
"integrity": "sha512-jIBvWWShCvlBqBNIZt0KAshWpvSjhkwkEu4ZUcASoAvhmrgAUI2t1dXrjSL4xXVLB4FznPrIsX3nKXFl/Dt4vA=="
},
"node_modules/@types/three": {
"version": "0.184.1",
"resolved": "https://registry.npmjs.org/@types/three/-/three-0.184.1.tgz",
"integrity": "sha512-6q4VdiqVsrTRqmk62/BnlcAvIrnDM0zf2ZDVKI5kZiniWrSaOHaQzmbp+BNzoggc/8tgW412pL//wZIxu2PPTA==",
"dependencies": {
"@dimforge/rapier3d-compat": "~0.12.0",
"@tweenjs/tween.js": "~23.1.3",
"@types/stats.js": "*",
"@types/webxr": ">=0.5.17",
"fflate": "~0.8.2",
"meshoptimizer": "~1.1.1"
}
},
"node_modules/@types/webxr": {
"version": "0.5.24",
"resolved": "https://registry.npmjs.org/@types/webxr/-/webxr-0.5.24.tgz",
"integrity": "sha512-h8fgEd/DpoS9CBrjEQXR+dIDraopAEfu4wYVNY2tEPwk60stPWhvZMf4Foo5FakuQ7HFZoa8WceaWFervK2Ovg=="
},
"node_modules/@use-gesture/core": {
"version": "10.3.1",
"resolved": "https://registry.npmjs.org/@use-gesture/core/-/core-10.3.1.tgz",
"integrity": "sha512-WcINiDt8WjqBdUXye25anHiNxPc0VOrlT8F6LLkU6cycrOGUDyY/yyFmsg3k8i5OLvv25llc0QC45GhR/C8llw=="
},
"node_modules/@use-gesture/react": {
"version": "10.3.1",
"resolved": "https://registry.npmjs.org/@use-gesture/react/-/react-10.3.1.tgz",
"integrity": "sha512-Yy19y6O2GJq8f7CHf7L0nxL8bf4PZCPaVOCgJrusOeFHY1LvHgYXnmnXg6N5iwAnbgbZCDjo60SiM6IPJi9C5g==",
"dependencies": {
"@use-gesture/core": "10.3.1"
},
"peerDependencies": {
"react": ">= 16.8.0"
}
},
"node_modules/babel-plugin-react-compiler": { "node_modules/babel-plugin-react-compiler": {
"version": "1.0.0", "version": "1.0.0",
"resolved": "https://registry.npmjs.org/babel-plugin-react-compiler/-/babel-plugin-react-compiler-1.0.0.tgz", "resolved": "https://registry.npmjs.org/babel-plugin-react-compiler/-/babel-plugin-react-compiler-1.0.0.tgz",
@@ -989,6 +1195,25 @@
"@babel/types": "^7.26.0" "@babel/types": "^7.26.0"
} }
}, },
"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"
}
]
},
"node_modules/baseline-browser-mapping": { "node_modules/baseline-browser-mapping": {
"version": "2.10.27", "version": "2.10.27",
"resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.10.27.tgz", "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.10.27.tgz",
@@ -1000,6 +1225,49 @@
"node": ">=6.0.0" "node": ">=6.0.0"
} }
}, },
"node_modules/bidi-js": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/bidi-js/-/bidi-js-1.0.3.tgz",
"integrity": "sha512-RKshQI1R3YQ+n9YJz2QQ147P66ELpa1FQEg20Dk8oW9t2KgLbpDLLp9aGZ7y8WHSshDknG0bknqGw5/tyCs5tw==",
"dependencies": {
"require-from-string": "^2.0.2"
}
},
"node_modules/buffer": {
"version": "6.0.3",
"resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz",
"integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==",
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/feross"
},
{
"type": "patreon",
"url": "https://www.patreon.com/feross"
},
{
"type": "consulting",
"url": "https://feross.org/support"
}
],
"dependencies": {
"base64-js": "^1.3.1",
"ieee754": "^1.2.1"
}
},
"node_modules/camera-controls": {
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/camera-controls/-/camera-controls-3.1.2.tgz",
"integrity": "sha512-xkxfpG2ECZ6Ww5/9+kf4mfg1VEYAoe9aDSY+IwF0UEs7qEzwy0aVRfs2grImIECs/PoBtWFrh7RXsQkwG922JA==",
"engines": {
"node": ">=22.0.0",
"npm": ">=10.5.1"
},
"peerDependencies": {
"three": ">=0.126.1"
}
},
"node_modules/caniuse-lite": { "node_modules/caniuse-lite": {
"version": "1.0.30001792", "version": "1.0.30001792",
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001792.tgz", "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001792.tgz",
@@ -1024,11 +1292,48 @@
"resolved": "https://registry.npmjs.org/client-only/-/client-only-0.0.1.tgz", "resolved": "https://registry.npmjs.org/client-only/-/client-only-0.0.1.tgz",
"integrity": "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==" "integrity": "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA=="
}, },
"node_modules/cross-env": {
"version": "7.0.3",
"resolved": "https://registry.npmjs.org/cross-env/-/cross-env-7.0.3.tgz",
"integrity": "sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw==",
"dependencies": {
"cross-spawn": "^7.0.1"
},
"bin": {
"cross-env": "src/bin/cross-env.js",
"cross-env-shell": "src/bin/cross-env-shell.js"
},
"engines": {
"node": ">=10.14",
"npm": ">=6",
"yarn": ">=1"
}
},
"node_modules/cross-spawn": {
"version": "7.0.6",
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
"integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==",
"dependencies": {
"path-key": "^3.1.0",
"shebang-command": "^2.0.0",
"which": "^2.0.1"
},
"engines": {
"node": ">= 8"
}
},
"node_modules/csstype": { "node_modules/csstype": {
"version": "3.2.3", "version": "3.2.3",
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz", "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz",
"integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==", "integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ=="
"dev": true },
"node_modules/detect-gpu": {
"version": "5.0.70",
"resolved": "https://registry.npmjs.org/detect-gpu/-/detect-gpu-5.0.70.tgz",
"integrity": "sha512-bqerEP1Ese6nt3rFkwPnGbsUF9a4q+gMmpTVVOEzoCyeCc+y7/RvJnQZJx1JwhgQI5Ntg0Kgat8Uu7XpBqnz1w==",
"dependencies": {
"webgl-constants": "^1.1.1"
}
}, },
"node_modules/detect-libc": { "node_modules/detect-libc": {
"version": "2.1.2", "version": "2.1.2",
@@ -1039,6 +1344,11 @@
"node": ">=8" "node": ">=8"
} }
}, },
"node_modules/draco3d": {
"version": "1.5.7",
"resolved": "https://registry.npmjs.org/draco3d/-/draco3d-1.5.7.tgz",
"integrity": "sha512-m6WCKt/erDXcw+70IJXnG7M3awwQPAsZvJGX5zY7beBqpELw6RDGkYVU0W43AFxye4pDZ5i2Lbyc/NNGqwjUVQ=="
},
"node_modules/enhanced-resolve": { "node_modules/enhanced-resolve": {
"version": "5.21.0", "version": "5.21.0",
"resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.21.0.tgz", "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.21.0.tgz",
@@ -1052,6 +1362,11 @@
"node": ">=10.13.0" "node": ">=10.13.0"
} }
}, },
"node_modules/fflate": {
"version": "0.8.2",
"resolved": "https://registry.npmjs.org/fflate/-/fflate-0.8.2.tgz",
"integrity": "sha512-cPJU47OaAoCbg0pBvzsgpTPhmhqI5eJjh/JIu8tPj5q+T7iLvW/JAYUqmE7KOB4R1ZyEhzBaIQpQpardBF5z8A=="
},
"node_modules/framer-motion": { "node_modules/framer-motion": {
"version": "12.38.0", "version": "12.38.0",
"resolved": "https://registry.npmjs.org/framer-motion/-/framer-motion-12.38.0.tgz", "resolved": "https://registry.npmjs.org/framer-motion/-/framer-motion-12.38.0.tgz",
@@ -1078,12 +1393,67 @@
} }
} }
}, },
"node_modules/glsl-noise": {
"version": "0.0.0",
"resolved": "https://registry.npmjs.org/glsl-noise/-/glsl-noise-0.0.0.tgz",
"integrity": "sha512-b/ZCF6amfAUb7dJM/MxRs7AetQEahYzJ8PtgfrmEdtw6uyGOr+ZSGtgjFm6mfsBkxJ4d2W7kg+Nlqzqvn3Bc0w=="
},
"node_modules/graceful-fs": { "node_modules/graceful-fs": {
"version": "4.2.11", "version": "4.2.11",
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz",
"integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==",
"dev": true "dev": true
}, },
"node_modules/hls.js": {
"version": "1.6.16",
"resolved": "https://registry.npmjs.org/hls.js/-/hls.js-1.6.16.tgz",
"integrity": "sha512-VSIRpLfRwlAAdGL4wiTucx2ScRipo0ed1FBatWkyt832jC4CReKstga6yIhYVwGu9LOBjuX9wzmRMeQdBJtzEA=="
},
"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"
}
]
},
"node_modules/immediate": {
"version": "3.0.6",
"resolved": "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz",
"integrity": "sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ=="
},
"node_modules/is-promise": {
"version": "2.2.2",
"resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.2.2.tgz",
"integrity": "sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ=="
},
"node_modules/isexe": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
"integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw=="
},
"node_modules/its-fine": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/its-fine/-/its-fine-2.0.0.tgz",
"integrity": "sha512-KLViCmWx94zOvpLwSlsx6yOCeMhZYaxrJV87Po5k/FoZzcPSahvK5qJ7fYhS61sZi5ikmh2S3Hz55A2l3U69ng==",
"dependencies": {
"@types/react-reconciler": "^0.28.9"
},
"peerDependencies": {
"react": "^19.0.0"
}
},
"node_modules/jiti": { "node_modules/jiti": {
"version": "2.7.0", "version": "2.7.0",
"resolved": "https://registry.npmjs.org/jiti/-/jiti-2.7.0.tgz", "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.7.0.tgz",
@@ -1093,6 +1463,14 @@
"jiti": "lib/jiti-cli.mjs" "jiti": "lib/jiti-cli.mjs"
} }
}, },
"node_modules/lie": {
"version": "3.3.0",
"resolved": "https://registry.npmjs.org/lie/-/lie-3.3.0.tgz",
"integrity": "sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==",
"dependencies": {
"immediate": "~3.0.5"
}
},
"node_modules/lightningcss": { "node_modules/lightningcss": {
"version": "1.32.0", "version": "1.32.0",
"resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.32.0.tgz", "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.32.0.tgz",
@@ -1350,6 +1728,15 @@
"react": "^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0" "react": "^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0"
} }
}, },
"node_modules/maath": {
"version": "0.10.8",
"resolved": "https://registry.npmjs.org/maath/-/maath-0.10.8.tgz",
"integrity": "sha512-tRvbDF0Pgqz+9XUa4jjfgAQ8/aPKmQdWXilFu2tMy4GWj4NOsx99HlULO4IeREfbO3a0sA145DZYyvXPkybm0g==",
"peerDependencies": {
"@types/three": ">=0.134.0",
"three": ">=0.134.0"
}
},
"node_modules/magic-string": { "node_modules/magic-string": {
"version": "0.30.21", "version": "0.30.21",
"resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz", "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz",
@@ -1359,6 +1746,19 @@
"@jridgewell/sourcemap-codec": "^1.5.5" "@jridgewell/sourcemap-codec": "^1.5.5"
} }
}, },
"node_modules/meshline": {
"version": "3.3.1",
"resolved": "https://registry.npmjs.org/meshline/-/meshline-3.3.1.tgz",
"integrity": "sha512-/TQj+JdZkeSUOl5Mk2J7eLcYTLiQm2IDzmlSvYm7ov15anEcDJ92GHqqazxTSreeNgfnYu24kiEvvv0WlbCdFQ==",
"peerDependencies": {
"three": ">=0.137"
}
},
"node_modules/meshoptimizer": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/meshoptimizer/-/meshoptimizer-1.1.1.tgz",
"integrity": "sha512-oRFNWJRDA/WTrVj7NWvqa5HqE1t9MYDj2VaWirQCzCCrAd2GHrqR/sQezCxiWATPNlKTcRaPRHPJwIRoPBAp5g=="
},
"node_modules/motion": { "node_modules/motion": {
"version": "12.38.0", "version": "12.38.0",
"resolved": "https://registry.npmjs.org/motion/-/motion-12.38.0.tgz", "resolved": "https://registry.npmjs.org/motion/-/motion-12.38.0.tgz",
@@ -1397,6 +1797,15 @@
"resolved": "https://registry.npmjs.org/motion-utils/-/motion-utils-12.36.0.tgz", "resolved": "https://registry.npmjs.org/motion-utils/-/motion-utils-12.36.0.tgz",
"integrity": "sha512-eHWisygbiwVvf6PZ1vhaHCLamvkSbPIeAYxWUuL3a2PD/TROgE7FvfHWTIH4vMl798QLfMw15nRqIaRDXTlYRg==" "integrity": "sha512-eHWisygbiwVvf6PZ1vhaHCLamvkSbPIeAYxWUuL3a2PD/TROgE7FvfHWTIH4vMl798QLfMw15nRqIaRDXTlYRg=="
}, },
"node_modules/n8ao": {
"version": "1.10.1",
"resolved": "https://registry.npmjs.org/n8ao/-/n8ao-1.10.1.tgz",
"integrity": "sha512-hhI1pC+BfOZBV1KMwynBrVlIm8wqLxj/abAWhF2nZ0qQKyzTSQa1QtLVS2veRiuoBQXojxobcnp0oe+PUoxf/w==",
"peerDependencies": {
"postprocessing": ">=6.30.0",
"three": ">=0.137"
}
},
"node_modules/nanoid": { "node_modules/nanoid": {
"version": "3.3.12", "version": "3.3.12",
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.12.tgz", "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.12.tgz",
@@ -1502,6 +1911,14 @@
"node": "^10 || ^12 || >=14" "node": "^10 || ^12 || >=14"
} }
}, },
"node_modules/path-key": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
"integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
"engines": {
"node": ">=8"
}
},
"node_modules/picocolors": { "node_modules/picocolors": {
"version": "1.1.1", "version": "1.1.1",
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
@@ -1535,6 +1952,28 @@
"node": "^10 || ^12 || >=14" "node": "^10 || ^12 || >=14"
} }
}, },
"node_modules/postprocessing": {
"version": "6.39.1",
"resolved": "https://registry.npmjs.org/postprocessing/-/postprocessing-6.39.1.tgz",
"integrity": "sha512-R2dG2zy+BAx3USl5EHw+PvnrlbT5PKnZVp3se0HCR0pWH8WQdh742yNG4YWOsq6c0bFpffk0Gd2RqPeoP/wKng==",
"peerDependencies": {
"three": ">= 0.168.0 < 0.185.0"
}
},
"node_modules/potpack": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/potpack/-/potpack-1.0.2.tgz",
"integrity": "sha512-choctRBIV9EMT9WGAZHn3V7t0Z2pMQyl0EZE6pFc/6ml3ssw7Dlf/oAOvFwjm1HVsqfQN8GfeFyJ+d8tRzqueQ=="
},
"node_modules/promise-worker-transferable": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/promise-worker-transferable/-/promise-worker-transferable-1.0.4.tgz",
"integrity": "sha512-bN+0ehEnrXfxV2ZQvU2PetO0n4gqBD4ulq3MI1WOPLgr7/Mg9yRQkX5+0v1vagr74ZTsl7XtzlaYDo2EuCeYJw==",
"dependencies": {
"is-promise": "^2.1.0",
"lie": "^3.0.2"
}
},
"node_modules/react": { "node_modules/react": {
"version": "19.2.4", "version": "19.2.4",
"resolved": "https://registry.npmjs.org/react/-/react-19.2.4.tgz", "resolved": "https://registry.npmjs.org/react/-/react-19.2.4.tgz",
@@ -1554,6 +1993,28 @@
"react": "^19.2.4" "react": "^19.2.4"
} }
}, },
"node_modules/react-use-measure": {
"version": "2.1.7",
"resolved": "https://registry.npmjs.org/react-use-measure/-/react-use-measure-2.1.7.tgz",
"integrity": "sha512-KrvcAo13I/60HpwGO5jpW7E9DfusKyLPLvuHlUyP5zqnmAPhNc6qTRjUQrdTADl0lpPpDVU2/Gg51UlOGHXbdg==",
"peerDependencies": {
"react": ">=16.13",
"react-dom": ">=16.13"
},
"peerDependenciesMeta": {
"react-dom": {
"optional": true
}
}
},
"node_modules/require-from-string": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz",
"integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/scheduler": { "node_modules/scheduler": {
"version": "0.27.0", "version": "0.27.0",
"resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.27.0.tgz", "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.27.0.tgz",
@@ -1615,6 +2076,25 @@
"@img/sharp-win32-x64": "0.34.5" "@img/sharp-win32-x64": "0.34.5"
} }
}, },
"node_modules/shebang-command": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
"integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
"dependencies": {
"shebang-regex": "^3.0.0"
},
"engines": {
"node": ">=8"
}
},
"node_modules/shebang-regex": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
"integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
"engines": {
"node": ">=8"
}
},
"node_modules/source-map-js": { "node_modules/source-map-js": {
"version": "1.2.1", "version": "1.2.1",
"resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz",
@@ -1623,6 +2103,29 @@
"node": ">=0.10.0" "node": ">=0.10.0"
} }
}, },
"node_modules/stats-gl": {
"version": "2.4.2",
"resolved": "https://registry.npmjs.org/stats-gl/-/stats-gl-2.4.2.tgz",
"integrity": "sha512-g5O9B0hm9CvnM36+v7SFl39T7hmAlv541tU81ME8YeSb3i1CIP5/QdDeSB3A0la0bKNHpxpwxOVRo2wFTYEosQ==",
"dependencies": {
"@types/three": "*",
"three": "^0.170.0"
},
"peerDependencies": {
"@types/three": "*",
"three": "*"
}
},
"node_modules/stats-gl/node_modules/three": {
"version": "0.170.0",
"resolved": "https://registry.npmjs.org/three/-/three-0.170.0.tgz",
"integrity": "sha512-FQK+LEpYc0fBD+J8g6oSEyyNzjp+Q7Ks1C568WWaoMRLW+TkNNWmenWeGgJjV105Gd+p/2ql1ZcjYvNiPZBhuQ=="
},
"node_modules/stats.js": {
"version": "0.17.0",
"resolved": "https://registry.npmjs.org/stats.js/-/stats.js-0.17.0.tgz",
"integrity": "sha512-hNKz8phvYLPEcRkeG1rsGmV5ChMjKDAWU7/OJJdDErPBNChQXxCo3WZurGpnWc6gZhAzEPFad1aVgyOANH1sMw=="
},
"node_modules/styled-jsx": { "node_modules/styled-jsx": {
"version": "5.1.6", "version": "5.1.6",
"resolved": "https://registry.npmjs.org/styled-jsx/-/styled-jsx-5.1.6.tgz", "resolved": "https://registry.npmjs.org/styled-jsx/-/styled-jsx-5.1.6.tgz",
@@ -1645,6 +2148,14 @@
} }
} }
}, },
"node_modules/suspend-react": {
"version": "0.1.3",
"resolved": "https://registry.npmjs.org/suspend-react/-/suspend-react-0.1.3.tgz",
"integrity": "sha512-aqldKgX9aZqpoDp3e8/BZ8Dm7x1pJl+qI3ZKxDN0i/IQTWUwBx/ManmlVJ3wowqbno6c2bmiIfs+Um6LbsjJyQ==",
"peerDependencies": {
"react": ">=17.0"
}
},
"node_modules/tailwindcss": { "node_modules/tailwindcss": {
"version": "4.2.4", "version": "4.2.4",
"resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.2.4.tgz", "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.2.4.tgz",
@@ -1664,11 +2175,107 @@
"url": "https://opencollective.com/webpack" "url": "https://opencollective.com/webpack"
} }
}, },
"node_modules/three": {
"version": "0.184.0",
"resolved": "https://registry.npmjs.org/three/-/three-0.184.0.tgz",
"integrity": "sha512-wtTRjG92pM5eUg/KuUnHsqSAlPM296brTOcLgMRqEeylYTh/CdtvKUvCyyCQTzFuStieWxvZb8mVTMvdPyUpxg=="
},
"node_modules/three-mesh-bvh": {
"version": "0.8.3",
"resolved": "https://registry.npmjs.org/three-mesh-bvh/-/three-mesh-bvh-0.8.3.tgz",
"integrity": "sha512-4G5lBaF+g2auKX3P0yqx+MJC6oVt6sB5k+CchS6Ob0qvH0YIhuUk1eYr7ktsIpY+albCqE80/FVQGV190PmiAg==",
"peerDependencies": {
"three": ">= 0.159.0"
}
},
"node_modules/three-stdlib": {
"version": "2.36.1",
"resolved": "https://registry.npmjs.org/three-stdlib/-/three-stdlib-2.36.1.tgz",
"integrity": "sha512-XyGQrFmNQ5O/IoKm556ftwKsBg11TIb301MB5dWNicziQBEs2g3gtOYIf7pFiLa0zI2gUwhtCjv9fmjnxKZ1Cg==",
"dependencies": {
"@types/draco3d": "^1.4.0",
"@types/offscreencanvas": "^2019.6.4",
"@types/webxr": "^0.5.2",
"draco3d": "^1.4.1",
"fflate": "^0.6.9",
"potpack": "^1.0.1"
},
"peerDependencies": {
"three": ">=0.128.0"
}
},
"node_modules/three-stdlib/node_modules/fflate": {
"version": "0.6.10",
"resolved": "https://registry.npmjs.org/fflate/-/fflate-0.6.10.tgz",
"integrity": "sha512-IQrh3lEPM93wVCEczc9SaAOvkmcoQn/G8Bo1e8ZPlY3X3bnAxWaBdvTdvM1hP62iZp0BXWDy4vTAy4fF0+Dlpg=="
},
"node_modules/troika-three-text": {
"version": "0.52.4",
"resolved": "https://registry.npmjs.org/troika-three-text/-/troika-three-text-0.52.4.tgz",
"integrity": "sha512-V50EwcYGruV5rUZ9F4aNsrytGdKcXKALjEtQXIOBfhVoZU9VAqZNIoGQ3TMiooVqFAbR1w15T+f+8gkzoFzawg==",
"dependencies": {
"bidi-js": "^1.0.2",
"troika-three-utils": "^0.52.4",
"troika-worker-utils": "^0.52.0",
"webgl-sdf-generator": "1.1.1"
},
"peerDependencies": {
"three": ">=0.125.0"
}
},
"node_modules/troika-three-utils": {
"version": "0.52.4",
"resolved": "https://registry.npmjs.org/troika-three-utils/-/troika-three-utils-0.52.4.tgz",
"integrity": "sha512-NORAStSVa/BDiG52Mfudk4j1FG4jC4ILutB3foPnfGbOeIs9+G5vZLa0pnmnaftZUGm4UwSoqEpWdqvC7zms3A==",
"peerDependencies": {
"three": ">=0.125.0"
}
},
"node_modules/troika-worker-utils": {
"version": "0.52.0",
"resolved": "https://registry.npmjs.org/troika-worker-utils/-/troika-worker-utils-0.52.0.tgz",
"integrity": "sha512-W1CpvTHykaPH5brv5VHLfQo9D1OYuo0cSBEUQFFT/nBUzM8iD6Lq2/tgG/f1OelbAS1WtaTPQzE5uM49egnngw=="
},
"node_modules/tslib": { "node_modules/tslib": {
"version": "2.8.1", "version": "2.8.1",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
"integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==" "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="
}, },
"node_modules/tunnel-rat": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/tunnel-rat/-/tunnel-rat-0.1.2.tgz",
"integrity": "sha512-lR5VHmkPhzdhrM092lI2nACsLO4QubF0/yoOhzX7c+wIpbN1GjHNzCc91QlpxBi+cnx8vVJ+Ur6vL5cEoQPFpQ==",
"dependencies": {
"zustand": "^4.3.2"
}
},
"node_modules/tunnel-rat/node_modules/zustand": {
"version": "4.5.7",
"resolved": "https://registry.npmjs.org/zustand/-/zustand-4.5.7.tgz",
"integrity": "sha512-CHOUy7mu3lbD6o6LJLfllpjkzhHXSBlX8B9+qPddUsIfeF5S/UZ5q0kmCsnRqT1UHFQZchNFDDzMbQsuesHWlw==",
"dependencies": {
"use-sync-external-store": "^1.2.2"
},
"engines": {
"node": ">=12.7.0"
},
"peerDependencies": {
"@types/react": ">=16.8",
"immer": ">=9.0.6",
"react": ">=16.8"
},
"peerDependenciesMeta": {
"@types/react": {
"optional": true
},
"immer": {
"optional": true
},
"react": {
"optional": true
}
}
},
"node_modules/typescript": { "node_modules/typescript": {
"version": "5.9.3", "version": "5.9.3",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz",
@@ -1687,6 +2294,74 @@
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz",
"integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==",
"dev": true "dev": true
},
"node_modules/use-sync-external-store": {
"version": "1.6.0",
"resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.6.0.tgz",
"integrity": "sha512-Pp6GSwGP/NrPIrxVFAIkOQeyw8lFenOHijQWkUTrDvrF4ALqylP2C/KCkeS9dpUM3KvYRQhna5vt7IL95+ZQ9w==",
"peerDependencies": {
"react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
}
},
"node_modules/utility-types": {
"version": "3.11.0",
"resolved": "https://registry.npmjs.org/utility-types/-/utility-types-3.11.0.tgz",
"integrity": "sha512-6Z7Ma2aVEWisaL6TvBCy7P8rm2LQoPv6dJ7ecIaIixHcwfbJ0x7mWdbcwlIM5IGQxPZSFYeqRCqlOOeKoJYMkw==",
"engines": {
"node": ">= 4"
}
},
"node_modules/webgl-constants": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/webgl-constants/-/webgl-constants-1.1.1.tgz",
"integrity": "sha512-LkBXKjU5r9vAW7Gcu3T5u+5cvSvh5WwINdr0C+9jpzVB41cjQAP5ePArDtk/WHYdVj0GefCgM73BA7FlIiNtdg=="
},
"node_modules/webgl-sdf-generator": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/webgl-sdf-generator/-/webgl-sdf-generator-1.1.1.tgz",
"integrity": "sha512-9Z0JcMTFxeE+b2x1LJTdnaT8rT8aEp7MVxkNwoycNmJWwPdzoXzMh0BjJSh/AEFP+KPYZUli814h8bJZFIZ2jA=="
},
"node_modules/which": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
"integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
"dependencies": {
"isexe": "^2.0.0"
},
"bin": {
"node-which": "bin/node-which"
},
"engines": {
"node": ">= 8"
}
},
"node_modules/zustand": {
"version": "5.0.13",
"resolved": "https://registry.npmjs.org/zustand/-/zustand-5.0.13.tgz",
"integrity": "sha512-efI2tVaVQPqtOh114loML/Z80Y4NP3yc+Ff0fYiZJPauNeWZeIp/bRFD7I9bfmCOYBh/PHxlglQ9+wvlwnPikQ==",
"engines": {
"node": ">=12.20.0"
},
"peerDependencies": {
"@types/react": ">=18.0.0",
"immer": ">=9.0.6",
"react": ">=18.0.0",
"use-sync-external-store": ">=1.2.0"
},
"peerDependenciesMeta": {
"@types/react": {
"optional": true
},
"immer": {
"optional": true
},
"react": {
"optional": true
},
"use-sync-external-store": {
"optional": true
}
}
} }
} }
} }

View File

@@ -8,19 +8,25 @@
"start": "next start" "start": "next start"
}, },
"dependencies": { "dependencies": {
"@react-three/drei": "^10.7.7",
"@react-three/fiber": "^9.6.1",
"@react-three/postprocessing": "^3.0.4",
"framer-motion": "^12.38.0", "framer-motion": "^12.38.0",
"lucide-react": "^1.14.0", "lucide-react": "^1.14.0",
"motion": "^12.0.6", "motion": "^12.0.6",
"next": "16.2.5", "next": "16.2.5",
"next-themes": "^0.4.6", "next-themes": "^0.4.6",
"postprocessing": "^6.39.1",
"react": "19.2.4", "react": "19.2.4",
"react-dom": "19.2.4" "react-dom": "19.2.4",
"three": "^0.184.0"
}, },
"devDependencies": { "devDependencies": {
"@tailwindcss/postcss": "^4", "@tailwindcss/postcss": "^4",
"@types/node": "^20", "@types/node": "^20",
"@types/react": "^19", "@types/react": "^19",
"@types/react-dom": "^19", "@types/react-dom": "^19",
"@types/three": "^0.184.1",
"babel-plugin-react-compiler": "1.0.0", "babel-plugin-react-compiler": "1.0.0",
"tailwindcss": "^4", "tailwindcss": "^4",
"typescript": "^5" "typescript": "^5"

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 MiB

View File

@@ -10,8 +10,11 @@ import {
} from '../services/[slug]/services.data'; } from '../services/[slug]/services.data';
import { isLocale, type Locale } from '../../../i18n/messages'; import { isLocale, type Locale } from '../../../i18n/messages';
const overriddenSlugs = new Set<ServiceSlug>(['domain', 'org-email']);
const servicePageSlugs = serviceSlugs.filter((s) => !overriddenSlugs.has(s));
export function generateStaticParams() { export function generateStaticParams() {
return serviceSlugs.flatMap((slug) => [{ slug }]); return servicePageSlugs.flatMap((slug) => [{ slug }]);
} }
export async function generateMetadata({ export async function generateMetadata({
@@ -21,7 +24,7 @@ export async function generateMetadata({
}): Promise<Metadata> { }): Promise<Metadata> {
const { locale, slug } = await params; const { locale, slug } = await params;
if (!isLocale(locale)) return {}; if (!isLocale(locale)) return {};
if (!serviceSlugs.includes(slug as ServiceSlug)) return {}; if (!servicePageSlugs.includes(slug as ServiceSlug)) return {};
return { title: serviceContent[slug as ServiceSlug][locale as Locale].seoTitle }; return { title: serviceContent[slug as ServiceSlug][locale as Locale].seoTitle };
} }
@@ -32,7 +35,7 @@ export default async function ServicePage({
}) { }) {
const { locale, slug } = await params; const { locale, slug } = await params;
if (!isLocale(locale)) notFound(); if (!isLocale(locale)) notFound();
if (!serviceSlugs.includes(slug as ServiceSlug)) notFound(); if (!servicePageSlugs.includes(slug as ServiceSlug)) notFound();
return ( return (
<main className="min-h-screen font-sans"> <main className="min-h-screen font-sans">
@@ -42,4 +45,3 @@ export default async function ServicePage({
</main> </main>
); );
} }

View File

@@ -0,0 +1,274 @@
import Header from '../../components/header';
import { Footer } from '../../components/footer';
import Image from 'next/image';
import { Headphones, Repeat2, Search, Settings, ShoppingCart, Tag } from 'lucide-react';
export default async function DomainPage({
params,
}: {
params: Promise<{ locale: string }>;
}) {
const { locale } = await params;
const isFa = locale === 'fa';
const dir = isFa ? 'rtl' : 'ltr';
return (
<main className="min-h-screen font-sans text-[color:var(--text-primary)] dark:bg-[#000315]" dir={dir}>
<Header />
{/* Hero (match provided UI) */}
<section className="relative overflow-hidden pt-28 pb-10 px-4 sm:px-6">
<div className="pointer-events-none absolute inset-0">
<div className="absolute inset-0 bg-[radial-gradient(1200px_520px_at_10%_40%,rgba(59,130,246,0.16),transparent_60%),radial-gradient(900px_420px_at_80%_20%,rgba(139,92,246,0.16),transparent_55%),radial-gradient(900px_420px_at_55%_90%,rgba(16,185,129,0.10),transparent_60%)]" />
<div className="absolute inset-0 opacity-[0.18] [background-image:radial-gradient(rgba(255,255,255,0.65)_1px,transparent_1px)] [background-size:42px_42px]" />
<div className="absolute inset-0 opacity-[0.10] [background-image:radial-gradient(rgba(59,130,246,0.70)_1px,transparent_1px)] [background-size:120px_120px]" />
</div>
<div className="max-w-7xl mx-auto">
<div className="grid grid-cols-1 lg:grid-cols-12 gap-10 items-center">
{/* Globe */}
<div className={`lg:col-span-6 ${isFa ? '' : 'lg:order-2'} order-1`}>
<div className="relative mx-auto w-full max-w-[640px] aspect-[1/1] -mt-6 lg:mt-0">
<Image
src="/images/domain-globe.png"
alt="Domain globe"
fill
priority
className="object-contain"
/>
{[
{ t: '.cert', s: 'top-[20%] left-[8%]' },
{ t: '.ir', s: 'top-[24%] right-[10%]' },
{ t: '.org', s: 'bottom-[34%] left-[6%]' },
{ t: '.co', s: 'bottom-[20%] left-[46%]' },
{ t: '.shop', s: 'bottom-[34%] right-[10%]' },
].map((b) => (
<div
key={b.t}
className={`absolute ${b.s} px-5 py-2.5 rounded-2xl border border-[rgba(148,163,184,0.20)] bg-[rgba(2,6,23,0.55)] backdrop-blur-md shadow-[0_0_50px_rgba(59,130,246,0.12)]`}
>
<span className="text-base font-extrabold text-cyan-100/90">{b.t}</span>
</div>
))}
</div>
</div>
{/* Copy + Search */}
<div className={`lg:col-span-6 ${isFa ? '' : 'lg:order-1'} order-2`}>
<div className={`text-sm font-semibold text-emerald-400 ${isFa ? 'text-right' : 'text-left'}`}>
{isFa ? 'ثبت دامنه' : 'Domain registration'}
</div>
<h1 className={`mt-4 text-4xl sm:text-5xl lg:text-6xl font-extrabold leading-[1.2] ${isFa ? 'text-right' : 'text-left'}`}>
{isFa ? (
<>
نامی که برند شما را <span className="text-emerald-400">ماندگار</span>
<br />
میکند.
</>
) : (
<>
A name that makes
<br />
your brand <span className="text-emerald-400">memorable</span>.
</>
)}
</h1>
<p className={`mt-5 text-[color:var(--text-muted-2)] leading-relaxed max-w-xl ${isFa ? 'text-right ml-auto' : 'text-left'}`}>
{isFa
? 'با ثبت دامنه دلخواه خود، اولین قدم برای ساختن هویت آنلاین\nخانوادهی دیجیتال خود را محکم بردارید.'
: 'Register your desired domain and take the first step to build a strong online identity.'}
</p>
<div className="mt-8">
{/* Search bar: button left + input right (as in screenshot) */}
<div className="flex items-stretch gap-0 rounded-2xl border border-[rgba(148,163,184,0.18)] bg-[rgba(2,6,23,0.40)] backdrop-blur-xl overflow-hidden shadow-[0_0_70px_rgba(59,130,246,0.10)]">
<button
type="button"
className="px-10 py-4 text-sm font-extrabold text-[#071027] bg-gradient-to-r from-emerald-400 via-cyan-400 to-indigo-500 hover:opacity-95 transition-opacity min-w-[160px]"
>
{isFa ? 'جستجو' : 'Search'}
</button>
<div className="relative flex-1">
<div className={`absolute inset-y-0 ${isFa ? 'left-4' : 'left-4'} flex items-center`}>
<div className="w-10 h-10 rounded-xl border border-[rgba(148,163,184,0.18)] bg-[rgba(2,6,23,0.30)] flex items-center justify-center">
<Search className="w-5 h-5 text-slate-200/80" />
</div>
</div>
<input
type="text"
placeholder={isFa ? 'نام دامنه خود را وارد کنید…' : 'Enter your domain name…'}
className={`w-full h-full bg-transparent px-4 py-4 text-sm text-[color:var(--text-primary)] placeholder:text-slate-300/40 outline-none ${
isFa ? 'pr-6 pl-16 text-right' : 'pl-16 pr-6 text-left'
}`}
/>
</div>
</div>
{/* Feature pills */}
<div
className={`mt-5 rounded-2xl border border-[rgba(148,163,184,0.14)] bg-[rgba(2,6,23,0.32)] backdrop-blur-xl overflow-hidden ${
isFa ? 'divide-x divide-x-reverse' : 'divide-x'
} divide-[rgba(148,163,184,0.12)]`}
>
<div className="grid grid-cols-2 sm:grid-cols-4">
{[
{ t: isFa ? 'قیمت‌های شفاف' : 'Transparent pricing', i: Tag },
{ t: isFa ? 'مدیریت آسان' : 'Easy management', i: Settings },
{ t: isFa ? 'انتقال رایگان' : 'Free transfer', i: Repeat2 },
{ t: isFa ? 'پشتیبانی ۲۴/۷' : '24/7 support', i: Headphones },
].map((item) => (
<div
key={item.t}
className={`flex items-center justify-center gap-2 px-4 py-4 text-xs sm:text-sm text-slate-200/80 ${
isFa ? 'flex-row-reverse' : ''
}`}
>
<item.i className="w-5 h-5 text-indigo-300/80" />
<span className="whitespace-nowrap">{item.t}</span>
</div>
))}
</div>
</div>
</div>
</div>
</div>
{/* Why cards */}
<div className="mt-12">
<div className="text-center text-xl md:text-2xl font-bold">{isFa ? 'چرا دامنه از MugCloud؟' : 'Why MugCloud domains?'}</div>
<div className="mt-6 grid grid-cols-1 md:grid-cols-4 gap-4">
{[
{ t: isFa ? 'ثبت فوری' : 'Instant registration', d: isFa ? 'ثبت سریع و قابل اعتماد' : 'Fast and reliable registration' },
{ t: isFa ? 'امنیت کامل' : 'Full security', d: isFa ? 'DNSSEC و قفل انتقال' : 'DNSSEC and transfer lock' },
{ t: isFa ? 'پنل قدرتمند' : 'Powerful panel', d: isFa ? 'مدیریت DNS، رکوردها و نیم‌سرورها' : 'Manage DNS, records, and nameservers' },
{ t: isFa ? 'پشتیبانی همیشه' : 'Always-on support', d: isFa ? 'تیم متخصص در تمام ساعات' : 'Expert help anytime' },
].map((c) => (
<div
key={c.t}
className="glass-rotating-border rounded-3xl border border-[color:var(--border-10)] bg-[color:var(--glass-05)] backdrop-blur-md p-6"
>
<div className="h-12 w-12 rounded-2xl border border-[color:var(--border-10)] bg-[color:var(--glass-02)] shadow-[0_0_25px_rgba(34,211,238,0.10)]" />
<div className="mt-4 font-bold">{c.t}</div>
<div className="mt-2 text-sm text-[color:var(--text-muted-2)] leading-relaxed">{c.d}</div>
</div>
))}
</div>
</div>
{/* Popular tlds */}
<div className="mt-12">
<div className="text-center text-xl md:text-2xl font-bold">{isFa ? 'پسوندهای محبوب' : 'Popular TLDs'}</div>
<div className="mt-6 grid grid-cols-2 md:grid-cols-6 gap-4">
{[
{ tld: '.com', price: isFa ? '۷۹۹,۰۰۰' : '799,000' },
{ tld: '.ir', price: isFa ? '۱۹,۹۰۰' : '19,900' },
{ tld: '.net', price: isFa ? '۹۹۹,۰۰۰' : '999,000' },
{ tld: '.org', price: isFa ? '۸۹۹,۰۰۰' : '899,000' },
{ tld: '.co', price: isFa ? '۱,۹۹۹,۰۰۰' : '1,999,000' },
{ tld: '.shop', price: isFa ? '۱,۴۹۹,۰۰۰' : '1,499,000' },
].map((p) => (
<div
key={p.tld}
className="rounded-3xl border border-[color:var(--border-10)] bg-[color:var(--glass-05)] backdrop-blur-md p-5"
>
<div className="flex items-start justify-between gap-3">
<div className="text-2xl font-extrabold">{p.tld}</div>
<div className="w-10 h-10 rounded-2xl border border-[color:var(--border-10)] bg-[color:var(--glass-02)] flex items-center justify-center">
<ShoppingCart className="w-4 h-4 text-cyan-300/90" />
</div>
</div>
<div className="mt-2 text-xs text-[color:var(--text-muted-3)]">{isFa ? 'قیمت سالانه' : 'Yearly price'}</div>
<div className="mt-2 text-sm text-[color:var(--text-muted-2)]">
{p.price} {isFa ? 'تومان/سال' : 'Toman/yr'}
</div>
</div>
))}
</div>
<div className="mt-6 flex justify-center">
<button
type="button"
className="px-7 py-3 rounded-2xl border border-[color:var(--border-10)] bg-[color:var(--glass-05)] hover:bg-[color:var(--glass-10)] transition-colors text-sm font-semibold"
>
{isFa ? 'مشاهده همه پسوندها' : 'View all TLDs'}
</button>
</div>
</div>
{/* 3-step process */}
<div className="mt-12">
<div className="text-center text-xl md:text-2xl font-bold">
{isFa ? 'فرآیند ثبت دامنه در ۳ مرحله' : 'Register a domain in 3 steps'}
</div>
<div className="mt-6 grid grid-cols-1 md:grid-cols-3 gap-4">
{[
{ t: isFa ? '۱. جستجو' : '1. Search', d: isFa ? 'نام دامنه را وارد کنید و جستجو کنید.' : 'Enter a name and search.' },
{ t: isFa ? '۲. انتخاب' : '2. Choose', d: isFa ? 'پسوند و پلن مناسب را انتخاب کنید.' : 'Pick your TLD and plan.' },
{ t: isFa ? '۳. ثبت و فعال‌سازی' : '3. Register & activate', d: isFa ? 'اطلاعات را تکمیل کنید؛ دامنه فعال می‌شود.' : 'Complete info; your domain becomes active.' },
].map((s) => (
<div
key={s.t}
className="rounded-3xl border border-[color:var(--border-10)] bg-[color:var(--glass-05)] backdrop-blur-md p-6"
>
<div className="h-12 w-12 rounded-2xl border border-[color:var(--border-10)] bg-[color:var(--glass-02)]" />
<div className="mt-4 font-bold">{s.t}</div>
<div className="mt-2 text-sm text-[color:var(--text-muted-2)] leading-relaxed">{s.d}</div>
</div>
))}
</div>
</div>
{/* Importance */}
<div className="mt-12">
<div className="rounded-[2rem] border border-[color:var(--border-10)] bg-[color:var(--glass-05)] backdrop-blur-md overflow-hidden">
<div className="p-8 md:p-10 grid grid-cols-1 lg:grid-cols-12 gap-8 items-center">
<div className="lg:col-span-7">
<div className="text-xl md:text-2xl font-bold">{isFa ? 'چرا داشتن دامنه مهم است؟' : 'Why does a domain matter?'}</div>
<div className="mt-4 text-sm text-[color:var(--text-muted-2)] leading-relaxed max-w-2xl">
{isFa
? 'دامنه، اعتبار برند و دسترسی‌پذیری شما را تقویت می‌کند و نقطه شروع هویت آنلاین است.'
: 'A domain boosts brand trust and accessibility — its your online identity foundation.'}
</div>
</div>
<div className="lg:col-span-5">
<div className="relative mx-auto w-full max-w-[320px] aspect-square rounded-full border border-[color:var(--border-10)] bg-[radial-gradient(circle_at_center,rgba(59,130,246,0.25),transparent_60%)]">
<div className="absolute inset-0 rounded-full bg-[radial-gradient(circle_at_center,rgba(16,185,129,0.18),transparent_62%)]" />
<div className="absolute inset-0 rounded-full bg-[radial-gradient(circle_at_center,rgba(99,102,241,0.18),transparent_68%)]" />
</div>
</div>
</div>
</div>
</div>
{/* Final CTA */}
<div className="mt-12 pb-14">
<div className="rounded-[2rem] border border-[color:var(--border-10)] bg-gradient-to-br from-emerald-500/10 via-[color:var(--glass-05)] to-indigo-500/10 backdrop-blur-md overflow-hidden">
<div className="p-8 md:p-10 flex flex-col md:flex-row items-center justify-between gap-6">
<div>
<div className="text-xl md:text-2xl font-extrabold">
{isFa ? 'دامنه مناسب برند خود را همین حالا ثبت کنید.' : 'Register the right domain for your brand today.'}
</div>
<div className="mt-2 text-sm text-[color:var(--text-muted-2)]">
{isFa ? 'آینده آنلاین خود را از امروز شروع کنید.' : 'Start building your online future now.'}
</div>
</div>
<button
type="button"
className="px-8 py-3.5 rounded-2xl bg-gradient-to-r from-emerald-400 to-indigo-500 text-[#071027] font-extrabold text-sm hover:opacity-90 transition-opacity"
>
{isFa ? 'جستجوی دامنه' : 'Search domain'}
</button>
</div>
</div>
</div>
</div>
</section>
<Footer />
</main>
);
}

View File

@@ -0,0 +1,85 @@
import Header from '../../../components/header';
import { Footer } from '../../../components/footer';
export default async function OrgEmailIranPage({
params,
}: {
params: Promise<{ locale: string }>;
}) {
const { locale } = await params;
const isFa = locale === 'fa';
return (
<main className="min-h-screen font-sans">
<Header />
<section className="px-4 sm:px-6 pt-28 pb-14">
<div className="max-w-6xl mx-auto">
<div className="rounded-[2rem] border border-[color:var(--border-10)] bg-gradient-to-br from-emerald-500/10 via-[color:var(--glass-05)] to-teal-500/10 backdrop-blur-md overflow-hidden">
<div className="p-10 md:p-14">
<div className="inline-flex items-center gap-2 px-3 py-1.5 rounded-full bg-[color:var(--glass-10)] border border-[color:var(--border-10)] text-xs text-[color:var(--text-muted)]">
<span>{isFa ? 'ایمیل سازمانی' : 'Business Email'}</span>
<span className="w-1 h-1 rounded-full bg-emerald-400/70" />
<span>{isFa ? 'ایران' : 'Iran'}</span>
</div>
<h1 className="mt-5 text-3xl md:text-5xl font-extrabold text-[color:var(--text-primary)]">
{isFa ? 'ایمیل سازمانی ایران' : 'Business email (Iran)'}
</h1>
<p className="mt-4 text-[color:var(--text-muted-2)] max-w-2xl leading-relaxed">
{isFa
? 'این صفحه نیز از قالب «خدمات» جداست تا UI مخصوص ایمیل ایران را مستقل طراحی کنیم.'
: 'This page is also separated from the services template so the Iran email UI can have its own design.'}
</p>
<div className="mt-10 grid grid-cols-1 lg:grid-cols-[0.95fr_1.05fr] gap-6">
<div className="rounded-3xl border border-[color:var(--border-10)] bg-[color:var(--glass-05)] p-6 md:p-7">
<div className="text-sm font-semibold text-[color:var(--text-primary)]">
{isFa ? 'شروع سریع (Placeholder)' : 'Quick start (Placeholder)'}
</div>
<div className="mt-4 grid grid-cols-1 gap-3">
{[
isFa ? 'انتخاب دامنه سازمانی' : 'Pick your domain',
isFa ? 'ایجاد اکانت‌ها و گروه‌ها' : 'Create accounts & groups',
isFa ? 'اتصال به Outlook / Mobile' : 'Connect to Outlook / Mobile',
].map((step) => (
<div
key={step}
className="rounded-2xl border border-[color:var(--border-10)] bg-[color:var(--glass-02)] p-5 text-sm text-[color:var(--text-muted-2)]"
>
{step}
</div>
))}
</div>
</div>
<div className="rounded-3xl border border-[color:var(--border-10)] bg-[color:var(--glass-05)] p-6 md:p-7">
<div className="text-sm font-semibold text-[color:var(--text-primary)]">
{isFa ? 'چرا ایمیل ایران؟' : 'Why Iran email?'}
</div>
<ul className="mt-4 space-y-3 text-sm text-[color:var(--text-muted-2)]">
<li className="flex items-start gap-2">
<span className="mt-1 w-1.5 h-1.5 rounded-full bg-emerald-400/80" />
<span>{isFa ? 'مناسب نیازهای داخلی و سازمان‌ها' : 'Tailored for local requirements'}</span>
</li>
<li className="flex items-start gap-2">
<span className="mt-1 w-1.5 h-1.5 rounded-full bg-emerald-400/80" />
<span>{isFa ? 'پشتیبانی فارسی و سریع' : 'Fast support'}</span>
</li>
<li className="flex items-start gap-2">
<span className="mt-1 w-1.5 h-1.5 rounded-full bg-emerald-400/80" />
<span>{isFa ? 'امنیت و ضد اسپم' : 'Security & anti-spam'}</span>
</li>
</ul>
</div>
</div>
</div>
</div>
</div>
</section>
<Footer />
</main>
);
}

View File

@@ -0,0 +1,86 @@
import Header from '../../components/header';
import { Footer } from '../../components/footer';
export default async function OrgEmailInternationalPage({
params,
}: {
params: Promise<{ locale: string }>;
}) {
const { locale } = await params;
const isFa = locale === 'fa';
return (
<main className="min-h-screen font-sans">
<Header />
<section className="px-4 sm:px-6 pt-28 pb-14">
<div className="max-w-6xl mx-auto">
<div className="rounded-[2rem] border border-[color:var(--border-10)] bg-gradient-to-br from-rose-500/10 via-[color:var(--glass-05)] to-purple-500/10 backdrop-blur-md overflow-hidden">
<div className="p-10 md:p-14">
<div className="inline-flex items-center gap-2 px-3 py-1.5 rounded-full bg-[color:var(--glass-10)] border border-[color:var(--border-10)] text-xs text-[color:var(--text-muted)]">
<span>{isFa ? 'ایمیل سازمانی' : 'Business Email'}</span>
<span className="w-1 h-1 rounded-full bg-rose-400/70" />
<span>{isFa ? 'بین‌الملل' : 'International'}</span>
</div>
<h1 className="mt-5 text-3xl md:text-5xl font-extrabold text-[color:var(--text-primary)]">
{isFa ? 'ایمیل سازمانی بین‌المللی' : 'International business email'}
</h1>
<p className="mt-4 text-[color:var(--text-muted-2)] max-w-2xl leading-relaxed">
{isFa
? 'این صفحه از قالب «خدمات» جدا شده تا UI ایمیل سازمانی متفاوت‌تر طراحی شود.'
: 'This page is separated from the services template so the business email UI can be designed differently.'}
</p>
<div className="mt-10 grid grid-cols-1 md:grid-cols-2 gap-5">
<div className="rounded-3xl border border-[color:var(--border-10)] bg-[color:var(--glass-05)] p-6 md:p-7">
<div className="text-sm font-semibold text-[color:var(--text-primary)]">
{isFa ? 'پلن‌ها (Placeholder)' : 'Plans (Placeholder)'}
</div>
<div className="mt-4 grid grid-cols-1 gap-3">
{[
{ name: isFa ? 'Starter' : 'Starter', price: isFa ? '...' : '...' },
{ name: isFa ? 'Team' : 'Team', price: isFa ? '...' : '...' },
{ name: isFa ? 'Business' : 'Business', price: isFa ? '...' : '...' },
].map((p) => (
<div
key={p.name}
className="rounded-2xl border border-[color:var(--border-10)] bg-[color:var(--glass-02)] p-5 flex items-center justify-between"
>
<div className="text-sm font-semibold text-[color:var(--text-primary)]">{p.name}</div>
<div className="text-sm text-[color:var(--text-muted-2)]">{p.price}</div>
</div>
))}
</div>
</div>
<div className="rounded-3xl border border-[color:var(--border-10)] bg-[color:var(--glass-05)] p-6 md:p-7">
<div className="text-sm font-semibold text-[color:var(--text-primary)]">
{isFa ? 'ویژگی‌ها' : 'Features'}
</div>
<ul className="mt-4 space-y-3 text-sm text-[color:var(--text-muted-2)]">
<li className="flex items-start gap-2">
<span className="mt-1 w-1.5 h-1.5 rounded-full bg-rose-400/80" />
<span>{isFa ? 'وب‌میل و موبایل' : 'Webmail & mobile'}</span>
</li>
<li className="flex items-start gap-2">
<span className="mt-1 w-1.5 h-1.5 rounded-full bg-rose-400/80" />
<span>{isFa ? 'امنیت و ضد اسپم' : 'Security & anti-spam'}</span>
</li>
<li className="flex items-start gap-2">
<span className="mt-1 w-1.5 h-1.5 rounded-full bg-rose-400/80" />
<span>{isFa ? 'پشتیبانی مهاجرت' : 'Migration support'}</span>
</li>
</ul>
</div>
</div>
</div>
</div>
</div>
</section>
<Footer />
</main>
);
}

View File

@@ -4,6 +4,14 @@ export type ServiceSlug =
| 'eco-hosting' | 'eco-hosting'
| 'high-traffic-hosting' | 'high-traffic-hosting'
| 'wordpress-hosting' | 'wordpress-hosting'
| 'woocommerce-hosting'
| 'vps'
| 'dedicated-server'
| 'managed-vps'
| 'managed-dedicated'
| 'storage'
| 'cdn'
| 'geodns'
| 'server-management' | 'server-management'
| 'domain' | 'domain'
| 'ssl' | 'ssl'
@@ -13,6 +21,14 @@ export const serviceSlugs: ServiceSlug[] = [
'eco-hosting', 'eco-hosting',
'high-traffic-hosting', 'high-traffic-hosting',
'wordpress-hosting', 'wordpress-hosting',
'woocommerce-hosting',
'vps',
'dedicated-server',
'managed-vps',
'managed-dedicated',
'storage',
'cdn',
'geodns',
'server-management', 'server-management',
'domain', 'domain',
'ssl', 'ssl',
@@ -858,4 +874,904 @@ export const serviceContent: Record<ServiceSlug, Record<Locale, ServiceContent>>
finalCtaButton: 'Request business email', finalCtaButton: 'Request business email',
}, },
}, },
'woocommerce-hosting': {
fa: {
seoTitle: 'هاست ووکامرس',
title: 'هاست ووکامرس',
accent: 'فروشگاهی',
heroBadge: 'میزبانی بهینه برای ووکامرس',
subtitle:
'برای فروشگاه‌های آنلاین سریع‌تر، پایدارتر و امن‌تر — آماده برای ترافیک و سفارش‌های بیشتر.',
breadcrumbs: ['صفحه اصلی', 'میزبانی', 'هاست ووکامرس'],
heroPrimaryCta: 'ثبت سفارش',
heroSecondaryCta: 'مشاهده پلن‌ها',
heroHighlights: [
{ label: 'بهینه‌سازی برای ووکامرس', icon: 'wp' },
{ label: 'امنیت و WAF', icon: 'shield' },
{ label: 'سرعت بالا', icon: 'speed' },
{ label: 'پشتیبانی ۲۴/۷', icon: 'support' },
],
quickStats: [
{ label: 'آپتایم شبکه', value: '۹۹.۹۹٪', icon: 'uptime' },
{ label: 'پشتیبانی', value: '۲۴/۷', icon: 'support' },
{ label: 'ذخیره‌ساز', value: 'NVMe SSD', icon: 'nvme' },
{ label: 'امنیت', value: 'WAF + SSL', icon: 'security' },
],
featuresTitle: 'ویژگی‌های هاست ووکامرس',
featuresSubtitle: 'برای فروشگاه‌های حرفه‌ای',
features: [
{ title: 'سرعت فروشگاه', desc: 'کشینگ و تنظیمات بهینه برای صفحات محصول.', icon: 'bolt' },
{ title: 'امنیت پرداخت', desc: 'SSL و محافظت در برابر حملات رایج.', icon: 'shield' },
{ title: 'پایداری در ترافیک', desc: 'آماده برای کمپین‌ها و پیک بازدید.', icon: 'cloud' },
{ title: 'راه‌اندازی سریع', desc: 'فعال‌سازی سریع بعد از سفارش.', icon: 'rocket' },
{ title: 'پشتیبان‌گیری', desc: 'بکاپ منظم و امکان بازیابی آسان.', icon: 'cloud' },
{ title: 'پشتیبانی تخصصی', desc: 'کمک برای مشکلات رایج ووکامرس.', icon: 'headphones' },
],
plansTitle: 'پلن‌های هاست ووکامرس',
plansSubtitle: 'مناسب فروشگاه‌های کوچک تا بزرگ',
plans: [
{
name: 'Starter',
price: '۱۹۹,۰۰۰',
period: 'تومان / ماهانه',
features: ['۱ فروشگاه', '۲۰ گیگ NVMe', 'SSL رایگان', 'بکاپ منظم'],
cta: 'سفارش',
},
{
name: 'Pro',
price: '۴۹۹,۰۰۰',
period: 'تومان / ماهانه',
badge: 'پیشنهادی',
featured: true,
features: ['۲ فروشگاه', '۴۰ گیگ NVMe', 'کشینگ پیشرفته', 'پشتیبانی اولویت‌دار'],
cta: 'سفارش',
},
{
name: 'Scale',
price: '۹۹۹,۰۰۰',
period: 'تومان / ماهانه',
features: ['۵ فروشگاه', '۸۰ گیگ NVMe', 'منابع بیشتر', 'پایش ۲۴/۷'],
cta: 'سفارش',
},
],
faqTitle: 'سوالات متداول',
faqSubtitle: 'پرسش‌های رایج درباره هاست ووکامرس',
faqs: [
{ q: 'برای فروشگاه‌های پربازدید مناسب است؟', a: 'بله، پلن‌های بالاتر برای ترافیک و سفارش بیشتر طراحی شده‌اند.' },
{ q: 'می‌توانم بعداً ارتقا بدهم؟', a: 'بله، هر زمان امکان ارتقا وجود دارد.' },
{ q: 'SSL رایگان دارد؟', a: 'بله، برای همه پلن‌ها SSL ارائه می‌شود.' },
{ q: 'بکاپ چگونه انجام می‌شود؟', a: 'به صورت منظم و طبق سیاست سرویس بکاپ تهیه می‌شود.' },
],
whyTitle: 'چرا هاست ووکامرس MugCloud؟',
whyText: 'برای فروشگاه، سرعت و پایداری مهم است — اینجا دقیقاً برای همین ساخته شده.',
whyBullets: ['سرعت بهتر', 'امنیت بیشتر', 'پشتیبانی ۲۴/۷', 'آماده برای ترافیک', 'راه‌اندازی سریع'],
finalCtaTitle: 'فروشگاه‌تان را سریع‌تر کنید',
finalCtaDesc: 'پلن مناسب ووکامرس را انتخاب کنید و شروع کنید.',
finalCtaButton: 'ثبت سفارش هاست ووکامرس',
},
en: {
seoTitle: 'WooCommerce Hosting',
title: 'WooCommerce Hosting',
accent: 'store-ready',
heroBadge: 'Optimized for WooCommerce',
subtitle:
'Fast, stable, and secure hosting for online stores — built for growth and peak traffic.',
breadcrumbs: ['Home', 'Hosting', 'WooCommerce Hosting'],
heroPrimaryCta: 'Order now',
heroSecondaryCta: 'View plans',
heroHighlights: [
{ label: 'WooCommerce-ready tuning', icon: 'wp' },
{ label: 'WAF + security', icon: 'shield' },
{ label: 'High performance', icon: 'speed' },
{ label: '24/7 support', icon: 'support' },
],
quickStats: [
{ label: 'Uptime', value: '99.99%', icon: 'uptime' },
{ label: 'Support', value: '24/7', icon: 'support' },
{ label: 'Storage', value: 'NVMe SSD', icon: 'nvme' },
{ label: 'Security', value: 'WAF + SSL', icon: 'security' },
],
featuresTitle: 'WooCommerce features',
featuresSubtitle: 'For serious online stores',
features: [
{ title: 'Store speed', desc: 'Caching and tuning for product pages.', icon: 'bolt' },
{ title: 'Secure checkout', desc: 'SSL and protection against common attacks.', icon: 'shield' },
{ title: 'Peak traffic stability', desc: 'Ready for campaigns and spikes.', icon: 'cloud' },
{ title: 'Quick activation', desc: 'Fast provisioning after purchase.', icon: 'rocket' },
{ title: 'Backups', desc: 'Regular backups with easy restore.', icon: 'cloud' },
{ title: 'Expert support', desc: 'Help with common WooCommerce issues.', icon: 'headphones' },
],
plansTitle: 'Plans',
plansSubtitle: 'From small to large stores',
plans: [
{ name: 'Starter', price: '199,000', period: 'Toman / month', features: ['1 store', '20GB NVMe', 'Free SSL', 'Backups'], cta: 'Order' },
{ name: 'Pro', price: '499,000', period: 'Toman / month', badge: 'Recommended', featured: true, features: ['2 stores', '40GB NVMe', 'Advanced caching', 'Priority support'], cta: 'Order' },
{ name: 'Scale', price: '999,000', period: 'Toman / month', features: ['5 stores', '80GB NVMe', 'More resources', '24/7 monitoring'], cta: 'Order' },
],
faqTitle: 'FAQ',
faqSubtitle: 'WooCommerce hosting questions',
faqs: [
{ q: 'Is it good for high-traffic stores?', a: 'Yes. Higher plans are built for more traffic and orders.' },
{ q: 'Can I upgrade later?', a: 'Yes, you can upgrade anytime.' },
{ q: 'Is SSL included?', a: 'Yes, all plans include SSL.' },
{ q: 'How do backups work?', a: 'Backups are taken regularly based on service policy.' },
],
whyTitle: 'Why MugCloud WooCommerce?',
whyText: 'Speed and stability are everything for stores — thats what we focus on.',
whyBullets: ['Faster store', 'Stronger security', '24/7 support', 'Peak-ready', 'Quick setup'],
finalCtaTitle: 'Make your store faster',
finalCtaDesc: 'Pick a WooCommerce plan and launch today.',
finalCtaButton: 'Order WooCommerce Hosting',
},
},
vps: {
fa: {
seoTitle: 'سرور مجازی',
title: 'سرور مجازی',
accent: 'پرسرعت',
heroBadge: 'VPS پایدار و سریع',
subtitle:
'منابع اختصاصی، دسترسی Root و عملکرد بالا — مناسب اپلیکیشن‌ها، سایت‌ها و سرویس‌های شما.',
breadcrumbs: ['صفحه اصلی', 'سرور', 'سرور مجازی'],
heroPrimaryCta: 'ثبت سفارش',
heroSecondaryCta: 'مشاهده پلن‌ها',
heroHighlights: [
{ label: 'دسترسی Root', icon: 'speed' },
{ label: 'امنیت شبکه', icon: 'shield' },
{ label: 'راه‌اندازی سریع', icon: 'support' },
{ label: 'مانیتورینگ ۲۴/۷', icon: 'support' },
],
quickStats: [
{ label: 'آپتایم شبکه', value: '۹۹.۹۹٪', icon: 'uptime' },
{ label: 'پشتیبانی', value: '۲۴/۷', icon: 'support' },
{ label: 'ذخیره‌ساز', value: 'NVMe SSD', icon: 'nvme' },
{ label: 'امنیت', value: 'DDoS Guard', icon: 'security' },
],
featuresTitle: 'ویژگی‌های سرور مجازی',
featuresSubtitle: 'کنترل و انعطاف‌پذیری',
features: [
{ title: 'منابع اختصاصی', desc: 'CPU/RAM تضمین‌شده برای پایداری بیشتر.', icon: 'bolt' },
{ title: 'دسترسی کامل', desc: 'Root/Administrator برای نصب و مدیریت.', icon: 'rocket' },
{ title: 'امنیت شبکه', desc: 'محافظت و مانیتورینگ لایه شبکه.', icon: 'shield' },
{ title: 'اسنپ‌شات و بکاپ', desc: 'راهکارهای پشتیبان‌گیری و بازیابی.', icon: 'cloud' },
{ title: 'مقیاس‌پذیری', desc: 'امکان ارتقا منابع در زمان نیاز.', icon: 'cloud' },
{ title: 'پشتیبانی', desc: 'کمک برای راه‌اندازی و مشکلات رایج.', icon: 'headphones' },
],
plansTitle: 'پلن‌های VPS',
plansSubtitle: 'برای شروع تا مقیاس بزرگ',
plans: [
{ name: 'VPS 1', price: '۲۹۹,۰۰۰', period: 'تومان / ماهانه', features: ['۲ vCPU', '۲GB RAM', ۰GB NVMe', '۱ IPv4'], cta: 'سفارش' },
{ name: 'VPS 2', price: '۵۹۹,۰۰۰', period: 'تومان / ماهانه', badge: 'محبوب', featured: true, features: ['۴ vCPU', '۴GB RAM', ۰GB NVMe', '۱ IPv4'], cta: 'سفارش' },
{ name: 'VPS 3', price: '۱,۱۹۹,۰۰۰', period: 'تومان / ماهانه', features: ['۸ vCPU', '۸GB RAM', '۱۲۰GB NVMe', '۱ IPv4'], cta: 'سفارش' },
],
faqTitle: 'سوالات متداول',
faqSubtitle: 'پرسش‌های رایج درباره VPS',
faqs: [
{ q: 'سیستم‌عامل قابل انتخاب است؟', a: 'بله، معمولاً چند توزیع لینوکس و ویندوز در دسترس است.' },
{ q: 'آیا ارتقا منابع ممکن است؟', a: 'بله، می‌توانید هر زمان منابع را افزایش دهید.' },
{ q: 'دسترسی Root دارم؟', a: 'بله، دسترسی کامل به سرور دارید.' },
{ q: 'برای چه کاربردی مناسب است؟', a: 'وب‌سایت‌ها، اپلیکیشن‌ها، دیتابیس‌ها و سرویس‌های مختلف.' },
],
whyTitle: 'چرا VPS MugCloud؟',
whyText: 'برای پروژه‌هایی که کنترل و منابع اختصاصی می‌خواهند.',
whyBullets: ['منابع اختصاصی', 'پایداری بالا', 'امنیت شبکه', 'راه‌اندازی سریع', 'پشتیبانی ۲۴/۷'],
finalCtaTitle: 'VPS خودتان را بسازید',
finalCtaDesc: 'پلن مناسب را انتخاب کنید و شروع کنید.',
finalCtaButton: 'ثبت سفارش VPS',
},
en: {
seoTitle: 'VPS',
title: 'VPS',
accent: 'high-performance',
heroBadge: 'Fast & stable virtual servers',
subtitle:
'Dedicated resources, root access, and solid performance — for websites, apps, and services.',
breadcrumbs: ['Home', 'Servers', 'VPS'],
heroPrimaryCta: 'Order now',
heroSecondaryCta: 'View plans',
heroHighlights: [
{ label: 'Root access', icon: 'speed' },
{ label: 'Network security', icon: 'shield' },
{ label: 'Quick provisioning', icon: 'support' },
{ label: '24/7 monitoring', icon: 'support' },
],
quickStats: [
{ label: 'Uptime', value: '99.99%', icon: 'uptime' },
{ label: 'Support', value: '24/7', icon: 'support' },
{ label: 'Storage', value: 'NVMe SSD', icon: 'nvme' },
{ label: 'Security', value: 'DDoS guard', icon: 'security' },
],
featuresTitle: 'VPS features',
featuresSubtitle: 'Control & flexibility',
features: [
{ title: 'Dedicated resources', desc: 'Guaranteed CPU/RAM for consistency.', icon: 'bolt' },
{ title: 'Full access', desc: 'Root/Administrator for installs and management.', icon: 'rocket' },
{ title: 'Network security', desc: 'Protection and monitoring.', icon: 'shield' },
{ title: 'Snapshots & backups', desc: 'Backup and recovery options.', icon: 'cloud' },
{ title: 'Scalability', desc: 'Scale up when you need more.', icon: 'cloud' },
{ title: 'Support', desc: 'Help with setups and common issues.', icon: 'headphones' },
],
plansTitle: 'VPS plans',
plansSubtitle: 'From starter to scale',
plans: [
{ name: 'VPS 1', price: '299,000', period: 'Toman / month', features: ['2 vCPU', '2GB RAM', '30GB NVMe', '1 IPv4'], cta: 'Order' },
{ name: 'VPS 2', price: '599,000', period: 'Toman / month', badge: 'Popular', featured: true, features: ['4 vCPU', '4GB RAM', '60GB NVMe', '1 IPv4'], cta: 'Order' },
{ name: 'VPS 3', price: '1,199,000', period: 'Toman / month', features: ['8 vCPU', '8GB RAM', '120GB NVMe', '1 IPv4'], cta: 'Order' },
],
faqTitle: 'FAQ',
faqSubtitle: 'Common VPS questions',
faqs: [
{ q: 'Can I choose an OS?', a: 'Yes, multiple Linux distros (and often Windows) are available.' },
{ q: 'Can I scale resources?', a: 'Yes, you can upgrade anytime.' },
{ q: 'Do I get root access?', a: 'Yes, full access is provided.' },
{ q: 'What is it good for?', a: 'Websites, applications, databases, and many services.' },
],
whyTitle: 'Why MugCloud VPS?',
whyText: 'For projects that need control and dedicated resources.',
whyBullets: ['Dedicated resources', 'High stability', 'Network security', 'Fast setup', '24/7 support'],
finalCtaTitle: 'Spin up your VPS',
finalCtaDesc: 'Pick a plan and launch today.',
finalCtaButton: 'Order VPS',
},
},
'dedicated-server': {
fa: {
seoTitle: 'سرور اختصاصی',
title: 'سرور اختصاصی',
accent: 'قدرت‌مند',
heroBadge: 'کنترل کامل سخت‌افزار',
subtitle:
'بیشترین قدرت و امنیت برای سرویس‌های سنگین — مناسب دیتابیس، پردازش و ترافیک بالا.',
breadcrumbs: ['صفحه اصلی', 'سرور', 'سرور اختصاصی'],
heroPrimaryCta: 'درخواست مشاوره',
heroSecondaryCta: 'مشاهده پلن‌ها',
heroHighlights: [
{ label: 'منابع ۱۰۰٪ اختصاصی', icon: 'speed' },
{ label: 'امنیت بالا', icon: 'shield' },
{ label: 'شبکه پایدار', icon: 'support' },
{ label: 'پشتیبانی ۲۴/۷', icon: 'support' },
],
quickStats: [
{ label: 'آپتایم شبکه', value: '۹۹.۹۹٪', icon: 'uptime' },
{ label: 'پشتیبانی', value: '۲۴/۷', icon: 'support' },
{ label: 'پرفورمنس', value: 'Bare metal', icon: 'nvme' },
{ label: 'امنیت', value: 'DDoS Guard', icon: 'security' },
],
featuresTitle: 'ویژگی‌های سرور اختصاصی',
featuresSubtitle: 'برای بارهای سنگین',
features: [
{ title: 'حداکثر پرفورمنس', desc: 'بدون اشتراک منابع، مناسب پردازش سنگین.', icon: 'bolt' },
{ title: 'کنترل کامل', desc: 'پیکربندی دلخواه و دسترسی مدیریتی کامل.', icon: 'rocket' },
{ title: 'امنیت شبکه', desc: 'محافظت و مانیتورینگ شبکه.', icon: 'shield' },
{ title: 'RAID و ذخیره‌سازی', desc: 'گزینه‌های ذخیره‌سازی متنوع و امن.', icon: 'cloud' },
{ title: 'آپ‌تایم بالا', desc: 'زیرساخت پایدار و پایش مداوم.', icon: 'cloud' },
{ title: 'پشتیبانی', desc: 'تیم فنی برای سناریوهای پیچیده.', icon: 'headphones' },
],
plansTitle: 'پلن‌های سرور اختصاصی',
plansSubtitle: 'پیشنهادی (قابل سفارشی‌سازی)',
plans: [
{ name: 'Entry', price: '۲,۹۹۹,۰۰۰', period: 'تومان / ماهانه', features: ['CPU 8c', '32GB RAM', '2xNVMe', '1Gbps'], cta: 'درخواست' },
{ name: 'Pro', price: '۴,۹۹۹,۰۰۰', period: 'تومان / ماهانه', badge: 'پیشنهادی', featured: true, features: ['CPU 12c', '64GB RAM', '2xNVMe', '1Gbps'], cta: 'درخواست' },
{ name: 'Ultra', price: '۷,۹۹۹,۰۰۰', period: 'تومان / ماهانه', features: ['CPU 16c', '128GB RAM', '4xNVMe', '1Gbps'], cta: 'درخواست' },
],
faqTitle: 'سوالات متداول',
faqSubtitle: 'پرسش‌های رایج درباره سرور اختصاصی',
faqs: [
{ q: 'سرور اختصاصی برای چه کسانی مناسب است؟', a: 'برای پروژه‌های سنگین، دیتابیس‌های بزرگ و ترافیک بالا.' },
{ q: 'آیا امکان سفارشی‌سازی هست؟', a: 'بله، سخت‌افزار و شبکه قابل تنظیم است.' },
{ q: 'زمان تحویل چقدر است؟', a: 'بسته به موجودی و پیکربندی، معمولاً سریع انجام می‌شود.' },
{ q: 'مدیریت هم دارید؟', a: 'بله، سرویس‌های مدیریت‌شده هم ارائه می‌شود.' },
],
whyTitle: 'چرا سرور اختصاصی MugCloud؟',
whyText: 'وقتی به نهایت قدرت و کنترل نیاز دارید.',
whyBullets: ['قدرت واقعی', 'منابع اختصاصی', 'امنیت شبکه', 'پشتیبانی ۲۴/۷', 'قابل سفارشی‌سازی'],
finalCtaTitle: 'آماده ارتقا هستید؟',
finalCtaDesc: 'برای انتخاب بهترین کانفیگ با ما صحبت کنید.',
finalCtaButton: 'درخواست مشاوره',
},
en: {
seoTitle: 'Dedicated Server',
title: 'Dedicated Server',
accent: 'maximum power',
heroBadge: 'Full hardware control',
subtitle:
'Top performance and security for heavy workloads — databases, processing, and high traffic.',
breadcrumbs: ['Home', 'Servers', 'Dedicated'],
heroPrimaryCta: 'Talk to sales',
heroSecondaryCta: 'View plans',
heroHighlights: [
{ label: '100% dedicated resources', icon: 'speed' },
{ label: 'Strong security', icon: 'shield' },
{ label: 'Stable network', icon: 'support' },
{ label: '24/7 support', icon: 'support' },
],
quickStats: [
{ label: 'Uptime', value: '99.99%', icon: 'uptime' },
{ label: 'Support', value: '24/7', icon: 'support' },
{ label: 'Performance', value: 'Bare metal', icon: 'nvme' },
{ label: 'Security', value: 'DDoS guard', icon: 'security' },
],
featuresTitle: 'Dedicated server features',
featuresSubtitle: 'Built for heavy workloads',
features: [
{ title: 'Max performance', desc: 'No noisy neighbors, built for heavy loads.', icon: 'bolt' },
{ title: 'Full control', desc: 'Choose your stack and manage everything.', icon: 'rocket' },
{ title: 'Network security', desc: 'Protection and monitoring.', icon: 'shield' },
{ title: 'RAID & storage', desc: 'Flexible storage options.', icon: 'cloud' },
{ title: 'High uptime', desc: 'Stable infrastructure and monitoring.', icon: 'cloud' },
{ title: 'Support', desc: 'Expert help for complex setups.', icon: 'headphones' },
],
plansTitle: 'Dedicated plans',
plansSubtitle: 'Suggested (customizable)',
plans: [
{ name: 'Entry', price: '2,999,000', period: 'Toman / month', features: ['CPU 8c', '32GB RAM', '2xNVMe', '1Gbps'], cta: 'Request' },
{ name: 'Pro', price: '4,999,000', period: 'Toman / month', badge: 'Recommended', featured: true, features: ['CPU 12c', '64GB RAM', '2xNVMe', '1Gbps'], cta: 'Request' },
{ name: 'Ultra', price: '7,999,000', period: 'Toman / month', features: ['CPU 16c', '128GB RAM', '4xNVMe', '1Gbps'], cta: 'Request' },
],
faqTitle: 'FAQ',
faqSubtitle: 'Dedicated server questions',
faqs: [
{ q: 'Who is it for?', a: 'Heavy workloads, big databases, and high traffic.' },
{ q: 'Can I customize hardware?', a: 'Yes, hardware and network can be customized.' },
{ q: 'How fast is delivery?', a: 'Depends on stock and configuration, usually fast.' },
{ q: 'Do you offer managed options?', a: 'Yes, managed services are available.' },
],
whyTitle: 'Why MugCloud Dedicated?',
whyText: 'When you need maximum power and control.',
whyBullets: ['Real power', 'Dedicated resources', 'Network security', '24/7 support', 'Customizable'],
finalCtaTitle: 'Ready to scale up?',
finalCtaDesc: 'Talk to us and pick the best configuration.',
finalCtaButton: 'Talk to sales',
},
},
'managed-vps': {
fa: {
seoTitle: 'سرور مجازی مدیریت‌شده',
title: 'سرور مجازی مدیریت‌شده',
accent: 'بدون دردسر',
heroBadge: 'مدیریت و نگهداری توسط تیم فنی',
subtitle:
'VPS با خیال راحت — مانیتورینگ، به‌روزرسانی و نگهداری توسط تیم ما، شما فقط روی محصول تمرکز کنید.',
breadcrumbs: ['صفحه اصلی', 'سرور', 'VPS مدیریت‌شده'],
heroPrimaryCta: 'درخواست',
heroSecondaryCta: 'مشاهده پلن‌ها',
heroHighlights: [
{ label: 'مانیتورینگ ۲۴/۷', icon: 'support' },
{ label: 'به‌روزرسانی امنیتی', icon: 'shield' },
{ label: 'پشتیبانی تخصصی', icon: 'support' },
{ label: 'بهینه‌سازی عملکرد', icon: 'speed' },
],
quickStats: [
{ label: 'SLA', value: '۹۹.۹۹٪', icon: 'uptime' },
{ label: 'پشتیبانی', value: '۲۴/۷', icon: 'support' },
{ label: 'امنیت', value: 'Hardening', icon: 'security' },
{ label: 'مدیریت', value: 'Managed', icon: 'nvme' },
],
featuresTitle: 'ویژگی‌های VPS مدیریت‌شده',
featuresSubtitle: 'وقتی تیم فنی ندارید یا وقتش را ندارید',
features: [
{ title: 'پایش و هشدار', desc: 'مانیتورینگ منابع و سرویس‌ها.', icon: 'bolt' },
{ title: 'امنیت', desc: 'هاردنینگ و تنظیمات امنیتی پایه.', icon: 'shield' },
{ title: 'به‌روزرسانی‌ها', desc: 'آپدیت‌های سیستم‌عامل و پکیج‌ها.', icon: 'cloud' },
{ title: 'پشتیبان‌گیری', desc: 'بکاپ و سناریوی بازیابی.', icon: 'cloud' },
{ title: 'بهینه‌سازی', desc: 'بهبود تنظیمات برای کارایی بهتر.', icon: 'rocket' },
{ title: 'پشتیبانی', desc: 'همراهی برای خطاها و مشکلات رایج.', icon: 'headphones' },
],
plansTitle: 'پلن‌های مدیریت VPS',
plansSubtitle: 'با سطح مدیریت مختلف',
plans: [
{ name: 'Basic', price: '۸۹۹,۰۰۰', period: 'تومان / ماهانه', features: ['مانیتورینگ', 'آپدیت امنیتی', 'پشتیبانی'], cta: 'درخواست' },
{ name: 'Pro', price: '۱,۴۹۹,۰۰۰', period: 'تومان / ماهانه', badge: 'پیشنهادی', featured: true, features: ['مانیتورینگ', 'هاردنینگ', 'بکاپ', 'پشتیبانی اولویت‌دار'], cta: 'درخواست' },
{ name: 'Enterprise', price: 'تماس', period: '', features: ['SLA', 'مدیریت اختصاصی', 'سناریوی سفارشی'], cta: 'تماس' },
],
faqTitle: 'سوالات متداول',
faqSubtitle: 'پرسش‌های رایج درباره مدیریت‌شده',
faqs: [
{ q: 'چه چیزهایی مدیریت می‌شود؟', a: 'پایش، به‌روزرسانی، تنظیمات امنیتی پایه و رسیدگی به موارد رایج.' },
{ q: 'آیا کنترل Root دارم؟', a: 'بله، دسترسی کامل همچنان در اختیار شماست.' },
{ q: 'برای چه کسانی مناسب است؟', a: 'برای تیم‌های کوچک یا کسب‌وکارهایی که تیم فنی ندارند.' },
{ q: 'آیا شامل توسعه نرم‌افزار هم هست؟', a: 'خیر، تمرکز روی مدیریت سرور و زیرساخت است.' },
],
whyTitle: 'چرا مدیریت‌شده؟',
whyText: 'کاهش ریسک، صرفه‌جویی در زمان و تمرکز روی رشد محصول.',
whyBullets: ['پایش ۲۴/۷', 'به‌روزرسانی امنیتی', 'پشتیبانی تخصصی', 'بهینه‌سازی', 'کاهش ریسک'],
finalCtaTitle: 'بدون دردسر مدیریت کنید',
finalCtaDesc: 'مدیریت را به ما بسپارید و روی محصول تمرکز کنید.',
finalCtaButton: 'درخواست VPS مدیریت‌شده',
},
en: {
seoTitle: 'Managed VPS',
title: 'Managed VPS',
accent: 'hands-off',
heroBadge: 'Operations handled by our team',
subtitle:
'A worry-free VPS — monitoring, updates, and maintenance handled for you so you can focus on your product.',
breadcrumbs: ['Home', 'Servers', 'Managed VPS'],
heroPrimaryCta: 'Request',
heroSecondaryCta: 'View plans',
heroHighlights: [
{ label: '24/7 monitoring', icon: 'support' },
{ label: 'Security updates', icon: 'shield' },
{ label: 'Expert support', icon: 'support' },
{ label: 'Performance tuning', icon: 'speed' },
],
quickStats: [
{ label: 'SLA', value: '99.99%', icon: 'uptime' },
{ label: 'Support', value: '24/7', icon: 'support' },
{ label: 'Security', value: 'Hardening', icon: 'security' },
{ label: 'Ops', value: 'Managed', icon: 'nvme' },
],
featuresTitle: 'Managed VPS features',
featuresSubtitle: 'For teams without ops bandwidth',
features: [
{ title: 'Monitoring & alerts', desc: 'Resource and service monitoring.', icon: 'bolt' },
{ title: 'Security', desc: 'Baseline hardening and policies.', icon: 'shield' },
{ title: 'Updates', desc: 'OS and package updates.', icon: 'cloud' },
{ title: 'Backups', desc: 'Backup and recovery plan.', icon: 'cloud' },
{ title: 'Optimization', desc: 'Performance tuning for common stacks.', icon: 'rocket' },
{ title: 'Support', desc: 'Help with incidents and common issues.', icon: 'headphones' },
],
plansTitle: 'Managed plans',
plansSubtitle: 'Different levels of ops',
plans: [
{ name: 'Basic', price: '899,000', period: 'Toman / month', features: ['Monitoring', 'Security updates', 'Support'], cta: 'Request' },
{ name: 'Pro', price: '1,499,000', period: 'Toman / month', badge: 'Recommended', featured: true, features: ['Monitoring', 'Hardening', 'Backups', 'Priority support'], cta: 'Request' },
{ name: 'Enterprise', price: 'Quote', period: '', features: ['SLA', 'Dedicated ops', 'Custom runbooks'], cta: 'Contact' },
],
faqTitle: 'FAQ',
faqSubtitle: 'Managed service questions',
faqs: [
{ q: 'What is managed?', a: 'Monitoring, updates, baseline hardening, and common operational tasks.' },
{ q: 'Do I still have root?', a: 'Yes, you keep full access.' },
{ q: 'Who is it for?', a: 'Small teams or businesses without an ops team.' },
{ q: 'Does it include app development?', a: 'No, it focuses on server and infrastructure operations.' },
],
whyTitle: 'Why managed?',
whyText: 'Reduce risk, save time, and focus on shipping.',
whyBullets: ['24/7 monitoring', 'Security updates', 'Expert support', 'Optimization', 'Lower risk'],
finalCtaTitle: 'Go hands-off',
finalCtaDesc: 'Let us manage ops while you build your product.',
finalCtaButton: 'Request Managed VPS',
},
},
'managed-dedicated': {
fa: {
seoTitle: 'سرور اختصاصی مدیریت‌شده',
title: 'سرور اختصاصی مدیریت‌شده',
accent: 'امن و پایدار',
heroBadge: 'عملیات و نگهداری توسط ما',
subtitle:
'Bare metal با مدیریت حرفه‌ای — مناسب سرویس‌های حیاتی که به SLA و پایداری بالا نیاز دارند.',
breadcrumbs: ['صفحه اصلی', 'سرور', 'اختصاصی مدیریت‌شده'],
heroPrimaryCta: 'درخواست',
heroSecondaryCta: 'مشاهده پلن‌ها',
heroHighlights: [
{ label: 'پایش و نگهداری', icon: 'support' },
{ label: 'امنیت سازمانی', icon: 'shield' },
{ label: 'کارایی بالا', icon: 'speed' },
{ label: 'SLA', icon: 'support' },
],
quickStats: [
{ label: 'SLA', value: '۹۹.۹۹٪', icon: 'uptime' },
{ label: 'پشتیبانی', value: '۲۴/۷', icon: 'support' },
{ label: 'امنیت', value: 'Hardening', icon: 'security' },
{ label: 'پرفورمنس', value: 'Bare metal', icon: 'nvme' },
],
featuresTitle: 'ویژگی‌های اختصاصی مدیریت‌شده',
featuresSubtitle: 'برای سرویس‌های حساس',
features: [
{ title: 'پایش ۲۴/۷', desc: 'مانیتورینگ عمیق سرویس‌ها و منابع.', icon: 'bolt' },
{ title: 'امنیت', desc: 'هاردنینگ و سیاست‌های امنیتی.', icon: 'shield' },
{ title: 'آپدیت و نگهداری', desc: 'به‌روزرسانی‌های دوره‌ای و مدیریت پچ‌ها.', icon: 'cloud' },
{ title: 'بکاپ و DR', desc: 'سناریوهای بکاپ و بازیابی.', icon: 'cloud' },
{ title: 'بهینه‌سازی', desc: 'پرفورمنس تیونینگ برای کاربری شما.', icon: 'rocket' },
{ title: 'پشتیبانی تخصصی', desc: 'همراهی برای Incidentها.', icon: 'headphones' },
],
plansTitle: 'پلن‌های مدیریت اختصاصی',
plansSubtitle: 'پیشنهادی (قابل سفارشی‌سازی)',
plans: [
{ name: 'Standard', price: 'تماس', period: '', features: ['پایش', 'امنیت', 'آپدیت'], cta: 'درخواست' },
{ name: 'SLA+', price: 'تماس', period: '', badge: 'پیشنهادی', featured: true, features: ['SLA', 'پشتیبانی اولویت‌دار', 'بکاپ/DR'], cta: 'درخواست' },
{ name: 'Enterprise', price: 'تماس', period: '', features: ['مدیریت اختصاصی', 'Runbook', 'شبکه سفارشی'], cta: 'تماس' },
],
faqTitle: 'سوالات متداول',
faqSubtitle: 'پرسش‌های رایج درباره مدیریت اختصاصی',
faqs: [
{ q: 'مدیریت شامل چه مواردی است؟', a: 'پایش، امنیت، آپدیت، بکاپ و رسیدگی به رخدادها.' },
{ q: 'آیا می‌توانم سفارشی‌سازی کنم؟', a: 'بله، بر اساس نیاز سرویس شما قابل تنظیم است.' },
{ q: 'برای چه استفاده‌ای مناسب است؟', a: 'سرویس‌های حیاتی، مالی، دیتابیس‌های بزرگ و ترافیک بالا.' },
{ q: 'آیا SLA ارائه می‌شود؟', a: 'بله، بر اساس پلن امکان ارائه SLA وجود دارد.' },
],
whyTitle: 'چرا اختصاصی مدیریت‌شده؟',
whyText: 'برای سرویس‌هایی که توقف برایشان معنی ندارد.',
whyBullets: ['SLA', 'پایش ۲۴/۷', 'امنیت سازمانی', 'پشتیبانی Incident', 'کاهش ریسک'],
finalCtaTitle: 'زیرساخت حیاتی‌تان را مطمئن کنید',
finalCtaDesc: 'برای انتخاب پلن مناسب با ما صحبت کنید.',
finalCtaButton: 'درخواست اختصاصی مدیریت‌شده',
},
en: {
seoTitle: 'Managed Dedicated',
title: 'Managed Dedicated',
accent: 'secure & stable',
heroBadge: 'Ops handled by us',
subtitle:
'Managed bare metal — for mission-critical services that require stability and SLAs.',
breadcrumbs: ['Home', 'Servers', 'Managed Dedicated'],
heroPrimaryCta: 'Request',
heroSecondaryCta: 'View plans',
heroHighlights: [
{ label: 'Monitoring & maintenance', icon: 'support' },
{ label: 'Enterprise security', icon: 'shield' },
{ label: 'High performance', icon: 'speed' },
{ label: 'SLA options', icon: 'support' },
],
quickStats: [
{ label: 'SLA', value: '99.99%', icon: 'uptime' },
{ label: 'Support', value: '24/7', icon: 'support' },
{ label: 'Security', value: 'Hardening', icon: 'security' },
{ label: 'Performance', value: 'Bare metal', icon: 'nvme' },
],
featuresTitle: 'Managed dedicated features',
featuresSubtitle: 'For critical workloads',
features: [
{ title: '24/7 monitoring', desc: 'Deep monitoring for services and resources.', icon: 'bolt' },
{ title: 'Security', desc: 'Hardening and security policies.', icon: 'shield' },
{ title: 'Maintenance', desc: 'Patch and update management.', icon: 'cloud' },
{ title: 'Backups & DR', desc: 'Backup and recovery runbooks.', icon: 'cloud' },
{ title: 'Optimization', desc: 'Performance tuning for your stack.', icon: 'rocket' },
{ title: 'Expert support', desc: 'Help during incidents.', icon: 'headphones' },
],
plansTitle: 'Managed dedicated plans',
plansSubtitle: 'Suggested (customizable)',
plans: [
{ name: 'Standard', price: 'Quote', period: '', features: ['Monitoring', 'Security', 'Updates'], cta: 'Request' },
{ name: 'SLA+', price: 'Quote', period: '', badge: 'Recommended', featured: true, features: ['SLA', 'Priority support', 'Backups/DR'], cta: 'Request' },
{ name: 'Enterprise', price: 'Quote', period: '', features: ['Dedicated ops', 'Runbooks', 'Custom network'], cta: 'Contact' },
],
faqTitle: 'FAQ',
faqSubtitle: 'Managed dedicated questions',
faqs: [
{ q: 'What is included?', a: 'Monitoring, security, updates, backups, and incident handling.' },
{ q: 'Can it be customized?', a: 'Yes, tailored to your workload requirements.' },
{ q: 'Who is it for?', a: 'Mission-critical services, finance, big databases, and high traffic.' },
{ q: 'Do you offer SLAs?', a: 'Yes, SLAs are available depending on plan.' },
],
whyTitle: 'Why managed dedicated?',
whyText: 'For services where downtime is not an option.',
whyBullets: ['SLA options', '24/7 monitoring', 'Enterprise security', 'Incident support', 'Lower risk'],
finalCtaTitle: 'Harden your critical stack',
finalCtaDesc: 'Talk to us and choose the right plan.',
finalCtaButton: 'Request Managed Dedicated',
},
},
storage: {
fa: {
seoTitle: 'فضای ذخیره‌سازی',
title: 'فضای ذخیره‌سازی',
accent: 'مطمئن',
heroBadge: 'Storage برای بکاپ و فایل‌ها',
subtitle:
'فضای ذخیره‌سازی سریع و پایدار برای بکاپ، فایل‌ها و داده‌های پروژه‌های شما.',
breadcrumbs: ['صفحه اصلی', 'سایر محصولات', 'فضای ذخیره‌سازی'],
heroPrimaryCta: 'ثبت سفارش',
heroSecondaryCta: 'مشاهده پلن‌ها',
heroHighlights: [
{ label: 'دسترسی ساده', icon: 'speed' },
{ label: 'امنیت داده', icon: 'shield' },
{ label: 'پایداری بالا', icon: 'support' },
{ label: 'پشتیبانی', icon: 'support' },
],
quickStats: [
{ label: 'آپتایم', value: '۹۹.۹۹٪', icon: 'uptime' },
{ label: 'پشتیبانی', value: '۲۴/۷', icon: 'support' },
{ label: 'نوع', value: 'Object/File', icon: 'nvme' },
{ label: 'امنیت', value: 'ACL', icon: 'security' },
],
featuresTitle: 'ویژگی‌های Storage',
featuresSubtitle: 'برای داده‌ها و بکاپ‌ها',
features: [
{ title: 'پایداری', desc: 'مناسب بکاپ‌های منظم و داده‌های مهم.', icon: 'shield' },
{ title: 'دسترسی', desc: 'دسترسی با کلید/کاربری و سیاست‌های دسترسی.', icon: 'cloud' },
{ title: 'مقیاس‌پذیری', desc: 'افزایش فضا با رشد پروژه.', icon: 'rocket' },
{ title: 'سازگاری', desc: 'قابل استفاده برای سناریوهای مختلف.', icon: 'wp' },
{ title: 'سرعت', desc: 'عملکرد مناسب برای استفاده روزمره.', icon: 'bolt' },
{ title: 'پشتیبانی', desc: 'راهنمایی برای اتصال و کانفیگ.', icon: 'headphones' },
],
plansTitle: 'پلن‌های Storage',
plansSubtitle: 'برای بکاپ تا آرشیو',
plans: [
{ name: '50GB', price: '۱۹۹,۰۰۰', period: 'تومان / ماهانه', features: ['۵۰ گیگ', 'دسترسی امن', 'پشتیبانی'], cta: 'سفارش' },
{ name: '200GB', price: '۵۹۹,۰۰۰', period: 'تومان / ماهانه', badge: 'پیشنهادی', featured: true, features: ['۲۰۰ گیگ', 'ACL', 'پشتیبانی'], cta: 'سفارش' },
{ name: '1TB', price: '۲,۴۹۹,۰۰۰', period: 'تومان / ماهانه', features: ['۱ ترابایت', 'مقیاس‌پذیر', 'پشتیبانی'], cta: 'سفارش' },
],
faqTitle: 'سوالات متداول',
faqSubtitle: 'پرسش‌های رایج درباره Storage',
faqs: [
{ q: 'برای بکاپ مناسب است؟', a: 'بله، یکی از کاربردهای اصلی Storage بکاپ است.' },
{ q: 'می‌توانم فضا را افزایش دهم؟', a: 'بله، ارتقا فضا ممکن است.' },
{ q: 'چطور به آن وصل می‌شوم؟', a: 'با کلیدها/اطلاعات دسترسی و ابزارهای استاندارد.' },
{ q: 'امنیت دسترسی چگونه است؟', a: 'با سیاست‌های دسترسی و کنترل سطح دسترسی (ACL).' },
],
whyTitle: 'چرا Storage MugCloud؟',
whyText: 'برای داده‌های مهم، پایداری و امنیت حیاتی است.',
whyBullets: ['پایداری بالا', 'امنیت دسترسی', 'مقیاس‌پذیر', 'سرعت مناسب', 'پشتیبانی'],
finalCtaTitle: 'فضای ذخیره‌سازی خود را فعال کنید',
finalCtaDesc: 'پلن مناسب داده‌های خود را انتخاب کنید.',
finalCtaButton: 'ثبت سفارش Storage',
},
en: {
seoTitle: 'Storage',
title: 'Storage',
accent: 'reliable',
heroBadge: 'Storage for files & backups',
subtitle:
'Fast and stable storage for backups, files, and project data.',
breadcrumbs: ['Home', 'Other products', 'Storage'],
heroPrimaryCta: 'Order now',
heroSecondaryCta: 'View plans',
heroHighlights: [
{ label: 'Simple access', icon: 'speed' },
{ label: 'Data security', icon: 'shield' },
{ label: 'High durability', icon: 'support' },
{ label: 'Support', icon: 'support' },
],
quickStats: [
{ label: 'Uptime', value: '99.99%', icon: 'uptime' },
{ label: 'Support', value: '24/7', icon: 'support' },
{ label: 'Type', value: 'Object/File', icon: 'nvme' },
{ label: 'Security', value: 'ACL', icon: 'security' },
],
featuresTitle: 'Storage features',
featuresSubtitle: 'For backups and archives',
features: [
{ title: 'Durability', desc: 'Great for frequent backups and important data.', icon: 'shield' },
{ title: 'Access control', desc: 'Policies and controlled access.', icon: 'cloud' },
{ title: 'Scalability', desc: 'Scale as you grow.', icon: 'rocket' },
{ title: 'Compatibility', desc: 'Fits many workflows.', icon: 'wp' },
{ title: 'Performance', desc: 'Good for day-to-day use.', icon: 'bolt' },
{ title: 'Support', desc: 'Help with setup and connection.', icon: 'headphones' },
],
plansTitle: 'Storage plans',
plansSubtitle: 'Backup to archive',
plans: [
{ name: '50GB', price: '199,000', period: 'Toman / month', features: ['50GB', 'Secure access', 'Support'], cta: 'Order' },
{ name: '200GB', price: '599,000', period: 'Toman / month', badge: 'Recommended', featured: true, features: ['200GB', 'ACL', 'Support'], cta: 'Order' },
{ name: '1TB', price: '2,499,000', period: 'Toman / month', features: ['1TB', 'Scalable', 'Support'], cta: 'Order' },
],
faqTitle: 'FAQ',
faqSubtitle: 'Storage questions',
faqs: [
{ q: 'Is it good for backups?', a: 'Yes, backups are a primary use case.' },
{ q: 'Can I increase capacity?', a: 'Yes, you can upgrade anytime.' },
{ q: 'How do I connect?', a: 'Using access keys and standard tools.' },
{ q: 'How is access secured?', a: 'Policies and access-control lists.' },
],
whyTitle: 'Why MugCloud Storage?',
whyText: 'Durability and access control for important data.',
whyBullets: ['High durability', 'Access security', 'Scalable', 'Good performance', 'Support'],
finalCtaTitle: 'Enable storage',
finalCtaDesc: 'Pick a plan for your data.',
finalCtaButton: 'Order Storage',
},
},
cdn: {
fa: {
seoTitle: 'CDN',
title: 'CDN',
accent: 'سریع‌تر',
heroBadge: 'شتاب‌دهی محتوا',
subtitle:
'کاهش تأخیر و افزایش سرعت لود با توزیع محتوا در لبه شبکه.',
breadcrumbs: ['صفحه اصلی', 'سایر محصولات', 'CDN'],
heroPrimaryCta: 'درخواست',
heroSecondaryCta: 'مشاهده پلن‌ها',
heroHighlights: [
{ label: 'کاهش تأخیر', icon: 'speed' },
{ label: 'امنیت بیشتر', icon: 'shield' },
{ label: 'پایداری', icon: 'support' },
{ label: 'پشتیبانی', icon: 'support' },
],
quickStats: [
{ label: 'Cache', value: 'Edge', icon: 'uptime' },
{ label: 'پشتیبانی', value: '۲۴/۷', icon: 'support' },
{ label: 'تحویل', value: 'Global', icon: 'nvme' },
{ label: 'امنیت', value: 'WAF/DDoS', icon: 'security' },
],
featuresTitle: 'ویژگی‌های CDN',
featuresSubtitle: 'برای لود سریع‌تر',
features: [
{ title: 'Edge cache', desc: 'کشینگ نزدیک کاربران برای سرعت بهتر.', icon: 'bolt' },
{ title: 'امنیت', desc: 'محافظت در برابر حملات رایج.', icon: 'shield' },
{ title: 'پایش', desc: 'مانیتورینگ و گزارش‌ها.', icon: 'cloud' },
{ title: 'راه‌اندازی سریع', desc: 'اتصال ساده به دامنه‌ها.', icon: 'rocket' },
{ title: 'بهینه‌سازی', desc: 'بهینه‌سازی تحویل محتوا.', icon: 'wp' },
{ title: 'پشتیبانی', desc: 'راهنمایی برای کانفیگ.', icon: 'headphones' },
],
plansTitle: 'پلن‌های CDN',
plansSubtitle: 'بر اساس مصرف و نیاز',
plans: [
{ name: 'Starter', price: '۱۹۹,۰۰۰', period: 'تومان / ماهانه', features: ['مصرف کم', 'پایش پایه', 'پشتیبانی'], cta: 'درخواست' },
{ name: 'Pro', price: '۵۹۹,۰۰۰', period: 'تومان / ماهانه', badge: 'پیشنهادی', featured: true, features: ['مصرف متوسط', 'امنیت بیشتر', 'پشتیبانی'], cta: 'درخواست' },
{ name: 'Enterprise', price: 'تماس', period: '', features: ['مصرف بالا', 'SLA', 'راهکار سفارشی'], cta: 'تماس' },
],
faqTitle: 'سوالات متداول',
faqSubtitle: 'پرسش‌های رایج درباره CDN',
faqs: [
{ q: 'CDN چطور سرعت را بیشتر می‌کند؟', a: 'محتوا را نزدیک کاربران کش می‌کند تا سریع‌تر تحویل شود.' },
{ q: 'برای فایل و تصویر مناسب است؟', a: 'بله، برای استاتیک‌ها بسیار کاربردی است.' },
{ q: 'آیا امنیت هم ارائه می‌دهد؟', a: 'بله، می‌تواند به امنیت و محافظت کمک کند.' },
{ q: 'راه‌اندازی سخت است؟', a: 'خیر، معمولاً با چند تنظیم ساده انجام می‌شود.' },
],
whyTitle: 'چرا CDN MugCloud؟',
whyText: 'برای تجربه سریع‌تر کاربران و فشار کمتر روی سرور.',
whyBullets: ['سرعت بهتر', 'کاهش بار سرور', 'امنیت', 'پایش', 'پشتیبانی'],
finalCtaTitle: 'سایت را سریع‌تر کنید',
finalCtaDesc: 'CDN را فعال کنید و سرعت را حس کنید.',
finalCtaButton: 'درخواست CDN',
},
en: {
seoTitle: 'CDN',
title: 'CDN',
accent: 'faster',
heroBadge: 'Content acceleration',
subtitle:
'Lower latency and faster loads by distributing content at the edge.',
breadcrumbs: ['Home', 'Other products', 'CDN'],
heroPrimaryCta: 'Request',
heroSecondaryCta: 'View plans',
heroHighlights: [
{ label: 'Lower latency', icon: 'speed' },
{ label: 'More security', icon: 'shield' },
{ label: 'Stability', icon: 'support' },
{ label: 'Support', icon: 'support' },
],
quickStats: [
{ label: 'Cache', value: 'Edge', icon: 'uptime' },
{ label: 'Support', value: '24/7', icon: 'support' },
{ label: 'Delivery', value: 'Global', icon: 'nvme' },
{ label: 'Security', value: 'WAF/DDoS', icon: 'security' },
],
featuresTitle: 'CDN features',
featuresSubtitle: 'For faster delivery',
features: [
{ title: 'Edge cache', desc: 'Cache close to users for speed.', icon: 'bolt' },
{ title: 'Security', desc: 'Protection against common attacks.', icon: 'shield' },
{ title: 'Analytics', desc: 'Monitoring and reports.', icon: 'cloud' },
{ title: 'Quick setup', desc: 'Easy domain onboarding.', icon: 'rocket' },
{ title: 'Optimization', desc: 'Better delivery performance.', icon: 'wp' },
{ title: 'Support', desc: 'Help with configuration.', icon: 'headphones' },
],
plansTitle: 'CDN plans',
plansSubtitle: 'Based on usage',
plans: [
{ name: 'Starter', price: '199,000', period: 'Toman / month', features: ['Low usage', 'Basic analytics', 'Support'], cta: 'Request' },
{ name: 'Pro', price: '599,000', period: 'Toman / month', badge: 'Recommended', featured: true, features: ['Mid usage', 'More security', 'Support'], cta: 'Request' },
{ name: 'Enterprise', price: 'Quote', period: '', features: ['High usage', 'SLA', 'Custom'], cta: 'Contact' },
],
faqTitle: 'FAQ',
faqSubtitle: 'CDN questions',
faqs: [
{ q: 'How does a CDN speed up?', a: 'By caching content closer to users for faster delivery.' },
{ q: 'Is it good for images/static?', a: 'Yes, its great for static assets.' },
{ q: 'Does it improve security?', a: 'It can help with protection and mitigation.' },
{ q: 'Is setup hard?', a: 'No, its usually a few simple settings.' },
],
whyTitle: 'Why MugCloud CDN?',
whyText: 'Better UX for users and less load on origin servers.',
whyBullets: ['Faster loads', 'Less origin load', 'Security', 'Analytics', 'Support'],
finalCtaTitle: 'Make it faster',
finalCtaDesc: 'Enable CDN and feel the speed.',
finalCtaButton: 'Request CDN',
},
},
geodns: {
fa: {
seoTitle: 'GeoDns',
title: 'GeoDns',
accent: 'هوشمند',
heroBadge: 'مسیر دهی DNS بر اساس موقعیت',
subtitle:
'هدایت کاربران به نزدیک‌ترین/بهترین مقصد با DNS هوشمند — برای سرعت و پایداری بهتر.',
breadcrumbs: ['صفحه اصلی', 'سایر محصولات', 'GeoDns'],
heroPrimaryCta: 'درخواست',
heroSecondaryCta: 'مشاهده پلن‌ها',
heroHighlights: [
{ label: 'بهبود سرعت', icon: 'speed' },
{ label: 'افزایش پایداری', icon: 'support' },
{ label: 'کنترل و گزارش', icon: 'support' },
{ label: 'امنیت', icon: 'shield' },
],
quickStats: [
{ label: 'Routing', value: 'Geo', icon: 'uptime' },
{ label: 'Policy', value: 'Rules', icon: 'support' },
{ label: 'Latency', value: 'Low', icon: 'nvme' },
{ label: 'Security', value: 'DNSSEC', icon: 'security' },
],
featuresTitle: 'ویژگی‌های GeoDns',
featuresSubtitle: 'DNS هوشمند برای زیرساخت مدرن',
features: [
{ title: 'Geo routing', desc: 'مسیردهی بر اساس کشور/منطقه.', icon: 'rocket' },
{ title: 'Failover', desc: 'سوییچ خودکار هنگام اختلال.', icon: 'shield' },
{ title: 'Policy rules', desc: 'تعریف قوانین و سناریوهای مختلف.', icon: 'cloud' },
{ title: 'Quick setup', desc: 'راه‌اندازی سریع روی دامنه‌ها.', icon: 'wp' },
{ title: 'Performance', desc: 'کاهش تأخیر و بهبود تجربه.', icon: 'bolt' },
{ title: 'Support', desc: 'راهنمایی و پشتیبانی برای تنظیمات.', icon: 'headphones' },
],
plansTitle: 'پلن‌های GeoDns',
plansSubtitle: 'بر اساس تعداد رکورد و سیاست',
plans: [
{ name: 'Starter', price: '۱۹۹,۰۰۰', period: 'تومان / ماهانه', features: ['رکورد محدود', 'قوانین پایه', 'پشتیبانی'], cta: 'درخواست' },
{ name: 'Pro', price: '۵۹۹,۰۰۰', period: 'تومان / ماهانه', badge: 'پیشنهادی', featured: true, features: ['رکورد بیشتر', 'Failover', 'گزارش'], cta: 'درخواست' },
{ name: 'Enterprise', price: 'تماس', period: '', features: ['سیاست‌های سفارشی', 'SLA', 'پشتیبانی ویژه'], cta: 'تماس' },
],
faqTitle: 'سوالات متداول',
faqSubtitle: 'پرسش‌های رایج درباره GeoDns',
faqs: [
{ q: 'GeoDns چه کاری انجام می‌دهد؟', a: 'کاربران را بر اساس موقعیت یا سیاست‌ها به مقصد مناسب هدایت می‌کند.' },
{ q: 'آیا Failover دارد؟', a: 'بله، بر اساس پلن امکان Failover وجود دارد.' },
{ q: 'برای چه سناریوهایی مناسب است؟', a: 'چند دیتاسنتر، چند region، یا نیاز به مسیردهی هوشمند.' },
{ q: 'DNSSEC دارید؟', a: 'بسته به پلن/راهکار، امکان استفاده از DNSSEC وجود دارد.' },
],
whyTitle: 'چرا GeoDns؟',
whyText: 'برای سرعت بهتر و دسترس‌پذیری بالاتر در سطح جهانی.',
whyBullets: ['کاهش تأخیر', 'Failover', 'قوانین هوشمند', 'کنترل بیشتر', 'پشتیبانی'],
finalCtaTitle: 'DNS هوشمند را فعال کنید',
finalCtaDesc: 'برای راه‌اندازی GeoDns با ما در تماس باشید.',
finalCtaButton: 'درخواست GeoDns',
},
en: {
seoTitle: 'GeoDNS',
title: 'GeoDNS',
accent: 'smart',
heroBadge: 'Location-aware DNS routing',
subtitle:
'Route users to the best destination using smart DNS — for lower latency and better availability.',
breadcrumbs: ['Home', 'Other products', 'GeoDNS'],
heroPrimaryCta: 'Request',
heroSecondaryCta: 'View plans',
heroHighlights: [
{ label: 'Speed improvement', icon: 'speed' },
{ label: 'Higher availability', icon: 'support' },
{ label: 'Control & reports', icon: 'support' },
{ label: 'Security', icon: 'shield' },
],
quickStats: [
{ label: 'Routing', value: 'Geo', icon: 'uptime' },
{ label: 'Policy', value: 'Rules', icon: 'support' },
{ label: 'Latency', value: 'Low', icon: 'nvme' },
{ label: 'Security', value: 'DNSSEC', icon: 'security' },
],
featuresTitle: 'GeoDNS features',
featuresSubtitle: 'Smart DNS for modern infra',
features: [
{ title: 'Geo routing', desc: 'Route by country/region.', icon: 'rocket' },
{ title: 'Failover', desc: 'Automatic switch during outages.', icon: 'shield' },
{ title: 'Policy rules', desc: 'Define rules for different scenarios.', icon: 'cloud' },
{ title: 'Quick setup', desc: 'Easy onboarding for domains.', icon: 'wp' },
{ title: 'Performance', desc: 'Lower latency and better UX.', icon: 'bolt' },
{ title: 'Support', desc: 'Help with configuration and best practices.', icon: 'headphones' },
],
plansTitle: 'GeoDNS plans',
plansSubtitle: 'Based on records and policies',
plans: [
{ name: 'Starter', price: '199,000', period: 'Toman / month', features: ['Limited records', 'Basic rules', 'Support'], cta: 'Request' },
{ name: 'Pro', price: '599,000', period: 'Toman / month', badge: 'Recommended', featured: true, features: ['More records', 'Failover', 'Reports'], cta: 'Request' },
{ name: 'Enterprise', price: 'Quote', period: '', features: ['Custom policies', 'SLA', 'Premium support'], cta: 'Contact' },
],
faqTitle: 'FAQ',
faqSubtitle: 'GeoDNS questions',
faqs: [
{ q: 'What does GeoDNS do?', a: 'Routes users to targets based on location and policies.' },
{ q: 'Do you support failover?', a: 'Yes, depending on the plan.' },
{ q: 'When should I use it?', a: 'Multi-region setups or when you need smart routing.' },
{ q: 'Do you support DNSSEC?', a: 'Depending on the plan/solution, DNSSEC can be enabled.' },
],
whyTitle: 'Why GeoDNS?',
whyText: 'Better latency and higher availability globally.',
whyBullets: ['Lower latency', 'Failover', 'Smart rules', 'More control', 'Support'],
finalCtaTitle: 'Enable smart DNS',
finalCtaDesc: 'Contact us to launch GeoDNS.',
finalCtaButton: 'Request GeoDNS',
},
},
}; };

View File

@@ -6,10 +6,14 @@ import {
ChevronDown, ChevronDown,
Cloud, Cloud,
Globe, Globe,
HardDrive,
Leaf, Leaf,
Mail, Mail,
Menu, Menu,
Moon, Moon,
Network,
Home,
Server,
Settings, Settings,
ShieldCheck, ShieldCheck,
Sun, Sun,
@@ -20,124 +24,193 @@ import { useTheme } from 'next-themes';
import Link from 'next/link'; import Link from 'next/link';
import { usePathname, useRouter } from 'next/navigation'; import { usePathname, useRouter } from 'next/navigation';
import { useI18n } from '../../i18n/provider'; import { useI18n } from '../../i18n/provider';
import { serviceContent, serviceSlugs, type ServiceSlug } from '../[locale]/services/[slug]/services.data';
export default function Header() { export default function Header() {
const [isScrolled, setIsScrolled] = useState(false); const [isScrolled, setIsScrolled] = useState(false);
const [mobileOpen, setMobileOpen] = useState(false); const [mobileOpen, setMobileOpen] = useState(false);
const [mobileServicesOpen, setMobileServicesOpen] = useState(false);
const [desktopActiveGroupId, setDesktopActiveGroupId] = useState<string>('');
const { locale, t } = useI18n(); const { locale, t } = useI18n();
const dir = locale === 'en' ? 'ltr' : 'rtl'; const dir = locale === 'en' ? 'ltr' : 'rtl';
const { theme, setTheme } = useTheme(); const { theme, setTheme } = useTheme();
const router = useRouter(); const router = useRouter();
const pathname = usePathname(); const pathname = usePathname();
const dropdownGroups = useMemo(() => { type NavChild = {
const labels = id: string;
locale === 'fa' label: string;
? { href: string;
hosting: 'هاست', icon: typeof Globe;
serverManagement: 'مدیریت سرور', bg: string;
domain: 'دامین', ring: string;
ssl: 'SSL',
orgEmail: 'ایمیل‌های سازمانی',
}
: {
hosting: 'Hosting',
serverManagement: 'Server Management',
domain: 'Domain',
ssl: 'SSL',
orgEmail: 'Business Email',
}; };
const itemMeta: Record< type NavItem =
ServiceSlug, | { id: string; type: 'link'; primary: string; secondary: string; href: string }
{ icon: typeof Globe; bg: string; ring: string } | { id: string; type: 'dropdown'; primary: string; secondary: string; children: NavChild[] };
> = {
'eco-hosting': { const navItems = useMemo<NavItem[]>(() => {
const isFa = locale === 'fa';
const pick = (fa: string, en: string) => (isFa ? { primary: fa, secondary: en } : { primary: en, secondary: fa });
const mkChild = (child: Omit<NavChild, 'bg' | 'ring'> & Partial<Pick<NavChild, 'bg' | 'ring'>>): NavChild => ({
bg: child.bg ?? 'from-slate-500/20 to-slate-500/10',
ring: child.ring ?? 'ring-slate-400/20',
...child,
});
return [
{ id: 'home', type: 'link', ...pick('خانه', 'Home'), href: `/${locale}` },
{
id: 'hosting',
type: 'dropdown',
...pick('میزبانی', 'Hosting'),
children: [
mkChild({
id: 'eco-hosting',
label: isFa ? 'هاست اقتصادی' : 'Budget Hosting',
href: `/${locale}/eco-hosting`,
icon: Leaf, icon: Leaf,
bg: 'from-emerald-500/25 to-teal-500/10', bg: 'from-emerald-500/25 to-teal-500/10',
ring: 'ring-emerald-400/20', ring: 'ring-emerald-400/20',
}, }),
'high-traffic-hosting': { mkChild({
id: 'high-traffic-hosting',
label: isFa ? 'هاست پربازدید' : 'High-traffic Hosting',
href: `/${locale}/high-traffic-hosting`,
icon: Zap, icon: Zap,
bg: 'from-fuchsia-500/20 to-indigo-500/10', bg: 'from-fuchsia-500/20 to-indigo-500/10',
ring: 'ring-fuchsia-400/20', ring: 'ring-fuchsia-400/20',
}, }),
'wordpress-hosting': { mkChild({
id: 'wordpress-hosting',
label: isFa ? 'هاست وردپرس' : 'WordPress Hosting',
href: `/${locale}/wordpress-hosting`,
icon: Cloud, icon: Cloud,
bg: 'from-sky-500/25 to-blue-500/10', bg: 'from-sky-500/25 to-blue-500/10',
ring: 'ring-sky-400/20', ring: 'ring-sky-400/20',
}),
mkChild({
id: 'woocommerce-hosting',
label: isFa ? 'هاست ووکامرس' : 'WooCommerce Hosting',
href: `/${locale}/woocommerce-hosting`,
icon: Cloud,
bg: 'from-rose-500/20 to-orange-500/10',
ring: 'ring-rose-400/20',
}),
],
}, },
'server-management': { {
id: 'server',
type: 'dropdown',
...pick('سرور', 'Servers'),
children: [
mkChild({
id: 'vps',
label: isFa ? 'سرور مجازی' : 'VPS',
href: `/${locale}/vps`,
icon: Server,
bg: 'from-cyan-500/20 to-sky-500/10',
ring: 'ring-cyan-400/20',
}),
mkChild({
id: 'dedicated-server',
label: isFa ? 'سرور اختصاصی' : 'Dedicated Server',
href: `/${locale}/dedicated-server`,
icon: Server,
bg: 'from-violet-500/20 to-purple-500/10',
ring: 'ring-violet-400/20',
}),
mkChild({
id: 'managed-vps',
label: isFa ? 'سرور مجازی مدیریت‌شده' : 'Managed VPS',
href: `/${locale}/managed-vps`,
icon: Settings, icon: Settings,
bg: 'from-amber-500/20 to-orange-500/10', bg: 'from-amber-500/20 to-orange-500/10',
ring: 'ring-amber-400/20', ring: 'ring-amber-400/20',
}),
mkChild({
id: 'managed-dedicated',
label: isFa ? 'سرور اختصاصی مدیریت‌شده' : 'Managed Dedicated',
href: `/${locale}/managed-dedicated`,
icon: Settings,
bg: 'from-lime-500/20 to-emerald-500/10',
ring: 'ring-lime-400/20',
}),
],
}, },
domain: { { id: 'domain', type: 'link', ...pick('دامین', 'Domain'), href: `/${locale}/domain` },
icon: Globe, {
bg: 'from-cyan-500/20 to-sky-500/10', id: 'org-email',
ring: 'ring-cyan-400/20', type: 'dropdown',
}, ...pick('ایمیل سازمانی', 'Business Email'),
ssl: { children: [
icon: ShieldCheck, mkChild({
bg: 'from-violet-500/20 to-purple-500/10', id: 'org-email-iran',
ring: 'ring-violet-400/20', label: isFa ? 'ایمیل سازمانی ایران' : 'Business Email (Iran)',
}, href: `/${locale}/org-email/iran`,
'org-email': {
icon: Mail, icon: Mail,
bg: 'from-rose-500/20 to-pink-500/10', bg: 'from-rose-500/20 to-pink-500/10',
ring: 'ring-rose-400/20', ring: 'ring-rose-400/20',
}, }),
}; mkChild({
id: 'org-email-international',
const mkItem = (slug: ServiceSlug) => ({ label: isFa ? 'ایمیل سازمانی بین‌الملل' : 'Business Email (International)',
slug, href: `/${locale}/org-email`,
title: serviceContent[slug][locale as 'fa' | 'en'].title, icon: Mail,
href: `/${locale}/${slug}`, bg: 'from-sky-500/20 to-indigo-500/10',
...itemMeta[slug], ring: 'ring-sky-400/20',
}); }),
],
const has = (slug: ServiceSlug) => serviceSlugs.includes(slug);
return [
{
id: 'hosting',
label: labels.hosting,
items: (['eco-hosting', 'high-traffic-hosting', 'wordpress-hosting'] as ServiceSlug[])
.filter(has)
.map(mkItem),
},
{
id: 'server-management',
label: labels.serverManagement,
items: (['server-management'] as ServiceSlug[]).filter(has).map(mkItem),
},
{
id: 'domain',
label: labels.domain,
items: (['domain'] as ServiceSlug[]).filter(has).map(mkItem),
}, },
{ {
id: 'other-products',
type: 'dropdown',
...pick('سایر محصولات', 'Other Products'),
children: [
mkChild({
id: 'ssl', id: 'ssl',
label: labels.ssl, label: 'SSL',
items: (['ssl'] as ServiceSlug[]).filter(has).map(mkItem), href: `/${locale}/ssl`,
icon: ShieldCheck,
bg: 'from-violet-500/20 to-purple-500/10',
ring: 'ring-violet-400/20',
}),
mkChild({
id: 'storage',
label: isFa ? 'فضای ذخیره‌سازی' : 'Storage',
href: `/${locale}/storage`,
icon: HardDrive,
bg: 'from-slate-500/25 to-zinc-500/10',
ring: 'ring-slate-400/20',
}),
mkChild({
id: 'cdn',
label: 'CDN',
href: `/${locale}/cdn`,
icon: Network,
bg: 'from-cyan-500/20 to-blue-500/10',
ring: 'ring-cyan-400/20',
}),
mkChild({
id: 'geodns',
label: 'GeoDns',
href: `/${locale}/geodns`,
icon: Globe,
bg: 'from-emerald-500/20 to-teal-500/10',
ring: 'ring-emerald-400/20',
}),
],
}, },
{ ];
id: 'org-email',
label: labels.orgEmail,
items: (['org-email'] as ServiceSlug[]).filter(has).map(mkItem),
},
].filter((g) => g.items.length > 0);
}, [locale]); }, [locale]);
const [mobileSections, setMobileSections] = useState<Record<string, boolean>>({});
useEffect(() => { useEffect(() => {
setDesktopActiveGroupId((prev) => { const initial: Record<string, boolean> = {};
if (dropdownGroups.some((g) => g.id === prev)) return prev; for (const item of navItems) {
return dropdownGroups[0]?.id ?? ''; if (item.type === 'dropdown') initial[item.id] = false;
}); }
}, [dropdownGroups]); setMobileSections((prev) => (Object.keys(prev).length ? prev : initial));
}, [navItems]);
useEffect(() => { useEffect(() => {
const handleScroll = () => { const handleScroll = () => {
@@ -155,7 +228,11 @@ export default function Header() {
useEffect(() => { useEffect(() => {
setMobileOpen(false); setMobileOpen(false);
setMobileServicesOpen(false); setMobileSections((prev) => {
const next: Record<string, boolean> = { ...prev };
for (const key of Object.keys(next)) next[key] = false;
return next;
});
}, [pathname]); }, [pathname]);
return ( return (
@@ -182,75 +259,65 @@ export default function Header() {
{/* منوی دسکتاپ */} {/* منوی دسکتاپ */}
<nav className={`hidden md:flex items-center transition-all duration-500 ${isScrolled ? 'gap-6' : 'gap-10'}`}> <nav className={`hidden md:flex items-center transition-all duration-500 ${isScrolled ? 'gap-6' : 'gap-10'}`}>
<div className="relative group"> {navItems.map((item) => {
<a if (item.type === 'link') {
href="#" return (
<Link
key={item.id}
href={item.href}
className="inline-flex items-center gap-1.5 text-[color:var(--text-muted)] hover:text-[color:var(--text-primary)] transition-colors text-sm font-medium" className="inline-flex items-center gap-1.5 text-[color:var(--text-muted)] hover:text-[color:var(--text-primary)] transition-colors text-sm font-medium"
> >
<span>{t('nav_products')}</span> {item.id === 'home' ? <Home className="w-4 h-4 opacity-80" /> : null}
<span className="flex flex-col leading-tight">
<span>{item.primary}</span>
<span className="text-[11px] font-semibold tracking-wide text-[color:var(--text-muted-3)]">
{item.secondary}
</span>
</span>
</Link>
);
}
return (
<div key={item.id} className="relative group">
<button
type="button"
className="inline-flex items-center gap-1.5 text-[color:var(--text-muted)] hover:text-[color:var(--text-primary)] transition-colors text-sm font-medium"
>
<span className="flex flex-col leading-tight text-start">
<span>{item.primary}</span>
<span className="text-[11px] font-semibold tracking-wide text-[color:var(--text-muted-3)]">
{item.secondary}
</span>
</span>
<ChevronDown className="w-4 h-4 text-[color:var(--text-muted-3)] transition-transform duration-200 group-hover:rotate-180" /> <ChevronDown className="w-4 h-4 text-[color:var(--text-muted-3)] transition-transform duration-200 group-hover:rotate-180" />
</a> </button>
<div className="absolute top-full pt-3 right-0 left-auto hidden group-hover:block"> <div className="absolute top-full pt-3 right-0 left-auto hidden group-hover:block">
<div className="min-w-[34rem] rounded-3xl bg-[color:var(--glass-08)] backdrop-blur-xl border border-[color:var(--border-10)] shadow-[0_20px_80px_rgba(0,0,0,0.35)] overflow-hidden"> <div className="glass-rotating-border min-w-[19.5rem] rounded-3xl border border-[color:var(--border-10)] bg-[color:var(--global-surface-bg-80)] backdrop-blur-2xl shadow-[0_20px_90px_rgba(0,0,0,0.42)] overflow-hidden">
<div className="p-3 grid grid-cols-[1.55fr_0.85fr] gap-3" dir="ltr"> <div className="relative p-2.5">
{/* ستون چپ: آیتم‌های دسته انتخاب‌شده */} <div className="pointer-events-none absolute inset-0 bg-gradient-to-br from-white/10 via-[color:var(--global-surface-bg-80)] to-blue-500/10 opacity-80" />
<div className="rounded-3xl text-right bg-[color:var(--glass-05)] border border-[color:var(--border-10)] overflow-hidden"> {item.children.map((child) => (
<div className="p-2.5">
{(dropdownGroups.find((g) => g.id === desktopActiveGroupId) ?? dropdownGroups[0])?.items.map(
(item) => (
<Link <Link
key={item.slug} key={child.id}
href={item.href} href={child.href}
className="group/item flex items-center gap-3 px-3 py-2 rounded-2xl text-sm text-[color:var(--text-muted)] hover:text-[color:var(--text-primary)] hover:bg-[color:var(--glass-10)] transition-colors" className="relative group/item flex items-center gap-3 px-3 py-2.5 rounded-2xl text-sm text-[color:var(--text-muted)] hover:text-[color:var(--text-primary)] hover:bg-[color:var(--glass-10)] transition-colors"
> >
<span className="flex-1">{item.title}</span>
<span <span
className={`w-9 h-9 rounded-2xl bg-gradient-to-br ${item.bg} ring-1 ${item.ring} border border-[color:var(--border-10)] flex items-center justify-center`} className={`w-9 h-9 rounded-2xl bg-gradient-to-br ${child.bg} ring-1 ${child.ring} border border-[color:var(--border-10)] flex items-center justify-center`}
> >
<item.icon className="w-4 h-4 text-[color:var(--text-primary)] opacity-90" /> <child.icon className="w-4 h-4 text-[color:var(--text-primary)] opacity-90" />
</span> </span>
<span className="flex-1">{child.label}</span>
<span className="w-1.5 h-1.5 rounded-full bg-blue-500/0 group-hover/item:bg-blue-400/70 transition-colors" /> <span className="w-1.5 h-1.5 rounded-full bg-blue-500/0 group-hover/item:bg-blue-400/70 transition-colors" />
</Link> </Link>
), ))}
)} </div>
</div>
</div> </div>
</div> </div>
{/* ستون راست: تیتر دسته‌ها */}
<div className="col-start-2 rounded-3xl bg-[color:var(--glass-05)] border border-[color:var(--border-10)] overflow-hidden">
<div className="p-2.5">
{dropdownGroups.map((group) => {
const isActive = group.id === desktopActiveGroupId;
return (
<button
key={group.id}
type="button"
onMouseEnter={() => setDesktopActiveGroupId(group.id)}
className={`w-full px-3 py-2.5 rounded-2xl text-sm font-semibold transition-colors ${
isActive
? 'text-[color:var(--text-primary)] bg-[color:var(--glass-10)]'
: 'text-[color:var(--text-muted)] hover:text-[color:var(--text-primary)] hover:bg-[color:var(--glass-10)]'
}`}
>
<span className={locale === 'fa' ? 'block text-right' : 'block text-left'}>
{group.label}
</span>
</button>
); );
})} })}
</div>
</div>
</div>
</div>
</div>
</div>
<a href="#" className="text-[color:var(--text-muted)] hover:text-[color:var(--text-primary)] transition-colors text-sm font-medium">{t('nav_pricing')}</a>
<a href="#" className="text-[color:var(--text-muted)] hover:text-[color:var(--text-primary)] transition-colors text-sm font-medium">{t('nav_network')}</a>
<a href="#" className="text-[color:var(--text-muted)] hover:text-[color:var(--text-primary)] transition-colors text-sm font-medium">{t('nav_support')}</a>
</nav> </nav>
{/* بخش اکشن‌ها */} {/* بخش اکشن‌ها */}
@@ -300,9 +367,9 @@ export default function Header() {
</button> </button>
{/* دکمه شروع کنید */} {/* دکمه شروع کنید */}
<button className="px-5 py-2 rounded-full bg-blue-600 hover:bg-blue-500 text-white text-sm font-semibold transition-all hover:shadow-[0_0_15px_rgba(37,99,235,0.5)]"> {/* <button className="px-5 py-2 rounded-full bg-blue-600 hover:bg-blue-500 text-white text-sm font-semibold transition-all hover:shadow-[0_0_15px_rgba(37,99,235,0.5)]">
{t('nav_start')} {t('nav_start')}
</button> </button> */}
</div> </div>
</motion.header> </motion.header>
@@ -313,49 +380,67 @@ export default function Header() {
dir={dir} dir={dir}
> >
<div className="p-3 flex flex-col gap-2"> <div className="p-3 flex flex-col gap-2">
{navItems.map((item) => {
if (item.type === 'link') {
return (
<Link
key={item.id}
href={item.href}
className="px-3 py-2 rounded-xl text-sm font-medium text-[color:var(--text-muted)] hover:text-[color:var(--text-primary)] hover:bg-[color:var(--glass-10)] transition-colors"
>
<span className="flex flex-col leading-tight">
<span>{item.primary}</span>
<span className="text-[11px] font-semibold tracking-wide text-[color:var(--text-muted-3)]">
{item.secondary}
</span>
</span>
</Link>
);
}
const isOpen = Boolean(mobileSections[item.id]);
return (
<div key={item.id} className="rounded-xl overflow-hidden border border-[color:var(--border-10)] bg-[color:var(--glass-02)]">
<button <button
type="button" type="button"
onClick={() => setMobileServicesOpen((v) => !v)} onClick={() => setMobileSections((prev) => ({ ...prev, [item.id]: !Boolean(prev[item.id]) }))}
className="w-full flex items-center justify-between px-3 py-2 rounded-xl text-sm font-medium text-[color:var(--text-muted)] hover:text-[color:var(--text-primary)] hover:bg-[color:var(--glass-10)] transition-colors" className="w-full flex items-center justify-between px-3 py-2 text-sm font-medium text-[color:var(--text-muted)] hover:text-[color:var(--text-primary)] hover:bg-[color:var(--glass-10)] transition-colors"
aria-expanded={mobileServicesOpen} aria-expanded={isOpen}
> >
<span>{t('nav_products')}</span> <span className="flex flex-col leading-tight text-start">
<span>{item.primary}</span>
<span className="text-[11px] font-semibold tracking-wide text-[color:var(--text-muted-3)]">
{item.secondary}
</span>
</span>
<ChevronDown <ChevronDown
className={`w-4 h-4 text-[color:var(--text-muted-3)] transition-transform ${mobileServicesOpen ? 'rotate-180' : ''}`} className={`w-4 h-4 text-[color:var(--text-muted-3)] transition-transform ${isOpen ? 'rotate-180' : ''}`}
/> />
</button> </button>
{mobileServicesOpen ? ( {isOpen ? (
<div className="pl-2 pr-2 pb-2"> <div className="px-2 pb-2">
{dropdownGroups.map((group) => (
<div key={group.id} className="px-1 py-2">
<div className="text-[11px] font-semibold tracking-wide text-[color:var(--text-muted-3)] mb-2 px-2">
{group.label}
</div>
<div className="grid grid-cols-1 gap-1"> <div className="grid grid-cols-1 gap-1">
{group.items.map((item) => ( {item.children.map((child) => (
<Link <Link
key={item.slug} key={child.id}
href={item.href} href={child.href}
className="flex items-center gap-3 px-3 py-2 rounded-2xl text-sm text-[color:var(--text-muted)] hover:text-[color:var(--text-primary)] hover:bg-[color:var(--glass-10)] transition-colors" className="flex items-center gap-3 px-3 py-2 rounded-2xl text-sm text-[color:var(--text-muted)] hover:text-[color:var(--text-primary)] hover:bg-[color:var(--glass-10)] transition-colors"
> >
<span <span
className={`w-9 h-9 rounded-2xl bg-gradient-to-br ${item.bg} ring-1 ${item.ring} border border-[color:var(--border-10)] flex items-center justify-center`} className={`w-9 h-9 rounded-2xl bg-gradient-to-br ${child.bg} ring-1 ${child.ring} border border-[color:var(--border-10)] flex items-center justify-center`}
> >
<item.icon className="w-4 h-4 text-[color:var(--text-primary)] opacity-90" /> <child.icon className="w-4 h-4 text-[color:var(--text-primary)] opacity-90" />
</span> </span>
<span className="flex-1">{item.title}</span> <span className="flex-1">{child.label}</span>
</Link> </Link>
))} ))}
</div> </div>
</div> </div>
))}
</div>
) : null} ) : null}
</div>
<a href="#" className="px-3 py-2 rounded-xl text-sm font-medium text-[color:var(--text-muted)] hover:text-[color:var(--text-primary)] hover:bg-[color:var(--glass-10)] transition-colors">{t('nav_pricing')}</a> );
<a href="#" className="px-3 py-2 rounded-xl text-sm font-medium text-[color:var(--text-muted)] hover:text-[color:var(--text-primary)] hover:bg-[color:var(--glass-10)] transition-colors">{t('nav_network')}</a> })}
<a href="#" className="px-3 py-2 rounded-xl text-sm font-medium text-[color:var(--text-muted)] hover:text-[color:var(--text-primary)] hover:bg-[color:var(--glass-10)] transition-colors">{t('nav_support')}</a>
</div> </div>
</div> </div>
) : null} ) : null}