Sumsub — Mobile SDK theming (iOS & Android)
Scan the host app's design system, derive a full palette, and write a theme the SDK picks
up at launch — iOS: a SumsubTheme: SNSTheme subclass assigned as
sdk.theme = SumsubTheme(); Android: a sumsubTheme(context) factory built with the
SNSTheme { … } DSL and attached via SNSMobileSDK.Builder(...).withTheme(...) — so the
KYC screens match the app instead of looking bolted on. Every SDK theme property is either
mapped from the app or explicitly derived; nothing is left at the SDK default by accident.
This is the trunk (always-on). Detect the platform, then walk that track's four stages in order: Scan → Map → Generate → Report.
Asking vs doing — keep approvals meaningful
- Read-only is free — scan / grep / read the project's colors, fonts and build settings without asking.
- Batch mutations into one approval, not one per item ("I'll write
SumsubTheme.swifthere + insert thissdk.theme = …line [diff] — apply?"). - Ask explicitly only for: the target file path, genuinely ambiguous brand / legibility / font choices, and editing existing app code (the single theme-attachment line — the skill adds it itself, never punts it to the user).
Detect the platform (do this before opening any stage file)
Decide whether this is an iOS or Android project — the token sources, the theme API, and the generated language all differ. Read-only.
# iOS markers
find . -maxdepth 3 \( -name '*.xcodeproj' -o -name '*.xcworkspace' -o -name 'Podfile' -o -name 'Package.swift' \) 2>/dev/null
# Android markers
find . -maxdepth 3 \( -name 'build.gradle' -o -name 'build.gradle.kts' -o -name 'settings.gradle*' -o -name 'AndroidManifest.xml' \) 2>/dev/null
- iOS only → iOS track. Android only → Android track.
- Both present → report both and ask which platform to theme. One platform per run. (React Native / Flutter wrappers are out of scope — this skill themes the native SDKs.)
- Neither → ask the user to point at the app's source root.
How to navigate this skill
A strictly linear flow per track — walk the four stages in order; each is self-contained and ends with a Next pointer.
iOS track
ios/stages/1-scan.md— scan the host app's design system (read-only).ios/stages/2-map.md— map tokens onto the SDK theme (after resolving open decisions).ios/stages/3-generate.md— writeSumsubTheme.swift(after the path is confirmed).ios/stages/4-report.md— present the coverage report.
Android track
android/stages/1-scan.md— scan the host app's design system (read-only).android/stages/2-map.md— map tokens onto the SDK theme (after resolving open decisions).android/stages/3-generate.md— writeSumsubTheme.kt(after the path is confirmed).android/stages/4-report.md— present the coverage report.
Fallback (last resort only). This skill and its stage files are the primary source — don't reach for external docs by default. Only if you hit a genuine blocker they don't resolve, consult the Sumsub theme docs: iOS · Android.
When the stages are walked, return here for Guardrails and Handoff.
Guardrails — what this skill must never do
- Never write the file without confirming the path with the user.
- Never leave a property at SDK default without noting it in the report.
- Never hard-code arbitrary values — colors come from the app palette or the documented alpha-derivation.
- Always show the hex (or asset / resource name) when reporting or asking; add a plain-word description in parentheses, never instead of the hex.
- Never silently guess a genuinely ambiguous choice — offer plain-word options + a recommendation; but don't over-ask where a safe default exists.
- Never theme the host app itself — only the Sumsub SDK screens.
- Never change SDK integration logic (install / init / present / launch). The skill's one edit to existing code is attaching the theme at the launch site — it makes that edit itself, with approval.
- (iOS) Never emit unsafe color/font code — no flat
UIColorliterals for dual-appearance apps (use named assets orUIColor { traits in … }); noUIFont(name:size:)without a?? .systemFont(…)fallback; no decorative/app colors in the success/warning/critical slots. - (iOS) Never override
images.*for verification-flow icons — Sumsub-specific, not derivable from the host. - (Android) Never emit single-appearance colors for a dual-appearance app — resolve both variants and use the two-argument
SNSThemeColor(light, dark); noResourcesCompat.getFontresult without a?: Typeface.…fallback. - (Android) Never override the SDK's
sns_*resources (colors / strings / drawables in the host'sres/) — theme through the Theme API only; resource overrides fight the theme and break on SDK updates. - (Android) Attach the theme on the builder —
.withTheme(...)before.build(); never try to restyle afterlaunch().
Handoff
After the file is generated and wired, summarise:
- File created —
SumsubTheme.swift/SumsubTheme.ktand where it lives (iOS: confirm it's a target member; Android: any location under a source set compiles). - Coverage — the Stage 4 report (mapped / derived / left at default), plus any contrast fix or choice the user made.
- Wiring done — the exact launch site (file:line) where the theme is attached (iOS:
sdk.theme = SumsubTheme()orSumsubTheme.make(); Android:.withTheme(sumsubTheme(activity))on the builder). If no integration code was found (SDK not wired up yet), say so and point tosumsub-integrate-msdk— the theme is ready to attach once it is.