eslint --fix

This commit is contained in:
Oscar
2026-06-08 15:09:53 +03:00
parent 10d696f4ca
commit b98387ea58
64 changed files with 6070 additions and 2467 deletions

View File

@@ -3,6 +3,7 @@
## Предисловие
Перед началом работы прочитай и усвой полностью:
- `.claude/skills/impeccable/SKILL.md` и все 7 файлов из `reference/`
- `.claude/skills/taste-skill/SKILL.md`
@@ -17,6 +18,7 @@
Весь дизайн — **на русском языке**: лейблы, плейсхолдеры, заголовки, подписи, пустые состояния, сообщения об ошибках, CTA-кнопки.
Два брейкпоинта:
- **Mobile** — 390 × 844 px (iPhone 14 Pro как эталон)
- **Desktop** — 1440 × 900 px
@@ -59,6 +61,7 @@ MeetMe/
## 1. ЦВЕТОВАЯ ПАЛИТРА
### Принципы (из impeccable color-and-contrast)
- Все цвета определяй в **OKLCH** — предсказуемый контраст при изменении яркости
- Нейтралы должны быть **тёплыми** (чуть красный/жёлтый подтон), не холодно-серыми
- Избегай: синих оттенков по умолчанию, generic «brand purple», чистого чёрного/белого
@@ -67,6 +70,7 @@ MeetMe/
**Brand (основной акцент):**
Тёплый терракотово-коралловый — не стандартный розовый Tinder, не красный. Живой, зрелый.
```
--color-brand-50: oklch(97% 0.012 22) /* почти белый с теплом */
--color-brand-100: oklch(93% 0.030 22)
@@ -81,6 +85,7 @@ MeetMe/
```
**Neutral (тёплые серые):**
```
--color-neutral-0: oklch(100% 0 0)
--color-neutral-50: oklch(97% 0.004 60)
@@ -96,6 +101,7 @@ MeetMe/
```
**Semantic:**
```
--color-success: oklch(62% 0.155 145) /* зелёный — матч состоялся */
--color-warning: oklch(78% 0.140 72) /* янтарный — встреча pending */
@@ -104,6 +110,7 @@ MeetMe/
```
**Поверхности (Light mode):**
```
--surface-page: --color-neutral-50
--surface-card: --color-neutral-0
@@ -118,6 +125,7 @@ MeetMe/
## 2. ТИПОГРАФИКА
### Принципы (из impeccable typography)
- Не Inter. Никогда Inter как единственный шрифт.
- Пара: выразительный дисплейный + читаемый текстовый
- Модульная шкала, не произвольные размеры
@@ -133,20 +141,20 @@ MeetMe/
### Типографическая шкала (модульная, ratio 1.25)
| Токен | Шрифт | Size | Weight | Line-height | Tracking | Применение |
|-------|-------|------|--------|-------------|----------|------------|
| `display-2xl` | Playfair Display | 48px | 700 | 1.1 | -0.02em | Экран матча, hero |
| `display-xl` | Playfair Display | 38px | 700 | 1.15 | -0.015em | Заголовки онбординга |
| `display-lg` | Playfair Display | 30px | 600 | 1.2 | -0.01em | Имя в профиле |
| `display-md` | Playfair Display | 24px | 600 | 1.25 | -0.005em | Заголовки секций |
| `heading-lg` | Manrope | 20px | 700 | 1.3 | -0.01em | Навбар, диалоги |
| `heading-md` | Manrope | 17px | 600 | 1.35 | -0.005em | Карточки, подзаголовки |
| `heading-sm` | Manrope | 15px | 600 | 1.4 | 0 | Лейблы полей |
| `body-lg` | Manrope | 16px | 400 | 1.6 | 0 | Основной текст |
| `body-md` | Manrope | 14px | 400 | 1.6 | 0 | Описание профиля |
| `body-sm` | Manrope | 12px | 400 | 1.5 | 0.01em | Мета, временные метки |
| `label-lg` | Manrope | 14px | 500 | 1 | 0.04em | Кнопки, таббар |
| `label-sm` | Manrope | 11px | 500 | 1 | 0.06em | Бейджи, чипы |
| Токен | Шрифт | Size | Weight | Line-height | Tracking | Применение |
| ------------- | ---------------- | ---- | ------ | ----------- | -------- | ---------------------- |
| `display-2xl` | Playfair Display | 48px | 700 | 1.1 | -0.02em | Экран матча, hero |
| `display-xl` | Playfair Display | 38px | 700 | 1.15 | -0.015em | Заголовки онбординга |
| `display-lg` | Playfair Display | 30px | 600 | 1.2 | -0.01em | Имя в профиле |
| `display-md` | Playfair Display | 24px | 600 | 1.25 | -0.005em | Заголовки секций |
| `heading-lg` | Manrope | 20px | 700 | 1.3 | -0.01em | Навбар, диалоги |
| `heading-md` | Manrope | 17px | 600 | 1.35 | -0.005em | Карточки, подзаголовки |
| `heading-sm` | Manrope | 15px | 600 | 1.4 | 0 | Лейблы полей |
| `body-lg` | Manrope | 16px | 400 | 1.6 | 0 | Основной текст |
| `body-md` | Manrope | 14px | 400 | 1.6 | 0 | Описание профиля |
| `body-sm` | Manrope | 12px | 400 | 1.5 | 0.01em | Мета, временные метки |
| `label-lg` | Manrope | 14px | 500 | 1 | 0.04em | Кнопки, таббар |
| `label-sm` | Manrope | 11px | 500 | 1 | 0.06em | Бейджи, чипы |
**Все токены фиксируй в Penpot как Text Styles.**
@@ -155,6 +163,7 @@ MeetMe/
## 3. SPACING & GRID
### Шкала отступов (4px база)
```
--space-1: 4px
--space-2: 8px
@@ -170,6 +179,7 @@ MeetMe/
```
### Радиусы скругления
```
--radius-sm: 6px /* чипы, теги */
--radius-md: 12px /* карточки, поля ввода */
@@ -179,11 +189,13 @@ MeetMe/
```
### Грид Mobile (390px)
- Колонки: 4
- Гаттер: 16px
- Отступы: 20px
### Грид Desktop (1440px)
- Колонки: 12
- Гаттер: 24px
- Отступы: 80px
@@ -211,6 +223,7 @@ MeetMe/
## 5. БИБЛИОТЕКА ИКОНОК
Создай коллекцию **48 иконок** в едином стиле:
- Стиль: **Outlined с rounded endpoints**, stroke 1.52px, 24×24 viewport
- Никакого filled + outlined микса в одном экране
- Все иконки — компоненты Penpot с именованием `icon/[category]/[name]`
@@ -218,6 +231,7 @@ MeetMe/
### Список иконок (сгруппируй в Penpot по категориям):
**Navigation (8)**
- `nav/feed` — сетка карточек или стопка
- `nav/matches` — сердце с двойным контуром или звёзды
- `nav/chat` — облако диалога
@@ -228,6 +242,7 @@ MeetMe/
- `nav/close` — крест
**Actions (12)**
- `action/like` — сердце
- `action/dislike` — крест в круге или большой X
- `action/superlike` — звезда
@@ -242,6 +257,7 @@ MeetMe/
- `action/more` — три точки (горизонтальные)
**Profile (8)**
- `profile/age` — торт или число
- `profile/location` — пин геолокации
- `profile/height` — линейка роста
@@ -252,6 +268,7 @@ MeetMe/
- `profile/tag` — тег/лейбл
**Chat (8)**
- `chat/read` — двойная галочка
- `chat/delivered` — одна галочка
- `chat/typing` — три точки анимированные
@@ -262,6 +279,7 @@ MeetMe/
- `chat/report` — флажок
**Status (6)**
- `status/online` — зелёная точка
- `status/pending` — часы
- `status/confirmed` — галочка
@@ -270,6 +288,7 @@ MeetMe/
- `status/limit` — замок или стоп-сигнал
**Misc (6)**
- `misc/filter` — воронка
- `misc/search` — лупа
- `misc/notification` — колокол
@@ -286,17 +305,20 @@ MeetMe/
#### Button
**Варианты (Property: variant)**
- `primary` — brand-500 фон, белый текст
- `secondary` — brand-100 фон, brand-700 текст
- `ghost` — прозрачный фон, brand-600 текст
- `destructive` — error фон, белый текст
**Размеры (Property: size)**
- `lg` — height 52px, padding 24px, radius-full, label-lg
- `md` — height 44px, padding 20px, radius-full, label-lg
- `sm` — height 36px, padding 16px, radius-md, label-sm
**Состояния (Property: state)**
- `default`, `hover`, `pressed`, `disabled`, `loading`
**Иконка (Property: icon):** leading / trailing / icon-only
@@ -327,6 +349,7 @@ MeetMe/
- Используется в профиле для отображения тегов интересов
#### Divider
- Горизонтальный, с опциональным текстом по центру («или»)
---
@@ -338,6 +361,7 @@ MeetMe/
Основной компонент приложения. Полноэкранная карточка на мобиле.
**Структура:**
```
┌─────────────────────────────┐
│ │
@@ -361,11 +385,13 @@ MeetMe/
- Тени под текстом нет — только градиент
**Действия (кнопки поверх карточки):**
- Дизлайк — круглая кнопка 64px, нейтральный фон, иконка `action/dislike` в neutral-600
- Лайк — круглая кнопка 64px, brand-500 фон, иконка `action/like` белый
- Суперлайк (опционально) — 52px, янтарный, звезда
**Свайп-оверлеи:**
- Свайп вправо: зелёный бейдж «НРАВИТСЯ» в левом верхнем углу, наклон текста
- Свайп влево: красный бейдж «ПРОПУСТИТЬ» в правом верхнем углу
@@ -417,6 +443,7 @@ MeetMe/
#### FilterSheet (панель фильтров)
Bottom sheet на мобиле, sidebar на десктопе.
- Возраст: range slider (ageMinageMax)
- Город: dropdown select
- Район: dropdown select (зависимый)
@@ -430,6 +457,7 @@ Bottom sheet на мобиле, sidebar на десктопе.
#### BottomNav (Mobile)
Высота 83px (+ safe area). 5 вкладок:
- Лента (`nav/feed`)
- Матчи (`nav/matches`) — с бейджем
- Чат (`nav/chat`) — с бейджем
@@ -445,6 +473,7 @@ Active state: иконка brand-500, лейбл brand-600, точка под и
#### ProfileHeader
Используется на экране публичного профиля.
- Фото-галерея (swiper, точки-индикаторы)
- Кнопка назад
- Кнопка «Пожаловаться» (три точки → меню)
@@ -457,6 +486,7 @@ Active state: иконка brand-500, лейбл brand-600, точка под и
#### MatchModal (bottom sheet / центральный модал)
Появляется при взаимном лайке.
- Анимированный фон (конфетти? мягкие частицы)
- Два аватара с перекрытием
- Заголовок: `display-xl` «Это матч!»
@@ -473,6 +503,7 @@ Active state: иконка brand-500, лейбл brand-600, точка под и
### Авторизация
**LoginView**
- Логотип MeetMe (wordmark Playfair Display + иконка) по центру верхней трети
- `display-xl`: «Рады видеть тебя»
- Поля: телефон (+7), пароль
@@ -480,6 +511,7 @@ Active state: иконка brand-500, лейбл brand-600, точка под и
- Ссылка: «Нет аккаунта? Зарегистрироваться»
**RegisterView**
- «Создай аккаунт»
- Поля: телефон, пароль, подтверждение пароля
- Кнопка: «Зарегистрироваться»
@@ -488,22 +520,26 @@ Active state: иконка brand-500, лейбл brand-600, точка под и
### Онбординг
**CreateProfileView — Шаг 1 (Основное)**
- Прогресс-бар (3 шага)
- «Расскажи о себе»
- Поля: Имя, Дата рождения, Пол (radio-кнопки с иконками ♂ ♀)
- CTA: «Далее»
**CreateProfileView — Шаг 2 (Детали)**
- Поля: Город (select), Район (select), Рост, Вес, Национальность
- Описание (textarea, 300 символов)
- CTA: «Далее»
**CreateProfileView — Шаг 3 (Интересы)**
- «Выбери до 10 интересов»
- Chip grid из тегов (GET /tags)
- CTA: «Готово»
**MediaUploadView**
- «Добавь фото»
- 6 слотов в сетке 2×3, первый — обязательный (основное фото)
- Плейсхолдер слота: `+` иконка, пунктирная рамка
@@ -513,18 +549,21 @@ Active state: иконка brand-500, лейбл brand-600, точка под и
### Лента
**FeedView**
- Карточка профиля на весь экран (за вычетом статус-бара и BottomNav)
- Вверху: логотип MeetMe (compact) + иконка фильтра + иконка уведомлений
- Кнопки действий снизу карточки
- Индикатор позиции (точки или счётчик «3 из 20»)
**FeedView — Empty State**
- Иллюстрация (простая, монолинейная, brand-200 цвет)
- «Ты просмотрел всех»
- «Попробуй позже или измени фильтры»
- CTA: «Изменить фильтры»
**FeedView — Limit Reached**
- «У тебя 10 матчей»
- «Пообщайся с ними, чтобы продолжить поиск»
- CTA: «Перейти к матчам»
@@ -532,6 +571,7 @@ Active state: иконка brand-500, лейбл brand-600, точка под и
### Матчи
**MatchesView**
- Заголовок «Матчи»
- Horizontal scroll «Новые» — аватары в кружках (как в Instagram Stories)
- Список MatchCard ниже — все матчи в хронологии
@@ -539,12 +579,14 @@ Active state: иконка brand-500, лейбл brand-600, точка под и
### Чат
**ChatsListView**
- Заголовок «Сообщения»
- Поиск по чатам
- Список ChatListItem
- Empty state: «Пока нет чатов. Напиши кому-нибудь из матчей!»
**ChatView**
- ChatHeader
- Сообщения (с группировкой по датам — «Сегодня», «Вчера», дата)
- Быстрые приветствия (горизонтальный скролл чипов, появляется при первом сообщении)
@@ -554,12 +596,14 @@ Active state: иконка brand-500, лейбл brand-600, точка под и
### Встречи
**DatesView**
- Заголовок «Встречи»
- Фильтр по статусу (таббар: Все / Ожидают / Подтверждены)
- Список DateCard
- Empty state: «Пока нет встреч. Договорись в чате!»
**DateProposalSheet (bottom sheet)**
- «Назначить встречу»
- Поле: дата и время (date-time picker)
- Карта или поле координат
@@ -568,17 +612,20 @@ Active state: иконка brand-500, лейбл brand-600, точка под и
### Профиль
**MyProfilesView**
- «Мои профили»
- Список профилей (аватар, имя, возраст)
- Кнопка «Добавить профиль» (+ иконка)
- Active badge на текущем профиле
**ProfileEditView**
- Редактирование с теми же полями что в создании
- Секция «Медиа» — галерея с drag-to-reorder
- Кнопка «Удалить профиль» (destructive, внизу)
**ProfilePublicView**
- ProfileHeader (фото-галерея)
- Имя, возраст, геолокация
- Описание
@@ -589,6 +636,7 @@ Active state: иконка brand-500, лейбл brand-600, точка под и
### Настройки
**SettingsView**
- Аватар + имя аккаунта
- Секции: Аккаунт, Уведомления, Безопасность, О приложении
- Кнопка «Выйти» (destructive)
@@ -600,24 +648,29 @@ Active state: иконка brand-500, лейбл brand-600, точка под и
Каждый фрейм 1440×900.
**Общий Layout:**
- Левая колонка: SideNav (240px, фиксированная)
- Основная область: 1200px
- Для чата: split-view — список (320px) + сообщения
**FeedView Desktop**
- SideNav слева
- Центр: карточка профиля 420×560px (не во весь экран!)
- Справа от карточки: детали профиля (имя, теги, описание) — 320px колонка
- Кнопки под карточкой или справа
**ChatsView Desktop**
- SideNav | ChatList 320px | ChatMessages | (опционально ProfilePanel 280px)
- Нет bottom sheet — поле ввода снизу в колонке сообщений
**MatchesView Desktop**
- Сетка 3 колонки из MatchCard
**ProfileEditView Desktop**
- Двухколоночный layout: форма | превью профиля
---
@@ -637,16 +690,19 @@ Active state: иконка brand-500, лейбл brand-600, точка под и
Для каждого ключевого экрана создай:
**Loading (Skeleton):**
- ProfileCard skeleton: прямоугольник с animated shimmer
- ChatListItem skeleton: аватар-круг + две строки
**Empty States (с иллюстрацией):**
- Лента пуста
- Нет матчей
- Нет чатов
- Нет встреч
**Error State:**
- Что-то пошло не так + кнопка «Повторить»
---
@@ -654,6 +710,7 @@ Active state: иконка brand-500, лейбл brand-600, точка под и
## 11. ЛОГОТИП MEETME
Создай wordmark:
- Текст «MeetMe» шрифтом Playfair Display, 700 weight
- «Meet» — neutral-900
- «Me» — brand-500
@@ -694,6 +751,7 @@ Page 7: 🖥 Desktop Screens
```
### Именование в Penpot:
- Компоненты: `ComponentName/variant/size/state`
- Цвета: `brand/500`, `neutral/200`, `semantic/success`
- Текстовые стили: `display/2xl`, `body/md`, `label/lg`
@@ -739,6 +797,7 @@ Page 7: 🖥 Desktop Screens
## Финальная проверка
После завершения прогони аудит по impeccable:
- Типографический контраст (все текстовые пары ≥ 4.5:1)
- Touch targets на мобиле (≥ 44×44px)
- Длина строк (4575 символов для body text)

View File

@@ -1,4 +1,5 @@
Before starting, read and internalize these two skills in full:
- .claude/skills/impeccable/SKILL.md (and all 7 reference files in reference/)
- .claude/skills/taste-skill/SKILL.md
@@ -8,6 +9,7 @@ DESIGN_VARIANCE: 8, MOTION_INTENSITY: 6, VISUAL_DENSITY: 4
You are a Figma design expert. Create a complete component library and UI screens for a mobile dating app called "Tandem". Use the Figma MCP tools to build everything directly in Figma.
## Anti-slop directives (from skills — enforce strictly)
- NO Inter font anywhere. DM Sans is explicitly specified below and is the exception (brand choice).
- NO centered hero layouts — use asymmetric, left-weighted compositions where possible within mobile constraints.
- NO generic 3-equal-card rows. Use asymmetric grids, varied sizes, hierarchy through scale.
@@ -21,11 +23,13 @@ You are a Figma design expert. Create a complete component library and UI screen
- Image placeholders: use picsum.photos/seed/{name}/800/600 format (never Unsplash links).
## Project overview
Mobile-first dating app (iOS/Android via Tauri). Users register by phone, create profiles, swipe a feed, match, chat in real-time (text/photo/voice/video), schedule meetups, report users.
## Design system — establish FIRST before any screens
### Color tokens (create as Figma variables)
- bg-primary: #0D0D0F
- bg-surface: #1A1A1F
- bg-elevated: #242429
@@ -40,6 +44,7 @@ Mobile-first dating app (iOS/Android via Tauri). Users register by phone, create
- border: #2C2C35
### Typography
- Display/Hero: Playfair Display Italic, 3248px (editorial moments only — match celebrations, onboarding headers)
- Title: DM Sans SemiBold, 2024px, tracking-tight
- Body: DM Sans Regular, 1516px, leading-relaxed
@@ -48,15 +53,19 @@ Mobile-first dating app (iOS/Android via Tauri). Users register by phone, create
- Mono data (stats, counts, timestamps): DM Mono or DM Sans Tabular Numbers
### Taste-skill typography enforcement:
- Headlines use tracking-tighter. No oversized H1s that scream.
- Control hierarchy through weight and color, not scale alone.
- Playfair Display is brand-intentional (editorial register) — use sparingly.
### Spacing scale: 4, 8, 12, 16, 20, 24, 32, 48px
### Border radius: sm=8, md=16, lg=24, full=999px
### Safe areas: top=44px, bottom=34px (iPhone)
### Shadow / elevation (taste-skill materiality rules):
- Shadows are ALWAYS tinted to the background hue, never pure black
- No outer glows. Use inner border (1px border-white/10) + inner shadow for glass surfaces
- Cards appear only where elevation communicates hierarchy
@@ -66,8 +75,10 @@ Mobile-first dating app (iOS/Android via Tauri). Users register by phone, create
## Component library (create as Figma components with variants)
### 1. Buttons
Component: Button
Variants — size: [Large, Medium, Small] × style: [Primary, Secondary, Ghost, Danger]
- Large: full-width, height 56px, border-radius 16px
- Primary: bg=accent, text=white. Active state: scale(0.98) — physical press feel
- Secondary: bg=bg-elevated, border=1px border-color, text=text-primary
@@ -76,8 +87,10 @@ Variants — size: [Large, Medium, Small] × style: [Primary, Secondary, Ghost,
- ALL buttons: no outer glow. Primary shadow = tinted coral shadow beneath
### 2. Input field
Component: InputField
Variants — state: [Default, Focused, Filled, Error]
- Height 56px, bg=bg-elevated, border-radius=12px, 1px border=border-color
- Focused: 1.5px border=accent, subtle inner shadow accent-soft
- Label sits above input (never placeholder-only)
@@ -85,9 +98,11 @@ Variants — state: [Default, Focused, Filled, Error]
- Optional: left icon, right icon/clear
### 3. Profile Card (hero swipe card)
Component: ProfileCard
Size: 340×480px
Structure:
- Full-bleed photo background. Gradient overlay: bottom 50%, black 0%→75%
- Photo: picsum.photos/seed/sofia/400/600 style
- Bottom section over gradient:
@@ -100,13 +115,16 @@ Structure:
- Card stack illusion: 2 cards partially peeking behind, scale-down + slight translate
### 4. SwipeActions
Three buttons row, centered:
- Dislike: 64px circle, bg=bg-elevated, X icon (accent red), tinted shadow below
- SuperLike: 52px circle, bg=gold 10% opacity, star icon (gold), smaller
- Like: 64px circle, accent gradient, heart icon white, shadow tinted coral
- No labels — icons only, phosphor style
### 5. BottomNav
Height 83px (inc 34px safe area), bg=bg-surface, 1px top border=border-color
5 tabs: Feed (flame), Matches (heart), Chats (message-circle), Dates (calendar), Profile (user)
Active: icon+label=accent, 2px accent indicator dot above icon
@@ -114,11 +132,13 @@ Inactive: text-muted
Labels: DM Sans Regular 11px
### 6. Avatar
Variants — size: [XL=80px, L=56px, M=40px, S=32px] × state: [Default, Online, Verified]
Online: 10px green dot (#30D158) bottom-right, 2px white border around dot
Verified: small accent checkmark badge bottom-right instead
### 7. MatchChip
Height 72px, full-width, bg=bg-surface, subtle 1px border bottom=border-color
Left: Avatar M + Online indicator
Center: Name (DM Sans SemiBold 15px) + last message preview (text-muted, 1 line, 13px)
@@ -126,7 +146,9 @@ Right: timestamp (Caption, text-muted) + unread count badge (accent circle, whit
Pressed state: bg=bg-elevated
### 8. MessageBubble
Variants — sender: [Me, Them] × type: [Text, Photo, Voice, Video]
- Me: right-aligned, bg=accent, text=white, radius 18 18 4 18
- Them: left-aligned, bg=bg-elevated, text=text-primary, radius 18 18 18 4
- Voice: horizontal bar waveform (1012 bars, varying heights) + duration + play circle icon
@@ -135,8 +157,10 @@ Variants — sender: [Me, Them] × type: [Text, Photo, Voice, Video]
- Max width: 72% of screen
### 9. MatchModal
Full-screen, bg=rgba(0,0,0,0.85), backdrop blur
Center:
- "It's a Match!" Playfair Display Italic 40px, white (no emoji — use decorative SVG spark icon)
- Two Avatar XL overlapping, gold border 2px, inner glow tinted gold
- Subtitle: "You and Sofia both liked each other" — text-secondary, DM Sans Regular
@@ -145,27 +169,32 @@ Center:
- Static confetti: geometric shapes (circles, triangles, small rectangles) in accent/gold/white scattered around, no emoji stars
### 10. TagPill
Variants — selected: [true, false]
Default: bg=bg-elevated, border=border, text=text-secondary, h=32px, px=12px, radius=full
Selected: bg=accent-soft, border=accent, text=accent
### 11. SectionHeader
Left: Title + optional Caption subtitle
Right: optional "See all" in accent (DM Sans Medium 13px)
### 12. GreetingCard
bg=bg-elevated, border-radius=16px, p=16px
Top-left: decorative quote mark in accent (SVG, not emoji)
Body text: italicized, text-primary
Pressed: 1px accent border appears
### 13. DateCard
Full-width, bg=bg-elevated, radius=16px, p=16px
Left: 48px accent circle with calendar icon (phosphor)
Right: Partner name (SemiBold 15px), date+time (Caption), location (text-muted Caption)
Bottom-right: status pill — Pending=gold bg+text, Confirmed=success, Cancelled=error, Rescheduled=text-secondary
### 14. Toast
Variants: [Success, Error, Info, Warning]
Bottom of screen, mx=16px, bg=bg-elevated, 3px left border in status color
Left: status icon (phosphor) in status color
@@ -180,6 +209,7 @@ Apply /impeccable craft principles: shape UX first, then build.
Asymmetric compositions where mobile constraints allow. Every screen complete, production-ready.
**1.1 — Splash / Welcome**
- Full bg-primary background
- Bottom-left: large abstract soft gradient blob in accent (#FF4D6D), heavily blurred (no hard edges)
- Center: geometric logo mark (abstract spark/connection shape, SVG — no emoji) + "Tandem" Playfair Display Italic 48px
@@ -188,6 +218,7 @@ Asymmetric compositions where mobile constraints allow. Every screen complete, p
- Subtle grain texture on background (fixed pseudo-element concept)
**1.2 — Register**
- Back arrow (phosphor) + "Create account" Title
- Subtitle: "Your number stays private." (concrete reassurance, not generic)
- Phone input with country code selector (+7 flag)
@@ -197,12 +228,14 @@ Asymmetric compositions where mobile constraints allow. Every screen complete, p
- "Already registered? Sign in" text-secondary centered bottom
**1.3 — Login**
- Back arrow + "Welcome back" Title
- Phone + password inputs
- "Sign In" Primary Large
- "Forgot password?" ghost link centered, text-secondary
**1.4 — Profile Setup Step 1/3**
- 3-segment progress bar, segment 1 active (accent), others text-muted
- "Tell us about you" Playfair Display Italic Title (editorial register)
- Name input (filled: "Alina")
@@ -212,6 +245,7 @@ Asymmetric compositions where mobile constraints allow. Every screen complete, p
- "Continue" Primary Large
**1.5 — Profile Setup Step 2/3**
- Segment 2 active
- "What moves you?" (concrete, not "What are you into?")
- "Pick up to 5" Caption subtitle
@@ -221,6 +255,7 @@ Asymmetric compositions where mobile constraints allow. Every screen complete, p
- "Continue" Primary Large
**1.6 — Profile Setup Step 3/3**
- Segment 3 active
- "Show yourself" Playfair Display Italic Title
- Upload zone 340×260: dashed 1.5px accent border, camera phosphor icon, "Tap to add a photo" Caption
@@ -232,6 +267,7 @@ Asymmetric compositions where mobile constraints allow. Every screen complete, p
## PAGE 2 — "02 · Main App" (390×844px frames, 40px gap)
**2.1 — Feed**
- Status bar 44px
- Top bar: small "Tandem" wordmark left (Playfair Display Italic 18px), sliders/filter icon right + Avatar M right
- ProfileCard centered, card stack visible (2 cards peeking: scale 0.95 and 0.90, translate-y)
@@ -239,11 +275,13 @@ Asymmetric compositions where mobile constraints allow. Every screen complete, p
- BottomNav: Feed active
**2.2 — Feed + Match Modal**
- Same feed, blurred/dimmed beneath
- MatchModal overlay. Avatars: Sofia + current user. Gold border glow (inner, not outer).
- Static confetti in corners (geometric, not emoji)
**2.3 — Matches List**
- "Matches" Title top bar + filter icon
- Horizontal scroll: 5 Avatar L circles with name below. First: gold ring border + "New" pill (gold). Use names: Lena, Sofia, Masha, Alina, Katya
- Divider line (1px border-color)
@@ -252,6 +290,7 @@ Asymmetric compositions where mobile constraints allow. Every screen complete, p
- BottomNav: Matches active
**2.4 — Chats List**
- "Chats" Title
- 4 MatchChip items:
- Sofia — "That place sounds perfect" — 14:32 — online dot
@@ -261,6 +300,7 @@ Asymmetric compositions where mobile constraints allow. Every screen complete, p
- BottomNav: Chats active
**2.5 — Chat View (with Sofia)**
- Top: back arrow + Avatar M (Sofia, online) + "Sofia" Title + "Online" Caption green + video-call icon + report icon
- Messages:
- Date divider: "Today" centered Caption text-muted
@@ -275,6 +315,7 @@ Asymmetric compositions where mobile constraints allow. Every screen complete, p
- BottomNav: Chats active
**2.6 — Public Profile (Sofia)**
- Photo area top: full-width, 380px height, 2-photo carousel with dots + "2/4" pill top-right
- Back arrow top-left (on photo) + report icon top-right (both on photo, ghost style)
- Below photo: "Sofia, 24" Title + "Moscow · 2.3 km" Caption + verified badge
@@ -285,6 +326,7 @@ Asymmetric compositions where mobile constraints allow. Every screen complete, p
- Sticky bottom: Dislike (Secondary) + "Like" (Primary accent) side by side
**2.7 — Dates/Meetups**
- "Meetups" Title + "+" phosphor icon
- SectionHeader "Upcoming"
- DateCard 1: Daniil · Sat, Jun 14 · 19:00 · Blue Goose Bar, Kamergersky · Confirmed (green)
@@ -294,6 +336,7 @@ Asymmetric compositions where mobile constraints allow. Every screen complete, p
- BottomNav: Dates active
**2.8 — Propose Meetup (bottom sheet)**
- Handle bar 4px, 36px wide, centered, text-muted
- "Propose a Meetup" Title
- Sofia Avatar M + "Sofia" centered below (Caption)
@@ -307,6 +350,7 @@ Asymmetric compositions where mobile constraints allow. Every screen complete, p
## PAGE 3 — "03 · Profile & Settings" (390×844px frames, 40px gap)
**3.1 — My Profile**
- "My Profile" Title + settings gear icon right
- Profile selector: horizontal scroll of compact cards 80×100, first (Alina) has accent border, others dimmed. Last: dashed border + "+" add
- Active profile:
@@ -321,6 +365,7 @@ Asymmetric compositions where mobile constraints allow. Every screen complete, p
- BottomNav: Profile active
**3.2 — Edit Profile**
- Back arrow + "Edit Profile" Title + "Save" accent text button right
- Avatar XL with camera icon overlay circle (bg-elevated)
- Scrollable form:
@@ -336,6 +381,7 @@ Asymmetric compositions where mobile constraints allow. Every screen complete, p
- "Delete Profile" Danger Ghost button (bottom, error color, no icon)
**3.3 — Settings**
- "Settings" Title
- User row: Avatar M + "+7 (916) 847-2391" + "Edit account" accent link
- Setting groups with 1px dividers:
@@ -345,6 +391,7 @@ Asymmetric compositions where mobile constraints allow. Every screen complete, p
- "Sign Out" Secondary Large button full-width bottom
**3.4 — Feed Filters (bottom sheet)**
- Handle bar
- "Search Filters" Title
- City dropdown (Moscow)
@@ -355,6 +402,7 @@ Asymmetric compositions where mobile constraints allow. Every screen complete, p
- "Apply Filters" Primary Large + "Reset" Ghost
**3.5 — Report User (bottom sheet)**
- Handle bar
- "Report" Title
- "Reporting Sofia, 24" Caption text-muted centered
@@ -364,7 +412,7 @@ Asymmetric compositions where mobile constraints allow. Every screen complete, p
· Inappropriate content
· Harassment
· Other
- Description textarea "Add details (optional)..."
- Description textarea "Add details (optional)..."
- "Submit Report" Danger Primary button
- "Cancel" Ghost
@@ -373,6 +421,7 @@ Asymmetric compositions where mobile constraints allow. Every screen complete, p
## Final instructions (Impeccable + Taste-skill enforcement)
**Sequence:**
1. Create all color variables and text styles.
2. Run `/impeccable teach` mentally — establish DESIGN.md context (dark luxury premium dating, not hookup app).
3. Create every component as a Figma component with all variants.
@@ -381,6 +430,7 @@ Asymmetric compositions where mobile constraints allow. Every screen complete, p
6. Run `/impeccable polish` — final pass: alignment, shadow consistency, border-radius uniformity.
**Quality gates (Taste-skill Pre-flight):**
- Every interactive element has Default + Pressed states at minimum
- No card where spacing would suffice
- Shadows tinted to bg hue
@@ -390,4 +440,4 @@ Asymmetric compositions where mobile constraints allow. Every screen complete, p
- Photo placeholders: picsum.photos/seed/{name}/400/600 (sofia, lena, masha, daniil, artem)
**Aesthetic directive:**
Dark luxury. Warm coral accent. The refinement of a premium product — not a hookup app, not a social network. Think: the design confidence of Locket or BeReal's intentionality, the premium feel of a high-end financial app, applied to human connection.
Dark luxury. Warm coral accent. The refinement of a premium product — not a hookup app, not a social network. Think: the design confidence of Locket or BeReal's intentionality, the premium feel of a high-end financial app, applied to human connection.

View File

@@ -1,4 +1,5 @@
Read and apply these skills before starting:
- .claude/skills/impeccable/SKILL.md
- .claude/skills/taste-skill/SKILL.md
@@ -8,8 +9,9 @@ You are a Penpot design expert building a mobile dating app "Tandem".
Work in a single Penpot page. Layout everything horizontally in one continuous canvas. Use penpot mcp.
## EFFICIENCY RULES (critical — minimize MCP calls)
- Create ALL color variables in one batch operation
- Create ALL text styles in one batch operation
- Create ALL text styles in one batch operation
- Create components in logical groups, not one-by-one
- Screens go into one frame row, left to right, 40px gaps
- Do NOT switch pages — one page only
@@ -18,6 +20,7 @@ Work in a single Penpot page. Layout everything horizontally in one continuous c
## PRIORITY ORDER — stop if rate-limited, complete in order:
### PHASE 1 — Design tokens (do first, everything depends on this)
Color variables:
bg-primary #0D0D0F, bg-surface #1A1A1F, bg-elevated #242429,
accent #FF4D6D, accent-soft #FF4D6D1A, gold #F5A623,
@@ -25,6 +28,7 @@ text-primary #F5F5F7, text-secondary #8E8E9A, text-muted #4A4A55,
success #30D158, error #FF453A, border #2C2C35
Text styles:
- Display: Playfair Display Italic 40px (editorial moments only)
- Title: DM Sans SemiBold 22px tracking-tight
- Body: DM Sans Regular 15px
@@ -32,6 +36,7 @@ Text styles:
- Button: DM Sans Medium 15px
### PHASE 2 — Core components (minimum viable set, batch-create)
Build these 6 first — screens depend on them:
1. Button/Primary — 56px height, radius 16, bg=accent, DM Sans Medium 15px white. Variants: Large/Medium
@@ -42,6 +47,7 @@ Build these 6 first — screens depend on them:
6. Avatar — Circle crop. Variants: XL 80px / L 56px / M 40px, with Online green dot state
### PHASE 3 — Secondary components (if quota allows)
7. MatchChip — 72px height, Avatar M + name + last message + timestamp + unread badge
8. MessageBubble — Me: right, bg=accent. Them: left, bg=bg-elevated. Variants: Text/Voice
9. TagPill — h=32px, radius=full. Variants: Default (bg-elevated) / Selected (accent-soft + accent border)
@@ -50,6 +56,7 @@ Build these 6 first — screens depend on them:
12. DateCard — bg-elevated, radius 16, calendar icon circle, partner name+date+location, status pill
### PHASE 4 — Screens (one frame per screen, 390×844px, horizontal row, 40px gap)
Label each frame. Use components from Phase 23.
**Auth group (screens A1A6):**
@@ -101,12 +108,14 @@ C5 · Report (bottom sheet) — Handle, "Report" Title, "Reporting Sofia, 24" ca
## Design principles (enforced throughout)
**Visual language — dark luxury:**
- Shadows always tinted to bg hue, never pure black drop shadows
- No outer glows — inner borders (1px rgba(255,255,255,0.08)) on elevated surfaces
- Cards only where elevation communicates hierarchy
- Spacing > cards where possible
**Anti-slop rules:**
- No pure #000000 anywhere
- No Inter font
- No centered hero on non-splash screens
@@ -118,4 +127,4 @@ C5 · Report (bottom sheet) — Handle, "Report" Title, "Reporting Sofia, 24" ca
**Touch targets:** All interactive elements minimum 44×44px
**Aesthetic:** Premium dating app. The design confidence of a high-end product — refined, warm, intentional.
**Aesthetic:** Premium dating app. The design confidence of a high-end product — refined, warm, intentional.