{"id":"e0b41e4b-017d-43a4-956d-2f2c263a4ced","shortId":"3rHxZt","kind":"skill","title":"adaptive-ui","tagline":"27 Android skills for AI agents (Claude Code, Codex, Cursor). Fixes Supabase auth, Hilt errors, design inconsistency, kapt→ksp, missing UiState states. Reduced my token bills 5×. FitGenZ AI shipped in 18 days.","description":"# Adaptive UI — Every Screen, Every Device\r\n\r\nAndroid has 1B+ active large-screen devices. Every screen must work on phones, tablets,\r\nfoldables, and Chromebooks. These 10 rules make that happen automatically.\r\n\r\n## The golden rule\r\n\r\n**Before placing any layout element: ask how it looks at 600dp width AND 840dp width.**\r\nIf the answer is \"one stretched column\" — it's wrong.\r\n\r\n## Setup — required dependencies\r\n\r\n```toml\r\n[versions]\r\nmaterial3Adaptive = \"1.1.0\"\r\n\r\n[libraries]\r\nmaterial3-adaptive = { group = \"androidx.compose.material3.adaptive\", name = \"adaptive\", version.ref = \"material3Adaptive\" }\r\nmaterial3-adaptive-layout = { group = \"androidx.compose.material3.adaptive\", name = \"adaptive-layout\", version.ref = \"material3Adaptive\" }\r\nmaterial3-adaptive-navigation = { group = \"androidx.compose.material3.adaptive\", name = \"adaptive-navigation\", version.ref = \"material3Adaptive\" }\r\nwindowSizeClass = { group = \"androidx.compose.material3\", name = \"material3-window-size-class\", version.ref = \"material3\" }\r\n```\r\n\r\n## Rule 1: NavigationSuiteScaffold — zero-code adaptive navigation\r\n\r\n```kotlin\r\n// ✅ One component → BottomBar on phone, Rail on tablet, Drawer on large screen\r\n@Composable\r\nfun MyApp() {\r\n    val navController = rememberNavController()\r\n    val currentEntry by navController.currentBackStackEntryAsState()\r\n\r\n    NavigationSuiteScaffold(\r\n        navigationSuiteItems = {\r\n            TopLevelRoute.entries.forEach { route ->\r\n                item(\r\n                    selected = currentEntry?.destination?.hasRoute(route.routeClass) == true,\r\n                    onClick = { navController.navigateTopLevel(route) },\r\n                    icon = {\r\n                        Icon(\r\n                            if (currentEntry?.destination?.hasRoute(route.routeClass) == true)\r\n                                route.selectedIcon else route.icon,\r\n                            contentDescription = stringResource(route.labelRes)\r\n                        )\r\n                    },\r\n                    label = { Text(stringResource(route.labelRes)) },\r\n                    badge = if (route.badgeCount > 0) {\r\n                        { Badge { Text(\"${route.badgeCount}\") } }\r\n                    } else null\r\n                )\r\n            }\r\n        }\r\n    ) {\r\n        AppNavHost(navController)\r\n    }\r\n}\r\n// Compact  (< 600dp): BottomNavigationBar\r\n// Medium   (600-840dp): NavigationRail\r\n// Expanded (> 840dp): NavigationDrawer (permanent)\r\n// No extra code needed — ever.\r\n\r\n// ✅ Define top-level routes\r\nenum class TopLevelRoute(\r\n    val routeClass: KClass<*>,\r\n    val icon: ImageVector,\r\n    val selectedIcon: ImageVector,\r\n    @StringRes val labelRes: Int,\r\n    val badgeCount: Int = 0\r\n) {\r\n    Home(HomeRoute::class, Icons.Outlined.Home, Icons.Filled.Home, R.string.home),\r\n    Search(SearchRoute::class, Icons.Outlined.Search, Icons.Filled.Search, R.string.search),\r\n    Inbox(InboxRoute::class, Icons.Outlined.Inbox, Icons.Filled.Inbox, R.string.inbox, badgeCount = 3),\r\n    Profile(ProfileRoute::class, Icons.Outlined.Person, Icons.Filled.Person, R.string.profile),\r\n}\r\n\r\n// ✅ Top-level navigate helper — prevents duplicate backstack entries\r\nfun NavController.navigateTopLevel(route: TopLevelRoute) {\r\n    navigate(route.routeClass.objectInstance ?: return) {\r\n        popUpTo(graph.findStartDestination().id) { saveState = true }\r\n        launchSingleTop = true\r\n        restoreState = true\r\n    }\r\n}\r\n```\r\n\r\n## Rule 2: ListDetailPaneScaffold — master-detail for all list screens\r\n\r\n```kotlin\r\n// ✅ Every list+detail screen should use this — replaces simple NavHost navigation\r\n@Composable\r\nfun ItemsScreen() {\r\n    val navigator = rememberListDetailPaneScaffoldNavigator<String>()\r\n\r\n    BackHandler(navigator.canNavigateBack()) {\r\n        navigator.navigateBack()\r\n    }\r\n\r\n    ListDetailPaneScaffold(\r\n        directive   = navigator.scaffoldDirective,\r\n        value       = navigator.scaffoldValue,\r\n        listPane    = {\r\n            AnimatedPane {\r\n                ItemListPane(\r\n                    onItemSelected = { id ->\r\n                        navigator.navigateTo(ListDetailPaneScaffoldRole.Detail, id)\r\n                    }\r\n                )\r\n            }\r\n        },\r\n        detailPane  = {\r\n            AnimatedPane {\r\n                val itemId = navigator.currentDestination?.content\r\n                if (itemId != null) {\r\n                    ItemDetailPane(itemId = itemId)\r\n                } else {\r\n                    // Large screen placeholder when nothing selected\r\n                    Box(Modifier.fillMaxSize(), Alignment.Center) {\r\n                        Text(\"Select an item\", style = MaterialTheme.typography.bodyLarge,\r\n                            color = MaterialTheme.colorScheme.onSurfaceVariant)\r\n                    }\r\n                }\r\n            }\r\n        }\r\n    )\r\n}\r\n// Phone: list screen → tap → detail screen (back button returns to list)\r\n// Tablet: list + detail side by side, selection updates detail pane live\r\n```\r\n\r\n## Rule 3: WindowSizeClass breakpoints — 3 layout tiers\r\n\r\n```kotlin\r\n// ✅ Access WindowSizeClass from composable hierarchy\r\n@Composable\r\nfun MyScreen() {\r\n    val windowSizeClass = currentWindowAdaptiveInfo().windowSizeClass\r\n    val isCompact  = windowSizeClass.windowWidthSizeClass == WindowWidthSizeClass.COMPACT   // < 600dp\r\n    val isMedium   = windowSizeClass.windowWidthSizeClass == WindowWidthSizeClass.MEDIUM    // 600-840dp\r\n    val isExpanded = windowSizeClass.windowWidthSizeClass == WindowWidthSizeClass.EXPANDED  // > 840dp\r\n\r\n    when {\r\n        isExpanded -> ExpandedLayout()   // desktop-like, two or three columns\r\n        isMedium   -> MediumLayout()     // tablet, two columns or wider single\r\n        else       -> CompactLayout()    // phone, single column\r\n    }\r\n}\r\n\r\n// ✅ Extension helpers (add to AdaptiveTokens.kt)\r\nval WindowSizeClass.isCompact  get() = windowWidthSizeClass == WindowWidthSizeClass.COMPACT\r\nval WindowSizeClass.isMedium   get() = windowWidthSizeClass == WindowWidthSizeClass.MEDIUM\r\nval WindowSizeClass.isExpanded get() = windowWidthSizeClass == WindowWidthSizeClass.EXPANDED\r\n\r\n// ✅ Also check height for landscape phones (compact height)\r\nval WindowSizeClass.isShortLandscape get() =\r\n    windowHeightSizeClass == WindowHeightSizeClass.COMPACT && !isCompact\r\n```\r\n\r\n## Rule 4: Adaptive Grid — fills screen width automatically\r\n\r\n```kotlin\r\n// ✅ GridCells.Adaptive — correct column count for any screen width\r\nLazyVerticalGrid(\r\n    columns = GridCells.Adaptive(minSize = 180.dp),  // as many as fit\r\n    contentPadding = PaddingValues(Spacing.md),\r\n    horizontalArrangement = Arrangement.spacedBy(Spacing.sm),\r\n    verticalArrangement   = Arrangement.spacedBy(Spacing.sm)\r\n) {\r\n    items(items, key = { it.id }) { item ->\r\n        ItemCard(item, modifier = Modifier.fillMaxWidth())\r\n    }\r\n}\r\n// Phone (360dp): 1 column. Standard phone (412dp): 2 columns.\r\n// Tablet (768dp): 4 columns. Large screen (1200dp): 6 columns. Zero extra code.\r\n\r\n// ✅ Fixed columns per breakpoint when design requires control\r\n@Composable\r\nfun DesignControlledGrid(items: List<Item>, windowSizeClass: WindowSizeClass) {\r\n    val columns = when {\r\n        windowSizeClass.isExpanded -> GridCells.Fixed(4)\r\n        windowSizeClass.isMedium   -> GridCells.Fixed(3)\r\n        else                       -> GridCells.Fixed(2)\r\n    }\r\n    LazyVerticalGrid(columns = columns) { /* ... */ }\r\n}\r\n```\r\n\r\n## Rule 5: Foldable support — FoldingFeature states\r\n\r\n```kotlin\r\n// ✅ Detect and respond to fold states\r\n@Composable\r\nfun FoldAwareScreen() {\r\n    val windowInfo = currentWindowAdaptiveInfo()\r\n    val posture    = windowInfo.windowPosture\r\n    val hinges     = posture.hingeList\r\n\r\n    val foldingFeature = hinges.firstOrNull()\r\n\r\n    when {\r\n        foldingFeature?.state == FoldingFeature.State.HALF_OPENED &&\r\n        foldingFeature.orientation == FoldingFeature.Orientation.HORIZONTAL -> {\r\n            // Tabletop / book posture — split top/bottom\r\n            TabletopLayout()\r\n        }\r\n        foldingFeature?.state == FoldingFeature.State.FLAT -> {\r\n            // Fully unfolded — treat as large tablet\r\n            ExpandedLayout()\r\n        }\r\n        else -> {\r\n            // Phone / folded state\r\n            CompactLayout()\r\n        }\r\n    }\r\n}\r\n\r\n// ✅ Tabletop layout — content above, controls below the hinge\r\n@Composable\r\nfun TabletopLayout() {\r\n    Column(Modifier.fillMaxSize()) {\r\n        // Content above hinge\r\n        Box(Modifier.weight(1f).fillMaxWidth()) {\r\n            VideoPlayer()   // or map, camera, media player\r\n        }\r\n        // Controls below hinge — easy thumb reach\r\n        Box(Modifier.weight(0.4f).fillMaxWidth()\r\n            .background(MaterialTheme.colorScheme.surfaceContainerLow)) {\r\n            PlaybackControls()\r\n        }\r\n    }\r\n}\r\n```\r\n\r\n## Rule 6: Content width constraints — never stretch text on large screens\r\n\r\n```kotlin\r\n// ✅ Cap readable content width — typography research: 75 chars max per line\r\n@Composable\r\nfun ReadableContent(content: @Composable ColumnScope.() -> Unit) {\r\n    BoxWithConstraints(Modifier.fillMaxSize()) {\r\n        val maxContentWidth = minOf(maxWidth, 720.dp)  // never wider than 720dp\r\n        Box(Modifier.fillMaxSize(), Alignment.TopCenter) {\r\n            Column(\r\n                Modifier.width(maxContentWidth)\r\n                    .padding(horizontal = Spacing.md)\r\n                    .verticalScroll(rememberScrollState()),\r\n                content = content\r\n            )\r\n        }\r\n    }\r\n}\r\n\r\n// ✅ Adaptive horizontal padding\r\n@Composable\r\nfun WindowSizeClass.contentPadding() = PaddingValues(\r\n    horizontal = when {\r\n        isExpanded -> Spacing.xl    // 32dp on large screen\r\n        isMedium   -> Spacing.lg    // 24dp on tablet\r\n        else       -> Spacing.md    // 16dp on phone\r\n    }\r\n)\r\n```\r\n\r\n## Rule 7: Bottom sheet → side sheet on tablets\r\n\r\n```kotlin\r\n// ✅ Adapt sheet direction to screen width\r\n@Composable\r\nfun AdaptiveSheet(\r\n    isVisible: Boolean,\r\n    onDismiss: () -> Unit,\r\n    windowSizeClass: WindowSizeClass = currentWindowAdaptiveInfo().windowSizeClass,\r\n    content: @Composable () -> Unit\r\n) {\r\n    if (windowSizeClass.isCompact) {\r\n        // Phone: bottom sheet\r\n        if (isVisible) {\r\n            ModalBottomSheet(onDismissRequest = onDismiss) {\r\n                Box(Modifier.navigationBarsPadding()) { content() }\r\n            }\r\n        }\r\n    } else {\r\n        // Tablet/desktop: side sheet from end edge\r\n        AnimatedVisibility(\r\n            visible = isVisible,\r\n            enter = slideInHorizontally(initialOffsetX = { it }),\r\n            exit  = slideOutHorizontally(targetOffsetX = { it })\r\n        ) {\r\n            Box(\r\n                Modifier.fillMaxHeight().width(360.dp)\r\n                    .background(MaterialTheme.colorScheme.surfaceContainerLow)\r\n                    .align(Alignment.CenterEnd)\r\n            ) {\r\n                Column {\r\n                    Row(Modifier.fillMaxWidth().padding(Spacing.md),\r\n                        horizontalArrangement = Arrangement.SpaceBetween,\r\n                        verticalAlignment = Alignment.CenterVertically) {\r\n                        Text(\"Filter\", style = MaterialTheme.typography.titleMedium)\r\n                        IconButton(onDismiss) { Icon(Icons.Default.Close, \"Close\") }\r\n                    }\r\n                    content()\r\n                }\r\n            }\r\n        }\r\n    }\r\n}\r\n```\r\n\r\n## Rule 8: Adaptive dialog — constrained on large screens\r\n\r\n```kotlin\r\n// ✅ Alert dialogs — constrain width on tablets\r\n@Composable\r\nfun AppDialog(\r\n    title: String, body: String, onConfirm: () -> Unit, onDismiss: () -> Unit,\r\n    confirmText: String = \"Confirm\", dismissText: String = \"Cancel\"\r\n) {\r\n    AlertDialog(\r\n        onDismissRequest = onDismiss,\r\n        title = { Text(title) },\r\n        text  = { Text(body, style = MaterialTheme.typography.bodyMedium) },\r\n        modifier = Modifier.widthIn(max = 400.dp),    // never full-width on tablet\r\n        confirmButton = { TextButton(onConfirm) { Text(confirmText) } },\r\n        dismissButton = { TextButton(onDismiss) { Text(dismissText) } }\r\n    )\r\n}\r\n\r\n// ✅ Full-screen dialogs — use Dialog for complex forms on phones, keep them in-place on tablets\r\n@Composable\r\nfun AdaptiveFormDialog(\r\n    isVisible: Boolean, onDismiss: () -> Unit,\r\n    windowSizeClass: WindowSizeClass = currentWindowAdaptiveInfo().windowSizeClass,\r\n    content: @Composable () -> Unit\r\n) {\r\n    if (!isVisible) return\r\n    if (windowSizeClass.isCompact) {\r\n        // Phone: full-screen takeover\r\n        Dialog(onDismissRequest = onDismiss,\r\n            properties = DialogProperties(usePlatformDefaultWidth = false)) {\r\n            Box(Modifier.fillMaxSize().background(MaterialTheme.colorScheme.background)) { content() }\r\n        }\r\n    } else {\r\n        // Tablet: constrained dialog\r\n        Dialog(onDismissRequest = onDismiss) {\r\n            Surface(shape = MaterialTheme.shapes.large, modifier = Modifier.widthIn(max = 560.dp)) { content() }\r\n        }\r\n    }\r\n}\r\n```\r\n\r\n## Rule 9: SupportingPaneScaffold — three-pane layouts\r\n\r\n```kotlin\r\n// ✅ Email/document apps: list + detail + supporting info\r\n@Composable\r\nfun ThreePaneScreen() {\r\n    val navigator = rememberSupportingPaneScaffoldNavigator<String>()\r\n\r\n    SupportingPaneScaffold(\r\n        directive = navigator.scaffoldDirective,\r\n        value     = navigator.scaffoldValue,\r\n        mainPane  = {\r\n            AnimatedPane {\r\n                MainContent(\r\n                    onShowDetails = { navigator.navigateTo(SupportingPaneScaffoldRole.Supporting, it) }\r\n                )\r\n            }\r\n        },\r\n        supportingPane = {\r\n            AnimatedPane {\r\n                SupportingContent(navigator.currentDestination?.content)\r\n            }\r\n        },\r\n        extraPane = {\r\n            AnimatedPane {\r\n                ExtraContent()  // shown only on very large screens (> 1200dp)\r\n            }\r\n        }\r\n    )\r\n}\r\n```\r\n\r\n## Rule 10: Predictive Back — gesture-driven navigation preview\r\n\r\n```kotlin\r\n// ✅ Enable predictive back in AndroidManifest\r\n// <application android:enableOnBackInvokedCallback=\"true\">\r\n\r\n// ✅ SeekableTransitionState for custom predictive back animation\r\n@Composable\r\nfun HomeScreen(navController: NavController) {\r\n    val scale by animateFloatAsState(\r\n        targetValue = 1f,\r\n        animationSpec = spring(stiffness = Spring.StiffnessMedium),\r\n        label = \"screenScale\"\r\n    )\r\n    Box(Modifier.graphicsLayer { scaleX = scale; scaleY = scale }) {\r\n        ScreenContent()\r\n    }\r\n    // NavHost 2.8+ handles predictive back automatically for composable() destinations\r\n}\r\n```\r\n\r\n## Common Mistakes\r\n\r\n❌ Hardcoded `BottomNavigation` — use `NavigationSuiteScaffold`\r\n❌ Single-column layout on tablet — use `ListDetailPaneScaffold` for list+detail\r\n❌ `LazyColumn` with no grid alternative on large screen — use `GridCells.Adaptive`\r\n❌ Full-width text — cap at `720.dp` with `widthIn(max = 720.dp)`\r\n❌ Same `ModalBottomSheet` on tablet — switch to side sheet on medium+\r\n❌ Fixed-size dialog — use `widthIn(max = 400.dp)` always\r\n❌ Ignoring `FoldingFeature` — check `windowPosture.hingeList` for foldables\r\n❌ No `BackHandler` in list-detail — handle back for phone navigation\r\n\r\n## Deep-dive references\r\n\r\n- `references/three-pane-layouts.md` — complex SupportingPaneScaffold patterns\r\n- `references/adaptive-testing.md` — resizable emulator testing guide\r\n- `references/chromebook-support.md` — keyboard/mouse/trackpad support","tags":["adaptive","android","agent","skills","piyushverma0","agent-skills","ai-agent","antigravity","claude-code","codex","cursor","gemini-cli"],"capabilities":["skill","source-piyushverma0","skill-adaptive-ui","topic-agent-skills","topic-ai-agent","topic-android","topic-antigravity","topic-claude-code","topic-codex","topic-cursor","topic-gemini-cli","topic-hilt","topic-jetpack-compose","topic-kotlin","topic-material3"],"categories":["android-agent-skills"],"synonyms":[],"warnings":[],"endpointUrl":"https://skills.sh/piyushverma0/android-agent-skills/adaptive-ui","protocol":"skill","transport":"skills-sh","auth":{"type":"none","details":{"cli":"npx skills add piyushverma0/android-agent-skills","source_repo":"https://github.com/piyushverma0/android-agent-skills","install_from":"skills.sh"}},"qualityScore":"0.454","qualityRationale":"deterministic score 0.45 from registry signals: · indexed on github topic:agent-skills · 8 github stars · SKILL.md body (15,530 chars)","verified":false,"liveness":"unknown","lastLivenessCheck":null,"agentReviews":{"count":0,"score_avg":null,"cost_usd_avg":null,"success_rate":null,"latency_p50_ms":null,"narrative_summary":null,"summary_updated_at":null},"enrichmentModel":"deterministic:skill-github:v1","enrichmentVersion":1,"enrichedAt":"2026-05-18T19:09:08.524Z","embedding":null,"createdAt":"2026-05-18T13:14:47.910Z","updatedAt":"2026-05-18T19:09:08.524Z","lastSeenAt":"2026-05-18T19:09:08.524Z","tsv":"'-840':228,442 '0':215,264 '0.4':691 '1':150,552 '1.1.0':102 '10':62,1043 '1200dp':565,1041 '16dp':773 '18':35 '180.dp':527 '1b':45 '1f':675,1073 '2':317,557,597 '2.8':1088 '24dp':768 '27':4 '3':284,413,416,594 '32dp':762 '360.dp':839 '360dp':551 '4':507,561,591 '400.dp':909,1151 '412dp':556 '5':30,602 '560.dp':993 '6':566,698 '600':227,441 '600dp':81,224,436 '7':777 '720.dp':733,1129,1133 '720dp':737 '75':715 '768dp':560 '8':864 '840dp':84,232,448 '9':996 'access':420 'activ':46 'adapt':2,37,106,110,115,121,127,133,155,508,751,785,865 'adaptive-layout':120 'adaptive-navig':132 'adaptive-ui':1 'adaptiveformdialog':946 'adaptivesheet':793 'adaptivetokens.kt':476 'add':474 'agent':9 'ai':8,32 'alert':872 'alertdialog':895 'align':842 'alignment.center':381 'alignment.centerend':843 'alignment.centervertically':852 'alignment.topcenter':740 'also':492 'altern':1117 'alway':1152 'android':5,43 'androidmanifest':1056 'androidx.compose':139 'androidx.compose.material3.adaptive':108,118,130 'anim':1062 'animatedpan':353,361,1021,1028,1033 'animatedvis':825 'animatefloatasst':1071 'animationspec':1074 'answer':88 'app':1004 'appdialog':880 'appnavhost':221 'arrangement.spacebetween':850 'arrangement.spacedby':536,539 'ask':76 'auth':16 'automat':67,513,1092 'back':396,1045,1054,1061,1091,1166 'background':694,840,977 'backhandl':344,1160 'backstack':298 'badg':212,216 'badgecount':262,283 'bill':29 'bodi':883,903 'book':637 'boolean':795,948 'bottom':778,808 'bottombar':160 'bottomnavig':1099 'bottomnavigationbar':225 'box':379,673,689,738,815,836,975,1080 'boxwithconstraint':727 'breakpoint':415,574 'button':397 'camera':680 'cancel':894 'cap':709,1127 'char':716 'check':493,1155 'chromebook':60 'class':146,246,267,273,279,287 'claud':10 'close':861 'code':11,154,237,570 'codex':12 'color':388 'column':92,458,463,471,517,524,553,558,562,567,572,587,599,600,668,741,844,1104 'columnscop':725 'common':1096 'compact':223,498 'compactlayout':468,656 'complex':933,1175 'compon':159 'compos':170,338,423,425,579,614,665,720,724,754,791,803,878,944,956,1009,1063,1094 'confirm':891 'confirmbutton':916 'confirmtext':889,920 'constrain':867,874,982 'constraint':701 'content':365,659,670,699,711,723,749,750,802,817,862,955,979,994,1031 'contentdescript':205 'contentpad':532 'control':578,661,683 'correct':516 'count':518 'currententri':177,186,197 'currentwindowadaptiveinfo':430,619,800,953 'cursor':13 'custom':1059 'day':36 'deep':1171 'deep-div':1170 'defin':240 'depend':98 'design':19,576 'designcontrolledgrid':581 'desktop':453 'desktop-lik':452 'destin':187,198,1095 'detail':321,329,394,403,409,1006,1112,1164 'detailpan':360 'detect':608 'devic':42,50 'dialog':866,873,929,931,968,983,984,1147 'dialogproperti':972 'direct':348,787,1016 'dismissbutton':921 'dismisstext':892,925 'dive':1172 'dp':229,443 'drawer':166 'driven':1048 'duplic':297 'easi':686 'edg':824 'element':75 'els':203,219,372,467,595,652,771,818,980 'email/document':1003 'emul':1180 'enabl':1052 'end':823 'enter':828 'entri':299 'enum':245 'error':18 'ever':239 'everi':39,41,51,327 'exit':832 'expand':231 'expandedlayout':451,651 'extens':472 'extra':236,569 'extracont':1034 'extrapan':1032 'f':692 'fals':974 'fill':510 'fillmaxwidth':676,693 'filter':854 'fit':531 'fitgenz':31 'fix':14,571,1145 'fixed-s':1144 'fold':612,654 'foldabl':58,603,1158 'foldawarescreen':616 'foldingfeatur':605,627,630,642,1154 'foldingfeature.orientation':634 'foldingfeature.orientation.horizontal':635 'foldingfeature.state.flat':644 'foldingfeature.state.half':632 'form':934 'full':912,927,965,1124 'full-screen':926,964 'full-width':911,1123 'fulli':645 'fun':171,300,339,426,580,615,666,721,755,792,879,945,1010,1064 'gestur':1047 'gesture-driven':1046 'get':479,484,489,502 'golden':69 'graph.findstartdestination':308 'grid':509,1116 'gridcells.adaptive':515,525,1122 'gridcells.fixed':590,593,596 'group':107,117,129,138 'guid':1182 'handl':1089,1165 'happen':66 'hardcod':1098 'hasrout':188,199 'height':494,499 'helper':295,473 'hierarchi':424 'hilt':17 'hing':624,664,672,685 'hinges.firstornull':628 'home':265 'homerout':266 'homescreen':1065 'horizont':745,752,758 'horizontalarrang':535,849 'icon':194,195,252,859 'iconbutton':857 'icons.default.close':860 'icons.filled.home':269 'icons.filled.inbox':281 'icons.filled.person':289 'icons.filled.search':275 'icons.outlined.home':268 'icons.outlined.inbox':280 'icons.outlined.person':288 'icons.outlined.search':274 'id':309,356,359 'ignor':1153 'imagevector':253,256 'in-plac':939 'inbox':277 'inboxrout':278 'inconsist':20 'info':1008 'initialoffsetx':830 'int':260,263 'iscompact':433,505 'isexpand':445,450,760 'ismedium':438,459,766 'isvis':794,811,827,947,959 'it.id':544 'item':184,385,541,542,545,547,582 'itemcard':546 'itemdetailpan':369 'itemid':363,367,370,371 'itemlistpan':354 'itemsscreen':340 'kapt':21 'kclass':250 'keep':937 'key':543 'keyboard/mouse/trackpad':1184 'kotlin':157,326,419,514,607,708,784,871,1002,1051 'ksp':22 'label':208,1078 'labelr':259 'landscap':496 'larg':48,168,373,563,649,706,764,869,1039,1119 'large-screen':47 'launchsingletop':312 'layout':74,116,122,417,658,1001,1105 'lazycolumn':1113 'lazyverticalgrid':523,598 'level':243,293 'librari':103 'like':454 'line':719 'list':324,328,391,400,402,583,1005,1111,1163 'list-detail':1162 'listdetailpanescaffold':318,347,1109 'listdetailpanescaffoldrole.detail':358 'listpan':352 'live':411 'look':79 'maincont':1022 'mainpan':1020 'make':64 'mani':529 'map':679 'master':320 'master-detail':319 'material3':105,114,126,140,143,148 'material3-adaptive':104 'material3-adaptive-layout':113 'material3-adaptive-navigation':125 'material3-window-size-class':142 'material3adaptive':101,112,124,136 'materialtheme.colorscheme.background':978 'materialtheme.colorscheme.onsurfacevariant':389 'materialtheme.colorscheme.surfacecontainerlow':695,841 'materialtheme.shapes.large':989 'materialtheme.typography.bodylarge':387 'materialtheme.typography.bodymedium':905 'materialtheme.typography.titlemedium':856 'max':717,908,992,1132,1150 'maxcontentwidth':730,743 'maxwidth':732 'media':681 'medium':226,1143 'mediumlayout':460 'minof':731 'minsiz':526 'miss':23 'mistak':1097 'modalbottomsheet':812,1135 'modifi':548,906,990 'modifier.fillmaxheight':837 'modifier.fillmaxsize':380,669,728,739,976 'modifier.fillmaxwidth':549,846 'modifier.graphicslayer':1081 'modifier.navigationbarspadding':816 'modifier.weight':674,690 'modifier.width':742 'modifier.widthin':907,991 'must':53 'myapp':172 'myscreen':427 'name':109,119,131,141 'navcontrol':174,222,1066,1067 'navcontroller.currentbackstackentryasstate':179 'navcontroller.navigatetoplevel':192,301 'navhost':336,1087 'navig':128,134,156,294,304,337,342,1013,1049,1169 'navigationdraw':233 'navigationrail':230 'navigationsuiteitem':181 'navigationsuitescaffold':151,180,1101 'navigator.cannavigateback':345 'navigator.currentdestination':364,1030 'navigator.navigateback':346 'navigator.navigateto':357,1024 'navigator.scaffolddirective':349,1017 'navigator.scaffoldvalue':351,1019 'need':238 'never':702,734,910 'noth':377 'null':220,368 'onclick':191 'onconfirm':885,918 'ondismiss':796,814,858,887,897,923,949,970,986 'ondismissrequest':813,896,969,985 'one':90,158 'onitemselect':355 'onshowdetail':1023 'open':633 'pad':744,753,847 'paddingvalu':533,757 'pane':410,1000 'pattern':1177 'per':573,718 'perman':234 'phone':56,162,390,469,497,550,555,653,775,807,936,963,1168 'place':72,941 'placehold':375 'playbackcontrol':696 'player':682 'popupto':307 'postur':621,638 'posture.hingelist':625 'predict':1044,1053,1060,1090 'prevent':296 'preview':1050 'profil':285 'profilerout':286 'properti':971 'r.string.home':270 'r.string.inbox':282 'r.string.profile':290 'r.string.search':276 'rail':163 'reach':688 'readabl':710 'readablecont':722 'reduc':26 'refer':1173 'references/adaptive-testing.md':1178 'references/chromebook-support.md':1183 'references/three-pane-layouts.md':1174 'rememberlistdetailpanescaffoldnavig':343 'remembernavcontrol':175 'rememberscrollst':748 'remembersupportingpanescaffoldnavig':1014 'replac':334 'requir':97,577 'research':714 'resiz':1179 'respond':610 'restorest':314 'return':306,398,960 'rout':183,193,244,302 'route.badgecount':214,218 'route.icon':204 'route.labelres':207,211 'route.routeclass':189,200 'route.routeclass.objectinstance':305 'route.selectedicon':202 'routeclass':249 'row':845 'rule':63,70,149,316,412,506,601,697,776,863,995,1042 'savest':310 'scale':1069,1083,1085 'scalex':1082 'scaley':1084 'screen':40,49,52,169,325,330,374,392,395,511,521,564,707,765,789,870,928,966,1040,1120 'screencont':1086 'screenscal':1079 'search':271 'searchrout':272 'seekabletransitionst':1057 'select':185,378,383,407 'selectedicon':255 'setup':96 'shape':988 'sheet':779,781,786,809,821,1141 'ship':33 'shown':1035 'side':404,406,780,820,1140 'simpl':335 'singl':466,470,1103 'single-column':1102 'size':145,1146 'skill':6 'skill-adaptive-ui' 'slideinhorizont':829 'slideouthorizont':833 'source-piyushverma0' 'spacing.lg':767 'spacing.md':534,746,772,848 'spacing.sm':537,540 'spacing.xl':761 'split':639 'spring':1075 'spring.stiffnessmedium':1077 'standard':554 'state':25,606,613,631,643,655 'stiff':1076 'stretch':91,703 'string':882,884,890,893 'stringr':257 'stringresourc':206,210 'style':386,855,904 'supabas':15 'support':604,1007,1185 'supportingcont':1029 'supportingpan':1027 'supportingpanescaffold':997,1015,1176 'supportingpanescaffoldrole.supporting':1025 'surfac':987 'switch':1138 'tablet':57,165,401,461,559,650,770,783,877,915,943,981,1107,1137 'tablet/desktop':819 'tabletop':636,657 'tabletoplayout':641,667 'takeov':967 'tap':393 'targetoffsetx':834 'targetvalu':1072 'test':1181 'text':209,217,382,704,853,899,901,902,919,924,1126 'textbutton':917,922 'three':457,999 'three-pan':998 'threepanescreen':1011 'thumb':687 'tier':418 'titl':881,898,900 'token':28 'toml':99 'top':242,292 'top-level':241,291 'top/bottom':640 'topic-agent-skills' 'topic-ai-agent' 'topic-android' 'topic-antigravity' 'topic-claude-code' 'topic-codex' 'topic-cursor' 'topic-gemini-cli' 'topic-hilt' 'topic-jetpack-compose' 'topic-kotlin' 'topic-material3' 'toplevelrout':247,303 'toplevelroute.entries.foreach':182 'treat':647 'true':190,201,311,313,315 'two':455,462 'typographi':713 'ui':3,38 'uistat':24 'unfold':646 'unit':726,797,804,886,888,950,957 'updat':408 'use':332,930,1100,1108,1121,1148 'useplatformdefaultwidth':973 'val':173,176,248,251,254,258,261,341,362,428,432,437,444,477,482,487,500,586,617,620,623,626,729,1012,1068 'valu':350,1018 'version':100 'version.ref':111,123,135,147 'verticalalign':851 'verticalarrang':538 'verticalscrol':747 'videoplay':677 'visibl':826 'wider':465,735 'width':82,85,512,522,700,712,790,838,875,913,1125 'widthin':1131,1149 'window':144 'windowheightsizeclass':503 'windowheightsizeclass.compact':504 'windowinfo':618 'windowinfo.windowposture':622 'windowposture.hingelist':1156 'windowsizeclass':137,414,421,429,431,584,585,798,799,801,951,952,954 'windowsizeclass.contentpadding':756 'windowsizeclass.iscompact':478,806,962 'windowsizeclass.isexpanded':488,589 'windowsizeclass.ismedium':483,592 'windowsizeclass.isshortlandscape':501 'windowsizeclass.windowwidthsizeclass':434,439,446 'windowwidthsizeclass':480,485,490 'windowwidthsizeclass.compact':435,481 'windowwidthsizeclass.expanded':447,491 'windowwidthsizeclass.medium':440,486 'work':54 'wrong':95 'zero':153,568 'zero-cod':152","prices":[{"id":"688f29f8-9c82-4263-b80f-d332bf152a40","listingId":"e0b41e4b-017d-43a4-956d-2f2c263a4ced","amountUsd":"0","unit":"free","nativeCurrency":null,"nativeAmount":null,"chain":null,"payTo":null,"paymentMethod":"skill-free","isPrimary":true,"details":{"org":"piyushverma0","category":"android-agent-skills","install_from":"skills.sh"},"createdAt":"2026-05-18T13:14:47.910Z"}],"sources":[{"listingId":"e0b41e4b-017d-43a4-956d-2f2c263a4ced","source":"github","sourceId":"piyushverma0/android-agent-skills/adaptive-ui","sourceUrl":"https://github.com/piyushverma0/android-agent-skills/tree/main/skills/adaptive-ui","isPrimary":false,"firstSeenAt":"2026-05-18T13:14:47.910Z","lastSeenAt":"2026-05-18T19:09:08.524Z"}],"details":{"listingId":"e0b41e4b-017d-43a4-956d-2f2c263a4ced","quickStartSnippet":null,"exampleRequest":null,"exampleResponse":null,"schema":null,"openapiUrl":null,"agentsTxtUrl":null,"citations":[],"useCases":[],"bestFor":[],"notFor":[],"kindDetails":{"org":"piyushverma0","slug":"adaptive-ui","github":{"repo":"piyushverma0/android-agent-skills","stars":8,"topics":["agent-skills","ai-agent","android","antigravity","claude-code","codex","cursor","gemini-cli","hilt","jetpack-compose","kotlin","material3","open-source","skills","supabase"],"license":"mit","html_url":"https://github.com/piyushverma0/android-agent-skills","pushed_at":"2026-04-27T09:15:31Z","description":"27 Android skills for AI agents (Claude Code, Codex, Cursor). Fixes Supabase auth, Hilt errors, design inconsistency, kapt→ksp, missing UiState states. Reduced my token bills 5×. FitGenZ AI shipped in 18 days.","skill_md_sha":"9b1c49e043e47429a8a6cb98a4d731df5defdffd","skill_md_path":"skills/adaptive-ui/SKILL.md","default_branch":"main","skill_tree_url":"https://github.com/piyushverma0/android-agent-skills/tree/main/skills/adaptive-ui"},"layout":"multi","source":"github","category":"android-agent-skills","frontmatter":{},"skills_sh_url":"https://skills.sh/piyushverma0/android-agent-skills/adaptive-ui"},"updatedAt":"2026-05-18T19:09:08.524Z"}}