feat(ui): viewport-fit, safe-area helpers, smoother nav drawer (LC-199) #251
Loading…
Reference in a new issue
No description provided.
Delete branch "feat/lc-199-responsive"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
LC-199 mobile polish, slice 1. The remaining items (44px touch-target audit, swipe-to-close on the drawer, responsive admin tables wrap, full-screen modals at phone widths) stay open under LC-199.
What's shipping
viewport-fit=cover, base.html. Lets the layout extend behind the iOS notch / home indicator. Without this,
env(safe-area-inset-*)returns 0 even on a cutout device, so the helper classes below would be no-ops everywhere.Three safe-area helpers, main.css, all wrapped in
max(...)so the existing visual padding is preserved when the inset is 0 (desktop, Android without nav-bar inset, any non-cutout device):.lc-pb-safefor form / bar bottom padding (max(0.5rem, env(safe-area-inset-bottom))).lc-px-safefor fullscreen content side padding.lc-bottom-safefor fixed-positioned bars anchored to bottomSmoother nav drawer, main.css + layout.html. Mobile drawer was a binary
hidden/flextoggle; now slides in/out ontransform: translateX(0/-100%)with a 200ms ease-out transition, and the backdrop fades. Keyed offdata-open="true"/"false"instead of class soup. The CSS is@media (max-width: 767px)only so desktop stays exactly as it was. The universalprefers-reduced-motion: reducereset from LC-196 already short-circuits both transitions to ~0ms, so no extra guard.Adopted:
room/composer.htmlform:p-2->px-2 pt-2 lc-pb-safe. iPhone message bar now clears the home indicator.layout.htmloutbox banner:bottom-3->lc-bottom-safe.Implementation notes worth flagging
void p.offsetWidthbetween removinghiddenand settingdata-open=true. Without that reflow, the browser would coalesce both DOM mutations into the same frame and the transition wouldn't have a starting state to interpolate from; the panel would snap in instead of sliding.setTimeout(..., 220ms)before re-applyinghidden. The 220ms = 200ms transition + 20ms margin. The guard inside the timeout re-checksdata-open === 'false'so a fast open-close-open sequence doesn't accidentally hide an already-reopened drawer.Not in this PR (still open under LC-199)
<table class="w-full">and overflow horizontally below 540ish px. Wrap each in<div class="overflow-x-auto">..modal-panelisw-full max-w-md; on phone < 28rem viewports it's effectively full-width withp-4outer padding, so this is cosmetic - dropping the outerp-4on phone would make modals fully flush.Tests
just test green (modulo the documented
routes_uploadsconcurrent-binary flake; passes 12/12 isolated). just test-saas green.🤖 Generated with Claude Code