Back to Components

Motion

Icons move only to communicate state. The vocabulary is deliberately small: 200–300ms, positional, and every transition is killed under prefers-reduced-motion.

  • Menu → XThe header menu button morphs while the drawer is open. The drawer slides under the header (z-index below it, top padding clearing it) so the X stays visible and tappable — morphing to an X you can’t see or tap is meaningless. The SVG is inlined in chrome.js — paths inside a <use> shadow tree can’t be targeted by CSS, so this is the one sanctioned exception to the sprite.
  • Tab fillThe active tab swaps its outline icon for the filled Tabler partner (icon-home-fill, icon-document-fill, icon-book-fill), iOS-style. .icon-fill overrides the stroke look of .ui-icon because filled glyphs are solid shapes.
  • Highlight slideTapping a tab swaps the page without a document navigation — site.js intercepts same-origin tab links, fetches the page, and swaps <main> in place while the tab bar stays mounted as the same element. The highlight pill glides the instant --active-index moves (.28s live ::before transition); the URL updates via history.pushState and the back button works via popstate. Neither the animation nor the load waits for the other — both start on tap. Feedback starts on pointerdown and navigation commits on click. Full interaction contract on the dock page.
  • Copy → checkThe copy button morphs on success — site.js toggles .copied and flips the label to “Copied” for 1.8 seconds. The icons scale and rotate (pivoting on transform-box: fill-box) so the morph reads as a morph, not a straight swap. No separate toast: the button is the feedback, and Android already shows its own native confirmation — a second toast just overlaps it.
  • Drawer staggerDrawer links slide in with a 40ms stagger, wrapped in prefers-reduced-motion: no-preference.
  • Dock positionbottom: calc(10px + env(safe-area-inset-bottom, 0px)), with viewport-fit=cover enabled on Android by chrome.js before first paint. The inset is evaluated against the live viewport, so the dock tracks Chrome's retracting toolbar with pure CSS. Full saga — dead ends included — on the dock page.