新規作成

This commit is contained in:
admin
2026-01-23 14:34:45 +09:00
commit e32ff0d9f6
28 changed files with 2739 additions and 0 deletions

3
.eslintrc.json Normal file
View File

@@ -0,0 +1,3 @@
{
"extends": "next/core-web-vitals"
}

10
.gitignore vendored Normal file
View File

@@ -0,0 +1,10 @@
node_modules/
.next/
out/
build/
.env.local
.env.*.local
.DS_Store
*.pem
.vscode/
.idea/

7
.prettierrc Normal file
View File

@@ -0,0 +1,7 @@
{
"semi": true,
"trailingComma": "es5",
"singleQuote": true,
"printWidth": 100,
"tabWidth": 2
}

75
README.md Normal file
View File

@@ -0,0 +1,75 @@
# 新日本テクノソリューションズ株式会社 公式ウェブサイト
日本のIT企業「新日本テクソリューションズ株式会社」の公式ウェブサイト。技術で持続可能な業務システムを構築することをミッションとしています。
## 技術スタック
- **フレームワーク**: Next.js 14
- **スタイリング**: Tailwind CSS
- **アニメーション**: Framer Motion
- **言語**: TypeScript
## ページ構成
### ホームページ
- **Hero セクション**: キャッチコピーと企業の価値提案
- **About**: 企業の強みと特徴
- **Expertise**: 5つの実務分野医療、物流、AI、会計、給与
- **Tech Stack**: 使用している技術スタック
- **Philosophy**: 企業理念と考え方
- **Who We Serve**: 対象となるクライアント
- **Footer**: 企業情報とリンク
## セットアップ方法
```bash
# 依存パッケージのインストール
npm install
# 開発サーバーの起動
npm run dev
# ビルド
npm run build
# 本番環境での実行
npm start
```
## 今後の拡張予定
- [ ] サービス詳細ページ
- [ ] ブログ機能
- [ ] お問い合わせフォーム
- [ ] キャリアページ
- [ ] 多言語対応(英語など)
- [ ] ダークモード以外のテーマ選択肢
## プロジェクト構成
```
src/
├── app/
│ ├── layout.tsx # ルートレイアウト
│ ├── page.tsx # ホームページ
│ └── globals.css # グローバルスタイル
├── components/
│ ├── Header.tsx # ナビゲーション
│ ├── Hero.tsx # ファーストビュー
│ ├── About.tsx # 企業概要
│ ├── Expertise.tsx # 実務経験
│ ├── TechStack.tsx # 技術スタック
│ ├── Philosophy.tsx # 企業理念
│ ├── WhoWeServe.tsx # 対象クライアント
│ └── Footer.tsx # フッター
```
## デザイン参考
Linear.app のモダンでクリーンなデザイン哲学を採用。
- ダークテーマ(グレー 950 をベースに)
- グラデーションテキスト(青→緑)
- スムーズなスクロールアニメーション
- ホバーエフェクトによるインタラクティビティ

5
next-env.d.ts vendored Normal file
View File

@@ -0,0 +1,5 @@
/// <reference types="next" />
/// <reference types="next/image-types/global" />
// NOTE: This file should not be edited
// see https://nextjs.org/docs/app/building-your-application/configuring/typescript for more information.

4
next.config.js Normal file
View File

@@ -0,0 +1,4 @@
/** @type {import('next').NextConfig} */
const nextConfig = {};
module.exports = nextConfig;

1666
package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

26
package.json Normal file
View File

@@ -0,0 +1,26 @@
{
"name": "njts-website",
"version": "0.1.0",
"private": true,
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start",
"lint": "next lint"
},
"dependencies": {
"react": "^18.2.0",
"react-dom": "^18.2.0",
"next": "^14.0.0",
"framer-motion": "^10.16.4"
},
"devDependencies": {
"typescript": "^5.3.3",
"@types/node": "^20.10.5",
"@types/react": "^18.2.45",
"@types/react-dom": "^18.2.18",
"autoprefixer": "^10.4.16",
"postcss": "^8.4.32",
"tailwindcss": "^3.4.1"
}
}

6
postcss.config.js Normal file
View File

@@ -0,0 +1,6 @@
module.exports = {
plugins: {
tailwindcss: {},
autoprefixer: {},
},
};

View File

