Initial commit: Vibe Coding Workshop landing page
This commit is contained in:
commit
21c3a6621a
22
README.md
Normal file
22
README.md
Normal file
@ -0,0 +1,22 @@
|
||||
# Vibe Coding Воркшоп — Казахтелеком
|
||||
|
||||
Информационная платформа для участников воркшопа по вайб-кодингу для финансового департамента Казахтелеком.
|
||||
|
||||
## Описание
|
||||
|
||||
Однодневный воркшоп: участники узнают что такое вайб-кодинг, выбирают свой проект из боли внутри департамента и к концу дня деплоят рабочий MVP в среде telecom.quest.
|
||||
|
||||
## Разделы
|
||||
|
||||
- **Введение** — до vs после вайб-кодинга
|
||||
- **Почему финансисты** — три навыка которые уже есть
|
||||
- **Инструменты** — Claude Desktop, VSCode/telecom.quest, Sandbox КТ
|
||||
- **Программа дня** — расписание с 09:00 до 17:00
|
||||
- **Словарь** — 7 терминов без технического жаргона (аккордеон)
|
||||
- **Проекты** — 6 идей для проектов из финансового департамента
|
||||
|
||||
## Стек
|
||||
|
||||
- Vanilla HTML/CSS/JS — без фреймворков
|
||||
- Inter (Google Fonts) — типографика
|
||||
- Дизайн: стиль aqryl.app — серый фрейм, единый синий акцент #0066cc
|
||||
136
data/content.js
Normal file
136
data/content.js
Normal file
@ -0,0 +1,136 @@
|
||||
const GLOSSARY = [
|
||||
{
|
||||
term: 'PRD',
|
||||
abbr: 'PRD',
|
||||
definition: '<strong>Product Requirements Document</strong> — описание задачи своими словами. Ты пишешь: что должна делать программа, кто ей пользуется, что считается успехом. Это уже умеют делать все финансисты — вы делаете это в каждом ТЗ для 1С.'
|
||||
},
|
||||
{
|
||||
term: 'TRD',
|
||||
abbr: 'TRD',
|
||||
definition: '<strong>Technical Requirements Document</strong> — техническое задание, которое Claude генерирует из твоего PRD. Claude берёт твои слова и переводит на язык программиста. Ты не пишешь TRD — это делает ИИ.'
|
||||
},
|
||||
{
|
||||
term: 'MVP',
|
||||
abbr: 'MVP',
|
||||
definition: '<strong>Minimum Viable Product</strong> — минимальный рабочий прототип. Самое простое, что решает проблему. Не идеальное — рабочее. Сначала делаем MVP, потом улучшаем. Как черновик отчёта: сначала цифры правильные, потом форматирование.'
|
||||
},
|
||||
{
|
||||
term: 'Sandbox',
|
||||
abbr: 'Sandbox',
|
||||
definition: 'Тестовая среда с mock-данными. Можно ломать, пробовать, перезапускать — ничего страшного не произойдёт. Ваши реальные данные в 1С в полной безопасности. Всё что делается сегодня — только в sandbox.'
|
||||
},
|
||||
{
|
||||
term: 'Mock',
|
||||
abbr: 'Mock',
|
||||
definition: 'Тестовые данные вместо реальных. Например: вместо реальных платёжек из 1С — файл с похожей структурой, но с выдуманными суммами и контрагентами. Позволяет разрабатывать без доступа к боевым системам.'
|
||||
},
|
||||
{
|
||||
term: 'Итерация',
|
||||
abbr: 'Итерация',
|
||||
definition: 'Один цикл: <strong>сделал → проверил → улучшил</strong>. В разработке через Claude это занимает минуты. Описал задачу → получил код → запустил → увидел что не так → поправил описание → снова запустил. Это и есть вайб-кодинг.'
|
||||
},
|
||||
{
|
||||
term: 'Промпт',
|
||||
abbr: 'Prompt',
|
||||
definition: 'Твоя инструкция для Claude. Чем точнее описание — тем точнее результат. Хороший промпт = хороший PRD: контекст, задача, ограничения, критерий успеха. Всё что ты пишешь в Claude Desktop — это промпты.'
|
||||
}
|
||||
];
|
||||
|
||||
const PROJECTS = [
|
||||
{
|
||||
num: '01',
|
||||
title: 'Дашборд дебиторской задолженности',
|
||||
pain: 'Каждый понедельник собираю данные из 1С вручную, строю таблицу в Excel. Тратится 2-3 часа. Хочу видеть картину в реальном времени.',
|
||||
tags: ['Excel → Web', 'Визуализация', 'Автоматизация']
|
||||
},
|
||||
{
|
||||
num: '02',
|
||||
title: 'Чеклист закрытия периода',
|
||||
pain: 'Список шагов закрытия есть только у меня в голове. Когда я в отпуске — коллеги теряются. Нужен интерактивный чеклист с историей выполнения.',
|
||||
tags: ['Процесс', 'Командная работа', 'История']
|
||||
},
|
||||
{
|
||||
num: '03',
|
||||
title: 'Трекер согласования платежей',
|
||||
pain: 'Платёжные поручения согласуем через email. Теряются версии, непонятно кто последний смотрел. Хочу одно место с историей статусов.',
|
||||
tags: ['Согласования', 'Статусы', 'Аудит']
|
||||
},
|
||||
{
|
||||
num: '04',
|
||||
title: 'Конвертер банковской выписки',
|
||||
pain: 'Выписка из банка приходит в одном формате, 1С принимает в другом. Каждый раз переделываю вручную через Excel. Это можно автоматизировать.',
|
||||
tags: ['Парсинг', 'Конвертация', 'Банк']
|
||||
},
|
||||
{
|
||||
num: '05',
|
||||
title: 'Калькулятор бюджет vs факт',
|
||||
pain: 'Отчёт по исполнению бюджета строю раз в месяц на 4 часа. Хочу вводить данные и сразу видеть отклонения с drill-down по статьям.',
|
||||
tags: ['Аналитика', 'Бюджет', 'Отклонения']
|
||||
},
|
||||
{
|
||||
num: '06',
|
||||
title: 'Архив финансовых документов',
|
||||
pain: 'Договоры, акты, счета — всё в разных папках. Когда нужно найти документ по контрагенту — ищешь полчаса. Нужен поиск с фильтрами.',
|
||||
tags: ['Поиск', 'Архив', 'Документы']
|
||||
}
|
||||
];
|
||||
|
||||
const SCHEDULE = [
|
||||
{
|
||||
time: '09:00',
|
||||
title: 'Введение в вайб-кодинг',
|
||||
desc: 'Что изменилось. Почему финансисты — идеальные разработчики. Первое знакомство с Claude.',
|
||||
tags: ['Теория'],
|
||||
active: false
|
||||
},
|
||||
{
|
||||
time: '09:45',
|
||||
title: 'Инструменты и среда',
|
||||
desc: 'Настройка Claude Desktop, telecom.quest VSCode, знакомство с Sandbox КТ.',
|
||||
tags: ['Практика'],
|
||||
active: false
|
||||
},
|
||||
{
|
||||
time: '10:30',
|
||||
title: 'Первый промпт: пишем вместе',
|
||||
desc: 'Берём общую задачу, пишем PRD вместе, запускаем первый код. Каждый участник видит результат на своём экране.',
|
||||
tags: ['Практика', 'Совместно'],
|
||||
active: false
|
||||
},
|
||||
{
|
||||
time: '11:30',
|
||||
title: 'Выбор и проработка своего проекта',
|
||||
desc: 'Каждый выбирает боль из своего опыта. Пишем PRD, Claude генерирует TRD. Наставник помогает с описанием.',
|
||||
tags: ['Ваш проект'],
|
||||
active: true
|
||||
},
|
||||
{
|
||||
time: '13:00',
|
||||
title: 'Обед',
|
||||
desc: '',
|
||||
tags: [],
|
||||
active: false,
|
||||
isBreak: true
|
||||
},
|
||||
{
|
||||
time: '14:00',
|
||||
title: 'Разработка MVP',
|
||||
desc: 'Работаем по итерациям: описал → получил → проверил → улучшил. Claude пишет код, ты — ставишь задачу и принимаешь результат.',
|
||||
tags: ['Ваш проект', 'Итерации'],
|
||||
active: false
|
||||
},
|
||||
{
|
||||
time: '16:00',
|
||||
title: 'Демо и обратная связь',
|
||||
desc: '3 минуты на команду: показываем что получилось, что сработало, что было сложно. Без оценок — только обмен опытом.',
|
||||
tags: ['Демо'],
|
||||
active: false
|
||||
},
|
||||
{
|
||||
time: '16:45',
|
||||
title: 'Запуск на telecom.quest',
|
||||
desc: 'Каждый разворачивает свой MVP в среде КТ. Итоги дня, следующие шаги, ресурсы.',
|
||||
tags: ['Финал'],
|
||||
active: false
|
||||
}
|
||||
];
|
||||
392
index.html
Normal file
392
index.html
Normal file
@ -0,0 +1,392 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="ru">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1">
|
||||
<title>Vibe Coding Воркшоп — Казахтелеком</title>
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Inter:ital,wght@0,400;0,500;1,400&display=swap" rel="stylesheet">
|
||||
<link rel="stylesheet" href="style.css">
|
||||
</head>
|
||||
<body>
|
||||
<div class="frame">
|
||||
|
||||
<!-- NAV -->
|
||||
<nav>
|
||||
<div class="nav-inner">
|
||||
<a class="nav-logo" href="#top">
|
||||
<span class="logo-mark">КТ</span>
|
||||
<span class="logo-text">Vibe Workshop</span>
|
||||
</a>
|
||||
<div class="nav-links">
|
||||
<a href="#intro" class="nav-link">Введение</a>
|
||||
<a href="#tools" class="nav-link">Инструменты</a>
|
||||
<a href="#schedule" class="nav-link">Программа</a>
|
||||
<a href="#glossary" class="nav-link">Словарь</a>
|
||||
<a href="#projects" class="nav-link">Проекты</a>
|
||||
</div>
|
||||
<a href="https://telecom.quest" target="_blank" rel="noopener" class="nav-cta">telecom.quest →</a>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<!-- MAIN -->
|
||||
<main id="top">
|
||||
|
||||
<!-- HERO -->
|
||||
<section class="hero">
|
||||
<div class="container hero-inner">
|
||||
<span class="badge">Казахтелеком · Финансовый департамент · Полный день</span>
|
||||
<h1 class="hero-title">
|
||||
Воркшоп:<br>
|
||||
<span class="underline-blue">Vibe Coding</span><br>
|
||||
для финансистов
|
||||
</h1>
|
||||
<p class="hero-sub">
|
||||
Сегодня ты напишешь своё первое рабочее приложение.<br>Без опыта программирования.
|
||||
</p>
|
||||
<div class="hero-meta">
|
||||
<div class="hero-stat">
|
||||
<div class="hero-stat-num">8ч</div>
|
||||
<div class="hero-stat-label">полный день</div>
|
||||
</div>
|
||||
<div class="hero-divider"></div>
|
||||
<div class="hero-stat">
|
||||
<div class="hero-stat-num">1</div>
|
||||
<div class="hero-stat-label">MVP на выходе</div>
|
||||
</div>
|
||||
<div class="hero-divider"></div>
|
||||
<div class="hero-stat">
|
||||
<div class="hero-stat-num">0</div>
|
||||
<div class="hero-stat-label">строк кода вручную</div>
|
||||
</div>
|
||||
</div>
|
||||
<a href="#intro" class="btn-primary">Начать →</a>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- SECTION 1: WHAT IS VIBE CODING -->
|
||||
<section class="section" id="intro">
|
||||
<div class="container two-col">
|
||||
<div class="section-header">
|
||||
<div class="section-label">01 — Введение</div>
|
||||
<h2 class="section-title">Что такое<br><em>вайб-кодинг?</em></h2>
|
||||
<p class="section-body">
|
||||
Раньше между идеей и программой стоял разработчик, ТЗ и несколько месяцев ожидания.
|
||||
Теперь — только точное описание задачи.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="before-after">
|
||||
<div class="ba-card">
|
||||
<div class="ba-label">Раньше</div>
|
||||
<div class="ba-row">
|
||||
<svg class="ba-icon neg" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.7">
|
||||
<circle cx="8" cy="8" r="7"/><line x1="10" y1="6" x2="6" y2="10"/><line x1="6" y1="6" x2="10" y2="10"/>
|
||||
</svg>
|
||||
<span>Описываешь задачу разработчику</span>
|
||||
</div>
|
||||
<div class="ba-row">
|
||||
<svg class="ba-icon neg" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.7">
|
||||
<circle cx="8" cy="8" r="7"/><line x1="10" y1="6" x2="6" y2="10"/><line x1="6" y1="6" x2="10" y2="10"/>
|
||||
</svg>
|
||||
<span>Разработчик пишет ТЗ — итерация №1</span>
|
||||
</div>
|
||||
<div class="ba-row">
|
||||
<svg class="ba-icon neg" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.7">
|
||||
<circle cx="8" cy="8" r="7"/><line x1="10" y1="6" x2="6" y2="10"/><line x1="6" y1="6" x2="10" y2="10"/>
|
||||
</svg>
|
||||
<span>Согласование, правки, спринт</span>
|
||||
</div>
|
||||
<div class="ba-row">
|
||||
<svg class="ba-icon neg" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.7">
|
||||
<circle cx="8" cy="8" r="7"/><line x1="10" y1="6" x2="6" y2="10"/><line x1="6" y1="6" x2="10" y2="10"/>
|
||||
</svg>
|
||||
<span>Результат через 2–6 месяцев</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="ba-card after">
|
||||
<div class="ba-label after">Теперь</div>
|
||||
<div class="ba-row">
|
||||
<svg class="ba-icon pos" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.7">
|
||||
<circle cx="8" cy="8" r="7"/><polyline points="5,8 7,10 11,6"/>
|
||||
</svg>
|
||||
<span>Описываешь задачу словами в Claude</span>
|
||||
</div>
|
||||
<div class="ba-row">
|
||||
<svg class="ba-icon pos" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.7">
|
||||
<circle cx="8" cy="8" r="7"/><polyline points="5,8 7,10 11,6"/>
|
||||
</svg>
|
||||
<span>Claude Code пишет код за секунды</span>
|
||||
</div>
|
||||
<div class="ba-row">
|
||||
<svg class="ba-icon pos" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.7">
|
||||
<circle cx="8" cy="8" r="7"/><polyline points="5,8 7,10 11,6"/>
|
||||
</svg>
|
||||
<span>Ты проверяешь, даёшь обратную связь</span>
|
||||
</div>
|
||||
<div class="ba-row">
|
||||
<svg class="ba-icon pos" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.7">
|
||||
<circle cx="8" cy="8" r="7"/><polyline points="5,8 7,10 11,6"/>
|
||||
</svg>
|
||||
<span>Рабочий прототип за часы</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- SECTION 2: WHY FINANCIERS -->
|
||||
<section class="section" id="why">
|
||||
<div class="container">
|
||||
<div class="section-label">02 — Почему вы</div>
|
||||
<h2 class="section-title">Ты уже умеешь<br><em>самое важное</em></h2>
|
||||
<p class="section-body">
|
||||
Финансисты — лучшие постановщики задач. Ваш язык — это уже готовый PRD.
|
||||
Три навыка, которые у вас есть по умолчанию:
|
||||
</p>
|
||||
|
||||
<div class="cards-3">
|
||||
<div class="card">
|
||||
<svg class="card-icon" viewBox="0 0 48 48" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round">
|
||||
<rect x="8" y="6" width="32" height="36" rx="3"/>
|
||||
<line x1="16" y1="16" x2="32" y2="16"/>
|
||||
<line x1="16" y1="22" x2="32" y2="22"/>
|
||||
<line x1="16" y1="28" x2="24" y2="28"/>
|
||||
</svg>
|
||||
<div class="card-title">Описывать процессы</div>
|
||||
<div class="card-desc">
|
||||
Как вы закрываете период, как согласуете платёж — это уже структурированное описание задачи. Claude понимает именно такой язык.
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card">
|
||||
<svg class="card-icon" viewBox="0 0 48 48" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round">
|
||||
<circle cx="24" cy="24" r="16"/>
|
||||
<line x1="24" y1="16" x2="24" y2="24"/>
|
||||
<line x1="24" y1="24" x2="30" y2="30"/>
|
||||
</svg>
|
||||
<div class="card-title">Видеть проблему</div>
|
||||
<div class="card-desc">
|
||||
Где данные расходятся, где Excel ломается, где теряется время — вы чувствуете это лучше любого разработчика. Эта экспертиза бесценна.
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card">
|
||||
<svg class="card-icon" viewBox="0 0 48 48" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round">
|
||||
<polyline points="8,28 18,18 26,26 40,12"/>
|
||||
<polyline points="34,12 40,12 40,18"/>
|
||||
</svg>
|
||||
<div class="card-title">Принимать результат</div>
|
||||
<div class="card-desc">
|
||||
Принять или отклонить — это ваша ключевая роль. Цифра правильная или нет — именно ваша экспертиза даёт качество итоговому продукту.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- SECTION 3: TOOLS -->
|
||||
<section class="section" id="tools">
|
||||
<div class="container">
|
||||
<div class="section-label">03 — Инструменты</div>
|
||||
<h2 class="section-title">Три инструмента.<br><em>Один результат.</em></h2>
|
||||
<p class="section-body">
|
||||
Всё что нужно сегодня — уже настроено. Никаких установок, регистраций и ключей.
|
||||
</p>
|
||||
|
||||
<div class="tools-grid">
|
||||
<div class="tool-card">
|
||||
<div class="tool-icon-wrap">
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"/>
|
||||
</svg>
|
||||
</div>
|
||||
<div class="tool-name">Claude Desktop</div>
|
||||
<div class="tool-role">
|
||||
ИИ-помощник, который пишет код. Говоришь задачу — получаешь код. Исправляешь словами — получаешь новую версию.
|
||||
</div>
|
||||
<a href="https://claude.ai" target="_blank" rel="noopener" class="tool-link">
|
||||
claude.ai
|
||||
<svg width="12" height="12" viewBox="0 0 12 12" fill="none" stroke="currentColor" stroke-width="1.7">
|
||||
<path d="M2 10L10 2M4 2h6v6"/>
|
||||
</svg>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="tool-card">
|
||||
<div class="tool-icon-wrap">
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round">
|
||||
<polyline points="16 18 22 12 16 6"/><polyline points="8 6 2 12 8 18"/>
|
||||
</svg>
|
||||
</div>
|
||||
<div class="tool-name">VSCode на telecom.quest</div>
|
||||
<div class="tool-role">
|
||||
Редактор кода прямо в браузере. Не нужно ничего устанавливать — открываешь ссылку и работаешь. Код Claude сразу запускается здесь.
|
||||
</div>
|
||||
<a href="https://telecom.quest" target="_blank" rel="noopener" class="tool-link">
|
||||
telecom.quest
|
||||
<svg width="12" height="12" viewBox="0 0 12 12" fill="none" stroke="currentColor" stroke-width="1.7">
|
||||
<path d="M2 10L10 2M4 2h6v6"/>
|
||||
</svg>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="tool-card">
|
||||
<div class="tool-icon-wrap">
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round">
|
||||
<ellipse cx="12" cy="5" rx="9" ry="3"/>
|
||||
<path d="M21 12c0 1.66-4 3-9 3s-9-1.34-9-3"/>
|
||||
<path d="M3 5v14c0 1.66 4 3 9 3s9-1.34 9-3V5"/>
|
||||
</svg>
|
||||
</div>
|
||||
<div class="tool-name">Sandbox КТ</div>
|
||||
<div class="tool-role">
|
||||
Тестовая среда с mock-данными, похожими на реальные данные КТ. Можно ломать, перезапускать. Реальные данные в полной безопасности.
|
||||
</div>
|
||||
<span class="tool-link" style="cursor:default;opacity:0.5">Настроено заранее</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- SECTION 4: SCHEDULE -->
|
||||
<section class="section" id="schedule">
|
||||
<div class="container two-col">
|
||||
<div class="section-header">
|
||||
<div class="section-label">04 — Программа</div>
|
||||
<h2 class="section-title">Что будет<br><em>сегодня</em></h2>
|
||||
<p class="section-body">
|
||||
Полный день поделён на блоки с чёткими результатами. К 17:00 — твой MVP задеплоен.
|
||||
</p>
|
||||
</div>
|
||||
<div class="schedule" id="schedule-list"></div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- SECTION 5: GLOSSARY -->
|
||||
<section class="section" id="glossary">
|
||||
<div class="container two-col">
|
||||
<div class="section-header">
|
||||
<div class="section-label">05 — Словарь</div>
|
||||
<h2 class="section-title">Термины,<br><em>которые услышишь</em></h2>
|
||||
<p class="section-body">
|
||||
Семь слов, которые встретятся сегодня. Нажми на любое — увидишь объяснение
|
||||
без технического жаргона.
|
||||
</p>
|
||||
</div>
|
||||
<div class="glossary" id="glossary-list"></div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- SECTION 6: PROJECTS -->
|
||||
<section class="section" id="projects">
|
||||
<div class="container">
|
||||
<div class="section-label">06 — Твой проект</div>
|
||||
<h2 class="section-title">Ты знаешь<br><em>боль изнутри</em></h2>
|
||||
<p class="section-body">
|
||||
Лучший проект — тот, где ты сам тратишь время впустую. Вот примеры из финансовых департаментов —
|
||||
выбери ближайший или опиши свой.
|
||||
</p>
|
||||
<div class="projects-grid" id="projects-grid"></div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- DARK CTA -->
|
||||
<section class="section" style="border-top: none; padding-bottom: 64px;">
|
||||
<div class="container">
|
||||
<div class="dark-section">
|
||||
<h2 class="dark-title">Запусти свой проект сегодня</h2>
|
||||
<p class="dark-sub">
|
||||
К концу дня — рабочий MVP в среде Казахтелеком. Первый шаг сделан.
|
||||
</p>
|
||||
<a href="https://telecom.quest" target="_blank" rel="noopener" class="dark-cta">
|
||||
Открыть telecom.quest →
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- FOOTER -->
|
||||
<footer>
|
||||
<span class="footer-copy">Казахтелеком · Финансовый департамент · Воркшоп по вайб-кодингу</span>
|
||||
<div class="footer-links">
|
||||
<a href="https://claude.ai" target="_blank" rel="noopener" class="footer-link">Claude Desktop</a>
|
||||
<a href="https://telecom.quest" target="_blank" rel="noopener" class="footer-link">telecom.quest</a>
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
</main>
|
||||
|
||||
</div>
|
||||
|
||||
<script src="data/content.js"></script>
|
||||
<script>
|
||||
// Render schedule
|
||||
const scheduleEl = document.getElementById('schedule-list');
|
||||
SCHEDULE.forEach(item => {
|
||||
const div = document.createElement('div');
|
||||
div.className = 'sched-item' + (item.active ? ' active' : '') + (item.isBreak ? ' break' : '');
|
||||
div.innerHTML = `
|
||||
<span class="sched-time">${item.time}</span>
|
||||
<span class="sched-dot"></span>
|
||||
<div class="sched-content">
|
||||
<div class="sched-title">${item.title}</div>
|
||||
${item.desc ? `<div class="sched-desc">${item.desc}</div>` : ''}
|
||||
${item.tags.length ? `<div class="sched-tags">${item.tags.map(t => `<span class="tag ${t === 'Ваш проект' || t === 'Финал' ? 'blue' : ''}">${t}</span>`).join('')}</div>` : ''}
|
||||
</div>
|
||||
`;
|
||||
scheduleEl.appendChild(div);
|
||||
});
|
||||
|
||||
// Render glossary
|
||||
const glossaryEl = document.getElementById('glossary-list');
|
||||
GLOSSARY.forEach(item => {
|
||||
const div = document.createElement('div');
|
||||
div.className = 'gloss-item';
|
||||
div.innerHTML = `
|
||||
<button class="gloss-trigger" aria-expanded="false">
|
||||
<span class="gloss-term">${item.term}</span>
|
||||
<span class="gloss-abbr">${item.abbr}</span>
|
||||
<svg class="gloss-chevron" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.9" stroke-linecap="round">
|
||||
<polyline points="4,6 8,10 12,6"/>
|
||||
</svg>
|
||||
</button>
|
||||
<div class="gloss-body" role="region">
|
||||
<div class="gloss-inner">
|
||||
<div class="gloss-text">${item.definition}</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
const btn = div.querySelector('.gloss-trigger');
|
||||
btn.addEventListener('click', () => {
|
||||
const isOpen = div.classList.contains('open');
|
||||
document.querySelectorAll('.gloss-item.open').forEach(el => {
|
||||
el.classList.remove('open');
|
||||
el.querySelector('.gloss-trigger').setAttribute('aria-expanded', 'false');
|
||||
});
|
||||
if (!isOpen) {
|
||||
div.classList.add('open');
|
||||
btn.setAttribute('aria-expanded', 'true');
|
||||
}
|
||||
});
|
||||
glossaryEl.appendChild(div);
|
||||
});
|
||||
|
||||
// Render projects
|
||||
const projectsEl = document.getElementById('projects-grid');
|
||||
PROJECTS.forEach(item => {
|
||||
const div = document.createElement('div');
|
||||
div.className = 'project-card';
|
||||
div.innerHTML = `
|
||||
<div class="project-num">${item.num}</div>
|
||||
<div class="project-title">${item.title}</div>
|
||||
<div class="project-pain">"${item.pain}"</div>
|
||||
<div class="project-tags">${item.tags.map(t => `<span class="tag">${t}</span>`).join('')}</div>
|
||||
`;
|
||||
projectsEl.appendChild(div);
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
751
style.css
Normal file
751
style.css
Normal file
@ -0,0 +1,751 @@
|
||||
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
|
||||
|
||||
:root {
|
||||
--blue: #0066cc;
|
||||
--blue-hover: #0055b3;
|
||||
--blue-link: #0058b3;
|
||||
--bg: #efefef;
|
||||
--card-neutral: #e3e3e3;
|
||||
--text: #000;
|
||||
--text-65: rgba(0,0,0,0.65);
|
||||
--text-55: rgba(0,0,0,0.55);
|
||||
--text-45: rgba(0,0,0,0.45);
|
||||
--border: rgba(0,0,0,0.08);
|
||||
--hover: rgba(0,0,0,0.06);
|
||||
--hover-light: rgba(0,0,0,0.03);
|
||||
--positive: #059669;
|
||||
--positive-bg: #dcfce7;
|
||||
--negative: #dc2626;
|
||||
}
|
||||
|
||||
html { scroll-behavior: smooth; }
|
||||
|
||||
body {
|
||||
font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
|
||||
background: #fff;
|
||||
min-height: 100dvh;
|
||||
padding: 12px;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
color: var(--text);
|
||||
}
|
||||
|
||||
/* ── FRAME ── */
|
||||
.frame {
|
||||
min-height: calc(100dvh - 24px);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
/* ── NAV ── */
|
||||
nav {
|
||||
height: 64px;
|
||||
background: var(--bg);
|
||||
border-radius: 16px;
|
||||
padding: 0 20px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
position: sticky;
|
||||
top: 12px;
|
||||
z-index: 50;
|
||||
}
|
||||
|
||||
.nav-inner {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 16px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.nav-logo {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
text-decoration: none;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.logo-mark {
|
||||
background: var(--blue);
|
||||
color: #fff;
|
||||
font-size: 0.75rem;
|
||||
font-weight: 500;
|
||||
padding: 3px 7px;
|
||||
border-radius: 6px;
|
||||
letter-spacing: 0.02em;
|
||||
}
|
||||
|
||||
.logo-text {
|
||||
font-size: 0.875rem;
|
||||
font-weight: 500;
|
||||
color: var(--text);
|
||||
}
|
||||
|
||||
.nav-links {
|
||||
display: none;
|
||||
flex: 1;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 4px;
|
||||
}
|
||||
|
||||
@media (min-width: 768px) {
|
||||
.nav-links { display: flex; }
|
||||
}
|
||||
|
||||
.nav-link {
|
||||
padding: 6px 12px;
|
||||
font-size: 0.875rem;
|
||||
font-weight: 400;
|
||||
color: var(--text-65);
|
||||
text-decoration: none;
|
||||
border-radius: 8px;
|
||||
transition: background 150ms ease, color 150ms ease;
|
||||
}
|
||||
|
||||
.nav-link:hover {
|
||||
background: var(--hover);
|
||||
color: var(--text);
|
||||
}
|
||||
|
||||
.nav-cta {
|
||||
margin-left: auto;
|
||||
background: var(--blue);
|
||||
color: #fff;
|
||||
font-size: 0.875rem;
|
||||
font-weight: 500;
|
||||
padding: 8px 16px;
|
||||
border-radius: 8px;
|
||||
text-decoration: none;
|
||||
transition: background 150ms ease;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.nav-cta:hover { background: var(--blue-hover); }
|
||||
|
||||
/* ── MAIN ── */
|
||||
main {
|
||||
background: var(--bg);
|
||||
border-radius: 16px;
|
||||
overflow: hidden;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
/* ── CONTAINER ── */
|
||||
.container {
|
||||
width: 100%;
|
||||
max-width: 1024px;
|
||||
margin: 0 auto;
|
||||
padding: 0 16px;
|
||||
}
|
||||
|
||||
@media (min-width: 640px) { .container { padding: 0 24px; } }
|
||||
|
||||
/* ── HERO ── */
|
||||
.hero {
|
||||
padding: 72px 0 56px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
@media (min-width: 640px) { .hero { padding: 96px 0 72px; } }
|
||||
@media (min-width: 1024px) { .hero { padding: 112px 0 80px; } }
|
||||
|
||||
.hero-inner {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.badge {
|
||||
display: inline-block;
|
||||
font-size: 0.75rem;
|
||||
font-weight: 400;
|
||||
color: var(--text-55);
|
||||
letter-spacing: 0.02em;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.hero-title {
|
||||
font-size: 2rem;
|
||||
font-weight: 400;
|
||||
line-height: 1.12;
|
||||
letter-spacing: -0.02em;
|
||||
color: var(--text);
|
||||
max-width: 540px;
|
||||
}
|
||||
|
||||
@media (min-width: 640px) { .hero-title { font-size: 2.5rem; } }
|
||||
@media (min-width: 1024px) { .hero-title { font-size: 3rem; max-width: 640px; } }
|
||||
|
||||
.underline-blue {
|
||||
text-decoration: underline;
|
||||
text-decoration-color: var(--blue);
|
||||
text-decoration-thickness: 3px;
|
||||
text-underline-offset: 6px;
|
||||
}
|
||||
|
||||
.hero-sub {
|
||||
margin-top: 16px;
|
||||
font-size: 0.9375rem;
|
||||
font-weight: 400;
|
||||
color: var(--text-55);
|
||||
max-width: 400px;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
@media (min-width: 640px) { .hero-sub { font-size: 1rem; } }
|
||||
|
||||
.hero-meta {
|
||||
margin-top: 32px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 20px;
|
||||
justify-content: center;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.hero-stat {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.hero-stat-num {
|
||||
font-size: 1.5rem;
|
||||
font-weight: 400;
|
||||
color: var(--blue);
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
.hero-stat-label {
|
||||
font-size: 0.75rem;
|
||||
color: var(--text-45);
|
||||
margin-top: 2px;
|
||||
}
|
||||
|
||||
.hero-divider {
|
||||
width: 1px;
|
||||
height: 32px;
|
||||
background: var(--border);
|
||||
}
|
||||
|
||||
/* ── SECTION ── */
|
||||
.section {
|
||||
padding: 64px 0;
|
||||
border-top: 1px solid var(--border);
|
||||
}
|
||||
|
||||
@media (min-width: 640px) { .section { padding: 80px 0; } }
|
||||
|
||||
.section-label {
|
||||
font-size: 0.75rem;
|
||||
font-weight: 400;
|
||||
color: var(--text-45);
|
||||
letter-spacing: 0.04em;
|
||||
text-transform: uppercase;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
.section-title {
|
||||
font-size: 1.5rem;
|
||||
font-weight: 400;
|
||||
line-height: 1.2;
|
||||
letter-spacing: -0.02em;
|
||||
color: var(--text);
|
||||
max-width: 540px;
|
||||
}
|
||||
|
||||
@media (min-width: 640px) { .section-title { font-size: 1.875rem; } }
|
||||
|
||||
.section-title em {
|
||||
font-style: normal;
|
||||
text-decoration: underline;
|
||||
text-decoration-color: var(--blue);
|
||||
text-decoration-thickness: 2px;
|
||||
text-underline-offset: 5px;
|
||||
}
|
||||
|
||||
.section-body {
|
||||
margin-top: 12px;
|
||||
font-size: 0.9375rem;
|
||||
font-weight: 400;
|
||||
color: var(--text-55);
|
||||
max-width: 520px;
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
/* ── BEFORE / AFTER ── */
|
||||
.before-after {
|
||||
margin-top: 40px;
|
||||
display: grid;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
@media (min-width: 640px) {
|
||||
.before-after { grid-template-columns: 1fr 1fr; }
|
||||
}
|
||||
|
||||
.ba-card {
|
||||
background: var(--card-neutral);
|
||||
border-radius: 12px;
|
||||
padding: 24px;
|
||||
}
|
||||
|
||||
.ba-card.after {
|
||||
background: #fff;
|
||||
border: 1px solid var(--border);
|
||||
}
|
||||
|
||||
.ba-label {
|
||||
font-size: 0.6875rem;
|
||||
font-weight: 500;
|
||||
letter-spacing: 0.06em;
|
||||
text-transform: uppercase;
|
||||
color: var(--text-45);
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.ba-label.after { color: var(--blue); }
|
||||
|
||||
.ba-row {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
gap: 10px;
|
||||
font-size: 0.875rem;
|
||||
color: var(--text-65);
|
||||
line-height: 1.5;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.ba-row:last-child { margin-bottom: 0; }
|
||||
|
||||
.ba-icon {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
flex-shrink: 0;
|
||||
margin-top: 2px;
|
||||
}
|
||||
|
||||
.ba-icon.neg { color: var(--negative); }
|
||||
.ba-icon.pos { color: var(--positive); }
|
||||
|
||||
/* ── THREE CARDS ── */
|
||||
.cards-3 {
|
||||
margin-top: 40px;
|
||||
display: grid;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
@media (min-width: 640px) { .cards-3 { grid-template-columns: repeat(2, 1fr); } }
|
||||
@media (min-width: 1024px) { .cards-3 { grid-template-columns: repeat(3, 1fr); } }
|
||||
|
||||
.card {
|
||||
background: var(--card-neutral);
|
||||
border-radius: 12px;
|
||||
padding: 28px 24px;
|
||||
}
|
||||
|
||||
.card-icon {
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
color: var(--blue);
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.card-title {
|
||||
font-size: 0.9375rem;
|
||||
font-weight: 500;
|
||||
letter-spacing: -0.01em;
|
||||
color: var(--text);
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.card-desc {
|
||||
font-size: 0.8125rem;
|
||||
font-weight: 400;
|
||||
color: var(--text-55);
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
/* ── TOOLS TABLE ── */
|
||||
.tools-grid {
|
||||
margin-top: 40px;
|
||||
display: grid;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
@media (min-width: 640px) { .tools-grid { grid-template-columns: repeat(3, 1fr); } }
|
||||
|
||||
.tool-card {
|
||||
background: #fff;
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 12px;
|
||||
padding: 24px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.tool-icon-wrap {
|
||||
width: 44px;
|
||||
height: 44px;
|
||||
background: var(--card-neutral);
|
||||
border-radius: 10px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
color: var(--blue);
|
||||
}
|
||||
|
||||
.tool-icon-wrap svg { width: 22px; height: 22px; }
|
||||
|
||||
.tool-name {
|
||||
font-size: 0.9375rem;
|
||||
font-weight: 500;
|
||||
color: var(--text);
|
||||
}
|
||||
|
||||
.tool-role {
|
||||
font-size: 0.8125rem;
|
||||
color: var(--text-55);
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
.tool-link {
|
||||
margin-top: auto;
|
||||
font-size: 0.8125rem;
|
||||
font-weight: 500;
|
||||
color: var(--blue);
|
||||
text-decoration: none;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
}
|
||||
|
||||
.tool-link:hover { color: var(--blue-hover); }
|
||||
|
||||
/* ── SCHEDULE ── */
|
||||
.schedule {
|
||||
margin-top: 40px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0;
|
||||
}
|
||||
|
||||
.sched-item {
|
||||
display: flex;
|
||||
gap: 20px;
|
||||
padding: 20px 0;
|
||||
border-bottom: 1px solid var(--border);
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.sched-item:last-child { border-bottom: none; }
|
||||
|
||||
.sched-time {
|
||||
font-size: 0.8125rem;
|
||||
font-weight: 400;
|
||||
color: var(--text-45);
|
||||
width: 52px;
|
||||
flex-shrink: 0;
|
||||
padding-top: 2px;
|
||||
font-variant-numeric: tabular-nums;
|
||||
}
|
||||
|
||||
.sched-dot {
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
border-radius: 50%;
|
||||
background: var(--card-neutral);
|
||||
border: 2px solid var(--border);
|
||||
flex-shrink: 0;
|
||||
margin-top: 5px;
|
||||
}
|
||||
|
||||
.sched-item.active .sched-dot {
|
||||
background: var(--blue);
|
||||
border-color: var(--blue);
|
||||
}
|
||||
|
||||
.sched-content { flex: 1; min-width: 0; }
|
||||
|
||||
.sched-title {
|
||||
font-size: 0.9375rem;
|
||||
font-weight: 500;
|
||||
color: var(--text);
|
||||
}
|
||||
|
||||
.sched-item.break .sched-title { color: var(--text-55); font-weight: 400; }
|
||||
|
||||
.sched-desc {
|
||||
margin-top: 4px;
|
||||
font-size: 0.8125rem;
|
||||
color: var(--text-55);
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
.sched-tags {
|
||||
margin-top: 8px;
|
||||
display: flex;
|
||||
gap: 6px;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.tag {
|
||||
font-size: 0.6875rem;
|
||||
font-weight: 500;
|
||||
padding: 2px 8px;
|
||||
border-radius: 6px;
|
||||
background: var(--card-neutral);
|
||||
color: var(--text-55);
|
||||
}
|
||||
|
||||
.tag.blue { background: rgba(0,102,204,0.1); color: var(--blue); }
|
||||
|
||||
/* ── GLOSSARY ── */
|
||||
.glossary {
|
||||
margin-top: 40px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.gloss-item {
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 12px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.gloss-trigger {
|
||||
width: 100%;
|
||||
padding: 16px 20px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 12px;
|
||||
background: transparent;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
text-align: left;
|
||||
transition: background 150ms ease;
|
||||
}
|
||||
|
||||
@media (prefers-reduced-motion: reduce) { .gloss-trigger { transition: none; } }
|
||||
|
||||
.gloss-trigger:hover { background: var(--hover-light); }
|
||||
|
||||
.gloss-term {
|
||||
font-size: 0.9375rem;
|
||||
font-weight: 500;
|
||||
color: var(--text);
|
||||
}
|
||||
|
||||
.gloss-abbr {
|
||||
font-size: 0.75rem;
|
||||
font-weight: 500;
|
||||
color: var(--blue);
|
||||
background: rgba(0,102,204,0.08);
|
||||
padding: 2px 8px;
|
||||
border-radius: 6px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.gloss-chevron {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
color: var(--text-55);
|
||||
flex-shrink: 0;
|
||||
transition: transform 200ms ease;
|
||||
}
|
||||
|
||||
@media (prefers-reduced-motion: reduce) { .gloss-chevron { transition: none; } }
|
||||
|
||||
.gloss-item.open .gloss-chevron { transform: rotate(180deg); }
|
||||
|
||||
.gloss-body {
|
||||
display: grid;
|
||||
grid-template-rows: 0fr;
|
||||
transition: grid-template-rows 200ms ease;
|
||||
}
|
||||
|
||||
@media (prefers-reduced-motion: reduce) { .gloss-body { transition: none; } }
|
||||
|
||||
.gloss-item.open .gloss-body { grid-template-rows: 1fr; }
|
||||
|
||||
.gloss-inner {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.gloss-text {
|
||||
padding: 0 20px 16px;
|
||||
font-size: 0.875rem;
|
||||
color: var(--text-65);
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
.gloss-text strong {
|
||||
color: var(--text);
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
/* ── PROJECTS ── */
|
||||
.projects-grid {
|
||||
margin-top: 40px;
|
||||
display: grid;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
@media (min-width: 640px) { .projects-grid { grid-template-columns: repeat(2, 1fr); } }
|
||||
|
||||
.project-card {
|
||||
background: #fff;
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 12px;
|
||||
padding: 24px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 10px;
|
||||
cursor: pointer;
|
||||
transition: border-color 150ms ease, box-shadow 150ms ease;
|
||||
}
|
||||
|
||||
@media (prefers-reduced-motion: reduce) { .project-card { transition: none; } }
|
||||
|
||||
.project-card:hover {
|
||||
border-color: rgba(0,102,204,0.3);
|
||||
box-shadow: 0 0 0 3px rgba(0,102,204,0.06);
|
||||
}
|
||||
|
||||
.project-num {
|
||||
font-size: 0.6875rem;
|
||||
font-weight: 500;
|
||||
color: var(--text-45);
|
||||
letter-spacing: 0.04em;
|
||||
}
|
||||
|
||||
.project-title {
|
||||
font-size: 0.9375rem;
|
||||
font-weight: 500;
|
||||
color: var(--text);
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
.project-pain {
|
||||
font-size: 0.8125rem;
|
||||
color: var(--text-55);
|
||||
line-height: 1.5;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.project-tags { display: flex; gap: 6px; flex-wrap: wrap; }
|
||||
|
||||
/* ── DARK CTA ── */
|
||||
.dark-section {
|
||||
background: linear-gradient(135deg, #000 0%, #002a63 50%, #0066cc 100%);
|
||||
border-radius: 16px;
|
||||
padding: 56px 24px;
|
||||
text-align: center;
|
||||
margin: 0 16px 0;
|
||||
}
|
||||
|
||||
@media (min-width: 640px) { .dark-section { padding: 72px 40px; } }
|
||||
|
||||
.dark-title {
|
||||
font-size: 1.75rem;
|
||||
font-weight: 400;
|
||||
color: #fff;
|
||||
letter-spacing: -0.02em;
|
||||
line-height: 1.2;
|
||||
max-width: 460px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
@media (min-width: 640px) { .dark-title { font-size: 2.25rem; } }
|
||||
|
||||
.dark-sub {
|
||||
margin-top: 12px;
|
||||
font-size: 0.9375rem;
|
||||
color: rgba(255,255,255,0.7);
|
||||
max-width: 380px;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
margin-top: 12px;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
.dark-cta {
|
||||
margin-top: 32px;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
background: #fff;
|
||||
color: var(--blue-link);
|
||||
font-size: 0.9375rem;
|
||||
font-weight: 500;
|
||||
padding: 12px 24px;
|
||||
border-radius: 10px;
|
||||
text-decoration: none;
|
||||
transition: color 150ms ease;
|
||||
}
|
||||
|
||||
.dark-cta:hover { color: var(--blue-hover); }
|
||||
|
||||
/* ── FOOTER ── */
|
||||
footer {
|
||||
padding: 32px 24px 24px;
|
||||
border-top: 1px solid var(--border);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
flex-wrap: wrap;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.footer-copy {
|
||||
font-size: 0.75rem;
|
||||
color: var(--text-45);
|
||||
}
|
||||
|
||||
.footer-links {
|
||||
display: flex;
|
||||
gap: 16px;
|
||||
}
|
||||
|
||||
.footer-link {
|
||||
font-size: 0.75rem;
|
||||
color: var(--text-55);
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.footer-link:hover { color: var(--text); }
|
||||
|
||||
/* ── UTILS ── */
|
||||
.btn-primary {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
background: var(--blue);
|
||||
color: #fff;
|
||||
font-size: 0.875rem;
|
||||
font-weight: 500;
|
||||
padding: 10px 20px;
|
||||
border-radius: 8px;
|
||||
text-decoration: none;
|
||||
transition: background 150ms ease;
|
||||
margin-top: 24px;
|
||||
}
|
||||
|
||||
.btn-primary:hover { background: var(--blue-hover); }
|
||||
|
||||
.two-col {
|
||||
display: grid;
|
||||
gap: 48px;
|
||||
}
|
||||
|
||||
@media (min-width: 1024px) {
|
||||
.two-col {
|
||||
grid-template-columns: 1fr 1fr;
|
||||
align-items: start;
|
||||
}
|
||||
}
|
||||
|
||||
.section-header { margin-bottom: 0; }
|
||||
Reference in New Issue
Block a user