feat: complete website redesign, security hardening, auth routing to web.houshan.ai, and enterprise banner update

This commit is contained in:
alireza 2026-08-25 08:37:28 +03:30
parent 90c5598524
commit 3f07971f35
127 changed files with 5355 additions and 1923 deletions

5
.env
View File

@ -1,5 +0,0 @@
# Houshan AI Platform Environment Configuration
VITE_APP_TITLE="هوشان | دستیار هوش مصنوعی شما"
VITE_APP_DESCRIPTION="پلتفرم جامع هوش مصنوعی فارسی برای مدیران، کسب‌وکارها و متخصصان"
VITE_API_BASE_URL="https://api.houshan.ai"
VITE_WEB_APP_URL="https://web.houshan.ai"

12
.gitignore vendored
View File

@ -11,6 +11,18 @@ node_modules
dist dist
dist-ssr dist-ssr
# Environment variables and secrets
.env
.env.local
.env.*.local
*.pem
*.key
# Scratch and internal utility scripts with credentials
scratch/
Dockerfile.wordpress
docker-compose.wordpress.yml
# Large binary user storage and media files (to prevent git 413 payload limit on Gitea) # Large binary user storage and media files (to prevent git 413 payload limit on Gitea)
public/storage/user/ public/storage/user/
public/storage/apk/*.apk public/storage/apk/*.apk

View File

@ -1,9 +1,10 @@
<!doctype html> <!doctype html>
<html lang="fa" dir="rtl" class="dark"> <html lang="fa" dir="rtl">
<head> <head>
<meta charset="UTF-8" /> <meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%236366F1'><path d='M12 2L2 7l10 5 10-5-10-5zM2 17l10 5 10-5M2 12l10 5 10-5'/></svg>" /> <link rel="icon" type="image/svg+xml" href="data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23193b74'><path d='M12 2L2 7l10 5 10-5-10-5zM2 17l10 5 10-5M2 12l10 5 10-5'/></svg>" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="referrer" content="strict-origin-when-cross-origin" />
<!-- Primary Meta Tags --> <!-- Primary Meta Tags -->
<title>هوشان | دستیار هوش مصنوعی شما - دستیار هوش مصنوعی مدیران</title> <title>هوشان | دستیار هوش مصنوعی شما - دستیار هوش مصنوعی مدیران</title>
@ -21,7 +22,7 @@
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Plus+Jakarta+Sans:wght@400;500;600;700;800&family=Vazirmatn:wght@300;400;500;600;700;800;900&display=swap" rel="stylesheet"> <link href="https://fonts.googleapis.com/css2?family=Plus+Jakarta+Sans:wght@400;500;600;700;800&family=Vazirmatn:wght@300;400;500;600;700;800;900&display=swap" rel="stylesheet">
</head> </head>
<body class="bg-slate-950 text-slate-100 font-vazir antialiased selection:bg-indigo-500/30 selection:text-indigo-200"> <body class="bg-white text-slate-800 font-vazir antialiased selection:bg-sky-500/20 selection:text-[#272757]">
<div id="root"></div> <div id="root"></div>
<script type="module" src="/src/main.tsx"></script> <script type="module" src="/src/main.tsx"></script>
</body> </body>

514
package-lock.json generated
View File

@ -16,6 +16,7 @@
"tailwind-merge": "^3.6.0" "tailwind-merge": "^3.6.0"
}, },
"devDependencies": { "devDependencies": {
"@aws-sdk/client-s3": "^3.1116.0",
"@tailwindcss/vite": "^4.3.3", "@tailwindcss/vite": "^4.3.3",
"@types/node": "^24.13.3", "@types/node": "^24.13.3",
"@types/react": "^19.2.17", "@types/react": "^19.2.17",
@ -24,11 +25,338 @@
"autoprefixer": "^10.5.4", "autoprefixer": "^10.5.4",
"oxlint": "^1.75.0", "oxlint": "^1.75.0",
"postcss": "^8.5.26", "postcss": "^8.5.26",
"ssh2": "^1.17.0",
"tailwindcss": "^4.3.3", "tailwindcss": "^4.3.3",
"typescript": "~6.0.2", "typescript": "~6.0.2",
"vite": "^8.2.0" "vite": "^8.2.0"
} }
}, },
"node_modules/@aws-sdk/checksums": {
"version": "3.1000.29",
"resolved": "https://registry.npmjs.org/@aws-sdk/checksums/-/checksums-3.1000.29.tgz",
"integrity": "sha512-Dtu0gr4dnATZAPwEYbpCsG+MpLM7OAliy2gTepEFQwl1vZ6DL3QMH2FveMa3HLvPsOdhJsPRB3KtxVhph9T75A==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
"@aws-sdk/core": "^3.977.9",
"@aws-sdk/types": "^3.974.5",
"@smithy/core": "^3.33.3",
"@smithy/types": "^4.17.2",
"tslib": "^2.6.2"
},
"engines": {
"node": ">=20.0.0"
}
},
"node_modules/@aws-sdk/client-s3": {
"version": "3.1116.0",
"resolved": "https://registry.npmjs.org/@aws-sdk/client-s3/-/client-s3-3.1116.0.tgz",
"integrity": "sha512-UKRl9qSVW0rZpvSOauQNpYAy8+ONBAVYnpfKVtCyOF+FZVT1tl6MunYuHvuarCrroD2/YJs+tHTALYNgAlec3Q==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
"@aws-sdk/checksums": "^3.1000.29",
"@aws-sdk/core": "^3.977.9",
"@aws-sdk/credential-provider-node": "^3.972.81",
"@aws-sdk/middleware-sdk-s3": "^3.972.75",
"@aws-sdk/signature-v4-multi-region": "^3.996.46",
"@aws-sdk/types": "^3.974.5",
"@smithy/core": "^3.33.3",
"@smithy/fetch-http-handler": "^5.7.2",
"@smithy/node-http-handler": "^4.11.3",
"@smithy/types": "^4.17.2",
"tslib": "^2.6.2"
},
"engines": {
"node": ">=20.0.0"
}
},
"node_modules/@aws-sdk/core": {
"version": "3.977.9",
"resolved": "https://registry.npmjs.org/@aws-sdk/core/-/core-3.977.9.tgz",
"integrity": "sha512-reqPFEQrZxDZpeGj4PFMepBeR5LGYHRqq/L0motTzgFkCRBA4rFdaVXDSLYyGHhxVz7sT2PDnPN9CluGSfgyJA==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
"@aws-sdk/types": "^3.974.5",
"@aws-sdk/xml-builder": "^3.972.40",
"@aws/lambda-invoke-store": "^0.3.0",
"@smithy/core": "^3.33.3",
"@smithy/signature-v4": "^5.6.12",
"@smithy/types": "^4.17.2",
"bowser": "^2.11.0",
"tslib": "^2.6.2"
},
"engines": {
"node": ">=20.0.0"
}
},
"node_modules/@aws-sdk/credential-provider-env": {
"version": "3.972.70",
"resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-env/-/credential-provider-env-3.972.70.tgz",
"integrity": "sha512-H404B7dJl2mCrBqahDEYsanB0xhdDp6tXnXcTUnXmmpy2Q3J0Ho0bUajZ2jr/RdwzCyS59Gi8xXIFwPLGBl6Uw==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
"@aws-sdk/core": "^3.977.9",
"@aws-sdk/types": "^3.974.5",
"@smithy/core": "^3.33.3",
"@smithy/types": "^4.17.2",
"tslib": "^2.6.2"
},
"engines": {
"node": ">=20.0.0"
}
},
"node_modules/@aws-sdk/credential-provider-http": {
"version": "3.972.72",
"resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-http/-/credential-provider-http-3.972.72.tgz",
"integrity": "sha512-X98zYOrVOeuosCX+6ktf29FC2N2GHPLia7qv6mzPzTc+RPAuHWCDS++Z6JK7eGYqb/v6uaW7bAXaOvDBfol+0w==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
"@aws-sdk/core": "^3.977.9",
"@aws-sdk/types": "^3.974.5",
"@smithy/core": "^3.33.3",
"@smithy/fetch-http-handler": "^5.7.2",
"@smithy/node-http-handler": "^4.11.3",
"@smithy/types": "^4.17.2",
"tslib": "^2.6.2"
},
"engines": {
"node": ">=20.0.0"
}
},
"node_modules/@aws-sdk/credential-provider-ini": {
"version": "3.973.15",
"resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.973.15.tgz",
"integrity": "sha512-Rykg6s5ceBuynMOGWgoowO4N+27JfnqXAnVaSunZl0hOO1XodSrxGNz6sCEbnmS0lAfQZDKyb3fbr46gSuv6Sg==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
"@aws-sdk/core": "^3.977.9",
"@aws-sdk/credential-provider-env": "^3.972.70",
"@aws-sdk/credential-provider-http": "^3.972.72",
"@aws-sdk/credential-provider-login": "^3.972.77",
"@aws-sdk/credential-provider-process": "^3.972.70",
"@aws-sdk/credential-provider-sso": "^3.973.14",
"@aws-sdk/credential-provider-web-identity": "^3.972.76",
"@aws-sdk/nested-clients": "^3.997.44",
"@aws-sdk/types": "^3.974.5",
"@smithy/core": "^3.33.3",
"@smithy/credential-provider-imds": "^4.4.16",
"@smithy/types": "^4.17.2",
"tslib": "^2.6.2"
},
"engines": {
"node": ">=20.0.0"
}
},
"node_modules/@aws-sdk/credential-provider-login": {
"version": "3.972.77",
"resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-login/-/credential-provider-login-3.972.77.tgz",
"integrity": "sha512-Jb59xfEISoN5mmbnA+HYqdtrSX3CgCtJoof+V5D8/TgUI56W63GEEd5Y58WijU3Ou6+WEgaLD1feVzaRXV5IDQ==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
"@aws-sdk/core": "^3.977.9",
"@aws-sdk/nested-clients": "^3.997.44",
"@aws-sdk/types": "^3.974.5",
"@smithy/core": "^3.33.3",
"@smithy/types": "^4.17.2",
"tslib": "^2.6.2"
},
"engines": {
"node": ">=20.0.0"
}
},
"node_modules/@aws-sdk/credential-provider-node": {
"version": "3.972.81",
"resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.972.81.tgz",
"integrity": "sha512-Rml+WitoFvXmv6JZ18U/xGdGDGGvB/mOin0ya0lTnTrdC0Z1lrVxTYh7iNklZBcvcRMrs4DoEf6xy1KWyrLQQw==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
"@aws-sdk/credential-provider-env": "^3.972.70",
"@aws-sdk/credential-provider-http": "^3.972.72",
"@aws-sdk/credential-provider-ini": "^3.973.15",
"@aws-sdk/credential-provider-process": "^3.972.70",
"@aws-sdk/credential-provider-sso": "^3.973.14",
"@aws-sdk/credential-provider-web-identity": "^3.972.76",
"@aws-sdk/types": "^3.974.5",
"@smithy/core": "^3.33.3",
"@smithy/credential-provider-imds": "^4.4.16",
"@smithy/types": "^4.17.2",
"tslib": "^2.6.2"
},
"engines": {
"node": ">=20.0.0"
}
},
"node_modules/@aws-sdk/credential-provider-process": {
"version": "3.972.70",
"resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-process/-/credential-provider-process-3.972.70.tgz",
"integrity": "sha512-2ry03fGRJr4sV3jI+ocjj5JqALnFD6ymM5KiNCDZMvq8bX2GSbE0vji4aM43TVCl2nXqqLRZaUxdq/KeWRAY4Q==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
"@aws-sdk/core": "^3.977.9",
"@aws-sdk/types": "^3.974.5",
"@smithy/core": "^3.33.3",
"@smithy/types": "^4.17.2",
"tslib": "^2.6.2"
},
"engines": {
"node": ">=20.0.0"
}
},
"node_modules/@aws-sdk/credential-provider-sso": {
"version": "3.973.14",
"resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.973.14.tgz",
"integrity": "sha512-jkhg/8ocAAoc0RFyLMhCw+/zZh7gystQgd4F4hznNa8P4Cc501PQmxd+jGLiMHodPJ+7Zv/3znM62gZojyasmA==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
"@aws-sdk/core": "^3.977.9",
"@aws-sdk/nested-clients": "^3.997.44",
"@aws-sdk/token-providers": "3.1116.0",
"@aws-sdk/types": "^3.974.5",
"@smithy/core": "^3.33.3",
"@smithy/types": "^4.17.2",
"tslib": "^2.6.2"
},
"engines": {
"node": ">=20.0.0"
}
},
"node_modules/@aws-sdk/credential-provider-web-identity": {
"version": "3.972.76",
"resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.972.76.tgz",
"integrity": "sha512-d3AGyVu759PGr35mEB2s22xxlNEA5rpdxtSPJthfPFJvoQ8dt357iVPECqWfUxXp1toJAvKmbtcIYVGigaGsCA==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
"@aws-sdk/core": "^3.977.9",
"@aws-sdk/nested-clients": "^3.997.44",
"@aws-sdk/types": "^3.974.5",
"@smithy/core": "^3.33.3",
"@smithy/types": "^4.17.2",
"tslib": "^2.6.2"
},
"engines": {
"node": ">=20.0.0"
}
},
"node_modules/@aws-sdk/middleware-sdk-s3": {
"version": "3.972.75",
"resolved": "https://registry.npmjs.org/@aws-sdk/middleware-sdk-s3/-/middleware-sdk-s3-3.972.75.tgz",
"integrity": "sha512-wMIsNumRVKaNMKhvU/s9VrdEwE8S6gSzXp4RygFG5BEMnGkkXf8cjh8zf7cKJBpUDpqTWqwbz5isEgp9rH6Lng==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
"@aws-sdk/core": "^3.977.9",
"@aws-sdk/signature-v4-multi-region": "^3.996.46",
"@aws-sdk/types": "^3.974.5",
"@smithy/core": "^3.33.3",
"@smithy/types": "^4.17.2",
"tslib": "^2.6.2"
},
"engines": {
"node": ">=20.0.0"
}
},
"node_modules/@aws-sdk/nested-clients": {
"version": "3.997.44",
"resolved": "https://registry.npmjs.org/@aws-sdk/nested-clients/-/nested-clients-3.997.44.tgz",
"integrity": "sha512-NhEgryjlBF9w38ZXqGymQV28IhkYa1mKhlbYnqIis57AYwWGVYfUPgg/qC2rLRqOUfblxx++irvju10kVTa8Vw==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
"@aws-sdk/core": "^3.977.9",
"@aws-sdk/signature-v4-multi-region": "^3.996.46",
"@aws-sdk/types": "^3.974.5",
"@smithy/core": "^3.33.3",
"@smithy/fetch-http-handler": "^5.7.2",
"@smithy/node-http-handler": "^4.11.3",
"@smithy/types": "^4.17.2",
"tslib": "^2.6.2"
},
"engines": {
"node": ">=20.0.0"
}
},
"node_modules/@aws-sdk/signature-v4-multi-region": {
"version": "3.996.46",
"resolved": "https://registry.npmjs.org/@aws-sdk/signature-v4-multi-region/-/signature-v4-multi-region-3.996.46.tgz",
"integrity": "sha512-L+2xZTye/2T96f3lwCws0Zw6GG2JHZW9e8FpVgGBeeExSKyeoZ6CWRpBml/7DNiK/O26jrgPM9F+Ay8VkgzUWQ==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
"@aws-sdk/types": "^3.974.5",
"@smithy/signature-v4": "^5.6.12",
"@smithy/types": "^4.17.2",
"tslib": "^2.6.2"
},
"engines": {
"node": ">=20.0.0"
}
},
"node_modules/@aws-sdk/token-providers": {
"version": "3.1116.0",
"resolved": "https://registry.npmjs.org/@aws-sdk/token-providers/-/token-providers-3.1116.0.tgz",
"integrity": "sha512-ygIivKqh8aHzNkucOCXHyIBgBpLPfrSI0mCqXF+vLBsPTUKqj0VSqAY0GFPe7lQl4HntjOcQ+KSyS7oUV2C54Q==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
"@aws-sdk/core": "^3.977.9",
"@aws-sdk/nested-clients": "^3.997.44",
"@aws-sdk/types": "^3.974.5",
"@smithy/core": "^3.33.3",
"@smithy/types": "^4.17.2",
"tslib": "^2.6.2"
},
"engines": {
"node": ">=20.0.0"
}
},
"node_modules/@aws-sdk/types": {
"version": "3.974.5",
"resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.974.5.tgz",
"integrity": "sha512-LkwLL2BLbC6wNNm4JaH9mbEqBMdOZCct6VAYqhdN4U1xrWM+fUJQEfbHwQgDypapOWTRtlk25akb5afM0P8CIQ==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
"@smithy/types": "^4.17.2",
"tslib": "^2.6.2"
},
"engines": {
"node": ">=20.0.0"
}
},
"node_modules/@aws-sdk/xml-builder": {
"version": "3.972.40",
"resolved": "https://registry.npmjs.org/@aws-sdk/xml-builder/-/xml-builder-3.972.40.tgz",
"integrity": "sha512-wlFmCIGUlwF4zx/kncw+bmxTQh1HeSJq4mYV/V5cZUSJadDP3kXvGW8Rn21cimj/7y9ju+47oYWXi97vF7czaA==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
"@smithy/types": "^4.17.2",
"tslib": "^2.6.2"
},
"engines": {
"node": ">=20.0.0"
}
},
"node_modules/@aws/lambda-invoke-store": {
"version": "0.3.0",
"resolved": "https://registry.npmjs.org/@aws/lambda-invoke-store/-/lambda-invoke-store-0.3.0.tgz",
"integrity": "sha512-sl4Bm6yiMNYrZKkqqDFWN0UfnWhlS8ivKxrYl+6t0gCLrqr8y3B2IqZZbFRkfaVVp7C/baApyh71P+LeE1A2sQ==",
"dev": true,
"license": "Apache-2.0",
"engines": {
"node": ">=18.0.0"
}
},
"node_modules/@jridgewell/gen-mapping": { "node_modules/@jridgewell/gen-mapping": {
"version": "0.3.13", "version": "0.3.13",
"resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz",
@ -674,6 +1002,93 @@
"dev": true, "dev": true,
"license": "MIT" "license": "MIT"
}, },
"node_modules/@smithy/core": {
"version": "3.33.3",
"resolved": "https://registry.npmjs.org/@smithy/core/-/core-3.33.3.tgz",
"integrity": "sha512-CsOeKq/9kA3y6VJHt+/+VTCtBaxJ4OTFpgrjIUhPpDIKxBci1k2bJaQASF2h/ELWrulGp+t97DZ0mevfAD8idg==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
"@smithy/types": "^4.17.2",
"tslib": "^2.6.2"
},
"engines": {
"node": ">=18.0.0"
}
},
"node_modules/@smithy/credential-provider-imds": {
"version": "4.5.2",
"resolved": "https://registry.npmjs.org/@smithy/credential-provider-imds/-/credential-provider-imds-4.5.2.tgz",
"integrity": "sha512-A9uSdn72ozbRUSit0eib0TW7nXuNPlaeM0zcGkJ+nE6tFcSDbnmtwoxbTCFBukVQcszDAyvsd7+rTduPTXpygg==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
"@smithy/core": "^3.33.2",
"@smithy/types": "^4.17.2",
"tslib": "^2.6.2"
},
"engines": {
"node": ">=18.0.0"
}
},
"node_modules/@smithy/fetch-http-handler": {
"version": "5.7.2",
"resolved": "https://registry.npmjs.org/@smithy/fetch-http-handler/-/fetch-http-handler-5.7.2.tgz",
"integrity": "sha512-nZyWTmSpJEXl6VtWVMBJve/7x12DZu6sIX1z1a+ZMaHlQQRs9Zpu6NbTe/gmxYXVRpkjxyDYpZ5gx2IM6f/Wkw==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
"@smithy/core": "^3.33.2",
"@smithy/types": "^4.17.2",
"tslib": "^2.6.2"
},
"engines": {
"node": ">=18.0.0"
}
},
"node_modules/@smithy/node-http-handler": {
"version": "4.11.3",
"resolved": "https://registry.npmjs.org/@smithy/node-http-handler/-/node-http-handler-4.11.3.tgz",
"integrity": "sha512-2jY1tSpERfPfWqyBV2pH+iGFaghVsIJszJNsT7hxtQYhVJpWDyc0LqOWI+nXOxOAHaEfZ4PXXtp1wW1TGpHhkA==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
"@smithy/core": "^3.33.3",
"@smithy/types": "^4.17.2",
"tslib": "^2.6.2"
},
"engines": {
"node": ">=18.0.0"
}
},
"node_modules/@smithy/signature-v4": {
"version": "5.7.3",
"resolved": "https://registry.npmjs.org/@smithy/signature-v4/-/signature-v4-5.7.3.tgz",
"integrity": "sha512-7ImGm+FkHRLcBaRttIAMZ6bzJZWb2cJGoYjq46F2UjycujWzrL9GEN9h4w7eQyXJYnltrUhxbbieBAIRrdqpow==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
"@smithy/core": "^3.33.3",
"@smithy/types": "^4.17.2",
"tslib": "^2.6.2"
},
"engines": {
"node": ">=18.0.0"
}
},
"node_modules/@smithy/types": {
"version": "4.17.2",
"resolved": "https://registry.npmjs.org/@smithy/types/-/types-4.17.2.tgz",
"integrity": "sha512-FOKpVZob9MPTn2znRzGrnsMHv7BOsKVw3XiP/cOyYLDVZ9qKp4nifIiSCuUU/fIj5Vu0UOAxCFr+qRAtG0NUkA==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
"tslib": "^2.6.2"
},
"engines": {
"node": ">=18.0.0"
}
},
"node_modules/@tailwindcss/node": { "node_modules/@tailwindcss/node": {
"version": "4.3.3", "version": "4.3.3",
"resolved": "https://registry.npmjs.org/@tailwindcss/node/-/node-4.3.3.tgz", "resolved": "https://registry.npmjs.org/@tailwindcss/node/-/node-4.3.3.tgz",
@ -1267,6 +1682,16 @@
} }
} }
}, },
"node_modules/asn1": {
"version": "0.2.6",
"resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz",
"integrity": "sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"safer-buffer": "~2.1.0"
}
},
"node_modules/autoprefixer": { "node_modules/autoprefixer": {
"version": "10.5.4", "version": "10.5.4",
"resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.5.4.tgz", "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.5.4.tgz",
@ -1317,6 +1742,23 @@
"node": ">=6.0.0" "node": ">=6.0.0"
} }
}, },
"node_modules/bcrypt-pbkdf": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz",
"integrity": "sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==",
"dev": true,
"license": "BSD-3-Clause",
"dependencies": {
"tweetnacl": "^0.14.3"
}
},
"node_modules/bowser": {
"version": "2.14.1",
"resolved": "https://registry.npmjs.org/bowser/-/bowser-2.14.1.tgz",
"integrity": "sha512-tzPjzCxygAKWFOJP011oxFHs57HzIhOEracIgAePE4pqB3LikALKnSzUyU4MGs9/iCEUuHlAJTjTc5M+u7YEGg==",
"dev": true,
"license": "MIT"
},
"node_modules/browserslist": { "node_modules/browserslist": {
"version": "4.28.8", "version": "4.28.8",
"resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.8.tgz", "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.8.tgz",
@ -1351,6 +1793,16 @@
"node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7"
} }
}, },
"node_modules/buildcheck": {
"version": "0.0.7",
"resolved": "https://registry.npmjs.org/buildcheck/-/buildcheck-0.0.7.tgz",
"integrity": "sha512-lHblz4ahamxpTmnsk+MNTRWsjYKv965MwOrSJyeD588rR3Jcu7swE+0wN5F+PbL5cjgu/9ObkhfzEPuofEMwLA==",
"dev": true,
"optional": true,
"engines": {
"node": ">=10.0.0"
}
},
"node_modules/caniuse-lite": { "node_modules/caniuse-lite": {
"version": "1.0.30001809", "version": "1.0.30001809",
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001809.tgz", "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001809.tgz",
@ -1394,6 +1846,21 @@
"url": "https://opencollective.com/express" "url": "https://opencollective.com/express"
} }
}, },
"node_modules/cpu-features": {
"version": "0.0.10",
"resolved": "https://registry.npmjs.org/cpu-features/-/cpu-features-0.0.10.tgz",
"integrity": "sha512-9IkYqtX3YHPCzoVg1Py+o9057a3i0fp7S530UWokCSaFVTc7CwXPRiOjRjBQQ18ZCNafx78YfnG+HALxtVmOGA==",
"dev": true,
"hasInstallScript": true,
"optional": true,
"dependencies": {
"buildcheck": "~0.0.6",
"nan": "^2.19.0"
},
"engines": {
"node": ">=10.0.0"
}
},
"node_modules/csstype": { "node_modules/csstype": {
"version": "3.2.3", "version": "3.2.3",
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz", "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz",
@ -1786,6 +2253,14 @@
"@jridgewell/sourcemap-codec": "^1.5.5" "@jridgewell/sourcemap-codec": "^1.5.5"
} }
}, },
"node_modules/nan": {
"version": "2.28.0",
"resolved": "https://registry.npmjs.org/nan/-/nan-2.28.0.tgz",
"integrity": "sha512-fTsDz99OTq2sVePhGdp4qQhggZFtKr64ZNVyVajRKtMOkJxYekplBh577PiJB12v/D3s2E5cGtOI45LWp6rnLQ==",
"dev": true,
"license": "MIT",
"optional": true
},
"node_modules/nanoid": { "node_modules/nanoid": {
"version": "3.3.18", "version": "3.3.18",
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.18.tgz", "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.18.tgz",
@ -2013,6 +2488,13 @@
"@rolldown/binding-win32-x64-msvc": "1.2.5" "@rolldown/binding-win32-x64-msvc": "1.2.5"
} }
}, },
"node_modules/safer-buffer": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
"dev": true,
"license": "MIT"
},
"node_modules/scheduler": { "node_modules/scheduler": {
"version": "0.27.0", "version": "0.27.0",
"resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.27.0.tgz", "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.27.0.tgz",
@ -2035,6 +2517,24 @@
"node": ">=0.10.0" "node": ">=0.10.0"
} }
}, },
"node_modules/ssh2": {
"version": "1.17.0",
"resolved": "https://registry.npmjs.org/ssh2/-/ssh2-1.17.0.tgz",
"integrity": "sha512-wPldCk3asibAjQ/kziWQQt1Wh3PgDFpC0XpwclzKcdT1vql6KeYxf5LIt4nlFkUeR8WuphYMKqUA56X4rjbfgQ==",
"dev": true,
"hasInstallScript": true,
"dependencies": {
"asn1": "^0.2.6",
"bcrypt-pbkdf": "^1.0.2"
},
"engines": {
"node": ">=10.16.0"
},
"optionalDependencies": {
"cpu-features": "~0.0.10",
"nan": "^2.23.0"
}
},
"node_modules/tailwind-merge": { "node_modules/tailwind-merge": {
"version": "3.6.0", "version": "3.6.0",
"resolved": "https://registry.npmjs.org/tailwind-merge/-/tailwind-merge-3.6.0.tgz", "resolved": "https://registry.npmjs.org/tailwind-merge/-/tailwind-merge-3.6.0.tgz",
@ -2083,6 +2583,20 @@
"url": "https://github.com/sponsors/SuperchupuDev" "url": "https://github.com/sponsors/SuperchupuDev"
} }
}, },
"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==",
"dev": true,
"license": "0BSD"
},
"node_modules/tweetnacl": {
"version": "0.14.5",
"resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz",
"integrity": "sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==",
"dev": true,
"license": "Unlicense"
},
"node_modules/typescript": { "node_modules/typescript": {
"version": "6.0.3", "version": "6.0.3",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-6.0.3.tgz", "resolved": "https://registry.npmjs.org/typescript/-/typescript-6.0.3.tgz",

View File

@ -18,6 +18,7 @@
"tailwind-merge": "^3.6.0" "tailwind-merge": "^3.6.0"
}, },
"devDependencies": { "devDependencies": {
"@aws-sdk/client-s3": "^3.1116.0",
"@tailwindcss/vite": "^4.3.3", "@tailwindcss/vite": "^4.3.3",
"@types/node": "^24.13.3", "@types/node": "^24.13.3",
"@types/react": "^19.2.17", "@types/react": "^19.2.17",
@ -26,6 +27,7 @@
"autoprefixer": "^10.5.4", "autoprefixer": "^10.5.4",
"oxlint": "^1.75.0", "oxlint": "^1.75.0",
"postcss": "^8.5.26", "postcss": "^8.5.26",
"ssh2": "^1.17.0",
"tailwindcss": "^4.3.3", "tailwindcss": "^4.3.3",
"typescript": "~6.0.2", "typescript": "~6.0.2",
"vite": "^8.2.0" "vite": "^8.2.0"

Binary file not shown.

After

Width:  |  Height:  |  Size: 590 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 583 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 594 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 534 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 514 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 514 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 564 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 507 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 590 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 564 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 570 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 516 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 212 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 355 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 376 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 354 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 73 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 139 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 216 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 274 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 57 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 84 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 384 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 54 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 125 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 60 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 64 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 746 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 54 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 128 KiB

BIN
public/storage/team/11.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

BIN
public/storage/team/12.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

BIN
public/storage/team/13.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 60 KiB

BIN
public/storage/team/21.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.5 KiB

BIN
public/storage/team/22.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

BIN
public/storage/team/4.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

BIN
public/storage/team/5.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 74 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 128 KiB

View File

@ -15,8 +15,28 @@ import { Blog } from './pages/Blog';
import { BlogPost } from './pages/BlogPost'; import { BlogPost } from './pages/BlogPost';
import { About } from './pages/About'; import { About } from './pages/About';
import { Contact } from './pages/Contact'; import { Contact } from './pages/Contact';
import { ChatPlayground } from './pages/ChatPlayground';
import { Privacy } from './pages/Privacy'; import { Privacy } from './pages/Privacy';
import { Story } from './pages/Story';
import { Team } from './pages/Team';
import { Partners } from './pages/Partners';
import { Careers } from './pages/Careers';
import { Licenses } from './pages/Licenses';
// External redirect helper component
const ExternalRedirect: React.FC<{ url: string }> = ({ url }) => {
React.useEffect(() => {
window.location.replace(url);
}, [url]);
return (
<div className="min-h-screen flex items-center justify-center bg-white text-slate-800">
<div className="text-center space-y-4">
<div className="w-12 h-12 border-4 border-[#272757] border-t-transparent rounded-full animate-spin mx-auto" />
<p className="font-bold text-sm">در حال انتقال به وباپلیکیشن هوشان (web.houshan.ai)...</p>
</div>
</div>
);
};
// Scroll to top helper component // Scroll to top helper component
const ScrollToTop: React.FC = () => { const ScrollToTop: React.FC = () => {
@ -32,27 +52,53 @@ const ScrollToTop: React.FC = () => {
export const App: React.FC = () => { export const App: React.FC = () => {
const [isAuthOpen, setIsAuthOpen] = useState(false); const [isAuthOpen, setIsAuthOpen] = useState(false);
const handleOpenAuth = () => {
window.open('https://web.houshan.ai', '_blank');
};
return ( return (
<Router> <Router>
<ScrollToTop /> <ScrollToTop />
<div className="min-h-screen bg-slate-950 text-slate-100 flex flex-col font-vazir selection:bg-indigo-500/30 selection:text-indigo-200"> <div className="min-h-screen bg-white text-slate-800 flex flex-col font-vazir selection:bg-sky-500/20 selection:text-[#272757]">
<Navbar onOpenAuth={() => setIsAuthOpen(true)} /> <Navbar onOpenAuth={handleOpenAuth} />
<main className="flex-1"> <main className="flex-1">
<Routes> <Routes>
<Route path="/" element={<Home onOpenAuth={() => setIsAuthOpen(true)} />} /> <Route path="/" element={<Home onOpenAuth={handleOpenAuth} />} />
<Route path="/tools" element={<Tools />} /> <Route path="/tools" element={<Tools onOpenAuth={handleOpenAuth} />} />
<Route path="/models" element={<Models />} /> <Route path="/models" element={<Models onOpenAuth={handleOpenAuth} />} />
<Route path="/pricing" element={<Pricing onOpenAuth={() => setIsAuthOpen(true)} />} /> <Route path="/pricing" element={<Pricing onOpenAuth={handleOpenAuth} />} />
<Route path="/enterprise" element={<Enterprise />} /> <Route path="/enterprise" element={<Enterprise />} />
<Route path="/academy" element={<Academy />} /> <Route path="/academy" element={<Academy />} />
<Route path="/blog" element={<Blog />} /> <Route path="/blog" element={<Blog />} />
<Route path="/blog/:slug" element={<BlogPost />} /> <Route path="/blog/:slug" element={<BlogPost />} />
{/* Houshan+ (هوشان +) Dropdown Routes */}
<Route path="/story" element={<Story />} />
<Route path="/about/story" element={<Story />} />
<Route path="/team" element={<Team />} />
<Route path="/about/team" element={<Team />} />
<Route path="/partners" element={<Partners />} />
<Route path="/about/partners" element={<Partners />} />
<Route path="/careers" element={<Careers />} />
<Route path="/about/careers" element={<Careers />} />
<Route path="/licenses" element={<Licenses />} />
<Route path="/about/licenses" element={<Licenses />} />
<Route path="/about" element={<About />} /> <Route path="/about" element={<About />} />
<Route path="/contact" element={<Contact />} /> <Route path="/contact" element={<Contact />} />
<Route path="/chat" element={<ChatPlayground />} />
<Route path="/privacy" element={<Privacy />} /> <Route path="/privacy" element={<Privacy />} />
<Route path="*" element={<Home onOpenAuth={() => setIsAuthOpen(true)} />} />
{/* Redirect /chat, /login, /register, /auth, /app to web.houshan.ai */}
<Route path="/chat" element={<ExternalRedirect url="https://web.houshan.ai" />} />
<Route path="/login" element={<ExternalRedirect url="https://web.houshan.ai" />} />
<Route path="/register" element={<ExternalRedirect url="https://web.houshan.ai" />} />
<Route path="/auth" element={<ExternalRedirect url="https://web.houshan.ai" />} />
<Route path="/signin" element={<ExternalRedirect url="https://web.houshan.ai" />} />
<Route path="/signup" element={<ExternalRedirect url="https://web.houshan.ai" />} />
<Route path="/app" element={<ExternalRedirect url="https://web.houshan.ai" />} />
<Route path="*" element={<Home onOpenAuth={handleOpenAuth} />} />
</Routes> </Routes>
</main> </main>

