diff --git a/ee/apps/landing/components/landing-enterprise-hero.tsx b/ee/apps/landing/components/landing-enterprise-hero.tsx deleted file mode 100644 index 5d73cd58..00000000 --- a/ee/apps/landing/components/landing-enterprise-hero.tsx +++ /dev/null @@ -1,951 +0,0 @@ -"use client"; - -import { - Bell, - Brain, - ChevronRight, - DollarSign, - Gauge, - Search, - Users -} from "lucide-react"; -import { useState } from "react"; -import { OpenWorkMark } from "./openwork-mark"; - -type DepartmentCategory = "Technical teams" | "Business teams"; - -type Department = { - name: string; - category: DepartmentCategory; - dailyActive: string; - spend: string; - avgPerPerson: string; - /** Daily active users over the last 10 weekdays. */ - trend: number[]; - powerUsers: string[]; -}; - -type ToolRow = { - tool: string; - penetration: string; - topDepartment: string; - topUsers: string[]; - featured?: boolean; -}; - -type PowerUser = { - name: string; - initials: string; - department: string; - topTool: string; - /** Cumulative requests by weekday (10 weekdays). Shape reveals usage personality. */ - trend: number[]; - /** One-line descriptor of the usage personality (shown as tooltip). */ - trendNote: string; - requests: string; - inputTokens: string; - outputTokens: string; - cost: string; -}; - -const departments: Department[] = [ - { - name: "Engineering", - category: "Technical teams", - dailyActive: "32 / 54", - spend: "$210K", - avgPerPerson: "$4.4K", - trend: [26, 28, 27, 29, 29, 30, 31, 30, 32, 32], - powerUsers: ["JC", "LT", "GH", "+3"] - }, - { - name: "Data Science", - category: "Technical teams", - dailyActive: "16 / 28", - spend: "$120K", - avgPerPerson: "$4.3K", - trend: [8, 9, 10, 11, 12, 13, 14, 15, 15, 16], - powerUsers: ["AL", "MC", "AT", "+2"] - }, - { - name: "Product", - category: "Technical teams", - dailyActive: "9 / 24", - spend: "$90K", - avgPerPerson: "$3.8K", - trend: [4, 5, 5, 4, 6, 7, 6, 8, 8, 9], - powerUsers: ["HL", "DG", "AR", "+1"] - }, - { - name: "Customer Support", - category: "Business teams", - dailyActive: "7 / 36", - spend: "$30K", - avgPerPerson: "$968", - trend: [9, 9, 10, 9, 8, 8, 7, 8, 7, 7], - powerUsers: ["MF", "SG", "RM", "+2"] - }, - { - name: "Marketing", - category: "Business teams", - dailyActive: "3 / 28", - spend: "$18K", - avgPerPerson: "$643", - trend: [1, 1, 1, 2, 1, 2, 2, 3, 3, 3], - powerUsers: ["RF", "AS", "JR", "+1"] - }, - { - name: "Sales", - category: "Business teams", - dailyActive: "1 / 25", - spend: "$15K", - avgPerPerson: "$600", - trend: [0, 1, 0, 0, 0, 1, 1, 0, 1, 1], - powerUsers: ["AC", "WB", "HF", "+2"] - }, - { - name: "Legal", - category: "Business teams", - dailyActive: "0 / 12", - spend: "$7K", - avgPerPerson: "$583", - trend: [3, 2, 2, 1, 1, 1, 0, 0, 0, 0], - powerUsers: ["SD", "OB", "RH", "+1"] - } -]; - -const toolRows: ToolRow[] = [ - { - tool: "OpenWork", - penetration: "41%", - topDepartment: "Customer Support", - topUsers: ["AL", "GH", "AC"], - featured: true - }, - { - tool: "Cursor", - penetration: "24%", - topDepartment: "Engineering", - topUsers: ["JC", "LT", "AT"] - }, - { - tool: "Figma AI", - penetration: "11%", - topDepartment: "Product", - topUsers: ["HL", "RF"] - }, - { - tool: "Notion AI", - penetration: "9%", - topDepartment: "Product", - topUsers: ["DG", "AS"] - }, - { - tool: "Zendesk AI", - penetration: "7%", - topDepartment: "Customer Support", - topUsers: ["MF", "SG"] - } -]; - -const powerUsers: PowerUser[] = [ - { - name: "John Carmack", - initials: "JC", - department: "Engineering", - topTool: "Cursor", - // Crunch sessions — some big-bang days, quieter ones in between. - trend: [60, 200, 290, 490, 610, 780, 860, 1080, 1260, 1400], - trendNote: "Deep-work bursts, quiet days in between", - requests: "1.4K", - inputTokens: "820K", - outputTokens: "310K", - cost: "$1.2K" - }, - { - name: "Linus Torvalds", - initials: "LT", - department: "Engineering", - topTool: "Cursor", - // Nearly-constant daily rhythm with tiny human variation. - trend: [105, 217, 325, 440, 550, 658, 771, 881, 993, 1100], - trendNote: "Steady daily rhythm, every weekday the same", - requests: "1.1K", - inputTokens: "640K", - outputTokens: "250K", - cost: "$910" - }, - { - name: "Ada Lovelace", - initials: "AL", - department: "Data Science", - topTool: "OpenWork", - // Front-loaded: early bursts of curiosity, then flattening. - trend: [160, 300, 420, 530, 630, 720, 800, 860, 920, 960], - trendNote: "Early-adopter curve — curiosity cooling off", - requests: "960", - inputTokens: "540K", - outputTokens: "210K", - cost: "$780" - }, - { - name: "Alan Turing", - initials: "AT", - department: "Data Science", - topTool: "OpenWork", - // Scheduled automation — perfectly linear. - trend: [88, 176, 264, 352, 440, 528, 616, 704, 792, 880], - trendNote: "Scheduled automation — same batch every day", - requests: "880", - inputTokens: "500K", - outputTokens: "200K", - cost: "$690" - }, - { - name: "Grace Hopper", - initials: "GH", - department: "Engineering", - topTool: "OpenWork", - // Weekly batch runs — two big step-jumps. - trend: [20, 35, 55, 185, 210, 235, 260, 395, 550, 720], - trendNote: "Weekly batch runs — steps every few days", - requests: "720", - inputTokens: "410K", - outputTokens: "180K", - cost: "$560" - }, - { - name: "Marie Curie", - initials: "MC", - department: "Data Science", - topTool: "OpenWork", - // Smooth, accelerating learning curve. - trend: [30, 70, 120, 180, 250, 330, 420, 520, 615, 680], - trendNote: "Learning curve — compounding every week", - requests: "680", - inputTokens: "380K", - outputTokens: "170K", - cost: "$520" - }, - { - name: "Andrew Carnegie", - initials: "AC", - department: "Sales", - topTool: "OpenWork", - // Late adopter — recent steep ramp. - trend: [15, 35, 60, 90, 130, 190, 265, 345, 430, 510], - trendNote: "Late adopter — just caught the wave", - requests: "510", - inputTokens: "290K", - outputTokens: "140K", - cost: "$420" - }, - { - name: "Warren Buffett", - initials: "WB", - department: "Sales", - topTool: "OpenWork", - // Patient, consistent daily use. - trend: [40, 82, 125, 168, 210, 253, 297, 341, 386, 430], - trendNote: "Patient, near-identical daily habit", - requests: "430", - inputTokens: "240K", - outputTokens: "115K", - cost: "$360" - } -]; - -/** - * All initials that appear as avatars anywhere in the dashboard, mapped to a - * full name (where we have one) and their home department (for pill color - * and tooltip context). - */ -const peopleByInitials: Record = { - JC: { name: "John Carmack", department: "Engineering" }, - LT: { name: "Linus Torvalds", department: "Engineering" }, - GH: { name: "Grace Hopper", department: "Engineering" }, - AL: { name: "Ada Lovelace", department: "Data Science" }, - MC: { name: "Marie Curie", department: "Data Science" }, - AT: { name: "Alan Turing", department: "Data Science" }, - AC: { name: "Andrew Carnegie", department: "Sales" }, - WB: { name: "Warren Buffett", department: "Sales" }, - HF: { name: "Henry Ford", department: "Sales" }, - HL: { department: "Product" }, - DG: { department: "Product" }, - AR: { department: "Product" }, - MF: { department: "Customer Support" }, - SG: { department: "Customer Support" }, - RM: { department: "Customer Support" }, - RF: { department: "Marketing" }, - AS: { department: "Marketing" }, - JR: { department: "Marketing" }, - SD: { department: "Legal" }, - OB: { department: "Legal" }, - RH: { department: "Legal" } -}; - -type TabId = "departments" | "users" | "tools"; - -type Props = { - /** When true, the outer card renders its own rounded border + shadow. When false, the caller wraps it. */ - standalone?: boolean; -}; - -export function LandingEnterpriseHero({ standalone = false }: Props) { - const [activeTab, setActiveTab] = useState("departments"); - - const shell = standalone - ? "overflow-hidden rounded-[28px] border border-[#dde2ea] bg-[#fbfbfa] shadow-[0_18px_60px_rgba(7,25,44,0.08)]" - : "overflow-hidden bg-[#fbfbfa]"; - - const tabCopy: Record = { - departments: { - crumb: "Departments", - description: - "Where AI usage is concentrated across the org, by team." - }, - users: { - crumb: "Power users", - description: - "The individuals driving the most AI usage. Use them to teach the rest of the org." - }, - tools: { - crumb: "AI tools", - description: - "The tools people reach for, who uses them most, and who to ask for access." - } - }; - - return ( -
- - -
-
- - - -
-
- - Q2 - - AI Adoption - - {tabCopy[activeTab].crumb} -
- -

- {tabCopy[activeTab].description} -

-
- -
- } - title="Daily active AI users" - value="68 / 131" - tone="violet" - /> - } - title="Monthly spend" - value="$480K" - tone="green" - /> - } - title="Top-tool penetration" - value="41%" - subvalue="OpenWork · 54 users" - tone="blue" - /> -
- -
- -
- -
- {activeTab === "departments" ? : null} - {activeTab === "users" ? : null} - {activeTab === "tools" ? : null} -
-
-
- ); -} - -function MacChrome() { - return ( -
-
-
-
-
- ); -} - -function TopNav() { - return ( -
-
- - - OpenWork - -
- -
- - -
- AG -
-
-
- ); -} - -type StatCardProps = { - icon: React.ReactNode; - title: string; - value: string; - subvalue?: string; - tone: "violet" | "green" | "blue"; -}; - -function StatCard({ icon, title, value, subvalue, tone }: StatCardProps) { - return ( -
-
-
- {icon} -
- -
-
- {title} -
-
- {value} -
- {subvalue ? ( -
- {subvalue} -
- ) : null} -
-
-
- ); -} - -type TabBarProps = { - activeTab: TabId; - onChange: (tab: TabId) => void; -}; - -function TabBar({ activeTab, onChange }: TabBarProps) { - const tabs: Array<{ id: TabId; label: string }> = [ - { id: "departments", label: "Departments" }, - { id: "users", label: "Power users" }, - { id: "tools", label: "AI tools" } - ]; - - return ( -
- {tabs.map((tab) => { - const selected = tab.id === activeTab; - return ( - - ); - })} -
- ); -} - -function DepartmentsTable() { - const grouped = departments.reduce>( - (acc, row) => { - acc[row.category].push(row); - return acc; - }, - { - "Technical teams": [], - "Business teams": [] - } - ); - - return ( -
-
-
Team
-
Daily active
-
Spend
-
Avg / person
-
Adoption trend
-
Power users
-
- - {(["Technical teams", "Business teams"] as const).map((group) => ( -
-
- {group} -
- - {grouped[group].map((row) => ( -
-
- {row.name} -
-
- {row.dailyActive} -
-
- {row.spend} -
-
- {row.avgPerPerson} -
-
- -
-
- {row.powerUsers.map((user) => - user.startsWith("+") ? ( - - {user} - - ) : ( - - ) - )} -
-
- ))} -
- ))} -
- ); -} - -function PowerUsersTable() { - return ( -
-
-
Name
-
Top tool
-
Cumulative trend
-
Requests
-
In tokens
-
Out tokens
-
Cost
-
- - {powerUsers.map((user) => ( -
-
- -
-
- {user.name} -
-
- {user.department} -
-
-
- -
- - - {user.topTool} - -
- -
- -
- -
- {user.requests} -
-
- {user.inputTokens} -
-
- {user.outputTokens} -
-
- {user.cost} -
-
- ))} -
- ); -} - -function ToolsTable() { - return ( -
-
-
Tool
-
Penetration
-
Top department
-
Power users
-
- - {toolRows.map((row) => ( -
-
- - - {row.tool} - -
-
- {row.penetration} -
-
- {row.topDepartment} -
-
- {row.topUsers.map((initials) => { - const person = peopleByInitials[initials]; - return ( - - ); - })} -
-
- ))} -
- ); -} - -type SparklineProps = { - values: number[]; - color: string; - title?: string; -}; - -function Sparkline({ values, color, title }: SparklineProps) { - const width = 84; - const height = 22; - const padding = 2; - - if (values.length === 0) return null; - - const min = Math.min(...values); - const max = Math.max(...values); - const range = Math.max(max - min, 1); - const stepX = (width - padding * 2) / Math.max(values.length - 1, 1); - - const points = values.map((v, i) => { - const x = padding + i * stepX; - const y = padding + (height - padding * 2) * (1 - (v - min) / range); - return `${x.toFixed(1)},${y.toFixed(1)}`; - }); - - const areaPath = - `M ${padding},${height - padding} ` + - points.map((p) => `L ${p}`).join(" ") + - ` L ${width - padding},${height - padding} Z`; - - const linePath = `M ${points.join(" L ")}`; - - const last = points[points.length - 1].split(","); - - return ( - - {title ? {title} : null} - - - - - ); -} - -function ToolGlyph({ tool, small = false }: { tool: string; small?: boolean }) { - const sizeClass = small - ? "h-6 w-6 rounded-[7px]" - : "h-7 w-7 rounded-[8px] md:h-8 md:w-8 md:rounded-[9px]"; - - if (tool === "OpenWork") { - return ( -
- -
- ); - } - - const iconMap: Record = { - Cursor: ( - - C - - ), - "Figma AI": ( - - F - - ), - "Notion AI": ( - - N - - ), - "Zendesk AI": ( - - Z - - ) - }; - - return ( -
- {iconMap[tool] ?? ( - - )} -
- ); -} - -function InitialPill({ - initials, - department, - name -}: { - initials: string; - department: string; - name?: string; -}) { - const tooltip = name - ? `${name} · ${department}` - : `${initials} · ${department}`; - - return ( -
- {initials} -
- ); -} - -function departmentColor(department: string) { - switch (department) { - case "Engineering": - return "bg-[#F9DADB] text-[#B43035]"; - case "Data Science": - return "bg-[#E7DEFF] text-[#6F3DFF]"; - case "Product": - return "bg-[#DFEAFE] text-[#1D63FF]"; - case "Customer Support": - return "bg-[#DFF5F6] text-[#127B85]"; - case "Marketing": - return "bg-[#FBE6D7] text-[#E56A17]"; - case "Sales": - return "bg-[#E3F4DF] text-[#2C8B39]"; - case "Legal": - return "bg-[#E8EBEF] text-[#5A6886]"; - default: - return "bg-[#EEF2F7] text-[#30405F]"; - } -} - -function sparklineColor(department: string) { - switch (department) { - case "Engineering": - return "#B43035"; - case "Data Science": - return "#6F3DFF"; - case "Product": - return "#1D63FF"; - case "Customer Support": - return "#127B85"; - case "Marketing": - return "#E56A17"; - case "Sales": - return "#2C8B39"; - case "Legal": - return "#5A6886"; - default: - return "#30405F"; - } -} - -/** - * Color the adoption trend line by direction so users can scan up/down/flat at a glance. - * Uses 3-point rolling averages at each end to avoid false signals on a single spiky day. - */ -function trendDirectionColor(trend: number[]): string { - if (trend.length < 3) return "#637291"; - const startAvg = (trend[0] + trend[1] + trend[2]) / 3; - const endAvg = - trend.slice(-3).reduce((a, b) => a + b, 0) / 3; - const delta = endAvg - startAvg; - if (delta > 0.5) return "#18A34A"; // green - if (delta < -0.5) return "#B43035"; // red - return "#637291"; // gray -} - -function toneBg(tone: "violet" | "green" | "blue") { - switch (tone) { - case "violet": - return "bg-[#EDE4FF]"; - case "green": - return "bg-[#E3F3E3]"; - case "blue": - return "bg-[#E4ECFB]"; - } -} - -export default LandingEnterpriseHero; diff --git a/ee/apps/landing/components/landing-enterprise.tsx b/ee/apps/landing/components/landing-enterprise.tsx index 070b7ca6..5993de55 100644 --- a/ee/apps/landing/components/landing-enterprise.tsx +++ b/ee/apps/landing/components/landing-enterprise.tsx @@ -11,7 +11,6 @@ import { useState } from "react"; import { BookCallForm } from "./book-call-form"; import { LandingAppDemoPanel } from "./landing-app-demo-panel"; import { LandingBackground } from "./landing-background"; -import { LandingEnterpriseHero } from "./landing-enterprise-hero"; import { defaultLandingDemoFlowId, landingDemoFlows, @@ -119,12 +118,15 @@ export function LandingEnterprise(props: Props) {
-
- -
+
+ OpenWork enterprise dashboard showing AI adoption, spend, and tool penetration by department +
diff --git a/ee/apps/landing/screenshots/before-enterprise-hero-png.png b/ee/apps/landing/screenshots/before-enterprise-hero-png.png deleted file mode 100644 index 4306fce0..00000000 Binary files a/ee/apps/landing/screenshots/before-enterprise-hero-png.png and /dev/null differ diff --git a/ee/apps/landing/screenshots/tab-1-departments.png b/ee/apps/landing/screenshots/tab-1-departments.png deleted file mode 100644 index 00e57392..00000000 Binary files a/ee/apps/landing/screenshots/tab-1-departments.png and /dev/null differ diff --git a/ee/apps/landing/screenshots/tab-2-power-users-lower.png b/ee/apps/landing/screenshots/tab-2-power-users-lower.png deleted file mode 100644 index 5d6d8a89..00000000 Binary files a/ee/apps/landing/screenshots/tab-2-power-users-lower.png and /dev/null differ diff --git a/ee/apps/landing/screenshots/tab-2-power-users.png b/ee/apps/landing/screenshots/tab-2-power-users.png deleted file mode 100644 index 0e735dcd..00000000 Binary files a/ee/apps/landing/screenshots/tab-2-power-users.png and /dev/null differ diff --git a/ee/apps/landing/screenshots/tab-3-ai-tools.png b/ee/apps/landing/screenshots/tab-3-ai-tools.png deleted file mode 100644 index e3dd786a..00000000 Binary files a/ee/apps/landing/screenshots/tab-3-ai-tools.png and /dev/null differ