@@ -0,0 +1,8 @@
<svg width="200" height="200" viewBox="0 0 200 200" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="200" height="200" fill="#1a1a2e"/>
<rect x="50" y="40" width="100" height="120" fill="none" stroke="#ec4899" stroke-width="2"/>
<line x1="50" y1="70" x2="150" y2="70" stroke="#ec4899" stroke-width="2"/>
<line x1="50" y1="100" x2="150" y2="100" stroke="#ec4899" stroke-width="2"/>
<line x1="50" y1="130" x2="150" y2="130" stroke="#ec4899" stroke-width="2"/>
<text x="100" y="190" font-size="12" fill="#e5e7eb" text-anchor="middle">会計システム</text>
</svg>

After

Width:  |  Height:  |  Size: 587 B

6
public/images/ai.svg Normal file
View File

@@ -0,0 +1,6 @@
<svg width="200" height="200" viewBox="0 0 200 200" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="200" height="200" fill="#1a1a2e"/>
<circle cx="100" cy="70" r="30" fill="#f59e0b" stroke="#f59e0b" stroke-width="2"/>
<path d="M 80 100 L 120 100 M 85 115 L 115 115 M 75 130 L 125 130" stroke="#f59e0b" stroke-width="3" stroke-linecap="round"/>
<text x="100" y="190" font-size="12" fill="#e5e7eb" text-anchor="middle">AI活用</text>
</svg>

After

Width:  |  Height:  |  Size: 460 B

View File

@@ -0,0 +1,8 @@
<svg width="200" height="200" viewBox="0 0 200 200" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="200" height="200" fill="#1a1a2e"/>
<circle cx="100" cy="50" r="25" fill="#60a5fa"/>
<rect x="80" y="85" width="40" height="60" fill="#60a5fa"/>
<circle cx="70" cy="165" r="8" fill="#60a5fa"/>
<circle cx="130" cy="165" r="8" fill="#60a5fa"/>
<text x="100" y="190" font-size="12" fill="#e5e7eb" text-anchor="middle">医療システム</text>
</svg>

After

Width:  |  Height:  |  Size: 471 B

View File

@@ -0,0 +1,55 @@
<svg width="800" height="400" viewBox="0 0 800 400" fill="none" xmlns="http://www.w3.org/2000/svg">
<defs>
<linearGradient id="gradientBg" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" style="stop-color:#1a3a52;stop-opacity:1" />
<stop offset="100%" style="stop-color:#0a1e2e;stop-opacity:1" />
</linearGradient>
</defs>
<rect width="800" height="400" fill="url(#gradientBg)"/>
<!-- Left side: Code/System visualization -->
<rect x="40" y="60" width="300" height="280" fill="none" stroke="#60a5fa" stroke-width="2" rx="8"/>
<text x="60" y="90" font-size="14" fill="#60a5fa" font-family="monospace">system.design</text>
<line x1="40" y1="100" x2="340" y2="100" stroke="#60a5fa" stroke-width="1" opacity="0.3"/>
<text x="60" y="130" font-size="12" fill="#34d399" font-family="monospace">class Infrastructure {</text>
<text x="80" y="155" font-size="12" fill="#e5e7eb" font-family="monospace">reliability: 99.9%</text>
<text x="80" y="180" font-size="12" fill="#e5e7eb" font-family="monospace">scalability: adaptive</text>
<text x="80" y="205" font-size="12" fill="#e5e7eb" font-family="monospace">maintenance: easy</text>
<text x="80" y="230" font-size="12" fill="#e5e7eb" font-family="monospace">security: enterprise</text>
<text x="60" y="260" font-size="12" fill="#34d399" font-family="monospace">}</text>
<!-- Right side: Technology stack -->
<g>
<!-- Database -->
<circle cx="580" cy="100" r="35" fill="none" stroke="#f59e0b" stroke-width="2"/>
<text x="565" y="110" font-size="18">📊</text>
<text x="520" y="155" font-size="13" fill="#f59e0b" text-anchor="middle">Database</text>
<!-- API -->
<circle cx="720" cy="100" r="35" fill="none" stroke="#ec4899" stroke-width="2"/>
<text x="705" y="110" font-size="18">🔌</text>
<text x="720" y="155" font-size="13" fill="#ec4899" text-anchor="middle">API</text>
<!-- Backend -->
<circle cx="580" cy="240" r="35" fill="none" stroke="#8b5cf6" stroke-width="2"/>
<text x="565" y="250" font-size="18">⚙️</text>
<text x="550" y="295" font-size="13" fill="#8b5cf6" text-anchor="middle">Backend</text>
<!-- Frontend -->
<circle cx="720" cy="240" r="35" fill="none" stroke="#34d399" stroke-width="2"/>
<text x="705" y="250" font-size="18">🎨</text>
<text x="720" y="295" font-size="13" fill="#34d399" text-anchor="middle">Frontend</text>
<!-- Connecting lines -->
<line x1="615" y1="120" x2="685" y2="120" stroke="#60a5fa" stroke-width="2" opacity="0.5"/>
<line x1="615" y1="260" x2="685" y2="260" stroke="#60a5fa" stroke-width="2" opacity="0.5"/>
<line x1="650" y1="135" x2="650" y2="225" stroke="#60a5fa" stroke-width="2" opacity="0.5"/>
</g>
<!-- Bottom text -->
<text x="400" y="370" font-size="14" fill="#a0aec0" text-anchor="middle">
設計から運用まで一貫したサポート
</text>
</svg>

