diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml deleted file mode 100644 index 0f85145..0000000 --- a/.github/workflows/ci.yml +++ /dev/null @@ -1,44 +0,0 @@ -name: CI - Build and Test - -on: - pull_request: - -jobs: - build_and_test: - runs-on: ubuntu-latest - steps: - - name: Checkout repository - uses: actions/checkout@v4 - - - name: Set up Node.js - uses: actions/setup-node@v4 - with: - node-version: '22' - cache: 'npm' - cache-dependency-path: frontend/package-lock.json - - - name: Install Frontend Dependencies - working-directory: ./frontend - run: npm ci - - - name: Build Frontend (for verification) - working-directory: ./frontend - run: npm run build - - - name: Set up Rust - uses: actions-rs/toolchain@v1 - with: - toolchain: stable - profile: minimal - override: true - - - name: Set up Rust cache - uses: Swatinem/rust-cache@v2 - - - name: Check Backend code - working-directory: ./backend - run: cargo check --verbose - - - name: Build Backend (for verification) - working-directory: ./backend - run: cargo build --verbose diff --git a/frontend/app/[locale]/contact/page.module.css b/frontend/app/[locale]/contact/page.module.css index ee9b8e6..8596e1b 100644 --- a/frontend/app/[locale]/contact/page.module.css +++ b/frontend/app/[locale]/contact/page.module.css @@ -1,168 +1,119 @@ -.page { - --gray-rgb: 0, 0, 0; - --gray-alpha-200: rgba(var(--gray-rgb), 0.08); - --gray-alpha-100: rgba(var(--gray-rgb), 0.05); - - --button-primary-hover: #383838; - --button-secondary-hover: #f2f2f2; - - display: grid; - grid-template-rows: 20px 1fr 20px; - align-items: center; - justify-items: center; - min-height: 100svh; - padding: 80px; - gap: 64px; - font-family: var(--font-geist-sans); +.container { + max-width: 960px; + margin: 40px auto; + padding: 20px; + text-align: center; } -@media (prefers-color-scheme: dark) { - .page { - --gray-rgb: 255, 255, 255; - --gray-alpha-200: rgba(var(--gray-rgb), 0.145); - --gray-alpha-100: rgba(var(--gray-rgb), 0.06); - - --button-primary-hover: #ccc; - --button-secondary-hover: #1a1a1a; - } -} - -.main { - display: flex; - flex-direction: column; - gap: 32px; - grid-row-start: 2; -} - -.main ol { - font-family: var(--font-geist-mono); - padding-left: 0; - margin: 0; - font-size: 14px; - line-height: 24px; - letter-spacing: -0.01em; - list-style-position: inside; +.title { + font-size: 2.5rem; + font-weight: bold; + margin-bottom: 1rem; + color: var(--foreground); } -.main li:not(:last-of-type) { - margin-bottom: 8px; +.subtitle { + font-size: 1.2rem; + color: var(--muted-foreground); + margin-bottom: 3rem; } -.main code { - font-family: inherit; - background: var(--gray-alpha-100); - padding: 2px 4px; - border-radius: 4px; - font-weight: 600; -} - -.ctas { - display: flex; - gap: 16px; +.grid { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); + gap: 1.5rem; + text-align: left; } -.ctas a { - appearance: none; - border-radius: 128px; - height: 48px; - padding: 0 20px; - border: none; - border: 1px solid transparent; - transition: - background 0.2s, - color 0.2s, - border-color 0.2s; - cursor: pointer; +.card { display: flex; align-items: center; - justify-content: center; - font-size: 16px; - line-height: 20px; - font-weight: 500; + gap: 1.5rem; + background-color: var(--card); + padding: 1.5rem; + border-radius: 12px; + border: 1px solid var(--border); + transition: transform 0.2s ease-in-out, box-shadow 0.2s ease-in-out; + text-decoration: none; + color: inherit; } -a.primary { - background: var(--foreground); - color: var(--background); - gap: 8px; +.card:hover { + transform: translateY(-5px); + box-shadow: 0 8px 25px rgba(0, 0, 0, 0.1); } -a.secondary { - border-color: var(--gray-alpha-200); - min-width: 180px; +.dark .card:hover { + box-shadow: 0 8px 25px rgba(255, 255, 255, 0.08); } -.footer { - grid-row-start: 3; - display: flex; - gap: 24px; -} - -.footer a { +.iconWrapper { + flex-shrink: 0; display: flex; align-items: center; - gap: 8px; + justify-content: center; + width: 64px; + height: 64px; + /* Для светлой темы фон остается прежним */ + background-color: var(--muted); + border-radius: 50%; + transition: background-color 0.3s ease-in-out; +} + +/* + НОВЫЙ БЛОК: Правило для фона иконки в темной теме. + Вместо светло-серого мы используем var(--secondary), + который является темно-серым и лучше вписывается в фон карточки. +*/ +.dark .iconWrapper { + background-color: var(--secondary); +} + +.icon { + width: 40px; + height: 40px; + object-fit: contain; + /* Добавляем плавный переход для фильтра и прозрачности */ + transition: filter 0.3s ease-in-out, opacity 0.3s ease-in-out; +} + +/* + ИЗМЕНЕННЫЙ БЛОК: Улучшенная адаптация иконки. + Мы по-прежнему инвертируем ее, чтобы сделать белой, + но добавляем прозрачность. Это убирает резкость и делает + иконку похожей по яркости на основной текст. +*/ +.dark .invertOnDark { + /* filter: brightness(0); + opacity: 1; */ + color: white; + background-color: white; +} + +.cardContent { + display: flex; + flex-direction: column; } -.footer img { - flex-shrink: 0; +.cardTitle { + font-size: 1.25rem; + font-weight: 600; + color: var(--foreground); + margin: 0; } -/* 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; - } - - .footer a:hover { - text-decoration: underline; - text-underline-offset: 4px; - } +.cardHandle { + font-size: 1rem; + color: var(--muted-foreground); + margin: 0; + word-break: break-all; } -@media (max-width: 600px) { - .page { - padding: 32px; - padding-bottom: 80px; +@media (max-width: 640px) { + .title { + font-size: 2rem; } - - .main { - align-items: center; - } - - .main ol { - text-align: center; + .grid { + grid-template-columns: 1fr; } - - .ctas { - flex-direction: column; - } - - .ctas a { - font-size: 14px; - height: 40px; - padding: 0 16px; - } - - a.secondary { - min-width: auto; - } - - .footer { - flex-wrap: wrap; - align-items: center; - justify-content: center; - } -} - -@media (prefers-color-scheme: dark) { - .logo { - filter: invert(); - } -} +} \ No newline at end of file diff --git a/frontend/app/[locale]/contact/page.tsx b/frontend/app/[locale]/contact/page.tsx index 5ed795d..cbe76d3 100644 --- a/frontend/app/[locale]/contact/page.tsx +++ b/frontend/app/[locale]/contact/page.tsx @@ -1,9 +1,75 @@ -import styles from "./page.module.css"; +'use client'; + +import Image from 'next/image'; +import { useTranslations } from 'next-intl'; +import styles from './page.module.css'; + +const contacts = [ + { + name: 'Telegram', + handle: '@diametrfq', + url: 'https://t.me/diametrfq', + iconUrl: '/logo/telegram.svg', + }, + { + name: 'LinkedIn', + handle: 'Dmitry Khokhlov', + url: 'https://www.linkedin.com/in/diametrfq', + iconUrl: '/logo/linkedin.svg', + }, + { + name: 'GitHub', + handle: 'DiametrFQ', + url: 'https://github.com/DiametrFQ', + iconUrl: 'https://cdn.worldvectorlogo.com/logos/github-icon-1.svg', + themeBehavior: 'invertOnDark', + }, + { + name: 'Email', + handle: 'hohlov.03@inbox.ru', + url: 'mailto:hohlov.03@inbox.ru', + iconUrl: '/logo/email.png', + }, + { + name: 'Steam', + handle: 'diametrfq', + url: 'https://steamcommunity.com/id/diametrfq/', + iconUrl: '/logo/steam.png', + }, +]; + +export default function Contact() { + const t = useTranslations('ContactPage'); -export default function Portfolio() { return ( -
{t('subtitle')}
+{contact.handle}
+