Initial commit
This commit is contained in:
1
.env.production
Normal file
1
.env.production
Normal file
@@ -0,0 +1 @@
|
||||
DISABLE_ESLINT_PLUGIN=true
|
||||
62
.gitea/workflows/build.yml
Normal file
62
.gitea/workflows/build.yml
Normal file
@@ -0,0 +1,62 @@
|
||||
name: Build
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
branch:
|
||||
description: 'Branch to build'
|
||||
required: true
|
||||
default: 'main'
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 10
|
||||
|
||||
steps:
|
||||
- name: Checkout branch
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
ref: ${{ gitea.event.inputs.branch }}
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 24
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
set -euo pipefail
|
||||
npm install --no-audit --silent 2>&1 | tee install.log
|
||||
env:
|
||||
NODE_OPTIONS: '--max-old-space-size=4096'
|
||||
|
||||
- name: Build (react-scripts build)
|
||||
env:
|
||||
CI: 'false'
|
||||
NODE_OPTIONS: '--max-old-space-size=4096'
|
||||
run: |
|
||||
set -euo pipefail
|
||||
npm run build 2>&1 | tee build.log
|
||||
timeout-minutes: 5
|
||||
|
||||
- name: Verify build folder exists
|
||||
run: test -d build || (echo "No build folder. Check build logs above."; exit 1)
|
||||
|
||||
- name: Upload logs on failure
|
||||
if: failure()
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: build-logs
|
||||
path: |
|
||||
install.log
|
||||
build.log
|
||||
npm-debug.log*
|
||||
if-no-files-found: ignore
|
||||
|
||||
- name: Build completed
|
||||
if: success()
|
||||
run: echo "Build completed successfully"
|
||||
41
package.json
Normal file
41
package.json
Normal file
@@ -0,0 +1,41 @@
|
||||
{
|
||||
"name": "nestjs-enterprise",
|
||||
"version": "0.1.0",
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"react": "^18.3.1",
|
||||
"react-dom": "^18.3.1",
|
||||
"react-scripts": "^5.0.1",
|
||||
"lucide-react": "^0.400.0",
|
||||
"framer-motion": "^11.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"tailwindcss": "^3.4.0",
|
||||
"postcss": "^8.4.0",
|
||||
"autoprefixer": "^10.4.0"
|
||||
},
|
||||
"scripts": {
|
||||
"start": "react-scripts start",
|
||||
"build": "react-scripts build",
|
||||
"test": "react-scripts test",
|
||||
"eject": "react-scripts eject"
|
||||
},
|
||||
"eslintConfig": {
|
||||
"extends": [
|
||||
"react-app",
|
||||
"react-app/jest"
|
||||
]
|
||||
},
|
||||
"browserslist": {
|
||||
"production": [
|
||||
">0.2%",
|
||||
"not dead",
|
||||
"not op_mini all"
|
||||
],
|
||||
"development": [
|
||||
"last 1 chrome version",
|
||||
"last 1 firefox version",
|
||||
"last 1 safari version"
|
||||
]
|
||||
}
|
||||
}
|
||||
6
postcss.config.js
Normal file
6
postcss.config.js
Normal file
@@ -0,0 +1,6 @@
|
||||
module.exports = {
|
||||
plugins: {
|
||||
tailwindcss: {},
|
||||
autoprefixer: {},
|
||||
},
|
||||
}
|
||||
1
public/images/adidas.718f26f2-1768394101243.svg
Normal file
1
public/images/adidas.718f26f2-1768394101243.svg
Normal file
@@ -0,0 +1 @@
|
||||
PHN2ZyB2aWV3Qm94PSIwIDAgMTAwIDY4IiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGZpbGwtcnVsZT0iZXZlbm9kZCIgY2xpcC1ydWxlPSJldmVub2RkIiBzdHJva2UtbGluZWpvaW49InJvdW5kIiBzdHJva2UtbWl0ZXJsaW1pdD0iMS40MTQiPjxwYXRoIGZpbGw9IiMzMzMiIGQ9Ik00OS43MzUgNTguMzVhNC44MjMgNC44MjMgMCAwIDEgNC44MzgtNC44MzggNC44MjIgNC44MjIgMCAwIDEgNC44MzcgNC44MzggNC44MjIgNC44MjIgMCAwIDEtNC44MzcgNC44MzggNC44MjMgNC44MjMgMCAwIDEtNC44MzgtNC44MzhtMTkuNjgyIDBhNC44MjMgNC44MjMgMCAwIDEgNC44MzgtNC44MzggNC44MjIgNC44MjIgMCAwIDEgNC44MzcgNC44MzggNC44MjIgNC44MjIgMCAwIDEtNC44MzcgNC44MzggNC44MjMgNC44MjMgMCAwIDEtNC44MzgtNC44MzhtLTQ1LjYyNiAwYTQuODIyIDQuODIyIDAgMCAxIDQuODM4LTQuODM4IDQuODIyIDQuODIyIDAgMCAxIDQuODM3IDQuODM4IDQuODIyIDQuODIyIDAgMCAxLTQuODM3IDQuODM4IDQuODIyIDQuODIyIDAgMCAxLTQuODM4LTQuODM4bS0xOS42ODIgMGE0LjgyMiA0LjgyMiAwIDAgMSA0LjgzNy00LjgzOCA0LjgyMiA0LjgyMiAwIDAgMSA0LjgzOCA0LjgzOCA0LjgyMiA0LjgyMiAwIDAgMS00LjgzOCA0LjgzOCA0LjgyMiA0LjgyMiAwIDAgMS00LjgzNy00LjgzOG0zOS43OTQtOC41NDloLTQuMjA4djE2LjkzMmg0LjIwOFY0OS44MDF6TTEzLjc1MSA2Ni43MzNoNC4yMDhWNDkuODAxaC00LjIwOHYxLjM1OWE4LjY5OCA4LjY5OCAwIDAgMC01LjAwMy0xLjU1N0E4LjczOSA4LjczOSAwIDAgMCAwIDU4LjM1YTguNzE4IDguNzE4IDAgMCAwIDguNzQ4IDguNzQ3IDguNjk4IDguNjk4IDAgMCAwIDUuMDAzLTEuNTU3djEuMTkzem02NS4zMDggMGg0LjIwOFY0OS44MDFoLTQuMjA4djEuMzU5YTguNjk4IDguNjk4IDAgMCAwLTUuMDAzLTEuNTU3IDguNzM4IDguNzM4IDAgMCAwLTguNzQ3IDguNzQ3IDguNzE3IDguNzE3IDAgMCAwIDguNzQ3IDguNzQ3IDguNjk4IDguNjk4IDAgMCAwIDUuMDAzLTEuNTU3djEuMTkzem01Ljc2Ni01LjUwMWMuMTMyIDMuNDEzIDMuMDQ4IDUuODMyIDcuOTE5IDUuODMyIDMuOTc2IDAgNy4yNTYtMS43MjMgNy4yNTYtNS41MzMgMC0yLjY1MS0xLjQ5MS00LjIwOC00LjkzNy00Ljg3MWwtMi42ODQtLjUzYy0xLjcyMy0uMzMxLTIuOTE2LS42NjMtMi45MTYtMS42OSAwLTEuMTI2IDEuMTYtMS42MjMgMi42MTgtMS42MjMgMi4xMjEgMCAyLjk4MiAxLjA2IDMuMDQ4IDIuMzE5aDQuMjQyYy0uMjMyLTMuMzE0LTIuODgzLTUuNTMzLTcuMTU3LTUuNTMzLTQuNDA3IDAtNy4wMjUgMi40MTgtNy4wMjUgNS41NjYgMCAzLjg0NCAzLjExNSA0LjQ3MyA1Ljc5OSA0Ljk3bDIuMjIuMzk4YzEuNTkuMjk4IDIuMjg2Ljc2MiAyLjI4NiAxLjY5IDAgLjgyOC0uNzk1IDEuNjU2LTIuNjg0IDEuNjU2LTIuNzUgMC0zLjY0NS0xLjQyNC0zLjY3OC0yLjY1MWgtNC4zMDd6TTMzLjQzMyA0NC4wMzZ2Ny4xMjRhOC42OTggOC42OTggMCAwIDAtNS4wMDMtMS41NTcgOC43MzkgOC43MzkgMCAwIDAtOC43NDggOC43NDcgOC43MTggOC43MTggMCAwIDAgOC43NDggOC43NDcgOC42OTggOC42OTggMCAwIDAgNS4wMDMtMS41NTd2MS4xOTNoNC4yMDhWNDQuMDM2aC00LjIwOHptMjUuOTQ0IDB2Ny4xMjRhOC42OTggOC42OTggMCAwIDAtNS4wMDMtMS41NTcgOC43MzggOC43MzggMCAwIDAtOC43NDcgOC43NDcgOC43MTcgOC43MTcgMCAwIDAgOC43NDcgOC43NDcgOC42OTggOC42OTggMCAwIDAgNS4wMDMtMS41NTd2MS4xOTNoNC4yMDhWNDQuMDM2aC00LjIwOHptLTQ4LjQ0My01LjAwM2wyLjg1IDUuMDAzaDE5LjY0OWwtNy43ODctMTMuNDUzLTE0LjcxMiA4LjQ1em0zMi45NjkgOS4yMTF2LTQuMjA4aDE1LjQ3NEw0Mi44NzYgMTUuNDc0bC0xNC43NDUgOC40NDkgMTEuNTY0IDIwLjExM3Y0LjIwOGg0LjIwOHptMjEuNzM3LTQuMjA4aDE5LjY4Mkw1OS44NzQgMCA0NS4xNjMgOC40ODIgNjUuNjQgNDQuMDM2eiIgZmlsbC1ydWxlPSJub256ZXJvIi8+PC9zdmc+
|
||||
File diff suppressed because one or more lines are too long
1
public/images/autodesk.a7f2b58e-1768394101281.png
Normal file
1
public/images/autodesk.a7f2b58e-1768394101281.png
Normal file
File diff suppressed because one or more lines are too long
1
public/images/big-data.88454030-1768394101375.svg
Normal file
1
public/images/big-data.88454030-1768394101375.svg
Normal file
File diff suppressed because one or more lines are too long
1
public/images/bmw.0ce4c05c-1768394101264.svg
Normal file
1
public/images/bmw.0ce4c05c-1768394101264.svg
Normal file
File diff suppressed because one or more lines are too long
1
public/images/capgemini.a1d43b77-1768394101309.svg
Normal file
1
public/images/capgemini.a1d43b77-1768394101309.svg
Normal file
File diff suppressed because one or more lines are too long
1
public/images/conversation.2689303c-1768394101310.svg
Normal file
1
public/images/conversation.2689303c-1768394101310.svg
Normal file
File diff suppressed because one or more lines are too long
1
public/images/decathlon.1f3c4744-1768394101274.png
Normal file
1
public/images/decathlon.1f3c4744-1768394101274.png
Normal file
File diff suppressed because one or more lines are too long
1
public/images/favicon-16x16.c832ad73-1768394101375.png
Normal file
1
public/images/favicon-16x16.c832ad73-1768394101375.png
Normal file
@@ -0,0 +1 @@
|
||||
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAABLFBMVEUAAADgI07hI07gJU3gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07///8RYHHZAAAAYnRSTlMAAAAACEkrDQEDBorPkwoZa6CunnGy9UW+/v36XR4EMYnY2US0O5TXeqUHx+706Ok2M18wPoPk/G5B3otmghqiNQle3/FULpac8tuXrdVYqPnwjCJSTh1I07OdtoY0KRQ4ApuOtd0AAAABYktHRGNcvi2qAAAAB3RJTUUH5QIECQU6y1Xy3gAAANBJREFUGNNjYIAARhZWNnZGJgiHmZGDk4OLm4eXjxEsx8gvICgkLCKaJCbOCOazSUgmJSVJSSdJycjKMTLIKygmQYGSsooqI4MajCuprqGZpKnFwKYtraML0iOppy+ZpGfAwGhoZGxiagZVZm4BNJSDkZHR0goqYg22h0WO0cYcImALErCzd3B00ncGCkm5uIIE3PTcPTy9vKWSkpw97EACfD5J5r5+/kkBgUGyHGAzgkNCw8IjpCKjghkZYZ7lZI2OiY2D85kY410T5BI5gHwAqtoq4cCuYkgAAAAldEVYdGRhdGU6Y3JlYXRlADIwMjEtMDItMDRUMDk6MDU6NTgrMDE6MDAZPq6OAAAAJXRFWHRkYXRlOm1vZGlmeQAyMDIxLTAyLTA0VDA5OjA1OjU4KzAxOjAwaGMWMgAAAFd6VFh0UmF3IHByb2ZpbGUgdHlwZSBpcHRjAAB4nOPyDAhxVigoyk/LzEnlUgADIwsuYwsTIxNLkxQDEyBEgDTDZAMjs1Qgy9jUyMTMxBzEB8uASKBKLgDqFxF08kI1lQAAAABJRU5ErkJggg==
|
||||
1
public/images/favicon-32x32.0a29681d-1768394101374.png
Normal file
1
public/images/favicon-32x32.0a29681d-1768394101374.png
Normal file
@@ -0,0 +1 @@
|
||||
iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAMAAABEpIrGAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAACEFBMVEUAAADgI07gJ0rgI0/gIk7fJE/gJE7gHk/gIk/hIE/hI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07gI07///+TdNRjAAAArnRSTlMAAAAAAAAAAAAAAAIVBwSBkyBDDV7bf+umHm6p5KoFIURgb19CCmnj+FUBNZ3h9/723qeI8Zlh5fuxZe6ePxtF85TOH3nc9bsRLuCPAz7s/b0puTr80II8mlLt0uIm8mKAcUZAUHq8mxI3C0vCwRmg1hqsLN3XHMQPXatONGsGE5zLuvpWhDPf9LTHKMaMhpcxWlEj8KOR+QhMou+2rc2/fmevVHXaEDiFrm0iJQldRelWAAAAAWJLR0SvzmyjMQAAAAd0SU1FB+UCBAkFOstV8t4AAAH4SURBVDjLY2BAA4zcPLyMjAy4ASMfv4CgkDBuNYyMIqJi4hKSOFUwMkpJy6xbJyuMqoCJUU5eQVFJSVlFUlVNfd26dRqaKEYwamnr6Orpr1unb2BoZGwCVLDOlBlJASO3mfk6OLDQB5GWfNxaMCWMclbW69CBDaOKLdgWRj47ex0HDHkLZUZHJ2eQAl4XV7d1mMDdw9NrnbcPUIWvHxZp/4BAwaB168SDGVkYgtUxpENCw8LNnECsCKARWpFRGPplomUswKyYWEagF8Li1ulrGFhgsWmdfjzQEYy8CU6JSckpqWmYflmXrgUK/IxMoFWMjFnZOfroCnKFUaIpL98fTUFBIXKMsTJmFKEpcBVEi+riElQFpWUIOW5GkEMSUBWUV8ATWmVVNSMjI1uN+Do3pIDR0YIpyBRfV8tYV6/WILqusQkq2+ygrwiP8Rb/da18bd7t+s3rXGShCtoDXAXhCmr81nV0doGCM6e7B6pAtrcPnu4Y6/qhoqETtKMg6ap54qTJ8GTHqGUFTolTpgZyTwPLd03PrZ+hhVDAzjOzb5ZNavAMxkmzQQE+R2B2NlrW4ODU0mJk1Ep2nzsP6P/g+Qt8sGUdRrlA54WzQxZNXpygijVrcTGqLpm9NHHZjOXY5Rm1YlesXCWoxailhT1rMvqsXrMW1W0AHSM0aNKRcBcAAAAldEVYdGRhdGU6Y3JlYXRlADIwMjEtMDItMDRUMDk6MDU6NTgrMDE6MDAZPq6OAAAAJXRFWHRkYXRlOm1vZGlmeQAyMDIxLTAyLTA0VDA5OjA1OjU4KzAxOjAwaGMWMgAAAFd6VFh0UmF3IHByb2ZpbGUgdHlwZSBpcHRjAAB4nOPyDAhxVigoyk/LzEnlUgADIwsuYwsTIxNLkxQDEyBEgDTDZAMjs1Qgy9jUyMTMxBzEB8uASKBKLgDqFxF08kI1lQAAAABJRU5ErkJggg==
|
||||
1
public/images/gitlab.4f9d2995-1768394101261.png
Normal file
1
public/images/gitlab.4f9d2995-1768394101261.png
Normal file
File diff suppressed because one or more lines are too long
1
public/images/header-2.50296714-1768394101471.jpg
Normal file
1
public/images/header-2.50296714-1768394101471.jpg
Normal file
File diff suppressed because one or more lines are too long
1
public/images/hired.123ab98d-1768394101309.svg
Normal file
1
public/images/hired.123ab98d-1768394101309.svg
Normal file
File diff suppressed because one or more lines are too long
1
public/images/ibm.b8c76e06-1768394101296.svg
Normal file
1
public/images/ibm.b8c76e06-1768394101296.svg
Normal file
File diff suppressed because one or more lines are too long
1
public/images/image-28-1768394101423.png
Normal file
1
public/images/image-28-1768394101423.png
Normal file
File diff suppressed because one or more lines are too long
1
public/images/jetbrains.536f2da5-1768394101295.svg
Normal file
1
public/images/jetbrains.536f2da5-1768394101295.svg
Normal file
@@ -0,0 +1 @@
|
||||
PHN2ZyBoZWlnaHQ9IjE4MCIgdmlld0JveD0iMCAwIDE4MCAxODAiIHdpZHRoPSIxODAiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiPjxsaW5lYXJHcmFkaWVudCBpZD0iYSIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiIHgxPSIzMi42NCIgeDI9IjgyLjc3IiB5MT0iNjEuMTYiIHkyPSI4NS41NCI+PHN0b3Agb2Zmc2V0PSIuMjEiIHN0b3AtY29sb3I9IiNmZTI4NTciLz48c3RvcCBvZmZzZXQ9IjEiIHN0b3AtY29sb3I9IiMyOTM4OTYiLz48L2xpbmVhckdyYWRpZW50PjxsaW5lYXJHcmFkaWVudCBpZD0iYiIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiIHgxPSIxNy4zOCIgeDI9IjgyLjk1IiB5MT0iNjkuODYiIHkyPSIyMS4yMyI+PHN0b3Agb2Zmc2V0PSIwIiBzdG9wLWNvbG9yPSIjZmUyODU3Ii8+PHN0b3Agb2Zmc2V0PSIuMDEiIHN0b3AtY29sb3I9IiNmZTI4NTciLz48c3RvcCBvZmZzZXQ9Ii44NiIgc3RvcC1jb2xvcj0iI2ZmMzE4YyIvPjwvbGluZWFyR3JhZGllbnQ+PGxpbmVhckdyYWRpZW50IGlkPSJjIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9Ijc0LjE3IiB4Mj0iMTYwLjI3IiB5MT0iMjEuNTgiIHkyPSI5OS43NiI+PHN0b3Agb2Zmc2V0PSIuMDIiIHN0b3AtY29sb3I9IiNmZjMxOGMiLz48c3RvcCBvZmZzZXQ9Ii4yMSIgc3RvcC1jb2xvcj0iI2ZlMjg1NyIvPjxzdG9wIG9mZnNldD0iLjg2IiBzdG9wLWNvbG9yPSIjZmRiNjBkIi8+PC9saW5lYXJHcmFkaWVudD48bGluZWFyR3JhZGllbnQgaWQ9ImQiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIiB4MT0iMTU1LjQ2IiB4Mj0iNTUuMDciIHkxPSI4OS44IiB5Mj0iMTU4LjkiPjxzdG9wIG9mZnNldD0iLjAxIiBzdG9wLWNvbG9yPSIjZmRiNjBkIi8+PHN0b3Agb2Zmc2V0PSIuODYiIHN0b3AtY29sb3I9IiNmY2Y4NGEiLz48L2xpbmVhckdyYWRpZW50PjxwYXRoIGQ9Im04MS41NiA4My43MS00MS4zNS0zNWExNSAxNSAwIDEgMCAtMTQuNDcgMjUuN2guMTVsLjM5LjEyIDUyLjE2IDE1Ljg5YTMuNTMgMy41MyAwIDAgMCAxLjE4LjIxIDMuNzMgMy43MyAwIDAgMCAxLjkzLTYuOTF6IiBmaWxsPSJ1cmwoI2EpIi8+PHBhdGggZD0ibTg5Ljg1IDI1LjkzYTEwLjg5IDEwLjg5IDAgMCAwIC0xNi44NS05LjE4bC01MC41IDMwLjY2YTE1IDE1IDAgMSAwIDE3LjkgMjRsNDUuMjctMzYuODkuMzYtLjNhMTAuOTMgMTAuOTMgMCAwIDAgMy44Mi04LjI5eiIgZmlsbD0idXJsKCNiKSIvPjxwYXRoIGQ9Im0xNjMuMjkgOTItNzYuNjItNzMuNzlhMTAuOTEgMTAuOTEgMCAxIDAgLTE0LjgxIDE2bC4xNC4xMiA4MS40IDY4LjU4YTcuMzYgNy4zNiAwIDAgMCAxMi4wOS01LjY1IDcuMzkgNy4zOSAwIDAgMCAtMi4yLTUuMjZ6IiBmaWxsPSJ1cmwoI2MpIi8+PHBhdGggZD0ibTE2NS41IDk3LjI5YTcuMzUgNy4zNSAwIDAgMCAtMTEuNjctNmwtOTIuNzEgNDUuM2ExNSAxNSAwIDEgMCAxNS40OCAyNS41OWw4NS43My01OC44NGE3LjM1IDcuMzUgMCAwIDAgMy4xNy02LjA1eiIgZmlsbD0idXJsKCNkKSIvPjxwYXRoIGQ9Im02MCA2MGg2MHY2MGgtNjB6Ii8+PGcgZmlsbD0iI2ZmZiI+PHBhdGggZD0ibTY2LjUzIDEwOC43NWgyMi41djMuNzVoLTIyLjV6Ii8+PHBhdGggZD0ibTY1LjU5IDc1LjQ3IDEuNjctMS41OGExLjg4IDEuODggMCAwIDAgMS40Ny44N2MuNjQgMCAxLjA2LS40NSAxLjA2LTEuMzJ2LTUuOTJoMi41OHY1Ljk0YTMuNDQgMy40NCAwIDAgMSAtLjkyIDIuNjMgMy41MiAzLjUyIDAgMCAxIC0yLjU3IDEgMy44NCAzLjg0IDAgMCAxIC0zLjI5LTEuNjJ6Ii8+PHBhdGggZD0ibTczLjUzIDY3LjUyaDcuNTN2Mi4xOWgtNXYxLjQzaDQuNDl2MmgtNC40NXYxLjQ5aDV2Mi4yaC03LjZ6Ii8+PHBhdGggZD0ibTg0LjczIDY5Ljc5aC0yLjh2LTIuMjdoOC4yMXYyLjI3aC0yLjgxdjcuMDloLTIuNnoiLz48cGF0aCBkPSJtNjYuNjMgODAuNThoNC40MmEzLjQ3IDMuNDcgMCAwIDEgMi41NS44MyAyLjA5IDIuMDkgMCAwIDEgLjYxIDEuNTIgMi4xOCAyLjE4IDAgMCAxIC0xLjQ1IDIuMDkgMi4yNyAyLjI3IDAgMCAxIDEuODYgMi4yOWMwIDEuNjktMS4zMSAyLjY5LTMuNTUgMi42OWgtNC40NHptNSAyLjg5YzAtLjUyLS40Mi0uOC0xLjE4LS44aC0xLjI5djEuNjRoMS4yNWMuNzggMCAxLjI0LS4yNyAxLjI0LS44MXptLS45IDIuNjZoLTEuNTd2MS43M2gxLjYyYy44IDAgMS4yNC0uMzEgMS4yNC0uODYtLjAyLS41My0uNC0uODctMS4yNy0uODd6Ii8+PHBhdGggZD0ibTc1LjQ1IDgwLjU4aDQuMTVhNC4xNCA0LjE0IDAgMCAxIDMuMDUgMSAyLjkyIDIuOTIgMCAwIDEgLjgzIDIuMTggMyAzIDAgMCAxIC0xLjkzIDIuODlsMi4yNCAzLjM1aC0zbC0xLjg5LTIuODRoLS44N3YyLjg0aC0yLjZ6bTQgNC41Yy44NyAwIDEuNC0uNDMgMS40LTEuMTIgMC0uNzUtLjU1LTEuMTMtMS40MS0xLjEzaC0xLjM5djIuMjd6Ii8+PHBhdGggZD0ibTg3LjA5IDgwLjUxaDIuNWw0IDkuNDRoLTIuNzlsLS42Ny0xLjY5aC0zLjYzbC0uNjcgMS43NGgtMi43MXptMi4yOCA1LjczLTEuMDUtMi42NS0xLjA2IDIuNjV6Ii8+PHBhdGggZD0ibTk0IDgwLjU1aDIuNnY5LjM3aC0yLjZ6Ii8+PHBhdGggZD0ibTk3LjU2IDgwLjU1aDIuNDRsMy4zNyA1di01aDIuNTd2OS4zN2gtMi4yN2wtMy41My01LjE0djUuMTRoLTIuNTh6Ii8+PHBhdGggZD0ibTEwNi4zNyA4OC41MyAxLjQ0LTEuNzNhNC44NiA0Ljg2IDAgMCAwIDMgMS4xM2MuNzEgMCAxLjA4LS4yNSAxLjA4LS42NSAwLS40MS0uMy0uNjEtMS41OS0uOTEtMi0uNDYtMy41My0xLTMuNTMtMi45MyAwLTEuNzQgMS4zOC0zIDMuNjMtM2E1Ljg4IDUuODggMCAwIDEgMy44NSAxLjI1bC0xLjI1IDEuNzhhNC41NiA0LjU2IDAgMCAwIC0yLjYyLS45MmMtLjYzIDAtLjk0LjI1LS45NC42IDAgLjQzLjMyLjYyIDEuNjMuOTEgMi4xNS40NyAzLjQ4IDEuMTcgMy40OCAyLjkyIDAgMS45MS0xLjUxIDMtMy43OCAzYTYuNTYgNi41NiAwIDAgMSAtNC40LTEuNDV6Ii8+PC9nPjxwYXRoIGQ9Im0wIDBoMTgwdjE4MGgtMTgweiIgZmlsbD0ibm9uZSIvPjwvc3ZnPg==
|
||||
File diff suppressed because one or more lines are too long
1
public/images/mercedes.ee8047a9-1768394101351.png
Normal file
1
public/images/mercedes.ee8047a9-1768394101351.png
Normal file
File diff suppressed because one or more lines are too long
1
public/images/protect.5939735a-1768394101376.svg
Normal file
1
public/images/protect.5939735a-1768394101376.svg
Normal file
File diff suppressed because one or more lines are too long
1
public/images/puzzle.a43aa4b7-1768394101375.svg
Normal file
1
public/images/puzzle.a43aa4b7-1768394101375.svg
Normal file
File diff suppressed because one or more lines are too long
1
public/images/red-hat.c5e6e64a-1768394101265.svg
Normal file
1
public/images/red-hat.c5e6e64a-1768394101265.svg
Normal file
@@ -0,0 +1 @@
|
||||
PHN2ZyBpZD0iYjZiZGQyYjQtNTJhYi00ODhhLTlhMzAtMWU2ZDFkN2RkMmQ0IiBkYXRhLW5hbWU9IkxheWVyIDEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgdmlld0JveD0iMCAwIDYxMS44IDE0NCI+PGRlZnM+PHN0eWxlPi5hNzM3NDU5Yy1lOGM3LTRhZmEtODAwOC1mNmNmZDE1Y2NkYTJ7ZmlsbDojZTAwO308L3N0eWxlPjwvZGVmcz48cGF0aCBkPSJNNTc5LjMsOTIuM2MwLDExLjksNy4yLDE3LjcsMjAuMiwxNy43YTUzLjM5LDUzLjM5LDAsMCwwLDExLjktMS43Vjk0LjVhMjUuMjcsMjUuMjcsMCwwLDEtNy43LDEuMmMtNS40LDAtNy40LTEuNy03LjQtNi43VjY3LjhoMTUuNlY1My42SDU5Ni4zdi0xOGwtMTcsMy43VjUzLjZINTY4VjY3LjhoMTEuMmwuMSwyNC41Wm0tNTMsLjNjMC0zLjcsMy43LTUuNSw5LjMtNS41YTM4LjM1LDM4LjM1LDAsMCwxLDEwLjEsMS4zdjcuMmEyMC44MiwyMC44MiwwLDAsMS0xMC42LDIuNmMtNS41LDAtOC44LTIuMS04LjgtNS42bTUuMiwxNy42YTI2LjY5LDI2LjY5LDAsMCwwLDE1LjQtNC4zdjMuNGgxNi44VjczLjZjMC0xMy42LTkuMS0yMS0yNC40LTIxLTguNSwwLTE2LjksMi0yNiw2LjFsNi4xLDEyLjVjNi41LTIuNywxMi00LjQsMTYuOC00LjQsNywwLDEwLjYsMi43LDEwLjYsOC4zdjIuN2E0OC45Miw0OC45MiwwLDAsMC0xMi42LTEuNmMtMTQuMywwLTIyLjksNi0yMi45LDE2LjcsMCw5LjgsNy44LDE3LjMsMjAuMiwxNy4zbS05Mi40LS45aDE4LjFWODAuNGgzMC4zdjI4LjhoMTguMVYzNS42SDQ4Ny41VjYzLjlINDU3LjJWMzUuNkg0MzkuMVpNMzcwLjIsODEuNGMwLTgsNi4zLTE0LjEsMTQuNi0xNC4xYTE3LjcyLDE3LjcyLDAsMCwxLDExLjgsNC4zVjkxLjFhMTYuNjIsMTYuNjIsMCwwLDEtMTEuOCw0LjVjLTguMi0uMS0xNC42LTYuMi0xNC42LTE0LjJtMjYuNiwyNy45aDE2LjhWMzEuOWwtMTcsMy43VjU2LjVhMjguMTQsMjguMTQsMCwwLDAtMTQuMi0zLjdjLTE2LjIsMC0yOC45LDEyLjUtMjguOSwyOC41YTI4LjI1LDI4LjI1LDAsMCwwLDI3LjksMjguNmguNWEyNS40NiwyNS40NiwwLDAsMCwxNC45LTQuOFpNMzE5LjYsNjYuNWM1LjQsMCw5LjksMy41LDExLjcsOC44SDMwOC4xYTExLjU2LDExLjU2LDAsMCwxLDExLjUtOC44bS0yOC43LDE1YzAsMTYuMiwxMy4yLDI4LjgsMzAuMywyOC44LDkuNCwwLDE2LjItMi41LDIzLjItOC40bC0xMS4zLTEwYy0yLjYsMi43LTYuNSw0LjItMTEuMSw0LjJhMTQuMzcsMTQuMzcsMCwwLDEtMTMuNy04LjhoMzkuNlY4My4xYzAtMTcuNy0xMS45LTMwLjQtMjguMS0zMC40YTI4LjU4LDI4LjU4LDAsMCwwLTI5LDI4LjEsMS40OCwxLjQ4LDAsMCwxLC4xLjdNMjYxLjYsNTEuMWM2LDAsOS40LDMuOCw5LjQsOC4zcy0zLjQsOC4zLTkuNCw4LjNIMjQzLjdWNTEuMVptLTM2LDU4LjFoMTguMVY4Mi40aDEzLjhsMTMuOSwyNi44aDIwLjJMMjc1LjQsNzkuN0EyMi4zMiwyMi4zMiwwLDAsMCwyODkuMyw1OWMwLTEzLjItMTAuNC0yMy41LTI2LTIzLjVIMjI1LjZ2NzMuN1oiIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0wLjEpIi8+PHBhdGggY2xhc3M9ImE3Mzc0NTljLWU4YzctNGFmYS04MDA4LWY2Y2ZkMTVjY2RhMiIgZD0iTTEyNy4xLDgzYzEyLjUsMCwzMC42LTIuNiwzMC42LTE3LjVhMTkuNTMsMTkuNTMsMCwwLDAtLjMtMy40TDE1MCwyOS43Yy0xLjctNy4xLTMuMi0xMC40LTE1LjctMTYuNkMxMjQuNiw4LjEsMTAzLjUsMCw5Ny4yLDBjLTUuOSwwLTcuNiw3LjUtMTQuNSw3LjVDNzYsNy41LDcxLjEsMS45LDY0LjgsMS45Yy02LDAtOS45LDQuMS0xMi45LDEyLjUsMCwwLTguNCwyMy43LTkuNSwyNy4yYTYuMTUsNi4xNSwwLDAsMC0uMiwxLjljLS4xLDkuMiwzNi4yLDM5LjQsODQuOSwzOS41bTMyLjUtMTEuNGMxLjcsOC4yLDEuNyw5LjEsMS43LDEwLjEsMCwxNC0xNS43LDIxLjgtMzYuNCwyMS44LTQ2LjgsMC04Ny43LTI3LjQtODcuNy00NS41YTE4LjM1LDE4LjM1LDAsMCwxLDEuNS03LjNDMjEuOSw1MS41LjEsNTQuNS4xLDczLjcuMSwxMDUuMiw3NC43LDE0NCwxMzMuNywxNDRjNDUuMywwLDU2LjctMjAuNSw1Ni43LTM2LjcsMC0xMi43LTExLTI3LjEtMzAuOC0zNS43IiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgtMC4xKSIvPjxwYXRoIGQ9Ik0xNTkuNiw3MS42YzEuNyw4LjIsMS43LDkuMSwxLjcsMTAuMSwwLDE0LTE1LjcsMjEuOC0zNi40LDIxLjgtNDYuOCwwLTg3LjctMjcuNC04Ny43LTQ1LjVhMTguMzUsMTguMzUsMCwwLDEsMS41LTcuM2wzLjctOS4xYTYuMTUsNi4xNSwwLDAsMC0uMiwxLjljMCw5LjIsMzYuMywzOS40LDg0LjksMzkuNCwxMi41LDAsMzAuNi0yLjYsMzAuNi0xNy41YTE5LjUzLDE5LjUzLDAsMCwwLS4zLTMuNFoiIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0wLjEpIi8+PC9zdmc+
|
||||
1
public/images/rewe.1250e1e4-1768394101296.svg
Normal file
1
public/images/rewe.1250e1e4-1768394101296.svg
Normal file
@@ -0,0 +1 @@
|
||||
PHN2ZyBpZD0iX2RldmVsb3BtZW50LS1hc3NldHMtLWltZy0tX3N2Zy1zcHJpdGVzLS1yZXdlLWRpZ2l0YWwiIHZpZXdCb3g9IjAgMCAyMTAgMzcuNjIiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSI+PHBhdGggY2xhc3M9ImJtc3QwIiBkPSJNMTMuOTcgMjkuMzFsLTMuMDctOC4xMmMtMS4xNC0zLjAyLTEuNzgtMy40Mi0zLjQyLTMuNDJ2MTEuNTRIMFYuMTloMTAuMDFjOC41NyAwIDExLjM0IDMuNDcgMTEuMzQgOC4zMiAwIDUtMi42MyA3LjU3LTYuMDQgOC4xMi45OS4zIDIuMTggMS42MyAyLjkyIDMuMTcuOTQgMS45MyAzLjQxIDcuMzMgNC4zNSA5LjUxaC04LjYxek03LjQ4IDYuMzR2NS45NGgyLjEzYzIuNTIgMCAzLjQxLTEuMjQgMy40MS0zLjE3IDAtMi4wOC0xLjE0LTIuNzctMy40Ny0yLjc3SDcuNDh6TTI1LjcxIDI5LjMxVi4xOWgxNi4zNHY2LjE1aC04Ljg3djQuOWg3LjI0djUuOTNoLTcuMjR2NS45aDkuOTZ2Ni4yNHpNNzMuMzEgMjkuMzFoLTcuOTdsLTEuNDktOC40MmMtLjY0LTMuNTItMS4yOS03LjMzLTEuNDMtOS4xNmgtLjA1Yy0uMDYgMS40My0uNyA1LjM0LTEuMzkgOS4xNmwtMS41NCA4LjQyaC04LjE3TDQ0LjE4LjE5aDcuOTJsMS42MyA3Ljg3YzEuMzkgNi41NCAxLjY0IDkuMzYgMS42OSAxMC40NS4yLTIuMzMuNjktNS45NCAxLjQ4LTEwLjI1TDU4LjM5LjE5aDguMzJsMS44OSA5Ljc2Yy40NCAyLjE4Ljk5IDUgMS4xOSA4LjU2aC4wNWMuMTUtMi42MyAxLjA0LTguMjYgMS41OC0xMS4wOUw3Mi45MS4xOWg3Ljk3bC03LjU3IDI5LjEyek04Mi45NiAyOS4zMVYuMTloMTYuMzl2Ni4xNWgtOC45MXY0LjloNy4yOHY1LjkzaC03LjI4djUuOWgxMHY2LjI0eiI+PC9wYXRoPjxwYXRoIGNsYXNzPSJibXN0MSIgZD0iTTIwNy4yMy4xOUgyMTBWMjkuM2gtMi43N3pNMTkyLjk3IDI2LjkzYy00LjgxIDAtOC43Mi0zLjkxLTguNzItOC43MSAwLTQuOCAzLjkxLTguNzEgOC43Mi04LjcxIDQuOCAwIDguNzEgMy45MSA4LjcxIDguNzEgMCA0LjgtMy45MSA4LjcxLTguNzEgOC43MXptMC0yMC4yYy02LjM0IDAtMTEuNDkgNS4xNS0xMS40OSAxMS40OXM1LjE1IDExLjQ5IDExLjQ5IDExLjQ5YzMuNDYgMCA2LjU5LTEuNTMgOC43MS00LjAxdjMuNjFoMi43N1YxOC4yMmMwLTYuMzQtNS4xNS0xMS40OS0xMS40OC0xMS40OXoiPjwvcGF0aD48cGF0aCBjbGFzcz0iYm1zdDEiIGQ9Ik0xNjYuMDIgNy4xM3YyMi4xOGgyLjc3VjkuOWg1Ljk1djE5LjQxaDIuNzdWOS45aDUuN1Y3LjEzaC01LjdWLjE5aC0yLjc3djYuOTR6TTE1MS43NSA5LjVjLTQuOCAwLTguNzIgMy45MS04LjcyIDguNzEgMCA0LjggMy45MSA4LjcxIDguNzIgOC43MSA0LjgxIDAgOC43Mi0zLjkxIDguNzItOC43MSAwLTQuOC0zLjkxLTguNzEtOC43Mi04Ljcxem0xMS40OSAxNi42NGMwIDYuMzQtNS4xNSAxMS40OS0xMS40OSAxMS40OS01LjU5IDAtMTAuMjUtNC4wMS0xMS4yOS05LjMxaDIuODhjLjk0IDMuNzYgNC4zNiA2LjU0IDguNDIgNi41NCA0LjgxIDAgOC43Mi0zLjkxIDguNzItOC43MXYtLjQ0Yy0yLjEzIDIuNDctNS4yNSA0LjAxLTguNzIgNC4wMS02LjM0IDAtMTEuNDktNS4xNS0xMS40OS0xMS40OXM1LjE1LTExLjQ5IDExLjQ5LTExLjQ5IDExLjQ5IDUuMTUgMTEuNDkgMTEuNDl2Ny45MXpNMTM1LjAyIDcuMTNoMi43N3YyMi4xOGgtMi43N3pNMTIwLjU1IDkuNWMtNC44IDAtOC43MSAzLjkxLTguNzEgOC43MSAwIDQuOCAzLjkxIDguNzEgOC43MSA4LjcxIDQuOCAwIDguNzEtMy45MSA4LjcxLTguNzEuMDEtNC44LTMuOTEtOC43MS04LjcxLTguNzF6bTExLjQ5IDguNzJjMCA2LjM0LTUuMTUgMTEuNDktMTEuNDkgMTEuNDlzLTExLjQ5LTUuMTUtMTEuNDktMTEuNDkgNS4xNS0xMS40OSAxMS40OS0xMS40OWMzLjQ3IDAgNi41OCAxLjUzIDguNzEgNC4wMVYuMTloMi43OHYxOC4wM3pNMTM2LjQgMGMuODkgMCAxLjU4LjY5IDEuNTggMS41OCAwIC44OS0uNyAxLjU4LTEuNTggMS41OC0uOSAwLTEuNTktLjY5LTEuNTktMS41OCAwLS44OS43LTEuNTggMS41OS0xLjU4ek0xNjcuNCAwYy44OSAwIDEuNTkuNjkgMS41OSAxLjU4IDAgLjg5LS43IDEuNTgtMS41OSAxLjU4LS44OSAwLTEuNTgtLjY5LTEuNTgtMS41OCAwLS44OS42OS0xLjU4IDEuNTgtMS41OHoiPjwvcGF0aD48L3N2Zz4=
|
||||
1
public/images/roche-logo.979d9061-1768394101307.png
Normal file
1
public/images/roche-logo.979d9061-1768394101307.png
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
1
public/images/sanofi.b18c1526-1768394101348.png
Normal file
1
public/images/sanofi.b18c1526-1768394101348.png
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
1
public/images/startup.b4dbf43d-1768394101375.svg
Normal file
1
public/images/startup.b4dbf43d-1768394101375.svg
Normal file
File diff suppressed because one or more lines are too long
1
public/images/support.cbdb04e7-1768394101952.png
Normal file
1
public/images/support.cbdb04e7-1768394101952.png
Normal file
File diff suppressed because one or more lines are too long
1
public/images/totalenergies.5a993082-1768394101309.svg
Normal file
1
public/images/totalenergies.5a993082-1768394101309.svg
Normal file
File diff suppressed because one or more lines are too long
1232
public/index.html
Normal file
1232
public/index.html
Normal file
File diff suppressed because it is too large
Load Diff
28
src/App.js
Normal file
28
src/App.js
Normal file
@@ -0,0 +1,28 @@
|
||||
import React from 'react';
|
||||
import Header from './components/Header';
|
||||
import Hero from './components/Hero';
|
||||
import AccelerateSection from './components/AccelerateSection';
|
||||
import TeamAugmentation from './components/TeamAugmentation';
|
||||
import CompanyLogos from './components/CompanyLogos';
|
||||
import Services from './components/Services';
|
||||
import CTA from './components/CTA';
|
||||
import Newsletter from './components/Newsletter';
|
||||
import Footer from './components/Footer';
|
||||
|
||||
function App() {
|
||||
return (
|
||||
<div className="App">
|
||||
<Header />
|
||||
<Hero />
|
||||
<AccelerateSection />
|
||||
<TeamAugmentation />
|
||||
<CompanyLogos />
|
||||
<Services />
|
||||
<CTA />
|
||||
<Newsletter />
|
||||
<Footer />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default App;
|
||||
98
src/components/AccelerateSection.js
Normal file
98
src/components/AccelerateSection.js
Normal file
@@ -0,0 +1,98 @@
|
||||
import React from 'react';
|
||||
import { motion, useReducedMotion } from 'framer-motion';
|
||||
import { CheckCircle } from 'lucide-react';
|
||||
|
||||
const fadeUpPreset = (delay = 0, duration = 1.2) => ({
|
||||
initial: { opacity: 0, y: 20 },
|
||||
whileInView: { opacity: 1, y: 0 },
|
||||
viewport: { once: true, amount: 0.2 },
|
||||
transition: { delay, duration, ease: "easeOut" }
|
||||
});
|
||||
|
||||
function AccelerateSection() {
|
||||
const shouldReduce = useReducedMotion();
|
||||
|
||||
const features = [
|
||||
"Providing technical guidance & architectural reviews",
|
||||
"Mentoring team members",
|
||||
"Advising best practices",
|
||||
"Addressing security & performance concerns",
|
||||
"Performing in-depth code reviews",
|
||||
"Long-term support (LTS) & upgrade assistance"
|
||||
];
|
||||
|
||||
if (shouldReduce) {
|
||||
return (
|
||||
<section className="section-padding bg-gray-50">
|
||||
<div className="container-custom">
|
||||
<div className="grid lg:grid-cols-2 gap-12 items-center">
|
||||
<div>
|
||||
<h2 className="text-4xl md:text-5xl font-bold text-gray-900 mb-6">
|
||||
Accelerate your development
|
||||
</h2>
|
||||
<p className="text-lg text-gray-600 mb-6">
|
||||
We work alongside you to meet your deadlines while avoiding costly tech debt. Challenging issue? We've got you covered.
|
||||
</p>
|
||||
<p className="text-lg text-gray-600 mb-8">
|
||||
Our goal is to help you get to market faster. Nest core team members will help you utilize best practices and choose the right strategy for unique goals.
|
||||
</p>
|
||||
<button className="text-brand-red font-medium hover:underline">
|
||||
Contact us to learn more
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div className="space-y-4">
|
||||
{features.map((feature, index) => (
|
||||
<div key={index} className="flex items-start space-x-3">
|
||||
<CheckCircle className="w-5 h-5 text-green-500 mt-1 flex-shrink-0" />
|
||||
<span className="text-gray-700">{feature}</span>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<motion.section
|
||||
{...fadeUpPreset(0.1, 1.0)}
|
||||
className="section-padding bg-gray-50"
|
||||
>
|
||||
<div className="container-custom">
|
||||
<div className="grid lg:grid-cols-2 gap-12 items-center">
|
||||
<motion.div {...fadeUpPreset(0.2, 1.0)}>
|
||||
<h2 className="text-4xl md:text-5xl font-bold text-gray-900 mb-6">
|
||||
Accelerate your development
|
||||
</h2>
|
||||
<p className="text-lg text-gray-600 mb-6">
|
||||
We work alongside you to meet your deadlines while avoiding costly tech debt. Challenging issue? We've got you covered.
|
||||
</p>
|
||||
<p className="text-lg text-gray-600 mb-8">
|
||||
Our goal is to help you get to market faster. Nest core team members will help you utilize best practices and choose the right strategy for unique goals.
|
||||
</p>
|
||||
<button className="text-brand-red font-medium hover:underline">
|
||||
Contact us to learn more
|
||||
</button>
|
||||
</motion.div>
|
||||
|
||||
<motion.div {...fadeUpPreset(0.3, 1.0)} className="space-y-4">
|
||||
{features.map((feature, index) => (
|
||||
<motion.div
|
||||
key={index}
|
||||
{...fadeUpPreset(0.4 + index * 0.05, 0.6)}
|
||||
className="flex items-start space-x-3"
|
||||
>
|
||||
<CheckCircle className="w-5 h-5 text-green-500 mt-1 flex-shrink-0" />
|
||||
<span className="text-gray-700">{feature}</span>
|
||||
</motion.div>
|
||||
))}
|
||||
</motion.div>
|
||||
</div>
|
||||
</div>
|
||||
</motion.section>
|
||||
);
|
||||
}
|
||||
|
||||
export default AccelerateSection;
|
||||
61
src/components/CTA.js
Normal file
61
src/components/CTA.js
Normal file
@@ -0,0 +1,61 @@
|
||||
import React from 'react';
|
||||
import { motion, useReducedMotion } from 'framer-motion';
|
||||
|
||||
const fadeUpPreset = (delay = 0, duration = 1.2) => ({
|
||||
initial: { opacity: 0, y: 20 },
|
||||
whileInView: { opacity: 1, y: 0 },
|
||||
viewport: { once: true, amount: 0.2 },
|
||||
transition: { delay, duration, ease: "easeOut" }
|
||||
});
|
||||
|
||||
function CTA() {
|
||||
const shouldReduce = useReducedMotion();
|
||||
|
||||
if (shouldReduce) {
|
||||
return (
|
||||
<section className="section-padding bg-black">
|
||||
<div className="container-custom text-center">
|
||||
<h2 className="text-4xl md:text-5xl font-bold text-white mb-6">
|
||||
Explore enterprise services today.
|
||||
</h2>
|
||||
<p className="text-xl text-gray-300 mb-8">
|
||||
Let's achieve your most ambitious goals - together.
|
||||
</p>
|
||||
<button className="btn-primary">
|
||||
Contact us
|
||||
</button>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<motion.section
|
||||
{...fadeUpPreset(0.1, 1.0)}
|
||||
className="section-padding bg-black"
|
||||
>
|
||||
<div className="container-custom text-center">
|
||||
<motion.h2
|
||||
{...fadeUpPreset(0.2, 1.0)}
|
||||
className="text-4xl md:text-5xl font-bold text-white mb-6"
|
||||
>
|
||||
Explore enterprise services today.
|
||||
</motion.h2>
|
||||
<motion.p
|
||||
{...fadeUpPreset(0.3, 1.0)}
|
||||
className="text-xl text-gray-300 mb-8"
|
||||
>
|
||||
Let's achieve your most ambitious goals - together.
|
||||
</motion.p>
|
||||
<motion.button
|
||||
{...fadeUpPreset(0.4, 1.0)}
|
||||
className="btn-primary"
|
||||
>
|
||||
Contact us
|
||||
</motion.button>
|
||||
</div>
|
||||
</motion.section>
|
||||
);
|
||||
}
|
||||
|
||||
export default CTA;
|
||||
102
src/components/CompanyLogos.js
Normal file
102
src/components/CompanyLogos.js
Normal file
@@ -0,0 +1,102 @@
|
||||
import React from 'react';
|
||||
import { motion, useReducedMotion } from 'framer-motion';
|
||||
|
||||
const fadeUpPreset = (delay = 0, duration = 1.2) => ({
|
||||
initial: { opacity: 0, y: 20 },
|
||||
whileInView: { opacity: 1, y: 0 },
|
||||
viewport: { once: true, amount: 0.2 },
|
||||
transition: { delay, duration, ease: "easeOut" }
|
||||
});
|
||||
|
||||
function CompanyLogos() {
|
||||
const shouldReduce = useReducedMotion();
|
||||
|
||||
const companies = [
|
||||
{ name: 'Sanofi', logo: 'https://enterprise.nestjs.com/assets/logos/sanofi.svg' },
|
||||
{ name: 'Adidas', logo: 'https://enterprise.nestjs.com/assets/logos/adidas.svg' },
|
||||
{ name: 'Autodesk', logo: 'https://enterprise.nestjs.com/assets/logos/autodesk.svg' },
|
||||
{ name: 'Mercedes-Benz', logo: 'https://enterprise.nestjs.com/assets/logos/mercedes.svg' },
|
||||
{ name: 'GitLab', logo: 'https://enterprise.nestjs.com/assets/logos/gitlab.svg' },
|
||||
{ name: 'Red Hat', logo: 'https://enterprise.nestjs.com/assets/logos/redhat.svg' },
|
||||
{ name: 'Roche', logo: 'https://enterprise.nestjs.com/assets/logos/roche.svg' },
|
||||
{ name: 'IBM', logo: 'https://enterprise.nestjs.com/assets/logos/ibm.svg' },
|
||||
{ name: 'Decathlon', logo: 'https://enterprise.nestjs.com/assets/logos/decathlon.svg' },
|
||||
{ name: 'Societe Generale', logo: 'https://enterprise.nestjs.com/assets/logos/sg.svg' },
|
||||
{ name: 'Capgemini', logo: 'https://enterprise.nestjs.com/assets/logos/capgemini.svg' },
|
||||
{ name: 'REWE', logo: 'https://enterprise.nestjs.com/assets/logos/rewe.svg' }
|
||||
];
|
||||
|
||||
if (shouldReduce) {
|
||||
return (
|
||||
<section className="section-padding bg-white">
|
||||
<div className="container-custom text-center">
|
||||
<h2 className="text-3xl md:text-4xl font-bold text-gray-900 mb-4">
|
||||
Who is using Nest?
|
||||
</h2>
|
||||
<p className="text-lg text-gray-600 mb-12">
|
||||
Nest is proudly powering a large ecosystem of enterprises and products out there.
|
||||
<br />
|
||||
Wanna see your logo here? <span className="text-brand-red font-medium">Find out more</span>.
|
||||
</p>
|
||||
|
||||
<div className="grid grid-cols-2 md:grid-cols-3 lg:grid-cols-6 gap-8 items-center">
|
||||
{companies.map((company, index) => (
|
||||
<div key={index} className="flex items-center justify-center h-16">
|
||||
<img
|
||||
src={company.logo}
|
||||
alt={company.name}
|
||||
className="max-h-12 max-w-full opacity-60 hover:opacity-100 transition-opacity grayscale hover:grayscale-0"
|
||||
/>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<motion.section
|
||||
{...fadeUpPreset(0.1, 1.0)}
|
||||
className="section-padding bg-white"
|
||||
>
|
||||
<div className="container-custom text-center">
|
||||
<motion.h2
|
||||
{...fadeUpPreset(0.2, 1.0)}
|
||||
className="text-3xl md:text-4xl font-bold text-gray-900 mb-4"
|
||||
>
|
||||
Who is using Nest?
|
||||
</motion.h2>
|
||||
<motion.p
|
||||
{...fadeUpPreset(0.3, 1.0)}
|
||||
className="text-lg text-gray-600 mb-12"
|
||||
>
|
||||
Nest is proudly powering a large ecosystem of enterprises and products out there.
|
||||
<br />
|
||||
Wanna see your logo here? <span className="text-brand-red font-medium">Find out more</span>.
|
||||
</motion.p>
|
||||
|
||||
<motion.div
|
||||
{...fadeUpPreset(0.4, 1.0)}
|
||||
className="grid grid-cols-2 md:grid-cols-3 lg:grid-cols-6 gap-8 items-center"
|
||||
>
|
||||
{companies.map((company, index) => (
|
||||
<motion.div
|
||||
key={index}
|
||||
{...fadeUpPreset(0.5 + index * 0.05, 0.6)}
|
||||
className="flex items-center justify-center h-16"
|
||||
>
|
||||
<img
|
||||
src={company.logo}
|
||||
alt={company.name}
|
||||
className="max-h-12 max-w-full opacity-60 hover:opacity-100 transition-opacity grayscale hover:grayscale-0"
|
||||
/>
|
||||
</motion.div>
|
||||
))}
|
||||
</motion.div>
|
||||
</div>
|
||||
</motion.section>
|
||||
);
|
||||
}
|
||||
|
||||
export default CompanyLogos;
|
||||
44
src/components/Footer.js
Normal file
44
src/components/Footer.js
Normal file
@@ -0,0 +1,44 @@
|
||||
import React from 'react';
|
||||
import { Github, X } from 'lucide-react';
|
||||
|
||||
function Footer() {
|
||||
return (
|
||||
<footer className="bg-white py-12">
|
||||
<div className="container-custom">
|
||||
<div className="text-center space-y-4">
|
||||
<div className="flex items-center justify-center space-x-6">
|
||||
<a href="#" className="text-gray-400 hover:text-gray-600 transition-colors">
|
||||
<Github className="w-5 h-5" />
|
||||
</a>
|
||||
<a href="#" className="text-gray-400 hover:text-gray-600 transition-colors">
|
||||
<X className="w-5 h-5" />
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div className="text-sm text-gray-600 space-y-2">
|
||||
<p>
|
||||
Official NestJS Consulting{' '}
|
||||
<a href="#" className="text-brand-red hover:underline">
|
||||
Trilon.io
|
||||
</a>
|
||||
</p>
|
||||
<p>
|
||||
Copyright © 2017-2026{' '}
|
||||
<a href="#" className="text-brand-red hover:underline">
|
||||
Kamil Mysliwiec
|
||||
</a>
|
||||
</p>
|
||||
<p>
|
||||
Designed by{' '}
|
||||
<a href="#" className="text-brand-red hover:underline">
|
||||
Jakub Staron
|
||||
</a>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
);
|
||||
}
|
||||
|
||||
export default Footer;
|
||||
71
src/components/Header.js
Normal file
71
src/components/Header.js
Normal file
@@ -0,0 +1,71 @@
|
||||
import React, { useState } from 'react';
|
||||
import { Menu, X, ChevronDown, Github } from 'lucide-react';
|
||||
|
||||
function Header() {
|
||||
const [isMenuOpen, setIsMenuOpen] = useState(false);
|
||||
|
||||
return (
|
||||
<header className="fixed top-0 left-0 right-0 z-50 bg-black/90 backdrop-blur-sm">
|
||||
<div className="container-custom">
|
||||
<div className="flex items-center justify-between h-16">
|
||||
{/* Logo */}
|
||||
<div className="flex items-center">
|
||||
<div className="w-10 h-10 bg-brand-red rounded-lg flex items-center justify-center">
|
||||
<svg viewBox="0 0 24 24" className="w-6 h-6 text-white fill-current">
|
||||
<path d="M12 2L2 7l10 5 10-5-10-5zM2 17l10 5 10-5M2 12l10 5 10-5"/>
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Desktop Navigation */}
|
||||
<nav className="hidden md:flex items-center space-x-8">
|
||||
<a href="#" className="text-white hover:text-brand-red transition-colors">OUR WEBSITE</a>
|
||||
<a href="#" className="text-white hover:text-brand-red transition-colors">COURSES</a>
|
||||
<div className="relative group">
|
||||
<button className="flex items-center text-white hover:text-brand-red transition-colors">
|
||||
<span className="bg-brand-red text-white text-xs px-2 py-1 rounded mr-2">NEW</span>
|
||||
RESOURCES
|
||||
<ChevronDown className="w-4 h-4 ml-1" />
|
||||
</button>
|
||||
</div>
|
||||
<a href="#" className="text-white hover:text-brand-red transition-colors">
|
||||
<Github className="w-5 h-5" />
|
||||
</a>
|
||||
<a href="#" className="text-white hover:text-brand-red transition-colors">
|
||||
<X className="w-5 h-5" />
|
||||
</a>
|
||||
</nav>
|
||||
|
||||
{/* Mobile menu button */}
|
||||
<button
|
||||
className="md:hidden text-white"
|
||||
onClick={() => setIsMenuOpen(!isMenuOpen)}
|
||||
>
|
||||
{isMenuOpen ? <X className="w-6 h-6" /> : <Menu className="w-6 h-6" />}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
{/* Mobile Navigation */}
|
||||
{isMenuOpen && (
|
||||
<div className="md:hidden bg-black/95 absolute top-16 left-0 right-0 border-t border-gray-800">
|
||||
<nav className="flex flex-col space-y-4 p-4">
|
||||
<a href="#" className="text-white hover:text-brand-red transition-colors">OUR WEBSITE</a>
|
||||
<a href="#" className="text-white hover:text-brand-red transition-colors">COURSES</a>
|
||||
<a href="#" className="text-white hover:text-brand-red transition-colors">RESOURCES</a>
|
||||
<div className="flex space-x-4 pt-2">
|
||||
<a href="#" className="text-white hover:text-brand-red transition-colors">
|
||||
<Github className="w-5 h-5" />
|
||||
</a>
|
||||
<a href="#" className="text-white hover:text-brand-red transition-colors">
|
||||
<X className="w-5 h-5" />
|
||||
</a>
|
||||
</div>
|
||||
</nav>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</header>
|
||||
);
|
||||
}
|
||||
|
||||
export default Header;
|
||||
93
src/components/Hero.js
Normal file
93
src/components/Hero.js
Normal file
@@ -0,0 +1,93 @@
|
||||
import React from 'react';
|
||||
import { motion, useReducedMotion } from 'framer-motion';
|
||||
|
||||
const fadeUpPreset = (delay = 0, duration = 1.2) => ({
|
||||
initial: { opacity: 0, y: 20 },
|
||||
whileInView: { opacity: 1, y: 0 },
|
||||
viewport: { once: true, amount: 0.2 },
|
||||
transition: { delay, duration, ease: "easeOut" }
|
||||
});
|
||||
|
||||
function Hero() {
|
||||
const shouldReduce = useReducedMotion();
|
||||
|
||||
if (shouldReduce) {
|
||||
return (
|
||||
<section className="relative min-h-screen bg-black flex items-center overflow-hidden">
|
||||
<div className="absolute inset-0 bg-gradient-to-r from-black via-black/80 to-transparent z-10"></div>
|
||||
<div className="absolute inset-0">
|
||||
<img
|
||||
src="https://enterprise.nestjs.com/assets/hero-bg.jpg"
|
||||
alt="Cat background"
|
||||
className="w-full h-full object-cover opacity-60"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="relative z-20 container-custom">
|
||||
<div className="max-w-2xl">
|
||||
<h1 className="text-5xl md:text-7xl font-bold text-white mb-6">
|
||||
Official support
|
||||
</h1>
|
||||
<p className="text-xl md:text-2xl text-gray-300 mb-8 leading-relaxed">
|
||||
Our Experts become your development partner to eliminate project risk, tackling the most ambitious projects - right by your side.
|
||||
</p>
|
||||
<div className="flex flex-col sm:flex-row gap-4">
|
||||
<button className="btn-primary">
|
||||
Get in touch
|
||||
</button>
|
||||
<button className="btn-secondary">
|
||||
Read more
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<motion.section
|
||||
{...fadeUpPreset(0.1, 0.8)}
|
||||
className="relative min-h-screen bg-black flex items-center overflow-hidden"
|
||||
>
|
||||
<div className="absolute inset-0 bg-gradient-to-r from-black via-black/80 to-transparent z-10"></div>
|
||||
<div className="absolute inset-0">
|
||||
<img
|
||||
src="https://enterprise.nestjs.com/assets/hero-bg.jpg"
|
||||
alt="Cat background"
|
||||
className="w-full h-full object-cover opacity-60"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="relative z-20 container-custom">
|
||||
<div className="max-w-2xl">
|
||||
<motion.h1
|
||||
{...fadeUpPreset(0.2, 0.8)}
|
||||
className="text-5xl md:text-7xl font-bold text-white mb-6"
|
||||
>
|
||||
Official support
|
||||
</motion.h1>
|
||||
<motion.p
|
||||
{...fadeUpPreset(0.3, 0.8)}
|
||||
className="text-xl md:text-2xl text-gray-300 mb-8 leading-relaxed"
|
||||
>
|
||||
Our Experts become your development partner to eliminate project risk, tackling the most ambitious projects - right by your side.
|
||||
</motion.p>
|
||||
<motion.div
|
||||
{...fadeUpPreset(0.4, 0.8)}
|
||||
className="flex flex-col sm:flex-row gap-4"
|
||||
>
|
||||
<button className="btn-primary">
|
||||
Get in touch
|
||||
</button>
|
||||
<button className="btn-secondary">
|
||||
Read more
|
||||
</button>
|
||||
</motion.div>
|
||||
</div>
|
||||
</div>
|
||||
</motion.section>
|
||||
);
|
||||
}
|
||||
|
||||
export default Hero;
|
||||
104
src/components/Newsletter.js
Normal file
104
src/components/Newsletter.js
Normal file
@@ -0,0 +1,104 @@
|
||||
import React, { useState } from 'react';
|
||||
import { motion, useReducedMotion } from 'framer-motion';
|
||||
import { ArrowRight } from 'lucide-react';
|
||||
|
||||
const fadeUpPreset = (delay = 0, duration = 1.2) => ({
|
||||
initial: { opacity: 0, y: 20 },
|
||||
whileInView: { opacity: 1, y: 0 },
|
||||
viewport: { once: true, amount: 0.2 },
|
||||
transition: { delay, duration, ease: "easeOut" }
|
||||
});
|
||||
|
||||
function Newsletter() {
|
||||
const [email, setEmail] = useState('');
|
||||
const shouldReduce = useReducedMotion();
|
||||
|
||||
const handleSubmit = (e) => {
|
||||
e.preventDefault();
|
||||
console.log('Newsletter signup:', email);
|
||||
setEmail('');
|
||||
};
|
||||
|
||||
if (shouldReduce) {
|
||||
return (
|
||||
<section className="section-padding bg-gray-50">
|
||||
<div className="container-custom">
|
||||
<div className="max-w-2xl mx-auto text-center">
|
||||
<h2 className="text-3xl md:text-4xl font-bold text-gray-900 mb-4">
|
||||
Join our Newsletter
|
||||
</h2>
|
||||
<p className="text-lg text-gray-600 mb-8">
|
||||
Subscribe to stay up to date with the latest Nest updates, features, and videos!
|
||||
</p>
|
||||
|
||||
<form onSubmit={handleSubmit} className="flex flex-col sm:flex-row gap-4 max-w-md mx-auto">
|
||||
<input
|
||||
type="email"
|
||||
value={email}
|
||||
onChange={(e) => setEmail(e.target.value)}
|
||||
placeholder="Enter your email"
|
||||
className="flex-1 px-4 py-3 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-brand-red focus:border-transparent"
|
||||
required
|
||||
/>
|
||||
<button
|
||||
type="submit"
|
||||
className="bg-brand-red text-white px-6 py-3 rounded-lg font-medium hover:bg-brand-red-dark transition-colors flex items-center justify-center gap-2"
|
||||
>
|
||||
Subscribe
|
||||
<ArrowRight className="w-4 h-4" />
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<motion.section
|
||||
{...fadeUpPreset(0.1, 1.0)}
|
||||
className="section-padding bg-gray-50"
|
||||
>
|
||||
<div className="container-custom">
|
||||
<div className="max-w-2xl mx-auto text-center">
|
||||
<motion.h2
|
||||
{...fadeUpPreset(0.2, 1.0)}
|
||||
className="text-3xl md:text-4xl font-bold text-gray-900 mb-4"
|
||||
>
|
||||
Join our Newsletter
|
||||
</motion.h2>
|
||||
<motion.p
|
||||
{...fadeUpPreset(0.3, 1.0)}
|
||||
className="text-lg text-gray-600 mb-8"
|
||||
>
|
||||
Subscribe to stay up to date with the latest Nest updates, features, and videos!
|
||||
</motion.p>
|
||||
|
||||
<motion.form
|
||||
{...fadeUpPreset(0.4, 1.0)}
|
||||
onSubmit={handleSubmit}
|
||||
className="flex flex-col sm:flex-row gap-4 max-w-md mx-auto"
|
||||
>
|
||||
<input
|
||||
type="email"
|
||||
value={email}
|
||||
onChange={(e) => setEmail(e.target.value)}
|
||||
placeholder="Enter your email"
|
||||
className="flex-1 px-4 py-3 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-brand-red focus:border-transparent"
|
||||
required
|
||||
/>
|
||||
<button
|
||||
type="submit"
|
||||
className="bg-brand-red text-white px-6 py-3 rounded-lg font-medium hover:bg-brand-red-dark transition-colors flex items-center justify-center gap-2"
|
||||
>
|
||||
Subscribe
|
||||
<ArrowRight className="w-4 h-4" />
|
||||
</button>
|
||||
</motion.form>
|
||||
</div>
|
||||
</div>
|
||||
</motion.section>
|
||||
);
|
||||
}
|
||||
|
||||
export default Newsletter;
|
||||
131
src/components/Services.js
Normal file
131
src/components/Services.js
Normal file
@@ -0,0 +1,131 @@
|
||||
import React from 'react';
|
||||
import { motion, useReducedMotion } from 'framer-motion';
|
||||
import { Users, Target, Zap, Search, Shield, GraduationCap } from 'lucide-react';
|
||||
|
||||
const fadeUpPreset = (delay = 0, duration = 1.2) => ({
|
||||
initial: { opacity: 0, y: 20 },
|
||||
whileInView: { opacity: 1, y: 0 },
|
||||
viewport: { once: true, amount: 0.2 },
|
||||
transition: { delay, duration, ease: "easeOut" }
|
||||
});
|
||||
|
||||
function Services() {
|
||||
const shouldReduce = useReducedMotion();
|
||||
|
||||
const services = [
|
||||
{
|
||||
icon: Users,
|
||||
title: "DEVELOPMENT",
|
||||
description: "Achieve your goals faster with Nest experts on your team tackling challenging issues right by your side."
|
||||
},
|
||||
{
|
||||
icon: Target,
|
||||
title: "TECHNICAL GUIDANCE",
|
||||
description: "Enable your team to get the most out of the technology. Ensure your solutions are secure and reliable."
|
||||
},
|
||||
{
|
||||
icon: Zap,
|
||||
title: "MIGRATION ASSISTANCE",
|
||||
description: "We provide a comprehensive migration assistance, ensuring you are using the latest and greatest."
|
||||
},
|
||||
{
|
||||
icon: Search,
|
||||
title: "IN-DEPTH CODE REVIEWS",
|
||||
description: "Frequent code reviews can eliminate potentially hazardous bugs and issues at an early stage while enforcing best practices."
|
||||
},
|
||||
{
|
||||
icon: Shield,
|
||||
title: "LONG-TERM SUPPORT (LTS)",
|
||||
description: "Have peace of mind with Nest long-term support (LTS), priority fixes, upgrade assistance, and live troubleshooting."
|
||||
},
|
||||
{
|
||||
icon: GraduationCap,
|
||||
title: "TEAM TRAININGS",
|
||||
description: "Level-up your team by having expert-led Nest trainings or workshops. Get everyone up-to-speed quickly."
|
||||
}
|
||||
];
|
||||
|
||||
if (shouldReduce) {
|
||||
return (
|
||||
<section className="section-padding bg-gray-50">
|
||||
<div className="container-custom">
|
||||
<div className="text-center mb-16">
|
||||
<h2 className="text-4xl md:text-5xl font-bold text-gray-900 mb-6">
|
||||
How can we help you be successful?
|
||||
</h2>
|
||||
<p className="text-lg text-gray-600 max-w-3xl mx-auto">
|
||||
Nest Enterprise Consulting includes a broad range of services to empower your team.
|
||||
We help you grow your business even long after our commitment is done.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="grid md:grid-cols-2 lg:grid-cols-3 gap-8">
|
||||
{services.map((service, index) => {
|
||||
const IconComponent = service.icon;
|
||||
return (
|
||||
<div key={index} className="text-center p-6">
|
||||
<div className="w-16 h-16 bg-brand-red rounded-full flex items-center justify-center mx-auto mb-6">
|
||||
<IconComponent className="w-8 h-8 text-white" />
|
||||
</div>
|
||||
<h3 className="text-lg font-bold text-gray-900 mb-4">
|
||||
{service.title}
|
||||
</h3>
|
||||
<p className="text-gray-600 leading-relaxed">
|
||||
{service.description}
|
||||
</p>
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<motion.section
|
||||
{...fadeUpPreset(0.1, 1.0)}
|
||||
className="section-padding bg-gray-50"
|
||||
>
|
||||
<div className="container-custom">
|
||||
<motion.div
|
||||
{...fadeUpPreset(0.2, 1.0)}
|
||||
className="text-center mb-16"
|
||||
>
|
||||
<h2 className="text-4xl md:text-5xl font-bold text-gray-900 mb-6">
|
||||
How can we help you be successful?
|
||||
</h2>
|
||||
<p className="text-lg text-gray-600 max-w-3xl mx-auto">
|
||||
Nest Enterprise Consulting includes a broad range of services to empower your team.
|
||||
We help you grow your business even long after our commitment is done.
|
||||
</p>
|
||||
</motion.div>
|
||||
|
||||
<div className="grid md:grid-cols-2 lg:grid-cols-3 gap-8">
|
||||
{services.map((service, index) => {
|
||||
const IconComponent = service.icon;
|
||||
return (
|
||||
<motion.div
|
||||
key={index}
|
||||
{...fadeUpPreset(0.3 + index * 0.1, 0.8)}
|
||||
className="text-center p-6"
|
||||
>
|
||||
<div className="w-16 h-16 bg-brand-red rounded-full flex items-center justify-center mx-auto mb-6">
|
||||
<IconComponent className="w-8 h-8 text-white" />
|
||||
</div>
|
||||
<h3 className="text-lg font-bold text-gray-900 mb-4">
|
||||
{service.title}
|
||||
</h3>
|
||||
<p className="text-gray-600 leading-relaxed">
|
||||
{service.description}
|
||||
</p>
|
||||
</motion.div>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
</motion.section>
|
||||
);
|
||||
}
|
||||
|
||||
export default Services;
|
||||
82
src/components/TeamAugmentation.js
Normal file
82
src/components/TeamAugmentation.js
Normal file
@@ -0,0 +1,82 @@
|
||||
import React from 'react';
|
||||
import { motion, useReducedMotion } from 'framer-motion';
|
||||
|
||||
const fadeUpPreset = (delay = 0, duration = 1.2) => ({
|
||||
initial: { opacity: 0, y: 20 },
|
||||
whileInView: { opacity: 1, y: 0 },
|
||||
viewport: { once: true, amount: 0.2 },
|
||||
transition: { delay, duration, ease: "easeOut" }
|
||||
});
|
||||
|
||||
function TeamAugmentation() {
|
||||
const shouldReduce = useReducedMotion();
|
||||
|
||||
if (shouldReduce) {
|
||||
return (
|
||||
<section className="section-padding bg-brand-red">
|
||||
<div className="container-custom">
|
||||
<div className="grid lg:grid-cols-2 gap-12 items-center">
|
||||
<div className="order-2 lg:order-1">
|
||||
<img
|
||||
src="https://enterprise.nestjs.com/assets/cat-chair.jpg"
|
||||
alt="Cat in chair"
|
||||
className="w-full max-w-md mx-auto"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="order-1 lg:order-2">
|
||||
<h2 className="text-4xl md:text-5xl font-bold text-white mb-6">
|
||||
Team augmentation. By your side at every step
|
||||
</h2>
|
||||
<p className="text-xl text-white/90 mb-8 leading-relaxed">
|
||||
Nest core team members can work directly with your team on a daily basis to help take your project to the next-level. Let us partner with you and your team to develop the most ambitious projects.
|
||||
</p>
|
||||
<button className="bg-white text-brand-red px-8 py-3 rounded-full font-medium hover:bg-gray-100 transition-colors">
|
||||
Contact us to learn more
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<motion.section
|
||||
{...fadeUpPreset(0.1, 1.0)}
|
||||
className="section-padding bg-brand-red"
|
||||
>
|
||||
<div className="container-custom">
|
||||
<div className="grid lg:grid-cols-2 gap-12 items-center">
|
||||
<motion.div
|
||||
{...fadeUpPreset(0.2, 1.0)}
|
||||
className="order-2 lg:order-1"
|
||||
>
|
||||
<img
|
||||
src="https://enterprise.nestjs.com/assets/cat-chair.jpg"
|
||||
alt="Cat in chair"
|
||||
className="w-full max-w-md mx-auto"
|
||||
/>
|
||||
</motion.div>
|
||||
|
||||
<motion.div
|
||||
{...fadeUpPreset(0.3, 1.0)}
|
||||
className="order-1 lg:order-2"
|
||||
>
|
||||
<h2 className="text-4xl md:text-5xl font-bold text-white mb-6">
|
||||
Team augmentation. By your side at every step
|
||||
</h2>
|
||||
<p className="text-xl text-white/90 mb-8 leading-relaxed">
|
||||
Nest core team members can work directly with your team on a daily basis to help take your project to the next-level. Let us partner with you and your team to develop the most ambitious projects.
|
||||
</p>
|
||||
<button className="bg-white text-brand-red px-8 py-3 rounded-full font-medium hover:bg-gray-100 transition-colors">
|
||||
Contact us to learn more
|
||||
</button>
|
||||
</motion.div>
|
||||
</div>
|
||||
</div>
|
||||
</motion.section>
|
||||
);
|
||||
}
|
||||
|
||||
export default TeamAugmentation;
|
||||
27
src/index.css
Normal file
27
src/index.css
Normal file
@@ -0,0 +1,27 @@
|
||||
@tailwind base;
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
|
||||
@layer base {
|
||||
body {
|
||||
@apply font-sans antialiased;
|
||||
}
|
||||
}
|
||||
|
||||
@layer components {
|
||||
.btn-primary {
|
||||
@apply bg-brand-red text-white px-8 py-3 rounded-full font-medium hover:bg-brand-red-dark transition-colors duration-200;
|
||||
}
|
||||
|
||||
.btn-secondary {
|
||||
@apply border-2 border-white text-white px-8 py-3 rounded-full font-medium hover:bg-white hover:text-gray-900 transition-colors duration-200;
|
||||
}
|
||||
|
||||
.section-padding {
|
||||
@apply py-16 md:py-24;
|
||||
}
|
||||
|
||||
.container-custom {
|
||||
@apply max-w-7xl mx-auto px-4 sm:px-6 lg:px-8;
|
||||
}
|
||||
}
|
||||
13
src/index.js
Normal file
13
src/index.js
Normal file
@@ -0,0 +1,13 @@
|
||||
import React from 'react';
|
||||
import { createRoot } from 'react-dom/client';
|
||||
import './index.css';
|
||||
import App from './App';
|
||||
|
||||
const container = document.getElementById('root');
|
||||
const root = createRoot(container);
|
||||
|
||||
root.render(
|
||||
<React.StrictMode>
|
||||
<App />
|
||||
</React.StrictMode>
|
||||
);
|
||||
18
tailwind.config.js
Normal file
18
tailwind.config.js
Normal file
@@ -0,0 +1,18 @@
|
||||
/** @type {import('tailwindcss').Config} */
|
||||
module.exports = {
|
||||
content: [
|
||||
"./src/**/*.{js,jsx,ts,tsx}",
|
||||
],
|
||||
theme: {
|
||||
extend: {
|
||||
colors: {
|
||||
'brand-red': '#e53e3e',
|
||||
'brand-red-dark': '#c53030',
|
||||
},
|
||||
fontFamily: {
|
||||
sans: ['Inter', 'system-ui', 'sans-serif'],
|
||||
},
|
||||
},
|
||||
},
|
||||
plugins: [],
|
||||
}
|
||||
5
vercel.json
Normal file
5
vercel.json
Normal file
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"installCommand": "npm install",
|
||||
"buildCommand": "CI=false npm run build",
|
||||
"outputDirectory": "build"
|
||||
}
|
||||
Reference in New Issue
Block a user