View File

@ -33,11 +33,8 @@ export const AuthModal: React.FC<AuthModalProps> = ({ isOpen, onClose }) => {
setLoading(false); setLoading(false);
setStep('success'); setStep('success');
setTimeout(() => { setTimeout(() => {
onClose(); window.location.href = 'https://web.houshan.ai';
setStep('phone'); }, 1000);
setPhoneNumber('');
setOtpCode('');
}, 1500);
}, 600); }, 600);
}; };
@ -109,7 +106,13 @@ export const AuthModal: React.FC<AuthModalProps> = ({ isOpen, onClose }) => {
)} )}
</button> </button>
<div className="pt-2 text-center"> <div className="pt-2 text-center space-y-2">
<a
href="https://web.houshan.ai"
className="text-xs text-[#54b4d3] hover:underline block font-bold"
>
انتقال مستقیم به وباپلیکیشن هوشان (web.houshan.ai)
</a>
<span className="text-[11px] text-slate-400 flex items-center justify-center gap-1"> <span className="text-[11px] text-slate-400 flex items-center justify-center gap-1">
<Shield className="w-3.5 h-3.5 text-emerald-400 inline" /> <Shield className="w-3.5 h-3.5 text-emerald-400 inline" />
ورود شما به معنای پذیرش شرایط و قوانین هوشان است. ورود شما به معنای پذیرش شرایط و قوانین هوشان است.

