К основному содержанию
скилл CX Codex

mobile-ux-optimizer — скилл Claude Code: что делает и как установить

Скилл помогает адаптировать веб-интерфейсы под смартфоны: настраивает safe area, переводит вёрстку на dvh и увеличивает области клика под тач-экраны.

Установить в Claude Code · Через Skills CLI (Vercel) Все способы и платформы ↓
npx skills add curiositech/some_claude_skills --skill mobile-ux-optimizer -a claude-code
Открыть на GitHub

Что делает mobile-ux-optimizer

Скилл учит агента верстать интерфейсы по принципу mobile-first: от базовой мобильной разметки вверх к экранам от 768px. Он подставляет единицы 100dvh вместо 100vh. Так адресная строка мобильного браузера перестаёт обрезать контент страницы. Для экранов с вырезами добавляется метатег viewport-fit=cover и безопасные отступы env(safe-area-inset-*) под чёлку и системную полосу навигации.

Внутри заложены стандарты кликабельных зон: минимум 44×44 точки по рекомендациям Apple и 48×48dp по правилам Material Design. Скилл генерирует готовые React-компоненты мобильной навигации. Среди них нижняя панель со служебными классами вроде .pb-safe и выдвижная шторка с блокировкой скролла страницы. Для жестов предусмотрены хуки useSwipe и usePullToRefresh.

Скилл бесполезен для нативных приложений на Swift или React Native, потому что он заточен исключительно под веб в браузере. Вопросы общего синтаксиса Tailwind или настройки service worker для PWA автор также выносит в отдельные навыки.

Какие задачи решает

  • адаптировать высоту экранов под плавающие панели браузера через 100dvh
  • настроить отступы safe-area-inset под чёлки и домашний индикатор
  • увеличить размеры тач-таргетов до стандартов 44–48 пикселей
  • собрать адаптивную нижнюю навигацию или шторку меню на React
  • привязать обработку свайпов и pull-to-refresh на тач-экранах

Примеры запросов агенту

  • Исправь мобильное меню: добавь отступы под safe area и сделай кнопки высотой от 44px
  • Экран обрезается мобильным браузером, переведи вёрстку с 100vh на 100dvh
  • Сделай нижнюю панель навигации для смартфона на Tailwind с классом pb-safe

Как установить mobile-ux-optimizer

1Через Skills CLI (Vercel)

npx skills add curiositech/some_claude_skills --skill mobile-ux-optimizer -a claude-code

2Вручную: положить файлы

~/.claude/skills/mobile-ux-optimizer/SKILL.md

Папка скилла целиком; для одного проекта — .claude/skills/mobile-ux-optimizer/

По шагам, с командами для каждой платформы: Как установить скилл в Claude Code: пять способов

Вопросы о mobile-ux-optimizer

Как установить mobile-ux-optimizer в Claude Code?

Выполните команду npx skills add curiositech/some_claude_skills --skill mobile-ux-optimizer -a claude-code. Агент сразу получит инструкции по мобильной вёрстке.

Что делает скилл mobile-ux-optimizer?

Он направляет агента при разработке мобильного веба: устраняет скачки интерфейса из-за адресной строки через 100dvh, рассчитывает отступы под вырезы экранов и удерживает размеры кнопок от 44 пикселей.

Подходит ли этот скилл для проектов на React Native?

Нет, скилл рассчитан только на мобильные веб-интерфейсы. Для нативной разработки под iOS или Android на React Native и Swift автор рекомендует специализированные инструменты.

Исходный текст

SKILL.md · MIT
---
name: mobile-ux-optimizer
description: Mobile-first UX optimization for touch interfaces, responsive layouts, and performance. Use for viewport handling, touch targets, gestures, mobile navigation. Activate on mobile, touch, responsive,
  dvh, viewport, safe area, hamburger menu. NOT for native app development (use React Native skills), desktop-only features, or general CSS (use Tailwind docs).
allowed-tools: Read,Write,Edit,Bash,Grep,Glob
metadata:
  category: Design & Creative
  tags:
  - mobile
  - ux
  - touch
  - responsive
  - viewport
  - safe-area
  - navigation
  pairs-with:
  - skill: pwa-expert
    reason: PWAs are a primary mobile delivery mechanism requiring touch and viewport optimization
  - skill: ux-friction-analyzer
    reason: Mobile-specific friction points (fat finger errors, scroll hijacking) need specialized analysis
  - skill: adhd-design-expert
    reason: Mobile ADHD users face amplified cognitive load that requires specialized UX optimization
---

# Mobile-First UX Optimization

Build touch-optimized, performant mobile experiences with proper viewport handling and responsive patterns.

## When to Use

