Extend Infrastructure hero banner to the top, overlapping the top bar
Moves the hero rendering to the layout level so the banner shows the full golden arch and sky behind the page title, search bar, and sub-tabs row. TopBar and the search input backgrounds are now transparent so the banner reads through cleanly.
This commit is contained in:
parent
2c87c32fd7
commit
54b7aa1e32
3 changed files with 73 additions and 68 deletions
36
src/App.tsx
36
src/App.tsx
|
|
@ -1,5 +1,5 @@
|
|||
import { useState } from 'react'
|
||||
import { Routes, Route } from 'react-router-dom'
|
||||
import { Routes, Route, useLocation } from 'react-router-dom'
|
||||
import Sidebar from './components/Sidebar'
|
||||
import TopBar from './components/TopBar'
|
||||
import Glance from './pages/Glance'
|
||||
|
|
@ -8,6 +8,8 @@ import Infrastructure from './pages/Infrastructure'
|
|||
function App() {
|
||||
const [sidebarCollapsed, setSidebarCollapsed] = useState(false)
|
||||
const sidebarWidth = sidebarCollapsed ? 64 : 200
|
||||
const location = useLocation()
|
||||
const showHero = location.pathname === '/infrastructure'
|
||||
|
||||
return (
|
||||
<div className="min-h-screen w-screen overflow-hidden bg-page">
|
||||
|
|
@ -17,14 +19,38 @@ function App() {
|
|||
/>
|
||||
|
||||
<main
|
||||
className="h-screen overflow-hidden"
|
||||
className="relative h-screen overflow-hidden"
|
||||
style={{ marginLeft: `${sidebarWidth}px`, width: `calc(100vw - ${sidebarWidth}px)` }}
|
||||
>
|
||||
<TopBar />
|
||||
{showHero && (
|
||||
<div className="pointer-events-none absolute left-0 right-0 top-0" style={{ height: '300px', zIndex: 0 }}>
|
||||
<img
|
||||
src="/archnest-hero-banner.png"
|
||||
alt=""
|
||||
className="absolute inset-0 h-full w-full"
|
||||
style={{
|
||||
objectFit: 'cover',
|
||||
objectPosition: 'center 5%',
|
||||
maskImage: 'linear-gradient(to bottom, black 0%, black 55%, transparent 100%)',
|
||||
WebkitMaskImage: 'linear-gradient(to bottom, black 0%, black 55%, transparent 100%)',
|
||||
}}
|
||||
/>
|
||||
<div
|
||||
className="absolute inset-0"
|
||||
style={{
|
||||
background: 'radial-gradient(ellipse 70% 100% at center, transparent 40%, var(--color-page) 100%)',
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div className="relative" style={{ zIndex: 1 }}>
|
||||
<TopBar />
|
||||
</div>
|
||||
|
||||
<section
|
||||
className="flex w-full flex-col overflow-hidden"
|
||||
style={{ height: 'calc(100vh - 56px)', scrollbarWidth: 'none', padding: '16px 24px 24px 24px', gap: '20px' }}
|
||||
className="relative flex w-full flex-col overflow-hidden"
|
||||
style={{ height: 'calc(100vh - 56px)', scrollbarWidth: 'none', padding: '16px 24px 24px 24px', gap: '20px', zIndex: 1 }}
|
||||
>
|
||||
<Routes>
|
||||
<Route path="/" element={<Glance />} />
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ export default function TopBar() {
|
|||
}, [])
|
||||
|
||||
return (
|
||||
<header className="h-14 flex items-center px-6 bg-page sticky top-0 z-40">
|
||||
<header className="h-14 flex items-center px-6 sticky top-0 z-40">
|
||||
{/* Page Title — pushed away from sidebar edge */}
|
||||
<h1 className="text-[18px] font-bold uppercase tracking-wide" style={{ color: '#C8A434', marginLeft: '20px' }}>
|
||||
{title}
|
||||
|
|
@ -41,8 +41,8 @@ export default function TopBar() {
|
|||
<input
|
||||
type="text"
|
||||
placeholder="Search resources..."
|
||||
className="w-[300px] h-8 rounded-full bg-card border border-border text-[12px] text-text-primary placeholder:text-text-secondary focus:outline-none focus:border-gold transition-colors"
|
||||
style={{ paddingLeft: '36px', paddingRight: '16px' }}
|
||||
className="w-[300px] h-8 rounded-full border border-border text-[12px] text-text-primary placeholder:text-text-secondary focus:outline-none focus:border-gold transition-colors"
|
||||
style={{ paddingLeft: '36px', paddingRight: '16px', backgroundColor: 'rgba(255,255,255,0.04)', backdropFilter: 'blur(6px)' }}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -117,67 +117,46 @@ export default function Infrastructure() {
|
|||
|
||||
return (
|
||||
<>
|
||||
{/* Hero banner — faded seamlessly into the page background, no hard edges */}
|
||||
<div className="relative w-full shrink-0 overflow-hidden" style={{ height: '140px', margin: '-16px -24px 0 -24px' }}>
|
||||
<img
|
||||
src="/archnest-hero-banner.png"
|
||||
alt=""
|
||||
className="absolute inset-0 h-full w-full"
|
||||
style={{
|
||||
objectFit: 'cover',
|
||||
objectPosition: 'center 30%',
|
||||
maskImage: 'linear-gradient(to bottom, transparent 0%, black 25%, black 55%, transparent 100%)',
|
||||
WebkitMaskImage: 'linear-gradient(to bottom, transparent 0%, black 25%, black 55%, transparent 100%)',
|
||||
}}
|
||||
/>
|
||||
<div
|
||||
className="pointer-events-none absolute inset-0"
|
||||
style={{
|
||||
background: 'radial-gradient(ellipse 70% 100% at center, transparent 40%, var(--color-page) 100%)',
|
||||
}}
|
||||
/>
|
||||
|
||||
{/* Sub-tabs + Add Resource, overlaid on the banner */}
|
||||
<div className="absolute bottom-0 left-0 right-0 z-10 flex items-center justify-between" style={{ padding: '0 24px 12px 24px' }}>
|
||||
<div className="flex items-center gap-1 overflow-x-auto" style={{ scrollbarWidth: 'none' }}>
|
||||
{subTabs.map((tab) => {
|
||||
const active = tab === activeTab
|
||||
return (
|
||||
<button
|
||||
key={tab}
|
||||
onClick={() => setActiveTab(tab)}
|
||||
className="cursor-pointer bg-transparent border-none transition-colors whitespace-nowrap"
|
||||
style={{
|
||||
fontSize: '12px',
|
||||
fontWeight: 500,
|
||||
padding: '8px 14px',
|
||||
borderRadius: '8px',
|
||||
color: active ? '#C8A434' : '#7A7D85',
|
||||
backgroundColor: active ? 'rgba(200,164,52,0.1)' : 'transparent',
|
||||
}}
|
||||
>
|
||||
{tab}
|
||||
</button>
|
||||
)
|
||||
})}
|
||||
</div>
|
||||
<button
|
||||
className="flex items-center gap-2 cursor-pointer transition-colors whitespace-nowrap"
|
||||
style={{
|
||||
fontSize: '12px',
|
||||
fontWeight: 600,
|
||||
color: '#0A0B0D',
|
||||
backgroundColor: '#C8A434',
|
||||
border: 'none',
|
||||
borderRadius: '8px',
|
||||
padding: '9px 16px',
|
||||
boxShadow: '0 0 14px rgba(200,164,52,0.2)',
|
||||
}}
|
||||
>
|
||||
<Plus size={14} />
|
||||
Add Resource
|
||||
</button>
|
||||
{/* Sub-tabs + Add Resource — hero banner is rendered at the layout level behind this */}
|
||||
<div className="flex items-center justify-between shrink-0">
|
||||
<div className="flex items-center gap-1 overflow-x-auto" style={{ scrollbarWidth: 'none' }}>
|
||||
{subTabs.map((tab) => {
|
||||
const active = tab === activeTab
|
||||
return (
|
||||
<button
|
||||
key={tab}
|
||||
onClick={() => setActiveTab(tab)}
|
||||
className="cursor-pointer bg-transparent border-none transition-colors whitespace-nowrap"
|
||||
style={{
|
||||
fontSize: '12px',
|
||||
fontWeight: 500,
|
||||
padding: '8px 14px',
|
||||
borderRadius: '8px',
|
||||
color: active ? '#C8A434' : '#7A7D85',
|
||||
backgroundColor: active ? 'rgba(200,164,52,0.1)' : 'transparent',
|
||||
}}
|
||||
>
|
||||
{tab}
|
||||
</button>
|
||||
)
|
||||
})}
|
||||
</div>
|
||||
<button
|
||||
className="flex items-center gap-2 cursor-pointer transition-colors whitespace-nowrap"
|
||||
style={{
|
||||
fontSize: '12px',
|
||||
fontWeight: 600,
|
||||
color: '#0A0B0D',
|
||||
backgroundColor: '#C8A434',
|
||||
border: 'none',
|
||||
borderRadius: '8px',
|
||||
padding: '9px 16px',
|
||||
boxShadow: '0 0 14px rgba(200,164,52,0.2)',
|
||||
}}
|
||||
>
|
||||
<Plus size={14} />
|
||||
Add Resource
|
||||
</button>
|
||||
</div>
|
||||
|
||||
{/* Status Cards */}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue