first commit
41
.gitignore
vendored
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
|
||||||
|
|
||||||
|
# dependencies
|
||||||
|
/node_modules
|
||||||
|
/.pnp
|
||||||
|
.pnp.*
|
||||||
|
.yarn/*
|
||||||
|
!.yarn/patches
|
||||||
|
!.yarn/plugins
|
||||||
|
!.yarn/releases
|
||||||
|
!.yarn/versions
|
||||||
|
|
||||||
|
# testing
|
||||||
|
/coverage
|
||||||
|
|
||||||
|
# next.js
|
||||||
|
/.next/
|
||||||
|
/out/
|
||||||
|
|
||||||
|
# production
|
||||||
|
/build
|
||||||
|
|
||||||
|
# misc
|
||||||
|
.DS_Store
|
||||||
|
*.pem
|
||||||
|
|
||||||
|
# debug
|
||||||
|
npm-debug.log*
|
||||||
|
yarn-debug.log*
|
||||||
|
yarn-error.log*
|
||||||
|
.pnpm-debug.log*
|
||||||
|
|
||||||
|
# env files (can opt-in for committing if needed)
|
||||||
|
.env*
|
||||||
|
|
||||||
|
# vercel
|
||||||
|
.vercel
|
||||||
|
|
||||||
|
# typescript
|
||||||
|
*.tsbuildinfo
|
||||||
|
next-env.d.ts
|
||||||
5
AGENTS.md
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
<!-- BEGIN:nextjs-agent-rules -->
|
||||||
|
# This is NOT the Next.js you know
|
||||||
|
|
||||||
|
This version has breaking changes — APIs, conventions, and file structure may all differ from your training data. Read the relevant guide in `node_modules/next/dist/docs/` before writing any code. Heed deprecation notices.
|
||||||
|
<!-- END:nextjs-agent-rules -->
|
||||||
36
README.md
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
This is a [Next.js](https://nextjs.org) project bootstrapped with [`create-next-app`](https://nextjs.org/docs/app/api-reference/cli/create-next-app).
|
||||||
|
|
||||||
|
## Getting Started
|
||||||
|
|
||||||
|
First, run the development server:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm run dev
|
||||||
|
# or
|
||||||
|
yarn dev
|
||||||
|
# or
|
||||||
|
pnpm dev
|
||||||
|
# or
|
||||||
|
bun dev
|
||||||
|
```
|
||||||
|
|
||||||
|
Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.
|
||||||
|
|
||||||
|
You can start editing the page by modifying `app/page.tsx`. The page auto-updates as you edit the file.
|
||||||
|
|
||||||
|
This project uses [`next/font`](https://nextjs.org/docs/app/building-your-application/optimizing/fonts) to automatically optimize and load [Geist](https://vercel.com/font), a new font family for Vercel.
|
||||||
|
|
||||||
|
## Learn More
|
||||||
|
|
||||||
|
To learn more about Next.js, take a look at the following resources:
|
||||||
|
|
||||||
|
- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API.
|
||||||
|
- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial.
|
||||||
|
|
||||||
|
You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js) - your feedback and contributions are welcome!
|
||||||
|
|
||||||
|
## Deploy on Vercel
|
||||||
|
|
||||||
|
The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js.
|
||||||
|
|
||||||
|
Check out our [Next.js deployment documentation](https://nextjs.org/docs/app/building-your-application/deploying) for more details.
|
||||||
18
eslint.config.mjs
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
import { defineConfig, globalIgnores } from "eslint/config";
|
||||||
|
import nextVitals from "eslint-config-next/core-web-vitals";
|
||||||
|
import nextTs from "eslint-config-next/typescript";
|
||||||
|
|
||||||
|
const eslintConfig = defineConfig([
|
||||||
|
...nextVitals,
|
||||||
|
...nextTs,
|
||||||
|
// Override default ignores of eslint-config-next.
|
||||||
|
globalIgnores([
|
||||||
|
// Default ignores of eslint-config-next:
|
||||||
|
".next/**",
|
||||||
|
"out/**",
|
||||||
|
"build/**",
|
||||||
|
"next-env.d.ts",
|
||||||
|
]),
|
||||||
|
]);
|
||||||
|
|
||||||
|
export default eslintConfig;
|
||||||
14
next.config.ts
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
import type { NextConfig } from "next";
|
||||||
|
|
||||||
|
const nextConfig: NextConfig = {
|
||||||
|
images: {
|
||||||
|
remotePatterns: [
|
||||||
|
{
|
||||||
|
protocol: 'https',
|
||||||
|
hostname: 'images.unsplash.com',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export default nextConfig;
|
||||||
6008
package-lock.json
generated
Normal file
26
package.json
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
{
|
||||||
|
"name": "web-hondavert",
|
||||||
|
"version": "0.1.0",
|
||||||
|
"private": true,
|
||||||
|
"scripts": {
|
||||||
|
"dev": "next dev",
|
||||||
|
"build": "next build",
|
||||||
|
"start": "next start",
|
||||||
|
"lint": "eslint"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"framer-motion": "^12.38.0",
|
||||||
|
"lucide-react": "^1.7.0",
|
||||||
|
"next": "16.2.1",
|
||||||
|
"react": "19.2.4",
|
||||||
|
"react-dom": "19.2.4"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@types/node": "^20",
|
||||||
|
"@types/react": "^19",
|
||||||
|
"@types/react-dom": "^19",
|
||||||
|
"eslint": "^9",
|
||||||
|
"eslint-config-next": "16.2.1",
|
||||||
|
"typescript": "^5"
|
||||||
|
}
|
||||||
|
}
|
||||||
BIN
public/ecu_kpro.png
Normal file
|
After Width: | Height: | Size: 79 KiB |
BIN
public/engine_bay.png
Normal file
|
After Width: | Height: | Size: 89 KiB |
1
public/file.svg
Normal file
@ -0,0 +1 @@
|
|||||||
|
<svg fill="none" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"><path d="M14.5 13.5V5.41a1 1 0 0 0-.3-.7L9.8.29A1 1 0 0 0 9.08 0H1.5v13.5A2.5 2.5 0 0 0 4 16h8a2.5 2.5 0 0 0 2.5-2.5m-1.5 0v-7H8v-5H3v12a1 1 0 0 0 1 1h8a1 1 0 0 0 1-1M9.5 5V2.12L12.38 5zM5.13 5h-.62v1.25h2.12V5zm-.62 3h7.12v1.25H4.5zm.62 3h-.62v1.25h7.12V11z" clip-rule="evenodd" fill="#666" fill-rule="evenodd"/></svg>
|
||||||
|
After Width: | Height: | Size: 391 B |
1
public/globe.svg
Normal file
@ -0,0 +1 @@
|
|||||||
|
<svg fill="none" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><g clip-path="url(#a)"><path fill-rule="evenodd" clip-rule="evenodd" d="M10.27 14.1a6.5 6.5 0 0 0 3.67-3.45q-1.24.21-2.7.34-.31 1.83-.97 3.1M8 16A8 8 0 1 0 8 0a8 8 0 0 0 0 16m.48-1.52a7 7 0 0 1-.96 0H7.5a4 4 0 0 1-.84-1.32q-.38-.89-.63-2.08a40 40 0 0 0 3.92 0q-.25 1.2-.63 2.08a4 4 0 0 1-.84 1.31zm2.94-4.76q1.66-.15 2.95-.43a7 7 0 0 0 0-2.58q-1.3-.27-2.95-.43a18 18 0 0 1 0 3.44m-1.27-3.54a17 17 0 0 1 0 3.64 39 39 0 0 1-4.3 0 17 17 0 0 1 0-3.64 39 39 0 0 1 4.3 0m1.1-1.17q1.45.13 2.69.34a6.5 6.5 0 0 0-3.67-3.44q.65 1.26.98 3.1M8.48 1.5l.01.02q.41.37.84 1.31.38.89.63 2.08a40 40 0 0 0-3.92 0q.25-1.2.63-2.08a4 4 0 0 1 .85-1.32 7 7 0 0 1 .96 0m-2.75.4a6.5 6.5 0 0 0-3.67 3.44 29 29 0 0 1 2.7-.34q.31-1.83.97-3.1M4.58 6.28q-1.66.16-2.95.43a7 7 0 0 0 0 2.58q1.3.27 2.95.43a18 18 0 0 1 0-3.44m.17 4.71q-1.45-.12-2.69-.34a6.5 6.5 0 0 0 3.67 3.44q-.65-1.27-.98-3.1" fill="#666"/></g><defs><clipPath id="a"><path fill="#fff" d="M0 0h16v16H0z"/></clipPath></defs></svg>
|
||||||
|
After Width: | Height: | Size: 1.0 KiB |
BIN
public/hondavert_logo.png
Normal file
|
After Width: | Height: | Size: 3.6 KiB |
BIN
public/hud_telemetry.png
Normal file
|
After Width: | Height: | Size: 54 KiB |
BIN
public/map_graph.png
Normal file
|
After Width: | Height: | Size: 169 KiB |
BIN
public/map_sensor.png
Normal file
|
After Width: | Height: | Size: 52 KiB |
1
public/next.svg
Normal file
@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 394 80"><path fill="#000" d="M262 0h68.5v12.7h-27.2v66.6h-13.6V12.7H262V0ZM149 0v12.7H94v20.4h44.3v12.6H94v21h55v12.6H80.5V0h68.7zm34.3 0h-17.8l63.8 79.4h17.9l-32-39.7 32-39.6h-17.9l-23 28.6-23-28.6zm18.3 56.7-9-11-27.1 33.7h17.8l18.3-22.7z"/><path fill="#000" d="M81 79.3 17 0H0v79.3h13.6V17l50.2 62.3H81Zm252.6-.4c-1 0-1.8-.4-2.5-1s-1.1-1.6-1.1-2.6.3-1.8 1-2.5 1.6-1 2.6-1 1.8.3 2.5 1a3.4 3.4 0 0 1 .6 4.3 3.7 3.7 0 0 1-3 1.8zm23.2-33.5h6v23.3c0 2.1-.4 4-1.3 5.5a9.1 9.1 0 0 1-3.8 3.5c-1.6.8-3.5 1.3-5.7 1.3-2 0-3.7-.4-5.3-1s-2.8-1.8-3.7-3.2c-.9-1.3-1.4-3-1.4-5h6c.1.8.3 1.6.7 2.2s1 1.2 1.6 1.5c.7.4 1.5.5 2.4.5 1 0 1.8-.2 2.4-.6a4 4 0 0 0 1.6-1.8c.3-.8.5-1.8.5-3V45.5zm30.9 9.1a4.4 4.4 0 0 0-2-3.3 7.5 7.5 0 0 0-4.3-1.1c-1.3 0-2.4.2-3.3.5-.9.4-1.6 1-2 1.6a3.5 3.5 0 0 0-.3 4c.3.5.7.9 1.3 1.2l1.8 1 2 .5 3.2.8c1.3.3 2.5.7 3.7 1.2a13 13 0 0 1 3.2 1.8 8.1 8.1 0 0 1 3 6.5c0 2-.5 3.7-1.5 5.1a10 10 0 0 1-4.4 3.5c-1.8.8-4.1 1.2-6.8 1.2-2.6 0-4.9-.4-6.8-1.2-2-.8-3.4-2-4.5-3.5a10 10 0 0 1-1.7-5.6h6a5 5 0 0 0 3.5 4.6c1 .4 2.2.6 3.4.6 1.3 0 2.5-.2 3.5-.6 1-.4 1.8-1 2.4-1.7a4 4 0 0 0 .8-2.4c0-.9-.2-1.6-.7-2.2a11 11 0 0 0-2.1-1.4l-3.2-1-3.8-1c-2.8-.7-5-1.7-6.6-3.2a7.2 7.2 0 0 1-2.4-5.7 8 8 0 0 1 1.7-5 10 10 0 0 1 4.3-3.5c2-.8 4-1.2 6.4-1.2 2.3 0 4.4.4 6.2 1.2 1.8.8 3.2 2 4.3 3.4 1 1.4 1.5 3 1.5 5h-5.8z"/></svg>
|
||||||
|
After Width: | Height: | Size: 1.3 KiB |
BIN
public/precan_car.png
Normal file
|
After Width: | Height: | Size: 56 KiB |
1
public/vercel.svg
Normal file
@ -0,0 +1 @@
|
|||||||
|
<svg fill="none" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1155 1000"><path d="m577.3 0 577.4 1000H0z" fill="#fff"/></svg>
|
||||||
|
After Width: | Height: | Size: 128 B |
1
public/window.svg
Normal file
@ -0,0 +1 @@
|
|||||||
|
<svg fill="none" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><path fill-rule="evenodd" clip-rule="evenodd" d="M1.5 2.5h13v10a1 1 0 0 1-1 1h-11a1 1 0 0 1-1-1zM0 1h16v11.5a2.5 2.5 0 0 1-2.5 2.5h-11A2.5 2.5 0 0 1 0 12.5zm3.75 4.5a.75.75 0 1 0 0-1.5.75.75 0 0 0 0 1.5M7 4.75a.75.75 0 1 1-1.5 0 .75.75 0 0 1 1.5 0m1.75.75a.75.75 0 1 0 0-1.5.75.75 0 0 0 0 1.5" fill="#666"/></svg>
|
||||||
|
After Width: | Height: | Size: 385 B |
377
src/app/about/AboutPage.module.css
Normal file
@ -0,0 +1,377 @@
|
|||||||
|
.main {
|
||||||
|
background-color: var(--neutral);
|
||||||
|
min-height: 100vh;
|
||||||
|
}
|
||||||
|
|
||||||
|
.container {
|
||||||
|
max-width: 1400px;
|
||||||
|
width: 100%;
|
||||||
|
margin: 0 auto;
|
||||||
|
padding: 0 4rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 1. HERO */
|
||||||
|
.hero {
|
||||||
|
position: relative;
|
||||||
|
min-height: 85vh;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
overflow: hidden;
|
||||||
|
padding-top: 100px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.heroBg {
|
||||||
|
position: absolute;
|
||||||
|
inset: 0;
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bgImg {
|
||||||
|
object-fit: cover;
|
||||||
|
filter: brightness(0.25) saturate(0.2) contrast(1.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.heroOverlay {
|
||||||
|
position: absolute;
|
||||||
|
inset: 0;
|
||||||
|
background: linear-gradient(to right, rgba(0,0,0,0.95) 0%, rgba(0,0,0,0.5) 100%);
|
||||||
|
z-index: 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.heroContent {
|
||||||
|
position: relative;
|
||||||
|
z-index: 3;
|
||||||
|
max-width: 800px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.label {
|
||||||
|
font-size: 0.65rem;
|
||||||
|
font-weight: 900;
|
||||||
|
color: var(--primary);
|
||||||
|
letter-spacing: 0.3em;
|
||||||
|
display: block;
|
||||||
|
margin-bottom: 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.title {
|
||||||
|
font-size: clamp(3rem, 7vw, 5.5rem);
|
||||||
|
font-weight: 900;
|
||||||
|
line-height: 0.95;
|
||||||
|
letter-spacing: -0.05em;
|
||||||
|
margin-bottom: 2.5rem;
|
||||||
|
text-transform: uppercase;
|
||||||
|
}
|
||||||
|
|
||||||
|
.red {
|
||||||
|
color: var(--primary);
|
||||||
|
font-style: italic;
|
||||||
|
}
|
||||||
|
|
||||||
|
.desc {
|
||||||
|
font-size: 1.2rem;
|
||||||
|
color: #888;
|
||||||
|
line-height: 1.6;
|
||||||
|
max-width: 600px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 2. STORY SECTION */
|
||||||
|
.story {
|
||||||
|
padding: 15rem 0;
|
||||||
|
border-bottom: 1px solid var(--border);
|
||||||
|
}
|
||||||
|
|
||||||
|
.storyGrid {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 1.2fr 1fr;
|
||||||
|
gap: 10rem;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.storyText h2 {
|
||||||
|
font-size: 3rem;
|
||||||
|
font-weight: 900;
|
||||||
|
margin-bottom: 3rem;
|
||||||
|
letter-spacing: -0.05em;
|
||||||
|
text-transform: uppercase;
|
||||||
|
}
|
||||||
|
|
||||||
|
.storyText p {
|
||||||
|
font-size: 1.1rem;
|
||||||
|
color: #888;
|
||||||
|
line-height: 1.8;
|
||||||
|
margin-bottom: 4rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stats {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(3, 1fr);
|
||||||
|
gap: 3rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.statItem strong {
|
||||||
|
display: block;
|
||||||
|
font-size: 2.5rem;
|
||||||
|
font-weight: 900;
|
||||||
|
color: #fff;
|
||||||
|
margin-bottom: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.statItem span {
|
||||||
|
font-size: 0.6rem;
|
||||||
|
color: #555;
|
||||||
|
font-weight: 900;
|
||||||
|
letter-spacing: 0.1em;
|
||||||
|
text-transform: uppercase;
|
||||||
|
}
|
||||||
|
|
||||||
|
.storyVisual {
|
||||||
|
position: relative;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.visualStack {
|
||||||
|
position: relative;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mainVisual {
|
||||||
|
width: 100%;
|
||||||
|
height: auto;
|
||||||
|
filter: saturate(0.5) contrast(1.1);
|
||||||
|
border-radius: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.floatingTag {
|
||||||
|
position: absolute;
|
||||||
|
bottom: -30px;
|
||||||
|
right: 20px;
|
||||||
|
background-color: var(--primary);
|
||||||
|
color: #fff;
|
||||||
|
padding: 1.5rem 2.5rem;
|
||||||
|
font-size: 0.7rem;
|
||||||
|
font-weight: 900;
|
||||||
|
letter-spacing: 0.1em;
|
||||||
|
border-radius: 4px;
|
||||||
|
box-shadow: 0 20px 40px rgba(0,0,0,0.5);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 3. LAB SECTION */
|
||||||
|
.lab {
|
||||||
|
padding: 15rem 0;
|
||||||
|
background-color: var(--secondary);
|
||||||
|
border-bottom: 1px solid var(--border);
|
||||||
|
}
|
||||||
|
|
||||||
|
.labHeader {
|
||||||
|
text-align: center;
|
||||||
|
max-width: 800px;
|
||||||
|
margin: 0 auto 8rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.redIcon {
|
||||||
|
margin-bottom: 2rem;
|
||||||
|
filter: drop-shadow(0 0 10px var(--primary));
|
||||||
|
}
|
||||||
|
|
||||||
|
.labHeader h2 {
|
||||||
|
font-size: 3.5rem;
|
||||||
|
font-weight: 900;
|
||||||
|
margin-bottom: 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.labHeader p {
|
||||||
|
font-size: 1.1rem;
|
||||||
|
color: #888;
|
||||||
|
line-height: 1.6;
|
||||||
|
}
|
||||||
|
|
||||||
|
.labGrid {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(3, 1fr);
|
||||||
|
gap: 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.labCard {
|
||||||
|
background-color: var(--neutral);
|
||||||
|
border: 1px solid var(--border);
|
||||||
|
padding: 3rem;
|
||||||
|
border-radius: 8px;
|
||||||
|
transition: all 0.4s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.labCard:hover {
|
||||||
|
border-color: var(--primary);
|
||||||
|
transform: translateY(-10px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.labImgBox {
|
||||||
|
position: relative;
|
||||||
|
width: 100%;
|
||||||
|
height: 300px;
|
||||||
|
border-radius: 4px;
|
||||||
|
overflow: hidden;
|
||||||
|
margin-bottom: 2.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.labImg {
|
||||||
|
object-fit: cover;
|
||||||
|
filter: brightness(0.6) saturate(0.2);
|
||||||
|
transition: transform 0.6s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.labCard:hover .labImg {
|
||||||
|
filter: brightness(0.8) saturate(0.6);
|
||||||
|
transform: scale(1.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.labCard h3 {
|
||||||
|
font-size: 1.1rem;
|
||||||
|
font-weight: 900;
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
color: #fff;
|
||||||
|
letter-spacing: 0.1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.labCard p {
|
||||||
|
font-size: 0.85rem;
|
||||||
|
color: #777;
|
||||||
|
line-height: 1.6;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 4. TIMELINE SEC */
|
||||||
|
.timelineSec {
|
||||||
|
padding: 15rem 0;
|
||||||
|
background-color: var(--neutral);
|
||||||
|
}
|
||||||
|
|
||||||
|
.timelineTitle {
|
||||||
|
font-size: 3.5rem;
|
||||||
|
font-weight: 900;
|
||||||
|
text-align: center;
|
||||||
|
margin-bottom: 8rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.timeline {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(4, 1fr);
|
||||||
|
gap: 2rem;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tlItem {
|
||||||
|
position: relative;
|
||||||
|
padding-top: 4rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tlYear {
|
||||||
|
font-size: 1rem;
|
||||||
|
font-weight: 900;
|
||||||
|
color: var(--primary);
|
||||||
|
letter-spacing: 0.1em;
|
||||||
|
display: block;
|
||||||
|
margin-bottom: 1.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tlDot {
|
||||||
|
width: 16px;
|
||||||
|
height: 16px;
|
||||||
|
background-color: var(--primary);
|
||||||
|
border-radius: 50%;
|
||||||
|
position: absolute;
|
||||||
|
top: -8px;
|
||||||
|
left: 0;
|
||||||
|
box-shadow: 0 0 15px var(--primary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.timeline::after {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
height: 1px;
|
||||||
|
background-color: var(--border);
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tlItem h3 {
|
||||||
|
font-size: 1.2rem;
|
||||||
|
font-weight: 900;
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tlItem p {
|
||||||
|
font-size: 0.85rem;
|
||||||
|
color: #666;
|
||||||
|
line-height: 1.6;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 5. CTA SECTION */
|
||||||
|
.cta {
|
||||||
|
padding: 10rem 0 15rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ctaCard {
|
||||||
|
background-color: var(--secondary);
|
||||||
|
border: 1px solid var(--border);
|
||||||
|
padding: 8rem 5rem;
|
||||||
|
border-radius: 8px;
|
||||||
|
text-align: center;
|
||||||
|
position: relative;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ctaCard h2 {
|
||||||
|
font-size: 3.5rem;
|
||||||
|
font-weight: 900;
|
||||||
|
margin-bottom: 2rem;
|
||||||
|
letter-spacing: -0.05em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ctaCard p {
|
||||||
|
font-size: 1.2rem;
|
||||||
|
color: #888;
|
||||||
|
margin-bottom: 4rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ctaActions {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
gap: 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.primaryBtn {
|
||||||
|
background-color: var(--primary);
|
||||||
|
color: #fff;
|
||||||
|
padding: 1.5rem 3.5rem;
|
||||||
|
border-radius: 4px;
|
||||||
|
font-size: 0.75rem;
|
||||||
|
font-weight: 900;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 1.2rem;
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.secondaryBtn {
|
||||||
|
background-color: rgba(255, 255, 255, 0.02);
|
||||||
|
border: 1px solid var(--border);
|
||||||
|
color: #fff;
|
||||||
|
padding: 1.5rem 3.5rem;
|
||||||
|
border-radius: 4px;
|
||||||
|
font-size: 0.75rem;
|
||||||
|
font-weight: 900;
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.primaryBtn:hover { transform: translateY(-5px); box-shadow: 0 10px 30px rgba(255, 0, 0, 0.2); }
|
||||||
|
.secondaryBtn:hover { background-color: rgba(255, 255, 255, 0.05); transform: translateY(-3px); }
|
||||||
|
|
||||||
|
@media (max-width: 1024px) {
|
||||||
|
.storyGrid, .labGrid, .timeline { grid-template-columns: 1fr; gap: 4rem; }
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
.container { padding: 0 2rem; }
|
||||||
|
}
|
||||||
183
src/app/about/page.tsx
Normal file
@ -0,0 +1,183 @@
|
|||||||
|
'use client';
|
||||||
|
|
||||||
|
import Navbar from '@/components/Navbar';
|
||||||
|
import Footer from '@/components/Footer';
|
||||||
|
import { motion } from 'framer-motion';
|
||||||
|
import Image from 'next/image';
|
||||||
|
import { Shield, Target, Cpu, Globe, Zap, History, ChevronRight } from 'lucide-react';
|
||||||
|
import styles from './AboutPage.module.css';
|
||||||
|
|
||||||
|
export default function AboutPage() {
|
||||||
|
const milestones = [
|
||||||
|
{ year: '2004', title: 'The Foundation', desc: 'Hondavert born from high-performance circuit racing needs.' },
|
||||||
|
{ year: '2010', title: 'CAN Interface Rev 1', desc: 'First universal CAN-Bus interface developed for K-Series.' },
|
||||||
|
{ year: '2018', title: 'Rev 4 Legacy', desc: 'Release of the Bluetooth-enabled daughterboard system.' },
|
||||||
|
{ year: '2026', title: 'Future of Flash', desc: 'Expanding platform diagnostics to modern direct-injection engines.' },
|
||||||
|
];
|
||||||
|
|
||||||
|
return (
|
||||||
|
<main className={styles.main}>
|
||||||
|
<Navbar />
|
||||||
|
|
||||||
|
{/* 1. INNER BANNER (UNIQUE HERO) */}
|
||||||
|
<section className={styles.hero}>
|
||||||
|
<div className={styles.heroBg}>
|
||||||
|
<Image
|
||||||
|
src="/engine_bay.png"
|
||||||
|
alt="Engineering Hub"
|
||||||
|
fill
|
||||||
|
priority
|
||||||
|
className={styles.bgImg}
|
||||||
|
/>
|
||||||
|
<div className={styles.heroOverlay}></div>
|
||||||
|
</div>
|
||||||
|
<div className={styles.container}>
|
||||||
|
<motion.div
|
||||||
|
className={styles.heroContent}
|
||||||
|
initial={{ opacity: 0, y: 30 }}
|
||||||
|
animate={{ opacity: 1, y: 0 }}
|
||||||
|
transition={{ duration: 0.8 }}
|
||||||
|
>
|
||||||
|
<span className={styles.label}>ESTABLISHED 2004</span>
|
||||||
|
<h1 className={styles.title}>BEYOND TUNING. <br />WE <span className={styles.red}>ENGINEER</span> SOLUTIONS.</h1>
|
||||||
|
<p className={styles.desc}>
|
||||||
|
With over 20 years of technical intelligence, Hondavert is the global standard for Honda engine management hardware and software.
|
||||||
|
</p>
|
||||||
|
</motion.div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
{/* 2. THE ENGINEERING STORY (UNIQUE LOOK) */}
|
||||||
|
<section className={styles.story}>
|
||||||
|
<div className={styles.container}>
|
||||||
|
<div className={styles.storyGrid}>
|
||||||
|
<motion.div
|
||||||
|
className={styles.storyText}
|
||||||
|
initial={{ opacity: 0, x: -30 }}
|
||||||
|
whileInView={{ opacity: 1, x: 0 }}
|
||||||
|
viewport={{ once: true }}
|
||||||
|
>
|
||||||
|
<h2>OUR TECHNICAL <span className={styles.red}>LEGACY</span></h2>
|
||||||
|
<p>
|
||||||
|
From building prototype motherboards in a small Warsaw laboratory to supporting thousands of K-Swap projects worldwide,
|
||||||
|
our DNA has always been rooted in precision electronics. We don't just sell interfaces; we develop the bridges that connect
|
||||||
|
modern computational speed with classic performance automotive engines.
|
||||||
|
</p>
|
||||||
|
<div className={styles.stats}>
|
||||||
|
<div className={styles.statItem}>
|
||||||
|
<strong>40+</strong>
|
||||||
|
<span>COUNTRIES SUPPORTED</span>
|
||||||
|
</div>
|
||||||
|
<div className={styles.statItem}>
|
||||||
|
<strong>100k+</strong>
|
||||||
|
<span>LINE CODES WRITTEN</span>
|
||||||
|
</div>
|
||||||
|
<div className={styles.statItem}>
|
||||||
|
<strong>100Hz</strong>
|
||||||
|
<span>DATALOGGING STANDARDS</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</motion.div>
|
||||||
|
<motion.div
|
||||||
|
className={styles.storyVisual}
|
||||||
|
initial={{ opacity: 0, scale: 0.95 }}
|
||||||
|
whileInView={{ opacity: 1, scale: 1 }}
|
||||||
|
viewport={{ once: true }}
|
||||||
|
>
|
||||||
|
<div className={styles.visualStack}>
|
||||||
|
<Image src="/ecu_kpro.png" width={500} height={500} alt="ECU Engineering" className={styles.mainVisual} />
|
||||||
|
<div className={styles.floatingTag}>REV.4 CORE</div>
|
||||||
|
</div>
|
||||||
|
</motion.div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
{/* 3. LABORATORY FOCUS (NEW SECTION) */}
|
||||||
|
<section className={styles.lab}>
|
||||||
|
<div className={styles.container}>
|
||||||
|
<motion.div
|
||||||
|
className={styles.labHeader}
|
||||||
|
initial={{ opacity: 0, y: 20 }}
|
||||||
|
whileInView={{ opacity: 1, y: 0 }}
|
||||||
|
viewport={{ once: true }}
|
||||||
|
>
|
||||||
|
<Cpu size={40} className={styles.redIcon} />
|
||||||
|
<h2>THE <span className={styles.red}>LABORATORY</span></h2>
|
||||||
|
<p>Our in-house R&D facility utilizes specialized oscilloscope diagnostic tools and high-speed data acquisition
|
||||||
|
systems to ensure maximum stability on every board produced.</p>
|
||||||
|
</motion.div>
|
||||||
|
|
||||||
|
<div className={styles.labGrid}>
|
||||||
|
<div className={styles.labCard}>
|
||||||
|
<div className={styles.labImgBox}>
|
||||||
|
<Image src="https://images.unsplash.com/photo-1695653422718-97d25c1cb8ec?q=80&w=1200" fill alt="Lab 1" className={styles.labImg} />
|
||||||
|
</div>
|
||||||
|
<h3>PROTO-BOARDING</h3>
|
||||||
|
<p>Rigorous multi-layer PCB testing for thermal stability and noise isolation.</p>
|
||||||
|
</div>
|
||||||
|
<div className={styles.labCard}>
|
||||||
|
<div className={styles.labImgBox}>
|
||||||
|
<Image src="https://images.unsplash.com/photo-1518770660439-4636190af475?q=80&w=1200" fill alt="Lab 2" className={styles.labImg} />
|
||||||
|
</div>
|
||||||
|
<h3>FIRMWARE STABILITY</h3>
|
||||||
|
<p>Real-time OKI/MCU emulation to eliminate communication lag.</p>
|
||||||
|
</div>
|
||||||
|
<div className={styles.labCard}>
|
||||||
|
<div className={styles.labImgBox}>
|
||||||
|
<Image src="https://images.unsplash.com/photo-1620288627223-53302f4e8c74?q=80&w=1200" fill alt="Lab 3" className={styles.labImg} />
|
||||||
|
</div>
|
||||||
|
<h3>CAN-BUS AUDITS</h3>
|
||||||
|
<p>Ensuring 100% telemetry accuracy for diagnostic tools.</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
{/* 4. TIMELINE (NEW SECTION) */}
|
||||||
|
<section className={styles.timelineSec}>
|
||||||
|
<div className={styles.container}>
|
||||||
|
<h2 className={styles.timelineTitle}>OUR <span className={styles.red}>JOURNEY</span></h2>
|
||||||
|
<div className={styles.timeline}>
|
||||||
|
{milestones.map((m, i) => (
|
||||||
|
<motion.div
|
||||||
|
key={i}
|
||||||
|
className={styles.tlItem}
|
||||||
|
initial={{ opacity: 0, y: 30 }}
|
||||||
|
whileInView={{ opacity: 1, y: 0 }}
|
||||||
|
viewport={{ once: true }}
|
||||||
|
transition={{ delay: i * 0.1 }}
|
||||||
|
>
|
||||||
|
<span className={styles.tlYear}>{m.year}</span>
|
||||||
|
<div className={styles.tlDot}></div>
|
||||||
|
<h3>{m.title}</h3>
|
||||||
|
<p>{m.desc}</p>
|
||||||
|
</motion.div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
{/* 5. CTA SECTION */}
|
||||||
|
<section className={styles.cta}>
|
||||||
|
<div className={styles.container}>
|
||||||
|
<motion.div
|
||||||
|
className={styles.ctaCard}
|
||||||
|
initial={{ opacity: 0, scale: 0.95 }}
|
||||||
|
whileInView={{ opacity: 1, scale: 1 }}
|
||||||
|
viewport={{ once: true }}
|
||||||
|
>
|
||||||
|
<h2>READY TO UNLOCK YOUR ENGINE?</h2>
|
||||||
|
<p>Our technical team is ready to support your next high-performance ECU upgrade.</p>
|
||||||
|
<div className={styles.ctaActions}>
|
||||||
|
<button className={styles.primaryBtn}>EXPLORE PRODUCTS <ChevronRight size={18} /></button>
|
||||||
|
<button className={styles.secondaryBtn}>CONTACT SUPPORT</button>
|
||||||
|
</div>
|
||||||
|
</motion.div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<Footer />
|
||||||
|
</main>
|
||||||
|
);
|
||||||
|
}
|
||||||
21
src/app/blog/page.tsx
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
import Navbar from '@/components/Navbar';
|
||||||
|
import Footer from '@/components/Footer';
|
||||||
|
import Blog from '@/components/Blog';
|
||||||
|
import { Metadata } from 'next';
|
||||||
|
|
||||||
|
export const metadata: Metadata = {
|
||||||
|
title: 'Blog | Engineering Hub | Hondavert Performance',
|
||||||
|
description: 'Technical insights, firmware updates, and news on JDM engine management systems.',
|
||||||
|
};
|
||||||
|
|
||||||
|
export default function BlogPage() {
|
||||||
|
return (
|
||||||
|
<main>
|
||||||
|
<Navbar />
|
||||||
|
<div style={{ paddingTop: '100px', backgroundColor: 'var(--neutral)' }}>
|
||||||
|
<Blog />
|
||||||
|
</div>
|
||||||
|
<Footer />
|
||||||
|
</main>
|
||||||
|
);
|
||||||
|
}
|
||||||
19
src/app/contact/page.tsx
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
import Navbar from '@/components/Navbar';
|
||||||
|
import Footer from '@/components/Footer';
|
||||||
|
import Contact from '@/components/Contact';
|
||||||
|
import { Metadata } from 'next';
|
||||||
|
|
||||||
|
export const metadata: Metadata = {
|
||||||
|
title: 'Contact Us | Technical Support & Sales | Hondavert Performance',
|
||||||
|
description: 'Reach our specialized team for technical consultations, installation queries, and dealer netwok applications.',
|
||||||
|
};
|
||||||
|
|
||||||
|
export default function ContactPage() {
|
||||||
|
return (
|
||||||
|
<main>
|
||||||
|
<Navbar />
|
||||||
|
<Contact />
|
||||||
|
<Footer />
|
||||||
|
</main>
|
||||||
|
);
|
||||||
|
}
|
||||||
BIN
src/app/favicon.ico
Normal file
|
After Width: | Height: | Size: 25 KiB |
67
src/app/globals.css
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
:root {
|
||||||
|
--primary: #FF0000;
|
||||||
|
--primary-hover: #D60000;
|
||||||
|
--secondary: #212121;
|
||||||
|
--tertiary: #00808C;
|
||||||
|
--neutral: #121212;
|
||||||
|
--background: #121212;
|
||||||
|
--card-bg: #212121;
|
||||||
|
--text-main: #FFFFFF;
|
||||||
|
--text-muted: #A1A1A1;
|
||||||
|
--border: rgba(255, 255, 255, 0.08);
|
||||||
|
}
|
||||||
|
|
||||||
|
* {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
background-color: var(--background);
|
||||||
|
color: var(--text-main);
|
||||||
|
font-family: 'Inter', sans-serif;
|
||||||
|
overflow-x: hidden;
|
||||||
|
-webkit-font-smoothing: antialiased;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: inherit;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
button {
|
||||||
|
background: none;
|
||||||
|
border: none;
|
||||||
|
cursor: pointer;
|
||||||
|
font-family: inherit;
|
||||||
|
transition: all 0.2s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Custom Scrollbar */
|
||||||
|
::-webkit-scrollbar {
|
||||||
|
width: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
::-webkit-scrollbar-track {
|
||||||
|
background: var(--background);
|
||||||
|
}
|
||||||
|
|
||||||
|
::-webkit-scrollbar-thumb {
|
||||||
|
background: var(--secondary);
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
::-webkit-scrollbar-thumb:hover {
|
||||||
|
background: var(--primary);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Utility Animations */
|
||||||
|
@keyframes fadeIn {
|
||||||
|
from { opacity: 0; transform: translateY(20px); }
|
||||||
|
to { opacity: 1; transform: translateY(0); }
|
||||||
|
}
|
||||||
|
|
||||||
|
.fade-in {
|
||||||
|
animation: fadeIn 0.8s ease forwards;
|
||||||
|
}
|
||||||
27
src/app/layout.tsx
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
import type { Metadata } from "next";
|
||||||
|
import { Inter } from "next/font/google";
|
||||||
|
import "./globals.css";
|
||||||
|
|
||||||
|
const inter = Inter({
|
||||||
|
variable: "--font-inter",
|
||||||
|
subsets: ["latin"],
|
||||||
|
});
|
||||||
|
|
||||||
|
export const metadata: Metadata = {
|
||||||
|
title: "HONDA VERT | ECU Management & Performance Engineering",
|
||||||
|
description: "The ultimate tuning interface for Honda K-Series engines. Surgical precision meets raw performance.",
|
||||||
|
};
|
||||||
|
|
||||||
|
export default function RootLayout({
|
||||||
|
children,
|
||||||
|
}: Readonly<{
|
||||||
|
children: React.ReactNode;
|
||||||
|
}>) {
|
||||||
|
return (
|
||||||
|
<html lang="en" className={inter.variable}>
|
||||||
|
<body>
|
||||||
|
{children}
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
);
|
||||||
|
}
|
||||||
142
src/app/page.module.css
Normal file
@ -0,0 +1,142 @@
|
|||||||
|
.page {
|
||||||
|
--background: #fafafa;
|
||||||
|
--foreground: #fff;
|
||||||
|
|
||||||
|
--text-primary: #000;
|
||||||
|
--text-secondary: #666;
|
||||||
|
|
||||||
|
--button-primary-hover: #383838;
|
||||||
|
--button-secondary-hover: #f2f2f2;
|
||||||
|
--button-secondary-border: #ebebeb;
|
||||||
|
|
||||||
|
display: flex;
|
||||||
|
flex: 1;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
font-family: var(--font-geist-sans);
|
||||||
|
background-color: var(--background);
|
||||||
|
}
|
||||||
|
|
||||||
|
.main {
|
||||||
|
display: flex;
|
||||||
|
flex: 1;
|
||||||
|
width: 100%;
|
||||||
|
max-width: 800px;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: flex-start;
|
||||||
|
justify-content: space-between;
|
||||||
|
background-color: var(--foreground);
|
||||||
|
padding: 120px 60px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.intro {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: flex-start;
|
||||||
|
text-align: left;
|
||||||
|
gap: 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.intro h1 {
|
||||||
|
max-width: 320px;
|
||||||
|
font-size: 40px;
|
||||||
|
font-weight: 600;
|
||||||
|
line-height: 48px;
|
||||||
|
letter-spacing: -2.4px;
|
||||||
|
text-wrap: balance;
|
||||||
|
color: var(--text-primary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.intro p {
|
||||||
|
max-width: 440px;
|
||||||
|
font-size: 18px;
|
||||||
|
line-height: 32px;
|
||||||
|
text-wrap: balance;
|
||||||
|
color: var(--text-secondary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.intro a {
|
||||||
|
font-weight: 500;
|
||||||
|
color: var(--text-primary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.ctas {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
width: 100%;
|
||||||
|
max-width: 440px;
|
||||||
|
gap: 16px;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ctas a {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
height: 40px;
|
||||||
|
padding: 0 16px;
|
||||||
|
border-radius: 128px;
|
||||||
|
border: 1px solid transparent;
|
||||||
|
transition: 0.2s;
|
||||||
|
cursor: pointer;
|
||||||
|
width: fit-content;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
a.primary {
|
||||||
|
background: var(--text-primary);
|
||||||
|
color: var(--background);
|
||||||
|
gap: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
a.secondary {
|
||||||
|
border-color: var(--button-secondary-border);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Enable hover only on non-touch devices */
|
||||||
|
@media (hover: hover) and (pointer: fine) {
|
||||||
|
a.primary:hover {
|
||||||
|
background: var(--button-primary-hover);
|
||||||
|
border-color: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
a.secondary:hover {
|
||||||
|
background: var(--button-secondary-hover);
|
||||||
|
border-color: transparent;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 600px) {
|
||||||
|
.main {
|
||||||
|
padding: 48px 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.intro {
|
||||||
|
gap: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.intro h1 {
|
||||||
|
font-size: 32px;
|
||||||
|
line-height: 40px;
|
||||||
|
letter-spacing: -1.92px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (prefers-color-scheme: dark) {
|
||||||
|
.logo {
|
||||||
|
filter: invert();
|
||||||
|
}
|
||||||
|
|
||||||
|
.page {
|
||||||
|
--background: #000;
|
||||||
|
--foreground: #000;
|
||||||
|
|
||||||
|
--text-primary: #ededed;
|
||||||
|
--text-secondary: #999;
|
||||||
|
|
||||||
|
--button-primary-hover: #ccc;
|
||||||
|
--button-secondary-hover: #1a1a1a;
|
||||||
|
--button-secondary-border: #1a1a1a;
|
||||||
|
}
|
||||||
|
}
|
||||||
36
src/app/page.tsx
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
import Navbar from '@/components/Navbar';
|
||||||
|
import HomeHeroSlider from '@/components/HomeHeroSlider';
|
||||||
|
import About from '@/components/About';
|
||||||
|
import HomeProducts from '@/components/HomeProducts';
|
||||||
|
import WhyChooseUs from '@/components/WhyChooseUs';
|
||||||
|
import Testimonials from '@/components/Testimonials';
|
||||||
|
import Blog from '@/components/Blog';
|
||||||
|
import Footer from '@/components/Footer';
|
||||||
|
|
||||||
|
export default function Home() {
|
||||||
|
return (
|
||||||
|
<main>
|
||||||
|
<Navbar />
|
||||||
|
|
||||||
|
{/* 1. BANNER 3 SLIDER */}
|
||||||
|
<HomeHeroSlider />
|
||||||
|
|
||||||
|
{/* 2. ABOUT SECTION */}
|
||||||
|
<About />
|
||||||
|
|
||||||
|
{/* 3. PRODUCTS SECTION */}
|
||||||
|
<HomeProducts />
|
||||||
|
|
||||||
|
{/* 4. WHY CHOOSE US SECTION */}
|
||||||
|
<WhyChooseUs />
|
||||||
|
|
||||||
|
{/* 5. CLIENT TESTIMONIALS SECTION */}
|
||||||
|
<Testimonials />
|
||||||
|
|
||||||
|
{/* 6. BLOG SECTION */}
|
||||||
|
<Blog />
|
||||||
|
|
||||||
|
<Footer />
|
||||||
|
</main>
|
||||||
|
);
|
||||||
|
}
|
||||||
101
src/app/products/ProductsPage.module.css
Normal file
@ -0,0 +1,101 @@
|
|||||||
|
.wrapper {
|
||||||
|
background-color: #000;
|
||||||
|
min-height: 100vh;
|
||||||
|
}
|
||||||
|
|
||||||
|
.container {
|
||||||
|
max-width: 1400px;
|
||||||
|
width: 100%;
|
||||||
|
margin: 0 auto;
|
||||||
|
padding: 0 4rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hero {
|
||||||
|
position: relative;
|
||||||
|
min-height: 80vh;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
padding-top: 100px;
|
||||||
|
padding-bottom: 50px;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.heroGlow {
|
||||||
|
position: absolute;
|
||||||
|
top: -20%;
|
||||||
|
right: -10%;
|
||||||
|
width: 800px;
|
||||||
|
height: 800px;
|
||||||
|
background: radial-gradient(circle at center, rgba(255, 0, 0, 0.08) 0%, transparent 70%);
|
||||||
|
filter: blur(100px);
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.heroContent {
|
||||||
|
position: relative;
|
||||||
|
z-index: 2;
|
||||||
|
max-width: 800px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.badge {
|
||||||
|
font-size: 0.65rem;
|
||||||
|
font-weight: 900;
|
||||||
|
color: var(--primary);
|
||||||
|
border: 1px solid var(--primary);
|
||||||
|
padding: 0.4rem 1rem;
|
||||||
|
border-radius: 99px;
|
||||||
|
letter-spacing: 0.2rem;
|
||||||
|
margin-bottom: 2.5rem;
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.heroTitle {
|
||||||
|
font-size: clamp(4rem, 10vw, 8rem);
|
||||||
|
font-weight: 900;
|
||||||
|
letter-spacing: -0.06em;
|
||||||
|
line-height: 0.8;
|
||||||
|
margin-bottom: 2.5rem;
|
||||||
|
text-transform: uppercase;
|
||||||
|
}
|
||||||
|
|
||||||
|
.red {
|
||||||
|
color: var(--primary);
|
||||||
|
font-style: italic;
|
||||||
|
}
|
||||||
|
|
||||||
|
.heroDesc {
|
||||||
|
font-size: 1.2rem;
|
||||||
|
max-width: 600px;
|
||||||
|
color: #888;
|
||||||
|
line-height: 1.6;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
.productsSection {
|
||||||
|
background-color: #050505;
|
||||||
|
padding: 100px 0;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.grid {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(auto-fit, minmax(400px, 1fr));
|
||||||
|
gap: 3rem;
|
||||||
|
margin-top: -150px; /* Overlap effect */
|
||||||
|
position: relative;
|
||||||
|
z-index: 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 1024px) {
|
||||||
|
.hero {
|
||||||
|
min-height: 60vh;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
.heroContent {
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
|
.grid {
|
||||||
|
margin-top: 0;
|
||||||
|
grid-template-columns: 1fr;
|
||||||
|
}
|
||||||
|
}
|
||||||
76
src/app/products/[id]/page.tsx
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
import { notFound } from 'next/navigation';
|
||||||
|
import Navbar from '@/components/Navbar';
|
||||||
|
import Footer from '@/components/Footer';
|
||||||
|
import Hero from '@/components/Hero';
|
||||||
|
import Compatibility from '@/components/Compatibility';
|
||||||
|
import PreCAN from '@/components/PreCAN';
|
||||||
|
import Telemetry from '@/components/Telemetry';
|
||||||
|
import Sensor from '@/components/Sensor';
|
||||||
|
import ProductShowcase from '@/components/ProductShowcase';
|
||||||
|
import CANFlash from '@/components/CANFlash';
|
||||||
|
import S300 from '@/components/S300';
|
||||||
|
import MapSensor from '@/components/MapSensor';
|
||||||
|
import Features from '@/components/Features';
|
||||||
|
import CTA from '@/components/CTA';
|
||||||
|
import { products } from '@/lib/products';
|
||||||
|
|
||||||
|
interface PageProps {
|
||||||
|
params: Promise<{ id: string }>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default async function ProductDetailPage({ params }: PageProps) {
|
||||||
|
const { id } = await params;
|
||||||
|
const product = products.find((p) => p.id === id);
|
||||||
|
|
||||||
|
if (!product) {
|
||||||
|
notFound();
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<main>
|
||||||
|
<Navbar />
|
||||||
|
|
||||||
|
{id === 'kpro' && (
|
||||||
|
<>
|
||||||
|
<Hero
|
||||||
|
version={product.version}
|
||||||
|
title1={product.name}
|
||||||
|
title2={product.subtitle}
|
||||||
|
description={product.description}
|
||||||
|
image={product.image}
|
||||||
|
badge={product.badge}
|
||||||
|
/>
|
||||||
|
<Compatibility />
|
||||||
|
<Telemetry />
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{id === 'canflash' && (
|
||||||
|
<>
|
||||||
|
<CANFlash />
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{id === 'precan' && (
|
||||||
|
<>
|
||||||
|
<PreCAN />
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{id === 's300' && (
|
||||||
|
<>
|
||||||
|
<S300 />
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{id === 'map-sensor' && (
|
||||||
|
<>
|
||||||
|
<MapSensor />
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{id !== 'kpro' && id !== 'canflash' && id !== 'precan' && id !== 's300' && id !== 'map-sensor' && <CTA />}
|
||||||
|
<Footer />
|
||||||
|
</main>
|
||||||
|
);
|
||||||
|
}
|
||||||
19
src/app/products/kpro/page.tsx
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
import Navbar from '@/components/Navbar';
|
||||||
|
import Footer from '@/components/Footer';
|
||||||
|
import KPro from '@/components/KPro';
|
||||||
|
import { Metadata } from 'next';
|
||||||
|
|
||||||
|
export const metadata: Metadata = {
|
||||||
|
title: 'KPro | Hondavert Performance',
|
||||||
|
description: 'Unlock the full potential of your Honda K-Series ECU with the Hondavert KPro daughterboard. Live tuning, datalogging, and advanced engine protection.',
|
||||||
|
};
|
||||||
|
|
||||||
|
export default function KProPage() {
|
||||||
|
return (
|
||||||
|
<main>
|
||||||
|
<Navbar />
|
||||||
|
<KPro />
|
||||||
|
<Footer />
|
||||||
|
</main>
|
||||||
|
);
|
||||||
|
}
|
||||||
47
src/app/products/page.tsx
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
import Navbar from '@/components/Navbar';
|
||||||
|
import Footer from '@/components/Footer';
|
||||||
|
import ProductCard from '@/components/ProductCard';
|
||||||
|
import { products } from '@/lib/products';
|
||||||
|
import styles from './ProductsPage.module.css';
|
||||||
|
|
||||||
|
export default function ProductsPage() {
|
||||||
|
return (
|
||||||
|
<main className={styles.wrapper}>
|
||||||
|
<Navbar />
|
||||||
|
|
||||||
|
<section className={styles.hero}>
|
||||||
|
<div className={styles.heroGlow}></div>
|
||||||
|
<div className={styles.container}>
|
||||||
|
<div className={styles.heroContent}>
|
||||||
|
<span className={styles.badge}>PRECISION ENGINEERED</span>
|
||||||
|
<h1 className={styles.heroTitle}>SELECT YOUR <br/><span className={styles.red}>PLATFORM</span></h1>
|
||||||
|
<p className={styles.heroDesc}>
|
||||||
|
Mission-critical engine management for the most demanding Honda builds.
|
||||||
|
Scroll to explore our complete technological ecosystem.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section className={styles.productsSection}>
|
||||||
|
<div className={styles.container}>
|
||||||
|
<div className={styles.grid}>
|
||||||
|
{products.map((product, i) => (
|
||||||
|
<ProductCard
|
||||||
|
key={product.id}
|
||||||
|
id={product.id}
|
||||||
|
name={product.name}
|
||||||
|
subtitle={product.subtitle}
|
||||||
|
description={product.description}
|
||||||
|
image={product.image}
|
||||||
|
price={product.price}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<Footer />
|
||||||
|
</main>
|
||||||
|
);
|
||||||
|
}
|
||||||
155
src/components/About.module.css
Normal file
@ -0,0 +1,155 @@
|
|||||||
|
.section {
|
||||||
|
padding: 150px 0;
|
||||||
|
background-color: var(--neutral);
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.container {
|
||||||
|
max-width: 1400px;
|
||||||
|
width: 100%;
|
||||||
|
margin: 0 auto;
|
||||||
|
padding: 0 4rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.grid {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 1fr 1.2fr;
|
||||||
|
gap: 10rem;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.label {
|
||||||
|
font-size: 0.65rem;
|
||||||
|
font-weight: 900;
|
||||||
|
color: var(--primary);
|
||||||
|
letter-spacing: 0.15em;
|
||||||
|
margin-bottom: 2rem;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.title {
|
||||||
|
font-size: clamp(2rem, 4vw, 3.5rem);
|
||||||
|
font-weight: 900;
|
||||||
|
line-height: 1;
|
||||||
|
letter-spacing: -0.05em;
|
||||||
|
margin-bottom: 3.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.desc {
|
||||||
|
font-size: 1.1rem;
|
||||||
|
color: #888;
|
||||||
|
line-height: 1.8;
|
||||||
|
margin-bottom: 4rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stats {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 3rem;
|
||||||
|
margin-bottom: 4rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.statItem {
|
||||||
|
display: flex;
|
||||||
|
gap: 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.statIcon {
|
||||||
|
width: 50px;
|
||||||
|
height: 50px;
|
||||||
|
background-color: var(--secondary);
|
||||||
|
border: 1px solid var(--border);
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
border-radius: 4px;
|
||||||
|
color: var(--primary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.statText h3 {
|
||||||
|
font-size: 0.85rem;
|
||||||
|
font-weight: 900;
|
||||||
|
letter-spacing: 0.05em;
|
||||||
|
margin-bottom: 0.8rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.statText p {
|
||||||
|
font-size: 0.85rem;
|
||||||
|
color: #666;
|
||||||
|
line-height: 1.6;
|
||||||
|
}
|
||||||
|
|
||||||
|
.moreBtn {
|
||||||
|
background-color: transparent;
|
||||||
|
border: 1px solid var(--border);
|
||||||
|
padding: 1.2rem 2.8rem;
|
||||||
|
font-size: 0.75rem;
|
||||||
|
font-weight: 900;
|
||||||
|
letter-spacing: 0.1em;
|
||||||
|
color: #fff;
|
||||||
|
border-radius: 4px;
|
||||||
|
transition: all 0.2s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.moreBtn:hover {
|
||||||
|
background-color: #fff;
|
||||||
|
color: #000;
|
||||||
|
}
|
||||||
|
|
||||||
|
.visual {
|
||||||
|
position: relative;
|
||||||
|
padding-left: 5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.imageOverlay {
|
||||||
|
position: absolute;
|
||||||
|
top: -2rem;
|
||||||
|
left: 0;
|
||||||
|
width: 300px;
|
||||||
|
height: 300px;
|
||||||
|
background-color: var(--primary);
|
||||||
|
opacity: 0.05;
|
||||||
|
z-index: 1;
|
||||||
|
border-radius: 50%;
|
||||||
|
filter: blur(80px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.aboutImg {
|
||||||
|
width: 100%;
|
||||||
|
height: auto;
|
||||||
|
filter: saturate(0) brightness(0.7);
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.founderBox {
|
||||||
|
position: absolute;
|
||||||
|
bottom: -2rem;
|
||||||
|
left: 0;
|
||||||
|
max-width: 320px;
|
||||||
|
background-color: var(--secondary);
|
||||||
|
border: 1px solid var(--border);
|
||||||
|
padding: 3rem;
|
||||||
|
border-left: 4px solid var(--primary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.founderBox strong {
|
||||||
|
font-size: 0.65rem;
|
||||||
|
font-weight: 900;
|
||||||
|
color: var(--primary);
|
||||||
|
display: block;
|
||||||
|
margin-bottom: 1.2rem;
|
||||||
|
letter-spacing: 0.15rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.founderBox p {
|
||||||
|
font-size: 0.95rem;
|
||||||
|
color: #fff;
|
||||||
|
font-style: italic;
|
||||||
|
font-family: serif;
|
||||||
|
line-height: 1.6;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 1024px) {
|
||||||
|
.grid { grid-template-columns: 1fr; gap: 8rem; }
|
||||||
|
.founderBox { position: relative; margin-top: 2rem; left: 2rem; }
|
||||||
|
}
|
||||||
54
src/components/About.tsx
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
'use client';
|
||||||
|
|
||||||
|
import { motion } from 'framer-motion';
|
||||||
|
import Image from 'next/image';
|
||||||
|
import { Target, History, Globe } from 'lucide-react';
|
||||||
|
import styles from './About.module.css';
|
||||||
|
|
||||||
|
export default function About() {
|
||||||
|
return (
|
||||||
|
<section className={styles.section}>
|
||||||
|
<div className={styles.container}>
|
||||||
|
<div className={styles.grid}>
|
||||||
|
<div className={styles.content}>
|
||||||
|
<span className={styles.label}>ESTABLISHED 2004</span>
|
||||||
|
<h2 className={styles.title}>PRECISION ENGINEERING FOR THE JDM COMMUNITY.</h2>
|
||||||
|
<p className={styles.desc}>
|
||||||
|
For over two decades, HondaVert has been at the forefront of aftermarket engine management solutions.
|
||||||
|
Born from a passion for circuit racing and technical excellence, we develop hardware and software
|
||||||
|
that empowers enthusiasts to push the limits of their Honda platforms.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<div className={styles.stats}>
|
||||||
|
<div className={styles.statItem}>
|
||||||
|
<div className={styles.statIcon}><Target size={24} /></div>
|
||||||
|
<div className={styles.statText}>
|
||||||
|
<h3>OUR MISSION</h3>
|
||||||
|
<p>To provide surgical-grade tuning tools that bridge the gap between amateur builds and professional racing teams.</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className={styles.statItem}>
|
||||||
|
<div className={styles.statIcon}><Globe size={24} /></div>
|
||||||
|
<div className={styles.statText}>
|
||||||
|
<h3>GLOBAL NETWORK</h3>
|
||||||
|
<p>Supported by a world-wide network of certified tuners and distributors across 40+ countries.</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<button className={styles.moreBtn}>OUR HISTORY</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className={styles.visual}>
|
||||||
|
<div className={styles.imageOverlay}></div>
|
||||||
|
<Image src="/engine_bay.png" alt="Engineering Legacy" width={800} height={600} className={styles.aboutImg} />
|
||||||
|
<div className={styles.founderBox}>
|
||||||
|
<strong>DRIVEN BY PERFORMANCE</strong>
|
||||||
|
<p>"We don't just sell parts; we provide the keys to unlock hidden potential."</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
);
|
||||||
|
}
|
||||||
143
src/components/Blog.module.css
Normal file
@ -0,0 +1,143 @@
|
|||||||
|
.section {
|
||||||
|
padding: 150px 0;
|
||||||
|
background-color: var(--neutral);
|
||||||
|
}
|
||||||
|
|
||||||
|
.container {
|
||||||
|
max-width: 1400px;
|
||||||
|
width: 100%;
|
||||||
|
margin: 0 auto;
|
||||||
|
padding: 0 4rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: flex-end;
|
||||||
|
margin-bottom: 80px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.label {
|
||||||
|
font-size: 0.65rem;
|
||||||
|
font-weight: 900;
|
||||||
|
color: var(--primary);
|
||||||
|
letter-spacing: 0.15em;
|
||||||
|
margin-bottom: 2rem;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.title {
|
||||||
|
font-size: clamp(2rem, 5vw, 4rem);
|
||||||
|
font-weight: 900;
|
||||||
|
line-height: 1;
|
||||||
|
letter-spacing: -0.05em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.allBtn {
|
||||||
|
background-color: transparent;
|
||||||
|
border: 1px solid var(--border);
|
||||||
|
padding: 1.2rem 2.5rem;
|
||||||
|
font-size: 0.75rem;
|
||||||
|
font-weight: 900;
|
||||||
|
letter-spacing: 0.1em;
|
||||||
|
color: #fff;
|
||||||
|
border-radius: 4px;
|
||||||
|
transition: all 0.2s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.allBtn:hover {
|
||||||
|
background-color: #fff;
|
||||||
|
color: #000;
|
||||||
|
}
|
||||||
|
|
||||||
|
.grid {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(auto-fit, minmax(380px, 1fr));
|
||||||
|
gap: 3rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card {
|
||||||
|
background-color: var(--secondary);
|
||||||
|
border: 1px solid var(--border);
|
||||||
|
border-radius: 4px;
|
||||||
|
overflow: hidden;
|
||||||
|
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.card:hover {
|
||||||
|
border-color: var(--primary);
|
||||||
|
transform: translateY(-10px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.imageBox {
|
||||||
|
position: relative;
|
||||||
|
height: 250px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.blogImg {
|
||||||
|
object-fit: cover;
|
||||||
|
filter: saturate(0) brightness(0.6);
|
||||||
|
transition: transform 0.5s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card:hover .blogImg {
|
||||||
|
transform: scale(1.05);
|
||||||
|
}
|
||||||
|
|
||||||
|
.content {
|
||||||
|
padding: 3rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.meta {
|
||||||
|
display: flex;
|
||||||
|
gap: 1.5rem;
|
||||||
|
margin-bottom: 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.metaItem {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 0.8rem;
|
||||||
|
font-size: 0.55rem;
|
||||||
|
font-weight: 900;
|
||||||
|
color: #555;
|
||||||
|
letter-spacing: 0.1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.redIcon { color: var(--primary); }
|
||||||
|
|
||||||
|
.content h3 {
|
||||||
|
font-size: 1.1rem;
|
||||||
|
font-weight: 900;
|
||||||
|
letter-spacing: -0.02em;
|
||||||
|
margin-bottom: 1.5rem;
|
||||||
|
line-height: 1.25;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content p {
|
||||||
|
font-size: 0.85rem;
|
||||||
|
color: #666;
|
||||||
|
line-height: 1.6;
|
||||||
|
margin-bottom: 2.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.readBtn {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 1rem;
|
||||||
|
font-size: 0.7rem;
|
||||||
|
font-weight: 900;
|
||||||
|
letter-spacing: 0.05rem;
|
||||||
|
color: #fff;
|
||||||
|
border-bottom: 1px solid var(--primary);
|
||||||
|
padding-bottom: 0.5rem;
|
||||||
|
transition: all 0.2s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.readBtn:hover {
|
||||||
|
color: var(--primary);
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 1024px) {
|
||||||
|
.header { flex-direction: column; align-items: flex-start; gap: 4rem; }
|
||||||
|
}
|
||||||
80
src/components/Blog.tsx
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
'use client';
|
||||||
|
|
||||||
|
import { motion } from 'framer-motion';
|
||||||
|
import Image from 'next/image';
|
||||||
|
import { Calendar, User, ArrowRight } from 'lucide-react';
|
||||||
|
import styles from './Blog.module.css';
|
||||||
|
|
||||||
|
export default function Blog() {
|
||||||
|
const posts = [
|
||||||
|
{
|
||||||
|
title: 'OPTIMIZING THE K-SERIES FOR TRACK USE',
|
||||||
|
desc: 'Technical insights into fuel and ignition management for circuit racing environments.',
|
||||||
|
date: 'MARCH 15, 2026',
|
||||||
|
author: 'MARK H.',
|
||||||
|
img: '/ecu_kpro.png'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'S300 V3 FIRMWARE UPDATE RELEASED',
|
||||||
|
desc: 'Exploring the new link stability improvements and telemetry protocols in the latest release.',
|
||||||
|
date: 'MARCH 10, 2026',
|
||||||
|
author: 'ADMIN',
|
||||||
|
img: '/hondavert_hud_telemetry_1774593564690.png'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'PRECISION TUNING: THE FUTURE OF FLASHING',
|
||||||
|
desc: 'A look into how CANFlash is changing the speed of development for modern ECU platforms.',
|
||||||
|
date: 'MARCH 02, 2026',
|
||||||
|
author: 'MARK H.',
|
||||||
|
img: '/engine_bay.png'
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
return (
|
||||||
|
<section className={styles.section}>
|
||||||
|
<div className={styles.container}>
|
||||||
|
<div className={styles.header}>
|
||||||
|
<div className={styles.left}>
|
||||||
|
<span className={styles.label}>LATEST NEWS</span>
|
||||||
|
<h2 className={styles.title}>ENGINEERING HUB</h2>
|
||||||
|
</div>
|
||||||
|
<button className={styles.allBtn}>VIEW ALL ARTICLES</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className={styles.grid}>
|
||||||
|
{posts.map((item, i) => (
|
||||||
|
<motion.div
|
||||||
|
key={i}
|
||||||
|
className={styles.card}
|
||||||
|
initial={{ y: 30, opacity: 0 }}
|
||||||
|
whileInView={{ y: 0, opacity: 1 }}
|
||||||
|
viewport={{ once: true }}
|
||||||
|
transition={{ delay: i * 0.15 }}
|
||||||
|
>
|
||||||
|
<div className={styles.imageBox}>
|
||||||
|
<Image src={item.img} alt={item.title} fill className={styles.blogImg} />
|
||||||
|
</div>
|
||||||
|
<div className={styles.content}>
|
||||||
|
<div className={styles.meta}>
|
||||||
|
<div className={styles.metaItem}>
|
||||||
|
<Calendar size={14} className={styles.redIcon} />
|
||||||
|
<span>{item.date}</span>
|
||||||
|
</div>
|
||||||
|
<div className={styles.metaItem}>
|
||||||
|
<User size={14} className={styles.redIcon} />
|
||||||
|
<span>{item.author}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<h3>{item.title}</h3>
|
||||||
|
<p>{item.desc}</p>
|
||||||
|
<button className={styles.readBtn}>
|
||||||
|
READ ARTICLE <ArrowRight size={16} />
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</motion.div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
);
|
||||||
|
}
|
||||||
219
src/components/CANFlash.module.css
Normal file
@ -0,0 +1,219 @@
|
|||||||
|
.wrapper {
|
||||||
|
background-color: var(--neutral);
|
||||||
|
min-height: 100vh;
|
||||||
|
}
|
||||||
|
|
||||||
|
.container {
|
||||||
|
max-width: 1400px;
|
||||||
|
width: 100%;
|
||||||
|
margin: 0 auto;
|
||||||
|
padding: 0 4rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 1. HERO */
|
||||||
|
.hero {
|
||||||
|
position: relative;
|
||||||
|
min-height: 80vh;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
overflow: hidden;
|
||||||
|
padding-top: 100px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bgWrapper {
|
||||||
|
position: absolute;
|
||||||
|
inset: 0;
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.heroImg {
|
||||||
|
object-fit: cover;
|
||||||
|
filter: saturate(0.2) contrast(1.2) brightness(0.4);
|
||||||
|
}
|
||||||
|
|
||||||
|
.heroOverlay {
|
||||||
|
position: absolute;
|
||||||
|
inset: 0;
|
||||||
|
background: linear-gradient(to bottom, rgba(0,0,0,0.6) 0%, rgba(0,0,0,0.9) 100%);
|
||||||
|
z-index: 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.heroGrid {
|
||||||
|
position: relative;
|
||||||
|
z-index: 3;
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 1.5fr 1fr;
|
||||||
|
gap: 5rem;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.heroLabel {
|
||||||
|
font-size: 0.65rem;
|
||||||
|
font-weight: 900;
|
||||||
|
color: #555;
|
||||||
|
letter-spacing: 0.2rem;
|
||||||
|
display: block;
|
||||||
|
margin-bottom: 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.heroTitle {
|
||||||
|
font-size: clamp(4rem, 8vw, 6.5rem);
|
||||||
|
font-weight: 900;
|
||||||
|
line-height: 0.85;
|
||||||
|
letter-spacing: -0.05em;
|
||||||
|
margin-bottom: 2.5rem;
|
||||||
|
text-transform: uppercase;
|
||||||
|
}
|
||||||
|
|
||||||
|
.red { color: var(--primary); font-style: italic; }
|
||||||
|
|
||||||
|
.heroDesc {
|
||||||
|
font-size: 1.1rem;
|
||||||
|
color: #888;
|
||||||
|
line-height: 1.6;
|
||||||
|
margin-bottom: 3.5rem;
|
||||||
|
max-width: 600px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.heroActions { display: flex; gap: 1rem; }
|
||||||
|
|
||||||
|
.primaryBtn {
|
||||||
|
background-color: var(--primary);
|
||||||
|
padding: 1.2rem 2.2rem;
|
||||||
|
border-radius: 4px;
|
||||||
|
font-size: 0.7rem;
|
||||||
|
font-weight: 900;
|
||||||
|
letter-spacing: 0.1em;
|
||||||
|
color: #fff;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 1.2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.secondaryBtn {
|
||||||
|
background-color: rgba(255, 255, 255, 0.02);
|
||||||
|
border: 1px solid var(--border);
|
||||||
|
padding: 1.2rem 2.2rem;
|
||||||
|
border-radius: 4px;
|
||||||
|
font-size: 0.7rem;
|
||||||
|
font-weight: 900;
|
||||||
|
letter-spacing: 0.1em;
|
||||||
|
color: #fff;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 1.2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.specBox {
|
||||||
|
background-color: rgba(18, 18, 18, 0.4);
|
||||||
|
border: 1px solid rgba(255, 255, 255, 0.05);
|
||||||
|
backdrop-filter: blur(10px);
|
||||||
|
padding: 3rem;
|
||||||
|
width: 100%;
|
||||||
|
max-width: 400px;
|
||||||
|
border-radius: 4px;
|
||||||
|
position: relative;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.progressLine {
|
||||||
|
position: absolute;
|
||||||
|
top: 0; left: 0; width: 60%;
|
||||||
|
height: 2px;
|
||||||
|
background-color: var(--primary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.specItem { margin-bottom: 2.5rem; }
|
||||||
|
.specItem:last-child { margin-bottom: 0; }
|
||||||
|
|
||||||
|
.specLabel {
|
||||||
|
font-size: 0.55rem;
|
||||||
|
font-weight: 900;
|
||||||
|
color: #444;
|
||||||
|
letter-spacing: 0.1em;
|
||||||
|
display: block;
|
||||||
|
margin-bottom: 0.8rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.specItem h3 { font-size: 1.3rem; font-weight: 900; font-style: italic; }
|
||||||
|
|
||||||
|
/* 2. OVERVIEW */
|
||||||
|
.overview { padding: 120px 0; background-color: var(--neutral); }
|
||||||
|
.overviewGrid { display: grid; grid-template-columns: 1fr 1fr; gap: 8rem; align-items: center; }
|
||||||
|
.overviewContent h2 { font-size: 3rem; font-weight: 900; letter-spacing: -0.05em; margin-bottom: 3rem; line-height: 0.9; }
|
||||||
|
.featuresGrid { display: grid; grid-template-columns: 1fr 1fr; gap: 3rem 4rem; }
|
||||||
|
|
||||||
|
.featureItem { display: flex; flex-direction: column; gap: 1.2rem; }
|
||||||
|
.fIcon { width: 32px; height: 32px; color: var(--primary); }
|
||||||
|
.featureItem h3 { font-size: 0.85rem; font-weight: 900; text-transform: uppercase; letter-spacing: 0.1em; }
|
||||||
|
.featureItem p { font-size: 0.75rem; color: #777; line-height: 1.5; font-weight: 500; }
|
||||||
|
|
||||||
|
.hwImg { width: 100%; height: auto; border-radius: 4px; filter: saturate(0.8) contrast(1.1); }
|
||||||
|
|
||||||
|
/* 3. COMPATIBILITY */
|
||||||
|
.compatibility { padding: 120px 0; background-color: var(--secondary); border-top: 1px solid var(--border); border-bottom: 1px solid var(--border); }
|
||||||
|
.platformGrid { display: grid; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); gap: 1.5rem; }
|
||||||
|
.platformCard { background-color: var(--secondary); border: 1px solid var(--border); padding: 2rem; border-radius: 8px; transition: all 0.3s ease; position: relative; overflow: hidden; }
|
||||||
|
.platformCard:hover { border-color: var(--primary); transform: translateY(-4px); box-shadow: 0 10px 30px rgba(0,0,0,0.5); }
|
||||||
|
.platformCard::before { content: ""; position: absolute; top: 0; left: 0; width: 4px; height: 100%; background-color: var(--border); transition: all 0.3s ease; }
|
||||||
|
.platformCard:hover::before { background-color: var(--primary); }
|
||||||
|
|
||||||
|
.platformHeader { display: flex; align-items: center; gap: 1rem; margin-bottom: 1.5rem; border-bottom: 1px solid rgba(255,255,255,0.05); padding-bottom: 1rem; }
|
||||||
|
.platformIcon { color: var(--primary); }
|
||||||
|
.platformHeader h3 { font-size: 0.9rem; font-weight: 900; text-transform: uppercase; color: #fff; margin: 0; letter-spacing: 0.05em; }
|
||||||
|
|
||||||
|
.variantList { display: flex; flex-direction: column; gap: 0.8rem; }
|
||||||
|
.variantTag { background-color: rgba(255,255,255,0.03); border: 1px solid transparent; padding: 0.8rem 1rem; border-radius: 4px; font-size: 0.7rem; color: #aaa; display: block; border-left: 2px solid transparent; transition: all 0.2s ease; }
|
||||||
|
.variantTag:hover { background-color: rgba(255,0,0,0.05); border-color: rgba(255,0,0,0.1); border-left-color: var(--primary); color: #fff; }
|
||||||
|
|
||||||
|
/* 4. GUIDES */
|
||||||
|
.guides { padding: 120px 0; background-color: var(--neutral); overflow: hidden; }
|
||||||
|
.sectionHeader { display: flex; justify-content: space-between; align-items: flex-end; margin-bottom: 5rem; }
|
||||||
|
.headerTitle .sub { font-size: 0.65rem; font-weight: 900; color: var(--primary); letter-spacing: 0.2rem; display: block; margin-bottom: 1rem; text-transform: uppercase; }
|
||||||
|
.headerTitle h2 { font-size: 2.5rem; font-weight: 900; margin: 0; line-height: 1; letter-spacing: -0.05em; text-transform: uppercase; }
|
||||||
|
|
||||||
|
.sliderNav { display: flex; gap: 1rem; }
|
||||||
|
.navBtn { width: 50px; height: 50px; border-radius: 50%; background-color: var(--secondary); border: 1px solid var(--border); color: #fff; display: flex; align-items: center; justify-content: center; cursor: pointer; transition: all 0.3s ease; }
|
||||||
|
.navBtn:hover:not(.disabled) { background-color: var(--primary); border-color: var(--primary); }
|
||||||
|
.navBtn.disabled { opacity: 0.3; cursor: not-allowed; }
|
||||||
|
|
||||||
|
.sliderContainer { width: 100%; overflow: hidden; padding: 1rem 0; }
|
||||||
|
.sliderTray { display: grid; grid-auto-flow: column; grid-auto-columns: calc(33.333% - 1.333rem); gap: 2rem; width: 100%; }
|
||||||
|
|
||||||
|
.guideCard { background-color: var(--secondary); border: 1px solid var(--border); padding: 3rem; border-radius: 8px; transition: all 0.3s ease; display: flex; flex-direction: column; gap: 1.5rem; height: 100%; min-height: 350px; }
|
||||||
|
.guideCard:hover { border-color: var(--primary); transform: translateY(-10px); }
|
||||||
|
|
||||||
|
.cardHeader { display: flex; justify-content: space-between; align-items: flex-start; margin-bottom: 1rem; }
|
||||||
|
.iconBox { width: 60px; height: 60px; background-color: rgba(255, 0, 0, 0.05); border: 1px solid rgba(255, 0, 0, 0.1); border-radius: 8px; display: flex; align-items: center; justify-content: center; color: var(--primary); }
|
||||||
|
.cardNum { font-size: 1.5rem; font-weight: 900; color: rgba(255, 255, 255, 0.1); letter-spacing: -0.05em; }
|
||||||
|
|
||||||
|
.guideCard h3 { font-size: 1.2rem; font-weight: 900; line-height: 1.3; margin: 0; letter-spacing: -0.02em; }
|
||||||
|
.guideCard p { font-size: 0.85rem; color: #888; line-height: 1.6; margin: 0; flex-grow: 1; }
|
||||||
|
.cardBtn { font-size: 0.7rem; font-weight: 900; color: #fff; display: flex; align-items: center; gap: 0.5rem; letter-spacing: 0.1em; background: none; border: none; padding: 0; margin-top: auto; cursor: pointer; transition: color 0.3s ease; }
|
||||||
|
.guideCard:hover .cardBtn { color: var(--primary); }
|
||||||
|
|
||||||
|
/* 5. DOWNLOADS */
|
||||||
|
.downloads { padding: 120px 0; background-color: var(--secondary); border-top: 1px solid var(--border); }
|
||||||
|
.dlHeader { text-align: center; margin-bottom: 5rem; }
|
||||||
|
.dlHeader h2 { font-size: 2.5rem; font-weight: 900; text-transform: uppercase; }
|
||||||
|
|
||||||
|
.dlDashboard { display: grid; grid-template-columns: 1fr 1fr; gap: 2rem; }
|
||||||
|
.dlCard { background-color: var(--neutral); border: 1px solid var(--border); padding: 4rem; border-radius: 8px; display: flex; flex-direction: column; align-items: center; text-align: center; gap: 2rem; position: relative; }
|
||||||
|
.dlCard h3 { font-size: 1.3rem; font-weight: 900; text-transform: uppercase; letter-spacing: 0.05em; }
|
||||||
|
.dlCard p { font-size: 0.8rem; color: #777; line-height: 1.6; }
|
||||||
|
|
||||||
|
.passwordBox { background-color: rgba(255, 255, 255, 0.02); border: 1px dashed var(--border); padding: 1.5rem; border-radius: 4px; display: flex; flex-direction: column; gap: 0.5rem; width: 100%; margin-top: auto; }
|
||||||
|
.passwordBox span { font-size: 0.55rem; font-weight: 900; color: #444; text-transform: uppercase; }
|
||||||
|
.passKey { font-family: monospace; font-size: 1.2rem; color: #fff; font-weight: 900; letter-spacing: 0.3em; }
|
||||||
|
|
||||||
|
.extractNote { font-size: 0.65rem; color: #555; margin-top: 1rem; }
|
||||||
|
.extractNote a { color: var(--primary); font-weight: 700; text-decoration: underline; }
|
||||||
|
|
||||||
|
.versionTag { font-size: 0.65rem; font-weight: 900; color: var(--primary); background-color: rgba(255, 0, 0, 0.1); padding: 0.5rem 1.5rem; border-radius: 100px; margin-top: auto; }
|
||||||
|
|
||||||
|
.dlBtn { background-color: #fff; color: #000; padding: 1.5rem; border-radius: 4px; font-size: 0.75rem; font-weight: 900; display: flex; align-items: center; justify-content: center; gap: 1.2rem; width: 100%; transition: all 0.3s ease; text-transform: uppercase; letter-spacing: 0.1em; }
|
||||||
|
.dlBtn:hover { background-color: var(--primary); color: #fff; }
|
||||||
|
|
||||||
|
@media (max-width: 1024px) {
|
||||||
|
.heroGrid, .overviewGrid, .compGrid, .dlDashboard { grid-template-columns: 1fr; gap: 4rem; }
|
||||||
|
}
|
||||||
256
src/components/CANFlash.tsx
Normal file
@ -0,0 +1,256 @@
|
|||||||
|
'use client';
|
||||||
|
|
||||||
|
import { motion } from 'framer-motion';
|
||||||
|
import Image from 'next/image';
|
||||||
|
import {
|
||||||
|
Info,
|
||||||
|
BookOpen,
|
||||||
|
Download,
|
||||||
|
ShieldCheck,
|
||||||
|
Activity,
|
||||||
|
Gauge,
|
||||||
|
Settings,
|
||||||
|
Cpu,
|
||||||
|
Terminal,
|
||||||
|
Lock,
|
||||||
|
User,
|
||||||
|
ChevronLeft,
|
||||||
|
ChevronRight,
|
||||||
|
Zap
|
||||||
|
} from 'lucide-react';
|
||||||
|
import { useState, useRef } from 'react';
|
||||||
|
import styles from './CANFlash.module.css';
|
||||||
|
|
||||||
|
export default function CANFlash() {
|
||||||
|
const [currentSlide, setCurrentSlide] = useState(0);
|
||||||
|
|
||||||
|
const infoRef = useRef<HTMLElement>(null);
|
||||||
|
const guidesRef = useRef<HTMLElement>(null);
|
||||||
|
const downloadRef = useRef<HTMLElement>(null);
|
||||||
|
|
||||||
|
const scrollToSection = (ref: React.RefObject<HTMLElement | null>) => {
|
||||||
|
if (ref.current) {
|
||||||
|
ref.current.scrollIntoView({ behavior: 'smooth' });
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const coreFeatures = [
|
||||||
|
{ title: 'Direct ECU Reflashing', desc: 'Modify factory firmware natively via CAN Bus through the OBDII port.', icon: <Cpu size={24} /> },
|
||||||
|
{ title: 'Drive-by-Wire & VTC', desc: 'Full electronic throttle curve tuning and variable timing control.', icon: <Activity size={24} /> },
|
||||||
|
{ title: 'Live Sensor Logging', desc: 'Precision data streaming for closed-loop combustion analysis.', icon: <Gauge size={24} /> },
|
||||||
|
{ title: '2-Step & Launch', desc: 'Customizable 2-step rev limiters for aggressive launch strategies.', icon: <Zap size={24} /> },
|
||||||
|
{ title: 'Monitor Disabling', desc: 'Deactivate specific sensors and emissions monitors for track use.', icon: <ShieldCheck size={24} /> },
|
||||||
|
{ title: 'MAF Scaling', desc: 'Scale Mass Air Flow sensors for high-flow intake systems.', icon: <Settings size={24} /> },
|
||||||
|
];
|
||||||
|
|
||||||
|
const supportedVehicles = [
|
||||||
|
{ title: 'Acura ILX', variants: ['13-22 Acura ILX'] },
|
||||||
|
{ title: 'Acura MDX', variants: ['07-13 Acura MDX', '14-15 Acura MDX'] },
|
||||||
|
{ title: 'Acura RDX', variants: ['19-23 Acura RDX'] },
|
||||||
|
{ title: 'Acura TL', variants: ['07-08 Acura TL', '09-14 Acura TL'] },
|
||||||
|
{ title: 'Acura TLX', variants: ['15-20 Acura TLX I', '21+ Acura TLX II'] },
|
||||||
|
{ title: 'Acura TSX', variants: ['07-08 Acura TSX I', '09-14 Acura TSX II'] },
|
||||||
|
{ title: 'Honda Accord', variants: ['08-12 Honda Accord 8 (USA Spec.)', '08-12 Honda Accord 8 (JDM Spec.)', '13-17 Honda Accord 9', '18-22 Honda Accord X'] },
|
||||||
|
{ title: 'Honda Civic', variants: ['06-11 Honda Civic 8', '12-15 Honda Civic 9', '16-21 Honda Civic X', '22+ Honda Civic 11'] },
|
||||||
|
{ title: 'Honda CR-V', variants: ['17-22 Honda CR-V'] },
|
||||||
|
{ title: 'Honda CR-Z', variants: ['11-16 Honda CR-Z'] },
|
||||||
|
{ title: 'Honda Element', variants: ['07-08 Honda Element'] },
|
||||||
|
{ title: 'Honda Fit', variants: ['09-13 Honda Fit', '15-20 Honda Fit'] },
|
||||||
|
{ title: 'Honda Ridgeline', variants: ['09-14 Honda Ridgeline'] },
|
||||||
|
{ title: 'Honda S2000', variants: ['06-09 Honda S2000 AP2'] },
|
||||||
|
];
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className={styles.wrapper}>
|
||||||
|
{/* 1. HERO SECTION */}
|
||||||
|
<section className={styles.hero}>
|
||||||
|
<div className={styles.bgWrapper}>
|
||||||
|
<Image src="/engine_bay.png" alt="CANFlash Hero" fill className={styles.heroImg} priority />
|
||||||
|
</div>
|
||||||
|
<div className={styles.heroOverlay}></div>
|
||||||
|
<div className={styles.container}>
|
||||||
|
<div className={styles.heroGrid}>
|
||||||
|
<motion.div
|
||||||
|
className={styles.heroContent}
|
||||||
|
initial={{ opacity: 0, x: -50 }}
|
||||||
|
animate={{ opacity: 1, x: 0 }}
|
||||||
|
transition={{ duration: 0.8 }}
|
||||||
|
>
|
||||||
|
<span className={styles.heroLabel}>OBDII FLASHING INTERFACE</span>
|
||||||
|
<h1 className={styles.heroTitle}>
|
||||||
|
CAN<span className={styles.red}>FLASH</span>
|
||||||
|
</h1>
|
||||||
|
<p className={styles.heroDesc}>
|
||||||
|
Designed to modify your factory ECU firmware directly via the CAN Bus through the OBDII connector,
|
||||||
|
achieving total control without requiring any physical hardware modifications to your ECU.
|
||||||
|
</p>
|
||||||
|
<div className={styles.heroActions}>
|
||||||
|
<button className={styles.primaryBtn} onClick={() => scrollToSection(infoRef)}>
|
||||||
|
<Info size={18} />
|
||||||
|
<span>INFORMATION</span>
|
||||||
|
</button>
|
||||||
|
<button className={styles.secondaryBtn} onClick={() => scrollToSection(guidesRef)}>
|
||||||
|
<BookOpen size={18} />
|
||||||
|
<span>GUIDES</span>
|
||||||
|
</button>
|
||||||
|
<button className={styles.secondaryBtn} onClick={() => scrollToSection(downloadRef)}>
|
||||||
|
<Download size={18} />
|
||||||
|
<span>DOWNLOAD</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</motion.div>
|
||||||
|
|
||||||
|
<motion.div
|
||||||
|
className={styles.heroSpecs}
|
||||||
|
initial={{ opacity: 0, x: 50 }}
|
||||||
|
animate={{ opacity: 1, x: 0 }}
|
||||||
|
transition={{ duration: 0.8, delay: 0.2 }}
|
||||||
|
>
|
||||||
|
<div className={styles.specBox}>
|
||||||
|
<div className={styles.progressLine}></div>
|
||||||
|
<div className={styles.specItem}>
|
||||||
|
<span className={styles.specLabel}>CONNECTION TYPE</span>
|
||||||
|
<h3>OBDII PORT NATIVE</h3>
|
||||||
|
</div>
|
||||||
|
<div className={styles.specItem}>
|
||||||
|
<span className={styles.specLabel}>HARDWARE MODS</span>
|
||||||
|
<h3>ZERO REQUIRED</h3>
|
||||||
|
</div>
|
||||||
|
<div className={styles.specItem}>
|
||||||
|
<span className={styles.specLabel}>SYSTEM COMPATIBILITY</span>
|
||||||
|
<h3>ABS / VSA / CLIMATE</h3>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</motion.div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
{/* 2. CORE CAPABILITIES */}
|
||||||
|
<section className={styles.overview} ref={infoRef}>
|
||||||
|
<div className={styles.container}>
|
||||||
|
<div className={styles.overviewGrid}>
|
||||||
|
<motion.div
|
||||||
|
className={styles.overviewContent}
|
||||||
|
initial={{ opacity: 0, y: 30 }}
|
||||||
|
whileInView={{ opacity: 1, y: 0 }}
|
||||||
|
viewport={{ once: true }}
|
||||||
|
>
|
||||||
|
<h2>CORE PERFORMANCE <br /><span className={styles.red}>ENGINEERING</span></h2>
|
||||||
|
<div className={styles.featuresGrid}>
|
||||||
|
{coreFeatures.map((feature, i) => (
|
||||||
|
<div key={i} className={styles.featureItem}>
|
||||||
|
<div className={styles.fIcon}>{feature.icon}</div>
|
||||||
|
<h3>{feature.title}</h3>
|
||||||
|
<p>{feature.desc}</p>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</motion.div>
|
||||||
|
<div className={styles.overviewImage}>
|
||||||
|
<Image src="/hud_telemetry.png" width={600} height={500} alt="CANFlash OBDII Tuning Interface" className={styles.hwImg} />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
{/* 3. SUPPORTED VEHICLES */}
|
||||||
|
<section className={styles.compatibility}>
|
||||||
|
<div className={styles.container}>
|
||||||
|
<div className={styles.sectionHeader}>
|
||||||
|
<div className={styles.headerTitle}>
|
||||||
|
<span className={styles.sub}>NATIVE OBDII DEPLOYMENT</span>
|
||||||
|
<h2>SUPPORTED <span className={styles.red}>VEHICLES</span></h2>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className={styles.platformGrid}>
|
||||||
|
{supportedVehicles.map((platform, bIdx) => (
|
||||||
|
<div key={bIdx} className={styles.platformCard}>
|
||||||
|
<div className={styles.platformHeader}>
|
||||||
|
<Cpu size={20} className={styles.platformIcon} />
|
||||||
|
<h3>{platform.title}</h3>
|
||||||
|
</div>
|
||||||
|
<div className={styles.variantList}>
|
||||||
|
{platform.variants.map((v, i) => (
|
||||||
|
<span key={i} className={styles.variantTag}>{v}</span>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
{/* 4. TECH GUIDES (SLIDER) */}
|
||||||
|
<section className={styles.guides} ref={guidesRef}>
|
||||||
|
<div className={styles.container}>
|
||||||
|
<div className={styles.sectionHeader}>
|
||||||
|
<div className={styles.headerTitle}>
|
||||||
|
<span className={styles.sub}>TECHNICAL INTELLIGENCE</span>
|
||||||
|
<h2>DOCUMENTATION <span className={styles.red}>SYSTEM</span></h2>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className={styles.sliderContainer}>
|
||||||
|
<motion.div
|
||||||
|
className={styles.sliderTray}
|
||||||
|
animate={{ x: 0 }}
|
||||||
|
transition={{ type: "spring", stiffness: 100, damping: 20 }}
|
||||||
|
>
|
||||||
|
{[
|
||||||
|
{ title: 'Device LEDs Meaning', desc: 'Troubleshoot status indicators and system health.', icon: <Settings size={32} /> },
|
||||||
|
{ title: 'Sign In or Register', desc: 'Create KTuner Account or Sign In to your dashboard.', icon: <User size={32} /> },
|
||||||
|
{ title: 'Registering CANFlash Unit', desc: 'Initialize and lock your hardware to your software account.', icon: <Lock size={32} /> },
|
||||||
|
].map((card, i) => (
|
||||||
|
<div key={i} className={styles.guideCard}>
|
||||||
|
<div className={styles.cardHeader}>
|
||||||
|
<div className={styles.iconBox}>{card.icon}</div>
|
||||||
|
<span className={styles.cardNum}>0{i+1}</span>
|
||||||
|
</div>
|
||||||
|
<h3>{card.title}</h3>
|
||||||
|
<p>{card.desc}</p>
|
||||||
|
<button className={styles.cardBtn}>
|
||||||
|
VIEW DOCUMENT <ChevronRight size={14} />
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</motion.div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
{/* 5. DOWNLOADS */}
|
||||||
|
<section className={styles.downloads} ref={downloadRef}>
|
||||||
|
<div className={styles.container}>
|
||||||
|
<div className={styles.dlHeader}>
|
||||||
|
<h2>SOFTWARE <span className={styles.red}>HUB</span></h2>
|
||||||
|
</div>
|
||||||
|
<div className={styles.dlDashboard}>
|
||||||
|
<div className={styles.dlCard}>
|
||||||
|
<ShieldCheck size={32} />
|
||||||
|
<h3>Security & Instructions</h3>
|
||||||
|
<p>False virus detections may occur. If you have trouble downloading, temporarily disable Antivirus and Windows Defender.</p>
|
||||||
|
<div className={styles.passwordBox}>
|
||||||
|
<span>Archive Password</span>
|
||||||
|
<div className={styles.passKey}>1234</div>
|
||||||
|
</div>
|
||||||
|
<p className={styles.extractNote}>
|
||||||
|
* Extract with <a href="https://www.rarlab.com/download.htm" target="_blank">WinRAR</a> or <a href="https://www.7-zip.org" target="_blank">7-Zip</a>.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div className={styles.dlCard}>
|
||||||
|
<Download size={32} />
|
||||||
|
<h3>KTuner Manager</h3>
|
||||||
|
<p>Get the latest KTuner Software Environment. Flash multiple map setups directly to your ECU.</p>
|
||||||
|
<span className={styles.versionTag}>V1.0.11.2 STABLE</span>
|
||||||
|
<a href="/files/KTSetup.rar" className={styles.dlBtn} download>
|
||||||
|
<Download size={18} />
|
||||||
|
DOWNLOAD INSTALLER
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
102
src/components/CTA.module.css
Normal file
@ -0,0 +1,102 @@
|
|||||||
|
.section {
|
||||||
|
padding: 150px 0;
|
||||||
|
background-color: #000;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.container {
|
||||||
|
max-width: 1400px;
|
||||||
|
width: 100%;
|
||||||
|
margin: 0 auto;
|
||||||
|
padding: 0 4rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header {
|
||||||
|
margin-bottom: 5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.title {
|
||||||
|
font-size: clamp(3rem, 8vw, 6rem);
|
||||||
|
font-weight: 900;
|
||||||
|
letter-spacing: -0.05em;
|
||||||
|
text-transform: uppercase;
|
||||||
|
}
|
||||||
|
|
||||||
|
.red {
|
||||||
|
color: var(--primary);
|
||||||
|
font-style: italic;
|
||||||
|
}
|
||||||
|
|
||||||
|
.grid {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
gap: 3rem;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card {
|
||||||
|
background-color: #0c0c0c;
|
||||||
|
border: 1px solid #1a1a1a;
|
||||||
|
padding: 3rem 4rem;
|
||||||
|
min-width: 400px;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.top {
|
||||||
|
margin-bottom: 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.label {
|
||||||
|
font-size: 0.6rem;
|
||||||
|
font-weight: 900;
|
||||||
|
color: #444;
|
||||||
|
letter-spacing: 0.1em;
|
||||||
|
display: block;
|
||||||
|
margin-bottom: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card h3 {
|
||||||
|
font-size: 1.8rem;
|
||||||
|
font-weight: 800;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btnPrimary {
|
||||||
|
background-color: var(--primary);
|
||||||
|
color: white;
|
||||||
|
padding: 1.2rem 2.5rem;
|
||||||
|
border-radius: 4px;
|
||||||
|
font-size: 0.85rem;
|
||||||
|
font-weight: 900;
|
||||||
|
letter-spacing: 0.1em;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 1.5rem;
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btnSecondary {
|
||||||
|
background-color: rgba(255, 255, 255, 0.02);
|
||||||
|
border: 1px solid #222;
|
||||||
|
color: white;
|
||||||
|
padding: 1.2rem 2.5rem;
|
||||||
|
border-radius: 4px;
|
||||||
|
font-size: 0.85rem;
|
||||||
|
font-weight: 900;
|
||||||
|
letter-spacing: 0.1em;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 1.5rem;
|
||||||
|
margin: 0 auto;
|
||||||
|
transition: all 0.2s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btnSecondary:hover {
|
||||||
|
background-color: #111;
|
||||||
|
border-color: #333;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
.card {
|
||||||
|
min-width: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
45
src/components/CTA.tsx
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
'use client';
|
||||||
|
|
||||||
|
import { motion } from 'framer-motion';
|
||||||
|
import { Download, BookOpen } from 'lucide-react';
|
||||||
|
import styles from './CTA.module.css';
|
||||||
|
|
||||||
|
export default function CTA() {
|
||||||
|
return (
|
||||||
|
<section className={styles.section}>
|
||||||
|
<div className={styles.container}>
|
||||||
|
<motion.div
|
||||||
|
initial={{ opacity: 0, y: 30 }}
|
||||||
|
whileInView={{ opacity: 1, y: 0 }}
|
||||||
|
className={styles.header}
|
||||||
|
>
|
||||||
|
<h2 className={styles.title}>
|
||||||
|
READY TO <span className={styles.red}>IGNITE?</span>
|
||||||
|
</h2>
|
||||||
|
</motion.div>
|
||||||
|
|
||||||
|
<div className={styles.grid}>
|
||||||
|
<div className={styles.card}>
|
||||||
|
<div className={styles.top}>
|
||||||
|
<span className={styles.label}>FIRMWARE</span>
|
||||||
|
<h3>v2.1 Stable</h3>
|
||||||
|
</div>
|
||||||
|
<button className={styles.btnPrimary}>
|
||||||
|
DOWNLOAD NOW <Download size={16} />
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className={styles.card}>
|
||||||
|
<div className={styles.top}>
|
||||||
|
<span className={styles.label}>DOCUMENTATION</span>
|
||||||
|
<h3>User Manual</h3>
|
||||||
|
</div>
|
||||||
|
<button className={styles.btnSecondary}>
|
||||||
|
VIEW GUIDES <BookOpen size={16} />
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
);
|
||||||
|
}
|
||||||
247
src/components/Compatibility.module.css
Normal file
@ -0,0 +1,247 @@
|
|||||||
|
.section {
|
||||||
|
padding: 100px 0;
|
||||||
|
background-color: var(--background);
|
||||||
|
}
|
||||||
|
|
||||||
|
.container {
|
||||||
|
max-width: 1400px;
|
||||||
|
width: 100%;
|
||||||
|
margin: 0 auto;
|
||||||
|
padding: 0 4rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header {
|
||||||
|
margin-bottom: 3rem;
|
||||||
|
border-left: 2px solid var(--primary);
|
||||||
|
padding-left: 1.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.subtitle {
|
||||||
|
font-size: 0.75rem;
|
||||||
|
color: var(--primary);
|
||||||
|
font-weight: 800;
|
||||||
|
letter-spacing: 0.1rem;
|
||||||
|
margin-bottom: 0.5rem;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.title {
|
||||||
|
font-size: 3rem;
|
||||||
|
font-weight: 900;
|
||||||
|
letter-spacing: -0.05em;
|
||||||
|
text-transform: uppercase;
|
||||||
|
}
|
||||||
|
|
||||||
|
.grid {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 1.5fr 1fr;
|
||||||
|
gap: 2rem;
|
||||||
|
margin-bottom: 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cardMain {
|
||||||
|
background-color: #0c0c0c;
|
||||||
|
border: 1px solid #1a1a1a;
|
||||||
|
padding: 2.5rem;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cardHeader {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 1.5rem;
|
||||||
|
margin-bottom: 2rem;
|
||||||
|
border-bottom: 1px solid #222;
|
||||||
|
padding-bottom: 1.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cardHeader h3 {
|
||||||
|
font-size: 1.2rem;
|
||||||
|
font-weight: 900;
|
||||||
|
letter-spacing: -0.02em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.iconRed {
|
||||||
|
color: var(--primary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.list {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 1fr 1fr;
|
||||||
|
gap: 1.5rem;
|
||||||
|
margin-bottom: 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.list li {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 0.8rem;
|
||||||
|
color: #888;
|
||||||
|
font-size: 0.9rem;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
.redDot {
|
||||||
|
width: 6px;
|
||||||
|
height: 6px;
|
||||||
|
background-color: var(--primary);
|
||||||
|
border-radius: 50%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.divider {
|
||||||
|
height: 1px;
|
||||||
|
background-color: #222;
|
||||||
|
margin: 1.5rem 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hardwareNote {
|
||||||
|
font-size: 0.65rem;
|
||||||
|
color: #444;
|
||||||
|
font-weight: 900;
|
||||||
|
letter-spacing: 0.1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cardRight {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cardSmall {
|
||||||
|
background-color: #0c0c0c;
|
||||||
|
border: 1px solid #1a1a1a;
|
||||||
|
padding: 1.5rem;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.listSmall {
|
||||||
|
margin-bottom: 1.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.listSmall li {
|
||||||
|
margin-bottom: 0.8rem;
|
||||||
|
font-size: 0.9rem;
|
||||||
|
color: #999;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
.alert {
|
||||||
|
background-color: #0a0808;
|
||||||
|
border: 1px solid #241212;
|
||||||
|
padding: 1rem;
|
||||||
|
display: flex;
|
||||||
|
gap: 1rem;
|
||||||
|
align-items: flex-start;
|
||||||
|
}
|
||||||
|
|
||||||
|
.alertContent strong {
|
||||||
|
display: block;
|
||||||
|
font-size: 0.65rem;
|
||||||
|
color: var(--primary);
|
||||||
|
font-weight: 900;
|
||||||
|
margin-bottom: 0.3rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.alertContent p {
|
||||||
|
font-size: 0.75rem;
|
||||||
|
color: #666;
|
||||||
|
line-height: 1.4;
|
||||||
|
}
|
||||||
|
|
||||||
|
.statsGrid {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 1fr 2fr 1fr;
|
||||||
|
gap: 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.specBox, .performanceBox, .versionBox {
|
||||||
|
background-color: #0c0c0c;
|
||||||
|
border: 1px solid #1a1a1a;
|
||||||
|
padding: 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.specLabel {
|
||||||
|
display: block;
|
||||||
|
font-size: 0.75rem;
|
||||||
|
font-weight: 900;
|
||||||
|
color: #fff;
|
||||||
|
margin-bottom: 1.5rem;
|
||||||
|
border-bottom: 1px solid #222;
|
||||||
|
padding-bottom: 0.8rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.specItem {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
margin-bottom: 1.2rem;
|
||||||
|
font-size: 0.85rem;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #555;
|
||||||
|
}
|
||||||
|
|
||||||
|
.red {
|
||||||
|
color: var(--primary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.note {
|
||||||
|
font-size: 0.85rem;
|
||||||
|
color: #666;
|
||||||
|
margin-bottom: 1.5rem;
|
||||||
|
line-height: 1.6;
|
||||||
|
}
|
||||||
|
|
||||||
|
.progressItem {
|
||||||
|
margin-bottom: 1.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.progressHeader {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
margin-bottom: 0.6rem;
|
||||||
|
font-size: 0.75rem;
|
||||||
|
font-weight: 900;
|
||||||
|
}
|
||||||
|
|
||||||
|
.progressBar {
|
||||||
|
height: 4px;
|
||||||
|
background-color: #222;
|
||||||
|
border-radius: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.progressFill {
|
||||||
|
height: 100%;
|
||||||
|
background-color: var(--primary);
|
||||||
|
border-radius: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.versionBox {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
text-align: center;
|
||||||
|
border-top: 4px solid var(--primary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.vLabel {
|
||||||
|
font-size: 3.5rem;
|
||||||
|
font-weight: 900;
|
||||||
|
letter-spacing: -0.05em;
|
||||||
|
margin-bottom: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.vStatus {
|
||||||
|
font-size: 0.65rem;
|
||||||
|
color: #444;
|
||||||
|
font-weight: 900;
|
||||||
|
letter-spacing: 0.1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 1024px) {
|
||||||
|
.grid {
|
||||||
|
grid-template-columns: 1fr;
|
||||||
|
}
|
||||||
|
.statsGrid {
|
||||||
|
grid-template-columns: 1fr;
|
||||||
|
}
|
||||||
|
}
|
||||||
99
src/components/Compatibility.tsx
Normal file
@ -0,0 +1,99 @@
|
|||||||
|
import { Car, Info, TriangleAlert } from 'lucide-react';
|
||||||
|
import styles from './Compatibility.module.css';
|
||||||
|
|
||||||
|
export default function Compatibility() {
|
||||||
|
return (
|
||||||
|
<section className={styles.section}>
|
||||||
|
<div className={styles.container}>
|
||||||
|
<div className={styles.header}>
|
||||||
|
<span className={styles.subtitle}>COMPATIBILITY MATRIX</span>
|
||||||
|
<h2 className={styles.title}>ECU COMPATIBILITY LIST</h2>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className={styles.grid}>
|
||||||
|
<div className={styles.cardMain}>
|
||||||
|
<div className={styles.cardHeader}>
|
||||||
|
<Car className={styles.iconRed} size={24} />
|
||||||
|
<h3>CIVIC & INTEGRA HIGH-PERFORMANCE</h3>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className={styles.cardBody}>
|
||||||
|
<ul className={styles.list}>
|
||||||
|
<li><span className={styles.redDot}></span> 02-05 Honda Civic Si (EP3)</li>
|
||||||
|
<li><span className={styles.redDot}></span> 01-05 Honda Civic TypeR (EP3)</li>
|
||||||
|
<li><span className={styles.redDot}></span> 01-06 Honda Integra DC5</li>
|
||||||
|
<li><span className={styles.redDot}></span> 02-06 Honda Integra TypeR</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<div className={styles.divider}></div>
|
||||||
|
<p className={styles.hardwareNote}>HARDWARE REVISION: 4.2 (FEB 2026)</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className={styles.cardRight}>
|
||||||
|
<div className={styles.cardSmall}>
|
||||||
|
<div className={styles.cardHeader}>
|
||||||
|
<TriangleAlert className={styles.iconRed} size={20} />
|
||||||
|
<h3>ACURA RSX LINEUP</h3>
|
||||||
|
</div>
|
||||||
|
<ul className={styles.listSmall}>
|
||||||
|
<li>02-04 Acura RSX Base</li>
|
||||||
|
<li>02-04 Acura RSX TypeS</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<div className={styles.alert}>
|
||||||
|
<TriangleAlert size={14} className={styles.iconRed} />
|
||||||
|
<div className={styles.alertContent}>
|
||||||
|
<strong>TECHNICAL CONSTRAINT</strong>
|
||||||
|
<p>Pr-Kpro for automatic not supported. Manual & Sequential conversion required for full functionality.</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className={styles.statsGrid}>
|
||||||
|
<div className={styles.specBox}>
|
||||||
|
<span className={styles.specLabel}>INTERFACE SPECS</span>
|
||||||
|
<div className={styles.specItem}>
|
||||||
|
<span>CAN RATE:</span>
|
||||||
|
<span className={styles.red}>500kbps</span>
|
||||||
|
</div>
|
||||||
|
<div className={styles.specItem}>
|
||||||
|
<span>CONNECTIVITY:</span>
|
||||||
|
<span className={styles.red}>USB 2.1 TYPE-C</span>
|
||||||
|
</div>
|
||||||
|
<div className={styles.specItem}>
|
||||||
|
<span>ONBOARD STORAGE:</span>
|
||||||
|
<span className={styles.red}>8GB FLASH</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className={styles.performanceBox}>
|
||||||
|
<span className={styles.specLabel}>PERFORMANCE GAINS</span>
|
||||||
|
<p className={styles.note}>Real-world benchmarking across supported ECU platforms shows significant response improvement.</p>
|
||||||
|
<div className={styles.progressItem}>
|
||||||
|
<div className={styles.progressHeader}>
|
||||||
|
<span>VTEC ENGAGEMENT</span>
|
||||||
|
<span className={styles.red}>+12.6% PRECISION</span>
|
||||||
|
</div>
|
||||||
|
<div className={styles.progressBar}><div className={styles.progressFill} style={{width: '92%'}}></div></div>
|
||||||
|
</div>
|
||||||
|
<div className={styles.progressItem}>
|
||||||
|
<div className={styles.progressHeader}>
|
||||||
|
<span>FUEL INJECTION MAP</span>
|
||||||
|
<span className={styles.red}>+11.2% EFFICIENCY</span>
|
||||||
|
</div>
|
||||||
|
<div className={styles.progressBar}><div className={styles.progressFill} style={{width: '88%'}}></div></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className={styles.versionBox}>
|
||||||
|
<div className={styles.vLabel}>v4.2</div>
|
||||||
|
<span className={styles.vStatus}>FIRMWARE REV 0226</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
);
|
||||||
|
}
|
||||||
174
src/components/Contact.module.css
Normal file
@ -0,0 +1,174 @@
|
|||||||
|
.section {
|
||||||
|
padding: 15rem 0 10rem;
|
||||||
|
background-color: var(--neutral);
|
||||||
|
min-height: 100vh;
|
||||||
|
}
|
||||||
|
|
||||||
|
.container {
|
||||||
|
max-width: 1400px;
|
||||||
|
margin: 0 auto;
|
||||||
|
padding: 0 4rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header {
|
||||||
|
margin-bottom: 8rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.label {
|
||||||
|
font-size: 0.65rem;
|
||||||
|
font-weight: 900;
|
||||||
|
color: var(--primary);
|
||||||
|
letter-spacing: 0.2rem;
|
||||||
|
display: block;
|
||||||
|
margin-bottom: 1.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.title {
|
||||||
|
font-size: 3.5rem;
|
||||||
|
font-weight: 900;
|
||||||
|
margin-bottom: 2rem;
|
||||||
|
line-height: 1.1;
|
||||||
|
letter-spacing: -0.05em;
|
||||||
|
text-transform: uppercase;
|
||||||
|
}
|
||||||
|
|
||||||
|
.red {
|
||||||
|
color: var(--primary);
|
||||||
|
font-style: italic;
|
||||||
|
}
|
||||||
|
|
||||||
|
.desc {
|
||||||
|
max-width: 600px;
|
||||||
|
font-size: 1.1rem;
|
||||||
|
color: #888;
|
||||||
|
line-height: 1.6;
|
||||||
|
}
|
||||||
|
|
||||||
|
.grid {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 1fr 1.5fr;
|
||||||
|
gap: 8rem;
|
||||||
|
align-items: start;
|
||||||
|
}
|
||||||
|
|
||||||
|
.infoCol {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 1fr;
|
||||||
|
gap: 3rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.infoCard {
|
||||||
|
display: flex;
|
||||||
|
gap: 2rem;
|
||||||
|
align-items: center;
|
||||||
|
padding: 2.5rem;
|
||||||
|
background-color: var(--secondary);
|
||||||
|
border: 1px solid var(--border);
|
||||||
|
border-radius: 4px;
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.infoCard:hover {
|
||||||
|
border-color: var(--primary);
|
||||||
|
transform: translateY(-5px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.infoIcon {
|
||||||
|
width: 60px;
|
||||||
|
height: 60px;
|
||||||
|
background-color: rgba(255, 0, 0, 0.05);
|
||||||
|
border: 1px solid rgba(255, 0, 0, 0.1);
|
||||||
|
border-radius: 50%;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
color: var(--primary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.infoText h4 {
|
||||||
|
font-size: 0.75rem;
|
||||||
|
font-weight: 900;
|
||||||
|
margin-bottom: 0.8rem;
|
||||||
|
color: #fff;
|
||||||
|
letter-spacing: 0.1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.infoText p {
|
||||||
|
font-size: 0.9rem;
|
||||||
|
color: #888;
|
||||||
|
line-height: 1.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.contactForm {
|
||||||
|
background-color: var(--secondary);
|
||||||
|
border: 1px solid var(--border);
|
||||||
|
padding: 5rem;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.inputGroup {
|
||||||
|
margin-bottom: 3rem;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 1.2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.inputGroup label {
|
||||||
|
font-size: 0.65rem;
|
||||||
|
font-weight: 900;
|
||||||
|
color: #555;
|
||||||
|
letter-spacing: 0.1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.inputGroup input,
|
||||||
|
.inputGroup select,
|
||||||
|
.inputGroup textarea {
|
||||||
|
background-color: #0c0c0c;
|
||||||
|
border: 1px solid var(--border);
|
||||||
|
border-radius: 4px;
|
||||||
|
padding: 1.5rem;
|
||||||
|
color: #fff;
|
||||||
|
font-size: 0.9rem;
|
||||||
|
width: 100%;
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.inputGroup input:focus,
|
||||||
|
.inputGroup select:focus,
|
||||||
|
.inputGroup textarea:focus {
|
||||||
|
outline: none;
|
||||||
|
border-color: var(--primary);
|
||||||
|
border-width: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.submitBtn {
|
||||||
|
width: 100%;
|
||||||
|
background-color: var(--primary);
|
||||||
|
color: #fff;
|
||||||
|
padding: 1.5rem;
|
||||||
|
border-radius: 4px;
|
||||||
|
font-size: 0.75rem;
|
||||||
|
font-weight: 900;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
gap: 1.2rem;
|
||||||
|
letter-spacing: 0.1em;
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.submitBtn:hover {
|
||||||
|
background-color: #ff4444;
|
||||||
|
transform: translateY(-3px);
|
||||||
|
box-shadow: 0 10px 30px rgba(255, 0, 0, 0.2);
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 1024px) {
|
||||||
|
.grid { grid-template-columns: 1fr; gap: 4rem; }
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
.container { padding: 0 2rem; }
|
||||||
|
.title { font-size: 2.5rem; }
|
||||||
|
.contactForm { padding: 3rem 2rem; }
|
||||||
|
}
|
||||||
123
src/components/Contact.tsx
Normal file
@ -0,0 +1,123 @@
|
|||||||
|
'use client';
|
||||||
|
|
||||||
|
import { motion } from 'framer-motion';
|
||||||
|
import { Mail, Phone, MapPin, Send, MessageSquare, Clock } from 'lucide-react';
|
||||||
|
import styles from './Contact.module.css';
|
||||||
|
|
||||||
|
export default function Contact() {
|
||||||
|
return (
|
||||||
|
<section className={styles.section}>
|
||||||
|
<div className={styles.container}>
|
||||||
|
<div className={styles.header}>
|
||||||
|
<motion.span
|
||||||
|
className={styles.label}
|
||||||
|
initial={{ opacity: 0, y: 10 }}
|
||||||
|
animate={{ opacity: 1, y: 0 }}
|
||||||
|
>
|
||||||
|
GET IN TOUCH
|
||||||
|
</motion.span>
|
||||||
|
<motion.h2
|
||||||
|
className={styles.title}
|
||||||
|
initial={{ opacity: 0, y: 20 }}
|
||||||
|
animate={{ opacity: 1, y: 0 }}
|
||||||
|
transition={{ delay: 0.1 }}
|
||||||
|
>
|
||||||
|
TECHNICAL <span className={styles.red}>SUPPORT</span> & SALES
|
||||||
|
</motion.h2>
|
||||||
|
<motion.p
|
||||||
|
className={styles.desc}
|
||||||
|
initial={{ opacity: 0, y: 30 }}
|
||||||
|
animate={{ opacity: 1, y: 0 }}
|
||||||
|
transition={{ delay: 0.2 }}
|
||||||
|
>
|
||||||
|
Our specialized team is available for technical consultations, installation queries, and dealer network applications.
|
||||||
|
</motion.p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className={styles.grid}>
|
||||||
|
<motion.div
|
||||||
|
className={styles.infoCol}
|
||||||
|
initial={{ opacity: 0, x: -30 }}
|
||||||
|
animate={{ opacity: 1, x: 0 }}
|
||||||
|
transition={{ duration: 0.6, delay: 0.3 }}
|
||||||
|
>
|
||||||
|
<div className={styles.infoCard}>
|
||||||
|
<div className={styles.infoIcon}><Mail size={24} /></div>
|
||||||
|
<div className={styles.infoText}>
|
||||||
|
<h4>EMAIL ENQUIRIES</h4>
|
||||||
|
<p>support@hondavert.com</p>
|
||||||
|
<p>sales@hondavert.com</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className={styles.infoCard}>
|
||||||
|
<div className={styles.infoIcon}><Phone size={24} /></div>
|
||||||
|
<div className={styles.infoText}>
|
||||||
|
<h4>DIRECT LINE</h4>
|
||||||
|
<p>+48 123 456 789 (EU Support)</p>
|
||||||
|
<p>+1 (800) 555-JDM (US Support)</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className={styles.infoCard}>
|
||||||
|
<div className={styles.infoIcon}><Clock size={24} /></div>
|
||||||
|
<div className={styles.infoText}>
|
||||||
|
<h4>TECHNICAL HOURS</h4>
|
||||||
|
<p>Mon - Fri: 09:00 - 18:00 (GMT+1)</p>
|
||||||
|
<p>Saturday: Emergency Support Only</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className={styles.infoCard}>
|
||||||
|
<div className={styles.infoIcon}><MapPin size={24} /></div>
|
||||||
|
<div className={styles.infoText}>
|
||||||
|
<h4>GLOBAL HUB</h4>
|
||||||
|
<p>Precision Engineering HQ</p>
|
||||||
|
<p>Warsaw, Poland. Europe</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</motion.div>
|
||||||
|
|
||||||
|
<motion.div
|
||||||
|
className={styles.formCol}
|
||||||
|
initial={{ opacity: 0, x: 30 }}
|
||||||
|
animate={{ opacity: 1, x: 0 }}
|
||||||
|
transition={{ duration: 0.6, delay: 0.4 }}
|
||||||
|
>
|
||||||
|
<form className={styles.contactForm} onSubmit={(e) => e.preventDefault()}>
|
||||||
|
<div className={styles.inputGroup}>
|
||||||
|
<label>FULL NAME</label>
|
||||||
|
<input type="text" placeholder="e.g. Mark Honda" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className={styles.inputGroup}>
|
||||||
|
<label>EMAIL ADDRESS</label>
|
||||||
|
<input type="email" placeholder="mark@example.com" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className={styles.inputGroup}>
|
||||||
|
<label>SUBJECT</label>
|
||||||
|
<select>
|
||||||
|
<option>Technical Support</option>
|
||||||
|
<option>Hardware Installation</option>
|
||||||
|
<option>Software Licensing</option>
|
||||||
|
<option>Wholesale/Dealer Network</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className={styles.inputGroup}>
|
||||||
|
<label>MESSAGE</label>
|
||||||
|
<textarea rows={5} placeholder="Explain your build or technical requirement..."></textarea>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<button className={styles.submitBtn}>
|
||||||
|
<span>TRANSMIT MESSAGE</span>
|
||||||
|
<Send size={18} />
|
||||||
|
</button>
|
||||||
|
</form>
|
||||||
|
</motion.div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
);
|
||||||
|
}
|
||||||
133
src/components/Features.module.css
Normal file
@ -0,0 +1,133 @@
|
|||||||
|
.section {
|
||||||
|
padding: 150px 0;
|
||||||
|
background-color: #050505;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.container {
|
||||||
|
max-width: 1400px;
|
||||||
|
width: 100%;
|
||||||
|
margin: 0 auto;
|
||||||
|
padding: 0 4rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.grid {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 1fr 1.5fr;
|
||||||
|
gap: 6rem;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.title {
|
||||||
|
font-size: clamp(2.5rem, 6vw, 4.5rem);
|
||||||
|
font-weight: 900;
|
||||||
|
line-height: 0.85;
|
||||||
|
letter-spacing: -0.05em;
|
||||||
|
margin-bottom: 5rem;
|
||||||
|
text-transform: uppercase;
|
||||||
|
}
|
||||||
|
|
||||||
|
.outline {
|
||||||
|
color: transparent;
|
||||||
|
-webkit-text-stroke: 1px var(--primary);
|
||||||
|
font-style: italic;
|
||||||
|
}
|
||||||
|
|
||||||
|
.featureList {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 3rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.feature {
|
||||||
|
display: flex;
|
||||||
|
gap: 2rem;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.iconBox {
|
||||||
|
background-color: #0c0c0c;
|
||||||
|
border: 1px solid #1a1a1a;
|
||||||
|
padding: 1.5rem;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.red {
|
||||||
|
color: var(--primary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.content h3 {
|
||||||
|
font-size: 1.1rem;
|
||||||
|
font-weight: 900;
|
||||||
|
margin-bottom: 0.8rem;
|
||||||
|
letter-spacing: -0.02em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content p {
|
||||||
|
font-size: 0.85rem;
|
||||||
|
color: #777;
|
||||||
|
line-height: 1.6;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
.right {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.imageWrapper {
|
||||||
|
position: relative;
|
||||||
|
background: radial-gradient(circle at center, rgba(255, 0, 0, 0.05) 0%, transparent 70%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.detailImg {
|
||||||
|
width: 100%;
|
||||||
|
height: auto;
|
||||||
|
object-fit: cover;
|
||||||
|
border-radius: 12px;
|
||||||
|
filter: saturate(0) brightness(0.8);
|
||||||
|
}
|
||||||
|
|
||||||
|
.buildQuality {
|
||||||
|
position: absolute;
|
||||||
|
bottom: -40px;
|
||||||
|
right: 40px;
|
||||||
|
max-width: 300px;
|
||||||
|
background-color: #0d0d0d;
|
||||||
|
border: 1px solid #1a1a1a;
|
||||||
|
padding: 2.5rem;
|
||||||
|
border-bottom: 3px solid var(--primary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.buildQuality strong {
|
||||||
|
font-size: 0.7rem;
|
||||||
|
font-weight: 900;
|
||||||
|
color: var(--primary);
|
||||||
|
letter-spacing: 0.1em;
|
||||||
|
display: block;
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.buildQuality p {
|
||||||
|
font-size: 0.75rem;
|
||||||
|
color: #555;
|
||||||
|
line-height: 1.5;
|
||||||
|
font-family: monospace;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 1024px) {
|
||||||
|
.grid {
|
||||||
|
grid-template-columns: 1fr;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
.feature {
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
.buildQuality {
|
||||||
|
position: relative;
|
||||||
|
bottom: auto;
|
||||||
|
right: auto;
|
||||||
|
margin: 2rem auto 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
61
src/components/Features.tsx
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
'use client';
|
||||||
|
|
||||||
|
import { motion } from 'framer-motion';
|
||||||
|
import Image from 'next/image';
|
||||||
|
import { Radio, ShieldCheck } from 'lucide-react';
|
||||||
|
import styles from './Features.module.css';
|
||||||
|
|
||||||
|
export default function Features() {
|
||||||
|
return (
|
||||||
|
<section className={styles.section}>
|
||||||
|
<div className={styles.container}>
|
||||||
|
<div className={styles.grid}>
|
||||||
|
<div className={styles.left}>
|
||||||
|
<h2 className={styles.title}>
|
||||||
|
THE PRECISION <br />
|
||||||
|
<span className={styles.outline}>DIFFERENCE</span>
|
||||||
|
</h2>
|
||||||
|
|
||||||
|
<div className={styles.featureList}>
|
||||||
|
<div className={styles.feature}>
|
||||||
|
<div className={styles.iconBox}>
|
||||||
|
<Radio className={styles.red} size={20} />
|
||||||
|
</div>
|
||||||
|
<div className={styles.content}>
|
||||||
|
<h3>REAL-TIME TELEMETRY</h3>
|
||||||
|
<p>Stream live engine data with zero latency directly to your workstation for surgical tuning precision.</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className={styles.feature}>
|
||||||
|
<div className={styles.iconBox}>
|
||||||
|
<ShieldCheck className={styles.red} size={20} />
|
||||||
|
</div>
|
||||||
|
<div className={styles.content}>
|
||||||
|
<h3>FAIL-SAFE RECOVERY</h3>
|
||||||
|
<p>Advanced brick-protection logic ensures your ECU remains accessible even in the event of power interruption.</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className={styles.right}>
|
||||||
|
<div className={styles.imageWrapper}>
|
||||||
|
<Image
|
||||||
|
src="/ecu_kpro.png"
|
||||||
|
alt="ECU Detail"
|
||||||
|
width={800}
|
||||||
|
height={600}
|
||||||
|
className={styles.detailImg}
|
||||||
|
/>
|
||||||
|
<div className={styles.buildQuality}>
|
||||||
|
<strong>BUILD QUALITY</strong>
|
||||||
|
<p>"Engineered for the workshop environment. Anodized aluminum housing with reinforced strain-relief cabling."</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
);
|
||||||
|
}
|
||||||
139
src/components/Footer.module.css
Normal file
@ -0,0 +1,139 @@
|
|||||||
|
.footer {
|
||||||
|
padding: 100px 0 50px;
|
||||||
|
background-color: var(--neutral);
|
||||||
|
border-top: 1px solid var(--border);
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.container {
|
||||||
|
max-width: 1400px;
|
||||||
|
width: 100%;
|
||||||
|
margin: 0 auto;
|
||||||
|
padding: 0 4rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.grid {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 1.5fr 2fr 1fr;
|
||||||
|
gap: 4rem;
|
||||||
|
margin-bottom: 80px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.branding {
|
||||||
|
max-width: 400px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.logoText {
|
||||||
|
font-size: 1.5rem;
|
||||||
|
font-weight: 900;
|
||||||
|
letter-spacing: -0.05em;
|
||||||
|
margin-bottom: 1.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.red {
|
||||||
|
color: var(--primary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.description {
|
||||||
|
font-size: 0.75rem;
|
||||||
|
color: #555;
|
||||||
|
font-weight: 800;
|
||||||
|
line-height: 1.6;
|
||||||
|
letter-spacing: 0.05em;
|
||||||
|
margin-bottom: 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.socials {
|
||||||
|
display: flex;
|
||||||
|
gap: 1.5rem;
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
|
||||||
|
.socials svg:hover {
|
||||||
|
color: var(--primary);
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.links {
|
||||||
|
display: flex;
|
||||||
|
gap: 4rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.col h4 {
|
||||||
|
font-size: 0.75rem;
|
||||||
|
font-weight: 900;
|
||||||
|
color: var(--primary);
|
||||||
|
margin-bottom: 1.5rem;
|
||||||
|
letter-spacing: 0.2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.col {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.col a {
|
||||||
|
font-size: 0.8rem;
|
||||||
|
color: #888;
|
||||||
|
font-weight: 600;
|
||||||
|
transition: color 0.2s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.col a:hover {
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.statusBox {
|
||||||
|
background-color: var(--secondary);
|
||||||
|
border: 1px solid var(--border);
|
||||||
|
padding: 2rem;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.statusLine {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 1rem;
|
||||||
|
margin-bottom: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dot {
|
||||||
|
width: 6px;
|
||||||
|
height: 6px;
|
||||||
|
background-color: #00ff00;
|
||||||
|
border-radius: 50%;
|
||||||
|
box-shadow: 0 0 10px #00ff00;
|
||||||
|
}
|
||||||
|
|
||||||
|
.statusLine strong {
|
||||||
|
font-size: 0.75rem;
|
||||||
|
font-weight: 900;
|
||||||
|
}
|
||||||
|
|
||||||
|
.statusBox p {
|
||||||
|
font-size: 0.65rem;
|
||||||
|
color: #444;
|
||||||
|
font-weight: 900;
|
||||||
|
letter-spacing: 0.1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bottom {
|
||||||
|
border-top: 1px solid var(--secondary);
|
||||||
|
padding-top: 2rem;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
font-size: 0.65rem;
|
||||||
|
color: #333;
|
||||||
|
font-weight: 900;
|
||||||
|
letter-spacing: 0.1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
.grid {
|
||||||
|
grid-template-columns: 1fr;
|
||||||
|
gap: 3rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
61
src/components/Footer.tsx
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
import Link from 'next/link';
|
||||||
|
import Image from 'next/image';
|
||||||
|
import { Camera, Play, MessageSquare } from 'lucide-react';
|
||||||
|
import styles from './Footer.module.css';
|
||||||
|
|
||||||
|
export default function Footer() {
|
||||||
|
return (
|
||||||
|
<footer className={styles.footer}>
|
||||||
|
<div className={styles.container}>
|
||||||
|
<div className={styles.grid}>
|
||||||
|
<div className={styles.branding}>
|
||||||
|
<div className={styles.logoImg}>
|
||||||
|
<Image src="/hondavert_logo.png" alt="HondaVert" width={150} height={44} />
|
||||||
|
</div>
|
||||||
|
<p className={styles.description}>
|
||||||
|
PRECISION ENGINEERING FOR THE MODERN HONDA ENTHUSIAST. BUILT FOR THE TRACK, REFINED IN THE GARAGE.
|
||||||
|
</p>
|
||||||
|
<div className={styles.socials}>
|
||||||
|
<Camera size={18} />
|
||||||
|
<Play size={18} />
|
||||||
|
<MessageSquare size={18} />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className={styles.links}>
|
||||||
|
<div className={styles.col}>
|
||||||
|
<h4>PRODUCT</h4>
|
||||||
|
<Link href="#">SUPPORT</Link>
|
||||||
|
<Link href="#">PRIVACY POLICY</Link>
|
||||||
|
<Link href="#">TERMS OF SERVICE</Link>
|
||||||
|
</div>
|
||||||
|
<div className={styles.col}>
|
||||||
|
<h4>CONNECT</h4>
|
||||||
|
<Link href="#">NEWSLETTER</Link>
|
||||||
|
<Link href="#">CONTACT</Link>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className={styles.status}>
|
||||||
|
<div className={styles.statusBox}>
|
||||||
|
<div className={styles.statusLine}>
|
||||||
|
<span className={styles.dot}></span>
|
||||||
|
<strong>SERVER ONLINE</strong>
|
||||||
|
</div>
|
||||||
|
<p>GLOBAL NET NODE 0863</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className={styles.bottom}>
|
||||||
|
<div className={styles.copyright}>
|
||||||
|
© 2026 HONDA VERT PRECISION ENGINEERING. ALL RIGHTS RESERVED.
|
||||||
|
</div>
|
||||||
|
<div className={styles.coords}>
|
||||||
|
LAT: 35.6895° N | LON: 139.6917° E
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</footer>
|
||||||
|
);
|
||||||
|
}
|
||||||
140
src/components/Hero.module.css
Normal file
@ -0,0 +1,140 @@
|
|||||||
|
.hero {
|
||||||
|
min-height: 100vh;
|
||||||
|
padding-top: 100px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
background-color: var(--background);
|
||||||
|
overflow: hidden;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content {
|
||||||
|
max-width: 1400px;
|
||||||
|
width: 100%;
|
||||||
|
margin: 0 auto;
|
||||||
|
padding: 0 4rem;
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 1.2fr 1fr;
|
||||||
|
gap: 4rem;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.version {
|
||||||
|
color: #555;
|
||||||
|
font-size: 0.75rem;
|
||||||
|
letter-spacing: 0.2rem;
|
||||||
|
font-weight: 700;
|
||||||
|
border-left: 2px solid var(--primary);
|
||||||
|
padding-left: 0.8rem;
|
||||||
|
margin-bottom: 2rem;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.title {
|
||||||
|
font-size: clamp(3rem, 7vw, 6rem);
|
||||||
|
font-weight: 900;
|
||||||
|
line-height: 0.85;
|
||||||
|
letter-spacing: -0.05em;
|
||||||
|
margin-bottom: 2rem;
|
||||||
|
text-transform: uppercase;
|
||||||
|
}
|
||||||
|
|
||||||
|
.red {
|
||||||
|
color: var(--primary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.description {
|
||||||
|
font-size: 1.1rem;
|
||||||
|
color: var(--text-dim);
|
||||||
|
line-height: 1.6;
|
||||||
|
max-width: 500px;
|
||||||
|
margin-bottom: 3rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.actions {
|
||||||
|
display: flex;
|
||||||
|
gap: 1rem;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 0.8rem;
|
||||||
|
padding: 1rem 1.8rem;
|
||||||
|
border-radius: 4px;
|
||||||
|
font-size: 0.75rem;
|
||||||
|
font-weight: 800;
|
||||||
|
letter-spacing: 0.1em;
|
||||||
|
transition: all 0.2s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btnPrimary {
|
||||||
|
background-color: var(--primary);
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btnSecondary {
|
||||||
|
background-color: rgba(255, 255, 255, 0.05);
|
||||||
|
border: 1px solid #222;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btnDownload {
|
||||||
|
background-color: #1a1a1a;
|
||||||
|
border: 1px solid #333;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn:hover {
|
||||||
|
transform: translateY(-2px);
|
||||||
|
filter: brightness(1.2);
|
||||||
|
}
|
||||||
|
|
||||||
|
.right {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.imageWrapper {
|
||||||
|
position: relative;
|
||||||
|
background: radial-gradient(circle at center, rgba(255, 0, 0, 0.1) 0%, transparent 70%);
|
||||||
|
border-radius: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mainImage {
|
||||||
|
width: 100%;
|
||||||
|
height: auto;
|
||||||
|
object-fit: contain;
|
||||||
|
filter: drop-shadow(0 0 50px rgba(0, 0, 0, 0.5));
|
||||||
|
}
|
||||||
|
|
||||||
|
.badge {
|
||||||
|
position: absolute;
|
||||||
|
top: 20px;
|
||||||
|
right: 20px;
|
||||||
|
background-color: var(--primary);
|
||||||
|
color: white;
|
||||||
|
padding: 0.4rem 0.8rem;
|
||||||
|
font-size: 0.6rem;
|
||||||
|
font-weight: 900;
|
||||||
|
letter-spacing: 0.1rem;
|
||||||
|
text-transform: uppercase;
|
||||||
|
z-index: 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 1024px) {
|
||||||
|
.content {
|
||||||
|
grid-template-columns: 1fr;
|
||||||
|
text-align: center;
|
||||||
|
padding: 0 2rem;
|
||||||
|
gap: 3rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.description {
|
||||||
|
margin: 0 auto 3rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.actions {
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
}
|
||||||
69
src/components/Hero.tsx
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
'use client';
|
||||||
|
|
||||||
|
import { motion } from 'framer-motion';
|
||||||
|
import Image from 'next/image';
|
||||||
|
import { Info, BookOpen, Download } from 'lucide-react';
|
||||||
|
import styles from './Hero.module.css';
|
||||||
|
|
||||||
|
interface HeroProps {
|
||||||
|
version?: string;
|
||||||
|
title1: string;
|
||||||
|
title2: string;
|
||||||
|
description: string;
|
||||||
|
image: string;
|
||||||
|
badge?: string;
|
||||||
|
className?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function Hero({ version, title1, title2, description, image, badge, className }: HeroProps) {
|
||||||
|
return (
|
||||||
|
<section className={`${styles.hero} ${className}`}>
|
||||||
|
<div className={styles.content}>
|
||||||
|
<motion.div
|
||||||
|
initial={{ opacity: 0, x: -30 }}
|
||||||
|
animate={{ opacity: 1, x: 0 }}
|
||||||
|
transition={{ duration: 0.8 }}
|
||||||
|
className={styles.left}
|
||||||
|
>
|
||||||
|
{version && <span className={styles.version}>{version}</span>}
|
||||||
|
<h1 className={styles.title}>
|
||||||
|
{title1} <br />
|
||||||
|
<span className={styles.red}>{title2}</span>
|
||||||
|
</h1>
|
||||||
|
<p className={styles.description}>{description}</p>
|
||||||
|
|
||||||
|
<div className={styles.actions}>
|
||||||
|
<button className={`${styles.btn} ${styles.btnPrimary}`}>
|
||||||
|
<Info size={16} /> <span>INFORMATION</span>
|
||||||
|
</button>
|
||||||
|
<button className={`${styles.btn} ${styles.btnSecondary}`}>
|
||||||
|
<BookOpen size={16} /> <span>GUIDES</span>
|
||||||
|
</button>
|
||||||
|
<button className={`${styles.btn} ${styles.btnDownload}`}>
|
||||||
|
<Download size={16} /> <span>DOWNLOAD</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</motion.div>
|
||||||
|
|
||||||
|
<motion.div
|
||||||
|
initial={{ opacity: 0, scale: 0.9 }}
|
||||||
|
animate={{ opacity: 1, scale: 1 }}
|
||||||
|
transition={{ duration: 1, delay: 0.2 }}
|
||||||
|
className={styles.right}
|
||||||
|
>
|
||||||
|
<div className={styles.imageWrapper}>
|
||||||
|
{badge && <div className={styles.badge}>{badge}</div>}
|
||||||
|
<Image
|
||||||
|
src={image}
|
||||||
|
alt={title1}
|
||||||
|
width={1000}
|
||||||
|
height={1000}
|
||||||
|
className={styles.mainImage}
|
||||||
|
priority
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</motion.div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
);
|
||||||
|
}
|
||||||
153
src/components/HomeHeroSlider.module.css
Normal file
@ -0,0 +1,153 @@
|
|||||||
|
.wrapper {
|
||||||
|
position: relative;
|
||||||
|
height: 100vh;
|
||||||
|
width: 100%;
|
||||||
|
overflow: hidden;
|
||||||
|
background-color: #000;
|
||||||
|
}
|
||||||
|
|
||||||
|
.slide {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bgWrapper {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bgImg {
|
||||||
|
object-fit: cover;
|
||||||
|
filter: saturate(0.2) contrast(1.2) brightness(0.4);
|
||||||
|
}
|
||||||
|
|
||||||
|
.overlay {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
background: linear-gradient(to right, rgba(18, 18, 18, 0.9) 0%, rgba(18, 18, 18, 0.45) 50%, rgba(18, 18, 18, 0.2) 100%);
|
||||||
|
z-index: 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.container {
|
||||||
|
max-width: 1400px;
|
||||||
|
width: 100%;
|
||||||
|
margin: 0 auto;
|
||||||
|
padding: 0 4rem;
|
||||||
|
position: relative;
|
||||||
|
z-index: 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content {
|
||||||
|
max-width: 800px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.subtitle {
|
||||||
|
font-size: 1rem;
|
||||||
|
font-weight: 900;
|
||||||
|
color: var(--primary);
|
||||||
|
letter-spacing: 0.3rem;
|
||||||
|
display: block;
|
||||||
|
margin-bottom: 2rem;
|
||||||
|
text-transform: uppercase;
|
||||||
|
}
|
||||||
|
|
||||||
|
.title {
|
||||||
|
font-size: clamp(4rem, 12vw, 9rem);
|
||||||
|
font-weight: 900;
|
||||||
|
line-height: 0.85;
|
||||||
|
letter-spacing: -0.06em;
|
||||||
|
margin-bottom: 4rem;
|
||||||
|
text-transform: uppercase;
|
||||||
|
}
|
||||||
|
|
||||||
|
.desc {
|
||||||
|
font-size: 1.2rem;
|
||||||
|
color: #888;
|
||||||
|
line-height: 1.6;
|
||||||
|
margin-bottom: 4.5rem;
|
||||||
|
max-width: 650px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ctaBtn {
|
||||||
|
background-color: var(--primary);
|
||||||
|
color: #fff;
|
||||||
|
padding: 1.5rem 3.5rem;
|
||||||
|
border-radius: 4px;
|
||||||
|
font-size: 0.9rem;
|
||||||
|
font-weight: 900;
|
||||||
|
letter-spacing: 0.15rem;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 1.5rem;
|
||||||
|
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.ctaBtn:hover {
|
||||||
|
background-color: var(--primary-hover);
|
||||||
|
transform: translateY(-5px);
|
||||||
|
box-shadow: 0 15px 40px rgba(255, 0, 0, 0.3);
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav {
|
||||||
|
position: absolute;
|
||||||
|
bottom: 4rem;
|
||||||
|
right: 4rem;
|
||||||
|
display: flex;
|
||||||
|
gap: 1.5rem;
|
||||||
|
z-index: 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
.navBtn {
|
||||||
|
background-color: rgba(255, 255, 255, 0.05);
|
||||||
|
border: 1px solid rgba(255, 255, 255, 0.1);
|
||||||
|
color: #fff;
|
||||||
|
padding: 1.5rem;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: all 0.2s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.navBtn:hover {
|
||||||
|
background-color: var(--primary);
|
||||||
|
border-color: var(--primary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.dots {
|
||||||
|
position: absolute;
|
||||||
|
bottom: 5.5rem;
|
||||||
|
left: 4rem;
|
||||||
|
display: flex;
|
||||||
|
gap: 1.5rem;
|
||||||
|
z-index: 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dot {
|
||||||
|
width: 60px;
|
||||||
|
height: 4px;
|
||||||
|
background-color: rgba(255, 255, 255, 0.1);
|
||||||
|
cursor: pointer;
|
||||||
|
transition: all 0.3s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.activeDot {
|
||||||
|
background-color: var(--primary);
|
||||||
|
width: 120px;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 1024px) {
|
||||||
|
.content { text-align: center; }
|
||||||
|
.ctaBtn { margin: 0 auto; }
|
||||||
|
.nav { display: none; }
|
||||||
|
.dots { left: 50%; transform: translateX(-50%); bottom: 2rem; }
|
||||||
|
}
|
||||||
96
src/components/HomeHeroSlider.tsx
Normal file
@ -0,0 +1,96 @@
|
|||||||
|
'use client';
|
||||||
|
|
||||||
|
import { useState, useEffect } from 'react';
|
||||||
|
import { motion, AnimatePresence } from 'framer-motion';
|
||||||
|
import Image from 'next/image';
|
||||||
|
import { ChevronRight, ChevronLeft, Zap } from 'lucide-react';
|
||||||
|
import styles from './HomeHeroSlider.module.css';
|
||||||
|
|
||||||
|
const slides = [
|
||||||
|
{
|
||||||
|
title: 'KPRO V4.0',
|
||||||
|
subtitle: 'UNLEASHED PERFORMANCE',
|
||||||
|
desc: 'The ultimate tuning interface for Honda K-Series engines. Surgical precision meets raw performance.',
|
||||||
|
img: '/ecu_kpro.png',
|
||||||
|
link: '/products/kpro'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'CAN FLASH',
|
||||||
|
subtitle: 'HIGH-SPEED TUNING',
|
||||||
|
desc: 'The definitive OBDII tuning interface for modern platforms. Advanced encryption and extreme flashing speed.',
|
||||||
|
img: '/engine_bay.png',
|
||||||
|
link: '/products/canflash'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'S300 CORE',
|
||||||
|
subtitle: 'LEGACY REDEFINED',
|
||||||
|
desc: 'Professional grade engine management for OBD1 Honda ECUs. Real-time data logging and track-ready metrics.',
|
||||||
|
img: '/hondavert_map_sensor_1774593624455.png',
|
||||||
|
link: '/products/s300'
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
export default function HomeHeroSlider() {
|
||||||
|
const [current, setCurrent] = useState(0);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const timer = setInterval(() => {
|
||||||
|
setCurrent((prev) => (prev + 1) % slides.length);
|
||||||
|
}, 6000);
|
||||||
|
return () => clearInterval(timer);
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const next = () => setCurrent((prev) => (prev + 1) % slides.length);
|
||||||
|
const prev = () => setCurrent((prev) => (prev - 1 + slides.length) % slides.length);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className={styles.wrapper}>
|
||||||
|
<AnimatePresence mode="wait">
|
||||||
|
<motion.div
|
||||||
|
key={current}
|
||||||
|
initial={{ opacity: 0 }}
|
||||||
|
animate={{ opacity: 1 }}
|
||||||
|
exit={{ opacity: 0 }}
|
||||||
|
transition={{ duration: 0.8 }}
|
||||||
|
className={styles.slide}
|
||||||
|
>
|
||||||
|
<div className={styles.bgWrapper}>
|
||||||
|
<Image src={slides[current].img} alt={slides[current].title} fill className={styles.bgImg} priority />
|
||||||
|
</div>
|
||||||
|
<div className={styles.overlay}></div>
|
||||||
|
|
||||||
|
<div className={styles.container}>
|
||||||
|
<motion.div
|
||||||
|
initial={{ y: 50, opacity: 0 }}
|
||||||
|
animate={{ y: 0, opacity: 1 }}
|
||||||
|
transition={{ delay: 0.4 }}
|
||||||
|
className={styles.content}
|
||||||
|
>
|
||||||
|
<span className={styles.subtitle}>{slides[current].subtitle}</span>
|
||||||
|
<h1 className={styles.title}>{slides[current].title}</h1>
|
||||||
|
<p className={styles.desc}>{slides[current].desc}</p>
|
||||||
|
<button className={styles.ctaBtn}>
|
||||||
|
EXPLORE SYSTEM <Zap size={18} />
|
||||||
|
</button>
|
||||||
|
</motion.div>
|
||||||
|
</div>
|
||||||
|
</motion.div>
|
||||||
|
</AnimatePresence>
|
||||||
|
|
||||||
|
<div className={styles.nav}>
|
||||||
|
<button onClick={prev} className={styles.navBtn}><ChevronLeft size={32} /></button>
|
||||||
|
<button onClick={next} className={styles.navBtn}><ChevronRight size={32} /></button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className={styles.dots}>
|
||||||
|
{slides.map((_, i) => (
|
||||||
|
<div
|
||||||
|
key={i}
|
||||||
|
className={`${styles.dot} ${i === current ? styles.activeDot : ''}`}
|
||||||
|
onClick={() => setCurrent(i)}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
57
src/components/HomeProducts.module.css
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
.section {
|
||||||
|
padding: 150px 0;
|
||||||
|
background-color: var(--background);
|
||||||
|
}
|
||||||
|
|
||||||
|
.container {
|
||||||
|
max-width: 1400px;
|
||||||
|
width: 100%;
|
||||||
|
margin: 0 auto;
|
||||||
|
padding: 0 4rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: flex-end;
|
||||||
|
margin-bottom: 80px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.label {
|
||||||
|
font-size: 0.65rem;
|
||||||
|
font-weight: 900;
|
||||||
|
color: var(--primary);
|
||||||
|
letter-spacing: 0.15em;
|
||||||
|
margin-bottom: 2rem;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.title {
|
||||||
|
font-size: clamp(2.5rem, 5vw, 4rem);
|
||||||
|
font-weight: 900;
|
||||||
|
line-height: 1;
|
||||||
|
letter-spacing: -0.05em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.allBtn {
|
||||||
|
font-size: 0.75rem;
|
||||||
|
font-weight: 900;
|
||||||
|
color: #fff;
|
||||||
|
border-bottom: 2px solid var(--primary);
|
||||||
|
padding-bottom: 0.5rem;
|
||||||
|
transition: all 0.2s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.allBtn:hover {
|
||||||
|
color: var(--primary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.grid {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(auto-fit, minmax(350px, 1fr));
|
||||||
|
gap: 3rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
.header { flex-direction: column; align-items: flex-start; gap: 4rem; }
|
||||||
|
}
|
||||||
50
src/components/HomeProducts.tsx
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
'use client';
|
||||||
|
|
||||||
|
import { motion } from 'framer-motion';
|
||||||
|
import Link from 'next/link';
|
||||||
|
import ProductCard from './ProductCard';
|
||||||
|
import { products } from '@/lib/products';
|
||||||
|
import styles from './HomeProducts.module.css';
|
||||||
|
|
||||||
|
export default function HomeProducts() {
|
||||||
|
const displayProducts = [
|
||||||
|
products.find(p => p.id === 'kpro'),
|
||||||
|
products.find(p => p.id === 'canflash'),
|
||||||
|
products.find(p => p.id === 's300'),
|
||||||
|
].filter(Boolean);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<section className={styles.section}>
|
||||||
|
<div className={styles.container}>
|
||||||
|
<div className={styles.header}>
|
||||||
|
<div className={styles.left}>
|
||||||
|
<span className={styles.label}>DISCOVER OUR LINEUP</span>
|
||||||
|
<h2 className={styles.title}>PRECISION PRODUCTS</h2>
|
||||||
|
</div>
|
||||||
|
<Link href="/products" className={styles.allBtn}>VIEW ALL PRODUCTS</Link>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className={styles.grid}>
|
||||||
|
{displayProducts.map((product, i) => (
|
||||||
|
<motion.div
|
||||||
|
key={i}
|
||||||
|
initial={{ y: 50, opacity: 0 }}
|
||||||
|
whileInView={{ y: 0, opacity: 1 }}
|
||||||
|
viewport={{ once: true }}
|
||||||
|
transition={{ delay: i * 0.15 }}
|
||||||
|
>
|
||||||
|
<ProductCard
|
||||||
|
id={product!.id}
|
||||||
|
name={product!.name}
|
||||||
|
subtitle={product!.subtitle}
|
||||||
|
description={product!.description}
|
||||||
|
image={product!.image}
|
||||||
|
price={product!.price}
|
||||||
|
/>
|
||||||
|
</motion.div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
);
|
||||||
|
}
|
||||||
684
src/components/KPro.module.css
Normal file
@ -0,0 +1,684 @@
|
|||||||
|
.wrapper {
|
||||||
|
background-color: var(--neutral);
|
||||||
|
min-height: 100vh;
|
||||||
|
}
|
||||||
|
|
||||||
|
.container {
|
||||||
|
max-width: 1400px;
|
||||||
|
width: 100%;
|
||||||
|
margin: 0 auto;
|
||||||
|
padding: 0 4rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 1. HERO SECTION */
|
||||||
|
.hero {
|
||||||
|
position: relative;
|
||||||
|
min-height: 80vh;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
overflow: hidden;
|
||||||
|
padding-top: 100px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bgWrapper {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.heroImg {
|
||||||
|
object-fit: cover;
|
||||||
|
filter: saturate(0.2) contrast(1.2) brightness(0.4);
|
||||||
|
}
|
||||||
|
|
||||||
|
.heroOverlay {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
background: linear-gradient(to bottom, rgba(0,0,0,0.6) 0%, rgba(0,0,0,0.9) 100%);
|
||||||
|
z-index: 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.heroGrid {
|
||||||
|
position: relative;
|
||||||
|
z-index: 3;
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 1.5fr 1fr;
|
||||||
|
gap: 5rem;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.heroLabel {
|
||||||
|
font-size: 0.65rem;
|
||||||
|
font-weight: 900;
|
||||||
|
color: #555;
|
||||||
|
letter-spacing: 0.2rem;
|
||||||
|
display: block;
|
||||||
|
margin-bottom: 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.heroTitle {
|
||||||
|
font-size: clamp(4rem, 8vw, 6.5rem);
|
||||||
|
font-weight: 900;
|
||||||
|
line-height: 0.85;
|
||||||
|
letter-spacing: -0.05em;
|
||||||
|
margin-bottom: 2.5rem;
|
||||||
|
text-transform: uppercase;
|
||||||
|
}
|
||||||
|
|
||||||
|
.red {
|
||||||
|
color: var(--primary);
|
||||||
|
font-style: italic;
|
||||||
|
}
|
||||||
|
|
||||||
|
.heroDesc {
|
||||||
|
font-size: 1.1rem;
|
||||||
|
color: #888;
|
||||||
|
line-height: 1.6;
|
||||||
|
margin-bottom: 3.5rem;
|
||||||
|
max-width: 600px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.heroActions {
|
||||||
|
display: flex;
|
||||||
|
gap: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.primaryBtn {
|
||||||
|
background-color: var(--primary);
|
||||||
|
padding: 1.2rem 2.2rem;
|
||||||
|
border-radius: 4px;
|
||||||
|
font-size: 0.7rem;
|
||||||
|
font-weight: 900;
|
||||||
|
letter-spacing: 0.1em;
|
||||||
|
color: #fff;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 1.2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.secondaryBtn {
|
||||||
|
background-color: rgba(255, 255, 255, 0.02);
|
||||||
|
border: 1px solid var(--border);
|
||||||
|
padding: 1.2rem 2.2rem;
|
||||||
|
border-radius: 4px;
|
||||||
|
font-size: 0.7rem;
|
||||||
|
font-weight: 900;
|
||||||
|
letter-spacing: 0.1em;
|
||||||
|
color: #fff;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 1.2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.heroSpecs {
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-end;
|
||||||
|
}
|
||||||
|
|
||||||
|
.specBox {
|
||||||
|
background-color: rgba(18, 18, 18, 0.4);
|
||||||
|
border: 1px solid rgba(255, 255, 255, 0.05);
|
||||||
|
backdrop-filter: blur(10px);
|
||||||
|
padding: 3rem;
|
||||||
|
width: 100%;
|
||||||
|
max-width: 400px;
|
||||||
|
border-radius: 4px;
|
||||||
|
position: relative;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.progressLine {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 60%;
|
||||||
|
height: 2px;
|
||||||
|
background-color: var(--primary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.specItem {
|
||||||
|
margin-bottom: 2.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.specItem:last-child { margin-bottom: 0; }
|
||||||
|
|
||||||
|
.specLabel {
|
||||||
|
font-size: 0.55rem;
|
||||||
|
font-weight: 900;
|
||||||
|
color: #444;
|
||||||
|
letter-spacing: 0.1em;
|
||||||
|
display: block;
|
||||||
|
margin-bottom: 0.8rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.specItem h3 {
|
||||||
|
font-size: 1.3rem;
|
||||||
|
font-weight: 900;
|
||||||
|
font-style: italic;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 2. OVERVIEW */
|
||||||
|
.overview {
|
||||||
|
padding: 120px 0;
|
||||||
|
background-color: var(--neutral);
|
||||||
|
}
|
||||||
|
|
||||||
|
.overviewGrid {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 1fr 1fr;
|
||||||
|
gap: 8rem;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.overviewContent h2 {
|
||||||
|
font-size: 3rem;
|
||||||
|
font-weight: 900;
|
||||||
|
letter-spacing: -0.05em;
|
||||||
|
margin-bottom: 3rem;
|
||||||
|
line-height: 0.9;
|
||||||
|
}
|
||||||
|
|
||||||
|
.featuresGrid {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 1fr 1fr;
|
||||||
|
gap: 3rem 4rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.featureItem {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 1.2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fIcon {
|
||||||
|
width: 32px;
|
||||||
|
height: 32px;
|
||||||
|
color: var(--primary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.featureItem h3 {
|
||||||
|
font-size: 0.85rem;
|
||||||
|
font-weight: 900;
|
||||||
|
letter-spacing: 0.1em;
|
||||||
|
text-transform: uppercase;
|
||||||
|
}
|
||||||
|
|
||||||
|
.featureItem p {
|
||||||
|
font-size: 0.75rem;
|
||||||
|
color: #777;
|
||||||
|
line-height: 1.5;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
.overviewImage {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hwImg {
|
||||||
|
width: 100%;
|
||||||
|
height: auto;
|
||||||
|
border-radius: 4px;
|
||||||
|
filter: saturate(0.8) contrast(1.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.imageOverlay {
|
||||||
|
position: absolute;
|
||||||
|
inset: -20px;
|
||||||
|
border: 1px solid var(--border);
|
||||||
|
z-index: -1;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 3. ADVANCED FEATURES */
|
||||||
|
.advanced {
|
||||||
|
padding: 120px 0;
|
||||||
|
background-color: var(--secondary);
|
||||||
|
border-top: 1px solid var(--border);
|
||||||
|
border-bottom: 1px solid var(--border);
|
||||||
|
}
|
||||||
|
|
||||||
|
.advHeader {
|
||||||
|
text-align: center;
|
||||||
|
margin-bottom: 6rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.advHeader h2 {
|
||||||
|
font-size: 2.5rem;
|
||||||
|
font-weight: 900;
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.advHeader p {
|
||||||
|
font-size: 0.8rem;
|
||||||
|
color: var(--primary);
|
||||||
|
font-weight: 800;
|
||||||
|
letter-spacing: 0.2em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.advGrid {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(3, 1fr);
|
||||||
|
grid-auto-rows: 250px;
|
||||||
|
gap: 1.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.advCard {
|
||||||
|
position: relative;
|
||||||
|
background-color: rgba(33, 33, 33, 0.5);
|
||||||
|
border: 1px solid var(--border);
|
||||||
|
border-radius: 12px;
|
||||||
|
overflow: hidden;
|
||||||
|
backdrop-filter: blur(10px);
|
||||||
|
transition: all 0.5s cubic-bezier(0.23, 1, 0.32, 1);
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Bento Variants */
|
||||||
|
.advCardWide { grid-column: span 2; }
|
||||||
|
.advCardTall { grid-row: span 2; }
|
||||||
|
|
||||||
|
.advCard:hover {
|
||||||
|
border-color: var(--primary);
|
||||||
|
transform: scale(1.02);
|
||||||
|
box-shadow: 0 20px 40px rgba(0,0,0,0.5), 0 0 20px rgba(255,0,0,0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.cardImage {
|
||||||
|
position: absolute;
|
||||||
|
inset: 0;
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.advImg {
|
||||||
|
object-fit: cover;
|
||||||
|
filter: brightness(0.4) saturate(0.5);
|
||||||
|
transition: all 0.7s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.advCard:hover .advImg {
|
||||||
|
filter: brightness(0.6) saturate(1);
|
||||||
|
transform: scale(1.05);
|
||||||
|
}
|
||||||
|
|
||||||
|
.cardOverlay {
|
||||||
|
position: absolute;
|
||||||
|
inset: 0;
|
||||||
|
background: linear-gradient(to top, rgba(18, 18, 18, 0.9) 0%, transparent 100%);
|
||||||
|
z-index: 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cardContent {
|
||||||
|
position: relative;
|
||||||
|
z-index: 3;
|
||||||
|
padding: 2.5rem;
|
||||||
|
margin-top: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.advCard h3 {
|
||||||
|
font-size: 1.1rem;
|
||||||
|
font-weight: 900;
|
||||||
|
margin-bottom: 0.8rem;
|
||||||
|
color: #fff;
|
||||||
|
text-transform: uppercase;
|
||||||
|
letter-spacing: 0.1em;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.advCard h3::before {
|
||||||
|
content: '';
|
||||||
|
width: 20px;
|
||||||
|
height: 3px;
|
||||||
|
background-color: var(--primary);
|
||||||
|
box-shadow: 0 0 10px var(--primary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.cardContent p {
|
||||||
|
font-size: 0.75rem;
|
||||||
|
color: #aaa;
|
||||||
|
line-height: 1.6;
|
||||||
|
max-width: 400px;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 1024px) {
|
||||||
|
.advGrid {
|
||||||
|
grid-template-columns: 1fr;
|
||||||
|
grid-auto-rows: auto;
|
||||||
|
}
|
||||||
|
.advCardWide, .advCardTall {
|
||||||
|
grid-column: auto;
|
||||||
|
grid-row: auto;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 4. COMPATIBILITY */
|
||||||
|
.compatibility {
|
||||||
|
padding: 120px 0;
|
||||||
|
background-color: var(--neutral);
|
||||||
|
}
|
||||||
|
|
||||||
|
.compGrid {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 1fr 1fr;
|
||||||
|
gap: 4rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.compBox {
|
||||||
|
background-color: var(--card-bg);
|
||||||
|
border: 1px solid var(--border);
|
||||||
|
padding: 3rem;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.compBox h2 {
|
||||||
|
font-size: 1.5rem;
|
||||||
|
font-weight: 900;
|
||||||
|
margin-bottom: 2rem;
|
||||||
|
border-bottom: 1px solid var(--border);
|
||||||
|
padding-bottom: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.vList {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.vItem {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
font-size: 0.85rem;
|
||||||
|
padding-bottom: 0.8rem;
|
||||||
|
border-bottom: 1px solid rgba(255, 255, 255, 0.03);
|
||||||
|
}
|
||||||
|
|
||||||
|
.vTag {
|
||||||
|
font-family: monospace;
|
||||||
|
color: var(--primary);
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 5. TECH SUITE / INSTALLATION */
|
||||||
|
.techSuite {
|
||||||
|
padding: 150px 0;
|
||||||
|
background-color: var(--secondary);
|
||||||
|
border-top: 1px solid var(--border);
|
||||||
|
border-bottom: 1px solid var(--border);
|
||||||
|
}
|
||||||
|
|
||||||
|
.techHeader {
|
||||||
|
margin-bottom: 3rem;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.techHeader h2 {
|
||||||
|
font-size: 3.5rem;
|
||||||
|
font-weight: 900;
|
||||||
|
letter-spacing: -0.05em;
|
||||||
|
text-transform: uppercase;
|
||||||
|
}
|
||||||
|
|
||||||
|
.guideGrid {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(auto-fill, minmax(350px, 1fr));
|
||||||
|
gap: 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.guideCard {
|
||||||
|
position: relative;
|
||||||
|
background-color: var(--secondary);
|
||||||
|
border: 1px solid var(--border);
|
||||||
|
min-height: 450px;
|
||||||
|
border-radius: 8px;
|
||||||
|
overflow: hidden;
|
||||||
|
transition: all 0.4s cubic-bezier(0.165, 0.84, 0.44, 1);
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: flex-end;
|
||||||
|
}
|
||||||
|
|
||||||
|
.guideCard:hover {
|
||||||
|
border-color: var(--primary);
|
||||||
|
transform: translateY(-8px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.cardBg {
|
||||||
|
position: absolute;
|
||||||
|
inset: 0;
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bgImg {
|
||||||
|
object-fit: cover;
|
||||||
|
filter: saturate(0.2) brightness(0.5);
|
||||||
|
transition: transform 0.6s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.guideCard:hover .bgImg {
|
||||||
|
transform: scale(1.1);
|
||||||
|
filter: saturate(0.5) brightness(0.6);
|
||||||
|
}
|
||||||
|
|
||||||
|
.cardOverlay {
|
||||||
|
position: absolute;
|
||||||
|
inset: 0;
|
||||||
|
background: linear-gradient(to top, rgba(18, 18, 18, 1) 10%, rgba(18, 18, 18, 0.5) 50%, transparent 100%);
|
||||||
|
z-index: 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.guideContent {
|
||||||
|
position: relative;
|
||||||
|
z-index: 3;
|
||||||
|
padding: 3rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.guideIconBox {
|
||||||
|
color: var(--primary);
|
||||||
|
margin-bottom: 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.guideCard h3 {
|
||||||
|
font-size: 1.2rem;
|
||||||
|
font-weight: 900;
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
text-transform: uppercase;
|
||||||
|
letter-spacing: 0.1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.guideCard p {
|
||||||
|
font-size: 0.8rem;
|
||||||
|
color: #888;
|
||||||
|
line-height: 1.6;
|
||||||
|
margin-bottom: 2.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.guideBtn {
|
||||||
|
font-size: 0.65rem;
|
||||||
|
font-weight: 900;
|
||||||
|
color: #fff;
|
||||||
|
border-bottom: 2px solid var(--primary);
|
||||||
|
padding-bottom: 0.5rem;
|
||||||
|
text-transform: uppercase;
|
||||||
|
letter-spacing: 0.1em;
|
||||||
|
transition: all 0.2s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.guideBtn:hover {
|
||||||
|
color: var(--primary);
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 1024px) {
|
||||||
|
.guideGrid { grid-template-columns: 1fr; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 6. DOWNLOADS & SOFTWARE HUB */
|
||||||
|
.downloads {
|
||||||
|
padding: 150px 0;
|
||||||
|
background-color: var(--neutral);
|
||||||
|
position: relative;
|
||||||
|
border-top: 1px solid var(--border);
|
||||||
|
}
|
||||||
|
|
||||||
|
.dlHeader {
|
||||||
|
text-align: center;
|
||||||
|
margin-bottom: 6rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dlHeader h2 {
|
||||||
|
font-size: 3.5rem;
|
||||||
|
font-weight: 900;
|
||||||
|
letter-spacing: -0.05em;
|
||||||
|
text-transform: uppercase;
|
||||||
|
}
|
||||||
|
|
||||||
|
.alertBox {
|
||||||
|
max-width: 800px;
|
||||||
|
margin: 0 auto 5rem;
|
||||||
|
background-color: rgba(255, 0, 0, 0.05);
|
||||||
|
border: 1px solid rgba(255, 0, 0, 0.2);
|
||||||
|
padding: 2rem 3rem;
|
||||||
|
border-radius: 8px;
|
||||||
|
display: flex;
|
||||||
|
gap: 2rem;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.alertIcon { color: var(--primary); }
|
||||||
|
|
||||||
|
.alertText h4 {
|
||||||
|
font-size: 0.9rem;
|
||||||
|
font-weight: 900;
|
||||||
|
margin-bottom: 0.5rem;
|
||||||
|
color: var(--primary);
|
||||||
|
text-transform: uppercase;
|
||||||
|
letter-spacing: 0.1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.alertText p {
|
||||||
|
font-size: 0.8rem;
|
||||||
|
color: #888;
|
||||||
|
line-height: 1.6;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dlDashboard {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(auto-fit, minmax(350px, 1fr));
|
||||||
|
gap: 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dlCard {
|
||||||
|
background-color: var(--secondary);
|
||||||
|
border: 1px solid var(--border);
|
||||||
|
padding: 4rem 3rem;
|
||||||
|
border-radius: 8px;
|
||||||
|
text-align: center;
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
gap: 2rem;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dlCard:hover {
|
||||||
|
border-color: var(--primary);
|
||||||
|
transform: translateY(-8px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.dlIconBox {
|
||||||
|
width: 60px;
|
||||||
|
height: 60px;
|
||||||
|
background-color: rgba(255, 255, 255, 0.02);
|
||||||
|
border: 1px solid var(--border);
|
||||||
|
border-radius: 50%;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
color: var(--primary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.dlCard h3 {
|
||||||
|
font-size: 1.2rem;
|
||||||
|
font-weight: 900;
|
||||||
|
text-transform: uppercase;
|
||||||
|
letter-spacing: 0.1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dlCard p {
|
||||||
|
font-size: 0.75rem;
|
||||||
|
color: #666;
|
||||||
|
line-height: 1.6;
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.passwordBox {
|
||||||
|
background-color: rgba(255, 255, 255, 0.02);
|
||||||
|
border: 1px dashed var(--border);
|
||||||
|
padding: 1rem 1.5rem;
|
||||||
|
border-radius: 4px;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 0.5rem;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.passwordBox span {
|
||||||
|
font-size: 0.55rem;
|
||||||
|
font-weight: 900;
|
||||||
|
color: #444;
|
||||||
|
text-transform: uppercase;
|
||||||
|
letter-spacing: 0.1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.passKey {
|
||||||
|
font-family: monospace;
|
||||||
|
font-size: 1.1rem;
|
||||||
|
color: #fff;
|
||||||
|
font-weight: 900;
|
||||||
|
letter-spacing: 0.3em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dlVersion {
|
||||||
|
font-size: 0.6rem;
|
||||||
|
font-weight: 900;
|
||||||
|
color: var(--primary);
|
||||||
|
letter-spacing: 0.1em;
|
||||||
|
padding: 0.4rem 1.2rem;
|
||||||
|
background-color: rgba(255, 0, 0, 0.1);
|
||||||
|
border-radius: 100px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dlBtn {
|
||||||
|
width: 100%;
|
||||||
|
background-color: #fff;
|
||||||
|
color: #000;
|
||||||
|
padding: 1.2rem;
|
||||||
|
border-radius: 4px;
|
||||||
|
font-size: 0.75rem;
|
||||||
|
font-weight: 900;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
gap: 1rem;
|
||||||
|
text-transform: uppercase;
|
||||||
|
letter-spacing: 0.1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dlBtn:hover {
|
||||||
|
background-color: var(--primary);
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 1024px) {
|
||||||
|
.instGrid, .dlDashboard {
|
||||||
|
grid-template-columns: 1fr;
|
||||||
|
}
|
||||||
|
}
|
||||||
488
src/components/KPro.tsx
Normal file
@ -0,0 +1,488 @@
|
|||||||
|
'use client';
|
||||||
|
|
||||||
|
import { useRef } from 'react';
|
||||||
|
import { motion } from 'framer-motion';
|
||||||
|
import Image from 'next/image';
|
||||||
|
import {
|
||||||
|
Info,
|
||||||
|
BookOpen,
|
||||||
|
Download,
|
||||||
|
ShieldCheck,
|
||||||
|
Activity,
|
||||||
|
Car,
|
||||||
|
Gauge,
|
||||||
|
LayoutGrid,
|
||||||
|
Cpu,
|
||||||
|
Zap,
|
||||||
|
Layers,
|
||||||
|
Server,
|
||||||
|
Bluetooth,
|
||||||
|
FileText,
|
||||||
|
ExternalLink,
|
||||||
|
ChevronRight,
|
||||||
|
Settings,
|
||||||
|
CircleCheck,
|
||||||
|
Smartphone,
|
||||||
|
AlertTriangle,
|
||||||
|
ShieldAlert
|
||||||
|
} from 'lucide-react';
|
||||||
|
import styles from './KPro.module.css';
|
||||||
|
|
||||||
|
export default function KPro() {
|
||||||
|
const infoRef = useRef<HTMLDivElement>(null);
|
||||||
|
const guidesRef = useRef<HTMLDivElement>(null);
|
||||||
|
const downloadRef = useRef<HTMLDivElement>(null);
|
||||||
|
|
||||||
|
const scrollTo = (ref: React.RefObject<HTMLDivElement | null>) => {
|
||||||
|
ref.current?.scrollIntoView({ behavior: 'smooth' });
|
||||||
|
};
|
||||||
|
|
||||||
|
const coreFeatures = [
|
||||||
|
{ title: 'Live Engine Tuning', desc: 'Modify and calibrate fuel, ignition, and cam timing maps in real-time.', icon: <Activity size={24} /> },
|
||||||
|
{ title: 'Live Sensors Logging', desc: 'High-speed data streaming of all critical engine sensors for precision analysis.', icon: <Gauge size={24} /> },
|
||||||
|
{ title: 'Boost Management', desc: 'Comprehensive boost tables and control with custom MAP sensor support.', icon: <Zap size={24} /> },
|
||||||
|
{ title: 'Engine Protection', desc: 'Failsafe logic for lean AFR, overboost, and overheat conditions.', icon: <ShieldCheck size={24} /> },
|
||||||
|
{ title: 'Launch Control', desc: 'Programmable launch parameters with integrated anti-lag systems.', icon: <Settings size={24} /> },
|
||||||
|
{ title: 'Custom Outputs', desc: 'Programmable outputs for nitrous, methanol injection, and shift lights.', icon: <Layers size={24} /> },
|
||||||
|
];
|
||||||
|
|
||||||
|
const advancedFeatures = [
|
||||||
|
{ title: 'Bluetooth Connect', desc: 'Wireless datalogging and mobile app integration (Rev.4 boards only).', image: 'https://images.unsplash.com/photo-1758411897998-999b2fe9d8e6?auto=format&fit=crop&q=80&w=1200' },
|
||||||
|
{ title: 'Onboard Datalog', desc: 'High-precision 100Hz onboard logging for standalone data capture.', image: 'https://images.unsplash.com/photo-1771920800290-53f22e5ac3f8?auto=format&fit=crop&q=80&w=1200' },
|
||||||
|
{ title: 'FlexFuel Support', desc: 'Ethanol sensor input for automatic fuel and ignition adjustments.', image: 'https://images.unsplash.com/photo-1549411210-613d9061df8d?auto=format&fit=crop&q=80&w=1200' },
|
||||||
|
{ title: 'Engine Safety', desc: 'Advanced engine protection logic for high-performance builds.', image: 'https://images.unsplash.com/photo-1486496146582-9ffcd0b2b2b7?auto=format&fit=crop&q=80&w=800' },
|
||||||
|
{ title: 'Analog Inputs', desc: 'Eight additional analog inputs for external wideband and sensors.', image: 'https://images.unsplash.com/photo-1518770660439-4636190af475?auto=format&fit=crop&q=80&w=800' },
|
||||||
|
{ title: 'Target Lambda', desc: 'Closed-loop target lambda tables for optimized fuel control.', image: 'https://images.unsplash.com/photo-1565105158896-8fce03d1024f?auto=format&fit=crop&q=80&w=1200' },
|
||||||
|
];
|
||||||
|
|
||||||
|
const ecuRevisions = [
|
||||||
|
{ name: '001DD-L5005-A0', type: 'OKI 66Q592 MCU' },
|
||||||
|
{ name: '001DD-L5003-00', type: 'OKI 66Q592 MCU' },
|
||||||
|
];
|
||||||
|
|
||||||
|
const factoryModels = [
|
||||||
|
{ name: '02-05 Honda Civic Si', years: '02-05' },
|
||||||
|
{ name: '01-05 Honda Civic TypeR', years: '01-05' },
|
||||||
|
{ name: '01-06 Honda Integra DC5', years: '01-06' },
|
||||||
|
{ name: '02-06 Honda Integra TypeR', years: '02-06' },
|
||||||
|
{ name: '02-04 Acura RSX Base', years: '02-04' },
|
||||||
|
{ name: '02-04 Acura RSX TypeS', years: '02-04' },
|
||||||
|
];
|
||||||
|
|
||||||
|
const replacementModels = [
|
||||||
|
{ name: '99-03 Honda S2000 AP1', years: '99-03' },
|
||||||
|
{ name: '02-05 Honda Civic D17 MT', years: '02-05' },
|
||||||
|
{ name: 'EG/EK/DC K-Swap', years: 'Various' },
|
||||||
|
];
|
||||||
|
|
||||||
|
const downloads = [
|
||||||
|
{ name: 'KPro Manager Software', size: 'V4.5.6', type: 'Setup Executable' },
|
||||||
|
{ name: 'USB Driver Pack', size: '1.2 MB', type: 'Drivers' },
|
||||||
|
];
|
||||||
|
|
||||||
|
const guides = [
|
||||||
|
{ name: 'Hardware Installation Guide', type: 'PDF Documentation' },
|
||||||
|
{ name: 'Bluetooth Setup Utility', type: 'Config Tool' },
|
||||||
|
{ name: 'Board LEDs Quick Reference', type: 'Pinout Guide' },
|
||||||
|
];
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className={styles.wrapper}>
|
||||||
|
{/* 1. HERO SECTION */}
|
||||||
|
<section className={styles.hero}>
|
||||||
|
<div className={styles.bgWrapper}>
|
||||||
|
<Image src="/engine_bay.png" alt="Engine Bay" fill className={styles.heroImg} priority />
|
||||||
|
</div>
|
||||||
|
<div className={styles.heroOverlay}></div>
|
||||||
|
<div className={styles.container}>
|
||||||
|
<div className={styles.heroGrid}>
|
||||||
|
<motion.div
|
||||||
|
className={styles.heroContent}
|
||||||
|
initial={{ opacity: 0, x: -50 }}
|
||||||
|
animate={{ opacity: 1, x: 0 }}
|
||||||
|
transition={{ duration: 0.8, ease: "easeOut" }}
|
||||||
|
>
|
||||||
|
<span className={styles.heroLabel}>ULTIMATE ECU UPGRADE INTERFACE</span>
|
||||||
|
<h1 className={styles.heroTitle}>
|
||||||
|
K<span className={styles.red}>PRO</span>
|
||||||
|
</h1>
|
||||||
|
<p className={styles.heroDesc}>
|
||||||
|
The Hondavert KPro daughterboard is the definitive performance upgrade for Honda K-Series ECUs.
|
||||||
|
Unlock live tuning, advanced engine protection, and professional motorsport features.
|
||||||
|
</p>
|
||||||
|
<div className={styles.heroActions}>
|
||||||
|
<button
|
||||||
|
className={styles.primaryBtn}
|
||||||
|
onClick={() => scrollTo(infoRef)}
|
||||||
|
>
|
||||||
|
<Info size={18} />
|
||||||
|
<span>INFORMATION</span>
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
className={styles.secondaryBtn}
|
||||||
|
onClick={() => scrollTo(guidesRef)}
|
||||||
|
>
|
||||||
|
<BookOpen size={18} />
|
||||||
|
<span>GUIDES</span>
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
className={styles.secondaryBtn}
|
||||||
|
onClick={() => scrollTo(downloadRef)}
|
||||||
|
>
|
||||||
|
<Download size={18} />
|
||||||
|
<span>DOWNLOAD</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</motion.div>
|
||||||
|
|
||||||
|
<motion.div
|
||||||
|
className={styles.heroSpecs}
|
||||||
|
initial={{ opacity: 0, x: 50 }}
|
||||||
|
animate={{ opacity: 1, x: 0 }}
|
||||||
|
transition={{ duration: 0.8, delay: 0.2, ease: "easeOut" }}
|
||||||
|
>
|
||||||
|
<div className={styles.specBox}>
|
||||||
|
<div className={styles.progressLine}></div>
|
||||||
|
<div className={styles.specItem}>
|
||||||
|
<span className={styles.specLabel}>PLATFORM SUPPORT</span>
|
||||||
|
<h3>K-SERIES / VTC</h3>
|
||||||
|
</div>
|
||||||
|
<div className={styles.specItem}>
|
||||||
|
<span className={styles.specLabel}>DATALOG RATE</span>
|
||||||
|
<h3>100Hz REALTIME</h3>
|
||||||
|
</div>
|
||||||
|
<div className={styles.specItem}>
|
||||||
|
<span className={styles.specLabel}>CONNECTIVITY</span>
|
||||||
|
<h3>USB / BLUETOOTH</h3>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</motion.div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
{/* 2. OVERVIEW & FEATURES */}
|
||||||
|
<section ref={infoRef} className={styles.overview}>
|
||||||
|
<div className={styles.container}>
|
||||||
|
<div className={styles.overviewGrid}>
|
||||||
|
<motion.div
|
||||||
|
className={styles.overviewContent}
|
||||||
|
initial={{ opacity: 0, y: 30 }}
|
||||||
|
whileInView={{ opacity: 1, y: 0 }}
|
||||||
|
viewport={{ once: true }}
|
||||||
|
transition={{ duration: 0.6 }}
|
||||||
|
>
|
||||||
|
<h2>CORE PERFORMANCE <br /><span className={styles.red}>CAPABILITIES</span></h2>
|
||||||
|
<div className={styles.featuresGrid}>
|
||||||
|
{coreFeatures.map((feature, i) => (
|
||||||
|
<motion.div
|
||||||
|
key={i}
|
||||||
|
className={styles.featureItem}
|
||||||
|
initial={{ opacity: 0, y: 20 }}
|
||||||
|
whileInView={{ opacity: 1, y: 0 }}
|
||||||
|
viewport={{ once: true }}
|
||||||
|
transition={{ duration: 0.5, delay: i * 0.1 }}
|
||||||
|
>
|
||||||
|
<div className={styles.fIcon}>{feature.icon}</div>
|
||||||
|
<h3>{feature.title}</h3>
|
||||||
|
<p>{feature.desc}</p>
|
||||||
|
</motion.div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</motion.div>
|
||||||
|
<motion.div
|
||||||
|
className={styles.overviewImage}
|
||||||
|
initial={{ opacity: 0, scale: 0.95 }}
|
||||||
|
whileInView={{ opacity: 1, scale: 1 }}
|
||||||
|
viewport={{ once: true }}
|
||||||
|
transition={{ duration: 0.8 }}
|
||||||
|
>
|
||||||
|
<Image src="/ecu_kpro.png" alt="KPro Daughterboard" width={600} height={600} className={styles.hwImg} />
|
||||||
|
<div className={styles.imageOverlay}></div>
|
||||||
|
</motion.div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
{/* 3. ADVANCED FEATURES (SUBSCRIPTION) */}
|
||||||
|
<section className={styles.advanced}>
|
||||||
|
<div className={styles.container}>
|
||||||
|
<motion.div
|
||||||
|
className={styles.advHeader}
|
||||||
|
initial={{ opacity: 0, y: 20 }}
|
||||||
|
whileInView={{ opacity: 1, y: 0 }}
|
||||||
|
viewport={{ once: true }}
|
||||||
|
>
|
||||||
|
<p>REV.4 EXCLUSIVE FEATURES</p>
|
||||||
|
<h2>ADVANCED ENGINE <span className={styles.red}>MANAGEMENT</span></h2>
|
||||||
|
</motion.div>
|
||||||
|
<div className={styles.advGrid}>
|
||||||
|
{advancedFeatures.map((adv, i) => (
|
||||||
|
<motion.div
|
||||||
|
key={i}
|
||||||
|
className={`
|
||||||
|
${styles.advCard}
|
||||||
|
${i === 0 ? styles.advCardWide : ''}
|
||||||
|
${i === 4 ? styles.advCardWide : ''}
|
||||||
|
${i === 1 ? styles.advCardTall : ''}
|
||||||
|
`}
|
||||||
|
initial={{ opacity: 0, scale: 0.95 }}
|
||||||
|
whileInView={{ opacity: 1, scale: 1 }}
|
||||||
|
viewport={{ once: true }}
|
||||||
|
transition={{ duration: 0.5, delay: i * 0.1 }}
|
||||||
|
>
|
||||||
|
<div className={styles.cardImage}>
|
||||||
|
<Image
|
||||||
|
src={adv.image}
|
||||||
|
alt={adv.title}
|
||||||
|
fill
|
||||||
|
className={styles.advImg}
|
||||||
|
sizes="(max-width: 768px) 100vw, 50vw"
|
||||||
|
/>
|
||||||
|
<div className={styles.cardOverlay}></div>
|
||||||
|
</div>
|
||||||
|
<div className={styles.cardContent}>
|
||||||
|
<h3>{adv.title}</h3>
|
||||||
|
<p>{adv.desc}</p>
|
||||||
|
</div>
|
||||||
|
</motion.div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
{/* 4. COMPATIBILITY */}
|
||||||
|
<section className={styles.compatibility}>
|
||||||
|
<div className={styles.container}>
|
||||||
|
<div className={styles.compGrid}>
|
||||||
|
<motion.div
|
||||||
|
className={styles.compBox}
|
||||||
|
initial={{ opacity: 0, x: -30 }}
|
||||||
|
whileInView={{ opacity: 1, x: 0 }}
|
||||||
|
viewport={{ once: true }}
|
||||||
|
>
|
||||||
|
<h2>FACTORY EQUIPPED</h2>
|
||||||
|
<div className={styles.vList}>
|
||||||
|
{factoryModels.map((m, i) => (
|
||||||
|
<div key={i} className={styles.vItem}>
|
||||||
|
<span>{m.name}</span>
|
||||||
|
<span className={styles.vTag}>{m.years}</span>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</motion.div>
|
||||||
|
<motion.div
|
||||||
|
className={styles.compBox}
|
||||||
|
initial={{ opacity: 0, x: 30 }}
|
||||||
|
whileInView={{ opacity: 1, x: 0 }}
|
||||||
|
viewport={{ once: true }}
|
||||||
|
>
|
||||||
|
<h2>ECU MODIFICATION REQUIRED</h2>
|
||||||
|
<div className={styles.vList}>
|
||||||
|
{replacementModels.map((m, i) => (
|
||||||
|
<div key={i} className={styles.vItem}>
|
||||||
|
<span>{m.name}</span>
|
||||||
|
<span className={styles.vTag}>{m.years}</span>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
<div style={{ marginTop: '2rem', display: 'flex', gap: '1rem', color: '#ff4444', fontSize: '0.75rem' }}>
|
||||||
|
<AlertTriangle size={16} />
|
||||||
|
<p>OEM ECUs in these vehicles are not directly compatible. Replacement with a supported ECU is required.</p>
|
||||||
|
</div>
|
||||||
|
</motion.div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<motion.div
|
||||||
|
style={{ marginTop: '4rem', padding: '3rem', backgroundColor: 'var(--secondary)', borderRadius: '4px', border: '1px solid var(--border)' }}
|
||||||
|
initial={{ opacity: 0, y: 30 }}
|
||||||
|
whileInView={{ opacity: 1, y: 0 }}
|
||||||
|
viewport={{ once: true }}
|
||||||
|
>
|
||||||
|
<h3 style={{ fontSize: '1rem', marginBottom: '1.5rem', fontWeight: 900 }}>SUPPORTED ECU ARCHITECTURE</h3>
|
||||||
|
<div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(200px, 1fr))', gap: '2rem' }}>
|
||||||
|
{ecuRevisions.map((rev, i) => (
|
||||||
|
<div key={i} style={{ padding: '1.5rem', border: '1px solid var(--border)', borderRadius: '4px' }}>
|
||||||
|
<p style={{ fontSize: '0.65rem', color: '#555', fontWeight: 800, marginBottom: '0.5rem' }}>BOARD REVISION</p>
|
||||||
|
<p style={{ fontFamily: 'monospace', fontWeight: 900, fontSize: '1.1rem' }}>{rev.name}</p>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</motion.div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
{/* 5. TECH SUITE / INSTALLATION */}
|
||||||
|
<section ref={guidesRef} className={styles.techSuite}>
|
||||||
|
<div className={styles.container}>
|
||||||
|
<motion.div
|
||||||
|
className={styles.techHeader}
|
||||||
|
initial={{ opacity: 0, y: 30 }}
|
||||||
|
whileInView={{ opacity: 1, y: 0 }}
|
||||||
|
viewport={{ once: true }}
|
||||||
|
>
|
||||||
|
<h2>TECHNICAL <span className={styles.red}>INTELLIGENCE</span></h2>
|
||||||
|
</motion.div>
|
||||||
|
|
||||||
|
<div className={styles.guideGrid}>
|
||||||
|
<motion.div
|
||||||
|
className={styles.guideCard}
|
||||||
|
initial={{ opacity: 0, scale: 0.9 }}
|
||||||
|
whileInView={{ opacity: 1, scale: 1 }}
|
||||||
|
viewport={{ once: true }}
|
||||||
|
>
|
||||||
|
<div className={styles.cardBg}>
|
||||||
|
<Image src="https://images.unsplash.com/photo-1518770660439-4636190af475?q=80&w=1200" alt="Installation" fill className={styles.bgImg} />
|
||||||
|
<div className={styles.cardOverlay}></div>
|
||||||
|
</div>
|
||||||
|
<div className={styles.guideContent}>
|
||||||
|
<div className={styles.guideIconBox}><Settings size={32} /></div>
|
||||||
|
<h3>Hardware Installation</h3>
|
||||||
|
<p>Comprehensive step-by-step soldering and seating guide for the KPro daughterboard onto your ECU PCB.</p>
|
||||||
|
<button className={styles.guideBtn}>VIEW INSTALL GUIDE</button>
|
||||||
|
</div>
|
||||||
|
</motion.div>
|
||||||
|
|
||||||
|
<motion.div
|
||||||
|
className={styles.guideCard}
|
||||||
|
initial={{ opacity: 0, scale: 0.9 }}
|
||||||
|
whileInView={{ opacity: 1, scale: 1 }}
|
||||||
|
viewport={{ once: true }}
|
||||||
|
transition={{ delay: 0.1 }}
|
||||||
|
>
|
||||||
|
<div className={styles.cardBg}>
|
||||||
|
<Image src="https://images.unsplash.com/photo-1695653422718-97d25c1cb8ec?q=80&w=1200" alt="Bluetooth" fill className={styles.bgImg} />
|
||||||
|
<div className={styles.cardOverlay}></div>
|
||||||
|
</div>
|
||||||
|
<div className={styles.guideContent}>
|
||||||
|
<div className={styles.guideIconBox}><Bluetooth size={32} /></div>
|
||||||
|
<h3>Bluetooth Config</h3>
|
||||||
|
<p>Wireless connection protocols, pairing procedures, and list of compatible mobile tuning applications.</p>
|
||||||
|
<button className={styles.guideBtn}>CONNECTION GUIDE</button>
|
||||||
|
</div>
|
||||||
|
</motion.div>
|
||||||
|
|
||||||
|
<motion.div
|
||||||
|
className={styles.guideCard}
|
||||||
|
initial={{ opacity: 0, scale: 0.9 }}
|
||||||
|
whileInView={{ opacity: 1, scale: 1 }}
|
||||||
|
viewport={{ once: true }}
|
||||||
|
transition={{ delay: 0.2 }}
|
||||||
|
>
|
||||||
|
<div className={styles.cardBg}>
|
||||||
|
<Image src="https://images.unsplash.com/photo-1550751827-4bd374c3f58b?q=80&w=1200" alt="LED Indicators" fill className={styles.bgImg} />
|
||||||
|
<div className={styles.cardOverlay}></div>
|
||||||
|
</div>
|
||||||
|
<div className={styles.guideContent}>
|
||||||
|
<div className={styles.guideIconBox}><Activity size={32} /></div>
|
||||||
|
<h3>Board LEDs Meaning</h3>
|
||||||
|
<p>Decipher onboard DIAG LED patterns for rapid troubleshooting and system status verification.</p>
|
||||||
|
<button className={styles.guideBtn}>DIAGNOSTIC KEYS</button>
|
||||||
|
</div>
|
||||||
|
</motion.div>
|
||||||
|
|
||||||
|
<motion.div
|
||||||
|
className={styles.guideCard}
|
||||||
|
initial={{ opacity: 0, scale: 0.9 }}
|
||||||
|
whileInView={{ opacity: 1, scale: 1 }}
|
||||||
|
viewport={{ once: true }}
|
||||||
|
transition={{ delay: 0.3 }}
|
||||||
|
>
|
||||||
|
<div className={styles.cardBg}>
|
||||||
|
<Image src="https://images.unsplash.com/photo-1555664424-778a1e5e1b48?q=80&w=1200" alt="ECU Pinout" fill className={styles.bgImg} />
|
||||||
|
<div className={styles.cardOverlay}></div>
|
||||||
|
</div>
|
||||||
|
<div className={styles.guideContent}>
|
||||||
|
<div className={styles.guideIconBox}><Cpu size={32} /></div>
|
||||||
|
<h3>ECU Pinout</h3>
|
||||||
|
<p>Detailed technical mapping of all ECU connectors, sensor inputs, and programmable output pins.</p>
|
||||||
|
<button className={styles.guideBtn}>VIEW PINOUT MAP</button>
|
||||||
|
</div>
|
||||||
|
</motion.div>
|
||||||
|
|
||||||
|
<motion.div
|
||||||
|
className={styles.guideCard}
|
||||||
|
initial={{ opacity: 0, scale: 0.9 }}
|
||||||
|
whileInView={{ opacity: 1, scale: 1 }}
|
||||||
|
viewport={{ once: true }}
|
||||||
|
transition={{ delay: 0.4 }}
|
||||||
|
>
|
||||||
|
<div className={styles.cardBg}>
|
||||||
|
<Image src="https://images.unsplash.com/photo-1549411210-613d9061df8d?q=80&w=1200" alt="O2 Sensors" fill className={styles.bgImg} />
|
||||||
|
<div className={styles.cardOverlay}></div>
|
||||||
|
</div>
|
||||||
|
<div className={styles.guideContent}>
|
||||||
|
<div className={styles.guideIconBox}><Zap size={32} /></div>
|
||||||
|
<h3>O2 Sensor Types</h3>
|
||||||
|
<p>In-depth analysis of PRA vs PRB sensor differences, compatibility notes, and custom wiring diagrams.</p>
|
||||||
|
<button className={styles.guideBtn}>WIRING DIAGRAMS</button>
|
||||||
|
</div>
|
||||||
|
</motion.div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
{/* 6. DOWNLOADS & SOFTWARE HUB */}
|
||||||
|
<section ref={downloadRef} className={styles.downloads}>
|
||||||
|
<div className={styles.container}>
|
||||||
|
<motion.div
|
||||||
|
className={styles.dlHeader}
|
||||||
|
initial={{ opacity: 0, y: 30 }}
|
||||||
|
whileInView={{ opacity: 1, y: 0 }}
|
||||||
|
viewport={{ once: true }}
|
||||||
|
>
|
||||||
|
<h2>SOFTWARE <span className={styles.red}>HUB</span></h2>
|
||||||
|
</motion.div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<div className={styles.dlDashboard}>
|
||||||
|
<motion.div
|
||||||
|
className={styles.dlCard}
|
||||||
|
initial={{ opacity: 0, scale: 0.95 }}
|
||||||
|
whileInView={{ opacity: 1, scale: 1 }}
|
||||||
|
viewport={{ once: true }}
|
||||||
|
>
|
||||||
|
<div className={styles.dlIconBox}><ShieldAlert size={32} /></div>
|
||||||
|
<h3>Security & Tools</h3>
|
||||||
|
<p>False virus detections may occur. If you have trouble downloading, temporarily disable your antivirus and Windows Defender.</p>
|
||||||
|
|
||||||
|
<div className={styles.passwordBox} style={{ marginTop: 'auto' }}>
|
||||||
|
<span>Archive Password</span>
|
||||||
|
<div className={styles.passKey}>1234</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<p style={{ marginTop: '1.5rem', fontSize: '0.65rem' }}>
|
||||||
|
* Extract with <a href="https://www.rarlab.com/download.htm" target="_blank" rel="noopener noreferrer" style={{ color: 'var(--primary)', fontWeight: 800, textDecoration: 'underline' }}>WinRAR</a> or <a href="https://www.7-zip.org/" target="_blank" rel="noopener noreferrer" style={{ color: 'var(--primary)', fontWeight: 800, textDecoration: 'underline' }}>7-Zip</a> for best results.
|
||||||
|
</p>
|
||||||
|
</motion.div>
|
||||||
|
|
||||||
|
<motion.div
|
||||||
|
className={styles.dlCard}
|
||||||
|
initial={{ opacity: 0, scale: 0.95 }}
|
||||||
|
whileInView={{ opacity: 1, scale: 1 }}
|
||||||
|
viewport={{ once: true }}
|
||||||
|
transition={{ delay: 0.1 }}
|
||||||
|
>
|
||||||
|
<div className={styles.dlIconBox}><Settings size={32} /></div>
|
||||||
|
<h3>KPro Manager</h3>
|
||||||
|
<p>Get Latest KPro Manager + Service Utility Securely. Standard installation package for all K-Series platforms.</p>
|
||||||
|
|
||||||
|
<span className={styles.dlVersion} style={{ marginTop: 'auto' }}>V4.5.6 STABLE</span>
|
||||||
|
|
||||||
|
<a
|
||||||
|
href="/files/KProSetup.rar"
|
||||||
|
className={styles.dlBtn}
|
||||||
|
download
|
||||||
|
>
|
||||||
|
<Download size={18} />
|
||||||
|
DOWNLOAD INSTALLER
|
||||||
|
</a>
|
||||||
|
</motion.div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
|
||||||
|
}
|
||||||
179
src/components/MapSensor.module.css
Normal file
@ -0,0 +1,179 @@
|
|||||||
|
.wrapper {
|
||||||
|
background-color: var(--neutral);
|
||||||
|
min-height: 100vh;
|
||||||
|
}
|
||||||
|
|
||||||
|
.container {
|
||||||
|
max-width: 1400px;
|
||||||
|
width: 100%;
|
||||||
|
margin: 0 auto;
|
||||||
|
padding: 0 4rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 1. HERO */
|
||||||
|
.hero {
|
||||||
|
position: relative;
|
||||||
|
min-height: 80vh;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
overflow: hidden;
|
||||||
|
padding-top: 100px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bgWrapper {
|
||||||
|
position: absolute;
|
||||||
|
inset: 0;
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.heroImg {
|
||||||
|
object-fit: contain;
|
||||||
|
filter: saturate(0.5) contrast(1.1) brightness(0.6);
|
||||||
|
}
|
||||||
|
|
||||||
|
.heroOverlay {
|
||||||
|
position: absolute;
|
||||||
|
inset: 0;
|
||||||
|
background: linear-gradient(to right, rgba(0,0,0,0.9) 0%, rgba(0,0,0,0.4) 100%);
|
||||||
|
z-index: 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.heroGrid {
|
||||||
|
position: relative;
|
||||||
|
z-index: 3;
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 1.5fr 1fr;
|
||||||
|
gap: 5rem;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.heroLabel {
|
||||||
|
font-size: 0.65rem;
|
||||||
|
font-weight: 900;
|
||||||
|
color: #555;
|
||||||
|
letter-spacing: 0.2rem;
|
||||||
|
display: block;
|
||||||
|
margin-bottom: 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.heroTitle {
|
||||||
|
font-size: clamp(4rem, 8vw, 6.5rem);
|
||||||
|
font-weight: 900;
|
||||||
|
line-height: 0.85;
|
||||||
|
letter-spacing: -0.05em;
|
||||||
|
margin-bottom: 2.5rem;
|
||||||
|
text-transform: uppercase;
|
||||||
|
}
|
||||||
|
|
||||||
|
.red { color: var(--primary); font-style: italic; }
|
||||||
|
|
||||||
|
.heroDesc {
|
||||||
|
font-size: 1.1rem;
|
||||||
|
color: #888;
|
||||||
|
line-height: 1.6;
|
||||||
|
margin-bottom: 3.5rem;
|
||||||
|
max-width: 600px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.heroActions { display: flex; gap: 1rem; }
|
||||||
|
|
||||||
|
.primaryBtn {
|
||||||
|
background-color: var(--primary);
|
||||||
|
padding: 1.2rem 2.2rem;
|
||||||
|
border-radius: 4px;
|
||||||
|
font-size: 0.7rem;
|
||||||
|
font-weight: 900;
|
||||||
|
letter-spacing: 0.1em;
|
||||||
|
color: #fff;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 1.2rem;
|
||||||
|
cursor: pointer;
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.secondaryBtn {
|
||||||
|
background-color: rgba(255, 255, 255, 0.02);
|
||||||
|
border: 1px solid var(--border);
|
||||||
|
padding: 1.2rem 2.2rem;
|
||||||
|
border-radius: 4px;
|
||||||
|
font-size: 0.7rem;
|
||||||
|
font-weight: 900;
|
||||||
|
letter-spacing: 0.1em;
|
||||||
|
color: #fff;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 1.2rem;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.specBox {
|
||||||
|
background-color: rgba(18, 18, 18, 0.4);
|
||||||
|
border: 1px solid rgba(255, 255, 255, 0.05);
|
||||||
|
backdrop-filter: blur(10px);
|
||||||
|
padding: 3rem;
|
||||||
|
width: 100%;
|
||||||
|
max-width: 400px;
|
||||||
|
border-radius: 4px;
|
||||||
|
position: relative;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.progressLine {
|
||||||
|
position: absolute;
|
||||||
|
top: 0; left: 0; width: 60%;
|
||||||
|
height: 2px;
|
||||||
|
background-color: var(--primary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.specItem { margin-bottom: 2.5rem; }
|
||||||
|
.specItem:last-child { margin-bottom: 0; }
|
||||||
|
|
||||||
|
.specLabel {
|
||||||
|
font-size: 0.55rem;
|
||||||
|
font-weight: 900;
|
||||||
|
color: #444;
|
||||||
|
letter-spacing: 0.1em;
|
||||||
|
display: block;
|
||||||
|
margin-bottom: 0.8rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.specItem h3 { font-size: 1.3rem; font-weight: 900; font-style: italic; }
|
||||||
|
|
||||||
|
/* 2. OVERVIEW */
|
||||||
|
.overview { padding: 120px 0; background-color: var(--neutral); }
|
||||||
|
.overviewGrid { display: grid; grid-template-columns: 1fr 1fr; gap: 8rem; align-items: center; }
|
||||||
|
.overviewContent h2 { font-size: 3rem; font-weight: 900; letter-spacing: -0.05em; margin-bottom: 3rem; line-height: 0.9; text-transform: uppercase; }
|
||||||
|
.featuresGrid { display: grid; grid-template-columns: 1fr 1fr; gap: 3rem 4rem; }
|
||||||
|
|
||||||
|
.featureItem { display: flex; flex-direction: column; gap: 1.2rem; }
|
||||||
|
.fIcon { width: 32px; height: 32px; color: var(--primary); }
|
||||||
|
.featureItem h3 { font-size: 0.85rem; font-weight: 900; text-transform: uppercase; letter-spacing: 0.1em; }
|
||||||
|
.featureItem p { font-size: 0.75rem; color: #777; line-height: 1.5; font-weight: 500; }
|
||||||
|
|
||||||
|
.hwImg { width: 100%; height: auto; border-radius: 4px; filter: saturate(0.8) contrast(1.1); }
|
||||||
|
|
||||||
|
/* 3. CALIBRATION (COMPATIBILITY FORMAT) */
|
||||||
|
.calibration { padding: 120px 0; background-color: var(--secondary); border-top: 1px solid var(--border); border-bottom: 1px solid var(--border); }
|
||||||
|
.compGrid { display: grid; grid-template-columns: 1fr 1.3fr; gap: 4rem; align-items: start; }
|
||||||
|
.compBox { background-color: var(--neutral); border: 1px solid var(--border); padding: 4rem; border-radius: 4px; width: 100%; height: 100%; }
|
||||||
|
.compBox h2 { font-size: 1.2rem; font-weight: 900; margin-bottom: 3.5rem; border-bottom: 1px solid var(--border); padding-bottom: 1.2rem; letter-spacing: 0.05em; text-align: center; }
|
||||||
|
|
||||||
|
.graphContainer { width: 100%; display: flex; align-items: center; justify-content: center; background-color: #fff; padding: 1.5rem; border-radius: 4px; border: 1px solid rgba(255,255,255,0.1); }
|
||||||
|
.graphImg { width: 100%; height: auto; object-fit: contain; }
|
||||||
|
|
||||||
|
.vList { display: flex; flex-direction: column; gap: 1.5rem; margin-bottom: 3rem; }
|
||||||
|
.vItem { display: flex; justify-content: space-between; font-size: 1rem; padding-bottom: 1rem; border-bottom: 1px solid rgba(255, 255, 255, 0.03); align-items: center; }
|
||||||
|
.vTag { font-family: monospace; color: var(--primary); font-weight: 900; font-size: 1.5rem; text-transform: uppercase; }
|
||||||
|
|
||||||
|
.note { display: flex; gap: 1rem; color: var(--primary); font-size: 0.85rem; margin-top: 2rem; font-weight: 700; opacity: 0.8; line-height: 1.6; }
|
||||||
|
|
||||||
|
.ecuSupported { margin-top: 2.5rem; background-color: rgba(255,255,255,0.02); padding: 2rem; border-radius: 4px; border: 1px solid var(--border); text-align: center; }
|
||||||
|
.ecuRow { display: flex; flex-direction: column; gap: 1rem; }
|
||||||
|
.ecuRegion { font-size: 0.75rem; font-weight: 900; color: var(--primary); letter-spacing: 0.1em; }
|
||||||
|
.ecuVer { font-size: 0.9rem; color: #bbb; line-height: 1.6; }
|
||||||
|
|
||||||
|
@media (max-width: 1024px) {
|
||||||
|
.heroGrid, .overviewGrid { grid-template-columns: 1fr; gap: 4rem; }
|
||||||
|
.featuresGrid { grid-template-columns: 1fr; }
|
||||||
|
}
|
||||||
166
src/components/MapSensor.tsx
Normal file
@ -0,0 +1,166 @@
|
|||||||
|
'use client';
|
||||||
|
|
||||||
|
import { motion } from 'framer-motion';
|
||||||
|
import Image from 'next/image';
|
||||||
|
import {
|
||||||
|
Info,
|
||||||
|
Activity,
|
||||||
|
Settings,
|
||||||
|
Gauge,
|
||||||
|
Zap,
|
||||||
|
CheckCircle,
|
||||||
|
Database
|
||||||
|
} from 'lucide-react';
|
||||||
|
import { useRef } from 'react';
|
||||||
|
import styles from './MapSensor.module.css';
|
||||||
|
|
||||||
|
export default function MapSensor() {
|
||||||
|
|
||||||
|
const infoRef = useRef<HTMLElement>(null);
|
||||||
|
const specsRef = useRef<HTMLElement>(null);
|
||||||
|
|
||||||
|
const scrollToSection = (ref: React.RefObject<HTMLElement | null>) => {
|
||||||
|
if (ref.current) {
|
||||||
|
ref.current.scrollIntoView({ behavior: 'smooth' });
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const coreFeatures = [
|
||||||
|
{ title: 'Direct Plug & Play', desc: 'Installs securely in under 60 seconds. Completely eliminates risky custom wiring splices.', icon: <CheckCircle size={24} /> },
|
||||||
|
{ title: '4-Bar Pressure Limit', desc: 'Reads vacuum to upwards of 43+ PSI of boost precisely across the curve.', icon: <Gauge size={24} /> },
|
||||||
|
{ title: 'Linear Calibration', desc: 'Exceptional linear voltage scaling ensures tuning stability under high output.', icon: <Activity size={24} /> },
|
||||||
|
{ title: 'B-D-F-H Series Fitment', desc: 'Bolts directly to the B/D/F/H-series proprietary factory throttle bodies.', icon: <Settings size={24} /> },
|
||||||
|
{ title: 'K-Series Fitment', desc: 'Available in specifically engineered K-series intake manifold form factors.', icon: <Zap size={24} /> },
|
||||||
|
{ title: 'Data Resolution', desc: 'High-speed transducer delivers robust feedback for ECU closed-loop processes.', icon: <Database size={24} /> },
|
||||||
|
];
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className={styles.wrapper}>
|
||||||
|
{/* 1. HERO SECTION */}
|
||||||
|
<section className={styles.hero}>
|
||||||
|
<div className={styles.bgWrapper}>
|
||||||
|
<Image src="/map_sensor.png" alt="MAP Sensor Hero" fill className={styles.heroImg} priority />
|
||||||
|
</div>
|
||||||
|
<div className={styles.heroOverlay}></div>
|
||||||
|
<div className={styles.container}>
|
||||||
|
<div className={styles.heroGrid}>
|
||||||
|
<motion.div
|
||||||
|
className={styles.heroContent}
|
||||||
|
initial={{ opacity: 0, x: -50 }}
|
||||||
|
animate={{ opacity: 1, x: 0 }}
|
||||||
|
transition={{ duration: 0.8 }}
|
||||||
|
>
|
||||||
|
<span className={styles.heroLabel}>PLUG-COMPATIBLE ENGINE SENSOR</span>
|
||||||
|
<h1 className={styles.heroTitle}>
|
||||||
|
4-BAR <span className={styles.red}>MAP</span>
|
||||||
|
</h1>
|
||||||
|
<p className={styles.heroDesc}>
|
||||||
|
The HondaVert 4 bar MAP sensor is a direct-fit replacement engineered for
|
||||||
|
B, D, H, F, and K-series engines. Safely and accurately measure up to 43+ PSI of boost.
|
||||||
|
</p>
|
||||||
|
<div className={styles.heroActions}>
|
||||||
|
<button className={styles.primaryBtn} onClick={() => scrollToSection(infoRef)}>
|
||||||
|
<Info size={18} />
|
||||||
|
<span>INFORMATION</span>
|
||||||
|
</button>
|
||||||
|
<button className={styles.secondaryBtn} onClick={() => scrollToSection(specsRef)}>
|
||||||
|
<Settings size={18} />
|
||||||
|
<span>CALIBRATION DATA</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</motion.div>
|
||||||
|
|
||||||
|
<motion.div
|
||||||
|
className={styles.heroSpecs}
|
||||||
|
initial={{ opacity: 0, x: 50 }}
|
||||||
|
animate={{ opacity: 1, x: 0 }}
|
||||||
|
transition={{ duration: 0.8, delay: 0.2 }}
|
||||||
|
>
|
||||||
|
<div className={styles.specBox}>
|
||||||
|
<div className={styles.progressLine}></div>
|
||||||
|
<div className={styles.specItem}>
|
||||||
|
<span className={styles.specLabel}>PLATFORM SUPPORT</span>
|
||||||
|
<h3>B/D/F/H & K SERIES</h3>
|
||||||
|
</div>
|
||||||
|
<div className={styles.specItem}>
|
||||||
|
<span className={styles.specLabel}>MAXIMUM PRESSURE</span>
|
||||||
|
<h3>4 BAR (43.5 PSI)</h3>
|
||||||
|
</div>
|
||||||
|
<div className={styles.specItem}>
|
||||||
|
<span className={styles.specLabel}>INSTALLATION</span>
|
||||||
|
<h3>PLUG & PLAY - NO WIRING</h3>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</motion.div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
{/* 2. CORE CAPABILITIES */}
|
||||||
|
<section className={styles.overview} ref={infoRef}>
|
||||||
|
<div className={styles.container}>
|
||||||
|
<div className={styles.overviewGrid}>
|
||||||
|
<motion.div
|
||||||
|
className={styles.overviewContent}
|
||||||
|
initial={{ opacity: 0, y: 30 }}
|
||||||
|
whileInView={{ opacity: 1, y: 0 }}
|
||||||
|
viewport={{ once: true }}
|
||||||
|
>
|
||||||
|
<h2>HARDWARE <br /><span className={styles.red}>INTEGRATION</span></h2>
|
||||||
|
<div className={styles.featuresGrid}>
|
||||||
|
{coreFeatures.map((feature, i) => (
|
||||||
|
<div key={i} className={styles.featureItem}>
|
||||||
|
<div className={styles.fIcon}>{feature.icon}</div>
|
||||||
|
<h3>{feature.title}</h3>
|
||||||
|
<p>{feature.desc}</p>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</motion.div>
|
||||||
|
<div className={styles.overviewImage}>
|
||||||
|
<Image src="/map_sensor.png" width={600} height={500} alt="4 Bar MAP Sensor Hardware" className={styles.hwImg} />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
{/* 3. CALIBRATION DATA */}
|
||||||
|
<section className={styles.calibration} ref={specsRef}>
|
||||||
|
<div className={styles.container}>
|
||||||
|
<div className={styles.compGrid}>
|
||||||
|
<div className={styles.compBox}>
|
||||||
|
<h2>ECU CALIBRATION CHARACTERISTICS</h2>
|
||||||
|
<div className={styles.vList}>
|
||||||
|
<div className={styles.vItem}>
|
||||||
|
<span style={{color: '#fff'}}>Required Scalar Value</span>
|
||||||
|
<span className={styles.vTag}>838</span>
|
||||||
|
</div>
|
||||||
|
<div className={styles.vItem}>
|
||||||
|
<span style={{color: '#fff'}}>Required Offset Value</span>
|
||||||
|
<span className={styles.vTag}>31</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className={styles.note}>
|
||||||
|
<Activity size={16} />
|
||||||
|
<p>Ensure these values are accurately entered into your engine management software to guarantee precise output vs absolute pressure scaling.</p>
|
||||||
|
</div>
|
||||||
|
<div className={styles.ecuSupported}>
|
||||||
|
<div className={styles.ecuRow}>
|
||||||
|
<span className={styles.ecuRegion}>SOFTWARE COMPATIBILITY</span>
|
||||||
|
<span className={styles.ecuVer}>Native support within Hondata, KPro, PreCAN, CANFlash, and S300 Manager. Select "HondaVert 4-Bar" or input the scalar/offset manually.</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className={styles.compBox}>
|
||||||
|
<h2>OUTPUT VS ABSOLUTE PRESSURE</h2>
|
||||||
|
<div className={styles.graphContainer}>
|
||||||
|
<Image src="/map_graph.png" alt="MAP Sensor Transfer Function Graph" width={600} height={400} className={styles.graphImg} />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
174
src/components/Navbar.module.css
Normal file
@ -0,0 +1,174 @@
|
|||||||
|
.nav {
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 80px;
|
||||||
|
background-color: rgba(18, 18, 18, 0.85);
|
||||||
|
backdrop-filter: blur(10px);
|
||||||
|
border-bottom: 1px solid rgba(255, 0, 0, 0.1);
|
||||||
|
z-index: 1000;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.container {
|
||||||
|
max-width: 1400px;
|
||||||
|
width: 100%;
|
||||||
|
margin: 0 auto;
|
||||||
|
padding: 0 2rem;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.logoImg {
|
||||||
|
display: block;
|
||||||
|
object-fit: contain;
|
||||||
|
filter: brightness(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.links {
|
||||||
|
display: flex;
|
||||||
|
gap: 2.5rem;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.navItemDropdown {
|
||||||
|
position: relative;
|
||||||
|
height: 80px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.chevron {
|
||||||
|
margin-left: 0.5rem;
|
||||||
|
transition: transform 0.2s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.navItemDropdown:hover .chevron {
|
||||||
|
transform: rotate(180deg);
|
||||||
|
color: var(--primary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.navItemDropdown > a {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.links > a, .navItemDropdown > a {
|
||||||
|
font-size: 0.75rem;
|
||||||
|
font-weight: 800;
|
||||||
|
color: #888;
|
||||||
|
letter-spacing: 0.1em;
|
||||||
|
transition: color 0.2s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.links > a:hover, .navItemDropdown > a:hover {
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.links a.active {
|
||||||
|
color: var(--primary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.submenu {
|
||||||
|
position: absolute;
|
||||||
|
top: 100%;
|
||||||
|
left: -20px;
|
||||||
|
background-color: var(--secondary);
|
||||||
|
border: 1px solid var(--border);
|
||||||
|
border-top: 2px solid var(--primary);
|
||||||
|
border-radius: 4px;
|
||||||
|
padding: 1.5rem;
|
||||||
|
width: 450px;
|
||||||
|
opacity: 0;
|
||||||
|
visibility: hidden;
|
||||||
|
transform: translateY(-10px);
|
||||||
|
transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);
|
||||||
|
box-shadow: 0 10px 40px rgba(0, 0, 0, 0.8);
|
||||||
|
}
|
||||||
|
|
||||||
|
.navItemDropdown:hover .submenu {
|
||||||
|
opacity: 1;
|
||||||
|
visibility: visible;
|
||||||
|
transform: translateY(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
.submenuGrid {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 1fr 1fr;
|
||||||
|
gap: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.submenuItem {
|
||||||
|
display: flex;
|
||||||
|
gap: 1.2rem;
|
||||||
|
align-items: center;
|
||||||
|
padding: 1rem;
|
||||||
|
border-radius: 4px;
|
||||||
|
transition: background-color 0.2s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.submenuItem:hover {
|
||||||
|
background-color: var(--neutral);
|
||||||
|
}
|
||||||
|
|
||||||
|
.submenuIcon {
|
||||||
|
width: 32px;
|
||||||
|
height: 32px;
|
||||||
|
background-color: var(--neutral);
|
||||||
|
border: 1px solid var(--border);
|
||||||
|
border-radius: 4px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
color: var(--primary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.submenuItem:hover .submenuIcon {
|
||||||
|
border-color: var(--primary);
|
||||||
|
background-color: #000;
|
||||||
|
}
|
||||||
|
|
||||||
|
.submenuContent {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
.submenuTitle {
|
||||||
|
font-size: 0.85rem;
|
||||||
|
font-weight: 900;
|
||||||
|
color: #fff;
|
||||||
|
letter-spacing: -0.01em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.submenuSubtitle {
|
||||||
|
font-size: 0.65rem;
|
||||||
|
color: #555;
|
||||||
|
font-weight: 800;
|
||||||
|
letter-spacing: 0.05em;
|
||||||
|
text-transform: uppercase;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tuningBtn {
|
||||||
|
background-color: var(--primary);
|
||||||
|
color: white;
|
||||||
|
padding: 0.7rem 1.6rem;
|
||||||
|
border-radius: 4px;
|
||||||
|
font-size: 0.75rem;
|
||||||
|
font-weight: 900;
|
||||||
|
letter-spacing: 0.1em;
|
||||||
|
transition: background-color 0.2s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tuningBtn:hover {
|
||||||
|
background-color: var(--primary-hover);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@media (max-width: 1024px) {
|
||||||
|
.links {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
59
src/components/Navbar.tsx
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
'use client';
|
||||||
|
|
||||||
|
import Link from 'next/link';
|
||||||
|
import Image from 'next/image';
|
||||||
|
import { ChevronDown, Cpu, Zap, Activity, Gauge, Settings } from 'lucide-react';
|
||||||
|
import { products } from '@/lib/products';
|
||||||
|
import styles from './Navbar.module.css';
|
||||||
|
|
||||||
|
const icons = {
|
||||||
|
'kpro': <Cpu size={16} />,
|
||||||
|
'canflash': <Zap size={16} />,
|
||||||
|
'precan': <Activity size={16} />,
|
||||||
|
's300': <Gauge size={16} />,
|
||||||
|
'map-sensor': <Settings size={16} />
|
||||||
|
};
|
||||||
|
|
||||||
|
export default function Navbar() {
|
||||||
|
return (
|
||||||
|
<nav className={styles.nav}>
|
||||||
|
<div className={styles.container}>
|
||||||
|
<div className={styles.logo}>
|
||||||
|
<Link href="/">
|
||||||
|
<Image src="/hondavert_logo.png" alt="HondaVert" width={140} height={40} className={styles.logoImg} priority />
|
||||||
|
</Link>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className={styles.links}>
|
||||||
|
<Link href="/about">ABOUT</Link>
|
||||||
|
<div className={styles.navItemDropdown}>
|
||||||
|
<Link href="/products" className={styles.active}>
|
||||||
|
PRODUCTS <ChevronDown size={14} className={styles.chevron} />
|
||||||
|
</Link>
|
||||||
|
<div className={styles.submenu}>
|
||||||
|
<div className={styles.submenuGrid}>
|
||||||
|
{products.map((product) => (
|
||||||
|
<Link key={product.id} href={`/products/${product.id}`} className={styles.submenuItem}>
|
||||||
|
<div className={styles.submenuIcon}>
|
||||||
|
{icons[product.id as keyof typeof icons] || <Cpu size={16}/>}
|
||||||
|
</div>
|
||||||
|
<div className={styles.submenuContent}>
|
||||||
|
<span className={styles.submenuTitle}>{product.name}</span>
|
||||||
|
<span className={styles.submenuSubtitle}>{product.subtitle}</span>
|
||||||
|
</div>
|
||||||
|
</Link>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<Link href="/blog">BLOG</Link>
|
||||||
|
<Link href="/contact">CONTACT</Link>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className={styles.actions}>
|
||||||
|
<button className={styles.tuningBtn}>TUNING CONSOLE</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</nav>
|
||||||
|
);
|
||||||
|
}
|
||||||
218
src/components/PreCAN.module.css
Normal file
@ -0,0 +1,218 @@
|
|||||||
|
.wrapper {
|
||||||
|
background-color: var(--neutral);
|
||||||
|
min-height: 100vh;
|
||||||
|
}
|
||||||
|
|
||||||
|
.container {
|
||||||
|
max-width: 1400px;
|
||||||
|
width: 100%;
|
||||||
|
margin: 0 auto;
|
||||||
|
padding: 0 4rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 1. HERO */
|
||||||
|
.hero {
|
||||||
|
position: relative;
|
||||||
|
min-height: 80vh;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
overflow: hidden;
|
||||||
|
padding-top: 100px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bgWrapper {
|
||||||
|
position: absolute;
|
||||||
|
inset: 0;
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.heroImg {
|
||||||
|
object-fit: cover;
|
||||||
|
filter: saturate(0.2) contrast(1.2) brightness(0.4);
|
||||||
|
}
|
||||||
|
|
||||||
|
.heroOverlay {
|
||||||
|
position: absolute;
|
||||||
|
inset: 0;
|
||||||
|
background: linear-gradient(to bottom, rgba(0,0,0,0.6) 0%, rgba(0,0,0,0.9) 100%);
|
||||||
|
z-index: 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.heroGrid {
|
||||||
|
position: relative;
|
||||||
|
z-index: 3;
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 1.5fr 1fr;
|
||||||
|
gap: 5rem;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.heroLabel {
|
||||||
|
font-size: 0.65rem;
|
||||||
|
font-weight: 900;
|
||||||
|
color: #555;
|
||||||
|
letter-spacing: 0.2rem;
|
||||||
|
display: block;
|
||||||
|
margin-bottom: 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.heroTitle {
|
||||||
|
font-size: clamp(4rem, 8vw, 6.5rem);
|
||||||
|
font-weight: 900;
|
||||||
|
line-height: 0.85;
|
||||||
|
letter-spacing: -0.05em;
|
||||||
|
margin-bottom: 2.5rem;
|
||||||
|
text-transform: uppercase;
|
||||||
|
}
|
||||||
|
|
||||||
|
.red { color: var(--primary); font-style: italic; }
|
||||||
|
|
||||||
|
.heroDesc {
|
||||||
|
font-size: 1.1rem;
|
||||||
|
color: #888;
|
||||||
|
line-height: 1.6;
|
||||||
|
margin-bottom: 3.5rem;
|
||||||
|
max-width: 600px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.heroActions { display: flex; gap: 1rem; }
|
||||||
|
|
||||||
|
.primaryBtn {
|
||||||
|
background-color: var(--primary);
|
||||||
|
padding: 1.2rem 2.2rem;
|
||||||
|
border-radius: 4px;
|
||||||
|
font-size: 0.7rem;
|
||||||
|
font-weight: 900;
|
||||||
|
letter-spacing: 0.1em;
|
||||||
|
color: #fff;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 1.2rem;
|
||||||
|
cursor: pointer;
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.secondaryBtn {
|
||||||
|
background-color: rgba(255, 255, 255, 0.02);
|
||||||
|
border: 1px solid var(--border);
|
||||||
|
padding: 1.2rem 2.2rem;
|
||||||
|
border-radius: 4px;
|
||||||
|
font-size: 0.7rem;
|
||||||
|
font-weight: 900;
|
||||||
|
letter-spacing: 0.1em;
|
||||||
|
color: #fff;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 1.2rem;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.specBox {
|
||||||
|
background-color: rgba(18, 18, 18, 0.4);
|
||||||
|
border: 1px solid rgba(255, 255, 255, 0.05);
|
||||||
|
backdrop-filter: blur(10px);
|
||||||
|
padding: 3rem;
|
||||||
|
width: 100%;
|
||||||
|
max-width: 400px;
|
||||||
|
border-radius: 4px;
|
||||||
|
position: relative;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.progressLine {
|
||||||
|
position: absolute;
|
||||||
|
top: 0; left: 0; width: 60%;
|
||||||
|
height: 2px;
|
||||||
|
background-color: var(--primary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.specItem { margin-bottom: 2.5rem; }
|
||||||
|
.specItem:last-child { margin-bottom: 0; }
|
||||||
|
|
||||||
|
.specLabel {
|
||||||
|
font-size: 0.55rem;
|
||||||
|
font-weight: 900;
|
||||||
|
color: #444;
|
||||||
|
letter-spacing: 0.1em;
|
||||||
|
display: block;
|
||||||
|
margin-bottom: 0.8rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.specItem h3 { font-size: 1.3rem; font-weight: 900; font-style: italic; }
|
||||||
|
|
||||||
|
/* 2. OVERVIEW */
|
||||||
|
.overview { padding: 120px 0; background-color: var(--neutral); }
|
||||||
|
.overviewGrid { display: grid; grid-template-columns: 1fr 1fr; gap: 8rem; align-items: center; }
|
||||||
|
.overviewContent h2 { font-size: 3rem; font-weight: 900; letter-spacing: -0.05em; margin-bottom: 3rem; line-height: 0.9; }
|
||||||
|
.featuresGrid { display: grid; grid-template-columns: 1fr 1fr; gap: 3rem 4rem; }
|
||||||
|
|
||||||
|
.featureItem { display: flex; flex-direction: column; gap: 1.2rem; }
|
||||||
|
.fIcon { width: 32px; height: 32px; color: var(--primary); }
|
||||||
|
.featureItem h3 { font-size: 0.85rem; font-weight: 900; text-transform: uppercase; letter-spacing: 0.1em; }
|
||||||
|
.featureItem p { font-size: 0.75rem; color: #777; line-height: 1.5; font-weight: 500; }
|
||||||
|
|
||||||
|
.hwImg { width: 100%; height: auto; border-radius: 4px; filter: saturate(0.8) contrast(1.1); }
|
||||||
|
|
||||||
|
/* 3. COMPATIBILITY */
|
||||||
|
.compatibility { padding: 120px 0; background-color: var(--secondary); border-top: 1px solid var(--border); border-bottom: 1px solid var(--border); }
|
||||||
|
.compGrid { display: grid; grid-template-columns: 1fr 1fr; gap: 4rem; }
|
||||||
|
.compBox { background-color: var(--neutral); border: 1px solid var(--border); padding: 3rem; border-radius: 4px; }
|
||||||
|
.compBox h2 { font-size: 1.2rem; font-weight: 900; margin-bottom: 2.5rem; border-bottom: 1px solid var(--border); padding-bottom: 1.2rem; letter-spacing: 0.05em; }
|
||||||
|
.vList { display: flex; flex-direction: column; gap: 1rem; }
|
||||||
|
|
||||||
|
.vItem { display: flex; justify-content: space-between; font-size: 0.85rem; padding-bottom: 0.8rem; border-bottom: 1px solid rgba(255, 255, 255, 0.03); }
|
||||||
|
.vTag { font-family: monospace; color: var(--primary); font-weight: 700; text-transform: uppercase; }
|
||||||
|
|
||||||
|
.note { display: flex; gap: 1rem; color: var(--primary); font-size: 0.75rem; margin-top: 2rem; font-weight: 700; opacity: 0.8; }
|
||||||
|
|
||||||
|
/* 4. GUIDES */
|
||||||
|
.guides { padding: 120px 0; background-color: var(--neutral); overflow: hidden; }
|
||||||
|
.sectionHeader { display: flex; justify-content: space-between; align-items: flex-end; margin-bottom: 5rem; }
|
||||||
|
.headerTitle .sub { font-size: 0.65rem; font-weight: 900; color: var(--primary); letter-spacing: 0.2rem; display: block; margin-bottom: 1rem; text-transform: uppercase; }
|
||||||
|
.headerTitle h2 { font-size: 2.5rem; font-weight: 900; margin: 0; line-height: 1; letter-spacing: -0.05em; text-transform: uppercase; }
|
||||||
|
|
||||||
|
.sliderNav { display: flex; gap: 1rem; }
|
||||||
|
.navBtn { width: 50px; height: 50px; border-radius: 50%; background-color: var(--secondary); border: 1px solid var(--border); color: #fff; display: flex; align-items: center; justify-content: center; cursor: pointer; transition: all 0.3s ease; }
|
||||||
|
.navBtn:hover:not(.disabled) { background-color: var(--primary); border-color: var(--primary); }
|
||||||
|
.navBtn.disabled { opacity: 0.3; cursor: not-allowed; }
|
||||||
|
|
||||||
|
.sliderContainer { width: 100%; overflow: hidden; padding: 1rem 0; }
|
||||||
|
.sliderTray { display: grid; grid-auto-flow: column; grid-auto-columns: calc(33.333% - 1.333rem); gap: 2rem; width: 100%; }
|
||||||
|
|
||||||
|
.guideCard { background-color: var(--secondary); border: 1px solid var(--border); padding: 3rem; border-radius: 8px; transition: all 0.3s ease; display: flex; flex-direction: column; gap: 1.5rem; height: 100%; min-height: 350px; }
|
||||||
|
.guideCard:hover { border-color: var(--primary); transform: translateY(-10px); }
|
||||||
|
|
||||||
|
.cardHeader { display: flex; justify-content: space-between; align-items: flex-start; margin-bottom: 1rem; }
|
||||||
|
.iconBox { width: 60px; height: 60px; background-color: rgba(255, 0, 0, 0.05); border: 1px solid rgba(255, 0, 0, 0.1); border-radius: 8px; display: flex; align-items: center; justify-content: center; color: var(--primary); }
|
||||||
|
.cardNum { font-size: 1.5rem; font-weight: 900; color: rgba(255, 255, 255, 0.1); letter-spacing: -0.05em; }
|
||||||
|
|
||||||
|
.guideCard h3 { font-size: 1.2rem; font-weight: 900; line-height: 1.3; margin: 0; letter-spacing: -0.02em; }
|
||||||
|
.guideCard p { font-size: 0.85rem; color: #888; line-height: 1.6; margin: 0; flex-grow: 1; }
|
||||||
|
.cardBtn { font-size: 0.7rem; font-weight: 900; color: #fff; display: flex; align-items: center; gap: 0.5rem; letter-spacing: 0.1em; background: none; border: none; padding: 0; margin-top: auto; cursor: pointer; transition: color 0.3s ease; }
|
||||||
|
.guideCard:hover .cardBtn { color: var(--primary); }
|
||||||
|
|
||||||
|
/* 5. DOWNLOADS */
|
||||||
|
.downloads { padding: 120px 0; background-color: var(--secondary); border-top: 1px solid var(--border); }
|
||||||
|
.dlHeader { text-align: center; margin-bottom: 5rem; }
|
||||||
|
.dlHeader h2 { font-size: 2.5rem; font-weight: 900; text-transform: uppercase; }
|
||||||
|
|
||||||
|
.dlDashboard { display: grid; grid-template-columns: 1fr 1fr; gap: 2rem; }
|
||||||
|
.dlCard { background-color: var(--neutral); border: 1px solid var(--border); padding: 4rem; border-radius: 8px; display: flex; flex-direction: column; align-items: center; text-align: center; gap: 2rem; position: relative; }
|
||||||
|
.dlCard h3 { font-size: 1.3rem; font-weight: 900; text-transform: uppercase; letter-spacing: 0.05em; }
|
||||||
|
.dlCard p { font-size: 0.8rem; color: #777; line-height: 1.6; }
|
||||||
|
|
||||||
|
.passwordBox { background-color: rgba(255, 255, 255, 0.02); border: 1px dashed var(--border); padding: 1.5rem; border-radius: 4px; display: flex; flex-direction: column; gap: 0.5rem; width: 100%; margin-top: auto; }
|
||||||
|
.passwordBox span { font-size: 0.55rem; font-weight: 900; color: #444; text-transform: uppercase; }
|
||||||
|
.passKey { font-family: monospace; font-size: 1.2rem; color: #fff; font-weight: 900; letter-spacing: 0.3em; }
|
||||||
|
|
||||||
|
.extractNote { font-size: 0.65rem; color: #555; margin-top: 1rem; }
|
||||||
|
.extractNote a { color: var(--primary); font-weight: 700; text-decoration: underline; }
|
||||||
|
|
||||||
|
.versionTag { font-size: 0.65rem; font-weight: 900; color: var(--primary); background-color: rgba(255, 0, 0, 0.1); padding: 0.5rem 1.5rem; border-radius: 100px; margin-top: auto; }
|
||||||
|
|
||||||
|
.dlBtn { background-color: #fff; color: #000; padding: 1.5rem; border-radius: 4px; font-size: 0.75rem; font-weight: 900; display: flex; align-items: center; justify-content: center; gap: 1.2rem; width: 100%; transition: all 0.3s ease; text-transform: uppercase; letter-spacing: 0.1em; }
|
||||||
|
.dlBtn:hover { background-color: var(--primary); color: #fff; }
|
||||||
|
|
||||||
|
@media (max-width: 1024px) {
|
||||||
|
.heroGrid, .overviewGrid, .compGrid, .dlDashboard { grid-template-columns: 1fr; gap: 4rem; }
|
||||||
|
}
|
||||||
281
src/components/PreCAN.tsx
Normal file
@ -0,0 +1,281 @@
|
|||||||
|
'use client';
|
||||||
|
|
||||||
|
import { motion } from 'framer-motion';
|
||||||
|
import Image from 'next/image';
|
||||||
|
import {
|
||||||
|
Info,
|
||||||
|
BookOpen,
|
||||||
|
Download,
|
||||||
|
ShieldCheck,
|
||||||
|
Activity,
|
||||||
|
Gauge,
|
||||||
|
Zap,
|
||||||
|
Layers,
|
||||||
|
Settings,
|
||||||
|
Cpu,
|
||||||
|
AlertTriangle,
|
||||||
|
Terminal,
|
||||||
|
Lock,
|
||||||
|
User,
|
||||||
|
ChevronLeft,
|
||||||
|
ChevronRight
|
||||||
|
} from 'lucide-react';
|
||||||
|
import { useState, useRef } from 'react';
|
||||||
|
import styles from './PreCAN.module.css';
|
||||||
|
|
||||||
|
export default function PreCAN() {
|
||||||
|
const [currentSlide, setCurrentSlide] = useState(0);
|
||||||
|
|
||||||
|
const infoRef = useRef<HTMLElement>(null);
|
||||||
|
const guidesRef = useRef<HTMLElement>(null);
|
||||||
|
const downloadRef = useRef<HTMLElement>(null);
|
||||||
|
|
||||||
|
const scrollToSection = (ref: React.RefObject<HTMLElement | null>) => {
|
||||||
|
if (ref.current) {
|
||||||
|
ref.current.scrollIntoView({ behavior: 'smooth' });
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const coreFeatures = [
|
||||||
|
{ title: 'Live Engine Tuning', desc: 'Real-time calibration of fuel, ignition, and cam timing maps.', icon: <Activity size={24} /> },
|
||||||
|
{ title: 'High-Speed Logging', desc: 'Precision sensor data streaming for accurate combustion analysis.', icon: <Gauge size={24} /> },
|
||||||
|
{ title: 'Boost Management', desc: 'Variable boost control with custom MAP sensor support.', icon: <Zap size={24} /> },
|
||||||
|
{ title: 'Engine Safety', desc: 'Failsafe logic for lean AFR, overboost, and overheat conditions.', icon: <ShieldCheck size={24} /> },
|
||||||
|
{ title: 'Launch Control', desc: 'Programmable launch strategy with integrated anti-lag utility.', icon: <Settings size={24} /> },
|
||||||
|
{ title: 'Nitrous / Methanol', desc: 'Programmable outputs for auxiliary injection and nitrous control.', icon: <Layers size={24} /> },
|
||||||
|
];
|
||||||
|
|
||||||
|
const factoryModels = [
|
||||||
|
{ name: '05-06 Acura RSX Base', years: '05-06' },
|
||||||
|
{ name: '05-06 Acura RSX TypeS', years: '05-06' },
|
||||||
|
{ name: '05-07 Honda Accord USA', years: '05-07' },
|
||||||
|
{ name: '05-06 Honda Element', years: '05-06' },
|
||||||
|
];
|
||||||
|
|
||||||
|
const replacementModels = [
|
||||||
|
{ name: '03-07 Honda Accord EuroR', codes: 'EuroR' },
|
||||||
|
{ name: '03-04 Honda Accord USA Spec.', codes: 'CM4-CM8' },
|
||||||
|
{ name: '03-07 Honda Accord JDM Spec.', codes: 'CL7-CL9' },
|
||||||
|
{ name: '03-07 Acura TSX I', codes: 'TSX I' },
|
||||||
|
{ name: '03-04 Honda Element', codes: 'MT Only' },
|
||||||
|
{ name: 'Various EG/EK/DC K-Swapped Vehicles', codes: 'K-Swap' },
|
||||||
|
];
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className={styles.wrapper}>
|
||||||
|
{/* 1. HERO SECTION */}
|
||||||
|
<section className={styles.hero}>
|
||||||
|
<div className={styles.bgWrapper}>
|
||||||
|
<Image src="/precan_car.png" alt="PreCAN Hero" fill className={styles.heroImg} priority />
|
||||||
|
</div>
|
||||||
|
<div className={styles.heroOverlay}></div>
|
||||||
|
<div className={styles.container}>
|
||||||
|
<div className={styles.heroGrid}>
|
||||||
|
<motion.div
|
||||||
|
className={styles.heroContent}
|
||||||
|
initial={{ opacity: 0, x: -50 }}
|
||||||
|
animate={{ opacity: 1, x: 0 }}
|
||||||
|
transition={{ duration: 0.8 }}
|
||||||
|
>
|
||||||
|
<span className={styles.heroLabel}>ENGINE MANAGEMENT SYSTEMS</span>
|
||||||
|
<h1 className={styles.heroTitle}>
|
||||||
|
PRE<span className={styles.red}>CAN</span>
|
||||||
|
</h1>
|
||||||
|
<p className={styles.heroDesc}>
|
||||||
|
Expand your ECU capabilities with the PreCAN daughterboard system. Native Renesas SH7058 support,
|
||||||
|
live tuning, and professional motorsport-grade failsafes for K-Series platforms.
|
||||||
|
</p>
|
||||||
|
<div className={styles.heroActions}>
|
||||||
|
<button className={styles.primaryBtn} onClick={() => scrollToSection(infoRef)}>
|
||||||
|
<Info size={18} />
|
||||||
|
<span>INFORMATION</span>
|
||||||
|
</button>
|
||||||
|
<button className={styles.secondaryBtn} onClick={() => scrollToSection(guidesRef)}>
|
||||||
|
<BookOpen size={18} />
|
||||||
|
<span>GUIDES</span>
|
||||||
|
</button>
|
||||||
|
<button className={styles.secondaryBtn} onClick={() => scrollToSection(downloadRef)}>
|
||||||
|
<Download size={18} />
|
||||||
|
<span>DOWNLOAD</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</motion.div>
|
||||||
|
|
||||||
|
<motion.div
|
||||||
|
className={styles.heroSpecs}
|
||||||
|
initial={{ opacity: 0, x: 50 }}
|
||||||
|
animate={{ opacity: 1, x: 0 }}
|
||||||
|
transition={{ duration: 0.8, delay: 0.2 }}
|
||||||
|
>
|
||||||
|
<div className={styles.specBox}>
|
||||||
|
<div className={styles.progressLine}></div>
|
||||||
|
<div className={styles.specItem}>
|
||||||
|
<span className={styles.specLabel}>MCU SUPPORT</span>
|
||||||
|
<h3>SH7058 RENESAS</h3>
|
||||||
|
</div>
|
||||||
|
<div className={styles.specItem}>
|
||||||
|
<span className={styles.specLabel}>DATALOG MEMORY</span>
|
||||||
|
<h3>2 HOURS ON-BOARD</h3>
|
||||||
|
</div>
|
||||||
|
<div className={styles.specItem}>
|
||||||
|
<span className={styles.specLabel}>PROTOCOL</span>
|
||||||
|
<h3>CAN-BUS / K-LINE</h3>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</motion.div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
{/* 2. CORE CAPABILITIES */}
|
||||||
|
<section className={styles.overview} ref={infoRef}>
|
||||||
|
<div className={styles.container}>
|
||||||
|
<div className={styles.overviewGrid}>
|
||||||
|
<motion.div
|
||||||
|
className={styles.overviewContent}
|
||||||
|
initial={{ opacity: 0, y: 30 }}
|
||||||
|
whileInView={{ opacity: 1, y: 0 }}
|
||||||
|
viewport={{ once: true }}
|
||||||
|
>
|
||||||
|
<h2>CORE PERFORMANCE <br /><span className={styles.red}>ENGINEERING</span></h2>
|
||||||
|
<div className={styles.featuresGrid}>
|
||||||
|
{coreFeatures.map((feature, i) => (
|
||||||
|
<div key={i} className={styles.featureItem}>
|
||||||
|
<div className={styles.fIcon}>{feature.icon}</div>
|
||||||
|
<h3>{feature.title}</h3>
|
||||||
|
<p>{feature.desc}</p>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</motion.div>
|
||||||
|
<div className={styles.overviewImage}>
|
||||||
|
<Image src="/precan_car.png" width={600} height={500} alt="PreCAN Hardware" className={styles.hwImg} />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
{/* 3. COMPATIBILITY */}
|
||||||
|
<section className={styles.compatibility}>
|
||||||
|
<div className={styles.container}>
|
||||||
|
<div className={styles.compGrid}>
|
||||||
|
<div className={styles.compBox}>
|
||||||
|
<h2>FACTORY NATIVE SUPPORT</h2>
|
||||||
|
<div className={styles.vList}>
|
||||||
|
{factoryModels.map((m, i) => (
|
||||||
|
<div key={i} className={styles.vItem}>
|
||||||
|
<span>{m.name}</span>
|
||||||
|
<span className={styles.vTag}>{m.years}</span>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className={styles.compBox}>
|
||||||
|
<h2>REPLACEMENT REQUIRED</h2>
|
||||||
|
<div className={styles.vList}>
|
||||||
|
{replacementModels.map((m, i) => (
|
||||||
|
<div key={i} className={styles.vItem}>
|
||||||
|
<span>{m.name}</span>
|
||||||
|
<span className={styles.vTag}>{m.codes}</span>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
<div className={styles.note}>
|
||||||
|
<AlertTriangle size={16} />
|
||||||
|
<p>OEM ECUs in these models aren't directly compatible. Requires hardware replacement with a supported board version.</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
{/* 4. TECH GUIDES (SLIDER) */}
|
||||||
|
<section className={styles.guides} ref={guidesRef}>
|
||||||
|
<div className={styles.container}>
|
||||||
|
<div className={styles.sectionHeader}>
|
||||||
|
<div className={styles.headerTitle}>
|
||||||
|
<span className={styles.sub}>TECHNICAL INTELLIGENCE</span>
|
||||||
|
<h2>DOCUMENTATION <span className={styles.red}>SYSTEM</span></h2>
|
||||||
|
</div>
|
||||||
|
<div className={styles.sliderNav}>
|
||||||
|
<button
|
||||||
|
onClick={() => setCurrentSlide(prev => Math.max(0, prev - 1))}
|
||||||
|
className={`${styles.navBtn} ${currentSlide === 0 ? styles.disabled : ''}`}
|
||||||
|
>
|
||||||
|
<ChevronLeft size={24} />
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
onClick={() => setCurrentSlide(prev => Math.min(3, prev + 1))}
|
||||||
|
className={`${styles.navBtn} ${currentSlide === 3 ? styles.disabled : ''}`}
|
||||||
|
>
|
||||||
|
<ChevronRight size={24} />
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className={styles.sliderContainer}>
|
||||||
|
<motion.div
|
||||||
|
className={styles.sliderTray}
|
||||||
|
animate={{ x: `-${currentSlide * 33.33}%` }}
|
||||||
|
transition={{ type: "spring", stiffness: 100, damping: 20 }}
|
||||||
|
>
|
||||||
|
{[
|
||||||
|
{ title: 'Hardware Installation', desc: 'Step by Step installation Guide', icon: <Terminal size={32} /> },
|
||||||
|
{ title: 'Board LEDs Meaning', desc: 'Troubleshooting using DIAG LEDs', icon: <Settings size={32} /> },
|
||||||
|
{ title: 'Sign In or Register', desc: 'Create KTuner Account or Sign In', icon: <User size={32} /> },
|
||||||
|
{ title: 'Registering PreCAN Unit', desc: 'Hardware Registration & ECU Locking', icon: <Lock size={32} /> },
|
||||||
|
{ title: 'ECU Pinout', desc: 'Detailed ECU Connectors Pinout', icon: <Cpu size={32} /> },
|
||||||
|
{ title: 'Throttle Body Variants', desc: 'Mechanical vs Electronic Throttle Bodies', icon: <Gauge size={32} /> },
|
||||||
|
].map((card, i) => (
|
||||||
|
<div key={i} className={styles.guideCard}>
|
||||||
|
<div className={styles.cardHeader}>
|
||||||
|
<div className={styles.iconBox}>{card.icon}</div>
|
||||||
|
<span className={styles.cardNum}>0{i+1}</span>
|
||||||
|
</div>
|
||||||
|
<h3>{card.title}</h3>
|
||||||
|
<p>{card.desc}</p>
|
||||||
|
<button className={styles.cardBtn}>
|
||||||
|
VIEW DOCUMENT <ChevronRight size={14} />
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</motion.div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
{/* 5. DOWNLOADS */}
|
||||||
|
<section className={styles.downloads} ref={downloadRef}>
|
||||||
|
<div className={styles.container}>
|
||||||
|
<div className={styles.dlHeader}>
|
||||||
|
<h2>SOFTWARE <span className={styles.red}>HUB</span></h2>
|
||||||
|
</div>
|
||||||
|
<div className={styles.dlDashboard}>
|
||||||
|
<div className={styles.dlCard}>
|
||||||
|
<ShieldCheck size={32} />
|
||||||
|
<h3>Security & Instructions</h3>
|
||||||
|
<p>False virus detections may occur. If you have trouble downloading, temporarily disable Antivirus and Windows Defender.</p>
|
||||||
|
<div className={styles.passwordBox}>
|
||||||
|
<span>Archive Password</span>
|
||||||
|
<div className={styles.passKey}>1234</div>
|
||||||
|
</div>
|
||||||
|
<p className={styles.extractNote}>
|
||||||
|
* Extract with <a href="https://www.rarlab.com/download.htm">WinRAR</a> or <a href="https://www.7-zip.org">7-Zip</a>.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div className={styles.dlCard}>
|
||||||
|
<Download size={32} />
|
||||||
|
<h3>KTuner Manager</h3>
|
||||||
|
<p>Get the latest KTuner Manager + Service Utility. Compatible with CANFlash and PreCAN units.</p>
|
||||||
|
<span className={styles.versionTag}>V1.0.11.2 STABLE</span>
|
||||||
|
<a href="/files/KTSetup.rar" className={styles.dlBtn}>
|
||||||
|
<Download size={18} />
|
||||||
|
DOWNLOAD INSTALLER
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
193
src/components/ProductCard.module.css
Normal file
@ -0,0 +1,193 @@
|
|||||||
|
.card {
|
||||||
|
background-color: #0d0d0d;
|
||||||
|
border: 1px solid rgba(255, 255, 255, 0.05);
|
||||||
|
border-radius: 8px;
|
||||||
|
overflow: hidden;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
height: 100%;
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card:hover {
|
||||||
|
border-color: var(--primary);
|
||||||
|
box-shadow: 0 10px 40px rgba(0, 0, 0, 0.5);
|
||||||
|
}
|
||||||
|
|
||||||
|
.topBar {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
padding: 1rem 1.5rem;
|
||||||
|
background-color: #111;
|
||||||
|
border-bottom: 1px solid #1a1a1a;
|
||||||
|
}
|
||||||
|
|
||||||
|
.redIcon {
|
||||||
|
color: var(--primary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.sku {
|
||||||
|
font-size: 0.5rem;
|
||||||
|
font-family: monospace;
|
||||||
|
font-weight: 800;
|
||||||
|
letter-spacing: 0.1em;
|
||||||
|
color: #444;
|
||||||
|
}
|
||||||
|
|
||||||
|
.imageBox {
|
||||||
|
position: relative;
|
||||||
|
background: radial-gradient(circle at center, #111 0%, #0d0d0d 100%);
|
||||||
|
padding: 3rem;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
border-bottom: 1px solid #1a1a1a;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.glow {
|
||||||
|
position: absolute;
|
||||||
|
width: 100px;
|
||||||
|
height: 100px;
|
||||||
|
background-color: var(--primary);
|
||||||
|
filter: blur(80px);
|
||||||
|
opacity: 0.1;
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.img {
|
||||||
|
width: 100%;
|
||||||
|
height: 220px;
|
||||||
|
object-fit: contain;
|
||||||
|
transition: transform 0.4s cubic-bezier(0.4, 0, 0.2, 1);
|
||||||
|
position: relative;
|
||||||
|
z-index: 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card:hover .img {
|
||||||
|
transform: translateY(-5px) scale(1.05);
|
||||||
|
}
|
||||||
|
|
||||||
|
.content {
|
||||||
|
padding: 2.5rem;
|
||||||
|
flex-grow: 1;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
.title {
|
||||||
|
margin-bottom: 1.5rem;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 0.2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mainTitle {
|
||||||
|
font-size: 2rem;
|
||||||
|
font-weight: 900;
|
||||||
|
letter-spacing: -0.05em;
|
||||||
|
text-transform: uppercase;
|
||||||
|
}
|
||||||
|
|
||||||
|
.red {
|
||||||
|
font-size: 1.8rem;
|
||||||
|
color: var(--primary);
|
||||||
|
font-weight: 900;
|
||||||
|
font-style: italic;
|
||||||
|
margin-top: -0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.desc {
|
||||||
|
font-size: 0.9rem;
|
||||||
|
color: #666;
|
||||||
|
line-height: 1.6;
|
||||||
|
margin-bottom: 2rem;
|
||||||
|
flex-grow: 1;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stats {
|
||||||
|
display: flex;
|
||||||
|
gap: 1.5rem;
|
||||||
|
margin-bottom: 2.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stat {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 0.6rem;
|
||||||
|
font-size: 0.6rem;
|
||||||
|
font-weight: 900;
|
||||||
|
color: #555;
|
||||||
|
letter-spacing: 0.1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cardFooter {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
border-top: 1px solid #1a1a1a;
|
||||||
|
padding-top: 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.priceContainer {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
.label {
|
||||||
|
font-size: 0.5rem;
|
||||||
|
font-weight: 900;
|
||||||
|
color: #444;
|
||||||
|
letter-spacing: 0.1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.price {
|
||||||
|
font-size: 1.4rem;
|
||||||
|
font-weight: 900;
|
||||||
|
color: #fff;
|
||||||
|
letter-spacing: -0.02em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 1.2rem;
|
||||||
|
background-color: #161616;
|
||||||
|
border: 1px solid #222;
|
||||||
|
border-radius: 4px;
|
||||||
|
padding: 0.2rem 0.2rem 0.2rem 1.2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btnText {
|
||||||
|
font-size: 0.7rem;
|
||||||
|
font-weight: 900;
|
||||||
|
letter-spacing: 0.05em;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.arrowBox {
|
||||||
|
background-color: var(--primary);
|
||||||
|
width: 40px;
|
||||||
|
height: 40px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
border-radius: 4px;
|
||||||
|
color: #fff;
|
||||||
|
transition: all 0.2s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn:hover .arrowBox {
|
||||||
|
transform: translateX(3px);
|
||||||
|
filter: brightness(1.2);
|
||||||
|
background-color: #fff;
|
||||||
|
color: #000;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 480px) {
|
||||||
|
.mainTitle { font-size: 1.6rem; }
|
||||||
|
.red { font-size: 1.4rem; }
|
||||||
|
}
|
||||||
71
src/components/ProductCard.tsx
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
'use client';
|
||||||
|
|
||||||
|
import { motion } from 'framer-motion';
|
||||||
|
import Image from 'next/image';
|
||||||
|
import Link from 'next/link';
|
||||||
|
import { ArrowRight, Cpu, Zap, Activity } from 'lucide-react';
|
||||||
|
import styles from './ProductCard.module.css';
|
||||||
|
|
||||||
|
interface ProductCardProps {
|
||||||
|
id: string;
|
||||||
|
name: string;
|
||||||
|
subtitle: string;
|
||||||
|
description: string;
|
||||||
|
image: string;
|
||||||
|
price: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function ProductCard({ id, name, subtitle, description, image, price }: ProductCardProps) {
|
||||||
|
return (
|
||||||
|
<motion.div
|
||||||
|
initial={{ opacity: 0, y: 30 }}
|
||||||
|
whileInView={{ opacity: 1, y: 0 }}
|
||||||
|
viewport={{ once: true }}
|
||||||
|
whileHover={{ y: -8 }}
|
||||||
|
className={styles.card}
|
||||||
|
>
|
||||||
|
<div className={styles.topBar}>
|
||||||
|
<Cpu size={14} className={styles.redIcon} />
|
||||||
|
<span className={styles.sku}>SKU: HV-{id.toUpperCase()}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className={styles.imageBox}>
|
||||||
|
<div className={styles.glow}></div>
|
||||||
|
<Image src={image} alt={name} width={400} height={400} className={styles.img} />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className={styles.content}>
|
||||||
|
<h3 className={styles.title}>
|
||||||
|
<span className={styles.mainTitle}>{name}</span>
|
||||||
|
<span className={styles.red}>{subtitle}</span>
|
||||||
|
</h3>
|
||||||
|
|
||||||
|
<p className={styles.desc}>{description.substring(0, 85)}...</p>
|
||||||
|
|
||||||
|
<div className={styles.stats}>
|
||||||
|
<div className={styles.stat}>
|
||||||
|
<Zap size={14} />
|
||||||
|
<span>LOW LATENCY</span>
|
||||||
|
</div>
|
||||||
|
<div className={styles.stat}>
|
||||||
|
<Activity size={14} />
|
||||||
|
<span>TELEMETRY</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className={styles.cardFooter}>
|
||||||
|
<div className={styles.priceContainer}>
|
||||||
|
<span className={styles.label}>MSRP</span>
|
||||||
|
<span className={styles.price}>{price}</span>
|
||||||
|
</div>
|
||||||
|
<Link href={`/products/${id}`} className={styles.btn}>
|
||||||
|
<span className={styles.btnText}>READ MORE</span>
|
||||||
|
<div className={styles.arrowBox}>
|
||||||
|
<ArrowRight size={14} />
|
||||||
|
</div>
|
||||||
|
</Link>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</motion.div>
|
||||||
|
);
|
||||||
|
}
|
||||||
174
src/components/ProductShowcase.module.css
Normal file
@ -0,0 +1,174 @@
|
|||||||
|
.section {
|
||||||
|
position: relative;
|
||||||
|
min-height: 80vh;
|
||||||
|
padding: 100px 0;
|
||||||
|
background-color: #000;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bgImage {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
opacity: 0.8;
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.image {
|
||||||
|
object-fit: cover;
|
||||||
|
filter: saturate(0.5) contrast(1.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.overlay {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
background: radial-gradient(circle at 30% 50%, rgba(0, 0, 0, 0.9) 0%, rgba(0, 0, 0, 0.4) 60%, transparent 100%);
|
||||||
|
z-index: 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.container {
|
||||||
|
position: relative;
|
||||||
|
max-width: 1400px;
|
||||||
|
width: 100%;
|
||||||
|
margin: 0 auto;
|
||||||
|
padding: 0 4rem;
|
||||||
|
z-index: 3;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.top {
|
||||||
|
max-width: 600px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.label {
|
||||||
|
font-size: 0.75rem;
|
||||||
|
font-weight: 800;
|
||||||
|
color: #555;
|
||||||
|
letter-spacing: 0.2rem;
|
||||||
|
display: block;
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.title {
|
||||||
|
font-size: clamp(3rem, 6vw, 5rem);
|
||||||
|
font-weight: 900;
|
||||||
|
line-height: 0.85;
|
||||||
|
letter-spacing: -0.05em;
|
||||||
|
margin-bottom: 2rem;
|
||||||
|
text-transform: uppercase;
|
||||||
|
}
|
||||||
|
|
||||||
|
.red {
|
||||||
|
color: var(--primary);
|
||||||
|
font-style: italic;
|
||||||
|
}
|
||||||
|
|
||||||
|
.description {
|
||||||
|
font-size: 1.1rem;
|
||||||
|
color: #aaa;
|
||||||
|
line-height: 1.6;
|
||||||
|
margin-bottom: 3rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.actions {
|
||||||
|
display: flex;
|
||||||
|
gap: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 0.8rem;
|
||||||
|
padding: 1rem 1.8rem;
|
||||||
|
border-radius: 4px;
|
||||||
|
font-size: 0.75rem;
|
||||||
|
font-weight: 800;
|
||||||
|
letter-spacing: 0.1em;
|
||||||
|
transition: all 0.2s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btnPrimary {
|
||||||
|
background-color: var(--primary);
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btnSecondary {
|
||||||
|
background-color: rgba(255, 255, 255, 0.05);
|
||||||
|
border: 1px solid #222;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btnDownload {
|
||||||
|
background-color: #1a1a1a;
|
||||||
|
border: 1px solid #333;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.right {
|
||||||
|
min-width: 350px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.specBox {
|
||||||
|
background-color: #0c0c0c;
|
||||||
|
border: 1px solid #1a1a1a;
|
||||||
|
padding: 2.5rem;
|
||||||
|
border-radius: 4px;
|
||||||
|
position: relative;
|
||||||
|
z-index: 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
.specHeader {
|
||||||
|
font-size: 0.65rem;
|
||||||
|
font-weight: 900;
|
||||||
|
color: var(--primary);
|
||||||
|
margin-bottom: 1.5rem;
|
||||||
|
border-bottom: 1px solid #222;
|
||||||
|
padding-bottom: 0.8rem;
|
||||||
|
letter-spacing: 0.2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.specItem {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
margin-bottom: 1.2rem;
|
||||||
|
font-size: 0.8rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.specItem span {
|
||||||
|
color: #444;
|
||||||
|
font-weight: 800;
|
||||||
|
margin-bottom: 0.3rem;
|
||||||
|
text-transform: uppercase;
|
||||||
|
}
|
||||||
|
|
||||||
|
.specItem strong {
|
||||||
|
font-size: 1.2rem;
|
||||||
|
font-weight: 800;
|
||||||
|
color: #fff;
|
||||||
|
font-style: italic;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 1024px) {
|
||||||
|
.container {
|
||||||
|
flex-direction: column;
|
||||||
|
text-align: center;
|
||||||
|
gap: 3rem;
|
||||||
|
padding: 0 2rem;
|
||||||
|
}
|
||||||
|
.actions {
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
.right {
|
||||||
|
min-width: unset;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
60
src/components/ProductShowcase.tsx
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
'use client';
|
||||||
|
|
||||||
|
import { motion } from 'framer-motion';
|
||||||
|
import Image from 'next/image';
|
||||||
|
import { Info, BookOpen, Download } from 'lucide-react';
|
||||||
|
import styles from './ProductShowcase.module.css';
|
||||||
|
|
||||||
|
interface ProductShowcaseProps {
|
||||||
|
label: string;
|
||||||
|
title1: string;
|
||||||
|
title2: string;
|
||||||
|
image: string;
|
||||||
|
specs: { label: string; value: string }[];
|
||||||
|
description: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function ProductShowcase({ label, title1, title2, image, specs, description }: ProductShowcaseProps) {
|
||||||
|
return (
|
||||||
|
<section className={styles.section}>
|
||||||
|
<div className={styles.bgImage}>
|
||||||
|
<Image src={image} alt={title1} fill className={styles.image} />
|
||||||
|
<div className={styles.overlay}></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className={styles.container}>
|
||||||
|
<div className={styles.top}>
|
||||||
|
<span className={styles.label}>{label}</span>
|
||||||
|
<h2 className={styles.title}>
|
||||||
|
{title1} <span className={styles.red}>{title2}</span>
|
||||||
|
</h2>
|
||||||
|
<p className={styles.description}>{description}</p>
|
||||||
|
|
||||||
|
<div className={styles.actions}>
|
||||||
|
<button className={`${styles.btn} ${styles.btnPrimary}`}>
|
||||||
|
<Info size={16} /> <span>INFORMATION</span>
|
||||||
|
</button>
|
||||||
|
<button className={`${styles.btn} ${styles.btnSecondary}`}>
|
||||||
|
<BookOpen size={16} /> <span>GUIDES</span>
|
||||||
|
</button>
|
||||||
|
<button className={`${styles.btn} ${styles.btnDownload}`}>
|
||||||
|
<Download size={16} /> <span>DOWNLOAD</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className={styles.right}>
|
||||||
|
<div className={styles.specBox}>
|
||||||
|
<div className={styles.specHeader}>TECHNICAL SPECS</div>
|
||||||
|
{specs.map((spec, i) => (
|
||||||
|
<div key={i} className={styles.specItem}>
|
||||||
|
<span>{spec.label}</span>
|
||||||
|
<strong>{spec.value}</strong>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
);
|
||||||
|
}
|
||||||
232
src/components/S300.module.css
Normal file
@ -0,0 +1,232 @@
|
|||||||
|
.wrapper {
|
||||||
|
background-color: var(--neutral);
|
||||||
|
min-height: 100vh;
|
||||||
|
}
|
||||||
|
|
||||||
|
.container {
|
||||||
|
max-width: 1400px;
|
||||||
|
width: 100%;
|
||||||
|
margin: 0 auto;
|
||||||
|
padding: 0 4rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 1. HERO */
|
||||||
|
.hero {
|
||||||
|
position: relative;
|
||||||
|
min-height: 80vh;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
overflow: hidden;
|
||||||
|
padding-top: 100px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bgWrapper {
|
||||||
|
position: absolute;
|
||||||
|
inset: 0;
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.heroImg {
|
||||||
|
object-fit: cover;
|
||||||
|
filter: saturate(0.2) contrast(1.2) brightness(0.4);
|
||||||
|
}
|
||||||
|
|
||||||
|
.heroOverlay {
|
||||||
|
position: absolute;
|
||||||
|
inset: 0;
|
||||||
|
background: linear-gradient(to bottom, rgba(0,0,0,0.6) 0%, rgba(0,0,0,0.9) 100%);
|
||||||
|
z-index: 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.heroGrid {
|
||||||
|
position: relative;
|
||||||
|
z-index: 3;
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 1.5fr 1fr;
|
||||||
|
gap: 5rem;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.heroLabel {
|
||||||
|
font-size: 0.65rem;
|
||||||
|
font-weight: 900;
|
||||||
|
color: #555;
|
||||||
|
letter-spacing: 0.2rem;
|
||||||
|
display: block;
|
||||||
|
margin-bottom: 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.heroTitle {
|
||||||
|
font-size: clamp(4rem, 8vw, 6.5rem);
|
||||||
|
font-weight: 900;
|
||||||
|
line-height: 0.85;
|
||||||
|
letter-spacing: -0.05em;
|
||||||
|
margin-bottom: 2.5rem;
|
||||||
|
text-transform: uppercase;
|
||||||
|
}
|
||||||
|
|
||||||
|
.red { color: var(--primary); font-style: italic; }
|
||||||
|
|
||||||
|
.heroDesc {
|
||||||
|
font-size: 1.1rem;
|
||||||
|
color: #888;
|
||||||
|
line-height: 1.6;
|
||||||
|
margin-bottom: 3.5rem;
|
||||||
|
max-width: 600px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.heroActions { display: flex; gap: 1rem; }
|
||||||
|
|
||||||
|
.primaryBtn {
|
||||||
|
background-color: var(--primary);
|
||||||
|
padding: 1.2rem 2.2rem;
|
||||||
|
border-radius: 4px;
|
||||||
|
font-size: 0.7rem;
|
||||||
|
font-weight: 900;
|
||||||
|
letter-spacing: 0.1em;
|
||||||
|
color: #fff;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 1.2rem;
|
||||||
|
cursor: pointer;
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.secondaryBtn {
|
||||||
|
background-color: rgba(255, 255, 255, 0.02);
|
||||||
|
border: 1px solid var(--border);
|
||||||
|
padding: 1.2rem 2.2rem;
|
||||||
|
border-radius: 4px;
|
||||||
|
font-size: 0.7rem;
|
||||||
|
font-weight: 900;
|
||||||
|
letter-spacing: 0.1em;
|
||||||
|
color: #fff;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 1.2rem;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.specBox {
|
||||||
|
background-color: rgba(18, 18, 18, 0.4);
|
||||||
|
border: 1px solid rgba(255, 255, 255, 0.05);
|
||||||
|
backdrop-filter: blur(10px);
|
||||||
|
padding: 3rem;
|
||||||
|
width: 100%;
|
||||||
|
max-width: 400px;
|
||||||
|
border-radius: 4px;
|
||||||
|
position: relative;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.progressLine {
|
||||||
|
position: absolute;
|
||||||
|
top: 0; left: 0; width: 60%;
|
||||||
|
height: 2px;
|
||||||
|
background-color: var(--primary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.specItem { margin-bottom: 2.5rem; }
|
||||||
|
.specItem:last-child { margin-bottom: 0; }
|
||||||
|
|
||||||
|
.specLabel {
|
||||||
|
font-size: 0.55rem;
|
||||||
|
font-weight: 900;
|
||||||
|
color: #444;
|
||||||
|
letter-spacing: 0.1em;
|
||||||
|
display: block;
|
||||||
|
margin-bottom: 0.8rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.specItem h3 { font-size: 1.3rem; font-weight: 900; font-style: italic; }
|
||||||
|
|
||||||
|
/* 2. OVERVIEW */
|
||||||
|
.overview { padding: 120px 0; background-color: var(--neutral); }
|
||||||
|
.overviewGrid { display: grid; grid-template-columns: 1fr 1fr; gap: 8rem; align-items: center; }
|
||||||
|
.overviewContent h2 { font-size: 3rem; font-weight: 900; letter-spacing: -0.05em; margin-bottom: 3rem; line-height: 0.9; }
|
||||||
|
.featuresGrid { display: grid; grid-template-columns: 1fr 1fr; gap: 3rem 4rem; }
|
||||||
|
|
||||||
|
.featureItem { display: flex; flex-direction: column; gap: 1.2rem; }
|
||||||
|
.fIcon { width: 32px; height: 32px; color: var(--primary); }
|
||||||
|
.featureItem h3 { font-size: 0.85rem; font-weight: 900; text-transform: uppercase; letter-spacing: 0.1em; }
|
||||||
|
.featureItem p { font-size: 0.75rem; color: #777; line-height: 1.5; font-weight: 500; }
|
||||||
|
|
||||||
|
.hwImg { width: 100%; height: auto; border-radius: 4px; filter: saturate(0.8) contrast(1.1); }
|
||||||
|
|
||||||
|
/* 3. COMPATIBILITY */
|
||||||
|
.compatibility { padding: 120px 0; background-color: var(--secondary); border-top: 1px solid var(--border); border-bottom: 1px solid var(--border); }
|
||||||
|
.compGrid { display: grid; grid-template-columns: 1fr 1fr; gap: 4rem; }
|
||||||
|
.compBox { background-color: var(--neutral); border: 1px solid var(--border); padding: 3rem; border-radius: 4px; }
|
||||||
|
.compBox h2 { font-size: 1.2rem; font-weight: 900; margin-bottom: 2.5rem; border-bottom: 1px solid var(--border); padding-bottom: 1.2rem; letter-spacing: 0.05em; }
|
||||||
|
.vList { display: flex; flex-direction: column; gap: 1rem; }
|
||||||
|
|
||||||
|
.vItem { display: flex; justify-content: space-between; font-size: 0.85rem; padding-bottom: 0.8rem; border-bottom: 1px solid rgba(255, 255, 255, 0.03); }
|
||||||
|
.vTag { font-family: monospace; color: var(--primary); font-weight: 700; text-transform: uppercase; }
|
||||||
|
|
||||||
|
.note { display: flex; gap: 1rem; color: var(--primary); font-size: 0.75rem; margin-top: 2rem; font-weight: 700; opacity: 0.8; }
|
||||||
|
|
||||||
|
.ecuSupported { margin-top: 2.5rem; background-color: rgba(255,255,255,0.02); padding: 1.5rem; border-radius: 4px; border: 1px solid var(--border); }
|
||||||
|
.ecuRow { display: flex; flex-direction: column; gap: 0.5rem; margin-bottom: 1.2rem; }
|
||||||
|
.ecuRow:last-child { margin-bottom: 0; }
|
||||||
|
.ecuRegion { font-size: 0.65rem; font-weight: 900; color: var(--primary); letter-spacing: 0.1em; }
|
||||||
|
.ecuVer { font-family: monospace; font-size: 0.8rem; color: #bbb; line-height: 1.5; }
|
||||||
|
|
||||||
|
/* 4. GUIDES */
|
||||||
|
.guides { padding: 120px 0; background-color: var(--neutral); overflow: hidden; }
|
||||||
|
.sectionHeader { display: flex; justify-content: space-between; align-items: flex-end; margin-bottom: 5rem; }
|
||||||
|
.headerTitle .sub { font-size: 0.65rem; font-weight: 900; color: var(--primary); letter-spacing: 0.2rem; display: block; margin-bottom: 1rem; text-transform: uppercase; }
|
||||||
|
.headerTitle h2 { font-size: 2.5rem; font-weight: 900; margin: 0; line-height: 1; letter-spacing: -0.05em; text-transform: uppercase; }
|
||||||
|
|
||||||
|
.sliderNav { display: flex; gap: 1rem; }
|
||||||
|
.navBtn { width: 50px; height: 50px; border-radius: 50%; background-color: var(--secondary); border: 1px solid var(--border); color: #fff; display: flex; align-items: center; justify-content: center; cursor: pointer; transition: all 0.3s ease; }
|
||||||
|
.navBtn:hover:not(.disabled) { background-color: var(--primary); border-color: var(--primary); }
|
||||||
|
.navBtn.disabled { opacity: 0.3; cursor: not-allowed; }
|
||||||
|
|
||||||
|
.sliderContainer { width: 100%; overflow: hidden; padding: 1rem 0; }
|
||||||
|
.sliderTray { display: grid; grid-auto-flow: column; grid-auto-columns: calc(33.333% - 1.333rem); gap: 2rem; width: 100%; }
|
||||||
|
|
||||||
|
.guideCard { background-color: var(--secondary); background-image: linear-gradient(to bottom, rgba(10,10,10,0.7) 0%, rgba(0,0,0,1) 100%), var(--card-bg); background-size: cover; background-position: center; border: 1px solid var(--border); padding: 3rem; border-radius: 8px; transition: all 0.3s ease; display: flex; flex-direction: column; gap: 1.5rem; height: 100%; min-height: 350px; position: relative; }
|
||||||
|
.guideCard:hover { border-color: var(--primary); transform: translateY(-10px); background-image: linear-gradient(to bottom, rgba(220, 38, 38, 0.05) 0%, rgba(0,0,0,0.95) 100%), var(--card-bg); }
|
||||||
|
|
||||||
|
.cardHeader { display: flex; justify-content: space-between; align-items: flex-start; margin-bottom: 1rem; }
|
||||||
|
.iconBox { width: 60px; height: 60px; background-color: rgba(255, 0, 0, 0.05); border: 1px solid rgba(255, 0, 0, 0.1); border-radius: 8px; display: flex; align-items: center; justify-content: center; color: var(--primary); }
|
||||||
|
.cardNum { font-size: 1.5rem; font-weight: 900; color: rgba(255, 255, 255, 0.1); letter-spacing: -0.05em; }
|
||||||
|
|
||||||
|
.guideCard h3 { font-size: 1.2rem; font-weight: 900; line-height: 1.3; margin: 0; letter-spacing: -0.02em; }
|
||||||
|
.guideCard p { font-size: 0.85rem; color: #888; line-height: 1.6; margin: 0; flex-grow: 1; }
|
||||||
|
.cardBtn { font-size: 0.7rem; font-weight: 900; color: #fff; display: flex; align-items: center; gap: 0.5rem; letter-spacing: 0.1em; background: none; border: none; padding: 0; margin-top: auto; cursor: pointer; transition: color 0.3s ease; }
|
||||||
|
.guideCard:hover .cardBtn { color: var(--primary); }
|
||||||
|
|
||||||
|
/* 5. DOWNLOADS */
|
||||||
|
.downloads { padding: 120px 0; background-color: var(--secondary); border-top: 1px solid var(--border); }
|
||||||
|
.dlHeader { text-align: center; margin-bottom: 5rem; }
|
||||||
|
.dlHeader h2 { font-size: 2.5rem; font-weight: 900; text-transform: uppercase; }
|
||||||
|
|
||||||
|
.dlDashboard { display: grid; grid-template-columns: 1fr 1fr; gap: 2rem; }
|
||||||
|
.dlCard { background-color: var(--neutral); border: 1px solid var(--border); padding: 4rem; border-radius: 8px; display: flex; flex-direction: column; align-items: center; text-align: center; gap: 2rem; position: relative; }
|
||||||
|
.dlCard h3 { font-size: 1.3rem; font-weight: 900; text-transform: uppercase; letter-spacing: 0.05em; }
|
||||||
|
.dlCard p { font-size: 0.8rem; color: #777; line-height: 1.6; }
|
||||||
|
|
||||||
|
.passwordBox { background-color: rgba(255, 255, 255, 0.02); border: 1px dashed var(--border); padding: 1.5rem; border-radius: 4px; display: flex; flex-direction: column; gap: 0.5rem; width: 100%; margin-top: auto; }
|
||||||
|
.passwordBox span { font-size: 0.55rem; font-weight: 900; color: #444; text-transform: uppercase; }
|
||||||
|
.passKey { font-family: monospace; font-size: 1.2rem; color: #fff; font-weight: 900; letter-spacing: 0.3em; }
|
||||||
|
|
||||||
|
.extractNote { font-size: 0.65rem; color: #555; margin-top: 1rem; }
|
||||||
|
.extractNote a { color: var(--primary); font-weight: 700; text-decoration: underline; }
|
||||||
|
|
||||||
|
.dlStack { display: flex; flex-direction: column; gap: 2rem; }
|
||||||
|
.dlRowCard { background-color: var(--neutral); border: 1px solid var(--border); padding: 3rem; border-radius: 8px; display: flex; justify-content: space-between; align-items: center; transition: all 0.3s ease; }
|
||||||
|
.dlRowCard:hover { border-color: var(--primary); }
|
||||||
|
.dlRowInfo { display: flex; flex-direction: column; align-items: flex-start; gap: 0.8rem; }
|
||||||
|
.dlRowInfo h4 { font-size: 1.1rem; font-weight: 900; margin: 0; color: #fff; }
|
||||||
|
.dlRowInfo p { font-size: 0.8rem; color: #888; margin: 0; }
|
||||||
|
.versionTag { font-size: 0.65rem; font-weight: 900; color: var(--primary); background-color: rgba(255, 0, 0, 0.1); padding: 0.3rem 0.8rem; border-radius: 100px; }
|
||||||
|
|
||||||
|
.dlBtn { background-color: #fff; color: #000; padding: 1.2rem 2.5rem; border-radius: 4px; font-size: 0.75rem; font-weight: 900; display: flex; align-items: center; justify-content: center; gap: 1.2rem; transition: all 0.3s ease; text-transform: uppercase; letter-spacing: 0.1em; }
|
||||||
|
.dlBtn:hover { background-color: var(--primary); color: #fff; box-shadow: 0 10px 20px rgba(255,0,0,0.2); }
|
||||||
|
|
||||||
|
@media (max-width: 1024px) {
|
||||||
|
.heroGrid, .overviewGrid, .compGrid, .dlDashboard { grid-template-columns: 1fr; gap: 4rem; }
|
||||||
|
.dlRowCard { flex-direction: column; gap: 2rem; align-items: stretch; text-align: center; }
|
||||||
|
.dlRowInfo { align-items: center; }
|
||||||
|
}
|
||||||
314
src/components/S300.tsx
Normal file
@ -0,0 +1,314 @@
|
|||||||
|
'use client';
|
||||||
|
|
||||||
|
import { motion } from 'framer-motion';
|
||||||
|
import Image from 'next/image';
|
||||||
|
import {
|
||||||
|
Info,
|
||||||
|
BookOpen,
|
||||||
|
Download,
|
||||||
|
ShieldCheck,
|
||||||
|
Activity,
|
||||||
|
Zap,
|
||||||
|
Layers,
|
||||||
|
Settings,
|
||||||
|
Cpu,
|
||||||
|
AlertTriangle,
|
||||||
|
Terminal,
|
||||||
|
ChevronLeft,
|
||||||
|
ChevronRight,
|
||||||
|
Bluetooth,
|
||||||
|
Gauge
|
||||||
|
} from 'lucide-react';
|
||||||
|
import { useState, useRef } from 'react';
|
||||||
|
import styles from './S300.module.css';
|
||||||
|
|
||||||
|
export default function S300() {
|
||||||
|
const [currentSlide, setCurrentSlide] = useState(0);
|
||||||
|
|
||||||
|
const infoRef = useRef<HTMLElement>(null);
|
||||||
|
const guidesRef = useRef<HTMLElement>(null);
|
||||||
|
const downloadRef = useRef<HTMLElement>(null);
|
||||||
|
|
||||||
|
const scrollToSection = (ref: React.RefObject<HTMLElement | null>) => {
|
||||||
|
if (ref.current) {
|
||||||
|
ref.current.scrollIntoView({ behavior: 'smooth' });
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const coreFeatures = [
|
||||||
|
{ title: 'Live Engine Tuning', desc: 'Real-time calibration of fuel, ignition, and injector settings.', icon: <Activity size={24} /> },
|
||||||
|
{ title: 'Advanced Bluetooth', desc: 'Wireless datalogging and telemetry via S300 Rev.3 architecture.', icon: <Bluetooth size={24} /> },
|
||||||
|
{ title: 'Flex Fuel & Boost', desc: 'Variable boost control, Flex Fuel support, and custom MAP sensor logic.', icon: <Zap size={24} /> },
|
||||||
|
{ title: 'Engine Protection', desc: 'Failsafe logic for lean AFR, overboost, and overheat conditions.', icon: <ShieldCheck size={24} /> },
|
||||||
|
{ title: 'Launch Control', desc: 'Full throttle shift capabilities and programmable anti-lag.', icon: <Gauge size={24} /> },
|
||||||
|
{ title: 'Nitrous / Methanol', desc: 'Auxiliary outputs for nitrous control and methanol injection systems.', icon: <Layers size={24} /> },
|
||||||
|
];
|
||||||
|
|
||||||
|
const factoryModels = [
|
||||||
|
{ name: '91-92 Honda Integra DA', codes: 'DA' },
|
||||||
|
{ name: '93-95 Honda Integra DB', codes: 'DB' },
|
||||||
|
{ name: '92-95 Honda Civic', codes: 'EG/EH/EJ' },
|
||||||
|
{ name: '92-95 Honda CR-X DelSol', codes: 'EG1/EG2' },
|
||||||
|
];
|
||||||
|
|
||||||
|
const replacementModels = [
|
||||||
|
{ name: '96-01 Honda Civic', codes: 'EK/EJ' },
|
||||||
|
{ name: '96-01 Honda Integra', codes: 'DC2/DC4' },
|
||||||
|
{ name: '96-01 Honda Prelude 5', codes: 'BB5-BB8' },
|
||||||
|
{ name: '95-01 Honda CR-V', codes: 'RD1' },
|
||||||
|
];
|
||||||
|
|
||||||
|
const ecuSupport = [
|
||||||
|
{ region: 'USDM ECU BOARDS', versions: '02D011F0-1500, 02D01720-1500, 02D01980-1500' },
|
||||||
|
{ region: 'JDM ECU BOARDS', versions: '02D01550-1500, 02D01840-1501' },
|
||||||
|
{ region: 'EDM ECU BOARDS', versions: '2PU6098-4460P1, 2PU6098-4508P1' },
|
||||||
|
];
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className={styles.wrapper}>
|
||||||
|
{/* 1. HERO SECTION */}
|
||||||
|
<section className={styles.hero}>
|
||||||
|
<div className={styles.bgWrapper}>
|
||||||
|
<Image src="/s300_board.png" alt="S300 Hero Component" fill className={styles.heroImg} priority />
|
||||||
|
</div>
|
||||||
|
<div className={styles.heroOverlay}></div>
|
||||||
|
<div className={styles.container}>
|
||||||
|
<div className={styles.heroGrid}>
|
||||||
|
<motion.div
|
||||||
|
className={styles.heroContent}
|
||||||
|
initial={{ opacity: 0, x: -50 }}
|
||||||
|
animate={{ opacity: 1, x: 0 }}
|
||||||
|
transition={{ duration: 0.8 }}
|
||||||
|
>
|
||||||
|
<span className={styles.heroLabel}>OBD1 ENGINE MANAGEMENT SYSTEM</span>
|
||||||
|
<h1 className={styles.heroTitle}>
|
||||||
|
S300 <br />
|
||||||
|
<span className={styles.red}>CORE</span>
|
||||||
|
</h1>
|
||||||
|
<p className={styles.heroDesc}>
|
||||||
|
Expand your Honda OBD1 ECU capabilities. Professional grade engine management
|
||||||
|
featuring Live Tuning, Flex Fuel support, and advanced Bluetooth telemetry options.
|
||||||
|
</p>
|
||||||
|
<div className={styles.heroActions}>
|
||||||
|
<button className={styles.primaryBtn} onClick={() => scrollToSection(infoRef)}>
|
||||||
|
<Info size={18} />
|
||||||
|
<span>INFORMATION</span>
|
||||||
|
</button>
|
||||||
|
<button className={styles.secondaryBtn} onClick={() => scrollToSection(guidesRef)}>
|
||||||
|
<BookOpen size={18} />
|
||||||
|
<span>GUIDES</span>
|
||||||
|
</button>
|
||||||
|
<button className={styles.secondaryBtn} onClick={() => scrollToSection(downloadRef)}>
|
||||||
|
<Download size={18} />
|
||||||
|
<span>DOWNLOAD</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</motion.div>
|
||||||
|
|
||||||
|
<motion.div
|
||||||
|
className={styles.heroSpecs}
|
||||||
|
initial={{ opacity: 0, x: 50 }}
|
||||||
|
animate={{ opacity: 1, x: 0 }}
|
||||||
|
transition={{ duration: 0.8, delay: 0.2 }}
|
||||||
|
>
|
||||||
|
<div className={styles.specBox}>
|
||||||
|
<div className={styles.progressLine}></div>
|
||||||
|
<div className={styles.specItem}>
|
||||||
|
<span className={styles.specLabel}>PLATFORM SUPPORT</span>
|
||||||
|
<h3>OBD1 USDM/JDM/EDM</h3>
|
||||||
|
</div>
|
||||||
|
<div className={styles.specItem}>
|
||||||
|
<span className={styles.specLabel}>SOFTWARE PROTOCOL</span>
|
||||||
|
<h3>S300 / OSTRICH 2</h3>
|
||||||
|
</div>
|
||||||
|
<div className={styles.specItem}>
|
||||||
|
<span className={styles.specLabel}>I/O EXPANSION</span>
|
||||||
|
<h3>6 ANALOG INPUTS</h3>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</motion.div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
{/* 2. CORE CAPABILITIES */}
|
||||||
|
<section className={styles.overview} ref={infoRef}>
|
||||||
|
<div className={styles.container}>
|
||||||
|
<div className={styles.overviewGrid}>
|
||||||
|
<motion.div
|
||||||
|
className={styles.overviewContent}
|
||||||
|
initial={{ opacity: 0, y: 30 }}
|
||||||
|
whileInView={{ opacity: 1, y: 0 }}
|
||||||
|
viewport={{ once: true }}
|
||||||
|
>
|
||||||
|
<h2>CORE PERFORMANCE <br /><span className={styles.red}>ENGINEERING</span></h2>
|
||||||
|
<div className={styles.featuresGrid}>
|
||||||
|
{coreFeatures.map((feature, i) => (
|
||||||
|
<div key={i} className={styles.featureItem}>
|
||||||
|
<div className={styles.fIcon}>{feature.icon}</div>
|
||||||
|
<h3>{feature.title}</h3>
|
||||||
|
<p>{feature.desc}</p>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</motion.div>
|
||||||
|
<div className={styles.overviewImage}>
|
||||||
|
<Image src="/hud_telemetry.png" width={600} height={500} alt="S300 Hardware" className={styles.hwImg} />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
{/* 3. COMPATIBILITY */}
|
||||||
|
<section className={styles.compatibility}>
|
||||||
|
<div className={styles.container}>
|
||||||
|
<div className={styles.compGrid}>
|
||||||
|
<div className={styles.compBox}>
|
||||||
|
<h2>FACTORY NATIVE SUPPORT</h2>
|
||||||
|
<div className={styles.vList}>
|
||||||
|
{factoryModels.map((m, i) => (
|
||||||
|
<div key={i} className={styles.vItem}>
|
||||||
|
<span>{m.name}</span>
|
||||||
|
<span className={styles.vTag}>{m.codes}</span>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
<div className={styles.ecuSupported}>
|
||||||
|
{ecuSupport.map((ecu, index) => (
|
||||||
|
<div key={index} className={styles.ecuRow}>
|
||||||
|
<span className={styles.ecuRegion}>{ecu.region}</span>
|
||||||
|
<span className={styles.ecuVer}>{ecu.versions}</span>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className={styles.compBox}>
|
||||||
|
<h2>REPLACEMENT REQUIRED</h2>
|
||||||
|
<div className={styles.vList}>
|
||||||
|
{replacementModels.map((m, i) => (
|
||||||
|
<div key={i} className={styles.vItem}>
|
||||||
|
<span>{m.name}</span>
|
||||||
|
<span className={styles.vTag}>{m.codes}</span>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
<div className={styles.note}>
|
||||||
|
<AlertTriangle size={16} />
|
||||||
|
<p>OEM ECUs in these models aren't directly compatible. Requires hardware replacement with a supported OBD1 board version.</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
{/* 4. TECH GUIDES (SLIDER) */}
|
||||||
|
<section className={styles.guides} ref={guidesRef}>
|
||||||
|
<div className={styles.container}>
|
||||||
|
<div className={styles.sectionHeader}>
|
||||||
|
<div className={styles.headerTitle}>
|
||||||
|
<span className={styles.sub}>TECHNICAL INTELLIGENCE</span>
|
||||||
|
<h2>DOCUMENTATION <span className={styles.red}>SYSTEM</span></h2>
|
||||||
|
</div>
|
||||||
|
<div className={styles.sliderNav}>
|
||||||
|
<button
|
||||||
|
onClick={() => setCurrentSlide(prev => Math.max(0, prev - 1))}
|
||||||
|
className={`${styles.navBtn} ${currentSlide === 0 ? styles.disabled : ''}`}
|
||||||
|
>
|
||||||
|
<ChevronLeft size={24} />
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
onClick={() => setCurrentSlide(prev => Math.min(5, prev + 1))}
|
||||||
|
className={`${styles.navBtn} ${currentSlide === 5 ? styles.disabled : ''}`}
|
||||||
|
>
|
||||||
|
<ChevronRight size={24} />
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className={styles.sliderContainer}>
|
||||||
|
<motion.div
|
||||||
|
className={styles.sliderTray}
|
||||||
|
animate={{ x: `-${currentSlide * 33.33}%` }}
|
||||||
|
transition={{ type: "spring", stiffness: 100, damping: 20 }}
|
||||||
|
>
|
||||||
|
{[
|
||||||
|
{ title: 'Hardware Install (USDM ECU)', desc: 'Step by Step installation Guide', icon: <Terminal size={32} />, img: '/engine_bay.png' },
|
||||||
|
{ title: 'Hardware Install (EDM ECU)', desc: 'Step by Step installation Guide', icon: <Terminal size={32} />, img: '/engine_bay.png' },
|
||||||
|
{ title: 'Hardware Install (JDM ECU)', desc: 'Step by Step installation Guide', icon: <Terminal size={32} />, img: '/engine_bay.png' },
|
||||||
|
{ title: 'Bluetooth', desc: 'Connection Guide and Compatible Applications', icon: <Bluetooth size={32} />, img: '/hud_telemetry.png' },
|
||||||
|
{ title: 'S300 / Ostrich 2 Mode Switch', desc: 'Use board with S300 Manager or 3rd-party software', icon: <Settings size={32} />, img: '/precan_car.png' },
|
||||||
|
{ title: 'Board LEDs Meaning', desc: 'Troubleshooting using DIAG LEDs', icon: <ShieldCheck size={32} />, img: '/map_sensor.png' },
|
||||||
|
{ title: 'ECU Pinout', desc: 'Detailed ECU Connectors Pinout', icon: <Cpu size={32} />, img: '/ecu_kpro.png' },
|
||||||
|
{ title: 'Automatic Transmission Setup', desc: 'How to control an automatic transmission using S300 Manager', icon: <Settings size={32} />, img: '/ecu_kpro.png' },
|
||||||
|
].map((card, i) => (
|
||||||
|
<div
|
||||||
|
key={i}
|
||||||
|
className={styles.guideCard}
|
||||||
|
style={{ '--card-bg': `url(${card.img})` } as React.CSSProperties}
|
||||||
|
>
|
||||||
|
<div className={styles.cardHeader}>
|
||||||
|
<div className={styles.iconBox}>{card.icon}</div>
|
||||||
|
<span className={styles.cardNum}>0{i+1}</span>
|
||||||
|
</div>
|
||||||
|
<h3>{card.title}</h3>
|
||||||
|
<p>{card.desc}</p>
|
||||||
|
<button className={styles.cardBtn}>
|
||||||
|
VIEW DOCUMENT <ChevronRight size={14} />
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</motion.div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
{/* 5. DOWNLOADS */}
|
||||||
|
<section className={styles.downloads} ref={downloadRef}>
|
||||||
|
<div className={styles.container}>
|
||||||
|
<div className={styles.dlHeader}>
|
||||||
|
<h2>SOFTWARE <span className={styles.red}>HUB</span></h2>
|
||||||
|
</div>
|
||||||
|
<div className={styles.dlDashboard}>
|
||||||
|
<div className={styles.dlCard}>
|
||||||
|
<ShieldCheck size={32} />
|
||||||
|
<h3>Security & Instructions</h3>
|
||||||
|
<p>False virus detections may occur. If you have trouble downloading, temporarily disable Antivirus and Windows Defender.</p>
|
||||||
|
<div className={styles.passwordBox}>
|
||||||
|
<span>Archive Password</span>
|
||||||
|
<div className={styles.passKey}>1234</div>
|
||||||
|
</div>
|
||||||
|
<p className={styles.extractNote}>
|
||||||
|
* Extract with <a href="https://www.rarlab.com/download.htm" target="_blank">WinRAR</a> or <a href="https://www.7-zip.org" target="_blank">7-Zip</a>.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div className={styles.dlStack}>
|
||||||
|
<div className={styles.dlRowCard}>
|
||||||
|
<div className={styles.dlRowInfo}>
|
||||||
|
<h4>S300 MANAGER</h4>
|
||||||
|
<p>Native tuning software environment.</p>
|
||||||
|
<span className={styles.versionTag}>PRIMARY GUI</span>
|
||||||
|
</div>
|
||||||
|
<a href="/files/S300Setup.rar" className={styles.dlBtn}>
|
||||||
|
<Download size={18} />
|
||||||
|
DOWNLOAD
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className={styles.dlRowCard}>
|
||||||
|
<div className={styles.dlRowInfo}>
|
||||||
|
<h4>HTS 2.15</h4>
|
||||||
|
<p>Ostrich 2 Protocol mapping software.</p>
|
||||||
|
<span className={styles.versionTag}>LEGACY COM</span>
|
||||||
|
</div>
|
||||||
|
<a href="/files/HTSSetup.rar" className={styles.dlBtn}>
|
||||||
|
<Download size={18} />
|
||||||
|
DOWNLOAD
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
253
src/components/Sensor.module.css
Normal file
@ -0,0 +1,253 @@
|
|||||||
|
.section {
|
||||||
|
padding: 100px 0;
|
||||||
|
background-color: var(--background);
|
||||||
|
}
|
||||||
|
|
||||||
|
.container {
|
||||||
|
max-width: 1400px;
|
||||||
|
width: 100%;
|
||||||
|
margin: 0 auto;
|
||||||
|
padding: 0 4rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.productGrid {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 1fr 1fr;
|
||||||
|
gap: 5rem;
|
||||||
|
align-items: center;
|
||||||
|
margin-bottom: 100px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.imageMain {
|
||||||
|
position: relative;
|
||||||
|
border-radius: 12px;
|
||||||
|
background: radial-gradient(circle at center, rgba(255, 255, 255, 0.05) 0%, transparent 80%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.imagePlaceholder {
|
||||||
|
position: relative;
|
||||||
|
width: 100%;
|
||||||
|
height: 500px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sensorImg {
|
||||||
|
width: 80%;
|
||||||
|
height: auto;
|
||||||
|
object-fit: contain;
|
||||||
|
filter: drop-shadow(0 0 50px rgba(0, 0, 0, 0.5));
|
||||||
|
}
|
||||||
|
|
||||||
|
.label {
|
||||||
|
font-size: 0.75rem;
|
||||||
|
font-weight: 800;
|
||||||
|
color: #555;
|
||||||
|
letter-spacing: 0.2rem;
|
||||||
|
display: block;
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.title {
|
||||||
|
font-size: clamp(3rem, 7vw, 6rem);
|
||||||
|
font-weight: 900;
|
||||||
|
line-height: 0.85;
|
||||||
|
letter-spacing: -0.05em;
|
||||||
|
margin-bottom: 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.red {
|
||||||
|
color: var(--primary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.description {
|
||||||
|
font-size: 1.1rem;
|
||||||
|
color: #aaa;
|
||||||
|
margin-bottom: 3rem;
|
||||||
|
line-height: 1.6;
|
||||||
|
}
|
||||||
|
|
||||||
|
.compLabel {
|
||||||
|
font-size: 0.65rem;
|
||||||
|
color: #444;
|
||||||
|
font-weight: 900;
|
||||||
|
letter-spacing: 0.1em;
|
||||||
|
display: block;
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tags {
|
||||||
|
display: flex;
|
||||||
|
gap: 1rem;
|
||||||
|
margin-bottom: 3rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tags span {
|
||||||
|
font-size: 0.65rem;
|
||||||
|
font-weight: 900;
|
||||||
|
color: #fff;
|
||||||
|
background-color: #111;
|
||||||
|
padding: 0.5rem 1rem;
|
||||||
|
border: 1px solid #222;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.purchaseBox {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 3rem;
|
||||||
|
border-top: 1px solid #1a1a1a;
|
||||||
|
padding-top: 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.msrp {
|
||||||
|
font-size: 0.65rem;
|
||||||
|
color: #444;
|
||||||
|
font-weight: 900;
|
||||||
|
letter-spacing: 0.1em;
|
||||||
|
display: block;
|
||||||
|
margin-bottom: 0.3rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.amount {
|
||||||
|
font-size: 2.5rem;
|
||||||
|
font-weight: 900;
|
||||||
|
letter-spacing: -0.05em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btnAction {
|
||||||
|
background-color: var(--primary);
|
||||||
|
color: white;
|
||||||
|
padding: 1.2rem 2.5rem;
|
||||||
|
border-radius: 4px;
|
||||||
|
font-size: 0.85rem;
|
||||||
|
font-weight: 900;
|
||||||
|
letter-spacing: 0.1em;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 1.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.specsGrid {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 1fr 1fr 1.2fr;
|
||||||
|
gap: 3rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.specsCol, .specsColMiddle {
|
||||||
|
background-color: #0c0c0c;
|
||||||
|
border: 1px solid #1a1a1a;
|
||||||
|
padding: 3rem;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.specsColMiddle {
|
||||||
|
border-left: 2px solid var(--primary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.colTitle {
|
||||||
|
font-size: 1.1rem;
|
||||||
|
font-weight: 900;
|
||||||
|
margin-bottom: 2rem;
|
||||||
|
letter-spacing: -0.02em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.specItem {
|
||||||
|
margin-bottom: 1.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.specName {
|
||||||
|
font-size: 0.65rem;
|
||||||
|
color: #555;
|
||||||
|
font-weight: 900;
|
||||||
|
letter-spacing: 0.05em;
|
||||||
|
display: block;
|
||||||
|
margin-bottom: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.specVal {
|
||||||
|
font-size: 1.2rem;
|
||||||
|
font-weight: 700;
|
||||||
|
margin-bottom: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.specBar {
|
||||||
|
height: 2px;
|
||||||
|
background-color: #222;
|
||||||
|
border-radius: 1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.specFill {
|
||||||
|
height: 100%;
|
||||||
|
background-color: var(--primary);
|
||||||
|
border-radius: 1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dataRow {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
margin-bottom: 1.5rem;
|
||||||
|
font-size: 0.85rem;
|
||||||
|
border-bottom: 1px solid #1a1a1a;
|
||||||
|
padding-bottom: 0.8rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dataRow span {
|
||||||
|
color: #888;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dataRow strong {
|
||||||
|
font-weight: 800;
|
||||||
|
}
|
||||||
|
|
||||||
|
.downloadBox {
|
||||||
|
display: flex;
|
||||||
|
gap: 1.5rem;
|
||||||
|
align-items: flex-start;
|
||||||
|
margin-top: 3rem;
|
||||||
|
font-size: 0.7rem;
|
||||||
|
color: #555;
|
||||||
|
font-weight: 700;
|
||||||
|
line-height: 1.4;
|
||||||
|
}
|
||||||
|
|
||||||
|
.colPara {
|
||||||
|
font-size: 0.9rem;
|
||||||
|
color: #aaa;
|
||||||
|
line-height: 1.6;
|
||||||
|
margin-bottom: 3rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.proTip {
|
||||||
|
background-color: #0d0d0d;
|
||||||
|
border: 1px solid #222;
|
||||||
|
padding: 1.5rem;
|
||||||
|
display: flex;
|
||||||
|
gap: 1.5rem;
|
||||||
|
align-items: flex-start;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tipContent strong {
|
||||||
|
display: block;
|
||||||
|
font-size: 0.65rem;
|
||||||
|
color: var(--primary);
|
||||||
|
font-weight: 900;
|
||||||
|
margin-bottom: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tipContent p {
|
||||||
|
font-size: 0.75rem;
|
||||||
|
color: #777;
|
||||||
|
line-height: 1.4;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 1024px) {
|
||||||
|
.productGrid {
|
||||||
|
grid-template-columns: 1fr;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
.specsGrid {
|
||||||
|
grid-template-columns: 1fr;
|
||||||
|
}
|
||||||
|
}
|
||||||
126
src/components/Sensor.tsx
Normal file
@ -0,0 +1,126 @@
|
|||||||
|
'use client';
|
||||||
|
|
||||||
|
import { motion } from 'framer-motion';
|
||||||
|
import Image from 'next/image';
|
||||||
|
import { ShoppingCart, FileText, Settings, ShieldCheck, Activity } from 'lucide-react';
|
||||||
|
import styles from './Sensor.module.css';
|
||||||
|
|
||||||
|
export default function Sensor() {
|
||||||
|
return (
|
||||||
|
<section className={styles.section}>
|
||||||
|
<div className={styles.container}>
|
||||||
|
<div className={styles.productGrid}>
|
||||||
|
<motion.div
|
||||||
|
initial={{ opacity: 0, x: -50 }}
|
||||||
|
whileInView={{ opacity: 1, x: 0 }}
|
||||||
|
className={styles.imageMain}
|
||||||
|
>
|
||||||
|
<div className={styles.imagePlaceholder}>
|
||||||
|
<Image
|
||||||
|
src="/map_sensor.png"
|
||||||
|
alt="4BAR MAP Sensor"
|
||||||
|
width={800}
|
||||||
|
height={800}
|
||||||
|
className={styles.sensorImg}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</motion.div>
|
||||||
|
|
||||||
|
<div className={styles.productInfo}>
|
||||||
|
<span className={styles.label}>PRECISION ENGINEERING</span>
|
||||||
|
<h2 className={styles.title}>
|
||||||
|
4BAR MAP <br />
|
||||||
|
<span className={styles.red}>SENSOR</span>
|
||||||
|
</h2>
|
||||||
|
<p className={styles.description}>
|
||||||
|
Engineered for high-boost applications requiring surgical telemetry accuracy.
|
||||||
|
Rapid response frequency with +/- 0.01% deviation for consistent performance.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<div className={styles.compatibility}>
|
||||||
|
<span className={styles.compLabel}>DEVICE COMPATIBILITY</span>
|
||||||
|
<div className={styles.tags}>
|
||||||
|
<span>HONDA VERT KPRO</span>
|
||||||
|
<span>HONDA VERT PRECAN</span>
|
||||||
|
<span>HONDA VERT S300</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className={styles.purchaseBox}>
|
||||||
|
<div className={styles.price}>
|
||||||
|
<span className={styles.msrp}>MSRP</span>
|
||||||
|
<span className={styles.amount}>$149.00</span>
|
||||||
|
</div>
|
||||||
|
<button className={styles.btnAction}>
|
||||||
|
ADD TO SYSTEM <ShoppingCart size={18} />
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className={styles.specsGrid}>
|
||||||
|
<div className={styles.specsCol}>
|
||||||
|
<h3 className={styles.colTitle}>PERFORMANCE SPECS</h3>
|
||||||
|
<div className={styles.specItem}>
|
||||||
|
<span className={styles.specName}>PRESSURE RANGE</span>
|
||||||
|
<p className={styles.specVal}>0.1 - 4.0 BAR</p>
|
||||||
|
<div className={styles.specBar}><div className={styles.specFill} style={{width: '90%'}}></div></div>
|
||||||
|
</div>
|
||||||
|
<div className={styles.specItem}>
|
||||||
|
<span className={styles.specName}>VOLTAGE OUTPUT</span>
|
||||||
|
<p className={styles.specVal}>0.5V - 4.5V Linear</p>
|
||||||
|
</div>
|
||||||
|
<div className={styles.specItem}>
|
||||||
|
<span className={styles.specName}>THERMAL TOLERANCE</span>
|
||||||
|
<p className={styles.specVal}>-40°C to +125°C</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className={styles.specsColMiddle}>
|
||||||
|
<h3 className={styles.colTitle}>INSTALLATION DATA</h3>
|
||||||
|
<div className={styles.dataRow}>
|
||||||
|
<span>Thread Pitch</span>
|
||||||
|
<strong>1/8" NPT</strong>
|
||||||
|
</div>
|
||||||
|
<div className={styles.dataRow}>
|
||||||
|
<span>Connector Type</span>
|
||||||
|
<strong>3-PIN WEATHERPROOF</strong>
|
||||||
|
</div>
|
||||||
|
<div className={styles.dataRow}>
|
||||||
|
<span>Input Voltage</span>
|
||||||
|
<strong>5.0V DC</strong>
|
||||||
|
</div>
|
||||||
|
<div className={styles.dataRow}>
|
||||||
|
<span>Calibration</span>
|
||||||
|
<strong>PLUG & PLAY PROFILE</strong>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className={styles.downloadBox}>
|
||||||
|
<FileText size={20} className={styles.red} />
|
||||||
|
<div>
|
||||||
|
<p>DOWNLOAD WIRING DIAGRAM FOR PRECAN INTEGRATION (PDF 1.4MB)</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className={styles.specsCol}>
|
||||||
|
<h3 className={styles.colTitle}>HARDWARE LOGIC</h3>
|
||||||
|
<p className={styles.colPara}>
|
||||||
|
Our sensors utilize a solid-state piezoresistive design, encapsulated in
|
||||||
|
high-grade chemical-resistant composite housing. Unlike cheap alternatives,
|
||||||
|
the HondaVert 4Bar sensor maintains zero-point calibration even under extreme
|
||||||
|
engine bay heat-soak conditions.
|
||||||
|
</p>
|
||||||
|
<div className={styles.proTip}>
|
||||||
|
<Settings size={20} className={styles.red} />
|
||||||
|
<div className={styles.tipContent}>
|
||||||
|
<strong>PRO TIP:</strong>
|
||||||
|
<p>Ensure sensor is mounted above the manifold vacuum port to prevent fuel condensation buildup.</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
);
|
||||||
|
}
|
||||||
124
src/components/Telemetry.module.css
Normal file
@ -0,0 +1,124 @@
|
|||||||
|
.section {
|
||||||
|
padding: 150px 0;
|
||||||
|
background-color: #050505;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.container {
|
||||||
|
max-width: 1400px;
|
||||||
|
width: 100%;
|
||||||
|
margin: 0 auto;
|
||||||
|
padding: 0 4rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.grid {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 1fr 1fr;
|
||||||
|
gap: 6rem;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.left {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hudOverlay {
|
||||||
|
position: relative;
|
||||||
|
background: radial-gradient(circle at center, rgba(255, 0, 0, 0.05) 0%, transparent 80%);
|
||||||
|
border-radius: 12px;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hudImg {
|
||||||
|
width: 100%;
|
||||||
|
height: auto;
|
||||||
|
object-fit: cover;
|
||||||
|
border-radius: 8px;
|
||||||
|
filter: saturate(0.5) contrast(1.2);
|
||||||
|
}
|
||||||
|
|
||||||
|
.hudLabel {
|
||||||
|
position: absolute;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
padding: 2.5rem;
|
||||||
|
background: linear-gradient(to top, rgba(0, 0, 0, 0.9) 0%, transparent 100%);
|
||||||
|
border-bottom: 5px solid var(--primary);
|
||||||
|
border-bottom-left-radius: 4px;
|
||||||
|
border-bottom-right-radius: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hudLabel span {
|
||||||
|
font-size: 0.65rem;
|
||||||
|
font-weight: 900;
|
||||||
|
color: var(--primary);
|
||||||
|
letter-spacing: 0.1em;
|
||||||
|
display: block;
|
||||||
|
margin-bottom: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hudLabel h3 {
|
||||||
|
font-size: 1.5rem;
|
||||||
|
font-weight: 800;
|
||||||
|
}
|
||||||
|
|
||||||
|
.label {
|
||||||
|
font-size: 0.75rem;
|
||||||
|
font-weight: 800;
|
||||||
|
color: #555;
|
||||||
|
letter-spacing: 0.2rem;
|
||||||
|
display: block;
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.title {
|
||||||
|
font-size: clamp(2rem, 5vw, 4rem);
|
||||||
|
font-weight: 900;
|
||||||
|
line-height: 0.9;
|
||||||
|
letter-spacing: -0.04em;
|
||||||
|
margin-bottom: 4rem;
|
||||||
|
text-transform: uppercase;
|
||||||
|
}
|
||||||
|
|
||||||
|
.red {
|
||||||
|
color: var(--primary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.featureList {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 3.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.feature {
|
||||||
|
display: flex;
|
||||||
|
gap: 2rem;
|
||||||
|
align-items: flex-start;
|
||||||
|
}
|
||||||
|
|
||||||
|
.feature h3 {
|
||||||
|
font-size: 1.1rem;
|
||||||
|
font-weight: 900;
|
||||||
|
margin-bottom: 0.8rem;
|
||||||
|
letter-spacing: -0.02em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.feature p {
|
||||||
|
font-size: 0.85rem;
|
||||||
|
color: #777;
|
||||||
|
line-height: 1.6;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 1024px) {
|
||||||
|
.grid {
|
||||||
|
grid-template-columns: 1fr;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
.feature {
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
}
|
||||||
70
src/components/Telemetry.tsx
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
'use client';
|
||||||
|
|
||||||
|
import { motion } from 'framer-motion';
|
||||||
|
import Image from 'next/image';
|
||||||
|
import { LayoutDashboard, Database, Lock } from 'lucide-react';
|
||||||
|
import styles from './Telemetry.module.css';
|
||||||
|
|
||||||
|
export default function Telemetry() {
|
||||||
|
return (
|
||||||
|
<section className={styles.section}>
|
||||||
|
<div className={styles.container}>
|
||||||
|
<div className={styles.grid}>
|
||||||
|
<motion.div
|
||||||
|
initial={{ opacity: 0, x: -50 }}
|
||||||
|
whileInView={{ opacity: 1, x: 0 }}
|
||||||
|
className={styles.left}
|
||||||
|
>
|
||||||
|
<div className={styles.hudOverlay}>
|
||||||
|
<Image
|
||||||
|
src="/hud_telemetry.png"
|
||||||
|
alt="HUD Telemetry"
|
||||||
|
width={800}
|
||||||
|
height={600}
|
||||||
|
className={styles.hudImg}
|
||||||
|
/>
|
||||||
|
<div className={styles.hudLabel}>
|
||||||
|
<span>VISUAL INTERFACE</span>
|
||||||
|
<h3>Real-Time HUD Telemetry</h3>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</motion.div>
|
||||||
|
|
||||||
|
<div className={styles.right}>
|
||||||
|
<span className={styles.label}>PERFORMANCE DATA</span>
|
||||||
|
<h2 className={styles.title}>
|
||||||
|
ENGINEERED FOR THE <br />
|
||||||
|
<span className={styles.red}>TRACK</span>
|
||||||
|
</h2>
|
||||||
|
|
||||||
|
<div className={styles.featureList}>
|
||||||
|
<div className={styles.feature}>
|
||||||
|
<LayoutDashboard className={styles.red} size={24} />
|
||||||
|
<div className={styles.content}>
|
||||||
|
<h3>LIVE TABLE EDITING</h3>
|
||||||
|
<p>Modify fuel and ignition maps while the engine is running. Instant feedback for precise tuning results.</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className={styles.feature}>
|
||||||
|
<Database className={styles.red} size={24} />
|
||||||
|
<div className={styles.content}>
|
||||||
|
<h3>ADVANCED DATA LOGGING</h3>
|
||||||
|
<p>Capture up to 100 sensors simultaneously at high frequency. Export to CSV or view in our proprietary analyzer.</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className={styles.feature}>
|
||||||
|
<Lock className={styles.red} size={24} />
|
||||||
|
<div className={styles.content}>
|
||||||
|
<h3>FULL SECURITY CONTROL</h3>
|
||||||
|
<p>Immobilizer bypass and valet mode settings built-in. Protect your intellectual property with encrypted map files.</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
);
|
||||||
|
}
|
||||||
93
src/components/Testimonials.module.css
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
.section {
|
||||||
|
padding: 150px 0;
|
||||||
|
background-color: var(--background);
|
||||||
|
}
|
||||||
|
|
||||||
|
.container {
|
||||||
|
max-width: 1400px;
|
||||||
|
width: 100%;
|
||||||
|
margin: 0 auto;
|
||||||
|
padding: 0 4rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header {
|
||||||
|
text-align: center;
|
||||||
|
margin-bottom: 80px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.label {
|
||||||
|
font-size: 0.65rem;
|
||||||
|
font-weight: 900;
|
||||||
|
color: var(--primary);
|
||||||
|
letter-spacing: 0.15em;
|
||||||
|
margin-bottom: 2rem;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.title {
|
||||||
|
font-size: clamp(2rem, 5vw, 4rem);
|
||||||
|
font-weight: 900;
|
||||||
|
line-height: 1;
|
||||||
|
letter-spacing: -0.05em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.grid {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(auto-fit, minmax(380px, 1fr));
|
||||||
|
gap: 3rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card {
|
||||||
|
background-color: var(--secondary);
|
||||||
|
border: 1px solid var(--border);
|
||||||
|
padding: 4rem;
|
||||||
|
border-radius: 4px;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: space-between;
|
||||||
|
transition: all 0.2s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card:hover {
|
||||||
|
transform: translateY(-5px);
|
||||||
|
background-color: var(--neutral);
|
||||||
|
}
|
||||||
|
|
||||||
|
.stars {
|
||||||
|
display: flex;
|
||||||
|
gap: 0.4rem;
|
||||||
|
margin-bottom: 2.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.iconBox {
|
||||||
|
color: var(--primary);
|
||||||
|
opacity: 0.2;
|
||||||
|
margin-bottom: 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.quote {
|
||||||
|
font-size: 1.15rem;
|
||||||
|
color: #fff;
|
||||||
|
line-height: 1.7;
|
||||||
|
font-style: italic;
|
||||||
|
font-family: serif;
|
||||||
|
margin-bottom: 3.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.user strong {
|
||||||
|
font-size: 0.85rem;
|
||||||
|
font-weight: 900;
|
||||||
|
display: block;
|
||||||
|
margin-bottom: 0.4rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.user span {
|
||||||
|
font-size: 0.65rem;
|
||||||
|
font-weight: 800;
|
||||||
|
color: var(--primary);
|
||||||
|
letter-spacing: 0.1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
.card { padding: 3rem; }
|
||||||
|
}
|
||||||
66
src/components/Testimonials.tsx
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
'use client';
|
||||||
|
|
||||||
|
import { motion } from 'framer-motion';
|
||||||
|
import { Quote, Star } from 'lucide-react';
|
||||||
|
import styles from './Testimonials.module.css';
|
||||||
|
|
||||||
|
export default function Testimonials() {
|
||||||
|
const reviews = [
|
||||||
|
{
|
||||||
|
name: 'ALEX R.',
|
||||||
|
role: 'TIME ATTACK DRIVER',
|
||||||
|
quote: 'Switched to HondaVert V4.0 last season. The data fidelity and zero-latency logging changed how we approach our setup. Unmatched precision.',
|
||||||
|
stars: 5,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'KEVIN L.',
|
||||||
|
role: 'MASTER TUNER',
|
||||||
|
quote: 'As a tuner, I need reliability. HondaVert consistently delivers hardware that doesn\'t crash, software that is intuitive, and support that actually knows their stuff.',
|
||||||
|
stars: 5,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'SARAH M.',
|
||||||
|
role: 'DRAG RACING SPECIALIST',
|
||||||
|
quote: 'From real-time telemetry to custom launch control, the S300 Core has been rock solid for my turbo setup. Highly recommend for any serious build.',
|
||||||
|
stars: 5,
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
return (
|
||||||
|
<section className={styles.section}>
|
||||||
|
<div className={styles.container}>
|
||||||
|
<div className={styles.header}>
|
||||||
|
<span className={styles.label}>CLIENT FEEDBACK</span>
|
||||||
|
<h2 className={styles.title}>VOICES OF THE COMMUNITY</h2>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className={styles.grid}>
|
||||||
|
{reviews.map((item, i) => (
|
||||||
|
<motion.div
|
||||||
|
key={i}
|
||||||
|
className={styles.card}
|
||||||
|
initial={{ y: 30, opacity: 0 }}
|
||||||
|
whileInView={{ y: 0, opacity: 1 }}
|
||||||
|
viewport={{ once: true }}
|
||||||
|
transition={{ delay: i * 0.1 }}
|
||||||
|
>
|
||||||
|
<div className={styles.stars}>
|
||||||
|
{[...Array(item.stars)].map((_, i) => (
|
||||||
|
<Star key={i} size={14} fill="var(--primary)" color="var(--primary)" />
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
<div className={styles.iconBox}><Quote size={32} /></div>
|
||||||
|
<p className={styles.quote}>"{item.quote}"</p>
|
||||||
|
<div className={styles.footer}>
|
||||||
|
<div className={styles.user}>
|
||||||
|
<strong>{item.name}</strong>
|
||||||
|
<span>{item.role}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</motion.div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
);
|
||||||
|
}
|
||||||
92
src/components/WhyChooseUs.module.css
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
.section {
|
||||||
|
padding: 150px 0;
|
||||||
|
background-color: var(--neutral);
|
||||||
|
}
|
||||||
|
|
||||||
|
.container {
|
||||||
|
max-width: 1400px;
|
||||||
|
width: 100%;
|
||||||
|
margin: 0 auto;
|
||||||
|
padding: 0 4rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.grid {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 1fr 1.5fr;
|
||||||
|
gap: 8rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header {
|
||||||
|
max-width: 400px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.label {
|
||||||
|
font-size: 0.65rem;
|
||||||
|
font-weight: 900;
|
||||||
|
color: var(--primary);
|
||||||
|
letter-spacing: 0.15em;
|
||||||
|
margin-bottom: 2rem;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.title {
|
||||||
|
font-size: clamp(2rem, 5vw, 4rem);
|
||||||
|
font-weight: 900;
|
||||||
|
line-height: 1;
|
||||||
|
letter-spacing: -0.05em;
|
||||||
|
margin-bottom: 4rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header .desc {
|
||||||
|
font-size: 1.1rem;
|
||||||
|
color: #888;
|
||||||
|
line-height: 1.8;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reasons {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 1fr 1fr;
|
||||||
|
gap: 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card {
|
||||||
|
background-color: var(--secondary);
|
||||||
|
border: 1px solid var(--border);
|
||||||
|
padding: 3rem;
|
||||||
|
border-radius: 4px;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 2.5rem;
|
||||||
|
transition: all 0.3s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card:hover {
|
||||||
|
border-color: var(--primary);
|
||||||
|
transform: translateY(-5px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.iconBox {
|
||||||
|
color: var(--primary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.cardContent h3 {
|
||||||
|
font-size: 0.9rem;
|
||||||
|
font-weight: 900;
|
||||||
|
letter-spacing: 0.05em;
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cardContent p {
|
||||||
|
font-size: 0.85rem;
|
||||||
|
color: #666;
|
||||||
|
line-height: 1.6;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 1024px) {
|
||||||
|
.grid { grid-template-columns: 1fr; gap: 6rem; }
|
||||||
|
.header { max-width: none; }
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
.reasons { grid-template-columns: 1fr; }
|
||||||
|
}
|
||||||
65
src/components/WhyChooseUs.tsx
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
'use client';
|
||||||
|
|
||||||
|
import { motion } from 'framer-motion';
|
||||||
|
import { ShieldCheck, Zap, Cpu, Award } from 'lucide-react';
|
||||||
|
import styles from './WhyChooseUs.module.css';
|
||||||
|
|
||||||
|
export default function WhyChooseUs() {
|
||||||
|
const reasons = [
|
||||||
|
{
|
||||||
|
title: 'PRECISION HARDWARE',
|
||||||
|
desc: 'Our proprietary hardware is built to surgical standards in-house, ensuring zero-latency communication and unmatched reliability.',
|
||||||
|
icon: <Cpu size={32} />
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'RAPID SUPPORT',
|
||||||
|
desc: 'Expert technical assistance from actual enthusiasts. We speak your language and understand your build goals.',
|
||||||
|
icon: <Zap size={32} />
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'SECURE ENCRYPTION',
|
||||||
|
desc: 'Industry-leading AES-256 bit encryption ensures your custom tunes and intellectual property remain yours and yours alone.',
|
||||||
|
icon: <ShieldCheck size={32} />
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'PROVEN PERFORMANCE',
|
||||||
|
desc: 'Over 20 years of track records across time attack, drag, and circuit series worldwide.',
|
||||||
|
icon: <Award size={32} />
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
return (
|
||||||
|
<section className={styles.section}>
|
||||||
|
<div className={styles.container}>
|
||||||
|
<div className={styles.grid}>
|
||||||
|
<div className={styles.header}>
|
||||||
|
<span className={styles.label}>WHY HONDA VERT</span>
|
||||||
|
<h2 className={styles.title}>THE PRECISION DIFFERENCE</h2>
|
||||||
|
<p className={styles.desc}>
|
||||||
|
We don't manufacture parts; we craft engineering solutions for those who demand more than 'adequate' performance.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className={styles.reasons}>
|
||||||
|
{reasons.map((item, i) => (
|
||||||
|
<motion.div
|
||||||
|
key={i}
|
||||||
|
className={styles.card}
|
||||||
|
initial={{ opacity: 0, x: 20 }}
|
||||||
|
whileInView={{ opacity: 1, x: 0 }}
|
||||||
|
viewport={{ once: true }}
|
||||||
|
transition={{ delay: i * 0.1 }}
|
||||||
|
>
|
||||||
|
<div className={styles.iconBox}>{item.icon}</div>
|
||||||
|
<div className={styles.cardContent}>
|
||||||
|
<h3>{item.title}</h3>
|
||||||
|
<p>{item.desc}</p>
|
||||||
|
</div>
|
||||||
|
</motion.div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
);
|
||||||
|
}
|
||||||
81
src/lib/products.ts
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
export interface Product {
|
||||||
|
id: string;
|
||||||
|
name: string;
|
||||||
|
subtitle: string;
|
||||||
|
description: string;
|
||||||
|
image: string;
|
||||||
|
price: string;
|
||||||
|
version: string;
|
||||||
|
badge?: string;
|
||||||
|
specs: { label: string; value: string }[] | null;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const products: Product[] = [
|
||||||
|
{
|
||||||
|
id: 'kpro',
|
||||||
|
name: 'KPRO',
|
||||||
|
subtitle: 'UNLEASHED',
|
||||||
|
description: 'The ultimate tuning interface for Honda K-Series engines. Surgical precision meets raw performance. Full telemetry, real-time mapping, and total control over your ECU environment.',
|
||||||
|
image: '/ecu_kpro.png',
|
||||||
|
price: '$699.00',
|
||||||
|
version: 'PERFORMANCE ENGINEERING V4.0',
|
||||||
|
badge: 'LIVE TELEMETRY ENABLED',
|
||||||
|
specs: [
|
||||||
|
{ label: 'CAN RATE', value: '500kbps' },
|
||||||
|
{ label: 'CONNECTIVITY', value: 'USB 2.1 TYPE-C' },
|
||||||
|
{ label: 'STORAGE', value: '8GB FLASH' }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'canflash',
|
||||||
|
name: 'CAN',
|
||||||
|
subtitle: 'FLASH',
|
||||||
|
description: 'The definitive OBDII tuning interface for modern Honda/Acura platforms. Surgical data accuracy meets raw flashing speed.',
|
||||||
|
image: '/engine_bay.png',
|
||||||
|
price: '$549.00',
|
||||||
|
version: 'HIGH-PRECISION FLASHING INTERFACE',
|
||||||
|
specs: [
|
||||||
|
{ label: 'ENCRYPTION PROTOCOL', value: 'AES-256 BIT' },
|
||||||
|
{ label: 'INTERFACE TYPE', value: 'OBDII / J2534' }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'precan',
|
||||||
|
name: 'PRECAN',
|
||||||
|
subtitle: 'SERIES',
|
||||||
|
description: 'Surgical precision for legacy K-Series platforms. Our PreCAN interface bridges the gap between raw mechanical potential and digital mastery.',
|
||||||
|
image: '/precan_car.png',
|
||||||
|
price: '$599.00',
|
||||||
|
version: 'ENGINE MANAGEMENT SYSTEMS',
|
||||||
|
specs: [
|
||||||
|
{ label: 'LATENCY', value: 'ZERO' },
|
||||||
|
{ label: 'SUPPORT', value: 'MT + AT' }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 's300',
|
||||||
|
name: 'S300',
|
||||||
|
subtitle: 'CORE',
|
||||||
|
description: 'Professional grade engine management for OBD1 Honda ECUs. Full real-time tuning, data logging, and track-ready performance metrics.',
|
||||||
|
image: '/ecu_kpro.png',
|
||||||
|
price: '$499.00',
|
||||||
|
version: 'PRECISION TUNER SERIES',
|
||||||
|
specs: [
|
||||||
|
{ label: 'USB RATE', value: '98% OPTIMAL' },
|
||||||
|
{ label: 'LATENCY', value: '3.4MS' }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'map-sensor',
|
||||||
|
name: '4BAR MAP',
|
||||||
|
subtitle: 'SENSOR',
|
||||||
|
description: 'Engineered for high-boost applications requiring surgical telemetry accuracy. Rapid response frequency with +/- 0.01% deviation.',
|
||||||
|
image: '/map_sensor.png',
|
||||||
|
price: '$149.00',
|
||||||
|
version: 'PRECISION ENGINEERING',
|
||||||
|
specs: [
|
||||||
|
{ label: 'RANGE', value: '0.1-4.0 BAR' },
|
||||||
|
{ label: 'OUTPUT', value: '0.5V-4.5V' }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
];
|
||||||
34
tsconfig.json
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"target": "ES2017",
|
||||||
|
"lib": ["dom", "dom.iterable", "esnext"],
|
||||||
|
"allowJs": true,
|
||||||
|
"skipLibCheck": true,
|
||||||
|
"strict": true,
|
||||||
|
"noEmit": true,
|
||||||
|
"esModuleInterop": true,
|
||||||
|
"module": "esnext",
|
||||||
|
"moduleResolution": "bundler",
|
||||||
|
"resolveJsonModule": true,
|
||||||
|
"isolatedModules": true,
|
||||||
|
"jsx": "react-jsx",
|
||||||
|
"incremental": true,
|
||||||
|
"plugins": [
|
||||||
|
{
|
||||||
|
"name": "next"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"paths": {
|
||||||
|
"@/*": ["./src/*"]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"include": [
|
||||||
|
"next-env.d.ts",
|
||||||
|
"**/*.ts",
|
||||||
|
"**/*.tsx",
|
||||||
|
".next/types/**/*.ts",
|
||||||
|
".next/dev/types/**/*.ts",
|
||||||
|
"**/*.mts"
|
||||||
|
],
|
||||||
|
"exclude": ["node_modules"]
|
||||||
|
}
|
||||||