본문으로 건너뛰기
cccskills
무료GitHub에 공개

mobile-design-system-foundation

Use when the mobile repository has no theme tokens or component library yet (a new app, an "Apply design system" task, or a task that asks for one), before building any screen - writes the approved design system's generated files from get_design_system (files true) and builds the theme from them when there is one.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

설치 방법 보기

포함된 파일(1)

  • SKILL.md7.4 KB

SKILL.md(원문)

설치하기 전에 에이전트에게 전달되는 지시 내용을 확인할 수 있습니다.

Mobile Design System Foundation

Overview

A screen built before tokens and an atomic component library exist turns into Color(0x…), one-off paddings, and a library that never forms. This skill lays the foundation once, in order, so every screen after it is composition, not invention.

Core principle: Lay the foundation before the first screen — tokens, folders, and the first atoms come before any feature work.

Detect first

get_design_system with files: true for this repository before anything else. When it returns a design system, the direction is already decided and approved: skip the design direction below and materialize it instead. Write every file in files verbatim at its path — DESIGN.md, design/tokens.json, design/tokens.css, design/INVENTORY.md; each carries a generated-file header and is never edited by hand, never transcribed. Then build the stack's theme from design/tokens.json by role (Flutter: ColorScheme light and dark plus ThemeExtensions for spacing, radius and sizes; SwiftUI: asset-catalog colour sets with Any/Dark appearances plus Theme.swift for type, spacing and radius; Compose: Color.kt / Theme.kt / Type.kt / Shape.kt with a light and a dark ColorScheme), each value exactly as its token holds it and named after it (color.light.primary → primary). Use the colours as given — no ColorScheme.fromSeed that would recompute them. The repository's own INVENTORY.md lists its components under the names design/INVENTORY.md gives them. A theme that already exists but differs from it gets its VALUES updated to the design system's, its structure kept. Only an empty answer leaves the direction to you.

A ThemeData/ThemeExtension, an asset-catalog colour set, a MaterialTheme wrapper, or an INVENTORY.md already present (and, when get_design_system returned a design system, the generated design/ files present and matching it) means this skill doesn't apply — stop, map and follow the existing structure (flutter-atomic-components / mobile-ui-ux) instead.

Design direction (5 minutes, written into the plan, not a separate doc)

