menu and services
This commit is contained in:
683
package-lock.json
generated
683
package-lock.json
generated
@@ -8,19 +8,25 @@
|
||||
"name": "mugit3",
|
||||
"version": "0.1.0",
|
||||
"dependencies": {
|
||||
"@react-three/drei": "^10.7.7",
|
||||
"@react-three/fiber": "^9.6.1",
|
||||
"@react-three/postprocessing": "^3.0.4",
|
||||
"framer-motion": "^12.38.0",
|
||||
"lucide-react": "^1.14.0",
|
||||
"motion": "^12.0.6",
|
||||
"next": "16.2.5",
|
||||
"next-themes": "^0.4.6",
|
||||
"postprocessing": "^6.39.1",
|
||||
"react": "19.2.4",
|
||||
"react-dom": "19.2.4"
|
||||
"react-dom": "19.2.4",
|
||||
"three": "^0.184.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@tailwindcss/postcss": "^4",
|
||||
"@types/node": "^20",
|
||||
"@types/react": "^19",
|
||||
"@types/react-dom": "^19",
|
||||
"@types/three": "^0.184.1",
|
||||
"babel-plugin-react-compiler": "1.0.0",
|
||||
"tailwindcss": "^4",
|
||||
"typescript": "^5"
|
||||
@@ -56,6 +62,14 @@
|
||||
"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": {
|
||||
"version": "7.29.0",
|
||||
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.0.tgz",
|
||||
@@ -69,6 +83,11 @@
|
||||
"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": {
|
||||
"version": "1.10.0",
|
||||
"resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.10.0.tgz",
|
||||
@@ -564,6 +583,22 @@
|
||||
"@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": {
|
||||
"version": "16.2.5",
|
||||
"resolved": "https://registry.npmjs.org/@next/env/-/env-16.2.5.tgz",
|
||||
@@ -689,6 +724,116 @@
|
||||
"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": {
|
||||
"version": "0.5.15",
|
||||
"resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.15.tgz",
|
||||
@@ -953,6 +1098,16 @@
|
||||
"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": {
|
||||
"version": "20.19.39",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.19.39.tgz",
|
||||
@@ -962,11 +1117,15 @@
|
||||
"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": {
|
||||
"version": "19.2.14",
|
||||
"resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.14.tgz",
|
||||
"integrity": "sha512-ilcTH/UniCkMdtexkoCN0bI7pMcJDvmQFPvuPvmEaYA/NSfFTAgdUSLAoVjaRJm7+6PvcM+q1zYOwS4wTYMF9w==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"csstype": "^3.2.2"
|
||||
}
|
||||
@@ -980,6 +1139,53 @@
|
||||
"@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": {
|
||||
"version": "1.0.0",
|
||||
"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"
|
||||
}
|
||||
},
|
||||
"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": {
|
||||
"version": "2.10.27",
|
||||
"resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.10.27.tgz",
|
||||
@@ -1000,6 +1225,49 @@
|
||||
"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": {
|
||||
"version": "1.0.30001792",
|
||||
"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",
|
||||
"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": {
|
||||
"version": "3.2.3",
|
||||
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz",
|
||||
"integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==",
|
||||
"dev": true
|
||||
"integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ=="
|
||||
},
|
||||
"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": {
|
||||
"version": "2.1.2",
|
||||
@@ -1039,6 +1344,11 @@
|
||||
"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": {
|
||||
"version": "5.21.0",
|
||||
"resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.21.0.tgz",
|
||||
@@ -1052,6 +1362,11 @@
|
||||
"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": {
|
||||
"version": "12.38.0",
|
||||
"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": {
|
||||
"version": "4.2.11",
|
||||
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz",
|
||||
"integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==",
|
||||
"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": {
|
||||
"version": "2.7.0",
|
||||
"resolved": "https://registry.npmjs.org/jiti/-/jiti-2.7.0.tgz",
|
||||
@@ -1093,6 +1463,14 @@
|
||||
"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": {
|
||||
"version": "1.32.0",
|
||||
"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"
|
||||
}
|
||||
},
|
||||
"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": {
|
||||
"version": "0.30.21",
|
||||
"resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz",
|
||||
@@ -1359,6 +1746,19 @@
|
||||
"@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": {
|
||||
"version": "12.38.0",
|
||||
"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",
|
||||
"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": {
|
||||
"version": "3.3.12",
|
||||
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.12.tgz",
|
||||
@@ -1502,6 +1911,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": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
|
||||
@@ -1535,6 +1952,28 @@
|
||||
"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": {
|
||||
"version": "19.2.4",
|
||||
"resolved": "https://registry.npmjs.org/react/-/react-19.2.4.tgz",
|
||||
@@ -1554,6 +1993,28 @@
|
||||
"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": {
|
||||
"version": "0.27.0",
|
||||
"resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.27.0.tgz",
|
||||
@@ -1615,6 +2076,25 @@
|
||||
"@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": {
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz",
|
||||
@@ -1623,6 +2103,29 @@
|
||||
"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": {
|
||||
"version": "5.1.6",
|
||||
"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": {
|
||||
"version": "4.2.4",
|
||||
"resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.2.4.tgz",
|
||||
@@ -1664,11 +2175,107 @@
|
||||
"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": {
|
||||
"version": "2.8.1",
|
||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
|
||||
"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": {
|
||||
"version": "5.9.3",
|
||||
"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",
|
||||
"integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==",
|
||||
"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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,19 +8,25 @@
|
||||
"start": "next start"
|
||||
},
|
||||
"dependencies": {
|
||||
"@react-three/drei": "^10.7.7",
|
||||
"@react-three/fiber": "^9.6.1",
|
||||
"@react-three/postprocessing": "^3.0.4",
|
||||
"framer-motion": "^12.38.0",
|
||||
"lucide-react": "^1.14.0",
|
||||
"motion": "^12.0.6",
|
||||
"next": "16.2.5",
|
||||
"next-themes": "^0.4.6",
|
||||
"postprocessing": "^6.39.1",
|
||||
"react": "19.2.4",
|
||||
"react-dom": "19.2.4"
|
||||
"react-dom": "19.2.4",
|
||||
"three": "^0.184.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@tailwindcss/postcss": "^4",
|
||||
"@types/node": "^20",
|
||||
"@types/react": "^19",
|
||||
"@types/react-dom": "^19",
|
||||
"@types/three": "^0.184.1",
|
||||
"babel-plugin-react-compiler": "1.0.0",
|
||||
"tailwindcss": "^4",
|
||||
"typescript": "^5"
|
||||
|
||||
BIN
public/images/domain-globe.png
Normal file
BIN
public/images/domain-globe.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.5 MiB |
@@ -10,8 +10,11 @@ import {
|
||||
} from '../services/[slug]/services.data';
|
||||
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() {
|
||||
return serviceSlugs.flatMap((slug) => [{ slug }]);
|
||||
return servicePageSlugs.flatMap((slug) => [{ slug }]);
|
||||
}
|
||||
|
||||
export async function generateMetadata({
|
||||
@@ -21,7 +24,7 @@ export async function generateMetadata({
|
||||
}): Promise<Metadata> {
|
||||
const { locale, slug } = await params;
|
||||
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 };
|
||||
}
|
||||
|
||||
@@ -32,7 +35,7 @@ export default async function ServicePage({
|
||||
}) {
|
||||
const { locale, slug } = await params;
|
||||
if (!isLocale(locale)) notFound();
|
||||
if (!serviceSlugs.includes(slug as ServiceSlug)) notFound();
|
||||
if (!servicePageSlugs.includes(slug as ServiceSlug)) notFound();
|
||||
|
||||
return (
|
||||
<main className="min-h-screen font-sans">
|
||||
@@ -42,4 +45,3 @@ export default async function ServicePage({
|
||||
</main>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
274
src/app/[locale]/domain/page.tsx
Normal file
274
src/app/[locale]/domain/page.tsx
Normal 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 — it’s 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>
|
||||
);
|
||||
}
|
||||
85
src/app/[locale]/org-email/iran/page.tsx
Normal file
85
src/app/[locale]/org-email/iran/page.tsx
Normal 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>
|
||||
);
|
||||
}
|
||||
|
||||
86
src/app/[locale]/org-email/page.tsx
Normal file
86
src/app/[locale]/org-email/page.tsx
Normal 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>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -4,6 +4,14 @@ export type ServiceSlug =
|
||||
| 'eco-hosting'
|
||||
| 'high-traffic-hosting'
|
||||
| 'wordpress-hosting'
|
||||
| 'woocommerce-hosting'
|
||||
| 'vps'
|
||||
| 'dedicated-server'
|
||||
| 'managed-vps'
|
||||
| 'managed-dedicated'
|
||||
| 'storage'
|
||||
| 'cdn'
|
||||
| 'geodns'
|
||||
| 'server-management'
|
||||
| 'domain'
|
||||
| 'ssl'
|
||||
@@ -13,6 +21,14 @@ export const serviceSlugs: ServiceSlug[] = [
|
||||
'eco-hosting',
|
||||
'high-traffic-hosting',
|
||||
'wordpress-hosting',
|
||||
'woocommerce-hosting',
|
||||
'vps',
|
||||
'dedicated-server',
|
||||
'managed-vps',
|
||||
'managed-dedicated',
|
||||
'storage',
|
||||
'cdn',
|
||||
'geodns',
|
||||
'server-management',
|
||||
'domain',
|
||||
'ssl',
|
||||
@@ -858,4 +874,904 @@ export const serviceContent: Record<ServiceSlug, Record<Locale, ServiceContent>>
|
||||
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 — that’s 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, it’s great for static assets.' },
|
||||
{ q: 'Does it improve security?', a: 'It can help with protection and mitigation.' },
|
||||
{ q: 'Is setup hard?', a: 'No, it’s 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',
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
@@ -6,10 +6,14 @@ import {
|
||||
ChevronDown,
|
||||
Cloud,
|
||||
Globe,
|
||||
HardDrive,
|
||||
Leaf,
|
||||
Mail,
|
||||
Menu,
|
||||
Moon,
|
||||
Network,
|
||||
Home,
|
||||
Server,
|
||||
Settings,
|
||||
ShieldCheck,
|
||||
Sun,
|
||||
@@ -20,124 +24,193 @@ import { useTheme } from 'next-themes';
|
||||
import Link from 'next/link';
|
||||
import { usePathname, useRouter } from 'next/navigation';
|
||||
import { useI18n } from '../../i18n/provider';
|
||||
import { serviceContent, serviceSlugs, type ServiceSlug } from '../[locale]/services/[slug]/services.data';
|
||||
|
||||
export default function Header() {
|
||||
const [isScrolled, setIsScrolled] = useState(false);
|
||||
const [mobileOpen, setMobileOpen] = useState(false);
|
||||
const [mobileServicesOpen, setMobileServicesOpen] = useState(false);
|
||||
const [desktopActiveGroupId, setDesktopActiveGroupId] = useState<string>('');
|
||||
const { locale, t } = useI18n();
|
||||
const dir = locale === 'en' ? 'ltr' : 'rtl';
|
||||
const { theme, setTheme } = useTheme();
|
||||
const router = useRouter();
|
||||
const pathname = usePathname();
|
||||
|
||||
const dropdownGroups = useMemo(() => {
|
||||
const labels =
|
||||
locale === 'fa'
|
||||
? {
|
||||
hosting: 'هاست',
|
||||
serverManagement: 'مدیریت سرور',
|
||||
domain: 'دامین',
|
||||
ssl: 'SSL',
|
||||
orgEmail: 'ایمیلهای سازمانی',
|
||||
}
|
||||
: {
|
||||
hosting: 'Hosting',
|
||||
serverManagement: 'Server Management',
|
||||
domain: 'Domain',
|
||||
ssl: 'SSL',
|
||||
orgEmail: 'Business Email',
|
||||
};
|
||||
type NavChild = {
|
||||
id: string;
|
||||
label: string;
|
||||
href: string;
|
||||
icon: typeof Globe;
|
||||
bg: string;
|
||||
ring: string;
|
||||
};
|
||||
|
||||
const itemMeta: Record<
|
||||
ServiceSlug,
|
||||
{ icon: typeof Globe; bg: string; ring: string }
|
||||
> = {
|
||||
'eco-hosting': {
|
||||
icon: Leaf,
|
||||
bg: 'from-emerald-500/25 to-teal-500/10',
|
||||
ring: 'ring-emerald-400/20',
|
||||
},
|
||||
'high-traffic-hosting': {
|
||||
icon: Zap,
|
||||
bg: 'from-fuchsia-500/20 to-indigo-500/10',
|
||||
ring: 'ring-fuchsia-400/20',
|
||||
},
|
||||
'wordpress-hosting': {
|
||||
icon: Cloud,
|
||||
bg: 'from-sky-500/25 to-blue-500/10',
|
||||
ring: 'ring-sky-400/20',
|
||||
},
|
||||
'server-management': {
|
||||
icon: Settings,
|
||||
bg: 'from-amber-500/20 to-orange-500/10',
|
||||
ring: 'ring-amber-400/20',
|
||||
},
|
||||
domain: {
|
||||
icon: Globe,
|
||||
bg: 'from-cyan-500/20 to-sky-500/10',
|
||||
ring: 'ring-cyan-400/20',
|
||||
},
|
||||
ssl: {
|
||||
icon: ShieldCheck,
|
||||
bg: 'from-violet-500/20 to-purple-500/10',
|
||||
ring: 'ring-violet-400/20',
|
||||
},
|
||||
'org-email': {
|
||||
icon: Mail,
|
||||
bg: 'from-rose-500/20 to-pink-500/10',
|
||||
ring: 'ring-rose-400/20',
|
||||
},
|
||||
};
|
||||
type NavItem =
|
||||
| { id: string; type: 'link'; primary: string; secondary: string; href: string }
|
||||
| { id: string; type: 'dropdown'; primary: string; secondary: string; children: NavChild[] };
|
||||
|
||||
const mkItem = (slug: ServiceSlug) => ({
|
||||
slug,
|
||||
title: serviceContent[slug][locale as 'fa' | 'en'].title,
|
||||
href: `/${locale}/${slug}`,
|
||||
...itemMeta[slug],
|
||||
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,
|
||||
});
|
||||
|
||||
const has = (slug: ServiceSlug) => serviceSlugs.includes(slug);
|
||||
|
||||
return [
|
||||
{ id: 'home', type: 'link', ...pick('خانه', 'Home'), href: `/${locale}` },
|
||||
{
|
||||
id: 'hosting',
|
||||
label: labels.hosting,
|
||||
items: (['eco-hosting', 'high-traffic-hosting', 'wordpress-hosting'] as ServiceSlug[])
|
||||
.filter(has)
|
||||
.map(mkItem),
|
||||
type: 'dropdown',
|
||||
...pick('میزبانی', 'Hosting'),
|
||||
children: [
|
||||
mkChild({
|
||||
id: 'eco-hosting',
|
||||
label: isFa ? 'هاست اقتصادی' : 'Budget Hosting',
|
||||
href: `/${locale}/eco-hosting`,
|
||||
icon: Leaf,
|
||||
bg: 'from-emerald-500/25 to-teal-500/10',
|
||||
ring: 'ring-emerald-400/20',
|
||||
}),
|
||||
mkChild({
|
||||
id: 'high-traffic-hosting',
|
||||
label: isFa ? 'هاست پربازدید' : 'High-traffic Hosting',
|
||||
href: `/${locale}/high-traffic-hosting`,
|
||||
icon: Zap,
|
||||
bg: 'from-fuchsia-500/20 to-indigo-500/10',
|
||||
ring: 'ring-fuchsia-400/20',
|
||||
}),
|
||||
mkChild({
|
||||
id: 'wordpress-hosting',
|
||||
label: isFa ? 'هاست وردپرس' : 'WordPress Hosting',
|
||||
href: `/${locale}/wordpress-hosting`,
|
||||
icon: Cloud,
|
||||
bg: 'from-sky-500/25 to-blue-500/10',
|
||||
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',
|
||||
}),
|
||||
],
|
||||
},
|
||||
{
|
||||
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: 'ssl',
|
||||
label: labels.ssl,
|
||||
items: (['ssl'] as ServiceSlug[]).filter(has).map(mkItem),
|
||||
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,
|
||||
bg: 'from-amber-500/20 to-orange-500/10',
|
||||
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',
|
||||
}),
|
||||
],
|
||||
},
|
||||
{ id: 'domain', type: 'link', ...pick('دامین', 'Domain'), href: `/${locale}/domain` },
|
||||
{
|
||||
id: 'org-email',
|
||||
label: labels.orgEmail,
|
||||
items: (['org-email'] as ServiceSlug[]).filter(has).map(mkItem),
|
||||
type: 'dropdown',
|
||||
...pick('ایمیل سازمانی', 'Business Email'),
|
||||
children: [
|
||||
mkChild({
|
||||
id: 'org-email-iran',
|
||||
label: isFa ? 'ایمیل سازمانی ایران' : 'Business Email (Iran)',
|
||||
href: `/${locale}/org-email/iran`,
|
||||
icon: Mail,
|
||||
bg: 'from-rose-500/20 to-pink-500/10',
|
||||
ring: 'ring-rose-400/20',
|
||||
}),
|
||||
mkChild({
|
||||
id: 'org-email-international',
|
||||
label: isFa ? 'ایمیل سازمانی بینالملل' : 'Business Email (International)',
|
||||
href: `/${locale}/org-email`,
|
||||
icon: Mail,
|
||||
bg: 'from-sky-500/20 to-indigo-500/10',
|
||||
ring: 'ring-sky-400/20',
|
||||
}),
|
||||
],
|
||||
},
|
||||
].filter((g) => g.items.length > 0);
|
||||
{
|
||||
id: 'other-products',
|
||||
type: 'dropdown',
|
||||
...pick('سایر محصولات', 'Other Products'),
|
||||
children: [
|
||||
mkChild({
|
||||
id: 'ssl',
|
||||
label: 'SSL',
|
||||
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',
|
||||
}),
|
||||
],
|
||||
},
|
||||
];
|
||||
}, [locale]);
|
||||
|
||||
const [mobileSections, setMobileSections] = useState<Record<string, boolean>>({});
|
||||
useEffect(() => {
|
||||
setDesktopActiveGroupId((prev) => {
|
||||
if (dropdownGroups.some((g) => g.id === prev)) return prev;
|
||||
return dropdownGroups[0]?.id ?? '';
|
||||
});
|
||||
}, [dropdownGroups]);
|
||||
const initial: Record<string, boolean> = {};
|
||||
for (const item of navItems) {
|
||||
if (item.type === 'dropdown') initial[item.id] = false;
|
||||
}
|
||||
setMobileSections((prev) => (Object.keys(prev).length ? prev : initial));
|
||||
}, [navItems]);
|
||||
|
||||
useEffect(() => {
|
||||
const handleScroll = () => {
|
||||
@@ -155,7 +228,11 @@ export default function Header() {
|
||||
|
||||
useEffect(() => {
|
||||
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]);
|
||||
|
||||
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'}`}>
|
||||
<div className="relative group">
|
||||
<a
|
||||
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"
|
||||
>
|
||||
<span>{t('nav_products')}</span>
|
||||
<ChevronDown className="w-4 h-4 text-[color:var(--text-muted-3)] transition-transform duration-200 group-hover:rotate-180" />
|
||||
</a>
|
||||
{navItems.map((item) => {
|
||||
if (item.type === 'link') {
|
||||
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"
|
||||
>
|
||||
{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>
|
||||
);
|
||||
}
|
||||
|
||||
<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="p-3 grid grid-cols-[1.55fr_0.85fr] gap-3" dir="ltr">
|
||||
{/* ستون چپ: آیتمهای دسته انتخابشده */}
|
||||
<div className="rounded-3xl text-right bg-[color:var(--glass-05)] border border-[color:var(--border-10)] overflow-hidden">
|
||||
<div className="p-2.5">
|
||||
{(dropdownGroups.find((g) => g.id === desktopActiveGroupId) ?? dropdownGroups[0])?.items.map(
|
||||
(item) => (
|
||||
<Link
|
||||
key={item.slug}
|
||||
href={item.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"
|
||||
>
|
||||
<span className="flex-1">{item.title}</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`}
|
||||
>
|
||||
<item.icon className="w-4 h-4 text-[color:var(--text-primary)] opacity-90" />
|
||||
</span>
|
||||
<span className="w-1.5 h-1.5 rounded-full bg-blue-500/0 group-hover/item:bg-blue-400/70 transition-colors" />
|
||||
</Link>
|
||||
),
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
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" />
|
||||
</button>
|
||||
|
||||
{/* ستون راست: تیتر دستهها */}
|
||||
<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)]'
|
||||
}`}
|
||||
<div className="absolute top-full pt-3 right-0 left-auto hidden group-hover:block">
|
||||
<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="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" />
|
||||
{item.children.map((child) => (
|
||||
<Link
|
||||
key={child.id}
|
||||
href={child.href}
|
||||
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={`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`}
|
||||
>
|
||||
<span className={locale === 'fa' ? 'block text-right' : 'block text-left'}>
|
||||
{group.label}
|
||||
</span>
|
||||
</button>
|
||||
);
|
||||
})}
|
||||
<child.icon className="w-4 h-4 text-[color:var(--text-primary)] opacity-90" />
|
||||
</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" />
|
||||
</Link>
|
||||
))}
|
||||
</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>
|
||||
|
||||
{/* بخش اکشنها */}
|
||||
@@ -300,9 +367,9 @@ export default function Header() {
|
||||
</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')}
|
||||
</button>
|
||||
</button> */}
|
||||
</div>
|
||||
</motion.header>
|
||||
|
||||
@@ -313,49 +380,67 @@ export default function Header() {
|
||||
dir={dir}
|
||||
>
|
||||
<div className="p-3 flex flex-col gap-2">
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => setMobileServicesOpen((v) => !v)}
|
||||
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"
|
||||
aria-expanded={mobileServicesOpen}
|
||||
>
|
||||
<span>{t('nav_products')}</span>
|
||||
<ChevronDown
|
||||
className={`w-4 h-4 text-[color:var(--text-muted-3)] transition-transform ${mobileServicesOpen ? 'rotate-180' : ''}`}
|
||||
/>
|
||||
</button>
|
||||
{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>
|
||||
);
|
||||
}
|
||||
|
||||
{mobileServicesOpen ? (
|
||||
<div className="pl-2 pr-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">
|
||||
{group.items.map((item) => (
|
||||
<Link
|
||||
key={item.slug}
|
||||
href={item.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"
|
||||
>
|
||||
<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`}
|
||||
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
|
||||
type="button"
|
||||
onClick={() => setMobileSections((prev) => ({ ...prev, [item.id]: !Boolean(prev[item.id]) }))}
|
||||
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={isOpen}
|
||||
>
|
||||
<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 ${isOpen ? 'rotate-180' : ''}`}
|
||||
/>
|
||||
</button>
|
||||
|
||||
{isOpen ? (
|
||||
<div className="px-2 pb-2">
|
||||
<div className="grid grid-cols-1 gap-1">
|
||||
{item.children.map((child) => (
|
||||
<Link
|
||||
key={child.id}
|
||||
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"
|
||||
>
|
||||
<item.icon className="w-4 h-4 text-[color:var(--text-primary)] opacity-90" />
|
||||
</span>
|
||||
<span className="flex-1">{item.title}</span>
|
||||
</Link>
|
||||
))}
|
||||
<span
|
||||
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`}
|
||||
>
|
||||
<child.icon className="w-4 h-4 text-[color:var(--text-primary)] opacity-90" />
|
||||
</span>
|
||||
<span className="flex-1">{child.label}</span>
|
||||
</Link>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
) : null}
|
||||
|
||||
<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>
|
||||
) : null}
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
) : null}
|
||||
|
||||
Reference in New Issue
Block a user