✅ **USE this skill for:**
- Viewport issues (`100vh` problems, safe areas, notches)
- Touch target sizing and spacing
- Mobile navigation patterns (bottom nav, drawers, hamburger menus)
- Swipe gestures and pull-to-refresh
- Responsive breakpoint strategies
- Mobile performance optimization

❌ **DO NOT use for:**
- Native app development → use `react-native` or `swift-executor` skills
- Desktop-only features → no skill needed, standard patterns apply
- General CSS/Tailwind questions → use Tailwind docs or `web-design-expert`
- PWA installation/service workers → use `pwa-expert` skill

## Core Principles

### Mobile-First Means Build Up, Not Down

```css
/* ❌ ANTI-PATTERN: Desktop-first (scale down) */
.card { width: 400px; }
@media (max-width: 768px) { .card { width: 100%; } }

/* ✅ CORRECT: Mobile-first (scale up) */
.card { width: 100%; }
@media (min-width: 768px) { .card { width: 400px; } }
```

### The 44px Rule

Apple's Human Interface Guidelines specify **44×44 points** as minimum touch target. Google Material suggests **48×48dp**.

```tsx
// Touch-friendly button
<button className="min-h-[44px] min-w-[44px] px-4 py-3">
  Tap me
</button>

// Touch-friendly link with adequate padding
<a href="/page" className="inline-block py-3 px-4">
  Link text
</a>
```

## Viewport Handling

### The `dvh` Solution

Mobile browsers have dynamic toolbars. `100vh` includes the URL bar, causing content to be cut off.

```css
/* ❌ ANTI-PATTERN: Content hidden behind browser UI */
.full-screen { height: 100vh; }

/* ✅ CORRECT: Responds to browser chrome */
.full-screen { height: 100dvh; }

/* Fallback for older browsers */
.full-screen {
  height: 100vh;
  height: 100dvh;
}
```

### Safe Area Insets (Notches & Home Indicators)

```css
/* Handle iPhone notch and home indicator */
.bottom-nav {
  padding-bottom: env(safe-area-inset-bottom, 0);
}

.header {
  padding-top: env(safe-area-inset-top, 0);
}

/* Full safe area padding */
.safe-container {
  padding: env(safe-area-inset-top)
           env(safe-area-inset-right)
           env(safe-area-inset-bottom)
           env(safe-area-inset-left);
}
```

**Required meta tag:**
```html
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
```

### Tailwind Safe Area Classes

```tsx
// Custom Tailwind utilities (add to globals.css)
@layer utilities {
  .pb-safe { padding-bottom: env(safe-area-inset-bottom); }
  .pt-safe { padding-top: env(safe-area-inset-top); }
  .h-screen-safe { height: calc(100dvh - env(safe-area-inset-top) - env(safe-area-inset-bottom)); }
}

// Usage
<nav className="fixed bottom-0 pb-safe bg-leather-900">
  <BottomNav />
</nav>
```

## Mobile Navigation Patterns

### Bottom Navigation (Recommended for Mobile)

```tsx
// components/BottomNav.tsx
'use client';

import { usePathname } from 'next/navigation';
import Link from 'next/link';

const navItems = [
  { href: '/', icon: HomeIcon, label: 'Home' },
  { href: '/meetings', icon: CalendarIcon, label: 'Meetings' },
  { href: '/tools', icon: ToolsIcon, label: 'Tools' },
  { href: '/my', icon: UserIcon, label: 'My Recovery' },
];

export function BottomNav() {
  const pathname = usePathname();

  return (
    <nav className="fixed bottom-0 left-0 right-0 bg-leather-900 border-t border-leather-700 pb-safe">
      <div className="flex justify-around">
        {navItems.map(({ href, icon: Icon, label }) => {
          const isActive = pathname === href || pathname.startsWith(`${href}/`);
          return (
            <Link
              key={href}
              href={href}
              className={`
                flex flex-col items-center py-2 px-3 min-h-[56px] min-w-[64px]
                ${isActive ? 'text-ember-400' : 'text-leather-400'}
              `}
            >
              <Icon className="w-6 h-6" />
              <span className="text-xs mt-1">{label}</span>
            </Link>
          );
        })}
      </div>
    </nav>
  );
}
```

### Slide-Out Drawer (Side Menu)