After

Width:  |  Height:  |  Size: 2.9 KiB

View File

@@ -0,0 +1,9 @@
<svg width="200" height="200" viewBox="0 0 200 200" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="200" height="200" fill="#1a1a2e"/>
<rect x="60" y="40" width="80" height="50" fill="#34d399" stroke="#34d399" stroke-width="2"/>
<circle cx="70" cy="110" r="12" fill="#34d399"/>
<circle cx="100" cy="110" r="12" fill="#34d399"/>
<circle cx="130" cy="110" r="12" fill="#34d399"/>
<rect x="40" y="140" width="120" height="30" fill="#34d399" stroke="#34d399" stroke-width="2"/>
<text x="100" y="190" font-size="12" fill="#e5e7eb" text-anchor="middle">物流システム</text>
</svg>

After

Width:  |  Height:  |  Size: 606 B

View File

@@ -0,0 +1,9 @@
<svg width="200" height="200" viewBox="0 0 200 200" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="200" height="200" fill="#1a1a2e"/>
<circle cx="100" cy="60" r="20" fill="#8b5cf6" stroke="#8b5cf6" stroke-width="2"/>
<rect x="60" y="100" width="80" height="50" fill="#8b5cf6" stroke="#8b5cf6" stroke-width="2" rx="4"/>
<circle cx="80" cy="140" r="6" fill="#1a1a2e"/>
<circle cx="100" cy="140" r="6" fill="#1a1a2e"/>
<circle cx="120" cy="140" r="6" fill="#1a1a2e"/>
<text x="100" y="190" font-size="12" fill="#e5e7eb" text-anchor="middle">給与システム</text>
</svg>

After

Width:  |  Height:  |  Size: 598 B

19
src/app/layout.tsx Normal file
View File

@@ -0,0 +1,19 @@
import type { Metadata } from 'next';
import '@/globals.css';
export const metadata: Metadata = {
title: '新日本テクノソリューションズ株式会社 - 技術で、持続可能な業務システムを構築する',
description:
'新日本テクソリューションズ株式会社は、システム構成力・業務理解力・長期運用を前提とした設計を強みとする技術志向のIT企業です。',
};
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html lang="ja">
<head>
<meta charSet="utf-8" />
</head>
<body>{children}</body>
</html>
);
}

30
src/app/page.tsx Normal file
View File

@@ -0,0 +1,30 @@
import type { Metadata } from 'next';
import Header from '@/components/Header';
import Hero from '@/components/Hero';
import About from '@/components/About';
import Expertise from '@/components/Expertise';
import TechStack from '@/components/TechStack';
import Philosophy from '@/components/Philosophy';
import WhoWeServe from '@/components/WhoWeServe';
import Footer from '@/components/Footer';
export const metadata: Metadata = {
title: '新日本テクノソリューションズ株式会社 - 技術で、持続可能な業務システムを構築する',
description:
'新日本テクソリューションズ株式会社は、システム構成力・業務理解力・長期運用を前提とした設計を強みとする技術志向のIT企業です。',
};
export default function Home() {
return (
<main className="min-h-screen bg-gray-950 text-white overflow-hidden">
<Header />
<Hero />
<About />
<Expertise />
<TechStack />
<Philosophy />
<WhoWeServe />
<Footer />
</main>
);
}

