feat: align landing capsule and remove glass from map ui
This commit is contained in:
@@ -85,6 +85,13 @@
|
||||
backdrop-filter: blur(22px);
|
||||
-webkit-backdrop-filter: blur(22px);
|
||||
}
|
||||
|
||||
/* Map overlays must stay solid (no glass) */
|
||||
.map-chip {
|
||||
background: color-mix(in oklab, var(--color-base-100) 96%, transparent);
|
||||
border: 1px solid color-mix(in oklab, var(--color-base-300) 80%, transparent);
|
||||
box-shadow: 0 10px 24px rgba(15, 23, 42, 0.12);
|
||||
}
|
||||
}
|
||||
|
||||
/* ── Header glass: two-layer Apple-style glassmorphism ── */
|
||||
|
||||
@@ -12,9 +12,9 @@
|
||||
/>
|
||||
|
||||
<!-- Sheet content -->
|
||||
<div class="relative flex w-full max-w-[980px] flex-col overflow-hidden rounded-t-[2rem] border border-white/60 bg-base-100/95 shadow-[0_-24px_70px_rgba(15,23,42,0.3)] backdrop-blur-xl">
|
||||
<div class="relative flex w-full max-w-[980px] flex-col overflow-hidden rounded-t-[2rem] border border-base-300 bg-base-100 shadow-[0_-24px_70px_rgba(15,23,42,0.3)]">
|
||||
<!-- Header with drag handle and close -->
|
||||
<div class="sticky top-0 z-10 border-b border-base-300 bg-base-100/90">
|
||||
<div class="sticky top-0 z-10 border-b border-base-300 bg-base-100">
|
||||
<div class="flex justify-center py-2">
|
||||
<div class="h-1.5 w-12 rounded-full bg-base-content/20" />
|
||||
</div>
|
||||
|
||||
@@ -12,9 +12,9 @@
|
||||
/>
|
||||
|
||||
<!-- Sheet content -->
|
||||
<div class="relative flex-1 bg-black/40 backdrop-blur-xl rounded-t-2xl border-t border-white/20 shadow-2xl overflow-hidden">
|
||||
<div class="relative flex-1 bg-neutral rounded-t-2xl border-t border-neutral/70 shadow-2xl overflow-hidden">
|
||||
<!-- Header with drag handle and close -->
|
||||
<div class="sticky top-0 z-10 bg-black/30 backdrop-blur-md border-b border-white/10">
|
||||
<div class="sticky top-0 z-10 bg-neutral border-b border-white/10">
|
||||
<div class="flex justify-center py-2">
|
||||
<div class="w-12 h-1.5 bg-white/30 rounded-full" />
|
||||
</div>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<div class="flex flex-col h-full">
|
||||
<!-- Header: белое стекло (negative margins to expand beyond parent padding) -->
|
||||
<div class="sticky top-0 z-10 -mx-4 -mt-4 px-4 pt-4 pb-3 rounded-t-xl bg-white/90 backdrop-blur-md border-b border-white/20">
|
||||
<!-- Header: solid panel (negative margins to expand beyond parent padding) -->
|
||||
<div class="sticky top-0 z-10 -mx-4 -mt-4 px-4 pt-4 pb-3 rounded-t-xl bg-base-100 border-b border-base-300">
|
||||
<slot name="header" />
|
||||
</div>
|
||||
|
||||
|
||||
@@ -12,9 +12,9 @@
|
||||
/>
|
||||
|
||||
<!-- Sheet content -->
|
||||
<div class="relative flex w-full max-w-[980px] flex-col overflow-hidden rounded-t-[2rem] border border-white/60 bg-base-100/95 shadow-[0_-24px_70px_rgba(15,23,42,0.3)] backdrop-blur-xl">
|
||||
<div class="relative flex w-full max-w-[980px] flex-col overflow-hidden rounded-t-[2rem] border border-base-300 bg-base-100 shadow-[0_-24px_70px_rgba(15,23,42,0.3)]">
|
||||
<!-- Header with drag handle and close -->
|
||||
<div class="sticky top-0 z-10 border-b border-base-300 bg-base-100/90">
|
||||
<div class="sticky top-0 z-10 border-b border-base-300 bg-base-100">
|
||||
<div class="flex justify-center py-2">
|
||||
<div class="h-1.5 w-12 rounded-full bg-base-content/20" />
|
||||
</div>
|
||||
|
||||
@@ -98,8 +98,10 @@
|
||||
|
||||
<!-- Center: Search input OR Client Area tabs (vertically centered) -->
|
||||
<div
|
||||
class="flex-1 flex flex-col items-center max-w-2xl mx-auto gap-2 transition-all"
|
||||
:class="isHeroLayout ? 'justify-start' : 'justify-center'"
|
||||
class="relative flex-1 flex flex-col items-center mx-auto gap-2 transition-all"
|
||||
:class="[
|
||||
isHeroLayout ? 'w-full max-w-none justify-start' : 'max-w-2xl justify-center'
|
||||
]"
|
||||
:style="centerStyle"
|
||||
>
|
||||
<!-- Hero slot for home page title -->
|
||||
@@ -141,7 +143,11 @@
|
||||
|
||||
<!-- Quote mode: Step-based capsule navigation (like logistics) -->
|
||||
<template v-else-if="catalogMode === 'quote'">
|
||||
<div class="flex items-center w-full rounded-full pill-glass overflow-hidden">
|
||||
<div
|
||||
class="flex items-center rounded-full pill-glass overflow-hidden"
|
||||
:class="searchCapsuleClass"
|
||||
:style="searchCapsuleStyle"
|
||||
>
|
||||
<!-- Product segment -->
|
||||
<NuxtLink
|
||||
:to="localePath('/catalog/product')"
|
||||
@@ -182,7 +188,9 @@
|
||||
<template v-else>
|
||||
<!-- Big pill input -->
|
||||
<div
|
||||
class="flex items-center gap-3 w-full px-5 py-3 rounded-full pill-glass focus-within:ring-2 focus-within:ring-primary/20 transition-all cursor-text"
|
||||
class="flex items-center gap-3 px-5 py-3 rounded-full pill-glass focus-within:ring-2 focus-within:ring-primary/20 transition-all cursor-text"
|
||||
:class="searchCapsuleClass"
|
||||
:style="searchCapsuleStyle"
|
||||
@click="focusInput"
|
||||
>
|
||||
<Icon name="lucide:search" size="22" class="text-primary flex-shrink-0" />
|
||||
@@ -409,9 +417,12 @@ const props = withDefaults(defineProps<{
|
||||
height?: number
|
||||
// Collapse progress for hero layout
|
||||
collapseProgress?: number
|
||||
// Home scroll position for floating center capsule
|
||||
heroScrollY?: number
|
||||
}>(), {
|
||||
height: 100,
|
||||
collapseProgress: 1
|
||||
collapseProgress: 1,
|
||||
heroScrollY: 0
|
||||
})
|
||||
|
||||
defineEmits([
|
||||
@@ -516,6 +527,8 @@ const getTokenIcon = (type: string) => {
|
||||
|
||||
const isHeroLayout = computed(() => props.isHomePage && !props.isClientArea)
|
||||
const topRowHeight = 100
|
||||
const LANDING_CAPSULE_TOP_START = 450
|
||||
const LANDING_CAPSULE_TOP_STOP = 2
|
||||
|
||||
const rowStyle = computed(() => {
|
||||
if (isHeroLayout.value) {
|
||||
@@ -534,6 +547,24 @@ const centerStyle = computed(() => {
|
||||
return { marginTop: `${top}px` }
|
||||
})
|
||||
|
||||
const isFloatingHomeCapsule = computed(() => isHeroLayout.value)
|
||||
|
||||
const landingCapsuleTop = computed(() => {
|
||||
if (!isFloatingHomeCapsule.value) return LANDING_CAPSULE_TOP_STOP
|
||||
const y = Math.max(0, props.heroScrollY || 0)
|
||||
return Math.max(LANDING_CAPSULE_TOP_STOP, LANDING_CAPSULE_TOP_START - y)
|
||||
})
|
||||
|
||||
const searchCapsuleClass = computed(() => {
|
||||
if (!isFloatingHomeCapsule.value) return 'w-full'
|
||||
return 'w-full lg:fixed lg:left-1/2 lg:z-40 lg:w-[min(1120px,calc(100%-1.5rem))] lg:-translate-x-1/2 transition-[top] duration-200 ease-out'
|
||||
})
|
||||
|
||||
const searchCapsuleStyle = computed(() => {
|
||||
if (!isFloatingHomeCapsule.value) return undefined
|
||||
return { top: `${landingCapsuleTop.value}px` }
|
||||
})
|
||||
|
||||
// Use white text on dark backgrounds (collapsed or home page with animation)
|
||||
const useWhiteText = computed(() => props.isCollapsed || props.isHomePage)
|
||||
</script>
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
<!-- View mode loading indicator -->
|
||||
<div
|
||||
v-if="clusterLoading || loading"
|
||||
class="absolute top-[116px] left-1/2 -translate-x-1/2 z-30 flex items-center gap-2 pill-glass rounded-full px-4 py-2"
|
||||
class="absolute top-[116px] left-1/2 -translate-x-1/2 z-30 flex items-center gap-2 map-chip rounded-full px-4 py-2"
|
||||
>
|
||||
<span class="loading loading-spinner loading-sm text-base-content" />
|
||||
<span class="text-base-content text-sm font-medium">{{ $t('common.loading') }}</span>
|
||||
@@ -35,7 +35,7 @@
|
||||
<!-- List button (LEFT, opens panel) - hide when panel is open -->
|
||||
<button
|
||||
v-if="!isPanelOpen"
|
||||
class="absolute top-[116px] left-4 z-20 hidden lg:flex items-center gap-2 pill-glass rounded-full px-3 py-1.5 text-base-content text-sm hover:bg-white/20 transition-colors"
|
||||
class="absolute top-[116px] left-4 z-20 hidden lg:flex items-center gap-2 map-chip rounded-full px-3 py-1.5 text-base-content text-sm hover:bg-base-200 transition-colors"
|
||||
@click="openPanel"
|
||||
>
|
||||
<Icon name="lucide:menu" size="16" />
|
||||
@@ -45,7 +45,7 @@
|
||||
<!-- Filter by bounds checkbox (LEFT, next to panel when open) - only in selection mode -->
|
||||
<label
|
||||
v-if="selectMode !== null"
|
||||
class="absolute top-[116px] left-[calc(1rem+32rem+1rem)] z-20 hidden lg:flex items-center gap-2 pill-glass rounded-full px-3 py-1.5 cursor-pointer text-base-content text-sm hover:bg-white/20 transition-colors"
|
||||
class="absolute top-[116px] left-[calc(1rem+32rem+1rem)] z-20 hidden lg:flex items-center gap-2 map-chip rounded-full px-3 py-1.5 cursor-pointer text-base-content text-sm hover:bg-base-200 transition-colors"
|
||||
>
|
||||
<input
|
||||
type="checkbox"
|
||||
@@ -60,11 +60,11 @@
|
||||
<!-- View toggle (top RIGHT overlay, below header) - hide in info mode or when hideViewToggle -->
|
||||
<div v-if="!isInfoMode && !hideViewToggle" class="absolute top-[116px] right-4 z-20 hidden lg:flex items-center gap-2">
|
||||
<!-- View mode toggle -->
|
||||
<div class="flex gap-1 pill-glass rounded-full p-1">
|
||||
<div class="flex gap-1 map-chip rounded-full p-1">
|
||||
<button
|
||||
v-if="showOffersToggle"
|
||||
class="flex items-center gap-2 px-3 py-1.5 rounded-full text-sm font-bold transition-colors"
|
||||
:class="mapViewMode === 'offers' ? 'bg-white/20 text-base-content' : 'text-base-content/70 hover:text-base-content hover:bg-white/10'"
|
||||
:class="mapViewMode === 'offers' ? 'bg-base-300 text-base-content' : 'text-base-content/70 hover:text-base-content hover:bg-base-200'"
|
||||
@click="setMapViewMode('offers')"
|
||||
>
|
||||
<span class="w-5 h-5 rounded-full flex items-center justify-center" style="background-color: #f97316">
|
||||
@@ -75,7 +75,7 @@
|
||||
<button
|
||||
v-if="showHubsToggle"
|
||||
class="flex items-center gap-2 px-3 py-1.5 rounded-full text-sm font-bold transition-colors"
|
||||
:class="mapViewMode === 'hubs' ? 'bg-white/20 text-base-content' : 'text-base-content/70 hover:text-base-content hover:bg-white/10'"
|
||||
:class="mapViewMode === 'hubs' ? 'bg-base-300 text-base-content' : 'text-base-content/70 hover:text-base-content hover:bg-base-200'"
|
||||
@click="setMapViewMode('hubs')"
|
||||
>
|
||||
<span class="w-5 h-5 rounded-full flex items-center justify-center" style="background-color: #22c55e">
|
||||
@@ -86,7 +86,7 @@
|
||||
<button
|
||||
v-if="showSuppliersToggle"
|
||||
class="flex items-center gap-2 px-3 py-1.5 rounded-full text-sm font-bold transition-colors"
|
||||
:class="mapViewMode === 'suppliers' ? 'bg-white/20 text-base-content' : 'text-base-content/70 hover:text-base-content hover:bg-white/10'"
|
||||
:class="mapViewMode === 'suppliers' ? 'bg-base-300 text-base-content' : 'text-base-content/70 hover:text-base-content hover:bg-base-200'"
|
||||
@click="setMapViewMode('suppliers')"
|
||||
>
|
||||
<span class="w-5 h-5 rounded-full flex items-center justify-center" style="background-color: #3b82f6">
|
||||
@@ -104,7 +104,7 @@
|
||||
class="absolute top-[116px] left-4 bottom-4 z-30 max-w-[calc(100vw-2rem)] hidden lg:block"
|
||||
:class="panelWidth"
|
||||
>
|
||||
<div class="bg-white/90 backdrop-blur-[14px] border border-white/50 rounded-[1.1rem] shadow-2xl h-full flex flex-col text-base-content">
|
||||
<div class="bg-neutral text-neutral-content border border-neutral/70 rounded-[1.1rem] shadow-2xl h-full flex flex-col">
|
||||
<slot name="panel" />
|
||||
</div>
|
||||
</div>
|
||||
@@ -116,7 +116,7 @@
|
||||
<div class="flex justify-between px-4 mb-2">
|
||||
<!-- List button (mobile) -->
|
||||
<button
|
||||
class="flex items-center gap-2 pill-glass rounded-full px-3 py-2 text-base-content text-sm font-medium"
|
||||
class="flex items-center gap-2 map-chip rounded-full px-3 py-2 text-base-content text-sm font-medium"
|
||||
@click="openPanel"
|
||||
>
|
||||
<Icon name="lucide:menu" size="16" />
|
||||
@@ -124,11 +124,11 @@
|
||||
</button>
|
||||
|
||||
<!-- Mobile view toggle - hide in info mode or when hideViewToggle -->
|
||||
<div v-if="!isInfoMode && !hideViewToggle" class="flex gap-1 pill-glass rounded-full p-1">
|
||||
<div v-if="!isInfoMode && !hideViewToggle" class="flex gap-1 map-chip rounded-full p-1">
|
||||
<button
|
||||
v-if="showOffersToggle"
|
||||
class="flex items-center justify-center w-8 h-8 rounded-full transition-colors"
|
||||
:class="mapViewMode === 'offers' ? 'bg-white/20' : 'hover:bg-white/10'"
|
||||
:class="mapViewMode === 'offers' ? 'bg-base-300' : 'hover:bg-base-200'"
|
||||
@click="setMapViewMode('offers')"
|
||||
>
|
||||
<span class="w-5 h-5 rounded-full flex items-center justify-center" style="background-color: #f97316">
|
||||
@@ -138,7 +138,7 @@
|
||||
<button
|
||||
v-if="showHubsToggle"
|
||||
class="flex items-center justify-center w-8 h-8 rounded-full transition-colors"
|
||||
:class="mapViewMode === 'hubs' ? 'bg-white/20' : 'hover:bg-white/10'"
|
||||
:class="mapViewMode === 'hubs' ? 'bg-base-300' : 'hover:bg-base-200'"
|
||||
@click="setMapViewMode('hubs')"
|
||||
>
|
||||
<span class="w-5 h-5 rounded-full flex items-center justify-center" style="background-color: #22c55e">
|
||||
@@ -148,7 +148,7 @@
|
||||
<button
|
||||
v-if="showSuppliersToggle"
|
||||
class="flex items-center justify-center w-8 h-8 rounded-full transition-colors"
|
||||
:class="mapViewMode === 'suppliers' ? 'bg-white/20' : 'hover:bg-white/10'"
|
||||
:class="mapViewMode === 'suppliers' ? 'bg-base-300' : 'hover:bg-base-200'"
|
||||
@click="setMapViewMode('suppliers')"
|
||||
>
|
||||
<span class="w-5 h-5 rounded-full flex items-center justify-center" style="background-color: #3b82f6">
|
||||
@@ -162,7 +162,7 @@
|
||||
<Transition name="slide-up">
|
||||
<div
|
||||
v-if="isPanelOpen"
|
||||
class="bg-white rounded-t-3xl shadow-[0_-8px_40px_rgba(0,0,0,0.12)] transition-all duration-300 text-base-content h-[60vh]"
|
||||
class="bg-neutral text-neutral-content rounded-t-3xl border-t border-neutral/70 shadow-[0_-8px_40px_rgba(0,0,0,0.35)] transition-all duration-300 h-[60vh]"
|
||||
>
|
||||
<!-- Drag handle / close -->
|
||||
<div
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
class="relative z-10"
|
||||
:height="isHomePage ? heroHeight : 100"
|
||||
:collapse-progress="isHomePage ? collapseProgress : 1"
|
||||
:hero-scroll-y="isHomePage ? heroScrollY : 0"
|
||||
:session-checked="sessionChecked"
|
||||
:logged-in="isLoggedIn"
|
||||
:user-avatar-svg="userAvatarSvg"
|
||||
@@ -126,6 +127,7 @@ const { headerOffset, isCollapsed } = useScrollCollapse(100)
|
||||
|
||||
// Hero scroll for home page
|
||||
const {
|
||||
scrollY: heroScrollY,
|
||||
heroHeight,
|
||||
heroBaseHeight,
|
||||
collapseProgress,
|
||||
@@ -358,4 +360,3 @@ const onSearch = () => {
|
||||
searchTrigger.value++
|
||||
}
|
||||
</script>
|
||||
|
||||
|
||||
@@ -15,14 +15,14 @@
|
||||
<div class="fixed inset-x-0 bottom-0 z-50 flex justify-center px-3 md:px-4" style="height: 72vh">
|
||||
<div class="absolute inset-0 -top-[32vh] bg-gradient-to-t from-black/45 via-black/20 to-transparent" />
|
||||
<!-- Sheet -->
|
||||
<div class="relative flex w-full max-w-[980px] flex-col overflow-hidden rounded-t-[2rem] border border-white/60 bg-base-100/95 shadow-[0_-24px_70px_rgba(15,23,42,0.3)] backdrop-blur-xl">
|
||||
<div class="relative flex w-full max-w-[980px] flex-col overflow-hidden rounded-t-[2rem] border border-base-300 bg-base-100 shadow-[0_-24px_70px_rgba(15,23,42,0.3)]">
|
||||
<!-- Drag handle -->
|
||||
<div class="flex justify-center py-2">
|
||||
<div class="h-1.5 w-12 rounded-full bg-base-content/20" />
|
||||
</div>
|
||||
|
||||
<!-- Header -->
|
||||
<div class="border-b border-base-300 bg-base-100/90 px-6 pb-4">
|
||||
<div class="border-b border-base-300 bg-base-100 px-6 pb-4">
|
||||
<!-- Back button -->
|
||||
<NuxtLink :to="localePath('/clientarea/orders')" class="mb-3 inline-flex items-center gap-1 text-sm text-base-content/60 hover:text-base-content">
|
||||
<Icon name="lucide:arrow-left" size="16" />
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
<!-- Bottom Sheet -->
|
||||
<div class="fixed inset-x-0 bottom-0 z-50 flex flex-col" style="height: 70vh">
|
||||
<!-- Glass sheet -->
|
||||
<div class="relative flex-1 bg-black/40 backdrop-blur-xl rounded-t-2xl border-t border-white/20 shadow-2xl overflow-hidden">
|
||||
<div class="relative flex-1 bg-neutral rounded-t-2xl border-t border-neutral/70 shadow-2xl overflow-hidden">
|
||||
<!-- Drag handle -->
|
||||
<div class="flex justify-center py-2">
|
||||
<div class="w-12 h-1.5 bg-white/30 rounded-full" />
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
<!-- Bottom Sheet -->
|
||||
<div class="fixed inset-x-0 bottom-0 z-50 flex flex-col" style="height: 70vh">
|
||||
<!-- Glass sheet -->
|
||||
<div class="relative flex-1 bg-black/40 backdrop-blur-xl rounded-t-2xl border-t border-white/20 shadow-2xl overflow-hidden">
|
||||
<div class="relative flex-1 bg-neutral rounded-t-2xl border-t border-neutral/70 shadow-2xl overflow-hidden">
|
||||
<!-- Drag handle -->
|
||||
<div class="flex justify-center py-2">
|
||||
<div class="w-12 h-1.5 bg-white/30 rounded-full" />
|
||||
|
||||
Reference in New Issue
Block a user