```tsx
'use client';

import { useState, useEffect } from 'react';
import { createPortal } from 'react-dom';

interface DrawerProps {
  isOpen: boolean;
  onClose: () => void;
  children: React.ReactNode;
}

export function Drawer({ isOpen, onClose, children }: DrawerProps) {
  // Prevent body scroll when open
  useEffect(() => {
    if (isOpen) {
      document.body.style.overflow = 'hidden';
    }
    return () => {
      document.body.style.overflow = '';
    };
  }, [isOpen]);

  // Close on escape
  useEffect(() => {
    const handleEscape = (e: KeyboardEvent) => {
      if (e.key === 'Escape') onClose();
    };
    document.addEventListener('keydown', handleEscape);
    return () => document.removeEventListener('keydown', handleEscape);
  }, [onClose]);

  if (!isOpen) return null;

  return createPortal(
    <div className="fixed inset-0 z-50">
      {/* Backdrop */}
      <div
        className="absolute inset-0 bg-black/60 backdrop-blur-sm"
        onClick={onClose}
        aria-hidden="true"
      />

      {/* Drawer */}
      <div
        className="absolute left-0 top-0 h-full w-[280px] max-w-[80vw]
                   bg-leather-900 shadow-xl transform transition-transform
                   animate-slide-in-left"
        role="dialog"
        aria-modal="true"
      >
        <div className="h-full overflow-y-auto pt-safe pb-safe">
          {children}
        </div>
      </div>
    </div>,
    document.body
  );
}
```

## Touch Gestures

> **Full implementations in `references/gestures.md`**

| Hook | Purpose |
|------|---------|
| `useSwipe()` | Directional swipe detection with configurable threshold |
| `usePullToRefresh()` | Pull-to-refresh with visual feedback and resistance |

**Quick usage:**

```tsx
// Swipe to dismiss
const { handleTouchStart, handleTouchEnd } = useSwipe({
  onSwipeLeft: () => dismiss(),
  threshold: 50,
});

// Pull to refresh
const { containerRef, pullDistance, isRefreshing, handlers } = 
  usePullToRefresh(async () => await refetchData());
```

## Mobile Performance

### Image Optimization

```tsx
import Image from 'next/image';

// Responsive images with proper sizing
<Image
  src="/hero.jpg"
  alt="Hero"
  fill
  sizes="(max-width: 768px) 100vw, 50vw"
  priority // For above-the-fold images
  className="object-cover"
/>

// Lazy load below-fold images
<Image
  src="/feature.jpg"
  alt="Feature"
  width={400}
  height={300}
  loading="lazy"
/>
```

### Reduce Bundle Size

```tsx
// Dynamic imports for heavy components
const HeavyChart = dynamic(() => import('@/components/Chart'), {
  loading: () => <ChartSkeleton />,
  ssr: false, // Skip server render for client-only
});

// Lazy load below-fold sections
const Comments = dynamic(() => import('@/components/Comments'));
```

### Skeleton Screens (Not Spinners)

```tsx
// Skeleton that matches final content layout
function MeetingCardSkeleton() {
  return (
    <div className="p-4 bg-leather-800 rounded-lg animate-pulse">
      <div className="h-4 bg-leather-700 rounded w-3/4 mb-2" />
      <div className="h-3 bg-leather-700 rounded w-1/2 mb-4" />
      <div className="flex gap-2">
        <div className="h-6 w-16 bg-leather-700 rounded" />
        <div className="h-6 w-16 bg-leather-700 rounded" />
      </div>
    </div>
  );
}

// Usage
{isLoading ? (
  <div className="space-y-4">
    {[...Array(5)].map((_, i) => <MeetingCardSkeleton key={i} />)}
  </div>
) : (
  meetings.map(m => <MeetingCard key={m.id} meeting={m} />)
)}
```

## Responsive Patterns

### Tailwind Breakpoint Strategy

```
sm: 640px   - Large phones (landscape)
md: 768px   - Tablets
lg: 1024px  - Small laptops
xl: 1280px  - Desktops
2xl: 1536px - Large screens
```

```tsx
// Mobile: stack, Tablet+: side-by-side
<div className="flex flex-col md:flex-row gap-4">
  <aside className="w-full md:w-64">Sidebar</aside>
  <main className="flex-1">Content</main>
</div>

// Mobile: bottom nav, Desktop: sidebar
<nav className="md:hidden fixed bottom-0 left-0 right-0">
  <BottomNav />
</nav>
<aside className="hidden md:block w-64">
  <SidebarNav />
</aside>
```

### Container Queries (CSS-only Responsive Components)

```css
/* Component responds to its container, not viewport */
@container (min-width: 400px) {
  .card { flex-direction: row; }
}
```

```tsx
<div className="@container">
  <div className="flex flex-col @md:flex-row">
    {/* Responds to parent container width */}
  </div>
</div>
```

## Testing on Real Devices

### Chrome DevTools Mobile Emulation
1. Open DevTools (F12)
2. Toggle device toolbar (Ctrl+Shift+M)
3. Select device or set custom dimensions
4. **Throttle network/CPU** for realistic performance