101
src/components/About.tsx Normal file
View File

@@ -0,0 +1,101 @@
'use client';
import { motion } from 'framer-motion';
const containerVariants = {
hidden: { opacity: 0 },
visible: {
opacity: 1,
transition: {
staggerChildren: 0.1,
},
},
};
const itemVariants = {
hidden: { opacity: 0, y: 20 },
visible: {
opacity: 1,
y: 0,
transition: { duration: 0.8 },
},
};
export default function About() {
return (
<section className="py-20 px-4 sm:px-6 lg:px-8 bg-gray-900/50">
<motion.div
className="max-w-4xl mx-auto"
variants={containerVariants}
initial="hidden"
whileInView="visible"
viewport={{ once: true, margin: '-100px' }}
>
<motion.h2
className="text-4xl sm:text-5xl font-bold mb-12 text-center"
variants={itemVariants}
>
</motion.h2>
<motion.div className="space-y-6" variants={containerVariants}>
<motion.p className="text-lg text-gray-300 leading-relaxed" variants={itemVariants}>
</motion.p>
<motion.p className="text-lg text-gray-300 leading-relaxed" variants={itemVariants}>
AI活用など
</motion.p>
<motion.div
className="grid grid-cols-1 md:grid-cols-2 gap-8 mt-12"
variants={containerVariants}
>
<motion.div
className="p-6 rounded-lg border border-gray-700 hover:border-blue-500 transition-colors"
variants={itemVariants}
>
<p className="text-gray-400 text-sm mb-2"></p>
<h3 className="text-xl font-semibold mb-3"></h3>
<p className="text-gray-300">
</p>
</motion.div>
<motion.div
className="p-6 rounded-lg border border-gray-700 hover:border-blue-500 transition-colors"
variants={itemVariants}
>
<p className="text-gray-400 text-sm mb-2"></p>
<h3 className="text-xl font-semibold mb-3"></h3>
<p className="text-gray-300">簿</p>
</motion.div>
<motion.div
className="p-6 rounded-lg border border-gray-700 hover:border-green-500 transition-colors"
variants={itemVariants}
>
<p className="text-gray-400 text-sm mb-2"></p>
<h3 className="text-xl font-semibold mb-3"></h3>
<p className="text-gray-300">
</p>
</motion.div>
<motion.div
className="p-6 rounded-lg border border-gray-700 hover:border-green-500 transition-colors"
variants={itemVariants}
>
<p className="text-gray-400 text-sm mb-2"></p>
<h3 className="text-xl font-semibold mb-3"></h3>
<p className="text-gray-300">
</p>
</motion.div>
</motion.div>
</motion.div>
</motion.div>
</section>
);
}

View File