Only when get_design_system returned nothing. One line each, from the task brief (the brief's own words win over any default below): audience + tone; 4–6 named brand colours mapped onto semantic roles (primary/secondary/error at minimum); type pairing; radius choice; ASCII wireframe of the key screen at phone (360) and tablet (768) width.

Per-stack tokens

Flutter (verified: flutter analyze clean):

@immutable
class AppSpacing extends ThemeExtension<AppSpacing> {
  const AppSpacing({this.xs = 4, this.sm = 8, this.md = 16, this.lg = 24, this.xl = 32});
  final double xs, sm, md, lg, xl;
  @override AppSpacing copyWith({double? xs, double? sm, double? md, double? lg, double? xl}) =>
      AppSpacing(xs: xs ?? this.xs, sm: sm ?? this.sm, md: md ?? this.md, lg: lg ?? this.lg, xl: xl ?? this.xl);
  @override AppSpacing lerp(AppSpacing? other, double t) => this;
}

ThemeData buildTheme(Brightness b) => ThemeData(
  colorScheme: ColorScheme.fromSeed(seedColor: const Color(0xFF2F5BEA), brightness: b),  // brand colour lives ONLY here
  extensions: const [AppSpacing()],
);

extension AppThemeX on BuildContext {
  AppSpacing get space => Theme.of(this).extension<AppSpacing>()!;
  ColorScheme get colors => Theme.of(this).colorScheme;
}

Folders: lib/ui/core/{theme,atoms,molecules,organisms} + lib/ui/features/<f>/ — this is the official Flutter architecture layout; follow the repo's existing layout if it already has one (e.g. lib/ui/atoms).

SwiftUI: asset-catalog colour sets with Any/Dark appearances, enum Space { static let xs: CGFloat = 4; static let sm: CGFloat = 8; static let md: CGFloat = 16; static let lg: CGFloat = 24 }, semantic Font text styles (never .system(size:) outside the theme), @ScaledMetric for any custom sizing so it still follows Dynamic Type.

Compose: data class AppSpacing(val xs: Dp = 4.dp, val sm: Dp = 8.dp, val md: Dp = 16.dp, val lg: Dp = 24.dp), val LocalSpacing = staticCompositionLocalOf { AppSpacing() }, val MaterialTheme.spacing @Composable get() = LocalSpacing.current; wrap the app in MaterialTheme(colorScheme = …) with dynamic colour on API 12+ and a static fallback below it.

Folders and inventory

Create the atomic folders (atoms/molecules/organisms, or the repo's existing naming) plus INVENTORY.md — header line One line per component: level · name · purpose · variants, one bullet per component added in the same commit that creates it.

Base atoms to start from: AppButton, AppTextField, AppIcon, StatusChip, Skeleton, EmptyState, ErrorView.

ui-guard as a test inside the normal suite

Wire a guard that runs inside the ordinary test command, so the build gate enforces it — not a separate CI step that can be skipped.

Flutter (verified: flags 4 violations in a raw-styled atom, passes on the token version):

// test/ui_guard_test.dart — runs inside `flutter test`, so the build gate enforces it
final banned = <String, RegExp>{
  'raw colour (use context.colors / ColorScheme)': RegExp(r'Color\(0x|Colors\.(?!transparent)'),
  'raw font size (use textTheme)': RegExp(r'fontSize:\s*\d'),
  'raw spacing (use context.space)': RegExp(r'EdgeInsets\.(all|symmetric|only|fromLTRB)\([^)]*\d'),
};
// walks lib/ui/**.dart except lib/ui/**/theme/**, collects "path:line reason", expect(offenders, isEmpty)

Compose: a JVM unit test scanning src/main/**/ui/** (except ui/theme) for Color(0x and a numeric literal inside .padding(.

iOS: SwiftLint custom_rules (Color\(red:, \.font\(\.system\(size:, \.padding\(\d) when the repo already uses SwiftLint; skip if it doesn't rather than introducing a new lint dependency for this alone.

Worked Example

❌ Start writing a screen straight away: Color(0xFF2196F3) inline, EdgeInsets.all(16)
   scattered across three widgets, no INVENTORY.md.

✅ 1. Detect: no ThemeData/ThemeExtension found → this skill applies.
   2. Design direction (one paragraph) → 3. buildTheme() + AppSpacing extension
   → 4. lib/ui/core/{theme,atoms,...} folders + INVENTORY.md → 5. AppButton,
   StatusChip, Skeleton atoms + widget tests → 6. ui_guard_test.dart green
   → 7. first screen, built entirely from atoms already in INVENTORY.md.

Common Mistakes

  • Writing a screen before any tokens exist — every colour becomes a one-off hex.
  • Skipping INVENTORY.md — the next task re-invents a Button.
  • Wiring the ui-guard as a separate script instead of a test inside the normal suite, so a hand-off can skip it.
  • Introducing SwiftLint to a repo that doesn't already use it, just for the guard.

Red Flags

  • A component file with Color(0x…), Colors.*, or a numeric EdgeInsets/.padding( literal anywhere in the diff outside the theme files.
  • lib/ui/ (or the repo's component folder) with no INVENTORY.md.
  • A primitive hand-rolled inline in a screen file instead of placed in the component library.

리뷰

아직 리뷰가 없습니다. 사용해 본 소감을 남겨 주세요.

댓글

로그인 없이 쓸 수 있습니다. 사용 후기, 질문, 작동하지 않은 환경 등을 편하게 남겨 주세요.

아직 댓글이 없습니다. 첫 댓글을 남겨 보세요.

보내면 바로 공개됩니다. 이메일 주소나 전화번호 같은 개인 정보는 쓰지 마세요. URL은 2개까지입니다.

0 / 1,000자

이 양식은 reCAPTCHA로 보호되며 Google 개인정보처리방침 및 서비스 약관이 적용됩니다.

같은 저장소의 스킬

Use when writing acceptance criteria for a task - express each as an observable Given/When/Then that QA can execute, including negative cases

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

makifbaysal/tasktrooper1172026년 10월 21일 업데이트

Use when the diff adds or changes an endpoint, resolver, RPC, job or query that takes an object id, a role check, a request binding or a tenant filter - BOLA/IDOR, function-level authorization, mass assignment and tenant scoping

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

makifbaysal/tasktrooper1172026년 10월 21일 업데이트

Use on every UI change - semantic HTML, labels for controls, keyboard-navigable dialogs/menus, visible focus, and never color as the only signal

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

makifbaysal/tasktrooper1172026년 10월 21일 업데이트

Use when a task changes any screen, form, dialog, menu or control - Lighthouse/axe scan of the changed screens, a keyboard walk, and the thresholds that fail a task

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

makifbaysal/tasktrooper1172026년 10월 21일 업데이트

How to work a task returned with review, QA or UAT findings. Use when a task is in need_revision or PR review comments are in your context.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

makifbaysal/tasktrooper1172026년 10월 21일 업데이트

Use when the repository keeps its alerting in code, or a person asks for alerts outside TaskTrooper - PrometheusRule YAML, a Cloud Monitoring alert policy in Terraform, a Datadog monitor, each routed to TaskTrooper's alert ingest URL so it opens an incident here

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

makifbaysal/tasktrooper1172026년 10월 21일 업데이트

makifbaysal의 스킬 모두 보기

이 스킬의 문제 신고