### Must-Test Scenarios
- [ ] Content doesn't get cut off by notch/home indicator
- [ ] Touch targets are at least 44×44px
- [ ] Scrolling is smooth (no jank)
- [ ] Bottom nav doesn't block content
- [ ] Forms work with virtual keyboard visible
- [ ] Landscape orientation works
- [ ] Pull-to-refresh doesn't fight with scroll

### BrowserStack/Real Device Testing
```bash
# Expose local dev server to internet
npx localtunnel --port 3000
# or
ngrok http 3000
```

## Quick Reference

| Issue | Solution |
|-------|----------|
| Content cut off at bottom | Use `100dvh` instead of `100vh` |
| Notch overlaps content | Add `pt-safe` / `pb-safe` |
| Touch targets too small | Min 44×44px |
| Scroll locked | Check `overflow: hidden` on body |
| Keyboard covers input | Use `visualViewport` API |
| Janky scrolling | Use `will-change: transform` |
| Double-tap zoom | Add `touch-action: manipulation` |

## References

See `/references/` for detailed guides:
- `keyboard-handling.md` - Virtual keyboard and form UX
- `animations.md` - Touch-friendly animations
- `accessibility.md` - Mobile a11y requirements

© curiositech · MIT · curiositech/some_claude_skills

Похожие скиллы

Всё по теме «Фронтенд и UI» →
mobile-design manutej Скилл для мобильного интерфейса: тач-цели, жесты, зоны большого пальца, безопасные области и адаптив под маленькие экраны. CX Codex +1 545установок mobile-native emilkowalski Убирает мелочи, из-за которых веб-приложение на телефоне выдаёт себя: залипающий hover, вспышку при тапе, ошибку с 100vh. CX Codex +1 86 600установок build-mobile-threejs-games MengTo Скилл для сборки и проверки Three.js-игры под мобильный веб: тач-управление, адаптивный HUD, бюджеты производительности. CX Codex +1 1 300установок godot-platform-mobile thedivergentai Скилл для ИИ-агента, который ведёт мобильную сборку Godot: тач-ввод, вырезы экрана, троттлинг и права Android. CX Codex +1 421установок mobile-principles AThevon Набор правил для мобильного интерфейса: размеры тап-зон, отказ от hover, зоны большого пальца, safe area и жесты. Подключается, когда агент видит мобильную платформу. CX Codex +1 974установок tailwindcss-mobile-first JosiahSiegel Скилл для ИИ-агента, который подсказывает, как верстать адаптивные интерфейсы на Tailwind CSS v4 по принципу mobile-first. Пригодится, когда нужно разложить брейкпоинты, типографику и сетки по полочкам. CX Codex +1 2 100установок

Из того же набора20

personal-finance-coach Скилл проводит расчёты пенсионных сценариев FIRE, помогает распределять активы и выбирать безопасные нормы изъятия капитала. Пригодится при планировании личных инвестиций. CX Codex +1 769установок photo-composition-critic Скилл для критики фотографий: оценивает композицию, цвет и эстетику, даёт конкретные замечания. Пригодится, когда нужно разобрать снимок, а не отретушировать его. CX Codex +1 643установок pwa-expert Помогает сделать веб-приложение устанавливаемым и работающим офлайн: манифест, Service Worker, стратегии кеширования, свой экран установки. CX Codex +1 544установок metal-shader-expert Помогает писать и оптимизировать шейдеры Metal под Apple GPU: MSL, PBR, tile-based deferred rendering, трассировка лучей. Пригодится, когда проект упирается в производительность графики на Apple Silicon. CX Codex +1 512установок web-design-expert Проектирует веб-интерфейсы, айдентику бренда и палитры в формате OKLCH. Помогает продумать визуальную иерархию и сетку сайта до передачи макетов в вёрстку. CX Codex +1 439установок color-theory-palette-harmony-expert Скилл для подбора цветовых палитр и последовательностей фото: перцептивные пространства LAB и OKLCH, расстояние землекопа, чередование тёплых и холодных тонов. CX Codex +1 430установок ai-video-production-master Скилл ведёт пайплайн от текста сценария до готового видео на Apple Silicon Mac: стоковые клипы, генерация T2V и I2V, облачные GPU. Пригодится, когда нужен ролик, а не отдельный кадр. CX Codex +1 398установок indie-monetization-strategist Скилл помогает инди-разработчикам выбирать модели монетизации для пет-проектов, настраивать тарифы SaaS и запускать спонсорство. Пригодится перед релизом продукта. CX Codex +1 387установок

Спонсоры проекта

Компании, которые помогают держать аналитику открытой