@@ -0,0 +1,147 @@
'use client';
import Image from 'next/image';
import { motion } from 'framer-motion';
const containerVariants = {
hidden: { opacity: 0 },
visible: {
opacity: 1,
transition: {
staggerChildren: 0.1,
},
},
};
const itemVariants = {
hidden: { opacity: 0, y: 20 },
visible: {
opacity: 1,
y: 0,
transition: { duration: 0.8 },
},
};
const expertise = [
{
emoji: '🏥',
title: '医療システム分野',
description: '高い信頼性と複雑な業務ロジックが求められる医療分野での豊富な実績',
image: '/images/healthcare.svg',
items: [
'医療系業務システム・データベースの設計・保守',
'複雑なストアドプロシージャやバッチ処理の解析・改善',
'データ不整合・重複データ・依存関係問題の調査',
'既存 VB / .NET システムの保守・改修・原因分析',
'医療システムの環境移行、バージョンアップ、緊急復旧対応',
],
},
{
emoji: '🚚',
title: '物流・業務システム',
description: '大量データ・複雑な連携・長年の運用履歴への対応',
image: '/images/logistics.svg',
items: [
'受注・在庫・入出庫・ロット管理などの業務ロジック整理',
'複数システム間のデータ連携・整合性確保',
'SQL / ストアドプロシージャ / 定期バッチの整理・最適化',
'Main / Release など既存フォルダ構成・運用ルールの再整理',
'DLL 差分分析・依存関係の可視化',
],
},
{
emoji: '🤖',
title: 'AI・インテリジェント活用',
description: 'AIを目的ではなく手段として捉えた実用的な導入',
image: '/images/ai.svg',
items: [
'ローカル/オンプレミス環境での AILLM構築',
'社内向け AI アシスタント(ログ・仕様・業務知識検索)',
'既存業務システム・データベースとの AI 連携',
'クラウド依存しない、安全で制御可能な AI 導入',
],
},
{
emoji: '📊',
title: '会計・財務システム',
description: '日本の中小企業における実務ベースの会計処理',
image: '/images/accounting.svg',
items: [
'勘定科目マスタ設計',
'仕訳・試算表・期首残高管理',
'消費税(税抜・税込)の正確な取り扱い',
'銀行手数料、利息、税金の適切な仕訳',
'税理士と共有可能な会計ロジック設計',
],
},
{
emoji: '💴',
title: '給与・人事システム',
description: '法律・数値計算・システム設計が密接に絡む分野',
image: '/images/payroll.svg',
items: [
'源泉所得税(扶養判定・年度切替)',
'健康保険・介護保険・厚生年金',
'子ども・子育て拠出金',
'月給・賞与・年末調整を考慮した設計',
'設定変更・履歴管理が可能な給与ロジック',
],
},
];
export default function Expertise() {
return (
<section className="py-20 px-4 sm:px-6 lg:px-8">
<motion.div
className="max-w-6xl mx-auto"
variants={containerVariants}
initial="hidden"
whileInView="visible"
viewport={{ once: true, margin: '-100px' }}
>
<motion.h2
className="text-4xl sm:text-5xl font-bold mb-16 text-center"
variants={itemVariants}
>
</motion.h2>
<motion.div
className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8"
variants={containerVariants}
>
{expertise.map((exp, index) => (
<motion.div
key={index}
className="p-8 rounded-lg border border-gray-700 hover:border-blue-500 transition-all hover:shadow-lg hover:shadow-blue-500/10 group"
variants={itemVariants}
>
<div className="mb-4 h-32 relative overflow-hidden rounded-lg bg-gray-800">
<Image
src={exp.image}
alt={exp.title}
width={200}
height={200}
className="w-full h-full object-cover transform group-hover:scale-105 transition-transform"
/>
</div>
<div className="text-4xl mb-4 transform group-hover:scale-110 transition-transform">
{exp.emoji}
</div>
<h3 className="text-xl font-semibold mb-2">{exp.title}</h3>
<p className="text-gray-400 text-sm mb-4">{exp.description}</p>
<ul className="space-y-2">
{exp.items.map((item, i) => (
<li key={i} className="text-sm text-gray-400 flex items-start">
<span className="mr-3 text-blue-400"></span>
<span>{item}</span>
</li>
))}
</ul>
</motion.div>
))}
</motion.div>
</motion.div>
</section>
);
}

98
src/components/Footer.tsx Normal file
View File

@@ -0,0 +1,98 @@
'use client';
import { motion } from 'framer-motion';
export default function Footer() {
return (
<footer className="bg-gray-950 border-t border-gray-800 py-12 px-4 sm:px-6 lg:px-8">
<motion.div
className="max-w-6xl mx-auto"
initial={{ opacity: 0 }}
whileInView={{ opacity: 1 }}
transition={{ duration: 0.8 }}
viewport={{ once: true }}
>
<div className="grid grid-cols-1 md:grid-cols-4 gap-8 mb-12">
<div>
<h3 className="text-lg font-bold mb-2 gradient-text">
</h3>
<div className="text-base font-semibold text-gray-300 mb-1">
New Japan Techno Solutions Inc.
</div>
<p className="text-gray-400 text-sm"></p>
</div>
<div>
<h4 className="font-semibold mb-4 text-white"></h4>
<ul className="space-y-2 text-gray-400 text-sm">
<li>
<a href="#" className="hover:text-white transition-colors">
</a>
</li>
<li>
<a href="#" className="hover:text-white transition-colors">
</a>
</li>
<li>
<a href="#" className="hover:text-white transition-colors">
</a>
</li>
</ul>
</div>
<div>
<h4 className="font-semibold mb-4 text-white"></h4>
<ul className="space-y-2 text-gray-400 text-sm">
<li>
<a href="#" className="hover:text-white transition-colors">
</a>
</li>
<li>
<a href="#" className="hover:text-white transition-colors">
</a>
</li>
<li>
<a href="#" className="hover:text-white transition-colors">
</a>
</li>
</ul>
</div>
<div>
<h4 className="font-semibold mb-4 text-white"></h4>
<ul className="space-y-2 text-gray-400 text-sm">
<li>
<a href="mailto:contact@njts.jp" className="hover:text-white transition-colors">
contact@njts.jp
</a>
</li>
<li>
<a href="#" className="hover:text-white transition-colors">
</a>
</li>
</ul>
</div>
</div>
<div className="border-t border-gray-800 pt-8">
<div className="flex flex-col md:flex-row justify-between items-center text-gray-400 text-sm">
<p>&copy; 2024 NJTS. All rights reserved.</p>
<div className="flex gap-6 mt-4 md:mt-0">
<a href="#" className="hover:text-white transition-colors">
</a>
<a href="#" className="hover:text-white transition-colors">
</a>
</div>
</div>
</div>
</motion.div>
</footer>
);
}

