archy/.claude/plans/reflective-meandering-castle.md
Dorian 11cee9dc70 fix: resolve content clipping on mobile by moving tab padding to scroll container
Moves dynamic pt-20/pt-40 padding from perspective-container-wrapper (which
shrank the content area) to the inner scroll container via computed style.
Removes spacer divs in CloudFolder, AppDetails, MarketplaceAppDetails.
Reduces excessive bottom padding in Marketplace. Hides Cloud/Network tabs
in CloudFolder detail view. Teleports mobile back buttons to body to escape
CSS transform containing block.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-05 10:14:10 +00:00

76 lines
3.1 KiB
Markdown

# Fix Content Clipping + Hide Network Tabs in CloudFolder
## Context
Content clips/cuts off before reaching the bottom across CloudFolder, Marketplace, AppDetails — both desktop and mobile. Fixed UI elements (toolbars, search) must stay sticky while scrollable content extends to the tab bar (mobile) or viewport bottom (desktop). Also: hide Cloud/Network switcher on mobile in CloudFolder detail view.
## Root Cause
`.perspective-container-wrapper` has `height: 100%` + `overflow: hidden` + dynamic `pt-20`/`pt-40`. With `box-sizing: border-box`, the padding shrinks the content area by 80-160px on mobile.
```
<main flex-1 overflow-hidden pb-20> ← reserves tab bar space (correct)
.perspective-container-wrapper h-100% pt-20 ← padding SHRINKS content area (BUG)
.perspective-container h-100% overflow-hidden
.view-wrapper absolute inset-0
content div overflow-y-auto h-full ← scroll viewport 80-160px too small
```
## Solution: Move padding from wrapper to scroll container
### File 1: `neode-ui/src/views/Dashboard.vue` [DONE]
**A. Add computed** (~line 440):
```ts
const mobileTabPaddingTop = computed(() => {
if (typeof window === 'undefined' || window.innerWidth >= 768) return 0
if (showAppsTabs.value && showNetworkTabs.value) return 160
if (showAppsTabs.value || showNetworkTabs.value) return 80
return 0
})
```
**B. Remove padding from wrapper** (line 258):
Remove `'pt-40': showAppsTabs && showNetworkTabs, 'pt-20': showAppsTabs !== showNetworkTabs` from `:class`.
**C. Apply offset to content div instead** (lines 269-277):
```html
<div v-else
:class="['px-4 pt-4 md:pt-8 md:px-8 overflow-y-auto h-full',
needsMobileBackButtonSpace
? 'pb-[calc(var(--mobile-tab-bar-height,_72px)+96px)] md:pb-8'
: 'pb-4 md:pb-8'
]"
:style="mobileTabPaddingTop ? { paddingTop: (mobileTabPaddingTop + 16) + 'px' } : undefined"
>
```
- When mobile tabs showing: `:style` overrides `pt-4` with dynamic value
- When no tabs (or desktop): `:style` is undefined, Tailwind `pt-4 md:pt-8` applies
- Bottom padding reduced from `pb-28 md:pb-24` to `pb-4 md:pb-8` (main's `pb-20` already handles tab bar)
**D. Hide Cloud/Network tabs in CloudFolder** (line 451):
```ts
if (route.name === 'cloud-folder') return false
```
### File 2: `neode-ui/src/views/CloudFolder.vue` [DONE]
Delete spacer div at line 156.
### File 3: `neode-ui/src/views/AppDetails.vue` [DONE]
Delete spacer div at line 377.
### File 4: `neode-ui/src/views/MarketplaceAppDetails.vue` [DONE]
Delete spacer div at line 324.
### File 5: `neode-ui/src/views/Marketplace.vue` [DONE]
Change `pb-48``pb-4` on line 121.
## Safety
- 3D transitions preserved: `overflow: hidden` stays on wrapper + perspective-container
- Chat view unaffected: has its own branch bypassing the content div
- Desktop unaffected: `mobileTabPaddingTop` returns 0
- Back button space preserved: `needsMobileBackButtonSpace` still adds extra bottom padding
## Verification [DONE]
1. `cd neode-ui && npm run build`
2. `./scripts/deploy-to-target.sh --live`
3. Test all views on mobile + desktop: CloudFolder, Marketplace, AppDetails, Chat, Home, page transitions