root = Card([header, quarterTabs, healthCallout, projectsSection, milestonesSection, budgetSection, utilizationSection, risksSection, deadlinesSection, paceSection, blockedSection, actionsSection])

header = CardHeader("Portfolio Review — Q3 2025", "Weekly PMO health check · 12 active projects")

quarterTabs = Tabs([q2Tab, q3Tab, q4Tab])
q2Tab = TabItem("q2", "Q2 2025", [q2Note])
q2Note = Callout("info", "Q2 review", "This quarter is archived. Switch to Q3 for the live portfolio.")
q3Tab = TabItem("q3", "Q3 2025", [q3Content])
q3Content = Card([q3Heading, q3Table])
q3Heading = Heading("Q3 projects", "h3")
q3Table = Table([projName, projOwner, projDeadline, projHealth])
projName = Col("Project", ["Atlas Migration", "Nimbus Launch", "Helios Rebrand", "Orion Data Hub", "Vega Compliance"])
projOwner = Col("Owner", ["A. Chen", "M. Patel", "S. Ortiz", "J. Kim", "R. Silva"])
projDeadline = Col("Deadline", ["2025-09-30", "2025-09-12", "2025-10-15", "2025-09-05", "2025-12-01"])
projHealth = Col("Health", ["On track", "At risk", "On track", "Blocked", "On track"])
q4Tab = TabItem("q4", "Q4 2025", [q4Note])
q4Note = Callout("info", "Q4 review", "Planning view. No active projects yet.")

healthCallout = Callout("success", "Portfolio health: Good", "11 of 12 projects on track. One blocker on Orion Data Hub needs attention before Friday.")

projectsSection = Card([projectsTitle, projectsTable], "sunk")
projectsTitle = Heading("Active projects", "h2")
projectsTable = Table([pName, pOwner, pDeadline, pHealth])
pName = Col("Project", ["Atlas Migration", "Nimbus Launch", "Helios Rebrand", "Orion Data Hub", "Vega Compliance", "Polaris CRM", "Quasar Analytics", "Lyra Mobile", "Zephyr API", "Titan Portal", "Nova Security", "Iris Insights"])
pOwner = Col("Owner", ["A. Chen", "M. Patel", "S. Ortiz", "J. Kim", "R. Silva", "T. Nguyen", "L. Brooks", "D. Foster", "P. Alvarez", "K. Morgan", "E. Walsh", "C. Reed"])
pDeadline = Col("Deadline", ["2025-09-30", "2025-09-12", "2025-10-15", "2025-09-05", "2025-12-01", "2025-10-01", "2025-09-20", "2025-11-10", "2025-09-25", "2025-10-30", "2025-11-15", "2025-12-10"])
pHealth = Col("Health", ["On track", "At risk", "On track", "Blocked", "On track", "On track", "At risk", "On track", "On track", "On track", "On track", "At risk"])

milestonesSection = Card([milestonesTitle, milestonesTable], "sunk")
milestonesTitle = Heading("Overdue milestones", "h2")
milestonesTable = Table([msName, msProject, msDue, msLag])
msName = Col("Milestone", ["Beta sign-off", "Data schema freeze", "API v2 release", "Security audit"])
msProject = Col("Project", ["Nimbus Launch", "Orion Data Hub", "Zephyr API", "Nova Security"])
msDue = Col("Due date", ["2025-08-28", "2025-08-30", "2025-09-02", "2025-08-25"])
msLag = Col("Days overdue", [15, 12, 5, 18])

budgetSection = Card([budgetTitle, budgetChart], "sunk")
budgetTitle = Heading("Budget spent vs allocated", "h2")
budgetChart = HorizontalBarChart(["Atlas Migration", "Nimbus Launch", "Helios Rebrand", "Orion Data Hub", "Vega Compliance"], [allocSeries, spentSeries], "grouped", "USD", "Project")
allocSeries = Series("Allocated", [450000, 320000, 180000, 510000, 260000])
spentSeries = Series("Spent", [398000, 305000, 142000, 478000, 171000])

utilizationSection = Card([utilTitle, utilChart], "sunk")
utilTitle = Heading("Team utilization", "h2")
utilChart = SingleStackedBarChart(["Engineering", "Design", "Product", "QA", "Data"], [72, 88, 64, 81, 57])

risksSection = Card([risksTitle, risksTable], "sunk")
risksTitle = Heading("Top risks", "h2")
risksTable = Table([riskName, riskProject, riskSeverity, riskOwner])
riskName = Col("Risk", ["Vendor dependency", "Scope creep", "Data quality", "Key person leave", "Infra capacity"])
riskProject = Col("Project", ["Atlas Migration", "Nimbus Launch", "Orion Data Hub", "Helios Rebrand", "Titan Portal"])
riskSeverity = Col("Severity", ["High", "Medium", "High", "Medium", "Low"])
riskOwner = Col("Owner", ["A. Chen", "M. Patel", "J. Kim", "S. Ortiz", "K. Morgan"])

deadlinesSection = Card([deadlinesTitle, deadlinesTable], "sunk")
deadlinesTitle = Heading("Deadlines in the next two weeks", "h2")
deadlinesTable = Table([dlProject, dlDate, dlOwner])
dlProject = Col("Project", ["Orion Data Hub", "Nimbus Launch", "Zephyr API", "Quasar Analytics"])
dlDate = Col("Due", ["2025-09-05", "2025-09-12", "2025-09-18", "2025-09-20"])
dlOwner = Col("Owner", ["J. Kim", "M. Patel", "P. Alvarez", "L. Brooks"])

paceSection = Card([paceTitle, paceChart], "sunk")
paceTitle = Heading("Delivery pace — last six sprints", "h2")
paceChart = LineChart(["S1", "S2", "S3", "S4", "S5", "S6"], [committedSeries, deliveredSeries], "natural", "Sprint", "Story points")
committedSeries = Series("Committed", [320, 340, 310, 360, 330, 350])
deliveredSeries = Series("Delivered", [295, 330, 288, 342, 305, 331])

blockedSection = Card([blockedTitle, blockedList], "sunk")
blockedTitle = Heading("Blocked work items", "h2")
blockedList = ListBlock([block1, block2, block3])
block1 = ListItem("Orion data pipeline stuck", "Waiting on vendor API access · blocked 6 days")
block2 = ListItem("Nimbus beta environment", "No staging capacity · blocked 3 days")
block3 = ListItem("Atlas schema migration", "Missing DBA approval · blocked 2 days")

actionsSection = Card([actionsHeading, actionButtons], "sunk")
actionsHeading = Heading("Actions", "h2")
actionButtons = Buttons([requestPeopleBtn, exportBtn, archiveBtn])
requestPeopleBtn = Button("Request more people")
exportBtn = Button("Export review", null, "secondary")
archiveBtn = Button("Archive finished project", null, "tertiary")