View File

@ -0,0 +1,226 @@
import React from 'react';
interface ModelIconProps {
provider: string;
name?: string;
className?: string;
}
export const ModelIcon: React.FC<ModelIconProps> = ({ provider, name = '', className = 'w-7 h-7' }) => {
const p = provider.toLowerCase();
const n = name.toLowerCase();
// OpenAI (GPT-4o, o1, o3-mini, GPT-4.5)
if (p.includes('openai') || n.includes('gpt') || n.includes('o1') || n.includes('o3') || n.includes('sora')) {
return (
<div className={`${className} flex items-center justify-center p-1 rounded-xl bg-slate-50 border border-slate-200 shrink-0 shadow-xs`}>
<img src="/storage/bot/llm/gpt.png" alt="OpenAI" className="w-full h-full object-contain" />
</div>
);
}
// Anthropic (Claude 3.7 Sonnet, 3.5 Sonnet, 3.5 Haiku, Opus)
if (p.includes('anthropic') || n.includes('claude')) {
return (
<div className={`${className} flex items-center justify-center p-1 rounded-xl bg-amber-50/50 border border-amber-200 shrink-0 shadow-xs`}>
<img src="/storage/bot/llm/claude.png" alt="Anthropic Claude" className="w-full h-full object-contain" />
</div>
);
}
// Google (Gemini 2.0 Flash, Gemini 2.0 Pro, Gemini 1.5 Pro, Veo)
if (p.includes('google') || n.includes('gemini') || n.includes('veo')) {
return (
<div className={`${className} flex items-center justify-center p-1 rounded-xl bg-sky-50 border border-sky-200 shrink-0 shadow-xs`}>
<img src="/storage/bot/llm/gemini.png" alt="Google Gemini" className="w-full h-full object-contain" />
</div>
);
}
// DeepSeek (R1, V3, Coder)
if (p.includes('deepseek') || n.includes('deepseek')) {
return (
<div className={`${className} flex items-center justify-center p-1 rounded-xl bg-blue-50 border border-blue-200 shrink-0 shadow-xs`}>
<img src="/storage/bot/llm/deepseek.png" alt="DeepSeek" className="w-full h-full object-contain" />
</div>
);
}
// Meta (Llama 3.3, 3.1 405B) - Official Meta Infinity Vector
if (p.includes('meta') || n.includes('llama')) {
return (
<div className={`${className} flex items-center justify-center p-1.5 rounded-xl bg-sky-50 border border-sky-200 shrink-0 shadow-xs`}>
<svg viewBox="0 0 24 24" className="w-full h-full" fill="none">
<path
d="M6.88 4C3.81 4 1.5 6.42 1.5 9.72c0 3.75 2.68 6.94 5.92 9.4 1.25.95 2.59 1.83 3.93 2.67.4.25.9.25 1.3 0 1.34-.84 2.68-1.72 3.93-2.67 3.24-2.46 5.92-5.65 5.92-9.4C22.5 6.42 20.19 4 17.12 4c-2.17 0-4.04 1.21-5.12 3.02C10.92 5.21 9.05 4 6.88 4z"
fill="url(#meta-grad)"
/>
<defs>
<linearGradient id="meta-grad" x1="1.5" y1="4" x2="22.5" y2="21.79" gradientUnits="userSpaceOnUse">
<stop stopColor="#0081FB" />
<stop offset="0.5" stopColor="#0064E0" />
<stop offset="1" stopColor="#004EC4" />
</linearGradient>
</defs>
<path
d="M16.5 7.5c1.8 0 3 1.3 3 3.2 0 2.5-2 4.9-4.8 6.9-1 .7-2 1.4-2.7 1.9-.7-.5-1.7-1.2-2.7-1.9-2.8-2-4.8-4.4-4.8-6.9 0-1.9 1.2-3.2 3-3.2 1.3 0 2.5.8 3.1 2 .2.4.6.7 1.1.7s.9-.3 1.1-.7c.6-1.2 1.8-2 3.2-2z"
fill="#ffffff"
opacity="0.3"
/>
</svg>
</div>
);
}
// Mistral AI (Mistral Large 2, Codestral, Pixtral Large) - Official Orange Pixel Staircase
if (p.includes('mistral') || n.includes('codestral') || n.includes('pixtral')) {
return (
<div className={`${className} flex items-center justify-center p-1.5 rounded-xl bg-amber-50 border border-amber-200 shrink-0 shadow-xs`}>
<svg viewBox="0 0 32 32" className="w-full h-full" fill="none">
<rect x="4" y="6" width="6" height="20" fill="#FF5722" rx="1" />
<rect x="22" y="6" width="6" height="20" fill="#FF5722" rx="1" />
<rect x="10" y="11" width="6" height="6" fill="#FF7043" rx="1" />
<rect x="16" y="11" width="6" height="6" fill="#FF8A65" rx="1" />
<rect x="13" y="17" width="6" height="6" fill="#FFAB91" rx="1" />
</svg>
</div>
);
}
// xAI Grok (Grok 3, Grok 2) - Official Slash-X
if (p.includes('xai') || n.includes('grok')) {
return (
<div className={`${className} flex items-center justify-center p-1.5 rounded-xl bg-slate-900 border border-slate-800 text-white shrink-0 shadow-xs`}>
<svg viewBox="0 0 24 24" className="w-full h-full" fill="currentColor">
<path d="M18.244 2.25h3.308l-7.227 8.26 8.502 11.24H16.17l-5.214-6.817L4.99 21.75H1.68l7.73-8.835L1.254 2.25H8.08l4.713 6.231zm-1.161 17.52h1.833L7.084 4.126H5.117z" />
</svg>
</div>
);
}
// Alibaba Qwen (Qwen 2.5 Max, Qwen 2.5 Coder) - Official Hexagonal Prism
if (p.includes('qwen') || p.includes('alibaba') || n.includes('qwen')) {
return (
<div className={`${className} flex items-center justify-center p-1.5 rounded-xl bg-indigo-50 border border-indigo-200 shrink-0 shadow-xs`}>
<svg viewBox="0 0 24 24" className="w-full h-full" fill="none">
<path
d="M12 2L3 7v10l9 5 9-5V7l-9-5z"
stroke="#6366F1"
strokeWidth="2"
strokeLinejoin="round"
/>
<path
d="M12 22V12m0 0L3 7m9 5l9-5"
stroke="#818CF8"
strokeWidth="2"
strokeLinejoin="round"
/>
<circle cx="12" cy="12" r="3" fill="#4F46E5" />
</svg>
</div>
);
}
// Moonshot AI / Kimi (Kimi k1.5, Moonshot v1) - Official Moonshot K Icon
if (p.includes('kimi') || p.includes('moonshot') || n.includes('kimi') || n.includes('moonshot')) {
return (
<div className={`${className} flex items-center justify-center p-1.5 rounded-xl bg-violet-50 border border-violet-200 text-violet-700 shrink-0 shadow-xs`}>
<svg viewBox="0 0 24 24" className="w-full h-full" fill="currentColor">
<path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-1 15h-2V7h2v4.5l3.5-4.5h2.5l-4 4.8 4.2 5.2h-2.7L11 12.8V17z" />
</svg>
</div>
);
}
// Perplexity (Sonar Deep Research) - Official Asterisk Loop
if (p.includes('perplexity') || n.includes('sonar')) {
return (
<div className={`${className} flex items-center justify-center p-1.5 rounded-xl bg-teal-50 border border-teal-200 shrink-0 shadow-xs`}>
<svg viewBox="0 0 24 24" className="w-full h-full" fill="none" stroke="#0D9488" strokeWidth="2.2" strokeLinecap="round" strokeLinejoin="round">
<line x1="12" y1="2" x2="12" y2="22" />
<line x1="2" y1="12" x2="22" y2="12" />
<line x1="4.93" y1="4.93" x2="19.07" y2="19.07" />
<line x1="19.07" y1="4.93" x2="4.93" y2="19.07" />
<circle cx="12" cy="12" r="3" fill="#14B8A6" stroke="none" />
</svg>
</div>
);
}
// Black Forest Labs (FLUX 1.1 Pro, FLUX Schnell)
if (p.includes('flux') || p.includes('black forest') || n.includes('flux')) {
return (
<div className={`${className} flex items-center justify-center p-1 rounded-xl bg-slate-50 border border-slate-200 shrink-0 shadow-xs`}>
<img src="/storage/bot/llm/flux.png" alt="Flux" className="w-full h-full object-contain" />
</div>
);
}
// Midjourney v6.1 - Official Sailboat
if (p.includes('midjourney') || n.includes('midjourney')) {
return (
<div className={`${className} flex items-center justify-center p-1.5 rounded-xl bg-slate-900 border border-slate-800 text-white shrink-0 shadow-xs`}>
<svg viewBox="0 0 24 24" className="w-full h-full" fill="none" stroke="#ffffff" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round">
<path d="M2 18c3-2 6-2 10 0 4-2 7-2 10 0" />
<path d="M12 3v13" />
<path d="M12 3c-4 4-7 8-7 12h7" />
<path d="M12 5c3 3 6 7 6 10h-6" />
</svg>
</div>
);
}
// Ideogram 2.0
if (p.includes('ideogram') || n.includes('ideogram')) {
return (
<div className={`${className} flex items-center justify-center p-1 rounded-xl bg-slate-50 border border-slate-200 shrink-0 shadow-xs`}>
<img src="/storage/bot/llm/ideogram.png" alt="Ideogram" className="w-full h-full object-contain" />
</div>
);
}
// Runway (Gen-3 Alpha) - Official Vector R
if (p.includes('runway') || n.includes('runway') || n.includes('gen-3')) {
return (
<div className={`${className} flex items-center justify-center p-1.5 rounded-xl bg-emerald-50 border border-emerald-200 text-emerald-800 shrink-0 shadow-xs`}>
<svg viewBox="0 0 24 24" className="w-full h-full" fill="currentColor">
<path d="M4 4h9a5 5 0 015 5c0 2.2-1.4 4-3.4 4.7L20 20h-4.5l-4.5-5.5H8.5V20H4V4zm4.5 7h4.2a2 2 0 000-4H8.5v4z" />
</svg>
</div>
);
}
// Suno AI (Suno v4) - Official Soundwave Vector
if (p.includes('suno') || n.includes('suno')) {
return (
<div className={`${className} flex items-center justify-center p-1.5 rounded-xl bg-rose-50 border border-rose-200 text-rose-600 shrink-0 shadow-xs`}>
<svg viewBox="0 0 24 24" className="w-full h-full" fill="currentColor">
<rect x="3" y="10" width="2.5" height="4" rx="1.2" />
<rect x="7.5" y="6" width="2.5" height="12" rx="1.2" />
<rect x="12" y="3" width="2.5" height="18" rx="1.2" />
<rect x="16.5" y="7" width="2.5" height="10" rx="1.2" />
<rect x="21" y="11" width="2.5" height="2" rx="1" />
</svg>
</div>
);
}
// ElevenLabs (Multilingual v2) - Official Dual Bars
if (p.includes('elevenlabs') || p.includes('eleven') || n.includes('elevenlabs')) {
return (
<div className={`${className} flex items-center justify-center p-1.5 rounded-xl bg-slate-900 border border-slate-800 text-white shrink-0 shadow-xs`}>
<svg viewBox="0 0 24 24" className="w-full h-full" fill="currentColor">
<rect x="7" y="4" width="3.5" height="16" rx="1.75" />
<rect x="13.5" y="4" width="3.5" height="16" rx="1.75" />
</svg>
</div>
);
}
// Default Fallback
return (
<div className={`${className} flex items-center justify-center p-1.5 rounded-xl bg-sky-50 border border-sky-200 text-[#272757] shrink-0 shadow-xs`}>
<img src="/storage/banner/owl_logo.png" alt="Houshan AI" className="w-full h-full object-contain" />
</div>
);
};