45
src/components/Header.tsx Normal file
View File

@@ -0,0 +1,45 @@
'use client';
import { motion } from 'framer-motion';
export default function Header() {
return (
<motion.header
className="fixed top-0 left-0 right-0 z-50 bg-gray-900/80 backdrop-blur-md border-b border-gray-800"
initial={{ y: -100 }}
animate={{ y: 0 }}
transition={{ duration: 0.5 }}
>
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-4 flex justify-between items-center">
<motion.div
className="flex flex-col items-start sm:items-center"
whileHover={{ scale: 1.03 }}
>
<span className="text-xl sm:text-2xl font-bold gradient-text">
</span>
<span className="text-base sm:text-lg font-semibold text-gray-300 mt-1">
New Japan Techno Solutions Inc.
</span>
</motion.div>
<nav className="hidden md:flex gap-8">
<a href="#about" className="text-gray-300 hover:text-white transition-colors">
</a>
<a href="#expertise" className="text-gray-300 hover:text-white transition-colors">
</a>
<a href="#technology" className="text-gray-300 hover:text-white transition-colors">
</a>
<a href="#contact" className="text-gray-300 hover:text-white transition-colors">
</a>
</nav>
<button className="px-6 py-2 bg-blue-500 hover:bg-blue-600 rounded-lg font-semibold transition-colors text-sm">
Contact
</button>
</div>
</motion.header>
);
}

79
src/components/Hero.tsx Normal file
View File

@@ -0,0 +1,79 @@
'use client';
import Image from 'next/image';
import { motion } from 'framer-motion';
const containerVariants = {
hidden: { opacity: 0 },
visible: {
opacity: 1,
transition: {
staggerChildren: 0.1,
delayChildren: 0.3,
},
},
};
const itemVariants = {
hidden: { opacity: 0, y: 20 },
visible: {
opacity: 1,
y: 0,
transition: { duration: 0.8, ease: 'easeOut' },
},
};
export default function Hero() {
return (
<section className="min-h-screen flex items-center justify-center pt-20 pb-20 px-4 sm:px-6 lg:px-8">
<motion.div
className="max-w-4xl mx-auto text-center"
variants={containerVariants}
initial="hidden"
whileInView="visible"
viewport={{ once: true }}
>
<motion.h1
className="text-5xl sm:text-6xl lg:text-7xl font-bold mb-6 leading-tight"
variants={itemVariants}
>
<span className="gradient-text"></span>
<br />
<span></span>
<br />
<span className="gradient-text"></span>
</motion.h1>
<motion.p
className="text-lg sm:text-xl text-gray-400 mb-8 leading-relaxed"
variants={itemVariants}
>
<br />
IT企業です
</motion.p>
<motion.div className="flex gap-4 justify-center flex-wrap mb-12" variants={itemVariants}>
<button className="px-8 py-3 bg-blue-500 hover:bg-blue-600 rounded-lg font-semibold transition-colors">
</button>
<button className="px-8 py-3 border border-gray-600 hover:border-gray-400 rounded-lg font-semibold transition-colors">
</button>
</motion.div>
<motion.div
className="mt-12 rounded-lg overflow-hidden border border-gray-700 shadow-2xl"
variants={itemVariants}
>
<div className="relative w-full h-64 sm:h-80 md:h-96 bg-gray-800">
<Image
src="/images/hero-image.svg"
alt="NJTS - システム構築"
fill
className="object-cover"
priority
/>
</div>
</motion.div>
</motion.div>
</section>
);
}

