754 lines
31 KiB
JavaScript
754 lines
31 KiB
JavaScript
// ============================================================
|
||
// 4 modern SaaS nav layouts. Each artboard is a full 1440×900
|
||
// app/marketing chrome with the nav as the focal point and just
|
||
// enough body content to read context. Original brand "Lattice
|
||
// Studio" used throughout so the navs feel like one product
|
||
// family — the variable is the nav pattern itself.
|
||
// ============================================================
|
||
|
||
// Generic placeholder block
|
||
const NavImgSlot = ({ label, h = 200, tone = "light" }) => {
|
||
const p = tone === "dark"
|
||
? { bg: "#1a1a1f", stripe: "#222229", ink: "#7a7a85" }
|
||
: { bg: "#f3f3f0", stripe: "#e7e7e3", ink: "#7a7a72" };
|
||
return (
|
||
<div style={{
|
||
width: "100%", height: h, position: "relative",
|
||
backgroundImage: `repeating-linear-gradient(135deg, ${p.bg} 0 14px, ${p.stripe} 14px 15px)`,
|
||
display: "flex", alignItems: "center", justifyContent: "center",
|
||
}}>
|
||
<span style={{
|
||
fontFamily: "ui-monospace, 'SF Mono', Menlo, monospace",
|
||
fontSize: 10, letterSpacing: "0.1em", textTransform: "uppercase",
|
||
color: p.ink, padding: "3px 8px",
|
||
border: `1px solid ${p.ink}40`, background: `${p.bg}d0`,
|
||
}}>{label}</span>
|
||
</div>
|
||
);
|
||
};
|
||
|
||
// Tiny stroke icon helper — single line so it doesn't bloat the file
|
||
const I = ({ d, size = 16, sw = 1.6 }) => (
|
||
<svg width={size} height={size} viewBox="0 0 24 24" fill="none"
|
||
stroke="currentColor" strokeWidth={sw}
|
||
strokeLinecap="round" strokeLinejoin="round">{d}</svg>
|
||
);
|
||
// Common path sets, kept terse
|
||
const Paths = {
|
||
search: <><circle cx="11" cy="11" r="7"/><path d="m20 20-3-3"/></>,
|
||
bell: <><path d="M6 8a6 6 0 0 1 12 0c0 7 3 9 3 9H3s3-2 3-9"/><path d="M10 21a2 2 0 0 0 4 0"/></>,
|
||
cmd: <path d="M9 3a3 3 0 0 0-3 3v3H3M15 3a3 3 0 0 1 3 3v3h3M9 21a3 3 0 0 1-3-3v-3H3M15 21a3 3 0 0 0 3-3v-3h3M9 9h6v6H9z"/>,
|
||
home: <><path d="m3 12 9-9 9 9"/><path d="M5 10v10h14V10"/></>,
|
||
inbox: <><path d="M22 12h-6l-2 3h-4l-2-3H2"/><path d="M5 5h14l3 7v7H2v-7z"/></>,
|
||
people: <><circle cx="9" cy="8" r="4"/><path d="M3 21a6 6 0 0 1 12 0"/><circle cx="17" cy="6" r="3"/><path d="M21 17a4 4 0 0 0-6-3.5"/></>,
|
||
building: <><path d="M3 21h18M5 21V5a2 2 0 0 1 2-2h10a2 2 0 0 1 2 2v16"/><path d="M9 7h2M13 7h2M9 11h2M13 11h2M9 15h2M13 15h2"/></>,
|
||
target: <><circle cx="12" cy="12" r="9"/><circle cx="12" cy="12" r="5"/><circle cx="12" cy="12" r="1"/></>,
|
||
check: <><path d="M9 11l3 3L22 4"/><path d="M21 12v7a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h11"/></>,
|
||
workflow: <><rect x="3" y="3" width="6" height="6" rx="1"/><rect x="15" y="15" width="6" height="6" rx="1"/><path d="M9 6h6a3 3 0 0 1 3 3v6"/></>,
|
||
bar: <><path d="M3 3v18h18"/><rect x="7" y="11" width="3" height="7"/><rect x="13" y="7" width="3" height="11"/><rect x="19" y="14" width="0" height="4"/></>,
|
||
hash: <path d="M9 3l-2 18M17 3l-2 18M3 9h18M2 15h18"/>,
|
||
lock: <><rect x="4" y="11" width="16" height="10" rx="2"/><path d="M8 11V7a4 4 0 0 1 8 0v4"/></>,
|
||
plus: <path d="M12 5v14M5 12h14"/>,
|
||
chevron: <path d="m6 9 6 6 6-6"/>,
|
||
arrow: <path d="M5 12h14M13 5l7 7-7 7"/>,
|
||
star: <path d="m12 3 2.6 6.2 6.7.5-5.1 4.4 1.6 6.6L12 17.3 6.2 20.7l1.6-6.6L2.7 9.7l6.7-.5z"/>,
|
||
doc: <><path d="M14 3H6a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V9z"/><path d="M14 3v6h6"/></>,
|
||
spark: <path d="M12 3v4M12 17v4M3 12h4M17 12h4M6 6l3 3M15 15l3 3M6 18l3-3M15 9l3-3"/>,
|
||
};
|
||
|
||
const sansStack = "'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, sans-serif";
|
||
|
||
// ============================================================
|
||
// 1. SIDEBAR — workspace + sections + secondary
|
||
// (Linear / Notion / Twenty school)
|
||
// ============================================================
|
||
const NavSidebar = () => {
|
||
const ItemRow = ({ icon, label, count, active }) => (
|
||
<div style={{
|
||
display: "flex", alignItems: "center", gap: 10,
|
||
padding: "6px 10px", borderRadius: 6, fontSize: 13,
|
||
color: active ? "#111" : "#5a5a5e",
|
||
background: active ? "#ffffff" : "transparent",
|
||
boxShadow: active ? "0 1px 0 #00000008, 0 0 0 1px #00000008" : "none",
|
||
fontWeight: active ? 500 : 400, cursor: "pointer",
|
||
}}>
|
||
<span style={{ color: active ? "#5e5cff" : "#8a8a90", display: "flex" }}>
|
||
<I d={icon} size={15} />
|
||
</span>
|
||
<span style={{ flex: 1 }}>{label}</span>
|
||
{count && <span style={{
|
||
fontSize: 11, color: "#8a8a90", fontVariantNumeric: "tabular-nums",
|
||
}}>{count}</span>}
|
||
</div>
|
||
);
|
||
const SectionHeader = ({ label }) => (
|
||
<div style={{
|
||
fontSize: 11, color: "#8a8a90", letterSpacing: "0.04em",
|
||
padding: "16px 10px 6px", textTransform: "uppercase",
|
||
fontWeight: 500,
|
||
}}>{label}</div>
|
||
);
|
||
|
||
return (
|
||
<div style={{
|
||
width: "100%", height: "100%", display: "grid",
|
||
gridTemplateColumns: "248px 1fr",
|
||
background: "#fcfcfb", fontFamily: sansStack, color: "#111",
|
||
}}>
|
||
{/* SIDEBAR */}
|
||
<aside style={{
|
||
background: "#f5f5f2", borderRight: "1px solid #e8e8e3",
|
||
display: "flex", flexDirection: "column",
|
||
}}>
|
||
{/* Workspace switcher */}
|
||
<div style={{
|
||
padding: "12px 12px", display: "flex", alignItems: "center", gap: 10,
|
||
borderBottom: "1px solid #e8e8e3",
|
||
}}>
|
||
<div style={{
|
||
width: 26, height: 26, borderRadius: 6,
|
||
background: "linear-gradient(135deg, #6e6cff 0%, #b15bff 100%)",
|
||
display: "flex", alignItems: "center", justifyContent: "center",
|
||
color: "#fff", fontWeight: 700, fontSize: 13,
|
||
}}>L</div>
|
||
<div style={{ flex: 1, lineHeight: 1.2 }}>
|
||
<div style={{ fontSize: 13, fontWeight: 600 }}>Lattice Studio</div>
|
||
<div style={{ fontSize: 11, color: "#8a8a90" }}>Free · 4 members</div>
|
||
</div>
|
||
<span style={{ color: "#8a8a90", display: "flex" }}>
|
||
<I d={Paths.chevron} size={14} />
|
||
</span>
|
||
</div>
|
||
|
||
{/* Search */}
|
||
<div style={{ padding: "10px 12px" }}>
|
||
<div style={{
|
||
display: "flex", alignItems: "center", gap: 8, padding: "6px 10px",
|
||
background: "#fff", border: "1px solid #e8e8e3", borderRadius: 6,
|
||
fontSize: 12, color: "#8a8a90",
|
||
}}>
|
||
<I d={Paths.search} size={14} />
|
||
<span style={{ flex: 1 }}>Search…</span>
|
||
<span style={{
|
||
fontSize: 10, padding: "1px 5px", border: "1px solid #e0e0d8",
|
||
borderRadius: 3, fontFamily: "monospace",
|
||
}}>⌘K</span>
|
||
</div>
|
||
</div>
|
||
|
||
{/* Nav */}
|
||
<nav style={{ padding: "4px 8px", flex: 1, overflowY: "auto" }}>
|
||
<ItemRow icon={Paths.home} label="Home" />
|
||
<ItemRow icon={Paths.inbox} label="Inbox" count="12" />
|
||
<ItemRow icon={Paths.check} label="My tasks" count="3" />
|
||
|
||
<SectionHeader label="Workspaces" />
|
||
<ItemRow icon={Paths.hash} label="Marketing site" active />
|
||
<ItemRow icon={Paths.hash} label="Q2 launch" />
|
||
<ItemRow icon={Paths.hash} label="Brand refresh" />
|
||
<ItemRow icon={Paths.hash} label="Customer interviews" />
|
||
|
||
<SectionHeader label="Pinned" />
|
||
<ItemRow icon={Paths.doc} label="Roadmap · 2026" />
|
||
<ItemRow icon={Paths.doc} label="Design tokens" />
|
||
<ItemRow icon={Paths.doc} label="Onboarding flow" />
|
||
|
||
<SectionHeader label="Team" />
|
||
<ItemRow icon={Paths.people} label="People" />
|
||
<ItemRow icon={Paths.bar} label="Insights" />
|
||
<ItemRow icon={Paths.workflow} label="Automations" />
|
||
</nav>
|
||
|
||
{/* Footer */}
|
||
<div style={{
|
||
padding: "10px 12px", borderTop: "1px solid #e8e8e3",
|
||
display: "flex", alignItems: "center", gap: 10,
|
||
}}>
|
||
<div style={{
|
||
width: 24, height: 24, borderRadius: "50%", background: "#d4b8a8",
|
||
display: "flex", alignItems: "center", justifyContent: "center",
|
||
fontSize: 11, fontWeight: 600, color: "#5a3e34",
|
||
}}>MR</div>
|
||
<div style={{ flex: 1, fontSize: 12 }}>
|
||
<div style={{ fontWeight: 500 }}>Mira Reyes</div>
|
||
<div style={{ color: "#8a8a90", fontSize: 11 }}>mira@lattice.co</div>
|
||
</div>
|
||
<span style={{ color: "#8a8a90", display: "flex" }}>
|
||
<I d={Paths.chevron} size={14} />
|
||
</span>
|
||
</div>
|
||
</aside>
|
||
|
||
{/* CONTENT */}
|
||
<main style={{ display: "flex", flexDirection: "column", overflow: "hidden" }}>
|
||
<div style={{
|
||
padding: "14px 28px", borderBottom: "1px solid #e8e8e3",
|
||
display: "flex", alignItems: "center", justifyContent: "space-between",
|
||
}}>
|
||
<div style={{ fontSize: 13, color: "#8a8a90" }}>
|
||
Workspaces / <span style={{ color: "#111" }}>Marketing site</span>
|
||
</div>
|
||
<div style={{ display: "flex", gap: 8 }}>
|
||
<button style={{
|
||
padding: "6px 12px", border: "1px solid #e0e0d8",
|
||
background: "#fff", borderRadius: 6, fontSize: 12, fontFamily: sansStack,
|
||
color: "#5a5a5e", cursor: "pointer",
|
||
}}>Share</button>
|
||
<button style={{
|
||
padding: "6px 12px", border: "none",
|
||
background: "#111", color: "#fff", borderRadius: 6, fontSize: 12,
|
||
fontFamily: sansStack, cursor: "pointer", display: "flex", alignItems: "center", gap: 6,
|
||
}}><I d={Paths.plus} size={12}/> New page</button>
|
||
</div>
|
||
</div>
|
||
<div style={{ padding: 36, flex: 1, overflow: "hidden" }}>
|
||
<h1 style={{
|
||
fontSize: 28, fontWeight: 600, letterSpacing: "-0.02em", margin: 0,
|
||
}}>Marketing site</h1>
|
||
<p style={{ color: "#5a5a5e", fontSize: 13, marginTop: 6 }}>
|
||
14 pages · last edited 4 minutes ago by Mira
|
||
</p>
|
||
<div style={{ marginTop: 28, display: "grid", gridTemplateColumns: "1fr 1fr 1fr", gap: 16 }}>
|
||
{["Homepage", "Pricing", "Changelog"].map(t => (
|
||
<div key={t} style={{
|
||
background: "#fff", border: "1px solid #e8e8e3", borderRadius: 10,
|
||
padding: 16,
|
||
}}>
|
||
<NavImgSlot label={`${t} · preview`} h={110} />
|
||
<div style={{ fontSize: 13, fontWeight: 500, marginTop: 12 }}>{t}</div>
|
||
<div style={{ fontSize: 11, color: "#8a8a90", marginTop: 2 }}>
|
||
Edited 2h ago · Mira
|
||
</div>
|
||
</div>
|
||
))}
|
||
</div>
|
||
</div>
|
||
</main>
|
||
</div>
|
||
);
|
||
};
|
||
|
||
// ============================================================
|
||
// 2. ICON RAIL + CONTEXT PANEL — Slack / Discord / Mail school
|
||
// ============================================================
|
||
const NavIconRail = () => {
|
||
const RailIcon = ({ icon, active, badge, color }) => (
|
||
<div style={{
|
||
width: 40, height: 40, borderRadius: 10,
|
||
background: active ? color : "transparent",
|
||
color: active ? "#fff" : "#9a9aa6",
|
||
display: "flex", alignItems: "center", justifyContent: "center",
|
||
cursor: "pointer", position: "relative",
|
||
border: active ? "none" : "1px solid transparent",
|
||
}}>
|
||
<I d={icon} size={18} sw={2} />
|
||
{badge && (
|
||
<span style={{
|
||
position: "absolute", top: -2, right: -2, minWidth: 16, height: 16,
|
||
padding: "0 4px", background: "#ff4d5e", color: "#fff",
|
||
borderRadius: 8, fontSize: 10, fontWeight: 600,
|
||
display: "flex", alignItems: "center", justifyContent: "center",
|
||
border: "2px solid #0f0f14",
|
||
}}>{badge}</span>
|
||
)}
|
||
</div>
|
||
);
|
||
|
||
const ChannelItem = ({ name, active, unread, mention }) => (
|
||
<div style={{
|
||
display: "flex", alignItems: "center", gap: 8,
|
||
padding: "6px 10px", borderRadius: 6, fontSize: 13,
|
||
color: active ? "#fff" : (unread ? "#dcdce4" : "#9a9aa6"),
|
||
background: active ? "#ffffff14" : "transparent",
|
||
fontWeight: unread ? 500 : 400, cursor: "pointer",
|
||
}}>
|
||
<span style={{ opacity: 0.7 }}>#</span>
|
||
<span style={{ flex: 1 }}>{name}</span>
|
||
{mention && <span style={{
|
||
background: "#ff4d5e", color: "#fff", fontSize: 10, fontWeight: 600,
|
||
padding: "1px 6px", borderRadius: 8,
|
||
}}>{mention}</span>}
|
||
</div>
|
||
);
|
||
|
||
return (
|
||
<div style={{
|
||
width: "100%", height: "100%", display: "grid",
|
||
gridTemplateColumns: "72px 260px 1fr",
|
||
background: "#0f0f14", color: "#e8e8ee", fontFamily: sansStack,
|
||
}}>
|
||
{/* RAIL */}
|
||
<div style={{
|
||
background: "#08080c", borderRight: "1px solid #ffffff08",
|
||
display: "flex", flexDirection: "column", alignItems: "center",
|
||
padding: "12px 0", gap: 6,
|
||
}}>
|
||
<div style={{
|
||
width: 40, height: 40, borderRadius: 10,
|
||
background: "linear-gradient(135deg, #5e5cff 0%, #b15bff 100%)",
|
||
display: "flex", alignItems: "center", justifyContent: "center",
|
||
color: "#fff", fontWeight: 800, fontSize: 16, marginBottom: 6,
|
||
}}>L</div>
|
||
<div style={{ width: 24, height: 1, background: "#ffffff10", margin: "4px 0" }}></div>
|
||
|
||
<RailIcon icon={Paths.home} active color="#5e5cff" />
|
||
<RailIcon icon={Paths.inbox} badge="9" />
|
||
<RailIcon icon={Paths.people} />
|
||
<RailIcon icon={Paths.target} badge="2" />
|
||
<RailIcon icon={Paths.bar} />
|
||
<RailIcon icon={Paths.doc} />
|
||
|
||
<div style={{ flex: 1 }}></div>
|
||
<RailIcon icon={Paths.plus} />
|
||
<RailIcon icon={Paths.spark} />
|
||
<div style={{
|
||
width: 32, height: 32, borderRadius: "50%", marginTop: 4,
|
||
background: "#d4b8a8", display: "flex", alignItems: "center",
|
||
justifyContent: "center", fontSize: 12, fontWeight: 600, color: "#5a3e34",
|
||
border: "2px solid #08080c", boxShadow: "0 0 0 2px #5e5cff",
|
||
position: "relative",
|
||
}}>MR
|
||
<span style={{
|
||
position: "absolute", bottom: -2, right: -2, width: 12, height: 12,
|
||
background: "#22c55e", borderRadius: "50%", border: "2px solid #08080c",
|
||
}}></span>
|
||
</div>
|
||
</div>
|
||
|
||
{/* SECONDARY PANEL */}
|
||
<div style={{
|
||
background: "#13131a", borderRight: "1px solid #ffffff08",
|
||
display: "flex", flexDirection: "column",
|
||
}}>
|
||
<div style={{
|
||
padding: "16px 16px 12px",
|
||
borderBottom: "1px solid #ffffff08",
|
||
}}>
|
||
<div style={{
|
||
display: "flex", justifyContent: "space-between", alignItems: "center",
|
||
marginBottom: 12,
|
||
}}>
|
||
<span style={{ fontSize: 15, fontWeight: 600 }}>Lattice HQ</span>
|
||
<span style={{ color: "#9a9aa6", display: "flex" }}>
|
||
<I d={Paths.chevron} size={16} />
|
||
</span>
|
||
</div>
|
||
<div style={{
|
||
display: "flex", alignItems: "center", gap: 8,
|
||
padding: "7px 10px", background: "#08080c",
|
||
borderRadius: 7, fontSize: 12, color: "#9a9aa6",
|
||
}}>
|
||
<I d={Paths.search} size={13} />
|
||
<span style={{ flex: 1 }}>Jump to…</span>
|
||
<span style={{
|
||
fontSize: 10, padding: "1px 5px",
|
||
background: "#ffffff08", borderRadius: 3, fontFamily: "monospace",
|
||
}}>⌘K</span>
|
||
</div>
|
||
</div>
|
||
|
||
<div style={{ padding: "12px 8px", flex: 1, overflowY: "auto" }}>
|
||
<div style={{
|
||
fontSize: 11, color: "#6a6a78", padding: "8px 10px 4px",
|
||
textTransform: "uppercase", letterSpacing: "0.04em", fontWeight: 500,
|
||
display: "flex", justifyContent: "space-between",
|
||
}}>
|
||
<span>Channels</span>
|
||
<I d={Paths.plus} size={12} />
|
||
</div>
|
||
<ChannelItem name="general" />
|
||
<ChannelItem name="design-crits" unread mention="3" />
|
||
<ChannelItem name="launch-2026" active />
|
||
<ChannelItem name="random" />
|
||
<ChannelItem name="bugs" unread />
|
||
|
||
<div style={{
|
||
fontSize: 11, color: "#6a6a78", padding: "16px 10px 4px",
|
||
textTransform: "uppercase", letterSpacing: "0.04em", fontWeight: 500,
|
||
}}>Direct messages</div>
|
||
{[
|
||
["Sun Kim", "#e8a87c", true],
|
||
["Devi Patel", "#a8c8e8", false],
|
||
["Theo Roux", "#c8e8a8", false],
|
||
].map(([n, c, online], i) => (
|
||
<div key={i} style={{
|
||
display: "flex", alignItems: "center", gap: 10,
|
||
padding: "6px 10px", borderRadius: 6, fontSize: 13, color: "#dcdce4",
|
||
cursor: "pointer",
|
||
}}>
|
||
<div style={{ position: "relative" }}>
|
||
<div style={{ width: 22, height: 22, borderRadius: "50%", background: c }}></div>
|
||
{online && <span style={{
|
||
position: "absolute", bottom: -1, right: -1, width: 8, height: 8,
|
||
background: "#22c55e", borderRadius: "50%", border: "2px solid #13131a",
|
||
}}></span>}
|
||
</div>
|
||
<span style={{ flex: 1 }}>{n}</span>
|
||
</div>
|
||
))}
|
||
</div>
|
||
</div>
|
||
|
||
{/* CONTENT */}
|
||
<main style={{ display: "flex", flexDirection: "column" }}>
|
||
<div style={{
|
||
padding: "14px 24px", borderBottom: "1px solid #ffffff08",
|
||
display: "flex", alignItems: "center", gap: 12,
|
||
}}>
|
||
<span style={{ color: "#9a9aa6" }}>#</span>
|
||
<span style={{ fontSize: 15, fontWeight: 600 }}>launch-2026</span>
|
||
<span style={{ color: "#6a6a78", fontSize: 12 }}>· 18 members</span>
|
||
<div style={{ flex: 1 }}></div>
|
||
<span style={{ color: "#9a9aa6", display: "flex" }}><I d={Paths.bell} size={16}/></span>
|
||
<span style={{ color: "#9a9aa6", display: "flex" }}><I d={Paths.star} size={16}/></span>
|
||
</div>
|
||
<div style={{ padding: 28, flex: 1, color: "#9a9aa6", fontSize: 13 }}>
|
||
<NavImgSlot label="conversation thread" h={420} tone="dark" />
|
||
</div>
|
||
</main>
|
||
</div>
|
||
);
|
||
};
|
||
|
||
// ============================================================
|
||
// 3. TOP HORIZONTAL + COMMAND BAR — Vercel / Stripe / Linear web
|
||
// ============================================================
|
||
const NavTopHorizontal = () => {
|
||
const TabItem = ({ label, active }) => (
|
||
<div style={{
|
||
padding: "16px 2px", margin: "0 12px", fontSize: 13, fontWeight: 500,
|
||
color: active ? "#fff" : "#9a9aa6",
|
||
borderBottom: active ? "2px solid #fff" : "2px solid transparent",
|
||
cursor: "pointer", position: "relative", top: 1,
|
||
}}>{label}</div>
|
||
);
|
||
|
||
return (
|
||
<div style={{
|
||
width: "100%", height: "100%", background: "#fafaf9",
|
||
color: "#111", fontFamily: sansStack, display: "flex", flexDirection: "column",
|
||
}}>
|
||
{/* DARK TOP BAR */}
|
||
<header style={{ background: "#0a0a0a", color: "#fff" }}>
|
||
{/* Row 1: brand + workspace + global */}
|
||
<div style={{
|
||
display: "flex", alignItems: "center", gap: 14,
|
||
padding: "12px 24px",
|
||
}}>
|
||
{/* Brand */}
|
||
<div style={{
|
||
display: "flex", alignItems: "center", gap: 8, fontWeight: 600, fontSize: 14,
|
||
}}>
|
||
<svg width="22" height="22" viewBox="0 0 24 24" fill="none">
|
||
<path d="M3 20 L12 4 L21 20 Z" fill="#fff"/>
|
||
</svg>
|
||
Lattice
|
||
</div>
|
||
<span style={{ color: "#3a3a3a" }}>/</span>
|
||
{/* Workspace */}
|
||
<div style={{
|
||
display: "flex", alignItems: "center", gap: 8, fontSize: 13,
|
||
}}>
|
||
<div style={{
|
||
width: 18, height: 18, borderRadius: "50%", background: "#e8a87c",
|
||
fontSize: 9, fontWeight: 700, color: "#5a3e34",
|
||
display: "flex", alignItems: "center", justifyContent: "center",
|
||
}}>MR</div>
|
||
<span>mira-reyes</span>
|
||
<span style={{ color: "#5a5a5e", display: "flex" }}><I d={Paths.chevron} size={12}/></span>
|
||
</div>
|
||
<span style={{ color: "#3a3a3a" }}>/</span>
|
||
{/* Project */}
|
||
<div style={{ fontSize: 13, display: "flex", alignItems: "center", gap: 6 }}>
|
||
<span>marketing-site</span>
|
||
<span style={{
|
||
fontSize: 10, padding: "1px 7px", borderRadius: 999,
|
||
background: "#1f1f1f", color: "#9a9aa6", border: "1px solid #2a2a2a",
|
||
}}>Hobby</span>
|
||
</div>
|
||
|
||
<div style={{ flex: 1 }}></div>
|
||
|
||
{/* Command bar — focal point */}
|
||
<div style={{
|
||
display: "flex", alignItems: "center", gap: 10,
|
||
padding: "6px 12px", borderRadius: 8,
|
||
background: "#1a1a1a", border: "1px solid #2a2a2a",
|
||
color: "#9a9aa6", fontSize: 12, minWidth: 320,
|
||
}}>
|
||
<I d={Paths.search} size={13} />
|
||
<span style={{ flex: 1 }}>Find or jump to anything…</span>
|
||
<span style={{
|
||
fontSize: 10, padding: "1px 5px", background: "#2a2a2a",
|
||
borderRadius: 3, fontFamily: "monospace",
|
||
}}>⌘K</span>
|
||
</div>
|
||
|
||
{/* Right icons */}
|
||
<button style={{
|
||
background: "transparent", border: "1px solid #2a2a2a",
|
||
color: "#fff", padding: "5px 12px", borderRadius: 6,
|
||
fontSize: 12, fontFamily: sansStack, cursor: "pointer",
|
||
}}>Feedback</button>
|
||
<span style={{ color: "#9a9aa6", display: "flex", cursor: "pointer" }}>
|
||
<I d={Paths.doc} size={16}/>
|
||
</span>
|
||
<span style={{ color: "#9a9aa6", display: "flex", cursor: "pointer", position: "relative" }}>
|
||
<I d={Paths.bell} size={16}/>
|
||
<span style={{
|
||
position: "absolute", top: -2, right: -2, width: 7, height: 7,
|
||
background: "#5e5cff", borderRadius: "50%",
|
||
}}></span>
|
||
</span>
|
||
<div style={{
|
||
width: 26, height: 26, borderRadius: "50%", background: "#d4b8a8",
|
||
fontSize: 11, fontWeight: 600, color: "#5a3e34",
|
||
display: "flex", alignItems: "center", justifyContent: "center",
|
||
cursor: "pointer",
|
||
}}>MR</div>
|
||
</div>
|
||
|
||
{/* Row 2: tabs */}
|
||
<div style={{
|
||
display: "flex", alignItems: "center",
|
||
padding: "0 16px", borderBottom: "1px solid #1a1a1a",
|
||
}}>
|
||
<TabItem label="Overview" active />
|
||
<TabItem label="Deployments" />
|
||
<TabItem label="Analytics" />
|
||
<TabItem label="Logs" />
|
||
<TabItem label="Storage" />
|
||
<TabItem label="Domains" />
|
||
<TabItem label="Settings" />
|
||
</div>
|
||
</header>
|
||
|
||
{/* CONTENT */}
|
||
<main style={{ flex: 1, padding: "32px 48px" }}>
|
||
<div style={{
|
||
display: "flex", justifyContent: "space-between", alignItems: "flex-end",
|
||
marginBottom: 24,
|
||
}}>
|
||
<div>
|
||
<h1 style={{
|
||
fontSize: 32, fontWeight: 600, margin: 0, letterSpacing: "-0.02em",
|
||
}}>Overview</h1>
|
||
<p style={{ color: "#6a6a72", margin: "4px 0 0", fontSize: 13 }}>
|
||
Last deployment 14 minutes ago to <code style={{
|
||
background: "#f0efea", padding: "1px 5px", borderRadius: 3,
|
||
fontSize: 12,
|
||
}}>main</code>
|
||
</p>
|
||
</div>
|
||
<button style={{
|
||
background: "#111", color: "#fff", border: "none",
|
||
padding: "8px 16px", borderRadius: 6, fontSize: 13, fontWeight: 500,
|
||
fontFamily: sansStack, cursor: "pointer", display: "flex",
|
||
alignItems: "center", gap: 6,
|
||
}}><I d={Paths.plus} size={13}/> Deploy</button>
|
||
</div>
|
||
|
||
<div style={{ display: "grid", gridTemplateColumns: "1.4fr 1fr", gap: 20 }}>
|
||
<div style={{
|
||
background: "#fff", border: "1px solid #ebebe6", borderRadius: 10,
|
||
padding: 20,
|
||
}}>
|
||
<div style={{ fontSize: 12, color: "#6a6a72", marginBottom: 12 }}>
|
||
Production · Last 24h
|
||
</div>
|
||
<NavImgSlot label="requests · time series" h={190} />
|
||
</div>
|
||
<div style={{
|
||
background: "#fff", border: "1px solid #ebebe6", borderRadius: 10,
|
||
padding: 20, display: "grid", gridTemplateRows: "1fr 1fr", gap: 14,
|
||
}}>
|
||
<div>
|
||
<div style={{ fontSize: 12, color: "#6a6a72" }}>Requests</div>
|
||
<div style={{ fontSize: 26, fontWeight: 600, marginTop: 4 }}>
|
||
284,012 <span style={{ color: "#22c55e", fontSize: 12 }}>+12%</span>
|
||
</div>
|
||
</div>
|
||
<div>
|
||
<div style={{ fontSize: 12, color: "#6a6a72" }}>Edge p99</div>
|
||
<div style={{ fontSize: 26, fontWeight: 600, marginTop: 4 }}>
|
||
47ms <span style={{ color: "#22c55e", fontSize: 12 }}>−3ms</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</main>
|
||
</div>
|
||
);
|
||
};
|
||
|
||
// ============================================================
|
||
// 4. FLOATING GLASS NAV — marketing site / homepage pattern
|
||
// ============================================================
|
||
const NavFloatingGlass = () => (
|
||
<div style={{
|
||
width: "100%", height: "100%", color: "#fff",
|
||
background: "#08081a", fontFamily: sansStack,
|
||
position: "relative", overflow: "hidden",
|
||
}}>
|
||
{/* Soft aurora background */}
|
||
<div style={{
|
||
position: "absolute", top: -250, left: -150, width: 700, height: 700,
|
||
borderRadius: "50%",
|
||
background: "radial-gradient(circle, #5e5cff 0%, transparent 60%)",
|
||
filter: "blur(100px)", opacity: 0.5,
|
||
}}></div>
|
||
<div style={{
|
||
position: "absolute", top: 100, right: -200, width: 600, height: 600,
|
||
borderRadius: "50%",
|
||
background: "radial-gradient(circle, #b15bff 0%, transparent 60%)",
|
||
filter: "blur(100px)", opacity: 0.4,
|
||
}}></div>
|
||
<div style={{
|
||
position: "absolute", bottom: -200, left: "30%", width: 500, height: 500,
|
||
borderRadius: "50%",
|
||
background: "radial-gradient(circle, #00e5b3 0%, transparent 60%)",
|
||
filter: "blur(100px)", opacity: 0.3,
|
||
}}></div>
|
||
|
||
{/* Floating pill nav — the focal point */}
|
||
<header style={{
|
||
position: "absolute", top: 24, left: "50%",
|
||
transform: "translateX(-50%)", zIndex: 10,
|
||
width: "max-content", whiteSpace: "nowrap",
|
||
display: "flex", alignItems: "center", gap: 4,
|
||
padding: "8px 8px 8px 18px",
|
||
background: "rgba(255,255,255,0.06)",
|
||
backdropFilter: "blur(24px)",
|
||
WebkitBackdropFilter: "blur(24px)",
|
||
border: "1px solid rgba(255,255,255,0.12)",
|
||
borderRadius: 999,
|
||
boxShadow: "0 20px 50px -20px rgba(0,0,0,0.6), inset 0 1px 0 rgba(255,255,255,0.1)",
|
||
}}>
|
||
<div style={{
|
||
display: "flex", alignItems: "center", gap: 8,
|
||
marginRight: 18, fontWeight: 600, fontSize: 14,
|
||
}}>
|
||
<svg width="18" height="18" viewBox="0 0 24 24" fill="none">
|
||
<path d="M3 20 L12 4 L21 20 Z" fill="url(#g)" />
|
||
<defs>
|
||
<linearGradient id="g" x1="0" y1="0" x2="1" y2="1">
|
||
<stop offset="0%" stopColor="#5e5cff"/>
|
||
<stop offset="100%" stopColor="#b15bff"/>
|
||
</linearGradient>
|
||
</defs>
|
||
</svg>
|
||
Lattice
|
||
</div>
|
||
|
||
{["Product", "Solutions", "Customers", "Pricing", "Docs"].map((l, i) => (
|
||
<button key={l} style={{
|
||
background: i === 0 ? "rgba(255,255,255,0.1)" : "transparent",
|
||
border: "none", color: "#fff", whiteSpace: "nowrap",
|
||
padding: "8px 14px", borderRadius: 999,
|
||
fontSize: 13, fontFamily: sansStack, cursor: "pointer",
|
||
display: "flex", alignItems: "center", gap: 4,
|
||
}}>
|
||
{l}
|
||
{(i === 0 || i === 1) && (
|
||
<span style={{ opacity: 0.6, display: "flex" }}>
|
||
<I d={Paths.chevron} size={11} />
|
||
</span>
|
||
)}
|
||
</button>
|
||
))}
|
||
|
||
<div style={{ width: 1, height: 22, background: "rgba(255,255,255,0.12)", margin: "0 6px" }}></div>
|
||
|
||
<button style={{
|
||
background: "transparent", border: "none", color: "#fff",
|
||
padding: "8px 14px", borderRadius: 999, fontSize: 13,
|
||
fontFamily: sansStack, cursor: "pointer", whiteSpace: "nowrap",
|
||
}}>Sign in</button>
|
||
<button style={{
|
||
background: "#fff", color: "#08081a", border: "none",
|
||
padding: "8px 16px", borderRadius: 999, fontSize: 13, fontWeight: 600,
|
||
fontFamily: sansStack, cursor: "pointer", whiteSpace: "nowrap",
|
||
}}>Get started →</button>
|
||
</header>
|
||
|
||
{/* Tiny status pill above nav */}
|
||
<div style={{
|
||
position: "absolute", top: -2, left: "50%",
|
||
transform: "translateX(-50%)",
|
||
padding: "4px 10px 4px 26px",
|
||
background: "rgba(255,255,255,0.04)",
|
||
backdropFilter: "blur(12px)",
|
||
border: "1px solid rgba(255,255,255,0.08)",
|
||
borderRadius: "0 0 10px 10px",
|
||
fontSize: 11, color: "#a8a8c0",
|
||
borderTop: "none",
|
||
}}>
|
||
All systems normal ·{" "}
|
||
<span style={{ color: "#7aff66" }}>● 99.99% uptime</span>
|
||
</div>
|
||
|
||
{/* HERO */}
|
||
<main style={{
|
||
position: "relative", paddingTop: 180,
|
||
textAlign: "center", maxWidth: 880, margin: "0 auto",
|
||
padding: "180px 40px 0",
|
||
}}>
|
||
<div style={{
|
||
display: "inline-flex", alignItems: "center", gap: 8,
|
||
padding: "5px 14px 5px 5px", borderRadius: 999,
|
||
background: "rgba(255,255,255,0.06)",
|
||
border: "1px solid rgba(255,255,255,0.12)",
|
||
fontSize: 12, marginBottom: 28,
|
||
}}>
|
||
<span style={{
|
||
padding: "2px 8px", background: "#5e5cff", borderRadius: 999,
|
||
fontWeight: 600, fontSize: 10,
|
||
}}>NEW</span>
|
||
Lattice 4.0 — agents that draft for you ·{" "}
|
||
<span style={{ opacity: 0.7 }}>read more →</span>
|
||
</div>
|
||
<h1 style={{
|
||
fontSize: 76, lineHeight: 1, margin: 0, fontWeight: 500,
|
||
letterSpacing: "-0.04em", textWrap: "balance",
|
||
}}>
|
||
The workspace where{" "}
|
||
<span style={{
|
||
background: "linear-gradient(90deg, #b15bff, #5e5cff, #00e5b3)",
|
||
WebkitBackgroundClip: "text", WebkitTextFillColor: "transparent",
|
||
fontStyle: "italic", fontWeight: 400,
|
||
}}>
|
||
good ideas
|
||
</span>{" "}
|
||
compound.
|
||
</h1>
|
||
<p style={{
|
||
fontSize: 17, lineHeight: 1.5, marginTop: 22, opacity: 0.7,
|
||
maxWidth: 540, marginLeft: "auto", marginRight: "auto",
|
||
}}>
|
||
Docs, canvases, and agents in one luminous surface.
|
||
Built by people who got tired of switching tabs.
|
||
</p>
|
||
<div style={{ display: "flex", gap: 12, justifyContent: "center", marginTop: 32 }}>
|
||
<button style={{
|
||
background: "#fff", color: "#08081a", border: "none",
|
||
padding: "14px 28px", borderRadius: 999, fontWeight: 600,
|
||
fontSize: 14, cursor: "pointer", fontFamily: sansStack,
|
||
whiteSpace: "nowrap",
|
||
}}>Start for free</button>
|
||
<button style={{
|
||
background: "rgba(255,255,255,0.08)", color: "#fff",
|
||
border: "1px solid rgba(255,255,255,0.16)",
|
||
backdropFilter: "blur(12px)",
|
||
padding: "14px 28px", borderRadius: 999, fontSize: 14,
|
||
cursor: "pointer", fontFamily: sansStack, whiteSpace: "nowrap",
|
||
}}>▶ Watch the film · 2 min</button>
|
||
</div>
|
||
</main>
|
||
</div>
|
||
);
|
||
|
||
// Export to window
|
||
Object.assign(window, {
|
||
NavSidebar, NavIconRail, NavTopHorizontal, NavFloatingGlass,
|
||
});
|