YouBothAgent▾
You — Business rules and flows you own. Read these yourself.
Both — Know the idea; your agent follows the details.
Agent — Conventions and references your agent follows. Look up as needed.

Interface▾


Observability▾transition in .config(). The mobile app shell then animates the change the way a native app does./chat is 1, /chat/[chatId] is 2.stack, bottomUp, fade, scaleOut and none.stack and bottomUp come with a real back gesture.transition out and the platform and route depth pick one for you:gesture to the platform default unless the page has a reason not to. iOS turns it on below the root; Android and the web leave it off, as their users expect.gesture written anywhere in the layout chain is used as-is.transition is none gets false, because there is nothing for the drag to move.true on iOS at route depth 2 or more, false everywhere else.stack touch stays pending until it travels 8px, then locks to drag or scroll by whichever axis moved clearly more (1.25×).

gesture: true does nothing on a fade, scaleOut or none page. Those transitions attach no drag handler at all..config() object sets the whole page frame: animation, gesture, reserved space and caching. Write it on a layout and every route under it inherits it.stack and bottomUp transitions.true means 48px, false or unset means 0.true."top" or "bottom" keeps one side only.none reserves nothing.safeArea object merges key by key.none, no gesture and cache: true, so tabs switch instantly.stack transition stays live for a swipe back, so bind a camera, a poll or a key handler with usePageFocusEffect from akanjs/webkit; usePageActivity() says whether the page is current, prev, pending or hidden. Only the current page offers its tools and state to the in-page agent.cache route stays one page for the whole session.topInset, in px.bottomInset, in px.h-(--akan-bottom-inset) sizes a bar to exactly the space the page reserved.bottomInset in .config().Layout.BottomInset marked keyboardSticky. Akan moves it into the keyboard accessory layer for you.contentAnchor="bottom", covered in the next section.bottomInset in .config(), BottomInset uses that height; without it, it measures its own content.h-(--akan-bottom-inset), so the bar and the reserved space never disagree.useCsr().frameLayout.keyboard carries three flags next to the height:keyboardSticky slot; when false, the keyboard layer is hidden.frozen is not set; branch on this, not on the height alone.contentAnchor="bottom": it keeps the scroll position's distance from the bottom while the viewport resizes, the way a messenger does.BottomInset follows the native keyboard animation, and the messages keep their distance from the composer.BottomInset is an ordinary Zone with a store-driven field:keyboardSticky moves the BottomInset into the keyboard accessory layer so it follows the keyboard.contentAnchor="bottom" keeps the bottom distance while the viewport resizes. bottom is the only value, and it works only together with keyboardSticky..akan-page-content, so document.querySelector can pick the wrong one; closest() finds this page's.<ScrollToBottomOnMount /> renders a hidden marker and nothing else.

contentAnchor is a BottomInset option, not a .config() option. Ordinary forms keep the default keyboard behaviour; only messenger-style screens opt in, locally.