View File

@ -1,6 +1,5 @@
import React from 'react'; import React from 'react';
import { Download, Smartphone, Globe, Sparkles, ArrowLeft, CheckCircle2 } from 'lucide-react'; import { Download, Smartphone, Globe, Sparkles, CheckCircle2 } from 'lucide-react';
import siteInfo from '../../data/siteInfo.json';
interface CTASectionProps { interface CTASectionProps {
onOpenAuth?: () => void; onOpenAuth?: () => void;
@ -8,70 +7,63 @@ interface CTASectionProps {
export const CTASection: React.FC<CTASectionProps> = ({ onOpenAuth }) => { export const CTASection: React.FC<CTASectionProps> = ({ onOpenAuth }) => {
return ( return (
<section className="py-20 relative overflow-hidden bg-radial-glow border-t border-white/10"> <section className="py-20 relative overflow-hidden bg-slate-50 border-t border-slate-200 select-none">
<div className="max-w-6xl mx-auto px-4 sm:px-6 lg:px-8 relative z-10"> <div className="max-w-6xl mx-auto px-4 sm:px-6 lg:px-8 relative z-10">
<div className="glass-panel p-8 sm:p-12 rounded-3xl text-center relative overflow-hidden shadow-2xl border border-indigo-500/30"> <div className="bg-white p-8 sm:p-12 rounded-3xl text-center relative overflow-hidden shadow-sm border border-slate-200">
<div className="absolute -top-24 -left-24 w-60 h-60 bg-indigo-500/20 rounded-full blur-3xl pointer-events-none" />
<div className="absolute -bottom-24 -right-24 w-60 h-60 bg-cyan-500/20 rounded-full blur-3xl pointer-events-none" />
<div className="inline-flex items-center gap-2 px-4 py-1.5 rounded-full bg-cyan-500/10 text-cyan-300 border border-cyan-500/20 text-xs sm:text-sm font-bold mb-6"> <h2 className="text-2xl sm:text-4xl lg:text-5xl font-black text-[#272757] mb-6 font-vazir tracking-tight">
<Sparkles className="w-4 h-4" />
<span>همین حالا به جمع هزاران کاربر هوشان بپیوندید</span>
</div>
<h2 className="text-2xl sm:text-4xl lg:text-5xl font-extrabold text-white mb-6 font-vazir">
همین حالا هوشانی شو! همین حالا هوشانی شو!
</h2> </h2>
<p className="text-slate-300 text-sm sm:text-base max-w-2xl mx-auto leading-relaxed mb-10"> <p className="text-slate-700 text-sm sm:text-base max-w-2xl mx-auto leading-relaxed mb-10 font-normal">
دسترسی بدون محدودیت به دستیارهای هوشمند در موبایل، تبلت و کامپیوتر. اپلیکیشن رسمی هوشان را دریافت کنید یا مستقیماً در مرورگر شروع کنید. دسترسی بدون محدودیت به دستیارهای هوشمند در موبایل، تبلت و کامپیوتر. اپلیکیشن رسمی هوشان را دریافت کنید یا مستقیماً در مرورگر شروع کنید.
</p> </p>
{/* Download & Platform Buttons */} {/* Download & Platform Buttons */}
<div className="flex flex-wrap items-center justify-center gap-4"> <div className="flex flex-wrap items-center justify-center gap-4">
<a <a
href="https://cafebazaar.ir" href="https://cafebazaar.ir/app/com.example.hoshan"
target="_blank" target="_blank"
rel="noreferrer" rel="noreferrer"
className="btn-donya-primary px-6 py-3.5 rounded-xl font-bold flex items-center gap-2.5 text-sm sm:text-base shadow-xl" className="px-6 py-3.5 rounded-xl font-bold flex items-center gap-2.5 text-sm sm:text-base bg-[#272757] hover:bg-[#373775] text-white shadow-xs transition-all cursor-pointer"
> >
<Smartphone className="w-5 h-5 text-emerald-400" /> <Smartphone className="w-5 h-5 text-emerald-400" />
<span>دانلود از کافهبازار</span> <span>دانلود از کافهبازار</span>
</a> </a>
<a <a
href="/app-release.apk" href="/storage/app/houshan-latest.apk"
download download
className="glass-panel px-6 py-3.5 rounded-xl font-bold text-white flex items-center gap-2.5 text-sm sm:text-base hover:border-cyan-500/50 hover:bg-slate-800 transition-all" className="px-6 py-3.5 rounded-xl font-bold text-slate-800 bg-slate-100 hover:bg-slate-200 border border-slate-200 flex items-center gap-2.5 text-sm sm:text-base transition-all shadow-xs"
> >
<Download className="w-5 h-5 text-cyan-400" /> <Download className="w-5 h-5 text-[#272757]" />
<span>دانلود مستقیم فایل APK</span> <span>دانلود مستقیم فایل APK</span>
</a> </a>
<a <a
href="https://app.houshan.ai" href="https://web.houshan.ai"
target="_blank" target="_blank"
rel="noreferrer" rel="noopener noreferrer"
className="btn-donya-outline px-6 py-3.5 rounded-xl font-bold flex items-center gap-2 text-sm sm:text-base" className="px-6 py-3.5 rounded-xl font-bold text-[#272757] bg-sky-50 hover:bg-sky-100 border border-sky-200 flex items-center gap-2 text-sm sm:text-base transition-all cursor-pointer"
> >
<Globe className="w-5 h-5 text-indigo-400" /> <Globe className="w-5 h-5 text-[#54b4d3]" />
<span>ورود به نسخه وب اپلیکیشن</span> <span>ورود به نسخه وب اپلیکیشن</span>
</a> </a>
</div> </div>
{/* Trust Features */} {/* Trust Features */}
<div className="flex flex-wrap justify-center gap-6 mt-10 pt-8 border-t border-white/5 text-xs text-slate-400"> <div className="flex flex-wrap justify-center gap-6 mt-10 pt-8 border-t border-slate-100 text-xs sm:text-sm font-medium text-slate-700">
<span className="flex items-center gap-1.5"> <span className="flex items-center gap-1.5">
<CheckCircle2 className="w-4 h-4 text-emerald-400" /> <CheckCircle2 className="w-4 h-4 text-emerald-600" />
بدون نیاز به فیلترشکن بدون نیاز به فیلترشکن
</span> </span>
<span className="flex items-center gap-1.5"> <span className="flex items-center gap-1.5">
<CheckCircle2 className="w-4 h-4 text-emerald-400" /> <CheckCircle2 className="w-4 h-4 text-emerald-600" />
اتصال پرسرعت به سرورهای داخلی اتصال پرسرعت به سرورهای داخلی
</span> </span>
<span className="flex items-center gap-1.5"> <span className="flex items-center gap-1.5">
<CheckCircle2 className="w-4 h-4 text-emerald-400" /> <CheckCircle2 className="w-4 h-4 text-emerald-600" />
پشتیبانی ۷ روز هفته پشتیبانی ۷ روز هفته
</span> </span>
</div> </div>

View File

@ -1,6 +1,6 @@
import React, { useState } from 'react'; import React, { useState } from 'react';
import { Link } from 'react-router-dom'; import { Link } from 'react-router-dom';
import { GraduationCap, BookOpen, Clock, Users, ArrowLeft, CheckCircle } from 'lucide-react'; import { GraduationCap, BookOpen, Clock, Users, ArrowLeft, Sparkles, CheckCircle2 } from 'lucide-react';
import coursesData from '../../data/courses.json'; import coursesData from '../../data/courses.json';
export const CoursesSection: React.FC = () => { export const CoursesSection: React.FC = () => {
@ -13,13 +13,12 @@ export const CoursesSection: React.FC = () => {
}); });
return ( return (
<section className="py-20 relative bg-slate-950/40"> <section className="py-20 relative bg-white border-t border-slate-200 select-none">
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8"> <div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
{/* Header */} {/* Header */}
<div className="donya-section-header"> <div className="donya-section-header">
<h2 className="donya-section-title"> <h2 className="donya-section-title text-3xl sm:text-4xl lg:text-5xl font-black text-[#272757] font-vazir tracking-tight">
<GraduationCap className="w-7 h-7 text-indigo-400" />
<span>آموزش هوش مصنوعی</span> <span>آموزش هوش مصنوعی</span>
</h2> </h2>
<div className="donya-divider"> <div className="donya-divider">
@ -27,94 +26,91 @@ export const CoursesSection: React.FC = () => {
<span className="donya-divider-icon"></span> <span className="donya-divider-icon"></span>
<span className="donya-divider-line"></span> <span className="donya-divider-line"></span>
</div> </div>
<p className="text-slate-400 text-sm sm:text-base max-w-2xl mx-auto mt-3"> <p className="text-slate-700 text-sm sm:text-base max-w-2xl mx-auto mt-3 font-normal leading-relaxed">
از مبانی تا تکنیکهای پیشرفته پرامپتنویسی و پیادهسازی هوش مصنوعی در کسبوکارها با آکادمی هوشان از مبانی تا تکنیکهای پیشرفته پرامپتنویسی و پیادهسازی هوش مصنوعی در کسبوکارها با آکادمی هوشان
</p> </p>
{/* Individual vs Enterprise Toggle Buttons */}
<div className="flex items-center justify-center gap-3 mt-6">
<button
onClick={() => setFilter('all')}
className={`px-5 py-2 rounded-xl text-xs sm:text-sm font-bold transition-all ${
filter === 'all' ? 'bg-indigo-600 text-white shadow-lg' : 'bg-slate-900/80 text-slate-400 hover:text-white border border-white/5'
}`}
>
همهی دورهها
</button>
<button
onClick={() => setFilter('individual')}
className={`px-5 py-2 rounded-xl text-xs sm:text-sm font-bold transition-all ${
filter === 'individual' ? 'bg-indigo-600 text-white shadow-lg' : 'bg-slate-900/80 text-slate-400 hover:text-white border border-white/5'
}`}
>
آموزش فردی
</button>
<button
onClick={() => setFilter('enterprise')}
className={`px-5 py-2 rounded-xl text-xs sm:text-sm font-bold transition-all ${
filter === 'enterprise' ? 'bg-indigo-600 text-white shadow-lg' : 'bg-slate-900/80 text-slate-400 hover:text-white border border-white/5'
}`}
>
آموزش سازمانی
</button>
</div>
</div> </div>
{/* Courses Grid */} {/* Courses Grid with Cover Images */}
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6 mb-12"> <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6 sm:gap-8 mb-12">
{filteredCourses.slice(0, 3).map((course) => ( {filteredCourses.slice(0, 3).map((course) => (
<div <div
key={course.id} key={course.id}
className="glass-panel rounded-2xl overflow-hidden flex flex-col justify-between hover:border-indigo-500/40 transition-all duration-300 hover:-translate-y-1 shadow-xl group" className="model-card-premium flex flex-col justify-between shadow-xs hover:shadow-lg transition-all duration-300 group"
> >
<div className="p-6"> <div>
<div className="flex items-center justify-between mb-4"> {/* Course Cover Image Banner */}
<span className="px-3 py-1 rounded-lg text-xs font-bold bg-indigo-500/20 text-indigo-300 border border-indigo-500/30"> <div className="relative aspect-[16/9] w-full bg-slate-100 overflow-hidden border-b border-slate-100">
<img
src="/storage/banner/course_cover_default.jpg"
alt={course.title}
className="w-full h-full object-cover group-hover:scale-105 transition-transform duration-500"
/>
<div className="absolute inset-0 bg-gradient-to-t from-black/60 via-transparent to-transparent pointer-events-none" />
{/* Category Pill on Image */}
<div className="absolute top-3 right-3 z-10">
<span className="text-[10px] font-bold px-3 py-1 rounded-lg bg-white/95 text-[#272757] border border-slate-200 shadow-xs backdrop-blur-md">
{course.category} {course.category}
</span> </span>
<span className="text-xs text-slate-400 flex items-center gap-1">
<Clock className="w-3.5 h-3.5 text-slate-500" />
{course.hours}
</span>
</div> </div>
<h3 className="text-lg font-bold text-white mb-3 group-hover:text-indigo-300 transition-colors"> {/* Duration Badge */}
<div className="absolute bottom-3 right-3 z-10 text-white flex items-center gap-1.5 text-xs font-bold bg-black/60 px-2.5 py-1 rounded-lg backdrop-blur-md">
<Clock className="w-3.5 h-3.5 text-amber-300" />
<span>{course.hours}</span>
</div>
{/* Level Tag */}
<div className="absolute bottom-3 left-3 z-10 text-white text-[11px] font-bold bg-[#272757]/80 px-2.5 py-1 rounded-lg backdrop-blur-md">
{course.level}
</div>
</div>
{/* Course Details Content */}
<div className="p-6 space-y-3.5">
<h3 className="text-base sm:text-lg font-black text-slate-900 group-hover:text-[#54b4d3] transition-colors leading-snug font-vazir min-h-[48px]">
{course.title} {course.title}
</h3> </h3>
<p className="text-xs sm:text-sm text-slate-400 leading-relaxed mb-4">
{course.excerpt || course.description.slice(0, 150) + '...'} <p className="text-xs sm:text-sm text-slate-600 leading-relaxed font-normal min-h-[50px] line-clamp-3">
{course.excerpt && course.excerpt !== '...' ? course.excerpt : course.description.slice(0, 140) + '...'}
</p> </p>
<div className="flex items-center gap-2 text-xs text-slate-300 mb-2"> <div className="flex items-center gap-2 text-xs text-slate-700 font-medium pt-2 border-t border-slate-100">
<Users className="w-3.5 h-3.5 text-cyan-400" /> <Users className="w-4 h-4 text-[#54b4d3] shrink-0" />
<span>مخاطبان: {course.audience}</span> <span className="line-clamp-1">مخاطبان: {course.audience}</span>
</div>
</div> </div>
</div> </div>
<div className="p-4 bg-slate-900/60 border-t border-white/5 flex items-center justify-between"> {/* Card Footer with Price and Action */}
<div className="p-4 bg-slate-50 border-t border-slate-100 flex items-center justify-between">
<div> <div>
<span className="text-xs text-slate-400 block">شهریه دوره:</span> <span className="text-[10px] text-slate-500 block font-medium">شهریه دوره:</span>
<span className="text-sm font-extrabold text-white">{course.price}</span> <span className="text-xs sm:text-sm font-black text-slate-900">{course.price}</span>
</div> </div>
<Link <Link
to="/academy" to="/academy"
className="btn-donya-primary px-4 py-2 rounded-lg text-xs font-bold flex items-center gap-1" className="px-4 py-2 rounded-xl text-xs font-bold flex items-center gap-1.5 bg-[#272757] hover:bg-[#373775] text-white shadow-xs transition-all group/btn cursor-pointer"
> >
<span>مشاهده دوره</span> <span>مشاهده دوره</span>
<ArrowLeft className="w-3.5 h-3.5" /> <ArrowLeft className="w-3.5 h-3.5 group-hover/btn:-translate-x-1 transition-transform" />
</Link> </Link>
</div> </div>
</div> </div>
))} ))}
</div> </div>
{/* Bottom CTA */}
<div className="text-center"> <div className="text-center">
<Link <Link
to="/academy" to="/academy"
className="btn-donya-outline inline-flex items-center gap-2 px-6 py-3 rounded-xl text-sm font-bold" className="inline-flex items-center gap-2.5 px-8 py-3.5 rounded-xl bg-white hover:bg-slate-50 border border-slate-200 text-[#272757] text-xs sm:text-sm font-bold shadow-xs hover:shadow-md transition-all cursor-pointer"
> >
<BookOpen className="w-4 h-4 text-indigo-400" /> <BookOpen className="w-4 h-4 text-[#54b4d3]" />
<span>مشاهده همه دورههای آموزشی</span> <span>مشاهده همه دورههای آموزشی ({coursesData.length} دوره)</span>
</Link> </Link>
</div> </div>

View File

@ -3,8 +3,6 @@ import { Link } from 'react-router-dom';
import { import {
Building2, Building2,
TrendingUp, TrendingUp,
Database,
Bot,
ShieldCheck, ShieldCheck,
ArrowLeft, ArrowLeft,
GraduationCap, GraduationCap,
@ -42,43 +40,35 @@ export const EnterpriseHighlight: React.FC = () => {
]; ];
return ( return (
<section className="py-20 relative bg-slate-900/40 border-y border-slate-800/80 overflow-hidden"> <section className="py-20 relative bg-slate-50 border-t border-slate-200 overflow-hidden select-none">
{/* Decorative Glow */}
<div className="absolute bottom-0 right-0 w-96 h-96 bg-cyan-600/10 rounded-full blur-3xl pointer-events-none" />
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 relative z-10"> <div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 relative z-10">
<div className="grid grid-cols-1 lg:grid-cols-12 gap-12 items-center"> <div className="grid grid-cols-1 lg:grid-cols-12 gap-12 items-center">
{/* Left Column: Heading & CTA */} {/* Left Column: Heading & CTA */}
<div className="lg:col-span-5 space-y-6"> <div className="lg:col-span-5 space-y-6">
<div className="inline-flex items-center gap-2 px-3 py-1 rounded-full bg-cyan-500/10 border border-cyan-500/20 text-cyan-400 text-xs font-semibold"> <h2 className="text-2xl sm:text-4xl font-black text-[#272757] tracking-tight leading-snug font-vazir">
<Building2 className="w-3.5 h-3.5" />
<span>راهکارهای سازمانی هوشان</span>
</div>
<h2 className="text-2xl sm:text-4xl font-black text-white tracking-tight leading-snug">
تحول دیجیتال و رشد بهرهوری سازمان با هوش مصنوعی تحول دیجیتال و رشد بهرهوری سازمان با هوش مصنوعی
</h2> </h2>
<p className="text-sm text-slate-300 leading-relaxed"> <p className="text-sm sm:text-base text-slate-700 leading-relaxed font-normal">
سازمانها برای ماندگاری و پیشگامی نیازمند ارتقای مهارتهای نیروها (Upskilling) و هوشمندسازی فرآیندهای عملیاتی هستند. تیم متخصصین هوشان آماده ارائه راهکارهای سفارشی و آموزشهای جامع سازمانی است. سازمانها برای ماندگاری و پیشگامی نیازمند ارتقای مهارتهای نیروها (Upskilling) و هوشمندسازی فرآیندهای عملیاتی هستند. تیم متخصصین هوشان آماده ارائه راهکارهای سفارشی و آموزشهای جامع سازمانی است.
</p> </p>
<div className="space-y-3 pt-2"> <div className="space-y-3 pt-2">
<div className="flex items-center gap-3 p-3.5 rounded-2xl bg-slate-950/60 border border-slate-800/80"> <div className="flex items-center gap-3.5 p-4 rounded-2xl bg-white border border-slate-200 shadow-xs">
<GraduationCap className="w-6 h-6 text-indigo-400 shrink-0" /> <GraduationCap className="w-6 h-6 text-[#272757] shrink-0" />
<div> <div>
<h4 className="text-xs font-bold text-white">دورههای آموزشی سازمانی هوشان</h4> <h4 className="text-xs sm:text-sm font-bold text-slate-900">دورههای آموزشی سازمانی هوشان</h4>
<p className="text-[11px] text-slate-400">۱۸ دوره تخصصی برای بازمهارتآموزی مدیران و کارکنان</p> <p className="text-xs text-slate-600 font-normal mt-0.5">۱۸ دوره تخصصی برای بازمهارتآموزی مدیران و کارکنان</p>
</div> </div>
</div> </div>
<div className="flex items-center gap-3 p-3.5 rounded-2xl bg-slate-950/60 border border-slate-800/80"> <div className="flex items-center gap-3.5 p-4 rounded-2xl bg-white border border-slate-200 shadow-xs">
<TrendingUp className="w-6 h-6 text-emerald-400 shrink-0" /> <TrendingUp className="w-6 h-6 text-emerald-600 shrink-0" />
<div> <div>
<h4 className="text-xs font-bold text-white">مشاوره تخصصی و طراحی سفارشی</h4> <h4 className="text-xs sm:text-sm font-bold text-slate-900">مشاوره تخصصی و طراحی سفارشی</h4>
<p className="text-[11px] text-slate-400">تحلیل چالشهای سازمان و طراحی نقشه راه هوش مصنوعی</p> <p className="text-xs text-slate-600 font-normal mt-0.5">تحلیل چالشهای سازمان و طراحی نقشه راه هوش مصنوعی</p>
</div> </div>
</div> </div>
</div> </div>
@ -86,7 +76,7 @@ export const EnterpriseHighlight: React.FC = () => {
<div className="flex flex-wrap items-center gap-3 pt-3"> <div className="flex flex-wrap items-center gap-3 pt-3">
<Link <Link
to="/enterprise" to="/enterprise"
className="px-6 py-3 rounded-2xl text-xs font-bold text-white bg-gradient-to-r from-cyan-600 to-indigo-600 hover:opacity-90 shadow-lg shadow-cyan-600/20 transition-all flex items-center gap-2" className="px-6 py-3 rounded-xl text-xs sm:text-sm font-bold text-white bg-[#272757] hover:bg-[#373775] shadow-xs transition-all flex items-center gap-2 cursor-pointer"
> >
<span>درخواست جلسه مشاوره سازمانی</span> <span>درخواست جلسه مشاوره سازمانی</span>
<ArrowLeft className="w-4 h-4" /> <ArrowLeft className="w-4 h-4" />
@ -94,7 +84,7 @@ export const EnterpriseHighlight: React.FC = () => {
<Link <Link
to="/academy" to="/academy"
className="px-5 py-3 rounded-2xl text-xs font-semibold text-slate-300 hover:text-white bg-slate-800 hover:bg-slate-700 transition-colors" className="px-5 py-3 rounded-xl text-xs sm:text-sm font-bold text-slate-700 hover:text-slate-900 bg-white hover:bg-slate-100 border border-slate-200 transition-colors shadow-xs"
> >
<span>مشاهده دورهها</span> <span>مشاهده دورهها</span>
</Link> </Link>
@ -108,23 +98,23 @@ export const EnterpriseHighlight: React.FC = () => {
return ( return (
<div <div
key={idx} key={idx}
className="p-6 rounded-3xl bg-slate-950/90 border border-slate-800/80 hover:border-cyan-500/40 glass-panel-hover space-y-3 flex flex-col justify-between" className="p-6 rounded-3xl bg-white border border-slate-200 hover:border-slate-300 shadow-xs hover:shadow-md transition-all space-y-3 flex flex-col justify-between"
> >
<div className="space-y-3"> <div className="space-y-3">
<div className="flex items-center justify-between"> <div className="flex items-center justify-between">
<div className="w-10 h-10 rounded-xl bg-cyan-500/10 text-cyan-400 flex items-center justify-center"> <div className="w-10 h-10 rounded-xl bg-sky-50 text-[#272757] flex items-center justify-center border border-sky-100">
<Icon className="w-5 h-5" /> <Icon className="w-5 h-5" />
</div> </div>
<span className="text-[10px] font-semibold px-2 py-0.5 rounded-full bg-slate-800 text-slate-400"> <span className="text-[10px] font-bold px-2.5 py-0.5 rounded-md bg-slate-100 text-slate-700">
{srv.badge} {srv.badge}
</span> </span>
</div> </div>
<h3 className="text-sm font-bold text-white"> <h3 className="text-sm sm:text-base font-bold text-slate-900 leading-snug">
{srv.title} {srv.title}
</h3> </h3>
<p className="text-xs text-slate-400 leading-relaxed"> <p className="text-xs text-slate-600 leading-relaxed font-normal">
{srv.desc} {srv.desc}
</p> </p>
</div> </div>

View File

@ -1,5 +1,5 @@
import React, { useState } from 'react'; import React, { useState } from 'react';
import { HelpCircle, ChevronDown, Sparkles } from 'lucide-react'; import { HelpCircle, ChevronDown } from 'lucide-react';
export const FAQSection: React.FC = () => { export const FAQSection: React.FC = () => {
const [openIdx, setOpenIdx] = useState<number | null>(0); const [openIdx, setOpenIdx] = useState<number | null>(0);
@ -24,12 +24,12 @@ export const FAQSection: React.FC = () => {
]; ];
return ( return (
<section className="py-20 relative bg-slate-950/40"> <section className="py-20 relative bg-white border-t border-slate-200 select-none">
<div className="max-w-4xl mx-auto px-4 sm:px-6 lg:px-8"> <div className="max-w-4xl mx-auto px-4 sm:px-6 lg:px-8">
<div className="donya-section-header"> <div className="donya-section-header">
<h2 className="donya-section-title"> <h2 className="donya-section-title">
<HelpCircle className="w-7 h-7 text-cyan-400" /> <HelpCircle className="w-7 h-7 text-[#272757]" />
<span>سوالات متداول</span> <span>سوالات متداول</span>
</h2> </h2>
<div className="donya-divider"> <div className="donya-divider">
@ -37,7 +37,7 @@ export const FAQSection: React.FC = () => {
<span className="donya-divider-icon"></span> <span className="donya-divider-icon"></span>
<span className="donya-divider-line"></span> <span className="donya-divider-line"></span>
</div> </div>
<p className="text-slate-400 text-sm sm:text-base max-w-2xl mx-auto mt-3"> <p className="text-slate-700 text-sm sm:text-base max-w-2xl mx-auto mt-3 font-normal leading-relaxed">
پاسخ به سوالات پرتکرار شما درباره نحوه کار، اشتراکها و قابلیتهای هوشان پاسخ به سوالات پرتکرار شما درباره نحوه کار، اشتراکها و قابلیتهای هوشان
</p> </p>
</div> </div>
@ -48,18 +48,18 @@ export const FAQSection: React.FC = () => {
return ( return (
<div <div
key={idx} key={idx}
className="glass-panel rounded-2xl overflow-hidden border border-white/5 transition-all duration-200" className="bg-white rounded-2xl overflow-hidden border border-slate-200 shadow-xs transition-all duration-200"
> >
<button <button
onClick={() => setOpenIdx(isOpen ? null : idx)} onClick={() => setOpenIdx(isOpen ? null : idx)}
className="w-full p-5 text-right flex items-center justify-between gap-4 font-bold text-white hover:text-cyan-300 transition-colors" className="w-full p-5 text-right flex items-center justify-between gap-4 font-bold text-slate-900 hover:text-[#54b4d3] transition-colors cursor-pointer"
> >
<span className="text-sm sm:text-base">{item.q}</span> <span className="text-sm sm:text-base font-bold">{item.q}</span>
<ChevronDown className={`w-5 h-5 text-cyan-400 transition-transform duration-300 ${isOpen ? 'rotate-180' : ''}`} /> <ChevronDown className={`w-5 h-5 text-[#272757] transition-transform duration-300 ${isOpen ? 'rotate-180' : ''}`} />
</button> </button>
{isOpen && ( {isOpen && (
<div className="px-5 pb-5 text-xs sm:text-sm text-slate-300 leading-relaxed border-t border-white/5 pt-4"> <div className="px-5 pb-5 text-xs sm:text-sm text-slate-700 leading-relaxed border-t border-slate-100 pt-4 font-normal">
{item.a} {item.a}
</div> </div>
)} )}

View File

@ -1,12 +1,12 @@
import React from 'react'; import React from 'react';
interface HeroProps { interface HeroProps {
onOpenAuth: () => void; onOpenAuth?: () => void;
} }
export const Hero: React.FC<HeroProps> = ({ onOpenAuth }) => { export const Hero: React.FC<HeroProps> = ({ onOpenAuth }) => {
return ( return (
<section className="relative pt-24 sm:pt-32 pb-16 sm:pb-24 bg-white overflow-hidden select-none"> <section className="relative pt-24 sm:pt-32 pb-16 sm:pb-24 bg-white overflow-hidden select-none border-b border-slate-100">
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8"> <div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div className="grid grid-cols-1 lg:grid-cols-12 gap-8 lg:gap-12 items-center"> <div className="grid grid-cols-1 lg:grid-cols-12 gap-8 lg:gap-12 items-center">
@ -14,12 +14,12 @@ export const Hero: React.FC<HeroProps> = ({ onOpenAuth }) => {
<div className="lg:col-span-6 order-2 lg:order-1 text-center lg:text-right flex flex-col items-center lg:items-start justify-center"> <div className="lg:col-span-6 order-2 lg:order-1 text-center lg:text-right flex flex-col items-center lg:items-start justify-center">
{/* Main Brand Title */} {/* Main Brand Title */}
<h1 className="text-4xl sm:text-5xl lg:text-6xl font-black text-[#5cbbe2] tracking-tight leading-tight font-vazir"> <h1 className="text-4xl sm:text-5xl lg:text-6xl font-black text-[#272757] tracking-tight leading-tight font-vazir">
هوشان؛ هوشان؛
</h1> </h1>
{/* Subtitle */} {/* Subtitle */}
<p className="text-xl sm:text-2xl lg:text-3xl font-bold text-[#5cbbe2] mt-2 sm:mt-3 mb-8 lg:mb-10 font-vazir"> <p className="text-xl sm:text-2xl lg:text-3xl font-bold text-[#54b4d3] mt-2 sm:mt-3 mb-8 lg:mb-10 font-vazir">
دستیار هوش مصنوعی شما دستیار هوش مصنوعی شما
</p> </p>
@ -54,10 +54,11 @@ export const Hero: React.FC<HeroProps> = ({ onOpenAuth }) => {
/> />
</a> </a>
{/* 3. Web App / iOS */} {/* 3. Web App / iOS -> web.houshan.ai */}
<button <a
type="button" href="https://web.houshan.ai"
onClick={onOpenAuth} target="_blank"
rel="noopener noreferrer"
className="block w-full transition-transform duration-200 hover:scale-[1.03] active:scale-[0.98] drop-shadow-sm cursor-pointer" className="block w-full transition-transform duration-200 hover:scale-[1.03] active:scale-[0.98] drop-shadow-sm cursor-pointer"
> >
<img <img
@ -65,7 +66,7 @@ export const Hero: React.FC<HeroProps> = ({ onOpenAuth }) => {
alt="نسخه وب / ios" alt="نسخه وب / ios"
className="w-full h-auto object-contain rounded-lg sm:rounded-xl" className="w-full h-auto object-contain rounded-lg sm:rounded-xl"
/> />
</button> </a>
{/* 4. Direct Android Download */} {/* 4. Direct Android Download */}
<a <a

View File

@ -153,7 +153,10 @@ $$\\min \\sum_{i,j} c_{ij} x_{ij} + \\lambda \\cdot E(traffic)$$
: 'text-slate-400 hover:text-white' : 'text-slate-400 hover:text-white'
}`} }`}
> >
<span>🏛 دستیار هوشان</span> <span className="flex items-center gap-1.5">
<img src="/storage/banner/owl_logo.png" alt="Houshan" className="w-4 h-4 object-contain" />
<span>دستیار هوشان</span>
</span>
</button> </button>
<button <button
@ -165,7 +168,7 @@ $$\\min \\sum_{i,j} c_{ij} x_{ij} + \\lambda \\cdot E(traffic)$$
}`} }`}
> >
<Sparkles className="w-3.5 h-3.5 text-cyan-300" /> <Sparkles className="w-3.5 h-3.5 text-cyan-300" />
<span>تست زنده مدلها</span> <span>تست زنده مدلها</span>
</button> </button>
</div> </div>
</div> </div>
@ -178,32 +181,32 @@ $$\\min \\sum_{i,j} c_{ij} x_{ij} + \\lambda \\cdot E(traffic)$$
<div className="absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 w-80 h-80 bg-indigo-500/20 rounded-full blur-3xl pointer-events-none" /> <div className="absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 w-80 h-80 bg-indigo-500/20 rounded-full blur-3xl pointer-events-none" />
{/* Floating AI Feature Badges */} {/* Floating AI Feature Badges */}
<div className="absolute top-6 right-4 sm:right-8 z-20 px-3 py-1.5 rounded-2xl bg-slate-900/90 border border-cyan-500/40 shadow-xl backdrop-blur-md flex items-center gap-2 animate-float"> <div className="absolute top-6 right-4 sm:right-8 z-20 px-3 py-1.5 rounded-2xl bg-slate-900/90 border border-cyan-500/40 shadow-xl backdrop-blur-md flex items-center gap-2.5 animate-float">
<span className="text-base">🎬</span> <img src="/storage/banner/owl_role_creative.jpg" alt="Video Owl" className="w-8 h-8 rounded-full object-cover border border-cyan-400/50 shadow-sm" />
<div className="text-right"> <div className="text-right">
<span className="text-[10px] text-cyan-300 block font-bold">تولید ویدیو</span> <span className="text-[10px] text-cyan-300 block font-bold">تولید ویدیو</span>
<span className="text-[9px] text-slate-400 block">متن و تصویر به ویدیو</span> <span className="text-[9px] text-slate-400 block">متن و تصویر به ویدیو</span>
</div> </div>
</div> </div>
<div className="absolute top-12 left-4 sm:left-6 z-20 px-3 py-1.5 rounded-2xl bg-slate-900/90 border border-purple-500/40 shadow-xl backdrop-blur-md flex items-center gap-2 animate-float-delayed"> <div className="absolute top-12 left-4 sm:left-6 z-20 px-3 py-1.5 rounded-2xl bg-slate-900/90 border border-purple-500/40 shadow-xl backdrop-blur-md flex items-center gap-2.5 animate-float-delayed">
<span className="text-base">🎨</span> <img src="/storage/banner/owl_role_writer.jpg" alt="Image Owl" className="w-8 h-8 rounded-full object-cover border border-purple-400/50 shadow-sm" />
<div className="text-right"> <div className="text-right">
<span className="text-[10px] text-purple-300 block font-bold">استودیو تصویر</span> <span className="text-[10px] text-purple-300 block font-bold">استودیو تصویر</span>
<span className="text-[9px] text-slate-400 block">کیفیت 4K و روتوش</span> <span className="text-[9px] text-slate-400 block">کیفیت 4K و روتوش</span>
</div> </div>
</div> </div>
<div className="absolute bottom-6 right-6 sm:right-10 z-20 px-3 py-1.5 rounded-2xl bg-slate-900/90 border border-amber-500/40 shadow-xl backdrop-blur-md flex items-center gap-2 animate-float"> <div className="absolute bottom-6 right-6 sm:right-10 z-20 px-3 py-1.5 rounded-2xl bg-slate-900/90 border border-amber-500/40 shadow-xl backdrop-blur-md flex items-center gap-2.5 animate-float">
<span className="text-base">🎙</span> <img src="/storage/banner/owl_role_audio.jpg" alt="Audio Owl" className="w-8 h-8 rounded-full object-cover border border-amber-400/50 shadow-sm" />
<div className="text-right"> <div className="text-right">
<span className="text-[10px] text-amber-300 block font-bold">صوت و موسیقی</span> <span className="text-[10px] text-amber-300 block font-bold">صوت و موسیقی</span>
<span className="text-[9px] text-slate-400 block">تولید آهنگ و TTS</span> <span className="text-[9px] text-slate-400 block">تولید آهنگ و TTS</span>
</div> </div>
</div> </div>
<div className="absolute bottom-8 left-4 sm:left-8 z-20 px-3 py-1.5 rounded-2xl bg-slate-900/90 border border-emerald-500/40 shadow-xl backdrop-blur-md flex items-center gap-2 animate-float-delayed"> <div className="absolute bottom-8 left-4 sm:left-8 z-20 px-3 py-1.5 rounded-2xl bg-slate-900/90 border border-emerald-500/40 shadow-xl backdrop-blur-md flex items-center gap-2.5 animate-float-delayed">
<span className="text-base">🧠</span> <img src="/storage/banner/owl_role_developer.jpg" alt="Reasoning Owl" className="w-8 h-8 rounded-full object-cover border border-emerald-400/50 shadow-sm" />
<div className="text-right"> <div className="text-right">
<span className="text-[10px] text-emerald-300 block font-bold">استدلال عمیق</span> <span className="text-[10px] text-emerald-300 block font-bold">استدلال عمیق</span>
<span className="text-[9px] text-slate-400 block">GPT-4o & DeepSeek R1</span> <span className="text-[9px] text-slate-400 block">GPT-4o & DeepSeek R1</span>

View File

@ -1,6 +1,6 @@
import React, { useState } from 'react'; import React, { useState } from 'react';
import { Link } from 'react-router-dom'; import { Link } from 'react-router-dom';
import { BookOpen, Calendar, Clock, ArrowLeft, Wand2, Cpu, TrendingUp, HelpCircle, Bot } from 'lucide-react'; import { BookOpen, Calendar, Clock, ArrowLeft } from 'lucide-react';
import postsData from '../../data/posts.json'; import postsData from '../../data/posts.json';
import { getCategoryCover } from '../../pages/Blog'; import { getCategoryCover } from '../../pages/Blog';
@ -9,48 +9,43 @@ export const LatestArticles: React.FC = () => {
const [imgErrors, setImgErrors] = useState<Record<number, boolean>>({}); const [imgErrors, setImgErrors] = useState<Record<number, boolean>>({});
return ( return (
<section className="py-20 relative bg-slate-950"> <section className="py-20 relative bg-white border-t border-slate-200 select-none">
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 relative z-10"> <div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 relative z-10">
{/* Section Header */} {/* Section Header */}
<div className="flex flex-col md:flex-row md:items-end justify-between gap-6 mb-12"> <div className="flex flex-col md:flex-row md:items-end justify-between gap-6 mb-12">
<div className="space-y-3 max-w-2xl"> <div className="space-y-3 max-w-2xl">
<div className="inline-flex items-center gap-2 px-3 py-1 rounded-full bg-indigo-500/10 border border-indigo-500/20 text-indigo-400 text-xs font-semibold"> <h2 className="text-2xl sm:text-4xl font-black text-[#272757] tracking-tight font-vazir">
<BookOpen className="w-3.5 h-3.5" />
<span>رسانه و مقالات تخصصی هوشان</span>
</div>
<h2 className="text-2xl sm:text-4xl font-black text-white tracking-tight">
آخرین تحلیلها و آموزشهای هوش مصنوعی آخرین تحلیلها و آموزشهای هوش مصنوعی
</h2> </h2>
<p className="text-sm text-slate-400 leading-relaxed"> <p className="text-sm sm:text-base text-slate-700 leading-relaxed font-normal">
از آموزش پرامپتنویسی اصولی تا بررسی جدیدترین ترندهای هوش مصنوعی و کاربردهای صنعتی، در بیش از ۱۰۰ مقاله بهروز. از آموزش پرامپتنویسی اصولی تا بررسی جدیدترین ترندهای هوش مصنوعی و کاربردهای صنعتی، در بیش از ۱۰۰ مقاله بهروز.
</p> </p>
</div> </div>
<Link <Link
to="/blog" to="/blog"
className="inline-flex items-center gap-2 text-xs sm:text-sm font-bold text-indigo-400 hover:text-indigo-300 transition-colors group shrink-0" className="inline-flex items-center gap-2 text-xs sm:text-sm font-bold text-[#272757] hover:text-[#54b4d3] transition-colors group shrink-0"
> >
<span>مشاهده همه مقالات ({postsData.length} مقاله)</span> <span>مشاهده همه مقالات (بیش از ۱۰۰ مقاله)</span>
<ArrowLeft className="w-4 h-4 group-hover:-translate-x-1 transition-transform" /> <ArrowLeft className="w-4 h-4 group-hover:-translate-x-1 transition-transform text-[#54b4d3]" />
</Link> </Link>
</div> </div>
{/* Articles Grid */} {/* Articles Grid */}
<div className="grid grid-cols-1 md:grid-cols-3 gap-6"> <div className="grid grid-cols-1 md:grid-cols-3 gap-6">
{featuredPosts.map((post) => { {featuredPosts.map((post) => {
const theme = getCategoryCover(post.categories[0] || ''); const meta = getCategoryCover(post.categories[0] || '');
const Icon = theme.icon;
const hasImg = post.thumbnail && !imgErrors[post.id]; const hasImg = post.thumbnail && !imgErrors[post.id];
return ( return (
<article <article
key={post.id} key={post.id}
className="rounded-3xl bg-slate-900/50 border border-slate-800/80 hover:border-indigo-500/40 glass-panel-hover flex flex-col justify-between overflow-hidden group" className="rounded-3xl bg-white border border-slate-200 hover:border-slate-300 shadow-xs hover:shadow-md transition-all flex flex-col justify-between overflow-hidden group"
> >
<div> <div>
{/* Cover */} {/* Cover */}
<div className="relative h-48 w-full bg-slate-950 overflow-hidden border-b border-slate-800/80"> <div className="relative aspect-[16/10] w-full bg-slate-100 overflow-hidden border-b border-slate-100">
{hasImg ? ( {hasImg ? (
<> <>
<img <img
@ -59,61 +54,49 @@ export const LatestArticles: React.FC = () => {
className="w-full h-full object-cover group-hover:scale-105 transition-transform duration-500" className="w-full h-full object-cover group-hover:scale-105 transition-transform duration-500"
onError={() => setImgErrors(prev => ({ ...prev, [post.id]: true }))} onError={() => setImgErrors(prev => ({ ...prev, [post.id]: true }))}
/> />
<div className="absolute inset-0 bg-gradient-to-t from-slate-950 via-slate-950/20 to-transparent pointer-events-none" />
<div className="absolute top-3 right-3 z-10"> <div className="absolute top-3 right-3 z-10">
<span className="text-[10px] font-bold px-2.5 py-1 rounded-full bg-indigo-600/90 text-white backdrop-blur-md"> <span className={`text-[10px] font-bold px-2.5 py-1 rounded-lg ${meta.badgeBg} backdrop-blur-md shadow-xs`}>
{post.categories[0] || 'هوش مصنوعی'} {post.categories[0] || 'هوش مصنوعی'}
</span> </span>
</div> </div>
</> </>
) : ( ) : (
<div className={`w-full h-full bg-gradient-to-br ${theme.gradient} flex flex-col justify-between p-5`}> <div className="w-full h-full bg-slate-100 flex items-center justify-center p-5">
<div className="flex items-center justify-between z-10"> <img src="/storage/banner/owl_logo.png" alt="Houshan" className="w-16 h-16 object-contain" />
<span className={`text-[10px] font-bold px-2.5 py-1 rounded-full ${theme.badgeColor} backdrop-blur-md`}>
{post.categories[0] || 'هوش مصنوعی'}
</span>
<div className="w-8 h-8 rounded-xl bg-slate-950/60 border border-slate-800 flex items-center justify-center text-slate-300">
<Icon className="w-4 h-4" />
</div>
</div>
<div className="z-10 text-right">
<span className="text-[10px] font-bold text-slate-400 font-mono block">#HOUSHAN_AI</span>
<h4 className="text-xs font-bold text-white line-clamp-1 mt-0.5">{post.title}</h4>
</div>
</div> </div>
)} )}
</div> </div>
{/* Content */} {/* Content */}
<div className="p-6 space-y-3"> <div className="p-6 space-y-3">
<div className="flex items-center gap-4 text-[11px] text-slate-400"> <div className="flex items-center gap-4 text-xs text-slate-500 font-medium">
<span className="flex items-center gap-1"> <span className="flex items-center gap-1">
<Calendar className="w-3.5 h-3.5 text-slate-500" /> <Calendar className="w-3.5 h-3.5 text-[#54b4d3]" />
{post.date} {post.date}
</span> </span>
<span className="flex items-center gap-1"> <span className="flex items-center gap-1">
<Clock className="w-3.5 h-3.5 text-slate-500" /> <Clock className="w-3.5 h-3.5 text-[#54b4d3]" />
{post.readTime} {post.readTime}
</span> </span>
</div> </div>
<h3 className="text-base font-bold text-white group-hover:text-indigo-300 transition-colors line-clamp-2"> <h3 className="text-base sm:text-lg font-bold text-slate-900 group-hover:text-[#54b4d3] transition-colors line-clamp-2 leading-snug">
<Link to={`/blog/${post.slug}`}> <Link to={`/blog/${post.slug}`}>
{post.title} {post.title}
</Link> </Link>
</h3> </h3>
<p className="text-xs text-slate-400 leading-relaxed line-clamp-3"> <p className="text-xs sm:text-sm text-slate-600 leading-relaxed line-clamp-3 font-normal">
{post.excerpt} {post.excerpt}
</p> </p>
</div> </div>
</div> </div>
{/* Read More Link */} {/* Read More Link */}
<div className="px-6 pb-6 pt-2"> <div className="px-6 pb-6 pt-2 border-t border-slate-100">
<Link <Link
to={`/blog/${post.slug}`} to={`/blog/${post.slug}`}
className="inline-flex items-center gap-2 text-xs font-bold text-indigo-400 hover:text-indigo-300 transition-colors" className="inline-flex items-center gap-1.5 text-xs font-bold text-[#272757] hover:text-[#54b4d3] transition-colors"
> >
<span>مطالعه کامل مقاله</span> <span>مطالعه کامل مقاله</span>
<ArrowLeft className="w-3.5 h-3.5" /> <ArrowLeft className="w-3.5 h-3.5" />

View File

@ -1,145 +1,125 @@
import React from 'react'; import React from 'react';
import { Link } from 'react-router-dom'; import { Link } from 'react-router-dom';
import { Cpu, Zap, ArrowLeft, Check, Sparkles, Star, Gauge } from 'lucide-react'; import { Cpu, ArrowLeft, Check, Sparkles } from 'lucide-react';
import modelsData from '../../data/models.json'; import modelsData from '../../data/models.json';
import { ModelIcon } from '../common/ModelIcon';
export const ModelsSection: React.FC = () => { export const ModelsSection: React.FC = () => {
return ( // Get subtle gradient theme for card header by provider
<section className="py-20 relative bg-slate-950"> const getProviderTheme = (provider: string) => {
{/* Background Glow */} const p = provider.toLowerCase();
<div className="absolute top-1/3 right-1/4 w-96 h-96 bg-purple-600/10 rounded-full blur-3xl pointer-events-none" /> if (p.includes('anthropic')) return 'from-amber-500/10 via-orange-500/5 to-transparent';
if (p.includes('openai')) return 'from-emerald-500/10 via-teal-500/5 to-transparent';
if (p.includes('google')) return 'from-sky-500/10 via-blue-500/5 to-transparent';
if (p.includes('deepseek')) return 'from-blue-600/10 via-indigo-500/5 to-transparent';
if (p.includes('xai')) return 'from-slate-800/10 via-slate-700/5 to-transparent';
return 'from-sky-500/10 via-slate-500/5 to-transparent';
};
return (
<section className="py-20 relative bg-slate-50 border-t border-slate-200 select-none">
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 relative z-10"> <div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 relative z-10">
{/* Section Header */} {/* Section Header */}
<div className="text-center max-w-2xl mx-auto space-y-3 mb-16"> <div className="text-center max-w-2xl mx-auto space-y-3 mb-16">
<div className="inline-flex items-center gap-2 px-3 py-1 rounded-full bg-purple-500/10 border border-purple-500/20 text-purple-400 text-xs font-semibold"> <h2 className="text-2xl sm:text-4xl font-black text-[#272757] tracking-tight font-vazir">
<Cpu className="w-3.5 h-3.5" />
<span>پیشرفتهترین مدلهای زبانی هوش مصنوعی دنیا</span>
</div>
<h2 className="text-2xl sm:text-4xl font-black text-white tracking-tight">
دسترسی به غولهای هوش مصنوعی در هوشان دسترسی به غولهای هوش مصنوعی در هوشان
</h2> </h2>
<p className="text-sm text-slate-400 leading-relaxed"> <p className="text-sm sm:text-base text-slate-700 leading-relaxed font-normal">
بدون نیاز به تحریمشکن، سیمکارت خارجی یا پرداخت ارزی، با پیشرفتهترین مدلهای GPT-4o، Claude 3.5 Sonnet و Gemini با بالاترین کیفیت زبان فارسی گفتگو کنید. بدون نیاز به تحریمشکن، سیمکارت خارجی یا پرداخت ارزی، با پیشرفتهترین مدلهای Claude 3.7 Sonnet، Grok 3، DeepSeek R1 و GPT-4o با بالاترین کیفیت زبان فارسی گفتگو کنید.
</p> </p>
</div> </div>
{/* Models Grid */} {/* Models Grid with Premium Animated Cards */}
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6"> <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6 sm:gap-8">
{modelsData.map((model) => ( {modelsData.slice(0, 6).map((model) => {
const providerTheme = getProviderTheme(model.provider);
return (
<div <div
key={model.id} key={model.id}
className="relative p-6 sm:p-7 rounded-3xl bg-slate-900/50 border border-slate-800/80 hover:border-purple-500/40 glass-panel-hover flex flex-col justify-between space-y-5" className="model-card-premium flex flex-col justify-between shadow-xs group"
> >
<div className="space-y-4">
{/* Header */}
<div className="flex items-center justify-between">
<div className="flex items-center gap-3">
{model.provider === 'OpenAI' && (
<div className="w-8 h-8 rounded-xl bg-slate-800 p-1.5 flex items-center justify-center">
<img src="/storage/bot/llm/gpt.png" alt="OpenAI" className="w-full h-full object-contain" />
</div>
)}
{model.provider === 'Anthropic' && (
<div className="w-8 h-8 rounded-xl bg-slate-800 p-1.5 flex items-center justify-center">
<img src="/storage/bot/llm/claude.png" alt="Anthropic" className="w-full h-full object-contain" />
</div>
)}
{model.provider === 'Google' && (
<div className="w-8 h-8 rounded-xl bg-slate-800 p-1.5 flex items-center justify-center">
<img src="/storage/bot/llm/gemini.png" alt="Google" className="w-full h-full object-contain" />
</div>
)}
{model.provider === 'DeepSeek' && (
<div className="w-8 h-8 rounded-xl bg-slate-800 p-1.5 flex items-center justify-center">
<img src="/storage/bot/llm/deepseek.png" alt="DeepSeek" className="w-full h-full object-contain" />
</div>
)}
{model.provider === 'Meta' && (
<div className="w-8 h-8 rounded-xl bg-slate-800 p-1.5 flex items-center justify-center">
<Cpu className="w-5 h-5 text-indigo-400" />
</div>
)}
<div> <div>
<span className="text-base font-black text-white font-english block"> {/* Card Top Header Banner with Gradient Background */}
<div className={`p-6 bg-gradient-to-b ${providerTheme} border-b border-slate-100 flex items-start justify-between relative`}>
<div className="flex items-center gap-3.5">
<div className="relative">
<ModelIcon provider={model.provider} name={model.name} className="w-11 h-11" />
<span className="absolute -bottom-1 -left-1 w-3 h-3 rounded-full bg-emerald-500 border-2 border-white shadow-xs" />
</div>
<div>
<span className="text-base font-black text-slate-900 font-english block leading-tight group-hover:text-[#54b4d3] transition-colors">
{model.name} {model.name}
</span> </span>
<span className="text-[10px] text-slate-400 font-mono"> <span className="text-[11px] text-slate-500 font-mono font-bold">
{model.provider} {model.provider}
</span> </span>
</div> </div>
</div> </div>
{model.badge && ( {model.badge && (
<span className="text-[10px] font-bold px-2.5 py-0.5 rounded-full bg-purple-500/20 text-purple-300 border border-purple-500/30"> <span className="text-[10px] font-bold px-2.5 py-1 rounded-lg bg-white/90 text-[#272757] border border-slate-200 shadow-xs backdrop-blur-md shrink-0">
{model.badge} {model.badge}
</span> </span>
)} )}
</div> </div>
<p className="text-xs text-slate-400 leading-relaxed"> {/* Card Body */}
<div className="p-6 space-y-4">
<p className="text-xs sm:text-sm text-slate-600 leading-relaxed font-normal min-h-[48px]">
{model.description} {model.description}
</p> </p>
{/* Specs Bar */} {/* Context Window Spec Bar */}
<div className="grid grid-cols-2 gap-2 p-3 rounded-2xl bg-slate-950/70 border border-slate-800/60 text-xs"> <div className="flex items-center justify-between p-3 rounded-2xl bg-slate-50 border border-slate-200 text-xs">
<div> <span className="text-slate-600 font-medium font-vazir">پنجره زمینه (Context):</span>
<span className="text-[10px] text-slate-500 block">پنجره زمینه (Context):</span> <span className="font-vazir font-bold text-slate-900 text-xs">{model.contextWindow}</span>
<span className="font-mono font-semibold text-slate-200 text-xs">{model.contextWindow}</span>
</div>
<div>
<span className="text-[10px] text-slate-500 block">امتیاز هوش:</span>
<div className="flex items-center gap-1">
<div className="w-16 h-1.5 rounded-full bg-slate-800 overflow-hidden">
<div
className="h-full bg-gradient-to-r from-indigo-500 to-cyan-400"
style={{ width: `${model.intelligenceScore}%` }}
/>
</div>
<span className="font-mono text-slate-200 text-[11px]">{model.intelligenceScore}%</span>
</div>
</div>
</div> </div>
{/* Strengths */} {/* Strengths */}
<div className="space-y-1.5 pt-1"> <div className="space-y-2 pt-1">
<span className="text-[11px] font-bold text-slate-300 block">ویژگیهای برجسته:</span> <span className="text-xs font-bold text-slate-900 block">ویژگیهای برجسته:</span>
{model.strengths.slice(0, 3).map((st, i) => ( {model.strengths.slice(0, 3).map((st, i) => (
<div key={i} className="flex items-center gap-2 text-[11px] text-slate-400"> <div key={i} className="flex items-center gap-2 text-xs text-slate-700">
<Check className="w-3.5 h-3.5 text-cyan-400 shrink-0" /> <div className="w-4 h-4 rounded-full bg-emerald-50 text-emerald-700 border border-emerald-200 flex items-center justify-center shrink-0">
<Check className="w-2.5 h-2.5 stroke-[3]" />
</div>
<span>{st}</span> <span>{st}</span>
</div> </div>
))} ))}
</div> </div>
</div>
</div> </div>
{/* Action Button */} {/* Action Button */}
<div className="pt-2"> <div className="p-5 bg-slate-50/50 border-t border-slate-100">
<Link <a
to="/chat" href="https://web.houshan.ai"
state={{ selectedModel: model.name }} target="_blank"
className="w-full py-2.5 rounded-xl bg-slate-800 hover:bg-gradient-to-r hover:from-purple-600 hover:to-indigo-600 text-slate-200 hover:text-white text-xs font-semibold transition-all flex items-center justify-center gap-2 shadow-sm" rel="noopener noreferrer"
className="w-full py-2.5 rounded-xl bg-[#272757] hover:bg-[#373775] text-white text-xs sm:text-sm font-bold transition-all flex items-center justify-center gap-2 shadow-xs group/btn cursor-pointer"
> >
<Sparkles className="w-3.5 h-3.5" /> <Sparkles className="w-3.5 h-3.5 text-amber-300" />
<span>شروع گفتگو با {model.name}</span> <span>شروع گفتگو با {model.name}</span>
</Link> <ArrowLeft className="w-3.5 h-3.5 group-hover/btn:-translate-x-1 transition-transform" />
</a>
</div> </div>
</div> </div>
))} );
})}
</div> </div>
{/* Bottom CTA */} {/* Bottom CTA */}
<div className="mt-12 text-center"> <div className="mt-12 text-center">
<Link <Link
to="/models" to="/models"
className="inline-flex items-center gap-2 px-6 py-3 rounded-2xl bg-slate-900 hover:bg-slate-800 border border-slate-700 text-slate-300 hover:text-white text-xs font-bold transition-all" className="inline-flex items-center gap-2 px-8 py-3.5 rounded-xl bg-white hover:bg-slate-100 border border-slate-200 text-[#272757] text-xs sm:text-sm font-bold shadow-xs transition-all cursor-pointer"
> >
<span>مقایسه جامع مشخصات و بنچمارک تمام مدلها</span> <span>مشاهده و مقایسه تمام {modelsData.length} مدل هوش مصنوعی</span>
<ArrowLeft className="w-4 h-4" /> <ArrowLeft className="w-4 h-4 text-[#54b4d3]" />
</Link> </Link>
</div> </div>

View File

@ -1,40 +1,90 @@
import React from 'react'; import React from 'react';
import { Link } from 'react-router-dom'; import {
import { DollarSign, Wand2, Share2, Wallet, ArrowLeft, Sparkles, CheckCircle2 } from 'lucide-react'; DollarSign,
Wand2,
Share2,
Wallet,
ArrowLeft,
Sparkles,
CheckCircle2,
TrendingUp,
Zap,
ShieldCheck,
CreditCard,
Users
} from 'lucide-react';
export const MonetizationSection: React.FC = () => { export const MonetizationSection: React.FC = () => {
const steps = [ const steps = [
{ {
step: '۱', step: '۰۱',
title: 'طراحی دستیار اختصاصی', title: 'طراحی دستیار اختصاصی',
desc: 'بدون نیاز به یک خط کدنویسی، پرامپت و تخصص دلخواه خود را تعیین کنید و دستیار هوشمندتان را بسازید.', desc: 'بدون نیاز به دانش کدنویسی، تخصص و رفتار هوش مصنوعی خود را با چند دستور متنی ساده طراحی و شخصی‌سازی کنید.',
icon: Wand2, image: '/storage/banner/owl_role_developer.jpg',
badge: 'ساده و سریع' badge: 'ساده و بدون کدنویسی',
features: [
'تعریف شخصیت و حیطه دانش ربات',
'آپلود فایل‌ها و مستندات راهنما (RAG)',
'پشتیبانی از تمام مدل‌های پیشرفته'
],
tagColor: 'bg-indigo-50 text-[#272757] border-indigo-200'
}, },
{ {
step: '۲', step: '۰۲',
title: 'انتشار در ویترین هوشان', title: 'انتشار در ویترین هوشان',
desc: 'دستیار خود را به عنوان یک ابزار عمومی یا تخصصی در دسترس هزاران کاربر فعال هوشان قرار دهید.', desc: 'دستیار خود را در مارکت‌پلیس عمومی یا تخصصی هوشان با نام و برند خودتان برای بیش از ۵۰,۰۰۰ کاربر فعال منتشر کنید.',
icon: Share2, image: '/storage/banner/owl_role_strategy.jpg',
badge: 'دیده‌شدن حداکثری' badge: 'دیده‌شدن حداکثری',
features: [
'دریافت لینک و صفحه اختصاصی دستیار',
'قابلیت اشتراک‌گذاری در شبکه‌های اجتماعی',
'ویترین پیشنهادات برتر هوشان'
],
tagColor: 'bg-sky-50 text-[#272757] border-sky-200'
}, },
{ {
step: '۳', step: '۰۳',
title: 'کسب درآمد و واریز آنی', title: 'کسب درآمد و تسویه آنی',
desc: 'به ازای هر بار استفاده و پیام‌های پردازش‌شده، سهم درآمد خود را به‌صورت شفاف و آنی دریافت کنید.', desc: 'به ازای هر بار استفاده کاربران، سهم خود از فروش اشتراک یا توکن‌ها را مستقیماً در پنل مالی خود دریافت و تسویه کنید.',
icon: Wallet, image: '/storage/banner/pricing-owl-header.png',
badge: 'تسویه حساب ریالی' badge: 'تسویه حساب خودکار ریالی',
features: [
'واریز مستقیم به حساب شتاب بانکی',
'گزارش زنده تعداد کاربران و درآمد',
'۷۰٪ سهم مستقیم سازنده بات'
],
tagColor: 'bg-emerald-50 text-emerald-800 border-emerald-200'
}
];
const highlights = [
{
icon: TrendingUp,
title: '۷۰٪ سهم توسعه‌دهنده',
desc: 'بیشترین درصد سهم مشارکت درآمدی در پلتفرم‌های هوش مصنوعی کشور'
},
{
icon: CreditCard,
title: 'تسویه حساب سریع',
desc: 'واریز منظم و خودکار مبالغ درآمدی به تمام کارت‌های بانکی عضو شتاب'
},
{
icon: Users,
title: 'بیش از ۵۰,۰۰۰ کاربر',
desc: 'دسترسی فوری به جامعه بزرگ و فعال کاربران هوشان بدون نیاز به تبلیغات اولیه'
} }
]; ];
return ( return (
<section className="py-20 relative overflow-hidden bg-slate-950/60 border-y border-white/5"> <section className="py-20 relative overflow-hidden bg-white border-t border-slate-200 select-none">
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8"> {/* Subtle background glow */}
<div className="absolute top-1/3 left-1/2 -translate-x-1/2 w-3/4 h-72 bg-emerald-500/5 rounded-full blur-3xl pointer-events-none" />
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 relative z-10">
{/* Section Header */} {/* Section Header */}
<div className="donya-section-header"> <div className="donya-section-header">
<h2 className="donya-section-title"> <h2 className="donya-section-title text-3xl sm:text-4xl lg:text-5xl font-black text-[#272757] font-vazir tracking-tight">
<DollarSign className="w-7 h-7 text-emerald-400" />
<span>کسب درآمد از هوشان</span> <span>کسب درآمد از هوشان</span>
</h2> </h2>
<div className="donya-divider"> <div className="donya-divider">
@ -42,55 +92,110 @@ export const MonetizationSection: React.FC = () => {
<span className="donya-divider-icon"></span> <span className="donya-divider-icon"></span>
<span className="donya-divider-line"></span> <span className="donya-divider-line"></span>
</div> </div>
<p className="text-slate-400 text-sm sm:text-base max-w-2xl mx-auto mt-3"> <p className="text-slate-700 text-sm sm:text-base max-w-2xl mx-auto mt-3 font-normal leading-relaxed">
شما میتوانید بهراحتی دستیارهای اختصاصی خود را طراحی کنید. این دستیارها میتوانند کاملاً مطابق با نیازها و علایق شما شخصیسازی شوند و منبع درآمد پایداری برای شما باشند. دستیارهای هوشمند اختصاصی خود را بسازید، آنها را در ویترین هوشان برای هزاران کاربر به اشتراک بگذارید و یک منبع درآمد پایدار و مستمر خلق کنید.
</p> </p>
</div> </div>
{/* Timeline Grid */} {/* 3 Step Visual Cards Grid */}
<div className="grid grid-cols-1 md:grid-cols-3 gap-6 relative z-10 mb-12"> <div className="grid grid-cols-1 md:grid-cols-3 gap-6 sm:gap-8 mb-12">
{steps.map((item, idx) => { {steps.map((item, idx) => (
const Icon = item.icon;
return (
<div <div
key={idx} key={idx}
className="glass-panel p-6 sm:p-8 rounded-2xl relative group hover:border-emerald-500/40 transition-all duration-300 hover:-translate-y-2 shadow-xl" className="model-card-premium flex flex-col justify-between shadow-xs hover:shadow-lg transition-all duration-300 group"
> >
<div className="flex items-center justify-between mb-5"> <div>
<div className="w-12 h-12 rounded-xl bg-emerald-500/10 border border-emerald-500/30 flex items-center justify-center text-emerald-400 group-hover:scale-110 transition-transform"> {/* Visual Image Header */}
<Icon className="w-6 h-6" /> <div className="relative h-48 sm:h-52 w-full bg-slate-50 overflow-hidden border-b border-slate-100 flex items-center justify-center p-4">
</div> <div className="relative w-32 h-32 sm:w-36 sm:h-36 rounded-2xl overflow-hidden shadow-sm group-hover:scale-105 transition-transform duration-500 bg-white border border-slate-200 p-2 flex items-center justify-center">
<span className="text-xs font-bold px-2.5 py-1 rounded-full bg-emerald-500/10 text-emerald-400 border border-emerald-500/20"> <img
گام {item.step} src={item.image}
</span> alt={item.title}
className="w-full h-full object-contain"
/>
</div> </div>
<h3 className="text-lg font-bold text-white mb-2 group-hover:text-emerald-300 transition-colors"> {/* Step Number Badge */}
<div className="absolute top-3.5 right-3.5 px-3 py-1 rounded-xl bg-white/95 text-[#272757] border border-slate-200/80 shadow-xs backdrop-blur-md text-xs font-black font-vazir">
گام {item.step}
</div>
{/* Tag Badge */}
<div className="absolute bottom-3 right-3.5">
<span className={`text-[10px] font-bold px-2.5 py-1 rounded-lg border shadow-xs backdrop-blur-md ${item.tagColor}`}>
{item.badge}
</span>
</div>
</div>
{/* Content */}
<div className="p-6 space-y-4">
<h3 className="text-xl font-black text-slate-900 font-vazir group-hover:text-[#54b4d3] transition-colors">
{item.title} {item.title}
</h3> </h3>
<p className="text-sm text-slate-400 leading-relaxed">
<p className="text-xs sm:text-sm text-slate-600 leading-relaxed font-normal min-h-[48px]">
{item.desc} {item.desc}
</p> </p>
<div className="mt-4 pt-4 border-t border-white/5 flex items-center gap-2 text-xs text-emerald-400/80 font-medium"> {/* Features List */}
<CheckCircle2 className="w-4 h-4" /> <div className="space-y-2 pt-3 border-t border-slate-100">
<span>{item.badge}</span> {item.features.map((feat, fIdx) => (
<div key={fIdx} className="flex items-center gap-2 text-xs text-slate-700 font-medium">
<div className="w-4 h-4 rounded-full bg-emerald-50 text-emerald-700 border border-emerald-200 flex items-center justify-center shrink-0">
<CheckCircle2 className="w-3 h-3 stroke-[2.5]" />
</div>
<span>{feat}</span>
</div>
))}
</div>
</div>
</div>
{/* Bottom Card Footer */}
<div className="p-4 bg-slate-50/60 border-t border-slate-100 flex items-center justify-between text-xs">
<span className="font-bold text-[#272757] flex items-center gap-1">
<Sparkles className="w-3.5 h-3.5 text-amber-500" />
<span>بدون هزینه زیرساخت</span>
</span>
<span className="text-slate-500 font-medium">فعالسازی آنی</span>
</div>
</div>
))}
</div>
{/* 3 Key Benefits Highlight Strip */}
<div className="p-6 sm:p-8 rounded-3xl bg-slate-50 border border-slate-200 mb-10 shadow-xs">
<div className="grid grid-cols-1 md:grid-cols-3 gap-6">
{highlights.map((h, i) => {
const Icon = h.icon;
return (
<div key={i} className="flex items-start gap-4">
<div className="w-12 h-12 rounded-2xl bg-white border border-slate-200 text-[#272757] shadow-xs flex items-center justify-center shrink-0">
<Icon className="w-6 h-6 text-[#54b4d3]" />
</div>
<div className="space-y-1">
<h4 className="text-sm sm:text-base font-bold text-slate-900">{h.title}</h4>
<p className="text-xs text-slate-600 leading-relaxed font-normal">{h.desc}</p>
</div> </div>
</div> </div>
); );
})} })}
</div> </div>
</div>
{/* Bottom CTA */} {/* Bottom CTA */}
<div className="text-center"> <div className="text-center">
<Link <a
to="/chat" href="https://web.houshan.ai"
className="btn-donya-primary inline-flex items-center gap-2 px-8 py-3.5 rounded-xl font-bold text-sm sm:text-base" target="_blank"
rel="noopener noreferrer"
className="inline-flex items-center gap-3 px-9 py-4 rounded-2xl bg-[#272757] hover:bg-[#373775] text-white font-bold text-sm sm:text-base shadow-md hover:shadow-lg transition-all group/btn cursor-pointer"
> >
<Sparkles className="w-5 h-5 text-emerald-300" /> <Sparkles className="w-5 h-5 text-amber-300 group-hover/btn:rotate-12 transition-transform" />
<span>شروع ساخت دستیار و کسب درآمد</span> <span>شروع ساخت دستیار و کسب درآمد در هوشان</span>
<ArrowLeft className="w-4 h-4" /> <ArrowLeft className="w-4 h-4 group-hover/btn:-translate-x-1 transition-transform" />
</Link> </a>
</div> </div>
</div> </div>

Some files were not shown because too many files have changed in this diff Show More