View File

@@ -0,0 +1,75 @@
'use client';
import { motion } from 'framer-motion';
const containerVariants = {
hidden: { opacity: 0 },
visible: {
opacity: 1,
transition: {
staggerChildren: 0.1,
},
},
};
const itemVariants = {
hidden: { opacity: 0, y: 20 },
visible: {
opacity: 1,
y: 0,
transition: { duration: 0.8 },
},
};
const principles = [
{
title: '一度きりの納品は行いません',
description:
'システムは「作って終わり」ではなく、「使われ続けて初めて価値を持つ」と考えています。',
},
{
title: '技術用語だけを並べません',
description: 'お客様の業務を理解し、実用的なソリューションを提供します。',
},
{
title: '業務を理解しない開発はしません',
description: '要件定義から運用改善まで、業務プロセスを深く理解した開発を行います。',
},
];
export default function Philosophy() {
return (
<section className="py-20 px-4 sm:px-6 lg:px-8">
<motion.div
className="max-w-4xl mx-auto"
variants={containerVariants}
initial="hidden"
whileInView="visible"
viewport={{ once: true, margin: '-100px' }}
>
<motion.h2
className="text-4xl sm:text-5xl font-bold mb-16 text-center"
variants={itemVariants}
>
🌱
</motion.h2>
<motion.div className="grid grid-cols-1 md:grid-cols-3 gap-8" variants={containerVariants}>
{principles.map((principle, index) => (
<motion.div
key={index}
className="p-8 rounded-lg border border-gray-700 hover:border-blue-500 transition-colors group"
variants={itemVariants}
>
<div className="text-3xl mb-4 font-bold text-blue-400 group-hover:scale-110 transition-transform origin-left">
{index + 1}
</div>
<h3 className="text-lg font-semibold mb-3">{principle.title}</h3>
<p className="text-gray-400 leading-relaxed">{principle.description}</p>
</motion.div>
))}
</motion.div>
</motion.div>
</section>
);
}

View File

@@ -0,0 +1,79 @@
'use client';
import { motion } from 'framer-motion';
const containerVariants = {
hidden: { opacity: 0 },
visible: {
opacity: 1,
transition: {
staggerChildren: 0.1,
},
},
};
const itemVariants = {
hidden: { opacity: 0, y: 20 },
visible: {
opacity: 1,
y: 0,
transition: { duration: 0.8 },
},
};
const technologies = [
{ category: 'バックエンド', items: ['FastAPI', 'Python', '.NET'] },
{ category: 'データベース', items: ['PostgreSQL', 'SQL Server'] },
{ category: 'インフラ', items: ['Docker', '自社サーバー', 'NAS'] },
{ category: 'Web', items: ['API 中心のフロント・バック分離構成', 'REST API'] },
{ category: 'セキュリティ', items: ['HTTPS', '証明書管理', 'リバースプロキシ'] },
];
export default function TechStack() {
return (
<section className="py-20 px-4 sm:px-6 lg:px-8 bg-gray-900/50">
<motion.div
className="max-w-4xl mx-auto"
variants={containerVariants}
initial="hidden"
whileInView="visible"
viewport={{ once: true, margin: '-100px' }}
>
<motion.h2
className="text-4xl sm:text-5xl font-bold mb-16 text-center"
variants={itemVariants}
>
🧩
</motion.h2>
<motion.p className="text-center text-gray-300 mb-12 text-lg" variants={itemVariants}>
<br />
</motion.p>
<motion.div className="grid grid-cols-1 md:grid-cols-2 gap-6" variants={containerVariants}>
{technologies.map((tech, index) => (
<motion.div
key={index}
className="p-6 rounded-lg border border-gray-700 hover:border-green-500 transition-colors"
variants={itemVariants}
>
<h3 className="font-semibold text-lg mb-4 text-green-400">{tech.category}</h3>
<div className="flex flex-wrap gap-2">
{tech.items.map((item, i) => (
<span
key={i}
className="px-3 py-1 bg-gray-800 rounded-full text-sm text-gray-300 border border-gray-700"
>
{item}
</span>
))}
</div>
</motion.div>
))}
</motion.div>
</motion.div>
</section>
);
}

