Initial commit
This commit is contained in:
19
.gitignore
vendored
Normal file
19
.gitignore
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
!**/glob-import/dir/node_modules
|
||||
.DS_Store
|
||||
.idea
|
||||
.pnpm-store
|
||||
*.cpuprofile
|
||||
*.local
|
||||
*.log
|
||||
/.vscode/
|
||||
/docs/.vitepress/cache
|
||||
/docs/.vitepress/.temp
|
||||
/packages/vite/LICENSE
|
||||
dist
|
||||
dist-ssr
|
||||
explorations
|
||||
node_modules
|
||||
playground-temp
|
||||
temp
|
||||
TODOs.md
|
||||
.eslintcache
|
||||
55
CLAUDE.md
Normal file
55
CLAUDE.md
Normal file
@@ -0,0 +1,55 @@
|
||||
# CLAUDE.md
|
||||
|
||||
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
||||
|
||||
## Project Overview
|
||||
|
||||
A brutalist editorial landing page for Alina Mamut, a brand strategy and creative consulting professional. The site is a premium magazine-style single-page website showcasing four service offerings, with content primarily in Russian.
|
||||
|
||||
**Status**: Pre-development — only `PLANNING.md` (content + design specs) and `design-spec.jpg` (visual spec) exist. No framework or build tooling has been chosen yet.
|
||||
|
||||
## Design System
|
||||
|
||||
Strict visual identity — do not deviate from these values.
|
||||
|
||||
**Typography**:
|
||||
- Headlines: **Druk Wide Bold** (tight line-height ~0.9)
|
||||
- Body: **Inter Regular** only — no medium/bold weights for body text
|
||||
- Desktop: H1 48px/40px, H2 31px/30px, H3 24px/20px, Body 16px/18px, Caption 16px/44px
|
||||
- Mobile: H1 32px/40px, H2 34px/30px, H3 20px/80px, Body 16px/14px, Caption 14px/12px
|
||||
|
||||
**Color palette** (flat only — no gradients, shadows, or cards):
|
||||
| Name | Hex |
|
||||
|------|-----|
|
||||
| Blue | `#007DDA` |
|
||||
| Warm White | `#E7F2EA` |
|
||||
| Stone Grey | `#FCC3C3` |
|
||||
| Ink Black | `#BD5E24` |
|
||||
| Oxide Red | `#FB9322` |
|
||||
|
||||
**Grid**:
|
||||
- Desktop: 12 columns, 1200px container, 1424px max-width, 32px gutters
|
||||
- Mobile: 4 columns, 20px margins
|
||||
- Vertical spacing between sections: 160–220px
|
||||
|
||||
**Design don'ts**: No phone mockups, no SaaS/startup patterns, no subscription-style UI, no shadowed text, no icons, pills, or card components.
|
||||
|
||||
## Page Structure (5 Screens)
|
||||
|
||||
1. **Hero** — Massive left-aligned headline (~7 cols), smartphone mockup center-right (~4 cols), small editorial annotations with thin hairline connectors, primary CTA
|
||||
2. **Manifest** — Asymmetric layout, large text block (5 cols), opposite side mostly empty with small caption
|
||||
3. **Journal Preview** — Large image breaking grid (~7 cols), offset text block (~4 cols), oversized faded number in background
|
||||
4. **Selected Cases** — Dark background, 2×2 editorial image tiles (6 cols each), overlapping titles
|
||||
5. **Access/FAQ** — Editorial accordion (8 cols centered), numbered thin rows, one-at-a-time expand behavior
|
||||
|
||||
**Header**: Minimal sticky nav — wordmark left, text anchors right. Buttons: rectangular, 2–4px border-radius.
|
||||
|
||||
## Content
|
||||
|
||||
All service descriptions and UI copy are in Russian (see `PLANNING.md` for full text). Four service sections expand via accordion:
|
||||
1. Creative & strategy consultations
|
||||
2. Brand platform development
|
||||
3. Communication strategies
|
||||
4. Special projects & creative concepts
|
||||
|
||||
CTA directs to Telegram: @alinamamut
|
||||
43
IMPLEMENTATION.md
Normal file
43
IMPLEMENTATION.md
Normal file
@@ -0,0 +1,43 @@
|
||||
# Implementation Summary
|
||||
|
||||
## Tech Stack
|
||||
- **Vite 6** + Vanilla HTML/CSS/JS (no framework)
|
||||
- **Archivo** (Google Fonts, expanded width, weight 900) for headlines
|
||||
- **Inter** (Google Fonts, weight 400) for body text
|
||||
|
||||
## Project Structure
|
||||
```
|
||||
├── index.html # Single page with all 5 screens
|
||||
├── package.json
|
||||
├── vite.config.js
|
||||
├── public/
|
||||
├── src/
|
||||
│ ├── main.js # Scroll reveal, smooth scroll, header scroll
|
||||
│ ├── style.css # Master @import file
|
||||
│ ├── css/
|
||||
│ │ ├── reset.css # Modern CSS reset
|
||||
│ │ ├── tokens.css # Design tokens (colors, type, spacing, grid)
|
||||
│ │ ├── base.css # Typography classes (.h1, .h2, .h3)
|
||||
│ │ ├── grid.css # 12-col grid + utilities
|
||||
│ │ ├── components.css # Buttons, annotations, hairlines
|
||||
│ │ ├── header.css # Sticky header
|
||||
│ │ ├── hero.css # Screen 1
|
||||
│ │ ├── manifest.css # Screen 2
|
||||
│ │ ├── journal.css # Screen 3
|
||||
│ │ ├── cases.css # Screen 4
|
||||
│ │ ├── services.css # Screen 5 (accordion)
|
||||
│ │ ├── footer.css
|
||||
│ │ └── animations.css # Scroll-driven + IntersectionObserver fallback
|
||||
│ └── assets/
|
||||
```
|
||||
|
||||
## Running
|
||||
- `npm run dev` — development server with HMR
|
||||
- `npm run build` — production build to `dist/`
|
||||
- `npm run preview` — preview production build
|
||||
|
||||
## Design Decisions
|
||||
- Native `<details name="accordion">` for one-at-a-time accordion (zero JS)
|
||||
- CSS `animation-timeline: view()` with IntersectionObserver fallback
|
||||
- Colored placeholder blocks instead of images (swap with `<img>` later)
|
||||
- BEM-lite class naming
|
||||
142
PLANNING.md
Normal file
142
PLANNING.md
Normal file
@@ -0,0 +1,142 @@
|
||||
Here is the plan, that needs to be done, combining several inputs and tasks.
|
||||
|
||||
# Initial goal, reasoning and explanation of pages (in Russian):
|
||||
|
||||
Раздел 1:
|
||||
1. Консультации по креативу и стратегии
|
||||
|
||||
Выпадающий текст:
|
||||
Когда это нужно
|
||||
• Бренд чувствует, что коммуникации устарели;
|
||||
• Идеи есть, но они не складываются в систему и, главное, не приносят результат;
|
||||
• Команда не понимает, куда двигаться дальше;
|
||||
• Нужно свежее, независимое видение.
|
||||
|
||||
Что вы получаете
|
||||
• Разбор текущей коммуникации бренда;
|
||||
• Анализ визуального языка и смыслов;
|
||||
• Точки роста и возможности для отстройки;
|
||||
• Направления для креатива и спецпроектов.
|
||||
|
||||
Как происходит работа:
|
||||
1. Оперативный созвон-знакомство, вы заполняете бриф, по которому я готовлюсь к консультации;
|
||||
2. 2-часовая консультация;
|
||||
3. Презентация с рекомендациями и планом работ.
|
||||
|
||||
⸻
|
||||
Раздел 2:
|
||||
2. Бренд-платформа
|
||||
|
||||
Выпадающий текст:
|
||||
Когда это нужно
|
||||
• Проект не растет, нет клиентов;
|
||||
• Коммуникации выглядят разрозненно;
|
||||
• Нет четкого позиционирования и голоса;
|
||||
• Нет понимания, кто аудитория проекта;
|
||||
• Сложно масштабировать маркетинг.
|
||||
|
||||
Что вы получаете
|
||||
• Ядро бренда: аудитория, конкуренты, миссия, ценности, характер;
|
||||
• Чёткое позиционирование и big idea;
|
||||
• Tone of voice и визуальные принципы;
|
||||
• Основу для всех коммуникаций.
|
||||
|
||||
Как происходит работа:
|
||||
1. Оперативный созвон-знакомство, вы заполняете бриф;
|
||||
2. 2-4 недели разработки бренд-платформы – анализ аудитории и конкурентов, интервью с основателем (при необходимости с командой и клиентами/потенциальными клиентами);
|
||||
3. Презентация с готовой бренд-платформой.
|
||||
|
||||
⸻
|
||||
Раздел 3:
|
||||
3. Коммуникационные стратегии
|
||||
|
||||
Выпадающий текст:
|
||||
Когда это нужно
|
||||
• Бренд хочет выйти за рамки стандартной рекламы;
|
||||
• Нужно привлечь новую аудиторию;
|
||||
• Конкуренты выглядят ярче и смелее;
|
||||
• Нет ясного сценария развития коммуникаций.
|
||||
|
||||
Что вы получаете
|
||||
• Стратегию коммуникаций на основе трендов и инсайтов;
|
||||
• Ключевые смыслы и сообщения бренда;
|
||||
• Идеи форматов, контента и спецпроектов;
|
||||
• Дорожную карту – для кого, в каком канале, что необходимо сделать.
|
||||
|
||||
Как происходит работа:
|
||||
1. Оперативный созвон-знакомство, вы заполняете бриф;
|
||||
2. 2-4 недели разработки коммуникационной стратегии – анализ аудитории и коммуникации конкурентов, анализ лучших релевантных зарубежных и локальных практик;
|
||||
3. Презентация с готовой коммуникационной стратегией.
|
||||
⸻
|
||||
|
||||
Раздел 4:
|
||||
4. Идеи спецпроектов и креативные концепции
|
||||
|
||||
Выпадающий текст:
|
||||
Когда это нужно
|
||||
• Бренд хочет вау-эффект без банальных решений;
|
||||
• Нужна идея, которую будут обсуждать;
|
||||
• Важно выйти за рамки стандартных форматов.
|
||||
|
||||
Что вы получаете
|
||||
• Концепции спецпроектов;
|
||||
• Сценарии интеграций и коллабораций;
|
||||
• Решения, которые можно масштабировать.
|
||||
|
||||
Как происходит работа:
|
||||
1. Оперативный созвон-знакомство, вы заполняете бриф;
|
||||
2. 2-3 недели разработки идеи – сбор референс, анализ лучших практик, подготовка идеи;
|
||||
3. Презентация с готовой коммуникационной стратегией.
|
||||
|
||||
Далее колл-ту-экшен:
|
||||
Я могу как разработать идею, так и взять на себя всю реализацию при помощи мой команды профессионалов.
|
||||
|
||||
Чтобы ознакомиться с моим портфолио и реализованными кейсами, пожалуйста, напишите мне: @alinamamut
|
||||
|
||||
Внизу подвал с политикой конфиденциальности и тд
|
||||
|
||||
***
|
||||
По арт-дирекшену:
|
||||
1. Шрифт заголовков – Druk Wide Bold
|
||||
2. Шрифт основного текста – Inter Regular
|
||||
3. Сверстать необходимо по референту – в том же стиле, что и в файле
|
||||
|
||||
# WebPage coding prompt that was generated by some LLM:
|
||||
|
||||
Create a premium editorial landing page for a cultural trend journal. The design must feel like a high-end magazine, not a startup. Style: brutal typography, strong grid, oversized type, large negative space, minimal color, zero friendly marketing patterns.
|
||||
|
||||
Grid: desktop 12 columns, container 1280px, max-width 1560px, gutter 32px, outer margins 96px. Vertical spacing 160–220px. Mobile: 4 columns, 20px margins.
|
||||
|
||||
Typography: Headlines similar to Druk Wide Bold. Body Inter Regular only. No medium weights. Massive scale contrast. Tight line-height for headers (~0.9). Large readable body (~20–22px desktop).
|
||||
|
||||
Color palette: warm white (#F7F7F5), ink black (#0A0A0A), oxide red (#B3342B), dusty blue (#6F8FA6), stone grey (#D9D9D6). Flat colors only. No gradients.
|
||||
|
||||
⸻
|
||||
|
||||
Screen 1 — Hero
|
||||
|
||||
Massive left-aligned headline spanning ~7 columns. Center-right smartphone mockup (~4 columns). 3–4 small editorial annotations with thin hairline connector lines. Primary button below headline. Leave 30–40% empty space.
|
||||
|
||||
Screen 2 — Manifest
|
||||
|
||||
Asymmetric layout. Large intellectual text block (5 columns). Opposite side mostly empty with a small caption in the top corner.
|
||||
|
||||
Screen 3 — Journal Preview
|
||||
|
||||
Large issue image breaking grid (~7 columns). Text block offset vertically (~4 columns). Oversized faded issue number in background. Two buttons: primary + outline.
|
||||
|
||||
Screen 4 — Selected Cases
|
||||
|
||||
Dark background. 2×2 editorial tiles (6 columns each). No cards, no shadows. Image-led with overlapping titles.
|
||||
|
||||
Screen 5 — Access
|
||||
|
||||
Editorial accordion centered in grid (8 columns). Closed: thin rows with numbers. Open: split text + button. One item open at a time.
|
||||
|
||||
Header: minimal sticky nav with wordmark left, text anchors right.
|
||||
Buttons: rectangular, 2–4px radius.
|
||||
Avoid icons, cards, gradients, pills, and SaaS visuals. Make it intellectual, cultural, and expensive.
|
||||
|
||||
# Additional DESIGN specification
|
||||
|
||||
Local file called design-spec.jpg
|
||||
BIN
design-spec.jpg
Normal file
BIN
design-spec.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 101 KiB |
307
index.html
Normal file
307
index.html
Normal file
@@ -0,0 +1,307 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="ru">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Alina Mamut — Бренд-стратегия и креативный консалтинг</title>
|
||||
<meta name="description" content="Бренд-стратегия, креативный консалтинг и коммуникационные стратегии от Алины Мамут." />
|
||||
|
||||
<!-- Fonts -->
|
||||
<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=Archivo:ital,wdth,wght@0,62..150,100..900;1,62..150,100..900&family=Inter:wght@400&display=swap" rel="stylesheet" />
|
||||
|
||||
<link rel="stylesheet" href="/src/style.css" />
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<!-- ============ HEADER ============ -->
|
||||
<header class="header" id="header">
|
||||
<div class="header__inner container">
|
||||
<a href="#" class="header__wordmark">ALINA MAMUT</a>
|
||||
<nav class="header__nav">
|
||||
<a href="#manifest" class="header__link">О подходе</a>
|
||||
<a href="#journal" class="header__link">Журнал</a>
|
||||
<a href="#cases" class="header__link">Кейсы</a>
|
||||
<a href="#services" class="header__link">Услуги</a>
|
||||
</nav>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<!-- ============ SCREEN 1: HERO ============ -->
|
||||
<section class="hero" id="hero">
|
||||
<div class="hero__inner container grid">
|
||||
<div class="hero__headline-block col-span-7" data-reveal>
|
||||
<h1 class="h1 hero__title">Бренд-стратегия<br />и креативный<br />консалтинг</h1>
|
||||
<p class="body-text hero__subtitle">Помогаю брендам находить свой голос, формировать стратегию и создавать коммуникации, которые работают.</p>
|
||||
<a href="https://t.me/alinamamut" class="btn btn--primary hero__cta" target="_blank" rel="noopener">Написать в Telegram</a>
|
||||
</div>
|
||||
<div class="hero__editorial col-start-8 col-span-5" data-reveal>
|
||||
<div class="hero__image-placeholder"></div>
|
||||
</div>
|
||||
<div class="hero__annotations col-span-7" data-reveal>
|
||||
<div class="annotation">
|
||||
<div class="annotation__label">Опыт</div>
|
||||
<div class="annotation__text">10+ лет в брендинге и стратегии</div>
|
||||
</div>
|
||||
<div class="annotation">
|
||||
<div class="annotation__label">Подход</div>
|
||||
<div class="annotation__text">Исследования, аналитика, креатив</div>
|
||||
</div>
|
||||
<div class="annotation">
|
||||
<div class="annotation__label">Результат</div>
|
||||
<div class="annotation__text">Система, а не разовые решения</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- ============ SCREEN 2: MANIFEST ============ -->
|
||||
<section class="manifest" id="manifest">
|
||||
<div class="manifest__inner container grid">
|
||||
<div class="manifest__text col-span-5" data-reveal>
|
||||
<h2 class="h2 manifest__heading">Я верю, что сильный бренд — это не логотип и не визуал. Это стратегия, смыслы и последовательность.</h2>
|
||||
<p class="body-text manifest__body">Каждый проект начинается с глубокого понимания: кто вы, для кого вы и зачем вы существуете. Я нахожу ответы, которые становятся основой для всех ваших коммуникаций — от позиционирования до рекламных кампаний.</p>
|
||||
</div>
|
||||
<div class="manifest__caption col-start-9 col-span-4" data-reveal>
|
||||
<span class="caption">О подходе</span>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- ============ SCREEN 3: JOURNAL PREVIEW ============ -->
|
||||
<section class="journal" id="journal" data-number="01">
|
||||
<div class="journal__inner container grid">
|
||||
<div class="journal__image-block col-span-7" data-reveal>
|
||||
<div class="journal__image-placeholder"></div>
|
||||
</div>
|
||||
<div class="journal__text-block col-start-9 col-span-4" data-reveal>
|
||||
<h2 class="h2 journal__heading">Стратегия — это не документ. Это способ думать о бренде каждый день.</h2>
|
||||
<p class="body-text journal__body">Результат моей работы — не просто презентация на 50 слайдов. Это живой инструмент, который помогает принимать решения, формировать контент и развивать бренд осознанно.</p>
|
||||
<div class="journal__buttons">
|
||||
<a href="https://t.me/alinamamut" class="btn btn--primary" target="_blank" rel="noopener">Обсудить проект</a>
|
||||
<a href="#services" class="btn btn--outline">Подробнее об услугах</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- ============ SCREEN 4: SELECTED CASES ============ -->
|
||||
<section class="cases" id="cases">
|
||||
<div class="cases__inner container">
|
||||
<h2 class="h2 cases__heading" data-reveal>Избранные кейсы</h2>
|
||||
<div class="cases__grid grid">
|
||||
<div class="cases__tile col-span-6" data-reveal>
|
||||
<div class="cases__tile-image" style="background-color: var(--color-primary);"></div>
|
||||
<h3 class="h3 cases__tile-title">Ребрендинг и стратегия коммуникаций</h3>
|
||||
</div>
|
||||
<div class="cases__tile col-span-6" data-reveal>
|
||||
<div class="cases__tile-image" style="background-color: var(--color-surface);"></div>
|
||||
<h3 class="h3 cases__tile-title">Бренд-платформа с нуля</h3>
|
||||
</div>
|
||||
<div class="cases__tile col-span-6" data-reveal>
|
||||
<div class="cases__tile-image" style="background-color: var(--color-ink);"></div>
|
||||
<h3 class="h3 cases__tile-title">Креативная концепция спецпроекта</h3>
|
||||
</div>
|
||||
<div class="cases__tile col-span-6" data-reveal>
|
||||
<div class="cases__tile-image" style="background-color: var(--color-accent);"></div>
|
||||
<h3 class="h3 cases__tile-title">Коммуникационная стратегия</h3>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- ============ SCREEN 5: SERVICES / ACCORDION ============ -->
|
||||
<section class="services" id="services">
|
||||
<div class="services__inner container grid">
|
||||
<div class="services__block col-start-3 col-span-8">
|
||||
<h2 class="h2 services__heading" data-reveal>Услуги</h2>
|
||||
|
||||
<!-- Service 1 -->
|
||||
<details class="services__item" name="accordion" data-reveal>
|
||||
<summary class="services__summary">
|
||||
<span class="services__number">01</span>
|
||||
<span class="services__title">Консультации по креативу и стратегии</span>
|
||||
<span class="services__icon">+</span>
|
||||
</summary>
|
||||
<div class="services__content">
|
||||
<div class="services__content-left">
|
||||
<div class="services__section">
|
||||
<h4 class="services__section-title">Когда это нужно</h4>
|
||||
<ul class="services__list">
|
||||
<li>Бренд чувствует, что коммуникации устарели;</li>
|
||||
<li>Идеи есть, но они не складываются в систему и, главное, не приносят результат;</li>
|
||||
<li>Команда не понимает, куда двигаться дальше;</li>
|
||||
<li>Нужно свежее, независимое видение.</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="services__section">
|
||||
<h4 class="services__section-title">Что вы получаете</h4>
|
||||
<ul class="services__list">
|
||||
<li>Разбор текущей коммуникации бренда;</li>
|
||||
<li>Анализ визуального языка и смыслов;</li>
|
||||
<li>Точки роста и возможности для отстройки;</li>
|
||||
<li>Направления для креатива и спецпроектов.</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div class="services__content-right">
|
||||
<div class="services__section">
|
||||
<h4 class="services__section-title">Как происходит работа</h4>
|
||||
<ol class="services__steps">
|
||||
<li>Оперативный созвон-знакомство, вы заполняете бриф, по которому я готовлюсь к консультации;</li>
|
||||
<li>2-часовая консультация;</li>
|
||||
<li>Презентация с рекомендациями и планом работ.</li>
|
||||
</ol>
|
||||
</div>
|
||||
<a href="https://t.me/alinamamut" class="btn btn--primary services__cta" target="_blank" rel="noopener">Записаться</a>
|
||||
</div>
|
||||
</div>
|
||||
</details>
|
||||
|
||||
<!-- Service 2 -->
|
||||
<details class="services__item" name="accordion" data-reveal>
|
||||
<summary class="services__summary">
|
||||
<span class="services__number">02</span>
|
||||
<span class="services__title">Бренд-платформа</span>
|
||||
<span class="services__icon">+</span>
|
||||
</summary>
|
||||
<div class="services__content">
|
||||
<div class="services__content-left">
|
||||
<div class="services__section">
|
||||
<h4 class="services__section-title">Когда это нужно</h4>
|
||||
<ul class="services__list">
|
||||
<li>Проект не растет, нет клиентов;</li>
|
||||
<li>Коммуникации выглядят разрозненно;</li>
|
||||
<li>Нет четкого позиционирования и голоса;</li>
|
||||
<li>Нет понимания, кто аудитория проекта;</li>
|
||||
<li>Сложно масштабировать маркетинг.</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="services__section">
|
||||
<h4 class="services__section-title">Что вы получаете</h4>
|
||||
<ul class="services__list">
|
||||
<li>Ядро бренда: аудитория, конкуренты, миссия, ценности, характер;</li>
|
||||
<li>Чёткое позиционирование и big idea;</li>
|
||||
<li>Tone of voice и визуальные принципы;</li>
|
||||
<li>Основу для всех коммуникаций.</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div class="services__content-right">
|
||||
<div class="services__section">
|
||||
<h4 class="services__section-title">Как происходит работа</h4>
|
||||
<ol class="services__steps">
|
||||
<li>Оперативный созвон-знакомство, вы заполняете бриф;</li>
|
||||
<li>2-4 недели разработки бренд-платформы — анализ аудитории и конкурентов, интервью с основателем (при необходимости с командой и клиентами/потенциальными клиентами);</li>
|
||||
<li>Презентация с готовой бренд-платформой.</li>
|
||||
</ol>
|
||||
</div>
|
||||
<a href="https://t.me/alinamamut" class="btn btn--primary services__cta" target="_blank" rel="noopener">Записаться</a>
|
||||
</div>
|
||||
</div>
|
||||
</details>
|
||||
|
||||
<!-- Service 3 -->
|
||||
<details class="services__item" name="accordion" data-reveal>
|
||||
<summary class="services__summary">
|
||||
<span class="services__number">03</span>
|
||||
<span class="services__title">Коммуникационные стратегии</span>
|
||||
<span class="services__icon">+</span>
|
||||
</summary>
|
||||
<div class="services__content">
|
||||
<div class="services__content-left">
|
||||
<div class="services__section">
|
||||
<h4 class="services__section-title">Когда это нужно</h4>
|
||||
<ul class="services__list">
|
||||
<li>Бренд хочет выйти за рамки стандартной рекламы;</li>
|
||||
<li>Нужно привлечь новую аудиторию;</li>
|
||||
<li>Конкуренты выглядят ярче и смелее;</li>
|
||||
<li>Нет ясного сценария развития коммуникаций.</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="services__section">
|
||||
<h4 class="services__section-title">Что вы получаете</h4>
|
||||
<ul class="services__list">
|
||||
<li>Стратегию коммуникаций на основе трендов и инсайтов;</li>
|
||||
<li>Ключевые смыслы и сообщения бренда;</li>
|
||||
<li>Идеи форматов, контента и спецпроектов;</li>
|
||||
<li>Дорожную карту — для кого, в каком канале, что необходимо сделать.</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div class="services__content-right">
|
||||
<div class="services__section">
|
||||
<h4 class="services__section-title">Как происходит работа</h4>
|
||||
<ol class="services__steps">
|
||||
<li>Оперативный созвон-знакомство, вы заполняете бриф;</li>
|
||||
<li>2-4 недели разработки коммуникационной стратегии — анализ аудитории и коммуникации конкурентов, анализ лучших релевантных зарубежных и локальных практик;</li>
|
||||
<li>Презентация с готовой коммуникационной стратегией.</li>
|
||||
</ol>
|
||||
</div>
|
||||
<a href="https://t.me/alinamamut" class="btn btn--primary services__cta" target="_blank" rel="noopener">Записаться</a>
|
||||
</div>
|
||||
</div>
|
||||
</details>
|
||||
|
||||
<!-- Service 4 -->
|
||||
<details class="services__item" name="accordion" data-reveal>
|
||||
<summary class="services__summary">
|
||||
<span class="services__number">04</span>
|
||||
<span class="services__title">Идеи спецпроектов и креативные концепции</span>
|
||||
<span class="services__icon">+</span>
|
||||
</summary>
|
||||
<div class="services__content">
|
||||
<div class="services__content-left">
|
||||
<div class="services__section">
|
||||
<h4 class="services__section-title">Когда это нужно</h4>
|
||||
<ul class="services__list">
|
||||
<li>Бренд хочет вау-эффект без банальных решений;</li>
|
||||
<li>Нужна идея, которую будут обсуждать;</li>
|
||||
<li>Важно выйти за рамки стандартных форматов.</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="services__section">
|
||||
<h4 class="services__section-title">Что вы получаете</h4>
|
||||
<ul class="services__list">
|
||||
<li>Концепции спецпроектов;</li>
|
||||
<li>Сценарии интеграций и коллабораций;</li>
|
||||
<li>Решения, которые можно масштабировать.</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div class="services__content-right">
|
||||
<div class="services__section">
|
||||
<h4 class="services__section-title">Как происходит работа</h4>
|
||||
<ol class="services__steps">
|
||||
<li>Оперативный созвон-знакомство, вы заполняете бриф;</li>
|
||||
<li>2-3 недели разработки идеи — сбор референс, анализ лучших практик, подготовка идеи;</li>
|
||||
<li>Презентация с готовой креативной концепцией.</li>
|
||||
</ol>
|
||||
</div>
|
||||
<a href="https://t.me/alinamamut" class="btn btn--primary services__cta" target="_blank" rel="noopener">Записаться</a>
|
||||
</div>
|
||||
</div>
|
||||
</details>
|
||||
|
||||
<div class="services__footer" data-reveal>
|
||||
<p class="body-text services__footer-text">Я могу как разработать идею, так и взять на себя всю реализацию при помощи моей команды профессионалов.</p>
|
||||
<p class="body-text services__footer-text">Чтобы ознакомиться с моим портфолио и реализованными кейсами, пожалуйста, напишите мне:</p>
|
||||
<a href="https://t.me/alinamamut" class="btn btn--primary" target="_blank" rel="noopener">@alinamamut</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- ============ FOOTER ============ -->
|
||||
<footer class="footer">
|
||||
<div class="footer__inner container">
|
||||
<span class="footer__copy">© 2026 Alina Mamut</span>
|
||||
<a href="https://t.me/alinamamut" class="footer__telegram" target="_blank" rel="noopener">@alinamamut</a>
|
||||
<a href="#" class="footer__privacy">Политика конфиденциальности</a>
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
<script type="module" src="/src/main.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
1104
package-lock.json
generated
Normal file
1104
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
14
package.json
Normal file
14
package.json
Normal file
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"name": "alina-design-website",
|
||||
"private": true,
|
||||
"version": "1.0.0",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
"build": "vite build",
|
||||
"preview": "vite preview"
|
||||
},
|
||||
"devDependencies": {
|
||||
"vite": "^6.0.0"
|
||||
}
|
||||
}
|
||||
49
src/css/animations.css
Normal file
49
src/css/animations.css
Normal file
@@ -0,0 +1,49 @@
|
||||
/* ===== IntersectionObserver fallback ===== */
|
||||
[data-reveal] {
|
||||
opacity: 0;
|
||||
transform: translateY(24px);
|
||||
transition: opacity 0.6s ease, transform 0.6s ease;
|
||||
}
|
||||
|
||||
[data-reveal].is-visible {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
}
|
||||
|
||||
/* ===== Scroll-driven animations (progressive enhancement) ===== */
|
||||
.has-scroll-driven [data-reveal] {
|
||||
opacity: 1;
|
||||
transform: none;
|
||||
transition: none;
|
||||
|
||||
animation: reveal-in linear both;
|
||||
animation-timeline: view();
|
||||
animation-range: entry 0% entry 30%;
|
||||
}
|
||||
|
||||
@keyframes reveal-in {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: translateY(24px);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
|
||||
/* Details open/close transition */
|
||||
.services__content {
|
||||
animation: accordion-open 0.25s ease;
|
||||
}
|
||||
|
||||
@keyframes accordion-open {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: translateY(-8px);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
53
src/css/base.css
Normal file
53
src/css/base.css
Normal file
@@ -0,0 +1,53 @@
|
||||
body {
|
||||
font-family: var(--font-body);
|
||||
font-size: var(--body-size);
|
||||
line-height: var(--body-lh);
|
||||
color: var(--color-dark);
|
||||
background-color: var(--color-bg);
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
.h1 {
|
||||
font-family: var(--font-headline);
|
||||
font-size: var(--h1-size);
|
||||
line-height: var(--h1-lh);
|
||||
font-weight: 900;
|
||||
font-stretch: 125%;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: -0.02em;
|
||||
}
|
||||
|
||||
.h2 {
|
||||
font-family: var(--font-headline);
|
||||
font-size: var(--h2-size);
|
||||
line-height: var(--h2-lh);
|
||||
font-weight: 900;
|
||||
font-stretch: 125%;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: -0.01em;
|
||||
}
|
||||
|
||||
.h3 {
|
||||
font-family: var(--font-headline);
|
||||
font-size: var(--h3-size);
|
||||
line-height: var(--h3-lh);
|
||||
font-weight: 900;
|
||||
font-stretch: 125%;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.body-text {
|
||||
font-family: var(--font-body);
|
||||
font-size: var(--body-size);
|
||||
line-height: calc(var(--body-lh) + 6px);
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
.caption {
|
||||
font-family: var(--font-body);
|
||||
font-size: var(--caption-size);
|
||||
line-height: var(--caption-lh);
|
||||
font-weight: 400;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.05em;
|
||||
}
|
||||
52
src/css/cases.css
Normal file
52
src/css/cases.css
Normal file
@@ -0,0 +1,52 @@
|
||||
.cases {
|
||||
padding: var(--section-gap) 0;
|
||||
background-color: var(--color-dark);
|
||||
color: var(--color-white);
|
||||
}
|
||||
|
||||
.cases__heading {
|
||||
margin-bottom: 60px;
|
||||
}
|
||||
|
||||
.cases__grid {
|
||||
row-gap: var(--grid-gutter);
|
||||
}
|
||||
|
||||
.cases__tile {
|
||||
display: grid;
|
||||
grid-template: 1fr / 1fr;
|
||||
overflow: hidden;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.cases__tile-image {
|
||||
grid-area: 1 / 1;
|
||||
width: 100%;
|
||||
aspect-ratio: 4 / 3;
|
||||
transition: transform 0.4s ease;
|
||||
}
|
||||
|
||||
.cases__tile:hover .cases__tile-image {
|
||||
transform: scale(1.03);
|
||||
}
|
||||
|
||||
.cases__tile-title {
|
||||
grid-area: 1 / 1;
|
||||
align-self: end;
|
||||
padding: 24px;
|
||||
color: var(--color-white);
|
||||
mix-blend-mode: difference;
|
||||
z-index: 1;
|
||||
line-height: 1.2;
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.cases__heading {
|
||||
margin-bottom: 32px;
|
||||
}
|
||||
|
||||
.cases__tile-title {
|
||||
padding: 16px;
|
||||
font-size: 16px;
|
||||
}
|
||||
}
|
||||
89
src/css/components.css
Normal file
89
src/css/components.css
Normal file
@@ -0,0 +1,89 @@
|
||||
.btn {
|
||||
display: inline-block;
|
||||
font-family: var(--font-body);
|
||||
font-size: 14px;
|
||||
font-weight: 400;
|
||||
letter-spacing: 0.05em;
|
||||
text-transform: uppercase;
|
||||
padding: 14px 32px;
|
||||
border-radius: var(--btn-radius);
|
||||
border: 1.5px solid transparent;
|
||||
cursor: pointer;
|
||||
transition: background-color 0.2s, color 0.2s, border-color 0.2s;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.btn--primary {
|
||||
background-color: var(--color-dark);
|
||||
color: var(--color-white);
|
||||
border-color: var(--color-dark);
|
||||
}
|
||||
|
||||
.btn--primary:hover {
|
||||
background-color: transparent;
|
||||
color: var(--color-dark);
|
||||
}
|
||||
|
||||
.btn--outline {
|
||||
background-color: transparent;
|
||||
color: var(--color-dark);
|
||||
border-color: var(--color-dark);
|
||||
}
|
||||
|
||||
.btn--outline:hover {
|
||||
background-color: var(--color-dark);
|
||||
color: var(--color-white);
|
||||
}
|
||||
|
||||
.btn--light {
|
||||
background-color: var(--color-white);
|
||||
color: var(--color-dark);
|
||||
border-color: var(--color-white);
|
||||
}
|
||||
|
||||
.btn--light:hover {
|
||||
background-color: transparent;
|
||||
color: var(--color-white);
|
||||
}
|
||||
|
||||
.hairline {
|
||||
width: 1px;
|
||||
background-color: var(--color-dark);
|
||||
opacity: 0.3;
|
||||
}
|
||||
|
||||
.hairline--h {
|
||||
width: 100%;
|
||||
height: 1px;
|
||||
}
|
||||
|
||||
.annotation {
|
||||
position: relative;
|
||||
padding-left: 16px;
|
||||
}
|
||||
|
||||
.annotation::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
width: 1px;
|
||||
background-color: var(--color-dark);
|
||||
opacity: 0.3;
|
||||
}
|
||||
|
||||
.annotation__label {
|
||||
font-family: var(--font-body);
|
||||
font-size: 11px;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.1em;
|
||||
opacity: 0.5;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
|
||||
.annotation__text {
|
||||
font-family: var(--font-body);
|
||||
font-size: 13px;
|
||||
line-height: 1.4;
|
||||
}
|
||||
31
src/css/footer.css
Normal file
31
src/css/footer.css
Normal file
@@ -0,0 +1,31 @@
|
||||
.footer {
|
||||
padding: 40px 0;
|
||||
border-top: 1px solid rgba(26, 26, 26, 0.15);
|
||||
}
|
||||
|
||||
.footer__inner {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.footer__copy,
|
||||
.footer__telegram,
|
||||
.footer__privacy {
|
||||
font-family: var(--font-body);
|
||||
font-size: 13px;
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
.footer__telegram:hover,
|
||||
.footer__privacy:hover {
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.footer__inner {
|
||||
flex-direction: column;
|
||||
gap: 12px;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
76
src/css/grid.css
Normal file
76
src/css/grid.css
Normal file
@@ -0,0 +1,76 @@
|
||||
.container {
|
||||
width: 100%;
|
||||
max-width: var(--grid-max);
|
||||
margin: 0 auto;
|
||||
padding: 0 var(--grid-margin);
|
||||
}
|
||||
|
||||
.grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(var(--grid-columns), 1fr);
|
||||
gap: var(--grid-gutter);
|
||||
}
|
||||
|
||||
/* Column span utilities */
|
||||
.col-span-1 { grid-column: span 1; }
|
||||
.col-span-2 { grid-column: span 2; }
|
||||
.col-span-3 { grid-column: span 3; }
|
||||
.col-span-4 { grid-column: span 4; }
|
||||
.col-span-5 { grid-column: span 5; }
|
||||
.col-span-6 { grid-column: span 6; }
|
||||
.col-span-7 { grid-column: span 7; }
|
||||
.col-span-8 { grid-column: span 8; }
|
||||
.col-span-9 { grid-column: span 9; }
|
||||
.col-span-10 { grid-column: span 10; }
|
||||
.col-span-11 { grid-column: span 11; }
|
||||
.col-span-12 { grid-column: span 12; }
|
||||
|
||||
/* Column start utilities */
|
||||
.col-start-1 { grid-column-start: 1; }
|
||||
.col-start-2 { grid-column-start: 2; }
|
||||
.col-start-3 { grid-column-start: 3; }
|
||||
.col-start-4 { grid-column-start: 4; }
|
||||
.col-start-5 { grid-column-start: 5; }
|
||||
.col-start-6 { grid-column-start: 6; }
|
||||
.col-start-7 { grid-column-start: 7; }
|
||||
.col-start-8 { grid-column-start: 8; }
|
||||
.col-start-9 { grid-column-start: 9; }
|
||||
.col-start-10 { grid-column-start: 10; }
|
||||
.col-start-11 { grid-column-start: 11; }
|
||||
.col-start-12 { grid-column-start: 12; }
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.container {
|
||||
padding: 0 var(--grid-margin);
|
||||
}
|
||||
|
||||
.col-span-1,
|
||||
.col-span-2,
|
||||
.col-span-3,
|
||||
.col-span-4,
|
||||
.col-span-5,
|
||||
.col-span-6,
|
||||
.col-span-7,
|
||||
.col-span-8,
|
||||
.col-span-9,
|
||||
.col-span-10,
|
||||
.col-span-11,
|
||||
.col-span-12 {
|
||||
grid-column: span 4;
|
||||
}
|
||||
|
||||
.col-start-1,
|
||||
.col-start-2,
|
||||
.col-start-3,
|
||||
.col-start-4,
|
||||
.col-start-5,
|
||||
.col-start-6,
|
||||
.col-start-7,
|
||||
.col-start-8,
|
||||
.col-start-9,
|
||||
.col-start-10,
|
||||
.col-start-11,
|
||||
.col-start-12 {
|
||||
grid-column-start: 1;
|
||||
}
|
||||
}
|
||||
59
src/css/header.css
Normal file
59
src/css/header.css
Normal file
@@ -0,0 +1,59 @@
|
||||
.header {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
z-index: 100;
|
||||
height: var(--header-height);
|
||||
background-color: rgba(231, 242, 234, 0.85);
|
||||
border-bottom: 1px solid rgba(26, 26, 26, 0.1);
|
||||
transition: backdrop-filter 0.3s;
|
||||
}
|
||||
|
||||
.header--scrolled {
|
||||
backdrop-filter: blur(8px);
|
||||
-webkit-backdrop-filter: blur(8px);
|
||||
}
|
||||
|
||||
.header__inner {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.header__wordmark {
|
||||
font-family: var(--font-headline);
|
||||
font-weight: 900;
|
||||
font-stretch: 125%;
|
||||
font-size: 14px;
|
||||
letter-spacing: 0.05em;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.header__nav {
|
||||
display: flex;
|
||||
gap: 32px;
|
||||
}
|
||||
|
||||
.header__link {
|
||||
font-family: var(--font-body);
|
||||
font-size: 13px;
|
||||
letter-spacing: 0.03em;
|
||||
opacity: 0.7;
|
||||
transition: opacity 0.2s;
|
||||
}
|
||||
|
||||
.header__link:hover {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.header__nav {
|
||||
gap: 16px;
|
||||
}
|
||||
|
||||
.header__link {
|
||||
font-size: 12px;
|
||||
}
|
||||
}
|
||||
72
src/css/hero.css
Normal file
72
src/css/hero.css
Normal file
@@ -0,0 +1,72 @@
|
||||
.hero {
|
||||
min-height: 100vh;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding-top: var(--header-height);
|
||||
padding-bottom: 80px;
|
||||
}
|
||||
|
||||
.hero__inner {
|
||||
align-items: start;
|
||||
row-gap: 60px;
|
||||
}
|
||||
|
||||
.hero__headline-block {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 32px;
|
||||
padding-top: 80px;
|
||||
}
|
||||
|
||||
.hero__title {
|
||||
max-width: 600px;
|
||||
}
|
||||
|
||||
.hero__subtitle {
|
||||
max-width: 420px;
|
||||
opacity: 0.7;
|
||||
}
|
||||
|
||||
.hero__editorial {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding-top: 80px;
|
||||
}
|
||||
|
||||
.hero__image-placeholder {
|
||||
width: 100%;
|
||||
aspect-ratio: 3 / 4;
|
||||
background-color: var(--color-primary);
|
||||
max-height: 500px;
|
||||
}
|
||||
|
||||
.hero__annotations {
|
||||
display: flex;
|
||||
gap: 40px;
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.hero {
|
||||
min-height: auto;
|
||||
padding-top: calc(var(--header-height) + 40px);
|
||||
padding-bottom: 60px;
|
||||
}
|
||||
|
||||
.hero__headline-block {
|
||||
padding-top: 40px;
|
||||
}
|
||||
|
||||
.hero__editorial {
|
||||
padding-top: 0;
|
||||
}
|
||||
|
||||
.hero__image-placeholder {
|
||||
max-height: 300px;
|
||||
}
|
||||
|
||||
.hero__annotations {
|
||||
flex-direction: column;
|
||||
gap: 24px;
|
||||
}
|
||||
}
|
||||
73
src/css/journal.css
Normal file
73
src/css/journal.css
Normal file
@@ -0,0 +1,73 @@
|
||||
.journal {
|
||||
padding: var(--section-gap) 0;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.journal::after {
|
||||
content: attr(data-number);
|
||||
position: absolute;
|
||||
top: -40px;
|
||||
right: 5%;
|
||||
font-family: var(--font-headline);
|
||||
font-weight: 900;
|
||||
font-stretch: 125%;
|
||||
font-size: clamp(200px, 30vw, 400px);
|
||||
line-height: 1;
|
||||
color: var(--color-dark);
|
||||
opacity: 0.04;
|
||||
pointer-events: none;
|
||||
z-index: 0;
|
||||
}
|
||||
|
||||
.journal__inner {
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
align-items: end;
|
||||
}
|
||||
|
||||
.journal__image-block {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.journal__image-placeholder {
|
||||
width: 100%;
|
||||
height: 500px;
|
||||
background-color: var(--color-surface);
|
||||
object-fit: cover;
|
||||
}
|
||||
|
||||
.journal__text-block {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 20px;
|
||||
align-self: end;
|
||||
}
|
||||
|
||||
.journal__body {
|
||||
opacity: 0.7;
|
||||
}
|
||||
|
||||
.journal__buttons {
|
||||
display: flex;
|
||||
gap: 16px;
|
||||
margin-top: 12px;
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.journal__image-placeholder {
|
||||
height: 300px;
|
||||
}
|
||||
|
||||
.journal__text-block {
|
||||
align-self: start;
|
||||
}
|
||||
|
||||
.journal__buttons {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.journal__buttons .btn {
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
39
src/css/manifest.css
Normal file
39
src/css/manifest.css
Normal file
@@ -0,0 +1,39 @@
|
||||
.manifest {
|
||||
padding: var(--section-gap) 0;
|
||||
}
|
||||
|
||||
.manifest__inner {
|
||||
align-items: start;
|
||||
}
|
||||
|
||||
.manifest__text {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 28px;
|
||||
}
|
||||
|
||||
.manifest__heading {
|
||||
color: var(--color-dark);
|
||||
}
|
||||
|
||||
.manifest__body {
|
||||
opacity: 0.7;
|
||||
max-width: 400px;
|
||||
}
|
||||
|
||||
.manifest__caption {
|
||||
text-align: right;
|
||||
padding-top: 8px;
|
||||
}
|
||||
|
||||
.manifest__caption .caption {
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.manifest__caption {
|
||||
text-align: left;
|
||||
order: -1;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
}
|
||||
61
src/css/reset.css
Normal file
61
src/css/reset.css
Normal file
@@ -0,0 +1,61 @@
|
||||
*,
|
||||
*::before,
|
||||
*::after {
|
||||
box-sizing: border-box;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
html {
|
||||
-moz-text-size-adjust: none;
|
||||
-webkit-text-size-adjust: none;
|
||||
text-size-adjust: none;
|
||||
scroll-behavior: smooth;
|
||||
}
|
||||
|
||||
body {
|
||||
min-height: 100vh;
|
||||
line-height: 1.5;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
}
|
||||
|
||||
img,
|
||||
picture,
|
||||
video,
|
||||
svg {
|
||||
display: block;
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
input,
|
||||
button,
|
||||
textarea,
|
||||
select {
|
||||
font: inherit;
|
||||
}
|
||||
|
||||
h1, h2, h3, h4, h5, h6 {
|
||||
overflow-wrap: break-word;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
a {
|
||||
color: inherit;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
ul, ol {
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
details summary {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
details summary::-webkit-details-marker {
|
||||
display: none;
|
||||
}
|
||||
|
||||
details summary::marker {
|
||||
content: '';
|
||||
}
|
||||
150
src/css/services.css
Normal file
150
src/css/services.css
Normal file
@@ -0,0 +1,150 @@
|
||||
.services {
|
||||
padding: var(--section-gap) 0;
|
||||
}
|
||||
|
||||
.services__heading {
|
||||
margin-bottom: 48px;
|
||||
}
|
||||
|
||||
.services__item {
|
||||
border-top: 1px solid rgba(26, 26, 26, 0.2);
|
||||
}
|
||||
|
||||
.services__item:last-of-type {
|
||||
border-bottom: 1px solid rgba(26, 26, 26, 0.2);
|
||||
}
|
||||
|
||||
.services__summary {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 24px;
|
||||
padding: 24px 0;
|
||||
list-style: none;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.services__number {
|
||||
font-family: var(--font-body);
|
||||
font-size: 13px;
|
||||
opacity: 0.4;
|
||||
min-width: 28px;
|
||||
}
|
||||
|
||||
.services__title {
|
||||
font-family: var(--font-headline);
|
||||
font-size: clamp(16px, 1.5vw, 20px);
|
||||
font-weight: 900;
|
||||
font-stretch: 125%;
|
||||
text-transform: uppercase;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.services__icon {
|
||||
font-size: 24px;
|
||||
font-weight: 300;
|
||||
opacity: 0.5;
|
||||
transition: transform 0.3s;
|
||||
}
|
||||
|
||||
.services__item[open] .services__icon {
|
||||
transform: rotate(45deg);
|
||||
}
|
||||
|
||||
.services__content {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
gap: 40px;
|
||||
padding: 8px 0 40px 52px;
|
||||
}
|
||||
|
||||
.services__section {
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
|
||||
.services__section-title {
|
||||
font-family: var(--font-body);
|
||||
font-size: 12px;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.1em;
|
||||
opacity: 0.5;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
.services__list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 6px;
|
||||
}
|
||||
|
||||
.services__list li {
|
||||
font-family: var(--font-body);
|
||||
font-size: 14px;
|
||||
line-height: 1.5;
|
||||
padding-left: 12px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.services__list li::before {
|
||||
content: '\2022';
|
||||
position: absolute;
|
||||
left: 0;
|
||||
opacity: 0.4;
|
||||
}
|
||||
|
||||
.services__steps {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 8px;
|
||||
counter-reset: step;
|
||||
}
|
||||
|
||||
.services__steps li {
|
||||
font-family: var(--font-body);
|
||||
font-size: 14px;
|
||||
line-height: 1.5;
|
||||
padding-left: 20px;
|
||||
position: relative;
|
||||
counter-increment: step;
|
||||
}
|
||||
|
||||
.services__steps li::before {
|
||||
content: counter(step) '.';
|
||||
position: absolute;
|
||||
left: 0;
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
.services__cta {
|
||||
margin-top: 8px;
|
||||
}
|
||||
|
||||
.services__footer {
|
||||
margin-top: 60px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 16px;
|
||||
align-items: flex-start;
|
||||
}
|
||||
|
||||
.services__footer-text {
|
||||
opacity: 0.7;
|
||||
max-width: 500px;
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.services__block {
|
||||
grid-column: span 4;
|
||||
grid-column-start: 1;
|
||||
}
|
||||
|
||||
.services__content {
|
||||
grid-template-columns: 1fr;
|
||||
gap: 24px;
|
||||
padding-left: 0;
|
||||
}
|
||||
|
||||
.services__summary {
|
||||
gap: 12px;
|
||||
padding: 20px 0;
|
||||
}
|
||||
}
|
||||
60
src/css/tokens.css
Normal file
60
src/css/tokens.css
Normal file
@@ -0,0 +1,60 @@
|
||||
:root {
|
||||
/* Colors */
|
||||
--color-primary: #007DDA;
|
||||
--color-bg: #E7F2EA;
|
||||
--color-surface: #FCC3C3;
|
||||
--color-ink: #BD5E24;
|
||||
--color-accent: #FB9322;
|
||||
--color-dark: #1A1A1A;
|
||||
--color-white: #FFFFFF;
|
||||
|
||||
/* Typography — Families */
|
||||
--font-headline: 'Archivo', sans-serif;
|
||||
--font-body: 'Inter', sans-serif;
|
||||
|
||||
/* Typography — Sizes (Desktop) */
|
||||
--h1-size: clamp(32px, 4vw, 48px);
|
||||
--h1-lh: 40px;
|
||||
--h2-size: clamp(24px, 2.5vw, 31px);
|
||||
--h2-lh: 30px;
|
||||
--h3-size: clamp(18px, 2vw, 24px);
|
||||
--h3-lh: 20px;
|
||||
--body-size: 16px;
|
||||
--body-lh: 18px;
|
||||
--caption-size: 16px;
|
||||
--caption-lh: 44px;
|
||||
|
||||
/* Grid */
|
||||
--grid-columns: 12;
|
||||
--grid-container: 1200px;
|
||||
--grid-max: 1424px;
|
||||
--grid-gutter: 32px;
|
||||
--grid-margin: 96px;
|
||||
|
||||
/* Spacing */
|
||||
--section-gap: clamp(120px, 15vw, 220px);
|
||||
--headline-spacing: 160px;
|
||||
|
||||
/* Misc */
|
||||
--btn-radius: 3px;
|
||||
--header-height: 64px;
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
:root {
|
||||
--h1-size: 32px;
|
||||
--h1-lh: 40px;
|
||||
--h2-size: 34px;
|
||||
--h2-lh: 30px;
|
||||
--h3-size: 20px;
|
||||
--h3-lh: 80px;
|
||||
--body-size: 16px;
|
||||
--body-lh: 14px;
|
||||
--caption-size: 14px;
|
||||
--caption-lh: 12px;
|
||||
|
||||
--grid-columns: 4;
|
||||
--grid-gutter: 16px;
|
||||
--grid-margin: 20px;
|
||||
}
|
||||
}
|
||||
75
src/main.js
Normal file
75
src/main.js
Normal file
@@ -0,0 +1,75 @@
|
||||
import './style.css'
|
||||
|
||||
function initScrollReveal() {
|
||||
const supportsScrollDriven = CSS.supports('animation-timeline', 'view()')
|
||||
|
||||
if (supportsScrollDriven) {
|
||||
document.documentElement.classList.add('has-scroll-driven')
|
||||
return
|
||||
}
|
||||
|
||||
const reveals = document.querySelectorAll('[data-reveal]')
|
||||
if (!reveals.length) return
|
||||
|
||||
const observer = new IntersectionObserver(
|
||||
(entries) => {
|
||||
entries.forEach((entry) => {
|
||||
if (entry.isIntersecting) {
|
||||
entry.target.classList.add('is-visible')
|
||||
observer.unobserve(entry.target)
|
||||
}
|
||||
})
|
||||
},
|
||||
{ threshold: 0.15 }
|
||||
)
|
||||
|
||||
reveals.forEach((el) => observer.observe(el))
|
||||
}
|
||||
|
||||
function initSmoothScroll() {
|
||||
document.querySelectorAll('a[href^="#"]').forEach((anchor) => {
|
||||
anchor.addEventListener('click', (e) => {
|
||||
const targetId = anchor.getAttribute('href')
|
||||
if (targetId === '#') return
|
||||
|
||||
const target = document.querySelector(targetId)
|
||||
if (!target) return
|
||||
|
||||
e.preventDefault()
|
||||
const headerOffset = parseInt(
|
||||
getComputedStyle(document.documentElement)
|
||||
.getPropertyValue('--header-height'),
|
||||
10
|
||||
)
|
||||
const top = target.getBoundingClientRect().top + window.scrollY - headerOffset - 20
|
||||
|
||||
window.scrollTo({ top, behavior: 'smooth' })
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
function initHeaderScroll() {
|
||||
const header = document.getElementById('header')
|
||||
if (!header) return
|
||||
|
||||
let ticking = false
|
||||
window.addEventListener(
|
||||
'scroll',
|
||||
() => {
|
||||
if (!ticking) {
|
||||
requestAnimationFrame(() => {
|
||||
header.classList.toggle('header--scrolled', window.scrollY > 100)
|
||||
ticking = false
|
||||
})
|
||||
ticking = true
|
||||
}
|
||||
},
|
||||
{ passive: true }
|
||||
)
|
||||
}
|
||||
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
initScrollReveal()
|
||||
initSmoothScroll()
|
||||
initHeaderScroll()
|
||||
})
|
||||
13
src/style.css
Normal file
13
src/style.css
Normal file
@@ -0,0 +1,13 @@
|
||||
@import './css/reset.css';
|
||||
@import './css/tokens.css';
|
||||
@import './css/base.css';
|
||||
@import './css/grid.css';
|
||||
@import './css/components.css';
|
||||
@import './css/header.css';
|
||||
@import './css/hero.css';
|
||||
@import './css/manifest.css';
|
||||
@import './css/journal.css';
|
||||
@import './css/cases.css';
|
||||
@import './css/services.css';
|
||||
@import './css/footer.css';
|
||||
@import './css/animations.css';
|
||||
9
vite.config.js
Normal file
9
vite.config.js
Normal file
@@ -0,0 +1,9 @@
|
||||
import { defineConfig } from 'vite'
|
||||
|
||||
export default defineConfig({
|
||||
root: '.',
|
||||
publicDir: 'public',
|
||||
build: {
|
||||
outDir: 'dist',
|
||||
},
|
||||
})
|
||||
Reference in New Issue
Block a user