seenry-apps について
iOS、Android、ウェブアプリの調査、仕様化、プロトタイプ作成、シミュレーターでの確認を導くモバイルアプリ設計スキルです。アプリの一連のフローを調べ、特徴的な画面を定め、プラットフォームの慣例に沿って状態を検証します。
主な機能
- 01アプリの全フローを調査
- 02設計判断とパターンを記録
- 03特徴的な画面の方向性を検討
- 04iOS と Android のレイアウト指針
- 05連続する UI 状態の構築
- 06シミュレーターでフローを確認
活用シーン
- 01モバイルアプリのオンボーディング設計
- 02複数のモバイル環境向けのプロトタイプ作成
- 03ナビゲーションと戻る操作の確認
- 04調査した参考例と画面を比較
MCP 対応
Seenry MCP に接続すると、アプリのフローを検索し、ページごとに確認して参考例を取り入れます。未接続の場合はローカルの調査スクリプトを実行する手順です。
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ ayangabryl/ seenry-skills --skill seenry-appsインストール後、Claude Code で/seenry-appsを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
agents/openai.yamlreferences/flows.mdresearch.mdscripts/app_preflight.mjsindependent_flow_gate.pyreview_schema.json詳細
Seenry Apps
モバイルの品質は、主にプラットフォームへの忠実さと、Web システムと同じ規律によって決まります。厳格なグリッド、レイヤー構造のコンポーネント、少数の文字サイズ、1つのアクセントカラー、そしてあらゆる状態を設計することが重要です。プロジェクトで既に採用されている技術スタックとコンポーネントを使用してください。
ワークフロー
- ジョブに名前を付けます。
research/brief.mdを作成します。製品が何をベースにしているか(フロー)、どのような見た目にするか(ルック)、シグネチャースクリーンがどのジョブを担うか(エッジ)を記述します。「Xをベースに、Yのようにデザインする」とは、Xからフローを、Yからルックを取り入れるという意味です。1つのアプリを指定した場合は、そのアプリから両方を取り入れます。指定しない場合は、意図を持ってルックを選びます。research に従ってください。 - 実際のアプリで、最初から最後までの体験を調査します。 Seenry MCPを使い、名前でアプリを探し(
search_app_flows {q: "<app>"})、順番に完全なフローをたどります(get_app_flowを使い、最後までページを進めます)。構築するフローごとに、完全なフローを少なくとも3つ確認します(ベースにするアプリに加え、オンボーディングならHeadspace、Duolingo、Calm、Noomなど、その分野で最も優れたアプリ)。ルックに使うアプリは、2〜3個のフローにわたって8画面以上確認し、その他の各画面タイプは10画面以上確認します。エッジについてはborrow_referencesを1回実行します。新しい画面を見ても仕様が変わらなくなる飽和点で調査を止めます。アプリ画面には小さなウォーターマークが入っていますが、無視してください。 - コードを書く前に仕様を作成します。
research/flows.mdには、各フローの骨格(各ステップで、何を尋ね、何を提供し、どう提示するか)を記録します。.seenry/look.mdには、ルックに使うアプリの配色、書体、数字、名前の付いたシグネチャーコンポーネントを記載します。research/patterns.mdでは、基本要件、エッジ、導入部分を分けて記録します。research/decisions.mdには、各判断と、その根拠となった画面IDに加え、ナビゲーションマップを記載します。オンボーディングのすべての画面に、この製品のコンテンツを使ったルックのシグネチャーコンポーネントを1つ取り入れます。 デフォルトではなく、シグネチャーを取り入れます。 ルックに使うアプリのプラットフォーム標準(システムブルー、白いグループ化シート、SF Pro、グレーの行)は、そのアプリ独自のルックではありません。どのアプリにもあるものです。そのアプリらしさを形作るのは、シグネチャーコンポーネントと、それを支える姿勢です。その上に製品独自のアイデンティティを築きます。製品独自のアイデアからアクセントカラーを選び(ブランドカラーでない限り、iOSブルーやインディゴは使いません)、人々の記憶に残るディスプレイ書体または数字の表現を取り入れ、テーマに合った色の世界を作ります(睡眠関連の製品なら、夜を感じさせる色にします)。ロゴを差し替えるだけでどのアプリのオンボーディングにも見えてしまうなら、それはリサーチに忠実であっても、粗雑な仕上がりです。 - flows に従って、フローとその入口を設計します。各画面がどの形式か(プッシュ、モーダル、シート、置き換え)、そこから戻るとどうなるか、そして戻ると再び入ってしまってはならない一方通行の入口(オンボーディング完了、サインイン、購入)を明確にします。オンボーディングでは、1画面につき質問を1つにし、回答を通じて説明し、回答をもとにした見返りを提示してから、権限の確認やペイウォールを表示します。
- シグネチャースクリーンを検討し、先入観なしに選びます。 フローの目的となる画面(通常は見返りの画面。ウェルカム画面も同じ方向性にします)のデザイン案を3つ作り、それぞれ別ファイルにします。1つは一般的な操作方法を使い、残り2つはそれぞれ既成概念を打ち破る案にし、さらにもう1つは借用したエッジを取り入れます。最初に目を引くものが異なる必要があり、レイアウトだけの違いでは不十分です。
node ../seenry/scripts/pick.mjs a.html b.html c.html --brief <brief> --refs <look app screens>を実行し、選ばれた案の方向性でフロー全体を構築します。 - 4層構造 に従って、各コンポーネントを仕様化します。グリッド → セーフスペース → 構造 → 書体と状態の順です。
- 実際のデータで、相互につながる各状態を構築します。 読み込み中、空、エラー、権限拒否、オフライン、成功、キーボード表示時のレイアウトを用意します。Webプロトタイプでは、
<!doctype html>、<meta charset="utf-8">、ビューポートのメタタグを最初に記述します。 - 事前チェックで各種件数を確認します。
node scripts/app_preflight.mjs <source>で、アクセントカラーの色相グループ、グレーのグループ、角丸の段階、UI内の絵文字、グラデーション、書体ファミリー、意図ごとのラベル数、エンコーディング、ドキュメントヘッダーを数えます。件数の不合格は修正すべきものであり、判断の余地はありません。Flightyのステータスカラーのように、ルックから意図的に逸脱する場合は、decisions.mdに記載します。 - シミュレーターで操作し、記録します。 iOS Simulator(またはAndroidエミュレーター)で、Webプロトタイプも含めてフローを最初から最後まで実行します。フォルダーを配信し、インストール済みのiPhoneを起動します(
xcrun simctl list devices availableを実行し、続けてxcrun simctl boot <udid>を実行します。シミュレーター1台につき1回実行します)。xcrun simctl openurl booted http://127.0.0.1:<port>/を実行し、各ステップのスクリーンショットをxcrun simctl io booted screenshot NN-step.pngで撮影します。幅390pxのデスクトップブラウザーでは、Safariのツールバー、セーフエリア、キーボード、実際のフォント描画は確認できません。すべてのステップ、すべての戻る経路(シェブロン、画面端からのスワイプ、Androidの戻る操作)、一方通行の入口を通過した後の戻る操作、シートをドラッグして途中でキャンセルする操作、キーボードの表示・非表示をテストし、すべてを一度はスキップします。記録し(xcrun simctl io booted recordVideo rec.mov。Androidではadb shell screenrecord /sdcard/rec.mp4)、再生速度どおりとコマ送りの2回確認して、テーマの誤表示、レイアウトの急な変化、フレームの欠落を探します。 - 画面ごとにリファレンスを上回ります。 自分の各画面を、調査した中で最も優れた同等の画面と並べます。見劣りする画面があれば、再度改善に取り組みます。その後、チェックを実行します。
node ../seenry/scripts/check.mjs --screens <screens in flow order> --video rec.mov --brief <brief>を実行し、PASSまたはSTOPになるまで修正を適用します。ショーケースモードで、目標未満のSTOPになった場合は、ステップ5とは別の方向性でシグネチャースクリーンとフローを作り直し、報告前にcheck.mjs --new-directionを1回実行します。デフォルトでは--mode quick(批評は1ラウンドのみで、修正は1回適用)を使います。プロダクション品質の成果物を求められた場合は--mode polishを使い、ショーケースの場合に限り--mode showcaseを使います。納品時には、スコアとレベルを報告します。pass(9)、leader level(8)、またはleader level未満の場合は不足点も記載します。Seenry MCPがない場合は、まずnode ../seenry/scripts/research.mjs --type appを実行し、批評の基準を用意します。seenryに従って.seenry/idea.md、.seenry/motion.md、DESIGN.mdを作成します。これらはチェックの対象です。 seenryに従ってSeenryシート(シート)を納品します。状態ごとのスクリーンショット、調査したアプリとフロー(ID付き)、各判断とその出典、シグネチャースクリーンの構造、ガイドラインを含めます。sheet.pyを使い、anatomy.mjs(Webのみ)が適用されないシミュレーターのスクリーンショットには、手作業で注釈を付けます。
プラットフォームシステム
| iOS | Android(Material 3) | |
|---|---|---|
| グリッド | 4ptを基準とし、レイアウトは8の倍数 | 4dpを基準とし、レイアウトは8の倍数 |
| 画面の余白 | 16(大型スマートフォンとインセット付きグループリストでは20) | 16(大型端末では24) |
| タッチ領域の最小サイズ | 44×44 pt | 48×48 dp |
| ナビゲーションバー | 44 + 大きなタイトル52 | トップアプリバー64 |
| タブバー | 49 + ホームインジケーター、項目数3~5、アイコン24~28 + ラベル10/500 | ナビゲーションバー80、項目数3~5 |
| リスト行 | 最小44、サブタイトルまたは40pt画像がある場合は60~76 | 1行の場合は56、2行の場合は72 |
| グループリスト | インセット16、角丸10~12、区切り線はテキスト位置にインセット | カード、または区切り線付きの全幅レイアウト |
| ボタン | 高さ50の全幅プライマリボタン、角丸12~14またはカプセル型 | 塗りつぶし/トーナルボタン40、角丸は最大 |
| シート | 中/大のデテント、グラバー、システム標準の角丸約10 | ボトムシート、ドラッグハンドル32×4 |
| タイプ | SF Pro:大きなタイトル34、タイトル1 28、タイトル2 22、タイトル3 20、見出し17/600、本文17、コールアウト16、サブヘッド15、フットノート13、キャプション12/11 | Roboto/Flex:ディスプレイ57/45/36、見出し32/28/24、タイトル22/16/14、本文16/14/12、ラベル14/12/11 |
固定サイズではなく、Dynamic Typeのテキストスタイル(iOS)と、フォントスケールを適用したsp(Android)を使用します。プロジェクトのトークン、または.seenry/look.mdで調査した外観をシステムのセマンティックロール(label、secondaryLabel、systemBackground)に対応付けて使用すると、ダークモードやコントラストの向上にも対応できます。どちらもない場合に限り、標準のシステムカラーを使用します。これらの寸法はプラットフォームの最低基準であり、スタイルそのものではありません。Webプロトタイプでは、iOSのデフォルトスタイルではなく、ネイティブのサイズ、タッチ領域、安全領域を採用します。
画面のルール
- 画面ごとに主要アクションは1つとし、親指が届く位置に配置します。ホームインジケーターの上に固定する全幅ボタン、または「保存/完了」用のナビゲーションバー末尾の項目を使用します。
- **コンポーネントごとにテキストスタイルは最大3つ。**プレーヤーカードでは見出し、サブヘッド、キャプションを使用し、それ以外は使用しません。
- ネストした形状では同心円状の角丸(
inner = outer − inset)を使い、iOSでは連続した角の曲線(.continuous/スクワークル)を使用します。 - **コンテンツを優先します。**画面の大部分をリスト、メディア、レコードに使い、概要やヘッダーはコンパクトにします。大きなタイトルはスクロール時に縮小します。
- カスタムコントロールより先にネイティブコントロールを使用します。ピッカー、トグル、セグメントコントロール、メニュー、共有シート、日付ピッカーなどが該当します。カスタムコントロールを使う場合は、フィードバック(触覚、押下状態)とアクセシビリティをこれらに合わせます。
- **安全領域とキーボード。**ノッチ、Dynamic Island、ホームインジケーター、キーボードの下に要素が隠れないようにします。主要ボタンはキーボードの上に配置します。
- オンボーディング:画面ごとにアイデアは1つとし、進捗とスキップを見える位置に表示します。最初の画面で製品の特徴的なビューを見せ、選択肢は大きな行として配置します。権限の要求は、そのメリットが得られるタイミングで事前説明を挟んで行います。長さは調査したフローに合わせます。パーソナライズ機能のある製品では、回答ごとにメリットが明確に変わるなら8~15画面、パーソナライズするものがないツールなら1~3画面にします。ペイウォールの前に、回答に基づくメリットを提示します(フロー)。
- ペイウォール:製品の機能(実際の画面または機能)を示します。おすすめプランをあらかじめ選択した状態でプランを提示し、CTAのすぐ下に期間あたりの価格とトライアル条件を平易なテキストで表示します。購入の復元リンクと利用規約へのリンクも表示します。
- 設定:インセット付きのグループリストを使い、セクションごとに2~6行にします。アイコンタイルは角丸6~7でサイズ28~29とし、スタイルを統一します。値は末尾に
secondaryLabelで表示し、破壊的な操作は最後に分けて配置します。 - 空の状態とエラーの状態は該当領域内に表示し、解決につながるアクションを1つ設けます。
配置
ネイティブでも、同じキーレベル、インクレベル、光学的なルールを適用します(配置、光学調整)。SF Symbolsはグリフに合わせて配置します(.imageScaleとテキストとのベースライン揃えを使い、キャップハイトを揃えるにはalignmentGuideを使用します)。アイコンとラベルの行ではfirstTextBaselineで揃えます。円形ボタン内の再生/シェブロングリフが中央に見えることを、3xのスクリーンショットで確認します。
モーション
アニメーションは、どのくらいの頻度で使われるかに応じて使い分けます(フロー)。タブ、スクロール、戻る操作、キーボードにはプラットフォーム標準の動きを使い、タップ操作には150ms未満の短い動きを使います。オンボーディングの達成感を演出する場面のように、まれな場面だけで意図的に動きを使います。ナビゲーションの動きにはプラットフォーム標準のもの(プッシュ、シート、ズーム)を使います。カスタムモーションにはスプリング(response 0.35–0.5, dampingFraction 0.8–0.9)を使い、操作を中断できるようにします。体感としては150〜300msとし、確定時(選択、成功、警告)には触覚フィードバックを加えます。視差効果を減らす設定(Reduce Motion)を尊重してください。ウェブベースのアプリには、seenry-motionとSeenry Transitionsキットを使います。
ウェブキットが提供するのと同じトランジションを、ネイティブでも使います(指示がなくても、状況に応じて適用します)。
| 状況 | SwiftUI | Jetpack Compose | React Native |
|---|---|---|---|
| トリガーがサーフェスに変わる(メニュー、カードから詳細画面への遷移) | matchedGeometryEffectまたは.navigationTransition(.zoom(sourceID:in:))を使います。閉じると、トリガーがあった場所に戻ります | SharedTransitionLayout + sharedBounds | Reanimatedの共有エレメントトランジション |
| シート、ダイアログ | .presentationDetentsを使った.sheet。カスタムの場合は.spring(response: 0.4, dampingFraction: 0.86) | ModalBottomSheet、spring(dampingRatio = 0.86f, stiffness = 400f) | @gorhom/bottom-sheet、スプリングの減衰値は20〜24 |
| 数字の変化 | withAnimation内で.contentTransition(.numericText(value:)) | 桁ごとのAnimatedContent。方向に応じてスライドさせます | 方向に応じて、桁ごとにReanimatedのFadeIn/SlideInを使います |
| タブ、セグメントコントロール | matchedGeometryEffectを使った共有インジケーター | animateDpAsStateを使ったインジケーターのオフセットアニメーション | ReanimatedのwithSpringを使ったインジケーターのtranslateX |
| リストへの挿入、削除、並べ替え | 安定したIDに.transition(.move(edge:).combined(with: .opacity))を指定します | Modifier.animateItem() | LinearTransition / FadeInレイアウトアニメーション |
| ボタンの読み込み中、成功、エラー | .symbolEffectと.contentTransition(.symbolEffect(.replace))を使います。.sensoryFeedback | ラベルにAnimatedContentを使います。HapticFeedback | スケールを0.9→1にし、不透明度を変えてアイコンを切り替えます。expo-haptics |
| トースト、バナー | 上部のセーフエリアからスプリングで表示し、閉じるときは120msのease-outを使います | AnimatedVisibility(slideInVertically + fadeIn) | ReanimatedのSlideInUp / FadeOut |
退場は登場より速くします。リスト内で動かすのは変形と不透明度だけにし、カスタムアニメーションには必ず視差効果を減らす設定(Reduce Motion)に対応した動きを用意します(@Environment(\.accessibilityReduceMotion)、Settings.Global.ANIMATOR_DURATION_SCALE、AccessibilityInfo.isReduceMotionEnabled)。
アプリの安直さを避ける
| 兆候 | 改善策 |
|---|---|
| アプリ内にウェブ風の中央揃えヒーロー画面がある | コンテンツを優先したネイティブレイアウトにします |
| 光彩、グラデーション、浮遊する図形をあしらったカスタムタブバー | システムのタブバーか、ネイティブの寸法に合わせた控えめなカスタムタブバーにします |
| すべての行がそれぞれ色付きのグラデーションカードに収まっている | インセット付きのグループ化リストにします |
| 本文が12pxで、フォントサイズが固定されている | Dynamic Typeのスタイルを使い、本文は17ptにします |
| 価格やトライアル条件が隠れているペイウォール | 期間ごとの料金と条件をCTAの下に表示します |
| 既製の3Dイラストを使った紫色のグラデーションのオンボーディング | 製品が実際に役立つ様子を見せます |
| 「Flighty風」と名付けた見た目が、グループ化リストにシステムブルーを使っただけ | .seenry/look.mdにあるシグネチャーコンポーネントと、製品独自のアクセントカラーや色の世界観を使います |
| すべての質問が、ラジオボタン付きの白いカードと青い全幅ボタンで統一されている | 製品独自のオブジェクトとして回答を表現します(ボード上の時刻、記入されていくパスなど)。回答の種類ごとに異なる入力方法を使います |
| リファレンスのプラットフォーム標準の見た目をそのままコピーし、それを独自のスタイルと呼んでいる | リファレンスのシグネチャーコンポーネントと個性を取り入れます。標準設定はアイデンティティではありません |
<meta charset="utf-8">とビューポートのmetaタグがないウェブプロトタイプ | 両方を<head>に入れます。句読点が正しく表示され、レイアウトが390ptに収まることを確認します |
| 画面下端にある、高さ36ptのボタン | 高さ50pt、インセット16で、ホームインジケーターより上に配置します |
フローごとの完了条件
- 3つ以上の完全なフローと8つ以上の参考アプリ画面を調査し、IDを
research/に保存し、各画面で採用したパターンを明記している -
.seenry/look.mdが存在し、その特徴的なコンポーネントがこのプロダクトのコンテンツを反映したビルドに含まれ、アクセントと配色の世界観がプラットフォームのデフォルトではなく、プロダクト独自のものになっている - 特徴的な画面の3つの方向性を作成し、
pick.mjsでブラインド選定している - ナビゲーションマップを作成し、すべての画面で戻る操作を確認し、一方向の画面に再入場できないことを確認している
- オンボーディングが回答に基づく成果画面で終わり、すべての権限に許可を求める前の説明と、無理なく断れる方法があり、ペイウォールの条件がCTAの下に平易なテキストで記載されている
- 読み込み中、空、エラー、権限拒否、長文コンテンツの各状態を設計し、デフォルトに任せていない
-
app_preflight.mjsが合格するか、各例外をdecisions.mdに記載している - ライトモードとダークモード、Dynamic Typeの最大サイズ、安全領域、画面上のキーボードを確認している
- フローの録画を2回視聴し、フラッシュ、ジャンプ、フレーム落ちがないことを確認している
- 画面と録画をデスクトップブラウザーではなく、iOS Simulator(またはエミュレーター)で撮影している
- すべての画面が調査した最良の参考画面と並べても見劣りせず、指定されたモードで
check.mjsを実行し、スコアとレベルを報告している
レビュー
デバイスまたはシミュレーター上で、ライトモードとダークモード、最大の文字サイズを使い、フローを順番にスクリーンショットで撮影して、seenry-reviewまたは新しいエージェントでレビューします。オプションのフローゲートは、Codex CLIがインストールされている場合、順番に並べたキャプチャを新しいビジュアルレビュアーとフローレビュアーに送信します。静止画ではジェスチャー、VoiceOver、計算が正しく動作することを証明できません。これらはデバイス上で試してください。