View File

@@ -0,0 +1,76 @@
'use client';
import { motion } from 'framer-motion';
const containerVariants = {
hidden: { opacity: 0 },
visible: {
opacity: 1,
transition: {
staggerChildren: 0.1,
},
},
};
const itemVariants = {
hidden: { opacity: 0, y: 20 },
visible: {
opacity: 1,
y: 0,
transition: { duration: 0.8 },
},
};
const customers = [
'既存システムが複雑化し、保守に困っている企業',
'医療・物流・基幹業務システムを長く使い続けたい組織',
'会計・給与を自社業務に合わせて最適化したい企業',
'短期外注ではなく、長期的なパートナーを求める方',
];
export default function WhoWeServe() {
return (
<section className="py-20 px-4 sm:px-6 lg:px-8 bg-gray-900/50">
<motion.div
className="max-w-4xl mx-auto"
variants={containerVariants}
initial="hidden"
whileInView="visible"
viewport={{ once: true, margin: '-100px' }}
>
<motion.h2
className="text-4xl sm:text-5xl font-bold mb-16 text-center"
variants={itemVariants}
>
🤝
</motion.h2>
<motion.div className="grid grid-cols-1 md:grid-cols-2 gap-6" variants={containerVariants}>
{customers.map((customer, index) => (
<motion.div
key={index}
className="p-6 rounded-lg border border-gray-700 hover:border-green-500 transition-all hover:shadow-lg hover:shadow-green-500/10"
variants={itemVariants}
>
<div className="flex items-start gap-4">
<div className="text-2xl font-bold text-green-400 flex-shrink-0">{index + 1}</div>
<p className="text-gray-300 leading-relaxed pt-1">{customer}</p>
</div>
</motion.div>
))}
</motion.div>
<motion.div
className="mt-12 p-8 rounded-lg bg-gradient-to-r from-blue-500/10 to-green-500/10 border border-blue-500/30"
variants={itemVariants}
>
<p className="text-center text-gray-300 text-lg">
<br />
<span className="font-semibold text-white"></span>
</p>
</motion.div>
</motion.div>
</section>
);
}

40
src/globals.css Normal file
View File

@@ -0,0 +1,40 @@
@tailwind base;
@tailwind components;
@tailwind utilities;
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
html {
scroll-behavior: smooth;
}
body {
background-color: #0a0a0a;
color: #e5e7eb;
font-family:
-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
}
a {
color: inherit;
text-decoration: none;
}
section {
scroll-margin-top: 80px;
}
.gradient-text {
background: linear-gradient(135deg, #60a5fa, #34d399);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
}
.section-gradient {
background: linear-gradient(135deg, rgba(96, 165, 250, 0.1), rgba(52, 211, 153, 0.1));
}

25
tailwind.config.ts Normal file
View File

@@ -0,0 +1,25 @@
import type { Config } from 'tailwindcss';
const config: Config = {
content: [
'./src/pages/**/*.{js,ts,jsx,tsx,mdx}',
'./src/components/**/*.{js,ts,jsx,tsx,mdx}',
'./src/app/**/*.{js,ts,jsx,tsx,mdx}',
],
theme: {
extend: {
colors: {
dark: '#0a0a0a',
},
typography: {
DEFAULT: {
css: {
color: '#e5e7eb',
},
},
},
},
},
plugins: [],
};
export default config;

28
tsconfig.json Normal file
View File

@@ -0,0 +1,28 @@
{
"compilerOptions": {
"target": "es5",
"lib": ["dom", "dom.iterable", "esnext"],
"jsx": "preserve",
"module": "esnext",
"moduleResolution": "node",
"allowJs": true,
"skipLibCheck": true,
"strict": true,
"forceConsistentCasingInFileNames": true,
"noEmit": true,
"esModuleInterop": true,
"resolveJsonModule": true,
"isolatedModules": true,
"incremental": true,
"paths": {
"@/*": ["./src/*"]
},
"plugins": [
{
"name": "next"
}
]
},
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
"exclude": ["node_modules"]
}