# Auth Page Redesign — Spec

**Date:** 2026-05-22
**Goal:** Минималистичный редизайн страницы входа с лёгким брендингом (медведь + слоган), pill-кнопками и Paper-карточкой.

**Style:** Минималистичный, чистый. Одна колонка по центру.

---

## 1. Шрифт Outfit

**Проблема:** Outfit указан в MUI-теме, но не загружается. Фактически везде системный Segoe UI.

**Исправление:** Скачать шрифт Outfit (woff2, веса 400/500/600/700) и разместить в `client/public/fonts/`. Добавить `@font-face` в `client/src/app/styles/global.css`:

```css
@font-face {
  font-family: 'Outfit';
  font-style: normal;
  font-weight: 400;
  src: url('/fonts/Outfit-Regular.woff2') format('woff2');
}
@font-face {
  font-family: 'Outfit';
  font-style: normal;
  font-weight: 500;
  src: url('/fonts/Outfit-Medium.woff2') format('woff2');
}
@font-face {
  font-family: 'Outfit';
  font-style: normal;
  font-weight: 600;
  src: url('/fonts/Outfit-SemiBold.woff2') format('woff2');
}
@font-face {
  font-family: 'Outfit';
  font-style: normal;
  font-weight: 700;
  src: url('/fonts/Outfit-Bold.woff2') format('woff2');
}
```

Файлы woff2 скачать с Google Fonts или из CDN и положить в `client/public/fonts/`.

---

## 2. Фон страницы

- `background.default` + лёгкий радиальный градиент
- Градиент: от центра к краям, `primary.main` с 3-5% opacity
- Реализация: `sx` prop на корневом `<Box>`: `background: radial-gradient(circle at 50% 30%, ${alpha(theme.palette.primary.main, 0.05)} 0%, transparent 70%)`

---

## 3. Компоновка

```
┌──────────────────────────────────────────┐
│                   (воздух)               │
│              🐻 BearLogo 72px            │
│       Добро пожаловать в Любимый Креатив  │
│           (subtitle, text.secondary)      │
│                   (воздух)               │
│   ┌─────── Paper 440px max-width ──────┐ │
│   │  [Пароль]  [Код]  [Другой способ]   │ │
│   │                                     │ │
│   │   Вход  /  Регистрация              │ │
│   │                                     │ │
│   │  Email:        __________________   │ │
│   │  Пароль:       __________________   │ │
│   │                                     │ │
│   │  [────────── Войти ──────────]      │ │
│   │                                     │ │
│   └─────────────────────────────────────┘ │
│                   (воздух)               │
└──────────────────────────────────────────┘
```

Детали:
- Корневой `<Box>`: `display: flex, alignItems: center, justifyContent: center, minHeight: calc(100vh - header)`
- BearLogo: `<Box sx={{ display: 'flex', justifyContent: 'center', mb: 2 }}><BearLogo sx={{ fontSize: 72 }} /></Box>`
- Заголовок: `variant="h5"`, `fontWeight: 700`, `textAlign: center`
- Слоган: `variant="body2"`, `color: text.secondary`, `textAlign: center`, `mb: 3`
- Paper: `maxWidth: 440`, `mx: auto`, `p: 4`, `borderRadius: 3` (12px), `border: 1px solid divider`, мягкая тень

---

## 4. Pill-переключатель методов

Вместо MUI Tabs — три MUI Button в ряд:

```tsx
<Stack direction="row" spacing={1} sx={{ mb: 3 }}>
  <Button
    variant={tab === 0 ? 'contained' : 'outlined'}
    sx={{ borderRadius: '24px', flex: 1, textTransform: 'none' }}
    onClick={() => setTab(0)}
  >
    Пароль
  </Button>
  <Button
    variant={tab === 1 ? 'contained' : 'outlined'}
    sx={{ borderRadius: '24px', flex: 1, textTransform: 'none' }}
    onClick={() => setTab(1)}
  >
    Код
  </Button>
  <Button
    variant={tab === 2 ? 'contained' : 'outlined'}
    sx={{ borderRadius: '24px', flex: 1, textTransform: 'none' }}
    onClick={() => setTab(2)}
  >
    Другой способ
  </Button>
</Stack>
```

---

## 5. Под-переключатель Вход/Регистрация

Только на вкладке «Пароль»:

```tsx
<Stack direction="row" justifyContent="center" spacing={3} sx={{ mb: 2 }}>
  <Button
    variant="text"
    size="small"
    sx={{
      color: !isRegister ? 'primary.main' : 'text.secondary',
      borderBottom: !isRegister ? 2 : 0,
      borderColor: 'primary.main',
      borderRadius: 0,
      pb: 0.5,
    }}
    onClick={() => setIsRegister(false)}
  >
    Вход
  </Button>
  <Button
    variant="text"
    size="small"
    sx={{
      color: isRegister ? 'primary.main' : 'text.secondary',
      borderBottom: isRegister ? 2 : 0,
      borderColor: 'primary.main',
      borderRadius: 0,
      pb: 0.5,
    }}
    onClick={() => setIsRegister(true)}
  >
    Регистрация
  </Button>
</Stack>
```

---

## 6. Формы по вкладкам

### Пароль (вход)
- Email TextField
- Пароль TextField
- Button contained fullWidth: «Войти»

### Пароль (регистрация)
- Email TextField
- Имя TextField (опционально, helperText: «Необязательно. Будет использована часть email»)
- Пароль TextField
- Подтверждение пароля TextField (с валидацией совпадения)
- Button contained fullWidth: «Зарегистрироваться»

### Код
- Строка: Email + кнопка «Отправить код»
- Строка: поле Код + кнопка «Войти»
- Alert outlined success после успешной отправки

### Другой способ
- OAuthButtons — стилизовать кнопки как outlined pill (borderRadius 24px, fullWidth)
- Кнопки: «Войти через Яндекс ID», «Войти через VK ID»

---

## 7. Alert'ы

- Все ошибки: `Alert severity="error" variant="outlined"` внутри Paper, над формой
- Успешная отправка кода: `Alert severity="success" variant="outlined"`
- OAuth-ошибки: так же внутри Paper

---

## 8. Иконки в TextField

Добавить `InputAdornment` с иконками для визуального улучшения:
- Email: `<Mail>` иконка (lucide-react)
- Пароль: `<Lock>` иконка

Иконки только если это не перегружает минималистичный стиль. Решение — использовать в полях email и пароля `startAdornment`.

---

## 9. Адаптивность

- `min-height` вместо `height` (использовать `minHeight: calc(100vh - 64px)`)
- Paper: `mx: 2` на мобильных, `mx: auto` на десктопе
- Pill-кнопки остаются в ряд на всех разрешениях (они и так компактные)
- Отправка кода: на мобильных поля в столбец (уже есть `direction={{ xs: 'column', sm: 'row' }}`)

---

## 10. Плавные переходы

- Смена вкладок: контент формы — `opacity` transition 200ms
- Смена Вход/Регистрация: поля появляются с fade-in

---

## 11. Заметки

- BearLogo уже существует (`@/shared/ui/BearLogo`)
- OAuthButtons существует (`@/features/auth-oauth`)
- Менять бизнес-логику (хуки, mutations) не нужно — только вёрстку
- Текущий AuthPage — 232 строки, нужно заменить полностью
- Все цвета брать из темы (`primary.main`, `text.secondary`, `divider`, `background.paper`)
- Для градиента использовать `useTheme` + `alpha` из MUI
